static int get_token(const char* string, int startIndex, const char* separators, int* output_index, int* token_start, int* token_length) { int past_token; int sep_pos; *token_start = ModelicaStrings_skipWhiteSpace(string, startIndex); /* Index of first char of token, after ws. */ past_token = SkipNonWhiteSpaceSeparator(string, *token_start, separators); /* Index of first char after token, ws or separator. */ sep_pos = ModelicaStrings_skipWhiteSpace(string, past_token); /* Index of first char after ws after token, maybe a separator. */ *output_index = InSet(string, sep_pos, separators) ? sep_pos + 1 : sep_pos; /* Skip any separator. */ *token_length = past_token-*token_start; if (*token_length == 0 || *token_length > MAX_TOKEN_SIZE) { /* Token missing or too long. */ *output_index = startIndex; return 0; /* error */ } return 1; /* ok */ }
void ModelicaStrings_scanIdentifier(_In_z_ const char* string, int startIndex, _Out_ int* nextIndex, _Out_ const char** identifier) { int token_start = ModelicaStrings_skipWhiteSpace(string, startIndex); /* Index of first char of token, after ws. */ if (isalpha((unsigned char)string[token_start-1])) { /* Identifier has begun. */ int token_length = 1; while (string[token_start+token_length-1] != '\0' && (isalpha((unsigned char)string[token_start+token_length-1]) || isdigit((unsigned char)string[token_start+token_length-1]) || string[token_start+token_length-1] == '_')) { ++token_length; } { char* s = ModelicaAllocateString((size_t)token_length); strncpy(s, string+token_start-1, (size_t)token_length); s[token_length] = '\0'; *nextIndex = token_start + token_length; *identifier = s; return; } } /* Token missing or not identifier. */ *nextIndex = startIndex; *identifier = ModelicaAllocateString(0); return; }
void ModelicaStrings_scanInteger(const char* string, int startIndex, int unsignedNumber, int* nextIndex, int* integerNumber) { int number_length=0; int sign = 0; /* Number of characters used for sign. */ int token_start = ModelicaStrings_skipWhiteSpace(string, startIndex); /* Index of first char of token, after ws. */ if (string[token_start-1] == '+' || string[token_start-1] == '-') sign = 1; if (unsignedNumber==0 || (unsignedNumber==1 && sign==0)) { number_length = MatchUnsignedInteger(string, token_start + sign); /* Number of characters in unsigned number. */ if (number_length > 0 && sign + number_length < MAX_TOKEN_SIZE) { /* check if the scanned string is no Real number */ int next = token_start + sign + number_length - 1; if ( string[next] == '\0' || (string[next] != '\0' && string[next] != '.' && string[next] != 'e' && string[next] != 'E') ) { /* get Integer value */ char buf[MAX_TOKEN_SIZE+1]; int x; strncpy(buf, string+token_start-1, sign + number_length); buf[sign + number_length] = '\0'; #if !defined(NO_FILE_SYSTEM) if (sscanf(buf, "%d", &x) == 1) { *integerNumber = x; *nextIndex = token_start + sign + number_length; return; } #endif } else { ++number_length; } } } /* Token missing or cannot be converted to result type. */ *nextIndex = startIndex; *integerNumber = 0; return; }
void ModelicaStrings_scanString(_In_z_ const char* string, int startIndex, _Out_ int* nextIndex, _Out_ const char** result) { int i, token_start, past_token, token_length; token_length = 0; token_start = ModelicaStrings_skipWhiteSpace(string, startIndex); i = token_start; if (string[token_start-1] != '"') { goto Modelica_ERROR; } /* Index of first char of token, after ws. */ ++i; while (1) { if (string[i-1] == '\0') { goto Modelica_ERROR; } if (string[i-2] == '\\' && string[i-1] == '"') ; /* escaped quote, consume */ else if (string[i-1] == '"') { break; /* end quote */ } ++i; } past_token = i + 1; /* Index of first char after token, ws or separator. */ token_length = past_token-token_start-2; if (token_length > 0) { char* s = ModelicaAllocateString((size_t)token_length); strncpy(s, string+token_start, (size_t)token_length); s[token_length] = '\0'; *result = s; *nextIndex = past_token; return; } Modelica_ERROR: *result = ModelicaAllocateString(0); *nextIndex = startIndex; return; }
void ModelicaStrings_scanReal(_In_z_ const char* string, int startIndex, int unsignedNumber, _Out_ int* nextIndex, _Out_ double* number) { /* Grammar of real number: real ::= [sign] unsigned [fraction] [exponent] sign ::= '+' | '-' unsigned ::= digit [unsigned] fraction ::= '.' [unsigned] exponent ::= ('e' | 'E') [sign] unsigned digit ::= '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9' */ int len = 0; /* Temporary variable for the length of a matched unsigned number. */ int total_length = 0; /* Total number of characters recognized as part of a decimal number. */ int token_start = ModelicaStrings_skipWhiteSpace(string, startIndex); /* Index of first char of token, after ws. */ int exp_len = 0; /* Total number of characters recognized as part of the non-numeric parts * of exponent (the 'e' and the sign). */ /* Scan sign of decimal number */ if (string[token_start-1] == '+' || string[token_start-1] == '-') { total_length = 1; if (unsignedNumber == 1) { goto Modelica_ERROR; } } /* Scan integer part of mantissa. */ len = MatchUnsignedInteger(string, token_start + total_length); total_length += len; /* Scan decimal part of mantissa. */ if (string[token_start + total_length-1] == '.') { total_length += 1; len = MatchUnsignedInteger(string, token_start + total_length); if (len > 0) { total_length += len; } } /* Scan exponent part of mantissa. */ if (string[token_start + total_length-1] == 'e' || string[token_start + total_length-1] == 'E') { /* total_length += 1; */ exp_len = 1; if (string[token_start + total_length] == '+' || string[token_start + total_length] == '-') { exp_len += 1; } len = MatchUnsignedInteger(string, token_start + total_length + exp_len); if (len == 0) { goto Modelica_ERROR; } total_length += exp_len + len; } /* Convert accumulated characters into a number. */ if (total_length > 0 && total_length < MAX_TOKEN_SIZE) { #if defined(NO_LOCALE) const char* const dec = "."; #elif defined(_MSC_VER) && _MSC_VER >= 1400 _locale_t loc = _create_locale(LC_NUMERIC, "C"); #elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3) locale_t loc = newlocale(LC_NUMERIC, "C", NULL); #else char* dec = localeconv()->decimal_point; #endif char buf[MAX_TOKEN_SIZE+1]; /* Buffer for copying the part recognized as the number for passing to strtod(). */ char* endptr; /* For error checking of strtod(). */ double x; /* For receiving the result. */ strncpy(buf, string+token_start-1, (size_t)total_length); buf[total_length] = '\0'; #if !defined(NO_LOCALE) && (defined(_MSC_VER) && _MSC_VER >= 1400) x = _strtod_l(buf, &endptr, loc); _free_locale(loc); #elif !defined(NO_LOCALE) && (defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3)) x = strtod_l(buf, &endptr, loc); freelocale(loc); #else if (*dec == '.') { x = strtod(buf, &endptr); } else if (NULL == strchr(buf, '.')) { x = strtod(buf, &endptr); } else { char* p = strchr(buf, '.'); *p = *dec; x = strtod(buf, &endptr); } #endif if (*endptr == 0) { *number = x; *nextIndex = token_start + total_length; return; } } /* Token missing or cannot be converted to result type. */ Modelica_ERROR: *nextIndex = startIndex; *number = 0; return; }
void ModelicaStrings_scanInteger(_In_z_ const char* string, int startIndex, int unsignedNumber, _Out_ int* nextIndex, _Out_ int* integerNumber) { int sign = 0; /* Number of characters used for sign. */ int token_start = ModelicaStrings_skipWhiteSpace(string, startIndex); /* Index of first char of token, after ws. */ if (string[token_start-1] == '+' || string[token_start-1] == '-') { sign = 1; } if (unsignedNumber==0 || (unsignedNumber==1 && sign==0)) { int number_length = MatchUnsignedInteger(string, token_start + sign); /* Number of characters in unsigned number. */ if (number_length > 0 && sign + number_length < MAX_TOKEN_SIZE) { /* check if the scanned string is no Real number */ int next = token_start + sign + number_length - 1; if ( string[next] == '\0' || (string[next] != '.' && string[next] != 'e' && string[next] != 'E') ) { #if defined(NO_LOCALE) #elif defined(_MSC_VER) && _MSC_VER >= 1400 _locale_t loc = _create_locale(LC_NUMERIC, "C"); #elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3) locale_t loc = newlocale(LC_NUMERIC, "C", NULL); #endif char buf[MAX_TOKEN_SIZE+1]; /* Buffer for copying the part recognized as the number for passing to strtol(). */ char* endptr; /* For error checking of strtol(). */ int x; /* For receiving the result. */ strncpy(buf, string+token_start-1, (size_t)(sign + number_length)); buf[sign + number_length] = '\0'; #if !defined(NO_LOCALE) && (defined(_MSC_VER) && _MSC_VER >= 1400) x = (int)_strtol_l(buf, &endptr, 10, loc); _free_locale(loc); #elif !defined(NO_LOCALE) && (defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3)) x = (int)strtol_l(buf, &endptr, 10, loc); freelocale(loc); #else x = (int)strtol(buf, &endptr, 10); #endif if (*endptr == 0) { *integerNumber = x; *nextIndex = token_start + sign + number_length; return; } } } } /* Token missing or cannot be converted to result type. */ *nextIndex = startIndex; *integerNumber = 0; return; }
void ModelicaStrings_scanReal(const char* string, int startIndex, int unsignedNumber, int* nextIndex, double* number) { /* Grammar of real number: real ::= [sign] unsigned [fraction] [exponent] sign ::= '+' | '-' unsigned ::= digit [unsigned] fraction ::= '.' [unsigned] exponent ::= ('e' | 'E') [sign] unsigned digit ::= '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9' */ int len = 0; /* Temporary variable for the length of a matched unsigned number. */ int total_length = 0; /* Total number of characters recognized as part of a decimal number. */ int token_start = ModelicaStrings_skipWhiteSpace(string, startIndex); /* Index of first char of token, after ws. */ int exp_len = 0; /* Total number of characters recognized as part of the non-numeric parts * of exponent (the 'e' and the sign). */ char buf[MAX_TOKEN_SIZE+1]; /* Buffer for copying the part recognized as the number for passing to sscanf(). */ double x; /* For receiving the result. */ /* Scan sign of decimal number */ if (string[token_start-1] == '+' || string[token_start-1] == '-') { total_length = 1; if (unsignedNumber==1) goto error; } /* Scan integer part of mantissa. */ len = MatchUnsignedInteger(string, token_start + total_length); total_length += len; /* Scan decimal part of mantissa. */ if (string[token_start + total_length-1] == '.') { total_length += 1; len = MatchUnsignedInteger(string, token_start + total_length); if (len > 0) { total_length += len; } } /* Scan exponent part of mantissa. */ if (string[token_start + total_length-1] == 'e' || string[token_start + total_length-1] == 'E') { /* total_length += 1; */ exp_len = 1; if (string[token_start + total_length] == '+' || string[token_start + total_length] == '-') { exp_len += 1; } len = MatchUnsignedInteger(string, token_start + total_length + exp_len); if (len == 0) goto error; total_length += exp_len + len; } /* Convert accumulated characters into a number. */ if (total_length > 0 && total_length < MAX_TOKEN_SIZE) { strncpy(buf, string+token_start-1, total_length); buf[total_length] = '\0'; #if !defined(NO_FILE_SYSTEM) if (sscanf(buf, "%lg", &x) == 1) { *number = x; *nextIndex = token_start + total_length; return; } #endif } /* Token missing or cannot be converted to result type. */ error: *nextIndex = startIndex; *number = 0; return; }