⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 options.c

📁 Exuberant Ctags is a multilanguage reimplementation of the much-underused ctags(1) program and is i
💻 C
📖 第 1 页 / 共 3 页
字号:
		const char *const option, const char *const parameter){	if (parameter [0] == '\0')		error (WARNING, "no option file supplied for \"%s\"", option);	else if (! parseFileOptions (parameter))		error (FATAL | PERROR, "cannot open option file \"%s\"", parameter);}static void processSortOption (		const char *const option, const char *const parameter){	if (isFalse (parameter))		Option.sorted = SO_UNSORTED;	else if (isTrue (parameter))		Option.sorted = SO_SORTED;	else if (strcasecmp (parameter, "f") == 0 ||			strcasecmp (parameter, "fold") == 0 ||			strcasecmp (parameter, "foldcase") == 0)		Option.sorted = SO_FOLDSORTED;	else		error (FATAL, "Invalid value for \"%s\" option", option);}static void installHeaderListDefaults (void){	Option.headerExt = stringListNewFromArgv (HeaderExtensions);	if (Option.verbose)	{		printf ("    Setting default header extensions: ");		stringListPrint (Option.headerExt);		putchar ('\n');	}}static void processHeaderListOption (const int option, const char *parameter){	/*  Check to make sure that the user did not enter "ctags -h *.c"	 *  by testing to see if the list is a filename that exists.	 */	if (doesFileExist (parameter))		error (FATAL, "-%c: Invalid list", option);	if (strcmp (parameter, "default") == 0)		installHeaderListDefaults ();	else	{		boolean clear = TRUE;		if (parameter [0] == '+')		{			++parameter;			clear = FALSE;		}		if (Option.headerExt == NULL)			Option.headerExt = stringListNew ();		verbose ("    Header Extensions:\n");		addExtensionList (Option.headerExt, parameter, clear);	}}/* *  Token ignore processing *//*  Determines whether or not "name" should be ignored, per the ignore list. */extern boolean isIgnoreToken (		const char *const name, boolean *const pIgnoreParens,		const char **const replacement){	boolean result = FALSE;	if (Option.ignore != NULL)	{		const size_t nameLen = strlen (name);		unsigned int i;		if (pIgnoreParens != NULL)			*pIgnoreParens = FALSE;		for (i = 0  ;  i < stringListCount (Option.ignore)  ;  ++i)		{			vString *token = stringListItem (Option.ignore, i);			if (strncmp (vStringValue (token), name, nameLen) == 0)			{				const size_t tokenLen = vStringLength (token);				if (nameLen == tokenLen)				{					result = TRUE;					break;				}				else if (tokenLen == nameLen + 1  &&						vStringChar (token, tokenLen - 1) == '+')				{					result = TRUE;					if (pIgnoreParens != NULL)						*pIgnoreParens = TRUE;					break;				}				else if (vStringChar (token, nameLen) == '=')				{					if (replacement != NULL)						*replacement = vStringValue (token) + nameLen + 1;					break;				}			}		}	}	return result;}static void saveIgnoreToken (vString *const ignoreToken){	if (Option.ignore == NULL)		Option.ignore = stringListNew ();	stringListAdd (Option.ignore, ignoreToken);	verbose ("    ignore token: %s\n", vStringValue (ignoreToken));}static void readIgnoreList (const char *const list){	char* newList = stringCopy (list);	const char *token = strtok (newList, IGNORE_SEPARATORS);	while (token != NULL)	{		vString *const entry = vStringNewInit (token);		saveIgnoreToken (entry);		token = strtok (NULL, IGNORE_SEPARATORS);	}	eFree (newList);}static void addIgnoreListFromFile (const char *const fileName){	stringList* tokens = stringListNewFromFile (fileName);	if (tokens == NULL)		error (FATAL | PERROR, "cannot open \"%s\"", fileName);	if (Option.ignore == NULL)		Option.ignore = tokens;	else		stringListCombine (Option.ignore, tokens);}static void processIgnoreOption (const char *const list){	if (strchr ("@./\\", list [0]) != NULL)	{		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=4 shiftwidth=4: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -