📄 options.c
字号:
toLowerString (etags);#endif if (strstr (execName, etags) != NULL) { verbose ("Running in etags mode\n"); setEtagsMode (); }}/* * Cooked argument parsing */static void parseShortOption (cookedArgs *const args){ args->simple [0] = *args->shortOptions++; args->simple [1] = '\0'; args->item = args->simple; if (! isCompoundOption (*args->simple)) args->parameter = ""; else if (*args->shortOptions == '\0') { argForth (args->args); if (argOff (args->args)) args->parameter = NULL; else args->parameter = argItem (args->args); args->shortOptions = NULL; } else { args->parameter = args->shortOptions; args->shortOptions = NULL; }}static void parseLongOption (cookedArgs *const args, const char *item){ const char* const equal = strchr (item, '='); if (equal == NULL) { args->item = eStrdup (item); args->parameter = ""; } else { const size_t length = equal - item; args->item = xMalloc (length + 1, char); strncpy (args->item, item, length); args->item [length] = '\0'; args->parameter = equal + 1; } Assert (args->item != NULL); Assert (args->parameter != NULL);}static void cArgRead (cookedArgs *const current){ char* item; Assert (current != NULL); if (! argOff (current->args)) { item = argItem (current->args); current->shortOptions = NULL; Assert (item != NULL); if (strncmp (item, "--", (size_t) 2) == 0) { current->isOption = TRUE; current->longOption = TRUE; parseLongOption (current, item + 2); Assert (current->item != NULL); Assert (current->parameter != NULL); } else if (*item == '-') { current->isOption = TRUE; current->longOption = FALSE; current->shortOptions = item + 1; parseShortOption (current); } else { current->isOption = FALSE; current->longOption = FALSE; current->item = item; current->parameter = NULL; } }}extern cookedArgs* cArgNewFromString (const char* string){ cookedArgs* const result = xMalloc (1, cookedArgs); memset (result, 0, sizeof (cookedArgs)); result->args = argNewFromString (string); cArgRead (result); return result;}extern cookedArgs* cArgNewFromArgv (char* const* const argv){ cookedArgs* const result = xMalloc (1, cookedArgs); memset (result, 0, sizeof (cookedArgs)); result->args = argNewFromArgv (argv); cArgRead (result); return result;}extern cookedArgs* cArgNewFromFile (FILE* const fp){ cookedArgs* const result = xMalloc (1, cookedArgs); memset (result, 0, sizeof (cookedArgs)); result->args = argNewFromFile (fp); cArgRead (result); return result;}extern cookedArgs* cArgNewFromLineFile (FILE* const fp){ cookedArgs* const result = xMalloc (1, cookedArgs); memset (result, 0, sizeof (cookedArgs)); result->args = argNewFromLineFile (fp); cArgRead (result); return result;}extern void cArgDelete (cookedArgs* const current){ Assert (current != NULL); argDelete (current->args); memset (current, 0, sizeof (cookedArgs)); eFree (current);}static boolean cArgOptionPending (cookedArgs* const current){ boolean result = FALSE; if (current->shortOptions != NULL) if (*current->shortOptions != '\0') result = TRUE; return result;}extern boolean cArgOff (cookedArgs* const current){ Assert (current != NULL); return (boolean) (argOff (current->args) && ! cArgOptionPending (current));}extern boolean cArgIsOption (cookedArgs* const current){ Assert (current != NULL); return current->isOption;}extern const char* cArgItem (cookedArgs* const current){ Assert (current != NULL); return current->item;}extern void cArgForth (cookedArgs* const current){ Assert (current != NULL); Assert (! cArgOff (current)); if (cArgOptionPending (current)) parseShortOption (current); else { Assert (! argOff (current->args)); argForth (current->args); if (! argOff (current->args)) cArgRead (current); else { current->isOption = FALSE; current->longOption = FALSE; current->shortOptions = NULL; current->item = NULL; current->parameter = NULL; } }}/* * File extension and language mapping */static void addExtensionList (stringList *const slist, const char *const elist, const boolean clear){ char *const extensionList = eStrdup (elist); const char *extension = NULL; boolean first = TRUE; if (clear) { verbose (" clearing\n"); stringListClear (slist); } verbose (" adding: "); if (elist != NULL && *elist != '\0') { extension = extensionList; if (elist [0] == EXTENSION_SEPARATOR) ++extension; } while (extension != NULL) { char *separator = strchr (extension, EXTENSION_SEPARATOR); if (separator != NULL) *separator = '\0'; verbose ("%s%s", first ? "" : ", ", *extension == '\0' ? "(NONE)" : extension); stringListAdd (slist, vStringNewInit (extension)); first = FALSE; if (separator == NULL) extension = NULL; else extension = separator + 1; } if (Option.verbose) { printf ("\n now: "); stringListPrint (slist); putchar ('\n'); } eFree (extensionList);}static boolean isFalse (const char *parameter){ return (boolean) ( strcasecmp (parameter, "0" ) == 0 || strcasecmp (parameter, "n" ) == 0 || strcasecmp (parameter, "no" ) == 0 || strcasecmp (parameter, "off") == 0);}static boolean isTrue (const char *parameter){ return (boolean) ( strcasecmp (parameter, "1" ) == 0 || strcasecmp (parameter, "y" ) == 0 || strcasecmp (parameter, "yes") == 0 || strcasecmp (parameter, "on" ) == 0);}/* Determines whether the specified file name is considered to be a header * file for the purposes of determining whether enclosed tags are global or * static. */extern boolean isIncludeFile (const char *const fileName){ boolean result = FALSE; const char *const extension = fileExtension (fileName); if (Option.headerExt != NULL) result = stringListExtensionMatched (Option.headerExt, extension); return result;}/* * Specific option processing */static void processEtagsInclude ( const char *const option, const char *const parameter){ if (! Option.etags) error (FATAL, "Etags must be enabled to use \"%s\" option", option); else { vString *const file = vStringNewInit (parameter); if (Option.etagsInclude == NULL) Option.etagsInclude = stringListNew (); stringListAdd (Option.etagsInclude, file); FilesRequired = FALSE; }}static void processExcludeOption ( const char *const option __unused__, const char *const parameter){ const char *const fileName = parameter + 1; if (parameter [0] == '\0') freeList (&Excluded); else if (parameter [0] == '@') { stringList* const sl = stringListNewFromFile (fileName); if (sl == NULL) error (FATAL | PERROR, "cannot open \"%s\"", fileName); if (Excluded == NULL) Excluded = sl; else stringListCombine (Excluded, sl); verbose (" adding exclude patterns from %s\n", fileName); } else { vString *const item = vStringNewInit (parameter); if (Excluded == NULL) Excluded = stringListNew (); stringListAdd (Excluded, item); verbose (" adding exclude pattern: %s\n", parameter); }}extern boolean isExcludedFile (const char* const name){ const char* base = baseFilename (name); boolean result = FALSE; if (Excluded != NULL) { result = stringListFileMatched (Excluded, base); if (! result && name != base) result = stringListFileMatched (Excluded, name); }#ifdef AMIGA /* not a good solution, but the only one which works often */ if (! result) result = (boolean) (strcmp (name, TagFile.name) == 0);#endif return result;}static void processExcmdOption ( const char *const option, const char *const parameter){ switch (*parameter) { case 'm': Option.locate = EX_MIX; break; case 'n': Option.locate = EX_LINENUM; break; case 'p': Option.locate = EX_PATTERN; break; default: error (FATAL, "Invalid value for \"%s\" option", option); break; }}static void processExtraTagsOption ( const char *const option, const char *const parameter){ struct sInclude *const inc = &Option.include; const char *p = parameter; boolean mode = TRUE; int c; if (*p != '+' && *p != '-') { inc->fileNames = FALSE; inc->qualifiedTags = FALSE;#if 0 inc->fileScope = FALSE;#endif } while ((c = *p++) != '\0') switch (c) { case '+': mode = TRUE; break; case '-': mode = FALSE; break; case 'f': inc->fileNames = mode; break; case 'q': inc->qualifiedTags = mode; break;#if 0 case 'F': inc->fileScope = mode; break;#endif default: error(WARNING, "Unsupported parameter '%c' for \"%s\" option", c, option); break; }}static void processFieldsOption ( const char *const option, const char *const parameter){ struct sExtFields *field = &Option.extensionFields; const char *p = parameter; boolean mode = TRUE; int c; if (*p != '+' && *p != '-') { field->access = FALSE; field->fileScope = FALSE; field->implementation = FALSE; field->inheritance = FALSE; field->kind = FALSE; field->kindKey = FALSE; field->kindLong = FALSE; field->language = FALSE; field->scope = FALSE; } while ((c = *p++) != '\0') switch (c) { case '+': mode = TRUE; break; case '-': mode = FALSE; break; case 'a': field->access = mode; break; case 'f': field->fileScope = mode; break; case 'm': field->implementation = mode; break; case 'i': field->inheritance = mode; break; case 'k': field->kind = mode; break; case 'K': field->kindLong = mode; break; case 'l': field->language = mode; break; case 'n': field->lineNumber = mode; break; case 's': field->scope = mode; break; case 'S': field->signature = mode; break; case 'z': field->kindKey = mode; break; default: error(WARNING, "Unsupported parameter '%c' for \"%s\" option", c, option); break; }}static void processFilterTerminatorOption ( const char *const option __unused__, const char *const parameter){ freeString (&Option.filterTerminator); Option.filterTerminator = stringCopy (parameter);}static void processFormatOption ( const char *const option, const char *const parameter){ unsigned int format; if (sscanf (parameter, "%u", &format) < 1) error (FATAL, "Invalid value for \"%s\" option",option); else if (format <= (unsigned int) MaxSupportedTagFormat) Option.tagFileFormat = format; else error (FATAL, "Unsupported value for \"%s\" option", option);}static void printInvocationDescription (void){ printf (INVOCATION, getExecutableName ());}static void printOptionDescriptions (const optionDescription *const optDesc){ int i; for (i = 0 ; optDesc [i].description != NULL ; ++i)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -