popt/popt-1.12-20070815cvs.patch
2007-08-23 21:21:22 +00:00

416 lines
13 KiB
Diff

Patch by Robert Scheck <robert@fedoraproject.org> for popt 1.12, which backports
the following changes as (hopefully) bugfixes for several popt bugreports in Red
Hat Bugzilla (#102254, #135428 and #178413). From the CHANGES file:
- jbj: refactor column cursor to a structure, carry maxcols as well.
- jbj: use TIOCGWINSZ to determine --help column wrapping.
- jbj: help formatting for POPT_ARG_MAINCALL.
- jbj: remove N_(...) markings from popt.h, markers in popthelp.c instead.
- jbj: hotwire POPT_AUTOHELP/POPT_AUTOALIAS lookup in popt i18n domain.
--- popt-1.12/popt.h 2007-05-25 19:36:23.000000000 +0200
+++ popt-1.13/popt.h 2007-08-14 16:42:33.000000000 +0200
@@ -157,10 +157,6 @@
*/
/*@{*/
-#if !defined(N_)
-#define N_(foo) foo
-#endif
-
/**
* Empty table marker to enable displaying popt alias/exec options.
*/
@@ -169,7 +165,7 @@
extern struct poptOption poptAliasOptions[];
/*@=exportvar@*/
#define POPT_AUTOALIAS { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptAliasOptions, \
- 0, N_("Options implemented via popt alias/exec:"), NULL },
+ 0, "Options implemented via popt alias/exec:", NULL },
/**
* Auto help table options.
@@ -185,7 +181,7 @@
/*@=exportvar@*/
#define POPT_AUTOHELP { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptions, \
- 0, N_("Help options:"), NULL },
+ 0, "Help options:", NULL },
#define POPT_TABLEEND { NULL, '\0', 0, NULL, 0, NULL, NULL }
/*@}*/
--- popt-1.12/popthelp.c 2007-06-14 15:31:10.000000000 +0200
+++ popt-1.13/popthelp.c 2007-08-15 20:58:05.000000000 +0200
@@ -10,6 +10,11 @@
#include "system.h"
+#define POPT_USE_TIOCGWINSZ
+#ifdef POPT_USE_TIOCGWINSZ
+#include <sys/ioctl.h>
+#endif
+
#define POPT_WCHAR_HACK
#ifdef POPT_WCHAR_HACK
#include <wchar.h> /* for mbsrtowcs */
@@ -19,8 +24,6 @@
/*@access poptContext@*/
-#define _POPTHELP_MAXLINE ((size_t)79)
-
/**
* Display arguments.
* @param con context
@@ -89,6 +92,33 @@
struct poptOption * poptHelpOptionsI18N = poptHelpOptions2;
/*@=castfcnptr@*/
+#define _POPTHELP_MAXLINE ((size_t)79)
+
+typedef struct columns_s {
+ size_t cur;
+ size_t max;
+} * columns_t;
+
+/**
+ * Return no. of columns in output window.
+ * @param fp FILE
+ * @return no. of columns
+ */
+static size_t maxColumnWidth(FILE *fp)
+ /*@*/
+{
+ size_t maxcols = _POPTHELP_MAXLINE;
+#if defined(TIOCGWINSZ)
+ struct winsize ws;
+ int fdno = fileno(fp ? fp : stdout);
+
+ if (fdno >= 0 && !ioctl(fdno, TIOCGWINSZ, &ws)
+ && ws.ws_col > maxcols && ws.ws_col < 256)
+ maxcols = ws.ws_col - 1;
+#endif
+ return maxcols;
+}
+
/**
* @param table option(s)
*/
@@ -119,10 +149,20 @@
{
if (!(opt->argInfo & POPT_ARG_MASK)) return NULL;
- if (opt == (poptHelpOptions + 1) || opt == (poptHelpOptions + 2))
- if (opt->argDescrip) return POPT_(opt->argDescrip);
+ if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_MAINCALL)
+ return opt->argDescrip;
- if (opt->argDescrip) return D_(translation_domain, opt->argDescrip);
+ if (opt->argDescrip) {
+ /* Some strings need popt library, not application, i18n domain. */
+ if (opt == (poptHelpOptions + 1)
+ || opt == (poptHelpOptions + 2)
+ || !strcmp(opt->argDescrip,N_("Help options:"))
+ || !strcmp(opt->argDescrip,N_("Options implemented via popt alias/exec:")))
+ return POPT_(opt->argDescrip);
+
+ /* Use the application i18n domain. */
+ return D_(translation_domain, opt->argDescrip);
+ }
switch (opt->argInfo & POPT_ARG_MASK) {
case POPT_ARG_NONE: return POPT_("NONE");
@@ -136,6 +176,7 @@
case POPT_ARG_STRING: return POPT_("STRING");
case POPT_ARG_FLOAT: return POPT_("FLOAT");
case POPT_ARG_DOUBLE: return POPT_("DOUBLE");
+ case POPT_ARG_MAINCALL: return NULL;
default: return POPT_("ARG");
}
}
@@ -185,6 +226,9 @@
{ double aDouble = *((double *)opt->arg);
le += sprintf(le, "%g", aDouble);
} break;
+ case POPT_ARG_MAINCALL:
+ le += sprintf(le, "%p", opt->arg);
+ break;
case POPT_ARG_STRING:
{ const char * s = *(const char **)opt->arg;
if (s == NULL) {
@@ -215,18 +259,19 @@
/**
* Display help text for an option.
* @param fp output file handle
- * @param maxLeftCol largest argument display width
+ * @param columns output display width control
* @param opt option(s)
* @param translation_domain translation domain
*/
-static void singleOptionHelp(FILE * fp, size_t maxLeftCol,
+static void singleOptionHelp(FILE * fp, columns_t columns,
const struct poptOption * opt,
/*@null@*/ const char * translation_domain)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
{
+ size_t maxLeftCol = columns->cur;
size_t indentLength = maxLeftCol + 5;
- size_t lineLength = _POPTHELP_MAXLINE - indentLength;
+ size_t lineLength = columns->max - indentLength;
const char * help = D_(translation_domain, opt->descrip);
const char * argDescrip = getArgDescrip(opt, translation_domain);
size_t helpLength;
@@ -253,7 +298,8 @@
sprintf(left, "-%c", opt->shortName);
else if (opt->longName)
sprintf(left, "%s%s",
- ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"),
+ ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_MAINCALL ? "" :
+ ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--")),
opt->longName);
if (!*left) goto out;
@@ -335,7 +381,8 @@
} else {
size_t lelen;
- *le++ = '=';
+ *le++ = ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_MAINCALL)
+ ? ' ' : '=';
strcpy(le, argDescrip);
lelen = strlen(le);
le += lelen;
@@ -475,7 +522,8 @@
* @param translation_domain translation domain
*/
static void itemHelp(FILE * fp,
- /*@null@*/ poptItem items, int nitems, size_t left,
+ /*@null@*/ poptItem items, int nitems,
+ columns_t columns,
/*@null@*/ const char * translation_domain)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
@@ -489,7 +537,7 @@
opt = &item->option;
if ((opt->longName || opt->shortName) &&
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
- singleOptionHelp(fp, left, opt, translation_domain);
+ singleOptionHelp(fp, columns, opt, translation_domain);
}
}
@@ -498,11 +546,12 @@
* @param con context
* @param fp output file handle
* @param table option(s)
- * @param left largest argument display width
+ * @param columns output display width control
* @param translation_domain translation domain
*/
static void singleTableHelp(poptContext con, FILE * fp,
- /*@null@*/ const struct poptOption * table, size_t left,
+ /*@null@*/ const struct poptOption * table,
+ columns_t columns,
/*@null@*/ const char * translation_domain)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
@@ -511,8 +560,8 @@
const char *sub_transdom;
if (table == poptAliasOptions) {
- itemHelp(fp, con->aliases, con->numAliases, left, NULL);
- itemHelp(fp, con->execs, con->numExecs, left, NULL);
+ itemHelp(fp, con->aliases, con->numAliases, columns, NULL);
+ itemHelp(fp, con->execs, con->numExecs, columns, NULL);
return;
}
@@ -520,7 +569,7 @@
for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) {
if ((opt->longName || opt->shortName) &&
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
- singleOptionHelp(fp, left, opt, translation_domain);
+ singleOptionHelp(fp, columns, opt, translation_domain);
}
if (table != NULL)
@@ -534,7 +583,7 @@
if (opt->descrip)
POPT_fprintf(fp, "\n%s\n", D_(sub_transdom, opt->descrip));
- singleTableHelp(con, fp, opt->arg, left, sub_transdom);
+ singleTableHelp(con, fp, opt->arg, columns, sub_transdom);
}
}
@@ -567,7 +616,7 @@
void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags)
{
- size_t leftColWidth;
+ columns_t columns = memset(alloca(sizeof(*columns)), 0, sizeof(*columns));
(void) showHelpIntro(con, fp);
if (con->otherHelp)
@@ -575,18 +624,19 @@
else
fprintf(fp, " %s\n", POPT_("[OPTION...]"));
- leftColWidth = maxArgWidth(con->options, NULL);
- singleTableHelp(con, fp, con->options, leftColWidth, NULL);
+ columns->cur = maxArgWidth(con->options, NULL);
+ columns->max = maxColumnWidth(fp);
+ singleTableHelp(con, fp, con->options, columns, NULL);
}
/**
* Display usage text for an option.
* @param fp output file handle
- * @param cursor current display position
+ * @param columns output display width control
* @param opt option(s)
* @param translation_domain translation domain
*/
-static size_t singleOptionUsage(FILE * fp, size_t cursor,
+static size_t singleOptionUsage(FILE * fp, columns_t columns,
const struct poptOption * opt,
/*@null@*/ const char *translation_domain)
/*@globals fileSystem @*/
@@ -615,7 +665,7 @@
bingo++;
}
- if (!bingo) return cursor;
+ if (!bingo) return columns->cur;
#ifdef POPT_WCHAR_HACK
/* XXX Calculate no. of display characters. */
@@ -636,9 +686,9 @@
len += sizeof("=")-1 + strlen(argDescrip);
#endif
- if ((cursor + len) > _POPTHELP_MAXLINE) {
+ if ((columns->cur + len) > columns->max) {
fprintf(fp, "\n ");
- cursor = (size_t)7;
+ columns->cur = (size_t)7;
}
if (opt->longName && opt->shortName) {
@@ -655,18 +705,18 @@
(argDescrip ? argDescrip : ""));
}
- return cursor + len + 1;
+ return columns->cur + len + 1;
}
/**
* Display popt alias and exec usage.
* @param fp output file handle
- * @param cursor current display position
+ * @param columns output display width control
* @param item alias/exec array
* @param nitems no. of ara/exec entries
* @param translation_domain translation domain
*/
-static size_t itemUsage(FILE * fp, size_t cursor,
+static size_t itemUsage(FILE * fp, columns_t columns,
/*@null@*/ poptItem item, int nitems,
/*@null@*/ const char * translation_domain)
/*@globals fileSystem @*/
@@ -683,12 +733,12 @@
translation_domain = (const char *)opt->arg;
} else if ((opt->longName || opt->shortName) &&
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
- cursor = singleOptionUsage(fp, cursor, opt, translation_domain);
+ columns->cur = singleOptionUsage(fp, columns, opt, translation_domain);
}
}
/*@=branchstate@*/
- return cursor;
+ return columns->cur;
}
/**
@@ -704,13 +754,13 @@
* Display usage text for a table of options.
* @param con context
* @param fp output file handle
- * @param cursor current display position
+ * @param columns output display width control
* @param opt option(s)
* @param translation_domain translation domain
* @param done tables already processed
* @return
*/
-static size_t singleTableUsage(poptContext con, FILE * fp, size_t cursor,
+static size_t singleTableUsage(poptContext con, FILE * fp, columns_t columns,
/*@null@*/ const struct poptOption * opt,
/*@null@*/ const char * translation_domain,
/*@null@*/ poptDone done)
@@ -741,16 +791,16 @@
done->opts[done->nopts++] = (const void *) opt->arg;
/*@=boundswrite@*/
}
- cursor = singleTableUsage(con, fp, cursor, opt->arg,
+ columns->cur = singleTableUsage(con, fp, columns, opt->arg,
translation_domain, done);
} else if ((opt->longName || opt->shortName) &&
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
- cursor = singleOptionUsage(fp, cursor, opt, translation_domain);
+ columns->cur = singleOptionUsage(fp, columns, opt, translation_domain);
}
}
/*@=branchstate@*/
- return cursor;
+ return columns->cur;
}
/**
@@ -798,30 +848,31 @@
void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags)
{
+ columns_t columns = memset(alloca(sizeof(*columns)), 0, sizeof(*columns));
struct poptDone_s done_buf;
poptDone done = &done_buf;
- size_t cursor;
memset(done, 0, sizeof(*done));
done->nopts = 0;
done->maxopts = 64;
- cursor = done->maxopts * sizeof(*done->opts);
+ columns->cur = done->maxopts * sizeof(*done->opts);
+ columns->max = maxColumnWidth(fp);
/*@-boundswrite@*/
- done->opts = calloc(1, cursor);
+ done->opts = calloc(1, columns->cur);
/*@-keeptrans@*/
done->opts[done->nopts++] = (const void *) con->options;
/*@=keeptrans@*/
/*@=boundswrite@*/
- cursor = showHelpIntro(con, fp);
- cursor += showShortOptions(con->options, fp, NULL);
- cursor = singleTableUsage(con, fp, cursor, con->options, NULL, done);
- cursor = itemUsage(fp, cursor, con->aliases, con->numAliases, NULL);
- cursor = itemUsage(fp, cursor, con->execs, con->numExecs, NULL);
+ columns->cur = showHelpIntro(con, fp);
+ columns->cur += showShortOptions(con->options, fp, NULL);
+ columns->cur = singleTableUsage(con, fp, columns, con->options, NULL, done);
+ columns->cur = itemUsage(fp, columns, con->aliases, con->numAliases, NULL);
+ columns->cur = itemUsage(fp, columns, con->execs, con->numExecs, NULL);
if (con->otherHelp) {
- cursor += strlen(con->otherHelp) + 1;
- if (cursor > _POPTHELP_MAXLINE) fprintf(fp, "\n ");
+ columns->cur += strlen(con->otherHelp) + 1;
+ if (columns->cur > columns->max) fprintf(fp, "\n ");
fprintf(fp, " %s", con->otherHelp);
}