const TCHAR* TiXmlBase::GetEntity( const TCHAR* p, TCHAR* value ) { // Presume an entity, and pull it out. int i; // Handle the &#x entities. if (generic_strncmp( TEXT("&#x"), p, 3 ) == 0) { const TCHAR* end = generic_strchr(p+3, TEXT(';')); if (end && end - p <= 3 + 4) { int val; if (generic_sscanf(p+3, TEXT("%x"), &val) == 1) { *value = (TCHAR)val; return end + 1; } } } // Now try to match it. for( i=0; i<NUM_ENTITY; ++i ) { if ( generic_strncmp( entity[i].str, p, entity[i].strLength ) == 0 ) { assert( (unsigned int)lstrlen( entity[i].str ) == entity[i].strLength ); *value = entity[i].chr; return ( p + entity[i].strLength ); } } // So it wasn't an entity, its unrecognized, or something like that. *value = *p; // Don't put back the last one, since we return it! return p+1; }
bool FunctionCallTip::getCursorFunction() { int line = _pEditView->execute(SCI_LINEFROMPOSITION, _curPos); int startpos = _pEditView->execute(SCI_POSITIONFROMLINE, line); int endpos = _pEditView->execute(SCI_GETLINEENDPOSITION, line); int len = endpos - startpos + 3; //also take CRLF in account, even if not there int offset = _curPos - startpos; //offset is cursor location, only stuff before cursor has influence const int maxLen = 128; if ((offset < 2) || (len >= maxLen)) { reset(); return false; //cannot be a func, need name and separator } TCHAR lineData[maxLen] = TEXT(""); _pEditView->getLine(line, lineData, len); //line aquired, find the functionname //first split line into tokens to parse //token is identifier or some expression, whitespace is ignored std::vector< Token > tokenVector; int tokenLen = 0; TCHAR ch; for (int i = 0; i < offset; i++) { //we dont care about stuff after the offset //tokenVector.push_back(pair(lineData+i, len)); ch = lineData[i]; if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9' || ch == '_') { //part of identifier tokenLen = 0; TCHAR * begin = lineData+i; while ( (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9' || ch == '_') && i < offset) { tokenLen++; i++; ch = lineData[i]; } tokenVector.push_back(Token(begin, tokenLen, true)); i--; //correct overshooting of while loop } else { if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') { //whitespace //do nothing } else { tokenLen = 1; tokenVector.push_back(Token(lineData+i, tokenLen, false)); } } } size_t vsize = tokenVector.size(); //mind nested funcs, like |blblb a (x, b(), c);| //therefore, use stack std::vector<FunctionValues> valueVec; FunctionValues curValue, newValue; int scopeLevel = 0; for (size_t i = 0; i < vsize; i++) { Token & curToken = tokenVector.at(i); if (curToken.isIdentifier) { curValue.lastIdentifier = i; } else { if (curToken.token[0] == _start) { scopeLevel++; newValue = curValue; valueVec.push_back(newValue); //store the current settings, so when this new function doesnt happen to be the 'real' one, we can restore everything curValue.scopeLevel = scopeLevel; if (i > 0 && curValue.lastIdentifier == i-1) { //identifier must be right before (, else we have some expression like "( x + y() )" curValue.lastFunctionIdentifier = curValue.lastIdentifier; curValue.param = 0; } else { //some expression curValue.lastFunctionIdentifier = -1; } } else if (curToken.token[0] == _param && curValue.lastFunctionIdentifier > -1) { curValue.param++; } else if (curToken.token[0] == _stop) { if (scopeLevel) //scope cannot go below -1 scopeLevel--; if (valueVec.size() > 0) { //only pop level if scope was of actual function curValue = valueVec.back(); valueVec.pop_back(); } else { //invalidate curValue curValue = FunctionValues(); } } else if (curToken.token[0] == _terminal) { //invalidate everything valueVec.clear(); curValue = FunctionValues(); } } } bool res = false; if (curValue.lastFunctionIdentifier == -1) { //not in direct function. Start popping the stack untill we empty it, or a func IS found while(curValue.lastFunctionIdentifier == -1 && valueVec.size() > 0) { curValue = valueVec.back(); valueVec.pop_back(); } } if (curValue.lastFunctionIdentifier > -1) { Token funcToken = tokenVector.at(curValue.lastFunctionIdentifier); funcToken.token[funcToken.length] = 0; _currentParam = curValue.param; bool same = false; if (_funcName) { if(_ignoreCase) same = testNameNoCase(_funcName, funcToken.token, lstrlen(_funcName)) == 0; else same = generic_strncmp(_funcName, funcToken.token, lstrlen(_funcName)) == 0; } if (!same) { //check if we need to reload data if (_funcName) { delete [] _funcName; } _funcName = new TCHAR[funcToken.length+1]; lstrcpy(_funcName, funcToken.token); res = loadFunction(); } else { res = true; } } return res; }