Upgrade from popt 1.2 to a cut-down 1.5
[rsync/rsync.git] / popt / popthelp.c
similarity index 61%
rename from popt-1.2/popthelp.c
rename to popt/popthelp.c
index 021e044..c36ecea 100644 (file)
@@ -1,58 +1,73 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+
 /* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
    file accompanying popt source distributions, available from 
    ftp://ftp.redhat.com/pub/code/popt */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "popt.h"
+#include "system.h"
 #include "poptint.h"
 
-static void displayArgs(poptContext con, enum poptCallbackReason foo, 
-                       struct poptOption * key, 
-                       const char * arg, void * data) {
+static void displayArgs(poptContext con,
+               /*@unused@*/ enum poptCallbackReason foo,
+               struct poptOption * key, 
+               /*@unused@*/ const char * arg, /*@unused@*/ void * data) {
     if (key->shortName== '?')
-       poptPrintHelp(con, stderr, 0);
+       poptPrintHelp(con, stdout, 0);
     else
-       poptPrintUsage(con, stderr, 0);
+       poptPrintUsage(con, stdout, 0);
     exit(0);
 }
 
 struct poptOption poptHelpOptions[] = {
-    { NULL, '\0', POPT_ARG_CALLBACK, &displayArgs, '\0', NULL },
-    { "help", '?', 0, NULL, '?', N_("Show this help message") },
-    { "usage", '\0', 0, NULL, 'u', N_("Display brief usage message") },
-    { NULL, '\0', 0, NULL, 0 }
+    { NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL, NULL },
+    { "help", '?', 0, NULL, '?', N_("Show this help message"), NULL },
+    { "usage", '\0', 0, NULL, 'u', N_("Display brief usage message"), NULL },
+    { NULL, '\0', 0, NULL, 0, NULL, NULL }
 } ;
 
-static const char * getArgDescrip(const struct poptOption * opt) {
+
+/*@observer@*/ /*@null@*/ static const char *const
+getTableTranslationDomain(const struct poptOption *table)
+{
+  const struct poptOption *opt;
+
+  for(opt = table;
+      opt->longName || opt->shortName || opt->arg;
+      opt++) {
+    if(opt->argInfo == POPT_ARG_INTL_DOMAIN)
+      return opt->arg;
+  }
+
+  return NULL;
+}
+
+/*@observer@*/ /*@null@*/ static const char *const
+getArgDescrip(const struct poptOption * opt, const char *translation_domain)
+{
     if (!(opt->argInfo & POPT_ARG_MASK)) return NULL;
 
     if (opt == (poptHelpOptions + 1) || opt == (poptHelpOptions + 2))
        if (opt->argDescrip) return POPT_(opt->argDescrip);
 
-    if (opt->argDescrip) return _(opt->argDescrip);
+    if (opt->argDescrip) return D_(translation_domain, opt->argDescrip);
     return POPT_("ARG");
 }
 
 static void singleOptionHelp(FILE * f, int maxLeftCol, 
-                            const struct poptOption * opt) {
+                            const struct poptOption * opt,
+                            const char *translation_domain) {
     int indentLength = maxLeftCol + 5;
     int lineLength = 79 - indentLength;
-    const char * help = _(opt->descrip);
+    const char * help = D_(translation_domain, opt->descrip);
     int helpLength;
     const char * ch;
     char format[10];
-    char * left = alloca(maxLeftCol + 1);
-    const char * argDescrip = getArgDescrip(opt);
+    char * left;
+    const char * argDescrip = getArgDescrip(opt, translation_domain);
 
+    left = malloc(maxLeftCol + 1);
     *left = '\0';
+
     if (opt->longName && opt->shortName)
        sprintf(left, "-%c, --%s", opt->shortName, opt->longName);
     else if (opt->shortName) 
@@ -69,7 +84,7 @@ static void singleOptionHelp(FILE * f, int maxLeftCol,
        fprintf(f,"  %-*s   ", maxLeftCol, left);
     else {
        fprintf(f,"  %s\n", left); 
-       return;
+       goto out;
     }
 
     helpLength = strlen(help);
@@ -88,16 +103,20 @@ static void singleOptionHelp(FILE * f, int maxLeftCol,
     }
 
     if (helpLength) fprintf(f, "%s\n", help);
+
+out:
+    free(left);
 }
 
-static int maxArgWidth(const struct poptOption * opt) {
+static int maxArgWidth(const struct poptOption * opt,
+                      const char * translation_domain) {
     int max = 0;
     int this;
     const char * s;
     
     while (opt->longName || opt->shortName || opt->arg) {
        if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
-           this = maxArgWidth(opt->arg);
+           this = maxArgWidth(opt->arg, translation_domain);
            if (this > max) max = this;
        } else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
            this = opt->shortName ? 2 : 0;
@@ -106,7 +125,7 @@ static int maxArgWidth(const struct poptOption * opt) {
                this += strlen(opt->longName) + 2;
            }
 
-           s = getArgDescrip(opt);
+           s = getArgDescrip(opt, translation_domain);
            if (s)
                this += strlen(s) + 1;
            if (this > max) max = this;
@@ -119,23 +138,30 @@ static int maxArgWidth(const struct poptOption * opt) {
 }
 
 static void singleTableHelp(FILE * f, const struct poptOption * table, 
-                           int left) {
+                           int left,
+                           const char *translation_domain) {
     const struct poptOption * opt;
+    const char *sub_transdom;
 
     opt = table;
     while (opt->longName || opt->shortName || opt->arg) {
        if ((opt->longName || opt->shortName) && 
            !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
-           singleOptionHelp(f, left, opt);
+           singleOptionHelp(f, left, opt, translation_domain);
        opt++;
     }
 
     opt = table;
     while (opt->longName || opt->shortName || opt->arg) {
        if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
+           sub_transdom = getTableTranslationDomain(opt->arg);
+           if(!sub_transdom)
+               sub_transdom = translation_domain;
+           
            if (opt->descrip)
-               fprintf(f, "\n%s\n", _(opt->descrip));
-           singleTableHelp(f, opt->arg, left);
+               fprintf(f, "\n%s\n", D_(sub_transdom, opt->descrip));
+
+           singleTableHelp(f, opt->arg, left, sub_transdom);
        }
        opt++;
     }
@@ -143,7 +169,7 @@ static void singleTableHelp(FILE * f, const struct poptOption * table,
 
 static int showHelpIntro(poptContext con, FILE * f) {
     int len = 6;
-    char * fn;
+    const char * fn;
 
     fprintf(f, POPT_("Usage:"));
     if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) {
@@ -156,7 +182,7 @@ static int showHelpIntro(poptContext con, FILE * f) {
     return len;
 }
 
-void poptPrintHelp(poptContext con, FILE * f, int flags) {
+void poptPrintHelp(poptContext con, FILE * f, /*@unused@*/ int flags) {
     int leftColWidth;
 
     showHelpIntro(con, f);
@@ -165,16 +191,17 @@ void poptPrintHelp(poptContext con, FILE * f, int flags) {
     else
        fprintf(f, " %s\n", POPT_("[OPTION...]"));
 
-    leftColWidth = maxArgWidth(con->options);
-    singleTableHelp(f, con->options, leftColWidth);
+    leftColWidth = maxArgWidth(con->options, NULL);
+    singleTableHelp(f, con->options, leftColWidth, NULL);
 }
 
 static int singleOptionUsage(FILE * f, int cursor, 
-                             const struct poptOption * opt) {
+                            const struct poptOption * opt,
+                            const char *translation_domain) {
     int len = 3;
-    char shortStr[2];
+    char shortStr[2] = { '\0', '\0' };
     const char * item = shortStr;
-    const char * argDescrip = getArgDescrip(opt);
+    const char * argDescrip = getArgDescrip(opt, translation_domain);
 
     if (opt->shortName) {
        if (!(opt->argInfo & POPT_ARG_MASK)) 
@@ -204,16 +231,21 @@ static int singleOptionUsage(FILE * f, int cursor,
     return cursor + len + 1;
 }
 
-int singleTableUsage(FILE * f, int cursor, const struct poptOption * table) {
+static int singleTableUsage(FILE * f, int cursor, const struct poptOption * table,
+                    const char *translation_domain) {
     const struct poptOption * opt;
     
     opt = table;
     while (opt->longName || opt->shortName || opt->arg) {
-       if ((opt->longName || opt->shortName) && 
-           !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
-           cursor = singleOptionUsage(f, cursor, opt);
+        if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN)
+           translation_domain = (const char *)opt->arg;
        else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) 
-           cursor = singleTableUsage(f, cursor, opt->arg);
+           cursor = singleTableUsage(f, cursor, opt->arg,
+                                     translation_domain);
+       else if ((opt->longName || opt->shortName) && 
+                !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
+         cursor = singleOptionUsage(f, cursor, opt, translation_domain);
+
        opt++;
     }
 
@@ -225,9 +257,10 @@ static int showShortOptions(const struct poptOption * opt, FILE * f,
     char s[300];               /* this is larger then the ascii set, so
                                   it should do just fine */
 
-    if (!str) {
+    s[0] = '\0';
+    if (str == NULL) {
+       memset(s, 0, sizeof(s));
        str = s;
-       memset(str, 0, sizeof(str));
     }
 
     while (opt->longName || opt->shortName || opt->arg) {
@@ -246,12 +279,12 @@ static int showShortOptions(const struct poptOption * opt, FILE * f,
     return strlen(s) + 4;
 }
 
-void poptPrintUsage(poptContext con, FILE * f, int flags) {
+void poptPrintUsage(poptContext con, FILE * f, /*@unused@*/ int flags) {
     int cursor;
 
     cursor = showHelpIntro(con, f);
     cursor += showShortOptions(con->options, f, NULL);
-    singleTableUsage(f, cursor, con->options);
+    singleTableUsage(f, cursor, con->options, NULL);
 
     if (con->otherHelp) {
        cursor += strlen(con->otherHelp) + 1;
@@ -263,6 +296,6 @@ void poptPrintUsage(poptContext con, FILE * f, int flags) {
 }
 
 void poptSetOtherOptionHelp(poptContext con, const char * text) {
-    if (con->otherHelp) free(con->otherHelp);
-    con->otherHelp = strdup(text);
+    if (con->otherHelp) xfree(con->otherHelp);
+    con->otherHelp = xstrdup(text);
 }