home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / AZTEC-C / COMND004.ARK / CMDPF2.C < prev    next >
C/C++ Source or Header  |  1986-06-17  |  10KB  |  413 lines

  1. /*    cmdpf2.c    COMND module; function parsing routines, set # 2
  2.  
  3.     Copyright (C) 1985 Mark E. Mallett
  4.  
  5.     Permission is hereby granted to distribute this file indiscriminately.
  6.  
  7.     This file contains parsing routines for various individual
  8. function codes.
  9.  
  10. Edit history
  11.  
  12. When    Who    What
  13. ------    ---    --------------------------------
  14. 84xxxx    MEM    Create file.
  15.  
  16.     Routines included:
  17.  
  18.         CFPnum        Number parsing
  19.         CFPswi        Switch
  20.         CFPtok        Parse an expected token
  21.         CFPtxt        Parse text to end of line
  22.         CFPuqs        Parse unquoted string
  23.  
  24. */
  25.  
  26.  
  27. #include "stdio.h"            /* Standard system defs */
  28. #include "comnd.h"            /* COMND interface definitions */
  29. #include "comndi.h"            /* COMND internal definitions */
  30.  
  31.  
  32. /* External routines */
  33.  
  34.  
  35. /* External data */
  36.  
  37. extern    int    CMDbel;            /* Beep request flag */
  38.  
  39. /* Internal (public) routines */
  40.  
  41.  
  42.  
  43. /* Internal (public) data */
  44.  
  45.  
  46. /* Local (static) data */
  47.  
  48. static    char    *Numhlp[] = {        /* help texts for _CMNUM */
  49.             "binary number",
  50.             "number in base 3",
  51.             "number in base 4",
  52.             "number in base 5",
  53.             "number in base 6",
  54.             "number in base 7",
  55.             "octal number",
  56.             "number in base 9",
  57.             "decimal number",
  58.             "number in base 11",
  59.             "number in base 12",
  60.             "number in base 13",
  61.             "number in base 14",
  62.             "number in base 15",
  63.             "hexadecimal number"
  64.                 };
  65. /*
  66.  
  67. *//* CFPnum (CSBptr, CFBptr, ccptr)
  68.  
  69.     Function parse for type=_CMNUM, number.
  70.  
  71. This routine attempts a parse of a number thought to be next in the
  72. command stream.  CFB_DAT of the command function block contains the
  73. radix to use, if zero then 10 is assumed.
  74.  
  75. Accepts :
  76.  
  77.     CSBptr        Address of command state block
  78.     CFBptr        Address of command function block
  79.     ccptr        Address of CC table (where appropriate)
  80.  
  81.  
  82. Returns :
  83.  
  84.     <value>        Parse status, _CPxxx as defined in comndi.h.
  85.  
  86. */
  87.  
  88. CFPnum (CSBptr, CFBptr, ccptr)
  89.  
  90. CSB        *CSBptr;        /* Addr of command state block */
  91. CFB        *CFBptr;        /* Addr of command function block */
  92. WORD        *ccptr;            /* Addr of CC table */
  93.  
  94. {
  95. IND    int    ec;            /* End char (action char, if any) */
  96. IND    BYTE    c;            /* A character */
  97. IND    int    cix;            /* Relative parse index */
  98. IND    int    icix;            /* Initial relative parse index */
  99. IND    int    base;            /* radix */
  100. IND    int    val;            /* Value */
  101. IND    int    sign;            /* Sign (-1, 0, 1) */
  102.  
  103. base = CFBptr -> CFB_DAT;        /* Get base */
  104. if (base == 0)                /* If zero */
  105.     base = 10;                /*  use decimal */
  106. if ((base < 2) || (base > 16))        /* If invalid base */
  107.     {
  108.     CSBptr -> CSB_RCD = _CRBAS;        /* Invalid base */
  109.     return (_CPABT);            /* Abort */
  110.     }
  111.  
  112. /* Get the number. */
  113.  
  114. icix = cix = CMDspc (CSBptr);        /* Init command index */
  115. val = 0;                /* Value is zero */
  116. sign = 0;                /* No sign seen */
  117.  
  118. while (TRUE)                /* Collect... */
  119.     {
  120.     ec = CMDgcc (CSBptr, cix);        /* Get next character */
  121.     if (sign == 0)            /* Check sign ? */
  122.     {
  123.     if (c == '-')
  124.         sign = -1;
  125.     if (c == '+')
  126.         sign = 1;
  127.     if (sign != 0)
  128.         {
  129.         cix++;
  130.         continue;
  131.         }
  132.     }
  133.  
  134.     c = ec-'0';                /* Get binary equivalent */
  135.     if (c > 9)                /* If it wasn't decimal */
  136.     c = (toupper(ec)-'A')+10;    /*  use alpha set */
  137.     if ((c < 0) || (c >= base))        /* If invalid digit */
  138.     break;                /*  then be done */
  139.  
  140.     if (base == 2)            /* optimize for shifts */
  141.     val <<= 1;
  142.     else if (base == 4)
  143.     val <<= 2;
  144.     else if (base == 8)
  145.     val <<= 3;
  146.     else if (base == 16)
  147.     val <<= 4;
  148.     else
  149.     val = val*base;
  150.     val = val + c;            /* Add in new value */
  151.     cix++;                /* Bump counter */
  152.     }
  153.  
  154. /* Here on no more digits */
  155.  
  156. if (sign < 0)                /* If negative */
  157.     val = -val;
  158.  
  159. CSBptr -> CSB_RVL._INT = val;        /* Stick it in there, in case */
  160.  
  161. switch (ec)                /* Dispatch on final char */
  162.     {
  163.     case _CCCMP:            /* Complete? */
  164.     if (cix)            /* If anything */
  165.         {
  166.         CMDcpl (CSBptr, " ");    /*  add a space */
  167.         return (_CPCPE);
  168.         }
  169.     CMDbel++;            /* Indicate our desire to beep */
  170.     return (_CPAGN);        /* Might work.. */
  171.  
  172.     case _CCINC:            /* Incomplete? */
  173.     return (_CPAGN);        /* Ok so far, try when you get more */
  174.  
  175.     case _CCHLP:            /* Help... */
  176.     CMDhlp (CFBptr, Numhlp[base-2]);
  177.     return (_CPGVH);        /* Gave help */
  178.  
  179.     default:                /* Anything else */
  180.     if (cix > icix)            /* If parsed anything */
  181.         {
  182.         CMDcpt (CSBptr, cix);    /* Parse is ok */
  183.         return (_CPSUCC);        /* Return it. */
  184.         }
  185.     return (_CPNOP);        /* Otherwise not */
  186.     }
  187. }
  188. /*
  189.  
  190. *//* CFPswi (CSBptr, CFBptr, ccptr)
  191.  
  192.     Function parse for type=_CMSWI, switch.
  193.  
  194. This routine performs a parse for a switch next in the command
  195. line.  This is like KWD, except that a slash must come first.
  196.  
  197. Accepts :
  198.  
  199.     CSBptr        Address of command state block
  200.     CFBptr        Address of command function block
  201.     ccptr        Address of CC table (where appropriate)
  202.  
  203.  
  204. Returns :
  205.  
  206.     <value>        Parse status, _CPxxx as defined in comndi.h.
  207.  
  208. */
  209.  
  210. CFPswi (CSBptr, CFBptr, ccptr)
  211.  
  212. CSB        *CSBptr;        /* Addr of command state block */
  213. CFB        *CFBptr;        /* Addr of command function block */
  214. WORD        *ccptr;            /* Addr of CC table */
  215.  
  216. {
  217. CSBptr -> CSB_RCD = _CRIFC;        /* Set invalid function (NYI) */
  218. return (_CPABT);            /* Abort now. */
  219. }
  220. /*
  221.  
  222. *//* CFPtok (CSBptr, CFBptr, ccptr)
  223.  
  224.     Function parse for type=_CMTOK, token
  225.  
  226. This function performs an exact match on an expected token
  227.  
  228. Accepts :
  229.  
  230.     CSBptr        Address of command state block
  231.     CFBptr        Address of command function block
  232.     ccptr        Address of CC table (where appropriate)
  233.  
  234.  
  235. Returns :
  236.  
  237.     <value>        Parse status, _CPxxx as defined in comndi.h.
  238.  
  239. */
  240.  
  241. CFPtok (CSBptr, CFBptr, ccptr)
  242.  
  243. CSB        *CSBptr;        /* Addr of command state block */
  244. CFB        *CFBptr;        /* Addr of command function block */
  245. WORD        *ccptr;            /* Addr of CC table */
  246.  
  247. {
  248. IND    int    cix;            /* Command index */
  249. IND    int    c,c1;            /* Chars */
  250. IND    char    *tptr;            /* Token pointer (ptr to token) */
  251.  
  252.  
  253. tptr = CFBptr -> CFB_DAT;        /* Get address of the token */
  254. cix = CMDspc(CSBptr);            /* Init parse index */
  255. while (TRUE)                /* Look at chars */
  256.     {
  257.     if ((c = *tptr++) == NUL)        /* If end of token passed */
  258.     {
  259.     CMDcpt (CSBptr, cix);        /* Checkpoint to here! */
  260.     return (_CPSUCC);        /* We matched */
  261.     }
  262.  
  263.     c = toupper(c);            /* Ignore case */
  264.     c1 = CMDgcc (CSBptr, cix);        /* Get next char from cmd */
  265.     if (c != toupper(c1))        /* If not the same */
  266.     break;                /*  exit the loop */
  267.     cix++;                /* Fine, skip it */
  268.     }
  269.  
  270. /* Here on mismatch... check for specials */
  271.  
  272. switch (c1)
  273.     {
  274.     case _CCCMP:            /* Complete.. */
  275.     case _CCINC:            /* or incomplete */
  276.     return (_CPAGN);        /*  try again */
  277.  
  278.     case _CCHLP:            /* Help ? */
  279.     if (CMDhlp (CFBptr, "token: "))
  280.         CMDpzs (CFBptr -> CFB_DAT);
  281.     CMDfob();
  282.     return (_CPGVH);        /* Say we gave help */
  283.  
  284.     default:                /* Anything else */
  285.     return (_CPNOP);        /* No parse */
  286.     }
  287. }
  288. /*
  289.  
  290. *//* CFPtxt (CSBptr, CFBptr, ccptr)
  291.  
  292.     Function parse for type=_CMTXT, text
  293.  
  294. This function parses text to the end of the line.
  295.  
  296. Accepts :
  297.  
  298.     CSBptr        Address of command state block
  299.     CFBptr        Address of command function block
  300.     ccptr        Address of CC table (where appropriate)
  301.  
  302.  
  303. Returns :
  304.  
  305.     <value>        Parse status, _CPxxx as defined in comndi.h.
  306.  
  307. */
  308.  
  309. CFPtxt (CSBptr, CFBptr, ccptr)
  310.  
  311. CSB        *CSBptr;        /* Addr of command state block */
  312. CFB        *CFBptr;        /* Addr of command function block */
  313. WORD        *ccptr;            /* Addr of CC table */
  314.  
  315. {
  316. IND    int    cix;            /* Command index */
  317. IND    int    c;            /* Character */
  318. IND    char    *aptr;            /* Atom buffer pointer */
  319.  
  320. cix = 0;                /* Init parse index */
  321. aptr = CSBptr -> CSB_ABF;        /* Point to atom buffer */
  322.  
  323. while (TRUE)                /* Get chars */
  324.     {
  325.     c = CMDgcc (CSBptr, cix);        /* Get next char */
  326.     switch (c)                /* Process specials */
  327.     {
  328.     case _CCCMP:            /* Escape ? */
  329.         CMDbel++;            /* We'd beep */
  330.  
  331.     case _CCINC:            /* Incomplete */
  332.         return (_CPAGN);        /*  try again */
  333.  
  334.     case _CCHLP:            /* Help ? */
  335.         CMDhlp (CFBptr, "text, end with carriage return");
  336.         return (_CPGVH);        /* Gave help */
  337.  
  338.     case _CCEND:            /* End of line */
  339.         *aptr = NUL;        /* End the string */
  340.         CMDcpt (CSBptr, cix);    /* Checkpoint to here */
  341.         return (_CPSUCC);        /* Return success */
  342.  
  343.     default:            /* Other */
  344.         break;            /*  loop */
  345.     }
  346.  
  347.     *aptr++ = c;            /* Store the char */
  348.     cix++;                /* Bump char index */
  349.     }
  350. }
  351. /*
  352.  
  353. *//* CFPuqs (CSBptr, CFBptr, ccptr)
  354.  
  355.     Function parse for type=_CMUQS, unquoted string
  356.  
  357. This function parses an unquoted string; a string delimited by
  358. spaces or commas only.
  359.  
  360.  
  361. Accepts :
  362.  
  363.     CSBptr        Address of command state block
  364.     CFBptr        Address of command function block
  365.     ccptr        Address of CC table (where appropriate)
  366.  
  367.  
  368. Returns :
  369.  
  370.     <value>        Parse status, _CPxxx as defined in comndi.h.
  371.  
  372. */
  373.  
  374. CFPuqs (CSBptr, CFBptr, ccptr)
  375.  
  376. CSB        *CSBptr;        /* Addr of command state block */
  377. CFB        *CFBptr;        /* Addr of command function block */
  378. WORD        *ccptr;            /* Addr of CC table */
  379.  
  380. {
  381. IND    int    cix;            /* Command index */
  382. IND    int    ec;            /* Character */
  383. IND    int    aptr;            /* Atom buffer pointer */
  384.  
  385. cix = CMDcab (CSBptr,             /* Collect atom buffer */
  386.         CSBptr -> CSB_ABF,    /*  where to put it */
  387.         CSBptr -> CSB_ASZ,    /*  how big it is */
  388.         ccptr,            /* Char table */
  389.         &ec,            /* What the end char is */
  390.         CMDspc(CSBptr));    /* Initial parse index */
  391.  
  392. switch (ec)                /* Process according to final */
  393.     {
  394.     case _CCINV:            /* Invalid delimiter */
  395.     return (_CPNOP);        /* No Parse */
  396.  
  397.     case _CCCMP:            /* Escape ? */
  398.     CMDcpl (CSBptr, " ");        /* Add a space */
  399.     return (_CPCPE);        /* Flag completed with escape */
  400.  
  401.     case _CCINC:            /* Incomplete */
  402.     return (_CPAGN);        /*  try again */
  403.  
  404.     case _CCHLP:            /* Help ? */
  405.     CMDhlp (CFBptr, "unquoted string");
  406.     return (_CPGVH);        /* Gave help */
  407.  
  408.     default:                /* Completed atom */
  409.     CMDcpt (CSBptr, cix);        /* Checkpoint to here */
  410.     return (_CPSUCC);        /* Return success */
  411.     }
  412. }
  413.