static void getScopeInfo(texKind kind, vString *const parentKind, vString *const parentName) { int i; /* * Put labels separately instead of under their scope. * Is this The Right Thing To Do? */ if (kind >= TEXTAG_LABEL) { return; } /* * This abuses the enum internals somewhat, but it should be ok in this * case. */ for (i = kind - 1; i >= TEXTAG_PART; --i) { if (i == TEXTAG_SUBSECTION && vStringLength(lastSubS) > 0) { vStringCopyS(parentKind, "subsection"); break; } else if (i == TEXTAG_SECTION && vStringLength(lastSection) > 0) { vStringCopyS(parentKind, "section"); break; } else if (i == TEXTAG_CHAPTER && vStringLength(lastChapter) > 0) { vStringCopyS(parentKind, "chapter"); break; } else if (i == TEXTAG_PART && vStringLength(lastPart) > 0) { vStringCopyS(parentKind, "part"); break; } } /* * Is '""' the best way to separate scopes? It has to be something that * should ideally never occur in normal LaTeX text. */ for (i = TEXTAG_PART; i < (int)kind; ++i) { if (i == TEXTAG_PART && vStringLength(lastPart) > 0) { vStringCat(parentName, lastPart); } else if (i == TEXTAG_CHAPTER && vStringLength(lastChapter) > 0) { if (vStringLength(parentName) > 0) { vStringCatS(parentName, "\"\""); } vStringCat(parentName, lastChapter); } else if (i == TEXTAG_SECTION && vStringLength(lastSection) > 0) { if (vStringLength(parentName) > 0) { vStringCatS(parentName, "\"\""); } vStringCat(parentName, lastSection); } else if (i == TEXTAG_SUBSECTION && vStringLength(lastSubS) > 0) { if (vStringLength(parentName) > 0) { vStringCatS(parentName, "\"\""); } vStringCat(parentName, lastSubS); } } }
static void findTag (vString *const name) { int c = '\0'; vhdlKind kind; vStringCopyToLower (Keyword, name); kind = (vhdlKind)lookupKeyword (vStringValue (Keyword), Lang_vhdl); if (kind == K_UNDEFINED) { c = skipWhite (vGetc ()); vStringCopyS(Lastname,vStringValue(name)); if (c == ':') { c = skipWhite (vGetc ()); if (isIdentifierCharacter (c)) { readIdentifier (name, c); vStringCopyToLower (Keyword, name); lookupKeyword (vStringValue (Keyword), Lang_vhdl); kind = (vhdlKind)lookupKeyword (vStringValue (Keyword), Lang_vhdl); if (kind == K_PROCESS || kind == K_BLOCK || kind == K_PORT) { makeSimpleTag (Lastname, VhdlKinds, kind); } } } else { vUngetc (c); } } else { if (kind == K_SIGNAL) { while (c!=':') { c = skipWhite (vGetc ()); if (c==',') c = vGetc (); if (isIdentifierCharacter (c)) tagNameList (kind, c); else break; c = vGetc (); } } else if (kind == K_PROCESS || kind == K_BLOCK) { vStringCopyS(TagName,"unnamed"); makeSimpleTag (TagName, VhdlKinds, kind); } else { c = skipWhite (vGetc ()); if (c=='\"') c = vGetc (); if (isIdentifierCharacter (c)) tagNameList (kind, c); } } }
static void findOcamlTags (void) { vString *name = vStringNew (); lexingState st; ocaToken tok; initStack (); computeModuleName (); tempIdent = vStringNew (); lastModule = vStringNew (); lastClass = vStringNew (); voidName = vStringNew (); vStringCopyS (voidName, "_"); st.name = vStringNew (); st.cp = fileReadLine (); toDoNext = &globalScope; tok = lex (&st); while (tok != Tok_EOF) { (*toDoNext) (st.name, tok); tok = lex (&st); } vStringDelete (st.name); vStringDelete (name); vStringDelete (voidName); vStringDelete (tempIdent); vStringDelete (lastModule); vStringDelete (lastClass); clearStack (); }
static boolean recurseIntoDirectory (const char *const dirName) { boolean resize = FALSE; if (isRecursiveLink (dirName)) verbose ("ignoring \"%s\" (recursive link)\n", dirName); else if (! Option.recurse) verbose ("ignoring \"%s\" (directory)\n", dirName); else { verbose ("RECURSING into directory \"%s\"\n", dirName); #if defined (HAVE_OPENDIR) resize = recurseUsingOpendir (dirName); #elif defined (HAVE_FINDFIRST) || defined (HAVE__FINDFIRST) { vString *const pattern = vStringNew (); vStringCopyS (pattern, dirName); vStringPut (pattern, OUTPUT_PATH_SEPARATOR); vStringCatS (pattern, "*.*"); resize = createTagsForWildcardUsingFindfirst (vStringValue (pattern)); vStringDelete (pattern); } #endif } return resize; }
CXXToken * cxxTokenCreateAnonymousIdentifier(enum CXXTagKind k) { g_uNextAnonumousIdentiferId++; char szNum[32]; CXXToken * t = cxxTokenCreate(); t->eType = CXXTokenTypeIdentifier; vStringCopyS(t->pszWord, "__anon"); // The names of anonymous structures depend on the name of // the file being processed so the identifiers won't collide across // multiple ctags runs with different file sets. unsigned int uHash = hash((const unsigned char *)getInputFileName()); sprintf(szNum,"%08x%02x%02x",uHash,g_uNextAnonumousIdentiferId, k); vStringCatS(t->pszWord,szNum); t->bFollowedBySpace = TRUE; t->iLineNumber = getInputLineNumber(); t->oFilePosition = getInputFilePosition(); return t; }
static bool recurseIntoDirectory (const char *const dirName) { static unsigned int recursionDepth = 0; recursionDepth++; bool resize = false; if (isRecursiveLink (dirName)) verbose ("ignoring \"%s\" (recursive link)\n", dirName); else if (! Option.recurse) verbose ("ignoring \"%s\" (directory)\n", dirName); else if(recursionDepth > Option.maxRecursionDepth) verbose ("not descending in directory \"%s\" (depth %u > %u)\n", dirName, recursionDepth, Option.maxRecursionDepth); else { verbose ("RECURSING into directory \"%s\"\n", dirName); #if defined (HAVE_OPENDIR) resize = recurseUsingOpendir (dirName); #elif defined (HAVE__FINDFIRST) { vString *const pattern = vStringNew (); vStringCopyS (pattern, dirName); vStringPut (pattern, OUTPUT_PATH_SEPARATOR); vStringCatS (pattern, "*.*"); resize = createTagsForWildcardUsingFindfirst (vStringValue (pattern)); vStringDelete (pattern); } #endif } recursionDepth--; return resize; }
/* 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 (c_tags_ignore != NULL) { const size_t nameLen = strlen (name); unsigned int i; guint len = g_strv_length (c_tags_ignore); vString *token = vStringNew(); if (pIgnoreParens != NULL) *pIgnoreParens = FALSE; for (i = 0 ; i < len ; ++i) { size_t tokenLen; vStringCopyS (token, c_tags_ignore[i]); vStringTerminate (token); tokenLen = vStringLength (token); if (tokenLen >= 2 && vStringChar (token, tokenLen - 1) == '*' && strncmp (vStringValue (token), name, tokenLen - 1) == 0) { result = TRUE; break; } if (strncmp (vStringValue (token), name, nameLen) == 0) { 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; } } } vStringDelete (token); } return result; }
static void findHxTags (void) { vString *name = vStringNew (); vString *clsName = vStringNew(); vString *scope2 = vStringNew(); vString *laccess = vStringNew(); const char *const priv = "private"; const char *const pub = "public"; const unsigned char *line; while ((line = readLineFromInputFile ()) != NULL) { const unsigned char *cp = line; another: while (isspace (*cp)) cp++; vStringCopyS(laccess,priv); if (strncmp ((const char*) cp, "var", (size_t) 3) == 0 && isspace ((int) cp [3])) { cp += 3; while (isspace ((int) *cp)) ++cp; vStringClear (name); while (isalnum ((int) *cp) || *cp == '_') { vStringPut (name, (int) *cp); ++cp; } vStringTerminate (name); makeSimpleTag (name, HxKinds, HXTAG_VARIABLE); vStringClear (name); } else if (strncmp ((const char*) cp, "function", (size_t) 8) == 0 && isspace ((int) cp [8])) { cp += 8; while (isspace ((int) *cp)) ++cp; vStringClear (name); while (isalnum ((int) *cp) || *cp == '_') { vStringPut (name, (int) *cp); ++cp; } vStringTerminate (name); makeSimpleTag (name, HxKinds, HXTAG_METHODS); vStringClear (name); } else if (strncmp ((const char*) cp, "class", (size_t) 5) == 0 && isspace ((int) cp [5])) { cp += 5; while (isspace ((int) *cp)) ++cp; vStringClear (name); while (isalnum ((int) *cp) || *cp == '_') { vStringPut (name, (int) *cp); ++cp; } vStringTerminate (name); makeSimpleTag (name, HxKinds, HXTAG_CLASS); vStringCopy(clsName,name); vStringClear (name); } else if (strncmp ((const char*) cp, "enum", (size_t) 4) == 0 && isspace ((int) cp [4])) { cp += 4; while (isspace ((int) *cp)) ++cp; vStringClear (name); while (isalnum ((int) *cp) || *cp == '_') { vStringPut (name, (int) *cp); ++cp; } vStringTerminate (name); makeSimpleTag (name, HxKinds, HXTAG_ENUM); vStringClear (name); } else if (strncmp ((const char*) cp, "public", (size_t) 6) == 0 && isspace((int) cp [6])) { cp += 6; while (isspace ((int) *cp)) ++cp; vStringCopyS(laccess,pub); goto another; } else if (strncmp ((const char*) cp, "static", (size_t) 6) == 0 && isspace((int) cp [6])) { cp += 6; while (isspace ((int) *cp)) ++cp; goto another; } else if (strncmp ((const char*) cp, "interface", (size_t) 9) == 0 && isspace((int) cp [9])) { cp += 9; while (isspace ((int) *cp)) ++cp; vStringClear (name); while (isalnum ((int) *cp) || *cp == '_') { vStringPut (name, (int) *cp); ++cp; } vStringTerminate (name); makeSimpleTag (name, HxKinds, HXTAG_INTERFACE); vStringClear (name); } else if (strncmp ((const char *) cp,"typedef",(size_t) 7) == 0 && isspace(((int) cp[7]))) { cp += 7; while (isspace ((int) *cp)) ++cp; vStringClear (name); while (isalnum ((int) *cp) || *cp == '_') { vStringPut (name, (int) *cp); ++cp; } vStringTerminate (name); makeSimpleTag (name, HxKinds, HXTAG_TYPEDEF); vStringClear (name); } } vStringDelete(name); vStringDelete(clsName); vStringDelete(scope2); vStringDelete(laccess); }
static void enterScope (tokenInfo *const parentToken, const vString *const extraScope, const int parentKind) { tokenInfo *token = newToken (); int origParentKind = parentToken->parentKind; copyToken (token, parentToken, TRUE); if (extraScope) { token->parentKind = parentKind; addToScope (token, extraScope, origParentKind); } readToken (token); while (token->type != TOKEN_EOF && token->type != TOKEN_CLOSE_CURLY) { boolean readNext = TRUE; switch (token->type) { case TOKEN_OPEN_CURLY: enterScope (token, NULL, -1); break; case TOKEN_KEYWORD: switch (token->keyword) { /* handle anonymous classes */ case KEYWORD_new: readToken (token); if (token->keyword != KEYWORD_class) readNext = FALSE; else { char buf[32]; tokenInfo *name = newToken (); copyToken (name, token, TRUE); snprintf (buf, sizeof buf, "AnonymousClass%u", ++AnonymousID); vStringCopyS (name->string, buf); readNext = parseClassOrIface (token, K_CLASS, name); deleteToken (name); } break; case KEYWORD_class: readNext = parseClassOrIface (token, K_CLASS, NULL); break; case KEYWORD_interface: readNext = parseClassOrIface (token, K_INTERFACE, NULL); break; case KEYWORD_trait: readNext = parseTrait (token); break; case KEYWORD_function: readNext = parseFunction (token, NULL); break; case KEYWORD_const: readNext = parseConstant (token); break; case KEYWORD_define: readNext = parseDefine (token); break; case KEYWORD_namespace: readNext = parseNamespace (token); break; case KEYWORD_private: CurrentStatement.access = ACCESS_PRIVATE; break; case KEYWORD_protected: CurrentStatement.access = ACCESS_PROTECTED; break; case KEYWORD_public: CurrentStatement.access = ACCESS_PUBLIC; break; case KEYWORD_var: CurrentStatement.access = ACCESS_PUBLIC; break; case KEYWORD_abstract: CurrentStatement.impl = IMPL_ABSTRACT; break; default: break; } break; case TOKEN_VARIABLE: readNext = parseVariable (token); break; default: break; } if (readNext) readToken (token); } copyToken (parentToken, token, FALSE); parentToken->parentKind = origParentKind; deleteToken (token); }
static void parseValue (tokenInfo *const token) { if (token->type == TOKEN_OPEN_CURLY) { tokenInfo *name = newToken (); do { readTokenFull (token, TRUE); if (token->type == TOKEN_STRING) { jsonKind tagKind = TAG_NULL; /* default in case of invalid value */ copyToken (name, token); /* skip any possible garbage before the value */ skipToOneOf3 (token, TOKEN_CLOSE_CURLY, TOKEN_COLON, TOKEN_COMMA); if (token->type == TOKEN_COLON) { readToken (token); tagKind = tokenToKind (token->type); pushScope (token, name, tagKind); parseValue (token); popScope (token, name); } makeJsonTag (name, tagKind); } /* skip to the end of the construct */ skipToOneOf2 (token, TOKEN_CLOSE_CURLY, TOKEN_COMMA); } while (token->type != TOKEN_EOF && token->type != TOKEN_CLOSE_CURLY); if (token->type == TOKEN_CLOSE_CURLY) readToken (token); deleteToken (name); } else if (token->type == TOKEN_OPEN_SQUARE) { tokenInfo *name = newToken (); char buf[32]; unsigned int nth = 0; readToken (token); while (token->type != TOKEN_EOF && token->type != TOKEN_CLOSE_SQUARE) { jsonKind tagKind; tagKind = tokenToKind (token->type); copyToken (name, token); snprintf (buf, sizeof buf, "%u", nth++); vStringCopyS (name->string, buf); makeJsonTag (name, tagKind); pushScope (token, name, tagKind); parseValue (token); popScope (token, name); /* skip to the end of the construct */ skipToOneOf2 (token, TOKEN_CLOSE_SQUARE, TOKEN_COMMA); if (token->type != TOKEN_CLOSE_SQUARE) readToken (token); } if (token->type == TOKEN_CLOSE_SQUARE) readToken (token); deleteToken (name); } }