From 342741d175e431ae66ca5a2bb572157fc80cbc9b Mon Sep 17 00:00:00 2001 From: huangxin Date: Thu, 9 Feb 2023 14:31:12 +0800 Subject: [PATCH] =?UTF-8?q?OCT=201.=20=E6=9B=B4=E6=96=B0Argtables=E5=BA=93?= =?UTF-8?q?=E5=88=B0=E6=9C=80=E6=96=B0=E7=89=88=E6=9C=AC=202.=20=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E7=B3=BB=E7=BB=9F=E4=BE=9D=E8=B5=96=E5=BA=93=E5=AE=89?= =?UTF-8?q?=E8=A3=85=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- depend/system_libs.cmake | 2 +- srcs/libs/args/argtable3.c | 592 +++++++++++++++++++---------------- srcs/libs/args/argtable3.h | 7 +- srcs/libs/cmdline/cmd_menu.c | 4 +- 4 files changed, 328 insertions(+), 277 deletions(-) diff --git a/depend/system_libs.cmake b/depend/system_libs.cmake index 85b286f..648dd15 100644 --- a/depend/system_libs.cmake +++ b/depend/system_libs.cmake @@ -21,7 +21,7 @@ FUNCTION(LINUX_INSTALL_SYSTEM_PACKAGE) IF (${OS_DISTRIB_NAME} MATCHES "CentOS") MESSAGE(FATAL_ERROR "$sudo yum -y install libcurl-devel czmq-devel openssl-devel") ELSEIF (${OS_DISTRIB_NAME} MATCHES "Ubuntu") - MESSAGE(FATAL_ERROR "$sudo -S apt -y install libcurl4-openssl-dev libczmq-dev libssl-dev") + MESSAGE(FATAL_ERROR "$sudo apt -y install libcurl4-openssl-dev libczmq-dev libssl-dev") ENDIF () ELSE () MESSAGE(FATAL_ERROR "Run command to install system dependencies libraries [libcurl,libssl,libcrypto,libzmq] by yourself") diff --git a/srcs/libs/args/argtable3.c b/srcs/libs/args/argtable3.c index 0082568..5a9e7e9 100644 --- a/srcs/libs/args/argtable3.c +++ b/srcs/libs/args/argtable3.c @@ -164,8 +164,8 @@ arg_hashtable_t *arg_hashtable_create(unsigned int minsize, int (*eqfn)(const void *, const void *)); /** - * @brief This function will cause the table to expand if the insertion would take - * the ratio of entries to table size over the maximum load factor. + * @brief This function will cause the table to expand if the insertion would + * take the ratio of entries to table size over the maximum load factor. * * This function does not check for repeated insertions with a duplicate key. * The value returned when using a duplicate key is undefined -- when @@ -264,7 +264,8 @@ extern void *arg_hashtable_itr_key(arg_hashtable_itr_t *i); extern void *arg_hashtable_itr_value(arg_hashtable_itr_t *i); /** - * @brief Advance the iterator to the next element. Returns zero if advanced to end of table. + * @brief Advance the iterator to the next element. Returns zero if advanced to + * end of table. */ int arg_hashtable_itr_advance(arg_hashtable_itr_t *itr); @@ -274,7 +275,8 @@ int arg_hashtable_itr_advance(arg_hashtable_itr_t *itr); int arg_hashtable_itr_remove(arg_hashtable_itr_t *itr); /** - * @brief Search and overwrite the supplied iterator, to point to the entry matching the supplied key. + * @brief Search and overwrite the supplied iterator, to point to the entry + * matching the supplied key. * * @return Zero if not found. */ @@ -468,6 +470,7 @@ void arg_mgsort(void *data, int size, int esize, int i, int k, arg_comparefn *co merge(data, esize, i, j, k, comparefn); } } + /******************************************************************************* * arg_hashtable: Implements the hash table utilities * @@ -559,14 +562,14 @@ const float max_load_factor = (float)0.65; static unsigned int enhanced_hash(arg_hashtable_t *h, const void *k) { /* - * Aim to protect against poor hash functions by adding logic here. - * The logic is taken from Java 1.4 hash table source. - */ + * Aim to protect against poor hash functions by adding logic here. + * The logic is taken from Java 1.4 hash table source. + */ unsigned int i = h->hashfn(k); - i += ~(i << 9); - i ^= ((i >> 14) | (i << 18)); /* >>> */ - i += (i << 4); - i ^= ((i >> 10) | (i << 22)); /* >>> */ + i += ~(i << 9); + i ^= ((i >> 14) | (i << 18)); /* >>> */ + i += (i << 4); + i ^= ((i >> 10) | (i << 22)); /* >>> */ return i; } @@ -587,10 +590,10 @@ arg_hashtable_t *arg_hashtable_create(unsigned int minsize, } /* - * Enforce size as prime. The reason is to avoid clustering of values - * into a small number of buckets (yes, distribution). A more even - * distributed hash table will perform more consistently. - */ + * Enforce size as prime. The reason is to avoid clustering of values + * into a small number of buckets (yes, distribution). A more even + * distributed hash table will perform more consistently. + */ for (pindex = 0; pindex < prime_table_length; pindex++) { if (primes[pindex] > minsize) { size = primes[pindex]; @@ -627,9 +630,9 @@ static int arg_hashtable_expand(arg_hashtable_t *h) { newtable = (struct arg_hashtable_entry **)xmalloc(sizeof(struct arg_hashtable_entry *) * newsize); memset(newtable, 0, newsize * sizeof(struct arg_hashtable_entry *)); /* - * This algorithm is not 'stable': it reverses the list - * when it transfers entries between the tables - */ + * This algorithm is not 'stable': it reverses the list + * when it transfers entries between the tables + */ for (i = 0; i < h->tablelength; i++) { while (NULL != (e = h->table[i])) { h->table[i] = e->next; @@ -656,11 +659,11 @@ void arg_hashtable_insert(arg_hashtable_t *h, void *k, void *v) { struct arg_hashtable_entry *e; if ((h->entrycount + 1) > h->loadlimit) { /* - * Ignore the return value. If expand fails, we should - * still try cramming just this value into the existing table - * -- we may not have memory for a larger table, but one more - * element may be ok. Next time we insert, we'll try expanding again. - */ + * Ignore the return value. If expand fails, we should + * still try cramming just this value into the existing table + * -- we may not have memory for a larger table, but one more + * element may be ok. Next time we insert, we'll try expanding again. + */ arg_hashtable_expand(h); } e = (struct arg_hashtable_entry *)xmalloc(sizeof(struct arg_hashtable_entry)); @@ -693,9 +696,9 @@ void *arg_hashtable_search(arg_hashtable_t *h, const void *k) { void arg_hashtable_remove(arg_hashtable_t *h, const void *k) { /* - * TODO: consider compacting the table when the load factor drops enough, - * or provide a 'compact' method. - */ + * TODO: consider compacting the table when the load factor drops enough, + * or provide a 'compact' method. + */ struct arg_hashtable_entry *e; struct arg_hashtable_entry **pE; @@ -899,6 +902,7 @@ int arg_hashtable_change(arg_hashtable_t *h, void *k, void *v) { } return 0; } + /******************************************************************************* * arg_dstr: Implements the dynamic string utilities * @@ -1049,10 +1053,10 @@ void arg_dstr_set(arg_dstr_t ds, char *str, arg_dstr_freefn *free_proc) { } /* - * If the old result was dynamically-allocated, free it up. Do it here, - * rather than at the beginning, in case the new result value was part of - * the old result value. - */ + * If the old result was dynamically-allocated, free it up. Do it here, + * rather than at the beginning, in case the new result value was part of + * the old result value. + */ if ((old_free_proc != 0) && (old_result != ds->data)) { if (old_free_proc == ARG_DSTR_DYNAMIC) { @@ -1108,14 +1112,15 @@ void arg_dstr_catc(arg_dstr_t ds, char c) { * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ void arg_dstr_catf(arg_dstr_t ds, const char *fmt, ...) { va_list arglist; @@ -1128,8 +1133,8 @@ void arg_dstr_catf(arg_dstr_t ds, const char *fmt, ...) { } /* Since the length is not determinable beforehand, a search is - performed using the truncating "vsnprintf" call (to avoid buffer - overflows) on increasing potential sizes for the output result. */ + performed using the truncating "vsnprintf" call (to avoid buffer + overflows) on increasing potential sizes for the output result. */ if ((n = (int)(2 * strlen(fmt))) < START_VSNBUFF) { n = START_VSNBUFF; @@ -1167,16 +1172,16 @@ static void setup_append_buf(arg_dstr_t ds, int new_space) { int total_space; /* - * Make the append buffer larger, if that's necessary, then copy the - * data into the append buffer and make the append buffer the official - * data. - */ + * Make the append buffer larger, if that's necessary, then copy the + * data into the append buffer and make the append buffer the official + * data. + */ if (ds->data != ds->append_data) { /* - * If the buffer is too big, then free it up so we go back to a - * smaller buffer. This avoids tying up memory forever after a large - * operation. - */ + * If the buffer is too big, then free it up so we go back to a + * smaller buffer. This avoids tying up memory forever after a large + * operation. + */ if (ds->append_data_size > 500) { xfree(ds->append_data); ds->append_data = NULL; @@ -1185,10 +1190,10 @@ static void setup_append_buf(arg_dstr_t ds, int new_space) { ds->append_used = (int)strlen(ds->data); } else if (ds->data[ds->append_used] != 0) { /* - * Most likely someone has modified a result created by - * arg_dstr_cat et al. so that it has a different size. Just - * recompute the size. - */ + * Most likely someone has modified a result created by + * arg_dstr_cat et al. so that it has a different size. Just + * recompute the size. + */ ds->append_used = (int)strlen(ds->data); } @@ -1294,14 +1299,14 @@ struct option { /* name of long option */ const char *name; /* - * one of no_argument, required_argument, and optional_argument: - * whether option takes an argument - */ - int has_arg; + * one of no_argument, required_argument, and optional_argument: + * whether option takes an argument + */ + int has_arg; /* if not NULL, set *flag to val when option found */ - int *flag; + int *flag; /* if flag not NULL, value to set *flag to; else return value */ - int val; + int val; }; #ifdef __cplusplus @@ -1329,7 +1334,8 @@ extern int optreset; /* getopt(3) external variable */ #endif /* !_GETOPT_H_ */ #endif /* ARG_REPLACE_GETOPT == 1 */ -/* $OpenBSD: getopt_long.c,v 1.26 2013/06/08 22:47:56 millert Exp $ */ +/* $OpenBSD: getopt_long.c,v 1.26 2013/06/08 22:47:56 millert Exp $ + */ /* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ /* @@ -1400,18 +1406,18 @@ int optopt = '?'; /* character checked for validity */ int optreset; /* reset getopt */ char *optarg; /* argument associated with option */ -#define PRINT_ERROR ((opterr) && (*options != ':')) +#define PRINT_ERROR ((opterr) && (*options != ':')) #define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ #define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ #define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ /* return values */ -#define BADCH (int)'?' -#define BADARG ((*options == ':') ? (int)':' : (int)'?') -#define INORDER (int)1 +#define BADCH (int)'?' +#define BADARG ((*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 -#define EMSG "" +#define EMSG "" #ifdef GNU_COMPATIBLE #define NO_PREFIX (-1) @@ -1472,9 +1478,9 @@ static void warnx(const char *fmt, ...) { va_start(ap, fmt); /* - * Make sure opterrmsg is always zero-terminated despite the _vsnprintf() - * implementation specifics and manually suppress the warning. - */ + * Make sure opterrmsg is always zero-terminated despite the _vsnprintf() + * implementation specifics and manually suppress the warning. + */ memset(opterrmsg, 0, sizeof(opterrmsg)); if (fmt != NULL) #if (defined(__STDC_LIB_EXT1__) && defined(__STDC_WANT_LIB_EXT1__)) || \ @@ -1521,8 +1527,8 @@ static void permute_args(int panonopt_start, int panonopt_end, int opt_end, char char *swap; /* - * compute lengths of blocks and number and size of cycles - */ + * compute lengths of blocks and number and size of cycles + */ nnonopts = panonopt_end - panonopt_start; nopts = opt_end - panonopt_end; ncycle = gcd(nnonopts, nopts); @@ -1537,9 +1543,9 @@ static void permute_args(int panonopt_start, int panonopt_end, int opt_end, char } else { pos += nopts; } - swap = nargv[pos]; + swap = nargv[pos]; /* LINTED const cast */ - ((char **)nargv)[pos] = nargv[cstart]; + ((char **)nargv)[pos] = nargv[cstart]; /* LINTED const cast */ ((char **)nargv)[cstart] = swap; } @@ -1608,9 +1614,9 @@ static int parse_long_options(char *const *nargv, break; } /* - * If this is a known short option, don't allow - * a partial match of a single character. - */ + * If this is a known short option, don't allow + * a partial match of a single character. + */ if (short_too && current_argv_len == 1) { continue; } @@ -1646,8 +1652,8 @@ static int parse_long_options(char *const *nargv, current_argv); } /* - * XXX: GNU sets optopt to val regardless of flag - */ + * XXX: GNU sets optopt to val regardless of flag + */ if (long_options[match].flag == NULL) { optopt = long_options[match].val; } else { @@ -1664,16 +1670,16 @@ static int parse_long_options(char *const *nargv, optarg = has_equal; } else if (long_options[match].has_arg == required_argument) { /* - * optional argument doesn't use next nargv - */ + * optional argument doesn't use next nargv + */ optarg = nargv[optind++]; } } if ((long_options[match].has_arg == required_argument) && (optarg == NULL)) { /* - * Missing argument; leading ':' indicates no error - * should be generated. - */ + * Missing argument; leading ':' indicates no error + * should be generated. + */ if (PRINT_ERROR) { warnx(recargstring, #ifdef GNU_COMPATIBLE @@ -1682,8 +1688,8 @@ static int parse_long_options(char *const *nargv, current_argv); } /* - * XXX: GNU sets optopt to val regardless of flag - */ + * XXX: GNU sets optopt to val regardless of flag + */ if (long_options[match].flag == NULL) { optopt = long_options[match].val; } else { @@ -1737,17 +1743,17 @@ static int getopt_internal(int nargc, } /* - * XXX Some GNU programs (like cvs) set optind to 0 instead of - * XXX using optreset. Work around this braindamage. - */ + * XXX Some GNU programs (like cvs) set optind to 0 instead of + * XXX using optreset. Work around this braindamage. + */ if (optind == 0) { optind = optreset = 1; } /* - * Disable GNU extensions if POSIXLY_CORRECT is set or options - * string begins with a '+'. - */ + * Disable GNU extensions if POSIXLY_CORRECT is set or options + * string begins with a '+'. + */ if (posixly_correct == -1 || optreset) { #if defined(_WIN32) && \ ((defined(__STDC_LIB_EXT1__) && defined(__STDC_WANT_LIB_EXT1__)) || \ @@ -1784,9 +1790,9 @@ start: optind -= nonopt_end - nonopt_start; } else if (nonopt_start != -1) { /* - * If we skipped non-options, set optind - * to the first of them. - */ + * If we skipped non-options, set optind + * to the first of them. + */ optind = nonopt_start; } nonopt_start = nonopt_end = -1; @@ -1801,17 +1807,17 @@ start: place = EMSG; /* found non-option */ if (flags & FLAG_ALLARGS) { /* - * GNU extension: - * return non-option as argument to option 1 - */ + * GNU extension: + * return non-option as argument to option 1 + */ optarg = nargv[optind++]; return (INORDER); } if (!(flags & FLAG_PERMUTE)) { /* - * If no permutation wanted, stop parsing - * at first non-option. - */ + * If no permutation wanted, stop parsing + * at first non-option. + */ return (-1); } /* do permutation */ @@ -1831,15 +1837,15 @@ start: } /* - * If we have "-" do nothing, if "--" we are done. - */ + * If we have "-" do nothing, if "--" we are done. + */ if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { optind++; place = EMSG; /* - * We found an option (--), so if we skipped - * non-options, we have to permute. - */ + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ if (nonopt_end != -1) { permute_args(nonopt_start, nonopt_end, optind, nargv); optind -= nonopt_end - nonopt_start; @@ -1850,11 +1856,11 @@ start: } /* - * Check long options if: - * 1) we were passed some - * 2) the arg is not just "-" - * 3) either the arg starts with -- we are getopt_long_only() - */ + * Check long options if: + * 1) we were passed some + * 2) the arg is not just "-" + * 3) either the arg starts with -- we are getopt_long_only() + */ if (long_options != NULL && place != nargv[optind] && (*place == '-' || (flags & FLAG_LONGONLY))) { short_too = 0; #ifdef GNU_COMPATIBLE @@ -1882,10 +1888,10 @@ start: if ((optchar = (int)*place++) == (int)':' || (optchar == (int)'-' && *place != '\0') || (oli = strchr(options, optchar)) == NULL) { /* - * If the user specified "-" and '-' isn't listed in - * options, return -1 (non-option) as per POSIX. - * Otherwise, it is an unknown option character (or ':'). - */ + * If the user specified "-" and '-' isn't listed in + * options, return -1 (non-option) as per POSIX. + * Otherwise, it is an unknown option character (or ':'). + */ if (optchar == (int)'-' && *place == '\0') { return (-1); } @@ -1961,13 +1967,13 @@ start: int getopt(int nargc, char *const *nargv, const char *options) { /* - * We don't pass FLAG_PERMUTE to getopt_internal() since - * the BSD getopt(3) (unlike GNU) has never done this. - * - * Furthermore, since many privileged programs call getopt() - * before dropping privileges it makes sense to keep things - * as simple (and bug-free) as possible. - */ + * We don't pass FLAG_PERMUTE to getopt_internal() since + * the BSD getopt(3) (unlike GNU) has never done this. + * + * Furthermore, since many privileged programs call getopt() + * before dropping privileges it makes sense to keep things + * as simple (and bug-free) as possible. + */ return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); } @@ -2044,7 +2050,8 @@ static int arg_date_scanfn(struct arg_date *parent, const char *argval) { if (parent->count == parent->hdr.maxcount) { errorcode = ARG_ERR_MAXCOUNT; } else if (!argval) { - /* no argument value was given, leave parent->tmval[] unaltered but still count it */ + /* no argument value was given, leave parent->tmval[] unaltered but still + * count it */ parent->count++; } else { const char *pend; @@ -2309,9 +2316,9 @@ char *arg_strptime(const char *buf, const char *fmt, struct tm *tm) { break; /* - * "Alternative" modifiers. Just set the appropriate flag - * and start over again. - */ + * "Alternative" modifiers. Just set the appropriate flag + * and start over again. + */ case 'E': /* "%E?" alternative conversion modifier. */ LEGAL_ALT(0); alt_format |= ALT_E; @@ -2323,8 +2330,8 @@ char *arg_strptime(const char *buf, const char *fmt, struct tm *tm) { goto again; /* - * "Complex" conversion rules, implemented through recursion. - */ + * "Complex" conversion rules, implemented through recursion. + */ case 'c': /* Date and time, using the locale's format. */ LEGAL_ALT(ALT_E); bp = arg_strptime(bp, "%x %X", tm); @@ -2382,8 +2389,8 @@ char *arg_strptime(const char *buf, const char *fmt, struct tm *tm) { break; /* - * "Elementary" conversion rules. - */ + * "Elementary" conversion rules. + */ case 'A': /* The day of week, using the locale's form. */ case 'a': LEGAL_ALT(0); @@ -2407,7 +2414,7 @@ char *arg_strptime(const char *buf, const char *fmt, struct tm *tm) { } tm->tm_wday = i; - bp += len; + bp += len; break; case 'B': /* The month, using the locale's form. */ @@ -2434,7 +2441,7 @@ char *arg_strptime(const char *buf, const char *fmt, struct tm *tm) { } tm->tm_mon = i; - bp += len; + bp += len; break; case 'C': /* The century number. */ @@ -2523,7 +2530,7 @@ char *arg_strptime(const char *buf, const char *fmt, struct tm *tm) { } tm->tm_hour += 12; - bp += strlen(am_pm[1]); + bp += strlen(am_pm[1]); break; } @@ -2541,11 +2548,11 @@ char *arg_strptime(const char *buf, const char *fmt, struct tm *tm) { case 'W': /* The week of year, beginning on monday. */ LEGAL_ALT(ALT_O); /* - * XXX This is bogus, as we can not assume any valid - * information present in the tm structure at this - * point to calculate a real value, so just check the - * range for now. - */ + * XXX This is bogus, as we can not assume any valid + * information present in the tm structure at this + * point to calculate a real value, so just check the + * range for now. + */ if (!(conv_num(&bp, &i, 0, 53))) { return (0); } @@ -2586,8 +2593,8 @@ char *arg_strptime(const char *buf, const char *fmt, struct tm *tm) { break; /* - * Miscellaneous conversions. - */ + * Miscellaneous conversions. + */ case 'n': /* Any kind of white-space. */ case 't': LEGAL_ALT(0); @@ -2618,7 +2625,7 @@ static int conv_num(const char **buf, int *dest, int llim, int ulim) { do { result *= 10; result += *(*buf)++ - '0'; - rulim /= 10; + rulim /= 10; } while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9'); if (result < llim || result > ulim) { @@ -2628,6 +2635,7 @@ static int conv_num(const char **buf, int *dest, int llim, int ulim) { *dest = result; return (1); } + /******************************************************************************* * arg_dbl: Implements the double command-line option * @@ -2691,7 +2699,8 @@ static int arg_dbl_scanfn(struct arg_dbl *parent, const char *argval) { /* extract double from argval into val */ val = strtod(argval, &end); - /* if success then store result in parent->dval[] array otherwise return error*/ + /* if success then store result in parent->dval[] array otherwise return + * error*/ if (*end == 0) { parent->dval[parent->count++] = val; } else { @@ -2763,9 +2772,9 @@ struct arg_dbl *arg_dbln(const char *shortopts, /* foolproof things by ensuring maxcount is not less than mincount */ maxcount = (maxcount < mincount) ? mincount : maxcount; - nbytes = sizeof(struct arg_dbl) /* storage for struct arg_dbl */ - + (size_t)(maxcount + 1) * - sizeof(double); /* storage for dval[maxcount] array plus one extra for padding to memory boundary */ + nbytes = sizeof(struct arg_dbl) /* storage for struct arg_dbl */ + + (size_t)(maxcount + 1) * sizeof(double); /* storage for dval[maxcount] array plus one + extra for padding to memory boundary */ result = (struct arg_dbl *)xmalloc(nbytes); @@ -2784,10 +2793,10 @@ struct arg_dbl *arg_dbln(const char *shortopts, result->hdr.errorfn = (arg_errorfn *)arg_dbl_errorfn; /* Store the dval[maxcount] array on the first double boundary that - * immediately follows the arg_dbl struct. We do the memory alignment - * purely for SPARC and Motorola systems. They require floats and - * doubles to be aligned on natural boundaries. - */ + * immediately follows the arg_dbl struct. We do the memory alignment + * purely for SPARC and Motorola systems. They require floats and + * doubles to be aligned on natural boundaries. + */ addr = (size_t)(result + 1); rem = addr % sizeof(double); result->dval = (double *)(addr + sizeof(double) - rem); @@ -2798,6 +2807,7 @@ struct arg_dbl *arg_dbln(const char *shortopts, ARG_TRACE(("arg_dbln() returns %p\n", result)); return result; } + /******************************************************************************* * arg_end: Implements the error handling utilities * @@ -2850,10 +2860,7 @@ static void arg_end_errorfn(void *parent, arg_dstr_t ds, int error, const char * progname = progname ? progname : ""; argval = argval ? argval : ""; - if (progname && strlen(progname) > 0) { - arg_dstr_catf(ds, "%s: ", progname); - } - + arg_dstr_catf(ds, "%s: ", progname); switch (error) { case ARG_ELIMIT: arg_dstr_cat(ds, "too many errors to display"); @@ -2932,6 +2939,7 @@ void arg_print_errors(FILE *fp, struct arg_end *end, const char *progname) { fputs(arg_dstr_cstr(ds), fp); arg_dstr_destroy(ds); } + /******************************************************************************* * arg_file: Implements the file command-line option * @@ -3005,7 +3013,8 @@ static const char *arg_basename(const char *filename) { } if (!result) { - result = filename; /* neither file separator was found so basename is the whole filename */ + result = filename; /* neither file separator was found so basename is the + whole filename */ } /* special cases of "." and ".." are not considered basenames */ @@ -3026,12 +3035,14 @@ static const char *arg_extension(const char *basename) { result = basename + strlen(basename); } - /* special case: basenames with a single leading dot (eg ".foo") are not considered as true extensions */ + /* special case: basenames with a single leading dot (eg ".foo") are not + * considered as true extensions */ if (basename && result == basename) { result = basename + strlen(basename); } - /* special case: empty extensions (eg "foo.","foo..") are not considered as true extensions */ + /* special case: empty extensions (eg "foo.","foo..") are not considered as + * true extensions */ if (basename && result && strlen(result) == 1) { result = basename + strlen(basename); } @@ -3054,7 +3065,8 @@ static int arg_file_scanfn(struct arg_file *parent, const char *argval) { parent->filename[parent->count] = argval; parent->basename[parent->count] = arg_basename(argval); parent->extension[parent->count] = arg_extension( - parent->basename[parent->count]); /* only seek extensions within the basename (not the file path)*/ + parent->basename[parent->count]); /* only seek extensions within the + basename (not the file path)*/ parent->count++; } @@ -3081,10 +3093,7 @@ static void arg_file_errorfn(struct arg_file *parent, /* make argval NULL safe */ argval = argval ? argval : ""; - if (progname && strlen(progname) > 0) { - arg_dstr_catf(ds, "%s: ", progname); - } - + arg_dstr_catf(ds, "%s: ", progname); switch (errorcode) { case ARG_ERR_MINCOUNT: arg_dstr_cat(ds, "missing option "); @@ -3143,7 +3152,8 @@ struct arg_file *arg_filen(const char *shortopts, result->hdr.checkfn = (arg_checkfn *)arg_file_checkfn; result->hdr.errorfn = (arg_errorfn *)arg_file_errorfn; - /* store the filename,basename,extension arrays immediately after the arg_file struct */ + /* store the filename,basename,extension arrays immediately after the arg_file + * struct */ result->filename = (const char **)(result + 1); result->basename = result->filename + maxcount; result->extension = result->basename + maxcount; @@ -3159,6 +3169,7 @@ struct arg_file *arg_filen(const char *shortopts, ARG_TRACE(("arg_filen() returns %p\n", result)); return result; } + /******************************************************************************* * arg_int: Implements the int command-line option * @@ -3316,7 +3327,8 @@ static int arg_int_scanfn(struct arg_int *parent, const char *argval) { long int val; const char *end; - /* attempt to extract hex integer (eg: +0x123) from argval into val conversion */ + /* attempt to extract hex integer (eg: +0x123) from argval into val + * conversion */ val = strtol0X(argval, &end, 'X', 16); if (end == argval) { /* hex failed, attempt octal conversion (eg +0o123) */ @@ -3325,7 +3337,8 @@ static int arg_int_scanfn(struct arg_int *parent, const char *argval) { /* octal failed, attempt binary conversion (eg +0B101) */ val = strtol0X(argval, &end, 'B', 2); if (end == argval) { - /* binary failed, attempt decimal conversion with no prefix (eg 1234) */ + /* binary failed, attempt decimal conversion with no prefix (eg 1234) + */ val = strtol(argval, (char **)&end, 10); if (end == argval) { /* all supported number formats failed */ @@ -3341,8 +3354,10 @@ static int arg_int_scanfn(struct arg_int *parent, const char *argval) { errorcode = ARG_ERR_OVERFLOW; } - /* Detect any suffixes (KB,MB,GB) and multiply argument value appropriately. */ - /* We need to be mindful of integer overflows when using such big numbers. */ + /* Detect any suffixes (KB,MB,GB) and multiply argument value appropriately. + */ + /* We need to be mindful of integer overflows when using such big numbers. + */ if (detectsuffix(end, "KB")) /* kilobytes */ { if (val > (INT_MAX / 1024) || val < (INT_MIN / 1024)) { @@ -3374,7 +3389,8 @@ static int arg_int_scanfn(struct arg_int *parent, const char *argval) { } } - /* printf("%s:scanfn(%p,%p) returns %d\n",__FILE__,parent,argval,errorcode); */ + /* printf("%s:scanfn(%p,%p) returns %d\n",__FILE__,parent,argval,errorcode); + */ return errorcode; } @@ -3467,6 +3483,7 @@ struct arg_int *arg_intn(const char *shortopts, ARG_TRACE(("arg_intn() returns %p\n", result)); return result; } + /******************************************************************************* * arg_lit: Implements the literature command-line option * @@ -3595,6 +3612,7 @@ struct arg_lit *arg_litn(const char *shortopts, ARG_TRACE(("arg_litn() returns %p\n", result)); return result; } + /******************************************************************************* * arg_rem: Implements the rem command-line option * @@ -3654,6 +3672,7 @@ struct arg_rem *arg_rem(const char *datatype, const char *glossary) { ARG_TRACE(("arg_rem() returns %p\n", result)); return result; } + /******************************************************************************* * arg_rex: Implements the regex command-line option * @@ -3752,7 +3771,9 @@ typedef struct { int len; } TRexMatch; -#ifdef __GNUC__ +#if defined(__clang__) +TREX_API TRex *trex_compile(const TRexChar *pattern, const TRexChar **error, int flags) __attribute__((optnone)); +#elif defined(__GNUC__) TREX_API TRex *trex_compile(const TRexChar *pattern, const TRexChar **error, int flags) __attribute__((optimize(0))); #else TREX_API TRex *trex_compile(const TRexChar *pattern, const TRexChar **error, int flags); @@ -3801,8 +3822,10 @@ static int arg_rex_scanfn(struct arg_rex *parent, const char *argval) { } else { struct privhdr *priv = (struct privhdr *)parent->hdr.priv; - /* test the current argument value for a match with the regular expression */ - /* if a match is detected, record the argument value in the arg_rex struct */ + /* test the current argument value for a match with the regular expression + */ + /* if a match is detected, record the argument value in the arg_rex struct + */ rex = trex_compile(priv->pattern, &error, priv->flags); is_match = trex_match(rex, argval); @@ -3942,16 +3965,17 @@ struct arg_rex *arg_rexn(const char *shortopts, result->sval = (const char **)(priv + 1); result->count = 0; - /* foolproof the string pointers by initializing them to reference empty strings */ + /* foolproof the string pointers by initializing them to reference empty + * strings */ for (i = 0; i < maxcount; i++) { result->sval[i] = ""; } /* here we construct and destroy a regex representation of the regular - * expression for no other reason than to force any regex errors to be - * trapped now rather than later. If we don't, then errors may go undetected - * until an argument is actually parsed. - */ + * expression for no other reason than to force any regex errors to be + * trapped now rather than later. If we don't, then errors may go undetected + * until an argument is actually parsed. + */ rex = trex_compile(priv->pattern, &error, priv->flags); if (rex == NULL) { @@ -4002,19 +4026,19 @@ static const TRexChar *g_nnames[] = {_SC("NONE"), _SC("OP_WB")}; #endif -#define OP_GREEDY (MAX_CHAR + 1) /* * + ? {n} */ -#define OP_OR (MAX_CHAR + 2) -#define OP_EXPR (MAX_CHAR + 3) /* parentesis () */ -#define OP_NOCAPEXPR (MAX_CHAR + 4) /* parentesis (?:) */ -#define OP_DOT (MAX_CHAR + 5) -#define OP_CLASS (MAX_CHAR + 6) -#define OP_CCLASS (MAX_CHAR + 7) -#define OP_NCLASS (MAX_CHAR + 8) /* negates class the [^ */ -#define OP_RANGE (MAX_CHAR + 9) -#define OP_CHAR (MAX_CHAR + 10) -#define OP_EOL (MAX_CHAR + 11) -#define OP_BOL (MAX_CHAR + 12) -#define OP_WB (MAX_CHAR + 13) +#define OP_GREEDY (MAX_CHAR + 1) /* * + ? {n} */ +#define OP_OR (MAX_CHAR + 2) +#define OP_EXPR (MAX_CHAR + 3) /* parentesis () */ +#define OP_NOCAPEXPR (MAX_CHAR + 4) /* parentesis (?:) */ +#define OP_DOT (MAX_CHAR + 5) +#define OP_CLASS (MAX_CHAR + 6) +#define OP_CCLASS (MAX_CHAR + 7) +#define OP_NCLASS (MAX_CHAR + 8) /* negates class the [^ */ +#define OP_RANGE (MAX_CHAR + 9) +#define OP_CHAR (MAX_CHAR + 10) +#define OP_EOL (MAX_CHAR + 11) +#define OP_BOL (MAX_CHAR + 12) +#define OP_WB (MAX_CHAR + 13) #define TREX_SYMBOL_ANY_CHAR ('.') #define TREX_SYMBOL_GREEDY_ONE_OR_MORE ('+') @@ -4063,7 +4087,7 @@ static int trex_newnode(TRex *exp, TRexNodeType type) { } if (exp->_nallocated < (exp->_nsize + 1)) { exp->_nallocated *= 2; - exp->_nodes = (TRexNode *)xrealloc(exp->_nodes, (size_t)exp->_nallocated * sizeof(TRexNode)); + exp->_nodes = (TRexNode *)xrealloc(exp->_nodes, (size_t)exp->_nallocated * sizeof(TRexNode)); } exp->_nodes[exp->_nsize++] = n; newid = exp->_nsize - 1; @@ -4179,6 +4203,7 @@ static int trex_charnode(TRex *exp, TRexBool isclass) { exp->_p++; return trex_newnode(exp, t); } + static int trex_class(TRex *exp) { int ret = -1; int first = -1, chain; @@ -4455,7 +4480,8 @@ static const TRexChar *trex_matchnode(TRex *exp, TRexNode *node, const TRexChar TRexNodeType type = node->type; switch (type) { case OP_GREEDY: { - /* TRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL; */ + /* TRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : + * NULL; */ TRexNode *greedystop = NULL; int p0 = (node->right >> 16) & 0x0000FFFF, p1 = node->right & 0x0000FFFF, nmaches = 0; const TRexChar *s = str, *good = str; @@ -4739,6 +4765,7 @@ TRexBool trex_getsubexp(TRex *exp, int n, TRexMatch *subexp) { *subexp = exp->_matches[n]; return TRex_True; } + /******************************************************************************* * arg_str: Implements the str command-line option * @@ -4887,7 +4914,8 @@ struct arg_str *arg_strn(const char *shortopts, result->sval = (const char **)(result + 1); result->count = 0; - /* foolproof the string pointers by initializing them to reference empty strings */ + /* foolproof the string pointers by initializing them to reference empty + * strings */ for (i = 0; i < maxcount; i++) { result->sval[i] = ""; } @@ -4895,6 +4923,7 @@ struct arg_str *arg_strn(const char *shortopts, ARG_TRACE(("arg_strn() returns %p\n", result)); return result; } + /******************************************************************************* * arg_cmd: Provides the sub-command mechanism * @@ -5172,8 +5201,8 @@ int arg_make_syntax_err_help_msg(arg_dstr_t ds, struct arg_end *end, int *exitcode) { /* help handling - * note: '-h|--help' takes precedence over error reporting - */ + * note: '-h|--help' takes precedence over error reporting + */ if (help > 0) { arg_make_help_msg(ds, name, argtable); *exitcode = EXIT_SUCCESS; @@ -5189,6 +5218,7 @@ int arg_make_syntax_err_help_msg(arg_dstr_t ds, return 0; } + /******************************************************************************* * argtable3: Implements the main interfaces of the library * @@ -5311,25 +5341,26 @@ static struct longoptions *alloc_longoptions(struct arg_hdr **table) { char *store; /* - * Determine the total number of option structs required - * by counting the number of comma separated long options - * in all table entries and return the count in noptions. - * note: noptions starts at 1 not 0 because we getoptlong - * requires a NULL option entry to terminate the option array. - * While we are at it, count the number of chars required - * to store private copies of all the longoption strings - * and return that count in logoptlen. - */ + * Determine the total number of option structs required + * by counting the number of comma separated long options + * in all table entries and return the count in noptions. + * note: noptions starts at 1 not 0 because we getoptlong + * requires a NULL option entry to terminate the option array. + * While we are at it, count the number of chars required + * to store private copies of all the longoption strings + * and return that count in logoptlen. + */ tabindex = 0; do { const char *longopts = table[tabindex]->longopts; - longoptlen += (longopts ? strlen(longopts) : 0) + 1; + longoptlen += (longopts ? strlen(longopts) : 0) + 1; while (longopts) { noptions++; longopts = strchr(longopts + 1, ','); } } while (!(table[tabindex++]->flag & ARG_TERMINATOR)); - /*printf("%d long options consuming %d chars in total\n",noptions,longoptlen);*/ + /*printf("%d long options consuming %d chars in + * total\n",noptions,longoptlen);*/ /* allocate storage for return data structure as: */ /* (struct longoptions) + (struct options)[noptions] + char[longoptlen] */ @@ -5390,7 +5421,7 @@ static char *alloc_shortoptions(struct arg_hdr **table) { /* determine the total number of option chars required */ for (tabindex = 0; !(table[tabindex]->flag & ARG_TERMINATOR); tabindex++) { struct arg_hdr *hdr = table[tabindex]; - len += 3 * (hdr->shortopts ? strlen(hdr->shortopts) : 0); + len += 3 * (hdr->shortopts ? strlen(hdr->shortopts) : 0); } result = xmalloc(len); @@ -5455,11 +5486,11 @@ static void arg_parse_tagged(int argc, char **argv, struct arg_hdr **table, stru while ((copt = getopt_long(argc, argv, shortoptions, longoptions->options, NULL)) != -1) { #endif /* - printf("optarg='%s'\n",optarg); - printf("optind=%d\n",optind); - printf("copt=%c\n",(char)copt); - printf("optopt=%c (%d)\n",optopt, (int)(optopt)); - */ + printf("optarg='%s'\n",optarg); + printf("optind=%d\n",optind); + printf("copt=%c\n",(char)copt); + printf("optopt=%c (%d)\n",optopt, (int)(optopt)); + */ switch (copt) { case 0: { int tabindex = longoptions->getoptval; @@ -5468,7 +5499,8 @@ static void arg_parse_tagged(int argc, char **argv, struct arg_hdr **table, stru if (optarg && optarg[0] == 0 && (table[tabindex]->flag & ARG_HASVALUE)) { /* printf(": long option %s requires an argument\n",argv[optind-1]); */ arg_register_error(endtable, endtable, ARG_EMISSARG, argv[optind - 1]); - /* continue to scan the (empty) argument value to enforce argument count checking */ + /* continue to scan the (empty) argument value to enforce argument count + * checking */ } if (table[tabindex]->scanfn) { int errorcode = table[tabindex]->scanfn(parent, optarg); @@ -5480,10 +5512,10 @@ static void arg_parse_tagged(int argc, char **argv, struct arg_hdr **table, stru case '?': /* - * getopt_long() found an unrecognised short option. - * if it was a short option its value is in optopt - * if it was a long option then optopt=0 - */ + * getopt_long() found an unrecognised short option. + * if it was a short option its value is in optopt + * if it was a long option then optopt=0 + */ switch (optopt) { case 0: /*printf("?0 unrecognised long option %s\n",argv[optind-1]);*/ @@ -5498,8 +5530,8 @@ static void arg_parse_tagged(int argc, char **argv, struct arg_hdr **table, stru case ':': /* - * getopt_long() found an option with its argument missing. - */ + * getopt_long() found an option with its argument missing. + */ /*printf(": option %s requires an argument\n",argv[optind-1]); */ arg_register_error(endtable, endtable, ARG_EMISSARG, argv[optind - 1]); break; @@ -5547,16 +5579,19 @@ static void arg_parse_untagged(int argc, char **argv, struct arg_hdr **table, st return; } - /* skip table entries with non-null long or short options (they are not untagged entries) */ + /* skip table entries with non-null long or short options (they are not + * untagged entries) */ if (table[tabindex]->longopts || table[tabindex]->shortopts) { - /*printf("arg_parse_untagged(): skipping argtable[%d] (tagged argument)\n",tabindex);*/ + /*printf("arg_parse_untagged(): skipping argtable[%d] (tagged + * argument)\n",tabindex);*/ tabindex++; continue; } /* skip table entries with NULL scanfn */ if (!(table[tabindex]->scanfn)) { - /*printf("arg_parse_untagged(): skipping argtable[%d] (NULL scanfn)\n",tabindex);*/ + /*printf("arg_parse_untagged(): skipping argtable[%d] (NULL + * scanfn)\n",tabindex);*/ tabindex++; continue; } @@ -5567,8 +5602,10 @@ static void arg_parse_untagged(int argc, char **argv, struct arg_hdr **table, st parent = table[tabindex]->parent; errorcode = table[tabindex]->scanfn(parent, argv[optind]); if (errorcode == 0) { - /* success, move onto next argv[optind] but stay with same table[tabindex] */ - /*printf("arg_parse_untagged(): argtable[%d] successfully matched\n",tabindex);*/ + /* success, move onto next argv[optind] but stay with same table[tabindex] + */ + /*printf("arg_parse_untagged(): argtable[%d] successfully + * matched\n",tabindex);*/ optind++; /* clear the last tentative error */ @@ -5585,7 +5622,8 @@ static void arg_parse_untagged(int argc, char **argv, struct arg_hdr **table, st } } - /* if a tenative error still remains at this point then register it as a proper error */ + /* if a tenative error still remains at this point then register it as a + * proper error */ if (errorlast) { arg_register_error(endtable, parentlast, errorlast, optarglast); optind++; @@ -5594,7 +5632,8 @@ static void arg_parse_untagged(int argc, char **argv, struct arg_hdr **table, st /* only get here when not all argv[] entries were consumed */ /* register an error for each unused argv[] entry */ while (optind < argc) { - /*printf("arg_parse_untagged(): argv[%d]=\"%s\" not consumed\n",optind,argv[optind]);*/ + /*printf("arg_parse_untagged(): argv[%d]=\"%s\" not + * consumed\n",optind,argv[optind]);*/ arg_register_error(endtable, endtable, ARG_ENOMATCH, argv[optind++]); } @@ -5646,7 +5685,8 @@ int arg_parse(int argc, char **argv, void **argtable) { /* Failure to trap this case results in an unwanted NULL result from */ /* the malloc for argvcopy (next code block). */ if (argc == 0) { - /* We must still perform post-parse checks despite the absence of command line arguments */ + /* We must still perform post-parse checks despite the absence of command + * line arguments */ arg_parse_check(table, endtable); /* Now we are finished */ @@ -5656,10 +5696,10 @@ int arg_parse(int argc, char **argv, void **argtable) { argvcopy = (char **)xmalloc(sizeof(char *) * (size_t)(argc + 1)); /* - Fill in the local copy of argv[]. We need a local copy - because getopt rearranges argv[] which adversely affects - susbsequent parsing attempts. - */ + Fill in the local copy of argv[]. We need a local copy + because getopt rearranges argv[] which adversely affects + susbsequent parsing attempts. + */ for (i = 0; i < argc; i++) { argvcopy[i] = argv[i]; } @@ -5708,12 +5748,12 @@ static void arg_cat(char **pdest, const char *src, size_t *pndest) { char *end = dest + *pndest; /*locate null terminator of dest string */ - while (dest < end && *dest != 0) { + while (dest < end - 1 && *dest != 0) { dest++; } /* concat src string to dest string */ - while (dest < end && *src != 0) { + while (dest < end - 1 && *src != 0) { *dest++ = *src++; } @@ -5871,14 +5911,16 @@ void arg_print_option_ds(arg_dstr_t ds, char syntax[200] = ""; suffix = suffix ? suffix : ""; - /* there is no way of passing the proper optvalue for optional argument values here, so we must ignore it */ + /* there is no way of passing the proper optvalue for optional argument values + * here, so we must ignore it */ arg_cat_optionv(syntax, sizeof(syntax) - 1, shortopts, longopts, datatype, 0, "|"); arg_dstr_cat(ds, syntax); arg_dstr_cat(ds, (char *)suffix); } -/* this function should be deprecated because it doesn't consider optional argument values (ARG_HASOPTVALUE) */ +/* this function should be deprecated because it doesn't consider optional + * argument values (ARG_HASOPTVALUE) */ void arg_print_option(FILE *fp, const char *shortopts, const char *longopts, const char *datatype, const char *suffix) { arg_dstr_t ds = arg_dstr_create(); arg_print_option_ds(ds, shortopts, longopts, datatype, suffix); @@ -5892,10 +5934,10 @@ void arg_print_option(FILE *fp, const char *shortopts, const char *longopts, con * in: -xvfsd, or -xvf[sd], or [-xvsfd] */ static void arg_print_gnuswitch_ds(arg_dstr_t ds, struct arg_hdr **table) { - int tabindex; - char *format1 = " -%c"; - char *format2 = " [-%c"; - char *suffix = ""; + int tabindex; + const char *format1 = " -%c"; + const char *format2 = " [-%c"; + const char *suffix = ""; /* print all mandatory switches that are without argument values */ for (tabindex = 0; table[tabindex] && !(table[tabindex]->flag & ARG_TERMINATOR); tabindex++) { @@ -5914,11 +5956,8 @@ static void arg_print_gnuswitch_ds(arg_dstr_t ds, struct arg_hdr **table) { continue; } - if (table[tabindex]->maxcount == ARG_MAX_FLAG) { - continue; - } - - /* print the short option (only the first short option char, ignore multiple choices)*/ + /* print the short option (only the first short option char, ignore multiple + * choices)*/ arg_dstr_catf(ds, format1, table[tabindex]->shortopts[0]); format1 = "%c"; format2 = "[%c"; @@ -5941,10 +5980,6 @@ static void arg_print_gnuswitch_ds(arg_dstr_t ds, struct arg_hdr **table) { continue; } - if (table[tabindex]->maxcount == ARG_MAX_FLAG) { - continue; - } - /* print first short option */ arg_dstr_catf(ds, format2, table[tabindex]->shortopts[0]); format2 = "%c"; @@ -5966,11 +6001,9 @@ void arg_print_syntax_ds(arg_dstr_t ds, void **argtable, const char *suffix) { char syntax[200] = ""; const char *shortopts, *longopts, *datatype; - /* skip short options without arg values (they were printed by arg_print_gnu_switch) */ + /* skip short options without arg values (they were printed by + * arg_print_gnu_switch) */ if (table[tabindex]->shortopts && !(table[tabindex]->flag & ARG_HASVALUE)) { - if (table[tabindex]->maxcount == ARG_MAX_FLAG) { - arg_dstr_catf(ds, " [-%c]", table[tabindex]->shortopts[0]); - } continue; } @@ -6170,9 +6203,9 @@ static void arg_print_formatted_ds(arg_dstr_t ds, const unsigned lmargin, const while (line_end > line_start) { /* Eat leading white spaces. This is essential because while - wrapping lines, there will often be a whitespace at beginning - of line */ - while (isspace((int)(*(text + line_start)))) { + wrapping lines, there will often be a whitespace at beginning + of line. Preserve newlines */ + while (isspace((int)(*(text + line_start))) && *(text + line_start) != '\n') { line_start++; } @@ -6184,18 +6217,33 @@ static void arg_print_formatted_ds(arg_dstr_t ds, const unsigned lmargin, const line_end--; } - /* Consume trailing spaces */ - while ((line_end > line_start) && isspace((int)(*(text + line_end)))) { - line_end--; - } + /* If no whitespace could be found, eg. the text is one long word, break + * the word */ + if (line_end == line_start) { + /* Set line_end to previous value */ + line_end = line_start + colwidth; + } else { + /* Consume trailing spaces, except newlines */ + while ((line_end > line_start) && isspace((int)(*(text + line_end))) && *(text + line_start) != '\n') { + line_end--; + } - /* Restore the last non-space character */ - line_end++; + /* Restore the last non-space character */ + line_end++; + } } /* Output line of text */ while (line_start < line_end) { char c = *(text + line_start); + + /* If character is newline stop printing, skip this character, as a + * newline will be printed below. */ + if (c == '\n') { + line_start++; + break; + } + arg_dstr_catc(ds, c); line_start++; } @@ -6295,15 +6343,15 @@ int arg_nullcheck(void **argtable) { } /* - * arg_free() is deprecated in favour of arg_freetable() due to a flaw in its design. - * The flaw results in memory leak in the (very rare) case that an intermediate - * entry in the argtable array failed its memory allocation while others following - * that entry were still allocated ok. Those subsequent allocations will not be - * deallocated by arg_free(). - * Despite the unlikeliness of the problem occurring, and the even unlikelier event - * that it has any deliterious effect, it is fixed regardless by replacing arg_free() - * with the newer arg_freetable() function. - * We still keep arg_free() for backwards compatibility. + * arg_free() is deprecated in favour of arg_freetable() due to a flaw in its + * design. The flaw results in memory leak in the (very rare) case that an + * intermediate entry in the argtable array failed its memory allocation while + * others following that entry were still allocated ok. Those subsequent + * allocations will not be deallocated by arg_free(). Despite the unlikeliness + * of the problem occurring, and the even unlikelier event that it has any + * deliterious effect, it is fixed regardless by replacing arg_free() with the + * newer arg_freetable() function. We still keep arg_free() for backwards + * compatibility. */ void arg_free(void **argtable) { struct arg_hdr **table = (struct arg_hdr **)argtable; @@ -6312,11 +6360,12 @@ void arg_free(void **argtable) { /*printf("arg_free(%p)\n",argtable);*/ do { /* - if we encounter a NULL entry then somewhat incorrectly we presume - we have come to the end of the array. It isnt strictly true because - an intermediate entry could be NULL with other non-NULL entries to follow. - The subsequent argtable entries would then not be freed as they should. - */ + if we encounter a NULL entry then somewhat incorrectly we presume + we have come to the end of the array. It isnt strictly true because + an intermediate entry could be NULL with other non-NULL entries to + follow. The subsequent argtable entries would then not be freed as they + should. + */ if (table[tabindex] == NULL) { break; } @@ -6328,7 +6377,8 @@ void arg_free(void **argtable) { } while (!(flag & ARG_TERMINATOR)); } -/* frees each non-NULL element of argtable[], where n is the size of the number of entries in the array */ +/* frees each non-NULL element of argtable[], where n is the size of the number + * of entries in the array */ void arg_freetable(void **argtable, size_t n) { struct arg_hdr **table = (struct arg_hdr **)argtable; size_t tabindex = 0; diff --git a/srcs/libs/args/argtable3.h b/srcs/libs/args/argtable3.h index d31054b..d1f3b87 100644 --- a/srcs/libs/args/argtable3.h +++ b/srcs/libs/args/argtable3.h @@ -44,7 +44,6 @@ extern "C" { #define ARG_DSTR_SIZE 200 #define ARG_CMD_NAME_LEN 100 #define ARG_CMD_DESCRIPTION_LEN 256 -#define ARG_MAX_FLAG (0x0000FFAA) #ifndef ARG_REPLACE_GETOPT #define ARG_REPLACE_GETOPT 1 /* use the embedded getopt as the system getopt(3) */ @@ -102,7 +101,8 @@ typedef struct arg_hdr { const char *shortopts; /* String defining the short options */ const char *longopts; /* String defiing the long options */ const char *datatype; /* Description of the argument data type */ - const char *glossary; /* Description of the option as shown by arg_print_glossary function */ + const char *glossary; /* Description of the option as shown by + arg_print_glossary function */ int mincount; /* Minimum number of occurences of this option accepted */ int maxcount; /* Maximum number of occurences if this option accepted */ void *parent; /* Pointer to parent arg_xxx struct */ @@ -168,6 +168,7 @@ enum { ARG_ELONGOPT, ARG_EMISSARG }; + typedef struct arg_end { struct arg_hdr hdr; /* The mandatory argtable header struct */ int count; /* Number of errors encountered */ @@ -293,7 +294,7 @@ ARG_EXTERN struct arg_date *arg_daten(const char *shortopts, int maxcount, const char *glossary); -ARG_EXTERN struct arg_end *arg_end(int maxerrors); +ARG_EXTERN struct arg_end *arg_end(int maxcount); #define ARG_DSTR_STATIC ((arg_dstr_freefn *)0) #define ARG_DSTR_VOLATILE ((arg_dstr_freefn *)1) diff --git a/srcs/libs/cmdline/cmd_menu.c b/srcs/libs/cmdline/cmd_menu.c index 759014c..3e7fd31 100644 --- a/srcs/libs/cmdline/cmd_menu.c +++ b/srcs/libs/cmdline/cmd_menu.c @@ -501,7 +501,7 @@ int menu_run(int argc, char **argv) { int errCode2 = 0; arg_rex_t *cmd3 = arg_rex1(NULL, NULL, "base64", NULL, REG_ICASE, NULL); - arg_lit_t *operate3 = arg_litn("o", "operate", 0, ARG_MAX_FLAG, "\tBase64 decode, otherwise mean base64 encode"); + arg_lit_t *operate3 = arg_litn("o", "operate", 0, 1, "\tBase64 decode, otherwise mean base64 encode"); arg_str_t *value3 = arg_str0(NULL, NULL, "", NULL); arg_lit_t *helpCmd3 = arg_lit0("h", "help", NULL); arg_end_t *end3 = arg_end(20); @@ -525,7 +525,7 @@ int menu_run(int argc, char **argv) { int errCode4 = 0; arg_rex_t *cmd5 = arg_rex1(NULL, NULL, "cipher", NULL, REG_ICASE, NULL); - arg_lit_t *operate5 = arg_litn("e", "encrypt", 0, ARG_MAX_FLAG, "\tEncryption, Ignore means decryption."); + arg_lit_t *operate5 = arg_litn("e", "encrypt", 0, 1, "\tEncryption, Ignore means decryption."); arg_str_t *alg5 = arg_str0("a", "algorithms", "algorithms", "\tChose \033[1;7mCryptography\033[0m algorithms."); arg_str_t *key5 = arg_str0("k", "key", "Key", "\tCryptographic key"); arg_str_t *value5 = arg_str0(NULL, NULL, "", NULL);