+static void
+print_clean (const char *line)
+{
+ const char *p;
+ char ***offsets = NULL;
+ unsigned int count = 0, i = 0;
+
+ for (p = line; *p; p++)
+ {
+ /* ESC[ */
+ if (*p == 27 && *(p + 1) == '[')
+ {
+ bool check_values, first = true;
+ const char *begin = p;
+ p += 2;
+ if (!isdigit (*p))
+ goto END;
+ do {
+ const char *digit;
+ check_values = false;
+ if (!first && !isdigit (*p))
+ goto DISCARD;
+ digit = p;
+ while (isdigit (*p))
+ p++;
+ if (p - digit > 2)
+ goto DISCARD;
+ else /* check range */
+ {
+ char val[3];
+ int value;
+ unsigned int i;
+ const unsigned int digits = p - digit;
+ for (i = 0; i < digits; i++)
+ val[i] = *digit++;
+ val[i] = '\0';
+ value = atoi (val);
+ if (!((value >= 0 && value <= 8) /* attributes */
+ || (value >= 30 && value <= 37) /* foreground colors */
+ || (value >= 40 && value <= 47) /* background colors */
+ || (value == 39 || value == 49))) /* default colors */
+ goto DISCARD;
+ }
+ if (*p == ';')
+ {
+ p++;
+ check_values = true;
+ }
+ first = false;
+ } while (check_values);
+ END: if (*p == 'm')
+ {
+ const char *end = p;
+ if (!offsets)
+ offsets = xmalloc (++count * sizeof (char **));
+ else
+ offsets = xrealloc (offsets, ++count * sizeof (char **));
+ offsets[i] = xmalloc (2 * sizeof (char *));
+ offsets[i][0] = (char *)begin; /* ESC */
+ offsets[i][1] = (char *)end; /* m */
+ i++;
+ }
+ DISCARD:
+ continue;
+ }
+ }
+
+ if (offsets)
+ print_free_offsets (line, offsets, count);
+ else
+ printf (formats[FMT_GENERIC], line);
+}
+
+#define SET_CHAR(offset, new, old) \
+ *old = *offset; \
+ *offset = new; \
+
+#define RESTORE_CHAR(offset, old) \
+ *offset = old; \
+
+static void
+print_free_offsets (const char *line, char ***offsets, unsigned int count)
+{
+ char ch;
+ unsigned int i;
+
+ SET_CHAR (offsets[0][0], '\0', &ch);
+ printf (formats[FMT_GENERIC], line);
+ RESTORE_CHAR (offsets[0][0], ch);
+
+ for (i = 0; i < count; i++)
+ {
+ char ch;
+ bool next_offset = false;
+ if (i + 1 < count)
+ {
+ SET_CHAR (offsets[i + 1][0], '\0', &ch);
+ next_offset = true;
+ }
+ printf (formats[FMT_GENERIC], offsets[i][1] + 1);
+ if (next_offset)
+ RESTORE_CHAR (offsets[i + 1][0], ch);
+ }
+ for (i = 0; i < count; i++)
+ free_null (offsets[i]);
+ free_null (offsets);
+}
+