📄 l_script.c
字号:
if (!PS_ReadWhiteSpace(script))
{
script->script_p = tmpscript_p;
script->line = tmpline;
break;
} //end if
//if there's no leading double qoute
if (*script->script_p != quote)
{
script->script_p = tmpscript_p;
script->line = tmpline;
break;
} //end if
//step over the new leading double quote
script->script_p++;
} //end if
else
{
if (*script->script_p == '\0')
{
token->string[len] = 0;
ScriptError(script, "missing trailing quote");
return 0;
} //end if
if (*script->script_p == '\n')
{
token->string[len] = 0;
ScriptError(script, "newline inside string %s", token->string);
return 0;
} //end if
token->string[len++] = *script->script_p++;
} //end else
} //end while
//trailing quote
token->string[len++] = quote;
//end string with a zero
token->string[len] = '\0';
//the sub type is the length of the string
token->subtype = len;
return 1;
} //end of the function PS_ReadString
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
int PS_ReadName(script_t *script, token_t *token)
{
int len = 0;
char c;
token->type = TT_NAME;
do
{
token->string[len++] = *script->script_p++;
if (len >= MAX_TOKEN)
{
ScriptError(script, "name longer than MAX_TOKEN = %d", MAX_TOKEN);
return 0;
} //end if
c = *script->script_p;
} while ((c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') ||
c == '_');
token->string[len] = '\0';
//the sub type is the length of the name
token->subtype = len;
return 1;
} //end of the function PS_ReadName
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
void NumberValue(char *string, int subtype, unsigned long int *intvalue,
long double *floatvalue)
{
unsigned long int dotfound = 0;
*intvalue = 0;
*floatvalue = 0;
//floating point number
if (subtype & TT_FLOAT)
{
while(*string)
{
if (*string == '.')
{
if (dotfound) return;
dotfound = 10;
string++;
} //end if
if (dotfound)
{
*floatvalue = *floatvalue + (long double) (*string - '0') /
(long double) dotfound;
dotfound *= 10;
} //end if
else
{
*floatvalue = *floatvalue * 10.0 + (long double) (*string - '0');
} //end else
string++;
} //end while
*intvalue = (unsigned long) *floatvalue;
} //end if
else if (subtype & TT_DECIMAL)
{
while(*string) *intvalue = *intvalue * 10 + (*string++ - '0');
*floatvalue = *intvalue;
} //end else if
else if (subtype & TT_HEX)
{
//step over the leading 0x or 0X
string += 2;
while(*string)
{
*intvalue <<= 4;
if (*string >= 'a' && *string <= 'f') *intvalue += *string - 'a' + 10;
else if (*string >= 'A' && *string <= 'F') *intvalue += *string - 'A' + 10;
else *intvalue += *string - '0';
string++;
} //end while
*floatvalue = *intvalue;
} //end else if
else if (subtype & TT_OCTAL)
{
//step over the first zero
string += 1;
while(*string) *intvalue = (*intvalue << 3) + (*string++ - '0');
*floatvalue = *intvalue;
} //end else if
else if (subtype & TT_BINARY)
{
//step over the leading 0b or 0B
string += 2;
while(*string) *intvalue = (*intvalue << 1) + (*string++ - '0');
*floatvalue = *intvalue;
} //end else if
} //end of the function NumberValue
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
int PS_ReadNumber(script_t *script, token_t *token)
{
int len = 0, i;
int octal, dot;
char c;
// unsigned long int intvalue = 0;
// long double floatvalue = 0;
token->type = TT_NUMBER;
//check for a hexadecimal number
if (*script->script_p == '0' &&
(*(script->script_p + 1) == 'x' ||
*(script->script_p + 1) == 'X'))
{
token->string[len++] = *script->script_p++;
token->string[len++] = *script->script_p++;
c = *script->script_p;
//hexadecimal
while((c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'f') ||
(c >= 'A' && c <= 'A'))
{
token->string[len++] = *script->script_p++;
if (len >= MAX_TOKEN)
{
ScriptError(script, "hexadecimal number longer than MAX_TOKEN = %d", MAX_TOKEN);
return 0;
} //end if
c = *script->script_p;
} //end while
token->subtype |= TT_HEX;
} //end if
#ifdef BINARYNUMBERS
//check for a binary number
else if (*script->script_p == '0' &&
(*(script->script_p + 1) == 'b' ||
*(script->script_p + 1) == 'B'))
{
token->string[len++] = *script->script_p++;
token->string[len++] = *script->script_p++;
c = *script->script_p;
//binary
while(c == '0' || c == '1')
{
token->string[len++] = *script->script_p++;
if (len >= MAX_TOKEN)
{
ScriptError(script, "binary number longer than MAX_TOKEN = %d", MAX_TOKEN);
return 0;
} //end if
c = *script->script_p;
} //end while
token->subtype |= TT_BINARY;
} //end if
#endif //BINARYNUMBERS
else //decimal or octal integer or floating point number
{
octal = qfalse;
dot = qfalse;
if (*script->script_p == '0') octal = qtrue;
while(1)
{
c = *script->script_p;
if (c == '.') dot = qtrue;
else if (c == '8' || c == '9') octal = qfalse;
else if (c < '0' || c > '9') break;
token->string[len++] = *script->script_p++;
if (len >= MAX_TOKEN - 1)
{
ScriptError(script, "number longer than MAX_TOKEN = %d", MAX_TOKEN);
return 0;
} //end if
} //end while
if (octal) token->subtype |= TT_OCTAL;
else token->subtype |= TT_DECIMAL;
if (dot) token->subtype |= TT_FLOAT;
} //end else
for (i = 0; i < 2; i++)
{
c = *script->script_p;
//check for a LONG number
if ( (c == 'l' || c == 'L') // bk001204 - brackets
&& !(token->subtype & TT_LONG))
{
script->script_p++;
token->subtype |= TT_LONG;
} //end if
//check for an UNSIGNED number
else if ( (c == 'u' || c == 'U') // bk001204 - brackets
&& !(token->subtype & (TT_UNSIGNED | TT_FLOAT)))
{
script->script_p++;
token->subtype |= TT_UNSIGNED;
} //end if
} //end for
token->string[len] = '\0';
#ifdef NUMBERVALUE
NumberValue(token->string, token->subtype, &token->intvalue, &token->floatvalue);
#endif //NUMBERVALUE
if (!(token->subtype & TT_FLOAT)) token->subtype |= TT_INTEGER;
return 1;
} //end of the function PS_ReadNumber
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
int PS_ReadLiteral(script_t *script, token_t *token)
{
token->type = TT_LITERAL;
//first quote
token->string[0] = *script->script_p++;
//check for end of file
if (!*script->script_p)
{
ScriptError(script, "end of file before trailing \'");
return 0;
} //end if
//if it is an escape character
if (*script->script_p == '\\')
{
if (!PS_ReadEscapeCharacter(script, &token->string[1])) return 0;
} //end if
else
{
token->string[1] = *script->script_p++;
} //end else
//check for trailing quote
if (*script->script_p != '\'')
{
ScriptWarning(script, "too many characters in literal, ignored");
while(*script->script_p &&
*script->script_p != '\'' &&
*script->script_p != '\n')
{
script->script_p++;
} //end while
if (*script->script_p == '\'') script->script_p++;
} //end if
//store the trailing quote
token->string[2] = *script->script_p++;
//store trailing zero to end the string
token->string[3] = '\0';
//the sub type is the integer literal value
token->subtype = token->string[1];
//
return 1;
} //end of the function PS_ReadLiteral
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
int PS_ReadPunctuation(script_t *script, token_t *token)
{
int len;
char *p;
punctuation_t *punc;
#ifdef PUNCTABLE
for (punc = script->punctuationtable[(unsigned int)*script->script_p]; punc; punc = punc->next)
{
#else
int i;
for (i = 0; script->punctuations[i].p; i++)
{
punc = &script->punctuations[i];
#endif //PUNCTABLE
p = punc->p;
len = strlen(p);
//if the script contains at least as much characters as the punctuation
if (script->script_p + len <= script->end_p)
{
//if the script contains the punctuation
if (!strncmp(script->script_p, p, len))
{
strncpy(token->string, p, MAX_TOKEN);
script->script_p += len;
token->type = TT_PUNCTUATION;
//sub type is the number of the punctuation
token->subtype = punc->n;
return 1;
} //end if
} //end if
} //end for
return 0;
} //end of the function PS_ReadPunctuation
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
int PS_ReadPrimitive(script_t *script, token_t *token)
{
int len;
len = 0;
while(*script->script_p > ' ' && *script->script_p != ';')
{
if (len >= MAX_TOKEN)
{
ScriptError(script, "primitive token longer than MAX_TOKEN = %d", MAX_TOKEN);
return 0;
} //end if
token->string[len++] = *script->script_p++;
} //end while
token->string[len] = 0;
//copy the token into the script structure
Com_Memcpy(&script->token, token, sizeof(token_t));
//primitive reading successfull
return 1;
} //end of the function PS_ReadPrimitive
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
int PS_ReadToken(script_t *script, token_t *token)
{
//if there is a token available (from UnreadToken)
if (script->tokenavailable)
{
script->tokenavailable = 0;
Com_Memcpy(token, &script->token, sizeof(token_t));
return 1;
} //end if
//save script pointer
script->lastscript_p = script->script_p;
//save line counter
script->lastline = script->line;
//clear the token stuff
Com_Memset(token, 0, sizeof(token_t));
//start of the white space
script->whitespace_p = script->script_p;
token->whitespace_p = script->script_p;
//read unusefull stuff
if (!PS_ReadWhiteSpace(script)) return 0;
//end of the white space
script->endwhitespace_p = script->script_p;
token->endwhitespace_p = script->script_p;
//line the token is on
token->line = script->line;
//number of lines crossed before token
token->linescrossed = script->line - script->lastline;
//if there is a leading double quote
if (*script->script_p == '\"')
{
if (!PS_ReadString(script, token, '\"')) return 0;
} //end if
//if an literal
else if (*script->script_p == '\'')
{
//if (!PS_ReadLiteral(script, token)) return 0;
if (!PS_ReadString(script, token, '\'')) return 0;
} //end if
//if there is a number
else if ((*script->script_p >= '0' && *script->script_p <= '9') ||
(*script->script_p == '.' &&
(*(script->script_p + 1) >= '0' && *(script->script_p + 1) <= '9')))
{
if (!PS_ReadNumber(script, token)) return 0;
} //end if
//if this is a primitive script
else if (script->flags & SCFL_PRIMITIVE)
{
return PS_ReadPrimitive(script, token);
} //end else if
//if there is a name
else if ((*script->script_p >= 'a' && *script->script_p <= 'z') ||
(*script->script_p >= 'A' && *script->script_p <= 'Z') ||
*script->script_p == '_')
{
if (!PS_ReadName(script, token)) return 0;
} //end if
//check for punctuations
else if (!PS_ReadPunctuation(script, token))
{
ScriptError(script, "can't read token");
return 0;
} //end if
//copy the token into the script structure
Com_Memcpy(&script->token, token, sizeof(token_t));
//succesfully read a token
return 1;
} //end of the function PS_ReadToken
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
int PS_ExpectTokenString(script_t *script, char *string)
{
token_t token;
if (!PS_ReadToken(script, &token))
{
ScriptError(script, "couldn't find expected %s", string);
return 0;
} //end if
if (strcmp(token.string, string))
{
ScriptError(script, "expected %s, found %s", string, token.string);
return 0;
} //end if
return 1;
} //end of the function PS_ExpectToken
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
int PS_ExpectTokenType(script_t *script, int type, int subtype, token_t *token)
{
char str[MAX_TOKEN];
if (!PS_ReadToken(script, token))
{
ScriptError(script, "couldn't read expected token");
return 0;
} //end if
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -