1 /*@ ATOI and ITOA: simple non-restartable integer conversion.
2  *
3  * Copyright (c) 2017 - 2020 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
4  * SPDX-License-Identifier: ISC
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 #ifndef su_ICODEC_H
19 #define su_ICODEC_H
20 #include <su/code.h>
21 #define su_HEADER
22 #include <su/code-in.h>
23 C_DECL_BEGIN
24 enum su_idec_mode{
25    su_IDEC_MODE_NONE,
26    su_IDEC_MODE_SIGNED_TYPE = 1u<<0,
27    su_IDEC_MODE_POW2BASE_UNSIGNED = 1u<<1,
28    su_IDEC_MODE_BASE0_NUMBER_SIGN_RESCAN = 1u<<2,
29 #if 0
30    su_IDEC_MODE_SIGN_FORCE_SIGNED_TYPE = 1u<<2,
31 #endif
32    su_IDEC_MODE_LIMIT_8BIT = 1u<<3,
33    su_IDEC_MODE_LIMIT_16BIT = 2u<<3,
34    su_IDEC_MODE_LIMIT_32BIT = 3u<<3,
35    su__IDEC_MODE_LIMIT_MASK = 3u<<3,
36    su_IDEC_MODE_LIMIT_NOERROR = 1u<<5,
37    /* These bits are duplicated in the _state result bits! */
38    su__IDEC_MODE_MASK = (1u<<6) - 1
39 };
40 enum su_idec_state{
41    su_IDEC_STATE_NONE,
42    su_IDEC_STATE_EINVAL = 1u<<8,
43    su_IDEC_STATE_EBASE = 2u<<8,
44    su_IDEC_STATE_EOVERFLOW = 3u<<8,
45    su_IDEC_STATE_EMASK = 3u<<8,
46    su_IDEC_STATE_SEEN_MINUS = 1u<<16,
47    su_IDEC_STATE_CONSUMED = 1u<<17,
48    su__IDEC_PRIVATE_SHIFT1 = 24u
49 };
50 MCTA(su__IDEC_MODE_MASK <= (1u<<8) - 1, "Shared bit range overlaps")
51 EXPORT u32 su_idec(void *resp, char const *cbuf, uz clen, u8 base,
52       u32 idec_mode, char const **endptr_or_nil);
su_idec_cp(void * resp,char const * cp,u8 base,u32 idec_mode,char const ** endptr_or_nil)53 INLINE u32 su_idec_cp(void *resp, char const *cp, u8 base, u32 idec_mode,
54       char const **endptr_or_nil){
55    uz len = UZ_MAX;
56    ASSERT_EXEC(cp != NIL, len = 0);
57    return su_idec(resp, cp, len, base, idec_mode, endptr_or_nil);
58 }
59 #define su_idec_u8(RP,CBP,CL,B,CLP) \
60    su_idec(RP, CBP, CL, B, (su_IDEC_MODE_LIMIT_8BIT), CLP)
61 #define su_idec_u8_cp(RP,CBP,B,CLP) su_idec_u8(RP,CBP,su_UZ_MAX,B,CLP)
62 #define su_idec_s8(RP,CBP,CL,B,CLP) \
63    su_idec(RP, CBP, CL, B,\
64       (su_IDEC_MODE_SIGNED_TYPE | su_IDEC_MODE_LIMIT_8BIT), CLP)
65 #define su_idec_s8_cp(RP,CBP,B,CLP) su_idec_s8(RP,CBP,su_UZ_MAX,B,CLP)
66 #define su_idec_u16(RP,CBP,CL,B,CLP) \
67    su_idec(RP, CBP, CL, B, (su_IDEC_MODE_LIMIT_16BIT), CLP)
68 #define su_idec_u16_cp(RP,CBP,B,CLP) su_idec_u16(RP,CBP,su_UZ_MAX,B,CLP)
69 #define su_idec_s16(RP,CBP,CL,B,CLP) \
70    su_idec(RP, CBP, CL, B,\
71       (su_IDEC_MODE_SIGNED_TYPE | su_IDEC_MODE_LIMIT_16BIT), CLP)
72 #define su_idec_s16_cp(RP,CBP,B,CLP) su_idec_s16(RP,CBP,su_UZ_MAX,B,CLP)
73 #define su_idec_u32(RP,CBP,CL,B,CLP) \
74    su_idec(RP, CBP, CL, B, (su_IDEC_MODE_LIMIT_32BIT), CLP)
75 #define su_idec_u32_cp(RP,CBP,B,CLP) su_idec_u32(RP,CBP,su_UZ_MAX,B,CLP)
76 #define su_idec_s32(RP,CBP,CL,B,CLP) \
77    su_idec(RP, CBP, CL, B,\
78       (su_IDEC_MODE_SIGNED_TYPE | su_IDEC_MODE_LIMIT_32BIT), CLP)
79 #define su_idec_s32_cp(RP,CBP,B,CLP) su_idec_s32(RP,CBP,su_UZ_MAX,B,CLP)
80 #define su_idec_u64(RP,CBP,CL,B,CLP) su_idec(RP, CBP, CL, B, 0, CLP)
81 #define su_idec_u64_cp(RP,CBP,B,CLP) su_idec_u64(RP,CBP,su_UZ_MAX,B,CLP)
82 #define su_idec_s64(RP,CBP,CL,B,CLP) \
83    su_idec(RP, CBP, CL, B, (su_IDEC_MODE_SIGNED_TYPE), CLP)
84 #define su_idec_s64_cp(RP,CBP,B,CLP) su_idec_s64(RP,CBP,su_UZ_MAX,B,CLP)
85 #if UZ_BITS == 32
86 # define su_idec_uz(RP,CBP,CL,B,CLP) \
87    su_idec(RP, CBP, CL, B, (su_IDEC_MODE_LIMIT_32BIT), CLP)
88 # define su_idec_sz(RP,CBP,CL,B,CLP) \
89    su_idec(RP, CBP, CL, B,\
90       (su_IDEC_MODE_SIGNED_TYPE | su_IDEC_MODE_LIMIT_32BIT), CLP)
91 #else
92 # define su_idec_uz(RP,CBP,CL,B,CLP) su_idec(RP, CBP, CL, B, 0, CLP)
93 # define su_idec_sz(RP,CBP,CL,B,CLP) \
94    su_idec(RP, CBP, CL, B, (su_IDEC_MODE_SIGNED_TYPE), CLP)
95 #endif
96 #define su_idec_uz_cp(RP,CBP,B,CLP) su_idec_uz(RP,CBP,su_UZ_MAX,B,CLP)
97 #define su_idec_sz_cp(RP,CBP,B,CLP) su_idec_sz(RP,CBP,su_UZ_MAX,B,CLP)
98 #if UZ_BITS == 32
99 # define su_idec_up(RP,CBP,CL,B,CLP) \
100    su_idec(RP, CBP, CL, B, (su_IDEC_MODE_LIMIT_32BIT), CLP)
101 # define su_idec_sp(RP,CBP,CL,B,CLP) \
102    su_idec(RP, CBP, CL, B,\
103       (su_IDEC_MODE_SIGNED_TYPE | su_IDEC_MODE_LIMIT_32BIT), CLP)
104 #else
105 # define su_idec_up(RP,CBP,CL,B,CLP) su_idec(RP, CBP, CL, B, 0, CLP)
106 # define su_idec_sp(RP,CBP,CL,B,CLP) \
107    su_idec(RP, CBP, CL, B, (su_IDEC_MODE_SIGNED_TYPE), CLP)
108 #endif
109 #define su_idec_up_cp(RP,CBP,B,CLP) su_idec_up(RP,CBP,su_UZ_MAX,B,CLP)
110 #define su_idec_sp_cp(RP,CBP,B,CLP) su_idec_sp(RP,CBP,su_UZ_MAX,B,CLP)
111 enum{
112    su_IENC_BUFFER_SIZE = 80u
113 };
114 enum su_ienc_mode{
115    su_IENC_MODE_NONE,
116    su_IENC_MODE_SIGNED_TYPE = 1u<<1,
117    su_IENC_MODE_SIGNED_PLUS = 1u<<2,
118    su_IENC_MODE_SIGNED_SPACE = 1u<<3,
119    su_IENC_MODE_NO_PREFIX = 1u<<4,
120    su_IENC_MODE_LOWERCASE = 1u<<5,
121    su__IENC_MODE_SHIFT = 6u,
122    su__IENC_MODE_MASK = (1u<<su__IENC_MODE_SHIFT) - 1
123 };
124 EXPORT char *su_ienc(char cbuf[su_IENC_BUFFER_SIZE], u64 value, u8 base,
125       u32 ienc_mode);
126 #define su_ienc_u8(CBP,VAL,B) \
127    su_ienc(CBP, su_S(su_u8,VAL), B, su_IENC_MODE_NONE)
128 #define su_ienc_s8(CBP,VAL,B) \
129    su_ienc(CBP, su_S(su_s8,VAL), B, su_IENC_MODE_SIGNED_TYPE)
130 #define su_ienc_u16(CBP,VAL,B) \
131    su_ienc(CBP, su_S(su_u16,VAL), B, su_IENC_MODE_NONE)
132 #define su_ienc_s16(CBP,VAL,B) \
133    su_ienc(CBP, su_S(su_s16,VAL), B, su_IENC_MODE_SIGNED_TYPE)
134 #define su_ienc_u32(CBP,VAL,B) \
135    su_ienc(CBP, su_S(su_u32,VAL), B, su_IENC_MODE_NONE)
136 #define su_ienc_s32(CBP,VAL,B) \
137    su_ienc(CBP, su_S(su_s32,VAL), B, su_IENC_MODE_SIGNED_TYPE)
138 #define su_ienc_u64(CBP,VAL,B) \
139    su_ienc(CBP, su_S(su_u64,VAL), B, su_IENC_MODE_NONE)
140 #define su_ienc_s64(CBP,VAL,B) \
141    su_ienc(CBP, su_S(su_s64,VAL), B, su_IENC_MODE_SIGNED_TYPE)
142 #define su_ienc_uz(CBP,VAL,B) \
143    su_ienc(CBP, su_S(su_uz,VAL), B, su_IENC_MODE_NONE)
144 #define su_ienc_sz(CBP,VAL,B) \
145    su_ienc(CBP, su_S(su_sz,VAL), B, su_IENC_MODE_SIGNED_TYPE)
146 #define su_ienc_up(CBP,VAL,B) \
147    su_ienc(CBP, su_S(su_up,VAL), B, su_IENC_MODE_NONE)
148 #define su_ienc_sp(CBP,VAL,B) \
149    su_ienc(CBP, su_S(su_sp,VAL), B, su_IENC_MODE_SIGNED_TYPE)
150 C_DECL_END
151 #include <su/code-ou.h>
152 #endif /* su_ICODEC_H */
153 /* s-it-mode */
154