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