Mercurial > cpython-lru_cache-weakref
annotate Tools/scripts/abitype.py @ 79691:05c8928362ee
Merge __next__ method link fixes with 3.3.
| author | Ezio Melotti <ezio.melotti@gmail.com> |
|---|---|
| date | Fri, 12 Oct 2012 13:46:37 +0300 |
| parents | 62dde5dd475e |
| children | 26531f21bc4c |
| rev | line source |
|---|---|
|
71557
65d5ecefd50d
Fix missing or wrong shebangs and missing executable bits for scripts (#10318)
Éric Araujo <merwok@netwok.org>
parents:
67924
diff
changeset
|
1 #!/usr/bin/env python3 |
| 66664 | 2 # This script converts a C file to use the PEP 384 type definition API |
| 3 # Usage: abitype.py < old_code > new_code | |
| 4 import re, sys | |
| 5 | |
| 6 ###### Replacement of PyTypeObject static instances ############## | |
| 7 | |
| 8 # classify each token, giving it a one-letter code: | |
| 9 # S: static | |
| 10 # T: PyTypeObject | |
| 11 # I: ident | |
| 12 # W: whitespace | |
| 13 # =, {, }, ; : themselves | |
| 14 def classify(): | |
| 15 res = [] | |
| 16 for t,v in tokens: | |
| 17 if t == 'other' and v in "={};": | |
| 18 res.append(v) | |
| 19 elif t == 'ident': | |
| 20 if v == 'PyTypeObject': | |
| 21 res.append('T') | |
| 22 elif v == 'static': | |
| 23 res.append('S') | |
| 24 else: | |
| 25 res.append('I') | |
| 26 elif t == 'ws': | |
| 27 res.append('W') | |
| 28 else: | |
| 29 res.append('.') | |
| 30 return ''.join(res) | |
| 31 | |
| 32 # Obtain a list of fields of a PyTypeObject, in declaration order, | |
| 33 # skipping ob_base | |
| 34 # All comments are dropped from the variable (which are typically | |
| 35 # just the slot names, anyway), and information is discarded whether | |
| 36 # the original type was static. | |
| 37 def get_fields(start, real_end): | |
| 38 pos = start | |
| 39 # static? | |
| 40 if tokens[pos][1] == 'static': | |
| 41 pos += 2 | |
| 42 # PyTypeObject | |
| 43 pos += 2 | |
| 44 # name | |
| 45 name = tokens[pos][1] | |
| 46 pos += 1 | |
| 47 while tokens[pos][1] != '{': | |
| 48 pos += 1 | |
| 49 pos += 1 | |
| 50 # PyVarObject_HEAD_INIT | |
| 51 while tokens[pos][0] in ('ws', 'comment'): | |
| 52 pos += 1 | |
| 53 if tokens[pos][1] != 'PyVarObject_HEAD_INIT': | |
|
76106
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
54 raise Exception('%s has no PyVarObject_HEAD_INIT' % name) |
| 66664 | 55 while tokens[pos][1] != ')': |
| 56 pos += 1 | |
| 57 pos += 1 | |
| 58 # field definitions: various tokens, comma-separated | |
| 59 fields = [] | |
| 60 while True: | |
| 61 while tokens[pos][0] in ('ws', 'comment'): | |
| 62 pos += 1 | |
| 63 end = pos | |
| 64 while tokens[end][1] not in ',}': | |
| 65 if tokens[end][1] == '(': | |
| 66 nesting = 1 | |
| 67 while nesting: | |
| 68 end += 1 | |
| 69 if tokens[end][1] == '(': nesting+=1 | |
| 70 if tokens[end][1] == ')': nesting-=1 | |
| 71 end += 1 | |
| 72 assert end < real_end | |
| 73 # join field, excluding separator and trailing ws | |
| 74 end1 = end-1 | |
| 75 while tokens[end1][0] in ('ws', 'comment'): | |
| 76 end1 -= 1 | |
| 77 fields.append(''.join(t[1] for t in tokens[pos:end1+1])) | |
| 78 if tokens[end][1] == '}': | |
| 79 break | |
| 80 pos = end+1 | |
| 81 return name, fields | |
| 82 | |
| 83 # List of type slots as of Python 3.2, omitting ob_base | |
| 84 typeslots = [ | |
| 85 'tp_name', | |
| 86 'tp_basicsize', | |
| 87 'tp_itemsize', | |
| 88 'tp_dealloc', | |
| 89 'tp_print', | |
| 90 'tp_getattr', | |
| 91 'tp_setattr', | |
| 92 'tp_reserved', | |
| 93 'tp_repr', | |
| 94 'tp_as_number', | |
| 95 'tp_as_sequence', | |
| 96 'tp_as_mapping', | |
| 97 'tp_hash', | |
| 98 'tp_call', | |
| 99 'tp_str', | |
| 100 'tp_getattro', | |
| 101 'tp_setattro', | |
| 102 'tp_as_buffer', | |
| 103 'tp_flags', | |
| 104 'tp_doc', | |
| 105 'tp_traverse', | |
| 106 'tp_clear', | |
| 107 'tp_richcompare', | |
| 108 'tp_weaklistoffset', | |
| 109 'tp_iter', | |
| 110 'iternextfunc', | |
| 111 'tp_methods', | |
| 112 'tp_members', | |
| 113 'tp_getset', | |
| 114 'tp_base', | |
| 115 'tp_dict', | |
| 116 'tp_descr_get', | |
| 117 'tp_descr_set', | |
| 118 'tp_dictoffset', | |
| 119 'tp_init', | |
| 120 'tp_alloc', | |
| 121 'tp_new', | |
| 122 'tp_free', | |
| 123 'tp_is_gc', | |
| 124 'tp_bases', | |
| 125 'tp_mro', | |
| 126 'tp_cache', | |
| 127 'tp_subclasses', | |
| 128 'tp_weaklist', | |
| 129 'tp_del' | |
| 130 'tp_version_tag' | |
| 131 ] | |
| 132 | |
| 133 # Generate a PyType_Spec definition | |
| 134 def make_slots(name, fields): | |
| 135 res = [] | |
| 136 res.append('static PyType_Slot %s_slots[] = {' % name) | |
| 137 # defaults for spec | |
|
67924
20d82873aa97
Issue #11135: Remove redundant doc field from PyType_Spec.
Martin v. Löwis <martin@v.loewis.de>
parents:
66664
diff
changeset
|
138 spec = { 'tp_itemsize':'0' } |
| 66664 | 139 for i, val in enumerate(fields): |
| 140 if val.endswith('0'): | |
| 141 continue | |
| 142 if typeslots[i] in ('tp_name', 'tp_doc', 'tp_basicsize', | |
| 143 'tp_itemsize', 'tp_flags'): | |
| 144 spec[typeslots[i]] = val | |
| 145 continue | |
| 146 res.append(' {Py_%s, %s},' % (typeslots[i], val)) | |
| 147 res.append('};') | |
| 148 res.append('static PyType_Spec %s_spec = {' % name) | |
| 149 res.append(' %s,' % spec['tp_name']) | |
| 150 res.append(' %s,' % spec['tp_basicsize']) | |
| 151 res.append(' %s,' % spec['tp_itemsize']) | |
| 152 res.append(' %s,' % spec['tp_flags']) | |
| 153 res.append(' %s_slots,' % name) | |
| 154 res.append('};\n') | |
| 155 return '\n'.join(res) | |
| 156 | |
| 157 | |
|
76106
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
158 if __name__ == '__main__': |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
159 |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
160 ############ Simplistic C scanner ################################## |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
161 tokenizer = re.compile( |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
162 r"(?P<preproc>#.*\n)" |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
163 r"|(?P<comment>/\*.*?\*/)" |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
164 r"|(?P<ident>[a-zA-Z_][a-zA-Z0-9_]*)" |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
165 r"|(?P<ws>[ \t\n]+)" |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
166 r"|(?P<other>.)", |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
167 re.MULTILINE) |
| 66664 | 168 |
|
76106
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
169 tokens = [] |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
170 source = sys.stdin.read() |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
171 pos = 0 |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
172 while pos != len(source): |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
173 m = tokenizer.match(source, pos) |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
174 tokens.append([m.lastgroup, m.group()]) |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
175 pos += len(tokens[-1][1]) |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
176 if tokens[-1][0] == 'preproc': |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
177 # continuation lines are considered |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
178 # only in preprocess statements |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
179 while tokens[-1][1].endswith('\\\n'): |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
180 nl = source.find('\n', pos) |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
181 if nl == -1: |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
182 line = source[pos:] |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
183 else: |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
184 line = source[pos:nl+1] |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
185 tokens[-1][1] += line |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
186 pos += len(line) |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
187 |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
188 # Main loop: replace all static PyTypeObjects until |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
189 # there are none left. |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
190 while 1: |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
191 c = classify() |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
192 m = re.search('(SW)?TWIW?=W?{.*?};', c) |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
193 if not m: |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
194 break |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
195 start = m.start() |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
196 end = m.end() |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
197 name, fields = get_fields(start, m) |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
198 tokens[start:end] = [('',make_slots(name, fields))] |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
199 |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
200 # Output result to stdout |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
201 for t, v in tokens: |
|
62dde5dd475e
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
R David Murray <rdmurray@bitdance.com>
parents:
71557
diff
changeset
|
202 sys.stdout.write(v) |
