aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/opthelp.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/src/opthelp.c b/src/opthelp.c
index 3c845b9..58deeed 100644
--- a/src/opthelp.c
+++ b/src/opthelp.c
@@ -233,7 +233,8 @@ grecs_print_usage(struct grecs_proginfo *pinfo)
{
unsigned i;
unsigned n;
- char buf[RMARGIN+1];
+ char *buf;
+ size_t bufsize;
unsigned nidx;
struct grecs_opthelp **optidx;
struct grecs_opthelp *opthelp = pinfo->opthelp;
@@ -248,13 +249,12 @@ grecs_print_usage(struct grecs_proginfo *pinfo)
#define ADDC(c) \
do { if (n == RMARGIN) FLUSH; buf[n++] = c; } while (0)
- optidx = calloc(optcount, sizeof(optidx[0]));
- if (!optidx) {
- fprintf(stderr, "not enough memory");
- abort();
- }
+ optidx = grecs_calloc(optcount, sizeof(optidx[0]));
- n = snprintf(buf, sizeof buf, "%s %s ", _("Usage:"), pinfo->progname);
+ bufsize = RMARGIN + 1;
+ buf = grecs_malloc(bufsize);
+
+ n = snprintf(buf, bufsize, "%s %s ", _("Usage:"), pinfo->progname);
/* Print a list of short options without arguments. */
for (i = nidx = 0; i < optcount; i++)
@@ -338,8 +338,15 @@ grecs_print_usage(struct grecs_proginfo *pinfo)
len = 3 + strlen(longopt)
+ (opt->arg ? 1 + strlen(opt->arg)
+ (opt->is_optional ? 2 : 0) : 0);
- if (n + len > RMARGIN)
+ if (n + len > RMARGIN) {
FLUSH;
+ /* Make sure we have enough buffer space if
+ the string cannot be split */
+ if (n + len > bufsize) {
+ bufsize = n + len;
+ buf = grecs_realloc(buf, bufsize);
+ }
+ }
buf[n++] = ' ';
buf[n++] = '[';
strcpy(&buf[n], longopt);
@@ -362,6 +369,7 @@ grecs_print_usage(struct grecs_proginfo *pinfo)
#endif
FLUSH;
free(optidx);
+ free(buf);
}
const char version_etc_copyright[] =

Return to:

Send suggestions and report system problems to the System administrator.