From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?ISO-8859-1?Q?R=FCdiger?= Sonderfeld Subject: [PATCH] ob-C: Add list support. Date: Thu, 06 Jun 2013 19:49:03 +0200 Message-ID: <2536552.JaI2attv7o@descartes> References: <87vc5ri259.fsf@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:57507) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UkeJG-0005QD-TC for emacs-orgmode@gnu.org; Thu, 06 Jun 2013 13:49:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UkeJD-0003E3-GC for emacs-orgmode@gnu.org; Thu, 06 Jun 2013 13:49:14 -0400 Received: from ptmx.org ([178.63.28.110]:45513) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UkeJD-0003Db-2l for emacs-orgmode@gnu.org; Thu, 06 Jun 2013 13:49:11 -0400 In-Reply-To: <87vc5ri259.fsf@gmail.com> List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: emacs-orgmode@gnu.org Cc: Eric Schulte * lisp/ob-C.el (org-babel-C-var-to-C): Add list support (org-babel-C-val-to-C-list-type, org-babel-C-val-to-C-type, org-babel-C-format-val): New functions. (org-babel-C-ensure-main-wrap, org-babel-execute:C, org-babel-execute:C++, rg-babel-execute:cpp, org-babel-C++-compiler, org-babel-C-compiler): Improve docstring. * testing/examples/ob-C-test.org (string_var): Add required std:: (Array): Add missing ID. (Matrix): Add tests for list support. * testing/lisp/test-ob-C.el (ob-C/table): Test succeeds. (ob-C/list-var, ob-C/vector-var, ob-C/list-list-var): Add tests for list support. Signed-off-by: R=C3=BCdiger Sonderfeld --- lisp/ob-C.el | 98 +++++++++++++++++++++++++++++++---= -------- testing/examples/ob-C-test.org | 28 +++++++++++- testing/lisp/test-ob-C.el | 20 ++++++++- 3 files changed, 118 insertions(+), 28 deletions(-) diff --git a/lisp/ob-C.el b/lisp/ob-C.el index b1e8a06..e9eec93 100644 --- a/lisp/ob-C.el +++ b/lisp/ob-C.el @@ -44,24 +44,24 @@ (defvar org-babel-default-header-args:C '()) =20 (defvar org-babel-C-compiler "gcc" "Command used to compile a C source code file into an - executable.") +executable.") =20 (defvar org-babel-C++-compiler "g++" "Command used to compile a C++ source code file into an - executable.") +executable.") =20 (defvar org-babel-c-variant nil "Internal variable used to hold which type of C (e.g. C or C++) is currently being evaluated.") =20 (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)) =20 (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))= ) =20 (defun org-babel-expand-body:C++ (body params) @@ -70,8 +70,8 @@ (defun org-babel-expand-body:C++ (body params) (let ((org-babel-c-variant 'cpp)) (org-babel-C-expand body params)))= =20 (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))) =20 (defun org-babel-expand-body:c (body params) @@ -146,10 +146,10 @@ (defun org-babel-C-expand (body params) =09=09 body) "\n") "\n"))) =20 (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))) =20 (defun org-babel-prep-session:C (session params) "This function does nothing as C is a compiled language with no @@ -163,6 +163,59 @@ (defun org-babel-load-session:C (session body para= ms) =20 ;; helper functions =20 +(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) +=09(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 wit= h 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) +=09 (lambda (val) +=09 (cons +=09 (format "[%d]%s" +=09=09 (length val) +=09=09 (car (org-babel-C-format-val type (elt val 0)))) +=09 (concat "{ " +=09=09 (mapconcat (lambda (v) +=09=09=09=09 (cdr (org-babel-C-format-val type v))) +=09=09=09=09 val +=09=09=09=09 ", ") +=09=09 " }")))))) + (t ;; treat unknown types as string + '("char" (lambda (val) +=09 (let ((s (format "%s" val))) ;; convert to string for unknow= n types +=09=09 (cons (format "[%d]" (1+ (length s))) +=09=09 (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) +=09 (let* ((tmp-type (org-babel-C-val-to-C-type i)) +=09=09(type-name (car type)) +=09=09(tmp-type-name (car tmp-type))) +=09 (when (and type (not (string=3D type-name tmp-type-name))) +=09 (if (and (member type-name '("int" "double" "int32_t")) +=09=09 (member tmp-type-name '("int" "double" "int32_t"))) +=09=09 (setq tmp-type '("double" "" "%f")) +=09 (error "Only homogeneous lists are supported by C. You can = not mix %s and %s" +=09=09 type-name +=09=09 tmp-type-name))) +=09 (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." @@ -173,22 +226,17 @@ (defun org-babel-C-var-to-C (pair) (setq val (symbol-name val)) (when (=3D (length val) 1) (setq val (string-to-char val)))) - (cond - ((integerp val) - (format "int %S =3D %S;" var val)) - ((floatp val) - (format "double %S =3D %S;" var val)) - ((or (integerp val)) - (format "char %S =3D '%S';" var val)) - ((stringp val) - (format "char %S[%d] =3D \"%s\";" - var (+ 1 (length val)) val)) - (t - (format "u32 %S =3D %S;" var val))))) - + (let* ((type-data (org-babel-C-val-to-C-type val)) +=09 (type (car type-data)) +=09 (formated (org-babel-C-format-val type-data val)) +=09 (suffix (car formated)) +=09 (data (cdr formated))) + (format "%s %s%s =3D %s;" +=09 type +=09 var +=09 suffix +=09 data)))) =20 (provide 'ob-C) =20 - - ;;; ob-C.el ends here diff --git a/testing/examples/ob-C-test.org b/testing/examples/ob-C-tes= t.org index 32ab88b..1d0a83f 100644 --- a/testing/examples/ob-C-test.org +++ b/testing/examples/ob-C-test.org @@ -24,7 +24,7 @@ * Simple tests =20 #+source: string_var #+begin_src cpp :var q=3D"word" :includes '( ) :res= ults silent - std::cout << q << ' ' << strlen(q); + std::cout << q << ' ' << std::strlen(q); return 0; #+end_src =20 @@ -35,6 +35,9 @@ * Simple tests #+end_src =20 * Array + :PROPERTIES: + :ID: 2df1ab83-3fa3-462a-a1f3-3aef6044a874 + :END: #+source: array #+begin_src cpp :includes "" :results vector :results silent= for (int i=3D1; i<3; i++) { @@ -42,3 +45,26 @@ * Array } return 0; #+end_src +* Matrix + :PROPERTIES: + :ID: cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5 + :END: +#+name: C-matrix +| 1 | 2 | +| 3 | 4 | + +#+source: list_var +#+begin_src cpp :var a=3D'("abc" "def") :includes "" :result= s silent + std::cout << a[0] << a[1] << sizeof(a)/sizeof(*a) << '\n'; +#+end_src + +#+source: vector_var +#+begin_src cpp :var a=3D'[1 2] :includes "" :results silent= + std::cout << a[0] << a[1] << sizeof(a)/sizeof(*a) << '\n'; +#+end_src + +#+source: list_list_var +#+begin_src cpp :var q=3DC-matrix :includes "" :results sile= nt + std::cout << q[0][0] << ' ' << q[1][0] << '\n' + << q[0][1] << ' ' << q[1][1] << '\n'; // transpose +#+end_src diff --git a/testing/lisp/test-ob-C.el b/testing/lisp/test-ob-C.el index 4243bb6..4430ceb 100644 --- a/testing/lisp/test-ob-C.el +++ b/testing/lisp/test-ob-C.el @@ -57,10 +57,26 @@ (ert-deftest ob-C/preprocessor () =20 (ert-deftest ob-C/table () "Test of a table output" - :expected-result :failed (org-test-at-id "2df1ab83-3fa3-462a-a1f3-3aef6044a874" (org-babel-next-src-block) (should (equal '((1) (2)) (org-babel-execute-src-block))))) =20 +(ert-deftest ob-C/list-var () +"Test of a list input variable" + (org-test-at-id "cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5" + (org-babel-next-src-block 1) + (should (string=3D "abcdef2" (org-babel-execute-src-block))))) + +(ert-deftest ob-C/vector-var () +"Test of a vector input variable" + (org-test-at-id "cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5" + (org-babel-next-src-block 2) + (should (equal 122 (org-babel-execute-src-block))))) + +(ert-deftest ob-C/list-list-var () + "Test of a list list input variable" + (org-test-at-id "cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5" + (org-babel-next-src-block 3) + (should (equal '((1 3) (2 4)) (org-babel-execute-src-block))))) + ;;; test-ob-C.el ends here -=20 --=20 1.8.3