Drizzled Public API Documentation

option.cc
1 /* Copyright (C) 2002-2006 MySQL AB
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 #include <config.h>
17 #include <drizzled/definitions.h>
18 #include <drizzled/charset.h>
19 #include <drizzled/internal/my_sys.h>
20 #include <drizzled/gettext.h>
21 
22 #include <drizzled/internal/m_string.h>
23 #include <drizzled/internal/my_sys.h>
24 #include <drizzled/error.h>
25 #include <drizzled/option.h>
26 #include <drizzled/typelib.h>
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <errno.h>
31 #include <iostream>
32 #include <algorithm>
33 
34 using namespace std;
35 
36 namespace drizzled {
37 
38 static void default_reporter(enum loglevel level, const char *format, ...)
39 {
40  va_list args;
41  va_start(args, format);
42 
43  if (level == WARNING_LEVEL)
44  fprintf(stderr, "%s", _("Warning: "));
45  else if (level == INFORMATION_LEVEL)
46  fprintf(stderr, "%s", _("Info: "));
47 
48  vfprintf(stderr, format, args);
49  va_end(args);
50  fputc('\n', stderr);
51  fflush(stderr);
52 }
53 
54 /*
55 function: compare_strings
56 
57 Works like strncmp, other than 1.) considers '-' and '_' the same.
58 2.) Returns -1 if strings differ, 0 if they are equal
59  */
60 
61 bool getopt_compare_strings(const char *s, const char *t, uint32_t length)
62 {
63  char const *end= s + length;
64  for (;s != end ; s++, t++)
65  {
66  if ((*s != '-' ? *s : '_') != (*t != '-' ? *t : '_'))
67  {
68  return true;
69  }
70  }
71 
72  return false;
73 }
74 
75 /*
76 function: getopt_ll_limit_value
77 
78 Applies min/max/block_size to a numeric value of an option.
79 Returns "fixed" value.
80  */
81 
82 int64_t getopt_ll_limit_value(int64_t num, const option& optp, bool *fix)
83 {
84  int64_t old= num;
85  bool adjusted= false;
86  char buf1[255], buf2[255];
87  uint64_t block_size= optp.block_size ? optp.block_size : 1;
88 
89  if (num > 0 && ((uint64_t) num > (uint64_t) optp.max_value) &&
90  optp.max_value) /* if max value is not set -> no upper limit */
91  {
92  num= (uint64_t) optp.max_value;
93  adjusted= true;
94  }
95 
96  switch ((optp.var_type & GET_TYPE_MASK)) {
97  case GET_INT:
98  if (num > (int64_t) INT_MAX)
99  {
100  num= ((int64_t) INT_MAX);
101  adjusted= true;
102  }
103  break;
104  case GET_LONG:
105  if (num > (int64_t) INT32_MAX)
106  {
107  num= ((int64_t) INT32_MAX);
108  adjusted= true;
109  }
110  break;
111  default:
112  assert((optp.var_type & GET_TYPE_MASK) == GET_LL);
113  break;
114  }
115 
116  num= ((num - optp.sub_size) / block_size);
117  num= (int64_t) (num * block_size);
118 
119  if (num < optp.min_value)
120  {
121  num= optp.min_value;
122  adjusted= true;
123  }
124 
125  if (fix)
126  {
127  *fix= adjusted;
128  }
129  else if (adjusted)
130  {
131  default_reporter(WARNING_LEVEL,
132  "option '%s': signed value %s adjusted to %s",
133  optp.name, internal::llstr(old, buf1), internal::llstr(num, buf2));
134  }
135  return num;
136 }
137 
138 /*
139 function: getopt_ull
140 
141 This is the same as getopt_ll, but is meant for uint64_t
142 values.
143  */
144 
145 uint64_t getopt_ull_limit_value(uint64_t num, const option& optp, bool *fix)
146 {
147  bool adjusted= false;
148  uint64_t old= num;
149  char buf1[255], buf2[255];
150 
151  if ((uint64_t) num > (uint64_t) optp.max_value &&
152  optp.max_value) /* if max value is not set -> no upper limit */
153  {
154  num= (uint64_t) optp.max_value;
155  adjusted= true;
156  }
157 
158  switch (optp.var_type & GET_TYPE_MASK)
159  {
160  case GET_UINT:
161  if (num > UINT_MAX)
162  {
163  num= UINT_MAX;
164  adjusted= true;
165  }
166  break;
167  case GET_UINT32:
168  case GET_ULONG_IS_FAIL:
169  if (num > UINT32_MAX)
170  {
171  num= UINT32_MAX;
172  adjusted= true;
173  }
174  break;
175  case GET_SIZE:
176  if (num > SIZE_MAX)
177  {
178  num= SIZE_MAX;
179  adjusted= true;
180  }
181  break;
182  default:
183  assert((optp.var_type & GET_TYPE_MASK) == GET_ULL || (optp.var_type & GET_TYPE_MASK) == GET_UINT64);
184  }
185 
186  if (optp.block_size > 1)
187  {
188  num/= optp.block_size;
189  num*= optp.block_size;
190  }
191 
192  if (num < (uint64_t) optp.min_value)
193  {
194  num= (uint64_t) optp.min_value;
195  adjusted= true;
196  }
197 
198  if (fix)
199  *fix= adjusted;
200  else if (adjusted)
201  default_reporter(WARNING_LEVEL, "option '%s': unsigned value %s adjusted to %s",
202  optp.name, internal::ullstr(old, buf1), internal::ullstr(num, buf2));
203 
204  return num;
205 }
206 
207 
208 /*
209 function: my_print_options
210 
211 Print help for all options and variables.
212  */
213 
214 void my_print_help(const option* options)
215 {
216  uint32_t col, name_space= 22, comment_space= 57;
217  const char *line_end;
218  const struct option *optp;
219 
220  for (optp= options; optp->id; optp++)
221  {
222  if (optp->id < 256)
223  {
224  printf(" -%c%s", optp->id, strlen(optp->name) ? ", " : " ");
225  col= 6;
226  }
227  else
228  {
229  printf(" ");
230  col= 2;
231  }
232  if (strlen(optp->name))
233  {
234  printf("--%s", optp->name);
235  col+= 2 + (uint32_t) strlen(optp->name);
236  if ((optp->var_type & GET_TYPE_MASK) == GET_STR ||
237  (optp->var_type & GET_TYPE_MASK) == GET_STR_ALLOC)
238  {
239  printf("%s=name%s ", optp->arg_type == OPT_ARG ? "[" : "",
240  optp->arg_type == OPT_ARG ? "]" : "");
241  col+= (optp->arg_type == OPT_ARG) ? 8 : 6;
242  }
243  else if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
244  (optp->var_type & GET_TYPE_MASK) == GET_BOOL)
245  {
246  putchar(' ');
247  col++;
248  }
249  else
250  {
251  printf("%s=#%s ", optp->arg_type == OPT_ARG ? "[" : "",
252  optp->arg_type == OPT_ARG ? "]" : "");
253  col+= (optp->arg_type == OPT_ARG) ? 5 : 3;
254  }
255  if (col > name_space && optp->comment && *optp->comment)
256  {
257  putchar('\n');
258  col= 0;
259  }
260  }
261  for (; col < name_space; col++)
262  putchar(' ');
263  if (optp->comment && *optp->comment)
264  {
265  const char *comment= _(optp->comment), *end= strchr(comment, '\0');
266 
267  while ((uint32_t) (end - comment) > comment_space)
268  {
269  for (line_end= comment + comment_space; *line_end != ' '; line_end--)
270  {}
271  for (; comment != line_end; comment++)
272  putchar(*comment);
273  comment++; /* skip the space, as a newline will take it's place now */
274  putchar('\n');
275  for (col= 0; col < name_space; col++)
276  putchar(' ');
277  }
278  printf("%s", comment);
279  }
280  putchar('\n');
281  if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
282  (optp->var_type & GET_TYPE_MASK) == GET_BOOL)
283  {
284  if (optp->def_value != 0)
285  {
286  printf(_("%*s(Defaults to on; use --skip-%s to disable.)\n"), name_space, "", optp->name);
287  }
288  }
289  }
290 }
291 
292 
293 } /* namespace drizzled */