summaryrefslogtreecommitdiff
path: root/support/highlight/src/cli
diff options
context:
space:
mode:
Diffstat (limited to 'support/highlight/src/cli')
-rw-r--r--support/highlight/src/cli/arg_parser.cc193
-rw-r--r--support/highlight/src/cli/arg_parser.h95
-rw-r--r--support/highlight/src/cli/cmdlineoptions.cpp1031
-rw-r--r--support/highlight/src/cli/cmdlineoptions.h471
-rw-r--r--support/highlight/src/cli/help.cpp185
-rw-r--r--support/highlight/src/cli/help.h42
-rw-r--r--support/highlight/src/cli/main.cpp709
-rw-r--r--support/highlight/src/cli/main.h117
8 files changed, 2843 insertions, 0 deletions
diff --git a/support/highlight/src/cli/arg_parser.cc b/support/highlight/src/cli/arg_parser.cc
new file mode 100644
index 0000000000..55e440d94f
--- /dev/null
+++ b/support/highlight/src/cli/arg_parser.cc
@@ -0,0 +1,193 @@
+/* Arg_parser - A POSIX/GNU command line argument parser.
+ Copyright (C) 2006, 2007, 2008 Antonio Diaz Diaz.
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <cstring>
+#include <string>
+#include <vector>
+
+#include "arg_parser.h"
+
+
+bool Arg_parser::parse_long_option( const char * const opt, const char * const arg,
+ const Option options[], int & argind ) throw()
+ {
+ unsigned int len;
+ int index = -1;
+ bool exact = false, ambig = false;
+
+ for( len = 0; opt[len+2] && opt[len+2] != '='; ++len ) ;
+
+ // Test all long options for either exact match or abbreviated matches.
+ for( int i = 0; options[i].code != 0; ++i )
+ if( options[i].name && !std::strncmp( options[i].name, &opt[2], len ) )
+ {
+ if( std::strlen( options[i].name ) == len ) // Exact match found
+ { index = i; exact = true; break; }
+ else if( index < 0 ) index = i; // First nonexact match found
+ else if( options[index].code != options[i].code ||
+ options[index].has_arg != options[i].has_arg )
+ ambig = true; // Second or later nonexact match found
+ }
+
+ if( ambig && !exact )
+ {
+ _error = "option `"; _error += opt; _error += "' is ambiguous";
+ return false;
+ }
+
+ if( index < 0 ) // nothing found
+ {
+ _error = "unrecognized option `"; _error += opt; _error += '\'';
+ return false;
+ }
+
+ ++argind;
+ data.push_back( Record( options[index].code ) );
+
+ if( opt[len+2] ) // `--<long_option>=<argument>' syntax
+ {
+ if( options[index].has_arg == no )
+ {
+ _error = "option `--"; _error += options[index].name;
+ _error += "' doesn't allow an argument";
+ return false;
+ }
+ if( options[index].has_arg == yes && !opt[len+3] )
+ {
+ _error = "option `--"; _error += options[index].name;
+ _error += "' requires an argument";
+ return false;
+ }
+ data.back().argument = &opt[len+3];
+ return true;
+ }
+
+ if( options[index].has_arg == yes )
+ {
+ if( !arg )
+ {
+ _error = "option `--"; _error += options[index].name;
+ _error += "' requires an argument";
+ return false;
+ }
+ ++argind; data.back().argument = arg;
+ return true;
+ }
+
+ return true;
+ }
+
+
+bool Arg_parser::parse_short_option( const char * const opt, const char * const arg,
+ const Option options[], int & argind ) throw()
+ {
+ int cind = 1; // character index in opt
+
+ while( cind > 0 )
+ {
+ int index = -1;
+ const unsigned char code = opt[cind];
+
+ if( code != 0 )
+ for( int i = 0; options[i].code; ++i )
+ if( code == options[i].code )
+ { index = i; break; }
+
+ if( index < 0 )
+ {
+ _error = "invalid option -- "; _error += code;
+ return false;
+ }
+
+ data.push_back( Record( code ) );
+ if( opt[++cind] == 0 ) { ++argind; cind = 0; } // opt finished
+
+ if( options[index].has_arg != no && cind > 0 && opt[cind] )
+ {
+ data.back().argument = &opt[cind]; ++argind; cind = 0;
+ }
+ else if( options[index].has_arg == yes )
+ {
+ if( !arg || !arg[0] )
+ {
+ _error = "option requires an argument -- "; _error += code;
+ return false;
+ }
+ data.back().argument = arg; ++argind; cind = 0;
+ }
+ }
+ return true;
+ }
+
+
+Arg_parser::Arg_parser( const int argc, const char * const argv[],
+ const Option options[], const bool in_order ) throw()
+ {
+ if( argc < 2 || !argv || !options ) return;
+
+ std::vector< std::string > non_options; // skipped non-options
+ int argind = 1; // index in argv
+
+ while( argind < argc )
+ {
+ const unsigned char ch1 = argv[argind][0];
+ const unsigned char ch2 = ( ch1 ? argv[argind][1] : 0 );
+
+ if( ch1 == '-' && ch2 ) // we found an option
+ {
+ const char * const opt = argv[argind];
+ const char * const arg = (argind + 1 < argc) ? argv[argind+1] : 0;
+ if( ch2 == '-' )
+ {
+ if( !argv[argind][2] ) { ++argind; break; } // we found "--"
+ else if( !parse_long_option( opt, arg, options, argind ) ) break;
+ }
+ else if( !parse_short_option( opt, arg, options, argind ) ) break;
+ }
+ else
+ {
+ if( !in_order ) non_options.push_back( argv[argind++] );
+ else { data.push_back( Record() ); data.back().argument = argv[argind++]; }
+ }
+ }
+ if( _error.size() ) data.clear();
+ else
+ {
+ for( unsigned int i = 0; i < non_options.size(); ++i )
+ { data.push_back( Record() ); data.back().argument.swap( non_options[i] ); }
+ while( argind < argc )
+ { data.push_back( Record() ); data.back().argument = argv[argind++]; }
+ }
+ }
+
+
+Arg_parser::Arg_parser( const char * const opt, const char * const arg,
+ const Option options[] ) throw()
+ {
+ if( !opt || !opt[0] || !options ) return;
+
+ if( opt[0] == '-' && opt[1] ) // we found an option
+ {
+ int argind = 1; // dummy
+ if( opt[1] == '-' )
+ { if( opt[2] ) parse_long_option( opt, arg, options, argind ); }
+ else
+ parse_short_option( opt, arg, options, argind );
+ if( _error.size() ) data.clear();
+ }
+ else { data.push_back( Record() ); data.back().argument = opt; }
+ }
diff --git a/support/highlight/src/cli/arg_parser.h b/support/highlight/src/cli/arg_parser.h
new file mode 100644
index 0000000000..b0e44a8770
--- /dev/null
+++ b/support/highlight/src/cli/arg_parser.h
@@ -0,0 +1,95 @@
+/* Arg_parser - A POSIX/GNU command line argument parser.
+ Copyright (C) 2006, 2007, 2008 Antonio Diaz Diaz.
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+/* Arg_parser reads the arguments in `argv' and creates a number of
+ option codes, option arguments and non-option arguments.
+
+ In case of error, `error' returns a non-empty error message.
+
+ `options' is an array of `struct Option' terminated by an element
+ containing a code which is zero. A null name means a short-only
+ option. A code value outside the unsigned char range means a
+ long-only option.
+
+ Arg_parser normally makes it appear as if all the option arguments
+ were specified before all the non-option arguments for the purposes
+ of parsing, even if the user of your program intermixed option and
+ non-option arguments. If you want the arguments in the exact order
+ the user typed them, call `Arg_parser' with `in_order' = true.
+
+ The argument `--' terminates all options; any following arguments are
+ treated as non-option arguments, even if they begin with a hyphen.
+
+ The syntax for optional option arguments is `-<short_option><argument>'
+ (without whitespace), or `--<long_option>=<argument>'.
+*/
+
+class Arg_parser
+{
+ public:
+ enum Has_arg { no, yes, maybe };
+
+ struct Option
+ {
+ int code; // Short option letter or code ( code != 0 )
+ const char * name; // Long option name (maybe null)
+ Has_arg has_arg;
+ };
+
+ private:
+ struct Record
+ {
+ int code;
+ std::string argument;
+ Record ( const int c = 0 ) : code ( c ) {}
+ };
+
+ std::string _error;
+ std::vector< Record > data;
+
+ bool parse_long_option ( const char * const opt, const char * const arg,
+ const Option options[], int & argind ) throw();
+ bool parse_short_option ( const char * const opt, const char * const arg,
+ const Option options[], int & argind ) throw();
+
+ public:
+ Arg_parser ( const int argc, const char * const argv[],
+ const Option options[], const bool in_order = false ) throw();
+
+ // Restricted constructor. Parses a single token and argument (if any)
+ Arg_parser ( const char * const opt, const char * const arg,
+ const Option options[] ) throw();
+
+ const std::string & error() const throw() { return _error; }
+
+ // The number of arguments parsed (may be different from argc)
+ int arguments() const throw() { return data.size(); }
+
+ // If code( i ) is 0, argument( i ) is a non-option.
+ // Else argument( i ) is the option's argument (or empty).
+ int code ( const int i ) const throw()
+ {
+ if ( i >= 0 && i < arguments() ) return data[i].code;
+ else return 0;
+ }
+
+ const std::string & argument ( const int i ) const throw()
+ {
+ if ( i >= 0 && i < arguments() ) return data[i].argument;
+ else return _error;
+ }
+};
diff --git a/support/highlight/src/cli/cmdlineoptions.cpp b/support/highlight/src/cli/cmdlineoptions.cpp
new file mode 100644
index 0000000000..21c7646bda
--- /dev/null
+++ b/support/highlight/src/cli/cmdlineoptions.cpp
@@ -0,0 +1,1031 @@
+/***************************************************************************
+ cmdlineoptions.cpp - description
+ -------------------
+ begin : Sun Nov 25 2001
+ copyright : (C) 2001-2008 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight 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.
+
+Highlight 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 Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "cmdlineoptions.h"
+#include "platform_fs.h"
+#include "configurationreader.h"
+#include "datadir.h"
+#include <sstream>
+#include <cstdio>
+
+#include "arg_parser.h"
+
+using namespace std;
+
+
+CmdLineOptions::CmdLineOptions ( const int argc, const char *argv[] ) :
+ numberSpaces ( 0 ),
+ lineNrWidth ( 5 ),
+ lineLength ( 80 ),
+ lineNrStart ( 1 ),
+ wrappingStyle ( highlight::WRAP_DISABLED ),
+ outputType ( highlight::HTML ),
+ keywordCase ( StringTools::CASE_UNCHANGED ),
+ className ( "hl" ),
+ opt_syntax ( false ),
+ opt_include_style ( false ),
+ opt_help ( false ),
+ opt_version ( false ),
+ opt_verbose ( false ),
+ opt_print_config ( false ),
+ opt_linenumbers ( false ),
+ opt_style ( false ),
+ opt_batch_mode ( false ),
+ opt_fragment ( false ) ,
+ opt_attach_line_anchors ( false ),
+ opt_show_themes ( false ),
+ opt_show_langdefs ( false ),
+ opt_printindex ( false ),
+ opt_quiet ( false ),
+ opt_replacequotes ( false ),
+ opt_babel ( false ),
+ opt_print_progress ( false ),
+ opt_fill_zeroes ( false ),
+ opt_stylepath_explicit ( false ),
+ opt_force_output ( false ),
+ opt_ordered_list ( false ),
+ opt_fnames_as_anchors ( false ),
+ opt_validate ( false ),
+ opt_inline_css ( false ),
+ opt_enclose_pre ( false ),
+ opt_char_styles ( false ),
+ opt_pretty_symbols ( false ),
+ opt_delim_CR (false),
+ opt_print_style(false),
+ opt_no_trailing_nl(false),
+ configFileRead ( false ),
+ anchorPrefix ( "l" ),
+ helpLang ( "en" ),
+ encodingName ( "ISO-8859-1" )
+{
+
+ loadConfigurationFile();
+
+ enum Optcode
+ {
+ S_OPT_ADDCONFDIR = 256, S_OPT_ENCLOSE_PRE, S_OPT_FORCE_OUTPUT,
+ S_OPT_INLINE_CSS, S_OPT_KW_CASE,
+ S_OPT_MARK_LINES, S_OPT_PRINT_CONFIG, S_OPT_TEST_INPUT,
+ S_OPT_SVG_WIDTH, S_OPT_SVG_HEIGHT, S_OPT_CLASSNAME, S_OPT_RTF_CHAR_STYLES,
+ S_OPT_SKIP_UNKNOWN,
+ S_OPT_COMPAT_DOC, S_OPT_COMPAT_NODOC, S_OPT_COMPAT_TAB, S_OPT_COMPAT_CSS,
+ S_OPT_COMPAT_OUTDIR, S_OPT_COMPAT_FAILSAFE, S_OPT_COMPAT_OUTFORMAT,
+ S_OPT_COMPAT_SRCLANG, S_OPT_COMPAT_LINENUM, S_OPT_COMPAT_LINEREF,
+ S_OPT_CTAGS_FILE, S_OPT_PRETTY_SYMBOLS, S_OPT_EOL_DELIM_CR, S_OPT_START_NESTED,
+ S_OPT_PRINT_STYLE, S_OPT_NO_TRAILING_NL
+ };
+
+ const Arg_parser::Option options[] =
+ {
+ { 'a', OPT_ANCHORS, Arg_parser::no },
+ { 'A', OPT_ANSI, Arg_parser::no },
+ { 'b', OPT_BABEL, Arg_parser::no },
+ { 'B', OPT_BATCHREC, Arg_parser::yes },
+ { 'c', OPT_STYLE_OUT, Arg_parser::yes },
+ { 'C', OPT_INDEXFILE, Arg_parser::no },
+ { 'd', OPT_DOC_TITLE, Arg_parser::yes },
+ { 'D', OPT_DATADIR, Arg_parser::yes },
+ { 'e', OPT_STYLE_IN, Arg_parser::yes },
+ { 'E', OPT_ADDDATADIR, Arg_parser::yes },
+ { 'f', OPT_FRAGMENT, Arg_parser::no },
+ { 'F', OPT_FORMAT, Arg_parser::yes },
+ { S_OPT_CLASSNAME, OPT_CLASSNAME, Arg_parser::yes },
+ { 'h', OPT_HELP, Arg_parser::no },
+ { 'H', OPT_HTML, Arg_parser::no },
+ { 'i', OPT_IN, Arg_parser::yes },
+ { 'I', OPT_INC_STYLE, Arg_parser::no },
+ { 'j', OPT_LNR_LEN, Arg_parser::yes },
+ { 'J', OPT_LINE_LEN, Arg_parser::yes },
+ { 'k', OPT_BASE_FONT, Arg_parser::yes },
+ { 'K', OPT_BASE_FONT_SIZE, Arg_parser::yes },
+ { 'l', OPT_LINENO, Arg_parser::no },
+ { 'L', OPT_LATEX, Arg_parser::no },
+ { 'm', OPT_LNR_START, Arg_parser::yes },
+ { 'M', OPT_XTERM256, Arg_parser::no },
+ { 'n', OPT_ORDERED_LIST, Arg_parser::no },
+ { 'N', OPT_ANCHOR_FN, Arg_parser::no },
+ { 'o', OPT_OUT, Arg_parser::yes },
+ { 'O', OPT_OUTDIR, Arg_parser::yes },
+ { 'p', OPT_LISTLANGS, Arg_parser::no },
+ { 'P', OPT_PROGRESSBAR, Arg_parser::no },
+ { 'q', OPT_QUIET, Arg_parser::no },
+ { 'Q', OPT_VERSION, Arg_parser::no },
+ { 'r', OPT_REPLACE_QUOTES, Arg_parser::no },
+ { 'R', OPT_RTF, Arg_parser::no },
+ { 's', OPT_STYLE, Arg_parser::yes },
+ { 'S', OPT_SYNTAX, Arg_parser::yes },
+ { 't', OPT_DELTABS, Arg_parser::yes },
+ { 'T', OPT_TEX, Arg_parser::no },
+ { 'u', OPT_ENCODING, Arg_parser::yes },
+ { 'v', OPT_VERBOSE, Arg_parser::no },
+ { 'V', OPT_WRAPSIMPLE, Arg_parser::no },
+ { 'w', OPT_LISTTHEMES, Arg_parser::no },
+ { 'W', OPT_WRAP, Arg_parser::no },
+ { 'x', OPT_RTF_PAGE_SIZE, Arg_parser::yes },
+ { 'X', OPT_XHTML, Arg_parser::no },
+ { 'y', OPT_ANCHOR_PFX, Arg_parser::yes },
+ { 'z', OPT_FILLZEROES, Arg_parser::no },
+ { 'Z', OPT_XML, Arg_parser::no },
+ { 'G', OPT_SVG, Arg_parser::no },
+ { 'Y', OPT_BBCODE, Arg_parser::no },
+ { S_OPT_SVG_WIDTH, OPT_SVG_WIDTH, Arg_parser::yes },
+ { S_OPT_SVG_HEIGHT, OPT_SVG_HEIGHT, Arg_parser::yes },
+ { S_OPT_ADDCONFDIR, OPT_ADDCONFDIR, Arg_parser::yes },
+ { S_OPT_ENCLOSE_PRE, OPT_ENCLOSE_PRE, Arg_parser::no },
+ { S_OPT_FORCE_OUTPUT, OPT_FORCE_OUTPUT, Arg_parser::no },
+ { S_OPT_INLINE_CSS, OPT_INLINE_CSS, Arg_parser::no },
+ { S_OPT_KW_CASE, OPT_KW_CASE, Arg_parser::yes },
+ { S_OPT_MARK_LINES, OPT_MARK_LINES, Arg_parser::yes },
+ { S_OPT_PRINT_CONFIG, OPT_PRINT_CONFIG, Arg_parser::no },
+ { S_OPT_TEST_INPUT, OPT_TEST_INPUT, Arg_parser::no },
+ { S_OPT_RTF_CHAR_STYLES, OPT_RTF_CHAR_STYLES, Arg_parser::no },
+ { S_OPT_SKIP_UNKNOWN, OPT_SKIP_UNKNOWN, Arg_parser::yes },
+ { S_OPT_CTAGS_FILE, OPT_CTAGS_FILE, Arg_parser::maybe },
+ { S_OPT_START_NESTED, OPT_START_NESTED, Arg_parser::yes },
+ { S_OPT_COMPAT_DOC, OPT_COMPAT_DOC, Arg_parser::no },
+ { S_OPT_COMPAT_NODOC, OPT_COMPAT_NODOC, Arg_parser::no },
+ { S_OPT_COMPAT_TAB, OPT_COMPAT_TAB, Arg_parser::yes },
+ { S_OPT_COMPAT_CSS, OPT_COMPAT_CSS, Arg_parser::yes },
+ { S_OPT_COMPAT_OUTDIR, OPT_COMPAT_OUTDIR, Arg_parser::yes },
+ { S_OPT_COMPAT_FAILSAFE, OPT_COMPAT_FAILSAFE, Arg_parser::no },
+ { S_OPT_COMPAT_OUTFORMAT, OPT_COMPAT_OUTFORMAT, Arg_parser::yes },
+ { S_OPT_COMPAT_SRCLANG, OPT_COMPAT_SRCLANG, Arg_parser::yes },
+ { S_OPT_COMPAT_LINENUM, OPT_COMPAT_LINENUM, Arg_parser::maybe },
+ { S_OPT_COMPAT_LINEREF, OPT_COMPAT_LINEREF, Arg_parser::maybe },
+ { S_OPT_PRETTY_SYMBOLS, OPT_PRETTY_SYMBOLS, Arg_parser::no },
+ { S_OPT_EOL_DELIM_CR, OPT_EOL_DELIM_CR, Arg_parser::no },
+ { S_OPT_PRINT_STYLE, OPT_PRINT_STYLE, Arg_parser::no },
+ { S_OPT_NO_TRAILING_NL, OPT_NO_TRAILING_NL, Arg_parser::no },
+
+ { 0, 0, Arg_parser::no }
+ };
+
+
+ Arg_parser parser ( argc, argv, options );
+ if ( parser.error().size() ) // bad option
+ {
+ cerr << "highlight: "<< parser.error() <<"\n";
+ cerr << "Try `highlight --help' for more information.\n";
+ exit ( 1 );
+ }
+
+ int argind = 0;
+ for ( ; argind < parser.arguments(); ++argind )
+ {
+ const int code = parser.code ( argind );
+ const std::string & arg = parser.argument ( argind );
+ if ( !code ) break; // no more options
+ switch ( code )
+ {
+ case 'a':
+ opt_attach_line_anchors = true;
+ break;
+ case 'A':
+ outputType=highlight::ANSI;
+ break;
+ case 'b':
+ opt_babel=true;
+ break;
+ case 'B':
+ opt_batch_mode = true;
+ readDirectory ( arg );
+ break;
+ case 'c':
+ case S_OPT_COMPAT_CSS:
+ styleOutFilename = arg;
+ opt_stylepath_explicit=true;
+ break;
+ case 'C':
+ opt_printindex=true;
+ break;
+ case 'd':
+ docTitle = arg;
+ break;
+ case 'D':
+ dataDir=validateDirPath ( arg );
+ break;
+ case 'e':
+ styleInFilename = arg;
+ break;
+ case 'E':
+ additionalDataDir=validateDirPath ( arg );
+ break;
+ case 'f':
+ case S_OPT_COMPAT_NODOC:
+ opt_fragment = true;
+ break;
+ case 'F':
+ indentScheme = arg;
+ break;
+ case S_OPT_CLASSNAME:
+ className = arg;
+ break;
+ case 'h':
+ opt_help = true;
+ break;
+ case 'H':
+ outputType=highlight::HTML;
+ break;
+ case 'i':
+ inputFileNames.push_back ( arg );
+ break;
+ case 'I':
+ opt_include_style = true;
+ break;
+ case 'j':
+ StringTools::str2num<int> ( lineNrWidth, arg, std::dec );
+ break;
+ case 'J':
+ StringTools::str2num<int> ( lineLength, arg, std::dec );
+ break;
+ case 'k':
+ baseFont = arg;
+ break;
+ case 'K':
+ baseFontSize = arg;
+ break;
+ case S_OPT_COMPAT_LINENUM:
+ if ( arg=="0" ) opt_fill_zeroes=true;
+ case 'l':
+ opt_linenumbers = true;
+ break;
+ case 'L':
+ outputType=highlight::LATEX;
+ break;
+ case 'm':
+ StringTools::str2num<int> ( lineNrStart, arg, std::dec );
+ break;
+ case 'M':
+ outputType=highlight::XTERM256;
+ break;
+ case 'n':
+ opt_ordered_list = opt_linenumbers = true;
+ break;
+ case 'N':
+ opt_fnames_as_anchors=true;
+ break;
+ case 'o':
+ outFilename = arg;
+ break;
+ case 'O':
+ case S_OPT_COMPAT_OUTDIR:
+ outDirectory = validateDirPath ( arg );
+ break;
+ case 'p':
+ opt_show_langdefs = true;
+ break;
+ case 'P':
+ opt_print_progress=true;
+ break;
+ case 'q':
+ opt_quiet = true;
+ break;
+ case 'Q':
+ opt_version = true;
+ break;
+ case 'r':
+ opt_replacequotes=true;
+ break;
+ case 'R':
+ outputType=highlight::RTF;
+ break;
+ case 's':
+ styleName = arg;
+ opt_style = true;
+ break;
+ case 'S':
+ case S_OPT_COMPAT_SRCLANG:
+ syntax = arg;
+ opt_syntax = true;
+ break;
+ case 't':
+ case S_OPT_COMPAT_TAB:
+ StringTools::str2num<int> ( numberSpaces, arg, std::dec );
+ break;
+ case 'T':
+ outputType=highlight::TEX;
+ break;
+ case 'u':
+ encodingName = arg;
+ break;
+ case 'v':
+ opt_verbose = true;
+ break;
+ case 'V':
+ wrappingStyle = highlight::WRAP_SIMPLE;
+ break;
+ case 'w':
+ opt_show_themes = true;
+ break;
+ case 'W':
+ wrappingStyle = highlight::WRAP_DEFAULT;
+ break;
+ case 'x':
+ pageSize = arg;
+ break;
+ case 'X':
+ outputType=highlight::XHTML;
+ break;
+ case 'y':
+ anchorPrefix = arg;
+ break;
+ case 'z':
+ opt_fill_zeroes=true;
+ break;
+ case 'Z':
+ outputType=highlight::XML;
+ break;
+ case 'G':
+ outputType=highlight::SVG;
+ break;
+ case 'Y':
+ outputType=highlight::BBCODE;
+ break;
+ case S_OPT_SVG_WIDTH:
+ svg_width = arg;
+ break;
+ case S_OPT_SVG_HEIGHT:
+ svg_height = arg;
+ break;
+ case S_OPT_ADDCONFDIR:
+ additionalConfigDir = validateDirPath ( arg );
+ break;
+ case S_OPT_ENCLOSE_PRE:
+ opt_enclose_pre=true;
+ break;
+ case S_OPT_FORCE_OUTPUT:
+ case S_OPT_COMPAT_FAILSAFE:
+ opt_force_output = true;
+ break;
+ case S_OPT_INLINE_CSS:
+ opt_inline_css=true;
+ break;
+ case S_OPT_KW_CASE:
+ {
+ const string tmp = StringTools::change_case ( arg );
+ if ( tmp == "upper" )
+ keywordCase = StringTools::CASE_UPPER;
+ else if ( tmp == "lower" )
+ keywordCase = StringTools::CASE_LOWER;
+ else if ( tmp == "capitalize" )
+ keywordCase = StringTools::CASE_CAPITALIZE;
+ }
+ break;
+ case S_OPT_COMPAT_OUTFORMAT:
+ {
+ const string tmp = StringTools::change_case ( arg );
+ if ( tmp == "xhtml" )
+ outputType = highlight::XHTML;
+ else if ( tmp == "tex" )
+ outputType = highlight::TEX;
+ else if ( tmp == "latex" )
+ outputType = highlight::LATEX;
+ else if ( tmp == "rtf" )
+ outputType = highlight::RTF;
+ else if ( tmp == "xml" )
+ outputType = highlight::XML;
+ else if ( tmp == "ansi" || tmp == "esc" ) // gnu source-highlight esc parameter
+ outputType = highlight::ANSI;
+ else if ( tmp == "xterm256" )
+ outputType = highlight::XTERM256;
+ else if ( tmp == "svg" )
+ outputType = highlight::SVG;
+ else if ( tmp == "bbcode" )
+ outputType = highlight::BBCODE;
+ else
+ outputType = highlight::HTML;
+ }
+ break;
+ case S_OPT_MARK_LINES:
+ markLinesArg = arg;
+ break;
+ case S_OPT_PRINT_CONFIG:
+ opt_print_config = true;
+ break;
+ case S_OPT_TEST_INPUT:
+ opt_validate=true;
+ break;
+ case S_OPT_RTF_CHAR_STYLES:
+ opt_char_styles=true;
+ break;
+ case S_OPT_SKIP_UNKNOWN:
+ skipArg=arg;
+ break;
+ case S_OPT_CTAGS_FILE:
+ ctagsFile = ( arg.empty() ) ? "tags" :arg;
+ break;
+ case S_OPT_PRETTY_SYMBOLS:
+ opt_pretty_symbols = true;
+ break;
+ case S_OPT_COMPAT_DOC:
+ opt_fragment = false;
+ break;
+ case S_OPT_COMPAT_LINEREF:
+ opt_linenumbers = true;
+ opt_attach_line_anchors = true;
+ anchorPrefix = ( arg.empty() ) ? "line":arg;
+ break;
+ case S_OPT_EOL_DELIM_CR:
+ opt_delim_CR = true;
+ break;
+ case S_OPT_START_NESTED:
+ startNestedLang=arg;
+ break;
+ case S_OPT_PRINT_STYLE:
+ opt_print_style = true;
+ break;
+ case S_OPT_NO_TRAILING_NL:
+ opt_no_trailing_nl = true;
+ break;
+ default:
+ cerr << "highlight: option parsing failed" << endl;
+ }
+ }
+
+ if ( argind < parser.arguments() ) //still args left
+ {
+ if ( inputFileNames.empty() )
+ {
+ while ( argind < parser.arguments() )
+ {
+ inputFileNames.push_back ( parser.argument ( argind++ ) );
+ }
+ }
+ }
+ else if ( inputFileNames.empty() )
+ {
+ inputFileNames.push_back ( "" );
+ }
+ if ( printDebugInfo() && configFileRead )
+ {
+ cout << "Configuration file \""<<configFilePath<<"\" was read.\n";
+ }
+
+ if ( skipArg.size() )
+ {
+ istringstream valueStream;
+ string elem;
+ string wildcard;
+ valueStream.str ( StringTools::change_case ( skipArg,StringTools::CASE_LOWER ) );
+
+ while ( getline ( valueStream, elem, ';' ) )
+ {
+ ignoredFileTypes.insert ( elem );
+ }
+ for ( vector<string>::iterator file=inputFileNames.begin();file!=inputFileNames.end();file++ )
+ {
+ for ( set<string>::iterator ext=ignoredFileTypes.begin();ext!=ignoredFileTypes.end();ext++ )
+ {
+ wildcard="*."+*ext;
+ if ( Platform::wildcmp ( wildcard.c_str(), ( *file ).c_str() ) )
+ {
+ inputFileNames.erase ( file );
+ file--;
+ break;
+ }
+ }
+ }
+ }
+}
+
+CmdLineOptions::~CmdLineOptions() {}
+
+const string &CmdLineOptions::getSingleOutFilename()
+{
+ if ( !inputFileNames.empty() && !outDirectory.empty() )
+ {
+ if ( outFilename.empty() )
+ {
+ outFilename = outDirectory;
+ int delim = getSingleInFilename().find_last_of ( Platform::pathSeparator ) +1;
+ outFilename += getSingleInFilename().substr ( ( delim>-1 ) ?delim:0 )
+ + getOutFileSuffix();
+ }
+ }
+ return outFilename;
+}
+
+const string &CmdLineOptions::getSingleInFilename() const
+{
+ return inputFileNames[0];
+}
+
+const string &CmdLineOptions::getOutDirectory()
+{
+ if ( !outFilename.empty() && !enableBatchMode() )
+ {
+ outDirectory=getDirName ( outFilename );
+ }
+ return outDirectory;
+}
+
+const string CmdLineOptions::getStyleOutFilename() const
+{
+ if ( !styleOutFilename.empty() ) return styleOutFilename;
+
+ if ( outputType==highlight::TEX || outputType==highlight::LATEX )
+ {
+ return "highlight.sty";
+ }
+ else
+ {
+ return "highlight.css";
+ }
+}
+const string &CmdLineOptions::getStyleInFilename() const
+{
+ return styleInFilename;
+}
+const string& CmdLineOptions::getSVGWidth() const
+{
+ return svg_width;
+}
+const string& CmdLineOptions::getSVGHeight() const
+{
+ return svg_height;
+}
+int CmdLineOptions::getNumberSpaces() const
+{
+ return numberSpaces;
+}
+bool CmdLineOptions::printVersion() const
+{
+ return opt_version;
+}
+bool CmdLineOptions::printHelp() const
+{
+ return opt_help;
+}
+bool CmdLineOptions::printDebugInfo() const
+{
+ return opt_verbose;
+}
+bool CmdLineOptions::printConfigInfo() const
+{
+ return opt_print_config;
+}
+bool CmdLineOptions::quietMode() const
+{
+ return opt_quiet;
+}
+bool CmdLineOptions::includeStyleDef() const
+{
+ return opt_include_style;
+}
+bool CmdLineOptions::useFNamesAsAnchors() const
+{
+ return opt_fnames_as_anchors;
+}
+
+bool CmdLineOptions::formatSupportsExtStyle()
+{
+ return outputType==highlight::HTML ||
+ outputType==highlight::XHTML ||
+ outputType==highlight::LATEX ||
+ outputType==highlight::TEX ||
+ outputType==highlight::SVG;
+}
+
+bool CmdLineOptions::printLineNumbers() const
+{
+ return opt_linenumbers;
+}
+
+string CmdLineOptions::getThemeName() const
+{
+ return ( ( opt_style ) ? styleName+".style" : "kwrite.style" );
+}
+bool CmdLineOptions::enableBatchMode() const
+{
+ return inputFileNames.size() >1 || opt_batch_mode;
+}
+bool CmdLineOptions::fragmentOutput() const
+{
+ return opt_fragment;
+}
+string CmdLineOptions::getOutFileSuffix() const
+{
+ switch ( outputType )
+ {
+ case highlight::XHTML: return ".xhtml";
+ case highlight::RTF: return ".rtf";
+ case highlight::TEX:
+ case highlight::LATEX: return ".tex";
+ case highlight::XML: return ".xml";
+ case highlight::SVG: return ".svg";
+ case highlight::ANSI: return ".ansi";
+ case highlight::XTERM256: return ".xterm";
+ case highlight::BBCODE: return ".bbcode";
+ default: return ".html";
+ }
+}
+string CmdLineOptions::getDirName ( const string & path )
+{
+ size_t dirNameLength=path.rfind ( Platform::pathSeparator );
+ return ( dirNameLength==string::npos ) ?string() :path.substr ( 0, dirNameLength+1 );
+}
+bool CmdLineOptions::attachLineAnchors() const
+{
+ return opt_attach_line_anchors;
+}
+bool CmdLineOptions::showThemes() const
+{
+ return opt_show_themes;
+}
+bool CmdLineOptions::showLangdefs() const
+{
+ return opt_show_langdefs;
+}
+bool CmdLineOptions::outDirGiven() const
+{
+ return !outFilename.empty();
+}
+bool CmdLineOptions::replaceQuotes() const
+{
+ return opt_replacequotes;
+}
+bool CmdLineOptions::disableBabelShorthands() const
+{
+ return opt_babel;
+}
+bool CmdLineOptions::prettySymbols() const
+{
+ return opt_pretty_symbols;
+}
+bool CmdLineOptions::getFlag ( const string& paramVal )
+{
+ return StringTools::change_case ( paramVal ) =="true";
+}
+/*
+bool CmdLineOptions::formattingEnabled(){
+ return !indentScheme.empty();
+}
+*/
+bool CmdLineOptions::orderedList() const
+{
+ return opt_ordered_list;
+}
+bool CmdLineOptions::useCRDelimiter() const {
+ return opt_delim_CR;
+}
+const string &CmdLineOptions::getDataDir() const
+{
+ return dataDir;
+}
+bool CmdLineOptions::printOnlyStyle() const {
+ return opt_print_style;
+}
+
+string CmdLineOptions::getIndentScheme() const
+{
+ return StringTools::change_case ( indentScheme );
+}
+
+const string &CmdLineOptions::getAdditionalDataDir() const
+{
+ return additionalDataDir;
+}
+const string &CmdLineOptions::getAdditionalConfDir() const
+{
+ return additionalConfigDir;
+}
+const string &CmdLineOptions::getLanguage() const
+{
+ return syntax;
+}
+const string&CmdLineOptions::getEncoding() const
+{
+ return encodingName;
+}
+
+const string& CmdLineOptions::getAnchorPrefix() const
+{
+ return anchorPrefix;
+}
+
+const string &CmdLineOptions::getPageSize() const
+{
+ return pageSize;
+}
+bool CmdLineOptions::printIndexFile() const
+{
+ return opt_printindex && ( outputType==highlight::HTML ||
+ outputType==highlight::XHTML );
+}
+bool CmdLineOptions::printProgress() const
+{
+ return opt_print_progress;
+}
+bool CmdLineOptions::fillLineNrZeroes() const
+{
+ return opt_fill_zeroes;
+}
+bool CmdLineOptions::syntaxGiven() const
+{
+ return opt_syntax;
+}
+bool CmdLineOptions::omitEncoding() const
+{
+ return StringTools::change_case ( encodingName ) =="none";
+}
+bool CmdLineOptions::forceOutput() const
+{
+ return opt_force_output;
+}
+bool CmdLineOptions::validateInput() const
+{
+ return opt_validate;
+}
+bool CmdLineOptions::inlineCSS() const
+{
+ return opt_inline_css;
+}
+bool CmdLineOptions::enclosePreTag() const
+{
+ return opt_enclose_pre;
+}
+bool CmdLineOptions::includeCharStyles() const
+{
+ return opt_char_styles;
+}
+bool CmdLineOptions::disableTrailingNL() const
+{
+ return opt_no_trailing_nl;
+}
+const string &CmdLineOptions::getConfigFilePath() const
+{
+ return configFilePath;
+}
+
+const string& CmdLineOptions::getDocumentTitle() const
+{
+ return docTitle;
+}
+
+highlight::WrapMode CmdLineOptions::getWrappingStyle() const
+{
+ return wrappingStyle;
+}
+const vector <string> & CmdLineOptions::getInputFileNames() const
+{
+ return inputFileNames;
+}
+
+const map <int,string> & CmdLineOptions::getMarkLines()
+{
+ markLines.clear();
+ istringstream valueStream;
+ string elem;
+ size_t delimPos;
+ int markLineNo;
+ valueStream.str ( markLinesArg );
+ // Format: "1=help line one; 3=help line three; 5 "
+ while ( getline ( valueStream, elem, ';' ) )
+ {
+ delimPos = elem.find ( '=' );
+ markLineNo=0;
+ StringTools::str2num<int> ( markLineNo, elem.substr ( 0,delimPos ), std::dec );
+ if ( markLineNo )
+ {
+ markLines[markLineNo] =
+ ( delimPos!=string::npos ) ?elem.substr ( delimPos+1 ) :"";
+ }
+ }
+ return markLines;
+}
+void CmdLineOptions::readDirectory ( const string & wildcard )
+{
+ // get matching files, use recursive search
+ bool directoryOK=Platform::getDirectoryEntries ( inputFileNames, wildcard, true );
+ if ( !directoryOK )
+ {
+ cerr << "highlight: No files matched the pattern \""
+ << wildcard << "\"."<< endl;
+ }
+}
+
+string CmdLineOptions::validateDirPath ( const string & path )
+{
+ return ( path[path.length()-1] !=Platform::pathSeparator ) ?
+ path+Platform::pathSeparator : path;
+}
+
+highlight::OutputType CmdLineOptions::getOutputType() const
+{
+ return outputType;
+}
+
+StringTools::KeywordCase CmdLineOptions::getKeywordCase() const
+{
+ return keywordCase;
+}
+
+bool CmdLineOptions::hasBaseFont() const
+{
+ return ( ! baseFont.empty() ) ;
+}
+
+const string& CmdLineOptions::getBaseFont() const
+{
+ return baseFont ;
+}
+
+bool CmdLineOptions::hasBaseFontSize() const
+{
+ return ( ! baseFontSize.empty() ) ;
+}
+
+const string& CmdLineOptions::getBaseFontSize() const
+{
+ return baseFontSize ;
+}
+
+const string& CmdLineOptions::getClassName() const
+{
+ return className ;
+}
+
+const string& CmdLineOptions::getTagsFile() const
+{
+ return ctagsFile;
+}
+const string& CmdLineOptions::getStartNestedLang() const
+{
+ return startNestedLang;
+}
+int CmdLineOptions::getNumberWidth()
+{
+ return lineNrWidth;
+}
+
+int CmdLineOptions::getLineLength()
+{
+ return lineLength;
+}
+
+int CmdLineOptions::getNumberStart()
+{
+ return lineNrStart;
+}
+
+void CmdLineOptions::loadConfigurationFile()
+{
+#ifndef _WIN32
+#ifdef CONFIG_FILE_PATH
+ configFilePath=CONFIG_FILE_PATH;
+#else
+ char* homeEnv=getenv ( "HOME" );
+ if ( homeEnv==NULL ) return;
+ configFilePath=string ( homeEnv ) +"/.highlightrc";
+#endif
+#else
+ configFilePath = Platform::getAppPath() + "highlight.conf";
+#endif
+ ConfigurationReader userConfig ( configFilePath );
+
+ if ( userConfig.found() )
+ {
+ string paramVal;
+ configFileRead=true;
+
+ styleOutFilename = userConfig.getParameter ( OPT_STYLE_OUT );
+ styleInFilename = userConfig.getParameter ( OPT_STYLE_IN );
+ styleName = userConfig.getParameter ( OPT_STYLE );
+ opt_style = !styleName.empty();
+ syntax = userConfig.getParameter ( OPT_SYNTAX );
+ opt_syntax = !syntax.empty();
+ StringTools::str2num<int> ( numberSpaces, userConfig.getParameter ( OPT_DELTABS ), std::dec );
+ indentScheme = userConfig.getParameter ( OPT_FORMAT );
+ baseFontSize = userConfig.getParameter ( OPT_BASE_FONT_SIZE );
+ baseFont = userConfig.getParameter ( OPT_BASE_FONT );
+ skipArg = userConfig.getParameter ( OPT_SKIP_UNKNOWN );
+
+ paramVal = userConfig.getParameter ( OPT_DATADIR );
+ if ( !paramVal.empty() )
+ {
+ dataDir=validateDirPath ( paramVal );
+ }
+ paramVal = userConfig.getParameter ( OPT_ADDDATADIR );
+ if ( !paramVal.empty() )
+ {
+ additionalDataDir=validateDirPath ( paramVal );
+ }
+ paramVal = userConfig.getParameter ( OPT_ADDCONFDIR );
+ if ( !paramVal.empty() )
+ {
+ additionalConfigDir=validateDirPath ( paramVal );
+ }
+ paramVal = userConfig.getParameter ( OPT_OUTDIR );
+ if ( !paramVal.empty() )
+ {
+ outDirectory=validateDirPath ( paramVal );
+ }
+ paramVal = userConfig.getParameter ( OPT_ENCODING );
+ if ( !paramVal.empty() )
+ {
+ encodingName=paramVal;
+ }
+ paramVal = userConfig.getParameter ( OPT_LNR_LEN );
+ if ( !paramVal.empty() )
+ {
+ StringTools::str2num<int> ( lineNrWidth, string ( paramVal ), std::dec );
+ }
+ paramVal = userConfig.getParameter ( OPT_LNR_START );
+ if ( !paramVal.empty() )
+ {
+ StringTools::str2num<int> ( lineNrStart, string ( paramVal ), std::dec );
+ }
+ paramVal = userConfig.getParameter ( OPT_ANCHOR_PFX );
+ if ( !paramVal.empty() )
+ {
+ anchorPrefix=paramVal;
+ }
+
+ opt_include_style=getFlag ( userConfig.getParameter ( OPT_INC_STYLE ) );
+ opt_verbose=getFlag ( userConfig.getParameter ( OPT_VERBOSE ) );
+ opt_ordered_list=getFlag ( userConfig.getParameter ( OPT_ORDERED_LIST ) );
+ opt_linenumbers=opt_ordered_list || getFlag ( userConfig.getParameter ( OPT_LINENO ) );
+ opt_fragment=getFlag ( userConfig.getParameter ( OPT_FRAGMENT ) );
+ opt_attach_line_anchors=getFlag ( userConfig.getParameter ( OPT_ANCHORS ) );
+ opt_printindex=getFlag ( userConfig.getParameter ( OPT_INDEXFILE ) );
+ opt_quiet=getFlag ( userConfig.getParameter ( OPT_QUIET ) );
+ opt_replacequotes=getFlag ( userConfig.getParameter ( OPT_REPLACE_QUOTES ) );
+ opt_print_progress=getFlag ( userConfig.getParameter ( OPT_PROGRESSBAR ) );
+ opt_fill_zeroes=getFlag ( userConfig.getParameter ( OPT_FILLZEROES ) );
+ opt_fnames_as_anchors=getFlag ( userConfig.getParameter ( OPT_ANCHOR_FN ) );
+ opt_validate=getFlag ( userConfig.getParameter ( OPT_TEST_INPUT ) );
+ opt_fnames_as_anchors=getFlag ( userConfig.getParameter ( OPT_ANCHOR_FN ) );
+ opt_inline_css=getFlag ( userConfig.getParameter ( OPT_INLINE_CSS ) );
+ opt_delim_CR=getFlag ( userConfig.getParameter ( OPT_EOL_DELIM_CR) );
+
+ if ( getFlag ( userConfig.getParameter ( OPT_WRAP ) ) )
+ {
+ wrappingStyle=highlight::WRAP_DEFAULT;
+ }
+ if ( getFlag ( userConfig.getParameter ( OPT_WRAPSIMPLE ) ) )
+ {
+ wrappingStyle=highlight::WRAP_SIMPLE;
+ }
+ if ( getFlag ( userConfig.getParameter ( OPT_XHTML ) ) )
+ {
+ outputType=highlight::XHTML;
+ }
+ else if ( getFlag ( userConfig.getParameter ( OPT_RTF ) ) )
+ {
+ outputType=highlight::RTF;
+ }
+ else if ( getFlag ( userConfig.getParameter ( OPT_TEX ) ) )
+ {
+ outputType=highlight::TEX;
+ }
+ else if ( getFlag ( userConfig.getParameter ( OPT_LATEX ) ) )
+ {
+ outputType=highlight::LATEX;
+ }
+ else if ( getFlag ( userConfig.getParameter ( OPT_ANSI ) ) )
+ {
+ outputType=highlight::ANSI;
+ }
+ else if ( getFlag ( userConfig.getParameter ( OPT_XML ) ) )
+ {
+ outputType=highlight::XML;
+ }
+ else if ( getFlag ( userConfig.getParameter ( OPT_SVG ) ) )
+ {
+ outputType=highlight::SVG;
+ }
+ else if ( getFlag ( userConfig.getParameter ( OPT_XTERM256 ) ) )
+ {
+ outputType=highlight::XTERM256;
+ }
+ else if ( getFlag ( userConfig.getParameter ( OPT_BBCODE) ) )
+ {
+ outputType=highlight::BBCODE;
+ }
+ }
+}
+
diff --git a/support/highlight/src/cli/cmdlineoptions.h b/support/highlight/src/cli/cmdlineoptions.h
new file mode 100644
index 0000000000..c4cbe26b6d
--- /dev/null
+++ b/support/highlight/src/cli/cmdlineoptions.h
@@ -0,0 +1,471 @@
+/***************************************************************************
+ cmdlineoptions.h - description
+ -------------------
+ begin : Sun Nov 25 2001
+ copyright : (C) 2001-2007 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight 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.
+
+Highlight 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 Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef CMDLINEOPTIONS_H
+#define CMDLINEOPTIONS_H
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#include <string>
+#include <map>
+#include <set>
+#include <cstdlib>
+#include <iostream>
+#include <fstream>
+#include <vector>
+
+#include "stringtools.h"
+#include "enums.h"
+
+
+#define OPT_ADDCONFDIR "add-config-dir"
+#define OPT_ADDDATADIR "add-data-dir"
+#define OPT_ANCHORS "anchors"
+#define OPT_ANCHOR_FN "anchor-filename"
+#define OPT_ANCHOR_PFX "anchor-prefix"
+#define OPT_ANSI "ansi"
+#define OPT_BABEL "babel"
+#define OPT_BASE_FONT "font"
+#define OPT_BASE_FONT_SIZE "font-size"
+#define OPT_BATCHREC "batch-recursive"
+#define OPT_CLASSNAME "class-name"
+#define OPT_DATADIR "data-dir"
+#define OPT_DELTABS "replace-tabs"
+#define OPT_DOC_TITLE "doc-title"
+#define OPT_ENCLOSE_PRE "enclose-pre"
+#define OPT_ENCODING "encoding"
+#define OPT_FILLZEROES "zeroes"
+#define OPT_FORCE_OUTPUT "force"
+#define OPT_FORMAT "reformat"
+#define OPT_FRAGMENT "fragment"
+#define OPT_HELP "help"
+#define OPT_HTML "html"
+#define OPT_IN "input"
+#define OPT_INC_STYLE "include-style"
+#define OPT_INDEXFILE "print-index"
+#define OPT_INLINE_CSS "inline-css"
+#define OPT_KW_CASE "kw-case"
+#define OPT_LATEX "latex"
+#define OPT_LINENO "linenumbers"
+#define OPT_LINE_LEN "line-length"
+#define OPT_LISTLANGS "list-langs"
+#define OPT_LISTTHEMES "list-themes"
+#define OPT_LNR_LEN "line-number-length"
+#define OPT_LNR_START "line-number-start"
+#define OPT_MARK_LINES "mark-line"
+#define OPT_ORDERED_LIST "ordered-list"
+#define OPT_OUT "output"
+#define OPT_OUTDIR "outdir"
+#define OPT_RTF_PAGE_SIZE "page-size"
+#define OPT_RTF_CHAR_STYLES "char-styles"
+#define OPT_PRINT_CONFIG "print-config"
+#define OPT_PROGRESSBAR "progress"
+#define OPT_QUIET "quiet"
+#define OPT_REPLACE_QUOTES "replace-quotes"
+#define OPT_RTF "rtf"
+#define OPT_STYLE "style"
+#define OPT_STYLE_IN "style-infile"
+#define OPT_STYLE_OUT "style-outfile"
+#define OPT_SYNTAX "syntax"
+#define OPT_TEST_INPUT "validate-input"
+#define OPT_TEX "tex"
+#define OPT_VERBOSE "verbose"
+#define OPT_VERSION "version"
+#define OPT_WRAP "wrap"
+#define OPT_WRAPSIMPLE "wrap-simple"
+#define OPT_XHTML "xhtml"
+#define OPT_XML "xml"
+#define OPT_XTERM256 "xterm256"
+#define OPT_SVG "svg"
+#define OPT_SVG_WIDTH "width"
+#define OPT_SVG_HEIGHT "height"
+#define OPT_SKIP_UNKNOWN "skip"
+#define OPT_CTAGS_FILE "ctags-file"
+#define OPT_PRETTY_SYMBOLS "pretty-symbols"
+#define OPT_EOL_DELIM_CR "delim-cr"
+#define OPT_BBCODE "bbcode"
+#define OPT_START_NESTED "start-nested"
+#define OPT_PRINT_STYLE "print-style"
+#define OPT_NO_TRAILING_NL "no-trailing-nl"
+
+// Improve CLI option compatibility with GNU source-highlight
+#define OPT_COMPAT_DOC "doc"
+#define OPT_COMPAT_NODOC "no-doc"
+#define OPT_COMPAT_TAB "tab"
+#define OPT_COMPAT_CSS "css"
+#define OPT_COMPAT_OUTDIR "output-dir"
+#define OPT_COMPAT_FAILSAFE "failsafe"
+#define OPT_COMPAT_OUTFORMAT "out-format"
+#define OPT_COMPAT_SRCLANG "src-lang"
+#define OPT_COMPAT_LINENUM "line-number"
+#define OPT_COMPAT_LINEREF "line-number-ref"
+
+using namespace std;
+
+/// handle command line options
+
+class CmdLineOptions
+{
+ public:
+
+ /**Constructor
+ \param argc Argument count
+ \param argv Argument strings
+ */
+ CmdLineOptions ( const int argc, const char *argv[] );
+ ~CmdLineOptions();
+
+ /** \return Single output file name*/
+ const string &getSingleOutFilename();
+
+ /** \return Single input file name*/
+ const string &getSingleInFilename() const;
+
+ /** \return Output directory*/
+ const string& getOutDirectory() ;
+
+ /** \return Style output file name*/
+ const string getStyleOutFilename() const;
+
+ /** \return Style input file name*/
+ const string& getStyleInFilename() const;
+
+ /** \return Char set*/
+ const string& getEncoding() const;
+
+ /** \return SVG width*/
+ const string& getSVGWidth() const;
+
+ /** \return SVG height*/
+ const string& getSVGHeight() const;
+
+ /** \return Number of spaces to replace a tab*/
+ int getNumberSpaces() const;
+
+ /** \return True if version information should be printed*/
+ bool printVersion() const;
+
+ /** \return True if help information should be printed*/
+ bool printHelp() const;
+
+ /** \return True if debug information should be printed*/
+ bool printDebugInfo() const;
+
+ /** \return True if configuration information should be printed*/
+ bool printConfigInfo() const;
+
+ /** \return True if Style definition should be included in output*/
+ bool includeStyleDef() const;
+
+ /** \return True if line numbers should be printed*/
+ bool printLineNumbers() const;
+
+ /** \return True if CR is eol delimiter */
+ bool useCRDelimiter() const;
+
+ /** \return colour theme name */
+ string getThemeName() const ;
+
+ /** gibt true zurck, falls deutsche Hilfe ausgegeben werden soll */
+ int helpLanguage() const;
+
+ /** \return True if batch mode is active*/
+ bool enableBatchMode() const;
+
+ /** \return True if output shluld be fragmented*/
+ bool fragmentOutput() const;
+
+ /** \return output file suffix */
+ string getOutFileSuffix() const;
+
+ /** \return True if anchors should be attached to line numbers*/
+ bool attachLineAnchors() const;
+
+ /** \return True if list of installed themes should be printed*/
+ bool showThemes() const;
+
+ /** \return True if list of installed language definitions should be printed*/
+ bool showLangdefs() const;
+
+ /** \return True if loutput directory is given*/
+ bool outDirGiven() const;
+
+ /** \return True if refomatting is enabled*/
+// bool formattingEnabled();
+
+ /** \return True if a new data directory is given*/
+ bool dataDirGiven() const;
+
+ /** \return True if an additional data directory is given*/
+ bool additionalDataDirGiven() const;
+
+ /** \return True if index file should be printed*/
+ bool printIndexFile() const;
+
+ /** \return True if quotes should be replaced by /dq in LaTeX*/
+ bool replaceQuotes() const;
+
+ /** \return True if shorthands of LaTeX Babel package should be disabled*/
+ bool disableBabelShorthands() const;
+
+ /** \return True if input file name should be used as anchor name */
+ bool useFNamesAsAnchors() const;
+
+ /** \return Data directory*/
+ const string &getDataDir() const;
+
+ /** \return Additional data directory*/
+ const string &getAdditionalDataDir() const;
+
+ /** \return Additional config data directory*/
+ const string &getAdditionalConfDir() const;
+
+ /** \return path of user config file*/
+ const string &getConfigFilePath() const;
+
+ /** \return True if language syntax is given*/
+ bool syntaxGiven() const;
+
+ /** \return True if quiet mode is active*/
+ bool quietMode() const;
+
+ /** \return True if progress bar should be printed in batch mode */
+ bool printProgress() const;
+
+ /** \return True if line numbers are filled with leading zeroes */
+ bool fillLineNrZeroes() const;
+
+ /** \return programming syntax */
+ const string &getLanguage() const ;
+
+ /** \return Wrapping style*/
+ highlight::WrapMode getWrappingStyle() const;
+
+ /** \return List of input file names*/
+ const vector <string> & getInputFileNames() const;
+
+ /** \return Map of marked lines*/
+ const map <int,string> &getMarkLines();
+
+ /** \return indentation and reformatting scheme*/
+ string getIndentScheme() const;
+
+ /** \return RTF page size */
+ const string &getPageSize() const;
+
+ /** \return Output file format */
+ highlight::OutputType getOutputType() const;
+
+ /** \return True if chosen output format supports referenced style files */
+ bool formatSupportsExtStyle();
+
+ /** \return True if style output path was defined by user*/
+ bool styleOutPathDefined() const
+ {
+ return opt_stylepath_explicit;
+ }
+
+ /** \return True if encoding specification should be omitted in output*/
+ bool omitEncoding() const;
+
+ /** \return True if output should be generated if languege type is unknown*/
+ bool forceOutput() const;
+
+ /** \return True if line numbers should be replaced by ordered list (HTML) */
+ bool orderedList() const;
+
+ /** \return True if a base font has been given */
+ bool hasBaseFont() const ;
+
+ /** \return True if input should be validated */
+ bool validateInput() const ;
+
+ /** \return True if CSS should be outputted within tag elements */
+ bool inlineCSS() const ;
+
+ /** \return True if fragmented html output should be enclosed with pre tags */
+ bool enclosePreTag() const ;
+
+ /** \return True if RTF output should include character styles */
+ bool includeCharStyles() const ;
+
+ /** \return True if LaTeX output should includ fancier symbols */
+ bool prettySymbols() const;
+
+ /** \return True if style should be printed */
+ bool printOnlyStyle() const;
+
+ /** \return The given base font, empty string by default */
+ const string& getBaseFont() const ;
+
+ /** \return Document title */
+ const string& getDocumentTitle() const ;
+
+ /** \return anchor prefix */
+ const string& getAnchorPrefix() const ;
+
+ /** \return class name */
+ const string& getClassName() const ;
+
+ /** \return ctags file name */
+ const string& getTagsFile() const ;
+
+ /** \return True if a base font size has been given */
+ bool hasBaseFontSize() const ;
+
+ /** \return True if trailing nl should be omitted */
+ bool disableTrailingNL() const ;
+
+ /** \return The given base font size, empty string by default */
+ const string& getBaseFontSize() const ;
+
+ /** \return name of nested syntax which starts the input */
+ const string& getStartNestedLang() const ;
+
+ /** \return line number width */
+ int getNumberWidth();
+
+ /** \return line length */
+ int getLineLength();
+
+ /** \return Line number start count */
+ int getNumberStart();
+
+ /** \return Keyword Case (upper, lower, unchanged) */
+ StringTools::KeywordCase getKeywordCase() const;
+
+ bool isSkippedExt ( const string& ext )
+ {
+ return ignoredFileTypes.count ( ext );
+ }
+
+ private:
+
+ int numberSpaces; // number of spaces which replace a tab
+ int lineNrWidth; // width of line number (left padding)
+ int lineLength; // length of line before wrapping
+ int lineNrStart; // line number start count
+ highlight::WrapMode wrappingStyle; // line wrapping mode
+ highlight::OutputType outputType;
+ StringTools::KeywordCase keywordCase;
+
+ // name of single output file
+ string outFilename,
+ // output directory
+ outDirectory,
+ // programming syntax which will be loaded
+ syntax,
+ // name of colour theme
+ styleName,
+ // name of external style file
+ styleOutFilename,
+ // name of file to be included in external style file
+ styleInFilename,
+ // used to define data directories at runtime
+ dataDir, additionalDataDir, additionalConfigDir;
+ // name of indenation scheme
+ string indentScheme,
+ pageSize, startNestedLang;
+
+ string baseFont, baseFontSize;
+ string docTitle, className;
+ string markLinesArg;
+ string skipArg;
+ string svg_height, svg_width;
+ string ctagsFile;
+
+ bool opt_syntax;
+ bool opt_include_style;
+ bool opt_help;
+ bool opt_version ;
+ bool opt_verbose;
+ bool opt_print_config;
+ bool opt_linenumbers;
+ bool opt_style;
+ bool opt_batch_mode;
+ bool opt_fragment;
+ bool opt_attach_line_anchors;
+ bool opt_show_themes;
+ bool opt_show_langdefs;
+ bool opt_asformat_output;
+ bool opt_printindex;
+ bool opt_quiet;
+ bool opt_replacequotes;
+ bool opt_babel;
+ bool opt_print_progress;
+ bool opt_fill_zeroes;
+ bool opt_stylepath_explicit;
+ bool opt_force_output;
+ bool opt_ordered_list;
+ bool opt_fnames_as_anchors;
+ bool opt_validate;
+ bool opt_inline_css;
+ bool opt_enclose_pre;
+ bool opt_char_styles;
+ bool opt_pretty_symbols;
+ bool opt_delim_CR;
+ bool opt_print_style;
+ bool opt_no_trailing_nl;
+
+ bool configFileRead;
+
+ string anchorPrefix;
+
+ string helpLang, encodingName;
+ string configFilePath;
+
+ /** list of all input file names */
+ vector <string> inputFileNames;
+
+ /** list lines which should be marked and supplied with help string */
+ map <int, string> markLines;
+
+ /** list of file types which should be ignored */
+ set <string> ignoredFileTypes;
+
+ /** load highlight configuration file */
+ void loadConfigurationFile();
+
+ /** \return file suffix */
+ string getFileSuffix ( const string & fileName ) const;
+
+ /** \return directory name of path */
+ string getDirName ( const string & path );
+
+ /** get all entries in the directory defined by wildcard */
+ void readDirectory ( const string & wildcard );
+
+ /** \return Boolean value of paramVal */
+ bool getFlag ( const string& paramVal );
+
+ /** \return Valid path name */
+ string validateDirPath ( const string & path );
+};
+
+#endif
diff --git a/support/highlight/src/cli/help.cpp b/support/highlight/src/cli/help.cpp
new file mode 100644
index 0000000000..d80312a7a9
--- /dev/null
+++ b/support/highlight/src/cli/help.cpp
@@ -0,0 +1,185 @@
+/***************************************************************************
+ help.cpp - description
+ -------------------
+ begin : Die Apr 23 2002
+ copyright : (C) 2002-2007 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight 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.
+
+Highlight 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 Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <iostream>
+
+#include "help.h"
+
+using namespace std;
+
+namespace Help
+{
+
+ void printHelp()
+ {
+ cout<<"USAGE: highlight [OPTIONS]... [FILES]...\n";
+ cout<<"\n";
+ cout<<"General options:\n";
+ cout<<"\n";
+ cout<<" -B, --batch-recursive=<wc> convert all matching files, searches subdirs\n";
+ cout<<" (Example: -B '*.cpp')\n";
+ cout<<" -D, --data-dir=<directory> set path to data directory\n";
+ cout<<" -E, --add-data-dir=<directory> set path to an additional data directory, which\n";
+ cout<<" is searched first\n";
+ cout<<" --add-config-dir=<dir> set path to an additional config directory\n";
+ cout<<" -h, --help print this help\n";
+ cout<<" -i, --input=<file> name of single input file\n";
+ cout<<" -o, --output=<file> name of single output file\n";
+ cout<<" -O, --outdir=<directory> name of output directory\n";
+ cout<<" -p, --list-langs list installed language definitions\n";
+ cout<<" -P, --progress print progress bar in batch mode\n";
+ cout<<" -q, --quiet supress progress info in batch mode\n";
+ cout<<" -S, --syntax=<type> specify type of source code\n";
+ cout<<" -v, --verbose print debug info\n";
+ cout<<" -w, --list-themes list installed colour themes\n";
+ cout<<" --force generate output if language type is unknown\n";
+ cout<<" --print-config print path configuration\n";
+ cout<<" --print-style print only style (see --style-outfile)\n";
+ cout<<" --skip=<list> ignore listed unknown file types\n";
+ cout<<" (Example: --skip='bak;c~;h~')\n";
+ cout<<" --start-nested=<lang> define nested language which starts input\n";
+ cout<<" without opening delimiter\n";
+ cout<<" --validate-input test if input is a valid text file\n";
+ cout<<" --version print version and copyright information\n";
+ cout<<"\n";
+ cout<<"\n";
+ cout<<"Output formats:\n";
+ cout<<"\n";
+ cout<<" -H, --html generate HTML (default)\n";
+ cout<<" -A, --ansi generate terminal output (16 colours)\n";
+ cout<<" -L, --latex generate LaTeX\n";
+ cout<<" -M, --xterm256 generate terminal output (256 colours)\n";
+ cout<<" -R, --rtf generate RTF\n";
+ cout<<" -T, --tex generate TeX\n";
+ cout<<" -X, --xhtml generate XHTML 1.1\n";
+ cout<<" -Z, --xml generate XML\n";
+ cout<<" -G, --svg generate SVG (experimental)\n";
+ cout<<" -Y, --bbcode generate BBCode (experimental)\n";
+ cout<<" --out-format=<format> output file in given format\n";
+ cout<<" <format>: see long options above\n";
+ cout<<"\n";
+ cout<<"\n";
+ cout<<"Output formatting options:\n";
+ cout<<"\n";
+ cout<<" -c, --style-outfile=<file> name of style file or output to stdout, if\n";
+ cout<<" 'stdout' is given as file argument\n";
+ cout<<" -d, --doc-title=<title> document title\n";
+ cout<<" -e, --style-infile=<file> file to be included in style-outfile\n";
+ cout<<" -I, --include-style include style definition\n";
+ cout<<" -f, --fragment omit file header and footer\n";
+ cout<<" -F, --reformat=<style> reformats and indents output in given style\n";
+ cout<<" <style>=['allman', 'banner', 'gnu',\n";
+ cout<<" 'horstmann', 'java', 'kr', 'linux', 'otbs',\n";
+ cout<<" 'stroustrup', 'whitesmith']\n";
+ cout<<" -J, --line-length=<num> line length before wrapping (see -W, -V)\n";
+ cout<<" -j, --line-number-length=<num> line number width incl. left padding\n";
+ cout<<" -k, --font=<font> set font (specific to output format)\n";
+ cout<<" -K, --font-size=<num?> set font size (specific to output format)\n";
+ cout<<" -l, --linenumbers print line numbers in output file\n";
+ cout<<" -m, --line-number-start=<cnt> start line numbering with cnt (assumes -l)\n";
+ cout<<" -s, --style=<style> set colour style (see -w)\n";
+ cout<<" -t, --replace-tabs=<num> replace tabs by <num> spaces\n";
+ cout<<" -u, --encoding=<enc> set output encoding which matches input file\n";
+ cout<<" encoding; omit encoding info if enc=NONE\n";
+ cout<<" -V, --wrap-simple wrap long lines without indenting function\n";
+ cout<<" parameters and statements\n";
+ cout<<" -W, --wrap wrap long lines\n";
+ cout<<" -z, --zeroes fill leading space of line numbers with 0's\n";
+ cout<<" --kw-case=<case> change case of case insensitive keywords\n";
+ cout<<" <case> = ['upper', 'lower', 'capitalize']\n";
+ cout<<" --delim-cr set CR as end-of-line delimiter (MacOS 9)\n";
+ cout<<" --no-trailing-nl omit trailing newline\n";
+ cout<<"\n";
+ cout<<"(X)HTML output options:\n";
+ cout<<"\n";
+ cout<<" -a, --anchors attach anchor to line numbers\n";
+ cout<<" -y, --anchor-prefix=<str> set anchor name prefix\n";
+ cout<<" -N, --anchor-filename use input file name as anchor name\n";
+ cout<<" -C, --print-index print index with hyperlinks to output files\n";
+ cout<<" -n, --ordered-list print lines as ordered list items\n";
+ cout<<" --class-name=<str> set CSS class name prefix\n";
+ cout<<" --inline-css output CSS within each tag (verbose output)\n";
+ cout<<" --mark-line='n[=txt]; m' mark given lines n..m and add optional help\n";
+ cout<<" texts as tooltips\n";
+ cout<<" --enclose-pre enclose fragmented output with pre tag \n";
+ cout<<" (assumes -f)\n";
+ cout<<" --ctags-file[=<file>] read ctags file to include meta information as\n";
+ cout<<" tooltips (default value: tags)\n";
+ cout<<"\n";
+ cout<<"LaTeX output options:\n";
+ cout<<"\n";
+ cout<<" -b, --babel disable Babel package shorthands\n";
+ cout<<" -r, --replace-quotes replace double quotes by \\dq{}\n";
+ cout<<" --pretty-symbols improve appearance of brackets and other symbols\n";
+ cout<<"\n";
+ cout<<"\n";
+ cout<<"RTF output options:\n";
+ cout<<"\n";
+ cout<<" -x, --page-size=<ps> set page size \n";
+ cout<<" <ps> = [a3, a4, a5, b4, b5, b6, letter]\n";
+ cout<<" --char-styles include character stylesheets\n";
+ cout<<"\n";
+ cout<<"\n";
+ cout<<"SVG output options:\n";
+ cout<<"\n";
+ cout<<" --height set image height (units allowed)\n";
+ cout<<" --width set image width (see --height)\n";
+ cout<<"\n";
+ cout<<"\n";
+ cout<<"GNU source-highlight compatibility options:\n";
+ cout<<"\n";
+ cout<<" --doc create stand alone document\n";
+ cout<<" --no-doc cancel the --doc option\n";
+ cout<<" --css=filename the external style sheet filename\n";
+ cout<<" --src-lang=STRING source language\n";
+ cout<<" -t, --tab=INT specify tab length\n";
+ cout<<" -n, --line-number[=0] number all output lines, optional padding\n";
+ cout<<" --line-number-ref[=p] number all output lines and generate an anchor,\n";
+ cout<<" made of the specified prefix p + the line\n";
+ cout<<" number (default='line')\n";
+ cout<<" --output-dir=path output directory\n";
+ cout<<" --failsafe if no language definition is found for the\n";
+ cout<<" input, it is simply copied to the output\n";
+ cout<<"\n";
+ cout<<"\n";
+ cout<<"-t will be ignored if -F is set.\n";
+ cout<<"-i and -o will be ignored if -b or -B is set.\n";
+ cout<<"-r will be ignored if -f is not set.\n";
+ cout<<"-c will be ignored if the output format does not support referenced styles.\n";
+ cout<<"If no in- or output files are specified, stdin and stdout will be used for\n";
+ cout<<"in- or output.\n";
+ cout<<"HTML will be generated, if no other output format is given. Style definitions\n";
+ cout<<"are stored in highlight.css (HTML, XHTML, SVG) or highlight.sty (LaTeX, TeX)\n";
+ cout<<"if neither -c nor -I is given.\n";
+ cout<<"Reformatting code will only work with C, C++, C# and Java input files.\n";
+ cout<<"Wrapping lines with -V or -W will cause faulty highlighting of long single\n";
+ cout<<"line comments and directives. Use with caution.\n";
+ cout<<"\n";
+ cout<<"Updates and information: http://www.andre-simon.de/\n";
+ }
+
+}
diff --git a/support/highlight/src/cli/help.h b/support/highlight/src/cli/help.h
new file mode 100644
index 0000000000..e4500d679c
--- /dev/null
+++ b/support/highlight/src/cli/help.h
@@ -0,0 +1,42 @@
+/***************************************************************************
+ help.h - description
+ -------------------
+ begin : Die Apr 23 2002
+ copyright : (C) 2002-2007 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight 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.
+
+Highlight 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 Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef HELP_H
+#define HELP_H
+
+#include <string>
+
+///Contains methods for printing help messages
+
+namespace Help
+{
+ /** print help message to stdout
+ */
+ void printHelp();
+}
+
+#endif
diff --git a/support/highlight/src/cli/main.cpp b/support/highlight/src/cli/main.cpp
new file mode 100644
index 0000000000..cb2030fdf5
--- /dev/null
+++ b/support/highlight/src/cli/main.cpp
@@ -0,0 +1,709 @@
+/***************************************************************************
+ main.cpp - description
+ -------------------
+ begin : Die Apr 23 22:16:35 CEST 2002
+ copyright : (C) 2002-2009 by Andre Simon
+ email : andre.simon1@gmx.de
+
+ Highlight is a universal source code to HTML converter. Syntax highlighting
+ is formatted by Cascading Style Sheets. It's possible to easily enhance
+ highlight's parsing database.
+
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight 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.
+
+Highlight 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 Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <memory>
+#include <algorithm>
+#include "main.h"
+#include "re/Pattern.h"
+
+#define MAX_LINE__WIDTH 80
+
+using namespace std;
+
+void HLCmdLineApp::printVersionInfo()
+{
+ cout << "\n highlight version "
+ << HIGHLIGHT_VERSION
+ << "\n Copyright (C) 2002-2010 Andre Simon <andre.simon1 at gmx.de>"
+ << "\n\n Artistic Style Classes (1.24)"
+ << "\n Copyright (C) 2006-2010 by Jim Pattee <jimp03 at email.com>"
+ << "\n Copyright (C) 1998-2002 by Tal Davidson"
+ << "\n\n Regex library (1.09.00)"
+ << "\n Copyright (C) 2003-2008 Jeffery Stuart <stuart at cs.unr.edu>"
+ << "\n\n xterm 256 color matching functions"
+ << "\n Copyright (C) 2006 Wolfgang Frisch <wf at frexx.de>"
+ << "\n\n Argparser class"
+ << "\n Copyright (C) 2006-2008 Antonio Diaz Diaz <ant_diaz at teleline.es>"
+ << "\n\n This software is released under the terms of the GNU General "
+ << "Public License."
+ << "\n For more information about these matters, see the file named "
+ << "COPYING.\n\n";
+}
+
+void HLCmdLineApp::printBadInstallationInfo()
+{
+ cerr << "highlight: Data directory not found ("<<DataDir::LSB_DATA_DIR<<")."
+ " Bad installation or wrong "<< OPT_DATADIR << " parameter."
+ << "\n\nCopy the highlight files into one of the directories listed "
+ << "in INSTALL.\nYou may also set the data directory with "
+ << OPT_DATADIR << " and " << OPT_ADDDATADIR << ".\n";
+}
+
+bool HLCmdLineApp::printInstalledThemes()
+{
+ vector <string> filePaths;
+ string wildcard="*.style";
+ string directory= dataDir.getThemePath();
+ string searchDir = directory + wildcard;
+
+ bool directoryOK = Platform::getDirectoryEntries ( filePaths, searchDir, true );
+ if ( !directoryOK )
+ {
+ cerr << "highlight: Could not access directory "
+ << searchDir
+ << ", aborted.\n";
+ return false;
+ }
+
+ cout << "\nInstalled themes"
+ << " (located in " << directory << "):\n\n";
+
+ sort ( filePaths.begin(), filePaths.end() );
+ string temp;
+
+ for ( unsigned int i=0;i< filePaths.size(); i++ )
+ {
+ temp = ( filePaths[i] ).substr ( directory.length() );
+ cout <<temp.substr ( 1, temp.length()- wildcard.length() ) << endl;
+ }
+ cout <<"\nUse name of the desired theme"
+ << " with the --" OPT_STYLE " option.\n" << endl;
+ return true;
+}
+
+
+bool HLCmdLineApp::printInstalledLanguages()
+{
+ vector <string> filePaths;
+ string wildcard="*.lang";
+ string directory=dataDir.getLangPath();
+ string searchDir = directory + wildcard;
+
+ bool directoryOK = Platform::getDirectoryEntries ( filePaths, searchDir, true );
+ if ( !directoryOK )
+ {
+ cerr << "highlight: Could not access directory "
+ << searchDir
+ << ", aborted.\n";
+ return false;
+ }
+
+ sort ( filePaths.begin(), filePaths.end() );
+ string suffix, desc;
+ cout << "\nInstalled language definitions"
+ << " (located in " << directory << "):\n\n";
+
+ for ( unsigned int i=0;i< filePaths.size(); i++ )
+ {
+ ConfigurationReader lang ( filePaths[i] );
+ desc = lang.getParameter ( "description" );
+ suffix = ( filePaths[i] ).substr ( directory.length() ) ;
+ suffix = suffix.substr ( 1, suffix.length()- wildcard.length() );
+ cout << setw ( 20 ) <<setiosflags ( ios::left ) <<desc<<": "<<suffix;
+ int extCnt=0;
+ for (StringMap::iterator it=extensions.begin();it!=extensions.end();it++) {
+ if (it->second==suffix ) {
+
+ cout << ((++extCnt==1)?" ( ":" ")<<it->first;
+ }
+ }
+ cout << ((extCnt)?" )":"")<<endl;
+ }
+ cout <<"\nUse name of the desired language"
+ << " with the --" OPT_SYNTAX " option.\n" << endl;
+ return true;
+}
+
+void HLCmdLineApp::printDebugInfo ( const highlight::LanguageDefinition &lang,
+ const string & langDefPath )
+{
+ cerr << "\nLoading language definition:\n" << langDefPath;
+ cerr << "\n\nDescription: " << lang.getDescription();
+ cerr << "\n\nSYMBOLS (followed by states):\n" << lang.getSymbolString();
+ cerr << "\n\nREGEX:\n";
+ highlight::RegexElement *re=NULL;
+ for ( unsigned int i=0; i<lang.getRegexElements().size(); i++ )
+ {
+ re = lang.getRegexElements() [i];
+ cerr << "State "<<re->open<<":\t"<<re->rePattern->getPattern() <<"\n";
+ }
+ cerr << "\nKEYWORDS:\n";
+ highlight::KeywordMap::iterator it;
+ highlight::KeywordMap keys=lang.getKeywords();
+ for ( it=keys.begin(); it!=keys.end(); it++ )
+ {
+ cerr << " "<< it->first << "("<< it->second << ")";
+ }
+ cerr <<"\n\n";
+}
+
+void HLCmdLineApp::printConfigInfo ( const string& configFile )
+{
+ cout << "\nRoot paths (modify with --" OPT_DATADIR " and --" OPT_ADDDATADIR "):\n";
+ cout << " Data directory: "<<dataDir.getDir() <<"\n";
+ if ( !dataDir.getAdditionalDataDir().empty() )
+ cout << " User defined directory: "<<dataDir.getAdditionalDataDir() <<"\n";
+ cout << "\nDefault search paths:\n";
+ cout << " Language definitions: "<<dataDir.getLangPath ( "", true ) <<"\n";
+ cout << " Colour themes: "<<dataDir.getThemePath ( "", true ) <<"\n";
+
+ if ( !dataDir.getAdditionalDataDir().empty() )
+ {
+ cout << "\nAdditional search paths:\n";
+ cout << " Language definitions: "<<dataDir.getAdditionalLangDefDir() <<"\n";
+ cout << " Colour themes: "<<dataDir.getAdditionalThemeDir() <<"\n";
+// cout << " Indentation schemes: "<<dataDir.getAdditionalIndentSchemesDir()<<"\n";
+ }
+
+ cout << "\nConfiguration paths:\n";
+ cout << " Configuration files: "<<dataDir.getConfDir ( true ) <<"\n";
+ cout << " User configuration: "<<configFile<<"\n";
+ if ( !dataDir.getAdditionalConfDir().empty() )
+ {
+ cout << "\nAdditional search paths:\n";
+ cout << " Configuration files: "<<dataDir.getAdditionalConfDir() <<"\n";
+ }
+ cout << endl;
+#ifdef HL_DATA_DIR
+ cout << "Compiler directive HL_DATA_DIR = " <<HL_DATA_DIR<< "\n";
+#endif
+#ifdef HL_CONFIG_DIR
+ cout << "Compiler directive HL_CONFIG_DIR = " <<HL_CONFIG_DIR<< "\n";
+#endif
+
+ cout << endl;
+}
+
+string HLCmdLineApp::getFileSuffix ( const string &fileName )
+{
+ size_t ptPos=fileName.rfind ( "." );
+ return ( ptPos == string::npos ) ? "" : fileName.substr ( ptPos+1, fileName.length() );
+}
+
+bool HLCmdLineApp::loadFileTypeConfig ( const string& name, StringMap* extMap, StringMap* shebangMap )
+{
+ if ( !extMap || !shebangMap ) return false;
+ string confPath=dataDir.getConfDir() + name + ".conf";
+ ConfigurationReader config ( confPath );
+ if ( config.found() )
+ {
+ stringstream values;
+ string paramName, paramVal;
+ for ( unsigned int i=0;i<config.getParameterNames().size();i++ )
+ {
+ paramName = config.getParameterNames() [i];
+
+ if ( paramName.find ( "ext" ) != string::npos )
+ {
+ values.str ( StringTools::change_case ( config.getParameter ( paramName ) ) );
+ paramName = StringTools::getParantheseVal ( paramName );
+ while ( values >> paramVal )
+ {
+ extMap->insert ( make_pair ( paramVal, paramName ) );
+ }
+ values.clear();
+ }
+ else if ( paramName.find ( "shebang" ) != string::npos )
+ {
+ values.str ( config.getParameter ( paramName ) ) ;
+ paramName = StringTools::getParantheseVal ( paramName );
+ while ( values >> paramVal )
+ {
+ shebangMap->insert ( make_pair ( paramVal, paramName ) );
+ }
+ values.clear();
+ }
+ }
+ return true;
+ }
+ else
+ {
+ cerr << "highlight: Configuration file "<< confPath << " not found.\n";
+ return false;
+ }
+}
+
+
+int HLCmdLineApp::getNumDigits ( int i )
+{
+ int res=0;
+ while ( i )
+ {
+ i/=10;
+ ++res;
+ }
+ return res;
+}
+
+void HLCmdLineApp::printProgressBar ( int total, int count )
+{
+ if ( !total ) return;
+ int p=100*count / total;
+ int numProgressItems=p/10;
+ cout << "\r[";
+ for ( int i=0;i<10;i++ )
+ {
+ cout << ( ( i<numProgressItems ) ?"#":" " );
+ }
+ cout<< "] " <<setw ( 3 ) <<p<<"%, "<<count << " / " << total << " " <<flush;
+ if ( p==100 )
+ {
+ cout << endl;
+ }
+}
+
+void HLCmdLineApp::printCurrentAction ( const string&outfilePath,
+ int total, int count, int countWidth )
+{
+ cout << "Writing file "
+ << setw ( countWidth ) << count
+ << " of "
+ << total
+ << ": "
+ << outfilePath
+ << "\n";
+}
+
+void HLCmdLineApp::printIOErrorReport ( unsigned int numberErrorFiles,
+ vector<string> & fileList,
+ const string &action )
+{
+ cerr << "highlight: Could not "
+ << action
+ << " file"
+ << ( ( numberErrorFiles>1 ) ?"s":"" ) <<":\n";
+ copy ( fileList.begin(), fileList.end(), ostream_iterator<string> ( cerr, "\n" ) );
+ if ( fileList.size() < numberErrorFiles )
+ {
+ cerr << "... ["
+ << ( numberErrorFiles - fileList.size() )
+ << " of "
+ << numberErrorFiles
+ << " failures not shown, use --"
+ << OPT_VERBOSE
+ << " switch to print all failures]\n";
+ }
+}
+
+string HLCmdLineApp::analyzeFile ( const string& file )
+{
+ string firstLine;
+
+ if ( !file.empty() )
+ {
+ ifstream inFile ( file.c_str() );
+ getline ( inFile, firstLine );
+ }
+ else
+ {
+ // This copies all the data to a new buffer, uses the data to get the
+ // first line, then makes cin use the new buffer that underlies the
+ // stringstream instance
+ cin_bufcopy << cin.rdbuf();
+ getline ( cin_bufcopy, firstLine );
+ cin_bufcopy.seekg ( 0, ios::beg );
+ cin.rdbuf ( cin_bufcopy.rdbuf() );
+ }
+ StringMap::iterator it;
+ for ( it=scriptShebangs.begin(); it!=scriptShebangs.end();it++ )
+ {
+ if ( Pattern::matches ( it->first, firstLine ) ) return it->second;
+ }
+ return "";
+}
+
+string HLCmdLineApp::guessFileType ( const string& suffix, const string &inputFile )
+{
+ string lcSuffix = StringTools::change_case ( suffix );
+ string fileType = ( extensions.count ( lcSuffix ) ) ? extensions[lcSuffix] : lcSuffix ;
+ if ( !fileType.empty() ) return fileType;
+ return analyzeFile ( inputFile );
+}
+
+
+int HLCmdLineApp::run ( const int argc, const char*argv[] )
+{
+
+ CmdLineOptions options ( argc, argv );
+
+ // set data directory path, where /langDefs and /themes reside
+ string dataDirPath = ( options.getDataDir().empty() ) ? Platform::getAppPath() :options.getDataDir();
+
+ if ( options.printVersion() )
+ {
+ printVersionInfo();
+ return EXIT_SUCCESS;
+ }
+
+
+
+
+ dataDir.setAdditionalDataDir ( options.getAdditionalDataDir() );
+ dataDir.setAdditionalConfDir ( options.getAdditionalConfDir() );
+
+ if ( ! dataDir.searchDataDir ( dataDirPath ) )
+ {
+ printBadInstallationInfo();
+ return EXIT_FAILURE;
+ }
+
+ if ( options.printHelp() )
+ {
+ Help::printHelp();
+ return EXIT_SUCCESS;
+ }
+
+ if ( options.printConfigInfo() )
+ {
+ printConfigInfo ( options.getConfigFilePath() );
+ return EXIT_SUCCESS;
+ }
+
+ if ( options.showThemes() )
+ {
+ return printInstalledThemes() ?EXIT_SUCCESS:EXIT_FAILURE;
+ }
+
+ //call before printInstalledLanguages!
+ loadFileTypeConfig ( "filetypes", &extensions, &scriptShebangs );
+
+ if ( options.showLangdefs() )
+ {
+ return printInstalledLanguages() ?EXIT_SUCCESS:EXIT_FAILURE;
+ }
+
+ const vector <string> inFileList=options.getInputFileNames();
+
+ if ( options.enableBatchMode() && inFileList[0].empty() )
+ {
+ return EXIT_FAILURE;
+ }
+
+ string themePath=dataDir.getThemePath ( options.getThemeName() );
+
+ auto_ptr<highlight::CodeGenerator> generator ( highlight::CodeGenerator::getInstance ( options.getOutputType() ) );
+
+
+ generator->setHTMLAttachAnchors ( options.attachLineAnchors() );
+ generator->setHTMLOrderedList ( options.orderedList() );
+ generator->setHTMLInlineCSS ( options.inlineCSS() );
+ generator->setHTMLEnclosePreTag ( options.enclosePreTag() );
+ generator->setHTMLAnchorPrefix ( options.getAnchorPrefix() );
+ generator->setHTMLClassName ( options.getClassName() );
+
+ generator->setLATEXReplaceQuotes ( options.replaceQuotes() );
+ generator->setLATEXNoShorthands ( options.disableBabelShorthands() );
+ generator->setLATEXPrettySymbols ( options.prettySymbols() );
+
+ generator->setRTFPageSize ( options.getPageSize() );
+ generator->setRTFCharStyles ( options.includeCharStyles() );
+
+ generator->setSVGSize ( options.getSVGWidth(), options.getSVGHeight() );
+
+ if (options.useCRDelimiter())
+ generator->setEOLDelimiter('\r');
+
+ generator->setValidateInput ( options.validateInput() );
+ generator->setStyleInputPath ( options.getStyleInFilename() );
+ generator->setStyleOutputPath ( options.getStyleOutFilename() );
+ generator->setIncludeStyle ( options.includeStyleDef() );
+ generator->setPrintLineNumbers ( options.printLineNumbers(), options.getNumberStart() );
+ generator->setPrintZeroes ( options.fillLineNrZeroes() );
+ generator->setFragmentCode ( options.fragmentOutput() );
+ generator->setPreformatting ( options.getWrappingStyle(),
+ ( generator->getPrintLineNumbers() ) ?
+ options.getLineLength() - options.getNumberWidth() : options.getLineLength(),
+ options.getNumberSpaces() );
+
+ generator->setEncoding ( options.getEncoding() );
+ generator->setBaseFont ( options.getBaseFont() ) ;
+ generator->setBaseFontSize ( options.getBaseFontSize() ) ;
+ generator->setLineNumberWidth ( options.getNumberWidth() );
+ generator->setStartingNestedLang( options.getStartNestedLang());
+ generator->disableTrailingNL(options.disableTrailingNL());
+
+ bool styleFileWanted = !options.fragmentOutput() || options.styleOutPathDefined();
+
+ if ( !generator->initTheme ( themePath ) )
+ {
+ cerr << "highlight: Could not find style "
+ << themePath
+ << ".\n";
+ return EXIT_FAILURE;
+ }
+
+ if ( options.printOnlyStyle() )
+ {
+ if (!options.formatSupportsExtStyle()){
+ cerr << "highlight: output format supports no external styles.\n";
+ return EXIT_FAILURE;
+ }
+ bool useStdout = options.getStyleOutFilename() =="stdout";
+ string cssOutFile=options.getOutDirectory() + options.getStyleOutFilename();
+ bool success=generator->printExternalStyle ( useStdout?"":cssOutFile );
+ if ( !success )
+ {
+ cerr << "highlight: Could not write " << cssOutFile <<".\n";
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+ }
+
+ bool formattingEnabled = generator->initIndentationScheme ( options.getIndentScheme() );
+
+ if ( !formattingEnabled && !options.getIndentScheme().empty() )
+ {
+ cerr << "highlight: Undefined indentation scheme "
+ << options.getIndentScheme()
+ << ".\n";
+ return EXIT_FAILURE;
+ }
+
+ if ( !options.getTagsFile().empty() )
+ {
+ if ( !generator->initTagInformation ( options.getTagsFile() ) )
+ {
+ cerr << "highlight: Could not load ctags file "
+ << options.getTagsFile()
+ << ".\n";
+ return EXIT_FAILURE;
+ }
+ }
+
+ string outDirectory = options.getOutDirectory();
+#ifndef WIN32
+ ifstream dirTest ( outDirectory.c_str() );
+ if ( !outDirectory.empty() && !options.quietMode() && !dirTest )
+ {
+ cerr << "highlight: Output directory \""
+ << outDirectory
+ << "\" does not exist.\n";
+ return EXIT_FAILURE;
+ }
+ dirTest.close();
+#endif
+
+ map <int,string> markedLines = options.getMarkLines();
+ if ( !markedLines.empty() )
+ {
+ map<int, string>::iterator it;
+ for ( it=markedLines.begin(); it!=markedLines.end();it++ )
+ {
+ generator->addMarkedLine ( it->first, it->second );
+ }
+ }
+
+ bool initError=false, IOError=false;
+ unsigned int fileCount=inFileList.size(),
+ fileCountWidth=getNumDigits ( fileCount ),
+ i=0,
+ numBadFormatting=0,
+ numBadInput=0,
+ numBadOutput=0;
+
+ vector<string> badFormattedFiles, badInputFiles, badOutputFiles;
+ string inFileName, outFilePath;
+ string suffix, lastSuffix;
+
+ if ( options.syntaxGiven() ) // user defined language definition, valid for all files
+ {
+ suffix = guessFileType ( options.getLanguage() );
+ }
+
+ while ( i < fileCount && !initError )
+ {
+ if ( !options.syntaxGiven() ) // determine file type for each file
+ {
+ suffix = guessFileType ( getFileSuffix ( inFileList[i] ), inFileList[i] );
+ }
+ if ( suffix.empty() )
+ {
+ if ( !options.enableBatchMode() )
+ cerr << "highlight: Undefined language definition. Use --"
+ << OPT_SYNTAX << " option.\n";
+ if ( !options.forceOutput() )
+ {
+ initError = true;
+ break;
+ }
+ }
+
+ if ( suffix != lastSuffix )
+ {
+ string langDefPath=dataDir.getLangPath ( suffix+".lang" );
+ highlight::LoadResult loadRes= generator->loadLanguage ( langDefPath );
+ if ( loadRes==highlight::LOAD_FAILED_REGEX )
+ {
+ cerr << "highlight: Regex error ( "
+ << generator->getLanguage().getFailedRegex()
+ << " ) in "<<suffix<<".lang\n";
+ initError = true;
+ break;
+ }
+ else if ( loadRes==highlight::LOAD_FAILED )
+ {
+ // do also ignore error msg if --syntax parameter should be skipped
+ if ( ! (options.quietMode() || options.isSkippedExt ( suffix )) )
+ {
+ cerr << "highlight: Unknown source file extension \""
+ << suffix
+ << "\".\n";
+ }
+ if ( !options.forceOutput() )
+ {
+ initError = true;
+ break;
+ }
+ }
+ if ( options.printDebugInfo() && loadRes==highlight::LOAD_NEW )
+ {
+ printDebugInfo ( generator->getLanguage(), langDefPath );
+ }
+ lastSuffix = suffix;
+ }
+
+ string::size_type pos= ( inFileList[i] ).find_last_of ( Platform::pathSeparator );
+ inFileName = inFileList[i].substr ( pos+1 );
+
+ if ( options.enableBatchMode() )
+ {
+ outFilePath = outDirectory;
+ outFilePath += inFileName;
+ outFilePath += options.getOutFileSuffix();
+
+ if ( !options.quietMode() )
+ {
+ if ( options.printProgress() )
+ {
+ printProgressBar ( fileCount, i+1 );
+ }
+ else
+ {
+ printCurrentAction ( outFilePath, fileCount, i+1, fileCountWidth );
+ }
+ }
+ }
+ else
+ {
+ outFilePath = options.getSingleOutFilename();
+ if ( outFilePath.size() && outFilePath==options.getSingleInFilename() )
+ {
+ cerr << "highlight: Output path equals input path: \""
+ << outFilePath << "\".\n";
+ initError = true;
+ break;
+ }
+
+ }
+
+ if ( options.useFNamesAsAnchors() )
+ {
+ generator->setHTMLAnchorPrefix ( inFileName );
+ }
+
+ generator->setTitle ( options.getDocumentTitle().empty() ?
+ inFileList[i]:options.getDocumentTitle() );
+
+ generator->setKeyWordCase ( options.getKeywordCase() );
+
+ highlight::ParseError error = generator->generateFile ( inFileList[i], outFilePath );
+
+ if ( error==highlight::BAD_INPUT )
+ {
+ if ( numBadInput++ < IO_ERROR_REPORT_LENGTH || options.printDebugInfo() )
+ {
+ badInputFiles.push_back ( inFileList[i] );
+ }
+ }
+ else if ( error==highlight::BAD_OUTPUT )
+ {
+ if ( numBadOutput++ < IO_ERROR_REPORT_LENGTH || options.printDebugInfo() )
+ {
+ badOutputFiles.push_back ( outFilePath );
+ }
+ }
+ if ( formattingEnabled && !generator->formattingIsPossible() )
+ {
+ if ( numBadFormatting++ < IO_ERROR_REPORT_LENGTH || options.printDebugInfo() )
+ {
+ badFormattedFiles.push_back ( outFilePath );
+ }
+ }
+ ++i;
+ }
+
+
+ if ( i && !options.includeStyleDef()
+ && styleFileWanted
+ && options.formatSupportsExtStyle() )
+ {
+ string cssOutFile=outDirectory + options.getStyleOutFilename();
+ bool success=generator->printExternalStyle ( cssOutFile );
+ if ( !success )
+ {
+ cerr << "highlight: Could not write " << cssOutFile <<".\n";
+ IOError = true;
+ }
+ }
+
+ if ( i && options.printIndexFile() )
+ {
+ bool success=generator -> printIndexFile ( inFileList, outDirectory );
+ if ( !success )
+ {
+ cerr << "highlight: Could not write index file.\n";
+ IOError = true;
+ }
+ }
+
+ if ( numBadInput )
+ {
+ printIOErrorReport ( numBadInput, badInputFiles, "read input" );
+ IOError = true;
+ }
+ if ( numBadOutput )
+ {
+ printIOErrorReport ( numBadOutput, badOutputFiles, "write output" );
+ IOError = true;
+ }
+ if ( numBadFormatting )
+ {
+ printIOErrorReport ( numBadFormatting, badFormattedFiles, "reformat" );
+ }
+ return ( initError || IOError ) ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+int main ( const int argc, const char *argv[] )
+{
+ HLCmdLineApp app;
+ return app.run ( argc, argv );
+}
diff --git a/support/highlight/src/cli/main.h b/support/highlight/src/cli/main.h
new file mode 100644
index 0000000000..2839e5c9fd
--- /dev/null
+++ b/support/highlight/src/cli/main.h
@@ -0,0 +1,117 @@
+
+/*
+This file is part of Highlight.
+
+Highlight 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.
+
+Highlight 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 Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef HIGHLIGHT_APP
+#define HIGHLIGHT_APP
+
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+#include <map>
+#include <iomanip>
+#include <cassert>
+
+//#include "./dirstream0.4/dirstream.h"
+#include "cmdlineoptions.h"
+#include "configurationreader.h"
+#include "codegenerator.h"
+#include "help.h"
+#include "datadir.h"
+#include "version.h"
+#include "platform_fs.h"
+
+#define IO_ERROR_REPORT_LENGTH 5
+#define SHEBANG_CNT 12
+
+typedef map<string, string> StringMap;
+
+/// Main application class of the command line interface
+
+class HLCmdLineApp
+{
+
+ public:
+
+ HLCmdLineApp() {};
+ ~HLCmdLineApp() {};
+
+ /** Start application
+ \param argc Number of command line arguments
+ \param argv values of command line arguments
+ \return EXIT_SUCCESS or EXIT_FAILURE
+ */
+ int run ( const int argc, const char *argv[] );
+
+ private:
+
+ DataDir dataDir;
+ StringMap extensions;
+ StringMap scriptShebangs;
+ stringstream cin_bufcopy;
+
+ /** print version info*/
+ void printVersionInfo();
+
+ /** print configuration info*/
+ void printConfigInfo ( const string& );
+
+ /** print error message*/
+ void printBadInstallationInfo();
+
+ /** print input and output errors */
+ void printIOErrorReport ( unsigned int numberErrorFiles, vector<string> & fileList, const string &action );
+
+ /** list installed theme files
+ \return true if theme files were found
+ */
+ bool printInstalledThemes();
+
+ /** list installed language definition files
+ \return true if lang files were found
+ */
+ bool printInstalledLanguages();
+
+ /** print debug information
+ \param lang language definition
+ \param langDefPath path to language definition
+ */
+ void printDebugInfo ( const highlight::LanguageDefinition &lang,
+ const string &langDefPath );
+
+ string getFileSuffix ( const string &fileName );
+
+ string guessFileType ( const string &suffix, const string &inputFile="" );
+
+ int getNumDigits ( int i );
+
+ void printProgressBar ( int total, int count );
+ void printCurrentAction ( const string&outfilePath,
+ int total, int count, int countWidth );
+
+ bool readInputFilePaths ( vector<string> &fileList, string wildcard,
+ bool recursiveSearch );
+
+ string analyzeFile ( const string& file );
+ bool loadFileTypeConfig ( const string& name, StringMap* map, StringMap* shebangMap );
+
+};
+
+#endif