home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 4 Drivers / 04-Drivers.zip / scsiopt2.zip / cmdparse.c next >
C/C++ Source or Header  |  1997-12-08  |  32KB  |  1,588 lines

  1. /**************************************************************************
  2.  *
  3.  * SOURCE FILE NAME = CMDPARSE.C
  4.  *
  5.  * DESCRIPTIVE NAME = ADD Command Line Parser
  6.  *              ADD CONFIG.SYS Command Line Parser Helper Routine
  7.  *
  8.  *
  9.  *
  10.  * COPYRIGHT    Copyright (C) 1992 IBM Corporation
  11.  *
  12.  * The following IBM OS/2 2.1 source code is provided to you solely for
  13.  * the purpose of assisting you in your development of OS/2 2.x device
  14.  * drivers. You may use this code in accordance with the IBM License
  15.  * Agreement provided in the IBM Device Driver Source Kit for OS/2. This
  16.  * Copyright statement may not be removed.
  17.  *
  18.  *
  19.  *
  20.  * VERSION = V2.0
  21.  *
  22.  * DATE
  23.  *
  24.  * DESCRIPTION :
  25.  *
  26.  * Purpose: This module consists of the Command_Parser Function and
  27.  *        its associated local routines.  For detailed description
  28.  *        of the Command_Parser interface refer to the CMDPARSE.H
  29.  *        file.
  30.  *
  31.  * FUNCTIONS  :  Command_Parser
  32.  *         Insert_End_Token
  33.  *         Locate_First_Slash
  34.  *         FarStrLen
  35.  *         strncmp
  36.  *         Parse_Option_Value
  37.  *         Skip_over_Blanks
  38.  *         char_parser
  39.  *         d_parser
  40.  *         dd_parser
  41.  *         hh_parser
  42.  *         H_Char_To_Byte
  43.  *         hhhh_parser
  44.  *         format_parser
  45.  *         scsi_id_parser
  46.  *         dev_id_parser
  47.  *         geometry_parser
  48.  *         chgline_parser
  49.  *         Insert_Token
  50.  *         Locate_Next_Slash
  51.  *         Validate_State_Index
  52.  *
  53.  *
  54.  * NOTES
  55.  *
  56.  *
  57.  * STRUCTURES
  58.  *
  59.  * EXTERNAL REFERENCES
  60.  *
  61.  *
  62.  *
  63.  * EXTERNAL FUNCTIONS
  64.  *
  65.  ***************************************************************************/
  66.  
  67.  
  68.  
  69. #if !defined(OS2_INCLUDED)
  70. # define  INCL_NOBASEAPI
  71. # define  INCL_NOPMAPI
  72. # include "OS2.H"
  73. #endif
  74. #include "CMDPHDR.H"
  75. #include "CMDPROTO.H"
  76. #define  TOKVBUF_LEN   255
  77. #define  UNDEFINED     -1
  78.  
  79.  
  80. PSZ      pcmdline1, pcmdline_slash, pcmdline_start;
  81. INT      tokv_index, state_index, length;
  82. CHARBYTE  tokvbuf[TOKVBUF_LEN];
  83. POPT      pend_option, ptable_option;
  84. PBYTE      poutbuf1, poutbuf_end;
  85. CC      cc;
  86.  
  87.  
  88.  
  89. /*
  90. **    Command_Parser -    external entry point into this module
  91. */
  92.  
  93.  
  94. /***************************************************************************
  95.  *
  96.  * FUNCTION NAME = Command_Parser
  97.  *
  98.  *
  99.  * DESCRIPTION     =
  100.  *
  101.  *   Purpose:
  102.  *
  103.  *
  104.  *   Function Calls:
  105.  *
  106.  *
  107.  *
  108.  *
  109.  * INPUT     = (pCmdLine,pOptTable,pOutBuf,OutBuf_Len)
  110.  *
  111.  *
  112.  *
  113.  *
  114.  * OUTPUT     = NONE
  115.  *
  116.  *
  117.  * RETURN-NORMAL = NONE
  118.  *
  119.  * RETURN-ERROR  = NONE
  120.  *
  121.  ****************************************************************************/
  122. CC FAR
  123. Command_Parser(PSZ pCmdLine,
  124.            POPTIONTABLE pOptTable,
  125.            PBYTE pOutBuf,
  126.            USHORT OutBuf_Len)
  127. {
  128.     USHORT j,end_index;
  129.  
  130.     if (OutBuf_Len < (TOKL_ID_END+TOK_MIN_LENGTH))
  131.     {
  132.     cc.ret_code = BUF_TOO_SMALL_ERR;
  133.     cc.err_index = 0;
  134.     return cc;
  135.     }
  136.     poutbuf_end = pOutBuf+OutBuf_Len;
  137.     poutbuf1 = pOutBuf;
  138.     for( poutbuf1 = pOutBuf; poutbuf1 < poutbuf_end; ++poutbuf1 )
  139.     *poutbuf1 = 0;
  140.     poutbuf1 = pOutBuf;
  141.     Insert_End_Token();
  142.  
  143.     /* Locate the last entry in the Option Table. This special entry
  144.      * defines whether or not an option is required based on the index
  145.      * in the state table. */
  146.  
  147.     for( end_index = 0;
  148.     pOptTable->poption[end_index]->id != TOK_ID_END;
  149.     ++end_index )
  150.     ;
  151.     pend_option = pOptTable->poption[end_index];
  152.  
  153.     /* Setup the initial index into the state table. */
  154.  
  155.     state_index = pOptTable->entry_state;
  156.     if( !Validate_State_Index(pOptTable->max_states) )
  157.     return cc;
  158.  
  159.     /* On return from Locate_First_Slash call pcmdline_slash
  160.      * contains the ptr to the slash in the command line. */
  161.  
  162.     pcmdline_start = pCmdLine;
  163.     pcmdline1 = pCmdLine;
  164.     if( !Locate_First_Slash() )
  165.     return cc;
  166.     for( j = 0; j < end_index; ++j )
  167.     {
  168.     /* Locate valid options in Option Table, based
  169.      * on state table index. */
  170.  
  171.     if( pOptTable->poption[j]->state[state_index] != E )
  172.     {
  173.         /* Found a valid option. Check to see if this is the option
  174.          * entered at this point in command line. */
  175.  
  176.         ptable_option = pOptTable->poption[j];
  177.         length = FarStrLen(ptable_option->string);
  178.         if( strncmp(pcmdline_slash, ptable_option->string, length) == TRUE )
  179.         {
  180.         /* Found the command line option.  Now, syntax check its
  181.          * associated value. */
  182.  
  183.         if ( !Parse_Option_Value() )
  184.             return cc;
  185.  
  186.         /* No syntax err detected.  Now, insert the option and its
  187.          * associated value into the output buffer in token format. */
  188.  
  189.         if( !Insert_Token() )
  190.             return cc;
  191.  
  192.         /* Setup next index into the state table. */
  193.  
  194.         state_index = ptable_option->state[state_index];
  195.         if( !Validate_State_Index(pOptTable->max_states) )
  196.             return cc;
  197.  
  198.         /* Setup cmdline_slash to point the the next / (option) in
  199.          * the command line.
  200.          * Parsing stops once either an invalid character is
  201.          * found on the command line or the end of the command line
  202.          * is detected. */
  203.  
  204.         if( !Locate_Next_Slash() )
  205.             return cc;
  206.  
  207.         /* Setup for option search. Point to the top
  208.          * of the Option Table. */
  209.  
  210.         j = (USHORT)-1;
  211.         } /*endif*/
  212.     } /*endif*/
  213.     } /*endfor*/
  214.  
  215.     if( pend_option->state[state_index] == R )
  216.     {
  217.     /* A required option was not found on the command line. */
  218.  
  219.     cc.ret_code = REQ_OPT_ERR;
  220.     }
  221.     else
  222.     {
  223.     /* Characters on the command line are not defined in the Option Table
  224.      * as a valid option.  All options must start with a / character. */
  225.  
  226.     cc.ret_code = INVALID_OPT_ERR;
  227.     }
  228.     cc.err_index = pcmdline_slash-pCmdLine;
  229.     return cc;
  230. }
  231.  
  232.  
  233.  
  234.  
  235. /***************************************************************************
  236.  *
  237.  * FUNCTION NAME = Insert_End_Token
  238.  *
  239.  *
  240.  * DESCRIPTION     =
  241.  *
  242.  *   Purpose: Insert the end of token marker into the output buffer
  243.  *
  244.  *
  245.  *   Function Calls:
  246.  *
  247.  *
  248.  *
  249.  *
  250.  * INPUT     = ()
  251.  *
  252.  *
  253.  *
  254.  *
  255.  * OUTPUT     = NONE
  256.  *
  257.  *
  258.  * RETURN-NORMAL = NONE
  259.  *
  260.  * RETURN-ERROR  = NONE
  261.  *
  262.  ****************************************************************************/
  263. STATIC void NEAR
  264. Insert_End_Token(void)
  265. {
  266.     *poutbuf1 = TOKL_ID_END;
  267.     *(poutbuf1+1) = (BYTE)TOK_ID_END;
  268.     return;
  269. }
  270.  
  271.  
  272.  
  273.  
  274. /***************************************************************************
  275.  *
  276.  * FUNCTION NAME = Locate_First_Slash
  277.  *
  278.  *
  279.  * DESCRIPTION     =
  280.  *
  281.  *   Purpose:  Locate the / on the command line.  All characters entered prior
  282.  *           to the first / are ignored.  This allows the parser to bypass
  283.  *           the BASEDEV = xxxxxxxx.xxx portion of the command line.
  284.  *
  285.  *   Function Calls:
  286.  *
  287.  *
  288.  *
  289.  *
  290.  * INPUT     = ()
  291.  *
  292.  *
  293.  *
  294.  *
  295.  * OUTPUT     = NONE
  296.  *
  297.  *
  298.  * RETURN-NORMAL = NONE
  299.  *
  300.  * RETURN-ERROR  = NONE
  301.  *
  302.  ****************************************************************************/
  303. STATIC BOOL NEAR Locate_First_Slash(VOID)
  304. {
  305.     while( *pcmdline1 != '\0'  &&  *pcmdline1 != '\n'  &&  *pcmdline1 != '\r' )
  306.     {
  307.     if( *pcmdline1 == '/' )
  308.     {
  309.         pcmdline_slash = pcmdline1;
  310.         return TRUE;
  311.     }
  312.     ++pcmdline1;
  313.     }
  314.     cc.err_index = 0;
  315.     cc.ret_code = NO_OPTIONS_FND_ERR;
  316.     if( pend_option->state[state_index] == R )
  317.     cc.ret_code = REQ_OPT_ERR;
  318.     return FALSE;
  319. }
  320.  
  321.  
  322.  
  323.  
  324. /***************************************************************************
  325.  *
  326.  * FUNCTION NAME = FarStrLen
  327.  *
  328.  *
  329.  * DESCRIPTION     =
  330.  *
  331.  *   Purpose: Return the length of a string
  332.  *
  333.  *
  334.  *   Function Calls:
  335.  *
  336.  *
  337.  *
  338.  *
  339.  * INPUT     = (s)
  340.  *
  341.  *
  342.  *
  343.  *
  344.  * OUTPUT     = NONE
  345.  *
  346.  *
  347.  * RETURN-NORMAL = NONE
  348.  *
  349.  * RETURN-ERROR  = FALSE
  350.  *
  351.  ****************************************************************************/
  352. STATIC INT NEAR FarStrLen(CHAR FAR *s)
  353. {
  354.     INT i;
  355.     for ( i=0; *s != '\0'; ++s )
  356.     ++i;
  357.     return i;
  358. }
  359.  
  360.  
  361. /***************************************************************************
  362.  *
  363.  * FUNCTION NAME = strncmp
  364.  *
  365.  *
  366.  * DESCRIPTION     =
  367.  *
  368.  *   Purpose: Compare n number of characters in 2 strings, return TRUE if =
  369.  *          If s1 is in lower case, convert to upper prior to comparing.
  370.  *
  371.  *   Function Calls:
  372.  *
  373.  *
  374.  *
  375.  *
  376.  * INPUT     = (s1,s2,n)
  377.  *
  378.  *
  379.  *
  380.  *
  381.  * OUTPUT     = NONE
  382.  *
  383.  *
  384.  * RETURN-NORMAL = NONE
  385.  *
  386.  * RETURN-ERROR  = FALSE
  387.  *
  388.  ****************************************************************************/
  389. STATIC BOOL NEAR strncmp(CHAR FAR *s1,CHAR FAR *s2,INT n)
  390. {
  391.     INT i;
  392.     CHAR temp;
  393.  
  394.     for( i = 0; i < n; ++i, ++s1, ++s2 )
  395.     if( *s1 != *s2 )
  396.     {
  397.         if( *s1 >= 'a'  &&  *s1 <= 'z' )
  398.         {
  399.         temp = *s1 - (CHAR)' ';
  400.         if( temp == *s2 )
  401.             continue;
  402.         }
  403.         return FALSE;
  404.     }
  405.     return TRUE;
  406. }
  407.  
  408.  
  409.  
  410.  
  411. /***************************************************************************
  412.  * FUNCTION NAME = Parse_Option_Value
  413.  *
  414.  * DESCRIPTION     =
  415.  *
  416.  *   Purpose: Parse the command line for the value assigned to located option
  417.  *
  418.  *   Function Calls:
  419.  *
  420.  *
  421.  * INPUT     = ()
  422.  *
  423.  * OUTPUT     = NONE
  424.  *
  425.  * RETURN-NORMAL = NONE
  426.  *
  427.  * RETURN-ERROR  = FALSE
  428.  ****************************************************************************/
  429. STATIC BOOL NEAR
  430. Parse_Option_Value()
  431. {
  432.     pcmdline1 = pcmdline_slash+length;
  433.     Skip_Over_Blanks();
  434.     for (tokv_index=0; tokv_index < TOKVBUF_LEN ; ++tokv_index)
  435.     tokvbuf[tokv_index].byte_value = 0;
  436.  
  437.     tokv_index = UNDEFINED;
  438.     cc.ret_code = NO_ERR;
  439.     cc.err_index = 0;
  440.  
  441.     switch (ptable_option->type)
  442.     {
  443.       case TYPE_0:
  444.     break;
  445.  
  446.       case TYPE_CHAR:
  447.     char_parser();
  448.     break;
  449.  
  450.       case TYPE_D:
  451.     d_parser();
  452.     break;
  453.  
  454.       case TYPE_DD:
  455.     dd_parser();
  456.     break;
  457.  
  458.       case TYPE_DDDD:
  459.     dddd_parser();
  460.     break;
  461.  
  462.       case TYPE_ULIST:
  463.     ulist_parser();
  464.     break;
  465.  
  466.       case TYPE_HH:
  467.     hh_parser();
  468.     break;
  469.  
  470.       case TYPE_HHHH:
  471.     hhhh_parser();
  472.     break;
  473.  
  474.       case TYPE_FORMAT:
  475.     format_parser();
  476.     break;
  477.  
  478.       case TYPE_SCSI_ID:
  479.     scsi_id_parser();
  480.     break;
  481.  
  482.       case TYPE_DEV_ID:
  483.     dev_id_parser();
  484.     break;
  485.  
  486.       case TYPE_GEOMETRY:
  487.     geometry_parser();
  488.     break;
  489.  
  490.       case TYPE_CHGLINE:
  491.     chgline_parser();
  492.     break;
  493.  
  494.       default:
  495.     cc.ret_code = UNDEFINED_TYPE_ERR;
  496.     } /* endswitch */
  497.  
  498.     if (cc.ret_code != NO_ERR)
  499.     {
  500.     cc.err_index = pcmdline1 - pcmdline_start;
  501.     return FALSE;
  502.     }
  503.     return TRUE;
  504. }
  505.  
  506.  
  507.  
  508.  
  509. /***************************************************************************
  510.  * FUNCTION NAME = Skip_Over_Blanks
  511.  *
  512.  * DESCRIPTION     =
  513.  *
  514.  *   Purpose:  Skip over all the blank and tab characters
  515.  *
  516.  *
  517.  *   Function Calls:
  518.  *
  519.  * INPUT     = ()
  520.  *
  521.  * OUTPUT     = NONE
  522.  *
  523.  * RETURN-NORMAL = NONE
  524.  *
  525.  * RETURN-ERROR  = FALSE
  526.  ****************************************************************************/
  527. STATIC void NEAR
  528. Skip_Over_Blanks()
  529. {
  530.     while( *pcmdline1 == ' '  ||  *pcmdline1 == '\t' )
  531.     ++pcmdline1;
  532.     return;
  533. }
  534.  
  535.  
  536.  
  537.  
  538. /***************************************************************************
  539.  * FUNCTION NAME = char_parser
  540.  *
  541.  * DESCRIPTION     =
  542.  *
  543.  *   Purpose: TYPE_CHAR option parser - scan till blank,tab,cr,new line or
  544.  *                    end of string char
  545.  *
  546.  *   Function Calls:
  547.  *
  548.  * INPUT     = ()
  549.  *
  550.  * OUTPUT     = NONE
  551.  *
  552.  * RETURN-NORMAL = NONE
  553.  *
  554.  * RETURN-ERROR  = FALSE
  555.  ****************************************************************************/
  556. STATIC void NEAR
  557. char_parser()
  558. {
  559.     while( *pcmdline1 != '\0'  &&  *pcmdline1 != '\n'
  560.       &&  *pcmdline1 != '\r'  &&  *pcmdline1 != '/' )
  561.     {
  562.     tokvbuf[++tokv_index].char_value = *pcmdline1;
  563.     ++pcmdline1;
  564.     }
  565.     return;
  566. }
  567.  
  568.  
  569.  
  570.  
  571. /***************************************************************************
  572.  * FUNCTION NAME = d_parser
  573.  *
  574.  * DESCRIPTION     =
  575.  *
  576.  *   Purpose: TYPE_D option parser - one digit decimal number (d)
  577.  *
  578.  *   Function Calls:
  579.  *
  580.  * INPUT     = ()
  581.  *
  582.  * OUTPUT     = NONE
  583.  *
  584.  * RETURN-NORMAL = NONE
  585.  *
  586.  * RETURN-ERROR  = FALSE
  587.  ****************************************************************************/
  588. STATIC void NEAR
  589. d_parser()
  590. {
  591.     if( (*pcmdline1 >= '0') && (*pcmdline1 <= '9') )
  592.     {
  593.        tokvbuf[++tokv_index].byte_value = *pcmdline1 - (CHAR)'0';
  594.        pcmdline1++;
  595.    }
  596.     else
  597.     {
  598.        cc.ret_code = SYNTAX_ERR;
  599.    }
  600.     return;
  601. }
  602.  
  603.  
  604.  
  605.  
  606. /***************************************************************************
  607.  * FUNCTION NAME = dd_parser
  608.  *
  609.  * DESCRIPTION     =
  610.  *
  611.  *   Purpose: TYPE_DD option parser - two digit decimal number (dd)
  612.  *
  613.  *   Function Calls:
  614.  *
  615.  * INPUT     = ()
  616.  *
  617.  * OUTPUT     = NONE
  618.  *
  619.  * RETURN-NORMAL = NONE
  620.  *
  621.  * RETURN-ERROR  = FALSE
  622.  ****************************************************************************/
  623. STATIC void NEAR
  624. dd_parser()
  625. {
  626.     INT i;
  627.     BYTE n;
  628.     BOOL flag;
  629.  
  630.     n = 0;
  631.     flag = FALSE;
  632.     for ( i=0; i < 2; i++ )
  633.     {
  634.     if( (*pcmdline1 >= '0') && (*pcmdline1 <= '9') )
  635.     {
  636.         n = (BYTE)(10 * n + *pcmdline1 - '0');
  637.         ++pcmdline1;
  638.         flag = TRUE;
  639.     }
  640.     else
  641.     {
  642.         /* Was at least 1 digit found on the command line? */
  643.  
  644.         if( flag )
  645.         break;
  646.         cc.ret_code = SYNTAX_ERR;
  647.         return;
  648.     }
  649.     }
  650.     tokvbuf[++tokv_index].byte_value = n;
  651.     return;
  652. }
  653.  
  654.  
  655.  
  656.  
  657. /*
  658.  * NAME
  659.  *    dddd_parser
  660.  * CALL
  661.  *    dddd_parser(void)
  662.  * PARAMETER
  663.  *    none
  664.  * RETURNS
  665.  *    nothing
  666.  * GLOBAL
  667.  *    cc
  668.  * DESPRIPTION
  669.  *    TYPE_DDDD option parser - four digit decimal number (dddd)
  670.  * REMARKS
  671.  */
  672. STATIC void NEAR
  673. dddd_parser()
  674. {
  675.     int        i;
  676.     NUMBER    un;
  677.     BYTE    c;
  678.     BOOL    flag = FALSE;
  679.  
  680.     un.n = 0;
  681.     flag = FALSE;
  682.     for( i = 0; i < 4; ++i )
  683.     {
  684.     c = *pcmdline1;
  685.     if( c >= '0'  &&  c <= '9' )
  686.     {
  687.         un.n = 10 * un.n + c - '0';
  688.         ++pcmdline1;
  689.         flag = TRUE;
  690.     }
  691.     else
  692.     {
  693.         /* Was at least 1 digit found on the command line? */
  694.  
  695.         if( flag == TRUE )
  696.         break;
  697.         cc.ret_code = SYNTAX_ERR;
  698.         return;
  699.     }
  700.     }
  701.  
  702.     tokvbuf[++tokv_index].byte_value = un.two_bytes.byte1;
  703.     tokvbuf[++tokv_index].byte_value = un.two_bytes.byte2;
  704.     return;
  705. }
  706.  
  707.  
  708.  
  709.  
  710. /*
  711.  * NAME
  712.  * CALL
  713.  * PARAMETER
  714.  * RETURNS
  715.  * GLOBAL
  716.  * DESPRIPTION
  717.  *    TYPE_ULIST option parser - two or three decimal
  718.  *     number (d,d[,d]) list (!)
  719.  *    If only two decimal are supplied the third is
  720.  *    set to '0'.
  721.  * REMARKS
  722.  */
  723. /*STATIC*/ void NEAR
  724. ulist_parser()
  725. {
  726.     int        i;
  727.     int        counter = 0;
  728.     NUMBER    un_number;
  729.     BOOL    flag, inside;
  730.  
  731.     while( TRUE )
  732.     {
  733.     if( counter == 0 )            /* first number in coordinate? */
  734.     {
  735.         if( *pcmdline1 != '(' )
  736.         {
  737.         cc.ret_code = SYNTAX_ERR;    /* no allowed */
  738.         return;
  739.         }
  740.         ++pcmdline1;
  741.         Skip_Over_Blanks();
  742.         inside = TRUE;            /* (inside) */
  743.     }
  744.  
  745.     un_number.n = 0;
  746.     flag = FALSE;
  747.     for( i = 0; i < 4; ++i )
  748.     {
  749.         if( *pcmdline1 >= '0'  &&  *pcmdline1 <= '9' )
  750.         {
  751.         un_number.n = 10 * un_number.n + (*pcmdline1 - '0');
  752.         ++pcmdline1;
  753.         flag = TRUE;
  754.         }
  755.         else
  756.         {
  757.         /* Was at least 1 digit found on the command line? */
  758.         if( flag )
  759.             break;
  760.         cc.ret_code = SYNTAX_ERR;
  761.         return;
  762.         }
  763.     }
  764.     tokvbuf[++tokv_index].byte_value = un_number.two_bytes.byte1;
  765.     tokvbuf[++tokv_index].byte_value = un_number.two_bytes.byte2;
  766.     Skip_Over_Blanks();
  767.  
  768.     if( *pcmdline1 == ')'  &&  (counter == 1  ||  counter == 2) )
  769.     {
  770.         if( counter == 1 )            /* only 2? Third = 0! */
  771.         {
  772.         tokvbuf[++tokv_index].byte_value = 0;
  773.         tokvbuf[++tokv_index].byte_value = 0;
  774.         }
  775.         counter = -1;            /* new coordinate */
  776.         ++pcmdline1;            /* skip ')' */
  777.         Skip_Over_Blanks();
  778.         inside = FALSE;            /* not (inside) */
  779.     }
  780.     else if( counter == 2 )
  781.     {
  782.         cc.ret_code = SYNTAX_ERR;
  783.         return;
  784.     }
  785.     if( *pcmdline1 != ',' )
  786.     {
  787.         if( inside )
  788.         cc.ret_code = SYNTAX_ERR;    /* missing ')' */
  789.         return;
  790.     }
  791.     ++pcmdline1;                /* skip ',' */
  792.     Skip_Over_Blanks();
  793.     ++counter;
  794.     }
  795.  
  796.     return;
  797. }
  798.  
  799.  
  800.  
  801.  
  802. /***************************************************************************
  803.  * FUNCTION NAME = hh_parser
  804.  *
  805.  * DESCRIPTION     =
  806.  *
  807.  *   Purpose: TYPE_HH option parser       hh,hh format (h = hex char)
  808.  *
  809.  *   Function Calls:
  810.  *
  811.  * INPUT     = ()
  812.  *
  813.  * OUTPUT     = NONE
  814.  *
  815.  * RETURN-NORMAL = NONE
  816.  *
  817.  * RETURN-ERROR  = FALSE
  818.  ****************************************************************************/
  819. STATIC void NEAR
  820. hh_parser()
  821. {
  822.     /* Convert command line HH char and setup token value buffer */
  823.  
  824.     if( !HH_Char_To_Byte() )
  825.     return;
  826.     Skip_Over_Blanks();
  827.  
  828.     if( *pcmdline1 != ',' )
  829.     {
  830.     cc.ret_code = SYNTAX_ERR;
  831.     return;
  832.     }
  833.     ++pcmdline1;
  834.     Skip_Over_Blanks();
  835.  
  836.     /* Convert command line HH char and setup token value buffer */
  837.  
  838.     HH_Char_To_Byte();
  839.     return;
  840. }
  841.  
  842.  
  843.  
  844.  
  845. /***************************************************************************
  846.  * FUNCTION NAME = HH_Char_To_Byte
  847.  *
  848.  * DESCRIPTION     =
  849.  *
  850.  *   Purpose: Convert HH char to byte value
  851.  *
  852.  *   Function Calls:
  853.  *
  854.  * INPUT     = ()
  855.  *
  856.  * OUTPUT     = NONE
  857.  *
  858.  * RETURN-NORMAL = NONE
  859.  *
  860.  * RETURN-ERROR  = FALSE
  861.  ****************************************************************************/
  862. STATIC BOOL NEAR
  863. HH_Char_To_Byte()
  864. {
  865.     BYTE  n;
  866.     INT   i;
  867.     BOOL  flag = FALSE;
  868.     BYTE  c;
  869.  
  870.     n = 0;
  871.     for( i = 0; i < 2; ++i )
  872.     {
  873.     c = *pcmdline1;
  874.     if( c >= '0'  &&  c <= '9' )
  875.     {
  876.         n = (BYTE)(16 * n + c - '0');
  877.         ++pcmdline1;
  878.         flag = TRUE;
  879.         continue;
  880.     }
  881.     c |= 0x20;                /* convert to lower case */
  882.     if( c >= 'a'  &&  c <= 'f' )
  883.     {
  884.         n = (BYTE)(16 * n + c - 'W');
  885.         ++pcmdline1;
  886.         flag = TRUE;
  887.         continue;
  888.     }
  889.  
  890.     /* Was at least 1 hex digit found on the command line? */
  891.  
  892.     if( flag )
  893.         break;
  894.     cc.ret_code = SYNTAX_ERR;
  895.     return FALSE;
  896.     }
  897.  
  898.     tokvbuf[++tokv_index].byte_value = n;
  899.     return TRUE;
  900. }
  901.  
  902.  
  903.  
  904.  
  905. /***************************************************************************
  906.  * FUNCTION NAME = hhhh_parser
  907.  *
  908.  * DESCRIPTION     =
  909.  *
  910.  *   Purpose: TYPE_HHHH option parser        hhhh format (h = hex char)
  911.  *
  912.  *   Function Calls:
  913.  *
  914.  * INPUT     = ()
  915.  *
  916.  * OUTPUT     = NONE
  917.  *
  918.  * RETURN-NORMAL = NONE
  919.  *
  920.  * RETURN-ERROR  = FALSE
  921.  ****************************************************************************/
  922. STATIC void NEAR
  923. hhhh_parser()
  924. {
  925.     INT    i;
  926.     BOOL   flag;
  927.     NUMBER un_number;
  928.     BYTE   c;
  929.  
  930.     un_number.n = 0;
  931.     flag = FALSE;
  932.     for( i = 0; i < 4; ++i )
  933.     {
  934.     c = *pcmdline1;
  935.     if( c >= '0'  &&  c <= '9' )
  936.     {
  937.         un_number.n = 16 * un_number.n + c - '0';
  938.         ++pcmdline1;
  939.         flag = TRUE;
  940.         continue;
  941.     }
  942.     c |= 0x20;
  943.     if( c >= 'a'  &&  c <= 'f' )
  944.     {
  945.         un_number.n = 16*un_number.n + c - 'W';
  946.         ++pcmdline1;
  947.         flag = TRUE;
  948.         continue;
  949.     }
  950.  
  951.     /* Was at least 1 hex digit found on the command line? */
  952.  
  953.     if( flag )
  954.         break;
  955.     cc.ret_code = SYNTAX_ERR;
  956.     return;
  957.     }
  958.  
  959.     tokvbuf[++tokv_index].byte_value = un_number.two_bytes.byte1;
  960.     tokvbuf[++tokv_index].byte_value = un_number.two_bytes.byte2;
  961.     return;
  962. }
  963.  
  964.  
  965.  
  966.  
  967. /***************************************************************************
  968.  * FUNCTION NAME = format_parser
  969.  *
  970.  * DESCRIPTION     =
  971.  *
  972.  *   Purpose: TYPE_FORMAT option parser -  format_table chars accepted
  973.  *
  974.  *   Function Calls:
  975.  *
  976.  * INPUT     = ()
  977.  *
  978.  * OUTPUT     = NONE
  979.  *
  980.  * RETURN-NORMAL = NONE
  981.  *
  982.  * RETURN-ERROR  = NONE
  983.  ****************************************************************************/
  984. STATIC void NEAR
  985. format_parser()
  986. {
  987.     typedef struct _formattable {
  988.     PSZ string;
  989.     USHORT type;
  990.     NUMBER MegBytes;
  991.     } FORMATTABLE;
  992.  
  993.     /*
  994.      * FORMATTABLE type definitions
  995.      * accepts # string followed by:
  996.      */
  997.  
  998. #define  M_BYTES       1           /* accepts MB,mb,Mb,mB, or nothing */
  999. #define  K_BYTES       2           /* accepts KB,kb,Kb,kB, or nothing */
  1000.  
  1001.     INT str_len,k;
  1002.     static FORMATTABLE format_table[] = {
  1003.     { "360",K_BYTES,360 } ,
  1004.     { "720",K_BYTES,720 } ,
  1005.     { "1200",K_BYTES,1200 } ,
  1006.     { "1.2",M_BYTES,1200 } ,
  1007.     { "1440",K_BYTES,1440 } ,
  1008.     { "1.44",M_BYTES,1440 } ,
  1009.     { "2880",K_BYTES,2880 } ,
  1010.     { "2    .88",M_BYTES,2880 } ,
  1011.     { "-1" } ,                          /* , ???? */
  1012.     };
  1013.  
  1014.     cc.ret_code = SYNTAX_ERR;
  1015.     for( k = 0; (format_table[k].string != "-1"); ++k )
  1016.     {
  1017.     str_len = FarStrLen(format_table[k].string);
  1018.     if( strncmp(pcmdline1, format_table[k].string, str_len) == TRUE )
  1019.     {
  1020.         pcmdline1 += str_len;
  1021.         if( format_table[k].type == K_BYTES )
  1022.         {
  1023.         if( *pcmdline1 == 'K'  || *pcmdline1 == 'k' )
  1024.         {
  1025.             ++pcmdline1;
  1026.             if( *(pcmdline1) == 'B'  ||  *(pcmdline1) == 'b' )
  1027.             ++pcmdline1;
  1028.         }
  1029.         }
  1030.         else
  1031.         {
  1032.         if( *pcmdline1 == 'M'  ||  *pcmdline1 == 'm' )
  1033.         {
  1034.             ++pcmdline1;
  1035.             if( *(pcmdline1) == 'B'  ||  *(pcmdline1) == 'b' )
  1036.             ++pcmdline1;
  1037.         }
  1038.         }
  1039.         ++tokv_index;
  1040.         tokvbuf[tokv_index].byte_value
  1041.         = format_table[k].MegBytes.two_bytes.byte1;
  1042.         ++tokv_index;
  1043.         tokvbuf[tokv_index].byte_value
  1044.         = format_table[k].MegBytes.two_bytes.byte2;
  1045.         cc.ret_code = NO_ERR;
  1046.         break;
  1047.     }
  1048.     }
  1049.  
  1050.     return;
  1051. }
  1052.  
  1053.  
  1054.  
  1055.  
  1056. /***************************************************************************
  1057.  * FUNCTION NAME = scsi_id_parser
  1058.  *
  1059.  * DESCRIPTION     =
  1060.  *
  1061.  *   Purpose: TYPE_SCSI_ID option parser - format d and (d,d) accepted
  1062.  *                       where d = 0 - 7
  1063.  *
  1064.  *   Function Calls:
  1065.  *
  1066.  * INPUT     = ()
  1067.  *
  1068.  * OUTPUT     = NONE
  1069.  *
  1070.  * RETURN-NORMAL = NONE
  1071.  *
  1072.  * RETURN-ERROR  = FALSE
  1073.  ****************************************************************************/
  1074. STATIC void NEAR
  1075. scsi_id_parser()
  1076. {
  1077.     BOOL found_bracket, found_one;
  1078.  
  1079.     found_bracket = FALSE;
  1080.     found_one = FALSE;
  1081.     if( *pcmdline1 == '(' )
  1082.     {
  1083.     found_bracket = TRUE;
  1084.     ++pcmdline1;
  1085.     Skip_Over_Blanks();
  1086.     }
  1087.     while( *pcmdline1 >= '0'  &&  *pcmdline1 <= '7' )
  1088.     {
  1089.     found_one = TRUE;
  1090.     tokv_index++;
  1091.     tokvbuf[tokv_index].byte_value = (BYTE)(*pcmdline1 - '0');
  1092.     ++pcmdline1;
  1093.     if( !found_bracket )
  1094.     {
  1095.         ++tokv_index;
  1096.         tokvbuf[tokv_index].byte_value = 0;
  1097.     }
  1098.     Skip_Over_Blanks();
  1099.     if( *pcmdline1 != ',' )
  1100.     {
  1101.         if( found_bracket )
  1102.         cc.ret_code = SYNTAX_ERR;
  1103.         return;
  1104.     }
  1105.     ++pcmdline1;
  1106.     Skip_Over_Blanks();
  1107.     if( found_bracket )
  1108.     {
  1109.         if( *pcmdline1 >= '0'  && *pcmdline1 <= '7' )
  1110.         {
  1111.         ++tokv_index;
  1112.         tokvbuf[tokv_index].byte_value = (BYTE)(*pcmdline1 - '0');
  1113.         ++pcmdline1;
  1114.         Skip_Over_Blanks();
  1115.         if( *pcmdline1 != ')' )
  1116.         {
  1117.             cc.ret_code = SYNTAX_ERR;
  1118.             return;
  1119.         }
  1120.         ++pcmdline1;
  1121.         Skip_Over_Blanks();
  1122.         found_bracket = FALSE;
  1123.         if( *pcmdline1 != ',' )
  1124.             return;
  1125.         ++pcmdline1;
  1126.         Skip_Over_Blanks();
  1127.         }
  1128.     }
  1129.     if( *pcmdline1 == '(' )
  1130.     {
  1131.         found_bracket = TRUE;
  1132.         pcmdline1++;
  1133.         Skip_Over_Blanks();
  1134.     }
  1135.     }
  1136.  
  1137.     if( found_bracket )
  1138.     cc.ret_code = SYNTAX_ERR;
  1139.     if( !found_one )
  1140.     cc.ret_code = SYNTAX_ERR;
  1141.     return;
  1142. }
  1143.  
  1144.  
  1145.  
  1146.  
  1147. /***************************************************************************
  1148.  * FUNCTION NAME = dev_id_parser
  1149.  *
  1150.  * DESCRIPTION     =
  1151.  *
  1152.  *   Purpose: TYPE_DEV_ID option parser - format c, (c,d) and (c,d,d) accepted
  1153.  *                       where d = 0 - 7
  1154.  *                       and     c = 0 - 9
  1155.  *
  1156.  *   Function Calls:
  1157.  *
  1158.  * INPUT     = ()
  1159.  *
  1160.  * OUTPUT     = NONE
  1161.  *
  1162.  * RETURN-NORMAL = NONE
  1163.  *
  1164.  * RETURN-ERROR  = FALSE
  1165.  *
  1166.  * 940215/VJ: Generated from scsi_id_parser() see CMDPDEFS.H for description
  1167.  *          of token
  1168.  ****************************************************************************/
  1169. VOID NEAR dev_id_parser()
  1170. {
  1171.     BOOL found_bracket=FALSE;
  1172.     BOOL found_one=FALSE;
  1173.  
  1174.     /* A SCSI coordinate may be contained in brackets */
  1175.     if( *pcmdline1 == '(' )
  1176.     {
  1177.     found_bracket = TRUE;
  1178.     ++pcmdline1;
  1179.     Skip_Over_Blanks();
  1180.     }
  1181.  
  1182.     /* Scan coordinates, first is cache device or scsi channel
  1183.      * and may evaluate to any value (currently supported 0-9). */
  1184.  
  1185.     while( *pcmdline1 >= '0'  &&  *pcmdline1 <= '9' )
  1186.     {
  1187.     found_one = TRUE;
  1188.     tokvbuf[++tokv_index].byte_value = *pcmdline1 - (CHAR)'0';
  1189.     ++pcmdline1;
  1190.     Skip_Over_Blanks();
  1191.  
  1192.     if( *pcmdline1 != ',' )            /* more coordinates? */
  1193.     {                    /*  NO */
  1194.         if( found_bracket )            /* started w/ bracket? */
  1195.         cc.ret_code = SYNTAX_ERR;    /*  have to stop w/ bracket! */
  1196.         tokvbuf[++tokv_index].byte_value = (CHAR)-1;
  1197.         tokvbuf[++tokv_index].byte_value = (CHAR)-1; /* fill w/ -1 */
  1198.         return;
  1199.     }
  1200.     ++pcmdline1;
  1201.     Skip_Over_Blanks();
  1202.  
  1203.     if( found_bracket )            /* started w/ brackets? */
  1204.     {                    /*  YES, more may come */
  1205.         if ( *pcmdline1 >= '0'  &&  *pcmdline1 <= '7' )
  1206.         {
  1207.         tokvbuf[++tokv_index].byte_value = *pcmdline1 - (CHAR)'0';
  1208.         ++pcmdline1;
  1209.         Skip_Over_Blanks();
  1210.  
  1211.         if( *pcmdline1 == ',' )        /* ',' behind 2nd coord. ? */
  1212.         {                /*  YES, 3rd coord. follows */
  1213.             ++pcmdline1;
  1214.             Skip_Over_Blanks();
  1215.             if( *pcmdline1 >= '0'  &&  *pcmdline1 <= '7' )
  1216.             {
  1217.             tokvbuf[++tokv_index].byte_value = *pcmdline1 - (CHAR)'0';
  1218.             ++pcmdline1;
  1219.             Skip_Over_Blanks();
  1220.             }
  1221.             else
  1222.             {
  1223.             cc.ret_code = SYNTAX_ERR;
  1224.             return;
  1225.             }
  1226.         }
  1227.         else
  1228.         {
  1229.             tokvbuf[++tokv_index].byte_value = (CHAR)-1; /* 3rd coord. not supplied */
  1230.         }
  1231.  
  1232.         if( *pcmdline1 != ')' )
  1233.         {
  1234.             cc.ret_code = SYNTAX_ERR;
  1235.             return;
  1236.         }
  1237.         ++pcmdline1;
  1238.         Skip_Over_Blanks();
  1239.  
  1240.         found_bracket = FALSE;
  1241.         if( *pcmdline1 != ',' )
  1242.             return ;
  1243.         ++pcmdline1;
  1244.         Skip_Over_Blanks();
  1245.         }
  1246.     }
  1247.     else
  1248.     {
  1249.         tokvbuf[++tokv_index].byte_value = (CHAR)-1;
  1250.         tokvbuf[++tokv_index].byte_value = (CHAR)-1; /* fill w/ -1 */
  1251.     }
  1252.  
  1253.     if( *pcmdline1 == '(' )
  1254.     {
  1255.         found_bracket = TRUE;
  1256.         ++pcmdline1;
  1257.         Skip_Over_Blanks();
  1258.     }
  1259.     }
  1260.  
  1261.     if( found_bracket )                /* missing closing bracket */
  1262.     cc.ret_code = SYNTAX_ERR;
  1263.     if( !found_one )                /* no numbers */
  1264.     cc.ret_code = SYNTAX_ERR;
  1265.     return;
  1266. }
  1267.  
  1268.  
  1269.  
  1270.  
  1271. /***************************************************************************
  1272.  * FUNCTION NAME = geometry_parser
  1273.  *
  1274.  * DESCRIPTION     =
  1275.  *
  1276.  *   Purpose: TYPE_GEOMETRY option parser - dd or (dddd,dddd,dddd) accepted
  1277.  *
  1278.  *   Function Calls:
  1279.  *
  1280.  * INPUT     = ()
  1281.  *
  1282.  * OUTPUT     = NONE
  1283.  *
  1284.  * RETURN-NORMAL = NONE
  1285.  *
  1286.  * RETURN-ERROR  = FALSE
  1287.  ****************************************************************************/
  1288. STATIC void NEAR
  1289. geometry_parser()
  1290. {
  1291.     INT        i, counter;
  1292.     USHORT    base;
  1293.     NUMBER    un_number;
  1294.     BOOL    flag;
  1295.  
  1296.     if( *pcmdline1 != '(' )
  1297.     {
  1298.     dd_parser();
  1299.     return;
  1300.     }
  1301.     ++pcmdline1;
  1302.     Skip_Over_Blanks();
  1303.     counter = 0;
  1304.     while( TRUE )
  1305.     {
  1306.     un_number.n = 0;
  1307.     base = 10;
  1308.     flag = FALSE;
  1309.  
  1310.     for( i = 0; i < 4; ++i )        /* max. 4 digits */
  1311.     {
  1312.       REDO_NO:
  1313.         if( *pcmdline1 >= '0'  &&  *pcmdline1 <= '9' )
  1314.         {
  1315.         un_number.n = base * un_number.n + *pcmdline1 - '0';
  1316.         ++pcmdline1;
  1317.         flag = TRUE;
  1318.         }
  1319.         else if( base == 16  &&  *pcmdline1 >= 'A'  &&  *pcmdline1 <= 'F' )
  1320.         {
  1321.         un_number.n = base * un_number.n + *pcmdline1 - 'A' + 10;
  1322.         ++pcmdline1;
  1323.         flag = TRUE;
  1324.         }
  1325.         else if( base == 16  &&  *pcmdline1 >= 'a'  &&  *pcmdline1 <= 'f' )
  1326.         {
  1327.         un_number.n = base * un_number.n + *pcmdline1 - 'a' + 10;
  1328.         ++pcmdline1;
  1329.         flag = TRUE;
  1330.         }
  1331.         else if( *pcmdline1 == 'x' )
  1332.         {
  1333.         ++pcmdline1;
  1334.         un_number.n = 0;
  1335.         base = 16;
  1336.         flag = FALSE;
  1337.         i = 0;
  1338.         goto REDO_NO;            /* switch to hex */
  1339.         }
  1340.         else
  1341.         {
  1342.         /* Was at least 1 digit found on the command line? */
  1343.  
  1344.         if( flag )
  1345.             break;
  1346.         cc.ret_code = SYNTAX_ERR;
  1347.         return;
  1348.         }
  1349.     } /* max. 4 digits */
  1350.  
  1351.     ++tokv_index;
  1352.     tokvbuf[tokv_index].byte_value = un_number.two_bytes.byte1;
  1353.     ++tokv_index;
  1354.     tokvbuf[tokv_index].byte_value = un_number.two_bytes.byte2;
  1355.     Skip_Over_Blanks();
  1356.     if( counter == 2 )            /* got a complete triple */
  1357.     {
  1358.         if( *pcmdline1 != ')' )
  1359.         {
  1360.         cc.ret_code = SYNTAX_ERR;
  1361.         return;
  1362.         }
  1363.         ++pcmdline1;            /* skip ')' */
  1364.         if( *pcmdline1 != ',' )
  1365.         return;                /* end of option, OK */
  1366.  
  1367.         ++pcmdline1;            /* skip ',' */
  1368.         if( *pcmdline1 != '(')        /* start of next triple? */
  1369.         {
  1370.         cc.ret_code = SYNTAX_ERR;
  1371.         return;
  1372.         }
  1373.         counter = 0;            /* reset counter */
  1374.     }
  1375.     else
  1376.     {
  1377.         if( *pcmdline1 != ',' )
  1378.         {
  1379.         cc.ret_code = SYNTAX_ERR;
  1380.         return;
  1381.         }
  1382.         ++counter;                /* another part of a triple */
  1383.     }
  1384.     ++pcmdline1;                /* skip ',' or '(' */
  1385.     Skip_Over_Blanks();
  1386.     } /* end[while(TRUE)] */
  1387.  
  1388.     return;
  1389. }
  1390.  
  1391.  
  1392.  
  1393.  
  1394. /***************************************************************************
  1395.  * FUNCTION NAME = chgline_parser
  1396.  *
  1397.  * DESCRIPTION     =
  1398.  *
  1399.  *   Purpose: TYPE_CHGLINE option parser - Valid options: PS2
  1400.  *                              AT
  1401.  *                              NONE
  1402.  *
  1403.  *   Function Calls:
  1404.  *
  1405.  * INPUT     = ()
  1406.  *
  1407.  * OUTPUT     = NONE
  1408.  *
  1409.  * RETURN-NORMAL = NONE
  1410.  *
  1411.  * RETURN-ERROR  = NONE
  1412.  ****************************************************************************/
  1413. STATIC void NEAR
  1414. chgline_parser()
  1415. {
  1416.     USHORT k, str_len;
  1417.     NPBYTE chgline_opts[] = { "\0","NONE","AT","PS2" };
  1418.  
  1419.     for( k = 1; k < sizeof(chgline_opts)/sizeof(chgline_opts[0]); ++k )
  1420.     {
  1421.     str_len = FarStrLen( chgline_opts[k] );
  1422.     if( strncmp(pcmdline1, chgline_opts[k], str_len) )
  1423.     {
  1424.         pcmdline1 += str_len;
  1425.         ++tokv_index;
  1426.         tokvbuf[tokv_index].byte_value = (BYTE)k;
  1427.         return;
  1428.     }
  1429.     }
  1430.     cc.ret_code = SYNTAX_ERR;
  1431.     return;
  1432. }
  1433.  
  1434.  
  1435.  
  1436.  
  1437. /***************************************************************************
  1438.  * FUNCTION NAME = Insert_Token
  1439.  *
  1440.  * DESCRIPTION     =
  1441.  *
  1442.  *   Purpose: Insert the parsed option (token) into the output buffer.
  1443.  *
  1444.  *   Function Calls:
  1445.  *
  1446.  * INPUT     = ()
  1447.  *
  1448.  * OUTPUT     = NONE
  1449.  *
  1450.  * RETURN-NORMAL = NONE
  1451.  *
  1452.  * RETURN-ERROR  = FALSE
  1453.  ****************************************************************************/
  1454. STATIC BOOL NEAR
  1455. Insert_Token()
  1456. {
  1457.     USHORT    tok_size;
  1458.     INT        t;
  1459.  
  1460.     tok_size = TOK_MIN_LENGTH + tokv_index;
  1461.     if( (poutbuf1+tok_size+TOKL_ID_END) >= poutbuf_end )
  1462.     {
  1463.     cc.err_index = pcmdline_slash - pcmdline_start;
  1464.     cc.ret_code = BUF_TOO_SMALL_ERR;
  1465.     return FALSE;
  1466.     }
  1467.     *poutbuf1 = (BYTE)(tok_size + 1);
  1468.     ++poutbuf1;
  1469.     *poutbuf1 = (BYTE)ptable_option->id;
  1470.     ++poutbuf1;
  1471.     if( tokv_index != UNDEFINED )
  1472.     {
  1473.     for( t = 0; t <= tokv_index; ++t )
  1474.     {
  1475.         *poutbuf1 = tokvbuf[t].byte_value;
  1476.         ++poutbuf1;
  1477.     }
  1478.     }
  1479.     Insert_End_Token();
  1480.     return TRUE;
  1481. }
  1482.  
  1483.  
  1484.  
  1485.  
  1486. /***************************************************************************
  1487.  * FUNCTION NAME = Locate_Next_Slash
  1488.  *
  1489.  * DESCRIPTION     =
  1490.  *
  1491.  *   Purpose: Locate the next / char.
  1492.  *
  1493.  *   Function Calls:
  1494.  *
  1495.  * INPUT     = ()
  1496.  *
  1497.  * OUTPUT     = NONE
  1498.  *
  1499.  * RETURN-NORMAL = NONE
  1500.  *
  1501.  * RETURN-ERROR  = NONE
  1502.  ****************************************************************************/
  1503. STATIC BOOL NEAR
  1504. Locate_Next_Slash()
  1505. {
  1506.     while( *pcmdline1 != '\0'  &&  *pcmdline1 != '\n'  &&  *pcmdline1 != '\r' )
  1507.     {
  1508.     if( *pcmdline1 == ' '  ||  *pcmdline1 == '\t' )
  1509.     {
  1510.         ++pcmdline1;
  1511.     }
  1512.     else
  1513.     {
  1514.         if( *pcmdline1 == '/' )
  1515.         {
  1516.         pcmdline_slash = pcmdline1;
  1517.         return TRUE;
  1518.         }
  1519.         else
  1520.         {
  1521.         cc.ret_code = INVALID_OPT_ERR;
  1522.         cc.err_index = pcmdline1 - pcmdline_start;
  1523.         return FALSE;
  1524.         }
  1525.     }
  1526.     } /* endwhile */
  1527.     if( pend_option->state[state_index] == R )
  1528.     {
  1529.     cc.ret_code = REQ_OPT_ERR;
  1530.     cc.err_index = pcmdline1 - pcmdline_start;
  1531.     }
  1532.     else
  1533.     {
  1534.     cc.ret_code = NO_ERR;
  1535.     cc.err_index = 0;
  1536.     }
  1537.  
  1538.     return FALSE;
  1539. }
  1540.  
  1541.  
  1542.  
  1543.  
  1544. /***************************************************************************
  1545.  * FUNCTION NAME = Validate_State_Index
  1546.  *
  1547.  * DESCRIPTION     =
  1548.  *
  1549.  *   Purpose: Validate the State Index
  1550.  *
  1551.  *   Function Calls:
  1552.  *
  1553.  * INPUT     = (maxstate)
  1554.  *
  1555.  * OUTPUT     = NONE
  1556.  *
  1557.  * RETURN-NORMAL = NONE
  1558.  *
  1559.  * RETURN-ERROR  = FALSE
  1560.  ****************************************************************************/
  1561. STATIC BOOL NEAR
  1562. Validate_State_Index(USHORT maxstate)
  1563. {
  1564.     if( state_index > maxstate  ||  state_index < 0 )
  1565.     {
  1566.     cc.ret_code = UNDEFINED_STATE_ERR;
  1567.     cc.err_index = 0;
  1568.     return FALSE;
  1569.     }
  1570.     return TRUE;
  1571. }
  1572.  
  1573.  
  1574. /* History:
  1575.  *
  1576.  * $Log: cmdparse.c,v $
  1577.  * Revision 1.4  1997/12/08 22:57:06  vitus
  1578.  * - did overwrite memory in Parse_Option_Value, fixed
  1579.  *
  1580.  * Revision 1.3  1997/12/06 01:00:30  vitus
  1581.  * - geometry_parser: expanded to accept several triples
  1582.  *
  1583.  * Revision 1.2  1997/10/28 01:53:33  vitus
  1584.  * - geometry_parser accepts hex values
  1585.  *
  1586.  * Imported from DSKSleep code (original IBM DDK for OS/2)
  1587.  */
  1588.