Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Command line argument parsing
0003  *
0004  * @file nclopt.c
0005  */
0006 /* -----------------------------------------------------------------------------
0007  * Enduro/X Middleware Platform for Distributed Transaction Processing
0008  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0009  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0010  * This software is released under one of the following licenses:
0011  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0012  * See LICENSE file for full text.
0013  * -----------------------------------------------------------------------------
0014  * AGPL license:
0015  *
0016  * This program is free software; you can redistribute it and/or modify it under
0017  * the terms of the GNU Affero General Public License, version 3 as published
0018  * by the Free Software Foundation;
0019  *
0020  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0021  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0022  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0023  * for more details.
0024  *
0025  * You should have received a copy of the GNU Affero General Public License along 
0026  * with this program; if not, write to the Free Software Foundation, Inc.,
0027  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0028  *
0029  * -----------------------------------------------------------------------------
0030  * A commercial use license is available from Mavimax, Ltd
0031  * contact@mavimax.com
0032  * -----------------------------------------------------------------------------
0033  */
0034 
0035 /*---------------------------Includes-----------------------------------*/
0036 #define __USE_POSIX_IMPLICITLY
0037 
0038 #include <ndrstandard.h>
0039 #include <time.h>
0040 #include <sys/time.h>
0041 #include <stdlib.h>
0042 #include <string.h>
0043 #include <stdio.h>
0044 #include <unistd.h>
0045 #include <nstdutil.h>
0046 #include <nclopt.h>
0047 #include <ndebug.h>
0048 
0049 #include <ubf.h>
0050 
0051 /*---------------------------Externs------------------------------------*/
0052 /*---------------------------Macros-------------------------------------*/
0053 /*---------------------------Enums--------------------------------------*/
0054 /*---------------------------Typedefs-----------------------------------*/
0055 /*---------------------------Globals------------------------------------*/
0056 /*---------------------------Statics------------------------------------*/
0057 /*---------------------------Prototypes---------------------------------*/
0058 
0059 /**
0060  * Parse command line options in standard way
0061  * @param opts - mapping list
0062  * @param print_values - should we print the values to debug?
0063  * @param argc - argument count
0064  * @param argv - argument list
0065  * @return SUCCEED/FAIL
0066  */
0067 expublic int nstd_parse_clopt(ncloptmap_t *opts, int print_values, 
0068         int argc, char **argv, int ignore_unk)
0069 {
0070     int ret = EXSUCCEED;
0071     char clopt_string[1024]={EXEOS};
0072     int len=0;
0073     unsigned char c; /* fix for rpi */
0074     int cc; /* fix for rpi */
0075     ncloptmap_t *p = opts;
0076 
0077     
0078     while (0!=p->key)
0079     {
0080         clopt_string[len]=p->key;
0081         p->have_loaded = EXFALSE;
0082         len++;
0083         if (p->flags & NCLOPT_HAVE_VALUE)
0084         {
0085             clopt_string[len]=':';
0086             len++;
0087         }
0088         clopt_string[len]=EXEOS;
0089         p++;
0090     }
0091     
0092     NDRX_LOG(log_debug, "clopt_string built: [%s] argc: [%d]", 
0093             clopt_string, argc);
0094     
0095 #ifdef __GNU_LIBRARY__
0096     optind=0; /* reset lib, so that we can scan again. */
0097 #else
0098     optind=1; /* reset lib, so that we can scan again. */
0099 #endif
0100     
0101     while ((cc = getopt(argc, argv, clopt_string)) != EXFAIL)
0102     {
0103         /* convert back char */
0104         c = (char)cc;
0105         
0106         /* search for key... */
0107         p = opts;
0108         while (0!=p->key)
0109         {
0110             if (p->key==c)
0111             {
0112                 break;
0113             }
0114             p++;
0115         }
0116         
0117         if (0==p->key)
0118         {
0119             if (!ignore_unk)
0120             {
0121                 NDRX_LOG(log_error, "Unknown command line option: [%c]", 
0122                         c);
0123                 EXFAIL_OUT(ret);
0124             }
0125             else
0126             {
0127                 continue;
0128             }
0129         }
0130         
0131         /* Translate the value */
0132         if (!(p->flags & NCLOPT_HAVE_VALUE))
0133         {
0134             short *val = (short *)p->ptr;
0135             *val = EXTRUE;
0136             NDRX_LOG(log_debug, "%c (%s) = [TRUE]", c, p->descr);
0137         }
0138         else
0139         {
0140             switch (p->datatype)
0141             {
0142                 case BFLD_SHORT:
0143                     {
0144                         short *val = (short *)p->ptr;
0145                         *val = (short) atoi(optarg);
0146                         if (print_values)
0147                         {
0148                             NDRX_LOG(log_debug, "%c (%s) = [%hd]", c, 
0149                                     p->descr, *val);
0150                         }
0151                     }
0152                     break;
0153                 case BFLD_LONG:
0154                     {
0155                         long *val = (long *)p->ptr;
0156                         *val = (long) atol(optarg);
0157                         if (print_values)
0158                         {
0159                             NDRX_LOG(log_debug, "%c (%s) = [%ld]", c, 
0160                                     p->descr, *val);
0161                         }
0162                     }
0163                     break;
0164                 case BFLD_CHAR:
0165                     {
0166                         char *val = (char *)p->ptr;
0167                         *val = optarg[0];
0168                         if (print_values)
0169                         {
0170                             NDRX_LOG(log_debug, "%c (%s) = [%c]", c, 
0171                                     p->descr, *val);
0172                         }
0173                     }
0174                     break;
0175                 case BFLD_FLOAT:
0176                     {
0177                         float *val = (float *)p->ptr;
0178                         *val = atof(optarg);
0179 
0180                         if (print_values)
0181                         {
0182                             NDRX_LOG(log_debug, "%c (%s) = [%f]", c, 
0183                                     p->descr, *val);
0184                         }
0185 
0186                     }
0187                     break;
0188                 case BFLD_DOUBLE:
0189                     {
0190                         double *val = (double *)p->ptr;
0191                         *val = atof(optarg);
0192                         if (print_values)
0193                         {
0194                             NDRX_LOG(log_debug, "%c (%s) = [%lf]", c, 
0195                                     p->descr, *val);
0196                         }
0197                     }
0198                     break;
0199                 case BFLD_STRING: 
0200                     {
0201                         int tmp = strlen(optarg);
0202                         if (tmp+1>p->buf_size)
0203                         {
0204                             NDRX_LOG(log_error, "Clopt [%c] invalid len: %d",
0205                                             c, tmp);
0206                             EXFAIL_OUT(ret);
0207                         }
0208                         strcpy((char *)p->ptr, optarg);
0209 
0210                         if (print_values)
0211                         {
0212                             NDRX_LOG(log_debug, "%c (%s) = [%s]", c, 
0213                                     p->descr, (char *)p->ptr);
0214                         }
0215                     }
0216                     break;
0217             }
0218         }
0219         
0220         p->have_loaded = EXTRUE;
0221     }
0222     
0223     /* Now cross check is all mandatory fields loaded... */
0224     p = opts;
0225     while (0!=p->key)
0226     {
0227         if (p->flags & NCLOPT_MAND && !p->have_loaded)
0228         {
0229             NDRX_LOG(log_error, "Missing command line option %c (%s)!",
0230                     p->key, p->descr);
0231             EXFAIL_OUT(ret);
0232         }
0233         
0234         p++;
0235     }
0236     
0237 out:
0238     return ret;
0239 }
0240 
0241 
0242 /* vim: set ts=4 sw=4 et smartindent: */