/* * config.c V1.4 * * configuration file handling * * (c) 1991 by Stefan Becker * */ #include "ToolManager.h" /* Tool type keywords in the configuration file, must end with a ':'!! */ static char IconKey[]="ICON:"; static char DummyKey[]="DUMMY:"; static char CLIKey[]="CLI:"; static char WBKey[]="WB:"; #define CONFIGBLOCKEND '#' /* Config entry keywords */ static char AssignKey[]=" = "; char AliasKey[]="Alias "; char RealKey[]="RealName"; char DirKey[]="WorkDir "; char MenuKey[]="Menu "; char HotKKey[]="HotKey "; char StackKey[]="Stack "; static char ArgsKey[]="Args "; char ITypeKey[]="IconType"; char IFileKey[]="IconFile"; static char IPosKey[]="IconPos "; static char OffKey[]="OFF"; char BrushKey[]="Brush"; char DObjKey[]="Icon"; /* miscellaneous */ extern char *ConfigName; struct Library *AslBase; /* Library for file requester */ static char ReqTitle[]="Save Configuration"; /* file requester title */ /* Data for syntax error requester */ static struct EasyStruct SyntaxErrES={sizeof(struct EasyStruct),0,MyName, "Syntax error in configuration file\n"\ "%s, line %ld\n'%s'","Ok"}; /* Set the name of the config file */ void SetConfigFileName(char *s) { if (ConfigName) free(ConfigName); ConfigName=strdup(s); } /* Init a config block struct */ void InitConfigBlock(struct ConfigBlock *cb) { cb->cb_Type=255; cb->cb_Flags=TNFLAGS_MENU|TNFLAGS_DOBJ; cb->cb_Stack=STACKMIN; cb->cb_IconX=NO_ICON_POSITION; cb->cb_IconY=NO_ICON_POSITION; cb->cb_Alias[0]='\0'; cb->cb_Alias[BUFLEN-1]='\0'; cb->cb_RealName[0]='\0'; cb->cb_RealName[BUFLEN-1]='\0'; cb->cb_WorkDir[0]='\0'; cb->cb_WorkDir[BUFLEN-1]='\0'; cb->cb_HotKey[0]='\0'; cb->cb_HotKey[BUFLEN-1]='\0'; cb->cb_IconFile[0]='\0'; cb->cb_IconFile[BUFLEN-1]='\0'; } /* Read one config file entry */ static void ReadConfigBlock(FILE *fh, struct ConfigBlock *cb, int *lines) { register char *cp=cb->cb_TempLine; while (!feof(fh)) /* if not end of file, read one line into buffer */ { (*lines)++; if (fgets(cp,BUFLEN+20,fh) && (strlen(cp)>1)) /* Skip empty lines */ if (*cp==CONFIGBLOCKEND) return; /* End of entry reached */ else { register char *parm; /* Remove trailing newline */ if (cp[strlen(cp)-1]=='\n') cp[strlen(cp)-1]='\0'; /* Scan line for '=' */ parm=strchr(cp,'='); /* Skip white space */ if (parm) { parm++; while (*parm && isspace(*parm)) parm++; } /* Valid parameter? */ if (!parm && !*parm) { /* No --> Syntax error */ EasyRequest(NULL,&SyntaxErrES,NULL,ConfigName,*lines,cp); /* Next line */ continue; } /* Extract parameter value */ if (!strnicmp(cp,AliasKey,5)) /* Alias = */ strncpy(cb->cb_Alias,parm,BUFLEN-1); else if (!strnicmp(cp,RealKey,8)) /* RealName = */ strncpy(cb->cb_RealName,parm,BUFLEN-1); else if (!strnicmp(cp,DirKey,7)) /* WorkDir = */ strncpy(cb->cb_WorkDir,parm,BUFLEN-1); else if (!strnicmp(cp,HotKKey,6)) /* HotKey = */ strncpy(cb->cb_HotKey,parm,BUFLEN-1); else if (!strnicmp(cp,IFileKey,8)) /* IconFile = */ { cb->cb_Flags|=TNFLAGS_ICON; /* Set icon flag */ strncpy(cb->cb_IconFile,parm,BUFLEN-1); } else if (!strnicmp(cp,StackKey,5)) /* Stack = */ { char *cp1; cb->cb_Stack=strtol(parm,&cp1,10); } else if (!strnicmp(cp,ArgsKey,4)) /* Args = OFF */ { if (!stricmp(parm,OffKey)) cb->cb_Flags|=TNFLAGS_NARG; } else if (!strnicmp(cp,MenuKey,4)) /* Menu = OFF */ { if (!stricmp(parm,OffKey)) cb->cb_Flags&=~TNFLAGS_MENU; } else if (!strnicmp(cp,ITypeKey,8)) /* IconType = Brush */ { cb->cb_Flags|=TNFLAGS_ICON; /* Set icon flag */ if (!stricmp(parm,BrushKey)) cb->cb_Flags&=~TNFLAGS_DOBJ; } else if (!strnicmp(cp,IPosKey,7)) /* IconPos = */ { char *cp1; cb->cb_Flags|=TNFLAGS_ICON; /* Set icon flag */ cb->cb_IconX=strtol(parm,&cp1,10); cb->cb_IconY=strtol(cp1+1,&cp1,10); } else /* Unknown keyword */ EasyRequest(NULL,&SyntaxErrES,NULL,ConfigName,*lines,cp); } } } /* Read configuration file */ void ReadConfigFile() { struct ConfigBlock *cb; /* Memory block for one config file entry */ FILE *fh; /* Filehandle for config file */ int lines=0; /* Line counter */ if (cb=malloc(sizeof(struct ConfigBlock))) /* Get memory */ { register char *cp=cb->cb_TempLine; if (ConfigName && (fh=fopen(ConfigName,"r"))) /* Scan config file */ { while (!feof(fh)) /* if not end of file, read one line into buffer */ { lines++; if (fgets(cp,BUFLEN,fh) && (strlen(cp)>1)) /* Skip empty lines */ { InitConfigBlock(cb); /* Extract tool type */ if (!strnicmp(cp,IconKey,sizeof(IconKey)-1)) /* ICON: */ { char *cp1; IconXPos=strtol(cp+sizeof(IconKey)-1,&cp1,10); IconYPos=strtol(cp1+1,&cp1,10); } else if (!strnicmp(cp,DummyKey,sizeof(DummyKey)-1)) /* DUMMY: */ cb->cb_Type=TNTYPE_DUMMY; else if (!strnicmp(cp,CLIKey,sizeof(CLIKey)-1)) /* CLI: */ cb->cb_Type=TNTYPE_CLI; else if (!strnicmp(cp,WBKey,sizeof(WBKey)-1)) /* WB: */ cb->cb_Type=TNTYPE_WB; else /* Syntax error */ { /* Display error requester */ EasyRequest(NULL,&SyntaxErrES,NULL,ConfigName,lines,cp); /* Try to skip to end of current block */ while (!feof(fh)) { lines++; fgets(cp,BUFLEN,fh); if (*cp==CONFIGBLOCKEND) break; } } /* Does a valid config block follow? */ if (cb->cb_Type!=255) { /* Read in one config file entry */ ReadConfigBlock(fh,cb,&lines); /* Special check for empty dummy tool entries */ if ((cb->cb_Type==TNTYPE_DUMMY) && (cb->cb_Alias[0]=='\0') && (cb->cb_RealName[0]=='\0')) strcpy(cb->cb_Alias," "); /* Add tool */ AddToolNode(cb,StartupCD); } } } fclose(fh); } free(cb); } } /* Tiny long to string conversion routine */ static void ltoa(char *s, long n) { long i=1000000000; /* Divisor */ BOOL inumber=FALSE; /* Flag */ if (n==-2147483648) /* Handle special case 2^31*/ { strcpy(s,"-2147483648"); return; } if (n<0) /* Handle negativ numbers */ { n=-n; *s++='-'; } if (n==0) *s++='0'; /* Zero is a special case */ else while (i) /* Every other numer goes here */ { *s=n/i+'0'; /* Retrieve leading digit */ if (*s!='0') inumber=TRUE; /* Suppress leading zero's */ if (inumber) s++; n%=i; /* Remove digit from number */ i/=10; /* next divisor */ } *s='\0'; /* Append string terminator */ } /* Write one parameter keyword */ static void WriteParamKey(char *cp, FILE *fh) { fputs(cp,fh); /* Write keyword */ fputs(AssignKey,fh); /* Write " = " */ } /* Write one complete config line */ static void WriteConfigLine(char *key, char *parm, FILE *fh) { WriteParamKey(key,fh); /* Write keyword */ fputs(parm,fh); /* Write parameter */ fputc('\n',fh); /* Write newline */ } /* Write configuration file */ void WriteConfigFile(struct Window *w) { struct FileRequester *req; BOOL rc=TRUE; char dir[NAMELEN],file[NAMELEN],*cp; /* ConfigName was NOT set because of low mem situation --> break */ if (!ConfigName) goto wce0; /* Open ASL library */ if (!(AslBase=OpenLibrary(AslName,0))) goto wce0; /* Split file name */ cp=FilePart(ConfigName); if (cp!=ConfigName) strncpy(dir,ConfigName,cp-ConfigName); dir[cp-ConfigName]='\0'; strncpy(file,cp,NAMELEN); /* Alloc file requester structure */ if (!(req=AllocAslRequestTags(ASL_FileRequest,ASL_Hail,ReqTitle, ASL_Window,w, ASL_LeftEdge,w->LeftEdge, ASL_TopEdge,w->TopEdge, ASL_Dir,dir, ASL_File,file, ASL_FuncFlags,FILF_SAVE, TAG_DONE))) goto wce1; /* Open file requester */ if (AslRequest(req,NULL)) if (*req->rf_File) /* Valid file name? */ { FILE *fh; strncpy(dir,req->rf_Dir,NAMELEN); /* Build complete name */ AddPart(dir,req->rf_File,NAMELEN); SetConfigFileName(dir); if (fh=fopen(dir,"w")) /* Open config file */ { register struct ToolNode *tn; /* Write icon position line */ if ((IconXPos!=NO_ICON_POSITION) || (IconYPos!=NO_ICON_POSITION)) { fputs(IconKey,fh); ltoa(dir,IconXPos); fputs(dir,fh); fputc(',',fh); ltoa(dir,IconYPos); fputs(dir,fh); fputc('\n',fh); } for (tn=GetHead(&ToolList); tn; tn=GetSucc(tn)) { /* Write tool type */ switch(tn->tn_Type) { case TNTYPE_DUMMY: fputs(DummyKey,fh); break; case TNTYPE_CLI: fputs(CLIKey,fh); break; case TNTYPE_WB: fputs(WBKey,fh); break; } fputc('\n',fh); /* Write alias name */ WriteConfigLine(AliasKey,tn->tn_Node.ln_Name,fh); /* Write real name */ if (tn->tn_RealName) WriteConfigLine(RealKey,tn->tn_RealName,fh); /* Write working directory */ if (tn->tn_WorkDir) WriteConfigLine(DirKey,tn->tn_WorkDir,fh); /* Write stack size */ if (tn->tn_Stack>STACKMIN) { WriteParamKey(StackKey,fh); ltoa(dir,tn->tn_Stack); fputs(dir,fh); fputc('\n',fh); } /* Write argument passing state */ if (tn->tn_Flags&TNFLAGS_NARG) WriteConfigLine(ArgsKey,OffKey,fh); /* Write menu entry status */ if (!(tn->tn_Flags&TNFLAGS_MENU)) WriteConfigLine(MenuKey,OffKey,fh); /* Write HotKey description */ if (tn->tn_HotKey) WriteConfigLine(HotKKey,tn->tn_HotKey,fh); /* Write icon stuff */ if (tn->tn_Flags&TNFLAGS_ICON) { if (!(tn->tn_Flags&TNFLAGS_DOBJ)) WriteConfigLine(ITypeKey,BrushKey,fh); if (tn->tn_IconFile) WriteConfigLine(IFileKey,tn->tn_IconFile,fh); if ((tn->tn_Icon->do_CurrentX!=NO_ICON_POSITION) || (tn->tn_Icon->do_CurrentY!=NO_ICON_POSITION)) { WriteParamKey(IPosKey,fh); ltoa(dir,tn->tn_Icon->do_CurrentX); fputs(dir,fh); fputc(',',fh); ltoa(dir,tn->tn_Icon->do_CurrentY); fputs(dir,fh); fputc('\n',fh); } } fputc(CONFIGBLOCKEND,fh); /* Append config entry terminator */ fputc('\n',fh); /* Append a new line */ } fclose(fh); /* Close the config file */ rc=FALSE; /* All OK */ } } wce2: FreeAslRequest(req); wce1: CloseLibrary(AslBase); wce0: if (rc) DisplayBeep(NULL); }