~malept/ubuntu/lucid/python2.6/dev-dependency-fix

« back to all changes in this revision

Viewing changes to Tools/framer/framer/function.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-02-13 12:51:00 UTC
  • Revision ID: james.westby@ubuntu.com-20090213125100-uufgcb9yeqzujpqw
Tags: upstream-2.6.1
ImportĀ upstreamĀ versionĀ 2.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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