yacc.y revision 1.10 1 1.10 christos /* $NetBSD: yacc.y,v 1.10 2015/06/16 22:54:10 christos Exp $ */
2 1.1 tshiozak
3 1.1 tshiozak %{
4 1.1 tshiozak /*-
5 1.7 tnozaki * Copyright (c)2003, 2006 Citrus Project,
6 1.1 tshiozak * All rights reserved.
7 1.1 tshiozak *
8 1.1 tshiozak * Redistribution and use in source and binary forms, with or without
9 1.1 tshiozak * modification, are permitted provided that the following conditions
10 1.1 tshiozak * are met:
11 1.1 tshiozak * 1. Redistributions of source code must retain the above copyright
12 1.1 tshiozak * notice, this list of conditions and the following disclaimer.
13 1.1 tshiozak * 2. Redistributions in binary form must reproduce the above copyright
14 1.1 tshiozak * notice, this list of conditions and the following disclaimer in the
15 1.1 tshiozak * documentation and/or other materials provided with the distribution.
16 1.1 tshiozak *
17 1.1 tshiozak * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 1.1 tshiozak * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 1.1 tshiozak * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 1.1 tshiozak * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 1.1 tshiozak * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 1.1 tshiozak * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 1.1 tshiozak * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 1.1 tshiozak * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 1.1 tshiozak * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 1.1 tshiozak * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 1.1 tshiozak * SUCH DAMAGE.
28 1.1 tshiozak */
29 1.1 tshiozak
30 1.3 lukem #if HAVE_NBTOOL_CONFIG_H
31 1.3 lukem #include "nbtool_config.h"
32 1.1 tshiozak #endif
33 1.1 tshiozak
34 1.1 tshiozak #include <sys/cdefs.h>
35 1.3 lukem #if !defined(lint)
36 1.10 christos __RCSID("$NetBSD: yacc.y,v 1.10 2015/06/16 22:54:10 christos Exp $");
37 1.3 lukem #endif /* not lint */
38 1.1 tshiozak
39 1.1 tshiozak #include <assert.h>
40 1.1 tshiozak #include <err.h>
41 1.1 tshiozak #include <errno.h>
42 1.1 tshiozak #include <limits.h>
43 1.1 tshiozak #include <stdio.h>
44 1.1 tshiozak #include <stdlib.h>
45 1.1 tshiozak #include <string.h>
46 1.1 tshiozak #include <unistd.h>
47 1.4 jmc #include <arpa/inet.h>
48 1.1 tshiozak #include <sys/types.h>
49 1.1 tshiozak
50 1.1 tshiozak #include "ldef.h"
51 1.1 tshiozak
52 1.1 tshiozak #ifndef __packed
53 1.1 tshiozak #define __packed
54 1.1 tshiozak #endif
55 1.1 tshiozak
56 1.1 tshiozak #include "citrus_namespace.h"
57 1.1 tshiozak #include "citrus_types.h"
58 1.1 tshiozak #include "citrus_mapper_std_file.h"
59 1.1 tshiozak #include "citrus_region.h"
60 1.1 tshiozak #include "citrus_db_factory.h"
61 1.1 tshiozak #include "citrus_db_hash.h"
62 1.1 tshiozak #include "citrus_lookup_factory.h"
63 1.1 tshiozak #include "citrus_pivot_factory.h"
64 1.1 tshiozak
65 1.1 tshiozak int debug = 0;
66 1.1 tshiozak static char *output = NULL;
67 1.1 tshiozak static void *table = NULL;
68 1.1 tshiozak static size_t table_size;
69 1.1 tshiozak static char *map_name;
70 1.1 tshiozak static int map_type;
71 1.2 tshiozak static u_int32_t dst_invalid, dst_ilseq, oob_mode, dst_unit_bits;
72 1.1 tshiozak static void (*putfunc)(void *, size_t, u_int32_t) = 0;
73 1.1 tshiozak
74 1.1 tshiozak static u_int32_t src_next;
75 1.1 tshiozak
76 1.1 tshiozak static u_int32_t done_flag = 0;
77 1.1 tshiozak #define DF_TYPE 0x00000001
78 1.1 tshiozak #define DF_NAME 0x00000002
79 1.1 tshiozak #define DF_SRC_ZONE 0x00000004
80 1.1 tshiozak #define DF_DST_INVALID 0x00000008
81 1.2 tshiozak #define DF_DST_ILSEQ 0x00000010
82 1.2 tshiozak #define DF_DST_UNIT_BITS 0x00000020
83 1.2 tshiozak #define DF_OOB_MODE 0x00000040
84 1.1 tshiozak
85 1.7 tnozaki static linear_zone_t rowcol[_CITRUS_MAPPER_STD_ROWCOL_MAX];
86 1.7 tnozaki static size_t rowcol_len = 0;
87 1.7 tnozaki static u_int32_t rowcol_bits = 0, rowcol_mask = 0;
88 1.7 tnozaki
89 1.1 tshiozak static void dump_file(void);
90 1.1 tshiozak static void setup_map(void);
91 1.1 tshiozak static void set_type(int);
92 1.1 tshiozak static void set_name(char *);
93 1.7 tnozaki static void set_src_zone(u_int32_t);
94 1.1 tshiozak static void set_dst_invalid(u_int32_t);
95 1.2 tshiozak static void set_dst_ilseq(u_int32_t);
96 1.1 tshiozak static void set_dst_unit_bits(u_int32_t);
97 1.2 tshiozak static void set_oob_mode(u_int32_t);
98 1.1 tshiozak static int check_src(u_int32_t, u_int32_t);
99 1.1 tshiozak static void store(const linear_zone_t *, u_int32_t, int);
100 1.1 tshiozak static void put8(void *, size_t, u_int32_t);
101 1.1 tshiozak static void put16(void *, size_t, u_int32_t);
102 1.1 tshiozak static void put32(void *, size_t, u_int32_t);
103 1.7 tnozaki static void set_range(u_int32_t, u_int32_t);
104 1.7 tnozaki static void set_src(linear_zone_t *, u_int32_t, u_int32_t);
105 1.1 tshiozak %}
106 1.1 tshiozak
107 1.1 tshiozak %union {
108 1.1 tshiozak u_int32_t i_value;
109 1.1 tshiozak char *s_value;
110 1.1 tshiozak linear_zone_t lz_value;
111 1.1 tshiozak }
112 1.1 tshiozak
113 1.2 tshiozak %token R_TYPE R_NAME R_SRC_ZONE R_DST_UNIT_BITS
114 1.2 tshiozak %token R_DST_INVALID R_DST_ILSEQ
115 1.1 tshiozak %token R_BEGIN_MAP R_END_MAP R_INVALID R_ROWCOL
116 1.2 tshiozak %token R_ILSEQ R_OOB_MODE
117 1.1 tshiozak %token R_LN
118 1.1 tshiozak %token <i_value> L_IMM
119 1.1 tshiozak %token <s_value> L_STRING
120 1.1 tshiozak
121 1.1 tshiozak %type <lz_value> src
122 1.7 tnozaki %type <i_value> dst types oob_mode_sel zone
123 1.1 tshiozak
124 1.1 tshiozak %%
125 1.1 tshiozak
126 1.1 tshiozak file : property mapping lns
127 1.1 tshiozak { dump_file(); }
128 1.1 tshiozak
129 1.1 tshiozak property : /* empty */
130 1.1 tshiozak | property R_LN
131 1.1 tshiozak | property name
132 1.1 tshiozak | property type
133 1.1 tshiozak | property src_zone
134 1.1 tshiozak | property dst_invalid
135 1.2 tshiozak | property dst_ilseq
136 1.1 tshiozak | property dst_unit_bits
137 1.2 tshiozak | property oob_mode
138 1.1 tshiozak
139 1.1 tshiozak name : R_NAME L_STRING { set_name($2); $2 = NULL; }
140 1.1 tshiozak type : R_TYPE types { set_type($2); }
141 1.1 tshiozak types : R_ROWCOL { $$ = R_ROWCOL; }
142 1.7 tnozaki range : L_IMM '-' L_IMM { set_range($1, $3); }
143 1.7 tnozaki
144 1.7 tnozaki ranges : /* empty */
145 1.7 tnozaki | ranges range '/'
146 1.7 tnozaki
147 1.7 tnozaki src_zone : R_SRC_ZONE zone { set_src_zone($2); }
148 1.7 tnozaki zone : range {
149 1.7 tnozaki $$ = 32;
150 1.1 tshiozak }
151 1.7 tnozaki | range '/' range '/' ranges L_IMM {
152 1.7 tnozaki $$ = $6;
153 1.1 tshiozak }
154 1.1 tshiozak
155 1.1 tshiozak dst_invalid : R_DST_INVALID L_IMM { set_dst_invalid($2); }
156 1.2 tshiozak dst_ilseq : R_DST_ILSEQ L_IMM { set_dst_ilseq($2); }
157 1.1 tshiozak dst_unit_bits : R_DST_UNIT_BITS L_IMM { set_dst_unit_bits($2); }
158 1.2 tshiozak oob_mode : R_OOB_MODE oob_mode_sel { set_oob_mode($2); }
159 1.1 tshiozak
160 1.2 tshiozak oob_mode_sel : R_INVALID { $$ = _CITRUS_MAPPER_STD_OOB_NONIDENTICAL; }
161 1.2 tshiozak | R_ILSEQ { $$ = _CITRUS_MAPPER_STD_OOB_ILSEQ; }
162 1.1 tshiozak
163 1.1 tshiozak mapping : begin_map map_elems R_END_MAP
164 1.1 tshiozak begin_map : R_BEGIN_MAP lns { setup_map(); }
165 1.1 tshiozak
166 1.1 tshiozak map_elems : /* empty */
167 1.1 tshiozak | map_elems map_elem lns
168 1.1 tshiozak
169 1.1 tshiozak map_elem : src '=' dst
170 1.1 tshiozak { store(&$1, $3, 0); }
171 1.1 tshiozak | src '=' L_IMM '-'
172 1.1 tshiozak { store(&$1, $3, 1); }
173 1.1 tshiozak dst : L_IMM
174 1.1 tshiozak {
175 1.1 tshiozak $$ = $1;
176 1.1 tshiozak }
177 1.1 tshiozak | R_INVALID
178 1.1 tshiozak {
179 1.1 tshiozak $$ = dst_invalid;
180 1.1 tshiozak }
181 1.2 tshiozak | R_ILSEQ
182 1.2 tshiozak {
183 1.2 tshiozak $$ = dst_ilseq;
184 1.2 tshiozak }
185 1.1 tshiozak
186 1.1 tshiozak src : /* empty */
187 1.1 tshiozak {
188 1.7 tnozaki set_src(&$$, src_next, src_next);
189 1.1 tshiozak }
190 1.1 tshiozak | L_IMM
191 1.1 tshiozak {
192 1.7 tnozaki set_src(&$$, $1, $1);
193 1.1 tshiozak }
194 1.1 tshiozak | L_IMM '-' L_IMM
195 1.1 tshiozak {
196 1.7 tnozaki set_src(&$$, $1, $3);
197 1.1 tshiozak }
198 1.1 tshiozak | '-' L_IMM
199 1.1 tshiozak {
200 1.7 tnozaki set_src(&$$, src_next, $2);
201 1.1 tshiozak }
202 1.1 tshiozak lns : R_LN
203 1.1 tshiozak | lns R_LN
204 1.1 tshiozak
205 1.1 tshiozak %%
206 1.1 tshiozak
207 1.1 tshiozak static void
208 1.1 tshiozak warning(const char *s)
209 1.1 tshiozak {
210 1.1 tshiozak fprintf(stderr, "%s in %d\n", s, line_number);
211 1.1 tshiozak }
212 1.1 tshiozak
213 1.1 tshiozak int
214 1.1 tshiozak yyerror(const char *s)
215 1.1 tshiozak {
216 1.1 tshiozak warning(s);
217 1.1 tshiozak exit(1);
218 1.1 tshiozak }
219 1.1 tshiozak
220 1.1 tshiozak void
221 1.1 tshiozak put8(void *ptr, size_t ofs, u_int32_t val)
222 1.1 tshiozak {
223 1.1 tshiozak *((u_int8_t *)ptr + ofs) = val;
224 1.1 tshiozak }
225 1.1 tshiozak
226 1.1 tshiozak void
227 1.1 tshiozak put16(void *ptr, size_t ofs, u_int32_t val)
228 1.1 tshiozak {
229 1.1 tshiozak u_int16_t oval = htons(val);
230 1.1 tshiozak memcpy((u_int16_t *)ptr + ofs, &oval, 2);
231 1.1 tshiozak }
232 1.1 tshiozak
233 1.1 tshiozak void
234 1.1 tshiozak put32(void *ptr, size_t ofs, u_int32_t val)
235 1.1 tshiozak {
236 1.1 tshiozak u_int32_t oval = htonl(val);
237 1.1 tshiozak memcpy((u_int32_t *)ptr + ofs, &oval, 4);
238 1.1 tshiozak }
239 1.1 tshiozak
240 1.1 tshiozak static void
241 1.1 tshiozak alloc_table(void)
242 1.1 tshiozak {
243 1.1 tshiozak size_t i;
244 1.6 lukem u_int32_t val = 0;
245 1.7 tnozaki linear_zone_t *p;
246 1.1 tshiozak
247 1.7 tnozaki i = rowcol_len;
248 1.7 tnozaki p = &rowcol[--i];
249 1.7 tnozaki table_size = p->width;
250 1.7 tnozaki while (i > 0) {
251 1.7 tnozaki p = &rowcol[--i];
252 1.7 tnozaki table_size *= p->width;
253 1.7 tnozaki }
254 1.7 tnozaki table = (void *)malloc(table_size * dst_unit_bits / 8);
255 1.7 tnozaki if (table == NULL) {
256 1.1 tshiozak perror("malloc");
257 1.1 tshiozak exit(1);
258 1.1 tshiozak }
259 1.1 tshiozak
260 1.2 tshiozak switch (oob_mode) {
261 1.2 tshiozak case _CITRUS_MAPPER_STD_OOB_NONIDENTICAL:
262 1.2 tshiozak val = dst_invalid;
263 1.2 tshiozak break;
264 1.2 tshiozak case _CITRUS_MAPPER_STD_OOB_ILSEQ:
265 1.2 tshiozak val = dst_ilseq;
266 1.2 tshiozak break;
267 1.2 tshiozak default:
268 1.2 tshiozak _DIAGASSERT(0);
269 1.2 tshiozak }
270 1.5 itojun for (i = 0; i < table_size; i++)
271 1.2 tshiozak (*putfunc)(table, i, val);
272 1.1 tshiozak }
273 1.1 tshiozak
274 1.1 tshiozak static void
275 1.1 tshiozak setup_map(void)
276 1.1 tshiozak {
277 1.1 tshiozak
278 1.1 tshiozak if ((done_flag & DF_SRC_ZONE)==0) {
279 1.1 tshiozak fprintf(stderr, "SRC_ZONE is mandatory.\n");
280 1.1 tshiozak exit(1);
281 1.1 tshiozak }
282 1.1 tshiozak if ((done_flag & DF_DST_UNIT_BITS)==0) {
283 1.1 tshiozak fprintf(stderr, "DST_UNIT_BITS is mandatory.\n");
284 1.1 tshiozak exit(1);
285 1.1 tshiozak }
286 1.1 tshiozak
287 1.1 tshiozak if ((done_flag & DF_DST_INVALID) == 0)
288 1.1 tshiozak dst_invalid = 0xFFFFFFFF;
289 1.2 tshiozak if ((done_flag & DF_DST_ILSEQ) == 0)
290 1.2 tshiozak dst_ilseq = 0xFFFFFFFE;
291 1.2 tshiozak if ((done_flag & DF_OOB_MODE) == 0)
292 1.2 tshiozak oob_mode = _CITRUS_MAPPER_STD_OOB_NONIDENTICAL;
293 1.1 tshiozak
294 1.1 tshiozak alloc_table();
295 1.1 tshiozak }
296 1.1 tshiozak
297 1.1 tshiozak static void
298 1.1 tshiozak create_rowcol_info(struct _region *r)
299 1.1 tshiozak {
300 1.1 tshiozak void *ptr;
301 1.7 tnozaki size_t ofs, i, len;
302 1.1 tshiozak
303 1.1 tshiozak ofs = 0;
304 1.1 tshiozak ptr = malloc(_CITRUS_MAPPER_STD_ROWCOL_INFO_SIZE);
305 1.7 tnozaki if (ptr == NULL)
306 1.1 tshiozak err(EXIT_FAILURE, "malloc");
307 1.7 tnozaki put32(ptr, ofs, rowcol_bits); ofs++;
308 1.7 tnozaki put32(ptr, ofs, dst_invalid); ofs++;
309 1.1 tshiozak
310 1.7 tnozaki /* XXX: keep backward compatibility */
311 1.7 tnozaki switch (rowcol_len) {
312 1.7 tnozaki case 1:
313 1.7 tnozaki put32(ptr, ofs, 0); ofs++;
314 1.7 tnozaki put32(ptr, ofs, 0); ofs++;
315 1.7 tnozaki /*FALLTHROUGH*/
316 1.7 tnozaki case 2:
317 1.7 tnozaki len = 0;
318 1.7 tnozaki break;
319 1.7 tnozaki default:
320 1.7 tnozaki len = rowcol_len;
321 1.7 tnozaki }
322 1.7 tnozaki for (i = 0; i < rowcol_len; ++i) {
323 1.7 tnozaki put32(ptr, ofs, rowcol[i].begin); ofs++;
324 1.7 tnozaki put32(ptr, ofs, rowcol[i].end); ofs++;
325 1.7 tnozaki }
326 1.1 tshiozak put32(ptr, ofs, dst_unit_bits); ofs++;
327 1.7 tnozaki put32(ptr, ofs, len); ofs++;
328 1.1 tshiozak
329 1.7 tnozaki _region_init(r, ptr, ofs * 4);
330 1.1 tshiozak }
331 1.1 tshiozak
332 1.7 tnozaki
333 1.2 tshiozak static void
334 1.2 tshiozak create_rowcol_ext_ilseq_info(struct _region *r)
335 1.2 tshiozak {
336 1.2 tshiozak void *ptr;
337 1.2 tshiozak size_t ofs;
338 1.2 tshiozak
339 1.2 tshiozak ofs = 0;
340 1.2 tshiozak ptr = malloc(_CITRUS_MAPPER_STD_ROWCOL_EXT_ILSEQ_SIZE);
341 1.2 tshiozak if (ptr==NULL)
342 1.2 tshiozak err(EXIT_FAILURE, "malloc");
343 1.2 tshiozak
344 1.2 tshiozak put32(ptr, ofs, oob_mode); ofs++;
345 1.2 tshiozak put32(ptr, ofs, dst_ilseq); ofs++;
346 1.2 tshiozak
347 1.2 tshiozak _region_init(r, ptr, _CITRUS_MAPPER_STD_ROWCOL_EXT_ILSEQ_SIZE);
348 1.2 tshiozak }
349 1.2 tshiozak
350 1.1 tshiozak #define CHKERR(ret, func, a) \
351 1.1 tshiozak do { \
352 1.1 tshiozak ret = func a; \
353 1.1 tshiozak if (ret) \
354 1.1 tshiozak errx(EXIT_FAILURE, "%s: %s", #func, strerror(ret)); \
355 1.1 tshiozak } while (/*CONSTCOND*/0)
356 1.1 tshiozak
357 1.1 tshiozak static void
358 1.1 tshiozak dump_file(void)
359 1.1 tshiozak {
360 1.1 tshiozak FILE *fp;
361 1.1 tshiozak int ret;
362 1.1 tshiozak struct _db_factory *df;
363 1.1 tshiozak struct _region data;
364 1.1 tshiozak void *serialized;
365 1.1 tshiozak size_t size;
366 1.1 tshiozak
367 1.1 tshiozak /*
368 1.1 tshiozak * build database
369 1.1 tshiozak */
370 1.1 tshiozak CHKERR(ret, _db_factory_create, (&df, _db_hash_std, NULL));
371 1.1 tshiozak
372 1.1 tshiozak /* store type */
373 1.1 tshiozak CHKERR(ret, _db_factory_addstr_by_s,
374 1.1 tshiozak (df, _CITRUS_MAPPER_STD_SYM_TYPE,
375 1.1 tshiozak _CITRUS_MAPPER_STD_TYPE_ROWCOL));
376 1.1 tshiozak
377 1.1 tshiozak /* store info */
378 1.1 tshiozak create_rowcol_info(&data);
379 1.1 tshiozak CHKERR(ret, _db_factory_add_by_s,
380 1.1 tshiozak (df, _CITRUS_MAPPER_STD_SYM_INFO, &data, 1));
381 1.1 tshiozak
382 1.2 tshiozak /* ilseq extension */
383 1.2 tshiozak create_rowcol_ext_ilseq_info(&data);
384 1.2 tshiozak CHKERR(ret, _db_factory_add_by_s,
385 1.2 tshiozak (df, _CITRUS_MAPPER_STD_SYM_ROWCOL_EXT_ILSEQ, &data, 1));
386 1.2 tshiozak
387 1.1 tshiozak /* store table */
388 1.1 tshiozak _region_init(&data, table, table_size*dst_unit_bits/8);
389 1.1 tshiozak CHKERR(ret, _db_factory_add_by_s,
390 1.1 tshiozak (df, _CITRUS_MAPPER_STD_SYM_TABLE, &data, 1));
391 1.1 tshiozak
392 1.1 tshiozak /*
393 1.1 tshiozak * dump database to file
394 1.1 tshiozak */
395 1.1 tshiozak if (output)
396 1.1 tshiozak fp = fopen(output, "wb");
397 1.1 tshiozak else
398 1.1 tshiozak fp = stdout;
399 1.1 tshiozak
400 1.1 tshiozak if (fp == NULL) {
401 1.1 tshiozak perror("fopen");
402 1.1 tshiozak exit(1);
403 1.1 tshiozak }
404 1.1 tshiozak
405 1.1 tshiozak /* dump database body */
406 1.1 tshiozak size = _db_factory_calc_size(df);
407 1.1 tshiozak serialized = malloc(size);
408 1.1 tshiozak _region_init(&data, serialized, size);
409 1.1 tshiozak CHKERR(ret, _db_factory_serialize,
410 1.1 tshiozak (df, _CITRUS_MAPPER_STD_MAGIC, &data));
411 1.1 tshiozak if (fwrite(serialized, size, 1, fp) != 1)
412 1.1 tshiozak err(EXIT_FAILURE, "fwrite");
413 1.1 tshiozak
414 1.1 tshiozak fclose(fp);
415 1.1 tshiozak }
416 1.1 tshiozak
417 1.1 tshiozak static void
418 1.1 tshiozak /*ARGSUSED*/
419 1.1 tshiozak set_type(int type)
420 1.1 tshiozak {
421 1.1 tshiozak
422 1.1 tshiozak if (done_flag & DF_TYPE) {
423 1.1 tshiozak warning("TYPE is duplicated. ignored this one");
424 1.1 tshiozak return;
425 1.1 tshiozak }
426 1.1 tshiozak
427 1.1 tshiozak map_type = type;
428 1.1 tshiozak
429 1.1 tshiozak done_flag |= DF_TYPE;
430 1.1 tshiozak }
431 1.1 tshiozak static void
432 1.1 tshiozak /*ARGSUSED*/
433 1.1 tshiozak set_name(char *str)
434 1.1 tshiozak {
435 1.1 tshiozak
436 1.1 tshiozak if (done_flag & DF_NAME) {
437 1.1 tshiozak warning("NAME is duplicated. ignored this one");
438 1.1 tshiozak return;
439 1.1 tshiozak }
440 1.1 tshiozak
441 1.1 tshiozak map_name = str;
442 1.1 tshiozak
443 1.1 tshiozak done_flag |= DF_NAME;
444 1.1 tshiozak }
445 1.1 tshiozak static void
446 1.7 tnozaki set_src_zone(u_int32_t val)
447 1.1 tshiozak {
448 1.7 tnozaki size_t i;
449 1.7 tnozaki linear_zone_t *p;
450 1.1 tshiozak
451 1.1 tshiozak if (done_flag & DF_SRC_ZONE) {
452 1.1 tshiozak warning("SRC_ZONE is duplicated. ignored this one");
453 1.1 tshiozak return;
454 1.1 tshiozak }
455 1.7 tnozaki rowcol_bits = val;
456 1.1 tshiozak
457 1.1 tshiozak /* sanity check */
458 1.7 tnozaki switch (rowcol_bits) {
459 1.7 tnozaki case 8: case 16: case 32:
460 1.7 tnozaki if (rowcol_len <= 32 / rowcol_bits)
461 1.7 tnozaki break;
462 1.7 tnozaki /*FALLTHROUGH*/
463 1.7 tnozaki default:
464 1.1 tshiozak goto bad;
465 1.1 tshiozak }
466 1.7 tnozaki rowcol_mask = 1 << (rowcol_bits - 1);
467 1.7 tnozaki rowcol_mask |= rowcol_mask - 1;
468 1.7 tnozaki for (i = 0; i < rowcol_len; ++i) {
469 1.7 tnozaki p = &rowcol[i];
470 1.7 tnozaki _DIAGASSERT(p->begin <= p->end);
471 1.7 tnozaki if (p->end > rowcol_mask)
472 1.7 tnozaki goto bad;
473 1.1 tshiozak }
474 1.1 tshiozak done_flag |= DF_SRC_ZONE;
475 1.7 tnozaki return;
476 1.1 tshiozak
477 1.7 tnozaki bad:
478 1.7 tnozaki yyerror("Illegal argument for SRC_ZONE");
479 1.1 tshiozak }
480 1.1 tshiozak static void
481 1.1 tshiozak set_dst_invalid(u_int32_t val)
482 1.1 tshiozak {
483 1.1 tshiozak
484 1.1 tshiozak if (done_flag & DF_DST_INVALID) {
485 1.1 tshiozak warning("DST_INVALID is duplicated. ignored this one");
486 1.1 tshiozak return;
487 1.1 tshiozak }
488 1.1 tshiozak
489 1.1 tshiozak dst_invalid = val;
490 1.1 tshiozak
491 1.1 tshiozak done_flag |= DF_DST_INVALID;
492 1.2 tshiozak }
493 1.2 tshiozak static void
494 1.2 tshiozak set_dst_ilseq(u_int32_t val)
495 1.2 tshiozak {
496 1.2 tshiozak
497 1.2 tshiozak if (done_flag & DF_DST_ILSEQ) {
498 1.2 tshiozak warning("DST_ILSEQ is duplicated. ignored this one");
499 1.2 tshiozak return;
500 1.2 tshiozak }
501 1.2 tshiozak
502 1.2 tshiozak dst_ilseq = val;
503 1.2 tshiozak
504 1.2 tshiozak done_flag |= DF_DST_ILSEQ;
505 1.2 tshiozak }
506 1.2 tshiozak static void
507 1.2 tshiozak set_oob_mode(u_int32_t val)
508 1.2 tshiozak {
509 1.2 tshiozak
510 1.2 tshiozak if (done_flag & DF_OOB_MODE) {
511 1.2 tshiozak warning("OOB_MODE is duplicated. ignored this one");
512 1.2 tshiozak return;
513 1.2 tshiozak }
514 1.2 tshiozak
515 1.2 tshiozak oob_mode = val;
516 1.2 tshiozak
517 1.2 tshiozak done_flag |= DF_OOB_MODE;
518 1.1 tshiozak }
519 1.1 tshiozak static void
520 1.1 tshiozak set_dst_unit_bits(u_int32_t val)
521 1.1 tshiozak {
522 1.1 tshiozak
523 1.1 tshiozak if (done_flag & DF_DST_UNIT_BITS) {
524 1.1 tshiozak warning("DST_UNIT_BITS is duplicated. ignored this one");
525 1.1 tshiozak return;
526 1.1 tshiozak }
527 1.1 tshiozak
528 1.1 tshiozak switch (val) {
529 1.1 tshiozak case 8:
530 1.1 tshiozak putfunc = &put8;
531 1.1 tshiozak dst_unit_bits = val;
532 1.1 tshiozak break;
533 1.1 tshiozak case 16:
534 1.1 tshiozak putfunc = &put16;
535 1.1 tshiozak dst_unit_bits = val;
536 1.1 tshiozak break;
537 1.1 tshiozak case 32:
538 1.1 tshiozak putfunc = &put32;
539 1.1 tshiozak dst_unit_bits = val;
540 1.1 tshiozak break;
541 1.1 tshiozak default:
542 1.1 tshiozak yyerror("Illegal argument for DST_UNIT_BITS");
543 1.1 tshiozak }
544 1.1 tshiozak done_flag |= DF_DST_UNIT_BITS;
545 1.1 tshiozak }
546 1.1 tshiozak static int
547 1.1 tshiozak check_src(u_int32_t begin, u_int32_t end)
548 1.1 tshiozak {
549 1.7 tnozaki size_t i;
550 1.7 tnozaki linear_zone_t *p;
551 1.7 tnozaki u_int32_t m, n;
552 1.1 tshiozak
553 1.7 tnozaki if (begin > end)
554 1.7 tnozaki return 1;
555 1.7 tnozaki if (begin < end) {
556 1.7 tnozaki m = begin & ~rowcol_mask;
557 1.7 tnozaki n = end & ~rowcol_mask;
558 1.7 tnozaki if (m != n)
559 1.7 tnozaki return 1;
560 1.7 tnozaki }
561 1.7 tnozaki for (i = rowcol_len * rowcol_bits, p = &rowcol[0]; i > 0; ++p) {
562 1.7 tnozaki i -= rowcol_bits;
563 1.7 tnozaki m = (begin >> i) & rowcol_mask;
564 1.7 tnozaki if (m < p->begin || m > p->end)
565 1.7 tnozaki return 1;
566 1.7 tnozaki }
567 1.7 tnozaki if (begin < end) {
568 1.7 tnozaki n = end & rowcol_mask;
569 1.7 tnozaki _DIAGASSERT(p > rowcol);
570 1.7 tnozaki --p;
571 1.7 tnozaki if (n < p->begin || n > p->end)
572 1.7 tnozaki return 1;
573 1.1 tshiozak }
574 1.7 tnozaki return 0;
575 1.1 tshiozak }
576 1.1 tshiozak static void
577 1.1 tshiozak store(const linear_zone_t *lz, u_int32_t dst, int inc)
578 1.1 tshiozak {
579 1.7 tnozaki size_t i, ofs;
580 1.7 tnozaki linear_zone_t *p;
581 1.7 tnozaki u_int32_t n;
582 1.1 tshiozak
583 1.7 tnozaki ofs = 0;
584 1.7 tnozaki for (i = rowcol_len * rowcol_bits, p = &rowcol[0]; i > 0; ++p) {
585 1.7 tnozaki i -= rowcol_bits;
586 1.7 tnozaki n = ((lz->begin >> i) & rowcol_mask) - p->begin;
587 1.7 tnozaki ofs = (ofs * p->width) + n;
588 1.7 tnozaki }
589 1.7 tnozaki n = lz->width;
590 1.7 tnozaki while (n-- > 0) {
591 1.1 tshiozak (*putfunc)(table, ofs++, dst);
592 1.1 tshiozak if (inc)
593 1.1 tshiozak dst++;
594 1.1 tshiozak }
595 1.1 tshiozak }
596 1.7 tnozaki static void
597 1.7 tnozaki set_range(u_int32_t begin, u_int32_t end)
598 1.7 tnozaki {
599 1.7 tnozaki linear_zone_t *p;
600 1.7 tnozaki
601 1.7 tnozaki if (rowcol_len >= _CITRUS_MAPPER_STD_ROWCOL_MAX)
602 1.7 tnozaki goto bad;
603 1.7 tnozaki p = &rowcol[rowcol_len++];
604 1.7 tnozaki
605 1.7 tnozaki if (begin > end)
606 1.7 tnozaki goto bad;
607 1.7 tnozaki p->begin = begin, p->end = end;
608 1.7 tnozaki p->width = end - begin + 1;
609 1.7 tnozaki
610 1.7 tnozaki return;
611 1.7 tnozaki
612 1.7 tnozaki bad:
613 1.7 tnozaki yyerror("Illegal argument for SRC_ZONE");
614 1.7 tnozaki }
615 1.7 tnozaki static void
616 1.7 tnozaki set_src(linear_zone_t *lz, u_int32_t begin, u_int32_t end)
617 1.7 tnozaki {
618 1.7 tnozaki _DIAGASSERT(lz != NULL);
619 1.7 tnozaki
620 1.7 tnozaki if (check_src(begin, end) != 0)
621 1.7 tnozaki yyerror("illegal zone");
622 1.7 tnozaki
623 1.7 tnozaki lz->begin = begin, lz->end = end;
624 1.7 tnozaki lz->width = end - begin + 1;
625 1.7 tnozaki
626 1.7 tnozaki src_next = end + 1;
627 1.7 tnozaki }
628 1.1 tshiozak
629 1.1 tshiozak static void
630 1.1 tshiozak do_mkdb(FILE *in)
631 1.1 tshiozak {
632 1.1 tshiozak int ret;
633 1.1 tshiozak FILE *out;
634 1.1 tshiozak
635 1.1 tshiozak /* dump DB to file */
636 1.1 tshiozak if (output)
637 1.1 tshiozak out = fopen(output, "wb");
638 1.1 tshiozak else
639 1.1 tshiozak out = stdout;
640 1.1 tshiozak
641 1.1 tshiozak if (out==NULL)
642 1.1 tshiozak err(EXIT_FAILURE, "fopen");
643 1.1 tshiozak
644 1.1 tshiozak ret = _lookup_factory_convert(out, in);
645 1.1 tshiozak fclose(out);
646 1.1 tshiozak if (ret && output)
647 1.1 tshiozak unlink(output); /* dump failure */
648 1.1 tshiozak }
649 1.1 tshiozak
650 1.1 tshiozak static void
651 1.1 tshiozak do_mkpv(FILE *in)
652 1.1 tshiozak {
653 1.1 tshiozak int ret;
654 1.1 tshiozak FILE *out;
655 1.1 tshiozak
656 1.1 tshiozak /* dump pivot to file */
657 1.1 tshiozak if (output)
658 1.1 tshiozak out = fopen(output, "wb");
659 1.1 tshiozak else
660 1.1 tshiozak out = stdout;
661 1.1 tshiozak
662 1.10 christos if (out == NULL)
663 1.1 tshiozak err(EXIT_FAILURE, "fopen");
664 1.1 tshiozak
665 1.1 tshiozak ret = _pivot_factory_convert(out, in);
666 1.1 tshiozak fclose(out);
667 1.1 tshiozak if (ret && output)
668 1.1 tshiozak unlink(output); /* dump failure */
669 1.1 tshiozak if (ret)
670 1.10 christos errc(EXIT_FAILURE, ret, "");
671 1.1 tshiozak }
672 1.1 tshiozak
673 1.9 joerg __dead static void
674 1.1 tshiozak usage(void)
675 1.1 tshiozak {
676 1.10 christos fprintf(stderr, "Usage: %s [-m|-p] [-d] [-o outfile] [infile]\n",
677 1.10 christos getprogname());
678 1.10 christos exit(EXIT_FAILURE);
679 1.1 tshiozak }
680 1.1 tshiozak
681 1.1 tshiozak int
682 1.1 tshiozak main(int argc, char **argv)
683 1.1 tshiozak {
684 1.1 tshiozak int ch;
685 1.1 tshiozak extern char *optarg;
686 1.1 tshiozak extern int optind;
687 1.6 lukem FILE *in = NULL;
688 1.1 tshiozak int mkdb = 0, mkpv = 0;
689 1.1 tshiozak
690 1.1 tshiozak while ((ch=getopt(argc, argv, "do:mp")) != EOF) {
691 1.1 tshiozak switch (ch) {
692 1.1 tshiozak case 'd':
693 1.1 tshiozak debug=1;
694 1.1 tshiozak break;
695 1.1 tshiozak case 'o':
696 1.1 tshiozak output = strdup(optarg);
697 1.1 tshiozak break;
698 1.1 tshiozak case 'm':
699 1.1 tshiozak mkdb = 1;
700 1.1 tshiozak break;
701 1.1 tshiozak case 'p':
702 1.1 tshiozak mkpv = 1;
703 1.1 tshiozak break;
704 1.1 tshiozak default:
705 1.1 tshiozak usage();
706 1.1 tshiozak }
707 1.1 tshiozak }
708 1.1 tshiozak
709 1.1 tshiozak argc-=optind;
710 1.1 tshiozak argv+=optind;
711 1.1 tshiozak switch (argc) {
712 1.1 tshiozak case 0:
713 1.1 tshiozak in = stdin;
714 1.1 tshiozak break;
715 1.1 tshiozak case 1:
716 1.1 tshiozak in = fopen(argv[0], "r");
717 1.1 tshiozak if (!in)
718 1.8 joerg err(EXIT_FAILURE, "%s", argv[0]);
719 1.1 tshiozak break;
720 1.1 tshiozak default:
721 1.1 tshiozak usage();
722 1.1 tshiozak }
723 1.1 tshiozak
724 1.1 tshiozak if (mkdb)
725 1.1 tshiozak do_mkdb(in);
726 1.1 tshiozak else if (mkpv)
727 1.1 tshiozak do_mkpv(in);
728 1.1 tshiozak else {
729 1.1 tshiozak yyin = in;
730 1.1 tshiozak yyparse();
731 1.1 tshiozak }
732 1.1 tshiozak
733 1.1 tshiozak return (0);
734 1.1 tshiozak }
735