diff options
author | Bastien Guerry <bzg@gnu.org> | 2013-11-12 14:06:26 +0100 |
---|---|---|
committer | Bastien Guerry <bzg@gnu.org> | 2013-11-12 14:06:26 +0100 |
commit | 271672fad74cdbc9065d23d6e6cee1b8540f571b (patch) | |
tree | d322b956ec0e74ee33b22354ef00839b23b1618d /lisp/org/ob-C.el | |
parent | f201cf3a8143b0b34b07769fc7d73dd14761b87b (diff) | |
download | emacs-271672fad74cdbc9065d23d6e6cee1b8540f571b.tar.gz |
Merge Org version 8.2.3a.
Diffstat (limited to 'lisp/org/ob-C.el')
-rw-r--r-- | lisp/org/ob-C.el | 109 |
1 files changed, 78 insertions, 31 deletions
diff --git a/lisp/org/ob-C.el b/lisp/org/ob-C.el index 42a98de8c05..e9eec934dc1 100644 --- a/lisp/org/ob-C.el +++ b/lisp/org/ob-C.el @@ -31,7 +31,6 @@ ;;; Code: (require 'ob) -(require 'ob-eval) (require 'cc-mode) (declare-function org-entry-get "org" @@ -45,24 +44,24 @@ (defvar org-babel-C-compiler "gcc" "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.") +executable.") (defvar org-babel-c-variant nil "Internal variable used to hold which type of C (e.g. C or C++) is currently being evaluated.") (defun org-babel-execute:cpp (body params) - "Execute BODY according to PARAMS. This function calls -`org-babel-execute:C++'." + "Execute BODY according to PARAMS. +This function calls `org-babel-execute:C++'." (org-babel-execute:C++ body params)) (defun 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'." + "Execute a block of C++ code with org-babel. +This function is called by `org-babel-execute-src-block'." (let ((org-babel-c-variant 'cpp)) (org-babel-C-execute body params))) (defun org-babel-expand-body:C++ (body params) @@ -71,8 +70,8 @@ header arguments (calls `org-babel-C-expand')." (let ((org-babel-c-variant 'cpp)) (org-babel-C-expand body params))) (defun 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'." + "Execute a block of C code with org-babel. +This function is called by `org-babel-execute-src-block'." (let ((org-babel-c-variant 'c)) (org-babel-C-execute body params))) (defun org-babel-expand-body:c (body params) @@ -106,11 +105,11 @@ or `org-babel-execute:C++'." (org-babel-process-file-name tmp-src-file)) "")))) ((lambda (results) (org-babel-reassemble-table - (if (member "vector" (cdr (assoc :result-params params))) - (let ((tmp-file (org-babel-temp-file "c-"))) - (with-temp-file tmp-file (insert results)) - (org-babel-import-elisp-from-file tmp-file)) - (org-babel-read results)) + (org-babel-result-cond (cdr (assoc :result-params params)) + (org-babel-read results) + (let ((tmp-file (org-babel-temp-file "c-"))) + (with-temp-file tmp-file (insert results)) + (org-babel-import-elisp-from-file tmp-file))) (org-babel-pick-name (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) (org-babel-pick-name @@ -147,10 +146,10 @@ it's header arguments." body) "\n") "\n"))) (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]*[intvod]+[ \t\n\r]*main[ \t]*(.*)" body) body - (format "int main() {\n%s\nreturn(0);\n}\n" body))) + (format "int main() {\n%s\nreturn 0;\n}\n" body))) (defun org-babel-prep-session:C (session params) "This function does nothing as C is a compiled language with no @@ -164,6 +163,59 @@ support for sessions" ;; helper functions +(defun org-babel-C-format-val (type val) + "Handle the FORMAT part of TYPE with the data from VAL." + (let ((format-data (cadr type))) + (if (stringp format-data) + (cons "" (format format-data val)) + (funcall format-data val)))) + +(defun org-babel-C-val-to-C-type (val) + "Determine the type of VAL. +Return a list (TYPE-NAME FORMAT). TYPE-NAME should be the name of the type. +FORMAT can be either a format string or a function which is called with VAL." + (cond + ((integerp val) '("int" "%d")) + ((floatp val) '("double" "%f")) + ((or (listp val) (vectorp val)) + (lexical-let ((type (org-babel-C-val-to-C-list-type val))) + (list (car type) + (lambda (val) + (cons + (format "[%d]%s" + (length val) + (car (org-babel-C-format-val type (elt val 0)))) + (concat "{ " + (mapconcat (lambda (v) + (cdr (org-babel-C-format-val type v))) + val + ", ") + " }")))))) + (t ;; treat unknown types as string + '("char" (lambda (val) + (let ((s (format "%s" val))) ;; convert to string for unknown types + (cons (format "[%d]" (1+ (length s))) + (concat "\"" s "\"")))))))) + +(defun org-babel-C-val-to-C-list-type (val) + "Determine the C array type of a VAL." + (let (type) + (mapc + #'(lambda (i) + (let* ((tmp-type (org-babel-C-val-to-C-type i)) + (type-name (car type)) + (tmp-type-name (car tmp-type))) + (when (and type (not (string= type-name tmp-type-name))) + (if (and (member type-name '("int" "double" "int32_t")) + (member tmp-type-name '("int" "double" "int32_t"))) + (setq tmp-type '("double" "" "%f")) + (error "Only homogeneous lists are supported by C. You can not mix %s and %s" + type-name + tmp-type-name))) + (setq type tmp-type))) + val) + type)) + (defun org-babel-C-var-to-C (pair) "Convert an elisp val into a string of C code specifying a var of the same value." @@ -174,22 +226,17 @@ of the same value." (setq val (symbol-name val)) (when (= (length val) 1) (setq val (string-to-char val)))) - (cond - ((integerp val) - (format "int %S = %S;" var val)) - ((floatp val) - (format "double %S = %S;" var val)) - ((or (integerp val)) - (format "char %S = '%S';" var val)) - ((stringp val) - (format "char %S[%d] = \"%s\";" - var (+ 1 (length val)) val)) - (t - (format "u32 %S = %S;" var val))))) - + (let* ((type-data (org-babel-C-val-to-C-type val)) + (type (car type-data)) + (formated (org-babel-C-format-val type-data val)) + (suffix (car formated)) + (data (cdr formated))) + (format "%s %s%s = %s;" + type + var + suffix + data)))) (provide 'ob-C) - - ;;; ob-C.el ends here |