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
41static size_t	map_table_resultlen(itmc_map_t *);
42static int	data_pair_compare(itmc_data_pair_t **, itmc_data_pair_t **);
43static long	data_to_long(itm_data_t *);
44
45static itm_tbl_hdr_t	*map_table_indexed_fixed(itmc_data_pair_t **,
46				itm_size_t, itm_data_t *, long, itm_num_t);
47static 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);
51static itm_tbl_hdr_t	*map_table_lookup_fixed(itmc_data_pair_t **,
52				itm_size_t, itm_data_t *, long, itm_size_t);
53static 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);
56static itm_tbl_hdr_t	*map_table_lookup_var();
57static void		put_dense_encoding_default(char *, unsigned char *,
58			unsigned char *, unsigned char *, long, long, long);
59static size_t		map_table_resultlen(itmc_map_t *);
60static void		map_range_adjust_byte_seq(unsigned char *,
61				unsigned char *, long, itmc_data_pair_t *);
62static void		map_range_make_result(char *, itm_size_t, itm_size_t,
63				char *, itm_size_t);
64static size_t		map_table_num_range(itmc_data_pair_t *);
65static itmc_map_type_t	check_map_type(itmc_map_attr_t *);
66
67
68static itmc_name_t	*name_lookup(itm_data_t *, itm_type_t);
69static itmc_name_t	*name_refer(itm_data_t *, itm_type_t, itmc_ref_t *);
70static itmc_name_t	*name_register(itm_data_t *, itm_type_t, itmc_ref_t *);
71static void		op_hirarchy(itm_tbl_hdr_t *, itmc_obj_t *);
72static obj_array_t	obj_list_to_array(itm_size_t, itmc_obj_t *, itm_size_t);
73
74
75void
76itm_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
113itmc_obj_t *
114direction_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
162itm_tbl_hdr_t *
163obj_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 */
199static obj_array_t
200obj_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
243static void
244op_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
281itmc_obj_t *
282obj_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
301itmc_ref_t *
302obj_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
368itm_tbl_hdr_t *
369range_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 */
434itm_tbl_hdr_t *
435escseq_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
512itm_tbl_hdr_t *
513map_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
923static itmc_map_type_t
924check_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
941static itm_tbl_hdr_t *
942map_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
1129static itm_tbl_hdr_t *
1130map_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
1281static itm_tbl_hdr_t *
1282map_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
1585static itm_tbl_hdr_t *
1586map_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
1768static void
1769put_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
1806char *
1807dense_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
1854itm_tbl_hdr_t *
1855map_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
1865static void
1866map_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 */
1902static size_t
1903map_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 */
1943static void
1944map_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 */
1976static size_t
1977map_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 */
2011itmc_map_t *
2012map_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
2032itmc_obj_t *
2033op_self(itm_op_type_t type)
2034{
2035	return (op_unit(type, NULL, 0, NULL, 0, NULL, 0));
2036}
2037
2038
2039itmc_obj_t *
2040op_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
2045itmc_obj_t *
2046op_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
2090itmc_obj_t *
2091op_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
2112itm_expr_t *
2113expr_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
2127itm_expr_t *
2128expr_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
2176itm_expr_t *
2177expr_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
2192itm_expr_t *
2193expr_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
2233itm_expr_t *
2234expr_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
2301itm_expr_t *
2302expr_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
2329itm_expr_t *
2330expr_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
2354itmc_name_t *
2355name_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
2396itmc_name_t *
2397name_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
2448itmc_name_t *
2449name_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
2497int
2498data_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
2517int
2518data_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
2570static long
2571data_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