1
1
import io
2
2
import logging
3
+ import os
3
4
import os .path
4
5
import re
5
6
import sys
9
10
add_verbosity_cli ,
10
11
add_traceback_cli ,
11
12
add_sepval_cli ,
13
+ add_progress_cli ,
12
14
add_files_cli ,
13
15
add_commands_cli ,
14
16
process_args_by_key ,
17
19
filter_filenames ,
18
20
iter_marks ,
19
21
)
20
- from c_parser .info import KIND , is_type_decl
22
+ from c_parser .info import KIND
23
+ from c_parser .match import is_type_decl
24
+ from .match import filter_forward
21
25
from . import (
22
26
analyze as _analyze ,
23
- check_all as _check_all ,
24
27
datafiles as _datafiles ,
28
+ check_all as _check_all ,
25
29
)
26
30
27
31
44
48
TABLE_SECTIONS = {
45
49
'types' : (
46
50
['kind' , 'name' , 'data' , 'file' ],
47
- is_type_decl ,
51
+ KIND . is_type_decl ,
48
52
(lambda v : (v .kind .value , v .filename or '' , v .name )),
49
53
),
50
54
'typedefs' : 'types' ,
@@ -167,9 +171,7 @@ def handle_failure(failure, data):
167
171
print (f'{ data .filename } :{ name } - { failure } ' )
168
172
elif fmt == 'summary' :
169
173
def handle_failure (failure , data ):
170
- parent = data .parent or ''
171
- funcname = parent if isinstance (parent , str ) else parent .name
172
- print (f'{ data .filename :35} \t { funcname or "-" :35} \t { data .name :40} \t { failure } ' )
174
+ print (_fmt_one_summary (data , failure ))
173
175
elif fmt == 'full' :
174
176
div = ''
175
177
def handle_failure (failure , data ):
@@ -230,6 +232,15 @@ def section(name):
230
232
yield f'grand total: { total } '
231
233
232
234
235
+ def _fmt_one_summary (item , extra = None ):
236
+ parent = item .parent or ''
237
+ funcname = parent if isinstance (parent , str ) else parent .name
238
+ if extra :
239
+ return f'{ item .filename :35} \t { funcname or "-" :35} \t { item .name :40} \t { extra } '
240
+ else :
241
+ return f'{ item .filename :35} \t { funcname or "-" :35} \t { item .name } '
242
+
243
+
233
244
def fmt_full (analysis ):
234
245
# XXX Support sorting.
235
246
items = sorted (analysis , key = lambda v : v .key )
@@ -272,10 +283,12 @@ def process_checks(args):
272
283
args .checks = [check ]
273
284
else :
274
285
process_checks = add_checks_cli (parser , checks = checks )
286
+ process_progress = add_progress_cli (parser )
275
287
process_output = add_output_cli (parser , default = None )
276
288
process_files = add_files_cli (parser , ** kwargs )
277
289
return [
278
290
process_checks ,
291
+ process_progress ,
279
292
process_output ,
280
293
process_files ,
281
294
]
@@ -288,6 +301,7 @@ def cmd_check(filenames, *,
288
301
relroot = None ,
289
302
failfast = False ,
290
303
iter_filenames = None ,
304
+ track_progress = None ,
291
305
verbosity = VERBOSITY ,
292
306
_analyze = _analyze ,
293
307
_CHECKS = CHECKS ,
@@ -304,36 +318,53 @@ def cmd_check(filenames, *,
304
318
) = _get_check_handlers (fmt , printer , verbosity )
305
319
306
320
filenames = filter_filenames (filenames , iter_filenames )
321
+ if track_progress :
322
+ filenames = track_progress (filenames )
307
323
308
- logger .info ('analyzing...' )
324
+ logger .info ('analyzing files ...' )
309
325
analyzed = _analyze (filenames , ** kwargs )
310
326
if relroot :
311
327
analyzed .fix_filenames (relroot )
328
+ decls = filter_forward (analyzed , markpublic = True )
312
329
313
- logger .info ('checking...' )
314
- numfailed = 0
315
- for data , failure in _check_all (analyzed , checks , failfast = failfast ):
330
+ logger .info ('checking analysis results ...' )
331
+ failed = []
332
+ for data , failure in _check_all (decls , checks , failfast = failfast ):
316
333
if data is None :
317
334
printer .info ('stopping after one failure' )
318
335
break
319
- if div is not None and numfailed > 0 :
336
+ if div is not None and len ( failed ) > 0 :
320
337
printer .info (div )
321
- numfailed += 1
338
+ failed . append ( data )
322
339
handle_failure (failure , data )
323
340
handle_after ()
324
341
325
342
printer .info ('-------------------------' )
326
- logger .info (f'total failures: { numfailed } ' )
343
+ logger .info (f'total failures: { len ( failed ) } ' )
327
344
logger .info ('done checking' )
328
345
329
- if numfailed > 0 :
330
- sys .exit (numfailed )
346
+ if fmt == 'summary' :
347
+ print ('Categorized by storage:' )
348
+ print ()
349
+ from .match import group_by_storage
350
+ grouped = group_by_storage (failed , ignore_non_match = False )
351
+ for group , decls in grouped .items ():
352
+ print ()
353
+ print (group )
354
+ for decl in decls :
355
+ print (' ' , _fmt_one_summary (decl ))
356
+ print (f'subtotal: { len (decls )} ' )
357
+
358
+ if len (failed ) > 0 :
359
+ sys .exit (len (failed ))
331
360
332
361
333
362
def _cli_analyze (parser , ** kwargs ):
363
+ process_progress = add_progress_cli (parser )
334
364
process_output = add_output_cli (parser )
335
365
process_files = add_files_cli (parser , ** kwargs )
336
366
return [
367
+ process_progress ,
337
368
process_output ,
338
369
process_files ,
339
370
]
@@ -343,6 +374,7 @@ def _cli_analyze(parser, **kwargs):
343
374
def cmd_analyze (filenames , * ,
344
375
fmt = None ,
345
376
iter_filenames = None ,
377
+ track_progress = None ,
346
378
verbosity = None ,
347
379
_analyze = _analyze ,
348
380
formats = FORMATS ,
@@ -356,56 +388,54 @@ def cmd_analyze(filenames, *,
356
388
raise ValueError (f'unsupported fmt { fmt !r} ' )
357
389
358
390
filenames = filter_filenames (filenames , iter_filenames )
359
- if verbosity == 2 :
360
- def iter_filenames (filenames = filenames ):
361
- marks = iter_marks ()
362
- for filename in filenames :
363
- print (next (marks ), end = '' )
364
- yield filename
365
- filenames = iter_filenames ()
366
- elif verbosity > 2 :
367
- def iter_filenames (filenames = filenames ):
368
- for filename in filenames :
369
- print (f'<{ filename } >' )
370
- yield filename
371
- filenames = iter_filenames ()
372
-
373
- logger .info ('analyzing...' )
391
+ if track_progress :
392
+ filenames = track_progress (filenames )
393
+
394
+ logger .info ('analyzing files...' )
374
395
analyzed = _analyze (filenames , ** kwargs )
396
+ decls = filter_forward (analyzed , markpublic = True )
375
397
376
- for line in do_fmt (analyzed ):
398
+ for line in do_fmt (decls ):
377
399
print (line )
378
400
379
401
380
402
def _cli_data (parser , filenames = None , known = None ):
381
403
ArgumentParser = type (parser )
382
404
common = ArgumentParser (add_help = False )
383
- if filenames is None :
384
- common .add_argument ('filenames' , metavar = 'FILE' , nargs = '+' )
405
+ # These flags will get processed by the top-level parse_args().
406
+ add_verbosity_cli (common )
407
+ add_traceback_cli (common )
385
408
386
409
subs = parser .add_subparsers (dest = 'datacmd' )
387
410
388
411
sub = subs .add_parser ('show' , parents = [common ])
389
412
if known is None :
390
413
sub .add_argument ('--known' , required = True )
414
+ if filenames is None :
415
+ sub .add_argument ('filenames' , metavar = 'FILE' , nargs = '+' )
391
416
392
- sub = subs .add_parser ('dump' )
417
+ sub = subs .add_parser ('dump' , parents = [ common ] )
393
418
if known is None :
394
419
sub .add_argument ('--known' )
395
420
sub .add_argument ('--show' , action = 'store_true' )
421
+ process_progress = add_progress_cli (sub )
396
422
397
- sub = subs .add_parser ('check' )
423
+ sub = subs .add_parser ('check' , parents = [ common ] )
398
424
if known is None :
399
425
sub .add_argument ('--known' , required = True )
400
426
401
- return None
427
+ def process_args (args ):
428
+ if args .datacmd == 'dump' :
429
+ process_progress (args )
430
+ return process_args
402
431
403
432
404
433
def cmd_data (datacmd , filenames , known = None , * ,
405
434
_analyze = _analyze ,
406
435
formats = FORMATS ,
407
436
extracolumns = None ,
408
437
relroot = None ,
438
+ track_progress = None ,
409
439
** kwargs
410
440
):
411
441
kwargs .pop ('verbosity' , None )
@@ -417,6 +447,8 @@ def cmd_data(datacmd, filenames, known=None, *,
417
447
for line in do_fmt (known ):
418
448
print (line )
419
449
elif datacmd == 'dump' :
450
+ if track_progress :
451
+ filenames = track_progress (filenames )
420
452
analyzed = _analyze (filenames , ** kwargs )
421
453
if known is None or usestdout :
422
454
outfile = io .StringIO ()
0 commit comments