Loading ITS-Container.asn +1 −0 Original line number Diff line number Diff line --! @options: no-fields-header ETSI-ITS-CDD {itu-t (0) identified-organization (4) etsi (0) itsDomain (5) wg1 (1) 102894 cdd (2) major-version-3 (3) minor-version-1 (1)} DEFINITIONS AUTOMATIC TAGS ::= Loading asn2md.py +41 −19 Original line number Diff line number Diff line Loading @@ -63,6 +63,8 @@ RE_OPTIONS = re.compile(r'^\s*@options[\s:]+(.+)', re.MULTILINE) extTypes = {} cpos = 0 o_args = [] m_options = [] f_options = [] def urlquote(s): if (sys.version_info > (3, 0)): Loading Loading @@ -112,6 +114,14 @@ def parseDoxyComments(content:str): ret += RE_STRIPSTAR.sub('', m.group(1)) return ret def parseOptions(doc, opts): def repl_options(m): if m.group(1) is not None: for o in m.group(1).split(','): setattr(opts, o.strip(), True) return '' return RE_OPTIONS.sub(repl_options, doc) def parseModule(mname, content): global cpos cpos = 0 Loading Loading @@ -139,24 +149,19 @@ def parseModule(mname, content): # parse types def repl_type (m, doc): global m_options title = t = m.group(1) # type name f_params = {} s_unit = '' s_category = '' s_note = '' s_revision = '' options = copy.copy(o_args) options = copy.copy(m_options) if doc : # doc is the prepending comment. Check if not None and not Empty doc = parseDoxyComments(doc) # parse options def repl_options(m): nonlocal options if m.group(1) is not None: for o in m.group(1).split(','): setattr(options, o.strip(), True) return '' doc=RE_OPTIONS.sub(repl_options, doc) doc = parseOptions(doc, options) def repl_section (m): nonlocal title Loading @@ -171,9 +176,12 @@ def parseModule(mname, content): ret = parseText(l) else: if len(l): if len(f_params) == 0: ret = '--((FIELDS))--' f_params[m.group(3)] = parseText(l, 2) elif m.group(1) == 'brief': if o_args.brief_as_title: if options.brief_as_title: title = parseText(l) else: ret = parseText(l) Loading @@ -189,29 +197,31 @@ def parseModule(mname, content): s_category = '\n **Categories**: ' for l in m.group(1).split(','): # s_category += '[{0}](#{1}) '.format(l.strip(), urlquote(l.strip())) s_category += l.strip() + ' ' s_category += parseText(l).strip() + ' ' s_category += '\n' return '' doc = RE_DOXY_CATEGORY.sub(repl_category, doc) def repl_unit(m): nonlocal s_unit s_unit = '\n **Unit**: _' + m.group(1).strip() + '_\n' s_unit = '\n **Unit**: _' + parseText(m.group(1)).strip() + '_\n' return '' doc = RE_DOXY_UNIT.sub(repl_unit, doc) def repl_revision(m): nonlocal s_revision s_revision = '\n **Revision**: _' + m.group(1).strip() + '_\n' s_revision = '\n **Revision**: _' + parseText(m.group(1)).strip() + '_\n' return '' doc = RE_DOXY_REVISION.sub(repl_revision, doc) else: doc = '' doc = [x.strip() for x in doc.split('--((FIELDS))--')] ret = '' if t is not None: fields = '' ret = '\n### <a name="{0}"></a>{1}\n'.format(t, title) + parseText(doc) ret = '\n### <a name="{0}"></a>{1}\n'.format(t, title) + parseText(doc[0]) # parse fields and get out fields descriptions if m.group(3) is not None: Loading @@ -222,6 +232,7 @@ def parseModule(mname, content): if typeBody is not None: fTitle = '' field = '' suffix = '' pos = 0 for fm in RE_FIELDS.finditer(typeBody): if fm.group(1) is not None: Loading @@ -235,15 +246,15 @@ def parseModule(mname, content): field = f_params.pop(f) + '\n\n' if fm.group(2) is not None: fTitle = 'Fields:\n' if len(field) or not o_args.no_auto_fields: if len(field) or not options.no_auto_fields: t = fm.group(2).strip() if RE_BASIC_TYPES.match(t) is not None: field = '* {0} **{1}** {2}<br>\n'.format(f, t, ext) + field field = '* {0} of type **{1}** {2}<br>\n'.format(f, t, ext) + field else: field = '* {0} [**{1}**]({2}#{1}) {3}<br>\n'.format(f, t, extTypes.get(t,''), ext) + field field = '* {0} of type [**{1}**]({2}#{1}) {3}<br>\n'.format(f, t, extTypes.get(t,''), ext) + field else: fTitle = 'Values:\n' if len(field) or not o_args.no_auto_values: if len(field) or not options.no_auto_values: field = '* **{0}** {1}<br>\n'.format(f, ext) + field if len(field): field += parseText(fm.string[pos:fm.start()], 3) Loading @@ -256,9 +267,11 @@ def parseModule(mname, content): if len(field): fields += parseInlineComments(typeBody[pos:], 3) # add all other fields defined as @params if 'force-all-fields' in options or 'force-all-fields' in o_args: if 'force-all-fields' in options: for f in f_params: fields += '* {}<br>\n{}\n\n'.format(f, f_params[f]) if 'no-fields-header' in options: fTitle = '' if len(fields): ret = ret.strip() + '\n\n' + fTitle + fields else: Loading @@ -270,6 +283,12 @@ def parseModule(mname, content): for p in f_params: ret += '* `{0}` {1}\n'.format(p, f_params[p]) try: if len(doc[1]): ret += doc[1] + '\n' except: pass return ret + s_unit + s_category + s_revision + s_note + '```asn1\n' + RE_COMMENTS.sub('', m.group(0).strip()) +'\n```\n\n' pos = 0 Loading @@ -282,11 +301,13 @@ def parseModule(mname, content): def parseAsn(outDir, content) : # iterate modules in the file global m_options pos= 0 cnt = 0 m_options = copy.copy(o_args) for m in RE_MODULE.finditer(content): ret = '# ASN.1 module {}\n OID: _{}_\n'.format(m.group(1), RE_SPACES.sub(' ', m.group(2))) ret += parseDoxyComments(content[pos:m.start()]) + '\n' ret += parseText(parseOptions(parseDoxyComments(content[pos:m.start()]), m_options)) + '\n' if m.group(3) is not None: ret += parseModule(m.group(1), m.group(3)) ret += '\n\n' Loading @@ -303,6 +324,7 @@ def main(): ap.add_argument('--force-all-fields', '-f', default=False,action='store_true', help='Add all fields in the list even if empty') ap.add_argument('--no-auto-fields', '-F', default=False,action='store_true', help='Add fields only if @param or @field is defined') ap.add_argument('--no-auto-values', '-V', default=False,action='store_true', help='Do not add named values or enums') ap.add_argument('--no-fields-header', '-H', default=False,action='store_true', help='Do not add fields and values header') ap.add_argument('modules', action='store', nargs='+', help='ASN.1 files') o_args = ap.parse_args() Loading Loading
ITS-Container.asn +1 −0 Original line number Diff line number Diff line --! @options: no-fields-header ETSI-ITS-CDD {itu-t (0) identified-organization (4) etsi (0) itsDomain (5) wg1 (1) 102894 cdd (2) major-version-3 (3) minor-version-1 (1)} DEFINITIONS AUTOMATIC TAGS ::= Loading
asn2md.py +41 −19 Original line number Diff line number Diff line Loading @@ -63,6 +63,8 @@ RE_OPTIONS = re.compile(r'^\s*@options[\s:]+(.+)', re.MULTILINE) extTypes = {} cpos = 0 o_args = [] m_options = [] f_options = [] def urlquote(s): if (sys.version_info > (3, 0)): Loading Loading @@ -112,6 +114,14 @@ def parseDoxyComments(content:str): ret += RE_STRIPSTAR.sub('', m.group(1)) return ret def parseOptions(doc, opts): def repl_options(m): if m.group(1) is not None: for o in m.group(1).split(','): setattr(opts, o.strip(), True) return '' return RE_OPTIONS.sub(repl_options, doc) def parseModule(mname, content): global cpos cpos = 0 Loading Loading @@ -139,24 +149,19 @@ def parseModule(mname, content): # parse types def repl_type (m, doc): global m_options title = t = m.group(1) # type name f_params = {} s_unit = '' s_category = '' s_note = '' s_revision = '' options = copy.copy(o_args) options = copy.copy(m_options) if doc : # doc is the prepending comment. Check if not None and not Empty doc = parseDoxyComments(doc) # parse options def repl_options(m): nonlocal options if m.group(1) is not None: for o in m.group(1).split(','): setattr(options, o.strip(), True) return '' doc=RE_OPTIONS.sub(repl_options, doc) doc = parseOptions(doc, options) def repl_section (m): nonlocal title Loading @@ -171,9 +176,12 @@ def parseModule(mname, content): ret = parseText(l) else: if len(l): if len(f_params) == 0: ret = '--((FIELDS))--' f_params[m.group(3)] = parseText(l, 2) elif m.group(1) == 'brief': if o_args.brief_as_title: if options.brief_as_title: title = parseText(l) else: ret = parseText(l) Loading @@ -189,29 +197,31 @@ def parseModule(mname, content): s_category = '\n **Categories**: ' for l in m.group(1).split(','): # s_category += '[{0}](#{1}) '.format(l.strip(), urlquote(l.strip())) s_category += l.strip() + ' ' s_category += parseText(l).strip() + ' ' s_category += '\n' return '' doc = RE_DOXY_CATEGORY.sub(repl_category, doc) def repl_unit(m): nonlocal s_unit s_unit = '\n **Unit**: _' + m.group(1).strip() + '_\n' s_unit = '\n **Unit**: _' + parseText(m.group(1)).strip() + '_\n' return '' doc = RE_DOXY_UNIT.sub(repl_unit, doc) def repl_revision(m): nonlocal s_revision s_revision = '\n **Revision**: _' + m.group(1).strip() + '_\n' s_revision = '\n **Revision**: _' + parseText(m.group(1)).strip() + '_\n' return '' doc = RE_DOXY_REVISION.sub(repl_revision, doc) else: doc = '' doc = [x.strip() for x in doc.split('--((FIELDS))--')] ret = '' if t is not None: fields = '' ret = '\n### <a name="{0}"></a>{1}\n'.format(t, title) + parseText(doc) ret = '\n### <a name="{0}"></a>{1}\n'.format(t, title) + parseText(doc[0]) # parse fields and get out fields descriptions if m.group(3) is not None: Loading @@ -222,6 +232,7 @@ def parseModule(mname, content): if typeBody is not None: fTitle = '' field = '' suffix = '' pos = 0 for fm in RE_FIELDS.finditer(typeBody): if fm.group(1) is not None: Loading @@ -235,15 +246,15 @@ def parseModule(mname, content): field = f_params.pop(f) + '\n\n' if fm.group(2) is not None: fTitle = 'Fields:\n' if len(field) or not o_args.no_auto_fields: if len(field) or not options.no_auto_fields: t = fm.group(2).strip() if RE_BASIC_TYPES.match(t) is not None: field = '* {0} **{1}** {2}<br>\n'.format(f, t, ext) + field field = '* {0} of type **{1}** {2}<br>\n'.format(f, t, ext) + field else: field = '* {0} [**{1}**]({2}#{1}) {3}<br>\n'.format(f, t, extTypes.get(t,''), ext) + field field = '* {0} of type [**{1}**]({2}#{1}) {3}<br>\n'.format(f, t, extTypes.get(t,''), ext) + field else: fTitle = 'Values:\n' if len(field) or not o_args.no_auto_values: if len(field) or not options.no_auto_values: field = '* **{0}** {1}<br>\n'.format(f, ext) + field if len(field): field += parseText(fm.string[pos:fm.start()], 3) Loading @@ -256,9 +267,11 @@ def parseModule(mname, content): if len(field): fields += parseInlineComments(typeBody[pos:], 3) # add all other fields defined as @params if 'force-all-fields' in options or 'force-all-fields' in o_args: if 'force-all-fields' in options: for f in f_params: fields += '* {}<br>\n{}\n\n'.format(f, f_params[f]) if 'no-fields-header' in options: fTitle = '' if len(fields): ret = ret.strip() + '\n\n' + fTitle + fields else: Loading @@ -270,6 +283,12 @@ def parseModule(mname, content): for p in f_params: ret += '* `{0}` {1}\n'.format(p, f_params[p]) try: if len(doc[1]): ret += doc[1] + '\n' except: pass return ret + s_unit + s_category + s_revision + s_note + '```asn1\n' + RE_COMMENTS.sub('', m.group(0).strip()) +'\n```\n\n' pos = 0 Loading @@ -282,11 +301,13 @@ def parseModule(mname, content): def parseAsn(outDir, content) : # iterate modules in the file global m_options pos= 0 cnt = 0 m_options = copy.copy(o_args) for m in RE_MODULE.finditer(content): ret = '# ASN.1 module {}\n OID: _{}_\n'.format(m.group(1), RE_SPACES.sub(' ', m.group(2))) ret += parseDoxyComments(content[pos:m.start()]) + '\n' ret += parseText(parseOptions(parseDoxyComments(content[pos:m.start()]), m_options)) + '\n' if m.group(3) is not None: ret += parseModule(m.group(1), m.group(3)) ret += '\n\n' Loading @@ -303,6 +324,7 @@ def main(): ap.add_argument('--force-all-fields', '-f', default=False,action='store_true', help='Add all fields in the list even if empty') ap.add_argument('--no-auto-fields', '-F', default=False,action='store_true', help='Add fields only if @param or @field is defined') ap.add_argument('--no-auto-values', '-V', default=False,action='store_true', help='Do not add named values or enums') ap.add_argument('--no-fields-header', '-H', default=False,action='store_true', help='Do not add fields and values header') ap.add_argument('modules', action='store', nargs='+', help='ASN.1 files') o_args = ap.parse_args() Loading