1 /* $Id: gram.y 246 2007-05-12 01:03:53Z jon $ */
2 /* $NCDId: @(#)gram.y,v 1.1 1996/04/24 17:01:03 greg Exp $ */
3 
4 
5 %{
6 #include <inttypes.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <ctype.h>
11 
12 #include "auservertype.h"
13 #include "nasconf.h"
14 #include "aulog.h"
15 #include "misc.h"
16 
17 static char     *ptr;
18 static intptr_t parsebool(const char *str);
19 extern int yylineno;
20 
21 %}
22 
23 %union
24 {
25     intptr_t num;
26     char *ptr;
27 };
28 
29 %token <num> INPUTSECTION OUTPUTSECTION ENDSECTION WORDSIZE FRAGSIZE MAXFRAGS
30 %token <num> MINFRAGS MAXRATE MINRATE NUMCHANS MIXER DEVICE NUMBER
31 %token <num> CDEBUG VERBOSE
32 %token <num> READWRITE FORCERATE AUTOOPEN GAIN GAINSCALE
33 %token <num> RELEASEDEVICE KEEPMIXER OUTDEVTYPE MIXERINIT REINITMIXER
34 %token <ptr> STRING
35 
36 %type <ptr> string
37 %type <num> number
38 
39 %start auconfig
40 
41 %%
42 auconfig        : globstmts sectconfigs
43                 ;
44 
45 globstmts       : /* Empty */
46                 | globstmts globstmt
47                 ;
48 
49 globstmt        : VERBOSE
50                         { NasConfig.DoVerbose = TRUE; }
51                 | CDEBUG number
52                         { NasConfig.DoDebug = $2 ; }
53                 | RELEASEDEVICE string
54                         {
55                           int j;
56 
57                           j = parsebool($2);
58                           if (j == -1) {
59                                 /* error - default to yes */
60                               NasConfig.DoDeviceRelease = TRUE;
61                           } else
62                               NasConfig.DoDeviceRelease = j;
63                         }
64                 | KEEPMIXER string
65                         {
66                           int j;
67 
68                           j = parsebool($2);
69                           if (j == -1) {
70                                 /* error - default to yes */
71                               NasConfig.DoKeepMixer = TRUE;
72                           } else
73                               NasConfig.DoKeepMixer = j;
74                         }
75                 | MIXERINIT string
76                         { ddaSetConfig(MIXERINIT, (void *)parsebool($2)); }
77                 | REINITMIXER string
78                         { ddaSetConfig(REINITMIXER, (void *)parsebool($2)); }
79                 | OUTDEVTYPE string
80                         { ddaSetConfig(OUTDEVTYPE, (void *)$2); }
81                 ;
82 
83 sectconfigs     : /* Empty */
84                 | sectconfigs sectconfig
85                 ;
86 
87 sectconfig      : inputconfig
88                 | outputconfig
89                 ;
90 
91 inputconfig     : inputword stmts ENDSECTION
92                 ;
93 
94 inputword       : INPUTSECTION
95                         { ddaSetConfig(CONF_SET_SECTION, (void *)INPUTSECTION); }
96                 ;
97 
98 outputconfig    : outputword stmts ENDSECTION
99                 ;
100 
101 outputword      : OUTPUTSECTION
102                         { ddaSetConfig(CONF_SET_SECTION, (void *)OUTPUTSECTION); }
103                 ;
104 
105 stmts           : /* Empty */
106                 | stmts stmt
107                 ;
108 
109 stmt            : error
110                 | AUTOOPEN string
111                         {
112                           ddaSetConfig(AUTOOPEN, (void *)parsebool($2));
113                         }
114                 | FORCERATE string
115                         {
116                           ddaSetConfig(FORCERATE, (void *)parsebool($2));
117                         }
118                 | READWRITE string
119                         {
120                           ddaSetConfig(READWRITE, (void *)parsebool($2));
121                         }
122                 | MIXER string
123                         {
124                           ddaSetConfig(MIXER, (void *)$2);
125                         }
126                 | DEVICE string
127                         {
128                           ddaSetConfig(DEVICE, (void *)$2);
129                         }
130                 | WORDSIZE number
131                         {
132                           ddaSetConfig(WORDSIZE, (void *)$2);
133                         }
134                 | FRAGSIZE number
135                         {
136                           ddaSetConfig(FRAGSIZE, (void *)$2);
137                         }
138                 | MINFRAGS number
139                         {
140                           ddaSetConfig(MINFRAGS, (void *)$2);
141                         }
142                 | MAXFRAGS number
143                         {
144                           ddaSetConfig(MAXFRAGS, (void *)$2);
145                         }
146                 | NUMCHANS number
147                         {
148                           ddaSetConfig(NUMCHANS, (void *)$2);
149                         }
150                 | MAXRATE number
151                         { ddaSetConfig(MAXRATE, (void *)$2); }
152                 | MINRATE number
153                         { ddaSetConfig(MINRATE, (void *)$2); }
154                 | GAIN number
155                         { ddaSetConfig(GAIN, (void *)$2); }
156                 | GAINSCALE number
157                         { ddaSetConfig(GAINSCALE, (void *)$2); }
158                 ;
159 
160 string          : STRING                { ptr = (char *)malloc(strlen($1)+1);
161                                           strcpy(ptr, $1);
162                                           RemoveDQuote(ptr);
163                                           $$ = ptr;
164                                         }
165                 ;
166 number          : NUMBER                { $$ = $1; }
167                 ;
168 
169 %%
170 
RemoveDQuote(str)171 RemoveDQuote(str)
172 char *str;
173 {
174     char *i, *o;
175     int n;
176     int count;
177 
178     for (i = str + 1, o = str; *i && *i != '\"'; o++) {
179         if (*i == '\\') {
180             switch (*++i) {
181             case 'n':
182                 *o = '\n';
183                 i++;
184                 break;
185             case 'b':
186                 *o = '\b';
187                 i++;
188                 break;
189             case 'r':
190                 *o = '\r';
191                 i++;
192                 break;
193             case 't':
194                 *o = '\t';
195                 i++;
196                 break;
197             case 'f':
198                 *o = '\f';
199                 i++;
200                 break;
201             case '0':
202                 if (*++i == 'x')
203                     goto hex;
204                 else
205                     --i;
206             case '1':
207             case '2':
208             case '3':
209             case '4':
210             case '5':
211             case '6':
212             case '7':
213                 n = 0;
214                 count = 0;
215                 while (*i >= '0' && *i <= '7' && count < 3) {
216                     n = (n << 3) + (*i++ - '0');
217                     count++;
218                 }
219                 *o = n;
220                 break;
221               hex:
222             case 'x':
223                 n = 0;
224                 count = 0;
225                 while (i++, count++ < 2) {
226                     if (*i >= '0' && *i <= '9')
227                         n = (n << 4) + (*i - '0');
228                     else if (*i >= 'a' && *i <= 'f')
229                         n = (n << 4) + (*i - 'a') + 10;
230                     else if (*i >= 'A' && *i <= 'F')
231                         n = (n << 4) + (*i - 'A') + 10;
232                     else
233                         break;
234                 }
235                 *o = n;
236                 break;
237             case '\n':
238                 i++;            /* punt */
239                 o--;            /* to account for o++ at end of loop */
240                 break;
241             case '\"':
242             case '\'':
243             case '\\':
244             default:
245                 *o = *i++;
246                 break;
247             }
248         } else
249             *o = *i++;
250     }
251     *o = '\0';
252 }
253 
254 static intptr_t
parsebool(const char * str)255 parsebool(const char *str)
256 {
257     if (str == NULL)
258         return (-1);
259 
260     if (((char *) strcasestr("false", str) != NULL) ||
261         ((char *) strcasestr("no", str) != NULL) ||
262         ((char *) strcasestr("0", str) != NULL) ||
263         ((char *) strcasestr("off", str) != NULL)) {
264         return (FALSE);
265     } else if (((char *) strcasestr("true", str) != NULL) ||
266                ((char *) strcasestr("yes", str) != NULL) ||
267                ((char *) strcasestr("1", str) != NULL) ||
268                ((char *) strcasestr("on", str) != NULL)) {
269         return (TRUE);
270     } else {
271         fprintf(stderr, "parsebool(): error parsing '%s', \n\t%s\n",
272                 str,
273                 "Value must be yes or no, true or false, or on or off.");
274         return (-1);
275     }
276 }
277