Commit c4450483 authored by jani@rhols221.adsl.netsonic.fi's avatar jani@rhols221.adsl.netsonic.fi
Browse files

Fixed some bugs in my_getopt.c, added functionality for new GET_*

types, migrated mysqld.cc to use my_getopt.
parent d8f20876
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -16,7 +16,8 @@

C_MODE_START

enum get_opt_var_type { GET_NO_ARG, GET_BOOL, GET_LONG, GET_LL, GET_STR };
enum get_opt_var_type { GET_NO_ARG, GET_BOOL, GET_INT, GET_UINT, GET_LONG,
			GET_ULONG, GET_LL, GET_ULL, GET_STR };
enum get_opt_arg_type { NO_ARG, OPT_ARG, REQUIRED_ARG };

struct my_option
+148 −37
Original line number Diff line number Diff line
@@ -26,8 +26,11 @@ static int findopt (char *optpat, uint length,
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 ulonglong getopt_ull (char *arg, const struct my_option *optp,
			     int *err);
static void init_variables(const struct my_option *options);

static int setval (const struct my_option *opts, char *argument,
		   my_bool set_maximum_value);

#define DISABLE_OPTION_COUNT      2

@@ -66,15 +69,16 @@ int handle_options(int *argc, char ***argv,
					     char *))
{
  uint opt_found, argvpos= 0, length, spec_len, i;
  int err= 0;
  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;
  int error;

  LINT_INIT(opt_found);
  (*argc)--; /* Skip the program name */
  (*argv)++; /*      --- || ----      */
  init_variables(longopts);

  for (pos= *argv; *pos; pos++)
  {
    char *cur_arg= *pos;
@@ -337,6 +341,13 @@ int handle_options(int *argc, char ***argv,
		  /* the other loop will break, because *optend + 1 == 0 */
		}
	      }
	      if ((error= setval(optp, argument, set_maximum_value)))
	      {
		fprintf(stderr,
			"%s: Error while setting value '%s' to '%s'\n",
			progname, argument, optp->name);
		return error;
	      }
	      get_one_option(optp->id, optp, argument);
	      break;
	    }
@@ -351,25 +362,12 @@ int handle_options(int *argc, char ***argv,
	(*argc)--; /* option handled (short), decrease argument count */
	continue;
      }
      if (optp->value)
      {
	gptr *result_pos= (set_maximum_value) ?
	  optp->u_max_value : optp->value;

	if (!result_pos)
      if ((error= setval(optp, argument, set_maximum_value)))
      {
	fprintf(stderr,
		  "%s: Can't set a value for %s\n", progname, optp->name);
	  return ERR_NO_PTR_TO_VARIABLE;
	}
	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;
		"%s: Error while setting value '%s' to '%s'\n",
		progname, argument, optp->name);
	return error;
      }
      get_one_option(optp->id, optp, argument);

@@ -381,6 +379,41 @@ int handle_options(int *argc, char ***argv,
  return 0;
}

/*
  function: setval

  Arguments: opts, argument
  Will set the option value to given value
*/

static int setval (const struct my_option *opts, char *argument,
		   my_bool set_maximum_value)
{
  int err= 0;

  if (opts->value && argument)
  {
    gptr *result_pos= (set_maximum_value) ?
      opts->u_max_value : opts->value;

    if (!result_pos)
      return ERR_NO_PTR_TO_VARIABLE;

    if (opts->var_type == GET_INT || opts->var_type == GET_UINT)
      *((int*) result_pos)= (int) getopt_ll(argument, opts, &err);
    else if (opts->var_type == GET_LONG || opts->var_type == GET_ULONG)
      *((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
    else if (opts->var_type == GET_LL)
      *((longlong*) result_pos)= getopt_ll(argument, opts, &err);
    else if (opts->var_type == GET_ULL)
      *((ulonglong*) result_pos)= getopt_ull(argument, opts, &err);
    else if (opts->var_type == GET_STR)
      *((char**) result_pos)= argument;
    if (err)
      return ERR_UNKNOWN_SUFFIX;
  }
  return 0;
}

/* 
  function: findopt
@@ -436,25 +469,20 @@ static my_bool compare_strings(register const char *s, register const char *t,
  return 0;
}


/*
  function: getopt_ll
  function: eval_num_suffix

  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.
  Transforms a number with a suffix to real number. Suffix can
  be k|K for kilo, m|M for mega or g|G for giga.
*/

static longlong getopt_ll (char *arg, const struct my_option *optp, int *err)
static longlong eval_num_suffix (char *argument, int *error, char *option_name)
{
  char *endchar;
  longlong num;
  
  *err= 0;
  num= strtoll(arg, &endchar, 10);
  *error= 0;
  num= strtoll(argument, &endchar, 10);
  if (*endchar == 'k' || *endchar == 'K')
    num*= 1024L;
  else if (*endchar == 'm' || *endchar == 'M')
@@ -465,9 +493,29 @@ static longlong getopt_ll (char *arg, const struct my_option *optp, int *err)
  {
    fprintf(stderr,
	    "Unknown suffix '%c' used for variable '%s' (value '%s')\n",
	    *endchar, optp->name, arg);
    *err= 1;
	    *endchar, option_name, argument);
    *error= 1;
    return 0;
  }
  return num;
}

/* 
  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)
{
  longlong num;
  
  num= eval_num_suffix(arg, err, (char*) optp->name);
  if (num < (longlong) optp->min_value)
    num= (longlong) optp->min_value;
  else if (num > 0 && (ulonglong) num > (ulonglong) (ulong) optp->max_value
@@ -480,6 +528,29 @@ static longlong getopt_ll (char *arg, const struct my_option *optp, int *err)
			    1L));
}

/*
  function: getopt_ull

  This is the same as getopt_ll, but is meant for unsigned long long
  values.
*/

static ulonglong getopt_ull (char *arg, const struct my_option *optp, int *err)
{
  ulonglong num;

  num= eval_num_suffix(arg, err, (char*) optp->name);  
  if (num < (ulonglong) optp->min_value)
    num= (ulonglong) optp->min_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= (ulonglong) (ulong) optp->max_value;
  num= ((num - (ulonglong) optp->sub_size) / (optp->block_size ?
					      (ulonglong) optp->block_size :
					      1L));
  return (ulonglong) (num * (optp->block_size ? (ulonglong) optp->block_size :
			     1L));
}

/* 
  function: init_variables
@@ -493,12 +564,24 @@ static void init_variables(const struct my_option *options)
  {
    if (options->value)
    {
      if (options->var_type == GET_LONG)
      if (options->var_type == GET_INT)
	*((int*) options->u_max_value)= *((int*) options->value)=
	  (int) options->def_value;
      else if (options->var_type == GET_UINT)
	*((uint*) options->u_max_value)= *((uint*) options->value)=
	  (uint) options->def_value;
      else if (options->var_type == GET_LONG)
	*((long*) options->u_max_value)= *((long*) options->value)=
	  (long) options->def_value;
      else if (options->var_type == GET_ULONG)
	*((ulong*) options->u_max_value)= *((ulong*) options->value)=
	  (ulong) options->def_value;
      else if (options->var_type == GET_LL)
	*((longlong*) options->u_max_value)= *((longlong*) options->value)=
	  options->def_value;
	  (longlong) options->def_value;
      else if (options->var_type == GET_ULL)
	*((ulonglong*) options->u_max_value)= *((ulonglong*) options->value)=
	  (ulonglong) options->def_value;
    }
  }
}
@@ -604,6 +687,20 @@ void my_print_variables(const struct my_option *options)
	else
	  printf("(No default value)\n");
      }
      else if (optp->var_type == GET_INT)
      {
	if (!optp->def_value && !*((int*) optp->value))
	  printf("(No default value)\n");
	else
	  printf("%d\n", *((int*) optp->value));
      }
      else if (optp->var_type == GET_UINT)
      {
	if (!optp->def_value && !*((uint*) optp->value))
	  printf("(No default value)\n");
	else
	  printf("%d\n", *((uint*) optp->value));
      }
      else if (optp->var_type == GET_LONG)
      {
	if (!optp->def_value && !*((long*) optp->value))
@@ -611,13 +708,27 @@ void my_print_variables(const struct my_option *options)
	else
	  printf("%lu\n", *((long*) optp->value));
      }
      else if (optp->var_type == GET_ULONG)
      {
	if (!optp->def_value && !*((ulong*) optp->value))
	  printf("(No default value)\n");
	else
	  printf("%lu\n", *((ulong*) optp->value));
      }
      else if (optp->var_type == GET_LL)
      {
	if (!optp->def_value && !*((longlong*) optp->value))
	  printf("(No default value)\n");
	else
	  printf("%s\n", llstr(*((longlong*) optp->value), buff));
      }
      else if (optp->var_type == GET_ULL)
      {
	if (!optp->def_value && !*((ulonglong*) optp->value))
	  printf("(No default value)\n");
	else
	  printf("%s\n", longlong2str(*((ulonglong*) optp->value), buff, 10));
      }
    }
  }
}
+1215 −1066

File changed.

Preview size limit exceeded, changes collapsed.