/* * config.c V1.5 * * 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 DockKey[]="DOCK:"; 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"; static char DirKey[]="WorkDir "; static char PathKey[]="Path "; static char OFileKey[]="OutFile "; char MenuKey[]="Menu "; char HotKKey[]="HotKey "; char StackKey[]="Stack "; static char ArgsKey[]="Args "; static char OutputKey[]="Output "; static char WBFrontKey[]="WBFront "; static char NameKey[]="IconName"; static char ITypeKey[]="IconType"; char IFileKey[]="IconFile"; static char IPosKey[]="IconPos "; static char DockOnKey[]="ShowDock"; static char SIconKey[]="SameIcon"; static char DTypeKey[]="DockType"; char DFileKey[]="DockFile"; static char OffKey[]="OFF"; static char OnKey[]="ON"; char BrushKey[]="Brush"; char DObjKey[]="Icon"; /* 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"}; /* External variables for Dock */ extern UWORD DockXPos,DockYPos; extern UWORD DockXSize,DockYSize; extern BOOL DockVertical; extern BOOL DockToBack; /* 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|TNFLAGS_DDOB; 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_Path[0]='\0'; cb->cb_Path[BUFLEN-1]='\0'; cb->cb_OutFile[0]='\0'; cb->cb_OutFile[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'; cb->cb_DockFile[0]='\0'; cb->cb_DockFile[BUFLEN-1]='\0'; } /* Read one config file entry */ static void ReadConfigBlock(FILE *fh, struct ConfigBlock *cb, char *name, int *lines, struct Window *w) { 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(w,&SyntaxErrES,NULL,name,*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,PathKey,4)) /* Path = */ { if (cb->cb_Type==TNTYPE_CLI) /* CLI tools only! */ strncpy(cb->cb_Path,parm,BUFLEN-1); } else if (!strnicmp(cp,OFileKey,7)) /* OutFile = */ { if (cb->cb_Type==TNTYPE_CLI) /* CLI tools only! */ { cb->cb_Flags|=TNFLAGS_COUT; /* Set output flag */ strncpy(cb->cb_OutFile,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,OutputKey,6)) /* Output = ON */ { if (!stricmp(parm,OnKey) && (cb->cb_Type==TNTYPE_CLI)) cb->cb_Flags|=TNFLAGS_COUT; /* Set output flag */ } else if (!strnicmp(cp,WBFrontKey,7)) /* WBFront = ON */ { if (!stricmp(parm,OnKey)) cb->cb_Flags|=TNFLAGS_WBTF; } else if (!strnicmp(cp,MenuKey,4)) /* Menu = OFF */ { if (!stricmp(parm,OffKey)) cb->cb_Flags&=~TNFLAGS_MENU; } else if (!strnicmp(cp,NameKey,6)) /* Name = OFF */ { cb->cb_Flags|=TNFLAGS_ICON; /* Set icon flag */ if (!stricmp(parm,OffKey)) cb->cb_Flags|=TNFLAGS_NNAM; } 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); if (cp1) cb->cb_IconY=strtol(cp1+1,&cp1,10); } else if (!strnicmp(cp,DockOnKey,8)) /* Dock = ON */ { if (!stricmp(parm,OnKey)) cb->cb_Flags|=TNFLAGS_DOCK; } else if (!strnicmp(cp,SIconKey,8)) /* SameIcon = ON */ { cb->cb_Flags|=TNFLAGS_DOCK; /* Set dock flag */ if (!stricmp(parm,OnKey)) cb->cb_Flags|=TNFLAGS_SICN; } else if (!strnicmp(cp,DTypeKey,8)) /* DockType = Brush */ { cb->cb_Flags|=TNFLAGS_DOCK; /* Set dock flag */ if (!stricmp(parm,BrushKey)) cb->cb_Flags&=~TNFLAGS_DDOB; } else if (!strnicmp(cp,DFileKey,8)) /* DockFile = */ { cb->cb_Flags|=TNFLAGS_DOCK; /* Set dock flag */ cb->cb_Flags&=~TNFLAGS_SICN; /* Clear same image flag */ strncpy(cb->cb_DockFile,parm,BUFLEN-1); } else /* Comment or unknown keyword */ if (*cp!=';') { cp[strlen(cp)-1]='\0'; /* remove trailing \n */ EasyRequest(w,&SyntaxErrES,NULL,name,*lines,cp); } } } } /* Read configuration file */ void ReadConfigFile(char *name, BOOL complete) { struct ConfigBlock *cb; /* Memory block for one config file entry */ FILE *fh; /* Filehandle for config file */ int lines=0; /* Line counter */ struct Screen *pubsc; struct Window *w=NULL; /* Pointer to Window for EasyRequest() */ if (pubsc=LockPubScreen(WBScreenName)) w=pubsc->FirstWindow; if (cb=malloc(sizeof(struct ConfigBlock))) /* Get memory */ { register char *cp=cb->cb_TempLine; if (name && (fh=fopen(name,"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: */ { if (complete) { char *cp1; /* ICON: , */ IconXPos=strtol(cp+sizeof(IconKey)-1,&cp1,10); if (cp1) IconYPos=strtol(cp1+1,&cp1,10); } } else if (!strnicmp(cp,DockKey,sizeof(DockKey)-1)) /* DOCK: */ { if (complete) { char *cp1; /* DOCK: ,,,,(H|V)(F|B) */ DockXPos=strtol(cp+sizeof(DockKey)-1,&cp1,10); if (cp1) DockYPos=strtol(cp1+1,&cp1,10); if (cp1) DockXSize=strtol(cp1+1,&cp1,10)+1; if (DockXSize<=0) DockXSize=41; if (cp1) DockYSize=strtol(cp1+1,&cp1,10)+1; if (DockYSize<=0) DockYSize=41; if (cp1) DockVertical=(cp1[1]=='V'); if (cp1) DockToBack=(cp1[2]=='B'); } } 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 if (*cp!=';') /* Comment or Syntax error */ { /* Syntax error, display error requester */ cp[strlen(cp)-1]='\0'; /* remove trailing \n */ EasyRequest(w,&SyntaxErrES,NULL,name,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,name,&lines,w); /* 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); } if (pubsc) UnlockPubScreen(NULL,pubsc); } /* 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 */ BOOL WriteConfigFile(struct Window *w, BOOL noreq) { BOOL error=FALSE; BOOL rc=TRUE; /* Means user pressed cancel */ char *cp; char number[20]; /* ConfigName was NOT set because of low mem situation --> break */ if (!ConfigName) goto wce0; /* Show file requester */ cp=ConfigName; if (noreq || !ShowFileRequester(w,"Save Configuration",&cp,FREQ_SAVE)) { /* User selected a file */ FILE *fh; /* Set new name */ if (!noreq) SetConfigFileName(cp); if (fh=fopen(cp,"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(number,IconXPos); fputs(number,fh); fputc(',',fh); ltoa(number,IconYPos); fputs(number,fh); fputc('\n',fh); } /* Write dock window position line */ fputs(DockKey,fh); ltoa(number,DockXPos); fputs(number,fh); fputc(',',fh); ltoa(number,DockYPos); fputs(number,fh); fputc(',',fh); ltoa(number,DockXSize-1); fputs(number,fh); fputc(',',fh); ltoa(number,DockYSize-1); fputs(number,fh); fputc(',',fh); if (DockVertical) fputc('V',fh); else fputc('H',fh); if (DockToBack) fputc('B',fh); else fputc('F',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 path string */ if (tn->tn_Path) WriteConfigLine(PathKey,tn->tn_Path,fh); /* Write stack size */ if (tn->tn_Stack>STACKMIN) { WriteParamKey(StackKey,fh); ltoa(number,tn->tn_Stack); fputs(number,fh); fputc('\n',fh); } /* Write argument passing state */ if (tn->tn_Flags&TNFLAGS_NARG) WriteConfigLine(ArgsKey,OffKey,fh); /* Write output file state */ if (tn->tn_Flags&TNFLAGS_COUT) if (tn->tn_OutFile) WriteConfigLine(OFileKey,tn->tn_OutFile,fh); else WriteConfigLine(OutputKey,OnKey,fh); /* Write Workbench to front state */ if (tn->tn_Flags&TNFLAGS_WBTF) WriteConfigLine(WBFrontKey,OnKey,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_NNAM) WriteConfigLine(NameKey,OffKey,fh); 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(number,tn->tn_Icon->do_CurrentX); fputs(number,fh); fputc(',',fh); ltoa(number,tn->tn_Icon->do_CurrentY); fputs(number,fh); fputc('\n',fh); } } /* Write dock stuff */ if (tn->tn_Flags&TNFLAGS_DOCK) if (tn->tn_Flags&TNFLAGS_SICN) WriteConfigLine(SIconKey,OnKey,fh); else if (tn->tn_DockFile) { WriteConfigLine(DFileKey,tn->tn_DockFile,fh); if (!(tn->tn_Flags&TNFLAGS_DDOB)) WriteConfigLine(DTypeKey,BrushKey,fh); } else WriteConfigLine(DockOnKey,OnKey,fh); fputc(CONFIGBLOCKEND,fh); /* Append config entry terminator */ fputc('\n',fh); /* Append a new line */ } fclose(fh); /* Close the config file */ ConfigChanged=FALSE; /* Config saved */ rc=FALSE; /* All OK */ } else error=TRUE; /* Couldn't open file */ if (!noreq) free(cp); /* free buffer from ShowFileRequester */ } wce0: if (error) DisplayBeep(NULL); return(rc); }