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

📄 parse.c

📁 ultraEdit的Ctag标签工具的实现源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		LanguageTable [def->id] = def;
	    }
	}
    }
    verbose ("\n");
    enableLanguages (TRUE);
    initializeParsers ();
}

extern void freeParserResources (void)
{
    unsigned int i;
    for (i = 0  ;  i < LanguageCount  ;  ++i)
    {
	freeList (&LanguageTable [i]->currentPatterns);
	freeList (&LanguageTable [i]->currentExtensions);
	eFree (LanguageTable [i]->name);
	LanguageTable [i]->name = NULL;
	eFree (LanguageTable [i]);
    }
    if (LanguageTable != NULL)
	eFree (LanguageTable);
    LanguageTable = NULL;
    LanguageCount = 0;
}

/*
*   Option parsing
*/

extern void processLanguageDefineOption (
	const char *const option, const char *const parameter __unused__)
{
#ifdef HAVE_REGEX
    if (parameter [0] == '\0')
	error (WARNING, "No language specified for \"%s\" option", option);
    else if (getNamedLanguage (parameter) != LANG_IGNORE)
	error (WARNING, "Language \"%s\" already defined", parameter);
    else
    {
	unsigned int i = LanguageCount++;
	parserDefinition* const def = parserNew (parameter);
	def->parser            = findRegexTags;
	def->currentPatterns   = stringListNew ();
	def->currentExtensions = stringListNew ();
	def->regex             = TRUE;
	def->enabled           = TRUE;
	def->id                = i;
	LanguageTable = xRealloc (LanguageTable, i + 1, parserDefinition*);
	LanguageTable [i] = def;
    }
#else
    error (WARNING, "regex support not available; required for --%s option",
	   option);
#endif
}

static kindOption *langKindOption (const langType language, const int flag)
{
    unsigned int i;
    kindOption* result = NULL;
    const parserDefinition* lang;
    Assert (0 <= language  &&  language < (int) LanguageCount);
    lang = LanguageTable [language];
    for (i=0  ;  i < lang->kindCount  &&  result == NULL  ;  ++i)
	if (lang->kinds [i].letter == flag)
	    result = &lang->kinds [i];
    return result;
}

static void disableLanguageKinds (const langType language)
{
    if (LanguageTable [language]->regex)
	disableRegexKinds (language);
    else
    {
	unsigned int i;
	for (i = 0  ;  i < LanguageTable [language]->kindCount  ;  ++i)
	    LanguageTable [language]->kinds [i].enabled = FALSE;
    }
}

static boolean enableLanguageKind (
	const langType language, const int kind, const boolean mode)
{
    boolean result = FALSE;
    if (LanguageTable [language]->regex)
	result = enableRegexKind (language, kind, mode);
    else
    {
	kindOption* const opt = langKindOption (language, kind);
	if (opt != NULL)
	{
	    opt->enabled = mode;
	    result = TRUE;
	}
    }
    return result;
}

static void processLangKindOption (
	const langType language, const char *const option,
	const char *const parameter)
{
    const char *p = parameter;
    boolean mode = TRUE;
    int c;

    Assert (0 <= language  &&  language < (int) LanguageCount);
    if (*p != '+'  &&  *p != '-')
	disableLanguageKinds (language);
    while ((c = *p++) != '\0') switch (c)
    {
	case '+': mode = TRUE;  break;
	case '-': mode = FALSE; break;
	default:
	    if (! enableLanguageKind (language, c, mode))
		error (WARNING, "Unsupported parameter '%c' for --%s option",
		    c, option);
	    break;
    }
}

extern boolean processKindOption (
	const char *const option, const char *const parameter)
{
    boolean handled = FALSE;
    const char* const dash = strchr (option, '-');
    if (dash != NULL  &&
	(strcmp (dash + 1, "kinds") == 0  ||  strcmp (dash + 1, "types") == 0))
    {
	langType language;
	vString* langName = vStringNew ();
	vStringNCopyS (langName, option, dash - option);
	language = getNamedLanguage (vStringValue (langName));
	if (language == LANG_IGNORE)
	    error (WARNING, "Unknown language specified in \"%s\" option", option);
	else
	    processLangKindOption (language, option, parameter);
	vStringDelete (langName);
	handled = TRUE;
    }
    return handled;
}

static void printLanguageKind (const kindOption* const kind, boolean indent)
{
    const char *const indentation = indent ? "    " : "";
    printf ("%s%c  %s%s\n", indentation, kind->letter,
	kind->description != NULL ? kind->description :
	    (kind->name != NULL ? kind->name : ""),
	kind->enabled ? "" : " [off]");
}

static void printKinds (langType language, boolean indent)
{
    const parserDefinition* lang;
    Assert (0 <= language  &&  language < (int) LanguageCount);
    lang = LanguageTable [language];
    if (lang->kinds != NULL  ||  lang->regex)
    {
	unsigned int i;
	for (i = 0  ;  i < lang->kindCount  ;  ++i)
	    printLanguageKind (lang->kinds + i, indent);
	printRegexKinds (language, indent);
    }
}

extern void printLanguageKinds (const langType language)
{
    if (language == LANG_AUTO)
    {
	unsigned int i;
	for (i = 0  ;  i < LanguageCount  ;  ++i)
	{
	    printf ("%s\n", LanguageTable [i]->name);
	    printKinds (i, TRUE);
	}
    }
    else
	printKinds (language, FALSE);
}

static void printMaps (const langType language)
{
    const parserDefinition* lang;
    unsigned int i;
    Assert (0 <= language  &&  language < (int) LanguageCount);
    lang = LanguageTable [language];
    printf ("%-8s", lang->name);
    if (lang->extensions != NULL)
	for (i = 0  ;  lang->extensions [i] != NULL  ;  ++i)
	    printf (" *.%s", lang->extensions [i]);
    if (lang->patterns != NULL)
	for (i = 0  ;  lang->patterns [i] != NULL  ;  ++i)
	    printf (" %s", lang->patterns [i]);
    putchar ('\n');
}

extern void printLanguageMaps (const langType language)
{
    if (language == LANG_AUTO)
    {
	unsigned int i;
	for (i = 0  ;  i < LanguageCount  ;  ++i)
	    printMaps (i);
    }
    else
	printMaps (language);
}

static void printLanguage (const langType language)
{
    const parserDefinition* lang;
    Assert (0 <= language  &&  language < (int) LanguageCount);
    lang = LanguageTable [language];
    if (lang->kinds != NULL  ||  lang->regex)
	printf ("%s\n", lang->name);
}
        
extern void printLanguageList (void)
{
    unsigned int i;
    for (i = 0  ;  i < LanguageCount  ;  ++i)
	printLanguage (i);
}

/*
*   File parsing
*/

static void makeFileTag (const char *const fileName)
{
    if (Option.include.fileNames)
    {
	tagEntryInfo tag;
	initTagEntry (&tag, baseFilename (fileName));

	tag.isFileEntry     = TRUE;
	tag.lineNumberEntry = TRUE;
	tag.lineNumber      = 1;
	tag.kindName        = "file";
	tag.kind            = 'F';

	makeTagEntry (&tag);
    }
}

static boolean createTagsForFile (
	const char *const fileName, const langType language,
	const unsigned int passCount)
{
    boolean retried = FALSE;

    if (fileOpen (fileName, language))
    {
	if (Option.etags)
	    beginEtagsFile ();

	makeFileTag (fileName);

	if (LanguageTable [language]->parser != NULL)
	    LanguageTable [language]->parser ();
	else if (LanguageTable [language]->parser2 != NULL)
	    retried = LanguageTable [language]->parser2 (passCount);

	if (Option.etags)
	    endEtagsFile (getSourceFileTagPath ());

	fileClose ();
    }

    return retried;
}

static boolean createTagsWithFallback (
	const char *const fileName, const langType language)
{
    const unsigned long numTags	= TagFile.numTags.added;
    fpos_t tagFilePosition;
    unsigned int passCount = 0;
    boolean tagFileResized = FALSE;

    fgetpos (TagFile.fp, &tagFilePosition);
    while (createTagsForFile (fileName, language, ++passCount))
    {
	/*  Restore prior state of tag file.
	 */
	fsetpos (TagFile.fp, &tagFilePosition);
	TagFile.numTags.added = numTags;
	tagFileResized = TRUE;
    }
    return tagFileResized;
}

extern boolean parseFile (const char *const fileName)
{
    boolean tagFileResized = FALSE;
    langType language = Option.language;
    if (Option.language == LANG_AUTO)
	language = getFileLanguage (fileName);
    Assert (language != LANG_AUTO);
    if (language == LANG_IGNORE)
	verbose ("ignoring %s (unknown language)\n", fileName);
    else if (! LanguageTable [language]->enabled)
	verbose ("ignoring %s (language disabled)\n", fileName);
    else
    {
	if (Option.filter)
	    openTagFile ();

	tagFileResized = createTagsWithFallback (fileName, language);

	if (Option.filter)
	    closeTagFile (tagFileResized);
	addTotals (1, 0L, 0L);

	return tagFileResized;
    }
    return tagFileResized;
}

/* vi:set tabstop=8 shiftwidth=4 nowrap: */

⌨️ 快捷键说明

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