[asterisk-commits] mjordan: branch mjordan/manager-events r368091 - in /team/mjordan/manager-eve...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu May 31 16:40:42 CDT 2012
Author: mjordan
Date: Thu May 31 16:40:37 2012
New Revision: 368091
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=368091
Log:
Add infrastructure for documentation of manager events
Although the post_process_documentation.py script is a tad on the broken
side currently, this actually will parse out information from manager
events (app_dial) and put it all in the appropriate XML file.
TODO:
1. Finish up the post_process_documentation.py script
2. Update the DTD for validation
3. Place documentation blobs in front of the 1000 or so manager events
4. Steal underpants
5. ...
6. Profit
Added:
team/mjordan/manager-events/
- copied from r367982, trunk/
team/mjordan/manager-events/build_tools/get_documentation.py (with props)
team/mjordan/manager-events/build_tools/post_process_documentation.py (with props)
team/mjordan/manager-events/configure.ac
- copied, changed from r366351, trunk/configure.ac
Modified:
team/mjordan/manager-events/Makefile
team/mjordan/manager-events/apps/app_dial.c
team/mjordan/manager-events/configure
team/mjordan/manager-events/makeopts.in
Modified: team/mjordan/manager-events/Makefile
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/manager-events/Makefile?view=diff&rev=368091&r1=367982&r2=368091
==============================================================================
--- team/mjordan/manager-events/Makefile (original)
+++ team/mjordan/manager-events/Makefile Thu May 31 16:40:37 2012
@@ -96,6 +96,7 @@
export WGET_EXTRA_ARGS
export LDCONFIG
export LDCONFIG_FLAGS
+export PYTHON
# even though we could use '-include makeopts' here, use a wildcard
# lookup anyway, so that make won't try to build makeopts if it doesn't
@@ -314,12 +315,28 @@
@echo " + $(mK) install +"
@echo " +-------------------------------------------+"
+full: _cleantest_all_full
+ @echo " +--------- Asterisk Build Complete ---------+"
+ @echo " + Asterisk has successfully been built, and +"
+ @echo " + can be installed by running: +"
+ @echo " + +"
+ @echo " + $(mK) install +"
+ @echo " +-------------------------------------------+"
+
+
# For parallel builds, we must call cleantest *before* running the
# other dependencies on _all.
_cleantest_all: cleantest
@$(MAKE) _all
+# For parallel builds, we must call cleantest *before* running the
+# other dependencies on _all.
+_cleantest_all_full: cleantest
+ @$(MAKE) _all_full
+
_all: makeopts $(SUBDIRS) doc/core-en_US.xml $(ADDL_TARGETS)
+
+_all_full: makeopts $(SUBDIRS) doc/core-full-en_US.xml $(ADDL_TARGETS)
makeopts: configure
@echo "****"
@@ -463,6 +480,34 @@
done
@echo
@echo "</docs>" >> $@
+
+doc/core-full-en_US.xml: $(foreach dir,$(MOD_SUBDIRS),$(shell $(GREP) -l "language=\"en_US\"" $(dir)/*.c $(dir)/*.cc 2>/dev/null))
+ @printf "Building Documentation For: "
+ @echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" > $@
+ @echo "<!DOCTYPE docs SYSTEM \"appdocsxml.dtd\">" >> $@
+ @echo "<docs xmlns:xi=\"http://www.w3.org/2001/XInclude\">" >> $@
+ @for x in $(MOD_SUBDIRS); do \
+ printf "$$x " ; \
+ for i in $$x/*.c; do \
+ $(PYTHON) build_tools/get_documentation.py < $$i >> $@ ; \
+ done ; \
+ done
+ @echo
+ @echo "</docs>" >> $@
+ $(PYTHON) build_tools/post_process_documentation.py -i $@ -o "doc/core-en_US.xml"
+
+validate-docs-full: doc/core-full-en_US.xml
+ifeq ($(XMLSTARLET)$(XMLLINT),::)
+ @echo "--------------------------------------------------------------------------"
+ @echo "--- Please install xmllint or xmlstarlet to validate the documentation ---"
+ @echo "--------------------------------------------------------------------------"
+else
+ ifneq ($(XMLLINT),:)
+ $(XMLLINT) --dtdvalid doc/appdocsxml.dtd --noout $<
+ else
+ $(XMLSTARLET) val -d doc/appdocsxml.dtd $<
+ endif
+endif
validate-docs: doc/core-en_US.xml
ifeq ($(XMLSTARLET)$(XMLLINT),::)
Modified: team/mjordan/manager-events/apps/app_dial.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/manager-events/apps/app_dial.c?view=diff&rev=368091&r1=367982&r2=368091
==============================================================================
--- team/mjordan/manager-events/apps/app_dial.c (original)
+++ team/mjordan/manager-events/apps/app_dial.c Thu May 31 16:40:37 2012
@@ -823,6 +823,16 @@
static void senddialevent(struct ast_channel *src, struct ast_channel *dst, const char *dialstring)
{
struct ast_channel *chans[] = { src, dst };
+ /*** DOCUMENTATION
+ <managerEventInstance>
+ <reason>Called when a dial event is started.</reason>
+ <syntax>
+ <parameter name="SubEvent">
+ <para>The sub event</para>
+ </parameter>
+ </syntax>
+ </managerEventInstance>
+ ***/
ast_manager_event_multichan(EVENT_FLAG_CALL, "Dial", 2, chans,
"SubEvent: Begin\r\n"
"Channel: %s\r\n"
@@ -845,6 +855,11 @@
static void senddialendevent(struct ast_channel *src, const char *dialstatus)
{
+ /*** DOCUMENTATION
+ <managerEventInstance>
+ <reason>Called when a dial event is ended.</reason>
+ </managerEventInstance>
+ ***/
ast_manager_event(src, EVENT_FLAG_CALL, "Dial",
"SubEvent: End\r\n"
"Channel: %s\r\n"
Added: team/mjordan/manager-events/build_tools/get_documentation.py
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/manager-events/build_tools/get_documentation.py?view=auto&rev=368091
==============================================================================
--- team/mjordan/manager-events/build_tools/get_documentation.py (added)
+++ team/mjordan/manager-events/build_tools/get_documentation.py Thu May 31 16:40:37 2012
@@ -1,0 +1,145 @@
+#! /usr/bin/env python
+# vin: sw=3 et:
+'''
+Copyright (C) 2012, Digium, Inc.
+Matt Jordan <mjordan at digium.com>
+
+This program is free software, distributed under the terms of
+the GNU General Public License Version 2.
+'''
+
+import sys
+import os
+import xml.dom.minidom
+
+from xml.dom.minidom import Element
+
+def parse_manager_event_instance(xml_fragment):
+ ''' Parse the information for a manager event
+
+ Keyword Arguments:
+ xml_fragment The XML fragment comment
+
+ Returns:
+ A well-formed XML fragment containing the comments passed in, as well as
+ information obtained from the manager_event macro calls
+ '''
+
+ candidate_lines = []
+ type = ""
+
+ # Read the manager_event method call, which should occur after
+ # the documentation block
+ while (True):
+ line = sys.stdin.readline()
+ line = line.strip()
+ candidate_lines.append(line)
+ if ");" in line:
+ break;
+
+ candidate_string = ''.join(candidate_lines)
+ if "ast_manager_event_multichan" in candidate_string:
+ type = "multichan"
+ elif "ast_manager_event" in candidate_string:
+ type = "ast_manager_event"
+ elif "manager_event" in candidate_string:
+ type = "manager_event"
+ else:
+ # Unknown, return what we have
+ return ''.join(xml_fragment)
+
+ # strip off the macro name
+ candidate_string = candidate_string[candidate_string.index("(",0) + 1:candidate_string.rindex(");")]
+ # split into parameter tokens
+ func_parameter_tokens = candidate_string.split(',')
+
+ if type == "manager_event" or type == "multichan":
+ class_level = func_parameter_tokens[0].strip()
+ event_type = func_parameter_tokens[1].strip()
+ else:
+ class_level = func_parameter_tokens[1].strip()
+ event_type = func_parameter_tokens[2].strip()
+
+ if type == "manager_event":
+ event_parameters = func_parameter_tokens[2].strip()
+ elif type == "ast_manager_event":
+ event_parameters = func_parameter_tokens[3].strip()
+ else:
+ event_parameters = func_parameter_tokens[4].strip()
+
+ parameter_tokens = event_parameters.replace("\"", "").split('\\r\\n')
+
+ # Build the top level XML element information
+ xml_fragment.insert(0, "<managerEvent name=\"%s\">" % event_type.strip().replace("\"",""))
+ xml_fragment[1] = "<managerEventInstance class=\"%s\">" % (class_level)
+ xml_fragment.insert(len(xml_fragment), "</managerEvent>")
+
+ dom = xml.dom.minidom.parseString(''.join(xml_fragment))
+
+ instance = dom.getElementsByTagName("managerEventInstance")[0]
+ syntax = instance.getElementsByTagName("syntax")
+ if not syntax:
+ syntax = dom.createElement("syntax")
+ instance.appendChild(syntax)
+ else:
+ syntax = syntax[0]
+
+ # Add parameters found in the method invocation that were not previously
+ # documented
+ for parameter in parameter_tokens:
+ if not parameter:
+ continue
+ parameter = (parameter.strip().replace("\"",""))[:parameter.index(":")]
+ if not any([node for node in syntax.getElementsByTagName("parameter") if
+ any([attr for attr in node.attributes.items() if attr[1] == parameter])]):
+ e = dom.createElement("parameter")
+ e.setAttribute('name', parameter)
+ syntax.appendChild(e)
+
+ return dom.toprettyxml().replace("<?xml version=\"1.0\" ?>", "")
+
+def main(argv=None):
+
+ if argv is None:
+ argv = sys.argv
+
+ in_doc = False
+ xml_fragment = []
+ xml = []
+ line_number = 0
+
+ while(True):
+ # Note: multiple places may have to read a line, so iterating over
+ # readlines isn't possible. Break when a null line is returned
+ line = sys.stdin.readline()
+ line_number += 1
+ if not line:
+ break
+
+ line = line.strip()
+ if ("/*** DOCUMENTATION" in line):
+ in_doc = True
+ elif ("***/" in line and in_doc == True):
+ # Depending on what we're processing, determine if we need to do
+ # any additional work
+ in_doc = False
+ if not xml_fragment:
+ # Nothing read, move along
+ continue
+ try:
+ if "<managerEventInstance>" in xml_fragment[0]:
+ xml.append(parse_manager_event_instance(xml_fragment))
+ else:
+ xml.append(''.join(xml_fragment))
+ xml_fragment = []
+ except:
+ print "Failed to parse XML near line: %d" % line_number
+ return 1
+ elif (in_doc == True):
+ xml_fragment.append("%s\n" % line)
+
+ sys.stdout.write(''.join(xml))
+ return 0
+
+if __name__ == "__main__":
+ sys.exit(main() or 0)
Propchange: team/mjordan/manager-events/build_tools/get_documentation.py
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/mjordan/manager-events/build_tools/get_documentation.py
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/mjordan/manager-events/build_tools/get_documentation.py
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: team/mjordan/manager-events/build_tools/post_process_documentation.py
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/manager-events/build_tools/post_process_documentation.py?view=auto&rev=368091
==============================================================================
--- team/mjordan/manager-events/build_tools/post_process_documentation.py (added)
+++ team/mjordan/manager-events/build_tools/post_process_documentation.py Thu May 31 16:40:37 2012
@@ -1,0 +1,85 @@
+#! /usr/bin/env python
+# vin: sw=3 et:
+'''
+Copyright (C) 2012, Digium, Inc.
+Matt Jordan <mjordan at digium.com>
+
+This program is free software, distributed under the terms of
+the GNU General Public License Version 2.
+'''
+
+import sys
+import os
+import xml.dom.minidom
+
+from xml.dom.minidom import Element, parse
+
+def merge_parameter_information(managerEvent):
+ instances = managerEvent.getElementsByTagName("managerEventInstance")
+ merged = []
+ for instance in instances:
+ others = [i for i in instances if i != instance]
+ parameters = instance.getElementsByTagName("parameter")
+ for parameter in parameters:
+ if parameter not in merged:
+ # Once we process a parameter, we don't need to do it again for any other
+ # managerEventInstances
+ merged.append(parameter)
+ # Compare the parameter to every other managerEventInstance's set of parameters
+ for other in others:
+ other_parameters = other.getElementsByTagName("parameter")
+ match = [p for p in other_parameters if p.getAttribute('name') == parameter.getAttribute('name')]
+ if (match):
+ # See who has the better documentation and use it,
+ if (parameter.hasChildNodes()):
+ match[0].parentNode.replaceChild(parameter.cloneNode(True), match[0])
+ elif (match[0].hasChildNodes()):
+ parameter.parentNode.replaceChild(match[0].cloneNode(True), parameter)
+
+def collapse_event_pair(managerEventOne, managerEventTwo):
+ # Move all children of managerEventTwo to managerEventOne
+ for node in managerEventTwo.childNodes:
+ managerEventOne.appendChild(node.cloneNode(True))
+
+ return managerEventOne
+
+def collapse_manager_events(rootNode, managerEvents):
+
+ events = {}
+ for managerEvent in managerEvents:
+ rootNode.removeChild(managerEvent)
+ attr = managerEvent.getAttribute('name')
+ if attr in events:
+ # match, collapse the two managerEvents
+ events[attr] = collapse_event_pair(events[attr], managerEvent)
+ else:
+ events[attr] = managerEvent
+
+ # Combine parameter information and re-add the manager Events
+ for k, event in events.items():
+ merge_parameter_information(event)
+ rootNode.appendChild(event)
+ return
+
+def main(argv=None):
+
+ if argv is None:
+ argv = sys.argv
+
+
+
+ dom = parse(inputFile)
+
+ datasource = open("doc/core-en_US.xml", 'w')
+ docs = dom.getElementsByTagName("docs")[0]
+ managerEvents = dom.getElementsByTagName("managerEvent")
+ if (managerEvents):
+ collapse_manager_events(docs, managerEvents)
+
+ dom.writexml(datasource)
+ datasource.close()
+
+ return 0
+
+if __name__ == "__main__":
+ sys.exit(main() or 0)
Propchange: team/mjordan/manager-events/build_tools/post_process_documentation.py
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/mjordan/manager-events/build_tools/post_process_documentation.py
------------------------------------------------------------------------------
svn:executable = *
Propchange: team/mjordan/manager-events/build_tools/post_process_documentation.py
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/mjordan/manager-events/build_tools/post_process_documentation.py
------------------------------------------------------------------------------
svn:mime-type = text/plain
Copied: team/mjordan/manager-events/configure.ac (from r366351, trunk/configure.ac)
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/manager-events/configure.ac?view=diff&rev=368091&p1=trunk/configure.ac&r1=366351&p2=team/mjordan/manager-events/configure.ac&r2=368091
==============================================================================
--- trunk/configure.ac (original)
+++ team/mjordan/manager-events/configure.ac Thu May 31 16:40:37 2012
@@ -247,6 +247,7 @@
AC_PATH_PROG([CMP], [cmp], :)
AC_PATH_PROG([FLEX], [flex], :)
AC_PATH_PROG([GREP], [grep], :)
+AC_PATH_PROG([PYTHON], [python], :)
AC_PATH_PROG([FIND], [find], :)
AC_PATH_PROG([COMPRESS], [compress], :)
AC_PATH_PROG([BASENAME], [basename], :)
Modified: team/mjordan/manager-events/makeopts.in
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/manager-events/makeopts.in?view=diff&rev=368091&r1=367982&r2=368091
==============================================================================
--- team/mjordan/manager-events/makeopts.in (original)
+++ team/mjordan/manager-events/makeopts.in Thu May 31 16:40:37 2012
@@ -12,6 +12,7 @@
BISON=@BISON@
FLEX=@FLEX@
GREP=@GREP@
+PYTHON=@PYTHON@
MAKE=@GNU_MAKE@
AR=@AR@
RANLIB=@RANLIB@
More information about the asterisk-commits
mailing list