⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 l_precomp.c

📁 quakeIII源码这个不用我多说吧
💻 C
📖 第 1 页 / 共 5 页
字号:
void PC_ConvertPath(char *path)
{
	char *ptr;

	//remove double path seperators
	for (ptr = path; *ptr;)
	{
		if ((*ptr == '\\' || *ptr == '/') &&
				(*(ptr+1) == '\\' || *(ptr+1) == '/'))
		{
			strcpy(ptr, ptr+1);
		} //end if
		else
		{
			ptr++;
		} //end else
	} //end while
	//set OS dependent path seperators
	for (ptr = path; *ptr;)
	{
		if (*ptr == '/' || *ptr == '\\') *ptr = PATHSEPERATOR_CHAR;
		ptr++;
	} //end while
} //end of the function PC_ConvertPath
//============================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//============================================================================
int PC_Directive_include(source_t *source)
{
	script_t *script;
	token_t token;
	char path[MAX_PATH];
#ifdef QUAKE
	foundfile_t file;
#endif //QUAKE

	if (source->skip > 0) return qtrue;
	//
	if (!PC_ReadSourceToken(source, &token))
	{
		SourceError(source, "#include without file name");
		return qfalse;
	} //end if
	if (token.linescrossed > 0)
	{
		SourceError(source, "#include without file name");
		return qfalse;
	} //end if
	if (token.type == TT_STRING)
	{
		StripDoubleQuotes(token.string);
		PC_ConvertPath(token.string);
		script = LoadScriptFile(token.string);
		if (!script)
		{
			strcpy(path, source->includepath);
			strcat(path, token.string);
			script = LoadScriptFile(path);
		} //end if
	} //end if
	else if (token.type == TT_PUNCTUATION && *token.string == '<')
	{
		strcpy(path, source->includepath);
		while(PC_ReadSourceToken(source, &token))
		{
			if (token.linescrossed > 0)
			{
				PC_UnreadSourceToken(source, &token);
				break;
			} //end if
			if (token.type == TT_PUNCTUATION && *token.string == '>') break;
			strncat(path, token.string, MAX_PATH);
		} //end while
		if (*token.string != '>')
		{
			SourceWarning(source, "#include missing trailing >");
		} //end if
		if (!strlen(path))
		{
			SourceError(source, "#include without file name between < >");
			return qfalse;
		} //end if
		PC_ConvertPath(path);
		script = LoadScriptFile(path);
	} //end if
	else
	{
		SourceError(source, "#include without file name");
		return qfalse;
	} //end else
#ifdef QUAKE
	if (!script)
	{
		Com_Memset(&file, 0, sizeof(foundfile_t));
		script = LoadScriptFile(path);
		if (script) strncpy(script->filename, path, MAX_PATH);
	} //end if
#endif //QUAKE
	if (!script)
	{
#ifdef SCREWUP
		SourceWarning(source, "file %s not found", path);
		return qtrue;
#else
		SourceError(source, "file %s not found", path);
		return qfalse;
#endif //SCREWUP
	} //end if
	PC_PushScript(source, script);
	return qtrue;
} //end of the function PC_Directive_include
//============================================================================
// reads a token from the current line, continues reading on the next
// line only if a backslash '\' is encountered.
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//============================================================================
int PC_ReadLine(source_t *source, token_t *token)
{
	int crossline;

	crossline = 0;
	do
	{
		if (!PC_ReadSourceToken(source, token)) return qfalse;
		
		if (token->linescrossed > crossline)
		{
			PC_UnreadSourceToken(source, token);
			return qfalse;
		} //end if
		crossline = 1;
	} while(!strcmp(token->string, "\\"));
	return qtrue;
} //end of the function PC_ReadLine
//============================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//============================================================================
int PC_WhiteSpaceBeforeToken(token_t *token)
{
	return token->endwhitespace_p - token->whitespace_p > 0;
} //end of the function PC_WhiteSpaceBeforeToken
//============================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//============================================================================
void PC_ClearTokenWhiteSpace(token_t *token)
{
	token->whitespace_p = NULL;
	token->endwhitespace_p = NULL;
	token->linescrossed = 0;
} //end of the function PC_ClearTokenWhiteSpace
//============================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//============================================================================
int PC_Directive_undef(source_t *source)
{
	token_t token;
	define_t *define, *lastdefine;
	int hash;

	if (source->skip > 0) return qtrue;
	//
	if (!PC_ReadLine(source, &token))
	{
		SourceError(source, "undef without name");
		return qfalse;
	} //end if
	if (token.type != TT_NAME)
	{
		PC_UnreadSourceToken(source, &token);
		SourceError(source, "expected name, found %s", token.string);
		return qfalse;
	} //end if
#if DEFINEHASHING

	hash = PC_NameHash(token.string);
	for (lastdefine = NULL, define = source->definehash[hash]; define; define = define->hashnext)
	{
		if (!strcmp(define->name, token.string))
		{
			if (define->flags & DEFINE_FIXED)
			{
				SourceWarning(source, "can't undef %s", token.string);
			} //end if
			else
			{
				if (lastdefine) lastdefine->hashnext = define->hashnext;
				else source->definehash[hash] = define->hashnext;
				PC_FreeDefine(define);
			} //end else
			break;
		} //end if
		lastdefine = define;
	} //end for
#else //DEFINEHASHING
	for (lastdefine = NULL, define = source->defines; define; define = define->next)
	{
		if (!strcmp(define->name, token.string))
		{
			if (define->flags & DEFINE_FIXED)
			{
				SourceWarning(source, "can't undef %s", token.string);
			} //end if
			else
			{
				if (lastdefine) lastdefine->next = define->next;
				else source->defines = define->next;
				PC_FreeDefine(define);
			} //end else
			break;
		} //end if
		lastdefine = define;
	} //end for
#endif //DEFINEHASHING
	return qtrue;
} //end of the function PC_Directive_undef
//============================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//============================================================================
int PC_Directive_define(source_t *source)
{
	token_t token, *t, *last;
	define_t *define;

	if (source->skip > 0) return qtrue;
	//
	if (!PC_ReadLine(source, &token))
	{
		SourceError(source, "#define without name");
		return qfalse;
	} //end if
	if (token.type != TT_NAME)
	{
		PC_UnreadSourceToken(source, &token);
		SourceError(source, "expected name after #define, found %s", token.string);
		return qfalse;
	} //end if
	//check if the define already exists
#if DEFINEHASHING
	define = PC_FindHashedDefine(source->definehash, token.string);
#else
	define = PC_FindDefine(source->defines, token.string);
#endif //DEFINEHASHING
	if (define)
	{
		if (define->flags & DEFINE_FIXED)
		{
			SourceError(source, "can't redefine %s", token.string);
			return qfalse;
		} //end if
		SourceWarning(source, "redefinition of %s", token.string);
		//unread the define name before executing the #undef directive
		PC_UnreadSourceToken(source, &token);
		if (!PC_Directive_undef(source)) return qfalse;
		//if the define was not removed (define->flags & DEFINE_FIXED)
#if DEFINEHASHING
		define = PC_FindHashedDefine(source->definehash, token.string);
#else
		define = PC_FindDefine(source->defines, token.string);
#endif //DEFINEHASHING
	} //end if
	//allocate define
	define = (define_t *) GetMemory(sizeof(define_t) + strlen(token.string) + 1);
	Com_Memset(define, 0, sizeof(define_t));
	define->name = (char *) define + sizeof(define_t);
	strcpy(define->name, token.string);
	//add the define to the source
#if DEFINEHASHING
	PC_AddDefineToHash(define, source->definehash);
#else //DEFINEHASHING
	define->next = source->defines;
	source->defines = define;
#endif //DEFINEHASHING
	//if nothing is defined, just return
	if (!PC_ReadLine(source, &token)) return qtrue;
	//if it is a define with parameters
	if (!PC_WhiteSpaceBeforeToken(&token) && !strcmp(token.string, "("))
	{
		//read the define parameters
		last = NULL;
		if (!PC_CheckTokenString(source, ")"))
		{
			while(1)
			{
				if (!PC_ReadLine(source, &token))
				{
					SourceError(source, "expected define parameter");
					return qfalse;
				} //end if
				//if it isn't a name
				if (token.type != TT_NAME)
				{
					SourceError(source, "invalid define parameter");
					return qfalse;
				} //end if
				//
				if (PC_FindDefineParm(define, token.string) >= 0)
				{
					SourceError(source, "two the same define parameters");
					return qfalse;
				} //end if
				//add the define parm
				t = PC_CopyToken(&token);
				PC_ClearTokenWhiteSpace(t);
				t->next = NULL;
				if (last) last->next = t;
				else define->parms = t;
				last = t;
				define->numparms++;
				//read next token
				if (!PC_ReadLine(source, &token))
				{
					SourceError(source, "define parameters not terminated");
					return qfalse;
				} //end if
				//
				if (!strcmp(token.string, ")")) break;
				//then it must be a comma
				if (strcmp(token.string, ","))
				{
					SourceError(source, "define not terminated");
					return qfalse;
				} //end if
			} //end while
		} //end if
		if (!PC_ReadLine(source, &token)) return qtrue;
	} //end if
	//read the defined stuff
	last = NULL;
	do
	{
		t = PC_CopyToken(&token);
		if (t->type == TT_NAME && !strcmp(t->string, define->name))
		{
			SourceError(source, "recursive define (removed recursion)");
			continue;
		} //end if
		PC_ClearTokenWhiteSpace(t);
		t->next = NULL;
		if (last) last->next = t;
		else define->tokens = t;
		last = t;
	} while(PC_ReadLine(source, &token));
	//
	if (last)
	{
		//check for merge operators at the beginning or end
		if (!strcmp(define->tokens->string, "##") ||
				!strcmp(last->string, "##"))
		{
			SourceError(source, "define with misplaced ##");
			return qfalse;
		} //end if
	} //end if
	return qtrue;
} //end of the function PC_Directive_define
//============================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//============================================================================
define_t *PC_DefineFromString(char *string)
{
	script_t *script;
	source_t src;
	token_t *t;
	int res, i;
	define_t *def;

	PC_InitTokenHeap();

	script = LoadScriptMemory(string, strlen(string), "*extern");
	//create a new source
	Com_Memset(&src, 0, sizeof(source_t));
	strncpy(src.filename, "*extern", MAX_PATH);
	src.scriptstack = script;
#if DEFINEHASHING
	src.definehash = GetClearedMemory(DEFINEHASHSIZE * sizeof(define_t *));
#endif //DEFINEHASHING
	//create a define from the source
	res = PC_Directive_define(&src);
	//free any tokens if left
	for (t = src.tokens; t; t = src.tokens)
	{
		src.tokens = src.tokens->next;
		PC_FreeToken(t);
	} //end for
#ifdef DEFINEHASHING
	def = NULL;
	for (i = 0; i < DEFINEHASHSIZE; i++)
	{
		if (src.definehash[i])
		{
			def = src.definehash[i];
			break;
		} //end if
	} //end for
#else
	def = src.defines;
#endif //DEFINEHASHING
	//
#if DEFINEHASHING
	FreeMemory(src.definehash);
#endif //DEFINEHASHING
	//
	FreeScript(script);
	//if the define was created succesfully
	if (res > 0) return def;
	//free the define is created
	if (src.defines) PC_FreeDefine(def);
	//
	return NULL;
} //end of the function PC_DefineFromString
//============================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//============================================================================
int PC_AddDefine(source_t *source, char *string)
{
	define_t *define;

	define = PC_DefineFromString(string);
	if (!define) return qfalse;
#if DEFINEHASHING
	PC_AddDefineToHash(define, source->definehash);
#else //DEFINEHASHING
	define->next = source->defines;
	source->defines = define;
#endif //DEFINEHASHING
	return qtrue;
} //end of the function PC_AddDefine
//============================================================================
// add a globals define that will be added to all opened sources
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//============================================================================
int PC_AddGlobalDefine(char *string)
{
	define_t *define;

	define = PC_DefineFromString(string);
	if (!define) return qfalse;
	define->next = globaldefines;
	globaldefines = define;
	return qtrue;
} //end of the function PC_AddGlobalDefine
//============================================================================

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -