mirror of https://github.com/asterisk/asterisk
				
				
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							176 lines
						
					
					
						
							5.8 KiB
						
					
					
				
			
		
		
	
	
							176 lines
						
					
					
						
							5.8 KiB
						
					
					
				| #! /usr/bin/env python
 | |
| # vin: sw=3 et:
 | |
| '''
 | |
| Copyright (C) 2012, Digium, Inc.
 | |
| Matt Jordan <mjordan@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 get_manager_event_method_type(candidate_string):
 | |
|     if "ast_manager_event_multichan" in candidate_string:
 | |
|         return "multichan"
 | |
|     elif "ast_manager_event" in candidate_string:
 | |
|         return "ast_manager_event"
 | |
|     elif "manager_event" in candidate_string:
 | |
|         return "manager_event"
 | |
|     return ""
 | |
| 
 | |
| 
 | |
| 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
 | |
|     '''
 | |
| 
 | |
|     def __node_contains_parameter(node, parameter):
 | |
|         ''' Return whether or not a node contains a given parameter name '''
 | |
|         return any([n for n in node.getElementsByTagName("parameter")
 | |
|                     if __node_contains_attribute(n, parameter)])
 | |
| 
 | |
|     def __node_contains_attribute(node, attribute_name):
 | |
|         ''' Return whether or not a node contains a given attribute name '''
 | |
|         return any([attr for attr in node.attributes.items()
 | |
|                     if attr[1] == attribute_name])
 | |
| 
 | |
|     candidate_lines = []
 | |
|     type = ""
 | |
| 
 | |
|     # Read the manager_event method call, which should occur after
 | |
|     # the documentation block
 | |
|     for line in sys.stdin:
 | |
|         if len(line):
 | |
|             candidate_lines.append(line)
 | |
|         if ");" in line:
 | |
|             break
 | |
| 
 | |
|     candidate_string = ''.join(candidate_lines)
 | |
|     type = get_manager_event_method_type(candidate_string)
 | |
|     if not type:
 | |
|         # Unknown, return what we have
 | |
|         return ''.join(xml_fragment)
 | |
| 
 | |
|     # strip off the macro name
 | |
|     first_paren = candidate_string.index("(", 0)
 | |
|     last_paren = candidate_string.rindex(");")
 | |
|     candidate_string = candidate_string[first_paren + 1:last_paren]
 | |
| 
 | |
|     # 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.  Note that we temporarily
 | |
|     # add the xi namespace in case any includes are used
 | |
|     node_text = '<managerEvent language=\"%s\" name=\"%s\" xmlns:xi=\"%s\">'
 | |
|     xml_fragment.insert(0, node_text % ('en_US',
 | |
|                                         event_type.strip().replace("\"", ""),
 | |
|                                         'http://www.w3.org/2001/XInclude'))
 | |
|     xml_fragment[1] = "<managerEventInstance class=\"%s\">" % (class_level)
 | |
|     xml_fragment.insert(len(xml_fragment), "</managerEvent>")
 | |
| 
 | |
|     # Turn the XML into a DOM to manage the rest of the node manipulations
 | |
|     dom = xml.dom.minidom.parseString(''.join(xml_fragment))
 | |
| 
 | |
|     # Get the syntax node if we have one; otherwise make one
 | |
|     instance = dom.getElementsByTagName("managerEventInstance")[0]
 | |
|     syntax = instance.getElementsByTagName("syntax")
 | |
|     if not syntax:
 | |
|         syntax = dom.createElement("syntax")
 | |
|         instance.appendChild(syntax)
 | |
|         # Move any existing parameter nodes over
 | |
|         for node in instance.getElementsByTagName("parameter"):
 | |
|             syntax.appendChild(node.cloneNode(True))
 | |
|             instance.removeChild(node)
 | |
|     else:
 | |
|         syntax = syntax[0]
 | |
| 
 | |
|     # Add parameters found in the method invocation that were not previously
 | |
|     # documented
 | |
|     for parameter in parameter_tokens:
 | |
|         if not len(parameter):
 | |
|             continue
 | |
|         index = parameter.find(':')
 | |
|         if index < 0:
 | |
|             index = len(parameter)
 | |
|         parameter = (parameter[:index].strip().replace("\"", ""))
 | |
|         if ('%s' not in parameter and
 | |
|             not __node_contains_parameter(syntax, parameter)):
 | |
|             e = dom.createElement("parameter")
 | |
|             e.setAttribute('name', parameter)
 | |
|             syntax.appendChild(e)
 | |
| 
 | |
|     return dom.toxml().replace("<?xml version=\"1.0\" ?>", "").replace(
 | |
|                'xmlns:xi="http://www.w3.org/2001/XInclude"', '')
 | |
| 
 | |
| 
 | |
| def main(argv=None):
 | |
| 
 | |
|     if argv is None:
 | |
|         argv = sys.argv
 | |
| 
 | |
|     in_doc = False
 | |
|     xml_fragment = []
 | |
|     xml = []
 | |
|     line_number = 0
 | |
| 
 | |
|     for line in sys.stdin:
 | |
|         # Note: multiple places may have to read a line, so iterating over
 | |
|         # readlines isn't possible.  Break when a null line is returned
 | |
|         line_number += 1
 | |
|         if not line:
 | |
|             break
 | |
| 
 | |
|         line = line.strip()
 | |
|         if ("/*** DOCUMENTATION" in line):
 | |
|             in_doc = True
 | |
|         elif ("***/" in line and in_doc):
 | |
|             # 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
 | |
| 
 | |
|             if "<managerEventInstance>" in xml_fragment[0]:
 | |
|                 xml.append(parse_manager_event_instance(xml_fragment))
 | |
|             else:
 | |
|                 xml.append(''.join(xml_fragment))
 | |
| 
 | |
|             xml_fragment = []
 | |
|         elif (in_doc):
 | |
|             xml_fragment.append("%s\n" % line)
 | |
| 
 | |
|     sys.stdout.write(''.join(xml))
 | |
|     return 0
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     sys.exit(main() or 0)
 |