overview of the execution of a C code block
The org-babel-execute:C
is used to execute a block of C code. The
source code of this function is presented below with inline comments
explaining the sequence of operations.
In actuality org-babel-execute:C
just calls org-babel-C-execute
,
which is used to execute both C and C++ code blocks. The evaluation
process is as follows. Note: hover your mouse over references to see
the corresponding point in the source code – this behavior is
described in the Org-mode manual.
- A temporary file (tmp-file) is created to hold the source code present in the code block. A language appropriate extension is added (ext).
- Another temporary file is created (bin-file) to hold the compiled binary executable.
- Two header arguments which are specific to C/C++ code blocks are collected.
- The body of the code block is expanded (expand). Every language has an expansion function which is responsible for adding variables to the code block, and in some cases wrapping the code block for the collection of results.
- To compile the code block, the expanded body is dumped into the temporary sourced code file (src-dump), the compiler command is generated from the compiler, src-file-name, bin-file-name and flags respectively (cmpl).
- The resulting binary file is then evaluated (evaluation) and the
output is passed to an anonymous function (results-processing) as
the local variable named
results
. - The results are then either read into a table (table) or read into
an elisp data structure (elisp) depending on the values of the
:results
header argument. Optional column (colname) and row (rowname) names are applied again according to the corresponding header arguments. - Finally the processed results are handed back to the rest of the code block machinery which handles the incorporation of the results into the Org-mode buffer.
1: (defun org-babel-C-execute (body params) 2: "This function should only be called by `org-babel-execute:C' 3: or `org-babel-execute:C++'." 4: (let* ((tmp-src-file (org-babel-temp-file ; (tmp-file) 5: "C-src-" 6: (cond ; (ext) 7: ((equal org-babel-c-variant 'c) ".c") 8: ((equal org-babel-c-variant 'cpp) ".cpp")))) 9: (tmp-bin-file (org-babel-temp-file "C-bin-")) ; (bin-file) 10: (cmdline (cdr (assoc :cmdline params))) ; (cmdline) 11: (flags (cdr (assoc :flags params))) ; (flags) 12: (full-body (org-babel-C-expand body params)) ; (expand) 13: (compile 14: (progn 15: (with-temp-file tmp-src-file (insert full-body)) ; (src-dump) 16: (org-babel-eval 17: (format "%s -o %s %s %s" ; (cmpl) 18: (cond 19: ((equal org-babel-c-variant 'c) org-babel-C-compiler) 20: ((equal org-babel-c-variant 'cpp) org-babel-C++-compiler)) 21: (org-babel-process-file-name tmp-bin-file) 22: (mapconcat 'identity 23: (if (listp flags) flags (list flags)) " ") 24: (org-babel-process-file-name tmp-src-file)) "")))) 25: ((lambda (results) ; (results-processing) 26: (org-babel-reassemble-table 27: (if (member "vector" (cdr (assoc :result-params params))) 28: (let ((tmp-file (org-babel-temp-file "c-"))) 29: (with-temp-file tmp-file (insert results)) 30: (org-babel-import-elisp-from-file tmp-file)) ; (table) 31: (org-babel-read results)) ; (elisp) 32: (org-babel-pick-name ; (colname) 33: (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) 34: (org-babel-pick-name ; (rowname) 35: (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params))))) 36: (org-babel-trim 37: (org-babel-eval ; (evaluation) 38: (concat tmp-bin-file (if cmdline (concat " " cmdline) "")) "")))))