1 /* PARSER.C     (c) Copyright Leland Lucius, 2001                    */
2 /*              Simple parameter parser                              */
3 
4 #include "hstdinc.h"
5 
6 #define _PARSER_C_
7 #define _HUTIL_DLL_
8 #include "hercules.h"
9 #include "parser.h"
10 
11 #if !defined( NULL )
12 #define NULL 0
13 #endif
14 
15 /*
16 
17     NAME
18             parser - parse parameter strings
19 
20     SYNOPSIS
21             #include "parser.h"
22 
23             int parser( PARSER *pp, char *str, void *res )
24 
25     DESCRIPTION
26             The parser() function breaks the str parameter into a keyword
27             and value using the "=" as a delimiter.  The pp table is then
28             scanned for the keyword.  If found and the table entry specifies
29             a format string, then parser() will use sscanf() to store the
30             value at the location specifed by res.
31 
32             The PARSER table entries consist of a string pointer that
33             designates the keyword and a string pointer that designates the
34             format of the associated value.  The format may be set to NULL
35             if the keyword does not take a value.  The table must be
36             terminated with an entry that specifies NULL for the keyword
37             string.
38 
39     RETURN VALUE
40             If no errors are detected then the returned value will be the
41             index+1 of the matching table entry.  The res argument will be
42             updated only when a format string is specified.
43 
44             If an entry couldn't be found, zero will be returned and res
45             will remain untouched.
46 
47             If an entry is found, but an error is detected while processing
48             the str parameter then a negative value is returned.  This value
49             will be the index-1 of the matching table entry.
50 
51     EXAMPLE
52             #include "parser.h"
53             #include <stdlib.h>
54 
55             PARSER ptab[] =
56             {
57                 { "switchkey", NULL },
58                 { "numkey", "%d" },
59                 { "strkey", "%s" },
60             };
61 
62             int main( int argc, char *argv[] )
63             {
64                 int rc;
65                 union
66                 {
67                     int num;
68                     char str[ 80 ];
69                 } res;
70 
71                 while( --argc )
72                 {
73                     rc = parser( &ptab[0], argv[ argc ], &res );
74                     printf( "parser() rc = %d\n", rc );
75                     if( rc < 0 )
76                     {
77                         printf( "error parsing keyword: %s\n",
78                             ptab[ abs( rc  1 ) ].key );
79                     }
80                     else if( rc == 0 )
81                     {
82                         printf( "unrecognized keyword: %s\n",
83                             argv[ argc ] );
84                     }
85                     else
86                     {
87                         switch( rc )
88                         {
89                             case 1:
90                                 printf( "found switchkey\n" );
91                             break;
92                             case 2:
93                                 printf( "numkey value is: %d\n", res.num );
94                             break;
95                             case 3:
96                                 printf( "strkey value is: %s\n", res.str );
97                             break;
98                         }
99                     }
100                 }
101             }
102 
103     SEE ALSO
104             sscanf(3)
105 
106 */
107 
108 DLL_EXPORT int
parser(PARSER * pp,char * str,void * res)109 parser( PARSER *pp, char *str, void *res )
110 {
111     int ndx;
112     char *key;
113     char *val;
114 
115     ndx = 1;
116     key = strtok( str, "=" );
117     val = strtok( NULL, "=" );
118 
119     while( pp->key != NULL )
120     {
121         if( strcasecmp( key, pp->key ) == 0 )
122         {
123             if( pp->fmt == NULL )
124             {
125                 if( val != NULL )
126                 {
127                     return( -ndx );
128                 }
129             }
130             else
131             {
132                 if( val == NULL )
133                 {
134                     return( -ndx );
135                 }
136 
137                 if( sscanf( val, pp->fmt, res ) != 1 )
138                 {
139                     return( -ndx );
140                 }
141             }
142 
143             return( ndx );
144         }
145         pp++;
146         ndx++;
147     }
148 
149     return( 0 );
150 }
151