trace.c revision a1f3da82
1/* $XTermId: trace.c,v 1.121 2011/02/17 00:34:47 tom Exp $ */ 2 3/* 4 * Copyright 1997-2010,2011 by Thomas E. Dickey 5 * 6 * All Rights Reserved 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the 10 * "Software"), to deal in the Software without restriction, including 11 * without limitation the rights to use, copy, modify, merge, publish, 12 * distribute, sublicense, and/or sell copies of the Software, and to 13 * permit persons to whom the Software is furnished to do so, subject to 14 * the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included 17 * in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22 * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY 23 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 * 27 * Except as contained in this notice, the name(s) of the above copyright 28 * holders shall not be used in advertising or otherwise to promote the 29 * sale, use or other dealings in this Software without prior written 30 * authorization. 31 * 32 */ 33 34/* 35 * debugging support via TRACE macro. 36 */ 37 38#include <xterm.h> /* for definition of GCC_UNUSED */ 39 40#if OPT_TRACE 41 42#include <data.h> 43#include <trace.h> 44 45#include <time.h> 46#include <stdlib.h> 47#include <unistd.h> 48#include <sys/types.h> 49#include <stdio.h> 50#include <stdarg.h> 51#include <assert.h> 52 53#include <X11/Xatom.h> 54#include <X11/Xmu/Atoms.h> 55 56#ifdef HAVE_X11_TRANSLATEI_H 57#include <X11/TranslateI.h> 58#else 59#ifdef __cplusplus 60extern "C" { 61#endif 62 63 extern String _XtPrintXlations(Widget w, 64 XtTranslations xlations, 65 Widget accelWidget, 66 _XtBoolean includeRHS); 67#ifdef __cplusplus 68} 69#endif 70#endif 71const char *trace_who = "parent"; 72 73static FILE *trace_fp; 74 75void 76Trace(const char *fmt,...) 77{ 78 static const char *trace_out; 79 va_list ap; 80 81 if (trace_fp != 0 82 && trace_who != trace_out) { 83 fclose(trace_fp); 84 trace_fp = 0; 85 } 86 trace_out = trace_who; 87 88 if (!trace_fp) { 89 char name[BUFSIZ]; 90#if 0 /* usually I do not want unique names */ 91 int unique; 92 for (unique = 0;; ++unique) { 93 if (unique) 94 sprintf(name, "Trace-%s.out-%d", trace_who, unique); 95 else 96 sprintf(name, "Trace-%s.out", trace_who); 97 if ((trace_fp = fopen(name, "r")) == 0) { 98 break; 99 } 100 fclose(trace_fp); 101 } 102#else 103 sprintf(name, "Trace-%s.out", trace_who); 104#endif 105 trace_fp = fopen(name, "w"); 106 if (trace_fp != 0) { 107 fprintf(trace_fp, "%s\n", xtermVersion()); 108 TraceIds(NULL, 0); 109 } 110 } 111 if (!trace_fp) 112 abort(); 113 114 va_start(ap, fmt); 115 vfprintf(trace_fp, fmt, ap); 116 (void) fflush(trace_fp); 117 va_end(ap); 118} 119 120void 121TraceClose(void) 122{ 123 if (trace_fp != 0) { 124 (void) fclose(trace_fp); 125 (void) fflush(stdout); 126 (void) fflush(stderr); 127 (void) visibleChars(NULL, 0); 128 (void) visibleIChars(NULL, 0); 129 (void) visibleIChar(NULL, 0); 130 trace_fp = 0; 131 } 132} 133 134void 135TraceIds(const char *fname, int lnum) 136{ 137 Trace("process %d ", (int) getpid()); 138#ifdef HAVE_UNISTD_H 139 Trace("real (%u/%u) effective (%u/%u)", 140 (unsigned) getuid(), (unsigned) getgid(), 141 (unsigned) geteuid(), (unsigned) getegid()); 142#endif 143 if (fname != 0) { 144 Trace(" (%s@%d)\n", fname, lnum); 145 } else { 146 time_t now = time((time_t *) 0); 147 Trace("-- %s", ctime(&now)); 148 } 149} 150 151static void 152formatAscii(char *dst, unsigned value) 153{ 154 switch (value) { 155 case '\\': 156 sprintf(dst, "\\\\"); 157 break; 158 case '\b': 159 sprintf(dst, "\\b"); 160 break; 161 case '\n': 162 sprintf(dst, "\\n"); 163 break; 164 case '\r': 165 sprintf(dst, "\\r"); 166 break; 167 case '\t': 168 sprintf(dst, "\\t"); 169 break; 170 default: 171 if (E2A(value) < 32 || (E2A(value) >= 127 && E2A(value) < 160)) 172 sprintf(dst, "\\%03o", value); 173 else 174 sprintf(dst, "%c", CharOf(value)); 175 break; 176 } 177} 178 179#if OPT_DEC_CHRSET 180 181const char * 182visibleChrsetName(unsigned chrset) 183{ 184 const char *result = "?"; 185 switch (chrset) { 186 case CSET_SWL: 187 result = "CSET_SWL"; 188 break; 189 case CSET_DHL_TOP: 190 result = "CSET_DHL_TOP"; 191 break; 192 case CSET_DHL_BOT: 193 result = "CSET_DHL_BOT"; 194 break; 195 case CSET_DWL: 196 result = "CSET_DWL"; 197 break; 198 } 199 return result; 200} 201#endif 202 203char * 204visibleChars(const Char * buf, unsigned len) 205{ 206 static char *result; 207 static unsigned used; 208 209 if (buf != 0) { 210 unsigned limit = ((len + 1) * 8) + 1; 211 char *dst; 212 213 if (limit > used) { 214 used = limit; 215 result = XtRealloc(result, used); 216 } 217 if (result != 0) { 218 dst = result; 219 *dst = '\0'; 220 while (len--) { 221 unsigned value = *buf++; 222 formatAscii(dst, value); 223 dst += strlen(dst); 224 } 225 } 226 } else if (result != 0) { 227 free(result); 228 result = 0; 229 used = 0; 230 } 231 return result; 232} 233 234char * 235visibleIChars(IChar * buf, unsigned len) 236{ 237 static char *result; 238 static unsigned used; 239 240 if (buf != 0) { 241 unsigned limit = ((len + 1) * 8) + 1; 242 char *dst; 243 244 if (limit > used) { 245 used = limit; 246 result = XtRealloc(result, used); 247 } 248 if (result != 0) { 249 dst = result; 250 *dst = '\0'; 251 while (len--) { 252 unsigned value = *buf++; 253#if OPT_WIDE_CHARS 254 if (value > 255) 255 sprintf(dst, "\\u+%04X", value); 256 else 257#endif 258 formatAscii(dst, value); 259 dst += strlen(dst); 260 } 261 } 262 } else if (result != 0) { 263 free(result); 264 result = 0; 265 used = 0; 266 } 267 return result; 268} 269 270char * 271visibleIChar(IChar * buf, unsigned len) 272{ 273 static char *result; 274 static unsigned used; 275 276 if (buf != 0) { 277 unsigned limit = ((len + 1) * 8) + 1; 278 char *dst; 279 280 if (limit > used) { 281 used = limit; 282 result = XtRealloc(result, used); 283 } 284 if (result != 0) { 285 dst = result; 286 while (len--) { 287 unsigned value = *buf++; 288#if OPT_WIDE_CHARS 289 if (value > 255) 290 sprintf(dst, "\\u+%04X", value); 291 else 292#endif 293 formatAscii(dst, value); 294 dst += strlen(dst); 295 } 296 } 297 } else if (result != 0) { 298 free(result); 299 result = 0; 300 used = 0; 301 } 302 return result; 303} 304 305#define CASETYPE(name) case name: result = #name; break 306 307const char * 308visibleKeyboardType(xtermKeyboardType type) 309{ 310 const char *result = "?"; 311 switch (type) { 312 CASETYPE(keyboardIsLegacy); /* bogus vt220 codes for F1-F4, etc. */ 313 CASETYPE(keyboardIsDefault); 314 CASETYPE(keyboardIsHP); 315 CASETYPE(keyboardIsSCO); 316 CASETYPE(keyboardIsSun); 317 CASETYPE(keyboardIsTermcap); 318 CASETYPE(keyboardIsVT220); 319 } 320 return result; 321} 322 323const char * 324visibleEventType(int type) 325{ 326 const char *result = "?"; 327 switch (type) { 328 CASETYPE(KeyPress); 329 CASETYPE(KeyRelease); 330 CASETYPE(ButtonPress); 331 CASETYPE(ButtonRelease); 332 CASETYPE(MotionNotify); 333 CASETYPE(EnterNotify); 334 CASETYPE(LeaveNotify); 335 CASETYPE(FocusIn); 336 CASETYPE(FocusOut); 337 CASETYPE(KeymapNotify); 338 CASETYPE(Expose); 339 CASETYPE(GraphicsExpose); 340 CASETYPE(NoExpose); 341 CASETYPE(VisibilityNotify); 342 CASETYPE(CreateNotify); 343 CASETYPE(DestroyNotify); 344 CASETYPE(UnmapNotify); 345 CASETYPE(MapNotify); 346 CASETYPE(MapRequest); 347 CASETYPE(ReparentNotify); 348 CASETYPE(ConfigureNotify); 349 CASETYPE(ConfigureRequest); 350 CASETYPE(GravityNotify); 351 CASETYPE(ResizeRequest); 352 CASETYPE(CirculateNotify); 353 CASETYPE(CirculateRequest); 354 CASETYPE(PropertyNotify); 355 CASETYPE(SelectionClear); 356 CASETYPE(SelectionRequest); 357 CASETYPE(SelectionNotify); 358 CASETYPE(ColormapNotify); 359 CASETYPE(ClientMessage); 360 CASETYPE(MappingNotify); 361 } 362 return result; 363} 364 365const char * 366visibleNotifyDetail(int code) 367{ 368 const char *result = "?"; 369 switch (code) { 370 CASETYPE(NotifyAncestor); 371 CASETYPE(NotifyVirtual); 372 CASETYPE(NotifyInferior); 373 CASETYPE(NotifyNonlinear); 374 CASETYPE(NotifyNonlinearVirtual); 375 CASETYPE(NotifyPointer); 376 CASETYPE(NotifyPointerRoot); 377 CASETYPE(NotifyDetailNone); 378 } 379 return result; 380} 381 382const char * 383visibleSelectionTarget(Display * d, Atom a) 384{ 385 const char *result = "?"; 386 387 if (a == XA_STRING) { 388 result = "XA_STRING"; 389 } else if (a == XA_TEXT(d)) { 390 result = "XA_TEXT()"; 391 } else if (a == XA_COMPOUND_TEXT(d)) { 392 result = "XA_COMPOUND_TEXT()"; 393 } else if (a == XA_UTF8_STRING(d)) { 394 result = "XA_UTF8_STRING()"; 395 } else if (a == XA_TARGETS(d)) { 396 result = "XA_TARGETS()"; 397 } 398 399 return result; 400} 401 402const char * 403visibleXError(int code) 404{ 405 static char temp[80]; 406 const char *result = "?"; 407 switch (code) { 408 CASETYPE(Success); 409 CASETYPE(BadRequest); 410 CASETYPE(BadValue); 411 CASETYPE(BadWindow); 412 CASETYPE(BadPixmap); 413 CASETYPE(BadAtom); 414 CASETYPE(BadCursor); 415 CASETYPE(BadFont); 416 CASETYPE(BadMatch); 417 CASETYPE(BadDrawable); 418 CASETYPE(BadAccess); 419 CASETYPE(BadAlloc); 420 CASETYPE(BadColor); 421 CASETYPE(BadGC); 422 CASETYPE(BadIDChoice); 423 CASETYPE(BadName); 424 CASETYPE(BadLength); 425 CASETYPE(BadImplementation); 426 default: 427 sprintf(temp, "%d", code); 428 result = temp; 429 break; 430 } 431 return result; 432} 433 434#if OPT_TRACE_FLAGS 435#define isScrnFlag(flag) ((flag) == LINEWRAPPED) 436 437static char * 438ScrnText(LineData * ld) 439{ 440 return visibleIChars(ld->charData, ld->lineSize); 441} 442 443#define SHOW_BAD_LINE(name, ld) \ 444 Trace("OOPS " #name " bad row\n") 445 446#define SHOW_SCRN_FLAG(name,code) \ 447 Trace(#name " %s:%s\n", \ 448 code ? "*" : "", \ 449 ScrnText(ld)) 450 451void 452LineClrFlag(LineData * ld, int flag) 453{ 454 if (ld == 0) { 455 SHOW_BAD_LINE(LineClrFlag, ld); 456 assert(0); 457 } else if (isScrnFlag(flag)) { 458 SHOW_SCRN_FLAG(LineClrFlag, 0); 459 } 460 461 LineFlags(ld) &= ~flag; 462} 463 464void 465LineSetFlag(LineData * ld, int flag) 466{ 467 if (ld == 0) { 468 SHOW_BAD_LINE(LineSetFlag, ld); 469 assert(0); 470 } else if (isScrnFlag(flag)) { 471 SHOW_SCRN_FLAG(LineSetFlag, 1); 472 } 473 474 LineFlags(ld) |= flag; 475} 476 477int 478LineTstFlag(LineData ld, int flag) 479{ 480 int code = 0; 481 if (ld == 0) { 482 SHOW_BAD_LINE(LineTstFlag, ld); 483 } else { 484 code = LineFlags(ld); 485 486 if (isScrnFlag(flag)) { 487 SHOW_SCRN_FLAG(LineTstFlag, code); 488 } 489 } 490 return code; 491} 492#endif /* OPT_TRACE_FLAGS */ 493 494void 495TraceFocus(Widget w, XEvent * ev) 496{ 497 TRACE(("trace_focus event type %d:%s\n", 498 ev->type, visibleEventType(ev->type))); 499 switch (ev->type) { 500 case FocusIn: 501 case FocusOut: 502 { 503 XFocusChangeEvent *event = (XFocusChangeEvent *) ev; 504 TRACE(("\tdetail: %s\n", visibleNotifyDetail(event->detail))); 505 TRACE(("\tmode: %d\n", event->mode)); 506 TRACE(("\twindow: %#lx\n", event->window)); 507 } 508 break; 509 case EnterNotify: 510 case LeaveNotify: 511 { 512 XCrossingEvent *event = (XCrossingEvent *) ev; 513 TRACE(("\tdetail: %s\n", visibleNotifyDetail(event->detail))); 514 TRACE(("\tmode: %d\n", event->mode)); 515 TRACE(("\twindow: %#lx\n", event->window)); 516 TRACE(("\troot: %#lx\n", event->root)); 517 TRACE(("\tsubwindow: %#lx\n", event->subwindow)); 518 } 519 break; 520 } 521 while (w != 0) { 522 TRACE(("w %p -> %#lx\n", (void *) w, XtWindow(w))); 523 w = XtParent(w); 524 } 525} 526 527void 528TraceSizeHints(XSizeHints * hints) 529{ 530 TRACE(("size hints:\n")); 531 if (hints->flags & (USPosition | PPosition)) 532 TRACE((" position %d,%d%s%s\n", hints->y, hints->x, 533 hints->flags & USPosition ? " user" : "", 534 hints->flags & PPosition ? " prog" : "")); 535 if (hints->flags & (USSize | PSize)) 536 TRACE((" size %d,%d%s%s\n", hints->height, hints->width, 537 hints->flags & USSize ? " user" : "", 538 hints->flags & PSize ? " prog" : "")); 539 if (hints->flags & PMinSize) 540 TRACE((" min %d,%d\n", hints->min_height, hints->min_width)); 541 if (hints->flags & PMaxSize) 542 TRACE((" max %d,%d\n", hints->max_height, hints->max_width)); 543 if (hints->flags & PResizeInc) 544 TRACE((" inc %d,%d\n", hints->height_inc, hints->width_inc)); 545 else 546 TRACE((" inc NONE!\n")); 547 if (hints->flags & PAspect) 548 TRACE((" min aspect %d/%d\n", hints->min_aspect.y, hints->min_aspect.y)); 549 if (hints->flags & PAspect) 550 TRACE((" max aspect %d/%d\n", hints->max_aspect.y, hints->max_aspect.y)); 551 if (hints->flags & PBaseSize) 552 TRACE((" base %d,%d\n", hints->base_height, hints->base_width)); 553 if (hints->flags & PWinGravity) 554 TRACE((" gravity %d\n", hints->win_gravity)); 555} 556 557void 558TraceWMSizeHints(XtermWidget xw) 559{ 560 XSizeHints sizehints = xw->hints; 561 562 getXtermSizeHints(xw); 563 TraceSizeHints(&xw->hints); 564 xw->hints = sizehints; 565} 566 567/* 568 * Some calls to XGetAtom() will fail, and we don't want to stop. So we use 569 * our own error-handler. 570 */ 571/* ARGSUSED */ 572static int 573no_error(Display * dpy GCC_UNUSED, XErrorEvent * event GCC_UNUSED) 574{ 575 return 1; 576} 577 578void 579TraceTranslations(const char *name, Widget w) 580{ 581 String result; 582 XErrorHandler save = XSetErrorHandler(no_error); 583 XtTranslations xlations; 584 Widget xcelerat; 585 586 TRACE(("TraceTranslations for %s (widget %#lx) {{\n", name, (long) w)); 587 if (w) { 588 XtVaGetValues(w, 589 XtNtranslations, &xlations, 590 XtNaccelerators, &xcelerat, 591 (XtPointer) 0); 592 TRACE(("... xlations %#08lx\n", (long) xlations)); 593 TRACE(("... xcelerat %#08lx\n", (long) xcelerat)); 594 result = _XtPrintXlations(w, xlations, xcelerat, True); 595 TRACE(("%s\n", NonNull(result))); 596 if (result) 597 XFree((char *) result); 598 } else { 599 TRACE(("none (widget is null)\n")); 600 } 601 TRACE(("}}\n")); 602 XSetErrorHandler(save); 603} 604 605int 606TraceResizeRequest(const char *fn, int ln, Widget w, 607 Dimension reqwide, 608 Dimension reqhigh, 609 Dimension * gotwide, 610 Dimension * gothigh) 611{ 612 int rc; 613 614 TRACE(("%s@%d ResizeRequest %dx%d\n", fn, ln, reqhigh, reqwide)); 615 rc = XtMakeResizeRequest((Widget) w, reqwide, reqhigh, gotwide, gothigh); 616 TRACE(("... ResizeRequest -> ")); 617 if (gothigh && gotwide) 618 TRACE(("%dx%d ", *gothigh, *gotwide)); 619 TRACE(("(%d)\n", rc)); 620 return rc; 621} 622 623#define XRES_S(name) Trace(#name " = %s\n", NonNull(resp->name)) 624#define XRES_B(name) Trace(#name " = %s\n", BtoS(resp->name)) 625#define XRES_I(name) Trace(#name " = %d\n", resp->name) 626 627void 628TraceXtermResources(void) 629{ 630 XTERM_RESOURCE *resp = &resource; 631 632 Trace("XTERM_RESOURCE settings:\n"); 633 XRES_S(icon_geometry); 634 XRES_S(title); 635 XRES_S(icon_name); 636 XRES_S(term_name); 637 XRES_S(tty_modes); 638 XRES_B(hold_screen); 639 XRES_B(utmpInhibit); 640 XRES_B(utmpDisplayId); 641 XRES_B(messages); 642#if OPT_SUNPC_KBD 643 XRES_B(sunKeyboard); 644#endif 645#if OPT_HP_FUNC_KEYS 646 XRES_B(hpFunctionKeys); 647#endif 648#if OPT_SCO_FUNC_KEYS 649 XRES_B(scoFunctionKeys); 650#endif 651#if OPT_SUN_FUNC_KEYS 652 XRES_B(sunFunctionKeys); 653#endif 654#if OPT_INITIAL_ERASE 655 XRES_B(ptyInitialErase); 656 XRES_B(backarrow_is_erase); 657#endif 658 XRES_B(useInsertMode); 659#if OPT_ZICONBEEP 660 XRES_I(zIconBeep); 661#endif 662#if OPT_PTY_HANDSHAKE 663 XRES_B(wait_for_map); 664 XRES_B(ptyHandshake); 665 XRES_B(ptySttySize); 666#endif 667#if OPT_SAME_NAME 668 XRES_B(sameName); 669#endif 670#if OPT_SESSION_MGT 671 XRES_B(sessionMgt); 672#endif 673#if OPT_TOOLBAR 674 XRES_B(toolBar); 675#endif 676#if OPT_MAXIMIZE 677 XRES_B(maximized); 678 XRES_S(fullscreen_s); 679#endif 680} 681 682void 683TraceArgv(const char *tag, char **argv) 684{ 685 int n = 0; 686 687 TRACE(("%s:\n", tag)); 688 while (*argv != 0) { 689 TRACE((" %d:%s\n", n++, *argv++)); 690 } 691} 692 693static char * 694parse_option(char *dst, String src, int first) 695{ 696 char *s; 697 698 if (!strncmp(src, "-/+", (size_t) 3)) { 699 dst[0] = (char) first; 700 strcpy(dst + 1, src + 3); 701 } else { 702 strcpy(dst, src); 703 } 704 for (s = dst; *s != '\0'; s++) { 705 if (*s == '#' || *s == '%' || *s == 'S') { 706 s[1] = '\0'; 707 } else if (*s == ' ') { 708 *s = '\0'; 709 break; 710 } 711 } 712 return dst; 713} 714 715static Bool 716same_option(OptionHelp * opt, XrmOptionDescRec * res) 717{ 718 char temp[BUFSIZ]; 719 return !strcmp(parse_option(temp, opt->opt, res->option[0]), res->option); 720} 721 722static Bool 723standard_option(String opt) 724{ 725 static const char *table[] = 726 { 727 "+rv", 728 "+synchronous", 729 "-background", 730 "-bd", 731 "-bg", 732 "-bordercolor", 733 "-borderwidth", 734 "-bw", 735 "-display", 736 "-fg", 737 "-fn", 738 "-font", 739 "-foreground", 740 "-geometry", 741 "-iconic", 742 "-name", 743 "-reverse", 744 "-rv", 745 "-selectionTimeout", 746 "-synchronous", 747 "-title", 748 "-xnllanguage", 749 "-xrm", 750 "-xtsessionID", 751 }; 752 Cardinal n; 753 char temp[BUFSIZ]; 754 755 opt = parse_option(temp, opt, '-'); 756 for (n = 0; n < XtNumber(table); n++) { 757 if (!strcmp(opt, table[n])) 758 return True; 759 } 760 return False; 761} 762 763/* 764 * Analyse the options/help messages for inconsistencies. 765 */ 766void 767TraceOptions(OptionHelp * options, XrmOptionDescRec * resources, Cardinal res_count) 768{ 769 OptionHelp *opt_array = sortedOpts(options, resources, res_count); 770 size_t j, k; 771 XrmOptionDescRec *res_array = sortedOptDescs(resources, res_count); 772 Bool first, found; 773 774 TRACE(("Checking options-tables for inconsistencies:\n")); 775 776#if 0 777 TRACE(("Options listed in help-message:\n")); 778 for (j = 0; options[j].opt != 0; j++) 779 TRACE(("%5d %-28s %s\n", j, opt_array[j].opt, opt_array[j].desc)); 780 TRACE(("Options listed in resource-table:\n")); 781 for (j = 0; j < res_count; j++) 782 TRACE(("%5d %-28s %s\n", j, res_array[j].option, res_array[j].specifier)); 783#endif 784 785 /* list all options[] not found in resources[] */ 786 for (j = 0, first = True; options[j].opt != 0; j++) { 787 found = False; 788 for (k = 0; k < res_count; k++) { 789 if (same_option(&opt_array[j], &res_array[k])) { 790 found = True; 791 break; 792 } 793 } 794 if (!found) { 795 if (first) { 796 TRACE(("Options listed in help, not found in resource list:\n")); 797 first = False; 798 } 799 TRACE((" %-28s%s\n", opt_array[j].opt, 800 standard_option(opt_array[j].opt) ? " (standard)" : "")); 801 } 802 } 803 804 /* list all resources[] not found in options[] */ 805 for (j = 0, first = True; j < res_count; j++) { 806 found = False; 807 for (k = 0; options[k].opt != 0; k++) { 808 if (same_option(&opt_array[k], &res_array[j])) { 809 found = True; 810 break; 811 } 812 } 813 if (!found) { 814 if (first) { 815 TRACE(("Resource list items not found in options-help:\n")); 816 first = False; 817 } 818 TRACE((" %s\n", res_array[j].option)); 819 } 820 } 821 822 TRACE(("Resource list items that will be ignored by XtOpenApplication:\n")); 823 for (j = 0; j < res_count; j++) { 824 switch (res_array[j].argKind) { 825 case XrmoptionSkipArg: 826 TRACE((" %-28s {param}\n", res_array[j].option)); 827 break; 828 case XrmoptionSkipNArgs: 829 TRACE((" %-28s {%ld params}\n", res_array[j].option, (long) 830 res_array[j].value)); 831 break; 832 case XrmoptionSkipLine: 833 TRACE((" %-28s {remainder of line}\n", res_array[j].option)); 834 break; 835 case XrmoptionIsArg: 836 case XrmoptionNoArg: 837 case XrmoptionResArg: 838 case XrmoptionSepArg: 839 case XrmoptionStickyArg: 840 default: 841 break; 842 } 843 } 844} 845#else 846extern void empty_trace(void); 847void 848empty_trace(void) 849{ 850} 851#endif 852