static boolean AutomakeMakeTag (vString *const name, const char* suffix, boolean appending, int kindex, int rindex, struct sBlacklist *blacklist, void *data) { int *index = data; size_t expected_len; size_t len; char* tail; vString *subname; int i; len = vStringLength (name); expected_len = strlen (suffix); if (len <= expected_len) return FALSE; for (i = 0; blacklist[i].type != BL_END; i++) { if (bl_check (vStringValue(name), blacklist + i) == FALSE) return FALSE; } tail = vStringValue (name) + len - expected_len; if (strcmp (tail, suffix)) return FALSE; subname = vStringNew(); /* ??? dist, nodist, nobase, notrans,... */ if (strncmp (vStringValue(name), "dist_", 5) == 0) vStringNCopyS(subname, vStringValue(name) + 5, len - expected_len - 5); else vStringNCopyS(subname, vStringValue(name), len - expected_len); if (rindex == ROLE_INDEX_DEFINITION) { *index = makeSimpleTag (subname, AutomakeKinds, kindex); addAutomakeDirectory (subname, *index); } else { *index = CORK_NIL; if (appending) *index = lookupAutomakeDirectory (subname); if ((!appending) || (*index == CORK_NIL)) *index = makeSimpleRefTag (subname, AutomakeKinds, kindex, rindex); } vStringDelete (subname); return TRUE; }
static void newInclude (vString *const name, boolean optional) { makeSimpleRefTag (name, MakeKinds, K_INCLUDE, optional? R_INCLUDE_OPTIONAL: R_INCLUDE_GENERIC); }
static void makeAsmTag ( const vString *const name, const vString *const operator, const bool labelCandidate, const bool nameFollows, const bool directive, unsigned int *lastMacroCorkIndex) { if (vStringLength (name) > 0) { bool found; const AsmKind kind = operatorKind (operator, &found); if (found) { if (kind > K_NONE) makeSimpleTag (name, kind); } else if (isDefineOperator (operator)) { if (! nameFollows) makeSimpleTag (name, K_DEFINE); } else if (labelCandidate) { operatorKind (name, &found); if (! found) makeSimpleTag (name, K_LABEL); } else if (directive) { bool found_dummy; const AsmKind kind_for_directive = operatorKind (name, &found_dummy); tagEntryInfo *macro_tag; switch (kind_for_directive) { case K_NONE: break; case K_MACRO: *lastMacroCorkIndex = makeSimpleTag (operator, kind_for_directive); break; case K_PSUEDO_MACRO_END: if (*lastMacroCorkIndex != CORK_NIL) { macro_tag = getEntryInCorkQueue (*lastMacroCorkIndex); macro_tag->extensionFields.endLine = getInputLineNumber (); *lastMacroCorkIndex = CORK_NIL; } break; case K_SECTION: makeSimpleRefTag (operator, kind_for_directive, ASM_SECTION_PLACEMENT); break; default: makeSimpleTag (operator, kind_for_directive); } } } }
static void findShTags (void) { vString *name = vStringNew (); const unsigned char *line; vString *hereDocDelimiter = NULL; boolean hereDocIndented = FALSE; boolean (* check_char)(int); while ((line = readLineFromInputFile ()) != NULL) { const unsigned char* cp = line; shKind found_kind = K_NOTHING; if (hereDocDelimiter) { if (hereDocIndented) { while (*cp == '\t') cp++; } if (strcmp ((const char *) cp, vStringValue (hereDocDelimiter)) == 0) { vStringDelete (hereDocDelimiter); hereDocDelimiter = NULL; } continue; } while (*cp != '\0') { /* jump over whitespace */ while (isspace ((int)*cp)) cp++; /* jump over strings */ if (*cp == '"') cp = skipDoubleString (cp); else if (*cp == '\'') cp = skipSingleString (cp); /* jump over comments */ else if (*cp == '#') break; /* jump over here-documents */ else if (cp[0] == '<' && cp[1] == '<') { const unsigned char *start, *end; boolean trimEscapeSequences = FALSE; boolean quoted = FALSE; cp += 2; /* an optional "-" strips leading tabulations from the heredoc lines */ if (*cp != '-') hereDocIndented = FALSE; else { hereDocIndented = TRUE; cp++; } while (isspace (*cp)) cp++; start = end = cp; /* the delimiter can be surrounded by quotes */ if (*cp == '"') { start++; end = cp = skipDoubleString (cp); /* we need not to worry about variable substitution, they * don't happen in heredoc delimiter definition */ trimEscapeSequences = TRUE; quoted = TRUE; } else if (*cp == '\'') { start++; end = cp = skipSingleString (cp); quoted = TRUE; } else { while (isIdentChar ((int) *cp)) cp++; end = cp; } if (end > start || quoted) { /* The input may be broken as a shell script but we need to avoid memory leaking. */ if (hereDocDelimiter) vStringClear(hereDocDelimiter); else hereDocDelimiter = vStringNew (); for (; end > start; start++) { if (trimEscapeSequences && *start == '\\') start++; vStringPut (hereDocDelimiter, *start); } } } if (strncmp ((const char*) cp, "function", (size_t) 8) == 0 && isspace ((int) cp [8])) { found_kind = K_FUNCTION; cp += 8; } else if (strncmp ((const char*) cp, "alias", (size_t) 5) == 0 && isspace ((int) cp [5])) { found_kind = K_ALIAS; cp += 5; } else if (isXtagEnabled (XTAG_REFERENCE_TAGS) && ShKinds [K_SOURCE].enabled) { if (cp [0] == '.' && isspace((int) cp [1])) { found_kind = K_SOURCE; ++cp; } else if (strncmp ((const char*) cp, "source", (size_t) 6) == 0 && isspace((int) cp [6])) { found_kind = K_SOURCE; cp += 6; } } if (found_kind != K_NOTHING) while (isspace ((int) *cp)) ++cp; // Get the name of the function, alias or file to be read by source check_char = isIdentChar; if (found_kind == K_SOURCE) check_char = isFileChar; if (! check_char ((int) *cp)) { found_kind = K_NOTHING; if (*cp != '\0') ++cp; continue; } while (check_char ((int) *cp)) { vStringPut (name, (int) *cp); ++cp; } vStringTerminate (name); while (isspace ((int) *cp)) ++cp; if ((found_kind != K_SOURCE) && *cp == '(') { ++cp; while (isspace ((int) *cp)) ++cp; if (*cp == ')') { found_kind = K_FUNCTION; ++cp; } } if (found_kind != K_NOTHING) { if (found_kind == K_SOURCE) makeSimpleRefTag (name, ShKinds, K_SOURCE, R_SOURCE_GENERIC); else makeSimpleTag (name, ShKinds, found_kind); found_kind = K_NOTHING; } vStringClear (name); } } vStringDelete (name); if (hereDocDelimiter) vStringDelete (hereDocDelimiter); }