diff options
-rw-r--r-- | include/my_getopt.h | 7 | ||||
-rw-r--r-- | myisam/myisamchk.c | 155 | ||||
-rw-r--r-- | mysys/getvar.c | 75 | ||||
-rw-r--r-- | mysys/my_getopt.c | 248 |
4 files changed, 246 insertions, 239 deletions
diff --git a/include/my_getopt.h b/include/my_getopt.h index fef8aacd75a..8321ad4cd1c 100644 --- a/include/my_getopt.h +++ b/include/my_getopt.h @@ -23,14 +23,15 @@ struct my_optarg }; -enum get_opt_var_type { GET_NO_ARG, GET_INT, GET_LL, GET_STR }; +enum get_opt_var_type { GET_NO_ARG, GET_LONG, GET_LL, GET_STR }; enum get_opt_arg_type { NO_ARG, OPT_ARG, REQUIRED_ARG }; struct my_option { const char *name; /* Name of the option */ const char *comment; /* option comment, for autom. --help */ - char *value; /* The variable value */ + gptr *value; /* The variable value */ + gptr *u_max_value; /* The user def. max variable value */ const char **str_values; /* Pointer to possible values */ enum get_opt_var_type var_type; enum get_opt_arg_type arg_type; @@ -41,6 +42,6 @@ struct my_option longlong sub_size; /* Subtract this from given value */ long block_size; /* Value should be a mult. of this */ int app_type; /* To be used by an application */ - my_bool changeable_var; /* If true, the option is a variable */ + my_bool opt_is_var; /* If true, the option is a variable */ }; diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index eedbb6af940..2bec695a7c0 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -142,31 +142,6 @@ int main(int argc, char **argv) #endif } /* main */ - -static CHANGEABLE_VAR changeable_vars[] = { - { "key_buffer_size",(long*) &check_param.use_buffers,(long) USE_BUFFER_INIT, - (long) MALLOC_OVERHEAD, (long) ~0L,(long) MALLOC_OVERHEAD,(long) IO_SIZE }, - { "myisam_block_size", (long*) &opt_myisam_block_size, - MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH, - 0, MI_MIN_KEY_BLOCK_LENGTH }, - { "read_buffer_size", (long*) &check_param.read_buffer_length,(long) READ_BUFFER_INIT, - (long) MALLOC_OVERHEAD,(long) ~0L,(long) MALLOC_OVERHEAD,(long) 1L }, - { "write_buffer_size", (long*) &check_param.write_buffer_length,(long) READ_BUFFER_INIT, - (long) MALLOC_OVERHEAD,(long) ~0L,(long) MALLOC_OVERHEAD,(long) 1L }, - { "sort_buffer_size",(long*) &check_param.sort_buffer_length,(long) SORT_BUFFER_INIT, - (long) (MIN_SORT_BUFFER+MALLOC_OVERHEAD),(long) ~0L, - (long) MALLOC_OVERHEAD,(long) 1L }, - { "sort_key_blocks",(long*) &check_param.sort_key_blocks,BUFFERS_WHEN_SORTING,4L,100L,0L, - 1L }, - { "decode_bits",(long*) &decode_bits,9L,4L,17L,0L,1L }, - { "ft_min_word_len", (long*) &ft_min_word_len, - 4, 1, HA_FT_MAXLEN, 0, 1 }, - { "ft_max_word_len", (long*) &ft_max_word_len, - HA_FT_MAXLEN, 10, HA_FT_MAXLEN, 0, 1 }, - { "ft_max_word_len_for_sort",(long*) &ft_max_word_len_for_sort, - 20, 4, HA_FT_MAXLEN, 0, 1 }, - { NullS,(long*) 0,0L,0L,0L,0L,0L,} }; - enum options { OPT_CHARSETS_DIR=256, OPT_SET_CHARSET,OPT_START_CHECK_POS, OPT_CORRECT_CHECKSUM, OPT_KEY_BUFFER_SIZE, OPT_MYISAM_BLOCK_SIZE, @@ -177,63 +152,63 @@ enum options { static struct my_option my_long_options[] = { - {"analyze", "", 0, 0, GET_NO_ARG, NO_ARG, 'a', 0, 0, 0, 0, 0, 0, 0}, - {"block-search", "", 0, 0, GET_LL, REQUIRED_ARG, 'b', 0, 0, 0, 0, 0, 0, 0}, - {"backup", "", 0, 0, GET_NO_ARG, NO_ARG, 'B', 0, 0, 0, 0, 0, 0, 0}, - {"character-sets-dir", "", 0, 0, GET_STR, REQUIRED_ARG, OPT_CHARSETS_DIR, 0, 0, 0, 0, 0, 0, 0}, + {"analyze", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'a', 0, 0, 0, 0, 0, 0, 0}, + {"block-search", "", 0, 0, 0, GET_LONG, REQUIRED_ARG, 'b', 0, 0, 0, 0, 0, 0, 0}, + {"backup", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'B', 0, 0, 0, 0, 0, 0, 0}, + {"character-sets-dir", "", 0, 0, 0, GET_STR, REQUIRED_ARG, OPT_CHARSETS_DIR, 0, 0, 0, 0, 0, 0, 0}, - {"check", "", 0, 0, GET_NO_ARG, NO_ARG, 'c', 0, 0, 0, 0, 0, 0, 0}, - {"check-only-changed", "", 0, 0, GET_NO_ARG, NO_ARG, 'C', 0, 0, 0, 0, 0, 0, 0}, + {"check", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'c', 0, 0, 0, 0, 0, 0, 0}, + {"check-only-changed", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'C', 0, 0, 0, 0, 0, 0, 0}, - {"correct-checksum", "", 0, 0, GET_NO_ARG, NO_ARG, OPT_CORRECT_CHECKSUM, 0, 0, 0, 0, 0, 0, 0}, + {"correct-checksum", "", 0, 0, 0, GET_NO_ARG, NO_ARG, OPT_CORRECT_CHECKSUM, 0, 0, 0, 0, 0, 0, 0}, #ifndef DBUG_OFF - {"debug", "", 0, 0, GET_STR, OPT_ARG, '#', 0, 0, 0, 0, 0, 0, 0}, + {"debug", "", 0, 0, 0, GET_STR, OPT_ARG, '#', 0, 0, 0, 0, 0, 0, 0}, #endif - {"description", "", 0, 0, GET_NO_ARG, NO_ARG, 'd', 0, 0, 0, 0, 0, 0, 0}, - {"data-file-length", "", 0, 0, GET_LL, REQUIRED_ARG, 'D', 0, 0, 0, 0, 0, 0, 0}, - {"extend-check", "", 0, 0, GET_NO_ARG, NO_ARG, 'e', 0, 0, 0, 0, 0, 0, 0}, - {"fast", "", 0, 0, GET_NO_ARG, NO_ARG, 'F', 0, 0, 0, 0, 0, 0, 0}, - {"force", "", 0, 0, GET_NO_ARG, NO_ARG, 'f', 0, 0, 0, 0, 0, 0, 0}, - {"help", "", 0, 0, GET_NO_ARG, NO_ARG, '?', 0, 0, 0, 0, 0, 0, 0}, - {"information", "", 0, 0, GET_NO_ARG, NO_ARG, 'i', 0, 0, 0, 0, 0, 0, 0}, - {"keys-used", "", 0, 0, GET_LL, REQUIRED_ARG, 'k', 0, 0, 0, 0, 0, 0, 0}, - {"medium-check", "", 0, 0, GET_NO_ARG, NO_ARG, 'm', 0, 0, 0, 0, 0, 0, 0}, - {"quick", "", 0, 0, GET_NO_ARG, NO_ARG, 'q', 0, 0, 0, 0, 0, 0, 0}, - {"read-only", "", 0, 0, GET_NO_ARG, NO_ARG, 'T', 0, 0, 0, 0, 0, 0, 0}, - {"recover", "", 0, 0, GET_NO_ARG, NO_ARG, 'r', 0, 0, 0, 0, 0, 0, 0}, - {"safe-recover", "", 0, 0, GET_NO_ARG, NO_ARG, 'o', 0, 0, 0, 0, 0, 0, 0}, - {"start-check-pos", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_START_CHECK_POS, 0, 0, 0, 0, 0, 0, 0}, - {"set-auto-increment", "", 0, 0, GET_LL, OPT_ARG, 'A', 0, 0, 0, 0, 0, 0, 0}, - {"set-character-set", "", 0, 0, GET_STR, REQUIRED_ARG, OPT_SET_CHARSET, 0, 0, 0, 0, 0, 0, 0}, - {"set-variable", "", 0, 0, GET_STR, REQUIRED_ARG, 'O', 0, 0, 0, 0, 0, 0, 0}, - {"silent", "", 0, 0, GET_NO_ARG, NO_ARG, 's', 0, 0, 0, 0, 0, 0, 0}, - {"sort-index", "", 0, 0, GET_NO_ARG, NO_ARG, 'S', 0, 0, 0, 0, 0, 0, 0}, - {"sort-records", "", 0, 0, GET_INT, REQUIRED_ARG, 'R', 0, 0, 0, 0, 0, 0, 0}, - {"sort-recover", "", 0, 0, GET_NO_ARG, NO_ARG, 'n', 0, 0, 0, 0, 0, 0, 0}, - {"tmpdir", "", 0, 0, GET_STR, REQUIRED_ARG, 't', 0, 0, 0, 0, 0, 0, 0}, - {"update-state", "", 0, 0, GET_NO_ARG, NO_ARG, 'U', 0, 0, 0, 0, 0, 0, 0}, - {"unpack", "", 0, 0, GET_NO_ARG, NO_ARG, 'u', 0, 0, 0, 0, 0, 0, 0}, - {"verbose", "", 0, 0, GET_NO_ARG, NO_ARG, 'v', 0, 0, 0, 0, 0, 0, 0}, - {"version", "", 0, 0, GET_NO_ARG, NO_ARG, 'V', 0, 0, 0, 0, 0, 0, 0}, - {"wait", "", 0, 0, GET_NO_ARG, NO_ARG, 'w', 0, 0, 0, 0, 0, 0, 0}, + {"description", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'd', 0, 0, 0, 0, 0, 0, 0}, + {"data-file-length", "", 0, 0, 0, GET_LONG, REQUIRED_ARG, 'D', 0, 0, 0, 0, 0, 0, 0}, + {"extend-check", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'e', 0, 0, 0, 0, 0, 0, 0}, + {"fast", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'F', 0, 0, 0, 0, 0, 0, 0}, + {"force", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'f', 0, 0, 0, 0, 0, 0, 0}, + {"help", "", 0, 0, 0, GET_NO_ARG, NO_ARG, '?', 0, 0, 0, 0, 0, 0, 0}, + {"information", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'i', 0, 0, 0, 0, 0, 0, 0}, + {"keys-used", "", 0, 0, 0, GET_LONG, REQUIRED_ARG, 'k', 0, 0, 0, 0, 0, 0, 0}, + {"medium-check", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'm', 0, 0, 0, 0, 0, 0, 0}, + {"quick", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'q', 0, 0, 0, 0, 0, 0, 0}, + {"read-only", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'T', 0, 0, 0, 0, 0, 0, 0}, + {"recover", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'r', 0, 0, 0, 0, 0, 0, 0}, + {"safe-recover", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'o', 0, 0, 0, 0, 0, 0, 0}, + {"start-check-pos", "", 0, 0, 0, GET_LONG, REQUIRED_ARG, OPT_START_CHECK_POS, 0, 0, 0, 0, 0, 0, 0}, + {"set-auto-increment", "", 0, 0, 0, GET_LONG, OPT_ARG, 'A', 0, 0, 0, 0, 0, 0, 0}, + {"set-character-set", "", 0, 0, 0, GET_STR, REQUIRED_ARG, OPT_SET_CHARSET, 0, 0, 0, 0, 0, 0, 0}, + {"set-variable", "", 0, 0, 0, GET_STR, REQUIRED_ARG, 'O', 0, 0, 0, 0, 0, 0, 0}, + {"silent", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 's', 0, 0, 0, 0, 0, 0, 0}, + {"sort-index", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'S', 0, 0, 0, 0, 0, 0, 0}, + {"sort-records", "", 0, 0, 0, GET_LONG, REQUIRED_ARG, 'R', 0, 0, 0, 0, 0, 0, 0}, + {"sort-recover", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'n', 0, 0, 0, 0, 0, 0, 0}, + {"tmpdir", "", 0, 0, 0, GET_STR, REQUIRED_ARG, 't', 0, 0, 0, 0, 0, 0, 0}, + {"update-state", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'U', 0, 0, 0, 0, 0, 0, 0}, + {"unpack", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'u', 0, 0, 0, 0, 0, 0, 0}, + {"verbose", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'v', 0, 0, 0, 0, 0, 0, 0}, + {"version", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'V', 0, 0, 0, 0, 0, 0, 0}, + {"wait", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'w', 0, 0, 0, 0, 0, 0, 0}, /* variables begin here */ - { "key_buffer_size", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_KEY_BUFFER_SIZE, 0, 0, 0, 0, 0, 0, 1}, - { "myisam_block_size", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_MYISAM_BLOCK_SIZE, 0, 0, 0, 0, 0, 0, 1}, - { "read_buffer_size", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_READ_BUFFER_SIZE, 0, 0, 0, 0, 0, 0, 1}, - { "write_buffer_size", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_WRITE_BUFFER_SIZE, 0, 0, 0, 0, 0, 0, 1}, - { "sort_buffer_size", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_SORT_BUFFER_SIZE, 0, 0, 0, 0, 0, 0, 1}, - { "sort_key_blocks", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_SORT_KEY_BLOCKS, 0, 0, 0, 0, 0, 0, 1}, - { "decode_bits", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_DECODE_BITS, 0, 0, 0, 0, 0, 0, 1}, - { "ft_min_word_len", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_FT_MIN_WORD_LEN, 0, 0, 0, 0, 0, 0, 1}, - { "ft_max_word_len", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_FT_MAX_WORD_LEN, 0, 0, 0, 0, 0, 0, 1}, - { "ft_max_word_len_for_sort", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_FT_MAX_WORD_LEN_FOR_SORT, 0, 0, 0, 0, 0, 0, 1}, + { "key_buffer_size", "", (gptr*) &check_param.use_buffers, (gptr*) &check_param.use_buffers, 0, GET_LONG, REQUIRED_ARG, OPT_KEY_BUFFER_SIZE, (long) USE_BUFFER_INIT, (long) MALLOC_OVERHEAD, (long) ~0L, (long) MALLOC_OVERHEAD, (long) IO_SIZE, 0, 1}, + { "myisam_block_size", "", (gptr*) &opt_myisam_block_size, (gptr*) &opt_myisam_block_size, 0, GET_LONG, REQUIRED_ARG, OPT_MYISAM_BLOCK_SIZE, MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH, 0, MI_MIN_KEY_BLOCK_LENGTH, 0, 1}, + { "read_buffer_size", "", (gptr*) &check_param.read_buffer_length, (gptr*) &check_param.read_buffer_length, 0, GET_LONG, REQUIRED_ARG, OPT_READ_BUFFER_SIZE, (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD, (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0, 1}, + { "write_buffer_size", "", (gptr*) &check_param.write_buffer_length, (gptr*) &check_param.write_buffer_length, 0, GET_LONG, REQUIRED_ARG, OPT_WRITE_BUFFER_SIZE, (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD, (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0, 1}, + { "sort_buffer_size", "", (gptr*) &check_param.sort_buffer_length, (gptr*) &check_param.sort_buffer_length, 0, GET_LONG, REQUIRED_ARG, OPT_SORT_BUFFER_SIZE, (long) SORT_BUFFER_INIT, (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD), (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0, 1}, + { "sort_key_blocks", "", (gptr*) &check_param.sort_key_blocks, (gptr*) &check_param.sort_key_blocks, 0, GET_LONG, REQUIRED_ARG, OPT_SORT_KEY_BLOCKS, BUFFERS_WHEN_SORTING, 4L, 100L, 0L, 1L, 0, 1}, + { "decode_bits", "", (gptr*) &decode_bits, (gptr*) &decode_bits, 0, GET_LONG, REQUIRED_ARG, OPT_DECODE_BITS, 9L, 4L, 17L, 0L, 1L, 0, 1}, + { "ft_min_word_len", "", (gptr*) &ft_min_word_len, (gptr*) &ft_min_word_len, 0, GET_LONG, REQUIRED_ARG, OPT_FT_MIN_WORD_LEN, 4, 1, HA_FT_MAXLEN, 0, 1, 0, 1}, + { "ft_max_word_len", "", (gptr*) &ft_max_word_len, (gptr*) &ft_max_word_len, 0, GET_LONG, REQUIRED_ARG, OPT_FT_MAX_WORD_LEN, HA_FT_MAXLEN, 10, HA_FT_MAXLEN, 0, 1, 0, 1}, + { "ft_max_word_len_for_sort", "", (gptr*) &ft_max_word_len_for_sort, (gptr*) &ft_max_word_len_for_sort, 0, GET_LONG, REQUIRED_ARG, OPT_FT_MAX_WORD_LEN_FOR_SORT, 20, 4, HA_FT_MAXLEN, 0, 1, 0, 1}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; static void print_version(void) { - printf("%s Ver 2.1 for %s at %s\n", my_progname, SYSTEM_TYPE, + printf("%s Ver 2.2 for %s at %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE); } @@ -323,10 +298,14 @@ static void usage(void) print_defaults("my",load_default_groups); printf("\nPossible variables for option --set-variable (-O) are:\n"); - for (i=0; changeable_vars[i].name ; i++) - printf("%-20s current value: %lu\n", - changeable_vars[i].name, - *changeable_vars[i].varptr); + for (i=0; my_long_options[i].name ; i++) + { + if (!my_long_options[i].opt_is_var) + continue; + printf("%-20s current value: %lu\n", my_long_options[i].name, + *my_long_options[i].value); + } + } @@ -417,27 +396,6 @@ static my_bool get_one_option(int optid, const struct my_option *opt, check_param.testflag|= T_VERBOSE; check_param.verbose++; break; - case 'O': - /* this is a temporary fix for variables to work until my_getopt */ - /* can my_set_changeable_vars */ - case OPT_KEY_BUFFER_SIZE: - case OPT_MYISAM_BLOCK_SIZE: - case OPT_READ_BUFFER_SIZE: - case OPT_WRITE_BUFFER_SIZE: - case OPT_SORT_BUFFER_SIZE: - case OPT_SORT_KEY_BLOCKS: - case OPT_DECODE_BITS: - case OPT_FT_MIN_WORD_LEN: - case OPT_FT_MAX_WORD_LEN: - case OPT_FT_MAX_WORD_LEN_FOR_SORT: - end= buff; - end= strmov(strmov(strmov(end, opt->name), "="), argument); - if (set_changeable_var(buff, changeable_vars)) - { - usage(); - exit(1); - } - break; case 'R': /* Sort records */ old_testflag=check_param.testflag; check_param.testflag|= T_SORT_RECORDS; @@ -492,11 +450,10 @@ static my_bool get_one_option(int optid, const struct my_option *opt, static void get_options(register int *argc,register char ***argv) { - int c,option_index=0; + int c, option_index=0; - load_defaults("my",load_default_groups,argc,argv); + load_defaults("my", load_default_groups, argc, argv); default_argv= *argv; - set_all_changeable_vars(changeable_vars); if (isatty(fileno(stdout))) check_param.testflag|=T_WRITE_LOOP; diff --git a/mysys/getvar.c b/mysys/getvar.c index 1a2adc10e62..bb470423c57 100644 --- a/mysys/getvar.c +++ b/mysys/getvar.c @@ -109,78 +109,3 @@ my_bool set_changeable_var(my_string str,CHANGEABLE_VAR *vars) } DBUG_RETURN(1); } - -my_bool my_set_changeable_var(my_string str, const struct my_option *vars) -{ - char endchar; - my_string end; - DBUG_ENTER("my_set_changeable_var"); - DBUG_PRINT("enter",("%s",str)); - - if (str) - { - if (!(end=strchr(str,'='))) - fprintf(stderr,"Can't find '=' in expression '%s' to option -O\n",str); - else - { - uint length,found_count=0; - const struct my_option *var, *found; - my_string var_end; - const char *name; - longlong num; - - /* Skip end space from variable */ - for (var_end=end ; end > str && isspace(var_end[-1]) ; var_end--) ; - length=(uint) (var_end-str); - /* Skip start space from argument */ - for (end++ ; isspace(*end) ; end++) ; - - for (var= vars, found= 0; (name= var->name); var++) - { - if (var->changeable_var) - { - if (!my_casecmp(name, str, length)) - { - found= var; found_count++; - if (!name[length]) - { - found_count=1; - break; - } - } - } - } - if (found_count == 0) - { - fprintf(stderr,"No variable match for: -O '%s'\n",str); - DBUG_RETURN(1); - } - if (found_count > 1) - { - fprintf(stderr,"Variable prefix '%*s' is not unique\n",length,str); - DBUG_RETURN(1); - } - - num=strtoll(end, (char **)NULL, 10); endchar=strend(end)[-1]; - if (endchar == 'k' || endchar == 'K') - num*=1024; - else if (endchar == 'm' || endchar == 'M') - num*=1024L*1024L; - else if (endchar == 'g' || endchar == 'G') - num*=1024L*1024L*1024L; - else if (!isdigit(endchar)) - { - fprintf(stderr,"Unknown prefix used for variable value '%s'\n",str); - DBUG_RETURN(1); - } - if (num < (longlong) found->min_value) - num=(longlong) found->min_value; - else if (num > 0 && (ulonglong) num > (ulonglong) (ulong) found->max_value) - num=(longlong) (ulong) found->max_value; - num=((num- (longlong) found->sub_size) / (ulonglong) found->block_size); - /* (*found->varptr)= (long) (num*(ulonglong) found->block_size);*/ - DBUG_RETURN(0); - } - } - DBUG_RETURN(1); -} diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index afe3da214bf..63d949e843b 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -21,22 +21,36 @@ #include <my_getopt.h> #include <assert.h> -static int sortopt (int *argc, char ***argv); static int findopt (char *optpat, uint length, const struct my_option **opt_res, char **ffname); +static my_bool compare_strings (register const char *s, register const char *t, + uint length); +static longlong getopt_ll (char *arg, const struct my_option *optp, int *err); +static void init_variables(const struct my_option *options); -#define DISABLE_OPTION_COUNT 2 +#define DISABLE_OPTION_COUNT 2 -static char *special_opt_prefix[] = {"skip", "disable", "enable", 0}; +#define ERR_UNKNOWN_OPTION 1 +#define ERR_AMBIGUOUS_OPTION 2 +#define ERR_NO_ARGUMENT_ALLOWED 3 +#define ERR_ARGUMENT_REQUIRED 4 +#define ERR_VAR_PREFIX_NOT_UNIQUE 5 +#define ERR_UNKNOWN_VARIABLE 6 +#define ERR_MUST_BE_VARIABLE 7 +#define ERR_UNKNOWN_SUFFIX 8 +static char *special_opt_prefix[]= {"skip", "disable", "enable", "maximum", 0}; -/* function: handle_options - Sort options; put options first, until special end of options (--), or - until end of argv. Parse options; check that the given option matches with - one of the options in struct 'my_option', return error in case of ambiguous - or unknown option. Check that option was given an argument if it requires - one. Call function 'get_one_option()' once for each option. + +/* + function: handle_options + + Sort options; put options first, until special end of options (--), or + until end of argv. Parse options; check that the given option matches with + one of the options in struct 'my_option', return error in case of ambiguous + or unknown option. Check that option was given an argument if it requires + one. Call function 'get_one_option()' once for each option. */ extern int handle_options (int *argc, char ***argv, const struct my_option *longopts, @@ -44,25 +58,29 @@ extern int handle_options (int *argc, char ***argv, const struct my_option *, char *)) { - uint opt_found, argvpos = 0, length, spec_len, i; - my_bool end_of_options = 0, must_be_var = 0; - char *progname = *(*argv), **pos, *optend, *prev_found; + uint opt_found, argvpos= 0, length, spec_len, i; + int err; + my_bool end_of_options= 0, must_be_var, set_maximum_value; + char *progname= *(*argv), **pos, *optend, *prev_found; const struct my_option *optp; - (*argc)--; - (*argv)++; - for (pos = *argv; *pos; pos++) + (*argc)--; /* Skip the program name */ + (*argv)++; /* --- || ---- */ + init_variables(longopts); + for (pos= *argv; *pos; pos++) { char *cur_arg= *pos; if (*cur_arg == '-' && *(cur_arg + 1) && !end_of_options) // must be opt. { - char *argument = 0; + char *argument= 0; must_be_var= 0; + set_maximum_value= 0; // check for long option, or --set-variable (-O) if (*(cur_arg + 1) == '-' || *(cur_arg + 1) == 'O') { - if (*(cur_arg + 1) == 'O' || !strncmp(cur_arg, "--set-variable", 14)) + if (*(cur_arg + 1) == 'O' || + !compare_strings(cur_arg, "--set-variable", 14)) { must_be_var= 1; @@ -76,7 +94,7 @@ extern int handle_options (int *argc, char ***argv, { fprintf(stderr, "%s: Option '-O' requires an argument\n", progname); - return 4; + return ERR_ARGUMENT_REQUIRED; } pos++; cur_arg= *pos; @@ -94,7 +112,7 @@ extern int handle_options (int *argc, char ***argv, fprintf(stderr, "%s: Option '--set-variable' requires an argument\n", progname); - return 4; + return ERR_ARGUMENT_REQUIRED; } } else if (*cur_arg) // garbage, or another option. break out @@ -110,7 +128,7 @@ extern int handle_options (int *argc, char ***argv, fprintf(stderr, "%s: Option '--set-variable' requires an argument\n", progname); - return 4; + return ERR_ARGUMENT_REQUIRED; } pos++; cur_arg= *pos; @@ -122,37 +140,39 @@ extern int handle_options (int *argc, char ***argv, { if (!*(cur_arg + 2)) // '--' means end of options, look no further { - end_of_options = 1; + end_of_options= 1; (*argc)--; continue; } cur_arg+= 2; // skip the double dash } - for (optend = cur_arg; *optend && *optend != '='; optend++) ; - length = optend - cur_arg; + for (optend= cur_arg; *optend && *optend != '='; optend++) ; + length= optend - cur_arg; /* Find first the right option. Return error in case of an ambiguous, or unknown option */ - optp = longopts; - if (!(opt_found = findopt(cur_arg, length, &optp, &prev_found))) + optp= longopts; + if (!(opt_found= findopt(cur_arg, length, &optp, &prev_found))) { /* Didn't find any matching option. Let's see if someone called option with a special option prefix */ - if (*optend != '=' && !must_be_var) + if (!must_be_var) { - for (i = 0; special_opt_prefix[i]; i++) + if (*optend == '=') + must_be_var= 1; + for (i= 0; special_opt_prefix[i]; i++) { - spec_len = strlen(special_opt_prefix[i]); - if (!strncmp(special_opt_prefix[i], cur_arg, spec_len) && + spec_len= strlen(special_opt_prefix[i]); + if (!compare_strings(special_opt_prefix[i], cur_arg, spec_len) && cur_arg[spec_len] == '-') { // We were called with a special prefix, we can reuse opt_found cur_arg += (spec_len + 1); - if ((opt_found = findopt(cur_arg, length - (spec_len + 1), - &optp, &prev_found))) + if ((opt_found= findopt(cur_arg, length - (spec_len + 1), + &optp, &prev_found))) { if (opt_found > 1) { @@ -160,12 +180,17 @@ extern int handle_options (int *argc, char ***argv, "%s: ambiguous option '--%s-%s' (--%s-%s)\n", progname, special_opt_prefix[i], cur_arg, special_opt_prefix[i], prev_found); - return 2; + return ERR_AMBIGUOUS_OPTION; } if (i < DISABLE_OPTION_COUNT) optend= "=0"; - else // enable + else if (!compare_strings(special_opt_prefix[i],"enable",6)) optend= "=1"; + else if (!compare_strings(special_opt_prefix[i],"maximum",7)) + { + set_maximum_value= 1; + must_be_var= 1; + } break; // note break from the inner loop, main loop continues } } @@ -177,13 +202,13 @@ extern int handle_options (int *argc, char ***argv, { fprintf(stderr, "%s: unknown variable '%s'\n", progname, cur_arg); - return 7; + return ERR_UNKNOWN_VARIABLE; } else { fprintf(stderr, "%s: unknown option '--%s'\n", progname, cur_arg); - return 1; + return ERR_UNKNOWN_OPTION; } } } @@ -193,26 +218,26 @@ extern int handle_options (int *argc, char ***argv, { fprintf(stderr, "%s: variable prefix '%s' is not unique\n", progname, cur_arg); - return 6; + return ERR_VAR_PREFIX_NOT_UNIQUE; } else { fprintf(stderr, "%s: ambiguous option '--%s' (%s, %s)\n", progname, cur_arg, prev_found, optp->name); - return 2; + return ERR_AMBIGUOUS_OPTION; } } - if (must_be_var && !optp->changeable_var) + if (must_be_var && !optp->opt_is_var) { fprintf(stderr, "%s: the argument to -O must be a variable\n", progname); - return 8; + return ERR_MUST_BE_VARIABLE; } if (optp->arg_type == NO_ARG && *optend == '=') { fprintf(stderr, "%s: option '--%s' cannot take an argument\n", progname, optp->name); - return 3; + return ERR_NO_ARGUMENT_ALLOWED; } else if (optp->arg_type == REQUIRED_ARG && !*optend) { @@ -221,21 +246,21 @@ extern int handle_options (int *argc, char ***argv, { fprintf(stderr, "%s: option '--%s' requires an argument\n", progname, optp->name); - return 4; + return ERR_ARGUMENT_REQUIRED; } pos++; - argument = *pos; + argument= *pos; (*argc)--; } else if (*optend == '=') - argument = *(optend + 1) ? optend + 1 : ""; + argument= *(optend + 1) ? optend + 1 : ""; } else // must be short option { my_bool skip; - for (skip = 0, optend = (cur_arg + 1); *optend && !skip; optend++) + for (skip= 0, optend= (cur_arg + 1); *optend && !skip; optend++) { - for (optp = longopts; optp->id ; optp++) + for (optp= longopts; optp->id ; optp++) { if (optp->id == (int) (uchar) *optend) { @@ -244,12 +269,12 @@ extern int handle_options (int *argc, char ***argv, { if (*(optend + 1)) { - argument = (optend + 1); + argument= (optend + 1); /* The rest of the option is option argument This is in effect a jump out of this loop */ - skip = 1; + skip= 1; } else if (optp->arg_type == REQUIRED_ARG) { @@ -258,10 +283,10 @@ extern int handle_options (int *argc, char ***argv, { fprintf(stderr, "%s: option '-%c' requires an argument\n", progname, optp->id); - return 4; + return ERR_ARGUMENT_REQUIRED; } pos++; - argument = *pos; + argument= *pos; (*argc)--; } } @@ -272,23 +297,41 @@ extern int handle_options (int *argc, char ***argv, } } } - get_one_option(optp->id, optp, argument); + if (optp->opt_is_var) + { + gptr *result_pos= (set_maximum_value) ? + optp->u_max_value : optp->value; + if (optp->var_type == GET_LONG) + *((long*) result_pos)= (long) getopt_ll(argument, optp, &err); + else if (optp->var_type == GET_LL) + *((longlong*) result_pos)= getopt_ll(argument, optp, &err); + else if (optp->var_type == GET_STR) + *((char**) result_pos)= argument; + if (err) + return ERR_UNKNOWN_SUFFIX; + } + else + get_one_option(optp->id, optp, argument); + (*argc)--; // option handled (short or long), decrease argument count } else // non-option found - (*argv)[argvpos++] = cur_arg; + (*argv)[argvpos++]= cur_arg; } return 0; } -/* function: findopt - Arguments: opt_pattern, length of opt_pattern, opt_struct, first found - name (ffname) - Go through all options in the my_option struct. Return number - of options found that match the pattern and in the argument - list the option found, if any. In case of ambiguous option, store - the name in ffname argument +/* + function: findopt + + Arguments: opt_pattern, length of opt_pattern, opt_struct, first found + name (ffname) + + Go through all options in the my_option struct. Return number + of options found that match the pattern and in the argument + list the option found, if any. In case of ambiguous option, store + the name in ffname argument */ static int findopt (char *optpat, uint length, const struct my_option **opt_res, @@ -297,13 +340,13 @@ static int findopt (char *optpat, uint length, int count; struct my_option *opt= (struct my_option *) *opt_res; - for (count = 0; opt->id; opt++) + for (count= 0; opt->id; opt++) { - if (!strncmp(opt->name, optpat, length)) // match found + if (!compare_strings(opt->name, optpat, length)) // match found { - (*opt_res) = opt; + (*opt_res)= opt; if (!count) - *ffname = (char *) opt->name; // we only need to know one prev + *ffname= (char *) opt->name; // we only need to know one prev if (length == strlen(opt->name)) // exact match return 1; count++; @@ -311,3 +354,84 @@ static int findopt (char *optpat, uint length, } return count; } + + +/* + function: compare_strings + + Works like strncmp, other than 1.) considers '-' and '_' the same. + 2.) Returns -1 if strings differ, 0 if they are equal +*/ +static my_bool compare_strings(register const char *s, register const char *t, + uint length) +{ + char const *end= s + length; + for (;s != end ; s++, t++) + { + if ((*s != '-' ? *s : '_') != (*t != '-' ? *t : '_')) + return 1; + } + return 0; +} + + +/* + function: getopt_ll + + Evaluates and returns the value that user gave as an argument + to a variable. Recognizes (case insensitive) K as KILO, M as MEGA + and G as GIGA bytes. Some values must be in certain blocks, as + defined in the given my_option struct, this function will check + that those values are honored. + In case of an error, set error value in *err. +*/ +static longlong getopt_ll (char *arg, const struct my_option *optp, int *err) +{ + char *endchar; + longlong num; + + *err= 0; + num= strtoll(arg, &endchar, 10); + if (*endchar == 'k' || *endchar == 'K') + num*= 1024L; + else if (*endchar == 'm' || *endchar == 'M') + num*= 1024L * 1024L; + else if (*endchar == 'g' || *endchar == 'G') + num*= 1024L * 1024L * 1024L; + else if (*endchar) + { + fprintf(stderr, + "Unknown suffix '%c' used for variable '%s' (value '%s')\n", + *endchar, optp->name, arg); + *err= 1; + } + if (num < (longlong) optp->min_value) + num= (longlong) optp->min_value; + else if (num > 0 && (ulonglong) num > (ulonglong) (ulong) optp->max_value) + num= (longlong) (ulong) optp->max_value; + num= ((num - (longlong) optp->sub_size) / (ulonglong) optp->block_size); + + return (longlong) (num * (ulonglong) optp->block_size); +} + + +/* + function: init_variables + + initialize all variables to their default values +*/ +static void init_variables(const struct my_option *options) +{ + for ( ; options->name ; options++) + { + if (options->opt_is_var) + { + if (options->var_type == GET_LONG) + *((long*) options->u_max_value)= *((long*) options->value)= + options->def_value; + else if (options->var_type == GET_LL) + *((longlong*) options->u_max_value)= *((longlong*) options->value)= + options->def_value; + } + } +} |