trace.c revision 0bd37d32
10bd37d32Smrg/* $XTermId: trace.c,v 1.146 2013/04/21 00:37:00 tom Exp $ */
2d522f475Smrg
320d2c4d2Smrg/*
40bd37d32Smrg * Copyright 1997-2012,2013 by Thomas E. Dickey
50bd37d32Smrg *
620d2c4d2Smrg *                         All Rights Reserved
70bd37d32Smrg *
820d2c4d2Smrg * Permission is hereby granted, free of charge, to any person obtaining a
920d2c4d2Smrg * copy of this software and associated documentation files (the
1020d2c4d2Smrg * "Software"), to deal in the Software without restriction, including
1120d2c4d2Smrg * without limitation the rights to use, copy, modify, merge, publish,
1220d2c4d2Smrg * distribute, sublicense, and/or sell copies of the Software, and to
1320d2c4d2Smrg * permit persons to whom the Software is furnished to do so, subject to
1420d2c4d2Smrg * the following conditions:
1520d2c4d2Smrg *
1620d2c4d2Smrg * The above copyright notice and this permission notice shall be included
1720d2c4d2Smrg * in all copies or substantial portions of the Software.
1820d2c4d2Smrg *
1920d2c4d2Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
2020d2c4d2Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2120d2c4d2Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
2220d2c4d2Smrg * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
2320d2c4d2Smrg * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2420d2c4d2Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2520d2c4d2Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2620d2c4d2Smrg *
2720d2c4d2Smrg * Except as contained in this notice, the name(s) of the above copyright
2820d2c4d2Smrg * holders shall not be used in advertising or otherwise to promote the
2920d2c4d2Smrg * sale, use or other dealings in this Software without prior written
3020d2c4d2Smrg * authorization.
3120d2c4d2Smrg */
32d522f475Smrg
33d522f475Smrg/*
34d522f475Smrg * debugging support via TRACE macro.
35d522f475Smrg */
36d522f475Smrg
37d522f475Smrg#include <xterm.h>		/* for definition of GCC_UNUSED */
380bd37d32Smrg#include <version.h>
39a1f3da82Smrg
40a1f3da82Smrg#if OPT_TRACE
41a1f3da82Smrg
42d522f475Smrg#include <data.h>
43d522f475Smrg#include <trace.h>
44d522f475Smrg
45d522f475Smrg#include <time.h>
46d522f475Smrg#include <stdlib.h>
47d522f475Smrg#include <unistd.h>
48d522f475Smrg#include <sys/types.h>
49d522f475Smrg#include <stdio.h>
50d522f475Smrg#include <stdarg.h>
51d522f475Smrg#include <assert.h>
52d522f475Smrg
53956cc18dSsnj#include <X11/Xatom.h>
54956cc18dSsnj#include <X11/Xmu/Atoms.h>
55956cc18dSsnj
56d522f475Smrg#ifdef HAVE_X11_TRANSLATEI_H
57d522f475Smrg#include <X11/TranslateI.h>
58d522f475Smrg#else
59d522f475Smrg#ifdef __cplusplus
60d522f475Smrgextern "C" {
61d522f475Smrg#endif
62d522f475Smrg
63d522f475Smrg    extern String _XtPrintXlations(Widget w,
64d522f475Smrg				   XtTranslations xlations,
65d522f475Smrg				   Widget accelWidget,
66d522f475Smrg				   _XtBoolean includeRHS);
67d522f475Smrg#ifdef __cplusplus
68d522f475Smrg}
69d522f475Smrg#endif
70d522f475Smrg#endif
7120d2c4d2Smrgconst char *trace_who = "parent";
7220d2c4d2Smrg
7320d2c4d2Smrgstatic FILE *trace_fp;
74d522f475Smrg
75d522f475Smrgvoid
76d522f475SmrgTrace(const char *fmt,...)
77d522f475Smrg{
7820d2c4d2Smrg    static const char *trace_out;
79d522f475Smrg    va_list ap;
80d522f475Smrg
8120d2c4d2Smrg    if (trace_fp != 0
82d522f475Smrg	&& trace_who != trace_out) {
8320d2c4d2Smrg	fclose(trace_fp);
8420d2c4d2Smrg	trace_fp = 0;
85d522f475Smrg    }
86d522f475Smrg    trace_out = trace_who;
87d522f475Smrg
8820d2c4d2Smrg    if (!trace_fp) {
890bd37d32Smrg	unsigned oldmask = umask(077);
90d522f475Smrg	char name[BUFSIZ];
91d522f475Smrg#if 0				/* usually I do not want unique names */
92d522f475Smrg	int unique;
93d522f475Smrg	for (unique = 0;; ++unique) {
94d522f475Smrg	    if (unique)
95d522f475Smrg		sprintf(name, "Trace-%s.out-%d", trace_who, unique);
96d522f475Smrg	    else
97d522f475Smrg		sprintf(name, "Trace-%s.out", trace_who);
9820d2c4d2Smrg	    if ((trace_fp = fopen(name, "r")) == 0) {
99d522f475Smrg		break;
100d522f475Smrg	    }
10120d2c4d2Smrg	    fclose(trace_fp);
102d522f475Smrg	}
103d522f475Smrg#else
104d522f475Smrg	sprintf(name, "Trace-%s.out", trace_who);
105d522f475Smrg#endif
10620d2c4d2Smrg	trace_fp = fopen(name, "w");
10720d2c4d2Smrg	if (trace_fp != 0) {
10820d2c4d2Smrg	    fprintf(trace_fp, "%s\n", xtermVersion());
109d522f475Smrg	    TraceIds(NULL, 0);
110d522f475Smrg	}
1110bd37d32Smrg	if (!trace_fp) {
1120bd37d32Smrg	    xtermWarning("Cannot open \"%s\"\n", name);
1130bd37d32Smrg	    exit(EXIT_FAILURE);
1140bd37d32Smrg	}
1150bd37d32Smrg	(void) umask(oldmask);
116d522f475Smrg    }
117d522f475Smrg
118d522f475Smrg    va_start(ap, fmt);
11920d2c4d2Smrg    vfprintf(trace_fp, fmt, ap);
12020d2c4d2Smrg    (void) fflush(trace_fp);
12120d2c4d2Smrg    va_end(ap);
12220d2c4d2Smrg}
12320d2c4d2Smrg
12420d2c4d2Smrgvoid
12520d2c4d2SmrgTraceClose(void)
12620d2c4d2Smrg{
12720d2c4d2Smrg    if (trace_fp != 0) {
12820d2c4d2Smrg	(void) fclose(trace_fp);
129d522f475Smrg	(void) fflush(stdout);
130d522f475Smrg	(void) fflush(stderr);
131956cc18dSsnj	(void) visibleChars(NULL, 0);
132956cc18dSsnj	(void) visibleIChars(NULL, 0);
133956cc18dSsnj	(void) visibleIChar(NULL, 0);
13420d2c4d2Smrg	trace_fp = 0;
135d522f475Smrg    }
136d522f475Smrg}
137d522f475Smrg
138d522f475Smrgvoid
139d522f475SmrgTraceIds(const char *fname, int lnum)
140d522f475Smrg{
141d522f475Smrg    Trace("process %d ", (int) getpid());
142d522f475Smrg#ifdef HAVE_UNISTD_H
143d522f475Smrg    Trace("real (%u/%u) effective (%u/%u)",
144d522f475Smrg	  (unsigned) getuid(), (unsigned) getgid(),
145d522f475Smrg	  (unsigned) geteuid(), (unsigned) getegid());
146d522f475Smrg#endif
147d522f475Smrg    if (fname != 0) {
148d522f475Smrg	Trace(" (%s@%d)\n", fname, lnum);
149d522f475Smrg    } else {
150d522f475Smrg	time_t now = time((time_t *) 0);
151d522f475Smrg	Trace("-- %s", ctime(&now));
152d522f475Smrg    }
153d522f475Smrg}
154d522f475Smrg
1550bd37d32Smrgvoid
1560bd37d32SmrgTraceTime(const char *fname, int lnum)
1570bd37d32Smrg{
1580bd37d32Smrg    time_t now;
1590bd37d32Smrg    if (fname != 0) {
1600bd37d32Smrg	Trace("datetime (%s@%d) ", fname, lnum);
1610bd37d32Smrg    }
1620bd37d32Smrg    now = time((time_t *) 0);
1630bd37d32Smrg    Trace("-- %s", ctime(&now));
1640bd37d32Smrg}
1650bd37d32Smrg
166d522f475Smrgstatic void
167d522f475SmrgformatAscii(char *dst, unsigned value)
168d522f475Smrg{
169d522f475Smrg    switch (value) {
170d522f475Smrg    case '\\':
171d522f475Smrg	sprintf(dst, "\\\\");
172d522f475Smrg	break;
173d522f475Smrg    case '\b':
174d522f475Smrg	sprintf(dst, "\\b");
175d522f475Smrg	break;
176d522f475Smrg    case '\n':
177d522f475Smrg	sprintf(dst, "\\n");
178d522f475Smrg	break;
179d522f475Smrg    case '\r':
180d522f475Smrg	sprintf(dst, "\\r");
181d522f475Smrg	break;
182d522f475Smrg    case '\t':
183d522f475Smrg	sprintf(dst, "\\t");
184d522f475Smrg	break;
185d522f475Smrg    default:
186d522f475Smrg	if (E2A(value) < 32 || (E2A(value) >= 127 && E2A(value) < 160))
187d522f475Smrg	    sprintf(dst, "\\%03o", value);
188d522f475Smrg	else
189d522f475Smrg	    sprintf(dst, "%c", CharOf(value));
190d522f475Smrg	break;
191d522f475Smrg    }
192d522f475Smrg}
193d522f475Smrg
194d522f475Smrg#if OPT_DEC_CHRSET
195d522f475Smrg
196d522f475Smrgconst char *
197956cc18dSsnjvisibleChrsetName(unsigned chrset)
198d522f475Smrg{
199d522f475Smrg    const char *result = "?";
200d522f475Smrg    switch (chrset) {
201d522f475Smrg    case CSET_SWL:
202d522f475Smrg	result = "CSET_SWL";
203d522f475Smrg	break;
204d522f475Smrg    case CSET_DHL_TOP:
205d522f475Smrg	result = "CSET_DHL_TOP";
206d522f475Smrg	break;
207d522f475Smrg    case CSET_DHL_BOT:
208d522f475Smrg	result = "CSET_DHL_BOT";
209d522f475Smrg	break;
210d522f475Smrg    case CSET_DWL:
211d522f475Smrg	result = "CSET_DWL";
212d522f475Smrg	break;
213d522f475Smrg    }
214d522f475Smrg    return result;
215d522f475Smrg}
216d522f475Smrg#endif
217d522f475Smrg
218d522f475Smrgchar *
21920d2c4d2SmrgvisibleChars(const Char * buf, unsigned len)
220d522f475Smrg{
221d522f475Smrg    static char *result;
222d522f475Smrg    static unsigned used;
223d522f475Smrg
224956cc18dSsnj    if (buf != 0) {
225956cc18dSsnj	unsigned limit = ((len + 1) * 8) + 1;
226956cc18dSsnj	char *dst;
227956cc18dSsnj
228956cc18dSsnj	if (limit > used) {
229956cc18dSsnj	    used = limit;
230956cc18dSsnj	    result = XtRealloc(result, used);
231956cc18dSsnj	}
23220d2c4d2Smrg	if (result != 0) {
23320d2c4d2Smrg	    dst = result;
23420d2c4d2Smrg	    *dst = '\0';
23520d2c4d2Smrg	    while (len--) {
23620d2c4d2Smrg		unsigned value = *buf++;
23720d2c4d2Smrg		formatAscii(dst, value);
23820d2c4d2Smrg		dst += strlen(dst);
23920d2c4d2Smrg	    }
240956cc18dSsnj	}
241956cc18dSsnj    } else if (result != 0) {
242956cc18dSsnj	free(result);
243956cc18dSsnj	result = 0;
244956cc18dSsnj	used = 0;
245d522f475Smrg    }
246956cc18dSsnj    return result;
247956cc18dSsnj}
248956cc18dSsnj
249956cc18dSsnjchar *
250956cc18dSsnjvisibleIChars(IChar * buf, unsigned len)
251956cc18dSsnj{
252956cc18dSsnj    static char *result;
253956cc18dSsnj    static unsigned used;
254956cc18dSsnj
255956cc18dSsnj    if (buf != 0) {
256956cc18dSsnj	unsigned limit = ((len + 1) * 8) + 1;
257956cc18dSsnj	char *dst;
258956cc18dSsnj
259956cc18dSsnj	if (limit > used) {
260956cc18dSsnj	    used = limit;
261956cc18dSsnj	    result = XtRealloc(result, used);
262d522f475Smrg	}
26320d2c4d2Smrg	if (result != 0) {
26420d2c4d2Smrg	    dst = result;
26520d2c4d2Smrg	    *dst = '\0';
26620d2c4d2Smrg	    while (len--) {
26720d2c4d2Smrg		unsigned value = *buf++;
268956cc18dSsnj#if OPT_WIDE_CHARS
26920d2c4d2Smrg		if (value > 255)
27020d2c4d2Smrg		    sprintf(dst, "\\u+%04X", value);
27120d2c4d2Smrg		else
272d522f475Smrg#endif
27320d2c4d2Smrg		    formatAscii(dst, value);
27420d2c4d2Smrg		dst += strlen(dst);
27520d2c4d2Smrg	    }
276956cc18dSsnj	}
277956cc18dSsnj    } else if (result != 0) {
278956cc18dSsnj	free(result);
279956cc18dSsnj	result = 0;
280956cc18dSsnj	used = 0;
281d522f475Smrg    }
282d522f475Smrg    return result;
283d522f475Smrg}
284d522f475Smrg
285d522f475Smrgchar *
286d522f475SmrgvisibleIChar(IChar * buf, unsigned len)
287d522f475Smrg{
288d522f475Smrg    static char *result;
289d522f475Smrg    static unsigned used;
290d522f475Smrg
291956cc18dSsnj    if (buf != 0) {
29220d2c4d2Smrg	unsigned limit = ((len + 1) * 8) + 1;
293956cc18dSsnj	char *dst;
294956cc18dSsnj
295956cc18dSsnj	if (limit > used) {
296956cc18dSsnj	    used = limit;
297956cc18dSsnj	    result = XtRealloc(result, used);
298956cc18dSsnj	}
29920d2c4d2Smrg	if (result != 0) {
30020d2c4d2Smrg	    dst = result;
30120d2c4d2Smrg	    while (len--) {
30220d2c4d2Smrg		unsigned value = *buf++;
303d522f475Smrg#if OPT_WIDE_CHARS
30420d2c4d2Smrg		if (value > 255)
30520d2c4d2Smrg		    sprintf(dst, "\\u+%04X", value);
30620d2c4d2Smrg		else
307d522f475Smrg#endif
30820d2c4d2Smrg		    formatAscii(dst, value);
30920d2c4d2Smrg		dst += strlen(dst);
31020d2c4d2Smrg	    }
311956cc18dSsnj	}
312956cc18dSsnj    } else if (result != 0) {
313956cc18dSsnj	free(result);
314956cc18dSsnj	result = 0;
315956cc18dSsnj	used = 0;
316d522f475Smrg    }
317d522f475Smrg    return result;
318d522f475Smrg}
319d522f475Smrg
320a1f3da82Smrg#define CASETYPE(name) case name: result = #name; break
321d522f475Smrg
322d522f475Smrgconst char *
323d522f475SmrgvisibleKeyboardType(xtermKeyboardType type)
324d522f475Smrg{
325d522f475Smrg    const char *result = "?";
326d522f475Smrg    switch (type) {
327d522f475Smrg	CASETYPE(keyboardIsLegacy);	/* bogus vt220 codes for F1-F4, etc. */
328d522f475Smrg	CASETYPE(keyboardIsDefault);
329d522f475Smrg	CASETYPE(keyboardIsHP);
330d522f475Smrg	CASETYPE(keyboardIsSCO);
331d522f475Smrg	CASETYPE(keyboardIsSun);
332d522f475Smrg	CASETYPE(keyboardIsTermcap);
333d522f475Smrg	CASETYPE(keyboardIsVT220);
334d522f475Smrg    }
335d522f475Smrg    return result;
336d522f475Smrg}
337d522f475Smrg
338d522f475Smrgconst char *
339d522f475SmrgvisibleEventType(int type)
340d522f475Smrg{
341d522f475Smrg    const char *result = "?";
342d522f475Smrg    switch (type) {
343d522f475Smrg	CASETYPE(KeyPress);
344d522f475Smrg	CASETYPE(KeyRelease);
345d522f475Smrg	CASETYPE(ButtonPress);
346d522f475Smrg	CASETYPE(ButtonRelease);
347d522f475Smrg	CASETYPE(MotionNotify);
348d522f475Smrg	CASETYPE(EnterNotify);
349d522f475Smrg	CASETYPE(LeaveNotify);
350d522f475Smrg	CASETYPE(FocusIn);
351d522f475Smrg	CASETYPE(FocusOut);
352d522f475Smrg	CASETYPE(KeymapNotify);
353d522f475Smrg	CASETYPE(Expose);
354d522f475Smrg	CASETYPE(GraphicsExpose);
355d522f475Smrg	CASETYPE(NoExpose);
356d522f475Smrg	CASETYPE(VisibilityNotify);
357d522f475Smrg	CASETYPE(CreateNotify);
358d522f475Smrg	CASETYPE(DestroyNotify);
359d522f475Smrg	CASETYPE(UnmapNotify);
360d522f475Smrg	CASETYPE(MapNotify);
361d522f475Smrg	CASETYPE(MapRequest);
362d522f475Smrg	CASETYPE(ReparentNotify);
363d522f475Smrg	CASETYPE(ConfigureNotify);
364d522f475Smrg	CASETYPE(ConfigureRequest);
365d522f475Smrg	CASETYPE(GravityNotify);
366d522f475Smrg	CASETYPE(ResizeRequest);
367d522f475Smrg	CASETYPE(CirculateNotify);
368d522f475Smrg	CASETYPE(CirculateRequest);
369d522f475Smrg	CASETYPE(PropertyNotify);
370d522f475Smrg	CASETYPE(SelectionClear);
371d522f475Smrg	CASETYPE(SelectionRequest);
372d522f475Smrg	CASETYPE(SelectionNotify);
373d522f475Smrg	CASETYPE(ColormapNotify);
374d522f475Smrg	CASETYPE(ClientMessage);
375d522f475Smrg	CASETYPE(MappingNotify);
376d522f475Smrg    }
377d522f475Smrg    return result;
378d522f475Smrg}
379d522f475Smrg
3800bd37d32Smrgconst char *
3810bd37d32SmrgvisibleNotifyMode(int code)
3820bd37d32Smrg{
3830bd37d32Smrg    const char *result = "?";
3840bd37d32Smrg    switch (code) {
3850bd37d32Smrg	CASETYPE(NotifyNormal);
3860bd37d32Smrg	CASETYPE(NotifyGrab);
3870bd37d32Smrg	CASETYPE(NotifyUngrab);
3880bd37d32Smrg	CASETYPE(NotifyWhileGrabbed);
3890bd37d32Smrg    }
3900bd37d32Smrg    return result;
3910bd37d32Smrg}
3920bd37d32Smrg
39320d2c4d2Smrgconst char *
39420d2c4d2SmrgvisibleNotifyDetail(int code)
39520d2c4d2Smrg{
39620d2c4d2Smrg    const char *result = "?";
39720d2c4d2Smrg    switch (code) {
39820d2c4d2Smrg	CASETYPE(NotifyAncestor);
39920d2c4d2Smrg	CASETYPE(NotifyVirtual);
40020d2c4d2Smrg	CASETYPE(NotifyInferior);
40120d2c4d2Smrg	CASETYPE(NotifyNonlinear);
40220d2c4d2Smrg	CASETYPE(NotifyNonlinearVirtual);
40320d2c4d2Smrg	CASETYPE(NotifyPointer);
40420d2c4d2Smrg	CASETYPE(NotifyPointerRoot);
40520d2c4d2Smrg	CASETYPE(NotifyDetailNone);
40620d2c4d2Smrg    }
40720d2c4d2Smrg    return result;
40820d2c4d2Smrg}
40920d2c4d2Smrg
410956cc18dSsnjconst char *
411956cc18dSsnjvisibleSelectionTarget(Display * d, Atom a)
412956cc18dSsnj{
413956cc18dSsnj    const char *result = "?";
414956cc18dSsnj
415956cc18dSsnj    if (a == XA_STRING) {
416956cc18dSsnj	result = "XA_STRING";
417956cc18dSsnj    } else if (a == XA_TEXT(d)) {
418956cc18dSsnj	result = "XA_TEXT()";
419956cc18dSsnj    } else if (a == XA_COMPOUND_TEXT(d)) {
420956cc18dSsnj	result = "XA_COMPOUND_TEXT()";
421956cc18dSsnj    } else if (a == XA_UTF8_STRING(d)) {
422956cc18dSsnj	result = "XA_UTF8_STRING()";
423956cc18dSsnj    } else if (a == XA_TARGETS(d)) {
424956cc18dSsnj	result = "XA_TARGETS()";
425956cc18dSsnj    }
426956cc18dSsnj
427956cc18dSsnj    return result;
428956cc18dSsnj}
429956cc18dSsnj
430d522f475Smrgconst char *
431d522f475SmrgvisibleXError(int code)
432d522f475Smrg{
433d522f475Smrg    static char temp[80];
434d522f475Smrg    const char *result = "?";
435d522f475Smrg    switch (code) {
436d522f475Smrg	CASETYPE(Success);
437d522f475Smrg	CASETYPE(BadRequest);
438d522f475Smrg	CASETYPE(BadValue);
439d522f475Smrg	CASETYPE(BadWindow);
440d522f475Smrg	CASETYPE(BadPixmap);
441d522f475Smrg	CASETYPE(BadAtom);
442d522f475Smrg	CASETYPE(BadCursor);
443d522f475Smrg	CASETYPE(BadFont);
444d522f475Smrg	CASETYPE(BadMatch);
445d522f475Smrg	CASETYPE(BadDrawable);
446d522f475Smrg	CASETYPE(BadAccess);
447d522f475Smrg	CASETYPE(BadAlloc);
448d522f475Smrg	CASETYPE(BadColor);
449d522f475Smrg	CASETYPE(BadGC);
450d522f475Smrg	CASETYPE(BadIDChoice);
451d522f475Smrg	CASETYPE(BadName);
452d522f475Smrg	CASETYPE(BadLength);
453d522f475Smrg	CASETYPE(BadImplementation);
454d522f475Smrg    default:
455d522f475Smrg	sprintf(temp, "%d", code);
456d522f475Smrg	result = temp;
457d522f475Smrg	break;
458d522f475Smrg    }
459d522f475Smrg    return result;
460d522f475Smrg}
461d522f475Smrg
462d522f475Smrg#if OPT_TRACE_FLAGS
463d522f475Smrg#define isScrnFlag(flag) ((flag) == LINEWRAPPED)
464d522f475Smrg
465d522f475Smrgstatic char *
466956cc18dSsnjScrnText(LineData * ld)
467d522f475Smrg{
468956cc18dSsnj    return visibleIChars(ld->charData, ld->lineSize);
469d522f475Smrg}
470d522f475Smrg
471956cc18dSsnj#define SHOW_BAD_LINE(name, ld) \
472956cc18dSsnj	Trace("OOPS " #name " bad row\n")
473d522f475Smrg
474d522f475Smrg#define SHOW_SCRN_FLAG(name,code) \
475956cc18dSsnj	Trace(#name " %s:%s\n", \
476d522f475Smrg	      code ? "*" : "", \
477956cc18dSsnj	      ScrnText(ld))
478d522f475Smrg
479d522f475Smrgvoid
480956cc18dSsnjLineClrFlag(LineData * ld, int flag)
481d522f475Smrg{
482956cc18dSsnj    if (ld == 0) {
483956cc18dSsnj	SHOW_BAD_LINE(LineClrFlag, ld);
484d522f475Smrg	assert(0);
485d522f475Smrg    } else if (isScrnFlag(flag)) {
486956cc18dSsnj	SHOW_SCRN_FLAG(LineClrFlag, 0);
487d522f475Smrg    }
488d522f475Smrg
489956cc18dSsnj    LineFlags(ld) &= ~flag;
490d522f475Smrg}
491d522f475Smrg
492d522f475Smrgvoid
493956cc18dSsnjLineSetFlag(LineData * ld, int flag)
494d522f475Smrg{
495956cc18dSsnj    if (ld == 0) {
496956cc18dSsnj	SHOW_BAD_LINE(LineSetFlag, ld);
497d522f475Smrg	assert(0);
498d522f475Smrg    } else if (isScrnFlag(flag)) {
499956cc18dSsnj	SHOW_SCRN_FLAG(LineSetFlag, 1);
500d522f475Smrg    }
501d522f475Smrg
502956cc18dSsnj    LineFlags(ld) |= flag;
503d522f475Smrg}
504d522f475Smrg
505d522f475Smrgint
506956cc18dSsnjLineTstFlag(LineData ld, int flag)
507d522f475Smrg{
508d522f475Smrg    int code = 0;
509956cc18dSsnj    if (ld == 0) {
510956cc18dSsnj	SHOW_BAD_LINE(LineTstFlag, ld);
511d522f475Smrg    } else {
512956cc18dSsnj	code = LineFlags(ld);
513956cc18dSsnj
514956cc18dSsnj	if (isScrnFlag(flag)) {
515956cc18dSsnj	    SHOW_SCRN_FLAG(LineTstFlag, code);
516d522f475Smrg	}
517d522f475Smrg    }
518d522f475Smrg    return code;
519d522f475Smrg}
520d522f475Smrg#endif /* OPT_TRACE_FLAGS */
521d522f475Smrg
5220bd37d32Smrg/*
5230bd37d32Smrg * Trace the normal or alternate screen, showing color values up to 16, e.g.,
5240bd37d32Smrg * for debugging with vttest.
5250bd37d32Smrg */
5260bd37d32Smrgvoid
5270bd37d32SmrgTraceScreen(XtermWidget xw, int whichBuf)
5280bd37d32Smrg{
5290bd37d32Smrg    TScreen *screen = TScreenOf(xw);
5300bd37d32Smrg    int row, col;
5310bd37d32Smrg
5320bd37d32Smrg    if (screen->editBuf_index[whichBuf]) {
5330bd37d32Smrg	TRACE(("TraceScreen %d:\n", whichBuf));
5340bd37d32Smrg	for (row = 0; row <= screen->max_row; ++row) {
5350bd37d32Smrg	    LineData *ld = getLineData(screen, row);
5360bd37d32Smrg	    TRACE((" %3d:", row));
5370bd37d32Smrg	    if (ld != 0) {
5380bd37d32Smrg		for (col = 0; col < ld->lineSize; ++col) {
5390bd37d32Smrg		    int ch = (int) ld->charData[col];
5400bd37d32Smrg		    if (ch < ' ')
5410bd37d32Smrg			ch = ' ';
5420bd37d32Smrg		    if (ch >= 127)
5430bd37d32Smrg			ch = '#';
5440bd37d32Smrg		    TRACE(("%c", ch));
5450bd37d32Smrg		}
5460bd37d32Smrg		TRACE((":\n"));
5470bd37d32Smrg
5480bd37d32Smrg		TRACE(("  xx:"));
5490bd37d32Smrg		for (col = 0; col < ld->lineSize; ++col) {
5500bd37d32Smrg		    unsigned attrs = ld->attribs[col];
5510bd37d32Smrg		    char ch;
5520bd37d32Smrg		    if (attrs & PROTECTED) {
5530bd37d32Smrg			ch = '*';
5540bd37d32Smrg		    } else if (attrs & BLINK) {
5550bd37d32Smrg			ch = 'B';
5560bd37d32Smrg		    } else if (attrs & CHARDRAWN) {
5570bd37d32Smrg			ch = '+';
5580bd37d32Smrg		    } else {
5590bd37d32Smrg			ch = ' ';
5600bd37d32Smrg		    }
5610bd37d32Smrg		    TRACE(("%c", ch));
5620bd37d32Smrg		}
5630bd37d32Smrg		TRACE((":\n"));
5640bd37d32Smrg
5650bd37d32Smrg#if 0
5660bd37d32Smrg		TRACE(("  fg:"));
5670bd37d32Smrg		for (col = 0; col < ld->lineSize; ++col) {
5680bd37d32Smrg		    unsigned fg = extract_fg(xw, ld->color[col], ld->attribs[col]);
5690bd37d32Smrg		    if (fg > 15)
5700bd37d32Smrg			fg = 15;
5710bd37d32Smrg		    TRACE(("%1x", fg));
5720bd37d32Smrg		}
5730bd37d32Smrg		TRACE((":\n"));
5740bd37d32Smrg
5750bd37d32Smrg		TRACE(("  bg:"));
5760bd37d32Smrg		for (col = 0; col < ld->lineSize; ++col) {
5770bd37d32Smrg		    unsigned bg = extract_bg(xw, ld->color[col], ld->attribs[col]);
5780bd37d32Smrg		    if (bg > 15)
5790bd37d32Smrg			bg = 15;
5800bd37d32Smrg		    TRACE(("%1x", bg));
5810bd37d32Smrg		}
5820bd37d32Smrg		TRACE((":\n"));
5830bd37d32Smrg#endif
5840bd37d32Smrg	    } else {
5850bd37d32Smrg		TRACE(("null lineData\n"));
5860bd37d32Smrg	    }
5870bd37d32Smrg	}
5880bd37d32Smrg    } else {
5890bd37d32Smrg	TRACE(("TraceScreen %d is nil\n", whichBuf));
5900bd37d32Smrg    }
5910bd37d32Smrg}
5920bd37d32Smrg
59320d2c4d2Smrgvoid
59420d2c4d2SmrgTraceFocus(Widget w, XEvent * ev)
59520d2c4d2Smrg{
59620d2c4d2Smrg    TRACE(("trace_focus event type %d:%s\n",
59720d2c4d2Smrg	   ev->type, visibleEventType(ev->type)));
59820d2c4d2Smrg    switch (ev->type) {
59920d2c4d2Smrg    case FocusIn:
60020d2c4d2Smrg    case FocusOut:
60120d2c4d2Smrg	{
60220d2c4d2Smrg	    XFocusChangeEvent *event = (XFocusChangeEvent *) ev;
60320d2c4d2Smrg	    TRACE(("\tdetail: %s\n", visibleNotifyDetail(event->detail)));
6040bd37d32Smrg	    TRACE(("\tmode:   %s\n", visibleNotifyMode(event->mode)));
60520d2c4d2Smrg	    TRACE(("\twindow: %#lx\n", event->window));
60620d2c4d2Smrg	}
60720d2c4d2Smrg	break;
60820d2c4d2Smrg    case EnterNotify:
60920d2c4d2Smrg    case LeaveNotify:
61020d2c4d2Smrg	{
61120d2c4d2Smrg	    XCrossingEvent *event = (XCrossingEvent *) ev;
61220d2c4d2Smrg	    TRACE(("\tdetail:    %s\n", visibleNotifyDetail(event->detail)));
6130bd37d32Smrg	    TRACE(("\tmode:      %s\n", visibleNotifyMode(event->mode)));
61420d2c4d2Smrg	    TRACE(("\twindow:    %#lx\n", event->window));
615e39b573cSmrg	    TRACE(("\tfocus:     %d\n", event->focus));
61620d2c4d2Smrg	    TRACE(("\troot:      %#lx\n", event->root));
61720d2c4d2Smrg	    TRACE(("\tsubwindow: %#lx\n", event->subwindow));
61820d2c4d2Smrg	}
61920d2c4d2Smrg	break;
62020d2c4d2Smrg    }
62120d2c4d2Smrg    while (w != 0) {
62220d2c4d2Smrg	TRACE(("w %p -> %#lx\n", (void *) w, XtWindow(w)));
62320d2c4d2Smrg	w = XtParent(w);
62420d2c4d2Smrg    }
62520d2c4d2Smrg}
62620d2c4d2Smrg
627d522f475Smrgvoid
628d522f475SmrgTraceSizeHints(XSizeHints * hints)
629d522f475Smrg{
630d522f475Smrg    TRACE(("size hints:\n"));
631d522f475Smrg    if (hints->flags & (USPosition | PPosition))
632d522f475Smrg	TRACE(("   position   %d,%d%s%s\n", hints->y, hints->x,
633d522f475Smrg	       hints->flags & USPosition ? " user" : "",
634d522f475Smrg	       hints->flags & PPosition ? " prog" : ""));
635d522f475Smrg    if (hints->flags & (USSize | PSize))
636d522f475Smrg	TRACE(("   size       %d,%d%s%s\n", hints->height, hints->width,
637d522f475Smrg	       hints->flags & USSize ? " user" : "",
638d522f475Smrg	       hints->flags & PSize ? " prog" : ""));
639d522f475Smrg    if (hints->flags & PMinSize)
640d522f475Smrg	TRACE(("   min        %d,%d\n", hints->min_height, hints->min_width));
641d522f475Smrg    if (hints->flags & PMaxSize)
642d522f475Smrg	TRACE(("   max        %d,%d\n", hints->max_height, hints->max_width));
643d522f475Smrg    if (hints->flags & PResizeInc)
644d522f475Smrg	TRACE(("   inc        %d,%d\n", hints->height_inc, hints->width_inc));
6452eaa94a1Schristos    else
6462eaa94a1Schristos	TRACE(("   inc        NONE!\n"));
647d522f475Smrg    if (hints->flags & PAspect)
648d522f475Smrg	TRACE(("   min aspect %d/%d\n", hints->min_aspect.y, hints->min_aspect.y));
649d522f475Smrg    if (hints->flags & PAspect)
650d522f475Smrg	TRACE(("   max aspect %d/%d\n", hints->max_aspect.y, hints->max_aspect.y));
651d522f475Smrg    if (hints->flags & PBaseSize)
652d522f475Smrg	TRACE(("   base       %d,%d\n", hints->base_height, hints->base_width));
653d522f475Smrg    if (hints->flags & PWinGravity)
654d522f475Smrg	TRACE(("   gravity    %d\n", hints->win_gravity));
655d522f475Smrg}
656d522f475Smrg
6570bd37d32Smrgstatic void
6580bd37d32SmrgTraceEventMask(const char *tag, long mask)
6590bd37d32Smrg{
6600bd37d32Smrg#define DATA(name) { name##Mask, #name }
6610bd37d32Smrg    /* *INDENT-OFF* */
6620bd37d32Smrg    static struct {
6630bd37d32Smrg	long mask;
6640bd37d32Smrg	const char *name;
6650bd37d32Smrg    } table[] = {
6660bd37d32Smrg	DATA(KeyPress),
6670bd37d32Smrg	DATA(KeyRelease),
6680bd37d32Smrg	DATA(ButtonPress),
6690bd37d32Smrg	DATA(ButtonRelease),
6700bd37d32Smrg	DATA(EnterWindow),
6710bd37d32Smrg	DATA(LeaveWindow),
6720bd37d32Smrg	DATA(PointerMotion),
6730bd37d32Smrg	DATA(PointerMotionHint),
6740bd37d32Smrg	DATA(Button1Motion),
6750bd37d32Smrg	DATA(Button2Motion),
6760bd37d32Smrg	DATA(Button3Motion),
6770bd37d32Smrg	DATA(Button4Motion),
6780bd37d32Smrg	DATA(Button5Motion),
6790bd37d32Smrg	DATA(ButtonMotion),
6800bd37d32Smrg	DATA(KeymapState),
6810bd37d32Smrg	DATA(Exposure),
6820bd37d32Smrg	DATA(VisibilityChange),
6830bd37d32Smrg	DATA(StructureNotify),
6840bd37d32Smrg	DATA(ResizeRedirect),
6850bd37d32Smrg	DATA(SubstructureNotify),
6860bd37d32Smrg	DATA(SubstructureRedirect),
6870bd37d32Smrg	DATA(FocusChange),
6880bd37d32Smrg	DATA(PropertyChange),
6890bd37d32Smrg	DATA(ColormapChange),
6900bd37d32Smrg	DATA(OwnerGrabButton),
6910bd37d32Smrg    };
6920bd37d32Smrg#undef DATA
6930bd37d32Smrg    Cardinal n;
6940bd37d32Smrg    /* *INDENT-ON* */
6950bd37d32Smrg
6960bd37d32Smrg    for (n = 0; n < XtNumber(table); ++n) {
6970bd37d32Smrg	if (table[n].mask & mask) {
6980bd37d32Smrg	    TRACE(("%s %s\n", tag, table[n].name));
6990bd37d32Smrg	}
7000bd37d32Smrg    }
7010bd37d32Smrg}
7020bd37d32Smrg
7030bd37d32Smrgvoid
7040bd37d32SmrgTraceWindowAttributes(XWindowAttributes * attrs)
7050bd37d32Smrg{
7060bd37d32Smrg    TRACE(("window attributes:\n"));
7070bd37d32Smrg    TRACE(("   position     %d,%d\n", attrs->y, attrs->x));
7080bd37d32Smrg    TRACE(("   size         %dx%d\n", attrs->height, attrs->width));
7090bd37d32Smrg    TRACE(("   border       %d\n", attrs->border_width));
7100bd37d32Smrg    TRACE(("   depth        %d\n", attrs->depth));
7110bd37d32Smrg    TRACE(("   bit_gravity  %d\n", attrs->bit_gravity));
7120bd37d32Smrg    TRACE(("   win_gravity  %d\n", attrs->win_gravity));
7130bd37d32Smrg    TRACE(("   root         %#lx\n", (long) attrs->root));
7140bd37d32Smrg    TRACE(("   class        %s\n", ((attrs->class == InputOutput)
7150bd37d32Smrg				    ? "InputOutput"
7160bd37d32Smrg				    : ((attrs->class == InputOnly)
7170bd37d32Smrg				       ? "InputOnly"
7180bd37d32Smrg				       : "unknown"))));
7190bd37d32Smrg    TRACE(("   map_state    %s\n", ((attrs->map_state == IsUnmapped)
7200bd37d32Smrg				    ? "IsUnmapped"
7210bd37d32Smrg				    : ((attrs->map_state == IsUnviewable)
7220bd37d32Smrg				       ? "IsUnviewable"
7230bd37d32Smrg				       : ((attrs->map_state == IsViewable)
7240bd37d32Smrg					  ? "IsViewable"
7250bd37d32Smrg					  : "unknown")))));
7260bd37d32Smrg    TRACE(("   all_events\n"));
7270bd37d32Smrg    TraceEventMask("        ", attrs->all_event_masks);
7280bd37d32Smrg    TRACE(("   your_events\n"));
7290bd37d32Smrg    TraceEventMask("        ", attrs->your_event_mask);
7300bd37d32Smrg    TRACE(("   no_propagate\n"));
7310bd37d32Smrg    TraceEventMask("        ", attrs->do_not_propagate_mask);
7320bd37d32Smrg}
7330bd37d32Smrg
734d522f475Smrgvoid
735d522f475SmrgTraceWMSizeHints(XtermWidget xw)
736d522f475Smrg{
737d522f475Smrg    XSizeHints sizehints = xw->hints;
738d522f475Smrg
739d522f475Smrg    getXtermSizeHints(xw);
740d522f475Smrg    TraceSizeHints(&xw->hints);
741d522f475Smrg    xw->hints = sizehints;
742d522f475Smrg}
743d522f475Smrg
744d522f475Smrg/*
745d522f475Smrg * Some calls to XGetAtom() will fail, and we don't want to stop.  So we use
746d522f475Smrg * our own error-handler.
747d522f475Smrg */
748a1f3da82Smrg/* ARGSUSED */
749d522f475Smrgstatic int
750d522f475Smrgno_error(Display * dpy GCC_UNUSED, XErrorEvent * event GCC_UNUSED)
751d522f475Smrg{
752d522f475Smrg    return 1;
753d522f475Smrg}
754d522f475Smrg
7550bd37d32Smrgconst char *
7560bd37d32SmrgModifierName(unsigned modifier)
7570bd37d32Smrg{
7580bd37d32Smrg    const char *s = "";
7590bd37d32Smrg    if (modifier & ShiftMask)
7600bd37d32Smrg	s = " Shift";
7610bd37d32Smrg    else if (modifier & LockMask)
7620bd37d32Smrg	s = " Lock";
7630bd37d32Smrg    else if (modifier & ControlMask)
7640bd37d32Smrg	s = " Control";
7650bd37d32Smrg    else if (modifier & Mod1Mask)
7660bd37d32Smrg	s = " Mod1";
7670bd37d32Smrg    else if (modifier & Mod2Mask)
7680bd37d32Smrg	s = " Mod2";
7690bd37d32Smrg    else if (modifier & Mod3Mask)
7700bd37d32Smrg	s = " Mod3";
7710bd37d32Smrg    else if (modifier & Mod4Mask)
7720bd37d32Smrg	s = " Mod4";
7730bd37d32Smrg    else if (modifier & Mod5Mask)
7740bd37d32Smrg	s = " Mod5";
7750bd37d32Smrg    return s;
7760bd37d32Smrg}
7770bd37d32Smrg
778d522f475Smrgvoid
779d522f475SmrgTraceTranslations(const char *name, Widget w)
780d522f475Smrg{
781d522f475Smrg    String result;
782d522f475Smrg    XErrorHandler save = XSetErrorHandler(no_error);
783d522f475Smrg    XtTranslations xlations;
784d522f475Smrg    Widget xcelerat;
785d522f475Smrg
78620d2c4d2Smrg    TRACE(("TraceTranslations for %s (widget %#lx) {{\n", name, (long) w));
787d522f475Smrg    if (w) {
788d522f475Smrg	XtVaGetValues(w,
789d522f475Smrg		      XtNtranslations, &xlations,
790d522f475Smrg		      XtNaccelerators, &xcelerat,
791d522f475Smrg		      (XtPointer) 0);
792d522f475Smrg	TRACE(("... xlations %#08lx\n", (long) xlations));
793d522f475Smrg	TRACE(("... xcelerat %#08lx\n", (long) xcelerat));
794d522f475Smrg	result = _XtPrintXlations(w, xlations, xcelerat, True);
79520d2c4d2Smrg	TRACE(("%s\n", NonNull(result)));
796d522f475Smrg	if (result)
79720d2c4d2Smrg	    XFree((char *) result);
798d522f475Smrg    } else {
799d522f475Smrg	TRACE(("none (widget is null)\n"));
800d522f475Smrg    }
80120d2c4d2Smrg    TRACE(("}}\n"));
802d522f475Smrg    XSetErrorHandler(save);
803d522f475Smrg}
804d522f475Smrg
8050bd37d32SmrgXtGeometryResult
8062eaa94a1SchristosTraceResizeRequest(const char *fn, int ln, Widget w,
807e39b573cSmrg		   unsigned reqwide,
808e39b573cSmrg		   unsigned reqhigh,
8092eaa94a1Schristos		   Dimension * gotwide,
8102eaa94a1Schristos		   Dimension * gothigh)
8112eaa94a1Schristos{
8120bd37d32Smrg    XtGeometryResult rc;
8132eaa94a1Schristos
814e39b573cSmrg    TRACE(("%s@%d ResizeRequest %ux%u\n", fn, ln, reqhigh, reqwide));
8150bd37d32Smrg    rc = XtMakeResizeRequest((Widget) w,
8160bd37d32Smrg			     (Dimension) reqwide,
8170bd37d32Smrg			     (Dimension) reqhigh,
8180bd37d32Smrg			     gotwide, gothigh);
8192eaa94a1Schristos    TRACE(("... ResizeRequest -> "));
8202eaa94a1Schristos    if (gothigh && gotwide)
8212eaa94a1Schristos	TRACE(("%dx%d ", *gothigh, *gotwide));
8222eaa94a1Schristos    TRACE(("(%d)\n", rc));
8232eaa94a1Schristos    return rc;
8242eaa94a1Schristos}
8252eaa94a1Schristos
826d522f475Smrg#define XRES_S(name) Trace(#name " = %s\n", NonNull(resp->name))
827d522f475Smrg#define XRES_B(name) Trace(#name " = %s\n", BtoS(resp->name))
828d522f475Smrg#define XRES_I(name) Trace(#name " = %d\n", resp->name)
829d522f475Smrg
830d522f475Smrgvoid
831d522f475SmrgTraceXtermResources(void)
832d522f475Smrg{
833d522f475Smrg    XTERM_RESOURCE *resp = &resource;
834d522f475Smrg
835d522f475Smrg    Trace("XTERM_RESOURCE settings:\n");
836d522f475Smrg    XRES_S(icon_geometry);
837d522f475Smrg    XRES_S(title);
8380bd37d32Smrg    XRES_S(icon_hint);
839d522f475Smrg    XRES_S(icon_name);
840d522f475Smrg    XRES_S(term_name);
841d522f475Smrg    XRES_S(tty_modes);
842e39b573cSmrg    XRES_I(minBufSize);
843e39b573cSmrg    XRES_I(maxBufSize);
844d522f475Smrg    XRES_B(hold_screen);
845d522f475Smrg    XRES_B(utmpInhibit);
846d522f475Smrg    XRES_B(utmpDisplayId);
847d522f475Smrg    XRES_B(messages);
848e39b573cSmrg    XRES_S(menuLocale);
849e39b573cSmrg    XRES_S(omitTranslation);
850e39b573cSmrg    XRES_S(keyboardType);
851e39b573cSmrg#if OPT_PRINT_ON_EXIT
852e39b573cSmrg    XRES_I(printModeNow);
853e39b573cSmrg    XRES_I(printModeOnXError);
854e39b573cSmrg    XRES_I(printOptsNow);
855e39b573cSmrg    XRES_I(printOptsOnXError);
856e39b573cSmrg    XRES_S(printFileNow);
857e39b573cSmrg    XRES_S(printFileOnXError);
858e39b573cSmrg#endif
859d522f475Smrg#if OPT_SUNPC_KBD
860d522f475Smrg    XRES_B(sunKeyboard);
861d522f475Smrg#endif
862d522f475Smrg#if OPT_HP_FUNC_KEYS
863d522f475Smrg    XRES_B(hpFunctionKeys);
864d522f475Smrg#endif
865d522f475Smrg#if OPT_SCO_FUNC_KEYS
866d522f475Smrg    XRES_B(scoFunctionKeys);
867d522f475Smrg#endif
868d522f475Smrg#if OPT_SUN_FUNC_KEYS
869d522f475Smrg    XRES_B(sunFunctionKeys);
870d522f475Smrg#endif
871d522f475Smrg#if OPT_INITIAL_ERASE
872d522f475Smrg    XRES_B(ptyInitialErase);
873d522f475Smrg    XRES_B(backarrow_is_erase);
874d522f475Smrg#endif
875d522f475Smrg    XRES_B(useInsertMode);
876d522f475Smrg#if OPT_ZICONBEEP
877d522f475Smrg    XRES_I(zIconBeep);
8780bd37d32Smrg    XRES_S(zIconFormat);
879d522f475Smrg#endif
880d522f475Smrg#if OPT_PTY_HANDSHAKE
881d522f475Smrg    XRES_B(wait_for_map);
882d522f475Smrg    XRES_B(ptyHandshake);
883d522f475Smrg    XRES_B(ptySttySize);
884d522f475Smrg#endif
885d522f475Smrg#if OPT_SAME_NAME
886d522f475Smrg    XRES_B(sameName);
887d522f475Smrg#endif
888d522f475Smrg#if OPT_SESSION_MGT
889d522f475Smrg    XRES_B(sessionMgt);
890d522f475Smrg#endif
891a1f3da82Smrg#if OPT_TOOLBAR
892a1f3da82Smrg    XRES_B(toolBar);
893a1f3da82Smrg#endif
894a1f3da82Smrg#if OPT_MAXIMIZE
895a1f3da82Smrg    XRES_B(maximized);
896a1f3da82Smrg    XRES_S(fullscreen_s);
897a1f3da82Smrg#endif
898d522f475Smrg}
899d522f475Smrg
900d522f475Smrgvoid
901d522f475SmrgTraceArgv(const char *tag, char **argv)
902d522f475Smrg{
903d522f475Smrg    int n = 0;
904d522f475Smrg
905d522f475Smrg    TRACE(("%s:\n", tag));
906d522f475Smrg    while (*argv != 0) {
907d522f475Smrg	TRACE(("  %d:%s\n", n++, *argv++));
908d522f475Smrg    }
909d522f475Smrg}
910d522f475Smrg
911d522f475Smrgstatic char *
91220d2c4d2Smrgparse_option(char *dst, String src, int first)
913d522f475Smrg{
914d522f475Smrg    char *s;
915d522f475Smrg
916a1f3da82Smrg    if (!strncmp(src, "-/+", (size_t) 3)) {
917956cc18dSsnj	dst[0] = (char) first;
918d522f475Smrg	strcpy(dst + 1, src + 3);
919d522f475Smrg    } else {
920d522f475Smrg	strcpy(dst, src);
921d522f475Smrg    }
922d522f475Smrg    for (s = dst; *s != '\0'; s++) {
923d522f475Smrg	if (*s == '#' || *s == '%' || *s == 'S') {
924d522f475Smrg	    s[1] = '\0';
925d522f475Smrg	} else if (*s == ' ') {
926d522f475Smrg	    *s = '\0';
927d522f475Smrg	    break;
928d522f475Smrg	}
929d522f475Smrg    }
930d522f475Smrg    return dst;
931d522f475Smrg}
932d522f475Smrg
933d522f475Smrgstatic Bool
934d522f475Smrgsame_option(OptionHelp * opt, XrmOptionDescRec * res)
935d522f475Smrg{
936d522f475Smrg    char temp[BUFSIZ];
937d522f475Smrg    return !strcmp(parse_option(temp, opt->opt, res->option[0]), res->option);
938d522f475Smrg}
939d522f475Smrg
940d522f475Smrgstatic Bool
94120d2c4d2Smrgstandard_option(String opt)
942d522f475Smrg{
943d522f475Smrg    static const char *table[] =
944d522f475Smrg    {
945d522f475Smrg	"+rv",
946d522f475Smrg	"+synchronous",
947d522f475Smrg	"-background",
948d522f475Smrg	"-bd",
949d522f475Smrg	"-bg",
950d522f475Smrg	"-bordercolor",
951d522f475Smrg	"-borderwidth",
952d522f475Smrg	"-bw",
953d522f475Smrg	"-display",
954d522f475Smrg	"-fg",
955d522f475Smrg	"-fn",
956d522f475Smrg	"-font",
957d522f475Smrg	"-foreground",
958d522f475Smrg	"-geometry",
959d522f475Smrg	"-iconic",
960d522f475Smrg	"-name",
961d522f475Smrg	"-reverse",
962d522f475Smrg	"-rv",
963d522f475Smrg	"-selectionTimeout",
964d522f475Smrg	"-synchronous",
965d522f475Smrg	"-title",
966d522f475Smrg	"-xnllanguage",
967d522f475Smrg	"-xrm",
968d522f475Smrg	"-xtsessionID",
969d522f475Smrg    };
970d522f475Smrg    Cardinal n;
971d522f475Smrg    char temp[BUFSIZ];
972d522f475Smrg
973d522f475Smrg    opt = parse_option(temp, opt, '-');
974d522f475Smrg    for (n = 0; n < XtNumber(table); n++) {
975d522f475Smrg	if (!strcmp(opt, table[n]))
976d522f475Smrg	    return True;
977d522f475Smrg    }
978d522f475Smrg    return False;
979d522f475Smrg}
980d522f475Smrg
981d522f475Smrg/*
982d522f475Smrg * Analyse the options/help messages for inconsistencies.
983d522f475Smrg */
984d522f475Smrgvoid
985d522f475SmrgTraceOptions(OptionHelp * options, XrmOptionDescRec * resources, Cardinal res_count)
986d522f475Smrg{
987d522f475Smrg    OptionHelp *opt_array = sortedOpts(options, resources, res_count);
988d522f475Smrg    size_t j, k;
989d522f475Smrg    XrmOptionDescRec *res_array = sortedOptDescs(resources, res_count);
990d522f475Smrg    Bool first, found;
991d522f475Smrg
992d522f475Smrg    TRACE(("Checking options-tables for inconsistencies:\n"));
993d522f475Smrg
994d522f475Smrg#if 0
995d522f475Smrg    TRACE(("Options listed in help-message:\n"));
996d522f475Smrg    for (j = 0; options[j].opt != 0; j++)
997d522f475Smrg	TRACE(("%5d %-28s %s\n", j, opt_array[j].opt, opt_array[j].desc));
998d522f475Smrg    TRACE(("Options listed in resource-table:\n"));
999d522f475Smrg    for (j = 0; j < res_count; j++)
1000d522f475Smrg	TRACE(("%5d %-28s %s\n", j, res_array[j].option, res_array[j].specifier));
1001d522f475Smrg#endif
1002d522f475Smrg
1003d522f475Smrg    /* list all options[] not found in resources[] */
1004d522f475Smrg    for (j = 0, first = True; options[j].opt != 0; j++) {
1005d522f475Smrg	found = False;
1006d522f475Smrg	for (k = 0; k < res_count; k++) {
1007d522f475Smrg	    if (same_option(&opt_array[j], &res_array[k])) {
1008d522f475Smrg		found = True;
1009d522f475Smrg		break;
1010d522f475Smrg	    }
1011d522f475Smrg	}
1012d522f475Smrg	if (!found) {
1013d522f475Smrg	    if (first) {
1014d522f475Smrg		TRACE(("Options listed in help, not found in resource list:\n"));
1015d522f475Smrg		first = False;
1016d522f475Smrg	    }
1017d522f475Smrg	    TRACE(("  %-28s%s\n", opt_array[j].opt,
1018d522f475Smrg		   standard_option(opt_array[j].opt) ? " (standard)" : ""));
1019d522f475Smrg	}
1020d522f475Smrg    }
1021d522f475Smrg
1022d522f475Smrg    /* list all resources[] not found in options[] */
1023d522f475Smrg    for (j = 0, first = True; j < res_count; j++) {
1024d522f475Smrg	found = False;
1025d522f475Smrg	for (k = 0; options[k].opt != 0; k++) {
1026d522f475Smrg	    if (same_option(&opt_array[k], &res_array[j])) {
1027d522f475Smrg		found = True;
1028d522f475Smrg		break;
1029d522f475Smrg	    }
1030d522f475Smrg	}
1031d522f475Smrg	if (!found) {
1032d522f475Smrg	    if (first) {
1033d522f475Smrg		TRACE(("Resource list items not found in options-help:\n"));
1034d522f475Smrg		first = False;
1035d522f475Smrg	    }
1036d522f475Smrg	    TRACE(("  %s\n", res_array[j].option));
1037d522f475Smrg	}
1038d522f475Smrg    }
1039d522f475Smrg
1040d522f475Smrg    TRACE(("Resource list items that will be ignored by XtOpenApplication:\n"));
1041d522f475Smrg    for (j = 0; j < res_count; j++) {
1042d522f475Smrg	switch (res_array[j].argKind) {
1043d522f475Smrg	case XrmoptionSkipArg:
1044d522f475Smrg	    TRACE(("  %-28s {param}\n", res_array[j].option));
1045d522f475Smrg	    break;
1046d522f475Smrg	case XrmoptionSkipNArgs:
1047d522f475Smrg	    TRACE(("  %-28s {%ld params}\n", res_array[j].option, (long)
1048d522f475Smrg		   res_array[j].value));
1049d522f475Smrg	    break;
1050d522f475Smrg	case XrmoptionSkipLine:
1051d522f475Smrg	    TRACE(("  %-28s {remainder of line}\n", res_array[j].option));
1052d522f475Smrg	    break;
1053d522f475Smrg	case XrmoptionIsArg:
1054d522f475Smrg	case XrmoptionNoArg:
1055d522f475Smrg	case XrmoptionResArg:
1056d522f475Smrg	case XrmoptionSepArg:
1057d522f475Smrg	case XrmoptionStickyArg:
1058d522f475Smrg	default:
1059d522f475Smrg	    break;
1060d522f475Smrg	}
1061d522f475Smrg    }
1062d522f475Smrg}
1063a1f3da82Smrg#else
1064a1f3da82Smrgextern void empty_trace(void);
1065a1f3da82Smrgvoid
1066a1f3da82Smrgempty_trace(void)
1067a1f3da82Smrg{
1068a1f3da82Smrg}
1069a1f3da82Smrg#endif
1070