/* * Attempts to advance 'cp' past a Ruby operator method name. Returns * TRUE if successful (and copies the name into 'name'), FALSE otherwise. */ static boolean parseRubyOperator (vString* name, const unsigned char** cp) { static const char* RUBY_OPERATORS[] = { "[]", "[]=", "**", "!", "~", "+@", "-@", "*", "/", "%", "+", "-", ">>", "<<", "&", "^", "|", "<=", "<", ">", ">=", "<=>", "==", "===", "!=", "=~", "!~", "`", NULL }; int i; for (i = 0; RUBY_OPERATORS[i] != NULL; ++i) { if (canMatch (cp, RUBY_OPERATORS[i], notOperatorChar)) { vStringCatS (name, RUBY_OPERATORS[i]); return TRUE; } } return FALSE; }
bool isMatch(const char *s, const char *p) { int lS = strlen(s); int lP = strlen(p); vector<vector<bool> > F(lS + 1, vector<bool>(lP + 1, false)); F[0][0] = true; for (int i = 0; i <= lS; i++) { for (int j = 1; j <= lP; j++) { if (i > 0) { if (F[i-1][j-1] && canMatch(s[i-1], p[j-1])) { F[i][j] = true; continue; } } if (i > 0 && j > 1) { if (F[i-1][j] && canMatch(s[i-1],p[j-2]) && p[j-1] == '*') { F[i][j] = true; continue; } } if (j > 1) { if (F[i][j-2] && p[j-1] == '*') { F[i][j] = true; continue; } } } } return F[lS][lP]; }
bool canMatch(const char* head, const char * end, HashMap & flags, int l){ if (head == end+1) return true; string s=""; for (int i=0; i<l; i++) s+= *(head+i); HashMap::iterator hi = flags.find(s); if (hi==flags.end() || hi->second<=0) return false; flags[s]--; bool rlt = canMatch(head+l,end,flags,l); flags[s]++; return rlt; }
vector<int> findSubstring(string S, vector<string> &L) { // IMPORTANT: Please reset any member data you declared, as // the same Solution instance will be reused for each test case. vector<int> rlt; int n = L.size(); if (n<=0) return rlt; int l = L[0].length(); if (l<=0) return rlt; HashMap flags; for (int i=0; i<n; i++){ if (flags.find(L[i]) == flags.end()) flags[L[i]]=1; else flags[L[i]]++; } const char * head = S.c_str(); for (int i=0; i+l*n<=S.length(); i++){ if (canMatch(head+i, head+i+l*n-1, flags, l)) rlt.push_back(i); } return rlt; }
static void findRubyTags (void) { const unsigned char *line; boolean inMultiLineComment = FALSE; nesting = nestingLevelsNew (0); /* FIXME: this whole scheme is wrong, because Ruby isn't line-based. * You could perfectly well write: * * def * method * puts("hello") * end * * if you wished, and this function would fail to recognize anything. */ while ((line = readLineFromInputFile ()) != NULL) { const unsigned char *cp = line; /* if we expect a separator after a while, for, or until statement * separators are "do", ";" or newline */ boolean expect_separator = FALSE; if (canMatch (&cp, "=begin", isWhitespace)) { inMultiLineComment = TRUE; continue; } if (canMatch (&cp, "=end", isWhitespace)) { inMultiLineComment = FALSE; continue; } if (inMultiLineComment) continue; skipWhitespace (&cp); /* Avoid mistakenly starting a scope for modifiers such as * * return if <exp> * * FIXME: this is fooled by code such as * * result = if <exp> * <a> * else * <b> * end * * FIXME: we're also fooled if someone does something heinous such as * * puts("hello") \ * unless <exp> */ if (canMatchKeyword (&cp, "for") || canMatchKeyword (&cp, "until") || canMatchKeyword (&cp, "while")) { expect_separator = TRUE; enterUnnamedScope (); } else if (canMatchKeyword (&cp, "case") || canMatchKeyword (&cp, "if") || canMatchKeyword (&cp, "unless")) { enterUnnamedScope (); } /* * "module M", "class C" and "def m" should only be at the beginning * of a line. */ if (canMatchKeyword (&cp, "module")) { readAndEmitTag (&cp, K_MODULE); } else if (canMatchKeyword (&cp, "class")) { readAndEmitTag (&cp, K_CLASS); } else if (canMatchKeyword (&cp, "def")) { rubyKind kind = K_METHOD; NestingLevel *nl = nestingLevelsGetCurrent (nesting); tagEntryInfo *e = getEntryOfNestingLevel (nl); /* if the def is inside an unnamed scope at the class level, assume * it's from a singleton from a construct like this: * * class C * class << self * def singleton * ... * end * end * end */ if (e && (e->kind - RubyKinds) == K_CLASS && strlen (e->name) == 0) kind = K_SINGLETON; readAndEmitTag (&cp, kind); } while (*cp != '\0') { /* FIXME: we don't cope with here documents, * or regular expression literals, or ... you get the idea. * Hopefully, the restriction above that insists on seeing * definitions at the starts of lines should keep us out of * mischief. */ if (inMultiLineComment || isspace (*cp)) { ++cp; } else if (*cp == '#') { /* FIXME: this is wrong, but there *probably* won't be a * definition after an interpolated string (where # doesn't * mean 'comment'). */ break; } else if (canMatchKeyword (&cp, "begin")) { enterUnnamedScope (); } else if (canMatchKeyword (&cp, "do")) { if (! expect_separator) enterUnnamedScope (); else expect_separator = FALSE; } else if (canMatchKeyword (&cp, "end") && nesting->n > 0) { /* Leave the most recent scope. */ nestingLevelsPop (nesting); } else if (*cp == '"') { /* Skip string literals. * FIXME: should cope with escapes and interpolation. */ do { ++cp; } while (*cp != 0 && *cp != '"'); if (*cp == '"') cp++; /* skip the last found '"' */ } else if (*cp == ';') { ++cp; expect_separator = FALSE; } else if (*cp != '\0') { do ++cp; while (isIdentChar (*cp)); } } } nestingLevelsFree (nesting); }
static boolean canMatchKeyword (const unsigned char** s, const char* literal) { return canMatch (s, literal, notIdentChar); }
static void findSdlTags (void) { vString *name = vStringNew() ; const unsigned char *line; sdlKind kindNow = K_UNDEFINED ; while ((line = fileReadLine ()) != NULL) { const unsigned char *cp = line; skipWhitespace (&cp); if (canMatch (&cp, "TOKEN")) { kindNow = K_TOKEN ; do{ cp = fileReadLine() ; while (isspace ((int) *cp)) ++cp; }while(!canMatch(&cp,"Name")) ; cp+=4 ; while (isspace ((int) *cp)) ++cp; while (*cp != '\0') { vStringPut (name, (int) *cp); ++cp; } } else if (canMatch (&cp, "ELINK")) { kindNow = K_ELINK ; do{ cp = fileReadLine() ; while (isspace ((int) *cp)) ++cp; }while(!canMatch(&cp,"Name")) ; cp+=4 ; while (*cp != '\0') { vStringPut (name, (int) *cp); ++cp; } } else if (canMatch (&cp, "PATH")) { kindNow = K_PATH ; do{ cp = fileReadLine() ; while (isspace ((int) *cp)) ++cp; }while(!canMatch(&cp,"Name")) ; cp+=4 ; while (*cp != '\0') { vStringPut (name, (int) *cp); ++cp; } } else if (canMatch (&cp, "MODULE")) { kindNow = K_MODULE ; do{ cp = fileReadLine() ; while (isspace ((int) *cp)) ++cp; }while(!canMatch(&cp,"Name")) ; cp+=4 ; while (*cp != '\0') { vStringPut (name, (int) *cp); ++cp; } } else if (canMatch (&cp, "IRQLINK")) { kindNow = K_IRQLINK ; do{ cp = fileReadLine() ; while (isspace ((int) *cp)) ++cp; }while(!canMatch(&cp,"Name")) ; cp+=4 ; while (*cp != '\0') { vStringPut (name, (int) *cp); ++cp; } } else if (canMatch (&cp, "IODEVICE")) { kindNow = K_IODEVICE ; do{ cp = fileReadLine() ; while (isspace ((int) *cp)) ++cp; }while(!canMatch(&cp,"Name")) ; cp+=4 ; while (*cp != '\0') { vStringPut (name, (int) *cp); ++cp; } } else if (canMatch (&cp, "PCIDEVICE")) { kindNow = K_PCIDEVICE ; do{ cp = fileReadLine() ; while (isspace ((int) *cp)) ++cp; }while(!canMatch(&cp,"Title")) ; cp+=4 ; while (*cp != '\0') { vStringPut (name, (int) *cp); ++cp; } } vStringTerminate (name); makeSimpleTag (name, sdlKinds, kindNow); vStringClear (name); while (*cp != '\0') { /* FIXME: we don't cope with here documents, * or regular expression literals, or ... you get the idea. * Hopefully, the restriction above that insists on seeing * definitions at the starts of lines should keep us out of * mischief. */ if (isspace (*cp)) { ++cp; } //else if (*cp == '#') //{ /* FIXME: this is wrong, but there *probably* won't be a * definition after an interpolated string (where # doesn't * mean 'comment'). */ // break; //} else if (*cp == '"') { /* Skip string literals. * FIXME: should cope with escapes and interpolation. */ do { ++cp; } while (*cp != 0 && *cp != '"'); } else if (*cp != '\0') { do ++cp; while (isalnum (*cp) || *cp == '_'); } } } }
bool isMatch(const char *s, const char *p) { // s is string // p is regex size_t slen = strlen(s); size_t plen = strlen(p); vector<bool> canMatch(slen + 1, false); canMatch[slen] = true; for (size_t i = plen; i-- > 0;) { if (p[i] == '*') { continue; } bool isRepeated; if (((i + 1) != plen) && (p[i + 1] == '*')) { isRepeated = true; } else { isRepeated = false; } for (size_t j = 0; j <= slen; ++j) { if (j == slen) { canMatch[j] = isRepeated && canMatch[j]; continue; } if (!isRepeated) { if (p[i] == '.') { canMatch[j] = canMatch[j + 1]; } else { canMatch[j] = (p[i] == s[j]) && canMatch[j + 1]; } } else { for (size_t k = j; k <= slen && !canMatch[j]; ++k) { if ((k > j) && (p[i] != '.')) { if (p[i] != s[k - 1]) { break; } } canMatch[j] = canMatch[k]; } } } } return canMatch[0]; }
static void findRubyTags (void) { const unsigned char *line; boolean inMultiLineComment = FALSE; nesting = stringListNew (); /* FIXME: this whole scheme is wrong, because Ruby isn't line-based. * You could perfectly well write: * * def * method * puts("hello") * end * * if you wished, and this function would fail to recognize anything. */ while ((line = fileReadLine ()) != NULL) { const unsigned char *cp = line; if (canMatch (&cp, "=begin")) { inMultiLineComment = TRUE; continue; } if (canMatch (&cp, "=end")) { inMultiLineComment = FALSE; continue; } skipWhitespace (&cp); /* Avoid mistakenly starting a scope for modifiers such as * * return if <exp> * * FIXME: this is fooled by code such as * * result = if <exp> * <a> * else * <b> * end * * FIXME: we're also fooled if someone does something heinous such as * * puts("hello") \ * unless <exp> */ if (canMatch (&cp, "case") || canMatch (&cp, "for") || canMatch (&cp, "if") || canMatch (&cp, "unless") || canMatch (&cp, "while")) { enterUnnamedScope (); } /* * "module M", "class C" and "def m" should only be at the beginning * of a line. */ if (canMatch (&cp, "module")) { readAndEmitTag (&cp, K_MODULE); } else if (canMatch (&cp, "class")) { readAndEmitTag (&cp, K_CLASS); } else if (canMatch (&cp, "def")) { readAndEmitTag (&cp, K_METHOD); } while (*cp != '\0') { /* FIXME: we don't cope with here documents, * or regular expression literals, or ... you get the idea. * Hopefully, the restriction above that insists on seeing * definitions at the starts of lines should keep us out of * mischief. */ if (inMultiLineComment || isspace (*cp)) { ++cp; } else if (*cp == '#') { /* FIXME: this is wrong, but there *probably* won't be a * definition after an interpolated string (where # doesn't * mean 'comment'). */ break; } else if (canMatch (&cp, "begin") || canMatch (&cp, "do")) { enterUnnamedScope (); } else if (canMatch (&cp, "end") && stringListCount (nesting) > 0) { /* Leave the most recent scope. */ vStringDelete (stringListLast (nesting)); stringListRemoveLast (nesting); } else if (*cp == '"') { /* Skip string literals. * FIXME: should cope with escapes and interpolation. */ do { ++cp; } while (*cp != 0 && *cp != '"'); } else if (*cp != '\0') { do ++cp; while (isalnum (*cp) || *cp == '_'); } } } stringListDelete (nesting); }
static void findEfilogTags (void) { vString *name = vStringNew() ; const unsigned char *line; const unsigned char *statusStart = "[==== Status Code Available ====]"; const unsigned char *DXE = "[==== DXE phase start ====]" ; const unsigned char *bbsTbl = "[==== BBS Table ====]" ; sdlKind kindNow = K_UNDEFINED ; while ((line = fileReadLine ()) != NULL) { const unsigned char *cp = line; skipWhitespace (&cp); if (canMatch (&cp, "ERROR:")) { kindNow = K_ERROR ; cp+=1 ; while (isspace ((int) *cp)) ++cp; while (*cp != '\0') { vStringPut (name, (int) *cp); ++cp; } } else if( canMatch(&cp, "DXE IPL Entry")) { kindNow = K_ENTRY ; cp = line ; while ( *cp != '\0') { vStringPut (name, (int) *cp); ++cp; } } else if( canMatch(&cp, "DXE Status Code Available")) { kindNow = K_ENTRY ; cp = DXE ; while ( *cp != '\0') { vStringPut (name, (int) *cp); ++cp; } } vStringTerminate (name); makeSimpleTag (name, efilogKinds, kindNow); vStringClear (name); while (*cp != '\0') { if (canMatch (&cp, ".Entry")) { kindNow = K_ENTRY ; cp = line ; while ( *cp != '\0') { if (canMatch (&cp, ".Entry")) ; // Skip ".Entry" vStringPut (name, (int) *cp); ++cp; } vStringTerminate (name); makeSimpleTag (name, efilogKinds, kindNow); vStringClear (name); break ; }else if(canMatch( &cp, "Status Code Available")){ kindNow = K_ENTRY ; cp = statusStart ; while ( *cp != '\0') { vStringPut (name, (int) *cp); ++cp; } vStringTerminate (name); makeSimpleTag (name, efilogKinds, kindNow); vStringClear (name); break ; } else if( canMatch(&cp, "BDS")) { kindNow = K_ENTRY ; cp = line ; while ( *cp != '\0') { vStringPut (name, (int) *cp); ++cp; } vStringTerminate (name); makeSimpleTag (name, efilogKinds, kindNow); vStringClear (name); break ; } else if( canMatch(&cp, "BBS_TABLE")) { kindNow = K_ENTRY ; cp = bbsTbl; while ( *cp != '\0') { vStringPut (name, (int) *cp); ++cp; } vStringTerminate (name); makeSimpleTag (name, efilogKinds, kindNow); vStringClear (name); break ; } ++cp ; } } }