~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_getopt.c

MergeĀ fromĀ trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
#include <my_getopt.h>
22
22
#include <errno.h>
23
23
 
24
 
typedef void (*init_func_p)(const struct my_option *option, uchar* *variable,
25
 
                            longlong value);
 
24
typedef void (*init_func_p)(const struct my_option *option, char **variable,
 
25
                            int64_t value);
26
26
 
27
27
static void default_reporter(enum loglevel level, const char *format, ...);
28
28
my_error_reporter my_getopt_error_reporter= &default_reporter;
30
30
static int findopt(char *optpat, uint length,
31
31
                   const struct my_option **opt_res,
32
32
                   char **ffname);
33
 
static longlong getopt_ll(char *arg, const struct my_option *optp, int *err);
34
 
static ulonglong getopt_ull(char *arg, const struct my_option *optp,
 
33
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err);
 
34
static uint64_t getopt_ull(char *arg, const struct my_option *optp,
35
35
                            int *err);
36
36
static double getopt_double(char *arg, const struct my_option *optp, int *err);
37
37
static void init_variables(const struct my_option *options,
38
38
                           init_func_p init_one_value);
39
 
static void init_one_value(const struct my_option *option, uchar* *variable,
40
 
                           longlong value);
41
 
static void fini_one_value(const struct my_option *option, uchar* *variable,
42
 
                           longlong value);
43
 
static int setval(const struct my_option *opts, uchar* *value, char *argument,
44
 
                  my_bool set_maximum_value);
 
39
static void init_one_value(const struct my_option *option, char **variable,
 
40
                           int64_t value);
 
41
static void fini_one_value(const struct my_option *option, char **variable,
 
42
                           int64_t value);
 
43
static int setval(const struct my_option *opts, char* *value, char *argument,
 
44
                  bool set_maximum_value);
45
45
static char *check_struct_option(char *cur_arg, char *key_name);
46
46
 
47
47
/*
63
63
   it by itself
64
64
*/
65
65
 
66
 
my_bool my_getopt_print_errors= 1;
 
66
bool my_getopt_print_errors= 1;
67
67
 
68
68
/* 
69
69
   This is a flag that can be set in client programs. 1 means that
70
70
   my_getopt will skip over options it does not know how to handle.
71
71
*/
72
72
 
73
 
my_bool my_getopt_skip_unknown= 0;
 
73
bool my_getopt_skip_unknown= 0;
74
74
 
75
75
static void default_reporter(enum loglevel level,
76
76
                             const char *format, ...)
97
97
  one. Call function 'get_one_option()' once for each option.
98
98
*/
99
99
 
100
 
static uchar** (*getopt_get_addr)(const char *, uint, const struct my_option *);
 
100
static char** (*getopt_get_addr)(const char *, uint, const struct my_option *);
101
101
 
102
 
void my_getopt_register_get_addr(uchar** (*func_addr)(const char *, uint,
 
102
void my_getopt_register_get_addr(char** (*func_addr)(const char *, uint,
103
103
                                                    const struct my_option *))
104
104
{
105
105
  getopt_get_addr= func_addr;
110
110
                   my_get_one_option get_one_option)
111
111
{
112
112
  uint opt_found, argvpos= 0, length;
113
 
  my_bool end_of_options= 0, must_be_var, set_maximum_value,
 
113
  bool end_of_options= 0, must_be_var, set_maximum_value,
114
114
          option_is_loose;
115
 
  char **pos, **pos_end, *optend, *prev_found,
 
115
  char **pos, **pos_end, *optend, *prev_found=NULL,
116
116
       *opt_str, key_name[FN_REFLEN];
117
117
  const struct my_option *optp;
118
 
  uchar* *value;
 
118
  char* *value;
119
119
  int error, i;
120
120
 
121
121
  /* handle_options() assumes arg0 (program name) always exists */
254
254
                  case OPT_DISABLE: /* fall through */
255
255
                    /*
256
256
                      double negation is actually enable again,
257
 
                      for example: --skip-option=0 -> option = TRUE
 
257
                      for example: --skip-option=0 -> option = true
258
258
                    */
259
259
                    optend= (optend && *optend == '0' && !(*(optend + 1))) ?
260
260
                      (char*) "1" : disabled_my_option;
380
380
            (*argc)--;
381
381
            if (!optend || *optend == '1' ||
382
382
                !my_strcasecmp(&my_charset_latin1, optend, "true"))
383
 
              *((my_bool*) value)= (my_bool) 1;
 
383
              *((bool*) value)= (bool) 1;
384
384
            else if (*optend == '0' ||
385
385
                     !my_strcasecmp(&my_charset_latin1, optend, "false"))
386
 
              *((my_bool*) value)= (my_bool) 0;
 
386
              *((bool*) value)= (bool) 0;
387
387
            else
388
388
            {
389
389
              my_getopt_error_reporter(WARNING_LEVEL,
393
393
              continue;
394
394
            }
395
395
            get_one_option(optp->id, optp,
396
 
                           *((my_bool*) value) ?
 
396
                           *((bool*) value) ?
397
397
                           (char*) "1" : disabled_my_option);
398
398
            continue;
399
399
          }
403
403
                 (optp->var_type & GET_TYPE_MASK) == GET_BOOL)
404
404
        {
405
405
          if (optend == disabled_my_option)
406
 
            *((my_bool*) value)= (my_bool) 0;
 
406
            *((bool*) value)= (bool) 0;
407
407
          else
408
408
          {
409
409
            if (!optend) /* No argument -> enable option */
410
 
              *((my_bool*) value)= (my_bool) 1;
 
410
              *((bool*) value)= (bool) 1;
411
411
            else
412
412
              argument= optend;
413
413
          }
451
451
              if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL &&
452
452
                  optp->arg_type == NO_ARG)
453
453
              {
454
 
                *((my_bool*) optp->value)= (my_bool) 1;
 
454
                *((bool*) optp->value)= (bool) 1;
455
455
                get_one_option(optp->id, optp, argument);
456
456
                continue;
457
457
              }
470
470
                  if (optp->arg_type == OPT_ARG)
471
471
                  {
472
472
                    if (optp->var_type == GET_BOOL)
473
 
                      *((my_bool*) optp->value)= (my_bool) 1;
 
473
                      *((bool*) optp->value)= (bool) 1;
474
474
                    get_one_option(optp->id, optp, argument);
475
475
                    continue;
476
476
                  }
488
488
                  /* the other loop will break, because *optend + 1 == 0 */
489
489
                }
490
490
              }
491
 
              if ((error= setval(optp, optp->value, argument,
 
491
              if ((error= setval(optp, optp->value, argument,
492
492
                                 set_maximum_value)))
493
493
              {
494
494
                my_getopt_error_reporter(ERROR_LEVEL,
586
586
  Will set the option value to given value
587
587
*/
588
588
 
589
 
static int setval(const struct my_option *opts, uchar* *value, char *argument,
590
 
                  my_bool set_maximum_value)
 
589
static int setval(const struct my_option *opts, char* *value, char *argument,
 
590
                  bool set_maximum_value)
591
591
{
592
592
  int err= 0;
593
593
 
594
594
  if (value && argument)
595
595
  {
596
 
    uchar* *result_pos= ((set_maximum_value) ?
597
 
                       opts->u_max_value : value);
 
596
    char* *result_pos= ((set_maximum_value) ?
 
597
                        opts->u_max_value : value);
598
598
 
599
599
    if (!result_pos)
600
600
      return EXIT_NO_PTR_TO_VARIABLE;
601
601
 
602
602
    switch ((opts->var_type & GET_TYPE_MASK)) {
603
603
    case GET_BOOL: /* If argument differs from 0, enable option, else disable */
604
 
      *((my_bool*) result_pos)= (my_bool) atoi(argument) != 0;
 
604
      *((bool*) result_pos)= (bool) atoi(argument) != 0;
605
605
      break;
606
606
    case GET_INT:
607
607
      *((int*) result_pos)= (int) getopt_ll(argument, opts, &err);
616
616
      *((long*) result_pos)= (long) getopt_ull(argument, opts, &err);
617
617
      break;
618
618
    case GET_LL:
619
 
      *((longlong*) result_pos)= getopt_ll(argument, opts, &err);
 
619
      *((int64_t*) result_pos)= getopt_ll(argument, opts, &err);
620
620
      break;
621
621
    case GET_ULL:
622
 
      *((ulonglong*) result_pos)= getopt_ull(argument, opts, &err);
 
622
      *((uint64_t*) result_pos)= getopt_ull(argument, opts, &err);
623
623
      break;
624
624
    case GET_DOUBLE:
625
625
      *((double*) result_pos)= getopt_double(argument, opts, &err);
638
638
        return EXIT_ARGUMENT_INVALID;
639
639
      break;
640
640
    case GET_SET:
641
 
      *((ulonglong*)result_pos)= find_typeset(argument, opts->typelib, &err);
 
641
      *((uint64_t*)result_pos)= find_typeset(argument, opts->typelib, &err);
642
642
      if (err)
643
643
        return EXIT_ARGUMENT_INVALID;
644
644
      break;
714
714
  2.) Returns -1 if strings differ, 0 if they are equal
715
715
*/
716
716
 
717
 
my_bool getopt_compare_strings(register const char *s, register const char *t,
 
717
bool getopt_compare_strings(register const char *s, register const char *t,
718
718
                               uint length)
719
719
{
720
720
  char const *end= s + length;
733
733
  be k|K for kilo, m|M for mega or g|G for giga.
734
734
*/
735
735
 
736
 
static longlong eval_num_suffix(char *argument, int *error, char *option_name)
 
736
static int64_t eval_num_suffix(char *argument, int *error, char *option_name)
737
737
{
738
738
  char *endchar;
739
 
  longlong num;
 
739
  int64_t num;
740
740
  
741
741
  *error= 0;
742
742
  errno= 0;
776
776
  In case of an error, set error value in *err.
777
777
*/
778
778
 
779
 
static longlong getopt_ll(char *arg, const struct my_option *optp, int *err)
 
779
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err)
780
780
{
781
 
  longlong num=eval_num_suffix(arg, err, (char*) optp->name);
 
781
  int64_t num=eval_num_suffix(arg, err, (char*) optp->name);
782
782
  return getopt_ll_limit_value(num, optp, NULL);
783
783
}
784
784
 
789
789
  Returns "fixed" value.
790
790
*/
791
791
 
792
 
longlong getopt_ll_limit_value(longlong num, const struct my_option *optp,
793
 
                               my_bool *fix)
 
792
int64_t getopt_ll_limit_value(int64_t num, const struct my_option *optp,
 
793
                               bool *fix)
794
794
{
795
 
  longlong old= num;
796
 
  my_bool adjusted= FALSE;
 
795
  int64_t old= num;
 
796
  bool adjusted= false;
797
797
  char buf1[255], buf2[255];
798
 
  ulonglong block_size= (optp->block_size ? (ulonglong) optp->block_size : 1L);
 
798
  uint64_t block_size= (optp->block_size ? (uint64_t) optp->block_size : 1L);
799
799
 
800
 
  if (num > 0 && ((ulonglong) num > (ulonglong) optp->max_value) &&
 
800
  if (num > 0 && ((uint64_t) num > (uint64_t) optp->max_value) &&
801
801
      optp->max_value) /* if max value is not set -> no upper limit */
802
802
  {
803
 
    num= (ulonglong) optp->max_value;
804
 
    adjusted= TRUE;
 
803
    num= (uint64_t) optp->max_value;
 
804
    adjusted= true;
805
805
  }
806
806
 
807
807
  switch ((optp->var_type & GET_TYPE_MASK)) {
808
808
  case GET_INT:
809
 
    if (num > (longlong) INT_MAX)
 
809
    if (num > (int64_t) INT_MAX)
810
810
    {
811
 
      num= ((longlong) INT_MAX);
812
 
      adjusted= TRUE;
 
811
      num= ((int64_t) INT_MAX);
 
812
      adjusted= true;
813
813
    }
814
814
    break;
815
815
  case GET_LONG:
816
816
#if SIZEOF_LONG < SIZEOF_LONG_LONG
817
 
    if (num > (longlong) LONG_MAX)
 
817
    if (num > (int64_t) LONG_MAX)
818
818
    {
819
 
      num= ((longlong) LONG_MAX);
820
 
      adjusted= TRUE;
 
819
      num= ((int64_t) LONG_MAX);
 
820
      adjusted= true;
821
821
    }
822
822
#endif
823
823
    break;
827
827
  }
828
828
 
829
829
  num= ((num - optp->sub_size) / block_size);
830
 
  num= (longlong) (num * block_size);
 
830
  num= (int64_t) (num * block_size);
831
831
 
832
832
  if (num < optp->min_value)
833
833
  {
834
834
    num= optp->min_value;
835
 
    adjusted= TRUE;
 
835
    adjusted= true;
836
836
  }
837
837
 
838
838
  if (fix)
851
851
  values.
852
852
*/
853
853
 
854
 
static ulonglong getopt_ull(char *arg, const struct my_option *optp, int *err)
 
854
static uint64_t getopt_ull(char *arg, const struct my_option *optp, int *err)
855
855
{
856
 
  ulonglong num= eval_num_suffix(arg, err, (char*) optp->name);
 
856
  uint64_t num= eval_num_suffix(arg, err, (char*) optp->name);
857
857
  return getopt_ull_limit_value(num, optp, NULL);
858
858
}
859
859
 
860
860
 
861
 
ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp,
862
 
                                 my_bool *fix)
 
861
uint64_t getopt_ull_limit_value(uint64_t num, const struct my_option *optp,
 
862
                                 bool *fix)
863
863
{
864
 
  my_bool adjusted= FALSE;
865
 
  ulonglong old= num;
 
864
  bool adjusted= false;
 
865
  uint64_t old= num;
866
866
  char buf1[255], buf2[255];
867
867
 
868
 
  if ((ulonglong) num > (ulonglong) optp->max_value &&
 
868
  if ((uint64_t) num > (uint64_t) optp->max_value &&
869
869
      optp->max_value) /* if max value is not set -> no upper limit */
870
870
  {
871
 
    num= (ulonglong) optp->max_value;
872
 
    adjusted= TRUE;
 
871
    num= (uint64_t) optp->max_value;
 
872
    adjusted= true;
873
873
  }
874
874
 
875
875
  switch ((optp->var_type & GET_TYPE_MASK)) {
876
876
  case GET_UINT:
877
 
    if (num > (ulonglong) UINT_MAX)
 
877
    if (num > (uint64_t) UINT_MAX)
878
878
    {
879
 
      num= ((ulonglong) UINT_MAX);
880
 
      adjusted= TRUE;
 
879
      num= ((uint64_t) UINT_MAX);
 
880
      adjusted= true;
881
881
    }
882
882
    break;
883
883
  case GET_ULONG:
884
884
#if SIZEOF_LONG < SIZEOF_LONG_LONG
885
 
    if (num > (ulonglong) ULONG_MAX)
 
885
    if (num > (uint64_t) ULONG_MAX)
886
886
    {
887
 
      num= ((ulonglong) ULONG_MAX);
888
 
      adjusted= TRUE;
 
887
      num= ((uint64_t) ULONG_MAX);
 
888
      adjusted= true;
889
889
    }
890
890
#endif
891
891
    break;
896
896
 
897
897
  if (optp->block_size > 1)
898
898
  {
899
 
    num/= (ulonglong) optp->block_size;
900
 
    num*= (ulonglong) optp->block_size;
 
899
    num/= (uint64_t) optp->block_size;
 
900
    num*= (uint64_t) optp->block_size;
901
901
  }
902
902
 
903
 
  if (num < (ulonglong) optp->min_value)
 
903
  if (num < (uint64_t) optp->min_value)
904
904
  {
905
 
    num= (ulonglong) optp->min_value;
906
 
    adjusted= TRUE;
 
905
    num= (uint64_t) optp->min_value;
 
906
    adjusted= true;
907
907
  }
908
908
 
909
909
  if (fix)
957
957
    value               Pointer to variable
958
958
*/
959
959
 
960
 
static void init_one_value(const struct my_option *option, uchar* *variable,
961
 
                           longlong value)
 
960
static void init_one_value(const struct my_option *option, char** variable,
 
961
                           int64_t value)
962
962
{
963
963
  DBUG_ENTER("init_one_value");
964
964
  switch ((option->var_type & GET_TYPE_MASK)) {
965
965
  case GET_BOOL:
966
 
    *((my_bool*) variable)= (my_bool) value;
 
966
    *((bool*) variable)= (bool) value;
967
967
    break;
968
968
  case GET_INT:
969
969
    *((int*) variable)= (int) value;
979
979
    *((ulong*) variable)= (ulong) value;
980
980
    break;
981
981
  case GET_LL:
982
 
    *((longlong*) variable)= (longlong) value;
 
982
    *((int64_t*) variable)= (int64_t) value;
983
983
    break;
984
984
  case GET_ULL:
985
985
  case GET_SET:
986
 
    *((ulonglong*) variable)=  (ulonglong) value;
 
986
    *((uint64_t*) variable)=  (uint64_t) value;
987
987
    break;
988
988
  case GET_DOUBLE:
989
989
    *((double*) variable)=  (double) value;
992
992
    /*
993
993
      Do not clear variable value if it has no default value.
994
994
      The default value may already be set.
995
 
      NOTE: To avoid compiler warnings, we first cast longlong to intptr,
 
995
      NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
996
996
      so that the value has the same size as a pointer.
997
997
    */
998
 
    if ((char*) (intptr) value)
999
 
      *((char**) variable)= (char*) (intptr) value;
 
998
    if ((char*) (intptr_t) value)
 
999
      *((char**) variable)= (char*) (intptr_t) value;
1000
1000
    break;
1001
1001
  case GET_STR_ALLOC:
1002
1002
    /*
1003
1003
      Do not clear variable value if it has no default value.
1004
1004
      The default value may already be set.
1005
 
      NOTE: To avoid compiler warnings, we first cast longlong to intptr,
 
1005
      NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1006
1006
      so that the value has the same size as a pointer.
1007
1007
    */
1008
 
    if ((char*) (intptr) value)
 
1008
    if ((char*) (intptr_t) value)
1009
1009
    {
1010
1010
      my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
1011
 
      *((char**) variable)= my_strdup((char*) (intptr) value, MYF(MY_WME));
 
1011
      *((char**) variable)= my_strdup((char*) (intptr_t) value, MYF(MY_WME));
1012
1012
    }
1013
1013
    break;
1014
1014
  default: /* dummy default to avoid compiler warnings */
1027
1027
    value               Pointer to variable
1028
1028
*/
1029
1029
 
1030
 
static void fini_one_value(const struct my_option *option, uchar* *variable,
1031
 
                           longlong value __attribute__ ((unused)))
 
1030
static void fini_one_value(const struct my_option *option, char **variable,
 
1031
                           int64_t value __attribute__ ((unused)))
1032
1032
{
1033
1033
  DBUG_ENTER("fini_one_value");
1034
1034
  switch ((option->var_type & GET_TYPE_MASK)) {
1068
1068
  DBUG_ENTER("init_variables");
1069
1069
  for (; options->name; options++)
1070
1070
  {
1071
 
    uchar* *variable;
 
1071
    char* *variable;
1072
1072
    DBUG_PRINT("options", ("name: '%s'", options->name));
1073
1073
    /*
1074
1074
      We must set u_max_value first as for some variables
1182
1182
void my_print_variables(const struct my_option *options)
1183
1183
{
1184
1184
  uint name_space= 34, length, nr;
1185
 
  ulonglong bit, llvalue;
 
1185
  uint64_t bit, llvalue;
1186
1186
  char buff[255];
1187
1187
  const struct my_option *optp;
1188
1188
 
1189
1189
  printf("\nVariables (--variable-name=value)\n");
1190
 
  printf("and boolean options {FALSE|TRUE}  Value (after reading options)\n");
 
1190
  printf("and boolean options {false|true}  Value (after reading options)\n");
1191
1191
  printf("--------------------------------- -----------------------------\n");
1192
1192
  for (optp= options; optp->id; optp++)
1193
1193
  {
1194
 
    uchar* *value= (optp->var_type & GET_ASK_ADDR ?
 
1194
    char* *value= (optp->var_type & GET_ASK_ADDR ?
1195
1195
                  (*getopt_get_addr)("", 0, optp) : optp->value);
1196
1196
    if (value)
1197
1197
    {
1201
1201
        putchar(' ');
1202
1202
      switch ((optp->var_type & GET_TYPE_MASK)) {
1203
1203
      case GET_SET:
1204
 
        if (!(llvalue= *(ulonglong*) value))
 
1204
        if (!(llvalue= *(uint64_t*) value))
1205
1205
          printf("%s\n", "(No default value)");
1206
1206
        else
1207
1207
        for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
1221
1221
               "(No default value)");
1222
1222
        break;
1223
1223
      case GET_BOOL:
1224
 
        printf("%s\n", *((my_bool*) value) ? "TRUE" : "FALSE");
 
1224
        printf("%s\n", *((bool*) value) ? "true" : "false");
1225
1225
        break;
1226
1226
      case GET_INT:
1227
1227
        printf("%d\n", *((int*) value));
1236
1236
        printf("%lu\n", *((ulong*) value));
1237
1237
        break;
1238
1238
      case GET_LL:
1239
 
        printf("%s\n", llstr(*((longlong*) value), buff));
 
1239
        printf("%s\n", llstr(*((int64_t*) value), buff));
1240
1240
        break;
1241
1241
      case GET_ULL:
1242
 
        longlong2str(*((ulonglong*) value), buff, 10);
 
1242
        int64_t2str(*((uint64_t*) value), buff, 10);
1243
1243
        printf("%s\n", buff);
1244
1244
        break;
1245
1245
      case GET_DOUBLE: