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

Annotation of /trunk/scons/doxygen.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1234 - (hide annotations)
Mon Aug 13 00:22:25 2007 UTC (13 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 phornby 1234 # 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