diff options
author | unknown <monty@hundin.mysql.fi> | 2002-02-07 18:28:24 +0200 |
---|---|---|
committer | unknown <monty@hundin.mysql.fi> | 2002-02-07 18:28:24 +0200 |
commit | 6340283614f9f5cc4b9212ec5affa177b3f71711 (patch) | |
tree | 8b894bd9b1882b46142db45408b9ada1f976f566 | |
parent | bb41d5308bfbd1b46a75e275bf5599a5e3bfb032 (diff) | |
parent | 90a76d688ab49832f51462dbc906b4c11b4a09fb (diff) | |
download | mariadb-git-6340283614f9f5cc4b9212ec5affa177b3f71711.tar.gz |
Merge work:/home/bk/mysql-4.0 into hundin.mysql.fi:/my/bk/mysql-4.0
-rw-r--r-- | include/my_getopt.h | 3 | ||||
-rw-r--r-- | myisam/myisamchk.c | 317 | ||||
-rw-r--r-- | mysys/my_getopt.c | 311 | ||||
-rw-r--r-- | support-files/my-huge.cnf.sh | 2 | ||||
-rw-r--r-- | support-files/my-large.cnf.sh | 2 | ||||
-rw-r--r-- | support-files/my-medium.cnf.sh | 2 | ||||
-rw-r--r-- | support-files/my-small.cnf.sh | 2 |
7 files changed, 447 insertions, 192 deletions
diff --git a/include/my_getopt.h b/include/my_getopt.h index a1a052ac8e2..2e40fb8ffaa 100644 --- a/include/my_getopt.h +++ b/include/my_getopt.h @@ -42,7 +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 opt_is_var; /* If true, the option is a variable */ }; extern int handle_options (int *argc, char ***argv, @@ -50,3 +49,5 @@ extern int handle_options (int *argc, char ***argv, my_bool (*get_one_option)(int, const struct my_option *, char *)); +extern void my_print_help(const struct my_option *options); +extern void my_print_variables(const struct my_option *options); diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index c1eb2fdf53f..20aaaf6ac8e 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -152,71 +152,145 @@ enum options { static struct my_option my_long_options[] = { - {"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", "", (gptr*) &set_charset_name, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0, 0, 1}, - - {"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, 0, GET_NO_ARG, NO_ARG, OPT_CORRECT_CHECKSUM, 0, 0, 0, 0, 0, 0, 0}, + {"analyze", + "Analyze distribution of keys. Will make some joins in MySQL faster. You can check the calculated distribution.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'a', 0, 0, + 0, 0, 0, 0}, + {"block-search", "No help available.", 0, 0, 0, GET_LONG, REQUIRED_ARG, 'b', + 0, 0, 0, 0, 0, 0}, + {"backup", "Make a backup of the .MYD file as 'filename-time.BAK'", 0, 0, 0, + GET_NO_ARG, NO_ARG, 'B', 0, 0, 0, 0, 0, 0}, + {"character-sets-dir", "Directory where character sets are.", + (gptr*) &set_charset_name, 0, 0, GET_STR, REQUIRED_ARG, OPT_CHARSETS_DIR, 0, + 0, 0, 0, 0, 0}, + {"check", "Check table for errors.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'c', 0, 0, + 0, 0, 0, 0}, + {"check-only-changed", + "Check only tables that has changed since last check.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 'C', 0, 0, 0, 0, 0, 0}, + {"correct-checksum", "Correct checksum information for table.", 0, 0, 0, + GET_NO_ARG, NO_ARG, OPT_CORRECT_CHECKSUM, 0, 0, 0, 0, 0, 0}, #ifndef DBUG_OFF - {"debug", "", 0, 0, 0, GET_STR, OPT_ARG, '#', 0, 0, 0, 0, 0, 0, 0}, + {"debug", "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0, + GET_STR, OPT_ARG, '#', 0, 0, 0, 0, 0, 0}, #endif - {"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", "", (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, 0} + {"description", "Prints some information about table.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 'd', 0, 0, 0, 0, 0, 0}, + {"data-file-length", + "Max length of data file (when recreating data-file when it's full).", + (gptr*) &check_param.max_data_file_length, + (gptr*) &check_param.max_data_file_length, 0, GET_LONG, REQUIRED_ARG, 'D', + 0, 0, 0, 0, 0, 0}, + {"extend-check", + "Try to recover every possible row from the data file. Normally this will also find a lot of garbage rows; Don't use this option if you are not totally desperate.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'e', 0, 0, 0, 0, 0, 0}, + {"fast", "Check only tables that hasn't been closed properly.", 0, 0, 0, + GET_NO_ARG, NO_ARG, 'F', 0, 0, 0, 0, 0, 0}, + {"force", + "Restart with -r if there are any errors in the table. States will be updated as with --update-state.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'f', 0, 0, 0, 0, 0, + 0}, + {"help", "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, '?', 0, + 0, 0, 0, 0, 0}, + {"information", "Print statistics information about table that is checked.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 'i', 0, 0, 0, 0, 0, 0}, + {"keys-used", "Tell MyISAM to update only some specific keys. # is a bit mask of which keys to use. This can be used to get faster inserts!", + (gptr*) &check_param.keys_in_use, (gptr*) &check_param.keys_in_use, 0, + GET_LONG, REQUIRED_ARG, 'k', 0, 0, 0, 0, 0, 0}, + {"medium-check", + "Faster than extended-check, but only finds 99.99% of all errors. Should be good enough for most cases.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'm', 0, 0, 0, 0, 0, + 0}, + {"quick", "Faster repair by not modifying the data file.", 0, 0, 0, + GET_NO_ARG, NO_ARG, 'q', 0, 0, 0, 0, 0, 0}, + {"read-only", "Don't mark table as checked.", 0, 0, 0, GET_NO_ARG, NO_ARG, + 'T', 0, 0, 0, 0, 0, 0}, + {"recover", + "Can fix almost anything except unique keys that aren't unique.", 0, 0, 0, + GET_NO_ARG, NO_ARG, 'r', 0, 0, 0, 0, 0, 0}, + {"safe-recover", + "Uses old recovery method; Slower than '-r' but can handle a couple of cases where '-r' reports that it can't fix the data file.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 'o', 0, 0, 0, 0, 0, 0}, + {"start-check-pos", "No help available.", 0, 0, 0, GET_LONG, REQUIRED_ARG, + OPT_START_CHECK_POS, 0, 0, 0, 0, 0, 0}, + {"set-auto-increment", + "Force auto_increment to start at this or higher value. If no value is given, then sets the next auto_increment value to the highest used value for the auto key + 1.", (gptr*) &check_param.auto_increment_value, + (gptr*) &check_param.auto_increment_value, 0, GET_LONG, OPT_ARG, 'A', 0, 0, + 0, 0, 0, 0}, + {"set-character-set", "Change the character set used by the index", 0, 0, 0, + GET_STR, REQUIRED_ARG, OPT_SET_CHARSET, 0, 0, 0, 0, 0, 0}, + {"set-variable", "Change the value of a variable. Please note that this option is depricated; you can set variables directly with --variable-name=value.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 'O', 0, 0, 0, 0, 0, 0}, + {"silent", + "Only print errors. One can use two -s to make myisamchk very silent.", 0, + 0, 0, GET_NO_ARG, NO_ARG, 's', 0, 0, 0, 0, 0, 0}, + {"sort-index", + "Sort index blocks. This speeds up 'read-next' in applications.", 0, 0, 0, + GET_NO_ARG, NO_ARG, 'S', 0, 0, 0, 0, 0, 0}, + {"sort-records", + "Sort records according to an index. This makes your data much more localized and may speed up things. (It may be VERY slow to do a sort the first time!)", + (gptr*) &check_param.opt_sort_key, (gptr*) &check_param.opt_sort_key, 0, + GET_LONG, REQUIRED_ARG, 'R', 0, 0, 0, 0, 0, 0}, + {"sort-recover", + "Force recovering with sorting even if the temporary file was very big.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 'n', 0, 0, 0, 0, 0, 0}, + {"tmpdir", "Path for temporary files.", (gptr*) &check_param.tmpdir, 0, 0, + GET_STR, REQUIRED_ARG, 't', 0, 0, 0, 0, 0, 0}, + {"update-state", "Mark tables as crashed if any errors were found.", 0, 0, + 0, GET_NO_ARG, NO_ARG, 'U', 0, 0, 0, 0, 0, 0}, + {"unpack", "Unpack file packed with myisampack.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 'u', 0, 0, 0, 0, 0, 0}, + {"verbose", + "Print more information. This can be used with --describe and --check. Use many -v for more verbosity!", 0, 0, 0, GET_NO_ARG, NO_ARG, 'v', 0, 0, 0, 0, 0, + 0}, + {"version", "Print version and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'V', 0, + 0, 0, 0, 0, 0}, + {"wait", "Wait if table is locked.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'w', 0, 0, + 0, 0, 0, 0}, + { "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}, + { "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}, + { "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}, + { "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}, + { "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}, + { "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}, + { "decode_bits", "", (gptr*) &decode_bits, (gptr*) &decode_bits, 0, + GET_LONG, REQUIRED_ARG, OPT_DECODE_BITS, 9L, 4L, 17L, 0L, 1L, 0}, + { "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}, + { "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}, + { "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}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; static void print_version(void) { - printf("%s Ver 2.2 for %s at %s\n", my_progname, SYSTEM_TYPE, + printf("%s Ver 2.3 for %s at %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE); } static void usage(void) { - uint i; print_version(); puts("By Monty, for your professional use"); puts("This software comes with NO WARRANTY: see the PUBLIC for details.\n"); @@ -297,17 +371,9 @@ static void usage(void) data much more localized and may speed up things\n\ (It may be VERY slow to do a sort the first time!)"); - print_defaults("my",load_default_groups); - printf("\nThe variables you can set are:\n"); - for (i=0; my_long_options[i].name ; i++) - { - if (!my_long_options[i].opt_is_var) - continue; -#ifdef TO_BE_FIXED - printf("%-20s current value: %lu\n", my_long_options[i].name, - *my_long_options[i].value); -#endif - } + print_defaults("my", load_default_groups); + putchar('\n'); + my_print_variables(my_long_options); } @@ -322,60 +388,102 @@ get_one_option(int optid, switch (optid) { case 'a': - check_param.testflag|= T_STATISTICS; + if (argument && *argument == '0') + check_param.testflag&= ~T_STATISTICS; + else + check_param.testflag|= T_STATISTICS; break; case 'A': if (argument) - check_param.auto_increment_value=strtoull(argument, NULL, 0); + check_param.auto_increment_value= strtoull(argument, NULL, 0); else - check_param.auto_increment_value=0; /* Set to max used value */ + check_param.auto_increment_value= 0; /* Set to max used value */ check_param.testflag|= T_AUTO_INC; break; case 'b': - check_param.search_after_block=strtoul(argument, NULL, 10); + check_param.search_after_block= strtoul(argument, NULL, 10); break; case 'B': - check_param.testflag|= T_BACKUP_DATA; + if (argument && *argument == '0') + check_param.testflag&= ~T_BACKUP_DATA; + else + check_param.testflag|= T_BACKUP_DATA; break; case 'c': - check_param.testflag|= T_CHECK; + if (argument && *argument == '0') + check_param.testflag&= ~T_CHECK; + else + check_param.testflag|= T_CHECK; break; case 'C': - check_param.testflag|= T_CHECK | T_CHECK_ONLY_CHANGED; + if (argument && *argument == '0') + { + check_param.testflag&= ~T_CHECK; + check_param.testflag&= ~T_CHECK_ONLY_CHANGED; + } + else + check_param.testflag|= T_CHECK | T_CHECK_ONLY_CHANGED; break; case 'D': check_param.max_data_file_length=strtoll(argument, NULL, 10); break; case 's': /* silent */ - if (check_param.testflag & T_SILENT) - check_param.testflag|=T_VERY_SILENT; - check_param.testflag|= T_SILENT; - check_param.testflag&= ~T_WRITE_LOOP; + if (argument && *argument == '0') + { + if (check_param.testflag & T_VERY_SILENT) + check_param.testflag&= ~T_VERY_SILENT; + check_param.testflag&= ~T_SILENT; + } + else + { + if (check_param.testflag & T_SILENT) + check_param.testflag|= T_VERY_SILENT; + check_param.testflag|= T_SILENT; + check_param.testflag&= ~T_WRITE_LOOP; + } break; case 'w': - check_param.testflag|= T_WAIT_FOREVER; + if (argument && *argument == '0') + check_param.testflag&= ~T_WAIT_FOREVER; + else + check_param.testflag|= T_WAIT_FOREVER; break; case 'd': /* description if isam-file */ - check_param.testflag|= T_DESCRIPT; + if (argument && *argument == '0') + check_param.testflag&= ~T_DESCRIPT; + else + check_param.testflag|= T_DESCRIPT; break; case 'e': /* extend check */ - check_param.testflag|= T_EXTEND; + if (argument && *argument == '0') + check_param.testflag&= ~T_EXTEND; + else + check_param.testflag|= T_EXTEND; break; case 'i': - check_param.testflag|= T_INFO; + if (argument && *argument == '0') + check_param.testflag&= ~T_INFO; + else + check_param.testflag|= T_INFO; break; case 'f': check_param.tmpfile_createflag= O_RDWR | O_TRUNC; check_param.testflag|= T_FORCE_CREATE | T_UPDATE_STATE; break; case 'F': - check_param.testflag|=T_FAST; + if (argument && *argument == '0') + check_param.testflag&= ~T_FAST; + else + check_param.testflag|= T_FAST; break; case 'k': check_param.keys_in_use= (ulonglong) strtoll(argument, NULL, 10); break; case 'm': - check_param.testflag|= T_MEDIUM; /* Medium check */ + if (argument && *argument == '0') + check_param.testflag&= ~T_MEDIUM; + else + check_param.testflag|= T_MEDIUM; /* Medium check */ break; case 'r': /* Repair table */ check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT; @@ -387,22 +495,34 @@ get_one_option(int optid, break; case 'n': check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT; - check_param.force_sort=1; + check_param.force_sort= 1; break; case 'q': - check_param.opt_rep_quick++; + if (argument && *argument == '0') + check_param.opt_rep_quick--; + else + check_param.opt_rep_quick++; break; case 'u': - check_param.testflag|= T_UNPACK | T_REP_BY_SORT; + if (argument && *argument == '0') + { + check_param.testflag&= ~T_UNPACK; + check_param.testflag&= ~T_REP_BY_SORT; + } + else + check_param.testflag|= T_UNPACK | T_REP_BY_SORT; break; case 'v': /* Verbose */ - check_param.testflag|= T_VERBOSE; + if (argument && *argument == '0') + check_param.testflag&= ~T_VERBOSE; + else + check_param.testflag|= T_VERBOSE; check_param.verbose++; break; case 'R': /* Sort records */ - old_testflag=check_param.testflag; + old_testflag= check_param.testflag; check_param.testflag|= T_SORT_RECORDS; - check_param.opt_sort_key=(uint) atoi(argument) - 1; + check_param.opt_sort_key= (uint) atoi(argument) - 1; if (check_param.opt_sort_key >= MI_MAX_KEY) { fprintf(stderr, @@ -412,17 +532,26 @@ get_one_option(int optid, } break; case 'S': /* Sort index */ - old_testflag=check_param.testflag; - check_param.testflag|= T_SORT_INDEX; + old_testflag= check_param.testflag; + if (argument && *argument == '0') + check_param.testflag&= ~T_SORT_INDEX; + else + check_param.testflag|= T_SORT_INDEX; break; case 't': - check_param.tmpdir=argument; + check_param.tmpdir= argument; break; case 'T': - check_param.testflag|= T_READONLY; + if (argument && *argument == '0') + check_param.testflag&= ~T_READONLY; + else + check_param.testflag|= T_READONLY; break; case 'U': - check_param.testflag|= T_UPDATE_STATE; + if (argument && *argument == '0') + check_param.testflag&= ~T_UPDATE_STATE; + else + check_param.testflag|= T_UPDATE_STATE; break; case '#': DBUG_PUSH(argument ? argument : "d:t:o,/tmp/myisamchk.trace"); @@ -431,14 +560,14 @@ get_one_option(int optid, print_version(); exit(0); case OPT_CORRECT_CHECKSUM: - if (*argument && *argument == '0') + if (argument && *argument == '0') check_param.testflag&= ~T_CALC_CHECKSUM; else - check_param.testflag|=T_CALC_CHECKSUM; + check_param.testflag|= T_CALC_CHECKSUM; break; #ifdef DEBUG /* Only useful if debugging */ case OPT_START_CHECK_POS: - check_param.start_check_pos=strtoull(argument, NULL, 0); + check_param.start_check_pos= strtoull(argument, NULL, 0); break; #endif case '?': diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index d16cd7d2d86..a28d3dd4e3c 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -29,8 +29,15 @@ static my_bool compare_strings (register const char *s, register const char *t, 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 +static const char *special_opt_prefix[]= +{"skip", "disable", "enable", "maximum", 0}; + + +/* Return error values from handle_options */ + #define ERR_UNKNOWN_OPTION 1 #define ERR_AMBIGUOUS_OPTION 2 #define ERR_NO_ARGUMENT_ALLOWED 3 @@ -41,9 +48,6 @@ static void init_variables(const struct my_option *options); #define ERR_UNKNOWN_SUFFIX 8 #define ERR_NO_PTR_TO_VARIABLE 9 -static const char *special_opt_prefix[]= -{"skip", "disable", "enable", "maximum", 0}; - /* function: handle_options @@ -63,95 +67,91 @@ int handle_options(int *argc, char ***argv, { uint opt_found, argvpos= 0, length, spec_len, i; int err; - my_bool end_of_options= 0, must_be_var, set_maximum_value; + my_bool end_of_options= 0, must_be_var, set_maximum_value, special_used; char *progname= *(*argv), **pos, *optend, *prev_found; const struct my_option *optp; + LINT_INIT(opt_found); (*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 */ + if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */ { - char *argument= 0; - must_be_var= 0; + char *argument= 0; + must_be_var= 0; set_maximum_value= 0; + special_used= 0; - /* check for long option, or --set-variable (-O) */ - if (*(cur_arg + 1) == '-' || *(cur_arg + 1) == 'O') + cur_arg++; /* skip '-' */ + if (*cur_arg == 'O') { - if (*(cur_arg + 1) == 'O' || - !compare_strings(cur_arg, "--set-variable", 14)) - { - must_be_var= 1; + must_be_var= 1; - if (*(cur_arg + 1) == 'O') + if (!(*++cur_arg)) /* If not -Ovar=# */ + { + /* the argument must be in next argv */ + if (!*++pos) { - cur_arg+= 2; - if (!(*cur_arg)) - { - /* the argument must be in next argv */ - if (!(*(pos + 1))) - { - fprintf(stderr, "%s: Option '-O' requires an argument\n", - progname); - return ERR_ARGUMENT_REQUIRED; - } - pos++; - cur_arg= *pos; - (*argc)--; - } + fprintf(stderr, "%s: Option '-O' requires an argument\n", + progname); + return ERR_ARGUMENT_REQUIRED; } - else /* Option argument begins with string '--set-variable' */ + cur_arg= *pos; + (*argc)--; + } + } + else if (*cur_arg == '-') /* check for long option, or --set-variable */ + { + if (!compare_strings(cur_arg, "-set-variable", 13)) + { + must_be_var= 1; + if (cur_arg[13] == '=') { cur_arg+= 14; - if (*cur_arg == '=') - { - cur_arg++; - if (!(*cur_arg)) - { - fprintf(stderr, - "%s: Option '--set-variable' requires an argument\n", - progname); - return ERR_ARGUMENT_REQUIRED; - } - } - else if (*cur_arg) /* garbage, or another option. break out */ + if (!*cur_arg) { - cur_arg-= 14; - must_be_var= 0; + fprintf(stderr, + "%s: Option '--set-variable' requires an argument\n", + progname); + return ERR_ARGUMENT_REQUIRED; } - else + } + else if (cur_arg[14]) /* garbage, or another option. break out */ + must_be_var= 0; + else + { + /* the argument must be in next argv */ + if (!*++pos) { - /* the argument must be in next argv */ - if (!(*(pos + 1))) - { - fprintf(stderr, - "%s: Option '--set-variable' requires an argument\n", - progname); - return ERR_ARGUMENT_REQUIRED; - } - pos++; - cur_arg= *pos; - (*argc)--; + fprintf(stderr, + "%s: Option '--set-variable' requires an argument\n", + progname); + return ERR_ARGUMENT_REQUIRED; } + cur_arg= *pos; + (*argc)--; } } else if (!must_be_var) { - /* '--' means end of options, look no further */ - if (!*(cur_arg + 2)) + if (!*++cur_arg) /* skip the double dash */ { + /* '--' means end of options, look no further */ end_of_options= 1; (*argc)--; continue; } - cur_arg+= 2; /* skip the double dash */ } - for (optend= cur_arg; *optend && *optend != '='; optend++) ; + optend= strcend(cur_arg, '='); length= optend - cur_arg; + if (*optend == '=') + optend++; + else + optend=0; + /* Find first the right option. Return error in case of an ambiguous, or unknown option @@ -165,7 +165,7 @@ int handle_options(int *argc, char ***argv, */ if (!must_be_var) { - if (*optend == '=') + if (optend) must_be_var= 1; for (i= 0; special_opt_prefix[i]; i++) { @@ -176,6 +176,7 @@ int handle_options(int *argc, char ***argv, /* We were called with a special prefix, we can reuse opt_found */ + special_used= 1; cur_arg += (spec_len + 1); if ((opt_found= findopt(cur_arg, length - (spec_len + 1), &optp, &prev_found))) @@ -189,9 +190,9 @@ int handle_options(int *argc, char ***argv, return ERR_AMBIGUOUS_OPTION; } if (i < DISABLE_OPTION_COUNT) - optend= (char*) "=0"; + optend= (char*) "0"; else if (!compare_strings(special_opt_prefix[i],"enable",6)) - optend= (char*) "=1"; + optend= (char*) "1"; else if (!compare_strings(special_opt_prefix[i],"maximum",7)) { set_maximum_value= 1; @@ -233,81 +234,81 @@ int handle_options(int *argc, char ***argv, return ERR_AMBIGUOUS_OPTION; } } - if (must_be_var && !optp->opt_is_var) + if (must_be_var && !optp->value) { fprintf(stderr, "%s: the argument '%s' is not an variable\n", progname, *pos); return ERR_MUST_BE_VARIABLE; } - if (optp->arg_type == NO_ARG && *optend == '=') + if (optp->arg_type == NO_ARG && optend && !special_used) { fprintf(stderr, "%s: option '--%s' cannot take an argument\n", progname, optp->name); return ERR_NO_ARGUMENT_ALLOWED; } - else if (optp->arg_type == REQUIRED_ARG && !*optend) + else if (optp->arg_type == REQUIRED_ARG && !optend) { /* Check if there are more arguments after this one */ - if (!(*(pos + 1))) + if (!*++pos) { fprintf(stderr, "%s: option '--%s' requires an argument\n", progname, optp->name); return ERR_ARGUMENT_REQUIRED; } - pos++; argument= *pos; (*argc)--; } - else if (*optend == '=') - argument= *(optend + 1) ? optend + 1 : (char*) ""; + else + argument= optend; } else /* must be short option */ { - my_bool skip; - for (skip= 0, optend= (cur_arg + 1); *optend && !skip; optend++) + for (optend= cur_arg; *optend; optend++, opt_found= 0) { - for (optp= longopts; optp->id ; optp++) + for (optp= longopts; optp->id; optp++) { if (optp->id == (int) (uchar) *optend) { /* Option recognized. Find next what to do with it */ + opt_found= 1; if (optp->arg_type == REQUIRED_ARG || optp->arg_type == OPT_ARG) { if (*(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; + // The rest of the option is option argument + argument= optend + 1; + // This is in effect a jump out of the outer loop + optend= (char*) " "; } else if (optp->arg_type == REQUIRED_ARG) { /* Check if there are more arguments after this one */ - if (!(*(pos + 1))) + if (!*++pos) { fprintf(stderr, "%s: option '-%c' requires an argument\n", progname, optp->id); return ERR_ARGUMENT_REQUIRED; } - pos++; argument= *pos; (*argc)--; + /* the other loop will break, because *optend + 1 == 0 */ } } - else - { - /* we are hitting many options in 1 argv */ - if (*(optend + 1)) - get_one_option(optp->id, optp, 0); - } + get_one_option(optp->id, optp, argument); break; } } + if (!opt_found) + { + fprintf(stderr, + "%s: unknown option '-%c'\n", progname, *cur_arg); + return ERR_UNKNOWN_OPTION; + } } + (*argc)--; /* option handled (short), decrease argument count */ + continue; } - if (optp->opt_is_var) + if (optp->value) { gptr *result_pos= (set_maximum_value) ? optp->u_max_value : optp->value; @@ -349,6 +350,7 @@ int handle_options(int *argc, char ***argv, 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, char **ffname) @@ -378,6 +380,7 @@ static int findopt (char *optpat, uint length, 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) { @@ -401,6 +404,7 @@ static my_bool compare_strings(register const char *s, register const char *t, 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; @@ -423,11 +427,14 @@ static longlong getopt_ll (char *arg, const struct my_option *optp, int *err) } if (num < (longlong) optp->min_value) num= (longlong) optp->min_value; - else if (num > 0 && (ulonglong) num > (ulonglong) (ulong) optp->max_value) + else if (num > 0 && (ulonglong) num > (ulonglong) (ulong) optp->max_value + && optp->max_value) // if max value is not set -> no upper limit num= (longlong) (ulong) optp->max_value; - num= ((num - (longlong) optp->sub_size) / (ulonglong) optp->block_size); - - return (longlong) (num * (ulonglong) optp->block_size); + num= ((num - (longlong) optp->sub_size) / (optp->block_size ? + (ulonglong) optp->block_size : + 1L)); + return (longlong) (num * (optp->block_size ? (ulonglong) optp->block_size : + 1L)); } @@ -436,11 +443,12 @@ static longlong getopt_ll (char *arg, const struct my_option *optp, int *err) initialize all variables to their default values */ + static void init_variables(const struct my_option *options) { - for ( ; options->name ; options++) + for (; options->name; options++) { - if (options->opt_is_var) + if (options->value) { if (options->var_type == GET_LONG) *((long*) options->u_max_value)= *((long*) options->value)= @@ -451,3 +459,120 @@ static void init_variables(const struct my_option *options) } } } + + +/* + function: my_print_options + + Print help for all options and variables. +*/ + +void my_print_help(const struct my_option *options) +{ + uint col, name_space= 22, comment_space= 57; + const char *line_end; + const struct my_option *optp; + + for (optp= options; optp->id; optp++) + { + if (optp->id < 256) + { + printf(" -%c, ", optp->id); + col= 6; + } + else + { + printf(" "); + col= 2; + } + printf("--%s", optp->name); + col+= 2 + strlen(optp->name); + if (optp->var_type == GET_STR) + { + printf("=name "); + col+= 6; + } + else if (optp->var_type == GET_NO_ARG) + { + putchar(' '); + col++; + } + else + { + printf("=# "); + col+= 3; + } + if (col > name_space) + { + putchar('\n'); + col= 0; + } + for (; col < name_space; col++) + putchar(' '); + if (optp->comment && *optp->comment) + { + const char *comment= optp->comment, *end= strend(comment); + + while ((uint) (end - comment) > comment_space) + { + for (line_end= comment + comment_space; *line_end != ' '; line_end--); + for (; comment != line_end; comment++) + putchar(*comment); + comment++; // skip the space, as a newline will take it's place now + putchar('\n'); + for (col= 0; col < name_space; col++) + putchar(' '); + } + printf("%s", comment); + } + putchar('\n'); + } +} + + +/* + function: my_print_options + + Print variables. +*/ + +void my_print_variables(const struct my_option *options) +{ + uint name_space= 34, length; + char buff[255]; + const struct my_option *optp; + + printf("Variables (--variable-name=value) Default value\n"); + printf("--------------------------------- -------------\n"); + for (optp= options; optp->id; optp++) + { + if (optp->value) + { + printf("%s", optp->name); + length= strlen(optp->name); + for (; length < name_space; length++) + putchar(' '); + if (optp->var_type == GET_STR) + { + if (!optp->def_value && !*((char**) optp->value)) + printf("(No default value)\n"); + else + printf("%s\n", *((char**) optp->value)); + } + else if (optp->var_type == GET_LONG) + { + if (!optp->def_value && !*((long*) optp->value)) + printf("(No default value)\n"); + else + printf("%lu\n", *((long*) optp->value)); + } + else + { + if (!optp->def_value && !*((longlong*) optp->value)) + printf("(No default value)\n"); + else + printf("%s\n", llstr(*((longlong*) optp->value), buff)); + } + } + } +} diff --git a/support-files/my-huge.cnf.sh b/support-files/my-huge.cnf.sh index 103a6c16cfd..ce9b5b18586 100644 --- a/support-files/my-huge.cnf.sh +++ b/support-files/my-huge.cnf.sh @@ -4,7 +4,7 @@ # MySQL. # # You can copy this file to -# /etc/mf.cnf to set global options, +# /etc/my.cnf to set global options, # mysql-data-dir/my.cnf to set server-specific options (in this # installation this directory is @localstatedir@) or # ~/.my.cnf to set user-specific options. diff --git a/support-files/my-large.cnf.sh b/support-files/my-large.cnf.sh index f314566c5fb..0602921abc1 100644 --- a/support-files/my-large.cnf.sh +++ b/support-files/my-large.cnf.sh @@ -4,7 +4,7 @@ # MySQL. # # You can copy this file to -# /etc/mf.cnf to set global options, +# /etc/my.cnf to set global options, # mysql-data-dir/my.cnf to set server-specific options (in this # installation this directory is @localstatedir@) or # ~/.my.cnf to set user-specific options. diff --git a/support-files/my-medium.cnf.sh b/support-files/my-medium.cnf.sh index 675241b25dd..bddba03eee9 100644 --- a/support-files/my-medium.cnf.sh +++ b/support-files/my-medium.cnf.sh @@ -5,7 +5,7 @@ # other programs (like a web server) # # You can copy this file to -# /etc/mf.cnf to set global options, +# /etc/my.cnf to set global options, # mysql-data-dir/my.cnf to set server-specific options (in this # installation this directory is @localstatedir@) or # ~/.my.cnf to set user-specific options. diff --git a/support-files/my-small.cnf.sh b/support-files/my-small.cnf.sh index cad0e10e684..9e7d07ec449 100644 --- a/support-files/my-small.cnf.sh +++ b/support-files/my-small.cnf.sh @@ -5,7 +5,7 @@ # doesn't use much resources. # # You can copy this file to -# /etc/mf.cnf to set global options, +# /etc/my.cnf to set global options, # mysql-data-dir/my.cnf to set server-specific options (in this # installation this directory is @localstatedir@) or # ~/.my.cnf to set user-specific options. |