X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Ftinfo%2Fcomp_parse.c;h=3334b1f762776f021e17237b0bb09e7ab1584411;hp=ca58bb5746e76ebed0c670789a84f097c50d175c;hb=7eb4be765b131f00ac3da7ce8cfd3bc6759d26c5;hpb=b1f61d9f3aa244512045a6b02e759825d7049d34 diff --git a/ncurses/tinfo/comp_parse.c b/ncurses/tinfo/comp_parse.c index ca58bb57..3334b1f7 100644 --- a/ncurses/tinfo/comp_parse.c +++ b/ncurses/tinfo/comp_parse.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. * + * Copyright (c) 1998-2005,2006 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 * @@ -29,18 +29,19 @@ /**************************************************************************** * Author: Zeyd M. Ben-Halim 1992,1995 * * and: Eric S. Raymond * + * and: Thomas E. Dickey 1996-on * ****************************************************************************/ /* * comp_parse.c -- parser driver loop and use handling. * * _nc_read_entry_source(FILE *, literal, bool, bool (*hook)()) - * _nc_resolve_uses(void) + * _nc_resolve_uses2(void) * _nc_free_entries(void) * * Use this code by calling _nc_read_entry_source() on as many source * files as you like (either terminfo or termcap syntax). If you - * want use-resolution, call _nc_resolve_uses(). To free the list + * want use-resolution, call _nc_resolve_uses2(). To free the list * storage, do _nc_free_entries(). * */ @@ -52,33 +53,14 @@ #include #include -MODULE_ID("$Id: comp_parse.c,v 1.40 2000/04/15 16:57:08 tom Exp $") +MODULE_ID("$Id: comp_parse.c,v 1.64 2006/12/24 00:45:20 tom Exp $") -static void sanity_check(TERMTYPE *); -void (*_nc_check_termtype) (TERMTYPE *) = sanity_check; +static void sanity_check2(TERMTYPE *, bool); +NCURSES_IMPEXP void NCURSES_API(*_nc_check_termtype2) (TERMTYPE *, bool) = sanity_check2; -/**************************************************************************** - * - * Entry queue handling - * - ****************************************************************************/ -/* - * The entry list is a doubly linked list with NULLs terminating the lists: - * - * --------- --------- --------- - * | | | | | | offset - * |-------| |-------| |-------| - * | ----+-->| ----+-->| NULL | next - * |-------| |-------| |-------| - * | NULL |<--+---- |<--+---- | last - * --------- --------- --------- - * ^ ^ - * | | - * | | - * _nc_head _nc_tail - */ - -ENTRY *_nc_head = 0, *_nc_tail = 0; +/* obsolete: 20040705 */ +static void sanity_check(TERMTYPE *); +NCURSES_IMPEXP void NCURSES_API(*_nc_check_termtype) (TERMTYPE *) = sanity_check; static void enqueue(ENTRY * ep) @@ -87,7 +69,7 @@ enqueue(ENTRY * ep) ENTRY *newp = _nc_copy_entry(ep); if (newp == 0) - _nc_err_abort("Out of memory"); + _nc_err_abort(MSG_NO_MEMORY); newp->last = _nc_tail; _nc_tail = newp; @@ -97,51 +79,29 @@ enqueue(ENTRY * ep) newp->last->next = newp; } -void -_nc_free_entries(ENTRY * headp) -/* free the allocated storage consumed by list entries */ +static char * +force_bar(char *dst, char *src) { - ENTRY *ep, *next; - - for (ep = headp; ep; ep = next) { - /* - * This conditional lets us disconnect storage from the list. - * To do this, copy an entry out of the list, then null out - * the string-table member in the original and any use entries - * it references. - */ - FreeIfNeeded(ep->tterm.str_table); - - next = ep->next; - - free(ep); - if (ep == _nc_head) - _nc_head = 0; - if (ep == _nc_tail) - _nc_tail = 0; + if (strchr(src, '|') == 0) { + size_t len = strlen(src); + if (len > MAX_NAME_SIZE) + len = MAX_NAME_SIZE; + (void) strncpy(dst, src, len); + (void) strcpy(dst + len, "|"); + src = dst; } + return src; } -bool +NCURSES_EXPORT(bool) _nc_entry_match(char *n1, char *n2) /* do any of the aliases in a pair of terminal names match? */ { char *pstart, *qstart, *pend, *qend; - char nc1[MAX_NAME_SIZE + 1], nc2[MAX_NAME_SIZE + 1]; - - if (strchr(n1, '|') == 0) { - (void) strncpy(nc1, n1, sizeof(nc1) - 2); - nc1[sizeof(nc1) - 2] = '\0'; - (void) strcat(nc1, "|"); - n1 = nc1; - } + char nc1[MAX_NAME_SIZE + 2], nc2[MAX_NAME_SIZE + 2]; - if (strchr(n2, '|') == 0) { - (void) strncpy(nc2, n2, sizeof(nc2) - 2); - nc2[sizeof(nc2) - 2] = '\0'; - (void) strcat(nc2, "|"); - n2 = nc2; - } + n1 = force_bar(nc1, n1); + n2 = force_bar(nc2, n2); for (pstart = n1; (pend = strchr(pstart, '|')); pstart = pend + 1) for (qstart = n2; (qend = strchr(qstart, '|')); qstart = qend + 1) @@ -158,10 +118,10 @@ _nc_entry_match(char *n1, char *n2) * ****************************************************************************/ -void -_nc_read_entry_source(FILE * fp, char *buf, - int literal, bool silent, - bool(*hook) (ENTRY *)) +NCURSES_EXPORT(void) +_nc_read_entry_source(FILE *fp, char *buf, + int literal, bool silent, + bool(*hook) (ENTRY *)) /* slurp all entries in the given file into core */ { ENTRY thisentry; @@ -176,18 +136,29 @@ _nc_read_entry_source(FILE * fp, char *buf, memset(&thisentry, 0, sizeof(thisentry)); if (_nc_parse_entry(&thisentry, literal, silent) == ERR) break; - if (!isalnum(thisentry.tterm.term_names[0])) + if (!isalnum(UChar(thisentry.tterm.term_names[0]))) _nc_err_abort("terminal names must start with letter or digit"); /* - * This can be used for immediate compilation of entries with no - * use references to disk, so as to avoid chewing up a lot of - * core when the resolution code could fetch entries off disk. + * This can be used for immediate compilation of entries with no "use=" + * references to disk. That avoids consuming a lot of memory when the + * resolution code could fetch entries off disk. */ - if (hook != NULLHOOK && (*hook) (&thisentry)) + if (hook != NULLHOOK && (*hook) (&thisentry)) { immediate++; - else + } else { enqueue(&thisentry); + /* + * The enqueued entry is copied with _nc_copy_termtype(), so we can + * free some of the data from thisentry, i.e., the arrays. + */ + FreeIfNeeded(thisentry.tterm.Booleans); + FreeIfNeeded(thisentry.tterm.Numbers); + FreeIfNeeded(thisentry.tterm.Strings); +#if NCURSES_XNAMES + FreeIfNeeded(thisentry.tterm.ext_Names); +#endif + } } if (_nc_tail) { @@ -206,13 +177,13 @@ _nc_read_entry_source(FILE * fp, char *buf, _nc_suppress_warnings = oldsuppress; } -int -_nc_resolve_uses(bool fullresolve) +NCURSES_EXPORT(int) +_nc_resolve_uses2(bool fullresolve, bool literal) /* try to resolve all use capabilities */ { ENTRY *qp, *rp, *lastread = 0; bool keepgoing; - int i, j, unresolved, total_unresolved, multiples; + int i, unresolved, total_unresolved, multiples; DEBUG(2, ("RESOLUTION BEGINNING")); @@ -223,17 +194,18 @@ _nc_resolve_uses(bool fullresolve) for_entry_list(qp) { int matchcount = 0; - for_entry_list(rp) + for_entry_list(rp) { if (qp > rp - && _nc_entry_match(qp->tterm.term_names, rp->tterm.term_names)) { - matchcount++; - if (matchcount == 1) { - (void) fprintf(stderr, "Name collision between %s", - _nc_first_name(qp->tterm.term_names)); - multiples++; + && _nc_entry_match(qp->tterm.term_names, rp->tterm.term_names)) { + matchcount++; + if (matchcount == 1) { + (void) fprintf(stderr, "Name collision between %s", + _nc_first_name(qp->tterm.term_names)); + multiples++; + } + if (matchcount >= 1) + (void) fprintf(stderr, " %s", _nc_first_name(rp->tterm.term_names)); } - if (matchcount >= 1) - (void) fprintf(stderr, " %s", _nc_first_name(rp->tterm.term_names)); } if (matchcount >= 1) (void) putc('\n', stderr); @@ -261,14 +233,15 @@ _nc_resolve_uses(bool fullresolve) _nc_set_type(child); /* first, try to resolve from in-core records */ - for_entry_list(rp) + for_entry_list(rp) { if (rp != qp - && _nc_name_match(rp->tterm.term_names, lookfor, "|")) { - DEBUG(2, ("%s: resolving use=%s (in core)", - child, lookfor)); + && _nc_name_match(rp->tterm.term_names, lookfor, "|")) { + DEBUG(2, ("%s: resolving use=%s (in core)", + child, lookfor)); - qp->uses[i].link = rp; - foundit = TRUE; + qp->uses[i].link = rp; + foundit = TRUE; + } } /* if that didn't work, try to merge in a compiled entry */ @@ -279,11 +252,11 @@ _nc_resolve_uses(bool fullresolve) memset(&thisterm, 0, sizeof(thisterm)); if (_nc_read_entry(lookfor, filename, &thisterm) == 1) { DEBUG(2, ("%s: resolving use=%s (compiled)", - child, lookfor)); + child, lookfor)); rp = typeMalloc(ENTRY, 1); if (rp == 0) - _nc_err_abort("Out of memory"); + _nc_err_abort(MSG_NO_MEMORY); rp->tterm = thisterm; rp->nuses = 0; rp->next = lastread; @@ -314,8 +287,8 @@ _nc_resolve_uses(bool fullresolve) DEBUG(2, ("NAME RESOLUTION COMPLETED OK")); /* - * OK, at this point all (char *) references in `name' mwmbers - * have been successfully converred to (ENTRY *) pointers in + * OK, at this point all (char *) references in `name' members + * have been successfully converted to (ENTRY *) pointers in * `link' members. Time to do the actual merges. */ if (fullresolve) { @@ -327,7 +300,7 @@ _nc_resolve_uses(bool fullresolve) for_entry_list(qp) { if (qp->nuses > 0) { DEBUG(2, ("%s: attempting merge", - _nc_first_name(qp->tterm.term_names))); + _nc_first_name(qp->tterm.term_names))); /* * If any of the use entries we're looking for is * incomplete, punt. We'll catch this entry on a @@ -336,15 +309,15 @@ _nc_resolve_uses(bool fullresolve) for (i = 0; i < qp->nuses; i++) if (qp->uses[i].link->nuses) { DEBUG(2, ("%s: use entry %d unresolved", - _nc_first_name(qp->tterm.term_names), i)); + _nc_first_name(qp->tterm.term_names), i)); goto incomplete; } /* - * First, make sure there's no garbage in the - * merge block. as a side effect, copy into - * the merged entry the name field and string - * table pointer. + * First, make sure there is no garbage in the + * merge block. As a side effect, copy into + * the merged entry the name field and string + * table pointer. */ _nc_copy_termtype(&merged, &(qp->tterm)); @@ -354,7 +327,7 @@ _nc_resolve_uses(bool fullresolve) */ for (; qp->nuses; qp->nuses--) _nc_merge_entry(&merged, - &qp->uses[qp->nuses - 1].link->tterm); + &qp->uses[qp->nuses - 1].link->tterm); /* * Now merge in the original entry. @@ -367,7 +340,11 @@ _nc_resolve_uses(bool fullresolve) FreeIfNeeded(qp->tterm.Booleans); FreeIfNeeded(qp->tterm.Numbers); FreeIfNeeded(qp->tterm.Strings); +#if NCURSES_XNAMES + FreeIfNeeded(qp->tterm.ext_Names); +#endif qp->tterm = merged; + _nc_wrap_entry(qp, TRUE); /* * We know every entry is resolvable because name resolution @@ -382,23 +359,6 @@ _nc_resolve_uses(bool fullresolve) (keepgoing); DEBUG(2, ("MERGES COMPLETED OK")); - - /* - * The exit condition of the loop above is such that all entries - * must now be resolved. Now handle cancellations. In a resolved - * entry there should be no cancellation markers. - */ - for_entry_list(qp) { - for_each_boolean(j, &(qp->tterm)) - if (qp->tterm.Booleans[j] == CANCELLED_BOOLEAN) - qp->tterm.Booleans[j] = ABSENT_BOOLEAN; - for_each_number(j, &(qp->tterm)) - if (qp->tterm.Numbers[j] == CANCELLED_NUMERIC) - qp->tterm.Numbers[j] = ABSENT_NUMERIC; - for_each_string(j, &(qp->tterm)) - if (qp->tterm.Strings[j] == CANCELLED_STRING) - qp->tterm.Strings[j] = ABSENT_STRING; - } } /* @@ -416,7 +376,7 @@ _nc_resolve_uses(bool fullresolve) for_entry_list(qp) { _nc_curr_line = qp->startline; _nc_set_type(_nc_first_name(qp->tterm.term_names)); - _nc_check_termtype(&qp->tterm); + _nc_check_termtype2(&qp->tterm, literal); } DEBUG(2, ("SANITY CHECK FINISHED")); } @@ -424,6 +384,13 @@ _nc_resolve_uses(bool fullresolve) return (TRUE); } +/* obsolete: 20040705 */ +NCURSES_EXPORT(int) +_nc_resolve_uses(bool fullresolve) +{ + return _nc_resolve_uses2(fullresolve, FALSE); +} + /* * This bit of legerdemain turns all the terminfo variable names into * references to locations in the arrays Booleans, Numbers, and Strings --- @@ -434,31 +401,41 @@ _nc_resolve_uses(bool fullresolve) #define CUR tp-> static void -sanity_check(TERMTYPE * tp) +sanity_check2(TERMTYPE *tp, bool literal) { if (!PRESENT(exit_attribute_mode)) { #ifdef __UNUSED__ /* this casts too wide a net */ bool terminal_entry = !strchr(tp->term_names, '+'); if (terminal_entry && (PRESENT(set_attributes) - || PRESENT(enter_standout_mode) - || PRESENT(enter_underline_mode) - || PRESENT(enter_blink_mode) - || PRESENT(enter_bold_mode) - || PRESENT(enter_dim_mode) - || PRESENT(enter_secure_mode) - || PRESENT(enter_protected_mode) - || PRESENT(enter_reverse_mode))) + || PRESENT(enter_standout_mode) + || PRESENT(enter_underline_mode) + || PRESENT(enter_blink_mode) + || PRESENT(enter_bold_mode) + || PRESENT(enter_dim_mode) + || PRESENT(enter_secure_mode) + || PRESENT(enter_protected_mode) + || PRESENT(enter_reverse_mode))) _nc_warning("no exit_attribute_mode"); #endif /* __UNUSED__ */ - PAIRED(enter_standout_mode, exit_standout_mode) - PAIRED(enter_underline_mode, exit_underline_mode) + PAIRED(enter_standout_mode, exit_standout_mode); + PAIRED(enter_underline_mode, exit_underline_mode); + } + + /* we do this check/fix in postprocess_termcap(), but some packagers + * prefer to bypass it... + */ + if (!literal) { + if (acs_chars == 0 + && enter_alt_charset_mode != 0 + && exit_alt_charset_mode != 0) + acs_chars = strdup(VT_ACSC); + ANDMISSING(enter_alt_charset_mode, acs_chars); + ANDMISSING(exit_alt_charset_mode, acs_chars); } /* listed in structure-member order of first argument */ PAIRED(enter_alt_charset_mode, exit_alt_charset_mode); - ANDMISSING(enter_alt_charset_mode, acs_chars); - ANDMISSING(exit_alt_charset_mode, acs_chars); ANDMISSING(enter_blink_mode, exit_attribute_mode); ANDMISSING(enter_bold_mode, exit_attribute_mode); PAIRED(exit_ca_mode, enter_ca_mode); @@ -476,6 +453,15 @@ sanity_check(TERMTYPE * tp) PAIRED(enter_xon_mode, exit_xon_mode); PAIRED(enter_am_mode, exit_am_mode); ANDMISSING(label_off, label_on); +#ifdef remove_clock PAIRED(display_clock, remove_clock); +#endif ANDMISSING(set_color_pair, initialize_pair); } + +/* obsolete: 20040705 */ +static void +sanity_check(TERMTYPE *tp) +{ + sanity_check2(tp, FALSE); +}