diff options
-rw-r--r-- | src/opthelp.c | 24 |
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[] = |