~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_getopt.cc

  • Committer: Toru Maesaka
  • Date: 2008-12-17 07:16:37 UTC
  • mto: (685.1.40 devel) (713.1.5 devel)
  • mto: This revision was merged to the branch mainline in revision 713.
  • Revision ID: dev@torum.net-20081217071637-7j9040w7lpms77r2
Removed my_time() and added error checking

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
#include "mysys_priv.h"
17
 
#include <libdrizzle/gettext.h>
 
17
#include <drizzled/gettext.h>
18
18
 
19
19
#include <mystrings/m_string.h>
 
20
#include <mysys/my_sys.h>
 
21
#include <mysys/mysys_err.h>
 
22
#include <mysys/my_getopt.h>
 
23
 
 
24
#include <stdio.h>
20
25
#include <stdlib.h>
21
 
#include <my_sys.h>
22
 
#include <mysys_err.h>
23
 
#include <my_getopt.h>
24
26
#include <errno.h>
 
27
#include <iostream>
 
28
 
 
29
using namespace std;
25
30
 
26
31
typedef void (*init_func_p)(const struct my_option *option, char **variable,
27
32
                            int64_t value);
28
33
 
29
 
static void default_reporter(enum loglevel level, const char *format, ...);
 
34
void default_reporter(enum loglevel level, const char *format, ...);
30
35
my_error_reporter my_getopt_error_reporter= &default_reporter;
31
36
 
32
37
static int findopt(char *optpat, uint32_t length,
35
40
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err);
36
41
static uint64_t getopt_ull(char *arg, const struct my_option *optp,
37
42
                            int *err);
 
43
static size_t getopt_size(char *arg, const struct my_option *optp, int *err);
38
44
static double getopt_double(char *arg, const struct my_option *optp, int *err);
39
45
static void init_variables(const struct my_option *options,
40
46
                           init_func_p init_one_value);
59
65
 
60
66
char *disabled_my_option= (char*) "0";
61
67
 
62
 
/* 
 
68
/*
63
69
   This is a flag that can be set in client programs. 0 means that
64
70
   my_getopt will not print error messages, but the client should do
65
71
   it by itself
67
73
 
68
74
bool my_getopt_print_errors= 1;
69
75
 
70
 
/* 
 
76
/*
71
77
   This is a flag that can be set in client programs. 1 means that
72
78
   my_getopt will skip over options it does not know how to handle.
73
79
*/
74
80
 
75
81
bool my_getopt_skip_unknown= 0;
76
82
 
77
 
static void default_reporter(enum loglevel level,
78
 
                             const char *format, ...)
 
83
void default_reporter(enum loglevel level,
 
84
                      const char *format, ...)
79
85
{
80
86
  va_list args;
81
87
  va_start(args, format);
89
95
  fflush(stderr);
90
96
}
91
97
 
92
 
/* 
 
98
/*
93
99
  function: handle_options
94
100
 
95
101
  Sort options; put options first, until special end of options (--), or
99
105
  one. Call function 'get_one_option()' once for each option.
100
106
*/
101
107
 
102
 
static char** (*getopt_get_addr)(const char *, uint, const struct my_option *);
 
108
static getopt_get_addr_func getopt_get_addr;
103
109
 
104
 
void my_getopt_register_get_addr(char** (*func_addr)(const char *, uint,
105
 
                                                    const struct my_option *))
 
110
void my_getopt_register_get_addr(getopt_get_addr_func func_addr)
106
111
{
107
112
  getopt_get_addr= func_addr;
108
113
}
109
114
 
110
 
int handle_options(int *argc, char ***argv, 
 
115
int handle_options(int *argc, char ***argv,
111
116
                   const struct my_option *longopts,
112
117
                   my_get_one_option get_one_option)
113
118
{
299
304
            if (must_be_var)
300
305
            {
301
306
              if (my_getopt_print_errors)
302
 
                my_getopt_error_reporter(option_is_loose ? 
 
307
                my_getopt_error_reporter(option_is_loose ?
303
308
                                           WARNING_LEVEL : ERROR_LEVEL,
304
309
                                         "%s: unknown variable '%s'",
305
310
                                         my_progname, cur_arg);
309
314
            else
310
315
            {
311
316
              if (my_getopt_print_errors)
312
 
                my_getopt_error_reporter(option_is_loose ? 
 
317
                my_getopt_error_reporter(option_is_loose ?
313
318
                                           WARNING_LEVEL : ERROR_LEVEL,
314
 
                                         "%s: unknown option '--%s'", 
 
319
                                         "%s: unknown option '--%s'",
315
320
                                         my_progname, cur_arg);
316
321
              if (!option_is_loose)
317
322
                return EXIT_UNKNOWN_OPTION;
338
343
            if (my_getopt_print_errors)
339
344
              my_getopt_error_reporter(ERROR_LEVEL,
340
345
                                       "%s: ambiguous option '--%s' (%s, %s)",
341
 
                                       my_progname, opt_str, prev_found, 
 
346
                                       my_progname, opt_str, prev_found,
342
347
                                       optp->name);
343
348
            return EXIT_AMBIGUOUS_OPTION;
344
349
          }
359
364
        if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG)
360
365
        {
361
366
          if (my_getopt_print_errors)
362
 
            my_getopt_error_reporter(ERROR_LEVEL, 
 
367
            my_getopt_error_reporter(ERROR_LEVEL,
363
368
                                     "%s: option '%s' cannot take an argument",
364
369
                                     my_progname, optp->name);
365
370
          return EXIT_NO_ARGUMENT_ALLOWED;
366
371
        }
367
372
        value= optp->var_type & GET_ASK_ADDR ?
368
373
          (*getopt_get_addr)(key_name, (uint) strlen(key_name), optp) : optp->value;
369
 
  
 
374
 
370
375
        if (optp->arg_type == NO_ARG)
371
376
        {
372
377
          if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL)
511
516
          {
512
517
            if (my_getopt_print_errors)
513
518
              my_getopt_error_reporter(ERROR_LEVEL,
514
 
                                       "%s: unknown option '-%c'", 
 
519
                                       "%s: unknown option '-%c'",
515
520
                                       my_progname, *optend);
516
521
            return EXIT_UNKNOWN_OPTION;
517
522
          }
565
570
  ptr= strrchr(cur_arg + 1, '.'); /* Skip the first character */
566
571
  end= strrchr(cur_arg, '=');
567
572
 
568
 
  /* 
 
573
  /*
569
574
     If the first dot is after an equal sign, then it is part
570
575
     of a variable value and the option is not a struct option.
571
576
     Also, if the last character in the string before the ending
576
581
  {
577
582
    uint32_t len= (uint) (ptr - cur_arg);
578
583
    set_if_smaller(len, FN_REFLEN-1);
579
 
    strmake(key_name, cur_arg, len);
 
584
    strncpy(key_name, cur_arg, len);
580
585
    return ++ptr;
581
586
  }
582
 
  else
583
 
  {
584
 
    key_name[0]= 0;
585
 
    return cur_arg;
586
 
  }
 
587
  key_name[0]= 0;
 
588
  return cur_arg;
587
589
}
588
590
 
589
591
/*
611
613
      *((bool*) result_pos)= (bool) atoi(argument) != 0;
612
614
      break;
613
615
    case GET_INT:
614
 
      *((int*) result_pos)= (int) getopt_ll(argument, opts, &err);
 
616
      *((int32_t*) result_pos)= (int) getopt_ll(argument, opts, &err);
615
617
      break;
616
618
    case GET_UINT:
617
 
      *((uint*) result_pos)= (uint) getopt_ull(argument, opts, &err);
 
619
      *((uint32_t*) result_pos)= (uint) getopt_ull(argument, opts, &err);
618
620
      break;
619
621
    case GET_LONG:
620
622
      *((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
628
630
    case GET_ULL:
629
631
      *((uint64_t*) result_pos)= getopt_ull(argument, opts, &err);
630
632
      break;
 
633
    case GET_SIZE:
 
634
      *((size_t*) result_pos)= getopt_size(argument, opts, &err);
 
635
      break;
631
636
    case GET_DOUBLE:
632
637
      *((double*) result_pos)= getopt_double(argument, opts, &err);
633
638
      break;
637
642
    case GET_STR_ALLOC:
638
643
      if ((*((char**) result_pos)))
639
644
        free((*(char**) result_pos));
640
 
      if (!(*((char**) result_pos)= my_strdup(argument, MYF(MY_WME))))
 
645
      if (!(*((char**) result_pos)= strdup(argument)))
641
646
        return EXIT_OUT_OF_MEMORY;
642
647
      break;
643
648
    case GET_ENUM:
659
664
}
660
665
 
661
666
 
662
 
/* 
 
667
/*
663
668
  Find option
664
669
 
665
670
  SYNOPSIS
714
719
}
715
720
 
716
721
 
717
 
/* 
 
722
/*
718
723
  function: compare_strings
719
724
 
720
725
  Works like strncmp, other than 1.) considers '-' and '_' the same.
744
749
{
745
750
  char *endchar;
746
751
  int64_t num;
747
 
  
 
752
 
748
753
  *error= 0;
749
754
  errno= 0;
750
755
  num= strtoll(argument, &endchar, 10);
772
777
  return num;
773
778
}
774
779
 
775
 
/* 
 
780
/*
776
781
  function: getopt_ll
777
782
 
778
783
  Evaluates and returns the value that user gave as an argument
820
825
    }
821
826
    break;
822
827
  case GET_LONG:
823
 
#if SIZEOF_LONG < SIZEOF_LONG_LONG
824
 
    if (num > (int64_t) LONG_MAX)
 
828
    if (num > (int64_t) INT32_MAX)
825
829
    {
826
 
      num= ((int64_t) LONG_MAX);
 
830
      num= ((int64_t) INT32_MAX);
827
831
      adjusted= true;
828
832
    }
829
 
#endif
830
833
    break;
831
834
  default:
832
835
    assert((optp->var_type & GET_TYPE_MASK) == GET_LL);
854
857
/*
855
858
  function: getopt_ull
856
859
 
857
 
  This is the same as getopt_ll, but is meant for unsigned long long
 
860
  This is the same as getopt_ll, but is meant for uint64_t
858
861
  values.
859
862
*/
860
863
 
865
868
}
866
869
 
867
870
 
 
871
static size_t getopt_size(char *arg, const struct my_option *optp, int *err)
 
872
{
 
873
  return (size_t)getopt_ull(arg, optp, err);
 
874
}
 
875
 
 
876
 
 
877
 
868
878
uint64_t getopt_ull_limit_value(uint64_t num, const struct my_option *optp,
869
 
                                 bool *fix)
 
879
                                bool *fix)
870
880
{
871
881
  bool adjusted= false;
872
882
  uint64_t old= num;
888
898
    }
889
899
    break;
890
900
  case GET_ULONG:
891
 
#if SIZEOF_LONG < SIZEOF_LONG_LONG
892
 
    if (num > (uint64_t) ULONG_MAX)
893
 
    {
894
 
      num= ((uint64_t) ULONG_MAX);
895
 
      adjusted= true;
896
 
    }
897
 
#endif
 
901
    if (num > (uint64_t) UINT32_MAX)
 
902
    {
 
903
      num= ((uint64_t) UINT32_MAX);
 
904
      adjusted= true;
 
905
    }
 
906
    break;
 
907
  case GET_SIZE:
 
908
    if (num > (uint64_t) SIZE_MAX)
 
909
    {
 
910
      num= ((uint64_t) SIZE_MAX);
 
911
      adjusted= true;
 
912
    }
898
913
    break;
899
914
  default:
900
915
    assert((optp->var_type & GET_TYPE_MASK) == GET_ULL);
987
1002
  case GET_LL:
988
1003
    *((int64_t*) variable)= (int64_t) value;
989
1004
    break;
 
1005
  case GET_SIZE:
 
1006
    *((size_t*) variable)= (size_t) value;
990
1007
  case GET_ULL:
991
1008
  case GET_SET:
992
1009
    *((uint64_t*) variable)=  (uint64_t) value;
1014
1031
    if ((char*) (intptr_t) value)
1015
1032
    {
1016
1033
      free((*(char**) variable));
1017
 
      *((char**) variable)= my_strdup((char*) (intptr_t) value, MYF(MY_WME));
 
1034
      char *tmpptr= strdup((char *) (intptr_t) value);
 
1035
      if (tmpptr != NULL)
 
1036
        *((char**) variable)= tmpptr;
1018
1037
    }
1019
1038
    break;
1020
1039
  default: /* dummy default to avoid compiler warnings */
1034
1053
*/
1035
1054
 
1036
1055
static void fini_one_value(const struct my_option *option, char **variable,
1037
 
                           int64_t value __attribute__ ((unused)))
 
1056
                           int64_t)
1038
1057
{
1039
1058
  switch ((option->var_type & GET_TYPE_MASK)) {
1040
1059
  case GET_STR_ALLOC:
1054
1073
}
1055
1074
 
1056
1075
 
1057
 
/* 
 
1076
/*
1058
1077
  initialize all variables to their default values
1059
1078
 
1060
1079
  SYNOPSIS
1151
1170
 
1152
1171
      while ((uint) (end - comment) > comment_space)
1153
1172
      {
1154
 
        for (line_end= comment + comment_space; *line_end != ' '; line_end--);
 
1173
        for (line_end= comment + comment_space; *line_end != ' '; line_end--)
 
1174
          {}
1155
1175
        for (; comment != line_end; comment++)
1156
1176
          putchar(*comment);
1157
1177
        comment++; /* skip the space, as a newline will take it's place now */
1236
1256
      case GET_ULONG:
1237
1257
        printf("%u\n", *((uint32_t*) value));
1238
1258
        break;
 
1259
      case GET_SIZE:
 
1260
        cout << value;
 
1261
        break;
1239
1262
      case GET_LL:
1240
1263
        printf("%s\n", llstr(*((int64_t*) value), buff));
1241
1264
        break;