/* * Parse.c - Copyright © 1990 by S.R. & P.C. * * Created: 16 Jun 1990 * Modified: 06 Jul 1990 * * Make>> make */ /* #define DO_ARP_COPIES #include #include #include #include */ #include #include #include "ParM.h" #define SYNTAX(msg) { Err(msg); return FALSE; } /* tokens */ #define CMDWIN 1 #define RB 2 #define WB 3 #define CLI 4 #define PRI 5 #define STACK 6 #define MENU 7 #define SUBMENU 8 #define ENDSUBMENU 9 #define ITEM 10 #define COLOR 11 #define STR 12 /* not a keyword! */ #define MAX_KEYWORD 11 /***** external functions *****/ extern void Warn(const char *); extern void AddMenu(char *); extern void AddSubMenu(char *); extern void AddEntry(char *, char *, char *, char*, char, char, long, short); extern void EndSubMenu(void); extern void FreeMenus(void); extern void CleanUp(void); /***** global functions *****/ BOOL ParseMenus( void ); /***** global variables *****/ extern struct Window *Win; extern char CurCfg[]; extern char CmdWindow[]; extern UBYTE menu_pen; /***** local variables *****/ static char *KeyWordTab[] = { NULL, /* possible implementation of an END keyword */ "CMDWIN", "RB", "WB", "CLI", "PRI", "STACK", "MENU", "SUBMENU", "ENDSUBMENU", "ITEM", "COLOR" }; /* status */ #define STAT_BEGIN 0 #define STAT_MENU 1 #define STAT_SUBMENU 2 #define STAT_ITEM 4 static char *filebuf,*fp; static char tok[80]; /* add the position of the error to the error message */ static void Err( char *msg ) { char buf[80]; SPrintf(buf,"%s, char %ld",msg,fp-filebuf); Warn(buf); } /* rfp is a register variable used to replace global fp pointer in * get_token() body. Then, fp must be restored before leaving function */ static char get_token( void ) { register char *p,*rfp; short i; char quote; rfp = fp; retry: while(isspace(*rfp)) rfp++; /* skip extra spaces */ if(*rfp=='#') { /* comment */ while(*rfp!='\n' && *rfp) rfp++; goto retry; } if(!isprint(*rfp) || *rfp=='{' || *rfp=='}') { fp = rfp; return *fp++; /* '{', '}', '\0', or invalid char */ } /* scan string */ p = tok; if(*rfp=='"') { rfp++; quote = TRUE; } else quote = FALSE; while( (quote && *rfp!='"') || (!quote && isspace(*rfp)==0) ) *p++ = *rfp++; *p = NULL; if (quote) rfp++; /* skip closing '"' */ for( i=1 ; i<=MAX_KEYWORD ; i++ ) { if (!Strcmp(tok ,KeyWordTab[i])) break; /* arp Strcmp() is not case sensitive */ } fp = rfp; return i; } static BOOL ParseConfig( void ) { char t,shortcut,mode; long stack; short pri; USHORT status = STAT_BEGIN; register char *p, c; char itemstr[80], cmd[80], args[200], win[80]; while(t=get_token()) { switch( t ) { case CMDWIN : get_token(); strcpy(CmdWindow, tok); break; case COLOR : get_token(); menu_pen = ( (menu_pen=Atol(tok)) == Win->BlockPen ) ? Win->DetailPen : menu_pen; break; case MENU : if ( !(status & (STAT_MENU|STAT_ITEM)) && status != STAT_BEGIN ) SYNTAX("Unexpected MENU statement") status = STAT_MENU; get_token(); AddMenu(tok); break; case SUBMENU : if ( !(status & STAT_MENU) || (status & STAT_SUBMENU) ) SYNTAX("Unexpected SUBMENU") status = STAT_SUBMENU; get_token(); AddSubMenu(tok); break; case ENDSUBMENU : if ( !(status & STAT_SUBMENU) || !(status & STAT_ITEM) ) SYNTAX("Unexpected ENDSUBMENU") EndSubMenu(); status = STAT_MENU|STAT_ITEM; break; case ITEM : if (status == STAT_BEGIN) SYNTAX("Unexpected ITEM") status |= STAT_ITEM; shortcut = pri = stack = 0; if (get_token()=='{') { /* command char */ shortcut = *fp++; if(get_token() != '}') SYNTAX("Missing closing '}'"); get_token(); } strcpy(itemstr,tok); t=get_token(); get_token(); switch( t ) { case WB : mode = 'w'; args[0] = '\0'; strcpy(cmd,tok); break; case RB : mode = 'r'; strcpy(cmd,tok); p = args; while ((c=*fp++) != '\n' && c ) *p++ = c; *p = '\0'; break; case CLI : mode = 'c'; strcpy(win,tok); while( (t=get_token())!=STR ) { get_token(); switch( t ) { case STACK : stack = Atol(tok); break; case PRI : pri = Atol(tok); if (pri < -128 || pri > 127) SYNTAX("Invalid priority") break; default : Err("STACK | PRI Expected"); return FALSE; } } strcpy(cmd,tok); p = args; while ((c=*fp++) != '\n' && c ) *p++ = c; *p = '\0'; break; default : Err("WB | RB | CLI Expected"); return FALSE; } AddEntry(itemstr, cmd, args, win, shortcut, mode, stack, pri); break; default : Err("Keyword expected"); return FALSE; } } return TRUE; } BOOL ParseMenus( void ) { BPTR lock,cfg; struct FileInfoBlock *fib; long bufsize,nch; BOOL stat; BOOL pb = TRUE; char msg[80]; if ( !(lock=Lock(CurCfg, ACCESS_READ)) ) { strcpy(msg, "Can't open "); strcat(msg, CurCfg); Warn(msg); return FALSE; } if (fib = (struct FileInfoBlock *) AllocMem(sizeof(struct FileInfoBlock), MEMF_PUBLIC|MEMF_CLEAR) ) { if (Examine(lock, (BPTR)fib)) { if ( fib->fib_DirEntryType < 0 ) { bufsize = fib->fib_Size+2; if (filebuf = AllocMem( bufsize , MEMF_PUBLIC|MEMF_CLEAR)) { cfg = Open(CurCfg, MODE_OLDFILE); nch = Read(cfg, filebuf, bufsize-1); Close(cfg); if (nch == fib->fib_Size) { fp = filebuf; stat = ParseConfig(); CleanUp(); /* setup items width */ pb = FALSE; } FreeMem(filebuf, bufsize); } } } FreeMem(fib, sizeof(struct FileInfoBlock)); } UnLock(lock); if (pb) { strcpy(msg, "Error reading "); strcat(msg, CurCfg); Warn(msg); return FALSE; } return stat; }