/* * prefs * * Preferences loading and saving * * © 1993-1998 Straylight */ /*----- Licensing note ----------------------------------------------------* * * This file is part of Straylight's Steel library. * * Steel 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, or (at your option) * any later version. * * Steel 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 Steel. If not, write to the Free Software Foundation, * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "prefs.h" #include "os.h" #include "utils.h" #include "msgs.h" #include "choices.h" #include "res.h" #include "kernel.h" #include "werr.h" #include #include #include #define unused(x) ((x)=(x)) static prefs_prefstr *prefs__prefs; /* * char *prefs__match(char *a,char *b) * * Use * Checks to see if the first part of a matches b. If it does, it returns * the rest of a. * * Parameters * char *a == an input string * char *b == a keyword * * Returns * The part of a following b, or NULL if no match */ static char *prefs__match(char *a,char *b) { if (!*a) return (0); while (*b) { if (tolower(*(a++))!=tolower(*(b++))) return (0); } while (*a==' ') a++; if (*a=='=') a++; while (*a==' ') a++; return (a); } /* * char *prefs_readBoolean(char *tag,char *args,void *handle) * * Use * Reads a Boolean variable (i.e. one that can be either TRUE or FALSE). */ char *prefs_readBoolean(char *tag,char *args,void *handle) { unused(tag); if (utils_caselessCmp(args,"true")==0) *(BOOL *)handle=TRUE; else if (utils_caselessCmp(args,"false")==0) *(BOOL *)handle=FALSE; else return (msgs_lookup("prefsRBB:Bad boolean variable '%s' at line %i (must be 'true' or 'false')")); return (0); } /* * char *prefs_writeBoolean(char *tag,FILE *fp,void *handle) * * Use * Writes a Boolean variable to the preferences file. */ char *prefs_writeBoolean(char *tag,FILE *fp,void *handle) { fprintf(fp,"%s=%s\n",tag,*(BOOL *)handle ? "true" : "false"); return (0); } /* * char *prefs_readNumeric(char *tag,char *args,void *handle) * * Use * Reads a signed integer from the preferences file. */ char *prefs_readNumeric(char *tag,char *args,void *handle) { unused(tag); sscanf(args,"%d",(int *)handle); return (0); } /* * char *prefs_writeNumeric(char *tag,FILE *fp,void *handle) * * Use * Writes a signed integer to the preferences file. */ char *prefs_writeNumeric(char *tag,FILE *fp,void *handle) { fprintf(fp,"%s=%i\n",tag,*(int *)handle); return (0); } /* * char *prefs_readString(char *tag,char *args,void *handle) * * Use * Reads a string from the preferences file. It is assumed that the buffer * pointed to by handle is big enough. */ char *prefs_readString(char *tag,char *args,void *handle) { char *p; unused(tag); if (*args=='\'') { for (p=++args;*p && *p!='\'';p++) /* blank! */; *p=0; } strcpy((char *)handle,args); return (0); } /* * char *prefs_writeString(char *tag,FILE *fp,void *handle) * * Use * Writes a signed integer to the preferences file. */ char *prefs_writeString(char *tag,FILE *fp,void *handle) { fprintf(fp,"%s='%s'\n",tag,(char *)handle); return (0); } /* * void prefs_preferences(prefs_prefstr *p) * * Use * Sets up the prefs system to use the preferences definition specified. * 'p' should be a pointer to an array of prefs_prefstrs, terminated by an * entry with a null 'tag'. The preferences file created will be called * 'Choices' in the current application's directory (.Choices). * * Parameters * prefs_prefstr *p == pointer to an array of preferences definitions */ void prefs_preferences(prefs_prefstr *p) { prefs__prefs=p; } /* * void prefs_read(void) * * Use * Reads preferences from the preferences file. */ void prefs_read(void) { FILE *fp; int i; int line=0; char buff[256]; char *p; char *args; char *error; char *preffile=choices_name("Choices",FALSE); /* --- Make sure the Preferences file exists --- * * * If we can't find the Preferences, we leave the user's buffer unchanged * to allow defaults */ if (!res_fileExists(preffile)) return; /* --- Open the Preferences file --- */ fp=fopen(preffile,"r"); if (!fp) { werr(FALSE, msgs_lookup("prefsERP:Error reading preferences. " "Assuming default preferences.")); return; } /* --- Read the file a line at a time and parse it --- */ while (fgets(buff,256,fp)) { /* --- Bump line count for error messages --- */ line++; /* --- Strip leading spaces --- */ for (p=buff;isspace(*p);p++) /* blank! */; /* --- fgets leaves a return on the end -- kill it --- */ utils_ctermToNterm(p); /* --- Do something about the line --- */ switch (*p) { /* --- Discard blank lines and comments --- */ case 0: case ';': break; /* --- Otherwise find the parser for this variable and call it --- */ default: for (i=0;prefs__prefs[i].tag;i++) { if (args=prefs__match(p,prefs__prefs[i].tag),args) { if (prefs__prefs[i].read) { if (error=prefs__prefs[i].read(prefs__prefs[i].tag, args, prefs__prefs[i].handle),error) { werr(FALSE,error,prefs__prefs[i].tag,line); fclose(fp); return; } } break; } } break; } } fclose(fp); } /* * void prefs_write(void) * * Use * Writes preferences out to disk. */ void prefs_write(void) { int i; FILE *fp=fopen(choices_name("Choices",TRUE),"w"); char *error; /* --- Complain if we can't write the file --- */ if (!fp) { werr(FALSE, msgs_lookup("prefsEWP:Error writing preferences: '%s'"), _kernel_last_oserror()->errmess); return; } /* --- Go through the entries one by one calling the output fns --- */ for (i=0;prefs__prefs[i].tag;i++) { if (prefs__prefs[i].tag[0]==';' || prefs__prefs[i].tag[0]=='\n') fprintf(fp,"%s",prefs__prefs[i].tag); else if (!prefs__prefs[i].write) /* blank! */; else if (error=prefs__prefs[i].write(prefs__prefs[i].tag, fp, prefs__prefs[i].handle),error) { werr(FALSE,error,prefs__prefs[i].tag); fclose(fp); return; } } /* --- Close the file and exit --- */ fclose(fp); return; }