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
27#pragma ident	"%Z%%M%	%I%	%E% SMI"
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <unistd.h>
32#include <libgen.h>
33#include <fcntl.h>
34#include <locale.h>
35#include <string.h>
36#include <sys/wait.h>
37#include <sys/param.h>
38#include <stdarg.h>
39#include <errno.h>
40
41#include "itmcomp.h"
42#include "maptype.h"
43
44#if !defined(TEXT_DOMAIN)
45#define	TEXT_DOMAIN	"SYS_TEST"
46#endif
47#define	ITMSUFFIX	".bt"
48#define	ME_DEFAULT	"geniconvtbl"
49#define	CPP_PATH	"/usr/lib/cpp"
50
51itmc_ref_t	*ref_first[ITMC_OBJ_LAST + 1];
52itmc_ref_t	*ref_last[ITMC_OBJ_LAST + 1];
53
54itmc_name_t	*name_first;
55itmc_name_t	*name_last;
56
57char		*itm_input_file;		/* referred in itm_comp.l */
58char		*itm_output_file;
59
60cmd_opt_t	cmd_opt;
61itm_num_t	name_id;
62itm_num_t	reg_id;
63
64itmc_name_t	name_lookup_error;
65int		error_deferred;
66
67char *itm_name_type_name[] = {
68	"UNKNOWN",
69	"ITM",
70	"STRING",
71	"DIRECTION",
72	"CONDITION",
73	"MAP",
74	"OPERATION",
75	"EXPRESSION",
76	"DATA",
77	"NAME",
78	"RANGE",
79	"REGISTER",
80};
81
82
83static void	usage(int status);
84static int	cpp_opt_append(char	*opt, char	*arg);
85static void	cpp_opt_trunc(int num);
86static int	parse_opts(int argc, char	**argv);
87static char	*prog_path_expand(const char	*base_name);
88static void	map_name_type_append(char	*optarg);
89static char	*map_type_name_str(itmc_map_type_t);
90static char	*strdup_vital(const char *);
91
92#if defined(ENABLE_TRACE)
93static void	trace_option(void);
94#endif /* ENABLE_TRACE */
95static FILE	*cpp_open(void);
96static void	cpp_close(FILE		*fp);
97static int	itm_compile(char	*file);
98static void	wait_child(pid_t pid);
99static int	fork_error(void);
100
101
102
103
104int
105main(int argc, char **argv)
106{
107	char	**pp;
108	pid_t	pid;
109
110	(void) setlocale(LC_ALL, "");
111
112	(void) textdomain(TEXT_DOMAIN);
113
114	(void) parse_opts(argc, argv);
115
116#if defined(ENABLE_TRACE)
117	trace_option();
118#endif /* ENABLE_TRACE */
119
120	if (NULL != cmd_opt.disassemble) {
121		disassemble(cmd_opt.disassemble);
122	} else if (NULL == cmd_opt.input_file) {
123		(void) itm_compile(NULL);
124	} else {
125		if (1 < cmd_opt.input_file_num) {
126			for (pp = cmd_opt.input_file; *pp; pp++) {
127				(void) printf("%s:\n", *pp);
128				pid = fork();
129				switch (pid) {
130				case 0:
131					exit(itm_compile(*pp));
132					break;
133				case -1:
134					(void) fork_error();
135					break;
136				default:
137					wait_child(pid);
138				}
139			}
140		} else {
141			(void) itm_compile(*(cmd_opt.input_file));
142		}
143	}
144
145	return (0);
146}
147
148
149static int
150itm_compile(char *file)
151{
152	char	*cmd_line;
153	char	*command;
154	char	*p;
155	size_t	length;
156	FILE	*fp;
157
158	extern int	yyparse();
159	extern FILE *yyin;
160
161	if (NULL == file) {
162		itm_input_file = gettext("*stdin*");
163	} else {
164		if (0 != access(file, R_OK)) {
165			int	e = errno;
166			itm_error(
167				gettext("%1$s: can not access %2$s: "),
168				cmd_opt.my_name, file);
169			errno = e;
170			PERROR(NULL);
171			exit(ITMC_STATUS_CMD2);
172		}
173		itm_input_file = file;
174	}
175
176	if ((NULL == cmd_opt.output_file) &&
177	    (0 == cmd_opt.no_output)) {
178		p = strrchr(file, '.');
179		if (NULL == p) {
180			length = strlen(file);
181		} else {
182			length = p - file;
183		}
184		itm_output_file = malloc_vital(length + 5);
185		(void) memcpy(itm_output_file, file, length);
186		(void) memcpy(itm_output_file + length, ITMSUFFIX, 5);
187	} else {
188		itm_output_file = cmd_opt.output_file;
189	}
190
191	if (0 != cmd_opt.preprocess) {
192		if (NULL == file) {
193			fp = cpp_open();
194			cmd_line = cmd_opt.preprocess;
195		} else {
196			(void) cpp_opt_append(file, NULL);
197			fp = cpp_open();
198			cpp_opt_trunc(1);
199		}
200		if (NULL == fp) {
201			p = strchr(cmd_line, ' ');
202			if (NULL == p) {
203				length = strlen(cmd_line);
204			} else {
205				length = (p - cmd_line);
206			}
207			command = malloc_vital((sizeof (char)) * (length + 1));
208			(void) memcpy(command, cmd_line, length);
209			*(command + length) = '\0';
210			PERROR(command);
211			itm_error(
212				gettext("%1$s: can not start %2$s on %3$s\n"),
213				cmd_opt.my_name, command, itm_input_file);
214			exit(ITMC_STATUS_SYS);
215		} else {
216			yyin = fp;
217		}
218
219		(void) yyparse();
220		if (NULL == cmd_opt.preprocess_specified) {
221			cpp_close(fp);
222		}
223	} else {
224		if ((NULL == file) || (0 != strcmp("-", file))) {
225			yyin = stdin;
226		} else {
227			yyin = fopen(file, "r");
228			if (NULL == yyin) {
229				itm_error(
230					gettext("%1$s: can not open %2$s\n"),
231					cmd_opt.my_name, itm_input_file);
232				exit(ITMC_STATUS_CMD2);
233			}
234		}
235		(void) yyparse();
236		if (stdin != yyin) {
237			(void) fclose(yyin);
238		}
239	}
240
241	return (ITMC_STATUS_SUCCESS);
242}
243
244
245
246
247static void
248wait_child(pid_t pid)
249{
250	int	stat_loc;
251	char *msgstr;
252
253	(void) waitpid(pid, &stat_loc, 0);
254	if (WTERMSIG(stat_loc)) {
255		if (WCOREDUMP(stat_loc)) {
256			msgstr = gettext("signal received: %s, core dumped\n");
257		} else {
258			msgstr = gettext("signal received: %s\n");
259		}
260		itm_error(msgstr, strsignal(WTERMSIG(stat_loc)));
261	}
262}
263
264
265static int
266fork_error(void)
267{
268	PERROR(gettext("fork"));
269	exit(ITMC_STATUS_SYS);
270	return (0); /* never return */
271}
272
273
274
275static int
276parse_opts(int argc, char **argv)
277{
278	int		c;
279	int		i;
280	char		*p;
281	int		error_num = 0;
282
283#ifdef YYDEBUG
284	extern int	yydebug;
285#endif /* YYDEBUG */
286
287	extern char	*optarg;
288	extern int	optind;
289
290
291	cmd_opt.my_name = basename(*(argv + 0));
292	if ('\0' == *(cmd_opt.my_name)) {
293		cmd_opt.my_name = ME_DEFAULT;
294	}
295
296	cmd_opt.preprocess_default = CPP_PATH;
297	cmd_opt.preprocess = cmd_opt.preprocess_default;
298	cmd_opt.strip = 1; /* stripped by default */
299	while ((c = getopt(argc, argv, "d:i:p:W:D:I:U:fnsM:lo:qX:h")) != EOF) {
300		switch (c) {
301		case 'd':
302			cmd_opt.disassemble = optarg;
303			break;
304		case 'i':
305			cmd_opt.interpreter = optarg;
306			break;
307		case 'p':
308			if (NULL != cmd_opt.preprocess_specified) {
309				(void) fprintf(stderr,
310				gettext("multiple -p options are specified\n"));
311				error_num += 1;
312			}
313			cmd_opt.preprocess_specified =
314				prog_path_expand(optarg);
315			cmd_opt.preprocess = cmd_opt.preprocess_specified;
316			if (NULL == cmd_opt.preprocess) {
317				(void) fprintf(stderr,
318				gettext("cannot find preprocessor \"%s\"\n"),
319					optarg);
320				error_num += 1;
321			}
322			(void) cpp_opt_append(NULL, NULL);
323			p = basename(optarg);
324			if (NULL == p) {
325				*(cmd_opt.cpp_opt + 0) = strdup_vital(optarg);
326			} else {
327				*(cmd_opt.cpp_opt + 0) = strdup_vital(p);
328			}
329			break;
330		case 'W':
331			if (cpp_opt_append(optarg, NULL)) {
332				error_num += 1;
333			}
334			break;
335		case 'I':
336			if (cpp_opt_append("-I", optarg)) {
337				error_num += 1;
338			}
339			break;
340		case 'D':
341			if (cpp_opt_append("-D", optarg)) {
342				error_num += 1;
343			}
344			break;
345		case 'U':
346			if (cpp_opt_append("-U", optarg)) {
347				error_num += 1;
348			}
349			break;
350		case 'f':
351			cmd_opt.force_overwrite = 1;
352			break;
353		case 'n':
354			cmd_opt.no_output = 1;
355			break;
356		case 'M':
357			map_name_type_append(optarg);
358			break;
359		case 'l':
360			cmd_opt.large_table = 1;
361			break;
362		case 'o':
363			cmd_opt.output_file = optarg;
364			break;
365		case 's':
366			cmd_opt.strip = 0;
367			break;
368		case 'q':
369			cmd_opt.quiet = 1;
370			break;
371#if defined(ENABLE_TRACE)
372		case 'X':
373			cmd_opt.trace = malloc_vital((sizeof (char)) * 128);
374			(void) memset(cmd_opt.trace, 0, (sizeof (char)) * 128);
375			for (p = optarg; *p; p++) {
376				*(cmd_opt.trace + ((*p) & 0x007f)) = 1;
377			}
378#ifdef YYDEBUG
379			if (TRACE('Y'))	yydebug = 1;
380#endif /* YYDEBUG */
381			break;
382#endif /* ENABLE_TRACE */
383		case 'h':
384			usage(ITMC_STATUS_SUCCESS);
385			break;
386		default:
387			usage(ITMC_STATUS_CMD);
388		}
389	}
390
391	if (optind < argc) {
392		cmd_opt.input_file_num = (argc - optind);
393		cmd_opt.input_file =
394			malloc_vital((sizeof (char *)) *
395					(argc - optind + 1));
396		*(cmd_opt.input_file + (argc - optind)) = NULL;
397	}
398
399	for (i = 0; optind < argc; optind++, i++) {
400		*(cmd_opt.input_file + i) = argv[optind];
401	}
402
403	/* check conflict */
404
405	if ((1 < cmd_opt.input_file_num) && (NULL != cmd_opt.output_file)) {
406		itm_error(gettext("use -o with single input file\n"));
407		error_num++;
408	}
409
410	if ((cmd_opt.input_file_num <= 0) &&
411	    (NULL == cmd_opt.output_file) &&
412	    (NULL == cmd_opt.disassemble) &&
413	    (0 == cmd_opt.no_output)) {
414		itm_error(gettext(
415			"output file is unnamed. "
416			"use -o to specify output file\n"));
417		error_num++;
418	}
419
420	if (cmd_opt.disassemble &&
421	    (cmd_opt.interpreter ||
422	    cmd_opt.cpp_opt ||
423	    cmd_opt.preprocess_specified ||
424	    cmd_opt.input_file ||
425	    cmd_opt.force_overwrite ||
426	    cmd_opt.no_output ||
427	    cmd_opt.map_name_type ||
428	    cmd_opt.large_table ||
429	    cmd_opt.output_file)) {
430		itm_error(
431			gettext("-d may not specified with other options\n"));
432		error_num++;
433	}
434
435	if (error_num) {
436		usage(ITMC_STATUS_CMD);
437	}
438
439	/*
440	 * do not move upward
441	 * may conflict with -d option
442	 */
443	if ((NULL == cmd_opt.preprocess_specified) &&
444	    (NULL != cmd_opt.preprocess_default)) {
445		(void) cpp_opt_append(NULL, NULL);
446		p = basename(cmd_opt.preprocess_default);
447		if (NULL == p) {
448			*(cmd_opt.cpp_opt + 0) =
449				strdup_vital(cmd_opt.preprocess_default);
450		} else {
451			*(cmd_opt.cpp_opt + 0) = strdup_vital(p);
452		}
453	}
454	return (0);
455}
456
457
458static FILE *
459cpp_open(void)
460{
461	pid_t	pid;
462	int	filedes[2];
463	int	i;
464
465	for (i = 0; i < cmd_opt.cpp_opt_num; i++) {
466		TRACE_MESSAGE('C', ("%s\n", *(cmd_opt.cpp_opt + i)));
467	}
468
469	if (pipe(filedes)) {
470		PERROR(gettext("pipe"));
471		itm_error(gettext("failed to open pipe\n"));
472		exit(ITMC_STATUS_SYS);
473	}
474	pid = fork();
475	if (pid == 0) {	/* child */
476		(void) close(filedes[0]);
477		(void) close(1);
478		(void) dup2(filedes[1], 1);
479		(void) execv(cmd_opt.preprocess, cmd_opt.cpp_opt);
480		exit(0);
481	} else if (pid == (pid_t)(-1)) {	/* error */
482		return	(NULL);
483	} else {
484		(void) close(filedes[1]);
485		return (fdopen(filedes[0], "r"));
486	}
487	return	(NULL); /* NEVER */
488}
489
490
491static int
492cpp_opt_append(char	*opt, char	*arg)
493{
494	size_t	opt_len;
495	size_t	arg_len;
496	char	*new_opt;
497	char	**new_opt_list;
498
499	opt_len = ((NULL == opt) ? 0 : strlen(opt));
500	arg_len = ((NULL == arg) ? 0 : strlen(arg));
501	if (0 < (opt_len + arg_len)) {
502		new_opt = malloc_vital(opt_len + arg_len + 1);
503		if (NULL != opt) {
504			(void) memcpy(new_opt, opt, opt_len + 1);
505		}
506		if (NULL != arg) {
507			(void) memcpy(new_opt + opt_len, arg, arg_len + 1);
508		}
509	} else {
510		new_opt = NULL;
511	}
512
513	if (0 == cmd_opt.cpp_opt_reserved) {
514		cmd_opt.cpp_opt_reserved = 32;
515		cmd_opt.cpp_opt = malloc_vital((sizeof (char *)) * 32);
516		*(cmd_opt.cpp_opt + 0) = "cpp";
517		cmd_opt.cpp_opt_num = 1;
518	} else if ((cmd_opt.cpp_opt_reserved - 2) <= cmd_opt.cpp_opt_num) {
519		cmd_opt.cpp_opt_reserved += 32;
520		new_opt_list = malloc_vital((sizeof (char *)) *
521					    cmd_opt.cpp_opt_reserved);
522		(void) memcpy(new_opt_list, cmd_opt.cpp_opt,
523			(sizeof (char *)) * cmd_opt.cpp_opt_num);
524		(void) memset(new_opt_list + cmd_opt.cpp_opt_num, 0, 32);
525		free(cmd_opt.cpp_opt);
526		cmd_opt.cpp_opt = new_opt_list;
527	}
528	if (NULL != new_opt) {
529		*(cmd_opt.cpp_opt + cmd_opt.cpp_opt_num) = new_opt;
530		cmd_opt.cpp_opt_num += 1;
531	}
532	return (0);
533}
534
535
536static void
537cpp_opt_trunc(int num)
538{
539	if (cmd_opt.cpp_opt_num < num) {
540		num = cmd_opt.cpp_opt_num;
541	}
542	for (; 0 < num; --num) {
543		free(cmd_opt.cpp_opt + cmd_opt.cpp_opt_num);
544		--(cmd_opt.cpp_opt_num);
545	}
546}
547
548
549static void
550cpp_close(FILE *fp)
551{
552	(void) fclose(fp);
553	(void) wait_child(0);
554}
555
556
557
558
559static char *
560prog_path_expand(const char *base_name)
561{
562	size_t	base_len;
563	size_t	dir_len;
564	char	path[MAXPATHLEN];
565	char	*p;
566	char	*pe;
567
568	base_len = strlen(base_name);
569	path[0] = '\0';
570
571	if (NULL != strchr(base_name, '/')) {
572		if (0 == access(base_name, X_OK)) {
573			return (strdup_vital(base_name));
574		} else {
575			return (NULL);
576		}
577	}
578
579	for (p = getenv("PATH"); p; ) {
580		pe = strchr(p, ':');
581		dir_len = ((NULL == pe) ? strlen(p) : (pe - p));
582		(void) memcpy(path, p, dir_len);
583		if ((0 != dir_len) &&
584		    ('/' != path[dir_len - 1])) {
585			path[dir_len] = '/';
586			dir_len += 1;
587		}
588		if ((dir_len + base_len) < MAXPATHLEN) {
589			(void) memcpy(path + dir_len, base_name, base_len + 1);
590			if (0 == access(path, X_OK)) {
591				return (strdup_vital(path));
592			}
593		}
594		p = ((NULL == pe) ? NULL : (pe + 1));
595	}
596	return	(NULL);
597}
598
599
600static void
601usage(int status)
602{
603
604	if (ITMC_STATUS_SUCCESS == status) {
605		(void) fprintf(stdout,
606		gettext("Usage: %1$s [-n] [-f] [-q]\n"
607		"	     [-p preprocessor] [-W argument]\n"
608		"	     [-Dname] [-Dname=def] [-Idirectory] [-Uname]\n"
609		"	     [file ...]\n	%2$s -h\n"),
610		cmd_opt.my_name, cmd_opt.my_name);
611	} else {
612		(void) itm_error(
613		gettext("Usage: %1$s [-n] [-f] [-q]\n"
614		"	     [-p preprocessor] [-W argument]\n"
615		"	     [-Dname] [-Dname=def] [-Idirectory] [-Uname]\n"
616		"	     [file ...]\n	%2$s -h\n"),
617		cmd_opt.my_name, cmd_opt.my_name);
618	}
619	exit(status);
620}
621
622
623static char *
624map_type_name_str(itmc_map_type_t type)
625{
626	int	i;
627	for (i = 0; NULL != map_type_name[i].name; i++) {
628		if (type == map_type_name[i].type) {
629			return (map_type_name[i].name);
630		}
631	}
632	return ("");
633}
634
635static void
636map_name_type_append(char *optarg)
637{
638	char			*oa;
639	char			*oa_save;
640	char			*name;
641	char			*p;
642	char			*phf;
643	int			hash_factor = 0;
644	itmc_map_type_t		type;
645	itmc_map_name_type_t	*m;
646	int			i;
647
648	oa = oa_save = strdup_vital(optarg);
649
650	while ((NULL != oa) && ('\0' != *oa)) {
651		name = oa;
652		oa = strchr(oa, ',');
653		if (NULL != oa) {
654			*(oa++) = '\0';
655		}
656		p = strchr(name, '=');
657		if (NULL == p) {
658			type = ITMC_MAP_AUTOMATIC;
659		} else {
660			*(p++) = '\0';
661			if ('\0' == *p) {
662				type = ITMC_MAP_AUTOMATIC;
663			} else {
664				phf = strchr(p, ':');
665				if (NULL != phf) {
666					*(phf++) = '\0';
667					hash_factor = atoi(phf);
668					if (hash_factor < 0) {
669						itm_error(
670						gettext(
671						"invalid hash factor is "
672						"specified: %s\n"),
673							phf);
674						hash_factor = 0;
675						error_deferred += 1;
676					}
677				}
678				for (i = 0;
679				    NULL != map_type_name[i].name; i++) {
680					if (0 ==
681					    strcmp(p, map_type_name[i].name)) {
682						type = map_type_name[i].type;
683						break;
684					}
685				}
686				if (NULL == map_type_name[i].name) {
687					itm_error(
688					gettext(
689					"unknown map type is specified: %s\n"),
690					p);
691					error_deferred += 1;
692					continue;
693				}
694			}
695		}
696		if (0 == strcmp(name, "default")) {
697			*name = '\0';
698		}
699		m = cmd_opt.map_name_type;
700		if (NULL == m) {
701			m = malloc_vital(sizeof (itmc_map_name_type_t));
702			m->name = strdup_vital(name);
703			m->type = type;
704			m->hash_factor = hash_factor;
705			m->next = NULL;
706			cmd_opt.map_name_type = m;
707			continue;
708		}
709		for (; ; m = m->next) {
710			if (0 == strcmp(name, m->name)) {
711				if (type == m->type) {
712					m = NULL;
713					break;
714				}
715				if ('\0' == *name) {
716					itm_error(
717					gettext(
718					"multiple default types are specified:"
719					" \"%1$s\" and \"%2$s\"\n"),
720						map_type_name_str(type),
721						map_type_name_str(m->type));
722				} else {
723					itm_error(
724					gettext("map \"%1$s\" is specified as "
725					"two types \"%2$s\" and \"%3$s\"\n"),
726					name,
727					map_type_name_str(type),
728					map_type_name_str(m->type));
729				}
730				error_deferred += 1;
731				m = NULL;
732				break;
733			}
734			if (NULL == m->next) {
735				break;
736			}
737		}
738		if (NULL != m) {
739			m->next = malloc_vital(sizeof (itmc_map_name_type_t));
740			m = m->next;
741			m->name = strdup_vital(name);
742			m->type = type;
743			m->hash_factor = hash_factor;
744			m->next = NULL;
745
746		}
747	}
748	free(oa_save);
749}
750
751
752
753void *
754malloc_vital(size_t size)
755{
756	void	*p;
757
758	TRACE_MESSAGE('M', ("malloc_vital: %d\n", size));
759
760	size = ITMROUNDUP(size);
761
762	p = (void*) malloc(size);
763	if (NULL == p) {
764		PERROR(gettext("malloc"));
765		exit(ITMC_STATUS_SYS);
766	}
767
768	(void) memset(p, 0, size);
769
770	return	(p);
771}
772
773
774static char *
775strdup_vital(const char		*str)
776{
777	char	*p;
778	size_t	len;
779
780	if (NULL == str) {
781		return	(NULL);
782	}
783
784	len = strlen(str) + 1;
785	p = malloc_vital(len);
786	(void) memcpy(p, str, len);
787	return	(p);
788}
789
790
791
792
793
794itm_data_t *
795str_to_data(int size, char *seq)
796{
797	itm_data_t *data;
798
799	data = malloc_vital(sizeof (itm_data_t));
800
801	data->size = size;
802	if (size <= sizeof (data->place)) {
803		(void) memmove(&(data->place), seq, size);
804	} else {
805		data->place.itm_ptr = (itm_place2_t)malloc_vital(size);
806		(void) memmove((char *)(data->place.itm_ptr), seq, size);
807	}
808
809	return	(data);
810}
811
812
813char *
814name_to_str(itm_data_t *name)
815{
816	static char	*ptr = NULL;
817	static size_t	len = 0;
818	size_t		req_len;
819	char		*p;
820
821	if (NULL == name) {
822		p = gettext("(no name)");
823		req_len = strlen(p) + 1;
824	} else {
825		req_len = name->size + 1;
826	}
827
828	if (len <= req_len) {
829		len += 512;
830		free(ptr);
831		ptr = malloc_vital(len);
832	}
833
834	if (NULL == name) {
835		(void) memcpy(ptr, p, req_len);
836		*(ptr + req_len) = '\0';
837	} else if (name->size <= (sizeof (name->place))) {
838		(void) memcpy(ptr, (char *)(&(name->place)), name->size);
839		*(ptr + name->size) = '\0';
840	} else {
841		(void) memcpy(ptr, (char *)(name->place.itm_ptr), name->size);
842		*(ptr + name->size) = '\0';
843	}
844
845	return	(ptr);
846}
847
848#define	ARGUMENTSMAX (8)
849char *
850data_to_hexadecimal(itm_data_t		*data)
851{
852	static int index = 0;
853	static char	*ptr[ARGUMENTSMAX] = { NULL, NULL, NULL, NULL,
854						NULL, NULL, NULL, NULL};
855	static long	len[ARGUMENTSMAX] = { 0, 0, 0, 0, 0, 0, 0, 0};
856	char		*hdp;
857	char		*p;
858	long		i;
859	int		val;
860	size_t		req_len;
861
862	if (ARGUMENTSMAX <= index) index = 0;
863	req_len = (2 * data->size) + 1;
864	if (len[index] <= req_len) {
865		len[index] += 512;
866		free(ptr[index]);
867		ptr[index] = malloc_vital(len[index]);
868	}
869	hdp = ptr[index];
870
871	if (data->size <= (sizeof (itm_place_t))) {
872		p = (char *)&(data->place);
873	} else {
874		p = (char *)(data->place.itm_ptr);
875	}
876
877	for (i = 0; i < data->size; i++, p++) {
878		val = ((*p & 0x00f0) >> 4);
879		if ((0 <= val) && (val <= 9)) {
880			*hdp = '0' + val;
881		} else {
882			*hdp = 'a' + val - 10;
883		}
884		hdp++;
885
886		val = (*p & 0x000f);
887		if ((0 <= val) && (val <= 9)) {
888			*hdp = '0' + val;
889		} else {
890			*hdp = 'a' + val - 10;
891		}
892		hdp++;
893	}
894	*hdp = '\0';
895	return (ptr[index++]);
896}
897
898
899
900
901
902void
903itm_error(char *format, ...)
904{
905	va_list		ap;
906	va_start(ap, format);
907
908	if (0 == cmd_opt.quiet) {
909		(void) vfprintf(stderr, format, ap);
910	}
911	va_end(ap);
912}
913
914#if defined(ENABLE_TRACE)
915static void
916trace_option(void)
917{
918	char **pp;
919	int	i;
920
921	if (!(TRACE('o')))
922		return;
923
924	itm_error("my_name	   = %s\n", cmd_opt.my_name);
925	if (NULL == cmd_opt.input_file) {
926		(void) fprintf(stdout, "input_file   = (stdin)\n");
927	} else {
928		for (pp = cmd_opt.input_file; *pp; pp++) {
929			(void) fprintf(stdout, "input_file   = %s\n", *pp);
930		}
931	}
932	itm_error("output_file  = %s\n",
933		cmd_opt.output_file ? cmd_opt.output_file : "(stdout)");
934	itm_error("interpreter  = %s\n",
935		cmd_opt.interpreter ? cmd_opt.interpreter : "(default)");
936	if (cmd_opt.cpp_opt) {
937		itm_error("cpp_opt	   = %s\n", *(cmd_opt.cpp_opt));
938		for (i = 1; i < cmd_opt.cpp_opt_num; i++) {
939			itm_error("\t%s\n", *(cmd_opt.cpp_opt + i));
940		}
941	} else {
942		itm_error("cpp_opt	   = %s\n", "(none)");
943	}
944	itm_error("preprocess_default = %s\n",
945		cmd_opt.preprocess_default ? cmd_opt.preprocess_default :
946		"(no)");
947	itm_error("preprocess_specified = %s\n",
948		cmd_opt.preprocess_specified ? cmd_opt.preprocess_specified :
949		"(no)");
950	itm_error("preprocess   = %s\n",
951		cmd_opt.preprocess ? cmd_opt.preprocess : "(no)");
952	itm_error("disassemble  = %s\n",
953		cmd_opt.disassemble ? "yes" : "no");
954	itm_error("map type	   =");
955	if (NULL == cmd_opt.map_name_type) {
956		itm_error("\n");
957	} else {
958		itmc_map_name_type_t *m;
959		itm_error(" ");
960		m = cmd_opt.map_name_type;
961		itm_error("%s=%s",
962			(((NULL == m->name) || ('\0' == *(m->name))) ?
963				"default" : m->name),
964			map_type_name_str(m->type));
965		if (0 != m->hash_factor) {
966			itm_error(":%ld\n", m->hash_factor);
967		} else {
968			(void) fputc('\n', stderr);
969		}
970		for (m = m->next; NULL != m; m = m->next) {
971			itm_error("		%s=%s",
972				(((NULL == m->name) || ('\0' == *(m->name))) ?
973					"default" : m->name),
974				map_type_name_str(m->type));
975			if (0 != m->hash_factor) {
976				itm_error(":%ld\n", m->hash_factor);
977			} else {
978				(void) fputc('\n', stderr);
979			}
980		}
981	}
982	itm_error("large table  = %s\n",
983		cmd_opt.large_table ? "true" : "false");
984	itm_error("overwrite	   = %s\n",
985		cmd_opt.force_overwrite ? "true" : "false");
986	itm_error("strip	      = %s\n",
987		cmd_opt.strip ? "true" : "false");
988	itm_error("no_output	   = %s\n",
989		cmd_opt.no_output ? "true" : "false");
990	itm_error("trace	      = ");
991	if (NULL == cmd_opt.trace) {
992		itm_error("(no)\n");
993	} else {
994		for (i = 0x21; i < 0x7f; i++) {
995			if (TRACE(i)) {
996				(void) fputc(i, stderr);
997			}
998		}
999		(void) fputc('\n', stderr);
1000	}
1001}
1002#endif /* ENABLE_TRACE */
1003
1004#if defined(ENABLE_TRACE)
1005extern void
1006trace_message(char *format, ...)
1007{
1008	va_list	ap;
1009	va_start(ap, format);
1010
1011	(void) vfprintf(stderr, format, ap);
1012
1013	va_end(ap);
1014}
1015#endif /* ENABLE_TRACE */
1016