pax_global_header00006660000000000000000000000064140207477640014525gustar00rootroot0000000000000052 comment=22497b190444e06491128bf7c4cd7d1d215325fb ccbuild-2.0.9/000077500000000000000000000000001402074776400131425ustar00rootroot00000000000000ccbuild-2.0.9/.github/000077500000000000000000000000001402074776400145025ustar00rootroot00000000000000ccbuild-2.0.9/.github/workflows/000077500000000000000000000000001402074776400165375ustar00rootroot00000000000000ccbuild-2.0.9/.github/workflows/main.yml000066400000000000000000000006111402074776400202040ustar00rootroot00000000000000name: main on: [push] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Setup run: | sudo apt-get install -y libgnutls28-dev g++ libbobcat-dev libgcrypt11-dev libboost-dev flex libfl-dev cmake . - name: Build run: cmake --build . --config Release - name: Test run: cd src; ../ccbuild ccbuild-2.0.9/.github/workflows/release.yml000066400000000000000000000011631402074776400207030ustar00rootroot00000000000000name: release on: push: tags: - "*" jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: Setup run: | sudo apt-get install -y libgnutls28-dev g++ libbobcat-dev libgcrypt11-dev libboost-dev flex libfl-dev pandoc cmake . - name: Build run: cmake --build . --config Release - name: Package run: ./package.sh id: package - uses: ncipollo/release-action@v1 with: artifacts: "build/ccbuild*.tar.gz" bodyFile: "build/release.md" token: ${{ secrets.GITHUB_TOKEN }} ccbuild-2.0.9/.gitignore000066400000000000000000000003011402074776400151240ustar00rootroot00000000000000.deps .dirstamp /src/o /test/o /src/*/*.o /src/ccbuild /pkgs /build /README /Makefile /CMakeCache.txt /CMakeFiles /cmake_install.cmake /autom4te.cache /src/sourceScanner/yylex.cc /ccbuild *.gchccbuild-2.0.9/AUTHORS000066400000000000000000000000361402074776400142110ustar00rootroot00000000000000A. Bram Neijt ccbuild-2.0.9/CMakeLists.txt000066400000000000000000000106611402074776400157060ustar00rootroot00000000000000cmake_minimum_required (VERSION 3.0) project (ccbuild) set (CMAKE_CXX_STANDARD 17) find_package(FLEX) FLEX_TARGET(SourceScanner "src/sourceScanner/lexer" "src/sourceScanner/yylex.cc" ) string(SUBSTRING ${FLEX_VERSION} 0 1 FLEX_VERSION_MAJOR) string(SUBSTRING ${FLEX_VERSION} 2 1 FLEX_VERSION_MINOR) add_definitions(-DVERSION="v2.0.7-39-gdf7b35c" -DFLEX_VERSION_MAJOR=${FLEX_VERSION_MAJOR} -DFLEX_VERSION_MINOR=${FLEX_VERSION_MINOR}) link_libraries(gomp bobcat gnutls) add_definitions(-fopenmp) add_executable(ccbuild src/ccbuild.cc src/MD5Info/statics.cc src/MD5Info/save.cc src/MD5Info/old.cc src/MD5Info/load.cc src/MD5Info/hashFilenameFor.cc src/MD5Info/getInstance.cc src/MD5Info/destroy.cc src/MD5Info/contentHash.cc src/MD5Info/MD5Info.cc src/options/statics.cc src/system/username.cc src/system/uname.cc src/system/trimmed.cc src/system/trim.cc src/system/system.cc src/system/statics.cc src/system/sleep.cc src/system/resolveTest.cc src/system/projectName.cc src/system/parseArguments.cc src/system/mkdtemp.cc src/system/md5.cc src/system/makefileForAll.cc src/system/makefileFor.cc src/system/localSourcesInto.cc src/system/lib.cc src/system/inspect.cc src/system/icmake.cc src/system/exit.cc src/system/dotgraphForAll.cc src/system/dotgraphFor.cc src/system/distclean.cc src/system/destroy.cc src/system/depsFor.cc src/system/collectTargets.cc src/system/clean.cc src/system/check.cc src/system/changeTo.cc src/system/buildAll.cc src/system/build.cc src/system/batchCompile.cc src/system/addArguments.cc src/system/aapForAll.cc src/system/aapFor.cc src/string/toUpper.cc src/string/replace.cc src/globallocks/statics.cc src/globals/statics.cc src/globals/indexoperator.cc src/globals/globals.cc src/globals/getInstance.cc src/globals/destroy.cc src/fileSystem/touch.cc src/fileSystem/rmIfExists.cc src/fileSystem/rmDirectoryIfExists.cc src/fileSystem/rename.cc src/fileSystem/recursiveGlobDirectoriesInto.cc src/fileSystem/newer.cc src/fileSystem/modTime.cc src/fileSystem/isReadable.cc src/fileSystem/isDirectory.cc src/fileSystem/globSourceFilesInto.cc src/fileSystem/globInto.cc src/fileSystem/globFilesInto.cc src/fileSystem/globDirectoriesInto.cc src/fileSystem/fileName.cc src/fileSystem/fileExists.cc src/fileSystem/ensureDirectory.cc src/fileSystem/directoryName.cc src/fileSystem/cwd.cc src/fileSystem/cleanPath.cc src/fileSystem/baseName.cc src/fileSystem/absolutePath.cc src/problem/problem.cc src/resolver/statics.cc src/resolver/resolver.cc src/resolver/resolveInto.cc src/resolver/resolve.cc src/resolver/loadIfExists.cc src/resolver/getInstance.cc src/resolver/expand.cc src/resolver/destroy.cc src/compiler/statics.cc src/compiler/splitInto.cc src/compiler/precompileCommand.cc src/compiler/precompile.cc src/compiler/operator_add.cc src/compiler/linkCommand.cc src/compiler/link.cc src/compiler/libCommand.cc src/compiler/lib.cc src/compiler/countFirstLinkerArguments.cc src/compiler/compileCommand.cc src/compiler/compile.cc src/compiler/cls.cc src/compiler/ar.cc src/compiler/addObject.cc src/compiler/addArgument.cc src/sources/statics.cc src/sources/sources.cc src/sources/reloadStaleSources.cc src/sources/indexoperator.cc src/sources/getInstance.cc src/sources/erase.cc src/sources/destroy.cc src/source/upToDate.cc src/source/stale.cc src/source/source.cc src/source/setType.cc src/source/scan.cc src/source/reload.cc src/source/producesOutput.cc src/source/outputFilename.cc src/source/markAsDone.cc src/source/isObjectTarget.cc src/source/isLocalHeader.cc src/source/isLibTarget.cc src/source/isInternalHeader.cc src/source/isHeader.cc src/source/isBinTarget.cc src/source/hasSourceExtension.cc src/source/genDeps.cc src/source/directory.cc src/source/directDeps.cc src/source/dependencies.cc src/source/changed.cc src/source/buildObjectTarget.cc src/source/buildHeader.cc src/source/buildBinTarget.cc src/source/build.cc src/source/basenameWithoutExtension.cc src/sourceScanner/storeLocal.cc src/sourceScanner/storeIgnore.cc src/sourceScanner/storeGlobal.cc src/sourceScanner/sourceScanner.cc src/sourceScanner/includes.cc src/sourceScanner/hasMainFunction.cc src/sourceScanner/hasDefine.cc src/arguments/values.cc src/arguments/value.cc src/arguments/statics.cc src/arguments/outputOptions.cc src/arguments/initialize.cc src/arguments/getInstance.cc src/arguments/flagged.cc src/arguments/destroy.cc src/arguments/clear.cc src/arguments/arguments.cc ${FLEX_SourceScanner_OUTPUTS}) install(TARGETS ccbuild DESTINATION bin) install(FILES doc/ccbuild/ccbuild.1 DESTINATION share/man/man1) ccbuild-2.0.9/COPYING000066400000000000000000000431101402074776400141740ustar00rootroot00000000000000 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. 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.) 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. 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. 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 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. Copyright (C) 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. , 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. ccbuild-2.0.9/ChangeLog000066400000000000000000000377621402074776400147330ustar00rootroot000000000000002.0.9: - Refresh build dependencies and upgrade to C++17 2.0.8: - Use cmake to generate flex scanner 2.0.7: - Bugfix: bobcat interface changes #28 - Change build system to cmake only 2.0.3: - Bugfix: multiple variable shadow problems resolved 2.0.2: - Bugfix: fix configure build problem with newest bobcat library headers - Bugfix: lock PREC output 2.0.1: - Bugfix: file path handling of files with multiple "../" elements was wrong. 2.0.0: - Multi-threading support using OpenMP (try -j 5) - Sub-process invocation using bobcat::Process (libbobcat 2.0+ required) - Header file lines in ccResolutions do not need to contain spaces anymore - Build last modified file first - Use gnutls-openssl library for MD5 instead of libgcrypt - Use a single top-level "o" directory, instead of a per directory option - Use of intermediate archive is nolonger experimental - libboost is now required for build, currently headers only - The "deps" command is now influenced by --verbose - Dropped the "tree" command. If you need is, try "check" or open an issue - The output of the "deps" command is now: 1st line: local headers (|head -n1) 2nd line: local source (|head -n2|tail -n1) 3rd line: global headers (|tail -n1) - Local resolution file load list is now: ./ccResolutions[.USERNAME,.HOSTNAME,.KERNEL_NAME,.MACHINE,] - New feature: --batch Compile a batch of files with one g++ call before any other compilation. This effectively disables any multi-threading, but may speed things up. The exact behavior of this option may change in the future. - Behaviour change: icmake The icmake command now lists the new CLASSES format and will leave out any classes already mentioned unless --verbose is flagged. - New homepage location, moved from sourceforge to github. 1.5.7: - Mac OSX patches by sent in by Michiel Holtkamp - Flex detection in autotools configure stage - Added --nowarn to suppress warnings about unknown includes 1.5.6: - Fix MD5 sum bug, created with moving to libgcrypt - Moved doc/debiandoc to doc/ccbuild - Added NODEBUG to debug.hh and the configure script 1.5.5: - Move to libgcrypt for the MD5 implementation to allow ccbuild to be packaged - Remove automate.cache from distribution source package - Bashisms removed from tools/*.sh 1.5.4: - Closed ~/.ccbuild/ccResolutions~/ loading problem - Autotools installation script added - Relink every target after the first link is needed closes bug 1424010 1.5.3: - Faster distclean - Remove o/*.rpo files in distclean - cleanPath bug fixed, eliminating bugs in find "../../" headers. 1.5.2: - Break loop when q is given. - Archive only when you have multiple objects - Archiving between compile and link failed on me. So moved it to an experimental option. 1.5.1: - Archive before link, this produces smaller binaries. - Debug information nolonger shows. - Start of --xml output support, implemented for check. - Small documentation changes. 1.5.0: - Better system() call return status handling - --append now also works for the lib command - Clean all works on both binary and non binary targets (for libraries) - Code cleanup - Dropped the --realman option in favour of cleaner code. - Without sources, the ccbuild will now do nothing - Behaviour change: loop now requests a _return_ before continuing looping. Although this is less of a loop, it removes the problems arising from editing a file while g++ is running and still keeps you from rewritten the commandline arguments and rescanning unchanged files. - Memory leaks plugged for: Globals, MD5, Arguments. - Possible bugfix: local directory to root translation? 1.4.2: - Strip command in install.sh changed, closes bug 1328023. 1.4.1: - Bugfix: moved linker flags to behind the objects in accordance with ( http://www.network-theory.co.uk/docs/gccintro/gccintro_18.html ) 1.4.0: - The option -V has been added in support of --version. - The --pversion has been added as the only way to enter the library version. - The library command takes only a source as a possible argument, no version. ! Bahaviour change: the lib command nolonger takes a version argument. ! Bahaviour change: if no binary target is found, build is chained to lib. - Documented the use of -(*)threads under caveats. - New "make help" possible. - Usage manual update. - Full movement to new homepage 1.3.3: - Added clean rule to the Makefile - Moved homepage reference to a variable - Hopefully removed the yylex.cc file before distribution - Bugfix: Makefile output wasn't set next to the source. 1.3.2: - Bugfix: Back to the old Make rules, from back in 0.9.6 (where the main target only depends on the directories.) - Added package.sh script, to clean and update before packaging. - Moved Make and A-A-P files to top directory - Optimization set to 2. - Bugfix in distclean where not all .gch files where removed. - Experimental "lib" command 1.3.1: - Bugfix: linking wasn't done when the main program changed. 1.3.0: ! Complete rewrite of MD5 sums system - ccResolutions.d files are loaded alphabatically - Added the md5 command, to generate a list of MD5 sums - Rewritten the options class - Doxygen mainpage updated 1.2.0: ! Bugfix: -C now works before default argument loading (ccResolutions should be in the directory pointed to by -C). ! Behaviour change: ccbuild will now ignore all include statements with a single space after the "#" character. - deps commands shows a line with ignored headers in the center. - dot command in verbose mode shows the ignored headers collected in a box. - Bugfix: the examples were not quoted correctly in the manual page. - In verbose mode, ignored headers are mentioned on the stderr. ! Bugfix: found binary targets in subdirectories are nolonger followed. - A-A-P rule rewrite with more variables and seperation. 1.1.0: - Bugfix: first file in aap rule wasn't quoted. - Added the --version commandline option. - A-A-P rules now include "INCLUDE", "DEFINE", "LIBS" and "conf". - Bugfix in MD5 hash storing (Not all were always generated and stored). ! Allot of bugfixes regarding MD5 hashes. - Nolonger show MD5 as TESTING in help (although it might still be :-S). - Check command with verbose now shows filetype ccbuild thinks it is. - Dot command with verbose will show all tree targets. - Bugfix: clean command now removes md5 files. - Removed nolonger working icmake buildscript 1.0.1: ! Bugfix: Ignore multiple arguments for compiler/linker. 1.0.0: ! Added aap command for a-a-p file generation. - MD5 sums are now stored seperately (o/filename.md5). - Warning when expansion results in an empty string. - Complete rewrite of the Compilers argument parser. - Doxygen documentation for all members. - Changed the update checking system (better md5 support). - Code cleanup. ! "--add" renamed to "--args". - Better long argument parsing warnings. - In makefiles, objects depend on their ownd output directory. ! Added a-a-p script, so installation is may now be cd src; aap install 0.9.6: - Added support for ".CPP" as a source extension. ! Added -L to isLinkerArgument, was missing! - Bahaviour change: --recursive-include now also adds -I to the commands. - Behaviour change: exec-on-fail/pass work only on PRE and CC commands. - Documentation update. - icmake slave mode never outputs the local path "." - If a command fails, the MD5Hash is removed from memory. - Cleaner exits, which means better/worse MD5Hash storing, this option still needs more testing. v0.9.5: - Bugfix: -C argument sometimes got an extra space because of an error in Arguments class. - Removed all rule for single source makefile generations. - Added flex generation fule to default install makefile. ! Added MD5 hashing support, as a TESTING feature. - Added removal of o/md5usms files in makefile. v0.9.0: - Behaviour change: deps now outputs: local include \n\n global includes This will make it scriptable using `ccbuild deps |[head|tail] -n1` ! Bugfix: wrong shell expansion caused a segfault. (C functions...) ! Bugfix: Resolution was only done on update? ! Bugfix: command argument in loop created segfault. - Added --nodefargs option, to stop default arguments. - Added --nodefres option, to stop default resolutions. - Behaviour change: -I is automatically passed on to g++ - Behaviour change: In brute mode, rm output files on failure. v0.8.0: - Cancel brute mode when g++ returns 2. - Dropped a few TODO's. - Makefile with support for all header precompilation. ! Bugfix: "Unable to resolve:" message was broken showing pointers. ! Bugfix: resolving all showed the same global multiple times - Added the recursive-include option. ! Bugfix: clean didn't remove the binary target object file. v0.7.0: - All precompiled headers are removed when using no precompilation this is needed because forgetting the -p option will make g++ use old precompiled headers which can give really weird errors. ! Bugfix: last, instead of first, resolution rule was used. - Additional arguments read from ccResolutions' first line if this starts with "#&". - Source tree change in loop forces reload of everything and removes objects of binary targets. - Loop option will only work in combination with build command. - _DebugLevel macro now also outputs "D" - Internal header precompilation in Makefile. - Added a distclean rule in Makefile. - Bugfix: .PHONY for all rule. - Better memory cleanup on exit. v0.6.0: - Added the -I option to add local search paths - Made the resolver faster (by chaching expand calls) and more memory efficient using pointers. - Added a tool script to list all headers for a package and create a resolution file. See tools/genPkgconfigList.sh ! Bugfix: distclean nolonger calls cleanAll. So now distclean is truly source independent. - Code cleanup using STL set container. - Speed-up for resolution and global header listing (GO pointers!) (which should also encompass a mem usage cut) - Added an experimental --loop option. - Added the resolve command. v0.5.0: ! Bugfix: lexer rules for includes didn't allow comments after includes ! Bugfix: headers don't have to end in .hh or any other header extension. Redefined isHeader. This means that sources are identified by extension and headers are now anything which isn't a source. - Transition from "make" utility to "build" utility. ! Bugfix: Argument parser could cause an abort. - Rewrite of build, check, makefile, icmake and dot commands. - Code cleaup using by adding UpToDate function - Support for first "not by me" projects! ! Bugfix: Include scanning error handling (and detection) was broken. v0.4.0: - Code cleanup: foreach to _foreach, debugLevel.. to _debugLevel... ! Bugfix: "[DONE]" message on stderr instead of stdout. - Added options: real-man, highlight, clearpc, append, exec-on-pass, exec-on-fail. - Repeated options are supported (Arguments class hack). - Added command "check" to check the up to date status of sourcefiles. - Added command "icmake" to act as an icmake slave: output class directories. - New status webpage creation tool, see the tools directory. - Real men can now use: "ccbuild --real-man 2>/dev/null" (Also see: Real Man's Compiler Collection on Freshmeat) v0.3.5: - Added support for ".H" as header extension. - Added the -C option, which works just like the make -C to change directory before anything else. - Added the "brute" option. To make ccbuild ignore compiler errors. - Added option to precompile all headers, not just internal headers. I noticed that precompiler headers is only faster when you don't use internal headers at all, otherwise it's not that handy. ! Behaviour change: precompile before any normal compilation. (due to flattend build algorithm) - Small speed-up (in isReadable code). - The distclean command nolonger uses clean, so it should work without a working source tree again (which is the reason it's there). v0.3.0: ! Bugfix: Internal headers where dependent on .cc files. This made the ccbuild want to precompile internal headers to often. ! Bugfix: Loading of ccResolutions.d files might have been broken. - Removed "#define" rule from sourcescanner, g++ should be able to do this at the moment. However we might need it in the future. - Cleaner class has removed in favour of a flat cleaning algorithm. - Link phase has been seperated from binaryTarget compilation. - Precompilation is no longer testing. However the implementation will probably be changed in some future release (see TODO). - Compiler has a cleaner and more "const" interface. - Added a small installation script to make up for not having autotools files. v0.2.1: - Added all ANSI C++ header files to static ignore list. (Resolver.cc) - Removed default path searches. Now, ccbuild needs a ccResolutions file to be build with ccbuild. It made me notice, and remove, a superflourish include statement in expand.cc already, so it's a good thing ;-) ! Wrong line number in resolution errors fixed. - Load all ~/.ccbuild/ccResolutions.d/* files into resolver. - Added a default ccResolutions.d in the tools directory, containing a list of known standard unix headers. - Added the --compiler option to change de base command of the compiler. ! Precompilation is now testing code! You need g++ 3.4 or up though, so try using: ccbuild -p --compiler g++-3.4 v0.2.0: - Moved back to "g++ -Wall -g" as default command. ! Fixed loading of ~/.ccbuild/ccResolutions, which was broken. - Always say something. ccbuild should now always output something. - All not-linker options are now compiler options. Which _should_ mean more or even all options are interpreted correctly. - Split testtree from distribution and added some libglademm examples to it. ! Added evaluation of ccResolution lines, meaning you can now use: gtkmm.h `/usr/bin/pkg-config --cflags --libs gtkmm-2.0` v0.1.1: - Not empty leftover arguments after parsing from the resolution file are mentioned. - Code clean-up. Should make building just a few microseconds faster. ! Handle the -Wl,... option which was wrongly interpeted as a compile-time option. - Experimental internalHeader precompilation support. Still gives warnings and I still have to run a few benchmarks on it. (see the tools/benchmark script) v0.1.0: - Moved to "g++ -Wall -ggdb" instead of "g++ -Wall -g" as default command. - Centralized globSourceFiles function, to support all source types (".cc", ".cpp" etc.). ! Fixed a bug in building single files (dependencies were not generated). - Argument parser in addArgument function of compiler. No Bash evaluation yet but. using the output from "pkg-config --cflags" in your ccResolution file shouldn't be a problem. - Added the 'distclean' command, which empties and removes all 'o' directories. - Added a few variables to the generated Makefile. - Changed the interface of the Compiler and Cleaner classes (see rmCompileOptions). - ccResolutions files now may have extra spaces and must have one tab to seperate the values. Also comment lines are possible (start with "#"). - Added a new example to the testtree showing the use of something that came out of pkg-config. Added using the following command: echo -e gtkmm.h "\t\t" `pkg-config gtkmm-2.4 --cflags --libs` >> ccResolutions This should, if you have gtkmm-2.4 development files, allow gtkmmbase.cc to build. v0.0.2: - Fixed header file dependencie in Makefile. - Error message added when a local include isn't found/loadable. - Default compiler command is set to "g++ -Wall -g". - Behavior change: when you add an option (using --add) the defaults are removed. - Unknown commands are mentioned. - Arguments class now has a const interface for flag and argument testing!. - Solved a few //TODO's. - Support for ".cpp" extension. v0.0.1.1: Emergency repair release... ! Directory dependencie of object target rules in Makefile broke it. making make think it always needed to update. - Some documentation changes. - Makefile contains correct version in the ccbuild banner. - All rule for single bintarget Makefiles. v0.0.1: Initial release! ccbuild-2.0.9/Doxyfile000066400000000000000000001202151402074776400146510ustar00rootroot00000000000000# Doxyfile 1.4.1 PROJECT_NAME = ccbuild PROJECT_NUMBER = v2.0.7-dirty OUTPUT_DIRECTORY = doc CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English USE_WINDOWS_ENCODING = NO BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ABBREVIATE_BRIEF = ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = YES STRIP_FROM_PATH = STRIP_FROM_INC_PATH = src SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO DETAILS_AT_TOP = NO INHERIT_DOCS = YES DISTRIBUTE_GROUP_DOC = NO TAB_SIZE = 8 ALIASES = OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_JAVA = NO SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = YES # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. SHOW_DIRECTORIES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from the # version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the progam writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = src src/ccbuild.cc # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm FILE_PATTERNS = *.hh # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = src/MD5Info/MD5Hash/md5-cc # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = YES # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. EXCLUDE_PATTERNS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = YES # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_PREDEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_WIDTH = 1024 # The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_HEIGHT = 1024 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that a graph may be further truncated if the graph's # image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH # and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), # the graph is not depth-constrained. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, which results in a white background. # Warning: Depending on the platform used, enabling this option may lead to # badly anti-aliased labels on the edges of a graph (i.e. they become hard to # read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO ccbuild-2.0.9/INSTALL.md000066400000000000000000000026701402074776400145770ustar00rootroot00000000000000As far as I know, ccbuild will not correctly function on anything else apart from plain, vanilla, Linux. However, please consider giving it a try on any system you can find and report any problems online at https://github.com/bneijt/ccbuild/issues Shortcut: `cmake . && make install` Shortcut for other prefix: `cmake . && make DESTDIR=/tmp/prefix install` There is only one binary, so installation should be easy... 1) Install the dependences: libbobcat 2.0 or higher (correct API of Process class) libgomp 1.0+ (OpenMP) libgnutls (for MD5 algorithm) libboost 1.37 or higher. Boost circular buffer is available since 1.35, but 1.35 seems to give build problems. flex 2.5.31 or newer (for the source scanner) 2) If you have absolutly no rights on the system, add a writable (for example ${HOME}/bin) to your path and run "sh localinstall.sh". This will use the first writeable PATH path as binary directory and install the configuration files to your home directory. Don't forget to awnser "yes" to the final do-you-really-want-this question. If you have some rights on the system and have cmake installed: cmake . make sudo make install 3) For the user of ccbuild, it might be nice to add the standard Unix headers as empty resolutions by copying the tools/ccResolutions.d directory to ~/.ccbuild (this is not automatically done by any of the install scripts). ccbuild-2.0.9/MD5SUMS000066400000000000000000000253541402074776400141730ustar00rootroot00000000000000f1cbc85bea3f70d88362d7e7989a6074 src/ccbuild.cc bad9bd0cafa0b1552f03b4ec3799783c src/misc/debug.hh 1eb06a3c7cd7be60632055d44f2dbd5b src/MD5Info/MD5Info.hh ca475bbd58f6c3096f945ccb5f307ec0 src/MD5Info/statics.cc 1aa3a0f0ddfc2c30d8d754da153efa45 src/MD5Info/MD5Info.ih 6c8662c8d1d75633db009bea901eb21d src/MD5Info/save.cc e7c16abc6d375d57fcc37c4ad26bdffd src/MD5Info/old.cc 9c61452501a27486e7a6a4980e57f699 src/MD5Info/load.cc e62e068190c0bb8bafad9766a51f0af8 src/MD5Info/hashFilenameFor.cc dbc3bc50365748c58966356a74404b9f src/MD5Info/getInstance.cc 25545ba799fc2e82700a2a27d69fd02c src/MD5Info/destroy.cc 4ce3f3ff3ce515edb639a70f3543f969 src/MD5Info/contentHash.cc 8f956c434ecafcd6d150b2de46ca43db src/MD5Info/MD5Info.cc 1a067f7e20797c5aef214410c75d5fdd src/misc/foreach.hh bc9756d0a4cd6612e5d631a346da1cad src/options/options.hh e77724708343904f6b556e2236cd8e0b src/options/statics.cc ce89c4b489094be4b160c6c8a9e4d348 src/options/options.ih 4f59235af3d706eb788a8803689231e3 src/openmp/scopedLock/scopedLock.hh 247614c2fde0cd71cd17be63dfa1f912 src/openmp/lock/lock.hh e4d58a54b1f20a28a6cf92e4f1d1d919 src/system/system.hh 559e4a02724a0c6e8bcbec4950a53cef src/system/username.cc 85e4d9a1f4cdf08937ec7904c16ca8f5 src/system/system.ih cfd0b439dd5b1bd7ce0fb235628ce203 src/system/uname.cc daa382bb5d172778b781d76cac1c6530 src/system/trimmed.cc 2c0bd5ee05c1333156639a1b632b0a76 src/system/trim.cc e2881d28af33cb2c5d7ebab639867cbb src/system/system.cc e95c7e83a1febc484095460026c66579 src/system/statics.cc 1cda3cc84c91ba757074ce0949447511 src/system/sleep.cc a5657ecb4ab3e0cb6009a9deded5d59c src/system/resolveTest.cc 5b3810b3ae044db68122bc8e417c4dba src/system/projectName.cc 7e5049ba5ead1d774cf056f16a4b1f29 src/system/parseArguments.cc 837f60bb758d5712528dedbde8bd83c0 src/system/mkdtemp.cc e6a20f6c03b325d4e50798a5bb1ebb39 src/system/md5.cc 423958de81ef135d4bfeabe2be1fc20f src/system/makefileForAll.cc 78e61e88e045ef53c9581199885bb901 src/system/makefileFor.cc 5cbe0a8b8dfca8737d80592eac151ec3 src/system/localSourcesInto.cc b23acf5b769cab0296f2040b73c5f223 src/system/lib.cc 383d4935d5eaf142d5e62609424a3343 src/system/inspect.cc bc4575ce620de7a210b3d56f664aa98c src/system/icmake.cc 27d11e24593d82f065859b9788e2bec7 src/system/exit.cc 5aced9790aecea17a993ca0d37e29ce0 src/system/dotgraphForAll.cc 412bae78ba236854a14b5cbf9ebf4b41 src/system/dotgraphFor.cc df45ad3d380c99e66e6823da6f802b05 src/system/distclean.cc 70e73052c192f5951e2494eb5af20e87 src/system/destroy.cc a9d2c49cb25b7d0f4fdb519dbecf0746 src/system/depsFor.cc e439f47f5861b31a9507314fb73ccc5b src/system/collectTargets.cc c2f16b259e004dbf03be0f0582b28a7f src/system/clean.cc f5edc34f66e095cd07ce43bc3fb9117c src/system/check.cc 8dd4265e57cccca8cab18ec98d880671 src/system/changeTo.cc 5a3d6c9ea047164cfb4a78a5823ecf40 src/system/buildAll.cc d290d37b8ec60263a3f88c7ac9fd4166 src/system/build.cc 04faba0ec8c959a9cc4d8a0124e4eb50 src/system/batchCompile.cc 03cd3ce187432d2d7717b6b482f2f493 src/system/addArguments.cc ac32c3800c90be06b63b98bc11250578 src/system/aapForAll.cc c3dd4230e2b1c3d4a6559abdccdc6c2b src/system/aapFor.cc f15d50cfc906257c7a3a9fbb2d8a418c src/posix/wordexp.h 710c91e39031e38f079aa96ffbf9d754 src/with/with.hh 6c2c80f0a8d98c0e4bfe0c7aae41456e src/string/string.hh 116a910c8c4f3b17d52a394bd86e6074 src/string/toUpper.cc e8a86890ed8771c431e445980a675f32 src/string/string.ih f7b66b7df9a03f9254d9fc0ed323f616 src/string/replace.cc 95f0d82dfa9b8c5c7c7c974f412720f8 src/globallocks/globallocks.hh 6b5dd123dc03dd04ddafd9db8f0ce674 src/globallocks/statics.cc 8701b145d42d710cee980800e545ac0c src/globallocks/globallocks.ih 9756d984833bf6c0172ec70b159762c0 src/globals/globals.hh 947ae607e88de22545c0380ddb5bd487 src/globals/statics.cc 2c685035cc4f864d29d3ffd8c7715f71 src/globals/globals.ih 9b49311679adfc55cac6f99e7ce56606 src/globals/indexoperator.cc 44dd218bad6288439a8d5072f4170a28 src/globals/globals.cc 5ae08430dbe943e6fdb6ca7fabc481c5 src/globals/getInstance.cc ca004eb5484f2c82b0f71a4ab1ebf219 src/globals/destroy.cc 481557d1e916109926de405793b44099 src/fileSystem/fileSystem.hh 0a0def8c487933a94d1d2ce68367a3b3 src/fileSystem/touch.cc 3e90537f883973248f8fa1f501ba50f0 src/fileSystem/fileSystem.ih 18ef36225ed842899eff7ef9db6da158 src/fileSystem/rmIfExists.cc 94b0b7b6a86507404eda68ccb01e7125 src/fileSystem/rmDirectoryIfExists.cc f657627447ca395d8f9384a8704e54a6 src/fileSystem/rename.cc 635f248f3639eea649b98a3fc78ee015 src/fileSystem/recursiveGlobDirectoriesInto.cc 73d25fc79aa6404442ad6ca7873509c9 src/fileSystem/newer.cc ff97562394ea7325e5726630b14a008e src/fileSystem/modTime.cc bedb729f3924d5b1e7af9aee298138ff src/fileSystem/isReadable.cc 917e9d0e23f22df8a39223cecf56079a src/fileSystem/isDirectory.cc 5194a9bbd525726860ba103a4348d067 src/fileSystem/globSourceFilesInto.cc aae51ffa312bd8d20c2d9f49b99fd410 src/fileSystem/globInto.cc cb4f8bd78f3c8fef2b7a71e0f8a12e17 src/fileSystem/globFilesInto.cc 10025e1ad260eb42f8c8e3054d905872 src/fileSystem/globDirectoriesInto.cc b1fc4bca17297178c730393a36f6bcf2 src/fileSystem/fileName.cc 57d592e8acbc78d4a6f075706adeb4e1 src/fileSystem/fileExists.cc 7de99cb67c1e527515f76af14512cf05 src/fileSystem/ensureDirectory.cc af53b3b2dd794c292675ee83258913a0 src/fileSystem/directoryName.cc 6ce60ed712ccad60bd910bd28f260645 src/fileSystem/cwd.cc 28108a8e6a45157fa02a7bb41dac5cfa src/fileSystem/cleanPath.cc 7f232e37aff9639525f5599740af69ac src/fileSystem/baseName.cc 150e156b7021b9849d563210ef7f5a43 src/fileSystem/absolutePath.cc 49e82a507fe6bacf35f56d27f070e9d4 src/problem/problem.hh 4cb839a6a2e20f43096fa520c6f2f77a src/problem/problem.cc 8ef300c8f27dd67e7973769e38628a5c src/problem/problem.ih e2e687f0975413aed601c0db8aad1b7f src/resolver/resolver.hh 6b8b2e3c7168f4e87fae3be896ef995b src/resolver/statics.cc c3f156e8a231b2b3050d7664d4967eb3 src/resolver/resolver.ih 6000a6aea4caca6ae1091f89e0ab6363 src/resolver/resolver.cc 64d5b38d24a7ace09b3a6bedb794b37d src/resolver/resolveInto.cc 1a10cf005a95c35e864ef06447aa9980 src/resolver/resolve.cc d096845661a86dc043d8c9bcd2b8c3c8 src/resolver/loadIfExists.cc fd95e7e2a53b1b23c867060d2ac8224a src/resolver/getInstance.cc 6988aff4fa3fb61e2f204a9943748184 src/resolver/expand.cc c4270a38a1f62b708c1f5064cf6ed848 src/resolver/destroy.cc 8523d07f5d77c1c5819b711e84c655b6 src/compiler/compiler.hh 785b33c46269d2a49cdcd24ac10acaf6 src/compiler/statics.cc c8e55f1bd214d445afd8516b5160e2e8 src/compiler/compiler.ih 3f859f006ae8b0835c4d45c3814a62e1 src/compiler/splitInto.cc ecdf2e31e74ef448b76c297a8571fd19 src/compiler/precompileCommand.cc b3025e64538700310b8a633ba2de7dc1 src/compiler/precompile.cc 5e0335b242ab8f7c57ef2c1b85417aea src/compiler/operator_add.cc d023d810b371eda6a14fee209e637d74 src/compiler/linkCommand.cc 2a405b4644f955e8d76db56424a2ba84 src/compiler/link.cc 6fa0f65baac2cce7b2a3b6e2ace447b7 src/compiler/libCommand.cc 66fe78596249451efc3d9dd1dcbfbd3b src/compiler/lib.cc a0ee5b96502c1201b28417bf967db171 src/compiler/countFirstLinkerArguments.cc 3045eabe1cbe9cd661b8cfb2ec8e918c src/compiler/compileCommand.cc 33334a3413ce1d88c875bb3d7d8ee05f src/compiler/compile.cc 94f60a260f2573c156d22edfbe926e99 src/compiler/cls.cc 260e5ccff300eb35031d44fc1a3c4724 src/compiler/ar.cc cbcfbb769b16ab3ce6e500a1f80f84d6 src/compiler/addObject.cc 8e1fed3b013c160b179b7e5605df50e3 src/compiler/addArgument.cc ded02db27879081f31e517ec89c534c7 src/sources/sources.hh 963589b58b2708e7fbc425cd83c81654 src/sources/statics.cc 9c51cf66d64142534dcac8cb0d438bbb src/sources/sources.ih 36684d05d545144757b824fb3ed9997a src/sources/sources.cc 4ee7a655de9917b97edc494208a52130 src/sources/reloadStaleSources.cc a4e315cdbe730a4c1a474ca342defd24 src/sources/indexoperator.cc 00ce055a004a91e98827090113d1cf1a src/sources/getInstance.cc 43eaf01ddd34db5944e0a18e05292ccb src/sources/erase.cc 24e13377c6cb15fda07fe374d35977a9 src/sources/destroy.cc 3bde57962a33ca09480fdc2cb747c507 src/source/source.hh c80ce0d4bbc2ef2c2b7e786baeea8bc6 src/source/upToDate.cc 1145569c57544065de0cff245011d9c6 src/source/source.ih 1fb812d3ec03ecf83abe2f167eb802e7 src/source/stale.cc 6e6788fbafb59db9d32c72b3c7a5713c src/source/source.cc 8e7bc7e4fbe5020673be14e1cd136b44 src/source/setType.cc cafdb113a084b16f39a036041bc1af65 src/source/scan.cc 6a21dd0bb39fc082bd4930982cde44d7 src/source/reload.cc 044c9671b4da212935d89d9f058c4264 src/source/producesOutput.cc 3d953f826b2305d4efc105e723cdc983 src/source/outputFilename.cc 75bc9ddc123ff60a74e3e0d78ccebce0 src/source/markAsDone.cc 7fc9af55b84c6200658f8e96aa0ff3b6 src/source/isObjectTarget.cc 9e2dbc16c222da82d8d48d724820f50a src/source/isLocalHeader.cc 7833172576a732245bf12fbc60c45501 src/source/isLibTarget.cc ae96d64b7b5ca36929fabb2ca1659a59 src/source/isInternalHeader.cc d6346d3598a6d869538dc2be698434c8 src/source/isHeader.cc 36848699700bad42304d62460398dec3 src/source/isBinTarget.cc 39d36edc641bfb8d87806f18375aa9a6 src/source/hasSourceExtension.cc 246fc4554b5598790703fe5966eac9a2 src/source/genDeps.cc 728f68d29948717d0d6540be44f413e4 src/source/directory.cc 18156193febf69bda1816f24007989e3 src/source/directDeps.cc 0401cf74a090825a601a8b5d5a8f4b82 src/source/dependencies.cc b51b137d5cd935cd5df490df562fb26b src/source/changed.cc 02dd8f7b5623a283a51a94e706f09f83 src/source/buildObjectTarget.cc eae91308448aabadbc9db0dc816b7e2e src/source/buildHeader.cc d6fd001913c07aaab91b447b1b167851 src/source/buildBinTarget.cc 8994f13bacbd519506e6e50be7e51a3d src/source/build.cc b4d699f462393b82d275abb44319868d src/source/basenameWithoutExtension.cc 2ea67ca2c0fd04a9e3f15230d347ab0f src/sourceScanner/sourceScanner.hh 30c5fe4bf636a3e4eb735b5297b28f52 src/sourceScanner/storeLocal.cc 63da7e83c158b6f438ede45ff06201b0 src/sourceScanner/sourceScanner.ih 4bc2d81bddb4c3177cd97aad4d3cab55 src/sourceScanner/storeIgnore.cc 9e9eab44cb9222de403a996ec3c5d228 src/sourceScanner/storeGlobal.cc d733e91250a3b934c4c994040d02228c src/sourceScanner/sourceScanner.cc 73630ca0e94e2513cdb83c71517bfe69 src/sourceScanner/includes.cc 3483405cf6855c00ae6ce027147de51a src/sourceScanner/hasMainFunction.cc b72f2bbec099824487a3d1950984d869 src/sourceScanner/hasDefine.cc 03299e5f1330144933d7c84b6a428f0d src/sourceScanner/lexer.h c86cfea71fd58f96fe9d01a1aa01ab7f src/arguments/arguments.hh b27e4bff072912270c1eecdd60d6fb97 src/arguments/values.cc eace8dff91459b3a6074ccc32bd213fe src/arguments/arguments.ih 8d37c42acad2509e7b398077de799c04 src/arguments/value.cc 71a22be4f9bd9fa99f78112b22c42cdc src/arguments/statics.cc 70c3d0a71adcafd14e7358c4b711ec9c src/arguments/outputOptions.cc e7052d51a574b41da8347f4733433988 src/arguments/initialize.cc 3e44e6377379b965028e83ae94fe1eb2 src/arguments/getInstance.cc fec66eff88ea4fe4d33cd7f9f577fe68 src/arguments/flagged.cc 863c40291a7b47b137a52de534eaf068 src/arguments/destroy.cc e662f212e0d434264f29c54bf462e9ba src/arguments/clear.cc 866ba645854eaf9b669c02f62cf0061a src/arguments/arguments.cc ccbuild-2.0.9/NEWS000066400000000000000000000004341402074776400136420ustar00rootroot00000000000000All news can be found at: https://github.com/bneijt/ccbuild The last NEWS file content was part of the ccbuild-1.3.3 release. News about the package content can be found in the ChangeLog file. However I couldn't remove this historical news: == May 16 2005 First release!! ccbuild-2.0.9/README.md000066400000000000000000000062471402074776400144320ustar00rootroot00000000000000ccbuild: A strict developer's build utility =========================================== by A. Bram Neijt See [INSTALL](INSTALL) for installation instructions. Thank you for downloading `ccbuild`! Documentation ------------- All documentation can be found in the doc directory. If you want to hack ccbuild, don't forget to run `doxygen` first. You can also use the online versions of these documents via the homepage, most easily found using [https://github.com/bneijt/ccbuild](https://github.com/bneijt/ccbuild) Program usage ------------- The program is meant to be run in the same directory as your main program resides. For ccbuild self, this is the src directory. The default behaviour of ccbuild is to find any sourcefile containing an `int main` function and start compiling it. If the manual is not installed, use: `man ./doc/debiandoc/ccbuild.1` see `ccbuild -h` for an overview of the possible options. Directories ----------- ./src The main source tree of ccbuild ./doc Documentation ./tools Currently contains only a one-liner to run dot on .dot files. ./test A collection of class testing programs, not really usefull. Examples of use --------------- * Compile for debugging and development: `ccbuild` * When recompiling for benchmark (force recompile, use `-O3`): `ccbuild -f --args -O3` * Generate a `Makefile` for a friend developer, who hasn't got `ccbuild`: `ccbuild makefile > Makefile` * Look at the dependencies for you program(s): `ccbuild deps` * Graph the dependencies: `ccbuild dot; dotty *.dot` * Clean up the generated `.o` files for all local programs: `ccbuild clean` * Remove all `.o` files and `.gch` files, before making a backup or release: `ccbuild distclean` DON'T DO THIS WHEN USING CCBUILD -------------------------------- These are very obvious, but just to overcome any problems that might occur. The following is a list of things you shouldn't do when using ccbuild: * Place important documents or sources in the directory called `o`. This directory will be removed without warning when calling `ccbuild distclean`. * Don't mix extensions for files with the same basename. So don't place a file called "main.cc" in the same directory as "main.cpp" because the object files in the `o` directory won't be seperated. * Don't expect any warrenty of any kind (read the license). Hacking the code, possible start-up problems -------------------------------------------- `ccbuild` development requires `ccbuild` to generate basic build files for `autotools`. For source releases this has been done using `bootstrap`. If you do not have a `ccbuild` release working yet, you can use make -f Makefile.ccbuild src/ccbuild to build ccbuild using a generated Makefile. Another option is using `cmake` which is used in the [Travis-CI build](https://travis-ci.org/bneijt/ccbuild). * Flex scanner may need to be generated, use: rm src/sourceScanner/yylex.cc; make -f Makefile.human src/sourceScanner/yylex.cc Use this if the compiler complains about something with `SourceScanner` * If the compiler complains about `FFB::Process` constructor called incorrectly, make sure you have `libbobcat 2.02.03` or higher. ccbuild-2.0.9/TODO000066400000000000000000000011361402074776400136330ustar00rootroot00000000000000 The features that may set of a new release and things to look out for: - Describe transition paths to various install/distribution systems (autotools, icmake, aap etc) in documentation - Write documentation on the ordering of library linking arguments. Showing that global header usage influences this and that it's a real problem with a solution in ccResolutions (force sequence by placing both libraries in both header resolution lines). - Take a look at source-header separation issue for library creation. Also see the list of inline TODO's generated by "sh tools/todo.sh" ccbuild-2.0.9/doc/000077500000000000000000000000001402074776400137075ustar00rootroot00000000000000ccbuild-2.0.9/doc/ccbuild/000077500000000000000000000000001402074776400153145ustar00rootroot00000000000000ccbuild-2.0.9/doc/ccbuild/Makefile000066400000000000000000000007771402074776400167670ustar00rootroot00000000000000.PHONY: all all: ccbuild.1 ccbuildman.html #TODO Add ccbuild.pdf and ccbuild.html back to the list ccbuild.1: ccbuild.1.md pandoc -s -t man $< > $@ ccbuildman.html: ccbuild.1.md pandoc -s -t html $< > $@ ccbuild.pdf: ccbuild.dvi dvipdf $< ccbuild.dvi: ccbuild.sgml debiandoc2dvi $< ccbuild.html: ccbuild.sgml debiandoc2html $< clean: rm -f ccbuild.1 ccbuildman.html ccbuild.log ccbuild.tex-in ccbuild.toc ccbuild.aux missfont.log ccbuild.tex #rm -f ccbuild.pdf ccbuild.dvi #rm -rf ccbuild.html ccbuild-2.0.9/doc/ccbuild/ccbuild.1000066400000000000000000000322141402074776400170050ustar00rootroot00000000000000.\" Automatically generated by Pandoc 2.11.3 .\" .TH "ccbuild" "1" "August 8, 2014" "General Commands Manual" "" .hy .SH NAME .PP ccbuild \[em] Strict C++ developer\[cq]s build utility .SH SYNOPSIS .PP \f[B]ccbuild\f[R] options [command] .SH DESCRIPTION .PP \f[B]ccbuild\f[R] is a build utility that will read C++ source. It collects all source surrounding your local includes and links these to your main program. Global include statements (#include ) are used to make sure the compiler gets the\[ga] right arguments. The link between com\[hy] piler arguments and these global includes is made using configuration files. These files contain lines with a global header file name and the extra arguments the compiler needs to find and use this file. The file name and arguments are separated by tab character(s) or a space. ccbuild reads these configuration files in order. Only the first men\[hy] tion of a global header file in these files is used. Usually only \f[B]./ccResolutions\f[R] is used, but there are more possibilities. See the sec\[hy] tion FILES for more information. .PP \f[B]ccbuild\f[R] will follow any local include (#include \[lq]something.hh\[rq]) to try to find more source code to compile. To keep \f[B]ccbuild\f[R] from following up on an include statement, separate the #-sign and the include statement by a single space (\[lq]# include\[rq]). .SH COMMANDS .TP build [filename.cc] Build everything or the given source. .TP lib [filename.cc] Collect all objects into an archive. If a version is given, using \[en]pversion, then a shared library is also build with symbolic links. This currently forces the -fPIC argument addition. The name of your library is given the name of the current directory or it\[cq]s parent when the current directory is called src. .RS .PP Example: create an empty .cc file which simply includes all the local libraries, run ccbuild \[en]pversion 0.0.1 lib that\[hy] file.cc .RE .TP clean [filename.cc] Clean everything or the given source. .TP distclean Recursively remove all \[lq]o\[rq] directories after removing all .md5 and .o files therein. And removes all .gch files. .TP deps [filename.cc] List all files this source depends on. It lists three lines separated by empty lines. The first contains the local dependencies, the second the ignored headers (for the file) and the last contains all global includes needed. .TP dot [filename.cc] Generate dot graph files for sources on the stdout. If no source file name is given, then for all binary targets in the local directory a .dot file will be created. If the \[en]verbose flag is used the dot graph will also contain all object file names and their dependencies and lists of ignored headers. Objects will be coloured light grey, binary targets light blue, ignored headers by a red line. .TP makefile [filename.cc] Generate a Makefile on stdout. If no file name is given, an all rule will be generated. Otherwise only the rules for the given file are generated. .TP aap [filename.cc] Generate an A-A-P file on stdout. If the file name is not given, an \[lq]all\[rq] rule will be added and all local binary tar\[hy] gets will be listed. .TP check [filename.cc] Display source status and file name on the stdout. Status and source path are separated with a tab character. Status is either \[lq]old\[rq] or \[lq]ok\[rq]. When the \[en]verbose flag is used, another tab separated column will be inserted containing a two letter file type ccbuild identifies it as. This file type is \[lq]bt\[rq], \[lq]ot\[rq], \[lq]ih\[rq] or \[lq]hh\[rq] for binary target, object target, internal header and header respectively. .TP icmake [filename.cc] icmake slave mode. This will output the used directories with one directory per line. If a CLASSES file already exists, it will only output the class directories not mentioned in the CLASSES file. If \[en]verbose is given, all classes will be listed. The output will not contain directories with only header files. Updating the CLASSES is typically done by run\[hy] ning: ccbuild icmake >> CLASSES .TP resolve [filename.cc] Print all unresolved globals onto the stdout followed by a tab character. These can be appended to the ccResolutions file using: ccbuild resolve >> ccResolutions . .TP md5 [filename.cc] MD5 sum all sources needed to compile all binary targets, or the given source on stdout. .SH OPTIONS .PP Options are used to change the behaviour of the commands. Some options are useless for some commands. .TP -f \[en]force-update Update everything by labelling everything as old. .TP -h \[en]help Get a list of options and commands. .TP \[en]gnutouch Touch files part of the GNU software standard. They will be touched in ../ except when there is a directory called src in the current directory, then the current directory will be used. This will touch AUTHORS, NEWS, README, INSTALL, COPYING, TODO and ChangeLog. .TP -s \[en]no-act Simulate, don\[cq]t really execute any writing commands. .TP \[en]compiler cmd Set the compiler command. The default is \[lq]g++\[rq]. .TP -a \[en]args argument Set these default compiler arguments, removing the standard default arguments (\[lq]-Wall -g\[rq]). Multiple uses of this option are concate\[hy] nated with spaces. .TP -C path Change directory before anything else. .TP -p \[en]precompile-ih Pre-compile only internal headers. This requires g++ version 3.4 up. .TP \[en]precompile-all Pre-compile both internal headers and normal headers. This requires g++ version 3.4 up. When you use internal headers, this will only slow you down. However, when you don\[cq]t use internal headers, this pre-compilation is all you\[cq]ve got. .TP \[en]brute Continue on compiler errors. .TP \[en]md5 Use MD5 hashes to check for file changes. The hashes are store in \[lq]o/filename.md5\[rq] for every file. These sums are only stored after a clean exit from ccbuild (last line showing \[lq][WR] MD5 data\[rq]) or a successful compilation. .TP -I path Add this path to the local include search path of ccbuild and the compiler (which will receive the same argument). .TP \[en]recursive-include path This is just like -I, but for the given path and every non-empty directory with a name other then \[lq]o\[rq]. Make sure you do not come to depend on this behaviour, that would be bad practice. .TP -l \[en]highlight Highlight the output of the compiler using a red terminal colour. .TP \[en]xof \[en]exec-on-fail command Execute this command when the command (pre)compilation returns any\[hy] thing but 0. The first argument given to the command will be rela\[hy] tive path to the file the command was executed on (which is either a C++ source or header). If you don\[cq]t want to use the file name, you can append an echo command like \[lq]sleep 2; echo\[rq]. .TP \[en]xop \[en]exec-on-pass cmd This is the same as \[en]exec-on-fail, except it only works when the command returns 0. The first argument given to the command will be the relative path to the file the command was executed on. .TP \[en]clearpc Clear the screen just before executing the command (clear per com\[hy] mand). .TP \[en]append cmd Append this to every command. This can be used to redirect output or set up pipes for compiler output. .TP \[en]loop Loop the system with one second intervals. This only works for the build command at the moment. All sources who are touched will be reloaded. If a file is removed, the whole source tree is reloaded. .TP \[en]nodefargs Do not read the first line of ./ccResolutions for extra arguments. .TP \[en]nodefres Do not load any ccResolutions files outside of ./ccResolutions. This can be used to create a monolithic ccResolutions file or dis\[hy] cover your project\[cq]s dependencies with the resolve command. .TP \[en]addres filename Load the given resolution file before any other. .TP \[en]pversion version Set the program version you are working on to version. This is cur\[hy] rently only used for the library command. When defined, the library command can make a shared object (.so) and symbolic links by using the version number. It should not contain any file system special characters like slashes. .TP \[en]ar Archive the objects before linking. This should reduce the binary size because it leaves out unused objects. .TP \[en]verbose Show commands and produce more output for dot and check commands. .TP -V \[en]version Output version number on stdout and copyright/license on stderr. .TP \[en]xml Output in XML where supported. Currently this is only the check command. .TP \[en]nowarn Leave out most warnings. .TP \[en]batch Compile a batch of files with one g++ call before any other compi\[hy] lation. This effectively disables any multi-threading, but may speed things up for larger collections of small files. This process involves creating a temporary directory in /tmp/ccbuild_batch.XXXX. The exact behaviour of this option may change in the future based on performance results and user experience. .TP -j number_threads Set the maximum number of threads used during build. Only available when OpenMP is enabled. .SH RESOLUTION CONFIGURATION .PP The ccResolutions file links global headers to compiler arguments. Every line should be either empty, start with a comment character \[lq]#\[rq] or contain a con\[hy] figuration line. A configuration line contains the name of the global header, followed by one or more tab characters and then the additional argu\[hy] ments needed when a source depends on this global header. The arguments are POSIX shell expanded. .PP If the first line of the ccResolutions file starts with \[lq]#&\[rq], the rest of this line is shell expanded and used and appended to the argument list of \f[I]ccbuild\f[R]. .SH EXAMPLES .PP Examples of program use. .TP ccbuild resolve >> ccResolutions Add any of the unknown global headers to the ccResolutions file. You can also use \[en]nowarn to keep ccbuild quiet, but you will have to think twice if you get compilation errors. .TP ccbuild \[en]brute Get back to development after a distclean. This will update as much objects as will compile. Which will allow you to focus on the errors in the next ccbuild call. .TP ccbuild -p \[en]compiler `g++-3.4' \[en]args -Wall \[en]args `-Wextra -ansi' Precompile internal headers using g++-3.4 and highlight all com\[hy] piler output (-l). Also give all compiler commands the parameters \[lq]-Wall -Wextra -ansi\[rq]. .TP ccbuild -f \[en]args -O3 Recompiling your project for benchmarking tests. Forces the update of all code (-f) and sets the compiler argument to -O3. .TP ccbuild \[en]verbose dot; dotty *.dot Graph the dependencies for all programs with colours. Then view these using dotty. This can help you to discover irregular depen\[hy] dencies and what test programs use. .TP ccbuild \[en]xof `gedit' Try to compile the program and open the first file that does not compile correctly. Open all error producing sources in gedit. Very useful for when you change the interface of a class. .TP ccbuild \[en]compiler distcc -j 20 Use 20 distcc compilers to compile the project. .SH FILES .PP Configuration files used by ccbuild .TP \&./ccResolutions[.USERNAME,.HOSTNAME,.KERNEL_NAME,.MACHINE,] Local configuration which is project specific. It will load the first existing file of: ./ccResolutions.USERNAME, \&./ccResolu\[hy] tions.HOSTNAME, ./ccResolutions.KERNEL_NAME, \&./ccResolu\[hy] tions.MACHINE, ./ccResolutions. Hostname, kernel name and machine can be found with uname -nsm. .TP \[ti]/.ccbuild/ccResolutions Global configuration file. .TP \[ti]/.ccbuild/ccResolutions.d The resolution configuration directory. All files in this directory are considered configuration files. .SH CAVEATS .PP Do not place any file into o directories, these will be removed when using the distclean command. Also don\[cq]t use files with the same basename, but different C++ extensions, this will give problems with the objects created (for example \[lq]add.cc\[rq] and \[lq]add.cpp\[rq] in the same directory). .PP Currently there is no way to allow one object file to effect the command-line parameters of another. This means that if all objects need a flag, you must use the \[en]args argument and cannot use a global header resolution line. Exam\[hy] ples of these flags that need to be defined everywhere are -pthreads, -mthreads and -threads. Please read the g++ manual for more information on usage of flags. .PP ccbuild seems to be incompatible with flex 2.5.4. That version of flex places an int main function in the resulting scanner and there doesn\[cq]t seem to be a way to stop it from mentioning it. The result is that ccbuild will think that the generated scanner is a test program for your class and won\[cq]t link it into the main program. A solution is to move to a newer version of flex or find a way to remove the int main function from the resulting scanner file. .SH REPORTING BUGS .PP Report any issue with ccbuild at: https://github.com/bneijt/ccbuild .SH RESTRICTIONS .PP ccbuild will not follow or act on any include statements with a single space between the #-sign and the include. So all include statements starting with \[lq]# include\[rq] will be ignored, all other combinations will be acted on. This is a feature, not a bug. In verbose mode (\[en]verbose) these are mentioned as warnings. .SH SEE ALSO .PP \f[C]pkg-config\f[R](1), \f[C]dotty\f[R](1), \f[C]make\f[R](1), \f[C]icmake\f[R](1), \f[C]g++\f[R](1), \f[C]aap\f[R](1), \f[C]svn\f[R](1) .SH AUTHORS A. Bram Neijt . ccbuild-2.0.9/doc/ccbuild/ccbuild.1.md000066400000000000000000000322741402074776400174120ustar00rootroot00000000000000% ccbuild(1) General Commands Manual % A. Bram Neijt % August 8, 2014 # NAME ccbuild — Strict C++ developer's build utility # SYNOPSIS **ccbuild** [options] [command] # DESCRIPTION **ccbuild** is a build utility that will read C++ source. It collects all source surrounding your local includes and links these to your main program. Global include statements (#include ) are used to make sure the compiler gets the` right arguments. The link between com‐ piler arguments and these global includes is made using configuration files. These files contain lines with a global header file name and the extra arguments the compiler needs to find and use this file. The file name and arguments are separated by tab character(s) or a space. ccbuild reads these configuration files in order. Only the first men‐ tion of a global header file in these files is used. Usually only **./ccResolutions** is used, but there are more possibilities. See the sec‐ tion FILES for more information. **ccbuild** will follow any local include (#include "something.hh") to try to find more source code to compile. To keep **ccbuild** from following up on an include statement, separate the #-sign and the include statement by a single space ("# include"). # COMMANDS build [filename.cc] : Build everything or the given source. lib [filename.cc] : Collect all objects into an archive. If a version is given, using --pversion, then a shared library is also build with symbolic links. This currently forces the -fPIC argument addition. The name of your library is given the name of the current directory or it's parent when the current directory is called src. Example: create an empty .cc file which simply includes all the local libraries, run ccbuild --pversion 0.0.1 lib that‐ file.cc clean [filename.cc] : Clean everything or the given source. distclean : Recursively remove all "o" directories after removing all .md5 and .o files therein. And removes all .gch files. deps [filename.cc] : List all files this source depends on. It lists three lines separated by empty lines. The first contains the local dependencies, the second the ignored headers (for the file) and the last contains all global includes needed. dot [filename.cc] : Generate dot graph files for sources on the stdout. If no source file name is given, then for all binary targets in the local directory a .dot file will be created. If the --verbose flag is used the dot graph will also contain all object file names and their dependencies and lists of ignored headers. Objects will be coloured light grey, binary targets light blue, ignored headers by a red line. makefile [filename.cc] : Generate a Makefile on stdout. If no file name is given, an all rule will be generated. Otherwise only the rules for the given file are generated. aap [filename.cc] : Generate an A-A-P file on stdout. If the file name is not given, an "all" rule will be added and all local binary tar‐ gets will be listed. check [filename.cc] : Display source status and file name on the stdout. Status and source path are separated with a tab character. Status is either "old" or "ok". When the --verbose flag is used, another tab separated column will be inserted containing a two letter file type ccbuild identifies it as. This file type is "bt", "ot", "ih" or "hh" for binary target, object target, internal header and header respectively. icmake [filename.cc] : icmake slave mode. This will output the used directories with one directory per line. If a CLASSES file already exists, it will only output the class directories not mentioned in the CLASSES file. If --verbose is given, all classes will be listed. The output will not contain directories with only header files. Updating the CLASSES is typically done by run‐ ning: ccbuild icmake >> CLASSES resolve [filename.cc] : Print all unresolved globals onto the stdout followed by a tab character. These can be appended to the ccResolutions file using: ccbuild resolve >> ccResolutions . md5 [filename.cc] : MD5 sum all sources needed to compile all binary targets, or the given source on stdout. # OPTIONS Options are used to change the behaviour of the commands. Some options are useless for some commands. -f --force-update : Update everything by labelling everything as old. -h --help : Get a list of options and commands. --gnutouch : Touch files part of the GNU software standard. They will be touched in ../ except when there is a directory called src in the current directory, then the current directory will be used. This will touch AUTHORS, NEWS, README, INSTALL, COPYING, TODO and ChangeLog. -s --no-act : Simulate, don't really execute any writing commands. --compiler cmd : Set the compiler command. The default is "g++". -a --args argument : Set these default compiler arguments, removing the standard default arguments ("-Wall -g"). Multiple uses of this option are concate‐ nated with spaces. -C path : Change directory before anything else. -p --precompile-ih : Pre-compile only internal headers. This requires g++ version 3.4 up. --precompile-all : Pre-compile both internal headers and normal headers. This requires g++ version 3.4 up. When you use internal headers, this will only slow you down. However, when you don't use internal headers, this pre-compilation is all you've got. --brute : Continue on compiler errors. --md5 : Use MD5 hashes to check for file changes. The hashes are store in "o/filename.md5" for every file. These sums are only stored after a clean exit from ccbuild (last line showing "[WR] MD5 data") or a successful compilation. -I path : Add this path to the local include search path of ccbuild and the compiler (which will receive the same argument). --recursive-include path : This is just like -I, but for the given path and every non-empty directory with a name other then "o". Make sure you do not come to depend on this behaviour, that would be bad practice. -l --highlight : Highlight the output of the compiler using a red terminal colour. --xof --exec-on-fail command : Execute this command when the command (pre)compilation returns any‐ thing but 0. The first argument given to the command will be rela‐ tive path to the file the command was executed on (which is either a C++ source or header). If you don't want to use the file name, you can append an echo command like "sleep 2; echo". --xop --exec-on-pass cmd : This is the same as --exec-on-fail, except it only works when the command returns 0. The first argument given to the command will be the relative path to the file the command was executed on. --clearpc : Clear the screen just before executing the command (clear per com‐ mand). --append cmd : Append this to every command. This can be used to redirect output or set up pipes for compiler output. --loop : Loop the system with one second intervals. This only works for the build command at the moment. All sources who are touched will be reloaded. If a file is removed, the whole source tree is reloaded. --nodefargs : Do not read the first line of ./ccResolutions for extra arguments. --nodefres : Do not load any ccResolutions files outside of ./ccResolutions. This can be used to create a monolithic ccResolutions file or dis‐ cover your project's dependencies with the resolve command. --addres filename : Load the given resolution file before any other. --pversion version : Set the program version you are working on to version. This is cur‐ rently only used for the library command. When defined, the library command can make a shared object (.so) and symbolic links by using the version number. It should not contain any file system special characters like slashes. --ar : Archive the objects before linking. This should reduce the binary size because it leaves out unused objects. --verbose : Show commands and produce more output for dot and check commands. -V --version : Output version number on stdout and copyright/license on stderr. --xml : Output in XML where supported. Currently this is only the check command. --nowarn : Leave out most warnings. --batch : Compile a batch of files with one g++ call before any other compi‐ lation. This effectively disables any multi-threading, but may speed things up for larger collections of small files. This process involves creating a temporary directory in /tmp/ccbuild_batch.XXXX. The exact behaviour of this option may change in the future based on performance results and user experience. -j number_threads : Set the maximum number of threads used during build. Only available when OpenMP is enabled. # RESOLUTION CONFIGURATION The ccResolutions file links global headers to compiler arguments. Every line should be either empty, start with a comment character "#" or contain a con‐ figuration line. A configuration line contains the name of the global header, followed by one or more tab characters and then the additional argu‐ ments needed when a source depends on this global header. The arguments are POSIX shell expanded. If the first line of the ccResolutions file starts with "#&", the rest of this line is shell expanded and used and appended to the argument list of *ccbuild*. # EXAMPLES Examples of program use. ccbuild resolve >> ccResolutions : Add any of the unknown global headers to the ccResolutions file. You can also use --nowarn to keep ccbuild quiet, but you will have to think twice if you get compilation errors. ccbuild --brute : Get back to development after a distclean. This will update as much objects as will compile. Which will allow you to focus on the errors in the next ccbuild call. ccbuild -p --compiler 'g++-3.4' --args -Wall --args '-Wextra -ansi' : Precompile internal headers using g++-3.4 and highlight all com‐ piler output (-l). Also give all compiler commands the parameters "-Wall -Wextra -ansi". ccbuild -f --args -O3 : Recompiling your project for benchmarking tests. Forces the update of all code (-f) and sets the compiler argument to -O3. ccbuild --verbose dot; dotty *.dot : Graph the dependencies for all programs with colours. Then view these using dotty. This can help you to discover irregular depen‐ dencies and what test programs use. ccbuild --xof 'gedit' : Try to compile the program and open the first file that does not compile correctly. Open all error producing sources in gedit. Very useful for when you change the interface of a class. ccbuild --compiler distcc -j 20 : Use 20 distcc compilers to compile the project. # FILES Configuration files used by ccbuild ./ccResolutions[.USERNAME,.HOSTNAME,.KERNEL_NAME,.MACHINE,] : Local configuration which is project specific. It will load the first existing file of: ./ccResolutions.USERNAME, ./ccResolu‐ tions.HOSTNAME, ./ccResolutions.KERNEL_NAME, ./ccResolu‐ tions.MACHINE, ./ccResolutions. Hostname, kernel name and machine can be found with uname -nsm. ~/.ccbuild/ccResolutions : Global configuration file. ~/.ccbuild/ccResolutions.d : The resolution configuration directory. All files in this directory are considered configuration files. # CAVEATS Do not place any file into o directories, these will be removed when using the distclean command. Also don't use files with the same basename, but different C++ extensions, this will give problems with the objects created (for example "add.cc" and "add.cpp" in the same directory). Currently there is no way to allow one object file to effect the command-line parameters of another. This means that if all objects need a flag, you must use the --args argument and cannot use a global header resolution line. Exam‐ ples of these flags that need to be defined everywhere are -pthreads, -mthreads and -threads. Please read the g++ manual for more information on usage of flags. ccbuild seems to be incompatible with flex 2.5.4. That version of flex places an int main function in the resulting scanner and there doesn't seem to be a way to stop it from mentioning it. The result is that ccbuild will think that the generated scanner is a test program for your class and won't link it into the main program. A solution is to move to a newer version of flex or find a way to remove the int main function from the resulting scanner file. # REPORTING BUGS Report any issue with ccbuild at: https://github.com/bneijt/ccbuild # RESTRICTIONS ccbuild will not follow or act on any include statements with a single space between the #-sign and the include. So all include statements starting with "# include" will be ignored, all other combinations will be acted on. This is a feature, not a bug. In verbose mode (--verbose) these are mentioned as warnings. # SEE ALSO `pkg-config`(1), `dotty`(1), `make`(1), `icmake`(1), `g++`(1), `aap`(1), `svn`(1) ccbuild-2.0.9/doc/ccbuild/ccbuild.html/000077500000000000000000000000001402074776400176645ustar00rootroot00000000000000ccbuild-2.0.9/doc/ccbuild/ccbuild.html/apA.html000066400000000000000000000116241402074776400212570ustar00rootroot00000000000000 ccbuild - A strict developer's build utility - The tools directory


[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ A ] [ B ] [ next ]


ccbuild - A strict developer's build utility
Appendix A - The tools directory


The tools directory contains a few scripts and default files that may come in handy. These are not meant to be used a lot and are mostly there as examples of using ccbuild in combination with other programs. These utilities are often crude and come with NO WARRANTY WHATSOEVER.

Bottom line: read them before you use them and enjoy.


A.1 genPkgconfigList.sh

This script will generate a list of includes that might be part of the given package. The scripts needs to get a valid package name as it's first argument. It will then call pkg-config to get a list of include paths used for the package. All these paths are searched and all files found are linked to the package using pkg-config in a way that is compatible with ccResolutions syntax.

This list will be very large, and it's not, generally, a good idea to add this list to your local ccResolutions file. A better way of using this is by adding the file to your ccResolutions.d directory under the name of the package.

Using this is of course a brute way of handling resolutions, because it's much nicer to only resolve the ones you need.


A.2 ccbuildStatusPage.sh

This is a small ccbuild status page creation script. All command line arguments you give it will be passed to ccbuild directly. It runs "ccbuild check" to check which files are up to date and which are not. Then using AWK it translates this into a small auto-refreshing web page. The web page uses ccbuild.css as it's style sheet.

General usage for a single run is:

         sh ccbuildStatusPage.sh -C "someproject/src"

Then use your favourite browser to open the generated html file: ccbuildstatus.html.

You can easily loop it in the background using:

         while [[ 1 ]];
           do sleep 5;
           nice sh ccbuildStatusPage.sh -C "someproject/src";
         done;

By default the up to date files are not shown by using "display: none" in the ccbuild.css. Remove this line from ccbuild.css to show all up to date files as well.


[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ A ] [ B ] [ next ]


ccbuild - A strict developer's build utility

2.0.6

A. Bram Neijt


ccbuild-2.0.9/doc/ccbuild/ccbuild.html/apB.html000066400000000000000000000111011402074776400212460ustar00rootroot00000000000000 ccbuild - A strict developer's build utility - Categorically sorted command line parameters


[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ A ] [ B ] [ next ]


ccbuild - A strict developer's build utility
Appendix B - Categorically sorted command line parameters


Here is list of the command line parameters divided over categories. If you think you know ccbuild, go down this list. If you don't think a given argument is in the right position, you might need to read up on it. Please refer to the ccbuild manual for a full explanation of these flags and arguments.

Command execution influencing arguments (the actual system call): --compiler, -a, --args, -I, --recursive-include, --xof, --exec-on-fail, --xop, --exec-on-pass, --append and Resolution arguments.

Global header resolution effecting arguments: -C, --nodefres, --addres and --nodefargs (if the default commands contain any of the before mentioned).

Command (build/lib/distclean etc.) effecting arguments: -s, --no-act, -p, --precompile-ih, --precompile-all, --brute, --loop, --verbose.

Arguments that won't, normally, change the resulting binary or output: -f, --force-update, --gnutouch, --md5, --real-man, -l, --highlight, --xof, --exec-on-fail, --xop, --exec-on-pass, --clearpc, --append.

Read only actions are:

  • Anything with -s or --no-act

  • The commands: resolve, md5, deps, dot filename.cc, makefile, aap, check and icmake.


[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ A ] [ B ] [ next ]


ccbuild - A strict developer's build utility

2.0.6

A. Bram Neijt


ccbuild-2.0.9/doc/ccbuild/ccbuild.html/ch1.html000066400000000000000000000120221402074776400212220ustar00rootroot00000000000000 ccbuild - A strict developer's build utility - Introduction


[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ A ] [ B ] [ next ]


ccbuild - A strict developer's build utility
Chapter 1 - Introduction


Programming should not become an administrative task. With most of the tools on the net I found myself either adding file names to scripts (and removing them) or digging deep into the core of some scripting language to try automate my builds. At first I ended up with a clumsy, to say the least, collection of find, grep, sed and bash. Combined they formed a script to generate Makefiles dispatched over multiple directories. The complexity quickly grew out of hand and it left me with a lot of clutter around my source. The second incarnation helped to generate autotools scripts. I had to run ./configure to get the new scripts to generate real Makefiles, followed by make. If you commonly add and remove files, updates are slow.

It was a depressing way to develop, because most additions to the project I made required me to run all those scripts. On top of that, it would take about 30 seconds, or so it felt.

You would say, well why not use an IDE? Well, trouble here was I wanted to split up my code in separate files... a lot of separate files. Not only do I separate my code into directories, I also use seperate files for functions of the same class. No IDE allowed me to do this without the hassle of having to go through a few menus (create file, register it as source, set is as part of the main program, etc.). Those who did, often used autotools in the background and would have to re-autotool on every added file. Frustrated, I almost gave up on my coding ethics and started to do it the way the masses do: 900+ lines of code in a single file, only accessible through a specially equipped text editor or full scale IDE.

The closest thing to perfection out there was icmake. This only requires you to mention the directories you use and will keep your development tree clean, however it had two small drawbacks: you needed to mention your classes and you could not use directories in directories. So, I decided to create a fast and simple program to solve my problem.

Although you have to keep some standards (split source over directories) to get ccbuild to work on your program, I found it almost completely eliminated my interaction with the build system. Better yet, it helps with bootstrapping other build systems.


[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ A ] [ B ] [ next ]


ccbuild - A strict developer's build utility

2.0.6

A. Bram Neijt


ccbuild-2.0.9/doc/ccbuild/ccbuild.html/ch2.html000066400000000000000000000103661402074776400212340ustar00rootroot00000000000000 ccbuild - A strict developer's build utility - How it works


[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ A ] [ B ] [ next ]


ccbuild - A strict developer's build utility
Chapter 2 - How it works


To know how to work with ccbuild is of course the most important thing (if you want to). So here is a quick and simple review of the internals.

We will now consider what happens when ccbuild is called without any arguments.

First ccbuild will find all source files in the current directory (using the list of source extensions to find them.) All these files are scanned which gives an in memory list of include statements and whether it has a main function.

If it has a main function, it is considered a binary target: ccbuild will try to make a program from this.

To find all the object files that need to be linked to the main program, ccbuild will follow all local include statements (warning if any fail). Then it will scan all files in the same directory as the included files. If they are object targets (don't have a int main function) they will be compiled and linked to the main program.

The arguments needed to compile an object are gathered by the global includes. Using the ccResolutions file, for every global include the arguments are added.

The needed linker arguments (which would create the "not linking now" warning) are identified and kept back for later use when the program is actually linked. If anything goes wrong here, please mail me and hack the file src/Compiler/countFirstLinkerArguments.cc for the meantime. This file contains two simple lists for for options with and options without arguments.


[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ A ] [ B ] [ next ]


ccbuild - A strict developer's build utility

2.0.6

A. Bram Neijt


ccbuild-2.0.9/doc/ccbuild/ccbuild.html/ch3.html000066400000000000000000000170061402074776400212330ustar00rootroot00000000000000 ccbuild - A strict developer's build utility - Using ccbuild


[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ A ] [ B ] [ next ]


ccbuild - A strict developer's build utility
Chapter 3 - Using ccbuild


3.1 Organizing your source

ccbuild will read your local includes (#include "something") and compile any source next to it into your program or library. For every class you want to use, make sure you create a separate directory. Every directory contains source files which define the different members of your class.

Because every member of a class has it's own file, each of these files will have an approximately equal header. To keep us from typing "using namespace" and "include <iostream>" for each of these files, a so called internal header file is created. The internal header file is the only file the member implementation include and is identified by the extension .ih.

An example member implementation is given fileSystem/touch.cc:

     #include "fileSystem.ih"
     
     bool FileSystem::touch(std::string const &filename)
     {
       ofstream file(filename.c_str(), ios::app);
       bool succes = file.is_open();
       file.close();
       return succes;
     }

The internal header file, fileSystem/fileSystem.ih:

     #include "fileSystem.hh"
     #include <fstream>
     
     #include "../options/options.hh"
     
     using namespace std;
     using namespace bneijt;

The header file defines the FileSystem class in the bneijt namespace and includes only what is needed for it's declaration.

Splitting the source up like this will get you a lot of files, but will make editing and hacking your code simple. The functions are easy to find, quick to open and easy to grasp. Furthermore, version control software will encounter less collisions and patches will merge more easily on quicker moving code.

The main program is in the root of the source. ccbuild has the following listing:

     ./fileSystem/touch.cc
     ./fileSystem/fileSystem.ih
     ./fileSystem/isDirectory.cc
     ./fileSystem/cleanPath.cc
     ./fileSystem/modTime.cc
     ./fileSystem/fileExists.cc
     ./fileSystem/isReadable.cc
     ./fileSystem/absolutePath.cc
     ./ccResolutions
     ./string/replace.cc
     ./string/test.cc
     ./string/string.ih
     ./string/toUpper.cc
     ./string/string.hh
     ./options/options.hh
     ./options/options.ih
     ./options/statics.cc
     ./ccbuild.cc

The top most file is ccbuild.cc, which contains a special function: int main. ccbuild does not care about the arguments the main function takes, but it does care about it being int main. This is what ccbuild calls a binary target, a file that is the root of a binary.


3.2 Building a program

To build a configured ccbuild compatible source tree, simple run ccbuild in the directory containing the main program. This will compile all programs in the given directory. However, if you only want to compile one given program, issue the command ccbuild build mainsource.cc, where mainsource.cc should be the name of the main source file.

Once the command is issued, ccbuild will start reading includes the source does and gather sources it should compile. Any sources it can find will be compiled and linked to the main program. Once the [LINK] mainsource line get's done, without any errors, your main program will be done and you can start it with ./mainsource.


3.3 Cleaning up

For cleaning your sourcetree, ccbuild offers two commands: clean and distclean. Although they might act almost the same, they are implemented quite different.

The distclean command is totally source independent: it does not scan sources, nor look for them. Distclean simply removes all ccbuild related file in the "o" directory and all ".gch" files everywhere. If the "o" directory is empty after that, the directory is removed as well.

The clean command is much more subtle: it reads the sources and removes any objects part of the current source tree. Because it reads the sources, using clean will only remove those sources part of the given or implied main binary target(s). This command will not remove any directories.

General rule is to use the force command when you want to update everything, use the clean when you want to remove all files for a local binary target (but not any other binary targets in the local directory) and use distclean to remove everything including old objects and pre-compiled headers.


[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ A ] [ B ] [ next ]


ccbuild - A strict developer's build utility

2.0.6

A. Bram Neijt


ccbuild-2.0.9/doc/ccbuild/ccbuild.html/ch4.html000066400000000000000000000151521402074776400212340ustar00rootroot00000000000000 ccbuild - A strict developer's build utility - Moving to ccbuild


[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ A ] [ B ] [ next ]


ccbuild - A strict developer's build utility
Chapter 4 - Moving to ccbuild


To be able to use ccbuild, you as a developer will have to adhere to some strict(er) rules then using something like autotools. Here is a list of things you should keep in mind when moving to ccbuild.


4.1 Strictness to adhere to

  • ccbuild only reads local includes

    When creating your source, make sure that all sources that ccbuild should care about can be found using local includes. This means you should strictly use system wide includes only for actual system wide include files. So any header file which is part or your packages should be included using a local include statement.

  • Preprocessing isn't helping

    To speed up ccbuild, it does not go around looking for system wide headers. This also means that it won't know all the preprocessing directives from these headers. This results in preprocessor excludes of local headers cannot be used. This is no problem if you are compiling for a single platform, but when you need configuration using preprocessor directives, you're going to get into trouble.

    The only way to keep ccbuild from reading these sources is by making sure there is a single space between the # and the include statement. So the include # include "something/hello.hh" will be ignored by ccbuild. To test this, run ccbuild in verbose mode (--verbose) and watch for the warning which state that the file in not included. You can also use the deps command to get a list for all binary targets.


4.2 Setting up your configuration file

To set up your ccResolutions file, it's best to do the following steps:

  1. Check your local includes span over your whole source

    To make sure ccbuild was able to follow your local includes, use the deps command. This will list all the local and global dependencies of a file. You may also use the dot command to get a graphical interpretation of the same information.

    All paths that ccbuild needs to search for local includes should be added to the first line of your ccResolutions file. Using -l in this first line will make ccbuild highlight all compiler output.

         	#& -I../tools -I. -l
    
  1. Add packages to your global ccResolutions

    You can add a package to your global resolution configuration using the genPkgconfigList.sh tool. This will find all files in the include path of a package's include paths and add them to a resolution file. See the Tools section for more information.

  1. Check the global includes are resolved

    To make sure the global includes are resolved, use the resolve command.

         	ccbuild resolve |sort >> ccResolutions
    

    Now all unresolved global headers are listed in your ccResolutions file. When you run ccbuild now, it won't complain about any global includes missing. However, g++ might complain because the needed extra arguments are not in place. You should now add the needed arguments to your ccResolutions file by using, for example, `pkg-config --cflags --libs <packagename>` with the needed package in place.

    If you have a lot of resolution rules in your defaults (~/.ccbuild/), then it might be hard to see what your project actually depends on. Passing ccbuild the option --nodefres will cause it to skip loading these files and will allow you to see which resolutions fail. This might give you some hints on what packages your program depends on.


[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ A ] [ B ] [ next ]


ccbuild - A strict developer's build utility

2.0.6

A. Bram Neijt


ccbuild-2.0.9/doc/ccbuild/ccbuild.html/ch5.html000066400000000000000000000114101402074776400212260ustar00rootroot00000000000000 ccbuild - A strict developer's build utility - Moving from ccbuild


[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ A ] [ B ] [ next ]


ccbuild - A strict developer's build utility
Chapter 5 - Moving from ccbuild


There will be a day you want to move away from ccbuild. When the day comes, you would probably only be able to use ccbuild for it's dependency generation commands.

To make ccbuild useful in these later stages, ccbuild has a few commands to help you cope. Don't forget, you can remove all ccbuild generated files using:

     	ccbuild distclean;
     	rm ./ccResolutions;

The build script generation commands only read source and, should not generate any output.


5.1 General build file generation

ccbuild can generate a number of different files for different build systems. When you call ccbuild with a build generation command without a source file, it will try to create a standalone file for that build system. Which will also contain an all rule.

For most systems however, you don't want the all rule to be defined. So, ccbuild allows you to state which source you want a build file for. This will then generate a build file without the all rule. Then simply include this build file into your main build file and write the all rule yourself.


5.2 Generating A-A-P files

One of the most useful generation features is probably the A-A-P file generation. You can use this by calling ccbuild with the aap command. This will generate an A-A-P file on the stdout.

The most common way of using this aap file is by generating it for a single binary target using:

     	ccbuild aap mainsource.cc > mainsource.aap

Or

     	ccbuild aap src/mainsource.cc > mainsource.aap

Then create a main.aap file with the following line:

     		:include mainsource.aap
     		
     		all : ./mainsource

Or

     		:include mainsource.aap
     		
     		all : ./src/mainsource

Add any recipes needed and then use aap to generate the main program.


[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ A ] [ B ] [ next ]


ccbuild - A strict developer's build utility

2.0.6

A. Bram Neijt


ccbuild-2.0.9/doc/ccbuild/ccbuild.html/ch6.html000066400000000000000000000073471402074776400212450ustar00rootroot00000000000000 ccbuild - A strict developer's build utility - Problem solving with ccbuild


[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ A ] [ B ] [ next ]


ccbuild - A strict developer's build utility
Chapter 6 - Problem solving with ccbuild


This is a collection of possible real usage examples for ccbuild. If you don't want to take the time to read the manual pages, this is a more problem oriented listing of the same.


6.1 You changed a class interface

When you change a class interface, a large collection of your code will probably break down. But which parts? Well, a hint of which files will be affected can be seen using ccbuild check. However, this won't show you whether these sources still compile or not. The only way to test that is by simply running ccbuild.

Solution: Use an editor running in the background (something that returns after using the command). An example is using the gedit command when you already have a window open: new files will be opened in a tab and the gedit command will return immediately. So, using gedit, the easiest way to get an overview of your problems would be: ccbuild --brute --xof "gedit"


[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ A ] [ B ] [ next ]


ccbuild - A strict developer's build utility

2.0.6

A. Bram Neijt


ccbuild-2.0.9/doc/ccbuild/ccbuild.html/index.html000066400000000000000000000121111402074776400216550ustar00rootroot00000000000000 ccbuild - A strict developer's build utility


[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ A ] [ B ] [ next ]


ccbuild - A strict developer's build utility


Abstract

This document is a general usage manual to ccbuild. It will introduce ways of using ccbuild. It will also explain ccbuild's behaviour in more words then the manual does. The newest version of ccbuild can be found at the https://github.com/bneijt/ccbuild


Copyright Notice

Copyright © 2005 A. Bram Neijt

This manual 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 3 of the License, or (at your option) any later version.

It 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 ccbuild. If not, see http://www.gnu.org/licenses/.


Contents


[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ A ] [ B ] [ next ]


ccbuild - A strict developer's build utility

2.0.6

A. Bram Neijt


ccbuild-2.0.9/doc/ccbuild/ccbuild.pdf000066400000000000000000002364721402074776400174320ustar00rootroot00000000000000%PDF-1.4 %쏢 5 0 obj <> stream xWrc7  U&@t3)"3ɨˤ#Zv>HYwgJƅcxhLkt_zyES>n'v:@jU& qj+!jx|pHWv>A3M`c1rW|ý,aa!6FN=t( +#IɇTb}!_rʼn%bY rFq-II̛uɫĢFl4l%XsV"(DJ@ =PM_zє~fmXGyIumr2q0<=˗YmȏNK@ucdfC BsbűVm@!(c]_xڠ.yX%j8ҙ(l yKI+ {np_mb%sP9yM*DTzWٍ55WTԉ &*S^/T-pTZ-ujP-~Z8Qac 8m4?ez{ -<^0\{/ 'eu3y9h5iSW:a̛& 0PzSup2Ňtdnhb cU6޶F-ɻvC3]U;'2ƾH|w87@ϘO˟LehY6Rv¶iVо.8bSv2Z"1G2m kt4FQe+9dn:8j"-Y[ce?S6»6*n)kQ4vab_xSGYG:ѷETTU| ZpZft ,o !q~9z:E kMg\Ooendstream endobj 6 0 obj 1241 endobj 17 0 obj <> stream xX[oT7~_ފx|7}*TJJT!@.EIwϦHxg}K=RӿbU\,|yesad`Y|& /!\^?,~S߯MB+D }Y[A]R;]rA7՞qyKqx[O9NW$zLpadѓ728~>x"(ЍqfI&/AGR%*6ʐ`Ҽ.K|*#b !=Gria(PtĴTكhBq&5j3GlQFnZyF۾)]he:K` V@8MFkt@(kE'Z|5UCލe7 K^CQ6 HW{6;:X;v2KWe srQ0zv+L w tr?wm-:%1k#maXD*Ґa}TUihQN'1 L-qzR87RzuhNYC%tL.0L$zo7D_4=5kƄdvX%rЕĞİp`.KQ#zeCl?ԋ"rаLMG oJ0do* lj?RvQN }DuACMjF0- ZBz],`Z*dޜC㢍)+:DLid2\ئMKL, /ryGقV&JAّ!"B[u^4tu> \M1~~YMٌtrĢ7+^ lZy᮳5*:Lxگm+x!hd)wNx|$i&!H `D7ڗ^ XΓ{٘ʨØ:hXO$&''̘|(>:Bhw]<"󈉑B4xW<'_x7^WXBW 2 qo>8,dd_OyTLdb-}[4nXd [jgD9^AI_Ef> stream xZK7r_1HeG@IDCr̲$)?]X@IvǏr_r#d|ۜ]4rsּlTqS{R3`i{ z)! a7'4ͷAc;n^  cݾA0Ԝ7׍ SB%܉80+$Zm?O:)7m_S4F:kX}# ۋ*e%cG^QN@cGƩ@SQytqXmLP}ŚD `\@С9ƨ3F/VR; u8m$) IQބdF6jԭVuuiuT u{CbʠeM7vYoV`5F &D+֙R @s=ojZIBNZP:Zۿ VT-cѦ`u3Ư2蓛u q2"M֮J q~6E)ia, ."ֶvR{e-n(m,aD`O tS&z'%iw9`1{ \ࢵϜ z NJXPDq/ ippsV*ehn/n bb7Wv|x9w);F ґE(_Қ8J_tQz篍#>S.녝_7ES^!Ħj~;lgYeN(FXʖ3ҕeKq\W,O>F,hҖxK)?PXYnHӺơxAG+YTXX:-iWf:n4LYMtK|= Q: _c9X\ )Z(Vg=y͎`T 5s[ ZsUZ#ݣцИAѣI(X).<A pzXD^[&xp@xtă.wE˩qeyit^6ΫBdZ╛SGjPāg1yZL"MG2h2#8+HOęHG4@\(U{+6i}#yuh*XYѯB$c aݎÐ6 4*ƲVpf< b ҮUD.!' EzH^~v! z4$ _Nna Uד89oClP*n2`d4XrcۨR0IjR/ceu|[U4~OC?h%cendstream endobj 23 0 obj 1806 endobj 29 0 obj <> stream xu?OAw>u(iP81\a ?9endstream endobj 30 0 obj 188 endobj 34 0 obj <> stream x\I9r|_QW*dž o00f|Qqk몒$_=5b`+fkW>\W?_Yu׿~uɥpic.K:ǸR_}ޘ%xjWtWW _ar/>}ŧ%͉p, DxBZJJLrLѳ|6>N΄ӏbͭ u׸-&&,drz8XWlʧ] !s޹s Q|:_?줪F.~VG3n6sq@i:lOB&gL-ա>ó؊P;&vA{w٭Dj[|ٳZrpR9QtbOt|ZnnCu h7 Ȧ AaB%6u=|q zw|Vxo-i^bՏ+!G4dzٽ܄fۇǜ#*aM!f¦1$*OtpEM,6Ә$Lk{Ot ZSH1Mgpޞ3VP5A *1QXfiA. YgKi`q: %BYBQX߂y(aDk*Q5lps֎ 25+ CZMI4"ihD|(2y 8| +w4u+.yowHCJ[T"ɴB3'ېq; '5ge0"AIM"}{dG0{RP4Cv;-!oIJCKcWZz6mleOۖ!?S$.)@j8p_ݗ1yI-,!p|޵%fBg$6tcxz/`.|Ų/+Om-%Bij~(cokPaaj؅.҃v.mN8VWqG {]g{A#h`P׸~/r??~K`]? {f7 J2!q/=s =~{D"8h Ȑ!@Yc7I#@Y -U3RlSS,`Ȭ5"C&O 'k5ov|eЈTNr\DE ~y 8?6mpya0Qㆮ#أ9ݯ[c/!*( 8I<ߐ\4): RSA_rFmU\n'A8nn/;Y~LJzv i^8'fu>vKDݯ뙔I(@17yDs2︳.<G"h tI.k`Aepb-:*:=+iT> hOU@*ϱʸS<*@XBR C=HD0)*{iAK6IwR()aR%IJb"$ֳ!.)A@ 1pelP1ʢq1O*a$j9𫨉>~>Gl=moˋxjW) <޴hMA|An+85p!VpOp#|}~v^&ey-}U>22Y`qZhh"صg0[ ?q5$2lrwFKlx֣D\E[ܜ/YGBA\xXj`<ۼUY91]k@^)bmYgw{\e],?rk ޟgXQֽ2s6j󘚔BBޭ\Z ^6d(CWMLDd'Y&TZIL* ƣz VJ<ڗE0L@5nIsDaW=Ǽ/@3x'.< 68 $k'ڤ@kyDf~^]FQ|86ܪ> ȅNq$/iSvդX ,=" 5CFu<X uuA!܈49Z0R%1ŸiWVs6 P^<3|Y l7;oĖnq[F9"Bްg 㯗>#GFL0UڈliׇQYimFi&F۹؁f=0q[ bJ,ݰFMqshl 8.hʫFv̙5_r Wyh.]k8$rx&Z:$V~WEL"\u2s:6y=[ո ,˗ʹC 7"=绮R=`X㰨ӭ68qZ͠` м3 *Gdu{ZWu >XQ*K`T˝( rf).Os\?!ev߸cxǦqf\Tf%;MOk„{v-6!6`FTᄄ[}!Gw(@'zm'@{L[ĒVb]q)@o``MA@u[҇|x@(e"N,[fqXM|L)`m}+1%Έ3Aj׫`Nvd2 aCYp*%طƲIV8fh{8MNJ7> \fMgmQhܔyp:_}L@Nt(}ȒC}UYc\  B{emv.쩏d[yx)O $˙Mt Eח0A^py龉NtM|8DջHuWJ>txqk;X٦7Џ|L6tQ c}_19Ibls 6Y%pjok;[Fy35k/N[9^pjuZ9TWSP;_x?~wy 1ʋpwo:Hx։uc=0fC@8T㓈xA'?|$ǜ%HQfˤkԜq7FfmiAdB RY&oS츹5 1 _ ? 'hxÀ֪ ]I906z#^@1ixj| 7!vx8jC>Qz|p)V#,Dk~KYCOCmT[6Sp Ɍ)ճv?$B2,4+Ǥf"w!Cwd.re|qYUxlz8 6%2MBXl)箧@Dwǁv)bJ0 .h.ZXtsVLWքMCavzLK{\$FM6 lop>k%/ ?CE^<:S,C'qN=SAh0+mfz\kQB~]Sh-x;$7F`Afxjsr7q)~ Lf}lѸk1 6݇^N{ \jPN ˅.V:6X%ȓQ 8G]Ǝ-;^Yaڍ%UaNB-nP.BK ׿}_ %@ s(/> stream xMP=O1 +2؎ Ȇе$hqRe \ ~Ap[EwΛ5XZ}MkϰLE]V\k<Ű2Xc2Ϝ$>"9Vj4{n7%DV1~a~_SΧV7޻f.fTpQ~:Tvj&okۗgĵe[>s^@@$ȼ uS endstream endobj 40 0 obj 250 endobj 44 0 obj <> stream x[r ~e2wv+N6SYY(D"ߑ|p~=JI 4h~{T>*wxu{Pǫۃ??OogoK}t!>cpn7&sfk4xq`gPEg7ׇ#٣\ qGo/*|yv Ϋ4 OzVF7uvzOϠ5(;=ccޝMq5-(c&e!70MY㍟>t~߭5d?B$T eVLK$6N-:]%=FFb q>xBm8sr (oGb1" "!%SYD|,HkӂR!6PDz(lB@DxJSJz 0i}^/ǑyCӺcҒ̜t3ܮe(;냻:S U!,{a/ypnh6e5\=ŰŰ(C`y:|3M5JMFH{3컫 ?Nh,bdt$T{'S.NU^[ 5A,dzQyij-*u]`=j,y^GA3#h~?{h>ℱ㠥Dq)elž\$&$; *PoI"CiwE\ԨXZq5OTRp Yj8܌@30~Ş_J T`UPV/Al#H>++^Mܘ8flyx/xt51 A 3 |SI;]ayUT@p8AH;[^%wL'{QR}B XpEB'`R1 H8UJBs(u1pFRIo# \迒[+К9(R1|N1@c), $*;_0 ThB]Ⱥ1x+8:R/HQ)&δx R$+A-8~hNl5<)_(pvӉv5,j$ Ѹ1~kDq()GM7!aVNBgq.MK|U p ٺ&#X?j_ҫ; `b?;/@@R0hka3ʸ3‚C  diЈλ>^nnMm 0'ٞ'p~"/jqkvnA]).;=Hr AUQ+]4h֩mBΏPܗ^# A3*rxe1TZ4s 8uap)g҉fM(F҆qJhe-Rݤ^2Π"e0eXkr; pLŻ)W5ꇘ]qyJ?if8{ɿ ɸdvtBzDob3gߝm'zɶ+C.A'XEs럺jOU!n֔M2ﲠvRƤB^&,#loC3KoۦUEژm x{NVlLWͥ3B,KY;!a9>$_9|}xxַLZ/^`gWg0~3&V_ ^ UN6^PַtlG}$JxvN<ޕHdG#HGVvn_R1w4LN5VgJ;t[iQX2N;"c%c)d1U7wqwrΉN3J|1kp3z{ej)&:O"t=Q'n su|W5˹Цoendstream endobj 45 0 obj 3465 endobj 49 0 obj <> stream xM=O1 !k*P*8A[} vxs˜9.KC۰89ln.%iH5ƢZlSxaŤ 9\="ߝӟY^;E0Hsʹ-6inތM$U3g;̣O b.RmP?y$^j.HO@S_jgScR# Nwendstream endobj 50 0 obj 247 endobj 54 0 obj <> stream x\nrUDkIiE6zlɒIn};Y/'M9o>9vW zW'_ݓ{.w?/.v?=pLp/wMcB{pYmrw>;| ~n$;xxA{w ӝgA]0i~78(h*oNo+W}rczo߸mN`ǥG Zz/q)&y>}==w2 LVěحpFᕴcQV[X  6ZO:E^Q_\=\:߸-ք!.~#krG%^6ֹ*&)W6)1} ՘tl{><4ua$L[k ? NVD `[6 BC3ّٜMHḝKۂcl׼X.\ckk8B5&u:h vr1|)rޛyo֎3$S1+3g؟BLj_jy7̕ԂWPv[)8@F< Ȉ{>{:q rM0  @G|YQFQqpp8hp` \ WtFCiklҥPU/ЀQ  sͪNfYsLJ3Qt,;l&V,-ݽZ85mľUa%h<-#vЈuP.9 *NI]d]=*L9XL;G!1]"{6YU0iͲ3AYlw D? :evɵwҘ)tGoi XDWKyx5튀}(K9IH0\"=KIUE@0@QK<@xT6f ds;Y<{DW[pS<#k<Eڛ6QZ!A[~;؎NriA%qDfNL;=ဦUygI/IObMG0(lpi~B}`GDF,"+{b>oBoxϮo$ M}@ʅJ_">ވOME<0`%ˠ` tޘem7$ ʿn{:Aǃ*tpàdᵃlTJ)vs9eJhE;j[%נssF'ls>00YxF%7d#fq 13a}Q[`pw}n)ƊLz^r}nr(Zg-x i4yߡԍYa 4r\6n{Ƅud&fs>85 #0_հ!z7u68.pż\Nz]18os ;q~AiX .⤞,`b.ds7رJgf}zO۬kD04c;C3[)iiyHᔟ mf۫'( RBbm?|(Q C6 6Fz署03T.Rcrx/wb4`O1n]#H~<>7{6>Q@ P B23~q/ef]^s]_-*fh)ƇҜ.fw ̈́ C߇]]&Ei1wɥْU}%~'pe7u>>8!{p~ KOwV+*p!9EgW`P\ 7tqQձ_"H Z/m!r}G_[yvRz<>x^1߲V.HK#- (Iѓ07Ql wƄ657-s>!b;[7]iugc௻s(hB,3.6}s##sAˀi_(`ySb\&ʡk&y0tNp Sq@DY([v) 5hOtנW]4˖Q˓'wG0~Kqse3aVzii-IVr-3yVXCѪM]LUDqbkUz9DƉ^i@$:]u⪨x^9ayȗ5B}*CHS=2_cL"E=RԸ6XʥHLmU> 'rb;.b?%HXb0"^ZU[Y1m]WxW*-XcQx m[2"UY5k Kn9 [QnIs:fB9W31xT 5-E31P< [mp['eˏVq'* !tBwb98Vծ 9!Yi!:tJ_AXuuSxNxXѡ,u+:: JdC'}U*FRKw\ɩdR b&>Z`byF &V)GuEwn^P s Ȋ3IT-˻ӬoEmVRgfal-"kOnHjĬsTjpbo810 ,A YҮ'c_JR|Z& uBcSj/@4hV}(֢9 CNmK4ư4?1ă>d A6YMHmT!ڡE0|znW8p"͂&oɗ?]fߤ;ypQRnV`l>ֵ[^|Z,E|V0j".xd gŗu_ ȝ`u]?ɈYE lNuͫq2F0k5P bYTBsf{v "l^fyng ΩT`iRGTA[OPϺE b ;`zԗ$+>_UMsv>R2~yaHZތO_Gۄ^w?ү%U a? eBbTSwV]mChfO֧ȧU#~h5]_5oZҊZa [Uh$;IۃhkbDQd8/VY?ArHGA׋Wbf߄]?wڢg/6}}|{JܳH7_5%~` (- 'Bx )wo}¡׍5}ȹ0an!)Q ! %_}w,am瀟Yendstream endobj 55 0 obj 4311 endobj 59 0 obj <> stream x\r_UEC6tt@€V;vfeuuҍIlԒeVp,&y,_団ᏯG#><|s4?r)U=N*7G_~r =hٽ:RN{{FkoۻXevVJTY1 w&Mذh4ã^{onh` {P:_`!û)\9L%v` ?~NXv<`ԌדjΥI#6GfG؈OTVZ|&˛nV8uy,+#?Bx"}r욚OF]SuJٲj:WJ}~t_hUooy/'P j:Y ~B%t%xwk:jqhJ-_p.^#oR Qyj/Cx23|˧~ȯys4蚚qFT}"y3@g*gM;NN"pǻ@tH 8-$dvLa.dfYP?g ɻe>1{ 9 2ccHR*֙(Լ/)ieGR=v'ᒹ,`l2T`Ѯ32i1IՌYo|JF[@~<ݛsBL֛틡RlnS.Ms1,a-GR&@g-Mod/D|$X}Py{3vfi'ͤ=P0\1\9+baIHȂAs[4zMaEz`*p;W(@~ dr"hLOГRN*%%-p|kmXJDkdI[Eȝ$Ŏm2#~sx2@Z9 ynjq'5S5C=.r`$UЖCV<}&SHx/7eeݿh Ϟ[U2M-gOKvVNIxL GBPж, ЦUpt^rR=COL:M$Ц_:BXL f䓑Aؙ!5HcPvίb<&\ yGI)]%!-2cŮA@ CQ 'fcqFf}Q:iNQYow4F'z~"o]8\Lbݽ) |iC#5@DVv0Eyg'Qj,?a.)9~ U#uGO>&i !7kܯ+XaRϖj4uf5!`'Y,a{+-K#4rz͆g=햲ոdw\]D[99 7ZѦa\0ۓ՘Ix~,+9Gk bm] e8ka]}$QK(!cmW(SiӚexm8}(e0VϺu(>Lڻd#2 Yp1F p/?B[jv3uaUU[p \,M+>.gߦJX ´|drY%vC[N_-"pl &/\̦u'#^eɇS q?1 `7~\/(Br4S<#,Ӌ:OtX,lLӭLnpm!U=+ Hj~Zԍ=PjYHT6+H08gt14n "nPn0=ހK%~ ϭbv8Э_,Ӱv nS;J {ţ=%U12ռx)-ʆ`Vsv[-$P@N&*5Vpm#%yN,e /Hв 1^ߕ5L5<$  /TJ `{=Y=a>W \uJwPQ>!u{4^"?1Pq8f{.䚴r\a(%ʂٷƄ B_&E ԙ!(nܲjԂ(T̍t}6a;RcFsN dۯP*{Mq)W06 ‹`ܞxa0}YZWv6s)$iaΉ cF`h4 0COo#A*l+f)3WTɇVq"h*U2H~ po9^;%Hy=jeI}LBPG]64A^R9 -:кxqv[@.vߝGR"B ,b UW10GRO8) kmkZ<3H]f`a*b_q=P٪6f -Pq%1&2~ 7+KN1ޮf<<[X2;떑ȂHÒD 081#TFBEkA3~s.0qUV#/<;j/2#907Fc ⇫#h#X(]!*6f *x&.>.*M ]\z"myJʏAR\T]1:!KƄVuETȲD-n_JzXTAϻ5q<4~gmgxz{S6n c$!,e$½wՕx, Ển4^ =A9q0P6¬Ct@`YlUxsB(ƘkuiƷuEgR9T+dI!qgAAJ4]мD5ޚQMTTK N=h(#qa*[1]@$du˒\Ɛh* N9=,-Zii4,ma3Gi0>O?j._CgV-5ڞgKJXޥ.gS7"4m+93uMukE&!{͵Jh*JCښxue. )ݺ򥳰?Av%YM;^Q%;}.jQ %پvPT uDa}|}o4@tV1ndD;?cpԄlѢ3Bk],*aXx*sZ{^T:KPT>57Eyn8*),U7y-,gڔM|5S(gXqe.nL/tk<4^ G8~t{i4"撞1'E[KEQȘ1&'ұvFT}T,jD oʭ]<% e|t槻WerR+hq([eꔕ0qzny|(qi҂̇͠i60Nn W)QIehw+F+c92VDsEB *d> stream x\Y]G8bA'/B$!`UÌz9۝ddPrO/U_ץyu݅|~ Ixͫ>gܢS\>zvևy}T^]|uWb3ZOtلÅ zՅ m67_'.̂OBMKgfBHStYh;|koYI9GϫmX;:y}t%aq x%aj */K啣((S!-(=8mv2:I{IL##U@[TQzrǙ܂VeSw8u0Y2{at6z%..>Ĵ9Zu^&r-jM(wM$~*->pifJ0A(z3)Ϸ}G 1Xjg) (2_n[+ }jM[> &oHCxIvU ^>c5HI9yNTۀ aYҼF" J+>( -R; Pl ċfcxUd&D#GQ<\4#t@[)nQÙ13kJJSZ[C5Q<Ө9T ՠ=Q{/vTG/Ը\˽K:kf S S *P }.&'yQ$?)\nm9IXL˄+S,1uEޟ%~LYM/Ԍm>v_M}7O heb~V?E|*z3).f>rMiROe8=Ϭ<*FwM^:w\4 <Nc|ǧyV,hPU 钉;u.9rA!.92^&e$PN; E;~* \#A -9_y֐,-ՙ]zb` j@nmZ%h${CaEZD\)DLaq7)@JƜ@AhL]oa qk}A4;Vay<hR-ߨLE0U5Păd'ZZ6!bZ`!5x+Qns>BجP8_=4>'j_3 hy1(&MQ)!$SU_a>D(4\Q6," C:Ϋar?wn*(Ͼ+*%U{&tu1gm|IW5>4@Br>`px# 0H f-F"8{hYGl~ho?Њ,%ǘc@,* Y d +e2 7bTu&g9E) bCF("5+JwĒ1  $\V*eVj-,p_gE9` ՖgzEcmٔ%*y  iY\h2Жn,GUIBa{oVaWϐZhS#)Ee/ +`Or0or5=OW'gB*ьwW wfDL;nk)a~k 3j'#Rjs6\R1=y K,NK8(W)ymZȎ|#1=@ۦj5%cqNP{=~~]>f{92S( аة0Mw"ߕ-$́oGe|AvN[Sm?/ATH)]o&J)5$>Ns7.~p".2Tjf4}4pvXc\7F] ̑ !<@m` }X׀WI`sH"W:RT\ߖh{iT,7yM`N`a+@zHE"dm~˯O+J h+ pie%g ۺ{2c >v(e"@ vŠ\rض!4XLFG𫇮5n9pTq=,P5 qpgPޗ/)i=­PYRX255y5{!-!ϡVfcg1M-hjM,ORF'Lݱ#yj B s/iES:ĤqW!R<. $pKBqvql#a&aU_s" LOGh0=ee6Ê8ׁh:=/'H td\xvR>"Aş3`ķiqyNIf(&?޲BR&98[/ ?i_wPb쪨J7/|l^.ueR4} .E(3A_g+tvCi287Rߘ_X뗧~e\gNg3}Pom/--vt[:|T((Am%qVG8}/i/o\? #i7vm#0U5c@6-_BFiR~z5a⾱O:k{T=c(P!Q jzz--3#΅E$o M7^=BO6qf6(F~ARa Zmj|m?sy|zb@w摻sV)NUӁte܇$J[fϿeO} fn-i3lH\ P..|6]ǐTI -;?bx_0 &,xڔqx  Gآ4xl}W{pꜟȝue@mժĨOeX0dbN6ˉ&81BiM9&R,7qztA=oCtKDi9!loX<` rl]|1xg.d!ſB Ջ|ZO1։ǝ5 w$ 7Ր-t .f,gtWN2xHmK(hW Q`endstream endobj 65 0 obj 5209 endobj 69 0 obj <> stream xZYk$?76<;5Y-iVowDFV-c>L*:8"kXQW}wM\_mWj}aˏϻhLp˕kFѤ>]m)KnxFczxKCgmtyRId.X zx895^J2m04:`pOCZyf Zp':+AAD?]5Ms5n{vN{lRE>6un|iaci^yoV߬ܨ+מe+l}%՟_NgُiM}ړSOM)ɵ*tc8gÍ+:rzّchUKiF[}@ڈ?y8cM}?i"SgX|-rtVeᴇ<44'wWa `dM$UJlTt Ta_s8NɕdM-pvI-9Oc";޲5krSL`ULTբ9T)u YtvrZIHoۮre}ۆW|!hK07y#!W3o1!0r!Iz2.Bκnfk*…Gx7!gs3Pao{3(Q9\\].Gm/ʐ r.E/-qpw66S{17(6缮bg;yǛȮ/ъltunmDDR8kY(>Q5&N@M݌G*xglJR#ӎ/`csz\ijCY7u t$GWAnB]o ZT(V*n*4t ;RB0`P0`&0uf Zy3&PH171b9m d$*,ҏMzݤ&=ґAl^I6Ԭ@( Q.lh"R0zǘ nVU:OѢ GX-:eS{zf$|X4謹Û@ԈJPY. #bWV41v>K"j=Ynu5:BP|W$I ۘ|Y&B'$mfzb߁b3ׁo5`o1`PrTsfz4EpK8}#t[:ChzCydcp',aε#.>"A Qxڶ#ez zwdd'1PaS47X~p yS>U3²la;)nS@y|k .-w xuDX3>HI2>)\2i+$%bH~ѳ]ӟ <@'I81{Q(r}|it_غ.&&۴2%7lAP]m41$Zx=r9]O|w(-v5(q.pFfqnZRɚڇ(Q&c4/I,jD3dM=9DH` 8iQٳ.g)U,?בf1eC{\ >UvTr(npNOwwK"[@<;H'uoP+/f۩%C`N?ToV0endstream endobj 70 0 obj 2425 endobj 74 0 obj <> stream x[Yo8bvxzy @C"XAƲi>U,dό[ `vG_}U~YA_ޭVb}e%ӏwrf}vE_ʵap^ q}~y`T1ϫ?_AGە znevՏˋPk%Pavbдߟma{:7R[qsmMn!7lTlvV8H6vzۢŘ/q1 Zeu7m0r,kjޤF+64v0^ذ9-:i`W2Ufj>M͛4מ#홇CЪ6mtpnY8V!IN4 n%*&P$1?xQp-(MH0 F~PBeA_#(4Hħ*`z23VD*6}X([hAaȴq#lqI`WXE+*`P L8Fgܱ-,xnrUZ 4ez{;56(?1Q Fɡ2R0B=`gƳ}dPu` 7FkeOopVrtw)l 3/'3!R[X*l5E"%M&B uyBL(b+v`pW5&y٥GD'tYL0Hʆ5st>@[YxMɀwc̣%;FlH;?ӒTBV&zؖ@;O(#П߁`8+zzE,;쀔M,)aoz󇴴(efU&(3&FpЧHS D+VLS[7Z,&0,&lVUYI|^ >D+ a)<;#c=@ ^&n^w0,"2 )%9:ri#2@0M"DpQ O0uQk-?@JQ?oW^ l >x<޸splO%{K"拸,~vjEu[zهC;os[ȕ40䶹l`xj7F&-ifAl*N#Grؠp釂YJyY fiY0qlc3nޅe6YA_pnL._פKl0Y AJ07 X|.#ngA'~ßhfbIq=& _E "XXMh yZܷ4wUpN- Zʛ`r:9h*%AiL^yh3tXCޔv*y)b"n_ ;9a0FEy\ VA~J*Nyę  RD7O?p:eKS2{{ qgnf oR_mĐ\>C6zhy}$&xRǐOEeV8]2:J ^ҝmvH-moo=-CE)Q$>Moo۫ Y )" C~Q_HI\l:VFZ(C[su`FRSV, ?APF&'nQ2aj# /#a21~:Tbˡ.%*&TC)rP;5o6+8hT̆ Yd:XS c'|@E_?QJ؉$BljJ/@ܘ$04@B S8ٔd_[d A@ճ"UlՆYOā:5;p ϥ9V,{ԏ܊ C-Ƹ g.2JUe x0&ۓ16G=a'|G+whiA>˼s4ZaX`=?R&h7KQ8˷pjwaAS?TeT읛HWgwlV,ﴲm’EINXxYh}>0CM`>K)*˧Rl [>L )KʑZrCt8򅃕cTU:t~< c 'E7XUʥYp~Np쒘AkXP^/`6B m'T]ϫQ'p.Î6,vڕL|u߯8Mej`!ciJl@1MRu7oYis7> stream xUKoA ){^!!8Vq(IM(=:UrB91wN~w.v߹{|=bӿ؁U ~ZX}B~tWlΙYٛkbdc` u.Yje5'ǃaq:<^=' NUieN`YQ)4!~ o֯fҚM2*> stream xZIo% r|/:Uݗ ,!f6&fw$ nV/#+ 0z,"?.{C~񧴿~ܙ/ϑ,}j''>$ǜ)rٟY(E-zow_|o w!؇2ٖ`iy .죏}Q 5M! ]8CV}Z`|whgKomMj0O9Ym ڝL=_]h;M5svLmepG[}7ucꞈ&Rlj?C[ВeIŤc,kp&FУ"l<-eSk+֧4]Zgq >q׹̻=<$ӇQttOGft c=ނ>ƴىn>wDOG&h#-mBK}Jhh\:ĥz%OCR}'WasHOoU״W|hEtGkH\Pλcr, j2:УW>?u*GvΏ:^d"j'5۲p>W-d4Qb&[<ȶhMp>cY6T@[ 4s$En9B4I%#A( 4*#9X%蔚lGUS9@efG1DL1N܉»+{#ĵ6I"qz\6gLJ3k@E6|a)y _TEP;5XR \ա1:]YoWcDTϡyGp`$SPPP꒚Ӓ9nMHLAS-eL/fJ^1uSxIُsJ1%Vm,l,ʪ9X4?M5*A@᩺ )hepV\jdB~]UULhvIrB kRUybT!k̚UIR{V NC@uԷZa#*IkY3"4-kpC[r-Ap$.P6*­(d[ psdw35pO-dL^6h\ (GN}q4$oذĵa9=c?dlhψޟg]YbDݺfV5)e!r,0pQ˸ &-V)U2u[ BNjN Pey$~}򃋱y,u[ f1n@IshڍQQv,Y 6i5Y[uh:fZN(Ԥšj5?R`Fia\+h8N=ewױR<>4GbGHSέf &bgD` 5D,RqvJd^jPP8׉f4vٗ(M>h0$!Uu>]FZµqZxa6ZqodEU *f(q&X AVCGJ|F  XHpR?^ r'T䯝7o 2~/A[Ǒ JEw5+6<PQc\)Py1L9}hT"(@P: kmR/ ,>Er40l3B|E4ܼ]A 1Wjn| ,܃;?ps}#Zڄq1L"I 8?ez*ykQZTAm8zݫ0㋶74WH" [gqڽv㸻޹vׄ@\WЉOdWbe?&WYo׻'endstream endobj 85 0 obj 2600 endobj 89 0 obj <> stream xMQN1 ) BlDZӂvރ[qvC[d2s˜1kܾ%c=ƃ~mU%wavb$K,QEY.pɥ+pʉ"\;,ZѨmg"HrY6d4E NEEVɵnCdf[~srnCeg%6RF8VUa۳0y_$.Rn$y;YZX =w\ cbOTpH^! hg,7~8tn b\_f. _tendstream endobj 90 0 obj 320 endobj 94 0 obj <> stream x\[%7x_13~I!nd!BM&C?vϜ}>n\U{_ś~/o/2xY{Ϩ%://Myi^\Exy%_.xaa/~u^,+mzۓۋOK%G<*,^:K3Ax)C<:Ҥ^k/ӵ:w5:]+) MWGe"}ݛ`L" fL^|.óWy$jkKæ^oS/hUiW/u{dץ?%& NIo@4 =VJ:i/r{hJm:>,3LER:JUi/4a-:+2J=JH7,*rޮOӑlZ-Į_Sc-k֑+GaQ*vDkTI=ieVe!gcYJy(-DX=m[[hEXt=^EyKO_f, X B֊^2'$ޥR;Uy<eQdrA Ctyyٽ) ޳"QV`ҭ&=F "uKI9K\eQ5"]yDN{Meﯤ5^ZD7R"ujg(-`r٬{$wErARXK; _:I uF/<\~+ohbh3H_4mu$Z2sЖ4C@o;toXr/#" 2}D6Z >v]4#T _m{T!`PflLCB z[0OH U YlI\PeO ՕϑYT_D1F/d7e%6JDW"~|hkVD&j/]72yu5ڽ(~F=To' B"/!bdȼG83Haȭ-^`&B3 64,R*? Ў2K4ۆPaFV 0wQM#L*oCg$f 2&^z7bk2󝠠?+Ml:X{%ԚD:1Şrɉ)ƳzǬi¨Dc=E|6B/eYʄֳEFJR0kE  P($fyWNPR3@%ᦄ$.|OpR$:5[#Ea'=Șa1~AJhfyLwpmc-Z,)ݴH)Y*h(XR΋qbC#ݝaF$T]gHlCv z=fȀqKa!UM]dOz/m/gwQ ѼvY 橵NB p\Fp2^$!Ġy\6W^TN $]s\ =GDDeE'z< хKž,"'A9c-˳bb9 &*ZDahtZdKGH7,-"F"Ujֶ/}iDz_80HQvG +V QzƏfI \{ yEP1LWo,WmM_3AMgO9h 2U y_VFug5MA,]!gtVV{ۀnI!Eb(YJ z^4,&*5`c[x PI3GsNǡr6C%:69[hOgC0U="9iGyY,մʹ^kѠg̠I.6 "5ձBѭvR)p!'mCF0NxT=%]EhG%cc-]_Kmj-aAɑjYz})ўכTl{Jϱz[OQxD~xhtyVT,ET fp%3#4NXNGBA2Njy2*$'uRSt_W8g;I*CŹ.4ٕGϬm@uه>ٟ?Fxe|.kOK!{J_AOP5D1%^Jov}zݞhiłivMDĎ7e0;ΠlIeN?s5t/i]An'bd6`%/<\B<\@Znad!Ż:pMr5l(H|-wYʏ@Ʈҟ țNXc îƽm$#1M./o*ΗB۱O?f};QZk3'  ZIõ2W] 4͎6@J# 9,#v٦VͶbFcx9I@ ٣ə{YdANsزOI֐VR_r8sA ϳ*/i OKJlF@q~*sfzl9]G7 m9ќؓcTݧP0#P[:8P:yDXmb4(|VT7-r7A`k7ϱǛ YlLDE1 ?oLG7L;$miV~ AFopaHW׋k~lp>%6{4?V .6;@ZA_>W 0>7{[gaUwǚrt;>YˉoDiǞ`OIX+_eW[>矧}(&2_& CԺ0۶*zH1=%H?}^wSbOVZ}oFśk'(-AaJofbOOȿ3Β?f\BԔِoa ~ \]ҟ} G3Z!zǯؑt1"ىqx2Plk~,ҹ}zaUe_ѿO?QTV883fl^O68!="Xhc/pXwIFfbD덵S>: aw ~)P @jsl&uŌf%.}Q$jm{:n@Zr'5:QSٟQih[g!H+^H E$> stream xMQN1.ˏB! @@ !]"㭏}Px~wѯte9fP%JTϪJmtOp=,Y!ZaR᫣bDBE䄰1ĘPBֆк+J1uY*ZM7FeEVE3?a7` /Y?HXQ:nbo'W, K,1AvMsNBTcspivltZ8'dM%bendstream endobj 100 0 obj 280 endobj 104 0 obj <> stream x[r$=_77E7Ky|ǰIM8u*BLb2Qmf_nOv}_\ߞ7֧Wqvmn ?a\xZtJ5L_ 'MkJ;i{`!F;,oO$4Xi c&6l6z= n[ڞ+ aK5#|ZѿWy]ki,0%ZlX))#N2$mpϰ ]R#W:rh/tӑ.l-$me-1^XE{s+U`4n@J+*m`NM@VNhZw;LI-Ϣ+Kf!"K1rys S2xHzd6 ΰFd޵[XOM*A)p(Z*?FzƹtPxEݑ@S}Js=D#ӺpՍ ֧i8~a}9JF“􃲸KbTM%wo!NޏWpF(< 1J j冼 L}LԋZpN[HR[)!+ %gBJ[n"KE(phrې *&oYU3ϢJF;rN$w)V/z/1%+=D؁naWFdR3㑻z;V6$FY]eVNi9S(h30[ދȤ7yRc'[u-\0#&Ї q |8\nCϴ .+uau>SJ8 j/,5f$1`~~lMT)``%'[qq/治UWvIDxe&T${⨧¨"sqlNK%etUM1iFU`v }N׬sG,e#_Kbdp8t0}   ؘb+ >k|"txMKkzP42XK 6Ҩt+p5hlԄ] !~�cUU&jU'UCKM0!LpՄP#O0. e@R޵zQA1+9N@zt-ՓPJ q<p9f]^S?[ Vtءp!mD]zg$I9eS^g꾧B.>f9RhE~L\Rc^ᭊzEɺr$Z-ݼafNqT5|MDc:UO"9 VQj(WCZWE aow $[U :sM^~k8 􋊺K..3ŽpUFֺ׆_FgUKMDAAcN#<t^u~pD\!A)r fDϊX?KcPg>nA1ߧB:Ά-XIBa$ExXvS#bvu)-{$! CYϸ:!UXGLjiHJ4J3@~1yde~:xSpB\xcDg I?/H(4LS;ӊ2`v@Lِ(ˊrQk(͠ @=dcB!ٛ[GOU7HxТf|>O@3{S{Q4G@ ɳfF:llq#bYԁJڥ 'QBpxn AU6ջ>+Q"Njn[)3%7oqΪlo FE,/E#D9_5jY_"ǿqN}endstream endobj 105 0 obj 3174 endobj 4 0 obj <> /Contents 5 0 R >> endobj 16 0 obj <> /Contents 17 0 R >> endobj 21 0 obj <> /Contents 22 0 R >> endobj 28 0 obj <> /Contents 29 0 R >> endobj 33 0 obj <> /Contents 34 0 R >> endobj 38 0 obj <> /Contents 39 0 R >> endobj 43 0 obj <> /Contents 44 0 R >> endobj 48 0 obj <> /Contents 49 0 R >> endobj 53 0 obj <> /Contents 54 0 R >> endobj 58 0 obj <> /Contents 59 0 R >> endobj 63 0 obj <> /Contents 64 0 R >> endobj 68 0 obj <> /Contents 69 0 R >> endobj 73 0 obj <> /Contents 74 0 R >> endobj 78 0 obj <> /Contents 79 0 R >> endobj 83 0 obj <> /Contents 84 0 R >> endobj 88 0 obj <> /Contents 89 0 R >> endobj 93 0 obj <> /Contents 94 0 R >> endobj 98 0 obj <> /Contents 99 0 R >> endobj 103 0 obj <> /Contents 104 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 4 0 R 16 0 R 21 0 R 28 0 R 33 0 R 38 0 R 43 0 R 48 0 R 53 0 R 58 0 R 63 0 R 68 0 R 73 0 R 78 0 R 83 0 R 88 0 R 93 0 R 98 0 R 103 0 R ] /Count 19 >> endobj 1 0 obj <> endobj 7 0 obj <>endobj 14 0 obj <> endobj 15 0 obj <> endobj 19 0 obj <> endobj 20 0 obj <> endobj 26 0 obj <> endobj 27 0 obj <> endobj 31 0 obj <> endobj 32 0 obj <> endobj 36 0 obj <> endobj 37 0 obj <> endobj 41 0 obj <> endobj 42 0 obj <> endobj 46 0 obj <> endobj 47 0 obj <> endobj 51 0 obj <> endobj 52 0 obj <> endobj 56 0 obj <> endobj 57 0 obj <> endobj 61 0 obj <> endobj 62 0 obj <> endobj 66 0 obj <> endobj 67 0 obj <> endobj 71 0 obj <> endobj 72 0 obj <> endobj 76 0 obj <> endobj 77 0 obj <> endobj 81 0 obj <> endobj 82 0 obj <> endobj 86 0 obj <> endobj 87 0 obj <> endobj 91 0 obj <> endobj 92 0 obj <> endobj 96 0 obj <> endobj 97 0 obj <> endobj 101 0 obj <> endobj 102 0 obj <> endobj 106 0 obj <> endobj 107 0 obj <> endobj 24 0 obj <> endobj 12 0 obj <> endobj 112 0 obj <> endobj 10 0 obj <> endobj 113 0 obj <> endobj 8 0 obj <> endobj 114 0 obj <> endobj 25 0 obj <> endobj 108 0 obj <
>stream xS]LUDVc| !Q B , ewX.,3ә.ۿO +URCP&F}ҚNɐdlP(>oh*!i: 7٤.&1'!u&$XD`0gcF"k1f++͇([>Vˏe6lH<*Ezn"Qe5JQT>U@EP'DTu~^k[6j=:ڦkZqZAE<g; !`EK {j)V2OLj.$20*4.J_܀0X]OҘ;̬9V }OQWxVBZٯ.0c^40*se.܃;K7'7Q3knlU~Z "/:`^-{$ 2ff"+EkO-w[;tsW L4&L+7at18903#O s.gisntD^=Vgp8c-XygXsmq{\cn?ØH]"zٶ4?4ű߲hqn^*{}C}6@t w]<Ӣ2S0'Nz}}!:L V@CjX wG`"PHf;P>ϿSUNMzMyКz_ߵB"y[/zщv`OyMu.]'ywh[ EIdUdv >7oo jA55 66_$'o&?AQ endstream endobj 13 0 obj <> endobj 109 0 obj <
>stream xX XS׶>ɉVi)%q(UkEuFXG$LA$ $H a@vmvunw P~Z{_9޼!,4J<,E:?' ~c000zLJ<؝mL]LAM}A)4y\Z¼y$ْO$˥*y\}ɐ*RId FTJdrT.tʵ+$SV,Y!ME)$ y$D#MVIJd)iŝ$1)ɱr<%Y5CT%9Z$͊*%JiZ\B%r$.-*Y-S$Ez,o.KIVKi)yz MQU1irZ,.:>JUcI Ο3uBJ4i\TZBޗo|@>a>*2- ^CSkO8zF4ߔ i@5nS2dJ_lg"bSJsm{\{ra,_Y͍O-r+o4tC^Xȴ: ("zbDmc5L^5AÑ| Nȕ H]rF+W@/ir'\ 6* H 2 &N0 8fk?n/zt%:>Opյ8RГښmJg+$Om^CO9aΠ|5BRe 6\ v2 M=~ՁYM8]ML{V` xsH<,k[?nWݾODljŚCǍnmBw==)|ZՈolb?NX:{_bzBs=G/xON$Yfq͆Oٟ_]㦈vu.RVއض{eΡINoxN!\n1t+cg ͊WsR58'A^"S18±t"uzQ/.cK& ⎃5mu-p9q! =iC|BUҬ4ĉP|p,kIyvuX{t6jfFl ʸN gp~/b4悑ok/ntz}k0tyFq}N~{yUzڅGL}]uo,+-3K+\DdmJ킏pBƍQDW{fReQ=J!wǰ{u0î%gC z&b5EinljW:4婪*̐/ct ʓFA}{C9 ^%-+VQwgVvG8Հx:<.icxݕW|I+,&(<h}\/8b95l>{(+X/G4NH1=@ b&Q4~oTY H9I.|kQkaϸ N :[Ad)faLWF pI?io.YOC[7_8%gHzq X>FaE150@ߞP+?* ~N NPokqx?XF/>qʐ(B)j%Zȑ= hePyH9=yU8i[e8 RyCu_i5SZQXZwXEUvTTU3nsi5\V$ BGX |f'ߡ gsatI@S 3)cEUI"?'~v %^2$:ܣ݋|ok̅bZJPc<$6xǍ 0 XAu'jߖDA0V0Ȗ-?7+S#b"yRw!ReYI@tX]xR%;@e$7dZoVSY{S~-Ehx_l#LN} e.vM9v]ՓݘYC,͑Y(3Sȸ5\(o8 ???v¸,(=@[C>o0]g4R8pA_bK;hm:8q\A(`PsQ#oXSH_%Bv,kP68\`T7 Ș01Np6\ [H$jx$u77N6^m =%S'_w UbfU7C &4hi3h /חӅT*Έ.]$=]1b{$.;(RΌ8_)H)R)-l7l8iem>WB^ kBcz3լ|=.OL#~u:w!(y{oC#y#bSlO 2E—\Uso{Q\ל%͍AM$1nxF8E{"JDDLT2~ Gy26ToM |MU equYt {{!م/+7FD&SznG6F a[d$gVD'  %plʏ1bE=y; "_C&65yᙖ, Љ @ 6H7/31~^( y7w06_ 3CL?,y'#eG\w]{;3o9"pǜs!C aH`60)lo WooIlJyw!M~pi ZTLX;soׇI]hN<ᎂG_/qԢ_xu`:R qUt\k8gOM*tޚv0Uh8">3`tk#K:dv3 ~{M1)^eCIy6}$ LYP@l$O~Mg'qrk6P7m`@q@4,8 ,t A[W^eYUkˮ)5h ލΗ&.]C) Exjv6!G¯\36 'R^1$|%#LJFS4`3| -ҧ<~:kdEx)lIo6V#F6dl05jAMgJ0etyZ%J;ձ-@t?"`ALXHSF%L~>5LɃpͷC͠/GKCI/Fda«V#D҉T#^Е|3_Ta\];(bhw6U9nǛ _@^?p>NȩpڭJq'"~iodBeCą#O\\)8{='Đ+$jYJX@@hk6{ <]ܿVҡX2(=0AA-y;߽b@g h p'pGN{bZEF?8H? Մ{5ԑ QQξh~֜tEE|F $Z{>@(\pgas¶v*}ѫ'e=~e}Bu_q%JSXJSp2E %Q5- ^zӜڎ(>ܻI ްMp "2 zlLquH<}0ųKDB%PfdʹG>%7;…ۧ,_FzW?sc3/۳h)0Td;PIY,mmZlkHV=)pJq^CG. 'sCsy5] {SsW`QH_p|/C a1 G ƛ~Àt?ׯck/}ނ;ٝ^p6 |)M{Uȏ[֔&wְ?6F0E2m*hcrg]B#t߂531M\Hi\vxwj$ Ff6 ]L~!ŮbDHt@hh>dA']XNܶit[*HhhY`{ jC$/4N 9юT:Hx!d[͇$`PWR7:S)ݺ6Z}gZr<%-k*Ȧ2MBgėٯu;+Kjyv &*QOY&ga8Nuwp2[Pw@ٌ5Ti67X(eLS ALO è*^R]羴mċiWNn`8 nldRaxAx E-r-B0e$`s[OOo_;Ėo=f{hkgNܺqw{e:9;FG9f3>3  endstream endobj 11 0 obj <> endobj 110 0 obj <>stream xyxW!$C H$QB%Ѝ Ƙb).--r%]Ir`pƔ !BR6ac;ͿϸHsssÇq2O&]~tF{GFY,O'=d W`o#0S(H(nREC;"ρh('%:ɳ0Ev@Nd!G]gwpJ7yg Y,YFAMLcnEX03P o<"_.棙F"G.p1Z@W_-Kdp NA5h&d8pm$]u}~n| t5-3|V r:\AG,&^e'sݕ" l#'JP( r;uF{].y:?[0P]ƚohɕV{SD\OF뇒QȂY,nl>+x'Zq*prGܐXaWxiQ tQ'Zj? n\;*Q֒sJCî,wGZsryW&t΄0 eqN-'$9=Y&7{f>8]pqw,5:}/KnXCR& 4:0}}?J$PhҒ#1]%BO 8n=ՑwHr.Jh]Q;NEeFV紪8$6&5 074(tP|y ~%!bbpu#5U. A6ZJ f@Ud(c 1Ww{Y3^EMYGג[5h "u[T ٮ)f'b& eK[]R)7'Hw\/%g`z=:sPS4 ~fsu %&̷M ^|Lt1-H 9l tGtVSZ);FeV5LGx#U]]n:_~1=:'W\nfZb Rjq vM\IIIK cMI5'긳{XHO[6>pIwS+tv6+tin&Tӈ:w6 eƬ. 2̛)DCz)Эwؐ%;tP>mL- >Ŷ;>2p6fC K[m@N sD>KarMeU~NtTϫ'E@,mSA$HQEEGT)KcULMK ay̬b *]GѺU›)ϗ7#*\\)іcEpZDUJE=gJj?Y-ixd SX F=bec$j gQVĉ{ɒxI7 h7 nM8 DAuVYᯟ ;[[Vߟ,޹g?KJjF)u"5DӜg OUC98cꓡ=9Z+C :h|L㜵jmV+J HO'#^ e <4jƁ'С+"o+)i r+tذ9dæDS΋/A*hT8=]e@HvT!+V&5pp?#<]iMsųP\Yú Ċ@&1-/!CT?2etezT亃=`GVن^q6wviQ\֘Pw(|z·=!%,{?U?C|`gh,`xŰkk+9]V N r*?-DzS4x;a}W&U `5]!~ Yr"f)<?0(p^mVf,uy%lVˆZ,ef=]Onke Bnm\5Uϻ^VQ 9&>BE@lCfGXʬQf7ϟ'X< Y1jrnK, y-20EJꃽ^k"Gs@ 0t}$إSHg @]~xQ]pIRba| r\ERI89~,9br :z.Cv95 oA:iD\\2):X4Lp|`zq_?g(OCf~BeD,6ǺMɵsʿn t9 h]0:ȎwܲLj4 7y: Н^_]q4jUIP Q3[L5;(FQS,*p9 ^H (DFU! \7\p>|\" },iFeTDlTi %oPKJ+vFdi46 ڳ5%aLlFxРſ,~1tKv]z3}9賃%F<H*v6S6C(+STwU`Ϳ;bbjLfl>ۧ;V)b,<4)ͫ;ݱ.Y {aBL *$'vPbb ,֏='6"&?;\קΦ#40(,}kǢMn%;uN[eIw# yxӀǛYqnϢk!*9T\!-O%*6A;IJJL4p*2tA.9x-ص3U(T6Uj=Q?m8F|4GK|)kĉ5XAr-@l*Z%y5`2_҂|`຺ڠ@?;cr*>.f;X| I_Wc՝jeuX^֚Wo|Tq5/_kx ث Mw6 |[X-irG Eс&ptᶤqSTn! sPj–k s^I0=a}82& OɄ:Urܥ耠sb]Q&KK6 r/!սF';u& ׂD"}/+gi@\ڦk=@zuu@Q] 6wy镺ܜZ+,Lxm'A Awc]i^- ?KLb!P2~U Pۀ,B(v5J;ܼuZ!ň* h&9#3k{}CH4q-zI~ꇸn@{!|}!qD H05 #) /(*7/|]Ta6~*9vVoŬl,顉o̞efٲ0n\+ϴ{DT|hL8QS<8yCSb.60s[ VMX#{]{SC.Zlgl nu}։{~O5'=7oY=s؂!9L=/oA)bWl6 ^^'.m>~7a>З5ЙYG R9HuZU;.A;&evχ Blhc^Co_+/W [󌆓w+|ce6 hwόm&5hom.=oG&MtfMatiJ>(MUYצI %||KxpIK߸RpǍp|M?D o-qZjd\E ޳}al/ra-.,2o8ѥ7ʦHZ\z/b3P2>;7m刵$LJYBq9E>2 I$ ;2VS:A[k Ӑ No،M|oXsUlVQ)c@>0WMQm +o":pgqϫwkD>r\m `/OYrެ;+~;?ؽë0%K$~;Ƥ Kͧ]v'hJ9T\QDG{v{f^Z\Uq&(AXf|:# w~ttU!%l ]:?5w㾈={C /`S+ -[c]4[6H= \ 6yikM5-(5_%|22kPkG.E4C_dv'78̛_q; ^-^BM N( }ZG׭NOMuqYoJvwO6"q7oBGX/| jc$ͺz>>x|FA޲{[EgqfUUq o\E&Nw0Y`^@{u߽_4ed -.ǿ񐴾=_ Ojʠm 'mOmᢽถbIyswe,Mf;ZG3I  endstream endobj 9 0 obj <> endobj 111 0 obj <>stream xX TWn(AM'n qM (+₻DGٜٗa2"0D:*5h4>-&F4y0mN;G=]VWUոnAahjIr ~m,7̅{k. EԝmkCx> ~>d wgCeAD,_?n)JEfl;#NؑU$hTyBrJd1I "9I Rɢdy_S2QR*Y2*I-eM,<^KNRRx?`Q**FHQ!՛*ޖ%ᓱ1ޚ=u"I%S;rYBŢR ")xRMry8 JIIHM{_V0ɲ2؄(KN1;()ynJbYc7NxMspb)N$ XIDjb 1O%uD01x!BI|b1XHL%ӈ["p%܈ak넘 џEJ&Z<xaPAMn ps.ڟN&rC^{}+H,/%Ͻ#uyp]~,`]@.9DZ]NEdT[53q$ZDh`۝D=Q`i,`9+A$$`hx!z^yfv} IB+ma$1pSh$$֪Uݺ}aGMߴ9F )b6.΋ h" 8YJ/iQXLsa]n\~͕ zw4|/i!/&of#{}/>[=/B]+l8i·Eߴ1y08 }zC鞦z` ̹4bњm!BAw 1CtUaҲLSA5jMl~AgiӥX 7Yxw.聽aEÑث^!;t '~ (8ɏpC&ݼߘ?NLA㯬'Qovlw`$M)"J$_wkjLO30:{4Z .lȐ6K/,7p1=oc~ gp"֩%d$CEi$ <ĒpVوÅ[} D:O&C,ZCNC??h#`ga#T-up0 }X,FC!{Y"l@œҼ"SyP^VV.RyP7OoY*6b<-|*Ck߽O||IJp8Bюl;{Ʊ>~J=d, 3a$n>I8&z;+@2أP <߉ "n; &*g; &Kp$pd?S$zy[a?Q|&&(DJIE '|'d/BO9kJ\Kq-89seg Wu}+Oy'?Qݻ`8h|`cA`ֵ OwgX>1f7_T  vx"۩?{4VÍڞ0s;Ivozg0%BL+|! -\IiyB7ᐫW0- j-⒂KTsIٷ܆|1dTj^0#1=4M2NYܑIrvGbYk >`, WvmI'ba(>tߝ9[f g,ƺr%ޜMN!LKy l Zٛ\ /9aXL@pt۲[<3^E޿AU}E%:&f0Z ] H&+W.yD]GJO0U\m՛rPÄMqRC_`uA(Ef/gQ;<),$o0H4rn_]Y2wT={_qwVI0Qz< йU Iġ+CqGC,Et}>™J<@ݺ#uah77!c|kZ$4U5ԟG.5M|Hh$-[;c1O\.|Xhj7 /|8E ?z :K%#.b #~a5^lW+b#5|)QV5Os0z;MkɨߺyhмAgKK@ 7G;hf\:>$ڒͳkXmSgz҇ܽ1z3܎a \ hĤ0 Vqu K`| ²^/oL@b`q%lBg"M8G3\ 6siyc<>K|I8dR_D1p.CD'< Æ 4zcG5|}Xͱ &П=|a_ovEoI]+՜ں{(Xs7mjCF%6K VU2< 2rGN 'uPYV9@_P4>xTVou/g8KjHLs-ڪJsAjD,,-(ło 0SV)M$-Г/xYkx9)Ilbr\ܾ#<ĖX&v$%G7GI!ciQi1(ͬɩ1WڬR8 6/.߀mnʪ((1JPYn4} Ʋr`E ZTW/0K_J}K N'm:+ۈ-{l96:jV;W737mCpϖy`7v wJU*<K|v{_0"&$5j%買>sctDUP+w^>Gռɸ?QaOpA+Ff찞i0Xh(z/*Zc]R!Z?¢BEeņbTTZn0c%Wn!|e~FvY򭀪ZK %L~5a(3r w?y|C%W8  h>?%A%%&z  C}8GbpKj/Ee/d $@NZV+T`ǹcV&Pp,77uf m%ŻSDWRA=7,xzQqFY cY` Pf)b A|sb?_e-yU;s6\ d,c,0-A A"sڪ Ce]ǫ%ϟ,bTd*O˭:ʜr:#@=[7ދӦa<7rgcc#y?;;*A_γ endstream endobj 115 0 obj <>stream 2013-11-05T18:29:57+01:00 2013-11-05T18:29:57+01:00 dvips(k) 5.992 Copyright 2012 Radical Eye Software ccbuild.dvi endstream endobj 2 0 obj <>endobj xref 0 116 0000000000 65535 f 0000051452 00000 n 0000078528 00000 n 0000051265 00000 n 0000048183 00000 n 0000000015 00000 n 0000001326 00000 n 0000051518 00000 n 0000054580 00000 n 0000071652 00000 n 0000053828 00000 n 0000062906 00000 n 0000053247 00000 n 0000056613 00000 n 0000051559 00000 n 0000051589 00000 n 0000048343 00000 n 0000001346 00000 n 0000003300 00000 n 0000051641 00000 n 0000051671 00000 n 0000048505 00000 n 0000003321 00000 n 0000005199 00000 n 0000053034 00000 n 0000055133 00000 n 0000051723 00000 n 0000051753 00000 n 0000048667 00000 n 0000005220 00000 n 0000005480 00000 n 0000051807 00000 n 0000051837 00000 n 0000048829 00000 n 0000005500 00000 n 0000010734 00000 n 0000051869 00000 n 0000051899 00000 n 0000048991 00000 n 0000010755 00000 n 0000011077 00000 n 0000051951 00000 n 0000051981 00000 n 0000049153 00000 n 0000011097 00000 n 0000014634 00000 n 0000052013 00000 n 0000052043 00000 n 0000049315 00000 n 0000014655 00000 n 0000014974 00000 n 0000052095 00000 n 0000052125 00000 n 0000049477 00000 n 0000014994 00000 n 0000019377 00000 n 0000052157 00000 n 0000052187 00000 n 0000049639 00000 n 0000019398 00000 n 0000024370 00000 n 0000052250 00000 n 0000052280 00000 n 0000049801 00000 n 0000024391 00000 n 0000029672 00000 n 0000052332 00000 n 0000052362 00000 n 0000049963 00000 n 0000029693 00000 n 0000032190 00000 n 0000052425 00000 n 0000052455 00000 n 0000050125 00000 n 0000032211 00000 n 0000035965 00000 n 0000052496 00000 n 0000052526 00000 n 0000050287 00000 n 0000035986 00000 n 0000036743 00000 n 0000052589 00000 n 0000052619 00000 n 0000050449 00000 n 0000036763 00000 n 0000039435 00000 n 0000052660 00000 n 0000052690 00000 n 0000050611 00000 n 0000039456 00000 n 0000039848 00000 n 0000052742 00000 n 0000052772 00000 n 0000050773 00000 n 0000039868 00000 n 0000044518 00000 n 0000052804 00000 n 0000052834 00000 n 0000050935 00000 n 0000044539 00000 n 0000044892 00000 n 0000052886 00000 n 0000052917 00000 n 0000051099 00000 n 0000044913 00000 n 0000048161 00000 n 0000052950 00000 n 0000052981 00000 n 0000055409 00000 n 0000056982 00000 n 0000063454 00000 n 0000072193 00000 n 0000053744 00000 n 0000054479 00000 n 0000055041 00000 n 0000077071 00000 n trailer << /Size 116 /Root 1 0 R /Info 2 0 R /ID [<8054EC0B084FF9375977F934E3AA5F21><8054EC0B084FF9375977F934E3AA5F21>] >> startxref 78734 %%EOF ccbuild-2.0.9/doc/ccbuild/ccbuild.sgml000066400000000000000000000463361402074776400176210ustar00rootroot00000000000000ccbuild" > ]> &ccb; - A strict developer's build utility <author>A. Bram Neijt <version>v2.0.7-39-gdf7b35c <abstract>This document is a general usage manual to &ccb;. It will introduce ways of using &ccb;. It will also explain &ccb;'s behaviour in more words then the manual does. The newest version of &ccb; can be found at the <url name="https://github.com/bneijt/ccbuild" id="https://github.com/bneijt/ccbuild"> <copyright>Copyright © 2005 A. Bram Neijt <p> This manual 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 3 of the License, or (at your option) any later version. <p> It 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. <p> You should have received a copy of the GNU General Public License along with &ccb;. If not, see <url name="http://www.gnu.org/licenses/" id="http://www.gnu.org/licenses/">. <toc> <chapt>Introduction <p>Programming should not become an administrative task. With most of the tools on the net I found myself either adding file names to scripts (and removing them) or digging deep into the core of some scripting language to try automate my builds. At first I ended up with a clumsy, to say the least, collection of <tt>find</tt>, <tt>grep</tt>, <tt>sed</tt> and <tt>bash</tt>. Combined they formed a script to generate Makefiles dispatched over multiple directories. The complexity quickly grew out of hand and it left me with a lot of clutter around my source. The second incarnation helped to generate autotools scripts. I had to run <tt>./configure</tt> to get the new scripts to generate real Makefiles, followed by make. If you commonly add and remove files, updates are slow. <p>It was a depressing way to develop, because most additions to the project I made required me to run all those scripts. On top of that, it would take about 30 seconds, or so it felt. <p>You would say, well why not use an IDE? Well, trouble here was I wanted to split up my code in separate files... a lot of separate files. Not only do I separate my code into directories, I also use seperate files for functions of the same class. No IDE allowed me to do this without the hassle of having to go through a few menus (create file, register it as source, set is as part of the main program, etc.). Those who did, often used autotools in the background and would have to re-autotool on every added file. Frustrated, I almost gave up on my coding ethics and started to do it the way the masses do: 900+ lines of code in a single file, only accessible through a specially equipped text editor or full scale IDE. <p>The closest thing to perfection out there was <prgn>icmake</prgn>. This only requires you to mention the directories you use and will keep your development tree clean, however it had two small drawbacks: you needed to mention your classes and you could not use directories in directories. So, I decided to create a fast and simple program to solve my problem. <p>Although you have to keep some standards (split source over directories) to get &ccb; to work on your program, I found it almost completely eliminated my interaction with the build system. Better yet, it helps with bootstrapping other build systems. </chapt> <chapt>How it works <p>To know how to work with &ccb; is of course the most important thing (if you want to). So here is a quick and simple review of the internals. <p> We will now consider what happens when &ccb; is called without any arguments. <p>First &ccb; will find all source files in the current directory (using the list of source extensions to find them.) All these files are scanned which gives an in memory list of include statements and whether it has a main function. <p> If it has a main function, it is considered a binary target: &ccb; will try to make a program from this. <p> To find all the object files that need to be linked to the main program, &ccb; will follow all local include statements (warning if any fail). Then it will scan all files in the same directory as the included files. If they are object targets (don't have a <tt>int main</tt> function) they will be compiled and linked to the main program. <p> The arguments needed to compile an object are gathered by the global includes. Using the ccResolutions file, for every global include the arguments are added. <p> The needed linker arguments (which would create the "not linking now" warning) are identified and kept back for later use when the program is actually linked. If anything goes wrong here, please mail me and hack the file <tt> src/Compiler/countFirstLinkerArguments.cc</tt> for the meantime. This file contains two simple lists for for options with and options without arguments. </chapt> <chapt>Using &ccb; <sect>Organizing your source <p>&ccb; will read your local includes (#include "something") and compile any source next to it into your program or library. For every class you want to use, make sure you create a separate directory. Every directory contains source files which define the different members of your class. <p>Because every member of a class has it's own file, each of these files will have an approximately equal header. To keep us from typing "using namespace" and "include <iostream>" for each of these files, a so called internal header file is created. The internal header file is the only file the member implementation include and is identified by the extension <tt>.ih</tt>. <p>An example member implementation is given <tt>fileSystem/touch.cc</tt>: <example> #include "fileSystem.ih" bool FileSystem::touch(std::string const &filename) { ofstream file(filename.c_str(), ios::app); bool succes = file.is_open(); file.close(); return succes; } </example> <p>The internal header file, <tt>fileSystem/fileSystem.ih</tt>: <example> #include "fileSystem.hh" #include <fstream> #include "../options/options.hh" using namespace std; using namespace bneijt; </example> <p>The header file defines the <tt>FileSystem</tt> class in the <tt>bneijt</tt> namespace and includes only what is needed for it's declaration. <p>Splitting the source up like this will get you a lot of files, but will make editing and hacking your code simple. The functions are easy to find, quick to open and easy to grasp. Furthermore, version control software will encounter less collisions and patches will merge more easily on quicker moving code. <p>The main program is in the root of the source. &ccb; has the following listing: <example> ./fileSystem/touch.cc ./fileSystem/fileSystem.ih ./fileSystem/isDirectory.cc ./fileSystem/cleanPath.cc ./fileSystem/modTime.cc ./fileSystem/fileExists.cc ./fileSystem/isReadable.cc ./fileSystem/absolutePath.cc ./ccResolutions ./string/replace.cc ./string/test.cc ./string/string.ih ./string/toUpper.cc ./string/string.hh ./options/options.hh ./options/options.ih ./options/statics.cc ./ccbuild.cc </example> <p>The top most file is <tt>ccbuild.cc</tt>, which contains a special function: <tt>int main</tt>. &ccb; does not care about the arguments the main function takes, but it does care about it being <tt>int main</tt>. This is what &ccb; calls a binary target, a file that is the root of a binary. <sect>Building a program <p>To build a configured &ccb; compatible source tree, simple run &ccb; in the directory containing the main program. This will compile all programs in the given directory. However, if you only want to compile one given program, issue the command <tt>ccbuild build mainsource.cc</tt>, where mainsource.cc should be the name of the main source file. <p> Once the command is issued, &ccb; will start reading includes the source does and gather sources it should compile. Any sources it can find will be compiled and linked to the main program. Once the <tt>[LINK] mainsource</tt> line get's done, without any errors, your main program will be done and you can start it with <tt>./mainsource</tt>. </sect> <sect>Cleaning up <p>For cleaning your sourcetree, &ccb; offers two commands: <tt>clean</tt> and <tt>distclean</tt>. Although they might act almost the same, they are implemented quite different. <p> The <tt>distclean</tt> command is totally source independent: it does not scan sources, nor look for them. Distclean simply removes all &ccb; related file in the "o" directory and all ".gch" files everywhere. If the "o" directory is empty after that, the directory is removed as well. <p> The <tt>clean</tt> command is much more subtle: it reads the sources and removes any objects part of the current source tree. Because it reads the sources, using clean will only remove those sources part of the given or implied main binary target(s). This command will not remove any directories. <p> General rule is to use the force command when you want to update everything, use the <tt>clean</tt> when you want to remove all files for a local binary target (but not any other binary targets in the local directory) and use <tt>distclean</tt> to remove everything including old objects and pre-compiled headers. </sect> </chapt> <chapt>Moving to &ccb; <p>To be able to use &ccb;, you as a developer will have to adhere to some strict(er) rules then using something like autotools. Here is a list of things you should keep in mind when moving to &ccb;. <sect>Strictness to adhere to <p> <list> <item>&ccb; only reads local includes <p> When creating your source, make sure that all sources that &ccb; should care about can be found using local includes. This means you should strictly use system wide includes only for actual system wide include files. So any header file which is part or your packages should be included using a local include statement. </item> <item>Preprocessing isn't helping <p> To speed up &ccb;, it does not go around looking for system wide headers. This also means that it won't know all the preprocessing directives from these headers. This results in preprocessor excludes of local headers cannot be used. This is no problem if you are compiling for a single platform, but when you need configuration using preprocessor directives, you're going to get into trouble. <p> The only way to keep &ccb; from reading these sources is by making sure there is a single space between the <tt>#</tt> and the <tt>include</tt> statement. So the include <tt># include "something/hello.hh"</tt> will be ignored by &ccb;. To test this, run &ccb; in verbose mode (<tt>--verbose</tt>) and watch for the warning which state that the file in not included. You can also use the <tt>deps</tt> command to get a list for all binary targets. </item> </list> </sect> <sect>Setting up your configuration file <p>To set up your ccResolutions file, it's best to do the following steps: <enumlist> <item>Check your local includes span over your whole source <p>To make sure &ccb; was able to follow your local includes, use the <tt>deps</tt> command. This will list all the local and global dependencies of a file. You may also use the dot command to get a graphical interpretation of the same information. <p>All paths that &ccb; needs to search for local includes should be added to the first line of your ccResolutions file. Using <tt>-l</tt> in this first line will make &ccb; highlight all compiler output. <example> #& -I../tools -I. -l </example> </item> <item>Add packages to your global ccResolutions <p>You can add a package to your global resolution configuration using the genPkgconfigList.sh tool. This will find all files in the include path of a package's include paths and add them to a resolution file. See the Tools section for more information. </item> <item>Check the global includes are resolved <p>To make sure the global includes are resolved, use the resolve command. <example> ccbuild resolve |sort >> ccResolutions </example> <p>Now all unresolved global headers are listed in your ccResolutions file. When you run &ccb; now, it won't complain about any global includes missing. However, g++ might complain because the needed extra arguments are not in place. You should now add the needed arguments to your ccResolutions file by using, for example, <tt>`pkg-config --cflags --libs <packagename>`</tt> with the needed package in place. <p>If you have a lot of resolution rules in your defaults (<tt>~/.ccbuild/</tt>), then it might be hard to see what your project actually depends on. Passing &ccb; the option <tt>--nodefres</tt> will cause it to skip loading these files and will allow you to see which resolutions fail. This might give you some hints on what packages your program depends on. </item> </enumlist> </sect> </chapt> <chapt>Moving from &ccb; <p>There will be a day you want to move away from &ccb;. When the day comes, you would probably only be able to use &ccb; for it's dependency generation commands. <p>To make &ccb; useful in these later stages, &ccb; has a few commands to help you cope. Don't forget, you can remove all &ccb; generated files using: <example> ccbuild distclean; rm ./ccResolutions; </example> The build script generation commands only read source and, should not generate any output. <sect>General build file generation <p>&ccb; can generate a number of different files for different build systems. When you call &ccb; with a build generation command without a source file, it will try to create a standalone file for that build system. Which will also contain an all rule. <p>For most systems however, you don't want the all rule to be defined. So, &ccb; allows you to state which source you want a build file for. This will then generate a build file without the all rule. Then simply include this build file into your main build file and write the all rule yourself. </sect> <sect>Generating A-A-P files <p>One of the most useful generation features is probably the A-A-P file generation. You can use this by calling &ccb; with the aap command. This will generate an A-A-P file on the stdout. <p>The most common way of using this aap file is by generating it for a single binary target using: <example> ccbuild aap mainsource.cc > mainsource.aap </example> Or <example> ccbuild aap src/mainsource.cc > mainsource.aap </example> <p>Then create a main.aap file with the following line: <example> :include mainsource.aap all : ./mainsource </example> Or <example> :include mainsource.aap all : ./src/mainsource </example> Add any recipes needed and then use aap to generate the main program. </sect> </chapt> <chapt>Problem solving with ccbuild <p>This is a collection of possible real usage examples for &ccb;. If you don't want to take the time to read the manual pages, this is a more problem oriented listing of the same. <sect>You changed a class interface <p>When you change a class interface, a large collection of your code will probably break down. But which parts? Well, a hint of which files will be affected can be seen using &ccb; <tt>check</tt>. However, this won't show you whether these sources still compile or not. The only way to test that is by simply running &ccb;. <p>Solution: Use an editor running in the background (something that returns after using the command). An example is using the gedit command when you already have a window open: new files will be opened in a tab and the gedit command will return immediately. So, using gedit, the easiest way to get an overview of your problems would be: &ccb; --brute --xof "gedit" </chapt> <appendix>The tools directory <p>The <tt>tools</tt> directory contains a few scripts and default files that may come in handy. These are not meant to be used a lot and are mostly there as examples of using &ccb; in combination with other programs. These utilities are often crude and come with NO WARRANTY WHATSOEVER.<p>Bottom line: read them before you use them and enjoy. <sect>genPkgconfigList.sh <p> This script will generate a list of includes that might be part of the given package. The scripts needs to get a valid package name as it's first argument. It will then call pkg-config to get a list of include paths used for the package. All these paths are searched and all files found are linked to the package using pkg-config in a way that is compatible with ccResolutions syntax. <p> This list will be very large, and it's not, generally, a good idea to add this list to your local ccResolutions file. A better way of using this is by adding the file to your ccResolutions.d directory under the name of the package. <p> Using this is of course a brute way of handling resolutions, because it's much nicer to only resolve the ones you need. </sect> <sect>ccbuildStatusPage.sh <p> This is a small &ccb; status page creation script. All command line arguments you give it will be passed to &ccb; directly. It runs "ccbuild check" to check which files are up to date and which are not. Then using AWK it translates this into a small auto-refreshing web page. The web page uses ccbuild.css as it's style sheet. <p> General usage for a single run is: <example> sh ccbuildStatusPage.sh -C "someproject/src" </example> Then use your favourite browser to open the generated html file: ccbuildstatus.html. <p> You can easily loop it in the background using: <example> while [[ 1 ]]; do sleep 5; nice sh ccbuildStatusPage.sh -C "someproject/src"; done; </example> By default the up to date files are not shown by using "display: none" in the ccbuild.css. Remove this line from ccbuild.css to show all up to date files as well. </appendix> <appendix>Categorically sorted command line parameters <p> Here is list of the command line parameters divided over categories. If you think you know &ccb;, go down this list. If you don't think a given argument is in the right position, you might need to read up on it. Please refer to the &ccb; manual for a full explanation of these flags and arguments. </p> <p>Command execution influencing arguments (the actual system call): <tt>--compiler</tt>, <tt>-a</tt>, <tt>--args</tt>, <tt>-I</tt>, <tt>--recursive-include</tt>, <tt>--xof</tt>, <tt>--exec-on-fail</tt>, <tt>--xop</tt>, <tt>--exec-on-pass</tt>, <tt>--append</tt> and Resolution arguments. </p> <p>Global header resolution effecting arguments: <tt>-C</tt>, <tt>--nodefres</tt>, <tt>--addres</tt> and <tt>--nodefargs</tt> (if the default commands contain any of the before mentioned). </p> <p>Command (build/lib/distclean etc.) effecting arguments: <tt>-s</tt>, <tt>--no-act</tt>, <tt>-p</tt>, <tt>--precompile-ih</tt>, <tt>--precompile-all</tt>, <tt>--brute</tt>, <tt>--loop</tt>, <tt>--verbose</tt>. </p> <p>Arguments that won't, normally, change the resulting binary or output: <tt>-f</tt>, <tt>--force-update</tt>, <tt>--gnutouch</tt>, <tt>--md5</tt>, <tt>--real-man</tt>, <tt>-l</tt>, <tt>--highlight</tt>, <tt>--xof</tt>, <tt>--exec-on-fail</tt>, <tt>--xop</tt>, <tt>--exec-on-pass</tt>, <tt>--clearpc</tt>, <tt>--append</tt>. </p> <p>Read only actions are: <list> <item>Anything with <tt>-s</tt> or <tt>--no-act</tt> <item>The commands: <tt>resolve</tt>, <tt>md5</tt>, <tt>deps</tt>, <tt>dot filename.cc</tt>, <tt>makefile</tt>, <tt>aap</tt>, <tt>check</tt> and <tt>icmake</tt>. </list> </p> </appendix> </book> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ccbuild-2.0.9/doc/ccbuild/ccbuildman.html�����������������������������������������������������������0000664�0000000�0000000�00000043152�14020747764�0020310�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""> <head> <meta charset="utf-8" /> <meta name="generator" content="pandoc" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> <meta name="author" content="A. Bram Neijt bneijt@gmail.com" /> <meta name="dcterms.date" content="2014-08-08" /> <title>ccbuild(1) General Commands Manual

ccbuild(1) General Commands Manual

A. Bram Neijt

August 8, 2014

NAME

ccbuild — Strict C++ developer’s build utility

SYNOPSIS

ccbuild options [command]

DESCRIPTION

ccbuild is a build utility that will read C++ source. It collects all source surrounding your local includes and links these to your main program. Global include statements (#include ) are used to make sure the compiler gets the` right arguments. The link between com‐ piler arguments and these global includes is made using configuration files. These files contain lines with a global header file name and the extra arguments the compiler needs to find and use this file. The file name and arguments are separated by tab character(s) or a space. ccbuild reads these configuration files in order. Only the first men‐ tion of a global header file in these files is used. Usually only ./ccResolutions is used, but there are more possibilities. See the sec‐ tion FILES for more information.

ccbuild will follow any local include (#include “something.hh”) to try to find more source code to compile. To keep ccbuild from following up on an include statement, separate the #-sign and the include statement by a single space (“# include”).

COMMANDS

build [filename.cc]
Build everything or the given source.
lib [filename.cc]

Collect all objects into an archive. If a version is given, using –pversion, then a shared library is also build with symbolic links. This currently forces the -fPIC argument addition. The name of your library is given the name of the current directory or it’s parent when the current directory is called src.

Example: create an empty .cc file which simply includes all the local libraries, run ccbuild –pversion 0.0.1 lib that‐ file.cc

clean [filename.cc]
Clean everything or the given source.
distclean
Recursively remove all “o” directories after removing all .md5 and .o files therein. And removes all .gch files.
deps [filename.cc]
List all files this source depends on. It lists three lines separated by empty lines. The first contains the local dependencies, the second the ignored headers (for the file) and the last contains all global includes needed.
dot [filename.cc]
Generate dot graph files for sources on the stdout. If no source file name is given, then for all binary targets in the local directory a .dot file will be created. If the –verbose flag is used the dot graph will also contain all object file names and their dependencies and lists of ignored headers. Objects will be coloured light grey, binary targets light blue, ignored headers by a red line.
makefile [filename.cc]
Generate a Makefile on stdout. If no file name is given, an all rule will be generated. Otherwise only the rules for the given file are generated.
aap [filename.cc]
Generate an A-A-P file on stdout. If the file name is not given, an “all” rule will be added and all local binary tar‐ gets will be listed.
check [filename.cc]
Display source status and file name on the stdout. Status and source path are separated with a tab character. Status is either “old” or “ok”. When the –verbose flag is used, another tab separated column will be inserted containing a two letter file type ccbuild identifies it as. This file type is “bt”, “ot”, “ih” or “hh” for binary target, object target, internal header and header respectively.
icmake [filename.cc]
icmake slave mode. This will output the used directories with one directory per line. If a CLASSES file already exists, it will only output the class directories not mentioned in the CLASSES file. If –verbose is given, all classes will be listed. The output will not contain directories with only header files. Updating the CLASSES is typically done by run‐ ning: ccbuild icmake >> CLASSES
resolve [filename.cc]
Print all unresolved globals onto the stdout followed by a tab character. These can be appended to the ccResolutions file using: ccbuild resolve >> ccResolutions .
md5 [filename.cc]
MD5 sum all sources needed to compile all binary targets, or the given source on stdout.

OPTIONS

Options are used to change the behaviour of the commands. Some options are useless for some commands.

-f –force-update
Update everything by labelling everything as old.
-h –help
Get a list of options and commands.
–gnutouch
Touch files part of the GNU software standard. They will be touched in ../ except when there is a directory called src in the current directory, then the current directory will be used. This will touch AUTHORS, NEWS, README, INSTALL, COPYING, TODO and ChangeLog.
-s –no-act
Simulate, don’t really execute any writing commands.
–compiler cmd
Set the compiler command. The default is “g++”.
-a –args argument
Set these default compiler arguments, removing the standard default arguments (“-Wall -g”). Multiple uses of this option are concate‐ nated with spaces.
-C path
Change directory before anything else.
-p –precompile-ih
Pre-compile only internal headers. This requires g++ version 3.4 up.
–precompile-all
Pre-compile both internal headers and normal headers. This requires g++ version 3.4 up. When you use internal headers, this will only slow you down. However, when you don’t use internal headers, this pre-compilation is all you’ve got.
–brute
Continue on compiler errors.
–md5
Use MD5 hashes to check for file changes. The hashes are store in “o/filename.md5” for every file. These sums are only stored after a clean exit from ccbuild (last line showing “[WR] MD5 data”) or a successful compilation.
-I path
Add this path to the local include search path of ccbuild and the compiler (which will receive the same argument).
–recursive-include path
This is just like -I, but for the given path and every non-empty directory with a name other then “o”. Make sure you do not come to depend on this behaviour, that would be bad practice.
-l –highlight
Highlight the output of the compiler using a red terminal colour.
–xof –exec-on-fail command
Execute this command when the command (pre)compilation returns any‐ thing but 0. The first argument given to the command will be rela‐ tive path to the file the command was executed on (which is either a C++ source or header). If you don’t want to use the file name, you can append an echo command like “sleep 2; echo”.
–xop –exec-on-pass cmd
This is the same as –exec-on-fail, except it only works when the command returns 0. The first argument given to the command will be the relative path to the file the command was executed on.
–clearpc
Clear the screen just before executing the command (clear per com‐ mand).
–append cmd
Append this to every command. This can be used to redirect output or set up pipes for compiler output.
–loop
Loop the system with one second intervals. This only works for the build command at the moment. All sources who are touched will be reloaded. If a file is removed, the whole source tree is reloaded.
–nodefargs
Do not read the first line of ./ccResolutions for extra arguments.
–nodefres
Do not load any ccResolutions files outside of ./ccResolutions. This can be used to create a monolithic ccResolutions file or dis‐ cover your project’s dependencies with the resolve command.
–addres filename
Load the given resolution file before any other.
–pversion version
Set the program version you are working on to version. This is cur‐ rently only used for the library command. When defined, the library command can make a shared object (.so) and symbolic links by using the version number. It should not contain any file system special characters like slashes.
–ar
Archive the objects before linking. This should reduce the binary size because it leaves out unused objects.
–verbose
Show commands and produce more output for dot and check commands.
-V –version
Output version number on stdout and copyright/license on stderr.
–xml
Output in XML where supported. Currently this is only the check command.
–nowarn
Leave out most warnings.
–batch
Compile a batch of files with one g++ call before any other compi‐ lation. This effectively disables any multi-threading, but may speed things up for larger collections of small files. This process involves creating a temporary directory in /tmp/ccbuild_batch.XXXX. The exact behaviour of this option may change in the future based on performance results and user experience.
-j number_threads
Set the maximum number of threads used during build. Only available when OpenMP is enabled.

RESOLUTION CONFIGURATION

The ccResolutions file links global headers to compiler arguments. Every line should be either empty, start with a comment character “#” or contain a con‐ figuration line. A configuration line contains the name of the global header, followed by one or more tab characters and then the additional argu‐ ments needed when a source depends on this global header. The arguments are POSIX shell expanded.

If the first line of the ccResolutions file starts with “#&”, the rest of this line is shell expanded and used and appended to the argument list of ccbuild.

EXAMPLES

Examples of program use.

ccbuild resolve >> ccResolutions
Add any of the unknown global headers to the ccResolutions file. You can also use –nowarn to keep ccbuild quiet, but you will have to think twice if you get compilation errors.
ccbuild –brute
Get back to development after a distclean. This will update as much objects as will compile. Which will allow you to focus on the errors in the next ccbuild call.
ccbuild -p –compiler ‘g++-3.4’ –args -Wall –args ‘-Wextra -ansi’
Precompile internal headers using g++-3.4 and highlight all com‐ piler output (-l). Also give all compiler commands the parameters “-Wall -Wextra -ansi”.
ccbuild -f –args -O3
Recompiling your project for benchmarking tests. Forces the update of all code (-f) and sets the compiler argument to -O3.
ccbuild –verbose dot; dotty *.dot
Graph the dependencies for all programs with colours. Then view these using dotty. This can help you to discover irregular depen‐ dencies and what test programs use.
ccbuild –xof ‘gedit’
Try to compile the program and open the first file that does not compile correctly. Open all error producing sources in gedit. Very useful for when you change the interface of a class.
ccbuild –compiler distcc -j 20
Use 20 distcc compilers to compile the project.

FILES

Configuration files used by ccbuild

./ccResolutions[.USERNAME,.HOSTNAME,.KERNEL_NAME,.MACHINE,]
Local configuration which is project specific. It will load the first existing file of: ./ccResolutions.USERNAME, ./ccResolu‐ tions.HOSTNAME, ./ccResolutions.KERNEL_NAME, ./ccResolu‐ tions.MACHINE, ./ccResolutions. Hostname, kernel name and machine can be found with uname -nsm.
~/.ccbuild/ccResolutions
Global configuration file.
~/.ccbuild/ccResolutions.d
The resolution configuration directory. All files in this directory are considered configuration files.

CAVEATS

Do not place any file into o directories, these will be removed when using the distclean command. Also don’t use files with the same basename, but different C++ extensions, this will give problems with the objects created (for example “add.cc” and “add.cpp” in the same directory).

Currently there is no way to allow one object file to effect the command-line parameters of another. This means that if all objects need a flag, you must use the –args argument and cannot use a global header resolution line. Exam‐ ples of these flags that need to be defined everywhere are -pthreads, -mthreads and -threads. Please read the g++ manual for more information on usage of flags.

ccbuild seems to be incompatible with flex 2.5.4. That version of flex places an int main function in the resulting scanner and there doesn’t seem to be a way to stop it from mentioning it. The result is that ccbuild will think that the generated scanner is a test program for your class and won’t link it into the main program. A solution is to move to a newer version of flex or find a way to remove the int main function from the resulting scanner file.

REPORTING BUGS

Report any issue with ccbuild at: https://github.com/bneijt/ccbuild

RESTRICTIONS

ccbuild will not follow or act on any include statements with a single space between the #-sign and the include. So all include statements starting with “# include” will be ignored, all other combinations will be acted on. This is a feature, not a bug. In verbose mode (–verbose) these are mentioned as warnings.

SEE ALSO

pkg-config(1), dotty(1), make(1), icmake(1), g++(1), aap(1), svn(1)

ccbuild-2.0.9/doc/ccbuild/ccbuildman.sgml000066400000000000000000000634671402074776400203210ustar00rootroot00000000000000cjwatson@debian.org, based on a man page template provided by Tom Christiansen tchrist@jhereg.perl.com and a DocBook man page example by Craig Small csmall@debian.org. --> Bram"> Neijt"> 2009-12-30"> 1"> bneijt@gmail.com"> ccbuild"> ccbuild
"> ]>
&manemail;
&manfirstname; &mansurname; 2009 &manusername; &mandate;
&manucpackage; &mansection; &manpackage; Strict C++ developer's build utility &manpackage; options command DESCRIPTION &manpackage; is a build utility that will read C++ source. It collects all source surrounding your local includes and links these to your main program. Global include statements (#include <something>) are used to make sure the compiler gets the right arguments. The link between compiler arguments and these global includes is made using configuration files. These files contain lines with a global header file name and the extra arguments the compiler needs to find and use this file. The file name and arguments are separated by tab character(s) or a space. &manpackage; reads these configuration files in order. Only the first mention of a global header file in these files is used. Usually only ./ccResolutions is used, but there are more possibilities. See the section FILES for more information. &manpackage; will follow any local include (#include "something.hh") to try to find more source code to compile. To keep &manpackage; from following up on an include statement, separate the #-sign and the include statement by a single space ("# include"). COMMANDS build [filename.cc] Build everything or the given source. lib [filename.cc] Collect all objects into an archive. If a version is given, using --pversion, then a shared library is also build with symbolic links. This currently forces the -fPIC argument addition. The name of your library is given the name of the current directory or it's parent when the current directory is called src. Example: create an empty .cc file which simply includes all the local libraries, run &ccb; --pversion 0.0.1 lib thatfile.cc clean [filename.cc] Clean everything or the given source. distclean Recursively remove all "o" directories after removing all .md5 and .o files therein. And removes all .gch files. deps [filename.cc] List all files this source depends on. It lists three lines separated by empty lines. The first contains the local dependencies, the second the ignored headers (for the file) and the last contains all global includes needed. dot [filename.cc] Generate dot graph files for sources on the stdout. If no source file name is given, then for all binary targets in the local directory a .dot file will be created. If the flag is used the dot graph will also contain all object file names and their dependencies and lists of ignored headers. Objects will be coloured light grey, binary targets light blue, ignored headers by a red line. makefile [filename.cc] Generate a Makefile on stdout. If no file name is given, an all rule will be generated. Otherwise only the rules for the given file are generated. aap [filename.cc] Generate an A-A-P file on stdout. If the file name is not given, an "all" rule will be added and all local binary targets will be listed. check [filename.cc] Dsplay source status and file name on the stdout. Status and source path are separated with a tab character. Status is either "old" or "ok". When the flag is used, another tab separated column will be inserted containing a two letter file type &ccb; identifies it as. This file type is "bt", "ot", "ih" or "hh" for binary target, object target, internal header and header respectively. icmake [filename.cc] icmake slave mode. This will output the used directories with one directory per line. If a CLASSES file already exists, it will only output the class directories not mentioned in the CLASSES file. If is given, all classes will be listed. The output will not contain directories with only header files. Updating the CLASSES is typically done by running: &ccb; icmake >> CLASSES resolve [filename.cc] Print all unresolved globals onto the stdout followed by a tab character. These can be appended to the ccResolutions file using: &ccb; resolve >> ccResolutions . md5 [filename.cc] MD5 sum all sources needed to compile all binary targets, or the given source on stdout. OPTIONS Options are used to change the behaviour of the commands. Some options are useless for some commands. Update everything by labelling everything as old. Get a list of options and commands. Touch files part of the GNU software standard. They will be touched in ../ except when there is a directory called src in the current directory, then the current directory will be used. This will touch AUTHORS, NEWS, README, INSTALL, COPYING, TODO and ChangeLog. Simulate, don't really execute any writing commands. cmd Set the compiler command. The default is "g++". argument Set these default compiler arguments, removing the standard default arguments ("-Wall -g"). Multiple uses of this option are concatenated with spaces. path Change directory before anything else. Pre-compile only internal headers. This requires g++ version 3.4 up. Pre-compile both internal headers and normal headers. This requires g++ version 3.4 up. When you use internal headers, this will only slow you down. However, when you don't use internal headers, this pre-compilation is all you've got. Continue on compiler errors. Use MD5 hashes to check for file changes. The hashes are store in "o/filename.md5" for every file. These sums are only stored after a clean exit from &ccb; (last line showing "[WR] MD5 data") or a successful compilation. path Add this path to the local include search path of &ccb; and the compiler (which will receive the same argument). path This is just like , but for the given path and every non-empty directory with a name other then "o". Make sure you do not come to depend on this behaviour, that would be bad practice. Highlight the output of the compiler using a red terminal colour. command Execute this command when the command (pre)compilation returns anything but 0. The first argument given to the command will be relative path to the file the command was executed on (which is either a C++ source or header). If you don't want to use the file name, you can append an echo command like "sleep 2; echo". cmd This is the same as , except it only works when the command returns 0. The first argument given to the command will be the relative path to the file the command was executed on. Clear the screen just before executing the command (clear per command). cmd Append this to every command. This can be used to redirect output or set up pipes for compiler output. Loop the system with one second intervals. This only works for the build command at the moment. All sources who are touched will be reloaded. If a file is removed, the whole source tree is reloaded. Do not read the first line of ./ccResolutions for extra arguments. Do not load any ccResolutions files outside of ./ccResolutions. This can be used to create a monolithic ccResolutions file or discover your project's dependencies with the resolve command. filename Load the given resolution file before any other. version Set the program version you are working on to version. This is currently only used for the library command. When defined, the library command can make a shared object (.so) and symbolic links by using the version number. It should not contain any file system special characters like slashes. Archive the objects before linking. This should reduce the binary size because it leaves out unused objects. Show commands and produce more output for dot and check commands. Output version number on stdout and copyright/license on stderr. Output in XML where supported. Currently this is only the check command. Leave out most warnings. Compile a batch of files with one g++ call before any other compilation. This effectively disables any multi-threading, but may speed things up for larger collections of small files. This process involves creating a temporary directory in /tmp/ccbuild_batch.XXXX. The exact behaviour of this option may change in the future based on performance results and user experience. number_threads Set the maximum number of threads used during build. Only available when OpenMP is enabled. RESOLUTION CONFIGURATION The ccResolutions file links global headers to compiler arguments. Every line should be either empty, start with a comment character "#" or contain a configuration line. A configuration line contains the name of the global header, followed by one or more tab characters and then the additional arguments needed when a source depends on this global header. The arguments are POSIX shell expanded. If the first line of the ccResolutions file starts with "#&", the rest of this line is shell expanded and used and appended to the argument list of &ccb;. EXAMPLES Examples of program use. &ccb; resolve >> ccResolutions Add any of the unknown global headers to the ccResolutions file. You can also use --nowarn to keep &manpackage; quiet, but you will have to think twice if you get compilation errors. &ccb; --brute Get back to development after a distclean. This will update as much objects as will compile. Which will allow you to focus on the errors in the next &manpackage; call. &ccb; -p --compiler 'g++-3.4' --args -Wall --args '-Wextra -ansi' Precompile internal headers using g++-3.4 and highlight all compiler output (-l). Also give all compiler commands the parameters "-Wall -Wextra -ansi". &ccb; -f --args -O3 Recompiling your project for benchmarking tests. Forces the update of all code (-f) and sets the compiler argument to -O3. &ccb; --verbose dot; dotty *.dot Graph the dependencies for all programs with colours. Then view these using dotty. This can help you to discover irregular dependencies and what test programs use. &ccb; --xof 'gedit' Try to compile the program and open the first file that does not compile correctly. Open all error producing sources in gedit. Very useful for when you change the interface of a class. &ccb; --compiler distcc -j 20 Use 20 distcc compilers to compile the project. &ccb; --nodefargs -f --args '-Wall -Werror' && svn commit -m 'buildable backup' If all the sources are buildable without any warnings, commit everything to the repository using subversion. FILES Configuration files used by &ccb; ./ccResolutions[.USERNAME,.HOSTNAME,.KERNEL_NAME,.MACHINE,] Local configuration which is project specific. It will load the first existing file of: ./ccResolutions.USERNAME, ./ccResolutions.HOSTNAME, ./ccResolutions.KERNEL_NAME, ./ccResolutions.MACHINE, ./ccResolutions. Hostname, kernel name and machine can be found with uname -nsm. ˜/.ccbuild/ccResolutions Global configuration file. ˜/.ccbuild/ccResolutions.d The resolution configuration directory. All files in this directory are considered configuration files. CAVEATS Don't place any file into o directories, these will be removed when using the distclean command. Also don't use files with the same basename, but different C++ extensions, this will give problems with the objects created (for example "add.cc" and "add.cpp" in the same directory). Currently there is no way to allow one object file to effect the command-line parameters of another. This means that if all objects need a flag, you must use the --args argument and cannot use a global header resolution line. Examples of these flags that need to be defined everywhere are -pthreads, -mthreads and -threads. Please read the g++ manual for more information on usage of flags. &manpackage; seems to be incompatible with flex 2.5.4. That version of flex places an int main function in the resulting scanner and there doesn't seem to be a way to stop it from mentioning it. The result is that &manpackage; will think that the generated scanner is a test program for your class and won't link it into the main program. A solution is to move to a newer version of flex or find a way to remove the int main function from the resulting scanner file. REPORTING BUGS Report any issue with &manpackage; at: https://github.com/bneijt/ccbuild RESTRICTIONS &manpackage; will not follow or act on any include statements with a single space between the #-sign and the include. So all include statements starting with "# include" will be ignored, all other combinations will be acted on. This is a feature, not a bug. In verbose mode (--verbose) these are mentioned as warnings. AUTHOR A. Bram Neijt <bneijt@gmail.com> SEE ALSO pkg-config(1), dotty(1), make(1), icmake(1), g++(1), aap(1), svn(1)
ccbuild-2.0.9/localinstall.sh000077500000000000000000000020441402074776400161620ustar00rootroot00000000000000#!/bin/sh echo "#" echo "#" echo "# Small install script" echo "# This program is distributed in the hope that it will be useful," echo "# but WITHOUT ANY WARRANTY; without even the implied warranty of" echo "# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." echo "#" echo "#" make -j2 || exit 1; strip -s ccbuild; function binDir() { #Determine BINDIR #Find another installation directory IFS=":" for path in $PATH; do if [ -d "$path" ]; then if [ -w "$path" ]; then echo $path; return 0; fi; fi done; return 1; } BINDIR=`binDir || echo /usr/local/bin` PROGRAM="src/ccbuild" DEFCONF="./tools/ccResolutions.d" CONFDIR="$HOME/.ccbuild" echo echo Install directory: $BINDIR echo Config directory: $CONFDIR echo echo "Do you want to continue with installation? (yes/no)" read REPLY if [[ "x$REPLY" != "xyes" ]]; then echo Reply "\"$REPLY\"" isn\'t \"yes\" echo EXIT exit 1; fi; mkdir -p $CONFDIR echo cp -r $DEFCONF $CONFDIR cp -r $DEFCONF $CONFDIR echo cp $PROGRAM $BINDIR cp $PROGRAM $BINDIR ccbuild-2.0.9/package.sh000077500000000000000000000030621402074776400150750ustar00rootroot00000000000000#!/bin/bash #This script is used to clean up the directory # # This file is part of ccbuild. # Copyright (C) 2013 A. Bram Neijt # ccbuild 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 3 of the License, or # (at your option) any later version. # ccbuild 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 ccbuild. If not, see . cd "`dirname "$0"`" set -e echo "]]] Clean cmake config" ./update_cmakelists.sh clean echo "]]] Update cmake config" . ./update_cmakelists.sh if [ -z "$VERSION" ]; then # VERSION should come from the import of update_cmakelists echo EMPTY VERSION FOUND exit 1 fi sed -r 's/PROJECT_NUMBER = [0-9.]+/PROJECT_NUMBER = '$VERSION'/' -i Doxyfile sed 's/.*/'$VERSION'/' -i doc/ccbuild/ccbuild.sgml echo "]]] Update documentation" make -C doc/ccbuild clean make -C doc/ccbuild rm -rf build mkdir -p build awk '/^\s*$/{exit}//{print}' < ChangeLog > build/release.md echo "Version is now $VERSION" git archive --format=tar --prefix=ccbuild-$VERSION/ HEAD | tar -xC build cp -rf doc build/ccbuild-$VERSION cd build tar -czf ccbuild-$VERSION.tar.gz ccbuild-$VERSION ccbuild-2.0.9/src/000077500000000000000000000000001402074776400137315ustar00rootroot00000000000000ccbuild-2.0.9/src/MD5Info/000077500000000000000000000000001402074776400151325ustar00rootroot00000000000000ccbuild-2.0.9/src/MD5Info/MD5Info.cc000066400000000000000000000014071402074776400166440ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "MD5Info.ih" MD5Info::MD5Info() : d_old(), d_new(), d_content() {} MD5Info::~MD5Info() {} ccbuild-2.0.9/src/MD5Info/MD5Info.hh000066400000000000000000000101201402074776400166460ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ #ifndef _MD5Info_H_INCLUDED_ #define _MD5Info_H_INCLUDED_ #include #include #include #include #include "../openmp/lock/lock.hh" namespace bneijt { /**\brief MD5Sum information singleton. Keeps an in memory list of current and last MD5Hashes MD5Info is an interface to the .md5 files in the o directory. The hash filenames are not to be used by other parts of the program. Instead, the filename of the source file (the hash is about) is used and internally translated to the right .md5 filename. The .md5 files contain a list of hashes which is a concatination of the hashes of the file and all it's dependencies. This means that if the file changes, the first 32 characters will change. Whenever a dependecy changes, characters in the latter part of the line will change. */ class MD5Info { static MD5Info *s_instance; /// d_old; ///< A map of filename-hashstring for containing cached information OpenMP::Lock d_oldLock; std::map d_new; ///< A map of filename-hashstring for the new md5sum information OpenMP::Lock d_newLock; /**\brief The cached content hash of the file on disk. */ std::map d_content; OpenMP::Lock d_contentLock; public: /**\brief Get the instance This get instance doesn't require an initialization, it creates a new default class when called uninitialized. \return An instance to the MD5Info singleton */ static MD5Info &getInstance(); /**\brief Delete the instance Unlike most destroy functions, this one is protected against multiple destoys. So calling this function on a already destroyed instance is no problem. */ static void destroy(); /**\brief Return the old, cached information for the given file. This will return the string placed in the configuration file with save. */ std::string const &old(std::string const &filename); ///\brief Return the current hex hash string for the given file std::string const &contentHash(std::string const &filename); /**\brief Save the hash information for the given file on disk now. \param filename The source filename the information is about. \param hash A string containing hash information. */ void save(std::string const &filename, std::string const &hash); /**\brief Returns the path to the hash file of a given filename This function should not be used very often. Currently it's only use is the cleaning part of the program. */ static std::string hashFilenameFor(std::string const &filename); private: ///\brief Load the hash for the given file from the default place void load(std::string const &filename); MD5Info(); ///\brief Destory the cache, saving any memory data to disk ~MD5Info(); ///\brief Not implemented MD5Info(MD5Info const &other); //NI ///\brief Not implemented MD5Info &operator=(MD5Info const &other); //NI }; }//namespace #endif ccbuild-2.0.9/src/MD5Info/MD5Info.ih000066400000000000000000000023631402074776400166610ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ #include "MD5Info.hh" #include "../fileSystem/fileSystem.hh" #include "../system/system.hh" #include "../openmp/scopedLock/scopedLock.hh" #include #include #include #include #include #include #include #include #include #include "../options/options.hh" #include "../misc/foreach.hh" //#define DEBUGLEVEL 6 #include "../misc/debug.hh" #define MD5_DIGEST_LENGTH 16 using namespace bneijt; using namespace std; ccbuild-2.0.9/src/MD5Info/contentHash.cc000066400000000000000000000036131402074776400177220ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "MD5Info.ih" std::string const &MD5Info::contentHash(std::string const &filename) { OpenMP::ScopedLock lock(d_contentLock); if(d_content.count(filename) == 0) { //#define MD5_DIGEST_LENGTH 16 unsigned char md[MD5_DIGEST_LENGTH]; gnutls_hash_hd_t context; gnutls_hash_init (&context, GNUTLS_DIG_MD5); //Start updating with the file content size_t const bufferSize = 1024*512/8; //512-bit block multiple for update char *buffer = new char[bufferSize]; ifstream ifile(filename.c_str()); while(ifile) { ifile.read(buffer, bufferSize); gnutls_hash (context, buffer, ifile.gcount()); } delete[] buffer; gnutls_hash_deinit (context, &md[0]); // gnutls_free (context); char hex_hash[(MD5_DIGEST_LENGTH * 2) + 1]; for(size_t i = 0; i < MD5_DIGEST_LENGTH; ++i) { sprintf(&hex_hash[i*2], "%02x", md[i]); } hex_hash[(MD5_DIGEST_LENGTH * 2)] = '\0'; d_content[filename] = string(&hex_hash[0]); _debugLevel2("Calculated content hash " << filename << " == " << d_content[filename]); } return d_content[filename]; } ccbuild-2.0.9/src/MD5Info/destroy.cc000066400000000000000000000016221402074776400171330ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "MD5Info.ih" void MD5Info::destroy() { OpenMP::ScopedLock instantiateLock(s_instanceLock); if(s_instance) { delete s_instance; } else { _debugLevel1("Already destroyed, but not a problem."); } s_instance = 0; } ccbuild-2.0.9/src/MD5Info/getInstance.cc000066400000000000000000000015431402074776400177100ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "MD5Info.ih" MD5Info &MD5Info::getInstance() { OpenMP::ScopedLock instantiateLock(s_instanceLock); if(s_instance == 0) { s_instance = new MD5Info; } return *s_instance; } ccbuild-2.0.9/src/MD5Info/hashFilenameFor.cc000066400000000000000000000015231402074776400204750ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "MD5Info.ih" std::string MD5Info::hashFilenameFor(std::string const &filename) { return FileSystem::cleanPath(Options::cacheRoot + FileSystem::absolutePath(filename) + ".md5"); } ccbuild-2.0.9/src/MD5Info/load.cc000066400000000000000000000031361402074776400163630ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "MD5Info.ih" void MD5Info::load(std::string const &filename) { OpenMP::ScopedLock oldLock(d_oldLock); //Load a configuration file if it exists std::string const confFile = hashFilenameFor(filename); ifstream file(confFile.c_str()); _debugLevel1("Loading: '" << confFile << "'"); if(!file.is_open()) { _debugLevel1("Unable to open: '" << confFile << "'"); return; } while(file) { //TODO Optimize or extend with extra options string line; string hashInfo; getline(file, line); if(file.eof()) { break; } //Try the next line if there aren't enough characters if(line.size() < 32) { continue; } hashInfo = line; _debugLevel4("Recall: " << hashInfo << " for '" << filename << "'"); d_old[filename] = hashInfo; } file.close(); } ccbuild-2.0.9/src/MD5Info/old.cc000066400000000000000000000021321402074776400162150ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "MD5Info.ih" std::string const &MD5Info::old(std::string const &filename) { d_oldLock.set(); bool available = (d_old.count(filename) > 0); d_oldLock.unset(); //Try to load it from disk if(not available) { load(filename); } OpenMP::ScopedLock lock(d_oldLock); _debugLevel3("Found old content hash: " << d_old[filename]); return d_old[filename]; } ccbuild-2.0.9/src/MD5Info/save.cc000066400000000000000000000025661402074776400164100ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "MD5Info.ih" void MD5Info::save(std::string const &filename, std::string const &hash) { //Save information out of current std::string hashFilename = hashFilenameFor(filename); _debugLevel2("Saving hash information to disk for " << filename << "\n\tto " << hashFilename); d_oldLock.set(); d_old[filename] = hash; d_oldLock.unset(); //Ensure directory FileSystem::ensureDirectory(FileSystem::directoryName(hashFilename)); //Open and write file std::ofstream file(hashFilename.c_str(), ios::trunc); if(!file.is_open()) { cerr << "ccbuild: Warning: Unable to write MD5 info to '" << hashFilename << "'.\n"; return; } file << hash << "\n"; file.close(); } ccbuild-2.0.9/src/MD5Info/statics.cc000066400000000000000000000016021402074776400171120ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "MD5Info.ih" MD5Info *MD5Info::s_instance(0); ///. */ #include "arguments.ih" Arguments::Arguments(Option const *options, int argc, char *argv[]) : d_flags(), d_values(), d_rest(), d_errors(), d_emptyList(), d_empty(""), d_options(options) { //Reset all getOpts extern variables optarg = 0; optind = 0; opterr = 0; optopt = 0; //For the getopts_long options system we need: // A string of single character options, and wether they take arguments // // ostringstream letterFlags(ios::app); //TODO In the future we will count the number of long options before hand, so dynamically allocate this array. struct ::option *longOpts = new ::option[50]; unsigned nlongOpts(0); //Collect options int optionIndex(0); //Although this should be an unsigned, get_longOpts wants an int :-( while(true) { Option const * curOption = &options[optionIndex]; bool hasArgument = false, mustHaveArgument = false; //Done yet?? if(curOption->flags.empty() && curOption->value.empty() && curOption->helpText.empty()) { break; } istringstream givenFlags(string(curOption->flags) + " "); //^^ Needed extra space for eof in while loop below if(curOption->value.length() > 0 && curOption->value[0] != '\0') { mustHaveArgument = curOption->value[0] == '<'; hasArgument = curOption->value[0] == '[' || mustHaveArgument; } //Parse options.. string flag; bool *flagPointer = new bool(false); while(true) { givenFlags >> flag; // cout << "givenFlags: " << givenFlags.str() << "\n"; if(givenFlags.eof()) { break; } if(flag.size() == 1) { d_flags[flag] = flagPointer; letterFlags << flag; if(hasArgument) { letterFlags << ":"; if(!mustHaveArgument) { letterFlags << ":"; } } } else { //Name longOpts[nlongOpts].name = new char[flag.size() +1]; strncpy(const_cast(longOpts[nlongOpts].name), flag.c_str(), flag.size() +1); //What kind of argument is it? longOpts[nlongOpts].has_arg = hasArgument ? optional_argument : no_argument; if(mustHaveArgument) { longOpts[nlongOpts].has_arg = required_argument; } //Return val on match longOpts[nlongOpts].flag = 0; //Give the index of the option +255 as a return value, it will always be above ascii //longOpts[nlongOpts]->val = 255 + nlongOpts; longOpts[nlongOpts].val = 0; //if it's a long option, the index is enough. //Store the flag pointer value d_flags[flag] = flagPointer; ++nlongOpts; } } ++optionIndex; } //Add empty element, superflourisch if newly allocated space contains zeros longOpts[nlongOpts].name = 0; longOpts[nlongOpts].has_arg = 0; longOpts[nlongOpts].flag = 0; longOpts[nlongOpts].val = 0; //++nlongOpts; #if DEBUGLEVEL > 3 _debugLevel3("Flags " << letterFlags.str()); _debugLevel3("nlongOpts " << nlongOpts); for(unsigned i=0; i < nlongOpts; ++i) { cerr << i << ")\tName " << longOpts[i].name << "\n"; cerr << "\tHasArg " << longOpts[i].has_arg << "\n"; cerr << "\tVal " << longOpts[i].val << "\n"; cerr << "\tFlag " << longOpts[i].flag << "\n"; cerr << "\n"; } _debugLevel3("Shortopts: \"" << letterFlags.str() << "\""); #endif // // Run the options through getopt_long and collect them in vectors // ::opterr = 0; //Don't report errors on stderr //The extra byte below this is just a precaution // for systems where the sizeof(char) == sizeof(int) :-S char *flagVal = new char[sizeof(int) +1]; string optionCharacter(" "); while(true) { int c = getopt_long(argc, argv, letterFlags.str().c_str(), longOpts, &optionIndex); if(c == -1) { break; } bool *flagPointer; switch(c) { case 0: //Long options flagPointer = d_flags[longOpts[optionIndex].name]; *flagPointer = true; if(::optarg) { d_values[flagPointer].push_back(::optarg); } break; case '?': _debugLevel4("Case ?"); _debugLevel4("optarg: " << (optarg ? optarg : "")); _debugLevel4("optind: " << optind << " optopt: " << optopt); if(optopt || optind < 1 || optind > argc) { optionCharacter[0] = optopt; d_errors.push_back(optionCharacter); } else { d_errors.push_back(argv[optind -1]); } break; case ':': _debugLevel4("Case :"); _debugLevel4("optarg: " << optarg); _debugLevel4("optind: " << optind << " optopt: " << optopt); optionCharacter[0] = optopt; d_errors.push_back(optionCharacter); break; default: //Short options flagVal[0] = static_cast(c); flagVal[1] = '\0'; _debugLevel2("OK on short option: '" << flagVal << "'"); flagPointer = d_flags[flagVal]; *flagPointer = true; if(::optarg) { d_values[flagPointer].push_back(::optarg); } } } //Get the rest of the options for(; ::optind < argc; ++(::optind)) { d_rest.push_back(argv[::optind]); } //Test code /* cout << "Arguments done\n"; _foreach(s, d_rest) cout << "\t" << *s << "\n"; */ //Free the memory for(unsigned i = 0; i < nlongOpts; ++i) if(longOpts[i].name) { delete[] longOpts[i].name; } //Delete arrays delete[] flagVal; delete[] longOpts; } Arguments::~Arguments() { //Free by deleting all boolean pointers //Reduce memory usage clear(); } ccbuild-2.0.9/src/arguments/arguments.hh000066400000000000000000000134361402074776400202730ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ //Arguments list singleton. There to make sure we only load Arguments once #ifndef arguments_H_INCLUDED #define arguments_H_INCLUDED #include #include #include #include #include "../openmp/lock/lock.hh" namespace bneijt { /** \brief Arguments singleton. Gives simple access to the give program arguments First initialize the singleton with options and the commandline arguments. Arguments can be tested using the functions flagged, value and rest. Options should be a 3xN array of character pointers, ending in {0,0,0}. Options are defined with: {"flagges and long names, space seperated", "valuename, if any", "Help text explaning what the option is."} WARNING: Arguments only supports up to 39 long options currently! See the TODO in Arguments.cc \section example Example of use \code #include "Arguments/Arguments.hh" #include #include int main(int argc, char *argv[]) { using namespace bneijt; using namespace std; Arguments::Option options[] = { {"f force-update", "", "Force an update"}, {"a add", "", "Add something to a list"}, {"b", "[maybe]", "Force an update"}, {0, 0, 0} }; Arguments::initialize(options, argc, argv); Arguments &args = Arguments::getInstance(); if(args.flagged("a")) cout << "Add: " << args.value("a") <<"\n"; if(args.errors().size() > 0) { vector &err = args.errors(); foreach(e, err) { cout << "ERROR: " << (*e) << "\n"; } } if(args.rest().size() > 0) { vector &err = args.rest(); foreach(e, err) { cout << "REST: " << (*e) << "\n"; } } args.destroy(); //Destroy the instance. return 0; } \endcode */ class Arguments { std::map d_flags; /// d_value; /// > d_values; /// d_rest; /// d_errors; /// d_emptyList; ///" for required, "[value]" for optional. std::string helpText; ///< The help text, describing this option. This is used when generating the help output. }; ///\brief Initialize the singleton with options and argv, argc /// /// static void initialize(Option const *options, int argc, char *argv[]); ///\brief Get the instance of the Arguments class. Use this only after initializing it. static Arguments &getInstance(); ///\brief Return true when an option if flagged, false otherwise. bool flagged(std::string const &optionName) const; ///\brief Returns the argument of an option or an empty string. std::string value(std::string const &optionName) const; ///\brief Returns the argument of an option or an empty string. std::vector const &values(std::string const &optionName) const; ///\brief Returns a vector containing all the remaining commandline options. std::vector &rest() { return d_rest; } ///\brief Returns a vector containing all the commanline options generating errors. std::vector &errors() { return d_errors; } ///\brief Delete the instance. Use this only if you aren't going to use the Arguments class instance. static void destroy(); ///\brief Output a list of the flags and help information onto the given stream. void outputOptions(std::ostream &stream) const; private: Option const *d_options; ///< A pointer to the options used to initialize the Arguments class ///\brief Clear the class, clearing all vectors and freeing pointers. void clear(); ///\brief Parse the argc and argv using the given options Arguments(Option const *options, int argc, char *argv[]); ~Arguments(); ///\brief Not implemented Arguments(Arguments const &other); //NI ///\brief Not implemented Arguments &operator=(Arguments const &other); //NI }; }//namespace #endif ccbuild-2.0.9/src/arguments/arguments.ih000066400000000000000000000022201402074776400202610ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ #include "arguments.hh" #include #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include #include #include #include #include #include "../openmp/scopedLock/scopedLock.hh" //#define DEBUGLEVEL 1 #include "../misc/debug.hh" #include "../misc/foreach.hh" using namespace std; using namespace bneijt; ccbuild-2.0.9/src/arguments/clear.cc000066400000000000000000000021471402074776400173370ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "arguments.ih" void Arguments::clear() { //Reduce memory usage std::set pointerList; //std::map d_flags; __foreach(flag, d_flags) pointerList.insert((*flag).second); //std::map d_value; __foreach(flag, d_values) pointerList.insert((*flag).first); //Kill all boolean pointers __foreach(p, pointerList) delete *p; d_rest.clear(); d_errors.clear(); } ccbuild-2.0.9/src/arguments/destroy.cc000066400000000000000000000016031402074776400177360ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "arguments.ih" void Arguments::destroy() { OpenMP::ScopedLock instantiateLock(s_instanceLock); if(s_instance) { delete s_instance; } else { _debugLevel1("Already destroyed!!"); } s_instance = 0; } ccbuild-2.0.9/src/arguments/flagged.cc000066400000000000000000000020321402074776400176330ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "arguments.ih" bool Arguments::flagged(std::string const &optionName) const { //The options are there, return the value if it is (which it is, because of arguments. But we still want to be const) map::const_iterator flag = d_flags.find(optionName); if(flag != d_flags.end() && (*flag).second) { return *((*flag).second); } return false; } ccbuild-2.0.9/src/arguments/getInstance.cc000066400000000000000000000013521402074776400205120ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "arguments.ih" Arguments &Arguments::getInstance() { return *s_instance; } ccbuild-2.0.9/src/arguments/initialize.cc000066400000000000000000000015231402074776400204070ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "arguments.ih" void Arguments::initialize(Option const *options, int argc, char *argv[]) { Arguments::destroy(); s_instance = new Arguments(options, argc, argv); return; } ccbuild-2.0.9/src/arguments/outputOptions.cc000066400000000000000000000056071402074776400211710ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "arguments.ih" void Arguments::outputOptions(ostream &str) const { int optionIndex(0); //Although this should be an unsigned, get_longOpts wants an int :-( char spacer[32]; memset(&spacer[0], ' ', sizeof(spacer)); spacer[sizeof(spacer) -1] = '\0'; unsigned spacerLen = strlen(spacer); string flag; while(true) { Option const * curOption = &d_options[optionIndex]; if(curOption->flags.empty() && curOption->value.empty() && curOption->helpText.empty()) { break; } istringstream givenFlags(string(curOption->flags) + " "); //Needed extra space for eof in while loop below bool first = true; unsigned alreadyOut = 0; while(true) { givenFlags >> flag; if(givenFlags.eof()) { break; } if(flag.size() == 1) { str << (first ? " " : ", ") << "-" << flag; alreadyOut += (first ? 2 : 3); } else { str << (first ? " " : ", ") << "--" << flag; alreadyOut += (first ? 3 : 4); } alreadyOut += flag.size(); first = false; } str << " "; ++alreadyOut; if(curOption->value.length() > 0) { str << curOption->value; alreadyOut += curOption->value.length(); } if(alreadyOut < spacerLen) { spacer[spacerLen - alreadyOut] = '\0'; str << spacer; spacer[spacerLen - alreadyOut] = ' '; } if(curOption->helpText.length() > 0) { istringstream helpText(string(curOption->helpText) + " "); unsigned maxLen = 79 - spacerLen; unsigned len = 0; string word; while(true) { helpText >> word; if(helpText.eof()) { break; } len += word.size(); if(len > maxLen) { str << "\n " << spacer; len = 0; } else { str << " "; ++len; } str << word; } } str << "\n"; ++optionIndex; } } ccbuild-2.0.9/src/arguments/statics.cc000066400000000000000000000014211402074776400177150ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "arguments.ih" Arguments *Arguments::s_instance(0); OpenMP::Lock Arguments::s_instanceLock; ///. */ #include "arguments.ih" namespace { std::string const spaceAdd(std::string const &rvalue, std::string const &lvalue) { _debugLevel4("rvalue.size=" << rvalue.size() << " lvalue.size=" << lvalue.size()); if(rvalue.size() > 0 && lvalue.size() > 0) { return rvalue + " " + lvalue; } return rvalue + lvalue; } } std::string Arguments::value(std::string const &optionName) const { map::const_iterator fi = d_flags.find(optionName); if(fi == d_flags.end()) { return d_empty; } map >::const_iterator vi = d_values.find((*fi).second); if(vi != d_values.end()) { return accumulate((*vi).second.begin(), (*vi).second.end(), string(""), spaceAdd); } else { return d_empty; } } ccbuild-2.0.9/src/arguments/values.cc000066400000000000000000000021341402074776400175440ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "arguments.ih" std::vector const &Arguments::values(std::string const &optionName) const { map::const_iterator fi = d_flags.find(optionName); if(fi == d_flags.end()) { return d_emptyList; } map >::const_iterator vi = d_values.find((*fi).second); if(vi != d_values.end()) { return (*vi).second; } else { return d_emptyList; } } ccbuild-2.0.9/src/ccResolutions000066400000000000000000000014701402074776400165120ustar00rootroot00000000000000#& --args "-std=c++17 -p -Wall -Werror -pg -g -Wstrict-null-sentinel -Wformat -Wformat-security -Wwrite-strings -DVERSION=\\\"0.0.1-dev\\\" -fstack-protector --param=ssp-buffer-size=4" #Left out -Wconversion and -pedantic because of the ugly yylex.cc # This file now requires ccbuild > 1.5.7 # Some options have no resolution, they should # be installed on any POSIX Linux system and don't # require extra options, for example: Flex, GNU GetOpt FlexLexer.h getopt.h errno.h glob.h pwd.h inttypes.h sys/stat.h sys/time.h sys/types.h unistd.h omp.h -fopenmp -lgomp sys/utsname.h features.h stddef.h boost/circular_buffer.hpp boost/lexical_cast.hpp openssl/evp.h `pkg-config --libs --cflags openssl` bobcat/process -lbobcat gnutls/crypto.h -lgnutls gnutls/gnutls.h -lgnutls boost/numeric/conversion/cast.hpp ccbuild-2.0.9/src/ccbuild.cc000066400000000000000000000373571402074776400156640ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ #include "problem/problem.hh" #include "system/system.hh" #include "source/source.hh" #include "fileSystem/fileSystem.hh" #include "globallocks/globallocks.hh" #include "misc/foreach.hh" #include "options/options.hh" //Singletons... #include "arguments/arguments.hh" #include "sources/sources.hh" #include "MD5Info/MD5Info.hh" #include #include #include #include #include #include #include #include //#define DEBUGLEVEL 20 #include "misc/debug.hh" using namespace bneijt; using namespace std; namespace { /** Temporary solution, this will probably go away and arguments will be handled as as vector arg(argv[0], argv[argc -1]); Which will remove the need for this weird class. (Wanted to call this Apoptosis, but ArgsDestory seemed more readable ;-) ) //TODO Cleanup with auto_ptr if possible */ class ArgsDestroy { char **d_argv; unsigned d_argc; public: ArgsDestroy() : d_argv(0), d_argc(0) {} ArgsDestroy(ArgsDestroy const & o);//NI ArgsDestroy operator=(const ArgsDestroy&);//NI void set(unsigned argc, char *argv[]) { assert(argc > 0); d_argc = argc; d_argv = argv; } ~ArgsDestroy() { for(unsigned i = 0; i < d_argc; ++i) { delete[] d_argv[i]; } if(d_argv) { delete[] d_argv; } } }; }//namespace /** The main program function: call argument parser and go through the commands using a large if-then-else block. */ int main(int argc, char **argv) try { //See Options/statics.cc Options::CC = "g++"; //See Options/statics.cc Options::version = "..."; Arguments::Option options[] = { {"f force-update", "", "Force an update of everything"}, {"h help", "", "Get this help message"}, {"gnutouch", "", "Do the GNU touch (NEWS, README, etc.)"}, {"s no-act", "", "Simulate, don't execute any writing commands"}, {"compiler", "", "Set the compiler command (Default: g++)"}, {"a args", "", "Use these as base compiler arguments (Default: -Wall -g)"}, {"C", "", "Change directory before anything else"}, {"cachedir", "", "Set the path of the object/metadata cache directory (Default: o)"}, {"p precompile-ih", "", "Precompile only internal headers (g++-3.4 up)"}, {"precompile-all", "", "Precompile all headers (g++-3.4 up)"}, {"brute", "", "Continue on compiler errors"}, {"md5", "", "Use md5 hashes instead or timestamps to check for file changes"}, {"I", "", "Add path to local include search paths"}, {"recursive-include", "", "Like -I but recursive"}, {"l highlight", "", "Colour command output"}, {"xof exec-on-fail", "", "Execute this command on source on failure"}, {"xop exec-on-pass", "", "Execute this command on source on success"}, {"clearpc", "", "Clear the screen just before every command"}, {"append", "", "Append this to every command (for pipes etc.)"}, {"loop", "", "Loop ccbuild execution (build only)."}, {"nodefargs", "", "Don't load extra arguments from ./ccResolutions"}, {"nodefres", "", "Don't load any ccResolutions files but ./ccResolutions"}, {"addres", "", "Also load this resolution file"}, {"pversion", "", "Set the program version you are working on (used by the lib command)"}, {"ar", "", "Archive before link (can shrink size for release)"}, {"verbose", "", "Show executed commands and produce more output for dot and check commands"}, {"V version", "", "Output ccbuild version number to stdout"}, {"xml", "", "Where supported, produce XML output"}, {"nowarn", "", "Leave out most warnings"}, {"batch", "", "Batch multiple source files into one g++ statement (very experimental, may not work with -I yet)"}, #ifdef _OPENMP {"j", "", "Set the maximum number of threads used during build"}, #endif {"", "", ""} //End of list }; int retValue = 0; //First find C option and change directory before anything else Arguments::initialize(options, argc, argv); Arguments &tempArg = Arguments::getInstance(); bool defargs = !tempArg.flagged("nodefargs"); if(tempArg.flagged("C")) if(!System::changeTo(tempArg.value("C"))) { throw Problem(Problem::Unable, "Unable to change dir to '" + tempArg.value("C") + "'"); } tempArg.destroy(); //Check for extra options on the start of our ccResolutions files ArgsDestroy a; if(defargs) if(System::addArguments(argc, argv)) { a.set(argc, argv); //set self destuctor } Arguments::initialize(options, argc, argv); Arguments &arg = Arguments::getInstance(); bool destroy = System::parseArguments(arg); if(Options::showCommands) { cerrLock.set(); cerr << "Command:"; for(int i = 0; i < argc; i++) { if(index(argv[i], ' ') || strlen(argv[i]) == 0) { cerr << " \"" << argv[i] << "\""; } else { cerr << " " << argv[i]; } } cerr << "\n"; cerrLock.unset(); } if(destroy) { System::destroy(); return 1; } if(arg.flagged("gnutouch")) { cerr << "[gnutouch]\n"; string offset; string cwd = FileSystem::cwd(); //Are we in the src directory? if(cwd.size() > 3 && cwd.substr(cwd.size() - 3) == "src") { offset = "../"; } //Are we being fooled?? if(FileSystem::fileExists("./src")) { offset = ""; } string gnufiles[] = {"AUTHORS", "NEWS", "README", "INSTALL", "COPYING", "TODO", "ChangeLog"}; for(unsigned i = 0; i < 7; ++i) { cerr << "[TOUCH] " << offset << gnufiles[i]; if(!Options::simulate) if(! FileSystem::touch(offset + gnufiles[i])) { cerr << " Failed !"; } cerr << "\n"; } } vector &rest = arg.rest(); if(rest.size() == 0) { cerr << "Implicit build\n"; rest.push_back("build"); } else if(rest.size() == 1 && FileSystem::fileExists(*rest.begin(), /*noDir=*/true)) { cerr << "Implicit build because first and only command is a file\n"; rest.insert(rest.begin(), "build"); } Sources &sources = Sources::getInstance(); bool skipArgument(false); __foreach(argument, rest) { vector::iterator next = argument; ++next; if(skipArgument) { skipArgument = false; continue; } if(*argument == "icmake") { cerr << "[" << *argument << "]\n"; if(next == rest.end()) { System::icmake(); } else { Source *s = sources[*next]; if(s) { skipArgument = true; System::icmake(s); } else { cerr << "Error loading '" << *next << "' for status checking.\n"; retValue = 2; break; } } retValue = 0; break; } else if(*argument == "check") { cerr << "[" << *argument << "]\n"; if(next == rest.end()) { System::check(); } else { Source *s = sources[*next]; if(s) { skipArgument = true; System::check(s); } else { cerr << "Error loading '" << *next << "' for status checking.\n"; retValue = 2; break; } } retValue = 0; break; } else if(*argument == "resolve") { cerr << "[" << *argument << "]\n"; if(next == rest.end()) { System::resolveTest(cout); } else { Source *s = sources[*next]; if(s) { skipArgument = true; System::resolveTest(s, cout); } else { cerr << "Error loading '" << *next << "' for status checking.\n"; retValue = 2; break; } } } else if(*argument == "build") { bool loop = arg.flagged("loop"); do { //Because we might destroy the instance, we need a new version cerr << "[" << *argument << "]\n"; if(next == rest.end()) { System::buildAll(); } else { Source *s = sources[*next]; if(s) { skipArgument = true; System::build(s); } else { cerr << "Error loading '" << *next << "' for building.\n"; retValue = 2; break; } } //Remove stale sources if(loop) { sources.reloadStaleSources(); //Restart all hash knowledge MD5Info::destroy(); cerr << "ccbuild: Loop mode: Press return to continue or q to exit..." << endl; string tmp; getline(cin, tmp); if(tmp == "q") { cerr << "ccbuild: breaking loop on 'q'\n"; break; } } /*Full reload, if(loop) { Sources::destroy(); MD5Cache::destroy(); cerr << "Loop sleep 1 second"; System::sleep(1); cerr << ".\n"; }*/ } while(loop); } else if(*argument == "clean") { cerr << "[" << *argument << "]\n"; if(next == rest.end()) { System::clean(); } else { Source *s = sources[*next]; if(s) { skipArgument = true; System::clean(s); } else { cerr << "Error loading '" << *next << "' for cleaning.\n"; retValue = 2; break; } } retValue = 0; break; } else if(*argument == "deps") { cerr << "[" << *argument << "]\n"; if(next == rest.end()) { System::depsFor(cout); } else { Source *s = sources[*next]; if(s) { skipArgument = true; System::depsFor(s, cout); } else { cerr << "Error loading '" << *next << "' for dependencie listing.\n"; retValue = 2; break; } } retValue = 0; break; } else if(*argument == "makefile") { cerr << "[" << *argument << "]\n"; if(next == rest.end()) { System::makefileForAll(cout); } else { Source *s = sources[*next]; if(s) { skipArgument = true; System::makefileFor(s, cout); } else { cerr << "Error loading '" << *next << "' for Makefile generation.\n"; retValue = 2; break; } } retValue = 0; break; } else if(*argument == "aap") { cerr << "[" << *argument << "]\n"; if(next == rest.end()) { System::aapForAll(cout); } else { Source *s = sources[*next]; if(s) { skipArgument = true; System::aapFor(s, cout); } else { cerr << "Error loading '" << *next << "' for A-A-P generation.\n"; retValue = 2; break; } } retValue = 0; break; } else if(*argument == "md5") { cerr << "[" << *argument << "]\n"; if(next == rest.end()) { System::md5(); } else { Source *s = sources[*next]; if(s) { skipArgument = true; System::md5(s); } else { cerr << "Error loading '" << *next << "' for MD5 list generation.\n"; retValue = 2; break; } } retValue = 0; break; } else if(*argument == "dot") { cerr << "[" << *argument << "]\n"; if(next == rest.end()) { System::dotgraphForAll(); } else { Source *s = sources[*next]; if(s) { skipArgument = true; System::dotgraphFor(s, cout); } else { cerr << "Error loading '" << *next << "' for graphing.\n"; retValue = 2; break; } } retValue = 0; break; } else if(*argument == "lib") { if(Options::progVersion.empty()) { cerr << "[" << *argument << " (archive only)]\n"; } else { cerr << "[" << *argument << " " << Options::progVersion << "]\n"; } if(next == rest.end()) { retValue = System::lib(Options::progVersion); } else { Source *s = sources[*next]; if(s) { skipArgument = true; retValue = System::lib(Options::progVersion, s); } else { cerr << "Error loading '" << *next << "' for library building.\n"; retValue = 2; break; } } break; } else if(*argument == "distclean") { cerr << "[" << *argument << "]\n"; System::distclean(); } else { throw Problem(Problem::Unknown, "Unknown command: " + *argument +"\n Try '" + argv[0] + " -h' for more information.\n"); } } //Cleanup and exit //Destroy singletons... System::destroy(); return retValue; } catch(const bneijt::Problem &p) { cerr << "ccbuild: Problem " << p.id() << ": " << p.what() << "\n"; System::destroy(); return p.id(); } catch(const std::exception &e) { //All is LOST... nothing to do here but die cerr << "Caught std::exception (" << typeid(e).name() << "): " << e.what(); cerr << "\nPlease report this as a bug.\n"; return 1; } ccbuild-2.0.9/src/compiler/000077500000000000000000000000001402074776400155435ustar00rootroot00000000000000ccbuild-2.0.9/src/compiler/addArgument.cc000066400000000000000000000037241402074776400203130ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ //See GNU manual for options: http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options #include "compiler.ih" void Compiler::addArgument(std::string argument) { _debugLevel4("Starting (" << argument << ")"); //String split the argument by spaces vector arguments; _debugLevel4("Split"); splitInto(argument, arguments); _debugLevel4("Parse"); //Parse arguments while(true) { unsigned count = countFirstLinkerArguments(arguments); //Move those arguments to the linker options list while(count--) { //Never add multiple arguments of the same value if(find(d_link.begin(), d_link.end(), arguments.front()) == d_link.end()) { d_link.push_back(arguments.front()); } arguments.erase(arguments.begin()); _debugLevel3("Linker opt: " << d_link.back()); } //EOF if(arguments.size() == 0) { break; } //Move this argument to the normal compilation argument list. //Never add multiple arguments of the same value if(find(d_compile.begin(), d_compile.end(), arguments.front()) == d_compile.end()) { d_compile.push_back(arguments.front()); } arguments.erase(arguments.begin()); } _debugLevel4("End"); } ccbuild-2.0.9/src/compiler/addObject.cc000066400000000000000000000016301402074776400177310ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "compiler.ih" void Compiler::addObject(std::string objFilename) { if(find(d_objects.begin(), d_objects.end(), objFilename) == d_objects.end()) { d_objects.push_back(objFilename); } } ccbuild-2.0.9/src/compiler/ar.cc000066400000000000000000000027771402074776400164710ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "compiler.ih" int Compiler::ar(std::string target) const { //Construct ar command // ar [--plugin name] [-X32_64] [-]p[mod [relpos] [count]] archive [member...] ostringstream command("ar qcs ", ios::ate); command << " " << target; __foreach(obj, d_objects) command << " \"" << (*obj) << "\""; cls(); //Remove the output file FileSystem::rmIfExists(target); cerrLock.set(); cerr << "[AR] " << target << "\n"; cerrLock.unset(); //Run ar command int retValue = System::system(command.str().c_str()); if(retValue != 0) { cerrLock.set(); cerr << "ccbuild: Non zero exit status (" << retValue << ")\n"; cerrLock.unset(); if(!Options::brute) { throw Problem(Problem::Subfailure, "Ar failed to create " + target, retValue); } } return retValue; } ccbuild-2.0.9/src/compiler/cls.cc000066400000000000000000000015111402074776400166310ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "compiler.ih" void Compiler::cls() const { if(Options::clearPerCommand) { cout << s_clear << flush; } } ccbuild-2.0.9/src/compiler/compile.cc000066400000000000000000000035721402074776400175110ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "compiler.ih" int Compiler::compile(std::string target, std::string outputFile) const { cls(); cerrLock.set(); cerr << "[CC] " << target << "\n"; cerrLock.unset(); assert(target != outputFile); string command = compileCommand(target, outputFile); //If possible fork this... if(Options::optino("numThreadsLeft") > 0) fork exit(system) int retValue = System::system(command); if(retValue != 0) { cerrLock.set(); cerr << "ccbuild: Non zero exit status (" << retValue << ")\n"; cerrLock.unset(); if(!Options::execOnFail.empty()) { System::system((Options::execOnFail + " \"" + target + "\"").c_str()); } if(!Options::brute) { throw Problem(Problem::Subfailure, "Compilation failed on " + target, retValue); } //Remove the output file, to make sure linking fails FileSystem::rmIfExists(outputFile); } else if(!Options::execOnPass.empty()) { System::system((Options::execOnPass + " \"" + target + "\"").c_str()); } //TODO retValue is always 0, thus meaningless because of exceptions. return retValue; } ccbuild-2.0.9/src/compiler/compileCommand.cc000066400000000000000000000030251402074776400210010ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "compiler.ih" string Compiler::compileCommand(std::string target, std::string outputFile) const { ostringstream command(d_baseCommand, ios::ate); command << " " << Options::extraArgs << " -c "; copy(d_compile.begin(), d_compile.end(), ostream_iterator(command, " ")); command << "-o \"" << outputFile << "\" \"" << target << "\" "; command << Options::commandAppend; return command.str(); } std::string Compiler::compileCommand(std::vector const &targets) const { ostringstream command(d_baseCommand, ios::ate); command << " " << Options::extraArgs << " -c "; copy(d_compile.begin(), d_compile.end(), ostream_iterator(command, " ")); __foreach(target, targets) command << " \"" << (*target) << "\""; command << Options::commandAppend; return command.str(); } ccbuild-2.0.9/src/compiler/compiler.hh000066400000000000000000000156251402074776400177070ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ #ifndef Compiler_H_INCLUDED_ #define Compiler_H_INCLUDED_ #include #include #include "../options/options.hh" namespace bneijt { ///\brief A compiler wrapping class /// ///This class is a wrapper for the compiler. All functionality of the compiler is ///is, as needed, reflected by functions in this class. ///It also keeps track of any additional compiler arguments "currently" needed. /// ///When cleaning a system, this Compiler's interface is overloaded with the Cleaner class, which issues the unlink command on the output files for all the objects. class Compiler { std::string d_baseCommand; /// d_objects; /// d_compile; /// d_link; /// const& targets ) const; ///\brief Return the command used to link all the objects to a file std::string linkCommand(std::string pwd,/// const & linkArguments() const { return d_link; } ///\brief Return the arguments used for compilation (also used while linking) std::vector const & compileArguments() const { return d_compile; } ///\brief Remove all compile-time arguments of the compiler void rmCompileOptions() { d_compile.clear(); } ///\brief Return the map containing all the objects. std::vector const &objects() const { return d_objects; } ///\brief Clear the list of objects used at link-time void rmObjects() { d_objects.clear(); } private: /**\brief Return the number of linker arguments at the beginning of the given list \return The number of arguments which are linker arguments. */ unsigned countFirstLinkerArguments(std::vector &arguments) const; /**\brief Split an arguments list into it's arguments This will split the arguments given in argument into the vector. It tries to combine all arguments with quoated values. */ void splitInto(std::string argument, std::vector &arguments) const; /** \brief Clear the screen if needed according to options */ void cls() const; }; } //namespace #endif ccbuild-2.0.9/src/compiler/compiler.ih000066400000000000000000000024421402074776400177010ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ #include "compiler.hh" //#include //System #include #include #include #include #include #include #include #include //Timeofday #include #include #include "../options/options.hh" #include "../fileSystem/fileSystem.hh" #include "../system/system.hh" #include "../problem/problem.hh" #include "../globallocks/globallocks.hh" //#define DEBUGLEVEL 5 #include "../misc/debug.hh" #include "../misc/foreach.hh" using namespace std; using namespace bneijt; ccbuild-2.0.9/src/compiler/countFirstLinkerArguments.cc000066400000000000000000000254451402074776400232570ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "compiler.ih" namespace { bool startsWith(std::string const &a, std::string const &b) { //Return whether a starts with b if(a.size() < b.size()) { return false; } return a.compare(0, b.length(), b) == 0; } }//namespace unsigned Compiler::countFirstLinkerArguments(std::vector &arguments) const { //Add argument taking linker options here, flags below //The following options take an argument: char const* takeArg[] = { "-Wl," //-Wl,option ,"-Xlinker" ,"-u" ,"-L" ,"-l" // ,"" ,0 }; //The following options are simple flags char const *flag[] = { "-nostartfiles" ,"-nodefaultlibs" ,"-nostdlib" ,"-pie" ,"-s" ,"-static" ,"-static-libgcc" ,"-shared" ,"-shared-libgcc" ,"-symbolic" ,"-rdynamic" // ,"-threads" // ,"-pthreads" // ,"" // ,"" ,0 }; //TODO optimize: arguments.size() test is possibly not necessary in nested for loop unsigned count(0); for(; count < arguments.size(); ++count) { bool found = false; //If one of the takeArg is found, count++ for(unsigned i = 0; count < arguments.size() && takeArg[i]; ++i) if(startsWith(arguments[count], takeArg[i])) { _debugLevel2("Found: '" << takeArg[i] << "'"); //If the argument is not attached to the flag if(arguments[count].size() == strlen(takeArg[i])) { ++count; } found = true; break; } //Go for the next one if(found) { continue; } //The flags for(unsigned i = 0; count < arguments.size() && flag[i]; ++i) if(arguments[count] == flag[i]) { found = true; break; } if(!found) { break; } } //If not any argument, break _debugLevel2("Stopped at: '" << (count < arguments.size() ? arguments[count] : "THE END" ) << "' counting " << count); return count; } /* DOCUMENTATION VALUES All added options are surrounded by parentheses From commandline: Linker Options (-llibrary) (-nostartfiles) (-nodefaultlibs) (-nostdlib) (-pie) (-s) (-static) (-static-libgcc) (-shared) (-shared-libgcc) (-symbolic) (-Wl,option) (-Xlinker option) (-u symbol) Directory Options -Bprefix -Idir -iquotedir (-Ldir) -specs=file -I- From: GNU manual for options: http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options 3.13 Options for Linking These options come into play when the compiler links object files into an executable output file. They are meaningless if the compiler is not doing a link step. object-file-name A file name that does not end in a special recognized suffix is considered to name an object file or library. (Object files are distinguished from libraries by the linker according to the file contents.) If linking is done, these object files are used as input to the linker. -c -S -E If any of these options is used, then the linker is not run, and object file names should not be used as arguments. See Overall Options. (-llibrary) (-l library) Search the library named library when linking. (The second alternative with the library as a separate argument is only for POSIX compliance and is not recommended.) It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, `foo.o -lz bar.o' searches library `z' after file foo.o but before bar.o. If bar.o refers to functions in `z', those functions may not be loaded. The linker searches a standard list of directories for the library, which is actually a file named liblibrary.a. The linker then uses this file as if it had been specified precisely by name. The directories searched include several standard system directories plus any that you specify with (-L). Normally the files found this way are library files—archive files whose members are object files. The linker handles an archive file by scanning through it for members which define symbols that have so far been referenced but not defined. But if the file that is found is an ordinary object file, it is linked in the usual fashion. The only difference between using an (-l) option and specifying a file name is that (-l) surrounds library with `lib' and `.a' and searches several directories. -lobjc You need this special case of the (-l) option in order to link an Objective-C or Objective-C++ program. -nostartfiles Do not use the standard system startup files when linking. The standard system libraries are used normally, unless -nostdlib or (-nodefaultlibs) is used. -nodefaultlibs Do not use the standard system libraries when linking. Only the libraries you specify will be passed to the linker. The standard startup files are used normally, unless -nostartfiles is used. The compiler may generate calls to memcmp, memset, memcpy and memmove. These entries are usually resolved by entries in libc. These entry points should be supplied through some other mechanism when this option is specified. (-nostdlib) Do not use the standard system startup files or libraries when linking. No startup files and only the libraries you specify will be passed to the linker. The compiler may generate calls to memcmp, memset, memcpy and memmove. These entries are usually resolved by entries in libc. These entry points should be supplied through some other mechanism when this option is specified. One of the standard libraries bypassed by -nostdlib and -nodefaultlibs is libgcc.a, a library of internal subroutines that GCC uses to overcome shortcomings of particular machines, or special needs for some languages. (See Interfacing to GCC Output, for more discussion of libgcc.a.) In most cases, you need libgcc.a even when you want to avoid other standard libraries. In other words, when you specify -nostdlib or -nodefaultlibs you should usually specify -lgcc as well. This ensures that you have no unresolved references to internal GCC library subroutines. (For example, `__main', used to ensure C++ constructors will be called; see collect2.) (-pie) Produce a position independent executable on targets which support it. For predictable results, you must also specify the same set of options that were used to generate code (-fpie, -fPIE, or model suboptions) when you specify this option. (-rdynamic) Pass the flag -export-dynamic to the ELF linker, on targets that support it. This instructs the linker to add all symbols, not only used ones, to the dynamic symbol table. This option is needed for some uses of dlopen or to allow obtaining backtraces from within a program. (-s) Remove all symbol table and relocation information from the executable. (-static) On systems that support dynamic linking, this prevents linking with the shared libraries. On other systems, this option has no effect. (-shared) Produce a shared object which can then be linked with other objects to form an executable. Not all systems support this option. For predictable results, you must also specify the same set of options that were used to generate code (-fpic, -fPIC, or model suboptions) when you specify this option.1 (-shared-libgcc) (-static-libgcc) On systems that provide libgcc as a shared library, these options force the use of either the shared or static version respectively. If no shared version of libgcc was built when the compiler was configured, these options have no effect. There are several situations in which an application should use the shared libgcc instead of the static version. The most common of these is when the application wishes to throw and catch exceptions across different shared libraries. In that case, each of the libraries as well as the application itself should use the shared libgcc. Therefore, the G++ and GCJ drivers automatically add -shared-libgcc whenever you build a shared library or a main executable, because C++ and Java programs typically use exceptions, so this is the right thing to do. If, instead, you use the GCC driver to create shared libraries, you may find that they will not always be linked with the shared libgcc. If GCC finds, at its configuration time, that you have a non-GNU linker or a GNU linker that does not support option --eh-frame-hdr, it will link the shared version of libgcc into shared libraries by default. Otherwise, it will take advantage of the linker and optimize away the linking with the shared version of libgcc, linking with the static version of libgcc by default. This allows exceptions to propagate through such shared libraries, without incurring relocation costs at library load time. However, if a library or main executable is supposed to throw or catch exceptions, you must link it using the G++ or GCJ driver, as appropriate for the languages used in the program, or using the option -shared-libgcc, such that it is linked with the shared libgcc. (-symbolic) Bind references to global symbols when building a shared object. Warn about any unresolved references (unless overridden by the link editor option `-Xlinker -z -Xlinker defs'). Only a few systems support this option. (-Xlinker option) Pass option as an option to the linker. You can use this to supply system-specific linker options which GCC does not know how to recognize. If you want to pass an option that takes an argument, you must use -Xlinker twice, once for the option and once for the argument. For example, to pass -assert definitions, you must write `-Xlinker -assert -Xlinker definitions'. It does not work to write -Xlinker "-assert definitions", because this passes the entire string as a single argument, which is not what the linker expects. (-Wl,option) Pass option as an option to the linker. If option contains commas, it is split into multiple options at the commas. (-u symbol) Pretend the symbol symbol is undefined, to force linking of library modules to define it. You can use -u multiple times with different symbols to force loading of additional library modules. */ ccbuild-2.0.9/src/compiler/lib.cc000066400000000000000000000043331402074776400166230ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "compiler.ih" int Compiler::lib(std::string outputFile, std::string const &version) const { cls(); cerrLock.set(); cerr << "[LIB] " << outputFile << "." << version << "\n"; cerrLock.unset(); string command = libCommand(outputFile + "." + version); int retValue = System::system(command.c_str()); if(retValue != 0) { cerrLock.set(); cerr << "ccbuild: Non zero exit status (" << retValue << ")\n"; cerrLock.unset(); throw Problem(Problem::Subfailure, "Library linking failed.", retValue); } std::string majorVersion = version.substr(0, version.find_first_of(".")); if(version.find_first_of(".") == string::npos) { majorVersion = "0"; cerrLock.set(); cerr << "ccbuild: Warning: Version without a point, setting Major to " << majorVersion << ".\n"; cerrLock.unset(); } // Major version -> full version std::string lnc = "ln -sf \"" + outputFile + "." + version + "\" \"" + outputFile + "." + majorVersion + "\""; retValue = System::system(lnc.c_str()); if(retValue != 0) { throw Problem(Problem::Subfailure, "Symlinking failed (major version to full version).", retValue); } // library.so -> Major version lnc = "ln -sf \"" + outputFile + "." + majorVersion + "\" \"" + outputFile + "\""; retValue = System::system(lnc.c_str()); if(retValue != 0) { throw Problem(Problem::Subfailure, "Symlinking failed (library to major version).", retValue); } //TODO Return value is now meaningless, throw on !=0 return retValue; } ccbuild-2.0.9/src/compiler/libCommand.cc000066400000000000000000000021741402074776400201230ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "compiler.ih" string Compiler::libCommand(std::string target) const { ostringstream command(d_baseCommand, ios::ate); command << " -shared -Wl,-soname,\"" << target << "\" " << Options::extraArgs << " "; __foreach(obj, d_objects) command << " \"" << (*obj) << "\" "; copy(d_link.begin(), d_link.end(), ostream_iterator(command, " ")); command << "-o \"" << target << "\" "; command << Options::commandAppend; return command.str(); } ccbuild-2.0.9/src/compiler/link.cc000066400000000000000000000027151402074776400170140ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "compiler.ih" int Compiler::link(std::string pwd, std::string outputFile) const { cls(); //TODO If arguments/object come above 32000, the we should collapse object files in the same directory // to *.o where possible. cerr << "[LINK] " << outputFile << "\n"; string command = linkCommand(pwd, outputFile); int retValue = System::system(command.c_str()); if(retValue != 0) { cerr << "ccbuild: Non zero exit status (" << retValue << ")\n"; if(!Options::brute) { throw Problem(Problem::Subfailure, "Linking failed.", retValue); } FileSystem::rmIfExists(outputFile); } else if(!Options::execOnPass.empty()) { System::system((Options::execOnPass + " \"" + outputFile + "\"").c_str()); } return retValue; } ccbuild-2.0.9/src/compiler/linkCommand.cc000066400000000000000000000053631402074776400203150ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "compiler.ih" /* //PART OF > 30000 objects code namespace { bool sameDirectory(string const &rvalue, string const &lvalue) { return FileSystem::directoryName(rvalue) == FileSystem::directoryName(lvalue); } }//Anon namespace */ string Compiler::linkCommand(std::string pwd, std::string outputFile) const { ostringstream command(d_baseCommand, ios::ate); command << " " << Options::extraArgs << " "; __foreach(obj, d_objects) command << "\"" << (*obj) << "\" "; copy(d_link.begin(), d_link.end(), ostream_iterator(command, " ")); command << "-o \"" << pwd << "/" << outputFile << "\" "; /* //checking the maximum length of command line arguments... 32768 //THIS BLOCK MUST BE BEFORE _foreach(obj, d_objects) line //TODO If arguments/object come above 30000, the we should collapse object files in the same directory // to *.o where possible. static const unsigned maxObjectCount(30000); if(d_objects.size() > maxObjectCount) sort(d_objects.begin(), d_objects.end()); while(d_objects.size() > maxObjectCount) { cerr << "OBJECTS REACH MAXIMUM!!"; pair< vector::forward_iterator, vector::forward_iterator > ip; ip = adjacent_find(d_objects.begin(), d_objects.end(), sameDirectory); if(ip.first != d_objects.end()) { vector::size_type oldSize = d_objects.size(); //Archive the objects ostringstream cmd("ar -c -r ", ios::append); string archiveName = FileSystem::directoryName(objects.first()) << "/arch.a"; cmd << archiveName << " "; copy(ip.first, ip.second, ostream_iterator(cmd, " ")); d_objects.erase(ip.first, ip.second); d_objects.push_back(archiveName); cerr << "[AR] " << oldSize << " to " << d_objects.size(); system(cmd.str().c_str()); } } */ command << Options::commandAppend; return command.str(); } ccbuild-2.0.9/src/compiler/operator_add.cc000066400000000000000000000030331402074776400205140ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ //See GNU manual for options: http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options #include "compiler.ih" Compiler const Compiler::operator+(Compiler const &rvalue) { //Adding two compilers will merge their options //Copying only the needed parts. //Keep base command: d_baseCommand(other.d_baseCommand), //Add objects __foreach(object, rvalue.d_objects) if(find(d_objects.begin(), d_objects.end(), *object) == d_objects.end()) { d_objects.push_back(*object); } //Add compiler arguments __foreach(carg, rvalue.d_objects) if(find(d_compile.begin(), d_compile.end(), *carg) == d_compile.end()) { d_compile.push_back(*carg); } //Add linking arguments __foreach(largument, rvalue.d_link) if(find(d_link.begin(), d_link.end(), *largument) == d_link.end()) { d_link.push_back(*largument); } return *this; } ccbuild-2.0.9/src/compiler/precompile.cc000066400000000000000000000032251402074776400202130ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "compiler.ih" int Compiler::precompile(std::string target, std::string outputFile) const { cls(); cerrLock.set(); cerr << "[PREC] " << target << "\n"; cerrLock.unset(); string command = precompileCommand(target, outputFile); int retValue = System::system(command.c_str()); if(retValue != 0) { cerrLock.set(); cerr << "ccbuild: Non zero exit status (" << retValue << ")\n"; cerrLock.unset(); if(!Options::execOnFail.empty()) { System::system((Options::execOnFail + " \"" + target + "\"").c_str()); } if(!Options::brute) { throw Problem(Problem::Subfailure, "Precompilation failed on " + target, retValue); } //Remove output, to make sure the gch is not used by g++ FileSystem::rmIfExists(outputFile); } else if(!Options::execOnPass.empty()) { System::system((Options::execOnPass + " \"" + target + "\"").c_str()); } return retValue; } ccbuild-2.0.9/src/compiler/precompileCommand.cc000066400000000000000000000022631402074776400215130ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "compiler.ih" string Compiler::precompileCommand(std::string target, std::string outputFile) const { ostringstream command(d_baseCommand, ios::ate); command << " " << Options::extraArgs << " "; copy(d_compile.begin(), d_compile.end(), ostream_iterator(command, " ")); command << "-c -o \"" << outputFile << "\" -x \"c++-header\" \"" << target << "\" "; command << Options::commandAppend; return command.str(); } ccbuild-2.0.9/src/compiler/splitInto.cc000066400000000000000000000050761402074776400200470ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "compiler.ih" void Compiler::splitInto(std::string argument, std::vector &arguments) const { vector tArguments; //Uncollapsed version istringstream argumentStream(argument); copy(istream_iterator(argumentStream), istream_iterator(), back_inserter(tArguments) ); #if DEBUGLEVEL > 3 { _debugLevel4("--- Before collapse"); unsigned i = 0; _foreach(arg, tArguments) _debugLevel4( (i++) << " " << *arg); _debugLevel4("---"); } #endif //vector arguments; //Collapsed (quoted strings collapsed) //Collapse the arguments with \" or \' for(unsigned i = 0; i < tArguments.size(); ++i) { unsigned start = i; if(tArguments[i][0] == '"' || tArguments[i][0] == '\'' || tArguments[i][0] == '`') { char stopChar = tArguments[i][0]; while(i < tArguments.size()) { //TODO Be more efficient //Ending in stop argument string const st = " " + tArguments[i]; if(st[st.size() - 1] == stopChar && st[st.size() - 2] != '\'') { break; } ++i; } } //Collapse start -> i into an argument. string arg = tArguments[start]; for(unsigned p = start + 1; p <= i; ++p) { arg += " " + tArguments[p]; } //Strip "" and '' if they both exist if(arg.find_first_of("\"'") == 0 && arg.find_last_of("\"'") == arg.size() -1) { //They must exist arg = arg.substr(1, arg.size() -2); } arguments.push_back(arg); } #if DEBUGLEVEL > 3 { _debugLevel4("--- After collapse"); unsigned i = 0; _foreach(arg, arguments) _debugLevel4( (i++) << " " << *arg); _debugLevel4("---"); } #endif } ccbuild-2.0.9/src/compiler/statics.cc000066400000000000000000000017731402074776400175340ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "compiler.ih" std::string const Compiler::s_highLightOff("\x1b\x5b\x30\x6d"); //\\e[0m std::string const Compiler::s_highLightOn("\x1b\x5b\x33\x31\x6d"); //\e[31m std::string const Compiler::s_clear("\33[H\33[2J"); //Messages std::string const Compiler::s_msgCancelBruteMode("ccbuild: Canceling brute because of return value 2 from compiler\n"); ccbuild-2.0.9/src/doxymainpage.hh000066400000000000000000000071511402074776400167430ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ // THIS FILE IS ONLY HERE FOR DOCUMENTATION PURPOSES /** \mainpage ccbuild See the ccbuild homepage at: https://github.com/bneijt/ccbuild \section intro_sec Introduction ccbuild is a simple build utility. It is site specific (not multiplatform) and probably Linux specific. This however, adds some additional simplicity to the compilation of your source. It's this simplicity which allows the automization. \section probs_sec Problems it should solve One of the main things this program should solve is removing scripts. Scripts for building are nice and editable, but adding filenames to them is a bore. My source should be enough for the system to be able to resolve the compiler arguments that it needs to pull it of. Currently most systems doing the same as ccbuild generate scripts. Mostly using script languages. These are mostly slow (scripts running generating and then running scripts takes time), and sometimes made you define magic variables somewhere to keep them running. ccbuild is very demanding on your source, but fast and simple to use. Also, source tree cluttering should be avoided at all times. \section progflow_sec Program flow The program should be called from a place where the source directory resides: "src". ccbuild identifies 5 file types: - Binary targets (source files with an "int main(" function) - Object targets (source files wich are not binary targets) - Internal headers (files with an ".ih" extension) - Headers (None of the above) - Global headers (Anything included using "#include <...>") When run, ccbuild will look at the current directory: - For all binary targets - Read the source, follow local includes - Scan and use local includes - Scan and use all object targets next these local - Use global includes to determine extra commanline arguments - Precompile (internal headers or all) - Compile - Link \subsection dependencies ccbuild dependencies Compile time: - flex 2.5.31 (newer might work, this is the version that I use) - As of >= 1.5.7 this is going to change.. please read the README \section hacking Hacking the ccbuild source \subsection link_ident Linker argument detection Currently linker argument detection is done in the Compiler class with the bneijt::Compiler::countFirstLinkerArguments function. \subsection hack_add_res Adding resolver functionality To add or change the way the global header resolutions are done, or the arguments are parsed, see the resolve function in the Resolver class. \subsection hack_add_cmd Adding commands To add a command, add it to the large if statement in ccbuild.cc and then add a static function to the System class. To see an example of how to use the dependencies generated, read the makefileFor function ( System/makefileFor.cc ). */ ccbuild-2.0.9/src/fileSystem/000077500000000000000000000000001402074776400160555ustar00rootroot00000000000000ccbuild-2.0.9/src/fileSystem/absolutePath.cc000066400000000000000000000023671402074776400210270ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" std::string FileSystem::absolutePath(std::string const &filename) { /* if file exists char * p = realpath(filename.c_str(), 0); if(not p) throw Problem(Problem::Unable, "Unable to create an absolute path from " + filename); std::string pf(p); delete p; return pf; */ //If it is already absolute, return it cleaned if(filename[0] == '/') { return FileSystem::cleanPath(filename); } //It is not root yet, so make it relative to cwd and clean it. return FileSystem::cleanPath(FileSystem::cwd() +"/"+ filename); } ccbuild-2.0.9/src/fileSystem/baseName.cc000066400000000000000000000016031402074776400200770ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" std::string FileSystem::baseName(string const &filename) { string::size_type i = filename.rfind('/') + 1; if(i == string::npos || i == filename.size()) { i = 0; } return filename.substr(i); } ccbuild-2.0.9/src/fileSystem/ccResolutions000066400000000000000000000001601402074776400206310ustar00rootroot00000000000000#& --args "-DVERSION=\\\"TEST\\\"" glob.h sys/stat.h sys/types.h unistd.h boost/filesystem/path.hpp omp.h ccbuild-2.0.9/src/fileSystem/cleanPath.cc000066400000000000000000000045041402074776400202660ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" std::string FileSystem::cleanPath(string const &filename) { //TODO Use a standard function for this, I might overlook something here //Strip filename of excess ../ parts _debugLevel2("Clean path from: " << filename); istringstream f(filename); size_t partNum = 0; vector path; //Split path into parts while(true) { string part; getline(f, part, '/'); ++partNum; if(!f) { break; } //Double slash lower in the path is ignored ("//" or "/hello//something") // but we can not ignore the first empty part, so we keep partNum as a reference if(part.empty() && partNum != 1) { continue; } //Skip pushing a single . if(part == ".") { continue; } //If it's .. , then pop the last pushed part if that part is not '..' if(part == ".." && path.size() > 0 && path.back() != "../") { _debugLevel3("Popping " << path.back() << " from path."); path.pop_back(); continue; } _debugLevel4("Push " << part << "/"); path.push_back(part + "/"); } string clean = accumulate(path.begin(), path.end(), string()); //Strip last "/" if it is not the first slash if(clean.size() > 1) { clean = clean.substr(0, clean.length() -1); } //Strip superflourous './' for local path if(clean[0] == '.' && clean[1] == '/') { clean = clean.substr(2); } //Return a single "." if we want the current path if(clean.empty()) { clean = "."; } _debugLevel2("Cleaned path to: " << clean); return clean; } ccbuild-2.0.9/src/fileSystem/cwd.cc000066400000000000000000000021651402074776400171450ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" string FileSystem::cwd() { #ifdef _GNU_SOURCE char *cwd = get_current_dir_name(); std::string wd(cwd); free(cwd); return wd; #else #ifndef PATH_MAX #define PATH_MAX 1024 #endif char *cwd = new char[PATH_MAX]; if(getcwd(cwd, PATH_MAX) == 0) { delete[] cwd; throw Problem(Problem::Unable, "Unable to correctly get the current working directory"); } std::string wd(cwd); delete[] cwd; return wd; #endif } ccbuild-2.0.9/src/fileSystem/directoryName.cc000066400000000000000000000022161402074776400211720ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" std::string FileSystem::directoryName(string const &filename) { //TODO allow for slash escaping of the character?? string::size_type lastSlashPos = filename.find_last_of("/"); if(lastSlashPos == string::npos) { //No slash in the path return "."; } if(lastSlashPos == 0) { return "/"; //Last slash is the root } _debugLevel2("dir(" + filename + ") = " + filename.substr(0, lastSlashPos)); return filename.substr(0, lastSlashPos); } ccbuild-2.0.9/src/fileSystem/ensureDirectory.cc000066400000000000000000000033071402074776400215550ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" void FileSystem::ensureDirectory(std::string const &directoryName) { //Check for object directory existence if(directoryName.size() && directoryName != "." && !fileExists(directoryName)) { //S_IRUSR 00400 owner has read permission //S_IWUSR 00200 owner has write permission //S_IXUSR 00100 owner has execute permission cerrLock.set(); cerr << "[MKDIR] " << directoryName << "\n"; cerrLock.unset(); if(!Options::simulate) { //Check base directory existence and create them if needed ensureDirectory(FileSystem::directoryName(directoryName)); fsLock.set(); int mdstat = ::mkdir(directoryName.c_str(), S_IRUSR | S_IWUSR | S_IXUSR); fsLock.unset(); if(mdstat != 0 && !isDirectory(directoryName)) { cerrLock.set(); cerr << "ccbuild: Warning: Unable to create directory \"" << directoryName << "\"\n"; cerrLock.unset(); } } } } ccbuild-2.0.9/src/fileSystem/fileExists.cc000066400000000000000000000017671402074776400205160ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" bool FileSystem::fileExists(std::string const &filename, bool noDir) { OpenMP::ScopedLock scopedFsLock(fsLock); struct stat a; int rcode = stat(filename.c_str(), &a); if(rcode != 0) { //Stat failed return false; } if(noDir and S_ISDIR(a.st_mode)) { return false; } return true; } ccbuild-2.0.9/src/fileSystem/fileName.cc000066400000000000000000000015621402074776400201100ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" std::string FileSystem::fileName(string const &filename) { string::size_type i = filename.find_last_of('/') + 1; if(i == string::npos) { i = 0; } return filename.substr(i); } ccbuild-2.0.9/src/fileSystem/fileSystem.hh000066400000000000000000000137441402074776400205330ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ #ifndef _FileSystem_H_INCLUDED_ #define _FileSystem_H_INCLUDED_ #include #include #include #include "../problem/problem.hh" #ifndef GLOB_ONLYDIR #define GLOB_ONLYDIR 0 #endif namespace bneijt { ///\brief FileSystem /// ///A small collection of FileSystem functions. class FileSystem { public: /**\brief Get a vector of regular files matching the glob pattern. \param list The vector to place the result into \param pattern The glob pattern \param sort Wether or not to use a sorting glob call */ static void globFilesInto(std::vector < std::string > *list, std::string const &pattern, bool sort = true ); ///\brief Get a vector of regular files matching the glob pattern. static void globSourceFilesInto(std::vector < std::string > *list, ///< The vector to place the result into std::string const &directory ///< The directory ); /**\brief Get a vector of regular directories matching the glob pattern. \param list The vector to place the result into \param pattern The glob pattern \param sort Wether or not to use a sorting glob call */ static void globDirectoriesInto(std::vector < std::string > *list, std::string const &pattern, bool sort = false ); ///\brief Glob all subdirectories of this directory static void recursiveGlobDirectoriesInto(std::vector< std::string> *list, std::string const &directory); /**\brief Get a vector of files matching the glob pattern. \param list The vector to place the result into \param pattern The glob pattern \param sort Wether or not to use a sorting glob call */ static void globInto(std::vector < std::string > *list, ///< The vector to place the result into std::string const &pattern, ///< The glob pattern bool sort = true ); ///\brief Returns true if the file exists, in any form (it may be a directory) static bool fileExists(std::string const &filename, ///< The filename of the file to check bool noDir = false ///< The file is not a directory ); ///\brief Remove the file it it exitst, return true on succes. static bool rmIfExists(std::string const &filename ///< The filename of the file to remove ); ///\brief Remove the directory it it exitst, return true on succes. static bool rmDirectoryIfExists(std::string const &filename ///< The filename of the file to remove ); /**\brief Returns a cleaner version of the given path ("./a/../b" -> "./b") \param filename The filename of the file to check */ static std::string cleanPath(std::string const &filename); /**\brief Returns the directory part of a path \param filename The filename of the file to check */ static std::string directoryName(std::string const &filename); /**\brief Returns cleanPath(cwd + "/" + filename) \param filename The filename of the file to check */ static std::string absolutePath(std::string const &filename); /**\brief Returns base of the filename (filename, withouth path, without extension) \param filename The filename to do the conversion on \return The resulting stripped basename */ static std::string baseName(std::string const &filename); /**\brief Returns the filename (filename, withouth path) \param filename The filename to do the conversion on \result The resulting stripped filename */ static std::string fileName(std::string const &filename); ///\brief Touch the given file static bool touch(std::string const &filename ///< The filename of the file to touch ); ///\brief Return the current working directory static std::string cwd(); /**\brief Check whether file1 is newer then file2 If either file doesn't exist, the function returns false. */ static bool newer(std::string const &file1, std::string const &file2); ///\brief Return the modification time for the given file static time_t modTime(std::string const &file); ///\brief Returns true when the given file is readable static bool isReadable(std::string const &file); ///\brief Returns true when the given file is a directory static bool isDirectory(std::string const &file); ///\brief If the given directory doesn't exist, create it. static void ensureDirectory(std::string const &directoryName); ///\brief Rename the given path to the other path static bool rename(std::string const &from, std::string const&to); }; } //namespace #endif ccbuild-2.0.9/src/fileSystem/fileSystem.ih000066400000000000000000000023711402074776400205260ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ #include "fileSystem.hh" #include #include #include #include #include #include #include #include #include // (2) stat includes #include #include #include #include "../options/options.hh" #include "../globallocks/globallocks.hh" #include "../openmp/scopedLock/scopedLock.hh" #include "../misc/foreach.hh" //#define DEBUGLEVEL 5 #include "../misc/debug.hh" using namespace std; using namespace bneijt; ccbuild-2.0.9/src/fileSystem/globDirectoriesInto.cc000066400000000000000000000035621402074776400223440ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" namespace { bool notDirectory(string target) { //Return true if the string doesn't point to a normal file struct stat statbuf; if(stat(target.c_str(), &statbuf) == 0) if(S_ISDIR(statbuf.st_mode)) { //Returns true if the statbuf denotes a regular file return false; } return true; } }//anon namespace void FileSystem::globDirectoriesInto(vector *list, string const &pattern, bool sort) { OpenMP::ScopedLock asdf(fsLock); glob_t globbuf; //Needs to be globfreed at the end //Use glob to get canditates //XXX GLOB_ONLYDIR doesn't seem to work well with simlinks if(sort) { ::glob(pattern.c_str(), GLOB_ONLYDIR | GLOB_TILDE, NULL, &globbuf); } else { ::glob(pattern.c_str(), GLOB_ONLYDIR | GLOB_NOSORT | GLOB_TILDE, NULL, &globbuf); } //Copy all the matches copy(&globbuf.gl_pathv[0], &globbuf.gl_pathv[globbuf.gl_pathc], back_inserter(*list) ); //Remove the not directory entries vector::iterator endOfFiles = remove_if(list->begin(), list->end(), notDirectory); //Delete the elements list->erase(endOfFiles, list->end()); //Cleanup globfree(&globbuf); } ccbuild-2.0.9/src/fileSystem/globFilesInto.cc000066400000000000000000000030531402074776400211250ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" //Using the path given, add all globstring results to the string vector list namespace { bool notFile(string target) { //Return true if the string doesn't point to a normal file struct stat statbuf; if(stat(target.c_str(), &statbuf) == 0) if(S_ISREG(statbuf.st_mode)) { //Returns true if the statbuf denotes a regular file return false; } _debugLevel4("NOT regular file: '" << target << "'"); return true; } }//anon namespace void FileSystem::globFilesInto(vector *list, string const &pattern, bool sort) { globInto(list, pattern, sort); _debugLevel3("Globbging '" << pattern << "' matches " << list->size()); //Remove the not regular file entries that were added vector::iterator endOfFiles = remove_if(list->begin(), list->end(), notFile); //Delete the elements list->erase(endOfFiles, list->end()); } ccbuild-2.0.9/src/fileSystem/globInto.cc000066400000000000000000000023421402074776400201420ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" void FileSystem::globInto(vector *list, string const &pattern, bool sort) { OpenMP::ScopedLock asdf(fsLock); glob_t globbuf; //Needs to be globfreed at the end //Use glob to get canditates if(sort) { ::glob(pattern.c_str(), GLOB_TILDE, NULL, &globbuf); } else { ::glob(pattern.c_str(), GLOB_TILDE | GLOB_NOSORT, NULL, &globbuf); } //Copy all the matches copy(&globbuf.gl_pathv[0], &globbuf.gl_pathv[globbuf.gl_pathc], back_inserter(*list) ); //Cleanup globfree(&globbuf); } ccbuild-2.0.9/src/fileSystem/globSourceFilesInto.cc000066400000000000000000000022511402074776400223050ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" void FileSystem::globSourceFilesInto(vector *list, string const &directory) { //C++ source files globFilesInto(list, directory + "/*.cc"); globFilesInto(list, directory + "/*.cp"); globFilesInto(list, directory + "/*.cxx"); globFilesInto(list, directory + "/*.cpp"); globFilesInto(list, directory + "/*.CPP"); globFilesInto(list, directory + "/*.c++"); globFilesInto(list, directory + "/*.C"); //C source files ??? //globFilesInto(list, directory + "/*.c"); } ccbuild-2.0.9/src/fileSystem/isDirectory.cc000066400000000000000000000017421402074776400206700ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" bool FileSystem::isDirectory(std::string const &filename) { OpenMP::ScopedLock scopedFsLock(fsLock); struct stat a; int rcode = stat(filename.c_str(), &a); if(rcode != 0) { //Stat failed return false; } if(S_ISDIR(a.st_mode)) { return true; } return false; } ccbuild-2.0.9/src/fileSystem/isReadable.cc000066400000000000000000000015631402074776400204240ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" bool FileSystem::isReadable(string const &filename) { OpenMP::ScopedLock asdf(fsLock); _debugLevel4("Readable test on '" << filename << "'"); return access(filename.c_str(), R_OK) == 0; } ccbuild-2.0.9/src/fileSystem/modTime.cc000066400000000000000000000017571402074776400177740ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" time_t FileSystem::modTime(string const &file) { OpenMP::ScopedLock asdf(fsLock); struct stat statbuff; if(stat(file.c_str(), &statbuff) != 0) { throw Problem(Problem::Missing, "Could not stat \"" + file +"\"\n\tFailed to get requested modTime."); return 0; } return statbuff.st_mtime; } ccbuild-2.0.9/src/fileSystem/newer.cc000066400000000000000000000017541402074776400175130ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" bool FileSystem::newer(string const &file1, string const &file2) { OpenMP::ScopedLock asdf(fsLock); struct stat stat1, stat2; if(stat(file1.c_str(), &stat1) != 0) { return false; } if(stat(file2.c_str(), &stat2) != 0) { return false; } return stat1.st_mtime > stat2.st_mtime; } ccbuild-2.0.9/src/fileSystem/recursiveGlobDirectoriesInto.cc000066400000000000000000000025321402074776400242300ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" void FileSystem::recursiveGlobDirectoriesInto(vector *list, string const &directory) { stack directoryStack; directoryStack.push(directory); set directories; while(directoryStack.size() > 0) { string dir = directoryStack.top(); directoryStack.pop(); vector dirList; FileSystem::globDirectoriesInto(&dirList, dir + "/*"); __foreach(d, dirList) if(!directories.count(*d)) { directoryStack.push(*d); } directories.insert(dir); } copy(directories.begin(), directories.end(), back_inserter(*list)); } ccbuild-2.0.9/src/fileSystem/rename.cc000066400000000000000000000015171402074776400176370ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" bool FileSystem::rename(std::string const &from, std::string const&to) { OpenMP::ScopedLock asdf(fsLock); return ::rename(from.c_str(), to.c_str()) == 0; } ccbuild-2.0.9/src/fileSystem/rmDirectoryIfExists.cc000066400000000000000000000023561402074776400223540ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" bool FileSystem::rmDirectoryIfExists(std::string const &dir) { if(! FileSystem::fileExists(dir)) { return false; } cerrLock.set(); cerr << "[RMDIR] " << dir << "\n"; cerrLock.unset(); fsLock.set(); int retValue = rmdir(dir.c_str()); fsLock.unset(); if(retValue != 0 && FileSystem::fileExists(dir)) { cerrLock.set(); cerr << "Non zero exit status for rmdir: status " << retValue << "\n"; cerr << " could not remove: " << dir << "\n"; cerrLock.unset(); return false; } return true; } ccbuild-2.0.9/src/fileSystem/rmIfExists.cc000066400000000000000000000024741402074776400204700ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" bool FileSystem::rmIfExists(std::string const &filename) { if(! FileSystem::fileExists(filename)) { return false; } cerrLock.set(); cerr << "[RM] " << filename << "\n"; cerrLock.unset(); if(Options::simulate) { return true; } fsLock.set(); int retValue = unlink(filename.c_str()); fsLock.unset(); if(retValue != 0 && FileSystem::fileExists(filename)) { cerrLock.set(); cerr << "Non zero exit status for unlink: status " << retValue << "\n"; cerr << " could not remove: " << filename << "\n"; cerrLock.unset(); return false; } return true; } ccbuild-2.0.9/src/fileSystem/test.cc000066400000000000000000000047051402074776400173510ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.hh" #include #include #include #include #include #include using namespace std; using namespace bneijt; int main(int argc, char **argv) try { #define FS(FNAME, a) std::cout << "FileSystem::" << #FNAME << "(\"" << a << "\")= " << FileSystem::FNAME(a) << "\n" FS(directoryName, "/home/bram/program/cc/ccbuild/src"); FS(directoryName, "."); FS(directoryName, "/"); FS(directoryName, "hello.txt"); FS(directoryName, "hello."); FS(directoryName, ".hello/"); std::string dname("/home/bram/program/cc/ccbuild/src"); for(size_t i = 0; i < 8; ++i) { std::cout << i << ": " << dname << "\n"; dname = FileSystem::directoryName(dname); } dname = "home/bram/program/cc/ccbuild/src"; for(size_t i = 0; i < 8; ++i) { std::cout << i << ": " << dname << "\n"; dname = FileSystem::directoryName(dname); } FS(cleanPath, "/home/bram/program/cc/ccbuild/src"); FS(cleanPath, "."); FS(cleanPath, "/"); FS(cleanPath, "././"); FS(cleanPath, "././/"); FS(cleanPath, "hello.txt"); FS(cleanPath, "hello."); FS(cleanPath, ".hello/"); FS(cleanPath, "../libbats/SocketComm/../../../Socket/socket.hh"); FS(cleanPath, "..//../../../Socket/socket.hh"); FS(absolutePath, "/home/bram/program/cc/ccbuild/src"); FS(absolutePath, "."); FS(absolutePath, "/"); FS(absolutePath, "././"); FS(absolutePath, "././/"); FS(absolutePath, "hello.txt"); FS(absolutePath, "hello."); FS(absolutePath, ".hello/"); cout << "\n"; return 0; } catch(const std::exception &e) { //All is LOST... nothing to do here but die cerr << "Caught std::exception (" << typeid(e).name() << "): " << e.what(); cerr << "\nPlease report this as a bug.\n"; } ccbuild-2.0.9/src/fileSystem/touch.cc000066400000000000000000000015761402074776400175170ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "fileSystem.ih" bool FileSystem::touch(std::string const &filename) { OpenMP::ScopedLock asdf(fsLock); ofstream file(filename.c_str(), ios::app); bool succes = file.is_open(); file.close(); return succes; } ccbuild-2.0.9/src/globallocks/000077500000000000000000000000001402074776400162255ustar00rootroot00000000000000ccbuild-2.0.9/src/globallocks/globallocks.hh000066400000000000000000000017171402074776400210500ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #ifndef globallocks_hh_included_ #define globallocks_hh_included_ #include "../openmp/lock/lock.hh" namespace bneijt { static OpenMP::Lock cerrLock; static OpenMP::Lock coutLock; static OpenMP::Lock flexLock; static OpenMP::Lock fsLock; } //Namespace #endif ccbuild-2.0.9/src/globallocks/globallocks.ih000066400000000000000000000013031402074776400210400ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "globallocks.hh" using namespace bneijt; ccbuild-2.0.9/src/globallocks/statics.cc000066400000000000000000000014741402074776400202140ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "globallocks.ih" OpenMP::Lock cerrLock; OpenMP::Lock coutLock; OpenMP::Lock flexLock; OpenMP::Lock fsLock; ccbuild-2.0.9/src/globals/000077500000000000000000000000001402074776400153545ustar00rootroot00000000000000ccbuild-2.0.9/src/globals/destroy.cc000066400000000000000000000015771402074776400173660ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "globals.ih" void Globals::destroy() { OpenMP::ScopedLock instantiateLock(s_instanceLock); if(s_instance) { delete s_instance; } else { _debugLevel1("Already destroyed!!"); } s_instance = 0; } ccbuild-2.0.9/src/globals/getInstance.cc000066400000000000000000000015371402074776400201350ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "globals.ih" Globals &Globals::getInstance() { OpenMP::ScopedLock instantiateLock(s_instanceLock); if(s_instance == 0) { s_instance = new Globals(); } return *s_instance; } ccbuild-2.0.9/src/globals/globals.cc000066400000000000000000000014771402074776400173170ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "globals.ih" Globals::Globals() : d_map() { } Globals::~Globals() { __foreach(link, *this) if(link->second) { delete link->second; } } ccbuild-2.0.9/src/globals/globals.hh000066400000000000000000000040571402074776400173260ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ //Globals map singleton. There to make sure globals only have one pointer to their name #ifndef _Globals_H_INCLUDED_ #define _Globals_H_INCLUDED_ #include #include #include #include "../openmp/scopedLock/scopedLock.hh" namespace bneijt { ///\brief Globals singleton. List of all loaded Globals /// class Globals { static Globals *s_instance; /// d_map; public: ///\brief Get the instance of the Globals class static Globals &getInstance(); ///\brief Destroy the instance static void destroy(); ///\brief Overwrite the index operator of map std::string const * operator[](std::string const &global); std::map::iterator begin() { return d_map.begin(); } std::map::iterator end() { return d_map.end(); } private: Globals(); ~Globals(); ///\brief Not implemented Globals(Globals const &other); //NI ///\brief Not implemented Globals &operator=(Globals const &other); //NI }; }//namespace #endif ccbuild-2.0.9/src/globals/globals.ih000066400000000000000000000017501402074776400173240ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ #include "globals.hh" #include "../fileSystem/fileSystem.hh" #include "../openmp/scopedLock/scopedLock.hh" #include //#define DEBUGLEVEL 2 #include "../misc/debug.hh" #include "../misc/foreach.hh" using namespace bneijt; using namespace std; ccbuild-2.0.9/src/globals/indexoperator.cc000066400000000000000000000015551402074776400205540ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "globals.ih" std::string const * Globals::operator[](std::string const &global) { string *p = d_map[global]; if(p == 0) { p = new string(global); d_map[global] = p; } return p; } ccbuild-2.0.9/src/globals/statics.cc000066400000000000000000000015131402074776400173350ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "globals.ih" Globals *Globals::s_instance(0); /// 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 3 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, see . */ ///\file ///\brief Preprosessor macro's for easy debug info printing /// ///These preprosessor instructions place info as debugging information on the screen. ///You should use DEBUGLEVEL to set the level of debugging info you want. When DEBUGLEVEL is not defined /// these macro's evaluate to nothing. /// ///If DEBUGLEVEL is set to 1, Level1 debug info is printed. If DEBUGLEVEL is set to 2, all Level2 and lower are printed. etc. /// ///To set the debuglevel of a class, place \#define DEBUGLEVEL in the internal header file (in contrast to the header). This will keep multiple defenitions from occuring when compiling. /// ///The output generated is: "[Filename]:[Line number]: [information]\n" /// ///The extraction operator is used for creating the debug line, so info can contain more then multiple elements devided /// by extraction operators. ///\section examples Examples ///\code /// _debugLevel2("Starting algorithm with:" << "something."); /// _debugLevel3("And thinking about running it" << i << " times."); ///\endcode //No include guards, to keep the defenitions as much up to date as possible, due to the dependencie on DEBUGLEVEL. #ifdef NODEBUG #ifdef DEBUGLEVEL #undef DEBUGLEVEL #endif #define DEBUGLEVEL 0 #endif #if DEBUGLEVEL > 0 #include #define _debugLevel1(info) std::cerr << "D1:" << __FILE__ << ":" << __LINE__ << ": " << info << std::endl #else ///\brief Output info when DEBUGLEVEL is 1 or more #define _debugLevel1(info) #endif #if DEBUGLEVEL > 1 #define _debugLevel2(info) std::cerr << "D2:" << __FILE__ << ":" << __LINE__ << ": " << info << std::endl #else ///\brief Output info when DEBUGLEVEL is 2 or more #define _debugLevel2(info) #endif #if DEBUGLEVEL > 2 #define _debugLevel3(info) std::cerr << "D3:" << __FILE__ << ":" << __LINE__ << ": " << info << std::endl #else ///\brief Output info when DEBUGLEVEL is 3 or more #define _debugLevel3(info) #endif #if DEBUGLEVEL > 3 #define _debugLevel4(info) std::cerr << "D4:" << __FILE__ << ":" << __LINE__ << ": " << info << std::endl #else ///\brief Output info when DEBUGLEVEL is 4 or more #define _debugLevel4(info) #endif ccbuild-2.0.9/src/misc/foreach.hh000066400000000000000000000040341402074776400166150ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ ///\file ///\brief Preprosessor macro to define a STL iterator for loop: _foreach(iterator, container) #ifndef __ccsys_FOREACH_H_INCLUDED #define __ccsys_FOREACH_H_INCLUDED // // The triple expansion may seem daring, but it is needed to fully expand the __LINE__ // Which is needed for code like: foreach(iter, arrayOfVectors[0]) // ///\brief Preprosessor macro to define a STL iterator for loop: __foreach(iterator, container) /// ///The preprosessor instruction foreach takes a variable name and an iterator name and translates ///into a default for loop using the != operator. It should work with any forward iterator. ///For const iterators, there is the cforeach preprocessor macro. ///\section examples Examples ///\code ///vector numbers; ///numbers.push_back(10); ///__foreach(number, numbers) /// cout << *number << "\n"; ///\endcode /// ///DON'T!!! ///Don't use temporary const objects returned by functions, like: foreach(i, file.lines()). #ifdef __foreach #error __foreach already defined! This macro may have gone wild! #endif #ifdef __GXX_EXPERIMENTAL_CXX0X__ #define __foreach( iter, cont) for(auto iter = (cont).begin(); iter != (cont).end(); ++iter) #else #define __foreach( iter, cont) for( __typeof__((cont).begin()) iter = (cont).begin(); iter != (cont).end(); ++iter) #endif //_INCLUDED #endif ccbuild-2.0.9/src/openmp/000077500000000000000000000000001402074776400152275ustar00rootroot00000000000000ccbuild-2.0.9/src/openmp/lock/000077500000000000000000000000001402074776400161575ustar00rootroot00000000000000ccbuild-2.0.9/src/openmp/lock/lock.hh000066400000000000000000000027701402074776400174360ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ #ifndef __Lock_HH_INCLUDED #define __Lock_HH_INCLUDED #ifdef _OPENMP #include #endif namespace bneijt { namespace OpenMP { #ifndef _OPENMP //Use an empty class if OpenMP is disabled (no -fopenmp) class Lock { public: Lock() {} //To make sure that OpenMP::Lock a; is not a declaration. void set() {} void unset() {} }; #else class Lock { omp_lock_t d_lock; public: Lock() { omp_init_lock(&d_lock); } ~Lock() { omp_destroy_lock(&d_lock); } void set() { omp_set_lock(&d_lock); } void unset() { omp_unset_lock(&d_lock); } }; #endif //OpenMP disables/enabled block }} //Namespace #endif ccbuild-2.0.9/src/openmp/scopedLock/000077500000000000000000000000001402074776400173155ustar00rootroot00000000000000ccbuild-2.0.9/src/openmp/scopedLock/scopedLock.hh000066400000000000000000000020641402074776400217260ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ #ifndef __ScopedLock_HH_INCLUDED #define __ScopedLock_HH_INCLUDED #include "../lock/lock.hh" namespace bneijt { namespace OpenMP { class ScopedLock { Lock &d_lock; public: ScopedLock(Lock &l) : d_lock(l) { d_lock.set(); } ~ScopedLock() { d_lock.unset(); } }; }} //Namespaces #endif ccbuild-2.0.9/src/openmp/scopedLock/scopedLock.ih000066400000000000000000000014301402074776400217230ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ #include "ScopedLock.hh" using namespace bneijt; ccbuild-2.0.9/src/options/000077500000000000000000000000001402074776400154245ustar00rootroot00000000000000ccbuild-2.0.9/src/options/options.hh000066400000000000000000000063451402074776400174500ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ #ifndef _Options_HH_INCLUDED_ #define _Options_HH_INCLUDED_ #include #include namespace bneijt { /**\brief A collection of static variables containing options */ struct Options { static std::string version; /// includePaths; /// extraResolutions; /// 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 3 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, see . */ #include "options.hh" using namespace bneijt; ccbuild-2.0.9/src/options/statics.cc000066400000000000000000000033731402074776400174130ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "options.ih" std::string Options::version(VERSION); std::string Options::CC("g++"); std::string Options::execOnPass(""); std::string Options::extraArgs(""); std::string Options::commandAppend(""); std::string Options::execOnFail(""); std::string Options::homepage("https://github.com/bneijt/ccbuild"); std::string Options::progVersion(""); std::string Options::cacheRoot("o"); //std::string Options::(""); bool Options::md5(false); bool Options::simulate(false); bool Options::precompile(false); bool Options::precompileAll(false); bool Options::verbose(false); bool Options::defaultUpdate(false); bool Options::highlight(false); bool Options::showCommands(false); bool Options::showProgress(false); bool Options::brute(false); bool Options::clearPerCommand(false); bool Options::loadGlobalRes(false); bool Options::makefileHeaderDone(false); bool Options::aapHeaderDone(false); bool Options::xml(false); bool Options::interAr(false); bool Options::noWarn(false); bool Options::batch(false); //bool Options::(false); std::vector Options::includePaths; std::vector Options::extraResolutions; ccbuild-2.0.9/src/posix/000077500000000000000000000000001402074776400150735ustar00rootroot00000000000000ccbuild-2.0.9/src/posix/README000066400000000000000000000001041402074776400157460ustar00rootroot00000000000000These files where taken from eglibc-2.10.1 apt-get source libc6-dev ccbuild-2.0.9/src/posix/wordexp.c000066400000000000000000001503011402074776400167270ustar00rootroot00000000000000/* POSIX.2 wordexp implementation. Copyright (C) 1997-2013, 2005, 2006, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Tim Waugh . The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 General Public License along with this program. If not, see .*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef USE_IN_LIBIO # include #endif #include "wordexp.h" #include #include #include /* Undefine the following line for the production version. */ /* #define NDEBUG 1 */ #include /* Get some device information. */ #include /* * This is a recursive-descent-style word expansion routine. */ /* These variables are defined and initialized in the startup code. */ extern int __libc_argc attribute_hidden; extern char **__libc_argv attribute_hidden; /* Some forward declarations */ static int parse_dollars (char **word, size_t *word_length, size_t *max_length, const char *words, size_t *offset, int flags, wordexp_t *pwordexp, const char *ifs, const char *ifs_white, int quoted) internal_function; static int parse_backtick (char **word, size_t *word_length, size_t *max_length, const char *words, size_t *offset, int flags, wordexp_t *pwordexp, const char *ifs, const char *ifs_white) internal_function; static int parse_dquote (char **word, size_t *word_length, size_t *max_length, const char *words, size_t *offset, int flags, wordexp_t *pwordexp, const char *ifs, const char *ifs_white) internal_function; static int eval_expr (char *expr, long int *result) internal_function; /* The w_*() functions manipulate word lists. */ #define W_CHUNK (100) /* Result of w_newword will be ignored if it's the last word. */ static inline char * w_newword (size_t *actlen, size_t *maxlen) { *actlen = *maxlen = 0; return NULL; } static char * w_addchar (char *buffer, size_t *actlen, size_t *maxlen, char ch) /* (lengths exclude trailing zero) */ { /* Add a character to the buffer, allocating room for it if needed. */ if (*actlen == *maxlen) { char *old_buffer = buffer; assert (buffer == NULL || *maxlen != 0); *maxlen += W_CHUNK; buffer = (char *) realloc (buffer, 1 + *maxlen); if (buffer == NULL) free (old_buffer); } if (buffer != NULL) { buffer[*actlen] = ch; buffer[++(*actlen)] = '\0'; } return buffer; } static char * internal_function w_addmem (char *buffer, size_t *actlen, size_t *maxlen, const char *str, size_t len) { /* Add a string to the buffer, allocating room for it if needed. */ if (*actlen + len > *maxlen) { char *old_buffer = buffer; assert (buffer == NULL || *maxlen != 0); *maxlen += MAX (2 * len, W_CHUNK); buffer = realloc (old_buffer, 1 + *maxlen); if (buffer == NULL) free (old_buffer); } if (buffer != NULL) { *((char *) __mempcpy (&buffer[*actlen], str, len)) = '\0'; *actlen += len; } return buffer; } static char * internal_function w_addstr (char *buffer, size_t *actlen, size_t *maxlen, const char *str) /* (lengths exclude trailing zero) */ { /* Add a string to the buffer, allocating room for it if needed. */ size_t len; assert (str != NULL); /* w_addstr only called from this file */ len = strlen (str); return w_addmem (buffer, actlen, maxlen, str, len); } static int internal_function w_addword (wordexp_t *pwordexp, char *word) { /* Add a word to the wordlist */ size_t num_p; char **new_wordv; bool allocated = false; /* Internally, NULL acts like "". Convert NULLs to "" before * the caller sees them. */ if (word == NULL) { word = __strdup (""); if (word == NULL) goto no_space; allocated = true; } num_p = 2 + pwordexp->we_wordc + pwordexp->we_offs; new_wordv = realloc (pwordexp->we_wordv, sizeof (char *) * num_p); if (new_wordv != NULL) { pwordexp->we_wordv = new_wordv; pwordexp->we_wordv[pwordexp->we_offs + pwordexp->we_wordc++] = word; pwordexp->we_wordv[pwordexp->we_offs + pwordexp->we_wordc] = NULL; return 0; } if (allocated) free (word); no_space: return WRDE_NOSPACE; } /* The parse_*() functions should leave *offset being the offset in 'words' * to the last character processed. */ static int internal_function parse_backslash (char **word, size_t *word_length, size_t *max_length, const char *words, size_t *offset) { /* We are poised _at_ a backslash, not in quotes */ switch (words[1 + *offset]) { case 0: /* Backslash is last character of input words */ return WRDE_SYNTAX; case '\n': ++(*offset); break; default: *word = w_addchar (*word, word_length, max_length, words[1 + *offset]); if (*word == NULL) return WRDE_NOSPACE; ++(*offset); break; } return 0; } static int internal_function parse_qtd_backslash (char **word, size_t *word_length, size_t *max_length, const char *words, size_t *offset) { /* We are poised _at_ a backslash, inside quotes */ switch (words[1 + *offset]) { case 0: /* Backslash is last character of input words */ return WRDE_SYNTAX; case '\n': ++(*offset); break; case '$': case '`': case '"': case '\\': *word = w_addchar (*word, word_length, max_length, words[1 + *offset]); if (*word == NULL) return WRDE_NOSPACE; ++(*offset); break; default: *word = w_addchar (*word, word_length, max_length, words[*offset]); if (*word != NULL) *word = w_addchar (*word, word_length, max_length, words[1 + *offset]); if (*word == NULL) return WRDE_NOSPACE; ++(*offset); break; } return 0; } static int internal_function parse_tilde (char **word, size_t *word_length, size_t *max_length, const char *words, size_t *offset, size_t wordc) { /* We are poised _at_ a tilde */ size_t i; if (*word_length != 0) { if (!((*word)[*word_length - 1] == '=' && wordc == 0)) { if (!((*word)[*word_length - 1] == ':' && strchr (*word, '=') && wordc == 0)) { *word = w_addchar (*word, word_length, max_length, '~'); return *word ? 0 : WRDE_NOSPACE; } } } for (i = 1 + *offset; words[i]; i++) { if (words[i] == ':' || words[i] == '/' || words[i] == ' ' || words[i] == '\t' || words[i] == 0 ) break; if (words[i] == '\\') { *word = w_addchar (*word, word_length, max_length, '~'); return *word ? 0 : WRDE_NOSPACE; } } if (i == 1 + *offset) { /* Tilde appears on its own */ uid_t uid; struct passwd pwd, *tpwd; int buflen = 1000; char* home; char* buffer; int result; /* POSIX.2 says ~ expands to $HOME and if HOME is unset the results are unspecified. We do a lookup on the uid if HOME is unset. */ home = getenv ("HOME"); if (home != NULL) { *word = w_addstr (*word, word_length, max_length, home); if (*word == NULL) return WRDE_NOSPACE; } else { uid = __getuid (); buffer = __alloca (buflen); while ((result = __getpwuid_r (uid, &pwd, buffer, buflen, &tpwd)) != 0 && errno == ERANGE) buffer = extend_alloca (buffer, buflen, buflen + 1000); if (result == 0 && tpwd != NULL && pwd.pw_dir != NULL) { *word = w_addstr (*word, word_length, max_length, pwd.pw_dir); if (*word == NULL) return WRDE_NOSPACE; } else { *word = w_addchar (*word, word_length, max_length, '~'); if (*word == NULL) return WRDE_NOSPACE; } } } else { /* Look up user name in database to get home directory */ char *user = strndupa (&words[1 + *offset], i - (1 + *offset)); struct passwd pwd, *tpwd; int buflen = 1000; char* buffer = __alloca (buflen); int result; while ((result = __getpwnam_r (user, &pwd, buffer, buflen, &tpwd)) != 0 && errno == ERANGE) buffer = extend_alloca (buffer, buflen, buflen + 1000); if (result == 0 && tpwd != NULL && pwd.pw_dir) *word = w_addstr (*word, word_length, max_length, pwd.pw_dir); else { /* (invalid login name) */ *word = w_addchar (*word, word_length, max_length, '~'); if (*word != NULL) *word = w_addstr (*word, word_length, max_length, user); } *offset = i - 1; } return *word ? 0 : WRDE_NOSPACE; } static int internal_function do_parse_glob (const char *glob_word, char **word, size_t *word_length, size_t *max_length, wordexp_t *pwordexp, const char *ifs, const char *ifs_white) { int error; unsigned int match; glob_t globbuf; error = glob (glob_word, GLOB_NOCHECK, NULL, &globbuf); if (error != 0) { /* We can only run into memory problems. */ assert (error == GLOB_NOSPACE); return WRDE_NOSPACE; } if (ifs && !*ifs) { /* No field splitting allowed. */ assert (globbuf.gl_pathv[0] != NULL); *word = w_addstr (*word, word_length, max_length, globbuf.gl_pathv[0]); for (match = 1; match < globbuf.gl_pathc && *word != NULL; ++match) { *word = w_addchar (*word, word_length, max_length, ' '); if (*word != NULL) *word = w_addstr (*word, word_length, max_length, globbuf.gl_pathv[match]); } globfree (&globbuf); return *word ? 0 : WRDE_NOSPACE; } assert (ifs == NULL || *ifs != '\0'); if (*word != NULL) { free (*word); *word = w_newword (word_length, max_length); } for (match = 0; match < globbuf.gl_pathc; ++match) { char *matching_word = __strdup (globbuf.gl_pathv[match]); if (matching_word == NULL || w_addword (pwordexp, matching_word)) { globfree (&globbuf); return WRDE_NOSPACE; } } globfree (&globbuf); return 0; } static int internal_function parse_glob (char **word, size_t *word_length, size_t *max_length, const char *words, size_t *offset, int flags, wordexp_t *pwordexp, const char *ifs, const char *ifs_white) { /* We are poised just after a '*', a '[' or a '?'. */ int error = WRDE_NOSPACE; int quoted = 0; /* 1 if singly-quoted, 2 if doubly */ size_t i; wordexp_t glob_list; /* List of words to glob */ glob_list.we_wordc = 0; glob_list.we_wordv = NULL; glob_list.we_offs = 0; for (; words[*offset] != '\0'; ++*offset) { if (strchr (ifs, words[*offset]) != NULL) /* Reached IFS */ break; /* Sort out quoting */ if (words[*offset] == '\'') { if (quoted == 0) { quoted = 1; continue; } else if (quoted == 1) { quoted = 0; continue; } } else if (words[*offset] == '"') { if (quoted == 0) { quoted = 2; continue; } else if (quoted == 2) { quoted = 0; continue; } } /* Sort out other special characters */ if (quoted != 1 && words[*offset] == '$') { error = parse_dollars (word, word_length, max_length, words, offset, flags, &glob_list, ifs, ifs_white, quoted == 2); if (error) goto tidy_up; continue; } else if (words[*offset] == '\\') { if (quoted) error = parse_qtd_backslash (word, word_length, max_length, words, offset); else error = parse_backslash (word, word_length, max_length, words, offset); if (error) goto tidy_up; continue; } *word = w_addchar (*word, word_length, max_length, words[*offset]); if (*word == NULL) goto tidy_up; } /* Don't forget to re-parse the character we stopped at. */ --*offset; /* Glob the words */ error = w_addword (&glob_list, *word); *word = w_newword (word_length, max_length); for (i = 0; error == 0 && i < glob_list.we_wordc; i++) error = do_parse_glob (glob_list.we_wordv[i], word, word_length, max_length, pwordexp, ifs, ifs_white); /* Now tidy up */ tidy_up: wordfree (&glob_list); return error; } static int internal_function parse_squote (char **word, size_t *word_length, size_t *max_length, const char *words, size_t *offset) { /* We are poised just after a single quote */ for (; words[*offset]; ++(*offset)) { if (words[*offset] != '\'') { *word = w_addchar (*word, word_length, max_length, words[*offset]); if (*word == NULL) return WRDE_NOSPACE; } else return 0; } /* Unterminated string */ return WRDE_SYNTAX; } /* Functions to evaluate an arithmetic expression */ static int internal_function eval_expr_val (char **expr, long int *result) { char *digit; /* Skip white space */ for (digit = *expr; digit && *digit && isspace (*digit); ++digit); if (*digit == '(') { /* Scan for closing paren */ for (++digit; **expr && **expr != ')'; ++(*expr)); /* Is there one? */ if (!**expr) return WRDE_SYNTAX; *(*expr)++ = 0; if (eval_expr (digit, result)) return WRDE_SYNTAX; return 0; } /* POSIX requires that decimal, octal, and hexadecimal constants are recognized. Therefore we pass 0 as the third parameter to strtol. */ *result = strtol (digit, expr, 0); if (digit == *expr) return WRDE_SYNTAX; return 0; } static int internal_function eval_expr_multdiv (char **expr, long int *result) { long int arg; /* Read a Value */ if (eval_expr_val (expr, result) != 0) return WRDE_SYNTAX; while (**expr) { /* Skip white space */ for (; *expr && **expr && isspace (**expr); ++(*expr)); if (**expr == '*') { ++(*expr); if (eval_expr_val (expr, &arg) != 0) return WRDE_SYNTAX; *result *= arg; } else if (**expr == '/') { ++(*expr); if (eval_expr_val (expr, &arg) != 0) return WRDE_SYNTAX; *result /= arg; } else break; } return 0; } static int internal_function eval_expr (char *expr, long int *result) { long int arg; /* Read a Multdiv */ if (eval_expr_multdiv (&expr, result) != 0) return WRDE_SYNTAX; while (*expr) { /* Skip white space */ for (; expr && *expr && isspace (*expr); ++expr); if (*expr == '+') { ++expr; if (eval_expr_multdiv (&expr, &arg) != 0) return WRDE_SYNTAX; *result += arg; } else if (*expr == '-') { ++expr; if (eval_expr_multdiv (&expr, &arg) != 0) return WRDE_SYNTAX; *result -= arg; } else break; } return 0; } static int internal_function parse_arith (char **word, size_t *word_length, size_t *max_length, const char *words, size_t *offset, int flags, int bracket) { /* We are poised just after "$((" or "$[" */ int error; int paren_depth = 1; size_t expr_length; size_t expr_maxlen; char *expr; expr = w_newword (&expr_length, &expr_maxlen); for (; words[*offset]; ++(*offset)) { switch (words[*offset]) { case '$': error = parse_dollars (&expr, &expr_length, &expr_maxlen, words, offset, flags, NULL, NULL, NULL, 1); /* The ``1'' here is to tell parse_dollars not to * split the fields. */ if (error) { free (expr); return error; } break; case '`': (*offset)++; error = parse_backtick (&expr, &expr_length, &expr_maxlen, words, offset, flags, NULL, NULL, NULL); /* The first NULL here is to tell parse_backtick not to * split the fields. */ if (error) { free (expr); return error; } break; case '\\': error = parse_qtd_backslash (&expr, &expr_length, &expr_maxlen, words, offset); if (error) { free (expr); return error; } /* I think that a backslash within an * arithmetic expansion is bound to * cause an error sooner or later anyway though. */ break; case ')': if (--paren_depth == 0) { char result[21]; /* 21 = ceil(log10(2^64)) + 1 */ long int numresult = 0; long long int convertme; if (bracket || words[1 + *offset] != ')') { free (expr); return WRDE_SYNTAX; } ++(*offset); /* Go - evaluate. */ if (*expr && eval_expr (expr, &numresult) != 0) { free (expr); return WRDE_SYNTAX; } if (numresult < 0) { convertme = -numresult; *word = w_addchar (*word, word_length, max_length, '-'); if (!*word) { free (expr); return WRDE_NOSPACE; } } else convertme = numresult; result[20] = '\0'; *word = w_addstr (*word, word_length, max_length, _itoa (convertme, &result[20], 10, 0)); free (expr); return *word ? 0 : WRDE_NOSPACE; } expr = w_addchar (expr, &expr_length, &expr_maxlen, words[*offset]); if (expr == NULL) return WRDE_NOSPACE; break; case ']': if (bracket && paren_depth == 1) { char result[21]; /* 21 = ceil(log10(2^64)) + 1 */ long int numresult = 0; /* Go - evaluate. */ if (*expr && eval_expr (expr, &numresult) != 0) { free (expr); return WRDE_SYNTAX; } result[20] = '\0'; *word = w_addstr (*word, word_length, max_length, _itoa_word (numresult, &result[20], 10, 0)); free (expr); return *word ? 0 : WRDE_NOSPACE; } free (expr); return WRDE_SYNTAX; case '\n': case ';': case '{': case '}': free (expr); return WRDE_BADCHAR; case '(': ++paren_depth; default: expr = w_addchar (expr, &expr_length, &expr_maxlen, words[*offset]); if (expr == NULL) return WRDE_NOSPACE; } } /* Premature end */ free (expr); return WRDE_SYNTAX; } /* Function called by child process in exec_comm() */ static inline void internal_function __attribute__ ((always_inline)) exec_comm_child (char *comm, int *fildes, int showerr, int noexec) { const char *args[4] = { _PATH_BSHELL, "-c", comm, NULL }; /* Execute the command, or just check syntax? */ if (noexec) args[1] = "-nc"; /* Redirect output. */ if (__builtin_expect (fildes[1] != STDOUT_FILENO, 1)) { __dup2 (fildes[1], STDOUT_FILENO); __close (fildes[1]); } else { #ifdef O_CLOEXEC /* Reset the close-on-exec flag (if necessary). */ # ifndef __ASSUME_PIPE2 if (__have_pipe2 > 0) # endif __fcntl (fildes[1], F_SETFD, 0); #endif } /* Redirect stderr to /dev/null if we have to. */ if (showerr == 0) { struct stat64 st; int fd; __close (STDERR_FILENO); fd = __open (_PATH_DEVNULL, O_WRONLY); if (fd >= 0 && fd != STDERR_FILENO) { __dup2 (fd, STDERR_FILENO); __close (fd); } /* Be paranoid. Check that we actually opened the /dev/null device. */ if (__builtin_expect (__fxstat64 (_STAT_VER, STDERR_FILENO, &st), 0) != 0 || __builtin_expect (S_ISCHR (st.st_mode), 1) == 0 #if defined DEV_NULL_MAJOR && defined DEV_NULL_MINOR || st.st_rdev != makedev (DEV_NULL_MAJOR, DEV_NULL_MINOR) #endif ) /* It's not the /dev/null device. Stop right here. The problem is: how do we stop? We use _exit() with an hopefully unusual exit code. */ _exit (90); } /* Make sure the subshell doesn't field-split on our behalf. */ __unsetenv ("IFS"); __close (fildes[0]); __execve (_PATH_BSHELL, (char *const *) args, __environ); /* Bad. What now? */ abort (); } /* Function to execute a command and retrieve the results */ /* pwordexp contains NULL if field-splitting is forbidden */ static int internal_function exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length, int flags, wordexp_t *pwordexp, const char *ifs, const char *ifs_white) { int fildes[2]; #define bufsize 128 int buflen; int i; int status = 0; size_t maxnewlines = 0; char buffer[bufsize]; pid_t pid; int noexec = 0; /* Don't fork() unless necessary */ if (!comm || !*comm) return 0; #ifdef O_CLOEXEC # ifndef __ASSUME_PIPE2 if (__have_pipe2 >= 0) # endif { int r = __pipe2 (fildes, O_CLOEXEC); # ifndef __ASSUME_PIPE2 if (__have_pipe2 == 0) __have_pipe2 = r != -1 || errno != ENOSYS ? 1 : -1; if (__have_pipe2 > 0) # endif if (r < 0) /* Bad */ return WRDE_NOSPACE; } #endif #ifndef __ASSUME_PIPE2 # ifdef O_CLOEXEC if (__have_pipe2 < 0) # endif if (__pipe (fildes) < 0) /* Bad */ return WRDE_NOSPACE; #endif again: if ((pid = __fork ()) < 0) { /* Bad */ __close (fildes[0]); __close (fildes[1]); return WRDE_NOSPACE; } if (pid == 0) exec_comm_child (comm, fildes, noexec ? 0 : flags & WRDE_SHOWERR, noexec); /* Parent */ /* If we are just testing the syntax, only wait. */ if (noexec) return (TEMP_FAILURE_RETRY (__waitpid (pid, &status, 0)) == pid && status != 0) ? WRDE_SYNTAX : 0; __close (fildes[1]); fildes[1] = -1; if (!pwordexp) /* Quoted - no field splitting */ { while (1) { if ((buflen = TEMP_FAILURE_RETRY (__read (fildes[0], buffer, bufsize))) < 1) { if (TEMP_FAILURE_RETRY (__waitpid (pid, &status, WNOHANG)) == 0) continue; if ((buflen = TEMP_FAILURE_RETRY (__read (fildes[0], buffer, bufsize))) < 1) break; } maxnewlines += buflen; *word = w_addmem (*word, word_length, max_length, buffer, buflen); if (*word == NULL) goto no_space; } } else /* Not quoted - split fields */ { int copying = 0; /* 'copying' is: * 0 when searching for first character in a field not IFS white space * 1 when copying the text of a field * 2 when searching for possible non-whitespace IFS * 3 when searching for non-newline after copying field */ while (1) { if ((buflen = TEMP_FAILURE_RETRY (__read (fildes[0], buffer, bufsize))) < 1) { if (TEMP_FAILURE_RETRY (__waitpid (pid, &status, WNOHANG)) == 0) continue; if ((buflen = TEMP_FAILURE_RETRY (__read (fildes[0], buffer, bufsize))) < 1) break; } for (i = 0; i < buflen; ++i) { if (strchr (ifs, buffer[i]) != NULL) { /* Current character is IFS */ if (strchr (ifs_white, buffer[i]) == NULL) { /* Current character is IFS but not whitespace */ if (copying == 2) { /* current character * | * V * eg: textmoretext * * So, strip whitespace IFS (like at the start) */ copying = 0; continue; } copying = 0; /* fall through and delimit field.. */ } else { if (buffer[i] == '\n') { /* Current character is (IFS) newline */ /* If copying a field, this is the end of it, but maybe all that's left is trailing newlines. So start searching for a non-newline. */ if (copying == 1) copying = 3; continue; } else { /* Current character is IFS white space, but not a newline */ /* If not either copying a field or searching for non-newline after a field, ignore it */ if (copying != 1 && copying != 3) continue; /* End of field (search for non-ws IFS afterwards) */ copying = 2; } } /* First IFS white space (non-newline), or IFS non-whitespace. * Delimit the field. Nulls are converted by w_addword. */ if (w_addword (pwordexp, *word) == WRDE_NOSPACE) goto no_space; *word = w_newword (word_length, max_length); maxnewlines = 0; /* fall back round the loop.. */ } else { /* Not IFS character */ if (copying == 3) { /* Nothing but (IFS) newlines since the last field, so delimit it here before starting new word */ if (w_addword (pwordexp, *word) == WRDE_NOSPACE) goto no_space; *word = w_newword (word_length, max_length); } copying = 1; if (buffer[i] == '\n') /* happens if newline not in IFS */ maxnewlines++; else maxnewlines = 0; *word = w_addchar (*word, word_length, max_length, buffer[i]); if (*word == NULL) goto no_space; } } } } /* Chop off trailing newlines (required by POSIX.2) */ /* Ensure we don't go back further than the beginning of the substitution (i.e. remove maxnewlines bytes at most) */ while (maxnewlines-- != 0 && *word_length > 0 && (*word)[*word_length - 1] == '\n') { (*word)[--*word_length] = '\0'; /* If the last word was entirely newlines, turn it into a new word * which can be ignored if there's nothing following it. */ if (*word_length == 0) { free (*word); *word = w_newword (word_length, max_length); break; } } __close (fildes[0]); fildes[0] = -1; /* Check for syntax error (re-execute but with "-n" flag) */ if (buflen < 1 && status != 0) { noexec = 1; goto again; } return 0; no_space: __kill (pid, SIGKILL); TEMP_FAILURE_RETRY (__waitpid (pid, NULL, 0)); __close (fildes[0]); return WRDE_NOSPACE; } static int internal_function parse_comm (char **word, size_t *word_length, size_t *max_length, const char *words, size_t *offset, int flags, wordexp_t *pwordexp, const char *ifs, const char *ifs_white) { /* We are poised just after "$(" */ int paren_depth = 1; int error = 0; int quoted = 0; /* 1 for singly-quoted, 2 for doubly-quoted */ size_t comm_length; size_t comm_maxlen; char *comm = w_newword (&comm_length, &comm_maxlen); for (; words[*offset]; ++(*offset)) { switch (words[*offset]) { case '\'': if (quoted == 0) quoted = 1; else if (quoted == 1) quoted = 0; break; case '"': if (quoted == 0) quoted = 2; else if (quoted == 2) quoted = 0; break; case ')': if (!quoted && --paren_depth == 0) { /* Go -- give script to the shell */ if (comm) { #ifdef __libc_ptf_call /* We do not want the exec_comm call to be cut short by a thread cancellation since cleanup is very ugly. Therefore disable cancellation for now. */ // XXX Ideally we do want the thread being cancelable. // XXX If demand is there we'll change it. int state = PTHREAD_CANCEL_ENABLE; __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), 0); #endif error = exec_comm (comm, word, word_length, max_length, flags, pwordexp, ifs, ifs_white); #ifdef __libc_ptf_call __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); #endif free (comm); } return error; } /* This is just part of the script */ break; case '(': if (!quoted) ++paren_depth; } comm = w_addchar (comm, &comm_length, &comm_maxlen, words[*offset]); if (comm == NULL) return WRDE_NOSPACE; } /* Premature end. */ free (comm); return WRDE_SYNTAX; } static int internal_function parse_param (char **word, size_t *word_length, size_t *max_length, const char *words, size_t *offset, int flags, wordexp_t *pwordexp, const char *ifs, const char *ifs_white, int quoted) { /* We are poised just after "$" */ enum action { ACT_NONE, ACT_RP_SHORT_LEFT = '#', ACT_RP_LONG_LEFT = 'L', ACT_RP_SHORT_RIGHT = '%', ACT_RP_LONG_RIGHT = 'R', ACT_NULL_ERROR = '?', ACT_NULL_SUBST = '-', ACT_NONNULL_SUBST = '+', ACT_NULL_ASSIGN = '=' }; size_t env_length; size_t env_maxlen; size_t pat_length; size_t pat_maxlen; size_t start = *offset; char *env; char *pattern; char *value = NULL; enum action action = ACT_NONE; int depth = 0; int colon_seen = 0; int seen_hash = 0; int free_value = 0; int pattern_is_quoted = 0; /* 1 for singly-quoted, 2 for doubly-quoted */ int error; int special = 0; char buffer[21]; int brace = words[*offset] == '{'; env = w_newword (&env_length, &env_maxlen); pattern = w_newword (&pat_length, &pat_maxlen); if (brace) ++*offset; /* First collect the parameter name. */ if (words[*offset] == '#') { seen_hash = 1; if (!brace) goto envsubst; ++*offset; } if (isalpha (words[*offset]) || words[*offset] == '_') { /* Normal parameter name. */ do { env = w_addchar (env, &env_length, &env_maxlen, words[*offset]); if (env == NULL) goto no_space; } while (isalnum (words[++*offset]) || words[*offset] == '_'); } else if (isdigit (words[*offset])) { /* Numeric parameter name. */ special = 1; do { env = w_addchar (env, &env_length, &env_maxlen, words[*offset]); if (env == NULL) goto no_space; if (!brace) goto envsubst; } while (isdigit(words[++*offset])); } else if (strchr ("*@$", words[*offset]) != NULL) { /* Special parameter. */ special = 1; env = w_addchar (env, &env_length, &env_maxlen, words[*offset]); if (env == NULL) goto no_space; ++*offset; } else { if (brace) goto syntax; } if (brace) { /* Check for special action to be applied to the value. */ switch (words[*offset]) { case '}': /* Evaluate. */ goto envsubst; case '#': action = ACT_RP_SHORT_LEFT; if (words[1 + *offset] == '#') { ++*offset; action = ACT_RP_LONG_LEFT; } break; case '%': action = ACT_RP_SHORT_RIGHT; if (words[1 + *offset] == '%') { ++*offset; action = ACT_RP_LONG_RIGHT; } break; case ':': if (strchr ("-=?+", words[1 + *offset]) == NULL) goto syntax; colon_seen = 1; action = words[++*offset]; break; case '-': case '=': case '?': case '+': action = words[*offset]; break; default: goto syntax; } /* Now collect the pattern, but don't expand it yet. */ ++*offset; for (; words[*offset]; ++(*offset)) { switch (words[*offset]) { case '{': if (!pattern_is_quoted) ++depth; break; case '}': if (!pattern_is_quoted) { if (depth == 0) goto envsubst; --depth; } break; case '\\': if (pattern_is_quoted) /* Quoted; treat as normal character. */ break; /* Otherwise, it's an escape: next character is literal. */ if (words[++*offset] == '\0') goto syntax; pattern = w_addchar (pattern, &pat_length, &pat_maxlen, '\\'); if (pattern == NULL) goto no_space; break; case '\'': if (pattern_is_quoted == 0) pattern_is_quoted = 1; else if (pattern_is_quoted == 1) pattern_is_quoted = 0; break; case '"': if (pattern_is_quoted == 0) pattern_is_quoted = 2; else if (pattern_is_quoted == 2) pattern_is_quoted = 0; break; } pattern = w_addchar (pattern, &pat_length, &pat_maxlen, words[*offset]); if (pattern == NULL) goto no_space; } } /* End of input string -- remember to reparse the character that we * stopped at. */ --(*offset); envsubst: if (words[start] == '{' && words[*offset] != '}') goto syntax; if (env == NULL) { if (seen_hash) { /* $# expands to the number of positional parameters */ buffer[20] = '\0'; value = _itoa_word (__libc_argc - 1, &buffer[20], 10, 0); seen_hash = 0; } else { /* Just $ on its own */ *offset = start - 1; *word = w_addchar (*word, word_length, max_length, '$'); return *word ? 0 : WRDE_NOSPACE; } } /* Is it a numeric parameter? */ else if (isdigit (env[0])) { int n = atoi (env); if (n >= __libc_argc) /* Substitute NULL. */ value = NULL; else /* Replace with appropriate positional parameter. */ value = __libc_argv[n]; } /* Is it a special parameter? */ else if (special) { /* Is it `$$'? */ if (*env == '$') { buffer[20] = '\0'; value = _itoa_word (__getpid (), &buffer[20], 10, 0); } /* Is it `${#*}' or `${#@}'? */ else if ((*env == '*' || *env == '@') && seen_hash) { buffer[20] = '\0'; value = _itoa_word (__libc_argc > 0 ? __libc_argc - 1 : 0, &buffer[20], 10, 0); *word = w_addstr (*word, word_length, max_length, value); free (env); free (pattern); return *word ? 0 : WRDE_NOSPACE; } /* Is it `$*' or `$@' (unquoted) ? */ else if (*env == '*' || (*env == '@' && !quoted)) { size_t plist_len = 0; int p; char *end; /* Build up value parameter by parameter (copy them) */ for (p = 1; __libc_argv[p]; ++p) plist_len += strlen (__libc_argv[p]) + 1; /* for space */ value = malloc (plist_len); if (value == NULL) goto no_space; end = value; *end = 0; for (p = 1; __libc_argv[p]; ++p) { if (p > 1) *end++ = ' '; end = __stpcpy (end, __libc_argv[p]); } free_value = 1; } else { /* Must be a quoted `$@' */ assert (*env == '@' && quoted); /* Each parameter is a separate word ("$@") */ if (__libc_argc == 2) value = __libc_argv[1]; else if (__libc_argc > 2) { int p; /* Append first parameter to current word. */ value = w_addstr (*word, word_length, max_length, __libc_argv[1]); if (value == NULL || w_addword (pwordexp, value)) goto no_space; for (p = 2; __libc_argv[p + 1]; p++) { char *newword = __strdup (__libc_argv[p]); if (newword == NULL || w_addword (pwordexp, newword)) goto no_space; } /* Start a new word with the last parameter. */ *word = w_newword (word_length, max_length); value = __libc_argv[p]; } else { free (env); free (pattern); return 0; } } } else value = getenv (env); if (value == NULL && (flags & WRDE_UNDEF)) { /* Variable not defined. */ error = WRDE_BADVAL; goto do_error; } if (action != ACT_NONE) { int expand_pattern = 0; /* First, find out if we need to expand pattern (i.e. if we will * use it). */ switch (action) { case ACT_RP_SHORT_LEFT: case ACT_RP_LONG_LEFT: case ACT_RP_SHORT_RIGHT: case ACT_RP_LONG_RIGHT: /* Always expand for these. */ expand_pattern = 1; break; case ACT_NULL_ERROR: case ACT_NULL_SUBST: case ACT_NULL_ASSIGN: if (!value || (!*value && colon_seen)) /* If param is unset, or set but null and a colon has been seen, the expansion of the pattern will be needed. */ expand_pattern = 1; break; case ACT_NONNULL_SUBST: /* Expansion of word will be needed if parameter is set and not null, or set null but no colon has been seen. */ if (value && (*value || !colon_seen)) expand_pattern = 1; break; default: assert (! "Unrecognised action!"); } if (expand_pattern) { /* We need to perform tilde expansion, parameter expansion, command substitution, and arithmetic expansion. We also have to be a bit careful with wildcard characters, as pattern might be given to fnmatch soon. To do this, we convert quotes to escapes. */ char *expanded; size_t exp_len; size_t exp_maxl; char *p; int quoted = 0; /* 1: single quotes; 2: double */ expanded = w_newword (&exp_len, &exp_maxl); for (p = pattern; p && *p; p++) { size_t offset; switch (*p) { case '"': if (quoted == 2) quoted = 0; else if (quoted == 0) quoted = 2; else break; continue; case '\'': if (quoted == 1) quoted = 0; else if (quoted == 0) quoted = 1; else break; continue; case '*': case '?': if (quoted) { /* Convert quoted wildchar to escaped wildchar. */ expanded = w_addchar (expanded, &exp_len, &exp_maxl, '\\'); if (expanded == NULL) goto no_space; } break; case '$': offset = 0; error = parse_dollars (&expanded, &exp_len, &exp_maxl, p, &offset, flags, NULL, NULL, NULL, 1); if (error) { if (free_value) free (value); free (expanded); goto do_error; } p += offset; continue; case '~': if (quoted || exp_len) break; offset = 0; error = parse_tilde (&expanded, &exp_len, &exp_maxl, p, &offset, 0); if (error) { if (free_value) free (value); free (expanded); goto do_error; } p += offset; continue; case '\\': expanded = w_addchar (expanded, &exp_len, &exp_maxl, '\\'); ++p; assert (*p); /* checked when extracted initially */ if (expanded == NULL) goto no_space; } expanded = w_addchar (expanded, &exp_len, &exp_maxl, *p); if (expanded == NULL) goto no_space; } free (pattern); pattern = expanded; } switch (action) { case ACT_RP_SHORT_LEFT: case ACT_RP_LONG_LEFT: case ACT_RP_SHORT_RIGHT: case ACT_RP_LONG_RIGHT: { char *p; char c; char *end; if (value == NULL || pattern == NULL || *pattern == '\0') break; end = value + strlen (value); switch (action) { case ACT_RP_SHORT_LEFT: for (p = value; p <= end; ++p) { c = *p; *p = '\0'; if (fnmatch (pattern, value, 0) != FNM_NOMATCH) { *p = c; if (free_value) { char *newval = __strdup (p); if (newval == NULL) { free (value); goto no_space; } free (value); value = newval; } else value = p; break; } *p = c; } break; case ACT_RP_LONG_LEFT: for (p = end; p >= value; --p) { c = *p; *p = '\0'; if (fnmatch (pattern, value, 0) != FNM_NOMATCH) { *p = c; if (free_value) { char *newval = __strdup (p); if (newval == NULL) { free (value); goto no_space; } free (value); value = newval; } else value = p; break; } *p = c; } break; case ACT_RP_SHORT_RIGHT: for (p = end; p >= value; --p) { if (fnmatch (pattern, p, 0) != FNM_NOMATCH) { char *newval; newval = malloc (p - value + 1); if (newval == NULL) { if (free_value) free (value); goto no_space; } *(char *) __mempcpy (newval, value, p - value) = '\0'; if (free_value) free (value); value = newval; free_value = 1; break; } } break; case ACT_RP_LONG_RIGHT: for (p = value; p <= end; ++p) { if (fnmatch (pattern, p, 0) != FNM_NOMATCH) { char *newval; newval = malloc (p - value + 1); if (newval == NULL) { if (free_value) free (value); goto no_space; } *(char *) __mempcpy (newval, value, p - value) = '\0'; if (free_value) free (value); value = newval; free_value = 1; break; } } break; default: break; } break; } case ACT_NULL_ERROR: if (value && *value) /* Substitute parameter */ break; error = 0; if (!colon_seen && value) /* Substitute NULL */ ; else { const char *str = pattern; if (str[0] == '\0') str = _("parameter null or not set"); __fxprintf (NULL, "%s: %s\n", env, str); } if (free_value) free (value); goto do_error; case ACT_NULL_SUBST: if (value && *value) /* Substitute parameter */ break; if (free_value) free (value); if (!colon_seen && value) /* Substitute NULL */ goto success; value = pattern ? __strdup (pattern) : pattern; free_value = 1; if (pattern && !value) goto no_space; break; case ACT_NONNULL_SUBST: if (value && (*value || !colon_seen)) { if (free_value) free (value); value = pattern ? __strdup (pattern) : pattern; free_value = 1; if (pattern && !value) goto no_space; break; } /* Substitute NULL */ if (free_value) free (value); goto success; case ACT_NULL_ASSIGN: if (value && *value) /* Substitute parameter */ break; if (!colon_seen && value) { /* Substitute NULL */ if (free_value) free (value); goto success; } if (free_value) free (value); value = pattern ? __strdup (pattern) : pattern; free_value = 1; if (pattern && !value) goto no_space; __setenv (env, value, 1); break; default: assert (! "Unrecognised action!"); } } free (env); env = NULL; free (pattern); pattern = NULL; if (seen_hash) { char param_length[21]; param_length[20] = '\0'; *word = w_addstr (*word, word_length, max_length, _itoa_word (value ? strlen (value) : 0, ¶m_length[20], 10, 0)); if (free_value) { assert (value != NULL); free (value); } return *word ? 0 : WRDE_NOSPACE; } if (value == NULL) return 0; if (quoted || !pwordexp) { /* Quoted - no field split */ *word = w_addstr (*word, word_length, max_length, value); if (free_value) free (value); return *word ? 0 : WRDE_NOSPACE; } else { /* Need to field-split */ char *value_copy = __strdup (value); /* Don't modify value */ char *field_begin = value_copy; int seen_nonws_ifs = 0; if (free_value) free (value); if (value_copy == NULL) goto no_space; do { char *field_end = field_begin; char *next_field; /* If this isn't the first field, start a new word */ if (field_begin != value_copy) { if (w_addword (pwordexp, *word) == WRDE_NOSPACE) { free (value_copy); goto no_space; } *word = w_newword (word_length, max_length); } /* Skip IFS whitespace before the field */ field_begin += strspn (field_begin, ifs_white); if (!seen_nonws_ifs && *field_begin == 0) /* Nothing but whitespace */ break; /* Search for the end of the field */ field_end = field_begin + strcspn (field_begin, ifs); /* Set up pointer to the character after end of field and skip whitespace IFS after it. */ next_field = field_end + strspn (field_end, ifs_white); /* Skip at most one non-whitespace IFS character after the field */ seen_nonws_ifs = 0; if (*next_field && strchr (ifs, *next_field)) { seen_nonws_ifs = 1; next_field++; } /* Null-terminate it */ *field_end = 0; /* Tag a copy onto the current word */ *word = w_addstr (*word, word_length, max_length, field_begin); if (*word == NULL && *field_begin != '\0') { free (value_copy); goto no_space; } field_begin = next_field; } while (seen_nonws_ifs || *field_begin); free (value_copy); } return 0; success: error = 0; goto do_error; no_space: error = WRDE_NOSPACE; goto do_error; syntax: error = WRDE_SYNTAX; do_error: free (env); free (pattern); return error; } static int internal_function parse_dollars (char **word, size_t *word_length, size_t *max_length, const char *words, size_t *offset, int flags, wordexp_t *pwordexp, const char *ifs, const char *ifs_white, int quoted) { /* We are poised _at_ "$" */ switch (words[1 + *offset]) { case '"': case '\'': case 0: *word = w_addchar (*word, word_length, max_length, '$'); return *word ? 0 : WRDE_NOSPACE; case '(': if (words[2 + *offset] == '(') { /* Differentiate between $((1+3)) and $((echo);(ls)) */ int i = 3 + *offset; int depth = 0; while (words[i] && !(depth == 0 && words[i] == ')')) { if (words[i] == '(') ++depth; else if (words[i] == ')') --depth; ++i; } if (words[i] == ')' && words[i + 1] == ')') { (*offset) += 3; /* Call parse_arith -- 0 is for "no brackets" */ return parse_arith (word, word_length, max_length, words, offset, flags, 0); } } if (flags & WRDE_NOCMD) return WRDE_CMDSUB; (*offset) += 2; return parse_comm (word, word_length, max_length, words, offset, flags, quoted? NULL : pwordexp, ifs, ifs_white); case '[': (*offset) += 2; /* Call parse_arith -- 1 is for "brackets" */ return parse_arith (word, word_length, max_length, words, offset, flags, 1); case '{': default: ++(*offset); /* parse_param needs to know if "{" is there */ return parse_param (word, word_length, max_length, words, offset, flags, pwordexp, ifs, ifs_white, quoted); } } static int internal_function parse_backtick (char **word, size_t *word_length, size_t *max_length, const char *words, size_t *offset, int flags, wordexp_t *pwordexp, const char *ifs, const char *ifs_white) { /* We are poised just after "`" */ int error; int squoting = 0; size_t comm_length; size_t comm_maxlen; char *comm = w_newword (&comm_length, &comm_maxlen); for (; words[*offset]; ++(*offset)) { switch (words[*offset]) { case '`': /* Go -- give the script to the shell */ error = exec_comm (comm, word, word_length, max_length, flags, pwordexp, ifs, ifs_white); free (comm); return error; case '\\': if (squoting) { error = parse_qtd_backslash (&comm, &comm_length, &comm_maxlen, words, offset); if (error) { free (comm); return error; } break; } ++(*offset); error = parse_backslash (&comm, &comm_length, &comm_maxlen, words, offset); if (error) { free (comm); return error; } break; case '\'': squoting = 1 - squoting; default: comm = w_addchar (comm, &comm_length, &comm_maxlen, words[*offset]); if (comm == NULL) return WRDE_NOSPACE; } } /* Premature end */ free (comm); return WRDE_SYNTAX; } static int internal_function parse_dquote (char **word, size_t *word_length, size_t *max_length, const char *words, size_t *offset, int flags, wordexp_t *pwordexp, const char * ifs, const char * ifs_white) { /* We are poised just after a double-quote */ int error; for (; words[*offset]; ++(*offset)) { switch (words[*offset]) { case '"': return 0; case '$': error = parse_dollars (word, word_length, max_length, words, offset, flags, pwordexp, ifs, ifs_white, 1); /* The ``1'' here is to tell parse_dollars not to * split the fields. It may need to, however ("$@"). */ if (error) return error; break; case '`': if (flags & WRDE_NOCMD) return WRDE_CMDSUB; ++(*offset); error = parse_backtick (word, word_length, max_length, words, offset, flags, NULL, NULL, NULL); /* The first NULL here is to tell parse_backtick not to * split the fields. */ if (error) return error; break; case '\\': error = parse_qtd_backslash (word, word_length, max_length, words, offset); if (error) return error; break; default: *word = w_addchar (*word, word_length, max_length, words[*offset]); if (*word == NULL) return WRDE_NOSPACE; } } /* Unterminated string */ return WRDE_SYNTAX; } /* * wordfree() is to be called after pwordexp is finished with. */ void wordfree (wordexp_t *pwordexp) { /* wordexp can set pwordexp to NULL */ if (pwordexp && pwordexp->we_wordv) { char **wordv = pwordexp->we_wordv; for (wordv += pwordexp->we_offs; *wordv; ++wordv) free (*wordv); free (pwordexp->we_wordv); pwordexp->we_wordv = NULL; } } libc_hidden_def (wordfree) /* * wordexp() */ int wordexp (const char *words, wordexp_t *pwordexp, int flags) { size_t words_offset; size_t word_length; size_t max_length; char *word = w_newword (&word_length, &max_length); int error; char *ifs; char ifs_white[4]; wordexp_t old_word = *pwordexp; if (flags & WRDE_REUSE) { /* Minimal implementation of WRDE_REUSE for now */ wordfree (pwordexp); old_word.we_wordv = NULL; } if ((flags & WRDE_APPEND) == 0) { pwordexp->we_wordc = 0; if (flags & WRDE_DOOFFS) { pwordexp->we_wordv = calloc (1 + pwordexp->we_offs, sizeof (char *)); if (pwordexp->we_wordv == NULL) { error = WRDE_NOSPACE; goto do_error; } } else { pwordexp->we_wordv = calloc (1, sizeof (char *)); if (pwordexp->we_wordv == NULL) { error = WRDE_NOSPACE; goto do_error; } pwordexp->we_offs = 0; } } /* Find out what the field separators are. * There are two types: whitespace and non-whitespace. */ ifs = getenv ("IFS"); if (ifs == NULL) /* IFS unset - use . */ ifs = strcpy (ifs_white, " \t\n"); else { char *ifsch = ifs; char *whch = ifs_white; while (*ifsch != '\0') { if (*ifsch == ' ' || *ifsch == '\t' || *ifsch == '\n') { /* Whitespace IFS. See first whether it is already in our collection. */ char *runp = ifs_white; while (runp < whch && *runp != *ifsch) ++runp; if (runp == whch) *whch++ = *ifsch; } ++ifsch; } *whch = '\0'; } for (words_offset = 0 ; words[words_offset] ; ++words_offset) switch (words[words_offset]) { case '\\': error = parse_backslash (&word, &word_length, &max_length, words, &words_offset); if (error) goto do_error; break; case '$': error = parse_dollars (&word, &word_length, &max_length, words, &words_offset, flags, pwordexp, ifs, ifs_white, 0); if (error) goto do_error; break; case '`': if (flags & WRDE_NOCMD) { error = WRDE_CMDSUB; goto do_error; } ++words_offset; error = parse_backtick (&word, &word_length, &max_length, words, &words_offset, flags, pwordexp, ifs, ifs_white); if (error) goto do_error; break; case '"': ++words_offset; error = parse_dquote (&word, &word_length, &max_length, words, &words_offset, flags, pwordexp, ifs, ifs_white); if (error) goto do_error; if (!word_length) { error = w_addword (pwordexp, NULL); if (error) return error; } break; case '\'': ++words_offset; error = parse_squote (&word, &word_length, &max_length, words, &words_offset); if (error) goto do_error; if (!word_length) { error = w_addword (pwordexp, NULL); if (error) return error; } break; case '~': error = parse_tilde (&word, &word_length, &max_length, words, &words_offset, pwordexp->we_wordc); if (error) goto do_error; break; case '*': case '[': case '?': error = parse_glob (&word, &word_length, &max_length, words, &words_offset, flags, pwordexp, ifs, ifs_white); if (error) goto do_error; break; default: /* Is it a word separator? */ if (strchr (" \t", words[words_offset]) == NULL) { char ch = words[words_offset]; /* Not a word separator -- but is it a valid word char? */ if (strchr ("\n|&;<>(){}", ch)) { /* Fail */ error = WRDE_BADCHAR; goto do_error; } /* "Ordinary" character -- add it to word */ word = w_addchar (word, &word_length, &max_length, ch); if (word == NULL) { error = WRDE_NOSPACE; goto do_error; } break; } /* If a word has been delimited, add it to the list. */ if (word != NULL) { error = w_addword (pwordexp, word); if (error) goto do_error; } word = w_newword (&word_length, &max_length); } /* End of string */ /* There was a word separator at the end */ if (word == NULL) /* i.e. w_newword */ return 0; /* There was no field separator at the end */ return w_addword (pwordexp, word); do_error: /* Error: * free memory used (unless error is WRDE_NOSPACE), and * set pwordexp members back to what they were. */ free (word); if (error == WRDE_NOSPACE) return WRDE_NOSPACE; if ((flags & WRDE_APPEND) == 0) wordfree (pwordexp); *pwordexp = old_word; return error; } ccbuild-2.0.9/src/posix/wordexp.h000066400000000000000000000047141402074776400167420ustar00rootroot00000000000000/* Copyright (C) 1991, 92, 1996-1999, 2001, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 General Public License along with this program. If not, see .*/ #ifndef _WORDEXP_H #define _WORDEXP_H 1 #include #define __need_size_t #include __BEGIN_DECLS /* Bits set in the FLAGS argument to `wordexp'. */ enum { WRDE_DOOFFS = (1 << 0), /* Insert PWORDEXP->we_offs NULLs. */ WRDE_APPEND = (1 << 1), /* Append to results of a previous call. */ WRDE_NOCMD = (1 << 2), /* Don't do command substitution. */ WRDE_REUSE = (1 << 3), /* Reuse storage in PWORDEXP. */ WRDE_SHOWERR = (1 << 4), /* Don't redirect stderr to /dev/null. */ WRDE_UNDEF = (1 << 5), /* Error for expanding undefined variables. */ __WRDE_FLAGS = (WRDE_DOOFFS | WRDE_APPEND | WRDE_NOCMD | WRDE_REUSE | WRDE_SHOWERR | WRDE_UNDEF) }; /* Structure describing a word-expansion run. */ typedef struct { size_t we_wordc; /* Count of words matched. */ char **we_wordv; /* List of expanded words. */ size_t we_offs; /* Slots to reserve in `we_wordv'. */ } wordexp_t; /* Possible nonzero return values from `wordexp'. */ enum { #ifdef __USE_XOPEN WRDE_NOSYS = -1, /* Never used since we support `wordexp'. */ #endif WRDE_NOSPACE = 1, /* Ran out of memory. */ WRDE_BADCHAR, /* A metachar appears in the wrong place. */ WRDE_BADVAL, /* Undefined var reference with WRDE_UNDEF. */ WRDE_CMDSUB, /* Command substitution with WRDE_NOCMD. */ WRDE_SYNTAX /* Shell syntax error. */ }; /* Do word expansion of WORDS into PWORDEXP. */ extern int wordexp (__const char *__restrict __words, wordexp_t *__restrict __pwordexp, int __flags); /* Free the storage allocated by a `wordexp' call. */ extern void wordfree (wordexp_t *__wordexp) __THROW; __END_DECLS #endif /* wordexp.h */ ccbuild-2.0.9/src/problem/000077500000000000000000000000001402074776400153715ustar00rootroot00000000000000ccbuild-2.0.9/src/problem/problem.cc000066400000000000000000000014741402074776400173460ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "problem.ih" Problem::Problem(Id problemId, std::string const &message, int status) throw() : d_stat(status), d_msg(message), d_id(problemId) {} ccbuild-2.0.9/src/problem/problem.hh000066400000000000000000000040471402074776400173570ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ #ifndef Problem_HH_INCLUDED_ #define Problem_HH_INCLUDED_ #include namespace bneijt { class Problem: public std::exception { int d_stat; std::string d_msg; public: enum Id { Subfailure = 1, /// 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 3 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, see . */ #include "problem.hh" using namespace bneijt; ccbuild-2.0.9/src/resolver/000077500000000000000000000000001402074776400155725ustar00rootroot00000000000000ccbuild-2.0.9/src/resolver/destroy.cc000066400000000000000000000016011402074776400175700ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "resolver.ih" void Resolver::destroy() { OpenMP::ScopedLock instantiateLock(s_instanceLock); if(s_instance) { delete s_instance; } else { _debugLevel1("Already destroyed!!"); } s_instance = 0; } ccbuild-2.0.9/src/resolver/expand.cc000066400000000000000000000063431402074776400173660ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "resolver.ih" namespace { bool hasSpaces(char const *w) { if(w) for(size_t i = 0; w[i] != '\0'; ++i) if(w[i] == ' ') { return true; } return false; } } string Resolver::expand(std::string const &name) const { #if defined(__CYGWIN__) or defined(__APPLE_C__) or defined(__APPLE__) //TODO Replace this with sh -c 'for i;do echo $i;done' dummy HELLO HOW ARE YOU //TODO to make sure that it handles quoted arguments correctly. Then it can //TODO very probably become the default. ostringstream pathstr("", ios::app); string echo("echo " + name); ostringstream os; FILE *f = popen(echo.c_str(), "r"); assert(f != 0); int read = 0; char buf[2]; // read 1 byte at the time buf[1] = 0; // null terminated while ((read = fread(buf, 1, 1, f) != 0)) { pathstr << buf; } return pathstr.str(); #else ostringstream pathstr("", ios::app); wordexp_t p; char **w; int retv = wordexp(name.c_str(), &p, 0); if(retv != 0) { cerr << "ccbuild: Error shell expanding '" << name << "'.\n"; switch(retv) { case WRDE_BADCHAR: cerr << "ccbuild: Illegal occurrence of newline or one of |, &, ;, <, >, (, ), {,}.\n"; break; // case WRDE_BADVAL: // cerr << "ccbuild: An undefined shell variable was referenced, and the WRDE_UNDEF flag told us to consider this an error.\n"; // break; case WRDE_CMDSUB: cerr << "ccbuild: Command substitution occurred, and the WRDE_NOCMD flag told us\n"; cerr << "ccbuild: to consider this an error.\n"; break; case WRDE_NOSPACE: cerr << "ccbuild: Out of memory.\n"; break; case WRDE_SYNTAX: cerr << "ccbuild: Shell syntax error, such as unbalanced parentheses or unmatched quotes.\n"; break; } //Flush error stream cerr << "ccbuild: You might want to check your ccResolutions file." << endl; } else { w = p.we_wordv; if(hasSpaces(w[0])) { pathstr << "\"" << w[0] << "\""; } else { pathstr << w[0]; } for (unsigned i = 1; i < p.we_wordc; ++i) { //Quick patch: quote only on words with spaces if(hasSpaces(w[i])) { pathstr << " \"" << w[i] << "\""; } else { pathstr << " " << w[i]; } } //wordfree segfaults if wordexp failed wordfree(&p); } return pathstr.str(); #endif } ccbuild-2.0.9/src/resolver/getInstance.cc000066400000000000000000000015441402074776400203510ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "resolver.ih" Resolver & Resolver::getInstance() { OpenMP::ScopedLock instantiateLock(s_instanceLock); if(s_instance == 0) { s_instance = new Resolver(); } return *s_instance; } ccbuild-2.0.9/src/resolver/loadIfExists.cc000066400000000000000000000057031402074776400205040ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "resolver.ih" bool Resolver::loadIfExists(std::string const &confFile, bool report) { //Load a configuration file if it exists ifstream file(confFile.c_str()); _debugLevel1("Loading: '" << confFile << "'"); std::vector lines; map expandCache; Globals &globs = Globals::getInstance(); if(!file.is_open()) { _debugLevel1("Unable to open: " << confFile); if(report) { cerr << "ccbuild: Unable to open: '" << confFile << "'\n"; } return false; } unsigned linenr=0; while(true) { string line; string global, arguments; getline(file, line); ++linenr; if(file.eof()) { break; } if(line.size() < 1) { //Empty lines continue; } if(line[0] == '#') { //Comment lines continue; } //Find a seperating tab string::size_type i = line.find_first_of("\t"); if(i == string::npos) { //Try to recover with a space seperation i = line.find_first_of(" "); } global = line.substr(0, i); arguments = ""; if(i != string::npos) { arguments = line.substr(i + 1); } System::trim(&global); System::trim(&arguments); string const *globalPointer = globs[global]; //Only add link if it isn't mentioned before! if(d_staticLinks.count(globalPointer)) { continue; } //Use local expand cache if(expandCache.find(arguments) == expandCache.end()) { expandCache[arguments] = new string(expand(arguments)); } if(System::trimmed(*expandCache[arguments]).size() == 0 && arguments.size() > 0) { cerr << "ccbuild: Warning: Expansion to an empty string,\nccbuild: Warning: from \"" << arguments << "\"\n"; } _debugLevel4("Link: '" << global << "' -> '" << arguments << "'"); d_staticLinks[globalPointer] = expandCache[arguments]; } file.close(); if(Options::verbose) { cerr << "Loaded resolutions file: " << confFile << "\n"; } //Clean up expand cache?? //NO The pointer part is stored in d_staticLinks // and will be deleted when the Resolver is destroyed. return true; } ccbuild-2.0.9/src/resolver/resolve.cc000066400000000000000000000027241402074776400175650ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "resolver.ih" std::string Resolver::resolve(std::string const &include) const { _debugLevel3("Resolving: " << include); Globals &globs = Globals::getInstance(); //Stupid but safe! std::string const *includePointer = globs[include]; //Check statics std::map::const_iterator it = d_staticLinks.find(includePointer); if(it != d_staticLinks.end()) { return *(*it).second; } return "FAIL"; } std::string Resolver::resolve(std::string const *includePointer) const { _debugLevel3("Resolving: " << *includePointer); //Check statics std::map::const_iterator it = d_staticLinks.find(includePointer); if(it != d_staticLinks.end()) { return *(*it).second; } return "FAIL"; } ccbuild-2.0.9/src/resolver/resolveInto.cc000066400000000000000000000021621402074776400204130ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "resolver.ih" bool Resolver::resolveInto(std::string const *include, Compiler & cc, bool quiet) const { string argument = resolve(include); //TODO: use exceptions?? if(argument == "FAIL") { if(not Options::noWarn) if(! quiet) { cerr << "ccbuild: Unable to resolve: \"" << *include << "\"\n"; } return false; } if(argument.size() > 0) { cc.addArgument(argument); } return true; } ccbuild-2.0.9/src/resolver/resolver.cc000066400000000000000000000062551402074776400177520ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "resolver.ih" Resolver::Resolver() : d_staticLinks(), d_empty("") { //Load commandline given extra resolution files __foreach(xr, Options::extraResolutions) loadIfExists(*xr, true);//Load if exists, reporting errors //Load default //Try username, try hostname dependent, try system name, try architecture dependent, try username, try default loadIfExists("./ccResolutions."+ System::username()) || loadIfExists("./ccResolutions."+System::uname('n')) || loadIfExists("./ccResolutions."+System::uname('s')) || loadIfExists("./ccResolutions."+System::uname('m')) || loadIfExists("./ccResolutions"); //Load global resolution files if(Options::loadGlobalRes) { _debugLevel3("Loading global resolution files"); loadIfExists(expand("~/.ccbuild/ccResolutions")); //The ccResolutions directory vector files; FileSystem::globFilesInto(&files, "~/.ccbuild/ccResolutions.d/*", true); __foreach(file, files) loadIfExists(*file); } Globals &gl = Globals::getInstance(); //ANSI C++ headers... static char const * const ccHeaders[] = { "algorithm", "bitset", "deque", "exception", "fstream", "functional", "iomanip", "ios", "iosfwd", "iostream", "istream", "iterator", "limits", "list", "locale", "map", "memory", "new", "numeric", "ostream", "queue", "set", "sstream", "stack", "stdexcept", "streambuf", "string", "typeinfo", "utility", "valarray", "vector", //C++ equivalent of ANSI C headers... "cassert", "cctype", "cerrno", "cfloat", "ciso646", "climits", "clocale", "cmath", "csetjmp", "csignal", "cstdarg", "cstddef", "cstdio", "cstdlib", "cstring", "ctime", "cwchar", "cwtype", 0 }; for(unsigned i = 0; ccHeaders[i]; ++i) if(d_staticLinks.count(gl[ccHeaders[i]]) == 0) { d_staticLinks[gl[ccHeaders[i]]] = &d_empty; } } Resolver::~Resolver() { //Todo: cleanup using unique_copy etc. set pointers; __foreach(link, d_staticLinks) pointers.insert((*link).second); pointers.erase(&d_empty); __foreach(pointer, pointers) delete (*pointer); } ccbuild-2.0.9/src/resolver/resolver.hh000066400000000000000000000063121402074776400177560ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ #ifndef Resolver_H_INCLUDED_ #define Resolver_H_INCLUDED_ #include #include #include #include #include "../openmp/lock/lock.hh" #include "../compiler/compiler.hh" namespace bneijt { ///\brief Gobal header -> compiler arguments resolver /// ///This class will do all header to compiler arguments resolution class Resolver { std::map d_staticLinks; ///< Link global to argument std::string d_empty; /// 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 3 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, see . */ #include "resolver.hh" #include "../fileSystem/fileSystem.hh" #include "../system/system.hh" #include "../globals/globals.hh" #include "../openmp/scopedLock/scopedLock.hh" #include "../misc/foreach.hh" //#define DEBUGLEVEL 1 #include "../misc/debug.hh" #include #include #include #include #include #include #include "../posix/wordexp.h" using namespace bneijt; using namespace std; ccbuild-2.0.9/src/resolver/statics.cc000066400000000000000000000014121402074776400175510ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "resolver.ih" Resolver *Resolver::s_instance; OpenMP::Lock Resolver::s_instanceLock; ///. */ #include "source.ih" std::string Source::basenameWithoutExtension() const { std::string basename = FileSystem::baseName(d_filename); std::string::size_type i = basename.rfind('.'); if(i == string::npos) { throw Problem(Problem::Missing, "Can not find extension in a file which was requested without extension. Basename: " + basename); } return basename.substr(0, i); } ccbuild-2.0.9/src/source/build.cc000066400000000000000000000023651402074776400166450ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" void Source::build(Compiler & cc) { d_apiLock.set(); //Protect d_filename if(!FileSystem::isReadable(d_filename)) { cerrLock.set(); cerr << "ccbuild: Warning: Trying to build a non-readable file: '" << d_filename << "'" << endl; cerrLock.unset(); } d_apiLock.unset(); if(isHeader()) { buildHeader(cc); } else if(isObjectTarget()) { buildObjectTarget(cc); } else { d_apiLock.set(); //Protect d_filename cerr << "ccbuild: Error: Unknown file type: " << d_filename << "\n"; d_apiLock.unset(); } } ccbuild-2.0.9/src/source/buildBinTarget.cc000066400000000000000000000041501402074776400204370ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" void Source::buildBinTarget(Compiler & cc) { OpenMP::ScopedLock slock(d_apiLock); _debugLevel4("Output filename: " << outputFilename()); vector srcList; vector globalList; dependencies(srcList, globalList); Resolver &resolver = Resolver::getInstance(); //Resolve all globals into the compiler __foreach(global, globalList) resolver.resolveInto(*global, cc); if(!upToDate(srcList)) { //Need an update string outputDirectory = directory() + "/o"; //Check for object directory existence (exists("o")) _debugLevel2("Ensure " + outputDirectory); FileSystem::ensureDirectory(outputDirectory); //Now, we have a compiler with all the objects in it. int ret = cc.compile(d_filename, outputFilename()); //Compilation OK //Update hash if(Options::md5 && ret == 0) { MD5Info &md5i = MD5Info::getInstance(); string collectedHash = md5i.contentHash(filename()); vector depSrcList; dependencies(depSrcList); __foreach(src, depSrcList) collectedHash += md5i.contentHash((*src)->filename()); md5i.save(filename(), collectedHash); } } //Now all local children are build, so now we can build our own functions. //compile me //Add my object to the list of objects in the compiler. cc.addObject(outputFilename()); } ccbuild-2.0.9/src/source/buildHeader.cc000066400000000000000000000031371402074776400177540ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" void Source::buildHeader(Compiler & cc) { OpenMP::ScopedLock slock(d_apiLock); //To build a header, precompile it vector srcList; vector globalList; dependencies(srcList, globalList); Resolver &resolver = Resolver::getInstance(); //Resolve all globals into the compiler __foreach(global, globalList) resolver.resolveInto(*global, cc); if(!upToDate(srcList)) { int ret = cc.precompile(d_filename, outputFilename()); //Compilation OK //Update hash if(Options::md5 && ret == 0) { MD5Info &md5i = MD5Info::getInstance(); string collectedHash = md5i.contentHash(filename()); vector depSrcList; dependencies(depSrcList); __foreach(src, depSrcList) collectedHash += md5i.contentHash((*src)->filename()); md5i.save(filename(), collectedHash); } } } ccbuild-2.0.9/src/source/buildObjectTarget.cc000066400000000000000000000037111402074776400211370ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" void Source::buildObjectTarget(Compiler &cc) { OpenMP::ScopedLock slock(d_apiLock); vector srcList; vector globalList; dependencies(srcList, globalList); Resolver &resolver = Resolver::getInstance(); //Resolve all globals into the compiler __foreach(global, globalList) resolver.resolveInto(*global, cc); if(!upToDate(srcList)) { //Need an update string outputDirectory = FileSystem::directoryName(outputFilename());//OLD directory() + "/o"; //Check for object directory existence (exists("o")) FileSystem::ensureDirectory(outputDirectory); //Now, we have a compiler with all the objects in it. int ret = cc.compile(d_filename, outputFilename()); //Compilation OK //Update hash if(Options::md5 && ret == 0) { MD5Info &md5i = MD5Info::getInstance(); string collectedHash = md5i.contentHash(filename()); vector depSrcList; dependencies(depSrcList); __foreach(src, depSrcList) collectedHash += md5i.contentHash((*src)->filename()); md5i.save(filename(), collectedHash); } } //Add my object to the list of objects in the compiler. cc.addObject(outputFilename()); } ccbuild-2.0.9/src/source/changed.cc000066400000000000000000000034441402074776400171360ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" bool Source::changed() const { //Without output, we can't check. So we probably are old if(producesOutput() && !FileSystem::fileExists(outputFilename())) { _debugLevel1("File changed because it produces output and the output does not exist\n" << " filename: " << outputFilename() ); return true; } //MD5 check if(Options::md5) { //This file has changed if the first 32 chars of it's contentHash are // not the same as the first 32 chars of it's stored hash. MD5Info &md5i = MD5Info::getInstance(); return md5i.old(filename()).compare(0, 32, md5i.contentHash(filename())) != 0; } return FileSystem::newer(filename(), outputFilename()); } bool Source::changed(std::string const &relativeToThis) const { //Relative changes are only checkable with timestamps currently assert(Options::md5 == false); //Wether we create output or not, we can check our status //According to this "relativeToThis" output. return FileSystem::newer(filename(), relativeToThis); } ccbuild-2.0.9/src/source/dependencies.cc000066400000000000000000000056121402074776400201720ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" void Source::dependencies(std::vector &srcList) const { if(!d_depsDone) { throw Problem(Problem::Unable, "Unable to load dependencies without the file being scanned."); } //Collect all Source pointers needed stack srcStack; srcStack.push(const_cast(this)); //Gather all the global includes and sources while(srcStack.size() > 0) { Source * current = srcStack.top(); srcStack.pop(); //Have we seen this source? if(find(srcList.begin(), srcList.end(), current) != srcList.end()) { continue; } //Copy dependencies to stack. vector deps; current->directDeps(deps); //Push all sources to the stack __foreach(dep, deps) { srcStack.push(*dep); } //Never collect this in the list if(current != this) { srcList.push_back(current); } } _debugLevel2("Stacked up " << srcList.size() << " dependencies for " << d_filename); } void Source::dependencies(std::vector &srcList, std::vector &globalList) const { //Collect all Source pointers needed stack srcStack; srcStack.push(const_cast(this)); set globalSet(d_globalDeps); //Gather all the global includes and sources while(srcStack.size() > 0) { Source *current = srcStack.top(); srcStack.pop(); //Have we seen this source? if(find(srcList.begin(), srcList.end(), current) != srcList.end()) { continue; } //Copy dependencies to stack. vector deps; vector globals; current->directDeps(deps, globals); //Push all sources to the stack __foreach(dep, deps) { srcStack.push(*dep); } //Copy new global includes to the list. copy(globals.begin(), globals.end(), inserter(globalSet, globalSet.begin())); srcList.push_back(current); } srcList.erase(srcList.begin()); //Remove "this" from the srcList; copy(globalSet.begin(), globalSet.end(), back_inserter(globalList)); } ccbuild-2.0.9/src/source/directDeps.cc000066400000000000000000000032721402074776400176320ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" void Source::directDeps(std::vector &localDeps, std::vector &globalDeps, std::vector &ignored) const { if(!d_depsDone) { throw Problem(Problem::Unable, "Unable to get directDeps without the file being scanned."); } localDeps = d_deps; copy(d_globalDeps.begin(), d_globalDeps.end(), back_inserter(globalDeps)); //String copying! ignored = d_ignored; } void Source::directDeps(std::vector &localDeps, std::vector &globalDeps) const { if(!d_depsDone) { throw Problem(Problem::Unable, "Unable to get directDeps without the file being scanned."); } localDeps = d_deps; copy(d_globalDeps.begin(), d_globalDeps.end(), back_inserter(globalDeps)); } void Source::directDeps(std::vector &localDeps) const { if(!d_depsDone) { throw Problem(Problem::Unable, "Unable to get directDeps without the file being scanned."); } localDeps = d_deps; } ccbuild-2.0.9/src/source/directory.cc000066400000000000000000000015341402074776400175470ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" std::string Source::directory() const { //Return current directory name return FileSystem::directoryName(d_filename); } ccbuild-2.0.9/src/source/genDeps.cc000066400000000000000000000063041402074776400171300ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" void Source::genDeps() { //If we already have deps, we are done. if(d_depsDone) { return; } d_apiLock.set(); if(d_depsDone) { return; } d_depsDone = true; //TODO Use an atomic variable for these kinds of checks? Sources &sources = Sources::getInstance(); //stack srcStack; //vector srcList; vector localIncludes, globalDeps; scan(&localIncludes, &globalDeps); Globals &globs = Globals::getInstance(); __foreach(globalDep, globalDeps) d_globalDeps.insert(globs[*globalDep]); __foreach(li, localIncludes) { std::string iname(directory() + "/" + *li); _debugLevel4("Loading source for local include: " << iname); Source *s = sources[iname]; if(s == this) { cerrLock.set(); cerr << "ccbuild: Recursive include encountered in '" << filename() << "'\n"; cerr << "ccbuild: ignoring self dependency.\n"; cerrLock.unset(); continue; } //if it's not there, try it from the local directory (The -I. might be used on the source tree) /*This variant is used for header files of your own program. It searches for a file named file first in the directory containing the current file, then in the quote directories and then the same directories used for . You can prepend directories to the list of quote directories with the -iquote option.*/ //-I option for ccbuild local resolution vector includePaths(Options::includePaths); __foreach(path, includePaths) { if(s != 0) { break; } _debugLevel4("Trying path: " << *path << " for " << *li); s = sources[*path + "/" + *li]; } if(s == 0) { cerrLock.set(); cerr << "ccbuild: Unable to read '" << iname << "'\n"; cerr << "ccbuild: mentioned in '" << filename() << "'\n"; cerrLock.unset(); continue; } d_deps.push_back(s); } _debugLevel2("genDeps done: " << d_deps.size() << " local, " << d_globalDeps.size() << " global, and " << d_ignored.size() << " ignored includes\n\t for file " << d_filename); //Trigger generation of sub-source dependencies: copy pointers, unlock api, call sub-generation vector deps(d_deps.begin(), d_deps.end()); d_apiLock.unset(); __foreach(dep, deps) (*dep)->genDeps(); //All sources we _directly_ depend on now have d_deps filled and genDeps ran. } ccbuild-2.0.9/src/source/hasSourceExtension.cc000066400000000000000000000030271402074776400213730ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" bool Source::hasSourceExtension() const { //Return true if this source has an extension // *.cc .cp *.cxx *.cpp *.c++ *.C if(d_filename.size() > 1 && d_filename.substr(d_filename.size() - 2) == ".C") { return true; } if(d_filename.size() > 2 && d_filename.substr(d_filename.size() - 3) == ".cc") { return true; } if(d_filename.size() > 2 && d_filename.substr(d_filename.size() - 3) == ".cp") { return true; } if(d_filename.size() > 3 && d_filename.substr(d_filename.size() - 4) == ".cxx") { return true; } if(d_filename.size() > 3 && d_filename.substr(d_filename.size() - 4) == ".cpp") { return true; } if(d_filename.size() > 3 && d_filename.substr(d_filename.size() - 4) == ".c++") { return true; } return false; } ccbuild-2.0.9/src/source/isBinTarget.cc000066400000000000000000000015071402074776400177560ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" bool Source::isBinTarget() const { //Return true if this source contains a //"int main(" function return d_hasMainFunction && hasSourceExtension(); } ccbuild-2.0.9/src/source/isHeader.cc000066400000000000000000000013771402074776400172740ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" bool Source::isHeader() const { return isLocalHeader() || isInternalHeader(); } ccbuild-2.0.9/src/source/isInternalHeader.cc000066400000000000000000000014561402074776400207670ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" bool Source::isInternalHeader() const { return d_srcType == InternalHeader; } ccbuild-2.0.9/src/source/isLibTarget.cc000066400000000000000000000016111402074776400177500ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" bool Source::isLibTarget() const { if(d_hasMainFunction || d_filename.size() < 5 || (! hasSourceExtension()) ) { return false; } return d_filename.substr(0, 3) == "lib"; } ccbuild-2.0.9/src/source/isLocalHeader.cc000066400000000000000000000013611402074776400202400ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" bool Source::isLocalHeader() const { return d_srcType == LocalHeader; } ccbuild-2.0.9/src/source/isObjectTarget.cc000066400000000000000000000015401402074776400204510ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" bool Source::isObjectTarget() const { //It is an object target is it has a source extension return hasSourceExtension(); } ccbuild-2.0.9/src/source/markAsDone.cc000066400000000000000000000021421402074776400175630ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" void Source::markAsDone() const { //If this is not MD5, then everything should be automatic if(Options::md5) { MD5Info &md5i = MD5Info::getInstance(); string collectedHash = md5i.contentHash(filename()); vector srcList; dependencies(srcList); __foreach(src, srcList) collectedHash += md5i.contentHash((*src)->filename()); md5i.save(filename(), collectedHash); } } ccbuild-2.0.9/src/source/outputFilename.cc000066400000000000000000000024401402074776400205410ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" std::string Source::outputFilename() const { if(isObjectTarget() || isBinTarget()) { //Output into a seperate directory with path in filename // OLD per directory output directory directory() + "/o/" + basename() + ".o"; String oname = FileSystem::absolutePath(directory()) +"/"+ FileSystem::baseName(d_filename) + ".o"; return Options::cacheRoot + "/" + oname.substr(1); } if(isHeader()) { return filename() + ".gch"; } throw Problem(Problem::Unable, "Output filename could not be determined. This is an internal error and should be reported as a bug."); return ""; } ccbuild-2.0.9/src/source/producesOutput.cc000066400000000000000000000017011402074776400206040ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" bool Source::producesOutput() const { if(isHeader() && Options::precompileAll) { return true; } if(isInternalHeader() && Options::precompile) { return true; } return hasSourceExtension(); } ccbuild-2.0.9/src/source/reload.cc000066400000000000000000000024371402074776400170140ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" bool Source::reload() { OpenMP::ScopedLock slock(d_apiLock); d_inoDev = make_pair(0,0); d_depsDone = false; d_hasMainFunction = false; /* Filename has not changed, so not d_srcType = Unknown; d_filename = FileSystem::cleanPath(d_filename); setType(); */ struct stat a; if(stat(d_filename.c_str(), &a) == 0) { d_inoDev.first = a.st_dev; d_inoDev.second = a.st_ino; d_modTime = a.st_mtime; } //Clear vectors d_deps.clear(); d_globalDeps.clear(); return d_inoDev != InodeDevPair(0,0); } ccbuild-2.0.9/src/source/scan.cc000066400000000000000000000045331402074776400164710ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" void Source::scan(vector < string > *local, vector < string > *global, vector < string > *ignore) { //Scan the file for all information if(FileSystem::isDirectory(d_filename)) { cerrLock.set(); cerr << "Warning: encountered a directory in the local includes,\n\tignoring: " << d_filename << endl; cerrLock.unset(); return; } //Scan sourcecode ifstream file(d_filename.c_str()); if(!file) { cerrLock.set(); cerr << "Could not open the source file for scanning: " << d_filename << endl; cerrLock.unset(); return; } OpenMP::ScopedLock fl(flexLock); SourceScanner *scanner = new SourceScanner(&file); try { scanner->yylex(); d_hasMainFunction = scanner->hasMainFunction(); //d_hasDefine = scanner->hasDefine(); if(ignore == 0) { ignore = &d_ignored; } scanner->includes(local, global, ignore); _debugLevel2("Scan resulted in " << local->size() << " local, " << global->size() << " global, and " << ignore->size() << " ignored includes\n\t for file " << d_filename); if(Options::verbose && ignore->size() > 0) { cerrLock.set(); __foreach(ig, *ignore) cerr << "ccbuild: warning: ignoring \"" << *ig << "\" in \"" << filename() << "\"\n"; cerrLock.unset(); } } catch(SourceScanner::Error err) { //Errors are seen just after they are encountered, thus decrement lineno. coutLock.set(); cout << "Include scanning error on line " << scanner->lineno() - 1 << " in file " << d_filename << "\n"; coutLock.unset(); } delete scanner; } ccbuild-2.0.9/src/source/setType.cc000066400000000000000000000017321402074776400172000ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" void Source::setType() { //Determine file type String fname(d_filename); //Return true if this source has an .ih extension if(fname.endsIn(".ih")) { d_srcType = InternalHeader; return; } if(hasSourceExtension()) { return; } d_srcType = LocalHeader; } ccbuild-2.0.9/src/source/source.cc000066400000000000000000000030301402074776400170340ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" Source::Source(string const &sourceFilename) : d_filename(sourceFilename), d_inoDev(make_pair(0,0)), d_modTime(0), d_deps(), d_globalDeps(), d_ignored(), d_depsDone(false), d_update(0), d_hasMainFunction(false), d_srcType(Unknown) { d_filename = FileSystem::cleanPath(d_filename); _debugLevel2("Loaded \"" << filename << "\" as \"" << d_filename << "\""); struct stat a; if(stat(d_filename.c_str(), &a) == 0) { d_inoDev.first = a.st_dev; d_inoDev.second = a.st_ino; d_modTime = a.st_mtime; } setType(); } //Empty source initializer Source::Source() : d_filename(""), d_inoDev(make_pair(0,0)), d_modTime(0), d_deps(), d_globalDeps(), d_ignored(), d_depsDone(false), d_update(0), d_hasMainFunction(false), d_srcType(Unknown) { setType(); } ccbuild-2.0.9/src/source/source.hh000066400000000000000000000235261402074776400170620ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ //Source is a wrapper class for sources //It should facilitate methods as: hasFunction() //and includes() //To investigate the source #ifndef _Source_H_INCLUDED_ #define _Source_H_INCLUDED_ #include #include #include #include #include #include "../compiler/compiler.hh" #include "../openmp/lock/lock.hh" namespace bneijt { ///\brief Sourcefile wrapper /// ///This class wraps a sourcefile. It holds all functionality needed to extract information /// from the source. Information like: is it a headerfile (isHeader) or a sourcefile? /// Wether it should be used to create a executable (isBinTarget), a /// library (isLibTarget) or just an object (isObjectTarget). ///The source wrapper should be able to tell us everything we want to know about a source. class Source { OpenMP::Lock d_apiLock;/// InodeDevPair; std::string d_filename; /// d_deps; /// d_globalDeps;/// d_ignored;/// &localDeps, std::vector &globalDeps) const; ///\brief Append this source's local dependency pointers to this list void dependencies(std::vector &localDeps) const; ///\brief Give a list of all the sources that this source depends on. void directDeps(std::vector &localDeps) const; ///\brief Give a list of all the sources that this source depends on. void directDeps(std::vector &localDeps, std::vector &globalDeps) const; ///\brief Give a list of all the sources that this source depends on. void directDeps(std::vector &localDeps, std::vector &globalDeps, std::vector &ignored) const; ///\brief Give a list of all ignored dependencies void ignoredDeps(std::vector &ignored) const { ignored = d_ignored; } ///\brief Create the list of all the sources that this source depends on directly. void genDeps(); ///\brief The directory the file is in std::string directory() const; ///\brief The actual given filename std::string const &filename() const { return d_filename; } ///\brief The filename it will create std::string outputFilename() const; /**\brief Reload this source Should only be used for reloading of source, as the pointers in other sources will still point to this source. */ bool reload(); /**\brief Compile this source using the compiler cc (Currently NOT USED) If we are a header, search for a local child and build that first This is done by seaking a local include that shares our path This source is loaded en build Now all local children are build, so now we can build our own functions Find all .cc files and build them We are a header, so we quit (no compilation). If we are a source, search for a local child and build that first check for update or not This is done by seaking a local include that shares our path This source is loaded en build (this handy for when a local child in the .ih but not in the .h) Now all local children are build, so now we can build our own functions. compile me Add my object to the list of objects in the compiler. \param cc Use this Compiler to compile this source */ void build(Compiler &cc); ///\brief Build this source using the given compiler void buildObjectTarget(Compiler &cc /// const &sources) const; /** \brief Return true if the source file is newer then the loaded class. This function checks to see if the on disk file is the same as the in memory file. If this is not the case, the dependency information might be old. */ bool stale(); ///\brief Compares two sources based on inode and device numbers. bool operator==(Source const &rvalue) const { //Two sources are equal when they have the same ino-dev pair return d_inoDev == rvalue.d_inoDev; } private: ///\brief Fills the two vectors up with the local and global includes and fills d_hasMainFunction void scan(std::vector< std::string > *local, std::vector< std::string > *global, std::vector< std::string > *ignore = 0); ///\brief Determine source type based on he filename void setType(); }; }//namespace #endif ccbuild-2.0.9/src/source/source.ih000066400000000000000000000030541402074776400170550ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ #include "source.hh" #include "../resolver/resolver.hh" #include "../sources/sources.hh" #include "../sourceScanner/sourceScanner.hh" #include "../fileSystem/fileSystem.hh" #include "../options/options.hh" #include "../globals/globals.hh" #include "../MD5Info/MD5Info.hh" #include "../string/string.hh" #include "../problem/problem.hh" #include "../globallocks/globallocks.hh" #include "../openmp/scopedLock/scopedLock.hh" #include #include #include #include #include #include #include #include #include #include // (2) stat includes #include #include #include //#define DEBUGLEVEL 3 #include "../misc/debug.hh" #include "../misc/foreach.hh" using namespace std; using namespace bneijt; ccbuild-2.0.9/src/source/stale.cc000066400000000000000000000017041402074776400166520ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" bool Source::stale() { if(!FileSystem::fileExists(filename())) { return true; } if(Options::md5) { return changed(); } return d_modTime == 0 || d_modTime != FileSystem::modTime(filename()); } ccbuild-2.0.9/src/source/upToDate.cc000066400000000000000000000047211402074776400172710ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "source.ih" //Non const helper brother bool Source::upToDate() const { vector srcList; dependencies(srcList); _debugLevel2("Running update check on " << filename() << " with " << srcList.size() << " hashes."); return upToDate(srcList); } bool Source::upToDate(vector const &srcList) const { bool needUpdate = Options::defaultUpdate; if(!producesOutput()) { return true; } if(needUpdate) { return false; } //This file changed (Only based on timestamp or content MD5) if(changed()) { _debugLevel2(filename() << " changed."); return false; } //Any of it's dependencies changed if(Options::md5) { //MD5 sum concatenated hash check //If the concatenated hash of this and it's deps changed // then we are not up to date //TODO Optimize with halfway unequal check? MD5Info &md5i = MD5Info::getInstance(); string collectedHash = md5i.contentHash(filename()); __foreach(src, srcList) collectedHash += md5i.contentHash((*src)->filename()); _debugLevel3("Current collected (" << srcList.size() << ") hash value: " << collectedHash << "\n\t old: " << md5i.old(filename()) << "\n\t file: " << filename()); needUpdate = (collectedHash != md5i.old(filename())); } else { //Normal timestamp check system __foreach(src, srcList) { //General update rule: any newer dependency / changed dependency if((*src)->changed(outputFilename())) { _debugLevel3(filename() << " deps on changed " << (*src)->filename()); needUpdate = true; } if(needUpdate) { break; } } } return !needUpdate; } ccbuild-2.0.9/src/sourceScanner/000077500000000000000000000000001402074776400165435ustar00rootroot00000000000000ccbuild-2.0.9/src/sourceScanner/hasDefine.cc000066400000000000000000000013661402074776400207460ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "sourceScanner.ih" bool const &SourceScanner::hasDefine() const { return d_hasDefine; } ccbuild-2.0.9/src/sourceScanner/hasMainFunction.cc000066400000000000000000000014021402074776400221350ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "sourceScanner.ih" bool const &SourceScanner::hasMainFunction() const { return d_hasMainFunction; } ccbuild-2.0.9/src/sourceScanner/includes.cc000066400000000000000000000023351402074776400206630ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "sourceScanner.ih" void SourceScanner::includes(std::vector < std::string > *local, std::vector < std::string > *global, std::vector < std::string > *ignore) { local->resize(d_locals.size()); copy(d_locals.begin(), d_locals.end(), local->begin()); global->resize(d_globals.size()); copy(d_globals.begin(), d_globals.end(), global->begin()); //If exists: Resize Write if(ignore) { ignore->resize(d_ignore.size()); copy(d_ignore.begin(), d_ignore.end(), ignore->begin()); } } ccbuild-2.0.9/src/sourceScanner/lexer000066400000000000000000000055131402074776400176110ustar00rootroot00000000000000/* This is scheme is based on an example shown in "C++ Annotations" Version 6.1.0b by Frank B. Brokken Copyright (C) 2005 A. Bram Neijt */ %{ #define _SKIP_YYFLEXLEXER_ #include "sourceScanner.ih" ///\cond %} %option yyclass="SourceScanner" c++ 8bit warn noyywrap yylineno /* Debug is now off... the sourcescanner seems to work ok. %option debug */ %x comment %x ginclude %x linclude %x iinclude %x quoted eolnComment "//".* anyChar .|\n /* -------------------------------------------------------------------------- Flex rules area: ~~~~~~~~~~~~~~~~ Regular expressions below here define what the lexer will recognize. ----------------------------------------------------------------------- */ %% /* The comment-rules: comment lines are ignored. */ {eolnComment} "/*" BEGIN comment; {anyChar} "*/" BEGIN INITIAL; "\"" BEGIN quoted; [^\"]* "\"" BEGIN INITIAL; /* Main function detection */ int[ \t\n]+main[ \t\n]*\( d_hasMainFunction = true; /* Define directive detection (disabled) ^[ \t]*#define[ \t]+ d_hasDefine = true; */ /* Ignore includes: "# include" */ ^[ \t]*#" "include[ \t]+[<\"] BEGIN iinclude; [^>\"]* d_iinclude = yytext; [>\"][^\n]*\n { BEGIN INITIAL; storeIgnore(); } {anyChar} throw invalidInclude; /* Global includes: #include (All not signle space variants) */ ^[ \t]*#include[ \t]+"<" BEGIN ginclude; ^[ \t]*#\tinclude[ \t]+"<" BEGIN ginclude; ^[ \t]*#[ \t][ \t]+include[ \t]+"<" BEGIN ginclude; [^>\n]+ d_ginclude = yytext; ">"[^\n]*\n { BEGIN INITIAL; storeGlobal(); } {anyChar} throw invalidInclude; /* Local includes: #include "file" (All not signle space variants) */ ^[ \t]*#include[ \t]+"\"" BEGIN linclude; ^[ \t]*#\tinclude[ \t]+"\"" BEGIN linclude; ^[ \t]*#[ \t][ \t]+include[ \t]+"\"" BEGIN linclude; [^\"\n]+ d_linclude = yytext; "\""[^\n]*\n { BEGIN INITIAL; storeLocal(); } {anyChar} throw invalidInclude; /* The default rules: eating all the rest */ {anyChar} /* The <> rule: terminate the lexer */ <> yyterminate(); %% ///\endcond ccbuild-2.0.9/src/sourceScanner/lexer.h000066400000000000000000000000601402074776400200270ustar00rootroot00000000000000#include "sourceScanner.hh" #include ccbuild-2.0.9/src/sourceScanner/sourceScanner.cc000066400000000000000000000014511402074776400216650ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "sourceScanner.ih" SourceScanner::SourceScanner(istream *newYyin) : d_hasMainFunction(false) { switch_streams(*newYyin, yyout); } ccbuild-2.0.9/src/sourceScanner/sourceScanner.hh000066400000000000000000000064401402074776400217020ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ #ifndef _SourceScanner_H_ #define _SourceScanner_H_ #include #include #include #include #ifndef _SKIP_YYFLEXLEXER_ #include #endif namespace bneijt { ///\brief Parse the given source /// ///The SourceScanner parses the source and stores a few features of it in memory: /// - The local includes it uses /// - The global includes it uses /// - Wether it contains a "int main" function class SourceScanner: public yyFlexLexer { std::vector < std::string > d_globals; ///< Global dependencies std::vector < std::string > d_locals; ///< Local dependencies std::vector < std::string > d_ignore; ///< Ignored dependencies std::string d_ginclude; ///< global include collecting string std::string d_linclude; ///< local include collecting string std::string d_iinclude; ///< local include collecting string bool d_hasMainFunction; ///< Has main function state bit bool d_hasDefine; ///< Has \#define state bit public: ///\brief An enumeration of possible error codes enum Error { invalidInclude }; ///\brief Initialize the SourceScanner on the given stream SourceScanner(std::istream * yyin ///< Stream to scan ); /**\brief Put the known local and global includes into these vectors \param local Vector for local includes \param global Vector for global includes \param ignore Vector for ignored includes */ void includes(std::vector *local, std::vector *global, std::vector *ignore = 0 ); ///\brief Returns true when the scanned source contained a main function bool const &hasMainFunction() const; ///\brief Returns true when the scanned source contained a \#define directive bool const &hasDefine() const; ///\brief The yylex function, to run the parser virtual int yylex(); private: ///\brief Not implemented SourceScanner(SourceScanner const &other); // NI ///\brief Not implemented SourceScanner &operator=(SourceScanner const &other); // NI ///\brief Push d_ginclude to the d_gobals vector void storeGlobal(); ///\brief Push d_ginclude to the d_gobals vector void storeIgnore(); ///\brief Push d_linclude to the d_locals vector void storeLocal(); }; }//Namespace #endif ccbuild-2.0.9/src/sourceScanner/sourceScanner.ih000066400000000000000000000020371402074776400217010ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ #include #include "sourceScanner.hh" #include "lexer.h" #include #include #include #include #include #include #ifndef _SKIP_YYFLEXLEXER_ #include #endif using namespace std; using namespace bneijt; ccbuild-2.0.9/src/sourceScanner/storeGlobal.cc000066400000000000000000000013701402074776400213300ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "sourceScanner.ih" void SourceScanner::storeGlobal() { d_globals.push_back(d_ginclude); } ccbuild-2.0.9/src/sourceScanner/storeIgnore.cc000066400000000000000000000013671402074776400213610ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "sourceScanner.ih" void SourceScanner::storeIgnore() { d_ignore.push_back(d_iinclude); } ccbuild-2.0.9/src/sourceScanner/storeLocal.cc000066400000000000000000000013661402074776400211670ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "sourceScanner.ih" void SourceScanner::storeLocal() { d_locals.push_back(d_linclude); } ccbuild-2.0.9/src/sources/000077500000000000000000000000001402074776400154145ustar00rootroot00000000000000ccbuild-2.0.9/src/sources/destroy.cc000066400000000000000000000016001402074776400174110ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "sources.ih" void Sources::destroy() { OpenMP::ScopedLock instantiateLock(s_instanceLock); if(s_instance) { delete s_instance; } else { _debugLevel1("Already destoryed!!"); } s_instance = 0; } ccbuild-2.0.9/src/sources/erase.cc000066400000000000000000000015211402074776400170210ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "sources.ih" void Sources::erase(Source *src) { OpenMP::ScopedLock slock(d_sourcesLock); if(d_sources.count(src)) { d_sources.erase(src); delete src; } } ccbuild-2.0.9/src/sources/getInstance.cc000066400000000000000000000015401402074776400201670ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "sources.ih" Sources &Sources::getInstance() { OpenMP::ScopedLock instantiateLock(s_instanceLock); if(s_instance == 0) { s_instance = new Sources(); } return *s_instance; } ccbuild-2.0.9/src/sources/indexoperator.cc000066400000000000000000000034111402074776400206050ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "sources.ih" namespace { class DerivedEqual { Source const * a; public: DerivedEqual(Source const *target) : a(target) {} bool operator()(Source * const &b) const { return *a == *b; } }; } //Anon namespace Source *Sources::operator[](std::string const &filename) { _debugLevel2("Request for " << filename); Source *s = new Source(filename); if(!s) { throw Problem(Problem::Unable, "Unable allocate a Source class. Out of memory?"); } if(!FileSystem::isReadable(s->filename())) { _debugLevel2("Requested file '" << s->filename() << "' not readable."); delete s; return 0; } OpenMP::ScopedLock sourceLock(d_sourcesLock); std::set::iterator pos = find_if(d_sources.begin(), d_sources.end(), DerivedEqual(s)); if(pos == d_sources.end()) { //Not found _debugLevel4("Not found: " << filename << " so inserting it"); d_sources.insert(s); return s; } //Found _debugLevel4("Found: " << filename); delete s; return *pos; } ccbuild-2.0.9/src/sources/reloadStaleSources.cc000066400000000000000000000032541402074776400215320ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "sources.ih" void Sources::reloadStaleSources() { OpenMP::ScopedLock dslock(d_sourcesLock); __foreach(src, d_sources) { if((*src)->stale()) { if((*src)->reload()) { continue; } //Reloading failed! _debugLevel1("Reload failed on " << (*src)->filename() << ". Cleaning up all sources."); cerr << "ccbuild: Source tree change. Forcing refresh.\n"; //Forget all memory resident hashes MD5Info::destroy(); MD5Info::getInstance(); //Remove the object of any binary target to ensure relinking __foreach(i, d_sources) { if((*i)->isBinTarget()) { FileSystem::rmIfExists((*i)->outputFilename()); } } //Cleanup //Remove all dependency knowledge because of stale pointers... __foreach(i, d_sources) delete *i; d_sources.clear(); break; } } } ccbuild-2.0.9/src/sources/sources.cc000066400000000000000000000015251402074776400174110ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "sources.ih" Sources::Sources() : d_sources() {} Sources::~Sources() { OpenMP::ScopedLock slock(d_sourcesLock); __foreach(src, d_sources) { delete *src; } } ccbuild-2.0.9/src/sources/sources.hh000066400000000000000000000051441402074776400174240ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ //Sources list singleton. There to make sure we only load sources once #ifndef _Sources_H_INCLUDED_ #define _Sources_H_INCLUDED_ #include #include #include #include #include "../openmp/lock/lock.hh" #include "../source/source.hh" namespace bneijt { ///\brief Sources singleton. List of all loaded sources /// class Sources { std::set d_sources; ///< A list of all loaded OpenMP::Lock d_sourcesLock; /// const &sources() const { return d_sources; } private: ///\brief Initializer Sources(); ///\brief Destructor ~Sources(); ///\brief Not implemented Sources(Sources const &other); //NI ///\brief Not implemented Sources &operator=(Sources const &other); //NI }; }//namespace #endif ccbuild-2.0.9/src/sources/sources.ih000066400000000000000000000020361402074776400174220ustar00rootroot00000000000000/* ccbuild - A strict developer's build utility Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ #include "sources.hh" #include "../fileSystem/fileSystem.hh" #include "../MD5Info/MD5Info.hh" #include "../openmp/scopedLock/scopedLock.hh" #include #include //#define DEBUGLEVEL 4 #include "../misc/debug.hh" #include "../misc/foreach.hh" using namespace bneijt; using namespace std; ccbuild-2.0.9/src/sources/statics.cc000066400000000000000000000015201402074776400173730ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "sources.ih" Sources *Sources::s_instance(0); /// ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ ccbuild-2.0.9/src/string/000077500000000000000000000000001402074776400152375ustar00rootroot00000000000000ccbuild-2.0.9/src/string/replace.cc000066400000000000000000000023721402074776400171650ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "string.ih" std::string String::replace(char from, char to) const { std::string contentCopy(*this); __foreach(c, contentCopy) if(*c == from) { *c = to; } return contentCopy; } std::string String::replace(std::string const &from, std::string const &to) const { std::string contentCopy(*this); while(true) { std::string::size_type pos = contentCopy.find(from); if(pos == std::string::npos) { break; } contentCopy.replace(pos, from.size(), to); } return contentCopy; } ccbuild-2.0.9/src/string/string.hh000066400000000000000000000053101402074776400170650ustar00rootroot00000000000000/* This file is part of the metalink program Copyright (C) 2008 A. Bram Neijt 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 3 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, see . */ #ifndef _String_HH_INCLUDED_ #define _String_HH_INCLUDED_ #include namespace bneijt { class String: public std::string { public: String() : std::string() {} String(std::string const & string) : std::string(string) {} String const &operator=(std::string const &s) { this->assign(s); return *this; } void strip() { char const * const trimstring("\x01\x02\x03\x04\x05\x06\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"); std::string::size_type pos = this->find_first_not_of(trimstring); this->erase(0, pos); pos = this->find_last_not_of(trimstring); this->erase(pos + 1); } ///\brief Return true if the string ends with the given character bool endsIn(char const endc) const { return this->size() > 1 && (*this)[this->size() -1] == endc; } ///\brief Return true if the string ends with the given string bool endsIn(std::string const &ending) const { return this->size() >= ending.size() && this->compare( this->size() - ending.size(), ending.size(), ending ) == 0; } ///\brief Return true if the string starts with the given string bool startsWith(std::string const &beginning) const { return this->size() >= beginning.size() && this->compare( 0, beginning.size(), beginning ) == 0; } ///\brief Transform this string to uppercase void toUpper(); std::string replace(char from, char to) const; std::string replace(std::string const &from, std::string const &to) const; }; } #endif ccbuild-2.0.9/src/string/string.ih000066400000000000000000000015621402074776400170730ustar00rootroot00000000000000/* This file is part of the metalink program Copyright (C) 2005 A. Bram Neijt 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, see . */ #include "string.hh" #include "../misc/foreach.hh" #include using namespace bneijt; using namespace std; ccbuild-2.0.9/src/string/test.cc000066400000000000000000000025371402074776400165340ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "string.hh" #include #include #include #include #include #include using namespace std; using namespace bneijt; int main(int argc, char **argv) try { String s("a hello b"); #define REP(a,b) std::cout << "Replace '" << a << "' with '" << b << "': " << s.replace(a,b) << "\n" REP("a","b"); REP("a", "hello"); REP("hello", "billy"); cout << "\n"; return 0; } catch(const std::exception &e) { //All is LOST... nothing to do here but die cerr << "Caught std::exception (" << typeid(e).name() << "): " << e.what(); cerr << "\nPlease report this as a bug.\n"; } ccbuild-2.0.9/src/string/toUpper.cc000066400000000000000000000015331402074776400172060ustar00rootroot00000000000000/* This file is part of ccbuild. Copyright (C) 2013 A. Bram Neijt ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "string.ih" void String::toUpper() { transform(this->begin(), this->end(), this->begin(), static_cast(std::toupper)); } ccbuild-2.0.9/src/system/000077500000000000000000000000001402074776400152555ustar00rootroot00000000000000ccbuild-2.0.9/src/system/aapFor.cc000066400000000000000000000177461402074776400170130ustar00rootroot00000000000000/* This file is part of ccbuild. ccbuild 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 3 of the License, or (at your option) any later version. ccbuild 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 ccbuild. If not, see . */ #include "system.ih" namespace { //Function object returning either "" or the \t