Complete SENFSCons documentation
g0dil [Tue, 13 Feb 2007 15:26:25 +0000 (15:26 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@198 270642c3-0616-0410-b53a-bc976706d245

LICENSE [new file with mode: 0644]
SConstruct
project.el [new file with mode: 0644]
senfscons/BoostUnitTests.py
senfscons/Dia2Png.py
senfscons/Doxyfile
senfscons/Doxygen.py
senfscons/Mainpage.dox [new file with mode: 0644]
senfscons/SENFSCons.py
senfscons/nodeglob.py [deleted file]
senfscons/pdflatex.py [deleted file]

diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..d60c31a
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,340 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
index 87c1beb..8198009 100644 (file)
@@ -6,16 +6,19 @@ import SENFSCons
 
 ###########################################################################
 
+# Load subversion information
 svninfo = dict(
     [ map(lambda y:y.strip(),x.split(":",1))
       for x in os.popen("svn info").read().split("\n")
       if ':' in x ] )
 svninfo['commited'] = not(os.popen("svn status -q").read())
 
+# Load utilities and setup libraries
 SENFSCons.UseBoost()
 SENFSCons.UseSTLPort()
 env = SENFSCons.MakeEnvironment()
 
+# Configure build
 env.Append(
    CPPPATH = [ '#' ],
    LIBS = [ 'iberty' ],
@@ -28,6 +31,7 @@ env.Append(
 
 Export('env')
 
+# Build modules (that is, instruct to build ... the build happens later)
 SConscript(glob.glob("*/SConscript"))
 
 SENFSCons.StandardTargets(env)
@@ -37,5 +41,7 @@ SENFSCons.DoxyXRef(env,
                    HTML_HEADER = '#/doclib/doxy-header-overview.html',
                    HTML_FOOTER = '#/doclib/doxy-footer.html')
 
+# Create Doxyfile.local if not cleaning and the file does not exist
+# otherwise doxygen will barf on this non-existent file
 if not env.GetOption('clean') and not os.path.exists("Doxyfile.local"):
     Execute(Touch("Doxyfile.local"))
diff --git a/project.el b/project.el
new file mode 100644 (file)
index 0000000..79f4e9b
--- /dev/null
@@ -0,0 +1,27 @@
+;; Configuration file for cc-ide.el (Emacs C++ IDE extension, see http://g0dil.de)
+
+(set (make-local-variable 'ccide-file-vars)
+     '(( fill-column  . 100    )
+       ( c-file-style . "senf" )
+       ( ispell-local-dictionary . "american" )))
+
+(set (make-local-variable 'ccide-default-copyright)
+     (concat "//\n"
+            "// This program is free software; you can redistribute it and/or modify\n"
+            "// it under the terms of the GNU General Public License as published by\n"
+            "// the Free Software Foundation; either version 2 of the License, or\n"
+            "// (at your option) any later version.\n"
+            "//\n"
+            "// This program is distributed in the hope that it will be useful,\n"
+            "// but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+            "// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
+            "// GNU General Public License for more details.\n"
+            "//\n"
+            "// You should have received a copy of the GNU General Public License\n"
+            "// along with this program; if not, write to the\n"
+            "// Free Software Foundation, Inc.,\n"
+            "// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\n"))
+
+(let ((local-conf (expand-file-name "project-local.el" ccide-project-root)))
+  (if (file-readable-p local-conf)
+      (load-file local-conf)))
index 7d250ad..e6aed7a 100644 (file)
@@ -1,3 +1,26 @@
+## \file
+# \brief BoostUnitTests build
+
+## \package senfscons.BoostUnitTests
+# \brief Builder utilizing the <a href="http://www.boost.org/libs/test/doc/index.html">Boost.Test</a> unit-test framework
+#
+# The BoostUnitTests builder will build a unit-test executable using
+# the <a
+# href="http://www.boost.org/libs/test/doc/index.html">Boost.Test</a>
+# library. After building, the unit-test will be executed.
+#
+# This builder is used by the SENFSCons.Object() helper to build the
+# unit test.
+#
+# \par Construction Envrionment Variables:
+# <table class="senf">
+# <tr><td>\c BOOSTTESTLIB</td><td>Name of the library to use, defaults to \c boost_unit_test_framework</td></tr>
+# <tr><td>\c BOOSTTESTARGS</td><td>Command line arguments of the test, defaults to <tt>--build_info=yes --log_level=test_suite</tt></td></tr>
+# </table>
+#
+# \todo This is not really a builder. This should be rewritten as one
+# \ingroup builder
+
 import SCons.Script.SConscript
 import SCons.Defaults
 import os.path
@@ -28,7 +51,7 @@ def BoostUnitTests(env, target, source, test_source=None, LIBS = [], DEPENDS = [
 
 def dispatcher(*arg,**kw):
     return BoostUnitTests(*arg,**kw)
-    
+
 def generate(env):
     env['BOOSTTESTLIB'] = 'boost_unit_test_framework'
     env['BOOSTTESTARGS'] = [ '--build_info=yes', '--log_level=test_suite' ]
index a518464..c20e6c7 100644 (file)
@@ -1,8 +1,22 @@
-"""Dia2Png SCons Builder: Build a PNG file given a DIA file.
-
-Support the specification of a scalefactor in the DIA2PNGDPI Environment variable.
-
-"""
+## \file
+# \brief Bia2Png builder
+
+## \package senfscons.Dia2Png
+# \brief Build a PNG file from a DIA file
+#
+# This builder will convert a given DIA file into a PNG image. The
+# size of the target file is specified by giving a preferred DPI value
+# and a maximum width. The Builder will automatically fetch the
+# correct aspect ratio from the dia file.
+#
+# \par Construction Envrionment Variables:
+# <table class="senf">
+# <tr><td>\c DIACOM</td><td>dia command, defaults to \c diak</td></tr>
+# <tr><td>\c DIA2PNGDPI</td><td>resolution of converted image, defaults to 115</td></tr>
+# <tr><td>\c DIA2PNGMAXWIDTH</td><td>maximum image width, defaults to 800</td></tr>
+# </table>
+#
+# \ingroup builder
 
 import os
 import SCons.Builder
index a3f0a5e..f76c709 100644 (file)
@@ -1,3 +1,8 @@
 @INCLUDE = "$(TOPDIR)/doclib/Doxyfile.global"
 
 PROJECT_NAME = SENFSCons
+BUILTIN_STL_SUPPORT = NO
+FILE_PATTERNS = *.dox *.py
+EXCLUDE_PATTERNS += __init__.py
+OPTIMIZE_OUTPUT_JAVA = YES
+ALPHABETICAL_INDEX = NO
index a853545..1d51a69 100644 (file)
@@ -1,3 +1,5 @@
+# The Doxygen builder is based on the Doxygen builder from:
+#
 # Astxx, the Asterisk C++ API and Utility Library.
 # Copyright (C) 2005, 2006  Matthew A. Nicholson
 # Copyright (C) 2006  Tim Blechmann
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-# I have been fighting 4 problems in this implementation:
+# The Modifications are Copyright (C) 2006,2007
+# Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+# Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+#     Stefan Bund <g0dil@berlios.de>
+
+## \file
+# \brief Doxygen builder
+
+## \package senfscons.Doxygen
+# \brief Doxygen Documentation Builder
+#
+# This builder will invoke \c doxygen to build software
+# documentation. The doxygen builder only takes the name of the
+# doxyfile as it's source file. The builder parses that doxygen
+# configuration file.
+#
+# The builder will automatically find all sources on which the
+# documentation depends. This includes
+# \li the source code files (as selected by the \c RECURSIVE, \c
+#     FILE_PATTERNS, \c INPUT and \c EXCLUDE_PATTERNS doxygen
+#     directives
+# \li the \c HTML_HEADER and \c HTML_FOOTER
+# \li all referenced \c TAGFILES
+# \li the \c INPUT_FILTER
+# \li all included doxyfiles (via \c @INCLUDE)
+#
+# The builder will emit a list of targets built by doxygen. This
+# depends on the types of documentation built.
+#
+# The builder will also generate additional commands to resolve
+# cross-references to other module documentations. This is based on
+# the \c TAGFILES used. Tagfiles built in the same project in other
+# modules are automatically found and the links will be resolved
+# correctly. To resolve links from external tagfiles, you may specify
+# <i>tagfilename</i><tt>_DOXY_URL</tt> as a construction environment
+# variable to specify the path to resolve references from the given
+# tagfile to. <i>tagfilename</i> is the uppercased basename of the
+# tagfile used.
+#
+# \par Construction Envrionment Variables:
+# <table class="senf">
+# <tr><td>\c DOXYGEN</td><td>doxygen command, defaults to \c doxygen</td></tr>
+# <tr><td><i>tag</i><tt>_DOXY_URL</tt></td><td>external tagfile resolve URL</td></tr>
+# </table>
+#
+# \ingroup builder
+
+# I (g0dil@berlios.de) have been fighting 4 problems in this
+# implementation:
 # - A Directory target will *not* call any source scanners
 # - A Directory target will interpret the directory contents as
 #   sources not targets. This means, that if a command creates that
@@ -71,7 +121,7 @@ def DoxyfileParse_(file, data, ENV):
 
       import shlex
       lex = shlex.shlex(instream=open(file), posix=True)
-      lex.wordchars += "*+./-:@~$()"
+      lex.wordchars += "*+=./-:@~$()"
       lex.whitespace = lex.whitespace.replace("\n", "")
       lex.escape = "\\"
 
diff --git a/senfscons/Mainpage.dox b/senfscons/Mainpage.dox
new file mode 100644 (file)
index 0000000..daaad72
--- /dev/null
@@ -0,0 +1,171 @@
+// Copyright (C) 2007 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+namespace senfscons {
+
+/** \mainpage The Senf Build Environment
+
+    The Senf Build Environment is based on the <a href="http://www.scons.org">SCons</a> software
+    construction tool. SCons is a <a href="http://www.python.org">python</a> based replacement for
+    \c make. SENFScons consists of several SCons builders as well as some global configuration and
+    build utilities. SEBFScons tightly integrates the <a
+    href="http://www.boost.org/libs/test/doc/index.html">Boost.Test</a> unit testing framework. It
+    also incorporates a very flexible infrastructure to build software documentation using <a
+    href="http://www.stack.nl/~dimitri/doxygen/">Doxygen</a>. This infrastructure uses quite a bit
+    of pre- and postprocessing (which is integrated with the provided Doxygen builder) to fix some
+    doxygen problems and generate a (IMHO) more readable layout.
+
+    \section layout The Project Layout
+
+    A Project using the SENFSCons infrastructure will always use a consistent directory layout. The
+    top-level directory will contain one subdirectory for every module. The main target will often
+    be considered to be just another module using the facilities provided by library modules.
+
+    The top-level project directory must contain the SENFSCons module in 'senfscons'.
+
+    The top-level \c SConstruct file will set up the global project configuration (which libraries
+    are used etc) and will then automatically load all module \c SConscript files.
+
+    Documentation is generated per module. This simplifies reusing modules in other projects. The
+    framework however semi-automatically creates the necessary cross-reference information to
+    cross-link the different module documentations. The unit-tests as well are run on a per-module
+    basis.
+    
+    \section Standard Build Configuration
+
+    When the \c SConsctruct and \c SConscript files are build using the default SENFSCons helpers,
+    by default all libraries and binaries are built. Some additional targets are
+
+    <dl><dt><tt>scons all_tests</tt></dt><dd>Build all unit tests</dd>
+    
+    <dt><tt>scons all_docs</tt></dt><dd>Build documentation of all modules</dd>
+    
+    <dt><tt>scons all</tt></dt><dd>Build all targets including binaries, libraries, documentation,
+    tests andpossible further targets </dd>
+
+    <dt><tt>scons -u doc</tt></dt><dd>Run from within a module directory will build the
+    documentation of that module</dd>
+
+    <dt><tt>scons -u test</tt></dt><dd>Run from within a module directory will build and run the
+    unit test of that module</dd></dl>
+
+    To clean any of the targets use the SCons \c -c parameter.
+
+    The build environment can be configured \e locally using \ref sconfig in the project root
+    directory.
+
+    \see
+       \ref sconstruct \n
+       \ref sconscript \n
+        \ref sconfig  \n
+        \ref builder
+ */
+
+/** \page sconstruct The Top-Level 'SConstruct' File
+
+    The top-level \c SConstruct file sets up the build, configures used libraries and parameters and
+    invokes the module \c SConscript files. To simplify the configuration, the SENFScons python
+    package is provided. This package has helper utilities to simplify standard tasks.
+
+    In \c senfscons/SConstruct.tempalte you may find an example SConstruct file. Copy this to the
+    project root (under the name \c SConstruct) to start a new project. You can then modify and
+    configure it to your wishes.
+
+    The general structure of the \c SConstruct file is
+    \li make the \c senfscons directory accessible
+    \li tell the SENFScons infrastructure, which frameworks you intend to use and let SENFScons
+       built a construction environment for you
+    \li configure the construction environment
+    \li load module sconscript file
+    \li specify global build targets
+
+    The first part, <i>making the \c senfscons directory accessible</i> will always stay the
+    same. See the template file for how this is done.
+    
+    <i>Simplifying the use of more complex frameworks</i> is one of the most important things why
+    SENFScons exists. If you only use very simple libraries, the configuration is quite
+    simple. However for more complex frameworks the configuration can get quite complicated. This is
+    simplified using the SENFScons framework statements. They all reside in the \c SENFSCons package
+    and have a prefix of \c Use. See \ref use.
+
+    After all frameworks are configured, you can use SEFNScons.MakeEnvironment() to create a
+    corretly configured construction environment.
+
+    To <i>configure the construction environment</i> you can set Variables in the construction
+    environment. See the SCons manpage for a list of supported variables. Some additional variables
+    are available with the new builders introduced with SENFSCons. Those are documented with the
+    builder module documentation.
+
+    <i>Loading the module \c SConscript files</i> will normally always be performed the same way
+    using \c glob.glob() to automatically include any subdirectory module.
+
+    You may then <i>specify global build targets</i>. You can use standard SCons targets or use all
+    the target helpers provided with SENFSCons. Two standard helpers should always be included:
+    SENFSCons.StandardTargets() and SENFSCons.GlobalTargets(). You can find more target helpers at
+    \ref target
+
+    The SConstruct file is an ordinary python file. It is loaded by SCons prior to building the
+    software. Just remember, you can use all of python and all of SCons here. SENFScons just
+    provides some additional helpers to make things simpler and more concise.
+
+    \see 
+       \ref use \n
+       \ref target
+ */
+
+/** \page sconscript The Module 'SConscript' Files
+
+    Every module (that is subdirectory) is built by that modules \c SConscript file. In \c
+    SConscript.template you can find a template of such a file.
+
+    Every \c SConscript file starts by importing the construction environment. The \c SConscript
+    file is an ordinary \c SConscript file as used by SCons. You may use any of the SCons facilities
+    to define targets. However, you will mostly use the \ref target.
+
+    Every \c SConscript file should call \c SENFSCons.StandardTargets() to initialize the standard
+    targets of every module.
+
+    \see
+       \ref target
+ */
+
+/** \page sconfig The 'SConfig' File
+    
+    To configure the build environment to the local environment, a \c SConfig file may be created in
+    the projects root directory. The supported parameters are
+    
+    <dl><dt>\c CXX</dt><dd>C++ compiler to use</dd>
+    <dt>\c EXTRA_DEFINES</dt><dd>preprocessor symbols to be defined locally</dd>
+    <dt>\c EXTRA_LIBS</dt><dd>additional libraries needed for a local build</dd></dl>
+
+    Additionally, the \ref use define additional configuration variables which may be set here.
+ */
+
+}
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// mode: flyspell
+// mode: auto-fill
+// ispell-local-dictionary: "american"
+// End:
index 771d4fa..9d243ce 100644 (file)
@@ -1,6 +1,50 @@
+## \file
+# \brief SENFSCons package
+
+## \package senfscons.SENFSCons
+# \brief Build helpers and utilities
+#
+# The SENFSCons package contains a number of build helpers and
+# utilities which are used to simplify commmon tasks. 
+#
+# The utitlities of this package are grouped into:
+# <dl><dt>\ref use</dt><dd>help using complex environments and
+# configure the construction environmen correspondingly</dd>
+#
+# <dt>\ref target</dt><dd>simplify building common targest and include
+# enhanced functionality like unit-testing.</dd></dl>
+#
+# Additionally for external use are
+# <dl><dt>MakeEnvironment()</dt><dd>Build construction
+# environment</dd>
+#
+# <dt>GlobSources()</dt><dd>Utility to find source files</dd></dl>
+#
+# All other functions are for internal use only.
+
 import os.path, glob
 import  SCons.Options, SCons.Environment, SCons.Script.SConscript, SCons.Node.FS, SCons.Defaults
 
+## \defgroup use Predefined Framework Configurators
+#
+# The following framework configurators are used in the top level \c
+# SConstruct file to simplify more complex configurations. 
+#
+# Each of the framework configurators introduces additional
+# configuration parameters to \ref sconfig
+
+## \defgroup target Target Helpers
+#
+# To specify standard targets, the following helpers can be used. They
+# automatically integrate several modules (like documentation,
+# unit-testing etc).
+
+## \defgroup builder Builders
+#
+# The SENFSCons framework includes a series of builders. Each builder
+# is defined in it's own package.
+
+# Tools to load in MakeEnvironment
 SCONS_TOOLS = [
     "Doxygen",
     "Dia2Png",
@@ -9,8 +53,11 @@ SCONS_TOOLS = [
 opts = None
 finalizers = []
 
+# This is the directory SENFSCons.py resides
 basedir = os.path.abspath(os.path.split(__file__)[0])
 
+## \brief Initialize configuration options
+# \internal
 def InitOpts():
     global opts
     if opts is not None: return
@@ -20,10 +67,51 @@ def InitOpts():
     opts.Add('EXTRA_LIBS', 'Additional libraries to link against', '')
     opts.Add(SCons.Options.BoolOption('final','Enable optimization',0))
 
+# A finalizer is any callable object. All finalizers will be called
+# in MakeEnvironment. We use them so every finalizer has knowledge of
+# all frameworks in use (e.g.: the boost runtime depends on the use of
+# stlport).
+
+## \brief Register finalizer
+# \internal
 def Finalizer(f):
     global finalizers
     finalizers.append(f)
 
+## \brief Initialize the use of the <a href="http://www.boost.org/">Boost</a> library
+#
+# Configure the use of the <a href="http://www.boost.org">Boost</a>
+# libraries. Most of these libraries are header-only, some however
+# depend on a built library. The library selection is somewhat
+# involved and depends on the threading model and the type of build
+# (debug or final).
+#
+# \par Configuration Parameters:
+#     <table class="senf">
+#     <tr><td>\c BOOST_INCLUDES</td><td>Include directory.</td></tr>
+#     <tr><td>\c BOOST_LIBDIR</td><td>Library directory</td></tr>
+#     <tr><td>\c BOOST_VARIANT</td><td>Complete variant specification</td></tr>
+#     <tr><td>\c BOOST_TOOLSET</td><td>Toolset to use</td></tr>
+#     <tr><td>\c BOOST_RUNTIME</td><td>Runtime to use</td></tr>
+#     <tr><td>\c BOOST_DEBUG_RUNTIME</td><td>Explicit debug runtime</td></tr>
+#     </table>
+#
+# You can either specify \c BOOST_VARIANT explicitly or specify \c
+# BOOST_TOOLSET and \c BOOST_RUNTIME. If you give \c BOOST_TOOLSET, \c
+# BOOST_RUNTIME defaults to empty and \c BOOST_DEBUG_RUNTIME defaults
+# to \c gd, If \c BOOST_TOOLSET is specified and you have included
+# STLPort support (UseSTLPort()), then \c p is appended to both
+# runtimes.
+#
+# The Boost configuration can get realtively complex. If the boost
+# libraries are provided by the distribution, you probably don't need
+# to specify any parameters. If your configuration is more complex,
+# refer to the <a
+# href="http://www.boost.org/tools/build/v1/build_system.htm">Boost.Build</a>
+# documentation for a definition of the terms used above (toolset,
+# variant, runtime ...).
+#
+# \ingroup use
 def UseBoost():
     global opts
     InitOpts()
@@ -35,6 +123,8 @@ def UseBoost():
     opts.Add('BOOST_LIBDIR', 'The directory of the boost libraries', '')
     Finalizer(FinalizeBoost)
 
+## \brief Finalize Boost environment
+# \internal
 def FinalizeBoost(env):
     env.Tool('BoostUnitTests', [basedir])
 
@@ -51,6 +141,28 @@ def FinalizeBoost(env):
     env.Append(LIBPATH = [ '$BOOST_LIBDIR' ],
                CPPPATH = [ '$BOOST_INCLUDES' ])
 
+## \brief Use STLPort as STL replacement if available
+#
+# Use <a href="http://www.stlport.org">STLPort</a> as a replacement
+# for the system STL. STLPort has the added feature of providing fully
+# checked containers and iterators. This can greatly simplify
+# debugging. However, STLPort and Boost interact in a non-trivial way
+# so the configuration is relatively complex. This command does not
+# enforce the use of STLPort, it is only used if available.
+#
+# \par Configuration Parameters:
+#     <table class="senf">
+#     <tr><td>\c STLPORT_INCLUDES</td><td>Include directory.</td></tr>
+#     <tr><td>\c STLPORT_LIBDIR</td><td>Library directory</td></tr>
+#     <tr><td>\c STLPORT_LIB</td><td>Name of STLPort library</td></tr>
+#     <tr><td>\c STLPORT_DEBUGLIB</td><td>Name of STLPort debug library</td></tr>
+#     </table>
+#
+# If \c STLPORT_LIB is specified, \c STLPORT_DEBUGLIB defaults to \c
+# STLPORT_LIB with \c _stldebug appended. The STLPort library will
+# only be used, if \c STLPORT_LIB is set in \c SConfig.
+#
+# \ingroup use
 def UseSTLPort():
     global opts
     InitOpts()
@@ -60,6 +172,10 @@ def UseSTLPort():
     opts.Add('STLPORT_LIBDIR', 'The directory of the stlport libraries','')
     Finalizer(FinalizeSTLPort)
 
+# \}
+
+## \brief Finalize STLPort environment
+# \internal
 def FinalizeSTLPort(env):
     if env['STLPORT_LIB']:
         if not env['STLPORT_DEBUGLIB']:
@@ -72,6 +188,16 @@ def FinalizeSTLPort(env):
             env.Append(LIBS = [ '$STLPORT_DEBUGLIB' ],
                        CPPDEFINES = [ '_STLP_DEBUG' ])
 
+## \brief Build a configured construction environment
+#
+# This function is called after all frameworks are specified to build
+# a tailored construction environment. You can then use this
+# construction environment just like an ordinary SCons construction
+# environment (which it is ...)
+#
+# This call will set some default compilation parameters depending on
+# the \c final command line option: specifying <tt>final=1</tt> will
+# built a release version of the code.
 def MakeEnvironment():
     global opts, finalizers
     InitOpts()
@@ -79,8 +205,10 @@ def MakeEnvironment():
     if SCons.Script.SConscript.Arguments.get('final'):
         env['final'] = 1
     env.Help(opts.GenerateHelpText(env))
-    #conf = env.Configure()
-    #env = conf.env
+
+    # We want to pass the SSH_AUTH_SOCK system env-var so we can ssh
+    # into other hosts from within SCons rules. I have used rules like
+    # this e.g. to automatically install stuff on a remote system ...
     if os.environ.has_key('SSH_AUTH_SOCK'):
         env.Append( ENV = { 'SSH_AUTH_SOCK': os.environ['SSH_AUTH_SOCK'] } )
 
@@ -90,6 +218,8 @@ def MakeEnvironment():
     for tool in SCONS_TOOLS:
         env.Tool(tool, [basedir])
 
+    # These are the default compilation parameters. We should probably
+    # make these configurable
     env.Append(CXXFLAGS = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long' ],
                LOCALLIBDIR = [ '#' ],
                LIBPATH = [ '$LOCALLIBDIR' ])
@@ -104,24 +234,63 @@ def MakeEnvironment():
     env.Append(CPPDEFINES = [ '$EXTRA_DEFINES' ],
                LIBS = [ '$EXTRA_LIBS' ])
 
-    #return conf.Finish()
     return env
 
+## \brief Find normal and test C++ sources
+#
+# GlobSources() will return a list of all C++ source files (named
+# "*.cc") as well as a list of all unit-test files (named "*.test.cc")
+# in the current directory. The sources will be returned as a tuple of
+# sources, test-sources. The target helpers all accept such a tuple as
+# their source argument.
 def GlobSources(exclude=[]):
     testSources = glob.glob("*.test.cc")
     sources = [ x for x in glob.glob("*.cc") if x not in testSources and x not in exclude ]
     return (sources, testSources)
     
+## \brief Add generic standard targets for every module
+#
+# This target helper should be called in the top-level \c SConstruct file
+# as well as in every module \c SConscipt file. It adds general
+# targets. Right now, these are
+# \li clean up \c .sconsign, \c .sconf_temp and \c config.log on
+#   <tt>scons -c all</tt>
+# 
+# \ingroup target
 def StandardTargets(env):
-    all = env.Alias('all')
-    env.Clean(all, [ '.sconsign', '.sconf_temp', 'config.log' ])
-    env.Depends(all, '.')
-
+    env.Clean(env.Alias('all'), [ '.sconsign', '.sconf_temp', 'config.log' ])
+
+## \brief Add generic global targets
+#
+# This target helper should be called in the top-level \c SConstruct
+# file. It adds general global targets. Right now theese are
+# \li Make <tt>scons all</tt> build all targets.
+#
+# \ingroup target
 def GlobalTargets(env):
-    pass
+    env.Depends(env.Alias('all'),'#')
 
+## \brief Return path of a built library within $LOCALLIBDIR
+# \internal
 def LibPath(lib): return '$LOCALLIBDIR/lib%s.a' % lib
-    
+
+## \brief Build object files
+#
+# This target helper will build object files from the given
+# sources.
+#
+# If \a testSources are given, a unit test will be built using the <a
+# href="http://www.boost.org/libs/test/doc/index.html">Boost.Test</a>
+# library. \a LIBS may specify any additional library modules <em>from
+# the same project</em> on which the test depends. Those libraries
+# will be linked into the final test executable. The test will
+# automatically be run if the \c test or \c all_tests targets are
+# given.
+#
+# If \a sources is a 2-tuple as returned by GlobSources(), it will
+# provide both \a sources and \a testSources.
+#
+# \ingroup target
 def Objects(env, sources, testSources = None, LIBS = []):
     if type(sources) == type(()):
         testSources = sources[1]
@@ -146,6 +315,43 @@ def Objects(env, sources, testSources = None, LIBS = []):
 
     return objects
 
+## \brief Build documentation with doxygen
+#
+# The doxygen target helper will build software documentation using
+# the given \a doxyfile (which defaults to \c Doxyfile). The Doxygen
+# builder used supports automatic dependency generation (dependencies
+# are automatically generated from the parameters specified in the \a
+# doxyfile), automatic target emitters (the exact targets created are
+# found parsing the \a doxyfile) and lots of other features. See the
+# Doxygen builder documentation
+#
+# If \a extra_sources are given, the generated documentation will
+# depend on them. This can be used to build images or other
+# supplementary files.
+#
+# The doxygen target helper extends the builder with additional
+# functionality:
+#
+# \li Fix tagfiles by removing namespace entries. These entries only
+#     work for namespaces completely defined in a single module. As
+#     soon as another module (which references the tagfile) has it's
+#     own members in that namespace, the crosslinking will break.
+# \li If \c DOXY_HTML_XSL is defined as a construction environment
+#     variable, preprocess all generated html files (if html files are
+#     generated) by the given XSLT stylesheet. Since the HTML
+#     generated by doxygen is broken, we first filter the code through
+#     HTML-\c tidy and filter out some error messages.
+# \li If xml output is generatedwe create files \c bug.xmli and \c
+#     todo.xmli which contain all bugs and todo items specified in the
+#     sources. The format of these files is much more suited to
+#     postprocessing and is a more database like format as the doxygen
+#     generated files (which are more presentation oriented). if \c
+#     DOXY_XREF_TYPES is given, it will specify the cross reference
+#     types to support (defaults to \c bug and \c todo). See <a
+#     href="http://www.stack.nl/~dimitri/doxygen/commands.html#cmdxrefitem">\xrefitem</a>
+#     in the doxygen documentation.
+#
+# \ingroup target
 def Doxygen(env, doxyfile = "Doxyfile", extra_sources = []):
     # ARGHHH !!! without the [:] we are changing the target list
     #        ||| WITHIN THE DOXYGEN BUILDER
@@ -209,8 +415,18 @@ def Doxygen(env, doxyfile = "Doxyfile", extra_sources = []):
         env.Alias('all_docs', doc)
         env.Clean('all_docs', doc)
         env.Clean('all', doc)
+
     return docs
 
+## \brief Build combined doxygen cross-reference
+#
+# This command will build a complete cross-reference of \c xrefitems
+# accross all modules.
+#
+# Right now, this command is very project specific. It needs to be
+# generalized.
+#
+# \ingroup target
 def DoxyXRef(env, docs=None,
              HTML_HEADER = None, HTML_FOOTER = None,
              TITLE = "Cross-reference of action points"):
@@ -243,6 +459,16 @@ def DoxyXRef(env, docs=None,
     env.Alias('all_docs',xref)
     return xref
 
+## \brief Build library
+#
+# This target helper will build the given library. The library will be
+# called lib<i>library</i>.a as is customary on UNIX systems. \a
+# sources, \a testSources and \a LIBS are directly forwarded to the
+# Objects build helper.
+#
+# The library is added to the list of default targets.
+#
+#\ingroup target
 def Lib(env, library, sources, testSources = None, LIBS = []):
     objects = Objects(env,sources,testSources,LIBS=LIBS)
     lib = None
@@ -252,6 +478,16 @@ def Lib(env, library, sources, testSources = None, LIBS = []):
         env.Append(ALLLIBS = library)
     return lib
 
+## \brief Build executable
+#
+# This target helper will build the given binary.  The \a sources, \a
+# testSources and \a LIBS arguments are forwarded to the Objects
+# builder. The final program will be linked against all the library
+# modules specified in \a LIBS (those are libraries which are built as
+# part of the same proejct). To specify non-module libraries, use the
+# construction environment parameters or the framework helpers.
+#
+# \ingroup target
 def Binary(env, binary, sources, testSources = None, LIBS = []):
     objects = Objects(env,sources,testSources,LIBS=LIBS)
     program = None
diff --git a/senfscons/nodeglob.py b/senfscons/nodeglob.py
deleted file mode 100644 (file)
index feb19ba..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-import fnmatch
-import os
-
-def glob(match):
-    """Similar to glob.glob, except globs SCons nodes, and thus sees
-    generated files and files from build directories.  Basically, it sees
-    anything SCons knows about.  A key subtlety is that since this function
-    operates on generated nodes as well as source nodes on the filesystem,
-    it needs to be called after builders that generate files you want to
-    include."""
-    def fn_filter(node):
-        fn = str(node)
-        return fnmatch.fnmatch(os.path.basename(fn), match)
-
-    here = Dir('.')
-
-    children = here.all_children()
-    nodes = map(File, filter(fn_filter, children))
-    node_srcs = [n.srcnode() for n in nodes]
-
-    src = here.srcnode()
-    if src is not here:
-        src_children = map(File, filter(fn_filter, src.all_children()))
-        for s in src_children:
-            if s not in node_srcs:
-                nodes.append(File(os.path.basename(str(s))))
-
-    return nodes
diff --git a/senfscons/pdflatex.py b/senfscons/pdflatex.py
deleted file mode 100644 (file)
index bbb129b..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-import SCons.Defaults
-
-import md5, os.path
-import SCons.Action, SCons.Builder, SCons.Util, SCons.Errors, SCons.Environment
-
-PDFLaTeXAction = SCons.Action.CommandAction("$PDFLATEXCOM")
-
-# copied from Action.py ... changed to tage explicit path-names as
-# target/source instead of node objects
-def my_executeCommand(cmd_list, target, source, env):
-    import SCons.Util 
-    escape = env.get('ESCAPE', lambda x: x)
-    if env.has_key('SHELL'): shell = env['SHELL']
-    else: raise SCons.Errors.UserError('Missing SHELL construction variable.')
-    if env.has_key('PIPE_BUILD'):
-        pipe_build = 1
-        if env.has_key('PSPAWN'): pspawn = env['PSPAWN']
-        else: raise SCons.Errors.UserError('Missing PSPAWN construction variable.')
-        if env.has_key('PSTDOUT'): pstdout = env['PSTDOUT']
-        else: raise SCons.Errors.UserError('Missing PSTDOUT construction variable.')
-        if env.has_key('PSTDERR'): pstderr = env['PSTDERR']
-        else: raise SCons.Errors.UserError('Missing PSTDOUT construction variable.')
-    else:
-        pipe_build = 0
-        if env.has_key('SPAWN'): spawn = env['SPAWN']
-        else: raise SCons.Errors.UserError('Missing SPAWN construction variable.')
-    # Here, replaced the source and target argumnets with a dict argument
-    cmd_list = env.subst_list(cmd_list, 0, dict = { 'TARGET': target, 'TARGETS': [ target ],
-                                                    'SOURCE': source, 'SOURCES': [ source ] })
-    for cmd_line in cmd_list:
-        if len(cmd_line):
-            try: ENV = env['ENV']
-            except KeyError:
-                global default_ENV
-                if not default_ENV:
-                    import SCons.Environment
-                    default_ENV = SCons.Environment.Environment()['ENV']
-                ENV = default_ENV
-            for key, value in ENV.items():
-                if SCons.Util.is_List(value):
-                    value = SCons.Util.flatten(value)
-                    ENV[key] = string.join(map(str, value), os.pathsep)
-                elif not SCons.Util.is_String(value):
-                    ENV[key] = str(value)
-            cmd_line = SCons.Util.escape_list(cmd_line, escape)
-            if pipe_build: ret = pspawn( shell, escape, cmd_line[0], cmd_line,
-                                         ENV, pstdout, pstderr )
-            else: ret = spawn(shell, escape, cmd_line[0], cmd_line, ENV)
-            if ret: return ret
-    return 0
-
-def TeXchecksum(files):
-    m = md5.new()
-    for f in files:
-        try:
-            m.update(file(f,"rb").read())
-        except IOError: pass
-    return m.digest()
-
-def TeXPdfAction(target, source, env):
-    src = os.path.abspath(str(source[0]))
-    path, pdf = os.path.split(str(target[0]))
-    base, ext = os.path.splitext(pdf)
-    cwd = os.getcwd()
-    if path: os.chdir(path)
-    checkfiles = [ base + ext for ext in env["TEXCHECKEXT"] ]
-    checksum = TeXchecksum(checkfiles)
-    rv = 0
-    for i in range(env["TEXMAXRECURSE"]+1):
-        if i==env["TEXMAXRECURSE"]:
-            print "\nWARNING: TeX recursion depth exceeded. They generated file may not be final.\n"
-            break
-        rv = my_executeCommand("$PDFLATEXCOM", pdf, src, env)
-        if rv: break
-        new_checksum = TeXchecksum(checkfiles)
-        if new_checksum == checksum: break
-        checksum = new_checksum
-    os.chdir(cwd)
-    return rv
-
-class TeXPdfBuilder(SCons.Builder.BuilderBase) :
-    def __call__(self, env, target = None, source = SCons.Builder._null, **kw):
-        tlist = SCons.Builder.BuilderBase.__call__(self, env, target, source, **kw)
-        exts = env["TEXCHECKEXT"] + env["TEXCLEANEXT"]
-        for t in tlist:
-            base, ext = os.path.splitext(str(t))
-            for ext in exts:
-                env.Clean(t,base+ext)
-        return tlist
-
-
-def generate(env):
-    env['TEXCHECKEXT'] = [ '.aux', '.toc' ]
-    env['TEXCLEANEXT'] = [ '.log', '.dvi' ]
-    env['TEXMAXRECURSE'] = 5
-    env['BUILDERS']['PDF'] = TeXPdfBuilder(action = TeXPdfAction, suffix='.pdf')
-
-def exists(env):
-    return 1