xref: /titanic_51/usr/src/cmd/geniconvtbl/itm_util.c (revision dcda19f50b2b80bfc622fff718ac04fb0e1cb670)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright (c) 1999 by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <assert.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <ctype.h>
32 #include <libintl.h>
33 #include <strings.h>
34 #include "iconv_tm.h"
35 #include "itmcomp.h"
36 #include "itm_util.h"
37 #include "hash.h"
38 #include "maptype.h"
39 
40 
41 static size_t	map_table_resultlen(itmc_map_t *);
42 static int	data_pair_compare(itmc_data_pair_t **, itmc_data_pair_t **);
43 static long	data_to_long(itm_data_t *);
44 
45 static itm_tbl_hdr_t	*map_table_indexed_fixed(itmc_data_pair_t **,
46 				itm_size_t, itm_data_t *, long, itm_num_t);
47 static itm_tbl_hdr_t	*map_table_dense_encoding(itmc_data_pair_t **,
48 				itm_size_t, itm_data_t *, unsigned long,
49 				unsigned char *, unsigned char *, long,
50 				itm_num_t);
51 static itm_tbl_hdr_t	*map_table_lookup_fixed(itmc_data_pair_t **,
52 				itm_size_t, itm_data_t *, long, itm_size_t);
53 static itm_tbl_hdr_t	*map_table_hash(itmc_data_pair_t **, itm_size_t,
54 				itm_data_t *, long, long, itm_size_t,
55 				itm_num_t);
56 static itm_tbl_hdr_t	*map_table_lookup_var();
57 static void		put_dense_encoding_default(char *, unsigned char *,
58 			unsigned char *, unsigned char *, long, long, long);
59 static size_t		map_table_resultlen(itmc_map_t *);
60 static void		map_range_adjust_byte_seq(unsigned char *,
61 				unsigned char *, long, itmc_data_pair_t *);
62 static void		map_range_make_result(char *, itm_size_t, itm_size_t,
63 				char *, itm_size_t);
64 static size_t		map_table_num_range(itmc_data_pair_t *);
65 static itmc_map_type_t	check_map_type(itmc_map_attr_t *);
66 
67 
68 static itmc_name_t	*name_lookup(itm_data_t *, itm_type_t);
69 static itmc_name_t	*name_refer(itm_data_t *, itm_type_t, itmc_ref_t *);
70 static itmc_name_t	*name_register(itm_data_t *, itm_type_t, itmc_ref_t *);
71 static void		op_hirarchy(itm_tbl_hdr_t *, itmc_obj_t *);
72 static obj_array_t	obj_list_to_array(itm_size_t, itmc_obj_t *, itm_size_t);
73 
74 
75 void
76 itm_def_process(itm_data_t	*itm_name)
77 {
78 	itm_hdr_t	*itm_hdr;
79 	long		len;
80 
81 	TRACE_MESSAGE('y', ("itm_def_process\n"));
82 
83 
84 	itm_hdr = malloc_vital(sizeof (itm_hdr_t));
85 	(void) memset(itm_hdr, 0, sizeof (itm_hdr_t));
86 
87 	if ((NULL != cmd_opt.interpreter) &&
88 	    (0 < (len = strlen(cmd_opt.interpreter)))) {
89 		itm_hdr->interpreter = *(str_to_data(len, cmd_opt.interpreter));
90 	}
91 	if ((sizeof (itm_place_t)) < itm_hdr->interpreter.size) {
92 		(void) obj_register(ITMC_OBJ_STRING, NULL,
93 				(void *)itm_hdr->interpreter.place.itm_ptr,
94 				itm_hdr->interpreter.size,
95 				&(itm_hdr->interpreter.place),
96 				OBJ_REG_HEAD);
97 	}
98 
99 	itm_hdr->type_id = *itm_name;
100 	if ((sizeof (itm_place_t)) < itm_hdr->type_id.size) {
101 		(void) obj_register(ITMC_OBJ_STRING, NULL,
102 				(void *)itm_hdr->type_id.place.itm_ptr,
103 				itm_hdr->type_id.size,
104 				&(itm_hdr->type_id.place),
105 				OBJ_REG_HEAD);
106 	}
107 
108 	(void) assemble(itm_hdr);
109 }
110 
111 
112 
113 itmc_obj_t *
114 direction_unit(
115 	itmc_ref_t	*cond,
116 	itm_data_t	*cond_name,
117 	itmc_action_t	*act,
118 	itm_data_t	*act_name)
119 {
120 	itmc_obj_t	*du;
121 	itm_direc_t	*direc;
122 
123 	du = malloc_vital(sizeof (itmc_obj_t));
124 	du->type = ITMC_OBJ_DIREC;
125 	du->name = NULL;
126 	du->obj = direc = malloc_vital(sizeof (itm_direc_t));
127 
128 	if (NULL != cond) {
129 		direc->condition.itm_ptr = 0;
130 		cond->referencer = &(direc->condition);
131 		du->ref[0] = cond;
132 	} else if (NULL != cond_name) {
133 		direc->condition.itm_ptr = (itm_place2_t)(cond_name);
134 		du->ref[0] = obj_register(ITMC_OBJ_COND, cond_name, NULL, 0,
135 					&(direc->condition), OBJ_REG_TAIL);
136 	} else {
137 		direc->condition.itm_ptr = 0;
138 		du->ref[0] = NULL;
139 	}
140 
141 
142 	if (NULL != act_name) {
143 		direc->action.itm_ptr = (itm_place2_t)(act_name);
144 		du->ref[1] = obj_register(ITMC_OBJ_ACTION, act_name, NULL, 0,
145 					&(direc->action), OBJ_REG_TAIL);
146 	} else if (NULL != act && act->tbl_hdr != NULL) {
147 		direc->action.itm_ptr = (itm_place2_t)(act->tbl_hdr);
148 		du->ref[1] = obj_register(act->type,
149 				(itm_data_t *)(act->tbl_hdr->name.itm_ptr),
150 				act->tbl_hdr, act->tbl_hdr->size,
151 				&(direc->action), OBJ_REG_TAIL);
152 	} else {
153 		return (NULL);
154 	}
155 
156 	du->ref[2] = NULL;
157 	return	(du);
158 }
159 
160 
161 
162 itm_tbl_hdr_t *
163 obj_table(itm_type_t	tbl_type,
164 	itm_data_t	*name,
165 	itmc_obj_t	*obj_list,
166 	itm_size_t	obj_size)
167 {
168 	itm_tbl_hdr_t	*tbl;
169 	obj_array_t	obj_array;
170 
171 	obj_array = obj_list_to_array(sizeof (itm_tbl_hdr_t),
172 					obj_list, obj_size);
173 	tbl = obj_array.obj;
174 
175 	tbl->type = tbl_type;
176 	if (name) {
177 #if !defined(_LP64)
178 		tbl->name.itm_pad = 0;
179 #endif
180 		tbl->name.itm_ptr = (itm_place2_t)name;
181 	} else {
182 #if !defined(_LP64)
183 		tbl->name.itm_pad = 0;
184 #endif
185 		tbl->name.itm_ptr = NULL;
186 	}
187 	tbl->size = (sizeof (itm_tbl_hdr_t)) + (obj_array.num	*obj_size);
188 	tbl->number = obj_array.num;
189 
190 	if ((ITM_TBL_MASK&tbl->type) == ITM_TBL_OP) {
191 		op_hirarchy(tbl, obj_list);
192 	}
193 	return	(tbl);
194 }
195 
196 /*
197  *
198  */
199 static obj_array_t
200 obj_list_to_array(itm_size_t hdr_size, itmc_obj_t	*obj_list,
201 			itm_size_t size)
202 {
203 	obj_array_t	obj_array;
204 	itm_size_t	offset;
205 	itmc_obj_t	*ol;
206 
207 	for (obj_array.num = 0, ol = obj_list;
208 	    ol; obj_array.num += 1, ol = ol->next) {
209 		/* NOP */;
210 	}
211 
212 	obj_array.obj = malloc_vital(hdr_size + (size * obj_array.num));
213 
214 	if (obj_array.num == 0)
215 		return	(obj_array);
216 
217 	for (offset = hdr_size, ol = obj_list;
218 	    ol; offset += size, ol = ol->next) {
219 		(void) memcpy((char *)(obj_array.obj) + offset, ol->obj, size);
220 		if (ol->ref[0]) {
221 			ol->ref[0]->referencer =
222 			(void *)((char *)(ol->ref[0]->referencer) +
223 			((char *)(obj_array.obj) -
224 			(char *)(ol->obj) + offset));
225 		}
226 		if (ol->ref[1]) {
227 			ol->ref[1]->referencer =
228 			(void *)((char *)(ol->ref[1]->referencer) +
229 			((char *)(obj_array.obj) -
230 			(char *)(ol->obj) + offset));
231 		}
232 		if (ol->ref[2]) {
233 			ol->ref[2]->referencer =
234 			(void *)((char *)(ol->ref[2]->referencer) +
235 			((char *)(obj_array.obj) -
236 			(char *)(ol->obj) + offset));
237 		}
238 	}
239 
240 	return	(obj_array);
241 }
242 
243 static void
244 op_hirarchy(itm_tbl_hdr_t	*optbl,
245 	itmc_obj_t		*obj_list)
246 {
247 	itm_op_outer_t	*o;
248 	itm_op_inner_t	*in;
249 	itmc_obj_t	*ol;
250 
251 	TRACE_MESSAGE('l', ("op_hirarchy (optbl=%x)\n", optbl));
252 	o = malloc_vital(sizeof (itm_op_outer_t));
253 	o->link = itm_op_outer;
254 	itm_op_outer = o;
255 	o->in = NULL;
256 	o->optbl = optbl;
257 
258 	for (ol = obj_list; ol != NULL; ol = ol->next) {
259 		if ((ol->type == ITMC_OBJ_OP) &&
260 			(((itm_op_t *)ol->obj)->type == ITM_OP_OPERATION)) {
261 			in = malloc_vital(sizeof (itm_op_inner_t));
262 			in->in = o->in;
263 			o->in = in;
264 			TRACE_MESSAGE('L', ("o->in(%x) in->in(%x)\n",
265 				o->in, in->in));
266 			in->ref = ol->ref[0];
267 		}
268 	}
269 
270 #ifdef ENABLE_TRACE
271 	for (in = o->in; in != NULL; in = in->in) {
272 		TRACE_MESSAGE('L', ("o=%x in=%x in->in=%x\n",
273 				o, in, in->in));
274 		TRACE_MESSAGE('L', ("o(table)%x->in(ref)=%x\n",
275 		o->optbl, in->ref));
276 	}
277 #endif
278 
279 }
280 
281 itmc_obj_t *
282 obj_list_append(itmc_obj_t	*obj_list, itmc_obj_t	*obj)
283 {
284 	if (0 == obj) {
285 		return	(obj_list);
286 	}
287 
288 	obj->next = NULL;
289 	obj->last = obj;
290 
291 	if (obj_list) {
292 		obj_list->last->next = obj;
293 		obj_list->last = obj;
294 		return	(obj_list);
295 	} else {
296 		return	(obj);
297 	}
298 }
299 
300 
301 itmc_ref_t *
302 obj_register(itm_type_t type, itm_data_t	*name,
303 		void	*obj, size_t size, itm_place_t	*ref,
304 		itm_type_t reg_place)
305 {
306 	itmc_ref_t	*refp;
307 
308 	TRACE_MESSAGE('O', ("obj_register: %6ld %08p %08p %08ld %08p %ld\n",
309 			type, name, obj, size, ref, reg_place));
310 
311 	refp = malloc_vital(sizeof (itmc_ref_t));
312 	refp->name = NULL;
313 	refp->referencee = obj;
314 #if !defined(_LP64)
315 	refp->reloc.itm_pad = 0;
316 #endif
317 	refp->reloc.itm_ptr = 0;
318 	refp->size = size;
319 	refp->referencer = ref;
320 	refp->next = NULL;
321 
322 	if (NULL == obj) { /* reference to named object */
323 		if (NULL == name) {
324 			if (0 == error_deferred) {
325 				/* should never happen */
326 				itm_error(
327 				gettext("internal error: "
328 					"obj_register: (NULL == obj) "
329 					"&& (NULL == name)\n"));
330 				exit(ITMC_STATUS_SYS2);
331 			}
332 			return (NULL);
333 		}
334 		refp->name = name_refer(name, type, refp);
335 		return	(refp);
336 	} else if ((NULL != name) && (0 < name->size)) {
337 		/* definition of named object */
338 		refp->name = name_register(name, type, refp);
339 	}
340 
341 	if ((ITMC_OBJ_FIRST <= type) && (type <= ITMC_OBJ_LAST)) {
342 		switch (reg_place) {
343 		case OBJ_REG_HEAD:
344 			refp->next = ref_first[type];
345 			ref_first[type] = refp;
346 			if (NULL == ref_last[type]) {
347 				ref_last[type] = refp;
348 			}
349 			break;
350 		case OBJ_REG_TAIL:
351 			if (ref_first[type]) {
352 				ref_last[type]->next = refp;
353 			} else {
354 				ref_first[type] = refp;
355 			}
356 			ref_last[type] = refp;
357 			break;
358 		}
359 	} else {
360 		itm_error(gettext("obj_register: illegal object type\n"));
361 		exit(ITMC_STATUS_SYS2);
362 	}
363 
364 	return	(refp);
365 }
366 
367 
368 itm_tbl_hdr_t *
369 range_table(itm_data_t		*name, itmc_obj_t	*obj_list)
370 {
371 	itm_num_t		num;
372 	itmc_obj_t		*ol;
373 	itmc_data_pair_t	*rp;
374 	itm_range_hdr_t		*rh;
375 	itm_tbl_hdr_t		*table;
376 	itm_size_t		length = 0;
377 	itm_num_t		i;
378 	char			*p;
379 	itm_size_t		table_size;
380 
381 	/* count range, determine length */
382 	for (num = 0, ol = obj_list; ol; ol = ol->next, num++) {
383 		rp = (itmc_data_pair_t *)(ol->obj);
384 		if (length == 0) {
385 			if (rp->data0.size == 0) {
386 				itm_error(gettext("between has null range\n"));
387 					error_deferred += 1;
388 				return	(NULL);
389 			}
390 			length = rp->data0.size;
391 		}
392 		if ((rp->data0.size != length) ||
393 		    (rp->data1.size != length)) {
394 			itm_error(gettext(
395 			"length of source sequences must be the same\n"));
396 			error_deferred += 1;
397 			return	(NULL);
398 		}
399 	}
400 	if (num == 0) {
401 		itm_error(gettext("between has no ranges\n"));
402 		error_deferred += 1;
403 		return	(NULL);
404 	}
405 	table_size = ((sizeof (itm_tbl_hdr_t)) +
406 			(sizeof (itm_range_hdr_t)) + (length * num) * 2);
407 	table_size = ITMROUNDUP(table_size);
408 
409 	table = malloc_vital(table_size);
410 	table->type = ITM_TBL_RANGE;
411 	if (NULL != name)
412 		table->name.itm_ptr = (itm_place2_t)name;
413 	table->size = table_size;
414 	table->number = num;
415 
416 	rh = (itm_range_hdr_t *)(table + 1);
417 	rh->len = length;
418 
419 	p = (char *)(rh + 1);
420 	for (ol = obj_list, i = 0; ol; ol = ol->next, i++) {
421 		rp = (itmc_data_pair_t *)(ol->obj);
422 		(void) memcpy(p, (NSPTR(&(rp->data0))), length);
423 		p += length;
424 		(void) memcpy(p, (NSPTR(&(rp->data1))), length);
425 		p += length;
426 	}
427 
428 	return	(table);
429 }
430 
431 /*
432  *	escape sequence table for stateful code set sequence
433  */
434 itm_tbl_hdr_t *
435 escseq_table(itm_data_t		*name, itmc_obj_t	*obj_list)
436 {
437 	itm_num_t		num;
438 	itmc_obj_t		*ol;
439 	itm_data_t		*ep;
440 	itm_escapeseq_hdr_t	*eh;
441 	itm_tbl_hdr_t		*table;
442 	itm_size_t		len_max = 0;
443 	itm_size_t		len_min;
444 	itm_num_t		i;
445 	itm_size_t		table_size;
446 
447 	ol = obj_list;
448 	len_min = ((itm_data_t *)(ol->obj))->size;
449 	for (num = 0; NULL != ol; ol = ol->next, num++) {
450 		ep = (itm_data_t *)(ol->obj);
451 		if (ep->size < len_min)	 len_min = ep->size;
452 		if (ep->size > len_max)	 len_max = ep->size;
453 	}
454 	if (num == 0) {
455 		itm_error(gettext
456 			("escape sequence is defined without sequence\n"));
457 		error_deferred += 1;
458 		return	(NULL);
459 	} else if (0 == len_min) {
460 		itm_error(gettext("null sequence\n"));
461 		error_deferred += 1;
462 		return	(NULL);
463 	}
464 
465 	table_size = ((sizeof (itm_tbl_hdr_t)) +
466 			(sizeof (itm_escapeseq_hdr_t)) +
467 			(sizeof (itm_data_t) * num));
468 	table_size = ITMROUNDUP(table_size);
469 	table = malloc_vital(table_size);
470 	table->type = ITM_TBL_ESCAPESEQ;
471 	if (NULL != name)
472 		table->name.itm_ptr = (itm_place2_t)name;
473 	table->size = table_size;
474 	table->number = num;
475 
476 	eh = (itm_escapeseq_hdr_t *)(table + 1);
477 	eh->len_max = len_max;
478 	eh->len_min = len_min;
479 
480 	for (ol = obj_list, ep = (itm_data_t *)(eh + 1);
481 	    ol != NULL;
482 	    ol = ol->next, ep++) {
483 		*ep = *((itm_data_t *)(ol->obj));
484 		if ((sizeof (itm_place_t)) < ep->size) {
485 			(void) obj_register(ITMC_OBJ_DATA, NULL,
486 					(void *)(ep->place.itm_ptr), ep->size,
487 					&(ep->place), OBJ_REG_TAIL);
488 		}
489 	}
490 	(void) qsort((itm_data_t *)(eh + 1), num, sizeof (itm_data_t),
491 		(int (*)(const void *, const void *))data_compare);
492 
493 	for (i = 0, ep = (itm_data_t *)(eh + 1);
494 	    i < num - 1;
495 	    i++, ep++) {
496 		if (0 <= data_compare(ep, (ep + 1))) {
497 			itm_error(
498 			gettext(
499 			"same escape sequences are defined: 0x%1$s 0x%2$s\n"),
500 			data_to_hexadecimal(ep),
501 			data_to_hexadecimal(ep + 1));
502 			error_deferred += 1;
503 			return	(NULL);
504 		}
505 	}
506 	return	(table);
507 }
508 
509 
510 
511 
512 itm_tbl_hdr_t *
513 map_table(itm_data_t	*name, itmc_map_t	*map_list,
514 		itmc_map_attr_t *attr)
515 {
516 	itm_size_t		num;
517 	itm_size_t		num2;
518 	itmc_map_t		*ml;
519 	itmc_data_pair_t	**tpp;
520 	itm_tbl_hdr_t		*table;
521 	long			source_len = 0;
522 	long			result_len = 0;
523 	long			source_fixed_len = 1;
524 	long			pass_through = 0;
525 	long			default_count = 0;
526 	itm_data_t		*default_data = NULL;
527 	long			error_deferred_local = 0;
528 	unsigned long		dense_encoded_map_ent;
529 	unsigned long		simple_indexed_map_ent;
530 	itm_size_t		source_start;
531 	itm_size_t		source_end;
532 	unsigned long		u;
533 	unsigned char		*byte_seq_min;
534 	unsigned char		*byte_seq_max;
535 	unsigned char		*p;
536 	long			i;
537 	itmc_map_type_t		map_type = NULL;
538 	itmc_map_name_type_t	*map_name_type;
539 	long			hash_factor;
540 	long			result_len_specfied = 0;
541 	size_t			j;
542 	long			n;
543 	itmc_data_pair_t	**dp1;
544 	itm_num_t		error_count = 0;
545 
546 	if (attr != NULL) {
547 		map_type = check_map_type(attr);
548 	}
549 	if (NULL == map_type) {
550 		map_type = ITMC_MAP_AUTOMATIC;
551 	}
552 	hash_factor = ((NULL != attr) && (attr->hash_factor != 0)) ?
553 							attr->hash_factor:
554 							200;
555 
556 	map_name_type = cmd_opt.map_name_type;
557 	for (; map_name_type; map_name_type = map_name_type->next) {
558 		if ('\0' == *(map_name_type->name)) {
559 			map_type = map_name_type->type;
560 			hash_factor = map_name_type->hash_factor;
561 			break;
562 		}
563 	}
564 	map_name_type = cmd_opt.map_name_type;
565 	if ((NULL != name) && (NULL != cmd_opt.map_name_type)) {
566 		p = NSPTR(name);
567 		for (; map_name_type; map_name_type = map_name_type->next) {
568 			if (0 == strcmp(map_name_type->name, (char *)p)) {
569 				map_type = map_name_type->type;
570 				hash_factor = map_name_type->hash_factor;
571 				break;
572 			}
573 		}
574 	}
575 
576 	if (NULL != attr) {
577 		if (MAXSEQUENCE < attr->resultlen) {
578 			itm_error(
579 			gettext("output_byte_length must be less than %1$d\n"),
580 			MAXSEQUENCE);
581 			error_deferred += 1;
582 			return	(NULL);
583 		}
584 		result_len_specfied = attr->resultlen;
585 	} else {
586 		result_len_specfied = 0;
587 	}
588 
589 	for (num = 0, ml = map_list; ml; ml = ml->next, num++) {
590 
591 		/* default */
592 		if (0 == ml->data_pair.data0.size) {
593 			if (0 == ml->data_pair.data1.size) {
594 				pass_through += 1;
595 				default_data = (itm_data_t *)(-1);
596 			} else {
597 				default_count += 1;
598 				default_data = &(ml->data_pair.data1);
599 			}
600 			--num;
601 
602 
603 		} else if (0 == ml->data_pair.data1.size) {
604 			/* error source sequence */
605 			continue;
606 		}
607 
608 		/* fixed length */
609 		if ((0 < source_len) &&
610 		    (0 < ml->data_pair.data0.size) &&
611 		    (source_len != ml->data_pair.data0.size)) {
612 			source_fixed_len = 0;
613 		}
614 
615 		/* maximum length */
616 		if (source_len < ml->data_pair.data0.size) {
617 			source_len = ml->data_pair.data0.size;
618 		}
619 		if (result_len < ml->data_pair.data1.size) {
620 			result_len = ml->data_pair.data1.size;
621 		}
622 
623 		/* map source has range */
624 		if (0 < ml->data_pair.range.size) {
625 			if (ml->data_pair.range.size !=
626 			    ml->data_pair.data0.size) {
627 				itm_error(
628 				gettext("length of source range must be "
629 				"the same: 0x%1$s 0x%2$s\n"),
630 				data_to_hexadecimal(&(ml->data_pair.data0)),
631 				data_to_hexadecimal(&(ml->data_pair.range)));
632 				error_deferred += 1;
633 				return	(NULL);
634 			}
635 			if (0 <= data_compare(&(ml->data_pair.data0),
636 			    &((ml->data_pair.range)))) {
637 				itm_error(
638 				gettext("source range error: 0x%1$s 0x%2$s\n"),
639 				data_to_hexadecimal(&(ml->data_pair.data0)),
640 				data_to_hexadecimal(&(ml->data_pair.range)));
641 				error_deferred += 1;
642 				return	(NULL);
643 			}
644 			j = map_table_resultlen(ml);
645 			if (result_len < j) {
646 				result_len = j;
647 			}
648 		}
649 	}
650 	if (num == 0) {
651 		itm_error(
652 			gettext("no mapping pair\n"));
653 		error_deferred += 1;
654 		return	(NULL);
655 	}
656 
657 	if (0 != result_len_specfied) {
658 		if (result_len > result_len_specfied) {
659 			itm_error(
660 			gettext("result value length is "
661 			"over specifed output_byte_length(%1$ld)\n"),
662 			result_len_specfied);
663 			error_deferred += 1;
664 			return	(NULL);
665 		}
666 		result_len = result_len_specfied;
667 	}
668 	byte_seq_min = malloc_vital((sizeof (unsigned char)) * source_len);
669 	byte_seq_max = malloc_vital((sizeof (unsigned char)) * source_len);
670 	for (num = 0, ml = map_list; ml; ml = ml->next, num++) {
671 		if (0 == ml->data_pair.data0.size) {
672 			continue;
673 		}
674 
675 		p = (unsigned char *)(NSPTR(&((ml->data_pair).data0)));
676 		for (i = 0; i < source_len; i++) {
677 			*(byte_seq_min + i) = *(p + i);
678 			*(byte_seq_max + i) = *(p + i);
679 		}
680 		break;
681 	}
682 	for (num = 0, ml = map_list; ml; ml = ml->next, num++) {
683 		if (0 == ml->data_pair.data0.size) {
684 			num--;
685 			continue;
686 		}
687 		if (ml->data_pair.range.size > 0) {
688 			map_range_adjust_byte_seq(byte_seq_min, byte_seq_max,
689 					    source_len, &(ml->data_pair));
690 		} else {
691 			p = (unsigned char *)(NSPTR(&((ml->data_pair).data0)));
692 			for (i = 0; i < source_len; i++) {
693 				if (*(p + i) < *(byte_seq_min + i)) {
694 					*(byte_seq_min + i) = *(p + i);
695 				}
696 				if (*(byte_seq_max + i) < *(p + i)) {
697 					*(byte_seq_max + i) = *(p + i);
698 				}
699 			}
700 		}
701 	}
702 	for (dense_encoded_map_ent = 1, i = 0; i < source_len; i++) {
703 		u = dense_encoded_map_ent;
704 		dense_encoded_map_ent *=
705 			(*(byte_seq_max + i) - *(byte_seq_min + i) + 1);
706 		if (dense_encoded_map_ent < u) {
707 			dense_encoded_map_ent = (ulong_t)(~0);
708 			break;
709 		}
710 	}
711 #if defined(DEBUG)
712 	if (TRACE('m')) {
713 		int	i;
714 		TRACE_MESSAGE('m', ("map_table: ent=%lu num=%lu	",
715 				dense_encoded_map_ent, num));
716 		TRACE_MESSAGE('m', ("byte_seq_min=0x"));
717 		for (i = 0; i < source_len; i++) {
718 			TRACE_MESSAGE('m', ("%02x", *(byte_seq_min + i)));
719 		}
720 		TRACE_MESSAGE('m', ("  byte_seq_max=0x"));
721 		for (i = 0; i < source_len; i++) {
722 			TRACE_MESSAGE('m', ("%02x", *(byte_seq_max + i)));
723 		}
724 		TRACE_MESSAGE('m', ("\n"));
725 	}
726 #endif /* DEBUG */
727 
728 	tpp = malloc_vital((sizeof (itmc_data_pair_t *)) * num);
729 	for (num = 0, num2 = 0, ml = map_list; ml; ml = ml->next) {
730 		if (0 < ml->data_pair.data0.size) {
731 			itm_num_t range_num;
732 			*(tpp + num) = &(ml->data_pair);
733 			num++;
734 			range_num = 1;
735 			if (ml->data_pair.range.size > 0) {
736 				range_num +=
737 				map_table_num_range(&(ml->data_pair));
738 			}
739 			num2 += range_num;
740 			if (0 == ml->data_pair.data1.size) {
741 				/* specified error sequence */
742 				error_count += range_num;
743 			}
744 		}
745 	}
746 	(void) qsort(tpp, num, sizeof (itmc_data_pair_t *),
747 		(int (*)(const void *, const void *))data_pair_compare);
748 
749 	/* check if map_pair range and next map_pair are overrapped */
750 	for (n = 0, dp1 = tpp; n < (num-1); n++, dp1++) {
751 		if (((*(dp1+0))->range.size != 0) &&
752 		    (0 <= data_compare(&((*(dp1+0))->range),
753 		    &((*(dp1+1))->data0)))) {
754 			itm_error(
755 			gettext("ranges of source sequences "
756 			"overrapped: %1$s %2$s\n"),
757 			data_to_hexadecimal(&((*(dp1+0))->range)),
758 			data_to_hexadecimal(&((*(dp1+1))->data0)));
759 			error_deferred += 1;
760 			return	(NULL);
761 		}
762 	}
763 
764 	if (1 < default_count) {
765 		itm_error(
766 			gettext("default is specified %1$d times in a map\n"),
767 			default_count);
768 		error_deferred_local += 1;
769 	}
770 	if ((1 == default_count) && (!source_fixed_len)) {
771 		itm_error(
772 			gettext("default is specified,"
773 				" but length of source data is not fixed\n"));
774 		error_deferred_local += 1;
775 	}
776 	if ((1 <= pass_through) && (source_len != result_len)) {
777 		itm_error(
778 			gettext("\"default no_change_copy\" is "
779 			"specified, but size does not match\n"));
780 		error_deferred_local += 1;
781 	}
782 
783 	if (error_deferred_local) {
784 		error_deferred += error_deferred_local;
785 		return	(NULL);
786 	}
787 
788 	if (source_fixed_len) {
789 		source_start = data_to_long(&((*(tpp + 0))->data0));
790 		source_end = data_to_long(&((*(tpp + num - 1))->data0));
791 		if (0 < (*(tpp + num - 1))->range.size) {
792 			source_end = data_to_long(&((*(tpp + num - 1))->range));
793 		}
794 
795 		simple_indexed_map_ent = source_end - source_start + 1;
796 
797 		TRACE_MESSAGE('m', ("map_table: simple_indexed_map_ent=%lu\n",
798 				simple_indexed_map_ent));
799 
800 		switch (map_type) {
801 		case ITMC_MAP_AUTOMATIC:
802 			if ((source_len <= 2) &&
803 			    (((ulong_t)(~0) == dense_encoded_map_ent) ||
804 			    (simple_indexed_map_ent <
805 			    (dense_encoded_map_ent * 2)))) {
806 				/*
807 				 * for small source sequence,
808 				 * if dense table is not so large
809 				 * compared with simple table,
810 				 * use simple.
811 				 */
812 				map_type = ITMC_MAP_SIMPLE_INDEX;
813 			} else if (cmd_opt.large_table) {
814 				if ((sizeof (long)) < source_len) {
815 					itm_error(
816 					gettext("length of source is too long "
817 						"for large table: %ld\n"),
818 						source_len);
819 					error_deferred += 1;
820 					return	(NULL);
821 				}
822 				map_type = ITMC_MAP_SIMPLE_INDEX;
823 			} else if (((ulong_t)(~0) == dense_encoded_map_ent) ||
824 			    ((0xffff < dense_encoded_map_ent) &&
825 			    ((num2 * 8) < dense_encoded_map_ent))) {
826 				/*
827 				 * if dense can be used and not too large
828 				 * ( less than (hash table entry * 8),
829 				 * use dense.
830 				 */
831 				map_type = ITMC_MAP_SIMPLE_HASH;
832 			} else {
833 				map_type = ITMC_MAP_DENSE_ENCODING;
834 			}
835 			break;
836 		case ITMC_MAP_SIMPLE_INDEX:
837 			if ((sizeof (long)) < source_len) {
838 				itm_error(
839 				gettext("length of source is too long "
840 					"for index lookup: %ld\n"),
841 					source_len);
842 				error_deferred += 1;
843 				return	(NULL);
844 			}
845 			break;
846 		case ITMC_MAP_SIMPLE_HASH:
847 			for (i = 2, u = 256; i < (sizeof (long)); i++) {
848 				u *= 256;
849 			}
850 			if (u < num2) {
851 				itm_error(
852 				gettext("map is too large for hashing: %lu\n"),
853 					num2);
854 				error_deferred += 1;
855 				return	(NULL);
856 			}
857 			break;
858 		case ITMC_MAP_DENSE_ENCODING:
859 			for (i = 2, u = 256; i < (sizeof (long)); i++) {
860 				u *= 256;
861 			}
862 			if (u < dense_encoded_map_ent) {
863 				itm_error(
864 				gettext(
865 				"map is too large for dense encoding: %lu\n"),
866 				dense_encoded_map_ent);
867 				error_deferred += 1;
868 				return	(NULL);
869 			}
870 			break;
871 		case ITMC_MAP_BINARY_SEARCH:
872 			for (i = 2, u = 256; i < (sizeof (long)); i++) {
873 				u *= 256;
874 			}
875 			if (u < num2) {
876 				itm_error(
877 				gettext("length of source is too long for "
878 					"binary search: %ld\n"),
879 				source_len);
880 				error_deferred += 1;
881 				return	(NULL);
882 			}
883 			break;
884 		default:
885 			break;
886 		}
887 		switch (map_type) {
888 		case ITMC_MAP_SIMPLE_INDEX:
889 			table = map_table_indexed_fixed(
890 				tpp, num, default_data,
891 				result_len, error_count);
892 			break;
893 		case ITMC_MAP_SIMPLE_HASH:
894 			table = map_table_hash(tpp, num, default_data,
895 					hash_factor, result_len, num2,
896 					error_count);
897 			break;
898 		case ITMC_MAP_DENSE_ENCODING:
899 			table = map_table_dense_encoding(tpp, num,
900 					default_data,
901 					dense_encoded_map_ent,
902 					byte_seq_min, byte_seq_max,
903 					result_len, error_count);
904 			break;
905 		case ITMC_MAP_BINARY_SEARCH:
906 			table = map_table_lookup_fixed(tpp, num,
907 					default_data,
908 					result_len, num2);
909 			break;
910 		}
911 	} else {
912 		table = map_table_lookup_var();
913 	}
914 
915 	if ((NULL != name) && (NULL != table)) {
916 		table->name.itm_ptr = (itm_place2_t)name;
917 	}
918 
919 	return	(table);
920 }
921 
922 
923 static itmc_map_type_t
924 check_map_type(itmc_map_attr_t *attr)
925 {
926 	int i;
927 
928 	if (NULL == attr->type) {
929 		return (0);
930 	}
931 	for (i = 0; NULL != map_type_name[i].name; i++) {
932 		if (0 == strncmp(((char *)&(attr->type->place)),
933 				map_type_name[i].name, attr->type->size)) {
934 			return (map_type_name[i].type);
935 		}
936 	}
937 	return (0);
938 }
939 
940 
941 static itm_tbl_hdr_t *
942 map_table_indexed_fixed(
943 	itmc_data_pair_t	**tpp,
944 	itm_size_t		num,
945 	itm_data_t		*default_data,
946 	long			resultlen,
947 	itm_num_t		error_count)
948 {
949 	itm_tbl_hdr_t		*header;
950 	itm_map_idx_fix_hdr_t	*sub_hdr;
951 	char			*table;
952 	char			*error_table;
953 	itm_size_t		source_start;
954 	itm_size_t		source_end;
955 	itm_size_t		entry_num;
956 	itm_size_t		table_size;
957 	itm_size_t		j;
958 	itm_size_t		i;
959 	itm_size_t		k;
960 	char			*p;
961 	itm_data_t		*source;
962 
963 	TRACE_MESSAGE('m', ("map_table_range : %ld\n", num));
964 
965 	source = &((*(tpp + 0))->data0);
966 	assert((sizeof (itm_place_t)) >= source->size);
967 
968 	if ((1 == source->size) &&
969 	    (1 == resultlen)) {
970 		source_start = 0;
971 		source_end = 255;
972 	} else {
973 		source_start = data_to_long(&((*(tpp + 0))->data0));
974 		source_end = data_to_long(&((*(tpp + num - 1))->data0));
975 		if (0 < (*(tpp + num - 1))->range.size)
976 			source_end = data_to_long(&((*(tpp + num - 1))->range));
977 	}
978 
979 	entry_num = source_end - source_start + 1;
980 
981 	table_size = ((sizeof (itm_tbl_hdr_t)) +
982 			(sizeof (itm_map_idx_fix_hdr_t)) +
983 			(resultlen * entry_num));
984 	if (0 < error_count) {
985 		table_size += entry_num;
986 	}
987 	if (NULL == default_data) {
988 		if ((num < entry_num) ||
989 		    (error_count <= 0)) {
990 			table_size += entry_num;
991 		}
992 	} else if ((itm_data_t *)(-1) != default_data) {
993 		table_size += resultlen;
994 	}
995 
996 	table_size = ITMROUNDUP(table_size);
997 	header = malloc_vital(table_size);
998 	sub_hdr = (itm_map_idx_fix_hdr_t *)(header + 1);
999 	table = (char *)(sub_hdr + 1);
1000 
1001 	if ((1 == (*tpp)->data0.size) &&
1002 	    (1 == (*tpp)->data1.size)) {
1003 		header->type = ITM_TBL_MAP_INDEX_FIXED_1_1;
1004 	} else {
1005 		header->type = ITM_TBL_MAP_INDEX_FIXED;
1006 	}
1007 	header->name.itm_ptr = 0;
1008 	header->size = table_size;
1009 	header->number = entry_num;
1010 
1011 	sub_hdr->source_len = (*tpp)->data0.size;
1012 	sub_hdr->result_len = resultlen;
1013 	sub_hdr->start.itm_ptr = source_start;
1014 	sub_hdr->end.itm_ptr = source_end;
1015 	sub_hdr->error_num = error_count; /* > 0; so pad4 = 0 */
1016 
1017 	if (NULL != default_data) {
1018 		if ((itm_data_t *)(-1) == default_data) {
1019 			sub_hdr->default_error = -1;
1020 #if !defined(_LP64)
1021 			sub_hdr->pad3_num = (pad_t)(~0);
1022 #endif
1023 		} else {
1024 			sub_hdr->default_error = 0;
1025 		}
1026 	} else {
1027 		if (num < entry_num) {
1028 			sub_hdr->default_error = 1;
1029 		} else {
1030 			sub_hdr->default_error = 2;
1031 		}
1032 	}
1033 
1034 	error_table = (table + (resultlen * entry_num));
1035 	if (-1 == sub_hdr->default_error) {
1036 		if (source->size != resultlen) {
1037 			itm_error(
1038 				gettext("\"default no_change_copy\" is "
1039 				"specified, but size does not match\n"));
1040 			exit(ITMC_STATUS_BT);
1041 		}
1042 
1043 		for (i = 0, j = 0;
1044 		    i < (entry_num);
1045 		    i++, j += resultlen) {
1046 			for (k = 0; k < resultlen; k++) {
1047 				*(table + j + k) =
1048 					(((source_start + i) >>
1049 					((resultlen - k - 1) * 8)) &
1050 					0x00ff);
1051 			}
1052 		}
1053 	} else if (0 == sub_hdr->default_error) {
1054 		error_table += resultlen;
1055 		if (default_data->size <= (sizeof (itm_place_t))) {
1056 			for (i = 0, j = 0;
1057 			    i < (entry_num + 1); /* last one is for default */
1058 			    i++, j += resultlen) {
1059 				(void) memcpy(table + j +
1060 				(resultlen - default_data->size),
1061 				(void *)(&(default_data->place.itm_64d)),
1062 				default_data->size);
1063 			}
1064 		} else {
1065 			for (i = 0, j = 0;
1066 			    i < (entry_num + 1); /* last one is for default */
1067 			    i++, j += resultlen) {
1068 				(void) memcpy(table + j +
1069 				(resultlen - default_data->size),
1070 				(void *)(default_data->place.itm_ptr),
1071 				default_data->size);
1072 			}
1073 		}
1074 	}
1075 	if (1 == sub_hdr->default_error) {
1076 		(void) memset(error_table, 1, entry_num);
1077 		for (i = 0; i < num; i++) {
1078 			if (0 == (*(tpp + i))->data1.size) {
1079 				continue; /* error sequence */
1080 			}
1081 			j = data_to_long(&((*(tpp + i))->data0)) -
1082 				source_start;
1083 			k = ((*(tpp + i))->range.size) == 0 ? j :
1084 			    data_to_long(&((*(tpp + i))->range)) -
1085 				source_start;
1086 			for (; j <= k; j++) {
1087 				*(error_table + j) = 0;
1088 			}
1089 		}
1090 	} else if (0 < error_count) {
1091 		(void) memset(error_table, 0, entry_num);
1092 		for (i = 0; i < num; i++) {
1093 			if (0 == (*(tpp + i))->data1.size) {
1094 				/* error sequence */
1095 				j = data_to_long(&((*(tpp + i))->data0)) -
1096 					source_start;
1097 				k = ((*(tpp + i))->range.size) == 0 ? j :
1098 				data_to_long(&((*(tpp + i))->range)) -
1099 				source_start;
1100 				for (; j <= k; j++) {
1101 					*(error_table + j) = 1;
1102 				}
1103 			}
1104 		}
1105 	}
1106 
1107 	p = malloc_vital(sizeof (uchar_t *) * resultlen);
1108 	for (i = 0; i < num; i++) {
1109 		j = data_to_long(&((*(tpp + i))->data0)) - source_start;
1110 		if (0 != (*(tpp + i))->range.size)
1111 			k = data_to_long(&((*(tpp + i))->range)) -
1112 			    source_start;
1113 		else
1114 			k = j;
1115 		(void) memset(p, 0, sizeof (uchar_t *) * resultlen);
1116 		(void) memcpy(p + (resultlen  - (*(tpp + i))->data1.size),
1117 			((caddr_t)NSPTR(&((*(tpp + i))->data1))),
1118 			(*(tpp + i))->data1.size);
1119 		map_range_make_result(table, j, k, p, resultlen);
1120 	}
1121 	free(p);
1122 
1123 	return	(header);
1124 }
1125 
1126 
1127 
1128 
1129 static itm_tbl_hdr_t *
1130 map_table_lookup_fixed(
1131 	itmc_data_pair_t	**tpp,
1132 	itm_size_t		num,
1133 	itm_data_t		*default_data,
1134 	long			resultlen,
1135 	itm_size_t		num2)
1136 {
1137 	itm_tbl_hdr_t		*header;
1138 	itm_map_lookup_hdr_t	*sub_hdr;
1139 	char			*table;
1140 	itm_size_t		table_size;
1141 	itm_size_t		j;
1142 	itm_size_t		i;
1143 	itm_size_t		k;
1144 	itm_size_t		h;
1145 	itm_data_t		*source;
1146 	uchar_t			*source_data;
1147 	uchar_t			*result_data;
1148 
1149 	TRACE_MESSAGE('m', ("map_table_lookup_fixed : %ld(%ld) 0x%lx\n",
1150 			num, num2, default_data));
1151 
1152 	source = &((*(tpp + 0))->data0);
1153 
1154 	table_size = ((sizeof (itm_tbl_hdr_t)) +
1155 			(sizeof (itm_map_idx_fix_hdr_t)) +
1156 			((source->size + 1 + resultlen) * num2));
1157 	if ((NULL != default_data) &&
1158 	    (((itm_data_t *)(-1)) != default_data)) {
1159 		table_size += (source->size + 1 + resultlen);
1160 	}
1161 	table_size = ITMROUNDUP(table_size);
1162 	header = malloc_vital(table_size);
1163 	sub_hdr = (itm_map_lookup_hdr_t *)(header + 1);
1164 	table = (char *)(sub_hdr + 1);
1165 
1166 	header->type = ITM_TBL_MAP_LOOKUP;
1167 	header->name.itm_ptr = 0;
1168 	header->size = table_size;
1169 	header->number = num2;
1170 	if (NULL != default_data) {
1171 		if ((itm_data_t *)(-1) == default_data) {
1172 #if !defined(_LP64)
1173 			sub_hdr->pad3_num = (pad_t)(~0);
1174 #endif
1175 			sub_hdr->default_error = -1;
1176 		} else {
1177 			sub_hdr->default_error = 0;
1178 		}
1179 	} else {
1180 		sub_hdr->default_error = 2;
1181 	}
1182 
1183 	sub_hdr->source_len = source->size;
1184 	sub_hdr->result_len = resultlen;
1185 
1186 	/* specified map */
1187 	source_data = malloc_vital(source->size);
1188 	result_data = malloc_vital(resultlen);
1189 	for (i = 0, j = 0; i < num; i++) {
1190 		(void) memcpy(table + j,
1191 			NSPTR(&((*(tpp + i))->data0)), source->size);
1192 		j += source->size;
1193 		if (0 == (*(tpp + i))->data1.size) {
1194 			*(table + j) = 1; /* specified error */
1195 			j += 1;
1196 		} else {
1197 			/* *(table + j) = 0; ** valid */
1198 			j += 1;
1199 			(void) memcpy(table + j +
1200 				(resultlen  - (*(tpp + i))->data1.size),
1201 				NSPTR(&((*(tpp + i))->data1)),
1202 				(*(tpp + i))->data1.size);
1203 		}
1204 		j += resultlen;
1205 
1206 		if ((*(tpp + i))->range.size != 0) {
1207 			(void) memcpy(source_data,
1208 				NSPTR(&((*(tpp + i))->data0)),
1209 				source->size);
1210 			(void) memset(result_data, 0, resultlen);
1211 			(void) memcpy(result_data +
1212 				(resultlen  - (*(tpp + i))->data1.size),
1213 				NSPTR(&((*(tpp + i))->data1)),
1214 				(*(tpp + i))->data1.size);
1215 			h = map_table_num_range((*(tpp + i)));
1216 			for (k = 0; k < h; k++) {
1217 				uchar_t		*dp;
1218 				itm_size_t	m;
1219 
1220 				for (m = 0,
1221 				    dp = (uchar_t *)
1222 				    (source_data + source->size - 1);
1223 				    m < source->size;
1224 				    m++, dp--) {
1225 					if (0xff != *dp) {
1226 						(*dp) += (char)1;
1227 						for (++dp; m > 0; m--, dp++) {
1228 							(*dp) = 0x00;
1229 						}
1230 						break;
1231 					}
1232 				}
1233 				(void) memcpy(table + j,
1234 					source_data, source->size);
1235 				j += source->size;
1236 
1237 				if (0 == (*(tpp + i))->data1.size) {
1238 					*(table + j) = 1; /* specified error */
1239 					j += 1;
1240 				} else {
1241 					/* *(table + j) = 0; ** valid */
1242 					j += 1;
1243 					for (m = 0, dp = (uchar_t *)
1244 					    (result_data + resultlen - 1);
1245 					    m < resultlen;
1246 					    m++, dp--) {
1247 						if (0xff != *dp) {
1248 							(*dp) += 1;
1249 							for (++dp;
1250 							    m > 0;
1251 							    m--, dp++) {
1252 								(*dp) = 0x00;
1253 							}
1254 							break;
1255 						}
1256 					}
1257 					(void) memcpy(table + j, result_data,
1258 						resultlen);
1259 				}
1260 				j += resultlen;
1261 			}
1262 		}
1263 	}
1264 	free(source_data);
1265 	free(result_data);
1266 
1267 	/* default */
1268 	if ((NULL != default_data) &&
1269 	    (((itm_data_t *)(-1)) != default_data)) {
1270 		(void) memset(table + j, 0, source->size + 1 + resultlen);
1271 		(void) memcpy(table + j + source->size + 1 +
1272 		(resultlen  - default_data->size),
1273 		NSPTR(default_data), default_data->size);
1274 	}
1275 	return	(header);
1276 }
1277 
1278 
1279 
1280 
1281 static itm_tbl_hdr_t *
1282 map_table_hash(
1283 	itmc_data_pair_t	**tpp,
1284 	itm_size_t		num,
1285 	itm_data_t		*default_data,
1286 	long			hash_factor,
1287 	long			resultlen,
1288 	itm_size_t		num2,
1289 	itm_num_t		error_count)
1290 {
1291 	itm_tbl_hdr_t		*header;
1292 	itm_map_hash_hdr_t	*sub_hdr;
1293 	itm_size_t		table_size;
1294 	char			*error_table;
1295 	char			*hash_table;
1296 	itm_size_t		hash_table_num;
1297 	char			*of_table;
1298 	itm_size_t		of_table_num;
1299 	itm_size_t		pair_size;
1300 	itm_size_t		i;
1301 	itm_size_t		j;
1302 	itm_size_t		k;
1303 	char			*p;
1304 	itm_data_t		*source;
1305 	long			hash_value;
1306 #if defined(DEBUG)
1307 	long			hash_none;
1308 	long			hash_one;
1309 	long			hash_conflict;
1310 #endif /* DEBUG */
1311 	uchar_t			*source_data;
1312 	uchar_t			*result_data;
1313 	uchar_t			*dp;
1314 	itm_size_t		m;
1315 	itm_size_t		n;
1316 	itm_size_t		h;
1317 
1318 	TRACE_MESSAGE('m', ("map_table_hash : %ld(%ld) 0x%lx\n",
1319 			num, num2, default_data));
1320 	source = &((*(tpp + 0))->data0);
1321 	pair_size = (source->size + 1 + resultlen);
1322 
1323 	if (100 <= hash_factor) {
1324 		hash_table_num = (num2 * (hash_factor / 100.0));
1325 	} else {
1326 		hash_table_num = (num2 * 2);
1327 	}
1328 	if (hash_table_num < 256) {
1329 		hash_table_num = 256;
1330 	}
1331 	source_data = malloc_vital(source->size);
1332 	result_data = malloc_vital(resultlen);
1333 
1334 	hash_table = malloc_vital(hash_table_num);
1335 	for (i = 0, of_table_num = 0; i < num; i++) {
1336 		hash_value =
1337 			hash(NSPTR(&((*(tpp + i))->data0)),
1338 				(*(tpp + i))->data0.size,
1339 				hash_table_num);
1340 		if (0 == *(hash_table + hash_value)) {
1341 			*(hash_table + hash_value) = 1;
1342 		} else {
1343 			*(hash_table + hash_value) = 2;
1344 			of_table_num += 1;
1345 		}
1346 
1347 		if ((*(tpp + i))->range.size != 0) {
1348 			(void) memcpy(source_data,
1349 				NSPTR(&((*(tpp + i))->data0)),
1350 				source->size);
1351 			h = map_table_num_range((*(tpp + i)));
1352 			for (n = 0; n < h; n++) {
1353 				for (m = 0,
1354 				    dp = (uchar_t *)
1355 				    (source_data + source->size - 1);
1356 				    m < source->size;
1357 				    m++, dp--) {
1358 					if (0xff != *dp) {
1359 						(*dp) += 1;
1360 						for (++dp; m > 0; m--, dp++) {
1361 							(*dp) = 0x00;
1362 						}
1363 						break;
1364 					}
1365 				}
1366 				hash_value =
1367 					hash((char *)source_data, source->size,
1368 						hash_table_num);
1369 
1370 				if (0 == *(hash_table + hash_value)) {
1371 					*(hash_table + hash_value) = 1;
1372 				} else {
1373 					*(hash_table + hash_value) = 2;
1374 					of_table_num += 1;
1375 				}
1376 			}
1377 		}
1378 	}
1379 
1380 #if defined(DEBUG)
1381 	if (TRACE('s')) {
1382 		hash_none = 0;
1383 		hash_one = 0;
1384 		hash_conflict = 0;
1385 		j = 0;
1386 		for (i = 0; i < hash_table_num; i++) {
1387 			if (2 == *(hash_table + i)) {
1388 				(void) putchar('2');
1389 				hash_conflict += 1;
1390 			} else if (1 == *(hash_table + i)) {
1391 				(void) putchar('1');
1392 				hash_one += 1;
1393 			} else if (0 == *(hash_table + i)) {
1394 				(void) putchar('-');
1395 				hash_none += 1;
1396 			} else {
1397 				(void) putchar('*');
1398 			}
1399 			if (63 <= j) {
1400 				j = 0;
1401 				(void) putchar('\n');
1402 			} else {
1403 				j += 1;
1404 			}
1405 		}
1406 		(void) putchar('\n');
1407 		(void) printf("null=%ld one=%ld conflict=%ld\n",
1408 			hash_none, hash_one, hash_conflict);
1409 	}
1410 #endif /* DEBUG */
1411 
1412 	free(hash_table);
1413 	table_size = ((sizeof (itm_tbl_hdr_t)) +
1414 			(sizeof (itm_map_hash_hdr_t)) +
1415 			(hash_table_num) +
1416 			(pair_size * hash_table_num) +
1417 			(pair_size * of_table_num));
1418 	if ((NULL != default_data) &&
1419 	    (((itm_data_t *)(-1)) != default_data)) {
1420 		table_size += pair_size;
1421 	}
1422 	table_size = ITMROUNDUP(table_size);
1423 	header = malloc_vital(table_size);
1424 	sub_hdr = (itm_map_hash_hdr_t *)(header + 1);
1425 	error_table = (char *)(sub_hdr + 1);
1426 	hash_table = error_table + hash_table_num;
1427 	of_table = hash_table + (pair_size * hash_table_num);
1428 
1429 	header->type = ITM_TBL_MAP_HASH;
1430 	header->name.itm_ptr = 0;
1431 	header->size = table_size;
1432 	header->number = num2;
1433 	if (NULL != default_data) {
1434 		if ((itm_data_t *)(-1) == default_data) {
1435 			sub_hdr->default_error = -1;
1436 #if !defined(_LP64)
1437 			sub_hdr->pad7_num = (pad_t)(~0);
1438 #endif
1439 		} else {
1440 			sub_hdr->default_error = 0;
1441 		}
1442 	} else {
1443 		sub_hdr->default_error = 2;
1444 	}
1445 
1446 	sub_hdr->source_len = source->size;
1447 	sub_hdr->result_len = resultlen;
1448 	sub_hdr->hash_tbl_size = (pair_size * hash_table_num);
1449 	sub_hdr->hash_tbl_num = hash_table_num;
1450 	sub_hdr->hash_of_size =
1451 		(pair_size * of_table_num);
1452 	sub_hdr->hash_of_num = of_table_num;
1453 	sub_hdr->error_num = error_count; /* > 0; so pad4 = 0 */
1454 
1455 	/* specified map */
1456 	for (i = 0, j = 0, k = 0; i < num; i++) {
1457 		hash_value =
1458 			hash(NSPTR(&((*(tpp + i))->data0)),
1459 				(*(tpp + i))->data0.size,
1460 				hash_table_num);
1461 		p = error_table + hash_value;
1462 		if (*p) {	/* conflict */
1463 			if (*p < 63) {
1464 				*p += 1;
1465 			}
1466 			p = of_table + k;
1467 			k += pair_size;
1468 		} else {
1469 			*p = 1;
1470 			p = hash_table + (pair_size * hash_value);
1471 		}
1472 
1473 		(void) memcpy(p, NSPTR(&((*(tpp + i))->data0)), source->size);
1474 		p += source->size;
1475 		if (0 == (*(tpp + i))->data1.size) {
1476 			(*p) = 1; /* specified error */
1477 			p++;
1478 		} else {
1479 			/* (*p) = 0; ** valid */
1480 			p++;
1481 			(void) memset(p, 0,
1482 				(resultlen - (*(tpp + i))->data1.size));
1483 			(void) memcpy(p +
1484 				(resultlen - (*(tpp + i))->data1.size),
1485 				NSPTR(&((*(tpp + i))->data1)),
1486 			(*(tpp + i))->data1.size);
1487 		}
1488 
1489 		if ((*(tpp + i))->range.size != 0) {
1490 			(void) memcpy(source_data,
1491 				NSPTR(&((*(tpp + i))->data0)),
1492 				source->size);
1493 			(void) memset(result_data, 0,
1494 				(resultlen  - (*(tpp + i))->data1.size));
1495 			(void) memcpy(result_data +
1496 				(resultlen  - (*(tpp + i))->data1.size),
1497 				NSPTR(&((*(tpp + i))->data1)),
1498 				(*(tpp + i))->data1.size);
1499 			h = map_table_num_range((*(tpp + i)));
1500 			for (n = 0; n < h; n++) {
1501 				for (m = 0,
1502 				    dp = (uchar_t *)
1503 				    (source_data + source->size - 1);
1504 				    m < source->size;
1505 				    m++, dp--) {
1506 					if (0xff != *dp) {
1507 						(*dp) += 1;
1508 						for (++dp; m > 0; m--, dp++) {
1509 							(*dp) = 0x00;
1510 						}
1511 						break;
1512 					}
1513 				}
1514 
1515 				hash_value = hash((char *)source_data,
1516 						source->size,
1517 						hash_table_num);
1518 				p = error_table + hash_value;
1519 				if (*p) {	/* conflict */
1520 					if (*p < 63) {
1521 						*p += 1;
1522 					}
1523 					p = of_table + k;
1524 					k += pair_size;
1525 				} else {
1526 					*p = 1;
1527 					p = hash_table +
1528 						(pair_size * hash_value);
1529 				}
1530 				(void) memcpy(p, source_data, source->size);
1531 				p += source->size;
1532 
1533 				if (0 == (*(tpp + i))->data1.size) {
1534 					(*p) = 1; /* specified error */
1535 					p += 1;
1536 				} else {
1537 					/* (*p) = 0; ** valid */
1538 					p += 1;
1539 					for (m = 0, dp = (uchar_t *)
1540 					    (result_data + resultlen - 1);
1541 					    m < resultlen;
1542 					    m++, dp--) {
1543 						if (0xff != *dp) {
1544 							(*dp) += 1;
1545 							for (++dp; m > 0;
1546 							    m--, dp++) {
1547 								(*dp) = 0x00;
1548 							}
1549 							break;
1550 						}
1551 					}
1552 					(void) memcpy(p,
1553 						result_data, resultlen);
1554 				}
1555 			}
1556 		}
1557 	}
1558 	free(source_data);
1559 	free(result_data);
1560 
1561 	/* default */
1562 	if ((NULL != default_data) &&
1563 	    (((itm_data_t *)(-1)) != default_data)) {
1564 		j = ((pair_size * hash_table_num) +
1565 			(pair_size * of_table_num));
1566 		(void) memcpy(hash_table + j + (resultlen - default_data->size),
1567 			NSPTR(default_data), default_data->size);
1568 	}
1569 #if defined(ENABLE_TRACE)
1570 	for (i = 0, p = of_table; i < of_table_num; i++, p += 5) {
1571 		(void) printf("0x%02x%02x%02x%02x	0x%02x\n",
1572 			((unsigned char)(*(p + 0))),
1573 			((unsigned char)(*(p + 1))),
1574 			((unsigned char)(*(p + 2))),
1575 			((unsigned char)(*(p + 3))),
1576 			((unsigned char)(*(p + 4))));
1577 	}
1578 #endif
1579 	return	(header);
1580 }
1581 
1582 
1583 
1584 
1585 static itm_tbl_hdr_t *
1586 map_table_dense_encoding(
1587 	itmc_data_pair_t	**tpp,
1588 	itm_size_t		num,
1589 	itm_data_t		*default_data,
1590 	unsigned long		entry_num,
1591 	unsigned char		*byte_seq_min,
1592 	unsigned char		*byte_seq_max,
1593 	long			resultlen,
1594 	itm_num_t		error_count)
1595 {
1596 
1597 	itm_tbl_hdr_t		*header;
1598 	itm_map_dense_enc_hdr_t	*sub_hdr;
1599 	char			*table;
1600 	char			*error_table;
1601 	itm_size_t		table_size;
1602 	itm_size_t		j;
1603 	itm_size_t		i;
1604 	itm_size_t		k;
1605 	char			*p;
1606 	itm_data_t		*source;
1607 	unsigned char		*byte_seq_def;
1608 
1609 	TRACE_MESSAGE('m', ("map_table_dense_encoding : %ld\n", num));
1610 
1611 	source = &((*(tpp + 0))->data0);
1612 
1613 
1614 	table_size = ((sizeof (itm_tbl_hdr_t)) +
1615 			(sizeof (itm_map_dense_enc_hdr_t)) +
1616 			(source->size + source->size) +
1617 			(resultlen * entry_num));
1618 	if (0 < error_count) {
1619 		table_size += entry_num;
1620 	}
1621 	if (NULL == default_data) {
1622 		if ((num < entry_num) ||
1623 		    (error_count <= 0)) {
1624 			table_size += entry_num;
1625 		}
1626 	} else if ((itm_data_t *)(-1) != default_data) {
1627 		table_size += resultlen;
1628 	}
1629 
1630 	table_size = ITMROUNDUP(table_size);
1631 	header = malloc_vital(table_size);
1632 	sub_hdr = (itm_map_dense_enc_hdr_t *)(header + 1);
1633 	table = (char *)(sub_hdr + 1) + source->size + source->size;
1634 
1635 	header->type = ITM_TBL_MAP_DENSE_ENC;
1636 	header->name.itm_ptr = 0;
1637 	header->size = table_size;
1638 	header->number = entry_num;
1639 
1640 	sub_hdr->source_len = (*tpp)->data0.size;
1641 	sub_hdr->result_len = resultlen;
1642 	sub_hdr->error_num = error_count; /* > 0; so pad4 = 0 */
1643 
1644 	if (NULL != default_data) {
1645 		if ((itm_data_t *)(-1) == default_data) {
1646 			sub_hdr->default_error = -1;
1647 #if !defined(_LP64)
1648 			sub_hdr->pad3_num = (pad_t)(~0);
1649 #endif
1650 
1651 		} else {
1652 			sub_hdr->default_error = 0;
1653 		}
1654 	} else {
1655 		if (num < entry_num) {
1656 			sub_hdr->default_error = 1;
1657 		} else {
1658 			sub_hdr->default_error = 2;
1659 		}
1660 	}
1661 
1662 	(void) memcpy((char *)(sub_hdr + 1), byte_seq_min, source->size);
1663 	(void) memcpy((char *)(sub_hdr + 1) + source->size,
1664 		byte_seq_max, source->size);
1665 
1666 	if (-1 == sub_hdr->default_error) {
1667 		byte_seq_def = malloc_vital((sizeof (unsigned char *)) *
1668 					    resultlen);
1669 		if (source->size != resultlen) {
1670 			itm_error(
1671 				gettext("\"default no_change_copy\" is "
1672 				"specified, but size does not match\n"));
1673 			exit(ITMC_STATUS_BT);
1674 		}
1675 		put_dense_encoding_default(
1676 			table, byte_seq_min, byte_seq_max, byte_seq_def,
1677 			resultlen - 1, 0, 0);
1678 		free(byte_seq_def);
1679 	} else if (0 == sub_hdr->default_error) {
1680 		if (default_data->size <= (sizeof (itm_place_t))) {
1681 			for (i = 0, j = 0;
1682 			    i < (entry_num + 1); /* 1:default data */
1683 			    i++, j += resultlen) {
1684 				(void) memcpy(table + j +
1685 				(resultlen - default_data->size),
1686 				(void *)(&(default_data->place.itm_64d)),
1687 				default_data->size);
1688 			}
1689 		} else {
1690 			for (i = 0, j = 0;
1691 			    i < (entry_num + 1);  /* 1:default data */
1692 			    i++, j += resultlen) {
1693 				(void) memcpy(table + j +
1694 				(resultlen - default_data->size),
1695 				(void *)(default_data->place.itm_ptr),
1696 				default_data->size);
1697 			}
1698 		}
1699 	}
1700 	if (1 == sub_hdr->default_error) {
1701 		(void) memset(table + (resultlen * entry_num), 1, entry_num);
1702 		error_table = (table + (resultlen * entry_num));
1703 		for (i = 0; i < num; i++) {
1704 			if (0 == (*(tpp + i))->data1.size) {
1705 				continue; /* error sequence */
1706 			}
1707 			j = hash_dense_encoding(NSPTR(&((*(tpp + i))->data0)),
1708 						(*(tpp + i))->data0.size,
1709 						byte_seq_min, byte_seq_max);
1710 			k = ((*(tpp + i))->range.size) == 0 ? j :
1711 			    hash_dense_encoding(NSPTR(&((*(tpp + i))->range)),
1712 						(*(tpp + i))->data0.size,
1713 						byte_seq_min, byte_seq_max);
1714 			for (; j <= k; j++) {
1715 				*(error_table + j) = 0;
1716 			}
1717 		}
1718 	} else if (0 < error_count) {
1719 		error_table = (table + (resultlen * entry_num));
1720 		if (0 == sub_hdr->default_error) {
1721 			error_table += resultlen;
1722 		}
1723 		(void) memset(error_table, 0, entry_num);
1724 		for (i = 0; i < num; i++) {
1725 			if (0 == (*(tpp + i))->data1.size) {
1726 				j = hash_dense_encoding(
1727 					NSPTR(&((*(tpp + i))->data0)),
1728 						(*(tpp + i))->data0.size,
1729 						byte_seq_min, byte_seq_max);
1730 				k = ((*(tpp + i))->range.size) == 0 ? j :
1731 					hash_dense_encoding(
1732 					NSPTR(&((*(tpp + i))->range)),
1733 					(*(tpp + i))->data0.size,
1734 					byte_seq_min, byte_seq_max);
1735 				for (; j <= k; j++) {
1736 					*(error_table + j) = 1; /* specified */
1737 				}
1738 			}
1739 		}
1740 	}
1741 
1742 
1743 	p = malloc_vital(resultlen);
1744 	for (i = 0; i < num; i++) {
1745 		j = hash_dense_encoding(NSPTR(&((*(tpp + i))->data0)),
1746 					(*(tpp + i))->data0.size,
1747 					byte_seq_min, byte_seq_max);
1748 
1749 		if (0 != (*(tpp + i))->range.size)
1750 			k = hash_dense_encoding(
1751 						NSPTR(&((*(tpp + i))->range)),
1752 						(*(tpp + i))->range.size,
1753 						byte_seq_min, byte_seq_max);
1754 		else
1755 			k = j;
1756 		(void) memset(p, 0, (resultlen	 - (*(tpp + i))->data1.size));
1757 		(void) memcpy(p + (resultlen  - (*(tpp + i))->data1.size),
1758 			((caddr_t)NSPTR(&((*(tpp + i))->data1))),
1759 			(*(tpp + i))->data1.size);
1760 		map_range_make_result(table, j, k, p, resultlen);
1761 	}
1762 	free(p);
1763 
1764 	return	(header);
1765 }
1766 
1767 
1768 static void
1769 put_dense_encoding_default(
1770 	char	*table,
1771 	unsigned char	*byte_seq_min,
1772 	unsigned char	*byte_seq_max,
1773 	unsigned char	*byte_seq_def,
1774 	long		pos_max,
1775 	long		position,
1776 	long		dense_encoded_value)
1777 {
1778 	uchar_t	i;
1779 
1780 	if (position < pos_max) {
1781 		for (i = *(byte_seq_min + position);
1782 		    i <= *(byte_seq_max + position); i++) {
1783 			*(byte_seq_def + position) = i;
1784 			put_dense_encoding_default(
1785 				table,
1786 				byte_seq_min, byte_seq_max,
1787 				byte_seq_def,
1788 				pos_max, position + 1,
1789 				((dense_encoded_value + i) *
1790 				(*(byte_seq_max + position) -
1791 				*(byte_seq_min + position) + 1)));
1792 		}
1793 		return;
1794 	}
1795 
1796 	for (i = *(byte_seq_min + position);
1797 	    i <= *(byte_seq_max + position); i++) {
1798 		*(byte_seq_def + position) = i;
1799 		(void) memcpy(table +
1800 			((pos_max + 1) * (dense_encoded_value + i - 1)),
1801 			byte_seq_def, pos_max + 1);
1802 	}
1803 }
1804 
1805 
1806 char *
1807 dense_enc_index_to_byte_seq(
1808 	long		value,
1809 	long		length,
1810 	unsigned char	*byte_seq_min,
1811 	unsigned char	*byte_seq_max)
1812 {
1813 	static char	*buf;
1814 	static long	buf_len;
1815 	char		*p;
1816 	int		i;
1817 	int		l;
1818 	int		residue;
1819 
1820 	if (buf_len < (2 + (length * 2) + 1)) {
1821 		free(buf);
1822 		buf_len = (2 + (length * 2) + 1) + 16;
1823 		buf = malloc_vital(buf_len);
1824 	}
1825 
1826 	*(buf + (length * 2)) = '\0';
1827 	*(buf + 0) = '0';
1828 	*(buf + 1) = 'x';
1829 	p = buf + 2;
1830 	for (i = length - 1; 0 <= i; --i) {
1831 		residue = value % (*(byte_seq_max + i) -
1832 					*(byte_seq_min + i) + 1);
1833 		value /= (*(byte_seq_max + i) -
1834 				*(byte_seq_min + i) + 1);
1835 
1836 		residue += *(byte_seq_min + i);
1837 		l = ((0xf0 & residue) >> 4);
1838 		if (l < 10) {
1839 			*(p + (i * 2)) = ('0' + l);
1840 		} else {
1841 			*(p + (i * 2)) = ('a' + l - 10);
1842 		}
1843 		l = (0x0f & residue);
1844 		if (l < 10) {
1845 			*(p + (i * 2) + 1) = ('0' + l);
1846 		} else {
1847 			*(p + (i * 2) + 1) = ('a' + l - 10);
1848 		}
1849 	}
1850 	return	(buf);
1851 }
1852 
1853 
1854 itm_tbl_hdr_t *
1855 map_table_lookup_var()
1856 {
1857 	itm_error(gettext(
1858 		"lenghth of all source sequences must be the same\n"));
1859 	error_deferred += 1;
1860 	return	(NULL);
1861 }
1862 
1863 
1864 
1865 static void
1866 map_range_adjust_byte_seq(
1867 	unsigned char		*byte_seq_min,
1868 	unsigned char		*byte_seq_max,
1869 	long			source_len,
1870 	itmc_data_pair_t	*pair)
1871 {
1872 	unsigned char		*p, *p2;
1873 	int			i;
1874 	int			flag;
1875 
1876 	p  = (unsigned char *)(NSPTR(&((pair)->data0)));
1877 	p2 = (unsigned char *)(NSPTR(&((pair)->range)));
1878 	flag = 0;
1879 	for (i = 0; i < source_len; i++) {
1880 		if (flag != 0) {
1881 			break;
1882 		}
1883 		if (*(p + i) != *(p2 + i))
1884 			flag = 1;
1885 		if (*(p + i) < *(byte_seq_min + i)) {
1886 			*(byte_seq_min + i) = *(p + i);
1887 		}
1888 		if (*(byte_seq_max + i) < *(p2 + i)) {
1889 			*(byte_seq_max + i) = *(p2 + i);
1890 		}
1891 	}
1892 	for (; i < source_len; i++) {
1893 		*(byte_seq_min + i) = 0x00;
1894 		*(byte_seq_max + i) = 0xff;
1895 	}
1896 }
1897 
1898 /*
1899  *	result value + (source range value - source base value)
1900  *	and just caluculate its length
1901  */
1902 static size_t
1903 map_table_resultlen(itmc_map_t		*ml)
1904 {
1905 	size_t	j;
1906 	size_t	len;
1907 	int	m;
1908 	uchar_t *c1;
1909 	uchar_t *c2;
1910 	uchar_t *c3;
1911 
1912 	j = ml->data_pair.data0.size;
1913 	if (j < ml->data_pair.data1.size) j = ml->data_pair.data1.size;
1914 	if (j < ml->data_pair.range.size) j = ml->data_pair.range.size;
1915 	c1 = (uchar_t *)(NSPTR(&((ml->data_pair).data0))) +
1916 			ml->data_pair.data0.size - 1;
1917 	c2 = (uchar_t *)(NSPTR(&((ml->data_pair).data1))) +
1918 			ml->data_pair.data1.size - 1;
1919 	c3 = (uchar_t *)(NSPTR(&((ml->data_pair.range)))) +
1920 			ml->data_pair.range.size - 1;
1921 	m = 0;
1922 	for (len = 0; len < j; len++, c1--, c2--, c3--) {
1923 		if (len < ml->data_pair.data0.size) m -= *c1;
1924 		if (len < ml->data_pair.data1.size) m += *c2;
1925 		if (len < ml->data_pair.range.size) m += *c3;
1926 		m >>= 8;
1927 	}
1928 	if (m > 0) {
1929 		len += 1;
1930 	}
1931 	TRACE_MESSAGE('g', ("map_table_resutlen: source(0x%s..0x%s), "
1932 			"result(0x%s.... len= %ld)\n",
1933 			data_to_hexadecimal(&(ml->data_pair.data0)),
1934 			data_to_hexadecimal(&(ml->data_pair.range)),
1935 			data_to_hexadecimal(&(ml->data_pair.data1)),
1936 			len));
1937 	return (len);
1938 }
1939 
1940 /*
1941  *
1942  */
1943 static void
1944 map_range_make_result(
1945 	char		*table,
1946 	itm_size_t	range_start,
1947 	itm_size_t	range_end,
1948 	char		*result_data,
1949 	itm_size_t	result_size)
1950 {
1951 	itm_size_t	i;
1952 	itm_size_t	j;
1953 	itm_size_t	p;
1954 	uchar_t		*dp; /* unsigned for ++ operation */
1955 
1956 	for (i = range_start, p = i * result_size;
1957 	    i <= range_end; i++, p += result_size) {
1958 		(void) memcpy(table + p, result_data, result_size);
1959 		for (j = 0, dp = (uchar_t *)(result_data + result_size - 1);
1960 		    j < result_size;
1961 		    j++, dp--) {
1962 			if (0xff != *dp) {
1963 				(*dp) += 1;
1964 				for (++dp; j > 0; j--, dp++) {
1965 					(*dp) = 0x00;
1966 				}
1967 				break;
1968 			}
1969 		}
1970 	}
1971 }
1972 
1973 /*
1974  *
1975  */
1976 static size_t
1977 map_table_num_range(itmc_data_pair_t	*pair)
1978 {
1979 	size_t		i, j;
1980 	itm_num_t	num;
1981 	itm_num_t	num2;
1982 	uchar_t		*c1;
1983 	uchar_t		*c2;
1984 
1985 	assert(0 < pair->range.size);
1986 	j = pair->data0.size;
1987 	if (j < pair->range.size)
1988 		j = pair->range.size;
1989 	c1 = ((uchar_t *)(NSPTR(&(pair->data0)))) + pair->data0.size - 1;
1990 	c2 = ((uchar_t *)(NSPTR(&(pair->range)))) + pair->range.size - 1;
1991 	num = 0;
1992 	for (i = 0; i < j; i++, c1--, c2--) {
1993 		if (i < pair->range.size) num2 = *c2;
1994 		if (i < pair->data0.size) num2 -= *c1;
1995 		TRACE_MESSAGE('G', (" num += %d(=%d-%d)\n ",
1996 				*c2 - *c1, *c2, *c1));
1997 		num2 <<= (i*8);
1998 		num += num2;
1999 	}
2000 	TRACE_MESSAGE('g', ("map_table_num_range: source(0x%s..0x%s), "
2001 			"num= %ld\n",
2002 			data_to_hexadecimal(&(pair->data0)),
2003 			data_to_hexadecimal(&(pair->range)),
2004 			num));
2005 	return (num);
2006 }
2007 
2008 /*
2009  *
2010  */
2011 itmc_map_t *
2012 map_list_append(itmc_map_t	*map_list, itmc_map_t	*map_pair)
2013 {
2014 	if (0 == map_pair) {
2015 		return	(map_list);
2016 	}
2017 
2018 	map_pair->next = NULL;
2019 	map_pair->last = map_pair;
2020 
2021 	if (map_list) {
2022 		map_list->last->next = map_pair;
2023 		map_list->last = map_pair;
2024 		return	(map_list);
2025 	} else {
2026 		return	(map_pair);
2027 	}
2028 }
2029 
2030 
2031 
2032 itmc_obj_t *
2033 op_self(itm_op_type_t type)
2034 {
2035 	return (op_unit(type, NULL, 0, NULL, 0, NULL, 0));
2036 }
2037 
2038 
2039 itmc_obj_t *
2040 op_unary(itm_op_type_t type, void	*data, size_t data_size)
2041 {
2042 	return (op_unit(type, data, data_size, NULL, 0, NULL, 0));
2043 }
2044 
2045 itmc_obj_t *
2046 op_unit(itm_op_type_t	type,
2047 	void	*data0, size_t data0_size,
2048 	void	*data1, size_t data1_size,
2049 	void	*data2, size_t data2_size)
2050 {
2051 	itm_op_t	*op;
2052 	itmc_obj_t	*obj;
2053 
2054 	op = malloc_vital(sizeof (itm_op_t));
2055 	op->type = type;
2056 	op->data.operand[0].itm_ptr = (itm_place2_t)(data0);
2057 	op->data.operand[1].itm_ptr = (itm_place2_t)(data1);
2058 	op->data.operand[2].itm_ptr = (itm_place2_t)(data2);
2059 
2060 	obj = malloc_vital(sizeof (itmc_obj_t));
2061 	obj->type = ITMC_OBJ_OP;
2062 	obj->name = NULL;
2063 	obj->obj = op;
2064 	obj->ref[0] = obj->ref[1] = obj->ref[2] = NULL;
2065 	if (NULL != data0) {
2066 		obj->ref[0] = obj_register(ITMC_OBJ_EXPR, NULL,
2067 						data0, data0_size,
2068 						&(op->data.operand[0]),
2069 						OBJ_REG_TAIL);
2070 	}
2071 	if (NULL != data1) {
2072 		obj->ref[1] = obj_register(ITMC_OBJ_EXPR, NULL,
2073 						data1, data1_size,
2074 						&(op->data.operand[1]),
2075 						OBJ_REG_TAIL);
2076 	}
2077 	if (NULL != data2) {
2078 		obj->ref[2] = obj_register(ITMC_OBJ_EXPR, NULL,
2079 						data2, data2_size,
2080 						&(op->data.operand[2]),
2081 						OBJ_REG_TAIL);
2082 	}
2083 	obj->next = NULL;
2084 	obj->last = NULL;
2085 
2086 	return	(obj);
2087 }
2088 
2089 
2090 itmc_obj_t *
2091 op_self_num(itm_op_type_t type, itm_num_t data)
2092 {
2093 	itm_op_t	*op;
2094 	itmc_obj_t	*obj;
2095 
2096 	op = malloc_vital(sizeof (itm_op_t));
2097 	op->type = type;
2098 	op->data.itm_opnum = data;
2099 #if !defined(_LP64)
2100 	op->data.itm_oppad = (data < 0) ? (pad_t)(~0) : 0;
2101 #endif
2102 	obj = malloc_vital(sizeof (itmc_obj_t));
2103 	obj->type = ITMC_OBJ_OP;
2104 	obj->name = NULL;
2105 	obj->obj = op;
2106 	obj->ref[0] = obj->ref[1] = obj->ref[2] = NULL;
2107 
2108 	return	(obj);
2109 }
2110 
2111 
2112 itm_expr_t *
2113 expr_self_num(itm_expr_type_t type, itm_num_t data)
2114 {
2115 	itm_expr_t	*expr;
2116 
2117 	expr = malloc_vital(sizeof (itm_expr_t));
2118 	expr->type = type;
2119 	expr->data.itm_exnum = data;
2120 #if !defined(_LP64)
2121 	expr->data.itm_expad = (data < 0) ? (pad_t)(~0) : 0;
2122 #endif
2123 	return	(expr);
2124 }
2125 
2126 
2127 itm_expr_t *
2128 expr_self(itm_expr_type_t type, itm_data_t	*data)
2129 {
2130 	itm_expr_t	*expr;
2131 	itmc_name_t	*name;
2132 
2133 	expr = malloc_vital(sizeof (itm_expr_t));
2134 	expr->type = type;
2135 	if (NULL == data) {
2136 		expr->data.value.size = 0;
2137 		expr->data.value.place.itm_ptr = 0;
2138 	} else {
2139 		expr->data.value = *(data);
2140 	}
2141 
2142 	switch (type) {
2143 	case ITM_EXPR_NAME: /* register */
2144 		name = name_lookup(data, ITMC_OBJ_REGISTER);
2145 		if (&name_lookup_error == name) {
2146 			return	(NULL);
2147 		} else if (NULL == name) {
2148 			if (reg_id >= MAXREGID) {
2149 			itm_error(
2150 				gettext("more than %d variables are used\n"),
2151 				MAXREGID);
2152 				exit(ITMC_STATUS_BT2);
2153 			}
2154 			name = name_register(data, ITMC_OBJ_REGISTER, NULL);
2155 			name->reg_id = (reg_id++);
2156 		}
2157 		expr->type = ITM_EXPR_REG;
2158 		expr->data.itm_exnum = name->reg_id;
2159 #if !defined(_LP64)
2160 		expr->data.itm_expad =
2161 			(expr->data.itm_exnum < 0) ? (pad_t)(~0) : 0;
2162 #endif
2163 		break;
2164 	case ITM_EXPR_SEQ:
2165 		if ((sizeof (itm_place_t)) < data->size) {
2166 			(void) obj_register(ITMC_OBJ_DATA, NULL,
2167 				(void *)(data->place.itm_ptr), data->size,
2168 				&(expr->data.value.place), OBJ_REG_TAIL);
2169 		}
2170 		break;
2171 	}
2172 	return	(expr);
2173 }
2174 
2175 
2176 itm_expr_t *
2177 expr_unary(itm_expr_type_t type, itm_expr_t *data0)
2178 {
2179 	itm_expr_t	*expr;
2180 
2181 	expr = malloc_vital(sizeof (itm_expr_t));
2182 	expr->type = type;
2183 	expr->data.operand[0].itm_ptr = (itm_place2_t)(data0);
2184 	(void) obj_register(ITMC_OBJ_EXPR, NULL,
2185 			data0, sizeof (itm_expr_t),
2186 			&(expr->data.operand[0]), OBJ_REG_TAIL);
2187 
2188 	return	(expr);
2189 }
2190 
2191 
2192 itm_expr_t *
2193 expr_binary(itm_expr_type_t type,
2194 	    itm_expr_t		*data0, itm_expr_t	*data1)
2195 {
2196 	itm_expr_t	*expr;
2197 	itm_num_t	num;
2198 	unsigned char	*p;
2199 	int		i;
2200 
2201 	expr = malloc_vital(sizeof (itm_expr_t));
2202 	expr->type = type;
2203 
2204 	if (ITM_EXPR_SEQ == data0->type) {
2205 		p = (unsigned char *)NSPTR(&(data0->data.value));
2206 		for (i = 0, num = 0; i < data0->data.value.size; i++, p++) {
2207 			num = ((num << 8) | *p);
2208 		}
2209 		data0 = expr_self_num(ITM_EXPR_INT, num);
2210 	}
2211 	if (ITM_EXPR_SEQ == data1->type) {
2212 		p = (unsigned char *)NSPTR(&(data1->data.value));
2213 		for (i = 0, num = 0; i < data1->data.value.size; i++, p++) {
2214 			num = ((num << 8) | *p);
2215 		}
2216 		data1 = expr_self_num(ITM_EXPR_INT, num);
2217 	}
2218 
2219 	expr->data.operand[0].itm_ptr = (itm_place2_t)(data0);
2220 	expr->data.operand[1].itm_ptr = (itm_place2_t)(data1);
2221 
2222 	(void) obj_register(ITMC_OBJ_EXPR, NULL,
2223 			data0, sizeof (itm_expr_t),
2224 			&(expr->data.operand[0]), OBJ_REG_TAIL);
2225 	(void) obj_register(ITMC_OBJ_EXPR, NULL,
2226 			data1, sizeof (itm_expr_t),
2227 			&(expr->data.operand[1]), OBJ_REG_TAIL);
2228 
2229 	return	(expr);
2230 }
2231 
2232 
2233 itm_expr_t *
2234 expr_binary2(itm_expr_type_t type,
2235 		itm_expr_t *data0, itm_expr_t *data1)
2236 {
2237 	itm_expr_t	*expr;
2238 	itm_num_t	num;
2239 	unsigned char	*p;
2240 	int		i;
2241 
2242 	if ((NULL == data0) || (NULL == data1)) {
2243 		return (NULL);
2244 	}
2245 	expr = malloc_vital(sizeof (itm_expr_t));
2246 	expr->type = type;
2247 
2248 	switch (data0->type) {
2249 	case ITM_EXPR_SEQ:
2250 		p = (unsigned char *)NSPTR(&(data0->data.value));
2251 		for (i = 0, num = 0; i < data0->data.value.size; i++, p++) {
2252 			num = ((num << 8) | *p);
2253 		}
2254 		data0 = expr_self_num(ITM_EXPR_INT, num);
2255 		expr->data.operand[0].itm_ptr = (itm_place2_t)(data0);
2256 		(void) obj_register(ITMC_OBJ_EXPR, NULL,
2257 				data0, sizeof (itm_expr_t),
2258 				&(expr->data.operand[0]), OBJ_REG_TAIL);
2259 		break;
2260 	case ITM_EXPR_INT:
2261 	case ITM_EXPR_REG:
2262 	case ITM_EXPR_IN_VECTOR_D:
2263 		expr->data.operand[0] = data0->data.operand[0];
2264 		break;
2265 	default:
2266 		expr->data.operand[0].itm_ptr = (itm_place2_t)(data0);
2267 		(void) obj_register(ITMC_OBJ_EXPR, NULL,
2268 				data0, sizeof (itm_expr_t),
2269 				&(expr->data.operand[0]), OBJ_REG_TAIL);
2270 		break;
2271 	}
2272 
2273 	switch (data1->type) {
2274 	case ITM_EXPR_SEQ:
2275 		p = (unsigned char *)NSPTR(&(data1->data.value));
2276 		for (i = 0, num = 0; i < data1->data.value.size; i++, p++) {
2277 			num = ((num << 8) | *p);
2278 		}
2279 		data1 = expr_self_num(ITM_EXPR_INT, num);
2280 		expr->data.operand[1].itm_ptr = (itm_place2_t)(data1);
2281 		(void) obj_register(ITMC_OBJ_EXPR, NULL,
2282 				data1, sizeof (itm_expr_t),
2283 				&(expr->data.operand[1]), OBJ_REG_TAIL);
2284 		break;
2285 	case ITM_EXPR_INT:
2286 	case ITM_EXPR_REG:
2287 	case ITM_EXPR_IN_VECTOR_D:
2288 		expr->data.operand[1] = data1->data.operand[0];
2289 		break;
2290 	default:
2291 		expr->data.operand[1].itm_ptr = (itm_place2_t)(data1);
2292 		(void) obj_register(ITMC_OBJ_EXPR, NULL,
2293 				data1, sizeof (itm_expr_t),
2294 				&(expr->data.operand[1]), OBJ_REG_TAIL);
2295 		break;
2296 	}
2297 	return	(expr);
2298 }
2299 
2300 
2301 itm_expr_t *
2302 expr_assign(itm_expr_type_t type,
2303 	    itm_data_t		*data0, itm_expr_t	*data1)
2304 {
2305 	itm_expr_t	*expr;
2306 	itmc_name_t	*name;
2307 
2308 	expr = malloc_vital(sizeof (itm_expr_t));
2309 	expr->type = type;
2310 	expr->data.operand[1].itm_ptr = (itm_place2_t)(data1);
2311 
2312 	name = name_lookup(data0, ITMC_OBJ_REGISTER);
2313 	if (&name_lookup_error == name) {
2314 		free(expr);
2315 		exit(ITMC_STATUS_BT);
2316 	} else if (NULL == name) {
2317 		name = name_register(data0, ITMC_OBJ_REGISTER, NULL);
2318 		name->reg_id = (reg_id++);
2319 	}
2320 	expr->data.operand[0].itm_ptr = name->reg_id;
2321 
2322 	(void) obj_register(ITMC_OBJ_EXPR, NULL,
2323 			data1, sizeof (itm_expr_t),
2324 			&(expr->data.operand[1]), OBJ_REG_TAIL);
2325 	return	(expr);
2326 }
2327 
2328 
2329 itm_expr_t *
2330 expr_seq_to_int(itm_expr_t	*expr)
2331 {
2332 	itm_num_t	num;
2333 	unsigned char	*p;
2334 	int		i;
2335 
2336 	if (ITM_EXPR_SEQ == expr->type) {
2337 		if ((sizeof (itm_place_t)) < expr->data.value.size) {
2338 			p = (unsigned char *)(expr->data.value.place.itm_ptr);
2339 		} else {
2340 			p = (unsigned char *)&(expr->data.value.place.itm_64d);
2341 		}
2342 		for (i = 0, num = 0;
2343 		    i < expr->data.value.size;
2344 		    i++, p++) {
2345 			num = ((num << 8) | *p);
2346 		}
2347 		free(expr);
2348 		expr = expr_self_num(ITM_EXPR_INT, num);
2349 	}
2350 	return	(expr);
2351 }
2352 
2353 
2354 itmc_name_t *
2355 name_lookup(itm_data_t		*name, itm_type_t type)
2356 {
2357 	itmc_name_t	*p;
2358 
2359 	TRACE_MESSAGE('N', ("name_lookup\t: \"%-16s\" %2ld %2ld %2ld\n",
2360 			name_to_str(name), name->size, type, name_id));
2361 
2362 	if (0 == name->size)
2363 		return	(NULL);
2364 	for (p = name_first; p; p = p->next) {
2365 		if ((name->size != p->name.size) ||
2366 		    (memcmp(NSPTR(name), NSPTR(&(p->name)), name->size))) {
2367 			continue;
2368 		}
2369 		if ((type != p->type) &&
2370 		    (((ITMC_OBJ_ACTION	!= type) &&
2371 		    (ITMC_OBJ_ACTION	!= p->type)) ||
2372 		    ((ITMC_OBJ_ACTION	== type) &&
2373 		    (ITMC_OBJ_DIREC	!= p->type) &&
2374 		    (ITMC_OBJ_OP	!= p->type) &&
2375 		    (ITMC_OBJ_MAP	!= p->type)) ||
2376 		    ((ITMC_OBJ_ACTION	== p->type) &&
2377 		    (ITMC_OBJ_DIREC	!= type) &&
2378 		    (ITMC_OBJ_OP	!= type) &&
2379 		    (ITMC_OBJ_MAP	!= type)))) {
2380 			itm_error(
2381 				gettext("name type conflict: \"%1$s\" "
2382 				"%2$s %3$s\n"),
2383 				name_to_str(name),
2384 				itm_name_type_name[type],
2385 				itm_name_type_name[p->type]);
2386 			error_deferred += 1;
2387 			return (&name_lookup_error);
2388 		} else {
2389 			return	(p);
2390 		}
2391 	}
2392 	return	(NULL);
2393 }
2394 
2395 
2396 itmc_name_t *
2397 name_refer(itm_data_t	*name, itm_type_t type, itmc_ref_t	*refp)
2398 {
2399 	itmc_name_t		*p;
2400 	itmc_ref_link_t		*rl;
2401 
2402 	p = name_lookup(name, type);
2403 
2404 	TRACE_MESSAGE('N', ("name_refer\t: \"%-16s\" %2ld %2ld %08p %2d %08p\n",
2405 			name_to_str(name), name->size, type, refp, name_id, p));
2406 
2407 	if (&name_lookup_error == p) {
2408 		return	(NULL);
2409 	}
2410 
2411 	rl = malloc_vital(sizeof (itmc_ref_link_t));
2412 
2413 	rl->ref = refp;
2414 	rl->next = NULL;
2415 
2416 	if (NULL != p) {
2417 		if (p->ref_last) {
2418 			p->ref_last->next = rl;
2419 		} else {
2420 			p->ref_first = rl;
2421 		}
2422 		p->ref_last = rl;
2423 	} else {
2424 		p = malloc_vital(sizeof (itmc_name_t));
2425 		p->id = (name_id++);
2426 		p->reg_id = 0;
2427 		p->name = *name;
2428 		p->type = type;
2429 #if !defined(_LP64)
2430 		p->reloc.itm_pad = 0;
2431 #endif
2432 		p->reloc.itm_ptr = 0;
2433 		p->ref_first = rl;
2434 		p->ref_last = rl;
2435 		p->next = NULL;
2436 
2437 		if (name_last) {
2438 			name_last->next = p;
2439 		} else {
2440 			name_first = p;
2441 		}
2442 		name_last = p;
2443 	}
2444 	return	(p);
2445 }
2446 
2447 
2448 itmc_name_t *
2449 name_register(itm_data_t	*name, itm_type_t type, itmc_ref_t	*refp)
2450 {
2451 	itmc_name_t	*p;
2452 
2453 	TRACE_MESSAGE('N', ("name_register\t: \"%-16s\" %2ld %2ld %08p %2ld\n",
2454 			name_to_str(name), name->size, type, refp, name_id));
2455 
2456 
2457 	p = name_lookup(name, type);
2458 	if (&name_lookup_error == p) {
2459 		return	(NULL);
2460 	}
2461 	if (NULL != p) {
2462 		if (NULL != p->object) {
2463 			itm_error(gettext(
2464 				"same names are specified: %1$s\n"),
2465 				name_to_str(name));
2466 			error_deferred += 1;
2467 			return (NULL);
2468 		}
2469 		p->object = refp;
2470 	} else {
2471 		p = malloc_vital(sizeof (itmc_name_t));
2472 		p->id = (name_id++);
2473 		p->reg_id = 0;
2474 		p->name = *name;
2475 		p->type = type;
2476 		p->object = refp;
2477 		p->reloc.itm_ptr = 0;
2478 #if !defined(_LP64)
2479 		p->reloc.itm_pad = 0;
2480 #endif
2481 		p->ref_first = NULL;
2482 		p->ref_last = NULL;
2483 		p->next = NULL;
2484 
2485 		if (name_last) {
2486 			name_last->next = p;
2487 		} else {
2488 			name_first = p;
2489 		}
2490 		name_last = p;
2491 	}
2492 
2493 	return	(p);
2494 }
2495 
2496 
2497 int
2498 data_compare(const itm_data_t	*d0, const itm_data_t	*d1)
2499 {
2500 	if (d0->size < d1->size) {
2501 		if (memcmp(NSPTR(d0), NSPTR(d1), d0->size) < 0) {
2502 			return (-1);
2503 		} else {
2504 			return	(1);
2505 		}
2506 	} else if (d0->size == d1->size) {
2507 		return (memcmp(NSPTR(d0), NSPTR(d1), d0->size));
2508 	} else /* (d0->size > d1->size) */ {
2509 		if (memcmp(NSPTR(d0), NSPTR(d1), d1->size) <= 0) {
2510 			return (-1);
2511 		} else {
2512 			return	(1);
2513 		}
2514 	}
2515 }
2516 
2517 int
2518 data_pair_compare(itmc_data_pair_t	**p0, itmc_data_pair_t	**p1)
2519 {
2520 	int		r;
2521 	itm_data_t	*d0;
2522 	itm_data_t	*d1;
2523 	uchar_t		*c0;
2524 	uchar_t		*c1;
2525 	size_t		s;
2526 	int		i;
2527 
2528 	d0 = &((*p0)->data0);
2529 	d1 = &((*p1)->data0);
2530 	c0 = NSPTR(d0);
2531 	c1 = NSPTR(d1);
2532 	if (d0->size == d1->size) {
2533 		s = d0->size;
2534 	} else if (d0->size < d1->size) {
2535 		s = d1->size - d0->size;
2536 		for (i = 0; i < s; i++, c1++) {
2537 			if (0x00 != *c1) {
2538 				return (-1);
2539 			}
2540 		}
2541 		s = d0->size;
2542 	} else {
2543 		assert(d0->size > d1->size);
2544 		s = d0->size - d1->size;
2545 		for (i = 0; i < s; i++, c0++) {
2546 			if (0x00 != *c0) {
2547 				return	(1);
2548 			}
2549 		}
2550 		s = d1->size;
2551 	}
2552 	r = memcmp(c0, c1, s);
2553 	if (0 == r) {
2554 		itm_data_t	*d;
2555 		if (c0 == NSPTR(d0)) {
2556 			d = d0;
2557 		} else {
2558 			assert(c1 == NSPTR(d0));
2559 			d = d1;
2560 		}
2561 		itm_error(gettext(
2562 			"distinct source values are specified: 0x%1$s\n"),
2563 			data_to_hexadecimal(d));
2564 		error_deferred += 1;
2565 	}
2566 	return	(r);
2567 }
2568 
2569 
2570 static long
2571 data_to_long(itm_data_t		*data)
2572 {
2573 	long		l;
2574 	int		i;
2575 	unsigned char	*p;
2576 
2577 	if ((sizeof (itm_place_t)) < data->size) {
2578 		return (0);
2579 	}
2580 	for (l = 0, i = 0, p = (unsigned char *)&(data->place);
2581 	    i < data->size;
2582 	    i++, p++) {
2583 		l <<= 8;
2584 		l |= *p;
2585 	}
2586 	return	(l);
2587 }
2588