LCOV - code coverage report
Current view: top level - src - ichiprt3.c (source / functions) Coverage Total Hit
Test: InChI Unit Test Coverage Lines: 23.0 % 1572 362
Test Date: 2026-05-04 07:05:02 Functions: 38.5 % 26 10
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 8.3 % 3970 328

             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                 :             : #include <string.h>
      42                 :             : 
      43                 :             : #include "mode.h"
      44                 :             : #include "ichimain.h"
      45                 :             : #include "ichimake.h"
      46                 :             : #include "ichi_io.h"
      47                 :             : 
      48                 :             : #include "bcf_s.h"
      49                 :             : 
      50                 :             : /*
      51                 :             : 
      52                 :             : Generate substrings of whole-structure InChI/AuxInfo
      53                 :             : 
      54                 :             : */
      55                 :             : 
      56                 :             : 
      57                 :             : /****************************************************************************
      58                 :             :   Produce Hill formula substring of the whole structure InChI string
      59                 :             : ****************************************************************************/
      60                 :          54 : int str_HillFormula( INCHI_SORT       *pINChISort,
      61                 :             :                      INCHI_IOS_STRING *strbuf,
      62                 :             :                      int               *bOverflow,
      63                 :             :                      int               bOutType,
      64                 :             :                      int               num_components,
      65                 :             :                      int               bUseMulipliers )
      66                 :             : {
      67                 :             :     int          i, ii, nUsedLength0;
      68                 :             :     INCHI_SORT   *is, *is0;
      69                 :             :     INChI        *pINChI, *pINChI_Prev;
      70                 :             :     int          mult, eq2prev, bNext;
      71                 :             : 
      72                 :          54 :     nUsedLength0 = strbuf->nUsedLength;
      73                 :             : 
      74         [ -  + ]:          54 :     if (!( is0 = pINChISort ))
      75                 :             :     {
      76                 :           0 :         return nUsedLength0;
      77                 :             :     }
      78                 :          54 :     i = 0;
      79   [ -  +  -  -  :          54 :     pINChI_Prev = ( 0 <= ( ii = GET_II( bOutType, is0 ) ) ) ? is0->pINChI[ii] : NULL;
          -  -  -  -  -  
          -  -  -  -  -  
          +  -  +  -  +  
          -  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
                   +  - ]
      80                 :          54 :     mult = 0;
      81                 :          54 :     bNext = 0;
      82                 :             : 
      83                 :             :     /* For each connected component */
      84         [ +  + ]:         123 :     for (i++; i <= num_components; i++)
      85                 :             :     {
      86                 :             : 
      87                 :          84 :         pINChI = ( i < num_components &&
      88   [ -  +  -  -  :          15 :             ( is = is0 + i, 0 <= ( ii = GET_II( bOutType, is ) ) ) )
          -  -  -  -  -  
          -  -  -  -  -  
          +  -  +  -  +  
          -  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
                   +  - ]
      89                 :             :             ? is->pINChI[ii]
      90         [ +  + ]:          84 :             : NULL;
      91                 :             : 
      92         [ +  + ]:          69 :         eq2prev = bUseMulipliers &&
      93         [ +  - ]:          15 :             pINChI &&
      94                 :          15 :             pINChI_Prev &&
      95         [ +  - ]:          15 :             pINChI->szHillFormula &&
      96         [ +  - ]:          15 :             pINChI_Prev->szHillFormula &&
      97   [ +  -  +  - ]:         153 :             pINChI->szHillFormula[0] &&
      98         [ +  + ]:          15 :             !strcmp( pINChI_Prev->szHillFormula, pINChI->szHillFormula );
      99                 :             : 
     100         [ +  + ]:          69 :         if (eq2prev)
     101                 :             :         {
     102                 :           8 :             mult++; /* mult = (number of non-empty equal items)-1 */
     103                 :           8 :             continue;
     104                 :             :         }
     105                 :             :         else
     106                 :             :         {
     107                 :             :             int ok;
     108         [ +  + ]:          61 :             if (bNext++)
     109                 :             :             {
     110                 :           7 :                 MakeDelim( ".", strbuf, bOverflow );
     111                 :             :             }
     112                 :             : 
     113                 :         122 :             ok = pINChI_Prev &&
     114   [ +  -  +  - ]:         122 :                 pINChI_Prev->szHillFormula &&
     115         [ +  - ]:          61 :                 pINChI_Prev->szHillFormula[0];
     116                 :             : 
     117         [ +  - ]:          61 :             if (ok)
     118                 :             :             {
     119                 :          61 :                 MakeMult( mult + 1, "", strbuf, 0, bOverflow );
     120                 :          61 :                 MakeHillFormulaString( pINChI_Prev->szHillFormula,
     121                 :             :                     strbuf,
     122                 :             :                     bOverflow );
     123                 :             :             }
     124                 :             :         }
     125                 :          61 :         pINChI_Prev = pINChI;
     126                 :          61 :         mult = 0; /* we do not know whether the item is empty */
     127                 :             :     }
     128                 :             : 
     129                 :          54 :     return ( strbuf->nUsedLength - nUsedLength0 );
     130                 :             : }
     131                 :             : 
     132                 :             : 
     133                 :             : /****************************************************************************
     134                 :             :   Produce Hill formula substring of the whole structure InChI string:
     135                 :             :   2nd appearance (FixedH).
     136                 :             : ****************************************************************************/
     137                 :           0 : int str_HillFormula2( INCHI_SORT       *pINChISort,     /* non-taut */
     138                 :             :                       INCHI_SORT       *pINChISort2,    /* taut     */
     139                 :             :                       INCHI_IOS_STRING *strbuf,
     140                 :             :                       int              *bOverflow,
     141                 :             :                       int              bOutType,
     142                 :             :                       int              num_components,
     143                 :             :                       int              bUseMulipliers )
     144                 :             : {
     145                 :             :     int          i, ii, ii2, nUsedLength0;
     146                 :             :     INCHI_SORT   *is, *is2, *is0, *is20;
     147                 :             :     INChI        *pINChI, *pINChI_Prev, *pINChI_Taut, *pINChI_Taut_Prev;
     148                 :             :     int          mult, eq2prev, bNext, bEqToTaut;
     149                 :             : 
     150                 :           0 :     is = NULL;
     151                 :           0 :     is2 = NULL;
     152                 :           0 :     is0 = pINChISort;
     153                 :           0 :     is20 = pINChISort2;
     154                 :           0 :     i = 0;
     155                 :           0 :     nUsedLength0 = strbuf->nUsedLength;
     156                 :             : 
     157   [ #  #  #  #  :           0 :     pINChI_Prev = ( 0 <= ( ii = GET_II( bOutType, is0 ) ) ) ? is0->pINChI[ii] : NULL;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     158   [ #  #  #  #  :           0 :     pINChI_Taut_Prev = ( 0 <= ( ii2 = GET_II( OUT_T1, is20 ) ) ) ? is20->pINChI[ii2] : NULL;
          #  #  #  #  #  
                      # ]
     159                 :           0 :     mult = 0;
     160                 :           0 :     bNext = 0;
     161                 :           0 :     bEqToTaut = 1;
     162         [ #  # ]:           0 :     bEqToTaut = bEqToTaut                 &&
     163         [ #  # ]:           0 :         pINChI_Prev                       &&
     164                 :           0 :         pINChI_Taut_Prev &&
     165         [ #  # ]:           0 :         !pINChI_Taut_Prev->bDeleted       &&
     166         [ #  # ]:           0 :         pINChI_Prev->szHillFormula        &&
     167   [ #  #  #  # ]:           0 :         pINChI_Taut_Prev->szHillFormula   &&
     168         [ #  # ]:           0 :         !strcmp( pINChI_Prev->szHillFormula, pINChI_Taut_Prev->szHillFormula );
     169                 :             : 
     170                 :             :     /* For each connected component    */
     171         [ #  # ]:           0 :     for (i++; i <= num_components; i++)
     172                 :             :     {
     173   [ #  #  #  #  :           0 :         pINChI = ( i < num_components && ( is = is0 + i, 0 <= ( ii = GET_II( bOutType, is ) ) ) ) ? is->pINChI[ii] : NULL;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     174   [ #  #  #  #  :           0 :         pINChI_Taut = ( i < num_components && ( is2 = is20 + i, 0 <= ( ii2 = GET_II( OUT_T1, is2 ) ) ) ) ? is2->pINChI[ii2] : NULL;
          #  #  #  #  #  
                #  #  # ]
     175   [ #  #  #  #  :           0 :         if (bEqToTaut && ( pINChI || pINChI_Taut ))
                   #  # ]
     176                 :             :         {
     177   [ #  #  #  # ]:           0 :             bEqToTaut = pINChI && pINChI_Taut && !pINChI_Taut->bDeleted &&
     178   [ #  #  #  #  :           0 :                 pINChI->szHillFormula && pINChI_Taut->szHillFormula     &&
                   #  # ]
     179         [ #  # ]:           0 :                 !strcmp( pINChI->szHillFormula, pINChI_Taut->szHillFormula );
     180                 :             :         }
     181                 :             : 
     182         [ #  # ]:           0 :         eq2prev = bUseMulipliers        &&
     183         [ #  # ]:           0 :             pINChI && pINChI_Prev       &&
     184         [ #  # ]:           0 :             pINChI->szHillFormula       &&
     185         [ #  # ]:           0 :             pINChI_Prev->szHillFormula  &&
     186   [ #  #  #  # ]:           0 :             pINChI->szHillFormula[0]    &&
     187         [ #  # ]:           0 :             !strcmp( pINChI_Prev->szHillFormula, pINChI->szHillFormula );
     188                 :             : 
     189         [ #  # ]:           0 :         if (eq2prev)
     190                 :             :         {
     191                 :           0 :             mult++; /* mult = (number of non-empty equal items)-1 */
     192                 :           0 :             continue;
     193                 :             :         }
     194                 :             :         else
     195                 :             :         {
     196         [ #  # ]:           0 :             if (bNext++)
     197                 :             :             {
     198                 :           0 :                 MakeDelim( ".", strbuf, bOverflow );
     199                 :             :             }
     200   [ #  #  #  #  :           0 :             if (pINChI_Prev && pINChI_Prev->szHillFormula && pINChI_Prev->szHillFormula[0])
                   #  # ]
     201                 :             :             {
     202                 :           0 :                 MakeMult( mult + 1, "", strbuf, 0, bOverflow );
     203                 :           0 :                 MakeHillFormulaString( pINChI_Prev->szHillFormula, strbuf, bOverflow );
     204                 :             :             }
     205                 :             :         }
     206                 :           0 :         pINChI_Prev = pINChI;
     207                 :           0 :         mult = 0; /* we do not know whether the item is empty */
     208                 :             :     }
     209                 :             : 
     210         [ #  # ]:           0 :     if (bEqToTaut)
     211                 :           0 :         strbuf->nUsedLength = nUsedLength0;
     212                 :             : 
     213                 :             :     {
     214                 :           0 :         strbuf->pStr[strbuf->nUsedLength] = '\0';
     215                 :             :     }
     216                 :             : 
     217                 :           0 :     return ( strbuf->nUsedLength - nUsedLength0 );
     218                 :             : }
     219                 :             : 
     220                 :             : 
     221                 :             : /****************************************************************************
     222                 :             :   Produce connections substring of InChI string for the whole structure
     223                 :             : ****************************************************************************/
     224                 :          54 : int str_Connections( CANON_GLOBALS    *pCG,
     225                 :             :                      INCHI_SORT       *pINChISort,
     226                 :             :                      INCHI_IOS_STRING *strbuf,
     227                 :             :                      int              *bOverflow,
     228                 :             :                      int              bOutType,
     229                 :             :                      int              ATOM_MODE,
     230                 :             :                      int              num_components,
     231                 :             :                      int              bUseMulipliers )
     232                 :             : {
     233                 :             :     int          i, ii, nUsedLength0;
     234                 :             :     INCHI_SORT   *is, *is0;
     235                 :             :     INChI        *pINChI, *pINChI_Prev;
     236                 :             :     int          mult, eq2prev, bNext, nNumEmpty;
     237                 :             : 
     238                 :          54 :     nUsedLength0 = strbuf->nUsedLength;
     239         [ -  + ]:          54 :     if (!( is0 = pINChISort ))
     240                 :             :     {
     241                 :           0 :         return nUsedLength0;
     242                 :             :     }
     243                 :          54 :     i = 0;
     244   [ -  +  -  -  :          54 :     pINChI_Prev = ( 0 <= ( ii = GET_II( bOutType, is0 ) ) ) ? is0->pINChI[ii] : NULL;
          -  -  -  -  -  
          -  -  -  -  -  
          +  -  +  -  +  
          -  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
                   +  - ]
     245                 :          54 :     is = NULL;
     246                 :          54 :     mult = 0;
     247                 :          54 :     bNext = 0;
     248                 :          54 :     nNumEmpty = 0;
     249                 :             : 
     250                 :             :     /* For each connected component...    */
     251         [ +  + ]:         123 :     for (i++; i <= num_components; i++)
     252                 :             :     {
     253   [ +  +  -  +  :          69 :         pINChI = ( i < num_components && ( is = is0 + i, 0 <= ( ii = GET_II( bOutType, is ) ) ) ) ? is->pINChI[ii] : NULL;
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  +  
          -  +  -  -  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
             -  -  +  - ]
     254         [ +  + ]:          69 :         eq2prev = bUseMulipliers                                &&
     255   [ +  -  +  + ]:          15 :             pINChI && pINChI_Prev && pINChI->lenConnTable > 1   &&
     256   [ +  -  +  + ]:         144 :             pINChI_Prev->lenConnTable == pINChI->lenConnTable   &&
     257                 :           6 :             !memcmp( pINChI_Prev->nConnTable, pINChI->nConnTable,
     258         [ +  - ]:           6 :                 pINChI_Prev->lenConnTable * sizeof( pINChI->nConnTable[0] ) );
     259         [ +  + ]:          69 :         if (eq2prev)
     260                 :             :         {
     261                 :           6 :             mult++; /* mult = (number of non-empty equal items)-1 */
     262                 :           6 :             continue;
     263                 :             :         }
     264                 :             :         else
     265                 :             :         {
     266         [ +  - ]:          63 :             if (pINChI_Prev)
     267                 :             :             {
     268         [ +  + ]:          63 :                 if (bNext++)
     269                 :             :                 {
     270                 :           9 :                     MakeDelim( sCompDelim, strbuf, bOverflow );
     271                 :             :                 }
     272   [ +  -  +  + ]:          63 :                 if (pINChI_Prev && pINChI_Prev->lenConnTable > 1)
     273                 :             :                 {
     274                 :          58 :                     MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
     275                 :          58 :                     MakeCtStringNew( pCG, pINChI_Prev->nConnTable,
     276                 :             :                         pINChI_Prev->lenConnTable,
     277                 :             :                         0, NULL,
     278                 :             :                         pINChI_Prev->nNumberOfAtoms,
     279                 :             :                         strbuf, ATOM_MODE, bOverflow );
     280                 :             :                 }
     281                 :             :                 else
     282                 :             :                 {
     283                 :           5 :                     nNumEmpty++;
     284                 :             :                 }
     285                 :             :             }
     286                 :             :         }
     287                 :          63 :         pINChI_Prev = pINChI;
     288                 :          63 :         mult = 0; /* we do not know whether the item is empty */
     289                 :             :     }
     290   [ +  +  +  - ]:          54 :     if (nNumEmpty == num_components && strbuf->nUsedLength > nUsedLength0)
     291                 :             :     {
     292                 :           1 :         strbuf->nUsedLength = nUsedLength0;
     293                 :           1 :         strbuf->pStr[strbuf->nUsedLength] = '\0';
     294                 :             :     }
     295                 :             :     /*
     296                 :             :     if ( nNumEmpty == num_components && tot_len > tot_len_inp ) {
     297                 :             :     tot_len = tot_len_inp;
     298                 :             :     strbuf->pStr[tot_len] = '\0';
     299                 :             :     }
     300                 :             :     */
     301                 :             : 
     302                 :          54 :     return ( strbuf->nUsedLength - nUsedLength0 );
     303                 :             : }
     304                 :             : 
     305                 :             : 
     306                 :             : /****************************************************************************
     307                 :             :   Produce H[ydrogens] substring of the whole structure InChI string
     308                 :             : ****************************************************************************/
     309                 :          51 : int str_H_atoms( INCHI_SORT       *pINChISort,
     310                 :             :                  INCHI_IOS_STRING *strbuf,
     311                 :             :                  int               *bOverflow,
     312                 :             :                  int               bOutType,
     313                 :             :                  int               ATOM_MODE,
     314                 :             :                  int               TAUT_MODE,
     315                 :             :                  int               num_components,
     316                 :             :                  int               bUseMulipliers )
     317                 :             : {
     318                 :             :     int          i, j, ii, len_H, nUsedLength0;
     319                 :             :     INCHI_SORT   *is, *is0;
     320                 :             :     INChI        *pINChI, *pINChI_Prev;
     321                 :             :     int          mult, eq2prev, bNext, bNotEmpty, nNumEmpty;
     322                 :             : 
     323                 :          51 :     nNumEmpty = 0;
     324                 :          51 :     is0 = pINChISort;
     325                 :          51 :     is = NULL;
     326                 :          51 :     i = 0;
     327   [ -  +  -  -  :          51 :     pINChI_Prev = ( 0 <= ( ii = GET_II( bOutType, is0 ) ) ) ? is0->pINChI[ii] : NULL;
          -  -  -  -  -  
          -  -  -  -  -  
          +  -  +  -  +  
          -  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
                   +  - ]
     328                 :          51 :     mult = 0;
     329                 :          51 :     bNext = 0;
     330                 :          51 :     nUsedLength0 = strbuf->nUsedLength;
     331                 :             : 
     332                 :             :     /* For each connected component...    */
     333         [ +  + ]:         117 :     for (i++; i <= num_components; i++)
     334                 :             :     {
     335                 :             : 
     336   [ +  +  -  +  :          66 :         pINChI = ( i < num_components && ( is = is0 + i, 0 <= ( ii = GET_II( bOutType, is ) ) ) ) ? is->pINChI[ii] : NULL;
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  +  
          -  +  -  -  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
             -  -  +  - ]
     337                 :             :         /*========== compare to previous ============*/
     338         [ +  + ]:          66 :         eq2prev = bUseMulipliers &&
     339   [ +  -  -  +  :          15 :             pINChI && pINChI_Prev && ( pINChI->nNumberOfAtoms > 0 || pINChI->lenTautomer > 1 ) &&
                   -  - ]
     340         [ +  + ]:          15 :             pINChI_Prev->nNumberOfAtoms == pINChI->nNumberOfAtoms &&
     341         [ +  - ]:           9 :             ( !pINChI_Prev->nNumberOfAtoms || !memcmp( pINChI_Prev->nNum_H, pINChI->nNum_H,
     342   [ +  -  +  +  :         140 :                 pINChI_Prev->nNumberOfAtoms * sizeof( pINChI->nNum_H[0] ) ) ) &&
                   +  - ]
     343                 :           8 :             !CompareTautNonIsoPartOfINChI( pINChI_Prev, pINChI );
     344                 :             : 
     345   [ +  +  +  - ]:          66 :         if (eq2prev && pINChI_Prev->lenTautomer <= 1)
     346                 :             :         {
     347                 :             :             /* make sure it is not empty */
     348                 :           8 :             eq2prev = 0;
     349         [ +  - ]:           8 :             for (j = 0; j < pINChI_Prev->nNumberOfAtoms; j++)
     350                 :             :             {
     351         [ +  - ]:           8 :                 if (pINChI_Prev->nNum_H[j])
     352                 :             :                 {
     353                 :           8 :                     eq2prev = 1;
     354                 :           8 :                     break;
     355                 :             :                 }
     356                 :             :             }
     357                 :             :         }
     358         [ +  + ]:          66 :         if (eq2prev)
     359                 :             :         {
     360                 :           8 :             mult++; /* mult = (number of non-empty equal items)-1 */
     361                 :           8 :             continue;
     362                 :             :         }
     363                 :             :         else
     364                 :             :         {
     365         [ +  - ]:          58 :             if (pINChI_Prev)
     366                 :             :             {
     367                 :             :                 /* delimiter */
     368         [ +  + ]:          58 :                 if (bNext++)
     369                 :             :                 {
     370                 :           7 :                     MakeDelim( sCompDelim, strbuf, bOverflow );
     371                 :             :                 }
     372                 :             :                 /* verify non-empty */
     373                 :          58 :                 bNotEmpty = 0;
     374         [ +  - ]:          58 :                 if (pINChI_Prev)
     375                 :             :                 {
     376                 :          58 :                     bNotEmpty = ( pINChI_Prev->lenTautomer > 1 );
     377         [ +  - ]:          58 :                     if (!bNotEmpty)
     378                 :             :                     {
     379         [ +  + ]:          60 :                         for (j = 0; j < pINChI_Prev->nNumberOfAtoms; j++)
     380                 :             :                         {
     381         [ +  + ]:          58 :                             if (pINChI_Prev->nNum_H[j])
     382                 :             :                             {
     383                 :          56 :                                 bNotEmpty = 1;
     384                 :          56 :                                 break;
     385                 :             :                             }
     386                 :             :                         }
     387                 :             :                     }
     388                 :             :                 }
     389         [ +  + ]:          58 :                 if (bNotEmpty)
     390                 :             :                 {
     391                 :          56 :                     MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
     392                 :             :                     /* H-atoms */
     393                 :          56 :                     len_H = MakeHString( 0, pINChI_Prev->nNum_H, pINChI_Prev->nNumberOfAtoms,
     394                 :             :                         strbuf, ATOM_MODE, bOverflow );
     395                 :             :                     /*  tautomeric groups */
     396                 :          56 :                     MakeTautString( pINChI_Prev->nTautomer, pINChI_Prev->lenTautomer, ( 0 != len_H ),
     397                 :             :                         strbuf, TAUT_MODE, bOverflow );
     398                 :             :                 }
     399                 :             :                 else
     400                 :             :                 {
     401                 :           2 :                     nNumEmpty++;
     402                 :             :                 }
     403                 :             :             }
     404                 :             :         }
     405                 :          58 :         pINChI_Prev = pINChI;
     406                 :          58 :         mult = 0; /* we do not know whether the item is empty */
     407                 :             :     }
     408   [ -  +  -  - ]:          51 :     if (nNumEmpty == num_components && strbuf->nUsedLength > nUsedLength0)
     409                 :             :     {
     410                 :           0 :         strbuf->nUsedLength = nUsedLength0;
     411                 :           0 :         strbuf->pStr[nUsedLength0] = '\0';
     412                 :             :     }
     413                 :             :     /*
     414                 :             :     if ( nNumEmpty == num_components && tot_len > tot_len_inp ) {
     415                 :             :     tot_len = tot_len_inp;
     416                 :             :     strbuf->pStr[tot_len] = '\0';
     417                 :             :     }
     418                 :             :     */
     419                 :             : 
     420                 :          51 :     return ( strbuf->nUsedLength - nUsedLength0 );
     421                 :             : }
     422                 :             : 
     423                 :             : 
     424                 :             : /****************************************************************************
     425                 :             :     Produce charge substring of the whole structure InChI string
     426                 :             : ****************************************************************************/
     427                 :           3 : int str_Charge2( INCHI_SORT       *pINChISort,
     428                 :             :                  INCHI_SORT       *pINChISort2,
     429                 :             :                  INCHI_IOS_STRING *strbuf,
     430                 :             :                  int              *bOverflow,
     431                 :             :                  int              bOutType,
     432                 :             :                  int              num_components,
     433                 :             :                  int              bSecondNonTautPass,
     434                 :             :                  int              bOmitRepetitions,
     435                 :             :                  int              bUseMulipliers )
     436                 :             : {
     437                 :             :     int          i, ii, ii2, nUsedLength0;
     438                 :             :     INCHI_SORT   *is, *is2, *is0, *is20;
     439                 :             :     INChI        *pINChI, *pINChI_Prev, *pINChI_Taut, *pINChI_Taut_Prev;
     440                 :             :     int         nTotalCharge, nTotalCharge_Prev, nTotalCharge_Taut; /* djb-rwth: removing redundant variables */
     441                 :             :     int          mult, eq2prev, eq2taut, eq2tautPrev, bNext;
     442                 :             :     const char  *pPrevEquStr, *pCurrEquStr;
     443                 :             :     int         multPrevEquStr;
     444                 :           3 :     pINChI_Taut = NULL;
     445                 :           3 :     pINChI_Prev = NULL;
     446                 :           3 :     pINChI_Taut_Prev = NULL;
     447                 :           3 :     mult = 0;
     448                 :           3 :     bNext = 0;
     449                 :           3 :     is = NULL;
     450                 :           3 :     is2 = NULL;
     451                 :           3 :     is0 = pINChISort;
     452         [ -  + ]:           3 :     is20 = bSecondNonTautPass ? pINChISort2 : NULL;
     453                 :             :     /* djb-rwth: removing redundant code */
     454                 :           3 :     eq2tautPrev = 1; /* pINChI_Prev (previous pINChI) does not exist */
     455                 :           3 :     pPrevEquStr = NULL; /*, *pCurrEquStr;*/
     456                 :           3 :     multPrevEquStr = 0;
     457                 :           3 :     nUsedLength0 = strbuf->nUsedLength;
     458                 :             : 
     459                 :             :     /* For each connected component...    */
     460         [ +  + ]:          14 :     for (i = 0; i <= num_components; i++)
     461                 :             :     {
     462                 :             : 
     463                 :             :         /* 1st (taut) pass: bOutType=OUT_TN  ; 2nd (non-taut pass) bOutType=OUT_NT */
     464   [ +  +  -  +  :          11 :         pINChI = ( i < num_components && ( is = is0 + i, 0 <= ( ii = GET_II( bOutType, is ) ) ) ) ? is->pINChI[ii] : NULL;
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  +  
          -  +  -  -  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
             -  -  +  - ]
     465                 :             :         /*================ compare sp3 to previous =====================*/
     466         [ -  + ]:          11 :         if (bSecondNonTautPass)
     467                 :             :         {
     468                 :             :             /* component that was output on the 1st pass */
     469   [ #  #  #  #  :           0 :             pINChI_Taut = ( i < num_components && ( is2 = is20 + i, 0 <= ( ii2 = GET_II( OUT_T1, is2 ) ) ) ) ? is2->pINChI[ii2] : NULL;
          #  #  #  #  #  
                #  #  # ]
     470                 :             :         }
     471                 :             :         /*========= if bSecondNonTautPass then compare non-iso non-taut stereo to non-iso taut ========*/
     472                 :          11 :         eq2taut = 0;
     473   [ +  -  -  +  :          11 :         if (!eq2taut && bSecondNonTautPass && bOmitRepetitions)
                   -  - ]
     474                 :             :         {
     475   [ #  #  #  # ]:           0 :             eq2taut = pINChI && pINChI_Taut && !pINChI_Taut->bDeleted &&
     476   [ #  #  #  #  :           0 :                 ( nTotalCharge = pINChI->nTotalCharge ) && ( nTotalCharge_Taut = pINChI_Taut->nTotalCharge ) &&
             #  #  #  # ]
     477                 :             :                 nTotalCharge == nTotalCharge_Taut;
     478         [ #  # ]:           0 :             eq2taut = eq2taut ? ( iiEQU | iitNONTAUT ) : 0;
     479                 :             :         }
     480         [ -  + ]:          11 :         if (eq2taut)
     481                 :             :         {
     482                 :             :             /* we may be here only in case of the second (non-taut) pass */
     483                 :             :             /* current non-taut stereo has been found to be same as tautomeric */
     484   [ #  #  #  # ]:           0 :             if (pINChI_Prev && pINChI_Prev->nNumberOfAtoms)
     485                 :             :             {
     486                 :             :                 /* previous component exists; output it */
     487         [ #  # ]:           0 :                 if (bNext++)
     488                 :             :                 {
     489                 :           0 :                     MakeDelim( sCompDelim, strbuf, bOverflow );
     490                 :             :                 }
     491         [ #  # ]:           0 :                 if ((nTotalCharge_Prev = pINChI_Prev->nTotalCharge)) /* djb-rwth: addressing LLVM warning */
     492                 :             :                 {
     493                 :           0 :                     MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
     494                 :           0 :                     inchi_strbuf_printf( strbuf, "%+d", nTotalCharge_Prev );
     495                 :             :                 }
     496                 :             :             }
     497                 :             :             else
     498                 :             :             {
     499   [ #  #  #  #  :           0 :                 if (pINChI_Taut_Prev && pINChI_Taut_Prev->nNumberOfAtoms && !pINChI_Taut_Prev->bDeleted)
                   #  # ]
     500                 :             :                 {
     501                 :             :                     /* previous non-taut component exists only in taut list */
     502         [ #  # ]:           0 :                     if (bNext++)
     503                 :             :                     {
     504                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
     505                 :             :                     }
     506                 :             :                 }
     507                 :             :             }
     508                 :             :             /* we have found pINChI->nTotalCharge same as in pINChI_Taut */
     509                 :             :             /* output this (current) equivalence as '*', that is, same as tautomeric */
     510                 :             :             /* that was printed on the 1st pass. */
     511                 :             : 
     512                 :           0 :             pCurrEquStr = EquString( eq2taut );
     513   [ #  #  #  # ]:           0 :             if (multPrevEquStr && pPrevEquStr)
     514                 :             :             {
     515   [ #  #  #  # ]:           0 :                 if (pCurrEquStr && !strcmp( pCurrEquStr, pPrevEquStr ))
     516                 :             :                 {
     517                 :           0 :                     multPrevEquStr++;
     518                 :             :                 }
     519                 :             :                 else
     520                 :             :                 {
     521                 :             :                     /* new EqStr is different; output it */
     522         [ #  # ]:           0 :                     if (bNext++)
     523                 :             :                     {
     524                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
     525                 :             :                     }
     526                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
     527                 :           0 :                     pPrevEquStr = pCurrEquStr;
     528                 :           0 :                     multPrevEquStr = 1;
     529                 :             :                 }
     530                 :             :             }
     531                 :             :             else
     532                 :             :             {
     533                 :           0 :                 pPrevEquStr = pCurrEquStr;
     534                 :           0 :                 multPrevEquStr = 1;
     535                 :             :             }
     536                 :             : 
     537                 :           0 :             pINChI_Prev = NULL; /* pINChI_Prev sp2 does not exist since */
     538                 :           0 :             pINChI_Taut_Prev = NULL; /* pINChI has just been printed */
     539                 :           0 :             mult = 0;
     540                 :           0 :             eq2tautPrev = 1;     /* pINChI_Prev sp2 does not exist */
     541                 :             :         }
     542                 :             :         else
     543                 :             :         {
     544         [ +  + ]:          11 :             if (eq2tautPrev)
     545                 :             :             {
     546                 :             :                 /* at this point pINChI_Prev does not exist; however, pINChI */
     547                 :             :                 /*might have been discovered and it is different from pINChI_Taut */
     548   [ -  +  -  - ]:           3 :                 if (multPrevEquStr && pPrevEquStr)
     549                 :             :                 {
     550                 :             :                     /* new EqStr is different; output it */
     551         [ #  # ]:           0 :                     if (bNext++)
     552                 :             :                     {
     553                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
     554                 :             :                     }
     555                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
     556                 :           0 :                     pPrevEquStr = NULL;
     557                 :           0 :                     multPrevEquStr = 0;
     558                 :             :                 }
     559                 :           3 :                 eq2tautPrev = 0;
     560                 :           3 :                 pINChI_Prev = pINChI;
     561                 :           3 :                 pINChI_Taut_Prev = pINChI_Taut;
     562                 :           3 :                 mult = 0;
     563                 :             :             }
     564                 :             :             else
     565                 :             :             {
     566                 :             :                 /* check whether pINChI and pINChI_Prev have non-zero identical stereo sp3 */
     567                 :             :                 /*================ compare sp3 to previous =====================*/
     568         [ +  + ]:           8 :                 eq2prev = bUseMulipliers &&
     569         [ +  - ]:           5 :                     pINChI && pINChI_Prev &&
     570   [ +  -  +  +  :          16 :                     ( nTotalCharge = pINChI->nTotalCharge ) && ( nTotalCharge_Prev = pINChI_Prev->nTotalCharge ) &&
             +  +  +  - ]
     571                 :             :                     nTotalCharge == nTotalCharge_Prev;
     572         [ +  + ]:           8 :                 if (eq2prev)
     573                 :             :                 {
     574                 :           1 :                     mult++; /* mult = (number of non-empty equal items)-1 */
     575                 :           1 :                     continue;
     576                 :             :                 }
     577                 :             :                 else
     578                 :             :                 {
     579         [ +  + ]:           7 :                     if (bNext++)
     580                 :             :                     {
     581                 :           4 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
     582                 :             :                     }
     583   [ +  -  +  - ]:           7 :                     if (pINChI_Prev && pINChI_Prev->nNumberOfAtoms)
     584                 :             :                     {
     585         [ +  + ]:           7 :                         if ((nTotalCharge_Prev = pINChI_Prev->nTotalCharge)) /* djb-rwth: addressing LLVM warning */
     586                 :             :                         {
     587                 :             :                             /* pINChI_Prev exists and has charge info */
     588                 :           3 :                             MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
     589                 :           3 :                             inchi_strbuf_printf( strbuf, "%+d", nTotalCharge_Prev );
     590                 :             :                         }
     591                 :             :                         /* else charge is not present in pINChI_Prev */
     592                 :             :                     }
     593                 :             :                     else
     594                 :             :                     {
     595                 :             :                         /* djb-rwth: removing redundant code */
     596                 :             : #if ( bRELEASE_VERSION != 1 && defined(_DEBUG) )
     597                 :             :                         if (!(bSecondNonTautPass && pINChI_Taut_Prev && pINChI_Taut_Prev->nNumberOfAtoms && !pINChI_Taut_Prev->bDeleted))
     598                 :             :                         {
     599                 :             :                             int stop = 1;   /* <BRKPT> */
     600                 :             :                         }
     601                 :             : #endif
     602                 :             :                     }
     603                 :             :                 }
     604                 :           7 :                 pINChI_Prev = pINChI;
     605                 :           7 :                 pINChI_Taut_Prev = pINChI_Taut;
     606                 :           7 :                 mult = 0; /* we do not know whether the item is empty */
     607                 :             :             }
     608                 :             :         }
     609                 :             :     }
     610                 :             : 
     611                 :           3 :     return ( strbuf->nUsedLength - nUsedLength0 );
     612                 :             : }
     613                 :             : 
     614                 :             : 
     615                 :             : /****************************************************************************
     616                 :             :   Produce FixedH substring of the whole structure InChI string
     617                 :             : ****************************************************************************/
     618                 :           0 : int str_FixedH_atoms( INCHI_SORT       *pINChISort,
     619                 :             :                       INCHI_IOS_STRING *strbuf,
     620                 :             :                       int              *bOverflow,
     621                 :             :                       int              bOutType,
     622                 :             :                       int              ATOM_MODE,
     623                 :             :                       int              num_components,
     624                 :             :                       int              bUseMulipliers )
     625                 :             : {
     626                 :             :     int          i, j, ii, nNumEmpty, nUsedLength0;
     627                 :             :     INCHI_SORT   *is, *is0;
     628                 :             :     INChI        *pINChI, *pINChI_Prev;
     629                 :             :     int          mult, eq2prev, bNext, bNotEmpty;
     630                 :             : 
     631                 :           0 :     is = NULL;
     632                 :           0 :     is0 = pINChISort;
     633                 :           0 :     i = 0;
     634   [ #  #  #  #  :           0 :     pINChI_Prev = ( 0 <= ( ii = GET_II( bOutType, is0 ) ) ) ? is0->pINChI[ii] : NULL;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     635                 :           0 :     mult = 0;
     636                 :           0 :     bNext = 0;
     637                 :           0 :     nNumEmpty = 0;
     638                 :           0 :     nUsedLength0 = strbuf->nUsedLength;
     639                 :             : 
     640                 :             :     /* For each connected component...    */
     641         [ #  # ]:           0 :     for (i++; i <= num_components; i++)
     642                 :             :     {
     643                 :             :         /* only non-tautomeric representation of tautomeric */
     644   [ #  #  #  #  :           0 :         pINChI = ( i < num_components && ( is = is0 + i, 0 <= ( ii = GET_II( bOutType, is ) ) ) ) ? is->pINChI[ii] : NULL;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     645                 :             :         /*================ compare fixed H to previous =====================*/
     646         [ #  # ]:           0 :         eq2prev = bUseMulipliers &&
     647   [ #  #  #  # ]:           0 :             pINChI && pINChI_Prev && pINChI->nNumberOfAtoms > 0 &&
     648   [ #  #  #  # ]:           0 :             pINChI_Prev->nNumberOfAtoms == pINChI->nNumberOfAtoms &&
     649                 :           0 :             !memcmp( pINChI_Prev->nNum_H_fixed, pINChI->nNum_H_fixed,
     650         [ #  # ]:           0 :                 pINChI_Prev->nNumberOfAtoms * sizeof( pINChI->nNum_H_fixed[0] ) );
     651         [ #  # ]:           0 :         if (eq2prev)
     652                 :             :         {
     653                 :             :             /* make sure it is not empty */
     654                 :           0 :             eq2prev = 0;
     655         [ #  # ]:           0 :             for (j = 0; j < pINChI_Prev->nNumberOfAtoms; j++)
     656                 :             :             {
     657         [ #  # ]:           0 :                 if (pINChI_Prev->nNum_H_fixed[j])
     658                 :             :                 {
     659                 :           0 :                     eq2prev = 1;
     660                 :           0 :                     break;
     661                 :             :                 }
     662                 :             :             }
     663                 :             :         }
     664         [ #  # ]:           0 :         if (eq2prev)
     665                 :             :         {
     666                 :           0 :             mult++; /* mult = (number of non-empty equal items)-1 */
     667                 :           0 :             continue;
     668                 :             :         }
     669                 :             :         else
     670                 :             :         {
     671                 :             :             /* print pINChI_Prev */
     672                 :             :             /* delimiter */
     673         [ #  # ]:           0 :             if (bNext++)
     674                 :             :             {
     675                 :           0 :                 MakeDelim( sCompDelim, strbuf, bOverflow );
     676                 :             :             }
     677         [ #  # ]:           0 :             if (pINChI_Prev)
     678                 :             :             {
     679                 :             :                 /* verify it is not empty */
     680                 :           0 :                 bNotEmpty = 0;
     681         [ #  # ]:           0 :                 for (j = 0; j < pINChI_Prev->nNumberOfAtoms; j++)
     682                 :             :                 {
     683         [ #  # ]:           0 :                     if (pINChI_Prev->nNum_H_fixed[j])
     684                 :             :                     {
     685                 :           0 :                         bNotEmpty = 1;
     686                 :           0 :                         break;
     687                 :             :                     }
     688                 :             :                 }
     689         [ #  # ]:           0 :                 if (bNotEmpty)
     690                 :             :                 {
     691                 :           0 :                     MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
     692                 :             :                     /* H-atoms-fixed */
     693                 :           0 :                     MakeHString( 0, pINChI_Prev->nNum_H_fixed,
     694                 :             :                         pINChI_Prev->nNumberOfAtoms,
     695                 :             :                         strbuf, ATOM_MODE, bOverflow );
     696                 :             :                 }
     697                 :             :                 else
     698                 :             :                 {
     699                 :           0 :                     nNumEmpty++;
     700                 :             :                 }
     701                 :             :             }
     702                 :             :         }
     703                 :           0 :         pINChI_Prev = pINChI;
     704                 :           0 :         mult = 0; /* we do not know whether the item is empty */
     705                 :             :     }
     706   [ #  #  #  # ]:           0 :     if (nNumEmpty == num_components && strbuf->nUsedLength > nUsedLength0)
     707                 :             :     {
     708                 :           0 :         strbuf->nUsedLength = nUsedLength0;
     709                 :           0 :         strbuf->pStr[nUsedLength0] = '\0';
     710                 :             :     }
     711                 :             :     /*
     712                 :             :     if ( nNumEmpty == num_components && tot_len > tot_len_inp ) {
     713                 :             :     tot_len = tot_len_inp;
     714                 :             :     strbuf->pStr[tot_len] = '\0';
     715                 :             :     }
     716                 :             :     */
     717                 :             : 
     718                 :           0 :     return ( strbuf->nUsedLength - nUsedLength0 );
     719                 :             : }
     720                 :             : 
     721                 :             : /**
     722                 :             :  * @brief Produce double bond stereo substring of the whole structure InChI string.
     723                 :             :  *
     724                 :             :  * @param pINChISort Pointer to the primary INCHI_SORT structure containing input data.
     725                 :             :  * @param pINChISort2 Pointer to the secondary INCHI_SORT structure, used for comparison or additional data.
     726                 :             :  * @param strbuf Pointer to an INCHI_IOS_STRING buffer where the output string will be stored.
     727                 :             :  * @param bOverflow Pointer to an integer flag that will be set if the output overflows the buffer.
     728                 :             :  * @param bOutType Output type flag specifying the format or type of output.
     729                 :             :  * @param TAUT_MODE Tautomer mode flag indicating how tautomers are handled.
     730                 :             :  * @param num_components Number of components to process.
     731                 :             :  * @param bSecondNonTautPass Flag indicating if this is the second pass for non-tautomeric processing.
     732                 :             :  * @param bOmitRepetitions Flag to omit repeated entries in the output.
     733                 :             :  * @param bUseMulipliers Flag to use multipliers in the output representation.
     734                 :             :  * @return Returns number of characters written to strbuf
     735                 :             :  */
     736                 :           0 : int str_Sp2( INCHI_SORT       *pINChISort,
     737                 :             :              INCHI_SORT       *pINChISort2,
     738                 :             :              INCHI_IOS_STRING *strbuf,
     739                 :             :              int              *bOverflow,
     740                 :             :              int              bOutType,
     741                 :             :              int              TAUT_MODE,
     742                 :             :              int              num_components,
     743                 :             :              int              bSecondNonTautPass,
     744                 :             :              int              bOmitRepetitions,
     745                 :             :              int              bUseMulipliers )
     746                 :             : {
     747                 :             :     int          i, ii, ii2, nUsedLength0;
     748                 :             :     INCHI_SORT   *is, *is2, *is0, *is20;
     749                 :             :     INChI        *pINChI, *pINChI_Prev, *pINChI_Taut, *pINChI_Taut_Prev;
     750                 :             :     INChI_Stereo *Stereo, *Stereo_Prev, *Stereo_Taut, *Stereo_Taut_Prev;
     751                 :             :     int          mult, eq2prev, eq2taut, eq2tautPrev, bNext;
     752                 :             :     const char  *pPrevEquStr, *pCurrEquStr;
     753                 :             :     int         multPrevEquStr;
     754                 :             : 
     755                 :           0 :     pINChI_Taut = NULL;
     756                 :           0 :     pINChI_Prev = NULL;
     757                 :           0 :     pINChI_Taut_Prev = NULL;
     758                 :           0 :     mult = 0;
     759                 :           0 :     bNext = 0;
     760                 :           0 :     is = NULL;
     761                 :           0 :     is2 = NULL;
     762                 :           0 :     is0 = pINChISort;
     763         [ #  # ]:           0 :     is20 = bSecondNonTautPass ? pINChISort2 : NULL;
     764                 :             :     /* djb-rwth: removing redundant code */
     765                 :           0 :     eq2tautPrev = 1; /* pINChI_Prev (previous pINChI) does not exist */
     766                 :           0 :     pPrevEquStr = NULL; /*, *pCurrEquStr;*/
     767                 :           0 :     multPrevEquStr = 0;
     768                 :           0 :     nUsedLength0 = strbuf->nUsedLength;
     769                 :             : 
     770                 :             :     /* For each connected component ... */
     771         [ #  # ]:           0 :     for (i = 0; i <= num_components; i++)
     772                 :             :     {
     773                 :             : 
     774                 :             :         /* 1st (taut) pass: bOutType=OUT_TN  ; 2nd (non-taut pass) bOutType=OUT_NT */
     775   [ #  #  #  #  :           0 :         pINChI = ( i < num_components && ( is = is0 + i, 0 <= ( ii = GET_II( bOutType, is ) ) ) ) ? is->pINChI[ii] : NULL;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     776                 :             :         /*================ compare sp2 to previous =====================*/
     777         [ #  # ]:           0 :         if (bSecondNonTautPass)
     778                 :             :         {
     779                 :             :             /* component that was output on the 1st pass */
     780   [ #  #  #  #  :           0 :             pINChI_Taut = ( i < num_components && ( is2 = is20 + i, 0 <= ( ii2 = GET_II( OUT_T1, is2 ) ) ) ) ? is2->pINChI[ii2] : NULL;
          #  #  #  #  #  
                #  #  # ]
     781                 :             :         }
     782                 :             :         /*========= if bSecondNonTautPass then compare non-iso non-taut stereo to non-iso taut ========*/
     783                 :           0 :         eq2taut = 0;
     784                 :             : #if ( FIX_EMPTY_LAYER_BUG == 1 )
     785                 :             :         if (!eq2taut && bSecondNonTautPass && bOmitRepetitions && pINChI && pINChI_Taut)
     786                 :             :         {
     787                 :             :             Stereo = pINChI->Stereo;
     788                 :             :             Stereo_Taut = pINChI_Taut->Stereo;
     789                 :             :             eq2taut = Stereo && Stereo_Taut &&
     790                 :             :                 Eql_INChI_Stereo( Stereo, EQL_SP2, Stereo_Taut, EQL_SP2, 0 );
     791                 :             :             eq2taut = eq2taut ? ( iiSTEREO | iitNONTAUT ) : 0;
     792                 :             : 
     793                 :             :             if (!eq2taut &&
     794                 :             :                 !Eql_INChI_Stereo( Stereo, EQL_SP2, NULL, EQL_EXISTS, 0 ) &&
     795                 :             :                 Eql_INChI_Stereo( Stereo_Taut, EQL_SP2, NULL, EQL_EXISTS, 0 ))
     796                 :             :             {
     797                 :             :                 eq2taut = iiEmpty; /* the current is empty while the preceding (taut) is not */
     798                 :             :             }
     799                 :             :         }
     800                 :             : #else
     801   [ #  #  #  #  :           0 :         if (!eq2taut && bSecondNonTautPass && bOmitRepetitions)
                   #  # ]
     802                 :             :         {
     803         [ #  # ]:           0 :             eq2taut = pINChI && pINChI_Taut &&
     804   [ #  #  #  #  :           0 :                 ( Stereo = pINChI->Stereo ) && ( Stereo_Taut = pINChI_Taut->Stereo ) &&
             #  #  #  # ]
     805                 :           0 :                 Eql_INChI_Stereo( Stereo, EQL_SP2, Stereo_Taut, EQL_SP2, 0 );
     806         [ #  # ]:           0 :             eq2taut = eq2taut ? ( iiSTEREO | iitNONTAUT ) : 0;
     807                 :             :         }
     808                 :             : #endif
     809         [ #  # ]:           0 :         if (eq2taut)
     810                 :             :         {
     811                 :             :             /* we may be here only in case of the second (non-taut) pass */
     812                 :             :             /* current non-taut stereo has been found to be same as tautomeric */
     813   [ #  #  #  # ]:           0 :             if (pINChI_Prev && pINChI_Prev->nNumberOfAtoms)
     814                 :             :             {
     815                 :             :                 /* previous component exists; output it */
     816         [ #  # ]:           0 :                 if (bNext++)
     817                 :             :                 {
     818                 :           0 :                     MakeDelim( sCompDelim, strbuf, bOverflow );
     819                 :             :                 }
     820   [ #  #  #  # ]:           0 :                 if (( Stereo_Prev = pINChI_Prev->Stereo ) && Stereo_Prev->nNumberOfStereoBonds > 0)
     821                 :             :                 {
     822                 :           0 :                     MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
     823                 :             : 
     824                 :           0 :                     MakeStereoString( Stereo_Prev->nBondAtom1, Stereo_Prev->nBondAtom2,
     825                 :             :                         Stereo_Prev->b_parity,
     826                 :             :                         0, Stereo_Prev->nNumberOfStereoBonds,
     827                 :             :                         strbuf, TAUT_MODE, bOverflow );
     828                 :             :                 }
     829                 :             :             }
     830                 :             :             else
     831                 :             :             {
     832   [ #  #  #  # ]:           0 :                 if (pINChI_Taut_Prev && pINChI_Taut_Prev->nNumberOfAtoms)
     833                 :             :                 {
     834                 :             :                     /* previous non-taut component exists only in taut list */
     835         [ #  # ]:           0 :                     if (bNext++)
     836                 :             :                     {
     837                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
     838                 :             :                     }
     839                 :             :                 }
     840                 :             :             }
     841                 :             :             /* we have found pINChI->Stereo sp2 same as in pINChI_Taut */
     842                 :             :             /* output this (current) equivalence as '*', that is, same as tautomeric */
     843                 :             :             /* that was printed on the 1st pass. */
     844                 :           0 :             pCurrEquStr = EquString( eq2taut );
     845   [ #  #  #  # ]:           0 :             if (multPrevEquStr && pPrevEquStr)
     846                 :             :             {
     847   [ #  #  #  # ]:           0 :                 if (pCurrEquStr && !strcmp( pCurrEquStr, pPrevEquStr ))
     848                 :             :                 {
     849                 :           0 :                     multPrevEquStr++;
     850                 :             :                 }
     851                 :             :                 else
     852                 :             :                 {
     853                 :             :                     /* new EqStr is different; output the previous one */
     854         [ #  # ]:           0 :                     if (bNext++)
     855                 :             :                     {
     856                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
     857                 :             :                     }
     858                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
     859                 :           0 :                     pPrevEquStr = pCurrEquStr;
     860                 :           0 :                     multPrevEquStr = 1;
     861                 :             :                 }
     862                 :             :             }
     863                 :             :             else
     864                 :             :             {
     865                 :           0 :                 pPrevEquStr = pCurrEquStr;
     866                 :           0 :                 multPrevEquStr = 1;
     867                 :             :             }
     868                 :           0 :             pINChI_Prev = NULL; /* pINChI_Prev sp2 does not exist since */
     869                 :           0 :             pINChI_Taut_Prev = NULL; /* pINChI has just been printed */
     870                 :           0 :             mult = 0;
     871                 :           0 :             eq2tautPrev = 1;     /* pINChI_Prev sp2 does not exist */
     872                 :             :         }
     873                 :             :         else
     874                 :             :         {
     875         [ #  # ]:           0 :             if (eq2tautPrev)
     876                 :             :             {
     877                 :             :                 /* at this point pINChI_Prev does not exist; however, pINChI */
     878                 :             :                 /*might have been discovered and it is different from pINChI_Taut */
     879   [ #  #  #  # ]:           0 :                 if (multPrevEquStr && pPrevEquStr)
     880                 :             :                 {
     881                 :             :                     /* new EqStr is different; output it */
     882         [ #  # ]:           0 :                     if (bNext++)
     883                 :             :                     {
     884                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
     885                 :             :                     }
     886                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
     887                 :           0 :                     pPrevEquStr = NULL;
     888                 :           0 :                     multPrevEquStr = 0;
     889                 :             :                 }
     890                 :           0 :                 eq2tautPrev = 0;
     891                 :           0 :                 pINChI_Prev = pINChI;
     892                 :           0 :                 pINChI_Taut_Prev = pINChI_Taut;
     893                 :           0 :                 mult = 0;
     894                 :             :             }
     895                 :             :             else
     896                 :             :             {
     897                 :             :                 /* check whether pINChI and pINChI_Prev have non-zero identical stereo sp2 */
     898         [ #  # ]:           0 :                 eq2prev = bUseMulipliers &&
     899         [ #  # ]:           0 :                     pINChI && pINChI_Prev &&
     900   [ #  #  #  #  :           0 :                     ( Stereo = pINChI->Stereo ) && ( Stereo_Prev = pINChI_Prev->Stereo ) &&
             #  #  #  # ]
     901                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP2, Stereo_Prev, EQL_SP2, 0 );
     902         [ #  # ]:           0 :                 if (eq2prev)
     903                 :             :                 {
     904                 :           0 :                     mult++; /* mult = (number of non-empty equal items)-1 */
     905                 :           0 :                     continue;
     906                 :             :                 }
     907                 :             :                 else
     908                 :             :                 {
     909                 :             :                     /* pINChI sp2 info is either different or trivial. Output pINChI_Prev anyway */
     910         [ #  # ]:           0 :                     if (bNext++)
     911                 :             :                     {
     912                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
     913                 :             :                     }
     914   [ #  #  #  # ]:           0 :                     if (pINChI_Prev && pINChI_Prev->nNumberOfAtoms)
     915                 :             :                     {
     916   [ #  #  #  # ]:           0 :                         if (( Stereo_Prev = pINChI_Prev->Stereo ) && Stereo_Prev->nNumberOfStereoBonds > 0)
     917                 :             :                         {
     918                 :             :                             /* pINChI_Prev exists and has sp2 info */
     919                 :           0 :                             MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
     920                 :             : 
     921                 :           0 :                             MakeStereoString( Stereo_Prev->nBondAtom1, Stereo_Prev->nBondAtom2,
     922                 :             :                                 Stereo_Prev->b_parity,
     923                 :             :                                 0, Stereo_Prev->nNumberOfStereoBonds,
     924                 :             :                                 strbuf, TAUT_MODE, bOverflow );
     925                 :             :                         }
     926                 :             :                         /* else sp2 info is not present in pINChI_Prev */
     927                 :             :                     }
     928                 :             :                     else
     929                 :             :                     {
     930   [ #  #  #  #  :           0 :                         if (bSecondNonTautPass && pINChI_Taut_Prev && pINChI_Taut_Prev->nNumberOfAtoms)
                   #  # ]
     931                 :             :                         {
     932         [ #  # ]:           0 :                             if (( Stereo_Taut_Prev = pINChI_Taut_Prev->Stereo ) && Stereo_Taut_Prev->nNumberOfStereoBonds > 0)
     933                 :             :                             {
     934                 :             :                                 /* since pINChI_Prev does not exist, pINChI_Taut_Prev is non-tautomeric */
     935                 :             :                                 /* and it has non-trivial sp2 info */
     936                 :             :                                 /*
     937                 :             :                                 tot_len += MakeDelim( sIdenticalValues, strbuf, bOverflow);
     938                 :             :                                 */
     939                 :             :                                 ;/* pINChI_Taut_Prev sp2 info was output in the main stereo section */
     940                 :             :                             }
     941                 :             :                             else
     942                 :             :                             {
     943                 :             :                                 ; /* pINChI_Taut_Prev exists and has not sp2 info */
     944                 :             :                             }
     945                 :             :                         }
     946                 :             :                     }
     947                 :             : #if ( bRELEASE_VERSION != 1 && defined(_DEBUG) )
     948                 :             :                         else
     949                 :             :                         {
     950                 :             :                             int stop = 1;   /* <BRKPT> */
     951                 :             :                         }
     952                 :             : #endif
     953                 :             :                 }
     954                 :           0 :                 pINChI_Prev = pINChI;
     955                 :           0 :                 pINChI_Taut_Prev = pINChI_Taut;
     956                 :           0 :                 mult = 0; /* we do not know whether the item is empty */
     957                 :             :             }
     958                 :             :         }
     959                 :             :     }    /* end of for each connected component ... */
     960                 :             : 
     961                 :           0 :     return ( strbuf->nUsedLength - nUsedLength0 );
     962                 :             : }
     963                 :             : 
     964                 :             : /**
     965                 :             :  * @brief Produce tetrahedral stereo substring of the whole structure InChI string.
     966                 :             :  *
     967                 :             :  * @param pINChISort Pointer to the primary INCHI_SORT structure containing input data.
     968                 :             :  * @param pINChISort2 Pointer to the secondary INCHI_SORT structure, used for comparison or additional data.
     969                 :             :  * @param strbuf Pointer to an INCHI_IOS_STRING buffer where the output string will be stored.
     970                 :             :  * @param bOverflow Pointer to an integer flag that will be set if the output overflows the buffer.
     971                 :             :  * @param bOutType Output type flag specifying the format or type of output.
     972                 :             :  * @param TAUT_MODE Tautomer mode flag indicating how tautomers are handled.
     973                 :             :  * @param num_components The number of components to process.
     974                 :             :  * @param bRelRac Flag for relative or racemic stereochemistry.
     975                 :             :  * @param bSecondNonTautPass Flag indicating if this is the second pass for non-tautomeric processing.
     976                 :             :  * @param bOmitRepetitions Flag to omit repeated entries in the output.
     977                 :             :  * @param bUseMulipliers Flag to use multipliers in the output representation.
     978                 :             :  * @return int
     979                 :             :  */
     980                 :          42 : int str_Sp3( INCHI_SORT       *pINChISort,
     981                 :             :              INCHI_SORT       *pINChISort2,
     982                 :             :              INCHI_IOS_STRING *strbuf,
     983                 :             :              int              *bOverflow,
     984                 :             :              int              bOutType,
     985                 :             :              int              TAUT_MODE,
     986                 :             :              int              num_components,
     987                 :             :              int              bRelRac,
     988                 :             :              int              bSecondNonTautPass,
     989                 :             :              int              bOmitRepetitions,
     990                 :             :              int              bUseMulipliers )
     991                 :             : {
     992                 :             :     int          i, ii, ii2, nUsedLength0;
     993                 :             :     INCHI_SORT   *is, *is2, *is0, *is20;
     994                 :             :     INChI        *pINChI, *pINChI_Prev, *pINChI_Taut, *pINChI_Taut_Prev;
     995                 :             :     INChI_Stereo *Stereo, *Stereo_Prev, *Stereo_Taut, *Stereo_Taut_Prev;
     996                 :             :     int          mult, eq2prev, eq2taut, eq2tautPrev, bNext;
     997                 :             :     const char  *pPrevEquStr, *pCurrEquStr;
     998                 :             :     int         multPrevEquStr;
     999                 :          42 :     pINChI_Taut = NULL;
    1000                 :          42 :     pINChI_Prev = NULL;
    1001                 :          42 :     pINChI_Taut_Prev = NULL;
    1002                 :          42 :     mult = 0;
    1003                 :          42 :     bNext = 0;
    1004                 :          42 :     is = NULL;
    1005                 :          42 :     is2 = NULL;
    1006                 :          42 :     is0 = pINChISort;
    1007         [ -  + ]:          42 :     is20 = bSecondNonTautPass ? pINChISort2 : NULL;
    1008                 :             :     /* djb-rwth: removing redundant code */
    1009                 :          42 :     eq2tautPrev = 1; /* pINChI_Prev (previous pINChI) does not exist */
    1010                 :          42 :     pPrevEquStr = NULL; /*, *pCurrEquStr;*/
    1011                 :          42 :     multPrevEquStr = 0;
    1012                 :             : #if ( REL_RAC_STEREO_IGN_1_SC == 1 )
    1013                 :             : #else
    1014                 :          42 :     bRelRac = 0;
    1015                 :             : #endif
    1016                 :          42 :     nUsedLength0 = strbuf->nUsedLength;
    1017                 :             : 
    1018                 :             :     /* For each connected component...    */
    1019         [ +  + ]:         136 :     for (i = 0; i <= num_components; i++)
    1020                 :             :     {
    1021                 :             : 
    1022                 :             :         /* 1st (taut) pass: bOutType=OUT_TN  ; 2nd (non-taut pass) bOutType=OUT_NT */
    1023   [ +  +  -  +  :          94 :         pINChI = ( i < num_components && ( is = is0 + i, 0 <= ( ii = GET_II( bOutType, is ) ) ) ) ? is->pINChI[ii] : NULL;
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  +  
          -  +  -  -  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
             -  -  +  - ]
    1024                 :             :         /*================ compare sp3 to previous =====================*/
    1025         [ -  + ]:          94 :         if (bSecondNonTautPass)
    1026                 :             :         {
    1027                 :             :             /* component that was output on the 1st pass */
    1028   [ #  #  #  #  :           0 :             pINChI_Taut = ( i < num_components && ( is2 = is20 + i, 0 <= ( ii2 = GET_II( OUT_T1, is2 ) ) ) ) ? is2->pINChI[ii2] : NULL;
          #  #  #  #  #  
                #  #  # ]
    1029                 :             :         }
    1030                 :             :         /*========= if bSecondNonTautPass then compare non-iso non-taut stereo to non-iso taut ========*/
    1031                 :          94 :         eq2taut = 0;
    1032                 :             : #if ( FIX_EMPTY_LAYER_BUG == 1 )
    1033                 :             :         if (!eq2taut && bSecondNonTautPass && bOmitRepetitions && pINChI && pINChI_Taut)
    1034                 :             :         {
    1035                 :             :             Stereo = pINChI->Stereo;
    1036                 :             :             Stereo_Taut = pINChI_Taut->Stereo;
    1037                 :             :             eq2taut = Stereo && Stereo_Taut &&
    1038                 :             :                 Eql_INChI_Stereo( Stereo, EQL_SP3, Stereo_Taut, EQL_SP3, bRelRac );
    1039                 :             :             eq2taut = eq2taut ? ( iiSTEREO | iitNONTAUT ) : 0;
    1040                 :             :             if (!eq2taut &&
    1041                 :             :                 !Eql_INChI_Stereo( Stereo, EQL_SP3, NULL, EQL_EXISTS, 0 ) &&
    1042                 :             :                 Eql_INChI_Stereo( Stereo_Taut, EQL_SP3, NULL, EQL_EXISTS, 0 ))
    1043                 :             :             {
    1044                 :             :                 eq2taut = iiEmpty; /* the current is empty while the preceding (taut) is not */
    1045                 :             :             }
    1046                 :             :         }
    1047                 :             : #else
    1048   [ +  -  -  +  :          94 :         if (!eq2taut && bSecondNonTautPass && bOmitRepetitions)
                   -  - ]
    1049                 :             :         {
    1050         [ #  # ]:           0 :             eq2taut = pINChI && pINChI_Taut &&
    1051   [ #  #  #  #  :           0 :                 ( Stereo = pINChI->Stereo ) && ( Stereo_Taut = pINChI_Taut->Stereo ) &&
             #  #  #  # ]
    1052                 :           0 :                 Eql_INChI_Stereo( Stereo, EQL_SP3, Stereo_Taut, EQL_SP3, bRelRac );
    1053         [ #  # ]:           0 :             eq2taut = eq2taut ? ( iiSTEREO | iitNONTAUT ) : 0;
    1054                 :             :         }
    1055                 :             : #endif
    1056         [ -  + ]:          94 :         if (eq2taut)
    1057                 :             :         {
    1058                 :             :             /* we may be here only in case of the second (non-taut) pass */
    1059                 :             :             /* current non-taut stereo has been found to be same as tautomeric */
    1060   [ #  #  #  # ]:           0 :             if (pINChI_Prev && pINChI_Prev->nNumberOfAtoms)
    1061                 :             :             {
    1062                 :             :                 /* previous component exists; output it */
    1063         [ #  # ]:           0 :                 if (bNext++)
    1064                 :             :                 {
    1065                 :           0 :                     MakeDelim( sCompDelim, strbuf, bOverflow );
    1066                 :             :                 }
    1067   [ #  #  #  # ]:           0 :                 if (( Stereo_Prev = pINChI_Prev->Stereo ) && Stereo_Prev->nNumberOfStereoCenters > 0)
    1068                 :             :                 {
    1069                 :             :                     /* non-empty item */
    1070                 :           0 :                     MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
    1071                 :           0 :                     MakeStereoString( Stereo_Prev->nNumber, NULL,
    1072                 :             :                                       Stereo_Prev->t_parity,0,
    1073                 :             :                                       Stereo_Prev->nNumberOfStereoCenters,
    1074                 :             :                                       strbuf, TAUT_MODE, bOverflow );
    1075                 :             :                 }
    1076                 :             :             }
    1077                 :             :             else
    1078   [ #  #  #  # ]:           0 :                 if (pINChI_Taut_Prev && pINChI_Taut_Prev->nNumberOfAtoms)
    1079                 :             :                 {
    1080                 :             :                     /* previous non-taut component exists only in taut list */
    1081         [ #  # ]:           0 :                     if (bNext++)
    1082                 :             :                     {
    1083                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    1084                 :             :                     }
    1085                 :             :                 }
    1086                 :             :             /* we have found pINChI->Stereo sp3 same as in pINChI_Taut */
    1087                 :             :             /* output this (current) equivalence as '*', that is, same as tautomeric */
    1088                 :             :             /* that was printed on the 1st pass. */
    1089                 :             : 
    1090                 :           0 :             pCurrEquStr = EquString( eq2taut );
    1091   [ #  #  #  # ]:           0 :             if (multPrevEquStr && pPrevEquStr)
    1092                 :             :             {
    1093   [ #  #  #  # ]:           0 :                 if (pCurrEquStr && !strcmp( pCurrEquStr, pPrevEquStr ))
    1094                 :             :                 {
    1095                 :           0 :                     multPrevEquStr++;
    1096                 :             :                 }
    1097                 :             :                 else
    1098                 :             :                 {
    1099                 :             :                     /* new EqStr is different; output it */
    1100         [ #  # ]:           0 :                     if (bNext++)
    1101                 :             :                     {
    1102                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    1103                 :             :                     }
    1104                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    1105                 :           0 :                     pPrevEquStr = pCurrEquStr;
    1106                 :           0 :                     multPrevEquStr = 1;
    1107                 :             :                 }
    1108                 :             :             }
    1109                 :             :             else
    1110                 :             :             {
    1111                 :           0 :                 pPrevEquStr = pCurrEquStr;
    1112                 :           0 :                 multPrevEquStr = 1;
    1113                 :             :             }
    1114                 :             : 
    1115                 :           0 :             pINChI_Prev = NULL; /* pINChI_Prev sp2 does not exist since */
    1116                 :           0 :             pINChI_Taut_Prev = NULL; /* pINChI has just been printed */
    1117                 :           0 :             mult = 0;
    1118                 :           0 :             eq2tautPrev = 1;     /* pINChI_Prev sp2 does not exist */
    1119                 :             :         }
    1120                 :             :         else
    1121                 :             :         {
    1122         [ +  + ]:          94 :             if (eq2tautPrev)
    1123                 :             :             {
    1124                 :             :                 /* at this point pINChI_Prev does not exist; however, pINChI */
    1125                 :             :                 /*might have been discovered and it is different from pINChI_Taut */
    1126   [ -  +  -  - ]:          42 :                 if (multPrevEquStr && pPrevEquStr)
    1127                 :             :                 {
    1128                 :             :                     /* new EqStr is different; output it */
    1129         [ #  # ]:           0 :                     if (bNext++)
    1130                 :             :                     {
    1131                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    1132                 :             :                     }
    1133                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    1134                 :           0 :                     pPrevEquStr = NULL;
    1135                 :           0 :                     multPrevEquStr = 0;
    1136                 :             :                 }
    1137                 :          42 :                 eq2tautPrev = 0;
    1138                 :          42 :                 pINChI_Prev = pINChI;
    1139                 :          42 :                 pINChI_Taut_Prev = pINChI_Taut;
    1140                 :          42 :                 mult = 0;
    1141                 :             :             }
    1142                 :             :             else
    1143                 :             :             {
    1144                 :             :                 /* check whether pINChI and pINChI_Prev have non-zero identical stereo sp3 */
    1145                 :             :                 /*================ compare sp3 to previous =====================*/
    1146         [ +  + ]:          52 :                 eq2prev = bUseMulipliers &&
    1147         [ +  - ]:          10 :                     pINChI && pINChI_Prev &&
    1148   [ +  -  +  -  :         114 :                     ( Stereo = pINChI->Stereo ) && ( Stereo_Prev = pINChI_Prev->Stereo ) &&
             +  -  +  + ]
    1149                 :          10 :                     Eql_INChI_Stereo( Stereo, EQL_SP3, Stereo_Prev, EQL_SP3, bRelRac );
    1150         [ +  + ]:          52 :                 if (eq2prev)
    1151                 :             :                 {
    1152                 :           5 :                     mult++; /* mult = (number of non-empty equal items)-1 */
    1153                 :           5 :                     continue;
    1154                 :             :                 }
    1155                 :             :                 else
    1156                 :             :                 {
    1157         [ +  + ]:          47 :                     if (bNext++)
    1158                 :             :                     {
    1159                 :           5 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    1160                 :             :                     }
    1161   [ +  -  +  - ]:          47 :                     if (pINChI_Prev && pINChI_Prev->nNumberOfAtoms)
    1162                 :             :                     {
    1163   [ +  -  +  + ]:          47 :                         if (( Stereo_Prev = pINChI_Prev->Stereo ) && Stereo_Prev->nNumberOfStereoCenters > bRelRac)
    1164                 :             :                         {
    1165                 :             :                             /* pINChI_Prev exists and has sp3 info */
    1166                 :          46 :                             MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
    1167                 :             : 
    1168                 :          46 :                             MakeStereoString( Stereo_Prev->nNumber, NULL, Stereo_Prev->t_parity,
    1169                 :             :                                 0, Stereo_Prev->nNumberOfStereoCenters,
    1170                 :             :                                 strbuf, TAUT_MODE, bOverflow );
    1171                 :             :                         }
    1172                 :             :                         /* else sp3 info is not present in pINChI_Prev */
    1173                 :             :                     }
    1174                 :             :                     else
    1175                 :             :                     {
    1176   [ #  #  #  #  :           0 :                         if (bSecondNonTautPass && pINChI_Taut_Prev && pINChI_Taut_Prev->nNumberOfAtoms)
                   #  # ]
    1177                 :             :                         {
    1178         [ #  # ]:           0 :                             if (( Stereo_Taut_Prev = pINChI_Taut_Prev->Stereo ) && Stereo_Taut_Prev->nNumberOfStereoCenters > bRelRac)
    1179                 :             :                             {
    1180                 :             :                                 /* since pINChI_Prev does not exist, pINChI_Taut_Prev is non-tautomeric */
    1181                 :             :                                 /* and it has non-trivial sp3 info. This info has already been printed in the main section */
    1182                 :             :                                 /*
    1183                 :             :                                 tot_len += MakeDelim( sIdenticalValues, strbuf, bOverflow);
    1184                 :             :                                 */
    1185                 :             :                                 ; /* pINChI_Taut_Prev sp3 info was output in the main stereo section */
    1186                 :             :                             }
    1187                 :             :                             else
    1188                 :             :                             {
    1189                 :             :                                 ; /* pINChI_Taut_Prev exists and has not sp3 info */
    1190                 :             :                             }
    1191                 :             :                         }
    1192                 :             : #if ( bRELEASE_VERSION != 1 && defined(_DEBUG) )
    1193                 :             :                         else
    1194                 :             :                         {
    1195                 :             :                             int stop = 1;   /* <BRKPT> */
    1196                 :             :                         }
    1197                 :             : #endif
    1198                 :             :                     }
    1199                 :             :                 }
    1200                 :          47 :                 pINChI_Prev = pINChI;
    1201                 :          47 :                 pINChI_Taut_Prev = pINChI_Taut;
    1202                 :          47 :                 mult = 0; /* we do not know whether the item is empty */
    1203                 :             :             }
    1204                 :             :         }
    1205                 :             :     }
    1206                 :             : 
    1207                 :          42 :     return ( strbuf->nUsedLength - nUsedLength0 );
    1208                 :             : }
    1209                 :             : 
    1210                 :             : /**
    1211                 :             :  * @brief Output absolute stereo inversion substring of the whole structure InChI string
    1212                 :             :  * @param pINChISort Pointer to INCHI_SORT array
    1213                 :             :  * @param strbuf Pointer to string buffer
    1214                 :             :  * @param bOverflow Overflow flag
    1215                 :             :  * @param bOutType Output type
    1216                 :             :  * @param num_components Number of connected components
    1217                 :             :  * @return Length of the added substring (return value '0', '1', or '.' in strbuf)
    1218                 :             :  */
    1219                 :          42 : int str_StereoAbsInv( INCHI_SORT       *pINChISort,
    1220                 :             :                       INCHI_IOS_STRING *strbuf,
    1221                 :             :                       int              *bOverflow,
    1222                 :             :                       int              bOutType,
    1223                 :             :                       int              num_components )
    1224                 :             : {
    1225                 :             :     int          i, j, ii, nUsedLength0;
    1226                 :             :     INCHI_SORT   *is, *is0;
    1227                 :             :     INChI_Stereo *Stereo;
    1228                 :             :     INChI        *pINChI;
    1229                 :             : 
    1230                 :          42 :     is = NULL;
    1231                 :          42 :     is0 = pINChISort;
    1232                 :          42 :     nUsedLength0 = strbuf->nUsedLength;
    1233                 :             : 
    1234                 :             :     /* For each connected component...    */
    1235   [ +  -  +  + ]:          94 :     for (i = 0; !*bOverflow && i < num_components; i++)
    1236                 :             :     {
    1237                 :             : 
    1238                 :          52 :         is = is0 + i;
    1239   [ -  +  -  -  :          52 :         pINChI = ( 0 <= ( ii = GET_II( bOutType, is ) ) ) ? is->pINChI[ii] : NULL;
          -  -  -  -  -  
          -  -  -  -  -  
          +  -  +  -  +  
          -  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
                   +  - ]
    1240   [ +  -  +  -  :          52 :         if (pINChI && ( Stereo = pINChI->Stereo ) && ( j = Stereo->nCompInv2Abs ))
                   +  + ]
    1241                 :             :         {
    1242         [ +  + ]:          51 :             MakeDelim( j < 0 ? "1" : "0", strbuf, bOverflow );
    1243                 :             :         }
    1244                 :             :         else
    1245                 :             :         {
    1246                 :           1 :             MakeDelim( ".", strbuf, bOverflow );
    1247                 :             :         }
    1248                 :             :     }
    1249                 :             : 
    1250                 :          42 :     return ( strbuf->nUsedLength - nUsedLength0 );
    1251                 :             : }
    1252                 :             : 
    1253                 :             : 
    1254                 :             : /****************************************************************************
    1255                 :             :   Produce isotopic substring of the whole structure InChI string.
    1256                 :             : ****************************************************************************/
    1257                 :           0 : int str_IsoAtoms( INCHI_SORT *pINChISort,
    1258                 :             :                   INCHI_SORT *pINChISort2,
    1259                 :             :                   INCHI_IOS_STRING *strbuf,
    1260                 :             :                   int *bOverflow,
    1261                 :             :                   int bOutType,
    1262                 :             :                   int TAUT_MODE,
    1263                 :             :                   int num_components,
    1264                 :             :                   int bAbcNumbers,
    1265                 :             :                   int bSecondNonTautPass,
    1266                 :             :                   int bOmitRepetitions,
    1267                 :             :                   int bUseMulipliers )
    1268                 :             : {
    1269                 :             :     int          i, ii, ii2, nUsedLength0;
    1270                 :             :     INCHI_SORT   *is, *is2, *is0, *is20;
    1271                 :             :     INChI        *pINChI, *pINChI_Prev, *pINChI_Taut, *pINChI_Taut_Prev;
    1272                 :             :     int          mult, eq2prev, eq2taut, eq2tautPrev, bNext;
    1273                 :             :     const char  *pPrevEquStr, *pCurrEquStr;
    1274                 :             :     int         multPrevEquStr;
    1275                 :           0 :     pINChI_Taut = NULL;
    1276                 :           0 :     pINChI_Prev = NULL;
    1277                 :           0 :     pINChI_Taut_Prev = NULL;
    1278                 :           0 :     mult = 0;
    1279                 :           0 :     bNext = 0;
    1280                 :           0 :     is = NULL;
    1281                 :           0 :     is2 = NULL;
    1282                 :           0 :     is0 = pINChISort;
    1283         [ #  # ]:           0 :     is20 = bSecondNonTautPass ? pINChISort2 : NULL;
    1284                 :             :     /* djb-rwth: removing redundant code */
    1285                 :           0 :     eq2tautPrev = 1; /* pINChI_Prev (previous pINChI) does not exist */
    1286                 :           0 :     pPrevEquStr = NULL; /*, *pCurrEquStr;*/
    1287                 :           0 :     multPrevEquStr = 0;
    1288                 :           0 :     nUsedLength0 = strbuf->nUsedLength;
    1289                 :             : 
    1290                 :             :     /* For each connected component...    */
    1291         [ #  # ]:           0 :     for (i = 0; i <= num_components; i++)
    1292                 :             :     {
    1293                 :             : 
    1294                 :             :         /* 1st (taut) pass: bOutType=OUT_TN  ; 2nd (non-taut pass) bOutType=OUT_NT */
    1295   [ #  #  #  #  :           0 :         pINChI = ( i < num_components && ( is = is0 + i, 0 <= ( ii = GET_II( bOutType, is ) ) ) ) ? is->pINChI[ii] : NULL;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    1296                 :             :         /*================ compare isotopic info to previous component =====================*/
    1297         [ #  # ]:           0 :         if (bSecondNonTautPass)
    1298                 :             :         {
    1299                 :             :             /* component that was output on the 1st pass */
    1300   [ #  #  #  #  :           0 :             pINChI_Taut = ( i < num_components && ( is2 = is20 + i, 0 <= ( ii2 = GET_II( OUT_T1, is2 ) ) ) ) ? is2->pINChI[ii2] : NULL;
          #  #  #  #  #  
                #  #  # ]
    1301                 :             :         }
    1302                 :             :         /*========= if bSecondNonTautPass then compare iso non-taut to taut non-iso ========*/
    1303                 :           0 :         eq2taut = 0;
    1304   [ #  #  #  #  :           0 :         if (!eq2taut && bSecondNonTautPass && bOmitRepetitions)
                   #  # ]
    1305                 :             :         {
    1306                 :           0 :             eq2taut = Eql_INChI_Isotopic( pINChI, pINChI_Taut );
    1307         [ #  # ]:           0 :             eq2taut = eq2taut ? ( iiNUMB | iitNONTAUT ) : 0;
    1308                 :             :         }
    1309         [ #  # ]:           0 :         if (eq2taut)
    1310                 :             :         {
    1311                 :             :             /* we may be here only in case of the second (non-taut) pass */
    1312                 :             :             /* current non-taut isotopic info has been found to be same as current tautomeric */
    1313   [ #  #  #  # ]:           0 :             if (pINChI_Prev && pINChI_Prev->nNumberOfAtoms)
    1314                 :             :             {
    1315                 :             :                 /* previous component exists; output it */
    1316         [ #  # ]:           0 :                 if (bNext++)
    1317                 :             :                 {
    1318                 :           0 :                     MakeDelim( sCompDelim, strbuf, bOverflow );
    1319                 :             :                 }
    1320   [ #  #  #  # ]:           0 :                 if (pINChI_Prev && ( pINChI_Prev->nNumberOfIsotopicAtoms > 0 ||
    1321         [ #  # ]:           0 :                     pINChI_Prev->nNumberOfIsotopicTGroups > 0 ))
    1322                 :             :                 {
    1323                 :             :                     /* non-empty item */
    1324                 :           0 :                     MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
    1325                 :             :                     /*  Isotopic atoms */
    1326   [ #  #  #  # ]:           0 :                     if (pINChI_Prev->nNumberOfIsotopicAtoms > 0/* && nStrLen-tot_len > 2*/ && !*bOverflow)
    1327                 :             :                     { /* dereferenced bOverflow 2004-06-07 */
    1328                 :           0 :                         MakeIsoAtomString( pINChI_Prev->IsotopicAtom,
    1329                 :             :                             pINChI_Prev->nNumberOfIsotopicAtoms,
    1330                 :             :                             strbuf,
    1331                 :             :                             TAUT_MODE, bOverflow );
    1332                 :             :                     }
    1333                 :             :                     /*  Isotopic tautomeric groups */
    1334         [ #  # ]:           0 :                     if (pINChI_Prev->nNumberOfIsotopicTGroups > 0 &&
    1335                 :             :                         /*nStrLen-tot_len > 3 && */
    1336         [ #  # ]:           0 :                         !*bOverflow)
    1337                 :             :                     {
    1338         [ #  # ]:           0 :                         MakeDelim( bAbcNumbers ? ITEM_DELIMETER : "(", strbuf, bOverflow );
    1339                 :           0 :                         MakeIsoTautString( pINChI_Prev->IsotopicTGroup, pINChI_Prev->nNumberOfIsotopicTGroups,
    1340                 :             :                             strbuf, TAUT_MODE, bOverflow );
    1341         [ #  # ]:           0 :                         if (!bAbcNumbers)
    1342                 :             :                         {
    1343                 :           0 :                             MakeDelim( ")", strbuf, bOverflow );
    1344                 :             :                         }
    1345                 :             :                     }
    1346                 :             :                 }
    1347                 :             :             }
    1348                 :             :             else
    1349                 :             :             {
    1350   [ #  #  #  # ]:           0 :                 if (pINChI_Taut_Prev && pINChI_Taut_Prev->nNumberOfAtoms)
    1351                 :             :                 {
    1352                 :             :                     /* previous non-taut component exists only in taut list */
    1353         [ #  # ]:           0 :                     if (bNext++)
    1354                 :             :                     {
    1355                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    1356                 :             :                     }
    1357                 :             :                 }
    1358                 :             :             }
    1359                 :             :             /* we have found pINChI isotopic info to be same as in pINChI_Taut */
    1360                 :             :             /* output this (current) equivalence as '*', that is, same as tautomeric */
    1361                 :             :             /* that was printed on the 1st pass. */
    1362                 :           0 :             pCurrEquStr = EquString( eq2taut );
    1363   [ #  #  #  # ]:           0 :             if (multPrevEquStr && pPrevEquStr)
    1364                 :             :             {
    1365   [ #  #  #  # ]:           0 :                 if (pCurrEquStr && !strcmp( pCurrEquStr, pPrevEquStr ))
    1366                 :             :                 {
    1367                 :           0 :                     multPrevEquStr++;
    1368                 :             :                 }
    1369                 :             :                 else
    1370                 :             :                 {
    1371                 :             :                     /* new EqStr is different; output it */
    1372         [ #  # ]:           0 :                     if (bNext++)
    1373                 :             :                     {
    1374                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    1375                 :             :                     }
    1376                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    1377                 :           0 :                     pPrevEquStr = pCurrEquStr;
    1378                 :           0 :                     multPrevEquStr = 1;
    1379                 :             :                 }
    1380                 :             :             }
    1381                 :             :             else
    1382                 :             :             {
    1383                 :           0 :                 pPrevEquStr = pCurrEquStr;
    1384                 :           0 :                 multPrevEquStr = 1;
    1385                 :             :             }
    1386                 :           0 :             pINChI_Prev = NULL; /* pINChI_Prev isotopic info does not exist since */
    1387                 :           0 :             pINChI_Taut_Prev = NULL; /* pINChI has just been printed */
    1388                 :           0 :             mult = 0;
    1389                 :           0 :             eq2tautPrev = 1;     /* pINChI_Prev isotopic info does not exist */
    1390                 :             :         }
    1391                 :             :         else
    1392         [ #  # ]:           0 :             if (eq2tautPrev)
    1393                 :             :             {
    1394                 :             :                 /* at this point pINChI_Prev does not exist; however, pINChI */
    1395                 :             :                 /* might have been discovered and it is different from pINChI_Taut */
    1396   [ #  #  #  # ]:           0 :                 if (multPrevEquStr && pPrevEquStr)
    1397                 :             :                 {
    1398                 :             :                     /* new EqStr is different; output it */
    1399         [ #  # ]:           0 :                     if (bNext++)
    1400                 :             :                     {
    1401                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    1402                 :             :                     }
    1403                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    1404                 :           0 :                     pPrevEquStr = NULL;
    1405                 :           0 :                     multPrevEquStr = 0;
    1406                 :             :                 }
    1407                 :           0 :                 eq2tautPrev = 0;
    1408                 :           0 :                 pINChI_Prev = pINChI;
    1409                 :           0 :                 pINChI_Taut_Prev = pINChI_Taut;
    1410                 :           0 :                 mult = 0;
    1411                 :             :             }
    1412                 :             :             else
    1413                 :             :             {
    1414                 :             :                 /*================ compare iso composition to previous =====================*/
    1415                 :             :                 /* check whether pINChI and pINChI_Prev have non-zero identical isotopic info */
    1416   [ #  #  #  # ]:           0 :                 eq2prev = bUseMulipliers && Eql_INChI_Isotopic( pINChI, pINChI_Prev );
    1417         [ #  # ]:           0 :                 if (eq2prev)
    1418                 :             :                 {
    1419                 :           0 :                     mult++; /* mult = (number of non-empty equal items)-1 */
    1420                 :           0 :                     continue;
    1421                 :             :                 }
    1422                 :             :                 else
    1423                 :             :                 {
    1424                 :             :                     /* pINChI isotopic info is either different or empty. Output pINChI_Prev anyway */
    1425         [ #  # ]:           0 :                     if (bNext++)
    1426                 :             :                     {
    1427                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    1428                 :             :                     }
    1429   [ #  #  #  # ]:           0 :                     if (pINChI_Prev && pINChI_Prev->nNumberOfAtoms)
    1430                 :             :                     {
    1431         [ #  # ]:           0 :                         if (( pINChI_Prev->nNumberOfIsotopicAtoms > 0 ||
    1432         [ #  # ]:           0 :                               pINChI_Prev->nNumberOfIsotopicTGroups > 0 ))
    1433                 :             :                         {
    1434                 :             :                             /* pINChI_Prev exists and has isotopic info */
    1435                 :           0 :                             MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
    1436                 :             :                             /*  Isotopic atoms */
    1437         [ #  # ]:           0 :                             if (pINChI_Prev->nNumberOfIsotopicAtoms > 0 &&
    1438                 :             :                                 /*nStrLen-tot_len > 2 && */
    1439         [ #  # ]:           0 :                                 !*bOverflow)
    1440                 :             :                             {
    1441                 :           0 :                                 MakeIsoAtomString( pINChI_Prev->IsotopicAtom,
    1442                 :             :                                     pINChI_Prev->nNumberOfIsotopicAtoms,
    1443                 :             :                                     strbuf, TAUT_MODE, bOverflow );
    1444                 :             :                             }
    1445                 :             :                             /*  Isotopic tautomeric groups */
    1446         [ #  # ]:           0 :                             if (pINChI_Prev->nNumberOfIsotopicTGroups > 0 &&
    1447                 :             :                                 /*nStrLen-tot_len > 3 && */
    1448         [ #  # ]:           0 :                                 !*bOverflow)
    1449                 :             :                             {
    1450         [ #  # ]:           0 :                                 MakeDelim( bAbcNumbers ? ITEM_DELIMETER : "(", strbuf, bOverflow );
    1451                 :           0 :                                 MakeIsoTautString( pINChI_Prev->IsotopicTGroup, pINChI_Prev->nNumberOfIsotopicTGroups,
    1452                 :             :                                     strbuf, TAUT_MODE, bOverflow );
    1453         [ #  # ]:           0 :                                 if (!bAbcNumbers)
    1454                 :             :                                 {
    1455                 :           0 :                                     MakeDelim( ")", strbuf, bOverflow );
    1456                 :             :                                 }
    1457                 :             :                             }
    1458                 :             :                         }
    1459                 :             :                         /* else isotopic info is not present in pINChI_Prev */
    1460                 :             :                     }
    1461                 :             :                     else
    1462                 :             :                     {
    1463   [ #  #  #  #  :           0 :                         if (bSecondNonTautPass && pINChI_Taut_Prev && pINChI_Taut_Prev->nNumberOfAtoms)
                   #  # ]
    1464                 :             :                         {
    1465         [ #  # ]:           0 :                             if (( pINChI_Taut_Prev->nNumberOfIsotopicAtoms > 0 ||
    1466                 :           0 :                                   pINChI_Taut_Prev->nNumberOfIsotopicTGroups > 0 ))
    1467                 :             :                             {
    1468                 :             :                                 /* since pINChI_Prev does not exist, pINChI_Taut_Prev is non-tautomeric */
    1469                 :             :                                 /* and it has non-trivial isotopic info */
    1470                 :             :                                 /*
    1471                 :             :                                 tot_len += MakeDelim( sIdenticalValues, strbuf, bOverflow);
    1472                 :             :                                 */
    1473                 :             :                                 ;/* pINChI_Taut_Prev isotopic info was output in the main isotopic section */
    1474                 :             :                             }
    1475                 :             :                             else
    1476                 :             :                             {
    1477                 :             :                                 ; /* pINChI_Taut_Prev exists and has not isotopic info */
    1478                 :             :                             }
    1479                 :             :                         }
    1480                 :             : #if ( bRELEASE_VERSION != 1 && defined(_DEBUG) )
    1481                 :             :                         else
    1482                 :             :                         {
    1483                 :             :                             int stop = 1;   /* <BRKPT> */
    1484                 :             :                         }
    1485                 :             : #endif
    1486                 :             :                     }
    1487                 :             :                 }
    1488                 :             :                 /* Fix17: moved here 2004-10-08 */
    1489                 :           0 :                 pINChI_Prev = pINChI;
    1490                 :           0 :                 pINChI_Taut_Prev = pINChI_Taut;
    1491                 :           0 :                 mult = 0; /* we do not know whether the item is empty */
    1492                 :             :             }
    1493                 :             :         /* Fix17: moved from here 2004-10-08
    1494                 :             :         pINChI_Prev = pINChI;
    1495                 :             :         pINChI_Taut_Prev = pINChI_Taut;
    1496                 :             :         mult = 0;
    1497                 :             :         */
    1498                 :             :     }
    1499                 :             : 
    1500                 :           0 :     return ( strbuf->nUsedLength - nUsedLength0 );
    1501                 :             : }
    1502                 :             : 
    1503                 :             : 
    1504                 :             : /****************************************************************************
    1505                 :             :   Produce isotopic-dbonds stereo substring of the whole structure InChI string.
    1506                 :             : ****************************************************************************/
    1507                 :           0 : int str_IsoSp2( INCHI_SORT       *pINChISort,
    1508                 :             :                 INCHI_SORT       *pINChISort2,
    1509                 :             :                 INCHI_IOS_STRING *strbuf,
    1510                 :             :                 int              *bOverflow,
    1511                 :             :                 int              bOutType,
    1512                 :             :                 int              TAUT_MODE,
    1513                 :             :                 int              num_components,
    1514                 :             :                 int              bSecondNonTautPass,
    1515                 :             :                 int              bOmitRepetitions,
    1516                 :             :                 int              bUseMulipliers )
    1517                 :             : {
    1518                 :             :     int          i, ii, ii2, nUsedLength0;
    1519                 :             :     INCHI_SORT   *is, *is2, *is0, *is20;
    1520                 :             :     INChI        *pINChI, *pINChI_Prev, *pINChI_Taut, *pINChI_Taut_Prev;
    1521                 :             :     INChI_Stereo *Stereo, *Stereo_Prev, *Stereo_Taut, *Stereo_Taut_Prev;
    1522                 :           0 :     int          mult, eq2prev, eq2taut, eq2tautPrev = 1, bNext; /* djb-rwth: initialisation required to avoid garbage values */
    1523                 :             :     const char  *pPrevEquStr, *pCurrEquStr;
    1524                 :             :     int         multPrevEquStr;
    1525                 :           0 :     pINChI_Taut = NULL;
    1526                 :           0 :     pINChI_Prev = NULL;
    1527                 :           0 :     pINChI_Taut_Prev = NULL;
    1528                 :           0 :     mult = 0;
    1529                 :           0 :     bNext = 0;
    1530                 :           0 :     is = NULL;
    1531                 :           0 :     is2 = NULL;
    1532                 :           0 :     is0 = pINChISort;
    1533         [ #  # ]:           0 :     is20 = bSecondNonTautPass ? pINChISort2 : NULL;
    1534                 :             :     /* djb-rwth: removing redundant code */
    1535                 :           0 :     pPrevEquStr = NULL; /*, *pCurrEquStr;*/
    1536                 :           0 :     multPrevEquStr = 0;
    1537                 :           0 :     nUsedLength0 = strbuf->nUsedLength;
    1538                 :             : 
    1539                 :             :     /* For each connected component...    */
    1540         [ #  # ]:           0 :     for (i = 0; i <= num_components; i++)
    1541                 :             :     {
    1542                 :             :         /* 1st (taut) pass: bOutType=OUT_TN  ; 2nd (non-taut pass) bOutType=OUT_NT */
    1543   [ #  #  #  #  :           0 :         pINChI = ( i < num_components && ( is = is0 + i, 0 <= ( ii = GET_II( bOutType, is ) ) ) ) ? is->pINChI[ii] : NULL;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    1544                 :             :         /*================ compare sp2 to previous =====================*/
    1545         [ #  # ]:           0 :         if (bSecondNonTautPass)
    1546                 :             :         {
    1547                 :             :             /* component that was output on the 1st pass */
    1548   [ #  #  #  #  :           0 :             pINChI_Taut = ( i < num_components && ( is2 = is20 + i, 0 <= ( ii2 = GET_II( OUT_T1, is2 ) ) ) ) ? is2->pINChI[ii2] : NULL;
          #  #  #  #  #  
                #  #  # ]
    1549                 :             :         }
    1550                 :           0 :         eq2taut = 0;
    1551                 :             :         /*========= if bSecondNonTautPass then compare iso non-taut stereo to other stereo ========*/
    1552   [ #  #  #  # ]:           0 :         if (bSecondNonTautPass && bOmitRepetitions)
    1553                 :             :         {
    1554                 :             :             /* compare non-tautomeric isotopic to:
    1555                 :             :             *   a) non-tautomeric non-isotopic
    1556                 :             :             *   b) tautomeric non-isotopic
    1557                 :             :             *   c) tautomeric isotopic
    1558                 :             :             */
    1559                 :             :             /* a) compare non-tautomeric isotopic to non-tautomeric non-isotopic */
    1560         [ #  # ]:           0 :             if (!eq2taut)
    1561                 :             :             {
    1562                 :           0 :                 eq2taut = pINChI &&
    1563                 :             :                     /* non-taut isotopic */                  /* non-taut non-isotopic */
    1564   [ #  #  #  #  :           0 :                     ( Stereo = pINChI->StereoIsotopic ) && ( Stereo_Taut = pINChI->Stereo ) &&
             #  #  #  # ]
    1565                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP2, Stereo_Taut, EQL_SP2, 0 );
    1566                 :             :                 /* stereo     isotopic non-taut =  non-taut (stereo) */
    1567         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO | iitISO | iitNONTAUT | iiEq2NONTAUT ) : 0;
    1568                 :             :             }
    1569                 :             :             /* b) compare non-tautomeric isotopic to tautomeric non-isotopic */
    1570         [ #  # ]:           0 :             if (!eq2taut)
    1571                 :             :             {
    1572         [ #  # ]:           0 :                 eq2taut = pINChI && pINChI_Taut &&
    1573                 :             :                     /* non-taut isotopic */                  /* taut non-isotopic */
    1574   [ #  #  #  #  :           0 :                     ( Stereo = pINChI->StereoIsotopic ) && ( Stereo_Taut = pINChI_Taut->Stereo ) &&
             #  #  #  # ]
    1575                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP2, Stereo_Taut, EQL_SP2, 0 );
    1576                 :             :                 /* stereo     isotopic non-taut =  taut (stereo) */
    1577         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO | iitISO | iitNONTAUT ) : 0;
    1578                 :             :             }
    1579                 :             :             /* c) compare non-tautomeric isotopic to tautomeric isotopic */
    1580   [ #  #  #  #  :           0 :             if (!eq2taut && bSecondNonTautPass && bOmitRepetitions)
                   #  # ]
    1581                 :             :             {
    1582         [ #  # ]:           0 :                 eq2taut = pINChI && pINChI_Taut &&
    1583   [ #  #  #  #  :           0 :                     ( Stereo = pINChI->StereoIsotopic ) && ( Stereo_Taut = pINChI_Taut->StereoIsotopic ) &&
             #  #  #  # ]
    1584                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP2, Stereo_Taut, EQL_SP2, 0 );
    1585                 :             :                 /* stereo     isotopic non-taut =  isotopic taut (stereo) */
    1586         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO | iitISO | iitNONTAUT | iiEq2ISO ) : 0;
    1587                 :             :             }
    1588                 :             : #if ( FIX_EMPTY_LAYER_BUG == 1 )
    1589                 :             :             if (!eq2taut && pINChI && !( ( Stereo = pINChI->StereoIsotopic ) &&
    1590                 :             :                 Eql_INChI_Stereo( Stereo, EQL_SP2, NULL, EQL_EXISTS, 0 ) ))
    1591                 :             :             {
    1592                 :             :                 /* component has no stereo; check whether it has stereo in the preceding layers */
    1593                 :             :                 if (pINChI_Taut && ( Stereo_Taut = pINChI_Taut->Stereo ) && /* F is not empty */
    1594                 :             :                     Eql_INChI_Stereo( Stereo_Taut, EQL_SP2, NULL, EQL_EXISTS, 0 ) ||
    1595                 :             :                     !( pINChI_Taut && ( Stereo_Taut = pINChI_Taut->Stereo ) &&  /* M is empty and ... */
    1596                 :             :                         Eql_INChI_Stereo( Stereo_Taut, EQL_SP2, NULL, EQL_EXISTS, 0 ) ) &&
    1597                 :             :                         ( pINChI_Taut && ( Stereo_Taut = pINChI_Taut->StereoIsotopic ) &&  /* ... MI is not empty */
    1598                 :             :                             Eql_INChI_Stereo( Stereo_Taut, EQL_SP2, NULL, EQL_EXISTS, 0 ) ))
    1599                 :             :                 {
    1600                 :             : 
    1601                 :             :                     eq2taut = iiEmpty; /* the component has stereo in the preceding layer  */
    1602                 :             :                 }
    1603                 :             :             }
    1604                 :             : #endif
    1605                 :             :         }
    1606                 :             :         else
    1607                 :             :         {
    1608                 :             :             /*========= if not bSecondNonTautPass then compare iso taut stereo to non-iso taut ========*/
    1609   [ #  #  #  # ]:           0 :             if (!bSecondNonTautPass && bOmitRepetitions)
    1610                 :             :             {
    1611                 :             :                 /* compare tautomeric isotopic to tautomeric non-isotopic */
    1612         [ #  # ]:           0 :                 if (!eq2taut)
    1613                 :             :                 {
    1614                 :           0 :                     eq2taut = pINChI &&
    1615                 :             :                         /* taut isotopic */                  /* taut non-isotopic */
    1616   [ #  #  #  #  :           0 :                         ( Stereo = pINChI->StereoIsotopic ) && ( Stereo_Taut = pINChI->Stereo ) &&
             #  #  #  # ]
    1617                 :           0 :                         Eql_INChI_Stereo( Stereo, EQL_SP2, Stereo_Taut, EQL_SP2, 0 );
    1618                 :             :                     /* stereo     isotopic taut =  taut (stereo) */
    1619         [ #  # ]:           0 :                     eq2taut = eq2taut ? ( iiSTEREO | iitISO ) : 0;
    1620                 :             : #if ( FIX_EMPTY_LAYER_BUG == 1 )
    1621                 :             :                     if (!eq2taut && pINChI && !( ( Stereo = pINChI->StereoIsotopic ) &&
    1622                 :             :                                                  Eql_INChI_Stereo( Stereo, EQL_SP2, NULL, EQL_EXISTS, 0 ) ))
    1623                 :             :                     {
    1624                 :             :                         /* component has no MI stereo; check whether it has stereo in the preceding layer M */
    1625                 :             :                         if (( Stereo_Taut = pINChI->Stereo ) &&
    1626                 :             :                             Eql_INChI_Stereo( Stereo_Taut, EQL_SP2, NULL, EQL_EXISTS, 0 ))
    1627                 :             :                         {
    1628                 :             :                             eq2taut = iiEmpty; /* the component has stereo in the preceding layer  */
    1629                 :             :                         }
    1630                 :             :                     }
    1631                 :             : #endif
    1632                 :             :                 }
    1633                 :             :             }
    1634                 :             :         }
    1635         [ #  # ]:           0 :         if (eq2taut)
    1636                 :             :         {
    1637                 :             :             /* we may be here only in case of the current layer found equal in another layer the same component */
    1638   [ #  #  #  # ]:           0 :             if (pINChI_Prev && pINChI_Prev->nNumberOfAtoms)
    1639                 :             :             {
    1640                 :             :                 /* previous component exists; output it before output the current component */
    1641         [ #  # ]:           0 :                 if (bNext++)
    1642                 :             :                 {
    1643                 :           0 :                     MakeDelim( sCompDelim, strbuf, bOverflow );
    1644                 :             :                 }
    1645   [ #  #  #  # ]:           0 :                 if (( Stereo_Prev = pINChI_Prev->StereoIsotopic ) && Stereo_Prev->nNumberOfStereoBonds > 0)
    1646                 :             :                 {
    1647                 :           0 :                     MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
    1648                 :             : 
    1649                 :           0 :                     MakeStereoString( Stereo_Prev->nBondAtom1, Stereo_Prev->nBondAtom2,
    1650                 :             :                         Stereo_Prev->b_parity,
    1651                 :             :                         0, Stereo_Prev->nNumberOfStereoBonds,
    1652                 :             :                         strbuf, TAUT_MODE, bOverflow );
    1653                 :             :                 }
    1654                 :             :             }
    1655                 :             :             else
    1656                 :             :             {
    1657   [ #  #  #  # ]:           0 :                 if (pINChI_Taut_Prev && pINChI_Taut_Prev->nNumberOfAtoms)
    1658                 :             :                 {
    1659                 :             :                     /* previous non-taut component exists only in taut list */
    1660         [ #  # ]:           0 :                     if (bNext++)
    1661                 :             :                     {
    1662                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    1663                 :             :                     }
    1664                 :             :                     /* do not output stereo of non-tautomeric in non-taut layer: it has been output in the main layer */
    1665                 :             :                 }
    1666                 :             :             }
    1667                 :             :             /* we have found another (previously printed) layer of the current component equal to this layer */
    1668                 :             :             /* output this (current) equivalence mark = EquString(eq2taut) */
    1669                 :           0 :             pCurrEquStr = EquString( eq2taut );
    1670   [ #  #  #  # ]:           0 :             if (multPrevEquStr && pPrevEquStr)
    1671                 :             :             {
    1672   [ #  #  #  # ]:           0 :                 if (pCurrEquStr && !strcmp( pCurrEquStr, pPrevEquStr ))
    1673                 :             :                 {
    1674                 :           0 :                     multPrevEquStr++;
    1675                 :             :                 }
    1676                 :             :                 else
    1677                 :             :                 {
    1678                 :             :                     /* new EqStr is different; output it */
    1679         [ #  # ]:           0 :                     if (bNext++)
    1680                 :             :                     {
    1681                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    1682                 :             :                     }
    1683                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    1684                 :           0 :                     pPrevEquStr = pCurrEquStr;
    1685                 :           0 :                     multPrevEquStr = 1;
    1686                 :             :                 }
    1687                 :             :             }
    1688                 :             :             else
    1689                 :             :             {
    1690                 :           0 :                 pPrevEquStr = pCurrEquStr;
    1691                 :           0 :                 multPrevEquStr = 1;
    1692                 :             :             }
    1693                 :           0 :             pINChI_Prev = NULL; /* pINChI_Prev sp2 does not exist since */
    1694                 :           0 :             pINChI_Taut_Prev = NULL; /* pINChI has just been printed */
    1695                 :           0 :             mult = 0;
    1696                 :           0 :             eq2tautPrev = 1;     /* pINChI_Prev and pINChI_Taut_Prev have already been */
    1697                 :             :         }
    1698                 :             :         else
    1699                 :             :         {
    1700         [ #  # ]:           0 :             if (eq2tautPrev)
    1701                 :             :             {
    1702                 :             :                 /* at this point pINChI_Prev does not exist; however, pINChI */
    1703                 :             :                 /*might have been discovered and it is different from pINChI_Taut */
    1704   [ #  #  #  # ]:           0 :                 if (multPrevEquStr && pPrevEquStr)
    1705                 :             :                 {
    1706                 :             :                     /* new EqStr is different; output it */
    1707         [ #  # ]:           0 :                     if (bNext++)
    1708                 :             :                     {
    1709                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    1710                 :             :                     }
    1711                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    1712                 :           0 :                     pPrevEquStr = NULL;
    1713                 :           0 :                     multPrevEquStr = 0;
    1714                 :             :                 }
    1715                 :           0 :                 eq2tautPrev = 0;
    1716                 :           0 :                 pINChI_Prev = pINChI;
    1717                 :           0 :                 pINChI_Taut_Prev = pINChI_Taut;
    1718                 :           0 :                 mult = 0;
    1719                 :             :             }
    1720                 :             :             else
    1721                 :             :             {
    1722                 :             :                 /* current layer is different from previously printed layers of the current component */
    1723                 :             :                 /* compare the current layer to this layer of the previous component: */
    1724                 :             :                 /* check whether pINChI and pINChI_Prev have non-zero identical stereo sp2 */
    1725                 :             :                 /*================ compare iso sp2 to previous =====================*/
    1726         [ #  # ]:           0 :                 eq2prev = bUseMulipliers &&
    1727         [ #  # ]:           0 :                     pINChI && pINChI_Prev &&
    1728   [ #  #  #  #  :           0 :                     ( Stereo = pINChI->StereoIsotopic ) && ( Stereo_Prev = pINChI_Prev->StereoIsotopic ) &&
             #  #  #  # ]
    1729                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP2, Stereo_Prev, EQL_SP2, 0 );
    1730         [ #  # ]:           0 :                 if (eq2prev)
    1731                 :             :                 {
    1732                 :           0 :                     mult++; /* mult = (number of non-empty equal items)-1 */
    1733                 :           0 :                     continue;
    1734                 :             :                 }
    1735                 :             :                 else
    1736                 :             :                 {
    1737                 :             :                     /* the current layer is different from this layer of the previous component */
    1738                 :             :                     /* therefore print the current layer */
    1739         [ #  # ]:           0 :                     if (bNext++)
    1740                 :             :                     {
    1741                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    1742                 :             :                     }
    1743   [ #  #  #  # ]:           0 :                     if (pINChI_Prev && pINChI_Prev->nNumberOfAtoms)
    1744                 :             :                     {
    1745   [ #  #  #  # ]:           0 :                         if (( Stereo_Prev = pINChI_Prev->StereoIsotopic ) && Stereo_Prev->nNumberOfStereoBonds > 0)
    1746                 :             :                         {
    1747                 :           0 :                             MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
    1748                 :             : 
    1749                 :           0 :                             MakeStereoString( Stereo_Prev->nBondAtom1, Stereo_Prev->nBondAtom2,
    1750                 :             :                                 Stereo_Prev->b_parity,
    1751                 :             :                                 0, Stereo_Prev->nNumberOfStereoBonds,
    1752                 :             :                                 strbuf, TAUT_MODE, bOverflow );
    1753                 :             :                         }
    1754                 :             :                         /* else sp2 info is not present in pINChI_Prev */
    1755                 :             :                     }
    1756                 :             :                     else
    1757                 :             :                     {/* do not print pINChI_Prev because it either do not exist of have already been printed */
    1758   [ #  #  #  #  :           0 :                         if (bSecondNonTautPass && pINChI_Taut_Prev && pINChI_Taut_Prev->nNumberOfAtoms)
                   #  # ]
    1759                 :             :                         {
    1760         [ #  # ]:           0 :                             if (( Stereo_Taut_Prev = pINChI_Taut_Prev->StereoIsotopic ) && Stereo_Taut_Prev->nNumberOfStereoBonds > 0)
    1761                 :             :                             {
    1762                 :             :                                 /* since pINChI_Prev does not exist, pINChI_Taut_Prev is non-tautomeric */
    1763                 :             :                                 /* and it has non-trivial sp2 info */
    1764                 :             :                                 /*
    1765                 :             :                                 tot_len += MakeDelim( sIdenticalValues, strbuf, bOverflow);
    1766                 :             :                                 */
    1767                 :             :                                 ;/* pINChI_Taut_Prev sp3 info was output in the main stereo section */
    1768                 :             :                             }
    1769                 :             :                             else
    1770                 :             :                             {
    1771                 :             :                                 ; /* pINChI_Taut_Prev exists and has not sp2 info */
    1772                 :             :                             }
    1773                 :             :                         }
    1774                 :             : #if ( bRELEASE_VERSION != 1 && defined(_DEBUG) )
    1775                 :             :                         else
    1776                 :             :                         {
    1777                 :             :                             int stop = 1;   /* <BRKPT> */
    1778                 :             :                         }
    1779                 :             : #endif
    1780                 :             :                     }
    1781                 :             :                 }
    1782                 :           0 :                 pINChI_Prev = pINChI;
    1783                 :           0 :                 pINChI_Taut_Prev = pINChI_Taut;
    1784                 :           0 :                 mult = 0; /* we do not know whether the item is empty */
    1785                 :             :             }
    1786                 :             :         }
    1787                 :             :     }
    1788                 :             : 
    1789                 :           0 :     return ( strbuf->nUsedLength - nUsedLength0 );
    1790                 :             : }
    1791                 :             : 
    1792                 :             : 
    1793                 :             : /****************************************************************************
    1794                 :             :   Produce isotopic-tetr stereo substring of the whole structure InChI string.
    1795                 :             : ****************************************************************************/
    1796                 :           0 : int str_IsoSp3( INCHI_SORT       *pINChISort,
    1797                 :             :                 INCHI_SORT       *pINChISort2,
    1798                 :             :                 INCHI_IOS_STRING *strbuf,
    1799                 :             :                 int              *bOverflow,
    1800                 :             :                 int              bOutType,
    1801                 :             :                 int              TAUT_MODE,
    1802                 :             :                 int              num_components,
    1803                 :             :                 int              bRelRac,
    1804                 :             :                 int              bSecondNonTautPass,
    1805                 :             :                 int              bOmitRepetitions,
    1806                 :             :                 int              bUseMulipliers )
    1807                 :             : {
    1808                 :             :     int          i, ii, ii2, nUsedLength0;
    1809                 :             :     INCHI_SORT   *is, *is2, *is0, *is20;
    1810                 :             :     INChI        *pINChI, *pINChI_Prev, *pINChI_Taut, *pINChI_Taut_Prev;
    1811                 :             :     INChI_Stereo *Stereo, *Stereo_Prev, *Stereo_Taut, *Stereo_Taut_Prev;
    1812                 :             :     int          mult, eq2prev, eq2taut, eq2tautPrev, bNext;
    1813                 :             :     const char  *pPrevEquStr, *pCurrEquStr;
    1814                 :             :     int         multPrevEquStr;
    1815                 :           0 :     pINChI_Taut = NULL;
    1816                 :           0 :     pINChI_Prev = NULL;
    1817                 :           0 :     pINChI_Taut_Prev = NULL;
    1818                 :           0 :     mult = 0;
    1819                 :           0 :     bNext = 0;
    1820                 :           0 :     is = NULL;
    1821                 :           0 :     is2 = NULL;
    1822                 :           0 :     is0 = pINChISort;
    1823         [ #  # ]:           0 :     is20 = bSecondNonTautPass ? pINChISort2 : NULL;
    1824                 :             :     /* djb-rwth: removing redundant code */
    1825                 :           0 :     eq2tautPrev = 1; /* pINChI_Prev (previous pINChI) does not exist */
    1826                 :           0 :     pPrevEquStr = NULL; /*, *pCurrEquStr;*/
    1827                 :           0 :     multPrevEquStr = 0;
    1828                 :             : #if ( REL_RAC_STEREO_IGN_1_SC == 1 )
    1829                 :             : #else
    1830                 :           0 :     bRelRac = 0;
    1831                 :             : #endif
    1832                 :           0 :     nUsedLength0 = strbuf->nUsedLength;
    1833                 :             : 
    1834                 :             :     /* For each connected component...    */
    1835         [ #  # ]:           0 :     for (i = 0; i <= num_components; i++)
    1836                 :             :     {
    1837                 :             : 
    1838                 :             :         /* 1st (taut) pass: bOutType=OUT_TN  ; 2nd (non-taut pass) bOutType=OUT_NT */
    1839   [ #  #  #  #  :           0 :         pINChI = ( i < num_components && ( is = is0 + i, 0 <= ( ii = GET_II( bOutType, is ) ) ) ) ? is->pINChI[ii] : NULL;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    1840                 :             :         /*================ compare sp2 to previous =====================*/
    1841         [ #  # ]:           0 :         if (bSecondNonTautPass)
    1842                 :             :         {
    1843                 :             :             /* component that was output on the 1st pass */
    1844   [ #  #  #  #  :           0 :             pINChI_Taut = ( i < num_components && ( is2 = is20 + i, 0 <= ( ii2 = GET_II( OUT_T1, is2 ) ) ) ) ? is2->pINChI[ii2] : NULL;
          #  #  #  #  #  
                #  #  # ]
    1845                 :             :         }
    1846                 :           0 :         eq2taut = 0;
    1847                 :             :         /*========= if bSecondNonTautPass then compare iso non-taut stereo to other stereo ========*/
    1848   [ #  #  #  # ]:           0 :         if (bSecondNonTautPass && bOmitRepetitions)
    1849                 :             :         {
    1850                 :             :             /* compare non-tautomeric isotopic to:
    1851                 :             :             *   a) non-tautomeric non-isotopic
    1852                 :             :             *   b) tautomeric non-isotopic
    1853                 :             :             *   c) tautomeric isotopic
    1854                 :             :             */
    1855                 :             :             /* a) compare non-tautomeric isotopic to non-tautomeric non-isotopic */
    1856         [ #  # ]:           0 :             if (!eq2taut)
    1857                 :             :             {
    1858                 :           0 :                 eq2taut = pINChI && /* non-taut isotopic */                  /* non-taut non-isotopic */
    1859   [ #  #  #  #  :           0 :                     ( Stereo = pINChI->StereoIsotopic ) && ( Stereo_Taut = pINChI->Stereo ) &&
             #  #  #  # ]
    1860                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP3, Stereo_Taut, EQL_SP3, bRelRac );
    1861                 :             :                 /* stereo     isotopic non-taut =  non-taut (stereo) */
    1862         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO | iitISO | iitNONTAUT | iiEq2NONTAUT ) : 0;
    1863                 :             :             }
    1864                 :             :             /* b) compare non-tautomeric isotopic to tautomeric non-isotopic */
    1865         [ #  # ]:           0 :             if (!eq2taut)
    1866                 :             :             {
    1867         [ #  # ]:           0 :                 eq2taut = pINChI && pINChI_Taut &&
    1868                 :             :                     /* non-taut isotopic */                  /* taut non-isotopic */
    1869   [ #  #  #  #  :           0 :                     ( Stereo = pINChI->StereoIsotopic ) && ( Stereo_Taut = pINChI_Taut->Stereo ) &&
             #  #  #  # ]
    1870                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP3, Stereo_Taut, EQL_SP3, bRelRac );
    1871                 :             :                 /* stereo     isotopic non-taut =  taut (stereo) */
    1872         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO | iitISO | iitNONTAUT ) : 0;
    1873                 :             :             }
    1874                 :             :             /* c) compare non-tautomeric isotopic to tautomeric isotopic */
    1875   [ #  #  #  #  :           0 :             if (!eq2taut && bSecondNonTautPass && bOmitRepetitions)
                   #  # ]
    1876                 :             :             {
    1877         [ #  # ]:           0 :                 eq2taut = pINChI && pINChI_Taut &&
    1878   [ #  #  #  #  :           0 :                     ( Stereo = pINChI->StereoIsotopic ) && ( Stereo_Taut = pINChI_Taut->StereoIsotopic ) &&
             #  #  #  # ]
    1879                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP3, Stereo_Taut, EQL_SP3, bRelRac );
    1880                 :             :                 /* stereo     isotopic non-taut =  isotopic taut (stereo) */
    1881         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO | iitISO | iitNONTAUT | iiEq2ISO ) : 0;
    1882                 :             :             }
    1883                 :             : #if ( FIX_EMPTY_LAYER_BUG == 1 )
    1884                 :             :             if (!eq2taut && pINChI && !( ( Stereo = pINChI->StereoIsotopic ) &&
    1885                 :             :                 Eql_INChI_Stereo( Stereo, EQL_SP3, NULL, EQL_EXISTS, 0 ) ))
    1886                 :             :             {
    1887                 :             :                 /* component has no stereo; check whether it has stereo in the preceding layers */
    1888                 :             :                 if (pINChI_Taut && ( Stereo_Taut = pINChI_Taut->Stereo ) && /* F is not empty */
    1889                 :             :                     Eql_INChI_Stereo( Stereo_Taut, EQL_SP3, NULL, EQL_EXISTS, 0 ) ||
    1890                 :             :                     !( pINChI_Taut && ( Stereo_Taut = pINChI_Taut->Stereo ) &&  /* M is empty and ... */
    1891                 :             :                         Eql_INChI_Stereo( Stereo_Taut, EQL_SP3, NULL, EQL_EXISTS, 0 ) ) &&
    1892                 :             :                         ( pINChI_Taut && ( Stereo_Taut = pINChI_Taut->StereoIsotopic ) &&  /* ... MI is not empty */
    1893                 :             :                             Eql_INChI_Stereo( Stereo_Taut, EQL_SP3, NULL, EQL_EXISTS, 0 ) ))
    1894                 :             :                 {
    1895                 :             : 
    1896                 :             :                     eq2taut = iiEmpty; /* the component has stereo in the preceding layer  */
    1897                 :             :                 }
    1898                 :             :             }
    1899                 :             : #endif
    1900                 :             :         }
    1901                 :             :         else
    1902                 :             :         {
    1903                 :             :             /*========= if not bSecondNonTautPass then compare iso taut stereo to non-iso taut ========*/
    1904   [ #  #  #  # ]:           0 :             if (!bSecondNonTautPass && bOmitRepetitions)
    1905                 :             :             {
    1906                 :             :                 /* compare tautomeric isotopic to tautomeric non-isotopic */
    1907         [ #  # ]:           0 :                 if (!eq2taut)
    1908                 :             :                 {
    1909                 :           0 :                     eq2taut = pINChI &&
    1910                 :             :                         /* taut isotopic */                  /* taut non-isotopic */
    1911   [ #  #  #  #  :           0 :                         ( Stereo = pINChI->StereoIsotopic ) && ( Stereo_Taut = pINChI->Stereo ) &&
             #  #  #  # ]
    1912                 :           0 :                         Eql_INChI_Stereo( Stereo, EQL_SP3, Stereo_Taut, EQL_SP3, bRelRac );
    1913                 :             :                     /* stereo     isotopic taut =  taut (stereo) */
    1914         [ #  # ]:           0 :                     eq2taut = eq2taut ? ( iiSTEREO | iitISO ) : 0;
    1915                 :             : #if ( FIX_EMPTY_LAYER_BUG == 1 )
    1916                 :             :                     if (!eq2taut && pINChI && !( ( Stereo = pINChI->StereoIsotopic ) &&
    1917                 :             :                                                  Eql_INChI_Stereo( Stereo, EQL_SP3, NULL, EQL_EXISTS, 0 ) ))
    1918                 :             :                     {
    1919                 :             :                         /* component has no MI stereo; check whether it has stereo in the preceding layer M */
    1920                 :             :                         if (( Stereo_Taut = pINChI->Stereo ) &&
    1921                 :             :                             Eql_INChI_Stereo( Stereo_Taut, EQL_SP3, NULL, EQL_EXISTS, 0 ))
    1922                 :             :                         {
    1923                 :             :                             eq2taut = iiEmpty; /* the component has stereo in the preceding layer  */
    1924                 :             :                         }
    1925                 :             :                     }
    1926                 :             : #endif
    1927                 :             :                 }
    1928                 :             :             }
    1929                 :             :         }
    1930         [ #  # ]:           0 :         if (eq2taut)
    1931                 :             :         {
    1932                 :             :             /* we may be here only in case of the current layer found equal in another layer the same component */
    1933   [ #  #  #  # ]:           0 :             if (pINChI_Prev && pINChI_Prev->nNumberOfAtoms)
    1934                 :             :             {
    1935                 :             :                 /* previous component exists; output it before output the current component */
    1936         [ #  # ]:           0 :                 if (bNext++)
    1937                 :             :                 {
    1938                 :           0 :                     MakeDelim( sCompDelim, strbuf, bOverflow );
    1939                 :             :                 }
    1940   [ #  #  #  # ]:           0 :                 if (( Stereo_Prev = pINChI_Prev->StereoIsotopic ) && Stereo_Prev->nNumberOfStereoCenters > bRelRac)
    1941                 :             :                 {
    1942                 :           0 :                     MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
    1943                 :             : 
    1944                 :           0 :                     MakeStereoString( Stereo_Prev->nNumber, NULL, Stereo_Prev->t_parity,
    1945                 :             :                         0, Stereo_Prev->nNumberOfStereoCenters,
    1946                 :             :                         strbuf, TAUT_MODE, bOverflow );
    1947                 :             :                 }
    1948                 :             :             }
    1949                 :             :             else
    1950                 :             :             {
    1951   [ #  #  #  # ]:           0 :                 if (pINChI_Taut_Prev && pINChI_Taut_Prev->nNumberOfAtoms)
    1952                 :             :                 {
    1953                 :             :                     /* previous non-taut component exists only in taut list */
    1954         [ #  # ]:           0 :                     if (bNext++)
    1955                 :             :                     {
    1956                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    1957                 :             :                     }
    1958                 :             :                     /* do not output stereo of non-tautomeric in non-taut layer: it has been output in the main layer */
    1959                 :             :                 }
    1960                 :             :             }
    1961                 :             :             /* we have found another (previously printed) layer of the current component equal to this layer */
    1962                 :             :             /* output this (current) equivalence mark = EquString(eq2taut) */
    1963                 :           0 :             pCurrEquStr = EquString( eq2taut );
    1964   [ #  #  #  # ]:           0 :             if (multPrevEquStr && pPrevEquStr)
    1965                 :             :             {
    1966   [ #  #  #  # ]:           0 :                 if (pCurrEquStr && !strcmp( pCurrEquStr, pPrevEquStr ))
    1967                 :             :                 {
    1968                 :           0 :                     multPrevEquStr++;
    1969                 :             :                 }
    1970                 :             :                 else
    1971                 :             :                 {
    1972                 :             :                     /* new EqStr is different; output it */
    1973         [ #  # ]:           0 :                     if (bNext++)
    1974                 :             :                     {
    1975                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    1976                 :             :                     }
    1977                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    1978                 :           0 :                     pPrevEquStr = pCurrEquStr;
    1979                 :           0 :                     multPrevEquStr = 1;
    1980                 :             :                 }
    1981                 :             :             }
    1982                 :             :             else
    1983                 :             :             {
    1984                 :           0 :                 pPrevEquStr = pCurrEquStr;
    1985                 :           0 :                 multPrevEquStr = 1;
    1986                 :             :             }
    1987                 :           0 :             pINChI_Prev = NULL; /* pINChI_Prev sp2 does not exist since */
    1988                 :           0 :             pINChI_Taut_Prev = NULL; /* pINChI has just been printed */
    1989                 :           0 :             mult = 0;
    1990                 :           0 :             eq2tautPrev = 1;     /* pINChI_Prev and pINChI_Taut_Prev have already been output */
    1991                 :             :         }
    1992                 :             :         else
    1993                 :             :         {
    1994         [ #  # ]:           0 :             if (eq2tautPrev)
    1995                 :             :             {
    1996                 :             :                 /* at this point pINChI_Prev does not exist; however, pINChI */
    1997                 :             :                 /*might have been discovered and it is different from pINChI_Taut */
    1998   [ #  #  #  # ]:           0 :                 if (multPrevEquStr && pPrevEquStr)
    1999                 :             :                 {
    2000                 :             :                     /* new EqStr is different; output it */
    2001         [ #  # ]:           0 :                     if (bNext++)
    2002                 :             :                     {
    2003                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    2004                 :             :                     }
    2005                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    2006                 :           0 :                     pPrevEquStr = NULL;
    2007                 :           0 :                     multPrevEquStr = 0;
    2008                 :             :                 }
    2009                 :           0 :                 eq2tautPrev = 0;
    2010                 :           0 :                 pINChI_Prev = pINChI;
    2011                 :           0 :                 pINChI_Taut_Prev = pINChI_Taut;
    2012                 :           0 :                 mult = 0;
    2013                 :             :             }
    2014                 :             :             else
    2015                 :             :             {
    2016                 :             :                 /* current layer is different from previously printed layers of the current component */
    2017                 :             :                 /* compare the current layer to this layer of the previous component: */
    2018                 :             :                 /* check whether pINChI and pINChI_Prev have non-zero identical stereo sp2 */
    2019                 :             :                 /*================ compare iso sp3 to previous =====================*/
    2020   [ #  #  #  # ]:           0 :                 eq2prev = bUseMulipliers && pINChI && pINChI_Prev &&
    2021   [ #  #  #  #  :           0 :                     ( Stereo = pINChI->StereoIsotopic ) && ( Stereo_Prev = pINChI_Prev->StereoIsotopic ) &&
             #  #  #  # ]
    2022                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP3, Stereo_Prev, EQL_SP3, bRelRac );
    2023         [ #  # ]:           0 :                 if (eq2prev)
    2024                 :             :                 {
    2025                 :           0 :                     mult++; /* mult = (number of non-empty equal items)-1 */
    2026                 :           0 :                     continue;
    2027                 :             :                 }
    2028                 :             :                 else
    2029                 :             :                 {
    2030         [ #  # ]:           0 :                     if (bNext++)
    2031                 :             :                     {
    2032                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    2033                 :             :                     }
    2034   [ #  #  #  # ]:           0 :                     if (pINChI_Prev && pINChI_Prev->nNumberOfAtoms)
    2035                 :             :                     {
    2036   [ #  #  #  # ]:           0 :                         if (( Stereo_Prev = pINChI_Prev->StereoIsotopic ) && Stereo_Prev->nNumberOfStereoCenters > bRelRac)
    2037                 :             :                         {
    2038                 :           0 :                             MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
    2039                 :             : 
    2040                 :           0 :                             MakeStereoString( Stereo_Prev->nNumber, NULL, Stereo_Prev->t_parity,
    2041                 :             :                                 0, Stereo_Prev->nNumberOfStereoCenters,
    2042                 :             :                                 strbuf, TAUT_MODE, bOverflow );
    2043                 :             :                         }
    2044                 :             :                         /* else sp3 info is not present in pINChI_Prev */
    2045                 :             :                     }
    2046                 :             :                     else
    2047                 :             :                         /* do not print pINChI_Prev because it either do not exist of have already been printed */
    2048   [ #  #  #  #  :           0 :                         if (bSecondNonTautPass && pINChI_Taut_Prev && pINChI_Taut_Prev->nNumberOfAtoms)
                   #  # ]
    2049                 :             :                         {
    2050         [ #  # ]:           0 :                             if (( Stereo_Taut_Prev = pINChI_Taut_Prev->StereoIsotopic ) && Stereo_Taut_Prev->nNumberOfStereoCenters > bRelRac)
    2051                 :             :                             {
    2052                 :             :                                 /* since pINChI_Prev does not exist, pINChI_Taut_Prev is non-tautomeric */
    2053                 :             :                                 /* and it has non-trivial sp2 info */
    2054                 :             :                                 /*
    2055                 :             :                                 tot_len += MakeDelim( sIdenticalValues, strbuf, bOverflow);
    2056                 :             :                                 */
    2057                 :             :                                 ;/* pINChI_Taut_Prev sp3 info was output in the main stereo section */
    2058                 :             :                             }
    2059                 :             :                             else
    2060                 :             :                             {
    2061                 :             :                                 ; /* pINChI_Taut_Prev exists and has not sp3 info */
    2062                 :             :                             }
    2063                 :             :                         }
    2064                 :             : #if ( bRELEASE_VERSION != 1 && defined(_DEBUG) )
    2065                 :             :                         else
    2066                 :             :                         {
    2067                 :             :                             int stop = 1;   /* <BRKPT> */
    2068                 :             :                         }
    2069                 :             : #endif
    2070                 :             :                 }
    2071                 :           0 :                 pINChI_Prev = pINChI;
    2072                 :           0 :                 pINChI_Taut_Prev = pINChI_Taut;
    2073                 :           0 :                 mult = 0; /* we do not know whether the item is empty */
    2074                 :             :             }
    2075                 :             :         }
    2076                 :             :     }
    2077                 :             : 
    2078                 :           0 :     return ( strbuf->nUsedLength - nUsedLength0 );
    2079                 :             : }
    2080                 :             : 
    2081                 :             : 
    2082                 :             : /****************************************************************************
    2083                 :             :   Output isotopic abs stero inversion substring
    2084                 :             :   of the whole structure InChI string
    2085                 :             : ****************************************************************************/
    2086                 :           0 : int str_IsoStereoAbsInv( INCHI_SORT       *pINChISort,
    2087                 :             :                          INCHI_IOS_STRING *strbuf,
    2088                 :             :                          int              *bOverflow,
    2089                 :             :                          int              bOutType,
    2090                 :             :                          int              num_components )
    2091                 :             : {
    2092                 :             :     int          i, j, ii, nUsedLength0;
    2093                 :             :     INCHI_SORT   *is, *is0;
    2094                 :             :     INChI_Stereo *Stereo;
    2095                 :             :     INChI        *pINChI;
    2096                 :             : 
    2097                 :           0 :     is = NULL;
    2098                 :           0 :     is0 = pINChISort;
    2099                 :           0 :     nUsedLength0 = strbuf->nUsedLength;
    2100                 :             : 
    2101                 :             :     /* For each connected component...    */
    2102   [ #  #  #  # ]:           0 :     for (i = 0; !*bOverflow && i < num_components; i++)
    2103                 :             :     {
    2104                 :           0 :         is = is0 + i;
    2105   [ #  #  #  #  :           0 :         pINChI = ( 0 <= ( ii = GET_II( bOutType, is ) ) )
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    2106                 :             :             ? is->pINChI[ii]
    2107         [ #  # ]:           0 :             : NULL;
    2108         [ #  # ]:           0 :         if (pINChI &&
    2109         [ #  # ]:           0 :             ( Stereo = pINChI->StereoIsotopic ) &&
    2110         [ #  # ]:           0 :             ( j = Stereo->nCompInv2Abs ))
    2111                 :             :         {
    2112         [ #  # ]:           0 :             MakeDelim( j < 0 ? "1" : "0", strbuf, bOverflow );
    2113                 :             :         }
    2114                 :             :         else
    2115                 :             :         {
    2116                 :           0 :             MakeDelim( ".", strbuf, bOverflow );
    2117                 :             :         }
    2118                 :             :     }
    2119                 :             : 
    2120                 :           0 :     return ( strbuf->nUsedLength - nUsedLength0 );
    2121                 :             : }
    2122                 :             : 
    2123                 :             : 
    2124                 :             : 
    2125                 :             : /*
    2126                 :             : Generate AuxInfo substrings
    2127                 :             : */
    2128                 :             : 
    2129                 :             : 
    2130                 :             : 
    2131                 :             : /****************************************************************************
    2132                 :             :   Produce equivalence substring of AuxInfo
    2133                 :             : ****************************************************************************/
    2134                 :          13 : int str_AuxEqu( INCHI_SORT       *pINChISort,
    2135                 :             :                 INCHI_SORT       *pINChISort2,
    2136                 :             :                 INCHI_IOS_STRING *strbuf,
    2137                 :             :                 int              *bOverflow,
    2138                 :             :                 int              bOutType,
    2139                 :             :                 int              TAUT_MODE,
    2140                 :             :                 int              num_components,
    2141                 :             :                 int              bSecondNonTautPass,
    2142                 :             :                 int              bOmitRepetitions,
    2143                 :             :                 int              bUseMulipliers )
    2144                 :             : {
    2145                 :             :     int          i, ii, ii2, nUsedLength0;
    2146                 :             :     INCHI_SORT   *is, *is2, *is0, *is20;
    2147                 :          13 :     INChI_Aux    *pINChI_Aux = NULL, *pINChI_Aux_Prev, *pINChI_Aux_Taut, *pINChI_Aux_Taut_Prev;
    2148                 :             :     int          mult, eq2prev, eq2taut, eq2tautPrev, bNext;
    2149                 :             :     const char  *pPrevEquStr, *pCurrEquStr;
    2150                 :             :     int         multPrevEquStr;
    2151                 :          13 :     pINChI_Aux_Prev = NULL;
    2152                 :          13 :     pINChI_Aux_Taut = NULL;
    2153                 :          13 :     pINChI_Aux_Taut_Prev = NULL;
    2154                 :             : 
    2155                 :          13 :     mult = 0;
    2156                 :          13 :     bNext = 0;
    2157                 :          13 :     is = NULL;
    2158                 :          13 :     is2 = NULL;
    2159                 :          13 :     is0 = pINChISort;
    2160         [ -  + ]:          13 :     is20 = bSecondNonTautPass ? pINChISort2 : NULL;
    2161                 :             :     /* djb-rwth: removing redundant code */
    2162                 :          13 :     eq2tautPrev = 1; /* pINChI_Aux_Prev (previous pINChI_Aux) does not exist */
    2163                 :          13 :     pPrevEquStr = NULL; /*, *pCurrEquStr;*/
    2164                 :          13 :     multPrevEquStr = 0;
    2165                 :          13 :     nUsedLength0 = strbuf->nUsedLength;
    2166                 :             : 
    2167                 :             :     /* For each connected component...    */
    2168         [ +  + ]:          47 :     for (i = 0; i <= num_components; i++)
    2169                 :             :     {
    2170                 :             : 
    2171                 :             :         /* 1st (taut) pass: bOutType=OUT_TN  ; 2nd (non-taut pass) bOutType=OUT_NT */
    2172   [ +  +  -  +  :          34 :         pINChI_Aux = ( i < num_components && ( is = is0 + i, 0 <= ( ii = GET_II( bOutType, is ) ) ) ) ? is->pINChI_Aux[ii] : NULL;
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  +  
          -  +  -  -  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
             -  -  +  - ]
    2173         [ -  + ]:          34 :         if (bSecondNonTautPass)
    2174                 :             :         {
    2175                 :             :             /* component that was output on the 1st pass */
    2176   [ #  #  #  #  :           0 :             pINChI_Aux_Taut = ( i < num_components && ( is2 = is20 + i, 0 <= ( ii2 = GET_II( OUT_T1, is2 ) ) ) ) ? is2->pINChI_Aux[ii2] : NULL;
          #  #  #  #  #  
                #  #  # ]
    2177                 :             :         }
    2178                 :             :         /*================ compare non-iso non-taut equivalence info to non-iso taut ========*/
    2179   [ -  +  -  -  :          34 :         eq2taut = bSecondNonTautPass && bOmitRepetitions &&
                   -  - ]
    2180                 :           0 :             Eql_INChI_Aux_Equ( pINChI_Aux, EQL_EQU, pINChI_Aux_Taut, EQL_EQU );
    2181         [ -  + ]:          34 :         eq2taut = eq2taut ? ( iiEQU | iitNONTAUT ) : 0;
    2182         [ -  + ]:          34 :         if (eq2taut)
    2183                 :             :         {
    2184                 :             :             /* we may be here only in case of the second (non-taut) pass */
    2185                 :             :             /* current non-taut equivalence has been found to be same as tautomeric */
    2186   [ #  #  #  # ]:           0 :             if (pINChI_Aux_Prev && pINChI_Aux_Prev->nNumberOfAtoms)
    2187                 :             :             {
    2188                 :             :                 /* previous component exists */
    2189         [ #  # ]:           0 :                 if (bNext++)
    2190                 :             :                 {
    2191                 :           0 :                     MakeDelim( sCompDelim, strbuf, bOverflow );
    2192                 :             :                 }
    2193         [ #  # ]:           0 :                 if (bHasEquString( pINChI_Aux_Prev->nConstitEquNumbers, pINChI_Aux_Prev->nNumberOfAtoms ))
    2194                 :             :                 {
    2195                 :             :                     /* output previous component(s) equivalence since it was found to be non-trivial */
    2196                 :           0 :                     MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
    2197                 :           0 :                     MakeEquString( pINChI_Aux_Prev->nConstitEquNumbers,
    2198                 :             :                         pINChI_Aux_Prev->nNumberOfAtoms,
    2199                 :             :                         0, strbuf, TAUT_MODE, bOverflow );
    2200                 :             :                 }
    2201                 :             :                 else
    2202                 :             :                 {
    2203                 :             :                     ; /* pINChI_Aux_Prev exists and has only trivial equivalence info */
    2204                 :             :                 }
    2205                 :             :             }
    2206                 :             :             else
    2207   [ #  #  #  # ]:           0 :                 if (pINChI_Aux_Taut_Prev && pINChI_Aux_Taut_Prev->nNumberOfAtoms)
    2208                 :             :                 {
    2209                 :             :                     /* previous non-taut component exists only in taut list */
    2210         [ #  # ]:           0 :                     if (bNext++)
    2211                 :             :                     {
    2212                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    2213                 :             :                     }
    2214                 :             :                 }
    2215                 :             :             /* we have found pINChI_Aux->nConstitEquNumbers same as in pINChI_Aux_Taut */
    2216                 :             :             /* output this (current) equivalence as '*', that is, same as tautomeric */
    2217                 :             :             /* that was printed on the 1st pass. */
    2218                 :           0 :             pCurrEquStr = EquString( eq2taut );
    2219   [ #  #  #  # ]:           0 :             if (multPrevEquStr && pPrevEquStr)
    2220                 :             :             {
    2221   [ #  #  #  # ]:           0 :                 if (pCurrEquStr && !strcmp( pCurrEquStr, pPrevEquStr ))
    2222                 :             :                 {
    2223                 :           0 :                     multPrevEquStr++;
    2224                 :             :                 }
    2225                 :             :                 else
    2226                 :             :                 {
    2227                 :             :                     /* new EqStr is different; output it */
    2228         [ #  # ]:           0 :                     if (bNext++)
    2229                 :             :                     {
    2230                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    2231                 :             :                     }
    2232                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    2233                 :           0 :                     pPrevEquStr = pCurrEquStr;
    2234                 :           0 :                     multPrevEquStr = 1;
    2235                 :             :                 }
    2236                 :             :             }
    2237                 :             :             else
    2238                 :             :             {
    2239                 :           0 :                 pPrevEquStr = pCurrEquStr;
    2240                 :           0 :                 multPrevEquStr = 1;
    2241                 :             :             }
    2242                 :           0 :             pINChI_Aux_Prev = NULL; /* pINChI_Aux_Prev does not exist since */
    2243                 :           0 :             pINChI_Aux_Taut_Prev = NULL; /* pINChI_Aux has just been printed */
    2244                 :           0 :             mult = 0;
    2245                 :           0 :             eq2tautPrev = 1;
    2246                 :             :         }
    2247                 :             :         else
    2248                 :             :         {
    2249         [ +  + ]:          34 :             if (eq2tautPrev)
    2250                 :             :             {
    2251                 :             :                 /* at this point pINChI_Aux_Prev does not exist; however, pINChI_Aux */
    2252                 :             :                 /*might have been discovered and it is different from pINChI_Aux_Taut */
    2253   [ -  +  -  - ]:          13 :                 if (multPrevEquStr && pPrevEquStr)
    2254                 :             :                 {
    2255                 :             :                     /* new EqStr is different; output it */
    2256         [ #  # ]:           0 :                     if (bNext++)
    2257                 :             :                     {
    2258                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    2259                 :             :                     }
    2260                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    2261                 :           0 :                     pPrevEquStr = NULL;
    2262                 :           0 :                     multPrevEquStr = 0;
    2263                 :             :                 }
    2264                 :          13 :                 eq2tautPrev = 0;
    2265                 :          13 :                 pINChI_Aux_Prev = pINChI_Aux;
    2266                 :          13 :                 pINChI_Aux_Taut_Prev = pINChI_Aux_Taut;
    2267                 :          13 :                 mult = 0;
    2268                 :             :             }
    2269                 :             :             else
    2270                 :             :             {
    2271                 :             :                 /* check whether pINChI_Aux and pINChI_Aux_Prev have identical non-trivial equivalence info */
    2272   [ +  -  +  + ]:          42 :                 eq2prev = bUseMulipliers &&
    2273                 :          21 :                     Eql_INChI_Aux_Equ( pINChI_Aux, EQL_EQU, pINChI_Aux_Prev, EQL_EQU );
    2274         [ +  + ]:          21 :                 if (eq2prev)
    2275                 :             :                 {
    2276                 :             :                     /* eq. info is same and non-trivial */
    2277                 :           1 :                     mult++; /* mult = (number of non-empty equal items)-1 */
    2278                 :           1 :                     continue;
    2279                 :             :                 }
    2280                 :             :                 else
    2281                 :             :                 {
    2282                 :             :                     /* pINChI_Aux eq. info is either different or trivial. Output pINChI_Aux_Prev anyway */
    2283         [ +  + ]:          20 :                     if (bNext++)
    2284                 :             :                     {
    2285                 :           7 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    2286                 :             :                     }
    2287   [ +  -  +  - ]:          20 :                     if (pINChI_Aux_Prev && pINChI_Aux_Prev->nNumberOfAtoms)
    2288                 :             :                     {
    2289         [ +  + ]:          35 :                         if (bHasEquString( pINChI_Aux_Prev->nConstitEquNumbers, pINChI_Aux_Prev->nNumberOfAtoms ))
    2290                 :             :                         {
    2291                 :             :                             /* pINChI_Aux_Prev exists and has equivalence info */
    2292                 :          15 :                             MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
    2293                 :          15 :                             MakeEquString( pINChI_Aux_Prev->nConstitEquNumbers, pINChI_Aux_Prev->nNumberOfAtoms, 0,
    2294                 :             :                                 strbuf, TAUT_MODE, bOverflow );
    2295                 :             :                         }
    2296                 :             :                         else
    2297                 :             :                         {
    2298                 :             :                             ; /* pINChI_Aux_Prev exists and has only trivial equivalence info */
    2299                 :             :                         }
    2300                 :             :                     }
    2301                 :             : 
    2302                 :             :                     else
    2303                 :             :                     {
    2304   [ #  #  #  #  :           0 :                         if (bSecondNonTautPass && pINChI_Aux_Taut_Prev && pINChI_Aux_Taut_Prev->nNumberOfAtoms)
                   #  # ]
    2305                 :             :                         {
    2306                 :           0 :                             if (bHasEquString( pINChI_Aux_Taut_Prev->nConstitEquNumbers, pINChI_Aux_Taut_Prev->nNumberOfAtoms ))
    2307                 :             :                             {
    2308                 :             :                                 /* since pINChI_Aux_Prev does not exist, pINChI_Aux_Taut_Prev is non-tautomeric */
    2309                 :             :                                 /* and it has non-trivial equivalence info. This info has already been printed in the main section  */
    2310                 :             :                                 /*
    2311                 :             :                                 MakeDelim( sIdenticalValues, strbuf, bOverflow);
    2312                 :             :                                 */
    2313                 :             :                             }
    2314                 :             :                             else
    2315                 :             :                             {
    2316                 :             :                                 ; /* pINChI_Aux_Taut_Prev exists and has only trivial equivalence info */
    2317                 :             :                             }
    2318                 :             :                         }
    2319                 :             : #if ( bRELEASE_VERSION != 1 && defined(_DEBUG) )
    2320                 :             :                         else
    2321                 :             :                         {
    2322                 :             :                             int stop = 1;   /* <BRKPT> */
    2323                 :             :                         }
    2324                 :             : #endif
    2325                 :             :                     }
    2326                 :             : 
    2327                 :             :                 }
    2328                 :             : 
    2329                 :          20 :                 pINChI_Aux_Prev = pINChI_Aux;
    2330                 :          20 :                 pINChI_Aux_Taut_Prev = pINChI_Aux_Taut;
    2331                 :          20 :                 mult = 0; /* we do not know whether the item is empty */
    2332                 :             :             }
    2333                 :             :         }
    2334                 :             :     }
    2335                 :             : 
    2336                 :          13 :     return ( strbuf->nUsedLength - nUsedLength0 );
    2337                 :             : }
    2338                 :             : 
    2339                 :             : 
    2340                 :             : /****************************************************************************
    2341                 :             :   Produce tetrahedral stereo inversion substring of AuxInfo.
    2342                 :             : ****************************************************************************/
    2343                 :          42 : int str_AuxInvSp3( INCHI_SORT       *pINChISort,
    2344                 :             :                    INCHI_SORT       *pINChISort2,
    2345                 :             :                    INCHI_IOS_STRING *strbuf,
    2346                 :             :                    int              *bOverflow,
    2347                 :             :                    int              bOutType,
    2348                 :             :                    int              TAUT_MODE,
    2349                 :             :                    int              num_components,
    2350                 :             :                    int              bSecondNonTautPass,
    2351                 :             :                    int              bOmitRepetitions,
    2352                 :             :                    int              bUseMulipliers )
    2353                 :             : {
    2354                 :             :     int          i, ii, ii2, nUsedLength0;
    2355                 :             :     INCHI_SORT   *is, *is2, *is0, *is20;
    2356                 :             :     INChI        *pINChI, *pINChI_Prev, *pINChI_Taut, *pINChI_Taut_Prev;
    2357                 :             :     INChI_Stereo *Stereo, *Stereo_Prev, *Stereo_Taut, *Stereo_Taut_Prev;
    2358                 :             :     int          mult, eq2prev, eq2taut, eq2tautPrev, bNext;
    2359                 :             :     const char  *pPrevEquStr, *pCurrEquStr;
    2360                 :             :     int         multPrevEquStr;
    2361                 :             :     /***************
    2362                 :             :     inverted sp3
    2363                 :             :     ****************/
    2364                 :          42 :     pINChI_Taut = NULL;
    2365                 :          42 :     pINChI_Prev = NULL;
    2366                 :          42 :     pINChI_Taut_Prev = NULL;
    2367                 :          42 :     mult = 0;
    2368                 :          42 :     bNext = 0;
    2369                 :          42 :     is = NULL;
    2370                 :          42 :     is2 = NULL;
    2371                 :          42 :     is0 = pINChISort;
    2372         [ -  + ]:          42 :     is20 = bSecondNonTautPass ? pINChISort2 : NULL;
    2373                 :             :     /* djb-rwth: removing redundant code */
    2374                 :          42 :     eq2tautPrev = 1; /* pINChI_Prev (previous pINChI) does not exist */
    2375                 :          42 :     pPrevEquStr = NULL; /*, *pCurrEquStr;*/
    2376                 :          42 :     multPrevEquStr = 0;
    2377                 :          42 :     nUsedLength0 = strbuf->nUsedLength;
    2378                 :             : 
    2379                 :             :     /* For each connected component...    */
    2380         [ +  + ]:         136 :     for (i = 0; i <= num_components; i++)
    2381                 :             :     {
    2382                 :             : 
    2383                 :             :         /* 1st (taut) pass: bOutType=OUT_TN  ; 2nd (non-taut pass) bOutType=OUT_NT */
    2384   [ +  +  -  +  :          94 :         pINChI = ( i < num_components && ( is = is0 + i, 0 <= ( ii = GET_II( bOutType, is ) ) ) ) ? is->pINChI[ii] : NULL;
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  +  
          -  +  -  -  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
             -  -  +  - ]
    2385                 :             :         /*================ compare sp2 to previous =====================*/
    2386         [ -  + ]:          94 :         if (bSecondNonTautPass)
    2387                 :             :         {
    2388                 :             :             /* component that was output on the 1st pass */
    2389   [ #  #  #  #  :           0 :             pINChI_Taut = ( i < num_components && ( is2 = is20 + i, 0 <= ( ii2 = GET_II( OUT_T1, is2 ) ) ) ) ? is2->pINChI[ii2] : NULL;
          #  #  #  #  #  
                #  #  # ]
    2390                 :             :         }
    2391                 :          94 :         eq2taut = 0;
    2392                 :             :         /*========= if bSecondNonTautPass then compare iso non-taut stereo to other stereo ========*/
    2393   [ -  +  -  - ]:          94 :         if (bSecondNonTautPass && bOmitRepetitions)
    2394                 :             :         {
    2395                 :             :             /* compare non-tautomeric inverted to:
    2396                 :             :             *   a) tautomeric inverted
    2397                 :             :             *   b) Inverted(tautomeric)
    2398                 :             :             *   c) Inverted(non-tautomeric)
    2399                 :             :             */
    2400                 :             :             /* a) compare non-tautomeric inverted to tautomeric inverted */
    2401         [ #  # ]:           0 :             if (!eq2taut)
    2402                 :             :             {
    2403         [ #  # ]:           0 :                 eq2taut = pINChI && pINChI_Taut &&
    2404                 :             :                     /* non-taut inverted */          /* taut invertedc */
    2405   [ #  #  #  #  :           0 :                     ( Stereo = pINChI->Stereo ) && ( Stereo_Taut = pINChI_Taut->Stereo ) &&
             #  #  #  # ]
    2406                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP3_INV, Stereo_Taut, EQL_SP3_INV, 0 );
    2407                 :             :                 /* stereo-inv      non-taut =  taut (stereo-inv) */
    2408         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO_INV | iitNONTAUT ) : 0;
    2409                 :             :             }
    2410                 :             :             /* b) compare non-tautomeric inverted to Inverted(tautomeric stereo) */
    2411         [ #  # ]:           0 :             if (!eq2taut)
    2412                 :             :             {
    2413         [ #  # ]:           0 :                 eq2taut = pINChI && pINChI_Taut &&
    2414   [ #  #  #  #  :           0 :                     ( Stereo = pINChI->Stereo ) && ( Stereo_Taut = pINChI_Taut->Stereo ) &&
             #  #  #  # ]
    2415                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP3_INV, Stereo_Taut, EQL_SP3, 0 );
    2416                 :             :                 /* stereo-inv    non-taut =  Inv(taut stereo) */
    2417         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO_INV | iitNONTAUT | iiEq2INV ) : 0;
    2418                 :             :             }
    2419                 :             :             /* c) compare non-tautomeric inverted to Inverted(non-tautomeric stereo) */
    2420         [ #  # ]:           0 :             if (!eq2taut)
    2421                 :             :             {
    2422                 :           0 :                 eq2taut = pINChI &&
    2423   [ #  #  #  #  :           0 :                     ( Stereo = pINChI->Stereo ) &&
                   #  # ]
    2424                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP3_INV, Stereo, EQL_SP3, 0 );
    2425                 :             :                 /* stereo-inv    non-taut =  Inv(non-taut stereo) */
    2426         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO_INV | iitNONTAUT | iiEq2INV | iiEq2NONTAUT ) : 0;
    2427                 :             :             }
    2428                 :             : #if ( FIX_EMPTY_LAYER_BUG == 1 )
    2429                 :             :             if (!eq2taut && pINChI && pINChI_Taut &&
    2430                 :             :                 !( ( Stereo = pINChI->Stereo ) && Eql_INChI_Stereo( Stereo, EQL_SP3_INV, NULL, EQL_EXISTS, 0 ) ))
    2431                 :             :             {
    2432                 :             :                 if (( Stereo_Taut = pINChI_Taut->Stereo ) &&
    2433                 :             :                     Eql_INChI_Stereo( Stereo_Taut, EQL_SP3, NULL, EQL_EXISTS, 0 ))
    2434                 :             :                 {
    2435                 :             : 
    2436                 :             :                     eq2taut = iiEmpty; /* the current is empty while the preceding (taut) is not */
    2437                 :             :                 }
    2438                 :             :             }
    2439                 :             : #endif
    2440                 :             :         }
    2441                 :             :         else
    2442                 :             :             /*========= if not bSecondNonTautPass then compare inv taut stereo to various taut stereo ========*/
    2443   [ +  -  +  - ]:          94 :             if (!bSecondNonTautPass && bOmitRepetitions)
    2444                 :             :             {
    2445                 :             :                 /* compare tautomeric inverted to Invetred(tautomeric) */
    2446         [ +  - ]:          94 :                 if (!eq2taut)
    2447                 :             :                 {
    2448                 :         146 :                     eq2taut = pINChI &&
    2449   [ +  +  +  -  :         146 :                         ( Stereo = pINChI->Stereo ) &&
                   +  + ]
    2450                 :          52 :                         Eql_INChI_Stereo( Stereo, EQL_SP3_INV, Stereo, EQL_SP3, 0 );
    2451                 :             :                     /* stereo     isotopic taut =  taut (stereo) */
    2452         [ +  + ]:          94 :                     eq2taut = eq2taut ? ( iiSTEREO_INV | iiEq2INV ) : 0;
    2453                 :             :                 }
    2454                 :             :             }
    2455         [ +  + ]:          94 :         if (eq2taut)
    2456                 :             :         {
    2457                 :             :             /* we may be here only in case of the current layer found equal in another layer the same component */
    2458   [ +  +  +  - ]:          38 :             if (pINChI_Prev && pINChI_Prev->nNumberOfAtoms)
    2459                 :             :             {
    2460                 :             :                 /* previous component exists; output it before output the current component */
    2461         [ +  + ]:           4 :                 if (bNext++)
    2462                 :             :                 {
    2463                 :           1 :                     MakeDelim( sCompDelim, strbuf, bOverflow );
    2464                 :             :                 }
    2465   [ +  -  +  - ]:           4 :                 if (( Stereo_Prev = pINChI_Prev->Stereo ) && Stereo_Prev->nNumberOfStereoCenters > 0)
    2466                 :             :                 {
    2467                 :           4 :                     MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
    2468                 :             : 
    2469                 :           4 :                     MakeStereoString( Stereo_Prev->nNumber, NULL, Stereo_Prev->t_parityInv,
    2470                 :             :                         0, Stereo_Prev->nNumberOfStereoCenters,
    2471                 :             :                         strbuf, TAUT_MODE, bOverflow );
    2472                 :             :                 }
    2473                 :             :             }
    2474                 :             :             else
    2475   [ -  +  -  - ]:          34 :                 if (pINChI_Taut_Prev && pINChI_Taut_Prev->nNumberOfAtoms)
    2476                 :             :                 {
    2477                 :             :                     /* previous non-taut component exists only in taut list */
    2478         [ #  # ]:           0 :                     if (bNext++)
    2479                 :             :                     {
    2480                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    2481                 :             :                     }
    2482                 :             :                     /* do not output stereo of non-tautomeric in non-taut layer: it has been output in the main layer */
    2483                 :             :                 }
    2484                 :             :             /* we have found another (previously printed) layer of the current component equal to this layer */
    2485                 :             :             /* output this (current) equivalence mark = EquString(eq2taut) */
    2486                 :          38 :             pCurrEquStr = EquString( eq2taut );
    2487   [ +  +  +  - ]:          38 :             if (multPrevEquStr && pPrevEquStr)
    2488                 :             :             {
    2489   [ +  -  +  - ]:           3 :                 if (pCurrEquStr && !strcmp( pCurrEquStr, pPrevEquStr ))
    2490                 :             :                 {
    2491                 :           3 :                     multPrevEquStr++;
    2492                 :             :                 }
    2493                 :             :                 else
    2494                 :             :                 {
    2495                 :             :                     /* new EqStr is different; output it */
    2496         [ #  # ]:           0 :                     if (bNext++)
    2497                 :             :                     {
    2498                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    2499                 :             :                     }
    2500                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    2501                 :           0 :                     pPrevEquStr = pCurrEquStr;
    2502                 :           0 :                     multPrevEquStr = 1;
    2503                 :             :                 }
    2504                 :             :             }
    2505                 :             :             else
    2506                 :             :             {
    2507                 :          35 :                 pPrevEquStr = pCurrEquStr;
    2508                 :          35 :                 multPrevEquStr = 1;
    2509                 :             :             }
    2510                 :          38 :             pINChI_Prev = NULL; /* pINChI_Prev sp2 does not exist since */
    2511                 :          38 :             pINChI_Taut_Prev = NULL; /* pINChI has just been printed */
    2512                 :          38 :             mult = 0;
    2513                 :          38 :             eq2tautPrev = 1;     /* pINChI_Prev and pINChI_Taut_Prev have already been output */
    2514                 :             :         }
    2515                 :             :         else
    2516         [ +  + ]:          56 :             if (eq2tautPrev)
    2517                 :             :             {
    2518                 :             :                 /* at this point pINChI_Prev does not exist; however, pINChI */
    2519                 :             :                 /*might have been discovered and it is different from pINChI_Taut */
    2520   [ +  +  +  - ]:          46 :                 if (multPrevEquStr && pPrevEquStr)
    2521                 :             :                 {
    2522                 :             :                     /* new EqStr is different; output it */
    2523         [ +  + ]:          35 :                     if (bNext++)
    2524                 :             :                     {
    2525                 :           4 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    2526                 :             :                     }
    2527                 :          35 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    2528                 :          35 :                     pPrevEquStr = NULL;
    2529                 :          35 :                     multPrevEquStr = 0;
    2530                 :             :                 }
    2531                 :          46 :                 eq2tautPrev = 0;
    2532                 :          46 :                 pINChI_Prev = pINChI;
    2533                 :          46 :                 pINChI_Taut_Prev = pINChI_Taut;
    2534                 :          46 :                 mult = 0;
    2535                 :             :             }
    2536                 :             :             else
    2537                 :             :             {
    2538                 :             :                 /* current layer is different from previously printed layers of the current component */
    2539                 :             :                 /* compare the current layer to this layer of the previous component: */
    2540                 :             :                 /* check whether pINChI and pINChI_Prev have non-zero identical stereo sp2 */
    2541                 :             :                 /*================ compare iso sp3 to previous =====================*/
    2542         [ -  + ]:          10 :                 eq2prev = bUseMulipliers &&
    2543         [ #  # ]:           0 :                     pINChI && pINChI_Prev &&
    2544                 :             :                     /* do both have stereo? */
    2545   [ +  -  -  -  :          20 :                     ( Stereo = pINChI->Stereo ) && ( Stereo_Prev = pINChI_Prev->Stereo ) &&
             -  -  -  - ]
    2546                 :             :                     /* is their inverted stereo same? */
    2547                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP3_INV, Stereo_Prev, EQL_SP3_INV, 0 );
    2548         [ -  + ]:          10 :                 if (eq2prev)
    2549                 :             :                 {
    2550                 :           0 :                     mult++; /* mult = (number of non-empty equal items)-1 */
    2551                 :           0 :                     continue;
    2552                 :             :                 }
    2553                 :             :                 else
    2554                 :             :                 {
    2555         [ +  + ]:          10 :                     if (bNext++)
    2556                 :             :                     {
    2557                 :           2 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    2558                 :             :                     }
    2559   [ +  -  +  - ]:          10 :                     if (pINChI_Prev && pINChI_Prev->nNumberOfAtoms)
    2560                 :             :                     {
    2561         [ +  - ]:          10 :                         if (( Stereo_Prev = pINChI_Prev->Stereo ) &&
    2562   [ +  +  +  - ]:          10 :                             Stereo_Prev->nNumberOfStereoCenters > 0 && Stereo_Prev->nCompInv2Abs)
    2563                 :             :                         {
    2564                 :           9 :                             MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
    2565                 :             : 
    2566                 :           9 :                             MakeStereoString( Stereo_Prev->nNumberInv, NULL, Stereo_Prev->t_parityInv,
    2567                 :             :                                 0, Stereo_Prev->nNumberOfStereoCenters,
    2568                 :             :                                 strbuf, TAUT_MODE, bOverflow );
    2569                 :             :                         }
    2570                 :             :                         /* else sp3 info is not present in pINChI_Prev */
    2571                 :             :                     }
    2572                 :             :                     else
    2573                 :             :                         /* do not print pINChI_Prev because it either do not exist of have already been printed */
    2574   [ #  #  #  #  :           0 :                         if (bSecondNonTautPass && pINChI_Taut_Prev && pINChI_Taut_Prev->nNumberOfAtoms)
                   #  # ]
    2575                 :             :                         {
    2576         [ #  # ]:           0 :                             if (( Stereo_Taut_Prev = pINChI_Taut_Prev->Stereo ) &&
    2577         [ #  # ]:           0 :                                 Stereo_Taut_Prev->nNumberOfStereoCenters > 0 && Stereo_Taut_Prev->nCompInv2Abs)
    2578                 :             :                             {
    2579                 :             :                                 /* since pINChI_Prev does not exist, pINChI_Taut_Prev is non-tautomeric */
    2580                 :             :                                 /* and it has non-trivial inv sp3 info. It has already been printed in the main section */
    2581                 :             :                                 /*
    2582                 :             :                                 MakeDelim( sIdenticalValues, strbuf, bOverflow);
    2583                 :             :                                 */
    2584                 :             :                                 ;/* pINChI_Taut_Prev sp3 info was output in the main stereo section */
    2585                 :             :                             }
    2586                 :             :                             else
    2587                 :             :                             {
    2588                 :             :                                 ; /* pINChI_Taut_Prev exists and has not sp3 info */
    2589                 :             :                             }
    2590                 :             :                         }
    2591                 :             : #if ( bRELEASE_VERSION != 1 && defined(_DEBUG) )
    2592                 :             :                         else
    2593                 :             :                         {
    2594                 :             :                             int stop = 1;   /* <BRKPT> */
    2595                 :             :                         }
    2596                 :             : #endif
    2597                 :             :                 }
    2598                 :          10 :                 pINChI_Prev = pINChI;
    2599                 :          10 :                 mult = 0; /* we do not know whether the item is empty */
    2600                 :             :             }
    2601                 :             :     }
    2602                 :             : 
    2603                 :          42 :     return ( strbuf->nUsedLength - nUsedLength0 );
    2604                 :             : }
    2605                 :             : 
    2606                 :             : 
    2607                 :             : /****************************************************************************
    2608                 :             :   Produce tetrahedral stereo inversion numbering substring of AuxInfo
    2609                 :             :   /iN: in Main and/or Isotopic and/or FixedH-Iso parts,
    2610                 :             :   in both normal and reconnected layers
    2611                 :             : ****************************************************************************/
    2612                 :           0 : int str_AuxInvSp3Numb( CANON_GLOBALS    *pCG,
    2613                 :             :                        INCHI_SORT       *pINChISort,
    2614                 :             :                        INCHI_SORT       *pINChISort2,
    2615                 :             :                        INCHI_IOS_STRING *strbuf,
    2616                 :             :                        int              *bOverflow,
    2617                 :             :                        int              bOutType,
    2618                 :             :                        int              TAUT_MODE,
    2619                 :             :                        int              num_components,
    2620                 :             :                        int              bSecondNonTautPass,
    2621                 :             :                        int               bOmitRepetitions )
    2622                 :             : {
    2623                 :             :     int          i, ii, ii2, nUsedLength0;
    2624                 :             :     INCHI_SORT   *is, *is0 /*, *is2*/;
    2625                 :             :     INChI        *pINChI, *pINChI_Taut;
    2626                 :             :     INChI_Aux    *pINChI_Aux, *pINChI_Aux_Taut; /* djb-rwth: removing redundant variables */
    2627                 :             :     INChI_Stereo *Stereo, *Stereo_Taut;
    2628                 :             :     int          eq2taut, bNext;
    2629                 :             :     const char  *pPrevEquStr, *pCurrEquStr;
    2630                 :             :     int         multPrevEquStr;
    2631                 :             :     /**************************************************
    2632                 :             :     * specificity of numbering: there is no previous *
    2633                 :             :     * component because no repetition is possible    *
    2634                 :             :     **************************************************/
    2635                 :           0 :     pINChI = NULL;
    2636                 :           0 :     pINChI_Taut = NULL;
    2637                 :           0 :     pINChI_Aux = NULL;
    2638                 :           0 :     pINChI_Aux_Taut = NULL;
    2639                 :             :     /* djb-rwth: removing redundant code */
    2640                 :           0 :     bNext = 0;
    2641                 :           0 :     is = NULL;
    2642                 :           0 :     is0 = pINChISort;
    2643                 :             :     /*is2         = bSecondNonTautPass? pINChISort2 : NULL;*/
    2644                 :             :     /* djb-rwth: removing redundant code */
    2645                 :           0 :     pPrevEquStr = NULL; /*, *pCurrEquStr;*/
    2646                 :           0 :     multPrevEquStr = 0;
    2647                 :           0 :     nUsedLength0 = strbuf->nUsedLength;
    2648                 :             : 
    2649                 :             :     /* For each connected component...    */
    2650         [ #  # ]:           0 :     for (i = 0; i < num_components; i++)
    2651                 :             :     {
    2652                 :             : 
    2653                 :             :         /* 1st (taut) pass: bOutType=OUT_TN  ; 2nd (non-taut pass) bOutType=OUT_NT */
    2654                 :           0 :         is = is0 + i;
    2655   [ #  #  #  #  :           0 :         pINChI = ( 0 <= ( ii = GET_II( bOutType, is ) ) ) ? is->pINChI[ii] : NULL;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    2656         [ #  # ]:           0 :         pINChI_Aux = pINChI ? is->pINChI_Aux[ii] : NULL;
    2657                 :             :         /*================ to compare to previously printed =====================*/
    2658         [ #  # ]:           0 :         if (bSecondNonTautPass)
    2659                 :             :         {
    2660                 :             :             /* component that was printed on the 1st pass */
    2661   [ #  #  #  #  :           0 :             pINChI_Taut = ( 0 <= ( ii2 = GET_II( OUT_T1, is ) ) ) ? is->pINChI[ii2] : NULL;
          #  #  #  #  #  
                      # ]
    2662         [ #  # ]:           0 :             pINChI_Aux_Taut = pINChI_Taut ? is->pINChI_Aux[ii2] : NULL;
    2663                 :             :         }
    2664                 :             : 
    2665                 :           0 :         eq2taut = 0;
    2666                 :             :         /*========= if bSecondNonTautPass then compare inv non-taut stereo to other stereo ========*/
    2667   [ #  #  #  #  :           0 :         if (bSecondNonTautPass && bOmitRepetitions &&
                   #  # ]
    2668   [ #  #  #  # ]:           0 :             pINChI && ( Stereo = pINChI->Stereo ) && Stereo->nCompInv2Abs)
    2669                 :             :         {
    2670                 :             :             /* compare non-tautomeric inverted stereo numbering to:
    2671                 :             :             *   a) tautomeric numbering
    2672                 :             :             *   b) non-tautomeric numbering
    2673                 :             :             *   c) tautomeric inverted stereo numbering
    2674                 :             :             */
    2675                 :             :             /* a) compare non-tautomeric inverted stereo numbering to tautomeric numbering */
    2676         [ #  # ]:           0 :             if (!eq2taut)
    2677                 :             :             {
    2678   [ #  #  #  # ]:           0 :                 eq2taut = pINChI_Taut &&
    2679                 :           0 :                     Eql_INChI_Aux_Num( pINChI_Aux, EQL_NUM_INV, pINChI_Aux_Taut, EQL_NUM );
    2680                 :             :                 /* stereo-inv     numbering  non-taut =  taut numbering */
    2681         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO_INV | iiNUMB | iitNONTAUT ) : 0;
    2682                 :             :             }
    2683                 :             :             /* b) compare non-tautomeric inverted stereo numbering to non-tautomeric numbering */
    2684         [ #  # ]:           0 :             if (!eq2taut)
    2685                 :             :             {
    2686                 :             :                 eq2taut =
    2687                 :           0 :                     Eql_INChI_Aux_Num( pINChI_Aux, EQL_NUM_INV, pINChI_Aux, EQL_NUM );
    2688                 :             :                 /* stereo-inv     numb.     non-taut =  non-taut numbering */
    2689         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO_INV | iiNUMB | iitNONTAUT | iiEq2NONTAUT ) : 0;
    2690                 :             :             }
    2691                 :             :             /* c) compare non-tautomeric inverted stereo numbering to tautomeric inverted stereo numbering */
    2692         [ #  # ]:           0 :             if (!eq2taut)
    2693                 :             :             {
    2694                 :           0 :                 eq2taut = pINChI_Taut &&
    2695   [ #  #  #  #  :           0 :                     ( Stereo_Taut = pINChI_Taut->Stereo ) && Stereo_Taut->nCompInv2Abs &&
             #  #  #  # ]
    2696                 :           0 :                     Eql_INChI_Aux_Num( pINChI_Aux, EQL_NUM_INV, pINChI_Aux_Taut, EQL_NUM_INV );
    2697                 :             :                 /* stereo-inv     numb.     non-taut =  taut inv stereo numbering */
    2698         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO_INV | iiNUMB | iitNONTAUT | iiEq2INV ) : 0;
    2699                 :             :             }
    2700                 :             :         }
    2701                 :             :         else
    2702                 :             :         {
    2703                 :             :             /*========= if not bSecondNonTautPass then compare inv taut stereo numb to taut numb ========*/
    2704   [ #  #  #  #  :           0 :             if (!bSecondNonTautPass && bOmitRepetitions &&
                   #  # ]
    2705   [ #  #  #  # ]:           0 :                 pINChI && ( Stereo = pINChI->Stereo ) && Stereo->nCompInv2Abs)
    2706                 :             :             {
    2707                 :             :                 /* compare tautomeric inverted stereo numbering to tautomeric numbering */
    2708         [ #  # ]:           0 :                 if (!eq2taut)
    2709                 :             :                 {
    2710                 :             :                     eq2taut =
    2711                 :           0 :                         Eql_INChI_Aux_Num( pINChI_Aux, EQL_NUM_INV, pINChI_Aux, EQL_NUM );
    2712                 :             :                     /* stereo-inv     numbering  (taut) =  taut numbering */
    2713         [ #  # ]:           0 :                     eq2taut = eq2taut ? ( iiSTEREO_INV | iiNUMB ) : 0;
    2714                 :             :                 }
    2715                 :             :             }
    2716                 :             :         }
    2717         [ #  # ]:           0 :         if (eq2taut)
    2718                 :             :         {
    2719                 :             :             /* we have found another (previously printed) layer of the current component equal to this layer */
    2720                 :             :             /* output this (current) equivalence mark = EquString(eq2taut) */
    2721                 :           0 :             pCurrEquStr = EquString( eq2taut );
    2722   [ #  #  #  # ]:           0 :             if (multPrevEquStr && pPrevEquStr)
    2723                 :             :             {
    2724   [ #  #  #  # ]:           0 :                 if (pCurrEquStr && !strcmp( pCurrEquStr, pPrevEquStr ))
    2725                 :             :                 {
    2726                 :           0 :                     multPrevEquStr++;
    2727                 :             :                 }
    2728                 :             :                 else
    2729                 :             :                 {
    2730                 :             :                     /* new EqStr is different; output it */
    2731         [ #  # ]:           0 :                     if (bNext++)
    2732                 :             :                     {
    2733                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    2734                 :             :                     }
    2735                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    2736                 :           0 :                     pPrevEquStr = pCurrEquStr;
    2737                 :           0 :                     multPrevEquStr = 1;
    2738                 :             :                 }
    2739                 :             :             }
    2740                 :             :             else
    2741                 :             :             {
    2742                 :           0 :                 pPrevEquStr = pCurrEquStr;
    2743                 :           0 :                 multPrevEquStr = 1;
    2744                 :             :             }
    2745                 :             :         }
    2746                 :             :         else
    2747                 :             :         {
    2748                 :             :             /* current layer is different from previously printed layers of the current component */
    2749   [ #  #  #  # ]:           0 :             if (multPrevEquStr && pPrevEquStr)
    2750                 :             :             {
    2751                 :             :                 /* new EqStr is different; output it */
    2752         [ #  # ]:           0 :                 if (bNext++)
    2753                 :             :                 {
    2754                 :           0 :                     MakeDelim( sCompDelim, strbuf, bOverflow );
    2755                 :             :                 }
    2756                 :           0 :                 MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    2757                 :           0 :                 pPrevEquStr = NULL;
    2758                 :           0 :                 multPrevEquStr = 0;
    2759                 :             :             }
    2760         [ #  # ]:           0 :             if (bNext++)
    2761                 :             :             {
    2762                 :           0 :                 MakeDelim( sCompDelim, strbuf, bOverflow );
    2763                 :             :             }
    2764   [ #  #  #  #  :           0 :             if (pINChI && pINChI_Aux && pINChI_Aux->nNumberOfAtoms &&
                   #  # ]
    2765   [ #  #  #  # ]:           0 :                 ( Stereo = pINChI->Stereo ) && Stereo->nNumberOfStereoCenters &&
    2766   [ #  #  #  # ]:           0 :                 Stereo->nCompInv2Abs && pINChI_Aux->nOrigAtNosInCanonOrdInv)
    2767                 :             :             {
    2768                 :           0 :                 MakeCtString( pCG, pINChI_Aux->nOrigAtNosInCanonOrdInv,
    2769                 :             :                     pINChI_Aux->nNumberOfAtoms, 0, NULL, 0,
    2770                 :             :                     strbuf, TAUT_MODE, bOverflow );
    2771                 :             :             }
    2772                 :             :             /* else inv stereo info is not present in pINChI */
    2773                 :             :         }
    2774                 :             :     }
    2775                 :             : 
    2776   [ #  #  #  # ]:           0 :     if (multPrevEquStr && pPrevEquStr)
    2777                 :             :     {
    2778                 :             :         /* the new EqStr of the last item has not been printed; output it now */
    2779         [ #  # ]:           0 :         if (bNext++)
    2780                 :             :         {
    2781                 :           0 :             MakeDelim( sCompDelim, strbuf, bOverflow );
    2782                 :             :         }
    2783                 :           0 :         MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    2784                 :           0 :         pPrevEquStr = NULL;
    2785                 :             :         /* djb-rwth: removing redundant code */
    2786                 :             :     }
    2787                 :             : 
    2788                 :           0 :     return ( strbuf->nUsedLength - nUsedLength0 );
    2789                 :             : }
    2790                 :             : 
    2791                 :             : 
    2792                 :             : /****************************************************************************
    2793                 :             :   Produce isotopic numbering substring of AuxInfo
    2794                 :             :   /I: in Isotopic and/or FixedH-Iso parts,
    2795                 :             :   in both normal and reconnected layers
    2796                 :             : ****************************************************************************/
    2797                 :           0 : int str_AuxIsoNumb( CANON_GLOBALS    *pCG,
    2798                 :             :                     INCHI_SORT       *pINChISort,
    2799                 :             :                     INCHI_SORT       *pINChISort2,
    2800                 :             :                     INCHI_IOS_STRING *strbuf,
    2801                 :             :                     int              *bOverflow,
    2802                 :             :                     int              bOutType,
    2803                 :             :                     int              TAUT_MODE,
    2804                 :             :                     int              num_components,
    2805                 :             :                     int              bSecondNonTautPass,
    2806                 :             :                     int              bOmitRepetitions )
    2807                 :             : {
    2808                 :             :     int          i, ii, ii2, nUsedLength0;
    2809                 :             :     INCHI_SORT   *is, *is0 /*, *is2*/;
    2810                 :             :     /* djb-rwth: removing redundant variables */
    2811                 :             :     INChI_Aux    *pINChI_Aux, *pINChI_Aux_Taut; /* djb-rwth: removing redundant variables */
    2812                 :             :     int          eq2taut, bNext;
    2813                 :             :     const char  *pPrevEquStr, *pCurrEquStr;
    2814                 :             :     int         multPrevEquStr;
    2815                 :             :     /**************************************************
    2816                 :             :     * specificity of numbering: there is no previous *
    2817                 :             :     * component because no repetition is possible    *
    2818                 :             :     **************************************************/
    2819                 :             :     /* djb-rwth: removing redundant code */
    2820                 :           0 :     pINChI_Aux = NULL;
    2821                 :           0 :     pINChI_Aux_Taut = NULL;
    2822                 :             :     /* djb-rwth: removing redundant code */
    2823                 :           0 :     bNext = 0;
    2824                 :           0 :     is = NULL;
    2825                 :           0 :     is0 = pINChISort;
    2826                 :             :     /*is2         = bSecondNonTautPass? pINChISort2 : NULL;*/
    2827                 :             :     /* djb-rwth: removing redundant code */
    2828                 :           0 :     pPrevEquStr = NULL; /*, *pCurrEquStr;*/
    2829                 :           0 :     multPrevEquStr = 0;
    2830                 :           0 :     nUsedLength0 = strbuf->nUsedLength;
    2831                 :             : 
    2832                 :             :     /* For each connected component...    */
    2833         [ #  # ]:           0 :     for (i = 0; i < num_components; i++)
    2834                 :             :     {
    2835                 :             : 
    2836                 :             :         /* 1st (taut) pass: bOutType=OUT_TN  ; 2nd (non-taut pass) bOutType=OUT_NT */
    2837                 :           0 :         is = is0 + i;
    2838   [ #  #  #  #  :           0 :         pINChI_Aux = ( i < num_components && 0 <= ( ii = GET_II( bOutType, is ) ) ) ? is->pINChI_Aux[ii] : NULL;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    2839                 :             :         /*================ to compare to previously printed =====================*/
    2840         [ #  # ]:           0 :         if (bSecondNonTautPass)
    2841                 :             :         {
    2842   [ #  #  #  #  :           0 :             pINChI_Aux_Taut = ( 0 <= ( ii2 = GET_II( OUT_T1, is ) ) ) ? is->pINChI_Aux[ii2] : NULL;
          #  #  #  #  #  
                      # ]
    2843                 :             :         }
    2844                 :           0 :         eq2taut = 0;
    2845                 :             :         /*========= if bSecondNonTautPass then compare iso non-taut numb to other numb ========*/
    2846   [ #  #  #  #  :           0 :         if (bSecondNonTautPass && bOmitRepetitions && pINChI_Aux && pINChI_Aux->bIsIsotopic)
             #  #  #  # ]
    2847                 :             :         {
    2848                 :             :             /* compare non-tautomeric isotopic numbering to:
    2849                 :             :             *   a) tautomeric numbering
    2850                 :             :             *   b) non-tautomeric numbering
    2851                 :             :             *   c) tautomeric isotopic numbering
    2852                 :             :             */
    2853                 :             :             /* a) compare non-tautomeric isotopic numbering to tautomeric numbering */
    2854         [ #  # ]:           0 :             if (!eq2taut)
    2855                 :             :             {
    2856                 :           0 :                 eq2taut = Eql_INChI_Aux_Num( pINChI_Aux, EQL_NUM_ISO, pINChI_Aux_Taut, EQL_NUM );
    2857                 :             :                 /* numbering  non-taut isotopic =  taut numbering */
    2858         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiNUMB | iitNONTAUT | iitISO ) : 0;
    2859                 :             :             }
    2860                 :             :             /* b) compare non-tautomeric isotopic numbering to non-tautomeric numbering */
    2861         [ #  # ]:           0 :             if (!eq2taut)
    2862                 :             :             {
    2863                 :           0 :                 eq2taut = Eql_INChI_Aux_Num( pINChI_Aux, EQL_NUM_ISO, pINChI_Aux, EQL_NUM );
    2864                 :             :                 /* numbering  non-taut isotopic =  non-taut numbering */
    2865         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiNUMB | iitNONTAUT | iitISO | iiEq2NONTAUT ) : 0;
    2866                 :             :             }
    2867                 :             :             /* c) compare non-tautomeric isotopic numbering to tautomeric isotopic numbering */
    2868         [ #  # ]:           0 :             if (!eq2taut)
    2869                 :             :             {
    2870                 :           0 :                 eq2taut = Eql_INChI_Aux_Num( pINChI_Aux, EQL_NUM_ISO, pINChI_Aux_Taut, EQL_NUM_ISO );
    2871                 :             :                 /* numbering  non-taut isotopic =  taut isotopic numbering */
    2872         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiNUMB | iitNONTAUT | iitISO | iiEq2ISO ) : 0;
    2873                 :             :             }
    2874                 :             :         }
    2875                 :             :         else
    2876                 :             :         {
    2877                 :             :             /*    2011-10-28
    2878                 :             :             Fix bug in src:cano mapping of  atoms printed to AuxInfo
    2879                 :             :             Reported by Sandor Mark on 2011-10-25 in inchi-discuss
    2880                 :             :             See http://sourceforge.net/p/inchi/mailman/message/28292914/ also
    2881                 :             :             */
    2882                 :             : #define AUX_ISO_NUMB_BUG_FIX
    2883                 :             : #ifdef AUX_ISO_NUMB_BUG_FIX
    2884                 :             :             /* Bug-fixed version */
    2885                 :             :             /*========= if not bSecondNonTautPass then compare isotopic taut numbering to taut numbering ========*/
    2886   [ #  #  #  #  :           0 :             if (!bSecondNonTautPass && bOmitRepetitions && pINChI_Aux && pINChI_Aux->bIsIsotopic)
             #  #  #  # ]
    2887                 :             :             {
    2888                 :             :                 /* compare tautomeric isotopic numbering to tautomeric non-isotopic numbering */
    2889         [ #  # ]:           0 :                 if (!eq2taut)
    2890                 :             :                 {
    2891                 :           0 :                     eq2taut = Eql_INChI_Aux_Num( pINChI_Aux, EQL_NUM_ISO, pINChI_Aux, EQL_NUM );
    2892                 :             :                     /*  numbering isotopic (taut) =  taut numbering */
    2893         [ #  # ]:           0 :                     eq2taut = eq2taut ? ( iiNUMB | iitISO ) : 0;
    2894                 :             :                 }
    2895                 :             :             }
    2896                 :             : #else
    2897                 :             :             /* Original (buggy) version */
    2898                 :             : 
    2899                 :             :             /*========= if not bSecondNonTautPass then compare inv taut stereo numb to taut numb ========*/
    2900                 :             :             if (!bSecondNonTautPass && bOmitRepetitions && pINChI_Aux && pINChI_Aux->bIsIsotopic)
    2901                 :             :             {
    2902                 :             :                 /* compare tautomeric isotopic numbering to tautomeric non-isotopic numbering */
    2903                 :             :                 if (!eq2taut)
    2904                 :             :                 {
    2905                 :             :                     eq2taut = Eql_INChI_Aux_Num( pINChI_Aux, EQL_NUM_ISO, pINChI_Aux, EQL_NUM_ISO );
    2906                 :             :                     /* stereo-inv     numbering  (taut) =  taut numbering */
    2907                 :             :                     eq2taut = eq2taut ? ( iiSTEREO_INV | iiNUMB ) : 0;
    2908                 :             :                 }
    2909                 :             :             }
    2910                 :             : #endif
    2911                 :             :         }
    2912                 :             : 
    2913         [ #  # ]:           0 :         if (eq2taut)
    2914                 :             :         {
    2915                 :             :             /* we have found another (previously printed) layer of the current component equal to this layer */
    2916                 :             :             /* output this (current) equivalence mark = EquString(eq2taut) */
    2917                 :           0 :             pCurrEquStr = EquString( eq2taut );
    2918   [ #  #  #  # ]:           0 :             if (multPrevEquStr && pPrevEquStr)
    2919                 :             :             {
    2920   [ #  #  #  # ]:           0 :                 if (pCurrEquStr && !strcmp( pCurrEquStr, pPrevEquStr ))
    2921                 :             :                 {
    2922                 :           0 :                     multPrevEquStr++;
    2923                 :             :                 }
    2924                 :             :                 else
    2925                 :             :                 {
    2926                 :             :                     /* new EqStr is different; output it */
    2927         [ #  # ]:           0 :                     if (bNext++)
    2928                 :             :                     {
    2929                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    2930                 :             :                     }
    2931                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    2932                 :           0 :                     pPrevEquStr = pCurrEquStr;
    2933                 :           0 :                     multPrevEquStr = 1;
    2934                 :             :                 }
    2935                 :             :             }
    2936                 :             :             else
    2937                 :             :             {
    2938                 :           0 :                 pPrevEquStr = pCurrEquStr;
    2939                 :           0 :                 multPrevEquStr = 1;
    2940                 :             :             }
    2941                 :             :         }
    2942                 :             :         else
    2943                 :             :         {
    2944                 :             :             /* current layer is different from previously printed layers of the current component */
    2945   [ #  #  #  # ]:           0 :             if (multPrevEquStr && pPrevEquStr)
    2946                 :             :             {
    2947                 :             :                 /* new EqStr is different; output it */
    2948         [ #  # ]:           0 :                 if (bNext++)
    2949                 :             :                 {
    2950                 :           0 :                     MakeDelim( sCompDelim, strbuf, bOverflow );
    2951                 :             :                 }
    2952                 :           0 :                 MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    2953                 :           0 :                 pPrevEquStr = NULL;
    2954                 :           0 :                 multPrevEquStr = 0;
    2955                 :             :             }
    2956         [ #  # ]:           0 :             if (bNext++)
    2957                 :             :             {
    2958                 :           0 :                 MakeDelim( sCompDelim, strbuf, bOverflow );
    2959                 :             :             }
    2960   [ #  #  #  #  :           0 :             if (pINChI_Aux && pINChI_Aux->nNumberOfAtoms && pINChI_Aux->bIsIsotopic &&
                   #  # ]
    2961         [ #  # ]:           0 :                 pINChI_Aux->nIsotopicOrigAtNosInCanonOrd)
    2962                 :             :             {
    2963                 :           0 :                 MakeCtString( pCG, pINChI_Aux->nIsotopicOrigAtNosInCanonOrd,
    2964                 :             :                     pINChI_Aux->nNumberOfAtoms,
    2965                 :             :                     0, NULL, 0, strbuf, TAUT_MODE, bOverflow );
    2966                 :             :             }
    2967                 :             :             /* else isotopic numbering is not present in pINChI */
    2968                 :             :         }
    2969                 :             :     }
    2970                 :             : 
    2971   [ #  #  #  # ]:           0 :     if (multPrevEquStr && pPrevEquStr)
    2972                 :             :     {
    2973                 :             :         /* the new EqStr of the last item has not been printed; output it now */
    2974         [ #  # ]:           0 :         if (bNext++)
    2975                 :             :         {
    2976                 :           0 :             MakeDelim( sCompDelim, strbuf, bOverflow );
    2977                 :             :         }
    2978                 :           0 :         MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    2979                 :           0 :         pPrevEquStr = NULL;
    2980                 :             :         /* djb-rwth: removing redundant code */
    2981                 :             :     }
    2982                 :             : 
    2983                 :           0 :     return ( strbuf->nUsedLength - nUsedLength0 );
    2984                 :             : }
    2985                 :             : 
    2986                 :             : 
    2987                 :             : /****************************************************************************
    2988                 :             :   Produce isotopic equivalence substring of AuxInfo.
    2989                 :             : ****************************************************************************/
    2990                 :           0 : int str_AuxIsoEqu( INCHI_SORT       *pINChISort,
    2991                 :             :                    INCHI_SORT       *pINChISort2,
    2992                 :             :                    INCHI_IOS_STRING *strbuf,
    2993                 :             :                    int              *bOverflow,
    2994                 :             :                    int              bOutType,
    2995                 :             :                    int              TAUT_MODE,
    2996                 :             :                    int              num_components,
    2997                 :             :                    int              bSecondNonTautPass,
    2998                 :             :                    int              bOmitRepetitions,
    2999                 :             :                    int              bUseMulipliers )
    3000                 :             : {
    3001                 :             :     int          i, ii, ii2, nUsedLength0;
    3002                 :             :     INCHI_SORT   *is, *is2, *is0, *is20;
    3003                 :             :     INChI_Aux    *pINChI_Aux, *pINChI_Aux_Prev, *pINChI_Aux_Taut, *pINChI_Aux_Taut_Prev;
    3004                 :             :     int          mult, eq2prev, eq2taut, eq2tautPrev, bNext;
    3005                 :             :     const char  *pPrevEquStr, *pCurrEquStr;
    3006                 :             :     int         multPrevEquStr;
    3007                 :           0 :     pINChI_Aux = NULL;
    3008                 :           0 :     pINChI_Aux_Prev = NULL;
    3009                 :           0 :     pINChI_Aux_Taut = NULL;
    3010                 :           0 :     pINChI_Aux_Taut_Prev = NULL;
    3011                 :           0 :     mult = 0;
    3012                 :           0 :     bNext = 0;
    3013                 :           0 :     is = NULL;
    3014                 :           0 :     is2 = NULL;
    3015                 :           0 :     is0 = pINChISort;
    3016         [ #  # ]:           0 :     is20 = bSecondNonTautPass ? pINChISort2 : NULL;
    3017                 :             :     /* djb-rwth: removing redundant code */
    3018                 :           0 :     eq2tautPrev = 1; /* pINChI_Aux_Prev (previous pINChI_Aux) does not exist */
    3019                 :           0 :     pPrevEquStr = NULL; /*, *pCurrEquStr;*/
    3020                 :           0 :     multPrevEquStr = 0;
    3021                 :           0 :     nUsedLength0 = strbuf->nUsedLength;
    3022                 :             : 
    3023                 :             :     /* For each connected component...    */
    3024         [ #  # ]:           0 :     for (i = 0; i <= num_components; i++)
    3025                 :             :     {
    3026                 :             : 
    3027                 :             :         /* 1st (taut) pass: bOutType=OUT_TN  ; 2nd (non-taut pass) bOutType=OUT_NT */
    3028   [ #  #  #  #  :           0 :         pINChI_Aux = ( i < num_components && ( is = is0 + i, 0 <= ( ii = GET_II( bOutType, is ) ) ) ) ? is->pINChI_Aux[ii] : NULL;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    3029         [ #  # ]:           0 :         if (bSecondNonTautPass)
    3030                 :             :         {
    3031                 :             :             /* component that was output on the 1st pass */
    3032   [ #  #  #  #  :           0 :             pINChI_Aux_Taut = ( i < num_components && ( is2 = is20 + i, 0 <= ( ii2 = GET_II( OUT_T1, is2 ) ) ) ) ? is2->pINChI_Aux[ii2] : NULL;
          #  #  #  #  #  
                #  #  # ]
    3033                 :             :         }
    3034                 :             :         /*================ compare iso non-taut equivalence info to non-iso taut ========*/
    3035                 :           0 :         eq2taut = 0;
    3036   [ #  #  #  #  :           0 :         if (bSecondNonTautPass && bOmitRepetitions && pINChI_Aux && pINChI_Aux->bIsIsotopic)
             #  #  #  # ]
    3037                 :             :         {
    3038                 :             :             /**************************************************
    3039                 :             :             * compare isotopic non-tautomeric equivalence to:
    3040                 :             :             *    a) tautomeric
    3041                 :             :             *    b) non-tautomeric
    3042                 :             :             *    c) isotopic tautomeric
    3043                 :             :             */
    3044         [ #  # ]:           0 :             if (!eq2taut)
    3045                 :             :             {
    3046                 :             :                 /* compare isotopic non-tautomeric equivalence to tautomeric */
    3047                 :           0 :                 eq2taut = Eql_INChI_Aux_Equ( pINChI_Aux, EQL_EQU_ISO, pINChI_Aux_Taut, EQL_EQU );
    3048                 :             :                 /* equ   non-taut     isotopic = tautomeric*/
    3049         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiEQU | iitNONTAUT | iitISO ) : 0;
    3050                 :             :             }
    3051         [ #  # ]:           0 :             if (!eq2taut)
    3052                 :             :             {
    3053                 :             :                 /* compare isotopic non-tautomeric equivalence to non-tautomeric */
    3054                 :           0 :                 eq2taut = Eql_INChI_Aux_Equ( pINChI_Aux, EQL_EQU_ISO, pINChI_Aux, EQL_EQU );
    3055                 :             :                 /* equ  non-taut    isotopic = non-tautomeric*/
    3056         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiEQU | iitNONTAUT | iitISO | iiEq2NONTAUT ) : 0;
    3057                 :             :             }
    3058         [ #  # ]:           0 :             if (!eq2taut)
    3059                 :             :             {
    3060                 :             :                 /* compare isotopic non-tautomeric equivalence to isotopic tautomeric */
    3061                 :           0 :                 eq2taut = Eql_INChI_Aux_Equ( pINChI_Aux, EQL_EQU_ISO, pINChI_Aux_Taut, EQL_EQU_ISO );
    3062                 :             :                 /* equ   non-taut     isotopic = isotopic tautomeric*/
    3063         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiEQU | iitNONTAUT | iitISO | iiEq2ISO ) : 0;
    3064                 :             :             }
    3065                 :             :         }
    3066                 :             :         else
    3067                 :             :         {
    3068   [ #  #  #  #  :           0 :             if (!bSecondNonTautPass && bOmitRepetitions && pINChI_Aux && pINChI_Aux->bIsIsotopic)
             #  #  #  # ]
    3069                 :             :             {
    3070                 :             :                 /**************************************************
    3071                 :             :                 * compare isotopic tautomeric equivalence to:
    3072                 :             :                 *    a) non-isotopic tautomeric
    3073                 :             :                 */
    3074         [ #  # ]:           0 :                 if (!eq2taut)
    3075                 :             :                 {
    3076                 :             :                     /* compare isotopic tautomeric equivalence to tautomeric */
    3077                 :           0 :                     eq2taut = Eql_INChI_Aux_Equ( pINChI_Aux, EQL_EQU_ISO, pINChI_Aux, EQL_EQU );
    3078                 :             :                     /* equ   taut-isotopic = tautomeric*/
    3079         [ #  # ]:           0 :                     eq2taut = eq2taut ? ( iiEQU | iitISO ) : 0;
    3080                 :             :                 }
    3081                 :             :             }
    3082                 :             :         }
    3083         [ #  # ]:           0 :         if (eq2taut)
    3084                 :             :         {
    3085                 :             :             /* we may be here only in case of the second (non-taut) pass */
    3086                 :             :             /* current non-taut equivalence has been found to be same as tautomeric */
    3087   [ #  #  #  # ]:           0 :             if (pINChI_Aux_Prev && pINChI_Aux_Prev->nNumberOfAtoms)
    3088                 :             :             {
    3089                 :             :                 /* previous component exists */
    3090         [ #  # ]:           0 :                 if (bNext++)
    3091                 :             :                 {
    3092                 :           0 :                     MakeDelim( sCompDelim, strbuf, bOverflow );
    3093                 :             :                 }
    3094         [ #  # ]:           0 :                 if (bHasEquString( pINChI_Aux_Prev->nConstitEquIsotopicNumbers, pINChI_Aux_Prev->nNumberOfAtoms ))
    3095                 :             :                 {
    3096                 :             :                     /* output previous component(s) equivalence since it was found to be non-trivial */
    3097                 :           0 :                     MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
    3098                 :           0 :                     MakeEquString( pINChI_Aux_Prev->nConstitEquIsotopicNumbers, pINChI_Aux_Prev->nNumberOfAtoms, 0,
    3099                 :             :                         strbuf, TAUT_MODE, bOverflow );
    3100                 :             :                 }
    3101                 :             :                 else
    3102                 :             :                 {
    3103                 :             :                     ; /* pINChI_Aux_Prev exists and has only trivial equivalence info */
    3104                 :             :                 }
    3105                 :             :             }
    3106                 :             :             else
    3107                 :             :             {
    3108   [ #  #  #  # ]:           0 :                 if (pINChI_Aux_Taut_Prev && pINChI_Aux_Taut_Prev->nNumberOfAtoms)
    3109                 :             :                 {
    3110                 :             :                     /* previous non-taut component exists only in taut list */
    3111         [ #  # ]:           0 :                     if (bNext++)
    3112                 :             :                     {
    3113                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    3114                 :             :                     }
    3115                 :             :                 }
    3116                 :             :             }
    3117                 :             :             /* we have found pINChI_Aux->pINChI_Aux->nConstitEquIsotopicNumbers same as in pINChI_Aux_Taut */
    3118                 :             :             /* output this (current) equivalence as '*', that is, same as tautomeric */
    3119                 :             :             /* that was printed on the 1st pass. */
    3120                 :           0 :             pCurrEquStr = EquString( eq2taut );
    3121   [ #  #  #  # ]:           0 :             if (multPrevEquStr && pPrevEquStr)
    3122                 :             :             {
    3123   [ #  #  #  # ]:           0 :                 if (pCurrEquStr && !strcmp( pCurrEquStr, pPrevEquStr ))
    3124                 :             :                 {
    3125                 :           0 :                     multPrevEquStr++;
    3126                 :             :                 }
    3127                 :             :                 else
    3128                 :             :                 {
    3129                 :             :                     /* new EqStr is different; output it */
    3130         [ #  # ]:           0 :                     if (bNext++)
    3131                 :             :                     {
    3132                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    3133                 :             :                     }
    3134                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    3135                 :           0 :                     pPrevEquStr = pCurrEquStr;
    3136                 :           0 :                     multPrevEquStr = 1;
    3137                 :             :                 }
    3138                 :             :             }
    3139                 :             :             else
    3140                 :             :             {
    3141                 :           0 :                 pPrevEquStr = pCurrEquStr;
    3142                 :           0 :                 multPrevEquStr = 1;
    3143                 :             :             }
    3144                 :           0 :             pINChI_Aux_Prev = NULL; /* pINChI_Aux_Prev does not exist since */
    3145                 :           0 :             pINChI_Aux_Taut_Prev = NULL; /* pINChI_Aux has just been printed */
    3146                 :           0 :             mult = 0;
    3147                 :           0 :             eq2tautPrev = 1;
    3148                 :             :         }
    3149                 :             :         else
    3150                 :             :         {
    3151         [ #  # ]:           0 :             if (eq2tautPrev)
    3152                 :             :             {
    3153                 :             :                 /* at this point pINChI_Aux_Prev does not exist; however, pINChI_Aux */
    3154                 :             :                 /*might have been discovered and it is different from pINChI_Aux_Taut */
    3155   [ #  #  #  # ]:           0 :                 if (multPrevEquStr && pPrevEquStr)
    3156                 :             :                 {
    3157                 :             :                     /* new EqStr is different; output it */
    3158         [ #  # ]:           0 :                     if (bNext++)
    3159                 :             :                     {
    3160                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    3161                 :             :                     }
    3162                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    3163                 :           0 :                     pPrevEquStr = NULL;
    3164                 :           0 :                     multPrevEquStr = 0;
    3165                 :             :                 }
    3166                 :           0 :                 eq2tautPrev = 0;
    3167                 :           0 :                 pINChI_Aux_Prev = pINChI_Aux;
    3168                 :           0 :                 pINChI_Aux_Taut_Prev = pINChI_Aux_Taut;
    3169                 :           0 :                 mult = 0;
    3170                 :             :             }
    3171                 :             :             else
    3172                 :             :             {
    3173                 :             :                 /* check whether pINChI_Aux and pINChI_Aux_Prev have identical non-trivial equivalence info */
    3174   [ #  #  #  # ]:           0 :                 eq2prev = bUseMulipliers && Eql_INChI_Aux_Equ( pINChI_Aux, EQL_EQU_ISO, pINChI_Aux_Prev, EQL_EQU_ISO );
    3175         [ #  # ]:           0 :                 if (eq2prev)
    3176                 :             :                 {
    3177                 :             :                     /* eq. info is same and non-trivial */
    3178                 :           0 :                     mult++; /* mult = (number of non-empty equal items)-1 */
    3179                 :           0 :                     continue;
    3180                 :             :                 }
    3181                 :             :                 else
    3182                 :             :                 {
    3183                 :             :                     /* pINChI_Aux eq. info is either different or trivial. Output pINChI_Aux_Prev anyway */
    3184         [ #  # ]:           0 :                     if (bNext++)
    3185                 :             :                     {
    3186                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    3187                 :             :                     }
    3188   [ #  #  #  # ]:           0 :                     if (pINChI_Aux_Prev && pINChI_Aux_Prev->nNumberOfAtoms)
    3189                 :             :                     {
    3190         [ #  # ]:           0 :                         if (bHasEquString( pINChI_Aux_Prev->nConstitEquIsotopicNumbers, pINChI_Aux_Prev->nNumberOfAtoms ))
    3191                 :             :                         {
    3192                 :             :                             /* pINChI_Aux_Prev exists and has equivalence info */
    3193                 :           0 :                             MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
    3194                 :           0 :                             MakeEquString( pINChI_Aux_Prev->nConstitEquIsotopicNumbers, pINChI_Aux_Prev->nNumberOfAtoms, 0,
    3195                 :             :                                 strbuf, TAUT_MODE, bOverflow );
    3196                 :             :                         }
    3197                 :             :                         else
    3198                 :             :                         {
    3199                 :             :                             ; /* pINChI_Aux_Prev exists and has only trivial equivalence info */
    3200                 :             :                         }
    3201                 :             :                     }
    3202                 :             :                     else
    3203                 :             :                     {
    3204   [ #  #  #  #  :           0 :                         if (bSecondNonTautPass && pINChI_Aux_Taut_Prev && pINChI_Aux_Taut_Prev->nNumberOfAtoms)
                   #  # ]
    3205                 :             :                         {
    3206                 :           0 :                             if (bHasEquString( pINChI_Aux_Taut_Prev->nConstitEquIsotopicNumbers, pINChI_Aux_Taut_Prev->nNumberOfAtoms ))
    3207                 :             :                             {
    3208                 :             :                                 /* since pINChI_Aux_Prev does not exist, pINChI_Aux_Taut_Prev is non-tautomeric */
    3209                 :             :                                 /* and it has non-trivial equivalence info. This info has already been printed in the main section  */
    3210                 :             :                                 /*
    3211                 :             :                                 MakeDelim( sIdenticalValues, strbuf, bOverflow);
    3212                 :             :                                 */
    3213                 :             :                             }
    3214                 :             :                             else
    3215                 :             :                             {
    3216                 :             :                                 ; /* pINChI_Aux_Taut_Prev exists and has only trivial equivalence info */
    3217                 :             :                             }
    3218                 :             :                         }
    3219                 :             : #if ( bRELEASE_VERSION != 1 && defined(_DEBUG) )
    3220                 :             :                         else
    3221                 :             :                         {
    3222                 :             :                             int stop = 1;   /* <BRKPT> */
    3223                 :             :                         }
    3224                 :             : #endif
    3225                 :             :                     }
    3226                 :             :                 }
    3227                 :           0 :                 pINChI_Aux_Prev = pINChI_Aux;
    3228                 :           0 :                 pINChI_Aux_Taut_Prev = pINChI_Aux_Taut;
    3229                 :           0 :                 mult = 0; /* we do not know whether the item is empty */
    3230                 :             :             }
    3231                 :             :         }
    3232                 :             :     }
    3233                 :             : 
    3234                 :           0 :     return ( strbuf->nUsedLength - nUsedLength0 );
    3235                 :             : }
    3236                 :             : 
    3237                 :             : 
    3238                 :             : /****************************************************************************
    3239                 :             :   Produce isotopic tetr stereo inversion substring of AuxInfo.
    3240                 :             : ****************************************************************************/
    3241                 :           0 : int str_AuxInvIsoSp3( INCHI_SORT       *pINChISort,
    3242                 :             :                       INCHI_SORT       *pINChISort2,
    3243                 :             :                       INCHI_IOS_STRING *strbuf,
    3244                 :             :                       int              *bOverflow,
    3245                 :             :                       int              bOutType,
    3246                 :             :                       int              TAUT_MODE,
    3247                 :             :                       int              num_components,
    3248                 :             :                       int              bSecondNonTautPass,
    3249                 :             :                       int              bOmitRepetitions,
    3250                 :             :                       int              bUseMulipliers )
    3251                 :             : {
    3252                 :             :     int          i, ii, ii2, nUsedLength0;
    3253                 :             :     INCHI_SORT   *is, *is2, *is0, *is20;
    3254                 :             :     INChI        *pINChI, *pINChI_Prev, *pINChI_Taut, *pINChI_Taut_Prev;
    3255                 :             :     INChI_Stereo *Stereo, *Stereo_Prev, *Stereo_Taut, *Stereo_Taut_Prev;
    3256                 :             :     int          mult, eq2prev, eq2taut, eq2tautPrev, bNext;
    3257                 :             :     const char  *pPrevEquStr, *pCurrEquStr;
    3258                 :             :     int         multPrevEquStr;
    3259                 :             :     /********************************
    3260                 :             :     inverted isotopic sp3
    3261                 :             :     *********************************/
    3262                 :           0 :     pINChI_Taut = NULL;
    3263                 :           0 :     pINChI_Prev = NULL;
    3264                 :           0 :     pINChI_Taut_Prev = NULL;
    3265                 :           0 :     mult = 0;
    3266                 :           0 :     bNext = 0;
    3267                 :           0 :     is = NULL;
    3268                 :           0 :     is2 = NULL;
    3269                 :           0 :     is0 = pINChISort;
    3270         [ #  # ]:           0 :     is20 = bSecondNonTautPass ? pINChISort2 : NULL;
    3271                 :             :     /* djb-rwth: removing redundant code */
    3272                 :           0 :     eq2tautPrev = 1; /* pINChI_Prev (previous pINChI) does not exist */
    3273                 :           0 :     pPrevEquStr = NULL; /*, *pCurrEquStr;*/
    3274                 :           0 :     multPrevEquStr = 0;
    3275                 :           0 :     nUsedLength0 = strbuf->nUsedLength;
    3276                 :             : 
    3277                 :             :     /* For each connected component...    */
    3278         [ #  # ]:           0 :     for (i = 0; i <= num_components; i++)
    3279                 :             :     {
    3280                 :             : 
    3281                 :             :         /* 1st (taut) pass: bOutType=OUT_TN  ; 2nd (non-taut pass) bOutType=OUT_NT */
    3282   [ #  #  #  #  :           0 :         pINChI = ( i < num_components && ( is = is0 + i, 0 <= ( ii = GET_II( bOutType, is ) ) ) ) ? is->pINChI[ii] : NULL;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    3283                 :             :         /*================ compare sp2 to previous =====================*/
    3284         [ #  # ]:           0 :         if (bSecondNonTautPass)
    3285                 :             :         {
    3286                 :             :             /* component that was output on the 1st pass */
    3287   [ #  #  #  #  :           0 :             pINChI_Taut = ( i < num_components && ( is2 = is20 + i, 0 <= ( ii2 = GET_II( OUT_T1, is2 ) ) ) ) ? is2->pINChI[ii2] : NULL;
          #  #  #  #  #  
                #  #  # ]
    3288                 :             :         }
    3289                 :           0 :         eq2taut = 0;
    3290                 :             :         /*========= if bSecondNonTautPass then compare iso non-taut stereo to other stereo ========*/
    3291   [ #  #  #  #  :           0 :         if (bSecondNonTautPass && bOmitRepetitions && pINChI && pINChI->nNumberOfIsotopicAtoms + pINChI->nNumberOfIsotopicTGroups > 0)
             #  #  #  # ]
    3292                 :             :         {
    3293                 :             :             /* compare non-tautomeric isotopic inverted to:
    3294                 :             :             *   a) tautomeric inverted
    3295                 :             :             *   b) *non-tautomeric inverted
    3296                 :             :             *   c) *isotopic tautomeric inverted
    3297                 :             :             *   d) Inverted(tautomeric)
    3298                 :             :             *   e) *Inverted(tautomeric isotopic)
    3299                 :             :             *   f) Inverted(non-tautomeric)
    3300                 :             :             *   g) *Inverted(non-tautomeric isotopic)
    3301                 :             :             */
    3302                 :             :             /* a) compare non-tautomeric isotopic inverted to tautomeric inverted */
    3303         [ #  # ]:           0 :             if (!eq2taut)
    3304                 :             :             {
    3305         [ #  # ]:           0 :                 eq2taut = pINChI && pINChI_Taut &&
    3306                 :             :                     /* non-taut inverted */          /* taut invertedc */
    3307   [ #  #  #  #  :           0 :                     ( Stereo = pINChI->StereoIsotopic ) && ( Stereo_Taut = pINChI_Taut->Stereo ) &&
             #  #  #  # ]
    3308                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP3_INV, Stereo_Taut, EQL_SP3_INV, 0 );
    3309                 :             :                 /* stereo-inv    isotopic  non-taut =  taut (stereo-inv) */
    3310         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO_INV | iitISO | iitNONTAUT ) : 0;
    3311                 :             :             }
    3312                 :             :             /* b) compare non-tautomeric isotopic inverted to non-tautomeric inverted */
    3313         [ #  # ]:           0 :             if (!eq2taut)
    3314                 :             :             {
    3315                 :           0 :                 eq2taut = pINChI &&                    /* it is non-taut non-iso stereo */
    3316   [ #  #  #  #  :           0 :                     ( Stereo = pINChI->StereoIsotopic ) && ( Stereo_Taut = pINChI->Stereo ) &&
             #  #  #  # ]
    3317                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP3_INV, Stereo_Taut, EQL_SP3_INV, 0 );
    3318                 :             :                 /* stereo-inv    isotopic non-taut =  non-taut stereo-inv */
    3319         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO_INV | iitISO | iitNONTAUT | iiEq2NONTAUT ) : 0;
    3320                 :             :             }
    3321                 :             :             /* c) compare non-tautomeric isotopic inverted to isotopic tautomeric inverted */
    3322         [ #  # ]:           0 :             if (!eq2taut)
    3323                 :             :             {
    3324         [ #  # ]:           0 :                 eq2taut = pINChI && pINChI_Taut &&
    3325                 :             :                     /* non-taut iso. inverted */             /* taut iso. inverted */
    3326   [ #  #  #  #  :           0 :                     ( Stereo = pINChI->StereoIsotopic ) && ( Stereo_Taut = pINChI_Taut->StereoIsotopic ) &&
             #  #  #  # ]
    3327                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP3_INV, Stereo_Taut, EQL_SP3_INV, 0 );
    3328                 :             :                 /* stereo-inv    isotopic  non-taut =  taut iso. stereo-inv */
    3329         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO_INV | iitISO | iitNONTAUT | iiEq2ISO ) : 0;
    3330                 :             :             }
    3331                 :             :             /* d) compare non-tautomeric inverted to Inverted(tautomeric stereo) */
    3332         [ #  # ]:           0 :             if (!eq2taut)
    3333                 :             :             {
    3334         [ #  # ]:           0 :                 eq2taut = pINChI && pINChI_Taut &&
    3335   [ #  #  #  #  :           0 :                     ( Stereo = pINChI->StereoIsotopic ) && ( Stereo_Taut = pINChI_Taut->Stereo ) &&
             #  #  #  # ]
    3336                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP3_INV, Stereo_Taut, EQL_SP3_INV, 0 );
    3337                 :             :                 /* stereo-inv   isotopic  non-taut =  Inv(non-iso taut stereo) */
    3338         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO_INV | iitISO | iitNONTAUT | iiEq2INV ) : 0;
    3339                 :             :             }
    3340                 :             :             /* e) compare non-tautomeric inverted to Inverted(isotopic tautomeric stereo) */
    3341         [ #  # ]:           0 :             if (!eq2taut)
    3342                 :             :             {
    3343         [ #  # ]:           0 :                 eq2taut = pINChI && pINChI_Taut &&
    3344   [ #  #  #  #  :           0 :                     ( Stereo = pINChI->StereoIsotopic ) && ( Stereo_Taut = pINChI_Taut->StereoIsotopic ) &&
             #  #  #  # ]
    3345                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP3_INV, Stereo_Taut, EQL_SP3, 0 );
    3346                 :             :                 /* stereo-inv   isotopic  non-taut =  Inv(iso taut stereo) */
    3347         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO_INV | iitISO | iitNONTAUT | iiEq2INV | iiEq2ISO ) : 0;
    3348                 :             :             }
    3349                 :             :             /* f) compare non-tautomeric isotopic inverted to Inverted(non-tautomeric stereo) */
    3350         [ #  # ]:           0 :             if (!eq2taut)
    3351                 :             :             {
    3352                 :           0 :                 eq2taut = pINChI &&                    /* it is non-taut non-iso stereo */
    3353   [ #  #  #  #  :           0 :                     ( Stereo = pINChI->StereoIsotopic ) && ( Stereo_Taut = pINChI->Stereo ) &&
             #  #  #  # ]
    3354                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP3_INV, Stereo_Taut, EQL_SP3, 0 );
    3355                 :             :                 /* stereo-inv   isotopic    non-taut =  Inv(non-taut stereo) */
    3356         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO_INV | iitISO | iitNONTAUT | iiEq2INV | iiEq2NONTAUT ) : 0;
    3357                 :             :             }
    3358                 :             :             /* g) compare non-tautomeric isotopic inverted to Inverted(non-tautomeric isotopic stereo) */
    3359         [ #  # ]:           0 :             if (!eq2taut)
    3360                 :             :             {
    3361                 :           0 :                 eq2taut = pINChI &&                    /* it is non-taut non-iso stereo */
    3362   [ #  #  #  #  :           0 :                     ( Stereo = pINChI->StereoIsotopic ) &&
                   #  # ]
    3363                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP3_INV, Stereo, EQL_SP3, 0 );
    3364                 :             :                 /* stereo-inv    isotopic  non-taut =   Inv( iso non-taut stereo) */
    3365         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO_INV | iitISO | iitNONTAUT | iiEq2INV | iiEq2ISO | iiEq2NONTAUT ) : 0;
    3366                 :             :             }
    3367                 :             : #if ( FIX_EMPTY_LAYER_BUG == 1 )
    3368                 :             :             if (!eq2taut && pINChI && !( ( Stereo = pINChI->StereoIsotopic ) &&
    3369                 :             :                 Eql_INChI_Stereo( Stereo, EQL_SP3_INV, NULL, EQL_EXISTS, 0 ) ))
    3370                 :             :             {
    3371                 :             :                 /* component has no stereo; check whether it has stereo in the preceding layers */
    3372                 :             :                 if (pINChI_Taut && ( Stereo_Taut = pINChI_Taut->Stereo ) && /* F is not empty */
    3373                 :             :                     Eql_INChI_Stereo( Stereo_Taut, EQL_SP3_INV, NULL, EQL_EXISTS, 0 ) ||
    3374                 :             :                     !( pINChI_Taut && ( Stereo_Taut = pINChI_Taut->Stereo ) &&  /* M is empty and ... */
    3375                 :             :                         Eql_INChI_Stereo( Stereo_Taut, EQL_SP3_INV, NULL, EQL_EXISTS, 0 ) ) &&
    3376                 :             :                         ( pINChI_Taut && ( Stereo_Taut = pINChI_Taut->StereoIsotopic ) &&  /* ... MI is not empty */
    3377                 :             :                             Eql_INChI_Stereo( Stereo_Taut, EQL_SP3_INV, NULL, EQL_EXISTS, 0 ) ))
    3378                 :             :                 {
    3379                 :             : 
    3380                 :             :                     eq2taut = iiEmpty; /* the component has stereo in the preceding layer  */
    3381                 :             :                 }
    3382                 :             :             }
    3383                 :             : #endif
    3384                 :             :         }
    3385                 :             :         else
    3386                 :             :         {
    3387                 :             :             /*========= if not bSecondNonTautPass then compare inv taut stereo to various stereo ========*/
    3388   [ #  #  #  #  :           0 :             if (!bSecondNonTautPass && bOmitRepetitions && pINChI &&
                   #  # ]
    3389         [ #  # ]:           0 :                 ( pINChI->nNumberOfIsotopicAtoms > 0 ||
    3390         [ #  # ]:           0 :                   pINChI->nNumberOfIsotopicTGroups > 0 ||
    3391   [ #  #  #  # ]:           0 :                   (pINChI->nPossibleLocationsOfIsotopicH && pINChI->nPossibleLocationsOfIsotopicH[0] > 1) )) /* djb-rwth: addressing LLVM warning */
    3392                 :             :             {
    3393                 :             :                 /* compare tautomeric isotopic stereo-inverted to:
    3394                 :             :                 *    a) tautomeric stereo-inverted
    3395                 :             :                 *    b) Inverted(tautomeric stereo)
    3396                 :             :                 *    c) Inverted(tautomeric isotopic stereo)
    3397                 :             :                 */
    3398                 :             :                 /* a) compare tautomeric isotopic stereo-inverted to tautomeric stereo-inverted */
    3399         [ #  # ]:           0 :                 if (!eq2taut)
    3400                 :             :                 {
    3401                 :           0 :                     eq2taut = pINChI &&
    3402   [ #  #  #  #  :           0 :                         ( Stereo = pINChI->StereoIsotopic ) && ( Stereo_Taut = pINChI->Stereo ) &&
             #  #  #  # ]
    3403                 :           0 :                         Eql_INChI_Stereo( Stereo, EQL_SP3_INV, Stereo_Taut, EQL_SP3_INV, 0 );
    3404                 :             :                     /* stereo-inv  isotopic taut =  taut stereo-inv */
    3405         [ #  # ]:           0 :                     eq2taut = eq2taut ? ( iiSTEREO_INV | iitISO ) : 0;
    3406                 :             :                 }
    3407                 :             :                 /* b) compare tautomeric isotopic stereo-inverted to Inverted(tautomeric stereo) */
    3408         [ #  # ]:           0 :                 if (!eq2taut)
    3409                 :             :                 {
    3410                 :           0 :                     eq2taut = pINChI &&
    3411   [ #  #  #  #  :           0 :                         ( Stereo = pINChI->StereoIsotopic ) && ( Stereo_Taut = pINChI->Stereo ) &&
             #  #  #  # ]
    3412                 :           0 :                         Eql_INChI_Stereo( Stereo, EQL_SP3_INV, Stereo_Taut, EQL_SP3, 0 );
    3413                 :             :                     /* stereo-inv   isotopic taut =  Inv(taut stereo) */
    3414         [ #  # ]:           0 :                     eq2taut = eq2taut ? ( iiSTEREO_INV | iitISO | iiEq2INV ) : 0;
    3415                 :             :                 }
    3416                 :             :                 /* c) compare tautomeric isotopic stereo-inverted to Inverted(tautomeric isotopic stereo) */
    3417         [ #  # ]:           0 :                 if (!eq2taut)
    3418                 :             :                 {
    3419                 :           0 :                     eq2taut = pINChI &&
    3420   [ #  #  #  #  :           0 :                         ( Stereo = pINChI->StereoIsotopic ) &&
                   #  # ]
    3421                 :           0 :                         Eql_INChI_Stereo( Stereo, EQL_SP3_INV, Stereo, EQL_SP3, 0 );
    3422                 :             :                     /* stereo-inv   isotopic taut =  Inv(taut iso stereo) */
    3423         [ #  # ]:           0 :                     eq2taut = eq2taut ? ( iiSTEREO_INV | iitISO | iiEq2INV | iiEq2ISO ) : 0;
    3424                 :             :                 }
    3425                 :             : #if ( FIX_EMPTY_LAYER_BUG == 1 )
    3426                 :             :                 if (!eq2taut && pINChI && !( ( Stereo = pINChI->StereoIsotopic ) &&
    3427                 :             :                                              Eql_INChI_Stereo( Stereo, EQL_SP3_INV, NULL, EQL_EXISTS, 0 ) ))
    3428                 :             :                 {
    3429                 :             :                     /* component has no MI stereo; check whether it has stereo in the preceding layer M */
    3430                 :             :                     if (( Stereo_Taut = pINChI->Stereo ) &&
    3431                 :             :                         Eql_INChI_Stereo( Stereo_Taut, EQL_SP3_INV, NULL, EQL_EXISTS, 0 ))
    3432                 :             :                     {
    3433                 :             :                         eq2taut = iiEmpty; /* the component has stereo in the preceding layer  */
    3434                 :             :                     }
    3435                 :             :                 }
    3436                 :             : #endif
    3437                 :             :             }
    3438                 :             :         }
    3439         [ #  # ]:           0 :         if (eq2taut)
    3440                 :             :         {
    3441                 :             :             /* we may be here only in case of the current layer found equal in another layer the same component */
    3442   [ #  #  #  # ]:           0 :             if (pINChI_Prev && pINChI_Prev->nNumberOfAtoms)
    3443                 :             :             {
    3444                 :             :                 /* previous component exists; output it before output the current component */
    3445         [ #  # ]:           0 :                 if (bNext++)
    3446                 :             :                 {
    3447                 :           0 :                     MakeDelim( sCompDelim, strbuf, bOverflow );
    3448                 :             :                 }
    3449   [ #  #  #  # ]:           0 :                 if (( Stereo_Prev = pINChI_Prev->StereoIsotopic ) && Stereo_Prev->nNumberOfStereoCenters > 0)
    3450                 :             :                 {
    3451                 :           0 :                     MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
    3452                 :             : 
    3453                 :           0 :                     MakeStereoString( Stereo_Prev->nNumber, NULL, Stereo_Prev->t_parityInv,
    3454                 :             :                         0, Stereo_Prev->nNumberOfStereoCenters,
    3455                 :             :                         strbuf, TAUT_MODE, bOverflow );
    3456                 :             :                 }
    3457                 :             :             }
    3458                 :             :             else
    3459                 :             :             {
    3460   [ #  #  #  # ]:           0 :                 if (pINChI_Taut_Prev && pINChI_Taut_Prev->nNumberOfAtoms)
    3461                 :             :                 {
    3462                 :             :                     /* previous non-taut component exists only in taut list */
    3463         [ #  # ]:           0 :                     if (bNext++)
    3464                 :             :                     {
    3465                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    3466                 :             :                     }
    3467                 :             :                     /* do not output stereo of non-tautomeric in non-taut layer: it has been output in the main layer */
    3468                 :             :                 }
    3469                 :             :             }
    3470                 :             :             /* we have found another (previously printed) layer of the current component equal to this layer */
    3471                 :             :             /* output this (current) equivalence mark = EquString(eq2taut) */
    3472                 :           0 :             pCurrEquStr = EquString( eq2taut );
    3473   [ #  #  #  # ]:           0 :             if (multPrevEquStr && pPrevEquStr)
    3474                 :             :             {
    3475   [ #  #  #  # ]:           0 :                 if (pCurrEquStr && !strcmp( pCurrEquStr, pPrevEquStr ))
    3476                 :             :                 {
    3477                 :           0 :                     multPrevEquStr++;
    3478                 :             :                 }
    3479                 :             :                 else
    3480                 :             :                 {
    3481                 :             :                     /* new EqStr is different; output it */
    3482         [ #  # ]:           0 :                     if (bNext++)
    3483                 :             :                     {
    3484                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    3485                 :             :                     }
    3486                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    3487                 :           0 :                     pPrevEquStr = pCurrEquStr;
    3488                 :           0 :                     multPrevEquStr = 1;
    3489                 :             :                 }
    3490                 :             :             }
    3491                 :             :             else
    3492                 :             :             {
    3493                 :           0 :                 pPrevEquStr = pCurrEquStr;
    3494                 :           0 :                 multPrevEquStr = 1;
    3495                 :             :             }
    3496                 :           0 :             pINChI_Prev = NULL; /* pINChI_Prev sp2 does not exist since */
    3497                 :           0 :             pINChI_Taut_Prev = NULL; /* pINChI has just been printed */
    3498                 :           0 :             mult = 0;
    3499                 :           0 :             eq2tautPrev = 1;     /* pINChI_Prev and pINChI_Taut_Prev have already been output */
    3500                 :             :         }
    3501                 :             :         else
    3502                 :             :         {
    3503         [ #  # ]:           0 :             if (eq2tautPrev)
    3504                 :             :             {
    3505                 :             :                 /* at this point pINChI_Prev does not exist; however, pINChI */
    3506                 :             :                 /*might have been discovered and it is different from pINChI_Taut */
    3507   [ #  #  #  # ]:           0 :                 if (multPrevEquStr && pPrevEquStr)
    3508                 :             :                 {
    3509                 :             :                     /* new EqStr is different; output it */
    3510         [ #  # ]:           0 :                     if (bNext++)
    3511                 :             :                     {
    3512                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    3513                 :             :                     }
    3514                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    3515                 :           0 :                     pPrevEquStr = NULL;
    3516                 :           0 :                     multPrevEquStr = 0;
    3517                 :             :                 }
    3518                 :           0 :                 eq2tautPrev = 0;
    3519                 :           0 :                 pINChI_Prev = pINChI;
    3520                 :           0 :                 pINChI_Taut_Prev = pINChI_Taut;
    3521                 :           0 :                 mult = 0;
    3522                 :             :             }
    3523                 :             :             else
    3524                 :             :             {
    3525                 :             :                 /* current layer is different from previously printed layers of the current component */
    3526                 :             :                 /* compare the current layer to this layer of the previous component: */
    3527                 :             :                 /* check whether pINChI and pINChI_Prev have non-zero identical stereo sp2 */
    3528                 :             :                 /*================ compare iso sp3 to previous =====================*/
    3529         [ #  # ]:           0 :                 eq2prev = bUseMulipliers &&
    3530   [ #  #  #  # ]:           0 :                     pINChI && pINChI->nNumberOfIsotopicAtoms + pINChI->nNumberOfIsotopicTGroups > 0 &&
    3531         [ #  # ]:           0 :                     pINChI_Prev && pINChI_Prev->nNumberOfIsotopicAtoms + pINChI_Prev->nNumberOfIsotopicTGroups > 0 &&
    3532                 :             :                     /* do both have stereo? */
    3533   [ #  #  #  #  :           0 :                     ( Stereo = pINChI->StereoIsotopic ) && ( Stereo_Prev = pINChI_Prev->StereoIsotopic ) &&
             #  #  #  # ]
    3534                 :             :                     /* is their inverted stereo same? */
    3535                 :           0 :                     Eql_INChI_Stereo( Stereo, EQL_SP3_INV, Stereo_Prev, EQL_SP3_INV, 0 );
    3536         [ #  # ]:           0 :                 if (eq2prev)
    3537                 :             :                 {
    3538                 :           0 :                     mult++; /* mult = (number of non-empty equal items)-1 */
    3539                 :           0 :                     continue;
    3540                 :             :                 }
    3541                 :             :                 else
    3542                 :             :                 {
    3543         [ #  # ]:           0 :                     if (bNext++)
    3544                 :             :                     {
    3545                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    3546                 :             :                     }
    3547   [ #  #  #  #  :           0 :                     if (pINChI_Prev && pINChI_Prev->nNumberOfAtoms && pINChI_Prev->nNumberOfIsotopicAtoms + pINChI_Prev->nNumberOfIsotopicTGroups > 0)
                   #  # ]
    3548                 :             :                     {
    3549         [ #  # ]:           0 :                         if (( Stereo_Prev = pINChI_Prev->StereoIsotopic ) &&
    3550   [ #  #  #  # ]:           0 :                             Stereo_Prev->nNumberOfStereoCenters > 0 && Stereo_Prev->nCompInv2Abs)
    3551                 :             :                         {
    3552                 :           0 :                             MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
    3553                 :             : 
    3554                 :           0 :                             MakeStereoString( Stereo_Prev->nNumberInv, NULL, Stereo_Prev->t_parityInv,
    3555                 :             :                                 0, Stereo_Prev->nNumberOfStereoCenters,
    3556                 :             :                                 strbuf, TAUT_MODE, bOverflow );
    3557                 :             :                         }
    3558                 :             :                         /* else sp3 info is not present in pINChI_Prev */
    3559                 :             :                     }
    3560                 :             :                     else
    3561                 :             :                     {
    3562                 :             :                         /* do not print pINChI_Prev because it either do not exist of have already been printed */
    3563   [ #  #  #  #  :           0 :                         if (bSecondNonTautPass && pINChI_Taut_Prev && pINChI_Taut_Prev->nNumberOfAtoms)
                   #  # ]
    3564                 :             :                         {
    3565         [ #  # ]:           0 :                             if (( Stereo_Taut_Prev = pINChI_Taut_Prev->StereoIsotopic ) &&
    3566         [ #  # ]:           0 :                                 Stereo_Taut_Prev->nNumberOfStereoCenters > 0 && Stereo_Taut_Prev->nCompInv2Abs)
    3567                 :             :                             {
    3568                 :             :                                 /* since pINChI_Prev does not exist, pINChI_Taut_Prev is non-tautomeric */
    3569                 :             :                                 /* and it has non-trivial inv sp3 info. It has already been printed in the main section */
    3570                 :             :                                 /*
    3571                 :             :                                 tot_len += MakeDelim( sIdenticalValues, strbuf, bOverflow);
    3572                 :             :                                 */
    3573                 :             :                                 ;/* pINChI_Taut_Prev sp3 info was output in the main stereo section */
    3574                 :             :                             }
    3575                 :             :                             else
    3576                 :             :                             {
    3577                 :             :                                 ; /* pINChI_Taut_Prev exists and has not sp3 info */
    3578                 :             :                             }
    3579                 :             :                         }
    3580                 :             : #if ( bRELEASE_VERSION != 1 && defined(_DEBUG) )
    3581                 :             :                         else
    3582                 :             :                         {
    3583                 :             :                             int stop = 1;   /* <BRKPT> */
    3584                 :             :                         }
    3585                 :             : #endif
    3586                 :             :                     }
    3587                 :             :                 }
    3588                 :           0 :                 pINChI_Prev = pINChI;
    3589                 :           0 :                 mult = 0; /* we do not know whether the item is empty */
    3590                 :             :             }
    3591                 :             :         }
    3592                 :             :     }
    3593                 :             : 
    3594                 :           0 :     return ( strbuf->nUsedLength - nUsedLength0 );
    3595                 :             : }
    3596                 :             : 
    3597                 :             : 
    3598                 :             : /****************************************************************************
    3599                 :             :   Produce isotopic tetr stereo inversion numbering substring of AuxInfo
    3600                 :             :   /iN: in Isotopic and/or FixedH-Iso parts,
    3601                 :             :   in both normal and in reconnected layers
    3602                 :             : ****************************************************************************/
    3603                 :           0 : int str_AuxInvIsoSp3Numb( CANON_GLOBALS    *pCG,
    3604                 :             :                           INCHI_SORT       *pINChISort,
    3605                 :             :                           INCHI_SORT       *pINChISort2,
    3606                 :             :                           INCHI_IOS_STRING *strbuf,
    3607                 :             :                           int              *bOverflow,
    3608                 :             :                           int              bOutType,
    3609                 :             :                           int              TAUT_MODE,
    3610                 :             :                           int              num_components,
    3611                 :             :                           int              bSecondNonTautPass,
    3612                 :             :                           int              bOmitRepetitions )
    3613                 :             : {
    3614                 :             :     int          i, ii, ii2, nUsedLength0;
    3615                 :             :     INCHI_SORT   *is, *is0 /*, *is2*/;
    3616                 :             :     INChI        *pINChI, *pINChI_Taut;
    3617                 :             :     INChI_Aux    *pINChI_Aux, *pINChI_Aux_Taut; /* djb-rwth: removing redundant variables */
    3618                 :             :     INChI_Stereo *Stereo, *Stereo_Taut;
    3619                 :             :     int          eq2taut, bNext;
    3620                 :             :     const char  *pPrevEquStr, *pCurrEquStr;
    3621                 :             :     int         multPrevEquStr;
    3622                 :             :     /**************************************************
    3623                 :             :     * specificity of numbering: there is no previous *
    3624                 :             :     * component because no repetition is possible    *
    3625                 :             :     **************************************************/
    3626                 :           0 :     pINChI = NULL;
    3627                 :           0 :     pINChI_Taut = NULL;
    3628                 :           0 :     pINChI_Aux = NULL;
    3629                 :           0 :     pINChI_Aux_Taut = NULL;
    3630                 :             :     /* djb-rwth: removing redundant code */
    3631                 :           0 :     bNext = 0;
    3632                 :           0 :     is = NULL;
    3633                 :             :     /* is2         = NULL;*/
    3634                 :           0 :     is0 = pINChISort;
    3635                 :             :     /* is20        = bSecondNonTautPass? pINChISort2 : NULL;*/
    3636                 :             :     /* djb-rwth: removing redundant code */
    3637                 :           0 :     pPrevEquStr = NULL; /*, *pCurrEquStr;*/
    3638                 :           0 :     multPrevEquStr = 0;
    3639                 :           0 :     nUsedLength0 = strbuf->nUsedLength;
    3640                 :             : 
    3641                 :             :     /* For each connected component...    */
    3642         [ #  # ]:           0 :     for (i = 0; i < num_components; i++)
    3643                 :             :     {
    3644                 :             : 
    3645                 :             :         /* 1st (taut) pass: bOutType=OUT_TN  ; 2nd (non-taut pass) bOutType=OUT_NT */
    3646                 :           0 :         is = is0 + i;
    3647   [ #  #  #  #  :           0 :         pINChI = ( 0 <= ( ii = GET_II( bOutType, is ) ) ) ? is->pINChI[ii] : NULL;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    3648         [ #  # ]:           0 :         pINChI_Aux = pINChI ? is->pINChI_Aux[ii] : NULL;
    3649                 :             :         /*================ to compare to previously printed =====================*/
    3650         [ #  # ]:           0 :         if (bSecondNonTautPass)
    3651                 :             :         {
    3652                 :             :             /* component that was printed on the 1st pass */
    3653   [ #  #  #  #  :           0 :             pINChI_Taut = ( 0 <= ( ii2 = GET_II( OUT_T1, is ) ) ) ? is->pINChI[ii2] : NULL;
          #  #  #  #  #  
                      # ]
    3654         [ #  # ]:           0 :             pINChI_Aux_Taut = pINChI_Taut ? is->pINChI_Aux[ii2] : NULL;
    3655                 :             :         }
    3656                 :           0 :         eq2taut = 0;
    3657                 :             :         /*========= if bSecondNonTautPass then compare iso non-taut stereo to other stereo ========*/
    3658   [ #  #  #  #  :           0 :         if (bSecondNonTautPass && bOmitRepetitions && pINChI && pINChI_Aux && pINChI_Aux->bIsIsotopic &&
          #  #  #  #  #  
                      # ]
    3659   [ #  #  #  # ]:           0 :             ( Stereo = pINChI->StereoIsotopic ) && Stereo->nCompInv2Abs &&
    3660   [ #  #  #  # ]:           0 :             pINChI_Aux->nNumberOfAtoms > 0 && pINChI_Aux->nIsotopicOrigAtNosInCanonOrdInv)
    3661                 :             :         {
    3662                 :             :             /* compare isotopic non-tautomeric inverted stereo numbering to:
    3663                 :             :             *   a) tautomeric numbering
    3664                 :             :             *   b) non-tautomeric numbering
    3665                 :             :             *   c) *tautomeric isotopic numbering
    3666                 :             :             *   d) *non-tautomeric isotopic numbering
    3667                 :             :             *   e) tautomeric inverted stereo numbering
    3668                 :             :             *   f) *non-tautomeric inverted stereo numbering
    3669                 :             :             *   g) tautomeric isotopic inverted stereo numbering
    3670                 :             :             */
    3671                 :             :             /* a) compare isotopic non-tautomeric inverted stereo numbering to tautomeric numbering */
    3672         [ #  # ]:           0 :             if (!eq2taut)
    3673                 :             :             {
    3674   [ #  #  #  # ]:           0 :                 eq2taut = pINChI_Taut &&
    3675                 :           0 :                     Eql_INChI_Aux_Num( pINChI_Aux, EQL_NUM_INV | EQL_NUM_ISO, pINChI_Aux_Taut, EQL_NUM );
    3676                 :             :                 /* stereo-inv   isotopic numbering  non-taut =  taut numbering */
    3677         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO_INV | iitISO | iiNUMB | iitNONTAUT ) : 0;
    3678                 :             :             }
    3679                 :             :             /* b) compare isotopic non-tautomeric inverted stereo numbering to non-tautomeric numbering */
    3680         [ #  # ]:           0 :             if (!eq2taut)
    3681                 :             :             {
    3682                 :             :                 eq2taut =
    3683                 :           0 :                     Eql_INChI_Aux_Num( pINChI_Aux, EQL_NUM_INV | EQL_NUM_ISO, pINChI_Aux, EQL_NUM );
    3684                 :             :                 /* stereo-inv    isotopic   numb.    non-taut =  non-taut numbering */
    3685         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO_INV | iitISO | iiNUMB | iitNONTAUT | iiEq2NONTAUT ) : 0;
    3686                 :             :             }
    3687                 :             :             /* c) compare isotopic non-tautomeric inverted stereo numbering to tautomeric isotopic numbering */
    3688         [ #  # ]:           0 :             if (!eq2taut)
    3689                 :             :             {
    3690   [ #  #  #  # ]:           0 :                 eq2taut = pINChI_Taut &&
    3691                 :           0 :                     Eql_INChI_Aux_Num( pINChI_Aux, EQL_NUM_INV | EQL_NUM_ISO, pINChI_Aux_Taut, EQL_NUM_ISO );
    3692                 :             :                 /* stereo-inv   isotopic   numb.     non-taut =  taut iso numbering */
    3693         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO_INV | iitISO | iiNUMB | iitNONTAUT | iiEq2ISO ) : 0;
    3694                 :             :             }
    3695                 :             :             /* d) compare isotopic non-tautomeric inverted stereo numbering to non-tautomeric isotopic numbering */
    3696         [ #  # ]:           0 :             if (!eq2taut)
    3697                 :             :             {
    3698                 :           0 :                 eq2taut = Eql_INChI_Aux_Num( pINChI_Aux, EQL_NUM_INV | EQL_NUM_ISO, pINChI_Aux, EQL_NUM_ISO );
    3699                 :             :                 /* stereo-inv   isotopic   numb.     non-taut =  non-taut isotopic numbering */
    3700         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO_INV | iitISO | iiNUMB | iitNONTAUT | iiEq2NONTAUT | iiEq2ISO ) : 0;
    3701                 :             :             }
    3702                 :             :             /* e) compare isotopic non-tautomeric inverted stereo numbering to tautomeric inverted stereo numbering */
    3703         [ #  # ]:           0 :             if (!eq2taut)
    3704                 :             :             {
    3705         [ #  # ]:           0 :                 eq2taut = pINChI_Taut && pINChI_Aux_Taut &&
    3706   [ #  #  #  #  :           0 :                     ( Stereo_Taut = pINChI_Taut->Stereo ) && Stereo_Taut->nCompInv2Abs &&
             #  #  #  # ]
    3707                 :           0 :                     Eql_INChI_Aux_Num( pINChI_Aux, EQL_NUM_INV | EQL_NUM_ISO, pINChI_Aux_Taut, EQL_NUM_INV );
    3708                 :             :                 /* stereo-inv   isotopic numbering  non-taut =  stereo-inv taut numbering */
    3709         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO_INV | iitISO | iiNUMB | iitNONTAUT | iiEq2INV ) : 0;
    3710                 :             :             }
    3711                 :             :             /* f) compare isotopic non-tautomeric inverted stereo numbering to non-tautomeric inverted stereo numbering */
    3712         [ #  # ]:           0 :             if (!eq2taut)
    3713                 :             :             {
    3714                 :           0 :                 eq2taut =
    3715   [ #  #  #  #  :           0 :                     ( Stereo_Taut = pINChI->StereoIsotopic ) && Stereo_Taut->nCompInv2Abs &&
                   #  # ]
    3716                 :           0 :                     Eql_INChI_Aux_Num( pINChI_Aux, EQL_NUM_INV | EQL_NUM_ISO, pINChI_Aux, EQL_NUM_INV );
    3717                 :             :                 /* stereo-inv   isotopic numbering  non-taut =  stereo-inv non-taut numbering */
    3718         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO_INV | iitISO | iiNUMB | iitNONTAUT | iiEq2INV | iiEq2NONTAUT ) : 0;
    3719                 :             :             }
    3720                 :             : 
    3721                 :             :             /* g) compare isotopic non-tautomeric inverted stereo numbering to tautomeric isotopic inverted stereo numbering */
    3722         [ #  # ]:           0 :             if (!eq2taut)
    3723                 :             :             {
    3724                 :           0 :                 eq2taut = pINChI_Taut &&
    3725   [ #  #  #  #  :           0 :                     ( Stereo_Taut = pINChI_Taut->StereoIsotopic ) && Stereo_Taut->nCompInv2Abs &&
             #  #  #  # ]
    3726                 :           0 :                     Eql_INChI_Aux_Num( pINChI_Aux, EQL_NUM_INV | EQL_NUM_ISO, pINChI_Aux_Taut, EQL_NUM_INV | EQL_NUM_ISO );
    3727                 :             :                 /* stereo-inv   isotopic numbering  non-taut =  stereo-inv iso taut numbering */
    3728         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiSTEREO_INV | iitISO | iiNUMB | iitNONTAUT | iiEq2INV | iiEq2ISO ) : 0;
    3729                 :             :             }
    3730                 :             :         }
    3731                 :             :         else
    3732                 :             :         {
    3733                 :             :             /*========= if not bSecondNonTautPass then compare inv taut stereo numb to taut numb ========*/
    3734   [ #  #  #  #  :           0 :             if (!bSecondNonTautPass && bOmitRepetitions && pINChI && pINChI_Aux && pINChI_Aux->bIsIsotopic &&
          #  #  #  #  #  
                      # ]
    3735   [ #  #  #  # ]:           0 :                 ( Stereo = pINChI->StereoIsotopic ) && Stereo->nCompInv2Abs &&
    3736   [ #  #  #  # ]:           0 :                 pINChI_Aux->nNumberOfAtoms > 0 && pINChI_Aux->nIsotopicOrigAtNosInCanonOrdInv)
    3737                 :             :             {
    3738                 :             :                 /* compare isotopic tautomeric inverted stereo numbering to:
    3739                 :             :                 *   a) tautomeric numbering
    3740                 :             :                 *   b) tautomeric isotopic numbering
    3741                 :             :                 *   c) tautomeric inverted stereo numbering
    3742                 :             :                 */
    3743                 :             :                 /* a) compare isotopic tautomeric inverted stereo numbering to tautomeric numbering */
    3744         [ #  # ]:           0 :                 if (!eq2taut)
    3745                 :             :                 {
    3746                 :           0 :                     eq2taut = Eql_INChI_Aux_Num( pINChI_Aux, EQL_NUM_INV | EQL_NUM_ISO, pINChI_Aux, EQL_NUM );
    3747                 :             :                     /* stereo-inv   isotopic numbering  (taut) =  taut numbering */
    3748         [ #  # ]:           0 :                     eq2taut = eq2taut ? ( iiSTEREO_INV | iitISO | iiNUMB ) : 0;
    3749                 :             :                 }
    3750                 :             :                 /* b) compare isotopic tautomeric inverted stereo numbering to tautomeric isotopic numbering */
    3751         [ #  # ]:           0 :                 if (!eq2taut)
    3752                 :             :                 {
    3753                 :           0 :                     eq2taut = Eql_INChI_Aux_Num( pINChI_Aux, EQL_NUM_INV | EQL_NUM_ISO, pINChI_Aux, EQL_NUM_ISO );
    3754                 :             :                     /* stereo-inv   isotopic numbering(taut) =  isotopic taut numbering */
    3755         [ #  # ]:           0 :                     eq2taut = eq2taut ? ( iiSTEREO_INV | iitISO | iiNUMB | iiEq2ISO ) : 0;
    3756                 :             :                 }
    3757                 :             :                 /* b) compare isotopic tautomeric inverted stereo numbering to tautomeric inverted stereo numbering */
    3758         [ #  # ]:           0 :                 if (!eq2taut)
    3759                 :             :                 {
    3760   [ #  #  #  #  :           0 :                     eq2taut = pINChI->Stereo && Stereo->nCompInv2Abs &&
                   #  # ]
    3761                 :           0 :                         Eql_INChI_Aux_Num( pINChI_Aux, EQL_NUM_INV | EQL_NUM_ISO, pINChI_Aux, EQL_NUM_INV ); /* djb-rwth: removing redundant code */
    3762                 :             :                     /* stereo-inv   isotopic numbering  (taut) =  taut stereo-inv numbering */
    3763         [ #  # ]:           0 :                     eq2taut = eq2taut ? ( iiSTEREO_INV | iitISO | iiNUMB | iiEq2INV ) : 0;
    3764                 :             :                 }
    3765                 :             :             }
    3766                 :             :         }
    3767         [ #  # ]:           0 :         if (eq2taut)
    3768                 :             :         {
    3769                 :             :             /* we have found another (previously printed) layer of the current component equal to this layer */
    3770                 :             :             /* output this (current) equivalence mark = EquString(eq2taut) */
    3771                 :           0 :             pCurrEquStr = EquString( eq2taut );
    3772   [ #  #  #  # ]:           0 :             if (multPrevEquStr && pPrevEquStr)
    3773                 :             :             {
    3774   [ #  #  #  # ]:           0 :                 if (pCurrEquStr && !strcmp( pCurrEquStr, pPrevEquStr ))
    3775                 :             :                 {
    3776                 :           0 :                     multPrevEquStr++;
    3777                 :             :                 }
    3778                 :             :                 else
    3779                 :             :                 {
    3780                 :             :                     /* new EqStr is different; output it */
    3781         [ #  # ]:           0 :                     if (bNext++)
    3782                 :             :                     {
    3783                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    3784                 :             :                     }
    3785                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    3786                 :           0 :                     pPrevEquStr = pCurrEquStr;
    3787                 :           0 :                     multPrevEquStr = 1;
    3788                 :             :                 }
    3789                 :             :             }
    3790                 :             :             else
    3791                 :             :             {
    3792                 :           0 :                 pPrevEquStr = pCurrEquStr;
    3793                 :           0 :                 multPrevEquStr = 1;
    3794                 :             :             }
    3795                 :             :         }
    3796                 :             :         else
    3797                 :             :         {
    3798                 :             :             /* current layer is different from previously printed layers of the current component */
    3799   [ #  #  #  # ]:           0 :             if (multPrevEquStr && pPrevEquStr)
    3800                 :             :             {
    3801                 :             :                 /* new EqStr is different; output it */
    3802         [ #  # ]:           0 :                 if (bNext++)
    3803                 :             :                 {
    3804                 :           0 :                     MakeDelim( sCompDelim, strbuf, bOverflow );
    3805                 :             :                 }
    3806                 :           0 :                 MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    3807                 :           0 :                 pPrevEquStr = NULL;
    3808                 :           0 :                 multPrevEquStr = 0;
    3809                 :             :             }
    3810         [ #  # ]:           0 :             if (bNext++)
    3811                 :             :             {
    3812                 :           0 :                 MakeDelim( sCompDelim, strbuf, bOverflow );
    3813                 :             :             }
    3814   [ #  #  #  #  :           0 :             if (pINChI && pINChI_Aux && pINChI_Aux->bIsIsotopic && pINChI_Aux->nNumberOfAtoms &&
             #  #  #  # ]
    3815   [ #  #  #  # ]:           0 :                 ( Stereo = pINChI->StereoIsotopic ) && Stereo->nNumberOfStereoCenters &&
    3816   [ #  #  #  # ]:           0 :                 Stereo->nCompInv2Abs && pINChI_Aux->nIsotopicOrigAtNosInCanonOrdInv)
    3817                 :             :             {
    3818                 :           0 :                 MakeCtString( pCG, pINChI_Aux->nIsotopicOrigAtNosInCanonOrdInv,
    3819                 :             :                     pINChI_Aux->nNumberOfAtoms, 0, NULL, 0,
    3820                 :             :                     strbuf, TAUT_MODE, bOverflow );
    3821                 :             :             }
    3822                 :             :             /* else isotopic inv stereo info is not present in pINChI */
    3823                 :             :         }
    3824                 :             :     }
    3825   [ #  #  #  # ]:           0 :     if (multPrevEquStr && pPrevEquStr)
    3826                 :             :     {
    3827                 :             :         /* the new EqStr of the last item has not been printed; output it now */
    3828         [ #  # ]:           0 :         if (bNext++)
    3829                 :             :         {
    3830                 :           0 :             MakeDelim( sCompDelim, strbuf, bOverflow );
    3831                 :             :         }
    3832                 :           0 :         MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    3833                 :           0 :         pPrevEquStr = NULL;
    3834                 :             :         /* djb-rwth: removing redundant code */
    3835                 :             :     }
    3836                 :             : 
    3837                 :           0 :     return ( strbuf->nUsedLength - nUsedLength0 );
    3838                 :             : }
    3839                 :             : 
    3840                 :             : 
    3841                 :             : /****************************************************************************
    3842                 :             :   Produce numbering substring of AuxInfo
    3843                 :             :   /N: in Main and/or /F: in FixedH part,
    3844                 :             :   in both normal and in reconnected layers
    3845                 :             : ****************************************************************************/
    3846                 :          54 : int str_AuxNumb( CANON_GLOBALS    *pCG,
    3847                 :             :                  INCHI_SORT       *pINChISort,
    3848                 :             :                  INCHI_SORT       *pINChISort2,
    3849                 :             :                  INCHI_IOS_STRING *strbuf,
    3850                 :             :                  int              *bOverflow,
    3851                 :             :                  int              bOutType,
    3852                 :             :                  int              TAUT_MODE,
    3853                 :             :                  int              num_components,
    3854                 :             :                  int              bSecondNonTautPass,
    3855                 :             :                  int              bOmitRepetitions )
    3856                 :             : {
    3857                 :             :     int          i, ii, ii2, nUsedLength0;
    3858                 :             :     INCHI_SORT   *is, *is0 /*, *is2*/;
    3859                 :          54 :     INChI        *pINChI, *pINChI_Taut = NULL;
    3860                 :          54 :     INChI_Aux    *pINChI_Aux, *pINChI_Aux_Taut = NULL;
    3861                 :             :     int          eq2taut, bNext;
    3862                 :             :     const char  *pPrevEquStr, *pCurrEquStr;
    3863                 :             :     int         multPrevEquStr;
    3864                 :          54 :     bNext = 0;
    3865                 :             :     /*is2         = bSecondNonTautPass? pINChISort2 : NULL;*/
    3866                 :             :     /* djb-rwth: removing redundant code */
    3867                 :          54 :     pPrevEquStr = NULL; /*, *pCurrEquStr;*/
    3868                 :          54 :     multPrevEquStr = 0;
    3869                 :          54 :     is = NULL;
    3870                 :          54 :     nUsedLength0 = strbuf->nUsedLength;
    3871                 :             : 
    3872         [ -  + ]:          54 :     if (!( is0 = pINChISort ))
    3873                 :             :     {
    3874                 :           0 :         return nUsedLength0;
    3875                 :             :     }
    3876                 :             : 
    3877                 :             :     /* For each connected component...    */
    3878         [ +  + ]:         123 :     for (i = 0; i < num_components; i++)
    3879                 :             :     {
    3880                 :             :         /* 1st (taut) pass: bOutType=OUT_TN  ; 2nd (non-taut pass) bOutType=OUT_NT */
    3881                 :          69 :         is = is0 + i;
    3882   [ -  +  -  -  :          69 :         pINChI = ( 0 <= ( ii = GET_II( bOutType, is ) ) ) ? is->pINChI[ii] : NULL;
          -  -  -  -  -  
          -  -  -  -  -  
          +  -  +  -  +  
          -  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
                   +  - ]
    3883         [ +  - ]:          69 :         pINChI_Aux = pINChI ? is->pINChI_Aux[ii] : NULL;
    3884                 :             :         /*================ to compare to previously printed =====================*/
    3885         [ -  + ]:          69 :         if (bSecondNonTautPass)
    3886                 :             :         {
    3887                 :             :             /* component that was printed on the 1st pass */
    3888   [ #  #  #  #  :           0 :             pINChI_Taut = ( 0 <= ( ii2 = GET_II( OUT_T1, is ) ) ) ? is->pINChI[ii2] : NULL;
          #  #  #  #  #  
                      # ]
    3889         [ #  # ]:           0 :             pINChI_Aux_Taut = pINChI_Taut ? is->pINChI_Aux[ii2] : NULL;
    3890                 :             :         }
    3891                 :          69 :         eq2taut = 0;
    3892                 :             :         /*========= if bSecondNonTautPass then compare iso non-taut stereo to other stereo ========*/
    3893   [ -  +  -  -  :          69 :         if (bSecondNonTautPass && bOmitRepetitions && pINChI && pINChI_Aux && pINChI_Aux->nNumberOfAtoms > 0)
          -  -  -  -  -  
                      - ]
    3894                 :             :         {
    3895                 :             :             /* compare non-tautomeric numbering to:
    3896                 :             :             *   a) tautomeric numbering
    3897                 :             :             */
    3898                 :             :             /* a) compare non-tautomeric numbering to tautomeric numbering */
    3899         [ #  # ]:           0 :             if (!eq2taut)
    3900                 :             :             {
    3901   [ #  #  #  #  :           0 :                 eq2taut = pINChI_Taut && !pINChI_Taut->bDeleted &&
                   #  # ]
    3902                 :           0 :                     Eql_INChI_Aux_Num( pINChI_Aux, EQL_NUM, pINChI_Aux_Taut, EQL_NUM );
    3903                 :             :                 /* numbering  non-taut =  taut numbering */
    3904         [ #  # ]:           0 :                 eq2taut = eq2taut ? ( iiNUMB | iitNONTAUT ) : 0;
    3905                 :             :             }
    3906                 :             :         }
    3907         [ -  + ]:          69 :         if (eq2taut)
    3908                 :             :         {
    3909                 :             :             /* we have found another (previously printed) layer of the current component equal to this layer */
    3910                 :             :             /* output this (current) equivalence mark = EquString(eq2taut) */
    3911                 :           0 :             pCurrEquStr = EquString( eq2taut );
    3912   [ #  #  #  # ]:           0 :             if (multPrevEquStr && pPrevEquStr)
    3913                 :             :             {
    3914   [ #  #  #  # ]:           0 :                 if (pCurrEquStr && !strcmp( pCurrEquStr, pPrevEquStr ))
    3915                 :             :                 {
    3916                 :           0 :                     multPrevEquStr++;
    3917                 :             :                 }
    3918                 :             :                 else
    3919                 :             :                 {
    3920                 :             :                     /* new EqStr is different; output it */
    3921         [ #  # ]:           0 :                     if (bNext++)
    3922                 :             :                     {
    3923                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    3924                 :             :                     }
    3925                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    3926                 :           0 :                     pPrevEquStr = pCurrEquStr;
    3927                 :           0 :                     multPrevEquStr = 1;
    3928                 :             :                 }
    3929                 :             :             }
    3930                 :             :             else
    3931                 :             :             {
    3932                 :           0 :                 pPrevEquStr = pCurrEquStr;
    3933                 :           0 :                 multPrevEquStr = 1;
    3934                 :             :             }
    3935                 :             :         }
    3936                 :             :         else
    3937                 :             :         {
    3938                 :             :             /* current layer is different from previously printed layers of the current component */
    3939   [ -  +  -  - ]:          69 :             if (multPrevEquStr && pPrevEquStr)
    3940                 :             :             {
    3941                 :             :                 /* new EqStr is different; output it */
    3942         [ #  # ]:           0 :                 if (bNext++)
    3943                 :             :                 {
    3944                 :           0 :                     MakeDelim( sCompDelim, strbuf, bOverflow );
    3945                 :             :                 }
    3946                 :           0 :                 MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    3947                 :           0 :                 pPrevEquStr = NULL;
    3948                 :           0 :                 multPrevEquStr = 0;
    3949                 :             :             }
    3950         [ +  + ]:          69 :             if (bNext++)
    3951                 :             :             {
    3952                 :          15 :                 MakeDelim( sCompDelim, strbuf, bOverflow );
    3953                 :             :             }
    3954   [ +  -  +  -  :          69 :             if (pINChI && pINChI_Aux && pINChI_Aux->nNumberOfAtoms)
                   +  - ]
    3955                 :             :             {
    3956                 :          69 :                 MakeCtString( pCG, pINChI_Aux->nOrigAtNosInCanonOrd,
    3957                 :             :                     pINChI_Aux->nNumberOfAtoms, 0, NULL, 0,
    3958                 :             :                     strbuf, TAUT_MODE, bOverflow );
    3959                 :             :             }
    3960                 :             :         }
    3961                 :             :     }
    3962   [ -  +  -  - ]:          54 :     if (multPrevEquStr && pPrevEquStr)
    3963                 :             :     {
    3964                 :             :         /* the new EqStr of the last item has not been printed; output it now */
    3965         [ #  # ]:           0 :         if (bNext++)
    3966                 :             :         {
    3967                 :           0 :             MakeDelim( sCompDelim, strbuf, bOverflow );
    3968                 :             :         }
    3969                 :           0 :         MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    3970                 :           0 :         pPrevEquStr = NULL;
    3971                 :             :         /* djb-rwth: removing redundant code */
    3972                 :             :     }
    3973                 :             : 
    3974                 :          54 :     return ( strbuf->nUsedLength - nUsedLength0 );
    3975                 :             : }
    3976                 :             : 
    3977                 :             : 
    3978                 :             : /****************************************************************************
    3979                 :             :   Produce TGroup equivalence substring of AuxInfo
    3980                 :             : ****************************************************************************/
    3981                 :           0 : int str_AuxTgroupEqu( INCHI_SORT       *pINChISort,
    3982                 :             :                       INCHI_IOS_STRING *strbuf,
    3983                 :             :                       int              *bOverflow,
    3984                 :             :                       int              bOutType,
    3985                 :             :                       int              TAUT_MODE,
    3986                 :             :                       int              num_components,
    3987                 :             :                       int              bUseMulipliers )
    3988                 :             : {
    3989                 :             :     int          i, ii, nUsedLength0;
    3990                 :             :     INCHI_SORT   *is, *is0;
    3991                 :             :     INChI_Aux    *pINChI_Aux, *pINChI_Aux_Prev;
    3992                 :             :     int          mult, eq2prev, bNext;
    3993                 :             : 
    3994                 :           0 :     nUsedLength0 = strbuf->nUsedLength;
    3995                 :             : 
    3996                 :           0 :     is0 = pINChISort;
    3997                 :           0 :     is = NULL;
    3998                 :           0 :     i = 0;
    3999   [ #  #  #  #  :           0 :     pINChI_Aux_Prev = ( 0 <= ( ii = GET_II( bOutType, is0 ) ) ) ? is0->pINChI_Aux[ii] : NULL;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    4000                 :           0 :     mult = 0;
    4001                 :           0 :     bNext = 0;
    4002                 :             : 
    4003                 :             :     /* For each connected component...    */
    4004         [ #  # ]:           0 :     for (i++; i <= num_components; i++)
    4005                 :             :     {
    4006   [ #  #  #  #  :           0 :         pINChI_Aux = ( i < num_components && ( is = is0 + i, 0 <= ( ii = GET_II( bOutType, is ) ) ) ) ? is->pINChI_Aux[ii] : NULL;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    4007   [ #  #  #  # ]:           0 :         eq2prev = bUseMulipliers &&
    4008                 :           0 :             Eql_INChI_Aux_Equ( pINChI_Aux, EQL_EQU_TG, pINChI_Aux_Prev, EQL_EQU_TG );
    4009         [ #  # ]:           0 :         if (eq2prev)
    4010                 :             :         {
    4011                 :           0 :             mult++; /* mult = (number of non-empty equal items)-1 */
    4012                 :           0 :             continue;
    4013                 :             :         }
    4014                 :             :         else
    4015                 :             :         {
    4016         [ #  # ]:           0 :             if (bNext++)
    4017                 :             :             {
    4018                 :           0 :                 MakeDelim( sCompDelim, strbuf, bOverflow );
    4019                 :             :             }
    4020   [ #  #  #  #  :           0 :             if (pINChI_Aux_Prev && pINChI_Aux_Prev->nNumberOfTGroups &&
                   #  # ]
    4021                 :           0 :                 bHasEquString( pINChI_Aux_Prev->nConstitEquTGroupNumbers, pINChI_Aux_Prev->nNumberOfTGroups ))
    4022                 :             :             {
    4023                 :           0 :                 MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
    4024                 :           0 :                 MakeEquString( pINChI_Aux_Prev->nConstitEquTGroupNumbers,
    4025                 :             :                     pINChI_Aux_Prev->nNumberOfTGroups,
    4026                 :             :                     0, strbuf,
    4027                 :             :                     TAUT_MODE, bOverflow );
    4028                 :             :             }
    4029                 :             :         }
    4030                 :           0 :         pINChI_Aux_Prev = pINChI_Aux;
    4031                 :           0 :         mult = 0; /* we do not know whether the item is empty */
    4032                 :             :     }
    4033                 :             : 
    4034                 :           0 :     return ( strbuf->nUsedLength - nUsedLength0 );
    4035                 :             : }
    4036                 :             : 
    4037                 :             : 
    4038                 :             : /****************************************************************************
    4039                 :             :   Produce charge-radical-valence substring of AuxInfo
    4040                 :             : ****************************************************************************/
    4041                 :           3 : int str_AuxChargeRadVal( INCHI_SORT       *pINChISort,
    4042                 :             :     INCHI_IOS_STRING *strbuf,
    4043                 :             :     int               *bOverflow,
    4044                 :             :     int               bOutType,
    4045                 :             :     int               TAUT_MODE,
    4046                 :             :     int               num_components,
    4047                 :             :     int               bUseMulipliers )
    4048                 :             : {
    4049                 :             :     int          i, ii, nUsedLength0;
    4050                 :             :     INCHI_SORT   *is, *is0;
    4051                 :             :     INChI_Aux    *pINChI_Aux, *pINChI_Aux_Prev;
    4052                 :             :     int          mult, eq2prev, bNext;
    4053                 :             : 
    4054                 :           3 :     pINChI_Aux_Prev = NULL;
    4055                 :           3 :     mult = 0;
    4056                 :           3 :     bNext = 0;
    4057                 :           3 :     is = NULL;
    4058                 :           3 :     is0 = pINChISort;
    4059                 :           3 :     nUsedLength0 = strbuf->nUsedLength;
    4060                 :             : 
    4061                 :             :     /* For each connected component...    */
    4062         [ +  + ]:          11 :     for (i = 0; i <= num_components; i++)
    4063                 :             :     {
    4064                 :             : 
    4065                 :             :         /* 1st (taut) pass: bOutType=OUT_TN  ; 2nd (non-taut pass) bOutType=OUT_NT */
    4066   [ +  +  -  +  :           8 :         pINChI_Aux = ( i < num_components && ( is = is0 + i, 0 <= ( ii = GET_II( bOutType, is ) ) ) ) ? is->pINChI_Aux[ii] : NULL;
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  +  
          -  +  -  -  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
             -  -  +  - ]
    4067                 :             :         /* check whether pINChI_Aux and pINChI_Aux_Prev have identical info */
    4068   [ +  -  -  + ]:          16 :         eq2prev = bUseMulipliers &&
    4069                 :           8 :             EqlOrigInfo( pINChI_Aux, pINChI_Aux_Prev );
    4070         [ -  + ]:           8 :         if (eq2prev)
    4071                 :             :         {
    4072                 :             :             /* eq. info is same and non-trivial */
    4073                 :           0 :             mult++; /* mult = (number of non-empty equal items)-1 */
    4074                 :           0 :             continue;
    4075                 :             :         }
    4076                 :             :         else
    4077                 :             :         {
    4078         [ +  + ]:           8 :             if (i)
    4079                 :             :             {
    4080                 :             :                 /* pINChI_Aux info is either different or trivial. Output pINChI_Aux_Prev anyway */
    4081         [ +  + ]:           5 :                 if (bNext++)
    4082                 :             :                 {
    4083                 :           2 :                     MakeDelim( sCompDelim, strbuf, bOverflow );
    4084                 :             :                 }
    4085   [ +  -  +  - ]:           5 :                 if (pINChI_Aux_Prev && pINChI_Aux_Prev->nNumberOfAtoms)
    4086                 :             :                 {
    4087         [ +  + ]:           5 :                     if (bHasOrigInfo( pINChI_Aux_Prev->OrigInfo, pINChI_Aux_Prev->nNumberOfAtoms ))
    4088                 :             :                     {
    4089                 :             :                         /* pINChI_Aux_Prev exists and has orig. info info */
    4090                 :           4 :                         MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
    4091                 :           4 :                         MakeCRVString( pINChI_Aux_Prev->OrigInfo,
    4092                 :             :                             pINChI_Aux_Prev->nNumberOfAtoms,
    4093                 :             :                             0, strbuf, TAUT_MODE, bOverflow );
    4094                 :             :                     }
    4095                 :             :                     else
    4096                 :             :                     {
    4097                 :             :                         ; /* pINChI_Aux_Prev exists and has only trivial info */
    4098                 :             :                     }
    4099                 :             :                 }
    4100                 :             : #if ( bRELEASE_VERSION != 1 && defined(_DEBUG) )
    4101                 :             :                 else
    4102                 :             :                 {
    4103                 :             :                     int stop = 1;   /* <BRKPT> */
    4104                 :             :                 }
    4105                 :             : #endif
    4106                 :             :             }
    4107                 :             :         }
    4108                 :           8 :         pINChI_Aux_Prev = pINChI_Aux;
    4109                 :           8 :         mult = 0; /* we do not know whether the item is empty */
    4110                 :             :     }
    4111                 :             : 
    4112                 :           3 :     return ( strbuf->nUsedLength - nUsedLength0 );
    4113                 :             : }
    4114                 :             : 
    4115                 :             : 
    4116                 :             : /****************************************************************************
    4117                 :             :   Prepare tautomeric transposition substring of AuxInfo
    4118                 :             : ****************************************************************************/
    4119                 :           0 : int bin_AuxTautTrans( INCHI_SORT *pINChISort,
    4120                 :             :     INCHI_SORT *pINChISort2,
    4121                 :             :     AT_NUMB    **pTrans_n,
    4122                 :             :     AT_NUMB    **pTrans_s,
    4123                 :             :     int        bOutType,
    4124                 :             :     int        num_components )
    4125                 :             : {
    4126                 :           0 :     int          i, ii, ii2, ret = 0;
    4127                 :             :     INCHI_SORT   *is, *is2, *is0, *is20;
    4128                 :             :     INChI        *pINChI, *pINChI_Taut;
    4129                 :           0 :     AT_NUMB     *nTrans_n = NULL;
    4130                 :           0 :     AT_NUMB     *nTrans_s = NULL;
    4131                 :             : 
    4132                 :             :     /* djb-rwth: removing redundant code */
    4133                 :           0 :     is0 = pINChISort;
    4134                 :           0 :     is20 = pINChISort2;
    4135                 :             : 
    4136                 :             :     /* djb-rwth: rewritten to avoid memory leaks -- updated 25/09/2025 */
    4137                 :             : 
    4138                 :             :     /* Pass 1: save new non-taut numbering */
    4139                 :             :     /* For each connected component...    */
    4140         [ #  # ]:           0 :     for (i = 0; i < num_components; i++)
    4141                 :             :     {
    4142                 :           0 :         is = is0 + i;
    4143                 :           0 :         is2 = is20 + i;
    4144   [ #  #  #  #  :           0 :         pINChI = (0 <= (ii = GET_II(bOutType, is))) ? is->pINChI[ii] : NULL;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    4145   [ #  #  #  #  :           0 :         pINChI_Taut = (0 <= (ii2 = GET_II(OUT_T1, is2))) ? is2->pINChI[ii2] : NULL;
          #  #  #  #  #  
                      # ]
    4146   [ #  #  #  #  :           0 :         if (pINChI && pINChI->nNumberOfAtoms > 0 &&
                   #  # ]
    4147         [ #  # ]:           0 :             pINChI_Taut && pINChI_Taut->nNumberOfAtoms > 0 &&
    4148                 :             :             /* different components save equal new ord. numbers: */
    4149         [ #  # ]:           0 :             is->ord_number != is2->ord_number)
    4150                 :             :         {
    4151         [ #  # ]:           0 :             if (!nTrans_n)
    4152                 :             :             {
    4153                 :           0 :                 nTrans_n = (AT_NUMB*)inchi_calloc((long long)num_components + 1, sizeof(nTrans_n[0]));
    4154                 :             :             }
    4155         [ #  # ]:           0 :             if (!nTrans_s)
    4156                 :             :             {
    4157                 :           0 :                 nTrans_s = (AT_NUMB*)inchi_calloc((long long)num_components + 1, sizeof(nTrans_s[0]));
    4158                 :             :             }
    4159   [ #  #  #  # ]:           0 :             if (nTrans_n && nTrans_s)
    4160                 :             :             {
    4161                 :             :                 /* new ordering number for original non-tautomeric component number is->ord_number */
    4162                 :           0 :                 nTrans_n[is->ord_number] = i + 1; /*nTrans_t[is2->ord_number] =*/
    4163                 :             :             }
    4164                 :             :         }
    4165                 :             :     }
    4166   [ #  #  #  # ]:           0 :     if (nTrans_n && nTrans_s)
    4167                 :             :     {
    4168                 :             :         /* Pass 2: get new taut numbering, retrieve new non-taut and save the transposition */
    4169         [ #  # ]:           0 :         for (i = 0; i < num_components; i++)
    4170                 :             :         {
    4171                 :           0 :             is = is0 + i;
    4172                 :           0 :             is2 = is20 + i;
    4173   [ #  #  #  #  :           0 :             pINChI = (0 <= (ii = GET_II(bOutType, is))) ? is->pINChI[ii] : NULL;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    4174   [ #  #  #  #  :           0 :             pINChI_Taut = (0 <= (ii2 = GET_II(OUT_T1, is2))) ? is2->pINChI[ii2] : NULL;
          #  #  #  #  #  
                      # ]
    4175   [ #  #  #  #  :           0 :             if (pINChI && pINChI->nNumberOfAtoms > 0 &&
                   #  # ]
    4176         [ #  # ]:           0 :                 pINChI_Taut && pINChI_Taut->nNumberOfAtoms > 0 &&
    4177         [ #  # ]:           0 :                 is->ord_number != is2->ord_number &&
    4178         [ #  # ]:           0 :                 nTrans_n[is2->ord_number])
    4179                 :             :             {
    4180                 :             :                 /* nTrans_n[is2->ord_number] is new ordering number of
    4181                 :             :                 the non-taut representation of the tautomeric component
    4182                 :             :                 that has new ord number i+1 and orig ordering number is2->ord_number.
    4183                 :             :                 Old numbers start from 0, new start from 1
    4184                 :             :                 */
    4185                 :             : 
    4186                 :             :                 /* n = nTrans_s[t]: taut component #t is in position #n of the non-taut representation */
    4187                 :           0 :                 nTrans_s[i + 1] = nTrans_n[is2->ord_number];
    4188                 :             :             }
    4189                 :             :         }
    4190                 :           0 :         *pTrans_n = nTrans_n;
    4191                 :           0 :         *pTrans_s = nTrans_s;
    4192                 :           0 :         ret = 1;
    4193                 :             :     }
    4194                 :             :     else
    4195                 :             :     {
    4196         [ #  # ]:           0 :         if (nTrans_n)
    4197                 :             :         {
    4198         [ #  # ]:           0 :             inchi_free(nTrans_n);
    4199                 :           0 :             ret = -1;
    4200                 :             :         }
    4201         [ #  # ]:           0 :         if (nTrans_s)
    4202                 :             :         {
    4203         [ #  # ]:           0 :             inchi_free(nTrans_s);
    4204                 :           0 :             ret = -1;
    4205                 :             :         }
    4206                 :             :     }
    4207                 :             : 
    4208                 :           0 :     return ret;
    4209                 :             : }
    4210                 :             : 
    4211                 :             : 
    4212                 :             : /****************************************************************************
    4213                 :             :   Output tautomeric transposition substring of AuxInfo
    4214                 :             : ****************************************************************************/
    4215                 :           0 : int str_AuxTautTrans( CANON_GLOBALS     *pCG,
    4216                 :             :     AT_NUMB           *nTrans_n,
    4217                 :             :     AT_NUMB           *nTrans_s,
    4218                 :             :     INCHI_IOS_STRING  *strbuf,
    4219                 :             :     int               *bOverflow,
    4220                 :             :     int               TAUT_MODE,
    4221                 :             :     int               num_components )
    4222                 :             : {
    4223                 :             :     int i, k, len, j, nUsedLength0;
    4224                 :             : 
    4225                 :           0 :     nUsedLength0 = strbuf->nUsedLength;
    4226                 :             : 
    4227   [ #  #  #  # ]:           0 :     if (nTrans_n && nTrans_s)
    4228                 :             :     {
    4229                 :             :         /* print the transposition, cycle after cycle */
    4230         [ #  # ]:           0 :         for (i = 1; i <= num_components; i++)
    4231                 :             :         {
    4232         [ #  # ]:           0 :             if (nTrans_s[i])
    4233                 :             :             {
    4234                 :             :                 /* get one cycle of the transposition */
    4235         [ #  # ]:           0 :                 for (j = i, len = 0; ( k = nTrans_s[j] ); j = k, len++)
    4236                 :             :                 {
    4237                 :           0 :                     nTrans_n[len] = j; /* save the transposition */
    4238                 :           0 :                     nTrans_s[j] = 0; /* clear used element to avoid repetitions */
    4239                 :             :                 }
    4240                 :             :                 /* print one cycle of the transposition */
    4241                 :           0 :                 MakeDelim( "(", strbuf, bOverflow );
    4242                 :           0 :                 MakeCtString( pCG, nTrans_n, len, 0, NULL, 0,
    4243                 :             :                     strbuf, TAUT_MODE, bOverflow );
    4244                 :           0 :                 MakeDelim( ")", strbuf, bOverflow );
    4245                 :             :             }
    4246                 :             :         }
    4247                 :             :     }
    4248         [ #  # ]:           0 :     if (nTrans_n)
    4249                 :             :     {
    4250         [ #  # ]:           0 :         inchi_free( nTrans_n );
    4251                 :             :     }
    4252         [ #  # ]:           0 :     if (nTrans_s)
    4253                 :             :     {
    4254         [ #  # ]:           0 :         inchi_free( nTrans_s );
    4255                 :             :     }
    4256                 :             : 
    4257                 :           0 :     return ( strbuf->nUsedLength - nUsedLength0 );
    4258                 :             : }
    4259                 :             : 
    4260                 :             : 
    4261                 :             : /****************************************************************************
    4262                 :             :   Output isotopic TGroup equivalence substring of AuxInfo
    4263                 :             : ****************************************************************************/
    4264                 :           0 : int str_AuxIsoTgroupEqu( INCHI_SORT       *pINChISort,
    4265                 :             :     INCHI_IOS_STRING *strbuf,
    4266                 :             :     int              *bOverflow,
    4267                 :             :     int              bOutType,
    4268                 :             :     int              TAUT_MODE,
    4269                 :             :     int              num_components,
    4270                 :             :     int              bOmitRepetitions,
    4271                 :             :     int              bUseMulipliers )
    4272                 :             : {
    4273                 :             :     int          i, ii, nUsedLength0;
    4274                 :             :     INCHI_SORT   *is, *is0;
    4275                 :             :     INChI_Aux    *pINChI_Aux, *pINChI_Aux_Prev;
    4276                 :             :     int          mult, eq2prev, eq2taut, eq2tautPrev, bNext;
    4277                 :             :     const char  *pPrevEquStr, *pCurrEquStr;
    4278                 :             :     int         multPrevEquStr;
    4279                 :           0 :     pINChI_Aux = NULL;
    4280                 :           0 :     pINChI_Aux_Prev = NULL;
    4281                 :           0 :     mult = 0;
    4282                 :           0 :     bNext = 0;
    4283                 :           0 :     is = NULL;
    4284                 :           0 :     is0 = pINChISort;
    4285                 :             :     /* djb-rwth: removing redundant code */
    4286                 :           0 :     eq2tautPrev = 1; /* pINChI_Aux_Prev (previous pINChI_Aux) does not exist */
    4287                 :           0 :     pPrevEquStr = NULL; /*, *pCurrEquStr;*/
    4288                 :           0 :     multPrevEquStr = 0;
    4289                 :           0 :     nUsedLength0 = strbuf->nUsedLength;
    4290                 :             : 
    4291                 :             :     /* For each connected component...    */
    4292         [ #  # ]:           0 :     for (i = 0; i <= num_components; i++)
    4293                 :             :     {
    4294                 :             :         /* 1st (taut) pass: bOutType=OUT_TN  ; 2nd (non-taut pass) bOutType=OUT_NT */
    4295   [ #  #  #  #  :           0 :         pINChI_Aux = ( i < num_components && ( is = is0 + i, 0 <= ( ii = GET_II( bOutType, is ) ) ) ) ? is->pINChI_Aux[ii] : NULL;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    4296                 :             :         /*================ compare iso non-taut equivalence info to non-iso taut ========*/
    4297                 :           0 :         eq2taut = 0;
    4298   [ #  #  #  #  :           0 :         if (bOmitRepetitions && pINChI_Aux && pINChI_Aux->bIsIsotopic)
                   #  # ]
    4299                 :             :         {
    4300                 :             :             /**************************************************
    4301                 :             :             * compare isotopic tautomeric equivalence to:
    4302                 :             :             *    a) non-isotopic tautomeric
    4303                 :             :             */
    4304                 :             :             /* compare isotopic t-group equivalence to non-isotopic */
    4305                 :           0 :             eq2taut = Eql_INChI_Aux_Equ( pINChI_Aux, EQL_EQU_TG | EQL_EQU_ISO, pINChI_Aux, EQL_EQU_TG );
    4306                 :             :             /* equ   taut-isotopic = tautomeric, same as for isotopic atom equivalence info*/
    4307         [ #  # ]:           0 :             eq2taut = eq2taut ? ( iiEQU | iitISO ) : 0;
    4308                 :             :         }
    4309         [ #  # ]:           0 :         if (eq2taut)
    4310                 :             :         {
    4311                 :             :             /* current isotopic t-group equivalence has been found to be same as non-isotopic */
    4312   [ #  #  #  # ]:           0 :             if (pINChI_Aux_Prev && pINChI_Aux_Prev->nNumberOfAtoms)
    4313                 :             :             {
    4314                 :             :                 /* previous component exists */
    4315         [ #  # ]:           0 :                 if (bNext++)
    4316                 :             :                 {
    4317                 :           0 :                     MakeDelim( sCompDelim, strbuf, bOverflow );
    4318                 :             :                 }
    4319         [ #  # ]:           0 :                 if (bHasEquString( pINChI_Aux_Prev->nConstitEquIsotopicTGroupNumbers, pINChI_Aux_Prev->nNumberOfTGroups ))
    4320                 :             :                 {
    4321                 :             :                     /* output previous component(s) equivalence since it was found to be non-trivial */
    4322                 :           0 :                     MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
    4323                 :           0 :                     MakeEquString( pINChI_Aux_Prev->nConstitEquIsotopicTGroupNumbers, pINChI_Aux_Prev->nNumberOfTGroups, 0,
    4324                 :             :                         strbuf, TAUT_MODE, bOverflow );
    4325                 :             :                 }
    4326                 :             :                 else
    4327                 :             :                 {
    4328                 :             :                     ; /* pINChI_Aux_Prev exists and does not have non-trivial t-group equivalence info */
    4329                 :             :                 }
    4330                 :             :             }
    4331                 :             :             /* we have found pINChI_Aux->pINChI_Aux->nConstitEquIsotopicTGroupNumbers same as in pINChI_Aux->nConstitEquTGroupNumbers */
    4332                 :           0 :             pCurrEquStr = EquString( eq2taut );
    4333   [ #  #  #  # ]:           0 :             if (multPrevEquStr && pPrevEquStr)
    4334                 :             :             {
    4335   [ #  #  #  # ]:           0 :                 if (pCurrEquStr && !strcmp( pCurrEquStr, pPrevEquStr ))
    4336                 :             :                 {
    4337                 :           0 :                     multPrevEquStr++;
    4338                 :             :                 }
    4339                 :             :                 else
    4340                 :             :                 {
    4341                 :             :                     /* new EqStr is different; output it */
    4342         [ #  # ]:           0 :                     if (bNext++)
    4343                 :             :                     {
    4344                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    4345                 :             :                     }
    4346                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    4347                 :           0 :                     pPrevEquStr = pCurrEquStr;
    4348                 :           0 :                     multPrevEquStr = 1;
    4349                 :             :                 }
    4350                 :             :             }
    4351                 :             :             else
    4352                 :             :             {
    4353                 :           0 :                 pPrevEquStr = pCurrEquStr;
    4354                 :           0 :                 multPrevEquStr = 1;
    4355                 :             :             }
    4356                 :           0 :             pINChI_Aux_Prev = NULL; /* pINChI_Aux_Prev has already been output */
    4357                 :           0 :             mult = 0;
    4358                 :           0 :             eq2tautPrev = 1;
    4359                 :             :         }
    4360                 :             :         else
    4361                 :             :         {
    4362         [ #  # ]:           0 :             if (eq2tautPrev)
    4363                 :             :             {
    4364                 :             :                 /* at this point pINChI_Aux_Prev does not exist; however, pINChI_Aux */
    4365                 :             :                 /* might have been discovered and it may be different from non-isotopic */
    4366   [ #  #  #  # ]:           0 :                 if (multPrevEquStr && pPrevEquStr)
    4367                 :             :                 {
    4368                 :             :                     /* new EqStr is different; output it */
    4369         [ #  # ]:           0 :                     if (bNext++)
    4370                 :             :                     {
    4371                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    4372                 :             :                     }
    4373                 :           0 :                     MakeEqStr( pPrevEquStr, multPrevEquStr, strbuf, bOverflow );
    4374                 :           0 :                     pPrevEquStr = NULL;
    4375                 :           0 :                     multPrevEquStr = 0;
    4376                 :             :                 }
    4377                 :           0 :                 eq2tautPrev = 0;
    4378                 :           0 :                 pINChI_Aux_Prev = pINChI_Aux;
    4379                 :           0 :                 mult = 0;
    4380                 :             :             }
    4381                 :             :             else
    4382                 :             :             {
    4383                 :             :                 /* check whether pINChI_Aux and pINChI_Aux_Prev have identical non-trivial isotopic t-group equivalence info */
    4384   [ #  #  #  # ]:           0 :                 eq2prev = bUseMulipliers && Eql_INChI_Aux_Equ( pINChI_Aux, EQL_EQU_TG | EQL_EQU_ISO, pINChI_Aux_Prev, EQL_EQU_TG | EQL_EQU_ISO );
    4385         [ #  # ]:           0 :                 if (eq2prev)
    4386                 :             :                 {
    4387                 :             :                     /* eq. info is same and non-trivial */
    4388                 :           0 :                     mult++; /* mult = (number of non-empty equal items)-1 */
    4389                 :           0 :                     continue;
    4390                 :             :                 }
    4391                 :             :                 else
    4392                 :             :                 {
    4393                 :             :                     /* pINChI_Aux eq. info is either different or trivial. Output pINChI_Aux_Prev anyway */
    4394         [ #  # ]:           0 :                     if (bNext++)
    4395                 :             :                     {
    4396                 :           0 :                         MakeDelim( sCompDelim, strbuf, bOverflow );
    4397                 :             :                     }
    4398   [ #  #  #  # ]:           0 :                     if (pINChI_Aux_Prev && pINChI_Aux_Prev->nNumberOfAtoms)
    4399                 :             :                     {
    4400         [ #  # ]:           0 :                         if (bHasEquString( pINChI_Aux_Prev->nConstitEquIsotopicTGroupNumbers, pINChI_Aux_Prev->nNumberOfTGroups ))
    4401                 :             :                         {
    4402                 :             :                             /* pINChI_Aux_Prev exists and has equivalence info */
    4403                 :           0 :                             MakeMult( mult + 1, "*", strbuf, 0, bOverflow );
    4404                 :           0 :                             MakeEquString( pINChI_Aux_Prev->nConstitEquIsotopicTGroupNumbers, pINChI_Aux_Prev->nNumberOfTGroups, 0,
    4405                 :             :                                 strbuf, TAUT_MODE, bOverflow );
    4406                 :             :                         }
    4407                 :             :                         else
    4408                 :             :                         {
    4409                 :             :                             ; /* pINChI_Aux_Prev exists and has only trivial equivalence info */
    4410                 :             :                         }
    4411                 :             :                     }
    4412                 :             : #if ( bRELEASE_VERSION != 1 && defined(_DEBUG) )
    4413                 :             :                     else
    4414                 :             :                     {
    4415                 :             :                         int stop = 1;   /* <BRKPT> */
    4416                 :             :                     }
    4417                 :             : #endif
    4418                 :             :                 }
    4419                 :           0 :                 pINChI_Aux_Prev = pINChI_Aux;
    4420                 :           0 :                 mult = 0; /* we do not know whether the item is empty */
    4421                 :             :             }
    4422                 :             :         }
    4423                 :             :     }
    4424                 :             : 
    4425                 :           0 :     return ( strbuf->nUsedLength - nUsedLength0 );
    4426                 :             : }
        

Generated by: LCOV version 2.0-1