223
223
]
224
224
225
225
# this must match the equivalent function in qstr.c
226
+
227
+
226
228
def compute_hash (qstr , bytes_hash ):
227
229
hash = 5381
228
230
for b in qstr :
@@ -257,7 +259,7 @@ def parse_input_headers(infiles):
257
259
258
260
# add the qstr to the list, with order number to retain original order in file
259
261
order = len (qstrs ) - 300000
260
- qstrs [ident ] = (order , ident , qstr )
262
+ qstrs [ident ] = Qstr (order , ident , qstr )
261
263
262
264
# read the qstrs in from the input files
263
265
for infile in infiles :
@@ -308,7 +310,7 @@ def parse_input_headers(infiles):
308
310
order = - 190000
309
311
elif ident .startswith ("__" ):
310
312
order -= 100000
311
- qstrs [ident ] = (order , ident , qstr )
313
+ qstrs [ident ] = Qstr (order , ident , qstr )
312
314
313
315
if not qcfgs :
314
316
sys .stderr .write ("ERROR: Empty preprocessor output - check for errors above\n " )
@@ -317,31 +319,44 @@ def parse_input_headers(infiles):
317
319
return qcfgs , qstrs
318
320
319
321
320
- def escape_bytes (qstr , qbytes ):
321
- if all (32 <= ord (c ) <= 126 and c != "\\ " and c != '"' for c in qstr ):
322
- # qstr is all printable ASCII so render it as-is (for easier debugging)
323
- return qstr
324
- else :
325
- # qstr contains non-printable codes so render entire thing as hex pairs
326
- return "" .join (("\\ x%02x" % b ) for b in qbytes )
322
+ class Qstr :
323
+ cfg_bytes_len = 0
324
+ cfg_bytes_hash = 0
327
325
326
+ def __init__ (self , order , ident , qstr ):
327
+ self .order = order
328
+ self .ident = ident
329
+ self .qstr = qstr
328
330
329
- def make_bytes (cfg_bytes_len , cfg_bytes_hash , qstr ):
330
- qbytes = bytes_cons (qstr , "utf8" )
331
- qlen = len (qbytes )
332
- qhash = compute_hash (qbytes , cfg_bytes_hash )
333
- if qlen >= (1 << (8 * cfg_bytes_len )):
334
- print ("qstr is too long:" , qstr )
335
- assert False
336
- qdata = escape_bytes (qstr , qbytes )
337
- return '%d, %d, "%s"' % (qhash , qlen , qdata )
331
+ @property
332
+ def qbytes (self ):
333
+ return bytes_cons (self .qstr , "utf8" )
338
334
335
+ @property
336
+ def qlen (self ):
337
+ if len (self .qbytes ) >= (1 << (8 * Qstr .cfg_bytes_len )):
338
+ print ("qstr is too long:" , self .qstr )
339
+ assert False
340
+ return len (self .qbytes )
339
341
340
- def print_qstr_data (qcfgs , qstrs ):
341
- # get config variables
342
- cfg_bytes_len = int (qcfgs ["BYTES_IN_LEN" ])
343
- cfg_bytes_hash = int (qcfgs ["BYTES_IN_HASH" ])
342
+ @property
343
+ def qhash (self ):
344
+ return compute_hash (self .qbytes , Qstr .cfg_bytes_hash )
345
+
346
+ def _escape_bytes (self ):
347
+ if all (32 <= ord (c ) <= 126 and c != "\\ " and c != '"' for c in self .qstr ):
348
+ # qstr is all printable ASCII so render it as-is (for easier debugging)
349
+ return self .qstr
350
+ else :
351
+ # qstr contains non-printable codes so render entire thing as hex pairs
352
+ return "" .join (("\\ x%02x" % b ) for b in self .qbytes )
353
+
354
+ @property
355
+ def qdata (self ):
356
+ return self ._escape_bytes ()
344
357
358
+
359
+ def print_qstr_data (qstrs ):
345
360
# print out the starter of the generated C header file
346
361
print ("// This file was automatically generated by makeqstrdata.py" )
347
362
print ("" )
@@ -350,23 +365,26 @@ def print_qstr_data(qcfgs, qstrs):
350
365
print ('QDEF0(MP_QSTRnull, 0, 0, "")' )
351
366
352
367
# split qstr values into two pools. static consts first.
353
- q0_values = [q for q in qstrs .values () if q [ 0 ] < 0 ]
354
- q1_values = [q for q in qstrs .values () if q [ 0 ] >= 0 ]
368
+ q0_values = [q for q in qstrs .values () if q . order < 0 ]
369
+ q1_values = [q for q in qstrs .values () if q . order >= 0 ]
355
370
356
371
# go through each qstr in pool 0 and print it out. pool0 has special sort.
357
- for order , ident , qstr in sorted (q0_values , key = lambda x : x [0 ]):
358
- qbytes = make_bytes (cfg_bytes_len , cfg_bytes_hash , qstr )
359
- print ("QDEF0(MP_QSTR_%s, %s)" % (ident , qbytes ))
372
+ for q in sorted (q0_values , key = lambda x : x .order ):
373
+ print ('QDEF0(MP_QSTR_%s, %d, %d, "%s")' % (q .ident , q .qhash , q .qlen , q .qdata ))
360
374
361
375
# go through each qstr in pool 1 and print it out. pool1 is regularly sorted.
362
- for order , ident , qstr in sorted (q1_values , key = lambda x : x [2 ]):
363
- qbytes = make_bytes (cfg_bytes_len , cfg_bytes_hash , qstr )
364
- print ("QDEF1(MP_QSTR_%s, %s)" % (ident , qbytes ))
376
+ for q in sorted (q1_values , key = lambda x : x .qstr ):
377
+ print ('QDEF1(MP_QSTR_%s, %d, %d, "%s")' % (q .ident , q .qhash , q .qlen , q .qdata ))
365
378
366
379
367
380
def do_work (infiles ):
368
381
qcfgs , qstrs = parse_input_headers (infiles )
369
- print_qstr_data (qcfgs , qstrs )
382
+
383
+ # get config variables
384
+ Qstr .cfg_bytes_len = int (qcfgs ["BYTES_IN_LEN" ])
385
+ Qstr .cfg_bytes_hash = int (qcfgs ["BYTES_IN_HASH" ])
386
+
387
+ print_qstr_data (qstrs )
370
388
371
389
372
390
if __name__ == "__main__" :
0 commit comments