1
0
mirror of https://git.savannah.gnu.org/git/emacs/org-mode.git synced 2024-11-22 07:09:47 +00:00

babel: org-babel-c more robust, better error messages and c++ support

This commit is contained in:
Eric Schulte 2010-03-26 18:52:16 -06:00
parent b61019489c
commit 22e4cd9b6d

View File

@ -39,9 +39,6 @@
(org-babel-add-interpreter "C") (org-babel-add-interpreter "C")
(add-to-list 'org-babel-tangle-langs '("C" "c" nil)) (add-to-list 'org-babel-tangle-langs '("C" "c" nil))
(org-babel-add-interpreter "cpp")
(add-to-list 'org-babel-tangle-langs '("cpp" "cpp" nil))
(org-babel-add-interpreter "c++") (org-babel-add-interpreter "c++")
(add-to-list 'org-babel-tangle-langs '("c++" "cpp" nil)) (add-to-list 'org-babel-tangle-langs '("c++" "cpp" nil))
@ -49,37 +46,56 @@
"Command used to compile a C source code file into an "Command used to compile a C source code file into an
executable.") executable.")
(defvar org-babel-c++-compiler "g++"
"Command used to compile a c++ source code file into an
executable.")
(defun org-babel-execute:cpp (body params) (defun org-babel-execute:cpp (body params)
(org-babel-execute:C body params)) (org-babel-execute:C body params))
(defun org-babel-execute:c++ (body params) (defun org-babel-execute:c++ (body params)
(org-babel-execute:C body params)) "Execute a block of C++ code with org-babel. This function is
called by `org-babel-execute-src-block'."
(let ((c-variant 'cpp)) (org-babel-C-execute body params)))
(defun org-babel-execute:C (body params) (defun org-babel-execute:C (body params)
"Execute a block of C commands with org-babel. This "Execute a block of C code with org-babel. This function is
function is called by `org-babel-execute-src-block'." called by `org-babel-execute-src-block'."
(let ((c-variant 'c)) (org-babel-C-execute body params)))
(defun org-babel-C-execute (body params)
"This should only be called by `org-babel-execute:C' or
`org-babel-execute:c++'."
(message "executing C source code block") (message "executing C source code block")
(let* ((processed-params (org-babel-process-params params)) (let* ((processed-params (org-babel-process-params params))
(tmp-src-file (make-temp-file "org-babel-C-src" nil ".c")) (tmp-src-file (make-temp-file "org-babel-C-src" nil
(case c-variant
('c ".c")
('cpp ".cpp"))))
(tmp-bin-file (make-temp-file "org-babel-C-bin")) (tmp-bin-file (make-temp-file "org-babel-C-bin"))
(tmp-out-file (make-temp-file "org-babel-C-out")) (tmp-out-file (make-temp-file "org-babel-C-out"))
(flags (cdr (assoc :flags params))) (flags (cdr (assoc :flags params)))
(vars (second processed-params)) (vars (second processed-params))
(includes (cdr (assoc :includes params))) (includes (org-babel-read
(defines (cdr (assoc :defines params))) (or (cdr (assoc :includes params))
(full-body (concat (org-entry-get nil "includes" t))))
;; includes (defines (org-babel-read
(mapconcat (or (cdr (assoc :includes params))
(lambda (inc) (format "#include %s" inc)) (org-entry-get nil "defines" t))))
(if (listp includes) includes (list includes)) "\n") (full-body (mapconcat 'identity
;; defines (list
(mapconcat ;; includes
(lambda (inc) (format "#define %s" inc)) (mapconcat
(if (listp defines) defines (list defines)) "\n") (lambda (inc) (format "#include %s" inc))
;; variables (if (listp includes) includes (list includes)) "\n")
(mapconcat 'org-babel-C-var-to-C vars "\n") ;; defines
;; body (mapconcat
"\n" (org-babel-C-ensure-main-wrap body) "\n\n")) (lambda (inc) (format "#define %s" inc))
(if (listp defines) defines (list defines)) "\n")
;; variables
(mapconcat 'org-babel-C-var-to-C vars "\n")
;; body
"\n" (org-babel-C-ensure-main-wrap body) "\n") "\n"))
(error-buf (get-buffer-create "*Org-Babel Error Output*")) (error-buf (get-buffer-create "*Org-Babel Error Output*"))
(compile (compile
(progn (progn
@ -88,7 +104,9 @@ function is called by `org-babel-execute-src-block'."
(org-babel-shell-command-on-region (org-babel-shell-command-on-region
(point-min) (point-max) (point-min) (point-max)
(format "%s -o %s %s %s" (format "%s -o %s %s %s"
org-babel-C-compiler (case c-variant
('c org-babel-C-compiler)
('cpp org-babel-c++-compiler))
tmp-bin-file tmp-bin-file
(mapconcat 'identity (mapconcat 'identity
(if (listp flags) flags (list flags)) " ") (if (listp flags) flags (list flags)) " ")
@ -101,11 +119,15 @@ function is called by `org-babel-execute-src-block'."
(org-babel-shell-command-on-region (org-babel-shell-command-on-region
(point-min) (point-max) tmp-bin-file (current-buffer) 'replace) (point-min) (point-max) tmp-bin-file (current-buffer) 'replace)
(buffer-string)))) (buffer-string))))
(progn (display-buffer error-buf) nil)))) (progn
(with-current-buffer error-buf
(goto-char (point-max))
(insert (concat "\n\n--body--\n" full-body)))
(display-buffer error-buf) nil))))
(defun org-babel-C-ensure-main-wrap (body) (defun org-babel-C-ensure-main-wrap (body)
"Wrap body in a \"main\" function call if none exists." "Wrap body in a \"main\" function call if none exists."
(if (string-match "^[ \t]*[intvoid][ \t]*main[ \t]*(.*)" body) (if (string-match "^[ \t]*[intvod]+[ \t]*main[ \t]*(.*)" body)
body body
(format "int main() {\n%s\n}\n" body))) (format "int main() {\n%s\n}\n" body)))