Asterisk - The Open Source Telephony Project GIT-master-f36a736
get_documentation.py
Go to the documentation of this file.
1#! /usr/bin/env python
2# vin: sw=3 et:
3'''
4Copyright (C) 2012, Digium, Inc.
5Matt Jordan <mjordan@digium.com>
6
7This program is free software, distributed under the terms of
8the GNU General Public License Version 2.
9'''
10
11import sys
12import xml.dom.minidom
13
14
15def 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
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
131def 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
171if __name__ == "__main__":
172 sys.exit(main() or 0)
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:888
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
def get_manager_event_method_type(candidate_string)
def main(argv=None)
def parse_manager_event_instance(xml_fragment)