X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=progs%2Fdump_entry.c;h=7be9b9127b82535c8e25f8c87315bed3672ab730;hp=0f4e7c56cf066d9e2f14a886aeb21892ae6c4960;hb=aa70bf3c762c5b6407bf34812d63c20f7ac8ffdd;hpb=b6d0d9ad9e372e856f01a4c283cf784a15993903;ds=sidebyside diff --git a/progs/dump_entry.c b/progs/dump_entry.c index 0f4e7c56..7be9b912 100644 --- a/progs/dump_entry.c +++ b/progs/dump_entry.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2011,2012 Free Software Foundation, Inc. * + * Copyright (c) 1998-2014,2015 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -39,9 +39,8 @@ #include "termsort.c" /* this C file is generated */ #include /* so is this */ -MODULE_ID("$Id: dump_entry.c,v 1.100 2012/06/09 21:44:40 tom Exp $") +MODULE_ID("$Id: dump_entry.c,v 1.124 2015/11/28 22:54:33 tom Exp $") -#define INDENT 8 #define DISCARD(string) string = ABSENT_STRING #define PRINTF (void) printf @@ -61,6 +60,8 @@ static int height = 65535; /* max number of lines for listings */ static int column; /* current column, limited by 'width' */ static int oldcol; /* last value of column before wrap */ static bool pretty; /* true if we format if-then-else strings */ +static bool checking; /* true if we are checking for tic */ +static int quickdump; /* true if we are dumping compiled data */ static char *save_sgr; @@ -73,7 +74,8 @@ static NCURSES_CONST char *const *bool_names; static NCURSES_CONST char *const *num_names; static NCURSES_CONST char *const *str_names; -static const char *separator, *trailer; +static const char *separator = "", *trailer = ""; +static int indent = 8; /* cover various ports and variants of terminfo */ #define V_ALLCAPS 0 /* all capabilities (SVr4, XSI, ncurses) */ @@ -100,6 +102,15 @@ static const char *separator, *trailer; #define StrIndirect(j) ((sortmode == S_NOSORT) ? (j) : str_indirect[j]) #endif +static void failed(const char *) GCC_NORETURN; + +static void +failed(const char *s) +{ + perror(s); + ExitProgram(EXIT_FAILURE); +} + static void strncpy_DYN(DYNBUF * dst, const char *src, size_t need) { @@ -107,6 +118,8 @@ strncpy_DYN(DYNBUF * dst, const char *src, size_t need) if (want > dst->size) { dst->size += (want + 1024); /* be generous */ dst->text = typeRealloc(char, dst->size, dst->text); + if (dst->text == 0) + failed("strncpy_DYN"); } (void) strncpy(dst->text + dst->used, src, need); dst->used += need; @@ -144,17 +157,17 @@ _nc_leaks_dump_entry(void) #endif #define NameTrans(check,result) \ - if (OkIndex(np->nte_index, check) \ + if ((np->nte_index <= OK_ ## check) \ && check[np->nte_index]) \ return (result[np->nte_index]) NCURSES_CONST char * nametrans(const char *name) -/* translate a capability name from termcap to terminfo */ +/* translate a capability name to termcap from terminfo */ { const struct name_table_entry *np; - if ((np = _nc_find_entry(name, _nc_get_hash_table(0))) != 0) + if ((np = _nc_find_entry(name, _nc_get_hash_table(0))) != 0) { switch (np->nte_type) { case BOOLEAN: NameTrans(bool_from_termcap, boolcodes); @@ -168,6 +181,7 @@ nametrans(const char *name) NameTrans(str_from_termcap, strcodes); break; } + } return (0); } @@ -179,12 +193,16 @@ dump_init(const char *version, int twidth, int theight, unsigned traceval, - bool formatted) + bool formatted, + bool check, + int quick) /* set up for entry display */ { width = twidth; height = theight; pretty = formatted; + checking = check; + quickdump = (quick & 3); /* versions */ if (version == 0) @@ -229,6 +247,7 @@ dump_init(const char *version, trailer = "\\\n\t:"; break; } + indent = 8; /* implement sort modes */ switch (sortmode = sort) { @@ -298,7 +317,11 @@ dump_predicate(PredType type, PredIdx idx) static void set_obsolete_termcaps(TERMTYPE *tp); /* is this the index of a function key string? */ -#define FNKEY(i) (((i)<= 65 && (i)>= 75) || ((i)<= 216 && (i)>= 268)) +#define FNKEY(i) \ + (((i) >= STR_IDX(key_f0) && \ + (i) <= STR_IDX(key_f9)) || \ + ((i) >= STR_IDX(key_f11) && \ + (i) <= STR_IDX(key_f63))) /* * If we configure with a different Caps file, the offsets into the arrays @@ -394,7 +417,7 @@ force_wrap(void) oldcol = column; trim_trailing(); strcpy_DYN(&outbuf, trailer); - column = INDENT; + column = indent; } static void @@ -403,7 +426,7 @@ wrap_concat(const char *src) size_t need = strlen(src); size_t want = strlen(separator) + need; - if (column > INDENT + if (column > indent && column + (int) want > width) { force_wrap(); } @@ -452,10 +475,10 @@ indent_DYN(DYNBUF * buffer, int level) int n; for (n = 0; n < level; n++) - strncpy_DYN(buffer, "\t", 1); + strncpy_DYN(buffer, "\t", (size_t) 1); } -static bool +bool has_params(const char *src) { bool result = FALSE; @@ -465,9 +488,9 @@ has_params(const char *src) bool params = FALSE; for (n = 0; n < len - 1; ++n) { - if (!strncmp(src + n, "%p", 2)) { + if (!strncmp(src + n, "%p", (size_t) 2)) { params = TRUE; - } else if (!strncmp(src + n, "%;", 2)) { + } else if (!strncmp(src + n, "%;", (size_t) 2)) { ifthen = TRUE; result = params; break; @@ -480,16 +503,20 @@ has_params(const char *src) } static char * -fmt_complex(char *src, int level) +fmt_complex(TERMTYPE *tterm, const char *capability, char *src, int level) { bool percent = FALSE; bool params = has_params(src); while (*src != '\0') { switch (*src) { + case '^': + percent = FALSE; + strncpy_DYN(&tmpbuf, src++, (size_t) 1); + break; case '\\': percent = FALSE; - strncpy_DYN(&tmpbuf, src++, 1); + strncpy_DYN(&tmpbuf, src++, (size_t) 1); break; case '%': percent = TRUE; @@ -503,26 +530,29 @@ fmt_complex(char *src, int level) /* treat a "%e" as else-if, on the same level */ if (*src == 'e') { indent_DYN(&tmpbuf, level); - strncpy_DYN(&tmpbuf, "%", 1); - strncpy_DYN(&tmpbuf, src, 1); + strncpy_DYN(&tmpbuf, "%", (size_t) 1); + strncpy_DYN(&tmpbuf, src, (size_t) 1); src++; params = has_params(src); if (!params && *src != '\0' && *src != '%') { - strncpy_DYN(&tmpbuf, "\n", 1); + strncpy_DYN(&tmpbuf, "\n", (size_t) 1); indent_DYN(&tmpbuf, level + 1); } } else { indent_DYN(&tmpbuf, level + 1); - strncpy_DYN(&tmpbuf, "%", 1); - strncpy_DYN(&tmpbuf, src, 1); + strncpy_DYN(&tmpbuf, "%", (size_t) 1); + strncpy_DYN(&tmpbuf, src, (size_t) 1); if (*src++ == '?') { - src = fmt_complex(src, level + 1); + src = fmt_complex(tterm, capability, src, level + 1); if (*src != '\0' && *src != '%') { - strncpy_DYN(&tmpbuf, "\n", 1); + strncpy_DYN(&tmpbuf, "\n", (size_t) 1); indent_DYN(&tmpbuf, level + 1); } } else if (level == 1) { - _nc_warning("%%%c without %%?", *src); + if (checking) + _nc_warning("%s: %%%c without %%? in %s", + _nc_first_name(tterm->term_names), + *src, capability); } } continue; @@ -534,31 +564,40 @@ fmt_complex(char *src, int level) if (level > 1) { tmpbuf.text[tmpbuf.used - 1] = '\n'; indent_DYN(&tmpbuf, level); - strncpy_DYN(&tmpbuf, "%", 1); - strncpy_DYN(&tmpbuf, src++, 1); + strncpy_DYN(&tmpbuf, "%", (size_t) 1); + strncpy_DYN(&tmpbuf, src++, (size_t) 1); + if (src[0] == '%' + && src[1] != '\0' + && (strchr("?e;", src[1])) == 0) { + tmpbuf.text[tmpbuf.used++] = '\n'; + indent_DYN(&tmpbuf, level); + } return src; } - _nc_warning("%%; without %%?"); + if (checking) + _nc_warning("%s: %%; without %%? in %s", + _nc_first_name(tterm->term_names), + capability); } break; case 'p': if (percent && params) { tmpbuf.text[tmpbuf.used - 1] = '\n'; indent_DYN(&tmpbuf, level + 1); - strncpy_DYN(&tmpbuf, "%", 1); + strncpy_DYN(&tmpbuf, "%", (size_t) 1); } params = FALSE; percent = FALSE; break; case ' ': - strncpy_DYN(&tmpbuf, "\\s", 2); + strncpy_DYN(&tmpbuf, "\\s", (size_t) 2); ++src; continue; default: percent = FALSE; break; } - strncpy_DYN(&tmpbuf, src++, 1); + strncpy_DYN(&tmpbuf, src++, (size_t) 1); } return src; } @@ -569,9 +608,9 @@ fmt_complex(char *src, int level) int fmt_entry(TERMTYPE *tterm, PredFunc pred, - bool content_only, - bool suppress_untranslatable, - bool infodump, + int content_only, + int suppress_untranslatable, + int infodump, int numbers) { PredIdx i, j; @@ -597,7 +636,7 @@ fmt_entry(TERMTYPE *tterm, strcpy_DYN(&outbuf, 0); if (content_only) { - column = INDENT; /* FIXME: workaround to prevent empty lines */ + column = indent; /* FIXME: workaround to prevent empty lines */ } else { strcpy_DYN(&outbuf, tterm->term_names); @@ -640,7 +679,7 @@ fmt_entry(TERMTYPE *tterm, } } - if (column != INDENT && height > 1) + if (column != indent && height > 1) force_wrap(); for_each_number(j, tterm) { @@ -668,7 +707,7 @@ fmt_entry(TERMTYPE *tterm, } } - if (column != INDENT && height > 1) + if (column != indent && height > 1) force_wrap(); len += (int) (num_bools @@ -747,6 +786,10 @@ fmt_entry(TERMTYPE *tterm, trimmed_sgr0 = _nc_trim_sgr0(tterm); if (strcmp(capability, trimmed_sgr0)) capability = trimmed_sgr0; + else { + if (trimmed_sgr0 != exit_attribute_mode) + free(trimmed_sgr0); + } set_attributes = my_sgr; } @@ -766,10 +809,13 @@ fmt_entry(TERMTYPE *tterm, "%s@", name); WRAP_CONCAT; } else if (outform == F_TERMCAP || outform == F_TCONVERR) { - int params = ((i < (int) SIZEOF(parametrized)) - ? parametrized[i] - : 0); char *srccap = _nc_tic_expand(capability, TRUE, numbers); + int params = (((i < (int) SIZEOF(parametrized)) && + (i < STRCOUNT)) + ? parametrized[i] + : ((*srccap == 'k') + ? 0 + : has_params(srccap))); char *cv = _nc_infotocap(name, srccap, params); if (cv == 0) { @@ -809,7 +855,7 @@ fmt_entry(TERMTYPE *tterm, if (pretty && (outform == F_TERMINFO || outform == F_VARIABLE)) { - fmt_complex(src, 1); + fmt_complex(tterm, name, src, 1); } else { strcpy_DYN(&tmpbuf, src); } @@ -819,7 +865,9 @@ fmt_entry(TERMTYPE *tterm, } } /* e.g., trimmed_sgr0 */ - if (capability != tterm->Strings[i]) + if (capability != ABSENT_STRING && + capability != CANCELLED_STRING && + capability != tterm->Strings[i]) free(capability); } len += (int) (num_strings * 2); @@ -849,7 +897,7 @@ fmt_entry(TERMTYPE *tterm, tp = boxchars; for (cp = acstrans; *cp; cp++) { - sp = strchr(acs_chars, *cp); + sp = (strchr) (acs_chars, *cp); if (sp) *tp++ = sp[1]; else { @@ -860,11 +908,41 @@ fmt_entry(TERMTYPE *tterm, tp[0] = '\0'; if (box_ok) { + char *tmp = _nc_tic_expand(boxchars, + (outform == F_TERMINFO), + numbers); _nc_STRCPY(buffer, "box1=", sizeof(buffer)); - _nc_STRCAT(buffer, - _nc_tic_expand(boxchars, - outform == F_TERMINFO, numbers), - sizeof(buffer)); + while (*tmp != '\0') { + size_t have = strlen(buffer); + size_t next = strlen(tmp); + size_t want = have + next + 1; + size_t last = next; + char save = '\0'; + + /* + * If the expanded string is too long for the buffer, + * chop it off and save the location where we chopped it. + */ + if (want >= sizeof(buffer)) { + save = tmp[last]; + tmp[last] = '\0'; + } + _nc_STRCAT(buffer, tmp, sizeof(buffer)); + + /* + * If we chopped the buffer, replace the missing piece and + * shift everything to append the remainder. + */ + if (save != '\0') { + next = 0; + tmp[last] = save; + while ((tmp[next] = tmp[last + next]) != '\0') { + ++next; + } + } else { + break; + } + } WRAP_CONCAT; } } @@ -1042,13 +1120,41 @@ purged_acs(TERMTYPE *tterm) return result; } +static void +encode_b64(char *target, char *source, unsigned state, int *saved) +{ + /* RFC-4648 */ + static const char data[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" "-_"; + int ch = UChar(source[state]); + + switch (state % 3) { + case 0: + *target++ = data[ch & 077]; + *saved = (ch >> 6) & 3; + break; + case 1: + *target++ = data[((ch << 2) | *saved) & 077]; + *saved = (ch >> 4) & 017; + break; + case 2: + *target++ = data[((ch << 4) | *saved) & 077]; + *target++ = data[(ch >> 2) & 077]; + *saved = 0; + break; + } + *target = '\0'; +} + /* * Dump a single entry. */ void dump_entry(TERMTYPE *tterm, - bool suppress_untranslatable, - bool limited, + int suppress_untranslatable, + int limited, int numbers, PredFunc pred) { @@ -1057,6 +1163,48 @@ dump_entry(TERMTYPE *tterm, const char *legend; bool infodump; + if (quickdump) { + char bigbuf[65536]; + unsigned n; + unsigned offset = 0; + separator = ""; + trailer = "\n"; + indent = 0; + if (_nc_write_object(tterm, bigbuf, &offset, sizeof(bigbuf)) == OK) { + char numbuf[80]; + if (quickdump & 1) { + if (outbuf.used) + wrap_concat("\n"); + wrap_concat("hex:"); + for (n = 0; n < offset; ++n) { + sprintf(numbuf, "%02X", UChar(bigbuf[n])); + wrap_concat(numbuf); + } + } + if (quickdump & 2) { + int value = 0; + if (outbuf.used) + wrap_concat("\n"); + wrap_concat("b64:"); + for (n = 0; n < offset; ++n) { + encode_b64(numbuf, bigbuf, n, &value); + wrap_concat(numbuf); + } + switch (n % 3) { + case 0: + break; + case 1: + wrap_concat("==="); + break; + case 2: + wrap_concat("=="); + break; + } + } + } + return; + } + if (outform == F_TERMCAP || outform == F_TCONVERR) { critlen = MAX_TERMCAP_LENGTH; legend = "older termcap"; @@ -1206,8 +1354,10 @@ show_entry(void) } outbuf.text[outbuf.used] = '\0'; } - (void) fputs(outbuf.text, stdout); - putchar('\n'); + if (outbuf.text != 0) { + (void) fputs(outbuf.text, stdout); + putchar('\n'); + } return (int) outbuf.used; }