Revision 09dc9a02 autotools/convert-constants

b/autotools/convert-constants
1 1
#!/usr/bin/python
2 2
#
3 3

  
4
# Copyright (C) 2011 Google Inc.
4
# Copyright (C) 2011, 2012 Google Inc.
5 5
#
6 6
# This program is free software; you can redistribute it and/or modify
7 7
# it under the terms of the GNU General Public License as published by
......
23 23
"""
24 24

  
25 25
import re
26
import types
26 27

  
27
from ganeti import constants
28 28
from ganeti import compat
29
from ganeti import constants
30
from ganeti import luxi
29 31

  
30 32
#: Constant name regex
31 33
CONSTANT_RE = re.compile("^[A-Z][A-Z0-9_-]+$")
32 34

  
35
#: Private name regex
36
PRIVATE_RE = re.compile("^__.+__$")
37

  
33 38
#: The type of regex objects
34 39
RE_TYPE = type(CONSTANT_RE)
35 40

  
......
79 84
    return None
80 85

  
81 86

  
82
def ConvertVariable(name, value):
87
def ConvertVariable(prefix, name, value):
83 88
  """Converts a given variable to Haskell code.
84 89

  
90
  @param prefix: a prefix for the Haskell name (useful for module
91
      identification)
85 92
  @param name: the Python name
86 93
  @param value: the value
87 94
  @return: a list of Haskell code lines
88 95

  
89 96
  """
90 97
  lines = []
91
  hs_name = NameRules(name)
98
  if prefix:
99
    pfx_name = prefix + "_"
100
    fqn = prefix + "." + name
101
  else:
102
    pfx_name = ""
103
    fqn = name
104
  hs_name = NameRules(pfx_name + name)
92 105
  hs_typeval = HaskellTypeVal(value)
93
  if not CONSTANT_RE.match(name):
94
    lines.append("-- Skipped %s, not constant" % name)
106
  if (isinstance(value, types.ModuleType) or callable(value) or
107
      PRIVATE_RE.match(name)):
108
    # no sense in marking these, as we don't _want_ to convert them; the
109
    # message in the next if block is for datatypes we don't _know_
110
    # (yet) how to convert
111
    pass
112
  elif not CONSTANT_RE.match(name):
113
    lines.append("-- Skipped %s %s, not constant" % (fqn, type(value)))
95 114
  elif hs_typeval is not None:
96 115
    # this is a simple value
97 116
    (hs_type, hs_val) = hs_typeval
98
    lines.append("-- | Converted from Python constant %s" % name)
117
    lines.append("-- | Converted from Python constant %s" % fqn)
99 118
    lines.append("%s :: %s" % (hs_name, hs_type))
100 119
    lines.append("%s = %s" % (hs_name, hs_val))
101 120
  elif isinstance(value, dict):
102 121
    if value:
103
      lines.append("-- Following lines come from dictionary %s" % name)
122
      lines.append("-- Following lines come from dictionary %s" % fqn)
104 123
      for k in sorted(value.keys()):
105
        lines.extend(ConvertVariable(DictKeyName(name, k), value[k]))
124
        lines.extend(ConvertVariable(prefix, DictKeyName(name, k), value[k]))
106 125
  elif isinstance(value, tuple):
107 126
    tvs = [HaskellTypeVal(elem) for elem in value]
108 127
    if compat.all(e is not None for e in tvs):
109 128
      ttypes = ", ".join(e[0] for e in tvs)
110 129
      tvals = ", ".join(e[1] for e in tvs)
111
      lines.append("-- | Converted from Python tuple %s" % name)
130
      lines.append("-- | Converted from Python tuple %s" % fqn)
112 131
      lines.append("%s :: (%s)" % (hs_name, ttypes))
113 132
      lines.append("%s = (%s)" % (hs_name, tvals))
114 133
    else:
115
      lines.append("-- Skipped tuple %s, cannot convert all elements" % name)
134
      lines.append("-- Skipped tuple %s, cannot convert all elements" % fqn)
116 135
  elif isinstance(value, (list, set, frozenset)):
117 136
    # Lists and frozensets are handled the same in Haskell: as lists,
118 137
    # since lists are immutable and we don't need for constants the
......
126 145
      ttypes, tvals = zip(*tvs)
127 146
      uniq_types = set(ttypes)
128 147
      if len(uniq_types) == 1:
129
        lines.append("-- | Converted from Python list or set %s" % name)
148
        lines.append("-- | Converted from Python list or set %s" % fqn)
130 149
        lines.append("%s :: [%s]" % (hs_name, uniq_types.pop()))
131 150
        lines.append("%s = [%s]" % (hs_name, ", ".join(tvals)))
132 151
      else:
133
        lines.append("-- | Skipped list/set %s, is not homogeneous" % name)
152
        lines.append("-- | Skipped list/set %s, is not homogeneous" % fqn)
134 153
    else:
135
      lines.append("-- | Skipped list/set %s, cannot convert all elems" % name)
154
      lines.append("-- | Skipped list/set %s, cannot convert all elems" % fqn)
136 155
  elif isinstance(value, RE_TYPE):
137 156
    tvs = HaskellTypeVal(value.pattern)
138 157
    assert tvs is not None
139
    lines.append("-- | Converted from Python RE object %s" % name)
158
    lines.append("-- | Converted from Python RE object %s" % fqn)
140 159
    lines.append("%s :: %s" % (hs_name, tvs[0]))
141 160
    lines.append("%s = %s" % (hs_name, tvs[1]))
142 161
  else:
143
    lines.append("-- Skipped %s, %s not handled" % (name, type(value)))
162
    lines.append("-- Skipped %s, %s not handled" % (fqn, type(value)))
144 163
  return lines
145 164

  
146 165

  
147
def Convert():
166
def Convert(module, prefix):
148 167
  """Converts the constants to Haskell.
149 168

  
150 169
  """
151 170
  lines = [""]
152 171

  
153
  all_names = dir(constants)
172
  all_names = dir(module)
154 173

  
155 174
  for name in all_names:
156
    value = getattr(constants, name)
157
    lines.extend(ConvertVariable(name, value))
158
    lines.append("")
175
    value = getattr(module, name)
176
    new_lines = ConvertVariable(prefix, name, value)
177
    if new_lines:
178
      lines.extend(new_lines)
179
      lines.append("")
159 180

  
160 181
  return "\n".join(lines)
161 182

  
162 183

  
163 184
def main():
164
  print Convert()
185
  print Convert(constants, "")
186
  print Convert(luxi, "luxi")
165 187

  
166 188

  
167 189
if __name__ == "__main__":

Also available in: Unified diff