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 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 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 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 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 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 * 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 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 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 550 cpp_close(FILE *fp) 551 { 552 (void) fclose(fp); 553 (void) wait_child(0); 554 } 555 556 557 558 559 static char * 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 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 * 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 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 * 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 * 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 * 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 * 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 * 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 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 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 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