=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tic/dump_entry.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- src/usr.bin/tic/dump_entry.c 2000/03/13 23:53:41 1.14 +++ src/usr.bin/tic/dump_entry.c 2000/06/19 03:53:58 1.15 @@ -1,4 +1,4 @@ -/* $OpenBSD: dump_entry.c,v 1.14 2000/03/13 23:53:41 millert Exp $ */ +/* $OpenBSD: dump_entry.c,v 1.15 2000/06/19 03:53:58 millert Exp $ */ /**************************************************************************** * Copyright (c) 1998-2000 Free Software Foundation, Inc. * @@ -40,12 +40,18 @@ #include /* this C file is generated */ #include /* so is this */ -MODULE_ID("$From: dump_entry.c,v 1.48 2000/03/12 02:33:01 tom Exp $") +MODULE_ID("$From: dump_entry.c,v 1.53 2000/04/15 21:23:30 tom Exp $") #define INDENT 8 #define DISCARD(string) string = ABSENT_STRING #define PRINTF (void) printf +typedef struct { + char *text; + size_t used; + size_t size; +} DYNBUF; + static int tversion; /* terminfo version */ static int outform; /* output format to use */ static int sortmode; /* sort mode to use */ @@ -55,9 +61,8 @@ static int tracelevel; /* level of debug output */ static bool pretty; /* true if we format if-then-else strings */ -static char *outbuf; /* the output-buffer */ -static size_t out_used; /* ...its current length */ -static size_t out_size; /* ...and its allocated length */ +static DYNBUF outbuf; +static DYNBUF tmpbuf; /* indirection pointers for implementing sort and display modes */ static const int *bool_indirect, *num_indirect, *str_indirect; @@ -92,14 +97,46 @@ #define StrIndirect(j) ((sortmode == S_NOSORT) ? (j) : str_indirect[j]) #endif +static void +strncpy_DYN(DYNBUF * dst, const char *src, size_t need) +{ + size_t want = need + dst->used + 1; + if (want > dst->size) { + dst->size += (want + 1024); /* be generous */ + dst->text = typeRealloc(char, dst->size, dst->text); + } + (void) strncpy(dst->text + dst->used, src, need); + dst->used += need; + dst->text[dst->used] = 0; +} + +static void +strcpy_DYN(DYNBUF * dst, const char *src) +{ + if (src == 0) { + dst->used = 0; + strcpy_DYN(dst, ""); + } else { + strncpy_DYN(dst, src, strlen(src)); + } +} + #if NO_LEAKS +static void +free_DYN(DYNBUF * p) +{ + if (p->text != 0) + free(p->text); + p->text = 0; + p->size = 0; + p->used = 0; +} + void _nc_leaks_dump_entry(void) { - if (outbuf != 0) { - free(outbuf); - outbuf = 0; - } + free_DYN(&outbuf); + free_DYN(&tmpbuf); } #endif @@ -329,31 +366,10 @@ } static void -append_output(const char *src) -{ - if (src == 0) { - out_used = 0; - append_output(""); - } else { - size_t need = strlen(src); - size_t want = need + out_used + 1; - if (want > out_size) { - out_size += want; /* be generous */ - if (outbuf == 0) - outbuf = malloc(out_size); - else - outbuf = realloc(outbuf, out_size); - } - (void) strcpy(outbuf + out_used, src); - out_used += need; - } -} - -static void force_wrap(void) { oldcol = column; - append_output(trailer); + strcpy_DYN(&outbuf, trailer); column = INDENT; } @@ -367,8 +383,8 @@ && column + want > width) { force_wrap(); } - append_output(src); - append_output(separator); + strcpy_DYN(&outbuf, src); + strcpy_DYN(&outbuf, separator); column += need; } @@ -407,19 +423,18 @@ #endif static char * -fmt_complex(char *dst, char *src, int level) +fmt_complex(char *src, int level) { int percent = 0; int n; bool if_then = strstr(src, "%?") != 0; bool params = !if_then && (strlen(src) > 50) && (strstr(src, "%p") != 0); - dst += strlen(dst); while (*src != '\0') { switch (*src) { case '\\': percent = 0; - *dst++ = *src++; + strncpy_DYN(&tmpbuf, src++, 1); break; case '%': percent = 1; @@ -429,17 +444,24 @@ case 'e': /* "else" */ if (percent) { percent = 0; - dst[-1] = '\n'; - for (n = 0; n <= level; n++) - *dst++ = '\t'; - *dst++ = '%'; - *dst++ = *src; - *dst = '\0'; - if (*src++ == '?') { - src = fmt_complex(dst, src, level + 1); - dst += strlen(dst); - } else if (level == 1) { - _nc_warning("%%%c without %%?", *src); + tmpbuf.text[tmpbuf.used - 1] = '\n'; + /* treat a "%e%?" as else-if, on the same level */ + if (!strncmp(src, "e%?", 3)) { + for (n = 0; n < level; n++) + strncpy_DYN(&tmpbuf, "\t", 1); + strncpy_DYN(&tmpbuf, "%", 1); + strncpy_DYN(&tmpbuf, src, 3); + src += 3; + } else { + for (n = 0; n <= level; n++) + strncpy_DYN(&tmpbuf, "\t", 1); + strncpy_DYN(&tmpbuf, "%", 1); + strncpy_DYN(&tmpbuf, src, 1); + if (*src++ == '?') { + src = fmt_complex(src, level + 1); + } else if (level == 1) { + _nc_warning("%%%c without %%?", *src); + } } continue; } @@ -448,12 +470,11 @@ if (percent) { percent = 0; if (level > 1) { - dst[-1] = '\n'; + tmpbuf.text[tmpbuf.used - 1] = '\n'; for (n = 0; n < level; n++) - *dst++ = '\t'; - *dst++ = '%'; - *dst++ = *src++; - *dst = '\0'; + strncpy_DYN(&tmpbuf, "\t", 1); + strncpy_DYN(&tmpbuf, "%", 1); + strncpy_DYN(&tmpbuf, src++, 1); return src; } _nc_warning("%%; without %%?"); @@ -461,10 +482,10 @@ break; case 'p': if (percent && params) { - dst[-1] = '\n'; + tmpbuf.text[tmpbuf.used - 1] = '\n'; for (n = 0; n <= level; n++) - *dst++ = '\t'; - *dst++ = '%'; + strncpy_DYN(&tmpbuf, "\t", 1); + strncpy_DYN(&tmpbuf, "%", 1); } percent = 0; break; @@ -472,9 +493,8 @@ percent = 0; break; } - *dst++ = *src++; + strncpy_DYN(&tmpbuf, src++, 1); } - *dst = '\0'; return src; } @@ -505,10 +525,10 @@ pred = dump_predicate; } - append_output(0); - append_output(tterm->term_names); - append_output(separator); - column = out_used; + strcpy_DYN(&outbuf, 0); + strcpy_DYN(&outbuf, tterm->term_names); + strcpy_DYN(&outbuf, separator); + column = outbuf.used; force_wrap(); for_each_boolean(j, tterm) { @@ -565,6 +585,20 @@ if (len & 1) len++; +#undef CUR +#define CUR tterm-> + if (outform == F_TERMCAP) { + if (termcap_reset != ABSENT_STRING) { + if (init_3string != ABSENT_STRING + && !strcmp(init_3string, termcap_reset)) + DISCARD(init_3string); + + if (reset_2string != ABSENT_STRING + && !strcmp(reset_2string, termcap_reset)) + DISCARD(reset_2string); + } + } + for_each_string(j, tterm) { i = StrIndirect(j); name = ExtStrname(tterm, i, str_names); @@ -580,52 +614,45 @@ * them to be output as defined and empty. */ if (outform == F_TERMCAP) { -#undef CUR -#define CUR tterm-> if (insert_character || parm_ich) { if (&tterm->Strings[i] == &enter_insert_mode && enter_insert_mode == ABSENT_STRING) { (void) strcpy(buffer, "im="); - goto catenate; + WRAP_CONCAT; + continue; } if (&tterm->Strings[i] == &exit_insert_mode && exit_insert_mode == ABSENT_STRING) { (void) strcpy(buffer, "ei="); - goto catenate; + WRAP_CONCAT; + continue; } } - - if (termcap_reset != ABSENT_STRING) { - if (init_3string != ABSENT_STRING - && !strcmp(init_3string, termcap_reset)) - DISCARD(init_3string); - - if (reset_2string != ABSENT_STRING - && !strcmp(reset_2string, termcap_reset)) - DISCARD(reset_2string); - } } predval = pred(STRING, i); buffer[0] = '\0'; + if (predval != FAIL) { if (tterm->Strings[i] != ABSENT_STRING && i + 1 > num_strings) num_strings = i + 1; - if (!VALID_STRING(tterm->Strings[i])) + + if (!VALID_STRING(tterm->Strings[i])) { sprintf(buffer, "%s@", name); - else if (outform == F_TERMCAP || outform == F_TCONVERR) { + WRAP_CONCAT; + } else if (outform == F_TERMCAP || outform == F_TCONVERR) { char *srccap = _nc_tic_expand(tterm->Strings[i], TRUE, numbers); char *cv = _nc_infotocap(name, srccap, parametrized[i]); if (cv == 0) { - if (outform == F_TCONVERR) + if (outform == F_TCONVERR) { sprintf(buffer, "%s=!!! %s WILL NOT CONVERT !!!", name, srccap); - else if (suppress_untranslatable) + } else if (suppress_untranslatable) { continue; - else { + } else { char *s = srccap, *d = buffer; sprintf(d, "..%s=", name); d += strlen(d); @@ -639,24 +666,29 @@ d++; } } - } else + } else { sprintf(buffer, "%s=%s", name, cv); + } len += strlen(tterm->Strings[i]) + 1; + WRAP_CONCAT; } else { char *src = _nc_tic_expand(tterm->Strings[i], outform == F_TERMINFO, numbers); - sprintf(buffer, "%s=", name); + + strcpy_DYN(&tmpbuf, 0); + strcpy_DYN(&tmpbuf, name); + strcpy_DYN(&tmpbuf, "="); if (pretty && (outform == F_TERMINFO - || outform == F_VARIABLE)) - fmt_complex(buffer + strlen(buffer), src, 1); - else - strcat(buffer, src); + || outform == F_VARIABLE)) { + fmt_complex(src, 1); + } else { + strcpy_DYN(&tmpbuf, src); + } len += strlen(tterm->Strings[i]) + 1; + wrap_concat(tmpbuf.text); + outcount = TRUE; } - - catenate: - WRAP_CONCAT; } } len += num_strings * 2; @@ -708,27 +740,32 @@ * in infocmp -u output when there are no string differences */ if (outcount) { - j = out_used; + bool trimmed = FALSE; + j = outbuf.used; if (j >= 2 - && outbuf[j - 1] == '\t' - && outbuf[j - 2] == '\n') { - out_used -= 2; + && outbuf.text[j - 1] == '\t' + && outbuf.text[j - 2] == '\n') { + outbuf.used -= 2; + trimmed = TRUE; } else if (j >= 4 - && outbuf[j - 1] == ':' - && outbuf[j - 2] == '\t' - && outbuf[j - 3] == '\n' - && outbuf[j - 4] == '\\') { - out_used -= 4; + && outbuf.text[j - 1] == ':' + && outbuf.text[j - 2] == '\t' + && outbuf.text[j - 3] == '\n' + && outbuf.text[j - 4] == '\\') { + outbuf.used -= 4; + trimmed = TRUE; } - outbuf[out_used] = '\0'; - column = oldcol; + if (trimmed) { + outbuf.text[outbuf.used] = '\0'; + column = oldcol; + } } #if 0 fprintf(stderr, "num_bools = %d\n", num_bools); fprintf(stderr, "num_values = %d\n", num_values); fprintf(stderr, "num_strings = %d\n", num_strings); fprintf(stderr, "term_names=%s, len=%d, strlen(outbuf)=%d, outbuf=%s\n", - tterm->term_names, len, out_used, outbuf); + tterm->term_names, len, outbuf.used, outbuf.text); #endif /* * Here's where we use infodump to trigger a more stringent length check @@ -737,7 +774,7 @@ * It gives an idea of which entries are deadly to even *scan past*, * as opposed to *use*. */ - return (infodump ? len : termcap_length(outbuf)); + return (infodump ? len : termcap_length(outbuf.text)); } int @@ -804,7 +841,7 @@ } } - (void) fputs(outbuf, stdout); + (void) fputs(outbuf.text, stdout); return len; } @@ -814,21 +851,23 @@ { char buffer[MAX_TERMINFO_LENGTH]; - append_output(0); + strcpy_DYN(&outbuf, 0); (void) sprintf(buffer, "%s%s", infodump ? "use=" : "tc=", name); wrap_concat(buffer); - (void) fputs(outbuf, stdout); - return out_used; + (void) fputs(outbuf.text, stdout); + return outbuf.used; } void -compare_entry(void (*hook) (int t, int i, const char *name), TERMTYPE * tp GCC_UNUSED, bool quiet) +compare_entry(void (*hook) (int t, int i, const char *name), TERMTYPE * tp + GCC_UNUSED, bool quiet) /* compare two entries */ { int i, j; NCURSES_CONST char *name; - if (!quiet) fputs(" comparing booleans.\n", stdout); + if (!quiet) + fputs(" comparing booleans.\n", stdout); for_each_boolean(j, tp) { i = BoolIndirect(j); name = ExtBoolname(tp, i, bool_names); @@ -839,7 +878,8 @@ (*hook) (CMP_BOOLEAN, i, name); } - if (!quiet) fputs(" comparing numbers.\n", stdout); + if (!quiet) + fputs(" comparing numbers.\n", stdout); for_each_number(j, tp) { i = NumIndirect(j); name = ExtNumname(tp, i, num_names); @@ -850,7 +890,8 @@ (*hook) (CMP_NUMBER, i, name); } - if (!quiet) fputs(" comparing strings.\n", stdout); + if (!quiet) + fputs(" comparing strings.\n", stdout); for_each_string(j, tp) { i = StrIndirect(j); name = ExtStrname(tp, i, str_names);