rino 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. data/Rakefile +1 -1
  2. data/ext/extconf.rb +1 -24
  3. data/ext/libinchi.so +0 -0
  4. data/ext/src/aux2atom.h +120 -39
  5. data/ext/src/comdef.h +3 -3
  6. data/ext/src/dispstru.c +2547 -0
  7. data/ext/src/dispstru.h +73 -0
  8. data/ext/src/extr_ct.h +5 -2
  9. data/ext/src/ichi.h +27 -11
  10. data/ext/src/ichi_bns.c +1800 -254
  11. data/ext/src/ichi_bns.h +205 -4
  12. data/ext/src/ichican2.c +197 -86
  13. data/ext/src/ichicano.c +8 -13
  14. data/ext/src/ichicano.h +2 -2
  15. data/ext/src/ichicans.c +11 -6
  16. data/ext/src/ichicant.h +2 -2
  17. data/ext/src/ichicomn.h +2 -2
  18. data/ext/src/ichicomp.h +19 -4
  19. data/ext/src/ichidrp.h +9 -5
  20. data/ext/src/ichierr.h +5 -3
  21. data/ext/src/ichiisot.c +2 -2
  22. data/ext/src/ichimain.c +461 -0
  23. data/ext/src/ichimain.h +23 -15
  24. data/ext/src/ichimak2.c +6 -6
  25. data/ext/src/ichimake.c +843 -42
  26. data/ext/src/ichimake.h +4 -2
  27. data/ext/src/ichimap1.c +5 -5
  28. data/ext/src/ichimap2.c +2 -2
  29. data/ext/src/ichimap4.c +34 -21
  30. data/ext/src/ichinorm.c +11 -5
  31. data/ext/src/ichinorm.h +3 -2
  32. data/ext/src/ichiparm.c +2 -2
  33. data/ext/src/ichiparm.h +232 -30
  34. data/ext/src/ichiprt1.c +35 -11
  35. data/ext/src/ichiprt2.c +78 -7
  36. data/ext/src/ichiprt3.c +300 -120
  37. data/ext/src/ichiqueu.c +17 -2
  38. data/ext/src/ichiread.c +6932 -0
  39. data/ext/src/ichiring.c +3 -2
  40. data/ext/src/ichiring.h +2 -2
  41. data/ext/src/ichirvr1.c +4891 -0
  42. data/ext/src/ichirvr2.c +6344 -0
  43. data/ext/src/ichirvr3.c +5499 -0
  44. data/ext/src/ichirvr4.c +3177 -0
  45. data/ext/src/ichirvr5.c +1166 -0
  46. data/ext/src/ichirvr6.c +1287 -0
  47. data/ext/src/ichirvr7.c +2319 -0
  48. data/ext/src/ichirvrs.h +882 -0
  49. data/ext/src/ichisize.h +2 -2
  50. data/ext/src/ichisort.c +5 -5
  51. data/ext/src/ichister.c +281 -86
  52. data/ext/src/ichister.h +9 -3
  53. data/ext/src/ichitaut.c +208 -9
  54. data/ext/src/ichitaut.h +13 -11
  55. data/ext/src/ichitime.h +16 -2
  56. data/ext/src/inchicmp.h +107 -0
  57. data/ext/src/inpdef.h +6 -3
  58. data/ext/src/libinchi_wrap.c +912 -0
  59. data/ext/src/lreadmol.h +34 -31
  60. data/ext/src/mode.h +244 -7
  61. data/ext/src/mol2atom.c +1060 -0
  62. data/ext/src/mol2atom.h +31 -0
  63. data/ext/src/readinch.c +239 -0
  64. data/ext/src/readmol.c +28 -0
  65. data/ext/src/{e_readmol.h → readmol.h} +7 -9
  66. data/ext/src/runichi.c +251 -177
  67. data/ext/src/strutil.c +444 -238
  68. data/ext/src/strutil.h +150 -11
  69. data/ext/src/util.c +176 -118
  70. data/ext/src/util.h +15 -3
  71. data/lib/rino.rb +71 -3
  72. data/test/test.rb +33 -4
  73. metadata +22 -34
  74. data/ext/ruby_inchi_main.so +0 -0
  75. data/ext/src/e_0dstereo.c +0 -3014
  76. data/ext/src/e_0dstereo.h +0 -31
  77. data/ext/src/e_comdef.h +0 -57
  78. data/ext/src/e_ctl_data.h +0 -147
  79. data/ext/src/e_ichi_io.c +0 -498
  80. data/ext/src/e_ichi_io.h +0 -40
  81. data/ext/src/e_ichi_parms.c +0 -37
  82. data/ext/src/e_ichi_parms.h +0 -41
  83. data/ext/src/e_ichicomp.h +0 -50
  84. data/ext/src/e_ichierr.h +0 -40
  85. data/ext/src/e_ichimain.c +0 -593
  86. data/ext/src/e_ichisize.h +0 -43
  87. data/ext/src/e_inchi_atom.c +0 -75
  88. data/ext/src/e_inchi_atom.h +0 -33
  89. data/ext/src/e_inpdef.h +0 -41
  90. data/ext/src/e_mode.h +0 -706
  91. data/ext/src/e_mol2atom.c +0 -649
  92. data/ext/src/e_readinch.c +0 -58
  93. data/ext/src/e_readmol.c +0 -54
  94. data/ext/src/e_readstru.c +0 -251
  95. data/ext/src/e_readstru.h +0 -33
  96. data/ext/src/e_util.c +0 -284
  97. data/ext/src/e_util.h +0 -61
  98. data/ext/src/ichilnct.c +0 -286
  99. data/ext/src/inchi_api.h +0 -670
  100. data/ext/src/inchi_dll.c +0 -1480
  101. data/ext/src/inchi_dll.h +0 -34
  102. data/ext/src/inchi_dll_main.c +0 -23
  103. data/ext/src/inchi_dll_main.h +0 -31
  104. data/ext/src/ruby_inchi_main.c +0 -558
@@ -2,8 +2,8 @@
2
2
  * International Union of Pure and Applied Chemistry (IUPAC)
3
3
  * International Chemical Identifier (InChI)
4
4
  * Version 1
5
- * Software version 1.00
6
- * April 13, 2005
5
+ * Software version 1.01
6
+ * July 21, 2006
7
7
  * Developed at NIST
8
8
  */
9
9
 
@@ -73,7 +73,11 @@ const char x_message[] = "message";
73
73
  const char x_text[] = "value";
74
74
 
75
75
  const char x_ferr[] = "fatal (aborted)";
76
+ #if( SPECIAL_BUILD == 1 )
77
+ const char x_err[] = "error (no MoChI)";
78
+ #else
76
79
  const char x_err[] = "error (no InChI)";
80
+ #endif
77
81
  const char x_warn[] = "warning";
78
82
 
79
83
  const char x_basic[] = "identifier";
@@ -338,7 +342,7 @@ typedef struct tagXmlEntityRef {
338
342
  char nChar;
339
343
  const char *pRef;
340
344
  } X_REF;
341
- X_REF xmlRef[] = { {'<', "&lt;"}, {'&', "&amp;"}, {'>', "&gt;"}, {'"', "&quot;"}, {'\'', "&apos;"}, {0, NULL}, };
345
+ const X_REF xmlRef[] = { {'<', "&lt;"}, {'&', "&amp;"}, {'>', "&gt;"}, {'"', "&quot;"}, {'\'', "&apos;"}, {0, NULL}, };
342
346
  const char szRefChars[sizeof(xmlRef)/sizeof(xmlRef[0])] = {'<', '&', '>', '"', '\'', '\0' };
343
347
  /**********************************************************************************************/
344
348
  int PrintXmlStartTag( char *pStr, int indent, int bEnd, const char *tag,
@@ -651,6 +655,14 @@ const char *EquString( int EquVal )
651
655
  int bEq2 = EquVal & (iiEq2NONTAUT | iiEq2ISO | iiEq2INV );
652
656
  const char *r = "";
653
657
 
658
+ #if ( FIX_EMPTY_LAYER_BUG == 1 )
659
+ int bEmpty= EquVal & iiEmpty;
660
+ if ( bEmpty ) {
661
+ r = "e";
662
+ return r;
663
+ }
664
+ #endif
665
+
654
666
  switch ( bFrom ) {
655
667
 
656
668
  case iiSTEREO: /* ------------ Stereo --------------------*/
@@ -1694,7 +1706,7 @@ int OutputINChI1( char *pStr, int nStrLen, INCHI_SORT *pINChISortTautAndNonTaut2
1694
1706
  }
1695
1707
  inchi_print( output_file, "%s%s", pStr, pTAB );
1696
1708
  }
1697
- inchi_print( output_file, "%s%s=%s", pLF, INCHI_NAME, pLF );
1709
+ inchi_print( output_file, "%s%s=%s", pLF, (FLAG_SORT_PRINT_ReChI_PREFIX & *pSortPrintINChIFlags)? INCHI_REC_NAME : INCHI_NAME, pLF );
1698
1710
  }
1699
1711
  /*****************************************************
1700
1712
  *
@@ -3127,7 +3139,7 @@ int WriteOrigCoord( int num_inp_atoms, MOL_COORD *szMolCoord, int *i, char *szBu
3127
3139
  */
3128
3140
  int WriteOrigAtoms( int num_inp_atoms, inp_ATOM *at, int *i, char *szBuf, int buf_len, STRUCT_DATA *sd)
3129
3141
  {
3130
- int j, k, n, len, len0, cur_len, val, mw, parity, num_trans, is_ok, b_self;
3142
+ int j, k, n, len, len0, cur_len, val, bonds_val, mw, parity, num_trans, is_ok, b_self;
3131
3143
  static char szIsoH[] = "hdt";
3132
3144
  char szCurAtom[32];
3133
3145
  AT_NUMB nNeighOrder[MAXVAL], neigh;
@@ -3179,8 +3191,10 @@ int WriteOrigAtoms( int num_inp_atoms, inp_ATOM *at, int *i, char *szBuf, int bu
3179
3191
 
3180
3192
  len = len0 = strlen( at[j].elname );
3181
3193
  memcpy( szCurAtom, at[j].elname, len );
3194
+ bonds_val = nBondsValenceInpAt( at+j, NULL, NULL );
3195
+
3182
3196
  if ( (val=needed_unusual_el_valence( at[j].el_number, at[j].charge, at[j].radical,
3183
- at[j].chem_bonds_valence, at[j].num_H, at[j].valence )) ||
3197
+ at[j].chem_bonds_valence, bonds_val, at[j].num_H, at[j].valence )) ||
3184
3198
  at[j].charge || at[j].radical || at[j].iso_atw_diff || NUM_ISO_H(at,j) || parity ) {
3185
3199
  /* valence */
3186
3200
  if ( val ) {
@@ -3248,7 +3262,6 @@ int WriteOrigAtoms( int num_inp_atoms, inp_ATOM *at, int *i, char *szBuf, int bu
3248
3262
 
3249
3263
  b = bond type:
3250
3264
  =============
3251
- v = undefined stereo, single
3252
3265
  w = undefined stereo, double
3253
3266
  s = single
3254
3267
  d = double
@@ -3256,6 +3269,8 @@ t = triple
3256
3269
  a = aromatic
3257
3270
  p = up from the current atom to the neighbor
3258
3271
  P = uP from the neighbor to the current atom
3272
+ v = undefined stereo Either, single from the current atom to the neighbor
3273
+ V = undefined stereo Either, single from the neighbor to the current atom
3259
3274
  n = down from the current atom to the neighbor
3260
3275
  N = dowN from the neighbor to the current atom
3261
3276
 
@@ -3268,9 +3283,9 @@ u = unknown
3268
3283
  = no parity (empty)
3269
3284
 
3270
3285
 
3271
- A=orig. number
3286
+ A = neighbor orig. atom number
3272
3287
  ===============
3273
- of the neighbor < number of the current atom
3288
+ neighbor orig. atom number < number of the current atom
3274
3289
  Number of the current atom: 2 until first ";", 3 until 2nd ";", etc.
3275
3290
 
3276
3291
  */
@@ -3280,7 +3295,7 @@ Number of the current atom: 2 until first ";", 3 until 2nd ";", etc.
3280
3295
  int WriteOrigBonds( int num_inp_atoms, inp_ATOM *at, int *i, char *szBuf, int buf_len, STRUCT_DATA *sd)
3281
3296
  {
3282
3297
  int j, k, k2, kk, len, cur_len, j2=0, bond_stereo, bond_char, bond_parity, bond_parityNM, num_trans;
3283
- char szCurBonds[5*MAXVAL+1+2*MAXVAL]; /* 1 byte bond type + up to 4 digits per neighbor number + 1 + 2*sign for bond parity; */
3298
+ char szCurBonds[7*MAXVAL+2]; /* num_neigh*(1 byte bond type + 2 bytes for bond parity up to 4 digits per neighbor number) + at the end one ';' */
3284
3299
  AT_RANK nNeighOrder[MAXVAL];
3285
3300
  int chain_len, pnxt_atom, pinxt2cur, pinxt_sb_parity_ord;
3286
3301
  int chain_len2, pnxt_atom2, pinxt2cur2, pinxt_sb_parity_ord2, m1, m2;
@@ -3321,10 +3336,19 @@ int WriteOrigBonds( int num_inp_atoms, inp_ATOM *at, int *i, char *szBuf, int bu
3321
3336
  case -STEREO_SNGL_DOWN:
3322
3337
  bond_char = 'N';
3323
3338
  break;
3339
+ #if( FIX_EITHER_STEREO_IN_AUX_INFO == 1 )
3340
+ case STEREO_SNGL_EITHER:
3341
+ bond_char = 'v';
3342
+ break;
3343
+ case -STEREO_SNGL_EITHER:
3344
+ bond_char = 'V';
3345
+ break;
3346
+ #else
3324
3347
  case STEREO_SNGL_EITHER:
3325
3348
  case -STEREO_SNGL_EITHER:
3326
3349
  bond_char = 'v';
3327
3350
  break;
3351
+ #endif
3328
3352
  default:
3329
3353
  bond_char = 's';
3330
3354
  break;
@@ -3523,7 +3547,7 @@ int WriteOrigBonds( int num_inp_atoms, inp_ATOM *at, int *i, char *szBuf, int bu
3523
3547
  }
3524
3548
 
3525
3549
 
3526
- #define ORIG_STR_BUFLEN 64 /* > 5*MAXVAL+2 = 52 */
3550
+ #define ORIG_STR_BUFLEN (7*MAXVAL+2) /* > 7*MAXVAL+2 = 142 */
3527
3551
  /******************************************************************************************/
3528
3552
  int FillOutOrigStruct( ORIG_ATOM_DATA *orig_inp_data, ORIG_STRUCT *pOrigStruct, STRUCT_DATA *sd )
3529
3553
  {
@@ -2,8 +2,8 @@
2
2
  * International Union of Pure and Applied Chemistry (IUPAC)
3
3
  * International Chemical Identifier (InChI)
4
4
  * Version 1
5
- * Software version 1.00
6
- * April 13, 2005
5
+ * Software version 1.01
6
+ * July 21, 2006
7
7
  * Developed at NIST
8
8
  */
9
9
 
@@ -1403,7 +1403,22 @@ int MakeStereoString( AT_NUMB *at1, AT_NUMB *at2, S_CHAR *parity, int bAddDelim,
1403
1403
  *bOverflow |= bOvfl;
1404
1404
  return nLen;
1405
1405
  }
1406
+ #ifdef ALPHA_BASE
1406
1407
 
1408
+ #if( ALPHA_BASE != 27 )
1409
+ #error ALPHA_BASE definitions mismatch
1410
+ #endif
1411
+
1412
+ #else
1413
+
1414
+ #define ALPHA_BASE 27
1415
+
1416
+ #endif
1417
+
1418
+ #define ALPHA_MINUS '-'
1419
+ #define ALPHA_ZERO_VAL '.'
1420
+ #define ALPHA_ONE 'a'
1421
+ #define ALPHA_ZERO '@'
1407
1422
  /**********************************************************************************************/
1408
1423
  /* Produce an "Alphabetic" number, base 27 (27 digits: 0, a, b, ..., z) */
1409
1424
  /* The leading "digit" uppercase, the rest -- lowercase */
@@ -1412,11 +1427,6 @@ int MakeStereoString( AT_NUMB *at1, AT_NUMB *at2, S_CHAR *parity, int bAddDelim,
1412
1427
  /* Note: ASCII-encoding specific implementation */
1413
1428
  int MakeAbcNumber( char *szString, int nStringLen, const char *szLeadingDelim, int nValue )
1414
1429
  {
1415
- #define ALPHA_BASE 27
1416
- #define ALPHA_MINUS '-'
1417
- #define ALPHA_ZERO_VAL '.'
1418
- #define ALPHA_ONE 'a'
1419
- #define ALPHA_ZERO '@'
1420
1430
  char *p = szString;
1421
1431
  char *q;
1422
1432
  int nChar;
@@ -1452,12 +1462,73 @@ int MakeAbcNumber( char *szString, int nStringLen, const char *szLeadingDelim, i
1452
1462
  mystrrev( p );
1453
1463
  p[0] = toupper(p[0]);
1454
1464
  return (q - szString);
1465
+ }
1466
+ #if( READ_INCHI_STRING == 1 )
1467
+ /*****************************************************/
1468
+ static long abctol( const char *szString, char **q ); /* keep compiler happy */
1469
+
1470
+ long abctol( const char *szString, char **q )
1471
+ {
1472
+ #define __MYTOLOWER(c) ( ((c) >= 'A') && ((c) <= 'Z') ? ((c) - 'A' + 'a') : (c) )
1473
+
1474
+ long val = 0;
1475
+ long sign = 1;
1476
+ const char *p = szString;
1477
+ if ( *p == ALPHA_MINUS ) {
1478
+ p ++;
1479
+ sign = -1;
1480
+ }
1481
+ if ( *p == ALPHA_ZERO ) {
1482
+ p ++;
1483
+ goto exit_function;
1484
+ }
1485
+ if ( !isupper(UCINT *p) ) {
1486
+ p = szString;
1487
+ goto exit_function; /* not an abc-number */
1488
+ }
1489
+ val = __MYTOLOWER(*p) - ALPHA_ONE + 1;
1490
+ p ++;
1491
+ while ( *p ) {
1492
+ if ( islower( UCINT *p ) ) {
1493
+ val *= ALPHA_BASE;
1494
+ val += *p - ALPHA_ONE + 1;
1495
+ } else
1496
+ if ( *p == ALPHA_ZERO ) {
1497
+ val *= ALPHA_BASE;
1498
+ } else {
1499
+ break;
1500
+ }
1501
+ p ++;
1502
+ }
1503
+ exit_function:
1504
+ if ( q ) {
1505
+ *q = (char *)p; /* cast deliberately discards const qualifier */
1506
+ }
1507
+ return val;
1508
+ #undef __MYTOLOWER
1509
+ }
1510
+ /********************************************************/
1511
+ long inchi_strtol( const char *str, const char **p, int base)
1512
+ {
1513
+ if ( base == ALPHA_BASE ) {
1514
+ return abctol( str, (char **)p ); /* cast deliberately discards const qualifier */
1515
+ } else {
1516
+ return strtol( str, (char **)p, base ); /* cast deliberately discards const qualifier */
1517
+ }
1518
+ }
1519
+ #endif
1455
1520
  #undef ALPHA_BASE
1456
1521
  #undef ALPHA_MINUS
1457
1522
  #undef ALPHA_ZERO_VAL
1458
1523
  #undef ALPHA_ONE
1459
1524
  #undef ALPHA_ZERO
1525
+
1526
+ /********************************************************/
1527
+ double inchi_strtod( const char *str, const char **p )
1528
+ {
1529
+ return strtod( str, (char **)p );
1460
1530
  }
1531
+
1461
1532
  /**********************************************************************************************/
1462
1533
  /* Produce a decimal number */
1463
1534
  /* szString length nStringLen includes 1 byte for zero termination */
@@ -2,8 +2,8 @@
2
2
  * International Union of Pure and Applied Chemistry (IUPAC)
3
3
  * International Chemical Identifier (InChI)
4
4
  * Version 1
5
- * Software version 1.00
6
- * April 13, 2005
5
+ * Software version 1.01
6
+ * July 21, 2006
7
7
  * Developed at NIST
8
8
  */
9
9
 
@@ -36,7 +36,7 @@ int str_Sp2(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int nSt
36
36
  int bSecondNonTautPass, int bOmitRepetitions, int bUseMulipliers)
37
37
  {
38
38
  int i, ii, ii2;
39
- INCHI_SORT *is, *is2;
39
+ INCHI_SORT *is, *is2, *is0, *is20;
40
40
  INChI *pINChI, *pINChI_Prev, *pINChI_Taut, *pINChI_Taut_Prev;
41
41
  INChI_Stereo *Stereo, *Stereo_Prev, *Stereo_Taut, *Stereo_Taut_Prev;
42
42
  int mult, eq2prev, eq2taut, eq2tautPrev, bNext;
@@ -48,27 +48,46 @@ int str_Sp2(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int nSt
48
48
  pINChI_Taut_Prev = NULL;
49
49
  mult = 0;
50
50
  bNext = 0;
51
- is2 = bSecondNonTautPass? pINChISort2 : NULL;
51
+ is = NULL;
52
+ is2 = NULL;
53
+ is0 = pINChISort;
54
+ is20 = bSecondNonTautPass? pINChISort2 : NULL;
52
55
  eq2taut = 0; /* may be non-zero only on the 2nd (non-taut) pass */
53
56
  eq2tautPrev = 1; /* pINChI_Prev (previous pINChI) does not exist */
54
57
  pPrevEquStr = NULL; /*, *pCurrEquStr;*/
55
58
  multPrevEquStr = 0;
56
- for ( i = 0, is = pINChISort; i <= num_components; i ++, is ++, (bSecondNonTautPass? is2++ : 0) ) {
59
+ for ( i = 0; i <= num_components; i ++ ) {
57
60
  /* 1st (taut) pass: bOutType=OUT_TN ; 2nd (non-taut pass) bOutType=OUT_NT */
58
- pINChI = (i < num_components && 0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
61
+ pINChI = (i < num_components && (is=is0+i, 0 <= (ii=GET_II(bOutType,is))))? is->pINChI[ii] : NULL;
59
62
  /*================ compare sp2 to previous =====================*/
60
63
  if ( bSecondNonTautPass ) {
61
64
  /* component that was output on the 1st pass */
62
- pINChI_Taut = ( i < num_components && 0 <= (ii2=GET_II(OUT_T1,is2)))? is2->pINChI[ii2] : NULL;
65
+ pINChI_Taut = ( i < num_components && (is2=is20+i, 0 <= (ii2=GET_II(OUT_T1,is2))))? is2->pINChI[ii2] : NULL;
63
66
  }
64
67
  /*========= if bSecondNonTautPass then compare non-iso non-taut stereo to non-iso taut ========*/
65
68
  eq2taut = 0;
69
+ #if ( FIX_EMPTY_LAYER_BUG == 1 )
70
+ if ( !eq2taut && bSecondNonTautPass && bOmitRepetitions && pINChI && pINChI_Taut ) {
71
+ Stereo = pINChI->Stereo;
72
+ Stereo_Taut = pINChI_Taut->Stereo;
73
+ eq2taut = Stereo && Stereo_Taut &&
74
+ Eql_INChI_Stereo( Stereo, EQL_SP2, Stereo_Taut, EQL_SP2, 0 );
75
+ eq2taut = eq2taut? (iiSTEREO | iitNONTAUT) : 0;
76
+
77
+ if ( !eq2taut &&
78
+ !Eql_INChI_Stereo( Stereo, EQL_SP2, NULL, EQL_EXISTS, 0 ) &&
79
+ Eql_INChI_Stereo( Stereo_Taut, EQL_SP2, NULL, EQL_EXISTS, 0 ) ) {
80
+ eq2taut = iiEmpty; /* the current is empty while the preceding (taut) is not */
81
+ }
82
+ }
83
+ #else
66
84
  if ( !eq2taut && bSecondNonTautPass && bOmitRepetitions ) {
67
85
  eq2taut = pINChI && pINChI_Taut &&
68
86
  (Stereo = pINChI->Stereo) && (Stereo_Taut = pINChI_Taut->Stereo) &&
69
87
  Eql_INChI_Stereo( Stereo, EQL_SP2, Stereo_Taut, EQL_SP2, 0 );
70
88
  eq2taut = eq2taut? (iiSTEREO | iitNONTAUT) : 0;
71
89
  }
90
+ #endif
72
91
  if ( eq2taut ) {
73
92
  /* we may be here only in case of the second (non-taut) pass */
74
93
  /* current non-taut stereo has been found to be same as tautomeric */
@@ -100,7 +119,7 @@ int str_Sp2(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int nSt
100
119
  if ( pCurrEquStr && !strcmp(pCurrEquStr, pPrevEquStr) ) {
101
120
  multPrevEquStr ++;
102
121
  } else {
103
- /* new EqStr is different; output it */
122
+ /* new EqStr is different; output the previous one */
104
123
  if ( bNext ++ ) {
105
124
  tot_len += MakeDelim( sCompDelim, pStr + tot_len, nStrLen-tot_len, bOverflow);
106
125
  }
@@ -191,7 +210,7 @@ int str_Sp3(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int nSt
191
210
  int bSecondNonTautPass, int bOmitRepetitions, int bUseMulipliers)
192
211
  {
193
212
  int i, ii, ii2;
194
- INCHI_SORT *is, *is2;
213
+ INCHI_SORT *is, *is2, *is0, *is20;
195
214
  INChI *pINChI, *pINChI_Prev, *pINChI_Taut, *pINChI_Taut_Prev;
196
215
  INChI_Stereo *Stereo, *Stereo_Prev, *Stereo_Taut, *Stereo_Taut_Prev;
197
216
  int mult, eq2prev, eq2taut, eq2tautPrev, bNext;
@@ -202,7 +221,10 @@ int str_Sp3(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int nSt
202
221
  pINChI_Taut_Prev = NULL;
203
222
  mult = 0;
204
223
  bNext = 0;
205
- is2 = bSecondNonTautPass? pINChISort2 : NULL;
224
+ is = NULL;
225
+ is2 = NULL;
226
+ is0 = pINChISort;
227
+ is20 = bSecondNonTautPass? pINChISort2 : NULL;
206
228
  eq2taut = 0; /* may be non-zero only on the 2nd (non-taut) pass */
207
229
  eq2tautPrev = 1; /* pINChI_Prev (previous pINChI) does not exist */
208
230
  pPrevEquStr = NULL; /*, *pCurrEquStr;*/
@@ -211,22 +233,37 @@ int str_Sp3(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int nSt
211
233
  #else
212
234
  bRelRac = 0;
213
235
  #endif
214
- for ( i = 0, is = pINChISort; i <= num_components; i ++, is ++, (bSecondNonTautPass? is2++ : 0) ) {
236
+ for ( i = 0; i <= num_components; i ++ ) {
215
237
  /* 1st (taut) pass: bOutType=OUT_TN ; 2nd (non-taut pass) bOutType=OUT_NT */
216
- pINChI = (i < num_components && 0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
238
+ pINChI = (i < num_components && (is=is0+i, 0 <= (ii=GET_II(bOutType,is))))? is->pINChI[ii] : NULL;
217
239
  /*================ compare sp3 to previous =====================*/
218
240
  if ( bSecondNonTautPass ) {
219
241
  /* component that was output on the 1st pass */
220
- pINChI_Taut = ( i < num_components && 0 <= (ii2=GET_II(OUT_T1,is2)))? is2->pINChI[ii2] : NULL;
242
+ pINChI_Taut = ( i < num_components && (is2=is20+i, 0 <= (ii2=GET_II(OUT_T1,is2))))? is2->pINChI[ii2] : NULL;
221
243
  }
222
244
  /*========= if bSecondNonTautPass then compare non-iso non-taut stereo to non-iso taut ========*/
223
245
  eq2taut = 0;
246
+ #if ( FIX_EMPTY_LAYER_BUG == 1 )
247
+ if ( !eq2taut && bSecondNonTautPass && bOmitRepetitions && pINChI && pINChI_Taut ) {
248
+ Stereo = pINChI->Stereo;
249
+ Stereo_Taut = pINChI_Taut->Stereo;
250
+ eq2taut = Stereo && Stereo_Taut &&
251
+ Eql_INChI_Stereo( Stereo, EQL_SP3, Stereo_Taut, EQL_SP3, bRelRac );
252
+ eq2taut = eq2taut? (iiSTEREO | iitNONTAUT) : 0;
253
+ if ( !eq2taut &&
254
+ !Eql_INChI_Stereo( Stereo, EQL_SP3, NULL, EQL_EXISTS, 0 ) &&
255
+ Eql_INChI_Stereo( Stereo_Taut, EQL_SP3, NULL, EQL_EXISTS, 0 ) ) {
256
+ eq2taut = iiEmpty; /* the current is empty while the preceding (taut) is not */
257
+ }
258
+ }
259
+ #else
224
260
  if ( !eq2taut && bSecondNonTautPass && bOmitRepetitions ) {
225
261
  eq2taut = pINChI && pINChI_Taut &&
226
262
  (Stereo = pINChI->Stereo) && (Stereo_Taut = pINChI_Taut->Stereo) &&
227
263
  Eql_INChI_Stereo( Stereo, EQL_SP3, Stereo_Taut, EQL_SP3, bRelRac );
228
264
  eq2taut = eq2taut? (iiSTEREO | iitNONTAUT) : 0;
229
265
  }
266
+ #endif
230
267
  if ( eq2taut ) {
231
268
  /* we may be here only in case of the second (non-taut) pass */
232
269
  /* current non-taut stereo has been found to be same as tautomeric */
@@ -350,7 +387,7 @@ int str_IsoAtoms(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, in
350
387
  int bSecondNonTautPass, int bOmitRepetitions, int bUseMulipliers)
351
388
  {
352
389
  int i, ii, ii2;
353
- INCHI_SORT *is, *is2;
390
+ INCHI_SORT *is, *is2, *is0, *is20;
354
391
  INChI *pINChI, *pINChI_Prev, *pINChI_Taut, *pINChI_Taut_Prev;
355
392
  int mult, eq2prev, eq2taut, eq2tautPrev, bNext;
356
393
  const char *pPrevEquStr, *pCurrEquStr;
@@ -360,18 +397,21 @@ int str_IsoAtoms(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, in
360
397
  pINChI_Taut_Prev = NULL;
361
398
  mult = 0;
362
399
  bNext = 0;
363
- is2 = bSecondNonTautPass? pINChISort2 : NULL;
400
+ is = NULL;
401
+ is2 = NULL;
402
+ is0 = pINChISort;
403
+ is20 = bSecondNonTautPass? pINChISort2 : NULL;
364
404
  eq2taut = 0; /* may be non-zero only on the 2nd (non-taut) pass */
365
405
  eq2tautPrev = 1; /* pINChI_Prev (previous pINChI) does not exist */
366
406
  pPrevEquStr = NULL; /*, *pCurrEquStr;*/
367
407
  multPrevEquStr = 0;
368
- for ( i = 0, is = pINChISort; i <= num_components; i ++, is ++, (bSecondNonTautPass? is2++ : 0) ) {
408
+ for ( i = 0; i <= num_components; i ++ ) {
369
409
  /* 1st (taut) pass: bOutType=OUT_TN ; 2nd (non-taut pass) bOutType=OUT_NT */
370
- pINChI = (i < num_components && 0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
410
+ pINChI = (i < num_components && (is=is0+i, 0 <= (ii=GET_II(bOutType,is))))? is->pINChI[ii] : NULL;
371
411
  /*================ compare isotopic info to previous component =====================*/
372
412
  if ( bSecondNonTautPass ) {
373
413
  /* component that was output on the 1st pass */
374
- pINChI_Taut = ( i < num_components && 0 <= (ii2=GET_II(OUT_T1,is2)))? is2->pINChI[ii2] : NULL;
414
+ pINChI_Taut = ( i < num_components && (is2=is20+i, 0 <= (ii2=GET_II(OUT_T1,is2))))? is2->pINChI[ii2] : NULL;
375
415
  }
376
416
  /*========= if bSecondNonTautPass then compare iso non-taut to taut non-iso ========*/
377
417
  eq2taut = 0;
@@ -526,7 +566,7 @@ int str_IsoSp2(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int
526
566
  int bSecondNonTautPass, int bOmitRepetitions, int bUseMulipliers)
527
567
  {
528
568
  int i, ii, ii2;
529
- INCHI_SORT *is, *is2;
569
+ INCHI_SORT *is, *is2, *is0, *is20;
530
570
  INChI *pINChI, *pINChI_Prev, *pINChI_Taut, *pINChI_Taut_Prev;
531
571
  INChI_Stereo *Stereo, *Stereo_Prev, *Stereo_Taut, *Stereo_Taut_Prev;
532
572
  int mult, eq2prev, eq2taut, eq2tautPrev, bNext;
@@ -537,18 +577,21 @@ int str_IsoSp2(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int
537
577
  pINChI_Taut_Prev = NULL;
538
578
  mult = 0;
539
579
  bNext = 0;
540
- is2 = bSecondNonTautPass? pINChISort2 : NULL;
580
+ is = NULL;
581
+ is2 = NULL;
582
+ is0 = pINChISort;
583
+ is20 = bSecondNonTautPass? pINChISort2 : NULL;
541
584
  eq2taut = 0; /* may be non-zero if another layer of the current component = current layer */
542
585
  eq2tautPrev = 1; /* pINChI_Prev (previous pINChI) does not exist */
543
586
  pPrevEquStr = NULL; /*, *pCurrEquStr;*/
544
587
  multPrevEquStr = 0;
545
- for ( i = 0, is = pINChISort; i <= num_components; i ++, is ++, (bSecondNonTautPass? is2++ : 0) ) {
588
+ for ( i = 0; i <= num_components; i ++ ) {
546
589
  /* 1st (taut) pass: bOutType=OUT_TN ; 2nd (non-taut pass) bOutType=OUT_NT */
547
- pINChI = (i < num_components && 0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
590
+ pINChI = (i < num_components && (is=is0+i, 0 <= (ii=GET_II(bOutType,is))))? is->pINChI[ii] : NULL;
548
591
  /*================ compare sp2 to previous =====================*/
549
592
  if ( bSecondNonTautPass ) {
550
593
  /* component that was output on the 1st pass */
551
- pINChI_Taut = ( i < num_components && 0 <= (ii2=GET_II(OUT_T1,is2)))? is2->pINChI[ii2] : NULL;
594
+ pINChI_Taut = ( i < num_components && (is2=is20+i, 0 <= (ii2=GET_II(OUT_T1,is2))))? is2->pINChI[ii2] : NULL;
552
595
  }
553
596
  eq2taut = 0;
554
597
  /*========= if bSecondNonTautPass then compare iso non-taut stereo to other stereo ========*/
@@ -556,7 +599,7 @@ int str_IsoSp2(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int
556
599
  /* compare non-tautomeric isotopic to:
557
600
  * a) non-tautomeric non-isotopic
558
601
  * b) tautomeric non-isotopic
559
- * c) tautomeric non-isotopic and isotopic
602
+ * c) tautomeric isotopic
560
603
  */
561
604
  /* a) compare non-tautomeric isotopic to non-tautomeric non-isotopic */
562
605
  if ( !eq2taut ) {
@@ -584,6 +627,21 @@ int str_IsoSp2(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int
584
627
  /* stereo isotopic non-taut = isotopic taut (stereo) */
585
628
  eq2taut = eq2taut? (iiSTEREO | iitISO | iitNONTAUT | iiEq2ISO) : 0;
586
629
  }
630
+ #if ( FIX_EMPTY_LAYER_BUG == 1 )
631
+ if ( !eq2taut && pINChI && !((Stereo = pINChI->StereoIsotopic) &&
632
+ Eql_INChI_Stereo( Stereo, EQL_SP2, NULL, EQL_EXISTS, 0 )) ) {
633
+ /* component has no stereo; check whether it has stereo in the preceding layers */
634
+ if ( pINChI_Taut && (Stereo_Taut = pINChI_Taut->Stereo) && /* F is not empty */
635
+ Eql_INChI_Stereo( Stereo_Taut, EQL_SP2, NULL, EQL_EXISTS, 0 ) ||
636
+ !(pINChI_Taut && (Stereo_Taut = pINChI_Taut->Stereo) && /* M is empty and ... */
637
+ Eql_INChI_Stereo( Stereo_Taut, EQL_SP2, NULL, EQL_EXISTS, 0 )) &&
638
+ (pINChI_Taut && (Stereo_Taut = pINChI_Taut->StereoIsotopic) && /* ... MI is not empty */
639
+ Eql_INChI_Stereo( Stereo_Taut, EQL_SP2, NULL, EQL_EXISTS, 0 )) ) {
640
+
641
+ eq2taut = iiEmpty; /* the component has stereo in the preceding layer */
642
+ }
643
+ }
644
+ #endif
587
645
  } else
588
646
  /*========= if not bSecondNonTautPass then compare iso taut stereo to non-iso taut ========*/
589
647
  if ( !bSecondNonTautPass && bOmitRepetitions ) {
@@ -595,6 +653,16 @@ int str_IsoSp2(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int
595
653
  Eql_INChI_Stereo( Stereo, EQL_SP2, Stereo_Taut, EQL_SP2, 0 );
596
654
  /* stereo isotopic taut = taut (stereo) */
597
655
  eq2taut = eq2taut? (iiSTEREO | iitISO ) : 0;
656
+ #if ( FIX_EMPTY_LAYER_BUG == 1 )
657
+ if ( !eq2taut && pINChI && !((Stereo = pINChI->StereoIsotopic) &&
658
+ Eql_INChI_Stereo( Stereo, EQL_SP2, NULL, EQL_EXISTS, 0 ) ) ) {
659
+ /* component has no MI stereo; check whether it has stereo in the preceding layer M */
660
+ if ( (Stereo_Taut = pINChI->Stereo) &&
661
+ Eql_INChI_Stereo( Stereo_Taut, EQL_SP2, NULL, EQL_EXISTS, 0 ) ) {
662
+ eq2taut = iiEmpty; /* the component has stereo in the preceding layer */
663
+ }
664
+ }
665
+ #endif
598
666
  }
599
667
  }
600
668
  if ( eq2taut ) {
@@ -721,7 +789,7 @@ int str_IsoSp3(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int
721
789
  int bSecondNonTautPass, int bOmitRepetitions, int bUseMulipliers)
722
790
  {
723
791
  int i, ii, ii2;
724
- INCHI_SORT *is, *is2;
792
+ INCHI_SORT *is, *is2, *is0, *is20;
725
793
  INChI *pINChI, *pINChI_Prev, *pINChI_Taut, *pINChI_Taut_Prev;
726
794
  INChI_Stereo *Stereo, *Stereo_Prev, *Stereo_Taut, *Stereo_Taut_Prev;
727
795
  int mult, eq2prev, eq2taut, eq2tautPrev, bNext;
@@ -732,7 +800,10 @@ int str_IsoSp3(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int
732
800
  pINChI_Taut_Prev = NULL;
733
801
  mult = 0;
734
802
  bNext = 0;
735
- is2 = bSecondNonTautPass? pINChISort2 : NULL;
803
+ is = NULL;
804
+ is2 = NULL;
805
+ is0 = pINChISort;
806
+ is20 = bSecondNonTautPass? pINChISort2 : NULL;
736
807
  eq2taut = 0; /* may be non-zero if another layer of the current component = current layer */
737
808
  eq2tautPrev = 1; /* pINChI_Prev (previous pINChI) does not exist */
738
809
  pPrevEquStr = NULL; /*, *pCurrEquStr;*/
@@ -741,13 +812,13 @@ int str_IsoSp3(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int
741
812
  #else
742
813
  bRelRac = 0;
743
814
  #endif
744
- for ( i = 0, is = pINChISort; i <= num_components; i ++, is ++, (bSecondNonTautPass? is2++ : 0) ) {
815
+ for ( i = 0; i <= num_components; i ++ ) {
745
816
  /* 1st (taut) pass: bOutType=OUT_TN ; 2nd (non-taut pass) bOutType=OUT_NT */
746
- pINChI = (i < num_components && 0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
817
+ pINChI = (i < num_components && (is=is0+i, 0 <= (ii=GET_II(bOutType,is))))? is->pINChI[ii] : NULL;
747
818
  /*================ compare sp2 to previous =====================*/
748
819
  if ( bSecondNonTautPass ) {
749
820
  /* component that was output on the 1st pass */
750
- pINChI_Taut = ( i < num_components && 0 <= (ii2=GET_II(OUT_T1,is2)))? is2->pINChI[ii2] : NULL;
821
+ pINChI_Taut = ( i < num_components && (is2=is20+i, 0 <= (ii2=GET_II(OUT_T1,is2))))? is2->pINChI[ii2] : NULL;
751
822
  }
752
823
  eq2taut = 0;
753
824
  /*========= if bSecondNonTautPass then compare iso non-taut stereo to other stereo ========*/
@@ -755,7 +826,7 @@ int str_IsoSp3(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int
755
826
  /* compare non-tautomeric isotopic to:
756
827
  * a) non-tautomeric non-isotopic
757
828
  * b) tautomeric non-isotopic
758
- * c) tautomeric non-isotopic and isotopic
829
+ * c) tautomeric isotopic
759
830
  */
760
831
  /* a) compare non-tautomeric isotopic to non-tautomeric non-isotopic */
761
832
  if ( !eq2taut ) {
@@ -782,6 +853,21 @@ int str_IsoSp3(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int
782
853
  /* stereo isotopic non-taut = isotopic taut (stereo) */
783
854
  eq2taut = eq2taut? (iiSTEREO | iitISO | iitNONTAUT | iiEq2ISO) : 0;
784
855
  }
856
+ #if ( FIX_EMPTY_LAYER_BUG == 1 )
857
+ if ( !eq2taut && pINChI && !((Stereo = pINChI->StereoIsotopic) &&
858
+ Eql_INChI_Stereo( Stereo, EQL_SP3, NULL, EQL_EXISTS, 0 )) ) {
859
+ /* component has no stereo; check whether it has stereo in the preceding layers */
860
+ if ( pINChI_Taut && (Stereo_Taut = pINChI_Taut->Stereo) && /* F is not empty */
861
+ Eql_INChI_Stereo( Stereo_Taut, EQL_SP3, NULL, EQL_EXISTS, 0 ) ||
862
+ !(pINChI_Taut && (Stereo_Taut = pINChI_Taut->Stereo) && /* M is empty and ... */
863
+ Eql_INChI_Stereo( Stereo_Taut, EQL_SP3, NULL, EQL_EXISTS, 0 )) &&
864
+ (pINChI_Taut && (Stereo_Taut = pINChI_Taut->StereoIsotopic) && /* ... MI is not empty */
865
+ Eql_INChI_Stereo( Stereo_Taut, EQL_SP3, NULL, EQL_EXISTS, 0 )) ) {
866
+
867
+ eq2taut = iiEmpty; /* the component has stereo in the preceding layer */
868
+ }
869
+ }
870
+ #endif
785
871
  } else
786
872
  /*========= if not bSecondNonTautPass then compare iso taut stereo to non-iso taut ========*/
787
873
  if ( !bSecondNonTautPass && bOmitRepetitions ) {
@@ -793,6 +879,16 @@ int str_IsoSp3(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int
793
879
  Eql_INChI_Stereo( Stereo, EQL_SP3, Stereo_Taut, EQL_SP3, bRelRac );
794
880
  /* stereo isotopic taut = taut (stereo) */
795
881
  eq2taut = eq2taut? (iiSTEREO | iitISO ) : 0;
882
+ #if ( FIX_EMPTY_LAYER_BUG == 1 )
883
+ if ( !eq2taut && pINChI && !((Stereo = pINChI->StereoIsotopic) &&
884
+ Eql_INChI_Stereo( Stereo, EQL_SP3, NULL, EQL_EXISTS, 0 ) ) ) {
885
+ /* component has no MI stereo; check whether it has stereo in the preceding layer M */
886
+ if ( (Stereo_Taut = pINChI->Stereo) &&
887
+ Eql_INChI_Stereo( Stereo_Taut, EQL_SP3, NULL, EQL_EXISTS, 0 ) ) {
888
+ eq2taut = iiEmpty; /* the component has stereo in the preceding layer */
889
+ }
890
+ }
891
+ #endif
796
892
  }
797
893
  }
798
894
  if ( eq2taut ) {
@@ -914,7 +1010,7 @@ int str_AuxEqu(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int
914
1010
  int bSecondNonTautPass, int bOmitRepetitions, int bUseMulipliers)
915
1011
  {
916
1012
  int i, ii, ii2;
917
- INCHI_SORT *is, *is2;
1013
+ INCHI_SORT *is, *is2, *is0, *is20;
918
1014
  INChI_Aux *pINChI_Aux = NULL, *pINChI_Aux_Prev, *pINChI_Aux_Taut, *pINChI_Aux_Taut_Prev;
919
1015
  int mult, eq2prev, eq2taut, eq2tautPrev, bNext;
920
1016
  const char *pPrevEquStr, *pCurrEquStr;
@@ -925,17 +1021,20 @@ int str_AuxEqu(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int
925
1021
 
926
1022
  mult = 0;
927
1023
  bNext = 0;
928
- is2 = bSecondNonTautPass? pINChISort2 : NULL;
1024
+ is = NULL;
1025
+ is2 = NULL;
1026
+ is0 = pINChISort;
1027
+ is20 = bSecondNonTautPass? pINChISort2 : NULL;
929
1028
  eq2taut = 0; /* may be non-zero only on the 2nd (non-taut) pass */
930
1029
  eq2tautPrev = 1; /* pINChI_Aux_Prev (previous pINChI_Aux) does not exist */
931
1030
  pPrevEquStr = NULL; /*, *pCurrEquStr;*/
932
1031
  multPrevEquStr = 0;
933
- for ( i = 0, is = pINChISort; i <= num_components; i ++, is ++, (bSecondNonTautPass? is2++ : 0) ) {
1032
+ for ( i = 0; i <= num_components; i ++ ) {
934
1033
  /* 1st (taut) pass: bOutType=OUT_TN ; 2nd (non-taut pass) bOutType=OUT_NT */
935
- pINChI_Aux = (i < num_components && 0 <= (ii=GET_II(bOutType,is)))? is->pINChI_Aux[ii] : NULL;
1034
+ pINChI_Aux = (i < num_components && (is = is0+i, 0 <= (ii=GET_II(bOutType,is))))? is->pINChI_Aux[ii] : NULL;
936
1035
  if ( bSecondNonTautPass ) {
937
1036
  /* component that was output on the 1st pass */
938
- pINChI_Aux_Taut = ( i < num_components && 0 <= (ii2=GET_II(OUT_T1,is2)))? is2->pINChI_Aux[ii2] : NULL;
1037
+ pINChI_Aux_Taut = ( i < num_components && (is2=is20+i, 0 <= (ii2=GET_II(OUT_T1,is2))))? is2->pINChI_Aux[ii2] : NULL;
939
1038
  }
940
1039
  /*================ compare non-iso non-taut equivalence info to non-iso taut ========*/
941
1040
  eq2taut = bSecondNonTautPass && bOmitRepetitions &&
@@ -1058,7 +1157,7 @@ int str_AuxInvSp3(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, i
1058
1157
  int bSecondNonTautPass, int bOmitRepetitions, int bUseMulipliers)
1059
1158
  {
1060
1159
  int i, ii, ii2;
1061
- INCHI_SORT *is, *is2;
1160
+ INCHI_SORT *is, *is2, *is0, *is20;
1062
1161
  INChI *pINChI, *pINChI_Prev, *pINChI_Taut, *pINChI_Taut_Prev;
1063
1162
  INChI_Stereo *Stereo, *Stereo_Prev, *Stereo_Taut, *Stereo_Taut_Prev;
1064
1163
  int mult, eq2prev, eq2taut, eq2tautPrev, bNext;
@@ -1072,18 +1171,21 @@ int str_AuxInvSp3(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, i
1072
1171
  pINChI_Taut_Prev = NULL;
1073
1172
  mult = 0;
1074
1173
  bNext = 0;
1075
- is2 = bSecondNonTautPass? pINChISort2 : NULL;
1174
+ is = NULL;
1175
+ is2 = NULL;
1176
+ is0 = pINChISort;
1177
+ is20 = bSecondNonTautPass? pINChISort2 : NULL;
1076
1178
  eq2taut = 0; /* may be non-zero if another layer of the current component = current layer */
1077
1179
  eq2tautPrev = 1; /* pINChI_Prev (previous pINChI) does not exist */
1078
1180
  pPrevEquStr = NULL; /*, *pCurrEquStr;*/
1079
1181
  multPrevEquStr = 0;
1080
- for ( i = 0, is = pINChISort; i <= num_components; i ++, is ++, (bSecondNonTautPass? is2++ : 0) ) {
1182
+ for ( i = 0; i <= num_components; i ++ ) {
1081
1183
  /* 1st (taut) pass: bOutType=OUT_TN ; 2nd (non-taut pass) bOutType=OUT_NT */
1082
- pINChI = (i < num_components && 0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
1184
+ pINChI = (i < num_components && (is=is0+i, 0 <= (ii=GET_II(bOutType,is))))? is->pINChI[ii] : NULL;
1083
1185
  /*================ compare sp2 to previous =====================*/
1084
1186
  if ( bSecondNonTautPass ) {
1085
1187
  /* component that was output on the 1st pass */
1086
- pINChI_Taut = ( i < num_components && 0 <= (ii2=GET_II(OUT_T1,is2)))? is2->pINChI[ii2] : NULL;
1188
+ pINChI_Taut = ( i < num_components && (is2=is20+i, 0 <= (ii2=GET_II(OUT_T1,is2))))? is2->pINChI[ii2] : NULL;
1087
1189
  }
1088
1190
  eq2taut = 0;
1089
1191
  /*========= if bSecondNonTautPass then compare iso non-taut stereo to other stereo ========*/
@@ -1118,6 +1220,16 @@ int str_AuxInvSp3(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, i
1118
1220
  /* stereo-inv non-taut = Inv(non-taut stereo) */
1119
1221
  eq2taut = eq2taut? (iiSTEREO_INV | iitNONTAUT | iiEq2INV | iiEq2NONTAUT) : 0;
1120
1222
  }
1223
+ #if ( FIX_EMPTY_LAYER_BUG == 1 )
1224
+ if ( !eq2taut && pINChI && pINChI_Taut &&
1225
+ !((Stereo = pINChI->Stereo) && Eql_INChI_Stereo( Stereo, EQL_SP3_INV, NULL, EQL_EXISTS, 0 ))) {
1226
+ if ( (Stereo_Taut = pINChI_Taut->Stereo) &&
1227
+ Eql_INChI_Stereo( Stereo_Taut, EQL_SP3, NULL, EQL_EXISTS, 0 ) ) {
1228
+
1229
+ eq2taut = iiEmpty; /* the current is empty while the preceding (taut) is not */
1230
+ }
1231
+ }
1232
+ #endif
1121
1233
  } else
1122
1234
  /*========= if not bSecondNonTautPass then compare inv taut stereo to various taut stereo ========*/
1123
1235
  if ( !bSecondNonTautPass && bOmitRepetitions ) {
@@ -1253,7 +1365,7 @@ int str_AuxInvSp3Numb(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pSt
1253
1365
  int bSecondNonTautPass, int bOmitRepetitions)
1254
1366
  {
1255
1367
  int i, ii, ii2;
1256
- INCHI_SORT *is, *is2;
1368
+ INCHI_SORT *is, *is0 /*, *is2*/;
1257
1369
  INChI *pINChI, *pINChI_Taut;
1258
1370
  INChI_Aux *pINChI_Aux, *pINChI_Aux_Prev, *pINChI_Aux_Taut;
1259
1371
  INChI_Stereo *Stereo, *Stereo_Taut;
@@ -1270,12 +1382,15 @@ int str_AuxInvSp3Numb(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pSt
1270
1382
  pINChI_Aux_Taut = NULL;
1271
1383
  pINChI_Aux_Prev = NULL;
1272
1384
  bNext = 0;
1273
- is2 = bSecondNonTautPass? pINChISort2 : NULL;
1385
+ is = NULL;
1386
+ is0 = pINChISort;
1387
+ /*is2 = bSecondNonTautPass? pINChISort2 : NULL;*/
1274
1388
  eq2taut = 0; /* may be non-zero if another layer of the current component = current layer */
1275
1389
  pPrevEquStr = NULL; /*, *pCurrEquStr;*/
1276
1390
  multPrevEquStr = 0;
1277
- for ( i = 0, is = pINChISort; i < num_components; i ++, is ++, (bSecondNonTautPass? is2++ : 0) ) {
1391
+ for ( i = 0; i < num_components; i ++ ) {
1278
1392
  /* 1st (taut) pass: bOutType=OUT_TN ; 2nd (non-taut pass) bOutType=OUT_NT */
1393
+ is=is0+i;
1279
1394
  pINChI = (0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
1280
1395
  pINChI_Aux = pINChI? is->pINChI_Aux[ii] : NULL;
1281
1396
  /*================ to compare to previously printed =====================*/
@@ -1389,7 +1504,7 @@ int str_AuxIsoNumb(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr,
1389
1504
  int bSecondNonTautPass, int bOmitRepetitions)
1390
1505
  {
1391
1506
  int i, ii, ii2;
1392
- INCHI_SORT *is, *is2;
1507
+ INCHI_SORT *is, *is0 /*, *is2*/;
1393
1508
  INChI *pINChI, *pINChI_Taut;
1394
1509
  INChI_Aux *pINChI_Aux, *pINChI_Aux_Prev, *pINChI_Aux_Taut;
1395
1510
  int eq2taut, bNext;
@@ -1405,12 +1520,15 @@ int str_AuxIsoNumb(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr,
1405
1520
  pINChI_Aux_Taut = NULL;
1406
1521
  pINChI_Aux_Prev = NULL;
1407
1522
  bNext = 0;
1408
- is2 = bSecondNonTautPass? pINChISort2 : NULL;
1523
+ is = NULL;
1524
+ is0 = pINChISort;
1525
+ /*is2 = bSecondNonTautPass? pINChISort2 : NULL;*/
1409
1526
  eq2taut = 0; /* may be non-zero if another layer of the current component = current layer */
1410
1527
  pPrevEquStr = NULL; /*, *pCurrEquStr;*/
1411
1528
  multPrevEquStr = 0;
1412
- for ( i = 0, is = pINChISort; i < num_components; i ++, is ++, (bSecondNonTautPass? is2++ : 0) ) {
1529
+ for ( i = 0; i < num_components; i ++ ) {
1413
1530
  /* 1st (taut) pass: bOutType=OUT_TN ; 2nd (non-taut pass) bOutType=OUT_NT */
1531
+ is=is0+i;
1414
1532
  pINChI_Aux = (i < num_components && 0 <= (ii=GET_II(bOutType,is)))? is->pINChI_Aux[ii] : NULL;
1415
1533
  /*================ to compare to previously printed =====================*/
1416
1534
  if ( bSecondNonTautPass ) {
@@ -1512,7 +1630,7 @@ int str_AuxIsoEqu(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, i
1512
1630
  int bSecondNonTautPass, int bOmitRepetitions, int bUseMulipliers)
1513
1631
  {
1514
1632
  int i, ii, ii2;
1515
- INCHI_SORT *is, *is2;
1633
+ INCHI_SORT *is, *is2, *is0, *is20;
1516
1634
  INChI_Aux *pINChI_Aux, *pINChI_Aux_Prev, *pINChI_Aux_Taut, *pINChI_Aux_Taut_Prev;
1517
1635
  int mult, eq2prev, eq2taut, eq2tautPrev, bNext;
1518
1636
  const char *pPrevEquStr, *pCurrEquStr;
@@ -1523,17 +1641,20 @@ int str_AuxIsoEqu(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, i
1523
1641
  pINChI_Aux_Taut_Prev = NULL;
1524
1642
  mult = 0;
1525
1643
  bNext = 0;
1526
- is2 = bSecondNonTautPass? pINChISort2 : NULL;
1644
+ is = NULL;
1645
+ is2 = NULL;
1646
+ is0 = pINChISort;
1647
+ is20 = bSecondNonTautPass? pINChISort2 : NULL;
1527
1648
  eq2taut = 0; /* may be non-zero only on the 2nd (non-taut) pass */
1528
1649
  eq2tautPrev = 1; /* pINChI_Aux_Prev (previous pINChI_Aux) does not exist */
1529
1650
  pPrevEquStr = NULL; /*, *pCurrEquStr;*/
1530
1651
  multPrevEquStr = 0;
1531
- for ( i = 0, is = pINChISort; i <= num_components; i ++, is ++, (bSecondNonTautPass? is2++ : 0) ) {
1652
+ for ( i = 0; i <= num_components; i ++ ) {
1532
1653
  /* 1st (taut) pass: bOutType=OUT_TN ; 2nd (non-taut pass) bOutType=OUT_NT */
1533
- pINChI_Aux = (i < num_components && 0 <= (ii=GET_II(bOutType,is)))? is->pINChI_Aux[ii] : NULL;
1654
+ pINChI_Aux = (i < num_components && (is=is0+i, 0 <= (ii=GET_II(bOutType,is))))? is->pINChI_Aux[ii] : NULL;
1534
1655
  if ( bSecondNonTautPass ) {
1535
1656
  /* component that was output on the 1st pass */
1536
- pINChI_Aux_Taut = ( i < num_components && 0 <= (ii2=GET_II(OUT_T1,is2)))? is2->pINChI_Aux[ii2] : NULL;
1657
+ pINChI_Aux_Taut = ( i < num_components && (is2=is20+i, 0 <= (ii2=GET_II(OUT_T1,is2))))? is2->pINChI_Aux[ii2] : NULL;
1537
1658
  }
1538
1659
  /*================ compare iso non-taut equivalence info to non-iso taut ========*/
1539
1660
  eq2taut = 0;
@@ -1691,7 +1812,7 @@ int str_AuxInvIsoSp3(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr
1691
1812
  int bSecondNonTautPass, int bOmitRepetitions, int bUseMulipliers)
1692
1813
  {
1693
1814
  int i, ii, ii2;
1694
- INCHI_SORT *is, *is2;
1815
+ INCHI_SORT *is, *is2, *is0, *is20;
1695
1816
  INChI *pINChI, *pINChI_Prev, *pINChI_Taut, *pINChI_Taut_Prev;
1696
1817
  INChI_Stereo *Stereo, *Stereo_Prev, *Stereo_Taut, *Stereo_Taut_Prev;
1697
1818
  int mult, eq2prev, eq2taut, eq2tautPrev, bNext;
@@ -1705,18 +1826,21 @@ int str_AuxInvIsoSp3(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr
1705
1826
  pINChI_Taut_Prev = NULL;
1706
1827
  mult = 0;
1707
1828
  bNext = 0;
1708
- is2 = bSecondNonTautPass? pINChISort2 : NULL;
1829
+ is = NULL;
1830
+ is2 = NULL;
1831
+ is0 = pINChISort;
1832
+ is20 = bSecondNonTautPass? pINChISort2 : NULL;
1709
1833
  eq2taut = 0; /* may be non-zero if another layer of the current component = current layer */
1710
1834
  eq2tautPrev = 1; /* pINChI_Prev (previous pINChI) does not exist */
1711
1835
  pPrevEquStr = NULL; /*, *pCurrEquStr;*/
1712
1836
  multPrevEquStr = 0;
1713
- for ( i = 0, is = pINChISort; i <= num_components; i ++, is ++, (bSecondNonTautPass? is2++ : 0) ) {
1837
+ for ( i = 0; i <= num_components; i ++ ) {
1714
1838
  /* 1st (taut) pass: bOutType=OUT_TN ; 2nd (non-taut pass) bOutType=OUT_NT */
1715
- pINChI = (i < num_components && 0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
1839
+ pINChI = (i < num_components && (is=is0+i, 0 <= (ii=GET_II(bOutType,is))))? is->pINChI[ii] : NULL;
1716
1840
  /*================ compare sp2 to previous =====================*/
1717
1841
  if ( bSecondNonTautPass ) {
1718
1842
  /* component that was output on the 1st pass */
1719
- pINChI_Taut = ( i < num_components && 0 <= (ii2=GET_II(OUT_T1,is2)))? is2->pINChI[ii2] : NULL;
1843
+ pINChI_Taut = ( i < num_components && (is2=is20+i, 0 <= (ii2=GET_II(OUT_T1,is2))))? is2->pINChI[ii2] : NULL;
1720
1844
  }
1721
1845
  eq2taut = 0;
1722
1846
  /*========= if bSecondNonTautPass then compare iso non-taut stereo to other stereo ========*/
@@ -1788,6 +1912,21 @@ int str_AuxInvIsoSp3(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr
1788
1912
  /* stereo-inv isotopic non-taut = Inv( iso non-taut stereo) */
1789
1913
  eq2taut = eq2taut? (iiSTEREO_INV | iitISO | iitNONTAUT | iiEq2INV | iiEq2ISO | iiEq2NONTAUT) : 0;
1790
1914
  }
1915
+ #if ( FIX_EMPTY_LAYER_BUG == 1 )
1916
+ if ( !eq2taut && pINChI && !((Stereo = pINChI->StereoIsotopic) &&
1917
+ Eql_INChI_Stereo( Stereo, EQL_SP3_INV, NULL, EQL_EXISTS, 0 )) ) {
1918
+ /* component has no stereo; check whether it has stereo in the preceding layers */
1919
+ if ( pINChI_Taut && (Stereo_Taut = pINChI_Taut->Stereo) && /* F is not empty */
1920
+ Eql_INChI_Stereo( Stereo_Taut, EQL_SP3_INV, NULL, EQL_EXISTS, 0 ) ||
1921
+ !(pINChI_Taut && (Stereo_Taut = pINChI_Taut->Stereo) && /* M is empty and ... */
1922
+ Eql_INChI_Stereo( Stereo_Taut, EQL_SP3_INV, NULL, EQL_EXISTS, 0 )) &&
1923
+ (pINChI_Taut && (Stereo_Taut = pINChI_Taut->StereoIsotopic) && /* ... MI is not empty */
1924
+ Eql_INChI_Stereo( Stereo_Taut, EQL_SP3_INV, NULL, EQL_EXISTS, 0 )) ) {
1925
+
1926
+ eq2taut = iiEmpty; /* the component has stereo in the preceding layer */
1927
+ }
1928
+ }
1929
+ #endif
1791
1930
  } else
1792
1931
  /*========= if not bSecondNonTautPass then compare inv taut stereo to various stereo ========*/
1793
1932
  if ( !bSecondNonTautPass && bOmitRepetitions && pINChI &&
@@ -1823,6 +1962,16 @@ int str_AuxInvIsoSp3(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr
1823
1962
  /* stereo-inv isotopic taut = Inv(taut iso stereo) */
1824
1963
  eq2taut = eq2taut? (iiSTEREO_INV | iitISO | iiEq2INV | iiEq2ISO ) : 0;
1825
1964
  }
1965
+ #if ( FIX_EMPTY_LAYER_BUG == 1 )
1966
+ if ( !eq2taut && pINChI && !((Stereo = pINChI->StereoIsotopic) &&
1967
+ Eql_INChI_Stereo( Stereo, EQL_SP3_INV, NULL, EQL_EXISTS, 0 ) ) ) {
1968
+ /* component has no MI stereo; check whether it has stereo in the preceding layer M */
1969
+ if ( (Stereo_Taut = pINChI->Stereo) &&
1970
+ Eql_INChI_Stereo( Stereo_Taut, EQL_SP3_INV, NULL, EQL_EXISTS, 0 ) ) {
1971
+ eq2taut = iiEmpty; /* the component has stereo in the preceding layer */
1972
+ }
1973
+ }
1974
+ #endif
1826
1975
  }
1827
1976
  if ( eq2taut ) {
1828
1977
  /* we may be here only in case of the current layer found equal in another layer the same component */
@@ -1948,7 +2097,7 @@ int str_AuxInvIsoSp3Numb(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *
1948
2097
  int bSecondNonTautPass, int bOmitRepetitions)
1949
2098
  {
1950
2099
  int i, ii, ii2;
1951
- INCHI_SORT *is, *is2;
2100
+ INCHI_SORT *is, *is0 /*, *is2*/;
1952
2101
  INChI *pINChI, *pINChI_Taut;
1953
2102
  INChI_Aux *pINChI_Aux, *pINChI_Aux_Prev, *pINChI_Aux_Taut;
1954
2103
  INChI_Stereo *Stereo, *Stereo_Taut;
@@ -1965,12 +2114,16 @@ int str_AuxInvIsoSp3Numb(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *
1965
2114
  pINChI_Aux_Taut = NULL;
1966
2115
  pINChI_Aux_Prev = NULL;
1967
2116
  bNext = 0;
1968
- is2 = bSecondNonTautPass? pINChISort2 : NULL;
2117
+ is = NULL;
2118
+ /* is2 = NULL;*/
2119
+ is0 = pINChISort;
2120
+ /* is20 = bSecondNonTautPass? pINChISort2 : NULL;*/
1969
2121
  eq2taut = 0; /* may be non-zero if another layer of the current component = current layer */
1970
2122
  pPrevEquStr = NULL; /*, *pCurrEquStr;*/
1971
2123
  multPrevEquStr = 0;
1972
- for ( i = 0, is = pINChISort; i < num_components; i ++, is ++, (bSecondNonTautPass? is2++ : 0) ) {
2124
+ for ( i = 0; i < num_components; i ++ ) {
1973
2125
  /* 1st (taut) pass: bOutType=OUT_TN ; 2nd (non-taut pass) bOutType=OUT_NT */
2126
+ is=is0+i;
1974
2127
  pINChI = (0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
1975
2128
  pINChI_Aux = pINChI? is->pINChI_Aux[ii] : NULL;
1976
2129
  /*================ to compare to previously printed =====================*/
@@ -2135,19 +2288,19 @@ int str_HillFormula(INCHI_SORT *pINChISort, char *pStr, int nStrLen, int tot_len
2135
2288
  int *bOverflow, int bOutType, int num_components, int bUseMulipliers)
2136
2289
  {
2137
2290
  int i, ii;
2138
- INCHI_SORT *is;
2291
+ INCHI_SORT *is, *is0;
2139
2292
  INChI *pINChI, *pINChI_Prev;
2140
2293
  int mult, eq2prev, bNext;
2141
2294
 
2142
- if ( !(is = pINChISort) ) {
2295
+ if ( !(is0 = pINChISort) ) {
2143
2296
  return tot_len;
2144
2297
  }
2145
2298
  i = 0;
2146
- pINChI_Prev = (0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
2299
+ pINChI_Prev = (0 <= (ii=GET_II(bOutType,is0)))? is0->pINChI[ii] : NULL;
2147
2300
  mult = 0;
2148
2301
  bNext = 0;
2149
- for ( i++, is++; i <= num_components; i ++, is ++ ) {
2150
- pINChI = (i < num_components && 0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
2302
+ for ( i++; i <= num_components; i ++ ) {
2303
+ pINChI = (i < num_components && (is=is0+i, 0 <= (ii=GET_II(bOutType,is))))? is->pINChI[ii] : NULL;
2151
2304
  eq2prev = bUseMulipliers &&
2152
2305
  pINChI && pINChI_Prev && pINChI->szHillFormula && pINChI_Prev->szHillFormula &&
2153
2306
  pINChI->szHillFormula[0] && !strcmp(pINChI_Prev->szHillFormula, pINChI->szHillFormula);
@@ -2175,16 +2328,18 @@ int str_HillFormula2(INCHI_SORT *pINChISort /* non-taut */, INCHI_SORT *pINChISo
2175
2328
  int *bOverflow, int bOutType, int num_components, int bUseMulipliers)
2176
2329
  {
2177
2330
  int i, ii, ii2;
2178
- INCHI_SORT *is, *is2;
2331
+ INCHI_SORT *is, *is2, *is0, *is20;
2179
2332
  INChI *pINChI, *pINChI_Prev, *pINChI_Taut, *pINChI_Taut_Prev;
2180
2333
  int mult, eq2prev, bNext, bEqToTaut, tot_len_inp = tot_len;
2181
2334
 
2182
- is = pINChISort;
2183
- is2 = pINChISort2;
2335
+ is = NULL;
2336
+ is2 = NULL;
2337
+ is0 = pINChISort;
2338
+ is20 = pINChISort2;
2184
2339
  i = 0;
2185
2340
 
2186
- pINChI_Prev = (0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
2187
- pINChI_Taut_Prev = (0 <= (ii2=GET_II(OUT_T1,is2)))? is2->pINChI[ii2] : NULL;
2341
+ pINChI_Prev = (0 <= (ii=GET_II(bOutType,is0)))? is0->pINChI[ii] : NULL;
2342
+ pINChI_Taut_Prev = (0 <= (ii2=GET_II(OUT_T1,is20)))? is20->pINChI[ii2] : NULL;
2188
2343
  mult = 0;
2189
2344
  bNext = 0;
2190
2345
  bEqToTaut = 1;
@@ -2192,9 +2347,9 @@ int str_HillFormula2(INCHI_SORT *pINChISort /* non-taut */, INCHI_SORT *pINChISo
2192
2347
  pINChI_Prev && pINChI_Taut_Prev && !pINChI_Taut_Prev->bDeleted &&
2193
2348
  pINChI_Prev->szHillFormula && pINChI_Taut_Prev->szHillFormula &&
2194
2349
  !strcmp(pINChI_Prev->szHillFormula, pINChI_Taut_Prev->szHillFormula);
2195
- for ( i++, is++, is2++; i <= num_components; i ++, is ++, is2 ++ ) {
2196
- pINChI = (i < num_components && 0 <= (ii =GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
2197
- pINChI_Taut = (i < num_components && 0 <= (ii2=GET_II(OUT_T1,is2)))? is2->pINChI[ii2] : NULL;
2350
+ for ( i++; i <= num_components; i ++ ) {
2351
+ pINChI = (i < num_components && (is=is0+i, 0 <= (ii =GET_II(bOutType,is))))? is->pINChI[ii] : NULL;
2352
+ pINChI_Taut = (i < num_components && (is2=is20+i, 0 <= (ii2=GET_II(OUT_T1,is2))))? is2->pINChI[ii2] : NULL;
2198
2353
  if ( bEqToTaut && (pINChI || pINChI_Taut) ) {
2199
2354
  bEqToTaut = pINChI && pINChI_Taut && !pINChI_Taut->bDeleted &&
2200
2355
  pINChI->szHillFormula && pINChI_Taut->szHillFormula &&
@@ -2229,21 +2384,22 @@ int str_Connections(INCHI_SORT *pINChISort, char *pStr, int nStrLen, int tot_len
2229
2384
  int *bOverflow, int bOutType, int ATOM_MODE, int num_components, int bUseMulipliers)
2230
2385
  {
2231
2386
  int i, ii;
2232
- INCHI_SORT *is;
2387
+ INCHI_SORT *is, *is0;
2233
2388
  INChI *pINChI, *pINChI_Prev;
2234
2389
  int mult, eq2prev, bNext, tot_len_inp, nNumEmpty;
2235
2390
 
2236
- if ( !(is = pINChISort) ) {
2391
+ if ( !(is0 = pINChISort) ) {
2237
2392
  return tot_len;
2238
2393
  }
2239
2394
  i = 0;
2240
- pINChI_Prev = (0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
2241
- mult = 0;
2242
- bNext = 0;
2395
+ pINChI_Prev = (0 <= (ii=GET_II(bOutType,is0)))? is0->pINChI[ii] : NULL;
2396
+ is = NULL;
2397
+ mult = 0;
2398
+ bNext = 0;
2243
2399
  tot_len_inp = tot_len;
2244
2400
  nNumEmpty = 0;
2245
- for ( i++, is++; i <= num_components; i ++, is ++ ) {
2246
- pINChI = (i < num_components && 0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
2401
+ for ( i++; i <= num_components; i ++ ) {
2402
+ pINChI = (i < num_components && (is=is0+i, 0 <= (ii=GET_II(bOutType,is))))? is->pINChI[ii] : NULL;
2247
2403
  eq2prev = bUseMulipliers &&
2248
2404
  pINChI && pINChI_Prev && pINChI->lenConnTable > 1 &&
2249
2405
  pINChI_Prev->lenConnTable==pINChI->lenConnTable &&
@@ -2281,19 +2437,20 @@ int str_H_atoms(INCHI_SORT *pINChISort, char *pStr, int nStrLen, int tot_len,
2281
2437
  int num_components, int bUseMulipliers)
2282
2438
  {
2283
2439
  int i, j, ii, len_H;
2284
- INCHI_SORT *is;
2440
+ INCHI_SORT *is, *is0;
2285
2441
  INChI *pINChI, *pINChI_Prev;
2286
2442
  int mult, eq2prev, bNext, bNotEmpty, nNumEmpty, tot_len_inp;
2287
2443
 
2288
2444
  nNumEmpty = 0;
2289
2445
  tot_len_inp = tot_len;
2290
- is = pINChISort;
2446
+ is0 = pINChISort;
2447
+ is = NULL;
2291
2448
  i = 0;
2292
- pINChI_Prev = (0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
2449
+ pINChI_Prev = (0 <= (ii=GET_II(bOutType,is0)))? is0->pINChI[ii] : NULL;
2293
2450
  mult = 0;
2294
2451
  bNext = 0;
2295
- for ( i++, is++; i <= num_components; i ++, is ++ ) {
2296
- pINChI = (i < num_components && 0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
2452
+ for ( i++; i <= num_components; i ++) {
2453
+ pINChI = (i < num_components && (is=is0+i, 0 <= (ii=GET_II(bOutType,is))))? is->pINChI[ii] : NULL;
2297
2454
  /*========== compare to previous ============*/
2298
2455
  eq2prev = bUseMulipliers &&
2299
2456
  pINChI && pINChI_Prev && (pINChI->nNumberOfAtoms > 0 || pINChI->lenTautomer>1) &&
@@ -2361,7 +2518,7 @@ int str_Charge2(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int
2361
2518
  int bSecondNonTautPass, int bOmitRepetitions, int bUseMulipliers)
2362
2519
  {
2363
2520
  int i, ii, ii2;
2364
- INCHI_SORT *is, *is2;
2521
+ INCHI_SORT *is, *is2, *is0, *is20;
2365
2522
  INChI *pINChI, *pINChI_Prev, *pINChI_Taut, *pINChI_Taut_Prev;
2366
2523
  int nTotalCharge, nTotalCharge_Prev, nTotalCharge_Taut, nTotalCharge_Taut_Prev;
2367
2524
  int mult, eq2prev, eq2taut, eq2tautPrev, bNext;
@@ -2372,18 +2529,21 @@ int str_Charge2(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int
2372
2529
  pINChI_Taut_Prev = NULL;
2373
2530
  mult = 0;
2374
2531
  bNext = 0;
2375
- is2 = bSecondNonTautPass? pINChISort2 : NULL;
2532
+ is = NULL;
2533
+ is2 = NULL;
2534
+ is0 = pINChISort;
2535
+ is20 = bSecondNonTautPass? pINChISort2 : NULL;
2376
2536
  eq2taut = 0; /* may be non-zero only on the 2nd (non-taut) pass */
2377
2537
  eq2tautPrev = 1; /* pINChI_Prev (previous pINChI) does not exist */
2378
2538
  pPrevEquStr = NULL; /*, *pCurrEquStr;*/
2379
2539
  multPrevEquStr = 0;
2380
- for ( i = 0, is = pINChISort; i <= num_components; i ++, is ++, (bSecondNonTautPass? is2++ : 0) ) {
2540
+ for ( i = 0; i <= num_components; i ++ ) {
2381
2541
  /* 1st (taut) pass: bOutType=OUT_TN ; 2nd (non-taut pass) bOutType=OUT_NT */
2382
- pINChI = (i < num_components && 0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
2542
+ pINChI = (i < num_components && (is=is0+i, 0 <= (ii=GET_II(bOutType,is))))? is->pINChI[ii] : NULL;
2383
2543
  /*================ compare sp3 to previous =====================*/
2384
2544
  if ( bSecondNonTautPass ) {
2385
2545
  /* component that was output on the 1st pass */
2386
- pINChI_Taut = ( i < num_components && 0 <= (ii2=GET_II(OUT_T1,is2)))? is2->pINChI[ii2] : NULL;
2546
+ pINChI_Taut = ( i < num_components && (is2=is20+i, 0 <= (ii2=GET_II(OUT_T1,is2))))? is2->pINChI[ii2] : NULL;
2387
2547
  }
2388
2548
  /*========= if bSecondNonTautPass then compare non-iso non-taut stereo to non-iso taut ========*/
2389
2549
  eq2taut = 0;
@@ -2507,20 +2667,21 @@ int str_FixedH_atoms(INCHI_SORT *pINChISort, char *pStr, int nStrLen, int tot_le
2507
2667
  int *bOverflow, int bOutType, int ATOM_MODE, int num_components, int bUseMulipliers)
2508
2668
  {
2509
2669
  int i, j, ii, nNumEmpty;
2510
- INCHI_SORT *is;
2670
+ INCHI_SORT *is, *is0;
2511
2671
  INChI *pINChI, *pINChI_Prev;
2512
2672
  int mult, eq2prev, bNext, bNotEmpty, tot_len_inp;
2513
2673
 
2514
- is = pINChISort;
2674
+ is = NULL;
2675
+ is0 = pINChISort;
2515
2676
  i = 0;
2516
- pINChI_Prev = (0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
2677
+ pINChI_Prev = (0 <= (ii=GET_II(bOutType,is0)))? is0->pINChI[ii] : NULL;
2517
2678
  mult = 0;
2518
2679
  bNext = 0;
2519
2680
  nNumEmpty = 0;
2520
2681
  tot_len_inp = tot_len;
2521
- for ( i++, is++; i <= num_components; i ++, is ++ ) {
2682
+ for ( i++; i <= num_components; i ++ ) {
2522
2683
  /* only non-tautomeric representation of tautomeric */
2523
- pINChI = (i < num_components && 0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
2684
+ pINChI = (i < num_components && (is=is0+i, 0 <= (ii=GET_II(bOutType,is))))? is->pINChI[ii] : NULL;
2524
2685
  /*================ compare fixed H to previous =====================*/
2525
2686
  eq2prev =bUseMulipliers &&
2526
2687
  pINChI && pINChI_Prev && pINChI->nNumberOfAtoms > 0 &&
@@ -2580,22 +2741,24 @@ int str_AuxNumb(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, char *pStr, int
2580
2741
  int bSecondNonTautPass, int bOmitRepetitions)
2581
2742
  {
2582
2743
  int i, ii, ii2;
2583
- INCHI_SORT *is, *is2;
2584
- INChI *pINChI, *pINChI_Taut;
2585
- INChI_Aux *pINChI_Aux, *pINChI_Aux_Taut;
2744
+ INCHI_SORT *is, *is0 /*, *is2*/;
2745
+ INChI *pINChI, *pINChI_Taut=NULL;
2746
+ INChI_Aux *pINChI_Aux, *pINChI_Aux_Taut=NULL;
2586
2747
  int eq2taut, bNext;
2587
2748
  const char *pPrevEquStr, *pCurrEquStr;
2588
2749
  int multPrevEquStr;
2589
2750
  bNext = 0;
2590
- is2 = bSecondNonTautPass? pINChISort2 : NULL;
2751
+ /*is2 = bSecondNonTautPass? pINChISort2 : NULL;*/
2591
2752
  eq2taut = 0; /* may be non-zero if another layer of the current component = current layer */
2592
2753
  pPrevEquStr = NULL; /*, *pCurrEquStr;*/
2593
2754
  multPrevEquStr = 0;
2594
- if ( !(is = pINChISort) ) {
2755
+ is = NULL;
2756
+ if ( !(is0 = pINChISort) ) {
2595
2757
  return tot_len;
2596
2758
  }
2597
- for ( i = 0; i < num_components; i ++, is ++, (bSecondNonTautPass? is2++ : 0) ) {
2759
+ for ( i = 0; i < num_components; i ++ ) {
2598
2760
  /* 1st (taut) pass: bOutType=OUT_TN ; 2nd (non-taut pass) bOutType=OUT_NT */
2761
+ is=is0+i;
2599
2762
  pINChI = ( 0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
2600
2763
  pINChI_Aux = pINChI? is->pINChI_Aux[ii] : NULL;
2601
2764
  /*================ to compare to previously printed =====================*/
@@ -2675,17 +2838,18 @@ int str_AuxTgroupEqu(INCHI_SORT *pINChISort, char *pStr, int nStrLen, int tot_le
2675
2838
  int *bOverflow, int bOutType, int TAUT_MODE, int num_components, int bUseMulipliers)
2676
2839
  {
2677
2840
  int i, ii;
2678
- INCHI_SORT *is;
2841
+ INCHI_SORT *is, *is0;
2679
2842
  INChI_Aux *pINChI_Aux, *pINChI_Aux_Prev;
2680
2843
  int mult, eq2prev, bNext;
2681
2844
 
2682
- is = pINChISort;
2845
+ is0 = pINChISort;
2846
+ is = NULL;
2683
2847
  i = 0;
2684
- pINChI_Aux_Prev = (0 <= (ii=GET_II(bOutType,is)))? is->pINChI_Aux[ii] : NULL;
2848
+ pINChI_Aux_Prev = (0 <= (ii=GET_II(bOutType,is0)))? is0->pINChI_Aux[ii] : NULL;
2685
2849
  mult = 0;
2686
2850
  bNext = 0;
2687
- for ( i++, is++; i <= num_components; i ++, is ++ ) {
2688
- pINChI_Aux = (i < num_components && 0 <= (ii=GET_II(bOutType,is)))? is->pINChI_Aux[ii] : NULL;
2851
+ for ( i++; i <= num_components; i ++ ) {
2852
+ pINChI_Aux = (i < num_components && (is=is0+i, 0 <= (ii=GET_II(bOutType,is))))? is->pINChI_Aux[ii] : NULL;
2689
2853
  eq2prev = bUseMulipliers &&
2690
2854
  Eql_INChI_Aux_Equ( pINChI_Aux, EQL_EQU_TG, pINChI_Aux_Prev, EQL_EQU_TG );
2691
2855
  if ( eq2prev ) {
@@ -2713,16 +2877,18 @@ int str_AuxChargeRadVal(INCHI_SORT *pINChISort, char *pStr, int nStrLen, int tot
2713
2877
  int *bOverflow, int bOutType, int TAUT_MODE, int num_components, int bUseMulipliers)
2714
2878
  {
2715
2879
  int i, ii;
2716
- INCHI_SORT *is;
2880
+ INCHI_SORT *is, *is0;
2717
2881
  INChI_Aux *pINChI_Aux, *pINChI_Aux_Prev;
2718
2882
  int mult, eq2prev, bNext;
2719
2883
 
2720
2884
  pINChI_Aux_Prev = NULL;
2721
2885
  mult = 0;
2722
2886
  bNext = 0;
2723
- for ( i = 0, is = pINChISort; i <= num_components; i ++, is ++ ) {
2887
+ is = NULL;
2888
+ is0 = pINChISort;
2889
+ for ( i = 0; i <= num_components; i ++ ) {
2724
2890
  /* 1st (taut) pass: bOutType=OUT_TN ; 2nd (non-taut pass) bOutType=OUT_NT */
2725
- pINChI_Aux = (i < num_components && 0 <= (ii=GET_II(bOutType,is)))? is->pINChI_Aux[ii] : NULL;
2891
+ pINChI_Aux = (i < num_components && (is=is0+i, 0 <= (ii=GET_II(bOutType,is))))? is->pINChI_Aux[ii] : NULL;
2726
2892
  /* check whether pINChI_Aux and pINChI_Aux_Prev have identical info */
2727
2893
  eq2prev = bUseMulipliers &&
2728
2894
  EqlOrigInfo( pINChI_Aux, pINChI_Aux_Prev );
@@ -2762,16 +2928,18 @@ int bin_AuxTautTrans(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2,
2762
2928
  AT_NUMB **pTrans_n, AT_NUMB **pTrans_s, int bOutType, int num_components)
2763
2929
  {
2764
2930
  int i, ii, ii2, ret;
2765
- INCHI_SORT *is, *is2;
2931
+ INCHI_SORT *is, *is2, *is0, *is20;
2766
2932
  INChI *pINChI, *pINChI_Taut;
2767
2933
  AT_NUMB *nTrans_n = NULL;
2768
2934
  AT_NUMB *nTrans_s = NULL;
2769
2935
 
2770
2936
  ret = 0;
2771
- *pTrans_n = NULL;
2772
- *pTrans_s = NULL;
2937
+ is0 = pINChISort;
2938
+ is20 = pINChISort2;
2773
2939
  /* pass 1: save new non-taut numbering */
2774
- for ( i = 0, is = pINChISort, is2 = pINChISort2; i < num_components; i ++, is ++, is2 ++ ) {
2940
+ for ( i = 0; i < num_components; i ++ ) {
2941
+ is=is0+i;
2942
+ is2=is20+i;
2775
2943
  pINChI = ( 0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
2776
2944
  pINChI_Taut = ( 0 <= (ii2=GET_II(OUT_T1,is2)))? is2->pINChI[ii2] : NULL;
2777
2945
  if ( pINChI && pINChI->nNumberOfAtoms > 0 &&
@@ -2788,7 +2956,9 @@ int bin_AuxTautTrans(INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2,
2788
2956
  }
2789
2957
  if ( nTrans_n && nTrans_s ) {
2790
2958
  /* pass 2: get new taut numbering, retrieve new non-taut and save the transposition */
2791
- for ( i = 0, is = pINChISort, is2 = pINChISort2; i < num_components; i ++, is ++, is2 ++ ) {
2959
+ for ( i = 0; i < num_components; i ++ ) {
2960
+ is=is0+i;
2961
+ is2=is20+i;
2792
2962
  pINChI = ( 0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
2793
2963
  pINChI_Taut = ( 0 <= (ii2=GET_II(OUT_T1,is2)))? is2->pINChI[ii2] : NULL;
2794
2964
  if ( pINChI && pINChI->nNumberOfAtoms > 0 &&
@@ -2854,11 +3024,15 @@ int str_StereoAbsInv(INCHI_SORT *pINChISort, char *pStr, int nStrLen, int tot_le
2854
3024
  int *bOverflow, int bOutType, int num_components)
2855
3025
  {
2856
3026
  int i, j, ii;
2857
- INCHI_SORT *is;
3027
+ INCHI_SORT *is, *is0;
2858
3028
  INChI_Stereo *Stereo;
2859
3029
  INChI *pINChI;
2860
3030
 
2861
- for ( i = 0, is = pINChISort; !*bOverflow && i < num_components; i ++, is ++ ) {
3031
+ is = NULL;
3032
+ is0 = pINChISort;
3033
+
3034
+ for ( i = 0; !*bOverflow && i < num_components; i ++ ) {
3035
+ is=is0+i;
2862
3036
  pINChI = (0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
2863
3037
  if ( pINChI && (Stereo = pINChI->Stereo) && (j=Stereo->nCompInv2Abs) ) {
2864
3038
  tot_len += MakeDelim( j<0? "1":"0", pStr + tot_len, nStrLen-tot_len, bOverflow);
@@ -2874,11 +3048,15 @@ int str_IsoStereoAbsInv(INCHI_SORT *pINChISort, char *pStr, int nStrLen, int tot
2874
3048
  int *bOverflow, int bOutType, int num_components)
2875
3049
  {
2876
3050
  int i, j, ii;
2877
- INCHI_SORT *is;
3051
+ INCHI_SORT *is, *is0;
2878
3052
  INChI_Stereo *Stereo;
2879
3053
  INChI *pINChI;
2880
3054
 
2881
- for ( i = 0, is = pINChISort; !*bOverflow && i < num_components; i ++, is ++ ) {
3055
+ is = NULL;
3056
+ is0 = pINChISort;
3057
+
3058
+ for ( i = 0; !*bOverflow && i < num_components; i ++ ) {
3059
+ is=is0+i;
2882
3060
  pINChI = (0 <= (ii=GET_II(bOutType,is)))? is->pINChI[ii] : NULL;
2883
3061
  if ( pINChI && (Stereo = pINChI->StereoIsotopic) && (j=Stereo->nCompInv2Abs) ) {
2884
3062
  tot_len += MakeDelim( j<0? "1":"0", pStr + tot_len, nStrLen-tot_len, bOverflow);
@@ -2894,7 +3072,7 @@ int str_AuxIsoTgroupEqu(INCHI_SORT *pINChISort, char *pStr, int nStrLen, int tot
2894
3072
  int *bOverflow, int bOutType, int TAUT_MODE, int num_components, int bOmitRepetitions, int bUseMulipliers)
2895
3073
  {
2896
3074
  int i, ii;
2897
- INCHI_SORT *is;
3075
+ INCHI_SORT *is, *is0;
2898
3076
  INChI_Aux *pINChI_Aux, *pINChI_Aux_Prev;
2899
3077
  int mult, eq2prev, eq2taut, eq2tautPrev, bNext;
2900
3078
  const char *pPrevEquStr, *pCurrEquStr;
@@ -2903,13 +3081,15 @@ int str_AuxIsoTgroupEqu(INCHI_SORT *pINChISort, char *pStr, int nStrLen, int tot
2903
3081
  pINChI_Aux_Prev = NULL;
2904
3082
  mult = 0;
2905
3083
  bNext = 0;
3084
+ is = NULL;
3085
+ is0 = pINChISort;
2906
3086
  eq2taut = 0; /* equal to non-isotopic equivalence */
2907
3087
  eq2tautPrev = 1; /* pINChI_Aux_Prev (previous pINChI_Aux) does not exist */
2908
3088
  pPrevEquStr = NULL; /*, *pCurrEquStr;*/
2909
3089
  multPrevEquStr = 0;
2910
- for ( i = 0, is = pINChISort; i <= num_components; i ++, is ++ ) {
3090
+ for ( i = 0; i <= num_components; i ++ ) {
2911
3091
  /* 1st (taut) pass: bOutType=OUT_TN ; 2nd (non-taut pass) bOutType=OUT_NT */
2912
- pINChI_Aux = (i < num_components && 0 <= (ii=GET_II(bOutType,is)))? is->pINChI_Aux[ii] : NULL;
3092
+ pINChI_Aux = (i < num_components && (is=is0+i, 0 <= (ii=GET_II(bOutType,is))))? is->pINChI_Aux[ii] : NULL;
2913
3093
  /*================ compare iso non-taut equivalence info to non-iso taut ========*/
2914
3094
  eq2taut = 0;
2915
3095
  if ( bOmitRepetitions && pINChI_Aux && pINChI_Aux->bIsIsotopic ) {