LCOV - code coverage report
Current view: top level - src - bcf_s.c (source / functions) Coverage Total Hit
Test: InChI Unit Test Coverage Lines: 0.0 % 192 0
Test Date: 2026-05-04 07:05:02 Functions: 0.0 % 6 0
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0.0 % 130 0

             Branch data     Line data    Source code
       1                 :             : /*
       2                 :             :  * International Chemical Identifier (InChI)
       3                 :             :  * Version 1
       4                 :             :  * Software version 1.07
       5                 :             :  * April 30, 2024
       6                 :             :  *
       7                 :             :  * MIT License
       8                 :             :  *
       9                 :             :  * Copyright (c) 2024 IUPAC and InChI Trust
      10                 :             :  *
      11                 :             :  * Permission is hereby granted, free of charge, to any person obtaining a copy
      12                 :             :  * of this software and associated documentation files (the "Software"), to deal
      13                 :             :  * in the Software without restriction, including without limitation the rights
      14                 :             :  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      15                 :             :  * copies of the Software, and to permit persons to whom the Software is
      16                 :             :  * furnished to do so, subject to the following conditions:
      17                 :             :  *
      18                 :             :  * The above copyright notice and this permission notice shall be included in all
      19                 :             :  * copies or substantial portions of the Software.
      20                 :             :  *
      21                 :             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      22                 :             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      24                 :             :  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      26                 :             :  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      27                 :             :  * SOFTWARE.
      28                 :             : *
      29                 :             : * The InChI library and programs are free software developed under the
      30                 :             :  * auspices of the International Union of Pure and Applied Chemistry (IUPAC).
      31                 :             :  * Originally developed at NIST.
      32                 :             :  * Modifications and additions by IUPAC and the InChI Trust.
      33                 :             :  * Some portions of code were developed/changed by external contributors
      34                 :             :  * (either contractor or volunteer) which are listed in the file
      35                 :             :  * 'External-contributors' included in this distribution.
      36                 :             :  *
      37                 :             :  * info@inchi-trust.org
      38                 :             :  *
      39                 :             : */
      40                 :             : 
      41                 :             : /* djb-rwth: implementation of missing bounds - checking functions */
      42                 :             : 
      43                 :             : #include <stdio.h>
      44                 :             : #include <stdlib.h>
      45                 :             : #include <string.h>
      46                 :             : #include <errno.h>
      47                 :             : #include "ichirvrs.h"
      48                 :             : #include <math.h>
      49                 :             : #include "bcf_s.h"
      50                 :             : 
      51                 :             : #define STB_SPRINTF_IMPLEMENTATION
      52                 :             : #include "stb_sprintf.h"
      53                 :             : 
      54                 :             : static int dbl2int_f(double dblinp, int fwidth, int ndecpl, char* str);
      55                 :             : static int dbl2int_e(double dblinp, int fwidth, int ndecpl, char* str);
      56                 :             : static int dbl2int_g(double dblinp, int fwidth, int ndecpl, char* str);
      57                 :             : 
      58                 :           0 : int max_3(int a, int b, int c)
      59                 :             : {
      60   [ #  #  #  # ]:           0 :     if ((a > b) && (a > c))
      61                 :           0 :         return a;
      62   [ #  #  #  # ]:           0 :     else if ((b > a) && (b > c))
      63                 :           0 :         return b;
      64                 :             :     else
      65                 :           0 :         return c;
      66                 :             : }
      67                 :             : 
      68                 :           0 : int memcpy_custom(char** dst, char* src, unsigned long long len)
      69                 :             : {
      70                 :           0 :     char* dst_local = (char*)calloc(len, sizeof(char));
      71                 :           0 :     char* src_local = src;
      72                 :             :     int k;
      73                 :             : 
      74         [ #  # ]:           0 :     if (dst_local)
      75                 :             :     {
      76                 :           0 :         *dst = dst_local;
      77         [ #  # ]:           0 :         for (k = 0; k < len; k++)
      78                 :             :         {
      79                 :           0 :             dst_local[k] = src_local[k];
      80                 :             :         }
      81                 :             :     }
      82                 :             :     else
      83                 :             :     {
      84                 :           0 :         free(dst_local);
      85                 :           0 :         free(src_local);
      86                 :           0 :         return RI_ERR_ALLOC;
      87                 :             :     }
      88                 :           0 :     return 0;
      89                 :             : }
      90                 :             : 
      91                 :             : /* djb-rwth: main sprintf emulation for avoiding locales */
      92                 :           0 : int dbl2int(char* str, int fwidth, int ndecpl, char dbl_flag, double dblinp)
      93                 :             : {
      94   [ #  #  #  # ]:           0 :         switch (dbl_flag)
      95                 :             :         {
      96                 :           0 :         case 'f':
      97                 :             :         case 'F':
      98                 :           0 :                 return dbl2int_f(dblinp, fwidth, ndecpl, str);
      99                 :             :                 break;
     100                 :           0 :         case 'e':
     101                 :             :         case 'E':
     102                 :           0 :                 return dbl2int_e(dblinp, fwidth, ndecpl, str);
     103                 :             :                 break;
     104                 :           0 :         case 'g':
     105                 :             :         case 'G':
     106                 :           0 :                 return dbl2int_g(dblinp, fwidth, ndecpl, str);
     107                 :             :                 break;
     108                 :           0 :         default:
     109                 :           0 :                 printf("dbl2int format flag not valid.\n");
     110                 :           0 :                 break;
     111                 :             :         }
     112                 :             : 
     113                 :           0 :         return -1;
     114                 :             : }
     115                 :             : 
     116                 :             : /* djb-rwth: sprintf("%X.Yf", arg) emulation */
     117                 :           0 : static int dbl2int_f(double dblinp, int fwidth, int ndecpl, char* str)
     118                 :             : {
     119                 :             :         double dec_part, dblinpabs;
     120                 :             :         char* intpl_str;
     121                 :             :         const char* dblinp_sign;
     122                 :           0 :         int fw_int, fw_dec, i, fw_real, ret = 0;
     123                 :           0 :         long long int intpl, decpl = 0, intpl_size;
     124                 :             : 
     125         [ #  # ]:           0 :         dblinp_sign = (dblinp >= 0.0) ? "" : "-";
     126                 :           0 :         dblinpabs = fabsl(dblinp);
     127                 :           0 :         intpl = (long long int)trunc(dblinpabs);
     128                 :           0 :         dec_part = dblinpabs - intpl;
     129         [ #  # ]:           0 :         fw_int = (int)log10((double)intpl > 0 ? (double)intpl : 1.0) + 1 + !strcmp(dblinp_sign, "-");
     130                 :           0 :         intpl_size = ((long long int)fw_int + 3) * sizeof(unsigned long long int);
     131                 :           0 :         intpl_str = (char*)inchi_malloc(intpl_size);
     132                 :             : 
     133         [ #  # ]:           0 :         if (ndecpl > 0)
     134                 :             :         {
     135                 :           0 :                 fw_dec = (ndecpl > 9) ? 9 : ndecpl;
     136                 :             :         }
     137         [ #  # ]:           0 :         else if (ndecpl == 0)
     138                 :             :         {
     139                 :           0 :                 fw_dec = 0;
     140                 :             :         }
     141                 :             :         else
     142                 :             :         {
     143                 :           0 :                 fw_dec = 6;
     144                 :             :         }
     145                 :           0 :         fw_real = fw_int + (ndecpl != 0) + fw_dec;
     146                 :             : 
     147         [ #  # ]:           0 :         if (ndecpl)
     148                 :             :         {
     149                 :           0 :                 fw_int += (fwidth - fw_real > 0) ? fwidth - fw_real : 0;
     150                 :             : 
     151         [ #  # ]:           0 :                 for (i = 0; i < fw_dec; i++)
     152                 :             :                 {
     153                 :           0 :                         dec_part *= 10;
     154                 :           0 :                         decpl = 10 * decpl + (long long int)dec_part;
     155                 :           0 :                         dec_part = dec_part - trunc(dec_part);
     156                 :             :                 }
     157                 :             : 
     158                 :           0 :                 decpl += (long long int)round(dec_part);
     159   [ #  #  #  # ]:           0 :                 if (((int)log10((double)decpl > 0 ? (double)decpl : 1.0) + 1) > fw_dec)
     160                 :             :                 {
     161                 :           0 :                         intpl++;
     162                 :           0 :                         decpl -= (int)pow(10, fw_dec);
     163                 :             :                 }
     164                 :             : 
     165         [ #  # ]:           0 :                 if (intpl_str)
     166                 :             :                 {
     167                 :           0 :                         sprintf(intpl_str, "%s%lld", dblinp_sign, intpl); /* djb-rwth: ignoring LLVM warning */
     168                 :             :                 }
     169                 :             :                 else
     170                 :             :                 {
     171                 :           0 :                         return -1;
     172                 :             :                 }
     173                 :             :                 
     174                 :           0 :                 ret = sprintf(str, "%*s.%0*lld", fw_int, intpl_str, fw_dec, decpl); /* djb-rwth: ignoring LLVM warning */
     175         [ #  # ]:           0 :                 inchi_free(intpl_str);
     176                 :           0 :                 return ret;
     177                 :             :         }
     178                 :             :         else
     179                 :             :         {
     180                 :           0 :                 intpl = (long long int)round(dblinp);
     181                 :             :                 
     182         [ #  # ]:           0 :                 inchi_free(intpl_str);
     183                 :           0 :                 return sprintf(str, "%*lld", fw_real, intpl); /* djb-rwth: ignoring LLVM warning */
     184                 :             :         }
     185                 :             : }
     186                 :             : 
     187                 :             : /* djb-rwth: sprintf("%X.Ye", arg) emulation */
     188                 :           0 : static int dbl2int_e(double dblinp, int fwidth, int ndecpl, char* str)
     189                 :             : {
     190                 :             :         double dec_part, dblinpabs;
     191                 :           0 :         int expnr = 0, fw_int, fw_dec, fw_real, dblinp_sign, nintpl, i, j;
     192                 :           0 :         long long int intpl = 0, decpl = 0;
     193                 :             : 
     194         [ #  # ]:           0 :         dblinp_sign = (dblinp >= 0.0) ? 1 : -1;
     195                 :           0 :         dblinpabs = fabsl(dblinp);
     196                 :           0 :         intpl = (long long int)trunc(dblinpabs);
     197         [ #  # ]:           0 :         nintpl = (int)log10((double)intpl > 0 ? (double)intpl : 1) + 1;
     198                 :             : 
     199         [ #  # ]:           0 :         if (nintpl > 1)
     200                 :             :         {
     201         [ #  # ]:           0 :                 for (j = 0; j < nintpl - 1; j++)
     202                 :             :                 {
     203                 :           0 :                         dblinp /= 10.0;
     204                 :           0 :                         expnr++;
     205                 :             :                 }
     206                 :             :         }
     207                 :             :         else
     208                 :             :         {
     209         [ #  # ]:           0 :                 if (dblinp)
     210                 :             :                 {
     211         [ #  # ]:           0 :                         while (!trunc(dblinp))
     212                 :             :                         {
     213                 :           0 :                                 dblinp *= 10.0;
     214                 :           0 :                                 expnr--;
     215                 :             :                         }
     216                 :             :                 }
     217                 :             :         }
     218                 :             : 
     219                 :           0 :         dblinpabs = fabsl(dblinp);
     220                 :           0 :         intpl = (long long int)trunc(dblinpabs);
     221                 :           0 :         dec_part = dblinpabs - intpl;
     222         [ #  # ]:           0 :         fw_int = (dblinp_sign < 0) + 1;
     223                 :             : 
     224         [ #  # ]:           0 :         if (ndecpl > 0)
     225                 :             :         {
     226                 :           0 :                 fw_dec = (ndecpl > 9) ? 9 : ndecpl;
     227                 :             :         }
     228         [ #  # ]:           0 :         else if (ndecpl == 0)
     229                 :             :         {
     230                 :           0 :                 fw_dec = 0;
     231                 :             :         }
     232                 :             :         else
     233                 :             :         {
     234                 :           0 :                 fw_dec = 6;
     235                 :             :         }
     236                 :           0 :         fw_real = fw_int + (ndecpl != 0) + fw_dec + 4;
     237                 :             : 
     238         [ #  # ]:           0 :         if (ndecpl)
     239                 :             :         {
     240                 :           0 :                 fw_int += (fwidth - fw_real > 0) ? fwidth - fw_real : 0;
     241                 :             : 
     242         [ #  # ]:           0 :                 for (i = 0; i < fw_dec; i++)
     243                 :             :                 {
     244                 :           0 :                         dec_part *= 10;
     245                 :           0 :                         decpl = 10 * decpl + (int)dec_part;
     246                 :           0 :                         dec_part = dec_part - trunc(dec_part);
     247                 :             :                 }
     248                 :             : 
     249                 :           0 :                 decpl += (long long int)round(dec_part);
     250   [ #  #  #  # ]:           0 :                 if (((int)log10((double)decpl > 0 ? (double)decpl : 1.0) + 1) > fw_dec)
     251                 :             :                 {
     252                 :           0 :                         intpl++;
     253                 :           0 :                         decpl -= (int)pow(10, fw_dec);
     254                 :             :                 }
     255                 :             : 
     256         [ #  # ]:           0 :                 nintpl = (int)log10((double)intpl > 0 ? (double)intpl : 1.0) + 1;
     257         [ #  # ]:           0 :                 if (nintpl > 1)
     258                 :             :                 {
     259                 :           0 :                         intpl /= 10;
     260                 :           0 :                         expnr++;
     261                 :             :                 }
     262                 :             : 
     263                 :           0 :                 intpl *= dblinp_sign;
     264                 :             : 
     265                 :           0 :                 return sprintf(str, "%*lld.%0*llde%+0*d", fw_int, intpl, fw_dec, decpl, 3, expnr); /* djb-rwth: ignoring LLVM warning */
     266                 :             :         }
     267                 :             :         else
     268                 :             :         {
     269                 :           0 :                 intpl = (int)round(dblinp);
     270                 :             : 
     271                 :           0 :                 return sprintf(str, "%*llde%+0*d", fw_real, intpl, 3, expnr); /* djb-rwth: ignoring LLVM warning */
     272                 :             :         }
     273                 :             : }
     274                 :             : 
     275                 :             : /* djb-rwth: sprintf("%X.Yg", arg) emulation */
     276                 :           0 : static int dbl2int_g(double dblinp, int fwidth, int ndecpl, char* str)
     277                 :             : {
     278                 :           0 :         double dec_part, dblinpabs, dblinpc = dblinp;
     279                 :             :         char* intpl_str;
     280                 :             :         const char* dblinp_signf;
     281                 :           0 :         int expnr = 0, fw_int, fw_dec, fw_real, dblinp_signe, nintpl, i, j, ret = 0;
     282                 :           0 :         long long int intpl = 0, decpl = 0, intpl_size;
     283                 :             : 
     284                 :           0 :         dblinpabs = fabsl(dblinpc);
     285                 :           0 :         intpl = (long long int)trunc(dblinpabs);
     286         [ #  # ]:           0 :         nintpl = (int)log10((double)intpl > 0 ? (double)intpl : 1) + 1;
     287                 :             : 
     288         [ #  # ]:           0 :         if (nintpl > 1)
     289                 :             :         {
     290         [ #  # ]:           0 :                 for (j = 0; j < nintpl - 1; j++)
     291                 :             :                 {
     292                 :           0 :                         dblinpc /= 10.0;
     293                 :           0 :                         expnr++;
     294                 :             :                 }
     295                 :             :         }
     296                 :             :         else
     297                 :             :         {
     298         [ #  # ]:           0 :                 if (dblinp)
     299                 :             :                 {
     300         [ #  # ]:           0 :                         while (!trunc(dblinpc))
     301                 :             :                         {
     302                 :           0 :                                 dblinpc *= 10.0;
     303                 :           0 :                                 expnr--;
     304                 :             :                         }
     305                 :             :                 }
     306                 :             :         }
     307                 :             : 
     308         [ #  # ]:           0 :         if (ndecpl > 0)
     309                 :             :         {
     310                 :           0 :                 fw_dec = (ndecpl > 9) ? 9 : ndecpl;
     311                 :             :         }
     312         [ #  # ]:           0 :         else if (ndecpl == 0)
     313                 :             :         {
     314                 :           0 :                 fw_dec = 1;
     315                 :             :         }
     316                 :             :         else
     317                 :             :         {
     318                 :           0 :                 fw_dec = 6;
     319                 :             :         }
     320                 :             : 
     321         [ #  # ]:           0 :         if (!dblinpc)
     322                 :             :         {
     323                 :           0 :                 ret = sprintf(str, "%lld", intpl); /* djb-rwth: ignoring LLVM warning */
     324                 :           0 :                 return ret;
     325                 :             :         }
     326                 :             : 
     327   [ #  #  #  # ]:           0 :         if ((fw_dec > expnr) && (expnr >= -4))
     328                 :             :         {
     329         [ #  # ]:           0 :                 dblinp_signf = (dblinp >= 0.0) ? "" : "-";
     330                 :           0 :                 dblinpabs = fabsl(dblinp);
     331                 :           0 :                 intpl = (long long int)trunc(dblinpabs);
     332                 :           0 :                 dec_part = dblinpabs - intpl;
     333         [ #  # ]:           0 :                 fw_int = (int)log10((double)intpl > 0 ? (double)intpl : 1.0) + 1 + !strcmp(dblinp_signf, "-");
     334                 :           0 :                 intpl_size = ((long long int)fw_int + 3) * sizeof(unsigned long long int);
     335                 :           0 :                 intpl_str = (char*)inchi_malloc(intpl_size);
     336                 :             : 
     337                 :           0 :                 fw_real = fw_int + (ndecpl != 0) + fw_dec;
     338                 :             : 
     339         [ #  # ]:           0 :                 if (fw_dec)
     340                 :             :                 {
     341                 :           0 :                         fw_int += (fwidth - fw_real > 0) ? fwidth - fw_real : 0;
     342                 :             : 
     343         [ #  # ]:           0 :                         for (i = 0; i < fw_dec; i++)
     344                 :             :                         {
     345                 :           0 :                                 dec_part *= 10;
     346                 :           0 :                                 decpl = 10 * decpl + (long long int)dec_part;
     347                 :           0 :                                 dec_part -= trunc(dec_part);
     348                 :             :                         }
     349                 :             : 
     350                 :           0 :                         decpl += (long long int)round(dec_part);
     351                 :             : 
     352   [ #  #  #  # ]:           0 :                         if (((int)log10((double)decpl > 0 ? (double)decpl : 1.0) + 1) > fw_dec)
     353                 :             :                         {
     354                 :           0 :                                 intpl++;
     355                 :           0 :                                 decpl -= (int)pow(10, fw_dec);
     356                 :             :                         }
     357                 :             : 
     358         [ #  # ]:           0 :                         if (decpl)
     359                 :             :                         {
     360         [ #  # ]:           0 :                                 while (!(decpl % 10))
     361                 :             :                                 {
     362                 :           0 :                                         decpl /= 10;
     363                 :           0 :                                         fw_dec--;
     364                 :             :                                 }
     365                 :             :                         }
     366                 :             : 
     367         [ #  # ]:           0 :                         if (intpl_str)
     368                 :             :                         {
     369         [ #  # ]:           0 :                                 sprintf(intpl_str, "%s%lld", intpl ? dblinp_signf : "", intpl); /* djb-rwth: ignoring LLVM warning */
     370                 :             :                         }
     371                 :             :                         else
     372                 :             :                         {
     373                 :           0 :                                 return -1;
     374                 :             :                         }
     375                 :             : 
     376         [ #  # ]:           0 :                         if (decpl)
     377                 :             :                         {
     378                 :           0 :                                 ret = sprintf(str, "%*s.%0*lld", fw_int, intpl_str, fw_dec, decpl); /* djb-rwth: ignoring LLVM warning */
     379         [ #  # ]:           0 :                                 inchi_free(intpl_str);
     380                 :           0 :                                 return ret;
     381                 :             :                         }
     382                 :             :                         else
     383                 :             :                         {
     384                 :           0 :                                 ret = sprintf(str,  "%*s", fw_int, intpl_str); /* djb-rwth: ignoring LLVM warning */
     385         [ #  # ]:           0 :                                 inchi_free(intpl_str);
     386                 :           0 :                                 return ret;
     387                 :             :                         }
     388                 :             :                 }
     389                 :             :                 else
     390                 :             :                 {       /* djb-rwth: addressing coverity ID #499558 -- currently leaving this as it is still a part of GHI #100 */
     391                 :           0 :                         intpl = (long long int)round(dblinp);
     392                 :           0 :                         ret = sprintf(str, "%*lld", fw_real, intpl); /* djb-rwth: ignoring LLVM warning */
     393                 :           0 :                         return ret;
     394                 :             :                 }
     395                 :             :         }
     396                 :             :         else
     397                 :             :         {
     398         [ #  # ]:           0 :                 dblinp_signe = (dblinpc >= 0.0) ? 1 : -1;
     399                 :           0 :                 dblinpabs = fabsl(dblinpc);
     400                 :           0 :                 intpl = (long long int)trunc(dblinpabs);
     401                 :           0 :                 dec_part = dblinpabs - intpl;
     402         [ #  # ]:           0 :                 fw_int = (dblinp_signe < 0) + 1;
     403                 :             : 
     404                 :           0 :                 fw_real = fw_int + (ndecpl != 0) + fw_dec + 4;
     405                 :             : 
     406         [ #  # ]:           0 :                 if (ndecpl)
     407                 :             :                 {
     408                 :           0 :                         fw_int += (fwidth - fw_real > 0) ? fwidth - fw_real : 0;
     409                 :             : 
     410         [ #  # ]:           0 :                         for (i = 0; i < fw_dec; i++)
     411                 :             :                         {
     412                 :           0 :                                 dec_part *= 10;
     413                 :           0 :                                 decpl = 10 * decpl + (int)dec_part;
     414                 :           0 :                                 dec_part = dec_part - trunc(dec_part);
     415                 :             :                         }
     416                 :             : 
     417                 :           0 :                         decpl += (long long int)round(dec_part);
     418   [ #  #  #  # ]:           0 :                         if (((int)log10((double)decpl > 0 ? (double)decpl : 1.0) + 1) > fw_dec)
     419                 :             :                         {
     420                 :           0 :                                 intpl++;
     421                 :           0 :                                 decpl -= (int)pow(10, fw_dec);
     422                 :             :                         }
     423                 :             : 
     424         [ #  # ]:           0 :                         nintpl = (int)log10((double)intpl > 0 ? (double)intpl : 1.0) + 1;
     425         [ #  # ]:           0 :                         if (nintpl > 1)
     426                 :             :                         {
     427                 :           0 :                                 intpl /= 10;
     428                 :           0 :                                 expnr++;
     429                 :             :                         }
     430                 :             : 
     431                 :           0 :                         intpl *= dblinp_signe;
     432                 :           0 :                         ret = sprintf(str, "%*lld.%0*llde%+0*d", fw_int, intpl, fw_dec, decpl, 3, expnr); /* djb-rwth: ignoring LLVM warning */
     433                 :           0 :                         return ret;
     434                 :             :                 }
     435                 :             :                 else
     436                 :             :                 {
     437                 :           0 :                         intpl = (int)round(dblinpc);
     438                 :           0 :                         ret = sprintf(str, "%*llde%+0*d", fw_real, intpl, 3, expnr); /* djb-rwth: ignoring LLVM warning */
     439                 :           0 :                         return ret;
     440                 :             :                 }
     441                 :             :         }
     442                 :             : }
        

Generated by: LCOV version 2.0-1