From 993c8e1da79c229a60aa76ade64780484a405df0 Mon Sep 17 00:00:00 2001
From: Pascal Fleury <fleury@google.com>
Date: Wed, 21 Jan 2015 23:55:34 +0100
Subject: [PATCH] [PATCH]ob-shell.el now emits associative array code only when
 the  installed version of bash supports them. This takes care of differences
 in  platforms that ship with bash v4+, that can deal with them, and those
 (e.g.  MacOSX) that ship with bash v3.x that does not support such arrays.

---
 lisp/ob-shell.el                   | 15 +++++++++++++--
 testing/examples/ob-shell-test.org | 10 ++++++++--
 testing/lisp/test-ob-shell.el      |  2 +-
 3 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/lisp/ob-shell.el b/lisp/ob-shell.el
index aa14a69..48b38cc 100644
--- a/lisp/ob-shell.el
+++ b/lisp/ob-shell.el
@@ -38,6 +38,10 @@
 
 (defvar org-babel-default-header-args:sh '())
 
+;; Contains the version of bash that is installed. If nil, will be
+;; found by using bash itself once.
+(defvar org-babel-shell-bash-version nil)
+
 (defcustom org-babel-shell-names
   '("sh" "bash" "csh" "ash" "dash" "ksh" "mksh" "posh")
   "List of names of shell supported by babel shell code blocks."
@@ -121,12 +125,19 @@ This function is called by `org-babel-execute-src-block'."
      values
      "\n")))
 
+(defun bash-supports-assoc-arrays ()
+  "Returns if the current bash running on the system supports associative arrays."
+  (if (= org-babel-shell-bash-version nil)
+      (setq org-babel-shell-bash-version (org-babel-execute:shell "echo ${BASH_VERSINFO[0]}" nil)))
+  (> 3 org-babel-shell-bash-version)))
+
 (defun org-babel-variable-assignments:bash (varname values &optional sep hline)
   "Represents the parameters as useful Bash shell variables."
   (if (listp values)
-      (if (and (listp (car values)) (= 1 (length (car values))))
+      (if (or (not (bash-supports-assoc-arrays))
+	      (and (listp (car values)) (= 1 (length (car values)))))
 	  (org-babel-variable-assignments:bash_array varname values sep hline)
-	(org-babel-variable-assignments:bash_assoc varname values sep hline))
+	  (org-babel-variable-assignments:bash_assoc varname values sep hline))
     (org-babel-variable-assignments:sh-generic varname values sep hline)))
 
 (defun org-babel-variable-assignments:sh (params)
diff --git a/testing/examples/ob-shell-test.org b/testing/examples/ob-shell-test.org
index a54e5c0..ebd7421 100644
--- a/testing/examples/ob-shell-test.org
+++ b/testing/examples/ob-shell-test.org
@@ -80,9 +80,15 @@ echo ${table}
 Bash will see an associative array that contains each row as a single
 string. Bash cannot handle lists in associative arrays.
 #+begin_src bash :exports results :var table=sample_big_table
-echo ${table[spaghetti]}
+if (( ${BASH_VERSINFO[0]} > 3 )); then
+  # understands associative arrays
+  echo spaghetti ${table[spaghetti]}
+else
+  # Default V3.x behavior, has one array item contains the key and values.
+  echo ${table[1]}
+fi
 #+end_src
 
 #+RESULTS:
-: 20 cm
+: spaghetti 20 cm
 
diff --git a/testing/lisp/test-ob-shell.el b/testing/lisp/test-ob-shell.el
index 58a7859..9aa7f35 100644
--- a/testing/lisp/test-ob-shell.el
+++ b/testing/lisp/test-ob-shell.el
@@ -84,7 +84,7 @@ ob-comint.el, which was not previously tested."
   "Bash associative arrays as strings for the row"
   (org-test-at-id "82320a48-3409-49d7-85c9-5de1c6d3ff87"
     (org-babel-next-src-block 2)
-    (should (equal "20 cm" (org-babel-execute-src-block)))))
+    (should (equal "spaghetti 20 cm" (org-babel-execute-src-block)))))
 
 
 (provide 'test-ob-shell)
-- 
2.2.1

