static void processFunction (tokenInfo *const token) { int c; tokenInfo *classType; /* Search for function name * Last identifier found before a '(' or a ';' is the function name */ c = skipWhite (vGetc ()); do { readIdentifier (token, c); c = skipWhite (vGetc ()); /* Identify class type prefixes and create respective context*/ if (isInputLanguage (Lang_systemverilog) && c == ':') { c = vGetc (); if (c == ':') { verbose ("Found function declaration with class type %s\n", vStringValue (token->name)); classType = newToken (); vStringCopy (classType->name, token->name); classType->kind = K_CLASS; createContext (classType); currentContext->classScope = true; } else { vUngetc (c); } } } while (c != '(' && c != ';' && c != EOF); if ( vStringLength (token->name) > 0 ) { verbose ("Found function: %s\n", vStringValue (token->name)); /* Create tag */ createTag (token); /* Get port list from function */ processPortList (c); } }
static void tagNameList (const verilogKind kind, int c) { vString *name = vStringNew (); bool repeat; Assert (isIdentifierCharacter (c)); do { repeat = false; if (isIdentifierCharacter (c)) { readIdentifier (name, c); makeSimpleTag (name, VerilogKinds, kind); } else break; c = skipWhite (vGetc ()); if (c == '[') c = skipPastMatch ("[]"); c = skipWhite (c); if (c == '=') { c = skipWhite (vGetc ()); if (c == '{') skipPastMatch ("{}"); else { do c = vGetc (); while (c != ',' && c != ';'); } } if (c == ',') { c = skipWhite (vGetc ()); repeat = true; } else repeat = false; } while (repeat); vStringDelete (name); vUngetc (c); }
static void findVerilogTags (void) { tokenInfo *const token = newToken (); int c = '\0'; currentContext = newToken (); while (c != EOF) { c = vGetc (); c = skipWhite (c); switch (c) { /* Store current block name whenever a : is found * This is used later by any tag type that requires this information * */ case ':': vStringCopy (currentContext->blockName, token->name); break; /* Skip interface modport port declarations */ case '(': if (currentContext && currentContext->lastKind == K_MODPORT) { skipPastMatch ("()"); } break; /* Drop context on prototypes because they don't have an end * statement */ case ';': if (currentContext->scope && currentContext->scope->prototype) { verbose ("Dropping context %s\n", vStringValue (currentContext->name)); currentContext = popToken (currentContext); currentContext->prototype = FALSE; } /* Prototypes end at the end of statement */ if (currentContext->prototype) { currentContext->prototype = FALSE; } break; default : if (isIdentifierCharacter (c)) { readIdentifier (token, c); updateKind (token); findTag (token); } } } deleteToken (token); pruneTokens (currentContext); currentContext = NULL; }
static void findTag (vString *const name) { const verilogKind kind = (verilogKind) lookupKeyword (vStringValue (name), Lang_verilog); if (kind == K_CONSTANT && vStringItem (name, 0) == '`') { /* Bug #961001: Verilog compiler directives are line-based. */ int c = skipWhite (vGetc ()); readIdentifier (name, c); makeSimpleTag (name, VerilogKinds, kind); /* Skip the rest of the line. */ do { c = vGetc(); } while (c != '\n'); vUngetc (c); } else if (kind != K_UNDEFINED) { int c = skipWhite (vGetc ()); /* Many keywords can have bit width. * reg [3:0] net_name; * inout [(`DBUSWIDTH-1):0] databus; */ if (c == '(') c = skipPastMatch ("()"); c = skipWhite (c); if (c == '[') c = skipPastMatch ("[]"); c = skipWhite (c); if (c == '#') { c = vGetc (); if (c == '(') c = skipPastMatch ("()"); } c = skipWhite (c); if (isIdentifierCharacter (c)) tagNameList (kind, c); } }
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 bool readIdentifier (vString *const name, int c) { vStringClear (name); if (isIdentifierCharacter (c)) { while (isIdentifierCharacter (c)) { vStringPut (name, c); c = vGetc (); } vUngetc (c); } return (bool)(name->length > 0); }
static void processFunction (tokenInfo *const token) { int c; /* Search for function name * Last identifier found before a '(' or a ';' is the function name */ c = skipWhite (vGetc ()); do { readIdentifier (token, c); c = skipWhite (vGetc ()); } while (c != '(' && c != ';' && c != EOF); if ( vStringLength (token->name) > 0 ) { verbose ("Found function: %s\n", vStringValue (token->name)); /* Create tag */ createTag (token); /* Get port list from function */ processPortList (c); } }
static int skipMacro (int c) { tokenInfo *token = newToken ();; if (c == '`') { /* Skip keyword */ if (isIdentifierCharacter (c = vGetc ())) { readIdentifier (token, c); c = vGetc (); /* Skip next keyword if macro is `ifdef or `ifndef or `elsif*/ if (strcmp (vStringValue (token->name), "ifdef") == 0 || strcmp (vStringValue (token->name), "ifndef") == 0 || strcmp (vStringValue (token->name), "elsif") == 0) { verbose ("%c\n", c); c = skipWhite (c); readIdentifier (token, c); c = vGetc (); verbose ("Skipping conditional macro %s\n", vStringValue (token->name)); } /* Skip macro functions */ else { c = skipWhite (c); if (c == '(') { c = skipPastMatch ("()"); } } } } deleteToken (token); return c; }
static bool readIdentifier (tokenInfo *const token, int c) { vStringClear (token->name); if (isIdentifierCharacter (c)) { while (isIdentifierCharacter (c)) { vStringPut (token->name, c); c = vGetc (); } vUngetc (c); token->lineNumber = getInputLineNumber (); token->filePosition = getInputFilePosition (); } return (bool)(vStringLength (token->name) > 0); }
static void processTypedef (tokenInfo *const token) { /*Note: At the moment, only identifies typedef name and not its contents */ int c; /* Get identifiers */ c = skipWhite (vGetc ()); while (isIdentifierCharacter (c)) { readIdentifier (token, c); c = skipWhite (vGetc ()); } /* Skip bus width definition */ if (c == '[') { skipPastMatch ("[]"); c = skipWhite (vGetc ()); } /* Skip typedef contents */ if (c == '{') { skipPastMatch ("{}"); c = skipWhite (vGetc ()); } /* Skip past class parameter override */ if (c == '#') { c = skipWhite (vGetc ()); if (c == '(') { skipPastMatch ("()"); } c = skipWhite (vGetc ()); } /* Read new typedef identifier */ if (isIdentifierCharacter (c)) { readIdentifier (token, c); } /* Use last identifier to create tag */ createTag (token); }
static void findVhdlTags (void) { volatile boolean newStatement = TRUE; volatile int c = '\0'; exception_t exception = (exception_t) setjmp (Exception); Name = vStringNew (); Lastname = vStringNew (); Keyword = vStringNew (); TagName = vStringNew (); if (exception == ExceptionNone) while (c != EOF) { c = vGetc (); switch (c) { case ';': case '\n': newStatement = TRUE; break; case ' ': case '\t': break; default: if (newStatement && readIdentifier (Name, c)) { findTag (Name); } newStatement = FALSE; break; } } vStringDelete (Name); vStringDelete (Lastname); vStringDelete (Keyword); vStringDelete (TagName); }
static void tagNameList (tokenInfo* token, int c) { verilogKind localKind; boolean repeat; /* Many keywords can have bit width. * reg [3:0] net_name; * inout [(`DBUSWIDTH-1):0] databus; */ if (c == '(') c = skipPastMatch ("()"); c = skipWhite (c); if (c == '[') c = skipPastMatch ("[]"); c = skipWhite (c); if (c == '#') { c = vGetc (); if (c == '(') c = skipPastMatch ("()"); } c = skipWhite (c); do { repeat = FALSE; while (c == '`' && c != EOF) { c = skipMacro (c); } if (isIdentifierCharacter (c)) { readIdentifier (token, c); localKind = getKind (token); /* Create tag in case name is not a known kind ... */ if (localKind == K_UNDEFINED) { createTag (token); } /* ... or else continue searching for names */ else { /* Update kind unless it's a port or an ignored keyword */ if (token->kind != K_PORT && localKind != K_IGNORE) { token->kind = localKind; } repeat = TRUE; } } else break; c = skipWhite (vGetc ()); if (c == '[') c = skipPastMatch ("[]"); c = skipWhite (c); if (c == '=') { c = skipWhite (vGetc ()); if (c == '{') skipPastMatch ("{}"); else { /* Skip until end of current name, kind or parameter list definition */ do c = vGetc (); while (c != EOF && c != ',' && c != ';' && c != ')'); } } if (c == ',') { c = skipWhite (vGetc ()); repeat = TRUE; } } while (repeat); vUngetc (c); }
static void processTypedef (tokenInfo *const token) { /*Note: At the moment, only identifies typedef name and not its contents */ int c; /* Get typedef type */ c = skipWhite (vGetc ()); if (isIdentifierCharacter (c)) { readIdentifier (token, c); /* A typedef class is just a prototype */ if (strcmp (vStringValue (token->name), "class") == 0) { currentContext->prototype = TRUE; } } /* Skip remaining identifiers */ c = skipWhite (vGetc ()); while (isIdentifierCharacter (c)) { readIdentifier (token, c); c = skipWhite (vGetc ()); } /* Skip bus width definition */ if (c == '[') { skipPastMatch ("[]"); c = skipWhite (vGetc ()); } /* Skip typedef contents */ if (c == '{') { skipPastMatch ("{}"); c = skipWhite (vGetc ()); } /* Skip past class parameter override */ if (c == '#') { c = skipWhite (vGetc ()); if (c == '(') { skipPastMatch ("()"); c = skipWhite (vGetc ()); } } /* Read typedef name */ if (isIdentifierCharacter (c)) { readIdentifier (token, c); } else { vUngetc (c); } /* Use last identifier to create tag */ createTag (token); }
static void processPortList (int c) { if ((c = skipWhite (c)) == '(') { tokenInfo *token = newToken (); /* Get next non-whitespace character after ( */ c = skipWhite (vGetc ()); while (c != ';' && c != EOF) { if (c == '[') { c = skipPastMatch ("[]"); } else if (c == '(') { c = skipPastMatch ("()"); } else if (c == '{') { c = skipPastMatch ("{}"); } else if (c == '`') { c = skipMacro (c); } else if (c == '=') { /* Search for next port or end of port declaration */ while (c != ',' && c != ')' && c != EOF) { c = skipWhite (vGetc ()); } } else if (isIdentifierCharacter (c)) { readIdentifier (token, c); updateKind (token); if (token->kind == K_UNDEFINED) { /* Only add port name if it is the last keyword. * First keyword can be a dynamic type, like a class name */ c = skipWhite (vGetc ()); if (! isIdentifierCharacter (c) || c == '`') { verbose ("Found port: %s\n", vStringValue (token->name)); token->kind = K_PORT; createTag (token); } } else { c = skipWhite (vGetc ()); } } else { c = skipWhite (vGetc ()); } } if (! isIdentifierCharacter (c)) vUngetc (c); deleteToken (token); } }
static int skipWhite (int c) { while (isspace (c)) c = vGetc (); return c; }
static int skipWhite (int c) { while (c==' ') c = vGetc (); return c; }
static void findTag (tokenInfo *const token) { if (currentContext->kind != K_UNDEFINED) { /* Drop context, but only if an end token is found */ dropContext (token); } if (token->kind == K_CONSTANT && vStringItem (token->name, 0) == '`') { /* Bug #961001: Verilog compiler directives are line-based. */ int c = skipWhite (vGetc ()); readIdentifier (token, c); createTag (token); /* Skip the rest of the line. */ do { c = vGetc(); } while (c != EOF && c != '\n'); vUngetc (c); } else if (token->kind == K_BLOCK) { /* Process begin..end blocks */ processBlock (token); } else if (token->kind == K_FUNCTION || token->kind == K_TASK) { /* Functions are treated differently because they may also include the * type of the return value. * Tasks are treated in the same way, although not having a return * value.*/ processFunction (token); } else if (token->kind == K_ASSERTION) { if (vStringLength (currentContext->blockName) > 0) { vStringCopy (token->name, currentContext->blockName); createTag (token); skipToSemiColon (); } } else if (token->kind == K_TYPEDEF) { processTypedef (token); } else if (token->kind == K_CLASS) { processClass (token); } else if (token->kind == K_IGNORE && isSingleStatement (token)) { currentContext->singleStat = TRUE; } else if (isVariable (token)) { int c = skipWhite (vGetc ()); tagNameList (token, c); } else if (token->kind != K_UNDEFINED && token->kind != K_IGNORE) { int c = skipWhite (vGetc ()); if (isIdentifierCharacter (c)) { readIdentifier (token, c); while (getKind (token) == K_IGNORE) { c = skipWhite (vGetc ()); readIdentifier (token, c); } createTag (token); /* Get port list if required */ c = skipWhite (vGetc ()); if (c == '(' && hasSimplePortList (token)) { processPortList (c); } else { vUngetc (c); } } } }
static void processClass (tokenInfo *const token) { /*Note: At the moment, only identifies typedef name and not its contents */ int c; tokenInfo *extra; tokenInfo *parameters = NULL; /* Get identifiers */ c = skipWhite (vGetc ()); if (isIdentifierCharacter (c)) { readIdentifier (token, c); c = skipWhite (vGetc ()); } /* Find class parameters list */ if (c == '#') { c = skipWhite (vGetc ()); if (c == '(') { parameters = newToken (); do { c = skipWhite (vGetc ()); readIdentifier (parameters, c); updateKind (parameters); verbose ("Found class parameter %s\n", vStringValue (parameters->name)); if (parameters->kind == K_UNDEFINED) { parameters->kind = K_CONSTANT; parameters = pushToken (parameters, newToken ()); c = vGetc(); while (c != ',' && c != ')' && c != EOF) { c = vGetc(); } } } while (c != ')' && c != EOF); c = vGetc (); parameters = popToken (parameters); } c = skipWhite (vGetc ()); } /* Search for inheritance information */ if (isIdentifierCharacter (c)) { extra = newToken (); readIdentifier (extra, c); c = skipWhite (vGetc ()); if (strcmp (vStringValue (extra->name), "extends") == 0) { readIdentifier (extra, c); vStringCopy (token->inheritance, extra->name); verbose ("Inheritance %s\n", vStringValue (token->inheritance)); } deleteToken (extra); } /* Use last identifier to create tag */ createTag (token); /* Add parameter list */ while (parameters) { createTag (parameters); parameters = popToken (parameters); } }