"Fossies" - the Fresh Open Source Software Archive

Member "xterm-379/trace.c" (6 Oct 2022, 33783 Bytes) of package /linux/misc/xterm-379.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "trace.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 373_vs_374.

    1 /* $XTermId: trace.c,v 1.239 2022/10/06 20:43:02 tom Exp $ */
    2 
    3 /*
    4  * Copyright 1997-2021,2022 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  * debugging support via TRACE macro.
   35  */
   36 
   37 #include <xterm.h>      /* for definition of GCC_UNUSED */
   38 #include <xstrings.h>
   39 #include <wcwidth.h>
   40 #include <version.h>
   41 
   42 #if OPT_TRACE
   43 
   44 #include <data.h>
   45 #include <trace.h>
   46 
   47 #include <time.h>
   48 #include <stdlib.h>
   49 #include <unistd.h>
   50 #include <sys/types.h>
   51 #include <sys/stat.h>
   52 #include <stdio.h>
   53 #include <assert.h>
   54 
   55 #include <X11/Xatom.h>
   56 #include <X11/Xmu/Atoms.h>
   57 #include <X11/Xmu/Error.h>
   58 
   59 #ifdef HAVE_X11_TRANSLATEI_H
   60 #include <X11/ConvertI.h>
   61 #include <X11/TranslateI.h>
   62 #else
   63 #ifdef __cplusplus
   64 extern "C" {
   65 #endif
   66 
   67     extern String _XtPrintXlations(Widget w,
   68                    XtTranslations xlations,
   69                    Widget accelWidget,
   70                    _XtBoolean includeRHS);
   71 #ifdef __cplusplus
   72 }
   73 #endif
   74 #endif
   75 const char *trace_who = "parent";
   76 
   77 static FILE *trace_fp;
   78 
   79 static FILE *
   80 TraceOpen(void)
   81 {
   82     static const char *trace_out;
   83 
   84     if (trace_fp != 0
   85     && trace_who != trace_out) {
   86     fclose(trace_fp);
   87     trace_fp = 0;
   88     }
   89     trace_out = trace_who;
   90 
   91     if (!trace_fp) {
   92     static char dot[] = ".";
   93     mode_t oldmask = umask(077);
   94     char *home;
   95     char *name;
   96     /*
   97      * Put the trace-file in user's home-directory if the current
   98      * directory is not writable.
   99      */
  100     home = ((access(dot, R_OK | W_OK) == 0)
  101         ? dot
  102         : getenv("HOME"));
  103     if (home != NULL &&
  104         (name = malloc(strlen(home) + strlen(trace_who) + 50)) != NULL) {
  105 #if OPT_TRACE_UNIQUE        /* usually I do not want unique names */
  106         int unique;
  107         for (unique = 0;; ++unique) {
  108         if (unique)
  109             sprintf(name, "%s/Trace-%s.out-%d", home, trace_who, unique);
  110         else
  111             sprintf(name, "%s/Trace-%s.out", home, trace_who);
  112         if ((trace_fp = fopen(name, "r")) == 0) {
  113             break;
  114         }
  115         fclose(trace_fp);
  116         }
  117 #else
  118         sprintf(name, "%s/Trace-%s.out", home, trace_who);
  119 #endif
  120         trace_fp = fopen(name, "w");
  121         if (trace_fp != 0) {
  122         fprintf(trace_fp, "%s\n", xtermVersion());
  123         TraceIds(NULL, 0);
  124         }
  125         if (!trace_fp) {
  126         xtermWarning("Cannot open \"%s\"\n", name);
  127         exit(EXIT_FAILURE);
  128         }
  129         (void) umask(oldmask);
  130         free(name);
  131     }
  132     }
  133     return trace_fp;
  134 }
  135 
  136 void
  137 Trace(const char *fmt, ...)
  138 {
  139     va_list ap;
  140     FILE *fp = TraceOpen();
  141 
  142     va_start(ap, fmt);
  143     vfprintf(fp, fmt, ap);
  144     (void) fflush(fp);
  145     va_end(ap);
  146 }
  147 
  148 void
  149 TraceVA(const char *fmt, va_list ap)
  150 {
  151     FILE *fp = TraceOpen();
  152 
  153     vfprintf(fp, fmt, ap);
  154     (void) fflush(fp);
  155 }
  156 
  157 void
  158 TraceClose(void)
  159 {
  160     if (trace_fp != 0) {
  161     (void) fclose(trace_fp);
  162     (void) fflush(stdout);
  163     (void) fflush(stderr);
  164     (void) visibleChars(NULL, 0);
  165     (void) visibleIChars(NULL, 0);
  166     trace_fp = 0;
  167     }
  168 }
  169 
  170 void
  171 TraceXError(Display *d, XErrorEvent *ev)
  172 {
  173     FILE *fp = TraceOpen();
  174     (void) XmuPrintDefaultErrorMessage(d, ev, fp);
  175     (void) fflush(fp);
  176 }
  177 
  178 void
  179 TraceIds(const char *fname, int lnum)
  180 {
  181     Trace("process %d ", (int) getpid());
  182 #ifdef HAVE_UNISTD_H
  183     Trace("real (%u/%u) effective (%u/%u)",
  184       (unsigned) getuid(), (unsigned) getgid(),
  185       (unsigned) geteuid(), (unsigned) getegid());
  186 #endif
  187     if (fname != 0) {
  188     Trace(" (%s@%d)\n", fname, lnum);
  189     } else {
  190     time_t now = time((time_t *) 0);
  191     Trace("-- %s", ctime(&now));
  192     }
  193 }
  194 
  195 void
  196 TraceTime(const char *fname, int lnum)
  197 {
  198     time_t now;
  199     if (fname != 0) {
  200     Trace("datetime (%s@%d) ", fname, lnum);
  201     }
  202     now = time((time_t *) 0);
  203     Trace("-- %s", ctime(&now));
  204 }
  205 
  206 static void
  207 formatAscii(char *dst, unsigned value)
  208 {
  209     switch (value) {
  210     case '\\':
  211     sprintf(dst, "\\\\");
  212     break;
  213     case '\b':
  214     sprintf(dst, "\\b");
  215     break;
  216     case '\n':
  217     sprintf(dst, "\\n");
  218     break;
  219     case '\r':
  220     sprintf(dst, "\\r");
  221     break;
  222     case '\t':
  223     sprintf(dst, "\\t");
  224     break;
  225     default:
  226     if (E2A(value) < 32 || (E2A(value) >= 127 && E2A(value) < 160))
  227         sprintf(dst, "\\%03o", value & 0xff);
  228     else
  229         sprintf(dst, "%c", CharOf(value));
  230     break;
  231     }
  232 }
  233 
  234 #if OPT_DEC_CHRSET
  235 
  236 const char *
  237 visibleDblChrset(unsigned chrset)
  238 {
  239     const char *result = "?";
  240     switch (chrset) {
  241     case CSET_SWL:
  242     result = "CSET_SWL";
  243     break;
  244     case CSET_DHL_TOP:
  245     result = "CSET_DHL_TOP";
  246     break;
  247     case CSET_DHL_BOT:
  248     result = "CSET_DHL_BOT";
  249     break;
  250     case CSET_DWL:
  251     result = "CSET_DWL";
  252     break;
  253     }
  254     return result;
  255 }
  256 #endif
  257 
  258 const char *
  259 visibleScsCode(DECNRCM_codes chrset)
  260 {
  261 #define MAP(to,from) case from: result = to ":" #from; break
  262     const char *result = "<ERR>";
  263     switch ((DECNRCM_codes) chrset) {
  264     MAP("B", nrc_ASCII);
  265     MAP("A", nrc_British);
  266     MAP("A", nrc_British_Latin_1);
  267     MAP("&4", nrc_DEC_Cyrillic);
  268     MAP("0", nrc_DEC_Spec_Graphic);
  269     MAP("1", nrc_DEC_Alt_Chars);
  270     MAP("2", nrc_DEC_Alt_Graphics);
  271     MAP("<", nrc_DEC_Supp);
  272     MAP("%5", nrc_DEC_Supp_Graphic);
  273     MAP(">", nrc_DEC_Technical);
  274     MAP("4", nrc_Dutch);
  275     MAP("5", nrc_Finnish);
  276     MAP("C", nrc_Finnish2);
  277     MAP("R", nrc_French);
  278     MAP("f", nrc_French2);
  279     MAP("Q", nrc_French_Canadian);
  280     MAP("9", nrc_French_Canadian2);
  281     MAP("K", nrc_German);
  282     MAP("\"?", nrc_DEC_Greek_Supp);
  283     MAP("\">", nrc_Greek);
  284     MAP("F", nrc_ISO_Greek_Supp);
  285     MAP("\"4", nrc_DEC_Hebrew_Supp);
  286     MAP("%=", nrc_Hebrew);
  287     MAP("H", nrc_ISO_Hebrew_Supp);
  288     MAP("Y", nrc_Italian);
  289     MAP("A", nrc_ISO_Latin_1_Supp);
  290     MAP("B", nrc_ISO_Latin_2_Supp);
  291     MAP("M", nrc_ISO_Latin_5_Supp);
  292     MAP("L", nrc_ISO_Latin_Cyrillic);
  293     MAP("`", nrc_Norwegian_Danish);
  294     MAP("E", nrc_Norwegian_Danish2);
  295     MAP("6", nrc_Norwegian_Danish3);
  296     MAP("%6", nrc_Portugese);
  297     MAP("&5", nrc_Russian);
  298     MAP("%3", nrc_SCS_NRCS);
  299     MAP("Z", nrc_Spanish);
  300     MAP("7", nrc_Swedish);
  301     MAP("H", nrc_Swedish2);
  302     MAP("=", nrc_Swiss);
  303     MAP("%2", nrc_Turkish);
  304     MAP("%0", nrc_DEC_Turkish_Supp);
  305     MAP("<UNK>", nrc_Unknown);
  306     }
  307 #undef MAP
  308     return result;
  309 }
  310 
  311 const char *
  312 visibleChars(const Char *buf, size_t len)
  313 {
  314     static char *result;
  315     static size_t used;
  316 
  317     if (buf != 0) {
  318     size_t limit = ((len + 1) * 8) + 1;
  319 
  320     if (limit > used) {
  321         used = limit;
  322         result = realloc(result, used);
  323     }
  324     if (result != 0) {
  325         char *dst = result;
  326         *dst = '\0';
  327         while (len--) {
  328         unsigned value = *buf++;
  329         formatAscii(dst, value);
  330         dst += strlen(dst);
  331         }
  332     }
  333     } else {
  334     FreeAndNull(result);
  335     used = 0;
  336     }
  337     return NonNull(result);
  338 }
  339 
  340 const char *
  341 visibleEventMode(EventMode value)
  342 {
  343     const char *result;
  344     switch (value) {
  345     case NORMAL:
  346     result = "NORMAL";
  347     break;
  348     case LEFTEXTENSION:
  349     result = "LEFTEXTENSION";
  350     break;
  351     case RIGHTEXTENSION:
  352     result = "RIGHTEXTENSION";
  353     break;
  354     default:
  355     result = "?";
  356     break;
  357     }
  358     return result;
  359 }
  360 
  361 const char *
  362 visibleIChars(const IChar *buf, size_t len)
  363 {
  364     static char *result;
  365     static size_t used;
  366 
  367     if (buf != 0) {
  368     size_t limit = ((len + 1) * 12) + 1;
  369 
  370     if (limit > used) {
  371         used = limit;
  372         result = realloc(result, used);
  373     }
  374     if (result != 0) {
  375         char *dst = result;
  376         *dst = '\0';
  377         while (len--) {
  378         unsigned value = *buf++;
  379 #if OPT_WIDE_CHARS
  380         if (value > 255)
  381             sprintf(dst, "\\U+%04X", value);
  382         else
  383 #endif
  384             formatAscii(dst, value);
  385         dst += strlen(dst);
  386         }
  387     }
  388     } else {
  389     FreeAndNull(result);
  390     used = 0;
  391     }
  392     return NonNull(result);
  393 }
  394 
  395 const char *
  396 visibleUChar(unsigned chr)
  397 {
  398     IChar buf[1];
  399     buf[0] = (IChar) chr;
  400     return visibleIChars(buf, 1);
  401 }
  402 
  403 const char *
  404 visibleEventType(int type)
  405 {
  406     const char *result = "?";
  407     switch (type) {
  408     CASETYPE(KeyPress);
  409     CASETYPE(KeyRelease);
  410     CASETYPE(ButtonPress);
  411     CASETYPE(ButtonRelease);
  412     CASETYPE(MotionNotify);
  413     CASETYPE(EnterNotify);
  414     CASETYPE(LeaveNotify);
  415     CASETYPE(FocusIn);
  416     CASETYPE(FocusOut);
  417     CASETYPE(KeymapNotify);
  418     CASETYPE(Expose);
  419     CASETYPE(GraphicsExpose);
  420     CASETYPE(NoExpose);
  421     CASETYPE(VisibilityNotify);
  422     CASETYPE(CreateNotify);
  423     CASETYPE(DestroyNotify);
  424     CASETYPE(UnmapNotify);
  425     CASETYPE(MapNotify);
  426     CASETYPE(MapRequest);
  427     CASETYPE(ReparentNotify);
  428     CASETYPE(ConfigureNotify);
  429     CASETYPE(ConfigureRequest);
  430     CASETYPE(GravityNotify);
  431     CASETYPE(ResizeRequest);
  432     CASETYPE(CirculateNotify);
  433     CASETYPE(CirculateRequest);
  434     CASETYPE(PropertyNotify);
  435     CASETYPE(SelectionClear);
  436     CASETYPE(SelectionRequest);
  437     CASETYPE(SelectionNotify);
  438     CASETYPE(ColormapNotify);
  439     CASETYPE(ClientMessage);
  440     CASETYPE(MappingNotify);
  441     }
  442     return result;
  443 }
  444 
  445 const char *
  446 visibleMappingMode(int code)
  447 {
  448     const char *result = "?";
  449     switch (code) {
  450     CASETYPE(MappingModifier);
  451     CASETYPE(MappingKeyboard);
  452     CASETYPE(MappingPointer);
  453     }
  454     return result;
  455 }
  456 
  457 const char *
  458 visibleNotifyMode(int code)
  459 {
  460     const char *result = "?";
  461     switch (code) {
  462     CASETYPE(NotifyNormal);
  463     CASETYPE(NotifyGrab);
  464     CASETYPE(NotifyUngrab);
  465     CASETYPE(NotifyWhileGrabbed);
  466     }
  467     return result;
  468 }
  469 
  470 const char *
  471 visibleNotifyDetail(int code)
  472 {
  473     const char *result = "?";
  474     switch (code) {
  475     CASETYPE(NotifyAncestor);
  476     CASETYPE(NotifyVirtual);
  477     CASETYPE(NotifyInferior);
  478     CASETYPE(NotifyNonlinear);
  479     CASETYPE(NotifyNonlinearVirtual);
  480     CASETYPE(NotifyPointer);
  481     CASETYPE(NotifyPointerRoot);
  482     CASETYPE(NotifyDetailNone);
  483     }
  484     return result;
  485 }
  486 
  487 const char *
  488 visibleSelectionTarget(Display *d, Atom a)
  489 {
  490     const char *result = "?";
  491 
  492     if (a == XA_STRING) {
  493     result = "XA_STRING";
  494     } else if (a == XA_TEXT(d)) {
  495     result = "XA_TEXT()";
  496     } else if (a == XA_COMPOUND_TEXT(d)) {
  497     result = "XA_COMPOUND_TEXT()";
  498     } else if (a == XA_UTF8_STRING(d)) {
  499     result = "XA_UTF8_STRING()";
  500     } else if (a == XA_TARGETS(d)) {
  501     result = "XA_TARGETS()";
  502     }
  503 
  504     return result;
  505 }
  506 
  507 #if OPT_TEK4014
  508 const char *
  509 visibleTekparse(int code)
  510 {
  511     static const struct {
  512     int code;
  513     const char *name;
  514     } table[] = {
  515 #include "Tekparse.cin"
  516     };
  517     const char *result = "?";
  518     Cardinal n;
  519     for (n = 0; n < XtNumber(table); ++n) {
  520     if (table[n].code == code) {
  521         result = table[n].name;
  522         break;
  523     }
  524     }
  525     return result;
  526 }
  527 #endif
  528 
  529 const char *
  530 visibleVTparse(int code)
  531 {
  532     static const struct {
  533     int code;
  534     const char *name;
  535     } table[] = {
  536 #include "VTparse.cin"
  537     };
  538     const char *result = "?";
  539     Cardinal n;
  540     for (n = 0; n < XtNumber(table); ++n) {
  541     if (table[n].code == code) {
  542         result = table[n].name;
  543         break;
  544     }
  545     }
  546     return result;
  547 }
  548 
  549 const char *
  550 visibleXError(int code)
  551 {
  552     static char temp[80];
  553     const char *result = "?";
  554     switch (code) {
  555     CASETYPE(Success);
  556     CASETYPE(BadRequest);
  557     CASETYPE(BadValue);
  558     CASETYPE(BadWindow);
  559     CASETYPE(BadPixmap);
  560     CASETYPE(BadAtom);
  561     CASETYPE(BadCursor);
  562     CASETYPE(BadFont);
  563     CASETYPE(BadMatch);
  564     CASETYPE(BadDrawable);
  565     CASETYPE(BadAccess);
  566     CASETYPE(BadAlloc);
  567     CASETYPE(BadColor);
  568     CASETYPE(BadGC);
  569     CASETYPE(BadIDChoice);
  570     CASETYPE(BadName);
  571     CASETYPE(BadLength);
  572     CASETYPE(BadImplementation);
  573     default:
  574     sprintf(temp, "%d", code);
  575     result = temp;
  576     break;
  577     }
  578     return result;
  579 }
  580 
  581 #if OPT_TRACE_FLAGS
  582 #define isScrnFlag(flag) ((flag) == LINEWRAPPED)
  583 
  584 static char *
  585 ScrnText(LineData *ld)
  586 {
  587     return visibleIChars(ld->charData, ld->lineSize);
  588 }
  589 
  590 #define SHOW_BAD_LINE(name, ld) \
  591     Trace("OOPS " #name " bad row\n")
  592 
  593 #define SHOW_SCRN_FLAG(name,code) \
  594     Trace(#name " %s:%s\n", \
  595           code ? "*" : "", \
  596           ScrnText(ld))
  597 
  598 void
  599 LineClrFlag(LineData *ld, int flag)
  600 {
  601     if (ld == 0) {
  602     SHOW_BAD_LINE(LineClrFlag, ld);
  603     assert(0);
  604     } else if (isScrnFlag(flag)) {
  605     SHOW_SCRN_FLAG(LineClrFlag, 0);
  606     }
  607 
  608     LineFlags(ld) &= ~flag;
  609 }
  610 
  611 void
  612 LineSetFlag(LineData *ld, int flag)
  613 {
  614     if (ld == 0) {
  615     SHOW_BAD_LINE(LineSetFlag, ld);
  616     assert(0);
  617     } else if (isScrnFlag(flag)) {
  618     SHOW_SCRN_FLAG(LineSetFlag, 1);
  619     }
  620 
  621     LineFlags(ld) |= flag;
  622 }
  623 
  624 int
  625 LineTstFlag(LineData ld, int flag)
  626 {
  627     int code = 0;
  628     if (ld == 0) {
  629     SHOW_BAD_LINE(LineTstFlag, ld);
  630     } else {
  631     code = LineFlags(ld);
  632 
  633     if (isScrnFlag(flag)) {
  634         SHOW_SCRN_FLAG(LineTstFlag, code);
  635     }
  636     }
  637     return code;
  638 }
  639 #endif /* OPT_TRACE_FLAGS */
  640 
  641 const char *
  642 TraceAtomName(Display *dpy, Atom atom)
  643 {
  644     static char *result;
  645     free(result);
  646     if (atom != 0) {
  647     result = XGetAtomName(dpy, atom);
  648     } else {
  649     result = x_strdup("NONE");
  650     }
  651     return result;
  652 }
  653 
  654 /*
  655  * Trace the normal or alternate screen, showing color values up to 16, e.g.,
  656  * for debugging with vttest.
  657  */
  658 void
  659 TraceScreen(XtermWidget xw, int whichBuf)
  660 {
  661     TScreen *screen = TScreenOf(xw);
  662 
  663     if (screen->editBuf_index[whichBuf]) {
  664     int row;
  665 
  666     TRACE(("TraceScreen %d:\n", whichBuf));
  667     for (row = 0; row <= LastRowNumber(screen); ++row) {
  668         LineData *ld = getLineData(screen, row);
  669 
  670         TRACE((" %3d:", row));
  671         if (ld != 0) {
  672         int col;
  673 
  674         for (col = 0; col < ld->lineSize; ++col) {
  675             int ch = (int) ld->charData[col];
  676             if (ch < ' ')
  677             ch = ' ';
  678             if (ch >= 127)
  679             ch = '#';
  680             TRACE(("%c", ch));
  681         }
  682         TRACE((":\n"));
  683 
  684 #if 0
  685         TRACE(("  xx:"));
  686         for (col = 0; col < ld->lineSize; ++col) {
  687             unsigned attrs = ld->attribs[col];
  688             char ch;
  689             if (attrs & PROTECTED) {
  690             ch = '*';
  691             } else if (attrs & BLINK) {
  692             ch = 'B';
  693             } else if (attrs & CHARDRAWN) {
  694             ch = '+';
  695             } else {
  696             ch = ' ';
  697             }
  698             TRACE(("%c", ch));
  699         }
  700         TRACE((":\n"));
  701 #endif
  702 
  703 #if 0
  704         TRACE(("  fg:"));
  705         for (col = 0; col < ld->lineSize; ++col) {
  706             unsigned fg = extract_fg(xw, ld->color[col], ld->attribs[col]);
  707             if (fg > 15)
  708             fg = 15;
  709             TRACE(("%1x", fg));
  710         }
  711         TRACE((":\n"));
  712 
  713         TRACE(("  bg:"));
  714         for (col = 0; col < ld->lineSize; ++col) {
  715             unsigned bg = extract_bg(xw, ld->color[col], ld->attribs[col]);
  716             if (bg > 15)
  717             bg = 15;
  718             TRACE(("%1x", bg));
  719         }
  720         TRACE((":\n"));
  721 #endif
  722         } else {
  723         TRACE(("null lineData\n"));
  724         }
  725     }
  726     } else {
  727     TRACE(("TraceScreen %d is nil\n", whichBuf));
  728     }
  729 }
  730 
  731 static char *
  732 formatEventMask(char *target, unsigned source, Boolean buttons)
  733 {
  734 #define DATA(name) { name ## Mask, #name }
  735     static struct {
  736     unsigned mask;
  737     const char *name;
  738     } table[] = {
  739     DATA(Shift),
  740         DATA(Lock),
  741         DATA(Control),
  742         DATA(Mod1),
  743         DATA(Mod2),
  744         DATA(Mod3),
  745         DATA(Mod4),
  746         DATA(Mod5),
  747         DATA(Button1),
  748         DATA(Button2),
  749         DATA(Button3),
  750         DATA(Button4),
  751         DATA(Button5),
  752     };
  753 #undef DATA
  754     Cardinal n;
  755     char marker = L_CURL;
  756     char *base = target;
  757 
  758     for (n = 0; n < XtNumber(table); ++n) {
  759     if (!buttons && (table[n].mask >= Button1Mask))
  760         continue;
  761     if ((table[n].mask & source)) {
  762         UIntClr(source, table[n].mask);
  763         sprintf(target, "%c%s", marker, table[n].name);
  764         target += strlen(target);
  765         marker = '|';
  766     }
  767     }
  768 
  769     if (source != 0) {
  770     sprintf(target, "%c?%#x", marker, source);
  771     target += strlen(target);
  772     marker = '|';
  773     }
  774 
  775     if (marker == L_CURL)
  776     *target++ = L_CURL;
  777     *target++ = R_CURL;
  778 
  779     *target = '\0';
  780     return base;
  781 }
  782 
  783 void
  784 TraceEvent(const char *tag, XEvent *ev, String *params, Cardinal *num_params)
  785 {
  786     char mask_buffer[160];
  787 
  788     TRACE(("Event #%lu %s: %#lx %s",
  789        ev->xany.serial,
  790        tag,
  791        ev->xany.window,
  792        visibleEventType(ev->type)));
  793 
  794     switch (ev->type) {
  795     case KeyPress:
  796     /* FALLTHRU */
  797     case KeyRelease:
  798     TRACE((" keycode 0x%04X %s",
  799            ev->xkey.keycode,
  800            formatEventMask(mask_buffer, ev->xkey.state, False)));
  801     break;
  802     case ButtonPress:
  803     /* FALLTHRU */
  804     case ButtonRelease:
  805     TRACE((" button %u state %#x %s",
  806            ev->xbutton.button,
  807            ev->xbutton.state,
  808            formatEventMask(mask_buffer, ev->xbutton.state, True)));
  809     break;
  810     case MotionNotify:
  811     TRACE((" (%d,%d) state %#x %s",
  812            ev->xmotion.y_root,
  813            ev->xmotion.x_root,
  814            ev->xmotion.state,
  815            formatEventMask(mask_buffer, ev->xmotion.state, True)));
  816     break;
  817     case EnterNotify:
  818     case LeaveNotify:
  819     TRACE((" at %d,%d root %d,%d %s %s",
  820            ev->xcrossing.y,
  821            ev->xcrossing.x,
  822            ev->xcrossing.y_root,
  823            ev->xcrossing.x_root,
  824            visibleNotifyMode(ev->xcrossing.mode),
  825            visibleNotifyDetail(ev->xcrossing.detail)));
  826     break;
  827     case FocusIn:
  828     case FocusOut:
  829     TRACE((" %s %s",
  830            visibleNotifyMode(ev->xfocus.mode),
  831            visibleNotifyDetail(ev->xfocus.detail)));
  832     break;
  833     case MapNotify:
  834     TRACE((" event %#lx %s",
  835            ev->xmap.event,
  836            ev->xmap.override_redirect ? "override" : ""));
  837     break;
  838     case UnmapNotify:
  839     TRACE((" event %#lx %s",
  840            ev->xunmap.event,
  841            ev->xunmap.from_configure ? "configure" : ""));
  842     break;
  843     case ReparentNotify:
  844     TRACE((" at %d,%d event %#lx parent %#lx %s",
  845            ev->xreparent.y,
  846            ev->xreparent.x,
  847            ev->xreparent.event,
  848            ev->xreparent.parent,
  849            ev->xreparent.override_redirect ? "override" : ""));
  850     break;
  851     case ConfigureNotify:
  852     TRACE((" at %d,%d size %dx%d bd %d above %#lx",
  853            ev->xconfigure.y,
  854            ev->xconfigure.x,
  855            ev->xconfigure.height,
  856            ev->xconfigure.width,
  857            ev->xconfigure.border_width,
  858            ev->xconfigure.above));
  859     break;
  860     case CreateNotify:
  861     TRACE((" at %d,%d size %dx%d bd %d",
  862            ev->xcreatewindow.y,
  863            ev->xcreatewindow.x,
  864            ev->xcreatewindow.height,
  865            ev->xcreatewindow.width,
  866            ev->xcreatewindow.border_width));
  867     break;
  868     case ResizeRequest:
  869     TRACE((" size %dx%d",
  870            ev->xresizerequest.height,
  871            ev->xresizerequest.width));
  872     break;
  873     case PropertyNotify:
  874     TRACE((" %s %s",
  875            TraceAtomName(XtDisplay(toplevel), ev->xproperty.atom),
  876            ((ev->xproperty.state == PropertyNewValue)
  877         ? "NewValue"
  878         : ((ev->xproperty.state == PropertyDelete)
  879            ? "Delete"
  880            : "?"))));
  881 
  882     break;
  883     case Expose:
  884     TRACE((" at %d,%d size %dx%d count %d",
  885            ev->xexpose.y,
  886            ev->xexpose.x,
  887            ev->xexpose.height,
  888            ev->xexpose.width,
  889            ev->xexpose.count));
  890     break;
  891     case MappingNotify:
  892     TRACE((" %s first_keycode %d count %d",
  893            visibleMappingMode(ev->xmapping.request),
  894            ev->xmapping.first_keycode,
  895            ev->xmapping.count));
  896     break;
  897     case VisibilityNotify:
  898     TRACE((" state %d",
  899            ev->xvisibility.state));
  900     break;
  901     case KeymapNotify:
  902     {
  903         Cardinal j;
  904         for (j = 0; j < XtNumber(ev->xkeymap.key_vector); ++j) {
  905         if (ev->xkeymap.key_vector[j] != 0) {
  906             Cardinal k;
  907             for (k = 0; k < CHAR_BIT; ++k) {
  908             if (ev->xkeymap.key_vector[j] & (1 << k)) {
  909                 TRACE((" key%u", (j * CHAR_BIT) + k));
  910             }
  911             }
  912         }
  913         }
  914     }
  915     break;
  916     case NoExpose:
  917     TRACE((" send_event:%d display %p major:%d minor:%d",
  918            ev->xnoexpose.send_event,
  919            (void *) ev->xnoexpose.display,
  920            ev->xnoexpose.major_code,
  921            ev->xnoexpose.minor_code));
  922     break;
  923     case GraphicsExpose:
  924     TRACE((" send_event:%d display %p major:%d minor:%d",
  925            ev->xgraphicsexpose.send_event,
  926            (void *) ev->xgraphicsexpose.display,
  927            ev->xgraphicsexpose.major_code,
  928            ev->xgraphicsexpose.minor_code));
  929     break;
  930     case SelectionClear:
  931     TRACE((" selection:%s",
  932            TraceAtomName(ev->xselectionclear.display,
  933                  ev->xselectionclear.selection)));
  934     break;
  935     case SelectionRequest:
  936     TRACE((" owner:%#lx requestor:%#lx",
  937            ev->xselectionrequest.owner,
  938            ev->xselectionrequest.requestor));
  939     TRACE((" selection:%s",
  940            TraceAtomName(ev->xselectionrequest.display,
  941                  ev->xselectionrequest.selection)));
  942     TRACE((" target:%s",
  943            TraceAtomName(ev->xselectionrequest.display,
  944                  ev->xselectionrequest.target)));
  945     TRACE((" property:%s",
  946            TraceAtomName(ev->xselectionrequest.display,
  947                  ev->xselectionrequest.property)));
  948     break;
  949     default:
  950     TRACE((":FIXME"));
  951     break;
  952     }
  953     TRACE(("\n"));
  954     if (params != 0 && *num_params != 0) {
  955     Cardinal n;
  956     for (n = 0; n < *num_params; ++n) {
  957         TRACE(("  param[%d] = %s\n", n, params[n]));
  958     }
  959     }
  960 }
  961 
  962 #if OPT_RENDERFONT && OPT_WIDE_CHARS
  963 void
  964 TraceFallback(XtermWidget xw, const char *tag, unsigned wc, int n, XftFont *font)
  965 {
  966     TScreen *screen = TScreenOf(xw);
  967     XGlyphInfo gi;
  968     int expect = my_wcwidth((wchar_t) wc);
  969     int hijack = mk_wcwidth_cjk((wchar_t) wc);
  970     int actual;
  971 
  972     XftTextExtents32(screen->display, font, &wc, 1, &gi);
  973     actual = ((gi.xOff + FontWidth(screen) - 1)
  974           / FontWidth(screen));
  975 
  976     TRACE(("FALLBACK #%d %s U+%04X %d,%d pos,"
  977        " %d,%d off," " %dx%d size,"
  978        " %d/%d next," " %d vs %d/%d cells%s\n",
  979        n + 1, tag, wc,
  980        gi.y, gi.x,
  981        gi.yOff, gi.xOff,
  982        gi.height, gi.width,
  983        font->max_advance_width,
  984        FontWidth(screen),
  985        actual, expect, hijack,
  986        ((actual != expect)
  987         ? ((actual == hijack)
  988            ? " OOPS"
  989            : " oops")
  990         : "")));
  991 }
  992 #endif /* OPT_RENDERFONT */
  993 
  994 void
  995 TraceFocus(Widget w, XEvent *ev)
  996 {
  997     TRACE(("trace_focus event type %d:%s\n",
  998        ev->type, visibleEventType(ev->type)));
  999     switch (ev->type) {
 1000     case FocusIn:
 1001     case FocusOut:
 1002     {
 1003         XFocusChangeEvent *event = (XFocusChangeEvent *) ev;
 1004         TRACE(("\tdetail: %s\n", visibleNotifyDetail(event->detail)));
 1005         TRACE(("\tmode:   %s\n", visibleNotifyMode(event->mode)));
 1006         TRACE(("\twindow: %#lx\n", event->window));
 1007     }
 1008     break;
 1009     case EnterNotify:
 1010     case LeaveNotify:
 1011     {
 1012         XCrossingEvent *event = (XCrossingEvent *) ev;
 1013         TRACE(("\tdetail:    %s\n", visibleNotifyDetail(event->detail)));
 1014         TRACE(("\tmode:      %s\n", visibleNotifyMode(event->mode)));
 1015         TRACE(("\twindow:    %#lx\n", event->window));
 1016         TRACE(("\tfocus:     %d\n", event->focus));
 1017         TRACE(("\troot:      %#lx\n", event->root));
 1018         TRACE(("\tsubwindow: %#lx\n", event->subwindow));
 1019     }
 1020     break;
 1021     }
 1022     while (w != 0) {
 1023     TRACE(("w %p -> %#lx\n", (void *) w, XtWindow(w)));
 1024     w = XtParent(w);
 1025     }
 1026 }
 1027 
 1028 void
 1029 TraceSizeHints(XSizeHints * hints)
 1030 {
 1031     TRACE(("size hints:\n"));
 1032     if (hints->flags & (USPosition | PPosition)) {
 1033     TRACE(("   position   %d,%d%s%s\n", hints->y, hints->x,
 1034            (hints->flags & USPosition) ? " user" : "",
 1035            (hints->flags & PPosition) ? " prog" : ""));
 1036     }
 1037     if (hints->flags & (USSize | PSize)) {
 1038     TRACE(("   size       %d,%d%s%s\n", hints->height, hints->width,
 1039            (hints->flags & USSize) ? " user" : "",
 1040            (hints->flags & PSize) ? " prog" : ""));
 1041     }
 1042     if (hints->flags & PMinSize) {
 1043     TRACE(("   min        %d,%d\n", hints->min_height, hints->min_width));
 1044     }
 1045     if (hints->flags & PMaxSize) {
 1046     TRACE(("   max        %d,%d\n", hints->max_height, hints->max_width));
 1047     }
 1048     if (hints->flags & PResizeInc) {
 1049     TRACE(("   inc        %d,%d\n", hints->height_inc, hints->width_inc));
 1050     } else {
 1051     TRACE(("   inc        NONE!\n"));
 1052     }
 1053     if (hints->flags & PAspect) {
 1054     TRACE(("   min aspect %d/%d\n", hints->min_aspect.y, hints->min_aspect.y));
 1055     TRACE(("   max aspect %d/%d\n", hints->max_aspect.y, hints->max_aspect.y));
 1056     }
 1057     if (hints->flags & PBaseSize) {
 1058     TRACE(("   base       %d,%d\n", hints->base_height, hints->base_width));
 1059     }
 1060     if (hints->flags & PWinGravity) {
 1061     TRACE(("   gravity    %d\n", hints->win_gravity));
 1062     }
 1063 }
 1064 
 1065 static void
 1066 TraceEventMask(const char *tag, long mask)
 1067 {
 1068 #define DATA(name) { name##Mask, #name }
 1069     /* *INDENT-OFF* */
 1070     static struct {
 1071     long mask;
 1072     const char *name;
 1073     } table[] = {
 1074     DATA(KeyPress),
 1075     DATA(KeyRelease),
 1076     DATA(ButtonPress),
 1077     DATA(ButtonRelease),
 1078     DATA(EnterWindow),
 1079     DATA(LeaveWindow),
 1080     DATA(PointerMotion),
 1081     DATA(PointerMotionHint),
 1082     DATA(Button1Motion),
 1083     DATA(Button2Motion),
 1084     DATA(Button3Motion),
 1085     DATA(Button4Motion),
 1086     DATA(Button5Motion),
 1087     DATA(ButtonMotion),
 1088     DATA(KeymapState),
 1089     DATA(Exposure),
 1090     DATA(VisibilityChange),
 1091     DATA(StructureNotify),
 1092     DATA(ResizeRedirect),
 1093     DATA(SubstructureNotify),
 1094     DATA(SubstructureRedirect),
 1095     DATA(FocusChange),
 1096     DATA(PropertyChange),
 1097     DATA(ColormapChange),
 1098     DATA(OwnerGrabButton),
 1099     };
 1100 #undef DATA
 1101     Cardinal n;
 1102     /* *INDENT-ON* */
 1103 
 1104     for (n = 0; n < XtNumber(table); ++n) {
 1105     if (table[n].mask & mask) {
 1106         TRACE(("%s %s\n", tag, table[n].name));
 1107     }
 1108     }
 1109 }
 1110 
 1111 void
 1112 TraceWindowAttributes(XWindowAttributes * attrs)
 1113 {
 1114     TRACE(("window attributes:\n"));
 1115     TRACE(("   position     %d,%d\n", attrs->y, attrs->x));
 1116     TRACE(("   size         %dx%d\n", attrs->height, attrs->width));
 1117     TRACE(("   border       %d\n", attrs->border_width));
 1118     TRACE(("   depth        %d\n", attrs->depth));
 1119     TRACE(("   bit_gravity  %d\n", attrs->bit_gravity));
 1120     TRACE(("   win_gravity  %d\n", attrs->win_gravity));
 1121     TRACE(("   root         %#lx\n", (long) attrs->root));
 1122     TRACE(("   class        %s\n", ((attrs->class == InputOutput)
 1123                     ? "InputOutput"
 1124                     : ((attrs->class == InputOnly)
 1125                        ? "InputOnly"
 1126                        : "unknown"))));
 1127     TRACE(("   map_state    %s\n", ((attrs->map_state == IsUnmapped)
 1128                     ? "IsUnmapped"
 1129                     : ((attrs->map_state == IsUnviewable)
 1130                        ? "IsUnviewable"
 1131                        : ((attrs->map_state == IsViewable)
 1132                       ? "IsViewable"
 1133                       : "unknown")))));
 1134     TRACE(("   all_events\n"));
 1135     TraceEventMask("        ", attrs->all_event_masks);
 1136     TRACE(("   your_events\n"));
 1137     TraceEventMask("        ", attrs->your_event_mask);
 1138     TRACE(("   no_propagate\n"));
 1139     TraceEventMask("        ", attrs->do_not_propagate_mask);
 1140 }
 1141 
 1142 void
 1143 TraceWMSizeHints(XtermWidget xw)
 1144 {
 1145     XSizeHints sizehints = xw->hints;
 1146 
 1147     getXtermSizeHints(xw);
 1148     TraceSizeHints(&xw->hints);
 1149     xw->hints = sizehints;
 1150 }
 1151 
 1152 const char *
 1153 ModifierName(unsigned modifier)
 1154 {
 1155     const char *s = "";
 1156     if (modifier & ShiftMask)
 1157     s = " Shift";
 1158     else if (modifier & LockMask)
 1159     s = " Lock";
 1160     else if (modifier & ControlMask)
 1161     s = " Control";
 1162     else if (modifier & Mod1Mask)
 1163     s = " Mod1";
 1164     else if (modifier & Mod2Mask)
 1165     s = " Mod2";
 1166     else if (modifier & Mod3Mask)
 1167     s = " Mod3";
 1168     else if (modifier & Mod4Mask)
 1169     s = " Mod4";
 1170     else if (modifier & Mod5Mask)
 1171     s = " Mod5";
 1172     return s;
 1173 }
 1174 
 1175 void
 1176 TraceTranslations(const char *name, Widget w)
 1177 {
 1178     String result;
 1179     XErrorHandler save = XSetErrorHandler(ignore_x11_error);
 1180     XtTranslations xlations;
 1181     Widget xcelerat;
 1182 
 1183     TRACE(("TraceTranslations for %s (widget %#lx) " TRACE_L "\n",
 1184        name, (long) w));
 1185     if (w) {
 1186     XtVaGetValues(w,
 1187               XtNtranslations, &xlations,
 1188               XtNaccelerators, &xcelerat,
 1189               (XtPointer) 0);
 1190     TRACE(("... xlations %#08lx\n", (long) xlations));
 1191     TRACE(("... xcelerat %#08lx\n", (long) xcelerat));
 1192     result = _XtPrintXlations(w, xlations, xcelerat, True);
 1193     TRACE(("%s\n", NonNull(result)));
 1194     if (result)
 1195         XFree((char *) result);
 1196     } else {
 1197     TRACE(("none (widget is null)\n"));
 1198     }
 1199     TRACE((TRACE_R "\n"));
 1200     XSetErrorHandler(save);
 1201 }
 1202 
 1203 XtGeometryResult
 1204 TraceResizeRequest(const char *fn, int ln, Widget w,
 1205            unsigned reqwide,
 1206            unsigned reqhigh,
 1207            Dimension *gotwide,
 1208            Dimension *gothigh)
 1209 {
 1210     XtGeometryResult rc;
 1211 
 1212     TRACE(("%s@%d ResizeRequest %ux%u\n", fn, ln, reqhigh, reqwide));
 1213     rc = XtMakeResizeRequest((Widget) w,
 1214                  (Dimension) reqwide,
 1215                  (Dimension) reqhigh,
 1216                  gotwide, gothigh);
 1217     TRACE(("... ResizeRequest -> "));
 1218     if (gothigh && gotwide)
 1219     TRACE(("%dx%d ", *gothigh, *gotwide));
 1220     TRACE(("(%d)\n", rc));
 1221     return rc;
 1222 }
 1223 
 1224 #define XRES_S(name) Trace(#name " = %s\n", NonNull(resp->name))
 1225 #define XRES_B(name) Trace(#name " = %s\n", MtoS(resp->name))
 1226 #define XRES_I(name) Trace(#name " = %d\n", resp->name)
 1227 
 1228 void
 1229 TraceXtermResources(void)
 1230 {
 1231     XTERM_RESOURCE *resp = &resource;
 1232 
 1233     Trace("XTERM_RESOURCE settings:\n");
 1234     XRES_S(icon_geometry);
 1235     XRES_S(title);
 1236     XRES_S(icon_hint);
 1237     XRES_S(icon_name);
 1238     XRES_S(term_name);
 1239     XRES_S(tty_modes);
 1240     XRES_I(minBufSize);
 1241     XRES_I(maxBufSize);
 1242     XRES_B(hold_screen);
 1243     XRES_B(utmpInhibit);
 1244     XRES_B(utmpDisplayId);
 1245     XRES_B(messages);
 1246     XRES_S(menuLocale);
 1247     XRES_S(omitTranslation);
 1248     XRES_S(keyboardType);
 1249 #ifdef HAVE_LIB_XCURSOR
 1250     XRES_S(cursorTheme);
 1251 #endif
 1252 #if OPT_PRINT_ON_EXIT
 1253     XRES_I(printModeNow);
 1254     XRES_I(printModeOnXError);
 1255     XRES_I(printOptsNow);
 1256     XRES_I(printOptsOnXError);
 1257     XRES_S(printFileNow);
 1258     XRES_S(printFileOnXError);
 1259 #endif
 1260 #if OPT_SUNPC_KBD
 1261     XRES_B(sunKeyboard);
 1262 #endif
 1263 #if OPT_HP_FUNC_KEYS
 1264     XRES_B(hpFunctionKeys);
 1265 #endif
 1266 #if OPT_SCO_FUNC_KEYS
 1267     XRES_B(scoFunctionKeys);
 1268 #endif
 1269 #if OPT_SUN_FUNC_KEYS
 1270     XRES_B(sunFunctionKeys);
 1271 #endif
 1272 #if OPT_INITIAL_ERASE
 1273     XRES_B(ptyInitialErase);
 1274     XRES_B(backarrow_is_erase);
 1275 #endif
 1276     XRES_B(useInsertMode);
 1277 #if OPT_ZICONBEEP
 1278     XRES_I(zIconBeep);
 1279     XRES_S(zIconFormat);
 1280 #endif
 1281 #if OPT_PTY_HANDSHAKE
 1282     XRES_B(wait_for_map);
 1283     XRES_B(ptyHandshake);
 1284     XRES_B(ptySttySize);
 1285 #endif
 1286 #if OPT_REPORT_CCLASS
 1287     XRES_B(reportCClass);
 1288 #endif
 1289 #if OPT_REPORT_COLORS
 1290     XRES_B(reportColors);
 1291 #endif
 1292 #if OPT_REPORT_FONTS
 1293     XRES_B(reportFonts);
 1294 #endif
 1295 #if OPT_REPORT_ICONS
 1296     XRES_B(reportIcons);
 1297 #endif
 1298 #if OPT_SAME_NAME
 1299     XRES_B(sameName);
 1300 #endif
 1301 #if OPT_SESSION_MGT
 1302     XRES_B(sessionMgt);
 1303 #endif
 1304 #if OPT_TOOLBAR
 1305     XRES_B(toolBar);
 1306 #endif
 1307 #if OPT_MAXIMIZE
 1308     XRES_B(maximized);
 1309     XRES_S(fullscreen_s);
 1310 #endif
 1311 #if USE_DOUBLE_BUFFER
 1312     XRES_B(buffered);
 1313     XRES_I(buffered_fps);
 1314 #endif
 1315 }
 1316 
 1317 void
 1318 TraceArgv(const char *tag, char **argv)
 1319 {
 1320     TRACE(("%s:\n", tag));
 1321     if (argv != 0) {
 1322     int n = 0;
 1323 
 1324     while (*argv != 0) {
 1325         TRACE(("  %d:%s\n", n++, *argv++));
 1326     }
 1327     }
 1328 }
 1329 
 1330 static char *
 1331 parse_option(char *dst, String src, int first)
 1332 {
 1333     char *s;
 1334 
 1335     if (!strncmp(src, "-/+", (size_t) 3)) {
 1336     dst[0] = (char) first;
 1337     strcpy(dst + 1, src + 3);
 1338     } else {
 1339     strcpy(dst, src);
 1340     }
 1341     for (s = dst; *s != '\0'; s++) {
 1342     if (*s == '#' || *s == '%' || *s == 'S') {
 1343         s[1] = '\0';
 1344     } else if (*s == ' ') {
 1345         *s = '\0';
 1346         break;
 1347     }
 1348     }
 1349     return dst;
 1350 }
 1351 
 1352 static Bool
 1353 same_option(OptionHelp * opt, XrmOptionDescRec * res)
 1354 {
 1355     char temp[BUFSIZ];
 1356     return !strcmp(parse_option(temp, opt->opt, res->option[0]), res->option);
 1357 }
 1358 
 1359 static Bool
 1360 standard_option(String opt)
 1361 {
 1362     static const char *table[] =
 1363     {
 1364     "+rv",
 1365     "+synchronous",
 1366     "-background",
 1367     "-bd",
 1368     "-bg",
 1369     "-bordercolor",
 1370     "-borderwidth",
 1371     "-bw",
 1372     "-display",
 1373     "-fg",
 1374     "-fn",
 1375     "-font",
 1376     "-foreground",
 1377     "-geometry",
 1378     "-iconic",
 1379     "-name",
 1380     "-reverse",
 1381     "-rv",
 1382     "-selectionTimeout",
 1383     "-synchronous",
 1384     "-title",
 1385     "-xnllanguage",
 1386     "-xrm",
 1387     "-xtsessionID",
 1388     };
 1389     Cardinal n;
 1390     char temp[BUFSIZ];
 1391 
 1392     opt = parse_option(temp, opt, '-');
 1393     for (n = 0; n < XtNumber(table); n++) {
 1394     if (!strcmp(opt, table[n]))
 1395         return True;
 1396     }
 1397     return False;
 1398 }
 1399 
 1400 /*
 1401  * Analyse the options/help messages for inconsistencies.
 1402  */
 1403 void
 1404 TraceOptions(OptionHelp * options, XrmOptionDescRec * resources, Cardinal res_count)
 1405 {
 1406     OptionHelp *opt_array = sortedOpts(options, resources, res_count);
 1407     size_t j, k;
 1408     XrmOptionDescRec *res_array = sortedOptDescs(resources, res_count);
 1409     Bool first, found;
 1410 
 1411     TRACE(("Checking options-tables for inconsistencies:\n"));
 1412 
 1413 #if 0
 1414     TRACE(("Options listed in help-message:\n"));
 1415     for (j = 0; options[j].opt != 0; j++)
 1416     TRACE(("%5d %-28s %s\n", j, opt_array[j].opt, opt_array[j].desc));
 1417     TRACE(("Options listed in resource-table:\n"));
 1418     for (j = 0; j < res_count; j++)
 1419     TRACE(("%5d %-28s %s\n", j, res_array[j].option, res_array[j].specifier));
 1420 #endif
 1421 
 1422     /* list all options[] not found in resources[] */
 1423     for (j = 0, first = True; options[j].opt != 0; j++) {
 1424     found = False;
 1425     for (k = 0; k < res_count; k++) {
 1426         if (same_option(&opt_array[j], &res_array[k])) {
 1427         found = True;
 1428         break;
 1429         }
 1430     }
 1431     if (!found) {
 1432         if (first) {
 1433         TRACE(("Options listed in help, not found in resource list:\n"));
 1434         first = False;
 1435         }
 1436         TRACE(("  %-28s%s\n", opt_array[j].opt,
 1437            standard_option(opt_array[j].opt) ? " (standard)" : ""));
 1438     }
 1439     }
 1440 
 1441     /* list all resources[] not found in options[] */
 1442     for (j = 0, first = True; j < res_count; j++) {
 1443     found = False;
 1444     for (k = 0; options[k].opt != 0; k++) {
 1445         if (same_option(&opt_array[k], &res_array[j])) {
 1446         found = True;
 1447         break;
 1448         }
 1449     }
 1450     if (!found) {
 1451         if (first) {
 1452         TRACE(("Resource list items not found in options-help:\n"));
 1453         first = False;
 1454         }
 1455         TRACE(("  %s\n", res_array[j].option));
 1456     }
 1457     }
 1458 
 1459     TRACE(("Resource list items that will be ignored by XtOpenApplication:\n"));
 1460     for (j = 0; j < res_count; j++) {
 1461     switch (res_array[j].argKind) {
 1462     case XrmoptionSkipArg:
 1463         TRACE(("  %-28s {param}\n", res_array[j].option));
 1464         break;
 1465     case XrmoptionSkipNArgs:
 1466         TRACE(("  %-28s {%ld params}\n", res_array[j].option, (long)
 1467            res_array[j].value));
 1468         break;
 1469     case XrmoptionSkipLine:
 1470         TRACE(("  %-28s {remainder of line}\n", res_array[j].option));
 1471         break;
 1472     case XrmoptionIsArg:
 1473     case XrmoptionNoArg:
 1474     case XrmoptionResArg:
 1475     case XrmoptionSepArg:
 1476     case XrmoptionStickyArg:
 1477     default:
 1478         break;
 1479     }
 1480     }
 1481 }
 1482 #else
 1483 extern void empty_trace(void);
 1484 void
 1485 empty_trace(void)
 1486 {
 1487 }
 1488 #endif