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

📄 t_prepro.c

📁 The source code of Doom legacy for windows
💻 C
字号:
// Emacs style mode select -*- C++ -*-//----------------------------------------------------------------------------//// $Id: t_prepro.c,v 1.1 2000/11/02 17:57:28 stroggonmeth Exp $//// Copyright(C) 2000 Simon Howard//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.// // This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.// // You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA//// $Log: t_prepro.c,v $// Revision 1.1  2000/11/02 17:57:28  stroggonmeth// FraggleScript files...//////--------------------------------------------------------------------------//// Preprocessor.//// The preprocessor must be called when the script is first loaded.// It performs 2 functions://      1: blank out comments (which could be misinterpreted)//      2: makes a list of all the sections held within {} braces//      3: 'dry' runs the script: goes thru each statement and//         sets the types of all the section_t's in the script//      4: Saves locations of all goto() labels//// the system of section_t's is pretty horrible really, but it works// and its probably the only way i can think of of saving scripts// half-way thru running//// By Simon Howard////---------------------------------------------------------------------------/* includes ************************/#include <stdio.h>#include <string.h>#include "command.h"#include "doomstat.h"#include "w_wad.h"#include "z_zone.h"#include "t_parse.h"#include "t_spec.h"#include "t_oper.h"#include "t_vari.h"#include "t_func.h"// clear the script: section and variable slotsvoid clear_script(){  int i;    for(i=0; i<SECTIONSLOTS; i++)    current_script->sections[i] = NULL;    for(i=0; i<VARIABLESLOTS; i++)    current_script->variables[i] = NULL;  // clear child scripts    for(i=0; i<MAXSCRIPTS; i++)    current_script->children[i] = NULL;}/*********** {} sections *************/// during preprocessing all of the {} sections// are found. these are stored in a hash table// according to their offset in the script. // functions here deal with creating new section_t's// and finding them from a given offset.#define section_hash(b)           \       ( (int) ( (b) - current_script->data) % SECTIONSLOTS)section_t *new_section(char *brace){  int n;  section_t *newsec;    // create section  // make level so its cleared at start of new level    newsec = Z_Malloc(sizeof(section_t), PU_LEVEL, 0);  newsec->start = brace;    // hook it into the hashchain    n = section_hash(brace);  newsec->next = current_script->sections[n];  current_script->sections[n] = newsec;    return newsec;}        // find a section_t from the location of the starting { bracesection_t *find_section_start(char *brace){  int n = section_hash(brace);  section_t *current;    current = current_script->sections[n];    // use the hash table: check the appropriate hash chain    while(current)    {      if(current->start == brace)	return current;      current = current->next;    }    return NULL;    // not found}        // find a section_t from the location of the ending } bracesection_t *find_section_end(char *brace){  int n;    // hash table is no use, they are hashed according to  // the offset of the starting brace    // we have to go through every entry to find from the  // ending brace    for(n=0; n<SECTIONSLOTS; n++)      // check all sections in all chains    {      section_t *current = current_script->sections[n];            while(current)	{	  if(current->end == brace)	    return current;        // found it	  current = current->next;	}    }    return NULL;    // not found}/********** labels ****************/// labels are also found during the// preprocessing. these are of the form////      label_name://// and are used for the goto function.// goto labels are stored as variables.                // from parse.c#define isop(c)   !( ( (c)<='Z' && (c)>='A') || ( (c)<='z' && (c)>='a') || \                     ( (c)<='9' && (c)>='0') || ( (c)=='_') )        // create a new label. pass the location inside the scriptsvariable_t *new_label(char *labelptr){  svariable_t *newlabel;   // labels are stored as variables  char labelname[256];  char *temp, *temp2;    // copy the label name from the script up to ':'  for(temp=labelptr, temp2 = labelname; *temp!=':'; temp++, temp2++)    *temp2 = *temp;  *temp2 = '\0';  // end string    newlabel = new_variable(current_script, labelname, svt_label);    // put neccesary data in the label    newlabel->value.labelptr = labelptr;    return newlabel;}/*********** main loop **************/// This works by recursion. when a { opening// brace is found, another instance of the// function is called for the data inside// the {} section.// At the same time, the sections are noted// down and hashed. Goto() labels are noted// down, and comments are blanked outchar *process_find_char(char *data, char find){  while(*data)    {      if(*data==find) return data;      if(*data=='\"')       // found a quote: ignore stuff in it	{	  data++;	  while(*data && *data != '\"')	    {	      // escape sequence ?	      if(*data=='\\') data++;	      data++;	    }	  // error: end of script in a constant	  if(!*data) return NULL;	}      // comments: blank out      if(*data=='/' && *(data+1)=='*')        // /* -- */ comment	{	  while(*data && (*data != '*' || *(data+1) != '/') )	    {	      *data=' '; data++;	    }	  if(*data)	    *data = *(data+1) = ' ';   // blank the last bit	  else	    {	      rover = data;	      // script terminated in comment	      script_error("script terminated inside comment\n");	    }	}      if(*data=='/' && *(data+1)=='/')        // // -- comment	while(*data != '\n')	  {	    *data=' '; data++;       // blank out	  }      // labels      if(*data==':'  // ':' -- a label         && current_script->scriptnum != -1)   // not levelscript	{	  char *labelptr = data-1;	  	  while(!isop(*labelptr)) labelptr--;	  new_label(labelptr+1);	}            if(*data=='{')  // { -- } sections: add 'em	{	  section_t *newsec = new_section(data);	  	  newsec->type = st_empty;	  // find the ending } and save	  newsec->end = process_find_char(data+1, '}');	  if(!newsec->end)	    {                // brace not found	      rover = data;	      script_error("section error: no ending brace\n");	      return NULL;	    }	  // continue from the end of the section	  data = newsec->end;	}      data++;    }  return NULL;}/*********** second stage parsing ************/// second stage preprocessing considers the script// in terms of tokens rather than as plain data.//// we 'dry' run the script: go thru each statement and// collect types for section_t//// this is an important thing to do, it cannot be done// at runtime for 2 reasons://      1. gotos() jumping inside loops will pass thru//         the end of the loop//      2. savegames. loading a script saved inside a//         loop will let it pass thru the loop//// this is basically a cut-down version of the normal// parsing loop.void get_tokens(char *);         // t_parse.cvoid dry_run_script(){  // save some stuff  char *old_rover = rover;  section_t *old_current_section = current_section;    char *end = current_script->data + current_script->len;  char *token_alloc;    killscript = false;    // allocate space for the tokens  token_alloc = Z_Malloc(current_script->len + T_MAXTOKENS, PU_STATIC, 0);    rover = current_script->data;    while(rover < end && *rover)    {      tokens[0] = token_alloc;      get_tokens(rover);            if(killscript) break;      if(!num_tokens) continue;            if(current_section && tokentype[0] == function)	{	  if(!strcmp(tokens[0], "if"))	    {              current_section->type = st_if;	      continue;	    }          else if(!strcmp(tokens[0], "elseif"))            {              current_section->type = st_elseif;              continue;            }          else if(!strcmp(tokens[0], "else"))            {              current_section->type = st_else;              continue;            }	  else if(!strcmp(tokens[0], "while") ||		  !strcmp(tokens[0], "for"))	    {	      current_section->type = st_loop;	      current_section->data.data_loop.loopstart = linestart;	      continue;	    }	}    }    Z_Free(token_alloc);    // restore stuff  current_section = old_current_section;  rover = old_rover;}/***************** main preprocess function ******************/// set up current_script, script->len// just call all the other functionsvoid preprocess(script_t *script){  if(debugfile)    fprintf(debugfile,"  preprocess script %i\n", script->scriptnum);  current_script = script;  script->len = strlen(script->data);    clear_script();  if(debugfile)    fprintf(debugfile, "    run thru script\n");    process_find_char(script->data, 0);  // fill in everything    if(debugfile)    fprintf(debugfile, "    dry run script\n");    dry_run_script();}/************ includes ******************/// FraggleScript allows 'including' of other lumps.// we divert input from the current_script (normally// levelscript) to a seperate lump. This of course// first needs to be preprocessed to remove comments// etc.void parse_data(char *data, char *end); // t_parse.c// parse an 'include' lumpvoid parse_include(char *lumpname){  int lumpnum;  char *temp;  char *lump, *end;  char *saved_rover;    if(-1 == (lumpnum = W_GetNumForName(lumpname)) )    {      script_error("include lump '%s' not found!\n", lumpname);      return;    }    lump = W_CacheLumpNum(lumpnum, PU_STATIC);    // realloc bigger for NULL at end  // SoM: REALLOC does not seem to work! So we alloc here and copy....  //lump = Z_Realloc(lump, W_LumpLength(lumpnum)+10, PU_STATIC, NULL);  temp = lump;  lump = Z_Malloc(W_LumpLength(lumpnum) + 10, PU_STATIC, NULL);  memcpy(lump, temp, W_LumpLength(lumpnum));    saved_rover = rover;    // save rover during include  rover = lump; end = lump+W_LumpLength(lumpnum);  *end = 0;    // preprocess the include  // we assume that it does not include sections or labels or   // other nasty things  process_find_char(lump, 0);    // now parse the lump  parse_data(lump, end);    // restore rover  rover = saved_rover;    // free the lump  Z_Free(lump);  Z_Free(temp);}//---------------------------------------------------------------------------//// $Log: t_prepro.c,v $// Revision 1.1  2000/11/02 17:57:28  stroggonmeth// FraggleScript files...//// Revision 1.1.1.1  2000/04/30 19:12:08  fraggle// initial import//////---------------------------------------------------------------------------

⌨️ 快捷键说明

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