/* 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 boolean isSpecialTarget (vString *const name) { size_t i = 0; /* All special targets begin with '.'. */ if (vStringLength (name) < 1 || vStringChar (name, i++) != '.') { return FALSE; } while (i < vStringLength (name)) { char ch = vStringChar (name, i++); if (ch != '_' && !isupper (ch)) { return FALSE; } } return TRUE; }
static void appendText (vString *text, vString *appendedText) { if (text != NULL && vStringLength (appendedText) > 0) { if (vStringLength (text) > 0 && vStringLast (text) == ' ' && vStringLength (appendedText) > 0 && vStringChar (appendedText, 0) == ' ') { vStringStripTrailing (text); } vStringCat (text, appendedText); } }
static void findBetaTags (void) { vString *line = vStringNew (); boolean incomment = FALSE; boolean inquote = FALSE; boolean dovirtuals = BetaKinds [K_VIRTUAL].enabled; boolean dopatterns = BetaKinds [K_PATTERN].enabled; do { boolean foundfragmenthere = FALSE; /* find fragment definition (line that starts and ends with --) */ int last; int first; int c; vStringClear (line); while ((c = fileGetc ()) != EOF && c != '\n' && c != '\r') vStringPut (line, c); vStringTerminate (line); last = vStringLength (line) - 1; first = 0; /* skip white space at start and end of line */ while (last && isspace ((int) vStringChar (line, last))) last--; while (first < last && isspace ((int) vStringChar (line, first))) first++; /* if line still has a reasonable length and ... */ if (last - first > 4 && (vStringChar (line, first) == '-' && vStringChar (line, first + 1) == '-' && vStringChar (line, last) == '-' && vStringChar (line, last - 1) == '-')) { if (!incomment && !inquote) { foundfragmenthere = TRUE; /* skip past -- and whitespace. Also skip back past 'dopart' or 'attributes' to the :. We have to do this because there is no sensible way to include whitespace in a ctags token so the conventional space after the ':' would mess us up */ last -= 2; first += 2; while (last && vStringChar (line, last) != ':') last--; while (last && (isspace ((int) vStringChar (line, last-1)))) last--; while (first < last && (isspace ((int) vStringChar (line, first)) || vStringChar (line, first) == '-')) first++; /* If there's anything left it is a fragment title */ if (first < last - 1) { vStringChar (line, last) = 0; if (strcasecmp ("LIB", vStringValue (line) + first) && strcasecmp ("PROGRAM", vStringValue (line) + first)) { makeBetaTag (vStringValue (line) + first, K_FRAGMENT); } } } } else { int pos = 0; int len = vStringLength (line); if (inquote) goto stringtext; if (incomment) goto commenttext; programtext: for ( ; pos < len; pos++) { if (vStringChar (line, pos) == '\'') { pos++; inquote = TRUE; goto stringtext; } if (vStringChar (line, pos) == '{') { pos++; incomment = TRUE; goto commenttext; } if (vStringChar (line, pos) == '(' && pos < len - 1 && vStringChar (line, pos+1) == '*') { pos +=2; incomment = TRUE; goto commenttext; } /* * SLOT definition looks like this: * <<SLOT nameofslot: dopart>> * or * <<SLOT nameofslot: descriptor>> */ if (!foundfragmenthere && vStringChar (line, pos) == '<' && pos+1 < len && vStringChar (line, pos+1) == '<' && strstr (vStringValue (line) + pos, ">>")) { /* Found slot name, get start and end */ int eoname; char c2; pos += 2; /* skip past << */ /* skip past space before SLOT */ while (pos < len && isspace ((int) vStringChar (line, pos))) pos++; /* skip past SLOT */ if (pos+4 <= len && !strncasecmp (vStringValue(line) + pos, "SLOT", (size_t)4)) pos += 4; /* skip past space after SLOT */ while (pos < len && isspace ((int) vStringChar (line, pos))) pos++; eoname = pos; /* skip to end of name */ while (eoname < len && (c2 = vStringChar (line, eoname)) != '>' && c2 != ':' && !isspace ((int) c2)) eoname++; if (eoname < len) { vStringChar (line, eoname) = 0; if (strcasecmp ("LIB", vStringValue (line) + pos) && strcasecmp ("PROGRAM", vStringValue (line) + pos) && strcasecmp ("SLOT", vStringValue (line) + pos)) { makeBetaTag (vStringValue (line) + pos, K_SLOT); } } if (eoname+1 < len) { pos = eoname + 1; } else { pos = len; continue; } } /* Only patterns that are virtual, extensions of virtuals or * final bindings are normally included so as not to overload * totally. * That means one of the forms name:: name:< or name::< */ if (!foundfragmenthere && vStringChar (line, pos) == ':' && (dopatterns || (dovirtuals && (vStringChar (line, pos+1) == ':' || vStringChar (line, pos+1) == '<') ) ) ) { /* Found pattern name, get start and end */ int eoname = pos; int soname; while (eoname && isspace ((int) vStringChar (line, eoname-1))) eoname--; foundanothername: /* terminate right after name */ vStringChar (line, eoname) = 0; soname = eoname; while (soname && isbident (vStringChar (line, soname-1))) { soname--; } if (soname != eoname) { makeBetaTag (vStringValue (line) + soname, K_PATTERN); /* scan back past white space */ while (soname && isspace ((int) vStringChar (line, soname-1))) soname--; if (soname && vStringChar (line, soname-1) == ',') { /* we found a new pattern name before comma */ eoname = soname; goto foundanothername; } } } } goto endofline; commenttext: for ( ; pos < len; pos++) { if (vStringChar (line, pos) == '*' && pos < len - 1 && vStringChar (line, pos+1) == ')') { pos += 2; incomment = FALSE; goto programtext; } if (vStringChar (line, pos) == '}') { pos++; incomment = FALSE; goto programtext; } } goto endofline; stringtext: for ( ; pos < len; pos++) { if (vStringChar (line, pos) == '\\') { if (pos < len - 1) pos++; } else if (vStringChar (line, pos) == '\'') { pos++; /* support obsolete '' syntax */ if (pos < len && vStringChar (line, pos) == '\'') { continue; } inquote = FALSE; goto programtext; } } } endofline: inquote = FALSE; /* This shouldn't really make a difference */ } while (!feof (File.fp)); }