trace.c revision e39b573c
1/* $XTermId: trace.c,v 1.125 2011/07/12 09:31:05 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(("\tfocus: %d\n", event->focus)); 517 TRACE(("\troot: %#lx\n", event->root)); 518 TRACE(("\tsubwindow: %#lx\n", event->subwindow)); 519 } 520 break; 521 } 522 while (w != 0) { 523 TRACE(("w %p -> %#lx\n", (void *) w, XtWindow(w))); 524 w = XtParent(w); 525 } 526} 527 528void 529TraceSizeHints(XSizeHints * hints) 530{ 531 TRACE(("size hints:\n")); 532 if (hints->flags & (USPosition | PPosition)) 533 TRACE((" position %d,%d%s%s\n", hints->y, hints->x, 534 hints->flags & USPosition ? " user" : "", 535 hints->flags & PPosition ? " prog" : "")); 536 if (hints->flags & (USSize | PSize)) 537 TRACE((" size %d,%d%s%s\n", hints->height, hints->width, 538 hints->flags & USSize ? " user" : "", 539 hints->flags & PSize ? " prog" : "")); 540 if (hints->flags & PMinSize) 541 TRACE((" min %d,%d\n", hints->min_height, hints->min_width)); 542 if (hints->flags & PMaxSize) 543 TRACE((" max %d,%d\n", hints->max_height, hints->max_width)); 544 if (hints->flags & PResizeInc) 545 TRACE((" inc %d,%d\n", hints->height_inc, hints->width_inc)); 546 else 547 TRACE((" inc NONE!\n")); 548 if (hints->flags & PAspect) 549 TRACE((" min aspect %d/%d\n", hints->min_aspect.y, hints->min_aspect.y)); 550 if (hints->flags & PAspect) 551 TRACE((" max aspect %d/%d\n", hints->max_aspect.y, hints->max_aspect.y)); 552 if (hints->flags & PBaseSize) 553 TRACE((" base %d,%d\n", hints->base_height, hints->base_width)); 554 if (hints->flags & PWinGravity) 555 TRACE((" gravity %d\n", hints->win_gravity)); 556} 557 558void 559TraceWMSizeHints(XtermWidget xw) 560{ 561 XSizeHints sizehints = xw->hints; 562 563 getXtermSizeHints(xw); 564 TraceSizeHints(&xw->hints); 565 xw->hints = sizehints; 566} 567 568/* 569 * Some calls to XGetAtom() will fail, and we don't want to stop. So we use 570 * our own error-handler. 571 */ 572/* ARGSUSED */ 573static int 574no_error(Display * dpy GCC_UNUSED, XErrorEvent * event GCC_UNUSED) 575{ 576 return 1; 577} 578 579void 580TraceTranslations(const char *name, Widget w) 581{ 582 String result; 583 XErrorHandler save = XSetErrorHandler(no_error); 584 XtTranslations xlations; 585 Widget xcelerat; 586 587 TRACE(("TraceTranslations for %s (widget %#lx) {{\n", name, (long) w)); 588 if (w) { 589 XtVaGetValues(w, 590 XtNtranslations, &xlations, 591 XtNaccelerators, &xcelerat, 592 (XtPointer) 0); 593 TRACE(("... xlations %#08lx\n", (long) xlations)); 594 TRACE(("... xcelerat %#08lx\n", (long) xcelerat)); 595 result = _XtPrintXlations(w, xlations, xcelerat, True); 596 TRACE(("%s\n", NonNull(result))); 597 if (result) 598 XFree((char *) result); 599 } else { 600 TRACE(("none (widget is null)\n")); 601 } 602 TRACE(("}}\n")); 603 XSetErrorHandler(save); 604} 605 606int 607TraceResizeRequest(const char *fn, int ln, Widget w, 608 unsigned reqwide, 609 unsigned reqhigh, 610 Dimension * gotwide, 611 Dimension * gothigh) 612{ 613 int rc; 614 615 TRACE(("%s@%d ResizeRequest %ux%u\n", fn, ln, reqhigh, reqwide)); 616 rc = XtMakeResizeRequest((Widget) w, reqwide, reqhigh, gotwide, gothigh); 617 TRACE(("... ResizeRequest -> ")); 618 if (gothigh && gotwide) 619 TRACE(("%dx%d ", *gothigh, *gotwide)); 620 TRACE(("(%d)\n", rc)); 621 return rc; 622} 623 624#define XRES_S(name) Trace(#name " = %s\n", NonNull(resp->name)) 625#define XRES_B(name) Trace(#name " = %s\n", BtoS(resp->name)) 626#define XRES_I(name) Trace(#name " = %d\n", resp->name) 627 628void 629TraceXtermResources(void) 630{ 631 XTERM_RESOURCE *resp = &resource; 632 633 Trace("XTERM_RESOURCE settings:\n"); 634 XRES_S(icon_geometry); 635 XRES_S(title); 636 XRES_S(icon_name); 637 XRES_S(term_name); 638 XRES_S(tty_modes); 639 XRES_I(minBufSize); 640 XRES_I(maxBufSize); 641 XRES_B(hold_screen); 642 XRES_B(utmpInhibit); 643 XRES_B(utmpDisplayId); 644 XRES_B(messages); 645 XRES_S(menuLocale); 646 XRES_S(omitTranslation); 647 XRES_S(keyboardType); 648#if OPT_PRINT_ON_EXIT 649 XRES_I(printModeNow); 650 XRES_I(printModeOnXError); 651 XRES_I(printOptsNow); 652 XRES_I(printOptsOnXError); 653 XRES_S(printFileNow); 654 XRES_S(printFileOnXError); 655#endif 656#if OPT_SUNPC_KBD 657 XRES_B(sunKeyboard); 658#endif 659#if OPT_HP_FUNC_KEYS 660 XRES_B(hpFunctionKeys); 661#endif 662#if OPT_SCO_FUNC_KEYS 663 XRES_B(scoFunctionKeys); 664#endif 665#if OPT_SUN_FUNC_KEYS 666 XRES_B(sunFunctionKeys); 667#endif 668#if OPT_INITIAL_ERASE 669 XRES_B(ptyInitialErase); 670 XRES_B(backarrow_is_erase); 671#endif 672 XRES_B(useInsertMode); 673#if OPT_ZICONBEEP 674 XRES_I(zIconBeep); 675#endif 676#if OPT_PTY_HANDSHAKE 677 XRES_B(wait_for_map); 678 XRES_B(ptyHandshake); 679 XRES_B(ptySttySize); 680#endif 681#if OPT_SAME_NAME 682 XRES_B(sameName); 683#endif 684#if OPT_SESSION_MGT 685 XRES_B(sessionMgt); 686#endif 687#if OPT_TOOLBAR 688 XRES_B(toolBar); 689#endif 690#if OPT_MAXIMIZE 691 XRES_B(maximized); 692 XRES_S(fullscreen_s); 693#endif 694} 695 696void 697TraceArgv(const char *tag, char **argv) 698{ 699 int n = 0; 700 701 TRACE(("%s:\n", tag)); 702 while (*argv != 0) { 703 TRACE((" %d:%s\n", n++, *argv++)); 704 } 705} 706 707static char * 708parse_option(char *dst, String src, int first) 709{ 710 char *s; 711 712 if (!strncmp(src, "-/+", (size_t) 3)) { 713 dst[0] = (char) first; 714 strcpy(dst + 1, src + 3); 715 } else { 716 strcpy(dst, src); 717 } 718 for (s = dst; *s != '\0'; s++) { 719 if (*s == '#' || *s == '%' || *s == 'S') { 720 s[1] = '\0'; 721 } else if (*s == ' ') { 722 *s = '\0'; 723 break; 724 } 725 } 726 return dst; 727} 728 729static Bool 730same_option(OptionHelp * opt, XrmOptionDescRec * res) 731{ 732 char temp[BUFSIZ]; 733 return !strcmp(parse_option(temp, opt->opt, res->option[0]), res->option); 734} 735 736static Bool 737standard_option(String opt) 738{ 739 static const char *table[] = 740 { 741 "+rv", 742 "+synchronous", 743 "-background", 744 "-bd", 745 "-bg", 746 "-bordercolor", 747 "-borderwidth", 748 "-bw", 749 "-display", 750 "-fg", 751 "-fn", 752 "-font", 753 "-foreground", 754 "-geometry", 755 "-iconic", 756 "-name", 757 "-reverse", 758 "-rv", 759 "-selectionTimeout", 760 "-synchronous", 761 "-title", 762 "-xnllanguage", 763 "-xrm", 764 "-xtsessionID", 765 }; 766 Cardinal n; 767 char temp[BUFSIZ]; 768 769 opt = parse_option(temp, opt, '-'); 770 for (n = 0; n < XtNumber(table); n++) { 771 if (!strcmp(opt, table[n])) 772 return True; 773 } 774 return False; 775} 776 777/* 778 * Analyse the options/help messages for inconsistencies. 779 */ 780void 781TraceOptions(OptionHelp * options, XrmOptionDescRec * resources, Cardinal res_count) 782{ 783 OptionHelp *opt_array = sortedOpts(options, resources, res_count); 784 size_t j, k; 785 XrmOptionDescRec *res_array = sortedOptDescs(resources, res_count); 786 Bool first, found; 787 788 TRACE(("Checking options-tables for inconsistencies:\n")); 789 790#if 0 791 TRACE(("Options listed in help-message:\n")); 792 for (j = 0; options[j].opt != 0; j++) 793 TRACE(("%5d %-28s %s\n", j, opt_array[j].opt, opt_array[j].desc)); 794 TRACE(("Options listed in resource-table:\n")); 795 for (j = 0; j < res_count; j++) 796 TRACE(("%5d %-28s %s\n", j, res_array[j].option, res_array[j].specifier)); 797#endif 798 799 /* list all options[] not found in resources[] */ 800 for (j = 0, first = True; options[j].opt != 0; j++) { 801 found = False; 802 for (k = 0; k < res_count; k++) { 803 if (same_option(&opt_array[j], &res_array[k])) { 804 found = True; 805 break; 806 } 807 } 808 if (!found) { 809 if (first) { 810 TRACE(("Options listed in help, not found in resource list:\n")); 811 first = False; 812 } 813 TRACE((" %-28s%s\n", opt_array[j].opt, 814 standard_option(opt_array[j].opt) ? " (standard)" : "")); 815 } 816 } 817 818 /* list all resources[] not found in options[] */ 819 for (j = 0, first = True; j < res_count; j++) { 820 found = False; 821 for (k = 0; options[k].opt != 0; k++) { 822 if (same_option(&opt_array[k], &res_array[j])) { 823 found = True; 824 break; 825 } 826 } 827 if (!found) { 828 if (first) { 829 TRACE(("Resource list items not found in options-help:\n")); 830 first = False; 831 } 832 TRACE((" %s\n", res_array[j].option)); 833 } 834 } 835 836 TRACE(("Resource list items that will be ignored by XtOpenApplication:\n")); 837 for (j = 0; j < res_count; j++) { 838 switch (res_array[j].argKind) { 839 case XrmoptionSkipArg: 840 TRACE((" %-28s {param}\n", res_array[j].option)); 841 break; 842 case XrmoptionSkipNArgs: 843 TRACE((" %-28s {%ld params}\n", res_array[j].option, (long) 844 res_array[j].value)); 845 break; 846 case XrmoptionSkipLine: 847 TRACE((" %-28s {remainder of line}\n", res_array[j].option)); 848 break; 849 case XrmoptionIsArg: 850 case XrmoptionNoArg: 851 case XrmoptionResArg: 852 case XrmoptionSepArg: 853 case XrmoptionStickyArg: 854 default: 855 break; 856 } 857 } 858} 859#else 860extern void empty_trace(void); 861void 862empty_trace(void) 863{ 864} 865#endif 866