]> git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Python/Python-2.7.2/Tools/framer/framer/function.py
AppPkg/Applications/Python: Add Python 2.7.2 sources since the release of Python...
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Tools / framer / framer / function.py
1 """Functions."""
2
3 from framer import template
4 from framer.util import cstring, unindent
5
6 METH_O = "METH_O"
7 METH_NOARGS = "METH_NOARGS"
8 METH_VARARGS = "METH_VARARGS"
9
10 def parsefmt(fmt):
11 for c in fmt:
12 if c == '|':
13 continue
14 yield c
15
16 class Argument:
17
18 def __init__(self, name):
19 self.name = name
20 self.ctype = "PyObject *"
21 self.default = None
22
23 def __str__(self):
24 return "%s%s" % (self.ctype, self.name)
25
26 def setfmt(self, code):
27 self.ctype = self._codes[code]
28 if self.ctype[-1] != "*":
29 self.ctype += " "
30
31 _codes = {"O": "PyObject *",
32 "i": "int",
33 }
34
35 def decl(self):
36 if self.default is None:
37 return str(self) + ";"
38 else:
39 return "%s = %s;" % (self, self.default)
40
41 class _ArgumentList(object):
42
43 # these instance variables should be initialized by subclasses
44 ml_meth = None
45 fmt = None
46
47 def __init__(self, args):
48 self.args = map(Argument, args)
49
50 def __len__(self):
51 return len(self.args)
52
53 def __getitem__(self, i):
54 return self.args[i]
55
56 def dump_decls(self, f):
57 pass
58
59 class NoArgs(_ArgumentList):
60
61 def __init__(self, args):
62 assert len(args) == 0
63 super(NoArgs, self).__init__(args)
64 self.ml_meth = METH_NOARGS
65
66 def c_args(self):
67 return "PyObject *self"
68
69 class OneArg(_ArgumentList):
70
71 def __init__(self, args):
72 assert len(args) == 1
73 super(OneArg, self).__init__(args)
74 self.ml_meth = METH_O
75
76 def c_args(self):
77 return "PyObject *self, %s" % self.args[0]
78
79 class VarArgs(_ArgumentList):
80
81 def __init__(self, args, fmt=None):
82 super(VarArgs, self).__init__(args)
83 self.ml_meth = METH_VARARGS
84 if fmt is not None:
85 self.fmt = fmt
86 i = 0
87 for code in parsefmt(fmt):
88 self.args[i].setfmt(code)
89 i += 1
90
91 def c_args(self):
92 return "PyObject *self, PyObject *args"
93
94 def targets(self):
95 return ", ".join(["&%s" % a.name for a in self.args])
96
97 def dump_decls(self, f):
98 for a in self.args:
99 print >> f, " %s" % a.decl()
100
101 def ArgumentList(func, method):
102 code = func.func_code
103 args = code.co_varnames[:code.co_argcount]
104 if method:
105 args = args[1:]
106 pyarg = getattr(func, "pyarg", None)
107 if pyarg is not None:
108 args = VarArgs(args, pyarg)
109 if func.func_defaults:
110 L = list(func.func_defaults)
111 ndefault = len(L)
112 i = len(args) - ndefault
113 while L:
114 args[i].default = L.pop(0)
115 return args
116 else:
117 if len(args) == 0:
118 return NoArgs(args)
119 elif len(args) == 1:
120 return OneArg(args)
121 else:
122 return VarArgs(args)
123
124 class Function:
125
126 method = False
127
128 def __init__(self, func, parent):
129 self._func = func
130 self._parent = parent
131 self.analyze()
132 self.initvars()
133
134 def dump(self, f):
135 def p(templ, vars=None): # helper function to generate output
136 if vars is None:
137 vars = self.vars
138 print >> f, templ % vars
139
140 if self.__doc__:
141 p(template.docstring)
142
143 d = {"name" : self.vars["CName"],
144 "args" : self.args.c_args(),
145 }
146 p(template.funcdef_start, d)
147
148 self.args.dump_decls(f)
149
150 if self.args.ml_meth == METH_VARARGS:
151 p(template.varargs)
152
153 p(template.funcdef_end)
154
155 def analyze(self):
156 self.__doc__ = self._func.__doc__
157 self.args = ArgumentList(self._func, self.method)
158
159 def initvars(self):
160 v = self.vars = {}
161 v["PythonName"] = self._func.__name__
162 s = v["CName"] = "%s_%s" % (self._parent.name, self._func.__name__)
163 v["DocstringVar"] = s + "_doc"
164 v["MethType"] = self.args.ml_meth
165 if self.__doc__:
166 v["Docstring"] = cstring(unindent(self.__doc__))
167 if self.args.fmt is not None:
168 v["ArgParse"] = self.args.fmt
169 v["ArgTargets"] = self.args.targets()
170
171 class Method(Function):
172
173 method = True