9 NetMsgs Generate Python files module. 11 A .py source file is generated from a RoadNarrows NetMsg XML specification. 73 space =
lambda indent:
"%*s" % (indent,
'')
80 """ RoadNarrows Net Messages Python Source Generator Class. 82 The NetMsgsGenPy class reads the post-parsed database of a 83 NetMsgsXmlParser class instance and generates a Python .py file. The 84 python file expects the NetMsgs run-time python library. 89 """ Initialize NetMsgsGenPy instance. 92 xml - NetMsgsXMLParser class instance. 93 pyfilepath - Generated output python file. 94 kwargs - Optional keyword arguments. 95 debug - Set debugging level: 0 == off, 1, 2, 3. 123 """ Augument the XML database of parsed XML values with python generated 126 self.
mXml[
'genpy'] = { }
127 encoding = self.
mXml[
'netmsgs'][
'encoding'].lower()
130 if encoding ==
'itv':
131 self.
mXml[
'genpy'][
'encoding_prefix'] = encoding.upper()
133 self.
mXml[
'genpy'][
'encoding_prefix'] = encoding.capitalize()
135 endian = self.
mXml[
'netmsgs'][
'endian'].lower()
138 self.
mXml[
'genpy'][
'endian_desc'] = endian +
'-endian' 139 self.
mXml[
'genpy'][
'endian_enum'] =
'NMEndian'+endian.capitalize()
147 """ Make initial pass through the XML database and augument with 148 specific python information. 150 No generated python code is written to file output. 161 """ Generate python .py source file. 164 Raises NetMsgError exception on error. 170 raise nmBase.NetMsgsError(
"Error: %s" % (err))
183 """ Generate .py file prologue. 185 Prologue includes core imports plus any prologue specified 189 fp - Opened output file pointer. 191 pre = self.
mXml[
'genpy'][
'encoding_prefix']
192 module =
"NetMsgs.NetMsgsLib%s" % pre
193 if self.
mXml[
'netmsgs'][
'encoding'] ==
'flat':
194 baseclass =
'NetMsgs' 196 baseclass =
'NetMsgs%s' % pre
197 prologue = self.
mXml[
'meta'][
'python'][
'prologue']
201 import NetMsgs.NetMsgsBase as nmBase 204 """ % (module, baseclass))
206 fp.write(
"%s\n\n" % (prologue))
211 """ Generate Message Id enumeration. 214 fp - Opened output file pointer. 216 ns = self.
mXml[
'meta'][
'ns']
217 msgorder = self.
mXml[
'msg_types'][nmBase.NMKeyOrder]
218 if len(msgorder) == 0:
221 fp.write(
"class %sMsgId:\n" % ns)
222 fp.write(
' """ %s Message Id Enumeration class. """\n' % ns)
224 nmBase.PrettyPrintCols(fp, 0,
227 42,
'# no message id\n')
228 for msgid
in msgorder:
230 msgdef = self.
mXml[
'msg_types'][msgid]
232 comment =
"%s (deprecated)" % (msgid)
234 comment =
"%s" % (msgid)
235 nmBase.PrettyPrintCols(fp, 0,
238 42,
"# %s\n" % (comment))
240 nmBase.PrettyPrintCols(fp, 0,
243 42,
'# number of message ids\n')
249 """ Generate field types dictionary. 252 ns+'ExtFieldTypes' '=' '{' ftdict '}' 256 | ftdict ',' ftdict_item 259 ftid ':' '{' msgdef '}' 260 | ftid ':' '{' fielddef '}' 263 fp - Opened output file pointer. 265 ns = self.
mXml[
'meta'][
'ns']
266 section =
'field_types' 267 if len(self.
mXml[section][nmBase.NMKeyOrder]) == 0:
272 self.
mFTDict[nmBase.NMKeyOrder] = []
273 nomsgid =
"@%sMsgId.NoId" % (ns)
274 nofid =
"@nmBase.NMFIdNone" 275 for ftid
in self.
mXml[section][nmBase.NMKeyOrder]:
276 ftdef = self.
mXml[section][ftid]
278 xtype = ftdef[
'ftype']
281 self.
mFTDict[nmBase.NMKeyOrder] += [ftid]
282 if base_xtype ==
'struct':
294 """ Generate message definition set. 297 ns+'MsgDefSet' '=' '{' msgdefset '}' 301 | msgdefset ',' msgdef_item 304 msgid ':' '{' msgdef '}' 307 fp - Opened output file pointer. 309 ns = self.
mXml[
'meta'][
'ns']
310 section =
'msg_types' 311 if len(self.
mXml[section][nmBase.NMKeyOrder]) == 0:
317 for msgid
in self.
mXml[section][nmBase.NMKeyOrder]:
318 msgdef = self.
mXml[section][msgid]
320 xtype = msgdef[
'ftype']
321 enum =
"@%sMsgId.%s" % (ns, msgid)
333 """ Generate message definition dictionary entry. 336 msgdef_common ',' 'fielddef:' '[' fdeflist ']' 339 'name:' name ',' 'msgid:' msgid ',' 'max_count:' n 343 fdeflist ',' '{' fielddef '}' 345 name ::= (* message string name *) 347 msgid ::= (* message id enumeration *) 349 max_count ::= (* number of fields in message definition *) 352 name - Name keyword value. 353 msgid - Message id keyword value. 354 msgdef - XML message definition. 355 deentry - Output message definition entry. 357 ns = self.
mXml[
'meta'][
'ns']
358 xtype = msgdef[
'ftype']
362 dentry[
'name'] = name
363 dentry[
'msgid'] = msgid
364 dentry[
'ftype'] = nmBase.NMBuiltInFieldTypes[base_xtype][
'code']
365 dentry[
'max_count'] = 0
366 dentry[
'fielddef'] = []
369 if xtype != base_xtype:
373 dentry[
'max_count'] = ftentry[
'max_count']
374 dentry[
'fielddef'] =
"@%sExtFType%s['fielddef']" % (ns, eve)
378 if not msgdef.has_key(
'fields'):
380 fields = msgdef[
'fields']
383 for fname
in fields[nmBase.NMKeyOrder]:
388 dentry[
'fielddef'] += [d]
391 dentry[
'max_count'] = max_count
396 """ Generate field definition dictionary entry. 405 fielddef_common ',' ['min:' m ',' 'max:' M ',' 'const:' C] 408 fielddef_common ',' ['const:' C] 411 fielddef_common ',' 'msgdef:' '{' msgdef '}' 414 fielddef_common ',' 'vdef:' '{' fielddef '}' 417 'name:' name ',' 'fid:' fid ',' 'ftype:' ftype ',' 'max_count:' n 419 name ::= (* field string name *) 421 msgid ::= (* field id enumeration *) 423 ftype ::= (* field type code *) 425 max_count ::= (* number of vector items, string characters or 1 for 429 name - Name keyword value. 430 fid - Field id keyword value. 431 fdef - XML field definition. 432 deentry - Output field definition entry. 434 ns = self.
mXml[
'meta'][
'ns']
435 xtype = fdef[
'ftype']
439 dentry[
'name'] = name
441 dentry[
'ftype'] = nmBase.NMBuiltInFieldTypes[base_xtype][
'code']
442 dentry[
'max_count'] = 1
445 if xtype != base_xtype:
454 if base_xtype ==
'struct':
455 nomsgid =
"@%sMsgId.NoId" % (ns)
456 subname = name +
'_struct' 460 dentry[
'msgdef'] =
"@%sExtFType%s" % (ns, eve)
463 dentry[
'msgdef'] = {}
464 self.
GenMsgDef(subname, nomsgid, fdef, dentry[
'msgdef'])
467 elif base_xtype ==
'vector':
468 nofid =
"@nmBase.NMFIdNone" 469 subname = name +
'_item' 473 dentry[
'max_count'] = ftentry[
'max_count']
474 dentry[
'vdef'] =
"@%sExtFType%s['vdef']" % (ns, eve)
477 dentry[
'max_count'] =
'@' + fdef.get(
'size',
'nmBase.NMVectorMaxCount')
480 vdef[
'name'] = subname
481 vdef[
'ftype'] = fdef[
'vtype']
482 vdef[
'fields'] = fdef.get(
'fields', {})
484 self.
GenFieldDef(subname, nofid, vdef, dentry[
'vdef'])
487 elif base_xtype ==
'string':
490 dentry[
'max_count'] = ftentry[
'max_count']
491 if ftentry.has_key(
'const'):
492 dentry[
'const'] = ftentry[
'const']
495 dentry[
'max_count'] =
'@' + fdef.get(
'size',
'nmBase.NMStringMaxCount')
496 if fdef.has_key(
'const'):
497 dentry[
'const'] =
'@' + fdef[
'const']
501 dentry[
'max_count'] =
'@' + fdef.get(
'count',
'nmBase.NMPadDftCount')
507 if ftentry.has_key(
'min'):
508 dentry[
'min'] = ftentry[
'min']
509 if ftentry.has_key(
'max'):
510 dentry[
'max'] = ftentry[
'max']
511 if ftentry.has_key(
'const'):
512 dentry[
'const'] = ftentry[
'const']
515 if fdef.has_key(
'min'):
516 dentry[
'min'] =
'@' + fdef[
'min']
517 if fdef.has_key(
'max'):
518 dentry[
'max'] =
'@' + fdef[
'max']
519 if fdef.has_key(
'const'):
520 dentry[
'const'] =
'@' + fdef[
'const']
524 """ Generate derived NetMsgs class. 527 fp - Opened output file pointer. 529 ns = self.
mXml[
'meta'][
'ns']
532 classname =
"%sNetMsgs" % (ns)
533 if self.
mXml[
'netmsgs'][
'encoding'] ==
'flat':
534 baseclass =
'NetMsgs' 536 pre = self.
mXml[
'genpy'][
'encoding_prefix']
537 baseclass =
'NetMsgs%s' % pre
538 msgdefset =
"%sSetMsgDef" % (ns)
539 msgsetname =
"%sMsgSet" % (ns)
543 \"\"\" %s NetMsgs Class. \"\"\" 546 def __init__(self, **kwargs): 547 \"\"\" %s NetMsgs initialization. \"\"\" 548 kwargs['msgsetname'] = '%s' 549 %s.__init__(self, %s, **kwargs) 551 ##""" % (classname, baseclass, ns, ns, msgsetname, baseclass, msgdefset))
556 """ Generate .py file epilogue. 559 fp - Opened output file pointer. 561 epilogue = self.
mXml[
'meta'][
'python'][
'epilogue']
563 fp.write(
"\n\n%s" % (epilogue))
574 """ Write field types and field type dictionary. 577 fp - Opened output file pointer. 579 ns = self.
mXml[
'meta'][
'ns']
581 for ftid
in self.
mFTDict[nmBase.NMKeyOrder]:
582 ftname =
"%sExtFType%s" % (ns, ftid)
584 nmBase.PrettyPrintAssignExpr(ftname, self.
mFTDict[ftid], fp=fp)
586 d[ftid] =
'@' + ftname
588 dname =
"%sExtFieldTypes" % (ns)
589 nmBase.PrettyPrintAssignExpr(dname, d, fp=fp)
595 """ Write message definitions and message definition set dictionary. 598 fp - Opened output file pointer. 600 ns = self.
mXml[
'meta'][
'ns']
602 for enum
in self.
mMsgDefSet[nmBase.NMKeyOrder]:
604 name = msgdef[
'name']
605 mname =
"%sMsgDef%s" % (ns, name)
607 nmBase.PrettyPrintAssignExpr(mname, msgdef, fp=fp)
609 d[enum] =
'@' + mname
611 "%s Message Definition Set Dictionary" % ns)
612 dname =
"%sSetMsgDef" % (ns)
613 nmBase.PrettyPrintAssignExpr(dname, d, fp=fp)
624 """ Returns True (False) is definition is (not) deprecated. 627 xdef - XML ftypedef, msgdef, or fielddef XML specification. 632 dispo = xdef.get(
'disposition',
'active')
633 if dispo ==
'deprecated':
641 """ Returns the base XML field type for the given field type. 644 ftype - (Derived) field type. 651 while not nmBase.NMBuiltInFieldTypes.has_key(ftype):
652 if self.
mXml[
'field_types'].has_key(ftype):
653 ftype = self.
mXml[
'field_types'][ftype][
'ftype']
655 raise nmBase.NetMsgsError(
"Error: %s is not a defined ftype" % (ftype))
661 """ Get lineage of XML field type 664 xtype - XML field type 667 List of ancestors order from base to nearest to xtype. 672 while not nmBase.NMBuiltInFieldTypes.has_key(xtype):
673 if self.
mXml[
'field_types'].has_key(xtype):
674 lineage = [xtype] + lineage
675 xtype = self.
mXml[
'field_types'][xtype][
'ftype']
677 raise nmBase.NetMsgsError(
"Error: %s is not a defined ftype" % (xtype))
683 """ Evaluate a summation of terms. 686 args List of summation terms, with each term one of: 687 an equation, string, number 691 5, '(3 * 10)' -> '35' 692 5, 'MY_MAX', '1*255' -> '300+MY_MAX' 695 Returns string of the evaluated results. 702 elif type(arg) == str:
703 arg = arg.replace(
"NMFVAL_LEN_MAX_STRING",
"255")
704 arg = arg.replace(
"NMFVAL_LEN_MAX_VECTOR",
"255")
710 s +=
'+(' + arg +
')' 722 """ Prints source file top comment block. 725 fp - Opened output file pointer. 728 brief = self.
mXml[
'meta'][
'brief']
729 xmlfilename = self.mXml.GetXMLFileName()
730 now = time.localtime()
731 thisdate =
"%d.%02d.%02d" % (now.tm_year, now.tm_mon, now.tm_mday)
732 thistime =
"%02d:%02d:%02d" % (now.tm_hour, now.tm_min, now.tm_sec)
734 ############################################################################## 747 ## \\warning This file was auto-generated on %s %s from the NetMsgs 748 ## XML specification %s. 751 ## (C) %d. RoadNarrows LLC 752 ## (http://www.roadnarrows.com) 753 ## All Rights Reserved 755 ############################################################################## 756 """ % (srcbasename, srcbasename, brief, thisdate, thistime,
757 xmlfilename, now.tm_year))
762 """ Prints major file division comment block. 765 fp - Opened output file pointer. 766 comment - Major division comment line. 770 # ----------------------------------------------------------------------------- 772 # ----------------------------------------------------------------------------- 779 """ Prints minor file division comment block. 782 fp - Opened output file pointer. 783 comment - Minor division comment line. 787 # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 789 # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 796 """ Print doxygen brief comment block. 799 fp - Opened output file pointer. 800 brief - Brief comment. mMsgDefSet
message definition set dictionary
def PrettyPrintMajorDivComment(self, fp, comment)
mFTDict
extended field type dictionary
def GenMsgDef(self, name, msgid, msgdef, dentry)
def GenFieldDef(self, name, fid, fdef, dentry)
def PrettyPrintBriefComment(self, fp, brief)
mPyBaseName
output .h header file basename
def PrettyPrintMinorDivComment(self, fp, comment)
NetMsgs Base Data Module.
def PrettyPrintTopComment(self, fp)
def GenPrologue(self, fp)
def GetLineage(self, xtype)
def WriteFTDict(self, fp)
def __init__(self, xml, pyfilepath, kwargs)
mHungarian
do [not] prepend RN Hungarian notation to message fields
mPyFilePath
output .h header file name
NetMsgs XML parser module.
def IsDeprecated(self, xdef)
def BaseXType(self, ftype)
def WriteMsgDefSet(self, fp)
def GenMsgDefSet(self, fp)
def GenEpilogue(self, fp)