+#else
+#define check_c_values(n) /* nothing */
+#endif
+#endif
+
+static int
+gather_c_values(int fg)
+{
+ int found = -1;
+#if HAVE_TSEARCH
+ FG_NODE **ft;
+ int next = reading_last;
+
+ reading_ncols[next].fgcol = fg;
+ reading_ncols[next].count = 0;
+
+ check_c_values(__LINE__);
+ if ((ft = tfind(I2P(next), &reading_ntree, compare_c_values)) != 0) {
+ found = P2I(*ft);
+ } else {
+ if (reading_last + 2 >= reading_size) {
+ int more = ((MAX(reading_last, reading_size) + 2) * 3) / 2;
+ int last = reading_last + 1;
+ FG_NODE *p = typeRealloc(FG_NODE, more, reading_ncols);
+ if (p == 0)
+ goto done;
+
+ reading_size = more;
+ reading_ncols = p;
+ memset(reading_ncols + last, 0,
+ sizeof(FG_NODE) * (size_t) (more - last));
+ check_c_values(__LINE__);
+ }
+ ++reading_last;
+ how_much.pair += sizeof(FG_NODE);
+ if ((ft = tsearch(I2P(next), &reading_ntree, compare_c_values)) != 0) {
+ found = P2I(*ft);
+ if (found != next)
+ logmsg("OOPS expected slot %d, got %d", next, found);
+ debugmsg("allocated color #%d as #%06X", next, fg);
+ check_c_values(__LINE__);
+ }
+ }
+#else
+ int n;
+
+ for (n = 0; n < reading_last; ++n) {
+ if (reading_ncols[n].fgcol == fg) {
+ found = n;
+ break;
+ }
+ }
+ if (found < 0) {
+ if (reading_last + 2 >= reading_size) {
+ int more = ((reading_last + 2) * 3) / 2;
+ FG_NODE *p = typeRealloc(FG_NODE, more, reading_ncols);
+ if (p == 0)
+ goto done;
+
+ how_much.pair -= (sizeof(FG_NODE) * (size_t) reading_size);
+ how_much.pair += (sizeof(FG_NODE) * (size_t) more);
+ reading_size = more;
+ reading_ncols = p;
+ memset(reading_ncols + reading_last, 0,
+ sizeof(FG_NODE) * (size_t) (more - reading_last));
+ }
+ reading_ncols[reading_last].fgcol = fg;
+ found = reading_last++;
+ }
+#endif
+ done:
+ return found;
+}
+
+static void
+finish_c_values(PICS_HEAD * head)
+{
+ head->colors = reading_last;
+ head->fgcol = reading_ncols;
+
+ reading_last = 0;
+ reading_size = 0;
+ reading_ncols = 0;
+}
+
+#if HAVE_TSEARCH && HAVE_TDESTROY
+static void
+never_free(void *node GCC_UNUSED)
+{
+}
+#endif
+
+static void
+dispose_c_values(void)
+{
+#if HAVE_TSEARCH
+ if (reading_ntree != 0) {
+#if HAVE_TDESTROY
+ tdestroy(reading_ntree, never_free);
+#else
+ int n;
+ for (n = 0; n < reading_last; ++n) {
+ tdelete(I2P(n), &reading_ntree, compare_c_values);
+ }
+#endif
+ reading_ntree = 0;
+ }
+#endif
+ if (reading_ncols != 0) {
+ free(reading_ncols);
+ reading_ncols = 0;
+ }
+ reading_last = 0;
+ reading_size = 0;
+}
+
+static int
+is_file(const char *filename, struct stat *sb)
+{
+ int result = 0;
+ if (stat(filename, sb) == 0
+ && (sb->st_mode & S_IFMT) == S_IFREG
+ && sb->st_size != 0) {
+ result = 1;
+ }
+ debugmsg("is_file(%s) %d", filename, result);
+ return result;
+}