diff options
Diffstat (limited to 'nx-X11/programs/xterm/trace.c')
-rw-r--r-- | nx-X11/programs/xterm/trace.c | 490 |
1 files changed, 490 insertions, 0 deletions
diff --git a/nx-X11/programs/xterm/trace.c b/nx-X11/programs/xterm/trace.c new file mode 100644 index 000000000..abaaf634f --- /dev/null +++ b/nx-X11/programs/xterm/trace.c @@ -0,0 +1,490 @@ +/* $XTermId: trace.c,v 1.63 2005/09/18 23:48:13 tom Exp $ */ + +/* + * $XFree86: xc/programs/xterm/trace.c,v 3.23 2005/09/18 23:48:13 dickey Exp $ + */ + +/************************************************************ + +Copyright 1997-2004,2005 by Thomas E. Dickey + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of the above listed +copyright holder(s) not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. + +THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD +TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE +LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +********************************************************/ + +/* + * debugging support via TRACE macro. + */ + +#include <xterm.h> /* for definition of GCC_UNUSED */ +#include <data.h> +#include <trace.h> + +#include <time.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <stdio.h> +#include <stdarg.h> + +#ifdef HAVE_X11_TRANSLATEI_H +#include <X11/TranslateI.h> +#else +#ifdef __cplusplus +extern "C" { +#endif + + extern String _XtPrintXlations(Widget w, + XtTranslations xlations, + Widget accelWidget, + _XtBoolean includeRHS); +#ifdef __cplusplus +} +#endif +#endif +char *trace_who = "parent"; + +void +Trace(char *fmt,...) +{ + static FILE *fp; + static char *trace_out; + va_list ap; + + if (fp != 0 + && trace_who != trace_out) { + fclose(fp); + fp = 0; + } + trace_out = trace_who; + + if (!fp) { + char name[BUFSIZ]; +#if 0 /* usually I do not want unique names */ + int unique; + for (unique = 0;; ++unique) { + if (unique) + sprintf(name, "Trace-%s.out-%d", trace_who, unique); + else + sprintf(name, "Trace-%s.out", trace_who); + if ((fp = fopen(name, "r")) == 0) { + break; + } + fclose(fp); + } +#else + sprintf(name, "Trace-%s.out", trace_who); +#endif + fp = fopen(name, "w"); + if (fp != 0) { + time_t now = time((time_t *) 0); + fprintf(fp, "%s\n", xtermVersion()); +#ifdef HAVE_UNISTD_H + fprintf(fp, "process %d real (%u/%u) effective (%u/%u) -- %s", + getpid(), + (unsigned) getuid(), (unsigned) getgid(), + (unsigned) geteuid(), (unsigned) getegid(), + ctime(&now)); +#else + fprintf(fp, "process %d -- %s", + getpid(), + ctime(&now)); +#endif + } + } + if (!fp) + abort(); + + va_start(ap, fmt); + if (fmt != 0) { + vfprintf(fp, fmt, ap); + (void) fflush(fp); + } else { + (void) fclose(fp); + (void) fflush(stdout); + (void) fflush(stderr); + } + va_end(ap); +} + +char * +visibleChars(PAIRED_CHARS(Char * buf, Char * buf2), unsigned len) +{ + static char *result; + static unsigned used; + unsigned limit = ((len + 1) * 8) + 1; + char *dst; + + if (limit > used) { + used = limit; + result = XtRealloc(result, used); + } + dst = result; + while (len--) { + unsigned value = *buf++; +#if OPT_WIDE_CHARS + if (buf2 != 0) { + value |= (*buf2 << 8); + buf2++; + } + if (value > 255) + sprintf(dst, "\\u+%04X", value); + else +#endif + if (E2A(value) < 32 || (E2A(value) >= 127 && E2A(value) < 160)) + sprintf(dst, "\\%03o", value); + else + sprintf(dst, "%c", CharOf(value)); + dst += strlen(dst); + } + return result; +} + +char * +visibleIChar(IChar * buf, unsigned len) +{ + static char *result; + static unsigned used; + unsigned limit = ((len + 1) * 6) + 1; + char *dst; + + if (limit > used) { + used = limit; + result = XtRealloc(result, used); + } + dst = result; + while (len--) { + unsigned value = *buf++; +#if OPT_WIDE_CHARS + if (value > 255) + sprintf(dst, "\\u+%04X", value); + else +#endif + if (E2A(value) < 32 || (E2A(value) >= 127 && E2A(value) < 160)) + sprintf(dst, "\\%03o", value); + else + sprintf(dst, "%c", CharOf(value)); + dst += strlen(dst); + } + return result; +} + +#define CASETYPE(name) case name: result = #name; break; + +const char * +visibleKeyboardType(xtermKeyboardType type) +{ + const char *result = "?"; + switch (type) { + CASETYPE(keyboardIsLegacy); /* bogus vt220 codes for F1-F4, etc. */ + CASETYPE(keyboardIsDefault); + CASETYPE(keyboardIsHP); + CASETYPE(keyboardIsSCO); + CASETYPE(keyboardIsSun); + CASETYPE(keyboardIsVT220); + } + return result; +} + +void +TraceSizeHints(XSizeHints * hints) +{ + TRACE(("size hints:\n")); + if (hints->flags & (USPosition | PPosition)) + TRACE((" position %d,%d%s%s\n", hints->y, hints->x, + hints->flags & USPosition ? " user" : "", + hints->flags & PPosition ? " prog" : "")); + if (hints->flags & (USSize | PSize)) + TRACE((" size %d,%d%s%s\n", hints->height, hints->width, + hints->flags & USSize ? " user" : "", + hints->flags & PSize ? " prog" : "")); + if (hints->flags & PMinSize) + TRACE((" min %d,%d\n", hints->min_height, hints->min_width)); + if (hints->flags & PMaxSize) + TRACE((" max %d,%d\n", hints->max_height, hints->max_width)); + if (hints->flags & PResizeInc) + TRACE((" inc %d,%d\n", hints->height_inc, hints->width_inc)); + if (hints->flags & PAspect) + TRACE((" min aspect %d/%d\n", hints->min_aspect.y, hints->min_aspect.y)); + if (hints->flags & PAspect) + TRACE((" max aspect %d/%d\n", hints->max_aspect.y, hints->max_aspect.y)); + if (hints->flags & PBaseSize) + TRACE((" base %d,%d\n", hints->base_height, hints->base_width)); + if (hints->flags & PWinGravity) + TRACE((" gravity %d\n", hints->win_gravity)); +} + +void +TraceWMSizeHints(XtermWidget xw) +{ + XSizeHints sizehints; + long supp = 0; + + bzero(&sizehints, sizeof(sizehints)); + if (!XGetWMNormalHints(xw->screen.display, XtWindow(SHELL_OF(xw)), + &sizehints, &supp)) + bzero(&sizehints, sizeof(sizehints)); + TraceSizeHints(&sizehints); +} + +/* + * Some calls to XGetAtom() will fail, and we don't want to stop. So we use + * our own error-handler. + */ +static int +no_error(Display * dpy GCC_UNUSED, XErrorEvent * event GCC_UNUSED) +{ + return 1; +} + +void +TraceTranslations(const char *name, Widget w) +{ + String result; + XErrorHandler save = XSetErrorHandler(no_error); + XtTranslations xlations; + Widget xcelerat; + + TRACE(("TraceTranslations for %s (widget %#lx)\n", name, (long) w)); + if (w) { + XtVaGetValues(w, + XtNtranslations, &xlations, + XtNaccelerators, &xcelerat, + (XtPointer) 0); + TRACE(("... xlations %#08lx\n", (long) xlations)); + TRACE(("... xcelerat %#08lx\n", (long) xcelerat)); + result = _XtPrintXlations(w, xlations, xcelerat, True); + TRACE(("%s\n", result != 0 ? result : "(null)")); + if (result) + XFree(result); + } else { + TRACE(("none (widget is null)\n")); + } + XSetErrorHandler(save); +} + +#define XRES_S(name) Trace(#name " = %s\n", NonNull(resp->name)) +#define XRES_B(name) Trace(#name " = %s\n", BtoS(resp->name)) +#define XRES_I(name) Trace(#name " = %d\n", resp->name) + +void +TraceXtermResources(void) +{ + XTERM_RESOURCE *resp = &resource; + + Trace("XTERM_RESOURCE settings:\n"); + XRES_S(xterm_name); + XRES_S(icon_geometry); + XRES_S(title); + XRES_S(icon_name); + XRES_S(term_name); + XRES_S(tty_modes); + XRES_B(hold_screen); + XRES_B(utmpInhibit); + XRES_B(utmpDisplayId); + XRES_B(messages); + XRES_B(sunFunctionKeys); +#if OPT_SUNPC_KBD + XRES_B(sunKeyboard); +#endif +#if OPT_HP_FUNC_KEYS + XRES_B(hpFunctionKeys); +#endif +#if OPT_SCO_FUNC_KEYS + XRES_B(scoFunctionKeys); +#endif +#if OPT_INITIAL_ERASE + XRES_B(ptyInitialErase); + XRES_B(backarrow_is_erase); +#endif + XRES_B(wait_for_map); + XRES_B(useInsertMode); +#if OPT_ZICONBEEP + XRES_I(zIconBeep); +#endif +#if OPT_PTY_HANDSHAKE + XRES_B(ptyHandshake); +#endif +#if OPT_SAME_NAME + XRES_B(sameName); +#endif +#if OPT_SESSION_MGT + XRES_B(sessionMgt); +#endif +} + +void +TraceArgv(const char *tag, char **argv) +{ + int n = 0; + + TRACE(("%s:\n", tag)); + while (*argv != 0) { + TRACE((" %d:%s\n", n++, *argv++)); + } +} + +static char * +parse_option(char *dst, char *src, int first) +{ + char *s; + + if (!strncmp(src, "-/+", 3)) { + dst[0] = first; + strcpy(dst + 1, src + 3); + } else { + strcpy(dst, src); + } + for (s = dst; *s != '\0'; s++) { + if (*s == '#' || *s == '%' || *s == 'S') { + s[1] = '\0'; + } else if (*s == ' ') { + *s = '\0'; + break; + } + } + return dst; +} + +static Bool +same_option(OptionHelp * opt, XrmOptionDescRec * res) +{ + char temp[BUFSIZ]; + return !strcmp(parse_option(temp, opt->opt, res->option[0]), res->option); +} + +static Bool +standard_option(char *opt) +{ + static const char *table[] = + { + "+rv", + "+synchronous", + "-background", + "-bd", + "-bg", + "-bordercolor", + "-borderwidth", + "-bw", + "-display", + "-fg", + "-fn", + "-font", + "-foreground", + "-geometry", + "-iconic", + "-name", + "-reverse", + "-rv", + "-selectionTimeout", + "-synchronous", + "-title", + "-xnllanguage", + "-xrm", + "-xtsessionID", + }; + Cardinal n; + char temp[BUFSIZ]; + + opt = parse_option(temp, opt, '-'); + for (n = 0; n < XtNumber(table); n++) { + if (!strcmp(opt, table[n])) + return True; + } + return False; +} + +/* + * Analyse the options/help messages for inconsistencies. + */ +void +TraceOptions(OptionHelp * options, XrmOptionDescRec * resources, Cardinal res_count) +{ + OptionHelp *opt_array = sortedOpts(options, resources, res_count); + size_t j, k; + XrmOptionDescRec *res_array = sortedOptDescs(resources, res_count); + Bool first, found; + + TRACE(("Checking options-tables for inconsistencies:\n")); + +#if 0 + TRACE(("Options listed in help-message:\n")); + for (j = 0; options[j].opt != 0; j++) + TRACE(("%5d %-28s %s\n", j, opt_array[j].opt, opt_array[j].desc)); + TRACE(("Options listed in resource-table:\n")); + for (j = 0; j < res_count; j++) + TRACE(("%5d %-28s %s\n", j, res_array[j].option, res_array[j].specifier)); +#endif + + /* list all options[] not found in resources[] */ + for (j = 0, first = True; options[j].opt != 0; j++) { + found = False; + for (k = 0; k < res_count; k++) { + if (same_option(&opt_array[j], &res_array[k])) { + found = True; + break; + } + } + if (!found) { + if (first) { + TRACE(("Options listed in help, not found in resource list:\n")); + first = False; + } + TRACE((" %-28s%s\n", opt_array[j].opt, + standard_option(opt_array[j].opt) ? " (standard)" : "")); + } + } + + /* list all resources[] not found in options[] */ + for (j = 0, first = True; j < res_count; j++) { + found = False; + for (k = 0; options[k].opt != 0; k++) { + if (same_option(&opt_array[k], &res_array[j])) { + found = True; + break; + } + } + if (!found) { + if (first) { + TRACE(("Resource list items not found in options-help:\n")); + first = False; + } + TRACE((" %s\n", res_array[j].option)); + } + } + + TRACE(("Resource list items that will be ignored by XtOpenApplication:\n")); + for (j = 0; j < res_count; j++) { + switch (res_array[j].argKind) { + case XrmoptionSkipArg: + TRACE((" %-28s {param}\n", res_array[j].option)); + break; + case XrmoptionSkipNArgs: + TRACE((" %-28s {%ld params}\n", res_array[j].option, (long) + res_array[j].value)); + break; + case XrmoptionSkipLine: + TRACE((" %-28s {remainder of line}\n", res_array[j].option)); + break; + default: + break; + } + } +} |