+static void
+process_opt_attr (const char *p)
+{
+ /* If attributes are added to this "list", also increase MAX_ATTRIBUTE_CHARS! */
+ const struct attr {
+ const char *name;
+ unsigned int val;
+ enum attr_type type;
+ } attrs[] = {
+ { "bold", 1, ATTR_BOLD },
+ { "underscore", 4, ATTR_UNDERSCORE },
+ { "blink", 5, ATTR_BLINK },
+ { "reverse", 7, ATTR_REVERSE },
+ { "concealed", 8, ATTR_CONCEALED },
+ };
+ unsigned int attr_types = 0;
+
+ while (*p)
+ {
+ const char *s;
+ if (!isalnum (*p))
+ vfprintf_fail (formats[FMT_GENERIC], "--attr switch must be provided a string");
+ s = p;
+ while (isalnum (*p))
+ p++;
+ if (*p != '\0' && *p != ',')
+ vfprintf_fail (formats[FMT_GENERIC], "--attr switch must have strings separated by ,");
+ else
+ {
+ bool valid_attr = false;
+ unsigned int i;
+ for (i = 0; i < sizeof (attrs) / sizeof (struct attr); i++)
+ {
+ size_t name_len = strlen (attrs[i].name);
+ if ((size_t)(p - s) == name_len && strneq (s, attrs[i].name, name_len))
+ {
+ write_attr (attrs[i].val, &attr_types, attrs[i].type, attrs[i].name);
+ valid_attr = true;
+ break;
+ }
+ }
+ if (!valid_attr)
+ vfprintf_fail (formats[FMT_GENERIC], "--attr switch must be provided valid attribute names");
+ }
+ if (*p)
+ p++;
+ }
+}
+
+static void
+write_attr (unsigned int val, unsigned int *attr_types, enum attr_type attr_type, const char *attr_name)
+{
+ if (*attr_types & attr_type)
+ vfprintf_fail ("--attr switch has attribute '%s' twice or more", attr_name);
+ snprintf (attr + strlen (attr), 3, "%u;", val);
+ *attr_types |= attr_type;
+}
+