home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD2.img
/
d4xx
/
d419
/
parm
/
parse.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-12-18
|
7KB
|
345 lines
/*
* Parse.c - Copyright © 1990 by S.R. & P.C.
*
* Created: 16 Jun 1990
* Modified: 09 Dec 1990 17:38:26
*
* Make>> make
*/
#include "Tokens.h"
/***** external functions *****/
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 struct Menu Menu1;
extern char CurCfg[];
extern char CmdWindow[];
extern char ShellWindow[];
extern char ShellCmd[];
extern char WaitCmd[];
extern char TmpDir[];
extern long DefaultStack;
extern UBYTE menu_pen;
extern char *ReqTitle;
/***** local variables *****/
static char *KeyWordTab[] = {
NULL,
"ITEM",
"ARUN",
"RUN",
"SHELL",
"WB",
"CFG",
"WIN",
"PRI",
"STACK",
"MENU",
"SUBMENU",
"ENDSUBMENU",
"COLOR",
"CMDWIN",
"SHELLWIN",
"SHELLCMD",
"WAITCMD",
"TMPDIR"
};
/* status */
#define STAT_BEGIN 0
#define STAT_MENU 1
#define STAT_SUBMENU 2
#define STAT_ITEM 4
static char *FileBuffer, *CurrentLine, *NextLine, *Byte, *LastByte;
static short LineNum;
static char tok[200];
/* add the position of the error to the error message */
static void Err(char *msg)
{
SimpleRequest(ReqTitle, "%s\nLine %d, Char %ld", msg, LineNum, Byte-CurrentLine+1);
}
#define SYNTAX(msg) { Err(msg); return FALSE; }
static BOOL get_line(void)
{
register char *s,c;
s = CurrentLine = NextLine;
if (!*s)
return FALSE;
while ((c = *s++) != 10 && c);
if (c)
*(s-1) = '\0';
NextLine = s;
LineNum++;
Byte = CurrentLine;
return TRUE;
}
/*
* b is a register variable used to replace global Byte pointer in
* get_token() body. Then, Byte must be restored before leaving.
*/
static char get_token(void)
{
register char *p, *b, c;
short i;
char quote;
b = Byte;
while ((c = *b) == ' ' || c == '\t')
b++; /* skip extra spaces */
if (c == '#') /* comment */
return 0;
LastByte = b; /* save address of next token */
if (c < 32 || c == '{' || c == '}') {
Byte = (c) ? b+1 : b; /* prevent skipping of sentinel */
return c; /* '{', '}', '\0', or invalid char */
}
/* scan string */
p = tok;
if (c == '"') {
b++;
quote = TRUE;
}
else
quote = FALSE;
while ((quote && *b != '"' && *b) || (!quote && *b > 32 && *b != ';'))
*p++ = *b++;
*p = '\0';
if (quote)
b++; /* skip closing '"' */
for (i = 1; i <= MAX_KEYWORD; i++) {
if (!Strcmp(tok, KeyWordTab[i]))
break; /* arp Strcmp() is not case sensitive */
}
Byte = b;
return i;
}
/*
* Parse a line that may contain semicolons. Backslash ('\') is the override
* char. This function is called from ParseConfig() and from Command().
*/
void ParseLine(char *cmd)
{
register char *s,*d,c;
s = d = cmd;
while (c = *d++ = *s++) {
if (c == '\\')
*(d-1) = *s++;
else if (c == ';')
*(d-1) = '\n';
}
}
static BOOL ParseConfig(void)
{
char t, shortcut, mode;
long stack;
short pri;
USHORT status = STAT_BEGIN;
char *args, *cmd, *win;
char itemstr[80], cmdstr[100], winstr[80];
FreeMenus();
while( get_line() ) {
switch (t = get_token()) {
case TOK_MENU:
if (!(status & (STAT_MENU | STAT_ITEM)) && status != STAT_BEGIN)
SYNTAX("Unexpected MENU")
status = STAT_MENU;
if (get_token())
AddMenu(tok);
else
SYNTAX("Unexpected end of line");
break;
case TOK_SUBMENU:
if (!(status & STAT_MENU) || (status & STAT_SUBMENU))
SYNTAX("Unexpected SUBMENU")
status = STAT_SUBMENU;
if (get_token())
AddSubMenu(tok);
else
SYNTAX("Unexpected end of line");
break;
case TOK_ENDSUBMENU:
if (!(status & STAT_SUBMENU) || !(status & STAT_ITEM))
SYNTAX("Unexpected ENDSUBMENU")
EndSubMenu();
status = STAT_MENU | STAT_ITEM;
break;
case TOK_ITEM:
if (status == STAT_BEGIN)
SYNTAX("Unexpected ITEM")
status |= STAT_ITEM;
shortcut = pri = 0;
stack = DefaultStack;
win = args = NULL;
cmd = cmdstr;
if (get_token() == '{') { /* command char */
shortcut = *Byte++;
if (get_token() != '}')
SYNTAX("Missing closing '}'");
get_token();
}
strcpy(itemstr, tok);
switch (mode = get_token()) {
case TOK_WB:
stack = 0; /* Tell WBRun to take icon stack as default */
case TOK_SHELL:
case TOK_ARUN:
case TOK_RUN:
while ((t = get_token())==TOK_WIN || t==TOK_STACK || t==TOK_PRI) {
if (!get_token())
SYNTAX("Unexpected end of line");
switch (t) {
case TOK_WIN:
if (mode == TOK_RUN || mode == TOK_WB)
SYNTAX("WIN not allowed in this mode")
strcpy(winstr, tok);
win = winstr;
break;
case TOK_STACK:
stack = Atol(tok);
if (IoErr() || stack < 2000)
SYNTAX("Invalid stack")
break;
case TOK_PRI:
pri = Atol(tok);
if (IoErr() || pri < -128 || pri > 127)
SYNTAX("Priority out of range")
break;
}
}
if (!t)
SYNTAX("Unexpected end of line");
switch(mode) {
case TOK_ARUN:
args = Byte;
case TOK_WB:
strcpy(cmdstr, tok);
break;
case TOK_SHELL:
ParseLine(LastByte);
default: /* RUN mode */
cmd = LastByte;
}
break;
case TOK_CFG:
if (!get_token())
SYNTAX("Unexpected end of line");
strcpy(cmdstr, tok);
break;
default:
Err("WB, ARUN, RUN, SHELL or CFG Expected");
return FALSE;
}
AddEntry(itemstr, cmd, args, win, shortcut, mode, stack, pri);
break;
case TOK_COLOR:
get_token();
menu_pen = ((menu_pen = Atol(tok)) == Win->BlockPen) ? Win->DetailPen : menu_pen; /* control if blockpen and detailpen are different */
break;
case TOK_CMDWIN:
if (get_token())
strcpy(CmdWindow, tok);
break;
case TOK_SHELLWIN:
if (get_token())
strcpy(ShellWindow, tok);
break;
case TOK_SHELLCMD:
if (get_token())
strcpy(ShellCmd, tok);
break;
case TOK_WAITCMD:
if (get_token())
strcpy(WaitCmd, tok);
break;
case TOK_TMPDIR:
if (get_token())
strcpy(TmpDir, tok);
break;
default:
if (t) /* allow empty lines */
SYNTAX("Keyword expected")
}
}
return TRUE;
}
BOOL ParseMenus(void)
{
BPTR lock, cfg;
struct FileInfoBlock *fib;
long bufsize, nch;
BOOL stat;
BOOL pb = TRUE;
if (!(lock = Lock(CurCfg, ACCESS_READ))) {
SimpleRequest(ReqTitle,"Can't open '%s'",CurCfg);
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 (FileBuffer = AllocMem(bufsize, MEMF_PUBLIC|MEMF_CLEAR)) {
cfg = Open(CurCfg, MODE_OLDFILE);
nch = Read(cfg, FileBuffer, bufsize-1);
Close(cfg);
if (nch == fib->fib_Size) {
NextLine = FileBuffer;
LineNum = 0;
stat = ParseConfig();
CleanUp(); /* setup items width */
pb = FALSE;
}
FreeMem(FileBuffer, bufsize);
}
}
}
FreeMem(fib, sizeof(struct FileInfoBlock));
}
UnLock(lock);
if (pb) {
SimpleRequest(ReqTitle, "Error reading '%s'", CurCfg);
return FALSE;
}
return stat;
}