This repository has been archived by the owner on Sep 25, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
Automatically exported from code.google.com/p/preprocess
License
trentm/preprocess
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
preprocess.py -- a portable multi-language file preprocessor ============================================================ Download the latest preprocess.py packages from here: (archive) http://preprocess.googlecode.com/files/preprocess-1.1.0.zip Home : http://trentm.com/projects/preprocess/ License : MIT (see LICENSE.txt) Platforms : Windows, Linux, Mac OS X, Unix Current Version : 1.1 Dev Status : Fairly mature, has been used in the Komodo build system for over 7 years. Requirements : Python >= 2.3 (http://www.activestate.com/ActivePython/) What's new? ----------- Support has been added for preprocessing TeX, Fortran, C#, Java, Shell script and PHP files. See the [Change Log](#changelog) below for more. Why preprocess.py? ------------------ There are millions of templating systems out there (most of them developed for the web). This isn't one of those, though it does share some basics: a markup syntax for templates that are processed to give resultant text output. The main difference with `preprocess.py` is that its syntax is hidden in comments (whatever the syntax for comments maybe in the target filetype) so that the file can still have valid syntax. A comparison with the C preprocessor is more apt. `preprocess.py` is targetted at build systems that deal with many types of files. Languages for which it works include: C++, Python, Perl, Tcl, XML, JavaScript, CSS, IDL, TeX, Fortran, PHP, Java, Shell scripts (Bash, CSH, etc.) and C#. Preprocess is usable both as a command line app and as a Python module. Here is how is works: All preprocessor statements are on their own line. A preprocessor statement is a comment (as appropriate for the language of the file being preprocessed). This way the preprocessor statements do not make an unpreprocessed file syntactically incorrect. For example: preprocess -D FEATURES=macros,scc myapp.py will yield this transformation: ... ... # #if "macros" in FEATURES def do_work_with_macros(): def do_work_with_macros(): pass pass # #else def do_work_without_macros(): pass # #endif ... ... or, with a JavaScript file: ... ... // #if "macros" in FEATURES function do_work_with_macros() { function do_work_with_macros() { } } // #else function do_work_without_macros() { } // #endif ... ... Despite these contrived examples preprocess has proved useful for build-time code differentiation in the [Komodo](http://www.activestate.com/Komodo) build system -- which includes source code in Python, JavaScript, XML, CSS, Perl, and C/C++. The #if expression (`"macros" in FEATURES` in the example) is Python code, so has Python's full comparison richness. A number of preprocessor statements are implemented: #define VAR [VALUE] #undef VAR #ifdef VAR #ifndef VAR #if EXPRESSION #elif EXPRESSION #else #endif #error ERROR_STRING #include "FILE" As well, preprocess will do in-line substitution of defined variables. Although this is currently off by default because substitution will occur in program strings, which is not ideal. When a future version of preprocess can lex languages being preprocessed it will NOT substitute into program strings and substitution will be turned ON by default. Please send any feedback to [Trent Mick](mailto:trentm@google's mail thing.com). Install Notes ------------- Download the latest `preprocess` source package, unzip it, and run `python setup.py install`: unzip preprocess-1.1.0.zip cd preprocess-1.1.0 python setup.py install If your install fails then please visit [the Troubleshooting FAQ](http://trentm.com/faq.html#troubleshooting-python-package-installation). This will install `preprocess.py` into your Python `site-packages` and also into your Python bin directory. If you can now run `preprocess` and get a response then you are good to go, otherwise read on. The *problem* is that the Python bin directory is not always on your PATH on some operating systems -- notably Mac OS X. To finish the install on OS X either manually move 'preprocess' to somewhere on your PATH: cp preprocess.py /usr/local/bin/preprocess or create a symlink to it (try one of these depending on your Python version): ln -s /System/Library/Frameworks/Python.framework/Versions/2.3/bin/preprocess /usr/local/bin/preprocess ln -s /Library/Frameworks/Python.framework/Versions/2.4/bin/preprocess /usr/local/bin/preprocess (Note: You'll probably need to prefix those commands with `sudo` and the exact paths may differ on your system.) Getting Started --------------- Once you have it install, run `preprocess --help` for full usage information: $ preprocess --help Preprocess a file. Command Line Usage: preprocess [<options>...] <infile> Options: -h, --help Print this help and exit. -V, --version Print the version info and exit. -v, --verbose Give verbose output for errors. -o <outfile> Write output to the given file instead of to stdout. -f, --force Overwrite given output file. (Otherwise an IOError will be raised if <outfile> already exists. -D <define> Define a variable for preprocessing. <define> can simply be a variable name (in which case it will be true) or it can be of the form <var>=<val>. An attempt will be made to convert <val> to an integer so "-D FOO=0" will create a false value. -I <dir> Add an directory to the include path for #include directives. -k, --keep-lines Emit empty lines for preprocessor statement lines and skipped output lines. This allows line numbers to stay constant. -s, --substitute Substitute defines into emitted lines. By default substitution is NOT done because it currently will substitute into program strings. Module Usage: from preprocess import preprocess preprocess(infile, outfile=sys.stdout, defines={}, force=0, keepLines=0, includePath=[], substitute=0) The <infile> can be marked up with special preprocessor statement lines of the form: <comment-prefix> <preprocessor-statement> <comment-suffix> where the <comment-prefix/suffix> are the native comment delimiters for that file type. Examples -------- HTML (*.htm, *.html) or XML (*.xml, *.kpf, *.xul) files: <!-- #if FOO --> ... <!-- #endif --> Python (*.py), Perl (*.pl), Tcl (*.tcl), Ruby (*.rb), Bash (*.sh), or make ([Mm]akefile*) files: # #if defined('FAV_COLOR') and FAV_COLOR == "blue" ... # #elif FAV_COLOR == "red" ... # #else ... # #endif C (*.c, *.h), C++ (*.cpp, *.cxx, *.cc, *.h, *.hpp, *.hxx, *.hh), Java (*.java), PHP (*.php) or C# (*.cs) files: // #define FAV_COLOR 'blue' ... /* #ifndef FAV_COLOR */ ... // #endif Fortran 77 (*.f) or 90/95 (*.f90) files: C #if COEFF == 'var' ... C #endif Preprocessor Syntax ------------------- - Valid statements: #define <var> [<value>] #undef <var> #ifdef <var> #ifndef <var> #if <expr> #elif <expr> #else #endif #error <error string> #include "<file>" where <expr> is any valid Python expression. - The expression after #if/elif may be a Python statement. It is an error to refer to a variable that has not been defined by a -D option or by an in-content #define. - Special built-in methods for expressions: defined(varName) Return true if given variable is defined. Tips ---- A suggested file naming convention is to let input files to preprocess be of the form <basename>.p.<ext> and direct the output of preprocess to <basename>.<ext>, e.g.: preprocess -o foo.py foo.p.py The advantage is that other tools (esp. editors) will still recognize the unpreprocessed file as the original language. And, for module usage, read the preprocess.preprocess() docstring: pydoc preprocess.preprocess Change Log ---------- ### v1.1.0 - Move to code.google.com/p/preprocess for code hosting. - Re-org directory structure to assist with deployment to pypi and better installation with setup.py. - Pulled the "content.types" file that assists with filetype determination into "preprocess.py". This makes "preprocess.py" fully independent and also makes the "setup.py" simpler. The "-c|--content-types-path" option can be used to specify addition content types information. ### v1.0.9 - Fix the 'contentType' optional arg for #include's. - Add cheap XML content sniffing. ### v1.0.8 - Allow for JS and CSS-style comment delims in XML/HTML. Ideally this would deal with full lexing but that isn't going to happen soon. ### v1.0.7 - Allow explicit specification of content type. ### v1.0.6 - Add ability to include a filename mentioned in a define: '#include VAR'. ### v1.0.5 - Make sure to use the *longest* define names first when doing substitutions. This ensure that substitution in this line: FOO and BAR are FOOBAR will do the right thing if there are "FOO" and "FOOBAR" defines. ### v1.0.4 - Add WiX XML file extensions. - Add XSLT file extensions. ### v1.0.3 - TeX support (from Hans Petter Langtangen) ### v1.0.2 - Fix a bug with -k|--keep-lines and preprocessor some directives in ignored if blocks (undef, define, error, include): those lines were not kept. (bug noted by Eric Promislow) ### v1.0.1 - Fix documentation error for '#define' statement. The correct syntax is '#define VAR [VALUE]' while the docs used to say '#define VAR[=VALUE]'. (from Hans Petter Langtangen) - Correct '! ...' comment-style for Fortran -- the '!' can be on any column in Fortran 90. (from Hans Petter Langtangen) - Return a non-zero exit code on error. ### v1.0.0 - Update the test suite (it had been broken for quite a while) and add a Fortran test case. - Improve Fortran support to support any char in the first column to indicate a comment. (Idea from Hans Petter Langtangen) - Recognize '.f90' files as Fortran. (from Hans Petter Langtangen) - Add Java, C#, Shell script and PHP support. (from Hans Petter Langtangen) ### v0.9.2 - Add Fortran support (from Hans Petter Langtangen) - Ensure content.types gets written to "bindir" next to preprocess.py there so it can be picked up (from Hans Petter Langtangen). ### v0.9.1 - Fully read in the input file before processing. This allows preprocessing of a file onto itself. ### v0.9.0 - Change version attributes and semantics. Before: had a _version_ tuple. After: __version__ is a string, __version_info__ is a tuple. ### v0.8.1 - Mentioned #ifdef and #ifndef in documentation (these have been there for a while). - Add preprocess.exe to source package (should fix installation on Windows). - Incorporate Komodo changes: - change 171050: add Ruby support - change 160914: Only attempt to convert define strings from the command-line to *int* instead of eval'ing as any Python expression: which could surprise with strings that work as floats. - change 67962: Fix '#include' directives in preprocessed files. ### v0.8.0 - Move hosting to trentm.com. Improve the starter docs a little bit. ### 0.7.0: - Fix bug 1: Nested #if-blocks will not be properly handled. - Add 'Text' type for .txt files and default (with a warn) unknown filetypes to 'Text'. Text files are defined to use to '#...'-style comments to allow if/else/.../endif directives as in Perl/Python/Tcl files. ### 0.6.1: - Fix a bug where preprocessor statements were not ignored when not emitting. For example the following should _not_ cause an error: # #if 0 # #error womba womba womba # #endif - Fix a bug where multiple uses of preprocess.preprocess() in the same interpreter would erroneously re-use the same list of __preprocessedFiles. This could cause false detection of recursive #include's. - Fix #include, broken in 0.6.0. ### 0.6.0: - substitution: Variables can now replaced with their defined value in preprocessed file content. This is turned OFF by default because, IMO, substitution should not be done in program strings. I need to add lexing for all supported languages before I can do *that* properly. Substitution can be turned on with the --substitute command-line option or the subst=1 module interface option. - Add support for preprocessing HTML files. ### 0.5.0: - Add #error, #define, #undef, #ifdef and #ifndef statements. - #include statement, -I command line option and 'includePath' module interface option to specify an include path - Add __FILE__ and __LINE__ default defines. - More strict and more helpful error messages: - Lines of the form "#else <expr>" and "#endif <expr>" no longer match. - error messages for illegal #if-block constructs - error messages for use of defined(BAR) instead of defined('BAR') in expressions - New "keep lines" option to output blank lines for skipped content lines and preprocessor statement lines (to preserve line numbers in the processed file). ### 0.4.0: - Add #elif preprocessor statement. - Add defined() built-in, e.g. #if defined('FOO') ### 0.3.2: - Make #if expressions Python code. - Change "defines" attribute of preprocess.preprocess(). - Add -f|--force option to overwrite given output file. ### 0.2.0: - Add content types for C/C++. - Better module documentation. - You can define *false* vars on the command line now. - 'python setup.py install' works. ### 0.1.0: - First release.
About
Automatically exported from code.google.com/p/preprocess
Resources
License
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published