summaryrefslogtreecommitdiff
path: root/ini.c
diff options
context:
space:
mode:
Diffstat (limited to 'ini.c')
-rw-r--r--ini.c526
1 files changed, 526 insertions, 0 deletions
diff --git a/ini.c b/ini.c
new file mode 100644
index 0000000..c4b37a1
--- /dev/null
+++ b/ini.c
@@ -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 */