Branch data Line data Source code
1 : : /*
2 : : * SPDX-License-Identifier: MIT
3 : : * Copyright (c) 2024 IUPAC and InChI Trust
4 : : */
5 : :
6 : : /* djb-rwth: implementation of missing bounds - checking functions */
7 : :
8 : : #include <stdio.h>
9 : : #include <stdlib.h>
10 : : #include <string.h>
11 : : #include <errno.h>
12 : : #include "ichirvrs.h"
13 : : #include <math.h>
14 : : #include "bcf_s.h"
15 : :
16 : : #define STB_SPRINTF_IMPLEMENTATION
17 : : #include "stb_sprintf.h"
18 : :
19 : : static int dbl2int_f(double dblinp, int fwidth, int ndecpl, char* str);
20 : : static int dbl2int_e(double dblinp, int fwidth, int ndecpl, char* str);
21 : : static int dbl2int_g(double dblinp, int fwidth, int ndecpl, char* str);
22 : :
23 : 0 : int max_3(int a, int b, int c)
24 : : {
25 [ # # # # ]: 0 : if ((a > b) && (a > c))
26 : 0 : return a;
27 [ # # # # ]: 0 : else if ((b > a) && (b > c))
28 : 0 : return b;
29 : : else
30 : 0 : return c;
31 : : }
32 : :
33 : 0 : int memcpy_custom(char** dst, char* src, unsigned long long len)
34 : : {
35 : 0 : char* dst_local = (char*)calloc(len, sizeof(char));
36 : 0 : char* src_local = src;
37 : : int k;
38 : :
39 [ # # ]: 0 : if (dst_local)
40 : : {
41 : 0 : *dst = dst_local;
42 [ # # ]: 0 : for (k = 0; k < len; k++)
43 : : {
44 : 0 : dst_local[k] = src_local[k];
45 : : }
46 : : }
47 : : else
48 : : {
49 : 0 : free(dst_local);
50 : 0 : free(src_local);
51 : 0 : return RI_ERR_ALLOC;
52 : : }
53 : 0 : return 0;
54 : : }
55 : :
56 : : /* djb-rwth: main sprintf emulation for avoiding locales */
57 : 0 : int dbl2int(char* str, int fwidth, int ndecpl, char dbl_flag, double dblinp)
58 : : {
59 [ # # # # ]: 0 : switch (dbl_flag)
60 : : {
61 : 0 : case 'f':
62 : : case 'F':
63 : 0 : return dbl2int_f(dblinp, fwidth, ndecpl, str);
64 : : break;
65 : 0 : case 'e':
66 : : case 'E':
67 : 0 : return dbl2int_e(dblinp, fwidth, ndecpl, str);
68 : : break;
69 : 0 : case 'g':
70 : : case 'G':
71 : 0 : return dbl2int_g(dblinp, fwidth, ndecpl, str);
72 : : break;
73 : 0 : default:
74 : 0 : printf("dbl2int format flag not valid.\n");
75 : 0 : break;
76 : : }
77 : :
78 : 0 : return -1;
79 : : }
80 : :
81 : : /* djb-rwth: sprintf("%X.Yf", arg) emulation */
82 : 0 : static int dbl2int_f(double dblinp, int fwidth, int ndecpl, char* str)
83 : : {
84 : : double dec_part, dblinpabs;
85 : : char* intpl_str;
86 : : const char* dblinp_sign;
87 : 0 : int fw_int, fw_dec, i, fw_real, ret = 0;
88 : 0 : long long int intpl, decpl = 0, intpl_size;
89 : :
90 [ # # ]: 0 : dblinp_sign = (dblinp >= 0.0) ? "" : "-";
91 : 0 : dblinpabs = fabsl(dblinp);
92 : 0 : intpl = (long long int)trunc(dblinpabs);
93 : 0 : dec_part = dblinpabs - intpl;
94 [ # # ]: 0 : fw_int = (int)log10((double)intpl > 0 ? (double)intpl : 1.0) + 1 + !strcmp(dblinp_sign, "-");
95 : 0 : intpl_size = ((long long int)fw_int + 3) * sizeof(unsigned long long int);
96 : 0 : intpl_str = (char*)inchi_malloc(intpl_size);
97 : :
98 [ # # ]: 0 : if (ndecpl > 0)
99 : : {
100 : 0 : fw_dec = (ndecpl > 9) ? 9 : ndecpl;
101 : : }
102 [ # # ]: 0 : else if (ndecpl == 0)
103 : : {
104 : 0 : fw_dec = 0;
105 : : }
106 : : else
107 : : {
108 : 0 : fw_dec = 6;
109 : : }
110 : 0 : fw_real = fw_int + (ndecpl != 0) + fw_dec;
111 : :
112 [ # # ]: 0 : if (ndecpl)
113 : : {
114 : 0 : fw_int += (fwidth - fw_real > 0) ? fwidth - fw_real : 0;
115 : :
116 [ # # ]: 0 : for (i = 0; i < fw_dec; i++)
117 : : {
118 : 0 : dec_part *= 10;
119 : 0 : decpl = 10 * decpl + (long long int)dec_part;
120 : 0 : dec_part = dec_part - trunc(dec_part);
121 : : }
122 : :
123 : 0 : decpl += (long long int)round(dec_part);
124 [ # # # # ]: 0 : if (((int)log10((double)decpl > 0 ? (double)decpl : 1.0) + 1) > fw_dec)
125 : : {
126 : 0 : intpl++;
127 : 0 : decpl -= (int)pow(10, fw_dec);
128 : : }
129 : :
130 [ # # ]: 0 : if (intpl_str)
131 : : {
132 : 0 : sprintf(intpl_str, "%s%lld", dblinp_sign, intpl); /* djb-rwth: ignoring LLVM warning */
133 : : }
134 : : else
135 : : {
136 : 0 : return -1;
137 : : }
138 : :
139 : 0 : ret = sprintf(str, "%*s.%0*lld", fw_int, intpl_str, fw_dec, decpl); /* djb-rwth: ignoring LLVM warning */
140 [ # # ]: 0 : inchi_free(intpl_str);
141 : 0 : return ret;
142 : : }
143 : : else
144 : : {
145 : 0 : intpl = (long long int)round(dblinp);
146 : :
147 [ # # ]: 0 : inchi_free(intpl_str);
148 : 0 : return sprintf(str, "%*lld", fw_real, intpl); /* djb-rwth: ignoring LLVM warning */
149 : : }
150 : : }
151 : :
152 : : /* djb-rwth: sprintf("%X.Ye", arg) emulation */
153 : 0 : static int dbl2int_e(double dblinp, int fwidth, int ndecpl, char* str)
154 : : {
155 : : double dec_part, dblinpabs;
156 : 0 : int expnr = 0, fw_int, fw_dec, fw_real, dblinp_sign, nintpl, i, j;
157 : 0 : long long int intpl = 0, decpl = 0;
158 : :
159 [ # # ]: 0 : dblinp_sign = (dblinp >= 0.0) ? 1 : -1;
160 : 0 : dblinpabs = fabsl(dblinp);
161 : 0 : intpl = (long long int)trunc(dblinpabs);
162 [ # # ]: 0 : nintpl = (int)log10((double)intpl > 0 ? (double)intpl : 1) + 1;
163 : :
164 [ # # ]: 0 : if (nintpl > 1)
165 : : {
166 [ # # ]: 0 : for (j = 0; j < nintpl - 1; j++)
167 : : {
168 : 0 : dblinp /= 10.0;
169 : 0 : expnr++;
170 : : }
171 : : }
172 : : else
173 : : {
174 [ # # ]: 0 : if (dblinp)
175 : : {
176 [ # # ]: 0 : while (!trunc(dblinp))
177 : : {
178 : 0 : dblinp *= 10.0;
179 : 0 : expnr--;
180 : : }
181 : : }
182 : : }
183 : :
184 : 0 : dblinpabs = fabsl(dblinp);
185 : 0 : intpl = (long long int)trunc(dblinpabs);
186 : 0 : dec_part = dblinpabs - intpl;
187 [ # # ]: 0 : fw_int = (dblinp_sign < 0) + 1;
188 : :
189 [ # # ]: 0 : if (ndecpl > 0)
190 : : {
191 : 0 : fw_dec = (ndecpl > 9) ? 9 : ndecpl;
192 : : }
193 [ # # ]: 0 : else if (ndecpl == 0)
194 : : {
195 : 0 : fw_dec = 0;
196 : : }
197 : : else
198 : : {
199 : 0 : fw_dec = 6;
200 : : }
201 : 0 : fw_real = fw_int + (ndecpl != 0) + fw_dec + 4;
202 : :
203 [ # # ]: 0 : if (ndecpl)
204 : : {
205 : 0 : fw_int += (fwidth - fw_real > 0) ? fwidth - fw_real : 0;
206 : :
207 [ # # ]: 0 : for (i = 0; i < fw_dec; i++)
208 : : {
209 : 0 : dec_part *= 10;
210 : 0 : decpl = 10 * decpl + (int)dec_part;
211 : 0 : dec_part = dec_part - trunc(dec_part);
212 : : }
213 : :
214 : 0 : decpl += (long long int)round(dec_part);
215 [ # # # # ]: 0 : if (((int)log10((double)decpl > 0 ? (double)decpl : 1.0) + 1) > fw_dec)
216 : : {
217 : 0 : intpl++;
218 : 0 : decpl -= (int)pow(10, fw_dec);
219 : : }
220 : :
221 [ # # ]: 0 : nintpl = (int)log10((double)intpl > 0 ? (double)intpl : 1.0) + 1;
222 [ # # ]: 0 : if (nintpl > 1)
223 : : {
224 : 0 : intpl /= 10;
225 : 0 : expnr++;
226 : : }
227 : :
228 : 0 : intpl *= dblinp_sign;
229 : :
230 : 0 : return sprintf(str, "%*lld.%0*llde%+0*d", fw_int, intpl, fw_dec, decpl, 3, expnr); /* djb-rwth: ignoring LLVM warning */
231 : : }
232 : : else
233 : : {
234 : 0 : intpl = (int)round(dblinp);
235 : :
236 : 0 : return sprintf(str, "%*llde%+0*d", fw_real, intpl, 3, expnr); /* djb-rwth: ignoring LLVM warning */
237 : : }
238 : : }
239 : :
240 : : /* djb-rwth: sprintf("%X.Yg", arg) emulation */
241 : 0 : static int dbl2int_g(double dblinp, int fwidth, int ndecpl, char* str)
242 : : {
243 : 0 : double dec_part, dblinpabs, dblinpc = dblinp;
244 : : char* intpl_str;
245 : : const char* dblinp_signf;
246 : 0 : int expnr = 0, fw_int, fw_dec, fw_real, dblinp_signe, nintpl, i, j, ret = 0;
247 : 0 : long long int intpl = 0, decpl = 0, intpl_size;
248 : :
249 : 0 : dblinpabs = fabsl(dblinpc);
250 : 0 : intpl = (long long int)trunc(dblinpabs);
251 [ # # ]: 0 : nintpl = (int)log10((double)intpl > 0 ? (double)intpl : 1) + 1;
252 : :
253 [ # # ]: 0 : if (nintpl > 1)
254 : : {
255 [ # # ]: 0 : for (j = 0; j < nintpl - 1; j++)
256 : : {
257 : 0 : dblinpc /= 10.0;
258 : 0 : expnr++;
259 : : }
260 : : }
261 : : else
262 : : {
263 [ # # ]: 0 : if (dblinp)
264 : : {
265 [ # # ]: 0 : while (!trunc(dblinpc))
266 : : {
267 : 0 : dblinpc *= 10.0;
268 : 0 : expnr--;
269 : : }
270 : : }
271 : : }
272 : :
273 [ # # ]: 0 : if (ndecpl > 0)
274 : : {
275 : 0 : fw_dec = (ndecpl > 9) ? 9 : ndecpl;
276 : : }
277 [ # # ]: 0 : else if (ndecpl == 0)
278 : : {
279 : 0 : fw_dec = 1;
280 : : }
281 : : else
282 : : {
283 : 0 : fw_dec = 6;
284 : : }
285 : :
286 [ # # ]: 0 : if (!dblinpc)
287 : : {
288 : 0 : ret = sprintf(str, "%lld", intpl); /* djb-rwth: ignoring LLVM warning */
289 : 0 : return ret;
290 : : }
291 : :
292 [ # # # # ]: 0 : if ((fw_dec > expnr) && (expnr >= -4))
293 : : {
294 [ # # ]: 0 : dblinp_signf = (dblinp >= 0.0) ? "" : "-";
295 : 0 : dblinpabs = fabsl(dblinp);
296 : 0 : intpl = (long long int)trunc(dblinpabs);
297 : 0 : dec_part = dblinpabs - intpl;
298 [ # # ]: 0 : fw_int = (int)log10((double)intpl > 0 ? (double)intpl : 1.0) + 1 + !strcmp(dblinp_signf, "-");
299 : 0 : intpl_size = ((long long int)fw_int + 3) * sizeof(unsigned long long int);
300 : 0 : intpl_str = (char*)inchi_malloc(intpl_size);
301 : :
302 : 0 : fw_real = fw_int + (ndecpl != 0) + fw_dec;
303 : :
304 [ # # ]: 0 : if (fw_dec)
305 : : {
306 : 0 : fw_int += (fwidth - fw_real > 0) ? fwidth - fw_real : 0;
307 : :
308 [ # # ]: 0 : for (i = 0; i < fw_dec; i++)
309 : : {
310 : 0 : dec_part *= 10;
311 : 0 : decpl = 10 * decpl + (long long int)dec_part;
312 : 0 : dec_part -= trunc(dec_part);
313 : : }
314 : :
315 : 0 : decpl += (long long int)round(dec_part);
316 : :
317 [ # # # # ]: 0 : if (((int)log10((double)decpl > 0 ? (double)decpl : 1.0) + 1) > fw_dec)
318 : : {
319 : 0 : intpl++;
320 : 0 : decpl -= (int)pow(10, fw_dec);
321 : : }
322 : :
323 [ # # ]: 0 : if (decpl)
324 : : {
325 [ # # ]: 0 : while (!(decpl % 10))
326 : : {
327 : 0 : decpl /= 10;
328 : 0 : fw_dec--;
329 : : }
330 : : }
331 : :
332 [ # # ]: 0 : if (intpl_str)
333 : : {
334 [ # # ]: 0 : sprintf(intpl_str, "%s%lld", intpl ? dblinp_signf : "", intpl); /* djb-rwth: ignoring LLVM warning */
335 : : }
336 : : else
337 : : {
338 : 0 : return -1;
339 : : }
340 : :
341 [ # # ]: 0 : if (decpl)
342 : : {
343 : 0 : ret = sprintf(str, "%*s.%0*lld", fw_int, intpl_str, fw_dec, decpl); /* djb-rwth: ignoring LLVM warning */
344 [ # # ]: 0 : inchi_free(intpl_str);
345 : 0 : return ret;
346 : : }
347 : : else
348 : : {
349 : 0 : ret = sprintf(str, "%*s", fw_int, intpl_str); /* djb-rwth: ignoring LLVM warning */
350 [ # # ]: 0 : inchi_free(intpl_str);
351 : 0 : return ret;
352 : : }
353 : : }
354 : : else
355 : : { /* djb-rwth: addressing coverity ID #499558 -- currently leaving this as it is still a part of GHI #100 */
356 : 0 : intpl = (long long int)round(dblinp);
357 : 0 : ret = sprintf(str, "%*lld", fw_real, intpl); /* djb-rwth: ignoring LLVM warning */
358 : 0 : return ret;
359 : : }
360 : : }
361 : : else
362 : : {
363 [ # # ]: 0 : dblinp_signe = (dblinpc >= 0.0) ? 1 : -1;
364 : 0 : dblinpabs = fabsl(dblinpc);
365 : 0 : intpl = (long long int)trunc(dblinpabs);
366 : 0 : dec_part = dblinpabs - intpl;
367 [ # # ]: 0 : fw_int = (dblinp_signe < 0) + 1;
368 : :
369 : 0 : fw_real = fw_int + (ndecpl != 0) + fw_dec + 4;
370 : :
371 [ # # ]: 0 : if (ndecpl)
372 : : {
373 : 0 : fw_int += (fwidth - fw_real > 0) ? fwidth - fw_real : 0;
374 : :
375 [ # # ]: 0 : for (i = 0; i < fw_dec; i++)
376 : : {
377 : 0 : dec_part *= 10;
378 : 0 : decpl = 10 * decpl + (int)dec_part;
379 : 0 : dec_part = dec_part - trunc(dec_part);
380 : : }
381 : :
382 : 0 : decpl += (long long int)round(dec_part);
383 [ # # # # ]: 0 : if (((int)log10((double)decpl > 0 ? (double)decpl : 1.0) + 1) > fw_dec)
384 : : {
385 : 0 : intpl++;
386 : 0 : decpl -= (int)pow(10, fw_dec);
387 : : }
388 : :
389 [ # # ]: 0 : nintpl = (int)log10((double)intpl > 0 ? (double)intpl : 1.0) + 1;
390 [ # # ]: 0 : if (nintpl > 1)
391 : : {
392 : 0 : intpl /= 10;
393 : 0 : expnr++;
394 : : }
395 : :
396 : 0 : intpl *= dblinp_signe;
397 : 0 : ret = sprintf(str, "%*lld.%0*llde%+0*d", fw_int, intpl, fw_dec, decpl, 3, expnr); /* djb-rwth: ignoring LLVM warning */
398 : 0 : return ret;
399 : : }
400 : : else
401 : : {
402 : 0 : intpl = (int)round(dblinpc);
403 : 0 : ret = sprintf(str, "%*llde%+0*d", fw_real, intpl, 3, expnr); /* djb-rwth: ignoring LLVM warning */
404 : 0 : return ret;
405 : : }
406 : : }
407 : : }
|