-import SCons.Script.SConscript
-import SCons.Builder
-import SCons.Defaults
+# Astxx, the Asterisk C++ API and Utility Library.
+# Copyright (C) 2005, 2006 Matthew A. Nicholson
+# Copyright (C) 2006 Tim Blechmann
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1 as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import os, sys, traceback
import os.path
+import glob
+from fnmatch import fnmatch
+
+def DoxyfileParse(file_contents, dir, data = None):
+ """
+ Parse a Doxygen source file and return a dictionary of all the values.
+ Values will be strings and lists of strings.
+ """
+ try:
+ if data is None : data = {}
+
+ import shlex
+ lex = shlex.shlex(instream = file_contents, posix = True)
+ lex.wordchars += "*+./-:"
+ lex.whitespace = lex.whitespace.replace("\n", "")
+ lex.escape = ""
+
+ lineno = lex.lineno
+ token = lex.get_token()
+ key = None
+ last_token = ""
+ key_token = True
+ next_key = False
+ new_data = True
+
+ def append_data(data, key, new_data, token):
+ if new_data or len(data[key]) == 0:
+ data[key].append(token)
+ else:
+ data[key][-1] += token
+
+ while token:
+ if token in ['\n']:
+ if last_token not in ['\\']:
+ key_token = True
+ elif token in ['\\']:
+ pass
+ elif key_token:
+ if key == '@' : key += token
+ else : key = token
+ if token != '@' : key_token = False
+ else:
+ if token == "+=" or (token == "==" and key == "@INCLUDE"):
+ if not data.has_key(key):
+ data[key] = list()
+ elif token == "=":
+ data[key] = list()
+ else:
+ append_data( data, key, new_data, token )
+ new_data = True
+ if key == '@INCLUDE':
+ inc = os.path.join(dir,data['@INCLUDE'][-1])
+ if os.path.exists(inc) :
+ DoxyfileParse(open(inc).read(),dir,data)
+
+ last_token = token
+ token = lex.get_token()
+
+ if last_token == '\\' and token != '\n':
+ new_data = False
+ append_data( data, key, new_data, '\\' )
+
+ # compress lists of len 1 into single strings
+ for (k, v) in data.items():
+ if k == "@INCLUDE" : continue
+ if len(v) == 0:
+ data.pop(k)
+
+ # items in the following list will be kept as lists and not converted to strings
+ if k in ["INPUT", "FILE_PATTERNS", "EXCLUDE_PATTERNS"]:
+ continue
+
+ if len(v) == 1:
+ data[k] = v[0]
+
+ return data
+ except:
+ return {}
+
+def DoxySourceScan(node, env, path):
+ """
+ Doxygen Doxyfile source scanner. This should scan the Doxygen file and add
+ any files used to generate docs to the list of source files.
+ """
+ default_file_patterns = [
+ '*.c', '*.cc', '*.cxx', '*.cpp', '*.c++', '*.java', '*.ii', '*.ixx',
+ '*.ipp', '*.i++', '*.inl', '*.h', '*.hh ', '*.hxx', '*.hpp', '*.h++',
+ '*.idl', '*.odl', '*.cs', '*.php', '*.php3', '*.inc', '*.m', '*.mm',
+ '*.py',
+ ]
+
+ default_exclude_patterns = [
+ '*~',
+ ]
+
+ sources = []
+
+ data = DoxyfileParse(node.get_contents(), str(node.dir))
+
+ if data.get("RECURSIVE", "NO") == "YES":
+ recursive = True
+ else:
+ recursive = False
+
+ file_patterns = data.get("FILE_PATTERNS", default_file_patterns)
+ exclude_patterns = data.get("EXCLUDE_PATTERNS", default_exclude_patterns)
-def replace_ext(n,ext):
- base,ext = os.path.splitext(n)
- return base+ext
-
-def Doxygen(env, target, source, image=[]):
- global __file__
- path, name = os.path.split(str(target))
- stamp = os.path.join(path, '.'+name+'.stamp')
- dir = env.Dir(target)
- mak = os.path.join(os.path.split(__file__)[0],'imgconvert.mak')
- env.Depends(dir,
- [ env.Command(os.path.splitext(img)[0]+".png", img,
- [ 'TERM=dumb make -f %s $TARGET' % mak ])
- for img in image ] +
- [ env.Command(stamp, source + [ os.path.join(path,"Doxyfile") ],
- [ 'cd $TARGET.dir && $DOXYGENCOM',
- "touch $TARGET" ],
- source_scanner = SCons.Defaults.ObjSourceScan) ])
- env.Clean(stamp, dir)
- return dir
+ for i in data.get("INPUT", [ "." ]):
+ input = os.path.normpath(os.path.join(str(node.dir),i))
+ if os.path.isfile(input):
+ sources.append(input)
+ elif os.path.isdir(input):
+ if recursive:
+ entries = os.walk(input)
+ else:
+ entries = [ (input, [], os.listdir(input)) ]
+ for root, dirs, files in entries:
+ for f in files:
+ filename = os.path.join(root, f)
+
+ pattern_check = reduce(lambda x, y: x or bool(fnmatch(filename, y)), file_patterns, False)
+ exclude_check = reduce(lambda x, y: x and fnmatch(filename, y), exclude_patterns, True)
+
+ if pattern_check and not exclude_check:
+ sources.append(filename)
+
+ sources.extend([ os.path.normpath(os.path.join(str(node.dir),x))
+ for x in data.get("@INCLUDE",[]) ])
+
+ for key in ('HTML_HEADER','HTML_FOOTER','TAGFILES'):
+ if data.has_key(key):
+ elt = data[key]
+ if type(elt) is type ("") : elt = [ elt ]
+ sources.extend([ os.path.normpath(os.path.join(str(node.dir),f))
+ for f in elt ])
+
+ sources = map( lambda path: env.File(path), sources )
+ return sources
+
+def DoxySourceScanCheck(node, env):
+ """Check if we should scan this file"""
+ return os.path.isfile(node.path)
+
+def DoxyEmitter(source, target, env):
+ """Doxygen Doxyfile emitter"""
+ # possible output formats and their default values and output locations
+ output_formats = {
+ "HTML": ("YES", "html"),
+ "LATEX": ("YES", "latex"),
+ "RTF": ("NO", "rtf"),
+ "MAN": ("YES", "man"),
+ "XML": ("NO", "xml"),
+ }
+
+ data = DoxyfileParse(source[0].get_contents(), str(source[0].dir))
+
+ targets = []
+ out_dir = data.get("OUTPUT_DIRECTORY", ".")
+
+ # add our output locations
+ for (k, v) in output_formats.items():
+ if data.get("GENERATE_" + k, v[0]) == "YES":
+ # Grmpf ... need to use a File object here. The problem is, that
+ # Dir.scan() is implemented to just return the directory entries
+ # and does *not* invoke the source-file scanners .. ARGH !!
+ node = env.File( os.path.join(str(source[0].dir), out_dir, data.get(k + "_OUTPUT", v[1]), ".stamp" ))
+ targets.append( node )
+
+ if data.has_key("GENERATE_TAGFILE"):
+ targets.append(env.File( os.path.join(str(source[0].dir), data["GENERATE_TAGFILE"]) ))
+
+ # don't clobber targets
+ for node in targets:
+ env.Precious(node)
+
+ # set up cleaning stuff
+ for node in targets:
+ env.Clean(node, node)
+
+ return (targets, source)
def generate(env):
- env['DOXYGENCOM'] = 'doxygen'
- env.__class__.Doxygen = Doxygen
+ """
+ Add builders and construction variables for the
+ Doxygen tool. This is currently for Doxygen 1.4.6.
+ """
+ doxyfile_scanner = env.Scanner(
+ DoxySourceScan,
+ "DoxySourceScan",
+ scan_check = DoxySourceScanCheck,
+ )
+
+ doxyfile_builder = env.Builder(
+ # scons 0.96.93 hang on the next line but I don't know hot to FIX the problem
+ action = env.Action("( cd ${SOURCE.dir} && ${DOXYGEN} ${SOURCE.file} ) && touch $TARGETS"),
+ emitter = DoxyEmitter,
+ target_factory = env.fs.Entry,
+ single_source = True,
+ source_scanner = doxyfile_scanner
+ )
+
+ env.Append(BUILDERS = {
+ 'Doxygen': doxyfile_builder,
+ })
+
+ env.AppendUnique(
+ DOXYGEN = 'doxygen',
+ )
def exists(env):
- return 1
+ """
+ Make sure doxygen exists.
+ """
+ return env.Detect("doxygen")
+++ /dev/null
-
-PSTOPNG_DPI := 100
-
-CLEAN_FILE := $(shell pwd)/.clean
-clean := clean() { \
- touch $(CLEAN_FILE); \
- for file in "$$@"; do \
- grep "^$$file"'$$' $(CLEAN_FILE) >/dev/null || echo $$file >>$(CLEAN_FILE); \
- done \
-}; clean
-
-cmd := run() { tput bold; echo -e "--[ $$* ]"; tput sgr0; } && run
-do := run() { tput bold; echo -e "--[ $$* ]"; tput sgr0; "$$@"; } && run
-eval := run() { tput bold; echo -e "--[ $$* ]"; tput sgr0; eval "$$@"; } && run
-
-Q := @
-
-%.rawtex: %.stxt
- $(Q)$(clean) $@
- $(Q)$(cmd) "rest2latex $< >$@"; \
- rest2latex \
- --language=de \
- --documentclass=scrreprt \
- --documentoptions="10pt,a4paper,DIV10" \
- --table-style=booktabs \
- --use-verbatim-when-possible \
- --use-latex-footnotes \
- --use-latex-toc \
- --no-section-numbering \
- --stylesheet=default.sty \
- --exit-status=2 \
- $< \
- > $@ || (rm -f $@; exit 1)
-
-%.tex: %.rawtex
- $(Q)$(clean) $@
- $(Q)$(cmd) "rawfilter $< >$@"; \
- sed -e 's/\.\(png\|gif\|jpg\)/.pdf/g' \
- -e 's/\[htbp\]/\[tbp\]/g' $< >$@ \
- || (rm -f $@; exit 1)
-
-%.html: %.stxt
- $(Q)$(clean) $@
- $(Q)$(cmd) "rest2html $< >$@"; \
- up="`echo $< | sed -r -e 's,^[^/]*$$,,' -e 's,/[^/]+$$,/,' -e 's,[^/]+,..,g'`"; \
- rest2html \
- --language=de \
- --exit-status=2 \
- --stylesheet-path="$${up}default.css" \
- $< \
- > $@ || (rm -f $@; exit 1)
-
-%.pdf: %.tex
- $(Q)( \
- dir="$$(dirname $<)"; \
- up="echo $$dir | sed -e 's,[^/]\+,..,g"; \
- [ -n "$$dir" ] && dir="$$dir/"; \
- stem="$$(basename $*)"; \
- tex="$$(basename $<)"; \
- pdf="$$(basename $@)"; \
- $(clean) $${dir}texput.log; \
- cd "$$dir"; \
- repeat=5; \
- origfiles="$$(find $$stem.* ! \( -name $$pdf -o -name $$stem.log \) \
- -maxdepth 0 -printf '%p-%TY%Tm%Td%TH%TM%TS\n')"; \
- while [ $$repeat -gt 0 ]; do \
- $(cmd) "pdflatex --interaction nonstopmode $$tex"; \
- TEXINPUTS=.:$$up: pdflatex --interaction nonstopmode $$tex; \
- pdfexit=$$?; \
- auxfiles=$$((echo $$origfiles | tr ' ' '\n'; \
- find $$stem.* ! \( -name $$pdf -o -name $$stem.log \) \
- -maxdepth 0 -printf '%p-%TY%Tm%Td%TH%TM%TS\n') \
- | sort | uniq -u | sed -e 's/-[0-9]*$$//' | sort -u ); \
- for f in $$auxfiles; do \
- $(clean) $$dir$$f; \
- done; \
- $(clean) $*.log $@; \
- [ $$pdfexit -ne 0 ] && exit $$pdfexit; \
- newauxsum=`md5sum $$auxfiles | md5sum 2>/dev/null`; \
- [ "$$auxsum" = "$$newauxsum" ] && break; \
- auxsum="$$newauxsum"; \
- repeat=$$[ $$repeat - 1 ]; \
- done; \
- ) || (rm -f $@; exit 1)
-
-%.png: %.sxd
- $(Q)$(clean) $@
- $(Q)$(cmd) "(openoffice) sxdtopng $<"; \
- openoffice -invisible "macro:///Local.Conversion.ConvertDrawToPNG($(shell realpath $<))"
-
-%.pdf: %.sxd
- $(Q)$(clean) $@
- $(Q)$(cmd) "(openoffice) sxdtopdf $<"; \
- openoffice -invisible "macro:///Local.Conversion.ConvertDrawToPDF($(shell realpath $<))"
-
-%.pdf: %.sxc
- $(Q)$(clean) $@
- $(Q)$(cmd) "(openoffice) sxctopdf $<"; \
- openoffice -invisible "macro:///Local.Conversion.ConvertCalcToPDF($(shell realpath $<))"
-
-%.ps: %.pdf
- $(Q)$(clean) $@
- $(Q)$(cmd) "pdftops $< >$@"; \
- pdftops -eps -nocrop -noshrink -nocenter $< - | pstops - >$@ || (rm -f $@; exit 1)
-
-%.png: %.ps
- $(Q)$(clean) $@
- $(Q)$(cmd) "pstopng $< >$@"; \
- bb=$$(grep -i '^%%BoundingBox:' $< | head -1 | sed -e 's/^%%BoundingBox: *//i'); \
- bbx=$${bb% *}; \
- bbx=$${bbx##* }; \
- bby=$${bb##* }; \
- pngx=$$(dc -e "$$bbx $(PSTOPNG_DPI) * 8 * 75.45 / p"); \
- pngy=$$(dc -e "$$bby $(PSTOPNG_DPI) * 8 * 75.45 / p"); \
- pstopnm -xborder 0 -yborder 0 -portrait -nocrop -stdout -xsize $$pngx -ysize $$pngy $< \
- | pnmscale -reduce 8 \
- | pnmtopng >$@ \
- || (rm -f $@; exit 1)
-
-%.gif: %.png
- $(Q)$(clean) $@
- $(Q)$(cmd) "pngtogif $< >$@"
- $(Q)pngtopnm $< | ppmquant 256 | ppmtogif >$@ || ( rm -f $@; exit 1)
-
-%.pdf: %.dot
- $(Q)$(clean) $@
- $(Q)$(eval) "dot -Tfig $< | fig2dev -L pdf -f Helvetica >$@" || ( rm -f $@; exit 1 )
-
-%.pdf: %.neato
- $(Q)$(clean) $@
- $(Q)$(eval) "neato -Tfig $< | fig2dev -L pdf -f Helvetica >$@" || ( rm -f $@; exit 1 )
-
-%.eps: %.dia
- $(Q)$(clean) $@
- $(Q)$(do) dia -t eps -e $@ $<
-
-%.pdf: %.eps
- $(Q)$(clean) $@
- $(Q)$(do) epstopdf --outfile=$@ $<
-
-%.d: %.stxt
- $(Q)$(clean) $@
- $(Q) \
- $(cmd) "makedep $<"; \
- base="$$(dirname $<)"; \
- [ -n "$$base" ] && base="$${base}/"; \
- function scaninc { \
- local includes; \
- [ -r $$1 ] || return; \
- includes="$$(sed -n -e 's/^.. \+include:: *//' -e T -e p $$1)"; \
- for include in $$includes; do \
- echo $$base$$include; \
- scaninc $$base$$include; \
- done \
- }; \
- includes="$$(scaninc $<)"; \
- figures="$$(sed -n -e "s,^.. \+figure:: *,$$base," -e T -e p $< $$includes)"; \
- \
- echo "$*_Includes := $$(echo $$includes)" >$@; \
- echo "$*_Figures := $$(echo $$figures)" >>$@; \
- echo "$*_PDFs := $$(echo $$figures | sed -e 's/\.\(gif\|png\|jpg\)/.pdf/g')" >>$@; \
- echo '$@: Makefile $< $$($*_Includes)' >>$@; \
- echo '$*.html: $< $$($*_Includes)' >>$@; \
- echo '$*_html: $*.html $$($*_Figures)' >>$@; \
- echo '$*.tex: $< $$($*_Includes)' >>$@; \
- echo '$*.pdf: $*.tex $$($*_PDFs) $(TEX_STYLE)' >>$@
-
-###########################################################################
-
-clean:
- $(Q)if [ -r $(CLEAN_FILE) ]; then \
- $(cmd) "xargs rm -f <.clean && rm -f .clean"; \
- xargs rm -f <$(CLEAN_FILE) && rm -f $(CLEAN_FILE); \
- fi
-
-# Local Variables:
-# mode: makefile
-# makefile-backslash-column: 100
-# End: