1+ /* argparse - fast argument parsing tool
2+ * Copyright (C) 2021 Sergey Lafin
3+ *
4+ * This program is free software; you can redistribute it and/or
5+ * modify it under the terms of the GNU General Public License
6+ * as published by the Free Software Foundation; either version 2
7+ * of the License, or (at your option) any later version.
8+ *
9+ * This program is distributed in the hope that it will be useful,
10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ * GNU General Public License for more details.
13+ *
14+ * You should have received a copy of the GNU General Public License
15+ * along with this program; if not, write to the Free Software
16+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17+
118#include "argparse.h"
219
320#define ARG_LONG 0
926# define ARG_STRLEN (str ) arg_strlen(str)
1027# define ARG_STRCPY (dest , src ) arg_strcpy(dest, src)
1128# define ARG_MEMCPY (dest , src , n ) arg_memcpy(dest, src, n)
29+ # define ARG_STRCMP (a , b ) arg_strcmp(a, b)
1230
1331static size_t arg_strlen (char * str ) {
1432 size_t len = 0 ;
@@ -52,9 +70,10 @@ static int arg_strcmp (char * f, char * s) {
5270# define ARG_STRLEN (str ) strlen(str)
5371# define ARG_STRCPY (dest , src ) strcpy(dest, src)
5472# define ARG_MEMCPY (dest , src , n ) memcpy(dest, src, n)
73+ # define ARG_STRCMP (a , b ) strcmp(a, b)
5574#endif
5675
57- #define ARG_STREQ (a , b ) (strcmp (a, b) == 0)
76+ #define ARG_STREQ (a , b ) (ARG_STRCMP (a, b) == 0)
5877
5978#if __STDC_VERSION__ >= 199903L
6079# define ARG_INLINE inline
@@ -76,9 +95,9 @@ int arg_strcpy_handler (void * data_ptr, size_t blksize, void * retval) {
7695 return 0 ;
7796}
7897struct arg_state {
79- size_t len ;
98+ size_t len ;
8099 int * argc ;
81- int flags ; /* NOT IMPLEMENTED YET */
100+ int flags ; /* NOT IMPLEMENTED YET */
82101
83102 char * * argv ;
84103 struct arg_argument * list ;
@@ -105,18 +124,28 @@ static ARG_INLINE void arg_parse_value (struct arg_state * state, void ** data,
105124}
106125
107126static ARG_INLINE arg_return arg_call_handler (struct arg_state * state ) {
127+ if (state -> ptr -> flags & ARG_FLAG_OPTIONAL ) {
128+ if (
129+ (state -> type == ARG_SHORT && * (* state -> argv + 1 ) != 0x0 ) ||
130+ * state -> argc == 1 ||
131+ * * (state -> argv + 1 ) == '-'
132+ ) {
133+ ++ (* state -> argv );
134+ return ARG_SUCCESS ;
135+ }
136+ }
108137 /* An argument with a mandatory value */
109138 if (state -> ptr -> handler ) {
110139 void * data ;
111140 size_t size ;
112141
113142 arg_return code ;
114143
115- if (* state -> argc > 1 ) {
116- ++ state -> argv ;
117- -- (* state -> argc );
118- } else
144+ if (* state -> argc <= 1 || (state -> type == ARG_SHORT && * (* state -> argv + 1 ) != 0x0 )) {
119145 return ARG_NVALUE ;
146+ }
147+ ++ state -> argv ;
148+ -- (* state -> argc );
120149 arg_parse_value (state , & data , & size );
121150
122151 if ((code = state -> ptr -> handler (data , size , state -> ptr -> retval )) != ARG_SUCCESS ) {
0 commit comments