vfs: check userland buffers before reading them.
[haiku.git] / src / bin / pcmcia-cs / yacc_cis.y
blobc6188c5a0db9b53d10f5f9d100bba61c44064d27
1 %{
2 /*
3 * yacc_cis.y 1.13 2001/08/24 12:21:41
5 * The contents of this file are subject to the Mozilla Public License
6 * Version 1.1 (the "License"); you may not use this file except in
7 * compliance with the License. You may obtain a copy of the License
8 * at http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS"
11 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
12 * the License for the specific language governing rights and
13 * limitations under the License.
15 * The initial developer of the original code is David A. Hinds
16 * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
17 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
19 * Alternatively, the contents of this file may be used under the
20 * terms of the GNU General Public License version 2 (the "GPL"), in
21 * which case the provisions of the GPL are applicable instead of the
22 * above. If you wish to allow the use of your version of this file
23 * only under the terms of the GPL and not to allow others to use
24 * your version of this file under the MPL, indicate your decision by
25 * deleting the provisions above and replace them with the notice and
26 * other provisions required by the GPL. If you do not delete the
27 * provisions above, a recipient may use your version of this file
28 * under either the MPL or the GPL.
31 #include <sys/types.h>
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <stdarg.h>
36 #include <math.h>
38 #include <pcmcia/cs_types.h>
39 #include <pcmcia/cs.h>
40 #include <pcmcia/cistpl.h>
42 #include "pack_cis.h"
44 /* If bison: generate nicer error messages */
45 #define YYERROR_VERBOSE 1
47 extern int current_lineno;
49 void yyerror(char *msg, ...);
50 static tuple_info_t *new_tuple(u_char type, cisparse_t *parse);
54 %token STRING NUMBER FLOAT VOLTAGE CURRENT SIZE
55 %token VERS_1 MANFID FUNCID CONFIG CFTABLE MFC CHECKSUM
56 %token POST ROM BASE LAST_INDEX CJEDEC AJEDEC
57 %token DEV_INFO ATTR_DEV_INFO NO_INFO
58 %token TIME TIMING WAIT READY RESERVED
59 %token VNOM VMIN VMAX ISTATIC IAVG IPEAK IDOWN
60 %token VCC VPP1 VPP2 IO MEM
61 %token DEFAULT BVD WP RDYBSY MWAIT AUDIO READONLY PWRDOWN
62 %token BIT8 BIT16 LINES RANGE
63 %token IRQ_NO MASK LEVEL PULSE SHARED
65 %union {
66 char *str;
67 u_long num;
68 float flt;
69 cistpl_power_t pwr;
70 cisparse_t *parse;
71 tuple_info_t *tuple;
74 %type <str> STRING
75 %type <num> NUMBER SIZE VOLTAGE CURRENT TIME
76 %type <flt> FLOAT
77 %type <pwr> pwr pwrlist
78 %type <parse> vers_1 manfid funcid config cftab io mem irq timing
79 %type <parse> dev_info attr_dev_info checksum cjedec ajedec
80 %type <tuple> tuple chain cis;
83 cis: chain
84 { cis_root = $1; }
85 | chain mfc
86 { cis_root = $1; }
89 chain: /* nothing */
90 { $$ = NULL; }
91 | chain tuple
93 if ($1 == NULL) {
94 $$ = $2;
95 } else if ($2 == NULL) {
96 $$ = $1;
97 } else {
98 tuple_info_t *tail = $1;
99 while (tail->next != NULL) tail = tail->next;
100 tail->next = $2;
101 $$ = $1;
106 mfc: MFC '{' chain '}'
107 { mfc[nf++] = $3; }
108 | mfc ',' '{' chain '}'
109 { mfc[nf++] = $4; }
112 tuple: dev_info
113 { $$ = new_tuple(CISTPL_DEVICE, $1); }
114 | attr_dev_info
115 { $$ = new_tuple(CISTPL_DEVICE_A, $1); }
116 | vers_1
117 { $$ = new_tuple(CISTPL_VERS_1, $1); }
118 | manfid
119 { $$ = new_tuple(CISTPL_MANFID, $1); }
120 | funcid
121 { $$ = new_tuple(CISTPL_FUNCID, $1); }
122 | config
123 { $$ = new_tuple(CISTPL_CONFIG, $1); }
124 | cftab
125 { $$ = new_tuple(CISTPL_CFTABLE_ENTRY, $1); }
126 | checksum
127 { $$ = NULL; }
128 | error
129 { $$ = NULL; }
130 | cjedec
131 { $$ = new_tuple(CISTPL_JEDEC_C, $1); }
132 | ajedec
133 { $$ = new_tuple(CISTPL_JEDEC_A, $1); }
136 dev_info: DEV_INFO
137 { $$ = calloc(1, sizeof(cisparse_t)); }
138 | dev_info NUMBER TIME ',' SIZE
140 $$->device.dev[$$->device.ndev].type = $2;
141 $$->device.dev[$$->device.ndev].speed = $3;
142 $$->device.dev[$$->device.ndev].size = $5;
143 $$->device.ndev++;
145 | dev_info NO_INFO
148 attr_dev_info: ATTR_DEV_INFO
149 { $$ = calloc(1, sizeof(cisparse_t)); }
150 | attr_dev_info NUMBER TIME ',' SIZE
152 $$->device.dev[$$->device.ndev].type = $2;
153 $$->device.dev[$$->device.ndev].speed = $3;
154 $$->device.dev[$$->device.ndev].size = $5;
155 $$->device.ndev++;
157 | attr_dev_info NO_INFO
160 vers_1: VERS_1 FLOAT
162 $$ = calloc(1, sizeof(cisparse_t));
163 $$->version_1.major = $2;
164 $2 -= floor($2+0.01);
165 while (fabs($2 - floor($2+0.5)) > 0.01) {
166 $2 *= 10;
168 $$->version_1.minor = $2+0.01;
170 | vers_1 ',' STRING
172 cistpl_vers_1_t *v = &$$->version_1;
173 u_int pos = 0;
174 if (v->ns) {
175 pos = v->ofs[v->ns-1];
176 pos += strlen(v->str+pos)+1;
178 v->ofs[v->ns] = pos;
179 strcpy(v->str+pos, $3);
180 v->ns++;
184 manfid: MANFID NUMBER ',' NUMBER
186 $$ = calloc(1, sizeof(cisparse_t));
187 $$->manfid.manf = $2;
188 $$->manfid.card = $4;
192 funcid: FUNCID NUMBER
194 $$ = calloc(1, sizeof(cisparse_t));
195 $$->funcid.func = $2;
197 | funcid POST
198 { $$->funcid.sysinit |= CISTPL_SYSINIT_POST; }
199 | funcid ROM
200 { $$->funcid.sysinit |= CISTPL_SYSINIT_ROM; }
203 cjedec: CJEDEC NUMBER NUMBER
205 $$ = calloc(1, sizeof(cisparse_t));
206 $$->jedec.id[0].mfr = $2;
207 $$->jedec.id[0].info = $3;
208 $$->jedec.nid = 1;
210 | cjedec ',' NUMBER NUMBER
212 $$->jedec.id[$$->jedec.nid].mfr = $3;
213 $$->jedec.id[$$->jedec.nid++].info = $4;
217 ajedec: AJEDEC NUMBER NUMBER
219 $$ = calloc(1, sizeof(cisparse_t));
220 $$->jedec.id[0].mfr = $2;
221 $$->jedec.id[0].info = $3;
222 $$->jedec.nid = 1;
224 | ajedec ',' NUMBER NUMBER
226 $$->jedec.id[$$->jedec.nid].mfr = $3;
227 $$->jedec.id[$$->jedec.nid++].info = $4;
231 config: CONFIG BASE NUMBER MASK NUMBER LAST_INDEX NUMBER
233 $$ = calloc(1, sizeof(cisparse_t));
234 $$->config.base = $3;
235 $$->config.rmask[0] = $5;
236 $$->config.last_idx = $7;
240 pwr: VNOM VOLTAGE
242 $$.present = CISTPL_POWER_VNOM;
243 $$.param[0] = $2;
245 | VMIN VOLTAGE
247 $$.present = CISTPL_POWER_VMIN;
248 $$.param[0] = $2;
250 | VMAX VOLTAGE
252 $$.present = CISTPL_POWER_VMAX;
253 $$.param[0] = $2;
255 | ISTATIC CURRENT
257 $$.present = CISTPL_POWER_ISTATIC;
258 $$.param[0] = $2;
260 | IAVG CURRENT
262 $$.present = CISTPL_POWER_IAVG;
263 $$.param[0] = $2;
265 | IPEAK CURRENT
267 $$.present = CISTPL_POWER_IPEAK;
268 $$.param[0] = $2;
270 | IDOWN CURRENT
272 $$.present = CISTPL_POWER_IDOWN;
273 $$.param[0] = $2;
277 pwrlist: /* nothing */
279 $$.present = 0;
281 | pwrlist pwr
283 $$.present |= 1<<($2.present);
284 $$.param[$2.present] = $2.param[0];
288 timing: cftab TIMING
289 | timing WAIT TIME
290 | timing READY TIME
291 | timing RESERVED TIME
294 io: cftab IO NUMBER '-' NUMBER
296 int n = $$->cftable_entry.io.nwin;
297 $$->cftable_entry.io.win[n].base = $3;
298 $$->cftable_entry.io.win[n].len = $5-$3+1;
299 $$->cftable_entry.io.nwin++;
301 | io ',' NUMBER '-' NUMBER
303 int n = $$->cftable_entry.io.nwin;
304 $$->cftable_entry.io.win[n].base = $3;
305 $$->cftable_entry.io.win[n].len = $5-$3+1;
306 $$->cftable_entry.io.nwin++;
308 | io BIT8
309 { $$->cftable_entry.io.flags |= CISTPL_IO_8BIT; }
310 | io BIT16
311 { $$->cftable_entry.io.flags |= CISTPL_IO_16BIT; }
312 | io LINES '=' NUMBER ']'
313 { $$->cftable_entry.io.flags |= $4; }
314 | io RANGE
317 mem: cftab MEM NUMBER '-' NUMBER '@' NUMBER
319 int n = $$->cftable_entry.mem.nwin;
320 $$->cftable_entry.mem.win[n].card_addr = $3;
321 $$->cftable_entry.mem.win[n].host_addr = $7;
322 $$->cftable_entry.mem.win[n].len = $5-$3+1;
323 $$->cftable_entry.mem.nwin++;
325 | mem ',' NUMBER '-' NUMBER '@' NUMBER
327 int n = $$->cftable_entry.mem.nwin;
328 $$->cftable_entry.mem.win[n].card_addr = $3;
329 $$->cftable_entry.mem.win[n].host_addr = $7;
330 $$->cftable_entry.mem.win[n].len = $5-$3+1;
331 $$->cftable_entry.mem.nwin++;
333 | mem BIT8
334 { $$->cftable_entry.io.flags |= CISTPL_IO_8BIT; }
335 | mem BIT16
336 { $$->cftable_entry.io.flags |= CISTPL_IO_16BIT; }
339 irq: cftab IRQ_NO NUMBER
340 { $$->cftable_entry.irq.IRQInfo1 = ($3 & 0x0f); }
341 | cftab IRQ_NO MASK NUMBER
343 $$->cftable_entry.irq.IRQInfo1 = IRQ_INFO2_VALID;
344 $$->cftable_entry.irq.IRQInfo2 = $4;
346 | irq PULSE
347 { $$->cftable_entry.irq.IRQInfo1 |= IRQ_PULSE_ID; }
348 | irq LEVEL
349 { $$->cftable_entry.irq.IRQInfo1 |= IRQ_LEVEL_ID; }
350 | irq SHARED
351 { $$->cftable_entry.irq.IRQInfo1 |= IRQ_SHARE_ID; }
354 cftab: CFTABLE NUMBER
356 $$ = calloc(1, sizeof(cisparse_t));
357 $$->cftable_entry.index = $2;
359 | cftab DEFAULT
360 { $$->cftable_entry.flags |= CISTPL_CFTABLE_DEFAULT; }
361 | cftab BVD
362 { $$->cftable_entry.flags |= CISTPL_CFTABLE_BVDS; }
363 | cftab WP
364 { $$->cftable_entry.flags |= CISTPL_CFTABLE_WP; }
365 | cftab RDYBSY
366 { $$->cftable_entry.flags |= CISTPL_CFTABLE_RDYBSY; }
367 | cftab MWAIT
368 { $$->cftable_entry.flags |= CISTPL_CFTABLE_MWAIT; }
369 | cftab AUDIO
370 { $$->cftable_entry.flags |= CISTPL_CFTABLE_AUDIO; }
371 | cftab READONLY
372 { $$->cftable_entry.flags |= CISTPL_CFTABLE_READONLY; }
373 | cftab PWRDOWN
374 { $$->cftable_entry.flags |= CISTPL_CFTABLE_PWRDOWN; }
375 | cftab VCC pwrlist
376 { $$->cftable_entry.vcc = $3; }
377 | cftab VPP1 pwrlist
378 { $$->cftable_entry.vpp1 = $3; }
379 | cftab VPP2 pwrlist
380 { $$->cftable_entry.vpp2 = $3; }
381 | io
382 | mem
383 | irq
384 | timing
387 checksum: CHECKSUM NUMBER '-' NUMBER '=' NUMBER
388 { $$ = NULL; }
392 static tuple_info_t *new_tuple(u_char type, cisparse_t *parse)
394 tuple_info_t *t = calloc(1, sizeof(tuple_info_t));
395 t->type = type;
396 t->parse = parse;
397 t->next = NULL;
400 void yyerror(char *msg, ...)
402 va_list ap;
403 char str[256];
405 va_start(ap, msg);
406 sprintf(str, "error at line %d: ", current_lineno);
407 vsprintf(str+strlen(str), msg, ap);
408 fprintf(stderr, "%s\n", str);
409 va_end(ap);
412 #ifdef DEBUG
413 void main(int argc, char *argv[])
415 if (argc > 1)
416 parse_cis(argv[1]);
418 #endif