commit 8751c041562da72b2eb6588dd3c8a3b2043c06b1
Author: Iustin Pop <iustin@google.com>
Date:   Thu Dec 22 17:32:15 2011 +0100

    Improve convert-constants to handle dictionaries
    
    The two main drawbacks for convert-constants are the fact that it
    can't handle sets/frozensets (mainly due to the fact that I don't know
    how useful this would be to the Haskell code) and that it cannot
    export dictionaries.
    
    To fix the second case, the current patch changes the code to support
    flattening (potentially nested) dictionaries into single name
    space. Yes, this could generate conflicts, but they will be detected
    at compile time.
    
    Signed-off-by: Iustin Pop <iustin@google.com>
    Reviewed-by: René Nussbaumer <rn@google.com>

diff --git a/autotools/convert-constants b/autotools/convert-constants
index 3f2b362..8dd1a11 100755
--- a/autotools/convert-constants
+++ b/autotools/convert-constants
@@ -26,13 +26,14 @@ import re
 
 from ganeti import constants
 
-CONSTANT_RE = re.compile("^[A-Z][A-Z0-9_]+$")
+CONSTANT_RE = re.compile("^[A-Z][A-Z0-9_-]+$")
 
 
 def NameRules(name):
   """Converts the upper-cased Python name to Haskell camelCase.
 
   """
+  name = name.replace("-", "_")
   elems = name.split("_")
   return elems[0].lower() + "".join(e.capitalize() for e in elems[1:])
 
@@ -46,6 +47,51 @@ def StringValueRules(value):
   return value
 
 
+def DictKeyName(dict_name, key_name):
+  """Converts a dict plus key name to a full name.
+
+  """
+  return"%s_%s" % (dict_name, str(key_name).upper())
+
+
+def ConvertVariable(name, value):
+  """Converts a given variable to Haskell code.
+
+  @param name: the Python name
+  @param value: the value
+  @return: a list of Haskell code lines
+
+  """
+  lines = []
+  hs_name = NameRules(name)
+  if not CONSTANT_RE.match(name):
+    lines.append("-- Skipped %s, not constant" % name)
+  elif isinstance(value, basestring):
+    lines.append("-- | Converted from Python constant %s" % name)
+    lines.append("%s :: String" % hs_name)
+    lines.append("%s = \"%s\"" % (hs_name, StringValueRules(value)))
+  elif isinstance(value, int):
+    lines.append("-- | Converted from Python constant %s" % name)
+    lines.append("%s :: Int" % hs_name)
+    lines.append("%s = %d" % (hs_name, value))
+  elif isinstance(value, long):
+    lines.append("-- | Converted from Python constant %s" % name)
+    lines.append("%s :: Integer" % hs_name)
+    lines.append("%s = %d" % (hs_name, value))
+  elif isinstance(value, float):
+    lines.append("-- | Converted from Python constant %s" % name)
+    lines.append("%s :: Double" % hs_name)
+    lines.append("%s = %f" % (hs_name, value))
+  elif isinstance(value, dict):
+    if value:
+      lines.append("-- Following lines come from dictionary %s" % name)
+      for k in sorted(value.keys()):
+        lines.extend(ConvertVariable(DictKeyName(name, k), value[k]))
+  else:
+    lines.append("-- Skipped %s, %s not handled" % (name, type(value)))
+  return lines
+
+
 def Convert():
   """Converts the constants to Haskell.
 
@@ -56,27 +102,7 @@ def Convert():
 
   for name in all_names:
     value = getattr(constants, name)
-    hs_name = NameRules(name)
-    if not CONSTANT_RE.match(name):
-      lines.append("-- Skipped %s, not constant" % name)
-    elif isinstance(value, basestring):
-      lines.append("-- | Converted from Python constant %s" % name)
-      lines.append("%s :: String" % hs_name)
-      lines.append("%s = \"%s\"" % (hs_name, StringValueRules(value)))
-    elif isinstance(value, int):
-      lines.append("-- | Converted from Python constant %s" % name)
-      lines.append("%s :: Int" % hs_name)
-      lines.append("%s = %d" % (hs_name, value))
-    elif isinstance(value, long):
-      lines.append("-- | Converted from Python constant %s" % name)
-      lines.append("%s :: Integer" % hs_name)
-      lines.append("%s = %d" % (hs_name, value))
-    elif isinstance(value, float):
-      lines.append("-- | Converted from Python constant %s" % name)
-      lines.append("%s :: Double" % hs_name)
-      lines.append("%s = %f" % (hs_name, value))
-    else:
-      lines.append("-- Skipped %s, %s not handled" % (name, type(value)))
+    lines.extend(ConvertVariable(name, value))
     lines.append("")
 
   return "\n".join(lines)
