s4: import lorikeet-heimdal-200810271034
[sfrench/samba-autobuild/.git] / source4 / heimdal / lib / roken / getarg.c
index 840febbf2118207c34e073e4dc98e5cd0c3eeb03..3884fa83d65270a4d634fe187055b295f718da04 100644 (file)
@@ -1,51 +1,56 @@
 /*
- * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden). 
- * All rights reserved. 
+ * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions 
- * are met: 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
  *
- * 1. Redistributions of source code must retain the above copyright 
- *    notice, this list of conditions and the following disclaimer. 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
  *
- * 2. Redistributions in binary form must reproduce the above copyright 
- *    notice, this list of conditions and the following disclaimer in the 
- *    documentation and/or other materials provided with the distribution. 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
  *
- * 3. Neither the name of the Institute nor the names of its contributors 
- *    may be used to endorse or promote products derived from this software 
- *    without specific prior written permission. 
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
- * SUCH DAMAGE. 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
-RCSID("$Id: getarg.c 21005 2007-06-08 01:54:35Z lha $");
+RCSID("$Id$");
 #endif
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <roken.h>
+#include "roken.h"
 #include "getarg.h"
 
 #define ISFLAG(X) ((X).type == arg_flag || (X).type == arg_negative_flag)
 
 static size_t
-print_arg (char *string, size_t len, int mdoc, int longp, struct getargs *arg)
+print_arg (char *string,
+          size_t len,
+          int mdoc,
+          int longp,
+          struct getargs *arg,
+          char *(i18n)(const char *))
 {
     const char *s;
 
@@ -66,7 +71,7 @@ print_arg (char *string, size_t len, int mdoc, int longp, struct getargs *arg)
     }
 
     if (arg->arg_help)
-       s = arg->arg_help;
+       s = (*i18n)(arg->arg_help);
     else if (arg->type == arg_integer || arg->type == arg_counter)
        s = "integer";
     else if (arg->type == arg_string)
@@ -86,7 +91,8 @@ static void
 mandoc_template(struct getargs *args,
                size_t num_args,
                const char *progname,
-               const char *extra_string)
+               const char *extra_string,
+               char *(i18n)(const char *))
 {
     int i;
     char timestr[64], cmd[64];
@@ -106,7 +112,7 @@ mandoc_template(struct getargs *args,
     if(p) p++; else p = progname;
     strlcpy(cmd, p, sizeof(cmd));
     strupr(cmd);
-       
+
     printf(".Dt %s SECTION\n", cmd);
     printf(".Os OPERATING_SYSTEM\n");
     printf(".Sh NAME\n");
@@ -118,27 +124,27 @@ mandoc_template(struct getargs *args,
     for(i = 0; i < num_args; i++){
        /* we seem to hit a limit on number of arguments if doing
            short and long flags with arguments -- split on two lines */
-       if(ISFLAG(args[i]) || 
+       if(ISFLAG(args[i]) ||
           args[i].short_name == 0 || args[i].long_name == NULL) {
            printf(".Op ");
 
            if(args[i].short_name) {
-               print_arg(buf, sizeof(buf), 1, 0, args + i);
+               print_arg(buf, sizeof(buf), 1, 0, args + i, i18n);
                printf("Fl %c%s", args[i].short_name, buf);
                if(args[i].long_name)
                    printf(" | ");
            }
            if(args[i].long_name) {
-               print_arg(buf, sizeof(buf), 1, 1, args + i);
+               print_arg(buf, sizeof(buf), 1, 1, args + i, i18n);
                printf("Fl -%s%s%s",
                       args[i].type == arg_negative_flag ? "no-" : "",
                       args[i].long_name, buf);
            }
            printf("\n");
        } else {
-           print_arg(buf, sizeof(buf), 1, 0, args + i);
+           print_arg(buf, sizeof(buf), 1, 0, args + i, i18n);
            printf(".Oo Fl %c%s \\*(Ba Xo\n", args[i].short_name, buf);
-           print_arg(buf, sizeof(buf), 1, 1, args + i);
+           print_arg(buf, sizeof(buf), 1, 1, args + i, i18n);
            printf(".Fl -%s%s\n.Xc\n.Oc\n", args[i].long_name, buf);
        }
     /*
@@ -155,7 +161,7 @@ mandoc_template(struct getargs *args,
        printf(".It Xo\n");
        if(args[i].short_name){
            printf(".Fl %c", args[i].short_name);
-           print_arg(buf, sizeof(buf), 1, 0, args + i);
+           print_arg(buf, sizeof(buf), 1, 0, args + i, i18n);
            printf("%s", buf);
            if(args[i].long_name)
                printf(" ,");
@@ -165,7 +171,7 @@ mandoc_template(struct getargs *args,
            printf(".Fl -%s%s",
                   args[i].type == arg_negative_flag ? "no-" : "",
                   args[i].long_name);
-           print_arg(buf, sizeof(buf), 1, 1, args + i);
+           print_arg(buf, sizeof(buf), 1, 1, args + i, i18n);
            printf("%s\n", buf);
        }
        printf(".Xc\n");
@@ -198,11 +204,29 @@ check_column(FILE *f, int col, int len, int columns)
     return col;
 }
 
+static char *
+builtin_i18n(const char *str)
+{
+    return rk_UNCONST(str);
+}
+
 void ROKEN_LIB_FUNCTION
 arg_printusage (struct getargs *args,
                size_t num_args,
                const char *progname,
                const char *extra_string)
+{
+    return arg_printusage_i18n(args, num_args, "Usage",
+                              progname, extra_string, builtin_i18n);
+}
+
+void ROKEN_LIB_FUNCTION
+arg_printusage_i18n (struct getargs *args,
+                    size_t num_args,
+                    const char *usage,
+                    const char *progname,
+                    const char *extra_string,
+                    char *(i18n)(const char *))
 {
     int i;
     size_t max_len = 0;
@@ -213,8 +237,11 @@ arg_printusage (struct getargs *args,
     if (progname == NULL)
        progname = getprogname();
 
+    if (i18n == NULL)
+       i18n = builtin_i18n;
+
     if(getenv("GETARGMANDOC")){
-       mandoc_template(args, num_args, progname, extra_string);
+       mandoc_template(args, num_args, progname, extra_string, i18n);
        return;
     }
     if(get_window_size(2, &ws) == 0)
@@ -222,7 +249,7 @@ arg_printusage (struct getargs *args,
     else
        columns = 80;
     col = 0;
-    col += fprintf (stderr, "Usage: %s", progname);
+    col += fprintf (stderr, "%s: %s", usage, progname);
     buf[0] = '\0';
     for (i = 0; i < num_args; ++i) {
        if(args[i].short_name && ISFLAG(args[i])) {
@@ -253,8 +280,8 @@ arg_printusage (struct getargs *args,
            }
            strlcat(buf, args[i].long_name, sizeof(buf));
            len += strlen(args[i].long_name);
-           len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf), 
-                            0, 1, &args[i]);
+           len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf),
+                            0, 1, &args[i], i18n);
            strlcat(buf, "]", sizeof(buf));
            if(args[i].type == arg_strings)
                strlcat(buf, "...", sizeof(buf));
@@ -264,8 +291,8 @@ arg_printusage (struct getargs *args,
        if (args[i].short_name && !ISFLAG(args[i])) {
            snprintf(buf, sizeof(buf), "[-%c", args[i].short_name);
            len += 2;
-           len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf), 
-                            0, 0, &args[i]);
+           len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf),
+                            0, 0, &args[i], i18n);
            strlcat(buf, "]", sizeof(buf));
            if(args[i].type == arg_strings)
                strlcat(buf, "...", sizeof(buf));
@@ -277,7 +304,7 @@ arg_printusage (struct getargs *args,
        max_len = max(max_len, len);
     }
     if (extra_string) {
-       col = check_column(stderr, col, strlen(extra_string) + 1, columns);
+       check_column(stderr, col, strlen(extra_string) + 1, columns);
        fprintf (stderr, " %s\n", extra_string);
     } else
        fprintf (stderr, "\n");
@@ -287,7 +314,7 @@ arg_printusage (struct getargs *args,
 
            if (args[i].short_name) {
                count += fprintf (stderr, "-%c", args[i].short_name);
-               print_arg (buf, sizeof(buf), 0, 0, &args[i]);
+               print_arg (buf, sizeof(buf), 0, 0, &args[i], i18n);
                count += fprintf(stderr, "%s", buf);
            }
            if (args[i].short_name && args[i].long_name)
@@ -297,12 +324,12 @@ arg_printusage (struct getargs *args,
                if (args[i].type == arg_negative_flag)
                    count += fprintf (stderr, "no-");
                count += fprintf (stderr, "%s", args[i].long_name);
-               print_arg (buf, sizeof(buf), 0, 1, &args[i]);
+               print_arg (buf, sizeof(buf), 0, 1, &args[i], i18n);
                count += fprintf(stderr, "%s", buf);
            }
            while(count++ <= max_len)
                putc (' ', stderr);
-           fprintf (stderr, "%s\n", args[i].help);
+           fprintf (stderr, "%s\n", (*i18n)(args[i].help));
        }
     }
 }
@@ -378,7 +405,7 @@ arg_match_long(struct getargs *args, size_t num_args,
        else
            return ARG_ERR_NO_MATCH;
     }
-    
+
     if(*goptarg == '\0'
        && !ISFLAG(*current)
        && current->type != arg_collect
@@ -407,7 +434,7 @@ arg_match_long(struct getargs *args, size_t num_args,
     {
        int *flag = current->value;
        if(*goptarg == '\0' ||
-          strcmp(goptarg + 1, "yes") == 0 || 
+          strcmp(goptarg + 1, "yes") == 0 ||
           strcmp(goptarg + 1, "true") == 0){
            *flag = !negate;
            return 0;
@@ -473,7 +500,7 @@ arg_match_short (struct getargs *args, size_t num_args,
                if(args[k].type == arg_negative_flag) {
                    *(int*)args[k].value = 0;
                    break;
-               } 
+               }
                if(args[k].type == arg_counter) {
                    ++*(int *)args[k].value;
                    break;
@@ -524,7 +551,7 @@ arg_match_short (struct getargs *args, size_t num_args,
 }
 
 int ROKEN_LIB_FUNCTION
-getarg(struct getargs *args, size_t num_args, 
+getarg(struct getargs *args, size_t num_args,
        int argc, char **argv, int *goptind)
 {
     int i;
@@ -546,7 +573,7 @@ getarg(struct getargs *args, size_t num_args,
                i++;
                break;
            }
-           ret = arg_match_long (args, num_args, argv[i] + 2, 
+           ret = arg_match_long (args, num_args, argv[i] + 2,
                                  argc, argv, &i);
        } else {
            ret = arg_match_short (args, num_args, argv[i],
@@ -585,9 +612,9 @@ int main(int argc, char **argv)
     int goptind = 0;
     while(getarg(args, 5, argc, argv, &goptind))
        printf("Bad arg: %s\n", argv[goptind]);
-    printf("flag1 = %d\n", flag1);  
-    printf("flag2 = %d\n", flag2);  
-    printf("foo_flag = %d\n", foo_flag);  
+    printf("flag1 = %d\n", flag1);
+    printf("flag2 = %d\n", flag2);
+    printf("foo_flag = %d\n", foo_flag);
     printf("bar_int = %d\n", bar_int);
     printf("baz_flag = %s\n", baz_string);
     arg_printusage (args, 5, argv[0], "nothing here");