Пример #1
0
static struct name_table_entry const *
_nc_extend_names(ENTRY * entryp, char *name, int token_type)
{
    static struct name_table_entry temp;
    TERMTYPE *tp = &(entryp->tterm);
    unsigned offset = 0;
    unsigned actual;
    unsigned tindex;
    unsigned first, last, n;
    bool found;

    switch (token_type) {
    case BOOLEAN:
	first = 0;
	last = tp->ext_Booleans;
	offset = tp->ext_Booleans;
	tindex = tp->num_Booleans;
	break;
    case NUMBER:
	first = tp->ext_Booleans;
	last = tp->ext_Numbers + first;
	offset = tp->ext_Booleans + tp->ext_Numbers;
	tindex = tp->num_Numbers;
	break;
    case STRING:
	first = tp->ext_Booleans + tp->ext_Numbers;
	last = tp->ext_Strings + first;
	offset = tp->ext_Booleans + tp->ext_Numbers + tp->ext_Strings;
	tindex = tp->num_Strings;
	break;
    case CANCEL:
	actual = NUM_EXT_NAMES(tp);
	for (n = 0; n < actual; n++) {
	    if (!strcmp(name, tp->ext_Names[n])) {
		if (n > (unsigned) (tp->ext_Booleans + tp->ext_Numbers)) {
		    token_type = STRING;
		} else if (n > tp->ext_Booleans) {
		    token_type = NUMBER;
		} else {
		    token_type = BOOLEAN;
		}
		return _nc_extend_names(entryp, name, token_type);
	    }
	}
	/* Well, we are given a cancel for a name that we don't recognize */
	return _nc_extend_names(entryp, name, STRING);
    default:
	return 0;
    }

    /* Adjust the 'offset' (insertion-point) to keep the lists of extended
     * names sorted.
     */
    for (n = first, found = FALSE; n < last; n++) {
	int cmp = strcmp(tp->ext_Names[n], name);
	if (cmp == 0)
	    found = TRUE;
	if (cmp >= 0) {
	    offset = n;
	    tindex = n - first;
	    switch (token_type) {
	    case BOOLEAN:
		tindex += BOOLCOUNT;
		break;
	    case NUMBER:
		tindex += NUMCOUNT;
		break;
	    case STRING:
		tindex += STRCOUNT;
		break;
	    }
	    break;
	}
    }
    if (!found) {
	switch (token_type) {
	case BOOLEAN:
	    tp->ext_Booleans += 1;
	    tp->num_Booleans += 1;
	    tp->Booleans = typeRealloc(NCURSES_SBOOL, tp->num_Booleans, tp->Booleans);
	    for (last = tp->num_Booleans - 1; last > tindex; last--)
		tp->Booleans[last] = tp->Booleans[last - 1];
	    break;
	case NUMBER:
	    tp->ext_Numbers += 1;
	    tp->num_Numbers += 1;
	    tp->Numbers = typeRealloc(short, tp->num_Numbers, tp->Numbers);
	    for (last = tp->num_Numbers - 1; last > tindex; last--)
		tp->Numbers[last] = tp->Numbers[last - 1];
	    break;
	case STRING:
	    tp->ext_Strings += 1;
	    tp->num_Strings += 1;
	    tp->Strings = typeRealloc(char *, tp->num_Strings, tp->Strings);
	    for (last = tp->num_Strings - 1; last > tindex; last--)
		tp->Strings[last] = tp->Strings[last - 1];
	    break;
	}
	actual = NUM_EXT_NAMES(tp);
	tp->ext_Names = typeRealloc(char *, actual, tp->ext_Names);
	while (--actual > offset)
	    tp->ext_Names[actual] = tp->ext_Names[actual - 1];
	tp->ext_Names[offset] = _nc_save_str(name);
    }

    temp.nte_name = tp->ext_Names[offset];
    temp.nte_type = token_type;
    temp.nte_index = tindex;
    temp.nte_link = -1;

    return &temp;
}
Пример #2
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);
}