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