home *** CD-ROM | disk | FTP | other *** search
- /*DDK*************************************************************************/
- /* */
- /* COPYRIGHT Copyright (C) 1995 IBM Corporation */
- /* */
- /* The following IBM OS/2 WARP source code is provided to you solely for */
- /* the purpose of assisting you in your development of OS/2 WARP device */
- /* drivers. You may use this code in accordance with the IBM License */
- /* Agreement provided in the IBM Device Driver Source Kit for OS/2. This */
- /* Copyright statement may not be removed. */
- /* */
- /*****************************************************************************/
- /*static char *SCCSID = "src/dev/dasd/os2aspi/cmdparse.c, aspi, r206 93/03/20";*/
- /**************************************************************************
- *
- * SOURCE FILE NAME = ASPIDATA.C
- *
- * DESCRIPTIVE NAME = OS2ASPI.DMD - OS/2 ASPI Device Manager
- * ADD CONFIG.SYS Command Line Parser Helper Routine
- *
- *
- *
- * VERSION = V2.0
- *
- * DATE: 2/11/92
- *
- * DESCRIPTION : ASPI Device Manager - This module consists of the
- * Command_Parser Function and its associated local
- * routines. For detailed description of the
- * Command_Parser interface refer to the CMDPROTO.H
- * file.
- *
- * EXTERNAL REFERENCES: *
- * BASEDEF.H - Type Definitions (OS2.H) *
- * CMDPARSE.H - Command_Parser Definitions *
- * CMDPROTO.H - Command_Parser Prototype *
- *
- */
- #if !(defined(OS2_INCLUDED))
- #define INCL_NOBASEAPI
- #define INCL_NOPMAPI
- #include "OS2.H"
- #endif
-
- #include <cmdphdr.h>
- #include <cmdproto.h>
-
- #define TOKVBUF_LEN 255
- #define UNDEFINED -1
-
- PSZ pcmdline1, pcmdline_slash, pcmdline_start;
- INT tokv_index, state_index, length;
- CHARBYTE tokvbuf[TOKVBUF_LEN];
- POPT pend_option, ptable_option;
- BYTE *poutbuf1, *poutbuf_end;
- CC cc;
-
- //
- // Command_Parser - external entry point into this module
- //
-
- CC FAR Command_Parser(pCmdLine,pOptTable,pOutBuf,OutBuf_Len)
-
- PSZ pCmdLine;
- POPTIONTABLE pOptTable;
- PBYTE pOutBuf;
- USHORT OutBuf_Len;
-
- {
- USHORT j, end_index;
-
- if (OutBuf_Len < (TOKL_ID_END + TOK_MIN_LENGTH))
- {
- cc.ret_code = BUF_TOO_SMALL_ERR;
- cc.err_index = 0;
- return (cc);
- }
-
- poutbuf_end = pOutBuf + OutBuf_Len;
-
- poutbuf1 = pOutBuf;
- for (poutbuf1 = pOutBuf;
- (poutbuf1 < poutbuf_end);
- poutbuf1++)
- *poutbuf1 = 0;
- poutbuf1 = pOutBuf;
-
- Insert_End_Token();
-
- //
- // Locate the last entry in the Option Table. This special entry
- // defines whether or not an option is required based on the index
- // in the state table.
- //
- for (end_index = 0 ;
- (pOptTable->poption[end_index]->id != TOK_ID_END);
- end_index++);
- pend_option = pOptTable->poption[end_index];
-
- //
- // Setup the initial index into the state table.
- //
- state_index = pOptTable->entry_state;
- if (!Validate_State_Index(pOptTable->max_states))
- return (cc);
-
- //
- // On return from Locate_First_Slash call pcmdline_slash
- // contains the ptr to the / in the command line.
- //
- pcmdline_start = pCmdLine;
- pcmdline1 = pCmdLine;
- if (!Locate_First_Slash())
- return (cc);
-
- for (j=0;j < end_index;j++)
- {
- //
- // Locate valid options in Option Table, based on state table index.
- //
- if (pOptTable->poption[j]->state[state_index] != E)
- {
- //
- // Found a valid option. Check to see if this is the option
- // entered at this point in command line.
- //
- ptable_option = pOptTable->poption[j];
- length = strlength(ptable_option->string);
- if (strncmp(pcmdline_slash,ptable_option->string, length) == TRUE)
- {
-
- //
- // Found the command line option. Now, syntax check its
- // associated value.
- //
- if (!Parse_Option_Value())
- return (cc);
-
- //
- // No syntax err detected. Now, insert the option and its
- // associated value into the output buffer in token format.
- //
- if (!Insert_Token())
- return (cc);
-
- //
- // Setup next index into the state table.
- //
- state_index = ptable_option->state[state_index];
- if (!Validate_State_Index(pOptTable->max_states))
- return (cc);
-
- //
- // Setup cmdline_slash to point the the next / (option) in
- // the command line.
- // Parsing stops once either an invalid character is
- // found on the command line or the end of the command line
- // is detected.
- //
- if (!Locate_Next_Slash())
- return (cc);
-
- //
- // Setup for option search. Point to the top of the Option Table.
- //
- j = -1;
-
- } /* endif */
-
- } /* endif */
-
- } /* endfor */
-
-
- if (pend_option->state[state_index] == R)
- {
- //
- // A required option was not found on the command line.
- //
- cc.ret_code = REQ_OPT_ERR;
- }
- else
- {
- //
- // Characters on the command line are not defined in the Option Table
- // as a valid option. All options must start with a / character.
- //
- cc.ret_code = INVALID_OPT_ERR;
- }
- cc.err_index = pcmdline_slash-pCmdLine;
- return (cc);
-
- }
-
- /*******************************************************************************
- * *
- * FUNCTION: Insert the end of token marker into the output buffer *
- * *
- *******************************************************************************/
- VOID NEAR Insert_End_Token()
- {
- *poutbuf1 = TOKL_ID_END;
- *(poutbuf1+1) = TOK_ID_END;
- return;
- }
-
- /*******************************************************************************
- * *
- * FUNCTION: Locate the / on the command line. All characters entered prior *
- * to the first / are ignored. This allows the parser to bypass *
- * the BASEDEV = xxxxxxxx.xxx portion of the command line. *
- * *
- *******************************************************************************/
- BOOL NEAR Locate_First_Slash()
- {
-
-
- while ((*pcmdline1 != '\0') &&
- (*pcmdline1 != '\n') &&
- (*pcmdline1 != '\r'))
- {
- if (*pcmdline1 == '/')
- {
- pcmdline_slash = pcmdline1;
- return(TRUE);
- }
-
- pcmdline1++;
- }
-
- cc.err_index = 0;
- cc.ret_code = NO_OPTIONS_FND_ERR;
- if (pend_option->state[state_index] == R)
- cc.ret_code = REQ_OPT_ERR;
-
- return(FALSE);
- }
-
- /*******************************************************************************
- * *
- * FUNCTION: Return the length of a string *
- * *
- *******************************************************************************/
- INT NEAR strlength(s)
-
- CHAR FAR *s;
- {
- INT i;
-
- for (i = 0; *s != '\0' ; s++)
- i++;
-
- return(i);
- }
-
- /*******************************************************************************
- * *
- * FUNCTION: Compare n number of characters in 2 strings, return TRUE if = *
- * If s1 is in lower case, convert to upper prior to comparing. *
- * *
- *******************************************************************************/
- BOOL NEAR strncmp(s1,s2,n)
-
- CHAR FAR *s1, FAR *s2;
- INT n;
- {
- INT i;
- CHAR temp;
-
- for (i=0;i < n;i++,s1++,s2++)
-
- if (*s1 != *s2)
- {
- if ((*s1 >= 'a') && (*s1 <= 'z'))
- {
- temp = *s1 - ' ';
- if (temp == *s2)
- continue;
- }
- return(FALSE);
- }
-
- return(TRUE);
- }
-
- /*******************************************************************************
- * *
- * FUNCTION: Parse the command line for the value assigned to located option *
- * *
- *******************************************************************************/
- BOOL NEAR Parse_Option_Value()
- {
- pcmdline1 = pcmdline_slash + length;
- Skip_Over_Blanks();
-
- for (tokv_index = 0; tokv_index <= TOKVBUF_LEN; tokv_index++)
- tokvbuf[tokv_index].byte_value= 0;
-
- tokv_index = UNDEFINED;
-
- cc.ret_code = NO_ERR;
- cc.err_index = 0;
-
- switch (ptable_option->type)
- {
- case TYPE_0:
- break;
-
- case TYPE_CHAR:
- char_parser();
- break;
-
- case TYPE_D:
- d_parser();
- break;
-
- case TYPE_DD:
- dd_parser();
- break;
-
- case TYPE_HH:
- hh_parser();
- break;
-
- case TYPE_HHHH:
- hhhh_parser();
- break;
-
- case TYPE_FORMAT:
- format_parser();
- break;
-
- case TYPE_SCSI_ID:
- scsi_id_parser();
- break;
-
- case TYPE_GEOMETRY:
- geometry_parser();
- break;
-
- default:
- cc.ret_code = UNDEFINED_TYPE_ERR;
-
- } /* endswitch */
-
- if (cc.ret_code != NO_ERR)
- {
- cc.err_index = pcmdline1 - pcmdline_start;
- return(FALSE);
- }
-
- return(TRUE);
- }
-
-
- /*******************************************************************************
- * *
- * FUNCTION: Skip over all the blank and tab characters *
- * *
- *******************************************************************************/
- VOID NEAR Skip_Over_Blanks()
- {
- while ((*pcmdline1 == ' ') || (*pcmdline1 == '\t'))
- pcmdline1++;
- return;
- }
-
- /*******************************************************************************
- * *
- * FUNCTION: TYPE_CHAR option parser - scan till blank,tab,cr,new line or *
- * end of string char *
- * *
- *******************************************************************************/
- VOID NEAR char_parser()
- {
- while ((*pcmdline1 != '\0') &&
- (*pcmdline1 != '\n') &&
- (*pcmdline1 != '\r') &&
- (*pcmdline1 != '/'))
-
- {
- tokv_index++;
- tokvbuf[tokv_index].char_value = *pcmdline1;
- pcmdline1++;
- }
-
- return;
- }
-
-
- /*******************************************************************************
- * *
- * FUNCTION: TYPE_D option parser - one digit decimal number (d) *
- * *
- *******************************************************************************/
- VOID NEAR d_parser()
- {
- if ((*pcmdline1 >= '0') && (*pcmdline1 <= '9'))
- {
- tokv_index++;
- tokvbuf[tokv_index].byte_value = *pcmdline1 - '0';
- pcmdline1++;
- }
- else
- {
- cc.ret_code = SYNTAX_ERR;
- }
-
- return;
- }
-
- /*******************************************************************************
- * *
- * FUNCTION: TYPE_DD option parser - two digit decimal number (dd) *
- * *
- *******************************************************************************/
- VOID NEAR dd_parser()
- {
- INT i;
- BYTE n;
- BOOL flag;
-
- n = 0;
- flag = FALSE;
- for ( i = 0; i < 2; i++)
- {
- if ((*pcmdline1 >= '0') && (*pcmdline1 <= '9'))
- {
- n = 10 * n + *pcmdline1 - '0';
- pcmdline1++;
- flag = TRUE;
- }
- else
- {
- //
- // Was at least 1 digit found on the command line?
- //
- if (flag)
- break;
-
- cc.ret_code = SYNTAX_ERR;
- return;
- }
- }
-
- tokv_index++;
- tokvbuf[tokv_index].byte_value = n;
-
- return;
- }
-
- /*******************************************************************************
- * *
- * FUNCTION: TYPE_HH option parser hh,hh format (h = hex char) *
- * *
- *******************************************************************************/
- VOID NEAR hh_parser()
- {
- //
- // Convert command line HH char and setup token value buffer
- //
- if (!HH_Char_To_Byte())
- return;
-
- Skip_Over_Blanks();
- if (*pcmdline1 != ',')
- {
- cc.ret_code = SYNTAX_ERR;
- return;
- }
- pcmdline1++;
- Skip_Over_Blanks();
-
- //
- // Convert command line HH char and setup token value buffer
- //
- HH_Char_To_Byte();
-
- return;
- }
-
-
-
- /*******************************************************************************
- * *
- * FUNCTION: Convert HH char to byte value *
- * *
- *******************************************************************************/
- BOOL NEAR HH_Char_To_Byte()
- {
- BYTE n;
- INT i;
- BOOL flag;
-
- n = 0;
- flag = FALSE;
-
- for ( i = 0; i < 2; i++)
- {
- if ((*pcmdline1 >= '0') && (*pcmdline1 <= '9'))
- {
- n = 16 * n + *pcmdline1 - '0';
- pcmdline1++;
- flag = TRUE;
- continue;
- }
-
- if ((*pcmdline1 >= 'A') && (*pcmdline1 <= 'F'))
- {
- n = 16 * n + *pcmdline1 - '7';
- pcmdline1++;
- flag = TRUE;
- continue;
- }
-
- if ((*pcmdline1 >= 'a') && (*pcmdline1 <= 'f'))
- {
- n = 16 * n + *pcmdline1 - 'W';
- pcmdline1++;
- flag = TRUE;
- continue;
- }
-
- //
- // Was at least 1 hex digit found on the command line?
- //
- if (flag)
- break;
-
- cc.ret_code = SYNTAX_ERR;
- return(FALSE);
-
- }
-
- tokv_index++;
- tokvbuf[tokv_index].byte_value = n;
-
- return(TRUE);
- }
-
-
- /*******************************************************************************
- * *
- * FUNCTION: TYPE_HHHH option parser hhhh format (h = hex char) *
- * *
- *******************************************************************************/
- VOID NEAR hhhh_parser()
- {
- INT i;
- BOOL flag;
- NUMBER un_number;
-
- un_number.n = 0;
- flag = FALSE;
-
- for ( i = 0; i < 4; i++)
- {
- if ((*pcmdline1 >= '0') && (*pcmdline1 <= '9'))
- {
- un_number.n = 16 * un_number.n + *pcmdline1 - '0';
- pcmdline1++;
- flag = TRUE;
- continue;
- }
-
- if ((*pcmdline1 >= 'A') && (*pcmdline1 <= 'F'))
- {
- un_number.n = 16 * un_number.n + *pcmdline1 - '7';
- pcmdline1++;
- flag = TRUE;
- continue;
- }
-
- if ((*pcmdline1 >= 'a') && (*pcmdline1 <= 'f'))
- {
- un_number.n = 16 * un_number.n + *pcmdline1 - 'W';
- pcmdline1++;
- flag = TRUE;
- continue;
- }
-
- //
- // Was at least 1 hex digit found on the command line?
- //
- if (flag)
- break;
-
- cc.ret_code = SYNTAX_ERR;
- return;
-
-
- }
-
- tokv_index++;
- tokvbuf[tokv_index].byte_value = un_number.two_bytes.byte1;
-
- tokv_index++;
- tokvbuf[tokv_index].byte_value = un_number.two_bytes.byte2;
-
- return;
- }
-
-
- /*******************************************************************************
- * *
- * FUNCTION: TYPE_FORMAT option parser - format_table chars accepted *
- * *
- *******************************************************************************/
- VOID NEAR format_parser()
- {
-
- typedef struct _formattable
- {
- PSZ string;
- USHORT type;
- NUMBER MegBytes;
-
- } FORMATTABLE;
-
- // FORMATTABLE type definitions
- #define M_BYTES 1 //accepts MB,mb,Mb,mB, or just the # string
- #define K_BYTES 2 //accepts KB,kb,Kb,kB, or just the # string
-
- INT str_len, k;
- static FORMATTABLE format_table[] =
- {
- { "360", K_BYTES, 360},
- { "720", K_BYTES, 720},
- { "1200", K_BYTES, 1200},
- { "1.2", M_BYTES, 1200},
- { "1440", K_BYTES, 1440},
- { "1.44", M_BYTES, 1440},
- { "2880", K_BYTES, 2880},
- { "2.88", M_BYTES, 2880},
- { "-1"},
- };
-
- cc.ret_code = SYNTAX_ERR;
- for (k = 0; (format_table[k].string != "-1"); k++)
- {
-
- str_len = strlength(format_table[k].string);
-
- if (strncmp(pcmdline1,format_table[k].string, str_len)
- == TRUE)
- {
- pcmdline1 += str_len;
- if (format_table[k].type == K_BYTES)
- {
- if ((*pcmdline1 == 'K') || (*pcmdline1 == 'k'))
- {
- ++pcmdline1;
-
- if ((*(pcmdline1+1) == 'B') || (*(pcmdline1+1) == 'b'))
- ++pcmdline1;
- }
- }
- else
- {
- if ((*pcmdline1 == 'M') || (*pcmdline1 == 'm'))
- {
- ++pcmdline1;
-
- if ((*(pcmdline1+1) == 'B') || (*(pcmdline1+1) == 'b'))
- ++pcmdline1;
- }
- }
-
- tokv_index++;
- tokvbuf[tokv_index].byte_value = format_table[k].MegBytes.two_bytes.byte1;
- tokv_index++;
- tokvbuf[tokv_index].byte_value = format_table[k].MegBytes.two_bytes.byte2;
-
- cc.ret_code = NO_ERR;
- break;
- }
- }
- return;
- }
-
- /*******************************************************************************
- * *
- * FUNCTION: TYPE_SCSI_ID option parser - format d and (d,d) accepted *
- * where d = 0 - 7 *
- * *
- *******************************************************************************/
- VOID NEAR scsi_id_parser()
- {
- BOOL found_bracket, found_one;
-
- found_bracket = FALSE;
- found_one = FALSE;
-
- if (*pcmdline1 == '(')
- {
- found_bracket = TRUE;
- pcmdline1++;
- Skip_Over_Blanks();
- }
-
-
- while ((*pcmdline1 >= '0') && (*pcmdline1 <= '7'))
- {
- found_one = TRUE;
- tokv_index++;
- tokvbuf[tokv_index].byte_value = *pcmdline1 - '0';
- pcmdline1++;
- if (!found_bracket)
- {
- tokv_index++;
- tokvbuf[tokv_index].byte_value = 0;
- }
-
- Skip_Over_Blanks();
- if (*pcmdline1 != ',')
- {
- if (found_bracket)
- cc.ret_code = SYNTAX_ERR;
- return;
- }
-
- pcmdline1++;
- Skip_Over_Blanks();
- if (found_bracket)
- {
- if ((*pcmdline1 >= '0') && (*pcmdline1 <= '7'))
- {
- tokv_index++;
- tokvbuf[tokv_index].byte_value = *pcmdline1 - '0';
- pcmdline1++;
- Skip_Over_Blanks();
- if (*pcmdline1 != ')')
- {
- cc.ret_code = SYNTAX_ERR;
- return;
- }
- pcmdline1++;
- Skip_Over_Blanks();
- found_bracket = FALSE;
-
- if (*pcmdline1 != ',')
- return;
-
- pcmdline1++;
- Skip_Over_Blanks();
- }
- }
-
- if (*pcmdline1 == '(')
- {
- found_bracket = TRUE;
- pcmdline1++;
- Skip_Over_Blanks();
- }
- }
-
- if (found_bracket)
- cc.ret_code = SYNTAX_ERR;
-
- if (!found_one)
- cc.ret_code = SYNTAX_ERR;
-
- return;
- }
-
-
- /*******************************************************************************
- * *
- * FUNCTION: TYPE_GEOMETRY option parser - dd or (dddd,dddd,dddd) accepted *
- * *
- *******************************************************************************/
- VOID NEAR geometry_parser()
- {
- INT i, counter;
- NUMBER un_number;
- BOOL flag;
-
- BOOL found_bracket, found_one;
-
- _asm{int 3};
- if (*pcmdline1 != '(')
- {
- dd_parser();
- return;
- }
-
- pcmdline1++;
- Skip_Over_Blanks();
-
- counter = 0;
- while(TRUE)
- {
- un_number.n = 0;
- flag = FALSE;
- for ( i = 0; i < 4; i++)
- {
- if ((*pcmdline1 >= '0') && (*pcmdline1 <= '9'))
- {
- un_number.n = 10 * un_number.n + *pcmdline1 - '0';
- pcmdline1++;
- flag = TRUE;
- }
- else
- {
- //
- // Was at least 1 digit found on the command line?
- //
- if (flag)
- break;
-
- cc.ret_code = SYNTAX_ERR;
- return;
- }
- }
-
- tokv_index++;
- tokvbuf[tokv_index].byte_value = un_number.two_bytes.byte1;
- tokv_index++;
- tokvbuf[tokv_index].byte_value = un_number.two_bytes.byte2;
-
- Skip_Over_Blanks();
- if (counter == 2)
- {
- if (*pcmdline1 != ')')
- cc.ret_code = SYNTAX_ERR;
- else
- pcmdline1++;
- return;
- }
-
-
- if (*pcmdline1 != ',')
- {
- cc.ret_code = SYNTAX_ERR;
- return;
- }
-
- pcmdline1++;
- counter++;
- Skip_Over_Blanks();
- }
-
- return;
- }
-
- /*******************************************************************************
- * *
- * FUNCTION: Insert the parsed option (token) into the output buffer. *
- * *
- *******************************************************************************/
- BOOL NEAR Insert_Token()
- {
- USHORT t, tok_size;
-
- tok_size = TOK_MIN_LENGTH + tokv_index;
- if ((poutbuf1 + tok_size + TOKL_ID_END) >= poutbuf_end)
- {
- cc.err_index = pcmdline_slash-pcmdline_start;
- cc.ret_code = BUF_TOO_SMALL_ERR;
- return(FALSE);
- }
-
- *poutbuf1 = tok_size + 1;
- poutbuf1++;
- *poutbuf1 = ptable_option->id;
- poutbuf1++;
-
- if (tokv_index != UNDEFINED)
- {
- for (t=0;t <= tokv_index;t++)
- {
- *poutbuf1 = tokvbuf[t].byte_value;
- poutbuf1++;
- }
- }
-
- Insert_End_Token();
-
- return(TRUE);
- }
-
- /*******************************************************************************
- * *
- * FUNCTION: Locate the next / char. *
- * *
- *******************************************************************************/
- BOOL NEAR Locate_Next_Slash()
- {
-
- while ((*pcmdline1 != '\0') &&
- (*pcmdline1 != '\n') &&
- (*pcmdline1 != '\r'))
- {
-
- if ((*pcmdline1 == ' ') ||
- (*pcmdline1 == '\t'))
- {
- pcmdline1++;
- }
- else
- {
- if (*pcmdline1 == '/')
- {
- pcmdline_slash = pcmdline1;
- return(TRUE);
- }
- else
- {
- cc.ret_code = INVALID_OPT_ERR;
- cc.err_index = pcmdline1-pcmdline_start;
- return(FALSE);
- }
- }
-
- } /* endwhile */
-
- if (pend_option->state[state_index] == R)
- {
- cc.ret_code = REQ_OPT_ERR;
- cc.err_index = pcmdline1-pcmdline_start;
- }
- else
- {
- cc.ret_code = NO_ERR;
- cc.err_index = 0;
- }
- return(FALSE);
- }
-
-
- /*******************************************************************************
- * *
- * FUNCTION: Validate the State Index *
- * *
- *******************************************************************************/
- BOOL NEAR Validate_State_Index(maxstate)
-
- USHORT maxstate;
- {
-
- if ((state_index > maxstate) ||
- (state_index < 0))
- {
- cc.ret_code = UNDEFINED_STATE_ERR;
- cc.err_index = 0;
- return(FALSE);
- }
-
- return(TRUE);
- }
-
-