📄 l_precomp.c
字号:
// remove the given global define
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
int PC_RemoveGlobalDefine(char *name)
{
define_t *define;
define = PC_FindDefine(globaldefines, name);
if (define)
{
PC_FreeDefine(define);
return qtrue;
} //end if
return qfalse;
} //end of the function PC_RemoveGlobalDefine
//============================================================================
// remove all globals defines
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
void PC_RemoveAllGlobalDefines(void)
{
define_t *define;
for (define = globaldefines; define; define = globaldefines)
{
globaldefines = globaldefines->next;
PC_FreeDefine(define);
} //end for
} //end of the function PC_RemoveAllGlobalDefines
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
define_t *PC_CopyDefine(source_t *source, define_t *define)
{
define_t *newdefine;
token_t *token, *newtoken, *lasttoken;
newdefine = (define_t *) GetMemory(sizeof(define_t) + strlen(define->name) + 1);
//copy the define name
newdefine->name = (char *) newdefine + sizeof(define_t);
strcpy(newdefine->name, define->name);
newdefine->flags = define->flags;
newdefine->builtin = define->builtin;
newdefine->numparms = define->numparms;
//the define is not linked
newdefine->next = NULL;
newdefine->hashnext = NULL;
//copy the define tokens
newdefine->tokens = NULL;
for (lasttoken = NULL, token = define->tokens; token; token = token->next)
{
newtoken = PC_CopyToken(token);
newtoken->next = NULL;
if (lasttoken) lasttoken->next = newtoken;
else newdefine->tokens = newtoken;
lasttoken = newtoken;
} //end for
//copy the define parameters
newdefine->parms = NULL;
for (lasttoken = NULL, token = define->parms; token; token = token->next)
{
newtoken = PC_CopyToken(token);
newtoken->next = NULL;
if (lasttoken) lasttoken->next = newtoken;
else newdefine->parms = newtoken;
lasttoken = newtoken;
} //end for
return newdefine;
} //end of the function PC_CopyDefine
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
void PC_AddGlobalDefinesToSource(source_t *source)
{
define_t *define, *newdefine;
for (define = globaldefines; define; define = define->next)
{
newdefine = PC_CopyDefine(source, define);
#if DEFINEHASHING
PC_AddDefineToHash(newdefine, source->definehash);
#else //DEFINEHASHING
newdefine->next = source->defines;
source->defines = newdefine;
#endif //DEFINEHASHING
} //end for
} //end of the function PC_AddGlobalDefinesToSource
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
int PC_Directive_if_def(source_t *source, int type)
{
token_t token;
define_t *d;
int skip;
if (!PC_ReadLine(source, &token))
{
SourceError(source, "#ifdef without name");
return qfalse;
} //end if
if (token.type != TT_NAME)
{
PC_UnreadSourceToken(source, &token);
SourceError(source, "expected name after #ifdef, found %s", token.string);
return qfalse;
} //end if
#if DEFINEHASHING
d = PC_FindHashedDefine(source->definehash, token.string);
#else
d = PC_FindDefine(source->defines, token.string);
#endif //DEFINEHASHING
skip = (type == INDENT_IFDEF) == (d == NULL);
PC_PushIndent(source, type, skip);
return qtrue;
} //end of the function PC_Directiveif_def
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
int PC_Directive_ifdef(source_t *source)
{
return PC_Directive_if_def(source, INDENT_IFDEF);
} //end of the function PC_Directive_ifdef
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
int PC_Directive_ifndef(source_t *source)
{
return PC_Directive_if_def(source, INDENT_IFNDEF);
} //end of the function PC_Directive_ifndef
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
int PC_Directive_else(source_t *source)
{
int type, skip;
PC_PopIndent(source, &type, &skip);
if (!type)
{
SourceError(source, "misplaced #else");
return qfalse;
} //end if
if (type == INDENT_ELSE)
{
SourceError(source, "#else after #else");
return qfalse;
} //end if
PC_PushIndent(source, INDENT_ELSE, !skip);
return qtrue;
} //end of the function PC_Directive_else
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
int PC_Directive_endif(source_t *source)
{
int type, skip;
PC_PopIndent(source, &type, &skip);
if (!type)
{
SourceError(source, "misplaced #endif");
return qfalse;
} //end if
return qtrue;
} //end of the function PC_Directive_endif
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
typedef struct operator_s
{
int operator;
int priority;
int parentheses;
struct operator_s *prev, *next;
} operator_t;
typedef struct value_s
{
signed long int intvalue;
double floatvalue;
int parentheses;
struct value_s *prev, *next;
} value_t;
int PC_OperatorPriority(int op)
{
switch(op)
{
case P_MUL: return 15;
case P_DIV: return 15;
case P_MOD: return 15;
case P_ADD: return 14;
case P_SUB: return 14;
case P_LOGIC_AND: return 7;
case P_LOGIC_OR: return 6;
case P_LOGIC_GEQ: return 12;
case P_LOGIC_LEQ: return 12;
case P_LOGIC_EQ: return 11;
case P_LOGIC_UNEQ: return 11;
case P_LOGIC_NOT: return 16;
case P_LOGIC_GREATER: return 12;
case P_LOGIC_LESS: return 12;
case P_RSHIFT: return 13;
case P_LSHIFT: return 13;
case P_BIN_AND: return 10;
case P_BIN_OR: return 8;
case P_BIN_XOR: return 9;
case P_BIN_NOT: return 16;
case P_COLON: return 5;
case P_QUESTIONMARK: return 5;
} //end switch
return qfalse;
} //end of the function PC_OperatorPriority
//#define AllocValue() GetClearedMemory(sizeof(value_t));
//#define FreeValue(val) FreeMemory(val)
//#define AllocOperator(op) op = (operator_t *) GetClearedMemory(sizeof(operator_t));
//#define FreeOperator(op) FreeMemory(op);
#define MAX_VALUES 64
#define MAX_OPERATORS 64
#define AllocValue(val) \
if (numvalues >= MAX_VALUES) { \
SourceError(source, "out of value space\n"); \
error = 1; \
break; \
} \
else \
val = &value_heap[numvalues++];
#define FreeValue(val)
//
#define AllocOperator(op) \
if (numoperators >= MAX_OPERATORS) { \
SourceError(source, "out of operator space\n"); \
error = 1; \
break; \
} \
else \
op = &operator_heap[numoperators++];
#define FreeOperator(op)
int PC_EvaluateTokens(source_t *source, token_t *tokens, signed long int *intvalue,
double *floatvalue, int integer)
{
operator_t *o, *firstoperator, *lastoperator;
value_t *v, *firstvalue, *lastvalue, *v1, *v2;
token_t *t;
int brace = 0;
int parentheses = 0;
int error = 0;
int lastwasvalue = 0;
int negativevalue = 0;
int questmarkintvalue = 0;
double questmarkfloatvalue = 0;
int gotquestmarkvalue = qfalse;
int lastoperatortype = 0;
//
operator_t operator_heap[MAX_OPERATORS];
int numoperators = 0;
value_t value_heap[MAX_VALUES];
int numvalues = 0;
firstoperator = lastoperator = NULL;
firstvalue = lastvalue = NULL;
if (intvalue) *intvalue = 0;
if (floatvalue) *floatvalue = 0;
for (t = tokens; t; t = t->next)
{
switch(t->type)
{
case TT_NAME:
{
if (lastwasvalue || negativevalue)
{
SourceError(source, "syntax error in #if/#elif");
error = 1;
break;
} //end if
if (strcmp(t->string, "defined"))
{
SourceError(source, "undefined name %s in #if/#elif", t->string);
error = 1;
break;
} //end if
t = t->next;
if (!strcmp(t->string, "("))
{
brace = qtrue;
t = t->next;
} //end if
if (!t || t->type != TT_NAME)
{
SourceError(source, "defined without name in #if/#elif");
error = 1;
break;
} //end if
//v = (value_t *) GetClearedMemory(sizeof(value_t));
AllocValue(v);
#if DEFINEHASHING
if (PC_FindHashedDefine(source->definehash, t->string))
#else
if (PC_FindDefine(source->defines, t->string))
#endif //DEFINEHASHING
{
v->intvalue = 1;
v->floatvalue = 1;
} //end if
else
{
v->intvalue = 0;
v->floatvalue = 0;
} //end else
v->parentheses = parentheses;
v->next = NULL;
v->prev = lastvalue;
if (lastvalue) lastvalue->next = v;
else firstvalue = v;
lastvalue = v;
if (brace)
{
t = t->next;
if (!t || strcmp(t->string, ")"))
{
SourceError(source, "defined without ) in #if/#elif");
error = 1;
break;
} //end if
} //end if
brace = qfalse;
// defined() creates a value
lastwasvalue = 1;
break;
} //end case
case TT_NUMBER:
{
if (lastwasvalue)
{
SourceError(source, "syntax error in #if/#elif");
error = 1;
break;
} //end if
//v = (value_t *) GetClearedMemory(sizeof(value_t));
AllocValue(v);
if (negativevalue)
{
v->intvalue = - (signed int) t->intvalue;
v->floatvalue = - t->floatvalue;
} //end if
else
{
v->intvalue = t->intvalue;
v->floatvalue = t->floatvalue;
} //end else
v->parentheses = parentheses;
v->next = NULL;
v->prev = lastvalue;
if (lastvalue) lastvalue->next = v;
else firstvalue = v;
lastvalue = v;
//last token was a value
lastwasvalue = 1;
//
negativevalue = 0;
break;
} //end case
case TT_PUNCTUATION:
{
if (negativevalue)
{
SourceError(source, "misplaced minus sign in #if/#elif");
error = 1;
break;
} //end if
if (t->subtype == P_PARENTHESESOPEN)
{
parentheses++;
break;
} //end if
else if (t->subtype == P_PARENTHESESCLOSE)
{
parentheses--;
if (parentheses < 0)
{
SourceError(source, "too many ) in #if/#elsif");
error = 1;
} //end if
break;
} //end else if
//check for invalid operators on floating point values
if (!integer)
{
if (t->subtype == P_BIN_NOT || t->subtype == P_MOD ||
t->subtype == P_RSHIFT || t->subtype == P_LSHIFT ||
t->subtype == P_BIN_AND || t->subtype == P_BIN_OR ||
t->subtype == P_BIN_XOR)
{
SourceError(source, "illigal operator %s on floating point operands\n", t->string);
error = 1;
break;
} //end if
} //end if
switch(t->subtype)
{
case P_LOGIC_NOT:
case P_BIN_NOT:
{
if (lastwasvalue)
{
SourceError(source, "! or ~ after value in #if/#elif");
error = 1;
break;
} //end if
break;
} //end case
case P_INC:
case P_DEC:
{
SourceError(source, "++ or -- used in #if/#elif");
break;
} //end case
case P_SUB:
{
if (!lastwasvalue)
{
negativevalue = 1;
break;
} //end if
} //end case
case P_MUL:
case P_DIV:
case P_MOD:
case P_ADD:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -