示例#1
0
vwprintw(WINDOW *win, const char *fmt, va_list argp)
{
    char *buf;
    int code = ERR;
#if NCURSES_SP_FUNCS
    SCREEN *sp = _nc_screen_of(win);
#endif

    T((T_CALLED("vwprintw(%p,%s,va_list)"), (void *) win, _nc_visbuf(fmt)));

    buf = NCURSES_SP_NAME(_nc_printf_string) (NCURSES_SP_ARGx fmt, argp);
    if (buf != 0) {
	code = waddstr(win, buf);
    }
    returnCode(code);
}
示例#2
0
int scr_restore(const char *file)
{
	FILE	*fp;

	T((T_CALLED("scr_restore(%s)"), _nc_visbuf(file)));

	if ((fp = fopen(file, "rb")) == 0)
	    returnCode(ERR);
	else
	{
	    delwin(newscr);
	    newscr = getwin(fp);
	    (void) fclose(fp);
	    returnCode(OK);
	}
}
示例#3
0
int scr_dump(const char *file)
{
	FILE	*fp;

	T((T_CALLED("scr_dump(%s)"), _nc_visbuf(file)));

	if ((fp = fopen(file, "wb")) == 0)
	    returnCode(ERR);
	else
	{
	    (void) putwin(newscr, fp);
	    (void) fclose(fp);
	    dumptime = time((time_t *)0);
	    returnCode(OK);
	}
}
示例#4
0
scr_restore(const char *file)
{
    FILE *fp = 0;

    T((T_CALLED("scr_restore(%s)"), _nc_visbuf(file)));

    if (_nc_access(file, R_OK) < 0
	|| (fp = fopen(file, "rb")) == 0) {
	returnCode(ERR);
    } else {
	delwin(newscr);
	SP->_newscr = newscr = getwin(fp);
	(void) fclose(fp);
	returnCode(OK);
    }
}
示例#5
0
set_menu_pattern(MENU * menu, const char *p)
{
  ITEM *matchitem;
  int matchpos;

  T((T_CALLED("set_menu_pattern(%p,%s)"), menu, _nc_visbuf(p)));

  if (!menu || !p)
    RETURN(E_BAD_ARGUMENT);

  if (!(menu->items))
    RETURN(E_NOT_CONNECTED);

  if (menu->status & _IN_DRIVER)
    RETURN(E_BAD_STATE);

  Reset_Pattern(menu);

  if (!(*p))
    {
      pos_menu_cursor(menu);
      RETURN(E_OK);
    }

  if (menu->status & _LINK_NEEDED)
    _nc_Link_Items(menu);

  matchpos = menu->toprow;
  matchitem = menu->curitem;
  assert(matchitem);

  while (*p)
    {
      if (!isprint(UChar(*p)) ||
	  (_nc_Match_Next_Character_In_Item_Name(menu, *p, &matchitem) != E_OK))
	{
	  Reset_Pattern(menu);
	  pos_menu_cursor(menu);
	  RETURN(E_NO_MATCH);
	}
      p++;
    }

  /* This is reached if there was a match. So we position to the new item */
  Adjust_Current_Item(menu, matchpos, matchitem);
  RETURN(E_OK);
}
示例#6
0
scr_dump(const char *file)
{
    int result;
    FILE *fp = 0;

    T((T_CALLED("scr_dump(%s)"), _nc_visbuf(file)));

    if (_nc_access(file, W_OK) < 0
	|| (fp = fopen(file, "wb")) == 0) {
	result = ERR;
    } else {
	(void) putwin(newscr, fp);
	(void) fclose(fp);
	result = OK;
    }
    returnCode(result);
}
示例#7
0
static void recur_tries(struct tries *tree, unsigned level)
{
	if (level > len)
		buffer = (unsigned char *)realloc(buffer, len = (level + 1) * 4);

	while (tree != 0) {
		if ((buffer[level] = tree->ch) == 0)
			buffer[level] = 128;
		buffer[level+1] = 0;
		if (tree->value != 0) {
			_tracef("%5d: %s (%s)", tree->value, _nc_visbuf((char *)buffer), keyname(tree->value));
		}
		if (tree->child)
			recur_tries(tree->child, level+1);
		tree = tree->sibling;
	}
}
示例#8
0
wprintw(WINDOW *win, const char *fmt,...)
{
    va_list argp;
    int code;

#ifdef TRACE
    va_start(argp, fmt);
    T((T_CALLED("wprintw(%p,%s%s)"),
       win, _nc_visbuf(fmt), _nc_varargs(fmt, argp)));
    va_end(argp);
#endif

    va_start(argp, fmt);
    code = vwprintw(win, fmt, argp);
    va_end(argp);

    returnCode(code);
}
示例#9
0
NCURSES_SP_NAME(scr_set) (NCURSES_SP_DCLx const char *file)
{
    int code = ERR;

    T((T_CALLED("scr_set(%p,%s)"), (void *) SP_PARM, _nc_visbuf(file)));

    if (NCURSES_SP_NAME(scr_init) (NCURSES_SP_ARGx file) == OK) {
	delwin(NewScreen(SP_PARM));
	NewScreen(SP_PARM) = dupwin(curscr);
#if !USE_REENTRANT
	newscr = NewScreen(SP_PARM);
#endif
	if (NewScreen(SP_PARM) != 0) {
	    code = OK;
	}
    }
    returnCode(code);
}
示例#10
0
int
define_key(char *str, int keycode)
{
	int code = ERR;

	T((T_CALLED("define_key(%s,%d)"), _nc_visbuf(str), keycode));
	if (keycode > 0) {
		if (has_key(keycode)) {
			if (_nc_remove_key(&(SP->_keytry), keycode))
				code = OK;
		}
		if (str != 0) {
			(void) _nc_add_to_try(&(SP->_keytry), str, keycode);
			code = OK;
		}
	}
	returnCode(code);
}
示例#11
0
mvprintw(int y, int x, const char *fmt,...)
{
    va_list argp;
    int code;

#ifdef TRACE
    va_start(argp, fmt);
    T((T_CALLED("mvprintw(%d,%d,%s%s)"),
       y, x, _nc_visbuf(fmt), _nc_varargs(fmt, argp)));
    va_end(argp);
#endif

    if ((code = move(y, x)) != ERR) {
	va_start(argp, fmt);
	code = vwprintw(stdscr, fmt, argp);
	va_end(argp);
    }
    returnCode(code);
}
示例#12
0
static int
compute_offsets(char **Strings, unsigned strmax, short *offsets)
{
    size_t nextfree = 0;
    unsigned i;

    for (i = 0; i < strmax; i++) {
	if (Strings[i] == ABSENT_STRING) {
	    offsets[i] = -1;
	} else if (Strings[i] == CANCELLED_STRING) {
	    offsets[i] = -2;
	} else {
	    offsets[i] = nextfree;
	    nextfree += strlen(Strings[i]) + 1;
	    TRACE_OUT(("put Strings[%d]=%s(%d)", i, _nc_visbuf(Strings[i]), nextfree));
	}
    }
    return nextfree;
}
示例#13
0
mvwprintw(WINDOW *win, int y, int x, const char *fmt,...)
{
    va_list argp;
    int code;

#ifdef TRACE
    va_start(argp, fmt);
    T((T_CALLED("mvwprintw(%d,%d,%p,%s%s)"),
       y, x, (void *) win, _nc_visbuf(fmt), _nc_varargs(fmt, argp)));
    va_end(argp);
#endif

    if ((code = wmove(win, y, x)) != ERR) {
	va_start(argp, fmt);
	code = vwprintw(win, fmt, argp);
	va_end(argp);
    }
    returnCode(code);
}
示例#14
0
scr_init(const char *file)
{
    FILE *fp = 0;

    T((T_CALLED("scr_init(%s)"), _nc_visbuf(file)));

    if (exit_ca_mode && non_rev_rmcup)
	returnCode(ERR);

    if (_nc_access(file, R_OK) < 0
	|| (fp = fopen(file, "rb")) == 0) {
	returnCode(ERR);
    } else {
	delwin(curscr);
	SP->_curscr = curscr = getwin(fp);
	(void) fclose(fp);
	returnCode(OK);
    }
}
NCURSES_SP_NAME(scr_restore) (NCURSES_SP_DCLx const char *file)
{
    FILE *fp = 0;

    T((T_CALLED("scr_restore(%s)"), _nc_visbuf(file)));

    if (_nc_access(file, R_OK) < 0
	|| (fp = fopen(file, "rb")) == 0) {
	returnCode(ERR);
    } else {
	delwin(newscr);
	SP_PARM->_newscr = getwin(fp);
#if !USE_REENTRANT
	newscr = SP_PARM->_newscr;
#endif
	(void) fclose(fp);
	returnCode(OK);
    }
}
示例#16
0
static int
compute_offsets(char **Strings, size_t strmax, short *offsets)
{
    int nextfree = 0;
    size_t i;

    for (i = 0; i < strmax; i++) {
	if (Strings[i] == ABSENT_STRING) {
	    offsets[i] = -1;
	} else if (Strings[i] == CANCELLED_STRING) {
	    offsets[i] = -2;
	} else {
	    offsets[i] = (short) nextfree;
	    nextfree += (int) strlen(Strings[i]) + 1;
	    TRACE_OUT(("put Strings[%d]=%s(%d)", (int) i,
		       _nc_visbuf(Strings[i]), (int) nextfree));
	}
    }
    return nextfree;
}
示例#17
0
NCURSES_SP_NAME(scr_restore) (NCURSES_SP_DCLx const char *file)
{
    FILE *fp = 0;
    int code = ERR;

    T((T_CALLED("scr_restore(%p,%s)"), (void *) SP_PARM, _nc_visbuf(file)));

    if (_nc_access(file, R_OK) >= 0
	&& (fp = fopen(file, "rb")) != 0) {
	delwin(NewScreen(SP_PARM));
	NewScreen(SP_PARM) = getwin(fp);
#if !USE_REENTRANT
	newscr = NewScreen(SP_PARM);
#endif
	(void) fclose(fp);
	if (NewScreen(SP_PARM) != 0) {
	    code = OK;
	}
    }
    returnCode(code);
}
NCURSES_SP_NAME(scr_init) (NCURSES_SP_DCLx const char *file)
{
    FILE *fp = 0;

    T((T_CALLED("scr_init(%s)"), _nc_visbuf(file)));

    if (exit_ca_mode && non_rev_rmcup)
	returnCode(ERR);

    if (_nc_access(file, R_OK) < 0
	|| (fp = fopen(file, "rb")) == 0) {
	returnCode(ERR);
    } else {
	delwin(curscr);
	SP_PARM->_curscr = getwin(fp);
#if !USE_REENTRANT
	curscr = SP_PARM->_curscr;
#endif
	(void) fclose(fp);
	returnCode(OK);
    }
}
示例#19
0
NCURSES_SP_NAME(define_key) (NCURSES_SP_DCLx const char *str, int keycode)
{
    int code = ERR;

    T((T_CALLED("define_key(%p, %s,%d)"), (void *) SP_PARM, _nc_visbuf(str), keycode));
    if (SP_PARM == 0 || !HasTInfoTerminal(SP_PARM)) {
	code = ERR;
    } else if (keycode > 0) {
	unsigned ukey = (unsigned) keycode;

#ifdef USE_TERM_DRIVER
#define CallHasKey(keycode) CallDriver_1(SP_PARM, td_kyExist, keycode)
#else
#define CallHasKey(keycode) NCURSES_SP_NAME(has_key)(NCURSES_SP_ARGx keycode)
#endif

	if (str != 0) {
	    NCURSES_SP_NAME(define_key) (NCURSES_SP_ARGx str, 0);
	} else if (CallHasKey(keycode)) {
	    while (_nc_remove_key(&(SP_PARM->_keytry), ukey))
		code = OK;
	}
	if (str != 0) {
	    if (NCURSES_SP_NAME(key_defined) (NCURSES_SP_ARGx str) == 0) {
		if (_nc_add_to_try(&(SP_PARM->_keytry), str, ukey) == OK) {
		    code = OK;
		} else {
		    code = ERR;
		}
	    } else {
		code = ERR;
	    }
	}
    } else {
	while (_nc_remove_string(&(SP_PARM->_keytry), str))
	    code = OK;
    }
    returnCode(code);
}
示例#20
0
scr_init(const char *file)
{
    FILE *fp = 0;
    struct stat stb;

    T((T_CALLED("scr_init(%s)"), _nc_visbuf(file)));

    if (exit_ca_mode && non_rev_rmcup)
	returnCode(ERR);

    if (_nc_access(file, R_OK) < 0
	|| (fp = fopen(file, "rb")) == 0)
	returnCode(ERR);
    else if (fstat(STDOUT_FILENO, &stb) || stb.st_mtime > dumptime)
	returnCode(ERR);
    else {
	delwin(curscr);
	curscr = getwin(fp);
	(void) fclose(fp);
	returnCode(OK);
    }
}
示例#21
0
_nc_retrace_ptr(char *code)
{
    T((T_RETURN("%s"), _nc_visbuf(code)));
    return code;
}
示例#22
0
_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);
}
示例#23
0
static void
postprocess_termcap(TERMTYPE * tp, bool has_base)
{
    char buf[MAX_LINE * 2 + 2];
    string_desc result;

    /*
     * TERMCAP DEFAULTS AND OBSOLETE-CAPABILITY TRANSLATIONS
     *
     * This first part of the code is the functional inverse of the
     * fragment in capdefaults.c.
     * ----------------------------------------------------------------------
     */

    /* if there was a tc entry, assume we picked up defaults via that */
    if (!has_base) {
	if (WANTED(init_3string) && termcap_init2)
	    init_3string = _nc_save_str(termcap_init2);

	if (WANTED(reset_2string) && termcap_reset)
	    reset_2string = _nc_save_str(termcap_reset);

	if (WANTED(carriage_return)) {
	    if (carriage_return_delay > 0) {
		sprintf(buf, "%s$<%d>", C_CR, carriage_return_delay);
		carriage_return = _nc_save_str(buf);
	    } else
		carriage_return = _nc_save_str(C_CR);
	}
	if (WANTED(cursor_left)) {
	    if (backspace_delay > 0) {
		sprintf(buf, "%s$<%d>", C_BS, backspace_delay);
		cursor_left = _nc_save_str(buf);
	    } else if (backspaces_with_bs == 1)
		cursor_left = _nc_save_str(C_BS);
	    else if (PRESENT(backspace_if_not_bs))
		cursor_left = backspace_if_not_bs;
	}
	/* vi doesn't use "do", but it does seems to use nl (or '\n') instead */
	if (WANTED(cursor_down)) {
	    if (PRESENT(linefeed_if_not_lf))
		cursor_down = linefeed_if_not_lf;
	    else if (linefeed_is_newline != 1) {
		if (new_line_delay > 0) {
		    sprintf(buf, "%s$<%d>", C_LF, new_line_delay);
		    cursor_down = _nc_save_str(buf);
		} else
		    cursor_down = _nc_save_str(C_LF);
	    }
	}
	if (WANTED(scroll_forward) && crt_no_scrolling != 1) {
	    if (PRESENT(linefeed_if_not_lf))
		cursor_down = linefeed_if_not_lf;
	    else if (linefeed_is_newline != 1) {
		if (new_line_delay > 0) {
		    sprintf(buf, "%s$<%d>", C_LF, new_line_delay);
		    scroll_forward = _nc_save_str(buf);
		} else
		    scroll_forward = _nc_save_str(C_LF);
	    }
	}
	if (WANTED(newline)) {
	    if (linefeed_is_newline == 1) {
		if (new_line_delay > 0) {
		    sprintf(buf, "%s$<%d>", C_LF, new_line_delay);
		    newline = _nc_save_str(buf);
		} else
		    newline = _nc_save_str(C_LF);
	    } else if (PRESENT(carriage_return) && PRESENT(scroll_forward)) {
		_nc_str_init(&result, buf, sizeof(buf));
		if (_nc_safe_strcat(&result, carriage_return)
		 && _nc_safe_strcat(&result, scroll_forward))
		    newline = _nc_save_str(buf);
	    } else if (PRESENT(carriage_return) && PRESENT(cursor_down)) {
		_nc_str_init(&result, buf, sizeof(buf));
		if (_nc_safe_strcat(&result, carriage_return)
		 && _nc_safe_strcat(&result, cursor_down))
		    newline = _nc_save_str(buf);
	    }
	}
    }

    /*
     * Inverse of capdefaults.c code ends here.
     * ----------------------------------------------------------------------
     *
     * TERMCAP-TO TERMINFO MAPPINGS FOR SOURCE TRANSLATION
     *
     * These translations will *not* be inverted by tgetent().
     */

    if (!has_base) {
	/*
	 * We wait until now to decide if we've got a working cr because even
	 * one that doesn't work can be used for newline. Unfortunately the
	 * space allocated for it is wasted.
	 */
	if (return_does_clr_eol == 1 || no_correctly_working_cr == 1)
	    carriage_return = ABSENT_STRING;

	/*
	 * Supposedly most termcap entries have ta now and '\t' is no longer a
	 * default, but it doesn't seem to be true...
	 */
	if (WANTED(tab)) {
	    if (horizontal_tab_delay > 0) {
		sprintf(buf, "%s$<%d>", C_HT, horizontal_tab_delay);
		tab = _nc_save_str(buf);
	    } else
		tab = _nc_save_str(C_HT);
	}
	if (init_tabs == ABSENT_NUMERIC && has_hardware_tabs == TRUE)
	    init_tabs = 8;

	/*
	 * Assume we can beep with ^G unless we're given bl@.
	 */
	if (WANTED(bell))
	    bell = _nc_save_str("\007");
    }

    /*
     * Translate the old termcap :pt: capability to it#8 + ht=\t
     */
    if (has_hardware_tabs == TRUE) {
	if (init_tabs != 8 && init_tabs != ABSENT_NUMERIC)
	    _nc_warning("hardware tabs with a width other than 8: %d", init_tabs);
	else {
	    if (tab && _nc_capcmp(tab, C_HT))
		_nc_warning("hardware tabs with a non-^I tab string %s",
			    _nc_visbuf(tab));
	    else {
		if (WANTED(tab))
		    tab = _nc_save_str(C_HT);
		init_tabs = 8;
	    }
	}
    }
    /*
     * Now translate the ko capability, if there is one.  This
     * isn't from mytinfo...
     */
    if (PRESENT(other_non_function_keys)) {
	char *base = other_non_function_keys;
	char *bp, *cp, *dp;
	struct name_table_entry const *from_ptr;
	struct name_table_entry const *to_ptr;
	assoc const *ap;
	char buf2[MAX_TERMINFO_LENGTH];
	bool foundim;

	/* we're going to use this for a special case later */
	dp = strchr(other_non_function_keys, 'i');
	foundim = (dp != 0) && (dp[1] == 'm');

	/* look at each comma-separated capability in the ko string... */
	for (base = other_non_function_keys;
	     (cp = strchr(base, ',')) != 0;
	     base = cp + 1) {
	    size_t len = cp - base;

	    for (ap = ko_xlate; ap->from; ap++)
		if (len == strlen(ap->from)
		    && strncmp(ap->from, base, len) == 0)
		    break;
	    if (!ap->to) {
		_nc_warning("unknown capability `%.*s' in ko string",
			    (int) len, base);
		continue;
	    } else if (ap->to == CANCELLED_STRING)	/* ignore it */
		continue;

	    /* now we know we found a match in ko_table, so... */

	    from_ptr = _nc_find_entry(ap->from, _nc_cap_hash_table);
	    to_ptr = _nc_find_entry(ap->to, _nc_info_hash_table);

	    if (!from_ptr || !to_ptr)	/* should never happen! */
		_nc_err_abort("ko translation table is invalid, I give up");

	    if (WANTED(tp->Strings[from_ptr->nte_index])) {
		_nc_warning("no value for ko capability %s", ap->from);
		continue;
	    }

	    if (tp->Strings[to_ptr->nte_index]) {
		/* There's no point in warning about it if it's the same
		 * string; that's just an inefficiency.
		 */
		if (strcmp(
			      tp->Strings[from_ptr->nte_index],
			      tp->Strings[to_ptr->nte_index]) != 0)
		    _nc_warning("%s (%s) already has an explicit value %s, ignoring ko",
				ap->to, ap->from,
				_nc_visbuf(tp->Strings[to_ptr->nte_index]));
		continue;
	    }

	    /*
	     * The magic moment -- copy the mapped key string over,
	     * stripping out padding.
	     */
	    for (dp = buf2, bp = tp->Strings[from_ptr->nte_index]; *bp; bp++) {
		if (bp[0] == '$' && bp[1] == '<') {
		    while (*bp && *bp != '>') {
			++bp;
		    }
		} else
		    *dp++ = *bp;
	    }
	    *dp++ = '\0';

	    tp->Strings[to_ptr->nte_index] = _nc_save_str(buf2);
	}

	/*
	 * Note: ko=im and ko=ic both want to grab the `Insert'
	 * keycap.  There's a kich1 but no ksmir, so the ic capability
	 * got mapped to kich1 and im to kIC to avoid a collision.
	 * If the description has im but not ic, hack kIC back to kich1.
	 */
	if (foundim && WANTED(key_ic) && key_sic) {
	    key_ic = key_sic;
	    key_sic = ABSENT_STRING;
	}
    }

    if (!hard_copy) {
	if (WANTED(key_backspace))
	    key_backspace = _nc_save_str(C_BS);
	if (WANTED(key_left))
	    key_left = _nc_save_str(C_BS);
	if (WANTED(key_down))
	    key_down = _nc_save_str(C_LF);
    }

    /*
     * Translate XENIX forms characters.
     */
    if (PRESENT(acs_ulcorner) ||
	PRESENT(acs_llcorner) ||
	PRESENT(acs_urcorner) ||
	PRESENT(acs_lrcorner) ||
	PRESENT(acs_ltee) ||
	PRESENT(acs_rtee) ||
	PRESENT(acs_btee) ||
	PRESENT(acs_ttee) ||
	PRESENT(acs_hline) ||
	PRESENT(acs_vline) ||
	PRESENT(acs_plus)) {
	char buf2[MAX_TERMCAP_LENGTH];

	_nc_str_init(&result, buf2, sizeof(buf2));
	_nc_safe_strcat(&result, acs_chars);

	append_acs (&result, 'j', acs_lrcorner);
	append_acs (&result, 'k', acs_urcorner);
	append_acs (&result, 'l', acs_ulcorner);
	append_acs (&result, 'm', acs_llcorner);
	append_acs (&result, 'n', acs_plus);
	append_acs (&result, 'q', acs_hline);
	append_acs (&result, 't', acs_ltee);
	append_acs (&result, 'u', acs_rtee);
	append_acs (&result, 'v', acs_btee);
	append_acs (&result, 'w', acs_ttee);
	append_acs (&result, 'x', acs_vline);

	if (buf2[0]) {
	    acs_chars = _nc_save_str(buf2);
	    _nc_warning("acsc string synthesized from XENIX capabilities");
	}
    } else if (acs_chars == 0
	       && enter_alt_charset_mode != 0
	       && exit_alt_charset_mode != 0) {
	acs_chars =
	    _nc_save_str("``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~");
    }
}
示例#24
0
static int
write_object(TERMTYPE *tp, char *buffer, unsigned *offset, unsigned limit)
{
    char *namelist;
    size_t namelen, boolmax, nummax, strmax;
    char zero = '\0';
    size_t i;
    short nextfree;
    short offsets[MAX_ENTRY_SIZE / 2];
    unsigned char buf[MAX_ENTRY_SIZE];
    unsigned last_bool = BOOLWRITE;
    unsigned last_num = NUMWRITE;
    unsigned last_str = STRWRITE;

#if NCURSES_XNAMES
    /*
     * Normally we limit the list of values to exclude the "obsolete"
     * capabilities.  However, if we are accepting extended names, add
     * these as well, since they are used for supporting translation
     * to/from termcap.
     */
    if (_nc_user_definable) {
	last_bool = BOOLCOUNT;
	last_num = NUMCOUNT;
	last_str = STRCOUNT;
    }
#endif

    namelist = tp->term_names;
    namelen = strlen(namelist) + 1;

    boolmax = 0;
    for (i = 0; i < last_bool; i++) {
	if (tp->Booleans[i] == TRUE)
	    boolmax = i + 1;
    }

    nummax = 0;
    for (i = 0; i < last_num; i++) {
	if (tp->Numbers[i] != ABSENT_NUMERIC)
	    nummax = i + 1;
    }

    strmax = 0;
    for (i = 0; i < last_str; i++) {
	if (tp->Strings[i] != ABSENT_STRING)
	    strmax = i + 1;
    }

    nextfree = compute_offsets(tp->Strings, strmax, offsets);

    /* fill in the header */
    LITTLE_ENDIAN(buf, MAGIC);
    LITTLE_ENDIAN(buf + 2, min(namelen, MAX_NAME_SIZE + 1));
    LITTLE_ENDIAN(buf + 4, boolmax);
    LITTLE_ENDIAN(buf + 6, nummax);
    LITTLE_ENDIAN(buf + 8, strmax);
    LITTLE_ENDIAN(buf + 10, nextfree);

    /* write out the header */
    TRACE_OUT(("Header of %s @%d", namelist, *offset));
    if (Write(buf, 12, 1) != 1
	|| Write(namelist, sizeof(char), namelen) != namelen)
	  return (ERR);

    for (i = 0; i < boolmax; i++)
	if (tp->Booleans[i] == TRUE)
	    buf[i] = TRUE;
	else
	    buf[i] = FALSE;
    if (Write(buf, sizeof(char), boolmax) != boolmax)
	  return (ERR);

    if (even_boundary(namelen + boolmax))
	return (ERR);

    TRACE_OUT(("Numerics begin at %04x", *offset));

    /* the numerics */
    convert_shorts(buf, tp->Numbers, nummax);
    if (Write(buf, 2, nummax) != nummax)
	return (ERR);

    TRACE_OUT(("String offsets begin at %04x", *offset));

    /* the string offsets */
    convert_shorts(buf, offsets, strmax);
    if (Write(buf, 2, strmax) != strmax)
	return (ERR);

    TRACE_OUT(("String table begins at %04x", *offset));

    /* the strings */
    for (i = 0; i < strmax; i++)
	if (VALID_STRING(tp->Strings[i]))
	    if (!WRITE_STRING(tp->Strings[i]))
		return (ERR);

#if NCURSES_XNAMES
    if (extended_object(tp)) {
	unsigned extcnt = NUM_EXT_NAMES(tp);

	if (even_boundary(nextfree))
	    return (ERR);

	nextfree = compute_offsets(tp->Strings + STRCOUNT,
				   tp->ext_Strings,
				   offsets);
	TRACE_OUT(("after extended string capabilities, nextfree=%d", nextfree));

	if (tp->ext_Strings >= SIZEOF(offsets))
	    return (ERR);

	nextfree += compute_offsets(tp->ext_Names,
				    extcnt,
				    offsets + tp->ext_Strings);
	TRACE_OUT(("after extended capnames, nextfree=%d", nextfree));
	strmax = tp->ext_Strings + extcnt;

	/*
	 * Write the extended header
	 */
	LITTLE_ENDIAN(buf + 0, tp->ext_Booleans);
	LITTLE_ENDIAN(buf + 2, tp->ext_Numbers);
	LITTLE_ENDIAN(buf + 4, tp->ext_Strings);
	LITTLE_ENDIAN(buf + 6, strmax);
	LITTLE_ENDIAN(buf + 8, nextfree);
	TRACE_OUT(("WRITE extended-header @%d", *offset));
	if (Write(buf, 10, 1) != 1)
	    return (ERR);

	TRACE_OUT(("WRITE %d booleans @%d", tp->ext_Booleans, *offset));
	if (tp->ext_Booleans
	    && Write(tp->Booleans + BOOLCOUNT, sizeof(char),
		     tp->ext_Booleans) != tp->ext_Booleans)
	      return (ERR);

	if (even_boundary(tp->ext_Booleans))
	    return (ERR);

	TRACE_OUT(("WRITE %d numbers @%d", tp->ext_Numbers, *offset));
	if (tp->ext_Numbers) {
	    convert_shorts(buf, tp->Numbers + NUMCOUNT, tp->ext_Numbers);
	    if (Write(buf, 2, tp->ext_Numbers) != tp->ext_Numbers)
		return (ERR);
	}

	/*
	 * Convert the offsets for the ext_Strings and ext_Names tables,
	 * in that order.
	 */
	convert_shorts(buf, offsets, strmax);
	TRACE_OUT(("WRITE offsets @%d", *offset));
	if (Write(buf, 2, strmax) != strmax)
	    return (ERR);

	/*
	 * Write the string table after the offset tables so we do not
	 * have to do anything about alignment.
	 */
	for (i = 0; i < tp->ext_Strings; i++) {
	    if (VALID_STRING(tp->Strings[i + STRCOUNT])) {
		TRACE_OUT(("WRITE ext_Strings[%d]=%s", (int) i,
			   _nc_visbuf(tp->Strings[i + STRCOUNT])));
		if (!WRITE_STRING(tp->Strings[i + STRCOUNT]))
		    return (ERR);
	    }
	}

	/*
	 * Write the extended names
	 */
	for (i = 0; i < extcnt; i++) {
	    TRACE_OUT(("WRITE ext_Names[%d]=%s", (int) i, tp->ext_Names[i]));
	    if (!WRITE_STRING(tp->ext_Names[i]))
		return (ERR);
	}

    }
#endif /* NCURSES_XNAMES */

    total_written++;
    return (OK);
}
示例#25
0
_nc_add_to_try(TRIES ** tree, const char *str, unsigned code)
{
    TRIES *ptr, *savedptr;
    unsigned const char *txt = (unsigned const char *) str;

    T((T_CALLED("_nc_add_to_try(%p, %s, %u)"), *tree, _nc_visbuf(str), code));
    if (txt == 0 || *txt == '\0' || code == 0)
	returnCode(ERR);

    if ((*tree) != 0) {
	ptr = savedptr = (*tree);

	for (;;) {
	    unsigned char cmp = *txt;

	    while (!CMP_TRY(ptr->ch, cmp)
		   && ptr->sibling != 0)
		ptr = ptr->sibling;

	    if (CMP_TRY(ptr->ch, cmp)) {
		if (*(++txt) == '\0') {
		    ptr->value = code;
		    returnCode(OK);
		}
		if (ptr->child != 0)
		    ptr = ptr->child;
		else
		    break;
	    } else {
		if ((ptr->sibling = typeCalloc(TRIES, 1)) == 0) {
		    returnCode(ERR);
		}

		savedptr = ptr = ptr->sibling;
		SET_TRY(ptr, txt);
		ptr->value = 0;

		break;
	    }
	}			/* end for (;;) */
    } else {			/* (*tree) == 0 :: First sequence to be added */
	savedptr = ptr = (*tree) = typeCalloc(TRIES, 1);

	if (ptr == 0) {
	    returnCode(ERR);
	}

	SET_TRY(ptr, txt);
	ptr->value = 0;
    }

    /* at this point, we are adding to the try.  ptr->child == 0 */

    while (*txt) {
	ptr->child = typeCalloc(TRIES, 1);

	ptr = ptr->child;

	if (ptr == 0) {
	    while ((ptr = savedptr) != 0) {
		savedptr = ptr->child;
		free(ptr);
	    }
	    returnCode(ERR);
	}

	SET_TRY(ptr, txt);
	ptr->value = 0;
    }

    ptr->value = code;
    returnCode(OK);
}
示例#26
0
tputs(const char *string, int affcnt, int (*outc) (int))
{
    bool always_delay;
    bool normal_delay;
    int number;
#if BSD_TPUTS
    int trailpad;
#endif /* BSD_TPUTS */

#ifdef TRACE
    char addrbuf[32];

    if (_nc_tracing & TRACE_TPUTS) {
	if (outc == _nc_outch)
	    (void) strcpy(addrbuf, "_nc_outch");
	else
	    (void) sprintf(addrbuf, "%p", outc);
	if (_nc_tputs_trace) {
	    _tracef("tputs(%s = %s, %d, %s) called", _nc_tputs_trace,
		    _nc_visbuf(string), affcnt, addrbuf);
	} else {
	    _tracef("tputs(%s, %d, %s) called", _nc_visbuf(string), affcnt, addrbuf);
	}
	_nc_tputs_trace = (char *) NULL;
    }
#endif /* TRACE */

    if (!VALID_STRING(string))
	return ERR;

    if (cur_term == 0) {
	always_delay = FALSE;
	normal_delay = TRUE;
    } else {
	always_delay = (string == bell) || (string == flash_screen);
	normal_delay =
	    !xon_xoff
	    && padding_baud_rate
#if NCURSES_NO_PADDING
	    && (SP == 0 || !(SP->_no_padding))
#endif
	    && (_nc_baudrate(ospeed) >= padding_baud_rate);
    }

#if BSD_TPUTS
    /*
     * This ugly kluge deals with the fact that some ancient BSD programs
     * (like nethack) actually do the likes of tputs("50") to get delays.
     */
    trailpad = 0;
    if (isdigit(UChar(*string))) {
	while (isdigit(UChar(*string))) {
	    trailpad = trailpad * 10 + (*string - '0');
	    string++;
	}
	trailpad *= 10;
	if (*string == '.') {
	    string++;
	    if (isdigit(UChar(*string))) {
		trailpad += (*string - '0');
		string++;
	    }
	    while (isdigit(UChar(*string)))
		string++;
	}

	if (*string == '*') {
	    trailpad *= affcnt;
	    string++;
	}
    }
#endif /* BSD_TPUTS */

    my_outch = outc;		/* redirect delay_output() */
    while (*string) {
	if (*string != '$')
	    (*outc) (*string);
	else {
	    string++;
	    if (*string != '<') {
		(*outc) ('$');
		if (*string)
		    (*outc) (*string);
	    } else {
		bool mandatory;

		string++;
		if ((!isdigit(UChar(*string)) && *string != '.')
		    || !strchr(string, '>')) {
		    (*outc) ('$');
		    (*outc) ('<');
		    continue;
		}

		number = 0;
		while (isdigit(UChar(*string))) {
		    number = number * 10 + (*string - '0');
		    string++;
		}
		number *= 10;
		if (*string == '.') {
		    string++;
		    if (isdigit(UChar(*string))) {
			number += (*string - '0');
			string++;
		    }
		    while (isdigit(UChar(*string)))
			string++;
		}

		mandatory = FALSE;
		while (*string == '*' || *string == '/') {
		    if (*string == '*') {
			number *= affcnt;
			string++;
		    } else {	/* if (*string == '/') */
			mandatory = TRUE;
			string++;
		    }
		}

		if (number > 0
		    && (always_delay
			|| normal_delay
			|| mandatory))
		    delay_output(number / 10);

	    }			/* endelse (*string == '<') */
	}			/* endelse (*string == '$') */

	if (*string == '\0')
	    break;

	string++;
    }

#if BSD_TPUTS
    /*
     * Emit any BSD-style prefix padding that we've accumulated now.
     */
    if (trailpad > 0
	&& (always_delay || normal_delay))
	delay_output(trailpad / 10);
#endif /* BSD_TPUTS */

    my_outch = _nc_outch;
    return OK;
}
示例#27
0
文件: lib_acs.c 项目: CSU-GH/okl4_3.0
_nc_init_acs(void)
{
    chtype *fake_map = acs_map;
    chtype *real_map = SP != 0 ? SP->_acs_map : fake_map;
    int j;

    T(("initializing ACS map"));

    /*
     * If we're using this from curses (rather than terminfo), we are storing
     * the mapping information in the SCREEN struct so we can decide how to
     * render it.
     */
    if (real_map != fake_map) {
	for (j = 1; j < ACS_LEN; ++j) {
	    real_map[j] = 0;
	    fake_map[j] = A_ALTCHARSET | j;
	    SP->_screen_acs_map[j] = FALSE;
	}
    } else {
	for (j = 1; j < ACS_LEN; ++j) {
	    real_map[j] = 0;
	}
    }

    /*
     * Initializations for a UNIX-like multi-terminal environment.  Use
     * ASCII chars and count on the terminfo description to do better.
     */
    real_map['l'] = '+';	/* should be upper left corner */
    real_map['m'] = '+';	/* should be lower left corner */
    real_map['k'] = '+';	/* should be upper right corner */
    real_map['j'] = '+';	/* should be lower right corner */
    real_map['u'] = '+';	/* should be tee pointing left */
    real_map['t'] = '+';	/* should be tee pointing right */
    real_map['v'] = '+';	/* should be tee pointing up */
    real_map['w'] = '+';	/* should be tee pointing down */
    real_map['q'] = '-';	/* should be horizontal line */
    real_map['x'] = '|';	/* should be vertical line */
    real_map['n'] = '+';	/* should be large plus or crossover */
    real_map['o'] = '~';	/* should be scan line 1 */
    real_map['s'] = '_';	/* should be scan line 9 */
    real_map['`'] = '+';	/* should be diamond */
    real_map['a'] = ':';	/* should be checker board (stipple) */
    real_map['f'] = '\'';	/* should be degree symbol */
    real_map['g'] = '#';	/* should be plus/minus */
    real_map['~'] = 'o';	/* should be bullet */
    real_map[','] = '<';	/* should be arrow pointing left */
    real_map['+'] = '>';	/* should be arrow pointing right */
    real_map['.'] = 'v';	/* should be arrow pointing down */
    real_map['-'] = '^';	/* should be arrow pointing up */
    real_map['h'] = '#';	/* should be board of squares */
    real_map['i'] = '#';	/* should be lantern symbol */
    real_map['0'] = '#';	/* should be solid square block */
    /* these defaults were invented for ncurses */
    real_map['p'] = '-';	/* should be scan line 3 */
    real_map['r'] = '-';	/* should be scan line 7 */
    real_map['y'] = '<';	/* should be less-than-or-equal-to */
    real_map['z'] = '>';	/* should be greater-than-or-equal-to */
    real_map['{'] = '*';	/* should be greek pi */
    real_map['|'] = '!';	/* should be not-equal */
    real_map['}'] = 'f';	/* should be pound-sterling symbol */

#if !USE_WIDEC_SUPPORT
    if (_nc_unicode_locale() && _nc_locale_breaks_acs()) {
	acs_chars = NULL;
	ena_acs = NULL;
	enter_alt_charset_mode = NULL;
	exit_alt_charset_mode = NULL;
	set_attributes = NULL;
    }
#endif

    if (ena_acs != NULL) {
	TPUTS_TRACE("ena_acs");
	putp(ena_acs);
    }
#if NCURSES_EXT_FUNCS
    /*
     * Linux console "supports" the "PC ROM" character set by the coincidence
     * that smpch/rmpch and smacs/rmacs have the same values.  ncurses has
     * no codepage support (see SCO Merge for an example).  Outside of the
     * values defined in acsc, there are no definitions for the "PC ROM"
     * character set (assumed by some applications to be codepage 437), but we
     * allow those applications to use those codepoints.
     *
     * test/blue.c uses this feature.
     */
#define PCH_KLUDGE(a,b) (a != 0 && b != 0 && !strcmp(a,b))
    if (PCH_KLUDGE(enter_pc_charset_mode, enter_alt_charset_mode) &&
	PCH_KLUDGE(exit_pc_charset_mode, exit_alt_charset_mode)) {
	size_t i;
	for (i = 1; i < ACS_LEN; ++i) {
	    if (real_map[i] == 0) {
		real_map[i] = i;
		if (real_map != fake_map) {
		    if (SP != 0)
			SP->_screen_acs_map[i] = TRUE;
		}
	    }
	}
    }
#endif

    if (acs_chars != NULL) {
	size_t i = 0;
	size_t length = strlen(acs_chars);

	while (i + 1 < length) {
	    if (acs_chars[i] != 0 && UChar(acs_chars[i]) < ACS_LEN) {
		real_map[UChar(acs_chars[i])] = UChar(acs_chars[i + 1]) | A_ALTCHARSET;
		if (SP != 0)
		    SP->_screen_acs_map[UChar(acs_chars[i])] = TRUE;
	    }
	    i += 2;
	}
    }
#ifdef TRACE
    /* Show the equivalent mapping, noting if it does not match the
     * given attribute, whether by re-ordering or duplication.
     */
    if (_nc_tracing & TRACE_CALLS) {
	size_t n, m;
	char show[ACS_LEN * 2 + 1];
	for (n = 1, m = 0; n < ACS_LEN; n++) {
	    if (real_map[n] != 0) {
		show[m++] = (char) n;
		show[m++] = ChCharOf(real_map[n]);
	    }
	}
	show[m] = 0;
	if (acs_chars == NULL || strcmp(acs_chars, show))
	    _tracef("%s acs_chars %s",
		    (acs_chars == NULL) ? "NULL" : "READ",
		    _nc_visbuf(acs_chars));
	_tracef("%s acs_chars %s",
		(acs_chars == NULL)
		? "NULL"
		: (strcmp(acs_chars, show)
		   ? "DIFF"
		   : "SAME"),
		_nc_visbuf(show));
    }
#endif /* TRACE */
}
示例#28
0
wgetnstr_events(WINDOW *win,
		char *str,
		int maxlen,
		EVENTLIST_1st(_nc_eventlist * evl))
{
    SCREEN *sp = _nc_screen_of(win);
    TTY buf;
    bool oldnl, oldecho, oldraw, oldcbreak;
    char erasec;
    char killc;
    char *oldstr;
    int ch;
    int y, x;

    T((T_CALLED("wgetnstr(%p,%p, %d)"), win, str, maxlen));

    if (!win)
	returnCode(ERR);

    _nc_get_tty_mode(&buf);

    oldnl = sp->_nl;
    oldecho = sp->_echo;
    oldraw = sp->_raw;
    oldcbreak = sp->_cbreak;
    nl();
    noecho();
    noraw();
    cbreak();

    erasec = erasechar();
    killc = killchar();

    oldstr = str;
    getyx(win, y, x);

    if (is_wintouched(win) || (win->_flags & _HASMOVED))
	wrefresh(win);

    while ((ch = wgetch_events(win, evl)) != ERR) {
	/*
	 * Some terminals (the Wyse-50 is the most common) generate
	 * a \n from the down-arrow key.  With this logic, it's the
	 * user's choice whether to set kcud=\n for wgetch();
	 * terminating *getstr() with \n should work either way.
	 */
	if (ch == '\n'
	    || ch == '\r'
	    || ch == KEY_DOWN
	    || ch == KEY_ENTER) {
	    if (oldecho == TRUE
		&& win->_cury == win->_maxy
		&& win->_scroll)
		wechochar(win, (chtype) '\n');
	    break;
	}
#ifdef KEY_EVENT
	if (ch == KEY_EVENT)
	    break;
#endif
#ifdef KEY_RESIZE
	if (ch == KEY_RESIZE)
	    break;
#endif
	if (ch == erasec || ch == KEY_LEFT || ch == KEY_BACKSPACE) {
	    if (str > oldstr) {
		str = WipeOut(win, y, x, oldstr, str, oldecho);
	    }
	} else if (ch == killc) {
	    while (str > oldstr) {
		str = WipeOut(win, y, x, oldstr, str, oldecho);
	    }
	} else if (ch >= KEY_MIN
		   || (maxlen >= 0 && str - oldstr >= maxlen)) {
	    beep();
	} else {
	    *str++ = (char) ch;
	    if (oldecho == TRUE) {
		int oldy = win->_cury;
		if (waddch(win, (chtype) ch) == ERR) {
		    /*
		     * We can't really use the lower-right
		     * corner for input, since it'll mess
		     * up bookkeeping for erases.
		     */
		    win->_flags &= ~_WRAPPED;
		    waddch(win, (chtype) ' ');
		    str = WipeOut(win, y, x, oldstr, str, oldecho);
		    continue;
		} else if (win->_flags & _WRAPPED) {
		    /*
		     * If the last waddch forced a wrap &
		     * scroll, adjust our reference point
		     * for erasures.
		     */
		    if (win->_scroll
			&& oldy == win->_maxy
			&& win->_cury == win->_maxy) {
			if (--y <= 0) {
			    y = 0;
			}
		    }
		    win->_flags &= ~_WRAPPED;
		}
		wrefresh(win);
	    }
	}
    }

    win->_curx = 0;
    win->_flags &= ~_WRAPPED;
    if (win->_cury < win->_maxy)
	win->_cury++;
    wrefresh(win);

    /* Restore with a single I/O call, to fix minor asymmetry between
     * raw/noraw, etc.
     */
    sp->_nl = oldnl;
    sp->_echo = oldecho;
    sp->_raw = oldraw;
    sp->_cbreak = oldcbreak;

    _nc_set_tty_mode(&buf);

    *str = '\0';
    if (ch == ERR)
	returnCode(ch);

    T(("wgetnstr returns %s", _nc_visbuf(oldstr)));

#ifdef KEY_EVENT
    if (ch == KEY_EVENT)
	returnCode(ch);
#endif
#ifdef KEY_RESIZE
    if (ch == KEY_RESIZE)
	returnCode(ch);
#endif

    returnCode(OK);
}
示例#29
0
_nc_get_token(bool silent)
{
    static const char terminfo_punct[] = "@%&*!#";
    long number;
    int type;
    int ch;
    char *numchk;
    char numbuf[80];
    unsigned found;
    static char buffer[MAX_ENTRY_SIZE];
    char *ptr;
    int dot_flag = FALSE;
    long token_start;

    if (pushtype != NO_PUSHBACK) {
	int retval = pushtype;

	_nc_set_type(pushname);
	DEBUG(3, ("pushed-back token: `%s', class %d",
		  _nc_curr_token.tk_name, pushtype));

	pushtype = NO_PUSHBACK;
	pushname[0] = '\0';

	/* currtok wasn't altered by _nc_push_token() */
	return (retval);
    }

    if (end_of_stream())
	return (EOF);

  start_token:
    token_start = stream_pos();
    while ((ch = next_char()) == '\n' || iswhite(ch))
	continue;

    ch = eat_escaped_newline(ch);

    if (ch == EOF)
	type = EOF;
    else {
	/* if this is a termcap entry, skip a leading separator */
	if (separator == ':' && ch == ':')
	    ch = next_char();

	if (ch == '.'
#if NCURSES_EXT_FUNCS
	    && !_nc_disable_period
#endif
	    ) {
	    dot_flag = TRUE;
	    DEBUG(8, ("dot-flag set"));

	    while ((ch = next_char()) == '.' || iswhite(ch))
		continue;
	}

	if (ch == EOF) {
	    type = EOF;
	    goto end_of_token;
	}

	/* have to make some punctuation chars legal for terminfo */
	if (!isalnum(ch)
#if NCURSES_EXT_FUNCS
	    && !(ch == '.' && _nc_disable_period)
#endif
	    && !strchr(terminfo_punct, (char) ch)) {
	    if (!silent)
		_nc_warning("Illegal character (expected alphanumeric or %s) - %s",
			    terminfo_punct, unctrl((chtype) ch));
	    _nc_panic_mode(separator);
	    goto start_token;
	}

	ptr = buffer;
	*(ptr++) = ch;

	if (first_column) {
	    char *desc;

	    _nc_comment_start = token_start;
	    _nc_comment_end = _nc_curr_file_pos;
	    _nc_start_line = _nc_curr_line;

	    _nc_syntax = ERR;
	    while ((ch = next_char()) != '\n') {
		if (ch == EOF)
		    _nc_err_abort("premature EOF");
		else if (ch == ':' && last_char() != ',') {
		    _nc_syntax = SYN_TERMCAP;
		    separator = ':';
		    break;
		} else if (ch == ',') {
		    _nc_syntax = SYN_TERMINFO;
		    separator = ',';
		    /*
		     * Fall-through here is not an accident.  The idea is that
		     * if we see a comma, we figure this is terminfo unless we
		     * subsequently run into a colon -- but we don't stop
		     * looking for that colon until hitting a newline.  This
		     * allows commas to be embedded in description fields of
		     * either syntax.
		     */
		    /* FALLTHRU */
		} else
		    ch = eat_escaped_newline(ch);

		*ptr++ = ch;
	    }
	    ptr[0] = '\0';
	    if (_nc_syntax == ERR) {
		/*
		 * Grrr...what we ought to do here is barf, complaining that
		 * the entry is malformed.  But because a couple of name fields
		 * in the 8.2 termcap file end with |\, we just have to assume
		 * it's termcap syntax.
		 */
		_nc_syntax = SYN_TERMCAP;
		separator = ':';
	    } else if (_nc_syntax == SYN_TERMINFO) {
		/* throw away trailing /, *$/ */
		for (--ptr; iswhite(*ptr) || *ptr == ','; ptr--)
		    continue;
		ptr[1] = '\0';
	    }

	    /*
	     * This is the soonest we have the terminal name fetched.  Set up
	     * for following warning messages.
	     */
	    ptr = strchr(buffer, '|');
	    if (ptr == (char *) NULL)
		ptr = buffer + strlen(buffer);
	    ch = *ptr;
	    *ptr = '\0';
	    _nc_set_type(buffer);
	    *ptr = ch;

	    /*
	     * Compute the boundary between the aliases and the description
	     * field for syntax-checking purposes.
	     */
	    desc = strrchr(buffer, '|');
	    if (!silent && desc) {
		if (*desc == '\0')
		    _nc_warning("empty longname field");
		else if (strchr(desc, ' ') == (char *) NULL)
		    _nc_warning("older tic versions may treat the description field as an alias");
	    }
	    if (!desc)
		desc = buffer + strlen(buffer);

	    /*
	     * Whitespace in a name field other than the long name can confuse
	     * rdist and some termcap tools.  Slashes are a no-no.  Other
	     * special characters can be dangerous due to shell expansion.
	     */
	    for (ptr = buffer; ptr < desc; ptr++) {
		if (isspace(CharOf(*ptr))) {
		    if (!silent)
			_nc_warning("whitespace in name or alias field");
		    break;
		} else if (*ptr == '/') {
		    if (!silent)
			_nc_warning("slashes aren't allowed in names or aliases");
		    break;
		} else if (strchr("$[]!*?", *ptr)) {
		    if (!silent)
			_nc_warning("dubious character `%c' in name or alias field", *ptr);
		    break;
		}
	    }

	    ptr = buffer;

	    _nc_curr_token.tk_name = buffer;
	    type = NAMES;
	} else {
	    while ((ch = next_char()) != EOF) {
		if (!isalnum(ch)) {
		    if (_nc_syntax == SYN_TERMINFO) {
			if (ch != '_')
			    break;
		    } else {	/* allow ';' for "k;" */
			if (ch != ';')
			    break;
		    }
		}
		*(ptr++) = ch;
	    }

	    *ptr++ = '\0';
	    switch (ch) {
	    case ',':
	    case ':':
		if (ch != separator)
		    _nc_err_abort("Separator inconsistent with syntax");
		_nc_curr_token.tk_name = buffer;
		type = BOOLEAN;
		break;
	    case '@':
		if ((ch = next_char()) != separator && !silent)
		    _nc_warning("Missing separator after `%s', have %s",
				buffer, unctrl((chtype) ch));
		_nc_curr_token.tk_name = buffer;
		type = CANCEL;
		break;

	    case '#':
		found = 0;
		while (isalnum(ch = next_char())) {
		    numbuf[found++] = ch;
		    if (found >= sizeof(numbuf) - 1)
			break;
		}
		numbuf[found] = '\0';
		number = strtol(numbuf, &numchk, 0);
		if (!silent) {
		    if (numchk == numbuf)
			_nc_warning("no value given for `%s'", buffer);
		    if ((*numchk != '\0') || (ch != separator))
			_nc_warning("Missing separator");
		}
		_nc_curr_token.tk_name = buffer;
		_nc_curr_token.tk_valnumber = number;
		type = NUMBER;
		break;

	    case '=':
		ch = _nc_trans_string(ptr, buffer + sizeof(buffer));
		if (!silent && ch != separator)
		    _nc_warning("Missing separator");
		_nc_curr_token.tk_name = buffer;
		_nc_curr_token.tk_valstring = ptr;
		type = STRING;
		break;

	    case EOF:
		type = EOF;
		break;
	    default:
		/* just to get rid of the compiler warning */
		type = UNDEF;
		if (!silent)
		    _nc_warning("Illegal character - %s", unctrl((chtype) ch));
	    }
	}			/* end else (first_column == FALSE) */
    }				/* end else (ch != EOF) */

  end_of_token:

#ifdef TRACE
    if (dot_flag == TRUE)
	DEBUG(8, ("Commented out "));

    if (_nc_tracing >= DEBUG_LEVEL(7)) {
	switch (type) {
	case BOOLEAN:
	    _tracef("Token: Boolean; name='%s'",
		    _nc_curr_token.tk_name);
	    break;

	case NUMBER:
	    _tracef("Token: Number;  name='%s', value=%d",
		    _nc_curr_token.tk_name,
		    _nc_curr_token.tk_valnumber);
	    break;

	case STRING:
	    _tracef("Token: String;  name='%s', value=%s",
		    _nc_curr_token.tk_name,
		    _nc_visbuf(_nc_curr_token.tk_valstring));
	    break;

	case CANCEL:
	    _tracef("Token: Cancel; name='%s'",
		    _nc_curr_token.tk_name);
	    break;

	case NAMES:

	    _tracef("Token: Names; value='%s'",
		    _nc_curr_token.tk_name);
	    break;

	case EOF:
	    _tracef("Token: End of file");
	    break;

	default:
	    _nc_warning("Bad token type");
	}
    }
#endif

    if (dot_flag == TRUE)	/* if commented out, use the next one */
	type = _nc_get_token(silent);

    DEBUG(3, ("token: `%s', class %d",
	      _nc_curr_token.tk_name != 0 ? _nc_curr_token.tk_name :
	      "<null>",
	      type));

    return (type);
}
示例#30
0
文件: lib_tparm.c 项目: vocho/openqnx
static inline char *tparam_internal(const char *string, va_list ap)
{
#define NUM_VARS 26
int	param[9];
int	popcount;
int	variable[NUM_VARS];
static int sVariable[NUM_VARS];
char	len;
int	number;
int	level;
int	x, y;
int	i;
int	varused = -1;
register const char *cp;

	out_used = 0;
	if (string == NULL)
		return NULL;

	/*
	 * Find the highest parameter-number referred to in the format string.
	 * Use this value to limit the number of arguments copied from the
	 * variable-length argument list.
	 */
	for (cp = string, popcount = number = 0; *cp != '\0'; cp++) {
		if (cp[0] == '%' && cp[1] != '\0') {
			switch (cp[1]) {
			case '%':
				cp++;
				break;
			case 'i':
				if (popcount < 2)
					popcount = 2;
				break;
			case 'p':
				cp++;
				if (cp[1] >= '1' && cp[1] <= '9') {
					int c = cp[1] - '0';
					if (c > popcount)
						popcount = c;
				}
				break;
			case '0': case '1': case '2': case '3': case '4':
			case '5': case '6': case '7': case '8': case '9':
			case 'd': case 'c': case 's':
				++number;
				break;
			}
		}
	}

	if (number > 9) number = 9;
	for (i = 0; i < max(popcount, number); i++) {
		/*
		 * FIXME: potential loss here if sizeof(int) != sizeof(char *).
		 * A few caps (such as plab_norm) have string-valued parms.
		 */
		param[i] = va_arg(ap, int);
	}

	/*
	 * This is a termcap compatibility hack.  If there are no explicit pop
	 * operations in the string, load the stack in such a way that
	 * successive pops will grab successive parameters.  That will make
	 * the expansion of (for example) \E[%d;%dH work correctly in termcap
	 * style, which means tparam() will expand termcap strings OK.
	 */
	stack_ptr = 0;
	if (popcount == 0) {
		popcount = number;
		for (i = number - 1; i >= 0; i--)
			npush(param[i]);
	}

#ifdef TRACE
	if (_nc_tracing & TRACE_CALLS) {
		for (i = 0; i < popcount; i++)
			save_number(", %d", param[i]);
		_tracef(T_CALLED("%s(%s%s)"), tname, _nc_visbuf(string), out_buff);
		out_used = 0;
 	}
#endif /* TRACE */

	while (*string) {
		if (*string != '%')
			save_char(*string);
		else {
			string++;
			switch (*string) {
			default:
				break;
			case '%':
				save_char('%');
				break;

			case 'd':
				save_number("%d", npop());
				break;

			case 'x':
				save_number("%x", npop());
				break;

			case '0':
				string++;
				len = *string;
				if (len == '2'  ||  len == '3')
				{
					++string;
					if (*string == 'd') {
						if (len == '2')
							save_number("%02d", npop());
						else
							save_number("%03d", npop());
					}
					else if (*string == 'x') {
						if (len == '2')
							save_number("%02x", npop());
						else
							save_number("%03x", npop());
					}
				}
				break;

			case '2':
				string++;
				if (*string == 'd') {
					save_number("%2d", npop());
				}
				else if (*string == 'x') {
					save_number("%2x", npop());
				}
				break;

			case '3':
				string++;
				if (*string == 'd') {
					save_number("%3d", npop());
				}
				else if (*string == 'x') {
					save_number("%3x", npop());
				}
				break;

			case 'c':
				save_char(npop());
				break;

			case 's':
				save_text(spop());
				break;

			case 'p':
				string++;
				if (*string >= '1'  &&  *string <= '9')
					npush(param[*string - '1']);
				break;

			case 'P':
				string++;
				if (islower(*string)) {
					i = (*string - 'a');
					if (i >= 0 && i < NUM_VARS) {
						while (varused < i)
							variable[++varused] = 0;
						variable[i] = npop();
					}
				} else {
					i = (*string - 'A');
					if (i >= 0 && i < NUM_VARS)
						sVariable[i] = npop();
				}
				break;

			case 'g':
				string++;
				if (islower(*string)) {
					i = (*string - 'a');
					if (i >= 0 && i < NUM_VARS) {
						while (varused < i)
							variable[++varused] = 0;
						npush(variable[i]);
					}
				} else {
					i = (*string - 'A');
					if (i >= 0 && i < NUM_VARS)
						npush(sVariable[i]);
				}
				break;

			case '\'':
				string++;
				npush(*string);
				string++;
				break;

			case L_BRACE:
				number = 0;
				string++;
				while (*string >= '0'  &&  *string <= '9') {
					number = number * 10 + *string - '0';
					string++;
				}
				npush(number);
				break;

			case '+':
				npush(npop() + npop());
				break;

			case '-':
				y = npop();
				x = npop();
				npush(x - y);
				break;

			case '*':
				npush(npop() * npop());
				break;

			case '/':
				y = npop();
				x = npop();
				npush(x / y);
				break;

			case 'm':
				y = npop();
				x = npop();
				npush(x % y);
				break;

			case 'A':
				npush(npop() && npop());
				break;

			case 'O':
				npush(npop() || npop());
				break;

			case '&':
				npush(npop() & npop());
				break;

			case '|':
				npush(npop() | npop());
				break;

			case '^':
				npush(npop() ^ npop());
				break;

			case '=':
				y = npop();
				x = npop();
				npush(x == y);
				break;

			case '<':
				y = npop();
				x = npop();
				npush(x < y);
				break;

			case '>':
				y = npop();
				x = npop();
				npush(x > y);
				break;

			case '!':
				npush(! npop());
				break;

			case '~':
				npush(~ npop());
				break;

			case 'i':
				param[0]++;
				param[1]++;
				break;

			case '?':
				break;

			case 't':
				x = npop();
				if (!x) {
					/* scan forward for %e or %; at level zero */
					string++;
					level = 0;
					while (*string) {
						if (*string == '%') {
							string++;
							if (*string == '?')
								level++;
							else if (*string == ';') {
								if (level > 0)
									level--;
								else
									break;
							}
							else if (*string == 'e'  && level == 0)
								break;
						}

						if (*string)
							string++;
					}
				}
				break;

			case 'e':
				/* scan forward for a %; at level zero */
				string++;
				level = 0;
				while (*string) {
					if (*string == '%') {
						string++;
						if (*string == '?')
							level++;
						else if (*string == ';') {
							if (level > 0)
								level--;
							else
								break;
						}
					}

					if (*string)
						string++;
				}
				break;

			case ';':
				break;

			} /* endswitch (*string) */
		} /* endelse (*string == '%') */

		if (*string == '\0')
			break;

		string++;
	} /* endwhile (*string) */

	if (out_buff == 0)
		out_buff = calloc(1,1);
	if (out_used == 0)
		*out_buff = '\0';

	T((T_RETURN("%s"), _nc_visbuf(out_buff)));
	return(out_buff);
}