home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 632.lha / ParM_v3.6 / ParM_Src.lzh / ParM_Src / Parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-13  |  9.3 KB  |  396 lines

  1. /*
  2.  *    Parse.c - Copyright © 1990 by S.R. & P.C.
  3.  *
  4.  *    Created:    16 Jun 1990
  5.  *    Modified:    12 Feb 1992  20:47:41
  6.  *
  7.  *    Make>> make
  8.  */
  9.  
  10. #include "ParMBase.h"
  11.  
  12. extern struct Extended_MenuItem *AllocItem(struct ParMConfig *PCfg, char *itemstr);
  13. extern BOOL AddMenu(struct ParMConfig *PCfg, char *str);
  14. extern BOOL AddSubMenu(struct ParMConfig *PCfg, char *substr);
  15. extern void EndSubMenu(struct ParMConfig *PCfg);
  16. extern BOOL AddEntry(struct ParMConfig *PCfg, char *item, char *cmd, char *args, char *win, char shortcut, char mode, long stk, short pri, USHORT Flags);
  17. extern BOOL AddAutoCmd(struct ParMConfig *PCfg, ULONG FileType, char *cmd, char *args, char *win, char mode, long stk, short pri, USHORT Flags);
  18. extern BOOL AddParMEvent(struct Window *Win, USHORT Code, USHORT Qual, USHORT Flags);
  19.  
  20.  
  21. struct StaticData {
  22.     char *FileBuffer, *CurrentLine, *NextLine, *Byte, *LastByte;
  23.     short LineNum;
  24.     char tok[200];
  25. };
  26.  
  27.  
  28. /*****                 local variables                    *****/
  29.  
  30. static char *KeyWordTab[] = {
  31.     NULL,
  32.     "ITEM",
  33.     "ARUN",
  34.     "RUN",
  35.     "SHELL",
  36.     "WB",
  37.     "CFG",
  38.     "WIN",
  39.     "PRI",
  40.     "STACK",
  41.     "MENU",
  42.     "SUBMENU",
  43.     "ENDSUBMENU",
  44.     "COLOR",
  45.     "CMDWIN",
  46.     "SHELLWIN",
  47.     "SHELLCMD",
  48.     "WAITCMD",
  49.     "TMPDIR",
  50.     "SHORTCUTQUAL",
  51.     "ACTIVATEKEY",
  52.     "PASSTHROUGH",
  53.     "SCREENTOFRONT",
  54.     "NOCHECK",
  55.     "WBTF",
  56.     "AUTOCMD"
  57. };
  58.  
  59. /* status  */
  60.  
  61. #define STAT_BEGIN        0
  62. #define STAT_MENU        1
  63. #define STAT_SUBMENU    2
  64. #define STAT_ITEM        4
  65.  
  66.  
  67.  
  68. /* add the position of the error to the error message */
  69.  
  70. static void Err(struct ParMConfig *PCfg, struct StaticData *SD, char *msg)
  71. {
  72.     SimpleRequest(PCfg->ReqTitle, "%s\nLine %d, Char %ld", msg, SD->LineNum, SD->Byte-SD->CurrentLine+1);
  73. }
  74.  
  75. #define SYNTAX(msg) { Err(PCfg, SD, msg); return FALSE; }
  76.  
  77.  
  78. /*
  79.  *    Parse a line that may contain semicolons. Backslash ('\') is the override
  80.  *    char. This function is called from ParseConfig() and from Command().
  81.  */
  82.  
  83. void ParseLine(char *cmd)
  84. {
  85.     char *s,*d,c;
  86.  
  87.     s = d = cmd;
  88.     while (c = *d++ = *s++) {
  89.         if (c == '\\')
  90.             *(d-1) = *s++;
  91.         else if (c == ';')
  92.             *(d-1) = '\n';
  93.     }
  94. }
  95.  
  96.  
  97. static BOOL get_line(struct StaticData *SD)
  98. {
  99.     register char *s,c;
  100.  
  101.     s = SD->CurrentLine = SD->NextLine;
  102.     if (!*s)
  103.         return FALSE;
  104.     while ((c = *s++) != 10 && c);
  105.     if (c)
  106.         *(s-1) = '\0';
  107.     SD->NextLine = s;
  108.     SD->LineNum++;
  109.     SD->Byte = SD->CurrentLine;
  110.     return TRUE;
  111. }
  112.  
  113.  
  114. /*
  115.  *    b is a register variable used to replace global Byte pointer in
  116.  *    get_token() body. Then, Byte must be restored before leaving.
  117.  */
  118.  
  119. static char get_token(struct StaticData *SD)
  120. {
  121.     register char *p, *b, c;
  122.     short i;
  123.     char quote;
  124.  
  125.     b = SD->Byte;
  126.     while ((c = *b) == ' ' || c == '\t')
  127.         b++;            /* skip extra spaces */
  128.     if (c == '#')        /* comment */
  129.         return 0;
  130.     SD->LastByte = b;    /* save address of next token */
  131.     if (c < 32 || c == '{' || c == '}') {
  132.         SD->Byte = (c) ? b+1 : b;    /* prevent skipping of sentinel */
  133.         return c;                    /* '{', '}', '\0', or invalid char */
  134.     }
  135.     /* scan string */
  136.     p = SD->tok;
  137.     if (c == '"') {
  138.         b++;
  139.         quote = TRUE;
  140.     }
  141.     else
  142.         quote = FALSE;
  143.     while ((quote && *b != '"' && *b) || (!quote && *b > 32 && *b != ';'))
  144.         *p++ = *b++;
  145.     *p = '\0';
  146.     if (quote)
  147.         b++;    /* skip closing '"' */
  148.     for (i = 1; i <= MAX_KEYWORD; i++) {
  149.         if (!Strcmp(SD->tok, KeyWordTab[i]))
  150.             break;    /* arp Strcmp() is not case sensitive */
  151.     }
  152.     SD->Byte = b;
  153.     return i;
  154. }
  155.  
  156.  
  157. static BOOL ParseConfig(struct ParMConfig *PCfg, struct StaticData *SD)
  158. {
  159.     char t, shortcut, mode, token;
  160.     long stack;
  161.     short pri, i;
  162.     USHORT status = STAT_BEGIN, Flags, Key[2];    /* Flags used for both ITEM and ACTIVATEKEY */
  163.     ULONG FileType;
  164.     char *args, *cmd, *win;
  165.     char itemstr[80], cmdstr[100], winstr[80];
  166.  
  167.     FreeMenus(PCfg);
  168.     while(get_line(SD)) {
  169.         switch (t = get_token(SD)) {
  170.         case 0:        /* allow empty lines */
  171.             break;
  172.         case TOK_MENU:
  173.             if (!(status & (STAT_MENU | STAT_ITEM)) && status != STAT_BEGIN)
  174.                 SYNTAX("Unexpected MENU")
  175.             status = STAT_MENU;
  176.             if (get_token(SD))
  177.                 AddMenu(PCfg, SD->tok);
  178.             else
  179.                 SYNTAX("Unexpected end of line");
  180.             break;
  181.         case TOK_SUBMENU:
  182.             if (!(status & STAT_MENU) || (status & STAT_SUBMENU))
  183.                 SYNTAX("Unexpected SUBMENU")
  184.             status = STAT_SUBMENU;
  185.             if (get_token(SD))
  186.                 AddSubMenu(PCfg, SD->tok);
  187.             else
  188.                 SYNTAX("Unexpected end of line");
  189.             break;
  190.         case TOK_ENDSUBMENU:
  191.             if (!(status & STAT_SUBMENU) || !(status & STAT_ITEM))
  192.                 SYNTAX("Unexpected ENDSUBMENU")
  193.             PCfg->CurrentItem = &PCfg->CurrentSubMenu->NextItem;
  194.             status = STAT_MENU | STAT_ITEM;
  195.             break;
  196.         case TOK_ITEM:
  197.         case TOK_AUTOCMD:
  198.             Flags = 0;
  199.             shortcut = pri = 0;
  200.             stack = PCfg->DefaultStack;
  201.             win = args = NULL;
  202.             cmd = cmdstr;
  203.             token = t;        /* save token to know if AddItem() or AddAutoCmd() a few lines below */
  204.             if (t == TOK_ITEM) {
  205.                 if (status == STAT_BEGIN)
  206.                     SYNTAX("Unexpected ITEM")
  207.                 status |= STAT_ITEM;
  208.                 if (get_token(SD) == '{') {    /* command char */
  209.                     shortcut = *SD->Byte++;
  210.                     if (get_token(SD) != '}')
  211.                         SYNTAX("Missing closing '}'");
  212.                     get_token(SD);
  213.                 }
  214.                 strcpy(itemstr, SD->tok);
  215.             }
  216.             else {    /* TOK_AUTOCMD */
  217.                 if (!PCfg->GetFileTypeID) {
  218.                     Err(PCfg, SD, "AUTOCMD not allowed in this tool");
  219.                     break;
  220.                 }
  221.                 if (!get_token(SD))
  222.                     SYNTAX("Unexpected end of line");
  223.                 FileType = PCfg->GetFileTypeID(SD->tok);
  224.                 if (FileType == ~0L)
  225.                     SYNTAX("Unknown file type")
  226.             }
  227.             if ((t = get_token(SD)) == TOK_WBTF) {
  228.                 Flags |= EMIF_WBTOFRONT;
  229.                 mode = get_token(SD);
  230.             }
  231.             else
  232.                 mode = t;
  233.             switch (mode) {
  234.             case TOK_WB:
  235.                 stack = 0;    /* Tell WBRun to take icon stack as default */
  236.             case TOK_SHELL:
  237.             case TOK_ARUN:
  238.             case TOK_RUN:
  239.                 while ((t = get_token(SD))==TOK_WIN || t==TOK_STACK || t==TOK_PRI) {
  240.                     if (!get_token(SD))
  241.                         SYNTAX("Unexpected end of line")
  242.                     switch (t) {
  243.                     case TOK_WIN:
  244.                         if (mode == TOK_WB)
  245.                             SYNTAX("WIN not allowed in WB mode")
  246.                         strcpy(winstr, SD->tok);
  247.                         win = winstr;
  248.                         break;
  249.                     case TOK_STACK:
  250.                         stack = Atol(SD->tok);
  251.                         if (IoErr() || stack < 2000)
  252.                             SYNTAX("Invalid stack")
  253.                         break;
  254.                     case TOK_PRI:
  255.                         pri = Atol(SD->tok);
  256.                         if (IoErr() || pri < -128 || pri > 127)
  257.                             SYNTAX("Priority out of range")
  258.                         break;
  259.                     }
  260.                 }
  261.                 if (!t)
  262.                     SYNTAX("Unexpected end of line")
  263.                 switch(mode) {
  264.                 case TOK_ARUN:
  265.                     args = SD->Byte;
  266.                 case TOK_WB:
  267.                     strcpy(cmdstr, SD->tok);
  268.                     break;
  269.                 default:    /* RUN & SHELL modes */
  270.                     ParseLine(SD->LastByte);
  271.                     cmd = SD->LastByte;
  272.                 }
  273.                 break;
  274.             case TOK_CFG:
  275.                 if (!get_token(SD))
  276.                     SYNTAX("Unexpected end of line")
  277.                 strcpy(cmdstr, SD->tok);
  278.                 break;
  279.             default:
  280.                 SYNTAX("WB, ARUN, RUN, SHELL or CFG Expected")
  281.             }
  282.             if (token == TOK_AUTOCMD) {
  283.                 if (!AddAutoCmd(PCfg, FileType, cmd, args, win, mode, stack, pri, Flags))
  284.                     return FALSE;
  285.             }
  286.             else if (!AddEntry(PCfg, itemstr, cmd, args, win, shortcut, mode, stack, pri, Flags))
  287.                 return FALSE;
  288.             break;
  289.         case TOK_ACTIVATEKEY:
  290.             Flags = 0;
  291.             while ((t = get_token(SD))==TOK_PASSTHROUGH || t==TOK_SCREENTOFRONT || t==TOK_NOCHECK) {
  292.                 switch (t) {
  293.                 case TOK_PASSTHROUGH:
  294.                     Flags |= PEF_PASSTHROUGH;
  295.                     break;
  296.                 case TOK_SCREENTOFRONT:
  297.                     Flags |= PEF_SCREENTOFRONT;
  298.                     break;
  299.                 case TOK_NOCHECK:
  300.                     Flags |= PEF_NOCHECK;
  301.                     break;
  302.                 }
  303.             }
  304.             for( i=0 ; i<2 ; i++ ) {
  305.                 if (t) {
  306.                     Key[i] = Atol(SD->tok);
  307.                     if (IoErr())
  308.                         SYNTAX("Invalid Key")
  309.                 }
  310.                 else
  311.                     SYNTAX("Unexpected end of line")
  312.                 t = get_token(SD);
  313.             }
  314.             /* Key[0] = Qualifier, Key[1] = Code */
  315.             if (!AddParMEvent(PCfg->Win, Key[1], Key[0], Flags))
  316.                 Err(PCfg, SD, "Key already used");
  317.             break;
  318.         case TOK_STR:
  319.             SYNTAX("Keyword expected")
  320.             break;
  321.         default:
  322.             if (get_token(SD)) {
  323.                 switch(t) {
  324.                 case TOK_COLOR:
  325.                     /* control if blockpen and detailpen are different */
  326.                     PCfg->MenuPen = ((PCfg->MenuPen = Atol(SD->tok)) == PCfg->Win->BlockPen) ? PCfg->Win->DetailPen : PCfg->MenuPen;
  327.                     break;
  328.                 case TOK_CMDWIN:
  329.                     strcpy(PCfg->CmdWindow, SD->tok);
  330.                     break;
  331.                 case TOK_SHELLWIN:
  332.                     strcpy(PCfg->ShellWindow, SD->tok);
  333.                     break;
  334.                 case TOK_SHELLCMD:
  335.                     strcpy(PCfg->ShellCmd, SD->LastByte);
  336.                     break;
  337.                 case TOK_WAITCMD:
  338.                     strcpy(PCfg->WaitCmd, SD->LastByte);
  339.                     break;
  340.                 case TOK_TMPDIR:
  341.                     strcpy(PCfg->TmpDir, SD->tok);
  342.                     break;
  343.                 case TOK_SHORTCUTQUAL:
  344.                     PCfg->ShortCutQual = (USHORT)Atol(SD->tok);
  345.                     if (IoErr()) {
  346.                         PCfg->ShortCutQual = 0;
  347.                         SYNTAX("Invalid qualifier")
  348.                     }
  349.                     break;
  350.                 }
  351.             }
  352.             else
  353.                 SYNTAX("Missing argument")
  354.         }
  355.     }
  356.     return TRUE;
  357. }
  358.  
  359.  
  360. long ParseMenus(struct ParMConfig *PCfg)
  361. {
  362.     struct ParMBase *ParMBase;
  363.     struct StaticData StaticData;
  364.     struct TextAttr MenuFont;
  365.     BPTR cfg;
  366.     long FileSize;
  367.     BOOL stat;
  368.     BOOL rw = FALSE;    /* assume the worst */
  369.  
  370.     if (cfg = Open(PCfg->CurCfg, MODE_OLDFILE)) {
  371.         Seek(cfg, 0, OFFSET_END);
  372.         if ((FileSize = Seek(cfg, 0, OFFSET_BEGINNING)) > 0) {
  373.             if (StaticData.FileBuffer = AllocMem(FileSize+1, MEMF_PUBLIC|MEMF_CLEAR)) {
  374.                 if (Read(cfg, StaticData.FileBuffer, FileSize) == FileSize)
  375.                     rw = TRUE;
  376.                 Close(cfg);
  377.                 if (rw) {
  378.                     StaticData.NextLine = StaticData.FileBuffer;
  379.                     StaticData.LineNum = 0;
  380.                     stat = ParseConfig(PCfg, &StaticData);
  381.                     AskFont(&PCfg->Win->WScreen->RastPort, &MenuFont);    /* Get default screen font */
  382.                     NewCleanUp(PCfg->LinkMenu->NextMenu, &MenuFont, PCfg->LinkMenu->LeftEdge + PCfg->LinkMenu->Width);
  383.                 }
  384.                 FreeMem(StaticData.FileBuffer, FileSize+1);
  385.             }
  386.         }
  387.     }
  388.     if (!rw) {
  389.         SimpleRequest(PCfg->ReqTitle, "Couldn't open/read \"%s\"", PCfg->CurCfg);
  390.         return FALSE;
  391.     }
  392.     return stat;
  393. }
  394.  
  395.  
  396.