~ubuntu-branches/ubuntu/oneiric/gnupg2/oneiric-updates

« back to all changes in this revision

Viewing changes to jnlib/argparse.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-10-04 10:25:53 UTC
  • mfrom: (5.1.15 intrepid)
  • Revision ID: james.westby@ubuntu.com-20081004102553-fv62pp8dsitxli47
Tags: 2.0.9-3.1
* Non-maintainer upload.
* agent/gpg-agent.c: Deinit the threading library before exec'ing
  the command to run in --daemon mode. And because that still doesn't
  restore the sigprocmask, do that manually. Closes: #499569

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* [argparse.c wk 17.06.97] Argument Parser for option handling
2
 
 *      Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3
 
 *
4
 
 *  This file is part of GnuPG.
5
 
 *
6
 
 *  GnuPG is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; either version 2 of the License, or
9
 
 *  (at your option) any later version.
10
 
 *
11
 
 *  GnuPG is distributed in the hope that it will be useful,
12
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 *  GNU General Public License for more details.
15
 
 *
16
 
 *  You should have received a copy of the GNU General Public License
17
 
 *  along with this program; if not, write to the Free Software
18
 
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
2
 * Copyright (C) 1998, 1999, 2000, 2001, 2006
 
3
 *               2007, 2008  Free Software Foundation, Inc.
 
4
 *
 
5
 * This file is part of JNLIB.
 
6
 *
 
7
 * JNLIB is free software; you can redistribute it and/or modify it
 
8
 * under the terms of the GNU Lesser General Public License as
 
9
 * published by the Free Software Foundation; either version 3 of
 
10
 * the License, or (at your option) any later version.
 
11
 *
 
12
 * JNLIB is distributed in the hope that it will be useful, but
 
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
 * Lesser General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU Lesser General Public
 
18
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19
19
 */
20
20
 
21
21
#include <config.h>
28
28
#include "mischelp.h"
29
29
#include "stringhelp.h"
30
30
#include "logging.h"
 
31
#ifdef JNLIB_NEED_UTF8CONV
 
32
#include "utf8conv.h"
 
33
#endif
31
34
#include "argparse.h"
32
35
 
33
36
 
146
149
static void
147
150
initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno )
148
151
{
149
 
    if( !(arg->flags & (1<<15)) ) { /* initialize this instance */
150
 
        arg->internal.idx = 0;
151
 
        arg->internal.last = NULL;
152
 
        arg->internal.inarg = 0;
153
 
        arg->internal.stopped = 0;
154
 
        arg->internal.aliases = NULL;
155
 
        arg->internal.cur_alias = NULL;
156
 
        arg->err = 0;
157
 
        arg->flags |= 1<<15; /* mark initialized */
158
 
        if( *arg->argc < 0 )
159
 
            jnlib_log_bug("Invalid argument for ArgParse\n");
 
152
  if( !(arg->flags & (1<<15)) ) 
 
153
    { 
 
154
      /* Initialize this instance. */
 
155
      arg->internal.idx = 0;
 
156
      arg->internal.last = NULL;
 
157
      arg->internal.inarg = 0;
 
158
      arg->internal.stopped = 0;
 
159
      arg->internal.aliases = NULL;
 
160
      arg->internal.cur_alias = NULL;
 
161
      arg->err = 0;
 
162
      arg->flags |= 1<<15; /* Mark as initialized.  */
 
163
      if ( *arg->argc < 0 )
 
164
        jnlib_log_bug ("invalid argument for arg_parsee\n");
160
165
    }
161
 
 
162
 
 
163
 
    if( arg->err ) { /* last option was erroneous */
164
 
        const char *s;
165
 
 
166
 
        if( filename ) {
167
 
            if( arg->r_opt == -6 )
168
 
                s = "argument not expected\n";
169
 
            else if( arg->r_opt == -5 )
170
 
                s = "read error\n";
171
 
            else if( arg->r_opt == -4 )
172
 
                s = "keyword too long\n";
173
 
            else if( arg->r_opt == -3 )
174
 
                s = "missing argument\n";
175
 
            else if( arg->r_opt == -7 )
176
 
                s = "invalid command\n";
177
 
            else if( arg->r_opt == -10 )
178
 
                s = "invalid alias definition\n";
179
 
            else
180
 
                s = "invalid option\n";
181
 
            jnlib_log_error("%s:%u: %s\n", filename, *lineno, s);
 
166
  
 
167
  
 
168
  if (arg->err)
 
169
    {
 
170
      /* Last option was erroneous.  */
 
171
      const char *s;
 
172
      
 
173
      if (filename)
 
174
        {
 
175
          if ( arg->r_opt == -6 )
 
176
            s = _("argument not expected");
 
177
          else if ( arg->r_opt == -5 )
 
178
            s = _("read error");
 
179
          else if ( arg->r_opt == -4 )
 
180
            s = _("keyword too long");
 
181
          else if ( arg->r_opt == -3 )
 
182
            s = _("missing argument");
 
183
          else if ( arg->r_opt == -7 )
 
184
            s = _("invalid command");
 
185
          else if ( arg->r_opt == -10 )
 
186
            s = _("invalid alias definition");
 
187
          else
 
188
            s = _("invalid option");
 
189
          jnlib_log_error ("%s:%u: %s\n", filename, *lineno, s);
182
190
        }
183
 
        else {
184
 
            s = arg->internal.last? arg->internal.last:"[??]";
 
191
      else 
 
192
        {
 
193
          s = arg->internal.last? arg->internal.last:"[??]";
185
194
            
186
 
            if( arg->r_opt == -3 )
187
 
              jnlib_log_error ("Missing argument for option \"%.50s\"\n", s);
188
 
            else if( arg->r_opt == -6 )
189
 
              jnlib_log_error ("Option \"%.50s\" does not expect an argument\n",
190
 
                               s );
191
 
            else if( arg->r_opt == -7 )
192
 
              jnlib_log_error ("Invalid command \"%.50s\"\n", s);
193
 
            else if( arg->r_opt == -8 )
194
 
              jnlib_log_error ("Option \"%.50s\" is ambiguous\n", s);
195
 
            else if( arg->r_opt == -9 )
196
 
              jnlib_log_error ("Command \"%.50s\" is ambiguous\n",s );
197
 
            else
198
 
              jnlib_log_error ("Invalid option \"%.50s\"\n", s);
 
195
          if ( arg->r_opt == -3 )
 
196
            jnlib_log_error (_("missing argument for option \"%.50s\"\n"), s);
 
197
          else if ( arg->r_opt == -6 )
 
198
            jnlib_log_error (_("option \"%.50s\" does not expect an "
 
199
                               "argument\n"), s );
 
200
          else if ( arg->r_opt == -7 )
 
201
            jnlib_log_error (_("invalid command \"%.50s\"\n"), s);
 
202
          else if ( arg->r_opt == -8 )
 
203
            jnlib_log_error (_("option \"%.50s\" is ambiguous\n"), s);
 
204
          else if ( arg->r_opt == -9 )
 
205
            jnlib_log_error (_("command \"%.50s\" is ambiguous\n"),s );
 
206
          else
 
207
            jnlib_log_error (_("invalid option \"%.50s\"\n"), s);
199
208
        }
200
 
        if( arg->err != 1 )
201
 
            exit(2);
202
 
        arg->err = 0;
 
209
      if ( arg->err != 1 )
 
210
        exit (2);
 
211
      arg->err = 0;
203
212
    }
204
213
 
205
 
    /* clearout the return value union */
206
 
    arg->r.ret_str = NULL;
207
 
    arg->r.ret_long= 0;
 
214
  /* Zero out the return value union.  */
 
215
  arg->r.ret_str = NULL;
 
216
  arg->r.ret_long = 0;
208
217
}
209
218
 
210
219
 
437
446
    for(i=0; opts[i].short_opt; i++ )
438
447
        if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) )
439
448
            return i;
440
 
  #if 0
 
449
#if 0
441
450
    {
442
451
        ALIAS_DEF a;
443
452
        /* see whether it is an alias */
449
458
            }
450
459
        }
451
460
    }
452
 
  #endif
 
461
#endif
453
462
    /* not found, see whether it is an abbreviation */
454
463
    /* aliases may not be abbreviated */
455
464
    n = strlen( keyword );
698
707
static size_t
699
708
long_opt_strlen( ARGPARSE_OPTS *o )
700
709
{
701
 
    size_t n = strlen(o->long_opt);
702
 
 
703
 
    if( o->description && *o->description == '|' ) {
704
 
        const char *s;
705
 
 
706
 
        s=o->description+1;
707
 
        if( *s != '=' )
708
 
            n++;
709
 
        for(; *s && *s != '|'; s++ )
710
 
            n++;
 
710
  size_t n = strlen (o->long_opt);
 
711
 
 
712
  if ( o->description && *o->description == '|' ) 
 
713
    {
 
714
      const char *s;
 
715
#ifdef JNLIB_NEED_UTF8CONV
 
716
      int is_utf8 = is_native_utf8 ();
 
717
#endif
 
718
        
 
719
      s=o->description+1;
 
720
      if ( *s != '=' )
 
721
        n++;
 
722
      /* For a (mostly) correct length calculation we exclude
 
723
         continuation bytes (10xxxxxx) if we are on a native utf8
 
724
         terminal. */
 
725
      for (; *s && *s != '|'; s++ )
 
726
#ifdef JNLIB_NEED_UTF8CONV
 
727
        if ( is_utf8 && (*s&0xc0) != 0x80 )
 
728
#endif
 
729
          n++;
711
730
    }
712
 
    return n;
 
731
  return n;
713
732
}
714
733
 
715
734
/****************
819
838
            puts("\n(A single dash may be used instead of the double ones)");
820
839
    }
821
840
    if( (s=strusage(19)) ) {  /* bug reports to ... */
 
841
        char *s2;
 
842
 
822
843
        putchar('\n');
823
 
        fputs(s, stdout);
 
844
        s2 = strstr (s, "@EMAIL@");
 
845
        if (s2)
 
846
          {
 
847
            if (s2-s)
 
848
              fwrite (s, s2-s, 1, stdout);
 
849
            fputs (PACKAGE_BUGREPORT, stdout);
 
850
            s2 += 7;
 
851
            if (*s2)
 
852
              fputs (s2, stdout);
 
853
          }
 
854
        else
 
855
          fputs(s, stdout);
824
856
    }
825
857
    fflush(stdout);
826
858
    exit(0);
829
861
static void
830
862
show_version()
831
863
{
832
 
    const char *s;
833
 
    int i;
834
 
    /* version line */
835
 
    fputs(strusage(11), stdout);
836
 
    if( (s=strusage(12)) )
837
 
        printf(" (%s)", s );
838
 
    printf(" %s\n", strusage(13) );
839
 
    /* additional version lines */
840
 
    for(i=20; i < 30; i++ )
841
 
        if( (s=strusage(i)) )
842
 
            printf("%s\n", s );
843
 
    /* copyright string */
844
 
    if( (s=strusage(14)) )
845
 
        printf("%s\n", s );
846
 
    /* copying conditions */
847
 
    if( (s=strusage(15)) )
848
 
        fputs(s, stdout);
849
 
    /* thanks */
850
 
    if( (s=strusage(18)) )
851
 
        fputs(s, stdout);
852
 
    /* additional program info */
853
 
    for(i=30; i < 40; i++ )
854
 
        if( (s=strusage(i)) )
855
 
            fputs (s, stdout);
856
 
    fflush(stdout);
 
864
  const char *s;
 
865
  int i;
 
866
 
 
867
  /* Version line.  */
 
868
  fputs (strusage (11), stdout);
 
869
  if ((s=strusage (12)))
 
870
    printf (" (%s)", s );
 
871
  printf (" %s\n", strusage (13) );
 
872
  /* Additional version lines. */
 
873
  for (i=20; i < 30; i++)
 
874
    if ((s=strusage (i)))
 
875
      printf ("%s\n", s );
 
876
  /* Copyright string.  */
 
877
  if( (s=strusage (14)) )
 
878
    printf("%s\n", s );
 
879
  /* Licence string.  */
 
880
  if( (s=strusage (10)) )
 
881
    printf("%s\n", s );
 
882
  /* Copying conditions. */
 
883
  if ( (s=strusage(15)) )
 
884
    fputs (s, stdout);
 
885
  /* Thanks. */
 
886
  if ((s=strusage(18)))
 
887
    fputs (s, stdout);
 
888
  /* Additional program info. */
 
889
  for (i=30; i < 40; i++ )
 
890
    if ( (s=strusage (i)) )
 
891
      fputs (s, stdout);
 
892
  fflush(stdout);
857
893
}
858
894
 
859
895
 
860
896
void
861
 
usage( int level )
 
897
usage (int level)
862
898
{
863
 
    if( !level ) {
864
 
        fprintf(stderr,"%s %s; %s\n", strusage(11), strusage(13),
865
 
                                                     strusage(14) );
866
 
        fflush(stderr);
867
 
    }
868
 
    else if( level == 1 ) {
869
 
        fputs(strusage(40),stderr);
870
 
        exit(2);
871
 
    }
872
 
    else if( level == 2 ) {
873
 
        puts(strusage(41));
874
 
        exit(0);
 
899
  if (!level)
 
900
    {
 
901
      fprintf(stderr,"%s %s; %s\n", strusage(11), strusage(13), strusage (14));
 
902
      fflush (stderr);
 
903
    }
 
904
  else if (level == 1)
 
905
    {
 
906
      fputs (strusage (40), stderr);
 
907
      exit (2);
 
908
    }
 
909
  else if (level == 2) 
 
910
    {
 
911
      puts (strusage(41));
 
912
      exit (0);
875
913
    }
876
914
}
877
915
 
878
916
/* Level
879
 
 *     0: Copyright String auf stderr ausgeben
880
 
 *     1: Kurzusage auf stderr ausgeben und beenden
881
 
 *     2: Langusage auf stdout ausgeben und beenden
882
 
 *    11: name of program
883
 
 *    12: optional name of package which includes this program.
 
917
 *     0: Print copyright string to stderr
 
918
 *     1: Print a short usage hint to stderr and terminate
 
919
 *     2: Print a long usage hint to stdout and terminate
 
920
 *    10: Return license info string
 
921
 *    11: Return the name of the program
 
922
 *    12: Return optional name of package which includes this program.
884
923
 *    13: version  string
885
924
 *    14: copyright string
886
925
 *    15: Short copying conditions (with LFs)
887
926
 *    16: Long copying conditions (with LFs)
888
927
 *    17: Optional printable OS name
889
 
 *    18: Optional thanks list   (with LFs)
 
928
 *    18: Optional thanks list (with LFs)
890
929
 *    19: Bug report info
891
930
 *20..29: Additional lib version strings.
892
931
 *30..39: Additional program info (with LFs)
902
941
        return p;
903
942
 
904
943
    switch( level ) {
 
944
      case 10: p = ("License GPLv3+: GNU GPL version 3 or later "
 
945
                    "<http://gnu.org/licenses/gpl.html>");
 
946
        break;
905
947
      case 11: p = "foo"; break;
906
948
      case 13: p = "0.0"; break;
907
 
      case 14: p = "Copyright (C) 2005 Free Software Foundation, Inc."; break;
 
949
      case 14: p = "Copyright (C) 2008 Free Software Foundation, Inc."; break;
908
950
      case 15: p =
909
 
"This program comes with ABSOLUTELY NO WARRANTY.\n"
910
 
"This is free software, and you are welcome to redistribute it\n"
911
 
"under certain conditions. See the file COPYING for details.\n"; break;
 
951
"This is free software: you are free to change and redistribute it.\n"
 
952
"There is NO WARRANTY, to the extent permitted by law.\n";
 
953
        break;
912
954
      case 16:  p =
913
955
"This is free software; you can redistribute it and/or modify\n"
914
956
"it under the terms of the GNU General Public License as published by\n"
915
 
"the Free Software Foundation; either version 2 of the License, or\n"
 
957
"the Free Software Foundation; either version 3 of the License, or\n"
916
958
"(at your option) any later version.\n\n"
917
959
"It is distributed in the hope that it will be useful,\n"
918
960
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
919
961
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
920
962
"GNU General Public License for more details.\n\n"
921
963
"You should have received a copy of the GNU General Public License\n"
922
 
"along with this program; if not, write to the Free Software\n"
923
 
"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n";
 
964
"along with this software.  If not, see <http://www.gnu.org/licenses/>.\n";
924
965
        break;
925
966
      case 40: /* short and long usage */
926
967
      case 41: p = ""; break;
952
993
{
953
994
    ARGPARSE_OPTS opts[] = {
954
995
    { 'v', "verbose",   0 , "Laut sein"},
955
 
    { 'e', "echo"   ,   0 , "Zeile ausgeben, damit wir sehen, was wir einegegeben haben"},
956
 
    { 'd', "debug",     0 , "Debug\nfalls mal etasws\nSchief geht"},
 
996
    { 'e', "echo"   ,   0 , ("Zeile ausgeben, damit wir sehen, was wir ein"
 
997
                             " gegeben haben")},
 
998
    { 'd', "debug",     0 , "Debug\nfalls mal etwas\nschief geht"},
957
999
    { 'o', "output",    2   },
958
1000
    { 'c', "cross-ref", 2|8, "cross-reference erzeugen\n" },
 
1001
    /* Note that on a non-utf8 terminal the ß might garble the output. */
 
1002
    { 's', "street",  0,     "|Straße|set the name of the street to Straße" },
959
1003
    { 'm', "my-option", 1|8 },
960
1004
    { 500, "a-long-option", 0 },
961
1005
    {0} };
962
1006
    ARGPARSE_ARGS pargs = { &argc, &argv, 2|4|32 };
963
1007
    int i;
964
1008
 
965
 
    while( ArgParse( &pargs, opts) ) {
 
1009
    while( arg_parse ( &pargs, opts) ) {
966
1010
        switch( pargs.r_opt ) {
967
1011
          case -1 : printf( "arg=`%s'\n", pargs.r.ret_str); break;
968
1012
          case 'v': opt.verbose++; break;