~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_getopt.c

  • Committer: Brian Aker
  • Date: 2008-07-14 03:04:13 UTC
  • mfrom: (77.1.90 codestyle)
  • Revision ID: brian@tangent.org-20080714030413-dpv6opb0eoy1rd3f
Merging Monty's code, I did remove error on compile though (since it does
not currently work because of sql_plugin.cc)

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
   along with this program; if not, write to the Free Software
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
 
#include "mysys_priv.h"
17
 
#include <libdrizzle/gettext.h>
18
 
 
19
 
#include <mystrings/m_string.h>
 
16
#include <my_global.h>
 
17
#include <m_string.h>
20
18
#include <stdlib.h>
21
19
#include <my_sys.h>
22
20
#include <mysys_err.h>
29
27
static void default_reporter(enum loglevel level, const char *format, ...);
30
28
my_error_reporter my_getopt_error_reporter= &default_reporter;
31
29
 
32
 
static int findopt(char *optpat, uint32_t length,
 
30
static int findopt(char *optpat, uint length,
33
31
                   const struct my_option **opt_res,
34
32
                   char **ffname);
35
33
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err);
52
50
*/
53
51
static const char *special_opt_prefix[]=
54
52
{"skip", "disable", "enable", "maximum", "loose", 0};
55
 
static const uint32_t special_opt_prefix_lengths[]=
 
53
static const uint special_opt_prefix_lengths[]=
56
54
{ 4,      7,         6,        7,         5,      0};
57
55
enum enum_special_opt
58
56
{ OPT_SKIP, OPT_DISABLE, OPT_ENABLE, OPT_MAXIMUM, OPT_LOOSE};
80
78
  va_list args;
81
79
  va_start(args, format);
82
80
  if (level == WARNING_LEVEL)
83
 
    fprintf(stderr, "%s", _("Warning: "));
 
81
    fprintf(stderr, "%s", "Warning: ");
84
82
  else if (level == INFORMATION_LEVEL)
85
 
    fprintf(stderr, "%s", _("Info: "));
 
83
    fprintf(stderr, "%s", "Info: ");
86
84
  vfprintf(stderr, format, args);
87
85
  va_end(args);
88
86
  fputc('\n', stderr);
111
109
                   const struct my_option *longopts,
112
110
                   my_get_one_option get_one_option)
113
111
{
114
 
  uint32_t opt_found, argvpos= 0, length;
115
 
  bool end_of_options= 0, must_be_var, set_maximum_value=false,
 
112
  uint opt_found, argvpos= 0, length;
 
113
  bool end_of_options= 0, must_be_var, set_maximum_value,
116
114
          option_is_loose;
117
115
  char **pos, **pos_end, *optend, *prev_found=NULL,
118
116
       *opt_str, key_name[FN_REFLEN];
121
119
  int error, i;
122
120
 
123
121
  /* handle_options() assumes arg0 (program name) always exists */
124
 
  assert(argc && *argc >= 1);
125
 
  assert(argv && *argv);
 
122
  DBUG_ASSERT(argc && *argc >= 1);
 
123
  DBUG_ASSERT(argv && *argv);
126
124
  (*argc)--; /* Skip the program name */
127
125
  (*argv)++; /*      --- || ----      */
128
126
  init_variables(longopts, init_one_value);
203
201
          }
204
202
        }
205
203
        opt_str= check_struct_option(cur_arg, key_name);
206
 
        optend= strrchr(opt_str, '=');
207
 
        if (optend != NULL)
208
 
        {
209
 
          length= (uint) (optend - opt_str);
 
204
        optend= strcend(opt_str, '=');
 
205
        length= (uint) (optend - opt_str);
 
206
        if (*optend == '=')
210
207
          optend++;
211
 
        }
212
208
        else
213
 
        {
214
 
          length= strlen(opt_str);
215
209
          optend= 0;
216
 
        }
217
210
 
218
211
        /*
219
212
          Find first the right option. Return error in case of an ambiguous,
261
254
                  case OPT_DISABLE: /* fall through */
262
255
                    /*
263
256
                      double negation is actually enable again,
264
 
                      for example: --skip-option=0 -> option = true
 
257
                      for example: --skip-option=0 -> option = TRUE
265
258
                    */
266
259
                    optend= (optend && *optend == '0' && !(*(optend + 1))) ?
267
260
                      (char*) "1" : disabled_my_option;
271
264
                      disabled_my_option : (char*) "1";
272
265
                    break;
273
266
                  case OPT_MAXIMUM:
274
 
                    set_maximum_value= true;
275
 
                    must_be_var= true;
 
267
                    set_maximum_value= 1;
 
268
                    must_be_var= 1;
276
269
                    break;
277
270
                  }
278
271
                  break; /* break from the inner loop, main loop continues */
347
340
        {
348
341
          if (my_getopt_print_errors)
349
342
            fprintf(stderr,
350
 
                    _("%s: %s: Option '%s' used, but is disabled\n"), my_progname,
351
 
                    option_is_loose ? _("WARNING") : _("ERROR"), opt_str);
 
343
                    "%s: %s: Option '%s' used, but is disabled\n", my_progname,
 
344
                    option_is_loose ? "WARNING" : "ERROR", opt_str);
352
345
          if (option_is_loose)
353
346
          {
354
347
            (*argc)--;
386
379
              */
387
380
            (*argc)--;
388
381
            if (!optend || *optend == '1' ||
389
 
                !my_strcasecmp(&my_charset_utf8_general_ci, optend, "true"))
 
382
                !my_strcasecmp(&my_charset_latin1, optend, "true"))
390
383
              *((bool*) value)= (bool) 1;
391
384
            else if (*optend == '0' ||
392
 
                     !my_strcasecmp(&my_charset_utf8_general_ci, optend, "false"))
 
385
                     !my_strcasecmp(&my_charset_latin1, optend, "false"))
393
386
              *((bool*) value)= (bool) 0;
394
387
            else
395
388
            {
443
436
          opt_found= 0;
444
437
          for (optp= longopts; optp->id; optp++)
445
438
          {
446
 
            if (optp->id == (int) (unsigned char) *optend)
 
439
            if (optp->id == (int) (uchar) *optend)
447
440
            {
448
441
              /* Option recognized. Find next what to do with it */
449
442
              opt_found= 1;
451
444
              {
452
445
                if (my_getopt_print_errors)
453
446
                  fprintf(stderr,
454
 
                          _("%s: ERROR: Option '-%c' used, but is disabled\n"),
 
447
                          "%s: ERROR: Option '-%c' used, but is disabled\n",
455
448
                          my_progname, optp->id);
456
449
                return EXIT_OPTION_DISABLED;
457
450
              }
496
489
                }
497
490
              }
498
491
              if ((error= setval(optp, optp->value, argument,
499
 
                                 set_maximum_value)))
500
 
              {
 
492
                                 set_maximum_value)))
 
493
              {
501
494
                my_getopt_error_reporter(ERROR_LEVEL,
502
495
                                         "%s: Error while setting value '%s' to '%s'",
503
496
                                         my_progname, argument, optp->name);
504
 
                return error;
505
 
              }
506
 
              get_one_option(optp->id, optp, argument);
507
 
              break;
508
 
            }
509
 
          }
510
 
          if (!opt_found)
511
 
          {
512
 
            if (my_getopt_print_errors)
 
497
                return error;
 
498
              }
 
499
              get_one_option(optp->id, optp, argument);
 
500
              break;
 
501
            }
 
502
          }
 
503
          if (!opt_found)
 
504
          {
 
505
            if (my_getopt_print_errors)
513
506
              my_getopt_error_reporter(ERROR_LEVEL,
514
507
                                       "%s: unknown option '-%c'", 
515
508
                                       my_progname, *optend);
516
 
            return EXIT_UNKNOWN_OPTION;
517
 
          }
518
 
        }
519
 
        (*argc)--; /* option handled (short), decrease argument count */
520
 
        continue;
 
509
            return EXIT_UNKNOWN_OPTION;
 
510
          }
 
511
        }
 
512
        (*argc)--; /* option handled (short), decrease argument count */
 
513
        continue;
521
514
      }
522
515
      if ((error= setval(optp, value, argument, set_maximum_value)))
523
516
      {
524
517
        my_getopt_error_reporter(ERROR_LEVEL,
525
518
                                 "%s: Error while setting value '%s' to '%s'",
526
519
                                 my_progname, argument, optp->name);
527
 
        return error;
 
520
        return error;
528
521
      }
529
522
      get_one_option(optp->id, optp, argument);
530
523
 
562
555
{
563
556
  char *ptr, *end;
564
557
 
565
 
  ptr= strrchr(cur_arg + 1, '.'); /* Skip the first character */
566
 
  end= strrchr(cur_arg, '=');
 
558
  ptr= strcend(cur_arg + 1, '.'); /* Skip the first character */
 
559
  end= strcend(cur_arg, '=');
567
560
 
568
561
  /* 
569
562
     If the first dot is after an equal sign, then it is part
572
565
     NULL, or the character right before equal sign is the first
573
566
     dot found, the option is not a struct option.
574
567
  */
575
 
  if ((ptr != NULL) && (end != NULL) && (end - ptr > 1))
 
568
  if (end - ptr > 1)
576
569
  {
577
 
    uint32_t len= (uint) (ptr - cur_arg);
 
570
    uint len= (uint) (ptr - cur_arg);
578
571
    set_if_smaller(len, FN_REFLEN-1);
579
572
    strmake(key_name, cur_arg, len);
580
573
    return ++ptr;
593
586
  Will set the option value to given value
594
587
*/
595
588
 
596
 
static int setval(const struct my_option *opts, char **value, char *argument,
597
 
                  bool set_maximum_value)
 
589
static int setval(const struct my_option *opts, char* *value, char *argument,
 
590
                  bool set_maximum_value)
598
591
{
599
592
  int err= 0;
600
593
 
636
629
      break;
637
630
    case GET_STR_ALLOC:
638
631
      if ((*((char**) result_pos)))
639
 
        free((*(char**) result_pos));
 
632
        my_free((*(char**) result_pos), MYF(MY_WME | MY_FAE));
640
633
      if (!(*((char**) result_pos)= my_strdup(argument, MYF(MY_WME))))
641
634
        return EXIT_OUT_OF_MEMORY;
642
635
      break;
681
674
        ffname points to first matching option
682
675
*/
683
676
 
684
 
static int findopt(char *optpat, uint32_t length,
 
677
static int findopt(char *optpat, uint length,
685
678
                   const struct my_option **opt_res,
686
679
                   char **ffname)
687
680
{
688
 
  uint32_t count;
 
681
  uint count;
689
682
  struct my_option *opt= (struct my_option *) *opt_res;
690
683
 
691
684
  for (count= 0; opt->name; opt++)
722
715
*/
723
716
 
724
717
bool getopt_compare_strings(register const char *s, register const char *t,
725
 
                               uint32_t length)
 
718
                               uint length)
726
719
{
727
720
  char const *end= s + length;
728
721
  for (;s != end ; s++, t++)
764
757
  else if (*endchar)
765
758
  {
766
759
    fprintf(stderr,
767
 
            _("Unknown suffix '%c' used for variable '%s' (value '%s')\n"),
 
760
            "Unknown suffix '%c' used for variable '%s' (value '%s')\n",
768
761
            *endchar, option_name, argument);
769
762
    *error= 1;
770
763
    return 0;
800
793
                               bool *fix)
801
794
{
802
795
  int64_t old= num;
803
 
  bool adjusted= false;
 
796
  bool adjusted= FALSE;
804
797
  char buf1[255], buf2[255];
805
798
  uint64_t block_size= (optp->block_size ? (uint64_t) optp->block_size : 1L);
806
799
 
808
801
      optp->max_value) /* if max value is not set -> no upper limit */
809
802
  {
810
803
    num= (uint64_t) optp->max_value;
811
 
    adjusted= true;
 
804
    adjusted= TRUE;
812
805
  }
813
806
 
814
807
  switch ((optp->var_type & GET_TYPE_MASK)) {
816
809
    if (num > (int64_t) INT_MAX)
817
810
    {
818
811
      num= ((int64_t) INT_MAX);
819
 
      adjusted= true;
 
812
      adjusted= TRUE;
820
813
    }
821
814
    break;
822
815
  case GET_LONG:
823
 
    if (num > (int64_t) INT32_MAX)
 
816
#if SIZEOF_LONG < SIZEOF_LONG_LONG
 
817
    if (num > (int64_t) LONG_MAX)
824
818
    {
825
 
      num= ((int64_t) INT32_MAX);
826
 
      adjusted= true;
 
819
      num= ((int64_t) LONG_MAX);
 
820
      adjusted= TRUE;
827
821
    }
 
822
#endif
828
823
    break;
829
824
  default:
830
 
    assert((optp->var_type & GET_TYPE_MASK) == GET_LL);
 
825
    DBUG_ASSERT((optp->var_type & GET_TYPE_MASK) == GET_LL);
831
826
    break;
832
827
  }
833
828
 
837
832
  if (num < optp->min_value)
838
833
  {
839
834
    num= optp->min_value;
840
 
    adjusted= true;
 
835
    adjusted= TRUE;
841
836
  }
842
837
 
843
838
  if (fix)
852
847
/*
853
848
  function: getopt_ull
854
849
 
855
 
  This is the same as getopt_ll, but is meant for uint64_t
 
850
  This is the same as getopt_ll, but is meant for unsigned long long
856
851
  values.
857
852
*/
858
853
 
866
861
uint64_t getopt_ull_limit_value(uint64_t num, const struct my_option *optp,
867
862
                                 bool *fix)
868
863
{
869
 
  bool adjusted= false;
 
864
  bool adjusted= FALSE;
870
865
  uint64_t old= num;
871
866
  char buf1[255], buf2[255];
872
867
 
874
869
      optp->max_value) /* if max value is not set -> no upper limit */
875
870
  {
876
871
    num= (uint64_t) optp->max_value;
877
 
    adjusted= true;
 
872
    adjusted= TRUE;
878
873
  }
879
874
 
880
875
  switch ((optp->var_type & GET_TYPE_MASK)) {
882
877
    if (num > (uint64_t) UINT_MAX)
883
878
    {
884
879
      num= ((uint64_t) UINT_MAX);
885
 
      adjusted= true;
 
880
      adjusted= TRUE;
886
881
    }
887
882
    break;
888
883
  case GET_ULONG:
889
 
    if (num > (uint64_t) UINT32_MAX)
 
884
#if SIZEOF_LONG < SIZEOF_LONG_LONG
 
885
    if (num > (uint64_t) ULONG_MAX)
890
886
    {
891
 
      num= ((uint64_t) UINT32_MAX);
892
 
      adjusted= true;
 
887
      num= ((uint64_t) ULONG_MAX);
 
888
      adjusted= TRUE;
893
889
    }
 
890
#endif
894
891
    break;
895
892
  default:
896
 
    assert((optp->var_type & GET_TYPE_MASK) == GET_ULL);
 
893
    DBUG_ASSERT((optp->var_type & GET_TYPE_MASK) == GET_ULL);
897
894
    break;
898
895
  }
899
896
 
906
903
  if (num < (uint64_t) optp->min_value)
907
904
  {
908
905
    num= (uint64_t) optp->min_value;
909
 
    adjusted= true;
 
906
    adjusted= TRUE;
910
907
  }
911
908
 
912
909
  if (fix)
941
938
  if (end[0] != 0 || error)
942
939
  {
943
940
    fprintf(stderr,
944
 
            _("%s: ERROR: Invalid decimal value for option '%s'\n"),
 
941
            "%s: ERROR: Invalid decimal value for option '%s'\n",
945
942
            my_progname, optp->name);
946
943
    *err= EXIT_ARGUMENT_INVALID;
947
944
    return 0.0;
948
945
  }
949
946
  if (optp->max_value && num > (double) optp->max_value)
950
947
    num= (double) optp->max_value;
951
 
  return cmax(num, (double) optp->min_value);
 
948
  return max(num, (double) optp->min_value);
952
949
}
953
950
 
954
951
/*
963
960
static void init_one_value(const struct my_option *option, char** variable,
964
961
                           int64_t value)
965
962
{
 
963
  DBUG_ENTER("init_one_value");
966
964
  switch ((option->var_type & GET_TYPE_MASK)) {
967
965
  case GET_BOOL:
968
966
    *((bool*) variable)= (bool) value;
978
976
    *((long*) variable)= (long) value;
979
977
    break;
980
978
  case GET_ULONG:
981
 
    *((uint32_t*) variable)= (uint32_t) value;
 
979
    *((ulong*) variable)= (ulong) value;
982
980
    break;
983
981
  case GET_LL:
984
982
    *((int64_t*) variable)= (int64_t) value;
994
992
    /*
995
993
      Do not clear variable value if it has no default value.
996
994
      The default value may already be set.
997
 
      NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
 
995
      NOTE: To avoid compiler warnings, we first cast int64_t to intptr,
998
996
      so that the value has the same size as a pointer.
999
997
    */
1000
 
    if ((char*) (intptr_t) value)
1001
 
      *((char**) variable)= (char*) (intptr_t) value;
 
998
    if ((char*) (intptr) value)
 
999
      *((char**) variable)= (char*) (intptr) value;
1002
1000
    break;
1003
1001
  case GET_STR_ALLOC:
1004
1002
    /*
1005
1003
      Do not clear variable value if it has no default value.
1006
1004
      The default value may already be set.
1007
 
      NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
 
1005
      NOTE: To avoid compiler warnings, we first cast int64_t to intptr,
1008
1006
      so that the value has the same size as a pointer.
1009
1007
    */
1010
 
    if ((char*) (intptr_t) value)
 
1008
    if ((char*) (intptr) value)
1011
1009
    {
1012
 
      free((*(char**) variable));
1013
 
      *((char**) variable)= my_strdup((char*) (intptr_t) value, MYF(MY_WME));
 
1010
      my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
 
1011
      *((char**) variable)= my_strdup((char*) (intptr) value, MYF(MY_WME));
1014
1012
    }
1015
1013
    break;
1016
1014
  default: /* dummy default to avoid compiler warnings */
1017
1015
    break;
1018
1016
  }
1019
 
  return;
 
1017
  DBUG_VOID_RETURN;
1020
1018
}
1021
1019
 
1022
1020
 
1032
1030
static void fini_one_value(const struct my_option *option, char **variable,
1033
1031
                           int64_t value __attribute__ ((unused)))
1034
1032
{
 
1033
  DBUG_ENTER("fini_one_value");
1035
1034
  switch ((option->var_type & GET_TYPE_MASK)) {
1036
1035
  case GET_STR_ALLOC:
1037
 
    free((*(char**) variable));
 
1036
    my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
1038
1037
    *((char**) variable)= NULL;
1039
1038
    break;
1040
1039
  default: /* dummy default to avoid compiler warnings */
1041
1040
    break;
1042
1041
  }
1043
 
  return;
 
1042
  DBUG_VOID_RETURN;
1044
1043
}
1045
1044
 
1046
1045
 
1066
1065
static void init_variables(const struct my_option *options,
1067
1066
                           init_func_p init_one_value)
1068
1067
{
 
1068
  DBUG_ENTER("init_variables");
1069
1069
  for (; options->name; options++)
1070
1070
  {
1071
1071
    char* *variable;
 
1072
    DBUG_PRINT("options", ("name: '%s'", options->name));
1072
1073
    /*
1073
1074
      We must set u_max_value first as for some variables
1074
1075
      options->u_max_value == options->value and in this case we want to
1082
1083
        (variable= (*getopt_get_addr)("", 0, options)))
1083
1084
      init_one_value(options, variable, options->def_value);
1084
1085
  }
1085
 
  return;
 
1086
  DBUG_VOID_RETURN;
1086
1087
}
1087
1088
 
1088
1089
 
1092
1093
  Print help for all options and variables.
1093
1094
*/
1094
1095
 
 
1096
#include <help_start.h>
 
1097
 
1095
1098
void my_print_help(const struct my_option *options)
1096
1099
{
1097
 
  uint32_t col, name_space= 22, comment_space= 57;
 
1100
  uint col, name_space= 22, comment_space= 57;
1098
1101
  const char *line_end;
1099
1102
  const struct my_option *optp;
1100
1103
 
1143
1146
      putchar(' ');
1144
1147
    if (optp->comment && *optp->comment)
1145
1148
    {
1146
 
      const char *comment= _(optp->comment), *end= strchr(comment, '\0');
 
1149
      const char *comment= optp->comment, *end= strend(comment);
1147
1150
 
1148
1151
      while ((uint) (end - comment) > comment_space)
1149
1152
      {
1163
1166
    {
1164
1167
      if (optp->def_value != 0)
1165
1168
      {
1166
 
        printf(_("%*s(Defaults to on; use --skip-%s to disable.)\n"), name_space, "", optp->name);
 
1169
        printf("%*s(Defaults to on; use --skip-%s to disable.)\n", name_space, "", optp->name);
1167
1170
      }
1168
1171
    }
1169
1172
  }
1178
1181
 
1179
1182
void my_print_variables(const struct my_option *options)
1180
1183
{
1181
 
  uint32_t name_space= 34, length, nr;
 
1184
  uint name_space= 34, length, nr;
1182
1185
  uint64_t bit, llvalue;
1183
1186
  char buff[255];
1184
1187
  const struct my_option *optp;
1185
1188
 
1186
 
  printf(_("\nVariables (--variable-name=value)\n"
1187
 
         "and boolean options {false|true}  Value (after reading options)\n"
1188
 
         "--------------------------------- -----------------------------\n"));
 
1189
  printf("\nVariables (--variable-name=value)\n");
 
1190
  printf("and boolean options {FALSE|TRUE}  Value (after reading options)\n");
 
1191
  printf("--------------------------------- -----------------------------\n");
1189
1192
  for (optp= options; optp->id; optp++)
1190
1193
  {
1191
1194
    char* *value= (optp->var_type & GET_ASK_ADDR ?
1199
1202
      switch ((optp->var_type & GET_TYPE_MASK)) {
1200
1203
      case GET_SET:
1201
1204
        if (!(llvalue= *(uint64_t*) value))
1202
 
          printf("%s\n", _("(No default value)"));
 
1205
          printf("%s\n", "(No default value)");
1203
1206
        else
1204
1207
        for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
1205
1208
        {
1215
1218
      case GET_STR:
1216
1219
      case GET_STR_ALLOC:                    /* fall through */
1217
1220
        printf("%s\n", *((char**) value) ? *((char**) value) :
1218
 
               _("(No default value)"));
 
1221
               "(No default value)");
1219
1222
        break;
1220
1223
      case GET_BOOL:
1221
 
        printf("%s\n", *((bool*) value) ? _("true") : _("false"));
 
1224
        printf("%s\n", *((bool*) value) ? "TRUE" : "FALSE");
1222
1225
        break;
1223
1226
      case GET_INT:
1224
1227
        printf("%d\n", *((int*) value));
1230
1233
        printf("%ld\n", *((long*) value));
1231
1234
        break;
1232
1235
      case GET_ULONG:
1233
 
        printf("%u\n", *((uint32_t*) value));
 
1236
        printf("%lu\n", *((ulong*) value));
1234
1237
        break;
1235
1238
      case GET_LL:
1236
1239
        printf("%s\n", llstr(*((int64_t*) value), buff));
1243
1246
        printf("%g\n", *(double*) value);
1244
1247
        break;
1245
1248
      default:
1246
 
        printf(_("(Disabled)\n"));
 
1249
        printf("(Disabled)\n");
1247
1250
        break;
1248
1251
      }
1249
1252
    }
1250
1253
  }
1251
1254
}
 
1255
 
 
1256
#include <help_end.h>