third_party/inchi/INCHI_BASE/src/ichicans.c
int GetAndCheckNextNeighbors( sp_ATOM       *at,
                              AT_RANK       cur1,
                              AT_RANK       prev1,
                              AT_RANK       cur2,
                              AT_RANK       prev2,
                              AT_RANK       *n1,
                              AT_RANK       *n2,
                              AT_RANK       *nVisited1,
                              AT_RANK       *nVisited2,
                              const AT_RANK *nRank,
                              const AT_RANK *nCanonRank )
{
    AT_RANK cr1, cr2, s1, s2;
    int     i1, i2, k1, k2;

    cr1 = ( *n1 > MAX_ATOMS ) ? 0 : nCanonRank[(int) *n1];
    cr2 = ( *n2 > MAX_ATOMS ) ? 0 : nCanonRank[(int) *n2];

    if (!GetNextNeighborAndRank( at, cur1, prev1, n1, &cr1, nCanonRank ) ||
         !GetNextNeighborAndRank( at, cur2, prev2, n2, &cr2, nCanonRank ) ||
         nRank[(int) *n1] != nRank[(int) *n2] || nVisited1[(int) *n1] != nVisited2[(int) *n2])
    {
        return 0;  /*  program error; no breakpoint here */ /*   <BRKPT> */
    }

    /*  Even though the bond or cumulene might have already been checked, check it: this is */
    /*  the only place we can check stereo bonds and cumulenes that are not edges of the DFS tree */
    /*  The code works both for a stereo bond and a stereogenic cumulene. */
    for (i1 = 0, k1 = 0;
         i1 < MAX_NUM_STEREO_BONDS &&
         ( s1 = at[cur1].stereo_bond_neighbor[i1] ) &&
            !( k1 = ( at[cur1].neighbor[(int) at[cur1].stereo_bond_ord[i1]] == *n1 ) );
         i1++)
    {
        ;
    }

    for (i2 = 0, k2 = 0;
         i2 < MAX_NUM_STEREO_BONDS &&
         ( s2 = at[cur2].stereo_bond_neighbor[i2] ) &&
            !( k2 = ( at[cur2].neighbor[(int) at[cur2].stereo_bond_ord[i2]] == *n2 ) );
         i2++)
    {
        ;
    }

    if (k1 != k2)
    {
        return 0; /*  possibly not an error: constit. equivalent atoms on a stereo bond and not on a stereo bond */
    }

    if (k1 /* yes, it is a stereo bond */ &&
        ( at[cur1].stereo_bond_parity[i1] != at[cur2].stereo_bond_parity[i2] ||
          /* PARITY_KNOWN (at[cur1].stereo_bond_parity[i1] ) */  /*  replaced 08-13-2002 with the next: */
            !PARITY_WELL_DEF( at[cur1].stereo_bond_parity[i1] ) /*  it suffices to check only one parity */
            ))
    {
        return 0; /*  different or (currently) unknown stereo bond parities */
    }

    return 1; /*  stereo bonds have known parities */
}
/****************************************************************************
 Find next pair of neighbors having the next greater canon. rank
 The neighbors should be constitutionally identical and traversed
 simultaneouslyor not traversed at all
 If a bond cur1-*n1 or cur2-*n2 is a stereo bond then reject if their stereo
 bond parities are different or cannot be calculated without breaking ties.
****************************************************************************/
Find next pair of neighbors having the next greater canon. rank
The neighbors should be constitutionally identical and traversed
simultaneouslyor not traversed at all
If a bond cur1-*n1 or cur2-*n2 is a stereo bond then reject if their stereo
bond parities are different or cannot be calculated without breaking ties.
Find next pair of neighbors having the next greater canon . rank The neighbors should be constitutionally identical and traversed simultaneouslyor not traversed at all If a bond cur1 - * n1 or cur2 - * n2 is a stereo bond then reject if their stereo bond parities are different or cannot be calculated without breaking ties .
int GetAndCheckNextNeighbors( sp_ATOM       *at,
                              AT_RANK       cur1,
                              AT_RANK       prev1,
                              AT_RANK       cur2,
                              AT_RANK       prev2,
                              AT_RANK       *n1,
                              AT_RANK       *n2,
                              AT_RANK       *nVisited1,
                              AT_RANK       *nVisited2,
                              const AT_RANK *nRank,
                              const AT_RANK *nCanonRank )
{
    AT_RANK cr1, cr2, s1, s2;
    int     i1, i2, k1, k2;
    cr1 = ( *n1 > MAX_ATOMS ) ? 0 : nCanonRank[(int) *n1];
    cr2 = ( *n2 > MAX_ATOMS ) ? 0 : nCanonRank[(int) *n2];
    if (!GetNextNeighborAndRank( at, cur1, prev1, n1, &cr1, nCanonRank ) ||
         !GetNextNeighborAndRank( at, cur2, prev2, n2, &cr2, nCanonRank ) ||
         nRank[(int) *n1] != nRank[(int) *n2] || nVisited1[(int) *n1] != nVisited2[(int) *n2])
    {
        return 0;   
    }
    for (i1 = 0, k1 = 0;
         i1 < MAX_NUM_STEREO_BONDS &&
         ( s1 = at[cur1].stereo_bond_neighbor[i1] ) &&
            !( k1 = ( at[cur1].neighbor[(int) at[cur1].stereo_bond_ord[i1]] == *n1 ) );
         i1++)
    {
        ;
    }
    for (i2 = 0, k2 = 0;
         i2 < MAX_NUM_STEREO_BONDS &&
         ( s2 = at[cur2].stereo_bond_neighbor[i2] ) &&
            !( k2 = ( at[cur2].neighbor[(int) at[cur2].stereo_bond_ord[i2]] == *n2 ) );
         i2++)
    {
        ;
    }
    if (k1 != k2)
    {
        return 0; 
    }
    if (k1  &&
        ( at[cur1].stereo_bond_parity[i1] != at[cur2].stereo_bond_parity[i2] ||
            !PARITY_WELL_DEF( at[cur1].stereo_bond_parity[i1] ) 
            ))
    {
        return 0; 
    }
    return 1; 
}
int GetAndCheckNextNeighbors ( sp_ATOM * at , AT_RANK cur1 , AT_RANK prev1 , AT_RANK cur2 , AT_RANK prev2 , AT_RANK * n1 , AT_RANK * n2 , AT_RANK * nVisited1 , AT_RANK * nVisited2 , const AT_RANK * nRank , const AT_RANK * nCanonRank ) { AT_RANK cr1 , cr2 , s1 , s2 ; int i1 , i2 , k1 , k2 ; cr1 = ( * n1 > MAX_ATOMS ) ? 0 : nCanonRank [ ( int ) * n1 ] ; cr2 = ( * n2 > MAX_ATOMS ) ? 0 : nCanonRank [ ( int ) * n2 ] ; if ( ! GetNextNeighborAndRank ( at , cur1 , prev1 , n1 , & cr1 , nCanonRank ) || ! GetNextNeighborAndRank ( at , cur2 , prev2 , n2 , & cr2 , nCanonRank ) || nRank [ ( int ) * n1 ] != nRank [ ( int ) * n2 ] || nVisited1 [ ( int ) * n1 ] != nVisited2 [ ( int ) * n2 ] ) { return 0 ; } for ( i1 = 0 , k1 = 0 ; i1 < MAX_NUM_STEREO_BONDS && ( s1 = at [ cur1 ] . stereo_bond_neighbor [ i1 ] ) && ! ( k1 = ( at [ cur1 ] . neighbor [ ( int ) at [ cur1 ] . stereo_bond_ord [ i1 ] ] == * n1 ) ) ; i1 ++ ) { ; } for ( i2 = 0 , k2 = 0 ; i2 < MAX_NUM_STEREO_BONDS && ( s2 = at [ cur2 ] . stereo_bond_neighbor [ i2 ] ) && ! ( k2 = ( at [ cur2 ] . neighbor [ ( int ) at [ cur2 ] . stereo_bond_ord [ i2 ] ] == * n2 ) ) ; i2 ++ ) { ; } if ( k1 != k2 ) { return 0 ; } if ( k1 && ( at [ cur1 ] . stereo_bond_parity [ i1 ] != at [ cur2 ] . stereo_bond_parity [ i2 ] || ! PARITY_WELL_DEF ( at [ cur1 ] . stereo_bond_parity [ i1 ] ) ) ) { return 0 ; } return 1 ; }
Find next pair of neighbors having the next greater canon.
Find next pair of neighbors having the next greater canon .
/*  program error; no breakpoint here */ /*   <BRKPT> */ /*  Even though the bond or cumulene might have already been checked, check it: this is */ /*  the only place we can check stereo bonds and cumulenes that are not edges of the DFS tree */ /*  The code works both for a stereo bond and a stereogenic cumulene. */ /*  possibly not an error: constit. equivalent atoms on a stereo bond and not on a stereo bond */ /* yes, it is a stereo bond */ /* PARITY_KNOWN (at[cur1].stereo_bond_parity[i1] ) */ /*  replaced 08-13-2002 with the next: */ /*  it suffices to check only one parity */ /*  different or (currently) unknown stereo bond parities */ /*  stereo bonds have known parities */