static void convert_shorts(unsigned char *buf, short *Numbers, unsigned count) { unsigned i; for (i = 0; i < count; i++) { if (Numbers[i] == ABSENT_NUMERIC) { /* HI/LO won't work */ buf[2 * i] = buf[2 * i + 1] = 0377; } else if (Numbers[i] == CANCELLED_NUMERIC) { /* HI/LO won't work */ buf[2 * i] = 0376; buf[2 * i + 1] = 0377; } else { LITTLE_ENDIAN(buf + 2 * i, Numbers[i]); TRACE_OUT(("put Numbers[%d]=%d", i, Numbers[i])); } } }
static size_t convert_shorts(unsigned char *buf, short *Numbers, size_t count) { size_t i; for (i = 0; i < count; i++) { if (Numbers[i] == ABSENT_NUMERIC) { /* HI/LO won't work */ buf[2 * i] = buf[2 * i + 1] = 0377; } else if (Numbers[i] == CANCELLED_NUMERIC) { /* HI/LO won't work */ buf[2 * i] = 0376; buf[2 * i + 1] = 0377; } else { LITTLE_ENDIAN(buf + 2 * i, Numbers[i]); TRACE_OUT(("put Numbers[%u]=%d", (unsigned) i, Numbers[i])); } } return SIZEOF_SHORT; }
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); }
static int write_object(FILE *fp, TERMTYPE *tp) { char *namelist; size_t namelen, boolmax, nummax, strmax; char zero = '\0'; size_t i; short nextfree; short offsets[STRCOUNT]; unsigned char buf[MAX_ENTRY_SIZE]; namelist = tp->term_names; namelen = strlen(namelist) + 1; boolmax = 0; for (i = 0; i < BOOLWRITE; i++) if (tp->Booleans[i]) boolmax = i+1; nummax = 0; for (i = 0; i < NUMWRITE; i++) if (tp->Numbers[i] != ABSENT_NUMERIC) nummax = i+1; strmax = 0; for (i = 0; i < STRWRITE; i++) if (tp->Strings[i] != ABSENT_STRING) strmax = i+1; nextfree = 0; for (i = 0; i < strmax; i++) if (tp->Strings[i] == ABSENT_STRING) offsets[i] = -1; else if (tp->Strings[i] == CANCELLED_STRING) offsets[i] = -2; else { offsets[i] = nextfree; nextfree += strlen(tp->Strings[i]) + 1; } /* 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 */ if (fwrite(buf, 12, 1, fp) != 1 || fwrite(namelist, sizeof(char), (size_t)namelen, fp) != namelen || fwrite(tp->Booleans, sizeof(char), (size_t)boolmax, fp) != boolmax) return(ERR); /* the even-boundary padding byte */ if ((namelen+boolmax) % 2 != 0 && fwrite(&zero, sizeof(char), 1, fp) != 1) return(ERR); #ifdef SHOWOFFSET (void) fprintf(stderr, "Numerics begin at %04lx\n", ftell(fp)); #endif /* SHOWOFFSET */ /* the numerics */ for (i = 0; i < nummax; i++) { if (tp->Numbers[i] == -1) /* HI/LO won't work */ buf[2*i] = buf[2*i + 1] = 0377; else if (tp->Numbers[i] == -2) /* HI/LO won't work */ buf[2*i] = 0376, buf[2*i + 1] = 0377; else LITTLE_ENDIAN(buf + 2*i, tp->Numbers[i]); } if (fwrite(buf, 2, (size_t)nummax, fp) != nummax) return(ERR); #ifdef SHOWOFFSET (void) fprintf(stderr, "String offets begin at %04lx\n", ftell(fp)); #endif /* SHOWOFFSET */ /* the string offsets */ for (i = 0; i < strmax; i++) if (offsets[i] == -1) /* HI/LO won't work */ buf[2*i] = buf[2*i + 1] = 0377; else if (offsets[i] == -2) /* HI/LO won't work */ { buf[2*i] = 0376; buf[2*i + 1] = 0377; } else LITTLE_ENDIAN(buf + 2*i, offsets[i]); if (fwrite(buf, 2, (size_t)strmax, fp) != strmax) return(ERR); #ifdef SHOWOFFSET (void) fprintf(stderr, "String table begins at %04lx\n", ftell(fp)); #endif /* SHOWOFFSET */ /* the strings */ for (i = 0; i < strmax; i++) if (tp->Strings[i] != ABSENT_STRING && tp->Strings[i] != CANCELLED_STRING) if (fwrite(tp->Strings[i], sizeof(char), strlen(tp->Strings[i]) + 1, fp) != strlen(tp->Strings[i]) + 1) return(ERR); total_written++; return(OK); }