📄 parse.c
字号:
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 + -