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
51 itmc_ref_t *ref_first[ITMC_OBJ_LAST + 1];
52 itmc_ref_t *ref_last[ITMC_OBJ_LAST + 1];
53
54 itmc_name_t *name_first;
55 itmc_name_t *name_last;
56
57 char *itm_input_file; /* referred in itm_comp.l */
58 char *itm_output_file;
59
60 cmd_opt_t cmd_opt;
61 itm_num_t name_id;
62 itm_num_t reg_id;
63
64 itmc_name_t name_lookup_error;
65 int error_deferred;
66
67 char *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
83 static void usage(int status);
84 static int cpp_opt_append(char *opt, char *arg);
85 static void cpp_opt_trunc(int num);
86 static int parse_opts(int argc, char **argv);
87 static char *prog_path_expand(const char *base_name);
88 static void map_name_type_append(char *optarg);
89 static char *map_type_name_str(itmc_map_type_t);
90 static char *strdup_vital(const char *);
91
92 #if defined(ENABLE_TRACE)
93 static void trace_option(void);
94 #endif /* ENABLE_TRACE */
95 static FILE *cpp_open(void);
96 static void cpp_close(FILE *fp);
97 static int itm_compile(char *file);
98 static void wait_child(pid_t pid);
99 static int fork_error(void);
100
101
102
103
104 int
main(int argc,char ** argv)105 main(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
149 static int
itm_compile(char * file)150 itm_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
247 static void
wait_child(pid_t pid)248 wait_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
265 static int
fork_error(void)266 fork_error(void)
267 {
268 PERROR(gettext("fork"));
269 exit(ITMC_STATUS_SYS);
270 return (0); /* never return */
271 }
272
273
274
275 static int
parse_opts(int argc,char ** argv)276 parse_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
458 static FILE *
cpp_open(void)459 cpp_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
491 static int
cpp_opt_append(char * opt,char * arg)492 cpp_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
536 static void
cpp_opt_trunc(int num)537 cpp_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
549 static void
cpp_close(FILE * fp)550 cpp_close(FILE *fp)
551 {
552 (void) fclose(fp);
553 (void) wait_child(0);
554 }
555
556
557
558
559 static char *
prog_path_expand(const char * base_name)560 prog_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
600 static void
usage(int status)601 usage(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
623 static char *
map_type_name_str(itmc_map_type_t type)624 map_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
635 static void
map_name_type_append(char * optarg)636 map_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
753 void *
malloc_vital(size_t size)754 malloc_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
774 static char *
strdup_vital(const char * str)775 strdup_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
794 itm_data_t *
str_to_data(int size,char * seq)795 str_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
813 char *
name_to_str(itm_data_t * name)814 name_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)
849 char *
data_to_hexadecimal(itm_data_t * data)850 data_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
902 void
itm_error(char * format,...)903 itm_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)
915 static void
trace_option(void)916 trace_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)
1005 extern void
trace_message(char * format,...)1006 trace_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