emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* Patch for testing `org-open-at-point'
@ 2014-04-11  1:34 York Zhao
  2014-04-11  7:23 ` Nicolas Goaziou
  2014-04-11 10:25 ` Bastien
  0 siblings, 2 replies; 31+ messages in thread
From: York Zhao @ 2014-04-11  1:34 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 329 bytes --]

Hi,

I found a bug that `org-open-at-point' doesn't work if the link is a heading
property. This used to work and was broken recently. I have written a test for
this. The test is suppose to fail in current org-mode version. Please find
attached my patch for the test. Hopefully I I didn't place the test in the wrong
file.

York

[-- Attachment #2: 0001-test-org-element-Add-test-for-org-open-at-point-with.patch --]
[-- Type: text/x-diff, Size: 933 bytes --]

From df0788134a16baa9762616637c0fe7f568e3e63e Mon Sep 17 00:00:00 2001
From: York Zhao <gtdplatform@gmail.com>
Date: Thu, 10 Apr 2014 21:21:15 -0400
Subject: [PATCH] test-org-element: Add test for `org-open-at-point' with link
 being heading property.

---
 testing/lisp/test-org-element.el | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el
index 576e3d3..8cfceac 100644
--- a/testing/lisp/test-org-element.el
+++ b/testing/lisp/test-org-element.el
@@ -1461,6 +1461,15 @@ e^{i\\pi}+1=0
 	    (search-forward "file:")
 	    (org-element-property :type (org-element-context))))))
 
+(ert-deftest test-org-element/org-open-at-point ()
+  "Test `org-open-at-point' with link being a heading property."
+  (org-test-with-temp-text
+      "* Headline
+:PROPERTIES:
+:URL: <point>[[info:org#Top]]
+:END:"
+    (org-open-at-point)))
+
 
 ;;;; Macro
 
-- 
1.8.4


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: Patch for testing `org-open-at-point'
  2014-04-11  1:34 Patch for testing `org-open-at-point' York Zhao
@ 2014-04-11  7:23 ` Nicolas Goaziou
  2014-04-11 10:25 ` Bastien
  1 sibling, 0 replies; 31+ messages in thread
From: Nicolas Goaziou @ 2014-04-11  7:23 UTC (permalink / raw)
  To: York Zhao; +Cc: emacs-orgmode

Hello,

York Zhao <gtdplatform@gmail.com> writes:

> I found a bug that `org-open-at-point' doesn't work if the link is a heading
> property.

This is expected, as node properties cannot contain Org syntax.  See
also

  http://permalink.gmane.org/gmane.emacs.orgmode/84300


Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Patch for testing `org-open-at-point'
  2014-04-11  1:34 Patch for testing `org-open-at-point' York Zhao
  2014-04-11  7:23 ` Nicolas Goaziou
@ 2014-04-11 10:25 ` Bastien
  2014-04-12 14:22   ` York Zhao
  1 sibling, 1 reply; 31+ messages in thread
From: Bastien @ 2014-04-11 10:25 UTC (permalink / raw)
  To: York Zhao; +Cc: emacs-orgmode

Hi York,

York Zhao <gtdplatform@gmail.com> writes:

> I found a bug that `org-open-at-point' doesn't work if the link is a
> heading property.

This is a known issue and we will address it soon.

> This used to work and was broken recently. I have written a test for
> this. The test is suppose to fail in current org-mode version. Please find
> attached my patch for the test. Hopefully I I didn't place the test in the wrong
> file.

Let's add tests when they don't fail :)

-- 
 Bastien

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Patch for testing `org-open-at-point'
  2014-04-11 10:25 ` Bastien
@ 2014-04-12 14:22   ` York Zhao
  2014-04-17 18:48     ` Bastien
  0 siblings, 1 reply; 31+ messages in thread
From: York Zhao @ 2014-04-12 14:22 UTC (permalink / raw)
  To: Bastien; +Cc: emacs-orgmode

Hi Bastien,

Sorry that I didn't know this was a known issue and I appreciate that you are
willing to fix it.

While I agree with Nicolas that it is more appropriate to keep org schedule line
from being a headline property, I also think it is totally legitimate to have an
org link as headline property. Sure we can always move org links out of headline
properties, but I'm sure there are times we don't want to see some of the links
all the time, we really want to hide them inside the property tree. For example,
when we put a person's information as properties, like the following:

* Peter
:PROPERTIES:
:ADDRESS: xxx xxx xxxx xxxx
:HOME_PHONE: xxx xxx xxx
:WORK_PHONE: xxx xxx xxx
:URL: www.foo.bar
:END:

We hope we don't have to always move the link (the URL line in the properties
tree) out, i.e., we don't want to see the link all the time.

> Let's add tests when they don't fail :)

Fair enough, just make sure it will not be forgotten.

Thanks

On Fri, Apr 11, 2014 at 6:25 AM, Bastien <bzg@gnu.org> wrote:
> Hi York,
>
> York Zhao <gtdplatform@gmail.com> writes:
>
>> I found a bug that `org-open-at-point' doesn't work if the link is a
>> heading property.
>
> This is a known issue and we will address it soon.
>
>> This used to work and was broken recently. I have written a test for
>> this. The test is suppose to fail in current org-mode version. Please find
>> attached my patch for the test. Hopefully I I didn't place the test in the wrong
>> file.
>
> Let's add tests when they don't fail :)
>
> --
>  Bastien

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Patch for testing `org-open-at-point'
  2014-04-12 14:22   ` York Zhao
@ 2014-04-17 18:48     ` Bastien
  2014-04-20 19:19       ` Michael Strey
  2014-04-20 19:56       ` York Zhao
  0 siblings, 2 replies; 31+ messages in thread
From: Bastien @ 2014-04-17 18:48 UTC (permalink / raw)
  To: York Zhao; +Cc: emacs-orgmode

Hi York,

York Zhao <gtdplatform@gmail.com> writes:

> * Peter
> :PROPERTIES:
> :ADDRESS: xxx xxx xxxx xxxx
> :HOME_PHONE: xxx xxx xxx
> :WORK_PHONE: xxx xxx xxx
> :URL: www.foo.bar
> :END:

The question is this: are we fine handling raw links in properties,
or do we also need Org links (e.g. bracket links) there?

Speaking for me, raw links is enough, and this is what I plan to
implement.  But maybe other users have existing use-cases for Org
links there, I don't know.

-- 
 Bastien

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Patch for testing `org-open-at-point'
  2014-04-17 18:48     ` Bastien
@ 2014-04-20 19:19       ` Michael Strey
  2014-04-20 19:56       ` York Zhao
  1 sibling, 0 replies; 31+ messages in thread
From: Michael Strey @ 2014-04-20 19:19 UTC (permalink / raw)
  To: Bastien; +Cc: York Zhao, emacs-orgmode

Hi Bastien,

On 2014-04-17, Bastien wrote:
> The question is this: are we fine handling raw links in properties,
> or do we also need Org links (e.g. bracket links) there?
>
> Speaking for me, raw links is enough, and this is what I plan to
> implement.  But maybe other users have existing use-cases for Org
> links there, I don't know.

I have.  I'm using phone links (see
http://thread.gmane.org/gmane.emacs.orgmode/69406/focus=70484) in
conjunction with org-contacts in the properties of my contacts.

-- 
Michael Strey 
www.strey.biz

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Patch for testing `org-open-at-point'
  2014-04-17 18:48     ` Bastien
  2014-04-20 19:19       ` Michael Strey
@ 2014-04-20 19:56       ` York Zhao
  2014-06-01  1:12         ` York Zhao
  1 sibling, 1 reply; 31+ messages in thread
From: York Zhao @ 2014-04-20 19:56 UTC (permalink / raw)
  To: Bastien; +Cc: emacs-orgmode

Hi Bastien,

I apologize that I missed your reply, I discovered it until now when I was
checking the replies in the "Sent" folder.

> The question is this: are we fine handling raw links in properties,
> or do we also need Org links (e.g. bracket links) there?

To me, raw link is hardly useful because too often the web link is really long,
in which case the bracket link acts like a way of abstraction.

Thank you very much for considering this fix.

On Thu, Apr 17, 2014 at 2:48 PM, Bastien <bzg@gnu.org> wrote:
> Hi York,
>
> York Zhao <gtdplatform@gmail.com> writes:
>
>> * Peter
>> :PROPERTIES:
>> :ADDRESS: xxx xxx xxxx xxxx
>> :HOME_PHONE: xxx xxx xxx
>> :WORK_PHONE: xxx xxx xxx
>> :URL: www.foo.bar
>> :END:
>
> The question is this: are we fine handling raw links in properties,
> or do we also need Org links (e.g. bracket links) there?
>
> Speaking for me, raw links is enough, and this is what I plan to
> implement.  But maybe other users have existing use-cases for Org
> links there, I don't know.
>
> --
>  Bastien

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Patch for testing `org-open-at-point'
  2014-04-20 19:56       ` York Zhao
@ 2014-06-01  1:12         ` York Zhao
  2014-06-01  8:53           ` Bastien
  2014-06-01 20:15           ` Achim Gratz
  0 siblings, 2 replies; 31+ messages in thread
From: York Zhao @ 2014-06-01  1:12 UTC (permalink / raw)
  To: Bastien; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 1423 bytes --]

Hi Bastien,

Thank you very much for implementing this. Really appreciated. So do you think
it is a good idea to add my test (the patch) now for testing this?

For your convenience, I've attached again in this message the same patch I had
sent on April 10.

Thanks,

York


On Sun, Apr 20, 2014 at 3:56 PM, York Zhao <gtdplatform@gmail.com> wrote:
> Hi Bastien,
>
> I apologize that I missed your reply, I discovered it until now when I was
> checking the replies in the "Sent" folder.
>
>> The question is this: are we fine handling raw links in properties,
>> or do we also need Org links (e.g. bracket links) there?
>
> To me, raw link is hardly useful because too often the web link is really long,
> in which case the bracket link acts like a way of abstraction.
>
> Thank you very much for considering this fix.
>
> On Thu, Apr 17, 2014 at 2:48 PM, Bastien <bzg@gnu.org> wrote:
>> Hi York,
>>
>> York Zhao <gtdplatform@gmail.com> writes:
>>
>>> * Peter
>>> :PROPERTIES:
>>> :ADDRESS: xxx xxx xxxx xxxx
>>> :HOME_PHONE: xxx xxx xxx
>>> :WORK_PHONE: xxx xxx xxx
>>> :URL: www.foo.bar
>>> :END:
>>
>> The question is this: are we fine handling raw links in properties,
>> or do we also need Org links (e.g. bracket links) there?
>>
>> Speaking for me, raw links is enough, and this is what I plan to
>> implement.  But maybe other users have existing use-cases for Org
>> links there, I don't know.
>>
>> --
>>  Bastien

[-- Attachment #2: 0001-test-org-element-Add-test-for-org-open-at-point-with.patch --]
[-- Type: text/x-diff, Size: 933 bytes --]

From df0788134a16baa9762616637c0fe7f568e3e63e Mon Sep 17 00:00:00 2001
From: York Zhao <gtdplatform@gmail.com>
Date: Thu, 10 Apr 2014 21:21:15 -0400
Subject: [PATCH] test-org-element: Add test for `org-open-at-point' with link
 being heading property.

---
 testing/lisp/test-org-element.el | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el
index 576e3d3..8cfceac 100644
--- a/testing/lisp/test-org-element.el
+++ b/testing/lisp/test-org-element.el
@@ -1461,6 +1461,15 @@ e^{i\\pi}+1=0
 	    (search-forward "file:")
 	    (org-element-property :type (org-element-context))))))
 
+(ert-deftest test-org-element/org-open-at-point ()
+  "Test `org-open-at-point' with link being a heading property."
+  (org-test-with-temp-text
+      "* Headline
+:PROPERTIES:
+:URL: <point>[[info:org#Top]]
+:END:"
+    (org-open-at-point)))
+
 
 ;;;; Macro
 
-- 
1.8.4


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: Patch for testing `org-open-at-point'
  2014-06-01  1:12         ` York Zhao
@ 2014-06-01  8:53           ` Bastien
  2014-06-01 20:15           ` Achim Gratz
  1 sibling, 0 replies; 31+ messages in thread
From: Bastien @ 2014-06-01  8:53 UTC (permalink / raw)
  To: York Zhao; +Cc: emacs-orgmode

Hi York,

York Zhao <gtdplatform@gmail.com> writes:

> Thank you very much for implementing this. Really appreciated. So do you think
> it is a good idea to add my test (the patch) now for testing this?

Yes.

> For your convenience, I've attached again in this message the same patch I had
> sent on April 10.

Installed, thanks,

-- 
 Bastien

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Patch for testing `org-open-at-point'
  2014-06-01  1:12         ` York Zhao
  2014-06-01  8:53           ` Bastien
@ 2014-06-01 20:15           ` Achim Gratz
  2014-06-01 21:14             ` Bastien
  1 sibling, 1 reply; 31+ messages in thread
From: Achim Gratz @ 2014-06-01 20:15 UTC (permalink / raw)
  To: emacs-orgmode

York Zhao writes:
> Thank you very much for implementing this. Really appreciated. So do you think
> it is a good idea to add my test (the patch) now for testing this?

Shouldn't the test check that the desired target is actually reached?


Regards,
Achim.
-- 
+<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+

DIY Stuff:
http://Synth.Stromeko.net/DIY.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Patch for testing `org-open-at-point'
  2014-06-01 20:15           ` Achim Gratz
@ 2014-06-01 21:14             ` Bastien
  2014-06-01 21:58               ` babel C, C++, D enhancement Thierry Banel
  2014-06-02 19:13               ` Patch for testing `org-open-at-point' Achim Gratz
  0 siblings, 2 replies; 31+ messages in thread
From: Bastien @ 2014-06-01 21:14 UTC (permalink / raw)
  To: Achim Gratz; +Cc: emacs-orgmode

Achim Gratz <Stromeko@nexgo.de> writes:

> York Zhao writes:
>> Thank you very much for implementing this. Really appreciated. So do you think
>> it is a good idea to add my test (the patch) now for testing this?
>
> Shouldn't the test check that the desired target is actually
> reached?

That would be too complicated.  Checking that `org-open-at-point'
does not throw an error is enough IMO.

-- 
 Bastien

^ permalink raw reply	[flat|nested] 31+ messages in thread

* babel C, C++, D enhancement
  2014-06-01 21:14             ` Bastien
@ 2014-06-01 21:58               ` Thierry Banel
  2014-06-06 16:31                 ` Eric Schulte
  2014-06-02 19:13               ` Patch for testing `org-open-at-point' Achim Gratz
  1 sibling, 1 reply; 31+ messages in thread
From: Thierry Banel @ 2014-06-01 21:58 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 520 bytes --]

Hi Bastien, hi all

Here is a Babel enhancement for C, C++ and D languages
- support for non-homogeneous tables (mixing numerics and strings)
- support for table headers
- easier iterating over a table
- added some error handling
- new D support for simple lists and vectors
- new unit tests

Current documentation is here :
http://orgmode.org/worg/org-contrib/babel/languages/ob-doc-C.html
Draft of future documentation is here :
http://orgmode.org/worg/org-contrib/babel/languages/ob-doc-C-new.html

Have fun
Thierry


[-- Attachment #2: 0001-enhanced-table-handling-in-Babel-C-C-D.patch --]
[-- Type: text/x-diff, Size: 23727 bytes --]

From e66e6545776c0506a1f15db800dfe6424c6f997e Mon Sep 17 00:00:00 2001
From: Thierry Banel <tbanelwebmin@free.fr>
Date: Sun, 1 Jun 2014 23:30:20 +0200
Subject: [PATCH] enhanced table handling in Babel C, C++, D

---
 lisp/ob-C.el                   |  302 +++++++++++++++++++++++++++-------------
 testing/examples/ob-C-test.org |   88 ++++++++++++
 testing/lisp/test-ob-C.el      |  103 ++++++++++++--
 3 files changed, 384 insertions(+), 109 deletions(-)

diff --git a/lisp/ob-C.el b/lisp/ob-C.el
index 793981a..b1846de 100644
--- a/lisp/ob-C.el
+++ b/lisp/ob-C.el
@@ -34,8 +34,6 @@
   (require 'cl))
 (require 'ob)
 (require 'cc-mode)
-(eval-when-compile
-  (require 'cl))
 
 (declare-function org-entry-get "org"
 		  (pom property &optional inherit literal-nil))
@@ -72,40 +70,25 @@ This function calls `org-babel-execute:C++'."
 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) ;; unused
-;;  "Expand a block of C++ code with org-babel according to it's
-;;header arguments (calls `org-babel-C-expand')."
-;;  (let ((org-babel-c-variant 'cpp)) (org-babel-C-expand body params)))
-
 (defun org-babel-execute:D (body params)
   "Execute a block of D code with org-babel.
 This function is called by `org-babel-execute-src-block'."
   (let ((org-babel-c-variant 'd)) (org-babel-C-execute body params)))
 
-;; (defun org-babel-expand-body:D (body params) ;; unused
-;;  "Expand a block of D code with org-babel according to it's
-;;header arguments (calls `org-babel-C-expand')."
-;;  (let ((org-babel-c-variant 'd)) (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'."
   (let ((org-babel-c-variant 'c)) (org-babel-C-execute body params)))
 
-;; (defun org-babel-expand-body:c (body params) ;; unused
-;;  "Expand a block of C code with org-babel according to it's
-;;header arguments (calls `org-babel-C-expand')."
-;;  (let ((org-babel-c-variant 'c)) (org-babel-C-expand body params)))
-
 (defun org-babel-C-execute (body params)
   "This function should only be called by `org-babel-execute:C'
 or `org-babel-execute:C++' or `org-babel-execute:D'."
   (let* ((tmp-src-file (org-babel-temp-file
 			"C-src-"
-			(cond
-			 ((equal org-babel-c-variant 'c  ) ".c"  )
-			 ((equal org-babel-c-variant 'cpp) ".cpp")
-			 ((equal org-babel-c-variant 'd  ) ".d"  ))))
+			(case org-babel-c-variant
+			 (c   ".c"  )
+			 (cpp ".cpp")
+			 (d   ".d"  ))))
 	 (tmp-bin-file (org-babel-temp-file "C-bin-" org-babel-exeext)) ;; not used for D
 	 (cmdline (cdr (assoc :cmdline params)))
 	 (cmdline (if cmdline (concat " " cmdline) ""))
@@ -113,43 +96,62 @@ or `org-babel-execute:C++' or `org-babel-execute:D'."
 	 (flags (mapconcat 'identity
 			   (if (listp flags) flags (list flags)) " "))
 	 (full-body
-	  (cond ((equal org-babel-c-variant 'c  ) (org-babel-C-expand-C   body params))
-		((equal org-babel-c-variant 'cpp) (org-babel-C-expand-C++ body params))
-		((equal org-babel-c-variant 'd  ) (org-babel-C-expand-D   body params)))))
+	  (case org-babel-c-variant
+	    (c   (org-babel-C-expand-C   body params))
+	    (cpp (org-babel-C-expand-C++ body params))
+	    (d   (org-babel-C-expand-D   body params)))))
     (with-temp-file tmp-src-file (insert full-body))
-    (if (memq org-babel-c-variant '(c cpp)) ;; no separate compilation for D
-	(org-babel-eval
-	 (format "%s -o %s %s %s"
-		 (cond
-		  ((equal org-babel-c-variant 'c  ) org-babel-C-compiler)
-		  ((equal org-babel-c-variant 'cpp) org-babel-C++-compiler))
-		 (org-babel-process-file-name tmp-bin-file)
-		 flags
-		 (org-babel-process-file-name tmp-src-file)) ""))
+    (case org-babel-c-variant
+      ((c cpp)
+       (org-babel-eval
+	(format "%s -o %s %s %s"
+		(case org-babel-c-variant
+		 (c   org-babel-C-compiler)
+		 (cpp org-babel-C++-compiler))
+		(org-babel-process-file-name tmp-bin-file)
+		flags
+		(org-babel-process-file-name tmp-src-file)) ""))
+      (d nil)) ;; no separate compilation for D
     (let ((results
-	   (org-babel-trim
-	    (org-remove-indentation
-	     (org-babel-eval
-	      (cond ((memq org-babel-c-variant '(c cpp))
-		     (concat tmp-bin-file cmdline))
-		    ((equal org-babel-c-variant 'd)
-		     (format "%s %s %s %s"
-			     org-babel-D-compiler
-			     flags
-			     (org-babel-process-file-name tmp-src-file)
-			     cmdline)))
-	      "")))))
-      (org-babel-reassemble-table
-       (org-babel-result-cond (cdr (assoc :result-params params))
-	 (org-babel-read results t)
-	 (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
-	(cdr (assoc :rowname-names params)) (cdr (assoc :rownames params)))))
-    ))
+	   (org-babel-eval
+	    (case org-babel-c-variant
+	      ((c cpp)
+	       (concat tmp-bin-file cmdline))
+	      (d
+	       (format "%s %s %s %s"
+		       org-babel-D-compiler
+		       flags
+		       (org-babel-process-file-name tmp-src-file)
+		       cmdline)))
+	    "")))
+      (when results
+	(setq results (org-babel-trim (org-remove-indentation results)))
+	(org-babel-reassemble-table
+	 (org-babel-result-cond (cdr (assoc :result-params params))
+	   (org-babel-read results t)
+	   (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
+	  (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params)))))
+      )))
+
+(defun org-babel-expand-body:C++ (body params)
+  "Expand a block of C++ code with org-babel according to it's
+header arguments."
+  (let ((org-babel-c-variant 'cpp)) (org-babel-C-expand-C++ body params)))
+
+(defun org-babel-expand-body:C (body params)
+  "Expand a block of C code with org-babel according to it's
+header arguments."
+  (let ((org-babel-c-variant 'c)) (org-babel-C-expand-C body params)))
+
+(defun org-babel-expand-body:D (body params)
+  "Expand a block of D code with org-babel according to it's
+header arguments."
+  (let ((org-babel-c-variant 'd)) (org-babel-C-expand-D body params)))
 
 (defun org-babel-C-expand-C++ (body params)
   "Expand a block of C or C++ code with org-babel according to
@@ -160,24 +162,34 @@ it's header arguments."
   "Expand a block of C or C++ code with org-babel according to
 it's header arguments."
   (let ((vars (mapcar #'cdr (org-babel-get-header params :var)))
+	(colnames (cdar (org-babel-get-header params :colname-names)))
 	(main-p (not (string= (cdr (assoc :main params)) "no")))
 	(includes (or (cdr (assoc :includes params))
 		      (org-babel-read (org-entry-get nil "includes" t))))
 	(defines (org-babel-read
 		  (or (cdr (assoc :defines params))
 		      (org-babel-read (org-entry-get nil "defines" t))))))
+    (unless (listp includes) (setq includes (list includes)))
+    (setq includes (append includes '("<string.h>" "<stdio.h>" "<stdlib.h>")))
     (mapconcat 'identity
 	       (list
 		;; includes
 		(mapconcat
 		 (lambda (inc) (format "#include %s" inc))
-		 (if (listp includes) includes (list includes)) "\n")
+		 includes "\n")
 		;; defines
 		(mapconcat
 		 (lambda (inc) (format "#define %s" inc))
 		 (if (listp defines) defines (list defines)) "\n")
 		;; variables
 		(mapconcat 'org-babel-C-var-to-C vars "\n")
+		;; table sizes
+		(mapconcat 'org-babel-C-table-sizes-to-C vars "\n")
+		;; tables headers utility
+		(when colnames
+		  (org-babel-C-utility-header-to-C))
+		;; tables headers
+		(mapconcat 'org-babel-C-header-to-C colnames "\n")
 		;; body
 		(if main-p
 		    (org-babel-C-ensure-main-wrap body)
@@ -187,18 +199,28 @@ it's header arguments."
   "Expand a block of D code with org-babel according to
 it's header arguments."
   (let ((vars (mapcar #'cdr (org-babel-get-header params :var)))
+	(colnames (cdar (org-babel-get-header params :colname-names)))
 	(main-p (not (string= (cdr (assoc :main params)) "no")))
 	(imports (or (cdr (assoc :imports params))
 		     (org-babel-read (org-entry-get nil "imports" t)))))
+    (unless (listp imports) (setq imports (list imports)))
+    (setq imports (append imports '("std.stdio" "std.conv")))
     (mapconcat 'identity
 	       (list
 		"module mmm;"
 		;; imports
 		(mapconcat
 		 (lambda (inc) (format "import %s;" inc))
-		 (if (listp imports) imports (list imports)) "\n")
+		 imports "\n")
 		;; variables
 		(mapconcat 'org-babel-C-var-to-C vars "\n")
+		;; table sizes
+		(mapconcat 'org-babel-C-table-sizes-to-C vars "\n")
+		;; tables headers utility
+		(when colnames
+		  (org-babel-C-utility-header-to-C))
+		;; tables headers
+		(mapconcat 'org-babel-C-header-to-C colnames "\n")
 		;; body
 		(if main-p
 		    (org-babel-C-ensure-main-wrap body)
@@ -229,50 +251,72 @@ support for sessions"
 	(cons "" (format format-data val))
       (funcall format-data val))))
 
+(defun org-babel-C-val-to-base-type (val)
+  "Determine the base type of VAL which may be
+'integerp if all base values are integers
+'floatp if all base values are either floating points or integers
+'stringp otherwise."
+  (cond
+   ((integerp val) 'integerp)
+   ((floatp val) 'floatp)
+   ((or (listp val) (vectorp val))
+    (let ((type nil))
+      (mapc (lambda (v)
+	      (case (org-babel-C-val-to-base-type v)
+		(stringp (setq type 'stringp))
+		(floatp
+		 (if (or (not type) (eq type 'integerp))
+		     (setq type 'floatp)))
+		(integerp
+		 (unless type (setq type 'integerp)))))
+	    val)
+      type))
+   (t 'stringp)))
+
 (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 (if (equal org-babel-c-variant 'd) "[ " "{ ")
-		       (mapconcat (lambda (v)
-				    (cdr (org-babel-C-format-val type v)))
-				  val
-				  ", ")
-		       (if (equal org-babel-c-variant 'd) " ]" " }")))))))
-   (t ;; treat unknown types as string
-    (list
-     (if (equal org-babel-c-variant 'd) "string" "const char*")
-     "\"%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))
+  (let* ((basetype (org-babel-C-val-to-base-type val))
+	 (type
+	  (case basetype
+	    (integerp '("int" "%d"))
+	    (floatp '("double" "%f"))
+	    (stringp
+	     (list
+	      (if (equal org-babel-c-variant 'd) "string" "const char*")
+	      "\"%s\""))
+	    (t (error "unknown type %S" type)))))
+    (cond
+     ((integerp val) type) ;; an integer declared in the #+begin_src line
+     ((floatp val) type) ;; a numeric declared in the #+begin_src line
+     ((and (listp val) (listp (car val))) ;; a table
+      `(,(car type)
+	(lambda (val)
+	  (cons
+	   (format "[%d][%d]" (length val) (length (car val)))
+	   (concat
+	    (if (equal org-babel-c-variant 'd) "[\n" "{\n")
+	    (mapconcat
+	     (lambda (v)
+	       (concat
+		(if (equal org-babel-c-variant 'd) " [" " {")
+		(mapconcat (lambda (w) (format ,(cadr type) w)) v ",")
+		(if (equal org-babel-c-variant 'd) "]" "}")))
+	     val
+	     ",\n")
+	    (if (equal org-babel-c-variant 'd) "\n]" "\n}"))))))
+     ((or (listp val) (vectorp val)) ;; a list declared in the #+begin_src line
+      `(,(car type)
+	(lambda (val)
+	  (cons
+	   (format "[%d]" (length val))
+	   (concat
+	    (if (equal org-babel-c-variant 'd) "[" "{")
+	    (mapconcat (lambda (v) (format ,(cadr type) v)) val ",")
+	    (if (equal org-babel-c-variant 'd) "]" "}"))))))
+     (t ;; treat unknown types as string
+      type))))
 
 (defun org-babel-C-var-to-C (pair)
   "Convert an elisp val into a string of C code specifying a var
@@ -295,6 +339,68 @@ of the same value."
 	      suffix
 	      data))))
 
+(defun org-babel-C-table-sizes-to-C (pair)
+  "Create constants of table dimensions, if PAIR is a table."
+  (when (listp (cdr pair))
+    (cond
+     ((listp (cadr pair)) ;; a table
+      (concat
+       (format "const int %s_rows = %d;" (car pair) (length (cdr pair)))
+       "\n"
+       (format "const int %s_cols = %d;" (car pair) (length (cadr pair)))))
+     (t ;; a list declared in the #+begin_src line
+      (format "const int %s_cols = %d;" (car pair) (length (cdr pair)))))))
+
+(defun org-babel-C-utility-header-to-C ()
+  "Generate a utility function to convert a column name
+into a column number."
+  (case org-babel-c-variant
+    ((c cpp)
+     "int get_column_num (int nbcols, const char** header, const char* column)
+{
+  int c;
+  for (c=0; c<nbcols; c++)
+    if (strcmp(header[c],column)==0)
+      return c;
+  return -1;
+}
+"
+     )
+    (d
+     "int get_column_num (string[] header, string column)
+{
+  foreach (c, h; header)
+    if (h==column)
+      return to!int(c);
+  return -1;
+}
+"
+     )))
+
+(defun org-babel-C-header-to-C (head)
+  "Convert an elisp list of header table into a C or D vector
+specifying a variable with the name of the table."
+  (let ((table (car head))
+        (headers (cdr head)))
+    (concat
+     (format
+      (case org-babel-c-variant
+	((c cpp) "const char* %s_header[%d] = {%s};")
+	(d       "string %s_header[%d] = [%s];"))
+      table
+      (length headers)
+      (mapconcat (lambda (h) (format "%S" h)) headers ","))
+     "\n"
+     (case org-babel-c-variant
+       ((c cpp)
+	(format
+	 "const char* %s_h (int row, const char* col) { return %s[row][get_column_num(%d,%s_header,col)]; }"
+	 table table (length headers) table))
+       (d
+	(format
+	 "string %s_h (ulong row, string col) { return %s[row][get_column_num(%s_header,col)]; }"
+	 table table table))))))
+
 (provide 'ob-C)
 
 ;;; ob-C.el ends here
diff --git a/testing/examples/ob-C-test.org b/testing/examples/ob-C-test.org
index 1d0a83f..a8c485d 100644
--- a/testing/examples/ob-C-test.org
+++ b/testing/examples/ob-C-test.org
@@ -10,24 +10,44 @@
   return 0;
 #+end_src
 
+#+source: simple
+#+begin_src D :results silent
+  writefln ("%s", 42);
+#+end_src
+
 #+source: integer_var
 #+begin_src cpp :var q=12 :includes "<iostream>" :results silent
   std::cout << q;
   return 0;
 #+end_src
 
+#+source: integer_var
+#+begin_src D :var q=12 :results silent
+  writefln ("%s", q);
+#+end_src
+
 #+source: two_var
 #+begin_src cpp :var q=12 :var p=10 :includes "<iostream>" :results silent
   std::cout << p+q;
   return 0;
 #+end_src
 
+#+source: two_var
+#+begin_src D :var q=12 :var p=10 :results silent
+  writefln ("%s", p+q);
+#+end_src
+
 #+source: string_var
 #+begin_src cpp :var q="word" :includes '(<iostream> <cstring>) :results silent
   std::cout << q << ' ' << std::strlen(q);
   return 0;
 #+end_src
 
+#+source: string_var
+#+begin_src D :var q="word" :results silent
+  writefln ("%s %s", q, q.length);
+#+end_src
+
 #+source: define
 #+begin_src cpp :defines N 42  :includes "<iostream>" :results silent
   std::cout << N;
@@ -45,6 +65,13 @@
   }
   return 0;
 #+end_src
+
+#+source: array
+#+begin_src D :results vector :results silent
+  foreach (i; 1..3)
+    writefln ("%s", i);
+#+end_src
+
 * Matrix
   :PROPERTIES:
   :ID:       cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5
@@ -58,13 +85,74 @@
   std::cout << a[0] << a[1] << sizeof(a)/sizeof(*a) << '\n';
 #+end_src
 
+#+source: list_var
+#+begin_src D :var a='("abc" "def") :results silent
+  writefln ("%s%s%s", a[0], a[1], a.length);
+#+end_src
+
 #+source: vector_var
 #+begin_src cpp :var a='[1 2] :includes "<iostream>" :results silent
   std::cout << a[0] << a[1] << sizeof(a)/sizeof(*a) << '\n';
 #+end_src
 
+#+source: vector_var
+#+begin_src D :var a='[1 2] :results silent
+  writefln ("%s%s%s", a[0], a[1], a.length);
+#+end_src
+
 #+source: list_list_var
 #+begin_src cpp :var q=C-matrix :includes "<iostream>" :results silent
   std::cout << q[0][0] << ' ' << q[1][0] << '\n'
             << q[0][1] << ' ' << q[1][1] << '\n'; // transpose
 #+end_src
+
+#+source: list_list_var
+#+begin_src D :var q=C-matrix :results silent
+  writefln ("%s %s", q[0][0], q[1][0]);
+  writefln ("%s %s", q[0][1], q[1][1]); // transpose
+#+end_src
+
+* Inhomogeneous table
+  :PROPERTIES:
+  :ID:       e112bc2e-419a-4890-99c2-7ac4779531cc
+  :END:
+
+#+tblname: tinomogen
+  | day       | quty |
+  |-----------+------|
+  | monday    |   34 |
+  | tuesday   |   41 |
+  | wednesday |   56 |
+  | thursday  |   17 |
+  | friday    |   12 |
+  | saturday  |    7 |
+  | sunday    |    4 |
+
+#+source: inhomogeneous_table
+#+BEGIN_SRC C :var tinomogen=tinomogen :results silent
+int main()
+{
+  int i, j;
+  for (i=0; i<tinomogen_rows; i++) {
+    for (j=0; j<tinomogen_cols; j++)
+      printf ("%s ", tinomogen[i][j]);
+    printf ("\n");
+  }
+  printf ("Friday %s\n", tinomogen_h(4,"day"));
+  return 0;
+}
+#+END_SRC
+
+#+source: inhomogeneous_table
+#+BEGIN_SRC D :var tinomogen=tinomogen :results silent
+import std.stdio;
+void main()
+{
+  for (int i=0; i<tinomogen_rows; i++) {
+    for (int j=0; j<tinomogen_cols; j++)
+      writef ("%s ", tinomogen[i][j]);
+    writeln();
+  }
+  writefln ("Friday %s\n", tinomogen_h(4,"day"));
+}
+#+END_SRC
diff --git a/testing/lisp/test-ob-C.el b/testing/lisp/test-ob-C.el
index 42e4dd2..2cc07fc 100644
--- a/testing/lisp/test-ob-C.el
+++ b/testing/lisp/test-ob-C.el
@@ -1,7 +1,7 @@
-;;; test-ob-awk.el --- tests for ob-awk.el
+;;; test-ob-C.el --- tests for ob-C.el
 
-;; Copyright (c) 2010-2014 Sergey Litvinov
-;; Authors: Sergey Litvinov
+;; Copyright (c) 2010-2014 Sergey Litvinov, Thierry Banel
+;; Authors: Sergey Litvinov, Thierry Banel
 
 ;; This file is not part of GNU Emacs.
 
@@ -28,55 +28,136 @@
 (ert-deftest ob-C/simple-program ()
   "Hello world program."
   (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
-    (org-babel-next-src-block)
+    (org-babel-next-src-block 1)
+    (should (= 42 (org-babel-execute-src-block)))))
+
+(ert-deftest ob-D/simple-program ()
+  "Hello world program."
+  (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
+    (org-babel-next-src-block 2)
     (should (= 42 (org-babel-execute-src-block)))))
 
 (ert-deftest ob-C/integer-var ()
   "Test of an integer variable."
   (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
-    (org-babel-next-src-block 2)
+    (org-babel-next-src-block 3)
+    (should (= 12 (org-babel-execute-src-block)))))
+
+(ert-deftest ob-D/integer-var ()
+  "Test of an integer variable."
+  (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
+    (org-babel-next-src-block 4)
     (should (= 12 (org-babel-execute-src-block)))))
 
 (ert-deftest ob-C/two-integer-var ()
   "Test of two input variables"
   (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
-    (org-babel-next-src-block 3)
+    (org-babel-next-src-block 5)
+    (should (= 22 (org-babel-execute-src-block)))))
+
+(ert-deftest ob-D/two-integer-var ()
+  "Test of two input variables"
+  (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
+    (org-babel-next-src-block 6)
     (should (= 22 (org-babel-execute-src-block)))))
 
 (ert-deftest ob-C/string-var ()
   "Test of a string input variable"
   (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
-    (org-babel-next-src-block 4)
+    (org-babel-next-src-block 7)
+    (should (equal "word 4" (org-babel-execute-src-block)))))
+
+(ert-deftest ob-D/string-var ()
+  "Test of a string input variable"
+  (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
+    (org-babel-next-src-block 8)
     (should (equal "word 4" (org-babel-execute-src-block)))))
 
 (ert-deftest ob-C/preprocessor ()
   "Test of a string variable"
   (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
-    (org-babel-next-src-block 5)
+    (org-babel-next-src-block 9)
     (should (= 42 (org-babel-execute-src-block)))))
 
+
 (ert-deftest ob-C/table ()
   "Test of a table output"
   (org-test-at-id "2df1ab83-3fa3-462a-a1f3-3aef6044a874"
-    (org-babel-next-src-block)
+    (org-babel-next-src-block 1)
     (should (equal '((1) (2)) (org-babel-execute-src-block)))))
 
+(ert-deftest ob-D/table ()
+  "Test of a table output"
+  (org-test-at-id "2df1ab83-3fa3-462a-a1f3-3aef6044a874"
+    (org-babel-next-src-block 2)
+    (should (equal '((1) (2)) (org-babel-execute-src-block)))))
+
+
 (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= "abcdef2" (org-babel-execute-src-block)))))
 
+(ert-deftest ob-D/list-var ()
+"Test of a list input variable"
+  (org-test-at-id "cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5"
+    (org-babel-next-src-block 2)
+    (should (string= "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)
+    (org-babel-next-src-block 3)
+    (should (equal 122 (org-babel-execute-src-block)))))
+
+(ert-deftest ob-D/vector-var ()
+"Test of a vector input variable"
+  (org-test-at-id "cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5"
+    (org-babel-next-src-block 4)
     (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)
+    (org-babel-next-src-block 5)
     (should (equal '((1 3) (2 4)) (org-babel-execute-src-block)))))
 
+(ert-deftest ob-D/list-list-var ()
+  "Test of a list list input variable"
+  (org-test-at-id "cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5"
+    (org-babel-next-src-block 6)
+    (should (equal '((1 3) (2 4)) (org-babel-execute-src-block)))))
+
+
+(ert-deftest ob-C/inhomogeneous_table ()
+  "Test inhomogeneous input table"
+  (org-test-at-id "e112bc2e-419a-4890-99c2-7ac4779531cc"
+    (org-babel-next-src-block 1)
+    (should (equal
+	     '(("monday" 34)
+	       ("tuesday" 41)
+	       ("wednesday" 56)
+	       ("thursday" 17)
+	       ("friday" 12)
+	       ("saturday" 7)
+	       ("sunday" 4)
+	       ("Friday" "friday"))
+	     (org-babel-execute-src-block)))))
+
+(ert-deftest ob-D/inhomogeneous_table ()
+  "Test inhomogeneous input table"
+  (org-test-at-id "e112bc2e-419a-4890-99c2-7ac4779531cc"
+    (org-babel-next-src-block 2)
+    (should (equal
+	     '(("monday" 34)
+	       ("tuesday" 41)
+	       ("wednesday" 56)
+	       ("thursday" 17)
+	       ("friday" 12)
+	       ("saturday" 7)
+	       ("sunday" 4)
+	       ("Friday" "friday"))
+	     (org-babel-execute-src-block)))))
+
 ;;; test-ob-C.el ends here
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: Patch for testing `org-open-at-point'
  2014-06-01 21:14             ` Bastien
  2014-06-01 21:58               ` babel C, C++, D enhancement Thierry Banel
@ 2014-06-02 19:13               ` Achim Gratz
  2014-06-03  7:22                 ` Bastien
  1 sibling, 1 reply; 31+ messages in thread
From: Achim Gratz @ 2014-06-02 19:13 UTC (permalink / raw)
  To: emacs-orgmode

Bastien writes:
> Achim Gratz <Stromeko@nexgo.de> writes:
>> Shouldn't the test check that the desired target is actually
>> reached?
>
> That would be too complicated.  Checking that `org-open-at-point'
> does not throw an error is enough IMO.

I don't think so.  Implemented a check for that in 8e72c8fcfa.


Regards,
Achim.
-- 
+<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+

Factory and User Sound Singles for Waldorf Blofeld:
http://Synth.Stromeko.net/Downloads.html#WaldorfSounds

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Patch for testing `org-open-at-point'
  2014-06-02 19:13               ` Patch for testing `org-open-at-point' Achim Gratz
@ 2014-06-03  7:22                 ` Bastien
  0 siblings, 0 replies; 31+ messages in thread
From: Bastien @ 2014-06-03  7:22 UTC (permalink / raw)
  To: Achim Gratz; +Cc: emacs-orgmode

Hi Achim,

Achim Gratz <Stromeko@nexgo.de> writes:

> Bastien writes:
>> Achim Gratz <Stromeko@nexgo.de> writes:
>>> Shouldn't the test check that the desired target is actually
>>> reached?
>>
>> That would be too complicated.  Checking that `org-open-at-point'
>> does not throw an error is enough IMO.
>
> I don't think so.  Implemented a check for that in 8e72c8fcfa.

Okay, thanks.  I pushed a small update, separating tests where we test
that `org-open-at-point' correctly opens the link at point, and tests
where we only tests that it correctly runs in a specific context.

-- 
 Bastien

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: babel C, C++, D enhancement
  2014-06-01 21:58               ` babel C, C++, D enhancement Thierry Banel
@ 2014-06-06 16:31                 ` Eric Schulte
  2014-06-07 18:19                   ` Thierry Banel
  2014-06-08 20:19                   ` Thierry Banel
  0 siblings, 2 replies; 31+ messages in thread
From: Eric Schulte @ 2014-06-06 16:31 UTC (permalink / raw)
  To: Thierry Banel; +Cc: emacs-orgmode

Hi Thierry,

This looks wonderful, however after applying this patch I get the
following errors when running "make test-dirty".

> 10 unexpected results:
>    FAILED  ob-C/inhomogeneous_table
>    FAILED  ob-D/inhomogeneous_table
>    FAILED  ob-D/integer-var
>    FAILED  ob-D/list-list-var
>    FAILED  ob-D/list-var
>    FAILED  ob-D/simple-program
>    FAILED  ob-D/string-var
>    FAILED  ob-D/table
>    FAILED  ob-D/two-integer-var
>    FAILED  ob-D/vector-var

Could you update the test suite so that the C tests pass, and the D
tests are not executed when D is not available?

Also, could you flesh out the commit message so that it meets the Emacs
commit message guidelines (http://orgmode.org/worg/org-contribute.html)?

Many Thanks,
Eric

Thierry Banel <tbanelwebmin@free.fr> writes:

> Hi Bastien, hi all
>
> Here is a Babel enhancement for C, C++ and D languages
> - support for non-homogeneous tables (mixing numerics and strings)
> - support for table headers
> - easier iterating over a table
> - added some error handling
> - new D support for simple lists and vectors
> - new unit tests
>
> Current documentation is here :
> http://orgmode.org/worg/org-contrib/babel/languages/ob-doc-C.html
> Draft of future documentation is here :
> http://orgmode.org/worg/org-contrib/babel/languages/ob-doc-C-new.html
>
> Have fun
> Thierry
>
>
> From e66e6545776c0506a1f15db800dfe6424c6f997e Mon Sep 17 00:00:00 2001
> From: Thierry Banel <tbanelwebmin@free.fr>
> Date: Sun, 1 Jun 2014 23:30:20 +0200
> Subject: [PATCH] enhanced table handling in Babel C, C++, D
>
> ---
>  lisp/ob-C.el                   |  302 +++++++++++++++++++++++++++-------------
>  testing/examples/ob-C-test.org |   88 ++++++++++++
>  testing/lisp/test-ob-C.el      |  103 ++++++++++++--
>  3 files changed, 384 insertions(+), 109 deletions(-)
>
> diff --git a/lisp/ob-C.el b/lisp/ob-C.el
> index 793981a..b1846de 100644
> --- a/lisp/ob-C.el
> +++ b/lisp/ob-C.el
> @@ -34,8 +34,6 @@
>    (require 'cl))
>  (require 'ob)
>  (require 'cc-mode)
> -(eval-when-compile
> -  (require 'cl))
>  
>  (declare-function org-entry-get "org"
>  		  (pom property &optional inherit literal-nil))
> @@ -72,40 +70,25 @@ This function calls `org-babel-execute:C++'."
>  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) ;; unused
> -;;  "Expand a block of C++ code with org-babel according to it's
> -;;header arguments (calls `org-babel-C-expand')."
> -;;  (let ((org-babel-c-variant 'cpp)) (org-babel-C-expand body params)))
> -
>  (defun org-babel-execute:D (body params)
>    "Execute a block of D code with org-babel.
>  This function is called by `org-babel-execute-src-block'."
>    (let ((org-babel-c-variant 'd)) (org-babel-C-execute body params)))
>  
> -;; (defun org-babel-expand-body:D (body params) ;; unused
> -;;  "Expand a block of D code with org-babel according to it's
> -;;header arguments (calls `org-babel-C-expand')."
> -;;  (let ((org-babel-c-variant 'd)) (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'."
>    (let ((org-babel-c-variant 'c)) (org-babel-C-execute body params)))
>  
> -;; (defun org-babel-expand-body:c (body params) ;; unused
> -;;  "Expand a block of C code with org-babel according to it's
> -;;header arguments (calls `org-babel-C-expand')."
> -;;  (let ((org-babel-c-variant 'c)) (org-babel-C-expand body params)))
> -
>  (defun org-babel-C-execute (body params)
>    "This function should only be called by `org-babel-execute:C'
>  or `org-babel-execute:C++' or `org-babel-execute:D'."
>    (let* ((tmp-src-file (org-babel-temp-file
>  			"C-src-"
> -			(cond
> -			 ((equal org-babel-c-variant 'c  ) ".c"  )
> -			 ((equal org-babel-c-variant 'cpp) ".cpp")
> -			 ((equal org-babel-c-variant 'd  ) ".d"  ))))
> +			(case org-babel-c-variant
> +			 (c   ".c"  )
> +			 (cpp ".cpp")
> +			 (d   ".d"  ))))
>  	 (tmp-bin-file (org-babel-temp-file "C-bin-" org-babel-exeext)) ;; not used for D
>  	 (cmdline (cdr (assoc :cmdline params)))
>  	 (cmdline (if cmdline (concat " " cmdline) ""))
> @@ -113,43 +96,62 @@ or `org-babel-execute:C++' or `org-babel-execute:D'."
>  	 (flags (mapconcat 'identity
>  			   (if (listp flags) flags (list flags)) " "))
>  	 (full-body
> -	  (cond ((equal org-babel-c-variant 'c  ) (org-babel-C-expand-C   body params))
> -		((equal org-babel-c-variant 'cpp) (org-babel-C-expand-C++ body params))
> -		((equal org-babel-c-variant 'd  ) (org-babel-C-expand-D   body params)))))
> +	  (case org-babel-c-variant
> +	    (c   (org-babel-C-expand-C   body params))
> +	    (cpp (org-babel-C-expand-C++ body params))
> +	    (d   (org-babel-C-expand-D   body params)))))
>      (with-temp-file tmp-src-file (insert full-body))
> -    (if (memq org-babel-c-variant '(c cpp)) ;; no separate compilation for D
> -	(org-babel-eval
> -	 (format "%s -o %s %s %s"
> -		 (cond
> -		  ((equal org-babel-c-variant 'c  ) org-babel-C-compiler)
> -		  ((equal org-babel-c-variant 'cpp) org-babel-C++-compiler))
> -		 (org-babel-process-file-name tmp-bin-file)
> -		 flags
> -		 (org-babel-process-file-name tmp-src-file)) ""))
> +    (case org-babel-c-variant
> +      ((c cpp)
> +       (org-babel-eval
> +	(format "%s -o %s %s %s"
> +		(case org-babel-c-variant
> +		 (c   org-babel-C-compiler)
> +		 (cpp org-babel-C++-compiler))
> +		(org-babel-process-file-name tmp-bin-file)
> +		flags
> +		(org-babel-process-file-name tmp-src-file)) ""))
> +      (d nil)) ;; no separate compilation for D
>      (let ((results
> -	   (org-babel-trim
> -	    (org-remove-indentation
> -	     (org-babel-eval
> -	      (cond ((memq org-babel-c-variant '(c cpp))
> -		     (concat tmp-bin-file cmdline))
> -		    ((equal org-babel-c-variant 'd)
> -		     (format "%s %s %s %s"
> -			     org-babel-D-compiler
> -			     flags
> -			     (org-babel-process-file-name tmp-src-file)
> -			     cmdline)))
> -	      "")))))
> -      (org-babel-reassemble-table
> -       (org-babel-result-cond (cdr (assoc :result-params params))
> -	 (org-babel-read results t)
> -	 (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
> -	(cdr (assoc :rowname-names params)) (cdr (assoc :rownames params)))))
> -    ))
> +	   (org-babel-eval
> +	    (case org-babel-c-variant
> +	      ((c cpp)
> +	       (concat tmp-bin-file cmdline))
> +	      (d
> +	       (format "%s %s %s %s"
> +		       org-babel-D-compiler
> +		       flags
> +		       (org-babel-process-file-name tmp-src-file)
> +		       cmdline)))
> +	    "")))
> +      (when results
> +	(setq results (org-babel-trim (org-remove-indentation results)))
> +	(org-babel-reassemble-table
> +	 (org-babel-result-cond (cdr (assoc :result-params params))
> +	   (org-babel-read results t)
> +	   (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
> +	  (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params)))))
> +      )))
> +
> +(defun org-babel-expand-body:C++ (body params)
> +  "Expand a block of C++ code with org-babel according to it's
> +header arguments."
> +  (let ((org-babel-c-variant 'cpp)) (org-babel-C-expand-C++ body params)))
> +
> +(defun org-babel-expand-body:C (body params)
> +  "Expand a block of C code with org-babel according to it's
> +header arguments."
> +  (let ((org-babel-c-variant 'c)) (org-babel-C-expand-C body params)))
> +
> +(defun org-babel-expand-body:D (body params)
> +  "Expand a block of D code with org-babel according to it's
> +header arguments."
> +  (let ((org-babel-c-variant 'd)) (org-babel-C-expand-D body params)))
>  
>  (defun org-babel-C-expand-C++ (body params)
>    "Expand a block of C or C++ code with org-babel according to
> @@ -160,24 +162,34 @@ it's header arguments."
>    "Expand a block of C or C++ code with org-babel according to
>  it's header arguments."
>    (let ((vars (mapcar #'cdr (org-babel-get-header params :var)))
> +	(colnames (cdar (org-babel-get-header params :colname-names)))
>  	(main-p (not (string= (cdr (assoc :main params)) "no")))
>  	(includes (or (cdr (assoc :includes params))
>  		      (org-babel-read (org-entry-get nil "includes" t))))
>  	(defines (org-babel-read
>  		  (or (cdr (assoc :defines params))
>  		      (org-babel-read (org-entry-get nil "defines" t))))))
> +    (unless (listp includes) (setq includes (list includes)))
> +    (setq includes (append includes '("<string.h>" "<stdio.h>" "<stdlib.h>")))
>      (mapconcat 'identity
>  	       (list
>  		;; includes
>  		(mapconcat
>  		 (lambda (inc) (format "#include %s" inc))
> -		 (if (listp includes) includes (list includes)) "\n")
> +		 includes "\n")
>  		;; defines
>  		(mapconcat
>  		 (lambda (inc) (format "#define %s" inc))
>  		 (if (listp defines) defines (list defines)) "\n")
>  		;; variables
>  		(mapconcat 'org-babel-C-var-to-C vars "\n")
> +		;; table sizes
> +		(mapconcat 'org-babel-C-table-sizes-to-C vars "\n")
> +		;; tables headers utility
> +		(when colnames
> +		  (org-babel-C-utility-header-to-C))
> +		;; tables headers
> +		(mapconcat 'org-babel-C-header-to-C colnames "\n")
>  		;; body
>  		(if main-p
>  		    (org-babel-C-ensure-main-wrap body)
> @@ -187,18 +199,28 @@ it's header arguments."
>    "Expand a block of D code with org-babel according to
>  it's header arguments."
>    (let ((vars (mapcar #'cdr (org-babel-get-header params :var)))
> +	(colnames (cdar (org-babel-get-header params :colname-names)))
>  	(main-p (not (string= (cdr (assoc :main params)) "no")))
>  	(imports (or (cdr (assoc :imports params))
>  		     (org-babel-read (org-entry-get nil "imports" t)))))
> +    (unless (listp imports) (setq imports (list imports)))
> +    (setq imports (append imports '("std.stdio" "std.conv")))
>      (mapconcat 'identity
>  	       (list
>  		"module mmm;"
>  		;; imports
>  		(mapconcat
>  		 (lambda (inc) (format "import %s;" inc))
> -		 (if (listp imports) imports (list imports)) "\n")
> +		 imports "\n")
>  		;; variables
>  		(mapconcat 'org-babel-C-var-to-C vars "\n")
> +		;; table sizes
> +		(mapconcat 'org-babel-C-table-sizes-to-C vars "\n")
> +		;; tables headers utility
> +		(when colnames
> +		  (org-babel-C-utility-header-to-C))
> +		;; tables headers
> +		(mapconcat 'org-babel-C-header-to-C colnames "\n")
>  		;; body
>  		(if main-p
>  		    (org-babel-C-ensure-main-wrap body)
> @@ -229,50 +251,72 @@ support for sessions"
>  	(cons "" (format format-data val))
>        (funcall format-data val))))
>  
> +(defun org-babel-C-val-to-base-type (val)
> +  "Determine the base type of VAL which may be
> +'integerp if all base values are integers
> +'floatp if all base values are either floating points or integers
> +'stringp otherwise."
> +  (cond
> +   ((integerp val) 'integerp)
> +   ((floatp val) 'floatp)
> +   ((or (listp val) (vectorp val))
> +    (let ((type nil))
> +      (mapc (lambda (v)
> +	      (case (org-babel-C-val-to-base-type v)
> +		(stringp (setq type 'stringp))
> +		(floatp
> +		 (if (or (not type) (eq type 'integerp))
> +		     (setq type 'floatp)))
> +		(integerp
> +		 (unless type (setq type 'integerp)))))
> +	    val)
> +      type))
> +   (t 'stringp)))
> +
>  (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 (if (equal org-babel-c-variant 'd) "[ " "{ ")
> -		       (mapconcat (lambda (v)
> -				    (cdr (org-babel-C-format-val type v)))
> -				  val
> -				  ", ")
> -		       (if (equal org-babel-c-variant 'd) " ]" " }")))))))
> -   (t ;; treat unknown types as string
> -    (list
> -     (if (equal org-babel-c-variant 'd) "string" "const char*")
> -     "\"%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))
> +  (let* ((basetype (org-babel-C-val-to-base-type val))
> +	 (type
> +	  (case basetype
> +	    (integerp '("int" "%d"))
> +	    (floatp '("double" "%f"))
> +	    (stringp
> +	     (list
> +	      (if (equal org-babel-c-variant 'd) "string" "const char*")
> +	      "\"%s\""))
> +	    (t (error "unknown type %S" type)))))
> +    (cond
> +     ((integerp val) type) ;; an integer declared in the #+begin_src line
> +     ((floatp val) type) ;; a numeric declared in the #+begin_src line
> +     ((and (listp val) (listp (car val))) ;; a table
> +      `(,(car type)
> +	(lambda (val)
> +	  (cons
> +	   (format "[%d][%d]" (length val) (length (car val)))
> +	   (concat
> +	    (if (equal org-babel-c-variant 'd) "[\n" "{\n")
> +	    (mapconcat
> +	     (lambda (v)
> +	       (concat
> +		(if (equal org-babel-c-variant 'd) " [" " {")
> +		(mapconcat (lambda (w) (format ,(cadr type) w)) v ",")
> +		(if (equal org-babel-c-variant 'd) "]" "}")))
> +	     val
> +	     ",\n")
> +	    (if (equal org-babel-c-variant 'd) "\n]" "\n}"))))))
> +     ((or (listp val) (vectorp val)) ;; a list declared in the #+begin_src line
> +      `(,(car type)
> +	(lambda (val)
> +	  (cons
> +	   (format "[%d]" (length val))
> +	   (concat
> +	    (if (equal org-babel-c-variant 'd) "[" "{")
> +	    (mapconcat (lambda (v) (format ,(cadr type) v)) val ",")
> +	    (if (equal org-babel-c-variant 'd) "]" "}"))))))
> +     (t ;; treat unknown types as string
> +      type))))
>  
>  (defun org-babel-C-var-to-C (pair)
>    "Convert an elisp val into a string of C code specifying a var
> @@ -295,6 +339,68 @@ of the same value."
>  	      suffix
>  	      data))))
>  
> +(defun org-babel-C-table-sizes-to-C (pair)
> +  "Create constants of table dimensions, if PAIR is a table."
> +  (when (listp (cdr pair))
> +    (cond
> +     ((listp (cadr pair)) ;; a table
> +      (concat
> +       (format "const int %s_rows = %d;" (car pair) (length (cdr pair)))
> +       "\n"
> +       (format "const int %s_cols = %d;" (car pair) (length (cadr pair)))))
> +     (t ;; a list declared in the #+begin_src line
> +      (format "const int %s_cols = %d;" (car pair) (length (cdr pair)))))))
> +
> +(defun org-babel-C-utility-header-to-C ()
> +  "Generate a utility function to convert a column name
> +into a column number."
> +  (case org-babel-c-variant
> +    ((c cpp)
> +     "int get_column_num (int nbcols, const char** header, const char* column)
> +{
> +  int c;
> +  for (c=0; c<nbcols; c++)
> +    if (strcmp(header[c],column)==0)
> +      return c;
> +  return -1;
> +}
> +"
> +     )
> +    (d
> +     "int get_column_num (string[] header, string column)
> +{
> +  foreach (c, h; header)
> +    if (h==column)
> +      return to!int(c);
> +  return -1;
> +}
> +"
> +     )))
> +
> +(defun org-babel-C-header-to-C (head)
> +  "Convert an elisp list of header table into a C or D vector
> +specifying a variable with the name of the table."
> +  (let ((table (car head))
> +        (headers (cdr head)))
> +    (concat
> +     (format
> +      (case org-babel-c-variant
> +	((c cpp) "const char* %s_header[%d] = {%s};")
> +	(d       "string %s_header[%d] = [%s];"))
> +      table
> +      (length headers)
> +      (mapconcat (lambda (h) (format "%S" h)) headers ","))
> +     "\n"
> +     (case org-babel-c-variant
> +       ((c cpp)
> +	(format
> +	 "const char* %s_h (int row, const char* col) { return %s[row][get_column_num(%d,%s_header,col)]; }"
> +	 table table (length headers) table))
> +       (d
> +	(format
> +	 "string %s_h (ulong row, string col) { return %s[row][get_column_num(%s_header,col)]; }"
> +	 table table table))))))
> +
>  (provide 'ob-C)
>  
>  ;;; ob-C.el ends here
> diff --git a/testing/examples/ob-C-test.org b/testing/examples/ob-C-test.org
> index 1d0a83f..a8c485d 100644
> --- a/testing/examples/ob-C-test.org
> +++ b/testing/examples/ob-C-test.org
> @@ -10,24 +10,44 @@
>    return 0;
>  #+end_src
>  
> +#+source: simple
> +#+begin_src D :results silent
> +  writefln ("%s", 42);
> +#+end_src
> +
>  #+source: integer_var
>  #+begin_src cpp :var q=12 :includes "<iostream>" :results silent
>    std::cout << q;
>    return 0;
>  #+end_src
>  
> +#+source: integer_var
> +#+begin_src D :var q=12 :results silent
> +  writefln ("%s", q);
> +#+end_src
> +
>  #+source: two_var
>  #+begin_src cpp :var q=12 :var p=10 :includes "<iostream>" :results silent
>    std::cout << p+q;
>    return 0;
>  #+end_src
>  
> +#+source: two_var
> +#+begin_src D :var q=12 :var p=10 :results silent
> +  writefln ("%s", p+q);
> +#+end_src
> +
>  #+source: string_var
>  #+begin_src cpp :var q="word" :includes '(<iostream> <cstring>) :results silent
>    std::cout << q << ' ' << std::strlen(q);
>    return 0;
>  #+end_src
>  
> +#+source: string_var
> +#+begin_src D :var q="word" :results silent
> +  writefln ("%s %s", q, q.length);
> +#+end_src
> +
>  #+source: define
>  #+begin_src cpp :defines N 42  :includes "<iostream>" :results silent
>    std::cout << N;
> @@ -45,6 +65,13 @@
>    }
>    return 0;
>  #+end_src
> +
> +#+source: array
> +#+begin_src D :results vector :results silent
> +  foreach (i; 1..3)
> +    writefln ("%s", i);
> +#+end_src
> +
>  * Matrix
>    :PROPERTIES:
>    :ID:       cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5
> @@ -58,13 +85,74 @@
>    std::cout << a[0] << a[1] << sizeof(a)/sizeof(*a) << '\n';
>  #+end_src
>  
> +#+source: list_var
> +#+begin_src D :var a='("abc" "def") :results silent
> +  writefln ("%s%s%s", a[0], a[1], a.length);
> +#+end_src
> +
>  #+source: vector_var
>  #+begin_src cpp :var a='[1 2] :includes "<iostream>" :results silent
>    std::cout << a[0] << a[1] << sizeof(a)/sizeof(*a) << '\n';
>  #+end_src
>  
> +#+source: vector_var
> +#+begin_src D :var a='[1 2] :results silent
> +  writefln ("%s%s%s", a[0], a[1], a.length);
> +#+end_src
> +
>  #+source: list_list_var
>  #+begin_src cpp :var q=C-matrix :includes "<iostream>" :results silent
>    std::cout << q[0][0] << ' ' << q[1][0] << '\n'
>              << q[0][1] << ' ' << q[1][1] << '\n'; // transpose
>  #+end_src
> +
> +#+source: list_list_var
> +#+begin_src D :var q=C-matrix :results silent
> +  writefln ("%s %s", q[0][0], q[1][0]);
> +  writefln ("%s %s", q[0][1], q[1][1]); // transpose
> +#+end_src
> +
> +* Inhomogeneous table
> +  :PROPERTIES:
> +  :ID:       e112bc2e-419a-4890-99c2-7ac4779531cc
> +  :END:
> +
> +#+tblname: tinomogen
> +  | day       | quty |
> +  |-----------+------|
> +  | monday    |   34 |
> +  | tuesday   |   41 |
> +  | wednesday |   56 |
> +  | thursday  |   17 |
> +  | friday    |   12 |
> +  | saturday  |    7 |
> +  | sunday    |    4 |
> +
> +#+source: inhomogeneous_table
> +#+BEGIN_SRC C :var tinomogen=tinomogen :results silent
> +int main()
> +{
> +  int i, j;
> +  for (i=0; i<tinomogen_rows; i++) {
> +    for (j=0; j<tinomogen_cols; j++)
> +      printf ("%s ", tinomogen[i][j]);
> +    printf ("\n");
> +  }
> +  printf ("Friday %s\n", tinomogen_h(4,"day"));
> +  return 0;
> +}
> +#+END_SRC
> +
> +#+source: inhomogeneous_table
> +#+BEGIN_SRC D :var tinomogen=tinomogen :results silent
> +import std.stdio;
> +void main()
> +{
> +  for (int i=0; i<tinomogen_rows; i++) {
> +    for (int j=0; j<tinomogen_cols; j++)
> +      writef ("%s ", tinomogen[i][j]);
> +    writeln();
> +  }
> +  writefln ("Friday %s\n", tinomogen_h(4,"day"));
> +}
> +#+END_SRC
> diff --git a/testing/lisp/test-ob-C.el b/testing/lisp/test-ob-C.el
> index 42e4dd2..2cc07fc 100644
> --- a/testing/lisp/test-ob-C.el
> +++ b/testing/lisp/test-ob-C.el
> @@ -1,7 +1,7 @@
> -;;; test-ob-awk.el --- tests for ob-awk.el
> +;;; test-ob-C.el --- tests for ob-C.el
>  
> -;; Copyright (c) 2010-2014 Sergey Litvinov
> -;; Authors: Sergey Litvinov
> +;; Copyright (c) 2010-2014 Sergey Litvinov, Thierry Banel
> +;; Authors: Sergey Litvinov, Thierry Banel
>  
>  ;; This file is not part of GNU Emacs.
>  
> @@ -28,55 +28,136 @@
>  (ert-deftest ob-C/simple-program ()
>    "Hello world program."
>    (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
> -    (org-babel-next-src-block)
> +    (org-babel-next-src-block 1)
> +    (should (= 42 (org-babel-execute-src-block)))))
> +
> +(ert-deftest ob-D/simple-program ()
> +  "Hello world program."
> +  (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
> +    (org-babel-next-src-block 2)
>      (should (= 42 (org-babel-execute-src-block)))))
>  
>  (ert-deftest ob-C/integer-var ()
>    "Test of an integer variable."
>    (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
> -    (org-babel-next-src-block 2)
> +    (org-babel-next-src-block 3)
> +    (should (= 12 (org-babel-execute-src-block)))))
> +
> +(ert-deftest ob-D/integer-var ()
> +  "Test of an integer variable."
> +  (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
> +    (org-babel-next-src-block 4)
>      (should (= 12 (org-babel-execute-src-block)))))
>  
>  (ert-deftest ob-C/two-integer-var ()
>    "Test of two input variables"
>    (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
> -    (org-babel-next-src-block 3)
> +    (org-babel-next-src-block 5)
> +    (should (= 22 (org-babel-execute-src-block)))))
> +
> +(ert-deftest ob-D/two-integer-var ()
> +  "Test of two input variables"
> +  (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
> +    (org-babel-next-src-block 6)
>      (should (= 22 (org-babel-execute-src-block)))))
>  
>  (ert-deftest ob-C/string-var ()
>    "Test of a string input variable"
>    (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
> -    (org-babel-next-src-block 4)
> +    (org-babel-next-src-block 7)
> +    (should (equal "word 4" (org-babel-execute-src-block)))))
> +
> +(ert-deftest ob-D/string-var ()
> +  "Test of a string input variable"
> +  (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
> +    (org-babel-next-src-block 8)
>      (should (equal "word 4" (org-babel-execute-src-block)))))
>  
>  (ert-deftest ob-C/preprocessor ()
>    "Test of a string variable"
>    (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
> -    (org-babel-next-src-block 5)
> +    (org-babel-next-src-block 9)
>      (should (= 42 (org-babel-execute-src-block)))))
>  
> +
>  (ert-deftest ob-C/table ()
>    "Test of a table output"
>    (org-test-at-id "2df1ab83-3fa3-462a-a1f3-3aef6044a874"
> -    (org-babel-next-src-block)
> +    (org-babel-next-src-block 1)
>      (should (equal '((1) (2)) (org-babel-execute-src-block)))))
>  
> +(ert-deftest ob-D/table ()
> +  "Test of a table output"
> +  (org-test-at-id "2df1ab83-3fa3-462a-a1f3-3aef6044a874"
> +    (org-babel-next-src-block 2)
> +    (should (equal '((1) (2)) (org-babel-execute-src-block)))))
> +
> +
>  (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= "abcdef2" (org-babel-execute-src-block)))))
>  
> +(ert-deftest ob-D/list-var ()
> +"Test of a list input variable"
> +  (org-test-at-id "cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5"
> +    (org-babel-next-src-block 2)
> +    (should (string= "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)
> +    (org-babel-next-src-block 3)
> +    (should (equal 122 (org-babel-execute-src-block)))))
> +
> +(ert-deftest ob-D/vector-var ()
> +"Test of a vector input variable"
> +  (org-test-at-id "cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5"
> +    (org-babel-next-src-block 4)
>      (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)
> +    (org-babel-next-src-block 5)
>      (should (equal '((1 3) (2 4)) (org-babel-execute-src-block)))))
>  
> +(ert-deftest ob-D/list-list-var ()
> +  "Test of a list list input variable"
> +  (org-test-at-id "cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5"
> +    (org-babel-next-src-block 6)
> +    (should (equal '((1 3) (2 4)) (org-babel-execute-src-block)))))
> +
> +
> +(ert-deftest ob-C/inhomogeneous_table ()
> +  "Test inhomogeneous input table"
> +  (org-test-at-id "e112bc2e-419a-4890-99c2-7ac4779531cc"
> +    (org-babel-next-src-block 1)
> +    (should (equal
> +	     '(("monday" 34)
> +	       ("tuesday" 41)
> +	       ("wednesday" 56)
> +	       ("thursday" 17)
> +	       ("friday" 12)
> +	       ("saturday" 7)
> +	       ("sunday" 4)
> +	       ("Friday" "friday"))
> +	     (org-babel-execute-src-block)))))
> +
> +(ert-deftest ob-D/inhomogeneous_table ()
> +  "Test inhomogeneous input table"
> +  (org-test-at-id "e112bc2e-419a-4890-99c2-7ac4779531cc"
> +    (org-babel-next-src-block 2)
> +    (should (equal
> +	     '(("monday" 34)
> +	       ("tuesday" 41)
> +	       ("wednesday" 56)
> +	       ("thursday" 17)
> +	       ("friday" 12)
> +	       ("saturday" 7)
> +	       ("sunday" 4)
> +	       ("Friday" "friday"))
> +	     (org-babel-execute-src-block)))))
> +
>  ;;; test-ob-C.el ends here

-- 
Eric Schulte
https://cs.unm.edu/~eschulte
PGP: 0x614CA05D (see https://u.fsf.org/yw)

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: babel C, C++, D enhancement
  2014-06-06 16:31                 ` Eric Schulte
@ 2014-06-07 18:19                   ` Thierry Banel
  2014-06-08 20:19                   ` Thierry Banel
  1 sibling, 0 replies; 31+ messages in thread
From: Thierry Banel @ 2014-06-07 18:19 UTC (permalink / raw)
  To: emacs-orgmode

Thanks Eric for your feed-back.
Bastien told me the same as you about the commit message.
So I will take time to clear all those issues.


Le 06/06/2014 18:31, Eric Schulte a écrit :
> Hi Thierry,
>
> This looks wonderful, however after applying this patch I get the
> following errors when running "make test-dirty".
>
>> 10 unexpected results:
>>    FAILED  ob-C/inhomogeneous_table
>>    FAILED  ob-D/inhomogeneous_table
>>    FAILED  ob-D/integer-var
>>    FAILED  ob-D/list-list-var
>>    FAILED  ob-D/list-var
>>    FAILED  ob-D/simple-program
>>    FAILED  ob-D/string-var
>>    FAILED  ob-D/table
>>    FAILED  ob-D/two-integer-var
>>    FAILED  ob-D/vector-var
> Could you update the test suite so that the C tests pass, and the D
> tests are not executed when D is not available?
>
> Also, could you flesh out the commit message so that it meets the Emacs
> commit message guidelines (http://orgmode.org/worg/org-contribute.html)?
>
> Many Thanks,
> Eric
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: babel C, C++, D enhancement
  2014-06-06 16:31                 ` Eric Schulte
  2014-06-07 18:19                   ` Thierry Banel
@ 2014-06-08 20:19                   ` Thierry Banel
  2014-06-08 23:22                     ` Eric Schulte
  1 sibling, 1 reply; 31+ messages in thread
From: Thierry Banel @ 2014-06-08 20:19 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 1639 bytes --]

Hi Eric, hi All

Here is a new patch (do not apply the previous).
I added a check in the test suite for the D compiler availability
(and for the C++ compiler as well).
It silently returns true when the compiler is not found.

To run the test suite I did that:
- start from an up-to-date org-mode/ GIT directory
- create a GIT branch, checkout there
- apply the patch : git am patch-file
- make clean
- make autoloads
- make test-dirty

Eric, this result you were getting is strange:
  FAILED ob-C/inhomogeneous_table
It is as though the NEW test suite was run against the OLD ob-C.el
Maybe there was an old .elc compiled file hanging around ?
 
Anyway, it works fine for me.
Could someone check and tell me if something goes wrong ?

Have fun
Thierry


Le 06/06/2014 18:31, Eric Schulte a écrit :
> Hi Thierry,
>
> This looks wonderful, however after applying this patch I get the
> following errors when running "make test-dirty".
>
>> 10 unexpected results:
>>    FAILED  ob-C/inhomogeneous_table
>>    FAILED  ob-D/inhomogeneous_table
>>    FAILED  ob-D/integer-var
>>    FAILED  ob-D/list-list-var
>>    FAILED  ob-D/list-var
>>    FAILED  ob-D/simple-program
>>    FAILED  ob-D/string-var
>>    FAILED  ob-D/table
>>    FAILED  ob-D/two-integer-var
>>    FAILED  ob-D/vector-var
> Could you update the test suite so that the C tests pass, and the D
> tests are not executed when D is not available?
>
> Also, could you flesh out the commit message so that it meets the Emacs
> commit message guidelines (http://orgmode.org/worg/org-contribute.html)?
>
> Many Thanks,
> Eric
>
>


[-- Attachment #2: 0001-Babel-C-C-D-support-for-non-homogeneous-input-tables.patch --]
[-- Type: text/x-diff, Size: 27765 bytes --]

From 06996e7af7c24b8b6adc16b13c183dcc46b5362c Mon Sep 17 00:00:00 2001
From: Thierry Banel <tbanelwebmin@free.fr>
Date: Sun, 8 Jun 2014 22:01:56 +0200
Subject: [PATCH]         Babel C, C++, D support for non-homogeneous input
 tables

        * ob-C.el: handling of non-homogeneous tables,
        support for table header,
        support for iterating over table cells.
        (org-babel-expand-body:C++): uncomment
        (org-babel-C-execute): cosmetic changes
        (org-babel-C-expand-C): add support for table columns names,
        add support for table dimensions,
        add standard includes
        (org-babel-C-val-to-C-type): rewrite to support non-homogeneous
        tables cells
        (org-babel-C-table-sizes-to-C): new function to gain access
        to the table dimensions
        (org-babel-C-utility-header-to-C):
        (org-babel-C-header-to-C): new functions to generate
        support for table header.

        * ob-C-test.org: added D sibling tests similar to C++,
        added non-homogeneous table example for C++ and D

        * test-ob-C.el: new tests for D and non-homogeneous tables
        (ob-C/simple-program):
        (ob-C/simple-program):
        (ob-D/simple-program):
        (ob-C/integer-var):
        (ob-D/integer-var):
        (ob-C/two-integer-var):
        (ob-D/two-integer-var):
        (ob-C/string-var):
        (ob-D/string-var):
        (ob-C/preprocessor):
        (ob-C/table):
        (ob-D/table):
        (ob-C/list-var):
        (ob-D/list-var):
        (ob-C/vector-var):
        (ob-D/vector-var):
        (ob-C/list-list-var):
        (ob-D/list-list-var):
        (ob-C/inhomogeneous_table):
        (ob-D/inhomogeneous_table): add compiler availability check
        (ob-D/simple-program):
        (ob-D/integer-var):
        (ob-D/two-integer-var):
        (ob-D/string-var):
        (ob-D/table):
        (ob-D/list-var):
        (ob-D/vector-var):
        (ob-D/list-list-var):
        (ob-D/inhomogeneous_table): add D unit tests
        (ob-C/inhomogeneous_table):
        (ob-D/inhomogeneous_table): add non-homogeneous table
        unit tests
---
 lisp/ob-C.el                   |  292 +++++++++++++++++++++++++++-------------
 testing/examples/ob-C-test.org |   88 ++++++++++++
 testing/lisp/test-ob-C.el      |  161 +++++++++++++++++-----
 3 files changed, 416 insertions(+), 125 deletions(-)

diff --git a/lisp/ob-C.el b/lisp/ob-C.el
index 793981a..dd03fa7 100644
--- a/lisp/ob-C.el
+++ b/lisp/ob-C.el
@@ -34,8 +34,6 @@
   (require 'cl))
 (require 'ob)
 (require 'cc-mode)
-(eval-when-compile
-  (require 'cl))
 
 (declare-function org-entry-get "org"
 		  (pom property &optional inherit literal-nil))
@@ -72,40 +70,40 @@ This function calls `org-babel-execute:C++'."
 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) ;; unused
-;;  "Expand a block of C++ code with org-babel according to it's
-;;header arguments (calls `org-babel-C-expand')."
-;;  (let ((org-babel-c-variant 'cpp)) (org-babel-C-expand body params)))
+(defun org-babel-expand-body:C++ (body params)
+  "Expand a block of C++ code with org-babel according to it's
+header arguments."
+  (let ((org-babel-c-variant 'cpp)) (org-babel-C-expand-C++ body params)))
 
 (defun org-babel-execute:D (body params)
   "Execute a block of D code with org-babel.
 This function is called by `org-babel-execute-src-block'."
   (let ((org-babel-c-variant 'd)) (org-babel-C-execute body params)))
 
-;; (defun org-babel-expand-body:D (body params) ;; unused
-;;  "Expand a block of D code with org-babel according to it's
-;;header arguments (calls `org-babel-C-expand')."
-;;  (let ((org-babel-c-variant 'd)) (org-babel-C-expand body params)))
+(defun org-babel-expand-body:D (body params)
+  "Expand a block of D code with org-babel according to it's
+header arguments."
+  (let ((org-babel-c-variant 'd)) (org-babel-C-expand-D 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'."
   (let ((org-babel-c-variant 'c)) (org-babel-C-execute body params)))
 
-;; (defun org-babel-expand-body:c (body params) ;; unused
-;;  "Expand a block of C code with org-babel according to it's
-;;header arguments (calls `org-babel-C-expand')."
-;;  (let ((org-babel-c-variant 'c)) (org-babel-C-expand body params)))
+(defun org-babel-expand-body:C (body params)
+  "Expand a block of C code with org-babel according to it's
+header arguments."
+  (let ((org-babel-c-variant 'c)) (org-babel-C-expand-C body params)))
 
 (defun org-babel-C-execute (body params)
   "This function should only be called by `org-babel-execute:C'
 or `org-babel-execute:C++' or `org-babel-execute:D'."
   (let* ((tmp-src-file (org-babel-temp-file
 			"C-src-"
-			(cond
-			 ((equal org-babel-c-variant 'c  ) ".c"  )
-			 ((equal org-babel-c-variant 'cpp) ".cpp")
-			 ((equal org-babel-c-variant 'd  ) ".d"  ))))
+			(case org-babel-c-variant
+			 (c   ".c"  )
+			 (cpp ".cpp")
+			 (d   ".d"  ))))
 	 (tmp-bin-file (org-babel-temp-file "C-bin-" org-babel-exeext)) ;; not used for D
 	 (cmdline (cdr (assoc :cmdline params)))
 	 (cmdline (if cmdline (concat " " cmdline) ""))
@@ -113,43 +111,47 @@ or `org-babel-execute:C++' or `org-babel-execute:D'."
 	 (flags (mapconcat 'identity
 			   (if (listp flags) flags (list flags)) " "))
 	 (full-body
-	  (cond ((equal org-babel-c-variant 'c  ) (org-babel-C-expand-C   body params))
-		((equal org-babel-c-variant 'cpp) (org-babel-C-expand-C++ body params))
-		((equal org-babel-c-variant 'd  ) (org-babel-C-expand-D   body params)))))
+	  (case org-babel-c-variant
+	    (c   (org-babel-C-expand-C   body params))
+	    (cpp (org-babel-C-expand-C++ body params))
+	    (d   (org-babel-C-expand-D   body params)))))
     (with-temp-file tmp-src-file (insert full-body))
-    (if (memq org-babel-c-variant '(c cpp)) ;; no separate compilation for D
-	(org-babel-eval
-	 (format "%s -o %s %s %s"
-		 (cond
-		  ((equal org-babel-c-variant 'c  ) org-babel-C-compiler)
-		  ((equal org-babel-c-variant 'cpp) org-babel-C++-compiler))
-		 (org-babel-process-file-name tmp-bin-file)
-		 flags
-		 (org-babel-process-file-name tmp-src-file)) ""))
+    (case org-babel-c-variant
+      ((c cpp)
+       (org-babel-eval
+	(format "%s -o %s %s %s"
+		(case org-babel-c-variant
+		 (c   org-babel-C-compiler)
+		 (cpp org-babel-C++-compiler))
+		(org-babel-process-file-name tmp-bin-file)
+		flags
+		(org-babel-process-file-name tmp-src-file)) ""))
+      (d nil)) ;; no separate compilation for D
     (let ((results
-	   (org-babel-trim
-	    (org-remove-indentation
-	     (org-babel-eval
-	      (cond ((memq org-babel-c-variant '(c cpp))
-		     (concat tmp-bin-file cmdline))
-		    ((equal org-babel-c-variant 'd)
-		     (format "%s %s %s %s"
-			     org-babel-D-compiler
-			     flags
-			     (org-babel-process-file-name tmp-src-file)
-			     cmdline)))
-	      "")))))
-      (org-babel-reassemble-table
-       (org-babel-result-cond (cdr (assoc :result-params params))
-	 (org-babel-read results t)
-	 (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
-	(cdr (assoc :rowname-names params)) (cdr (assoc :rownames params)))))
-    ))
+	   (org-babel-eval
+	    (case org-babel-c-variant
+	      ((c cpp)
+	       (concat tmp-bin-file cmdline))
+	      (d
+	       (format "%s %s %s %s"
+		       org-babel-D-compiler
+		       flags
+		       (org-babel-process-file-name tmp-src-file)
+		       cmdline)))
+	    "")))
+      (when results
+	(setq results (org-babel-trim (org-remove-indentation results)))
+	(org-babel-reassemble-table
+	 (org-babel-result-cond (cdr (assoc :result-params params))
+	   (org-babel-read results t)
+	   (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
+	  (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params)))))
+      )))
 
 (defun org-babel-C-expand-C++ (body params)
   "Expand a block of C or C++ code with org-babel according to
@@ -160,24 +162,34 @@ it's header arguments."
   "Expand a block of C or C++ code with org-babel according to
 it's header arguments."
   (let ((vars (mapcar #'cdr (org-babel-get-header params :var)))
+	(colnames (cdar (org-babel-get-header params :colname-names)))
 	(main-p (not (string= (cdr (assoc :main params)) "no")))
 	(includes (or (cdr (assoc :includes params))
 		      (org-babel-read (org-entry-get nil "includes" t))))
 	(defines (org-babel-read
 		  (or (cdr (assoc :defines params))
 		      (org-babel-read (org-entry-get nil "defines" t))))))
+    (unless (listp includes) (setq includes (list includes)))
+    (setq includes (append includes '("<string.h>" "<stdio.h>" "<stdlib.h>")))
     (mapconcat 'identity
 	       (list
 		;; includes
 		(mapconcat
 		 (lambda (inc) (format "#include %s" inc))
-		 (if (listp includes) includes (list includes)) "\n")
+		 includes "\n")
 		;; defines
 		(mapconcat
 		 (lambda (inc) (format "#define %s" inc))
 		 (if (listp defines) defines (list defines)) "\n")
 		;; variables
 		(mapconcat 'org-babel-C-var-to-C vars "\n")
+		;; table sizes
+		(mapconcat 'org-babel-C-table-sizes-to-C vars "\n")
+		;; tables headers utility
+		(when colnames
+		  (org-babel-C-utility-header-to-C))
+		;; tables headers
+		(mapconcat 'org-babel-C-header-to-C colnames "\n")
 		;; body
 		(if main-p
 		    (org-babel-C-ensure-main-wrap body)
@@ -187,18 +199,28 @@ it's header arguments."
   "Expand a block of D code with org-babel according to
 it's header arguments."
   (let ((vars (mapcar #'cdr (org-babel-get-header params :var)))
+	(colnames (cdar (org-babel-get-header params :colname-names)))
 	(main-p (not (string= (cdr (assoc :main params)) "no")))
 	(imports (or (cdr (assoc :imports params))
 		     (org-babel-read (org-entry-get nil "imports" t)))))
+    (unless (listp imports) (setq imports (list imports)))
+    (setq imports (append imports '("std.stdio" "std.conv")))
     (mapconcat 'identity
 	       (list
 		"module mmm;"
 		;; imports
 		(mapconcat
 		 (lambda (inc) (format "import %s;" inc))
-		 (if (listp imports) imports (list imports)) "\n")
+		 imports "\n")
 		;; variables
 		(mapconcat 'org-babel-C-var-to-C vars "\n")
+		;; table sizes
+		(mapconcat 'org-babel-C-table-sizes-to-C vars "\n")
+		;; tables headers utility
+		(when colnames
+		  (org-babel-C-utility-header-to-C))
+		;; tables headers
+		(mapconcat 'org-babel-C-header-to-C colnames "\n")
 		;; body
 		(if main-p
 		    (org-babel-C-ensure-main-wrap body)
@@ -233,46 +255,68 @@ support for sessions"
   "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."
+  (let* ((basetype (org-babel-C-val-to-base-type val))
+	 (type
+	  (case basetype
+	    (integerp '("int" "%d"))
+	    (floatp '("double" "%f"))
+	    (stringp
+	     (list
+	      (if (equal org-babel-c-variant 'd) "string" "const char*")
+	      "\"%s\""))
+	    (t (error "unknown type %S" type)))))
+    (cond
+     ((integerp val) type) ;; an integer declared in the #+begin_src line
+     ((floatp val) type) ;; a numeric declared in the #+begin_src line
+     ((and (listp val) (listp (car val))) ;; a table
+      `(,(car type)
+	(lambda (val)
+	  (cons
+	   (format "[%d][%d]" (length val) (length (car val)))
+	   (concat
+	    (if (equal org-babel-c-variant 'd) "[\n" "{\n")
+	    (mapconcat
+	     (lambda (v)
+	       (concat
+		(if (equal org-babel-c-variant 'd) " [" " {")
+		(mapconcat (lambda (w) (format ,(cadr type) w)) v ",")
+		(if (equal org-babel-c-variant 'd) "]" "}")))
+	     val
+	     ",\n")
+	    (if (equal org-babel-c-variant 'd) "\n]" "\n}"))))))
+     ((or (listp val) (vectorp val)) ;; a list declared in the #+begin_src line
+      `(,(car type)
+	(lambda (val)
+	  (cons
+	   (format "[%d]" (length val))
+	   (concat
+	    (if (equal org-babel-c-variant 'd) "[" "{")
+	    (mapconcat (lambda (v) (format ,(cadr type) v)) val ",")
+	    (if (equal org-babel-c-variant 'd) "]" "}"))))))
+     (t ;; treat unknown types as string
+      type))))
+
+(defun org-babel-C-val-to-base-type (val)
+  "Determine the base type of VAL which may be
+'integerp if all base values are integers
+'floatp if all base values are either floating points or integers
+'stringp otherwise."
   (cond
-   ((integerp val) '("int" "%d"))
-   ((floatp val) '("double" "%f"))
+   ((integerp val) 'integerp)
+   ((floatp val) 'floatp)
    ((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 (if (equal org-babel-c-variant 'd) "[ " "{ ")
-		       (mapconcat (lambda (v)
-				    (cdr (org-babel-C-format-val type v)))
-				  val
-				  ", ")
-		       (if (equal org-babel-c-variant 'd) " ]" " }")))))))
-   (t ;; treat unknown types as string
-    (list
-     (if (equal org-babel-c-variant 'd) "string" "const char*")
-     "\"%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))
+    (let ((type nil))
+      (mapc (lambda (v)
+	      (case (org-babel-C-val-to-base-type v)
+		(stringp (setq type 'stringp))
+		(floatp
+		 (if (or (not type) (eq type 'integerp))
+		     (setq type 'floatp)))
+		(integerp
+		 (unless type (setq type 'integerp)))))
+	    val)
+      type))
+   (t 'stringp)))
 
 (defun org-babel-C-var-to-C (pair)
   "Convert an elisp val into a string of C code specifying a var
@@ -295,6 +339,68 @@ of the same value."
 	      suffix
 	      data))))
 
+(defun org-babel-C-table-sizes-to-C (pair)
+  "Create constants of table dimensions, if PAIR is a table."
+  (when (listp (cdr pair))
+    (cond
+     ((listp (cadr pair)) ;; a table
+      (concat
+       (format "const int %s_rows = %d;" (car pair) (length (cdr pair)))
+       "\n"
+       (format "const int %s_cols = %d;" (car pair) (length (cadr pair)))))
+     (t ;; a list declared in the #+begin_src line
+      (format "const int %s_cols = %d;" (car pair) (length (cdr pair)))))))
+
+(defun org-babel-C-utility-header-to-C ()
+  "Generate a utility function to convert a column name
+into a column number."
+  (case org-babel-c-variant
+    ((c cpp)
+     "int get_column_num (int nbcols, const char** header, const char* column)
+{
+  int c;
+  for (c=0; c<nbcols; c++)
+    if (strcmp(header[c],column)==0)
+      return c;
+  return -1;
+}
+"
+     )
+    (d
+     "int get_column_num (string[] header, string column)
+{
+  foreach (c, h; header)
+    if (h==column)
+      return to!int(c);
+  return -1;
+}
+"
+     )))
+
+(defun org-babel-C-header-to-C (head)
+  "Convert an elisp list of header table into a C or D vector
+specifying a variable with the name of the table."
+  (let ((table (car head))
+        (headers (cdr head)))
+    (concat
+     (format
+      (case org-babel-c-variant
+	((c cpp) "const char* %s_header[%d] = {%s};")
+	(d       "string %s_header[%d] = [%s];"))
+      table
+      (length headers)
+      (mapconcat (lambda (h) (format "%S" h)) headers ","))
+     "\n"
+     (case org-babel-c-variant
+       ((c cpp)
+	(format
+	 "const char* %s_h (int row, const char* col) { return %s[row][get_column_num(%d,%s_header,col)]; }"
+	 table table (length headers) table))
+       (d
+	(format
+	 "string %s_h (ulong row, string col) { return %s[row][get_column_num(%s_header,col)]; }"
+	 table table table))))))
+
 (provide 'ob-C)
 
 ;;; ob-C.el ends here
diff --git a/testing/examples/ob-C-test.org b/testing/examples/ob-C-test.org
index 1d0a83f..ab744f1 100644
--- a/testing/examples/ob-C-test.org
+++ b/testing/examples/ob-C-test.org
@@ -10,24 +10,44 @@
   return 0;
 #+end_src
 
+#+source: simple
+#+begin_src D :results silent
+  writefln ("%s", 42);
+#+end_src
+
 #+source: integer_var
 #+begin_src cpp :var q=12 :includes "<iostream>" :results silent
   std::cout << q;
   return 0;
 #+end_src
 
+#+source: integer_var
+#+begin_src D :var q=12 :results silent
+  writefln ("%s", q);
+#+end_src
+
 #+source: two_var
 #+begin_src cpp :var q=12 :var p=10 :includes "<iostream>" :results silent
   std::cout << p+q;
   return 0;
 #+end_src
 
+#+source: two_var
+#+begin_src D :var q=12 :var p=10 :results silent
+  writefln ("%s", p+q);
+#+end_src
+
 #+source: string_var
 #+begin_src cpp :var q="word" :includes '(<iostream> <cstring>) :results silent
   std::cout << q << ' ' << std::strlen(q);
   return 0;
 #+end_src
 
+#+source: string_var
+#+begin_src D :var q="word" :results silent
+  writefln ("%s %s", q, q.length);
+#+end_src
+
 #+source: define
 #+begin_src cpp :defines N 42  :includes "<iostream>" :results silent
   std::cout << N;
@@ -45,6 +65,13 @@
   }
   return 0;
 #+end_src
+
+#+source: array
+#+begin_src D :results vector :results silent
+  foreach (i; 1..3)
+    writefln ("%s", i);
+#+end_src
+
 * Matrix
   :PROPERTIES:
   :ID:       cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5
@@ -58,13 +85,74 @@
   std::cout << a[0] << a[1] << sizeof(a)/sizeof(*a) << '\n';
 #+end_src
 
+#+source: list_var
+#+begin_src D :var a='("abc" "def") :results silent
+  writefln ("%s%s%s", a[0], a[1], a.length);
+#+end_src
+
 #+source: vector_var
 #+begin_src cpp :var a='[1 2] :includes "<iostream>" :results silent
   std::cout << a[0] << a[1] << sizeof(a)/sizeof(*a) << '\n';
 #+end_src
 
+#+source: vector_var
+#+begin_src D :var a='[1 2] :results silent
+  writefln ("%s%s%s", a[0], a[1], a.length);
+#+end_src
+
 #+source: list_list_var
 #+begin_src cpp :var q=C-matrix :includes "<iostream>" :results silent
   std::cout << q[0][0] << ' ' << q[1][0] << '\n'
             << q[0][1] << ' ' << q[1][1] << '\n'; // transpose
 #+end_src
+
+#+source: list_list_var
+#+begin_src D :var q=C-matrix :results silent
+  writefln ("%s %s", q[0][0], q[1][0]);
+  writefln ("%s %s", q[0][1], q[1][1]); // transpose
+#+end_src
+
+* Inhomogeneous table
+  :PROPERTIES:
+  :ID:       e112bc2e-419a-4890-99c2-7ac4779531cc
+  :END:
+
+#+tblname: tinomogen
+  | day       | quty |
+  |-----------+------|
+  | monday    |   34 |
+  | tuesday   |   41 |
+  | wednesday |   56 |
+  | thursday  |   17 |
+  | friday    |   12 |
+  | saturday  |    7 |
+  | sunday    |    4 |
+
+#+source: inhomogeneous_table
+#+begin_src cpp :var tinomogen=tinomogen :results silent
+int main()
+{
+  int i, j;
+  for (i=0; i<tinomogen_rows; i++) {
+    for (j=0; j<tinomogen_cols; j++)
+      printf ("%s ", tinomogen[i][j]);
+    printf ("\n");
+  }
+  printf ("Friday %s\n", tinomogen_h(4,"day"));
+  return 0;
+}
+#+end_src
+
+#+source: inhomogeneous_table
+#+begin_src D :var tinomogen=tinomogen :results silent
+import std.stdio;
+void main()
+{
+  for (int i=0; i<tinomogen_rows; i++) {
+    for (int j=0; j<tinomogen_cols; j++)
+      writef ("%s ", tinomogen[i][j]);
+    writeln();
+  }
+  writefln ("Friday %s\n", tinomogen_h(4,"day"));
+}
+#+end_src
diff --git a/testing/lisp/test-ob-C.el b/testing/lisp/test-ob-C.el
index 42e4dd2..4639004 100644
--- a/testing/lisp/test-ob-C.el
+++ b/testing/lisp/test-ob-C.el
@@ -1,7 +1,7 @@
-;;; test-ob-awk.el --- tests for ob-awk.el
+;;; test-ob-C.el --- tests for ob-C.el
 
-;; Copyright (c) 2010-2014 Sergey Litvinov
-;; Authors: Sergey Litvinov
+;; Copyright (c) 2010-2014 Sergey Litvinov, Thierry Banel
+;; Authors: Sergey Litvinov, Thierry Banel
 
 ;; This file is not part of GNU Emacs.
 
@@ -27,56 +27,153 @@
 
 (ert-deftest ob-C/simple-program ()
   "Hello world program."
-  (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
-    (org-babel-next-src-block)
-    (should (= 42 (org-babel-execute-src-block)))))
+  (if (executable-find org-babel-C++-compiler)
+      (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
+		      (org-babel-next-src-block 1)
+		      (should (= 42 (org-babel-execute-src-block))))))
+
+(ert-deftest ob-D/simple-program ()
+  "Hello world program."
+  (if (executable-find org-babel-D-compiler)
+      (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
+		      (org-babel-next-src-block 2)
+		      (should (= 42 (org-babel-execute-src-block))))))
 
 (ert-deftest ob-C/integer-var ()
   "Test of an integer variable."
-  (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
-    (org-babel-next-src-block 2)
-    (should (= 12 (org-babel-execute-src-block)))))
+  (if (executable-find org-babel-C++-compiler)
+      (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
+		      (org-babel-next-src-block 3)
+		      (should (= 12 (org-babel-execute-src-block))))))
+
+(ert-deftest ob-D/integer-var ()
+  "Test of an integer variable."
+  (if (executable-find org-babel-D-compiler)
+      (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
+		      (org-babel-next-src-block 4)
+		      (should (= 12 (org-babel-execute-src-block))))))
 
 (ert-deftest ob-C/two-integer-var ()
   "Test of two input variables"
-  (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
-    (org-babel-next-src-block 3)
-    (should (= 22 (org-babel-execute-src-block)))))
+  (if (executable-find org-babel-C++-compiler)
+      (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
+		      (org-babel-next-src-block 5)
+		      (should (= 22 (org-babel-execute-src-block))))))
+
+(ert-deftest ob-D/two-integer-var ()
+  "Test of two input variables"
+  (if (executable-find org-babel-D-compiler)
+      (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
+		      (org-babel-next-src-block 6)
+		      (should (= 22 (org-babel-execute-src-block))))))
 
 (ert-deftest ob-C/string-var ()
   "Test of a string input variable"
-  (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
-    (org-babel-next-src-block 4)
-    (should (equal "word 4" (org-babel-execute-src-block)))))
+  (if (executable-find org-babel-C++-compiler)
+      (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
+		      (org-babel-next-src-block 7)
+		      (should (equal "word 4" (org-babel-execute-src-block))))))
+
+(ert-deftest ob-D/string-var ()
+  "Test of a string input variable"
+  (if (executable-find org-babel-D-compiler)
+      (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
+		      (org-babel-next-src-block 8)
+		      (should (equal "word 4" (org-babel-execute-src-block))))))
 
 (ert-deftest ob-C/preprocessor ()
   "Test of a string variable"
-  (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
-    (org-babel-next-src-block 5)
-    (should (= 42 (org-babel-execute-src-block)))))
+  (if (executable-find org-babel-C++-compiler)
+      (org-test-at-id "fa6db330-e960-4ea2-ac67-94bb845b8577"
+		      (org-babel-next-src-block 9)
+		      (should (= 42 (org-babel-execute-src-block))))))
 
 (ert-deftest ob-C/table ()
   "Test of a table output"
-  (org-test-at-id "2df1ab83-3fa3-462a-a1f3-3aef6044a874"
-    (org-babel-next-src-block)
-    (should (equal '((1) (2)) (org-babel-execute-src-block)))))
+  (if (executable-find org-babel-C++-compiler)
+      (org-test-at-id "2df1ab83-3fa3-462a-a1f3-3aef6044a874"
+		      (org-babel-next-src-block 1)
+		      (should (equal '((1) (2)) (org-babel-execute-src-block))))))
+
+(ert-deftest ob-D/table ()
+  "Test of a table output"
+  (if (executable-find org-babel-D-compiler)
+      (org-test-at-id "2df1ab83-3fa3-462a-a1f3-3aef6044a874"
+		      (org-babel-next-src-block 2)
+		      (should (equal '((1) (2)) (org-babel-execute-src-block))))))
 
 (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= "abcdef2" (org-babel-execute-src-block)))))
+  "Test of a list input variable"
+  (if (executable-find org-babel-C++-compiler)
+      (org-test-at-id "cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5"
+		      (org-babel-next-src-block 1)
+		      (should (string= "abcdef2" (org-babel-execute-src-block))))))
+
+(ert-deftest ob-D/list-var ()
+  "Test of a list input variable"
+  (if (executable-find org-babel-D-compiler)
+      (org-test-at-id "cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5"
+		      (org-babel-next-src-block 2)
+		      (should (string= "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)))))
+  "Test of a vector input variable"
+  (if (executable-find org-babel-C++-compiler)
+      (org-test-at-id "cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5"
+		      (org-babel-next-src-block 3)
+		      (should (equal 122 (org-babel-execute-src-block))))))
+
+(ert-deftest ob-D/vector-var ()
+  "Test of a vector input variable"
+  (if (executable-find org-babel-D-compiler)
+      (org-test-at-id "cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5"
+		      (org-babel-next-src-block 4)
+		      (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)))))
+  (if (executable-find org-babel-C++-compiler)
+      (org-test-at-id "cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5"
+		      (org-babel-next-src-block 5)
+		      (should (equal '((1 3) (2 4)) (org-babel-execute-src-block))))))
+
+(ert-deftest ob-D/list-list-var ()
+  "Test of a list list input variable"
+  (if (executable-find org-babel-D-compiler)
+      (org-test-at-id "cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5"
+		      (org-babel-next-src-block 6)
+		      (should (equal '((1 3) (2 4)) (org-babel-execute-src-block))))))
+
+(ert-deftest ob-C/inhomogeneous_table ()
+  "Test inhomogeneous input table"
+  (if (executable-find org-babel-C++-compiler)
+      (org-test-at-id "e112bc2e-419a-4890-99c2-7ac4779531cc"
+		      (org-babel-next-src-block 1)
+		      (should (equal
+			       '(("monday" 34)
+				 ("tuesday" 41)
+				 ("wednesday" 56)
+				 ("thursday" 17)
+				 ("friday" 12)
+				 ("saturday" 7)
+				 ("sunday" 4)
+				 ("Friday" "friday"))
+			       (org-babel-execute-src-block))))))
+
+(ert-deftest ob-D/inhomogeneous_table ()
+  "Test inhomogeneous input table"
+  (if (executable-find org-babel-D-compiler)
+      (org-test-at-id "e112bc2e-419a-4890-99c2-7ac4779531cc"
+		      (org-babel-next-src-block 2)
+		      (should (equal
+			       '(("monday" 34)
+				 ("tuesday" 41)
+				 ("wednesday" 56)
+				 ("thursday" 17)
+				 ("friday" 12)
+				 ("saturday" 7)
+				 ("sunday" 4)
+				 ("Friday" "friday"))
+			       (org-babel-execute-src-block))))))
 
 ;;; test-ob-C.el ends here
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: babel C, C++, D enhancement
  2014-06-08 20:19                   ` Thierry Banel
@ 2014-06-08 23:22                     ` Eric Schulte
  2014-06-09  9:40                       ` Thierry Banel
                                         ` (2 more replies)
  0 siblings, 3 replies; 31+ messages in thread
From: Eric Schulte @ 2014-06-08 23:22 UTC (permalink / raw)
  To: Thierry Banel; +Cc: emacs-orgmode

Thierry Banel <tbanelwebmin@free.fr> writes:

> Hi Eric, hi All
>
> Here is a new patch (do not apply the previous).
> I added a check in the test suite for the D compiler availability
> (and for the C++ compiler as well).
> It silently returns true when the compiler is not found.
>
> To run the test suite I did that:
> - start from an up-to-date org-mode/ GIT directory
> - create a GIT branch, checkout there
> - apply the patch : git am patch-file
> - make clean
> - make autoloads
> - make test-dirty
>
> Eric, this result you were getting is strange:
>   FAILED ob-C/inhomogeneous_table
> It is as though the NEW test suite was run against the OLD ob-C.el
> Maybe there was an old .elc compiled file hanging around ?
>  
> Anyway, it works fine for me.
> Could someone check and tell me if something goes wrong ?
>
> Have fun
> Thierry
>

Hi Theirry,

This new patch looks great, and the test suite passes locally.  I've
just applied it.

Thanks!
Eric

also, thanks for taking the time to flesh out the commit message

>
>
> Le 06/06/2014 18:31, Eric Schulte a écrit :
>> Hi Thierry,
>>
>> This looks wonderful, however after applying this patch I get the
>> following errors when running "make test-dirty".
>>
>>> 10 unexpected results:
>>>    FAILED  ob-C/inhomogeneous_table
>>>    FAILED  ob-D/inhomogeneous_table
>>>    FAILED  ob-D/integer-var
>>>    FAILED  ob-D/list-list-var
>>>    FAILED  ob-D/list-var
>>>    FAILED  ob-D/simple-program
>>>    FAILED  ob-D/string-var
>>>    FAILED  ob-D/table
>>>    FAILED  ob-D/two-integer-var
>>>    FAILED  ob-D/vector-var
>> Could you update the test suite so that the C tests pass, and the D
>> tests are not executed when D is not available?
>>
>> Also, could you flesh out the commit message so that it meets the Emacs
>> commit message guidelines (http://orgmode.org/worg/org-contribute.html)?
>>
>> Many Thanks,
>> Eric
>>
>>
>
>

-- 
Eric Schulte
https://cs.unm.edu/~eschulte
PGP: 0x614CA05D (see https://u.fsf.org/yw)

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: babel C, C++, D enhancement
  2014-06-08 23:22                     ` Eric Schulte
@ 2014-06-09  9:40                       ` Thierry Banel
  2014-06-13  6:51                       ` Achim Gratz
  2014-06-13 10:55                       ` Bastien
  2 siblings, 0 replies; 31+ messages in thread
From: Thierry Banel @ 2014-06-09  9:40 UTC (permalink / raw)
  To: emacs-orgmode

Good !
Now I will update the documentation
(worg/org-contrib/babel/languages/ob-doc-C.org)
and... that's it.

Le 09/06/2014 01:22, Eric Schulte a écrit :
> Hi Theirry,
>
> This new patch looks great, and the test suite passes locally.  I've
> just applied it.
>
> Thanks!
> Eric
>
> also, thanks for taking the time to flesh out the commit message
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: babel C, C++, D enhancement
  2014-06-08 23:22                     ` Eric Schulte
  2014-06-09  9:40                       ` Thierry Banel
@ 2014-06-13  6:51                       ` Achim Gratz
  2014-06-13 11:47                         ` Eric Schulte
  2014-06-13 22:07                         ` Thierry Banel
  2014-06-13 10:55                       ` Bastien
  2 siblings, 2 replies; 31+ messages in thread
From: Achim Gratz @ 2014-06-13  6:51 UTC (permalink / raw)
  To: emacs-orgmode

Eric Schulte writes:
> This new patch looks great, and the test suite passes locally.  I've
> just applied it.

You also get a warning from the byte-compiler on something that is
clearly a bug.  I think the fix should be:

--8<---------------cut here---------------start------------->8---
diff --git a/lisp/ob-C.el b/lisp/ob-C.el
index dd03fa7..a794e2a 100644
--- a/lisp/ob-C.el
+++ b/lisp/ob-C.el
@@ -264,7 +264,7 @@ (defun org-babel-C-val-to-C-type (val)
 	     (list
 	      (if (equal org-babel-c-variant 'd) "string" "const char*")
 	      "\"%s\""))
-	    (t (error "unknown type %S" type)))))
+	    (t (error "unknown type %S" basetype)))))
     (cond
      ((integerp val) type) ;; an integer declared in the #+begin_src line
      ((floatp val) type) ;; a numeric declared in the #+begin_src line
--8<---------------cut here---------------end--------------->8---

The type determination is a tad optimistic, too.  An Emacs integer may
or may not fit into C type "int" depending on how Emacs is compiled and
which compiler you are using.


Regards,
Achim.
-- 
+<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+

Factory and User Sound Singles for Waldorf rackAttack:
http://Synth.Stromeko.net/Downloads.html#WaldorfSounds

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: babel C, C++, D enhancement
  2014-06-08 23:22                     ` Eric Schulte
  2014-06-09  9:40                       ` Thierry Banel
  2014-06-13  6:51                       ` Achim Gratz
@ 2014-06-13 10:55                       ` Bastien
  2014-06-13 11:58                         ` conforming commit messages Was: " Eric Schulte
  2014-06-13 14:50                         ` Eric Abrahamsen
  2 siblings, 2 replies; 31+ messages in thread
From: Bastien @ 2014-06-13 10:55 UTC (permalink / raw)
  To: Eric Schulte; +Cc: Thierry Banel, emacs-orgmode

Hi Eric and Thierry,

Eric Schulte <schulte.eric@gmail.com> writes:

> This new patch looks great, and the test suite passes locally.  I've
> just applied it.

Thanks for applying this -- let me just be boring again and insist on
properly rewrite the Changelog when applying patches... in this case,
there are a lot of tiny formatting issues I will need to fix myself
when merging into Emacs :/

Thanks to both of you!

-- 
 Bastien

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: babel C, C++, D enhancement
  2014-06-13  6:51                       ` Achim Gratz
@ 2014-06-13 11:47                         ` Eric Schulte
  2014-06-13 22:07                         ` Thierry Banel
  1 sibling, 0 replies; 31+ messages in thread
From: Eric Schulte @ 2014-06-13 11:47 UTC (permalink / raw)
  To: Achim Gratz; +Cc: emacs-orgmode

Achim Gratz <Stromeko@nexgo.de> writes:

> Eric Schulte writes:
>> This new patch looks great, and the test suite passes locally.  I've
>> just applied it.
>
> You also get a warning from the byte-compiler on something that is
> clearly a bug.  I think the fix should be:
>
> --8<---------------cut here---------------start------------->8---
> diff --git a/lisp/ob-C.el b/lisp/ob-C.el
> index dd03fa7..a794e2a 100644
> --- a/lisp/ob-C.el
> +++ b/lisp/ob-C.el
> @@ -264,7 +264,7 @@ (defun org-babel-C-val-to-C-type (val)
>  	     (list
>  	      (if (equal org-babel-c-variant 'd) "string" "const char*")
>  	      "\"%s\""))
> -	    (t (error "unknown type %S" type)))))
> +	    (t (error "unknown type %S" basetype)))))
>      (cond
>       ((integerp val) type) ;; an integer declared in the #+begin_src line
>       ((floatp val) type) ;; a numeric declared in the #+begin_src line
> --8<---------------cut here---------------end--------------->8---
>

Agreed, I've just pushed up a fix.  Please feel free to push these sorts
of obvious bug fixes yourself in the future.

>
> The type determination is a tad optimistic, too.  An Emacs integer may
> or may not fit into C type "int" depending on how Emacs is compiled and
> which compiler you are using.
>

Certainly, more refinement wouldn't hurt.

Best,
Eric

>
>
> Regards,
> Achim.

-- 
Eric Schulte
https://cs.unm.edu/~eschulte
PGP: 0x614CA05D (see https://u.fsf.org/yw)

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: conforming commit messages Was: babel C, C++, D enhancement
  2014-06-13 10:55                       ` Bastien
@ 2014-06-13 11:58                         ` Eric Schulte
  2014-06-13 14:50                         ` Eric Abrahamsen
  1 sibling, 0 replies; 31+ messages in thread
From: Eric Schulte @ 2014-06-13 11:58 UTC (permalink / raw)
  To: Bastien; +Cc: Thierry Banel, emacs-orgmode

Bastien <bzg@gnu.org> writes:

> Hi Eric and Thierry,
>
> Eric Schulte <schulte.eric@gmail.com> writes:
>
>> This new patch looks great, and the test suite passes locally.  I've
>> just applied it.
>
> Thanks for applying this -- let me just be boring again and insist on
> properly rewrite the Changelog when applying patches... in this case,
> there are a lot of tiny formatting issues I will need to fix myself
> when merging into Emacs :/
>
> Thanks to both of you!

Mea culpa!

I glanced at it and it looked good, but I'll be more careful moving
forward.  Does anyone on the list happen to have or know of a script
which could be used to automatically check for conforming commit
messages?  If so I'm sure git provides a hook to make passing such a
script part of the git commit process.  That's the only way I'll really
be consistent about this.

Thanks,
Eric

-- 
Eric Schulte
https://cs.unm.edu/~eschulte
PGP: 0x614CA05D (see https://u.fsf.org/yw)

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: babel C, C++, D enhancement
  2014-06-13 10:55                       ` Bastien
  2014-06-13 11:58                         ` conforming commit messages Was: " Eric Schulte
@ 2014-06-13 14:50                         ` Eric Abrahamsen
  1 sibling, 0 replies; 31+ messages in thread
From: Eric Abrahamsen @ 2014-06-13 14:50 UTC (permalink / raw)
  To: emacs-orgmode

Bastien <bzg@gnu.org> writes:

> Hi Eric and Thierry,
>
> Eric Schulte <schulte.eric@gmail.com> writes:
>
>> This new patch looks great, and the test suite passes locally.  I've
>> just applied it.
>
> Thanks for applying this -- let me just be boring again and insist on
> properly rewrite the Changelog when applying patches... in this case,
> there are a lot of tiny formatting issues I will need to fix myself
> when merging into Emacs :/
>
> Thanks to both of you!

Apologies on this count, as well, I'll study the proper Changelog format
diligently!

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: babel C, C++, D enhancement
  2014-06-13  6:51                       ` Achim Gratz
  2014-06-13 11:47                         ` Eric Schulte
@ 2014-06-13 22:07                         ` Thierry Banel
  2014-06-16 18:28                           ` Achim Gratz
  1 sibling, 1 reply; 31+ messages in thread
From: Thierry Banel @ 2014-06-13 22:07 UTC (permalink / raw)
  To: emacs-orgmode

Thanks Achim for finding and fixing this bug.

I do agree about fuzziness between int and float.
My Emacs considers
  2305843009213693951 as an integer,
  2305843009213693952 too large to be an integer.
My C++ compiler sees
  4294967295 as an integer,
  4294967296 as too large to fit an int.

So Babel C++ may cause problem for large integers.
I am not sure how we can fix this in any case.
In the meantime, we can force large values to be declared as doubles by
adding dot zero
like this:

#+BEGIN_SRC C++ :var large=9876543210 .0
printf ("%g", large);
#+END_SRC

Thierry


Le 13/06/2014 08:51, Achim Gratz a écrit :
> Eric Schulte writes:
>> This new patch looks great, and the test suite passes locally.  I've
>> just applied it.
> You also get a warning from the byte-compiler on something that is
> clearly a bug.  I think the fix should be:
>
> --8<---------------cut here---------------start------------->8---
> diff --git a/lisp/ob-C.el b/lisp/ob-C.el
> index dd03fa7..a794e2a 100644
> --- a/lisp/ob-C.el
> +++ b/lisp/ob-C.el
> @@ -264,7 +264,7 @@ (defun org-babel-C-val-to-C-type (val)
>  	     (list
>  	      (if (equal org-babel-c-variant 'd) "string" "const char*")
>  	      "\"%s\""))
> -	    (t (error "unknown type %S" type)))))
> +	    (t (error "unknown type %S" basetype)))))
>      (cond
>       ((integerp val) type) ;; an integer declared in the #+begin_src line
>       ((floatp val) type) ;; a numeric declared in the #+begin_src line
> --8<---------------cut here---------------end--------------->8---
>
> The type determination is a tad optimistic, too.  An Emacs integer may
> or may not fit into C type "int" depending on how Emacs is compiled and
> which compiler you are using.
>
>
> Regards,
> Achim.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: babel C, C++, D enhancement
  2014-06-13 22:07                         ` Thierry Banel
@ 2014-06-16 18:28                           ` Achim Gratz
  2014-06-16 20:49                             ` Thierry Banel
  0 siblings, 1 reply; 31+ messages in thread
From: Achim Gratz @ 2014-06-16 18:28 UTC (permalink / raw)
  To: emacs-orgmode

Thierry Banel writes:
> So Babel C++ may cause problem for large integers.
> I am not sure how we can fix this in any case.

You'd need to know INT_MAX and give an error for larger values or use an
integral type that is large enough to handle Emacs' integer (which would
most likely be necessary for any Emacs that uses wide integer).

> In the meantime, we can force large values to be declared as doubles by
> adding dot zero
> like this:
>
> #+BEGIN_SRC C++ :var large=9876543210 .0
> printf ("%g", large);
> #+END_SRC

That will lose precision, so it may not be the right thing either.


Regards,
Achim.
-- 
+<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+

SD adaptation for Waldorf Blofeld V1.15B11:
http://Synth.Stromeko.net/Downloads.html#WaldorfSDada

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: babel C, C++, D enhancement
  2014-06-16 18:28                           ` Achim Gratz
@ 2014-06-16 20:49                             ` Thierry Banel
  2014-06-16 21:14                               ` Thomas S. Dye
  2014-06-17 17:16                               ` Achim Gratz
  0 siblings, 2 replies; 31+ messages in thread
From: Thierry Banel @ 2014-06-16 20:49 UTC (permalink / raw)
  To: emacs-orgmode

Hi Achim.

You are right, INT_MAX is the C++ constant to compare to.
It is defined in limits.h

I'm not sure I want to locate limits.h (where is it ? are there several
versions ?),
and parse it, all from within Emacs-lisp...
And this will have to be done for all languages (Python, Perl, Java, and
so on),
not just C++.

Or we could assume that INT_MAX is always 2147483647.
(Which of course is not true).

Not so easy...

Regards
Thierry

Le 16/06/2014 20:28, Achim Gratz a écrit :
> Thierry Banel writes:
>> So Babel C++ may cause problem for large integers.
>> I am not sure how we can fix this in any case.
> You'd need to know INT_MAX and give an error for larger values or use an
> integral type that is large enough to handle Emacs' integer (which would
> most likely be necessary for any Emacs that uses wide integer).
>
>> In the meantime, we can force large values to be declared as doubles by
>> adding dot zero
>> like this:
>>
>> #+BEGIN_SRC C++ :var large=9876543210 .0
>> printf ("%g", large);
>> #+END_SRC
> That will lose precision, so it may not be the right thing either.
>
>
> Regards,
> Achim.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: babel C, C++, D enhancement
  2014-06-16 20:49                             ` Thierry Banel
@ 2014-06-16 21:14                               ` Thomas S. Dye
  2014-06-16 22:24                                 ` Nick Dokos
  2014-06-17 17:16                               ` Achim Gratz
  1 sibling, 1 reply; 31+ messages in thread
From: Thomas S. Dye @ 2014-06-16 21:14 UTC (permalink / raw)
  To: Thierry Banel; +Cc: emacs-orgmode

Aloha Thierry,

How about a user-customizable variable with a default value of
2147483647?

All the best,
Tom

Thierry Banel <tbanelwebmin@free.fr> writes:

> Hi Achim.
>
> You are right, INT_MAX is the C++ constant to compare to.
> It is defined in limits.h
>
> I'm not sure I want to locate limits.h (where is it ? are there several
> versions ?),
> and parse it, all from within Emacs-lisp...
> And this will have to be done for all languages (Python, Perl, Java, and
> so on),
> not just C++.
>
> Or we could assume that INT_MAX is always 2147483647.
> (Which of course is not true).
>
> Not so easy...
>
> Regards
> Thierry
>
> Le 16/06/2014 20:28, Achim Gratz a écrit :
>> Thierry Banel writes:
>>> So Babel C++ may cause problem for large integers.
>>> I am not sure how we can fix this in any case.
>> You'd need to know INT_MAX and give an error for larger values or use an
>> integral type that is large enough to handle Emacs' integer (which would
>> most likely be necessary for any Emacs that uses wide integer).
>>
>>> In the meantime, we can force large values to be declared as doubles by
>>> adding dot zero
>>> like this:
>>>
>>> #+BEGIN_SRC C++ :var large=9876543210 .0
>>> printf ("%g", large);
>>> #+END_SRC
>> That will lose precision, so it may not be the right thing either.
>>
>>
>> Regards,
>> Achim.
>
>
>

-- 
Thomas S. Dye
http://www.tsdye.com

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: babel C, C++, D enhancement
  2014-06-16 21:14                               ` Thomas S. Dye
@ 2014-06-16 22:24                                 ` Nick Dokos
  0 siblings, 0 replies; 31+ messages in thread
From: Nick Dokos @ 2014-06-16 22:24 UTC (permalink / raw)
  To: emacs-orgmode

tsd@tsdye.com (Thomas S. Dye) writes:

> Aloha Thierry,
>
> How about a user-customizable variable with a default value of
> 2147483647?
>
> All the best,
> Tom
>
> Thierry Banel <tbanelwebmin@free.fr> writes:
>
>> Hi Achim.
>>
>> You are right, INT_MAX is the C++ constant to compare to.
>> It is defined in limits.h
>>
>> I'm not sure I want to locate limits.h (where is it ? are there several
>> versions ?),
>> and parse it, all from within Emacs-lisp...
>> And this will have to be done for all languages (Python, Perl, Java, and
>> so on),
>> not just C++.
>>
>> Or we could assume that INT_MAX is always 2147483647.
>> (Which of course is not true).
>>
>> Not so easy...
>>

You don't need to parse limits.h: for POSIX systems, one can use
`getconf INT_MAX' from the shell. `getconf -a' will list all the
names.

Nick

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: babel C, C++, D enhancement
  2014-06-16 20:49                             ` Thierry Banel
  2014-06-16 21:14                               ` Thomas S. Dye
@ 2014-06-17 17:16                               ` Achim Gratz
  2014-06-17 20:51                                 ` Thierry Banel
  1 sibling, 1 reply; 31+ messages in thread
From: Achim Gratz @ 2014-06-17 17:16 UTC (permalink / raw)
  To: emacs-orgmode

Thierry Banel writes:
> You are right, INT_MAX is the C++ constant to compare to.
> It is defined in limits.h
>
> I'm not sure I want to locate limits.h (where is it ? are there several
> versions ?),
> and parse it, all from within Emacs-lisp...

No, this isn't something you should even try.  The only method that is
known to work is what autoconf does: compile a program and check the
output.

> And this will have to be done for all languages (Python, Perl, Java,
> and so on), not just C++.

Let's stick with C(++) and solve that problem first, that there is a lot
of boilerplate code in Babel language support that should be lifted off
elsewhere is a discussion for another time.

> Or we could assume that INT_MAX is always 2147483647.
> (Which of course is not true).

You've just made compilers customizable.  For a start, make those
constants customizable per compiler as well?


Regards,
Achim.
-- 
+<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+

SD adaptation for Waldorf microQ V2.22R2:
http://Synth.Stromeko.net/Downloads.html#WaldorfSDada

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: babel C, C++, D enhancement
  2014-06-17 17:16                               ` Achim Gratz
@ 2014-06-17 20:51                                 ` Thierry Banel
  0 siblings, 0 replies; 31+ messages in thread
From: Thierry Banel @ 2014-06-17 20:51 UTC (permalink / raw)
  To: emacs-orgmode

Le 17/06/2014 19:16, Achim Gratz a écrit :
> Thierry Banel writes:
>> You are right, INT_MAX is the C++ constant to compare to.
>> It is defined in limits.h
>>
>> I'm not sure I want to locate limits.h (where is it ? are there several
>> versions ?),
>> and parse it, all from within Emacs-lisp...
> No, this isn't something you should even try.  The only method that is
> known to work is what autoconf does: compile a program and check the
> output.
Absolutely right.
Or use "getconf INT_MAX" as suggested by Nick Dokos, but this does not
works everywhere.
>> And this will have to be done for all languages (Python, Perl, Java,
>> and so on), not just C++.
> Let's stick with C(++) and solve that problem first, that there is a lot
> of boilerplate code in Babel language support that should be lifted off
> elsewhere is a discussion for another time.
I do agree.

By the way, other languages may not be as tricky.

- Java specifies int to be exactly 32 bits, long to be 64 bits.
  http://en.wikibooks.org/wiki/Java_Programming/Primitive_Types

- Same goes for D.
  http://dlang.org/type.html

- In C++ there is a new specification with types like:
  |int_least32_t| // at least 32 bits
  |int32_t // exactly 32 bits|
  http://en.cppreference.com/w/cpp/types/integer

>> Or we could assume that INT_MAX is always 2147483647.
>> (Which of course is not true).
> You've just made compilers customizable.  For a start, make those
> constants customizable per compiler as well?
>
Thomas S. Dye suggested just that.
Should we throw this detail at the user ?
She will have a hard time figuring out why we bother her with integer size.


Regards
Thierry

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2014-06-17 20:51 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-11  1:34 Patch for testing `org-open-at-point' York Zhao
2014-04-11  7:23 ` Nicolas Goaziou
2014-04-11 10:25 ` Bastien
2014-04-12 14:22   ` York Zhao
2014-04-17 18:48     ` Bastien
2014-04-20 19:19       ` Michael Strey
2014-04-20 19:56       ` York Zhao
2014-06-01  1:12         ` York Zhao
2014-06-01  8:53           ` Bastien
2014-06-01 20:15           ` Achim Gratz
2014-06-01 21:14             ` Bastien
2014-06-01 21:58               ` babel C, C++, D enhancement Thierry Banel
2014-06-06 16:31                 ` Eric Schulte
2014-06-07 18:19                   ` Thierry Banel
2014-06-08 20:19                   ` Thierry Banel
2014-06-08 23:22                     ` Eric Schulte
2014-06-09  9:40                       ` Thierry Banel
2014-06-13  6:51                       ` Achim Gratz
2014-06-13 11:47                         ` Eric Schulte
2014-06-13 22:07                         ` Thierry Banel
2014-06-16 18:28                           ` Achim Gratz
2014-06-16 20:49                             ` Thierry Banel
2014-06-16 21:14                               ` Thomas S. Dye
2014-06-16 22:24                                 ` Nick Dokos
2014-06-17 17:16                               ` Achim Gratz
2014-06-17 20:51                                 ` Thierry Banel
2014-06-13 10:55                       ` Bastien
2014-06-13 11:58                         ` conforming commit messages Was: " Eric Schulte
2014-06-13 14:50                         ` Eric Abrahamsen
2014-06-02 19:13               ` Patch for testing `org-open-at-point' Achim Gratz
2014-06-03  7:22                 ` Bastien

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).