route_graph.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. #! /usr/bin/env python
  2. """
  3. * $Id$
  4. *
  5. * Copyright (C) 2006 iptelorg GmbH
  6. *
  7. * This file is part of ser, a free SIP server.
  8. *
  9. * ser is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version
  13. *
  14. * For a license to use the ser software under conditions
  15. * other than those described here, or to purchase support for this
  16. * software, please contact iptel.org by e-mail at the following addresses:
  17. * [email protected]
  18. *
  19. * ser is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software
  26. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  27. *
  28. """
  29. import sys,re
  30. max_depth = 120
  31. debug = 0
  32. re_main_route = re.compile("^([a-z]+_)*route[\s\t]*(?![\(\)])[\s\t]*\{?", re.I)
  33. re_def_route = re.compile("^([a-z]+_)*route(\[\"?([A-Za-z0-9-_:]+)\"?\])+[\s\t]*\{?", re.I)
  34. re_call_route = re.compile("^(.*\([\s\t!]*)?route\(\"?([A-Za-z0-9-_]+)\"?\)", re.I)
  35. routes = {}
  36. f_routes = {}
  37. b_routes = {}
  38. r_routes = {}
  39. s_routes = {}
  40. e_routes = {}
  41. def log(_s):
  42. if debug:
  43. print _s
  44. def print_route_level(_l, _n):
  45. log("prl: %i, %s" % (_l, _n))
  46. if _l > max_depth:
  47. return
  48. spacer = ""
  49. route = ""
  50. for i in range(_l):
  51. spacer += "| "
  52. if i < _l - 1:
  53. route += "| "
  54. else:
  55. route += "\- " + str(_n)
  56. if len(spacer) > 0:
  57. print spacer
  58. if len(route) > 0:
  59. print route
  60. def traverse_routes(_level, _name):
  61. log("tr: %i, %s" % (_level, _name))
  62. if _level > max_depth:
  63. print "warning: max_depth reached"
  64. return
  65. print_route_level(_level, _name)
  66. if routes.has_key(_name):
  67. for r in routes[_name]:
  68. traverse_routes(_level + 1, r)
  69. if len(sys.argv) < 2:
  70. raise "usage: %s configuration-file [max_depth]" % sys.argv[0]
  71. if len(sys.argv) == 3:
  72. max_depth = int(sys.argv[2])
  73. cfg = file(sys.argv[1], "r")
  74. if cfg == None:
  75. raise "Missing config file"
  76. line = cfg.readline()
  77. rt = routes
  78. while line:
  79. line = line.strip()
  80. if not line.startswith("#"):
  81. log(line)
  82. main_match = re_main_route.search(line)
  83. def_match = re_def_route.search(line)
  84. call_match = re_call_route.search(line)
  85. if not call_match == None:
  86. log("CALL: " + line)
  87. name = call_match.group(2)
  88. log(rname +":"+name)
  89. rt[rname].append(name)
  90. elif not def_match == None:
  91. log("DEF: " + line)
  92. rtype = def_match.group(1)
  93. rname = def_match.group(3)
  94. if rtype == "failure_":
  95. rt = f_routes
  96. if rname == None:
  97. rname = "failure"
  98. elif rtype == "onreply_":
  99. rt = r_routes
  100. if rname == None:
  101. rname = "onreply"
  102. elif rtype == "onsend_":
  103. rt = s_routes
  104. if rname == None:
  105. rname = "onsend"
  106. elif rtype == "branch_":
  107. rt = b_routes
  108. if rname == None:
  109. rname = "branch"
  110. elif rtype == "event_":
  111. rt = e_routes
  112. if rname == None:
  113. rname = "event"
  114. else:
  115. rt = routes
  116. log(rname)
  117. rt[rname] = []
  118. elif not main_match == None:
  119. log("MAIN: " + line)
  120. rtype = main_match.group(1)
  121. if rtype == "failure_":
  122. rt = f_routes
  123. rname = "failure"
  124. elif rtype == "onreply_":
  125. rt = r_routes
  126. rname = "onreply"
  127. elif rtype == "onsend_":
  128. rt = s_routes
  129. rname = "onsend"
  130. elif rtype == "branch_":
  131. rt = b_routes
  132. rname = "branch"
  133. elif rtype == "event_":
  134. rt = e_routes
  135. rname = "event"
  136. else:
  137. rt = routes
  138. rname = "Main"
  139. log(rname)
  140. rt[rname] = []
  141. line = cfg.readline()
  142. log("routes: %s" % (routes))
  143. log("branch_routes: %s" % (b_routes))
  144. log("failure_routes: %s" % (f_routes))
  145. log("onreply_routes: %s" % (r_routes))
  146. log("onsend_routes: %s" % (s_routes))
  147. log("event_routes: %s" % (e_routes))
  148. for name in routes.keys():
  149. for val in routes[name]:
  150. if not routes.has_key(val):
  151. print "Missing Route %s!!!" % val
  152. # checking for unreferenced routes does not work yet because functions
  153. # can call routes as well?!
  154. #found = False
  155. #for n in routes.keys():
  156. # for v in routes[n]:
  157. # if v == name:
  158. # found = True
  159. #if not found and (not (name == "Main" or name == "Failure" or name == "Onreply" or name == "Branch")):
  160. # print "Unreferenced Route %s!!!" % name
  161. print "\nMain"
  162. traverse_routes(0, "Main")
  163. if len(b_routes) > 0:
  164. print "\nBranch routes\n-------------"
  165. for br in b_routes.keys():
  166. print "\n%s" % (br)
  167. for r in b_routes[br]:
  168. traverse_routes(1, r)
  169. if len(s_routes) > 0:
  170. print "\nSend routes\n-----------"
  171. for sr in s_routes.keys():
  172. print "\n%s" % (sr)
  173. for r in s_routes[sr]:
  174. traverse_routes(1, r)
  175. if len(f_routes) > 0:
  176. print "\nFailure routes\n--------------"
  177. for fr in f_routes.keys():
  178. print "\n%s" % (fr)
  179. for r in f_routes[fr]:
  180. traverse_routes(1, r)
  181. if len(r_routes) > 0:
  182. print "\nOnreply routes\n--------------"
  183. for onr in r_routes.keys():
  184. print "\n%s" % (onr)
  185. for r in r_routes[onr]:
  186. traverse_routes(1, r)
  187. if len(e_routes) > 0:
  188. print "\nEvent routes\n--------------"
  189. for onr in e_routes.keys():
  190. print "\n%s" % (onr)
  191. for r in e_routes[onr]:
  192. traverse_routes(1, r)
  193. print