static bool loopCond(ff::ptr<int> s) { return isDigit(ff::deref(s)); };
/*--------------------------------------------------------------------------- | Facility : libnform | Function : static bool Check_This_Field( | FIELD * field, | const void * argp) | | Description : Validate buffer content to be a valid integer value | | Return Values : TRUE - field is valid | FALSE - field is invalid +--------------------------------------------------------------------------*/ static bool Check_This_Field(FIELD *field, const void *argp) { const thisARG *argi = (const thisARG *)argp; long low = argi->low; long high = argi->high; int prec = argi->precision; unsigned char *bp = (unsigned char *)field_buffer(field, 0); char *s = (char *)bp; long val; char buf[100]; bool result = FALSE; while (*bp && *bp == ' ') bp++; if (*bp) { if (*bp == '-') bp++; #if USE_WIDEC_SUPPORT if (*bp) { bool blank = FALSE; int len; int n; wchar_t *list = _nc_Widen_String((char *)bp, &len); if (list != 0) { result = TRUE; for (n = 0; n < len; ++n) { if (blank) { if (list[n] != ' ') { result = FALSE; break; } } else if (list[n] == ' ') { blank = TRUE; } else if (!isDigit(list[n])) { result = FALSE; break; } } free(list); } } #else while (*bp) { if (!isdigit(UChar(*bp))) break; bp++; } while (*bp && *bp == ' ') bp++; result = (*bp == '\0'); #endif if (result) { val = atol(s); if (low < high) { if (val < low || val > high) result = FALSE; } if (result) { snprintf(buf, sizeof(buf), "%.*ld", (prec > 0 ? prec : 0), val); set_field_buffer(field, 0, buf); } } } return (result); }
/** * Get next token in the current string expr. * Uses the ExpParser data expr, e, token, t, token_type and err */ void ExpParser::getToken() { token_type = NOTHING; char* t; // points to a character in token t = token; // let t point to the first character in token *t = '\0'; // set token empty //printf("\tgetToken e:{%c}, ascii=%i, col=%i\n", *e, *e, e-expr); // skip over whitespaces while (*e == ' ' || *e == '\t') // space or tab { e++; } // check for end of expression if (*e == '\0') { // token is still empty token_type = DELIMETER; return; } // check for minus if (*e == '-') { token_type = DELIMETER; *t = *e; e++; t++; *t = '\0'; // add a null character at the end of token return; } // check for parentheses if (*e == '(' || *e == ')') { token_type = DELIMETER; *t = *e; e++; t++; *t = '\0'; return; } // check for operators (delimeters) if (isDelimeter(*e)) { token_type = DELIMETER; while (isDelimeter(*e)) { *t = *e; e++; t++; } *t = '\0'; // add a null character at the end of token return; } // check for a value if (isDigitDot(*e)) { token_type = NUMBER; while (isDigitDot(*e)) { *t = *e; e++; t++; } // check for scientific notation like "2.3e-4" or "1.23e50" if (toupper(*e) == 'E') { *t = *e; e++; t++; if (*e == '+' || *e == '-') { *t = *e; e++; t++; } while (isDigit(*e)) { *t = *e; e++; t++; } } *t = '\0'; return; } // check for variables or functions if (isAlpha(*e)) { while (isAlpha(*e) || isDigit(*e)) //while (isNotDelimeter(*e)) { *t = *e; e++; t++; } *t = '\0'; // add a null character at the end of token // check if this is a variable or a function. // a function has a parentesis '(' open after the name char* e2 = NULL; e2 = e; // skip whitespaces while (*e2 == ' ' || *e2 == '\t') // space or tab { e2++; } if (*e2 == '(') { token_type = FUNCTION; } else { token_type = VARIABLE; } return; } // something unknown is found, wrong characters -> a syntax error token_type = UNKNOWN; while (*e != '\0') { *t = *e; e++; t++; } *t = '\0'; throw Error(row(), col(), 1, token); return; }
double LexicalCast::fromDouble(const char* signedp) const { unsigned char* p = (unsigned char*)signedp; unsigned char c; double fl, flexp, exp5; double big = 72057594037927936.; /*2^56*/ int nd; int eexp, exp, neg, negexp, bexp; neg = 1; while((c = *p++) == ' ') ; if (c == '-') neg = -1; else if (c=='+') ; else --p; exp = 0; fl = 0; nd = 0; while ((c = *p++), isDigit(c)) { if (fl<big) fl = 10*fl + (c-'0'); else exp++; nd++; } if (c == _separator) { while ((c = *p++), isDigit(c)) { if (fl<big) { fl = 10*fl + (c-'0'); exp--; } nd++; } } negexp = 1; eexp = 0; if ((c == 'E') || (c == 'e')) { if ((c= *p++) == '+') ; else if (c=='-') negexp = -1; else --p; while ((c = *p++), isDigit(c)) { eexp = 10*eexp+(c-'0'); } if (negexp<0) eexp = -eexp; exp = exp + eexp; } negexp = 1; if (exp<0) { negexp = -1; exp = -exp; } if((nd+exp*negexp) < -LOGHUGE){ fl = 0; exp = 0; } flexp = 1; exp5 = 5; bexp = exp; for (;;) { if (exp&01) flexp *= exp5; exp >>= 1; if (exp==0) break; exp5 *= exp5; } if (negexp<0) fl /= flexp; else fl *= flexp; fl = ldexp(fl, negexp*bexp); if (neg<0) fl = -fl; return(fl); }
static int initFunction( DEVICE_INFO *deviceInfo, const char *name, const int nameLength ) { CK_SESSION_HANDLE hSession; CK_SLOT_ID slotList[ MAX_PKCS11_SLOTS + 8 ]; CK_ULONG slotCount = MAX_PKCS11_SLOTS; CK_SLOT_INFO slotInfo; CK_TOKEN_INFO tokenInfo; CK_RV status; PKCS11_INFO *pkcs11Info = deviceInfo->devicePKCS11; const PKCS11_MECHANISM_INFO *mechanismInfoPtr; char *labelPtr; int tokenSlot = DEFAULT_SLOT, i, labelLength, mechanismInfoSize; int cryptStatus, cryptStatus2; assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) ); assert( isReadPtr( name, nameLength ) ); /* Get information on all available slots */ memset( slotList, 0, sizeof( slotList ) ); status = C_GetSlotList( TRUE, slotList, &slotCount ); if( status != CKR_OK ) return( pkcs11MapError( status, CRYPT_ERROR_OPEN ) ); if( slotCount <= 0 ) { /* There are token slots present but no tokens in the slots */ return( CRYPT_ERROR_OPEN ); } /* Check whether a token name (used to select the slot) has been specified */ for( i = 1; i < nameLength - 1; i++ ) { if( name[ i ] == ':' && name[ i + 1 ] == ':' ) break; } if( i < nameLength - 1 ) { const char *tokenName = name + i + 2; /* Skip '::' */ const int tokenNameLength = nameLength - ( i + 2 ); if( tokenNameLength <= 0 ) return( CRYPT_ARGERROR_STR1 ); /* Some tokens don't implement named slots, so we also allow them to be specified using slot counts */ if( tokenNameLength == 1 && isDigit( *tokenName ) ) { tokenSlot = *tokenName - '0'; if( tokenSlot < 0 || tokenSlot > 9 ) return( CRYPT_ARGERROR_STR1 ); if( tokenSlot > slotCount - 1 ) /* Slots numbered from zero */ return( CRYPT_ERROR_NOTFOUND ); status = C_GetTokenInfo( slotList[ tokenSlot ], &tokenInfo ); if( status != CKR_OK ) return( CRYPT_ERROR_NOTFOUND ); } else { /* Check each (named) slot for a token matching the given name */ for( tokenSlot = 0; tokenSlot < slotCount && \ tokenSlot < FAILSAFE_ITERATIONS_MED; tokenSlot++ ) { status = C_GetTokenInfo( slotList[ tokenSlot ], &tokenInfo ); if( status == CKR_OK && \ !strCompare( tokenName, tokenInfo.label, tokenNameLength ) ) break; } ENSURES( tokenSlot < FAILSAFE_ITERATIONS_MED ); if( tokenSlot >= slotCount ) return( CRYPT_ERROR_NOTFOUND ); } } pkcs11Info->slotID = slotList[ tokenSlot ]; /* Get information on device-specific capabilities */ status = C_GetSlotInfo( pkcs11Info->slotID, &slotInfo ); if( status != CKR_OK ) { shutdownFunction( deviceInfo ); return( pkcs11MapError( status, CRYPT_ERROR_OPEN ) ); } if( slotInfo.flags & CKF_REMOVABLE_DEVICE ) { /* The device is removable */ deviceInfo->flags |= DEVICE_REMOVABLE; } status = C_GetTokenInfo( pkcs11Info->slotID, &tokenInfo ); if( status != CKR_OK ) { shutdownFunction( deviceInfo ); return( pkcs11MapError( status, CRYPT_ERROR_OPEN ) ); } if( tokenInfo.flags & CKF_RNG ) { /* The device has an onboard RNG that we can use */ deviceInfo->getRandomFunction = getRandomFunction; } #if 0 /* The Spyrus driver for pre-Lynks-II cards returns the local system time (with a GMT/localtime offset), ignoring the fact that the token has an onboard clock, so having the CKF_CLOCK_ON_TOKEN not set is accurate, although having it ignore the presence of the clock isn't very valid */ if( !( tokenInfo.flags & CKF_CLOCK_ON_TOKEN ) && \ ( !strCompare( tokenInfo.label, "Lynks Token", 11 ) || \ !strCompare( tokenInfo.model, "Rosetta", 7 ) ) ) { /* Fix buggy Spyrus PKCS #11 drivers which claim that the token doesn't have a RTC even though it does (the Rosetta (smart card) form of the token is even worse, it returns garbage in the label and manufacturer fields, but the model field is OK). There is a chance that there's a genuine problem with the clock (there are batches of tokens with bad clocks) but the time check that follows below will catch those */ tokenInfo.flags |= CKF_CLOCK_ON_TOKEN; } #endif /* 0 */ if( tokenInfo.flags & CKF_CLOCK_ON_TOKEN ) { const time_t theTime = getTokenTime( &tokenInfo ); const time_t currentTime = getTime(); /* The token claims to have an onboard clock that we can use. Since this could be arbitrarily inaccurate we compare it with the system time and only rely on it if it's within +/- 1 day of the system time. There is a second check that we should make to catch drivers that claim to read the time from the token but actually use the local computer's time, but this isn't easy to do. The most obvious way is to set the system time to a bogus value and check whether this matches the returned time, but this is somewhat drastic and requires superuser privs on most systems. An alternative is to check whether the claimed token time exactly matches the system time, but this will produce false positives if (for example) the token has been recently synchronised to the system time. For now all we can do is throw an exception if it appears that the token time is faked */ if( theTime > MIN_TIME_VALUE && \ theTime >= currentTime - 86400 && \ theTime <= currentTime + 86400 ) deviceInfo->flags |= DEVICE_TIME; /* If this check is triggered then the token time may be faked since it's identical to the host system time, see the comment above for details. We make an exception for soft-tokens (if we can detect them), which will (by definition) have the same time as the system time */ if( !( pkcs11InfoTbl[ pkcs11Info->deviceNo ].name[ 0 ] && \ !strCompare( pkcs11InfoTbl[ pkcs11Info->deviceNo ].name, "Software", 8 ) ) && \ theTime == currentTime ) { DEBUG_DIAG(( "PKCS #11 token time is the same as the host " "system time, token time may be faked by the " "driver." )); assert( DEBUG_WARN ); } } if( tokenInfo.flags & CKF_WRITE_PROTECTED ) { /* The device can't have data on it changed */ deviceInfo->flags |= DEVICE_READONLY; } if( ( tokenInfo.flags & CKF_LOGIN_REQUIRED ) || \ !( tokenInfo.flags & CKF_USER_PIN_INITIALIZED ) ) { /* The user needs to log in before using various device functions. We check for the absence of CKF_USER_PIN_INITIALIZED as well as the more obvious CKF_LOGIN_REQUIRED because if we've got an uninitialised device there's no PIN set so some devices will report that there's no login required (or at least none is possible). We need to introduce some sort of pipeline stall if this is the case because otherwise the user could successfully perform some functions that don't require a login (where the exact details of what's allowed without a login are device- specific) before running into mysterious failures when they get to functions that do require a login. To avoid this, we make an uninitialised device look like a login-required device, so the user gets an invalid-PIN error if they try and proceed */ deviceInfo->flags |= DEVICE_NEEDSLOGIN; } if( ( pkcs11Info->minPinSize = ( int ) tokenInfo.ulMinPinLen ) < 4 ) { /* Some devices report silly PIN sizes */ DEBUG_DIAG(( "Driver reports suspicious minimum PIN size %lu, " "using 4", tokenInfo.ulMinPinLen )); pkcs11Info->minPinSize = 4; } if( ( pkcs11Info->maxPinSize = ( int ) tokenInfo.ulMaxPinLen ) < 4 ) { /* Some devices report silly PIN sizes (setting this to ULONG_MAX or 4GB, which becomes -1 as an int, counts as silly). Since we can't differentiate between 0xFFFFFFFF = bogus value and 0xFFFFFFFF = ULONG_MAX we play it safe and set the limit to 8 bytes, which most devices should be able to handle */ DEBUG_DIAG(( "Driver reports suspicious maximum PIN size %lu, " "using 8", tokenInfo.ulMinPinLen )); pkcs11Info->maxPinSize = 8; } labelPtr = ( char * ) tokenInfo.label; for( labelLength = 32; labelLength > 0 && \ ( labelPtr[ labelLength - 1 ] == ' ' || \ !labelPtr[ labelLength - 1 ] ); labelLength-- ); /* Strip trailing blanks/nulls */ while( labelLength > 0 && *labelPtr == ' ' ) { /* Strip leading blanks */ labelPtr++; labelLength--; } if( labelLength > 0 ) { memcpy( pkcs11Info->label, labelPtr, labelLength ); pkcs11Info->labelLen = labelLength; sanitiseString( pkcs11Info->label, CRYPT_MAX_TEXTSIZE, labelLength ); } else { /* There's no label for the token, use the device label instead */ if( pkcs11InfoTbl[ pkcs11Info->deviceNo ].name[ 0 ] ) { labelLength = \ min( strlen( pkcs11InfoTbl[ pkcs11Info->deviceNo ].name ), CRYPT_MAX_TEXTSIZE ); memcpy( pkcs11Info->label, pkcs11InfoTbl[ pkcs11Info->deviceNo ].name, labelLength ); } } pkcs11Info->hActiveSignObject = CK_OBJECT_NONE; deviceInfo->label = pkcs11Info->label; deviceInfo->labelLen = pkcs11Info->labelLen; /* Open a session with the device. This gets a bit awkward because we can't tell whether a R/W session is OK without opening a session, but we can't open a session unless we know whether a R/W session is OK, so we first try for a RW session and if that fails we go for a read- only session */ status = C_OpenSession( pkcs11Info->slotID, CKF_RW_SESSION | CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSession ); if( status == CKR_TOKEN_WRITE_PROTECTED ) { status = C_OpenSession( pkcs11Info->slotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSession ); } if( status != CKR_OK ) { cryptStatus = pkcs11MapError( status, CRYPT_ERROR_OPEN ); if( cryptStatus == CRYPT_ERROR_OPEN && \ !( tokenInfo.flags & CKF_USER_PIN_INITIALIZED ) ) { /* We couldn't do much with the error code, it could be that the token hasn't been initialised yet but unfortunately PKCS #11 doesn't define an error code for this condition. In addition many tokens will allow a session to be opened and then fail with a "PIN not set" error at a later point (which allows for more accurate error reporting), however a small number won't allow a session to be opened and return some odd-looking error because there's nothing useful available. The best way to report this in a meaningful manner to the caller is to check whether the user PIN has been initialised, if it hasn't then it's likely that the token as a whole hasn't been initialised so we return a not initialised error */ cryptStatus = CRYPT_ERROR_NOTINITED; } return( cryptStatus ); } ENSURES( hSession != CK_OBJECT_NONE ); pkcs11Info->hSession = hSession; deviceInfo->flags |= DEVICE_ACTIVE; /* Set up the capability information for this device. Since there can be devices that have one set of capabilities but not the other (e.g. a smart card that only performs RSA ops), we allow one of the two sets of mechanism information setups to fail, but not both */ mechanismInfoPtr = getMechanismInfoPKC( &mechanismInfoSize ); cryptStatus = getCapabilities( deviceInfo, mechanismInfoPtr, mechanismInfoSize ); mechanismInfoPtr = getMechanismInfoConv( &mechanismInfoSize ); cryptStatus2 = getCapabilities( deviceInfo, mechanismInfoPtr, mechanismInfoSize ); if( cryptStatusError( cryptStatus ) && cryptStatusError( cryptStatus2 ) ) { shutdownFunction( deviceInfo ); return( ( cryptStatus == CRYPT_ERROR ) ? \ CRYPT_ERROR_OPEN : ( int ) cryptStatus ); } return( CRYPT_OK ); }
void call21h() { /* * 对21h 中的功能号进行测试 */ while(1) { cls(); print("\r\n Now, you can run some commands to test the 21h:\n\n\r"); print(" 1.ouch -- to ouch 2.upper -- change the letter to upper\n\r"); print(" 3.lower -- change the letter to lower\n\r"); print(" 4.to_digit -- change the string to digit\r\n"); print(" 5.to_string -- change the digit to string\r\n"); print(" 6.display_where -- you can assign where to display\r\n"); print(" 7.to_deci -- change the Hex to a decimal digit\r\n"); print(" 8.reverse -- to reverse your string\r\n"); print(" 9.strlen -- get the length of your string\r\n"); print(" 10.quit -- just to quit\r\n\r\n"); print("Please input your choice:"); getline(input,20); if(strcmp(input,"1") || strcmp(input,"ouch")) { /* * 测试 0 号功能 */ to_OUCH(); } else if(strcmp(input,"2") || strcmp(input,"upper")) { /* * 测试 1 号功能 */ while(1) { print("\r\nPlease input a sentence or quit to back:"); getline(input,30); if(strcmp(input,"quit")) break; upper(input); print("\r\nThe upper case is:"); print(input); print("\r\n"); } } else if(strcmp(input,"3") || strcmp(input,"lower")) { /* * 测试 2 号功能 */ while(1) { print("\r\nPlease input a sentence or quit to back:"); getline(input,30); if(strcmp(input,"quit")) break; lower(input); print("\r\nThe lower case is:"); print(input); print("\r\n"); } } else if(strcmp(input,"4") || strcmp(input,"to_digit")) { /* * 测试 3 号功能 */ print("\r\nDo you want to continue? Y | N :"); getline(input,2); while(1) { int t1,t2,t3; t1 = 0;t2 = 0; if(strcmp(input,"n") || strcmp(input,"N")) break; print("\r\nPlease input the first digit:"); getline(input,4); if(isDigit(input)) { t1 = digital(input); } else { print("\r\nInvalid digit!We assume it is 12\n\r"); t1 = 12; } print("\r\nPlease input the second digit:"); getline(input,4); if(isDigit(input)) { t2 = digital(input); } else { print("\r\nInvalid digit!We assume it is 21\n\r"); t2 = 21; } print("\r\nThe sum of the them is:"); t3 = t1 + t2; printInt(t3); print("\r\n"); print("\r\nDo you want to continue? Y | N :"); getline(input,2); } } else if(strcmp(input,"5") || strcmp(input,"to_string")) { /* * 测试 4 号功能 */ print("\r\nDo you want to continue? Y | N: "); getline(input,2); while(1) { char *cht; int tt = rand(); if(strcmp(input,"n") || strcmp(input,"N")) break; cht = convertToString(tt); print("\r\nI am a string: "); print(cht); print("\r\n"); print("\r\nDo you want to continue? Y | N: "); getline(input,2); } } else if(strcmp(input,"6") || strcmp(input,"display_where")) { /* * 测试 5 号功能 */ int row,col; print("\r\nPlease input the row:"); getline(input,3); if(isDigit(input)) { row = digital(input); } else { print("\r\nInvalid digit!We assume it is 12\n\r"); row = 12; } print("\r\nPlease input column:"); getline(input,3); if(isDigit(input)) { col = digital(input); } else { print("\r\nInvalid digit!We assume it is 40\n\r"); col = 40; } print("\r\nPlease input the string:"); getline(input,30); display(row,col,input); } else if(strcmp(input,"7") || strcmp(input,"to_dec")) { /* * 测试 6 号功能 */ print("\r\nDo you want to continue? Y | N :"); getline(input,2); while(1) { int t1; t1 = 0; if(strcmp(input,"n") || strcmp(input,"N")) break; print("\r\nPlease input the hex digit:"); getline(input,3); if(isHex(input)) { t1 = convertHexToDec(input); } else { print("\r\nInvalid Hex!We assume it is 12\n\r"); t1 = 12; } print("\r\nThe decimal form is:"); printInt(t1); print("\r\n"); print("\r\nDo you want to continue? Y | N :"); getline(input,2); } } else if(strcmp(input,"8") || strcmp(input,"reverse")) { /* * 测试 7 号功能 */ print("\r\nDo you want to continue? Y | N :"); getline(input,2); while(1) { if(strcmp(input,"n") || strcmp(input,"N")) break; print("\r\nPlease input the your string:"); getline(input,30); reverse(input,strlen(input)); print("\r\nThe string after reverse is:"); print(input); print("\r\n"); print("\r\nDo you want to continue? Y | N :"); getline(input,2); } } else if(strcmp(input,"9") || strcmp(input,"strlen")) { /* * 测试 8 号功能 */ print("\r\nDo you want to continue? Y | N :"); getline(input,2); while(1) { int t; if(strcmp(input,"n") || strcmp(input,"N")) break; print("\r\nPlease input the your string:"); getline(input,30); t = strlen(input); print("\r\nThe length of the string is:"); printInt(t); print("\r\n"); print("\r\nDo you want to continue? Y | N :"); getline(input,2); } } else if(strcmp(input,"10") || strcmp(input,"quit")) { /* * 退出 */ break; } } }
bool Tree::letCalc() { bool result = true; if (left && isDigit(left->value) && right && isDigit(right->value)) return result; }
ConstantToken* Lexer::scanNumber(const int tokenID) throw (std::runtime_error) { std::string numberString(""); ConstantToken::Base base = ConstantToken::BASE_10; ConstantToken::ConstantType type = ConstantToken::TYPE_INT; bool hasExponent = false; bool (*pred)(const char ref) = &isDigit; size_t pos = 0; for (bool atEnd = false; (! atEnd); ++pos) { if ((pred != 0) && ((*pred)(peek_) == true)) { numberString += peek_; if ((pos == 0) && (peek_ == '0')) { if ((nextChar() == 'x') || (nextChar() == 'X')) { numberString += readChar(); ++pos; pred = &isHexDigit; base = ConstantToken::BASE_16; } else if (nextChar() == '.') type = ConstantToken::TYPE_FLOAT; else { pred = &isOctalDigit; base = ConstantToken::BASE_8; } } switch (nextChar()) { case 'u': case 'U': atEnd = true; if (type == ConstantToken::TYPE_INT) { numberString += readChar(); ++pos; type = ConstantToken::TYPE_UINT; } break; case 'f': case 'F': atEnd = true; if (type == ConstantToken::TYPE_FLOAT) { numberString += readChar(); ++pos; } break; case '.': if (base == ConstantToken::BASE_10) { type = ConstantToken::TYPE_FLOAT; numberString += readChar(); ++pos; } break; case 'e': case 'E': if (type == ConstantToken::TYPE_FLOAT) { hasExponent = true; numberString += readChar(); ++pos; } break; default: if (! (*pred)(nextChar())) atEnd = true; break; } // switch } else if ((peek_ == 'f') && (type == ConstantToken::TYPE_FLOAT)) numberString += peek_; else if ((peek_ == '.') && (base == ConstantToken::BASE_10)) { // Accept the dot '.' only, if it is not the first character or // if a digit is following to avoid invalid ".f" strings. // if ((pos > 0) || (isDigit(nextChar()) == true)) { type = ConstantToken::TYPE_FLOAT; numberString += peek_; } } else if (((peek_ == '+') || (peek_ == '-')) && (hasExponent == true)) { numberString += peek_; } else break; if (! atEnd) readChar(); } // for (pos if (numberString.empty() == true) return 0; return new ConstantToken(tokenID, numberString, type, base); }
std::deque<Token*> PreprocessorLexer::scanDirective(const std::string& directive) const { std::deque<Token*> tokenList; size_t stringStart = std::string::npos; for (size_t pos = 0; pos < directive.length(); ++pos) { const char top = directive[pos]; const char next = ((pos < (directive.length() - 1)) ? directive[pos + 1] : '\0'); if (stringStart != std::string::npos) { switch (top) { case '\\': if (next == '"') ++pos; break; case '"': tokenList.push_back( new StringToken(PreprocessorTerminals::ID_STRING, directive.substr(stringStart, (pos - stringStart))) ); tokenList.push_back(new Token(PreprocessorTerminals::ID_QUOTE)); stringStart = std::string::npos; break; default: break; } // switch (top) continue; } // if (readingString // omit any kind of whitespace within the directive // if (isWhitespace(top) == true) continue; bool consumed = true; // at first determine characters which correspond to preprocessor operators // switch (top) { case '#': if (next == '#') { tokenList.push_back(new Token(PreprocessorTerminals::ID_OP_FFENCE)); ++pos; } else if ((next == 0) || (isWhitespace(next))) tokenList.push_back(new Token(PreprocessorTerminals::ID_FENCE)); else consumed = false; break; case '(': tokenList.push_back(new Token(PreprocessorTerminals::ID_LPAREN)); break; case ')': tokenList.push_back(new Token(PreprocessorTerminals::ID_RPAREN)); break; case ',': tokenList.push_back(new Token(PreprocessorTerminals::ID_COMMA)); break; case '+': tokenList.push_back(new Token(PreprocessorTerminals::ID_PLUS)); break; case '-': tokenList.push_back(new Token(PreprocessorTerminals::ID_DASH)); break; case '~': tokenList.push_back(new Token(PreprocessorTerminals::ID_OP_COMPLEMENT)); break; case '!': if (next == '=') { tokenList.push_back(new Token(PreprocessorTerminals::ID_NEQ)); ++pos; } else tokenList.push_back(new Token(PreprocessorTerminals::ID_OP_NOT)); break; case '*': tokenList.push_back(new Token(PreprocessorTerminals::ID_OP_MUL)); break; case '/': tokenList.push_back(new Token(PreprocessorTerminals::ID_OP_DIV)); break; case '%': tokenList.push_back(new Token(PreprocessorTerminals::ID_OP_MOD)); break; case '<': if (next == '<') { tokenList.push_back(new Token(PreprocessorTerminals::ID_OP_LSHIFT)); ++pos; } else if (next == '=') { tokenList.push_back(new Token(PreprocessorTerminals::ID_LEQ)); ++pos; } else tokenList.push_back(new Token(PreprocessorTerminals::ID_LESS)); break; case '>': if (next == '>') { tokenList.push_back(new Token(PreprocessorTerminals::ID_OP_RSHIFT)); ++pos; } else if (next == '=') { tokenList.push_back(new Token(PreprocessorTerminals::ID_GEQ)); ++pos; } else tokenList.push_back(new Token(PreprocessorTerminals::ID_GREATER)); break; case '=': if (next == '=') { tokenList.push_back(new Token(PreprocessorTerminals::ID_EQ)); ++pos; } else consumed = false; break; case '&': if (next == '&') { tokenList.push_back(new Token(PreprocessorTerminals::ID_LOGICAL_AND)); ++pos; } else tokenList.push_back(new Token(PreprocessorTerminals::ID_BIT_AND)); break; case '|': if (next == '|') { tokenList.push_back(new Token(PreprocessorTerminals::ID_LOGICAL_OR)); ++pos; } else tokenList.push_back(new Token(PreprocessorTerminals::ID_BIT_OR)); break; case '^': tokenList.push_back(new Token(PreprocessorTerminals::ID_BIT_XOR)); break; case '"': stringStart = pos + 1; // indicates the start of a string which will be read. tokenList.push_back(new Token(PreprocessorTerminals::ID_QUOTE)); break; default: consumed = false; break; } // switch (top) if (consumed == true) continue; if ((isAlpha(top) == true) || (top == '#')) { std::string identifier(&top, 1); for (++pos; pos < directive.length(); ++pos) { const char top = directive[pos]; if ((isAlpha(top) == true) || (isDigit(top) == true)) identifier += top; else { --pos; break; } } KeywordMap::const_iterator it = keywords_.find(identifier); if (it != keywords_.end()) tokenList.push_back(new Word(it->second)); else tokenList.push_back(new IdentifierToken(PreprocessorTerminals::ID_IDENTIFIER, identifier)); } else if ((isDigit(top) == true) || ((top == '.') && (isDigit(next) == true))) { size_t end = 0; ConstantToken* ct = scanNumber(directive.substr(pos), end); if (ct != 0) tokenList.push_back(ct); pos += end; } else tokenList.push_back(new TextToken(PreprocessorTerminals::ID_TEXT, std::string(&top, 1))); } // for (pos < length) return tokenList; }
int calculate(string s) { stack<char> symbols; stack<int> values; int num = 0; bool wasDigit = false; for (int i = 0; i <= s.length(); i++) { if (s[i] == ' ') continue; if (isDigit(s[i])) { num *= 10; num += s[i] - '0'; wasDigit = true; continue; } if (wasDigit) { wasDigit = false; values.push(num); num = 0; if (!symbols.empty()) { char op = symbols.top(); if (op == '+' || op == '-') { symbols.pop(); int num1 = values.top(); values.pop(); int num2 = values.top(); values.pop(); if (op == '+') num2 += num1; if (op == '-') num2 -= num1; values.push(num2); } } } if (s[i] == '+' || s[i] == '-' || s[i] == '(') { symbols.push(s[i]); continue; } if (s[i] == ')') { while(!symbols.empty()) { char op = symbols.top(); symbols.pop(); if (op == '+' || op == '-') { int num1 = values.top(); values.pop(); int num2 = values.top(); values.pop(); if (op == '+') num2 += num1; if (op == '-') num2 -= num1; values.push(num2); } else if (op == '(') break; } if (!symbols.empty()) { char op = symbols.top(); if (op == '+' || op == '-') { symbols.pop(); int num1 = values.top(); values.pop(); int num2 = values.top(); values.pop(); if (op == '+') num2 += num1; if (op == '-') num2 -= num1; values.push(num2); } } } } return values.top(); }
static z_token lex_scan(z_lexstate *ls) { if(ls->cur.eof) { lex_save(ls); return lex_newToken(ls, T_EOF, 0); } if(isWhite(nc)) { while(isWhite(nc)) { if(isNewLine(nc)) { lex_scanNewLine(ls); return lex_newToken(ls, T_NL, tk_generic); } else lex_nextchar(ls); } return lex_scan(ls); } /* line comment */ if(nc == '/') { if(nnc == '/') { while(!isNewLine(nc)) lex_nextchar(ls); return lex_scan(ls); } } /* multi line comment */ if(nc == '/') { if(nnc == '*') { lex_nextchar(ls); lex_nextchar(ls); for(;;) { if(ls->cur.eof) { syntaxError(ls, "unterminated comment reached end of file"); break; } else if(nc == '*') { lex_nextchar(ls); if(nc == '/') { lex_nextchar(ls); return lex_scan(ls); } } else if(isNewLine(nc)) { lex_scanNewLine(ls); } else lex_nextchar(ls); } } } lex_save(ls); /* numerical constants */ if(isDigit(nc)) { parse_number: while(isDigit(nc)) lex_nextchar(ls); if(nc == '.') { lex_nextchar(ls); while(isDigit(nc)) lex_nextchar(ls); if(nc == '.') syntaxError(ls, "invalid numerical constant"); } return lex_newToken(ls, T_NUMBER, tk_numeric); } /* identifiers */ else if(isAlpha(nc)) { parse_ident: while(isAlNum(nc) || nc == '_') lex_nextchar(ls); /* check if it matches a keyword token */ z_token tk = lex_newToken(ls, T_IDENT, tk_identifier); lex_matchKeyword(ls, &tk); return tk; } /* string literals */ else if(nc == '"' || nc == '\''){ //parse_string: char q = nc; lex_nextchar(ls); while(nc != q) { if(ls->cur.eof) { syntaxError(ls, "unterminated string literal reached end of file"); break; } /* skip escaped chars */ if(nc == '\\') { lex_nextchar(ls); continue; } if(isNewLine(nc)) { lex_scanNewLine(ls); } lex_nextchar(ls); } lex_nextchar(ls); // skip the closing cc return lex_newToken(ls, T_STRING, tk_string); } /* other multi char tokens */ switch(nc) { case '.': // may be numeric? lex_nextchar(ls); if(isDigit(nc)) goto parse_number; return lex_newToken(ls, '.', 0); case '_': // may be ident? lex_nextchar(ls); if(isAlNum(nc)) goto parse_ident; return lex_newToken(ls, '_', 0); case '+': lex_nextchar(ls); if(nc == '+') { lex_nextchar(ls); return lex_newToken(ls, T_INC, tk_op); } else if(nc == '=') { lex_nextchar(ls); return lex_newToken(ls, T_AA, tk_op); } return lex_newToken(ls, '+', tk_op); case '-': lex_nextchar(ls); if(nc == '-') { lex_nextchar(ls); return lex_newToken(ls, T_DEC, tk_op); } else if(nc == '=') { lex_nextchar(ls); return lex_newToken(ls, T_SA, tk_op); } return lex_newToken(ls, '-', tk_op); case '*': lex_nextchar(ls); if(nc == '=') { lex_nextchar(ls); return lex_newToken(ls, T_MA, tk_op); } return lex_newToken(ls, '*', tk_op); case '/': lex_nextchar(ls); if(nc == '=') { lex_nextchar(ls); return lex_newToken(ls, T_DA, tk_op); } return lex_newToken(ls, '/', tk_op); case '>': lex_nextchar(ls); if(nc == '=') { lex_nextchar(ls); return lex_newToken(ls, T_GTE, tk_op); } return lex_newToken(ls, '>', tk_op); case '<': lex_nextchar(ls); if(nc == '=') { lex_nextchar(ls); return lex_newToken(ls, T_LTE, tk_op); } else if(nc == '>') { lex_nextchar(ls); return lex_newToken(ls, T_NE, tk_op); } return lex_newToken(ls, '<', tk_op); case '=': lex_nextchar(ls); if(nc == '=') { lex_nextchar(ls); return lex_newToken(ls, T_EQ, tk_op); } return lex_newToken(ls, '=', tk_op); case '&': lex_nextchar(ls); if(nc == '&') { lex_nextchar(ls); return lex_newToken(ls, T_AND, tk_op); } return lex_newToken(ls, '&', tk_op); case '|': lex_nextchar(ls); if(nc == '|') { lex_nextchar(ls); return lex_newToken(ls, T_OR, tk_op); } return lex_newToken(ls, '|', tk_op); case '^': lex_nextchar(ls); if(nc == '^') { lex_nextchar(ls); return lex_newToken(ls, T_XOR, tk_op); } return lex_newToken(ls, '^', tk_op); case '!': lex_nextchar(ls); return lex_newToken(ls, T_NOT, tk_op); case ':': lex_nextchar(ls); if(nc == '=') { lex_nextchar(ls); return lex_newToken(ls, T_DE, tk_op); } return lex_newToken(ls, ':', 0); } char c = nc; lex_nextchar(ls); return lex_newToken(ls, c, 0); }
static inline int _atoi(const char **s){ int i = 0; while(isDigit(**s)) i = i * 10 + *((*s)++) - '0'; return i; }
extern int vsprintf(char *buf,const char *fmt,va_list args){ int style = 0; int width = 0; long num = 0; _bool sign = _true; HexBase base = DECIMAL; char *str,*s; enum type{ _long = 'L', _int = 'l' , _short = 'h' , _char = 'H',_string = 's'}_type = _int; //数据类型,long long,int,short for( str = buf; *fmt; fmt++){ if(*fmt == '%'){ style = 0; sign = _false; width = 0; _type = _int; repeat: fmt++; switch(* fmt){ case '-': style |= STYLE_LEFT;goto repeat; case '+': style |= STYLE_SIGN;goto repeat; case ' ': style |= STYLE_SIGN;goto repeat; case '0': style |= STYLE_ZEROPAD;goto repeat; case '#': style |= STYLE_SPECIAL;goto repeat; } if(isDigit(*fmt)) width = _atoi(&fmt); else if(* fmt == '*'){ fmt++; width = va_arg(args,int); } if(*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'H'){ _type = (enum type)(*fmt); fmt++; } switch(*fmt){ case 'c': *str++ = (unsigned char)va_arg(args,int);continue; case 's': _type = _string;break; case 'p': style |= STYLE_SPECIAL; base = HEX; break; case 'X': style |= STYLE_LARGE; case 'x': base = HEX;break; case 'd': base = DECIMAL; case 'i': sign = _true; case 'u': break; case 'o': base = OCTAL;break; default: if(*fmt) *str++ = *fmt; continue; } int mask = -1; switch(_type){ case _char: mask = 0xff; case _short: mask &= 0xffff; case _int: mask &= 0xffffffff; num = va_arg(args,int); str = _toNumber(str,num, sign,base,width,style,mask); break; case _long: num = va_arg(args,long long); str = _toNumber(str,num, sign,base,width,style,mask); break; case _string: s = va_arg(args,char *); if(!s) s = "<NULL>"; str = _toString(str,s,width,style); break; } }
static double RadixStringToDouble(const char* current, const char* end, bool sign, bool allow_trailing_junk, double junk_string_value, const char** trailing_pointer) { ASSERT(current != end); // Skip leading 0s. while (*current == '0') { ++current; if (current == end) { *trailing_pointer = end; return SignedZero(sign); } } int64_t number = 0; int exponent = 0; const int radix = (1 << radix_log_2); do { int digit; if (*current >= '0' && *current <= '9' && *current < '0' + radix) { digit = static_cast<char>(*current) - '0'; } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) { digit = static_cast<char>(*current) - 'a' + 10; } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) { digit = static_cast<char>(*current) - 'A' + 10; } else { if (allow_trailing_junk || !AdvanceToNonspace(¤t, end)) { break; } else { return junk_string_value; } } number = number * radix + digit; int overflow = static_cast<int>(number >> 53); if (overflow != 0) { // Overflow occurred. Need to determine which direction to round the // result. int overflow_bits_count = 1; while (overflow > 1) { overflow_bits_count++; overflow >>= 1; } int dropped_bits_mask = ((1 << overflow_bits_count) - 1); int dropped_bits = static_cast<int>(number) & dropped_bits_mask; number >>= overflow_bits_count; exponent = overflow_bits_count; bool zero_tail = true; while (true) { ++current; if (current == end || !isDigit(*current, radix)) break; zero_tail = zero_tail && *current == '0'; exponent += radix_log_2; } if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { return junk_string_value; } int middle_value = (1 << (overflow_bits_count - 1)); if (dropped_bits > middle_value) { number++; // Rounding up. } else if (dropped_bits == middle_value) { // Rounding to even to consistency with decimals: half-way case rounds // up if significant part is odd and down otherwise. if ((number & 1) != 0 || !zero_tail) { number++; // Rounding up. } } // Rounding up may cause overflow. if ((number & ((int64_t)1 << 53)) != 0) { exponent++; number >>= 1; } break; }
short CRConData::CheckProgressInConsole(UINT nCursorLine) { if (!isValid(true, nWidth*(nCursorLine+1))) return -1; const wchar_t* pszCurLine = pConChar + (nWidth * nCursorLine); // Обработка прогресса NeroCMD и пр. консольных программ (если курсор находится в видимой области) //Плагин Update //"Downloading Far 99%" //NeroCMD //"012% ########.................................................................." //ChkDsk //"Completed: 25%" //Rar // ... Vista x86\Vista x86.7z 6% //aria2c //[#1 SIZE:0B/9.1MiB(0%) CN:1 SPD:1.2KiBs ETA:2h1m11s] int nIdx = 0; bool bAllowDot = false; short nProgress = -1; const wchar_t *szPercentEng = L" percent"; const wchar_t *szComplEng = L"Completed:"; static wchar_t szPercentRus[16] = {}, szComplRus[16] = {}; static int nPercentEngLen = lstrlen(szPercentEng), nComplEngLen = lstrlen(szComplEng); static int nPercentRusLen, nComplRusLen; if (szPercentRus[0] == 0) { szPercentRus[0] = L' '; TODO("Хорошо бы и другие национальные названия обрабатывать, брать из настройки"); lstrcpy(szPercentRus,L"процент"); lstrcpy(szComplRus,L"Завершено:"); nPercentRusLen = lstrlen(szPercentRus); nComplRusLen = lstrlen(szComplEng); } // Сначала проверим, может цифры идут в начале строки (лидирующие пробелы)? if (pszCurLine[nIdx] == L' ' && isDigit(pszCurLine[nIdx+1])) nIdx++; // один лидирующий пробел перед цифрой else if (pszCurLine[nIdx] == L' ' && pszCurLine[nIdx+1] == L' ' && isDigit(pszCurLine[nIdx+2])) nIdx += 2; // два лидирующих пробела перед цифрой else if (!isDigit(pszCurLine[nIdx])) { // Строка начинается НЕ с цифры. Может начинается одним из известных префиксов (ChkDsk)? if (!wcsncmp(pszCurLine, szComplRus, nComplRusLen)) { nIdx += nComplRusLen; if (pszCurLine[nIdx] == L' ') nIdx++; if (pszCurLine[nIdx] == L' ') nIdx++; bAllowDot = true; } else if (!wcsncmp(pszCurLine, szComplEng, nComplEngLen)) { nIdx += nComplEngLen; if (pszCurLine[nIdx] == L' ') nIdx++; if (pszCurLine[nIdx] == L' ') nIdx++; bAllowDot = true; } else if (!wcsncmp(pszCurLine, L"[#", 2)) { const wchar_t* p = wcsstr(pszCurLine, L"%) "); while ((p > pszCurLine) && (p[-1] != L'(')) p--; if (p > pszCurLine) nIdx = p - pszCurLine; } // Известных префиксов не найдено, проверяем, может процент есть в конце строки? if (!nIdx) { //TODO("Не работает с одной цифрой"); // Creating archive T:\From_Work\VMWare\VMWare.part006.rar // ... Vista x86\Vista x86.7z 6% int i = nWidth - 1; // Откусить trailing spaces while ((i > 3) && (pszCurLine[i] == L' ')) i--; // Теперь, если дошли до '%' и перед ним - цифра if (i >= 3 && pszCurLine[i] == L'%' && isDigit(pszCurLine[i-1])) { //i -= 2; i--; int j = i, k = -1; while (j > 0 && isDigit(pszCurLine[j-1])) j--; // Может быть что-то типа "Progress 25.15%" if (((i - j) <= 2) && (j >= 2) && isDot(pszCurLine[j-1])) { k = j - 1; while (k > 0 && isDigit(pszCurLine[k-1])) k--; } if (k >= 0) { if (((j - k) <= 3) // 2 цифры + точка || (((j - k) <= 4) && (pszCurLine[k] == L'1'))) // "100.0%" { nIdx = i = k; bAllowDot = true; } } else { if (((j - i) <= 2) // 2 цифры + точка || (((j - i) <= 3) && (pszCurLine[j] == L'1'))) // "100%" { nIdx = i = j; } } #if 0 // Две цифры перед '%'? if (isDigit(pszCurLine[i-1])) i--; // Три цифры допускается только для '100%' if (pszCurLine[i-1] == L'1' && !isDigit(pszCurLine[i-2])) { nIdx = i - 1; } // final check else if (!isDigit(pszCurLine[i-1])) { nIdx = i; } #endif // Может ошибочно детектировать прогресс, если его ввести в prompt // Допустим, что если в строке есть символ '>' - то это не прогресс while (i>=0) { if (pszCurLine[i] == L'>') { nIdx = 0; break; } i--; } } } } // Менять nProgress только если нашли проценты в строке с курсором if (isDigit(pszCurLine[nIdx])) { if (isDigit(pszCurLine[nIdx+1]) && isDigit(pszCurLine[nIdx+2]) && (pszCurLine[nIdx+3]==L'%' || (bAllowDot && isDot(pszCurLine[nIdx+3])) || !wcsncmp(pszCurLine+nIdx+3,szPercentEng,nPercentEngLen) || !wcsncmp(pszCurLine+nIdx+3,szPercentRus,nPercentRusLen))) { nProgress = 100*(pszCurLine[nIdx] - L'0') + 10*(pszCurLine[nIdx+1] - L'0') + (pszCurLine[nIdx+2] - L'0'); } else if (isDigit(pszCurLine[nIdx+1]) && (pszCurLine[nIdx+2]==L'%' || (bAllowDot && isDot(pszCurLine[nIdx+2])) || !wcsncmp(pszCurLine+nIdx+2,szPercentEng,nPercentEngLen) || !wcsncmp(pszCurLine+nIdx+2,szPercentRus,nPercentRusLen))) { nProgress = 10*(pszCurLine[nIdx] - L'0') + (pszCurLine[nIdx+1] - L'0'); } else if (pszCurLine[nIdx+1]==L'%' || (bAllowDot && isDot(pszCurLine[nIdx+1])) || !wcsncmp(pszCurLine+nIdx+1,szPercentEng,nPercentEngLen) || !wcsncmp(pszCurLine+nIdx+1,szPercentRus,nPercentRusLen)) { nProgress = (pszCurLine[nIdx] - L'0'); } } if (nProgress != -1) { mp_RCon->setLastConsoleProgress(nProgress, true); // его обновляем всегда } else { DWORD nDelta = GetTickCount() - mp_RCon->m_Progress.LastConProgrTick; if (nDelta < CONSOLEPROGRESSTIMEOUT) // Если таймаут предыдущего значения еще не наступил nProgress = mp_RCon->m_Progress.ConsoleProgress; // возъмем предыдущее значение mp_RCon->setLastConsoleProgress(-1, false); // его обновляем всегда } return nProgress; }
ConstantToken* PreprocessorLexer::scanNumber(const std::string& input, size_t& end) const { std::string numberString(""); ConstantToken::Base base = ConstantToken::BASE_10; ConstantToken::ConstantType type = ConstantToken::TYPE_INT; bool hasExponent = false; bool (*pred)(const char ref) = &isDigit; size_t pos = 0; for (bool atEnd = false; ((! atEnd) && (pos < input.length())); ++pos) { const char top = input[pos]; const char next = ((pos < (input.length() - 1)) ? input[pos + 1] : '\0'); if ((pred != 0) && ((*pred)(top) == true)) { numberString += top; if ((pos == 0) && (top == '0')) { if ((next == 'x') || (next == 'X')) { numberString += next; ++pos; pred = &isHexDigit; base = ConstantToken::BASE_16; } else if (next == '.') type = ConstantToken::TYPE_FLOAT; else { pred = &isOctalDigit; base = ConstantToken::BASE_8; } } switch (next) { case 'u': case 'U': atEnd = true; if (type == ConstantToken::TYPE_INT) { numberString += next; ++pos; type = ConstantToken::TYPE_UINT; } break; case 'f': case 'F': atEnd = true; if (type == ConstantToken::TYPE_FLOAT) { numberString += next; ++pos; } break; case '.': if (base == ConstantToken::BASE_10) { type = ConstantToken::TYPE_FLOAT; numberString += next; ++pos; } break; case 'e': case 'E': if (type == ConstantToken::TYPE_FLOAT) { hasExponent = true; numberString += next; ++pos; } break; default: break; } } else if ((top == 'f') && (type == ConstantToken::TYPE_FLOAT)) { numberString += top; } else if ((top == '.') && (base == ConstantToken::BASE_10)) { // Accept the dot '.' only, if it is not the first character or // if a digit is following to avoid invalid ".f" strings. // if ((pos > 0) || (isDigit(next) == true)) { type = ConstantToken::TYPE_FLOAT; numberString += top; } } else if (((top == '+') || (top == '-')) && (hasExponent == true)) { numberString += top; } else break; } // for (pos end = (pos > 0) ? --pos : 0; if (numberString.empty() == true) return 0; return new ConstantToken(PreprocessorTerminals::ID_CONSTANT, numberString, type, base); }
bool isWordCharacter(char c) { return isDigit(c)||isCapitalLetter(c)||isSmallLetter(c)||c=='-'; }
bool Lexer::isValueLetter(char c) { return c == '-' || c == '+' || c == '.' || isDigit(c) || isBooleanLetter(c); }
bool CMatch::MatchAny() { bool bFound = false; // В именах файлов недопустимы: "/\:|*?<>~t~r~n а для простоты - учитываем и рамки const wchar_t* pszBreak = gszBreak; const wchar_t* pszSpacing = gszSpacing; // Пробел, таб, остальные для режима "Show white spaces" в редакторе фара const wchar_t* pszSeparat = L" \t:("; const wchar_t* pszTermint = L":)],"; const wchar_t* pszDigits = L"0123456789"; const wchar_t* pszSlashes = L"/\\"; const wchar_t* pszUrl = L":/\\:%#ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz;?@&=+$,-_.!~*'()0123456789"; const wchar_t* pszUrlTrimRight = L".,;"; const wchar_t* pszProtocol = L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_+-."; const wchar_t* pszEMail = L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_+-."; const wchar_t* pszUrlDelim = L"\\\"<>{}[]^`'\r\n" MATCH_SPACINGS; const wchar_t* pszUrlFileDelim = L"\"<>^\r\n" MATCH_SPACINGS; const wchar_t* pszEndBrackets = L">])}"; const wchar_t* pszPuctuators = L".,:;…!?"; int nColons = 0; bool bUrlMode = false, bMaybeMail = false; SHORT MailX = -1; bool bDigits = false, bLineNumberFound = false, bWasSeparator = false; bool bWasPunctuator = false; bool bNakedFile = false; int nNakedFileLen = 0; enum { ef_NotFound = 0, ef_DotFound = 1, ef_ExtFound = 2, } iExtFound = ef_NotFound; int iBracket = 0; int iSpaces = 0; int iQuotStart = -1; const wchar_t* pszTest; mn_MatchLeft = mn_MatchRight = mn_SrcFrom; // Курсор над знаком препинания и за ним пробел? Допускать только ':' - это для строк/колонок с ошибками if ((wcschr(L";,.", m_SrcLine.ms_Val[mn_SrcFrom])) && (((mn_SrcFrom+1) >= mn_SrcLength) || wcschr(pszSpacing, m_SrcLine.ms_Val[mn_SrcFrom+1]))) { MatchTestAlert(); goto wrap; } // Курсор над протоколом? (http, etc) if (!CheckValidUrl(mn_MatchLeft, mn_MatchRight, bUrlMode, pszUrlDelim, pszUrl, pszProtocol, m_SrcLine.ms_Val, mn_SrcLength)) { MatchTestAlert(); goto wrap; } if (!bUrlMode) { // Not URL mode, restart searching mn_MatchLeft = mn_MatchRight = mn_SrcFrom; // Курсор над комментарием? // Попробуем найти начало имени файла if (!FindRangeStart(mn_MatchLeft, mn_MatchRight, bUrlMode, pszBreak, pszUrlDelim, pszSpacing, pszUrl, pszProtocol, m_SrcLine.ms_Val, mn_SrcLength)) { MatchTestAlert(); goto wrap; } // Try again with URL? if (mn_MatchLeft < mn_SrcFrom) { if (!CheckValidUrl(mn_MatchLeft, mn_MatchRight, bUrlMode, pszUrlDelim, pszUrl, pszProtocol, m_SrcLine.ms_Val, mn_SrcLength)) { MatchTestAlert(); goto wrap; } } } // Starts with quotation? if ((pszTest = wcschr(gszQuotStart, m_SrcLine.ms_Val[mn_MatchLeft])) != NULL) { iQuotStart = (int)(pszTest - gszQuotStart); } // Чтобы корректно флаги обработались (типа наличие расширения и т.п.) mn_MatchRight = mn_MatchLeft; // Теперь - найти конец. // Считаем, что для файлов конец это двоеточие, после которого идет описание ошибки // Для протоколов (http/...) - первый недопустимый символ TODO("Можно бы и просто открытие файлов прикрутить, без требования 'строки с ошибкой'"); // -- VC // 1>c:\sources\conemu\realconsole.cpp(8104) : error C2065: 'qqq' : undeclared identifier // DefResolve.cpp(18) : error C2065: 'sdgagasdhsahd' : undeclared identifier // DefResolve.cpp(18): warning: note xxx // -- GCC // ConEmuC.cpp:49: error: 'qqq' does not name a type // 1.c:3: some message // file.cpp:29:29: error // CPP Check // [common\PipeServer.h:1145]: (style) C-style pointer casting // Delphi // c:\sources\FarLib\FarCtrl.pas(1002) Error: Undeclared identifier: 'PCTL_GETPLUGININFO' // FPC // FarCtrl.pas(1002,49) Error: Identifier not found "PCTL_GETPLUGININFO" // PowerShell // Script.ps1:35 знак:23 // -- Possible? // abc.py (3): some message // ASM - подсвечивать нужно "test.asasm(1,1)" // [email protected](1239): test.asasm(1,1): // Issue 1594 // /src/class.c:123:m_func(...) // /src/class.c:123: m_func(...) // -- URL's // file://c:\temp\qqq.html // http://www.farmanager.com // $ http://www.KKK.ru - левее слеша - не срабатывает // C:\ConEmu>http://www.KKK.ru - ... // -- False detects // 29.11.2011 18:31:47 // C:\VC\unicode_far\macro.cpp 1251 Ln 5951/8291 Col 51 Ch 39 0043h 13:54 // InfoW1900->SettingsControl(sc.Handle, SCTL_FREE, 0, 0); // Нас на интересуют строки типа "11.05.2010 10:20:35" // В имени файла должна быть хотя бы одна буква (расширение), причем английская // Поехали if (bUrlMode) { LPCWSTR pszDelim = (wcsncmp(m_SrcLine.ms_Val+mn_MatchLeft, L"file://", 7) == 0) ? pszUrlFileDelim : pszUrlDelim; while (((mn_MatchRight+1) < mn_SrcLength) && !wcschr(pszDelim, m_SrcLine.ms_Val[mn_MatchRight+1])) mn_MatchRight++; DEBUGTEST(int i4break = 0); } else while ((mn_MatchRight+1) < mn_SrcLength) { if ((m_SrcLine.ms_Val[mn_MatchRight] == L'/') && ((mn_MatchRight+1) < mn_SrcLength) && (m_SrcLine.ms_Val[mn_MatchRight+1] == L'/') && !((mn_MatchRight > 1) && (m_SrcLine.ms_Val[mn_MatchRight] == L':'))) // и НЕ URL адрес { MatchTestAlert(); goto wrap; // Не оно (комментарий в строке) } if (bWasSeparator // " \t:(" && (isDigit(m_SrcLine.ms_Val[mn_MatchRight]) || (bDigits && (m_SrcLine.ms_Val[mn_MatchRight] == L',')))) // FarCtrl.pas(1002,49) Error: { if (!bDigits && (mn_MatchLeft < mn_MatchRight) /*&& (m_SrcLine.ms_Val[mn_MatchRight-1] == L':')*/) { bDigits = true; // Если перед разделителем был реальный файл - сразу выставим флажок "номер строки найден" if (IsValidFile(m_SrcLine.ms_Val+mn_MatchLeft, mn_MatchRight - mn_MatchLeft - 1, pszBreak, pszSpacing, nNakedFileLen)) { bLineNumberFound = true; } // Skip leading quotation mark? else if ((iQuotStart >= 0) && IsValidFile(m_SrcLine.ms_Val+mn_MatchLeft+1, mn_MatchRight - mn_MatchLeft - 2, pszBreak, pszSpacing, nNakedFileLen)) { mn_MatchLeft++; bLineNumberFound = true; } } } else if (bWasSeparator && bLineNumberFound && wcschr(L":)] \t", m_SrcLine.ms_Val[mn_MatchRight])) { //// gcc такие строки тоже может выкинуть //// file.cpp:29:29: error //mn_MatchRight--; break; } else { if (iExtFound != ef_ExtFound) { if (iExtFound == ef_NotFound) { if (m_SrcLine.ms_Val[mn_MatchRight] == L'.') iExtFound = ef_ExtFound; } else { // Не особо заморачиваясь с точками и прочим. Просто небольшая страховка от ложных срабатываний... if ((m_SrcLine.ms_Val[mn_MatchRight] >= L'a' && m_SrcLine.ms_Val[mn_MatchRight] <= L'z') || (m_SrcLine.ms_Val[mn_MatchRight] >= L'A' && m_SrcLine.ms_Val[mn_MatchRight] <= L'Z')) { iExtFound = ef_ExtFound; iBracket = 0; } } } if (iExtFound == 2) { if (m_SrcLine.ms_Val[mn_MatchRight] == L'.') { iExtFound = ef_DotFound; iBracket = 0; } else if (wcschr(pszSlashes, m_SrcLine.ms_Val[mn_MatchRight]) != NULL) { // Был слеш, значит расширения - еще нет iExtFound = ef_NotFound; iBracket = 0; bWasSeparator = false; } else if (wcschr(pszSpacing, m_SrcLine.ms_Val[mn_MatchRight]) && wcschr(pszSpacing, m_SrcLine.ms_Val[mn_MatchRight-1])) { // Слишком много пробелов iExtFound = ef_NotFound; iBracket = 0; bWasSeparator = false; } // Stop on naked file if we found space after it else if (!bLineNumberFound && !bMaybeMail && wcschr(pszSpacing, m_SrcLine.ms_Val[mn_MatchRight]) // But don't stop if there is a line number: "abc.py (3): ..." && !(((mn_MatchRight+3) < mn_SrcLength) && (m_SrcLine.ms_Val[mn_MatchRight+1] == L'(') && isDigit(m_SrcLine.ms_Val[mn_MatchRight+2])) // Is this a file without digits (line/col)? && IsValidFile(m_SrcLine.ms_Val+mn_MatchLeft, mn_MatchRight - mn_MatchLeft + 1, pszBreak, pszSpacing, nNakedFileLen)) { // File without digits, just for opening in the editor bNakedFile = true; break; } // Stop if after colon there is another letter but a digit else if (!bLineNumberFound && !bMaybeMail && (m_SrcLine.ms_Val[mn_MatchRight] == L':') && (((mn_MatchRight+1) >= mn_SrcLength) || !isDigit(m_SrcLine.ms_Val[mn_MatchRight+1])) // Is this a file without digits (line/col)? && IsValidFile(m_SrcLine.ms_Val+mn_MatchLeft, mn_MatchRight - mn_MatchLeft, pszBreak, pszSpacing, nNakedFileLen)) { // File without digits, just for opening in the editor bNakedFile = true; mn_MatchRight--; break; } else { bWasSeparator = (wcschr(pszSeparat, m_SrcLine.ms_Val[mn_MatchRight]) != NULL); } } if ((iQuotStart >= 0) && (m_SrcLine.ms_Val[mn_MatchRight] == gszQuotEnd[iQuotStart])) { bNakedFile = IsValidFile(m_SrcLine.ms_Val+mn_MatchLeft+1, mn_MatchRight - mn_MatchLeft - 1, pszBreak, pszSpacing, nNakedFileLen); if (bNakedFile || bMaybeMail) { mn_MatchLeft++; mn_MatchRight--; break; } } if (bWasPunctuator && !bLineNumberFound) { if (bMaybeMail) { // Если после мейла нашли что-то кроме точки if ((m_SrcLine.ms_Val[mn_MatchRight-1] != L'.') // или после точки - пробельный символ || wcschr(pszSpacing, m_SrcLine.ms_Val[mn_MatchRight])) { break; } } else if (wcschr(pszSpacing, m_SrcLine.ms_Val[mn_MatchRight])) { bNakedFile = IsValidFile(m_SrcLine.ms_Val+mn_MatchLeft, mn_MatchRight - mn_MatchLeft - 1, pszBreak, pszSpacing, nNakedFileLen); if (bNakedFile) { mn_MatchRight--; break; } } } bWasPunctuator = (wcschr(pszPuctuators, m_SrcLine.ms_Val[mn_MatchRight]) != NULL); // Рассчитано на закрывающие : или ) или ] или , _ASSERTE(pszTermint[0]==L':' && pszTermint[1]==L')' && pszTermint[2]==L']' && pszTermint[3]==L',' && pszTermint[4]==0); // Script.ps1:35 знак:23 if (bDigits && IsFileLineTerminator(m_SrcLine.ms_Val+mn_MatchRight, pszTermint)) { // Validation if (((m_SrcLine.ms_Val[mn_MatchRight] == L':' || m_SrcLine.ms_Val[mn_MatchRight] == L' ') // Issue 1594: /src/class.c:123:m_func(...) /* && (wcschr(pszSpacing, m_SrcLine.ms_Val[mn_MatchRight+1]) || wcschr(pszDigits, m_SrcLine.ms_Val[mn_MatchRight+1]))*/) // Если номер строки обрамлен скобками - скобки должны быть сбалансированы || ((m_SrcLine.ms_Val[mn_MatchRight] == L')') && (iBracket == 1) && ((m_SrcLine.ms_Val[mn_MatchRight+1] == L':') || wcschr(pszSpacing, m_SrcLine.ms_Val[mn_MatchRight+1]) || wcschr(pszDigits, m_SrcLine.ms_Val[mn_MatchRight+1]))) // [file.cpp:1234]: (cppcheck) || ((m_SrcLine.ms_Val[mn_MatchRight] == L']') && (m_SrcLine.ms_Val[mn_MatchRight+1] == L':')) ) { //_ASSERTE(bLineNumberFound==false); //bLineNumberFound = true; break; // found? } } // Issue 1758: Support file/line format for php: C:\..\test.php:28 if (bDigits && !wcschr(pszSpacing, m_SrcLine.ms_Val[mn_MatchRight])) { bDigits = false; } switch (m_SrcLine.ms_Val[mn_MatchRight]) { // Пока регулярок нет... case L'(': iBracket++; break; case L')': iBracket--; break; case L'/': case L'\\': iBracket = 0; break; case L'@': if (MailX != -1) { bMaybeMail = false; } else if (((mn_MatchRight > 0) && wcschr(pszEMail, m_SrcLine.ms_Val[mn_MatchRight-1])) && (((mn_MatchRight+1) < mn_SrcLength) && wcschr(pszEMail, m_SrcLine.ms_Val[mn_MatchRight+1]))) { bMaybeMail = true; MailX = mn_MatchRight; } break; } if (m_SrcLine.ms_Val[mn_MatchRight] == L':') nColons++; else if (m_SrcLine.ms_Val[mn_MatchRight] == L'\\' || m_SrcLine.ms_Val[mn_MatchRight] == L'/') nColons = 0; } if (nColons >= 2) break; mn_MatchRight++; if (wcschr(pszBreak, m_SrcLine.ms_Val[mn_MatchRight])) { if (bMaybeMail) break; if ((bLineNumberFound) || !IsValidFile(m_SrcLine.ms_Val+mn_MatchLeft, mn_MatchRight - mn_MatchLeft + 1, pszBreak, pszSpacing, nNakedFileLen)) { MatchTestAlert(); goto wrap; // Не оно } // File without digits, just for opening in the editor _ASSERTE(!bLineNumberFound); bNakedFile = true; break; } else if (wcschr(pszSpacing, m_SrcLine.ms_Val[mn_MatchRight])) { if ((++iSpaces) > 1) { if ((bLineNumberFound) || !IsValidFile(m_SrcLine.ms_Val+mn_MatchLeft, mn_MatchRight - mn_MatchLeft + 1, pszBreak, pszSpacing, nNakedFileLen)) { if (!bLineNumberFound && bMaybeMail) break; MatchTestAlert(); goto wrap; // Не оно? } // File without digits, just for opening in the editor _ASSERTE(!bLineNumberFound); bNakedFile = true; break; } } else { iSpaces = 0; } } // end of 'while ((mn_MatchRight+1) < mn_SrcLength)' if (bUrlMode) { // Считаем, что OK bMaybeMail = false; // Cut off ending punctuators if (wcschr(pszPuctuators, m_SrcLine.ms_Val[mn_MatchRight])) mn_MatchRight--; // Cut off ending bracket if it is if (wcschr(pszEndBrackets, m_SrcLine.ms_Val[mn_MatchRight])) mn_MatchRight--; } else { if (!bNakedFile && !bMaybeMail && ((mn_MatchRight+1) == mn_SrcLength) && !bLineNumberFound && (iExtFound == ef_ExtFound)) { bNakedFile = IsValidFile(m_SrcLine.ms_Val+mn_MatchLeft, mn_MatchRight - mn_MatchLeft + 1, pszBreak, pszSpacing, nNakedFileLen); } if (bLineNumberFound) bMaybeMail = false; if (bNakedFile) { // correct the end pos mn_MatchRight = mn_MatchLeft + nNakedFileLen - 1; _ASSERTE(mn_MatchRight > mn_MatchLeft); // and no need to check for colon } else if (bMaybeMail) { // no need to check for colon } else if ((m_SrcLine.ms_Val[mn_MatchRight] != L':' && m_SrcLine.ms_Val[mn_MatchRight] != L' ' && !((m_SrcLine.ms_Val[mn_MatchRight] == L')') && iBracket == 1) && !((m_SrcLine.ms_Val[mn_MatchRight] == L']') && (m_SrcLine.ms_Val[mn_MatchRight+1] == L':')) ) || !bLineNumberFound || (nColons > 2)) { MatchTestAlert(); goto wrap; } if (bMaybeMail || (!bMaybeMail && !bNakedFile && m_SrcLine.ms_Val[mn_MatchRight] != L')')) mn_MatchRight--; // Откатить ненужные пробелы while ((mn_MatchLeft < mn_MatchRight) && wcschr(pszSpacing, m_SrcLine.ms_Val[mn_MatchLeft])) mn_MatchLeft++; while ((mn_MatchRight > mn_MatchLeft) && wcschr(pszSpacing, m_SrcLine.ms_Val[mn_MatchRight])) mn_MatchRight--; if (bMaybeMail) { // Для мейлов - проверяем допустимые символы (чтобы пробелов не было и прочего мусора) int x = MailX - 1; _ASSERTE(x>=0); while ((x > 0) && wcschr(pszEMail, m_SrcLine.ms_Val[x-1])) x--; mn_MatchLeft = x; x = MailX + 1; _ASSERTE(x<mn_SrcLength); while (((x+1) < mn_SrcLength) && wcschr(pszEMail, m_SrcLine.ms_Val[x+1])) x++; mn_MatchRight = x; } else if (bNakedFile) { // ??? } else { if ((mn_MatchLeft + 4) > mn_MatchRight) // 1.c:1: //-V112 { // Слишком коротко, считаем что не оно MatchTestAlert(); goto wrap; } // Проверить, чтобы был в наличии номер строки if (!(m_SrcLine.ms_Val[mn_MatchRight] >= L'0' && m_SrcLine.ms_Val[mn_MatchRight] <= L'9') // ConEmuC.cpp:49: && !(m_SrcLine.ms_Val[mn_MatchRight] == L')' && (m_SrcLine.ms_Val[mn_MatchRight-1] >= L'0' && m_SrcLine.ms_Val[mn_MatchRight-1] <= L'9'))) // ConEmuC.cpp(49) : { MatchTestAlert(); goto wrap; // Номера строки нет } // [file.cpp:1234]: (cppcheck) ? if ((m_SrcLine.ms_Val[mn_MatchRight+1] == L']') && (m_SrcLine.ms_Val[mn_MatchLeft] == L'[')) mn_MatchLeft++; // Чтобы даты ошибочно не подсвечивать: // 29.11.2011 18:31:47 { bool bNoDigits = false; for (int i = mn_MatchLeft; i <= mn_MatchRight; i++) { if (m_SrcLine.ms_Val[i] < L'0' || m_SrcLine.ms_Val[i] > L'9') { bNoDigits = true; } } if (!bNoDigits) { MatchTestAlert(); goto wrap; } } // -- уже включены // Для красивости в VC включить скобки //if ((m_SrcLine.ms_Val[mn_MatchRight] == L')') && (m_SrcLine.ms_Val[mn_MatchRight+1] == L':')) // mn_MatchRight++; } } // end "else / if (bUrlMode)" // Check mouse pos, it must be inside region if ((mn_SrcFrom < mn_MatchLeft) || (mn_MatchRight < mn_SrcFrom)) { MatchTestAlert(); goto wrap; } // Ok if (mn_MatchRight >= mn_MatchLeft) { bFound = true; _ASSERTE(!bMaybeMail || !bUrlMode); // Одновременно - флаги не могут быть выставлены! LPCWSTR pszPrefix = (bMaybeMail && !bUrlMode) ? L"mailto:" : NULL; if (bMaybeMail && !bUrlMode) bUrlMode = true; StoreMatchText(pszPrefix, bUrlMode ? pszUrlTrimRight : NULL); #ifdef _DEBUG if (!bUrlMode && wcsstr(ms_Match.ms_Val, L"//")!=NULL) { _ASSERTE(FALSE); } #endif } if (bUrlMode) m_Type = etr_Url; else m_Type = (bLineNumberFound ? etr_FileRow : etr_File); wrap: return bFound; }
static bool isAlnum( char ch) { return isAlpha(ch)||isDigit(ch); }
// Returns ">0" - when changes was made // 0 - no changes // -1 - error // bForceCurConsole==true, если разбор параметров идет // при запуске Tasks из GUI int RConStartArgs::ProcessNewConArg(bool bForceCurConsole /*= false*/) { NewConsole = crb_Undefined; if (!pszSpecialCmd || !*pszSpecialCmd) { _ASSERTE(pszSpecialCmd && *pszSpecialCmd); return -1; } int nChanges = 0; // 140219 - Остановить обработку, если встретим любой из: ConEmu[.exe], ConEmu64[.exe], ConEmuC[.exe], ConEmuC64[.exe] LPCWSTR pszStopAt = NULL; { LPCWSTR pszTemp = pszSpecialCmd; LPCWSTR pszSave = pszSpecialCmd; LPCWSTR pszName; CmdArg szExe; LPCWSTR pszWords[] = {L"ConEmu", L"ConEmu.exe", L"ConEmu64", L"ConEmu64.exe", L"ConEmuC", L"ConEmuC.exe", L"ConEmuC64", L"ConEmuC64.exe", L"ConEmuPortable.exe", L"ConEmuPortable", NULL}; while (!pszStopAt && (0 == NextArg(&pszTemp, szExe))) { pszName = PointToName(szExe); for (size_t i = 0; pszWords[i]; i++) { if (lstrcmpi(pszName, pszWords[i]) == 0) { pszStopAt = pszSave; break; } } pszSave = pszTemp; } } #if 0 // 140219 - Остановить обработку, если встретим любой из: ConEmu[.exe], ConEmu64[.exe], ConEmuC[.exe], ConEmuC64[.exe] if (!hShlwapi) { hShlwapi = LoadLibrary(L"Shlwapi.dll"); WcsStrI = hShlwapi ? (StrStrI_t)GetProcAddress(hShlwapi, "StrStrIW") : NULL; } #endif // 111211 - здесь может быть передан "-new_console:..." LPCWSTR pszNewCon = L"-new_console"; // 120108 - или "-cur_console:..." для уточнения параметров запуска команд (из фара например) LPCWSTR pszCurCon = L"-cur_console"; int nNewConLen = lstrlen(pszNewCon); _ASSERTE(lstrlen(pszCurCon)==nNewConLen); wchar_t* pszFrom = pszSpecialCmd; bool bStop = false; while (!bStop) { wchar_t* pszSwitch = wcschr(pszFrom, L'-'); if (!pszSwitch) break; // Pre-validation if (((pszSwitch[1] != L'n') && (pszSwitch[1] != L'c')) // -new_... or -cur_... || (((pszSwitch != /* > */ pszFrom) // If it is started from pszFrom - no need to check previous symbols && (*(pszSwitch-1) != L'"') || (((pszSwitch-2) >= pszFrom) && (*(pszSwitch-2) == L'\\'))) // Found: \"-new... && (*(pszSwitch-1) != L' '))) // Prev symbol was space { // НЕ наш аргумент pszSwitch = wcschr(pszSwitch+1, L' '); if (!pszSwitch) break; pszFrom = pszSwitch; continue; } wchar_t* pszFindNew = NULL; wchar_t* pszFind = NULL; wchar_t szTest[12]; lstrcpyn(szTest, pszSwitch+1, countof(szTest)); if (lstrcmp(szTest, L"new_console") == 0) pszFindNew = pszFind = pszSwitch; else if (lstrcmp(szTest, L"cur_console") == 0) pszFind = pszSwitch; else { // НЕ наш аргумент pszSwitch = wcschr(pszSwitch+1, L' '); if (!pszSwitch) break; pszFrom = pszSwitch; continue; } if (!pszFind) break; if (pszStopAt && (pszFind >= pszStopAt)) break; // Проверка валидности _ASSERTE(pszFind >= pszSpecialCmd); if ((pszFind[nNewConLen] != L' ') && (pszFind[nNewConLen] != L':') && (pszFind[nNewConLen] != L'"') && (pszFind[nNewConLen] != 0)) { // НЕ наш аргумент pszFrom = pszFind+nNewConLen; } else { if (pszFindNew) NewConsole = crb_On; // -- не будем пока, мешает. например, при запуске задач //// По умолчанию, принудительно включить "Press Enter or Esc to close console" //if (!bForceCurConsole) // eConfirmation = eConfAlways; bool lbQuot = (*(pszFind-1) == L'"'); bool lbWasQuot = lbQuot; const wchar_t* pszEnd = pszFind+nNewConLen; //wchar_t szNewConArg[MAX_PATH+1]; if (lbQuot) pszFind--; if (*pszEnd == L'"') { pszEnd++; } else if (*pszEnd != L':') { // Конец _ASSERTE(*pszEnd == L' ' || *pszEnd == 0); } else { if (*pszEnd == L':') { pszEnd++; } else { _ASSERTE(*pszEnd == L':'); } // Найти конец аргумента const wchar_t* pszArgEnd = pszEnd; bool lbLocalQuot = false; while (*pszArgEnd) { switch (*pszArgEnd) { case L'^': pszArgEnd++; // Skip control char, goto escaped char break; case L'"': if (*(pszArgEnd+1) == L'"') { pszArgEnd += 2; // Skip qoubled qouble quote continue; } if (!lbQuot) { if (!lbLocalQuot && (*(pszArgEnd-1) == L':')) { lbLocalQuot = true; pszArgEnd++; continue; } if (lbLocalQuot) { if (*(pszArgEnd+1) != L':') goto EndFound; lbLocalQuot = false; pszArgEnd += 2; continue; } } goto EndFound; case L' ': if (!lbQuot && !lbLocalQuot) goto EndFound; break; case 0: goto EndFound; } pszArgEnd++; } EndFound: // Обработка доп.параметров -new_console:xxx bool lbReady = false; while (!lbReady && *pszEnd) { _ASSERTE(pszEnd <= pszArgEnd); wchar_t cOpt = *(pszEnd++); switch (cOpt) { //case L'-': // bStop = true; // следующие "-new_console" - не трогать! // break; case L'"': _ASSERTE(pszEnd > pszArgEnd); lbReady = true; break; case L' ': case 0: lbReady = true; break; case L':': // Just skip ':'. Delimiter between switches: -new_console:c:b:a // Revert stored value to lbQuot. We need to "cut" last double quote in the first two cases // cmd -cur_console:d:"C:\users":t:"My title" "-cur_console:C:C:\cmd.ico" -cur_console:P:"<PowerShell>":a /k ver lbWasQuot = lbQuot; break; case L'b': // b - background, не активировать таб BackgroundTab = crb_On; ForegroungTab = crb_Off; break; case L'f': // f - foreground, активировать таб (аналог ">" в Tasks) ForegroungTab = crb_On; BackgroundTab = crb_Off; break; case L'z': // z - don't use "Default terminal" feature NoDefaultTerm = crb_On; break; case L'a': // a - RunAs shell verb (as admin on Vista+, login/password in WinXP-) RunAsAdministrator = crb_On; break; case L'r': // r - run as restricted user RunAsRestricted = crb_On; break; case L'o': // o - disable "Long output" for next command (Far Manager) LongOutputDisable = crb_On; break; case L'w': // e - enable "Overwrite" mode in console prompt OverwriteMode = crb_On; break; case L'p': if (isDigit(*pszEnd)) { switch (*(pszEnd++)) { case L'0': nPTY = 0; // don't change break; case L'1': nPTY = 1; // enable PTY mode break; case L'2': nPTY = 2; // disable PTY mode (switch to plain $CONIN, $CONOUT, $CONERR) break; default: nPTY = 1; } } else { nPTY = 1; // enable PTY mode } break; case L'i': // i - don't inject ConEmuHk into the starting application InjectsDisable = crb_On; break; case L'N': // N - Force new ConEmu window with Default terminal ForceNewWindow = crb_On; break; case L'h': // "h0" - отключить буфер, "h9999" - включить буфер в 9999 строк { BufHeight = crb_On; if (isDigit(*pszEnd)) { wchar_t* pszDigits = NULL; nBufHeight = wcstoul(pszEnd, &pszDigits, 10); if (pszDigits) pszEnd = pszDigits; } else { nBufHeight = 0; } } // L'h': break; case L'n': // n - отключить "Press Enter or Esc to close console" eConfirmation = eConfNever; break; case L'c': // c - принудительно включить "Press Enter or Esc to close console" eConfirmation = eConfAlways; break; case L'x': // x - Force using dosbox for .bat files ForceDosBox = crb_On; break; case L'I': // I - tell GuiMacro to execute new command inheriting active process state. This is only usage ATM. ForceInherit = crb_On; break; // "Long" code blocks below: 'd', 'u', 's' and so on (in future) case L's': // s[<SplitTab>T][<Percents>](H|V) // Пример: "s3T30H" - разбить 3-ий таб. будет создан новый Pane справа, шириной 30% от 3-го таба. { UINT nTab = 0 /*active*/, nValue = /*пополам*/DefaultSplitValue/10; bool bDisableSplit = false; while (*pszEnd) { if (isDigit(*pszEnd)) { wchar_t* pszDigits = NULL; UINT n = wcstoul(pszEnd, &pszDigits, 10); if (!pszDigits) break; pszEnd = pszDigits; if (*pszDigits == L'T') { nTab = n; } else if ((*pszDigits == L'H') || (*pszDigits == L'V')) { nValue = n; eSplit = (*pszDigits == L'H') ? eSplitHorz : eSplitVert; } else { break; } pszEnd++; } else if (*pszEnd == L'T') { nTab = 0; pszEnd++; } else if ((*pszEnd == L'H') || (*pszEnd == L'V')) { nValue = DefaultSplitValue/10; eSplit = (*pszEnd == L'H') ? eSplitHorz : eSplitVert; pszEnd++; } else if (*pszEnd == L'N') { bDisableSplit = true; pszEnd++; break; } else { break; } } if (bDisableSplit) { eSplit = eSplitNone; nSplitValue = DefaultSplitValue; nSplitPane = 0; } else { if (!eSplit) eSplit = eSplitHorz; // Для удобства, пользователь задает размер НОВОЙ части nSplitValue = 1000-max(1,min(nValue*10,999)); // проценты _ASSERTE(nSplitValue>=1 && nSplitValue<1000); nSplitPane = nTab; } } // L's' break; // Following options (except of single 'u') must be placed on the end of "-new_console:..." // If one needs more that one option - use several "-new_console:..." switches case L'd': // d:<StartupDir>. MUST be last option case L't': // t:<TabName>. MUST be last option case L'u': // u - ConEmu choose user dialog (may be specified in the middle, if it is without ':' - user or pwd) // u:<user> - ConEmu choose user dialog with prefilled user field. MUST be last option // u:<user>:<pwd> - specify user/pwd in args. MUST be last option case L'C': // C:<IconFile>. MUST be last option case L'P': // P:<Palette>. MUST be last option case L'W': // W:<Wallpaper>. MUST be last option { if (cOpt == L'u') { // Show choose user dialog (may be specified in the middle, if it is without ':' - user or pwd) SafeFree(pszUserName); SafeFree(pszDomain); if (szUserPassword[0]) SecureZeroMemory(szUserPassword, sizeof(szUserPassword)); } if (*pszEnd == L':') { pszEnd++; } else { if (cOpt == L'u') { ForceUserDialog = crb_On; break; } } const wchar_t* pszTab = pszEnd; // we need to find end of argument pszEnd = pszArgEnd; // temp buffer wchar_t* lpszTemp = NULL; wchar_t** pptr = NULL; switch (cOpt) { case L'd': pptr = &pszStartupDir; break; case L't': pptr = &pszRenameTab; break; case L'u': pptr = &lpszTemp; break; case L'C': pptr = &pszIconFile; break; case L'P': pptr = &pszPalette; break; case L'W': pptr = &pszWallpaper; break; } if (pszEnd > pszTab) { size_t cchLen = pszEnd - pszTab; SafeFree(*pptr); *pptr = (wchar_t*)malloc((cchLen+1)*sizeof(**pptr)); if (*pptr) { // We need to process escape sequences ("^>" -> ">", "^&" -> "&", etc.) //wmemmove(*pptr, pszTab, cchLen); wchar_t* pD = *pptr; const wchar_t* pS = pszTab; if (lbQuot) { lbLocalQuot = false; } else if (*pS == L'"' && *(pS+1) != L'"') { // Remember, that last processed switch was local-quoted lbWasQuot = true; // This item is local quoted. Example: -new_console:t:"My title" lbLocalQuot = true; pS++; } // There is enough room allocated while (pS < pszEnd) { if ((*pS == L'^') && ((pS + 1) < pszEnd)) { pS++; // Skip control char, goto escaped char } else if (*pS == L'"') { if (((pS + 1) < pszEnd) && (*(pS+1) == L'"')) { pS++; // Skip qoubled qouble quote } else if (lbLocalQuot) { pszEnd = (pS+1); _ASSERTE(*pszEnd==L':' || *pszEnd==L' ' || *pszEnd==0); break; // End of local quoted argument: -new_console:d:"C:\User\super user":t:"My title" } } *(pD++) = *(pS++); } // Terminate with '\0' _ASSERTE(pD <= ((*pptr)+cchLen)); *pD = 0; } // Additional processing switch (cOpt) { case L'd': // Например, "%USERPROFILE%" // TODO("А надо ли разворачивать их тут? Наверное при запуске под другим юзером некорректно? Хотя... все равно до переменных не доберемся"); if (wcschr(pszStartupDir, L'%')) { wchar_t* pszExpand = NULL; if (((pszExpand = ExpandEnvStr(pszStartupDir)) != NULL)) { SafeFree(pszStartupDir); pszStartupDir = pszExpand; } } break; case L'u': if (lpszTemp) { // Split in form: // [Domain\]UserName[:Password] wchar_t* pszPwd = wcschr(lpszTemp, L':'); if (pszPwd) { // Password was specified, dialog prompt is not required ForceUserDialog = crb_Off; *pszPwd = 0; int nPwdLen = lstrlen(pszPwd+1); lstrcpyn(szUserPassword, pszPwd+1, countof(szUserPassword)); if (nPwdLen > 0) SecureZeroMemory(pszPwd+1, nPwdLen); UseEmptyPassword = (nPwdLen == 0) ? crb_On : crb_Off; } else { // Password was NOT specified, dialog prompt IS required ForceUserDialog = crb_On; UseEmptyPassword = crb_Off; } wchar_t* pszSlash = wcschr(lpszTemp, L'\\'); if (pszSlash) { *pszSlash = 0; pszDomain = lstrdup(lpszTemp); pszUserName = lstrdup(pszSlash+1); } else { pszUserName = lstrdup(lpszTemp); } } break; } } SafeFree(lpszTemp); } // L't': break; } } } if (pszEnd > pszFind) { // pszEnd должен указывать на конец -new_console[:...] / -cur_console[:...] // и включать обрамляющую кавычку, если он окавычен if (lbWasQuot) { if (*pszEnd == L'"' && *(pszEnd-1) != L'"') pszEnd++; } else { while (*(pszEnd-1) == L'"') pszEnd--; } // Откусить лишние пробелы, которые стоят ПЕРЕД -new_console[:...] / -cur_console[:...] while (((pszFind - 1) >= pszSpecialCmd) && (*(pszFind-1) == L' ') && (((pszFind - 1) == pszSpecialCmd) || (*(pszFind-2) == L' ') || (/**pszEnd == L'"' ||*/ *pszEnd == 0 || *pszEnd == L' '))) { pszFind--; } // Откусить лишние пробелы ПОСЛЕ -new_console[:...] / -cur_console[:...] если он стоит в НАЧАЛЕ строки! if (pszFind == pszSpecialCmd) { while (*pszEnd == L' ') pszEnd++; } // Здесь нужно подвинуть pszStopAt if (pszStopAt) pszStopAt -= (pszEnd - pszFind); // Удалить из строки запуска обработанный ключ wmemmove(pszFind, pszEnd, (lstrlen(pszEnd)+1)); nChanges++; } else { _ASSERTE(pszEnd > pszFind); *pszFind = 0; nChanges++; } } // if ((((pszFind == pszFrom) ... } // while (!bStop) return nChanges; } // int RConStartArgs::ProcessNewConArg(bool bForceCurConsole /*= false*/)
static qreal toDouble(const QChar *&str) { const int maxLen = 255;//technically doubles can go til 308+ but whatever char temp[maxLen+1]; int pos = 0; if (*str == QLatin1Char('-')) { temp[pos++] = '-'; ++str; } else if (*str == QLatin1Char('+')) { ++str; } while (isDigit(str->unicode()) && pos < maxLen) { temp[pos++] = str->toLatin1(); ++str; } if (*str == QLatin1Char('.') && pos < maxLen) { temp[pos++] = '.'; ++str; } while (isDigit(str->unicode()) && pos < maxLen) { temp[pos++] = str->toLatin1(); ++str; } bool exponent = false; if ((*str == QLatin1Char('e') || *str == QLatin1Char('E')) && pos < maxLen) { exponent = true; temp[pos++] = 'e'; ++str; if ((*str == QLatin1Char('-') || *str == QLatin1Char('+')) && pos < maxLen) { temp[pos++] = str->toLatin1(); ++str; } while (isDigit(str->unicode()) && pos < maxLen) { temp[pos++] = str->toLatin1(); ++str; } } temp[pos] = '\0'; qreal val; if (!exponent && pos < 10) { int ival = 0; const char *t = temp; bool neg = false; if(*t == '-') { neg = true; ++t; } while(*t && *t != '.') { ival *= 10; ival += (*t) - '0'; ++t; } if(*t == '.') { ++t; int div = 1; while(*t) { ival *= 10; ival += (*t) - '0'; div *= 10; ++t; } val = ((qreal)ival)/((qreal)div); } else { val = ival; } if (neg) val = -val; } else { bool ok = false; val = qstrtod(temp, 0, &ok); } return val; }
//////////////////////////////////////////////////////////////////////////////// // Lexer::Type::number // \d+ // [ . \d+ ] // [ e|E [ +|- ] \d+ [ . \d+ ] ] // not followed by non-operator. bool Lexer::isNumber (std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; if (isDigit (_text[marker])) { ++marker; while (isDigit (_text[marker])) utf8_next_char (_text, marker); if (_text[marker] == '.') { ++marker; if (isDigit (_text[marker])) { ++marker; while (isDigit (_text[marker])) utf8_next_char (_text, marker); } } if (_text[marker] == 'e' || _text[marker] == 'E') { ++marker; if (_text[marker] == '+' || _text[marker] == '-') ++marker; if (isDigit (_text[marker])) { ++marker; while (isDigit (_text[marker])) utf8_next_char (_text, marker); if (_text[marker] == '.') { ++marker; if (isDigit (_text[marker])) { ++marker; while (isDigit (_text[marker])) utf8_next_char (_text, marker); } } } } // Lookahread: !<isWhitespace> | !<isSingleCharOperator> // If there is an immediately consecutive character, that is not an operator, fail. if (_eos > marker && ! isWhitespace (_text[marker]) && ! isSingleCharOperator (_text[marker])) return false; token = _text.substr (_cursor, marker - _cursor); type = Lexer::Type::number; _cursor = marker; return true; } return false; }
void proc() { // 初始化&声明 int l = strlen(str); int i, t, type; int basey = 0, yt = 0; int count = 0, start = 0; char tstr[500]; tstr[0] = 0; proc_ret = SDL_CS(1, 1); SDL_FR(proc_ret); SDL_Surface *sf, *bkup, *f1, *f2; // start for (i = 0; i < l; i++) { switch (str[i]) { case '+': case '-': case '*': case '/': if (tstr[0]) { if (isDigit(tstr[0])) sf = TTF_RenderUTF8_Blended(fontBig, tstr, NUMCOLOR); else sf = TTF_RenderUTF8_Blended(fontBig, tstr, VARCOLOR); basey = _append(sf, basey, 0); } char tt[2]; tt[0] = str[i]; tt[1] = 0; sf = TTF_RenderUTF8_Blended(fontBig, tt, OPERCOLOR); basey = _append(sf, basey, 0); tstr[0] = 0; break; case '|': cursor = 1; break; case '_': if (str[++i] == 'p' && str[++i] == 'i') { sf = TTF_RenderUTF8_Blended(fontBig, "π", NUMCOLOR); basey = _append(sf, basey, 0); } break; case '(': start = i; bkup = proc_ret; for (;; i++) { if (str[i] == '(') count++; else if (str[i] == ')') { count--; if (!count) { break; } } } _proc(start + 1, i, 0, 1); SDL_Surface *bk2; bk2 = proc_ret; sf = TTF_RenderUTF8_Blended(fontSmall, "(", BRCOLOR); rDst.x = rDst.y = 0; rDst.w = sf->w; rDst.h = bk2->h; proc_ret = SDL_CS(bk2->w + 2 * sf->w, bk2->h); SDL_FillRect(proc_ret, NULL, BGCOLOR); SDL_BlitScaled(sf, NULL, proc_ret, &rDst); rDst.x = sf->w; SDL_FreeSurface(sf); rDst.y = 0; rDst.w = bk2->w; rDst.h = bk2->h; SDL_BlitSurface(bk2, NULL, proc_ret, &rDst); SDL_FreeSurface(bk2); sf = TTF_RenderUTF8_Blended(fontSmall, ")", BRCOLOR); rDst.x = proc_ret->w - sf->w; rDst.y = 0; rDst.w = sf->w; rDst.h = proc_ret->h; SDL_BlitScaled(sf, NULL, proc_ret, &rDst); SDL_FreeSurface(sf); sf = proc_ret; proc_ret = bkup; _append(sf, basey, 0); i++; break; case '{': // 初始化及备份 { count = 0; start = i; if (tstr[0]) { if (isDigit(tstr[0])) sf = TTF_RenderUTF8_Blended(fontBig, tstr, NUMCOLOR); else sf = TTF_RenderUTF8_Blended(fontBig, tstr, VARCOLOR); basey = _append(sf, basey, 0); tstr[0] = 0; } bkup = proc_ret; // start for (;; i++) { if (str[i] == '{') count++; else if (str[i] == '}') { count--; if (!count) { break; } } } if (str[++i] == '^') type = 1; else type = 2; _proc(start + 1, i - 1, type == 1 ? 0 : 1, 0); f1 = proc_ret; i++; start = i; count = 0; for (;; i++) { if (str[i] == '{') count++; else if (str[i] == '}') { count--; if (!count) { break; } } } _proc(start + 1, i, 1, 0); f2 = proc_ret; if (type == 1) yt = _draw_power(f1, f2, 0); else yt = _draw_frac(f1, f2, 0); f2 = proc_ret; proc_ret = bkup; basey = _append(f2, basey, yt); } break; default: t = strlen(tstr); tstr[t] = str[i]; tstr[t + 1] = 0; break; } } if (tstr[0]) { if (isDigit(tstr[0])) sf = TTF_RenderUTF8_Blended(fontBig, tstr, NUMCOLOR); else sf = TTF_RenderUTF8_Blended(fontBig, tstr, VARCOLOR); basey = _append(sf, basey, 0); tstr[0] = 0; } }
int CVPParser::Parse(const char *str) { int i,iline = 0; bool inProgram = false; std::stringstream input(str); struct nvfx_src none = nvfx_src(nvfx_reg(NVFXSR_NONE,0)); while(!input.eof()) { char line[256]; opcode *opc = NULL; struct nvfx_insn *insn = NULL; input.getline(line,255); iline++; for(i=0; i<256; i++) { char c = line[i]; if(c=='\n' || c=='\r' || c==';') c = 0; if(c=='\t') c = ' '; line[i] = c; if(c==0) break; } if(line[0]=='#') { ParseComment(line); continue; } if(!inProgram) { if(strncmp(line,"!!VP2.0",7)==0) inProgram = true; else if(strncmp(line,"!!ARBvp1.0",10)==0) inProgram = true; continue; } char *label = NULL; char *col_ptr = NULL; char *opcode = NULL; char *ptr = line; if((col_ptr = strstr((char*)ptr,":"))!=NULL) { int j = 0; bool valid = true; while((ptr+j)<col_ptr) { if(j==0 && !(isLetter(ptr[j]) || ptr[j]=='_')) valid = false; if(!(isLetter(ptr[j]) || isDigit(ptr[j]) || ptr[j]=='_')) valid = false; j++; } if(valid) { label = strtok(ptr,":\x20"); ptr = col_ptr + 1; } } opcode = strtok(ptr," "); if(label) { jmpdst d; strcpy(d.ident,label); d.location = m_nInstructions; m_lIdent.push_back(d); } if(opcode) { char *param_str = SkipSpaces(strtok(NULL,"\0")); if(strcasecmp(opcode,"OPTION")==0) { if(strncasecmp(param_str,"NV_vertex_program3",18)==0) m_nOption |= NV_OPTION_VP3; continue; } else if(strcasecmp(opcode,"PARAM")==0) continue; else if(strcasecmp(opcode,"TEMP")==0) continue; else { opc = FindOpcode(opcode); insn = &m_pInstructions[m_nInstructions]; if(!opc) continue; InitInstruction(insn,opc->opcode); if(opc->opcode==OPCODE_END) { m_nInstructions++; break; } char *opc_ext = opcode + strlen(opc->mnemonic); if(m_nOption&(NV_OPTION_VP2|NV_OPTION_VP3)) { if(opc_ext[0]=='C') { insn->cc_update = TRUE; if(m_nOption&NV_OPTION_VP3 && (opc_ext[1]=='0' || opc_ext[1]=='1')) { switch(opc_ext[1]) { case '0': insn->cc_update_reg = 0; break; case '1': insn->cc_update_reg = 1; break; } opc_ext++; } opc_ext++; } } if(opc_ext[0]=='_') { if(strncasecmp(opc_ext,"_sat",4)==0) insn->sat = TRUE; } ParseInstruction(insn,opc,param_str); m_nInstructions++; } } } for(std::list<jmpdst>::iterator r=m_lJmpDst.begin(); r!=m_lJmpDst.end(); r++) { bool found = false; for(std::list<jmpdst>::iterator i=m_lIdent.begin(); i!=m_lIdent.end(); i++) { if(strcmp(r->ident,i->ident)==0) { found = true; m_pInstructions[r->location].dst = nvfx_reg(NVFXSR_RELOCATED,i->location); break; } } if(found==false) { fprintf(stderr,"Identifier \'%s\' not found.\n",r->ident); exit(EXIT_FAILURE); } } return 0; }
boost::tribool RequestParser::consume(Request &req, char input, http::CompressionType *compressionType) { switch (state_) { case method_start: if (!isChar(input) || isCTL(input) || isTSpecial(input)) { return false; } state_ = method; return boost::indeterminate; case method: if (input == ' ') { state_ = uri; return boost::indeterminate; } if (!isChar(input) || isCTL(input) || isTSpecial(input)) { return false; } return boost::indeterminate; case uri_start: if (isCTL(input)) { return false; } state_ = uri; req.uri.push_back(input); return boost::indeterminate; case uri: if (input == ' ') { state_ = http_version_h; return boost::indeterminate; } if (isCTL(input)) { return false; } req.uri.push_back(input); return boost::indeterminate; case http_version_h: if (input == 'H') { state_ = http_version_t_1; return boost::indeterminate; } return false; case http_version_t_1: if (input == 'T') { state_ = http_version_t_2; return boost::indeterminate; } return false; case http_version_t_2: if (input == 'T') { state_ = http_version_p; return boost::indeterminate; } return false; case http_version_p: if (input == 'P') { state_ = http_version_slash; return boost::indeterminate; } return false; case http_version_slash: if (input == '/') { state_ = http_version_major_start; return boost::indeterminate; } return false; case http_version_major_start: if (isDigit(input)) { state_ = http_version_major; return boost::indeterminate; } return false; case http_version_major: if (input == '.') { state_ = http_version_minor_start; return boost::indeterminate; } if (isDigit(input)) { return boost::indeterminate; } return false; case http_version_minor_start: if (isDigit(input)) { state_ = http_version_minor; return boost::indeterminate; } return false; case http_version_minor: if (input == '\r') { state_ = expecting_newline_1; return boost::indeterminate; } if (isDigit(input)) { return boost::indeterminate; } return false; case expecting_newline_1: if (input == '\n') { state_ = header_line_start; return boost::indeterminate; } return false; case header_line_start: if (header.name == "Accept-Encoding") { /* giving gzip precedence over deflate */ if (header.value.find("deflate") != std::string::npos) { *compressionType = deflateRFC1951; } if (header.value.find("gzip") != std::string::npos) { *compressionType = gzipRFC1952; } } if ("Referer" == header.name) { req.referrer = header.value; } if ("User-Agent" == header.name) { req.agent = header.value; } if (input == '\r') { state_ = expecting_newline_3; return boost::indeterminate; } if (!isChar(input) || isCTL(input) || isTSpecial(input)) { return false; } state_ = header_name; header.Clear(); header.name.push_back(input); return boost::indeterminate; case header_lws: if (input == '\r') { state_ = expecting_newline_2; return boost::indeterminate; } if (input == ' ' || input == '\t') { return boost::indeterminate; } if (isCTL(input)) { return false; } state_ = header_value; return boost::indeterminate; case header_name: if (input == ':') { state_ = space_before_header_value; return boost::indeterminate; } if (!isChar(input) || isCTL(input) || isTSpecial(input)) { return false; } header.name.push_back(input); return boost::indeterminate; case space_before_header_value: if (input == ' ') { state_ = header_value; return boost::indeterminate; } return false; case header_value: if (input == '\r') { state_ = expecting_newline_2; return boost::indeterminate; } if (isCTL(input)) { return false; } header.value.push_back(input); return boost::indeterminate; case expecting_newline_2: if (input == '\n') { state_ = header_line_start; return boost::indeterminate; } return false; case expecting_newline_3: return (input == '\n'); default: return false; } }
void lexAnalyze() { char ch; int n = 0; for (n = 0; n < 16; n++) token[n] = '\0'; category = 0; n = 0; ch = program[p]; p++;// p is the next while (ch == ' ') { ch = program[p++]; } if (isDigit(ch)) { // is digit while (isDigit(ch)) { token[n++] = ch; ch = program[p++]; } category = 11; p--; } else if (isLetter(ch)) { while (isDigit(ch) || isLetter(ch)) { token[n++] = ch; ch = program[p++]; } category = 10; // identify p--; // is keywords for (n = 0; n < 9; n++) { if (strcmp(token, keywords[n]) == 0) { category = n + 1;// keywords category id break; } } } else { switch (ch) { case '=': token[0] = '='; category = 12; break; case '<': ch = program[p]; if (ch == '=') { token[0] = '<'; token[1] = '='; category = 14; p++; } else if (ch == '>') { token[0] = '<'; token[1] = '>'; category = 13; p++; } else { token[0] = '<'; category = 15; } break; case '>': ch = program[p]; if (ch == '=') { token[0] = '>'; token[1] = '='; category = 16; p++; } else { token[0] = '>'; category = 17; } break; case '-': token[0] = '-'; category = 18; break; case '*': token[0] = '*'; category = 19; break; case ':': ch = program[p]; if (ch == '=') { token[0] = ':'; token[1] = '='; category = 20; p++; } else { // handle error category = -1; msg = "After \":\" should be \"=\""; } break; case '(': token[0] = '('; category = 21; break; case ')': token[0] = ')'; category = 22; break; case ';': token[0] = ';'; category = 23; break; case '\n': line++; token[0] = 'E'; token[1] = 'O'; token[2] = 'L'; token[3] = 'N'; category = 24; break; case '\0': break; default: // handle error category = -1; msg = "Invalid character"; break; } } }
bool SglExprLex::isAlphaNum() const { return isLetter() || isDigit(); }
char *ADVANCE_DIGITS(char *aux_p){ while(isDigit(*aux_p)) aux_p++; return aux_p; }
bool derpGetTokens( const std::string &str, std::vector<DerpToken*> &outTokens, DerpErrorState &errorState, const std::string &fileName) { unsigned int i = 0; unsigned int lineNumber = 1; while(i < str.size()) { // Skip over whitespace. while(i < str.size() && isWhitespace(str[i])) { if(str[i] == '\n') lineNumber++; i++; } if(i >= str.size()) break; // Figure out token type with a big ugly if/else thinger. if(str[i] == '/' && (i + 1) < str.size() && str[i+1] == '/') { // C++ style comment. Just throw it away. i += 2; while(i < str.size()) { if(str[i] == '\n') break; i++; } } else if(str[i] == '#') { // Shell-script style comment. Just throw it away too. i++; while(i < str.size()) { if(str[i] == '\n') break; i++; } } else if(str[i] == '\"') { // Found a literal quoted string. DerpToken *stringToken = parseString( str, i, fileName, lineNumber, errorState); if(!stringToken) { return false; } outTokens.push_back(stringToken); } else if(isDigit(str[i])) { // Found a number outTokens.push_back(parseNumber(str, i, fileName, lineNumber)); } else if(isValidSymbolChar(str[i], true)) { // Found either a symbol or a keyword. DerpToken *symbolToken = parseSymbolOrKeyword( str, i, fileName, lineNumber, errorState); if(!symbolToken) { return false; } outTokens.push_back(symbolToken); } else { // Found some special character. // TODO: Replace this with some table-based lookup. bool foundTwoCharacterOperator = false; // First check all the two-character operators. if(str.size() > (i + 1)) { char twoCharOp[3] = { str[i], str[i+1], 0 }; if(string(":=") == twoCharOp || string("&&") == twoCharOp || string("||") == twoCharOp || string("!=") == twoCharOp || string("==") == twoCharOp || string("++") == twoCharOp || string("--") == twoCharOp || string(">=") == twoCharOp || string("<=") == twoCharOp) { foundTwoCharacterOperator = true; outTokens.push_back(new DerpToken(twoCharOp, DERPTOKEN_MATHOP, fileName, lineNumber)); i += 2; } } // If it wasn't a two-character operator, try the // single-character operators. if(!foundTwoCharacterOperator) { switch(str[i]) { case '{': // Found an open curly. outTokens.push_back(new DerpToken("{", DERPTOKEN_OPENCURLY, fileName, lineNumber)); i++; break; case '}': // Found a closing curly. outTokens.push_back(new DerpToken("}", DERPTOKEN_CLOSECURLY, fileName, lineNumber)); i++; break; case '[': // Found an open curly. outTokens.push_back(new DerpToken("[", DERPTOKEN_OPENBRACKET, fileName, lineNumber)); i++; break; case ']': // Found a closing curly. outTokens.push_back(new DerpToken("]", DERPTOKEN_CLOSEBRACKET, fileName, lineNumber)); i++; break; case '(': // Found an open parenthesis. outTokens.push_back(new DerpToken("(", DERPTOKEN_OPENPAREN, fileName, lineNumber)); i++; break; case ')': // Found a closing parenthesis. outTokens.push_back(new DerpToken("(", DERPTOKEN_CLOSEPAREN, fileName, lineNumber)); i++; break; case ';': // End statement. outTokens.push_back(new DerpToken(";", DERPTOKEN_ENDSTATEMENT, fileName, lineNumber)); i++; break; case ',': outTokens.push_back(new DerpToken(",", DERPTOKEN_COMMA, fileName, lineNumber)); i++; break; case '+': case '-': case '*': case '/': case '!': case '=': case '<': case '>': case '.': // Found math operator. outTokens.push_back(new DerpToken(strFromChar(str[i]), DERPTOKEN_MATHOP, fileName, lineNumber)); i++; break; default: // I have no idea what to do with this. Toss an error and return. errorState.setFileAndLineDirect( fileName, lineNumber); errorState.addError( derpSprintf("Bad token: \"%c\"", str[i])); return false; } } } if(outTokens.size() > DERP_MAX_TOKENS) { errorState.setFileAndLineDirect( fileName, lineNumber); errorState.addError( "Exceeded maximum number of tokens."); return false; } } return true; }