1 /***************************************************************************
2                           cmdlineoptions.h  -  description
3                              -------------------
4     begin                : Sun Nov 25 2001
5     copyright            : (C) 2001-2021 by Andre Simon
6     email                : a.simon@mailbox.org
7  ***************************************************************************/
8 
9 
10 /*
11 This file is part of Highlight.
12 
13 Highlight is free software: you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17 
18 Highlight is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22 
23 You should have received a copy of the GNU General Public License
24 along with Highlight.  If not, see <http://www.gnu.org/licenses/>.
25 */
26 
27 
28 #ifndef CMDLINEOPTIONS_H
29 #define CMDLINEOPTIONS_H
30 
31 #ifdef _WIN32
32 #include <windows.h>
33 #endif
34 
35 #include <string>
36 #include <map>
37 #include <set>
38 #include <cstdlib>
39 #include <iostream>
40 #include <fstream>
41 #include <vector>
42 
43 #include "stringtools.h"
44 #include "enums.h"
45 
46 #define OPT_OUTFORMAT      "out-format"
47 #define OPT_ANCHORS        "anchors"
48 #define OPT_ANCHOR_FN      "anchor-filename"
49 #define OPT_ANCHOR_PFX     "anchor-prefix"
50 #define OPT_LATEX_BABEL    "babel"
51 #define OPT_LATEX_BEAMER   "beamer"
52 #define OPT_BASE_FONT      "font"
53 #define OPT_BASE_FONT_SIZE "font-size"
54 #define OPT_BATCHREC       "batch-recursive"
55 #define OPT_CLASSNAME      "class-name"
56 #define OPT_DATADIR        "data-dir"
57 #define OPT_DELTABS        "replace-tabs"
58 #define OPT_DOC_TITLE      "doc-title"
59 #define OPT_ENCLOSE_PRE    "enclose-pre"
60 #define OPT_ENCODING       "encoding"
61 #define OPT_FILLZEROES     "zeroes"
62 #define OPT_FORCE_OUTPUT   "force"
63 #define OPT_FORMAT         "reformat"
64 #define OPT_FRAGMENT       "fragment"
65 #define OPT_HELP           "help"
66 #define OPT_IN             "input"
67 #define OPT_INC_STYLE      "include-style"
68 #define OPT_INDEXFILE      "print-index"
69 #define OPT_INLINE_CSS     "inline-css"
70 #define OPT_KW_CASE        "kw-case"
71 #define OPT_LINENO         "line-numbers"
72 #define OPT_LINE_LEN       "line-length"
73 #define OPT_LIST_SCRIPTS   "list-scripts"
74 #define OPT_LNR_LEN        "line-number-length"
75 #define OPT_LNR_START      "line-number-start"
76 #define OPT_ORDERED_LIST   "ordered-list"
77 #define OPT_OUT            "output"
78 #define OPT_OUTDIR         "outdir"
79 #define OPT_RTF_PAGE_SIZE  "page-size"
80 #define OPT_RTF_CHAR_STYLES "char-styles"
81 #define OPT_RTF_PAGE_COLOR "page-color"
82 #define OPT_PRINT_CONFIG   "print-config"
83 #define OPT_PROGRESSBAR    "progress"
84 #define OPT_QUIET          "quiet"
85 #define OPT_REPLACE_QUOTES "replace-quotes"
86 #define OPT_STYLE          "style"
87 #define OPT_STYLE_IN       "style-infile"
88 #define OPT_STYLE_OUT      "style-outfile"
89 #define OPT_SYNTAX         "syntax"
90 #define OPT_TEST_INPUT     "validate-input"
91 #define OPT_VERBOSE        "verbose"
92 #define OPT_VERSION        "version"
93 #define OPT_WRAP           "wrap"
94 #define OPT_WRAPSIMPLE     "wrap-simple"
95 #define OPT_SVG_WIDTH      "width"
96 #define OPT_SVG_HEIGHT     "height"
97 #define OPT_SKIP_UNKNOWN   "skip"
98 #define OPT_PRETTY_SYMBOLS "pretty-symbols"
99 #define OPT_EOL_DELIM_CR   "delim-cr"
100 #define OPT_START_NESTED   "start-nested"
101 #define OPT_PRINT_STYLE    "print-style"
102 #define OPT_NO_TRAILING_NL "no-trailing-nl"
103 #define OPT_PLUGIN         "plug-in"
104 #define OPT_ABS_CFG_PATH   "config-file"
105 #define OPT_PLUGIN_READFILE  "plug-in-read"
106 #define OPT_PLUGIN_PARAMETER "plug-in-param"
107 #define OPT_NO_NUMBER_WL     "wrap-no-numbers"
108 #define OPT_KEEP_INJECTIONS  "keep-injections"
109 #define OPT_FORCE_STDOUT     "stdout"
110 #define OPT_NO_VERSION_INFO  "no-version-info"
111 #define OPT_CANVAS           "canvas"
112 #define OPT_REFORMAT_OPT     "reformat-option"
113 #define OPT_RANGE_OPT        "line-range"
114 #define OPT_BASE16           "base16"
115 #define OPT_CATEGORIES       "list-cat"
116 #define OPT_PIPED_FNAME      "syntax-by-name"
117 #define OPT_ISOLATE_TAGS     "isolate"
118 #define OPT_MAX_FILE_SIZE    "max-size"
119 #define OPT_SYNTAX_SUPPORTED "syntax-supported"
120 
121 // Improve CLI option compatibility with GNU source-highlight
122 #define OPT_COMPAT_DOC       "doc"
123 #define OPT_COMPAT_NODOC     "no-doc"
124 #define OPT_COMPAT_TAB       "tab"
125 #define OPT_COMPAT_CSS       "css"
126 #define OPT_COMPAT_OUTDIR    "output-dir"
127 #define OPT_COMPAT_FAILSAFE  "failsafe"
128 #define OPT_COMPAT_SRCLANG   "src-lang"
129 #define OPT_COMPAT_LINENUM   "line-number"
130 #define OPT_COMPAT_LINEREF   "line-number-ref"
131 
132 #define OPT_LS_PROFILE       "ls-profile"
133 #define OPT_LS_WORKSPACE     "ls-workspace"
134 #define OPT_LS_EXEC          "ls-exec"
135 #define OPT_LS_OPTION        "ls-option"
136 #define OPT_LS_HOVER         "ls-hover"
137 #define OPT_LS_SEMANTIC      "ls-semantic"
138 #define OPT_LS_RAINBOW       "ls-rainbow"
139 #define OPT_LS_SYNTAX        "ls-syntax"
140 #define OPT_LS_DELAY         "ls-delay"
141 #define OPT_LS_SYNTAX_ERROR  "ls-syntax-error"
142 
143 /// handle command line options
144 
145 class CmdLineOptions
146 {
147 public:
148 
149     /**Constructor
150      \param argc Argument count
151      \param argv Argument strings
152     */
153     CmdLineOptions ( const int argc, const char *argv[] );
154     ~CmdLineOptions();
155 
156     /** \return Single output file name*/
157     const std::string &getSingleOutFilename();
158 
159     /** \return Single input file name*/
160     const std::string &getSingleInFilename() const;
161 
162     /** \return Output directory*/
163     const std::string& getOutDirectory() ;
164 
165     /** \return Style output file name*/
166     const std::string getStyleOutFilename() const;
167 
168     /** \return Style input file name*/
169     const std::string& getStyleInFilename() const;
170 
171     /** \return Char set*/
172     const std::string& getEncoding() const;
173 
174     /** \return SVG width*/
175     const std::string& getSVGWidth() const;
176 
177     /** \return SVG height*/
178     const std::string& getSVGHeight() const;
179 
180     /** \return Number of spaces to replace a tab*/
181     int getNumberSpaces() const;
182 
183     /** \return True if version information should be printed*/
184     bool printVersion() const;
185 
186     /** \return True if help information should be printed*/
187     bool printHelp() const;
188 
189     /** \return verbosity level */
190     int verbosityLevel() const;
191 
192     /** \return True if configuration information should be printed*/
193     bool printConfigInfo() const;
194 
195     /** \return True if Style definition should be included in output*/
196     bool includeStyleDef() const;
197 
198     /** \return True if line numbers should be printed*/
199     bool printLineNumbers() const;
200 
201     /** \return True if CR is eol delimiter */
202     bool useCRDelimiter() const;
203 
204     /** \return colour theme name */
205     std::string getThemeName() const ;
206 
207     /** gibt true zurck, falls deutsche Hilfe ausgegeben werden soll */
208     int helpLanguage() const;
209 
210     /** \return True if batch mode is active*/
211     bool enableBatchMode() const;
212 
213     /** \return True if output shluld be fragmented*/
214     bool fragmentOutput() const;
215 
216     /** \return output file suffix */
217     std::string getOutFileSuffix() const;
218 
219     /** \return True if anchors should be attached to line numbers*/
220     bool attachLineAnchors() const;
221 
222     /** \return True if loutput directory is given*/
223     bool outDirGiven() const;
224 
225     /** \return True if a new data directory is given*/
226     bool dataDirGiven() const;
227 
228     /** \return True if index file should be printed*/
229     bool printIndexFile() const;
230 
231     /** \return True if quotes should be replaced by /dq in LaTeX*/
232     bool replaceQuotes() const;
233 
234     /** \return True if shorthands of LaTeX Babel package should be disabled*/
235     bool disableBabelShorthands() const;
236 
237     /** \return True if support for the Beamer package should be enabled*/
238     bool enableBeamerMode() const;
239 
240     /** \return True if input file name should be used as anchor name */
241     bool useFNamesAsAnchors() const;
242 
243     /** \return Data directory*/
244     const std::string &getDataDir() const;
245 
246     /** \return True if language syntax is given*/
247     bool syntaxGiven() const;
248 
249     /** \return True if quiet mode is active*/
250     bool quietMode() const;
251 
252     /** \return True if progress bar should be printed in batch mode */
253     bool printProgress() const;
254 
255     /** \return True if line numbers are filled with leading zeroes */
256     bool fillLineNrZeroes() const;
257 
258     /** \return True if plug-in injections are outputted despite of --fragment */
259     bool keepInjections() const;
260 
261     /** \return True if files should be sent to stdout in batch mode */
262     bool forceStdout() const;
263 
264      /** \return True if output should not contain version info comment */
265     bool omitVersionInfo() const;
266 
267     /** \return programming syntax */
268     const std::string &getSyntax() const ;
269 
270     /** \return Wrapping style*/
271     highlight::WrapMode getWrappingStyle() const;
272 
273     /** \return List of input file names*/
274     const std::vector <std::string> & getInputFileNames() const;
275 
276     /** \return indentation and reformatting scheme*/
277     std::string getIndentScheme() const;
278 
279     /** \return RTF page size */
280     const std::string &getPageSize() const;
281 
282     /** \return Output file format */
283     highlight::OutputType getOutputType() const;
284 
285     /** \return True if chosen output format supports referenced style files */
286     bool formatSupportsExtStyle();
287 
288     /** \return True if style output path was defined by user*/
styleOutPathDefined()289     bool styleOutPathDefined() const
290     {
291         return opt_stylepath_explicit;
292     }
293 
294     /** \return True if encoding specification should be omitted in output*/
295     bool omitEncoding() const;
296 
297      /** \return True if encoding was set by user*/
encodingDefined()298     bool encodingDefined() const
299         {
300         return opt_encoding_explicit;
301     }
302 
303     /** \return True if style was defined by user*/
styleDefined()304     bool styleDefined() const
305     {
306         return !styleName.empty();
307     }
308 
309     /** \return True if output should be generated if language type is unknown*/
310     bool forceOutput() const;
311 
312     /** \return True if line numbers should be replaced by ordered list (HTML) */
313     bool orderedList() const;
314 
315     /** \return True if a base font has been given */
316     bool hasBaseFont() const ;
317 
318     /** \return True if input should be validated */
319     bool validateInput() const ;
320 
321     /** \return True if wrapped lines should get unique numbers */
322     bool numberWrappedLines() const ;
323 
324     /** \return True if CSS should be outputted within tag elements */
325     bool inlineCSS() const ;
326 
327     /** \return True if fragmented html output should be enclosed with pre tags */
328     bool enclosePreTag() const ;
329 
330     /** \return True if RTF output should include character styles */
331     bool includeCharStyles() const ;
332 
333     /** \return True if RTF output should include page color */
334     bool includePageColor() const ;
335 
336     /** \return True if LaTeX output should include fancier symbols */
337     bool prettySymbols() const;
338 
339     /** \return True if style should be printed */
340     bool printOnlyStyle() const;
341 
342     /** \return True if Base16 theme should be used */
343     bool useBase16Theme() const;
344 
345     /** \return True if output token of the same syntax category should be in separate tags */
346     bool isolateTags() const;
347 
348     /** \return true if file extension should be ignored */
349     bool isSkippedExt ( const std::string& ext ) const;
350 
351     /** \return true if syntax load result should be reported */
352     bool checkSyntaxSupport () const;
353 
354     /** \return false  */
355     bool isLsRainbow () const;
356 
357     /** \return false  */
358     bool isLsSemantic () const;
359 
360     /** \return false  */
361     bool isLsHover () const;
362 
363     /** \return false  */
364     bool isLsSyntaxError () const;
365 
366     /** \return max. input file size (default 256 MB) */
367     off_t getMaxFileSize() const;
368 
369     /** \return The given base font, empty std::string by default */
370     const std::string& getBaseFont() const ;
371 
372     /** \return Document title */
373     const std::string& getDocumentTitle() const ;
374 
375     /** \return anchor prefix */
376     const std::string& getAnchorPrefix() const ;
377 
378     /** \return class name */
379     const std::string& getClassName() const ;
380 
381     /** \return list of plugin file paths */
382     const std::vector <std::string> &getPluginPaths() const;
383 
384     /** \return list of astyle options */
385     const std::vector <std::string> &getAStyleOptions() const;
386 
387     /** \return list of langiage server options */
388     const std::vector <std::string> &getLSOptions() const;
389 
390     /** \return 1 if trailing nl should be omitted,
391      *          2 if it should only be omitted for empty input */
392     int disableTrailingNL() const ;
393 
394     /** \return The given base font size, empty string by default */
395     const std::string& getBaseFontSize() const ;
396 
397     /** \return name of nested syntax which starts the input */
398     const std::string& getStartNestedLang() const ;
399 
400     /** \return absolute theme definition path name */
401     const std::string& getAbsThemePath() const ;
402 
403     /** \return absolute language definition path name */
404     const std::string& getAbsLangPath() const ;
405 
406     /** \return parameter passed to plugin */
407     const std::string& getPluginParameter() const ;
408 
409     /** \return category to filter scripts of --list-scripts */
410     const std::string& getCategories() const ;
411 
412     /** \return optional help topic */
413     const std::string& getHelpTopic() const;
414 
415     /** \return name of the file which will later be redirected to highlight's stdin */
416     const std::string& getSyntaxByFilename() const;
417 
418     /** \return category of scripts which should be listed */
419     const std::string& getListScriptKind() const;
420 
421         /** \return fallback syntax if not defined or found by filename or shebang */
422     const std::string& getFallbackSyntax() const;
423 
424     /** \return language server executable */
425     const std::string& getLsExecutable() const;
426 
427     /** \return language server workspace directory */
428     const std::string& getLsWorkspace() const;
429 
430     /** \return language server profile name */
431     const std::string& getLsProfile() const;
432 
433     /** \return syntax which triggers language server requests */
434     const std::string& getLsSyntax() const;
435 
436     /** \return server delay time in ms */
437     const int getLsDelay() const;
438 
439     /** \return line number width */
440     int getNumberWidth();
441 
442     /** \return line length */
443     int getLineLength();
444 
445     /** \return Line number start count */
446     int getNumberStart();
447 
448     /** \return ANSI background color padding width */
449     int getCanvasPadding();
450 
451     /** \return line range start */
452     int getLineRangeStart();
453 
454     /** \return line range end (number of lines starting from getLineRangeStart() ) */
455     int getLineRangeEnd();
456 
457     /** \return Keyword Case (upper, lower, unchanged) */
458     StringTools::KeywordCase getKeywordCase() const;
459 
460 private:
461 
462     int numberSpaces;   // number of spaces which replace a tab
463     int lineNrWidth;    // width of line number (left padding)
464     int lineLength;    // length of line before wrapping
465     int lineNrStart;    // line number start count
466     int lineRangeStart;    // line range start
467     int lineRangeEnd;    // line range end
468     int opt_no_trailing_nl;
469     int verbosity;
470     int lsDelay;
471 
472     unsigned int canvasPaddingWidth;    // line number start count
473 
474     highlight::WrapMode wrappingStyle; // line wrapping mode
475     highlight::OutputType outputType;
476     StringTools::KeywordCase keywordCase;
477 
478     // name of single output file
479     std::string outFilename,
480            // output directory
481            outDirectory,
482            // programming syntax which will be loaded
483            syntax,
484            // name of colour theme
485            styleName,
486            // name of external style file
487            styleOutFilename,
488            // name of file to be included in external style file
489            styleInFilename,
490            // used to define data directories at runtime
491            dataDir;
492 
493     // name of indenation scheme
494     std::string indentScheme,
495            pageSize,
496            startNestedLang;
497 
498     std::string baseFont, baseFontSize;
499     std::string docTitle, className;
500     std::string skipArg;
501     std::string svg_height, svg_width;
502     std::string absThemePath, absLangPath/*, twoPassFile*/;
503 
504     bool opt_syntax;
505     bool opt_include_style;
506     bool opt_help;
507     bool opt_version ;
508     bool opt_print_config;
509     bool opt_linenumbers;
510     bool opt_batch_mode;
511     bool opt_fragment;
512     bool opt_attach_line_anchors;
513     bool opt_printindex;
514     bool opt_quiet;
515     bool opt_replacequotes;
516     bool opt_babel;
517     bool opt_beamer;
518     bool opt_print_progress;
519     bool opt_fill_zeroes;
520     bool opt_stylepath_explicit;
521     bool opt_force_output;
522     bool opt_ordered_list;
523     bool opt_fnames_as_anchors;
524     bool opt_validate;
525     bool opt_number_wrapped_lines;
526     bool opt_inline_css;
527     bool opt_enclose_pre;
528     bool opt_char_styles;
529     bool opt_page_color;
530     bool opt_pretty_symbols;
531     bool opt_delim_CR;
532     bool opt_print_style;
533     bool opt_base16_theme;
534     bool opt_keep_injections;
535     bool opt_force_stdout;
536     bool opt_no_version_info;
537     bool explicit_output_format;
538     bool opt_isolate;
539     bool opt_encoding_explicit;
540     bool opt_syntax_supported_check;
541 
542     bool opt_ls_hover;
543     bool opt_ls_semantic;
544     bool opt_ls_rainbow;
545     bool opt_ls_syntax_error;
546 
547     off_t maxFileSize;
548 
549     std::string fallbackSyntax, anchorPrefix;
550     std::string helpLang, encodingName;
551 
552     std::string pluginPath, pluginParameter,
553            listScriptCategory, helpTopic, redirectedFilename, listScriptType;
554 
555     std::string lsProfile, lsExecutable, lsWorkspace, lsSyntax;
556 
557     /** list of all input file names */
558     std::vector <std::string> inputFileNames;
559 
560     /** list of plugin file names */
561     std::vector <std::string> userPlugins;
562 
563     /** list of additional Artistic Style options */
564     std::vector <std::string> astyleOptions;
565 
566     /** list of Language Server options */
567     std::vector <std::string> lsOptions;
568 
569     /** list of file types which should be ignored */
570     set <std::string> ignoredFileTypes;
571 
572     /** \return file suffix */
573     std::string getFileSuffix ( const std::string & fileName ) const;
574 
575     /** \return directory name of path */
576     std::string getDirName ( const std::string & path );
577 
578     /** get all entries in the directory defined by wildcard */
579     void readDirectory ( const std::string & wildcard );
580 
581     /** \return Valid path name */
582     std::string validateDirPath ( const std::string & path );
583 
584     void parseRuntimeOptions( const int argc, const char *argv[], bool readInputFilenames=true);
585 
586     void showDeprecationHint ( const std::string & option, const std::string & alt ) const;
587 };
588 
589 #endif
590