Revision: 1678
Author: sebastien.lelong
Date: Fri Feb 19 05:55:25 2010
Log: new action command, 'api': generate an API representation from a jal file, outputs in XML, JSON or python strings
http://code.google.com/p/jallib/source/detail?r=1678

Modified:
 /trunk/tools/jallib.py

=======================================
--- /trunk/tools/jallib.py      Thu Feb 18 07:14:48 2010
+++ /trunk/tools/jallib.py      Fri Feb 19 05:55:25 2010
@@ -1129,6 +1129,129 @@
         print jalfile[1]


+#----------#
+# API FUNC #
+#----------#
+
+VAR_RE = re.compile("var\s+(\w+)\s+(\w+)\s+=?")
+CONST_RE = re.compile("const\s+(\w+)\s*(\w+)\s+=")
+ALIAS_RE = re.compile("alias\s+(\w+)\s+is(\w+)")
+PROC_RE = re.compile("procedure\s+(\w+)\s*\((.*)\)\s+is")
+FUNC_RE = re.compile("function\s+(\w+)\s*\((.*)\)\s+return\s+(\w+)\s+is")
+SIGN_RE = re.compile("(bit|byte|sbyte|word|sword|dword|sdword)\s+(in|out| in out)\s+(\w+),?")
+INCL_RE = re.compile("include\s+(\w+)")
+
+def api_parse(filename):
+    desc = {"include" : {}, "procedure" : {}, "function" : {},
+            "var" : {}, "const" : {}, 'alias' : {}}
+
+    def get_params(signature):
+        params = SIGN_RE.findall(signature)
+        dsign = []
+        for param in params:
+ dsign.append({'type' : param[0], 'context' : param[1], 'name' : param[2]})
+        return dsign
+
+    if filename == "-":
+        lines = sys.stdin.readlines()
+    else:
+        lines = file(filename).readlines()
+    for num,content in enumerate(lines):
+        content = content.strip()
+        if VAR_RE.match(content):
+            type, name = VAR_RE.match(content).groups()
+ desc['var'][name] = {'type' : type, 'name' : name, 'line' : num}#, 'content' : content}
+        elif CONST_RE.match(content):
+            type, name = CONST_RE.match(content).groups()
+ desc['const'][name] = {'type' : type, 'name' : name, 'line' : num}#, 'content' : content}
+        elif ALIAS_RE.match(content):
+            alias, source = ALIAS_RE.match(content).groups()
+ desc['alias'][alias] = {'alias' : alias, 'source' : source, 'line' : num}#, 'content' : content}
+        elif PROC_RE.match(content):
+            name,signature = PROC_RE.match(content).groups()
+            params = get_params(signature)
+            desc['procedure'][name] = {'name' : name, 'params' : params}
+        elif FUNC_RE.match(content):
+            name,signature,rettype = FUNC_RE.match(content).groups()
+            params = get_params(signature)
+ desc['function'][name] = {'name' : name, 'params' : params, 'return' : rettype}
+        elif INCL_RE.match(content):
+            lib = INCL_RE.match(content).groups()[0]
+            desc['include'][lib] = {'name' : lib}
+
+    # normalize: replace {} used to keep things unique by real list
+    final = {}.fromkeys(desc)
+    for k,v in desc.items():
+        final[k] = v.values()
+
+    return final
+
+def api2xml(py,elem=None,doc=None,libname=None):
+    import xml.dom.minidom as minidom
+    if not doc:
+        doc = minidom.Document()
+        elem = doc.appendChild(doc.createElement("api"))
+        elem.setAttribute("file",libname)
+    if isinstance(py,pytypes.DictType):
+        for k,v in py.items():
+            node = doc.createElement(k)
+            elem.appendChild(node)
+            api2xml(v,node,doc)
+    if isinstance(py,pytypes.ListType):
+        for val in py:
+            node = doc.createElement("element")
+            elem.appendChild(node)
+            api2xml(val,node,doc)
+    if isinstance(py,pytypes.StringType) or isinstance(py,pytypes.IntType):
+        elem.setAttribute("value",str(py))
+
+    return doc
+
+def api2json(py):
+    import simplejson
+    return simplejson.dumps(py)
+
+def do_api(args):
+    try:
+        opts, args = getopt.getopt(args, ACTIONS['api']['options'])
+    except getopt.error,e:
+        print >> sys.stderr, "Wrong option or missing argument: %s" % e.opt
+        sys.exit(255)
+
+    # now args contain jal file
+
+    outxml = False
+    outjson = False
+    outpystr = False
+    outfile = sys.stdout
+    input = None
+    for o,v in opts:
+        if o == "-x":
+            outxml = True
+        elif o == '-j':
+            outjson = True
+        elif o == '-p':
+            outpystr = True
+        elif o == '-o':
+            outfile = file(v,"w")
+        else:
+            print >> sys.stderr, "Wrong option %s" % o
+
+    if not args:
+ print >> sys.stderr, "You must specify a JAL file as input (last argument)"
+        sys.exit(255)
+
+    pydesc = api_parse(args[0])
+    if outxml:
+        doc = api2xml(pydesc,libname=os.path.basename(args[0]))
+        outfile.write(doc.toprettyxml())
+    elif outjson:
+        json = api2json(pydesc)
+        outfile.write(json)
+    else:
+        import pprint
+        outfile.write(pprint.pformat(pydesc) + "\n")
+

 #############
 # HELP FUNC #
@@ -1143,6 +1266,7 @@
- validate : validate the given file, according to Jallib Style Guide (JSG)
     - sample   : generate samples from board and test files
     - reindent : re-indent jal code
+    - api      : generate API description from jal file
     - jalapi   : generate HTML documentation from jal files
- list : list all JAL libraries found in JALLIB_REPOS, as resolved by compiler
     - license  : display license
@@ -1324,6 +1448,25 @@

 Output contains one line per library.

+"""
+
+def api_help():
+    print """
+    jallib api [-x|-j|-p] [-o output] file.jal|-
+
+Takes a JAL file (or read stdin if "-" is specified), parses and
+extracts API information about const, var, procedure, function,
+include, ...
+
+Several output formats are supported:
+
+    -x: XML format (default)
+    -j: JSON format (requires simplejson library)
+    -p: python string (can be used by eval'ing it)
+
+If -o option is specified, output is written in a file, else written
+on stdout.
+
 """

 def do_help(action_args=[]):
@@ -1341,6 +1484,7 @@
'compile' : {'callback' : do_compile, 'options' : 'R:E:', 'help' : compile_help}, 'validate' : {'callback' : do_validate, 'options' : '', 'help' : validate_help}, 'list' : {'callback' : do_list, 'options' : '', 'help' : list_help}, + 'api' : {'callback' : do_api, 'options' : 'xjpo:', 'help' : api_help}, 'jalapi' : {'callback' : do_jalapi, 'options' : 'slt:d:g:o:', 'help' : jalapi_help}, 'sample' : {'callback' : do_sample, 'options' : 'a:b:t:o:', 'help' : sample_help}, 'reindent' : {'callback' : do_reindent, 'options' : 'c:', 'help' : reindent_help},

--
You received this message because you are subscribed to the Google Groups 
"jallib" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/jallib?hl=en.

Reply via email to