1 /* See LICENSE file for copyright and license details. */ 2 #include <errno.h> 3 #include <stdlib.h> 4 5 int tollu(const char *s, unsigned long long int min, unsigned long long int max, unsigned long long int *out); 6 int tolli(const char *s, long long int min, long long int max, long long int *out); 7 #define DEF_STR_TO_INT(FNAME, INTTYPE, INTER_FNAME, INTER_INTTYPE, PRI)\ 8 static inline int\ 9 FNAME(const char *s, INTTYPE min, INTTYPE max, INTTYPE *out)\ 10 {\ 11 INTER_INTTYPE inter;\ 12 if (INTER_FNAME(s, (INTER_INTTYPE)min, (INTER_INTTYPE)max, &inter))\ 13 return -1;\ 14 *out = (INTTYPE)inter;\ 15 return 0;\ 16 } 17 DEF_STR_TO_INT(tolu, unsigned long int, tollu, unsigned long long int, "lu") 18 DEF_STR_TO_INT(tou, unsigned int, tollu, unsigned long long int, "u") 19 DEF_STR_TO_INT(toli, long int, tolli, long long int, "li") 20 DEF_STR_TO_INT(toi, int, tolli, long long int, "i") 21 #undef DEF_STR_TO_INT 22 #define tozu tolu 23 #define tozi toli 24 #define toju tollu 25 #define toji tolli 26 27 #define DEF_STR_TO_INT(FNAME, TYPE, PRI)\ 28 static inline TYPE\ 29 en##FNAME##_flag(int status, int flag, const char *s, TYPE min, TYPE max)\ 30 {\ 31 TYPE ret = 0;\ 32 if (FNAME(s, min, max, &ret))\ 33 enprintf(status,\ 34 "argument of -%c must be an integer in [%"PRI", %"PRI"]\n",\ 35 flag, min, max);\ 36 return ret;\ 37 }\ 38 \ 39 static inline TYPE\ 40 e##FNAME##_flag(int flag, const char *s, TYPE min, TYPE max)\ 41 {\ 42 return en##FNAME##_flag(1, flag, s, min, max);\ 43 }\ 44 \ 45 static inline TYPE\ 46 en##FNAME##_arg(int status, const char *name, const char *s, TYPE min, TYPE max)\ 47 {\ 48 TYPE ret = 0;\ 49 if (FNAME(s, min, max, &ret))\ 50 enprintf(status,\ 51 "%s must be an integer in [%"PRI", %"PRI"]\n",\ 52 name, min, max);\ 53 return ret;\ 54 }\ 55 \ 56 static inline TYPE\ 57 e##FNAME##_arg(const char *name, const char *s, TYPE min, TYPE max)\ 58 {\ 59 return en##FNAME##_arg(1, name, s, min, max);\ 60 } 61 DEF_STR_TO_INT(tollu, unsigned long long int, "llu") 62 DEF_STR_TO_INT(tolu, unsigned long int, "lu") 63 DEF_STR_TO_INT(tou, unsigned int, "u") 64 DEF_STR_TO_INT(tolli, long long int, "lli") 65 DEF_STR_TO_INT(toli, long int, "li") 66 DEF_STR_TO_INT(toi, int, "i") 67 #undef DEF_STR_TO_INT 68 69 #define etozu_flag etolu_flag 70 #define etozi_flag etoli_flag 71 #define etoju_flag etollu_flag 72 #define etoji_flag etolli_flag 73 #define entozu_flag entolu_flag 74 #define entozi_flag entoli_flag 75 #define entoju_flag entollu_flag 76 #define entoji_flag entolli_flag 77 78 #define etozu_arg etolu_arg 79 #define etozi_arg etoli_arg 80 #define etoju_arg etollu_arg 81 #define etoji_arg etolli_arg 82 #define entozu_arg entolu_arg 83 #define entozi_arg entoli_arg 84 #define entoju_arg entollu_arg 85 #define entoji_arg entolli_arg 86 87 #define DEF_STR_TO_FLOAT(FNAME, TYPE, FUN)\ 88 static inline int\ 89 FNAME(const char *s, TYPE *out)\ 90 {\ 91 char *end;\ 92 errno = 0;\ 93 *out = FUN(s, &end);\ 94 if (errno) {\ 95 return -1;\ 96 } else if (*end) {\ 97 errno = EINVAL;\ 98 return -1;\ 99 }\ 100 return 0;\ 101 }\ 102 \ 103 static inline TYPE\ 104 en##FNAME##_flag(int status, int flag, const char *s)\ 105 {\ 106 TYPE ret = 0;\ 107 if (FNAME(s, &ret))\ 108 enprintf(status, "argument of -%c must be floating-point value\n", flag);\ 109 return ret;\ 110 }\ 111 \ 112 static inline TYPE\ 113 e##FNAME##_flag(int flag, const char *s)\ 114 {\ 115 return en##FNAME##_flag(1, flag, s);\ 116 }\ 117 \ 118 static inline TYPE\ 119 en##FNAME##_arg(int status, const char *name, const char *s)\ 120 {\ 121 TYPE ret = 0;\ 122 if (FNAME(s, &ret))\ 123 enprintf(status, "%s must be floating-point value\n", name);\ 124 return ret;\ 125 }\ 126 \ 127 static inline TYPE\ 128 e##FNAME##_arg(const char *name, const char *s)\ 129 {\ 130 return en##FNAME##_arg(1, name, s);\ 131 } 132 DEF_STR_TO_FLOAT(tof, float, strtof) 133 DEF_STR_TO_FLOAT(tolf, double, strtod) 134 DEF_STR_TO_FLOAT(tollf, long double, strtold) 135 #undef DEF_STR_TO_FLOAT 136