Exemplo n.º 1
0
/** find_option_short
  *
  *     Finds the option specification for a short option name (i.e., an
  *     option of the form "-o").
  *
  * PARAMETERS:
  *     IN context   : The dropt context.
  *     IN shortName : The short option name to search for.
  *
  * RETURNS:
  *     A pointer to the corresponding option specification or NULL if not
  *       found.
  */
static const dropt_option *
find_option_short(const dropt_context * context, dropt_char shortName)
{
  assert(context != NULL);
  assert(shortName != DROPT_TEXT_LITERAL('\0'));
  assert(context->ncmpstr != NULL);

  if (context->sortedByShort != NULL) {
    option_proxy * found = bsearch(&shortName, context->sortedByShort,
                                   context->numOptions, sizeof * (context->sortedByShort),
                                   cmp_key_option_proxy_short);
    return (found == NULL) ? NULL : found->option;
  }

  /* Fall back to a linear search. */
  {
    const dropt_option * option;
    for (option = context->options; is_valid_option(option); option++) {
      if (context->ncmpstr(&shortName, &option->short_name, 1) == 0) {
        return option;
      }
    }
  }
  return NULL;
}
Exemplo n.º 2
0
/** find_option_long
  *
  *     Finds the option specification for a long option name (i.e., an
  *     option of the form "--option").
  *
  * PARAMETERS:
  *     IN context     : The dropt context.
  *     IN longName    : The long option name to search for (excluding
  *                        leading dashes).
  *                      longName.s must not be NULL.
  *
  * RETURNS:
  *     A pointer to the corresponding option specification or NULL if not
  *       found.
  */
static const dropt_option *
find_option_long(const dropt_context * context,
                 char_array longName)
{
  assert(context != NULL);
  assert(longName.s != NULL);

  if (context->sortedByLong != NULL) {
    option_proxy * found = bsearch(&longName, context->sortedByLong,
                                   context->numOptions, sizeof * (context->sortedByLong),
                                   cmp_key_option_proxy_long);
    return (found == NULL) ? NULL : found->option;
  }

  /* Fall back to a linear search. */
  {
    option_proxy item = { 0 };
    item.context = context;
    for (item.option = context->options; is_valid_option(item.option); item.option++) {
      if (cmp_key_option_proxy_long(&longName, &item) == 0) {
        return item.option;
      }
    }
  }
  return NULL;
}
Exemplo n.º 3
0
manager::manager(const config &gamecfg, CVideo &video, gui::scrollpane *pane, const config &values)
	: options_info_()
	, values_(values)
	, video_(video)
	, pane_(pane)
	, era_()
	, scenario_()
	, is_campaign_()
	, modifications_()
	, widgets_()
	, widgets_ordered_()
{
	DBG_MP << "Initializing the options manager" << std::endl;
	init_info(gamecfg, "modification");
	init_info(gamecfg, "era");
	init_info(gamecfg, "multiplayer");
	init_info(gamecfg, "campaign");

	BOOST_FOREACH (const config::any_child& i,
				   options_info_.all_children_range())
	{
		BOOST_FOREACH (const config::any_child& j, i.cfg.all_children_range())
		{
			if (is_valid_option(j.key, j.cfg)) {
				config& value = get_value_cfg(j.cfg["id"]);
				value["value"] = get_stored_value(j.cfg["id"]);
			}
		}
	}

	init_widgets();
}
Exemplo n.º 4
0
int main(int argc, char *argv[]) {
    char option = '\0';
    char *filepath = NULL;
    unsigned int length = 0;
    int *array = NULL;
    int *original_array = NULL;
	struct sorting_stats ops;
    /* parse the filepath given in command line arguments */
    filepath = parse_filepath(argc, argv);

    /* parse the array given in the input file */
    array = array_from_file(filepath, &length);

    /* save a copy of array used to make some checks later */
    original_array = array_duplicate(array, length);

    /* print a simple menu and do the actual sorting */
    do {
        option = print_menu();
        switch (option) {
        case INSERTION_SORT:
            ops = insertion_sort(array, length);
            break;
        case SELECTION_SORT:
            ops = selection_sort(array, length);
            break;
        case QUICK_SORT:
            ops = quick_sort(array, length);
            break;
        case EXIT:
            printf("Exiting.\n");
            return (EXIT_SUCCESS);
        default:
            printf("\n\"%c\" is invalid. Please choose a valid option."
                   "\n\n", option);
        }
    } while (!is_valid_option(option));

    /* show the ordered array in the screen */
    array_dump(array, length);
    
    // show the comparation of the algorithm
    printf("Comparisons: %d \n",(int)ops.comps);
    printf("Swaps: %d \n",(int)ops.swaps);
    
    /* check if it is sorted */
    assert(array_is_sorted(array, length));

    /* check if it is a permutation of original */
    assert(array_is_permutation_of(array, original_array, length));

    /* destroy array */
    array_destroy(array);
    array_destroy(original_array);

    return (EXIT_SUCCESS);
}
Exemplo n.º 5
0
char catch_options(char *param, int ac, char **av, int *k, int *index, char *options, char (*message)[100])
{
    unsigned int i;

    for (i = 1; i < strlen(param); i++) {
        if (!has_option(param[i], options)) {
            if (is_valid_option(param[i])) {
                options[*index] = param[i];
                if (param[i] == 'p' && (*k + 1) <= (ac - 1)) {
                    *k = *k + 1;
                    strcpy(message[0], av[*k]);
                }
                else if (param[i] == 'L' && (*k + 1) <= (ac - 1)) {
                    *k = *k + 1;
                    strcpy(message[1], av[*k]);
                }
                *index = *index + 1;
            }
            else
                return (param[i]);
        }
    }
    return (0);
}
Exemplo n.º 6
0
/** dropt_new_context
  *
  *     Creates a new dropt context.
  *
  * PARAMETERS:
  *     IN options : The list of option specifications.
  *                  Must not be NULL.
  *
  * RETURNS:
  *     An allocated dropt context.  The caller is responsible for freeing
  *       it with dropt_free_context when no longer needed.
  *     Returns NULL on error.
  */
dropt_context *
dropt_new_context(const dropt_option * options)
{
  dropt_context * context = NULL;
  size_t n;

  if (options == NULL) {
    DROPT_MISUSE("No option list specified.");
    goto exit;
  }

  /* Sanity-check the options. */
  for (n = 0; is_valid_option(&options[n]); n++) {
    if (options[n].short_name == DROPT_TEXT_LITERAL('=')
        || (options[n].long_name != NULL
            && dropt_strchr(options[n].long_name, DROPT_TEXT_LITERAL('=')) != NULL)) {
      DROPT_MISUSE("Invalid option list. '=' may not be used in an option name.");
      goto exit;
    }
  }

  context = malloc(sizeof * context);
  if (context == NULL) {
    goto exit;
  } else {
    dropt_context emptyContext = { 0 };
    *context = emptyContext;

    context->options = options;
    context->numOptions = n;
    dropt_set_strncmp(context, NULL);
  }

exit:
  return context;
}
Exemplo n.º 7
0
/*
 * Validate the generic options given to a FOREIGN DATA WRAPPER, SERVER,
 * USER MAPPING or FOREIGN TABLE that uses file_fdw.
 *
 * Raise an ERROR if the option or its value is considered invalid.
 */
Datum
file_fdw_validator(PG_FUNCTION_ARGS)
{
	List	   *options_list = untransformRelOptions(PG_GETARG_DATUM(0));
	Oid			catalog = PG_GETARG_OID(1);
	char	   *filename = NULL;
	DefElem	   *force_not_null = NULL;
	List	   *other_options = NIL;
	ListCell   *cell;

	/*
	 * Only superusers are allowed to set options of a file_fdw foreign table.
	 * This is because the filename is one of those options, and we don't want
	 * non-superusers to be able to determine which file gets read.
	 *
	 * Putting this sort of permissions check in a validator is a bit of a
	 * crock, but there doesn't seem to be any other place that can enforce
	 * the check more cleanly.
	 *
	 * Note that the valid_options[] array disallows setting filename at any
	 * options level other than foreign table --- otherwise there'd still be a
	 * security hole.
	 */
	if (catalog == ForeignTableRelationId && !superuser())
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 errmsg("only superuser can change options of a file_fdw foreign table")));

	/*
	 * Check that only options supported by file_fdw, and allowed for the
	 * current object type, are given.
	 */
	foreach(cell, options_list)
	{
		DefElem    *def = (DefElem *) lfirst(cell);

		if (!is_valid_option(def->defname, catalog))
		{
			struct FileFdwOption *opt;
			StringInfoData buf;

			/*
			 * Unknown option specified, complain about it. Provide a hint
			 * with list of valid options for the object.
			 */
			initStringInfo(&buf);
			for (opt = valid_options; opt->optname; opt++)
			{
				if (catalog == opt->optcontext)
					appendStringInfo(&buf, "%s%s", (buf.len > 0) ? ", " : "",
									 opt->optname);
			}

			ereport(ERROR,
					(errcode(ERRCODE_FDW_INVALID_OPTION_NAME),
					 errmsg("invalid option \"%s\"", def->defname),
					 errhint("Valid options in this context are: %s",
							 buf.data)));
		}

		/*
		 * Separate out filename and force_not_null, since ProcessCopyOptions
		 * won't accept them.  (force_not_null only comes in a boolean
		 * per-column flavor here.)
		 */
		if (strcmp(def->defname, "filename") == 0)
		{
			if (filename)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options")));
			filename = defGetString(def);
		}
		else if (strcmp(def->defname, "force_not_null") == 0)
		{
			if (force_not_null)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options")));
			force_not_null = def;
			/* Don't care what the value is, as long as it's a legal boolean */
			(void) defGetBoolean(def);
		}
		else
			other_options = lappend(other_options, def);
	}
Exemplo n.º 8
0
Arquivo: options.c Projeto: mej/libast
/**
 * Parse the command line arguments for options.
 *
 * This function iterates through the command line arguments looking
 * for options which have been defined.  Each option encountered is
 * handled according to its type.
 *
 * @param argc The number of arguments.
 * @param argv The array of argument strings.
 *
 * @see @link DOXGRP_OPT Command Line Option Parser @endlink
 * @ingroup DOXGRP_OPT
 */
void
spifopt_parse(int argc, char *argv[])
{
    spif_int32_t i, j;
    spif_charptr_t opt;

    REQUIRE(argc > 1);
    REQUIRE(argv != NULL);

    /* Process each command line arg one-by-one. */
    for (i = 1, opt = SPIF_CHARPTR(argv[1]); i < argc; ) {
        spif_charptr_t val_ptr = NULL;
        spif_char_t islong = 0, hasequal = 0;

        D_OPTIONS(("argv[%d] == \"%s\", opt == \"%s\"\n", i, argv[i], opt));

        if (SPIF_PTR_ISNULL(opt)) {
            /* NEXT_ARG(); */
            break;
        } else if (opt == SPIF_CHARPTR(argv[i])) {
            /* If it's not an option, skip it. */
            if (*opt != '-') {
                NEXT_ARG();
            } else {
                opt++;
            }
        }

        /* If the second character is also a hyphen, it's a long option. */
        if (*opt == '-') {
            islong = 1;
            /* Skip the leading "--" */
            opt++;
            D_OPTIONS(("Long option detected\n"));
            if ((j = find_long_option(opt)) == -1) {
                NEXT_ARG();
            }
        } else {
            if ((j = find_short_option(*opt)) == -1) {
                NEXT_LETTER();
            }
        }
        if (!SPIFOPT_FLAGS_IS_SET(SPIFOPT_SETTING_PREPARSE) && SPIFOPT_FLAGS_IS_SET(SPIFOPT_SETTING_REMOVE_ARGS)) {
            argv[i] = NULL;
        }

        /* If a value was passed to this option, set val_ptr to point to it. */
        if (islong) {
            val_ptr = find_value_long(SPIF_CHARPTR(opt), SPIF_CHARPTR(argv[i + 1]), &hasequal);
        } else {
            val_ptr = find_value_short(opt, SPIF_CHARPTR(argv[i + 1]));
        }

        /* Boolean options may or may not have a value... */
        if (val_ptr) {
            if (SPIFOPT_OPT_IS_BOOLEAN(j) && !is_boolean_value(val_ptr)) {
                val_ptr = NULL;
            } else if (SPIFOPT_OPT_IS_ABSTRACT(j) && is_valid_option(val_ptr)) {
                val_ptr = NULL;
            }
        }
        if (val_ptr) {
            if (val_ptr == SPIF_CHARPTR(argv[i + 1])) {
                i++;
                opt += strlen((char *) opt);
            }
        }

        /* If this option is deprecated, print a warning before continuing. */
        if (SPIFOPT_OPT_IS_DEPRECATED(j)) {
            spif_str_t warn;

            warn = spif_str_new_from_buff(SPIF_CHARPTR("The "), 128);
            if (SPIFOPT_OPT_SHORT(j)) {
                spif_str_append_char(warn, '-');
                spif_str_append_char(warn, SPIFOPT_OPT_SHORT(j));
                spif_str_append_from_ptr(warn, SPIF_CHARPTR(" / --"));
            } else {
                spif_str_append_from_ptr(warn, SPIF_CHARPTR("--"));
            }
            spif_str_append_from_ptr(warn, SPIFOPT_OPT_LONG(j));
            spif_str_append_from_ptr(warn, SPIF_CHARPTR(" option is deprecated and should not be used.\n"));
            libast_print_warning((char *) SPIF_STR_STR(warn));
            spif_str_del(warn);
        }

        /* Make sure that options which require a parameter have them. */
        if (SPIFOPT_OPT_NEEDS_VALUE(j)) {
            if (!val_ptr) {
                if (islong) {
                    libast_print_error("long option --%s requires a%s value\n", SPIFOPT_OPT_LONG(j),
                                (SPIFOPT_OPT_IS_INTEGER(j)
                                 ? ("n integer")
                                 : (SPIFOPT_OPT_IS_STRING(j)
                                    ? " string"
                                    : (SPIFOPT_OPT_IS_ARGLIST(j)
                                       ? "n argument list"
                                       : ""))));
                } else {
                    libast_print_error("option -%c requires a%s value\n", SPIFOPT_OPT_SHORT(j),
                                (SPIFOPT_OPT_IS_INTEGER(j)
                                 ? ("n integer")
                                 : (SPIFOPT_OPT_IS_STRING(j)
                                    ? " string"
                                    : (SPIFOPT_OPT_IS_ARGLIST(j)
                                       ? "n argument list"
                                       : ""))));
                }
                CHECK_BAD();
                continue;
            }
            /* Also make sure we know what to do with the value. */
            if (!SPIFOPT_OPT_VALUE(j)) {
                NEXT_LOOP();
            }
        } else if (SPIFOPT_OPT_IS_ABSTRACT(j) && !SPIFOPT_OPT_VALUE(j)) {
            /* Also make sure that abstract options have a function pointer. */
            NEXT_LOOP();
        }

        if (SPIFOPT_OPT_IS_BOOLEAN(j)) {
            if (!handle_boolean(j, val_ptr, islong)) {
                i--;
            }
        } else if (SPIFOPT_OPT_IS_STRING(j)) {
            if (SHOULD_PARSE(j)) {
                handle_string(j, val_ptr);
            }
        } else if (SPIFOPT_OPT_IS_INTEGER(j)) {
            if (SHOULD_PARSE(j)) {
                handle_integer(j, val_ptr);
            }
        } else if (SPIFOPT_OPT_IS_ARGLIST(j)) {
            if (SHOULD_PARSE(j)) {
                handle_arglist(j, val_ptr, hasequal, i, argc, argv);
            }
            if (!hasequal) {
                break;
            }
        } else if (SPIFOPT_OPT_IS_ABSTRACT(j)) {
            if (SHOULD_PARSE(j)) {
                D_OPTIONS(("Abstract option detected\n"));
                ((spifopt_abstract_handler_t) SPIFOPT_OPT_VALUE(j))(val_ptr);
            }
        }
        if (!SPIFOPT_FLAGS_IS_SET(SPIFOPT_SETTING_PREPARSE) && SPIFOPT_FLAGS_IS_SET(SPIFOPT_SETTING_REMOVE_ARGS)) {
            argv[i] = NULL;
        }
        NEXT_LOOP();
    }

    if (SPIFOPT_FLAGS_IS_SET(SPIFOPT_SETTING_PREPARSE)) {
        SPIFOPT_FLAGS_CLEAR(SPIFOPT_SETTING_PREPARSE);
    } else if (SPIFOPT_FLAGS_IS_SET(SPIFOPT_SETTING_REMOVE_ARGS)) {
        for (i = 1, j = 1; i < argc; i++) {
            if (argv[i]) {
                argv[j] = argv[i];
                j++;
            }
        }
        if (j > 1) {
            argv[j] = NULL;
        }
    }
}
Exemplo n.º 9
0
/*
 * Validate the generic options given to a FOREIGN DATA WRAPPER, SERVER,
 * USER MAPPING or FOREIGN TABLE that uses file_fdw.
 *
 * Raise an ERROR if the option or its value is considered invalid.
 */
Datum
s3_fdw_validator(PG_FUNCTION_ARGS)
{
	List	   *options_list = untransformRelOptions(PG_GETARG_DATUM(0));
	Oid			catalog = PG_GETARG_OID(1);
	char	   *filename = NULL,
			   *bucketname = NULL,
			   *hostname = NULL,
			   *accesskey = NULL,
			   *secretkey = NULL;
	List	   *copy_options = NIL;
	ListCell   *cell;

	/*
	 * Check that only options supported by s3_fdw, and allowed for the
	 * current object type, are given.
	 */
	foreach(cell, options_list)
	{
		DefElem    *def = (DefElem *) lfirst(cell);

		if (!is_valid_option(def->defname, catalog))
		{
			struct S3FdwOption *opt;
			StringInfoData buf;

			/*
			 * Unknown option specified, complain about it. Provide a hint
			 * with list of valid options for the object.
			 */
			initStringInfo(&buf);
			for (opt = valid_options; opt->optname; opt++)
			{
				if (catalog == opt->optcontext)
					appendStringInfo(&buf, "%s%s", (buf.len > 0) ? ", " : "",
									 opt->optname);
			}

			ereport(ERROR,
					(errcode(ERRCODE_FDW_INVALID_OPTION_NAME),
					 errmsg("invalid option \"%s\"", def->defname),
					 errhint("Valid options in this context are: %s",
							 buf.data)));
		}

		/* Separate out filename, since ProcessCopyOptions won't allow it */
		if (strcmp(def->defname, "filename") == 0)
		{
			if (filename)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options")));
			filename = defGetString(def);
		}
		else if(strcmp(def->defname, "bucketname") == 0)
		{
			if (bucketname)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options")));
			bucketname = defGetString(def);
		}
		else if(strcmp(def->defname, "hostname") == 0)
		{
			if (hostname)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options")));
			hostname = defGetString(def);
		}
		else if(strcmp(def->defname, "accesskey") == 0)
		{	
			if (accesskey)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options")));
			accesskey = defGetString(def);
		}
		else if(strcmp(def->defname, "secretkey") == 0)
		{
			if (secretkey)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options")));
			secretkey = defGetString(def);
		}
		else
			copy_options = lappend(copy_options, def);
	}
Exemplo n.º 10
0
Datum
ppg_fdw_validator(PG_FUNCTION_ARGS)
{
	List	   *options_list = untransformRelOptions(PG_GETARG_DATUM(0));
	Oid			catalog = PG_GETARG_OID(1);
	ListCell   *cell;

	/* Build our options lists if we didn't yet. */
	InitPgFdwOptions();

	/*
	 * Check that only options supported by postgres_fdw, and allowed for the
	 * current object type, are given.
	 */
	foreach(cell, options_list)
	{
		DefElem    *def = (DefElem *) lfirst(cell);

		if (!is_valid_option(def->defname, catalog))
		{
			/*
			 * Unknown option specified, complain about it. Provide a hint
			 * with list of valid options for the object.
			 */
			PgFdwOption *opt;
			StringInfoData buf;

			initStringInfo(&buf);
			for (opt = postgres_fdw_options; opt->keyword; opt++)
			{
				if (catalog == opt->optcontext)
					appendStringInfo(&buf, "%s%s", (buf.len > 0) ? ", " : "",
									 opt->keyword);
			}

			ereport(ERROR,
					(errcode(ERRCODE_FDW_INVALID_OPTION_NAME),
					 errmsg("invalid option \"%s\"", def->defname),
					 errhint("Valid options in this context are: %s",
							 buf.data)));
		}

		/*
		 * Validate option value, when we can do so without any context.
		 */
		if (strcmp(def->defname, "use_remote_estimate") == 0)
		{
			/* use_remote_estimate accepts only boolean values */
			(void) defGetBoolean(def);
		}
		else if (strcmp(def->defname, "fdw_startup_cost") == 0 ||
				 strcmp(def->defname, "fdw_tuple_cost") == 0)
		{
			/* these must have a non-negative numeric value */
			double		val;
			char	   *endp;

			val = strtod(defGetString(def), &endp);
			if (*endp || val < 0)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("%s requires a non-negative numeric value",
								def->defname)));
		}
	}
Exemplo n.º 11
0
/** dropt_get_help
  *
  * PARAMETERS:
  *     IN context    : The dropt context.
  *                     Must not be NULL.
  *     IN helpParams : The help parameters.
  *                     Pass NULL to use the default help parameters.
  *
  * RETURNS:
  *     An allocated help string for the available options.  The caller is
  *       responsible for calling free() on it when no longer needed.
  *     Returns NULL on error.
  */
dropt_char *
dropt_get_help(const dropt_context * context, const dropt_help_params * helpParams)
{
  dropt_char * helpText = NULL;
  dropt_stringstream * ss = dropt_ssopen();

  if (context == NULL) {
    DROPT_MISUSE("No dropt context specified.");
  } else if (ss != NULL) {
    const dropt_option * option;
    dropt_help_params hp;

    if (helpParams == NULL) {
      dropt_init_help_params(&hp);
    } else {
      hp = *helpParams;
    }

    for (option = context->options; is_valid_option(option); option++) {
      bool hasLongName =    option->long_name != NULL
                            && option->long_name[0] != DROPT_TEXT_LITERAL('\0');
      bool hasShortName = option->short_name != DROPT_TEXT_LITERAL('\0');

      /* The number of characters printed on the current line so far. */
      int n;

      if (option->description == NULL || (option->attr & dropt_attr_hidden)) {
        /* Undocumented option.  Ignore it and move on. */
        continue;
      } else if (hasLongName && hasShortName) {
        n = dropt_ssprintf(ss, DROPT_TEXT_LITERAL("%*s-%c, --%s"),
                           hp.indent, DROPT_TEXT_LITERAL(""),
                           option->short_name, option->long_name);
      } else if (hasLongName) {
        n = dropt_ssprintf(ss, DROPT_TEXT_LITERAL("%*s--%s"),
                           hp.indent, DROPT_TEXT_LITERAL(""),
                           option->long_name);
      } else if (hasShortName) {
        n = dropt_ssprintf(ss, DROPT_TEXT_LITERAL("%*s-%c"),
                           hp.indent, DROPT_TEXT_LITERAL(""),
                           option->short_name);
      } else {
        /* Comment text.  Don't bother with indentation. */
        assert(option->description != NULL);
        dropt_ssprintf(ss, DROPT_TEXT_LITERAL("%s\n"), option->description);
        goto next;
      }

      if (n < 0) {
        n = 0;
      }

      if (option->arg_description != NULL) {
        int m = dropt_ssprintf(ss,
                               (option->attr & dropt_attr_optional_val)
                               ? DROPT_TEXT_LITERAL("[=%s]")
                               : DROPT_TEXT_LITERAL("=%s"),
                               option->arg_description);
        if (m > 0) {
          n += m;
        }
      }

      /* Check for equality to make sure that there's at least one
       * space between the option name and its description.
       */
      if ((unsigned int) n >= hp.description_start_column) {
        dropt_ssprintf(ss, DROPT_TEXT_LITERAL("\n"));
        n = 0;
      }

      {
        const dropt_char * line = option->description;
        while (line != NULL) {
          int lineLen;
          const dropt_char * nextLine;
          const dropt_char * newline = dropt_strchr(line, DROPT_TEXT_LITERAL('\n'));

          if (newline == NULL) {
            lineLen = dropt_strlen(line);
            nextLine = NULL;
          } else {
            lineLen = newline - line;
            nextLine = newline + 1;
          }

          dropt_ssprintf(ss, DROPT_TEXT_LITERAL("%*s%.*s\n"),
                         hp.description_start_column - n, DROPT_TEXT_LITERAL(""),
                         lineLen, line);
          n = 0;

          line = nextLine;
        }
      }

next:
      if (hp.blank_lines_between_options) {
        dropt_ssprintf(ss, DROPT_TEXT_LITERAL("\n"));
      }
    }
    helpText = dropt_ssfinalize(ss);
  }

  return helpText;
}