"Fossies" - the Fresh Open Source Software Archive

Member "highlight-3.57-x64/src/cli/cmdlineoptions.cpp" (12 May 2020, 31793 Bytes) of package /windows/www/highlight-3.57-x64.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "cmdlineoptions.cpp": 3.55_vs_3.56.

    1 /***************************************************************************
    2                           cmdlineoptions.cpp  -  description
    3                              -------------------
    4     begin                : Sun Nov 25 2001
    5     copyright            : (C) 2001-2017 by Andre Simon
    6     email                : a.simon@mailbox.org
    7  ***************************************************************************/
    8 
    9 /*
   10 This file is part of Highlight.
   11 
   12 Highlight is free software: you can redistribute it and/or modify
   13 it under the terms of the GNU General Public License as published by
   14 the Free Software Foundation, either version 3 of the License, or
   15 (at your option) any later version.
   16 
   17 Highlight is distributed in the hope that it will be useful,
   18 but WITHOUT ANY WARRANTY; without even the implied warranty of
   19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   20 GNU General Public License for more details.
   21 
   22 You should have received a copy of the GNU General Public License
   23 along with Highlight.  If not, see <http://www.gnu.org/licenses/>.
   24 */
   25 
   26 #include "cmdlineoptions.h"
   27 #include "platform_fs.h"
   28 #include "datadir.h"
   29 #include <sstream>
   30 #include <cstdio>
   31 #include <list>
   32 
   33 #include "arg_parser.h"
   34 
   35 using namespace std;
   36 
   37 enum Optcode {
   38         S_OPT_ENCLOSE_PRE = 256, S_OPT_FORCE_OUTPUT,
   39         S_OPT_INLINE_CSS, S_OPT_KW_CASE,
   40         S_OPT_PRINT_CONFIG, S_OPT_TEST_INPUT, S_OPT_NO_NUMBER_WL,
   41         S_OPT_SVG_WIDTH, S_OPT_SVG_HEIGHT, S_OPT_CLASSNAME,
   42         S_OPT_RTF_CHAR_STYLES, S_OPT_RTF_PAGE_COLOR,
   43         S_OPT_SKIP_UNKNOWN,
   44         S_OPT_COMPAT_DOC, S_OPT_COMPAT_NODOC, S_OPT_COMPAT_TAB, S_OPT_COMPAT_CSS,
   45         S_OPT_COMPAT_OUTDIR, S_OPT_COMPAT_FAILSAFE,
   46         S_OPT_COMPAT_SRCLANG, S_OPT_COMPAT_LINENUM, S_OPT_COMPAT_LINEREF,
   47         S_OPT_PRETTY_SYMBOLS, S_OPT_EOL_DELIM_CR, S_OPT_START_NESTED,
   48         S_OPT_PRINT_STYLE, S_OPT_NO_TRAILING_NL, S_OPT_PLUGIN, S_OPT_ABS_CFG_PATH,
   49         S_OPT_PLUGIN_READFILE, S_OPT_PLUGIN_PARAMETER, S_OPT_LIST_SCRIPTS, S_OPT_CANVAS,
   50         S_OPT_KEEP_INJECTIONS, S_OPT_FORCE_STDOUT, S_OPT_LATEX_BEAMER, S_OPT_NO_VERSION_INFO,
   51         S_OPT_REFORMAT_OPT, S_OPT_RANGE_OPT, S_OPT_BASE16, S_OPT_CATEGORIES, S_OPT_PIPED_FNAME,
   52         S_OPT_ISOLATE, S_OPT_MAX_FILE_SIZE
   53     };
   54 
   55 const Arg_parser::Option options[] = {
   56         { 'a', OPT_ANCHORS,        Arg_parser::no  },
   57         { 'b', OPT_LATEX_BABEL,    Arg_parser::no  },
   58         { 'B', OPT_BATCHREC,       Arg_parser::yes },
   59         { 'c', OPT_STYLE_OUT,      Arg_parser::yes },
   60         { 'C', OPT_INDEXFILE,      Arg_parser::no  },
   61         { 'd', OPT_OUTDIR,         Arg_parser::yes },
   62         { 'D', OPT_DATADIR,        Arg_parser::yes },
   63         { 'e', OPT_STYLE_IN,       Arg_parser::yes },
   64         { 'f', OPT_FRAGMENT,       Arg_parser::no  },
   65         { 'F', OPT_FORMAT,         Arg_parser::yes },
   66 
   67         { 'h', OPT_HELP,           Arg_parser::maybe  },
   68         { 'i', OPT_IN,             Arg_parser::yes },
   69         { 'I', OPT_INC_STYLE,      Arg_parser::no  },
   70         { 'j', OPT_LNR_LEN,        Arg_parser::yes },
   71         { 'J', OPT_LINE_LEN,       Arg_parser::yes },
   72         { 'k', OPT_BASE_FONT,      Arg_parser::yes },
   73         { 'K', OPT_BASE_FONT_SIZE, Arg_parser::yes },
   74         { 'l', OPT_LINENO,         Arg_parser::no  },
   75         { 'm', OPT_LNR_START,      Arg_parser::yes },
   76         { 'n', OPT_ORDERED_LIST,   Arg_parser::no  },
   77         { 'N', OPT_ANCHOR_FN,      Arg_parser::no  },
   78         { 'o', OPT_OUT,            Arg_parser::yes },
   79         { 'O', OPT_OUTFORMAT,      Arg_parser::yes },
   80         { 'P', OPT_PROGRESSBAR,    Arg_parser::no  },
   81         { 'q', OPT_QUIET,          Arg_parser::no  },
   82         { 'Q', OPT_VERSION,        Arg_parser::no  },
   83         { 'r', OPT_REPLACE_QUOTES, Arg_parser::no  },
   84         { 's', OPT_STYLE,          Arg_parser::yes },
   85         { 'S', OPT_SYNTAX,         Arg_parser::yes },
   86         { 't', OPT_DELTABS,        Arg_parser::yes },
   87         { 'T', OPT_DOC_TITLE,      Arg_parser::yes },
   88         { 'u', OPT_ENCODING,       Arg_parser::yes },
   89         { 'v', OPT_VERBOSE,        Arg_parser::no  },
   90         { 'V', OPT_WRAPSIMPLE,     Arg_parser::no  },
   91         { 'W', OPT_WRAP,           Arg_parser::no  },
   92         { 'x', OPT_RTF_PAGE_SIZE,  Arg_parser::yes },
   93         { 'y', OPT_ANCHOR_PFX,     Arg_parser::yes },
   94         { 'z', OPT_FILLZEROES,     Arg_parser::no  },
   95 
   96         { S_OPT_CLASSNAME,        OPT_CLASSNAME,    Arg_parser::yes },
   97         { S_OPT_SVG_WIDTH,        OPT_SVG_WIDTH,    Arg_parser::yes  },
   98         { S_OPT_SVG_HEIGHT,       OPT_SVG_HEIGHT,   Arg_parser::yes  },
   99         { S_OPT_ENCLOSE_PRE,      OPT_ENCLOSE_PRE,  Arg_parser::no  },
  100         { S_OPT_FORCE_OUTPUT,     OPT_FORCE_OUTPUT, Arg_parser::maybe  },
  101         { S_OPT_INLINE_CSS,       OPT_INLINE_CSS,   Arg_parser::no  },
  102         { S_OPT_KW_CASE,          OPT_KW_CASE,      Arg_parser::yes },
  103         { S_OPT_PRINT_CONFIG,     OPT_PRINT_CONFIG, Arg_parser::no  },
  104         { S_OPT_TEST_INPUT,       OPT_TEST_INPUT,   Arg_parser::no  },
  105         { S_OPT_NO_NUMBER_WL,     OPT_NO_NUMBER_WL, Arg_parser::no  },
  106         { S_OPT_RTF_CHAR_STYLES,  OPT_RTF_CHAR_STYLES, Arg_parser::no  },
  107         { S_OPT_RTF_PAGE_COLOR,   OPT_RTF_PAGE_COLOR,  Arg_parser::no  },
  108         { S_OPT_SKIP_UNKNOWN,     OPT_SKIP_UNKNOWN,    Arg_parser::yes },
  109         { S_OPT_START_NESTED,     OPT_START_NESTED,    Arg_parser::yes },
  110         { S_OPT_COMPAT_DOC,       OPT_COMPAT_DOC,      Arg_parser::no },
  111         { S_OPT_COMPAT_NODOC,     OPT_COMPAT_NODOC,    Arg_parser::no },
  112         { S_OPT_COMPAT_TAB,       OPT_COMPAT_TAB,      Arg_parser::yes },
  113         { S_OPT_COMPAT_CSS,       OPT_COMPAT_CSS,      Arg_parser::yes },
  114         { S_OPT_COMPAT_OUTDIR,    OPT_COMPAT_OUTDIR,   Arg_parser::yes },
  115         { S_OPT_COMPAT_FAILSAFE,  OPT_COMPAT_FAILSAFE, Arg_parser::no },
  116         { S_OPT_COMPAT_SRCLANG,   OPT_COMPAT_SRCLANG,  Arg_parser::yes },
  117         { S_OPT_COMPAT_LINENUM,   OPT_COMPAT_LINENUM,  Arg_parser::maybe },
  118         { S_OPT_COMPAT_LINEREF,   OPT_COMPAT_LINEREF,  Arg_parser::maybe },
  119         { S_OPT_PRETTY_SYMBOLS,   OPT_PRETTY_SYMBOLS,  Arg_parser::no },
  120         { S_OPT_EOL_DELIM_CR,     OPT_EOL_DELIM_CR,    Arg_parser::no },
  121         { S_OPT_PRINT_STYLE,      OPT_PRINT_STYLE,     Arg_parser::no },
  122         { S_OPT_BASE16,           OPT_BASE16,          Arg_parser::maybe },
  123         { S_OPT_NO_TRAILING_NL,   OPT_NO_TRAILING_NL,  Arg_parser::maybe },
  124         { S_OPT_KEEP_INJECTIONS,  OPT_KEEP_INJECTIONS, Arg_parser::no },
  125         { S_OPT_FORCE_STDOUT,     OPT_FORCE_STDOUT,    Arg_parser::no },
  126         { S_OPT_LATEX_BEAMER,     OPT_LATEX_BEAMER,    Arg_parser::no },
  127         { S_OPT_NO_VERSION_INFO,  OPT_NO_VERSION_INFO, Arg_parser::no },
  128         
  129         { S_OPT_PLUGIN,           OPT_PLUGIN,          Arg_parser::yes },
  130         { S_OPT_PLUGIN_READFILE,  OPT_PLUGIN_READFILE, Arg_parser::yes },
  131         { S_OPT_PLUGIN_PARAMETER, OPT_PLUGIN_PARAMETER, Arg_parser::yes },
  132         { S_OPT_ABS_CFG_PATH,     OPT_ABS_CFG_PATH,    Arg_parser::yes},
  133         { S_OPT_LIST_SCRIPTS,     OPT_LIST_SCRIPTS,    Arg_parser::yes},
  134         { S_OPT_CANVAS,           OPT_CANVAS,          Arg_parser::maybe },
  135         { S_OPT_REFORMAT_OPT,     OPT_REFORMAT_OPT,    Arg_parser::yes },
  136         { S_OPT_RANGE_OPT,        OPT_RANGE_OPT,       Arg_parser::yes },
  137         { S_OPT_CATEGORIES,       OPT_CATEGORIES,      Arg_parser::yes },
  138         { S_OPT_PIPED_FNAME,      OPT_PIPED_FNAME,     Arg_parser::yes },
  139         { S_OPT_ISOLATE,          OPT_ISOLATE_TAGS,    Arg_parser::no },
  140         { S_OPT_MAX_FILE_SIZE,    OPT_MAX_FILE_SIZE,   Arg_parser::yes },
  141         //{ S_OPT_TWO_PASS,         OPT_TWO_PASS,        Arg_parser::yes },
  142         
  143         { 0, 0, Arg_parser::no }
  144     };
  145 
  146 
  147 
  148 CmdLineOptions::CmdLineOptions ( const int argc, const char *argv[] ) :
  149     numberSpaces ( 0 ),
  150     lineNrWidth ( 5 ),
  151     lineLength ( 80 ),
  152     lineNrStart ( 1 ),
  153     lineRangeStart( 0 ),
  154     lineRangeEnd( 0 ),
  155     opt_no_trailing_nl(0),
  156     canvasPaddingWidth(0),
  157     wrappingStyle ( highlight::WRAP_DISABLED ),
  158     outputType ( highlight::HTML ),
  159     keywordCase ( StringTools::CASE_UNCHANGED ),
  160     baseFontSize("10"),
  161     className ( "hl" ),
  162     opt_syntax ( false ),
  163     opt_include_style ( false ),
  164     opt_help ( false ),
  165     opt_version ( false ),
  166     opt_verbose ( false ),
  167     opt_print_config ( false ),
  168     opt_linenumbers ( false ),
  169     opt_batch_mode ( false ),
  170     opt_fragment ( false ) ,
  171     opt_attach_line_anchors ( false ),
  172     opt_printindex ( false ),
  173     opt_quiet ( false ),
  174     opt_replacequotes ( false ),
  175     opt_babel ( false ),
  176     opt_beamer ( false ),
  177     opt_print_progress ( false ),
  178     opt_fill_zeroes ( false ),
  179     opt_stylepath_explicit ( false ),
  180     opt_force_output ( false ),
  181     opt_ordered_list ( false ),
  182     opt_fnames_as_anchors ( false ),
  183     opt_validate ( false ),
  184     opt_number_wrapped_lines ( true ),
  185     opt_inline_css ( false ),
  186     opt_enclose_pre ( false ),
  187     opt_char_styles ( false ),
  188     opt_page_color(false),
  189     opt_pretty_symbols ( false ),
  190     opt_delim_CR (false),
  191     opt_print_style(false),
  192     opt_base16_theme(false),
  193     opt_keep_injections(false),
  194     opt_force_stdout(false),
  195     opt_no_version_info(false),
  196     explicit_output_format(false),
  197     opt_isolate(false),
  198     opt_encoding_explicit(false),
  199     maxFileSize(268435456),
  200     fallbackSyntax("txt"),
  201     anchorPrefix ( "l" ),
  202     helpLang ( "en" ),
  203     encodingName ( "ISO-8859-1" )
  204 {
  205     
  206     char* hlEnvOptions=getenv("HIGHLIGHT_OPTIONS");
  207     if (hlEnvOptions!=NULL) {
  208         std::ostringstream envos;
  209         envos<<argv[0]<<" "<<hlEnvOptions;
  210         std::istringstream ss( envos.str());
  211         std::string arg;
  212         std::list<std::string> ls;
  213         std::vector<char*> options;
  214         while (ss >> arg)
  215         {
  216             ls.push_back(arg); 
  217             options.push_back(const_cast<char*>(ls.back().c_str()));
  218         }
  219         options.push_back(0); 
  220         parseRuntimeOptions(options.size()-1, (const char**) &options[0], false);
  221     }
  222     
  223     parseRuntimeOptions(argc, argv);
  224     
  225     if ( skipArg.size() && inputFileNames.size() > 1) {
  226         istringstream valueStream;
  227         string elem;
  228         valueStream.str ( StringTools::change_case ( skipArg,StringTools::CASE_LOWER ) );
  229 
  230         while ( getline ( valueStream, elem, ';' ) ) {
  231             ignoredFileTypes.insert ( elem );
  232         }
  233        
  234         vector<string>::iterator file=inputFileNames.begin();
  235         while ( file!=inputFileNames.end()) {
  236             for ( set<string>::iterator ext=ignoredFileTypes.begin(); ext!=ignoredFileTypes.end(); ext++ ) {
  237                 if (file!=inputFileNames.end() && StringTools::endsWith(  *file, *ext )) {
  238                     file = inputFileNames.erase ( file );
  239                     break;
  240                 }
  241             }
  242             if (file!=inputFileNames.end())
  243                 file++;
  244         }
  245     }
  246     
  247     // no batch mode + no explicit format given
  248     if (inputFileNames.size()==1 && !explicit_output_format){
  249         int colorOptions = Platform::isColorEscCapable();
  250         if (colorOptions) {
  251             outputType = colorOptions==2 ? highlight::ESC_TRUECOLOR : highlight::ESC_XTERM256;
  252         }
  253     }
  254 }
  255 
  256 CmdLineOptions::~CmdLineOptions() {}
  257 
  258 void CmdLineOptions::parseRuntimeOptions( const int argc, const char *argv[], bool readInputFilenames) {
  259     
  260 
  261     Arg_parser parser ( argc, argv, options );
  262     if ( parser.error().size() ) { // bad option
  263         cerr << "highlight: "<< parser.error() <<"\n";
  264         cerr << "Try 'highlight --help' for more information.\n";
  265         exit ( EXIT_FAILURE );
  266     }
  267     
  268     int argind = 0;
  269     for ( ; argind < parser.arguments(); ++argind ) {
  270         const int code = parser.code ( argind );
  271         const std::string & arg = parser.argument ( argind );
  272         if ( !code ) break; // no more options
  273         switch ( code ) {
  274         case 'O': {
  275             explicit_output_format=true;
  276             const string tmp = StringTools::change_case ( arg );
  277             if ( tmp == "xhtml" )
  278                 outputType = highlight::XHTML;
  279             else if ( tmp == "tex" )
  280                 outputType = highlight::TEX;
  281             else if ( tmp == "latex" )
  282                 outputType = highlight::LATEX;
  283             else if ( tmp == "rtf" )
  284                 outputType = highlight::RTF;
  285             else if ( tmp == "ansi" || tmp == "esc" ) // gnu source-highlight esc parameter
  286                 outputType = highlight::ESC_ANSI;
  287             else if ( tmp == "xterm256" )
  288                 outputType = highlight::ESC_XTERM256;
  289             else if ( tmp == "truecolor" )
  290                 outputType = highlight::ESC_TRUECOLOR;
  291             else if ( tmp == "svg" )
  292                 outputType = highlight::SVG;
  293             else if ( tmp == "bbcode" )
  294                 outputType = highlight::BBCODE;
  295             else if ( tmp == "pango" )
  296                 outputType = highlight::PANGO;
  297             else if ( tmp == "odt" )
  298                 outputType = highlight::ODTFLAT;
  299             else
  300                 outputType = highlight::HTML;
  301         }
  302         break;
  303         case 'a':
  304             opt_attach_line_anchors = true;
  305             break;
  306         case 'b':
  307             opt_babel=true;
  308             break;
  309         case 'B':
  310             explicit_output_format=true;
  311             opt_batch_mode = true;
  312             readDirectory ( arg );
  313             break;
  314         case 'c':
  315         case S_OPT_COMPAT_CSS:
  316             styleOutFilename = arg;
  317             opt_stylepath_explicit=true;
  318             break;
  319         case 'C':
  320             opt_printindex=true;
  321             break;
  322         case 'T':
  323             docTitle = arg;
  324             break;
  325         case 'D':
  326             dataDir=validateDirPath ( arg );
  327             break;
  328         case 'e':
  329             styleInFilename = arg;
  330             break;
  331         case 'f':
  332         case S_OPT_COMPAT_NODOC:
  333             opt_fragment = true;
  334             break;
  335         case 'F':
  336             indentScheme = arg;
  337             break;
  338         case S_OPT_CLASSNAME:
  339             className = arg;
  340             break;
  341         case 'h':
  342             opt_help = true;
  343             helpTopic = arg;
  344             break;
  345         case 'i':
  346             inputFileNames.push_back ( arg );
  347             break;
  348         case 'I':
  349             opt_include_style = true;
  350             break;
  351         case 'j':
  352             StringTools::str2num<int> ( lineNrWidth, arg, std::dec );
  353             break;
  354         case 'J':
  355             StringTools::str2num<int> ( lineLength, arg, std::dec );
  356             break;
  357         case 'k':
  358             baseFont = arg;
  359             break;
  360         case 'K':
  361             baseFontSize = arg;
  362             break;
  363         case S_OPT_COMPAT_LINENUM:
  364             if ( arg=="0" ) opt_fill_zeroes=true;
  365             /* Falls through */
  366         case 'l':
  367             opt_linenumbers = true;
  368             break;
  369         case 'm':
  370             StringTools::str2num<int> ( lineNrStart, arg, std::dec );
  371             break;
  372         case 'M':
  373             explicit_output_format=true;
  374             outputType=highlight::ESC_XTERM256;
  375             break;
  376         case 'n':
  377             opt_ordered_list = opt_linenumbers = true;
  378             break;
  379         case 'N':
  380             opt_fnames_as_anchors=true;
  381             break;
  382         case 'o':
  383             explicit_output_format=true;
  384             outFilename = arg;
  385             break;
  386         case 'd':
  387         case S_OPT_COMPAT_OUTDIR:
  388             explicit_output_format=true;
  389             outDirectory = validateDirPath ( arg );
  390             break;
  391         case 'P':
  392             opt_print_progress=true;
  393             break;
  394         case 'q':
  395             opt_quiet = true;
  396             break;
  397         case 'Q':
  398             opt_version = true;
  399             break;
  400         case 'r':
  401             opt_replacequotes=true;
  402             break;
  403         case 's':
  404             styleName = arg;
  405             if (Platform::fileExists(styleName)){
  406                 absThemePath = styleName; 
  407             }
  408             break;
  409         case 'S':
  410         case S_OPT_COMPAT_SRCLANG:
  411             syntax = arg;
  412             opt_syntax = true;
  413             
  414             if (Platform::fileExists(arg) && string::npos!=arg.find_last_of('.')){
  415                 absLangPath = arg;
  416                 syntax = arg.substr(0, arg.find_last_of('.'));
  417             }
  418             break;
  419         case 't':
  420         case S_OPT_COMPAT_TAB:
  421             StringTools::str2num<int> ( numberSpaces, arg, std::dec );
  422             break;
  423         case 'u':
  424             encodingName = arg;
  425             opt_encoding_explicit=true;
  426             break;
  427         case 'v':
  428             opt_verbose = true;
  429             break;
  430         case 'V':
  431             wrappingStyle = highlight::WRAP_SIMPLE;
  432             break;
  433         case 'W':
  434             wrappingStyle = highlight::WRAP_DEFAULT;
  435             break;
  436         case 'x':
  437             pageSize = arg;
  438             break;
  439         case 'y':
  440             anchorPrefix = arg;
  441             break;
  442         case 'z':
  443             opt_fill_zeroes=true;
  444             break;
  445         case S_OPT_SVG_WIDTH:
  446             svg_width = arg;
  447             break;
  448         case S_OPT_SVG_HEIGHT:
  449             svg_height = arg;
  450             break;
  451         case S_OPT_ENCLOSE_PRE:
  452             opt_enclose_pre=true;
  453             break;
  454         case S_OPT_FORCE_OUTPUT:
  455         case S_OPT_COMPAT_FAILSAFE:
  456             opt_force_output = true;
  457             if  ( !arg.empty() ) {
  458                 fallbackSyntax=arg;
  459             } 
  460             break;
  461         case S_OPT_INLINE_CSS:
  462             opt_inline_css=true;
  463             break;
  464         case S_OPT_KW_CASE: {
  465             const string tmp = StringTools::change_case ( arg );
  466             if ( tmp == "upper" )
  467                 keywordCase = StringTools::CASE_UPPER;
  468             else if ( tmp == "lower" )
  469                 keywordCase = StringTools::CASE_LOWER;
  470             else if ( tmp == "capitalize" )
  471                 keywordCase = StringTools::CASE_CAPITALIZE;
  472         }
  473         break;
  474         case S_OPT_PRINT_CONFIG:
  475             opt_print_config = true;
  476             break;
  477         case S_OPT_TEST_INPUT:
  478             opt_validate=true;
  479             break;
  480         case S_OPT_NO_NUMBER_WL:
  481             opt_number_wrapped_lines=false;
  482             break;
  483         case S_OPT_RTF_CHAR_STYLES:
  484             opt_char_styles=true;
  485             break;
  486         case S_OPT_RTF_PAGE_COLOR:
  487              opt_page_color=true;
  488             break;
  489         case S_OPT_SKIP_UNKNOWN:
  490             skipArg=arg;
  491             break;
  492         case S_OPT_PLUGIN:
  493             userPlugins.push_back(arg);
  494             break;
  495         case S_OPT_REFORMAT_OPT:
  496             astyleOptions.push_back(arg);
  497             break;
  498         case S_OPT_PLUGIN_PARAMETER:
  499         case S_OPT_PLUGIN_READFILE:
  500             pluginParameter=arg;
  501             break;
  502 
  503         case S_OPT_PRETTY_SYMBOLS:
  504             opt_pretty_symbols = true;
  505             break;
  506         case S_OPT_LATEX_BEAMER:
  507             opt_beamer = true;
  508             break;
  509         case S_OPT_NO_VERSION_INFO:
  510             opt_no_version_info = true;
  511             break;
  512         case S_OPT_COMPAT_DOC:
  513             opt_fragment = false;
  514             break;
  515         case S_OPT_COMPAT_LINEREF:
  516             opt_linenumbers = true;
  517             opt_attach_line_anchors = true;
  518             anchorPrefix = ( arg.empty() ) ? "line" : arg;
  519             break;
  520         case S_OPT_EOL_DELIM_CR:
  521             opt_delim_CR = true;
  522             break;
  523         case S_OPT_START_NESTED:
  524             startNestedLang=arg;
  525             break;
  526         case S_OPT_PRINT_STYLE:
  527             opt_print_style = true;
  528             break;
  529         case S_OPT_BASE16:
  530             opt_base16_theme = true;
  531             if (!arg.empty())
  532                 styleName = arg;
  533             break;
  534         case S_OPT_NO_TRAILING_NL:
  535             opt_no_trailing_nl = 1;
  536             if (arg=="empty-file" || arg=="blank")
  537                 opt_no_trailing_nl = 2;
  538             break;
  539         case S_OPT_KEEP_INJECTIONS:
  540             opt_keep_injections = true;
  541             break;
  542         case S_OPT_FORCE_STDOUT:
  543             opt_force_stdout = true;
  544             break;
  545         case S_OPT_ABS_CFG_PATH:
  546             if (arg.find(".lang")!=string::npos) {
  547                 absLangPath=arg;
  548                 syntax = arg.substr(0, arg.find_last_of('.'));
  549                 opt_syntax = true;
  550             } else if (arg.find(".theme")!=string::npos) absThemePath=arg;
  551             else cerr << "highlight: unknown config file type" << endl;
  552             break;
  553         
  554         case S_OPT_RANGE_OPT: {
  555             size_t delimPos=arg.find("-");
  556             if (delimPos!=string::npos) {
  557                 StringTools::str2num<int> ( lineRangeStart, arg.substr(0, delimPos), std::dec );
  558                 StringTools::str2num<int> ( lineRangeEnd, arg.substr(delimPos+1), std::dec );
  559                 lineRangeEnd = lineRangeEnd - lineRangeStart + 1;
  560                 if (lineRangeEnd<=0 || lineRangeStart <=0) {
  561                     lineRangeStart = lineRangeEnd = 0;
  562                 }
  563             }
  564             break;
  565         }
  566         case S_OPT_LIST_SCRIPTS:
  567             listScriptType=arg;
  568             break;
  569         case S_OPT_CANVAS:
  570             canvasPaddingWidth=80;
  571             numberSpaces=4; // get around problem with maskWs and tab output
  572             if  ( !arg.empty() ) 
  573                 StringTools::str2num<unsigned int> ( canvasPaddingWidth, arg, std::dec );
  574             break;
  575             
  576         case S_OPT_CATEGORIES:
  577             listScriptCategory=arg;
  578             if (listScriptType.empty()) listScriptType = "langs";
  579             break;
  580         case S_OPT_PIPED_FNAME:
  581             redirectedFilename=arg;
  582             opt_syntax=true;
  583             break;
  584         case S_OPT_ISOLATE:
  585             opt_isolate=true;
  586             break;
  587         case S_OPT_MAX_FILE_SIZE: {
  588             StringTools::str2num<off_t> ( maxFileSize, arg, std::dec );
  589             switch (arg[arg.size()-1]) {
  590                 case 'G': maxFileSize *= 1024;
  591                 case 'M': maxFileSize *= 1024;
  592                 case 'K': maxFileSize *= 1024;
  593             }
  594             break;
  595         }
  596         
  597         default:
  598             cerr << "highlight: option parsing failed" << endl;
  599         }
  600     }
  601 
  602     if (readInputFilenames) {
  603         if ( argind < parser.arguments() ) { //still args left
  604             if ( inputFileNames.empty() ) {
  605                 string fName;
  606                 while ( argind < parser.arguments() ) {
  607                     fName=parser.argument ( argind++ );
  608                     if (fName=="-") fName = ""; // handle single "-" as empty arg to trigger reading from stdin
  609                     inputFileNames.push_back ( fName );
  610                 }
  611             }
  612         } else if ( inputFileNames.empty() ) {
  613             inputFileNames.push_back ( "" );
  614         }
  615     }
  616 }
  617 
  618 const string &CmdLineOptions::getSingleOutFilename()
  619 {
  620     if ( !inputFileNames.empty() && !outDirectory.empty() ) {
  621         if ( outFilename.empty() ) {
  622             outFilename = outDirectory;
  623             int delim = getSingleInFilename().find_last_of ( Platform::pathSeparator ) +1;
  624             outFilename += getSingleInFilename().substr ( ( delim>-1 ) ?delim:0 )
  625                            + getOutFileSuffix();
  626         }
  627     }
  628     return outFilename;
  629 }
  630 
  631 const string &CmdLineOptions::getSingleInFilename()  const
  632 {
  633     return inputFileNames[0];
  634 }
  635 
  636 const string &CmdLineOptions::getOutDirectory()
  637 {
  638     if ( !outFilename.empty() && !enableBatchMode() ) {
  639         outDirectory=getDirName ( outFilename );
  640     }
  641     return outDirectory;
  642 }
  643 
  644 const string CmdLineOptions::getStyleOutFilename() const
  645 {
  646     if ( !styleOutFilename.empty() ) return styleOutFilename;
  647 
  648     if ( outputType==highlight::TEX || outputType==highlight::LATEX ) {
  649         return "highlight.sty";
  650     } else {
  651         return "highlight.css";
  652     }
  653 }
  654 const string &CmdLineOptions::getStyleInFilename() const
  655 {
  656     return styleInFilename;
  657 }
  658 const string& CmdLineOptions::getSVGWidth() const
  659 {
  660     return svg_width;
  661 }
  662 const string& CmdLineOptions::getSVGHeight() const
  663 {
  664     return svg_height;
  665 }
  666 int CmdLineOptions::getNumberSpaces() const
  667 {
  668     return numberSpaces;
  669 }
  670 bool CmdLineOptions::printVersion() const
  671 {
  672     return opt_version;
  673 }
  674 bool CmdLineOptions::printHelp() const
  675 {
  676     return opt_help;
  677 }
  678 bool CmdLineOptions::printDebugInfo() const
  679 {
  680     return opt_verbose;
  681 }
  682 bool CmdLineOptions::printConfigInfo() const
  683 {
  684     return opt_print_config;
  685 }
  686 bool CmdLineOptions::quietMode() const
  687 {
  688     return opt_quiet;
  689 }
  690 bool CmdLineOptions::includeStyleDef() const
  691 {
  692     return opt_include_style;
  693 }
  694 bool CmdLineOptions::useFNamesAsAnchors() const
  695 {
  696     return opt_fnames_as_anchors;
  697 }
  698 
  699 bool CmdLineOptions::formatSupportsExtStyle()
  700 {
  701     return outputType==highlight::HTML ||
  702            outputType==highlight::XHTML ||
  703            outputType==highlight::LATEX ||
  704            outputType==highlight::TEX ||
  705            outputType==highlight::SVG;
  706 }
  707 
  708 bool CmdLineOptions::printLineNumbers() const
  709 {
  710     return opt_linenumbers;
  711 }
  712 
  713 string CmdLineOptions::getThemeName() const
  714 {
  715     if (!styleName.empty())
  716         return styleName+".theme";
  717     
  718     bool isEscOutput = outputType==highlight::ESC_XTERM256 || outputType==highlight::ESC_TRUECOLOR;
  719     if (opt_base16_theme)
  720         return isEscOutput ? "harmonic-dark.theme" : "harmonic-light.theme";
  721     
  722     return isEscOutput ? "edit-vim-dark.theme" : "edit-kwrite.theme";
  723 }
  724 
  725 bool CmdLineOptions::enableBatchMode() const
  726 {
  727     return inputFileNames.size() >1 || opt_batch_mode;
  728 }
  729 
  730 bool CmdLineOptions::fragmentOutput() const
  731 {
  732     return opt_fragment;
  733 }
  734 
  735 bool CmdLineOptions::omitVersionInfo() const {
  736     return opt_no_version_info;    
  737 }
  738 
  739 bool CmdLineOptions::isolateTags() const
  740 {
  741     return opt_isolate;
  742 }
  743 
  744 string CmdLineOptions::getOutFileSuffix() const
  745 {
  746     switch ( outputType ) {
  747     case highlight::XHTML:
  748         return ".xhtml";
  749     case highlight::RTF:
  750         return ".rtf";
  751     case highlight::TEX:
  752     case highlight::LATEX:
  753         return ".tex";
  754     case highlight::SVG:
  755         return ".svg";
  756     case highlight::ESC_ANSI:
  757         return ".ansi";
  758     case highlight::ESC_XTERM256:
  759     case highlight::ESC_TRUECOLOR:
  760         return ".xterm";
  761     case highlight::BBCODE:
  762         return ".bbcode";
  763     case highlight::ODTFLAT:
  764         return ".fodt";
  765     default:
  766         return ".html";
  767     }
  768 }
  769 string CmdLineOptions::getDirName ( const string & path )
  770 {
  771     size_t dirNameLength=path.rfind ( Platform::pathSeparator );
  772     return ( dirNameLength==string::npos ) ?string() :path.substr ( 0, dirNameLength+1 );
  773 }
  774 bool CmdLineOptions::attachLineAnchors() const
  775 {
  776     return opt_attach_line_anchors;
  777 }
  778 bool CmdLineOptions::outDirGiven() const
  779 {
  780     return !outFilename.empty();
  781 }
  782 bool CmdLineOptions::replaceQuotes() const
  783 {
  784     return opt_replacequotes;
  785 }
  786 bool CmdLineOptions::disableBabelShorthands() const
  787 {
  788     return opt_babel;
  789 }
  790 bool CmdLineOptions::enableBeamerMode() const
  791 {
  792     return opt_beamer;
  793 }
  794 bool CmdLineOptions::prettySymbols() const
  795 {
  796     return opt_pretty_symbols;
  797 }
  798 bool CmdLineOptions::orderedList() const
  799 {
  800     return opt_ordered_list;
  801 }
  802 bool CmdLineOptions::useCRDelimiter() const
  803 {
  804     return opt_delim_CR;
  805 }
  806 const string &CmdLineOptions::getDataDir() const
  807 {
  808     return dataDir;
  809 }
  810 const vector<string> &CmdLineOptions::getPluginPaths() const
  811 {
  812     return userPlugins;
  813 }
  814 const vector<string> &CmdLineOptions::getAStyleOptions() const
  815 {
  816     return astyleOptions;
  817 }
  818 bool CmdLineOptions::printOnlyStyle() const
  819 {
  820     return opt_print_style;
  821 }
  822 bool CmdLineOptions::useBase16Theme() const
  823 {
  824     return opt_base16_theme;
  825 }
  826 off_t CmdLineOptions::getMaxFileSize() const
  827 {
  828     return maxFileSize;
  829 }
  830 
  831 string CmdLineOptions::getIndentScheme() const
  832 {
  833     return StringTools::change_case ( indentScheme );
  834 }
  835 
  836 const string &CmdLineOptions::getSyntax() const
  837 {
  838     return syntax;
  839 }
  840 const string&CmdLineOptions::getEncoding() const
  841 {
  842     return encodingName;
  843 }
  844 
  845 const string& CmdLineOptions::getAnchorPrefix() const
  846 {
  847     return anchorPrefix;
  848 }
  849 
  850 const string &CmdLineOptions::getPageSize() const
  851 {
  852     return pageSize;
  853 }
  854 
  855 bool CmdLineOptions::printIndexFile() const
  856 {
  857     return opt_printindex && ( outputType==highlight::HTML ||
  858                                outputType==highlight::XHTML );
  859 }
  860 bool CmdLineOptions::printProgress() const
  861 {
  862     return opt_print_progress;
  863 }
  864 bool CmdLineOptions::fillLineNrZeroes() const
  865 {
  866     return opt_fill_zeroes;
  867 }
  868 bool CmdLineOptions::syntaxGiven() const
  869 {
  870     return opt_syntax;
  871 }
  872 bool CmdLineOptions::omitEncoding() const
  873 {
  874     return StringTools::change_case ( encodingName ) =="none";
  875 }
  876 bool CmdLineOptions::forceOutput() const
  877 {
  878     return opt_force_output;
  879 }
  880 bool CmdLineOptions::validateInput() const
  881 {
  882     return opt_validate;
  883 }
  884 bool CmdLineOptions::numberWrappedLines() const
  885 {
  886     return opt_number_wrapped_lines;
  887 }
  888 bool CmdLineOptions::inlineCSS() const
  889 {
  890     return opt_inline_css;
  891 }
  892 bool CmdLineOptions::enclosePreTag() const
  893 {
  894     return opt_enclose_pre;
  895 }
  896 bool CmdLineOptions::includeCharStyles() const
  897 {
  898     return opt_char_styles;
  899 }
  900 bool CmdLineOptions::includePageColor() const
  901 {
  902   return opt_page_color;
  903 }
  904 int CmdLineOptions::disableTrailingNL() const
  905 {
  906     return opt_no_trailing_nl;
  907 }
  908 bool CmdLineOptions::keepInjections() const
  909 {
  910   return opt_keep_injections;
  911 }
  912 bool CmdLineOptions::forceStdout() const
  913 {
  914   return opt_force_stdout;
  915 }
  916 const string& CmdLineOptions::getDocumentTitle() const
  917 {
  918     return docTitle;
  919 }
  920 highlight::WrapMode CmdLineOptions::getWrappingStyle() const
  921 {
  922     return wrappingStyle;
  923 }
  924 const vector <string> & CmdLineOptions::getInputFileNames() const
  925 {
  926     return inputFileNames;
  927 }
  928 
  929 void CmdLineOptions::readDirectory ( const string & wildcard )
  930 {
  931     // get matching files, use  recursive search
  932     bool directoryOK=Platform::getDirectoryEntries ( inputFileNames, wildcard, true );
  933     if ( !directoryOK ) {
  934         cerr << "highlight: No files matched the pattern \""
  935              << wildcard << "\"."<< endl;
  936     }
  937 }
  938 
  939 string CmdLineOptions::validateDirPath ( const string & path )
  940 {
  941     return ( path[path.length()-1] !=Platform::pathSeparator ) ?
  942            path+Platform::pathSeparator : path;
  943 }
  944 
  945 highlight::OutputType CmdLineOptions::getOutputType() const
  946 {
  947     return outputType;
  948 }
  949 
  950 StringTools::KeywordCase CmdLineOptions::getKeywordCase() const
  951 {
  952     return keywordCase;
  953 }
  954 
  955 bool CmdLineOptions::hasBaseFont() const
  956 {
  957     return ( ! baseFont.empty() ) ;
  958 }
  959 
  960 const string& CmdLineOptions::getBaseFont() const
  961 {
  962     return baseFont ;
  963 }
  964 
  965 const string& CmdLineOptions::getBaseFontSize() const
  966 {
  967     return baseFontSize ;
  968 }
  969 
  970 const string& CmdLineOptions::getClassName() const
  971 {
  972     return className ;
  973 }
  974 
  975 const string& CmdLineOptions::getStartNestedLang() const
  976 {
  977     return startNestedLang;
  978 }
  979 const string& CmdLineOptions::getAbsThemePath() const
  980 {
  981     return absThemePath;
  982 }
  983 
  984 const string& CmdLineOptions::getAbsLangPath() const
  985 {
  986     return absLangPath;
  987 }
  988 const string& CmdLineOptions::getPluginParameter() const
  989 {
  990     return pluginParameter;
  991 }
  992 int CmdLineOptions::getNumberWidth()
  993 {
  994     return lineNrWidth;
  995 }
  996 
  997 int CmdLineOptions::getLineLength()
  998 {
  999     return lineLength;
 1000 }
 1001 
 1002 int CmdLineOptions::getNumberStart()
 1003 {
 1004     return lineNrStart;
 1005 }
 1006 
 1007 int CmdLineOptions::getCanvasPadding()
 1008 {
 1009     return canvasPaddingWidth;
 1010 }
 1011 
 1012 int CmdLineOptions::getLineRangeStart()
 1013 {
 1014     return lineRangeStart;
 1015 }
 1016 
 1017 int CmdLineOptions::getLineRangeEnd()
 1018 {
 1019     return lineRangeEnd;
 1020 }
 1021 
 1022 const string& CmdLineOptions::getCategories() const {
 1023     return listScriptCategory;
 1024 }
 1025 
 1026 const string& CmdLineOptions::getHelpTopic() const {
 1027     return helpTopic;
 1028 }
 1029 
 1030 const string& CmdLineOptions::getSyntaxByFilename() const {
 1031     return redirectedFilename;
 1032 }
 1033 
 1034 const string& CmdLineOptions::getListScriptKind() const{
 1035     return listScriptType;
 1036 }
 1037 
 1038 const string& CmdLineOptions::getFallbackSyntax() const {
 1039     return fallbackSyntax;
 1040 }
 1041