home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddkx86v5.zip / DDKX86 / SRC / DEV / DASD / OS2ASPI / CMDPARSE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-14  |  27.1 KB  |  951 lines

  1. /*DDK*************************************************************************/
  2. /*                                                                           */
  3. /* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
  4. /*                                                                           */
  5. /*    The following IBM OS/2 WARP source code is provided to you solely for  */
  6. /*    the purpose of assisting you in your development of OS/2 WARP device   */
  7. /*    drivers. You may use this code in accordance with the IBM License      */
  8. /*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
  9. /*    Copyright statement may not be removed.                                */
  10. /*                                                                           */
  11. /*****************************************************************************/
  12. /*static char *SCCSID = "src/dev/dasd/os2aspi/cmdparse.c, aspi, r206 93/03/20";*/
  13. /**************************************************************************
  14.  *
  15.  * SOURCE FILE NAME = ASPIDATA.C
  16.  *
  17.  * DESCRIPTIVE NAME = OS2ASPI.DMD - OS/2 ASPI Device Manager
  18.  *                    ADD CONFIG.SYS Command Line Parser Helper Routine
  19.  *
  20.  *
  21.  *
  22.  * VERSION = V2.0
  23.  *
  24.  * DATE: 2/11/92
  25.  *
  26.  * DESCRIPTION : ASPI Device Manager - This module consists of the
  27.  *               Command_Parser Function and its associated local
  28.  *               routines.  For detailed description of the
  29.  *               Command_Parser interface refer to the CMDPROTO.H
  30.  *               file.
  31.  *
  32.  *   EXTERNAL REFERENCES:                                                       *
  33.  *                        BASEDEF.H  - Type Definitions (OS2.H)                 *
  34.  *                        CMDPARSE.H - Command_Parser Definitions               *
  35.  *                        CMDPROTO.H - Command_Parser Prototype                 *
  36.  *
  37. */
  38. #if !(defined(OS2_INCLUDED))
  39.     #define INCL_NOBASEAPI
  40.     #define INCL_NOPMAPI
  41.     #include "OS2.H"
  42. #endif
  43.  
  44. #include <cmdphdr.h>
  45. #include <cmdproto.h>
  46.  
  47. #define TOKVBUF_LEN 255
  48. #define UNDEFINED   -1
  49.  
  50. PSZ        pcmdline1, pcmdline_slash, pcmdline_start;
  51. INT        tokv_index, state_index, length;
  52. CHARBYTE   tokvbuf[TOKVBUF_LEN];
  53. POPT       pend_option, ptable_option;
  54. BYTE       *poutbuf1, *poutbuf_end;
  55. CC         cc;
  56.  
  57. //
  58. //    Command_Parser -  external entry point into this module
  59. //
  60.  
  61. CC FAR Command_Parser(pCmdLine,pOptTable,pOutBuf,OutBuf_Len)
  62.  
  63. PSZ           pCmdLine;
  64. POPTIONTABLE  pOptTable;
  65. PBYTE         pOutBuf;
  66. USHORT        OutBuf_Len;
  67.  
  68. {
  69.    USHORT j, end_index;
  70.  
  71.    if (OutBuf_Len < (TOKL_ID_END + TOK_MIN_LENGTH))
  72.    {
  73.       cc.ret_code = BUF_TOO_SMALL_ERR;
  74.       cc.err_index = 0;
  75.       return (cc);
  76.    }
  77.  
  78.    poutbuf_end = pOutBuf + OutBuf_Len;
  79.  
  80.    poutbuf1 = pOutBuf;
  81.    for (poutbuf1 = pOutBuf;
  82.         (poutbuf1 < poutbuf_end);
  83.         poutbuf1++)
  84.        *poutbuf1 = 0;
  85.    poutbuf1 = pOutBuf;
  86.  
  87.    Insert_End_Token();
  88.  
  89.    //
  90.    //  Locate the last entry in the Option Table. This special entry
  91.    //  defines whether or not an option is required based on the index
  92.    //  in the state table.
  93.    //
  94.    for (end_index = 0 ;
  95.         (pOptTable->poption[end_index]->id != TOK_ID_END);
  96.         end_index++);
  97.    pend_option = pOptTable->poption[end_index];
  98.  
  99.    //
  100.    //  Setup the initial index into the state table.
  101.    //
  102.    state_index = pOptTable->entry_state;
  103.    if (!Validate_State_Index(pOptTable->max_states))
  104.       return (cc);
  105.  
  106.    //
  107.    //  On return from Locate_First_Slash call pcmdline_slash
  108.    //  contains the ptr to the / in the command line.
  109.    //
  110.    pcmdline_start = pCmdLine;
  111.    pcmdline1 = pCmdLine;
  112.    if (!Locate_First_Slash())
  113.       return (cc);
  114.  
  115.    for (j=0;j < end_index;j++)
  116.    {
  117.       //
  118.       //  Locate valid options in Option Table, based on state table index.
  119.       //
  120.       if (pOptTable->poption[j]->state[state_index] != E)
  121.       {
  122.         //
  123.         //  Found a valid option. Check to see if this is the option
  124.         //  entered at this point in command line.
  125.         //
  126.         ptable_option = pOptTable->poption[j];
  127.         length = strlength(ptable_option->string);
  128.         if (strncmp(pcmdline_slash,ptable_option->string, length) == TRUE)
  129.         {
  130.  
  131.            //
  132.            // Found the command line option.  Now, syntax check its
  133.            // associated value.
  134.            //
  135.            if (!Parse_Option_Value())
  136.               return (cc);
  137.  
  138.            //
  139.            // No syntax err detected.  Now, insert the option and its
  140.            // associated value into the output buffer in token format.
  141.            //
  142.            if (!Insert_Token())
  143.               return (cc);
  144.  
  145.            //
  146.            //  Setup next index into the state table.
  147.            //
  148.            state_index = ptable_option->state[state_index];
  149.            if (!Validate_State_Index(pOptTable->max_states))
  150.               return (cc);
  151.  
  152.            //
  153.            //  Setup cmdline_slash to point the the next / (option) in
  154.            //  the command line.
  155.            //  Parsing stops once either an invalid character is
  156.            //  found on the command line or the end of the command line
  157.            //  is detected.
  158.            //
  159.            if (!Locate_Next_Slash())
  160.               return (cc);
  161.  
  162.            //
  163.            // Setup for option search. Point to the top of the Option Table.
  164.            //
  165.            j = -1;
  166.  
  167.         } /* endif */
  168.  
  169.       } /* endif */
  170.  
  171.    } /* endfor */
  172.  
  173.  
  174.    if (pend_option->state[state_index] == R)
  175.    {
  176.    //
  177.    // A required option was not found on the command line.
  178.    //
  179.       cc.ret_code = REQ_OPT_ERR;
  180.    }
  181.    else
  182.    {
  183.    //
  184.    // Characters on the command line are not defined in the Option Table
  185.    // as a valid option.  All options must start with a / character.
  186.    //
  187.       cc.ret_code = INVALID_OPT_ERR;
  188.    }
  189.    cc.err_index = pcmdline_slash-pCmdLine;
  190.    return (cc);
  191.  
  192. }
  193.  
  194. /*******************************************************************************
  195. *                                                                              *
  196. *   FUNCTION: Insert the end of token marker into the output buffer            *
  197. *                                                                              *
  198. *******************************************************************************/
  199. VOID NEAR Insert_End_Token()
  200. {
  201.      *poutbuf1 = TOKL_ID_END;
  202.      *(poutbuf1+1) = TOK_ID_END;
  203.      return;
  204. }
  205.  
  206. /*******************************************************************************
  207. *                                                                              *
  208. *   FUNCTION: Locate the / on the command line.  All characters entered prior  *
  209. *             to the first / are ignored.  This allows the parser to bypass    *
  210. *             the BASEDEV = xxxxxxxx.xxx portion of the command line.          *
  211. *                                                                              *
  212. *******************************************************************************/
  213. BOOL NEAR Locate_First_Slash()
  214. {
  215.  
  216.  
  217.      while ((*pcmdline1 != '\0') &&
  218.             (*pcmdline1 != '\n') &&
  219.             (*pcmdline1 != '\r'))
  220.      {
  221.          if (*pcmdline1 == '/')
  222.          {
  223.             pcmdline_slash = pcmdline1;
  224.             return(TRUE);
  225.          }
  226.  
  227.          pcmdline1++;
  228.      }
  229.  
  230.      cc.err_index = 0;
  231.      cc.ret_code = NO_OPTIONS_FND_ERR;
  232.      if (pend_option->state[state_index] == R)
  233.         cc.ret_code = REQ_OPT_ERR;
  234.  
  235.      return(FALSE);
  236. }
  237.  
  238. /*******************************************************************************
  239. *                                                                              *
  240. *   FUNCTION: Return the length of a string                                    *
  241. *                                                                              *
  242. *******************************************************************************/
  243. INT  NEAR strlength(s)
  244.  
  245. CHAR FAR *s;
  246. {
  247.      INT i;
  248.  
  249.      for (i = 0; *s != '\0' ; s++)
  250.          i++;
  251.  
  252.      return(i);
  253. }
  254.  
  255. /*******************************************************************************
  256. *                                                                              *
  257. *   FUNCTION: Compare n number of characters in 2 strings, return TRUE if =    *
  258. *             If s1 is in lower case, convert to upper prior to comparing.     *
  259. *                                                                              *
  260. *******************************************************************************/
  261. BOOL NEAR strncmp(s1,s2,n)
  262.  
  263. CHAR FAR *s1, FAR *s2;
  264. INT  n;
  265. {
  266.      INT i;
  267.      CHAR temp;
  268.  
  269.      for (i=0;i < n;i++,s1++,s2++)
  270.  
  271.          if (*s1 != *s2)
  272.          {
  273.             if ((*s1 >= 'a') && (*s1 <= 'z'))
  274.             {
  275.                temp = *s1 - ' ';
  276.                if (temp == *s2)
  277.                   continue;
  278.             }
  279.             return(FALSE);
  280.          }
  281.  
  282.      return(TRUE);
  283. }
  284.  
  285. /*******************************************************************************
  286. *                                                                              *
  287. *   FUNCTION: Parse the command line for the value assigned to located option  *
  288. *                                                                              *
  289. *******************************************************************************/
  290. BOOL  NEAR Parse_Option_Value()
  291. {
  292.       pcmdline1 = pcmdline_slash + length;
  293.       Skip_Over_Blanks();
  294.  
  295.       for (tokv_index = 0; tokv_index <= TOKVBUF_LEN; tokv_index++)
  296.            tokvbuf[tokv_index].byte_value= 0;
  297.  
  298.       tokv_index = UNDEFINED;
  299.  
  300.       cc.ret_code = NO_ERR;
  301.       cc.err_index = 0;
  302.  
  303.       switch (ptable_option->type)
  304.       {
  305.       case TYPE_0:
  306.            break;
  307.  
  308.       case TYPE_CHAR:
  309.            char_parser();
  310.            break;
  311.  
  312.       case TYPE_D:
  313.            d_parser();
  314.            break;
  315.  
  316.       case TYPE_DD:
  317.            dd_parser();
  318.            break;
  319.  
  320.       case TYPE_HH:
  321.            hh_parser();
  322.            break;
  323.  
  324.       case TYPE_HHHH:
  325.            hhhh_parser();
  326.            break;
  327.  
  328.       case TYPE_FORMAT:
  329.            format_parser();
  330.            break;
  331.  
  332.       case TYPE_SCSI_ID:
  333.            scsi_id_parser();
  334.            break;
  335.  
  336.       case TYPE_GEOMETRY:
  337.            geometry_parser();
  338.            break;
  339.  
  340.       default:
  341.            cc.ret_code = UNDEFINED_TYPE_ERR;
  342.  
  343.       } /* endswitch */
  344.  
  345.       if (cc.ret_code != NO_ERR)
  346.       {
  347.          cc.err_index = pcmdline1 - pcmdline_start;
  348.          return(FALSE);
  349.       }
  350.  
  351.       return(TRUE);
  352. }
  353.  
  354.  
  355. /*******************************************************************************
  356. *                                                                              *
  357. *   FUNCTION: Skip over all the blank and tab characters                       *
  358. *                                                                              *
  359. *******************************************************************************/
  360. VOID NEAR Skip_Over_Blanks()
  361. {
  362.      while ((*pcmdline1 == ' ') || (*pcmdline1 == '\t'))
  363.            pcmdline1++;
  364.      return;
  365. }
  366.  
  367. /*******************************************************************************
  368. *                                                                              *
  369. *   FUNCTION: TYPE_CHAR option parser - scan till blank,tab,cr,new line or     *
  370. *                                       end of string char                     *
  371. *                                                                              *
  372. *******************************************************************************/
  373. VOID NEAR  char_parser()
  374. {
  375.      while ((*pcmdline1 != '\0') &&
  376.             (*pcmdline1 != '\n') &&
  377.             (*pcmdline1 != '\r') &&
  378.             (*pcmdline1 != '/'))
  379.  
  380.      {
  381.            tokv_index++;
  382.            tokvbuf[tokv_index].char_value = *pcmdline1;
  383.            pcmdline1++;
  384.      }
  385.  
  386.      return;
  387. }
  388.  
  389.  
  390. /*******************************************************************************
  391. *                                                                              *
  392. *   FUNCTION: TYPE_D option parser - one digit decimal number (d)              *
  393. *                                                                              *
  394. *******************************************************************************/
  395. VOID NEAR  d_parser()
  396. {
  397.      if ((*pcmdline1 >= '0') && (*pcmdline1 <= '9'))
  398.      {
  399.         tokv_index++;
  400.         tokvbuf[tokv_index].byte_value = *pcmdline1 - '0';
  401.         pcmdline1++;
  402.      }
  403.      else
  404.      {
  405.         cc.ret_code = SYNTAX_ERR;
  406.      }
  407.  
  408.      return;
  409. }
  410.  
  411. /*******************************************************************************
  412. *                                                                              *
  413. *   FUNCTION: TYPE_DD option parser - two digit decimal number (dd)            *
  414. *                                                                              *
  415. *******************************************************************************/
  416. VOID NEAR dd_parser()
  417. {
  418.      INT  i;
  419.      BYTE n;
  420.      BOOL flag;
  421.  
  422.      n = 0;
  423.      flag = FALSE;
  424.      for ( i = 0; i < 2; i++)
  425.      {
  426.          if ((*pcmdline1 >= '0') && (*pcmdline1 <= '9'))
  427.          {
  428.             n = 10 * n + *pcmdline1 - '0';
  429.             pcmdline1++;
  430.             flag = TRUE;
  431.          }
  432.          else
  433.          {
  434.             //
  435.             // Was at least 1 digit found on the command line?
  436.             //
  437.             if (flag)
  438.                break;
  439.  
  440.             cc.ret_code = SYNTAX_ERR;
  441.             return;
  442.          }
  443.      }
  444.  
  445.      tokv_index++;
  446.      tokvbuf[tokv_index].byte_value = n;
  447.  
  448.      return;
  449. }
  450.  
  451. /*******************************************************************************
  452. *                                                                              *
  453. *   FUNCTION: TYPE_HH option parser        hh,hh format (h = hex char)         *
  454. *                                                                              *
  455. *******************************************************************************/
  456. VOID NEAR hh_parser()
  457. {
  458.      //
  459.      //  Convert command line HH char and setup token value buffer
  460.      //
  461.      if (!HH_Char_To_Byte())
  462.         return;
  463.  
  464.      Skip_Over_Blanks();
  465.      if (*pcmdline1 != ',')
  466.      {
  467.         cc.ret_code = SYNTAX_ERR;
  468.         return;
  469.      }
  470.      pcmdline1++;
  471.      Skip_Over_Blanks();
  472.  
  473.      //
  474.      //  Convert command line HH char and setup token value buffer
  475.      //
  476.      HH_Char_To_Byte();
  477.  
  478.      return;
  479. }
  480.  
  481.  
  482.  
  483. /*******************************************************************************
  484. *                                                                              *
  485. *   FUNCTION: Convert HH char to byte value                                    *
  486. *                                                                              *
  487. *******************************************************************************/
  488. BOOL NEAR HH_Char_To_Byte()
  489. {
  490.      BYTE n;
  491.      INT  i;
  492.      BOOL flag;
  493.  
  494.      n = 0;
  495.      flag = FALSE;
  496.  
  497.      for ( i = 0; i < 2; i++)
  498.      {
  499.          if ((*pcmdline1 >= '0') && (*pcmdline1 <= '9'))
  500.          {
  501.             n = 16 * n + *pcmdline1 - '0';
  502.             pcmdline1++;
  503.             flag = TRUE;
  504.             continue;
  505.          }
  506.  
  507.          if ((*pcmdline1 >= 'A') && (*pcmdline1 <= 'F'))
  508.          {
  509.             n = 16 * n + *pcmdline1 - '7';
  510.             pcmdline1++;
  511.             flag = TRUE;
  512.             continue;
  513.          }
  514.  
  515.          if ((*pcmdline1 >= 'a') && (*pcmdline1 <= 'f'))
  516.          {
  517.             n = 16 * n + *pcmdline1 - 'W';
  518.             pcmdline1++;
  519.             flag = TRUE;
  520.             continue;
  521.          }
  522.  
  523.          //
  524.          // Was at least 1 hex digit found on the command line?
  525.          //
  526.          if (flag)
  527.             break;
  528.  
  529.          cc.ret_code = SYNTAX_ERR;
  530.          return(FALSE);
  531.  
  532.      }
  533.  
  534.      tokv_index++;
  535.      tokvbuf[tokv_index].byte_value = n;
  536.  
  537.      return(TRUE);
  538. }
  539.  
  540.  
  541. /*******************************************************************************
  542. *                                                                              *
  543. *   FUNCTION: TYPE_HHHH option parser       hhhh format (h = hex char)         *
  544. *                                                                              *
  545. *******************************************************************************/
  546. VOID NEAR hhhh_parser()
  547. {
  548.      INT  i;
  549.      BOOL flag;
  550.      NUMBER un_number;
  551.  
  552.      un_number.n = 0;
  553.      flag = FALSE;
  554.  
  555.      for ( i = 0; i < 4; i++)
  556.      {
  557.          if ((*pcmdline1 >= '0') && (*pcmdline1 <= '9'))
  558.          {
  559.             un_number.n = 16 * un_number.n + *pcmdline1 - '0';
  560.             pcmdline1++;
  561.             flag = TRUE;
  562.             continue;
  563.          }
  564.  
  565.          if ((*pcmdline1 >= 'A') && (*pcmdline1 <= 'F'))
  566.          {
  567.             un_number.n = 16 * un_number.n + *pcmdline1 - '7';
  568.             pcmdline1++;
  569.             flag = TRUE;
  570.             continue;
  571.          }
  572.  
  573.          if ((*pcmdline1 >= 'a') && (*pcmdline1 <= 'f'))
  574.          {
  575.             un_number.n = 16 * un_number.n + *pcmdline1 - 'W';
  576.             pcmdline1++;
  577.             flag = TRUE;
  578.             continue;
  579.          }
  580.  
  581.          //
  582.          // Was at least 1 hex digit found on the command line?
  583.          //
  584.          if (flag)
  585.             break;
  586.  
  587.          cc.ret_code = SYNTAX_ERR;
  588.          return;
  589.  
  590.  
  591.      }
  592.  
  593.      tokv_index++;
  594.      tokvbuf[tokv_index].byte_value = un_number.two_bytes.byte1;
  595.  
  596.      tokv_index++;
  597.      tokvbuf[tokv_index].byte_value = un_number.two_bytes.byte2;
  598.  
  599.      return;
  600. }
  601.  
  602.  
  603. /*******************************************************************************
  604. *                                                                              *
  605. *   FUNCTION: TYPE_FORMAT option parser -  format_table chars accepted         *
  606. *                                                                              *
  607. *******************************************************************************/
  608. VOID NEAR format_parser()
  609. {
  610.  
  611.      typedef struct _formattable
  612.      {
  613.          PSZ        string;
  614.          USHORT     type;
  615.          NUMBER     MegBytes;
  616.  
  617.      } FORMATTABLE;
  618.  
  619. // FORMATTABLE type definitions
  620. #define M_BYTES             1       //accepts MB,mb,Mb,mB, or just the # string
  621. #define K_BYTES             2       //accepts KB,kb,Kb,kB, or just the # string
  622.  
  623.        INT  str_len, k;
  624. static FORMATTABLE format_table[] =
  625.      {
  626.       { "360",  K_BYTES, 360},
  627.       { "720",  K_BYTES, 720},
  628.       { "1200", K_BYTES, 1200},
  629.       { "1.2",  M_BYTES, 1200},
  630.       { "1440", K_BYTES, 1440},
  631.       { "1.44", M_BYTES, 1440},
  632.       { "2880", K_BYTES, 2880},
  633.       { "2.88", M_BYTES, 2880},
  634.       { "-1"},
  635.      };
  636.  
  637.      cc.ret_code = SYNTAX_ERR;
  638.      for (k = 0; (format_table[k].string != "-1"); k++)
  639.      {
  640.  
  641.          str_len = strlength(format_table[k].string);
  642.  
  643.          if (strncmp(pcmdline1,format_table[k].string, str_len)
  644.             == TRUE)
  645.          {
  646.             pcmdline1 += str_len;
  647.             if (format_table[k].type == K_BYTES)
  648.             {
  649.                if ((*pcmdline1 == 'K') || (*pcmdline1 == 'k'))
  650.                {
  651.                   ++pcmdline1;
  652.  
  653.                   if ((*(pcmdline1+1) == 'B') || (*(pcmdline1+1) == 'b'))
  654.                      ++pcmdline1;
  655.                }
  656.             }
  657.             else
  658.             {
  659.                if ((*pcmdline1 == 'M') || (*pcmdline1 == 'm'))
  660.                {
  661.                   ++pcmdline1;
  662.  
  663.                   if ((*(pcmdline1+1) == 'B') || (*(pcmdline1+1) == 'b'))
  664.                      ++pcmdline1;
  665.                 }
  666.             }
  667.  
  668.             tokv_index++;
  669.             tokvbuf[tokv_index].byte_value = format_table[k].MegBytes.two_bytes.byte1;
  670.             tokv_index++;
  671.             tokvbuf[tokv_index].byte_value = format_table[k].MegBytes.two_bytes.byte2;
  672.  
  673.             cc.ret_code = NO_ERR;
  674.             break;
  675.          }
  676.      }
  677.      return;
  678. }
  679.  
  680. /*******************************************************************************
  681. *                                                                              *
  682. *   FUNCTION: TYPE_SCSI_ID option parser - format d and (d,d) accepted         *
  683. *                                          where d = 0 - 7                     *
  684. *                                                                              *
  685. *******************************************************************************/
  686. VOID NEAR scsi_id_parser()
  687. {
  688.      BOOL found_bracket, found_one;
  689.  
  690.      found_bracket = FALSE;
  691.      found_one = FALSE;
  692.  
  693.      if (*pcmdline1 == '(')
  694.      {
  695.         found_bracket = TRUE;
  696.         pcmdline1++;
  697.         Skip_Over_Blanks();
  698.      }
  699.  
  700.  
  701.      while ((*pcmdline1 >= '0') && (*pcmdline1 <= '7'))
  702.      {
  703.            found_one = TRUE;
  704.            tokv_index++;
  705.            tokvbuf[tokv_index].byte_value = *pcmdline1 - '0';
  706.            pcmdline1++;
  707.            if (!found_bracket)
  708.            {
  709.               tokv_index++;
  710.               tokvbuf[tokv_index].byte_value = 0;
  711.            }
  712.  
  713.            Skip_Over_Blanks();
  714.            if (*pcmdline1 != ',')
  715.            {
  716.               if (found_bracket)
  717.                  cc.ret_code = SYNTAX_ERR;
  718.               return;
  719.            }
  720.  
  721.            pcmdline1++;
  722.            Skip_Over_Blanks();
  723.            if (found_bracket)
  724.            {
  725.               if ((*pcmdline1 >= '0') && (*pcmdline1 <= '7'))
  726.               {
  727.                  tokv_index++;
  728.                  tokvbuf[tokv_index].byte_value = *pcmdline1 - '0';
  729.                  pcmdline1++;
  730.                  Skip_Over_Blanks();
  731.                  if (*pcmdline1 != ')')
  732.                  {
  733.                    cc.ret_code = SYNTAX_ERR;
  734.                    return;
  735.                  }
  736.                  pcmdline1++;
  737.                  Skip_Over_Blanks();
  738.                  found_bracket = FALSE;
  739.  
  740.                  if (*pcmdline1 != ',')
  741.                     return;
  742.  
  743.                  pcmdline1++;
  744.                  Skip_Over_Blanks();
  745.               }
  746.            }
  747.  
  748.            if (*pcmdline1 == '(')
  749.            {
  750.               found_bracket = TRUE;
  751.               pcmdline1++;
  752.               Skip_Over_Blanks();
  753.            }
  754.      }
  755.  
  756.      if (found_bracket)
  757.         cc.ret_code = SYNTAX_ERR;
  758.  
  759.      if (!found_one)
  760.         cc.ret_code = SYNTAX_ERR;
  761.  
  762.      return;
  763. }
  764.  
  765.  
  766. /*******************************************************************************
  767. *                                                                              *
  768. *   FUNCTION: TYPE_GEOMETRY option parser - dd or (dddd,dddd,dddd) accepted    *
  769. *                                                                              *
  770. *******************************************************************************/
  771. VOID NEAR geometry_parser()
  772. {
  773.      INT  i, counter;
  774.      NUMBER un_number;
  775.      BOOL flag;
  776.  
  777.      BOOL found_bracket, found_one;
  778.  
  779.      _asm{int 3};
  780.      if (*pcmdline1 != '(')
  781.      {
  782.         dd_parser();
  783.         return;
  784.      }
  785.  
  786.      pcmdline1++;
  787.      Skip_Over_Blanks();
  788.  
  789.      counter = 0;
  790.      while(TRUE)
  791.      {
  792.            un_number.n = 0;
  793.            flag = FALSE;
  794.            for ( i = 0; i < 4; i++)
  795.            {
  796.                if ((*pcmdline1 >= '0') && (*pcmdline1 <= '9'))
  797.                {
  798.                   un_number.n = 10 * un_number.n + *pcmdline1 - '0';
  799.                   pcmdline1++;
  800.                   flag = TRUE;
  801.                }
  802.                else
  803.                {
  804.                   //
  805.                   // Was at least 1 digit found on the command line?
  806.                   //
  807.                   if (flag)
  808.                      break;
  809.  
  810.                   cc.ret_code = SYNTAX_ERR;
  811.                   return;
  812.                }
  813.            }
  814.  
  815.            tokv_index++;
  816.            tokvbuf[tokv_index].byte_value = un_number.two_bytes.byte1;
  817.            tokv_index++;
  818.            tokvbuf[tokv_index].byte_value = un_number.two_bytes.byte2;
  819.  
  820.            Skip_Over_Blanks();
  821.            if (counter == 2)
  822.            {
  823.               if (*pcmdline1 != ')')
  824.                  cc.ret_code = SYNTAX_ERR;
  825.               else
  826.                  pcmdline1++;
  827.               return;
  828.            }
  829.  
  830.  
  831.            if (*pcmdline1 != ',')
  832.            {
  833.               cc.ret_code = SYNTAX_ERR;
  834.               return;
  835.            }
  836.  
  837.            pcmdline1++;
  838.            counter++;
  839.            Skip_Over_Blanks();
  840.      }
  841.  
  842.      return;
  843. }
  844.  
  845. /*******************************************************************************
  846. *                                                                              *
  847. *   FUNCTION: Insert the parsed option (token) into the output buffer.         *
  848. *                                                                              *
  849. *******************************************************************************/
  850. BOOL NEAR Insert_Token()
  851. {
  852.     USHORT t, tok_size;
  853.  
  854.     tok_size = TOK_MIN_LENGTH + tokv_index;
  855.     if ((poutbuf1 + tok_size + TOKL_ID_END) >= poutbuf_end)
  856.     {
  857.        cc.err_index = pcmdline_slash-pcmdline_start;
  858.        cc.ret_code = BUF_TOO_SMALL_ERR;
  859.        return(FALSE);
  860.     }
  861.  
  862.     *poutbuf1 = tok_size + 1;
  863.     poutbuf1++;
  864.     *poutbuf1 = ptable_option->id;
  865.     poutbuf1++;
  866.  
  867.     if (tokv_index != UNDEFINED)
  868.     {
  869.        for (t=0;t <= tokv_index;t++)
  870.        {
  871.            *poutbuf1 = tokvbuf[t].byte_value;
  872.             poutbuf1++;
  873.        }
  874.     }
  875.  
  876.     Insert_End_Token();
  877.  
  878.     return(TRUE);
  879. }
  880.  
  881. /*******************************************************************************
  882. *                                                                              *
  883. *   FUNCTION: Locate the next / char.                                          *
  884. *                                                                              *
  885. *******************************************************************************/
  886. BOOL NEAR Locate_Next_Slash()
  887. {
  888.  
  889.      while ((*pcmdline1 != '\0') &&
  890.             (*pcmdline1 != '\n') &&
  891.             (*pcmdline1 != '\r'))
  892.      {
  893.  
  894.            if ((*pcmdline1 == ' ') ||
  895.                (*pcmdline1 == '\t'))
  896.            {
  897.               pcmdline1++;
  898.            }
  899.            else
  900.            {
  901.               if (*pcmdline1 == '/')
  902.               {
  903.                  pcmdline_slash = pcmdline1;
  904.                  return(TRUE);
  905.               }
  906.               else
  907.               {
  908.                  cc.ret_code = INVALID_OPT_ERR;
  909.                  cc.err_index = pcmdline1-pcmdline_start;
  910.                  return(FALSE);
  911.               }
  912.            }
  913.  
  914.      } /* endwhile */
  915.  
  916.      if (pend_option->state[state_index] == R)
  917.      {
  918.         cc.ret_code = REQ_OPT_ERR;
  919.         cc.err_index = pcmdline1-pcmdline_start;
  920.      }
  921.      else
  922.      {
  923.         cc.ret_code = NO_ERR;
  924.         cc.err_index = 0;
  925.      }
  926.      return(FALSE);
  927. }
  928.  
  929.  
  930. /*******************************************************************************
  931. *                                                                              *
  932. *   FUNCTION: Validate the State Index                                         *
  933. *                                                                              *
  934. *******************************************************************************/
  935. BOOL NEAR Validate_State_Index(maxstate)
  936.  
  937. USHORT  maxstate;
  938. {
  939.  
  940.    if ((state_index > maxstate) ||
  941.        (state_index < 0))
  942.    {
  943.       cc.ret_code = UNDEFINED_STATE_ERR;
  944.       cc.err_index = 0;
  945.       return(FALSE);
  946.    }
  947.  
  948.    return(TRUE);
  949. }
  950.  
  951.