mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Added my_getopt struct and modified myisamchk to the bk tree.
This commit is contained in:
@ -42,3 +42,4 @@ bell@sanja.is.com.ua
|
||||
kaj@work.mysql.com
|
||||
mwagner@cash.mwagner.org
|
||||
tom@basil-firewall.home.com
|
||||
jani@rhols221.adsl.netsonic.fi
|
||||
|
@ -28,7 +28,7 @@ noinst_HEADERS = config-win.h \
|
||||
my_dir.h mysys_err.h my_base.h \
|
||||
my_nosys.h my_alarm.h queues.h \
|
||||
my_tree.h hash.h thr_alarm.h thr_lock.h \
|
||||
getopt.h t_ctype.h violite.h md5.h \
|
||||
getopt.h my_getopt.h t_ctype.h violite.h md5.h \
|
||||
mysql_version.h.in
|
||||
|
||||
# mysql_version.h are generated
|
||||
|
46
include/my_getopt.h
Normal file
46
include/my_getopt.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
struct my_optarg
|
||||
{
|
||||
char *arg; /* option argument */
|
||||
int pos; /* next element in ARGV */
|
||||
int verbose; /* 0 = inhibit warnings of unrecognized options */
|
||||
int unrecognized; /* position of the unrecognized option */
|
||||
};
|
||||
|
||||
|
||||
enum get_opt_var_type { GET_NO_ARG, GET_INT, 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 */
|
||||
const char **str_values; /* Pointer to possible values */
|
||||
enum get_opt_var_type var_type;
|
||||
enum get_opt_arg_type arg_type;
|
||||
int id; /* unique id or short option */
|
||||
long long def_value; /* Default value */
|
||||
long long min_value; /* Min allowed value */
|
||||
long long max_value; /* Max allowed value */
|
||||
long long 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 */
|
||||
};
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#include <m_ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <getopt.h>
|
||||
#include <my_getopt.h>
|
||||
#include <assert.h>
|
||||
#ifdef HAVE_SYS_VADVICE_H
|
||||
#include <sys/vadvise.h>
|
||||
@ -169,58 +169,75 @@ static CHANGEABLE_VAR changeable_vars[] = {
|
||||
|
||||
enum options {
|
||||
OPT_CHARSETS_DIR=256, OPT_SET_CHARSET,OPT_START_CHECK_POS,
|
||||
OPT_CORRECT_CHECKSUM
|
||||
OPT_CORRECT_CHECKSUM, OPT_KEY_BUFFER_SIZE, OPT_MYISAM_BLOCK_SIZE,
|
||||
OPT_READ_BUFFER_SIZE, OPT_WRITE_BUFFER_SIZE, OPT_SORT_BUFFER_SIZE,
|
||||
OPT_SORT_KEY_BLOCKS, OPT_DECODE_BITS, OPT_FT_MIN_WORD_LEN,
|
||||
OPT_FT_MAX_WORD_LEN, OPT_FT_MAX_WORD_LEN_FOR_SORT
|
||||
};
|
||||
|
||||
|
||||
static struct option long_options[] =
|
||||
static struct my_option my_long_options[] =
|
||||
{
|
||||
{"analyze", no_argument, 0, 'a'},
|
||||
{"block-search", required_argument,0, 'b'},
|
||||
{"backup", no_argument, 0, 'B'},
|
||||
{"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR},
|
||||
{"check", no_argument, 0, 'c'},
|
||||
{"check-only-changed",no_argument, 0, 'C'},
|
||||
{"correct-checksum", no_argument, 0, OPT_CORRECT_CHECKSUM},
|
||||
{"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},
|
||||
|
||||
{"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},
|
||||
|
||||
{"correct-checksum", "", 0, 0, GET_NO_ARG, NO_ARG, OPT_CORRECT_CHECKSUM, 0, 0, 0, 0, 0, 0, 0},
|
||||
#ifndef DBUG_OFF
|
||||
{"debug", optional_argument, 0, '#'},
|
||||
{"debug", "", 0, 0, GET_STR, OPT_ARG, '#', 0, 0, 0, 0, 0, 0, 0},
|
||||
#endif
|
||||
{"description", no_argument, 0, 'd'},
|
||||
{"data-file-length", required_argument, 0, 'D'},
|
||||
{"extend-check", no_argument, 0, 'e'},
|
||||
{"fast", no_argument, 0, 'F'},
|
||||
{"force", no_argument, 0, 'f'},
|
||||
{"help", no_argument, 0, '?'},
|
||||
{"information", no_argument, 0, 'i'},
|
||||
{"keys-used", required_argument, 0, 'k'},
|
||||
{"medium-check", no_argument, 0, 'm'},
|
||||
{"quick", no_argument, 0, 'q'},
|
||||
{"read-only", no_argument, 0, 'T'},
|
||||
{"recover", no_argument, 0, 'r'},
|
||||
{"safe-recover", no_argument, 0, 'o'},
|
||||
{"start-check-pos", required_argument, 0, OPT_START_CHECK_POS},
|
||||
{"set-auto-increment",optional_argument, 0, 'A'},
|
||||
{"set-character-set",required_argument,0,OPT_SET_CHARSET},
|
||||
{"set-variable", required_argument, 0, 'O'},
|
||||
{"silent", no_argument, 0, 's'},
|
||||
{"sort-index", no_argument, 0, 'S'},
|
||||
{"sort-records", required_argument, 0, 'R'},
|
||||
{"sort-recover", no_argument, 0, 'n'},
|
||||
{"tmpdir", required_argument, 0, 't'},
|
||||
{"update-state", no_argument, 0, 'U'},
|
||||
{"unpack", no_argument, 0, 'u'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"wait", no_argument, 0, 'w'},
|
||||
{0, 0, 0, 0}
|
||||
{"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},
|
||||
/* 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},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
static void print_version(void)
|
||||
{
|
||||
printf("%s Ver 2.0 for %s at %s\n",my_progname,SYSTEM_TYPE,
|
||||
printf("%s Ver 2.1 for %s at %s\n", my_progname, SYSTEM_TYPE,
|
||||
MACHINE_TYPE);
|
||||
}
|
||||
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
uint i;
|
||||
@ -315,163 +332,182 @@ static void usage(void)
|
||||
|
||||
/* Read options */
|
||||
|
||||
static my_bool get_one_option(int optid, const struct my_option *opt,
|
||||
char *argument)
|
||||
{
|
||||
uint old_testflag;
|
||||
char buff[255], *end;
|
||||
|
||||
switch(optid) {
|
||||
case 'a':
|
||||
check_param.testflag|= T_STATISTICS;
|
||||
break;
|
||||
case 'A':
|
||||
if (argument)
|
||||
check_param.auto_increment_value=strtoull(argument, NULL, 0);
|
||||
else
|
||||
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);
|
||||
break;
|
||||
case 'B':
|
||||
check_param.testflag|= T_BACKUP_DATA;
|
||||
break;
|
||||
case 'c':
|
||||
check_param.testflag|= T_CHECK;
|
||||
break;
|
||||
case 'C':
|
||||
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;
|
||||
break;
|
||||
case 'w':
|
||||
check_param.testflag|= T_WAIT_FOREVER;
|
||||
break;
|
||||
case 'd': /* description if isam-file */
|
||||
check_param.testflag|= T_DESCRIPT;
|
||||
break;
|
||||
case 'e': /* extend check */
|
||||
check_param.testflag|= T_EXTEND;
|
||||
break;
|
||||
case 'i':
|
||||
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;
|
||||
break;
|
||||
case 'k':
|
||||
check_param.keys_in_use= (ulonglong) strtoll(argument, NULL, 10);
|
||||
break;
|
||||
case 'm':
|
||||
check_param.testflag|= T_MEDIUM; /* Medium check */
|
||||
break;
|
||||
case 'r': /* Repair table */
|
||||
check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT;
|
||||
break;
|
||||
case 'o':
|
||||
check_param.testflag= (check_param.testflag & ~T_REP_BY_SORT) | T_REP;
|
||||
check_param.force_sort=0;
|
||||
my_disable_async_io=1; /* More safety */
|
||||
break;
|
||||
case 'n':
|
||||
check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT;
|
||||
check_param.force_sort=1;
|
||||
break;
|
||||
case 'q':
|
||||
check_param.opt_rep_quick++;
|
||||
break;
|
||||
case 'u':
|
||||
check_param.testflag|= T_UNPACK | T_REP_BY_SORT;
|
||||
break;
|
||||
case 'v': /* Verbose */
|
||||
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;
|
||||
check_param.opt_sort_key=(uint) atoi(argument) - 1;
|
||||
if (check_param.opt_sort_key >= MI_MAX_KEY)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"The value of the sort key is bigger than max key: %d.\n",
|
||||
MI_MAX_KEY);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'S': /* Sort index */
|
||||
old_testflag=check_param.testflag;
|
||||
check_param.testflag|= T_SORT_INDEX;
|
||||
break;
|
||||
case 't':
|
||||
check_param.tmpdir=argument;
|
||||
break;
|
||||
case 'T':
|
||||
check_param.testflag|= T_READONLY;
|
||||
break;
|
||||
case 'U':
|
||||
check_param.testflag|= T_UPDATE_STATE;
|
||||
break;
|
||||
case '#':
|
||||
DBUG_PUSH(argument ? argument : "d:t:o,/tmp/myisamchk.trace");
|
||||
break;
|
||||
case 'V':
|
||||
print_version();
|
||||
exit(0);
|
||||
case OPT_CORRECT_CHECKSUM:
|
||||
check_param.testflag|=T_CALC_CHECKSUM;
|
||||
break;
|
||||
case OPT_CHARSETS_DIR:
|
||||
charsets_dir= argument;
|
||||
break;
|
||||
case OPT_SET_CHARSET:
|
||||
set_charset_name= argument;
|
||||
break;
|
||||
#ifdef DEBUG /* Only useful if debugging */
|
||||
case OPT_START_CHECK_POS:
|
||||
check_param.start_check_pos=strtoull(argument, NULL, 0);
|
||||
break;
|
||||
#endif
|
||||
case '?':
|
||||
usage();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void get_options(register int *argc,register char ***argv)
|
||||
{
|
||||
int c,option_index=0;
|
||||
uint old_testflag;
|
||||
|
||||
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;
|
||||
while ((c=getopt_long(*argc,*argv,
|
||||
"aBcCdeifF?lqrmnosSTuUvVw#:b:D:k:O:R:A::t:",
|
||||
long_options, &option_index)) != EOF)
|
||||
{
|
||||
switch(c) {
|
||||
case 'a':
|
||||
check_param.testflag|= T_STATISTICS;
|
||||
break;
|
||||
case 'A':
|
||||
if (optarg)
|
||||
check_param.auto_increment_value=strtoull(optarg,NULL,0);
|
||||
else
|
||||
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(optarg,NULL,10);
|
||||
break;
|
||||
case 'B':
|
||||
check_param.testflag|= T_BACKUP_DATA;
|
||||
break;
|
||||
case 'c':
|
||||
check_param.testflag|= T_CHECK;
|
||||
break;
|
||||
case 'C':
|
||||
check_param.testflag|= T_CHECK | T_CHECK_ONLY_CHANGED;
|
||||
break;
|
||||
case 'D':
|
||||
check_param.max_data_file_length=strtoll(optarg,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;
|
||||
break;
|
||||
case 'w':
|
||||
check_param.testflag|= T_WAIT_FOREVER;
|
||||
break;
|
||||
case 'd': /* description if isam-file */
|
||||
check_param.testflag|= T_DESCRIPT;
|
||||
break;
|
||||
case 'e': /* extend check */
|
||||
check_param.testflag|= T_EXTEND;
|
||||
break;
|
||||
case 'i':
|
||||
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;
|
||||
break;
|
||||
case 'k':
|
||||
check_param.keys_in_use= (ulonglong) strtoll(optarg,NULL,10);
|
||||
break;
|
||||
case 'm':
|
||||
check_param.testflag|= T_MEDIUM; /* Medium check */
|
||||
break;
|
||||
case 'r': /* Repair table */
|
||||
check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT;
|
||||
break;
|
||||
case 'o':
|
||||
check_param.testflag= (check_param.testflag & ~T_REP_BY_SORT) | T_REP;
|
||||
check_param.force_sort=0;
|
||||
my_disable_async_io=1; /* More safety */
|
||||
break;
|
||||
case 'n':
|
||||
check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT;
|
||||
check_param.force_sort=1;
|
||||
break;
|
||||
case 'q':
|
||||
check_param.opt_rep_quick++;
|
||||
break;
|
||||
case 'u':
|
||||
check_param.testflag|= T_UNPACK | T_REP_BY_SORT;
|
||||
break;
|
||||
case 'v': /* Verbose */
|
||||
check_param.testflag|= T_VERBOSE;
|
||||
check_param.verbose++;
|
||||
break;
|
||||
case 'O':
|
||||
if (set_changeable_var(optarg, changeable_vars))
|
||||
{
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'R': /* Sort records */
|
||||
old_testflag=check_param.testflag;
|
||||
check_param.testflag|= T_SORT_RECORDS;
|
||||
check_param.opt_sort_key=(uint) atoi(optarg)-1;
|
||||
if (check_param.opt_sort_key >= MI_MAX_KEY)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"The value of the sort key is bigger than max key: %d.\n",
|
||||
MI_MAX_KEY);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'S': /* Sort index */
|
||||
old_testflag=check_param.testflag;
|
||||
check_param.testflag|= T_SORT_INDEX;
|
||||
break;
|
||||
case 't':
|
||||
check_param.tmpdir=optarg;
|
||||
break;
|
||||
case 'T':
|
||||
check_param.testflag|= T_READONLY;
|
||||
break;
|
||||
case 'U':
|
||||
check_param.testflag|= T_UPDATE_STATE;
|
||||
break;
|
||||
case '#':
|
||||
DBUG_PUSH(optarg ? optarg : "d:t:o,/tmp/myisamchk.trace");
|
||||
break;
|
||||
case 'V':
|
||||
print_version();
|
||||
exit(0);
|
||||
case OPT_CORRECT_CHECKSUM:
|
||||
check_param.testflag|=T_CALC_CHECKSUM;
|
||||
break;
|
||||
case OPT_CHARSETS_DIR:
|
||||
charsets_dir = optarg;
|
||||
break;
|
||||
case OPT_SET_CHARSET:
|
||||
set_charset_name=optarg;
|
||||
break;
|
||||
#ifdef DEBUG /* Only useful if debugging */
|
||||
case OPT_START_CHECK_POS:
|
||||
check_param.start_check_pos=strtoull(optarg,NULL,0);
|
||||
break;
|
||||
#endif
|
||||
case '?':
|
||||
usage();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (handle_options(argc, argv, my_long_options, get_one_option))
|
||||
exit(1);
|
||||
|
||||
/* If using repair, then update checksum if one uses --update-state */
|
||||
if ((check_param.testflag & T_UPDATE_STATE) &&
|
||||
(check_param.testflag & (T_REP | T_REP_BY_SORT)))
|
||||
check_param.testflag|= T_CALC_CHECKSUM;
|
||||
|
||||
(*argc)-=optind;
|
||||
(*argv)+=optind;
|
||||
if (*argc == 0)
|
||||
{
|
||||
usage();
|
||||
|
@ -44,7 +44,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
|
||||
my_delete.c my_rename.c my_redel.c my_tempnam.c \
|
||||
my_chsize.c my_lread.c my_lwrite.c my_clock.c \
|
||||
my_quick.c my_lockmem.c my_static.c \
|
||||
getopt.c getopt1.c getvar.c my_mkdir.c \
|
||||
getopt.c getopt1.c my_getopt.c getvar.c my_mkdir.c \
|
||||
default.c my_compress.c checksum.c raid.cc my_net.c \
|
||||
my_vsnprintf.c charset.c my_bitmap.c my_bit.c md5.c
|
||||
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
#include <m_ctype.h>
|
||||
|
||||
#include <my_getopt.h>
|
||||
/* set all changeable variables */
|
||||
|
||||
void set_all_changeable_vars(CHANGEABLE_VAR *vars)
|
||||
@ -109,3 +109,78 @@ 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);
|
||||
}
|
||||
|
313
mysys/my_getopt.c
Normal file
313
mysys/my_getopt.c
Normal file
@ -0,0 +1,313 @@
|
||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <my_config.h>
|
||||
#include <my_global.h>
|
||||
#include <m_string.h>
|
||||
#include <stdlib.h>
|
||||
#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);
|
||||
|
||||
#define DISABLE_OPTION_COUNT 2
|
||||
|
||||
static char *special_opt_prefix[] = {"skip", "disable", "enable", 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.
|
||||
*/
|
||||
extern int handle_options (int *argc, char ***argv,
|
||||
const struct my_option *longopts,
|
||||
my_bool (*get_one_option)(int,
|
||||
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;
|
||||
const struct my_option *optp;
|
||||
|
||||
(*argc)--;
|
||||
(*argv)++;
|
||||
for (pos = *argv; *pos; pos++)
|
||||
{
|
||||
char *cur_arg= *pos;
|
||||
if (*cur_arg == '-' && *(cur_arg + 1) && !end_of_options) // must be opt.
|
||||
{
|
||||
char *argument = 0;
|
||||
must_be_var= 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))
|
||||
{
|
||||
must_be_var= 1;
|
||||
|
||||
if (*(cur_arg + 1) == 'O')
|
||||
{
|
||||
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 4;
|
||||
}
|
||||
pos++;
|
||||
cur_arg= *pos;
|
||||
(*argc)--;
|
||||
}
|
||||
}
|
||||
else // Option argument begins with string '--set-variable'
|
||||
{
|
||||
cur_arg+= 14;
|
||||
if (*cur_arg == '=')
|
||||
{
|
||||
cur_arg++;
|
||||
if (!(*cur_arg))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: Option '--set-variable' requires an argument\n",
|
||||
progname);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
else if (*cur_arg) // garbage, or another option. break out
|
||||
{
|
||||
cur_arg-= 14;
|
||||
must_be_var= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// the argument must be in next argv
|
||||
if (!(*(pos + 1)))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: Option '--set-variable' requires an argument\n",
|
||||
progname);
|
||||
return 4;
|
||||
}
|
||||
pos++;
|
||||
cur_arg= *pos;
|
||||
(*argc)--;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!must_be_var)
|
||||
{
|
||||
if (!*(cur_arg + 2)) // '--' 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++) ;
|
||||
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)))
|
||||
{
|
||||
/*
|
||||
Didn't find any matching option. Let's see if someone called
|
||||
option with a special option prefix
|
||||
*/
|
||||
if (*optend != '=' && !must_be_var)
|
||||
{
|
||||
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) &&
|
||||
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 > 1)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: ambiguous option '--%s-%s' (--%s-%s)\n",
|
||||
progname, special_opt_prefix[i], cur_arg,
|
||||
special_opt_prefix[i], prev_found);
|
||||
return 2;
|
||||
}
|
||||
if (i < DISABLE_OPTION_COUNT)
|
||||
optend= "=0";
|
||||
else // enable
|
||||
optend= "=1";
|
||||
break; // note break from the inner loop, main loop continues
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!opt_found)
|
||||
{
|
||||
if (must_be_var)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: unknown variable '%s'\n", progname, cur_arg);
|
||||
return 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: unknown option '--%s'\n", progname, cur_arg);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (opt_found > 1)
|
||||
{
|
||||
if (must_be_var)
|
||||
{
|
||||
fprintf(stderr, "%s: variable prefix '%s' is not unique\n",
|
||||
progname, cur_arg);
|
||||
return 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "%s: ambiguous option '--%s' (%s, %s)\n",
|
||||
progname, cur_arg, prev_found, optp->name);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
if (must_be_var && !optp->changeable_var)
|
||||
{
|
||||
fprintf(stderr, "%s: the argument to -O must be a variable\n",
|
||||
progname);
|
||||
return 8;
|
||||
}
|
||||
if (optp->arg_type == NO_ARG && *optend == '=')
|
||||
{
|
||||
fprintf(stderr, "%s: option '--%s' cannot take an argument\n",
|
||||
progname, optp->name);
|
||||
return 3;
|
||||
}
|
||||
else if (optp->arg_type == REQUIRED_ARG && !*optend)
|
||||
{
|
||||
/* Check if there are more arguments after this one */
|
||||
if (!(*(pos + 1)))
|
||||
{
|
||||
fprintf(stderr, "%s: option '--%s' requires an argument\n",
|
||||
progname, optp->name);
|
||||
return 4;
|
||||
}
|
||||
pos++;
|
||||
argument = *pos;
|
||||
(*argc)--;
|
||||
}
|
||||
else if (*optend == '=')
|
||||
argument = *(optend + 1) ? optend + 1 : "";
|
||||
}
|
||||
else // must be short option
|
||||
{
|
||||
my_bool skip;
|
||||
for (skip = 0, optend = (cur_arg + 1); *optend && !skip; optend++)
|
||||
{
|
||||
for (optp = longopts; optp->id ; optp++)
|
||||
{
|
||||
if (optp->id == (int) (uchar) *optend)
|
||||
{
|
||||
/* Option recognized. Find next what to do with it */
|
||||
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;
|
||||
}
|
||||
else if (optp->arg_type == REQUIRED_ARG)
|
||||
{
|
||||
/* Check if there are more arguments after this one */
|
||||
if (!(*(pos + 1)))
|
||||
{
|
||||
fprintf(stderr, "%s: option '-%c' requires an argument\n",
|
||||
progname, optp->id);
|
||||
return 4;
|
||||
}
|
||||
pos++;
|
||||
argument = *pos;
|
||||
(*argc)--;
|
||||
}
|
||||
}
|
||||
else if (*(optend + 1)) // we are hitting many options in 1 argv
|
||||
get_one_option(optp->id, optp, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
get_one_option(optp->id, optp, argument);
|
||||
(*argc)--; // option handled (short<72>or<6F>long), decrease argument count
|
||||
}
|
||||
else // non-option found
|
||||
(*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
|
||||
*/
|
||||
static int findopt (char *optpat, uint length,
|
||||
const struct my_option **opt_res,
|
||||
char **ffname)
|
||||
{
|
||||
int count;
|
||||
struct my_option *opt= (struct my_option *) *opt_res;
|
||||
|
||||
for (count = 0; opt->id; opt++)
|
||||
{
|
||||
if (!strncmp(opt->name, optpat, length)) // match found
|
||||
{
|
||||
(*opt_res) = opt;
|
||||
if (!count)
|
||||
*ffname = (char *) opt->name; // we only need to know one prev
|
||||
if (length == strlen(opt->name)) // exact match
|
||||
return 1;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
Reference in New Issue
Block a user