halflife-photomode/utils/common/scriplib.cpp

265 lines
4.7 KiB
C++

/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// scriplib.c
#include "cmdlib.h"
#include "scriplib.h"
/*
=============================================================================
PARSING STUFF
=============================================================================
*/
typedef struct
{
char filename[1024];
char *buffer, *script_p, *end_p;
int line;
} script_t;
#define MAX_INCLUDES 8
script_t scriptstack[MAX_INCLUDES];
script_t* script;
int scriptline;
char token[MAXTOKEN];
qboolean endofscript;
qboolean tokenready; // only true if UnGetToken was just called
/*
==============
AddScriptToStack
==============
*/
void AddScriptToStack(char* filename)
{
int size;
script++;
if (script == &scriptstack[MAX_INCLUDES])
Error("script file exceeded MAX_INCLUDES");
strcpy(script->filename, ExpandPath(filename));
size = LoadFile(script->filename, (void**)&script->buffer);
printf("entering %s\n", script->filename);
script->line = 1;
script->script_p = script->buffer;
script->end_p = script->buffer + size;
}
/*
==============
LoadScriptFile
==============
*/
void LoadScriptFile(char* filename)
{
script = scriptstack;
AddScriptToStack(filename);
endofscript = false;
tokenready = false;
}
/*
==============
ParseFromMemory
==============
*/
void ParseFromMemory(char* buffer, int size)
{
script = scriptstack;
script++;
if (script == &scriptstack[MAX_INCLUDES])
Error("script file exceeded MAX_INCLUDES");
strcpy(script->filename, "memory buffer");
script->buffer = buffer;
script->line = 1;
script->script_p = script->buffer;
script->end_p = script->buffer + size;
endofscript = false;
tokenready = false;
}
/*
==============
UnGetToken
Signals that the current token was not used, and should be reported
for the next GetToken. Note that
GetToken (true);
UnGetToken ();
GetToken (false);
could cross a line boundary.
==============
*/
void UnGetToken(void)
{
tokenready = true;
}
qboolean EndOfScript(qboolean crossline)
{
if (!crossline)
Error("Line %i is incomplete\n", scriptline);
if (!strcmp(script->filename, "memory buffer"))
{
endofscript = true;
return false;
}
free(script->buffer);
if (script == scriptstack + 1)
{
endofscript = true;
return false;
}
script--;
scriptline = script->line;
printf("returning to %s\n", script->filename);
return GetToken(crossline);
}
/*
==============
GetToken
==============
*/
qboolean GetToken(qboolean crossline)
{
char* token_p;
if (tokenready) // is a token allready waiting?
{
tokenready = false;
return true;
}
if (script->script_p >= script->end_p)
return EndOfScript(crossline);
//
// skip space
//
skipspace:
while (*script->script_p <= 32)
{
if (script->script_p >= script->end_p)
return EndOfScript(crossline);
if (*script->script_p++ == '\n')
{
if (!crossline)
Error("Line %i is incomplete\n", scriptline);
scriptline = script->line++;
}
}
if (script->script_p >= script->end_p)
return EndOfScript(crossline);
if (*script->script_p == ';' || *script->script_p == '#' || // semicolon and # is comment field
(*script->script_p == '/' && *((script->script_p) + 1) == '/')) // also make // a comment field
{
if (!crossline)
Error("Line %i is incomplete\n", scriptline);
while (*script->script_p++ != '\n')
if (script->script_p >= script->end_p)
return EndOfScript(crossline);
goto skipspace;
}
//
// copy token
//
token_p = token;
if (*script->script_p == '"')
{
// quoted token
script->script_p++;
while (*script->script_p != '"')
{
*token_p++ = *script->script_p++;
if (script->script_p == script->end_p)
break;
if (token_p == &token[MAXTOKEN])
Error("Token too large on line %i\n", scriptline);
}
script->script_p++;
}
else // regular token
while (*script->script_p > 32 && *script->script_p != ';')
{
*token_p++ = *script->script_p++;
if (script->script_p == script->end_p)
break;
if (token_p == &token[MAXTOKEN])
Error("Token too large on line %i\n", scriptline);
}
*token_p = 0;
if (!strcmp(token, "$include"))
{
GetToken(false);
AddScriptToStack(token);
return GetToken(crossline);
}
return true;
}
/*
==============
TokenAvailable
Returns true if there is another token on the line
==============
*/
qboolean TokenAvailable(void)
{
char* search_p;
search_p = script->script_p;
if (search_p >= script->end_p)
return false;
while (*search_p <= 32)
{
if (*search_p == '\n')
return false;
search_p++;
if (search_p == script->end_p)
return false;
}
if (*search_p == ';')
return false;
return true;
}