Example #1
0
	static bool loopCond(ff::ptr<int> s)
	{
		return isDigit(ff::deref(s));
	};
Example #2
0
/*---------------------------------------------------------------------------
|   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);
}
Example #3
0
/**
 * 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);
}
Example #5
0
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 );
	}
Example #6
0
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;
		}
	}
}
Example #7
0
bool Tree::letCalc() {
    bool result = true;
    if (left && isDigit(left->value) && right && isDigit(right->value))
    return result;
}
Example #8
0
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);
}
Example #9
0
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;
}
Example #10
0
 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();
 }
Example #11
0
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);
}
Example #12
0
static inline int _atoi(const char **s){
    int i = 0;
    while(isDigit(**s)) i = i * 10 + *((*s)++) - '0';
    return i;
}
Example #13
0
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;
            }
        }
Example #14
0
 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(&current, 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(&current, 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;
         }
Example #15
0
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;
}
Example #16
0
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);
}
Example #17
0
bool isWordCharacter(char c)
{
	return isDigit(c)||isCapitalLetter(c)||isSmallLetter(c)||c=='-';
}
Example #18
0
bool Lexer::isValueLetter(char c)
{
	return c == '-' || c == '+' || c == '.' || isDigit(c) || isBooleanLetter(c);
}
Example #19
0
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*/)
Example #22
0
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;

}
Example #23
0
////////////////////////////////////////////////////////////////////////////////
// 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;
}
Example #24
0
File: zrsx3.c Project: djytw/Zept
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;
	}
}
Example #25
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;
}
Example #26
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;
    }
}
Example #27
0
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;
        }
    }
}
Example #28
0
bool SglExprLex::isAlphaNum() const
{
  return isLetter() || isDigit();
}
Example #29
0
char *ADVANCE_DIGITS(char *aux_p){

	while(isDigit(*aux_p))	aux_p++;
	return aux_p;
}
Example #30
0
    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;
    }