jack2 codebase
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.

456 lines
13KB

  1. #!/usr/bin/python
  2. #
  3. # Copyright (C) 2007 Arnold Krille
  4. #
  5. # This file originates from FFADO (www.ffado.org)
  6. #
  7. # This program is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation, either version 3 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. #
  20. #
  21. # Astxx, the Asterisk C++ API and Utility Library.
  22. # Copyright (C) 2005, 2006 Matthew A. Nicholson
  23. # Copyright (C) 2006 Tim Blechmann
  24. #
  25. # This library is free software; you can redistribute it and/or
  26. # modify it under the terms of the GNU Lesser General Public
  27. # License version 2.1 as published by the Free Software Foundation.
  28. #
  29. # This library is distributed in the hope that it will be useful,
  30. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  31. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  32. # Lesser General Public License for more details.
  33. #
  34. # You should have received a copy of the GNU Lesser General Public
  35. # License along with this library; if not, write to the Free Software
  36. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  37. import os
  38. import os.path
  39. import glob
  40. from fnmatch import fnmatch
  41. def DoxyfileParse(file_contents):
  42. """
  43. Parse a Doxygen source file and return a dictionary of all the values.
  44. Values will be strings and lists of strings.
  45. """
  46. data = {}
  47. import shlex
  48. lex = shlex.shlex(instream = file_contents, posix = True)
  49. lex.wordchars += "*+./-:"
  50. lex.whitespace = lex.whitespace.replace("\n", "")
  51. lex.escape = ""
  52. lineno = lex.lineno
  53. token = lex.get_token()
  54. key = token # the first token should be a key
  55. last_token = ""
  56. key_token = False
  57. next_key = False
  58. new_data = True
  59. def append_data(data, key, new_data, token):
  60. if new_data or len(data[key]) == 0:
  61. data[key].append(token)
  62. else:
  63. data[key][-1] += token
  64. while token:
  65. if token in ['\n']:
  66. if last_token not in ['\\']:
  67. key_token = True
  68. elif token in ['\\']:
  69. pass
  70. elif key_token:
  71. key = token
  72. key_token = False
  73. else:
  74. if token == "+=":
  75. if not data.has_key(key):
  76. data[key] = list()
  77. elif token == "=":
  78. data[key] = list()
  79. else:
  80. append_data( data, key, new_data, token )
  81. new_data = True
  82. last_token = token
  83. token = lex.get_token()
  84. if last_token == '\\' and token != '\n':
  85. new_data = False
  86. append_data( data, key, new_data, '\\' )
  87. # compress lists of len 1 into single strings
  88. for (k, v) in data.items():
  89. if len(v) == 0:
  90. data.pop(k)
  91. # items in the following list will be kept as lists and not converted to strings
  92. if k in ["INPUT", "FILE_PATTERNS", "EXCLUDE_PATTERNS"]:
  93. continue
  94. if len(v) == 1:
  95. data[k] = v[0]
  96. return data
  97. def DoxySourceScan(node, env, path):
  98. """
  99. Doxygen Doxyfile source scanner. This should scan the Doxygen file and add
  100. any files used to generate docs to the list of source files.
  101. """
  102. default_file_patterns = [
  103. '*.c', '*.cc', '*.cxx', '*.cpp', '*.c++', '*.java', '*.ii', '*.ixx',
  104. '*.ipp', '*.i++', '*.inl', '*.h', '*.hh ', '*.hxx', '*.hpp', '*.h++',
  105. '*.idl', '*.odl', '*.cs', '*.php', '*.php3', '*.inc', '*.m', '*.mm',
  106. '*.py',
  107. ]
  108. default_exclude_patterns = [
  109. '*~',
  110. ]
  111. sources = []
  112. data = DoxyfileParse(node.get_contents())
  113. if data.get("RECURSIVE", "NO") == "YES":
  114. recursive = True
  115. else:
  116. recursive = False
  117. file_patterns = data.get("FILE_PATTERNS", default_file_patterns)
  118. exclude_patterns = data.get("EXCLUDE_PATTERNS", default_exclude_patterns)
  119. for node in data.get("INPUT", []):
  120. if os.path.isfile(node):
  121. sources.append(node)
  122. elif os.path.isdir(node):
  123. if recursive:
  124. for root, dirs, files in os.walk(node):
  125. for f in files:
  126. filename = os.path.join(root, f)
  127. pattern_check = reduce(lambda x, y: x or bool(fnmatch(filename, y)), file_patterns, False)
  128. exclude_check = reduce(lambda x, y: x and fnmatch(filename, y), exclude_patterns, True)
  129. if pattern_check and not exclude_check:
  130. sources.append(filename)
  131. else:
  132. for pattern in file_patterns:
  133. sources.extend(glob.glob("/".join([node, pattern])))
  134. sources = map( lambda path: env.File(path), sources )
  135. return sources
  136. def DoxySourceScanCheck(node, env):
  137. """Check if we should scan this file"""
  138. return os.path.isfile(node.path)
  139. def DoxyEmitter(source, target, env):
  140. """Doxygen Doxyfile emitter"""
  141. # possible output formats and their default values and output locations
  142. output_formats = {
  143. "HTML": ("YES", "html"),
  144. "LATEX": ("YES", "latex"),
  145. "RTF": ("NO", "rtf"),
  146. "MAN": ("YES", "man"),
  147. "XML": ("NO", "xml"),
  148. }
  149. data = DoxyfileParse(source[0].get_contents())
  150. targets = []
  151. out_dir = data.get("OUTPUT_DIRECTORY", ".")
  152. # add our output locations
  153. for (k, v) in output_formats.items():
  154. if data.get("GENERATE_" + k, v[0]) == "YES":
  155. targets.append(env.Dir( os.path.join(out_dir, data.get(k + "_OUTPUT", v[1]))) )
  156. # don't clobber targets
  157. for node in targets:
  158. env.Precious(node)
  159. # set up cleaning stuff
  160. for node in targets:
  161. env.Clean(node, node)
  162. return (targets, source)
  163. def generate(env):
  164. """
  165. Add builders and construction variables for the
  166. Doxygen tool. This is currently for Doxygen 1.4.6.
  167. """
  168. doxyfile_scanner = env.Scanner(
  169. DoxySourceScan,
  170. "DoxySourceScan",
  171. scan_check = DoxySourceScanCheck,
  172. )
  173. import SCons.Builder
  174. doxyfile_builder = SCons.Builder.Builder(
  175. action = "cd ${SOURCE.dir} && ${DOXYGEN} ${SOURCE.file}",
  176. emitter = DoxyEmitter,
  177. target_factory = env.fs.Entry,
  178. single_source = True,
  179. source_scanner = doxyfile_scanner,
  180. )
  181. env.Append(BUILDERS = {
  182. 'Doxygen': doxyfile_builder,
  183. })
  184. env.AppendUnique(
  185. DOXYGEN = 'doxygen',
  186. )
  187. def exists(env):
  188. """
  189. Make sure doxygen exists.
  190. """
  191. return env.Detect("doxygen")
  192. #!/usr/bin/python
  193. #
  194. # Copyright (C) 2007 Arnold Krille
  195. #
  196. # This file originates from FFADO (www.ffado.org)
  197. #
  198. # This program is free software: you can redistribute it and/or modify
  199. # it under the terms of the GNU General Public License as published by
  200. # the Free Software Foundation, either version 3 of the License, or
  201. # (at your option) any later version.
  202. #
  203. # This program is distributed in the hope that it will be useful,
  204. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  205. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  206. # GNU General Public License for more details.
  207. #
  208. # You should have received a copy of the GNU General Public License
  209. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  210. #
  211. #
  212. # Astxx, the Asterisk C++ API and Utility Library.
  213. # Copyright (C) 2005, 2006 Matthew A. Nicholson
  214. # Copyright (C) 2006 Tim Blechmann
  215. #
  216. # This library is free software; you can redistribute it and/or
  217. # modify it under the terms of the GNU Lesser General Public
  218. # License version 2.1 as published by the Free Software Foundation.
  219. #
  220. # This library is distributed in the hope that it will be useful,
  221. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  222. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  223. # Lesser General Public License for more details.
  224. #
  225. # You should have received a copy of the GNU Lesser General Public
  226. # License along with this library; if not, write to the Free Software
  227. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  228. import os
  229. import os.path
  230. import glob
  231. from fnmatch import fnmatch
  232. def DoxyfileParse(file_contents):
  233. """
  234. Parse a Doxygen source file and return a dictionary of all the values.
  235. Values will be strings and lists of strings.
  236. """
  237. data = {}
  238. import shlex
  239. lex = shlex.shlex(instream = file_contents, posix = True)
  240. lex.wordchars += "*+./-:"
  241. lex.whitespace = lex.whitespace.replace("\n", "")
  242. lex.escape = ""
  243. lineno = lex.lineno
  244. token = lex.get_token()
  245. key = token # the first token should be a key
  246. last_token = ""
  247. key_token = False
  248. next_key = False
  249. new_data = True
  250. def append_data(data, key, new_data, token):
  251. if new_data or len(data[key]) == 0:
  252. data[key].append(token)
  253. else:
  254. data[key][-1] += token
  255. while token:
  256. if token in ['\n']:
  257. if last_token not in ['\\']:
  258. key_token = True
  259. elif token in ['\\']:
  260. pass
  261. elif key_token:
  262. key = token
  263. key_token = False
  264. else:
  265. if token == "+=":
  266. if not data.has_key(key):
  267. data[key] = list()
  268. elif token == "=":
  269. data[key] = list()
  270. else:
  271. append_data( data, key, new_data, token )
  272. new_data = True
  273. last_token = token
  274. token = lex.get_token()
  275. if last_token == '\\' and token != '\n':
  276. new_data = False
  277. append_data( data, key, new_data, '\\' )
  278. # compress lists of len 1 into single strings
  279. for (k, v) in data.items():
  280. if len(v) == 0:
  281. data.pop(k)
  282. # items in the following list will be kept as lists and not converted to strings
  283. if k in ["INPUT", "FILE_PATTERNS", "EXCLUDE_PATTERNS"]:
  284. continue
  285. if len(v) == 1:
  286. data[k] = v[0]
  287. return data
  288. def DoxySourceScan(node, env, path):
  289. """
  290. Doxygen Doxyfile source scanner. This should scan the Doxygen file and add
  291. any files used to generate docs to the list of source files.
  292. """
  293. default_file_patterns = [
  294. '*.c', '*.cc', '*.cxx', '*.cpp', '*.c++', '*.java', '*.ii', '*.ixx',
  295. '*.ipp', '*.i++', '*.inl', '*.h', '*.hh ', '*.hxx', '*.hpp', '*.h++',
  296. '*.idl', '*.odl', '*.cs', '*.php', '*.php3', '*.inc', '*.m', '*.mm',
  297. '*.py',
  298. ]
  299. default_exclude_patterns = [
  300. '*~',
  301. ]
  302. sources = []
  303. data = DoxyfileParse(node.get_contents())
  304. if data.get("RECURSIVE", "NO") == "YES":
  305. recursive = True
  306. else:
  307. recursive = False
  308. file_patterns = data.get("FILE_PATTERNS", default_file_patterns)
  309. exclude_patterns = data.get("EXCLUDE_PATTERNS", default_exclude_patterns)
  310. for node in data.get("INPUT", []):
  311. if os.path.isfile(node):
  312. sources.append(node)
  313. elif os.path.isdir(node):
  314. if recursive:
  315. for root, dirs, files in os.walk(node):
  316. for f in files:
  317. filename = os.path.join(root, f)
  318. pattern_check = reduce(lambda x, y: x or bool(fnmatch(filename, y)), file_patterns, False)
  319. exclude_check = reduce(lambda x, y: x and fnmatch(filename, y), exclude_patterns, True)
  320. if pattern_check and not exclude_check:
  321. sources.append(filename)
  322. else:
  323. for pattern in file_patterns:
  324. sources.extend(glob.glob("/".join([node, pattern])))
  325. sources = map( lambda path: env.File(path), sources )
  326. return sources
  327. def DoxySourceScanCheck(node, env):
  328. """Check if we should scan this file"""
  329. return os.path.isfile(node.path)
  330. def DoxyEmitter(source, target, env):
  331. """Doxygen Doxyfile emitter"""
  332. # possible output formats and their default values and output locations
  333. output_formats = {
  334. "HTML": ("YES", "html"),
  335. "LATEX": ("YES", "latex"),
  336. "RTF": ("NO", "rtf"),
  337. "MAN": ("YES", "man"),
  338. "XML": ("NO", "xml"),
  339. }
  340. data = DoxyfileParse(source[0].get_contents())
  341. targets = []
  342. out_dir = data.get("OUTPUT_DIRECTORY", ".")
  343. # add our output locations
  344. for (k, v) in output_formats.items():
  345. if data.get("GENERATE_" + k, v[0]) == "YES":
  346. targets.append(env.Dir( os.path.join(out_dir, data.get(k + "_OUTPUT", v[1]))) )
  347. # don't clobber targets
  348. for node in targets:
  349. env.Precious(node)
  350. # set up cleaning stuff
  351. for node in targets:
  352. env.Clean(node, node)
  353. return (targets, source)
  354. def generate(env):
  355. """
  356. Add builders and construction variables for the
  357. Doxygen tool. This is currently for Doxygen 1.4.6.
  358. """
  359. doxyfile_scanner = env.Scanner(
  360. DoxySourceScan,
  361. "DoxySourceScan",
  362. scan_check = DoxySourceScanCheck,
  363. )
  364. import SCons.Builder
  365. doxyfile_builder = SCons.Builder.Builder(
  366. action = "cd ${SOURCE.dir} && ${DOXYGEN} ${SOURCE.file}",
  367. emitter = DoxyEmitter,
  368. target_factory = env.fs.Entry,
  369. single_source = True,
  370. source_scanner = doxyfile_scanner,
  371. )
  372. env.Append(BUILDERS = {
  373. 'Doxygen': doxyfile_builder,
  374. })
  375. env.AppendUnique(
  376. DOXYGEN = 'doxygen',
  377. )
  378. def exists(env):
  379. """
  380. Make sure doxygen exists.
  381. """
  382. return env.Detect("doxygen")