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