Changeset 1498:01efba83bf60 in freeDiameter for contrib
- Timestamp:
- Apr 3, 2020, 9:37:26 AM (4 years ago)
- Branch:
- default
- Phase:
- public
- committer:
- Luke Mewburn <luke@mewburn.net> 1585876473 -39600
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
contrib/tools/csv_to_fd
r1494 r1498 205 205 206 206 @abc.abstractmethod 207 def next_file(self, filename):207 def filename(self, filename): 208 208 """Called when a file is opened.""" 209 209 pass … … 226 226 pass 227 227 228 @abc.abstractmethod 229 def parameter(self, name, value): 230 """Process a parameter row: 231 @name,value. 232 """ 233 pass 234 228 235 229 236 class DebugProcessor(Processor): 230 237 """Display the CSV parsing.""" 231 238 232 def next_file(self, filename):239 def filename(self, filename): 233 240 print('File: {}'.format(filename)) 234 241 … … 243 250 print('Generate') 244 251 252 def parameter(self, name, value): 253 print('Parameter: {} {}'.format(name, value)) 254 245 255 246 256 class NoopProcessor(Processor): 247 257 """Validate the CSV; no other output.""" 248 258 249 def next_file(self, filename):259 def filename(self, filename): 250 260 pass 251 261 … … 257 267 258 268 def generate(self): 269 pass 270 271 def parameter(self, name, value): 259 272 pass 260 273 … … 271 284 COMMENT_WIDTH = 64 272 285 286 class AvpFunction(object): 287 """Maintain per-function state to create DICT_AVP entries. 288 """ 289 290 def __init__(self, name): 291 self.__name = name 292 self.__lines = [] 293 self.__derived = set() 294 295 @property 296 def name(self): 297 """Return name.""" 298 return self.__name 299 300 @property 301 def lines(self): 302 """Return all lines.""" 303 return self.__lines 304 305 @lines.setter 306 def lines(self, value): 307 """Set to append a line.""" 308 self.__lines.append(value) 309 310 @property 311 def derived(self): 312 """Return list of all derived values.""" 313 return list(self.__derived) 314 315 @derived.setter 316 def derived(self, value): 317 """Set to store a derived type.""" 318 self.__derived.add(value) 319 273 320 def __init__(self): 274 self. filenames = []275 self. lines = []276 277 def next_file(self, filename):278 self. filenames.append(os.path.basename(filename))321 self._filenames = [] 322 self._functions = collections.OrderedDict() 323 324 def filename(self, filename): 325 self._filenames.append(os.path.basename(filename)) 279 326 280 327 def avp(self, avp): … … 312 359 elif avp.datatype in DERIVED_TO_BASE: 313 360 avp_type = '{}_type'.format(avp.datatype) 361 self.derived(avp.datatype) 314 362 self.add('\t\tCHECK_dict_new(DICT_AVP, &data, {}, NULL);'.format( 315 363 avp_type)) … … 329 377 330 378 def generate(self): 331 self.print_header() 332 self.print_comment('Start of generated data.') 333 self.print_comment('') 334 self.print_comment('The following is created automatically with:') 335 self.print_comment(' csv_to_fd -p {} {}'.format( 336 self.cls_name(), ' '.join(self.filenames))) 337 self.print_comment('Changes will be lost during the next update.') 338 self.print_comment('Do not modify;' 339 ' modify the source .csv file instead.') 340 self.print_header() 341 print('') 342 print('\n'.join(self.lines)) 343 self.print_header() 344 self.print_comment('End of generated data.') 345 self.print_header() 379 fp = sys.stdout 380 self.write_introduction(fp) 381 for func in self._functions: 382 self.write_function(fp, self._functions[func]) 383 384 def parameter(self, name, value): 385 pass 386 387 # internal methods 388 389 def current_avpfunction(self): 390 """Return current AvpFunction to update. 391 392 Note: allows for easier future enhancement to generate separate 393 C functions per AVP groups such as: by csv file, standard, or vendor. 394 """ 395 name = 'add_avps' 396 if name not in self._functions: 397 self._functions[name] = self.AvpFunction(name) 398 return self._functions[name] 399 400 def add(self, line): 401 self.current_avpfunction().lines = line 402 403 def derived(self, value): 404 self.current_avpfunction().derived = value 405 406 def build_c_token(self, value): 407 """Convert a string into a valid C token.""" 408 return re.sub(r'[^\w]', '_', value) 346 409 347 410 def build_flags(self, flags): … … 353 416 return ' |'.join(result) 354 417 355 def add(self, line):356 self.lines.append(line)357 358 418 def add_comment(self, comment): 359 self. lines.append(self.format_comment(comment))419 self.add(self.format_comment(comment)) 360 420 361 421 def add_header(self): 362 self. lines.append(self.format_header())422 self.add(self.format_header()) 363 423 364 424 def format_comment(self, comment): … … 368 428 return '\t/*={:=<{width}}=*/'.format('', width=self.COMMENT_WIDTH) 369 429 370 def print_comment(self, comment): 371 print(self.format_comment(comment)) 372 373 def print_header(self): 374 print(self.format_header()) 430 def write_introduction(self, fp): 431 """Write the introduction to the generated file.""" 432 fp.write('''\ 433 /* 434 Generated by: 435 \tcsv_to_fd -p {processor} {files} 436 437 Do not modify; modify the source .csv files instead. 438 */ 439 440 #include <freeDiameter/extension.h> 441 442 #define CHECK_dict_new( _type, _data, _parent, _ref ) \\ 443 \tCHECK_FCT( fd_dict_new( fd_g_config->cnf_dict, \ 444 (_type), (_data), (_parent), (_ref)) ); 445 446 #define CHECK_dict_search( _type, _criteria, _what, _result ) \\ 447 \tCHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, \ 448 (_type), (_criteria), (_what), (_result), ENOENT) ); 449 '''.format( 450 processor=self.cls_name(), 451 files=' '.join(self._filenames))) 452 453 def write_function(self, fp, avpfunction): 454 """Generate a function from AvpFunction.""" 455 function = self.build_c_token(avpfunction.name) 456 # Function start 457 fp.write('''\ 458 459 int {}() 460 {{ 461 '''.format(function)) 462 463 # Create variables used by derived type validation 464 for derived in avpfunction.derived: 465 fp.write('''\ 466 \tstruct dict_object * {name}_type = NULL; 467 \tCHECK_dict_search(DICT_TYPE, TYPE_BY_NAME, "{name}", &{name}_type); 468 469 '''.format(name=derived)) 470 471 # Write generated DICT_AVP creation 472 fp.write('\n'.join(avpfunction.lines)) 473 474 # Write function end 475 fp.write('''\ 476 477 \treturn 0; 478 }} /* {}() */ 479 '''.format(function)) 375 480 376 481 … … 382 487 self.avps = [] 383 488 384 def next_file(self, filename):489 def filename(self, filename): 385 490 pass 386 491 … … 405 510 doc = {"AVPs": self.avps} 406 511 print(json.dumps(doc, indent=2)) 512 513 def parameter(self, name, value): 514 pass 407 515 408 516 def build_flags(self, flags): … … 467 575 into various formats using the specified processor PROCESSOR. 468 576 """) 469 470 577 parser.add_option( 471 578 '-p', '--processor', … … 491 598 # Process files 492 599 for filename in args: 493 avpproc. next_file(filename)600 avpproc.filename(filename) 494 601 with open(filename, 'r') as csvfile: 495 602 csvdata = csv.DictReader(csvfile, CSV_COLUMN_NAMES, … … 517 624 raise ValueError('Unknown parameter "{}"'.format( 518 625 parameter)) 626 avpproc.parameter(parameter, value) 519 627 else: 520 628 avp = Avp(filename=filename, line_num=csvdata.line_num,
Note: See TracChangeset
for help on using the changeset viewer.