Skip to content

Commit 39a7cca

Browse files
committed
Code refactoring
Refactored code: `arg_string_handler` now changes the pointer of retval to the corresponding argv element, instead of copying it. To replicate the previous functionality (copy the value to the static buffer) `arg_strcpy_handler` can be used. Renewed Makefile. Fixed the bug where long arguments' values were ignored if its key was preceeded by short flags.
1 parent 94b83f0 commit 39a7cca

File tree

3 files changed

+70
-37
lines changed

3 files changed

+70
-37
lines changed

README.md

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,45 +13,65 @@ static char is_verbose = 0;
1313
static char jump = 0;
1414
static char jump_last = 0;
1515
static char should_create = 0;
16-
static char project_name [5000];
16+
17+
static char * project_name;
18+
19+
static char * move_to = NULL;
20+
static char * not_moving = "not moving anywhere";
1721

1822
int main (int argc, char ** argv) {
23+
/* argparse does not check if a program had recieved any arguments */
1924
if (argc == 1) {
2025
return 0;
2126
}
22-
char buffer[5000] = { 0x0 };
27+
28+
/* An array, describing the options, that this program accepts */
2329
arg_list list = {
24-
{ 'v', "verbose", NULL, &is_verbose },
25-
{ 'c', "create", NULL, &should_create },
26-
{ 'j', "jump", NULL, &jump },
27-
{ 'J', "jump-last", NULL, &jump_last },
28-
{ 'm', "move", arg_string_handler, buffer },
30+
/* s , long opt , handler , value buffer */
31+
{ 'v', "verbose" , NULL , &is_verbose },
32+
{ 'c', "create" , NULL , &should_create },
33+
{ 'j', "jump" , NULL , &jump },
34+
{ 'J', "jump-last", NULL , &jump_last },
35+
{ 'm', "move" , arg_string_handler, &move_to },
2936
{ 0 }
37+
/* NOTE */
38+
/* 's' stands for "short option" here
39+
* "handler" is a function that accepts a parsed value
40+
* of the argument, modifying and writing it into the
41+
* value buffer */
3042
};
3143

44+
/* return code of the parser */
3245
arg_return code;
46+
/* in case of an error, this is going to point to the program's argument
47+
* that was the cause of it */
3348
char ** ptr;
3449

35-
/* buffer for elements, that are not keys */
36-
char * nk_buffer[3];
37-
/* size of the written buffer */
50+
/* buffer for the elements, that are not keys */
51+
char * nk_buffer = NULL;
52+
/* size of the nk_buffer */
3853
size_t buf_size;
3954

40-
if ((ptr = arg_parse (argc, argv, list, nk_buffer, &buf_size, &code)) != NULL) {
55+
/* parse the program's arguments */
56+
if ((ptr = arg_parse (argc, argv, list, &nk_buffer, &buf_size, &code)) != NULL) {
4157
printf ("An error occured here: %s", *ptr);
4258
return code;
4359
}
4460

45-
if (nk_buffer[0]) {
46-
ARG_STRCPY(project_name, nk_buffer[0]);
47-
}
61+
/* if the user entered an argument, that does not belong to any key */
62+
if (nk_buffer)
63+
project_name = nk_buffer;
64+
65+
if (move_to == NULL)
66+
move_to = not_moving;
4867

49-
printf ("Name: %s\nCreate? %i\nVerbose? %i\nJump? %i\nJump-last? %i\nMove to: %s\n", (const char *)project_name, should_create, is_verbose, jump, jump_last, buffer);
68+
printf ("Name: %s\nCreate? %i\nVerbose? %i\nJump? %i\nJump-last? %i\nMove to: %s\n", (const char *)project_name, should_create, is_verbose, jump, jump_last, move_to);
5069

5170
return 0;
5271
}
72+
5373
```
5474
5575
## Installation
5676
57-
To install argparse on a unix system just type `make && doas make install`
77+
To install argparse on a unix system just type `make && sudo make install`

argparse.c

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,18 @@
2323
*
2424
* RETURN: return code */
2525
static ARG_INLINE arg_return arg_parse_value (int * argc, char *** argv, void ** data, size_t * size) {
26-
if (!(***argv)) {
27-
if (*argc == 1)
28-
return ARG_NVALUE;
29-
else {
30-
--(*argc);
31-
++(*argv);
32-
}
26+
if (*argc <= 1)
27+
return ARG_NVALUE;
28+
else {
29+
--(*argc);
30+
++(*argv);
3331
}
3432
*size = ARG_STRLEN (**argv);
3533
if (*size == 0) {
3634
*data = NULL;
3735
return ARG_NVALUE;
3836
}
3937
*data = **argv;
40-
**argv += *size;
4138
return ARG_SUCCESS;
4239
}
4340

@@ -48,18 +45,18 @@ static ARG_INLINE arg_return arg_parse_call_handler (int * argc, char *** argv,
4845
/* TODO: Add a freaking check for non-value arguments */
4946
if (ptr->handler) {
5047
arg_return ret_code;
51-
++(**argv);
5248
ret_code = arg_parse_value(argc, argv, &data, &size);
5349
if (ret_code == ARG_NVALUE) {
5450
return ret_code;
5551
}
5652
if ((ret_code = ptr->handler(data, size, ptr->retval)) != 0)
5753
return ret_code;
5854
} else {
59-
++(**argv);
6055
*(char *)ptr->retval = 1;
61-
if (*argc > 1 && (***argv + 1) == 0x0)
56+
++(**argv);
57+
if ((**argv + 1) == 0x0) {
6258
++(*argv);
59+
}
6360
}
6461
return ARG_SUCCESS;
6562
}
@@ -74,8 +71,11 @@ static ARG_INLINE arg_return arg_parse_long (int * argc, char *** argv, arg_list
7471
size_t i;
7572
for (i = 0; i < len; ++i) {
7673
if (ARG_STREQ(list[i].long_arg, &(**argv))) {
77-
78-
return arg_parse_call_handler (argc, argv, &list[i]);
74+
arg_return code;
75+
if ((code = arg_parse_call_handler (argc, argv, &list[i])) != ARG_SUCCESS)
76+
return code;
77+
++(*argv);
78+
return ARG_SUCCESS;
7979
}
8080
}
8181
return ARG_NMATCH;
@@ -100,12 +100,17 @@ static ARG_INLINE arg_return arg_parse_short (int * argc, char *** argv, arg_lis
100100
if (list[i].short_arg == ***argv) {
101101
if ((code = arg_parse_call_handler (argc, argv, &list[i])) != ARG_SUCCESS)
102102
return code;
103+
if (list[i].handler) {
104+
++(*argv);
105+
return ARG_SUCCESS;
106+
}
103107
its_a_match = 1;
104108
break;
105109
}
106110
}
107111
if (!its_a_match) return ARG_NMATCH;
108112
}
113+
++(*argv);
109114
return ARG_SUCCESS;
110115
}
111116

@@ -143,42 +148,42 @@ char ** arg_parse (int argc, char ** argv, arg_list list, char ** not_keys, size
143148

144149
char accept_args = 1;
145150

146-
while (--argc) {
151+
while ((--argc) > 0) {
147152
if (**argv == '-' && accept_args) {
148-
if (*(*argv) == 0x0) {
153+
if ((**argv + 1) == 0x0) {
149154
*code = ARG_UNEXP;
150155
return argv;
151156
}
152157
if (*(++*argv) == '-') { /* If the "--" is passed we have to stop accepting the arguments */
153-
154158
if (**argv == '-' && !*(*argv + 1)) {
155159
accept_args = 0;
156160
++argv;
161+
--argc;
157162
continue;
158163
}
159164
++(*argv);
160165
if ((ret_code = arg_parse_long (&argc, &argv, list, list_len)) != 0) {
161166
*code = ret_code;
162167
return argv;
163168
}
164-
++argv;
165169
continue;
166170
}
167171

168172
if ((ret_code = arg_parse_short (&argc, &argv, list, list_len)) != 0) {
169173
*code = ret_code;
170174
return argv;
171-
} else {
172-
++argv;
173-
continue;
174175
}
176+
continue;
177+
175178
}
176179
/* Not a key */
177180
if (not_keys) {
178181
*not_keys = *argv;
179182
++(*not_keys_len);
180183
++not_keys;
181-
++argv;
184+
if (argc > 0) {
185+
++argv;
186+
}
182187
continue;
183188
} else {
184189
*code = ARG_UNEXP;

argparse.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,16 @@ typedef p_arg_handler * arg_handler;
125125

126126
/* A handler for a generic string. */
127127
static p_arg_handler arg_string_handler;
128+
/* A handler for a generic string, copies the data
129+
* to the static buffer */
130+
static p_arg_handler arg_strcpy_handler;
128131

129132
static int arg_string_handler (void * data_ptr, size_t blksize, void * retval) {
133+
void ** _retval = (void **)retval;
134+
*_retval = data_ptr;
135+
return 0;
136+
}
137+
static int arg_strcpy_handler (void * data_ptr, size_t blksize, void * retval) {
130138
if (blksize == 0) {
131139
retval = NULL;
132140
return 0;

0 commit comments

Comments
 (0)