📄 l_precomp.c
字号:
for (t = tokens; t; t = t->next)
{
strncat(token->string, t->string, MAX_TOKEN - strlen(token->string));
} //end for
strncat(token->string, "\"", MAX_TOKEN - strlen(token->string));
return qtrue;
} //end of the function PC_StringizeTokens
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
int PC_MergeTokens(token_t *t1, token_t *t2)
{
//merging of a name with a name or number
if (t1->type == TT_NAME && (t2->type == TT_NAME || t2->type == TT_NUMBER))
{
strcat(t1->string, t2->string);
return qtrue;
} //end if
//merging of two strings
if (t1->type == TT_STRING && t2->type == TT_STRING)
{
//remove trailing double quote
t1->string[strlen(t1->string)-1] = '\0';
//concat without leading double quote
strcat(t1->string, &t2->string[1]);
return qtrue;
} //end if
//FIXME: merging of two number of the same sub type
return qfalse;
} //end of the function PC_MergeTokens
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
/*
void PC_PrintDefine(define_t *define)
{
printf("define->name = %s\n", define->name);
printf("define->flags = %d\n", define->flags);
printf("define->builtin = %d\n", define->builtin);
printf("define->numparms = %d\n", define->numparms);
// token_t *parms; //define parameters
// token_t *tokens; //macro tokens (possibly containing parm tokens)
// struct define_s *next; //next defined macro in a list
} //end of the function PC_PrintDefine*/
#if DEFINEHASHING
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
void PC_PrintDefineHashTable(define_t **definehash)
{
int i;
define_t *d;
for (i = 0; i < DEFINEHASHSIZE; i++)
{
Log_Write("%4d:", i);
for (d = definehash[i]; d; d = d->hashnext)
{
Log_Write(" %s", d->name);
} //end for
Log_Write("\n");
} //end for
} //end of the function PC_PrintDefineHashTable
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
//char primes[16] = {1, 3, 5, 7, 11, 13, 17, 19, 23, 27, 29, 31, 37, 41, 43, 47};
int PC_NameHash(char *name)
{
int register hash, i;
hash = 0;
for (i = 0; name[i] != '\0'; i++)
{
hash += name[i] * (119 + i);
//hash += (name[i] << 7) + i;
//hash += (name[i] << (i&15));
} //end while
hash = (hash ^ (hash >> 10) ^ (hash >> 20)) & (DEFINEHASHSIZE-1);
return hash;
} //end of the function PC_NameHash
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
void PC_AddDefineToHash(define_t *define, define_t **definehash)
{
int hash;
hash = PC_NameHash(define->name);
define->hashnext = definehash[hash];
definehash[hash] = define;
} //end of the function PC_AddDefineToHash
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
define_t *PC_FindHashedDefine(define_t **definehash, char *name)
{
define_t *d;
int hash;
hash = PC_NameHash(name);
for (d = definehash[hash]; d; d = d->hashnext)
{
if (!strcmp(d->name, name)) return d;
} //end for
return NULL;
} //end of the function PC_FindHashedDefine
#endif //DEFINEHASHING
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
define_t *PC_FindDefine(define_t *defines, char *name)
{
define_t *d;
for (d = defines; d; d = d->next)
{
if (!strcmp(d->name, name)) return d;
} //end for
return NULL;
} //end of the function PC_FindDefine
//============================================================================
//
// Parameter: -
// Returns: number of the parm
// if no parm found with the given name -1 is returned
// Changes Globals: -
//============================================================================
int PC_FindDefineParm(define_t *define, char *name)
{
token_t *p;
int i;
i = 0;
for (p = define->parms; p; p = p->next)
{
if (!strcmp(p->string, name)) return i;
i++;
} //end for
return -1;
} //end of the function PC_FindDefineParm
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
void PC_FreeDefine(define_t *define)
{
token_t *t, *next;
//free the define parameters
for (t = define->parms; t; t = next)
{
next = t->next;
PC_FreeToken(t);
} //end for
//free the define tokens
for (t = define->tokens; t; t = next)
{
next = t->next;
PC_FreeToken(t);
} //end for
//free the define
FreeMemory(define);
} //end of the function PC_FreeDefine
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
void PC_AddBuiltinDefines(source_t *source)
{
int i;
define_t *define;
struct builtin
{
char *string;
int builtin;
} builtin[] = { // bk001204 - brackets
{ "__LINE__", BUILTIN_LINE },
{ "__FILE__", BUILTIN_FILE },
{ "__DATE__", BUILTIN_DATE },
{ "__TIME__", BUILTIN_TIME },
// { "__STDC__", BUILTIN_STDC },
{ NULL, 0 }
};
for (i = 0; builtin[i].string; i++)
{
define = (define_t *) GetMemory(sizeof(define_t) + strlen(builtin[i].string) + 1);
Com_Memset(define, 0, sizeof(define_t));
define->name = (char *) define + sizeof(define_t);
strcpy(define->name, builtin[i].string);
define->flags |= DEFINE_FIXED;
define->builtin = builtin[i].builtin;
//add the define to the source
#if DEFINEHASHING
PC_AddDefineToHash(define, source->definehash);
#else
define->next = source->defines;
source->defines = define;
#endif //DEFINEHASHING
} //end for
} //end of the function PC_AddBuiltinDefines
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
int PC_ExpandBuiltinDefine(source_t *source, token_t *deftoken, define_t *define,
token_t **firsttoken, token_t **lasttoken)
{
token_t *token;
unsigned long t; // time_t t; //to prevent LCC warning
char *curtime;
token = PC_CopyToken(deftoken);
switch(define->builtin)
{
case BUILTIN_LINE:
{
sprintf(token->string, "%d", deftoken->line);
#ifdef NUMBERVALUE
token->intvalue = deftoken->line;
token->floatvalue = deftoken->line;
#endif //NUMBERVALUE
token->type = TT_NUMBER;
token->subtype = TT_DECIMAL | TT_INTEGER;
*firsttoken = token;
*lasttoken = token;
break;
} //end case
case BUILTIN_FILE:
{
strcpy(token->string, source->scriptstack->filename);
token->type = TT_NAME;
token->subtype = strlen(token->string);
*firsttoken = token;
*lasttoken = token;
break;
} //end case
case BUILTIN_DATE:
{
t = time(NULL);
curtime = ctime(&t);
strcpy(token->string, "\"");
strncat(token->string, curtime+4, 7);
strncat(token->string+7, curtime+20, 4);
strcat(token->string, "\"");
free(curtime);
token->type = TT_NAME;
token->subtype = strlen(token->string);
*firsttoken = token;
*lasttoken = token;
break;
} //end case
case BUILTIN_TIME:
{
t = time(NULL);
curtime = ctime(&t);
strcpy(token->string, "\"");
strncat(token->string, curtime+11, 8);
strcat(token->string, "\"");
free(curtime);
token->type = TT_NAME;
token->subtype = strlen(token->string);
*firsttoken = token;
*lasttoken = token;
break;
} //end case
case BUILTIN_STDC:
default:
{
*firsttoken = NULL;
*lasttoken = NULL;
break;
} //end case
} //end switch
return qtrue;
} //end of the function PC_ExpandBuiltinDefine
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
int PC_ExpandDefine(source_t *source, token_t *deftoken, define_t *define,
token_t **firsttoken, token_t **lasttoken)
{
token_t *parms[MAX_DEFINEPARMS], *dt, *pt, *t;
token_t *t1, *t2, *first, *last, *nextpt, token;
int parmnum, i;
//if it is a builtin define
if (define->builtin)
{
return PC_ExpandBuiltinDefine(source, deftoken, define, firsttoken, lasttoken);
} //end if
//if the define has parameters
if (define->numparms)
{
if (!PC_ReadDefineParms(source, define, parms, MAX_DEFINEPARMS)) return qfalse;
#ifdef DEBUG_EVAL
for (i = 0; i < define->numparms; i++)
{
Log_Write("define parms %d:", i);
for (pt = parms[i]; pt; pt = pt->next)
{
Log_Write("%s", pt->string);
} //end for
} //end for
#endif //DEBUG_EVAL
} //end if
//empty list at first
first = NULL;
last = NULL;
//create a list with tokens of the expanded define
for (dt = define->tokens; dt; dt = dt->next)
{
parmnum = -1;
//if the token is a name, it could be a define parameter
if (dt->type == TT_NAME)
{
parmnum = PC_FindDefineParm(define, dt->string);
} //end if
//if it is a define parameter
if (parmnum >= 0)
{
for (pt = parms[parmnum]; pt; pt = pt->next)
{
t = PC_CopyToken(pt);
//add the token to the list
t->next = NULL;
if (last) last->next = t;
else first = t;
last = t;
} //end for
} //end if
else
{
//if stringizing operator
if (dt->string[0] == '#' && dt->string[1] == '\0')
{
//the stringizing operator must be followed by a define parameter
if (dt->next) parmnum = PC_FindDefineParm(define, dt->next->string);
else parmnum = -1;
//
if (parmnum >= 0)
{
//step over the stringizing operator
dt = dt->next;
//stringize the define parameter tokens
if (!PC_StringizeTokens(parms[parmnum], &token))
{
SourceError(source, "can't stringize tokens");
return qfalse;
} //end if
t = PC_CopyToken(&token);
} //end if
else
{
SourceWarning(source, "stringizing operator without define parameter");
continue;
} //end if
} //end if
else
{
t = PC_CopyToken(dt);
} //end else
//add the token to the list
t->next = NULL;
if (last) last->next = t;
else first = t;
last = t;
} //end else
} //end for
//check for the merging operator
for (t = first; t; )
{
if (t->next)
{
//if the merging operator
if (t->next->string[0] == '#' && t->next->string[1] == '#')
{
t1 = t;
t2 = t->next->next;
if (t2)
{
if (!PC_MergeTokens(t1, t2))
{
SourceError(source, "can't merge %s with %s", t1->string, t2->string);
return qfalse;
} //end if
PC_FreeToken(t1->next);
t1->next = t2->next;
if (t2 == last) last = t1;
PC_FreeToken(t2);
continue;
} //end if
} //end if
} //end if
t = t->next;
} //end for
//store the first and last token of the list
*firsttoken = first;
*lasttoken = last;
//free all the parameter tokens
for (i = 0; i < define->numparms; i++)
{
for (pt = parms[i]; pt; pt = nextpt)
{
nextpt = pt->next;
PC_FreeToken(pt);
} //end for
} //end for
//
return qtrue;
} //end of the function PC_ExpandDefine
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
int PC_ExpandDefineIntoSource(source_t *source, token_t *deftoken, define_t *define)
{
token_t *firsttoken, *lasttoken;
if (!PC_ExpandDefine(source, deftoken, define, &firsttoken, &lasttoken)) return qfalse;
if (firsttoken && lasttoken)
{
lasttoken->next = source->tokens;
source->tokens = firsttoken;
return qtrue;
} //end if
return qfalse;
} //end of the function PC_ExpandDefineIntoSource
//============================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//============================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -