LCOV - code coverage report
Current view: top level - lib/argparse - rte_argparse.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 335 422 79.4 %
Date: 2025-11-01 17:50:34 Functions: 23 28 82.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 247 308 80.2 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2024 HiSilicon Limited
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <errno.h>
       6                 :            : #include <stdlib.h>
       7                 :            : #include <string.h>
       8                 :            : #include <ctype.h>
       9                 :            : 
      10                 :            : #include <eal_export.h>
      11                 :            : #include <rte_log.h>
      12                 :            : #include <rte_os.h>
      13                 :            : 
      14                 :            : #include "rte_argparse.h"
      15                 :            : 
      16         [ -  + ]:        253 : RTE_LOG_REGISTER_DEFAULT(rte_argparse_logtype, INFO);
      17                 :            : #define RTE_LOGTYPE_ARGPARSE rte_argparse_logtype
      18                 :            : #define ARGPARSE_LOG(level, ...) \
      19                 :            :         RTE_LOG_LINE(level, ARGPARSE, "" __VA_ARGS__)
      20                 :            : 
      21                 :            : static inline bool
      22                 :            : is_arg_optional(const struct rte_argparse_arg *arg)
      23                 :            : {
      24                 :      12483 :         return arg->name_long[0] == '-';
      25                 :            : }
      26                 :            : 
      27                 :            : static inline bool
      28                 :            : is_arg_positional(const struct rte_argparse_arg *arg)
      29                 :            : {
      30                 :      38950 :         return arg->name_long[0] != '-';
      31                 :            : }
      32                 :            : 
      33                 :            : static inline bool
      34                 :            : is_valid_has_value_field(const struct rte_argparse_arg *arg)
      35                 :            : {
      36                 :      12475 :         switch (arg->value_required) {
      37                 :            :         case RTE_ARGPARSE_VALUE_NONE:
      38                 :            :         case RTE_ARGPARSE_VALUE_OPTIONAL:
      39                 :            :         case RTE_ARGPARSE_VALUE_REQUIRED:
      40                 :            :                 return true;
      41                 :            :         /* omit default case so compiler warns on any missing enum values */
      42                 :            :         }
      43                 :            :         return false;
      44                 :            : }
      45                 :            : 
      46                 :            : static inline bool
      47                 :            : is_valid_value_type_field(const struct rte_argparse_arg *arg)
      48                 :            : {
      49         [ +  - ]:      10913 :         switch (arg->value_type) {
      50                 :            :         case RTE_ARGPARSE_VALUE_TYPE_NONE:
      51                 :            :         case RTE_ARGPARSE_VALUE_TYPE_INT:
      52                 :            :         case RTE_ARGPARSE_VALUE_TYPE_U8:
      53                 :            :         case RTE_ARGPARSE_VALUE_TYPE_U16:
      54                 :            :         case RTE_ARGPARSE_VALUE_TYPE_U32:
      55                 :            :         case RTE_ARGPARSE_VALUE_TYPE_U64:
      56                 :            :         case RTE_ARGPARSE_VALUE_TYPE_STR:
      57                 :            :         case RTE_ARGPARSE_VALUE_TYPE_BOOL:
      58                 :            :         case RTE_ARGPARSE_VALUE_TYPE_CORELIST:
      59                 :            :                 return true;
      60                 :            :         /* omit default case so compiler warns on any missing enum values */
      61                 :            :         }
      62                 :            :         return false;
      63                 :            : }
      64                 :            : 
      65                 :            : 
      66                 :            : static inline bool
      67                 :            : arg_attr_flag_multi(const struct rte_argparse_arg *arg)
      68                 :            : {
      69                 :          8 :         return (arg->flags & RTE_ARGPARSE_FLAG_SUPPORT_MULTI) != 0;
      70                 :            : }
      71                 :            : 
      72                 :            : static inline uint64_t
      73                 :            : arg_attr_unused_bits(const struct rte_argparse_arg *arg)
      74                 :            : {
      75                 :            : #define USED_BIT_MASK   (RTE_ARGPARSE_FLAG_SUPPORT_MULTI)
      76                 :      12463 :         return arg->flags & ~USED_BIT_MASK;
      77                 :            : }
      78                 :            : 
      79                 :            : static int
      80                 :      12483 : verify_arg_name(const struct rte_argparse_arg *arg)
      81                 :            : {
      82         [ +  + ]:      12483 :         if (is_arg_optional(arg)) {
      83         [ +  + ]:      12472 :                 if (strlen(arg->name_long) <= 3) {
      84                 :          1 :                         ARGPARSE_LOG(ERR, "optional long name %s too short!", arg->name_long);
      85                 :          1 :                         return -EINVAL;
      86                 :            :                 }
      87         [ +  + ]:      12471 :                 if (arg->name_long[1] != '-') {
      88                 :          1 :                         ARGPARSE_LOG(ERR, "optional long name %s doesn't start with '--'",
      89                 :            :                                      arg->name_long);
      90                 :          1 :                         return -EINVAL;
      91                 :            :                 }
      92         [ +  + ]:      12470 :                 if (arg->name_long[2] == '-') {
      93                 :          1 :                         ARGPARSE_LOG(ERR, "optional long name %s should not start with '---'",
      94                 :            :                                      arg->name_long);
      95                 :          1 :                         return -EINVAL;
      96                 :            :                 }
      97                 :            :         }
      98                 :            : 
      99         [ +  + ]:      12480 :         if (arg->name_short == NULL)
     100                 :            :                 return 0;
     101                 :            : 
     102         [ +  + ]:       3109 :         if (!is_arg_optional(arg)) {
     103                 :          1 :                 ARGPARSE_LOG(ERR, "short name %s corresponding long name must be optional!",
     104                 :            :                              arg->name_short);
     105                 :          1 :                 return -EINVAL;
     106                 :            :         }
     107                 :            : 
     108   [ +  +  +  + ]:       3108 :         if (strlen(arg->name_short) != 2 || arg->name_short[0] != '-' ||
     109         [ -  + ]:       3105 :                 arg->name_short[1] == '-') {
     110                 :          3 :                 ARGPARSE_LOG(ERR, "short name %s must start with a hyphen (-) followed by an English letter",
     111                 :            :                              arg->name_short);
     112                 :          3 :                 return -EINVAL;
     113                 :            :         }
     114                 :            : 
     115                 :            :         return 0;
     116                 :            : }
     117                 :            : 
     118                 :            : static int
     119                 :            : verify_arg_help(const struct rte_argparse_arg *arg)
     120                 :            : {
     121         [ +  + ]:      12476 :         if (arg->help == NULL) {
     122                 :          1 :                 ARGPARSE_LOG(ERR, "argument %s doesn't have help info!", arg->name_long);
     123                 :            :                 return -EINVAL;
     124                 :            :         }
     125                 :            : 
     126                 :            :         return 0;
     127                 :            : }
     128                 :            : 
     129                 :            : static int
     130         [ +  - ]:      12475 : verify_arg_has_val(const struct rte_argparse_arg *arg)
     131                 :            : {
     132                 :            :         if (!is_valid_has_value_field(arg)) {
     133                 :          0 :                 ARGPARSE_LOG(ERR, "argument %s has invalid value field!", arg->name_long);
     134                 :          0 :                 return -EINVAL;
     135                 :            :         }
     136         [ +  + ]:      12475 :         if (is_arg_positional(arg)) {
     137         [ +  + ]:         10 :                 if (arg->value_required == RTE_ARGPARSE_VALUE_REQUIRED)
     138                 :            :                         return 0;
     139                 :          2 :                 ARGPARSE_LOG(ERR, "argument %s is positional, must config required-val!",
     140                 :            :                              arg->name_long);
     141                 :          2 :                 return -EINVAL;
     142                 :            :         }
     143                 :            : 
     144                 :            :         return 0;
     145                 :            : }
     146                 :            : 
     147                 :            : static int
     148                 :      12473 : verify_arg_saver(const struct rte_argparse *obj, uint32_t index)
     149                 :            : {
     150                 :            :         const struct rte_argparse_arg *arg = &obj->args[index];
     151                 :            : 
     152         [ +  + ]:      12473 :         if (arg->val_saver == NULL) {
     153         [ +  + ]:       1560 :                 if (arg->value_type != RTE_ARGPARSE_VALUE_TYPE_NONE) {
     154                 :          1 :                         ARGPARSE_LOG(ERR, "argument %s parsed by callback, value-type should not be set!",
     155                 :            :                                      arg->name_long);
     156                 :          1 :                         return -EINVAL;
     157                 :            :                 }
     158         [ +  + ]:       1559 :                 if (obj->callback == NULL) {
     159                 :          1 :                         ARGPARSE_LOG(ERR, "argument %s parsed by callback, but callback is NULL!",
     160                 :            :                                      arg->name_long);
     161                 :          1 :                         return -EINVAL;
     162                 :            :                 }
     163                 :            :                 return 0;
     164                 :            :         }
     165                 :            : 
     166                 :            :         /* check value_type field */
     167                 :            :         if (!is_valid_value_type_field(arg)) {
     168                 :          0 :                 ARGPARSE_LOG(ERR, "argument %s has invalid value-type field!", arg->name_long);
     169                 :          0 :                 return -EINVAL;
     170                 :            :         }
     171         [ +  + ]:      10913 :         if (arg->value_type == RTE_ARGPARSE_VALUE_TYPE_NONE) {
     172                 :          7 :                 ARGPARSE_LOG(ERR, "missing value-type for argument %s!", arg->name_long);
     173                 :          7 :                 return -EINVAL;
     174                 :            :         }
     175                 :            : 
     176   [ +  +  +  + ]:      10906 :         if (arg->value_required == RTE_ARGPARSE_VALUE_REQUIRED && arg->val_set != NULL) {
     177                 :          1 :                 ARGPARSE_LOG(ERR, "argument %s has required value, value-set should be NULL!",
     178                 :            :                              arg->name_long);
     179                 :          1 :                 return -EINVAL;
     180                 :            :         }
     181                 :            : 
     182                 :            :         return 0;
     183                 :            : }
     184                 :            : 
     185                 :            : static int
     186                 :      12463 : verify_arg_flags(const struct rte_argparse *obj, uint32_t index)
     187                 :            : {
     188                 :            :         const struct rte_argparse_arg *arg = &obj->args[index];
     189                 :            :         uint64_t unused_bits = arg_attr_unused_bits(arg);
     190                 :            : 
     191         [ -  + ]:      12463 :         if (unused_bits != 0) {
     192                 :          0 :                 ARGPARSE_LOG(ERR, "argument %s flags unused bits should not be set!",
     193                 :            :                              arg->name_long);
     194                 :          0 :                 return -EINVAL;
     195                 :            :         }
     196                 :            : 
     197         [ +  + ]:      12463 :         if (!(arg->flags & RTE_ARGPARSE_FLAG_SUPPORT_MULTI))
     198                 :            :                 return 0;
     199                 :            : 
     200         [ +  + ]:       1520 :         if (is_arg_positional(arg)) {
     201                 :          1 :                 ARGPARSE_LOG(ERR, "argument %s is positional, don't support multiple times!",
     202                 :            :                              arg->name_long);
     203                 :          1 :                 return -EINVAL;
     204                 :            :         }
     205                 :            : 
     206         [ -  + ]:       1519 :         if (arg->val_saver != NULL) {
     207                 :          0 :                 ARGPARSE_LOG(ERR, "argument %s supports multiple times, should use callback to parse!",
     208                 :            :                              arg->name_long);
     209                 :          0 :                 return -EINVAL;
     210                 :            :         }
     211                 :            : 
     212                 :            :         return 0;
     213                 :            : }
     214                 :            : 
     215                 :            : static int
     216                 :      12462 : verify_arg_repeat(const struct rte_argparse *self, uint32_t index)
     217                 :            : {
     218                 :            :         const struct rte_argparse_arg *arg = &self->args[index];
     219                 :            :         uint32_t i;
     220                 :            : 
     221         [ +  + ]:     310006 :         for (i = 0; i < index; i++) {
     222         [ -  + ]:     297544 :                 if (!strcmp(arg->name_long, self->args[i].name_long)) {
     223                 :          0 :                         ARGPARSE_LOG(ERR, "argument %s repeat!", arg->name_long);
     224                 :          0 :                         return -EINVAL;
     225                 :            :                 }
     226                 :            :         }
     227                 :            : 
     228         [ +  + ]:      12462 :         if (arg->name_short == NULL)
     229                 :            :                 return 0;
     230                 :            : 
     231         [ +  + ]:      48395 :         for (i = 0; i < index; i++) {
     232         [ +  + ]:      45301 :                 if (self->args[i].name_short == NULL)
     233                 :      28589 :                         continue;
     234         [ -  + ]:      16712 :                 if (!strcmp(arg->name_short, self->args[i].name_short)) {
     235                 :          0 :                         ARGPARSE_LOG(ERR, "argument %s repeat!", arg->name_short);
     236                 :          0 :                         return -EINVAL;
     237                 :            :                 }
     238                 :            :         }
     239                 :            : 
     240                 :            :         return 0;
     241                 :            : }
     242                 :            : 
     243                 :            : static int
     244                 :      12483 : verify_argparse_arg(const struct rte_argparse *obj, uint32_t index)
     245                 :            : {
     246                 :      12483 :         const struct rte_argparse_arg *arg = &obj->args[index];
     247                 :            :         int ret;
     248                 :            : 
     249                 :      12483 :         ret = verify_arg_name(arg);
     250         [ +  + ]:      12483 :         if (ret != 0)
     251                 :            :                 return ret;
     252                 :            : 
     253                 :            :         ret = verify_arg_help(arg);
     254                 :            :         if (ret != 0)
     255                 :          1 :                 return ret;
     256                 :            : 
     257                 :      12475 :         ret = verify_arg_has_val(arg);
     258         [ +  + ]:      12475 :         if (ret != 0)
     259                 :            :                 return ret;
     260                 :            : 
     261                 :      12473 :         ret = verify_arg_saver(obj, index);
     262         [ +  + ]:      12473 :         if (ret != 0)
     263                 :            :                 return ret;
     264                 :            : 
     265                 :      12463 :         ret = verify_arg_flags(obj, index);
     266         [ +  + ]:      12463 :         if (ret != 0)
     267                 :            :                 return ret;
     268                 :            : 
     269                 :      12462 :         ret = verify_arg_repeat(obj, index);
     270         [ -  + ]:      12462 :         if (ret != 0)
     271                 :          0 :                 return ret;
     272                 :            : 
     273                 :            :         return 0;
     274                 :            : }
     275                 :            : 
     276                 :            : static int
     277                 :        326 : verify_argparse(const struct rte_argparse *obj, size_t *nb_args)
     278                 :            : {
     279                 :            :         size_t idx;
     280                 :            :         int ret;
     281                 :            : 
     282         [ +  + ]:        326 :         if (obj->prog_name == NULL) {
     283                 :          1 :                 ARGPARSE_LOG(ERR, "program name is NULL!");
     284                 :          1 :                 return -EINVAL;
     285                 :            :         }
     286                 :            : 
     287         [ +  + ]:        325 :         if (obj->usage == NULL) {
     288                 :          1 :                 ARGPARSE_LOG(ERR, "usage is NULL!");
     289                 :          1 :                 return -EINVAL;
     290                 :            :         }
     291                 :            : 
     292         [ +  + ]:       2268 :         for (idx = 0; idx < RTE_DIM(obj->reserved_flags); idx++) {
     293         [ -  + ]:       1944 :                 if (obj->reserved_flags[idx]) {
     294                 :          0 :                         ARGPARSE_LOG(ERR, "reserved flags cannot be set!");
     295                 :          0 :                         return -EINVAL;
     296                 :            :                 }
     297                 :            :         }
     298                 :            : 
     299         [ +  + ]:       5184 :         for (idx = 0; idx < RTE_DIM(obj->reserved); idx++) {
     300         [ -  + ]:       4860 :                 if (obj->reserved[idx] != 0) {
     301                 :          0 :                         ARGPARSE_LOG(ERR, "reserved field must be zero!");
     302                 :          0 :                         return -EINVAL;
     303                 :            :                 }
     304                 :            :         }
     305                 :            : 
     306                 :            :         idx = 0;
     307         [ +  + ]:      12786 :         while (obj->args[idx].name_long != NULL) {
     308   [ +  +  +  + ]:      12484 :                 if (is_arg_positional(&obj->args[idx]) && obj->ignore_non_flag_args) {
     309                 :          1 :                         ARGPARSE_LOG(ERR, "Error validating argparse object: positional args are not allowed when ignore_non_flag_args is set!");
     310                 :          1 :                         return -EINVAL;
     311                 :            :                 }
     312                 :      12483 :                 ret = verify_argparse_arg(obj, idx);
     313         [ +  + ]:      12483 :                 if (ret != 0)
     314                 :         21 :                         return ret;
     315                 :      12462 :                 idx++;
     316                 :            :         }
     317                 :        302 :         *nb_args = idx;
     318                 :            : 
     319                 :        302 :         return 0;
     320                 :            : }
     321                 :            : 
     322                 :            : static uint32_t
     323                 :            : calc_position_count(const struct rte_argparse *obj)
     324                 :            : {
     325                 :            :         const struct rte_argparse_arg *arg;
     326                 :            :         uint32_t count = 0;
     327                 :            :         uint32_t i;
     328                 :            : 
     329                 :      12462 :         for (i = 0; /* NULL */; i++) {
     330                 :      12462 :                 arg = &obj->args[i];
     331   [ -  -  +  + ]:      12764 :                 if (obj->args[i].name_long == NULL)
     332                 :            :                         break;
     333   [ -  -  +  + ]:      12462 :                 if (is_arg_positional(arg))
     334                 :          7 :                         count++;
     335                 :            :         }
     336                 :            : 
     337                 :            :         return count;
     338                 :            : }
     339                 :            : 
     340                 :            : static const struct rte_argparse_arg *
     341                 :            : find_position_arg(const struct rte_argparse *obj, uint32_t index)
     342                 :            : {
     343                 :            :         const struct rte_argparse_arg *arg;
     344                 :            :         uint32_t count = 0;
     345                 :            :         uint32_t i;
     346                 :            : 
     347                 :          2 :         for (i = 0; /* NULL */; i++) {
     348                 :          9 :                 arg = &obj->args[i];
     349         [ +  - ]:          9 :                 if (arg->name_long == NULL)
     350                 :            :                         break;
     351         [ -  + ]:          9 :                 if (!is_arg_positional(arg))
     352                 :          0 :                         continue;
     353                 :          9 :                 count++;
     354         [ +  + ]:          9 :                 if (count == index)
     355                 :            :                         return arg;
     356                 :            :         }
     357                 :            : 
     358                 :            :         return NULL;
     359                 :            : }
     360                 :            : 
     361                 :            : static bool
     362                 :      14376 : is_arg_match(const struct rte_argparse_arg *arg, const char *curr_argv, uint32_t len)
     363                 :            : {
     364   [ +  +  +  + ]:      14376 :         if (strlen(arg->name_long) == len && strncmp(arg->name_long, curr_argv, len) == 0)
     365                 :            :                 return true;
     366                 :            : 
     367         [ +  + ]:      13949 :         if (arg->name_short == NULL)
     368                 :            :                 return false;
     369                 :            : 
     370   [ +  +  +  + ]:       4938 :         if (strlen(arg->name_short) == len && strncmp(arg->name_short, curr_argv, len) == 0)
     371                 :        199 :                 return true;
     372                 :            : 
     373                 :            :         return false;
     374                 :            : }
     375                 :            : 
     376                 :            : static const struct rte_argparse_arg *
     377                 :        627 : find_option_arg(const struct rte_argparse *obj, uint32_t *idx,
     378                 :            :                 const char *curr_argv, const char *has_equal, const char **arg_name)
     379                 :            : {
     380         [ +  + ]:        627 :         uint32_t len = strlen(curr_argv) - (has_equal != NULL ? strlen(has_equal) : 0);
     381                 :            :         const struct rte_argparse_arg *arg;
     382                 :            :         uint32_t i;
     383                 :            :         bool match;
     384                 :            : 
     385                 :      13750 :         for (i = 0; /* nothing */; i++) {
     386                 :      14377 :                 arg = &obj->args[i];
     387         [ +  + ]:      14377 :                 if (arg->name_long == NULL)
     388                 :            :                         break;
     389                 :      14376 :                 match = is_arg_match(arg, curr_argv, len);
     390         [ +  + ]:      14376 :                 if (match) {
     391                 :            :                         /* Obtains the exact matching name (long or short). */
     392         [ +  + ]:        626 :                         *arg_name = len > 2 ? arg->name_long : arg->name_short;
     393                 :        626 :                         *idx = i;
     394                 :        626 :                         return arg;
     395                 :            :                 }
     396                 :            :         }
     397                 :            : 
     398                 :            :         return NULL;
     399                 :            : }
     400                 :            : 
     401                 :            : static int
     402                 :         26 : parse_arg_int(const struct rte_argparse_arg *arg, const char *value)
     403                 :            : {
     404                 :         26 :         char *s = NULL;
     405                 :            : 
     406         [ +  + ]:         26 :         if (value == NULL) {
     407                 :          5 :                 *(int *)arg->val_saver = (int)(intptr_t)arg->val_set;
     408                 :          5 :                 return 0;
     409                 :            :         }
     410                 :            : 
     411                 :         21 :         errno = 0;
     412                 :         21 :         *(int *)arg->val_saver = strtol(value, &s, 0);
     413         [ +  + ]:         21 :         if (errno == ERANGE) {
     414                 :          1 :                 ARGPARSE_LOG(ERR, "argument %s numerical out of range!", arg->name_long);
     415                 :          1 :                 return -EINVAL;
     416                 :            :         }
     417                 :            : 
     418         [ +  + ]:         20 :         if (s[0] != '\0') {
     419                 :          5 :                 ARGPARSE_LOG(ERR, "argument %s expect an integer value!", arg->name_long);
     420                 :          5 :                 return -EINVAL;
     421                 :            :         }
     422                 :            : 
     423                 :            :         return 0;
     424                 :            : }
     425                 :            : 
     426                 :            : static int
     427                 :          4 : parse_arg_u8(const struct rte_argparse_arg *arg, const char *value)
     428                 :            : {
     429                 :            :         unsigned long val;
     430                 :          4 :         char *s = NULL;
     431                 :            : 
     432         [ -  + ]:          4 :         if (value == NULL) {
     433                 :          0 :                 *(uint8_t *)arg->val_saver = (uint8_t)(intptr_t)arg->val_set;
     434                 :          0 :                 return 0;
     435                 :            :         }
     436                 :            : 
     437                 :          4 :         errno = 0;
     438                 :          4 :         val = strtoul(value, &s, 0);
     439   [ +  +  +  + ]:          4 :         if (errno == ERANGE || val > UINT8_MAX) {
     440                 :          2 :                 ARGPARSE_LOG(ERR, "argument %s numerical out of range!", arg->name_long);
     441                 :          2 :                 return -EINVAL;
     442                 :            :         }
     443                 :            : 
     444         [ +  + ]:          2 :         if (s[0] != '\0') {
     445                 :          1 :                 ARGPARSE_LOG(ERR, "argument %s expect an uint8 value!", arg->name_long);
     446                 :          1 :                 return -EINVAL;
     447                 :            :         }
     448                 :            : 
     449                 :          1 :         *(uint8_t *)arg->val_saver = val;
     450                 :            : 
     451                 :          1 :         return 0;
     452                 :            : }
     453                 :            : 
     454                 :            : static int
     455                 :          4 : parse_arg_u16(const struct rte_argparse_arg *arg, const char *value)
     456                 :            : {
     457                 :            :         unsigned long val;
     458                 :          4 :         char *s = NULL;
     459                 :            : 
     460         [ -  + ]:          4 :         if (value == NULL) {
     461                 :          0 :                 *(uint16_t *)arg->val_saver = (uint16_t)(intptr_t)arg->val_set;
     462                 :          0 :                 return 0;
     463                 :            :         }
     464                 :            : 
     465                 :          4 :         errno = 0;
     466                 :          4 :         val = strtoul(value, &s, 0);
     467   [ +  +  +  + ]:          4 :         if (errno == ERANGE || val > UINT16_MAX) {
     468                 :          2 :                 ARGPARSE_LOG(ERR, "argument %s numerical out of range!", arg->name_long);
     469                 :          2 :                 return -EINVAL;
     470                 :            :         }
     471                 :            : 
     472         [ +  + ]:          2 :         if (s[0] != '\0') {
     473                 :          1 :                 ARGPARSE_LOG(ERR, "argument %s expect an uint16 value!", arg->name_long);
     474                 :          1 :                 return -EINVAL;
     475                 :            :         }
     476                 :            : 
     477                 :          1 :         *(uint16_t *)arg->val_saver = val;
     478                 :            : 
     479                 :          1 :         return 0;
     480                 :            : }
     481                 :            : 
     482                 :            : static int
     483                 :          4 : parse_arg_u32(const struct rte_argparse_arg *arg, const char *value)
     484                 :            : {
     485                 :            :         unsigned long val;
     486                 :          4 :         char *s = NULL;
     487                 :            : 
     488         [ -  + ]:          4 :         if (value == NULL) {
     489                 :          0 :                 *(uint32_t *)arg->val_saver = (uint32_t)(intptr_t)arg->val_set;
     490                 :          0 :                 return 0;
     491                 :            :         }
     492                 :            : 
     493                 :          4 :         errno = 0;
     494                 :          4 :         val = strtoul(value, &s, 0);
     495   [ +  +  +  + ]:          4 :         if (errno == ERANGE || val > UINT32_MAX) {
     496                 :          2 :                 ARGPARSE_LOG(ERR, "argument %s numerical out of range!", arg->name_long);
     497                 :          2 :                 return -EINVAL;
     498                 :            :         }
     499                 :            : 
     500         [ +  + ]:          2 :         if (s[0] != '\0') {
     501                 :          1 :                 ARGPARSE_LOG(ERR, "argument %s expect an uint32 value!", arg->name_long);
     502                 :          1 :                 return -EINVAL;
     503                 :            :         }
     504                 :            : 
     505                 :          1 :         *(uint32_t *)arg->val_saver = val;
     506                 :            : 
     507                 :          1 :         return 0;
     508                 :            : }
     509                 :            : 
     510                 :            : static int
     511                 :          3 : parse_arg_u64(const struct rte_argparse_arg *arg, const char *value)
     512                 :            : {
     513                 :            :         unsigned long val;
     514                 :          3 :         char *s = NULL;
     515                 :            : 
     516         [ -  + ]:          3 :         if (value == NULL) {
     517                 :          0 :                 *(uint64_t *)arg->val_saver = (uint64_t)(intptr_t)arg->val_set;
     518                 :          0 :                 return 0;
     519                 :            :         }
     520                 :            : 
     521                 :          3 :         errno = 0;
     522                 :          3 :         val = strtoull(value, &s, 0);
     523         [ +  + ]:          3 :         if (errno == ERANGE) {
     524                 :          1 :                 ARGPARSE_LOG(ERR, "argument %s numerical out of range!", arg->name_long);
     525                 :          1 :                 return -EINVAL;
     526                 :            :         }
     527                 :            : 
     528         [ +  + ]:          2 :         if (s[0] != '\0') {
     529                 :          1 :                 ARGPARSE_LOG(ERR, "argument %s expect an uint64 value!", arg->name_long);
     530                 :          1 :                 return -EINVAL;
     531                 :            :         }
     532                 :            : 
     533                 :          1 :         *(uint64_t *)arg->val_saver = val;
     534                 :            : 
     535                 :          1 :         return 0;
     536                 :            : }
     537                 :            : 
     538                 :            : static int
     539                 :            : parse_arg_str(const struct rte_argparse_arg *arg, const char *value)
     540                 :            : {
     541         [ +  + ]:        413 :         if (value == NULL) {
     542                 :          5 :                 *(char **)arg->val_saver = arg->val_set;
     543                 :          5 :                 return 0;
     544                 :            :         }
     545                 :        408 :         *(const char **)arg->val_saver = value;
     546                 :            : 
     547                 :        408 :         return 0;
     548                 :            : }
     549                 :            : 
     550                 :            : static int
     551                 :        131 : parse_arg_bool(const struct rte_argparse_arg *arg, const char *value)
     552                 :            : {
     553         [ +  + ]:        131 :         if (value == NULL) {
     554                 :        125 :                 *(bool *)arg->val_saver = (arg->val_set != NULL);
     555                 :        125 :                 return 0;
     556                 :            :         }
     557                 :            : 
     558   [ +  +  +  + ]:          6 :         if (strcmp(value, "true") == 0 || strcmp(value, "1") == 0)
     559                 :          2 :                 *(bool *)arg->val_saver = true;
     560   [ +  +  +  + ]:          4 :         else if (strcmp(value, "false") == 0 || strcmp(value, "0") == 0)
     561                 :          2 :                 *(bool *)arg->val_saver = false;
     562                 :            :         else {
     563                 :          2 :                 ARGPARSE_LOG(ERR, "argument %s expects a boolean (true/false, 0/1) value!",
     564                 :            :                         arg->name_long);
     565                 :          2 :                 return -EINVAL;
     566                 :            :         }
     567                 :            : 
     568                 :            :         return 0;
     569                 :            : }
     570                 :            : 
     571                 :            : static int
     572                 :         34 : parse_arg_corelist(const struct rte_argparse_arg *arg, const char *value)
     573                 :            : {
     574                 :         34 :         rte_cpuset_t *cpuset = arg->val_saver;
     575                 :            :         const char *last = value;
     576                 :            :         int min = -1;
     577                 :            : 
     578         [ -  + ]:         34 :         if (value == NULL) {
     579                 :          0 :                 *cpuset = *(rte_cpuset_t *)arg->val_set;
     580                 :          0 :                 return 0;
     581                 :            :         }
     582                 :            : 
     583                 :         34 :         CPU_ZERO(cpuset);
     584         [ +  + ]:         76 :         while (*last != '\0') {
     585                 :            :                 char *end;
     586                 :            :                 int64_t idx;
     587                 :            :                 int32_t max;
     588                 :            : 
     589         [ +  + ]:         67 :                 while (isblank(*value))
     590                 :          6 :                         value++;
     591                 :            : 
     592         [ +  + ]:         61 :                 if (!isdigit(*value)) {
     593                 :         13 :                         ARGPARSE_LOG(ERR, "argument %s has an unexpected non digit character!",
     594                 :            :                                 arg->name_long);
     595                 :         19 :                         return -EINVAL;
     596                 :            :                 }
     597                 :            : 
     598                 :         48 :                 errno = 0;
     599                 :         48 :                 idx = strtol(value, &end, 10);
     600                 :         48 :                 last = end;
     601   [ +  -  +  + ]:         48 :                 if (errno || idx > UINT16_MAX) {
     602                 :          1 :                         ARGPARSE_LOG(ERR, "argument %s contains a numerical value out of range!",
     603                 :            :                                 arg->name_long);
     604                 :          1 :                         return -EINVAL;
     605                 :            :                 }
     606                 :            : 
     607         [ +  + ]:         47 :                 if (*end == '-') {
     608         [ +  + ]:         16 :                         if (min != -1) { /* can't have '-' within a range */
     609                 :          2 :                                 ARGPARSE_LOG(ERR, "argument %s has an unexpected - character!",
     610                 :            :                                         arg->name_long);
     611                 :          2 :                                 return -EINVAL;
     612                 :            :                         }
     613                 :         14 :                         min = idx; /* start of range, move to next loop stage */
     614         [ +  + ]:         31 :                 } else if (*end == ',' || *end == '\0') {
     615                 :            :                         /* single value followed by comma or end (min is set only by '-') */
     616         [ +  + ]:         28 :                         if (min == -1) {
     617                 :         20 :                                 min = max = idx;
     618         [ +  + ]:          8 :                         } else if (min > idx) {
     619                 :            :                                 /* we have range from high to low */
     620                 :            :                                 max = min;
     621                 :          1 :                                 min = idx;
     622                 :            :                         } else {
     623                 :            :                                 /* range from low to high */
     624                 :          7 :                                 max = idx;
     625                 :            :                         }
     626                 :            : 
     627         [ +  + ]:        206 :                         for (; min <= max; min++)
     628         [ +  - ]:        178 :                                 CPU_SET(min, cpuset);
     629                 :            : 
     630                 :            :                         min = -1; /* no longer in a range */
     631                 :            :                 } else {
     632                 :            :                         /* end is an unexpected character, return error */
     633                 :          3 :                         ARGPARSE_LOG(ERR, "argument %s has an unexpected character!",
     634                 :            :                                 arg->name_long);
     635                 :          3 :                         return -EINVAL;
     636                 :            :                 }
     637                 :         42 :                 value = last + 1;
     638                 :            :         }
     639                 :            :         return 0;
     640                 :            : }
     641                 :            : 
     642                 :            : static int
     643                 :        619 : parse_arg_autosave(const struct rte_argparse_arg *arg, const char *value)
     644                 :            : {
     645   [ -  +  +  +  :        619 :         switch (arg->value_type) {
          +  +  +  +  +  
                      - ]
     646                 :          0 :         case RTE_ARGPARSE_VALUE_TYPE_NONE:
     647                 :          0 :                 ARGPARSE_LOG(ERR, "argument %s doesn't specify a value-type!", arg->name_long);
     648                 :          0 :                 return -EINVAL;
     649                 :         26 :         case RTE_ARGPARSE_VALUE_TYPE_INT:
     650                 :         26 :                 return parse_arg_int(arg, value);
     651                 :          4 :         case RTE_ARGPARSE_VALUE_TYPE_U8:
     652                 :          4 :                 return parse_arg_u8(arg, value);
     653                 :          4 :         case RTE_ARGPARSE_VALUE_TYPE_U16:
     654                 :          4 :                 return parse_arg_u16(arg, value);
     655                 :          4 :         case RTE_ARGPARSE_VALUE_TYPE_U32:
     656                 :          4 :                 return parse_arg_u32(arg, value);
     657                 :          3 :         case RTE_ARGPARSE_VALUE_TYPE_U64:
     658                 :          3 :                 return parse_arg_u64(arg, value);
     659                 :            :         case RTE_ARGPARSE_VALUE_TYPE_STR:
     660                 :            :                 return parse_arg_str(arg, value);
     661                 :        131 :         case RTE_ARGPARSE_VALUE_TYPE_BOOL:
     662                 :        131 :                 return parse_arg_bool(arg, value);
     663                 :         34 :         case RTE_ARGPARSE_VALUE_TYPE_CORELIST:
     664                 :         34 :                 return parse_arg_corelist(arg, value);
     665                 :            :         /* omit default case so compiler warns on missing enum values */
     666                 :            :         }
     667                 :            :         return -EINVAL;
     668                 :            : }
     669                 :            : 
     670                 :            : /* arg_parse indicates the name entered by the user, which can be long-name or short-name. */
     671                 :            : static int
     672                 :        625 : parse_arg_val(const struct rte_argparse *obj, const char *arg_name,
     673                 :            :               const struct rte_argparse_arg *arg, char *value)
     674                 :            : {
     675                 :            :         int ret;
     676                 :            : 
     677         [ +  + ]:        625 :         if (arg->val_saver == NULL)
     678                 :         64 :                 ret = obj->callback((uint32_t)(uintptr_t)arg->val_set, value, obj->opaque);
     679                 :            :         else
     680                 :        561 :                 ret = parse_arg_autosave(arg, value);
     681         [ +  + ]:        625 :         if (ret != 0) {
     682                 :          7 :                 ARGPARSE_LOG(ERR, "argument %s parse value fail!", arg_name);
     683                 :          7 :                 return ret;
     684                 :            :         }
     685                 :            : 
     686                 :            :         return 0;
     687                 :            : }
     688                 :            : 
     689                 :            : static bool
     690                 :        627 : is_help(const char *curr_argv)
     691                 :            : {
     692   [ +  -  +  - ]:        627 :         return strcmp(curr_argv, "-h") == 0 || strcmp(curr_argv, "--help") == 0;
     693                 :            : }
     694                 :            : 
     695                 :            : static int
     696                 :        302 : parse_args(const struct rte_argparse *obj, bool *arg_parsed,
     697                 :            :                 int argc, char **argv, bool *show_help)
     698                 :            : {
     699                 :            :         uint32_t position_count = calc_position_count(obj);
     700                 :            :         const struct rte_argparse_arg *arg;
     701                 :            :         uint32_t position_index = 0;
     702                 :            :         const char *arg_name;
     703                 :            :         size_t n_args_to_move;
     704                 :            :         char **args_to_move;
     705                 :            :         uint32_t arg_idx;
     706                 :            :         char *curr_argv;
     707                 :            :         char *value;
     708                 :            :         int ret;
     709                 :            :         int i;
     710                 :            : 
     711                 :            :         n_args_to_move = 0;
     712                 :        302 :         args_to_move = calloc(argc, sizeof(args_to_move[0]));
     713         [ -  + ]:        302 :         if (args_to_move == NULL) {
     714                 :          0 :                 ARGPARSE_LOG(ERR, "failed to allocate memory for internal flag processing!");
     715                 :          0 :                 return -ENOMEM;
     716                 :            :         }
     717                 :            : 
     718         [ +  + ]:        949 :         for (i = 1; i < argc; i++) {
     719                 :        667 :                 curr_argv = argv[i];
     720                 :            : 
     721         [ +  + ]:        667 :                 if (strcmp(argv[i], "--") == 0) {
     722                 :          1 :                         i++;
     723                 :          1 :                         break;
     724                 :            :                 }
     725                 :            : 
     726         [ +  + ]:        666 :                 if (curr_argv[0] != '-') {
     727         [ +  + ]:         39 :                         if (obj->ignore_non_flag_args) {
     728                 :            :                                 /* Move non-flag args to args_to_move array. */
     729                 :         29 :                                 args_to_move[n_args_to_move++] = curr_argv;
     730                 :         29 :                                 argv[i] = NULL;
     731                 :         29 :                                 continue;
     732                 :            :                         }
     733                 :            :                         /* process positional parameters. */
     734                 :         10 :                         position_index++;
     735         [ +  + ]:         10 :                         if (position_index > position_count) {
     736                 :          3 :                                 ARGPARSE_LOG(ERR, "too many positional arguments %s!", curr_argv);
     737                 :            :                                 ret = -EINVAL;
     738                 :          3 :                                 goto err_out;
     739                 :            :                         }
     740                 :            :                         arg = find_position_arg(obj, position_index);
     741                 :          7 :                         ret = parse_arg_val(obj, arg->name_long, arg, curr_argv);
     742         [ +  + ]:          7 :                         if (ret != 0)
     743                 :          2 :                                 goto err_out;
     744                 :          5 :                         continue;
     745                 :            :                 }
     746                 :            : 
     747                 :            :                 /* process optional parameters. */
     748         [ -  + ]:        627 :                 if (is_help(curr_argv)) {
     749                 :          0 :                         *show_help = true;
     750                 :          0 :                         continue;
     751                 :            :                 }
     752                 :            : 
     753                 :        627 :                 value = strchr(curr_argv, '=');
     754   [ +  +  +  +  :        627 :                 if (value == NULL && curr_argv[1] != '-' && strlen(curr_argv) > 2)
                   +  + ]
     755                 :          4 :                         value = &curr_argv[2];
     756                 :        627 :                 arg_name = NULL;
     757                 :        627 :                 arg = find_option_arg(obj, &arg_idx, curr_argv, value, &arg_name);
     758   [ +  +  -  + ]:        627 :                 if (arg == NULL || arg_name == NULL) {
     759                 :          1 :                         ARGPARSE_LOG(ERR, "unknown argument %s!", curr_argv);
     760                 :            :                         ret = -EINVAL;
     761                 :          1 :                         goto err_out;
     762                 :            :                 }
     763                 :            : 
     764   [ +  +  +  + ]:        626 :                 if (arg_parsed[arg_idx] && !arg_attr_flag_multi(arg)) {
     765                 :          1 :                         ARGPARSE_LOG(ERR, "argument %s should not occur multiple times!", arg_name);
     766                 :            :                         ret = -EINVAL;
     767                 :          1 :                         goto err_out;
     768                 :            :                 }
     769                 :            : 
     770   [ +  +  +  + ]:        625 :                 if (value != NULL && value[0] == '=')
     771                 :        251 :                         value++; /* skip '=' */
     772         [ +  + ]:        625 :                 if (arg->value_required == RTE_ARGPARSE_VALUE_NONE) {
     773         [ -  + ]:        147 :                         if (value != NULL) {
     774                 :          0 :                                 ARGPARSE_LOG(ERR, "argument %s should not take value!", arg_name);
     775                 :            :                                 ret = -EINVAL;
     776                 :          0 :                                 goto err_out;
     777                 :            :                         }
     778         [ +  + ]:        478 :                 } else if (arg->value_required == RTE_ARGPARSE_VALUE_REQUIRED) {
     779         [ +  + ]:        450 :                         if (value == NULL) {
     780         [ +  + ]:        213 :                                 if (i >= argc - 1) {
     781                 :          7 :                                         ARGPARSE_LOG(ERR, "argument %s doesn't have value!",
     782                 :            :                                                         arg_name);
     783                 :            :                                         ret = -EINVAL;
     784                 :          7 :                                         goto err_out;
     785                 :            :                                 }
     786                 :            :                                 /* Set value and make i move next. */
     787                 :        206 :                                 value = argv[++i];
     788                 :            :                         }
     789                 :            :                 } else {
     790                 :            :                         /* Do nothing, because it's optional value, only support arg=val or arg. */
     791                 :            :                 }
     792                 :            : 
     793                 :        618 :                 ret = parse_arg_val(obj, arg_name, arg, value);
     794         [ +  + ]:        618 :                 if (ret != 0)
     795                 :          5 :                         goto err_out;
     796                 :            : 
     797                 :            :                 /* This argument parsed success! then mark it parsed. */
     798                 :        613 :                 arg_parsed[arg_idx] = true;
     799                 :            :         }
     800                 :            : 
     801                 :            :         ret = i;
     802         [ +  + ]:        283 :         if (n_args_to_move > 0) {
     803                 :            :                 /* Close the gaps in argv array by moving elements down filling in the NULLs. */
     804                 :            :                 int j = 1;
     805         [ +  + ]:         87 :                 for (i = 1; i < ret; i++) {
     806         [ +  + ]:         72 :                         if (argv[i] != NULL)
     807                 :         43 :                                 argv[j++] = argv[i];
     808                 :            :                 }
     809                 :            :                 ret = j; /* only return args actually handled */
     810                 :            :                 /* Then put contents of the args_to_move array into the argv in the space left. */
     811         [ +  + ]:         44 :                 for (i = 0; i < (int)n_args_to_move; i++)
     812                 :         29 :                         argv[j++] = args_to_move[i];
     813                 :            :         }
     814                 :        283 : err_out:
     815                 :        302 :         free(args_to_move);
     816                 :        302 :         return ret;
     817                 :            : }
     818                 :            : 
     819                 :            : static uint32_t
     820                 :          0 : calc_help_align(const struct rte_argparse *obj)
     821                 :            : {
     822                 :            :         const struct rte_argparse_arg *arg;
     823                 :            :         uint32_t width = 12; /* Default "-h, --help  " len. */
     824                 :            :         uint32_t len;
     825                 :            :         uint32_t i;
     826                 :            : 
     827                 :          0 :         for (i = 0; /* NULL */; i++) {
     828                 :          0 :                 arg = &obj->args[i];
     829         [ #  # ]:          0 :                 if (arg->name_long == NULL)
     830                 :            :                         break;
     831                 :          0 :                 len = strlen(arg->name_long);
     832   [ #  #  #  # ]:          0 :                 if (is_arg_optional(arg) && arg->name_short != NULL) {
     833                 :          0 :                         len += strlen(", ");
     834                 :          0 :                         len += strlen(arg->name_short);
     835                 :            :                 }
     836                 :          0 :                 width = RTE_MAX(width, 1 + len + 2); /* start with 1 & end with 2 space. */
     837                 :            :         }
     838                 :            : 
     839                 :          0 :         return width;
     840                 :            : }
     841                 :            : 
     842                 :            : static void
     843                 :          0 : show_oneline_help(FILE *stream, const struct rte_argparse_arg *arg, uint32_t width)
     844                 :            : {
     845                 :            :         uint32_t len = 0;
     846                 :            :         uint32_t i;
     847                 :            : 
     848         [ #  # ]:          0 :         if (arg->name_short != NULL)
     849                 :          0 :                 len = fprintf(stream, " %s,", arg->name_short);
     850                 :          0 :         len += fprintf(stream, " %s", arg->name_long);
     851                 :            : 
     852         [ #  # ]:          0 :         for (i = len; i < width; i++)
     853                 :            :                 fprintf(stream, " ");
     854                 :            : 
     855                 :          0 :         fprintf(stream, "%s\n", arg->help);
     856                 :          0 : }
     857                 :            : 
     858                 :            : static void
     859                 :          0 : show_args_pos_help(FILE *stream, const struct rte_argparse *obj, uint32_t align)
     860                 :            : {
     861                 :            :         uint32_t position_count = calc_position_count(obj);
     862                 :            :         const struct rte_argparse_arg *arg;
     863                 :            :         uint32_t i;
     864                 :            : 
     865         [ #  # ]:          0 :         if (position_count == 0)
     866                 :            :                 return;
     867                 :            : 
     868                 :            :         fprintf(stream, "\npositional arguments:\n");
     869                 :          0 :         for (i = 0; /* NULL */; i++) {
     870                 :          0 :                 arg = &obj->args[i];
     871         [ #  # ]:          0 :                 if (arg->name_long == NULL)
     872                 :            :                         break;
     873         [ #  # ]:          0 :                 if (!is_arg_positional(arg))
     874                 :          0 :                         continue;
     875                 :          0 :                 show_oneline_help(stream, arg, align);
     876                 :            :         }
     877                 :            : }
     878                 :            : 
     879                 :            : static void
     880                 :          0 : show_args_opt_help(FILE *stream, const struct rte_argparse *obj, uint32_t align)
     881                 :            : {
     882                 :            :         static const struct rte_argparse_arg help = {
     883                 :            :                 .name_long = "--help",
     884                 :            :                 .name_short = "-h",
     885                 :            :                 .help = "show this help message and exit.",
     886                 :            :         };
     887                 :            :         const struct rte_argparse_arg *arg;
     888                 :            :         uint32_t i;
     889                 :            : 
     890                 :            :         fprintf(stream, "\noptions:\n");
     891                 :          0 :         show_oneline_help(stream, &help, align);
     892                 :          0 :         for (i = 0; /* NULL */; i++) {
     893                 :          0 :                 arg = &obj->args[i];
     894         [ #  # ]:          0 :                 if (arg->name_long == NULL)
     895                 :            :                         break;
     896         [ #  # ]:          0 :                 if (!is_arg_optional(arg))
     897                 :          0 :                         continue;
     898                 :          0 :                 show_oneline_help(stream, arg, align);
     899                 :            :         }
     900                 :          0 : }
     901                 :            : 
     902                 :            : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_argparse_print_help, 25.11)
     903                 :            : void
     904                 :          0 : rte_argparse_print_help(FILE *stream, const struct rte_argparse *obj)
     905                 :            : {
     906                 :          0 :         uint32_t align = calc_help_align(obj);
     907                 :            : 
     908                 :          0 :         fprintf(stream, "usage: %s %s\n", obj->prog_name, obj->usage);
     909         [ #  # ]:          0 :         if (obj->descriptor != NULL)
     910                 :            :                 fprintf(stream, "\ndescriptor: %s\n", obj->descriptor);
     911                 :            : 
     912                 :          0 :         show_args_pos_help(stream, obj, align);
     913                 :          0 :         show_args_opt_help(stream, obj, align);
     914                 :            : 
     915         [ #  # ]:          0 :         if (obj->epilog != NULL)
     916                 :            :                 fprintf(stream, "\n%s\n", obj->epilog);
     917                 :            :         else
     918                 :            :                 fprintf(stream, "\n");
     919                 :          0 : }
     920                 :            : 
     921                 :            : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_argparse_parse, 24.03)
     922                 :            : int
     923                 :        326 : rte_argparse_parse(const struct rte_argparse *obj, int argc, char **argv)
     924                 :            : {
     925                 :            :         bool *arg_parsed = NULL;
     926                 :        326 :         bool show_help = false;
     927                 :        326 :         size_t nb_args = 0;
     928                 :            :         int ret;
     929                 :            : 
     930                 :        326 :         ret = verify_argparse(obj, &nb_args);
     931         [ +  + ]:        326 :         if (ret != 0)
     932                 :         24 :                 goto error;
     933                 :            : 
     934                 :            :         /* allocate the flags array to indicate what arguments are parsed or not */
     935                 :        302 :         arg_parsed = calloc(nb_args, sizeof(*arg_parsed));
     936         [ -  + ]:        302 :         if (arg_parsed == NULL) {
     937                 :          0 :                 ARGPARSE_LOG(ERR, "failed to allocate memory for argument flags!");
     938                 :            :                 ret = -ENOMEM;
     939                 :          0 :                 goto error;
     940                 :            :         }
     941                 :            : 
     942                 :        302 :         ret = parse_args(obj, arg_parsed, argc, argv, &show_help);
     943                 :        302 :         free(arg_parsed);
     944         [ +  + ]:        302 :         if (ret < 0)
     945                 :         19 :                 goto error;
     946                 :            : 
     947         [ -  + ]:        283 :         if (show_help) {
     948         [ #  # ]:          0 :                 if (obj->print_help != NULL)
     949                 :          0 :                         obj->print_help(obj);
     950                 :            :                 else
     951                 :          0 :                         rte_argparse_print_help(stdout, obj);
     952                 :          0 :                 exit(0);
     953                 :            :         }
     954                 :            : 
     955                 :            :         return ret;
     956                 :            : 
     957                 :         43 : error:
     958         [ +  + ]:         43 :         if (obj->exit_on_error)
     959                 :          7 :                 exit(ret);
     960                 :            :         return ret;
     961                 :            : }
     962                 :            : 
     963                 :            : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_argparse_parse_type, 24.03)
     964                 :            : int
     965                 :         58 : rte_argparse_parse_type(const char *str, enum rte_argparse_value_type val_type, void *val)
     966                 :            : {
     967                 :         58 :         struct rte_argparse_arg arg = {
     968                 :            :                 .name_long = str,
     969                 :            :                 .name_short = NULL,
     970                 :            :                 .val_saver = val,
     971                 :            :                 .val_set = NULL,
     972                 :            :                 .value_type = val_type,
     973                 :            :         };
     974         [ -  + ]:         58 :         if (val_type == RTE_ARGPARSE_VALUE_TYPE_NONE) {
     975                 :          0 :                 ARGPARSE_LOG(ERR, "argument %s doesn't have value-type!", str);
     976                 :          0 :                 return -EINVAL;
     977                 :            :         }
     978                 :         58 :         return parse_arg_autosave(&arg, str);
     979                 :            : }

Generated by: LCOV version 1.14