geany  1.38
About: Geany is a text editor (using GTK2) with basic features of an integrated development environment (syntax highlighting, code folding, symbol name auto-completion, ...). F: office T: editor programming GTK+ IDE
  Fossies Dox: geany-1.38.tar.bz2  ("unofficial" and yet experimental doxygen-generated source code documentation)  

options.c
Go to the documentation of this file.
1/*
2* Copyright (c) 1996-2003, Darren Hiebert
3*
4* This source code is released for free distribution under the terms of the
5* GNU General Public License version 2 or (at your option) any later version.
6*
7* This module contains functions to process command line options.
8*/
9
10/*
11* INCLUDE FILES
12*/
13#include "general.h" /* must always come first */
14
15#define OPTION_WRITE
16#include "options_p.h"
17
18#ifndef _GNU_SOURCE
19# define _GNU_SOURCE /* for asprintf */
20#endif
21#include <stdlib.h>
22#include <string.h>
23#include <stdio.h>
24#include <ctype.h> /* to declare isspace () */
25
26#include "ctags.h"
27#include "debug.h"
28#include "entry_p.h"
29#include "field_p.h"
30#include "gvars.h"
31#include "keyword_p.h"
32#include "parse_p.h"
33#include "ptag_p.h"
34#include "routines_p.h"
35#include "xtag_p.h"
36#include "param_p.h"
37#include "error_p.h"
38#include "interactive_p.h"
39#include "writer_p.h"
40#include "trace.h"
41
42#ifdef HAVE_JANSSON
43#include <jansson.h>
44#endif
45
46/*
47* MACROS
48*/
49#define INVOCATION "Usage: %s [options] [file(s)]\n"
50
51#define CTAGS_ENVIRONMENT "CTAGS"
52#define ETAGS_ENVIRONMENT "ETAGS"
53
54#ifndef ETAGS
55# define ETAGS "etags" /* name which causes default use of to -e */
56#endif
57
58/* The following separators are permitted for list options.
59 */
60#define EXTENSION_SEPARATOR '.'
61#define PATTERN_START '('
62#define PATTERN_STOP ')'
63#define IGNORE_SEPARATORS ", \t\n"
64
65#ifndef DEFAULT_FILE_FORMAT
66# define DEFAULT_FILE_FORMAT 2
67#endif
68
69#if defined (HAVE_OPENDIR) || defined (HAVE__FINDFIRST)
70# define RECURSE_SUPPORTED
71#endif
72
73#define isCompoundOption(c) (bool) (strchr ("fohiILpdDb", (c)) != NULL)
74
75#define ENTER(STAGE) do { \
76 Assert (Stage <= OptionLoadingStage##STAGE); \
77 if (Stage != OptionLoadingStage##STAGE) \
78 { \
79 Stage = OptionLoadingStage##STAGE; \
80 verbose ("Entering configuration stage: loading %s\n", StageDescription[Stage]); \
81 } \
82 } while (0)
83#define ACCEPT(STAGE) (1UL << OptionLoadingStage##STAGE)
84
85/*
86* Data declarations
87*/
88
90 MaxHeaderExtensions = 100, /* maximum number of extensions in -h option */
92};
93
94typedef struct sOptionDescription {
96 const char *description;
98
99typedef void (*parametricOptionHandler) (const char *const option, const char *const parameter);
100
101typedef const struct {
102 const char* name; /* name of option as specified by user */
103 parametricOptionHandler handler; /* routine to handle option */
104 bool initOnly; /* option must be specified before any files */
105 unsigned long acceptableStages;
107
108typedef const struct sBooleanOption {
109 const char* name; /* name of option as specified by user */
110 bool* pValue; /* pointer to option value */
111 bool initOnly; /* option must be specified before any files */
112 unsigned long acceptableStages;
113 void (* set) (const struct sBooleanOption *const option, bool value);
115
116/*
117* DATA DEFINITIONS
118*/
119
120static bool NonOptionEncountered = false;
122
125
127static bool FilesRequired = true;
129
130static const char *const HeaderExtensions [] = {
131 "h", "H", "hh", "hpp", "hxx", "h++", "inc", "def", NULL
132};
133
135bool ctags_verbose = false;
136
138 .append = false,
139 .backward = false,
140 .etags = false,
141 .locate =
142#ifdef MACROS_USE_PATTERNS
144#else
145 EX_MIX
146#endif
147 ,
148 .recurse = false,
149 .sorted = SO_SORTED,
150 .xref = false,
151 .customXfmt = NULL,
152 .fileList = NULL,
153 .tagFileName = NULL,
154 .headerExt = NULL,
155 .etagsInclude = NULL,
156 .tagFileFormat = DEFAULT_FILE_FORMAT,
157#ifdef HAVE_ICONV
158 .inputEncoding= NULL,
159 .outputEncoding = NULL,
160#endif
161 .language = LANG_AUTO,
162 .followLinks = true,
163 .filter = false,
164 .filterTerminator = NULL,
165 .tagRelative = TREL_NO,
166 .printTotals = 0,
167 .lineDirectives = false,
168 .printLanguage =false,
169 .guessLanguageEagerly = false,
170 .quiet = false,
171 .fatalWarnings = false,
172 .patternLengthLimit = 96,
173 .putFieldPrefix = false,
174 .maxRecursionDepth = 0xffffffff,
175 .interactive = false,
176#ifdef WIN32
177 .useSlashAsFilenameSeparator = FILENAME_SEP_UNSET,
178#endif
179#ifdef DEBUG
180 .breakLine = 0,
181#endif
182};
183
185 bool machinable; /* --machinable */
186 bool withListHeader; /* --with-list-header */
187} localOption = {
188 .machinable = false,
189 .withListHeader = true,
191
193#define STAGE_ANY ~0UL
194
195/*
196- Locally used only
197*/
198
200 {1," -? Print this option summary."},
201 {1," -a Append the tags to an existing tag file."},
202#ifdef DEBUG
203 {1," -b <line>"},
204 {1," Set break line."},
205#endif
206 {0," -B Use backward searching patterns (?...?)."},
207#ifdef DEBUG
208 {1," -d <level>"},
209 {1," Set debug level."},
210#endif
211 {1," -D <macro>=<definition>"},
212 {1," (CPreProcessor) Give definition for macro."},
213 {0," -e Output tag file for use with Emacs."},
214 {1," -f <name>"},
215 {1," Write tags to specified file. Value of \"-\" writes tags to stdout"},
216 {1," [\"tags\"; or \"TAGS\" when -e supplied]."},
217 {0," -F Use forward searching patterns (/.../; default)."},
218 {1," -G Equivalent to --guess-language-eagerly."},
219 {1," -h <list>"},
220 {1," Specify list of file extensions to be treated as include files"},
221 {1," [\".h.H.hh.hpp.hxx.h++.inc.def\"]."},
222 {1," -I <list|@file>"},
223 {1," A list of tokens to be specially handled is read from either the"},
224 {1," command line or the specified file."},
225 {1," -L <file>"},
226 {1," A list of input file names is read from the specified file."},
227 {1," If specified as \"-\", then standard input is read."},
228 {0," -n Equivalent to --excmd=number."},
229 {0," -N Equivalent to --excmd=pattern."},
230 {1," -o Alternative for -f."},
231#ifdef RECURSE_SUPPORTED
232 {1," -R Equivalent to --recurse."},
233#else
234 {1," -R Not supported on this platform."},
235#endif
236 {0," -u Equivalent to --sort=no."},
237 {1," -V Equivalent to --verbose."},
238 {1," -x Print a tabular cross reference file to standard output."},
239 {1," --alias-<LANG>=[+|-]aliasPattern"},
240 {1," Add a pattern detecting a name, can be used as an alternative name"},
241 {1," for LANG."},
242 {1," --append=[yes|no]"},
243 {1," Should tags should be appended to existing tag file [no]?"},
244 {1," --etags-include=file"},
245 {1," Include reference to 'file' in Emacs-style tag file (requires -e)."},
246 {1," --exclude=pattern"},
247 {1," Exclude files and directories matching 'pattern'."},
248 {1," See also --exclude-exception option."},
249 {1," --exclude-exception=pattern"},
250 {1," Don't exclude files and directories matching 'pattern' even if"},
251 {1," they match the pattern specified with --exclude option."},
252 {0," --excmd=number|pattern|mix|combine"},
253#ifdef MACROS_USE_PATTERNS
254 {0," Uses the specified type of EX command to locate tags [pattern]."},
255#else
256 {0," Uses the specified type of EX command to locate tags [mix]."},
257#endif
258 {1," --extras=[+|-]flags"},
259 {1," Include extra tag entries for selected information (flags: \"fFgpqrs\") [F]."},
260 {1," --extras-<LANG|all>=[+|-]flags"},
261 {1," Include <LANG> own extra tag entries for selected information"},
262 {1," (flags: see the output of --list-extras=<LANG> option)."},
263 {1," --fields=[+|-]flags"},
264 {1," Include selected extension fields (flags: \"aCeEfFikKlmnNpPrRsStxzZ\") [fks]."},
265 {1," --fields-<LANG|all>=[+|-]flags"},
266 {1," Include selected <LANG> own extension fields"},
267 {1," (flags: see the output of --list-fields=<LANG> option)."},
268 {1," --filter=[yes|no]"},
269 {1," Behave as a filter, reading file names from standard input and"},
270 {1," writing tags to standard output [no]."},
271 {1," --filter-terminator=string"},
272 {1," Specify string to print to stdout following the tags for each file"},
273 {1," parsed when --filter is enabled."},
274 {0," --format=level"},
275#if DEFAULT_FILE_FORMAT == 1
276 {0," Force output of specified tag file format [1]."},
277#else
278 {0," Force output of specified tag file format [2]."},
279#endif
280 {1," --guess-language-eagerly"},
281 {1," Guess the language of input file more eagerly"},
282 {1," (but taking longer time for guessing):"},
283 {1," o shebang, even if the input file is not executable,"},
284 {1," o emacs mode specification at the beginning and end of input file, and"},
285 {1," o vim syntax specification at the end of input file."},
286 {1," --help"},
287 {1," Print this option summary."},
288 {1," --help-full"},
289 {1," Print this option summary including experimental features."},
290 {1," --if0=[yes|no]"},
291 {1," Should code within #if 0 conditional branches be parsed [no]?"},
292#ifdef HAVE_ICONV
293 {1," --input-encoding=encoding"},
294 {1," Specify encoding of all input files."},
295 {1," --input-encoding-<LANG>=encoding"},
296 {1," Specify encoding of the LANG input files."},
297#endif
298 {1," --kinddef-<LANG>=letter,name,desc"},
299 {1," Define new kind for <LANG>."},
300 {1," --kinds-<LANG>=[+|-]kinds, or"},
301 {1," Enable/disable tag kinds for language <LANG>."},
302 {1," --langdef=name"},
303 {1," Define a new language to be parsed with regular expressions."},
304 {1," --langmap=map(s)"},
305 {1," Override default mapping of language to input file extension."},
306 {1," --language-force=language"},
307 {1," Force all files to be interpreted using specified language."},
308 {1," --languages=[+|-]list"},
309 {1," Restrict files scanned for tags to those mapped to languages"},
310 {1," specified in the comma-separated 'list'. The list can contain any"},
311 {1," built-in or user-defined language [all]."},
312 {1," --license"},
313 {1," Print details of software license."},
314 {0," --line-directives=[yes|no]"},
315 {0," Should #line directives be processed [no]?"},
316 {1," --links=[yes|no]"},
317 {1," Indicate whether symbolic links should be followed [yes]."},
318 {1," --list-aliases=[language|all]"},
319 {1," Output list of alias patterns."},
320 {1," --list-excludes"},
321 {1," Output list of exclude patterns for excluding files/directories."},
322 {1," --list-extras=[language|all]"},
323 {1," Output list of extra tag flags."},
324 {1," --list-features"},
325 {1," Output list of compiled features."},
326 {1," --list-fields=[language|all]"},
327 {1," Output list of fields."},
328 {1," --list-kinds=[language|all]"},
329 {1," Output a list of all tag kinds for specified language or all."},
330 {1," --list-kinds-full=[language|all]"},
331 {1," List the details of all tag kinds for specified language or all"},
332 {1," For each line, associated language name is printed when \"all\" is"},
333 {1," specified as language."},
334 {1," --list-languages"},
335 {1," Output list of supported languages."},
336 {1," --list-map-extensions=[language|all]"},
337 {1," Output list of language extensions in mapping."},
338 {1," --list-map-patterns=[language|all]"},
339 {1," Output list of language patterns in mapping."},
340 {1," --list-maps=[language|all]"},
341 {1," Output list of language mappings(both extensions and patterns)."},
342 {1," --list-mline-regex-flags"},
343 {1," Output list of flags which can be used in a multiline regex parser definition."},
344 {1," --list-params=[language|all]"},
345 {1," Output list of language parameters. This works with --machinable."},
346 {0," --list-pseudo-tags"},
347 {0," Output list of pseudo tags."},
348 {1," --list-regex-flags"},
349 {1," Output list of flags which can be used in a regex parser definition."},
350 {1," --list-roles=[[language|all].[kindspecs|*]]"},
351 {1," Output list of all roles of tag kind(s) specified for language(s)."},
352 {1," Both letters and names can be used in kindspecs."},
353 {1," e.g. --list-roles=C.{header}d"},
354 {1," --list-subparsers=[baselang|all]"},
355 {1," Output list of subparsers for the base language."},
356 {1," --machinable=[yes|no]"},
357 {1," Use tab separated representation in --list- option output. [no]"},
358 {1," --list-{aliases,extras,features,fields,kind-full,langdef-flags,params," },
359 {1," pseudo-tags,regex-flags,roles,subparsers} support this option."},
360 {1," Suitable for scripting. Specify before --list-* option."},
361 {1," --map-<LANG>=[+|-]extension|pattern"},
362 {1," Set, add(+) or remove(-) the map for <LANG>."},
363 {1," Unlike --langmap, this doesn't take a list; only one file name pattern"},
364 {1," or one file extension can be specified at once."},
365 {1," Unlike --langmap the change with this option affects mapping of <LANG> only."},
366 {1," --maxdepth=N"},
367#ifdef RECURSE_SUPPORTED
368 {1," Specify maximum recursion depth."},
369#else
370 {1," Not supported on this platform."},
371#endif
372 {1," --mline-regex-<LANG>=/line_pattern/name_pattern/[flags]"},
373 {1," Define multiline regular expression for locating tags in specific language."},
374 {1," --options=path"},
375 {1," Specify file(or directory) from which command line options should be read."},
376 {1," --options-maybe=path"},
377 {1," Do the same as --options but this doesn't make an error for non-existing file."},
378 {1," --optlib-dir=[+]DIR"},
379 {1," Add or set DIR to optlib search path."},
380#ifdef HAVE_ICONV
381 {1," --output-encoding=encoding"},
382 {1," The encoding to write the tag file in. Defaults to UTF-8 if --input-encoding"},
383 {1," is specified, otherwise no conversion is performed."},
384#endif
385 {0," --output-format=u-ctags|e-ctags|etags|xref"
386#ifdef HAVE_JANSSON
387 "|json"
388#endif
389 },
390 {0," Specify the output format. [u-ctags]"},
391 {1," --param-<LANG>:name=argument"},
392 {1," Set <LANG> specific parameter. Available parameters can be listed with --list-params."},
393 {0," --pattern-length-limit=N"},
394 {0," Cutoff patterns of tag entries after N characters. Disable by setting to 0. [96]"},
395 {0," --print-language"},
396 {0," Don't make tags file but just print the guessed language name for"},
397 {0," input file."},
398 {0," --pseudo-tags=[+|-]ptag"},
399 {0," --pseudo-tags=*"},
400 {0," Enable/disable emitting pseudo tag named ptag."},
401 {0," if * is given, enable emitting all pseudo tags."},
402 {0," --put-field-prefix"},
403 {0," Put \"" CTAGS_FIELD_PREFIX "\" as prefix for the name of fields newly introduced in"},
404 {0," universal-ctags."},
405 {1," --quiet=[yes|no]"},
406 {0," Don't print NOTICE class messages [no]."},
407 {1," --recurse=[yes|no]"},
408#ifdef RECURSE_SUPPORTED
409 {1," Recurse into directories supplied on command line [no]."},
410#else
411 {1," Not supported on this platform."},
412#endif
413 {1," --regex-<LANG>=/line_pattern/name_pattern/[flags]"},
414 {1," Define regular expression for locating tags in specific language."},
415 {1," --roles-<LANG>.kind=[+|-]role, or"},
416 {1," Enable/disable tag roles for kinds of language <LANG>."},
417 {0," --sort=[yes|no|foldcase]"},
418 {0," Should tags be sorted (optionally ignoring case) [yes]?"},
419 {0," --tag-relative=[yes|no|always|never]"},
420 {0," Should paths be relative to location of tag file [no; yes when -e]?"},
421 {0," always: be relative even if input files are passed in with absolute paths" },
422 {0," never: be absolute even if input files are passed in with relative paths" },
423 {1," --totals=[yes|no|extra]"},
424 {1," Print statistics about input and tag files [no]."},
425#ifdef WIN32
426 {1," --use-slash-as-filename-separator=[yes|no]"},
427 {1," Use slash as filename separator [yes] for u-ctags output format."},
428#endif
429 {1," --verbose=[yes|no]"},
430 {1," Enable verbose messages describing actions on each input file."},
431 {1," --version"},
432 {1," Print version identifier to standard output."},
433 {1," --with-list-header=[yes|no]"},
434 {1," Prepend the column descriptions in --list- output. [yes]"},
435 {1," --list-{aliases,extras,features,fields,kind-full,langdef-flags,params," },
436 {1," pseudo-tags,regex-flags,roles,subparsers} support this option."},
437 {1," Specify before --list-* option."},
438 {1, NULL}
439};
440
442 {1," --_anonhash=fname"},
443 {1," Used in u-ctags test harness"},
444 {1," --_dump-keywords"},
445 {1," Dump keywords of initialized parser(s)."},
446 {1," --_dump-options"},
447 {1," Dump options."},
448 {1," --_echo=msg"},
449 {1," Echo MSG to standard error. Useful to debug the chain"},
450 {1," of loading option files."},
451 {1," --_extradef-<LANG>=name,desc"},
452 {1," Define new extra for <LANG>. \"--extras-<LANG>=+{name}\" enables it."},
453 {1," --_fatal-warnings"},
454 {1," Make all warnings fatal."},
455 {1," --_fielddef-<LANG>=name,description"},
456 {1," EXPERIMENTAL, Define new field for <LANG>."},
457 {1," --_force-initializing"},
458 {1," Initialize all parsers in early stage"},
459 {1," --_force-quit=[num]"},
460 {1," Quit when the option is processed. Useful to debug the chain"},
461 {1," of loading option files."},
462#ifdef HAVE_JANSSON
463 {0," --_interactive"
464#ifdef HAVE_SECCOMP
465 "=[default|sandbox]"
466#endif
467 },
468 {0," Enter interactive mode (json over stdio)."},
469#ifdef HAVE_SECCOMP
470 {0," Enter file I/O limited interactive mode if sandbox is specified. [default]"},
471#endif
472#endif
473 {1," --_list-kinddef-flags"},
474 {1," Output list of flags which can be used with --kinddef option."},
475 {1," --_list-langdef-flags"},
476 {1," Output list of flags which can be used with --langdef option."},
477 {1," --_list-mtable-regex-flags"},
478 {1," Output list of flags which can be used in a multitable regex parser definition."},
479 {1," --_mtable-extend-<LANG>=disttable+srctable."},
480 {1," Copy patterns of a regex table to another regex table."},
481 {1," --_mtable-regex-<LANG>=table/line_pattern/name_pattern/[flags]"},
482 {1," Define multitable regular expression for locating tags in specific language."},
483 {1," --_pretend-<NEWLANG>=<OLDLANG>"},
484 {1," Make NEWLANG parser pretend OLDLANG parser in lang: field."},
485 {1," --_roledef-<LANG>.kind=role_name,role_desc"},
486 {1," Define new role for the kind in <LANG>."},
487 {1," --_scopesep-<LANG>=[parent_kind_letter]/child_kind_letter:separator"},
488 {1," Specify scope separator between <PARENT_KIND> and <KIND>."},
489 {1," * as a kind letter matches any kind."},
490 {1," --_tabledef-<LANG>=name"},
491 {1," Define new regex table for <LANG>."},
492#ifdef DO_TRACING
493 {1," --_trace=list"},
494 {1," Trace parsers for the languages."},
495#endif
496 {1," --_xformat=field_format"},
497 {1," Specify custom format for tabular cross reference (-x)."},
498 {1," Fields can be specified with letter listed in --list-fields."},
499 {1," e.g. --_xformat=%10N %10l:%K @ %-20F:%-20n"},
500 {1, NULL}
501};
502
503static const char* const License1 =
504"This program is free software; you can redistribute it and/or\n"
505"modify it under the terms of the GNU General Public License\n"
506"as published by the Free Software Foundation; either version 2"
507"of the License, or (at your option) any later version.\n"
508"\n";
509static const char* const License2 =
510"This program is distributed in the hope that it will be useful,\n"
511"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
512"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
513"GNU General Public License for more details.\n"
514"\n"
515"You should have received a copy of the GNU General Public License\n"
516"along with this program; if not, write to the Free Software\n"
517"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n";
518
519/* Contains a set of strings describing the set of "features" compiled into
520 * the code.
521 */
522static struct Feature {
523 const char *name;
524 const char *description;
525} Features [] = {
526#ifdef WIN32
527 {"win32", "TO BE WRITTEN"},
528#endif
529 /* Following two features are always available on universal ctags */
530 {"wildcards", "can use glob matching"},
531 {"regex", "can use regular expression based pattern matching"},
532
533#ifndef EXTERNAL_SORT
534 {"internal-sort", "uses internal sort routine instead of invoking sort command"},
535#endif
536#ifdef CUSTOM_CONFIGURATION_FILE
537 {"custom-conf", "read \"" CUSTOM_CONFIGURATION_FILE "\" as config file"},
538#endif
539#if defined (WIN32)
540 {"unix-path-separator", "can use '/' as file name separator"},
541#endif
542#ifdef HAVE_ICONV
543 {"iconv", "can convert input/output encodings"},
544#endif
545#ifdef DEBUG
546 {"debug", "TO BE WRITTEN"},
547#endif
548#if defined (HAVE_DIRENT_H) || defined (_MSC_VER)
549 {"option-directory", "TO BE WRITTEN"},
550#endif
551#ifdef HAVE_LIBXML
552 {"xpath", "linked with library for parsing xml input"},
553#endif
554#ifdef HAVE_JANSSON
555 {"json", "supports json format output"},
556 {"interactive", "accepts source code from stdin"},
557#endif
558#ifdef HAVE_SECCOMP
559 {"sandbox", "linked with code for system call level sandbox"},
560#endif
561#ifdef HAVE_LIBYAML
562 {"yaml", "linked with library for parsing yaml input"},
563#endif
564#ifdef CASE_INSENSITIVE_FILENAMES
565 {"case-insensitive-filenames", "TO BE WRITTEN"},
566#endif
567#ifdef ENABLE_GCOV
568 {"gcov", "linked with code for coverage analysis"},
569#endif
570#ifdef HAVE_PACKCC
571 /* The test harnesses use this as hints for skipping test cases */
572 {"packcc", "has peg based parser(s)"},
573#endif
574 {NULL,}
576
577static const char *const StageDescription [] = {
578 [OptionLoadingStageNone] = "not initialized",
579 [OptionLoadingStageCustom] = "custom file",
580 [OptionLoadingStageDosCnf] = "DOS .cnf file",
581 [OptionLoadingStageEtc] = "file under /etc (e.g. ctags.conf)",
582 [OptionLoadingStageLocalEtc] = "file under /usr/local/etc (e.g. ctags.conf)",
583 [OptionLoadingStageXdg] = "file(s) under $XDG_CONFIG_HOME and $HOME/.config",
584 [OptionLoadingStageHomeRecursive] = "file(s) under $HOME",
585 [OptionLoadingStageCurrentRecursive] = "file(s) under the current directory",
586 [OptionLoadingStagePreload] = "optlib preload files",
587 [OptionLoadingStageEnvVar] = "environment variable",
588 [OptionLoadingStageCmdline] = "command line",
589};
590
591/*
592* FUNCTION PROTOTYPES
593*/
594static bool parseFileOptions (const char *const fileName);
595static bool parseAllConfigurationFilesOptionsInDirectory (const char *const fileName,
596 stringList* const already_loaded_files);
597static bool getBooleanOption (const char *const option, const char *const parameter);
598
599/*
600* FUNCTION DEFINITIONS
601*/
602
603#ifndef HAVE_ASPRINTF
604
605/* Some versions of MinGW are missing _vscprintf's declaration, although they
606 * still provide the symbol in the import library.
607 */
608#ifdef __MINGW32__
609_CRTIMP int _vscprintf(const char *format, va_list argptr);
610#endif
611
612#ifndef va_copy
613#define va_copy(dest, src) (dest = src)
614#endif
615
616int asprintf(char **strp, const char *fmt, ...)
617{
618 va_list args;
619 va_list args_copy;
620 int length;
621 size_t size;
622
623 va_start(args, fmt);
624
625 va_copy(args_copy, args);
626
627#ifdef _WIN32
628 /* We need to use _vscprintf to calculate the length as vsnprintf returns -1
629 * if the number of characters to write is greater than count.
630 */
631 length = _vscprintf(fmt, args_copy);
632#else
633 char dummy;
634 length = vsnprintf(&dummy, sizeof dummy, fmt, args_copy);
635#endif
636
637 va_end(args_copy);
638
639 Assert(length >= 0);
640 size = length + 1;
641
642 *strp = malloc(size);
643 if (!*strp) {
644 return -1;
645 }
646
647 va_start(args, fmt);
648 vsnprintf(*strp, size, fmt, args);
649 va_end(args);
650
651 return length;
652}
653#endif
654
655extern void verbose (const char *const format, ...)
656{
657 if (ctags_verbose)
658 {
659 va_list ap;
660 va_start (ap, format);
661 vfprintf (stderr, format, ap);
662 va_end (ap);
663 }
664}
665
666extern void notice (const char *const format, ...)
667{
668 if (!Option.quiet)
669 {
670 va_list ap;
671 fprintf (stderr, "%s: Notice: ", getExecutableName ());
672 va_start (ap, format);
673 vfprintf (stderr, format, ap);
674 va_end (ap);
675 fputs ("\n", stderr);
676 }
677}
678
679
680static char *stringCopy (const char *const string)
681{
682 char* result = NULL;
683 if (string != NULL)
684 result = eStrdup (string);
685 return result;
686}
687
688static void freeString (char **const pString)
689{
690 if (*pString != NULL)
691 {
692 eFree (*pString);
693 *pString = NULL;
694 }
695}
696
697extern void freeList (stringList** const pList)
698{
699 if (*pList != NULL)
700 {
701 stringListDelete (*pList);
702 *pList = NULL;
703 }
704}
705
706extern void setDefaultTagFileName (void)
707{
709 return;
710
711 if (Option.tagFileName == NULL)
712 {
713 const char *tmp = outputDefaultFileName ();
714
715 if (tmp == NULL)
716 tmp = "-";
717
719 }
720}
721
722extern bool filesRequired (void)
723{
724 bool result = FilesRequired;
725 if (Option.recurse)
726 result = false;
727 return result;
728}
729
730extern void checkOptions (void)
731{
732 const char* notice;
733 if (Option.xref && (Option.customXfmt == NULL))
734 {
735 notice = "xref output";
737 {
738 error (WARNING, "%s disables file name tags", notice);
740 }
741 }
742 if (Option.append)
743 {
744 notice = "append mode is not compatible with";
745 if (isDestinationStdout ())
746 error (FATAL, "%s tags to stdout", notice);
747 }
748 if (Option.filter)
749 {
750 notice = "filter mode";
752 {
753 error (WARNING, "%s disables totals", notice);
755 }
756 if (Option.tagFileName != NULL)
757 error (WARNING, "%s ignores output tag file name", notice);
758 }
760}
761
762extern langType getLanguageComponentInOptionFull (const char *const option,
763 const char *const prefix,
764 bool noPretending)
765{
766 size_t prefix_len;
767 langType language;
768 const char *lang;
769 char *sep = NULL;
770 size_t lang_len = 0;
771
772 Assert (prefix && prefix[0]);
773 Assert (option);
774
775 prefix_len = strlen (prefix);
776 if (strncmp (option, prefix, prefix_len) != 0)
777 return LANG_IGNORE;
778 else
779 {
780 lang = option + prefix_len;
781 if (lang [0] == '\0')
782 return LANG_IGNORE;
783 }
784
785 /* Extract <LANG> from
786 * --param-<LANG>:<PARAM>=..., and
787 * --_roledef-<LANG>.<KIND>=... */
788 sep = strpbrk (lang, ":.");
789 if (sep)
790 lang_len = sep - lang;
791 language = getNamedLanguageFull (lang, lang_len, noPretending);
792 if (language == LANG_IGNORE)
793 {
794 const char *langName = (lang_len == 0)? lang: eStrndup (lang, lang_len);
795 error (FATAL, "Unknown language \"%s\" in \"%s\" option", langName, option);
796 }
797
798 return language;
799}
800
801extern langType getLanguageComponentInOption (const char *const option,
802 const char *const prefix)
803{
804 return getLanguageComponentInOptionFull (option, prefix, false);
805}
806
807static void setEtagsMode (void)
808{
809 Option.etags = true;
811 Option.lineDirectives = false;
815}
816
817extern void testEtagsInvocation (void)
818{
819 char* const execName = eStrdup (getExecutableName ());
820 char* const etags = eStrdup (ETAGS);
821#ifdef CASE_INSENSITIVE_FILENAMES
822 toLowerString (execName);
823 toLowerString (etags);
824#endif
825 if (strstr (execName, etags) != NULL)
826 {
827 verbose ("Running in etags mode\n");
828 setEtagsMode ();
829 }
830 eFree (execName);
831 eFree (etags);
832}
833
834static void setXrefMode (void)
835{
836 Option.xref = true;
838}
839
840#ifdef HAVE_JANSSON
841static void setJsonMode (void)
842{
847}
848#endif
849
850/*
851 * Cooked argument parsing
852 */
853
854static void parseShortOption (cookedArgs *const args)
855{
856 args->simple [0] = *args->shortOptions++;
857 args->simple [1] = '\0';
858 args->item = eStrdup (args->simple);
859 if (! isCompoundOption (*args->simple))
860 args->parameter = "";
861 else if (*args->shortOptions == '\0')
862 {
863 argForth (args->args);
864 if (argOff (args->args))
865 args->parameter = NULL;
866 else
867 args->parameter = argItem (args->args);
868 args->shortOptions = NULL;
869 }
870 else
871 {
872 args->parameter = args->shortOptions;
873 args->shortOptions = NULL;
874 }
875}
876
877static void parseLongOption (cookedArgs *const args, const char *item)
878{
879 const char* const equal = strchr (item, '=');
880 if (equal == NULL)
881 {
882 args->item = eStrdup (item);
883 args->parameter = "";
884 }
885 else
886 {
887 args->item = eStrndup (item, equal - item);
888 args->parameter = equal + 1;
889 }
890 Assert (args->item != NULL);
891 Assert (args->parameter != NULL);
892}
893
894static void cArgRead (cookedArgs *const current)
895{
896 char* item;
897
898 Assert (current != NULL);
899 if (! argOff (current->args))
900 {
901 item = argItem (current->args);
902 current->shortOptions = NULL;
903 Assert (item != NULL);
904 if (strncmp (item, "--", (size_t) 2) == 0)
905 {
906 current->isOption = true;
907 current->longOption = true;
908 parseLongOption (current, item + 2);
909 Assert (current->item != NULL);
910 Assert (current->parameter != NULL);
911 }
912 else if (*item == '-')
913 {
914 current->isOption = true;
915 current->longOption = false;
916 current->shortOptions = item + 1;
917 parseShortOption (current);
918 }
919 else
920 {
921 current->isOption = false;
922 current->longOption = false;
923 current->item = eStrdup (item);
924 current->parameter = NULL;
925 }
926 }
927}
928
929extern cookedArgs* cArgNewFromString (const char* string)
930{
931 cookedArgs* const result = xMalloc (1, cookedArgs);
932 memset (result, 0, sizeof (cookedArgs));
933 result->args = argNewFromString (string);
934 cArgRead (result);
935 return result;
936}
937
938extern cookedArgs* cArgNewFromArgv (char* const* const argv)
939{
940 cookedArgs* const result = xMalloc (1, cookedArgs);
941 memset (result, 0, sizeof (cookedArgs));
942 result->args = argNewFromArgv (argv);
943 cArgRead (result);
944 return result;
945}
946
947extern cookedArgs* cArgNewFromFile (FILE* const fp)
948{
949 cookedArgs* const result = xMalloc (1, cookedArgs);
950 memset (result, 0, sizeof (cookedArgs));
951 result->args = argNewFromFile (fp);
952 cArgRead (result);
953 return result;
954}
955
956extern cookedArgs* cArgNewFromLineFile (FILE* const fp)
957{
958 cookedArgs* const result = xMalloc (1, cookedArgs);
959 memset (result, 0, sizeof (cookedArgs));
960 result->args = argNewFromLineFile (fp);
961 cArgRead (result);
962 return result;
963}
964
965extern void cArgDelete (cookedArgs* const current)
966{
967 Assert (current != NULL);
968 argDelete (current->args);
969 if (current->item != NULL)
970 eFree (current->item);
971 memset (current, 0, sizeof (cookedArgs));
972 eFree (current);
973}
974
975static bool cArgOptionPending (cookedArgs* const current)
976{
977 bool result = false;
978 if (current->shortOptions != NULL)
979 if (*current->shortOptions != '\0')
980 result = true;
981 return result;
982}
983
984extern bool cArgOff (cookedArgs* const current)
985{
986 Assert (current != NULL);
987 return (bool) (argOff (current->args) && ! cArgOptionPending (current));
988}
989
990extern bool cArgIsOption (cookedArgs* const current)
991{
992 Assert (current != NULL);
993 return current->isOption;
994}
995
996extern const char* cArgItem (cookedArgs* const current)
997{
998 Assert (current != NULL);
999 return current->item;
1000}
1001
1002extern void cArgForth (cookedArgs* const current)
1003{
1004 Assert (current != NULL);
1005 Assert (! cArgOff (current));
1006 if (current->item != NULL)
1007 eFree (current->item);
1008 if (cArgOptionPending (current))
1009 parseShortOption (current);
1010 else
1011 {
1012 Assert (! argOff (current->args));
1013 argForth (current->args);
1014 if (! argOff (current->args))
1015 cArgRead (current);
1016 else
1017 {
1018 current->isOption = false;
1019 current->longOption = false;
1020 current->shortOptions = NULL;
1021 current->item = NULL;
1022 current->parameter = NULL;
1023 }
1024 }
1025}
1026
1027/*
1028 * File extension and language mapping
1029 */
1030
1031static void addExtensionList (
1032 stringList *const slist, const char *const elist, const bool clear)
1033{
1034 char *const extensionList = eStrdup (elist);
1035 const char *extension = NULL;
1036 bool first = true;
1037
1038 if (clear)
1039 {
1040 verbose (" clearing\n");
1041 stringListClear (slist);
1042 }
1043 verbose (" adding: ");
1044 if (elist != NULL && *elist != '\0')
1045 {
1046 extension = extensionList;
1047 if (elist [0] == EXTENSION_SEPARATOR)
1048 ++extension;
1049 }
1050 while (extension != NULL)
1051 {
1052 char *separator = strchr (extension, EXTENSION_SEPARATOR);
1053 if (separator != NULL)
1054 *separator = '\0';
1055 verbose ("%s%s", first ? "" : ", ",
1056 *extension == '\0' ? "(NONE)" : extension);
1057 stringListAdd (slist, vStringNewInit (extension));
1058 first = false;
1059 if (separator == NULL)
1060 extension = NULL;
1061 else
1062 extension = separator + 1;
1063 }
1064 BEGIN_VERBOSE(vfp);
1065 {
1066 fprintf (vfp, "\n now: ");
1067 stringListPrint (slist, vfp);
1068 putc ('\n', vfp);
1069 }
1070 END_VERBOSE();
1071}
1072
1073static bool isFalse (const char *parameter)
1074{
1075 return (bool) (
1076 strcasecmp (parameter, "0" ) == 0 ||
1077 strcasecmp (parameter, "n" ) == 0 ||
1078 strcasecmp (parameter, "no" ) == 0 ||
1079 strcasecmp (parameter, "off") == 0 ||
1080 strcasecmp (parameter, "false") == 0 );
1081}
1082
1083static bool isTrue (const char *parameter)
1084{
1085 return (bool) (
1086 strcasecmp (parameter, "1" ) == 0 ||
1087 strcasecmp (parameter, "y" ) == 0 ||
1088 strcasecmp (parameter, "yes") == 0 ||
1089 strcasecmp (parameter, "on" ) == 0 ||
1090 strcasecmp (parameter, "true" ) == 0);
1091}
1092
1093extern bool paramParserBool (const char *value, bool fallback,
1094 const char *errWhat, const char *errCategory)
1095{
1096 bool r = fallback;
1097
1098 if (value [0] == '\0')
1099 r = true;
1100 else if (isFalse (value))
1101 r = false;
1102 else if (isTrue (value))
1103 r = true;
1104 else
1105 error (FATAL, "Invalid value for \"%s\" %s", errWhat, errCategory);
1106
1107 return r;
1108}
1109
1110/* Determines whether the specified file name is considered to be a header
1111 * file for the purposes of determining whether enclosed tags are global or
1112 * static.
1113 */
1114extern bool isIncludeFile (const char *const fileName)
1115{
1116 bool result = false;
1117 const char *const extension = fileExtension (fileName);
1118 if (Option.headerExt != NULL)
1119 result = stringListExtensionMatched (Option.headerExt, extension);
1120 return result;
1121}
1122
1123/*
1124 * Specific option processing
1125 */
1126
1128 const char *const option, const char *const parameter)
1129{
1130 if (! Option.etags)
1131 error (FATAL, "Etags must be enabled to use \"%s\" option", option);
1132 else
1133 {
1134 vString *const file = vStringNewInit (parameter);
1135 if (Option.etagsInclude == NULL)
1138 FilesRequired = false;
1139 }
1140}
1141
1143 stringList** list, const char *const optname, const char *const parameter)
1144{
1145 const char *const fileName = parameter + 1;
1146 if (parameter [0] == '\0')
1147 freeList (list);
1148 else if (parameter [0] == '@')
1149 {
1150 stringList* const sl = stringListNewFromFile (fileName);
1151 if (sl == NULL)
1152 error (FATAL | PERROR, "cannot open \"%s\"", fileName);
1153 if (*list == NULL)
1154 *list = sl;
1155 else
1156 stringListCombine (*list, sl);
1157 verbose (" adding %s patterns from %s\n", optname, fileName);
1158 }
1159 else
1160 {
1161 vString *const item = vStringNewInit (parameter);
1162#if defined (WIN32)
1164#endif
1165 if (*list == NULL)
1166 *list = stringListNew ();
1167 stringListAdd (*list, item);
1168 verbose (" adding %s pattern: %s\n", optname, parameter);
1169 }
1170}
1171
1173 const char *const option, const char *const parameter)
1174{
1175 processExcludeOptionCommon (&Excluded, option, parameter);
1176}
1177
1179 const char *const option, const char *const parameter)
1180{
1181 processExcludeOptionCommon (&ExcludedException, option, parameter);
1182}
1183
1184extern bool isExcludedFile (const char* const name,
1185 bool falseIfExceptionsAreDefeind)
1186{
1187 const char* base = baseFilename (name);
1188 bool result = false;
1189
1190 if (falseIfExceptionsAreDefeind
1193 return false;
1194
1195 if (Excluded != NULL)
1196 {
1197 result = stringListFileMatched (Excluded, base);
1198 if (! result && name != base)
1200 }
1201
1202 if (result && ExcludedException != NULL)
1203 {
1204 bool result_exception;
1205
1206 result_exception = stringListFileMatched (ExcludedException, base);
1207 if (! result_exception && name != base)
1208 result_exception = stringListFileMatched (ExcludedException, name);
1209
1210 if (result_exception)
1211 result = false;
1212 }
1213 return result;
1214}
1215
1217 const char *const option, const char *const parameter)
1218{
1219 switch (*parameter)
1220 {
1221 case 'm': Option.locate = EX_MIX; break;
1222 case 'n': Option.locate = EX_LINENUM; break;
1223 case 'p': Option.locate = EX_PATTERN; break;
1224 default:
1225 if (strcmp(parameter, "combine") == 0)
1227 else
1228 error (FATAL, "Invalid value for \"%s\" option: %s", option, parameter);
1229 break;
1230 }
1231}
1232
1233static void resetXtags (langType lang, bool mode)
1234{
1235 int i;
1236 for (i = 0; i < countXtags (); i++)
1237 if ((lang == LANG_AUTO) || (lang == getXtagOwner (i)))
1238 enableXtag (i, mode);
1239}
1240
1242 const char *const option, const char *const parameter)
1243{
1244 xtagType t;
1245 const char *p = parameter;
1246 bool mode = true;
1247 int c;
1248 static vString *longName;
1249 bool inLongName = false;
1250 const char *x;
1251
1252 if (strcmp (option, "extra") == 0)
1253 error(WARNING, "--extra option is obsolete; use --extras instead");
1254
1255 if (*p == '*')
1256 {
1257 resetXtags (LANG_IGNORE, true);
1258 p++;
1259 }
1260 else if (*p != '+' && *p != '-')
1261 resetXtags (LANG_IGNORE, false);
1262
1263 longName = vStringNewOrClearWithAutoRelease (longName);
1264
1265 while ((c = *p++) != '\0')
1266 {
1267 switch (c)
1268 {
1269 case '+':
1270 if (inLongName)
1271 vStringPut (longName, c);
1272 else
1273 mode = true;
1274 break;
1275 case '-':
1276 if (inLongName)
1277 vStringPut (longName, c);
1278 else
1279 mode = false;
1280 break;
1281 case '{':
1282 if (inLongName)
1283 error(FATAL,
1284 "unexpected character in extra specification: \'%c\'",
1285 c);
1286 inLongName = true;
1287 break;
1288 case '}':
1289 if (!inLongName)
1290 error(FATAL,
1291 "unexpected character in extra specification: \'%c\'",
1292 c);
1293 x = vStringValue (longName);
1295
1296 if (t == XTAG_UNKNOWN)
1297 error(WARNING, "Unsupported parameter '{%s}' for \"%s\" option",
1298 x, option);
1299 else
1300 enableXtag (t, mode);
1301
1302 inLongName = false;
1303 vStringClear (longName);
1304 break;
1305 default:
1306 if (inLongName)
1307 vStringPut (longName, c);
1308 else
1309 {
1310 t = getXtagTypeForLetter (c);
1311 if (t == XTAG_UNKNOWN)
1312 error(WARNING, "Unsupported parameter '%c' for \"%s\" option",
1313 c, option);
1314 else
1315 enableXtag (t, mode);
1316 }
1317 break;
1318 }
1319 }
1320}
1321
1322static void resetFieldsOption (langType lang, bool mode)
1323{
1324 int i;
1325
1326 for (i = 0; i < countFields (); ++i)
1327 if ((lang == LANG_AUTO) || (lang == getFieldOwner (i)))
1328 enableField (i, mode, false);
1329}
1330
1332 const char *const option, const char *const parameter)
1333{
1334 const char *p = parameter;
1335 bool mode = true;
1336 int c;
1337 fieldType t;
1338
1339 static vString * longName;
1340 bool inLongName = false;
1341
1342 longName = vStringNewOrClearWithAutoRelease (longName);
1343
1344 if (*p == '*')
1345 {
1347 p++;
1348 }
1349 else if (*p != '+' && *p != '-')
1351
1352 while ((c = *p++) != '\0') switch (c)
1353 {
1354 case '+':
1355 if (inLongName)
1356 vStringPut (longName, c);
1357 else
1358 mode = true;
1359 break;
1360 case '-':
1361 if (inLongName)
1362 vStringPut (longName, c);
1363 else
1364 mode = false;
1365 break;
1366 case '{':
1367 if (inLongName)
1368 error(FATAL,
1369 "unexpected character in field specification: \'%c\'",
1370 c);
1371 inLongName = true;
1372 break;
1373 case '}':
1374 if (!inLongName)
1375 error(FATAL,
1376 "unexpected character in field specification: \'%c\'",
1377 c);
1378
1379 {
1380 const char *f = vStringValue (longName);
1382 }
1383
1384 if (t == FIELD_UNKNOWN)
1385 error(FATAL, "no such field: \'%s\'", vStringValue (longName));
1386
1387 enableField (t, mode, true);
1388
1389 inLongName = false;
1390 vStringClear (longName);
1391 break;
1392 default :
1393 if (inLongName)
1394 vStringPut (longName, c);
1395 else
1396 {
1397 t = getFieldTypeForOption (c);
1398 if (t == FIELD_UNKNOWN)
1399 error(WARNING, "Unsupported parameter '%c' for \"%s\" option",
1400 c, option);
1401 else
1402 enableField (t, mode, true);
1403 }
1404 break;
1405 }
1406}
1407
1409 const char *const option CTAGS_ATTR_UNUSED, const char *const parameter)
1410{
1412 Option.filterTerminator = stringCopy (parameter);
1413}
1414
1416 const char *const option, const char *const parameter)
1417{
1418 unsigned int format;
1419
1420 if (sscanf (parameter, "%u", &format) < 1)
1421 error (FATAL, "Invalid value for \"%s\" option",option);
1422 else if (format <= (unsigned int) MaxSupportedTagFormat)
1424 else
1425 error (FATAL, "Unsupported value for \"%s\" option", option);
1426}
1427
1428#ifdef HAVE_ICONV
1429static void processInputEncodingOption(const char *const option CTAGS_ATTR_UNUSED,
1430 const char *const parameter)
1431{
1432 if (Option.inputEncoding)
1433 eFree (Option.inputEncoding);
1434 else
1435 {
1436 if (!Option.outputEncoding)
1437 Option.outputEncoding = eStrdup("UTF-8");
1438 }
1439 Option.inputEncoding = eStrdup(parameter);
1440}
1441
1442static void processOutputEncodingOption(const char *const option CTAGS_ATTR_UNUSED,
1443 const char *const parameter)
1444{
1445 if (Option.outputEncoding)
1446 eFree (Option.outputEncoding);
1447 Option.outputEncoding = eStrdup(parameter);
1448}
1449#endif
1450
1452{
1453 printf (INVOCATION, getExecutableName ());
1454}
1455
1456static void printOptionDescriptions (const optionDescription *const optDesc)
1457{
1458 int i;
1459 for (i = 0 ; optDesc [i].description != NULL ; ++i)
1460 {
1461 if (! Option.etags || optDesc [i].usedByEtags)
1462 puts (optDesc [i].description);
1463 }
1464}
1465
1466
1467static int excludesCompare (struct colprintLine *a, struct colprintLine *b)
1468{
1469 return strcmp (colprintLineGetColumn (a, 0), colprintLineGetColumn (b, 0));
1470}
1471
1472static void processListExcludesOption(const char *const option CTAGS_ATTR_UNUSED,
1473 const char *const parameter CTAGS_ATTR_UNUSED)
1474{
1475 int i;
1476 struct colprintTable *table = colprintTableNew ("L:NAME", NULL);
1477
1478 const int max = Excluded ? stringListCount (Excluded) : 0;
1479
1480 for (i = 0; i < max; ++i)
1481 {
1482 struct colprintLine * line = colprintTableGetNewLine (table);
1484 }
1485
1488 colprintTableDelete (table);
1489
1490 if (i == 0)
1491 putchar ('\n');
1492
1493 exit (0);
1494}
1495
1496
1497static void printFeatureList (void)
1498{
1499 int i;
1500
1501 for (i = 0 ; Features [i].name != NULL ; ++i)
1502 {
1503 if (i == 0)
1504 printf (" Optional compiled features: ");
1505 if (strcmp (Features [i].name, "regex") != 0 || checkRegex ())
1506 printf ("%s+%s", (i>0 ? ", " : ""), Features [i].name);
1507#ifdef CUSTOM_CONFIGURATION_FILE
1508 if (strcmp (Features [i].name, "custom-conf") == 0)
1509 printf ("=%s", CUSTOM_CONFIGURATION_FILE);
1510#endif
1511 }
1512 if (i > 0)
1513 putchar ('\n');
1514}
1515
1516
1517static int featureCompare (struct colprintLine *a, struct colprintLine *b)
1518{
1519 return strcmp (colprintLineGetColumn (a, 0),
1520 colprintLineGetColumn (b, 0));
1521}
1522
1523static void processListFeaturesOption(const char *const option CTAGS_ATTR_UNUSED,
1524 const char *const parameter CTAGS_ATTR_UNUSED)
1525{
1526 int i;
1527
1528 struct colprintTable *table = colprintTableNew ("L:NAME", "L:DESCRIPTION", NULL);
1529
1530 for (i = 0 ; Features [i].name != NULL ; ++i)
1531 {
1532 struct colprintLine * line = colprintTableGetNewLine (table);
1533 if (strcmp (Features [i].name, "regex") != 0 || checkRegex ())
1534 {
1537 }
1538
1539 }
1540
1543 colprintTableDelete (table);
1544
1545 if (i == 0)
1546 putchar ('\n');
1547 exit (0);
1548}
1549
1550static void processListFieldsOption(const char *const option CTAGS_ATTR_UNUSED,
1551 const char *const parameter)
1552{
1553 struct colprintTable * table = fieldColprintTableNew ();
1554
1555 if (parameter [0] == '\0' || strcasecmp (parameter, RSV_LANG_ALL) == 0)
1556 {
1558
1560 for (unsigned int i = 0; i < countParsers (); i++)
1561 {
1562 if (isLanguageVisible(i))
1564 }
1565 }
1566 else
1567 {
1568 langType language = getNamedLanguage (parameter, 0);
1569 if (language == LANG_IGNORE)
1570 error (FATAL, "Unknown language \"%s\" in \"%s\" option", parameter, option);
1571
1572 initializeParser (language);
1573 fieldColprintAddLanguageLines (table, language);
1574 }
1575
1577 colprintTableDelete (table);
1578 exit (0);
1579}
1580
1582{
1583 if ((ctags_repoinfo == NULL)
1584 || (strcmp (ctags_repoinfo, PROGRAM_VERSION) == 0))
1585 printf ("%s %s, %s %s\n",
1588 else
1589 printf ("%s %s(%s), %s %s\n",
1592 printf ("Universal Ctags is derived from Exuberant Ctags.\n");
1593 printf ("Exuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert\n");
1594
1595 printf (" Compiled: %s, %s\n", __DATE__, __TIME__);
1596 printf (" URL: %s\n", PROGRAM_URL);
1597
1599}
1600
1602 const char *const option CTAGS_ATTR_UNUSED,
1603 const char *const parameter CTAGS_ATTR_UNUSED,
1604 bool includingExperimentalOptions)
1605{
1607 putchar ('\n');
1609 putchar ('\n');
1611 if (includingExperimentalOptions)
1613}
1614
1616 const char *const option,
1617 const char *const parameter)
1618{
1619 processHelpOptionCommon (option, parameter, false);
1620 exit (0);
1621}
1622
1624 const char *const option,
1625 const char *const parameter)
1626{
1627 processHelpOptionCommon (option, parameter, true);
1628 exit (0);
1629}
1630
1631#ifdef HAVE_JANSSON
1632static void processInteractiveOption (
1633 const char *const option CTAGS_ATTR_UNUSED,
1634 const char *const parameter)
1635{
1636 static struct interactiveModeArgs args;
1637
1638
1639 if (parameter && (strcmp (parameter, "sandbox") == 0))
1640 {
1641 Option.interactive = INTERACTIVE_SANDBOX;
1642 args.sandbox = true;
1643 }
1644 else if (parameter && (strcmp (parameter, "default") == 0))
1645 {
1646 Option.interactive = INTERACTIVE_DEFAULT;
1647 args.sandbox = false;
1648 }
1649 else if ((!parameter) || *parameter == '\0')
1650 {
1651 Option.interactive = INTERACTIVE_DEFAULT;
1652 args.sandbox = false;
1653 }
1654 else
1655 error (FATAL, "Unknown option argument \"%s\" for --%s option",
1656 parameter, option);
1657
1658#ifndef HAVE_SECCOMP
1659 if (args.sandbox)
1660 error (FATAL, "sandbox submode is not supported on this platform");
1661#endif
1662
1663#ifdef ENABLE_GCOV
1664 if (args.sandbox)
1665 error (FATAL, "sandbox submode does not work if gcov is instrumented");
1666#endif
1667
1673
1674 json_set_alloc_funcs (eMalloc, eFree);
1675}
1676#endif
1677
1678static void processIf0Option (const char *const option,
1679 const char *const parameter)
1680{
1681 bool if0 = getBooleanOption (option, parameter);
1682 langType lang = getNamedLanguage ("CPreProcessor", 0);
1683 const char *arg = if0? "true": "false";
1684
1685 applyParameter (lang, "if0", arg);
1686}
1687
1689 const char *const option, const char *const parameter)
1690{
1691 langType language;
1692 if (strcasecmp (parameter, RSV_LANG_AUTO) == 0)
1693 language = LANG_AUTO;
1694 else
1695 language = getNamedLanguage (parameter, 0);
1696
1697 if (strcmp (option, "lang") == 0 || strcmp (option, "language") == 0)
1698 error (WARNING,
1699 "\"--%s\" option is obsolete; use \"--language-force\" instead",
1700 option);
1701 if (language == LANG_IGNORE)
1702 error (FATAL, "Unknown language \"%s\" in \"%s\" option", parameter, option);
1703 else
1704 Option.language = language;
1705}
1706static char* skipPastMap (char* p)
1707{
1708 while (*p != EXTENSION_SEPARATOR &&
1709 *p != PATTERN_START && *p != ',' && *p != '\0')
1710 ++p;
1711 return p;
1712}
1713
1714/* Parses the mapping beginning at `map', adds it to the language map, and
1715 * returns first character past the map.
1716 */
1717static char* extractMapFromParameter (const langType language,
1718 char* parameter,
1719 char** tail,
1720 bool* pattern_p,
1721 char* (* skip) (char *))
1722{
1723 char* p = NULL;
1724 const char first = *parameter;
1725 char tmp;
1726 char* result;
1727
1728 if (first == EXTENSION_SEPARATOR) /* extension map */
1729 {
1730 *pattern_p = false;
1731
1732 ++parameter;
1733 p = (* skip) (parameter);
1734 if (*p == '\0')
1735 {
1736 result = eStrdup (parameter);
1737 *tail = parameter + strlen (parameter);
1738 return result;
1739 }
1740 else
1741 {
1742 tmp = *p;
1743 *p = '\0';
1744 result = eStrdup (parameter);
1745 *p = tmp;
1746 *tail = p;
1747 return result;
1748 }
1749 }
1750 else if (first == PATTERN_START) /* pattern map */
1751 {
1752 *pattern_p = true;
1753
1754 ++parameter;
1755 for (p = parameter ; *p != PATTERN_STOP && *p != '\0' ; ++p)
1756 {
1757 if (*p == '\\' && *(p + 1) == PATTERN_STOP)
1758 ++p;
1759 }
1760 if (*p == '\0')
1761 error (FATAL, "Unterminated file name pattern for %s language",
1762 getLanguageName (language));
1763 else
1764 {
1765 tmp = *p;
1766 *p = '\0';
1767 result = eStrdup (parameter);
1768 *p = tmp;
1769 *tail = p + 1;
1770 return result;
1771 }
1772 }
1773
1774 return NULL;
1775}
1776
1777static char* addLanguageMap (const langType language, char* map_parameter,
1778 bool exclusiveInAllLanguages)
1779{
1780 char* p = NULL;
1781 bool pattern_p;
1782 char* map;
1783
1784 map = extractMapFromParameter (language, map_parameter, &p, &pattern_p, skipPastMap);
1785 if (map && pattern_p == false)
1786 addLanguageExtensionMap (language, map, exclusiveInAllLanguages);
1787 else if (map && pattern_p == true)
1788 addLanguagePatternMap (language, map, exclusiveInAllLanguages);
1789 else
1790 error (FATAL, "Badly formed language map for %s language",
1791 getLanguageName (language));
1792
1793 if (map)
1794 eFree (map);
1795 return p;
1796}
1797
1798static char* removeLanguageMap (const langType language, char* map_parameter)
1799{
1800 char* p = NULL;
1801 bool pattern_p;
1802 char* map;
1803
1804 map = extractMapFromParameter (language, map_parameter, &p, &pattern_p, skipPastMap);
1805 if (map && pattern_p == false)
1806 removeLanguageExtensionMap (language, map);
1807 else if (map && pattern_p == true)
1808 removeLanguagePatternMap (language, map);
1809 else
1810 error (FATAL, "Badly formed language map for %s language",
1811 getLanguageName (language));
1812
1813 if (map)
1814 eFree (map);
1815 return p;
1816}
1817
1818static char* processLanguageMap (char* map)
1819{
1820 char* const separator = strchr (map, ':');
1821 char* result = NULL;
1822 if (separator != NULL)
1823 {
1824 langType language;
1825 char *list = separator + 1;
1826 bool clear = false;
1827 *separator = '\0';
1828 language = getNamedLanguage (map, 0);
1829 if (language != LANG_IGNORE)
1830 {
1831 const char *const deflt = RSV_LANGMAP_DEFAULT;
1832 char* p;
1833 if (*list == '+')
1834 ++list;
1835 else
1836 clear = true;
1837 for (p = list ; *p != ',' && *p != '\0' ; ++p) /*no-op*/ ;
1838 if ((size_t) (p - list) == strlen (deflt) &&
1839 strncasecmp (list, deflt, p - list) == 0)
1840 {
1841 verbose (" Restoring default %s language map: ", getLanguageName (language));
1842 installLanguageMapDefault (language);
1843 list = p;
1844 }
1845 else
1846 {
1847 if (clear)
1848 {
1849 verbose (" Setting %s language map:", getLanguageName (language));
1850 clearLanguageMap (language);
1851 }
1852 else
1853 verbose (" Adding to %s language map:", getLanguageName (language));
1854 while (list != NULL && *list != '\0' && *list != ',')
1855 list = addLanguageMap (language, list, true);
1856 verbose ("\n");
1857 }
1858 if (list != NULL && *list == ',')
1859 ++list;
1860 result = list;
1861 }
1862 }
1863 return result;
1864}
1865
1867 const char *const option, const char *const parameter)
1868{
1869 char *const maps = eStrdup (parameter);
1870 char *map = maps;
1871
1872 if (strcmp (parameter, RSV_LANGMAP_DEFAULT) == 0)
1873 {
1874 verbose (" Restoring default language maps:\n");
1876 }
1877 else while (map != NULL && *map != '\0')
1878 {
1879 char* const next = processLanguageMap (map);
1880 if (next == NULL)
1881 error (WARNING, "Unknown language \"%s\" in \"%s\" option", parameter, option);
1882 map = next;
1883 }
1884 eFree (maps);
1885}
1886
1888 const char *const option, const char *const parameter)
1889{
1890 char *const langs = eStrdup (parameter);
1891 enum { Add, Remove, Replace } mode = Replace;
1892 bool first = true;
1893 char *lang = langs;
1894 const char* prefix = "";
1895 verbose (" Enabled languages: ");
1896 while (lang != NULL)
1897 {
1898 char *const end = strchr (lang, ',');
1899 if (lang [0] == '+')
1900 {
1901 ++lang;
1902 mode = Add;
1903 prefix = "+ ";
1904 }
1905 else if (lang [0] == '-')
1906 {
1907 ++lang;
1908 mode = Remove;
1909 prefix = "- ";
1910 }
1911 if (mode == Replace)
1912 enableLanguages (false);
1913 if (end != NULL)
1914 *end = '\0';
1915 if (lang [0] != '\0')
1916 {
1917 if (strcmp (lang, RSV_LANG_ALL) == 0)
1918 enableLanguages ((bool) (mode != Remove));
1919 else
1920 {
1921 const langType language = getNamedLanguage (lang, 0);
1922 if (language == LANG_IGNORE)
1923 error (WARNING, "Unknown language \"%s\" in \"%s\" option", lang, option);
1924 else
1925 enableLanguage (language, (bool) (mode != Remove));
1926 }
1927 verbose ("%s%s%s", (first ? "" : ", "), prefix, lang);
1928 prefix = "";
1929 first = false;
1930 if (mode == Replace)
1931 mode = Add;
1932 }
1933 lang = (end != NULL ? end + 1 : NULL);
1934 }
1935 verbose ("\n");
1936 eFree (langs);
1937}
1938
1939extern bool processMapOption (
1940 const char *const option, const char *const parameter)
1941{
1942 langType language;
1943 const char* spec;
1944 char* map_parameter;
1945 bool clear = false;
1946 char op;
1947
1948 language = getLanguageComponentInOption (option, "map-");
1949 if (language == LANG_IGNORE)
1950 return false;
1951
1952 if (parameter == NULL || parameter [0] == '\0')
1953 error (FATAL, "no parameter is given for %s", option);
1954
1955 spec = parameter;
1956 if (*spec == '+' || *spec == '-')
1957 {
1958 op = *spec;
1959 spec++;
1960 }
1961 else
1962 {
1963 op = '\0';
1964 clear = true;
1965 }
1966
1967 if (clear)
1968 {
1969 verbose (" Setting %s language map:", getLanguageName (language));
1970 clearLanguageMap (language);
1971 op = '+';
1972 }
1973 else
1974 verbose (" %s %s %s %s language map:",
1975 op == '+'? "Adding": "Removing",
1976 spec,
1977 op == '+'? "to": "from",
1978 getLanguageName (language));
1979 map_parameter = eStrdup (spec);
1980
1981 if (op == '+')
1982 addLanguageMap (language, map_parameter, false);
1983 else if (op == '-')
1984 removeLanguageMap (language, map_parameter);
1985 else
1986 Assert ("Should not reach here" == NULL);
1987
1988 eFree (map_parameter);
1989 verbose ("\n");
1990
1991 return true;
1992}
1993
1995 const char *const option, const char *const value)
1996{
1997 langType language;
1998 const char* name;
1999 const char* sep;
2000
2001 language = getLanguageComponentInOption (option, "param-");
2002 if (language == LANG_IGNORE)
2003 return false;
2004
2005 sep = option + strlen ("param-") + strlen (getLanguageName (language));
2006 if (*sep != ':')
2007 error (FATAL, "no separator(:) is given for %s=%s", option, value);
2008 name = sep + 1;
2009
2010 if (value == NULL || value [0] == '\0')
2011 error (FATAL, "no parameter is given for %s", option);
2012
2013 applyParameter (language, name, value);
2014
2015 return true;
2016}
2017
2019 const char *const option CTAGS_ATTR_UNUSED,
2020 const char *const parameter CTAGS_ATTR_UNUSED)
2021{
2023 puts ("");
2024 puts (License1);
2025 puts (License2);
2026 exit (0);
2027}
2028
2030 const char *const option, const char *const parameter)
2031{
2032 if (parameter [0] == '\0' || strcasecmp (parameter, RSV_LANG_ALL) == 0)
2035 else
2036 {
2037 langType language = getNamedLanguage (parameter, 0);
2038 if (language == LANG_IGNORE)
2039 error (FATAL, "Unknown language \"%s\" in \"%s\" option", parameter, option);
2040 else
2041 printLanguageAliases (language,
2043 }
2044 exit (0);
2045}
2046
2048 const char *const option CTAGS_ATTR_UNUSED, const char *const parameter CTAGS_ATTR_UNUSED)
2049{
2050 struct colprintTable * table = xtagColprintTableNew ();
2051
2052 if (parameter [0] == '\0' || strcasecmp (parameter, RSV_LANG_ALL) == 0)
2053 {
2055
2057 for (unsigned int i = 0; i < countParsers (); i++)
2058 {
2059 if (isLanguageVisible(i))
2061 }
2062 }
2063 else
2064 {
2065 langType language = getNamedLanguage (parameter, 0);
2066 if (language == LANG_IGNORE)
2067 error (FATAL, "Unknown language \"%s\" in \"%s\" option", parameter, option);
2068
2069 initializeParser (language);
2070 xtagColprintAddLanguageLines (table, language);
2071 }
2072
2074 colprintTableDelete (table);
2075 exit (0);
2076}
2077
2079 const char *const option, const char *const parameter)
2080{
2081 bool print_all = (strcmp (option, "list-kinds-full") == 0)? true: false;
2082
2083 if (parameter [0] == '\0' || strcasecmp (parameter, RSV_LANG_ALL) == 0)
2084 printLanguageKinds (LANG_AUTO, print_all,
2086 else
2087 {
2088 langType language = getNamedLanguage (parameter, 0);
2089 if (language == LANG_IGNORE)
2090 error (FATAL, "Unknown language \"%s\" in \"%s\" option", parameter, option);
2091 else
2092 printLanguageKinds (language, print_all,
2094 }
2095 exit (0);
2096}
2097
2098static void processListParametersOption (const char *const option,
2099 const char *const parameter)
2100{
2101 if (parameter [0] == '\0' || strcasecmp (parameter, RSV_LANG_ALL) == 0)
2104 stdout);
2105 else
2106 {
2107 langType language = getNamedLanguage (parameter, 0);
2108 if (language == LANG_IGNORE)
2109 error (FATAL, "Unknown language \"%s\" in \"%s\" option", parameter, option);
2110 else
2111 printLanguageParameters (language,
2113 stdout);
2114 }
2115 exit (0);
2116}
2117
2118
2119static void processListMapsOptionForType (const char *const option CTAGS_ATTR_UNUSED,
2120 const char *const parameter,
2121 langmapType type)
2122{
2123 if (parameter [0] == '\0' || strcasecmp (parameter, RSV_LANG_ALL) == 0)
2126 stdout);
2127 else
2128 {
2129 langType language = getNamedLanguage (parameter, 0);
2130 if (language == LANG_IGNORE)
2131 error (FATAL, "Unknown language \"%s\" in \"%s\" option", parameter, option);
2132 else
2133 printLanguageMaps (language, type,
2135 stdout);
2136 }
2137 exit (0);
2138}
2139
2140static void processListMapExtensionsOption (const char *const option,
2141 const char *const parameter)
2142{
2144}
2145
2146static void processListMapPatternsOption (const char *const option,
2147 const char *const parameter)
2148{
2150}
2151
2153 const char *const option CTAGS_ATTR_UNUSED,
2154 const char *const parameter CTAGS_ATTR_UNUSED)
2155{
2156 processListMapsOptionForType (option, parameter, LMAP_ALL);
2157}
2158
2160 const char *const option CTAGS_ATTR_UNUSED,
2161 const char *const parameter CTAGS_ATTR_UNUSED)
2162{
2164 exit (0);
2165}
2166
2168 const char *const option CTAGS_ATTR_UNUSED,
2169 const char *const parameter CTAGS_ATTR_UNUSED)
2170{
2172 exit (0);
2173}
2174
2176 const char *const option CTAGS_ATTR_UNUSED,
2177 const char *const parameter CTAGS_ATTR_UNUSED)
2178{
2180 exit (0);
2181}
2182
2184 const char *const option CTAGS_ATTR_UNUSED,
2185 const char *const parameter CTAGS_ATTR_UNUSED)
2186{
2188 exit (0);
2189}
2190
2192 const char *const option CTAGS_ATTR_UNUSED,
2193 const char *const parameter CTAGS_ATTR_UNUSED)
2194{
2196 exit (0);
2197}
2198
2200 const char *const option CTAGS_ATTR_UNUSED,
2201 const char *const parameter CTAGS_ATTR_UNUSED)
2202{
2204 exit (0);
2205}
2206
2208 const char *const option CTAGS_ATTR_UNUSED,
2209 const char *const parameter CTAGS_ATTR_UNUSED)
2210{
2212 exit (0);
2213}
2214
2215static void processListRolesOptions (const char *const option CTAGS_ATTR_UNUSED,
2216 const char *const parameter)
2217{
2218 const char* sep;
2219 const char *kindspecs;
2220 langType lang;
2221
2222
2223 if (parameter == NULL || parameter[0] == '\0')
2224 {
2228 stdout);
2229 exit (0);
2230 }
2231
2232 sep = strchr (parameter, '.');
2233
2234 if (sep == NULL || sep [1] == '\0')
2235 {
2236 vString* vstr = vStringNewInit (parameter);
2237 vStringCatS (vstr, (sep? "*": ".*"));
2238 processListRolesOptions (option, vStringValue (vstr));
2239 /* The control should never reached here. */
2240 }
2241
2242 kindspecs = sep + 1;
2243 if (strncmp (parameter, "all.", 4) == 0
2244 /* Handle the case if no language is specified.
2245 * This case is not documented. */
2246 || strncmp (parameter, ".", 1) == 0)
2247 lang = LANG_AUTO;
2248 else
2249 {
2250 lang = getNamedLanguage (parameter, sep - parameter);
2251 if (lang == LANG_IGNORE)
2252 {
2253 const char *langName = eStrndup (parameter, sep - parameter);
2254 error (FATAL, "Unknown language \"%s\" in \"%s\"", langName, option);
2255 }
2256 }
2257 printLanguageRoles (lang, kindspecs,
2260 stdout);
2261 exit (0);
2262}
2263
2264static void processListSubparsersOptions (const char *const option CTAGS_ATTR_UNUSED,
2265 const char *const parameter)
2266{
2267 langType lang;
2268
2269
2270 if (parameter == NULL || parameter[0] == '\0'
2271 || (strcmp(parameter, RSV_LANG_ALL) == 0))
2272 {
2275 stdout);
2276 exit (0);
2277 }
2278
2279 lang = getNamedLanguage (parameter, 0);
2280 if (lang == LANG_IGNORE)
2281 error (FATAL, "Unknown language \"%s\" in \"%s\"", parameter, option);
2282
2285 stdout);
2286 exit (0);
2287}
2288
2289static void freeSearchPathList (searchPathList** pathList)
2290{
2291 stringListClear (*pathList);
2292 stringListDelete (*pathList);
2293 *pathList = NULL;
2294}
2295
2296static vString* expandOnSearchPathList (searchPathList *pathList, const char* leaf,
2297 bool (* check) (const char *const))
2298{
2299 unsigned int i;
2300
2301 for (i = stringListCount (pathList); i > 0; --i)
2302 {
2303 const char* const body = vStringValue (stringListItem (pathList, i - 1));
2304 char* tmp = combinePathAndFile (body, leaf);
2305
2306 if ((* check) (tmp))
2307 {
2308 vString *r = vStringNewOwn (tmp);
2309 return r;
2310 }
2311 else
2312 eFree (tmp);
2313 }
2314 return NULL;
2315}
2316
2317static vString* expandOnOptlibPathList (const char* leaf)
2318{
2319
2322}
2323
2325 const char *const option, const char *const parameter,
2326 bool allowNonExistingFile)
2327{
2328 const char* path;
2329 vString* vpath = NULL;
2330 fileStatus *status;
2331
2332 if (parameter [0] == '\0')
2333 error (FATAL, "no option file supplied for \"%s\"", option);
2334
2335 if (parameter [0] != '/' && parameter [0] != '.')
2336 {
2337 vpath = expandOnOptlibPathList (parameter);
2338 path = vpath? vStringValue (vpath): parameter;
2339 }
2340 else
2341 path = parameter;
2342
2343 status = eStat (path);
2344 if (!status->exists)
2345 {
2346 if (!allowNonExistingFile)
2347 error (FATAL | PERROR, "cannot stat \"%s\"", path);
2348 }
2349 else if (status->isDirectory)
2350 {
2352 error (FATAL | PERROR, "cannot open option directory \"%s\"", path);
2353 }
2354 else
2355 {
2356 if (!parseFileOptions (path))
2357 error (FATAL | PERROR, "cannot open option file \"%s\"", path);
2358 }
2359
2360 eStatFree (status);
2361 if (vpath)
2362 vStringDelete (vpath);
2363}
2364
2366 const char *const option, const char *const parameter)
2367{
2368 processOptionFileCommon(option, parameter, false);
2369}
2370
2372 const char *const option, const char *const parameter)
2373{
2374 processOptionFileCommon(option, parameter, true);
2375}
2376
2377static void processOutputFormat (const char *const option CTAGS_ATTR_UNUSED,
2378 const char *const parameter)
2379{
2380 if (parameter [0] == '\0')
2381 error (FATAL, "no output format name supplied for \"%s\"", option);
2382
2383 if (strcmp (parameter, "u-ctags") == 0)
2384 ;
2385 else if (strcmp (parameter, "e-ctags") == 0)
2387 else if (strcmp (parameter, "etags") == 0)
2388 setEtagsMode ();
2389 else if (strcmp (parameter, "xref") == 0)
2390 setXrefMode ();
2391#ifdef HAVE_JANSSON
2392 else if (strcmp (parameter, "json") == 0)
2393 setJsonMode ();
2394#endif
2395 else
2396 error (FATAL, "unknown output format name supplied for \"%s=%s\"", option, parameter);
2397}
2398
2399static void processPseudoTags (const char *const option CTAGS_ATTR_UNUSED,
2400 const char *const parameter)
2401{
2402 const char *p = parameter;
2403 bool s = true;
2404 ptagType t;
2405 vString *str = vStringNew();
2406
2407 if (*p == '\0' || !strchr ("*+-", *p))
2408 {
2409 for (unsigned int i = 0; i < PTAG_COUNT; i++)
2410 enablePtag (i, false);
2411 }
2412
2413 while (1)
2414 {
2415 if (*p == '\0')
2416 break;
2417
2418 if (*p == '*')
2419 {
2420 int i;
2421 for (i = 0; i < PTAG_COUNT; i++)
2422 enablePtag (i, true);
2423 p++;
2424 continue;
2425 }
2426 else if (*p == '-')
2427 {
2428 s= false;
2429 p++;
2430 continue;
2431 }
2432 else if (*p == '+')
2433 {
2434 s = true;
2435 p++;
2436 continue;
2437 }
2438 else if (*p == '{')
2439 {
2440 const char *origin = p;
2441
2442 p++;
2443 while (*p != '\0' && *p != '}')
2444 {
2445 vStringPut (str, *p);
2446 p++;
2447 }
2448 if (*p != '}')
2449 error (FATAL, "curly bracket specifying a pseudo tags is unbalanced: %s",
2450 origin);
2451 p++;
2452 }
2453 else
2454 {
2455 vStringCopyS (str, p);
2456 p += vStringLength (str);
2457 }
2458
2459 char *name = vStringValue (str);
2461 if (t == PTAG_UNKNOWN)
2462 error (FATAL, "Unknown pseudo tag name: %s", name);
2463 enablePtag (t, s);
2464 vStringClear (str);
2465 }
2466 vStringDelete (str);
2467}
2468
2470 const char *const option, const char *const parameter)
2471{
2472 if (isFalse (parameter))
2474 else if (isTrue (parameter))
2476 else if (strcasecmp (parameter, "f") == 0 ||
2477 strcasecmp (parameter, "fold") == 0 ||
2478 strcasecmp (parameter, "foldcase") == 0)
2480 else
2481 error (FATAL, "Invalid value for \"%s\" option", option);
2482}
2483
2485 const char *const option, const char *const parameter)
2486{
2487 if (isFalse (parameter))
2489 else if (isTrue (parameter) || *parameter == '\0')
2491 else if (strcasecmp (parameter, "always") == 0)
2493 else if (strcasecmp (parameter, "never") == 0)
2495 else
2496 error (FATAL, "Invalid value for \"%s\" option", option);
2497}
2498
2499static void processTotals (
2500 const char *const option, const char *const parameter)
2501{
2502 if (isFalse (parameter))
2503 Option.printTotals = 0;
2504 else if (isTrue (parameter) || *parameter == '\0')
2505 Option.printTotals = 1;
2506 else if (strcasecmp (parameter, "extra") == 0)
2507 Option.printTotals = 2;
2508 else
2509 error (FATAL, "Invalid value for \"%s\" option", option);
2510}
2511
2513{
2515
2516 BEGIN_VERBOSE(vfp);
2517 {
2518 fprintf (vfp, " Setting default header extensions: ");
2520 putc ('\n', vfp);
2521 }
2522 END_VERBOSE();
2523}
2524
2525static void processHeaderListOption (const int option, const char *parameter)
2526{
2527 /* Check to make sure that the user did not enter "ctags -h *.c"
2528 * by testing to see if the list is a filename that exists.
2529 */
2530 if (doesFileExist (parameter))
2531 error (FATAL, "-%c: Invalid list", option);
2532 if (strcmp (parameter, "default") == 0)
2534 else
2535 {
2536 bool clear = true;
2537
2538 if (parameter [0] == '+')
2539 {
2540 ++parameter;
2541 clear = false;
2542 }
2543 if (Option.headerExt == NULL)
2545 verbose (" Header Extensions:\n");
2546 addExtensionList (Option.headerExt, parameter, clear);
2547 }
2548}
2549
2550/*
2551 * Token ignore processing
2552 */
2553static void readIgnoreList (const char *const list)
2554{
2555 langType lang = getNamedLanguage ("CPreProcessor", 0);
2556 char* newList = stringCopy (list);
2557 const char *token = strtok (newList, IGNORE_SEPARATORS);
2558
2559 while (token != NULL)
2560 {
2561 applyParameter (lang, "ignore", token);
2562 token = strtok (NULL, IGNORE_SEPARATORS);
2563 }
2564 eFree (newList);
2565}
2566
2567static void addIgnoreListFromFile (const char *const fileName)
2568{
2569 langType lang = getNamedLanguage ("CPreProcessor", 0);
2570
2571 stringList* tokens = stringListNewFromFile (fileName);
2572 if (tokens == NULL)
2573 error (FATAL | PERROR, "cannot open \"%s\"", fileName);
2574
2575 int c = stringListCount(tokens);
2576 int i;
2577
2578 for(i=0;i<c;i++)
2579 {
2580 vString * s = stringListItem(tokens,i);
2581 applyParameter (lang, "ignore", vStringValue(s));
2582 }
2583
2584 stringListDelete(tokens);
2585}
2586
2587static void processIgnoreOption (const char *const list, int IgnoreOrDefine)
2588{
2589 langType lang = getNamedLanguage ("CPreProcessor", 0);
2590
2591 if (IgnoreOrDefine == 'D')
2592 applyParameter (lang, "define", list);
2593 else if (strchr ("@./\\", list [0]) != NULL)
2594 {
2595 const char* fileName = (*list == '@') ? list + 1 : list;
2596 addIgnoreListFromFile (fileName);
2597 }
2598#if defined (WIN32)
2599 else if (isalpha (list [0]) && list [1] == ':')
2601#endif
2602 else if (strcmp (list, "-") == 0)
2603 applyParameter (lang, "ignore", NULL);
2604 else
2606}
2607
2608static void processAnonHashOption (const char *const option CTAGS_ATTR_UNUSED, const char *const parameter CTAGS_ATTR_UNUSED)
2609{
2610 if (parameter == NULL || parameter[0] == '\0')
2611 error (FATAL, "Something string is needed for \"%s\" option", option);
2612 char buf [9];
2613
2614 anonHashString (parameter, buf);
2615 printf("%s\n", buf);
2616 exit (0);
2617}
2618
2619static void processDumpKeywordsOption (const char *const option CTAGS_ATTR_UNUSED, const char *const parameter CTAGS_ATTR_UNUSED)
2620{
2621 dumpKeywordTable (stdout);
2622}
2623
2624static void processEchoOption (const char *const option, const char *const parameter)
2625{
2626 if (parameter == NULL || parameter[0] == '\0')
2627 error (FATAL, "Something message is needed for \"%s\" option", option);
2628 notice ("%s", parameter);
2629}
2630
2631static void processForceInitOption (const char *const option CTAGS_ATTR_UNUSED,
2632 const char *const parameter CTAGS_ATTR_UNUSED)
2633{
2634 verbose ("force initializing all built-in parsers\n");
2636}
2637
2638static void processForceQuitOption (const char *const option CTAGS_ATTR_UNUSED,
2639 const char *const parameter)
2640{
2641 int s;
2642 if (parameter == NULL || parameter[0] == '\0' || !strToInt(parameter, 0, &s))
2643 s = 0;
2644 exit (s);
2645}
2646
2648 const char *const option CTAGS_ATTR_UNUSED,
2649 const char *const parameter CTAGS_ATTR_UNUSED)
2650{
2652 exit (0);
2653}
2654
2655#ifdef DO_TRACING
2656static void processTraceOption(const char *const option CTAGS_ATTR_UNUSED,
2657 const char *const parameter)
2658{
2659 const char *langs = eStrdup (parameter);
2660 const char *lang = langs;
2661
2662 traceMain();
2663
2664 while (lang != NULL)
2665 {
2666 if (*lang == '\0')
2667 break;
2668 if (*lang == ',')
2669 {
2670 lang++;
2671 continue;
2672 }
2673
2674 char *const end = strchr (lang, ',');
2675
2676 if (end != NULL)
2677 *end = '\0';
2678
2679 const langType language = getNamedLanguage (lang, 0);
2680 if (language == LANG_IGNORE)
2681 error (WARNING, "Unknown language \"%s\" in \"%s\" option", lang, option);
2682 else
2683 {
2684 traceLanguage (language);
2685 verbose ("Enable tracing language: %s\n", lang);
2686
2687 }
2688 lang = (end != NULL ? end + 1 : NULL);
2689 }
2690 eFree ((char *)langs);
2691}
2692#endif
2693
2694static void processXformatOption (const char *const option CTAGS_ATTR_UNUSED,
2695 const char *const parameter)
2696{
2697 if (Option.customXfmt)
2699
2700 Option.customXfmt = fmtNew (parameter);
2701}
2702
2703static void prependToOptlibPathList (const char *const dir, bool report_in_verbose)
2704{
2705 vString *elt = vStringNewInit (dir);
2706
2707 if (report_in_verbose)
2708 verbose ("Prepend %s to %s\n",
2709 dir, "OptlibPathList");
2710
2712}
2713
2714static void resetOptlibPathList (bool report_in_verbose)
2715{
2717 if (report_in_verbose)
2718 verbose ("Reset OptlibPathList\n");
2720}
2721
2722static void processOptlibDir (
2723 const char *const option, const char *const parameter)
2724{
2725 const char* path;
2726
2727 Assert (parameter);
2728
2729
2730 if (parameter[0] == '\0')
2731 resetOptlibPathList (true);
2732 else if (parameter[0] == '+')
2733 {
2734 path = parameter + 1;
2735 if (path[0] == '\0')
2736 return;
2737 prependToOptlibPathList (path, true);
2738 }
2739 else
2740 {
2741 resetOptlibPathList (true);
2742 path = parameter;
2743 prependToOptlibPathList (path, true);
2744 }
2745}
2746
2747static void processMaxRecursionDepthOption (const char *const option, const char *const parameter)
2748{
2749 if (parameter == NULL || parameter[0] == '\0')
2750 error (FATAL, "A parameter is needed after \"%s\" option", option);
2751
2752 if (atol (parameter) < 1)
2753 error (FATAL, "-%s: Invalid maximum recursion depth", option);
2754
2755 Option.maxRecursionDepth = atol(parameter);
2756}
2757
2758static void processPatternLengthLimit(const char *const option, const char *const parameter)
2759{
2760 if (parameter == NULL || parameter[0] == '\0')
2761 error (FATAL, "A parameter is needed after \"%s\" option", option);
2762
2763 if (!strToUInt(parameter, 0, &Option.patternLengthLimit))
2764 error (FATAL, "-%s: Invalid pattern length limit", option);
2765}
2766
2768 const void *data)
2769{
2770 const optionValues *opt = data;
2771 char buf [21];
2772
2773 if (snprintf (buf, 21, "%u", opt->patternLengthLimit) >= 0)
2774 return writePseudoTag (pdesc, buf, "0 for no limit", NULL);
2775 return false;
2776}
2777
2778static void setBooleanToXtagWithWarning(booleanOption *const option, bool value)
2779{
2780 /* WARNING/TODO: This function breaks capsulization. */
2781
2782 char x = 0;
2783
2784 if (strcmp (option->name, "file-tags") == 0)
2785 x = 'f';
2786 else if (strcmp (option->name, "file-scope") == 0)
2787 x = 'F';
2788
2789 if (x)
2790 error (WARNING, "\"--%s\" option is obsolete; use \"--extras=%c%c\" instead",
2791 option->name, value? '+': '-', x);
2792
2793 xtagType t = (xtagType)option->pValue;
2794 enableXtag (t, value);
2795}
2796
2797/*
2798 * Option tables
2799 */
2800
2801static void processDumpOptionsOption (const char *const option, const char *const parameter);
2802
2804 { "etags-include", processEtagsInclude, false, STAGE_ANY },
2805 { "exclude", processExcludeOption, false, STAGE_ANY },
2806 { "exclude-exception", processExcludeExceptionOption, false, STAGE_ANY },
2807 { "excmd", processExcmdOption, false, STAGE_ANY },
2808 { "extra", processExtraTagsOption, false, STAGE_ANY },
2809 { "extras", processExtraTagsOption, false, STAGE_ANY },
2810 { "fields", processFieldsOption, false, STAGE_ANY },
2811 { "filter-terminator", processFilterTerminatorOption, true, STAGE_ANY },
2812 { "format", processFormatOption, true, STAGE_ANY },
2813 { "help", processHelpOption, true, STAGE_ANY },
2814 { "help-full", processHelpFullOption, true, STAGE_ANY },
2815 { "if0", processIf0Option, false, STAGE_ANY },
2816#ifdef HAVE_ICONV
2817 { "input-encoding", processInputEncodingOption, false, STAGE_ANY },
2818 { "output-encoding", processOutputEncodingOption, false, STAGE_ANY },
2819#endif
2820 { "lang", processLanguageForceOption, false, STAGE_ANY },
2821 { "language", processLanguageForceOption, false, STAGE_ANY },
2822 { "language-force", processLanguageForceOption, false, STAGE_ANY },
2823 { "languages", processLanguagesOption, false, STAGE_ANY },
2824 { "langdef", processLanguageDefineOption, false, STAGE_ANY },
2825 { "langmap", processLanguageMapOption, false, STAGE_ANY },
2826 { "license", processLicenseOption, true, STAGE_ANY },
2827 { "list-aliases", processListAliasesOption, true, STAGE_ANY },
2828 { "list-excludes", processListExcludesOption, true, STAGE_ANY },
2829 { "list-extras", processListExtrasOption, true, STAGE_ANY },
2830 { "list-features", processListFeaturesOption, true, STAGE_ANY },
2831 { "list-fields", processListFieldsOption, true, STAGE_ANY },
2832 { "list-kinds", processListKindsOption, true, STAGE_ANY },
2833 { "list-kinds-full", processListKindsOption, true, STAGE_ANY },
2834 { "list-languages", processListLanguagesOption, true, STAGE_ANY },
2835 { "list-maps", processListMapsOption, true, STAGE_ANY },
2836 { "list-map-extensions", processListMapExtensionsOption, true, STAGE_ANY },
2837 { "list-map-patterns", processListMapPatternsOption, true, STAGE_ANY },
2838 { "list-mline-regex-flags", processListMultilineRegexFlagsOptions, true, STAGE_ANY },
2839 { "list-params", processListParametersOption, true, STAGE_ANY },
2840 { "list-pseudo-tags", processListPseudoTagsOptions, true, STAGE_ANY },
2841 { "list-regex-flags", processListRegexFlagsOptions, true, STAGE_ANY },
2842 { "list-roles", processListRolesOptions, true, STAGE_ANY },
2843 { "list-subparsers", processListSubparsersOptions, true, STAGE_ANY },
2844 { "maxdepth", processMaxRecursionDepthOption, true, STAGE_ANY },
2845 { "optlib-dir", processOptlibDir, false, STAGE_ANY },
2846 { "options", processOptionFile, false, STAGE_ANY },
2847 { "options-maybe", processOptionFileMaybe, false, STAGE_ANY },
2848 { "output-format", processOutputFormat, true, STAGE_ANY },
2849 { "pattern-length-limit", processPatternLengthLimit, true, STAGE_ANY },
2850 { "pseudo-tags", processPseudoTags, false, STAGE_ANY },
2851 { "sort", processSortOption, true, STAGE_ANY },
2852 { "tag-relative", processTagRelative, true, STAGE_ANY },
2853 { "totals", processTotals, true, STAGE_ANY },
2854 { "version", processVersionOption, true, STAGE_ANY },
2855 { "_anonhash", processAnonHashOption, false, STAGE_ANY },
2856 { "_dump-keywords", processDumpKeywordsOption, false, STAGE_ANY },
2857 { "_dump-options", processDumpOptionsOption, false, STAGE_ANY },
2858 { "_echo", processEchoOption, false, STAGE_ANY },
2859 { "_force-initializing", processForceInitOption, false, STAGE_ANY },
2860 { "_force-quit", processForceQuitOption, false, STAGE_ANY },
2861#ifdef HAVE_JANSSON
2862 { "_interactive", processInteractiveOption, true, STAGE_ANY },
2863#endif
2864 { "_list-kinddef-flags", processListKinddefFlagsOptions, true, STAGE_ANY },
2865 { "_list-langdef-flags", processListLangdefFlagsOptions, true, STAGE_ANY },
2866 { "_list-mtable-regex-flags", processListMultitableRegexFlagsOptions, true, STAGE_ANY },
2867#ifdef DO_TRACING
2868 { "_trace", processTraceOption, false, STAGE_ANY },
2869#endif
2870 { "_xformat", processXformatOption, false, STAGE_ANY },
2871};
2872
2874 { "append", &Option.append, true, STAGE_ANY },
2875 { "file-scope", ((bool *)XTAG_FILE_SCOPE), false, STAGE_ANY, setBooleanToXtagWithWarning },
2876 { "file-tags", ((bool *)XTAG_FILE_NAMES), false, STAGE_ANY, setBooleanToXtagWithWarning },
2877 { "filter", &Option.filter, true, STAGE_ANY },
2878 { "guess-language-eagerly", &Option.guessLanguageEagerly, false, STAGE_ANY },
2879 { "line-directives",&Option.lineDirectives, false, STAGE_ANY },
2880 { "links", &Option.followLinks, false, STAGE_ANY },
2881 { "machinable", &localOption.machinable, true, STAGE_ANY },
2882 { "put-field-prefix", &Option.putFieldPrefix, false, STAGE_ANY },
2883 { "print-language", &Option.printLanguage, true, STAGE_ANY },
2884 { "quiet", &Option.quiet, false, STAGE_ANY },
2885#ifdef RECURSE_SUPPORTED
2886 { "recurse", &Option.recurse, false, STAGE_ANY },
2887#endif
2888 { "verbose", &ctags_verbose, false, STAGE_ANY },
2889#ifdef WIN32
2890 { "use-slash-as-filename-separator", (bool *)&Option.useSlashAsFilenameSeparator, false, STAGE_ANY },
2891#endif
2892 { "with-list-header", &localOption.withListHeader, true, STAGE_ANY },
2893 { "_fatal-warnings",&Option.fatalWarnings, false, STAGE_ANY },
2894};
2895
2896/*
2897 * Generic option parsing
2898 */
2899
2900static void checkOptionOrder (const char* const option, bool longOption)
2901{
2903 error (FATAL, "-%s%s option may not follow a file name", longOption? "-": "", option);
2904}
2905
2907 const char *const option, const char *const parameter)
2908{
2909 const int count = sizeof (ParametricOptions) / sizeof (parametricOption);
2910 bool found = false;
2911 int i;
2912
2913 for (i = 0 ; i < count && ! found ; ++i)
2914 {
2916 if (strcmp (option, entry->name) == 0)
2917 {
2918 found = true;
2919 if (!(entry->acceptableStages & (1UL << Stage)))
2920 {
2921 error (WARNING, "Cannot use --%s option in %s",
2922 option, StageDescription[Stage]);
2923 break;
2924 }
2925 if (entry->initOnly)
2926 checkOptionOrder (option, true);
2927 (entry->handler) (option, parameter);
2928 }
2929 }
2930 return found;
2931}
2932
2933static bool getBooleanOption (
2934 const char *const option, const char *const parameter)
2935{
2936 return paramParserBool (parameter, true, option, "option");
2937}
2938
2940 const char *const option, const char *const parameter)
2941{
2942 const int count = sizeof (BooleanOptions) / sizeof (booleanOption);
2943 bool found = false;
2944 int i;
2945
2946 for (i = 0 ; i < count && ! found ; ++i)
2947 {
2948 booleanOption* const entry = &BooleanOptions [i];
2949 if (strcmp (option, entry->name) == 0)
2950 {
2951 found = true;
2952 if (!(entry->acceptableStages & (1UL << Stage)))
2953 {
2954 error (WARNING, "Cannot use --%s option in %s",
2955 option, StageDescription[Stage]);
2956 break;
2957 }
2958 if (entry->initOnly)
2959 checkOptionOrder (option, true);
2960
2961 bool value = getBooleanOption (option, parameter);
2962 if (entry->set)
2963 entry->set (entry, value);
2964 else
2965 *entry->pValue = value;
2966 }
2967 }
2968 return found;
2969}
2970
2971static void enableLanguageField (langType language, const char *field, bool mode)
2972{
2973
2974 fieldType t;
2975
2976 t = getFieldTypeForNameAndLanguage (field, language);
2977 if (t == FIELD_UNKNOWN)
2978 error(FATAL, "no such field: \'%s\'", field);
2979 enableField (t, mode, (language != LANG_AUTO));
2980 if (language == LANG_AUTO)
2981 {
2982 fieldType ftype_next = t;
2983
2984 while ((ftype_next = nextSiblingField (ftype_next)) != FIELD_UNKNOWN)
2985 enableField (ftype_next, mode, (language != LANG_AUTO));
2986 }
2987}
2988
2989static void enableLanguageXtag (langType language, const char *xtag, bool mode)
2990{
2991
2992 xtagType x;
2993
2994 x = getXtagTypeForNameAndLanguage (xtag, language);
2995 if (x == XTAG_UNKNOWN)
2996 error(FATAL, "no such extra: \'%s\'", xtag);
2997 enableXtag (x, mode);
2998 if (language == LANG_AUTO)
2999 {
3000 xtagType xtag_next = x;
3001
3002 while ((xtag_next = nextSiblingXtag (xtag_next)) != XTAG_UNKNOWN)
3003 enableXtag (xtag_next, mode);
3004 }
3005}
3006
3007static bool processLangSpecificFieldsOption (const char *const option,
3008 const char *const parameter)
3009{
3010#define PREFIX "fields-"
3011#define PREFIX_LEN strlen(PREFIX)
3012 const char* lang;
3013 size_t len;
3014 langType language = LANG_IGNORE;
3015 const char *p = parameter;
3016 int c;
3017 static vString * longName;
3018 bool mode = true;
3019 const char *f;
3020 bool inLongName = false;
3021
3022 if ( strncmp (option, PREFIX, PREFIX_LEN) != 0 )
3023 return false;
3024
3025 lang = option + PREFIX_LEN;
3026 len = strlen (lang);
3027 if (len == 0)
3028 error (FATAL, "No language given in \"%s\" option", option);
3029 else if (len == strlen(RSV_LANG_ALL) && (strncmp(lang, RSV_LANG_ALL, len) == 0))
3030 language = LANG_AUTO;
3031 else
3032 language = getNamedLanguage (lang, len);
3033
3034 if (language == LANG_IGNORE)
3035 {
3036 error (WARNING, "Unknown language: %s (ignoring \"--%s\")", lang, option);
3037 /* The option is consumed in this function. */
3038 return true;
3039 }
3040
3041 initializeParser (language);
3042
3043 if (*p == '*')
3044 {
3045 resetFieldsOption (language, true);
3046 p++;
3047 }
3048 else if (*p == '{' || *p == '\0')
3049 {
3050 resetFieldsOption (language, false);
3051 if (*p == '\0')
3052 return true;
3053 }
3054 else if (*p != '+' && *p != '-')
3055 error (WARNING, "Wrong per language field specification: %s", p);
3056
3057 longName = vStringNewOrClearWithAutoRelease (longName);
3058 while ((c = *p++) != '\0')
3059 {
3060 switch (c)
3061 {
3062 case '+':
3063 if (inLongName)
3064 vStringPut (longName, c);
3065 else
3066 mode = true;
3067 break;
3068 case '-':
3069 if (inLongName)
3070 vStringPut (longName, c);
3071 else
3072 mode = false;
3073 break;
3074 case '{':
3075 if (inLongName)
3076 error (FATAL,
3077 "unexpected character in field specification: \'%c\'",
3078 c);
3079 inLongName = true;
3080 break;
3081 case '}':
3082 if (!inLongName)
3083 error (FATAL,
3084 "unexpected character in field specification: \'%c\'",
3085 c);
3086
3087 f = vStringValue (longName);
3088 enableLanguageField (language, f, mode);
3089 inLongName = false;
3090 vStringClear (longName);
3091 break;
3092 default:
3093 if (inLongName)
3094 vStringPut (longName, c);
3095 else
3096 error (FATAL,
3097 "only long name can be used in per language field spec: \'%c\'",
3098 c);
3099 break;
3100 }
3101 }
3102#undef PREFIX_LEN
3103#undef PREFIX
3104 return true;
3105}
3106
3107static bool processLangSpecificExtraOption (const char *const option,
3108 const char *const parameter)
3109{
3110#define PREFIX "extras-"
3111#define PREFIX_LEN strlen(PREFIX)
3112 const char* lang;
3113 size_t len;
3114 langType language = LANG_IGNORE;
3115 const char *p = parameter;
3116 int c;
3117 static vString * longName;
3118 bool mode = true;
3119 const char *x;
3120 bool inLongName = false;
3121
3122 if ( strncmp (option, PREFIX, PREFIX_LEN) != 0 )
3123 return false;
3124
3125 lang = option + PREFIX_LEN;
3126 len = strlen (lang);
3127
3128 if (len == 0)
3129 error (FATAL, "No language given in \"%s\" option", option);
3130 else if (len == strlen(RSV_LANG_ALL) && (strncmp(lang, RSV_LANG_ALL, len) == 0))
3131 language = LANG_AUTO;
3132 else
3133 language = getNamedLanguage (lang, len);
3134
3135 if (language == LANG_IGNORE)
3136 {
3137 error (WARNING, "Unknown language: %s (ignoring \"--%s\")", lang, option);
3138 /* The option is consumed in this function. */
3139 return true;
3140 }
3141
3142 initializeParser (language);
3143
3144 if (*p == '*')
3145 {
3146 resetXtags (language, true);
3147 p++;
3148 }
3149 else if (*p == '{' || *p == '\0')
3150 {
3151 resetXtags (language, false);
3152 if (*p == '\0')
3153 return true;
3154 }
3155 else if (*p != '+' && *p != '-')
3156 error (WARNING, "Wrong per language extra specification: %s", p);
3157
3158 longName = vStringNewOrClearWithAutoRelease (longName);
3159 while ((c = *p++) != '\0')
3160 {
3161 switch (c)
3162 {
3163 case '+':
3164 if (inLongName)
3165 vStringPut (longName, c);
3166 else
3167 mode = true;
3168 break;
3169 case '-':
3170 if (inLongName)
3171 vStringPut (longName, c);
3172 else
3173 mode = false;
3174 break;
3175 case '{':
3176 if (inLongName)
3177 error (FATAL,
3178 "unexpected character in extra specification: \'%c\'",
3179 c);
3180 inLongName = true;
3181 break;
3182 case '}':
3183 if (!inLongName)
3184 error (FATAL,
3185 "unexpected character in extra specification: \'%c\'",
3186 c);
3187
3188 x = vStringValue (longName);
3189 enableLanguageXtag (language, x, mode);
3190 inLongName = false;
3191 vStringClear (longName);
3192 break;
3193 default:
3194 if (inLongName)
3195 vStringPut (longName, c);
3196 else
3197 error (FATAL,
3198 "only long name can be used in per language extra spec: \'%c\'",
3199 c);
3200 break;
3201 }
3202 }
3203 return true;
3204}
3205
3206static bool processRegexOption (const char *const option,
3207 const char *const parameter)
3208{
3209 langType language;
3210
3211 language = getLanguageComponentInOption (option, "regex-");
3212 if (language == LANG_IGNORE)
3213 return false;
3214
3216
3217 return true;
3218}
3219
3220static bool processMultilineRegexOption (const char *const option,
3221 const char *const parameter)
3222{
3223 langType language;
3224
3225 language = getLanguageComponentInOption (option, "mline-regex-");
3226 if (language == LANG_IGNORE)
3227 return false;
3228
3230
3231 return true;
3232}
3233
3234static bool processMultitableRegexOption (const char *const option,
3235 const char *const parameter)
3236{
3237 langType language;
3238
3239 language = getLanguageComponentInOption (option, "_mtable-regex-");
3240 if (language == LANG_IGNORE)
3241 return false;
3242
3244
3245 return true;
3246}
3247
3248static bool processMultitableExtendingOption (const char *const option,
3249 const char *const parameter)
3250{
3251 langType language;
3252
3253 language = getLanguageComponentInOption (option, "_mtable-extend-");
3254 if (language == LANG_IGNORE)
3255 return false;
3256
3257 processLanguageMultitableExtendingOption (language, parameter);
3258
3259 return true;
3260}
3261
3263 const char *const option, const char *const parameter)
3264{
3265 Assert (parameter != NULL);
3266 Assert (option != NULL);
3267
3268 if (parameter [0] == '\0')
3269 verbose (" Option: --%s\n", option);
3270 else
3271 verbose (" Option: --%s=%s\n", option, parameter);
3272
3273 if (processBooleanOption (option, parameter))
3274 ;
3275 else if (processLangSpecificFieldsOption(option, parameter))
3276 ;
3277 else if (processExtradefOption(option, parameter))
3278 ;
3279 else if (processFielddefOption(option, parameter))
3280 ;
3281 else if (processLangSpecificExtraOption(option, parameter))
3282 ;
3283 else if (processParametricOption (option, parameter))
3284 ;
3285 else if (processKinddefOption (option, parameter))
3286 ;
3287 else if (processKindsOption (option, parameter))
3288 ;
3289 else if (processAliasOption (option, parameter))
3290 ;
3291 else if (processRegexOption (option, parameter))
3292 ;
3293 else if (processMultilineRegexOption (option, parameter))
3294 ;
3295 else if (processMapOption (option, parameter))
3296 ;
3297 else if (processParamOption (option, parameter))
3298 ;
3299 else if (processTabledefOption (option, parameter))
3300 ;
3301 else if (processMultitableRegexOption (option, parameter))
3302 ;
3303 else if (processMultitableExtendingOption (option, parameter))
3304 ;
3305#ifdef HAVE_ICONV
3306 else if (processLanguageEncodingOption (option, parameter))
3307 ;
3308#endif
3309#ifndef RECURSE_SUPPORTED
3310 else if (strcmp (option, "recurse") == 0)
3311 error (WARNING, "%s option not supported on this host", option);
3312#endif
3313 else if (processRoledefOption (option, parameter))
3314 ;
3315 else if (processScopesepOption (option, parameter))
3316 ;
3317 else if (processPretendOption (option, parameter))
3318 ;
3319 else if (processRolesOption (option, parameter))
3320 ;
3321 else
3322 error (FATAL, "Unknown option: --%s", option);
3323}
3324
3326 const char *const option, const char *const parameter)
3327{
3328 if (parameter == NULL || parameter [0] == '\0')
3329 verbose (" Option: -%s\n", option);
3330 else
3331 verbose (" Option: -%s %s\n", option, parameter);
3332
3333 if (isCompoundOption (*option) && (parameter == NULL || parameter [0] == '\0'))
3334 error (FATAL, "Missing parameter for \"%s\" option", option);
3335 else switch (*option)
3336 {
3337 case '?':
3338 processHelpOption ("?", NULL);
3339 exit (0);
3340 break;
3341 case 'a':
3342 checkOptionOrder (option, false);
3343 Option.append = true;
3344 break;
3345#ifdef DEBUG
3346 case 'b':
3347 if (atol (parameter) < 0)
3348 error (FATAL, "-%s: Invalid line number", option);
3349 Option.breakLine = atol (parameter);
3350 break;
3351 case 'd':
3352 if (!strToLong(parameter, 0, &ctags_debugLevel))
3353 error (FATAL, "-%s: Invalid debug level", option);
3354
3355 if (debug (DEBUG_STATUS))
3356 ctags_verbose = true;
3357 break;
3358#endif
3359 case 'B':
3360 Option.backward = true;
3361 break;
3362 case 'D':
3363 processIgnoreOption (parameter, *option);
3364 break;
3365 case 'e':
3366 checkOptionOrder (option, false);
3367 setEtagsMode ();
3368 break;
3369 case 'f':
3370 case 'o':
3371 checkOptionOrder (option, false);
3372 if (Option.tagFileName != NULL)
3373 {
3374 error (WARNING,
3375 "-%s option specified more than once, last value used",
3376 option);
3378 }
3379 else if (parameter [0] == '-' && parameter [1] != '\0')
3380 error (FATAL, "output file name may not begin with a '-'");
3381 Option.tagFileName = stringCopy (parameter);
3382 break;
3383 case 'F':
3384 Option.backward = false;
3385 break;
3386 case 'G':
3388 break;
3389 case 'h':
3390 processHeaderListOption (*option, parameter);
3391 break;
3392 case 'I':
3393 processIgnoreOption (parameter, *option);
3394 break;
3395 case 'L':
3396 if (Option.fileList != NULL)
3397 {
3398 error (WARNING,
3399 "-%s option specified more than once, last value used",
3400 option);
3402 }
3403 Option.fileList = stringCopy (parameter);
3404 break;
3405 case 'n':
3407 break;
3408 case 'N':
3410 break;
3411 case 'R':
3412#ifdef RECURSE_SUPPORTED
3413 Option.recurse = true;
3414#else
3415 error (WARNING, "-%s option not supported on this host", option);
3416#endif
3417 break;
3418 case 'u':
3419 checkOptionOrder (option, false);
3421 break;
3422 case 'V':
3423 ctags_verbose = true;
3424 break;
3425 case 'w':
3426 /* silently ignored */
3427 break;
3428 case 'x':
3429 checkOptionOrder (option, false);
3430 setXrefMode ();
3431 break;
3432 default:
3433 error (FATAL, "Unknown option: -%s", option);
3434 break;
3435 }
3436}
3437
3438static void parseOption (cookedArgs* const args)
3439{
3440 Assert (! cArgOff (args));
3441 if (args->isOption)
3442 {
3443 if (args->longOption)
3444 processLongOption (args->item, args->parameter);
3445 else
3446 {
3447 const char *parameter = args->parameter;
3448 while (*parameter == ' ')
3449 ++parameter;
3450 processShortOption (args->item, parameter);
3451 }
3452 cArgForth (args);
3453 }
3454}
3455
3456static void parseOptions (cookedArgs* const args)
3457{
3458 while (! cArgOff (args) && cArgIsOption (args))
3459 parseOption (args);
3460 if (! cArgOff (args) && ! cArgIsOption (args))
3461 NonOptionEncountered = true;
3462}
3463
3464extern void parseCmdlineOptions (cookedArgs* const args)
3465{
3466 ENTER (Cmdline);
3467 parseOptions (args);
3468}
3469
3470static bool checkSameFile (const char *const fileName, void * userData)
3471{
3472 return isSameFile ((const char* const) userData, fileName);
3473}
3474
3475static bool parseFileOptions (const char* const fileName)
3476{
3477 bool fileFound = false;
3478 const char* const format = "Considering option file %s: %s\n";
3479 if (stringListHasTest (OptionFiles, checkSameFile, (void *) fileName))
3480 {
3481 verbose (format, fileName, "already considered");
3482 fileFound = true;
3483 }
3484 else
3485 {
3486 FILE* const fp = fopen (fileName, "r");
3487 if (fp == NULL)
3488 verbose (format, fileName, "not found");
3489 else
3490 {
3491 cookedArgs* const args = cArgNewFromLineFile (fp);
3492 vString* file = vStringNewInit (fileName);
3493 stringListAdd (OptionFiles, file);
3494 verbose (format, fileName, "reading...");
3495 parseOptions (args);
3497 error (WARNING, "Ignoring non-option in %s\n", fileName);
3498 cArgDelete (args);
3499 fclose (fp);
3500 fileFound = true;
3501 }
3502 }
3503 return fileFound;
3504}
3505
3506/* Actions to be taken before reading any other options */
3507extern void previewFirstOption (cookedArgs* const args)
3508{
3509 while (cArgIsOption (args))
3510 {
3511 if (strcmp (args->item, "V") == 0
3512 || strcmp (args->item, "verbose") == 0
3513 || strcmp (args->item, "quiet") == 0)
3514 parseOption (args);
3515 else if (strcmp (args->item, "options") == 0 &&
3516 strcmp (args->parameter, RSV_NONE) == 0)
3517 {
3518 notice ("No options will be read from files or environment");
3519 SkipConfiguration = true;
3520 cArgForth (args);
3521 }
3522 else
3523 break;
3524 }
3525}
3526
3527#if defined (HAVE_DIRENT_H) || defined (_MSC_VER)
3528extern int scanDirectory (const char *directory_name,
3529 struct dirent ***array_pointer, int (*select_function) (const struct dirent *),
3530 int (*compare_function) (const struct dirent **, const struct dirent **));
3531
3532static void parseConfigurationFileOptionsInDirectoryWithLeafname (const char* directory, const char* leafname)
3533{
3534 char* pathname = combinePathAndFile (directory, leafname);
3535 parseFileOptions (pathname);
3536 eFree (pathname);
3537}
3538
3539static int ignore_dot_file(const struct dirent* dent)
3540{
3541 /* Ignore a file which name is started from dot. */
3542 if (*dent->d_name == '.')
3543 return 0;
3544 else
3545 return 1;
3546}
3547
3548static int accept_only_dot_ctags(const struct dirent* dent)
3549{
3550 size_t len;
3551
3552 /* accept only a file ended with ".ctags" */
3553 len = strlen(dent->d_name);
3554
3555 if (len < 7)
3556 return 0;
3557 if (strcmp(dent->d_name + (len - 6), ".ctags") == 0)
3558 return 1;
3559
3560 return 0;
3561}
3562
3563static int alphaSort(const struct dirent ** a,
3564 const struct dirent ** b)
3565{
3566 return strcmp ((*a)->d_name, (*b)->d_name);
3567}
3568
3569static bool parseAllConfigurationFilesOptionsInDirectory (const char* const dirName,
3570 stringList* const already_loaded_files)
3571{
3572 struct dirent **dents;
3573 int i, n;
3574
3575 n = scanDirectory (dirName, &dents, ignore_dot_file, alphaSort);
3576 if (n < 0)
3577 return false;
3578
3579 for (i = 0; i < n; i++)
3580 {
3581 char* path;
3582 fileStatus *s;
3583
3584 if (already_loaded_files && stringListHas (already_loaded_files, dents[i]->d_name))
3585 continue;
3586 else if (already_loaded_files)
3587 stringListAdd (already_loaded_files, vStringNewInit (dents[i]->d_name));
3588
3589 path = combinePathAndFile (dirName, dents[i]->d_name);
3590 s = eStat (path);
3591
3592 if (s->exists && accept_only_dot_ctags(dents[i]))
3593 parseConfigurationFileOptionsInDirectoryWithLeafname (dirName,
3594 dents[i]->d_name);
3595 eStatFree (s);
3596 free (dents[i]);
3597 eFree (path);
3598 }
3599 free (dents);
3600 return true;
3601}
3602#else
3603static bool parseAllConfigurationFilesOptionsInDirectory (const char* const dirName,
3604 stringList* const already_loaded_files)
3605{
3606 return false;
3607}
3608#endif
3609
3610typedef char* (* preloadMakePathFunc) (const char*, const char*);
3611
3613 const char *path; /* NULL means the end of list */
3616 const char *extra;
3618};
3619
3620static char* prependEnvvar (const char *path, const char* envvar)
3621{
3622 char *full_path = NULL;
3623
3624 const char* const envval = getenv (envvar);
3625 if (envval && strlen (envval))
3626 full_path = combinePathAndFile(envval, path);
3627
3628 return full_path;
3629}
3630
3631#ifndef WIN32
3632static char *getConfigForXDG (const char *path CTAGS_ATTR_UNUSED,
3633 const char* extra CTAGS_ATTR_UNUSED)
3634{
3635 char *r = prependEnvvar ("ctags", "XDG_CONFIG_HOME");
3636 if (r)
3637 return r;
3638
3639 return prependEnvvar (".config/ctags", "HOME");
3640}
3641#endif
3642
3643#ifdef WIN32
3644static char *getConfigAtHomeOnWindows (const char *path,
3645 const char* extra CTAGS_ATTR_UNUSED)
3646{
3647 /*
3648 * Windows users don't usually set HOME.
3649 * The OS sets HOMEDRIVE and HOMEPATH for them.
3650 */
3651 const char* homeDrive = getenv ("HOMEDRIVE");
3652 const char* homePath = getenv ("HOMEPATH");
3653 if (homeDrive != NULL && homePath != NULL)
3654 {
3655 vString* const windowsHome = vStringNew ();
3656 vStringCatS (windowsHome, homeDrive);
3657 vStringCatS (windowsHome, homePath);
3658
3659 char *tmp = vStringIsEmpty (windowsHome)
3660 ? NULL
3661 : combinePathAndFile (vStringValue(windowsHome), path);
3662
3663 vStringDelete (windowsHome);
3664 return tmp;
3665 }
3666 return NULL;
3667}
3668#endif
3669
3670static void preload (struct preloadPathElt *pathList)
3671{
3672 unsigned int i;
3674
3675 loaded = stringListNew ();
3676 for (i = 0; pathList[i].path != NULL || pathList[i].makePath != NULL; ++i)
3677 {
3678 struct preloadPathElt *elt = pathList + i;
3679 preloadMakePathFunc maker = elt->makePath;
3680 const char *path = elt->path;
3681
3682
3683 if (maker)
3684 path = maker(elt->path, elt->extra);
3685
3686 if (path == NULL)
3687 continue;
3688
3689 Assert (Stage <= elt->stage);
3690 if (Stage != elt->stage)
3691 {
3692 Stage = elt->stage;
3693 verbose ("Entering configuration stage: loading %s\n", StageDescription[Stage]);
3694 }
3695
3696 if (elt->isDirectory)
3698 else
3700
3701 if (path != elt->path)
3702 eFree ((void *)path);
3703 }
3706}
3707
3709#ifdef CUSTOM_CONFIGURATION_FILE
3710 {
3711 .path = CUSTOM_CONFIGURATION_FILE,
3712 .isDirectory = false,
3713 .makePath = NULL,
3714 .stage = OptionLoadingStageCustom,
3715 },
3716#endif
3717#ifndef WIN32
3718 {
3719 .path = NULL,
3720 .isDirectory = true,
3721 .makePath = getConfigForXDG,
3722 .stage = OptionLoadingStageXdg,
3723 },
3724#endif
3725 {
3726 .path = ".ctags.d",
3727 .isDirectory = true,
3728 .makePath = prependEnvvar,
3729 .extra = "HOME",
3731 },
3732#ifdef WIN32
3733 {
3734 .path = "ctags.d",
3735 .isDirectory = true,
3736 .makePath = getConfigAtHomeOnWindows,
3737 .extra = NULL,
3739 },
3740#endif
3741 {
3742 .path = ".ctags.d",
3743 .isDirectory = true,
3744 .makePath = NULL,
3746 },
3747 {
3748 .path = "ctags.d",
3749 .isDirectory = true,
3750 .makePath = NULL,
3752 },
3753 {
3754 .path = NULL,
3755 .makePath = NULL,
3756 },
3757};
3758
3760{
3762}
3763
3764static void parseEnvironmentOptions (void)
3765{
3766 const char *envOptions = NULL;
3767 const char* var = NULL;
3768
3769 ENTER(EnvVar);
3770 if (Option.etags)
3771 {
3772 var = ETAGS_ENVIRONMENT;
3773 envOptions = getenv (var);
3774 }
3775 if (envOptions == NULL)
3776 {
3777 var = CTAGS_ENVIRONMENT;
3778 envOptions = getenv (var);
3779 }
3780 if (envOptions != NULL && envOptions [0] != '\0')
3781 {
3782 cookedArgs* const args = cArgNewFromString (envOptions);
3783 verbose ("Reading options from $CTAGS\n");
3784 parseOptions (args);
3785 cArgDelete (args);
3787 error (WARNING, "Ignoring non-option in %s variable", var);
3788 }
3789}
3790
3791extern void readOptionConfiguration (void)
3792{
3793 if (! SkipConfiguration)
3794 {
3797 }
3798}
3799
3800/*
3801* Option initialization
3802*/
3803
3804extern void initOptions (void)
3805{
3808
3809 verbose ("Setting option defaults\n");
3811 verbose (" Installing default language mappings:\n");
3813 verbose (" Installing default language aliases:\n");
3815
3816 /* always excluded by default */
3817 verbose (" Installing default exclude patterns:\n");
3818 processExcludeOption (NULL, "{arch}");
3819 processExcludeOption (NULL, ".arch-ids");
3820 processExcludeOption (NULL, ".arch-inventory");
3821 processExcludeOption (NULL, "autom4te.cache");
3822 processExcludeOption (NULL, "BitKeeper");
3823 processExcludeOption (NULL, ".bzr");
3824 processExcludeOption (NULL, ".bzrignore");
3825 processExcludeOption (NULL, "CVS");
3826 processExcludeOption (NULL, ".cvsignore");
3827 processExcludeOption (NULL, "_darcs");
3828 processExcludeOption (NULL, ".deps");
3829 processExcludeOption (NULL, ".dvi");
3830 processExcludeOption (NULL, ".DS_Store");
3831 processExcludeOption (NULL, "EIFGEN");
3832 processExcludeOption (NULL, ".git");
3833 processExcludeOption (NULL, ".gitignore");
3834 processExcludeOption (NULL, ".gitattributes");
3835 processExcludeOption (NULL, ".hg");
3836 processExcludeOption (NULL, ".hgignore");
3837 processExcludeOption (NULL, "PENDING");
3838 processExcludeOption (NULL, "RCS");
3839 processExcludeOption (NULL, "RESYNC");
3840 processExcludeOption (NULL, "SCCS");
3841 processExcludeOption (NULL, ".svn");
3842 processExcludeOption (NULL, "*~");
3843 processExcludeOption (NULL, ".*.swp");
3844
3845 /* Exclude binary files
3846 * -----------------------------------------------
3847 *
3848 * TODO
3849 *
3850 * It will be interesting if ctags can extract
3851 * symbols from these binaries.
3852 *
3853 * --langdef=nm --regex-nm=...
3854 * --langdef=elf --pre-processor-elf=/bin/nm ...
3855 *
3856 * vim/emacs users never wants the cursor to jump to
3857 * a binary file but may wants to utilize the symbol
3858 * information for completion.
3859 *
3860 * https://bitbucket.org/haypo/hachoir3 can be
3861 * used the alternative for /bin/nm
3862 */
3863 processExcludeOption (NULL, "*.o");
3864 processExcludeOption (NULL, "*.a");
3865 processExcludeOption (NULL, "*.so");
3866
3867 processExcludeOption (NULL, "*.obj");
3868 processExcludeOption (NULL, "*.lib");
3869 processExcludeOption (NULL, "*.dll");
3870 processExcludeOption (NULL, "*.exe");
3871
3872 processExcludeOption (NULL, "*.gcno");
3873 processExcludeOption (NULL, "*.gcda");
3874
3875 processExcludeOption (NULL, "*.class");
3876
3877 processExcludeOption (NULL, "*.pyc");
3878 processExcludeOption (NULL, "*.pyo");
3879}
3880
3881extern void freeOptionResources (void)
3882{
3886
3887 freeList (&Excluded);
3891
3893
3895}
3896
3897static void processDumpOptionsOption (const char *const option CTAGS_ATTR_UNUSED, const char *const parameter CTAGS_ATTR_UNUSED)
3898{
3899 fprintf(stdout, "# %s\n", "ParametricOptions");
3900 for (unsigned int i = 0; i < ARRAY_SIZE(ParametricOptions); i++)
3901 fprintf(stdout, "%s\n", ParametricOptions[i].name);
3902
3903 fprintf(stdout, "# %s\n", "BooleanOptions");
3904 for (unsigned int i = 0; i < ARRAY_SIZE(BooleanOptions); i++)
3905 fprintf(stdout, "%s\n", BooleanOptions[i].name);
3906}
3907
3908extern bool inSandbox (void)
3909{
3910 return (Option.interactive == INTERACTIVE_SANDBOX);
3911}
3912
3914{
3915 return (Option.locate != EX_PATTERN);
3916}
3917
3918extern bool isDestinationStdout (void)
3919{
3920 bool toStdout = false;
3921
3923 (Option.tagFileName != NULL && (strcmp (Option.tagFileName, "-") == 0
3924 || strcmp (Option.tagFileName, "/dev/stdout") == 0
3925 )))
3926 toStdout = true;
3927 else if (Option.tagFileName == NULL && NULL == outputDefaultFileName ())
3928 toStdout = true;
3929
3930 return toStdout;
3931}
void argDelete(Arguments *const current)
Definition: args.c:282
Arguments * argNewFromLineFile(FILE *const fp)
Definition: args.c:220
void argForth(Arguments *const current)
Definition: args.c:256
bool argOff(const Arguments *const current)
Definition: args.c:238
char * argItem(const Arguments *const current)
Definition: args.c:231
Arguments * argNewFromString(const char *const string)
Definition: args.c:189
Arguments * argNewFromFile(FILE *const fp)
Definition: args.c:210
Arguments * argNewFromArgv(char *const *const argv)
Definition: args.c:199
void colprintLineAppendColumnCString(struct colprintLine *line, const char *column)
Definition: colprint.c:254
void colprintTableSort(struct colprintTable *table, int(*compareFn)(struct colprintLine *, struct colprintLine *))
Definition: colprint.c:235
struct colprintLine * colprintTableGetNewLine(struct colprintTable *table)
Definition: colprint.c:240
void colprintTableDelete(struct colprintTable *table)
Definition: colprint.c:109
struct colprintTable * colprintTableNew(const char *columnHeader,...)
Definition: colprint.c:73
void colprintLineAppendColumnVString(struct colprintLine *line, vString *column)
Definition: colprint.c:260
void colprintTablePrint(struct colprintTable *table, unsigned int startFrom, bool withHeader, bool machinable, FILE *fp)
Definition: colprint.c:227
const char * colprintLineGetColumn(struct colprintLine *line, unsigned int column)
Definition: colprint.c:285
void setMainLoop(mainLoopFunc func, void *data)
Definition: main.c:324
const char * ctags_repoinfo
Definition: repoinfo.c:12
#define PROGRAM_URL
Definition: ctags.h:23
#define PROGRAM_VERSION
Definition: ctags.h:20
#define PROGRAM_COPYRIGHT
Definition: ctags.h:24
#define PROGRAM_NAME
Definition: ctags.h:22
#define CTAGS_FIELD_PREFIX
Definition: ctags.h:31
#define AUTHOR_NAME
Definition: ctags.h:25
#define RSV_LANG_ALL
Definition: ctags.h:37
#define RSV_LANGMAP_DEFAULT
Definition: ctags.h:36
#define RSV_LANG_AUTO
Definition: ctags.h:38
#define RSV_NONE
Definition: ctags.h:39
default
Definition: filetypes.c:4
#define Assert(c)
Definition: debug.h:47
@ DEBUG_STATUS
Definition: debug.h:67
const gchar * name
Definition: document.c:3219
gboolean loaded
Definition: document.c:3221
bool writePseudoTag(const ptagDesc *desc, const char *const fileName, const char *const pattern, const char *const parserName)
Definition: entry.c:1568
#define field(x)
void error(const errorSelection selection, const char *const format,...)
Definition: error.c:53
void setErrorPrinter(errorPrintFunc printer, void *data)
Definition: error.c:27
struct colprintTable * fieldColprintTableNew(void)
Definition: field.c:1105
int countFields(void)
Definition: field.c:1011
void fieldColprintAddLanguageLines(struct colprintTable *table, langType language)
Definition: field.c:1152
bool enableField(fieldType type, bool state, bool warnIfFixedField)
Definition: field.c:950
fieldType getFieldTypeForOption(char letter)
Definition: field.c:308
fieldType nextSiblingField(fieldType type)
Definition: field.c:1016
void fieldColprintAddCommonLines(struct colprintTable *table)
Definition: field.c:1146
int getFieldOwner(fieldType type)
Definition: field.c:993
void fieldColprintTablePrint(struct colprintTable *table, bool withListHeader, bool machinable, FILE *fp)
Definition: field.c:1232
fieldType getFieldTypeForNameAndLanguage(const char *fieldName, langType language)
Definition: field.c:325
enum eFieldType fieldType
@ FIELD_UNKNOWN
Definition: field.h:29
static void clear(void)
Definition: filebrowser.c:302
fmtElement * fmtNew(const char *fmtString)
Definition: fmt.c:248
void fmtDelete(fmtElement *fmtelts)
Definition: fmt.c:377
#define CTAGS_ATTR_UNUSED
Definition: gcc-attr.h:22
vString * line
Definition: geany_cobol.c:133
CobolFormat format
Definition: geany_cobol.c:137
unsigned int count
tokenInfo * list
unsigned int max
static parseNext fallback
Definition: geany_objc.c:412
static bool tail(const char *cp)
Definition: geany_pascal.c:70
#define strncasecmp(s1, s2, n)
Definition: general.h:45
#define strcasecmp(s1, s2)
Definition: general.h:37
void interactiveLoop(cookedArgs *args, void *user)
bool jsonErrorPrinter(const errorSelection selection, const char *const format, va_list ap, void *data)
void dumpKeywordTable(FILE *fp)
Definition: keyword.c:245
static gboolean dummy
Definition: libmain.c:115
void printMultitableRegexFlags(bool withListHeader, bool machinable, FILE *fp)
Definition: lregex.c:2216
bool checkRegex(void)
Definition: lregex.c:2768
void printRegexFlags(bool withListHeader, bool machinable, FILE *fp)
Definition: lregex.c:2185
void printMultilineRegexFlags(bool withListHeader, bool machinable, FILE *fp)
Definition: lregex.c:2201
@ REG_PARSER_SINGLE_LINE
Definition: lregex_p.h:29
@ REG_PARSER_MULTI_TABLE
Definition: lregex_p.h:31
@ REG_PARSER_MULTI_LINE
Definition: lregex_p.h:30
#define PATTERN_START
Definition: options.c:61
#define ETAGS_ENVIRONMENT
Definition: options.c:52
stringList searchPathList
Definition: options.c:123
static bool parseFileOptions(const char *const fileName)
Definition: options.c:3475
static void freeString(char **const pString)
Definition: options.c:688
static void installHeaderListDefaults(void)
Definition: options.c:2512
static char * processLanguageMap(char *map)
Definition: options.c:1818
#define ETAGS
Definition: options.c:55
static bool parseAllConfigurationFilesOptionsInDirectory(const char *const fileName, stringList *const already_loaded_files)
Definition: options.c:3603
static void processListSubparsersOptions(const char *const option, const char *const parameter)
Definition: options.c:2264
static void processListPseudoTagsOptions(const char *const option, const char *const parameter)
Definition: options.c:2167
static void readIgnoreList(const char *const list)
Definition: options.c:2553
static vString * expandOnSearchPathList(searchPathList *pathList, const char *leaf, bool(*check)(const char *const))
Definition: options.c:2296
static bool NonOptionEncountered
Definition: options.c:120
static void processListLanguagesOption(const char *const option, const char *const parameter)
Definition: options.c:2159
#define va_copy(dest, src)
Definition: options.c:613
int asprintf(char **strp, const char *fmt,...)
Definition: options.c:616
cookedArgs * cArgNewFromArgv(char *const *const argv)
Definition: options.c:938
static void setEtagsMode(void)
Definition: options.c:807
const struct sBooleanOption booleanOption
eOptionLimits
Definition: options.c:89
@ MaxSupportedTagFormat
Definition: options.c:91
@ MaxHeaderExtensions
Definition: options.c:90
static void checkOptionOrder(const char *const option, bool longOption)
Definition: options.c:2900
const char * cArgItem(cookedArgs *const current)
Definition: options.c:996
static const char *const License2
Definition: options.c:509
static void processListRegexFlagsOptions(const char *const option, const char *const parameter)
Definition: options.c:2175
static optionDescription LongOptionDescription[]
Definition: options.c:199
bool cArgOff(cookedArgs *const current)
Definition: options.c:984
langType getLanguageComponentInOptionFull(const char *const option, const char *const prefix, bool noPretending)
Definition: options.c:762
static bool SkipConfiguration
Definition: options.c:128
void parseCmdlineOptions(cookedArgs *const args)
Definition: options.c:3464
#define CTAGS_ENVIRONMENT
Definition: options.c:51
static void processSortOption(const char *const option, const char *const parameter)
Definition: options.c:2469
#define PREFIX_LEN
static bool isTrue(const char *parameter)
Definition: options.c:1083
bool canUseLineNumberAsLocator(void)
Definition: options.c:3913
static void processDumpKeywordsOption(const char *const option, const char *const parameter)
Definition: options.c:2619
static void processExcludeOptionCommon(stringList **list, const char *const optname, const char *const parameter)
Definition: options.c:1142
static void processFieldsOption(const char *const option, const char *const parameter)
Definition: options.c:1331
static bool processMultitableRegexOption(const char *const option, const char *const parameter)
Definition: options.c:3234
static void processListMapPatternsOption(const char *const option, const char *const parameter)
Definition: options.c:2146
static void processHeaderListOption(const int option, const char *parameter)
Definition: options.c:2525
void testEtagsInvocation(void)
Definition: options.c:817
void freeList(stringList **const pList)
Definition: options.c:697
static void processListMultitableRegexFlagsOptions(const char *const option, const char *const parameter)
Definition: options.c:2191
static void resetXtags(langType lang, bool mode)
Definition: options.c:1233
static int excludesCompare(struct colprintLine *a, struct colprintLine *b)
Definition: options.c:1467
static void processEtagsInclude(const char *const option, const char *const parameter)
Definition: options.c:1127
static void processAnonHashOption(const char *const option, const char *const parameter)
Definition: options.c:2608
static int featureCompare(struct colprintLine *a, struct colprintLine *b)
Definition: options.c:1517
static void processForceQuitOption(const char *const option, const char *const parameter)
Definition: options.c:2638
static void resetFieldsOption(langType lang, bool mode)
Definition: options.c:1322
struct localOptionValues localOption
static void cArgRead(cookedArgs *const current)
Definition: options.c:894
static stringList * Excluded
Definition: options.c:126
static bool checkSameFile(const char *const fileName, void *userData)
Definition: options.c:3470
static bool processBooleanOption(const char *const option, const char *const parameter)
Definition: options.c:2939
static void printOptionDescriptions(const optionDescription *const optDesc)
Definition: options.c:1456
static void processFilterTerminatorOption(const char *const option, const char *const parameter)
Definition: options.c:1408
static void processExtraTagsOption(const char *const option, const char *const parameter)
Definition: options.c:1241
static bool processMultilineRegexOption(const char *const option, const char *const parameter)
Definition: options.c:3220
cookedArgs * cArgNewFromFile(FILE *const fp)
Definition: options.c:947
bool isIncludeFile(const char *const fileName)
Definition: options.c:1114
static void addExtensionList(stringList *const slist, const char *const elist, const bool clear)
Definition: options.c:1031
long ctags_debugLevel
Definition: options.c:134
bool ctags_verbose
Definition: options.c:135
#define STAGE_ANY
Definition: options.c:193
static void processExcmdOption(const char *const option, const char *const parameter)
Definition: options.c:1216
void notice(const char *const format,...)
Definition: options.c:666
bool paramParserBool(const char *value, bool fallback, const char *errWhat, const char *errCategory)
Definition: options.c:1093
static void processOptionFileMaybe(const char *const option, const char *const parameter)
Definition: options.c:2371
static bool processParametricOption(const char *const option, const char *const parameter)
Definition: options.c:2906
static struct Feature Features[]
static void processOptlibDir(const char *const option, const char *const parameter)
Definition: options.c:2722
bool filesRequired(void)
Definition: options.c:722
#define isCompoundOption(c)
Definition: options.c:73
static void enableLanguageField(langType language, const char *field, bool mode)
Definition: options.c:2971
static booleanOption BooleanOptions[]
Definition: options.c:2873
static const char *const License1
Definition: options.c:503
void previewFirstOption(cookedArgs *const args)
Definition: options.c:3507
static void processEchoOption(const char *const option, const char *const parameter)
Definition: options.c:2624
static void processListLangdefFlagsOptions(const char *const option, const char *const parameter)
Definition: options.c:2199
cookedArgs * cArgNewFromLineFile(FILE *const fp)
Definition: options.c:956
bool ptagMakePatternLengthLimit(ptagDesc *pdesc, langType language, const void *data)
Definition: options.c:2767
static bool processRegexOption(const char *const option, const char *const parameter)
Definition: options.c:3206
static void addIgnoreListFromFile(const char *const fileName)
Definition: options.c:2567
static void processListMapExtensionsOption(const char *const option, const char *const parameter)
Definition: options.c:2140
static const char *const StageDescription[]
Definition: options.c:577
static void processListKindsOption(const char *const option, const char *const parameter)
Definition: options.c:2078
#define ENTER(STAGE)
Definition: options.c:75
void initOptions(void)
Definition: options.c:3804
static char * extractMapFromParameter(const langType language, char *parameter, char **tail, bool *pattern_p, char *(*skip)(char *))
Definition: options.c:1717
static bool processMultitableExtendingOption(const char *const option, const char *const parameter)
Definition: options.c:3248
static void processPseudoTags(const char *const option, const char *const parameter)
Definition: options.c:2399
void checkOptions(void)
Definition: options.c:730
static void processOutputFormat(const char *const option, const char *const parameter)
Definition: options.c:2377
static void processListKinddefFlagsOptions(const char *const option, const char *const parameter)
Definition: options.c:2207
static stringList * OptionFiles
Definition: options.c:121
static char * skipPastMap(char *p)
Definition: options.c:1706
void verbose(const char *const format,...)
Definition: options.c:655
void cArgDelete(cookedArgs *const current)
Definition: options.c:965
static bool FilesRequired
Definition: options.c:127
static void processListRolesOptions(const char *const option, const char *const parameter)
Definition: options.c:2215
static const char *const HeaderExtensions[]
Definition: options.c:130
static void processListExcludesOption(const char *const option, const char *const parameter)
Definition: options.c:1472
static void resetOptlibPathList(bool report_in_verbose)
Definition: options.c:2714
static void processListMapsOption(const char *const option, const char *const parameter)
Definition: options.c:2152
static void parseShortOption(cookedArgs *const args)
Definition: options.c:854
static void processListExtrasOption(const char *const option, const char *const parameter)
Definition: options.c:2047
static void processMaxRecursionDepthOption(const char *const option, const char *const parameter)
Definition: options.c:2747
static void enableLanguageXtag(langType language, const char *xtag, bool mode)
Definition: options.c:2989
bool cArgIsOption(cookedArgs *const current)
Definition: options.c:990
static void processLanguagesOption(const char *const option, const char *const parameter)
Definition: options.c:1887
static void processLanguageMapOption(const char *const option, const char *const parameter)
Definition: options.c:1866
static void processListFieldsOption(const char *const option, const char *const parameter)
Definition: options.c:1550
static void processHelpOption(const char *const option, const char *const parameter)
Definition: options.c:1615
static void processExcludeExceptionOption(const char *const option, const char *const parameter)
Definition: options.c:1178
static void processForceInitOption(const char *const option, const char *const parameter)
Definition: options.c:2631
bool inSandbox(void)
Definition: options.c:3908
static char * stringCopy(const char *const string)
Definition: options.c:680
#define PATTERN_STOP
Definition: options.c:62
static stringList * ExcludedException
Definition: options.c:126
void(* parametricOptionHandler)(const char *const option, const char *const parameter)
Definition: options.c:99
static searchPathList * OptlibPathList
Definition: options.c:124
#define DEFAULT_FILE_FORMAT
Definition: options.c:66
static OptionLoadingStage Stage
Definition: options.c:192
static bool getBooleanOption(const char *const option, const char *const parameter)
Definition: options.c:2933
static void preload(struct preloadPathElt *pathList)
Definition: options.c:3670
static void processListMultilineRegexFlagsOptions(const char *const option, const char *const parameter)
Definition: options.c:2183
void cArgForth(cookedArgs *const current)
Definition: options.c:1002
static char * getConfigForXDG(const char *path, const char *extra)
Definition: options.c:3632
bool processMapOption(const char *const option, const char *const parameter)
Definition: options.c:1939
struct sOptionDescription optionDescription
static void processHelpOptionCommon(const char *const option, const char *const parameter, bool includingExperimentalOptions)
Definition: options.c:1601
static void setBooleanToXtagWithWarning(booleanOption *const option, bool value)
Definition: options.c:2778
void setDefaultTagFileName(void)
Definition: options.c:706
static void processFormatOption(const char *const option, const char *const parameter)
Definition: options.c:1415
static void processListAliasesOption(const char *const option, const char *const parameter)
Definition: options.c:2029
static void processLicenseOption(const char *const option, const char *const parameter)
Definition: options.c:2018
static void freeSearchPathList(searchPathList **pathList)
Definition: options.c:2289
char *(* preloadMakePathFunc)(const char *, const char *)
Definition: options.c:3610
static void processLongOption(const char *const option, const char *const parameter)
Definition: options.c:3262
bool isDestinationStdout(void)
Definition: options.c:3918
static void setXrefMode(void)
Definition: options.c:834
static parametricOption ParametricOptions[]
Definition: options.c:2803
static void processPatternLengthLimit(const char *const option, const char *const parameter)
Definition: options.c:2758
static void processShortOption(const char *const option, const char *const parameter)
Definition: options.c:3325
static char * addLanguageMap(const langType language, char *map_parameter, bool exclusiveInAllLanguages)
Definition: options.c:1777
static bool processLangSpecificFieldsOption(const char *const option, const char *const parameter)
Definition: options.c:3007
static char * prependEnvvar(const char *path, const char *envvar)
Definition: options.c:3620
static optionDescription ExperimentalLongOptionDescription[]
Definition: options.c:441
static void processListParametersOption(const char *const option, const char *const parameter)
Definition: options.c:2098
static void processOptionFileCommon(const char *const option, const char *const parameter, bool allowNonExistingFile)
Definition: options.c:2324
void readOptionConfiguration(void)
Definition: options.c:3791
static char * removeLanguageMap(const langType language, char *map_parameter)
Definition: options.c:1798
static void processHelpFullOption(const char *const option, const char *const parameter)
Definition: options.c:1623
static bool processLangSpecificExtraOption(const char *const option, const char *const parameter)
Definition: options.c:3107
langType getLanguageComponentInOption(const char *const option, const char *const prefix)
Definition: options.c:801
static void parseLongOption(cookedArgs *const args, const char *item)
Definition: options.c:877
optionValues Option
Definition: options.c:137
static void printProgramIdentification(void)
Definition: options.c:1581
bool isExcludedFile(const char *const name, bool falseIfExceptionsAreDefeind)
Definition: options.c:1184
static void processDumpOptionsOption(const char *const option, const char *const parameter)
Definition: options.c:3897
#define PREFIX
static void prependToOptlibPathList(const char *const dir, bool report_in_verbose)
Definition: options.c:2703
bool processParamOption(const char *const option, const char *const value)
Definition: options.c:1994
void freeOptionResources(void)
Definition: options.c:3881
static void printInvocationDescription(void)
Definition: options.c:1451
static vString * expandOnOptlibPathList(const char *leaf)
Definition: options.c:2317
static void processOptionFile(const char *const option, const char *const parameter)
Definition: options.c:2365
static bool isFalse(const char *parameter)
Definition: options.c:1073
static struct preloadPathElt preload_path_list[]
Definition: options.c:3708
static void processVersionOption(const char *const option, const char *const parameter)
Definition: options.c:2647
static void parseConfigurationFileOptions(void)
Definition: options.c:3759
static void processIgnoreOption(const char *const list, int IgnoreOrDefine)
Definition: options.c:2587
static void printFeatureList(void)
Definition: options.c:1497
static void parseEnvironmentOptions(void)
Definition: options.c:3764
static bool cArgOptionPending(cookedArgs *const current)
Definition: options.c:975
static void processLanguageForceOption(const char *const option, const char *const parameter)
Definition: options.c:1688
static void processListFeaturesOption(const char *const option, const char *const parameter)
Definition: options.c:1523
static void parseOptions(cookedArgs *const args)
Definition: options.c:3456
#define IGNORE_SEPARATORS
Definition: options.c:63
static void processIf0Option(const char *const option, const char *const parameter)
Definition: options.c:1678
static void parseOption(cookedArgs *const args)
Definition: options.c:3438
static void processExcludeOption(const char *const option, const char *const parameter)
Definition: options.c:1172
static void processListMapsOptionForType(const char *const option, const char *const parameter, langmapType type)
Definition: options.c:2119
static void processXformatOption(const char *const option, const char *const parameter)
Definition: options.c:2694
#define INVOCATION
Definition: options.c:49
static void processTotals(const char *const option, const char *const parameter)
Definition: options.c:2499
#define EXTENSION_SEPARATOR
Definition: options.c:60
cookedArgs * cArgNewFromString(const char *string)
Definition: options.c:929
static void processTagRelative(const char *const option, const char *const parameter)
Definition: options.c:2484
#define END_VERBOSE()
Definition: options.h:33
#define BEGIN_VERBOSE(VFP)
Definition: options.h:31
@ OptionLoadingStageCmdline
Definition: options_p.h:84
@ OptionLoadingStageNone
Definition: options_p.h:74
@ OptionLoadingStageXdg
Definition: options_p.h:79
@ OptionLoadingStageDosCnf
Definition: options_p.h:76
@ OptionLoadingStageCurrentRecursive
Definition: options_p.h:81
@ OptionLoadingStagePreload
Definition: options_p.h:82
@ OptionLoadingStageHomeRecursive
Definition: options_p.h:80
@ OptionLoadingStageEnvVar
Definition: options_p.h:83
@ OptionLoadingStageLocalEtc
Definition: options_p.h:78
@ OptionLoadingStageCustom
Definition: options_p.h:75
@ OptionLoadingStageEtc
Definition: options_p.h:77
bool processScopesepOption(const char *const option, const char *const parameter)
Definition: parse.c:665
bool processAliasOption(const char *const option, const char *const parameter)
Definition: parse.c:3314
bool processRoledefOption(const char *const option, const char *const parameter)
Definition: parse.c:2651
@ EX_LINENUM
Definition: options_p.h:55
@ EX_PATTERN
Definition: options_p.h:56
@ EX_COMBINE
Definition: options_p.h:57
@ EX_MIX
Definition: options_p.h:54
bool processTabledefOption(const char *const option, const char *const parameter)
Definition: parse.c:4296
@ SO_SORTED
Definition: options_p.h:62
@ SO_FOLDSORTED
Definition: options_p.h:63
@ SO_UNSORTED
Definition: options_p.h:61
bool processKindsOption(const char *const option, const char *const parameter)
Definition: parse.c:2728
bool processFielddefOption(const char *const option, const char *const parameter)
Definition: parse.c:3693
bool processKinddefOption(const char *const option, const char *const parameter)
Definition: parse.c:2640
bool processExtradefOption(const char *const option, const char *const parameter)
Definition: parse.c:3622
bool processRolesOption(const char *const option, const char *const parameter)
Definition: parse.c:2979
void processLanguageDefineOption(const char *const option, const char *const parameter)
Definition: parse.c:2146
bool processPretendOption(const char *const option, const char *const parameter)
Definition: parse.c:4953
@ TREL_NEVER
Definition: options_p.h:70
@ TREL_ALWAYS
Definition: options_p.h:69
@ TREL_NO
Definition: options_p.h:67
@ TREL_YES
Definition: options_p.h:68
enum eOptionLoadingStage OptionLoadingStage
void applyParameter(const langType language, const char *name, const char *args)
Definition: parse.c:4729
langType getNamedLanguage(const char *const name, size_t len)
Definition: parse.c:406
void printLanguageAliases(const langType language, bool withListHeader, bool machinable, FILE *fp)
Definition: parse.c:3501
langType getNamedLanguageFull(const char *const name, size_t len, bool noPretending)
Definition: parse.c:373
void installLanguageAliasesDefaults(void)
Definition: parse.c:1626
void processLanguageMultitableExtendingOption(langType language, const char *const parameter)
Definition: parse.c:4203
unsigned int countParsers(void)
Definition: parse.c:177
void printLanguageMaps(const langType language, langmapType type, bool withListHeader, bool machinable, FILE *fp)
Definition: parse.c:3426
bool removeLanguageExtensionMap(const langType language, const char *const extension)
Definition: parse.c:1705
void installLanguageMapDefault(const langType language)
Definition: parse.c:1560
void printLangdefFlags(bool withListHeader, bool machinable, FILE *fp)
Definition: parse.c:4906
void printLanguageSubparsers(const langType language, bool withListHeader, bool machinable, FILE *fp)
Definition: parse.c:4872
void enableLanguages(const bool state)
Definition: parse.c:1761
void enableLanguage(const langType language, const bool state)
Definition: parse.c:1742
bool isLanguageVisible(const langType language)
Definition: parse.c:226
const char * getLanguageName(const langType language)
Definition: parse.c:284
void printLanguageParameters(const langType language, bool withListHeader, bool machinable, FILE *fp)
Definition: parse.c:3243
void printKinddefFlags(bool withListHeader, bool machinable, FILE *fp)
Definition: parse.c:4918
void printLanguageRoles(const langType language, const char *kindspecs, bool withListHeader, bool machinable, FILE *fp)
Definition: parse.c:3145
void printLanguageKinds(const langType language, bool allKindFields, bool withListHeader, bool machinable, FILE *fp)
Definition: parse.c:3195
void initializeParser(langType lang)
Definition: parse.c:1850
void printLanguageList(void)
Definition: parse.c:3548
void addLanguageExtensionMap(const langType language, const char *extension, bool exclusiveInAllLanguages)
Definition: parse.c:1720
bool removeLanguagePatternMap(const langType language, const char *const pattern)
Definition: parse.c:1665
void clearLanguageMap(const langType language)
Definition: parse.c:1636
void addLanguagePatternMap(const langType language, const char *ptrn, bool exclusiveInAllLanguages)
Definition: parse.c:1680
void anonHashString(const char *filename, char buf[9])
Definition: parse.c:4693
void installLanguageMapDefaults(void)
Definition: parse.c:1592
bool processLanguageRegexOption(langType language, enum regexParserType regptype, const char *const parameter)
Definition: parse.c:4286
#define LANG_IGNORE
Definition: parse.h:27
#define LANG_AUTO
Definition: parse.h:26
#define LANG_FALLBACK
Definition: parse_p.h:28
langmapType
Definition: parse_p.h:33
@ LMAP_EXTENSION
Definition: parse_p.h:35
@ LMAP_ALL
Definition: parse_p.h:36
@ LMAP_PATTERN
Definition: parse_p.h:34
@ LMAP_TABLE_OUTPUT
Definition: parse_p.h:37
ptagType getPtagTypeForName(const char *name)
Definition: ptag.c:247
void printPtags(bool withListHeader, bool machinable, FILE *fp)
Definition: ptag.c:277
bool enablePtag(ptagType type, bool state)
Definition: ptag.c:225
@ PTAG_JSON_OUTPUT_VERSION
Definition: ptag_p.h:25
@ PTAG_UNKNOWN
Definition: ptag_p.h:22
@ PTAG_COUNT
Definition: ptag_p.h:45
@ PTAG_FILE_FORMAT
Definition: ptag_p.h:27
@ PTAG_OUTPUT_MODE
Definition: ptag_p.h:40
enum ePtagType ptagType
#define NULL
Definition: rbtree.h:150
char * combinePathAndFile(const char *const path, const char *const file)
Definition: routines.c:713
char * eStrndup(const char *str, size_t len)
Definition: routines.c:334
bool doesFileExist(const char *const fileName)
Definition: routines.c:495
bool strToUInt(const char *const str, int base, unsigned int *value)
Definition: routines.c:412
bool strToInt(const char *const str, int base, int *value)
Definition: routines.c:423
void * eMalloc(const size_t size)
Definition: routines.c:218
void toLowerString(char *str)
Definition: routines.c:342
bool isSameFile(const char *const name1, const char *const name2)
Definition: routines.c:582
const char * fileExtension(const char *const fileName)
Definition: routines.c:650
char * strstr(const char *str, const char *substr)
Definition: routines.c:304
const char * getExecutableName(void)
Definition: routines.c:192
char * eStrdup(const char *str)
Definition: routines.c:327
void eFree(void *const ptr)
Definition: routines.c:252
fileStatus * eStat(const char *const fileName)
Definition: routines.c:455
void eStatFree(fileStatus *status)
Definition: routines.c:486
const char * baseFilename(const char *const filePath)
Definition: routines.c:608
bool strToLong(const char *const str, int base, long *value)
Definition: routines.c:403
#define xMalloc(n, Type)
Definition: routines.h:23
@ PERROR
Definition: routines.h:37
@ FATAL
Definition: routines.h:37
@ WARNING
Definition: routines.h:37
#define ARRAY_SIZE(X)
Definition: routines.h:27
#define PATH_SEPARATOR
Definition: routines_p.h:26
#define OUTPUT_PATH_SEPARATOR
Definition: routines_p.h:33
GtkWidget * entry
Definition: search.c:118
stringList * stringListNew(void)
Definition: strlist.c:27
bool stringListHasTest(const stringList *const current, bool(*test)(const char *s, void *userData), void *userData)
Definition: strlist.c:170
void stringListDelete(stringList *const current)
Definition: strlist.c:102
void stringListClear(stringList *const current)
Definition: strlist.c:97
void stringListCombine(stringList *const current, stringList *const from)
Definition: strlist.c:43
stringList * stringListNewFromArgv(const char *const *const argv)
Definition: strlist.c:49
vString * stringListItem(const stringList *const current, const unsigned int indx)
Definition: strlist.c:86
stringList * stringListNewFromFile(const char *const fileName)
Definition: strlist.c:59
void stringListPrint(const stringList *const current, FILE *fp)
Definition: strlist.c:267
bool stringListExtensionMatched(const stringList *const current, const char *const extension)
Definition: strlist.c:195
bool stringListFileMatched(const stringList *const current, const char *const fileName)
Definition: strlist.c:234
unsigned int stringListCount(const stringList *const current)
Definition: strlist.c:81
void stringListAdd(stringList *const current, vString *string)
Definition: strlist.c:32
bool stringListHas(const stringList *const current, const char *const string)
Definition: strlist.c:135
const char * description
Definition: options.c:524
const char * name
Definition: options.c:523
bool exists
Definition: routines_p.h:49
bool isDirectory
Definition: routines_p.h:55
bool withListHeader
Definition: options.c:186
parametricOptionHandler handler
Definition: options.c:103
const char * name
Definition: options.c:102
unsigned long acceptableStages
Definition: options.c:105
bool isDirectory
Definition: options.c:3614
const char * path
Definition: options.c:3613
const char * extra
Definition: options.c:3616
OptionLoadingStage stage
Definition: options.c:3617
preloadMakePathFunc makePath
Definition: options.c:3615
void(* set)(const struct sBooleanOption *const option, bool value)
Definition: options.c:113
unsigned long acceptableStages
Definition: options.c:112
const char * name
Definition: options.c:109
bool initOnly
Definition: options.c:111
bool * pValue
Definition: options.c:110
char * shortOptions
Definition: options_p.h:44
char simple[2]
Definition: options_p.h:45
bool isOption
Definition: options_p.h:46
bool longOption
Definition: options_p.h:47
char * item
Definition: options_p.h:50
Arguments * args
Definition: options_p.h:43
const char * parameter
Definition: options_p.h:48
const char * description
Definition: options.c:96
char * filterTerminator
Definition: options_p.h:110
sortType sorted
Definition: options_p.h:95
bool followLinks
Definition: options_p.h:108
unsigned int tagFileFormat
Definition: options_p.h:102
bool backward
Definition: options_p.h:91
bool lineDirectives
Definition: options_p.h:113
unsigned int patternLengthLimit
Definition: options_p.h:118
tagRelative tagRelative
Definition: options_p.h:111
fmtElement * customXfmt
Definition: options_p.h:97
bool putFieldPrefix
Definition: options_p.h:119
stringList * etagsInclude
Definition: options_p.h:101
bool printLanguage
Definition: options_p.h:114
char * fileList
Definition: options_p.h:98
enum sOptionValues::interactiveMode interactive
langType language
Definition: options_p.h:107
unsigned int maxRecursionDepth
Definition: options_p.h:120
bool fatalWarnings
Definition: options_p.h:117
exCmd locate
Definition: options_p.h:93
bool recurse
Definition: options_p.h:94
char * tagFileName
Definition: options_p.h:99
bool guessLanguageEagerly
Definition: options_p.h:115
stringList * headerExt
Definition: options_p.h:100
int langType
Definition: types.h:13
void vStringTranslate(vString *const string, char fromC, char toC)
Definition: vstring.c:394
void vStringCopyS(vString *const string, const char *const s)
Definition: vstring.c:213
vString * vStringNew(void)
Definition: vstring.c:70
void vStringDelete(vString *const string)
Definition: vstring.c:60
vString * vStringNewOrClearWithAutoRelease(vString *const string)
Definition: vstring.c:379
vString * vStringNewOwn(char *s)
Definition: vstring.c:257
void vStringCatS(vString *const string, const char *const s)
Definition: vstring.c:146
vString * vStringNewInit(const char *const s)
Definition: vstring.c:90
#define vStringClear(string)
Definition: vstring.h:36
#define vStringLength(vs)
Definition: vstring.h:31
#define vStringIsEmpty(vs)
Definition: vstring.h:32
#define vStringValue(vs)
Definition: vstring.h:28
static void vStringPut(vString *const string, const int c)
Definition: vstring.h:101
void writerCheckOptions(void)
Definition: writer.c:180
const char * outputDefaultFileName(void)
Definition: writer.c:110
void setTagWriter(writerType wtype, tagWriter *customWriter)
Definition: writer.c:34
@ WRITER_JSON
Definition: writer_p.h:28
@ WRITER_E_CTAGS
Definition: writer_p.h:25
@ WRITER_XREF
Definition: writer_p.h:27
@ WRITER_ETAGS
Definition: writer_p.h:26
void xtagColprintTablePrint(struct colprintTable *table, bool withListHeader, bool machinable, FILE *fp)
Definition: xtag.c:228
xtagType getXtagTypeForLetter(char letter)
Definition: xtag.c:127
bool enableXtag(xtagType type, bool state)
Definition: xtag.c:259
xtagType nextSiblingXtag(xtagType type)
Definition: xtag.c:383
struct colprintTable * xtagColprintTableNew(void)
Definition: xtag.c:148
int countXtags(void)
Definition: xtag.c:327
bool isXtagEnabled(xtagType type)
Definition: xtag.c:235
void xtagColprintAddLanguageLines(struct colprintTable *table, langType language)
Definition: xtag.c:181
xtagType getXtagTypeForNameAndLanguage(const char *name, langType language)
Definition: xtag.c:143
int getXtagOwner(xtagType type)
Definition: xtag.c:285
void xtagColprintAddCommonLines(struct colprintTable *table)
Definition: xtag.c:175
@ XTAG_UNKNOWN
Definition: xtag.h:26
@ XTAG_FILE_SCOPE
Definition: xtag.h:28
@ XTAG_FILE_NAMES
Definition: xtag.h:29
enum eXtagType xtagType