📄 options.c
字号:
const char* fileName = (*list == '@') ? list + 1 : list; addIgnoreListFromFile (fileName); }#if defined (MSDOS) || defined (WIN32) || defined (OS2) else if (isalpha (list [0]) && list [1] == ':') addIgnoreListFromFile (list);#endif else if (strcmp (list, "-") == 0) { freeList (&Option.ignore); verbose (" clearing list\n"); } else readIgnoreList (list);}static void processVersionOption ( const char *const option __unused__, const char *const parameter __unused__){ printProgramIdentification (); exit (0);}/* * Option tables */static parametricOption ParametricOptions [] = { { "etags-include", processEtagsInclude, FALSE }, { "exclude", processExcludeOption, FALSE }, { "excmd", processExcmdOption, FALSE }, { "extra", processExtraTagsOption, FALSE }, { "fields", processFieldsOption, FALSE }, { "filter-terminator", processFilterTerminatorOption, TRUE }, { "format", processFormatOption, TRUE }, { "help", processHelpOption, TRUE }, { "lang", processLanguageForceOption, FALSE }, { "language", processLanguageForceOption, FALSE }, { "language-force", processLanguageForceOption, FALSE }, { "languages", processLanguagesOption, FALSE }, { "langdef", processLanguageDefineOption, FALSE }, { "langmap", processLanguageMapOption, FALSE }, { "license", processLicenseOption, TRUE }, { "list-kinds", processListKindsOption, TRUE }, { "list-maps", processListMapsOption, TRUE }, { "list-languages", processListLanguagesOption, TRUE }, { "options", processOptionFile, FALSE }, { "sort", processSortOption, TRUE }, { "version", processVersionOption, TRUE },};static booleanOption BooleanOptions [] = { { "append", &Option.append, TRUE }, { "file-scope", &Option.include.fileScope, FALSE }, { "file-tags", &Option.include.fileNames, FALSE }, { "filter", &Option.filter, TRUE }, { "if0", &Option.if0, FALSE }, { "kind-long", &Option.kindLong, TRUE }, { "line-directives",&Option.lineDirectives, FALSE }, { "links", &Option.followLinks, FALSE },#ifdef RECURSE_SUPPORTED { "recurse", &Option.recurse, FALSE },#endif { "tag-relative", &Option.tagRelative, TRUE }, { "totals", &Option.printTotals, TRUE }, { "verbose", &Option.verbose, FALSE },};/* * Generic option parsing */static void checkOptionOrder (const char* const option){ if (NonOptionEncountered) error (FATAL, "-%s option may not follow a file name", option);}static boolean processParametricOption ( const char *const option, const char *const parameter){ const int count = sizeof (ParametricOptions) / sizeof (parametricOption); boolean found = FALSE; int i; for (i = 0 ; i < count && ! found ; ++i) { parametricOption* const entry = &ParametricOptions [i]; if (strcmp (option, entry->name) == 0) { found = TRUE; if (entry->initOnly) checkOptionOrder (option); (entry->handler) (option, parameter); } } return found;}static boolean getBooleanOption ( const char *const option, const char *const parameter){ boolean selection = TRUE; if (parameter [0] == '\0') selection = TRUE; else if (isFalse (parameter)) selection = FALSE; else if (isTrue (parameter)) selection = TRUE; else error (FATAL, "Invalid value for \"%s\" option", option); return selection;}static boolean processBooleanOption ( const char *const option, const char *const parameter){ const int count = sizeof (BooleanOptions) / sizeof (booleanOption); boolean found = FALSE; int i; for (i = 0 ; i < count && ! found ; ++i) { booleanOption* const entry = &BooleanOptions [i]; if (strcmp (option, entry->name) == 0) { found = TRUE; if (entry->initOnly) checkOptionOrder (option); *entry->pValue = getBooleanOption (option, parameter); } } return found;}static void processLongOption ( const char *const option, const char *const parameter){ Assert (parameter != NULL); if (parameter == NULL && parameter [0] == '\0') verbose (" Option: --%s\n", option); else verbose (" Option: --%s=%s\n", option, parameter); if (processBooleanOption (option, parameter)) ; else if (processParametricOption (option, parameter)) ; else if (processKindOption (option, parameter)) ; else if (processRegexOption (option, parameter)) ;#ifndef RECURSE_SUPPORTED else if (strcmp (option, "recurse") == 0) error (WARNING, "%s option not supported on this host", option);#endif else error (FATAL, "Unknown option: --%s", option);}static void processShortOption ( const char *const option, const char *const parameter){ if (parameter == NULL || parameter [0] == '\0') verbose (" Option: -%s\n", option); else verbose (" Option: -%s %s\n", option, parameter); if (isCompoundOption (*option) && (parameter == NULL || parameter [0] == '\0')) error (FATAL, "Missing parameter for \"%s\" option", option); else switch (*option) { case '?': processHelpOption ("?", NULL); exit (0); break; case 'a': checkOptionOrder (option); Option.append = TRUE; break;#ifdef DEBUG case 'b': if (atol (parameter) < 0) error (FATAL, "-%s: Invalid line number", option); Option.breakLine = atol (parameter); break; case 'D': Option.debugLevel = strtol (parameter, NULL, 0); if (debug (DEBUG_STATUS)) Option.verbose = TRUE; break;#endif case 'B': Option.backward = TRUE; break; case 'e': checkOptionOrder (option); setEtagsMode (); break; case 'f': case 'o': checkOptionOrder (option); if (Option.tagFileName != NULL) { error (WARNING, "-%s option specified more than once, last value used", option); freeString (&Option.tagFileName); } else if (parameter [0] == '-' && parameter [1] != '\0') error (FATAL, "output file name may not begin with a '-'"); Option.tagFileName = stringCopy (parameter); break; case 'F': Option.backward = FALSE; break; case 'h': processHeaderListOption (*option, parameter); break; case 'I': processIgnoreOption (parameter); break; case 'L': if (Option.fileList != NULL) { error (WARNING, "-%s option specified more than once, last value used", option); freeString (&Option.fileList); } Option.fileList = stringCopy (parameter); break; case 'n': Option.locate = EX_LINENUM; break; case 'N': Option.locate = EX_PATTERN; break; case 'R':#ifdef RECURSE_SUPPORTED Option.recurse = TRUE;#else error (WARNING, "-%s option not supported on this host", option);#endif break; case 'u': checkOptionOrder (option); Option.sorted = SO_UNSORTED; break; case 'V': Option.verbose = TRUE; break; case 'w': /* silently ignored */ break; case 'x': checkOptionOrder (option); Option.xref = TRUE; break; default: error (FATAL, "Unknown option: -%s", option); break; }}extern void parseOption (cookedArgs* const args){ Assert (! cArgOff (args)); if (args->isOption) { if (args->longOption) processLongOption (args->item, args->parameter); else { const char *parameter = args->parameter; while (*parameter == ' ') ++parameter; processShortOption (args->item, parameter); } cArgForth (args); }}extern void parseOptions (cookedArgs* const args){ NonOptionEncountered = FALSE; while (! cArgOff (args) && cArgIsOption (args)) parseOption (args); if (! cArgOff (args) && ! cArgIsOption (args)) NonOptionEncountered = TRUE;}static const char *CheckFile;static boolean checkSameFile (const char *const fileName){ return isSameFile (CheckFile, fileName);}static boolean parseFileOptions (const char* const fileName){ boolean fileFound = FALSE; const char* const format = "Considering option file %s: %s\n"; CheckFile = fileName; if (stringListHasTest (OptionFiles, checkSameFile)) verbose (format, fileName, "already considered"); else { FILE* const fp = fopen (fileName, "r"); if (fp == NULL) verbose (format, fileName, "not found"); else { cookedArgs* const args = cArgNewFromLineFile (fp); vString* file = vStringNewInit (fileName); stringListAdd (OptionFiles, file); verbose (format, fileName, "reading..."); parseOptions (args); if (NonOptionEncountered) error (WARNING, "Ignoring non-option in %s\n", fileName); cArgDelete (args); fclose (fp); fileFound = TRUE; } } return fileFound;}/* Actions to be taken before reading any other options */extern void previewFirstOption (cookedArgs* const args){ while (cArgIsOption (args)) { if (strcmp (args->item, "V") == 0 || strcmp (args->item, "verbose") == 0) parseOption (args); else if (strcmp (args->item, "options") == 0 && strcmp (args->parameter, "NONE") == 0) { fprintf (stderr, "No options will be read from files or environment\n"); SkipConfiguration = TRUE; cArgForth (args); } else break; }}static void parseConfigurationFileOptions (void){ const char* const home = getenv ("HOME"); const char* conf;#ifdef CUSTOM_CONFIGURATION_FILE parseFileOptions (CUSTOM_CONFIGURATION_FILE);#endif#ifdef MSDOS_STYLE_PATH parseFileOptions ("/ctags.cnf"); conf = "ctags.cnf";#else conf = ".ctags";#endif parseFileOptions ("/etc/ctags.conf"); parseFileOptions ("/usr/local/etc/ctags.conf"); if (home != NULL) { vString* const homeFile = combinePathAndFile (home, conf); parseFileOptions (vStringValue (homeFile)); vStringDelete (homeFile); } parseFileOptions (conf);}static void parseEnvironmentOptions (void){ const char *envOptions = NULL; const char* var = NULL; if (Option.etags) { var = ETAGS_ENVIRONMENT; envOptions = getenv (var); } if (envOptions == NULL) { var = CTAGS_ENVIRONMENT; envOptions = getenv (var); } if (envOptions != NULL && envOptions [0] != '\0') { cookedArgs* const args = cArgNewFromString (envOptions); verbose ("Reading options from $CTAGS\n"); parseOptions (args); cArgDelete (args); if (NonOptionEncountered) error (WARNING, "Ignoring non-option in %s variable", var); }}extern void readOptionConfiguration (void){ if (! SkipConfiguration) { parseConfigurationFileOptions (); parseEnvironmentOptions (); }}/** Option initialization*/extern void initOptions (void){ OptionFiles = stringListNew (); verbose ("Setting option defaults\n"); installHeaderListDefaults (); verbose (" Installing default language mappings:\n"); installLanguageMapDefaults (); /* always excluded by default */ verbose (" Installing default exclude patterns:\n"); processExcludeOption (NULL, "EIFGEN"); processExcludeOption (NULL, "SCCS"); processExcludeOption (NULL, "RCS"); processExcludeOption (NULL, "CVS");}extern void freeOptionResources (void){ freeString (&Option.tagFileName); freeString (&Option.fileList); freeString (&Option.filterTerminator); freeList (&Excluded); freeList (&Option.ignore); freeList (&Option.headerExt); freeList (&Option.etagsInclude); freeList (&OptionFiles);}/* vi:set tabstop=8 shiftwidth=4: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -