comparison contrib/tools/csv_to_fd @ 1494:ae76ea63ee12

csv_to_fd: improve comments and usage
author Luke Mewburn <luke@mewburn.net>
date Mon, 30 Mar 2020 16:46:31 +1100
parents 5c2d061a8c8e
children 01efba83bf60
comparison
equal deleted inserted replaced
1493:a89913941dcf 1494:ae76ea63ee12
8 - Row per 3GPP AVP tables: 8 - Row per 3GPP AVP tables:
9 Name, Code, Section, DataType, Must, May, ShouldNot, MustNot [, extra] 9 Name, Code, Section, DataType, Must, May, ShouldNot, MustNot [, extra]
10 - Name: 10 - Name:
11 AVP Name. String, validated as ALPHA *(ALPHA / DIGIT / "-") 11 AVP Name. String, validated as ALPHA *(ALPHA / DIGIT / "-")
12 per RFC 6733 section 3.2. 12 per RFC 6733 section 3.2.
13 May start with a DIGIT (e.g., "3GPP-IMSI").
13 - Code: 14 - Code:
14 AVP Code. Integer, 0..4294967295. 15 AVP Code. Integer, 0..4294967295.
15 - Section: 16 - Section:
16 Section in relevant standard. String. 17 Section in relevant standard. String.
17 - DataType: 18 - DataType:
18 AVP Data Type. String, validated per basic and derived types in: 19 AVP Data Type. String, validated per basic and derived types in:
19 - RFC 6733 section 4.2 20 - RFC 6733 section 4.2
20 - RFC 6733 section 4.3 21 - RFC 6733 section 4.3
21 - RFC 7155 section 4.1 22 - RFC 7155 section 4.1
22 - Must, May, ShouldNot, MustNot: 23 - Must, May, ShouldNot, MustNot:
23 Flags, possibly comma or space separated: M, V 24 Flags, possibly comma or space separated: M, P, V
24 25
25 - Comment row. First cell: 26 - Comment row. First cell:
26 # Comment text 'Comment text' 27 # Comment text 'Comment text'
27 #= '/*========*/' 28 #= '/*========*/'
28 # Blank line 29 # Blank line
180 def description(self): 181 def description(self):
181 return 'AVP "{}" ({})'.format(self.name, self.code) 182 return 'AVP "{}" ({})'.format(self.name, self.code)
182 183
183 184
184 class Processor(object): 185 class Processor(object):
185 """Interface for processor of Avp""" 186 """Interface for processor of Avp."""
186 187
187 __metaclass__ = abc.ABCMeta 188 __metaclass__ = abc.ABCMeta
188 189
189 @classmethod 190 @classmethod
190 def cls_name(cls): 191 def cls_name(cls):
224 """Invoked after all rows processed.""" 225 """Invoked after all rows processed."""
225 pass 226 pass
226 227
227 228
228 class DebugProcessor(Processor): 229 class DebugProcessor(Processor):
229 """Display the CSV parsing""" 230 """Display the CSV parsing."""
230 231
231 def next_file(self, filename): 232 def next_file(self, filename):
232 print('File: {}'.format(filename)) 233 print('File: {}'.format(filename))
233 234
234 def avp(self, avp): 235 def avp(self, avp):
241 def generate(self): 242 def generate(self):
242 print('Generate') 243 print('Generate')
243 244
244 245
245 class NoopProcessor(Processor): 246 class NoopProcessor(Processor):
246 """Validate the CSV; no other output""" 247 """Validate the CSV; no other output."""
247 248
248 def next_file(self, filename): 249 def next_file(self, filename):
249 pass 250 pass
250 251
251 def avp(self, avp): 252 def avp(self, avp):
257 def generate(self): 258 def generate(self):
258 pass 259 pass
259 260
260 261
261 class FdcProcessor(Processor): 262 class FdcProcessor(Processor):
262 """Generate freeDiameter C code 263 """Generate freeDiameter C code.
263 264
264 Comment cells are parsed as: 265 Comment cells are parsed as:
265 # text comment /* text comment */ 266 # text comment /* text comment */
266 #= /*==============*/ 267 #= /*==============*/
267 # [blank line] 268 # [blank line]
372 def print_header(self): 373 def print_header(self):
373 print(self.format_header()) 374 print(self.format_header())
374 375
375 376
376 class JsonProcessor(Processor): 377 class JsonProcessor(Processor):
377 """Generate freeDiameter JSON object 378 """Generate freeDiameter JSON object.
378 """ 379 """
379 380
380 def __init__(self): 381 def __init__(self):
381 self.avps = [] 382 self.avps = []
382 383
458 optparse.OptionParser.format_help(self, formatter), 459 optparse.OptionParser.format_help(self, formatter),
459 processor_help) 460 processor_help)
460 461
461 # Parse options 462 # Parse options
462 parser = MyParser( 463 parser = MyParser(
464 usage='%prog [-h] [-p PROCESSOR] FILE ...',
463 description="""\ 465 description="""\
464 Convert CSV files containing RADIUS or Diameter AVP tables 466 Convert CSV files FILE ... containing RADIUS or Diameter AVP tables
465 into various formats using the specified processor PROCESSOR. 467 into various formats using the specified processor PROCESSOR.
466 """) 468 """)
467 469
468 parser.add_option( 470 parser.add_option(
469 '-p', '--processor', 471 '-p', '--processor',
470 default='noop', 472 default='noop',
471 help='AVP processor. One of: {}. [%default]'.format( 473 help='AVP processor. One of: {}. [%default]'.format(
472 ', '.join(processors.keys()))) 474 ', '.join(processors.keys())))
473 (opts, args) = parser.parse_args() 475 (opts, args) = parser.parse_args()
474 if len(args) < 1: 476 if len(args) < 1:
475 parser.error('Incorrect number of arguments') 477 parser.error('Incorrect number of arguments. Use -h for help.')
476 478
477 # Find processor 479 # Find processor
478 try: 480 try:
479 avpproc = processors[opts.processor]() 481 avpproc = processors[opts.processor]()
480 except KeyError as e: 482 except KeyError as e:
481 parser.error('Unknown processor "{}"'.format(opts.processor)) 483 parser.error('Unknown processor "{}".'.format(opts.processor))
482 484
483 # dict of [vendor][code] : Avp 485 # dict of [vendor][code] : Avp
484 avp_codes = collections.defaultdict(dict) 486 avp_codes = collections.defaultdict(dict)
485 487
486 # dict of [vendor][name] : Avp 488 # dict of [vendor][name] : Avp
"Welcome to our mercurial repository"