Statistics
| Branch: | Tag: | Revision:

root / autotools / convert-constants @ df41d855

History | View | Annotate | Download (3.2 kB)

1
#!/usr/bin/python
2
#
3

    
4
# Copyright (C) 2011 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

    
21
"""Script for converting Python constants to Haskell code fragments.
22

    
23
"""
24

    
25
import re
26

    
27
from ganeti import constants
28

    
29
CONSTANT_RE = re.compile("^[A-Z][A-Z0-9_-]+$")
30

    
31

    
32
def NameRules(name):
33
  """Converts the upper-cased Python name to Haskell camelCase.
34

    
35
  """
36
  name = name.replace("-", "_")
37
  elems = name.split("_")
38
  return elems[0].lower() + "".join(e.capitalize() for e in elems[1:])
39

    
40

    
41
def StringValueRules(value):
42
  """Converts a string value from Python to Haskell.
43

    
44
  """
45
  value = value.encode("string_escape") # escapes backslashes
46
  value = value.replace("\"", "\\\"")
47
  return value
48

    
49

    
50
def DictKeyName(dict_name, key_name):
51
  """Converts a dict plus key name to a full name.
52

    
53
  """
54
  return"%s_%s" % (dict_name, str(key_name).upper())
55

    
56

    
57
def HaskellTypeVal(value):
58
  """Returns the Haskell type and value for a Python value.
59

    
60
  Note that this only work for 'plain' Python types.
61

    
62
  @returns: (string, string) or None, if we can't determine the type.
63

    
64
  """
65
  if isinstance(value, basestring):
66
    return ("String", "\"%s\"" % StringValueRules(value))
67
  elif isinstance(value, int):
68
    return ("Int", "%d" % value)
69
  elif isinstance(value, long):
70
    return ("Integer", "%d" % value)
71
  elif isinstance(value, float):
72
    return ("Double", "%f" % value)
73
  else:
74
    return None
75

    
76

    
77
def ConvertVariable(name, value):
78
  """Converts a given variable to Haskell code.
79

    
80
  @param name: the Python name
81
  @param value: the value
82
  @return: a list of Haskell code lines
83

    
84
  """
85
  lines = []
86
  hs_name = NameRules(name)
87
  hs_typeval = HaskellTypeVal(value)
88
  if not CONSTANT_RE.match(name):
89
    lines.append("-- Skipped %s, not constant" % name)
90
  elif hs_typeval is not None:
91
    # this is a simple value
92
    (hs_type, hs_val) = hs_typeval
93
    lines.append("-- | Converted from Python constant %s" % name)
94
    lines.append("%s :: %s" % (hs_name, hs_type))
95
    lines.append("%s = %s" % (hs_name, hs_val))
96
  elif isinstance(value, dict):
97
    if value:
98
      lines.append("-- Following lines come from dictionary %s" % name)
99
      for k in sorted(value.keys()):
100
        lines.extend(ConvertVariable(DictKeyName(name, k), value[k]))
101
  else:
102
    lines.append("-- Skipped %s, %s not handled" % (name, type(value)))
103
  return lines
104

    
105

    
106
def Convert():
107
  """Converts the constants to Haskell.
108

    
109
  """
110
  lines = [""]
111

    
112
  all_names = dir(constants)
113

    
114
  for name in all_names:
115
    value = getattr(constants, name)
116
    lines.extend(ConvertVariable(name, value))
117
    lines.append("")
118

    
119
  return "\n".join(lines)
120

    
121

    
122
def main():
123
  print Convert()
124

    
125

    
126
if __name__ == "__main__":
127
  main()