X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Ftinfo%2Fcomp_parse.c;h=48bd97a8923cd9c1d1d347ac2aa8adba3415dd2b;hp=649731346395cb7a0b6346f141bc195c33c51e25;hb=01433b4eede468929bccc74b22324cb44540e990;hpb=8e25fff6a5f576b6dc35eb02b9783fa58680d07b diff --git a/ncurses/tinfo/comp_parse.c b/ncurses/tinfo/comp_parse.c index 64973134..48bd97a8 100644 --- a/ncurses/tinfo/comp_parse.c +++ b/ncurses/tinfo/comp_parse.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2010,2011 Free Software Foundation, Inc. * + * Copyright (c) 1998-2011,2012 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 * @@ -47,7 +47,7 @@ #include -MODULE_ID("$Id: comp_parse.c,v 1.74 2011/07/25 22:46:47 tom Exp $") +MODULE_ID("$Id: comp_parse.c,v 1.79 2012/01/28 21:49:23 tom Exp $") static void sanity_check2(TERMTYPE *, bool); NCURSES_IMPEXP void NCURSES_API(*_nc_check_termtype2) (TERMTYPE *, bool) = sanity_check2; @@ -56,7 +56,7 @@ NCURSES_IMPEXP void NCURSES_API(*_nc_check_termtype2) (TERMTYPE *, bool) = sanit static void sanity_check(TERMTYPE *); NCURSES_IMPEXP void NCURSES_API(*_nc_check_termtype) (TERMTYPE *) = sanity_check; -static void fixup_acsc(TERMTYPE *, bool); +static void fixup_acsc(TERMTYPE *, int); static void enqueue(ENTRY * ep) @@ -90,9 +90,21 @@ force_bar(char *dst, char *src) } #define ForceBar(dst, src) ((strchr(src, '|') == 0) ? force_bar(dst, src) : src) -NCURSES_EXPORT(bool) -_nc_entry_match(char *n1, char *n2) -/* do any of the aliases in a pair of terminal names match? */ +#if USE_TERMCAP && NCURSES_XNAMES +static char * +skip_index(char *name) +{ + char *bar = strchr(name, '|'); + + if (bar != 0 && (bar - name) == 2) + name = bar + 1; + + return name; +} +#endif + +static bool +check_collisions(char *n1, char *n2, int counter) { char *pstart, *qstart, *pend, *qend; char nc1[MAX_NAME_SIZE + 2]; @@ -101,15 +113,98 @@ _nc_entry_match(char *n1, char *n2) n1 = ForceBar(nc1, n1); n2 = ForceBar(nc2, n2); - for (pstart = n1; (pend = strchr(pstart, '|')); pstart = pend + 1) - for (qstart = n2; (qend = strchr(qstart, '|')); qstart = qend + 1) +#if USE_TERMCAP && NCURSES_XNAMES + if ((_nc_syntax == SYN_TERMCAP) && _nc_user_definable) { + n1 = skip_index(n1); + n2 = skip_index(n2); + } +#endif + + for (pstart = n1; (pend = strchr(pstart, '|')); pstart = pend + 1) { + for (qstart = n2; (qend = strchr(qstart, '|')); qstart = qend + 1) { if ((pend - pstart == qend - qstart) - && memcmp(pstart, qstart, (size_t) (pend - pstart)) == 0) + && memcmp(pstart, qstart, (size_t) (pend - pstart)) == 0) { + if (counter > 0) + (void) fprintf(stderr, "Name collision '%.*s' between\n", + (int) (pend - pstart), pstart); return (TRUE); + } + } + } return (FALSE); } +static char * +next_name(char *name) +{ + if (*name != '\0') + ++name; + return name; +} + +static char * +name_ending(char *name) +{ + if (*name == '\0') { + name = 0; + } else { + while (*name != '\0' && *name != '|') + ++name; + } + return name; +} + +/* + * Essentially, find the conflict reported in check_collisions() and remove + * it from the second name, unless that happens to be the last alias. + */ +static bool +remove_collision(char *n1, char *n2) +{ + char *p1 = n1; + char *p2 = n2; + char *pstart, *qstart, *pend, *qend; + bool removed = FALSE; + +#if USE_TERMCAP && NCURSES_XNAMES + if ((_nc_syntax == SYN_TERMCAP) && _nc_user_definable) { + p1 = n1 = skip_index(n1); + p2 = n2 = skip_index(n2); + } +#else + (void) p1; +#endif + + for (pstart = n1; (pend = name_ending(pstart)); pstart = next_name(pend)) { + for (qstart = n2; (qend = name_ending(qstart)); qstart = next_name(qend)) { + if ((pend - pstart == qend - qstart) + && memcmp(pstart, qstart, (size_t) (pend - pstart)) == 0) { + if (qstart != p2 || *qend == '|') { + if (*qend == '|') + ++qend; + while ((*qstart++ = *qend++) != '\0') ; + fprintf(stderr, "...now\t%s\n", p2); + } else { + fprintf(stderr, "Cannot remove alias '%.*s'\n", + (int) (qend - qstart), qstart); + } + removed = TRUE; + break; + } + } + } + + return removed; +} + +/* do any of the aliases in a pair of terminal names match? */ +NCURSES_EXPORT(bool) +_nc_entry_match(char *n1, char *n2) +{ + return check_collisions(n1, n2, 0); +} + /**************************************************************************** * * Entry compiler and resolution logic @@ -195,19 +290,19 @@ _nc_resolve_uses2(bool fullresolve, bool literal) 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++; + && check_collisions(qp->tterm.term_names, + rp->tterm.term_names, + matchcount + 1)) { + if (!matchcount++) { + (void) fprintf(stderr, "\t%s\n", rp->tterm.term_names); + } + (void) fprintf(stderr, "and\t%s\n", qp->tterm.term_names); + if (!remove_collision(rp->tterm.term_names, + qp->tterm.term_names)) { + ++multiples; } - if (matchcount >= 1) - (void) fprintf(stderr, " %s", _nc_first_name(rp->tterm.term_names)); } } - if (matchcount >= 1) - (void) putc('\n', stderr); } if (multiples > 0) return (FALSE); @@ -375,7 +470,15 @@ _nc_resolve_uses2(bool fullresolve, bool literal) for_entry_list(qp) { _nc_curr_line = (int) qp->startline; _nc_set_type(_nc_first_name(qp->tterm.term_names)); - fixup_acsc(&qp->tterm, literal); + /* + * tic overrides this function pointer to provide more verbose + * checking. + */ + if (_nc_check_termtype2 != sanity_check2) { + _nc_check_termtype2(&qp->tterm, literal); + } else { + fixup_acsc(&qp->tterm, literal); + } } DEBUG(2, ("SANITY CHECK FINISHED")); } @@ -400,7 +503,7 @@ _nc_resolve_uses(bool fullresolve) #define CUR tp-> static void -fixup_acsc(TERMTYPE *tp, bool literal) +fixup_acsc(TERMTYPE *tp, int literal) { if (!literal) { if (acs_chars == 0