/[escript]/trunk/scons/doxygen.py
ViewVC logotype

Contents of /trunk/scons/doxygen.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1234 - (show annotations)
Mon Aug 13 00:22:25 2007 UTC (11 years, 10 months ago) by phornby
File MIME type: text/x-python
File size: 6111 byte(s)
Based on http://www.scons.org/wiki/DoxygenBuilder, this is a useful tool for managing doxygen builds.
1 # vim: set et sw=4 tw=0 fo=awqorc ft=python:
2 #
3 # Astxx, the Asterisk C++ API and Utility Library.
4 # Copyright (C) 2005, 2006 Matthew A. Nicholson
5 # Copyright (C) 2006 Tim Blechmann
6 #
7 # This library is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU Lesser General Public
9 # License version 2.1 as published by the Free Software Foundation.
10 #
11 # This library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # Lesser General Public License for more details.
15 #
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with this library; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 import os
21 import os.path
22 import glob
23 from fnmatch import fnmatch
24
25 def DoxyfileParse(file_contents):
26 """
27 Parse a Doxygen source file and return a dictionary of all the values.
28 Values will be strings and lists of strings.
29 """
30 data = {}
31
32 import shlex
33 lex = shlex.shlex(instream = file_contents, posix = True)
34 lex.wordchars += "*+./-:"
35 lex.whitespace = lex.whitespace.replace("\n", "")
36 lex.escape = ""
37
38 lineno = lex.lineno
39 token = lex.get_token()
40 key = token # the first token should be a key
41 last_token = ""
42 key_token = False
43 next_key = False
44 new_data = True
45
46 def append_data(data, key, new_data, token):
47 if new_data or len(data[key]) == 0:
48 data[key].append(token)
49 else:
50 data[key][-1] += token
51
52 while token:
53 if token in ['\n']:
54 if last_token not in ['\\']:
55 key_token = True
56 elif token in ['\\']:
57 pass
58 elif key_token:
59 key = token
60 key_token = False
61 else:
62 if token == "+=":
63 if not data.has_key(key):
64 data[key] = list()
65 elif token == "=":
66 data[key] = list()
67 else:
68 append_data( data, key, new_data, token )
69 new_data = True
70
71 last_token = token
72 token = lex.get_token()
73
74 if last_token == '\\' and token != '\n':
75 new_data = False
76 append_data( data, key, new_data, '\\' )
77
78 # compress lists of len 1 into single strings
79 for (k, v) in data.items():
80 if len(v) == 0:
81 data.pop(k)
82
83 # items in the following list will be kept as lists and not converted to strings
84 if k in ["INPUT", "FILE_PATTERNS", "EXCLUDE_PATTERNS"]:
85 continue
86
87 if len(v) == 1:
88 data[k] = v[0]
89
90 return data
91
92 def DoxySourceScan(node, env, path):
93 """
94 Doxygen Doxyfile source scanner. This should scan the Doxygen file and add
95 any files used to generate docs to the list of source files.
96 """
97 default_file_patterns = [
98 '*.c', '*.cc', '*.cxx', '*.cpp', '*.c++', '*.java', '*.ii', '*.ixx',
99 '*.ipp', '*.i++', '*.inl', '*.h', '*.hh ', '*.hxx', '*.hpp', '*.h++',
100 '*.idl', '*.odl', '*.cs', '*.php', '*.php3', '*.inc', '*.m', '*.mm',
101 '*.py',
102 ]
103
104 default_exclude_patterns = [
105 '*~',
106 ]
107
108 sources = []
109
110 data = DoxyfileParse(node.get_contents())
111
112 if data.get("RECURSIVE", "NO") == "YES":
113 recursive = True
114 else:
115 recursive = False
116
117 file_patterns = data.get("FILE_PATTERNS", default_file_patterns)
118 exclude_patterns = data.get("EXCLUDE_PATTERNS", default_exclude_patterns)
119
120 for node in data.get("INPUT", []):
121 if os.path.isfile(node):
122 sources.append(node)
123 elif os.path.isdir(node):
124 if recursive:
125 for root, dirs, files in os.walk(node):
126 for f in files:
127 filename = os.path.join(root, f)
128
129 pattern_check = reduce(lambda x, y: x or bool(fnmatch(filename, y)), file_patterns, False)
130 exclude_check = reduce(lambda x, y: x and fnmatch(filename, y), exclude_patterns, True)
131
132 if pattern_check and not exclude_check:
133 sources.append(filename)
134 else:
135 for pattern in file_patterns:
136 sources.extend(glob.glob("/".join([node, pattern])))
137
138 sources = map( lambda path: env.File(path), sources )
139 return sources
140
141
142 def DoxySourceScanCheck(node, env):
143 """Check if we should scan this file"""
144 return os.path.isfile(node.path)
145
146 def DoxyEmitter(source, target, env):
147 """Doxygen Doxyfile emitter"""
148 # possible output formats and their default values and output locations
149 output_formats = {
150 "HTML": ("YES", "html"),
151 "LATEX": ("YES", "latex"),
152 "RTF": ("NO", "rtf"),
153 "MAN": ("YES", "man"),
154 "XML": ("NO", "xml"),
155 }
156
157 data = DoxyfileParse(source[0].get_contents())
158
159 targets = []
160 out_dir = data.get("OUTPUT_DIRECTORY", ".")
161
162 # add our output locations
163 for (k, v) in output_formats.items():
164 if data.get("GENERATE_" + k, v[0]) == "YES":
165 targets.append(env.Dir( os.path.join(out_dir, data.get(k + "_OUTPUT", v[1]))) )
166
167 # don't clobber targets
168 for node in targets:
169 env.Precious(node)
170
171 # set up cleaning stuff
172 for node in targets:
173 env.Clean(node, node)
174
175 return (targets, source)
176
177 def generate(env):
178 """
179 Add builders and construction variables for the
180 Doxygen tool. This is currently for Doxygen 1.4.6.
181 """
182 doxyfile_scanner = env.Scanner(
183 DoxySourceScan,
184 "DoxySourceScan",
185 scan_check = DoxySourceScanCheck,
186 )
187
188 doxyfile_builder = env.Builder(
189 # Stuffed if I know why I can't put quotes around ${SOURCE.dir}
190 # or ${SOURCE.file} on linux. Scons sucks,....really.
191 action = env.Action(
192 'cd ${SOURCE.dir} && "${DOXYGEN}" ${SOURCE.file}'),
193 emitter = DoxyEmitter,
194 target_factory = env.fs.Entry,
195 single_source = True,
196 source_scanner = doxyfile_scanner,
197 )
198
199 env.Append(BUILDERS = {
200 'Doxygen': doxyfile_builder,
201 })
202
203 env.AppendUnique( DOXYGEN = 'doxygen', )
204
205 def exists(env):
206 """
207 Make sure doxygen exists.
208 """
209 return env.Detect("doxygen")

  ViewVC Help
Powered by ViewVC 1.1.26