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

Generated by: LCOV version 2.0-1