Skip to content

Commit e36bf67

Browse files
committed
Added error messages, added cmake options
Now, argparse can be compiled with the support for error messages, which can be obtained via `arg_geterror ()`. If argparse was compiled without the support for error messages, NULL will be returned instead. Added CMake option to compile example.c via `-DARGPARSE_EXAMPLES` option.
1 parent 235338c commit e36bf67

File tree

5 files changed

+96
-24
lines changed

5 files changed

+96
-24
lines changed

CMakeLists.txt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,32 @@
1-
cmake_minimum_required (VERSION 3.10)
1+
cmake_minimum_required (VERSION 3.12)
22
project (argparse)
33

44
set (CMAKE_C_FLAGS "-O3")
5+
option (ARGPARSE_ERRORS "builtin error description via arg_geterror ()" OFF)
6+
option (ARGPARSE_EXAMPLES "build examples" OFF)
57

68
set (argparse_h
79
${PROJECT_SOURCE_DIR}/argparse.h)
810
set (argparse_c
911
${PROJECT_SOURCE_DIR}/argparse.c)
12+
set (argparse_example_c
13+
${PROJECT_SOURCE_DIR}/example.c)
1014
add_library (argparse SHARED
15+
${argparse_h}
1116
${argparse_c})
1217

1318
set_target_properties (argparse PROPERTIES OUTPUT_NAME "argparse")
1419

20+
if (ARGPARSE_ERRORS)
21+
target_compile_definitions (argparse PUBLIC ARGPARSE_ERRORS)
22+
endif()
23+
24+
if (ARGPARSE_EXAMPLES)
25+
add_executable (argparse_ex
26+
${argparse_example_c})
27+
target_link_libraries (argparse_ex argparse)
28+
endif()
29+
1530
set (LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
1631

1732
install (TARGETS argparse

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,6 @@ To build and install argparse on \*Unix systems, in your shell type
9191
mkdir build && cd build\
9292
cmake .. && make && sudo make install
9393
```
94+
95+
To build examples to `cmake` command add `-DARGPARSE_EXAMPLES=1`; to include error messages via `arg_geterror ()` to `cmake` command add `-DARGPARSE_ERRORS=1`
96+
Note, that if the library is compiled without error messages, a call to `arg_geterror ()` will always return NULL.

argparse.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,20 @@
2626
# define ARG_INLINE
2727
#endif
2828

29+
#ifdef ARGPARSE_ERRORS
30+
# define _inc_aerr
31+
/* a map with descriptions of all error codes */
32+
const char * arg_err_map [] = {
33+
[ARG_SUCCESS] = 0x0,
34+
35+
[ARG_HALT] = "parsing was halted",
36+
[ARG_INVAL] = "invalid argument",
37+
[ARG_UNEXP] = "unexpected characters are met",
38+
[ARG_NMATCH] = "not an argument",
39+
[ARG_NVALUE] = "argument does not have a value"
40+
};
41+
#endif
42+
2943
/* A simple implementation of some important "string.h" functions */
3044
#ifdef ARG_STANDALONE
3145
# define ARG_ASSERT(x)
@@ -292,3 +306,11 @@ char * arg_parse (int * argc, char *** argv, arg_list list, char ** nk, size_t *
292306

293307
return NULL;
294308
}
309+
310+
const char * arg_geterror (arg_return code) {
311+
#ifdef _inc_aerr
312+
return arg_err_map [code];
313+
#else
314+
return NULL;
315+
#endif
316+
}

argparse.h

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
1717

1818
/* Parsing:
19-
* check whether or not the argument belongs in line
20-
* check if its long or short type
19+
* check whether or not the argument is valid
20+
* if it is a key, determine is it long or short type
2121
* parse accordingly:
22-
* short, meaning that the data can be inserted after a whitespace
23-
* long, meaning that the data can be inserted after a space char
22+
* short, meaning that the data can be inserted after a whitespace or immediately after the key
23+
* long, meaning that the data can be inserted after a space char
2424
*
25-
* keys can be merged together, if they are flags (i.e: tar -xzvf ...) or,
25+
* keys can be merged together if they are flags (i.e: tar -xzvf ...) or,
2626
* if ARG_PARSE_MERGED is passed to the arg_parse function, merged key-value
2727
* arguments can be used (i.e objdump -Mintel ...) */
2828

@@ -32,19 +32,33 @@
3232

3333
#include <stddef.h>
3434

35-
#define ARG_SUCCESS 0
35+
/* For windows compatibility */
36+
#if defined(_WIN32) || defined(__WIN32__)
37+
# if defined(argparse_EXPORTS) /* should be added by cmake */
38+
# define ARGPARSE_API __declspec(dllexport)
39+
# else
40+
# define ARGPARSE_API __declspec(dllimport)
41+
# endif
42+
#elif defined(linux) || defined(__linux)
43+
# define ARGPARSE_API
44+
#endif
3645

37-
#define ARG_ZERO -1
38-
#define ARG_INVAL -2
39-
#define ARG_NFOUND -3
40-
#define ARG_HALT -4
41-
#define ARG_UNEXP -5
42-
#define ARG_NMATCH -6
43-
#define ARG_NVALUE -7
46+
#ifdef __cplusplus
47+
extern "C" {
48+
#endif
4449

4550
/* Type for the return codes */
46-
typedef signed char arg_return;
51+
typedef enum {
52+
ARG_SUCCESS = 0, /* everything is ok */
4753

54+
ARG_INVAL, /* invalid arguments given */
55+
ARG_HALT, /* halted by the parser (flag) */
56+
ARG_UNEXP, /* unexpected characters are met (garbage input) */
57+
ARG_NMATCH,/* no match found */
58+
ARG_NVALUE /* no value passed to the argument*/
59+
} arg_return;
60+
61+
/* Prototype for the arg_handler */
4862
typedef arg_return p_arg_handler (char * data_ptr, size_t blksize, void * retval);
4963

5064
/* The handler is the parser for the value of the argument
@@ -60,19 +74,19 @@ p_arg_handler arg_string_handler;
6074
p_arg_handler arg_strcpy_handler;
6175

6276
/* Defaults */
63-
#define ARG_FLAG_DEFAULT 0x0
77+
#define ARG_FLAG_DEFAULT 0
6478
/* This flag tells the parser to set the flag argument value to 0 instead of 1 */
65-
#define ARG_FLAG_UNSET 0x01
79+
#define ARG_FLAG_UNSET (1 << 1)
6680
/* This flag tells the parser that the value for this argument is optional */
67-
#define ARG_FLAG_OPTIONAL 0x04
81+
#define ARG_FLAG_OPTIONAL (1 << 2)
6882
/* This flag tells the parser to stop when the argument is met and parsed */
69-
#define ARG_FLAG_HALT 0x08
83+
#define ARG_FLAG_HALT (1 << 3)
7084

7185
/* Global parser flags */
7286
/* Defaults */
73-
#define ARG_PARSE_DEFAULT 0x0
87+
#define ARG_PARSE_DEFAULT 0
7488
/* Allow merged arguments (i.e: objdump -Mintel ...) */
75-
#define ARG_PARSE_MERGED 0x01
89+
#define ARG_PARSE_MERGED 1
7690

7791
/* Flags define the behaviour of the arguments parser
7892
* As example, ARG_FLAG_HALT will cause parser to be stopped when
@@ -126,6 +140,24 @@ typedef struct arg_argument arg_list[];
126140
* continue parsing.
127141
* 2 this function changes the addresses of the pointers, to save them
128142
* as they were, consider writing them into another set of variables. */
129-
char * arg_parse (int * argc, char *** argv, arg_list list, char ** not_keys, size_t * not_keys_size, arg_flags flags, arg_return * return_code);
143+
ARGPARSE_API char * arg_parse (int * argc, char *** argv, arg_list list, char ** not_keys, size_t * not_keys_size, arg_flags flags, arg_return * return_code);
144+
145+
/* const char * arg_geterror:
146+
* @param code:
147+
* the code of the error
148+
* RETURN const char * err:
149+
* returns the string with a description of the error code
150+
* NOTES:
151+
* 1 this function does not do bound checking, if an arbitrary code
152+
* is passed, an undefined behavior will occur.
153+
* 2 if argparse was compiled with ARGPARSE_ERRORS turned off, the
154+
* function will always return NULL. */
155+
ARGPARSE_API const char * arg_geterror (arg_return code);
156+
157+
#ifdef __cplusplus
158+
}
159+
#endif
160+
161+
#undef ARGPARSE_API
130162

131163
#endif

example.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ static char op = undef;
3636
*
3737
* handlers modify the value of the argument
3838
* to write it in retval the right way */
39-
arg_return custom_enum_handler (void * data, size_t size, void * retval) {
39+
arg_return custom_enum_handler (char * data, size_t size, void * retval) {
4040
if (STREQ (data, "+")) {
4141
op = plus;
4242
}
@@ -114,7 +114,7 @@ int main (int argc, char ** argv) {
114114
return 0;
115115
}
116116
/* if an error occured */
117-
printf ("Could not parse argument: %s\n", err_arg);
117+
printf ("Could not parse argument: %s [%s]\n", err_arg, arg_geterror (code));
118118
return 1;
119119
}
120120

0 commit comments

Comments
 (0)