Skip to content

Commit caccac5

Browse files
committed
Added global parser flags and merged key-value arguments
ARG_PARSE_MERGED can now be passed to `arg_parse` function flags to enable merged key-value arguments (i.e objdump -Mintel ...)*
1 parent 279de4b commit caccac5

File tree

3 files changed

+66
-28
lines changed

3 files changed

+66
-28
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ int main (int argc, char ** argv) {
5353
size_t buf_size;
5454

5555
/* parse the program's arguments */
56-
if ((ptr = arg_parse (&argc, &argv, list, &nk_buffer, &buf_size, &code)) != NULL) {
56+
if ((ptr = arg_parse (&argc, &argv, list, &nk_buffer, &buf_size, ARG_PARSE_DEFAULT, &code)) != NULL) {
5757
printf ("An error occured here: %s", ptr);
5858
return code;
5959
}

argparse.c

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,29 +81,30 @@ static int arg_strcmp (char * f, char * s) {
8181
# define ARG_INLINE
8282
#endif
8383

84-
int arg_string_handler (void * data_ptr, size_t blksize, void * retval) {
84+
arg_return arg_string_handler (void * data_ptr, size_t blksize, void * retval) {
8585
void ** _retval = (void **)retval;
8686
*_retval = data_ptr;
8787
return 0;
8888
}
89-
int arg_strcpy_handler (void * data_ptr, size_t blksize, void * retval) {
89+
arg_return arg_strcpy_handler (void * data_ptr, size_t blksize, void * retval) {
9090
if (blksize == 0) {
9191
retval = NULL;
9292
return 0;
9393
}
9494
ARG_STRCPY((char *)retval, (char *)data_ptr);
9595
return 0;
9696
}
97+
9798
struct arg_state {
9899
size_t len;
99100
int * argc;
100-
int flags; /* NOT IMPLEMENTED YET */
101+
int flags;
101102

102103
char ** argv;
103104
struct arg_argument * list;
104105
struct arg_argument * ptr;
105106

106-
char type; /* NOT IMPLEMENTED YET */
107+
char type;
107108
};
108109

109110
static ARG_INLINE size_t arg_list_len (arg_list list) {
@@ -141,11 +142,32 @@ static ARG_INLINE arg_return arg_call_handler (struct arg_state * state) {
141142

142143
arg_return code;
143144

144-
if (*state->argc <= 1 || (state->type == ARG_SHORT && *(*state->argv + 1) != 0x0)) {
145-
return ARG_NVALUE;
146-
}
147-
++state->argv;
148-
--(*state->argc);
145+
switch (state->type) {
146+
case ARG_SHORT:
147+
if (state->flags & ARG_PARSE_MERGED) {
148+
if (*(*state->argv + 1) == 0x0) {
149+
if (*state->argc == 1)
150+
return ARG_NVALUE;
151+
++state->argv;
152+
--(*state->argc);
153+
break;
154+
}
155+
++(*state->argv);
156+
break;
157+
}
158+
if (*(*state->argv + 1) != 0x0 || *state->argc == 1)
159+
return ARG_NVALUE;
160+
++state->argv;
161+
--(*state->argc);
162+
break;
163+
case ARG_LONG:
164+
if (*state->argc == 1) {
165+
return ARG_NVALUE;
166+
}
167+
++state->argv;
168+
--(*state->argc);
169+
break;
170+
}
149171
arg_parse_value (state, &data, &size);
150172

151173
if ((code = state->ptr->handler (data, size, state->ptr->retval)) != ARG_SUCCESS) {
@@ -154,7 +176,8 @@ static ARG_INLINE arg_return arg_call_handler (struct arg_state * state) {
154176
return ARG_SUCCESS;
155177
}
156178
/* A flag */
157-
*(char *)state->ptr->retval = state->ptr->flags & ARG_FLAG_UNSET ? 0 : 1;
179+
if (state->ptr->retval != NULL)
180+
*(char *)state->ptr->retval = state->ptr->flags & ARG_FLAG_UNSET ? 0 : 1;
158181
++(*state->argv);
159182

160183
if (state->ptr->flags & ARG_FLAG_HALT)
@@ -204,7 +227,7 @@ static ARG_INLINE arg_return arg_parse_long (struct arg_state * state) {
204227
return ARG_NMATCH;
205228
}
206229

207-
char * arg_parse (int * argc, char *** argv, arg_list list, char ** nk, size_t * nk_size, arg_return * code) {
230+
char * arg_parse (int * argc, char *** argv, arg_list list, char ** nk, size_t * nk_size, arg_flags flags, arg_return * code) {
208231
ARG_ASSERT (*argc > 1);
209232
ARG_ASSERT (argv != NULL);
210233
ARG_ASSERT (list != NULL);
@@ -218,7 +241,7 @@ char * arg_parse (int * argc, char *** argv, arg_list list, char ** nk, size_t *
218241
struct arg_state state;
219242
state.argc = argc;
220243
state.argv = *argv;
221-
state.flags = 0;
244+
state.flags = flags;
222245
state.list = list;
223246
state.ptr = NULL;
224247
state.len = len;

argparse.h

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
* short, meaning that the data can be inserted after a whitespace
2323
* long, meaning that the data can be inserted after a space char
2424
*
25-
* flags can be merged together, if they are flags (i.e: tar -xzvf ...) */
25+
* keys can be merged together, if they are flags (i.e: tar -xzvf ...) or,
26+
* if ARG_PARSE_MERGED is passed to the arg_parse function, merged key-value
27+
* arguments can be used (i.e objdump -Mintel ...) */
2628

2729

2830
#ifndef __SL_ARGPARSE_H__
@@ -42,7 +44,10 @@
4244
#define ARG_NMATCH -6
4345
#define ARG_NVALUE -7
4446

45-
typedef int p_arg_handler (void * data_ptr, size_t blksize, void * retval);
47+
/* Type for the return codes */
48+
typedef signed char arg_return;
49+
50+
typedef arg_return p_arg_handler (void * data_ptr, size_t blksize, void * retval);
4651

4752
/* The handler is the parser for the value of the argument
4853
* if NULL is passed instead of a valid handler function,
@@ -56,22 +61,24 @@ p_arg_handler arg_string_handler;
5661
* to the static buffer */
5762
p_arg_handler arg_strcpy_handler;
5863

59-
6064
/* This flag tells the parser to set the flag argument value to 0 instead of 1 */
6165
#define ARG_FLAG_UNSET 0x01
6266
/* This flag tells the parser that the value for this argument is optional */
6367
#define ARG_FLAG_OPTIONAL 0x04
6468
/* This flag tells the parser to stop when the argument is met and parsed */
6569
#define ARG_FLAG_HALT 0x08
6670

71+
/* Global parser flags */
72+
/* Defaults */
73+
#define ARG_PARSE_DEFAULT 0x0
74+
/* Allow merged arguments (i.e: objdump -Mintel ...) */
75+
#define ARG_PARSE_MERGED 0x01
76+
6777
/* Flags define the behaviour of the arguments parser
6878
* As example, ARG_FLAG_HALT will cause parser to be stopped when
6979
* the specified argument is met. */
7080
typedef unsigned char arg_flags;
7181

72-
/* Type for the return codes */
73-
typedef signed char arg_return;
74-
7582
/* struct arg_argument
7683
* Contains a basic description of the argument list
7784
* char short_arg: a short variant of the argument's key (i.e: -r)
@@ -92,25 +99,33 @@ struct arg_argument {
9299
typedef struct arg_argument arg_list[];
93100

94101
/* char * arg_parse:
95-
* IN int * argc: argument count
96-
* IN char *** argv: arguments array
97-
* IN arg_list list: list, defining the accepted arguments
98-
* IN char ** not_keys: a buffer for random values
99-
* IN size_t * not_keys_size: size of the not_keys buffer
100-
* OUT arg_return * return_code: a return code of the status
101-
* ARG_SUCCESS [0] if the parsing is done without failures
102+
* @param argc
103+
* argument count
104+
* @param argv
105+
* arguments array
106+
* @param list
107+
* list, defining the accepted arguments
108+
* @param not_keys
109+
* a buffer for random values
110+
* @param not_keys_size
111+
* size of the not_keys buffer
112+
* @param flags
113+
* flags, defining the behaviour of the parser
114+
* @param return_code
115+
* return code of the parser
116+
* NOTE: ARG_SUCCESS [0] is returned on success
102117
*
103118
* RETURN char * arg:
104119
* - NULL on a complete success.
105120
* - A pointer to the argv list's element which failed the parsing on
106121
* a failure.
107122
*
108123
* NOTES:
109-
* 1 this function is reentrant, meaning, that if an error occured, you
124+
* 1 this function is re-entrant, meaning, that if an error occured, you
110125
* can call this function again with the same set of variables and
111126
* continue parsing.
112127
* 2 this function changes the addresses of the pointers, to save them
113128
* as they were, consider writing them into another set of variables. */
114-
char * arg_parse (int * argc, char *** argv, arg_list list, char ** not_keys, size_t * not_keys_size, arg_return * return_code);
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);
115130

116131
#endif

0 commit comments

Comments
 (0)