home *** CD-ROM | disk | FTP | other *** search
- /*
- * Parse.c - Copyright © 1990 by S.R. & P.C.
- *
- * Created: 16 Jun 1990
- * Modified: 28 Jul 1991 18:22:05
- *
- * Make>> make
- */
-
- #include "ParMBase.h"
-
- extern struct Extended_MenuItem *AllocItem(struct ParMConfig *PCfg, char *itemstr);
- extern BOOL AddMenu(struct ParMConfig *PCfg, char *str);
- extern BOOL AddSubMenu(struct ParMConfig *PCfg, char *substr);
- extern void EndSubMenu(struct ParMConfig *PCfg);
- extern BOOL AddEntry(struct ParMConfig *PCfg, char *item, char *cmd, char *args, char *win, char shortcut, char mode, long stk, short pri);
- extern BOOL AddParMEvent(struct Window *Win, USHORT Code, USHORT Qual, USHORT Flags);
-
-
- struct StaticData {
- char *FileBuffer, *CurrentLine, *NextLine, *Byte, *LastByte;
- short LineNum;
- char tok[200];
- };
-
-
- /***** local variables *****/
-
- static char *KeyWordTab[] = {
- NULL,
- "ITEM",
- "ARUN",
- "RUN",
- "SHELL",
- "WB",
- "CFG",
- "WIN",
- "PRI",
- "STACK",
- "MENU",
- "SUBMENU",
- "ENDSUBMENU",
- "COLOR",
- "CMDWIN",
- "SHELLWIN",
- "SHELLCMD",
- "WAITCMD",
- "TMPDIR",
- "SHORTCUTQUAL",
- "ACTIVATEKEY",
- "PASSTHROUGH",
- "SCREENTOFRONT",
- "NOCHECK"
- };
-
- /* status */
-
- #define STAT_BEGIN 0
- #define STAT_MENU 1
- #define STAT_SUBMENU 2
- #define STAT_ITEM 4
-
-
-
- /* add the position of the error to the error message */
-
- static void Err(struct ParMConfig *PCfg, struct StaticData *SD, char *msg)
- {
- SimpleRequest(PCfg->ReqTitle, "%s\nLine %d, Char %ld", msg, SD->LineNum, SD->Byte-SD->CurrentLine+1);
- }
-
- #define SYNTAX(msg) { Err(PCfg, SD, msg); return FALSE; }
-
-
- /*
- * 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)
- {
- struct ParMBase *ParMBase;
- char *s,*d,c;
-
- s = d = cmd;
- while (c = *d++ = *s++) {
- if (c == '\\')
- *(d-1) = *s++;
- else if (c == ';')
- *(d-1) = '\n';
- }
- }
-
-
- static BOOL get_line(struct StaticData *SD)
- {
- register char *s,c;
-
- s = SD->CurrentLine = SD->NextLine;
- if (!*s)
- return FALSE;
- while ((c = *s++) != 10 && c);
- if (c)
- *(s-1) = '\0';
- SD->NextLine = s;
- SD->LineNum++;
- SD->Byte = SD->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(struct StaticData *SD)
- {
- register char *p, *b, c;
- short i;
- char quote;
-
- b = SD->Byte;
- while ((c = *b) == ' ' || c == '\t')
- b++; /* skip extra spaces */
- if (c == '#') /* comment */
- return 0;
- SD->LastByte = b; /* save address of next token */
- if (c < 32 || c == '{' || c == '}') {
- SD->Byte = (c) ? b+1 : b; /* prevent skipping of sentinel */
- return c; /* '{', '}', '\0', or invalid char */
- }
- /* scan string */
- p = SD->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(SD->tok, KeyWordTab[i]))
- break; /* arp Strcmp() is not case sensitive */
- }
- SD->Byte = b;
- return i;
- }
-
-
- static BOOL ParseConfig(struct ParMConfig *PCfg, struct StaticData *SD)
- {
- char t, shortcut, mode;
- long stack;
- short pri, i;
- USHORT status = STAT_BEGIN, Flags, Key[2];
- char *args, *cmd, *win;
- char itemstr[80], cmdstr[100], winstr[80];
-
- FreeMenus(PCfg);
- while(get_line(SD)) {
- switch (t = get_token(SD)) {
- case 0: /* allow empty lines */
- break;
- case TOK_MENU:
- if (!(status & (STAT_MENU | STAT_ITEM)) && status != STAT_BEGIN)
- SYNTAX("Unexpected MENU")
- status = STAT_MENU;
- if (get_token(SD))
- AddMenu(PCfg, SD->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(SD))
- AddSubMenu(PCfg, SD->tok);
- else
- SYNTAX("Unexpected end of line");
- break;
- case TOK_ENDSUBMENU:
- if (!(status & STAT_SUBMENU) || !(status & STAT_ITEM))
- SYNTAX("Unexpected ENDSUBMENU")
- PCfg->CurrentItem = &PCfg->CurrentSubMenu->NextItem;
- status = STAT_MENU | STAT_ITEM;
- break;
- case TOK_ITEM:
- if (status == STAT_BEGIN)
- SYNTAX("Unexpected ITEM")
- status |= STAT_ITEM;
- shortcut = pri = 0;
- stack = PCfg->DefaultStack;
- win = args = NULL;
- cmd = cmdstr;
- if (get_token(SD) == '{') { /* command char */
- shortcut = *SD->Byte++;
- if (get_token(SD) != '}')
- SYNTAX("Missing closing '}'");
- get_token(SD);
- }
- strcpy(itemstr, SD->tok);
- switch (mode = get_token(SD)) {
- 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(SD))==TOK_WIN || t==TOK_STACK || t==TOK_PRI) {
- if (!get_token(SD))
- 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, SD->tok);
- win = winstr;
- break;
- case TOK_STACK:
- stack = Atol(SD->tok);
- if (IoErr() || stack < 2000)
- SYNTAX("Invalid stack")
- break;
- case TOK_PRI:
- pri = Atol(SD->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 = SD->Byte;
- case TOK_WB:
- strcpy(cmdstr, SD->tok);
- break;
- default: /* RUN & SHELL modes */
- ParseLine(SD->LastByte);
- cmd = SD->LastByte;
- }
- break;
- case TOK_CFG:
- if (!get_token(SD))
- SYNTAX("Unexpected end of line")
- strcpy(cmdstr, SD->tok);
- break;
- default:
- SYNTAX("WB, ARUN, RUN, SHELL or CFG Expected")
- }
- if (!AddEntry(PCfg, itemstr, cmd, args, win, shortcut, mode, stack, pri))
- return FALSE;
- break;
- case TOK_ACTIVATEKEY:
- Flags = 0;
- while ((t = get_token(SD))==TOK_PASSTHROUGH || t==TOK_SCREENTOFRONT || t==TOK_NOCHECK) {
- switch (t) {
- case TOK_PASSTHROUGH:
- Flags |= PEF_PASSTHROUGH;
- break;
- case TOK_SCREENTOFRONT:
- Flags |= PEF_SCREENTOFRONT;
- break;
- case TOK_NOCHECK:
- Flags |= PEF_NOCHECK;
- break;
- }
- }
- for( i=0 ; i<2 ; i++ ) {
- if (t) {
- Key[i] = Atol(SD->tok);
- if (IoErr())
- SYNTAX("Invalid Key")
- }
- else
- SYNTAX("Unexpected end of line")
- t = get_token(SD);
- }
- /* Key[0] = Qualifier, Key[1] = Code */
- if (!AddParMEvent(PCfg->Win, Key[1], Key[0], Flags))
- Err(PCfg, SD, "Key already used");
- break;
- case TOK_STR:
- SYNTAX("Keyword expected")
- break;
- default:
- if (get_token(SD)) {
- switch(t) {
- case TOK_COLOR:
- /* control if blockpen and detailpen are different */
- PCfg->MenuPen = ((PCfg->MenuPen = Atol(SD->tok)) == PCfg->Win->BlockPen) ? PCfg->Win->DetailPen : PCfg->MenuPen;
- break;
- case TOK_CMDWIN:
- strcpy(PCfg->CmdWindow, SD->tok);
- break;
- case TOK_SHELLWIN:
- strcpy(PCfg->ShellWindow, SD->tok);
- break;
- case TOK_SHELLCMD:
- strcpy(PCfg->ShellCmd, SD->LastByte);
- break;
- case TOK_WAITCMD:
- strcpy(PCfg->WaitCmd, SD->LastByte);
- break;
- case TOK_TMPDIR:
- strcpy(PCfg->TmpDir, SD->tok);
- break;
- case TOK_SHORTCUTQUAL:
- PCfg->ShortCutQual = (USHORT)Atol(SD->tok);
- if (IoErr()) {
- PCfg->ShortCutQual = 0;
- SYNTAX("Invalid qualifier");
- }
- break;
- }
- }
- else
- SYNTAX("Missing argument")
- }
- }
- return TRUE;
- }
-
-
- long ParseMenus(struct ParMConfig *PCfg)
- {
- struct ParMBase *ParMBase;
- struct StaticData StaticData;
- BPTR cfg;
- long FileSize;
- BOOL stat;
- BOOL pb = TRUE;
-
- if (cfg = Open(PCfg->CurCfg, MODE_OLDFILE)) {
- Seek(cfg, 0, OFFSET_END);
- if ((FileSize = Seek(cfg, 0, OFFSET_BEGINNING)) > 0) {
- if (StaticData.FileBuffer = AllocMem(FileSize+1, MEMF_PUBLIC|MEMF_CLEAR)) {
- if (Read(cfg, StaticData.FileBuffer, FileSize) == FileSize) {
- StaticData.NextLine = StaticData.FileBuffer;
- StaticData.LineNum = 0;
- stat = ParseConfig(PCfg, &StaticData);
- CleanUp(PCfg->LinkMenu->NextMenu, PCfg->LinkMenu->LeftEdge + PCfg->LinkMenu->Width, PCfg->ItemHeight);
- pb = FALSE;
- }
- Close(cfg);
- FreeMem(StaticData.FileBuffer, FileSize+1);
- }
- }
- }
- if (pb) {
- SimpleRequest(PCfg->ReqTitle, "Couldn't open/read \"%s\"", PCfg->CurCfg);
- return FALSE;
- }
- return stat;
- }
-
-
-