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

📄 scriplib.c

📁 An interactive water fountain. A realistic water source in your pocket with full control. Contro
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * scriplib.c * MACT library Script file parsing and writing * * by Jonathon Fowler * * Since we weren't given the source for MACT386.LIB so I've had to do some * creative interpolation here. * * This all should be rewritten in a much much cleaner fashion. * *///-------------------------------------------------------------------------/*Duke Nukem Copyright (C) 1996, 2003 3D Realms EntertainmentThis file is part of Duke Nukem 3D version 1.5 - Atomic EditionDuke Nukem 3D is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of 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 ofMERCHANTABILITY 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 Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.*///-------------------------------------------------------------------------#include "compat.h"#include "types.h"#include "scriplib.h"#include "util_lib.h"#include "file_lib.h"#include "_scrplib.h"#include <string.h>#include <stdio.h>#include <ctype.h>#ifdef __WATCOMC__#include <malloc.h>#endifstatic script_t *scriptfiles[MAXSCRIPTFILES];#define SC(s) scriptfiles[s]int32 SCRIPT_New(void){    int32 i;    for (i=0; i<MAXSCRIPTFILES; i++)    {        if (!SC(i))        {            SC(i) = (script_t *)SafeMalloc(sizeof(script_t));            if (!SC(i)) return -1;            memset(SC(i), 0, sizeof(script_t));            return i;        }    }    return -1;}void SCRIPT_Delete(int32 scripthandle){    ScriptSectionType *s;    if (scripthandle < 0 || scripthandle >= MAXSCRIPTFILES) return;    if (!SC(scripthandle)) return;    if (SCRIPT(scripthandle,script))    {        while (SCRIPT(scripthandle,script)->nextsection != SCRIPT(scripthandle,script))        {            s = SCRIPT(scripthandle,script)->nextsection;            SCRIPT_FreeSection(SCRIPT(scripthandle,script));            SafeFree(SCRIPT(scripthandle,script));            SCRIPT(scripthandle,script) = s;        }        SafeFree(SCRIPT(scripthandle,script));    }    SafeFree(SC(scripthandle));    SC(scripthandle) = 0;}void SCRIPT_FreeSection(ScriptSectionType * section){    ScriptEntryType *e;    if (!section) return;    if (!section->entries) return;    while (section->entries->nextentry != section->entries)    {        e = section->entries->nextentry;        SafeFree(section->entries);        section->entries = e;    }    SafeFree(section->entries);    free(section->name);}#define AllocSection(s) \	{ \		(s) = SafeMalloc(sizeof(ScriptSectionType)); \		(s)->name = NULL; \		(s)->entries = NULL; \		(s)->lastline = NULL; \		(s)->nextsection = (s); \		(s)->prevsection = (s); \	}#define AllocEntry(e) \	{ \		(e) = SafeMalloc(sizeof(ScriptEntryType)); \		(e)->name = NULL; \		(e)->value = NULL; \		(e)->nextentry = (e); \		(e)->preventry = (e); \	}ScriptSectionType * SCRIPT_SectionExists(int32 scripthandle, char * sectionname){    ScriptSectionType *s, *ls=NULL;    if (scripthandle < 0 || scripthandle >= MAXSCRIPTFILES) return NULL;    if (!sectionname) return NULL;    if (!SC(scripthandle)) return NULL;    if (!SCRIPT(scripthandle,script)) return NULL;    for (s = SCRIPT(scripthandle,script); ls != s; ls=s,s=s->nextsection)        if (!Bstrcasecmp(s->name, sectionname)) return s;    return NULL;}ScriptSectionType * SCRIPT_AddSection(int32 scripthandle, char * sectionname){    ScriptSectionType *s,*s2;    if (scripthandle < 0 || scripthandle >= MAXSCRIPTFILES) return NULL;    if (!sectionname) return NULL;    if (!SC(scripthandle)) return NULL;    s = SCRIPT_SectionExists(scripthandle, sectionname);    if (s) return s;    AllocSection(s);    s->name = strdup(sectionname);    if (!SCRIPT(scripthandle,script))    {        SCRIPT(scripthandle,script) = s;    }    else    {        s2 = SCRIPT(scripthandle,script);        while (s2->nextsection != s2) s2=s2->nextsection;        s2->nextsection = s;        s->prevsection = s2;    }    return s;}ScriptEntryType * SCRIPT_EntryExists(ScriptSectionType * section, char * entryname){    ScriptEntryType *e,*le=NULL;    if (!section) return NULL;    if (!entryname) return NULL;    if (!section->entries) return NULL;    for (e = section->entries; le != e; le=e,e=e->nextentry)        if (!Bstrcasecmp(e->name, entryname)) return e;    return NULL;}void SCRIPT_AddEntry(int32 scripthandle, char * sectionname, char * entryname, char * entryvalue){    ScriptSectionType *s;    ScriptEntryType *e,*e2;    if (scripthandle < 0 || scripthandle >= MAXSCRIPTFILES) return;    if (!sectionname || !entryname || !entryvalue) return;    if (!SC(scripthandle)) return;//	s = SCRIPT_SectionExists(scripthandle, sectionname);//	if (!s) {    s = SCRIPT_AddSection(scripthandle, sectionname);    if (!s) return;//	}    e = SCRIPT_EntryExists(s, entryname);    if (!e)    {        AllocEntry(e);        e->name = strdup(entryname);        if (!s->entries)        {            s->entries = e;        }        else        {            e2 = s->entries;            while (e2->nextentry != e2) e2=e2->nextentry;            e2->nextentry = e;            e->preventry = e2;        }    }    if (e->value) free(e->value);    e->value = strdup(entryvalue);}int32 SCRIPT_ParseBuffer(int32 scripthandle, char *data, int32 length){    char *fence = data + length;    char *dp, *sp, ch=0, lastch=0;    char *currentsection = "";    char *currententry = NULL;    char *currentvalue = NULL;    enum    {        ParsingIdle,        ParsingSectionBegin,        ParsingSectionName,        ParsingEntry,        ParsingValueBegin,        ParsingValue    };    enum    {        ExpectingSection = 1,        ExpectingEntry = 2,        ExpectingAssignment = 4,        ExpectingValue = 8,        ExpectingComment = 16    };    int32_t state;    int32_t expect;    int32_t linenum=1;    int32_t rv = 0;#define SETRV(v) if (v>rv||rv==0) rv=v    if (!data) return 1;    if (length < 0) return 1;    dp = sp = data;    state = ParsingIdle;    expect = ExpectingSection | ExpectingEntry;#define EATLINE(p) while (length > 0 && *p != '\n' && *p != '\r') { p++; length--; }#define LETTER() { lastch = ch; ch = *(sp++); length--; }    while (length > 0)    {        switch (state)        {        case ParsingIdle:            LETTER();            switch (ch)            {                // whitespace            case ' ':            case '\t': continue;            case '\n': if (lastch == '\r') continue; linenum++; continue;            case '\r': linenum++; continue;            case ';':                /*case '#':*/                EATLINE(sp);                continue;            case '[': if (!(expect & ExpectingSection))                {                    // Unexpected section start                    printf("Unexpected start of section on line %d.\n", linenum);                    SETRV(-1);                    EATLINE(sp);                    continue;                }                else                {                    state = ParsingSectionBegin;                    continue;                }            default:  if (isalpha(ch))                {                    if (!(expect & ExpectingEntry))                    {                        // Unexpected name start                        printf("Unexpected entry LabelText on line %d.\n", linenum);                        SETRV(-1);                        EATLINE(sp);                        continue;                    }                    else                    {                        currententry = dp = sp-1;                        state = ParsingEntry;                        continue;                    }                }                else                {                    // Unexpected character                    printf("Illegal character (ASCII %d) on line %d.\n", ch, linenum);                    SETRV(-1);                    EATLINE(sp);                    continue;                }            }        case ParsingSectionBegin:            currentsection = dp = sp;            state = ParsingSectionName;        case ParsingSectionName:            LETTER();            switch (ch)            {            case '\n':            case '\r':	// Unexpected newline                printf("Unexpected newline on line %d.\n", linenum);                SETRV(-1);                state = ParsingIdle;                linenum++;                continue;            case ']':                *(dp) = 0;	// Add new section                expect = ExpectingSection | ExpectingEntry;                state = ParsingIdle;                EATLINE(sp);                continue;            default:                dp++;                continue;            }        case ParsingEntry:            LETTER();            switch (ch)            {            case ';':                /*case '#':*/                // unexpected comment                EATLINE(sp);                printf("Unexpected comment on line %d.\n", linenum);                SETRV(-1);            case '\n':            case '\r':                // Unexpected newline                printf("Unexpected newline on line %d.\n", linenum);                SETRV(-1);                expect = ExpectingSection | ExpectingEntry;                state = ParsingIdle;                linenum++;                continue;            case '=':                // Entry name finished, now for the value                while (*dp == ' ' || *dp == '\t') dp--;                *(++dp) = 0;                state = ParsingValueBegin;                continue;            default:                dp++;                continue;            }        case ParsingValueBegin:            currentvalue = dp = sp;            state = ParsingValue;        case ParsingValue:            LETTER();            switch (ch)            {            case '\n':            case '\r':                // value complete, add it using parsed name                while (*dp == ' ' && *dp == '\t') dp--;                *(dp) = 0;                while (*currentvalue == ' ' || *currentvalue == '\t') currentvalue++;                state = ParsingIdle;                linenum++;                SCRIPT_AddSection(scripthandle,currentsection);                SCRIPT_AddEntry(scripthandle,currentsection,currententry,currentvalue);                continue;            default:                dp++;                continue;            }        default: length=0;            continue;        }    }    if (sp > fence) printf("Stepped outside the fence!\n");    return rv;}//---int32 SCRIPT_Init(char * name){    int32 h = SCRIPT_New();    if (h >= 0) Bstrncpy(SCRIPT(h,scriptfilename), name, 127);    return h;}void SCRIPT_Free(int32 scripthandle){    SCRIPT_Delete(scripthandle);}int32 SCRIPT_Load(char * filename){    int32 s,h,l;    char *b;    h = SafeOpenRead(filename, filetype_binary);    l = SafeFileLength(h)+1;    b = (char *)SafeMalloc(l);    SafeRead(h,b,l-1);    b[l-1] = '\n';	// JBF 20040111: evil nasty hack to trick my evil nasty parser    SafeClose(h);    s = SCRIPT_Init(filename);    if (s<0)    {        SafeFree(b);        return -1;    }    SCRIPT_ParseBuffer(s,b,l);    SafeFree(b);    return s;}void SCRIPT_Save(int32 scripthandle, char * filename){    char *section, *entry, *value;    int32_t sec, ent, numsect, nument;    FILE *fp;

⌨️ 快捷键说明

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