rino 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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 ) {