+ total_values++;
+ total_s_values++;
+ if (!q_opt) {
+ /*
+ * Note that the strings returned are mostly terminfo format, since
+ * ncurses does not convert except for a handful of special cases.
+ */
+ printf(FNAME(str), cap);
+ while (*str != 0) {
+ int ch = UChar(*str++);
+ switch (ch) {
+ case '\177':
+ fputs("^?", stdout);
+ break;
+ case '\033':
+ fputs("\\E", stdout);
+ break;
+ case '\b':
+ fputs("\\b", stdout);
+ break;
+ case '\f':
+ fputs("\\f", stdout);
+ break;
+ case '\n':
+ fputs("\\n", stdout);
+ break;
+ case '\r':
+ fputs("\\r", stdout);
+ break;
+ case ' ':
+ fputs("\\s", stdout);
+ break;
+ case '\t':
+ fputs("\\t", stdout);
+ break;
+ case '^':
+ fputs("\\^", stdout);
+ break;
+ case ':':
+ fputs("\\072", stdout);
+ break;
+ case '\\':
+ fputs("\\\\", stdout);
+ break;
+ default:
+ if (isgraph(ch))
+ fputc(ch, stdout);
+ else if (ch < 32)
+ printf("^%c", ch + '@');
+ else
+ printf("\\%03o", ch);
+ break;
+ }
+ }
+ printf("\n");
+ }
+ } else if ((num = tgetnum(cap)) >= 0) {
+ total_values++;
+ total_n_values++;
+ if (!q_opt) {
+ printf(FNAME(num), cap);
+ printf(" %d\n", num);
+ }
+ } else if (tgetflag(cap) > 0) {
+ total_values++;
+ total_b_values++;
+ if (!q_opt) {
+ printf(FNAME(flg), cap);
+ printf("%s\n", "true");
+ }
+ }
+
+ if (!q_opt)
+ fflush(stdout);
+}
+
+static void
+brute_force(const char *name)
+{
+ char buffer[1024];
+
+ if (db_list) {
+ putenv(next_dbitem());
+ }
+ if (!q_opt)
+ printf("Terminal type \"%s\"\n", name);
+ if (tgetent(buffer, name) >= 0) {
+ char cap[3];
+ int c1, c2;
+
+ cap[2] = 0;
+ for (EachCapName(c1)) {
+ cap[0] = (char) c1;
+ if (isCapName(c1)) {
+ for (EachCapName(c2)) {
+ cap[1] = (char) c2;
+ if (isCapName(c2)) {
+ dumpit(cap);
+ }
+ }
+ }
+ }
+ }
+}
+
+#if NCURSES_XNAMES
+static void
+dump_xname(NCURSES_CONST char *cap)
+{
+ if (strlen(cap) == 2)
+ dumpit(cap);
+}
+#endif
+
+static void
+demo_termcap(NCURSES_CONST char *name)
+{
+ unsigned n;
+ NCURSES_CONST char *cap;
+ char buffer[1024];
+
+ if (db_list) {
+ putenv(next_dbitem());
+ }
+ if (!q_opt)
+ printf("Terminal type \"%s\"\n", name);
+ if (tgetent(buffer, name) >= 0) {
+
+ if (b_opt) {
+ for (n = 0;; ++n) {
+ cap = my_boolcodes[n];
+ if (cap == 0)
+ break;
+ dumpit(cap);
+ }
+ }
+
+ if (n_opt) {
+ for (n = 0;; ++n) {
+ cap = my_numcodes[n];
+ if (cap == 0)
+ break;
+ dumpit(cap);
+ }
+ }
+
+ if (s_opt) {
+ for (n = 0;; ++n) {
+ cap = my_strcodes[n];
+ if (cap == 0)
+ break;
+ dumpit(cap);
+ }
+ }
+#ifdef NCURSES_VERSION
+ if (x_opt && (my_blob == 0) && y_opt) {
+#if NCURSES_XNAMES
+ TERMTYPE *term = &(cur_term->type);
+ if (term != 0
+ && ((NUM_BOOLEANS(term) != BOOLCOUNT)
+ || (NUM_NUMBERS(term) != NUMCOUNT)
+ || (NUM_STRINGS(term) != STRCOUNT))) {
+ for (n = BOOLCOUNT; n < NUM_BOOLEANS(term); ++n) {
+ dump_xname(ExtBoolname(term, (int) n, boolnames));
+ }
+ for (n = NUMCOUNT; n < NUM_NUMBERS(term); ++n) {
+ dump_xname(ExtNumname(term, (int) n, numnames));
+ }
+ for (n = STRCOUNT; n < NUM_STRINGS(term); ++n) {
+ dump_xname(ExtStrname(term, (int) n, strnames));
+ }
+ }
+#endif
+ }
+#endif
+ }
+}
+
+typedef enum {
+ pDefault = 0
+ ,pComment
+ ,pDescription
+ ,pEscaped
+ ,pNewline
+ ,pName
+ ,pNumber
+ ,pString
+} STATE;
+
+static void
+parse_description(const char *input_name)
+{
+ FILE *fp;
+ struct stat sb;
+ size_t count_bools = 0;
+ size_t count_nums = 0;
+ size_t count_strs = 0;
+ size_t len;
+ size_t j, k;
+ STATE state;
+
+ if (stat(input_name, &sb) != 0
+ || (sb.st_mode & S_IFMT) != S_IFREG) {
+ failed("input is not a file");
+ }
+
+ if (sb.st_size == 0) {
+ failed("input is empty");
+ }
+
+ /*
+ * None of the arrays could be larger than the input-file, and since it
+ * is small, just allocate the maximum for simplicity.
+ */
+ if ((my_blob = malloc((size_t) sb.st_size + 1)) == 0 ||
+ (my_boolcodes = typeCalloc(char *, sb.st_size)) == 0 ||
+ (my_numcodes = typeCalloc(char *, sb.st_size)) == 0 ||
+ (my_numvalues = typeCalloc(char *, sb.st_size)) == 0 ||
+ (my_strcodes = typeCalloc(char *, sb.st_size)) == 0 ||
+ (my_strvalues = typeCalloc(char *, sb.st_size)) == 0) {
+ failed("cannot allocate memory for input-file");
+ }
+
+ if ((fp = fopen(input_name, "r")) == 0)
+ failed("cannot open input-file");
+ len = fread(my_blob, sizeof(char), (size_t) sb.st_size, fp);
+ fclose(fp);
+
+ /*
+ * First, get rid of comments and escaped newlines, as well as repeated
+ * colons to construct a canonical entry.
+ *
+ * FIXME: actually this should make an additional pass just to strip
+ * comment-lines and escaped newlines. But it is workable for infocmp
+ * output.
+ */
+ state = pNewline;
+ for (j = k = 0; j < len; ++j) {
+ int ch = my_blob[j];
+ if (ch == '\t') {
+ ch = ' ';
+ }
+ switch (state) {
+ case pNewline:
+ if (ch == ' ') {
+ continue;
+ }
+ if (ch == '#') {
+ state = pComment;
+ continue;
+ }
+ state = pDefault;
+ /* FALLTHRU */
+ case pDefault: