/* * Store the latest value of an environment variable in my_vars[] so we can * detect if one changes, invalidating the cached search-list. */ static bool update_getenv(const char *name, DBDIRS which) { bool result = FALSE; if (which < dbdLAST) { char *value; if ((value = getenv(name)) == 0 || (value = strdup(value)) == 0) { ; } else if (my_vars[which].name == 0 || strcmp(my_vars[which].name, name)) { FreeIfNeeded(my_vars[which].value); my_vars[which].name = name; my_vars[which].value = value; result = TRUE; } else if ((my_vars[which].value != 0) ^ (value != 0)) { FreeIfNeeded(my_vars[which].value); my_vars[which].value = value; result = TRUE; } else if (value != 0 && strcmp(value, my_vars[which].value)) { FreeIfNeeded(my_vars[which].value); my_vars[which].value = value; result = TRUE; } else { free(value); } } return result; }
int main( int argc, char *argv[]) { FILE *input = stdin; FILE *output = stdout; FILE *output2 = open_it("options_menu.h", "w"); MYDATA *m, *n; if (argc > 1) input = open_it(argv[1], "r"); if (argc > 2) output = open_it(argv[2], "w"); makecfg(input, output, output2); m = all_data; while (m) { n = m->link; FreeIfNeeded(m->name); FreeIfNeeded(m->type); free(m); m = n; } return (0); }
static HANDLE exec_shell(char *cmd, HANDLE *handles, int hide_child) { W32_CHAR *w32_cmdstr = 0; char *cmdstr; int freestr; PROCESS_INFORMATION pi; STARTUPINFO si; proc_handle = BAD_PROC_HANDLE; /* in case of failure */ TRACE((T_CALLED "exec_shell %s\n", cmd)); if ((cmdstr = mk_shell_cmd_str(cmd, &freestr, TRUE)) == NULL) { /* heap exhausted! */ no_memory("exec_shell"); /* Give user a chance to read message--more will surely follow. */ Sleep(3000); } else if ((w32_cmdstr = w32_charstring(cmdstr)) == 0) { no_memory("exec_shell"); } else { memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = handles[0]; si.hStdOutput = handles[1]; si.hStdError = handles[2]; #if DISP_NTWIN if (hide_child) { si.dwFlags |= STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; } #endif TRACE(("CreateProcess %s (pipe)\n", cmdstr)); if (CreateProcess(NULL, w32_cmdstr, NULL, NULL, TRUE, /* Inherit handles */ 0, NULL, NULL, &si, &pi)) { /* Success */ w32_close_handle(pi.hThread); proc_handle = pi.hProcess; TRACE(("...created proc_handle %#x\n", proc_handle)); } } FreeIfNeeded(cmdstr); FreeIfNeeded(w32_cmdstr); returnPtr(proc_handle); }
_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; bool oldsuppress = _nc_suppress_warnings; int immediate = 0; if (silent) _nc_suppress_warnings = TRUE; /* shut the lexer up, too */ _nc_reset_input(fp, buf); for (;;) { memset(&thisentry, 0, sizeof(thisentry)); if (_nc_parse_entry(&thisentry, literal, silent) == ERR) break; 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. That avoids consuming a lot of memory when the * resolution code could fetch entries off disk. */ if (hook != NULLHOOK && (*hook) (&thisentry)) { immediate++; } 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) { /* set up the head pointer */ for (_nc_head = _nc_tail; _nc_head->last; _nc_head = _nc_head->last) continue; DEBUG(1, ("head = %s", _nc_head->tterm.term_names)); DEBUG(1, ("tail = %s", _nc_tail->tterm.term_names)); } #ifdef TRACE else if (!immediate) DEBUG(1, ("no entries parsed")); #endif _nc_suppress_warnings = oldsuppress; }
static void old_elapsed(BI_NODE * a) { beginDisplay(); if (a != 0) { FreeIfNeeded(BI_KEY(a)); FreeIfNeeded(a->value.data); free(a); } endofDisplay(); }
_nc_leaks_tinfo(void) { #if NO_LEAKS char *s; #endif T((T_CALLED("_nc_free_tinfo()"))); #if NO_LEAKS _nc_free_tparm(); _nc_tgetent_leaks(); _nc_free_entries(_nc_head); _nc_get_type(0); _nc_first_name(0); _nc_keyname_leaks(); #if BROKEN_LINKER || USE_REENTRANT _nc_names_leaks(); _nc_codes_leaks(); FreeIfNeeded(_nc_prescreen.real_acs_map); #endif if ((s = _nc_home_terminfo()) != 0) free(s); #endif /* NO_LEAKS */ returnVoid; }
_nc_freewin(WINDOW *win) { WINDOWLIST *p, *q; int i; int result = ERR; T((T_CALLED("_nc_freewin(%p)"), win)); if (win != 0) { if (_nc_try_global(curses) == 0) { q = 0; for (each_window(p)) { if (&(p->win) == win) { remove_window_from_screen(win); if (q == 0) _nc_windows = p->next; else q->next = p->next; if (!(win->_flags & _SUBWIN)) { for (i = 0; i <= win->_maxy; i++) FreeIfNeeded(win->_line[i].text); } free(win->_line); free(p); result = OK; T(("...deleted win=%p", win)); break; } q = p; } _nc_unlock_global(curses); } }
/* The TERMINFO_DIRS value, if defined by the configure script, begins with a * ":", which will be interpreted as TERMINFO. */ static const char * next_list_item(const char *source, int *offset) { if (source != 0) { FreeIfNeeded(ThisDbList); ThisDbList = strdup(source); ThisDbSize = strlen(source); } if (ThisDbList != 0 && ThisDbSize && *offset < ThisDbSize) { static char system_db[] = TERMINFO; char *result = ThisDbList + *offset; char *marker = strchr(result, NCURSES_PATHSEP); /* * Put a null on the marker if a separator was found. Set the offset * to the next position after the marker so we can call this function * again, using the data at the offset. */ if (marker == 0) { *offset += strlen(result) + 1; marker = result + *offset; } else { *marker++ = 0; *offset = marker - ThisDbList; } if (*result == 0 && result != (ThisDbList + ThisDbSize)) result = system_db; return result; } return 0; }
_nc_tgetent_leaks(void) { for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx) { FreeIfNeeded(FIX_SGR0); if (LAST_TRM != 0) del_curterm(LAST_TRM); } }
static void old_tags(BI_NODE * a) { beginDisplay(); FreeIfNeeded(BI_KEY(a)); FreeIfNeeded(TYPECAST(char, a)); endofDisplay(); }
/* * Free any memory related to soft labels, return an error. */ static int slk_failed(void) { if (SP->_slk) { FreeIfNeeded(SP->_slk->ent); free(SP->_slk); SP->_slk = (SLK *) 0; } return ERR; }
/* * Free any memory related to soft labels, return an error. */ static int slk_failed(NCURSES_SP_DCL0) { if ((0 != SP_PARM) && SP_PARM->_slk) { FreeIfNeeded(SP_PARM->_slk->ent); free(SP_PARM->_slk); SP_PARM->_slk = (SLK *) 0; } return ERR; }
_nc_free_and_exit(int code) { char *last_setbuf = (SP != 0) ? SP->_setbuf : 0; _nc_freeall(); #ifdef TRACE trace(0); /* close trace file, freeing its setbuf */ free(_nc_varargs("?", 0)); #endif fclose(stdout); FreeIfNeeded(last_setbuf); exit(code); }
del_curterm(TERMINAL * termp) { T((T_CALLED("del_curterm(%p)"), termp)); if (termp != 0) { _nc_free_termtype(&(termp->type)); FreeIfNeeded(termp->_termname); free(termp); if (termp == cur_term) cur_term = 0; returnCode(OK); } returnCode(ERR); }
_nc_free_termtype(TERMTYPE *ptr) { T(("_nc_free_termtype(%s)", ptr->term_names)); if (ptr->str_table == 0 || (ptr->term_names < ptr->str_table || ptr->term_names >= ptr->str_table + MAX_ENTRY_SIZE)) { FreeIfNeeded(ptr->term_names); } #if NO_LEAKS else { if (ptr->str_table != 0 && (ptr->term_names < ptr->str_table + MAX_ENTRY_SIZE)) { int j; char *last = ptr->str_table; /* * We should have saved the entry-size someplace. Too late, * but this is useful for the memory-leak checking, though more * work/time than should be in the normal library. */ for (j = 0; j < NUM_STRINGS(ptr); j++) { char *s = ptr->Strings[j]; if (VALID_STRING(s)) { char *t = s + strlen(s) + 1; if (t > last) last = t; } } if (last < ptr->term_names) { FreeIfNeeded(ptr->term_names); } } } #endif FreeIfNeeded(ptr->str_table); FreeIfNeeded(ptr->Booleans); FreeIfNeeded(ptr->Numbers); FreeIfNeeded(ptr->Strings); #if NCURSES_XNAMES FreeIfNeeded(ptr->ext_str_table); FreeIfNeeded(ptr->ext_Names); #endif memset(ptr, 0, sizeof(TERMTYPE)); _nc_free_entry(_nc_head, ptr); }
static void SetEnv(char **namep, const char *value) { char *newvalue; beginDisplay(); if (*namep == 0 || strcmp(*namep, value)) { if ((newvalue = strmalloc(value)) != 0) { #if OPT_EVAL && OPT_SHELL FreeIfNeeded(*namep); #endif *namep = newvalue; } } endofDisplay(); }
int var_CRYPTKEY(TBUFF **rp, const char *vp) { if (rp) { tb_scopy(rp, WRITE_ONLY); return TRUE; } else if (vp) { beginDisplay(); FreeIfNeeded(cryptkey); cryptkey = typeallocn(char, NKEYLEN); endofDisplay(); if (cryptkey == 0) return no_memory("var_CRYPTKEY"); vl_make_encrypt_key(cryptkey, vp); return TRUE; } else { return FALSE;
/* * Cgetset() allows the addition of a user specified buffer to be added to the * database array, in effect "pushing" the buffer on top of the virtual * database. 0 is returned on success, -1 on failure. */ static int _nc_cgetset(const char *ent) { if (ent == 0) { FreeIfNeeded(toprec); toprec = 0; topreclen = 0; return (0); } topreclen = strlen(ent); if ((toprec = malloc (topreclen + 1)) == 0) { errno = ENOMEM; return (-1); } gottoprec = 0; (void)strcpy(toprec, ent); return (0); }
del_curterm(TERMINAL * termp) { int rc = ERR; T((T_CALLED("del_curterm(%p)"), termp)); _nc_lock_global(curses); if (termp != 0) { _nc_free_termtype(&(termp->type)); FreeIfNeeded(termp->_termname); free(termp); if (termp == cur_term) set_curterm(0); rc = OK; } _nc_unlock_global(curses); returnCode(rc); }
void set_default_bitmap( struct t_group *group) { if (group != NULL) { group->newsrc.num_unread = 0; group->newsrc.present = FALSE; FreeIfNeeded(group->newsrc.xbitmap); group->newsrc.xbitmap = (t_bitmap *) 0; group->newsrc.xbitlen = 0; if (group->xmin > 0) group->newsrc.xmin = group->xmin; else group->newsrc.xmin = 1; group->newsrc.xmax = group->newsrc.xmin - 1; } }
_nc_leaks_tinfo(void) { #if NO_LEAKS char *s; #endif T((T_CALLED("_nc_free_tinfo()"))); #if NO_LEAKS _nc_globals.leak_checking = TRUE; _nc_free_tparm(); _nc_tgetent_leaks(); if (TerminalOf(CURRENT_SCREEN) != 0) { del_curterm(TerminalOf(CURRENT_SCREEN)); } _nc_forget_prescr(); _nc_comp_captab_leaks(); _nc_free_entries(_nc_head); _nc_get_type(0); _nc_first_name(0); _nc_db_iterator_leaks(); _nc_keyname_leaks(); #if BROKEN_LINKER || USE_REENTRANT _nc_names_leaks(); _nc_codes_leaks(); FreeIfNeeded(_nc_prescreen.real_acs_map); #endif _nc_comp_error_leaks(); if ((s = _nc_home_terminfo()) != 0) free(s); #ifdef TRACE T((T_RETURN(""))); trace(0); _nc_trace_buf(-1, (size_t) 0); #endif #endif /* NO_LEAKS */ returnVoid; }
free_field(FIELD *field) { T((T_CALLED("free_field(%p)"), field)); if (!field) { RETURN(E_BAD_ARGUMENT); } else if (field->form != 0) { RETURN(E_CONNECTED); } else if (field == field->link) { if (field->buf != 0) free(field->buf); } else { FIELD *f; for (f = field; f->link != field; f = f->link) { } f->link = field->link; } _nc_Free_Type(field); #if USE_WIDEC_SUPPORT if (field->expanded != 0) { int n; for (n = 0; n <= field->nbuf; ++n) { FreeIfNeeded(field->expanded[n]); } free(field->expanded); (void)delwin(field->working); } #endif free(field); RETURN(E_OK); }
_nc_free_termtype(TERMTYPE *ptr) { T(("_nc_free_termtype(%s)", ptr->term_names)); FreeIfNeeded(ptr->str_table); FreeIfNeeded(ptr->Booleans); FreeIfNeeded(ptr->Numbers); FreeIfNeeded(ptr->Strings); #if NCURSES_XNAMES FreeIfNeeded(ptr->ext_str_table); FreeIfNeeded(ptr->ext_Names); #endif memset(ptr, 0, sizeof(TERMTYPE)); _nc_free_entry(_nc_head, ptr); }
/* * This hack will search for the next occurrence of <searchpat> in the buffer, * either forward or backward. It is called with the status of the prior * search attempt, so that it knows not to bother if it didn't work last * time. If we can't find any more matches, "point" is left where it was * before. If we do find a match, "point" will be at the end of the matched * string for forward searches and at the beginning of the matched string for * reverse searches. */ static int scanmore( /* search forward or back for a pattern */ TBUFF *patrn, /* string to scan for */ int dir) /* direction to search */ { int sts = FALSE; /* current search status */ FreeIfNeeded(gregexp); gregexp = regcomp(tb_values(patrn), tb_length(patrn), b_val(curbp, MDMAGIC)); if (gregexp != 0) { ignorecase = window_b_val(curwp, MDIGNCASE); sts = scanner(gregexp, (dir < 0) ? REVERSE : FORWARD, FALSE, (int *) 0); if (!sts) { kbd_alarm(); /* beep the terminal if we fail */ } #if OPT_EXTRA_COLOR else { MARK save_MK; int *attrp = lookup_extra_color(XCOLOR_ISEARCH); if (!isEmpty(attrp)) { /* clear any existing search-match */ clear_match_attrs(TRUE, 1); /* draw the new search-match */ regionshape = rgn_EXACT; save_MK = MK; MK.l = DOT.l; MK.o = DOT.o + (C_NUM) tb_length(patrn); videoattribute = (VIDEO_ATTR) * attrp; videoattribute |= VOWN_MATCHES; (void) attributeregion(); /* fix for clear_match_attrs */ curbp->b_highlight |= HILITE_ON; MK = save_MK; } } #endif } return (sts); /* else, don't even try */ }
_nc_freewin(WINDOW *win) { WINDOWLIST *p, *q; int i; int result = ERR; #ifdef USE_SP_WINDOWLIST SCREEN *sp = _nc_screen_of(win); /* pretend this is parameter */ #endif T((T_CALLED("_nc_freewin(%p)"), (void *) win)); if (win != 0) { if (_nc_nonsp_try_global(curses) == 0) { q = 0; for (each_window(SP_PARM, p)) { if (&(p->win) == win) { remove_window_from_screen(win); if (q == 0) WindowList(SP_PARM) = p->next; else q->next = p->next; if (!(win->_flags & _SUBWIN)) { for (i = 0; i <= win->_maxy; i++) FreeIfNeeded(win->_line[i].text); } free(win->_line); free(p); result = OK; T(("...deleted win=%p", (void *) win)); break; } q = p; } _nc_nonsp_unlock_global(curses); } }
void grp_mark_unread( struct t_group *group) { int bitlength; t_bitmap *newbitmap = (t_bitmap *)0; #ifdef DEBUG_NEWSRC debug_print_comment("Z command"); #endif /* DEBUG_NEWSRC */ group_get_art_info(group->spooldir, group->name, group->type, &group->count, &group->xmax, &group->xmin); group->newsrc.num_unread = group->count; if (group->xmax > group->newsrc.xmax) group->newsrc.xmax = group->xmax; if (group->xmin > 0) group->newsrc.xmin = group->xmin; bitlength = (group->newsrc.xmax - group->newsrc.xmin) + 1; if (bitlength < 0) bitlength = 0; if (bitlength > 0) newbitmap = my_malloc(BITS_TO_BYTES(bitlength)); FreeIfNeeded(group->newsrc.xbitmap); group->newsrc.xbitmap = newbitmap; group->newsrc.xbitlen = bitlength; if (bitlength) NSETRNG1(group->newsrc.xbitmap, 0L, bitlength - 1L); #ifdef DEBUG_NEWSRC debug_print_bitmap(group, NULL); #endif /* DEBUG_NEWSRC */ }
NCURSES_SP_NAME(del_curterm) (NCURSES_SP_DCLx TERMINAL * termp) { int rc = ERR; T((T_CALLED("del_curterm(%p, %p)"), (void *) SP_PARM, (void *) termp)); if (termp != 0) { #ifdef USE_TERM_DRIVER TERMINAL_CONTROL_BLOCK *TCB = (TERMINAL_CONTROL_BLOCK *) termp; #endif TERMINAL *cur = ( #if USE_REENTRANT NCURSES_SP_NAME(_nc_get_cur_term) (NCURSES_SP_ARG) #else cur_term #endif ); _nc_free_termtype(&(termp->type)); if (termp == cur) NCURSES_SP_NAME(set_curterm) (NCURSES_SP_ARGx 0); FreeIfNeeded(termp->_termname); #if USE_HOME_TERMINFO if (_nc_globals.home_terminfo != 0) { FreeAndNull(_nc_globals.home_terminfo); } #endif #ifdef USE_TERM_DRIVER if (TCB->drv) TCB->drv->release(TCB); #endif free(termp); rc = OK; } returnCode(rc); }
/* * Initialize soft labels. * Called from newterm() */ int _nc_slk_initialize(WINDOW *stwin, int cols) { int i, x; char *p; T(("slk_initialize()")); if (SP->_slk) { /* we did this already, so simply return */ return(OK); } else if ((SP->_slk = typeCalloc(SLK, 1)) == 0) return(ERR); SP->_slk->ent = NULL; SP->_slk->buffer = NULL; SP->_slk->attr = A_STANDOUT; #ifdef num_labels SP->_slk->maxlab = (num_labels > 0) ? num_labels : MAX_SKEY; SP->_slk->maxlen = (num_labels > 0) ? label_width * label_height : MAX_SKEY_LEN; SP->_slk->labcnt = (SP->_slk->maxlab < MAX_SKEY) ? MAX_SKEY : SP->_slk->maxlab; #else SP->_slk->labcnt = SP->_slk->maxlab = MAX_SKEY; SP->_slk->maxlen = MAX_SKEY_LEN; #endif /* num_labels */ SP->_slk->ent = typeCalloc(slk_ent, SP->_slk->labcnt); if (SP->_slk->ent == NULL) goto exception; p = SP->_slk->buffer = (char*) calloc(2*SP->_slk->labcnt,(1+SP->_slk->maxlen)); if (SP->_slk->buffer == NULL) goto exception; for (i = 0; i < SP->_slk->labcnt; i++) { SP->_slk->ent[i].text = p; p += (1 + SP->_slk->maxlen); SP->_slk->ent[i].form_text = p; p += (1 + SP->_slk->maxlen); memset(SP->_slk->ent[i].form_text, ' ', (unsigned)(SP->_slk->maxlen)); SP->_slk->ent[i].visible = (i < SP->_slk->maxlab); } if (_nc_slk_format >= 3) /* PC style */ { int gap = (cols - 3 * (3 + 4*SP->_slk->maxlen))/2; if (gap < 1) gap = 1; for (i = x = 0; i < SP->_slk->maxlab; i++) { SP->_slk->ent[i].x = x; x += SP->_slk->maxlen; x += (i==3 || i==7) ? gap : 1; } if (_nc_slk_format == 4) slk_paint_info (stwin); } else { if (_nc_slk_format == 2) { /* 4-4 */ int gap = cols - (SP->_slk->maxlab * SP->_slk->maxlen) - 6; if (gap < 1) gap = 1; for (i = x = 0; i < SP->_slk->maxlab; i++) { SP->_slk->ent[i].x = x; x += SP->_slk->maxlen; x += (i == 3) ? gap : 1; } } else { if (_nc_slk_format == 1) { /* 1 -> 3-2-3 */ int gap = (cols - (SP->_slk->maxlab * SP->_slk->maxlen) - 5) / 2; if (gap < 1) gap = 1; for (i = x = 0; i < SP->_slk->maxlab; i++) { SP->_slk->ent[i].x = x; x += SP->_slk->maxlen; x += (i == 2 || i == 4) ? gap : 1; } } else goto exception; } } SP->_slk->dirty = TRUE; if ((SP->_slk->win = stwin) == NULL) { exception: if (SP->_slk) { FreeIfNeeded(SP->_slk->buffer); FreeIfNeeded(SP->_slk->ent); free(SP->_slk); SP->_slk = (SLK*)0; return(ERR); } } return(OK); }
_nc_trim_sgr0(TERMTYPE *tp) { char *result = exit_attribute_mode; T((T_CALLED("_nc_trim_sgr0()"))); if (PRESENT(exit_attribute_mode) && PRESENT(set_attributes)) { bool found = FALSE; char *on = set_attribute_9(tp, 1); char *off = set_attribute_9(tp, 0); char *end = strdup(exit_attribute_mode); char *tmp; size_t i, j, k; TR(TRACE_DATABASE, ("checking if we can trim sgr0 based on sgr")); TR(TRACE_DATABASE, ("sgr0 %s", _nc_visbuf(end))); TR(TRACE_DATABASE, ("sgr(9:off) %s", _nc_visbuf(off))); TR(TRACE_DATABASE, ("sgr(9:on) %s", _nc_visbuf(on))); if (!rewrite_sgr(on, enter_alt_charset_mode) || !rewrite_sgr(off, exit_alt_charset_mode) || !rewrite_sgr(end, exit_alt_charset_mode)) { FreeIfNeeded(off); } else if (similar_sgr(off, end) && !similar_sgr(off, on)) { TR(TRACE_DATABASE, ("adjusting sgr(9:off) : %s", _nc_visbuf(off))); result = off; /* * If rmacs is a substring of sgr(0), remove that chunk. */ if (exit_alt_charset_mode != 0) { TR(TRACE_DATABASE, ("scan for rmacs %s", _nc_visbuf(exit_alt_charset_mode))); j = strlen(off); k = strlen(exit_alt_charset_mode); if (j > k) { for (i = 0; i <= (j - k); ++i) { unsigned k2 = compare_part(exit_alt_charset_mode, off + i); if (k2 != 0) { found = TRUE; chop_out(off, (unsigned) i, (unsigned) (i + k2)); break; } } } } /* * SGR 10 would reset to normal font. */ if (!found) { if ((i = (size_t) is_csi(off)) != 0 && off[strlen(off) - 1] == 'm') { TR(TRACE_DATABASE, ("looking for SGR 10 in %s", _nc_visbuf(off))); tmp = skip_zero(off + i); if (tmp[0] == '1' && skip_zero(tmp + 1) != tmp + 1) { i = (size_t) (tmp - off); if (off[i - 1] == ';') i--; j = (size_t) (skip_zero(tmp + 1) - off); (void) chop_out(off, (unsigned) i, (unsigned) j); found = TRUE; } } } if (!found && (tmp = strstr(end, off)) != 0 && strcmp(end, off) != 0) { i = (size_t) (tmp - end); j = strlen(off); tmp = strdup(end); chop_out(tmp, (unsigned) i, (unsigned) j); free(off); result = tmp; } TR(TRACE_DATABASE, ("...adjusted sgr0 : %s", _nc_visbuf(result))); if (!strcmp(result, exit_attribute_mode)) { TR(TRACE_DATABASE, ("...same result, discard")); free(result); result = exit_attribute_mode; } } else { /* * Either the sgr does not reference alternate character set, * or it is incorrect. That's too hard to decide right now. */ free(off); } FreeIfNeeded(end); FreeIfNeeded(on); } else { /* * Possibly some applications are confused if sgr0 contains rmacs, * but that would be a different bug report -TD */ } returnPtr(result); }
_nc_resolve_uses2(bool fullresolve, bool literal) /* try to resolve all use capabilities */ { ENTRY *qp, *rp, *lastread = 0; bool keepgoing; unsigned i; int unresolved, total_unresolved, multiples; DEBUG(2, ("RESOLUTION BEGINNING")); /* * Check for multiple occurrences of the same name. */ multiples = 0; for_entry_list(qp) { int matchcount = 0; 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++; } 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); DEBUG(2, ("NO MULTIPLE NAME OCCURRENCES")); /* * First resolution stage: compute link pointers corresponding to names. */ total_unresolved = 0; _nc_curr_col = -1; for_entry_list(qp) { unresolved = 0; for (i = 0; i < qp->nuses; i++) { bool foundit; char *child = _nc_first_name(qp->tterm.term_names); char *lookfor = qp->uses[i].name; long lookline = qp->uses[i].line; foundit = FALSE; _nc_set_type(child); /* first, try to resolve from in-core records */ 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)); qp->uses[i].link = rp; foundit = TRUE; } } /* if that didn't work, try to merge in a compiled entry */ if (!foundit) { TERMTYPE thisterm; char filename[PATH_MAX]; memset(&thisterm, 0, sizeof(thisterm)); if (_nc_read_entry(lookfor, filename, &thisterm) == 1) { DEBUG(2, ("%s: resolving use=%s (compiled)", child, lookfor)); rp = typeMalloc(ENTRY, 1); if (rp == 0) _nc_err_abort(MSG_NO_MEMORY); rp->tterm = thisterm; rp->nuses = 0; rp->next = lastread; lastread = rp; qp->uses[i].link = rp; foundit = TRUE; } } /* no good, mark this one unresolvable and complain */ if (!foundit) { unresolved++; total_unresolved++; _nc_curr_line = lookline; _nc_warning("resolution of use=%s failed", lookfor); qp->uses[i].link = 0; } } } if (total_unresolved) { /* free entries read in off disk */ _nc_free_entries(lastread); return (FALSE); } DEBUG(2, ("NAME RESOLUTION COMPLETED OK")); /* * 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) { do { TERMTYPE merged; keepgoing = FALSE; for_entry_list(qp) { if (qp->nuses > 0) { DEBUG(2, ("%s: attempting merge", _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 * subsequent pass. */ 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)); goto incomplete; } /* * 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)); /* * Now merge in each use entry in the proper * (reverse) order. */ for (; qp->nuses; qp->nuses--) _nc_merge_entry(&merged, &qp->uses[qp->nuses - 1].link->tterm); /* * Now merge in the original entry. */ _nc_merge_entry(&merged, &qp->tterm); /* * Replace the original entry with the merged one. */ 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 * didn't bomb. So go back for another pass. */ /* FALLTHRU */ incomplete: keepgoing = TRUE; } } } while (keepgoing); DEBUG(2, ("MERGES COMPLETED OK")); } /* * We'd like to free entries read in off disk at this point, but can't. * The merge_entry() code doesn't copy the strings in the use entries, * it just aliases them. If this ever changes, do a * free_entries(lastread) here. */ DEBUG(2, ("RESOLUTION FINISHED")); if (fullresolve) if (_nc_check_termtype != 0) { _nc_curr_col = -1; for_entry_list(qp) { _nc_curr_line = qp->startline; _nc_set_type(_nc_first_name(qp->tterm.term_names)); _nc_check_termtype2(&qp->tterm, literal); } DEBUG(2, ("SANITY CHECK FINISHED")); }