Asterisk - The Open Source Telephony Project  18.5.0
get_documentation.py
Go to the documentation of this file.
1 #! /usr/bin/env python
2 # vin: sw=3 et:
3 '''
4 Copyright (C) 2012, Digium, Inc.
5 Matt Jordan <[email protected]>
6 
7 This program is free software, distributed under the terms of
8 the GNU General Public License Version 2.
9 '''
10 
11 import sys
12 import xml.dom.minidom
13 
14 
15 def get_manager_event_method_type(candidate_string):
16  if "ast_manager_event_multichan" in candidate_string:
17  return "multichan"
18  elif "ast_manager_event" in candidate_string:
19  return "ast_manager_event"
20  elif "manager_event" in candidate_string:
21  return "manager_event"
22  return ""
23 
24 
25 def parse_manager_event_instance(xml_fragment):
26  ''' Parse the information for a manager event
27 
28  Keyword Arguments:
29  xml_fragment The XML fragment comment
30 
31  Returns:
32  A well-formed XML fragment containing the comments passed in, as well as
33  information obtained from the manager_event macro calls
34  '''
35 
36  def __node_contains_parameter(node, parameter):
37  ''' Return whether or not a node contains a given parameter name '''
38  return any([n for n in node.getElementsByTagName("parameter")
39  if __node_contains_attribute(n, parameter)])
40 
41  def __node_contains_attribute(node, attribute_name):
42  ''' Return whether or not a node contains a given attribute name '''
43  return any([attr for attr in node.attributes.items()
44  if attr[1] == attribute_name])
45 
46  candidate_lines = []
47  type = ""
48 
49  # Read the manager_event method call, which should occur after
50  # the documentation block
51  for line in sys.stdin:
52  if len(line):
53  candidate_lines.append(line)
54  if ");" in line:
55  break
56 
57  candidate_string = ''.join(candidate_lines)
58  type = get_manager_event_method_type(candidate_string)
59  if not type:
60  # Unknown, return what we have
61  return ''.join(xml_fragment)
62 
63  # strip off the macro name
64  first_paren = candidate_string.index("(", 0)
65  last_paren = candidate_string.rindex(");")
66  candidate_string = candidate_string[first_paren + 1:last_paren]
67 
68  # split into parameter tokens
69  func_parameter_tokens = candidate_string.split(',')
70 
71  if type == "manager_event" or type == "multichan":
72  class_level = func_parameter_tokens[0].strip()
73  event_type = func_parameter_tokens[1].strip()
74  else:
75  class_level = func_parameter_tokens[1].strip()
76  event_type = func_parameter_tokens[2].strip()
77 
78  if type == "manager_event":
79  event_parameters = func_parameter_tokens[2].strip()
80  elif type == "ast_manager_event":
81  event_parameters = func_parameter_tokens[3].strip()
82  else:
83  event_parameters = func_parameter_tokens[4].strip()
84 
85  parameter_tokens = event_parameters.replace("\"", "").split('\\r\\n')
86 
87  # Build the top level XML element information. Note that we temporarily
88  # add the xi namespace in case any includes are used
89  node_text = '<managerEvent language=\"%s\" name=\"%s\" xmlns:xi=\"%s\">'
90  xml_fragment.insert(0, node_text % ('en_US',
91  event_type.strip().replace("\"", ""),
92  'http://www.w3.org/2001/XInclude'))
93  xml_fragment[1] = "<managerEventInstance class=\"%s\">" % (class_level)
94  xml_fragment.insert(len(xml_fragment), "</managerEvent>")
95 
96  # Turn the XML into a DOM to manage the rest of the node manipulations
97  dom = xml.dom.minidom.parseString(''.join(xml_fragment))
98 
99  # Get the syntax node if we have one; otherwise make one
100  instance = dom.getElementsByTagName("managerEventInstance")[0]
101  syntax = instance.getElementsByTagName("syntax")
102  if not syntax:
103  syntax = dom.createElement("syntax")
104  instance.appendChild(syntax)
105  # Move any existing parameter nodes over
106  for node in instance.getElementsByTagName("parameter"):
107  syntax.appendChild(node.cloneNode(True))
108  instance.removeChild(node)
109  else:
110  syntax = syntax[0]
111 
112  # Add parameters found in the method invocation that were not previously
113  # documented
114  for parameter in parameter_tokens:
115  if not len(parameter):
116  continue
117  index = parameter.find(':')
118  if index < 0:
119  index = len(parameter)
120  parameter = (parameter[:index].strip().replace("\"", ""))
121  if ('%s' not in parameter and
122  not __node_contains_parameter(syntax, parameter)):
123  e = dom.createElement("parameter")
124  e.setAttribute('name', parameter)
125  syntax.appendChild(e)
126 
127  return dom.toxml().replace("<?xml version=\"1.0\" ?>", "").replace(
128  'xmlns:xi="http://www.w3.org/2001/XInclude"', '')
129 
130 
131 def main(argv=None):
132 
133  if argv is None:
134  argv = sys.argv
135 
136  in_doc = False
137  xml_fragment = []
138  xml = []
139  line_number = 0
140 
141  for line in sys.stdin:
142  # Note: multiple places may have to read a line, so iterating over
143  # readlines isn't possible. Break when a null line is returned
144  line_number += 1
145  if not line:
146  break
147 
148  line = line.strip()
149  if ("/*** DOCUMENTATION" in line):
150  in_doc = True
151  elif ("***/" in line and in_doc):
152  # Depending on what we're processing, determine if we need to do
153  # any additional work
154  in_doc = False
155  if not xml_fragment:
156  # Nothing read, move along
157  continue
158 
159  if "<managerEventInstance>" in xml_fragment[0]:
160  xml.append(parse_manager_event_instance(xml_fragment))
161  else:
162  xml.append(''.join(xml_fragment))
163 
164  xml_fragment = []
165  elif (in_doc):
166  xml_fragment.append("%s\n" % line)
167 
168  sys.stdout.write(''.join(xml))
169  return 0
170 
171 if __name__ == "__main__":
172  sys.exit(main() or 0)
def get_manager_event_method_type(candidate_string)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
def parse_manager_event_instance(xml_fragment)
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:790
def main(argv=None)