bool IsValidIdentifier(const char *Str) { if (!isidentf(Str[0])) return false; while (char c = *Str++) if (!isident(c)) return false; return true; }
bool is_template(const char *text) { if(*text == '<') { const char *p = comment(text + 1); return isidentf(*p); } return false; } /* is_template */
void ScanForFunctions(CLanguageProxy& proxy) { const char* text = proxy.Text(), *max = text + proxy.Size(); char* scope = (char*)"file"; if (*max != 0) return; while (text < max) { text = comment(text, false); switch (*text) { case 0: return; case '\'': text = skip(text + 1, '\''); break; case '"': text = skip(text + 1, '"'); break; case '(': case '{': case '[': text = parens(text + 1, *text); break; case '#': text = preprocessor(text + 1, proxy); break; default: if (isidentf(*text)) text = ident(text, proxy, scope); else text++; break; } } } /* ScanForFunctions */
const char *ident(const char *text, CLanguageProxy& proxy, char *&scope) { const char *start = text, *id = start; char nameBuf[kMaxNameSize], *name = nameBuf; int size = 0, offset = start - proxy.Text(); bool destructor = false; while (isident(*text)) name_append(text, name, size); *name = 0; text = comment(text); if (strcmp(nameBuf, "extern") == 0) return i_extern(text); else if (strcmp(nameBuf, "header") == 0) { // first add "header" while (!isspace(*text)) { name_append(text, name, size); } // then a space *name++ = ' '; // skip past the double quote text = skip(text, '"'); // save the identifier location start = text; // put in the identifier [up to next quote] while (*text != '"') name_append(text, name, size); // terminate *name = 0; // add it char match[256]; long l = std::min((long)255, text - start); strncpy(match, start, l); match[l] = 0; if (proxy.Types()) proxy.AddFunction(nameBuf, match, offset, false); // walk past the double quote text++; // eat the code text = parens(text + 1, '{'); return text; } else if (strcmp(nameBuf, "options") == 0) { // first add the scope label for (char * c = scope ; (size < kMaxNameSize) ; size++) { if (*c == '\0') break; *name++ = *c++; } // then a space *name++ = ' '; // save the "options" location start = text; // then add "options" while (!isspace(*text)) { name_append(text, name, size); } // terminate *name = 0; // add it char match[256]; long l = std::min((long)255, text - start); strncpy(match, start, l); match[l] = 0; if (proxy.Types()) proxy.AddFunction(nameBuf, match, offset, false); // walk past the double quote text++; // eat the code text = parens(text + 1, '{'); return text; } else if (strcmp(nameBuf, "class") == 0 || strcmp(nameBuf, "struct") == 0 || strcmp(nameBuf, "union") == 0) { *name++ = ' '; if (isidentf(*text)) { while (isident(*text)) name_append(text, name, size); *name = 0; text = comment(text); if (*text == ':') { text = comment(text + 1); while (isident(*text)) text++; text = comment(text); while (isident(*text)) text++; text = comment(text); } if (*text == '{' && proxy.Types()) { char match[256]; long l = std::min((long)255, text - start); strncpy(match, start, l); match[l] = 0; proxy.AddFunction(nameBuf, match, offset, false); } } if (*text == '{') text = parens(text + 1, '{'); text = comment(text); while (isidentf(*text)) { char match[kMaxNameSize]; name = strchr(nameBuf, ' ') + 1; strncpy(match, nameBuf, name - nameBuf - 1); match[name - nameBuf - 1] = 0; while (isident(*text)) name_append(text, name, size); *name = 0; if (proxy.Types()) proxy.AddFunction(nameBuf, match, offset, false); text = comment(text); while (*text == ',' || *text == '*') text = comment(text + 1); } return text; } if (is_template(text)) { name_append(text, name, size); text = comment(text); while (isident(*text)) { while (isident(*text)) name_append(text, name, size); text = comment(text); if (*text == ',') { name_append(text, name, size); text = comment(text); } } if (*text == '>') { name_append(text, name, size); text = comment(text); } } while (*text == ':' && text[1] == ':') { name_append(text, name, size); name_append(text, name, size); text = comment(text); id = name; if (*text == '~') { name_append(text, name, size); text = comment(text); destructor = true; } if (isidentf(*text)) while (isident(*text)) name_append(text, name, size); text = comment(text); if (is_template(text)) { name_append(text, name, size); text = comment(text); while (isident(*text)) { while (isident(*text)) name_append(text, name, size); text = comment(text); if (*text == ',') { name_append(text, name, size); text = comment(text); } } if (*text == '>') { name_append(text, name, size); text = comment(text); } } } if (!destructor && strcmp(id, "operator") == 0) { if (*text == '(') name_append(text, name, size); text = comment(text); while (*text != '(' && size < kMaxNameSize) { if (isidentf(*text)) { while (isident(*text)) name_append(text, name, size); } else if (! isspace(*text)) { while (! isspace(*text) && ! isidentf(*text) && *text != '(' && ! (*text == '/' && (text[1] == '*' || text[1] == '/'))) name_append(text, name, size); } text = comment(text); } } *name = 0; if (*text == '(') { char match[256]; long l = std::min((long)255, text - start); strncpy(match, start, l); match[l] = 0; text = parens(text + 1, '('); text = comment(text); if (*text == ':') { while (*text != '{' && *text != ';') text++; if (*text == '{') { text = parens(text + 1, '{'); proxy.AddFunction(nameBuf, match, offset, false); } else { text++; if (proxy.Prototypes()) proxy.AddFunction(nameBuf, match, offset, true); } if (*text == '\n') text++; return text; } if (*text == ';') { if (proxy.Prototypes()) proxy.AddFunction(nameBuf, match, offset, true); return text + 1; } if (isidentf(*text) || *text == '{') { proxy.AddFunction(nameBuf, match, offset, false); text = skip_ne(text, '{'); text = parens(text, '{'); if (*text == '\n') text ++; return text; } } return text; } /* ident */