Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
ccan
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
mirror
ccan
Commits
f8b1841d
Commit
f8b1841d
authored
Sep 30, 2010
by
Rusty Russell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
opt: add support for showing default value.
parent
d7d5abe9
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
451 additions
and
34 deletions
+451
-34
ccan/opt/helpers.c
ccan/opt/helpers.c
+45
-1
ccan/opt/opt.c
ccan/opt/opt.c
+2
-0
ccan/opt/opt.h
ccan/opt/opt.h
+40
-18
ccan/opt/test/run-helpers.c
ccan/opt/test/run-helpers.c
+325
-0
ccan/opt/test/run-usage.c
ccan/opt/test/run-usage.c
+3
-3
ccan/opt/test/run.c
ccan/opt/test/run.c
+1
-1
ccan/opt/test/utils.c
ccan/opt/test/utils.c
+11
-5
ccan/opt/test/utils.h
ccan/opt/test/utils.h
+2
-1
ccan/opt/usage.c
ccan/opt/usage.c
+22
-5
No files found.
ccan/opt/helpers.c
View file @
f8b1841d
...
...
@@ -5,6 +5,9 @@
#include <stdio.h>
#include "private.h"
/* Upper bound to sprintf this simple type? Each 3 bits < 1 digit. */
#define CHAR_SIZE(type) (((sizeof(type)*CHAR_BIT + 2) / 3) + 1)
/* FIXME: asprintf module? */
static
char
*
arg_bad
(
const
char
*
fmt
,
const
char
*
arg
)
{
...
...
@@ -116,7 +119,7 @@ char *opt_inc_intval(int *i)
}
/* Display version string. */
char
*
opt_
show_
version_and_exit
(
const
char
*
version
)
char
*
opt_version_and_exit
(
const
char
*
version
)
{
printf
(
"%s
\n
"
,
version
);
exit
(
0
);
...
...
@@ -127,3 +130,44 @@ char *opt_usage_and_exit(const char *extra)
printf
(
"%s"
,
opt_usage
(
opt_argv0
,
extra
));
exit
(
0
);
}
void
opt_show_bool
(
char
buf
[
OPT_SHOW_LEN
],
const
bool
*
b
)
{
strncpy
(
buf
,
*
b
?
"true"
:
"false"
,
OPT_SHOW_LEN
);
}
void
opt_show_invbool
(
char
buf
[
OPT_SHOW_LEN
],
const
bool
*
b
)
{
strncpy
(
buf
,
*
b
?
"false"
:
"true"
,
OPT_SHOW_LEN
);
}
void
opt_show_charp
(
char
buf
[
OPT_SHOW_LEN
],
char
*
const
*
p
)
{
size_t
len
=
strlen
(
*
p
);
buf
[
0
]
=
'"'
;
if
(
len
>
OPT_SHOW_LEN
-
2
)
len
=
OPT_SHOW_LEN
-
2
;
strncpy
(
buf
+
1
,
*
p
,
len
);
buf
[
1
+
len
]
=
'"'
;
}
/* Set an integer value, various forms. Sets to 1 on arg == NULL. */
void
opt_show_intval
(
char
buf
[
OPT_SHOW_LEN
],
const
int
*
i
)
{
snprintf
(
buf
,
OPT_SHOW_LEN
,
"%i"
,
*
i
);
}
void
opt_show_uintval
(
char
buf
[
OPT_SHOW_LEN
],
const
unsigned
int
*
ui
)
{
snprintf
(
buf
,
OPT_SHOW_LEN
,
"%u"
,
*
ui
);
}
void
opt_show_longval
(
char
buf
[
OPT_SHOW_LEN
],
const
long
*
l
)
{
snprintf
(
buf
,
OPT_SHOW_LEN
,
"%li"
,
*
l
);
}
void
opt_show_ulongval
(
char
buf
[
OPT_SHOW_LEN
],
const
unsigned
long
*
ul
)
{
snprintf
(
buf
,
OPT_SHOW_LEN
,
"%lu"
,
*
ul
);
}
ccan/opt/opt.c
View file @
f8b1841d
...
...
@@ -31,6 +31,7 @@ static void add_opt(const struct opt_table *entry)
void
_opt_register
(
const
char
*
longopt
,
char
shortopt
,
enum
opt_flags
flags
,
char
*
(
*
cb
)(
void
*
arg
),
char
*
(
*
cb_arg
)(
const
char
*
optarg
,
void
*
arg
),
void
(
*
show
)(
char
buf
[
OPT_SHOW_LEN
],
const
void
*
arg
),
void
*
arg
,
const
char
*
desc
)
{
struct
opt_table
opt
;
...
...
@@ -39,6 +40,7 @@ void _opt_register(const char *longopt, char shortopt, enum opt_flags flags,
opt
.
flags
=
flags
;
opt
.
cb
=
cb
;
opt
.
cb_arg
=
cb_arg
;
opt
.
show
=
show
;
opt
.
arg
=
arg
;
opt
.
desc
=
desc
;
check_opt
(
&
opt
);
...
...
ccan/opt/opt.h
View file @
f8b1841d
...
...
@@ -12,12 +12,16 @@ enum opt_flags {
OPT_END
=
8
,
/* End of the table. */
};
/* Maximum length of arg to show in opt_usage */
#define OPT_SHOW_LEN 80
struct
opt_table
{
const
char
*
longopt
;
/* --longopt, or NULL */
char
shortopt
;
/* -s, or 0 */
enum
opt_flags
flags
;
char
*
(
*
cb
)(
void
*
arg
);
/* OPT_NOARG */
char
*
(
*
cb_arg
)(
const
char
*
optarg
,
void
*
arg
);
/* OPT_HASARG */
void
(
*
show
)(
char
buf
[
OPT_SHOW_LEN
],
const
void
*
arg
);
void
*
arg
;
const
char
*
desc
;
};
...
...
@@ -48,22 +52,28 @@ struct opt_table {
* @longopt: the name of the argument (eg. "foo" for "--foo <arg>"), or NULL.
* @shortopt: the character of the argument (eg. 'f' for "-f <arg>"), or 0.
* @cb: the callback when the option is found (along with <arg>).
* @arg: the argument to hand to @cb.
* @show: the callback to print the value in get_usage (or NULL)
* @arg: the argument to hand to @cb and @show
*
* This is a typesafe wrapper for intializing a struct opt_table. The callback
* is of type "
bool
cb(const char *, type *)",
* "
bool cb(const char *, const type *)" or "bool
cb(const char *, void *)",
* is of type "
char *
cb(const char *, type *)",
* "
char *cb(const char *, const type *)" or "char *
cb(const char *, void *)",
* where "type" is the type of the @arg argument. The first argument to the
* @cb is the argument found on the commandline.
*
* Similarly, if @show is not NULL, it should be of type "void *show(char *,
* const type *)". It should write up to OPT_SHOW_LEN bytes into the first
* argument; unless it uses the entire OPT_SHOW_LEN bytes it should
* nul-terminate that buffer.
*
* At least one of @longopt and @shortopt must be non-zero. If the
* @cb returns false, opt_parse() will stop parsing and return false.
*
* See Also:
* OPT_WITH_ARG()
* OPT_WITH
OUT
_ARG()
*/
#define OPT_WITH_ARG(longopt, shortopt, cb, arg) \
(longopt), (shortopt), OPT_CB_ARG((cb), (arg))
#define OPT_WITH_ARG(longopt, shortopt, cb,
show,
arg) \
(longopt), (shortopt), OPT_CB_ARG((cb), (
show), (
arg))
/**
* OPT_SUBTABLE() - macro for including another table inside a table.
...
...
@@ -74,7 +84,7 @@ struct opt_table {
*/
#define OPT_SUBTABLE(table, desc) \
{ (const char *)(table), sizeof(_check_is_entry(table)), \
OPT_SUBTABLE,
NULL, NULL, NULL, (desc) }
OPT_SUBTABLE, NULL,
NULL, NULL, NULL, (desc) }
/**
* opt_table_hidden - string for undocumented option tables.
...
...
@@ -125,8 +135,8 @@ void opt_register_table(const struct opt_table table[], const char *desc);
* This is used for registering a single commandline option which takes
* no argument.
*
* The callback is of type "
bool cb(type *)", "bool
cb(const type *)"
* or "
bool
cb(void *)", where "type" is the type of the @arg
* The callback is of type "
char *cb(type *)", "char *
cb(const type *)"
* or "
char *
cb(void *)", where "type" is the type of the @arg
* argument.
*
* At least one of @longopt and @shortopt must be non-zero. If the
...
...
@@ -140,14 +150,15 @@ void opt_register_table(const struct opt_table table[], const char *desc);
* @longopt: the name of the argument (eg. "foo" for "--foo"), or NULL.
* @shortopt: the character of the argument (eg. 'f' for "-f"), or 0.
* @cb: the callback when the option is found.
* @show: the callback when the option is found.
* @arg: the argument to hand to @cb.
* @desc: the verbose desction of the option (for opt_usage()), or NULL.
*
* This is used for registering a single commandline option which takes
* an argument.
*
* The callback is of type "
bool
cb(const char *, type *)",
* "
bool cb(const char *, const type *)" or "bool
cb(const char *, void *)",
* The callback is of type "
char *
cb(const char *, type *)",
* "
char *cb(const char *, const type *)" or "char *
cb(const char *, void *)",
* where "type" is the type of the @arg argument. The first argument to the
* @cb is the argument found on the commandline.
*
...
...
@@ -158,8 +169,8 @@ void opt_register_table(const struct opt_table table[], const char *desc);
* opt_register_arg("explode", 'e', explode_cb, NULL,
* "Make the machine explode (developers only)");
*/
#define opt_register_arg(longopt, shortopt, cb, arg, desc) \
_opt_register((longopt), (shortopt), OPT_CB_ARG((cb
), (arg)), (desc))
#define opt_register_arg(longopt, shortopt, cb,
show,
arg, desc) \
_opt_register((longopt), (shortopt), OPT_CB_ARG((cb), (show
), (arg)), (desc))
/**
* opt_parse - parse arguments.
...
...
@@ -216,24 +227,32 @@ char *opt_usage(const char *argv0, const char *extra);
char
*
opt_set_bool
(
bool
*
b
);
/* Sets @b based on arg: (yes/no/true/false). */
char
*
opt_set_bool_arg
(
const
char
*
arg
,
bool
*
b
);
void
opt_show_bool
(
char
buf
[
OPT_SHOW_LEN
],
const
bool
*
b
);
/* The inverse */
char
*
opt_set_invbool
(
bool
*
b
);
void
opt_show_invbool
(
char
buf
[
OPT_SHOW_LEN
],
const
bool
*
b
);
/* Sets @b based on !arg: (yes/no/true/false). */
char
*
opt_set_invbool_arg
(
const
char
*
arg
,
bool
*
b
);
/* Set a char *. */
char
*
opt_set_charp
(
const
char
*
arg
,
char
**
p
);
void
opt_show_charp
(
char
buf
[
OPT_SHOW_LEN
],
char
*
const
*
p
);
/* Set an integer value, various forms. Sets to 1 on arg == NULL. */
char
*
opt_set_intval
(
const
char
*
arg
,
int
*
i
);
void
opt_show_intval
(
char
buf
[
OPT_SHOW_LEN
],
const
int
*
i
);
char
*
opt_set_uintval
(
const
char
*
arg
,
unsigned
int
*
ui
);
void
opt_show_uintval
(
char
buf
[
OPT_SHOW_LEN
],
const
unsigned
int
*
ui
);
char
*
opt_set_longval
(
const
char
*
arg
,
long
*
l
);
void
opt_show_longval
(
char
buf
[
OPT_SHOW_LEN
],
const
long
*
l
);
char
*
opt_set_ulongval
(
const
char
*
arg
,
unsigned
long
*
ul
);
void
opt_show_ulongval
(
char
buf
[
OPT_SHOW_LEN
],
const
unsigned
long
*
ul
);
/* Increment. */
char
*
opt_inc_intval
(
int
*
i
);
/* Display version string to stdout, exit(0). */
char
*
opt_
show_
version_and_exit
(
const
char
*
version
);
char
*
opt_version_and_exit
(
const
char
*
version
);
/* Display usage string to stdout, exit(0). */
char
*
opt_usage_and_exit
(
const
char
*
extra
);
...
...
@@ -245,22 +264,25 @@ char *opt_usage_and_exit(const char *extra);
cast_if_any(char *(*)(void *), (cb), &*(cb), \
char *(*)(typeof(*(arg))*), \
char *(*)(const typeof(*(arg))*), \
char *(*)(const
typeof(*(arg))*)),
\
NULL, (arg)
char *(*)(const
void *)),
\
NULL,
NULL,
(arg)
/* Resolves to the four parameters for arg callbacks. */
#define OPT_CB_ARG(cb,
arg)
\
#define OPT_CB_ARG(cb,
show, arg)
\
OPT_HASARG, NULL, \
cast_if_any(char *(*)(const char *,void *), (cb), &*(cb), \
char *(*)(const char *, typeof(*(arg))*), \
char *(*)(const char *, const typeof(*(arg))*), \
char *(*)(const char *, const typeof(*(arg))*)), \
char *(*)(const char *, const void *)), \
cast_if_type(void (*)(char buf[], const void *), (show), &*(show), \
void (*)(char buf[], const typeof(*(arg))*)), \
(arg)
/* Non-typesafe register function. */
void
_opt_register
(
const
char
*
longopt
,
char
shortopt
,
enum
opt_flags
flags
,
char
*
(
*
cb
)(
void
*
arg
),
char
*
(
*
cb_arg
)(
const
char
*
optarg
,
void
*
arg
),
void
(
*
show
)(
char
buf
[
OPT_SHOW_LEN
],
const
void
*
arg
),
void
*
arg
,
const
char
*
desc
);
/* We use this to get typechecking for OPT_SUBTABLE */
...
...
ccan/opt/test/run-helpers.c
0 → 100644
View file @
f8b1841d
#define _GNU_SOURCE
#include <stdio.h>
#include <ccan/tap/tap.h>
#include <setjmp.h>
#include <stdlib.h>
#include "utils.h"
/* We don't actually want it to exit... */
static
jmp_buf
exited
;
#define exit(status) longjmp(exited, (status) + 1)
#define printf saved_printf
static
int
saved_printf
(
const
char
*
fmt
,
...);
#include <ccan/opt/helpers.c>
#include <ccan/opt/opt.c>
#include <ccan/opt/usage.c>
static
void
reset_options
(
void
)
{
free
(
opt_table
);
opt_table
=
NULL
;
opt_count
=
0
;
}
static
char
*
output
=
NULL
;
static
int
saved_printf
(
const
char
*
fmt
,
...)
{
va_list
ap
;
char
*
p
;
int
ret
;
va_start
(
ap
,
fmt
);
ret
=
vasprintf
(
&
p
,
fmt
,
ap
);
va_end
(
ap
);
if
(
output
)
{
output
=
realloc
(
output
,
strlen
(
output
)
+
strlen
(
p
)
+
1
);
strcat
(
output
,
p
);
free
(
p
);
}
else
output
=
p
;
return
ret
;
}
/* Test helpers. */
int
main
(
int
argc
,
char
*
argv
[])
{
plan_tests
(
88
);
/* opt_set_bool */
{
bool
arg
=
false
;
reset_options
();
opt_register_noarg
(
NULL
,
'a'
,
opt_set_bool
,
&
arg
,
NULL
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-a"
,
NULL
));
ok1
(
arg
);
opt_register_arg
(
NULL
,
'b'
,
opt_set_bool_arg
,
NULL
,
&
arg
,
NULL
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-b"
,
"no"
,
NULL
));
ok1
(
!
arg
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-b"
,
"yes"
,
NULL
));
ok1
(
arg
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-b"
,
"false"
,
NULL
));
ok1
(
!
arg
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-b"
,
"true"
,
NULL
));
ok1
(
arg
);
}
/* opt_set_invbool */
{
bool
arg
=
true
;
reset_options
();
opt_register_noarg
(
NULL
,
'a'
,
opt_set_invbool
,
&
arg
,
NULL
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-a"
,
NULL
));
ok1
(
!
arg
);
opt_register_arg
(
NULL
,
'b'
,
opt_set_invbool_arg
,
NULL
,
&
arg
,
NULL
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-b"
,
"no"
,
NULL
));
ok1
(
arg
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-b"
,
"yes"
,
NULL
));
ok1
(
!
arg
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-b"
,
"false"
,
NULL
));
ok1
(
arg
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-b"
,
"true"
,
NULL
));
ok1
(
!
arg
);
}
/* opt_set_charp */
{
char
*
arg
=
(
char
*
)
"wrong"
;
reset_options
();
opt_register_arg
(
NULL
,
'a'
,
opt_set_charp
,
NULL
,
&
arg
,
NULL
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"string"
,
NULL
));
ok1
(
strcmp
(
arg
,
"string"
)
==
0
);
}
/* opt_set_intval */
{
int
arg
=
1000
;
reset_options
();
opt_register_arg
(
NULL
,
'a'
,
opt_set_intval
,
NULL
,
&
arg
,
NULL
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"9999"
,
NULL
));
ok1
(
arg
==
9999
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"-9999"
,
NULL
));
ok1
(
arg
==
-
9999
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"0"
,
NULL
));
ok1
(
arg
==
0
);
ok1
(
!
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"100crap"
,
NULL
));
if
(
sizeof
(
int
)
==
4
)
ok1
(
!
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"4294967296"
,
NULL
));
else
fail
(
"Handle other int sizes"
);
}
/* opt_set_uintval */
{
unsigned
int
arg
=
1000
;
reset_options
();
opt_register_arg
(
NULL
,
'a'
,
opt_set_uintval
,
NULL
,
&
arg
,
NULL
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"9999"
,
NULL
));
ok1
(
arg
==
9999
);
ok1
(
!
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"-9999"
,
NULL
));
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"0"
,
NULL
));
ok1
(
arg
==
0
);
ok1
(
!
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"100crap"
,
NULL
));
ok1
(
!
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"4294967296"
,
NULL
));
}
/* opt_set_longval */
{
long
int
arg
=
1000
;
reset_options
();
opt_register_arg
(
NULL
,
'a'
,
opt_set_longval
,
NULL
,
&
arg
,
NULL
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"9999"
,
NULL
));
ok1
(
arg
==
9999
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"-9999"
,
NULL
));
ok1
(
arg
==
-
9999
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"0"
,
NULL
));
ok1
(
arg
==
0
);
ok1
(
!
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"100crap"
,
NULL
));
if
(
sizeof
(
long
)
==
4
)
ok1
(
!
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"4294967296"
,
NULL
));
else
if
(
sizeof
(
long
)
==
8
)
ok1
(
!
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"18446744073709551616"
,
NULL
));
else
fail
(
"FIXME: Handle other long sizes"
);
}
/* opt_set_ulongval */
{
unsigned
long
int
arg
=
1000
;
reset_options
();
opt_register_arg
(
NULL
,
'a'
,
opt_set_ulongval
,
NULL
,
&
arg
,
NULL
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"9999"
,
NULL
));
ok1
(
arg
==
9999
);
ok1
(
!
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"-9999"
,
NULL
));
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"0"
,
NULL
));
ok1
(
arg
==
0
);
ok1
(
!
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"100crap"
,
NULL
));
if
(
sizeof
(
long
)
==
4
)
ok1
(
!
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"4294967296"
,
NULL
));
else
if
(
sizeof
(
long
)
==
8
)
ok1
(
!
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"18446744073709551616"
,
NULL
));
else
fail
(
"FIXME: Handle other long sizes"
);
}
/* opt_inc_intval */
{
int
arg
=
1000
;
reset_options
();
opt_register_noarg
(
NULL
,
'a'
,
opt_inc_intval
,
&
arg
,
NULL
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-a"
,
NULL
));
ok1
(
arg
==
1001
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-a"
,
"-a"
,
NULL
));
ok1
(
arg
==
1003
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"-aa"
,
NULL
));
ok1
(
arg
==
1005
);
}
/* opt_show_version_and_exit. */
{
int
exitval
;
reset_options
();
opt_register_noarg
(
NULL
,
'a'
,
opt_version_and_exit
,
"1.2.3"
,
NULL
);
exitval
=
setjmp
(
exited
);
if
(
exitval
==
0
)
{
parse_args
(
&
argc
,
&
argv
,
"-a"
,
NULL
);
fail
(
"opt_show_version_and_exit returned?"
);
}
else
{
ok1
(
exitval
-
1
==
0
);
}
ok1
(
strcmp
(
output
,
"1.2.3
\n
"
)
==
0
);
free
(
output
);
output
=
NULL
;
}
/* opt_usage_and_exit. */
{
int
exitval
;
reset_options
();
opt_register_noarg
(
NULL
,
'a'
,
opt_usage_and_exit
,
"[args]"
,
NULL
);
exitval
=
setjmp
(
exited
);
if
(
exitval
==
0
)
{
parse_args
(
&
argc
,
&
argv
,
"-a"
,
NULL
);
fail
(
"opt_usage_and_exit returned?"
);
}
else
{
ok1
(
exitval
-
1
==
0
);
}
ok1
(
strstr
(
output
,
"[args]"
));
ok1
(
strstr
(
output
,
argv
[
0
]));
ok1
(
strstr
(
output
,
"[-a]"
));
free
(
output
);
output
=
NULL
;
}
/* opt_show_bool */
{
bool
b
;
char
buf
[
OPT_SHOW_LEN
+
2
]
=
{
0
};
buf
[
OPT_SHOW_LEN
]
=
'!'
;
b
=
true
;
opt_show_bool
(
buf
,
&
b
);
ok1
(
strcmp
(
buf
,
"true"
)
==
0
);
ok1
(
buf
[
OPT_SHOW_LEN
]
==
'!'
);
b
=
false
;
opt_show_bool
(
buf
,
&
b
);
ok1
(
strcmp
(
buf
,
"false"
)
==
0
);
ok1
(
buf
[
OPT_SHOW_LEN
]
==
'!'
);
}
/* opt_show_invbool */
{
bool
b
;
char
buf
[
OPT_SHOW_LEN
+
2
]
=
{
0
};
buf
[
OPT_SHOW_LEN
]
=
'!'
;
b
=
true
;
opt_show_invbool
(
buf
,
&
b
);
ok1
(
strcmp
(
buf
,
"false"
)
==
0
);
ok1
(
buf
[
OPT_SHOW_LEN
]
==
'!'
);
b
=
false
;
opt_show_invbool
(
buf
,
&
b
);
ok1
(
strcmp
(
buf
,
"true"
)
==
0
);
ok1
(
buf
[
OPT_SHOW_LEN
]
==
'!'
);
}
/* opt_show_charp */
{
char
str
[
OPT_SHOW_LEN
*
2
],
*
p
;
char
buf
[
OPT_SHOW_LEN
+
2
]
=
{
0
};
buf
[
OPT_SHOW_LEN
]
=
'!'
;
/* Short test. */
p
=
str
;
strcpy
(
p
,
"short"
);
opt_show_charp
(
buf
,
&
p
);
ok1
(
strcmp
(
buf
,
"
\"
short
\"
"
)
==
0
);
ok1
(
buf
[
OPT_SHOW_LEN
]
==
'!'
);
/* Truncate test. */
memset
(
p
,
'x'
,
OPT_SHOW_LEN
*
2
);
p
[
OPT_SHOW_LEN
*
2
-
1
]
=
'\0'
;
opt_show_charp
(
buf
,
&
p
);
ok1
(
buf
[
0
]
==
'"'
);
ok1
(
buf
[
OPT_SHOW_LEN
-
1
]
==
'"'
);
ok1
(
buf
[
OPT_SHOW_LEN
]
==
'!'
);
ok1
(
strspn
(
buf
+
1
,
"x"
)
==
OPT_SHOW_LEN
-
2
);
}
/* opt_show_intval */
{
int
i
;
char
buf
[
OPT_SHOW_LEN
+
2
]
=
{
0
};
buf
[
OPT_SHOW_LEN
]
=
'!'
;
i
=
-
77
;
opt_show_intval
(
buf
,
&
i
);
ok1
(
strcmp
(
buf
,
"-77"
)
==
0
);
ok1
(
buf
[
OPT_SHOW_LEN
]
==
'!'
);
i
=
77
;
opt_show_intval
(
buf
,
&
i
);
ok1
(
strcmp
(
buf
,
"77"
)
==
0
);
ok1
(
buf
[
OPT_SHOW_LEN
]
==
'!'
);
}
/* opt_show_uintval */
{
unsigned
int
ui
;
char
buf
[
OPT_SHOW_LEN
+
2
]
=
{
0
};
buf
[
OPT_SHOW_LEN
]
=
'!'
;
ui
=
4294967295U
;
opt_show_uintval
(
buf
,
&
ui
);
ok1
(
strcmp
(
buf
,
"4294967295"
)
==
0
);
ok1
(
buf
[
OPT_SHOW_LEN
]
==
'!'
);
}
/* opt_show_longval */
{
long
l
;
char
buf
[
OPT_SHOW_LEN
+
2
]
=
{
0
};
buf
[
OPT_SHOW_LEN
]
=
'!'
;
l
=
1234567890L
;
opt_show_longval
(
buf
,
&
l
);
ok1
(
strcmp
(
buf
,
"1234567890"
)
==
0
);
ok1
(
buf
[
OPT_SHOW_LEN
]
==
'!'
);
}
/* opt_show_ulongval */
{
unsigned
long
ul
;
char
buf
[
OPT_SHOW_LEN
+
2
]
=
{
0
};
buf
[
OPT_SHOW_LEN
]
=
'!'
;
ul
=
4294967295UL
;
opt_show_ulongval
(
buf
,
&
ul
);
ok1
(
strcmp
(
buf
,
"4294967295"
)
==
0
);
ok1
(
buf
[
OPT_SHOW_LEN
]
==
'!'
);
}
return
exit_status
();
}
ccan/opt/test/run-usage.c
View file @
f8b1841d
...
...
@@ -19,7 +19,7 @@ int main(int argc, char *argv[])
char
*
output
;
plan_tests
(
18
);
opt_register_table
(
subtables
,
NULL
);
opt_register_noarg
(
"
--
kkk"
,
'k'
,
my_cb
,
NULL
,
"magic kkk option"
);
opt_register_noarg
(
"kkk"
,
'k'
,
my_cb
,
NULL
,
"magic kkk option"
);
output
=
opt_usage
(
"my name"
,
"ExTrA Args"
);
diag
(
"%s"
,
output
);
ok1
(
strstr
(
output
,
"Usage: my name"
));
...
...
@@ -28,11 +28,11 @@ int main(int argc, char *argv[])
ok1
(
strstr
(
output
,
"-a "
));
ok1
(
strstr
(
output
,
" Description of a
\n
"
));
ok1
(
strstr
(
output
,
"-b <arg>"
));
ok1
(
strstr
(
output
,
" Description of b
\n
"
));
ok1
(
strstr
(
output
,
" Description of b
(default: b)
\n
"
));
ok1
(
strstr
(
output
,
"--ddd "
));
ok1
(
strstr
(
output
,
" Description of ddd
\n
"
));
ok1
(
strstr
(
output
,
"--eee <arg> "
));
ok1
(
strstr
(
output
,
"
Description of eee
\n
"
));
ok1
(
strstr
(
output
,
"
(default: eee)
\n
"
));
ok1
(
strstr
(
output
,
"long table options:
\n
"
));
/* This table is hidden. */
ok1
(
!
strstr
(
output
,
"--ggg/-g "
));
...
...
ccan/opt/test/run.c
View file @
f8b1841d
...
...
@@ -54,7 +54,7 @@ int main(int argc, char *argv[])
/* Argument variants. */
reset_options
();
test_cb_called
=
0
;
opt_register_arg
(
"aaa"
,
'a'
,
test_arg
,
"aaa"
,
NULL
);
opt_register_arg
(
"aaa"
,
'a'
,
test_arg
,
NULL
,
"aaa"
,
NULL
);
ok1
(
parse_args
(
&
argc
,
&
argv
,
"--aaa"
,
"aaa"
,
NULL
));
ok1
(
argc
==
1
);
ok1
(
argv
[
0
]
==
myname
);
...
...
ccan/opt/test/utils.c
View file @
f8b1841d
...
...
@@ -15,13 +15,18 @@ char *test_noarg(void *arg)
return
NULL
;
}
char
*
test_arg
(
const
char
*
optarg
,
void
*
arg
)
char
*
test_arg
(
const
char
*
optarg
,
const
char
*
arg
)
{
test_cb_called
++
;
ok1
(
strcmp
(
optarg
,
arg
)
==
0
);
return
NULL
;
}
void
show_arg
(
char
buf
[
OPT_SHOW_LEN
],
const
char
*
arg
)
{
strncpy
(
buf
,
arg
,
OPT_SHOW_LEN
);
}
char
*
err_output
=
NULL
;
static
void
save_err_output
(
const
char
*
fmt
,
...)
...
...
@@ -66,14 +71,14 @@ bool parse_args(int *argc, char ***argv, ...)
struct
opt_table
short_table
[]
=
{
/* Short opts, different args. */
{
OPT_WITHOUT_ARG
(
NULL
,
'a'
,
test_noarg
,
"a"
),
"Description of a"
},
{
OPT_WITH_ARG
(
NULL
,
'b'
,
test_arg
,
"b"
),
"Description of b"
},
{
OPT_WITH_ARG
(
NULL
,
'b'
,
test_arg
,
show_arg
,
"b"
),
"Description of b"
},
OPT_ENDTABLE
};
struct
opt_table
long_table
[]
=
{
/* Long opts, different args. */
{
OPT_WITHOUT_ARG
(
"ddd"
,
0
,
test_noarg
,
"ddd"
),
"Description of ddd"
},
{
OPT_WITH_ARG
(
"eee"
,
0
,
test_arg
,
"eee"
),
"Description of eee"
},
{
OPT_WITH_ARG
(
"eee"
,
0
,
test_arg
,
show_arg
,
"eee"
),
},
OPT_ENDTABLE
};
...
...
@@ -81,14 +86,15 @@ struct opt_table long_and_short_table[] = {
/* Short and long, different args. */
{
OPT_WITHOUT_ARG
(
"ggg"
,
'g'
,
test_noarg
,
"ggg"
),
"Description of ggg"
},
{
OPT_WITH_ARG
(
"hhh"
,
'h'
,
test_arg
,
"hhh"
),
"Description of hhh"
},
{
OPT_WITH_ARG
(
"hhh"
,
'h'
,
test_arg
,
NULL
,
"hhh"
),
"Description of hhh"
},
OPT_ENDTABLE
};
/* Sub-table test. */
struct
opt_table
subtables
[]
=
{
/* Short and long, no description */
{
OPT_WITH_ARG
(
"jjj"
,
'j'
,
test_arg
,
"jjj"
)
},
{
OPT_WITH_ARG
(
"jjj"
,
'j'
,
test_arg
,
show_arg
,
"jjj"
)
},
OPT_SUBTABLE
(
short_table
,
NULL
),
OPT_SUBTABLE
(
long_table
,
"long table options"
),
OPT_SUBTABLE
(
long_and_short_table
,
opt_table_hidden
),
...
...
ccan/opt/test/utils.h
View file @
f8b1841d
...
...
@@ -8,7 +8,8 @@ extern char *err_output;
extern
unsigned
int
test_cb_called
;
char
*
test_noarg
(
void
*
arg
);
char
*
test_arg
(
const
char
*
optarg
,
void
*
arg
);
char
*
test_arg
(
const
char
*
optarg
,
const
char
*
arg
);
void
show_arg
(
char
buf
[
OPT_SHOW_LEN
],
const
char
*
arg
);
extern
struct
opt_table
short_table
[];
extern
struct
opt_table
long_table
[];
...
...
ccan/opt/usage.c
View file @
f8b1841d
...
...
@@ -25,6 +25,8 @@ static unsigned write_short_options(char *str)
return
num
;
}
#define OPT_SPACE_PAD " "
/* FIXME: Get all purdy. */
char
*
opt_usage
(
const
char
*
argv0
,
const
char
*
extra
)
{
...
...
@@ -45,8 +47,14 @@ char *opt_usage(const char *argv0, const char *extra)
len
+=
strlen
(
"--%s/-%c"
)
+
strlen
(
" <arg>"
);
if
(
opt_table
[
i
].
longopt
)
len
+=
strlen
(
opt_table
[
i
].
longopt
);
if
(
opt_table
[
i
].
desc
)
len
+=
20
+
strlen
(
opt_table
[
i
].
desc
);
if
(
opt_table
[
i
].
desc
)
{
len
+=
strlen
(
OPT_SPACE_PAD
)
+
strlen
(
opt_table
[
i
].
desc
)
+
1
;
}
if
(
opt_table
[
i
].
show
)
{
len
+=
strlen
(
"(default: %s)"
)
+
OPT_SHOW_LEN
+
sizeof
(
"..."
);
}
len
+=
strlen
(
"
\n
"
);
}
}
...
...
@@ -89,11 +97,20 @@ char *opt_usage(const char *argv0, const char *extra)
len
=
sprintf
(
p
,
"--%s"
,
opt_table
[
i
].
longopt
);
if
(
opt_table
[
i
].
flags
==
OPT_HASARG
)
len
+=
sprintf
(
p
+
len
,
" <arg>"
);
if
(
opt_table
[
i
].
desc
)
{
if
(
opt_table
[
i
].
desc
||
opt_table
[
i
].
show
)
len
+=
sprintf
(
p
+
len
,
"%.*s"
,
len
<
20
?
20
-
len
:
1
,
" "
);
len
<
strlen
(
OPT_SPACE_PAD
)
?
strlen
(
OPT_SPACE_PAD
)
-
len
:
1
,
OPT_SPACE_PAD
);
if
(
opt_table
[
i
].
desc
)
len
+=
sprintf
(
p
+
len
,
"%s"
,
opt_table
[
i
].
desc
);
if
(
opt_table
[
i
].
show
)
{
char
buf
[
OPT_SHOW_LEN
+
sizeof
(
"..."
)];
strcpy
(
buf
+
OPT_SHOW_LEN
,
"..."
);
opt_table
[
i
].
show
(
buf
,
opt_table
[
i
].
arg
);
len
+=
sprintf
(
p
+
len
,
"%s(default: %s)"
,
opt_table
[
i
].
desc
?
" "
:
""
,
buf
);
}
p
+=
len
;
p
+=
sprintf
(
p
,
"
\n
"
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment