📄 parse.c
字号:
/** $Id: parse.c,v 1.11 2003/10/13 02:35:45 darren Exp $** Copyright (c) 1996-2003, Darren Hiebert** This source code is released for free distribution under the terms of the* GNU General Public License.** This module contains functions for managing source languages and* dispatching files to the appropriate language parser.*//** INCLUDE FILES*/#include "general.h" /* must always come first */#include <string.h>#ifdef HAVE_FNMATCH_H#include <fnmatch.h>#endif#include "debug.h"#include "entry.h"#include "main.h"#define OPTION_WRITE#include "options.h"#include "parsers.h" #include "read.h"#include "routines.h"#include "vstring.h"/** DATA DEFINITIONS*/static parserDefinitionFunc* BuiltInParsers[] = { PARSER_LIST };static parserDefinition** LanguageTable = NULL;static unsigned int LanguageCount = 0;/** FUNCTION DEFINITIONS*/extern void makeSimpleTag ( const vString* const name, kindOption* const kinds, const int kind){ if (kinds [kind].enabled && name != NULL && vStringLength (name) > 0) { tagEntryInfo e; initTagEntry (&e, vStringValue (name)); e.kindName = kinds [kind].name; e.kind = kinds [kind].letter; makeTagEntry (&e); }}/** parserDescription mapping management*/extern parserDefinition* parserNew (const char* name){ parserDefinition* result = xCalloc (1, parserDefinition); result->name = eStrdup (name); return result;}extern const char *getLanguageName (const langType language){ const char* result; if (language == LANG_IGNORE) result = "unknown"; else { Assert (0 <= language && language < (int) LanguageCount); result = LanguageTable [language]->name; } return result;}extern langType getNamedLanguage (const char *const name){ langType result = LANG_IGNORE; unsigned int i; Assert (name != NULL); for (i = 0 ; i < LanguageCount && result == LANG_IGNORE ; ++i) { if (LanguageTable [i]->name != NULL) if (strcasecmp (name, LanguageTable [i]->name) == 0) result = i; } return result;}static langType getExtensionLanguage (const char *const extension){ langType result = LANG_IGNORE; unsigned int i; for (i = 0 ; i < LanguageCount && result == LANG_IGNORE ; ++i) { stringList* const exts = LanguageTable [i]->currentExtensions; if (exts != NULL && stringListExtensionMatched (exts, extension)) result = i; } return result;}static langType getPatternLanguage (const char *const fileName){ langType result = LANG_IGNORE; const char* base = baseFilename (fileName); unsigned int i; for (i = 0 ; i < LanguageCount && result == LANG_IGNORE ; ++i) { stringList* const ptrns = LanguageTable [i]->currentPatterns; if (ptrns != NULL && stringListFileMatched (ptrns, base)) result = i; } return result;}#ifdef SYS_INTERPRETER/* The name of the language interpreter, either directly or as the argument * to "env". */static vString* determineInterpreter (const char* const cmd){ vString* const interpreter = vStringNew (); const char* p = cmd; do { vStringClear (interpreter); for ( ; isspace ((int) *p) ; ++p) ; /* no-op */ for ( ; *p != '\0' && ! isspace ((int) *p) ; ++p) vStringPut (interpreter, (int) *p); vStringTerminate (interpreter); } while (strcmp (vStringValue (interpreter), "env") == 0); return interpreter;}static langType getInterpreterLanguage (const char *const fileName){ langType result = LANG_IGNORE; FILE* const fp = fopen (fileName, "r"); if (fp != NULL) { vString* const vLine = vStringNew (); const char* const line = readLine (vLine, fp); if (line != NULL && line [0] == '#' && line [1] == '!') { const char* const lastSlash = strrchr (line, '/'); const char *const cmd = lastSlash != NULL ? lastSlash+1 : line+2; vString* const interpreter = determineInterpreter (cmd); result = getExtensionLanguage (vStringValue (interpreter)); vStringDelete (interpreter); } vStringDelete (vLine); fclose (fp); } return result;}#endifextern langType getFileLanguage (const char *const fileName){ langType language = Option.language; if (language == LANG_AUTO) { language = getExtensionLanguage (fileExtension (fileName)); if (language == LANG_IGNORE) language = getPatternLanguage (fileName);#ifdef SYS_INTERPRETER if (language == LANG_IGNORE) { fileStatus *status = eStat (fileName); if (status->isExecutable) language = getInterpreterLanguage (fileName); }#endif } return language;}extern void printLanguageMap (const langType language){ boolean first = TRUE; unsigned int i; stringList* map = LanguageTable [language]->currentPatterns; Assert (0 <= language && language < (int) LanguageCount); for (i = 0 ; map != NULL && i < stringListCount (map) ; ++i) { printf ("%s(%s)", (first ? "" : " "), vStringValue (stringListItem (map, i))); first = FALSE; } map = LanguageTable [language]->currentExtensions; for (i = 0 ; map != NULL && i < stringListCount (map) ; ++i) { printf ("%s.%s", (first ? "" : " "), vStringValue (stringListItem (map, i))); first = FALSE; }}extern void installLanguageMapDefault (const langType language){ Assert (language >= 0); if (LanguageTable [language]->currentPatterns != NULL) stringListDelete (LanguageTable [language]->currentPatterns); if (LanguageTable [language]->currentExtensions != NULL) stringListDelete (LanguageTable [language]->currentExtensions); if (LanguageTable [language]->patterns == NULL) LanguageTable [language]->currentPatterns = stringListNew (); else { LanguageTable [language]->currentPatterns = stringListNewFromArgv (LanguageTable [language]->patterns); } if (LanguageTable [language]->extensions == NULL) LanguageTable [language]->currentExtensions = stringListNew (); else { LanguageTable [language]->currentExtensions = stringListNewFromArgv (LanguageTable [language]->extensions); } if (Option.verbose) printLanguageMap (language); verbose ("\n");}extern void installLanguageMapDefaults (void){ unsigned int i; for (i = 0 ; i < LanguageCount ; ++i) { verbose (" %s: ", getLanguageName (i)); installLanguageMapDefault (i); }}extern void clearLanguageMap (const langType language){ Assert (0 <= language && language < (int) LanguageCount); stringListClear (LanguageTable [language]->currentPatterns); stringListClear (LanguageTable [language]->currentExtensions);}extern void addLanguagePatternMap (const langType language, const char* ptrn){ vString* const str = vStringNewInit (ptrn); Assert (0 <= language && language < (int) LanguageCount); if (LanguageTable [language]->currentPatterns == NULL) LanguageTable [language]->currentPatterns = stringListNew (); stringListAdd (LanguageTable [language]->currentPatterns, str);}extern void addLanguageExtensionMap ( const langType language, const char* extension){ vString* const str = vStringNewInit (extension); Assert (0 <= language && language < (int) LanguageCount); stringListAdd (LanguageTable [language]->currentExtensions, str);}extern void enableLanguages (const boolean state){ unsigned int i; for (i = 0 ; i < LanguageCount ; ++i) LanguageTable [i]->enabled = state;}extern void enableLanguage (const langType language, const boolean state){ Assert (0 <= language && language < (int) LanguageCount); LanguageTable [language]->enabled = state;}static void initializeParsers (void){ unsigned int i; for (i = 0 ; i < LanguageCount ; ++i) if (LanguageTable [i]->initialize != NULL) (LanguageTable [i]->initialize) ((langType) i);}extern void initializeParsing (void){ unsigned int builtInCount; unsigned int i; builtInCount = sizeof (BuiltInParsers) / sizeof (BuiltInParsers [0]); LanguageTable = xMalloc (builtInCount, parserDefinition*); verbose ("Installing parsers: "); for (i = 0 ; i < builtInCount ; ++i) { parserDefinition* const def = (*BuiltInParsers [i]) (); if (def != NULL) { boolean accepted = FALSE; if (def->name == NULL || def->name[0] == '\0') error (FATAL, "parser definition must contain name\n"); else if (def->regex) {#ifdef HAVE_REGEX def->parser = findRegexTags; accepted = TRUE;#endif } else if ((def->parser == NULL) == (def->parser2 == NULL)) error (FATAL, "%s parser definition must define one and only one parsing routine\n", def->name); else accepted = TRUE; if (accepted) { verbose ("%s%s", i > 0 ? ", " : "", def->name); def->id = LanguageCount++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -