diff options
Diffstat (limited to 'ini.c')
-rw-r--r-- | ini.c | 526 |
1 files changed, 526 insertions, 0 deletions
@@ -0,0 +1,526 @@ +/* + + viDOOM - level editor for DOOM + + Copyright (C) 2000 Ian Cowburn (ianc@noddybox.demon.co.uk) + + 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 + + ------------------------------------------------------------------------- + + Routines to read our version of an INI file + + +*/ +static const char rcs_id[]="$Id$"; + +#include "config.h" + +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include "ini.h" +#include "mem.h" +#include "file.h" +#include "vstring.h" + +#define MAXLEN (PATH_MAX*2) +#define ROOTVAR "%WADDED%" + +typedef struct Token + { + char *key; + char *valkey; + char *val; + struct Token *next; + struct Token *prev; + } Token; + +static Token *ini=NULL; + +static char ini_dir[PATH_MAX]; +static char ini_file[PATH_MAX]; + +/* Token tables to export +*/ +TokenTable ini_yesno[]={{"yes",TRUE}, + {"no",FALSE}, + {"true",TRUE}, + {"false",FALSE}, + {"y",TRUE}, + {"n",FALSE}, + {"1",TRUE}, + {"0",FALSE}, + {NULL,0}}; + + +/* ---------------------------------------- PRIVATE FUNCTIONS +*/ +static int cmpstr(char *a,char *b) +{ + if ((a)&&(b)) + return(StrCaseCmp(a,b)); + else if ((!a)&&(!b)) + return(0); + else if (!a) + return(-1); + else + return(1); +} + + +static int CompareToken(Token *a, Token *b) +{ + int n; + + if ((n=cmpstr(a->key,b->key))) + return(n); + + return (cmpstr(a->valkey,b->valkey)); +} + +static Token *FindToken(char *key, char *val) +{ + Token *tok; + + tok=ini; + + while(tok) + { + if ((cmpstr(tok->key,key)==0)&& + (cmpstr(tok->valkey,val)==0)) + return(tok); + + tok=tok->next; + } + + return(NULL); +} + + +static char *GetLine(FILE *fp, int len) +{ + static char s[MAXLEN]; + int l,f; + + fgets(s,len-1,fp); + + if (feof(fp)) + return(FALSE); + + l=strlen(s)-1; + + if ((l>=0)&&(s[l]=='\n')) + s[l]=0; + + l=strlen(s)-1; + + if ((l>=0)&&(s[l]=='\r')) + s[l]=0; + + for(f=0;f<l;f++) + if (!isspace(s[f])) + if (s[f]=='#') + return(GetLine(fp,len)); + else + return(s+f); + + return(GetLine(fp,len)); +} + + +static void AddToken(char *key, char *line) +{ + Token *tok; + Token *ins; + char *valkey,*val; + + valkey=strtok(line,"="); + val=strtok(NULL,"="); + + if (!val) + val=""; + + tok=Grab(sizeof(Token)); + + tok->key=Strdup(key); + tok->valkey=Strdup(valkey); + tok->val=Strdup(val); + tok->next=NULL; + tok->prev=NULL; + + if (!ini) + { + ini=tok; + return; + } + + ins=ini; + + while(ins) + { + if (CompareToken(ins,tok)>0) + if (ins->prev) + { + ins->prev->next=tok; + tok->prev=ins->prev; + tok->next=ins; + ins->prev=tok; + + return; + } + else + { + tok->next=ins; + ins->prev=tok; + ini=tok; + + return; + } + + if (ins->next) + ins=ins->next; + else + { + ins->next=tok; + tok->prev=ins; + return; + } + } +} + +static int TokenToNum(char *val, TokenTable tokens[]) +{ + int f; + + f=0; + + while(tokens[f].token) + if (cmpstr(tokens[f].token,val)==0) + return(tokens[f].val); + else + f++; + + return(0); +} + +static char *NumToToken(int val, TokenTable tokens[]) +{ + int f; + + f=0; + + while(tokens[f].token) + if (tokens[f].val==val) + return(tokens[f].token); + else + f++; + + return(""); +} + + +static char *Expand(char *p) +{ + static char r[MAXLEN]; + + if (strncmp(p,ROOTVAR,strlen(ROOTVAR))==0) + { + strcpy(r,ini_dir); + strcat(r,p+strlen(ROOTVAR)); + return(r); + } + else + return(p); +} + + +static char *Unexpand(char *p) +{ + static char r[MAXLEN]; + + if (strncmp(p,ini_dir,strlen(ini_dir))==0) + { + strcpy(r,ROOTVAR); + strcat(r,p+strlen(ini_dir)); + return(r); + } + else + return(p); +} + + +/* ---------------------------------------- EXPORTED FUNCTIONS +*/ + +int INI_ReadInt(char *key, char *val) +{ + Token *tok; + + if ((tok=FindToken(key,val))) + return((int)strtol(tok->val,(char **)NULL,0)); + else + return(0); +} + +char *INI_ReadStr(char *key, char *val) +{ + Token *tok; + + if ((tok=FindToken(key,val))) + return(Expand(tok->val)); + else + return(""); +} + +int INI_ReadToken(char *key, char *val, TokenTable tokens[]) +{ + Token *tok; + + if ((tok=FindToken(key,val))) + return(TokenToNum(tok->val,tokens)); + else + return(0); +} + +double INI_ReadDouble(char *key, char *val) +{ + Token *tok; + char *dum; + + if ((tok=FindToken(key,val))) + return(strtod(tok->val,&dum)); + else + return(0.0); +} + +void INI_SaveInt(char *key, char *valkey, int val) +{ + char s[MAXLEN]; + Token *tok; + + sprintf(s,"%d",val); + + if ((tok=FindToken(key,valkey))) + { + Release(tok->val); + tok->val=Strdup(s); + } + else + { + sprintf(s,"%s=%d",valkey,val); + AddToken(key,s); + } +} + +void INI_SaveStr(char *key, char *valkey, char *val) +{ + char s[MAXLEN]; + Token *tok; + + if ((tok=FindToken(key,valkey))) + { + Release(tok->val); + tok->val=Strdup(Unexpand(val)); + } + else + { + sprintf(s,"%s=%s",valkey,val); + AddToken(key,s); + } +} + +void INI_SaveToken(char *key, char *valkey, int val, + TokenTable tokens[]) +{ + char s[MAXLEN]; + Token *tok; + + if ((tok=FindToken(key,valkey))) + { + Release(tok->val); + tok->val=Strdup(NumToToken(val,tokens)); + } + else + { + sprintf(s,"%s=%s",valkey,NumToToken(val,tokens)); + AddToken(key,s); + } +} + +void INI_SaveDouble(char *key, char *valkey, double val) +{ + char s[MAXLEN]; + Token *tok; + + sprintf(s,"%f",val); + + if ((tok=FindToken(key,valkey))) + { + Release(tok->val); + tok->val=Strdup(s); + } + else + { + sprintf(s,"%s=%f",valkey,val); + AddToken(key,s); + } +} + +void INI_DeleteKey(char *key,char *valkey) +{ + Token *tok; + + if ((tok=FindToken(key,valkey))) + { + if (tok->prev) + tok->prev->next=tok->next; + + if (tok->next) + tok->next->prev=tok->prev; + + if (ini==tok) + ini=tok->next; + + Release(tok->key); + Release(tok->valkey); + Release(tok->val); + Release(tok); + } +} + +void INI_Load(char *name) +{ + FILE *fp; + char *line; + char token[32]; + + strcpy(ini_dir,Pwd()); + strcpy(ini_file,ini_dir); + strcat(ini_file,DIRSEP); + strcat(ini_file,name); + + if ((fp=fopen(ini_file,"r"))) + while((line=GetLine(fp,MAXLEN))) + if (line[0]=='[') + { + line[strlen(line)-1]=0; + strcpy(token,line+1); + } + else + AddToken(token,line); +} + +void INI_Save(void) +{ + FILE *fp; + Token *tok; + char *last_key; + int first=TRUE; + + if ((fp=fopen(ini_file,"w"))) + { + tok=ini; + last_key=NULL; + + while(tok) + { + if (cmpstr(last_key,tok->key)) + { + if (first) + fprintf(fp,"[%s]\n",tok->key); + else + fprintf(fp,"\n[%s]\n",tok->key); + last_key=tok->key; + first=FALSE; + } + + fprintf(fp,"%s=%s\n",tok->valkey,tok->val); + + tok=tok->next; + } + + fclose(fp); + } +} + +void INI_GetTable(INI_Table table[],int no) +{ + int f; + int *i; + char *p; + double *d; + + for(f=0;f<no;f++) + if (FindToken(table[f].key,table[f].valkey)) + switch(table[f].type) + { + case INI_INT: + i=(int *)table[f].data; + *i=INI_ReadInt(table[f].key,table[f].valkey); + break; + + case INI_STR: + p=(char *)table[f].data; + strcpy(p,INI_ReadStr(table[f].key,table[f].valkey)); + break; + + case INI_TOK: + i=(int *)table[f].data; + *i=INI_ReadToken(table[f].key,table[f].valkey, + table[f].tokens); + break; + + case INI_DOUBLE: + d=(double *)table[f].data; + *d=INI_ReadDouble(table[f].key,table[f].valkey); + break; + } +} + +void INI_PutTable(INI_Table table[],int no) +{ + int f; + int i; + char *p; + double d; + + for(f=0;f<no;f++) + switch(table[f].type) + { + case INI_INT: + i=*((int *)table[f].data); + INI_SaveInt(table[f].key,table[f].valkey,i); + break; + + case INI_STR: + p=(char *)table[f].data; + INI_SaveStr(table[f].key,table[f].valkey,p); + break; + + case INI_TOK: + i=*((int *)table[f].data); + INI_SaveToken(table[f].key,table[f].valkey,i,table[f].tokens); + break; + + case INI_DOUBLE: + d=*((double *)table[f].data); + INI_SaveDouble(table[f].key,table[f].valkey,d); + break; + } +} + + +/* END OF FILE */ |