LCOV - code coverage report
Current view: top level - src - ichimap4.c (source / functions) Coverage Total Hit
Test: InChI Unit Test Coverage Lines: 20.6 % 801 165
Test Date: 2026-10-14 12:14:55 Functions: 100.0 % 2 2
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 15.1 % 716 108

             Branch data     Line data    Source code
       1                 :             : /*
       2                 :             :  * SPDX-License-Identifier: MIT
       3                 :             :  * Copyright (c) 2024 IUPAC and InChI Trust
       4                 :             :  */
       5                 :             : 
       6                 :             : #include <string.h>
       7                 :             : 
       8                 :             : #include "mode.h"
       9                 :             : #include "ichicomn.h"
      10                 :             : 
      11                 :             : #include "bcf_s.h"
      12                 :             : 
      13                 :             : #define SB_DEPTH 6
      14                 :             : 
      15                 :             : /*
      16                 :             : static int deep_map_stereo_atoms4=0;
      17                 :             : */
      18                 :             : 
      19                 :             : /****************************************************************************
      20                 :             :    map_stereo_bonds4 and map_stereo_atoms4 use
      21                 :             :    the following members of CANON_STAT *pCS:
      22                 :             : 
      23                 :             :         pCS->bKeepSymmRank  // ??? almost unused, replaced with nSymmStereo != NULL ???
      24                 :             :         pCS->bFirstCT
      25                 :             :         pCS->bStereoIsBetter
      26                 :             :         pCS->lNumNeighListIter
      27                 :             :         pCS->lNumBreakTies
      28                 :             :         pCS->lNumRejectedCT
      29                 :             :         pCS->lNumTotCT
      30                 :             :         pCS->lNumEqualCT
      31                 :             :         pCS->lNumDecreasedCT
      32                 :             :         pCS->bExtract (bRELEASE_VERSION == 0)
      33                 :             :         pCS->ulTimeOutTime
      34                 :             : 
      35                 :             :         pCS->bRankUsedForStereo
      36                 :             :         pCS->bAtomUsedForStereo
      37                 :             : 
      38                 :             :         pCS->LinearCTStereoDble
      39                 :             :         pCS->LinearCTStereoCarb
      40                 :             :         pCS->nLenLinearCTStereoCarb
      41                 :             :         pCS->nLenLinearCTStereoDble
      42                 :             : 
      43                 :             :         pCS->nPrevAtomNumber
      44                 :             : ****************************************************************************/
      45                 :             : 
      46                 :             : 
      47                 :             : /****************************************************************************/
      48                 :         109 : int map_stereo_bonds4( struct tagINCHI_CLOCK *ic,
      49                 :             :                         CANON_GLOBALS *pCG,
      50                 :             :                         sp_ATOM *at,
      51                 :             :                         int num_atoms,
      52                 :             :                         int num_at_tg,
      53                 :             :                         int num_max,
      54                 :             :                         int bAllene,
      55                 :             :                         const AT_RANK *nCanonRankFrom,
      56                 :             :                         const AT_RANK *nAtomNumberCanonFrom, /*  non-stereo canon ranking */
      57                 :             :                         AT_RANK *nCanonRankTo,  /* output canonical stereo numbering*/
      58                 :             :                         const AT_RANK *nSymmRank,
      59                 :             :                         AT_RANK   **pRankStack1 /* from */,
      60                 :             :                         AT_RANK **pRankStack2   /* to */,
      61                 :             :                         AT_RANK *nTempRank,
      62                 :             :                         int nNumMappedRanksInput,
      63                 :             :                         AT_RANK *nSymmStereo,
      64                 :             :                         NEIGH_LIST *NeighList,
      65                 :             :                         CANON_STAT *pCS,
      66                 :             :                         CUR_TREE *cur_tree,
      67                 :             :                         int nNumMappedBonds,
      68                 :             :                         int vABParityUnknown )
      69                 :             : {
      70                 :         109 :     int nTotSuccess = 0; /* 1=>full mapping has been completed;
      71                 :             :                           * 2=>obtained a better stereo;
      72                 :             :                           * 4=>restart (stereo bond or atom removed from the stereo CT)
      73                 :             :                           */
      74                 :         109 :     int tpos1 = 0;
      75                 :             :     AT_STEREO_DBLE prevBond;
      76                 :         109 :     memset( &prevBond, 0, sizeof( prevBond ) ); /* djb-rwth: memset_s C11/Annex K variant? */
      77                 :         109 :     tpos1 = CurTreeGetPos( cur_tree );
      78                 :             : 
      79                 :           0 : total_restart:
      80                 :             : 
      81         [ +  - ]:         109 :     if (!nNumMappedBonds)
      82                 :             :     {
      83                 :             : 
      84                 :         109 :         memset( pCS->bRankUsedForStereo, 0, sizeof( pCS->bRankUsedForStereo[0] )*num_atoms ); /* djb-rwth: memset_s C11/Annex K variant? */
      85                 :         109 :         SetUseAtomForStereo( pCS->bAtomUsedForStereo, at, num_atoms );
      86                 :             : 
      87   [ +  -  +  -  :         109 :         if (pCS->bFirstCT && nSymmStereo && !pCS->bKeepSymmRank)
                   +  - ]
      88                 :             :         {
      89                 :             :             int i;
      90         [ +  + ]:        1221 :             for (i = 0; i < num_at_tg; i++)
      91                 :             :             {
      92                 :             :                 /*  nSymmStereo[i] = min. {k | at[k] stereo eq. to at[i]} */
      93                 :        1112 :                 nSymmStereo[i] = i; /*  for union-join to keep track of stereo-equivalent atoms */
      94                 :             :             }
      95                 :             :         }
      96                 :             : #ifdef FIX_STEREOCOUNT_ERR
      97         [ +  - ]:         109 :         if (pCS->bFirstCT)
      98                 :             :         {
      99                 :         109 :             CurTreeSetPos( cur_tree, tpos1 = 0 );
     100                 :             :         }
     101                 :             : #endif
     102                 :             :     }
     103                 :             : 
     104         [ -  + ]:         109 :     if (nNumMappedBonds < pCS->nLenLinearCTStereoDble)
     105                 :             :     {
     106                 :             : 
     107                 :             :         int at_rank1, at_rank2, bStereoIsBetterWasSetHere;
     108                 :             :         /* AT_RANK *nRankFrom=*pRankStack1++,  AT_RANK *nAtomNumberFrom=pRankStack1++; */
     109                 :             :         /* AT_RANK *nRankTo  =*pRankStack2++,  AT_RANK *nAtomNumberTo  =pRankStack2++; */
     110                 :             :         AT_RANK canon_min1, canon_min2;
     111                 :             :         int bFirstCanonRank;
     112                 :             :         int i, j, j1, j2, at_from1, at_from2, at_to1, at_to2, iMax, c;
     113                 :             :         int nStackPtr[SB_DEPTH], nNumMappedRanks[SB_DEPTH], LastMappedTo1;
     114                 :             :         int istk, istk2, istk3, bAddStack, nNumAtTo1Success;
     115                 :             :         int ret1, ret2, parity1, parity2;
     116                 :             : 
     117                 :             :         AT_RANK at_rank_canon1; /*  = pCS->LinearCTStereoDble[nNumMappedBonds].at_num1; */ /*  canonical numbers of atoms */
     118                 :             :         AT_RANK at_rank_canon2; /*  = pCS->LinearCTStereoDble[nNumMappedBonds].at_num2; */ /*  adjacent to the stereogenic bond */
     119                 :             :         int nNumChoices, nNumUnkn, nNumUndf, nNumBest, nNumWorse, nNumCalc, sb_parity_calc;
     120                 :           0 :         int stereo_bond_parity = 0, prev_stereo_bond_parity, pass, bAllParitiesIdentical, bAllParitiesIdentical2;
     121                 :             :         AT_STEREO_DBLE prevBond2;
     122                 :             : 
     123                 :           0 :         prevBond = pCS->LinearCTStereoDble[nNumMappedBonds];
     124                 :           0 :         bFirstCanonRank = 1;
     125                 :           0 :         canon_min1 = canon_min2 = 0;
     126                 :             :         /*
     127                 :             :                 // find candidates for atom_from1, atom_to1; they must have identical mapping ranks
     128                 :             :                 at_rank1=pRankStack1[0][at_from1=nAtomNumberCanonFrom[(int)at_rank_canon1 - 1]]; // rank "from" for mapping
     129                 :             :                 at_rank2=pRankStack1[0][at_from2=nAtomNumberCanonFrom[(int)at_rank_canon2 - 1]]; // rank "from" for mapping
     130                 :             :         */
     131         [ #  # ]:           0 :         if (nNumMappedBonds)
     132                 :             :         {
     133                 :           0 :             at_rank_canon1 = pCS->LinearCTStereoDble[nNumMappedBonds - 1].at_num1;
     134                 :           0 :             at_rank_canon2 = pCS->LinearCTStereoDble[nNumMappedBonds - 1].at_num2;
     135                 :             :         }
     136                 :             :         else
     137                 :             :         {
     138                 :           0 :             at_rank_canon1 = 0;
     139                 :           0 :             at_rank_canon2 = 0;
     140                 :             :         }
     141                 :           0 :         goto bypass_next_canon_ranks_check;
     142                 :             : 
     143                 :           0 :     next_canon_ranks:
     144                 :             : 
     145                 :             :             /*  Save time: avoid calling Next_SB_At_CanonRanks2() */
     146         [ #  # ]:           0 :         if ((!pCS->bStereoIsBetter /* ??? && !pCS->bFirstCT ???*/ &&
     147         [ #  # ]:           0 :               at_rank_canon1 > pCS->LinearCTStereoDble[nNumMappedBonds].at_num1) ||
     148         [ #  # ]:           0 :               (at_rank_canon1 == pCS->LinearCTStereoDble[nNumMappedBonds].at_num1 &&
     149         [ #  # ]:           0 :               at_rank_canon2 >= pCS->LinearCTStereoDble[nNumMappedBonds].at_num2)) /* djb-rwth: addressing LLVM warning */
     150                 :             :         {
     151                 :             : 
     152         [ #  # ]:           0 :             if (!nTotSuccess)
     153                 :             :             {
     154                 :           0 :                 pCS->LinearCTStereoDble[nNumMappedBonds] = prevBond;
     155                 :             :             }
     156                 :           0 :             CurTreeSetPos( cur_tree, tpos1 );
     157                 :           0 :             return nTotSuccess;
     158                 :             :         }
     159                 :             : 
     160                 :           0 :     bypass_next_canon_ranks_check:
     161                 :             : 
     162                 :           0 :         CurTreeSetPos( cur_tree, tpos1 );
     163                 :             : 
     164                 :             :         /*  find next available canon. numbers for a stereogenic bond pair of atoms */
     165                 :             :         /*  process allenes AFTER all double bonds and odd-number-of-double-bonds cumulenes */
     166         [ #  # ]:           0 :         if (!( ret1 = Next_SB_At_CanonRanks2( &at_rank_canon1, &at_rank_canon2, /*  canonical numbers */
     167                 :             :             &canon_min1, &canon_min2,
     168                 :             :             &bFirstCanonRank, pCS->bAtomUsedForStereo,
     169                 :             :             pRankStack1, pRankStack2,
     170                 :             :             nCanonRankFrom, nAtomNumberCanonFrom,
     171                 :             :             at, num_atoms, bAllene ) ))
     172                 :             :         {
     173                 :             :             /* failed to find next stereo bond to assign parity */
     174   [ #  #  #  # ]:           0 :             if (!bAllene && bFirstCanonRank)
     175                 :             :             {
     176                 :             :                 /* all stereobond have been processed; try to find allene to continue */
     177                 :           0 :                 AT_RANK at_rank_canon1_Allene = 0, canon_min1_Allene = 0;
     178                 :           0 :                 AT_RANK at_rank_canon2_Allene = 0, canon_min2_Allene = 0;
     179         [ #  # ]:           0 :                 if ((ret1 = Next_SB_At_CanonRanks2( &at_rank_canon1_Allene, &at_rank_canon2_Allene,
     180                 :             :                     &canon_min1_Allene, &canon_min2_Allene,
     181                 :             :                     &bFirstCanonRank, pCS->bAtomUsedForStereo,
     182                 :             :                     pRankStack1, pRankStack2,
     183                 :             :                     nCanonRankFrom, nAtomNumberCanonFrom,
     184                 :             :                     at, num_atoms, 1 ))) /* djb-rwth: addressing LLVM warning */
     185                 :             :                 {
     186                 :           0 :                     at_rank_canon1 = at_rank_canon1_Allene;
     187                 :           0 :                     at_rank_canon2 = at_rank_canon2_Allene;
     188                 :           0 :                     canon_min1 = canon_min1_Allene;
     189                 :           0 :                     canon_min2 = canon_min2_Allene;
     190                 :           0 :                     bAllene = 1; /* switch to allenes */
     191                 :             :                 }
     192                 :             :             }
     193                 :             :         }
     194                 :             : 
     195   [ #  #  #  # ]:           0 :         if (!ret1 || (!pCS->bStereoIsBetter &&
     196         [ #  # ]:           0 :             ( at_rank_canon1 > pCS->LinearCTStereoDble[nNumMappedBonds].at_num1 ||
     197         [ #  # ]:           0 :                 (at_rank_canon1 == pCS->LinearCTStereoDble[nNumMappedBonds].at_num1 &&
     198         [ #  # ]:           0 :                 at_rank_canon2 > pCS->LinearCTStereoDble[nNumMappedBonds].at_num2) ))) /* djb-rwth: addressing LLVM warnings */
     199                 :             :         {
     200                 :             :             /* new ranks provide greater pCS->LinearCTStereoDble[nNumMappedBonds] and therefore rejected */
     201         [ #  # ]:           0 :             if (!nTotSuccess)
     202                 :             :             {
     203                 :           0 :                 pCS->LinearCTStereoDble[nNumMappedBonds] = prevBond; /* restore stereo bond CT for the current bond */
     204                 :             :             }
     205                 :           0 :             return nTotSuccess;
     206                 :             :         }
     207                 :             : 
     208                 :             :         /* current stereo bond initialization */
     209                 :           0 :         nNumChoices = 0;
     210                 :           0 :         nNumUnkn = 0;
     211                 :           0 :         nNumUndf = 0;
     212                 :           0 :         nNumBest = 0;
     213                 :           0 :         nNumWorse = 0;
     214                 :           0 :         nNumCalc = 0;
     215                 :           0 :         pass = 0;
     216                 :           0 :         prev_stereo_bond_parity = 0;
     217                 :             : 
     218                 :           0 :         at_rank1 = pRankStack1[0][at_from1 = nAtomNumberCanonFrom[(int) at_rank_canon1 - 1]]; /* atom 1 rank "from" for mapping */
     219                 :           0 :         at_rank2 = pRankStack1[0][at_from2 = nAtomNumberCanonFrom[(int) at_rank_canon2 - 1]]; /* atom 2 rank "from" for mapping */
     220                 :             :         /* we are going to map bond (at[at_from1], at[at_from2]) and
     221                 :             :            canonical ranks of its atoms (at_rank_canon1, at_rank_canon2)
     222                 :             :            onto a stereogenic bond (at[at_to1], at[at_to2])
     223                 :             :          */
     224                 :           0 :         iMax = at_rank1 - 1;
     225                 :             :         /*  test correctness: sorted pRankStack2[0][] and pRankStack1[0][] should have same ranks for both atoms */
     226         [ #  # ]:           0 :         if (at_rank1 != pRankStack2[0][pRankStack2[1][at_rank1 - 1]] ||
     227         [ #  # ]:           0 :              at_rank2 != pRankStack2[0][pRankStack2[1][at_rank2 - 1]])
     228                 :             :         {
     229                 :             :             /* program error: "from" and "to" mapping ranks are not equal */
     230                 :           0 :             return CT_STEREOCOUNT_ERR; /*   <BRKPT> */
     231                 :             :         }
     232                 :             :         /* -- do not check stereo features of "from" atoms:
     233                 :             :            -- in case of "bond/charge isomerism" they may be missing.
     234                 :             :         if ( !at[at_from1].stereo_bond_neighbor[0] ||
     235                 :             :              !at[at_from2].stereo_bond_neighbor[0] )
     236                 :             :             return CT_STEREOCOUNT_ERR; // program error
     237                 :             :         */
     238                 :             : 
     239                 :             :         /*  find out if we have a choice in mapping: check all possible pairs (at_to1, at_to2)
     240                 :             :             such that at_from1 is possibly constitutionally equivalent to at_to1, at_from2 to at_to2 */
     241   [ #  #  #  # ]:           0 :         for (j1 = 0; j1 <= iMax && at_rank1 == pRankStack2[0][at_to1 = pRankStack2[1][iMax - j1]]; j1++)
     242                 :             :         {
     243         [ #  # ]:           0 :             if (!at[at_to1].stereo_bond_neighbor[0])
     244                 :           0 :                 continue; /*  at_to1 does not belong to a stereo bond */
     245         [ #  # ]:           0 :             for (j2 = 0; j2 < MAX_NUM_STEREO_BONDS &&
     246         [ #  # ]:           0 :                 ( at_to2 = at[at_to1].stereo_bond_neighbor[j2] ); j2++)
     247                 :             :             {
     248                 :           0 :                 at_to2--;
     249         [ #  # ]:           0 :                 if (pRankStack1[0][at_from2] != pRankStack2[0][at_to2])
     250                 :           0 :                     continue; /*  at_from2 cannot be mapped on at_to2 */
     251                 :           0 :                 stereo_bond_parity = PARITY_VAL( at[at_to1].stereo_bond_parity[j2] );
     252                 :           0 :                 i = 0;
     253   [ #  #  #  #  :           0 :                 switch (stereo_bond_parity)
                #  #  # ]
     254                 :             :                 {
     255                 :             : 
     256                 :           0 :                     case AB_PARITY_UNDF: nNumUndf++;
     257                 :           0 :                         break; /*  4 */
     258                 :           0 :                     case AB_PARITY_UNKN: nNumUnkn++;
     259                 :           0 :                         break; /*  3 (occurs if forced different to UNDF)*/
     260                 :             : 
     261                 :           0 :                     case BEST_PARITY:    nNumBest++; break; /*  1 */
     262                 :           0 :                     case WORSE_PARITY:   nNumWorse++; break; /*  2 */
     263                 :           0 :                     case AB_PARITY_CALC: nNumCalc++; break; /*  6 */
     264                 :           0 :                     case AB_PARITY_NONE: i++;         break; /*  0 */
     265                 :             :                 }
     266                 :           0 :                 nNumChoices += !i;
     267                 :             :             }
     268                 :             :         }
     269         [ #  # ]:           0 :         if (nNumChoices != nNumCalc + nNumUndf + nNumUnkn + nNumBest + nNumWorse)
     270                 :             :         {
     271                 :           0 :             return CT_STEREOCOUNT_ERR; /*  program error */ /*   <BRKPT> */
     272                 :             :         }
     273         [ #  # ]:           0 :         if (!nNumChoices)
     274                 :             :         {
     275                 :           0 :             goto next_canon_ranks;
     276                 :             :         }
     277                 :             :         /*  Determine the first parity to search */
     278                 :           0 :         sb_parity_calc = ( nNumCalc > 0 ) ? BEST_PARITY : 0;
     279                 :             : 
     280                 :             :         /*  ==============================================================
     281                 :             :             Search sequence:           sb_parity_calc    stereo_bond_parity
     282                 :             :             ==============================================================
     283                 :             :             BEST_PARITY   (calc)       BEST_PARITY     BEST_PARITY
     284                 :             :             BEST_PARITY   (known)      BEST_PARITY     WORSE_PARITY  or 0
     285                 :             :             WORSE_PARITY  (calc)       WORSE_PARITY    WORSE_PARITY
     286                 :             :             WORSE_PARITY  (known)      WORSE_PARITY    0
     287                 :             :             AB_PARITY_UNKN(known)      AB_PARITY_UNKN  0
     288                 :             :             AB_PARITY_UNDF(known)      AB_PARITY_UNDF  0
     289                 :             : 
     290                 :             :             if (sb_parity_calc==stereo_bond_parity) then "calc" else "known"
     291                 :             :          */
     292                 :             : 
     293                 :           0 :     repeat_all:
     294                 :             : 
     295         [ #  # ]:           0 :         if (!nNumMappedBonds)
     296                 :           0 :             pCS->bStereoIsBetter = 0;  /*  the first stereo feature in the canonical CT; moved here 7-13-2002 */
     297                 :             : 
     298         [ #  # ]:           0 :         if (!pass++)
     299                 :             :         {
     300                 :             :             /*  select the smallest (best) parity to search */
     301         [ #  # ]:           0 :             if (sb_parity_calc)
     302                 :             :             {
     303                 :           0 :                 stereo_bond_parity = BEST_PARITY;
     304                 :             :             }
     305                 :             :             else
     306                 :             :             {
     307         [ #  # ]:           0 :                 stereo_bond_parity = nNumBest ? BEST_PARITY :
     308         [ #  # ]:           0 :                     nNumWorse ? WORSE_PARITY :
     309         [ #  # ]:           0 :                     nNumUnkn ? AB_PARITY_UNKN :
     310         [ #  # ]:           0 :                     nNumUndf ? AB_PARITY_UNDF : AB_PARITY_NONE;
     311                 :             :             }
     312                 :             :         }
     313                 :             :         else
     314                 :             :         {
     315                 :             :              /* second pass: since the first pass failed, search for a worse result */
     316                 :           0 :             prev_stereo_bond_parity = stereo_bond_parity;
     317                 :           0 :             i = NextStereoParity2Test( &stereo_bond_parity, &sb_parity_calc,
     318                 :             :                                      nNumBest, nNumWorse, nNumUnkn, nNumUndf, nNumCalc, vABParityUnknown );
     319      [ #  #  # ]:           0 :             switch (i)
     320                 :             :             {
     321                 :           0 :                 case 0:
     322                 :           0 :                     break; /* obtained next parity to test */
     323                 :           0 :                 case 1:
     324                 :           0 :                     goto next_canon_ranks;
     325                 :           0 :                 default:
     326                 :           0 :                     return i; /* program error */
     327                 :             :             }
     328                 :             :         }
     329         [ #  # ]:           0 :         if (stereo_bond_parity == AB_PARITY_NONE)
     330                 :             :         {
     331                 :             :             /*  error? */
     332                 :           0 :             return CT_STEREOCOUNT_ERR;                   /*   <BRKPT> */
     333                 :             :         }
     334                 :             :         /*  check if the new requested parity is good (small) enough */
     335         [ #  # ]:           0 :         if (!pCS->bStereoIsBetter)
     336                 :             :         {
     337                 :           0 :             c = CompareLinCtStereoDoubleToValues( nTotSuccess ? pCS->LinearCTStereoDble + nNumMappedBonds : &prevBond,
     338         [ #  # ]:           0 :                               at_rank_canon1, at_rank_canon2, (U_CHAR) stereo_bond_parity );
     339         [ #  # ]:           0 :             if (c < 0)
     340                 :             :             {
     341         [ #  # ]:           0 :                 if (!nTotSuccess)
     342                 :             :                 {
     343                 :           0 :                     pCS->LinearCTStereoDble[nNumMappedBonds] = prevBond;
     344                 :             :                 }
     345                 :           0 :                 CurTreeSetPos( cur_tree, tpos1 );
     346                 :           0 :                 return nTotSuccess;
     347                 :             :             }
     348                 :             :         }
     349                 :             : 
     350                 :           0 :         bAllParitiesIdentical = 0;
     351                 :             :         /* djb-rwth: removing redundant code */
     352                 :           0 :         LastMappedTo1 = -1;
     353                 :           0 :         bStereoIsBetterWasSetHere = 0;
     354                 :             :         /* djb-rwth: removing redundant code */
     355                 :             : 
     356   [ #  #  #  # ]:           0 :         if (!nNumMappedBonds && prev_stereo_bond_parity != stereo_bond_parity)
     357                 :           0 :             pCS->bStereoIsBetter = 0;  /*  the first stereo feature in the canonical CT; moved here 5-24-2002 */
     358                 :             : 
     359         [ #  # ]:           0 :         if (prev_stereo_bond_parity != stereo_bond_parity)
     360                 :             :         {
     361                 :           0 :             CurTreeSetPos( cur_tree, tpos1 );  /*  start over */
     362                 :             :         }
     363                 :             : 
     364                 :             :         /* Mapping: here at_rank1 = nRankTo, at_to1 = nAtomNumberTo */
     365   [ #  #  #  # ]:           0 :         for (j1 = 0; j1 <= iMax && at_rank1 == pRankStack2[0][at_to1 = pRankStack2[1][iMax - j1]]; j1++)
     366                 :             :         {
     367                 :           0 :             nNumAtTo1Success = 0;
     368         [ #  # ]:           0 :             if (!at[at_to1].stereo_bond_neighbor[0])
     369                 :           0 :                 continue; /*  at_to1 does not belong to a stereo bond */
     370   [ #  #  #  # ]:           0 :             if (tpos1 < CurTreeGetPos( cur_tree ) &&
     371         [ #  # ]:           0 :                  1 == CurTreeIsLastRank( cur_tree, at_rank_canon1 ) &&
     372                 :           0 :                  1 == CurTreeIsLastAtomEqu( cur_tree, at_to1, nSymmStereo ))
     373                 :             :             {
     374                 :             :                 /* at_to1 is known to be stereogenically equivalent to another atom tried with at_rank_canon1 */
     375                 :           0 :                 continue;
     376                 :             :             }
     377                 :           0 :             bAllParitiesIdentical2 = 0;
     378   [ #  #  #  # ]:           0 :             for (j2 = 0; j2 < MAX_NUM_STEREO_BONDS && ( at_to2 = at[at_to1].stereo_bond_neighbor[j2] ); j2++)
     379                 :             :             {
     380                 :             :                 EQ_NEIGH  EN1[2], EN2[2];
     381                 :             :                 int bond_parity, num1, num2;
     382                 :             :                 AT_RANK at_rank_canon_n1, at_rank_canon_n2;
     383                 :             : 
     384                 :           0 :                 at_to2--;
     385         [ #  # ]:           0 :                 if (pRankStack1[0][at_from2] != pRankStack2[0][at_to2])
     386                 :           0 :                     continue; /*  at_from2 cannot be mapped on at_to2 even without mapping at_from1 to at_to1 */
     387                 :             : 
     388                 :             :                 /*  check whether the bond parity corresponds to the requested bond parity */
     389   [ #  #  #  # ]:           0 :                 if (PARITY_KNOWN( at[at_to1].stereo_bond_parity[j2] ))
     390                 :             :                 {
     391         [ #  # ]:           0 :                     if (stereo_bond_parity == sb_parity_calc)
     392                 :             :                     {
     393                 :           0 :                         continue;  /*  requested parity to be calculated, found known parity */
     394                 :             :                     }
     395         [ #  # ]:           0 :                     if (stereo_bond_parity != PARITY_VAL( at[at_to1].stereo_bond_parity[j2] ))
     396                 :             :                     {
     397                 :           0 :                         continue;  /*  parity differs from the requested parity */
     398                 :             :                     }
     399                 :             :                 }
     400                 :             :                 else
     401         [ #  # ]:           0 :                     if (PARITY_CALCULATE( at[at_to1].stereo_bond_parity[j2] ))
     402                 :             :                     {
     403         [ #  # ]:           0 :                         if (stereo_bond_parity != sb_parity_calc)
     404                 :             :                         {
     405                 :           0 :                             continue;  /*  requested known parity, found parity to be calculated */
     406                 :             :                         }
     407                 :             :                     }
     408                 :             :                     else
     409                 :             :                     {
     410                 :           0 :                         return CT_STEREOCOUNT_ERR;  /*  unknown parity type */ /*   <BRKPT> */
     411                 :             :                     }
     412                 :             :                     /*  initialize stack pointer nStackPtr[istk] for "hand-made" recursion */
     413                 :             :                     /*  stacks are pRankStack1[], pRankStack2[], nNumMappedRanks[] */
     414                 :           0 :                 istk = 0;
     415                 :           0 :                 nStackPtr[0] = 0;
     416                 :           0 :                 nNumMappedRanks[0] = nNumMappedRanksInput;
     417                 :           0 :                 bAddStack = 0;
     418         [ #  # ]:           0 :                 bAllParitiesIdentical = ( ( at[at_to1].stereo_bond_parity[j2] & KNOWN_PARITIES_EQL ) ) &&
     419   [ #  #  #  # ]:           0 :                     PARITY_KNOWN( at[at_to1].stereo_bond_parity[j2] );
     420                 :             : 
     421   [ #  #  #  # ]:           0 :                 if (!bAllParitiesIdentical && !nNumCalc &&
     422         [ #  # ]:           0 :                     ( !nNumUndf + !nNumUnkn + !nNumBest + !nNumWorse ) == 3)
     423                 :             :                 {
     424                 :             :                     /* only one kind of bond parity is present; check whether all parities are really same */
     425                 :           0 :                     bAllParitiesIdentical = All_SB_Same( at_rank_canon1, at_rank_canon2, /*  canonical numbers */
     426                 :             :                                                           pRankStack1, pRankStack2,
     427                 :             :                                                           nAtomNumberCanonFrom, at );
     428         [ #  # ]:           0 :                     if (bAllParitiesIdentical < 0)
     429                 :             :                     {
     430                 :           0 :                         return CT_STEREOCOUNT_ERR;  /*   <BRKPT> */
     431                 :             :                     }
     432                 :             :                 }
     433                 :             : 
     434                 :             :                 /*****************************************************************
     435                 :             :                  * do the mapping only if parities are not same
     436                 :             :                  */
     437         [ #  # ]:           0 :                 if (!bAllParitiesIdentical)
     438                 :             :                 {
     439                 :             :                     /*  map atom 1 or reuse previous mapping */
     440         [ #  # ]:           0 :                     if (LastMappedTo1 != at_to1)
     441                 :             :                     {
     442                 :             :                         /*  avoid repetitve mapping to the same first at_to1 using LastMappedTo1 variable */
     443                 :             :                         /*  map atom 1 */
     444                 :           0 :                         ret1 = map_an_atom2( pCG, num_at_tg, num_max, at_from1, at_to1,
     445                 :           0 :                                             nTempRank, nNumMappedRanks[istk], &nNumMappedRanks[istk + 1], pCS,
     446                 :           0 :                                             NeighList, pRankStack1 + nStackPtr[istk], pRankStack2 + nStackPtr[istk],
     447                 :             :                                             &bAddStack );
     448   [ #  #  #  # ]:           0 :                         if (RETURNED_ERROR( ret1 ))
     449                 :             :                         {
     450                 :           0 :                             return ret1; /*  error */
     451                 :             :                         }
     452                 :           0 :                         nStackPtr[istk + 1] = nStackPtr[istk] + bAddStack;
     453                 :           0 :                         LastMappedTo1 = at_to1;
     454         [ #  # ]:           0 :                         if (bAddStack)
     455                 :             :                         {
     456   [ #  #  #  # ]:           0 :                             if (tpos1 == CurTreeGetPos( cur_tree ) ||
     457                 :           0 :                                  0 == CurTreeIsLastRank( cur_tree, at_rank_canon1 ))
     458                 :             :                             {
     459                 :           0 :                                 CurTreeAddRank( cur_tree, at_rank_canon1 );
     460                 :             :                             }
     461                 :           0 :                             CurTreeAddAtom( cur_tree, at_to1 );
     462                 :             :                         }
     463                 :             :                     }
     464                 :           0 :                     istk++; /*  = 1 */
     465                 :             :                     /*  check if we can map atom 2 */
     466         [ #  # ]:           0 :                     if (pRankStack1[nStackPtr[istk]][at_from2] != pRankStack2[nStackPtr[istk]][at_to2])
     467                 :             :                     {
     468                 :             :                         /*
     469                 :             :                          * This may happen when:
     470                 :             :                          * A) Charge/bond isomerism, for example cyclopentadiene(-), or
     471                 :             :                          * B) possibly stereogenic bond in an alternating ring has heighbors
     472                 :             :                          * in 2 symmetrically attached rings.
     473                 :             :                          * Such an alternating bond cannot be mapped on possibly stereogenic bond
     474                 :             :                          * that has neighbors belonging to 1 of the symmetrically attached rings only.
     475                 :             :                          * For example:
     476                 :             :                          *   A---B---C---D  If all atoms are Carbons then B, C, F, G are constitutionally
     477                 :             :                          *  ||  ||  ||  ||  equivalent. However, bonds B-C, F-G are not equivalent to
     478                 :             :                          *  ||  ||  ||  ||  B-F and C-G and cannot be mapped on them.
     479                 :             :                          *   E---F---G---H  If at_from1=B, at_from2=F, at_to1=B, then at_from2 cannot be mapped on at_to2=C
     480                 :             :                          *                  If at_from1=B, at_from2=F, at_to1=C, then at_from2 cannot be mapped on at_to2=B
     481                 :             :                          *                  etc.
     482                 :             :                          */
     483         [ #  # ]:           0 :                         if (sb_parity_calc != stereo_bond_parity)
     484                 :             :                         {
     485                 :             :                             /* can be passed only once for each bond */
     486                 :           0 :                             nNumChoices--;
     487                 :           0 :                             nNumUndf -= ( stereo_bond_parity == AB_PARITY_UNDF );
     488                 :           0 :                             nNumUnkn -= ( stereo_bond_parity == AB_PARITY_UNKN );
     489                 :           0 :                             nNumBest -= ( stereo_bond_parity == BEST_PARITY );
     490                 :           0 :                             nNumWorse -= ( stereo_bond_parity == WORSE_PARITY );
     491                 :             :                             /* nNumCalc  = nNumChoices - (nNumUndf + nNumUnkn + nNumBest + nNumWorse); */
     492                 :             :                         }
     493                 :             :                         else
     494         [ #  # ]:           0 :                             if (sb_parity_calc == BEST_PARITY)
     495                 :             :                             {
     496                 :             :                                 /* can be passed 2 times: for BEST_PARITY and WORSE_PARITY in this order */
     497                 :           0 :                                 nNumChoices--; /*  do not repeate for WORSE_PARITY */
     498                 :           0 :                                 nNumCalc--;
     499                 :             :                             }
     500                 :           0 :                         continue;  /*  Happens for ID=80036,80253,91354,95532,101532,103788 */
     501                 :             :                     }
     502         [ #  # ]:           0 :                     if (nStackPtr[istk] > nStackPtr[istk - 1])
     503                 :             :                     {
     504                 :           0 :                         bAllParitiesIdentical2 = All_SB_Same( at_rank_canon1, at_rank_canon2,
     505                 :           0 :                                                   pRankStack1 + nStackPtr[istk], pRankStack2 + nStackPtr[istk],
     506                 :             :                                                   nAtomNumberCanonFrom, at );
     507         [ #  # ]:           0 :                         if (bAllParitiesIdentical2 < 0)
     508                 :             :                         {
     509                 :           0 :                             return CT_STEREOBOND_ERROR;  /*   <BRKPT> */
     510                 :             :                         }
     511                 :             :                     }
     512                 :             :                     else
     513                 :             :                     {
     514                 :           0 :                         bAllParitiesIdentical2 = 0;
     515                 :             :                     }
     516         [ #  # ]:           0 :                     if (bAllParitiesIdentical2)
     517                 :             :                     {
     518                 :             :                         /*  do no mapping when all equivalent bonds have same parity */
     519                 :             :                         /*  stereo_bond_parity = PARITY_VAL(at[at_to1].stereo_bond_parity[j2]); */
     520                 :           0 :                         ClearPreviousMappings( pRankStack1 + nStackPtr[istk] + 2 );
     521                 :             :                     }
     522                 :             :                     else
     523                 :             :                     {
     524   [ #  #  #  # ]:           0 :                         if (tpos1 < CurTreeGetPos( cur_tree ) &&
     525         [ #  # ]:           0 :                              1 == CurTreeIsLastRank( cur_tree, at_rank_canon2 ) &&
     526                 :           0 :                              1 == CurTreeIsLastAtomEqu( cur_tree, at_to2, nSymmStereo ))
     527                 :             :                         {
     528                 :           0 :                             continue;
     529                 :             :                         }
     530                 :             :                         /*  map atom 2 */
     531                 :           0 :                         ret2 = map_an_atom2( pCG, num_at_tg, num_max, at_from2, at_to2,
     532                 :           0 :                                             nTempRank, nNumMappedRanks[istk], &nNumMappedRanks[istk + 1], pCS,
     533                 :           0 :                                             NeighList, pRankStack1 + nStackPtr[istk], pRankStack2 + nStackPtr[istk],
     534                 :             :                                             &bAddStack );
     535   [ #  #  #  # ]:           0 :                         if (RETURNED_ERROR( ret2 ))
     536                 :             :                         {
     537                 :           0 :                             return ret2; /*  program error */
     538                 :             :                         }
     539                 :           0 :                         nStackPtr[istk + 1] = nStackPtr[istk] + bAddStack;
     540                 :           0 :                         istk++; /*  = 2 */
     541         [ #  # ]:           0 :                         if (bAddStack)
     542                 :             :                         {
     543   [ #  #  #  # ]:           0 :                             if (tpos1 == CurTreeGetPos( cur_tree ) ||
     544                 :           0 :                                  0 == CurTreeIsLastRank( cur_tree, at_rank_canon2 ))
     545                 :             :                             {
     546                 :           0 :                                 CurTreeAddRank( cur_tree, at_rank_canon2 );
     547                 :             :                             }
     548                 :           0 :                             CurTreeAddAtom( cur_tree, at_to2 );
     549                 :             :                         }
     550                 :             :                     }
     551                 :             :                 }
     552                 :             :                 else
     553                 :             :                 {
     554                 :             :                     /*  do no mapping when all equivalent bonds have same parity */
     555                 :             :                     /*  stereo_bond_parity = PARITY_VAL(at[at_to1].stereo_bond_parity[j2]); */
     556                 :           0 :                     ClearPreviousMappings( pRankStack1 + 2 );
     557                 :             :                 }
     558                 :             : 
     559                 :             :                 /*  we have a precalculated (known) bond parity */
     560                 :             : 
     561                 :             :                 /************************************************************
     562                 :             :                  *
     563                 :             :                  *   Known Bond Parity case: do not map stereo bond neighbors
     564                 :             :                  */
     565         [ #  # ]:           0 :                 if (stereo_bond_parity != sb_parity_calc) /*  parity is known */
     566                 :             :                 {
     567                 :             :                     /*  accept bond parity and do not map the neighbors */
     568                 :           0 :                     bond_parity = stereo_bond_parity;
     569                 :             :                     /*  same code as under " make a decision to accept current mapping" comment below */
     570                 :             :                     /*  with one exception: istk instead of istk3 */
     571                 :           0 :                     c = CompareLinCtStereoDoubleToValues( pCS->LinearCTStereoDble + nNumMappedBonds,
     572                 :           0 :                                               at_rank_canon1, at_rank_canon2, (U_CHAR) bond_parity );
     573   [ #  #  #  # ]:           0 :                     if (c < 0 && !pCS->bStereoIsBetter)
     574                 :             :                     {
     575                 :             :                         /*  reject */
     576                 :             : 
     577                 :           0 :                         pCS->lNumRejectedCT++;
     578                 :             :                         /*  remove failed atom2 from the tree */
     579   [ #  #  #  # ]:           0 :                         if (tpos1 < CurTreeGetPos( cur_tree ) &&
     580                 :           0 :                              1 == CurTreeIsLastRank( cur_tree, at_rank_canon2 ))
     581                 :             :                         {
     582                 :           0 :                             CurTreeRemoveIfLastAtom( cur_tree, at_to2 );
     583                 :           0 :                             CurTreeRemoveLastRankIfNoAtoms( cur_tree );
     584                 :             :                         }
     585                 :           0 :                         continue;  /*  to next at_to2; Reject this at_to2: not a minimal CT. */
     586                 :             :                     }
     587                 :             :                     else
     588                 :             :                     {
     589                 :             :                         /*  accept */
     590                 :             : 
     591   [ #  #  #  # ]:           0 :                         if (c > 0 && !pCS->bStereoIsBetter)
     592                 :             :                         {
     593                 :             :                             /*  bond entry is less than the previusly found */
     594                 :           0 :                             pCS->bStereoIsBetter = bStereoIsBetterWasSetHere = 1;
     595                 :           0 :                             prevBond2 = pCS->LinearCTStereoDble[nNumMappedBonds];
     596                 :             :                         }
     597                 :           0 :                         pCS->LinearCTStereoDble[nNumMappedBonds].at_num1 = at_rank_canon1;
     598                 :           0 :                         pCS->LinearCTStereoDble[nNumMappedBonds].at_num2 = at_rank_canon2;
     599                 :           0 :                         pCS->LinearCTStereoDble[nNumMappedBonds].parity = bond_parity;
     600                 :             :                         /*  recursive call */
     601                 :           0 :                         pCS->bRankUsedForStereo[at_from1] ++;
     602                 :           0 :                         pCS->bRankUsedForStereo[at_from2] ++;
     603         [ #  # ]:           0 :                         if (!bAllParitiesIdentical)
     604                 :             :                         {
     605                 :           0 :                             pCS->bAtomUsedForStereo[at_to1] --;
     606                 :           0 :                             pCS->bAtomUsedForStereo[at_to2] --;
     607                 :             :                         }
     608                 :           0 :                         ret2 = map_stereo_bonds4( ic, pCG, at, num_atoms, num_at_tg, num_max, bAllene, nCanonRankFrom, nAtomNumberCanonFrom, nCanonRankTo,
     609                 :           0 :                                                   nSymmRank, pRankStack1 + nStackPtr[istk], pRankStack2 + nStackPtr[istk],
     610                 :             :                                                   nTempRank, nNumMappedRanks[istk], nSymmStereo, NeighList,
     611                 :             :                                                   pCS, cur_tree, nNumMappedBonds + 1,
     612                 :             :                                                   vABParityUnknown );
     613         [ #  # ]:           0 :                         if (!bAllParitiesIdentical)
     614                 :             :                         {
     615                 :           0 :                             pCS->bAtomUsedForStereo[at_to1] ++;
     616                 :           0 :                             pCS->bAtomUsedForStereo[at_to2] ++;
     617                 :             :                         }
     618                 :           0 :                         pCS->bRankUsedForStereo[at_from1] --;
     619                 :           0 :                         pCS->bRankUsedForStereo[at_from2] --;
     620         [ #  # ]:           0 :                         if (ret2 == 4)
     621                 :             :                         {
     622         [ #  # ]:           0 :                             if (nNumMappedBonds)
     623                 :             :                             {
     624                 :           0 :                                 return ret2;
     625                 :             :                             }
     626                 :             :                             else
     627                 :             :                             {
     628                 :           0 :                                 pCS->bFirstCT = 1;
     629                 :           0 :                                 goto total_restart;
     630                 :             :                             }
     631                 :             :                         }
     632                 :             : 
     633   [ #  #  #  # ]:           0 :                         if (RETURNED_ERROR( ret2 ))
     634                 :             :                         {
     635         [ #  # ]:           0 :                             if (ret2 == CT_TIMEOUT_ERR)
     636                 :           0 :                                 return ret2;
     637                 :             :                             else
     638                 :           0 :                                 return ret2; /*  program error */
     639                 :             :                         }
     640         [ #  # ]:           0 :                         if (ret2 > 0)
     641                 :             :                         {
     642                 :           0 :                             nTotSuccess |= 1;
     643                 :           0 :                             nNumAtTo1Success++;
     644   [ #  #  #  # ]:           0 :                             if (bStereoIsBetterWasSetHere || ( ret2 & 2 ))
     645                 :             :                             {
     646                 :           0 :                                 CurTreeKeepLastAtomsOnly( cur_tree, tpos1, 1 );  /*  start over */
     647                 :           0 :                                 nTotSuccess |= 2; /*  Obtained a smaller CT */
     648                 :             :                             }
     649                 :             :                         }
     650                 :             :                         else
     651                 :             :                         {
     652         [ #  # ]:           0 :                             if (bStereoIsBetterWasSetHere)
     653                 :             :                             { /*  rollback */
     654                 :           0 :                                 pCS->bStereoIsBetter = 0;
     655                 :           0 :                                 pCS->LinearCTStereoDble[nNumMappedBonds] = prevBond2;
     656                 :             :                             }
     657                 :             :                             /*  remove failed atom2 from the tree */
     658   [ #  #  #  # ]:           0 :                             if (tpos1 < CurTreeGetPos( cur_tree ) &&
     659                 :           0 :                                  1 == CurTreeIsLastRank( cur_tree, at_rank_canon2 ))
     660                 :             :                             {
     661                 :           0 :                                 CurTreeRemoveIfLastAtom( cur_tree, at_to2 );
     662                 :           0 :                                 CurTreeRemoveLastRankIfNoAtoms( cur_tree );
     663                 :             :                             }
     664                 :             :                             /*
     665                 :             :                             if ( 1 == CurTreeIsLastRank( cur_tree, at_rank_canon1 ) ) {
     666                 :             :                                 CurTreeRemoveLastAtom( cur_tree, at_to1 );
     667                 :             :                                 CurTreeRemoveLastRankIfNoAtoms( cur_tree );
     668                 :             :                             }
     669                 :             :                             */
     670                 :             :                         }
     671                 :           0 :                         bStereoIsBetterWasSetHere = 0;
     672                 :             :                     }
     673   [ #  #  #  # ]:           0 :                     if (bAllParitiesIdentical || bAllParitiesIdentical2)
     674                 :             :                     {
     675                 :             :                         break; /* j2 cycle, at_to2 (no need to repeat) */
     676                 :             :                     }
     677                 :           0 :                     continue; /*  to next at_to2 */
     678                 :             :                 }
     679                 :             :                 /***************************************************************************
     680                 :             :                  *
     681                 :             :                  *   Unknown Bond Parity case: may need to map stereo bond neighbors
     682                 :             :                  *
     683                 :             :                  ****************************************************************************
     684                 :             :                  * Ranks are not known in advance
     685                 :             :                  * check if at_from1/at_to1 half-bond has neighbors with equal mapping ranks
     686                 :             :                  */
     687                 :             : 
     688                 :           0 :                 parity1 = parity_of_mapped_half_bond( at_from1, at_to1, at_from2, at_to2, at, &EN1[0],
     689                 :           0 :                            nCanonRankFrom, pRankStack1[nStackPtr[istk]], pRankStack2[nStackPtr[istk]] );
     690                 :             :                 /* old approach -- before E/Z parities
     691                 :             :                 parity1 = parity_of_mapped_atom2( pCG, at_from1, at_to1, at, &EN1[0],
     692                 :             :                                nCanonRankFrom, pRankStack1[nStackPtr[istk]], pRankStack2[nStackPtr[istk]] );
     693                 :             :                  */
     694                 :             :                 /*  the following commented out statement is not needed here. */
     695                 :             :                 /*  parity2 = parity_of_mapped_atom2( pCG, at_from2, at_to2, at, &EN2[0],
     696                 :             :                                                      nCanonRankFrom, pRankStack1[nStackPtr[istk]],
     697                 :             :                                                      pRankStack2[nStackPtr[istk]] );
     698                 :             :                  */
     699         [ #  # ]:           0 :                 if (!parity1)
     700                 :             :                 {
     701                 :           0 :                     return CT_STEREOCOUNT_ERR; /*  program error */ /*   <BRKPT> */
     702                 :             :                 }
     703         [ #  # ]:           0 :                 num1 = parity1 > 0 ? 1 : 2; /*  parity < 0 means additional mapping is needed to set parity */
     704                 :             : 
     705                 :             :                 /*  --- try all possible mappings of the stereo bond ending atoms' neighbors --- */
     706                 :           0 :                 at_rank_canon_n1 = 0;
     707                 :             :                 /* djb-rwth: removing redundant code */
     708         [ #  # ]:           0 :                 for (i = 0; i < num1; i++)
     709                 :             :                 {
     710                 :           0 :                     int at_from_n1, at_to_n1, at_no_n1_num_success = 0;
     711                 :           0 :                     istk2 = istk;
     712         [ #  # ]:           0 :                     if (num1 == 2)
     713                 :             :                     {
     714                 :           0 :                         at_rank_canon_n1 = nCanonRankFrom[EN1[0].from_at];
     715                 :             :                         /*  an additional neighbor mapping is necessary; */
     716                 :             :                         /*  we need to map only one at_from1 neighbor to make all neighbors have different ranks */
     717                 :             : 
     718                 :           0 :                         at_from_n1 = EN1[0].from_at;
     719                 :           0 :                         at_to_n1 = EN1[0].to_at[i];
     720                 :             : 
     721   [ #  #  #  # ]:           0 :                         if (tpos1 < CurTreeGetPos( cur_tree ) &&
     722         [ #  # ]:           0 :                              1 == CurTreeIsLastRank( cur_tree, at_rank_canon_n1 ) &&
     723                 :           0 :                              1 == CurTreeIsLastAtomEqu( cur_tree, at_to_n1, nSymmStereo ))
     724                 :           0 :                             continue;
     725                 :             :                         /*
     726                 :             :                         if ( nSymmStereo && !pCS->bFirstCT ) {
     727                 :             :                             if ( i && nSymmStereo[at_to_n1] == nSymmStereo[(int)EN1[0].to_at[0]] ) {
     728                 :             :                                 continue; // do not test stereo equivalent atoms except the first one
     729                 :             :                             }
     730                 :             :                         }
     731                 :             :                         */
     732                 :             :                         /*  neighbors are tied. Untie them by breaking a tie on ONE of them. */
     733                 :           0 :                         ret1 = map_an_atom2( pCG, num_at_tg, num_max, at_from_n1, at_to_n1,
     734                 :           0 :                                             nTempRank, nNumMappedRanks[istk2], &nNumMappedRanks[istk2 + 1], pCS,
     735                 :           0 :                                             NeighList, pRankStack1 + nStackPtr[istk2], pRankStack2 + nStackPtr[istk2],
     736                 :             :                                             &bAddStack );
     737   [ #  #  #  # ]:           0 :                         if (RETURNED_ERROR( ret1 ))
     738                 :             :                         {
     739                 :           0 :                             return ret1; /*  program error */ /*   <BRKPT> */
     740                 :             :                         }
     741                 :           0 :                         nStackPtr[istk2 + 1] = nStackPtr[istk2] + bAddStack;
     742                 :           0 :                         istk2++;  /*  <= 3 */
     743                 :             :                         /*  debug */
     744         [ #  # ]:           0 :                         if (istk2 >= SB_DEPTH)
     745                 :             :                         {
     746                 :           0 :                             return CT_OVERFLOW; /*  program error */ /*   <BRKPT> */
     747                 :             :                         }
     748         [ #  # ]:           0 :                         if (bAddStack)
     749                 :             :                         {
     750   [ #  #  #  # ]:           0 :                             if (tpos1 == CurTreeGetPos( cur_tree ) ||
     751                 :           0 :                                  0 == CurTreeIsLastRank( cur_tree, at_rank_canon_n1 ))
     752                 :             :                             {
     753                 :           0 :                                 CurTreeAddRank( cur_tree, at_rank_canon_n1 );
     754                 :             :                             }
     755                 :           0 :                             CurTreeAddAtom( cur_tree, at_to_n1 );
     756                 :             :                         }
     757                 :             : 
     758                 :             : 
     759                 :             :                         /*  now that all at_from1 neighbors have been mapped the parity must be defined */
     760                 :           0 :                         parity1 = parity_of_mapped_half_bond( at_from1, at_to1, at_from2, at_to2, at, &EN1[1],
     761                 :           0 :                            nCanonRankFrom, pRankStack1[nStackPtr[istk2]], pRankStack2[nStackPtr[istk2]] );
     762         [ #  # ]:           0 :                         if (parity1 <= 0)
     763                 :           0 :                             return CT_STEREOCOUNT_ERR;  /*  program error */ /*   <BRKPT> */
     764                 :             :                     }
     765                 :             :                     else
     766                 :             :                     {
     767                 :           0 :                         nNumMappedRanks[istk2 + 1] = nNumMappedRanks[istk2];
     768                 :           0 :                         nStackPtr[istk2 + 1] = nStackPtr[istk2];
     769                 :           0 :                         istk2++;  /*  <= 3 */
     770                 :             :                     }
     771                 :             : 
     772                 :             :                     /*  check if at_from2/at_to2 half-bond has neighbors with equal mapping ranks */
     773                 :           0 :                     parity2 = parity_of_mapped_half_bond( at_from2, at_to2, at_from1, at_to1, at, &EN2[0],
     774                 :           0 :                            nCanonRankFrom, pRankStack1[nStackPtr[istk2]], pRankStack2[nStackPtr[istk2]] );
     775         [ #  # ]:           0 :                     if (!parity2)
     776                 :             :                     {
     777                 :           0 :                         return CT_STEREOCOUNT_ERR; /*  program error */ /*   <BRKPT> */
     778                 :             :                     }
     779         [ #  # ]:           0 :                     num2 = parity2 > 0 ? 1 : 2;
     780                 :           0 :                     at_rank_canon_n2 = 0;
     781         [ #  # ]:           0 :                     for (j = 0; j < num2; j++)
     782                 :             :                     {
     783                 :           0 :                         int at_from_n2, at_to_n2 = 0;
     784                 :           0 :                         istk3 = istk2;
     785         [ #  # ]:           0 :                         if (num2 == 2)
     786                 :             :                         {
     787                 :           0 :                             at_rank_canon_n2 = nCanonRankFrom[EN2[0].from_at];
     788                 :             :                             /*  we need to map only one at_from2 neighbor to make its neighbors have different ranks */
     789                 :           0 :                             at_from_n2 = EN2[0].from_at;
     790                 :           0 :                             at_to_n2 = EN2[0].to_at[j];
     791                 :             : 
     792   [ #  #  #  # ]:           0 :                             if (tpos1 < CurTreeGetPos( cur_tree ) &&
     793         [ #  # ]:           0 :                                  1 == CurTreeIsLastRank( cur_tree, at_rank_canon_n2 ) &&
     794                 :           0 :                                  1 == CurTreeIsLastAtomEqu( cur_tree, at_to_n2, nSymmStereo ))
     795                 :           0 :                                 continue;
     796                 :             : 
     797                 :             :                             /*
     798                 :             :                             if ( nSymmStereo && !pCS->bFirstCT ) {
     799                 :             :                                 if ( j && nSymmStereo[at_to_n2] == nSymmStereo[(int)EN2[0].to_at[0]] ) {
     800                 :             :                                     continue; // do not test stereo equivalent atoms except the first one
     801                 :             :                                 }
     802                 :             :                             }
     803                 :             :                             */
     804                 :             :                             /*  neighbors are tied. Untie them by breaking a tie on ONE of them. */
     805                 :           0 :                             ret1 = map_an_atom2( pCG, num_at_tg, num_max, at_from_n2, at_to_n2,
     806                 :           0 :                                                 nTempRank, nNumMappedRanks[istk3], &nNumMappedRanks[istk3 + 1], pCS,
     807                 :           0 :                                                 NeighList, pRankStack1 + nStackPtr[istk3],
     808                 :           0 :                                                 pRankStack2 + nStackPtr[istk3],
     809                 :             :                                                 &bAddStack );
     810   [ #  #  #  # ]:           0 :                             if (RETURNED_ERROR( ret1 ))
     811                 :             :                             {
     812                 :           0 :                                 return ret1; /*  program error */
     813                 :             :                             }
     814                 :           0 :                             nStackPtr[istk3 + 1] = nStackPtr[istk3] + bAddStack;
     815                 :           0 :                             istk3++;  /*  <= 4 */
     816                 :             : 
     817         [ #  # ]:           0 :                             if (bAddStack)
     818                 :             :                             {
     819   [ #  #  #  # ]:           0 :                                 if (tpos1 == CurTreeGetPos( cur_tree ) ||
     820                 :           0 :                                      0 == CurTreeIsLastRank( cur_tree, at_rank_canon_n2 ))
     821                 :             :                                 {
     822                 :           0 :                                     CurTreeAddRank( cur_tree, at_rank_canon_n2 );
     823                 :             :                                 }
     824                 :           0 :                                 CurTreeAddAtom( cur_tree, at_to_n2 );
     825                 :             :                             }
     826                 :             : 
     827                 :           0 :                             parity2 = parity_of_mapped_half_bond( at_from2, at_to2, at_from1, at_to1, at, &EN2[1],
     828                 :           0 :                                      nCanonRankFrom, pRankStack1[nStackPtr[istk3]], pRankStack2[nStackPtr[istk3]] );
     829         [ #  # ]:           0 :                             if (parity2 <= 0)
     830                 :             :                             {
     831                 :           0 :                                 return CT_STEREOCOUNT_ERR;  /*  program error */ /*   <BRKPT> */
     832                 :             :                             }
     833                 :             :                         }
     834                 :             :                         else
     835                 :             :                         {
     836                 :             :                                              /*  no additional mapping is needed to set atom's parity */
     837                 :           0 :                             nNumMappedRanks[istk3 + 1] = nNumMappedRanks[istk3];
     838                 :           0 :                             nStackPtr[istk3 + 1] = nStackPtr[istk3];
     839                 :           0 :                             istk3++;  /*  <= 4 */
     840                 :             :                         }
     841                 :             : 
     842                 :             :                         /*******************************************************************
     843                 :             :                          * at this point the stereo bond is fully mapped to find its parity
     844                 :             :                          *******************************************************************/
     845                 :             : 
     846   [ #  #  #  # ]:           0 :                         if (parity1 <= 0 || parity2 <= 0)
     847                 :             :                         {
     848                 :           0 :                             return CT_STEREOCOUNT_ERR; /*  program error */ /*   <BRKPT> */
     849                 :             :                         }
     850                 :             : 
     851                 :             :                         /*  find current bond parity  AB_PARITY_ODD */
     852   [ #  #  #  #  :           0 :                         if (ATOM_PARITY_WELL_DEF( parity1 ) && ATOM_PARITY_WELL_DEF( parity2 ))
             #  #  #  # ]
     853                 :             :                         {
     854                 :           0 :                             bond_parity = 2 - ( parity1 + parity2 ) % 2;
     855                 :             :                         }
     856                 :             :                         else
     857                 :             :                         {
     858                 :           0 :                             bond_parity = inchi_max( parity1, parity2 );
     859                 :             :                         }
     860   [ #  #  #  #  :           0 :                         if (ATOM_PARITY_WELL_DEF( bond_parity ) && at[at_to1].stereo_bond_z_prod[j2] < 0)
                   #  # ]
     861                 :           0 :                             bond_parity = 2 - ( bond_parity + 1 ) % 2; /*  invert the bond parity */
     862                 :             : 
     863                 :             : 
     864                 :             :                         /********************************************************
     865                 :             :                          * make a decision whether to accept the current mapping
     866                 :             :                          */
     867                 :           0 :                         c = CompareLinCtStereoDoubleToValues( pCS->LinearCTStereoDble + nNumMappedBonds,
     868                 :           0 :                                                   at_rank_canon1, at_rank_canon2, (U_CHAR) bond_parity );
     869   [ #  #  #  # ]:           0 :                         if (sb_parity_calc != bond_parity ||
     870         [ #  # ]:           0 :                              (c < 0 && !pCS->bStereoIsBetter)) /* djb-rwth: addressing LLVM warning */
     871                 :             :                         {
     872                 :             :                             /*  reject */
     873                 :           0 :                             pCS->lNumRejectedCT++;
     874                 :             :                             /*  remove failed atom2 from the tree */
     875   [ #  #  #  # ]:           0 :                             if (tpos1 < CurTreeGetPos( cur_tree ) &&
     876                 :           0 :                                  1 == CurTreeIsLastRank( cur_tree, at_rank_canon_n2 ))
     877                 :             :                             {
     878                 :           0 :                                 CurTreeRemoveIfLastAtom( cur_tree, at_to_n2 );
     879                 :           0 :                                 CurTreeRemoveLastRankIfNoAtoms( cur_tree );
     880                 :             :                             }
     881                 :           0 :                             continue;  /*  Reject: not a minimal CT. */
     882                 :             :                         }
     883                 :             :                         else
     884                 :             :                         {
     885                 :             : 
     886                 :             :                                             /*  try to accept */
     887                 :             : 
     888   [ #  #  #  # ]:           0 :                             if (c > 0 && !pCS->bStereoIsBetter)
     889                 :             :                             {
     890                 :             :                                 /*  bond_parity is less than the previusly found */
     891                 :           0 :                                 pCS->bStereoIsBetter = bStereoIsBetterWasSetHere = 1;
     892                 :           0 :                                 prevBond2 = pCS->LinearCTStereoDble[nNumMappedBonds];
     893                 :             :                             }
     894                 :             :                             /*  accept */
     895                 :           0 :                             pCS->LinearCTStereoDble[nNumMappedBonds].at_num1 = at_rank_canon1;
     896                 :           0 :                             pCS->LinearCTStereoDble[nNumMappedBonds].at_num2 = at_rank_canon2;
     897                 :           0 :                             pCS->LinearCTStereoDble[nNumMappedBonds].parity = bond_parity;
     898                 :             :                             /*  recursive call */
     899                 :           0 :                             pCS->bRankUsedForStereo[at_from1] ++;
     900                 :           0 :                             pCS->bRankUsedForStereo[at_from2] ++;
     901                 :           0 :                             pCS->bAtomUsedForStereo[at_to1] --;
     902                 :           0 :                             pCS->bAtomUsedForStereo[at_to2] --;
     903                 :           0 :                             ret2 = map_stereo_bonds4( ic, pCG, at, num_atoms, num_at_tg, num_max, bAllene, nCanonRankFrom, nAtomNumberCanonFrom, nCanonRankTo,
     904                 :           0 :                                                       nSymmRank, pRankStack1 + nStackPtr[istk3], pRankStack2 + nStackPtr[istk3],
     905                 :             :                                                       nTempRank, nNumMappedRanks[istk3], nSymmStereo, NeighList,
     906                 :             :                                                       pCS, cur_tree, nNumMappedBonds + 1,
     907                 :             :                                                       vABParityUnknown );
     908                 :           0 :                             pCS->bRankUsedForStereo[at_from1] --;
     909                 :           0 :                             pCS->bRankUsedForStereo[at_from2] --;
     910                 :           0 :                             pCS->bAtomUsedForStereo[at_to1] ++;
     911                 :           0 :                             pCS->bAtomUsedForStereo[at_to2] ++;
     912         [ #  # ]:           0 :                             if (ret2 == 4)
     913                 :             :                             {
     914         [ #  # ]:           0 :                                 if (nNumMappedBonds)
     915                 :             :                                 {
     916                 :           0 :                                     return ret2;
     917                 :             :                                 }
     918                 :             :                                 else
     919                 :             :                                 {
     920                 :           0 :                                     pCS->bFirstCT = 1;
     921                 :           0 :                                     goto total_restart;
     922                 :             :                                 }
     923                 :             :                             }
     924   [ #  #  #  # ]:           0 :                             if (RETURNED_ERROR( ret2 ))
     925                 :             :                             {
     926                 :           0 :                                 return ret2; /*  program error */ /* djb-rwth: fixing coverity ID #499569 */
     927                 :             :                             }
     928         [ #  # ]:           0 :                             if (ret2 > 0)
     929                 :             :                             {
     930                 :           0 :                                 nTotSuccess |= 1;
     931                 :           0 :                                 nNumAtTo1Success++;
     932   [ #  #  #  # ]:           0 :                                 if (bStereoIsBetterWasSetHere || ( ret2 & 2 ))
     933                 :             :                                 {
     934                 :           0 :                                     CurTreeKeepLastAtomsOnly( cur_tree, tpos1, 1 );  /*  start over */
     935                 :           0 :                                     nTotSuccess |= 2; /*  Obtained a smaller CT */
     936                 :             :                                 }
     937                 :           0 :                                 at_no_n1_num_success++;
     938                 :             :                             }
     939                 :             :                             else
     940                 :             :                             {
     941         [ #  # ]:           0 :                                 if (bStereoIsBetterWasSetHere)
     942                 :             :                                 {  /*  rollback */
     943                 :           0 :                                     pCS->bStereoIsBetter = 0;
     944                 :           0 :                                     pCS->LinearCTStereoDble[nNumMappedBonds] = prevBond2;
     945                 :             :                                 }
     946   [ #  #  #  # ]:           0 :                                 if (tpos1 < CurTreeGetPos( cur_tree ) &&
     947                 :           0 :                                      1 == CurTreeIsLastRank( cur_tree, at_rank_canon_n2 ))
     948                 :             :                                 {
     949                 :           0 :                                     CurTreeRemoveIfLastAtom( cur_tree, at_to_n2 );
     950                 :           0 :                                     CurTreeRemoveLastRankIfNoAtoms( cur_tree );
     951                 :             :                                 }
     952                 :             :                             }
     953                 :           0 :                             bStereoIsBetterWasSetHere = 0;
     954                 :             :                         }
     955                 :             :                     } /*  end choices in mapping neighbors of the 2nd half-bond */
     956   [ #  #  #  # ]:           0 :                     if (tpos1 < CurTreeGetPos( cur_tree ) &&
     957                 :           0 :                          1 == CurTreeIsLastRank( cur_tree, at_rank_canon_n2 ))
     958                 :             :                     {
     959                 :           0 :                         CurTreeRemoveLastRank( cur_tree );
     960                 :             :                     }
     961                 :             :                     /* added 2006-07-20 */
     962   [ #  #  #  #  :           0 :                     if (!at_no_n1_num_success && tpos1 < CurTreeGetPos( cur_tree ) &&
                   #  # ]
     963                 :           0 :                         1 == CurTreeIsLastRank( cur_tree, at_rank_canon_n1 ))
     964                 :             :                     {
     965                 :           0 :                         CurTreeRemoveIfLastAtom( cur_tree, at_to_n1 );
     966                 :             :                     }
     967                 :             :                 } /*  end choices in mapping neighbors of the 1st half-bond */
     968   [ #  #  #  # ]:           0 :                 if (tpos1 < CurTreeGetPos( cur_tree ) &&
     969                 :           0 :                       1 == CurTreeIsLastRank( cur_tree, at_rank_canon_n1 ))
     970                 :             :                 {
     971                 :           0 :                     CurTreeRemoveLastRank( cur_tree );
     972                 :             :                 }
     973                 :             :             } /*  end of choices in mapping at_from2 */
     974   [ #  #  #  # ]:           0 :             if (tpos1 < CurTreeGetPos( cur_tree ) &&
     975                 :           0 :                  1 == CurTreeIsLastRank( cur_tree, at_rank_canon2 ))
     976                 :             :             {
     977                 :           0 :                 CurTreeRemoveLastRank( cur_tree );
     978                 :             :             }
     979         [ #  # ]:           0 :             if (!nNumAtTo1Success)
     980                 :             :             {
     981   [ #  #  #  # ]:           0 :                 if (tpos1 < CurTreeGetPos( cur_tree ) &&
     982                 :           0 :                      1 == CurTreeIsLastRank( cur_tree, at_rank_canon1 ))
     983                 :             :                 {
     984                 :           0 :                     CurTreeRemoveIfLastAtom( cur_tree, at_to1 );
     985                 :           0 :                     CurTreeRemoveLastRankIfNoAtoms( cur_tree );
     986                 :             :                 }
     987                 :             :             }
     988         [ #  # ]:           0 :             if (bAllParitiesIdentical /*&& !nSymmStereo*/)
     989                 :             :             {
     990                 :           0 :                 break;
     991                 :             :             }
     992                 :             :         } /*  end of choices in mapping at_from1 */
     993                 :             : 
     994   [ #  #  #  # ]:           0 :         if (tpos1 < CurTreeGetPos( cur_tree ) &&
     995                 :           0 :              1 == CurTreeIsLastRank( cur_tree, at_rank_canon1 ))
     996                 :             :         {
     997                 :           0 :             CurTreeRemoveLastRank( cur_tree );
     998                 :             :         }
     999                 :             :         else
    1000                 :             :         {
    1001                 :             :             /*  CurTree consistecy check (debug only) */
    1002         [ #  # ]:           0 :             if (tpos1 != CurTreeGetPos( cur_tree ))
    1003                 :             :             {
    1004                 :           0 :                 return CT_STEREOCOUNT_ERR;  /*   <BRKPT> */
    1005                 :             :             }
    1006                 :             :         }
    1007                 :             : 
    1008   [ #  #  #  # ]:           0 :         if (!nTotSuccess || stereo_bond_parity == sb_parity_calc)
    1009                 :             :         {
    1010                 :           0 :             goto repeat_all; /*  repeat with next parity if no success or with the same parity, now known */
    1011                 :             :         }
    1012                 :             : 
    1013                 :             :         /*  Previously the control flow never came here... */
    1014         [ #  # ]:           0 :         if (!nTotSuccess)
    1015                 :             :         {
    1016                 :           0 :             pCS->LinearCTStereoDble[nNumMappedBonds] = prevBond;
    1017                 :           0 :             CurTreeSetPos( cur_tree, tpos1 );
    1018                 :             :             /*  Occurs when atoms are not really equvalent ( -O= without positive charge in "aromatic" ring) */
    1019                 :           0 :             return 0; /* Happens for ID=92439,100318,100319 when EXCL_ALL_AROM_BOND_PARITY=0 and
    1020                 :             :                        * nNumChoices=0.
    1021                 :             :                        * Results from impossible previous mapping of symmetric relatively
    1022                 :             :                        * to a central ring aromatic circles while central ring is not symmetrical due to
    1023                 :             :                        * alternate bonds (in the central ring number of pi-electrons, atoms and bonds
    1024                 :             :                        * are symmetrical).
    1025                 :             :                        * Does not happen when alternate bonds of the central ring
    1026                 :             :                        * are treated as aromatic by attaching a (+) charge to the oxygen.
    1027                 :             :                        */
    1028                 :             :         }
    1029                 :             :     }
    1030                 :             :     else
    1031                 :             :     {
    1032                 :             :         int ret;
    1033                 :             : 
    1034         [ +  - ]:         109 :         if (!nNumMappedBonds)
    1035                 :             :         {
    1036                 :         109 :             pCS->bStereoIsBetter = 0;  /*  the first stereo feature in the canonical CT has not been processed yet */
    1037                 :             :         }
    1038                 :             : 
    1039         [ -  + ]:         109 :         if (nNumMappedBonds < pCS->nLenLinearCTStereoDble)
    1040                 :             :         {
    1041                 :           0 :             prevBond = pCS->LinearCTStereoDble[nNumMappedBonds];
    1042                 :             :         }
    1043                 :             : 
    1044                 :             :         /*deep_map_stereo_atoms4=0;*/
    1045                 :             : 
    1046                 :             :         /*  all stereo bonds have been mapped; now start processing stereo atoms... */
    1047                 :         109 :         ret = map_stereo_atoms4( ic, pCG, at, num_atoms, num_at_tg, num_max, nCanonRankFrom, nAtomNumberCanonFrom, nCanonRankTo,
    1048                 :             :                         nSymmRank, pRankStack1, pRankStack2, nTempRank, nNumMappedRanksInput,
    1049                 :             :                         nSymmStereo, NeighList, pCS, cur_tree, 0, vABParityUnknown );
    1050                 :             : 
    1051         [ -  + ]:         109 :         if (ret == 4)
    1052                 :             :         {
    1053         [ #  # ]:           0 :             if (nNumMappedBonds)
    1054                 :             :             {
    1055                 :           0 :                 return ret;
    1056                 :             :             }
    1057                 :             :             else
    1058                 :             :             {
    1059                 :           0 :                 pCS->bFirstCT = 1;
    1060                 :           0 :                 goto total_restart;
    1061                 :             :             }
    1062                 :             :         }
    1063   [ +  -  -  + ]:         109 :         if (RETURNED_ERROR( ret ))
    1064                 :             :         {
    1065         [ #  # ]:           0 :             if (ret == CT_TIMEOUT_ERR)
    1066                 :           0 :                 return ret;
    1067                 :             :             else
    1068                 :           0 :                 return ret; /*  program error */
    1069                 :             :         }
    1070         [ +  - ]:         109 :         if (ret > 0)
    1071                 :             :         {
    1072                 :         109 :             nTotSuccess |= 1;
    1073         [ +  + ]:         109 :             if (ret & 2)
    1074                 :             :             {
    1075                 :          41 :                 CurTreeKeepLastAtomsOnly( cur_tree, tpos1, 1 );  /*  start over */
    1076                 :          41 :                 nTotSuccess |= 2; /*  Obtained a smaller CT */
    1077                 :             :             }
    1078                 :             :         }
    1079                 :             :     }
    1080   [ -  +  -  - ]:         109 :     if (!nTotSuccess && pCS->nLenLinearCTStereoDble &&
    1081         [ #  # ]:           0 :          nNumMappedBonds < pCS->nLenLinearCTStereoDble)
    1082                 :             :     {
    1083                 :           0 :         pCS->LinearCTStereoDble[nNumMappedBonds] = prevBond;
    1084                 :             :     }
    1085                 :             : 
    1086                 :         109 :     return nTotSuccess;  /*  ok */
    1087                 :             : }
    1088                 :             : 
    1089                 :             : 
    1090                 :             : /****************************************************************************/
    1091                 :         476 : int map_stereo_atoms4( struct tagINCHI_CLOCK *ic,
    1092                 :             :                        CANON_GLOBALS *pCG,
    1093                 :             :                        sp_ATOM *at,
    1094                 :             :                        int num_atoms,
    1095                 :             :                        int num_at_tg,
    1096                 :             :                        int num_max,
    1097                 :             :                        const AT_RANK *nCanonRankFrom,
    1098                 :             :                        const AT_RANK *nAtomNumberCanonFrom,
    1099                 :             :                        AT_RANK *nCanonRankTo, /*  canonical numbering to be mapped */
    1100                 :             :                        const AT_RANK *nSymmRank,
    1101                 :             :                        AT_RANK **pRankStack1/*from*/,
    1102                 :             :                        AT_RANK **pRankStack2/*to*/,
    1103                 :             :                        AT_RANK *nTempRank,
    1104                 :             :                        int nNumMappedRanksInput,
    1105                 :             :                        AT_RANK *nSymmStereo,
    1106                 :             :                        NEIGH_LIST *NeighList,
    1107                 :             :                        CANON_STAT *pCS,
    1108                 :             :                        CUR_TREE *cur_tree,
    1109                 :             :                        int nNumMappedAtoms,
    1110                 :             :                        int vABParityUnknown )
    1111                 :             : {
    1112                 :             :     /*
    1113                 :             :      *   Do not check whether "from" atoms have any stereo features.
    1114                 :             :      */
    1115                 :         476 :     int nTotSuccess = 0;
    1116                 :             :     AT_STEREO_CARB prevAtom;
    1117                 :             :     int tpos1;
    1118                 :             : 
    1119                 :         476 :     memset( &prevAtom, 0, sizeof( prevAtom ) );
    1120                 :             : 
    1121                 :         476 :     tpos1 = CurTreeGetPos( cur_tree );
    1122                 :             : 
    1123         [ +  + ]:         476 :     if (nNumMappedAtoms < pCS->nLenLinearCTStereoCarb)
    1124                 :             :     {
    1125                 :             :         /* AT_RANK *nRankFrom=*pRankStack1++,  AT_RANK *nAtomNumberFrom=pRankStack1++; */
    1126                 :             :         /* AT_RANK *nRankTo  =*pRankStack2++,  AT_RANK *nAtomNumberTo  =pRankStack2++; */
    1127                 :             :         int j1, at_from1, at_to1, /*at_from2, at_to2,*/ iMax, lvl, bStereoIsBetterWasSetHere;
    1128                 :         367 :         int istk, bAddStack, nNumAtTo1Success, c, bFirstTime = 1, bAllParitiesIdentical; /* djb-rwth: removing redundant variables */
    1129                 :             :         EQ_NEIGH EN[5], *pEN;
    1130                 :             :         int nStackPtr[5], nMappedRanks[5], j[5], *nSP, *nMR, bLastLvlFailed;
    1131                 :             : 
    1132                 :             :         AT_RANK at_rank_canon1, cr[5], at_to[5];
    1133                 :         367 :         AT_RANK canon_rank1_min = 0;
    1134                 :             :         int at_rank1; /*  rank for mapping */
    1135                 :             :         int nNumChoices, nNumUnkn, nNumUndf, nNumWorse, nNumBest, nNumCalc;
    1136                 :         367 :         int stereo_center_parity = 0, sb_parity_calc, pass; /* djb-rwth: removing redundant variable */
    1137                 :             :         AT_STEREO_CARB prevAtom2;
    1138                 :             : 
    1139                 :         367 :         prevAtom = pCS->LinearCTStereoCarb[nNumMappedAtoms]; /*  save to restore in case of failure */
    1140         [ +  + ]:         367 :         at_rank_canon1 = nNumMappedAtoms ? pCS->LinearCTStereoCarb[nNumMappedAtoms - 1].at_num : 0;
    1141                 :             : 
    1142                 :         367 :         goto bypass_next_canon_rank_check;
    1143                 :             : 
    1144                 :           0 :     next_canon_rank:
    1145                 :             : 
    1146         [ #  # ]:           0 :         if (!pCS->bStereoIsBetter /*??? && !pCS->bFirstCT ???*/ &&
    1147         [ #  # ]:           0 :               at_rank_canon1 >= pCS->LinearCTStereoCarb[nNumMappedAtoms].at_num)
    1148                 :             :         {
    1149                 :             :             /*  cannot find next available canonical number */
    1150         [ #  # ]:           0 :             if (!nTotSuccess)
    1151                 :             :             {
    1152                 :           0 :                 pCS->LinearCTStereoCarb[nNumMappedAtoms] = prevAtom; /*  restore because of failure */
    1153                 :             :             }
    1154                 :           0 :             CurTreeSetPos( cur_tree, tpos1 );
    1155                 :           0 :             return nTotSuccess;
    1156                 :             :         }
    1157                 :             : 
    1158                 :           0 : bypass_next_canon_rank_check:
    1159                 :             : 
    1160                 :         367 :         CurTreeSetPos( cur_tree, tpos1 );
    1161                 :             : 
    1162                 :             :         /*  find next available canon. number for a stereogenic atom */
    1163         [ +  - ]:         367 :         if (!Next_SC_At_CanonRank2( &at_rank_canon1, &canon_rank1_min, &bFirstTime,
    1164                 :             :             pCS->bAtomUsedForStereo, pRankStack1, pRankStack2,
    1165                 :         367 :             nAtomNumberCanonFrom, num_atoms ) ||
    1166         [ +  + ]:         367 :               (!pCS->bStereoIsBetter &&
    1167         [ -  + ]:         286 :               at_rank_canon1 > pCS->LinearCTStereoCarb[nNumMappedAtoms].at_num)) /* djb-rwth: addressing LLVM warning */
    1168                 :             :         {
    1169                 :             :             /*  cannot find next available canonical number */
    1170         [ #  # ]:           0 :             if (!nTotSuccess)
    1171                 :             :             {
    1172                 :           0 :                 pCS->LinearCTStereoCarb[nNumMappedAtoms] = prevAtom; /*  restore because of failure */
    1173                 :             :             }
    1174                 :           0 :             return nTotSuccess;
    1175                 :             :         }
    1176                 :             : 
    1177                 :         367 :         nNumChoices = 0;
    1178                 :         367 :         nNumUnkn = 0;
    1179                 :         367 :         nNumUndf = 0;
    1180                 :         367 :         nNumBest = 0;
    1181                 :         367 :         nNumWorse = 0;
    1182                 :         367 :         nNumCalc = 0;
    1183                 :         367 :         pass = 0;
    1184                 :             :         /* djb-rwth: removing redundant code */
    1185                 :             : 
    1186                 :             :         /*  get mapping rank for the canon. number */
    1187                 :         367 :         at_rank1 = pRankStack1[0][at_from1 = (int) nAtomNumberCanonFrom[at_rank_canon1 - 1]];
    1188                 :         367 :         iMax = at_rank1 - 1;
    1189                 :             :         /*  for debug only */
    1190         [ -  + ]:         367 :         if (at_rank1 != pRankStack2[0][pRankStack2[1][at_rank1 - 1]])
    1191                 :             :         {
    1192                 :           0 :             return CT_STEREOCOUNT_ERR; /*  program error */ /*   <BRKPT> */
    1193                 :             :         }
    1194                 :             : 
    1195                 :             :         /*  count special parities of the not mapped yet "to" atoms */
    1196   [ +  -  +  + ]:         738 :         for (j1 = 0; j1 <= iMax && at_rank1 == pRankStack2[0][at_to1 = pRankStack2[1][iMax - j1]]; j1++)
    1197                 :             :         {
    1198   [ +  -  +  - ]:         371 :             if (!at[at_to1].stereo_bond_neighbor[0] && pCS->bAtomUsedForStereo[at_to1] == STEREO_AT_MARK)
    1199                 :             :             {
    1200                 :         371 :                 int no_choice = 0;
    1201                 :         371 :                 stereo_center_parity = PARITY_VAL( at[at_to1].stereo_atom_parity );
    1202   [ +  -  +  +  :         371 :                 switch (stereo_center_parity)
                -  -  - ]
    1203                 :             :                 {
    1204                 :             : 
    1205                 :          33 :                     case AB_PARITY_UNDF: nNumUndf++; break; /*  4 */
    1206                 :             : 
    1207                 :           0 :                     case AB_PARITY_UNKN: nNumUnkn++;
    1208                 :           0 :                         break; /*  3 */
    1209                 :             : 
    1210                 :         169 :                     case BEST_PARITY:    nNumBest++; break; /*  1 */
    1211                 :         169 :                     case WORSE_PARITY:   nNumWorse++; break; /*  2 */
    1212                 :           0 :                     case AB_PARITY_CALC: nNumCalc++; break;
    1213                 :           0 :                     case AB_PARITY_NONE: no_choice++; break; /*  0 */
    1214                 :             :                 }
    1215                 :         371 :                 nNumChoices += !no_choice;
    1216                 :             :             }
    1217                 :             :         }
    1218                 :             : 
    1219         [ -  + ]:         367 :         if (nNumChoices != nNumCalc + nNumUndf + nNumUnkn + nNumBest + nNumWorse)
    1220                 :             :         {
    1221                 :           0 :             return CT_STEREOCOUNT_ERR; /*  program error */ /*   <BRKPT> */
    1222                 :             :         }
    1223         [ -  + ]:         367 :         if (!nNumChoices)
    1224                 :             :         {
    1225                 :           0 :             goto next_canon_rank;
    1226                 :             :         }
    1227                 :             :         /*  Determine the first parity to search */
    1228                 :         367 :         sb_parity_calc = ( nNumCalc > 0 ) ? BEST_PARITY : 0;
    1229                 :             : 
    1230                 :             :         /*  ==============================================================
    1231                 :             :             Search sequence:           sb_parity_calc    stereo_center_parity
    1232                 :             :             ==============================================================
    1233                 :             :             BEST_PARITY   (calc)       BEST_PARITY     BEST_PARITY
    1234                 :             :             BEST_PARITY   (known)      BEST_PARITY     WORSE_PARITY  or 0
    1235                 :             :             WORSE_PARITY  (calc)       WORSE_PARITY    WORSE_PARITY
    1236                 :             :             WORSE_PARITY  (known)      WORSE_PARITY    0
    1237                 :             :             AB_PARITY_UNKN(known)      AB_PARITY_UNKN  0
    1238                 :             :             AB_PARITY_UNDF(known)      AB_PARITY_UNDF  0
    1239                 :             : 
    1240                 :             :             if (sb_parity_calc==stereo_center_parity) then "calc" else "known"
    1241                 :             :          */
    1242                 :             : 
    1243                 :         367 :     repeat_all:
    1244                 :             : 
    1245         [ +  - ]:         367 :         if (!pass++)
    1246                 :             :         {
    1247                 :             :             /*  select the smallest parity to search */
    1248         [ -  + ]:         367 :             if (sb_parity_calc)
    1249                 :             :             {
    1250                 :           0 :                 stereo_center_parity = BEST_PARITY;
    1251                 :             :             }
    1252                 :             :             else
    1253                 :             :             {
    1254         [ +  + ]:         567 :                 stereo_center_parity = nNumBest ? BEST_PARITY :
    1255         [ +  + ]:         233 :                     nNumWorse ? WORSE_PARITY :
    1256         [ +  - ]:          66 :                     nNumUnkn ? AB_PARITY_UNKN :
    1257         [ +  - ]:          33 :                     nNumUndf ? AB_PARITY_UNDF : AB_PARITY_NONE;
    1258                 :             :             }
    1259                 :             :         }
    1260                 :             :         else
    1261                 :             :         {
    1262                 :             :             /* djb-rwth: removing redundant code */
    1263                 :           0 :             j1 = NextStereoParity2Test( &stereo_center_parity, &sb_parity_calc,
    1264                 :             :                                      nNumBest, nNumWorse, nNumUnkn, nNumUndf, nNumCalc,
    1265                 :             :                                      vABParityUnknown );
    1266      [ #  #  # ]:           0 :             switch (j1)
    1267                 :             :             {
    1268                 :           0 :                 case 0:
    1269                 :           0 :                     break; /* obtained next parity to test */
    1270                 :           0 :                 case 1:
    1271                 :           0 :                     goto next_canon_rank;
    1272                 :           0 :                 default:
    1273                 :           0 :                     return j1; /* program error */
    1274                 :             :             }
    1275                 :             :         }
    1276                 :             : 
    1277         [ -  + ]:         367 :         if (stereo_center_parity == AB_PARITY_NONE)
    1278                 :             :         {
    1279                 :             :             /*  error? */
    1280                 :           0 :             return CT_STEREOCOUNT_ERR;                  /*   <BRKPT> */
    1281                 :             :         }
    1282                 :             : 
    1283                 :             :         /*  check if the new requested parity is small enough */
    1284         [ +  + ]:         367 :         if (!pCS->bStereoIsBetter)
    1285                 :             :         {
    1286                 :         286 :             c = CompareLinCtStereoAtomToValues( nTotSuccess ? pCS->LinearCTStereoCarb + nNumMappedAtoms : &prevAtom,
    1287         [ -  + ]:         286 :                               at_rank_canon1, (U_CHAR) stereo_center_parity );
    1288         [ -  + ]:         286 :             if (c < 0)
    1289                 :             :             {
    1290         [ #  # ]:           0 :                 if (!nTotSuccess)
    1291                 :             :                 {
    1292                 :           0 :                     pCS->LinearCTStereoCarb[nNumMappedAtoms] = prevAtom;
    1293                 :             :                 }
    1294                 :           0 :                 CurTreeSetPos( cur_tree, tpos1 );
    1295                 :           0 :                 return nTotSuccess;
    1296                 :             :             }
    1297                 :             :         }
    1298                 :             : 
    1299                 :             :         /* djb-rwth: removing redundant code */
    1300                 :         367 :         bStereoIsBetterWasSetHere = 0;
    1301                 :             :         /* djb-rwth: removing redundant code */
    1302                 :         367 :         CurTreeSetPos( cur_tree, tpos1 );  /*  start over */
    1303                 :             : 
    1304                 :             :         /*
    1305                 :             :         if ( prev_stereo_center_parity != stereo_center_parity ) {
    1306                 :             :             CurTreeSetPos( cur_tree, tpos1 );
    1307                 :             :         }
    1308                 :             :         */
    1309                 :             :         /*  nRankTo                 nAtomNumberTo */
    1310   [ +  -  +  - ]:         367 :         for (j1 = 0; j1 <= iMax && at_rank1 == pRankStack2[0][at_to1 = pRankStack2[1][iMax - j1]]; j1++)
    1311                 :             :         {
    1312                 :             :             int ret, ret1, ret2, parity1;
    1313                 :         367 :             nNumAtTo1Success = 0;
    1314                 :             :             /*
    1315                 :             :             if ( !(at[at_to1].stereo_atom_parity && !at[at_to1].stereo_bond_neighbor[0] &&
    1316                 :             :                    pCS->bAtomUsedForStereo[at_to1] == STEREO_AT_MARK ) )
    1317                 :             :             */
    1318   [ +  -  +  - ]:         367 :             if (!at[at_to1].stereo_atom_parity || at[at_to1].stereo_bond_neighbor[0] ||
    1319         [ -  + ]:         367 :                   pCS->bAtomUsedForStereo[at_to1] != STEREO_AT_MARK) /* simplify 12-17-2003 */
    1320                 :             :             {
    1321                 :           0 :                 continue;
    1322                 :             :             }
    1323                 :             :             /* Do not map on non-stereogenic atom constitutionally
    1324                 :             :             * equivalent to a steregenic atom. Here
    1325                 :             :             * at[at_to1] is not a sterereo center;  |       |
    1326                 :             :             * bonds tautomerism is a usual cause.  -P(+)-CH=P-
    1327                 :             :             * For example, consider a fragment:     |       |
    1328                 :             :             * The two atoms P may be constitutionally
    1329                 :             :             * equivalent, P(+) may be seen as a stereocenter
    1330                 :             :             * while another P has a double bond (Now such a P(V) IS a stereocenter).
    1331                 :             :             */
    1332                 :             : 
    1333                 :             :             /*  check whether the stereocenter parity corresponds to the requested stereocenter parity */
    1334   [ +  -  +  - ]:         367 :             if (PARITY_KNOWN( at[at_to1].stereo_atom_parity ))
    1335                 :             :             {
    1336         [ -  + ]:         367 :                 if (stereo_center_parity == sb_parity_calc)
    1337                 :             :                 {
    1338                 :           0 :                     continue;  /*  requested parity to be calculated, found known parity */
    1339                 :             :                 }
    1340         [ -  + ]:         367 :                 if (stereo_center_parity != PARITY_VAL( at[at_to1].stereo_atom_parity ))
    1341                 :             :                 {
    1342                 :           0 :                     continue;  /*  parity differs from the requested parity */
    1343                 :             :                 }
    1344                 :             :             }
    1345                 :             :             else
    1346                 :             :             {
    1347         [ #  # ]:           0 :                 if (PARITY_CALCULATE( at[at_to1].stereo_atom_parity ))
    1348                 :             :                 {
    1349         [ #  # ]:           0 :                     if (stereo_center_parity != sb_parity_calc)
    1350                 :             :                     {
    1351                 :           0 :                         continue;  /*  requested known parity, found patity to be calculated */
    1352                 :             :                     }
    1353                 :             :                 }
    1354                 :             :                 else
    1355                 :             :                 {
    1356                 :           0 :                     return CT_STEREOCOUNT_ERR;  /*  unknown parity type */
    1357                 :             :                 }
    1358                 :             :             }
    1359                 :             : 
    1360         [ +  - ]:         734 :             bAllParitiesIdentical = ( ( at[at_to1].stereo_atom_parity & KNOWN_PARITIES_EQL ) &&
    1361   [ +  -  +  - ]:         367 :                                      PARITY_KNOWN( at[at_to1].stereo_atom_parity ) );
    1362                 :             : 
    1363   [ -  +  -  - ]:         367 :             if (!bAllParitiesIdentical && !nNumCalc &&
    1364         [ #  # ]:           0 :                 ( !nNumUndf + !nNumUnkn + !nNumBest + !nNumWorse ) == 3)
    1365                 :             :             {
    1366                 :             :                 /* only one kind of stereocenter parity is present; check whether all parities are really same */
    1367                 :           0 :                 bAllParitiesIdentical = All_SC_Same( at_rank_canon1, /*  canonical number */
    1368                 :             :                                                       pRankStack1, pRankStack2,
    1369                 :             :                                                       nAtomNumberCanonFrom, at );
    1370         [ #  # ]:           0 :                 if (bAllParitiesIdentical < 0)
    1371                 :             :                 {
    1372                 :           0 :                     return CT_STEREOCOUNT_ERR;
    1373                 :             :                 }
    1374                 :             :             }
    1375   [ -  +  -  - ]:         367 :             if (tpos1 < CurTreeGetPos( cur_tree ) &&
    1376         [ #  # ]:           0 :                  1 == CurTreeIsLastRank( cur_tree, at_rank_canon1 ) &&
    1377                 :           0 :                  1 == CurTreeIsLastAtomEqu( cur_tree, at_to1, nSymmStereo ))
    1378                 :             :             {
    1379                 :           0 :                 continue;
    1380                 :             :             }
    1381                 :             : 
    1382                 :             : 
    1383                 :             :             /*  initialize stack pointer nStackPtr[istk] for "hand-made" recursion */
    1384                 :             :             /*  stacks are pRankStack1[], pRankStack2[], nNumMappedRanks[] */
    1385                 :         367 :             istk = 0;
    1386                 :         367 :             nStackPtr[istk] = 0;
    1387                 :         367 :             nMappedRanks[istk] = nNumMappedRanksInput;
    1388                 :         367 :             bAddStack = 0;
    1389                 :             :             /*  if all equivalent atoms have same known parity, do not map any of them here */
    1390         [ -  + ]:         367 :             if (!bAllParitiesIdentical)
    1391                 :             :             {
    1392                 :             :                 /*  map the central atom */
    1393                 :             :                 /*  this mapping is always possible */
    1394                 :           0 :                 ret1 = map_an_atom2( pCG, num_at_tg, num_max, at_from1, at_to1,
    1395                 :           0 :                                     nTempRank, nMappedRanks[istk], &nMappedRanks[istk + 1], pCS,
    1396                 :           0 :                                     NeighList, pRankStack1 + nStackPtr[istk], pRankStack2 + nStackPtr[istk],
    1397                 :             :                                     &bAddStack );
    1398   [ #  #  #  # ]:           0 :                 if (RETURNED_ERROR( ret1 ))
    1399                 :             :                 {
    1400                 :           0 :                     return ret1; /*  error */
    1401                 :             :                 }
    1402                 :           0 :                 nStackPtr[istk + 1] = nStackPtr[istk] + bAddStack;
    1403                 :           0 :                 istk++;
    1404                 :             :             }
    1405                 :             :             else
    1406                 :             :             {
    1407                 :         367 :                 ClearPreviousMappings( pRankStack1 + 2 ); /*  precaution */
    1408                 :             :             }
    1409                 :             : 
    1410                 :             :             /*********************************************************************************
    1411                 :             :              *
    1412                 :             :              *   Unknown Stereocenter Parity case: possibly need to map stereo center neighbors
    1413                 :             :              */
    1414         [ -  + ]:         367 :             if (stereo_center_parity == sb_parity_calc)
    1415                 :             :             {
    1416                 :             :                 /*  find out the parity */
    1417                 :           0 :                 parity1 = parity_of_mapped_atom2( pCG, at_from1, at_to1, at, &EN[istk],
    1418                 :           0 :                                                  nCanonRankFrom, pRankStack1[nStackPtr[istk]],
    1419                 :           0 :                                                  pRankStack2[nStackPtr[istk]] );
    1420                 :             :                 /*  if parity is well-defined then returned EN[istk].num_to=0 */
    1421         [ #  # ]:           0 :                 if (!parity1)
    1422                 :             :                 {
    1423                 :           0 :                     return CT_STEREOCOUNT_ERR; /*  program error */ /*   <BRKPT> */
    1424                 :             :                 }
    1425   [ #  #  #  # ]:           0 :                 if (!EN[istk].num_to && parity1 != sb_parity_calc)
    1426                 :             :                 {
    1427                 :           0 :                     continue; /*  looking for the parity value = sb_parity_calc */
    1428                 :             :                 }
    1429                 :             :             }
    1430                 :             :             else
    1431                 :             :             {
    1432                 :             :                 /*  Known parity */
    1433                 :         367 :                 parity1 = stereo_center_parity;
    1434                 :         367 :                 EN[istk].num_to = 0;
    1435                 :             :             }
    1436                 :             : 
    1437                 :             :             /***********************************************************************
    1438                 :             :              * no need to map the neighbors: parity is known or has been calculated
    1439                 :             :              */
    1440   [ -  +  -  - ]:         367 :             if ((stereo_center_parity == sb_parity_calc && !EN[istk].num_to) ||
    1441                 :             :                  /*  now well-defined, but unknown in advance atom parity  OR   */
    1442         [ +  - ]:         367 :                  stereo_center_parity != sb_parity_calc) /* djb-rwth: addressing LLVM warning */
    1443                 :             :                  /*  known in advance parity = stereo_center_parity */
    1444                 :             :             {
    1445                 :             :                 /*  do not need to map the neighbors */
    1446                 :         367 :                 c = CompareLinCtStereoAtomToValues( pCS->LinearCTStereoCarb + nNumMappedAtoms,
    1447                 :         367 :                                             at_rank_canon1, (U_CHAR) parity1 );
    1448   [ -  +  -  - ]:         367 :                 if (c < 0 && !pCS->bStereoIsBetter)
    1449                 :             :                 {
    1450                 :             :                     /*  reject */
    1451                 :           0 :                     pCS->lNumRejectedCT++;
    1452                 :           0 :                     continue;  /*  Reject: not a minimal CT. Should not happen */
    1453                 :             :                 }
    1454                 :             :                 else
    1455                 :             :                 {
    1456                 :             :                     /*  accept */
    1457         [ -  + ]:         367 :                     if (bAddStack)
    1458                 :             :                     {
    1459   [ #  #  #  # ]:           0 :                         if (tpos1 == CurTreeGetPos( cur_tree ) ||
    1460                 :           0 :                              0 == CurTreeIsLastRank( cur_tree, at_rank_canon1 ))
    1461                 :             :                         {
    1462                 :           0 :                             CurTreeAddRank( cur_tree, at_rank_canon1 );
    1463                 :             :                         }
    1464                 :           0 :                         CurTreeAddAtom( cur_tree, at_to1 );
    1465                 :             :                     }
    1466                 :             : 
    1467   [ +  +  +  + ]:         367 :                     if (c > 0 && !pCS->bStereoIsBetter)
    1468                 :             :                     {
    1469                 :             :                         /*  stereo center entry is less than the previusly found */
    1470                 :          41 :                         pCS->bStereoIsBetter = bStereoIsBetterWasSetHere = 1;
    1471                 :          41 :                         prevAtom2 = pCS->LinearCTStereoCarb[nNumMappedAtoms];
    1472                 :             :                     }
    1473                 :         367 :                     pCS->LinearCTStereoCarb[nNumMappedAtoms].parity = parity1;
    1474                 :         367 :                     pCS->LinearCTStereoCarb[nNumMappedAtoms].at_num = at_rank_canon1;
    1475                 :         367 :                     pCS->bRankUsedForStereo[at_from1] = 3;
    1476                 :             : #if ( FIX_ChCh_STEREO_CANON_BUG == 1 )
    1477         [ -  + ]:         367 :                     if (!bAllParitiesIdentical)
    1478                 :             : #endif
    1479                 :           0 :                         pCS->bAtomUsedForStereo[at_to1] -= STEREO_AT_MARK;
    1480                 :             : 
    1481                 :             : 
    1482                 :         367 :                     ret = map_stereo_atoms4( ic, pCG,
    1483                 :             :                                               at, num_atoms, num_at_tg, num_max,
    1484                 :             :                                               nCanonRankFrom,
    1485                 :             :                                               nAtomNumberCanonFrom,
    1486                 :             :                                               nCanonRankTo,
    1487                 :             :                                               nSymmRank,
    1488                 :         367 :                                               pRankStack1 + nStackPtr[istk],
    1489                 :         367 :                                               pRankStack2 + nStackPtr[istk],
    1490                 :             :                                               nTempRank,
    1491                 :             :                                               nMappedRanks[istk],
    1492                 :             :                                               nSymmStereo,
    1493                 :             :                                               NeighList,
    1494                 :             :                                               pCS,
    1495                 :             :                                               cur_tree,
    1496                 :             :                                               nNumMappedAtoms + 1,
    1497                 :             :                                               vABParityUnknown );
    1498                 :             : 
    1499                 :         367 :                     pCS->bRankUsedForStereo[at_from1] = 0;
    1500                 :             : #if ( FIX_ChCh_STEREO_CANON_BUG == 1 )
    1501         [ -  + ]:         367 :                     if (!bAllParitiesIdentical)
    1502                 :             : #endif
    1503                 :           0 :                         pCS->bAtomUsedForStereo[at_to1] += STEREO_AT_MARK;
    1504                 :             : 
    1505         [ -  + ]:         367 :                     if (ret == 4)
    1506                 :             :                     {
    1507                 :           0 :                         return ret;
    1508                 :             :                     }
    1509                 :             : 
    1510   [ +  -  -  + ]:         367 :                     if (RETURNED_ERROR( ret ))
    1511                 :             :                     {
    1512                 :           0 :                         return ret; /*  program error */ /* djb-rwth: fixing coverity ID #499567 */
    1513                 :             :                     }
    1514                 :             : 
    1515         [ +  - ]:         367 :                     if (ret > 0)
    1516                 :             :                     {
    1517                 :         367 :                         nTotSuccess |= 1;
    1518                 :         367 :                         nNumAtTo1Success++;
    1519   [ +  +  +  + ]:         367 :                         if (bStereoIsBetterWasSetHere || ( ret & 2 ))
    1520                 :             :                         {
    1521                 :          76 :                             CurTreeKeepLastAtomsOnly( cur_tree, tpos1, 1 );  /*  start over */
    1522                 :          76 :                             nTotSuccess |= 2; /*  Obtained a smaller CT */
    1523                 :             :                         }
    1524                 :             :                     }
    1525                 :             :                     else
    1526                 :             :                     {
    1527         [ #  # ]:           0 :                         if (bStereoIsBetterWasSetHere)
    1528                 :             :                         {
    1529                 :           0 :                             pCS->bStereoIsBetter = 0;
    1530                 :           0 :                             pCS->LinearCTStereoCarb[nNumMappedAtoms] = prevAtom2;
    1531                 :             :                         }
    1532                 :             :                         /*  remove failed atom1 from the tree */
    1533                 :             : 
    1534   [ #  #  #  # ]:           0 :                         if (tpos1 < CurTreeGetPos( cur_tree ) &&
    1535                 :           0 :                              1 == CurTreeIsLastRank( cur_tree, at_rank_canon1 ))
    1536                 :             :                         {
    1537                 :           0 :                             CurTreeRemoveIfLastAtom( cur_tree, at_to1 );
    1538                 :           0 :                             CurTreeRemoveLastRankIfNoAtoms( cur_tree );
    1539                 :             :                         }
    1540                 :             :                     }
    1541                 :         367 :                     bStereoIsBetterWasSetHere = 0;
    1542                 :             :                 }
    1543                 :             : 
    1544                 :             :                 /*
    1545                 :             :                 if ( (at[at_to1].stereo_atom_parity & KNOWN_PARITIES_EQL ) &&
    1546                 :             :                      ATOM_PARITY_KNOWN(stereo_center_parity) && !nSymmStereo ) { // ??? add && !nSymmStereo ???
    1547                 :             :                     break; // do not repeat for the same kind of stereo atom with the parity known in advance
    1548                 :             :                 }
    1549                 :             :                 */
    1550         [ +  - ]:         367 :                 if (bAllParitiesIdentical)
    1551                 :             :                 {
    1552                 :         367 :                     break;  /*  do not repeat for the same kind of stereo atom with the parity known in advance */
    1553                 :             :                 }
    1554                 :           0 :                 continue;
    1555                 :             :             }
    1556                 :             : 
    1557                 :             :             /***************************************************
    1558                 :             :              *
    1559                 :             :              * Need to map the neighbors
    1560                 :             :              */
    1561         [ #  # ]:           0 :             if (stereo_center_parity != sb_parity_calc)
    1562                 :             :             {
    1563                 :           0 :                 return CT_STEREOCOUNT_ERR;  /*  program error */ /*   <BRKPT> */
    1564                 :             :             }
    1565                 :             :             /* -- has already been calculated --
    1566                 :             :             parity1 = parity_of_mapped_atom2( pCG, at_from1, at_to1, at, &EN[istk],
    1567                 :             :                                              nCanonRankFrom, pRankStack1[nStackPtr[istk]], pRankStack2[nStackPtr[istk]] );
    1568                 :             :             */
    1569         [ #  # ]:           0 :             if (!parity1)
    1570                 :             :             {
    1571                 :           0 :                 return CT_STEREOCOUNT_ERR; /*  1/25/2002 */ /*   <BRKPT> */
    1572                 :             :             }
    1573                 :             : 
    1574         [ #  # ]:           0 :             if (bAddStack)
    1575                 :             :             {
    1576   [ #  #  #  # ]:           0 :                 if (tpos1 == CurTreeGetPos( cur_tree ) ||
    1577                 :           0 :                      0 == CurTreeIsLastRank( cur_tree, at_rank_canon1 ))
    1578                 :             :                 {
    1579                 :           0 :                     CurTreeAddRank( cur_tree, at_rank_canon1 );
    1580                 :             :                 }
    1581                 :           0 :                 CurTreeAddAtom( cur_tree, at_to1 );
    1582                 :             :             }
    1583                 :             :             /******************************************************
    1584                 :             :              * Need to fix the neighbors to define the atom parity
    1585                 :             :              ******************************************************/
    1586                 :             :             /*  a recursion replaced with the hand-made stack */
    1587                 :           0 :             lvl = 0;              /*  the "recursion" depth level */
    1588                 :           0 :             nSP = &nStackPtr[istk];
    1589                 :           0 :             nMR = &nMappedRanks[istk];
    1590                 :           0 :             pEN = &EN[istk];
    1591                 :           0 :             bLastLvlFailed = 0;
    1592                 :             : 
    1593                 :             :             /*  entering "recursion" depth level lvl */
    1594                 :           0 :         next_lvl:
    1595         [ #  # ]:           0 :             if (pEN[lvl].num_to)
    1596                 :             :             {
    1597                 :             :                 /* Found tied neighbors. Try all transpositions of the tied neighbors.
    1598                 :             :                  * j is a number of the "to" tied neighbor in the pEN[lvl].to_at[*] to
    1599                 :             :                  * which the pEN[lvl].from_at "from" neighbor's canonical number is mapped
    1600                 :             :                  */
    1601                 :           0 :                 j[lvl] = 0;
    1602                 :           0 :             next_j:
    1603                 :           0 :                 cr[lvl] = nCanonRankFrom[pEN[lvl].from_at];
    1604                 :           0 :                 at_to[lvl] = pEN[lvl].to_at[j[lvl]];
    1605   [ #  #  #  #  :           0 :                 if (j[lvl] && tpos1 < CurTreeGetPos( cur_tree ) &&
                   #  # ]
    1606         [ #  # ]:           0 :                      1 == CurTreeIsLastRank( cur_tree, cr[lvl] ) &&
    1607                 :           0 :                      1 == CurTreeIsLastAtomEqu( cur_tree, at_to[lvl], nSymmStereo ))
    1608                 :             :                 {
    1609                 :           0 :                     lvl++;
    1610                 :           0 :                     bLastLvlFailed = 0;
    1611                 :           0 :                     goto backup; /*  do not test stereo equivalent atoms except the first one */
    1612                 :             :                 }
    1613                 :             : 
    1614                 :           0 :                 ret2 = map_an_atom2( pCG, num_at_tg, num_max,
    1615                 :           0 :                                     pEN[lvl].from_at,        /* from */
    1616                 :           0 :                                     pEN[lvl].to_at[j[lvl]],  /* to */
    1617                 :           0 :                                     nTempRank, nMR[lvl], &nMR[lvl + 1], pCS,
    1618                 :           0 :                                     NeighList, pRankStack1 + nSP[lvl], pRankStack2 + nSP[lvl],
    1619                 :             :                                     &bAddStack );
    1620                 :             : 
    1621   [ #  #  #  # ]:           0 :                 if (RETURNED_ERROR( ret2 ))
    1622                 :             :                 {
    1623                 :           0 :                     return ret2; /*  program error */
    1624                 :             :                 }
    1625                 :             : 
    1626                 :             :                 /*  next recursion depth level */
    1627         [ #  # ]:           0 :                 if (bAddStack)
    1628                 :             :                 {
    1629   [ #  #  #  # ]:           0 :                     if (tpos1 == CurTreeGetPos( cur_tree ) ||
    1630                 :           0 :                          0 == CurTreeIsLastRank( cur_tree, cr[lvl] ))
    1631                 :             :                     {
    1632                 :           0 :                         CurTreeAddRank( cur_tree, cr[lvl] );
    1633                 :             :                     }
    1634                 :           0 :                     CurTreeAddAtom( cur_tree, at_to[lvl] );
    1635                 :             :                 }
    1636                 :           0 :                 nSP[lvl + 1] = nSP[lvl] + bAddStack;
    1637                 :           0 :                 lvl++; /*  upon increment lvl = number of additionally mapped neighbors
    1638                 :             :                          *  (entering next recursion level) */
    1639                 :             : 
    1640                 :             :                 /*  check if the mapping has defined the parity */
    1641                 :           0 :                 parity1 = parity_of_mapped_atom2( pCG, at_from1, at_to1, at, &pEN[lvl],
    1642                 :           0 :                                              nCanonRankFrom, pRankStack1[nSP[lvl]], pRankStack2[nSP[lvl]] );
    1643                 :             : 
    1644         [ #  # ]:           0 :                 if (!parity1)
    1645                 :             :                 {
    1646                 :           0 :                     return CT_STEREOCOUNT_ERR; /*  1/25/2002 */ /*   <BRKPT> */
    1647                 :             :                 }
    1648         [ #  # ]:           0 :                 if (parity1 < 0)
    1649                 :             :                 {
    1650                 :           0 :                     goto next_lvl; /*  we need at least one more mapping to define the parity */
    1651                 :             :                 }
    1652                 :             : 
    1653                 :             :                 /**********************************************************
    1654                 :             :                  *
    1655                 :             :                  *  Check the parity
    1656                 :             :                  *
    1657                 :             :                  **********************************************************
    1658                 :             :                  *  make a decision whether to accept the current mapping */
    1659                 :             : 
    1660                 :           0 :                 c = CompareLinCtStereoAtomToValues( pCS->LinearCTStereoCarb + nNumMappedAtoms,
    1661                 :           0 :                                             at_rank_canon1, (U_CHAR) parity1 );
    1662   [ #  #  #  # ]:           0 :                 if (sb_parity_calc != parity1 ||
    1663         [ #  # ]:           0 :                      (c < 0 && !pCS->bStereoIsBetter)) /* djb-rwth: addressing LLVM warning */
    1664                 :             :                 {
    1665                 :           0 :                     pCS->lNumRejectedCT++;
    1666                 :           0 :                     bLastLvlFailed = 1;
    1667                 :             :                 }
    1668                 :             :                 else
    1669                 :             :                    /*  the parity has been defined (all neighbors have untied ranks) */
    1670                 :             :                    /*  if ( bAcceptAllParities || parity1 == BEST_PARITY ) */
    1671                 :             :                 {
    1672                 :             :                     /*********************************************************************
    1673                 :             :                      *
    1674                 :             :                      * Process the parity here. We are at the top of the recursion stack.
    1675                 :             :                      *
    1676                 :             :                      *********************************************************************/
    1677                 :             :                     /*  try to accept current neighbors mapping */
    1678   [ #  #  #  # ]:           0 :                     if (c > 0 && !pCS->bStereoIsBetter)
    1679                 :             :                     {
    1680                 :           0 :                         pCS->bStereoIsBetter = bStereoIsBetterWasSetHere = 1;
    1681                 :           0 :                         prevAtom2 = pCS->LinearCTStereoCarb[nNumMappedAtoms];
    1682                 :             :                     }
    1683                 :           0 :                     pCS->LinearCTStereoCarb[nNumMappedAtoms].parity = parity1;
    1684                 :           0 :                     pCS->LinearCTStereoCarb[nNumMappedAtoms].at_num = at_rank_canon1;
    1685                 :           0 :                     pCS->bRankUsedForStereo[at_from1] = 3;
    1686                 :           0 :                     pCS->bAtomUsedForStereo[at_to1] -= STEREO_AT_MARK;
    1687                 :             : 
    1688                 :           0 :                     ret = map_stereo_atoms4( ic, pCG, at, num_atoms, num_at_tg, num_max, nCanonRankFrom, nAtomNumberCanonFrom, nCanonRankTo,
    1689                 :           0 :                                        nSymmRank, pRankStack1 + nSP[lvl], pRankStack2 + nSP[lvl],
    1690                 :           0 :                                        nTempRank, nMR[lvl], nSymmStereo, NeighList,
    1691                 :             :                                        pCS, cur_tree, nNumMappedAtoms + 1,
    1692                 :             :                                        vABParityUnknown );
    1693                 :             : 
    1694                 :           0 :                     pCS->bRankUsedForStereo[at_from1] = 0;
    1695                 :           0 :                     pCS->bAtomUsedForStereo[at_to1] += STEREO_AT_MARK;
    1696         [ #  # ]:           0 :                     if (ret == 4)
    1697                 :             :                     {
    1698                 :           0 :                         return ret;
    1699                 :             :                     }
    1700   [ #  #  #  # ]:           0 :                     if (RETURNED_ERROR( ret ))
    1701                 :             :                     {
    1702         [ #  # ]:           0 :                         if (ret == CT_TIMEOUT_ERR)
    1703                 :           0 :                             return ret;
    1704                 :             :                         else
    1705                 :           0 :                             return ret; /*  program error */
    1706                 :             :                     }
    1707         [ #  # ]:           0 :                     if (ret > 0)
    1708                 :             :                     {
    1709                 :           0 :                         nTotSuccess |= 1;
    1710                 :           0 :                         nNumAtTo1Success++;
    1711   [ #  #  #  # ]:           0 :                         if (bStereoIsBetterWasSetHere || ( ret & 2 ))
    1712                 :             :                         {
    1713                 :           0 :                             CurTreeKeepLastAtomsOnly( cur_tree, tpos1, 1 );  /*  start over */
    1714                 :           0 :                             nTotSuccess |= 2; /*  Obtained a smaller CT */
    1715                 :             :                         }
    1716                 :             :                     }
    1717                 :             :                     else
    1718                 :             :                     {
    1719         [ #  # ]:           0 :                         if (bStereoIsBetterWasSetHere)
    1720                 :             :                         {
    1721                 :           0 :                             pCS->bStereoIsBetter = 0;
    1722                 :           0 :                             pCS->LinearCTStereoCarb[nNumMappedAtoms] = prevAtom2;
    1723                 :             :                         }
    1724                 :           0 :                         bLastLvlFailed = 1;
    1725                 :             :                     }
    1726                 :           0 :                     bStereoIsBetterWasSetHere = 0;
    1727                 :             : 
    1728                 :             :                     /*  avoid redundant repetitions: */
    1729                 :             :                     /*  check if neighbors mappings have altered another stereo center parity */
    1730   [ #  #  #  # ]:           0 :                     if (!nSymmStereo && !might_change_other_atom_parity( at, num_atoms, at_to1,
    1731                 :           0 :                         pRankStack2[nSP[lvl]] /* ranks after neigbors mapping */,
    1732                 :           0 :                         pRankStack2[nStackPtr[istk]] /* ranks before the mapping neighbors */ ))
    1733                 :             :                     {
    1734                 :           0 :                         goto done;
    1735                 :             :                     }
    1736                 :             :                 }
    1737                 :             :                 /*  Continue the cycle. Go to the previous "recursion" level */
    1738                 :           0 :             backup:
    1739         [ #  # ]:           0 :                 while (lvl-- > 0)
    1740                 :             :                 {
    1741                 :             : 
    1742                 :           0 :                     j[lvl] ++; /*  next neighbor at this level */
    1743         [ #  # ]:           0 :                     if (j[lvl] < pEN[lvl].num_to)
    1744                 :             :                     {
    1745         [ #  # ]:           0 :                         if (bLastLvlFailed)
    1746                 :             :                         {
    1747   [ #  #  #  # ]:           0 :                             if (tpos1 < CurTreeGetPos( cur_tree ) &&
    1748                 :           0 :                                  1 == CurTreeIsLastRank( cur_tree, cr[lvl] ))
    1749                 :             :                             {
    1750                 :           0 :                                 CurTreeRemoveIfLastAtom( cur_tree, at_to[lvl] );
    1751                 :           0 :                                 CurTreeRemoveLastRankIfNoAtoms( cur_tree );
    1752                 :             :                             }
    1753                 :           0 :                             bLastLvlFailed = 0;
    1754                 :             :                         }
    1755                 :             :                         /*  Done with this level. Go back one level */
    1756                 :           0 :                         goto next_j;
    1757                 :             :                     }
    1758                 :             :                     /*  remove failed atom from the tree */
    1759   [ #  #  #  # ]:           0 :                     if (tpos1 < CurTreeGetPos( cur_tree ) &&
    1760                 :           0 :                          1 == CurTreeIsLastRank( cur_tree, cr[lvl] ))
    1761                 :             :                     {
    1762                 :           0 :                         CurTreeRemoveLastRank( cur_tree );
    1763                 :             :                     }
    1764                 :             :                 }
    1765                 :           0 :                 goto done;
    1766                 :             :             }
    1767                 :             :             else
    1768                 :             :             {
    1769                 :           0 :                 cr[lvl] = 0;
    1770                 :             :             }
    1771                 :             : 
    1772                 :           0 : done:;      /*  at this point lvl=0. */
    1773         [ #  # ]:           0 :             if (!nNumAtTo1Success)
    1774                 :             :             {
    1775   [ #  #  #  # ]:           0 :                 if (tpos1 < CurTreeGetPos( cur_tree ) &&
    1776                 :           0 :                      1 == CurTreeIsLastRank( cur_tree, at_rank_canon1 ))
    1777                 :             :                 {
    1778                 :           0 :                     CurTreeRemoveIfLastAtom( cur_tree, at_to1 );
    1779                 :           0 :                     CurTreeRemoveLastRankIfNoAtoms( cur_tree );
    1780                 :             :                 }
    1781                 :             :             }
    1782                 :             :         } /*  end of stereo atom mapping cycle */
    1783                 :             : 
    1784   [ -  +  -  - ]:         367 :         if (tpos1 < CurTreeGetPos( cur_tree ) &&
    1785                 :           0 :              1 == CurTreeIsLastRank( cur_tree, at_rank_canon1 ))
    1786                 :             :         {
    1787                 :           0 :             CurTreeRemoveLastRank( cur_tree );
    1788                 :             :         }
    1789                 :             :         else
    1790                 :             :         {
    1791                 :             :             /*  CurTree consistency check (debug only) */
    1792         [ -  + ]:         367 :             if (tpos1 != CurTreeGetPos( cur_tree ))
    1793                 :             :             {
    1794                 :           0 :                 return CT_STEREOCOUNT_ERR;  /*   <BRKPT> */
    1795                 :             :             }
    1796                 :             :         }
    1797                 :             : 
    1798   [ +  -  -  + ]:         367 :         if (!nTotSuccess || stereo_center_parity == sb_parity_calc)
    1799                 :             :         {
    1800                 :           0 :             goto repeat_all; /*  repeat with next parity if no success or with the same parity, now known */
    1801                 :             :         }
    1802                 :             :     }
    1803                 :             : 
    1804                 :             :     else
    1805                 :             :     {
    1806                 :             : 
    1807                 :             :         /****************************************************
    1808                 :             :          *
    1809                 :             :          *  All stereogenic atoms and bonds have been mapped
    1810                 :             :          *
    1811                 :             :          ****************************************************/
    1812                 :             : 
    1813   [ -  +  -  - ]:         109 :         if ((UserAction && USER_ACTION_QUIT == ( *UserAction )( )) ||
    1814   [ -  +  -  - ]:         109 :              (ConsoleQuit && ( *ConsoleQuit )( ))) /* djb-rwth: addressing LLVM warning */
    1815                 :             :         {
    1816                 :           0 :             return CT_USER_QUIT_ERR;
    1817                 :             :         }
    1818                 :             : 
    1819   [ +  +  +  - ]:         109 :         if (pCS->bStereoIsBetter || pCS->bFirstCT)
    1820                 :         109 :         {
    1821                 :             :             /* All stereo atoms have been mapped. Current stereo name is better than all previous.
    1822                 :             :              * Create new numbering for the new CT
    1823                 :             :              * break all remaining "from" ties
    1824                 :             :              */
    1825                 :             :             int i1, ret;
    1826                 :             :             AT_RANK rc, n1, n2;
    1827                 :             : 
    1828                 :         109 :             ret = BreakAllTies( pCG, num_at_tg, num_max, pRankStack1,
    1829                 :             :                               NeighList, nTempRank, pCS );
    1830                 :             : 
    1831   [ +  -  -  + ]:         109 :             if (RETURNED_ERROR( ret ))
    1832                 :             :             {
    1833                 :           0 :                 return ret;
    1834                 :             :             }
    1835                 :             : 
    1836                 :             :             /*  break all remaining "from" ties */
    1837                 :         109 :             ret = BreakAllTies( pCG, num_at_tg, num_max, pRankStack2,
    1838                 :             :                               NeighList, nTempRank, pCS );
    1839                 :             : 
    1840   [ +  -  -  + ]:         109 :             if (RETURNED_ERROR( ret ))
    1841                 :             :             {
    1842                 :           0 :                 return ret;
    1843                 :             :             }
    1844                 :             :             /*  move stack pointers to the "nAtomNumber[*]" after all ties are broken */
    1845                 :         109 :             pRankStack1 += 2;
    1846                 :         109 :             pRankStack2 += 2;
    1847                 :             :             /* Now final mapping ranks of "to" atom (*pRankStack2)[i] and "from" atom (*pRankStack1)[i]
    1848                 :             :              * are equal and all ranks are different, that is, we have a full mapping
    1849                 :             :              * Copy so far best canonical numbering from "from" to "to".
    1850                 :             :              */
    1851                 :         109 :             memset( pCS->nPrevAtomNumber, 0, num_at_tg * sizeof( pCS->nPrevAtomNumber[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */
    1852         [ +  + ]:        1221 :             for (i1 = 0; i1 < num_at_tg; i1++)
    1853                 :             :             {
    1854                 :        1112 :                 n1 = pRankStack1[1][i1];
    1855                 :        1112 :                 rc = nCanonRankFrom[n1]; /*  new canon. rank */
    1856                 :        1112 :                 n2 = pRankStack2[1][i1];                  /*  orig. atom number */
    1857                 :        1112 :                 nCanonRankTo[n2] = rc;                    /*  assign new canon. number to the atom */
    1858                 :             :                 /*  use this array to find stereo-equivalent atoms */
    1859                 :        1112 :                 pCS->nPrevAtomNumber[rc - 1] = n2; /*  ord. number of the atom having canon. rank = rc */
    1860                 :        1112 :                 nSymmStereo[i1] = i1;            /*  restart search for stereo equivalent atoms */
    1861                 :             :                 /* check mapping correctness */
    1862         [ +  - ]:        1112 :                 if (pRankStack1[0][n1] != pRankStack2[0][n2] ||
    1863         [ -  + ]:        1112 :                      nSymmRank[n1] != nSymmRank[n2])
    1864                 :             :                 {
    1865                 :           0 :                     return CT_STEREO_CANON_ERR; /* stereo mapping error */
    1866                 :             :                 }
    1867                 :             :             }
    1868                 :             :             /*  statistics */
    1869                 :         109 :             pCS->lNumTotCT++;
    1870                 :         109 :             pCS->lNumEqualCT = 1;
    1871                 :         109 :             pCS->lNumDecreasedCT++;
    1872                 :         109 :             pCS->bStereoIsBetter = 0; /*  prepare to start over */
    1873                 :         109 :             nTotSuccess = 1;
    1874                 :         109 :             pCS->bFirstCT = 0;
    1875                 :             : 
    1876                 :             : #if ( REMOVE_CALC_NONSTEREO == 1 ) /* { */
    1877         [ +  - ]:         109 :             if (!( pCS->nMode & CMODE_REDNDNT_STEREO ))
    1878                 :             :             {
    1879                 :         109 :                 i1 = RemoveCalculatedNonStereo( pCG, at, num_atoms, num_at_tg,
    1880                 :             :                                   pRankStack1, pRankStack2, nTempRank, NeighList,
    1881                 :             :                                   nSymmRank, nCanonRankTo, pCS->nPrevAtomNumber, pCS,
    1882                 :             :                                   vABParityUnknown );
    1883   [ +  -  -  + ]:         109 :                 if (RETURNED_ERROR( i1 ))
    1884                 :             :                 {
    1885                 :           0 :                     return i1;
    1886                 :             :                 }
    1887         [ -  + ]:         109 :                 if (i1 < 0)
    1888                 :             :                 {
    1889                 :             : #if ( bRELEASE_VERSION == 0 )
    1890                 :             :                     pCS->bExtract |= EXTR_REMOVE_PARITY_WARNING;
    1891                 :             : #endif
    1892                 :           0 :                     i1 = -( 1 + i1 );
    1893                 :             :                 }
    1894         [ -  + ]:         109 :                 if (i1 > 0)
    1895                 :             :                 {
    1896                 :           0 :                     return 4; /*  total restart: due to newly found stereo equivalence */
    1897                 :             :                               /*  the length of the stereo CT has changed */
    1898                 :             :                 }
    1899                 :             :             }
    1900                 :             : #endif /* } REMOVE_CALC_NONSTEREO */
    1901                 :             : 
    1902                 :             :             /* djb-rwth: removing redundant code */
    1903                 :             :         }
    1904                 :             :         else
    1905                 :             :         {
    1906                 :             :             /*  current stereo name is same as previous. We do not need a full mapping. */
    1907         [ #  # ]:           0 :             if (nSymmStereo)
    1908                 :             :             {
    1909                 :           0 :                 int num_changes = 0;
    1910                 :             :                 AT_RANK r, n1, n2, r_max, cr;
    1911                 :           0 :                 r_max = (AT_RANK) num_at_tg;
    1912         [ #  # ]:           0 :                 for (r = 1; r <= r_max; r++)
    1913                 :             :                 {
    1914         [ #  # ]:           0 :                     if (bUniqueAtNbrFromMappingRank( pRankStack1, r, &n1 ))
    1915                 :             :                     {
    1916         [ #  # ]:           0 :                         if (bUniqueAtNbrFromMappingRank( pRankStack2, r, &n2 ))
    1917                 :             :                         {
    1918                 :             :                             /*  atoms at[n1], at[n2] have identical untied mapping rank r */
    1919                 :           0 :                             cr = nCanonRankFrom[(int) n1] - 1; /*  (new at[n2] canonical rank)-1 */
    1920                 :             :                             /*  pCS->nPrevAtomNumber[(int)cr] = */
    1921                 :             :                             /*    previous ordering number of an atom with the canon. rank = cr+1; */
    1922                 :             :                             /*    make this atom equivalent to atom at[n2]: */
    1923                 :           0 :                             num_changes += nJoin2Mcrs( nSymmStereo, pCS->nPrevAtomNumber[(int) cr], n2 );
    1924                 :             :                         }
    1925                 :             :                         else
    1926                 :             :                         {
    1927                 :           0 :                             return CT_MAPCOUNT_ERR; /*  mapping ranks must be either both tied or untied. */ /*   <BRKPT> */
    1928                 :             :                         }
    1929                 :             :                     }
    1930                 :             :                 }
    1931         [ #  # ]:           0 :                 if (num_changes)
    1932                 :             :                 { /*  compress trees to stars */
    1933         [ #  # ]:           0 :                     for (r = r_max - 1; r; r--)
    1934                 :             :                     {
    1935                 :           0 :                         nGetMcr( nSymmStereo, r );
    1936                 :             :                     }
    1937                 :             :                 }
    1938                 :             :             }
    1939                 :             :             /*  statistics */
    1940                 :           0 :             pCS->lNumEqualCT++;
    1941                 :           0 :             pCS->lNumTotCT++;
    1942                 :           0 :             nTotSuccess = 1;
    1943                 :             :         }
    1944         [ -  + ]:         109 :         if (bInchiTimeIsOver( ic, pCS->ulTimeOutTime ))
    1945                 :             :         {
    1946                 :           0 :             return CT_TIMEOUT_ERR;
    1947                 :             :         }
    1948                 :             :     }
    1949   [ -  +  -  - ]:         476 :     if (!nTotSuccess && nNumMappedAtoms < pCS->nLenLinearCTStereoCarb)
    1950                 :             :     {
    1951                 :           0 :         pCS->LinearCTStereoCarb[nNumMappedAtoms] = prevAtom;
    1952                 :           0 :         CurTreeSetPos( cur_tree, tpos1 );
    1953                 :             :     }
    1954                 :             : 
    1955                 :         476 :     return nTotSuccess;  /*  return to the previous level of the recursion. */
    1956                 :             : }
        

Generated by: LCOV version 2.0-1