This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Tarantool -- an efficient key/value data store".
The branch core-help has been updated
via 3ef3176a37b12368b742ba05b831beea4c6db8ea (commit)
via 07dc47fa277f46f4e422823b142c0bb66ea21f92 (commit)
via 2f2fb3462be08c2b43ec9674b87c4e4e9dff5f57 (commit)
via bbca430955345a57b8111eb53049211164faa130 (commit)
via cf9cc2df9f9bfa979425d922aeae22d2f5a71664 (commit)
via 44f5399b490759ee47c34bf3ed01d08d381d167e (commit)
via c06cda26cf897423f85ba7cad0e68ef54104186a (commit)
via 44d0c1ca72506fffb8801c523c090bfac73779bd (commit)
via 3e544aac4d63cfc7d1436fbd187d2da46eafe1a2 (commit)
via 60f28f1bcb27dd977a1f8409e8d1cf2740a44844 (commit)
via a2bd93f68da0334bd621b91439c33710404607fa (commit)
via f7bbe259d425025cb33281f650160172f06cff18 (commit)
via 9298278ebf4940e54a6fd0d497c82af1dc716412 (commit)
via dd0aafb406e917f46b92aebbdba53454c182ef44 (commit)
via dbf7c101a499bb5ebaee47b2c88741f43a42f769 (commit)
via f7e3f794b94898724dc4f718098e89db54edf93e (commit)
via 1a9bd036e09cf3fdba12d6a70a5365dd14fecac3 (commit)
via 6039c2e086d265c073a125c6878dff889ef5579d (commit)
via a4d75a661820c7864a770d1d8191ec5e218ecdaf (commit)
via aba07b3511dcc10e3f0a1d7f5bc0ec8aa2950fd9 (commit)
via 922a27bf240e472299e93fa452ab0988fa42a424 (commit)
from b2fc4fd40a0e7d2caa29b535c5eeb758930f0b06 (commit)
Summary of changes:
.gitignore | 4 +-
Makefile | 5 +
core/tarantool.c | 152 ++-----
doc/silverbox-protocol.txt | 407 +++++++++++++----
include/tarantool.h | 5 +-
mod/silverbox/Makefile | 1 +
mod/silverbox/assoc.h | 11 +-
mod/silverbox/box.c | 522 +--------------------
mod/silverbox/box.h | 77 +---
mod/silverbox/client/perl/lib/MR/SilverBox.pm | 2 +-
mod/silverbox/index.c | 607 +++++++++++++++++++++++++
mod/silverbox/{box.h => index.h} | 139 ++-----
mod/silverbox/memcached.c | 4 +-
mod/silverbox/memcached.rl | 4 +-
mod/silverbox/t/box.pl | 35 ++-
scripts/rules.mk | 1 +
scripts/run_test.sh | 8 +-
test/Makefile | 3 +
test/admin.py | 145 ++++++
test/box/show.test | 58 +++
test/box/suite.ini | 5 +
test/box/tarantool.cfg | 16 +
test/cmd/args.test | 8 +
test/cmd/suite.ini | 5 +
test/cmd/tarantool.cfg | 16 +
test/cmdline.py | 84 ++++
test/run | 1 +
test/test-run.py | 435 ++++++++++++++++++
third_party/Makefile | 2 +
third_party/gopt/gopt.c | 298 ++++++++++++
third_party/gopt/gopt.h | 64 +++
31 files changed, 2249 insertions(+), 875 deletions(-)
create mode 100644 mod/silverbox/index.c
copy mod/silverbox/{box.h => index.h} (55%)
create mode 100644 test/Makefile
create mode 100755 test/admin.py
create mode 100644 test/box/show.test
create mode 100644 test/box/suite.ini
create mode 100644 test/box/tarantool.cfg
create mode 100644 test/cmd/args.test
create mode 100644 test/cmd/suite.ini
create mode 100644 test/cmd/tarantool.cfg
create mode 100755 test/cmdline.py
create mode 120000 test/run
create mode 100755 test/test-run.py
create mode 100644 third_party/gopt/gopt.c
create mode 100644 third_party/gopt/gopt.h
commit 3ef3176a37b12368b742ba05b831beea4c6db8ea
Merge: 2f2fb34 07dc47f
Author: Yuriy Vostrikov <[email protected]>
Date: Mon Dec 13 17:58:30 2010 +0300
Merge branch 'test-runner' into core-help
commit 2f2fb3462be08c2b43ec9674b87c4e4e9dff5f57
Author: Yuriy Vostrikov <[email protected]>
Date: Mon Dec 13 11:12:01 2010 +0300
[core] Implement command options parsing via gopt.
diff --git a/core/tarantool.c b/core/tarantool.c
index 4436043..c5e9250 100644
--- a/core/tarantool.c
+++ b/core/tarantool.c
@@ -50,16 +50,15 @@
#include <stat.h>
#include <tarantool.h>
#include <util.h>
+#include <third_party/gopt/gopt.h>
#include <tarantool_version.h>
static pid_t master_pid;
-char *cfg_filename = "tarantool.cfg";
+const char *cfg_filename = "tarantool.cfg";
struct tarantool_cfg cfg;
bool init_storage;
-enum tarantool_role role = def;
-
extern int daemonize(int nochdir, int noclose);
const char *
@@ -221,30 +220,12 @@ initialize_minimal()
initialize(0.1, 4, 2);
}
-static void
-print_usage(void)
-{
- puts("usage:");
- puts(" -h, --help");
- puts(" -c, --config=filename");
-#ifdef STORAGE
- puts(" --cat=filename");
- puts(" --init_storage");
-#endif
- puts(" -V, --version");
- puts(" -p, --create_pid");
- puts(" -v, --verbose");
- puts(" -D, --daemonize");
- puts(" --cfg_get=paramname");
-}
int
main(int argc, char **argv)
{
- int c, verbose = 0;
- char *cat_filename = NULL;
- char *cfg_paramname = NULL;
- bool be_daemon = false;
+ const char *cat_filename = NULL;
+ const char *cfg_paramname = NULL;
int n_accepted, n_skipped;
FILE *f;
@@ -255,90 +236,44 @@ main(int argc, char **argv)
stat_init();
palloc_init();
- const char *short_opt = "hc:pvVD";
- const struct option long_opt[] = {
- {.name = "help",
- .has_arg = 0,
- .flag = NULL,
- .val = 'h'},
- {.name = "config",
- .has_arg = 1,
- .flag = NULL,
- .val = 'c'},
+ const void *opt_def =
+ gopt_start(gopt_option('h', 0, gopt_shorts('h', '?'),
gopt_longs("help"),
+ NULL, "display this help"),
+ gopt_option('c', GOPT_ARG, gopt_shorts('c'),
gopt_longs("config"),
+ "=<filename>", "path to config file"),
+ gopt_option('v', 0, gopt_shorts('V'),
gopt_longs("version"),
+ NULL, "print version"),
#ifdef STORAGE
- {.name = "cat",
- .has_arg = 1,
- .flag = NULL,
- .val = 'C'},
- {.name = "init_storage",
- .has_arg = 0,
- .flag = NULL,
- .val = 'I'},
+ gopt_option('C', 0, gopt_shorts(0),
gopt_longs("cat"),
+ "=<filename>", "cat file to stdout in
readable format"),
+ gopt_option('I', 0, gopt_shorts(0),
gopt_longs("init_storage", "init-storage"),
+ NULL, "initialize storage"),
#endif
- {.name = "create_pid",
- .has_arg = 0,
- .flag = NULL,
- .val = 'p'},
- {.name = "verbose",
- .has_arg = 0,
- .flag = NULL,
- .val = 'v'},
- {.name = "version",
- .has_arg = 0,
- .flag = NULL,
- .val = 'V'},
- {.name = "daemonize",
- .has_arg = 0,
- .flag = NULL,
- .val = 'D'},
- {.name = "cfg_get",
- .has_arg = 1,
- .flag = NULL,
- .val = 'g'},
- {.name = NULL,
- .has_arg = 0,
- .flag = NULL,
- .val = 0}
- };
-
- while ((c = getopt_long(argc, argv, short_opt, long_opt, NULL)) != -1) {
- switch (c) {
- case 'V':
- puts(tarantool_version());
- return 0;
- case 'c':
- if (optarg == NULL)
- panic("no arg given");
- cfg_filename = strdup(optarg);
- break;
- case 'C':
- if (optarg == NULL)
- panic("no arg given");
- cat_filename = strdup(optarg);
- role = cat;
- case 'v':
- verbose++;
- break;
- case 'p':
- cfg.pid_file = "tarantool.pid";
- break;
- case 'D':
- be_daemon = true;
- break;
- case 'I':
- init_storage = true;
- break;
- case 'g':
- role = cfg_get;
- cfg_paramname = strdup(optarg);
- break;
- case 'h':
- print_usage();
- return 0;
- }
+ gopt_option('v', 0, gopt_shorts('v'),
gopt_longs("verbose"),
+ NULL, "increase log level"),
+ gopt_option('D', 0, gopt_shorts('D'),
gopt_longs("daemonize"),
+ NULL, "daemonize"),
+ gopt_option('g', GOPT_ARG, gopt_shorts(0),
gopt_longs("cfg_get", "cfg-get"),
+ "=<key>", "return value from config
described by key"));
+
+ void *opt = gopt_sort(&argc, (const char **)argv, opt_def);
+
+ if (gopt(opt, 'V')){
+ puts(tarantool_version());
+ return 0;
+ }
+
+ if (gopt(opt, 'h')) {
+ puts("usage:");
+ gopt_help(opt_def);
+ return 0;
}
- if (argc != optind) {
+ /* If config filename given in command line it will override the
default */
+ gopt_arg(opt, 'c', &cfg_filename);
+ cfg.log_level += gopt(opt, 'v');
+
+ if (argc != 1) {
fprintf(stderr, "Can't parse command line: try --help or -h for
help.\n");
exit(EX_USAGE);
}
@@ -365,7 +300,7 @@ main(int argc, char **argv)
fclose(f);
#ifdef STORAGE
- if (role == cat) {
+ if (gopt_arg(opt, 'C', &cat_filename)) {
initialize_minimal();
if (access(cat_filename, R_OK) == -1) {
say_syserror("access(\"%s\")", cat_filename);
@@ -375,7 +310,7 @@ main(int argc, char **argv)
}
#endif
- if (role == cfg_get) {
+ if (gopt_arg(opt, 'g', &cfg_paramname)) {
tarantool_cfg_iterator_t *i;
char *key, *value;
@@ -394,8 +329,6 @@ main(int argc, char **argv)
return 1;
}
- cfg.log_level += verbose;
-
if (cfg.work_dir != NULL && chdir(cfg.work_dir) == -1)
say_syserror("can't chdir to `%s'", cfg.work_dir);
@@ -436,7 +369,8 @@ main(int argc, char **argv)
#endif
}
#ifdef STORAGE
- if (init_storage) {
+ if (gopt(opt, 'I')) {
+ init_storage = true;
initialize_minimal();
mod_init();
next_lsn(recovery_state, 1);
@@ -445,7 +379,7 @@ main(int argc, char **argv)
exit(EXIT_SUCCESS);
}
#endif
- if (be_daemon)
+ if (gopt(opt, 'D'))
daemonize(1, 1);
if (cfg.pid_file != NULL) {
diff --git a/include/tarantool.h b/include/tarantool.h
index a308f3e..cde791a 100644
--- a/include/tarantool.h
+++ b/include/tarantool.h
@@ -41,7 +41,7 @@ void mod_exec(char *str, int len, struct tbuf *out);
extern struct tarantool_module module;
extern struct tarantool_cfg cfg;
-extern char *cfg_filename;
+extern const char *cfg_filename;
extern bool init_storage;
void snapshot(void *ev __unused__, int events __unused__);
const char *tarantool_version(void);
@@ -51,7 +51,4 @@ double tarantool_uptime(void);
char **init_set_proc_title(int argc, char **argv);
void set_proc_title(const char *format, ...);
-enum tarantool_role { usage, cat, def, cfg_get };
-extern enum tarantool_role role;
-
#endif
diff --git a/third_party/Makefile b/third_party/Makefile
index 50158d3..a2de6b5 100644
--- a/third_party/Makefile
+++ b/third_party/Makefile
@@ -3,7 +3,9 @@ obj += third_party/daemon.o
obj += third_party/coro/coro.o
obj += third_party/proctitle.o
obj += third_party/confetti/prscfg.o
+obj += third_party/gopt/gopt.o
third_party/coro/coro.o third_party/confetti/prscfg.o: CFLAGS += -Wno-unused
+third_party/gopt/gopt.o: CFLAGS += -Wno-all
CFLAGS += -DCORO_$(CORO_IMPL)
diff --git a/third_party/gopt/gopt.c b/third_party/gopt/gopt.c
new file mode 100644
index 0000000..3f9e3bb
--- /dev/null
+++ b/third_party/gopt/gopt.c
@@ -0,0 +1,298 @@
+/* gopt.c version 8.1: [email protected] PUBLIC DOMAIN 2003-8 */
+/*
+I, Tom Vajzovic, am the author of this software and its documentation and
+permanently abandon all copyright and other intellectual property rights in
+them, including the right to be identified as the author.
+
+I am fairly certain that this software does what the documentation says it
+does, but I cannot guarantee that it does, or that it does what you think it
+should, and I cannot guarantee that it will not have undesirable side effects.
+
+You are free to use, modify and distribute this software as you please, but
+you do so at your own risk. If you remove or hide this warning then you are
+responsible for any problems encountered by people that you make the software
+available to.
+
+Before modifying or distributing this software I ask that you would please
+read http://www.purposeful.co.uk/tfl/
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "gopt.h"
+
+#ifdef USE_SYSEXITS
+#include <sysexits.h>
+#else
+#define EX_OSERR EXIT_FAILURE
+#define EX_USAGE EXIT_FAILURE
+#endif
+
+struct opt_spec_s {
+ int key;
+ int flags;
+ const char *shorts;
+ const char* const *longs;
+ const char *help_arg;
+ const char *help;
+};
+typedef struct opt_spec_s opt_spec_t;
+
+struct opt_s {
+ int key;
+ const char *arg;
+};
+typedef struct opt_s opt_t;
+
+void *gopt_sort( int *argc, const char **argv, const void *opt_specs ){
+ void *opts;
+ {{{
+ const char* const *arg_p= argv + 1;
+ size_t opt_count= 1;
+ for( ; *arg_p; ++arg_p )
+ if( '-' == (*arg_p)[0] && (*arg_p)[1] )
+ if( '-' == (*arg_p)[1] )
+ if( (*arg_p)[2] )
+ ++opt_count;
+ else
+ break;
+ else {
+ const opt_spec_t *opt_spec_p= opt_specs;
+ for( ; opt_spec_p-> key; ++opt_spec_p )
+ if( strchr( opt_spec_p-> shorts, (*arg_p)[1] )){
+ opt_count+= opt_spec_p-> flags & GOPT_ARG ? 1 : strlen( (*arg_p)
+ 1 );
+ break;
+ }
+ }
+ opts= malloc( opt_count * sizeof(opt_t) );
+ }}}
+ {
+ const char **arg_p= argv + 1;
+ const char **next_operand= arg_p;
+ opt_t *next_option= opts;
+
+ if( ! opts ){
+ perror( argv[0] );
+ exit( EX_OSERR );
+ }
+ for( ; *arg_p; ++arg_p )
+ if( '-' == (*arg_p)[0] && (*arg_p)[1] )
+ if( '-' == (*arg_p)[1] )
+ if( (*arg_p)[2] )
+ {{{
+ const opt_spec_t *opt_spec_p= opt_specs;
+ const char* const *longs= opt_spec_p-> longs;
+ next_option-> key= 0;
+ while( *longs ){
+ const char *option_cp= (*arg_p) + 2;
+ const char *name_cp= *longs;
+ while( *option_cp && *option_cp == *name_cp ){
+ ++option_cp;
+ ++name_cp;
+ }
+ if( '=' == *option_cp || !*option_cp ){
+ if( *name_cp ){
+ if( next_option-> key ){
+ fprintf( stderr, "%s: --%.*s: abbreviated option is
ambiguous\n", argv[0], (int)( option_cp -( (*arg_p) + 2 )), (*arg_p) + 2 );
+ free( opts );
+ exit( EX_USAGE );
+ }
+ next_option-> key= opt_spec_p-> key;
+ }
+ else {
+ next_option-> key= opt_spec_p-> key;
+ goto found_long;
+ }
+ }
+ if( !*++longs ){
+ ++opt_spec_p;
+ if( opt_spec_p-> key )
+ longs= opt_spec_p-> longs;
+ }
+ }
+ if( ! next_option-> key ){
+ fprintf( stderr, "%s: --%.*s: unknown option\n", argv[0],
(int)strcspn( (*arg_p) + 2, "=" ), (*arg_p) + 2 );
+ free( opts );
+ exit( EX_USAGE );
+ }
+ for( opt_spec_p= opt_specs; opt_spec_p-> key != next_option-> key;
++opt_spec_p );
+ found_long:
+
+ if( !( opt_spec_p-> flags & GOPT_REPEAT )){
+ const opt_t *opt_p= opts;
+ for( ; opt_p != next_option; ++opt_p )
+ if( opt_p-> key == opt_spec_p-> key ){
+ fprintf( stderr, "%s: --%.*s: option may not be repeated (in
any long or short form)\n", argv[0], (int)strcspn( (*arg_p) + 2, "=" ),
(*arg_p) + 2 );
+ free( opts );
+ exit( EX_USAGE );
+ }
+ }
+ if( opt_spec_p-> flags & GOPT_ARG ){
+ next_option-> arg= strchr( (*arg_p) + 2, '=' ) + 1;
+ if( (char*)0 + 1 == next_option-> arg ){
+ ++arg_p;
+ if( !*arg_p || '-' == (*arg_p)[0] && (*arg_p)[1] ){
+ fprintf( stderr, "%s: --%s: option requires an option
argument\n", argv[0], (*(arg_p-1)) + 2 );
+ free( opts );
+ exit( EX_USAGE );
+ }
+ next_option-> arg= *arg_p;
+ }
+ }
+ else {
+ if( strchr( (*arg_p) + 2, '=' )){
+ fprintf( stderr, "%s: --%.*s: option may not take an option
argument\n", argv[0], (int)strcspn( (*arg_p) + 2, "=" ), (*arg_p) + 2 );
+ free( opts );
+ exit( EX_USAGE );
+ }
+ next_option-> arg= NULL;
+ }
+ ++next_option;
+ }}}
+ else {
+ for( ++arg_p; *arg_p; ++arg_p )
+ *next_operand++= *arg_p;
+ break;
+ }
+ else
+ {{{
+ const char *short_opt= (*arg_p) + 1;
+ for( ;*short_opt; ++short_opt ){
+ const opt_spec_t *opt_spec_p= opt_specs;
+
+ for( ; opt_spec_p-> key; ++opt_spec_p )
+ if( strchr( opt_spec_p-> shorts, *short_opt )){
+ if( !( opt_spec_p-> flags & GOPT_REPEAT )){
+ const opt_t *opt_p= opts;
+ for( ; opt_p != next_option; ++opt_p )
+ if( opt_p-> key == opt_spec_p-> key ){
+ fprintf( stderr, "%s: -%c: option may not be repeated
(in any long or short form)\n", argv[0], *short_opt );
+ free( opts );
+ exit( EX_USAGE );
+ }
+ }
+ next_option-> key= opt_spec_p-> key;
+
+ if( opt_spec_p-> flags & GOPT_ARG ){
+ if( short_opt[1] )
+ next_option-> arg= short_opt + 1;
+
+ else {
+ ++arg_p;
+ if( !*arg_p || '-' == (*arg_p)[0] && (*arg_p)[1] ){
+ fprintf( stderr, "%s: -%c: option requires an option
argument\n", argv[0], *short_opt );
+ free( opts );
+ exit( EX_USAGE );
+ }
+ next_option-> arg= *arg_p;
+ }
+ ++next_option;
+ goto break_2;
+ }
+ next_option-> arg= NULL;
+ ++next_option;
+ goto continue_2;
+ }
+ fprintf( stderr, "%s: -%c: unknown option\n", argv[0], *short_opt
);
+ free( opts );
+ exit( EX_USAGE );
+ continue_2: 0;
+ }
+ break_2: 0;
+ }}}
+ else
+ *next_operand++= *arg_p;
+
+ next_option-> key= 0;
+ *next_operand= NULL;
+ *argc= next_operand - argv;
+ }
+ return opts;
+}
+
+size_t gopt( const void *vptr_opts, int key ){
+ const opt_t *opts= vptr_opts;
+ size_t count= 0;
+ for( ; opts-> key; ++opts )
+ count+= opts-> key == key;
+
+ return count;
+}
+
+size_t gopt_arg( const void *vptr_opts, int key, const char **arg ){
+ const opt_t *opts= vptr_opts;
+ size_t count= 0;
+
+ for( ; opts-> key; ++opts )
+ if( opts-> key == key ){
+ if( ! count )
+ *arg= opts-> arg;
+ ++count;
+ }
+ return count;
+}
+
+const char *gopt_arg_i( const void *vptr_opts, int key, size_t i ){
+ const opt_t *opts= vptr_opts;
+
+ for( ; opts-> key; ++opts )
+ if( opts-> key == key ){
+ if( ! i )
+ return opts-> arg;
+ --i;
+ }
+ return NULL;
+}
+
+size_t gopt_args( const void *vptr_opts, int key, const char **args, size_t
args_len ){
+ const char **args_stop= args + args_len;
+ const char **args_ptr= args;
+ const opt_t *opts= vptr_opts;
+
+ for( ; opts-> key; ++opts )
+ if( opts-> key == key ){
+ if( args_stop == args_ptr )
+ return args_len + gopt( opts, key );
+
+ *args_ptr++= opts-> arg;
+ }
+ if( args_stop != args_ptr )
+ *args_ptr= NULL;
+ return args_ptr - args;
+}
+
+void gopt_free( void *vptr_opts ){
+ free( vptr_opts );
+}
+
+void gopt_help(const void *opt_def){
+ const struct opt_spec_s *opt = opt_def;
+ while (opt->key) {
+ const char *shorts = opt->shorts;
+ char has_shorts = 0;
+ printf("\t");
+ if (*shorts) {
+ has_shorts = 1;
+ printf("-%c", *shorts++);
+ } else
+ printf(" ");
+
+ const char *const *longs = opt->longs;
+ if (*longs) {
+ if (has_shorts)
+ printf(", ");
+ else
+ printf(" ");
+ if (opt->help_arg)
+ printf("--%s%-*s", *longs, 25 - strlen(*longs), opt->help_arg);
+ else
+ printf("--%-*s", 25, *longs);
+ }
+ if (opt->help)
+ puts(opt->help);
+ else
+ puts("");
+ opt++;
+ }
+}
diff --git a/third_party/gopt/gopt.h b/third_party/gopt/gopt.h
new file mode 100644
index 0000000..441e8b1
--- /dev/null
+++ b/third_party/gopt/gopt.h
@@ -0,0 +1,64 @@
+/* gopt.h version 8.1: [email protected] PUBLIC DOMAIN 2003-8 */
+/*
+I, Tom Vajzovic, am the author of this software and its documentation and
+permanently abandon all copyright and other intellectual property rights in
+them, including the right to be identified as the author.
+
+I am fairly certain that this software does what the documentation says it
+does, but I cannot guarantee that it does, or that it does what you think it
+should, and I cannot guarantee that it will not have undesirable side effects.
+
+You are free to use, modify and distribute this software as you please, but
+you do so at your own risk. If you remove or hide this warning then you are
+responsible for any problems encountered by people that you make the software
+available to.
+
+Before modifying or distributing this software I ask that you would please
+read http://www.purposeful.co.uk/tfl/
+*/
+
+#ifndef GOPT_H_INCLUDED
+#define GOPT_H_INCLUDED
+
+#define GOPT_ONCE 0
+#define GOPT_REPEAT 1
+#define GOPT_NOARG 0
+#define GOPT_ARG 2
+
+#define gopt_start(...) (const void*)( const struct { int k; int f; const
char *s; const char*const*l; const char *a; const char *h;}[]){ __VA_ARGS__,
{0, 0, NULL, NULL, NULL, NULL}}
+#define gopt_option(k,f,s,l,a,h) { k, f, s, l, a, h }
+#define gopt_shorts( ... ) (const char*)(const char[]){ __VA_ARGS__, 0 }
+#define gopt_longs( ... ) (const char**)(const char*[]){ __VA_ARGS__,
NULL }
+
+
+void *gopt_sort( int *argc, const char **argv, const void *opt_specs );
+/* returns a pointer for use in the following calls
+ * prints to stderr and call exit() on error
+ */
+size_t gopt( const void *opts, int key );
+/* returns the number of times the option was specified
+ * which will be 0 or 1 unless GOPT_REPEAT was used
+ */
+size_t gopt_arg( const void *opts, int key, const char **arg );
+/* returns the number of times the option was specified
+ * writes a pointer to the option argument from the first (or only) occurance
to *arg
+ */
+const char *gopt_arg_i( const void *opts, int key, size_t i );
+/* returns a pointer to the ith (starting at zero) occurance
+ * of the option, or NULL if it was not specified that many times
+ */
+size_t gopt_args( const void *opts, int key, const char **args, size_t
args_len );
+/* returns the number of times the option was specified
+ * writes pointers to the option arguments in the order of occurance to args[].
+ * writes at most args_len pointers
+ * if the return value is less than args_len, also writes a null pointer
+ */
+void gopt_free( void *opts );
+/* releases memory allocated in the corresponding call to gopt_sort()
+ * opts can no longer be used
+ */
+
+void gopt_help(const void *opt_def);
+/* prints options description */
+
+#endif /* GOPT_H_INCLUDED */
--
Tarantool -- an efficient key/value data store
_______________________________________________
Mailing list: https://launchpad.net/~tarantool-developers
Post to : [email protected]
Unsubscribe : https://launchpad.net/~tarantool-developers
More help : https://help.launchpad.net/ListHelp