-// FIXME: This could be an inline function, couldn't it?
-#define OPT_ADD_DEFAULT_ITEM_FLAGS(item, flags) \
- do { \
- if (item->letter >= 256) { \
- if (flags & OPT_VALUE_FLAGS) /* FIXME: Redundant condition */ \
- flags &= ~OPT_VALUE_FLAGS; \
- flags |= OPT_REQUIRED_VALUE; \
- } \
- if (!(flags & OPT_VALUE_FLAGS) && \
- (item->cls == OPT_CL_CALL || item->cls == OPT_CL_USER)) { \
- fprintf(stderr, "You MUST specify some of the value flags for the %c/%s item.\n", item->letter, item->name); \
- ASSERT(0); \
- } \
- else if (!(flags & OPT_VALUE_FLAGS)) /* FIXME: Streamline the conditions */ \
- flags |= opt_default_value_flags[item->cls]; \
- } while (0)
-// FIXME: Is this still useful? Isn't it better to use OPT_ADD_DEFAULT_ITEM_FLAGS during init?
-#define OPT_ITEM_FLAGS(item) ((item->flags & OPT_VALUE_FLAGS) ? item->flags : item->flags | opt_default_value_flags[item->cls])
-
-const struct opt_section * opt_section_root;
-
-#define FOREACHLINE(text) for (const char * begin = (text), * end = (text); (*end) && (end = strchrnul(begin, '\n')); begin = end+1)
-
-void opt_help_internal(const struct opt_section * help) {
- int sections_cnt = 0;
- int lines_cnt = 0;
-
- for (struct opt_item * item = help->opt; item->cls != OPT_CL_END; item++) {
- if (item->flags & OPT_NO_HELP) continue;
- if (item->cls == OPT_CL_SECTION) {
- sections_cnt++;
- continue;
- }
- if (!*(item->help)) {
- lines_cnt++;
- continue;
- }
- FOREACHLINE(item->help)
- lines_cnt++;
- }
-
- struct opt_sectlist {
- int pos;
- struct opt_section * sect;
- } sections[sections_cnt];
- int s = 0;
-
- const char *lines[lines_cnt][3];
- memset(lines, 0, sizeof(lines));
- int line = 0;
-
- int linelengths[3] = { -1, -1, -1 };
-
- for (struct opt_item * item = help->opt; item->cls != OPT_CL_END; item++) {
- if (item->flags & OPT_NO_HELP) continue;
-
- if (item->cls == OPT_CL_HELP) {
- if (!*(item->help)) {
- line++;
- continue;
- }
-#define SPLITLINES(text) do { \
- FOREACHLINE(text) { \
- int cell = 0; \
- for (const char * b = begin, * e = begin; (e < end) && (e = strchrnul(b, '\t')) && (e > end ? (e = end) : end); b = e+1) { \
- lines[line][cell] = b; \
- if (cell >= 2) \
- break; \
- else \
- if (*e == '\t' && linelengths[cell] < (e - b)) \
- linelengths[cell] = e-b; \
- cell++; \
- } \
- line++; \
- } } while (0)
- SPLITLINES(item->help);
- continue;
- }
-
- if (item->cls == OPT_CL_SECTION) {
- sections[s++] = (struct opt_sectlist) { .pos = line, .sect = item->u.section };
- continue;
- }
-
- uns valoff = strchrnul(item->help, '\t') - item->help;
- uns eol = strchrnul(item->help, '\n') - item->help;
- if (valoff > eol)
- valoff = eol;
-#define VAL(it) ((OPT_ITEM_FLAGS(it) & OPT_REQUIRED_VALUE) ? stk_printf("=%.*s", valoff, item->help) : ((OPT_ITEM_FLAGS(it) & OPT_NO_VALUE) ? "" : stk_printf("(=%.*s)", valoff, item->help)))
- if (item->name) {
- lines[line][1] = stk_printf("--%s%s", item->name, VAL(item));
- if (linelengths[1] < (int) strlen(lines[line][1]))
- linelengths[1] = strlen(lines[line][1]);
- lines[line][0] = "";
- if (linelengths[0] < 0)
- linelengths[0] = 0;
- }
- if (item->letter) {
- lines[line][0] = stk_printf("-%c,", item->letter);
- if (linelengths[0] < (int) strlen(lines[line][0]))
- linelengths[0] = strlen(lines[line][0]);
- }
-#undef VAL