rino 0.1.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 (87) hide show
  1. data/README +44 -0
  2. data/Rakefile +123 -0
  3. data/ext/extconf.rb +26 -0
  4. data/ext/ruby_inchi_main.so +0 -0
  5. data/ext/src/aux2atom.h +2786 -0
  6. data/ext/src/comdef.h +148 -0
  7. data/ext/src/e_0dstereo.c +3014 -0
  8. data/ext/src/e_0dstereo.h +31 -0
  9. data/ext/src/e_comdef.h +57 -0
  10. data/ext/src/e_ctl_data.h +147 -0
  11. data/ext/src/e_ichi_io.c +498 -0
  12. data/ext/src/e_ichi_io.h +40 -0
  13. data/ext/src/e_ichi_parms.c +37 -0
  14. data/ext/src/e_ichi_parms.h +41 -0
  15. data/ext/src/e_ichicomp.h +50 -0
  16. data/ext/src/e_ichierr.h +40 -0
  17. data/ext/src/e_ichimain.c +593 -0
  18. data/ext/src/e_ichisize.h +43 -0
  19. data/ext/src/e_inchi_atom.c +75 -0
  20. data/ext/src/e_inchi_atom.h +33 -0
  21. data/ext/src/e_inpdef.h +41 -0
  22. data/ext/src/e_mode.h +706 -0
  23. data/ext/src/e_mol2atom.c +649 -0
  24. data/ext/src/e_readinch.c +58 -0
  25. data/ext/src/e_readmol.c +54 -0
  26. data/ext/src/e_readmol.h +180 -0
  27. data/ext/src/e_readstru.c +251 -0
  28. data/ext/src/e_readstru.h +33 -0
  29. data/ext/src/e_util.c +284 -0
  30. data/ext/src/e_util.h +61 -0
  31. data/ext/src/extr_ct.h +251 -0
  32. data/ext/src/ichi.h +206 -0
  33. data/ext/src/ichi_bns.c +7999 -0
  34. data/ext/src/ichi_bns.h +231 -0
  35. data/ext/src/ichican2.c +5000 -0
  36. data/ext/src/ichicano.c +2195 -0
  37. data/ext/src/ichicano.h +49 -0
  38. data/ext/src/ichicans.c +1625 -0
  39. data/ext/src/ichicant.h +379 -0
  40. data/ext/src/ichicomn.h +260 -0
  41. data/ext/src/ichicomp.h +50 -0
  42. data/ext/src/ichidrp.h +119 -0
  43. data/ext/src/ichierr.h +124 -0
  44. data/ext/src/ichiisot.c +101 -0
  45. data/ext/src/ichilnct.c +286 -0
  46. data/ext/src/ichimain.h +132 -0
  47. data/ext/src/ichimak2.c +1189 -0
  48. data/ext/src/ichimake.c +3812 -0
  49. data/ext/src/ichimake.h +205 -0
  50. data/ext/src/ichimap1.c +851 -0
  51. data/ext/src/ichimap2.c +2856 -0
  52. data/ext/src/ichimap4.c +1609 -0
  53. data/ext/src/ichinorm.c +741 -0
  54. data/ext/src/ichinorm.h +67 -0
  55. data/ext/src/ichiparm.c +45 -0
  56. data/ext/src/ichiparm.h +1441 -0
  57. data/ext/src/ichiprt1.c +3612 -0
  58. data/ext/src/ichiprt2.c +1511 -0
  59. data/ext/src/ichiprt3.c +3011 -0
  60. data/ext/src/ichiqueu.c +1003 -0
  61. data/ext/src/ichiring.c +326 -0
  62. data/ext/src/ichiring.h +49 -0
  63. data/ext/src/ichisize.h +35 -0
  64. data/ext/src/ichisort.c +539 -0
  65. data/ext/src/ichister.c +3538 -0
  66. data/ext/src/ichister.h +35 -0
  67. data/ext/src/ichitaut.c +3843 -0
  68. data/ext/src/ichitaut.h +387 -0
  69. data/ext/src/ichitime.h +74 -0
  70. data/ext/src/inchi_api.h +670 -0
  71. data/ext/src/inchi_dll.c +1480 -0
  72. data/ext/src/inchi_dll.h +34 -0
  73. data/ext/src/inchi_dll_main.c +23 -0
  74. data/ext/src/inchi_dll_main.h +31 -0
  75. data/ext/src/inpdef.h +328 -0
  76. data/ext/src/lreadmol.h +1246 -0
  77. data/ext/src/mode.h +706 -0
  78. data/ext/src/ruby_inchi_main.c +558 -0
  79. data/ext/src/runichi.c +4179 -0
  80. data/ext/src/strutil.c +3861 -0
  81. data/ext/src/strutil.h +182 -0
  82. data/ext/src/util.c +1130 -0
  83. data/ext/src/util.h +85 -0
  84. data/lib/clean_tempfile.rb +220 -0
  85. data/lib/rino.rb +111 -0
  86. data/test/test.rb +386 -0
  87. metadata +130 -0
data/ext/src/runichi.c ADDED
@@ -0,0 +1,4179 @@
1
+ /*
2
+ * International Union of Pure and Applied Chemistry (IUPAC)
3
+ * International Chemical Identifier (InChI)
4
+ * Version 1
5
+ * Software version 1.00
6
+ * April 13, 2005
7
+ * Developed at NIST
8
+ */
9
+
10
+ #include <stdio.h>
11
+ #include <stdlib.h>
12
+ #include <string.h>
13
+ #include <ctype.h>
14
+ #include <stdarg.h>
15
+ /* #include <varargs.h> */
16
+ #include <errno.h>
17
+ #include <limits.h>
18
+
19
+ #include "mode.h" /* moved from below, suggestion by David Mosenkis */
20
+
21
+ #include "ichitime.h"
22
+
23
+ #ifndef INCHI_ANSI_ONLY
24
+ #include <conio.h>
25
+ #endif
26
+
27
+ #include "inpdef.h"
28
+ #include "ichi.h"
29
+ #include "strutil.h"
30
+ #include "util.h"
31
+ #include "ichidrp.h"
32
+ #include "ichierr.h"
33
+ #include "ichimain.h"
34
+ #include "extr_ct.h"
35
+
36
+ #ifdef INCHI_LIB
37
+ #include "ichi_lib.h"
38
+ #endif
39
+
40
+ #include "ichicomp.h"
41
+
42
+ #if( ADD_CMLPP == 1 )
43
+ #include "readcml.hpp"
44
+ #include "debug.h"
45
+ #endif
46
+
47
+ /* for DisplayTheWholeStructure() */
48
+
49
+ #define COMP_ORIG_0_MAIN 0x0001
50
+ #define COMP_ORIG_0_RECN 0x0002
51
+ #define COMP_PREP_0_MAIN 0x0004
52
+ #define COMP_PREP_0_RECN 0x0008
53
+ #define COMP_ORIG_1_MAIN 0x0010
54
+ #define COMP_ORIG_1_RECN 0x0020
55
+
56
+
57
+ /* local prototypes */
58
+ int GetProcessingWarningsOneINChI(INChI *pINChI, INP_ATOM_DATA *inp_norm_data, char *pStrErrStruct);
59
+ int GetProcessingWarnings(INChI *cur_INChI[], INP_ATOM_DATA **inp_norm_data, STRUCT_DATA *sd);
60
+ int DisplayTheWholeStructure( STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle, FILE *inp_file, INCHI_FILE *log_file,
61
+ ORIG_ATOM_DATA *orig_inp_data, int num_inp, int iINChI, int bShowStruct, int bINCHI_LIB_Flag );
62
+ int DuplicateOrigAtom( ORIG_ATOM_DATA *new_orig_atom, ORIG_ATOM_DATA *orig_atom );
63
+ int bCheckUnusualValences( ORIG_ATOM_DATA *orig_at_data, int bAddIsoH, char *pStrErrStruct );
64
+ int CreateCompositeNormAtom( COMP_ATOM_DATA *composite_norm_data, INP_ATOM_DATA2 *all_inp_norm_data,
65
+ PINChI2 *pINChI, PINChI_Aux2 *pINChI_Aux, int num_components, INCHI_MODE nMode );
66
+ int DetectInputINChIFileType( FILE **inp_file, INPUT_PARMS *ip, const char *fmode );
67
+ int GetMaxPrintfLength( const char *lpszFormat, va_list argList);
68
+
69
+ /* callback */
70
+ int (*ConsoleQuit)(void) = NULL; /* Console user issued CTRL+C etc. */
71
+ int (*UserAction)(void) = NULL; /* callback */
72
+
73
+ #ifdef INCHI_LIB
74
+ void (*FWPRINT) (const char * format, va_list argptr )=NULL;
75
+ void (*DRAWDATA) ( struct DrawData * pDrawData) = NULL;
76
+ int (*DRAWDATA_EXISTS) ( int nComponent, int nType, int bReconnected ) = NULL;
77
+ struct DrawData * (*GET_DRAWDATA) ( int nComponent, int nType, int bReconnected ) = NULL;
78
+ #endif
79
+
80
+ #if( TEST_RENUMB_ATOMS == 1 ) /* { */
81
+ /************************************************/
82
+ /* atoms renumbering -- for testing only */
83
+ /************************************************/
84
+ typedef struct tagRenumbData {
85
+ PINChI2 ren_INChI2[1];
86
+ PINChI_Aux2 ren_INChI_Aux[1];
87
+ INP_ATOM_DATA orig_inp_cur_data;
88
+ INP_ATOM_DATA saved_inp_cur_data;
89
+ #if( TEST_RENUMB_ATOMS_SAVE_LONGEST == 1 )
90
+ INP_ATOM_DATA longest_inp_cur_data;
91
+ #endif
92
+ INP_ATOM_DATA ren_inp_norm_data1, ren_inp_norm_data2;
93
+ INP_ATOM_DATA *ren_inp_norm_data[2];
94
+ int ren_counter;
95
+ int num_taut, num_non_taut, num_taut0, num_non_taut0;
96
+ AT_RANK *new_ord;
97
+ int nRet2, c1, c2, nComp, bRenumbErr;
98
+ unsigned long ulCurTimeNorm0, ulCurTimeCanon0, ulCurTimeNorm1, ulCurTimeCanon1;
99
+ unsigned long ulCurTimeNorm, ulCurTimeCanon, ulMaxTimeNorm, ulMaxTimeCanon;
100
+ unsigned long ulMaxTime, ulCurTime, ulCurTime0, ulCurTime1;
101
+ #if ( bRELEASE_VERSION == 0 )
102
+ int bExtract;
103
+ #endif
104
+ } RENUMB_DATA;
105
+
106
+ int RenumberingTestInit( RENUMB_DATA *pRenumbData, INP_ATOM_DATA *inp_cur_data );
107
+ int RenumberingTestUninit( RENUMB_DATA *pRenumbData );
108
+ int RenumberingTest( PINChI2 *pICh, PINChI_Aux2 *pINChI_Aux, ORIG_ATOM_DATA *orig_inp_data, int iINChI,
109
+ RENUMB_DATA *pRenumbData, INP_ATOM_DATA *inp_cur_data, INP_ATOM_DATA **inp_norm_data,
110
+ STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle, INCHI_FILE *log_file, INCHI_FILE *prb_file,
111
+ int i, int num_inp, NORM_CANON_FLAGS *pncFlags);
112
+ /*
113
+ int RenumberingTest( INChI *pINChI[][TAUT_NUM], INChI_Aux *pINChI_Aux[][TAUT_NUM], int iINChI,
114
+ RENUMB_DATA *pRenumbData, INP_ATOM_DATA *inp_cur_data, INP_ATOM_DATA **inp_norm_data,
115
+ STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle, INCHI_FILE *log_file, int i, int num_inp);
116
+ */
117
+ #endif /* } TEST_RENUMB_ATOMS */
118
+
119
+
120
+ #ifdef INCHI_LIBRARY
121
+ /*****************************************************************
122
+ *
123
+ * Estimate printf string length
124
+ *
125
+ * The code is based on Microsoft Knowledge Base article Q127038:
126
+ * "FIX: CString::Format Gives Assertion Failed, Access Violation"
127
+ * (Related to Microsoft Visual C++, 32-bit Editions, versions 2.0, 2.1)
128
+ *
129
+ *****************************************************************/
130
+
131
+ #define FORCE_ANSI 0x10000
132
+ #define FORCE_UNICODE 0x20000
133
+
134
+ /* formatting (using wsprintf style formatting)*/
135
+ int GetMaxPrintfLength( const char *lpszFormat, va_list argList)
136
+ {
137
+ /*ASSERT(AfxIsValidString(lpszFormat, FALSE));*/
138
+ const char * lpsz;
139
+ int nMaxLen, nWidth, nPrecision, nModifier, nItemLen;
140
+
141
+ nMaxLen = 0;
142
+ /* make a guess at the maximum length of the resulting string */
143
+ for ( lpsz = lpszFormat; *lpsz; lpsz ++ )
144
+ {
145
+ /* handle '%' character, but watch out for '%%' */
146
+ if (*lpsz != '%' || *( ++ lpsz ) == '%')
147
+ {
148
+ nMaxLen += 1;
149
+ continue;
150
+ }
151
+
152
+ nItemLen = 0;
153
+
154
+ /* handle '%' character with format */
155
+ nWidth = 0;
156
+ for (; *lpsz; lpsz ++ )
157
+ {
158
+ /* check for valid flags */
159
+ if (*lpsz == '#')
160
+ nMaxLen += 2; /* for '0x' */
161
+ else if (*lpsz == '*')
162
+ nWidth = va_arg(argList, int);
163
+ else if (*lpsz == '-' || *lpsz == '+' || *lpsz == '0'
164
+ || *lpsz == ' ')
165
+ ;
166
+ else /* hit non-flag character */
167
+ break;
168
+ }
169
+ /* get width and skip it */
170
+ if (nWidth == 0)
171
+ {
172
+ /* width indicated by */
173
+ nWidth = atoi(lpsz);
174
+ for (; *lpsz && isdigit(*lpsz); lpsz ++ )
175
+ ;
176
+ }
177
+ /*ASSERT(nWidth >= 0);*/
178
+ if ( nWidth < 0 )
179
+ goto exit_error; /* instead of exception */
180
+
181
+ nPrecision = 0;
182
+ if (*lpsz == '.')
183
+ {
184
+ /* skip past '.' separator (width.precision)*/
185
+ lpsz ++;
186
+
187
+ /* get precision and skip it*/
188
+ if (*lpsz == '*')
189
+ {
190
+ nPrecision = va_arg(argList, int);
191
+ lpsz ++;
192
+ }
193
+ else
194
+ {
195
+ nPrecision = atoi(lpsz);
196
+ for (; *lpsz && isdigit(*lpsz); lpsz ++)
197
+ ;
198
+ }
199
+ if ( nPrecision < 0 )
200
+ goto exit_error; /* instead of exception */
201
+ }
202
+
203
+ /* should be on type modifier or specifier */
204
+ nModifier = 0;
205
+ switch (*lpsz)
206
+ {
207
+ /* modifiers that affect size */
208
+ case 'h':
209
+ switch ( lpsz[1] ) {
210
+ case 'd':
211
+ case 'i':
212
+ case 'o':
213
+ case 'x':
214
+ case 'X':
215
+ case 'u':
216
+ /* short unsigned, short double, etc. -- added to the original MS example */
217
+ /* ignore the fact that these modifiers do affect size */
218
+ lpsz ++;
219
+ break;
220
+ default:
221
+ nModifier = FORCE_ANSI;
222
+ lpsz ++;
223
+ break;
224
+ }
225
+ break;
226
+ case 'l':
227
+ switch ( lpsz[1] ) {
228
+ case 'd':
229
+ case 'i':
230
+ case 'o':
231
+ case 'x':
232
+ case 'X':
233
+ case 'u':
234
+ case 'f': /* long float -- post ANSI C */
235
+ /* long unsigned, long double, etc. -- added to the original MS example */
236
+ /* ignore the fact that these modifiers do affect size */
237
+ lpsz ++;
238
+ break;
239
+ default:
240
+ /*
241
+ nModifier = FORCE_UNICODE;
242
+ lpsz ++;
243
+ break;
244
+ */
245
+ goto exit_error; /* no UNICODE, please */
246
+ }
247
+ break;
248
+ /* modifiers that do not affect size */
249
+ case 'F':
250
+ case 'N':
251
+ case 'L':
252
+ lpsz ++;
253
+ break;
254
+ }
255
+
256
+ /* now should be on specifier */
257
+ switch (*lpsz | nModifier)
258
+ {
259
+ /* single characters*/
260
+ case 'c':
261
+ case 'C':
262
+ nItemLen = 2;
263
+ va_arg(argList, int);
264
+ break;
265
+ case 'c'|FORCE_ANSI:
266
+ case 'C'|FORCE_ANSI:
267
+ nItemLen = 2;
268
+ va_arg(argList, int);
269
+ break;
270
+ case 'c'|FORCE_UNICODE:
271
+ case 'C'|FORCE_UNICODE:
272
+ goto exit_error; /* no UNICODE, please */
273
+ /*
274
+ nItemLen = 2;
275
+ va_arg(argList, wchar_t);
276
+ break;
277
+ */
278
+
279
+ /* strings*/
280
+ case 's':
281
+ case 'S':
282
+ nItemLen = strlen(va_arg(argList, char*));
283
+ nItemLen = inchi_max(1, nItemLen);
284
+ break;
285
+ case 's'|FORCE_ANSI:
286
+ case 'S'|FORCE_ANSI:
287
+ nItemLen = strlen(va_arg(argList, char*));
288
+ nItemLen = inchi_max(1, nItemLen);
289
+ break;
290
+
291
+ case 's'|FORCE_UNICODE:
292
+ case 'S'|FORCE_UNICODE:
293
+ goto exit_error; /* no UNICODE, please */
294
+ /*
295
+ nItemLen = wcslen(va_arg(argList, wchar_t*));
296
+ nItemLen = inchi_max(1, nItemLen);
297
+ break;
298
+ */
299
+
300
+ }
301
+
302
+ /* adjust nItemLen for strings */
303
+ if (nItemLen != 0)
304
+ {
305
+ nItemLen = inchi_max(nItemLen, nWidth);
306
+ if (nPrecision != 0)
307
+ nItemLen = inchi_min(nItemLen, nPrecision);
308
+ }
309
+ else
310
+ {
311
+ switch (*lpsz)
312
+ {
313
+ /* integers */
314
+ case 'd':
315
+ case 'i':
316
+ case 'u':
317
+ case 'x':
318
+ case 'X':
319
+ case 'o':
320
+ va_arg(argList, int);
321
+ nItemLen = 32;
322
+ nItemLen = inchi_max(nItemLen, nWidth+nPrecision);
323
+ break;
324
+
325
+ case 'e':
326
+ case 'f':
327
+ case 'g':
328
+ case 'G':
329
+ va_arg(argList, double);
330
+ nItemLen = 32;
331
+ nItemLen = inchi_max(nItemLen, nWidth+nPrecision);
332
+ break;
333
+
334
+ case 'p':
335
+ va_arg(argList, void*);
336
+ nItemLen = 32;
337
+ nItemLen = inchi_max(nItemLen, nWidth+nPrecision);
338
+ break;
339
+
340
+ /* no output */
341
+ case 'n':
342
+ va_arg(argList, int*);
343
+ break;
344
+
345
+ default:
346
+ /*ASSERT(FALSE);*/ /* unknown formatting option*/
347
+ goto exit_error; /* instead of exception */
348
+ }
349
+ }
350
+
351
+ /* adjust nMaxLen for output nItemLen */
352
+ nMaxLen += nItemLen;
353
+ }
354
+ return nMaxLen;
355
+
356
+ exit_error:
357
+ return -1; /* wrong format */
358
+ }
359
+ #define INCHI_ADD_STR_LEN 32768
360
+ #endif /* INCHI_LIBRARY */
361
+
362
+ #ifdef INCHI_LIBRARY
363
+ /*****************************************************************/
364
+ int inchi_print( INCHI_FILE* f, const char* lpszFormat, ... )
365
+ {
366
+ if ( f ) {
367
+ int ret=0, max_len;
368
+ va_list argList;
369
+ my_va_start( argList, lpszFormat );
370
+ max_len = GetMaxPrintfLength( lpszFormat, argList);
371
+ va_end( argList );
372
+
373
+ if ( max_len >= 0 ) {
374
+ if ( f->nAllocatedLength - f->nUsedLength <= max_len ) {
375
+ /* enlarge output string */
376
+ int nAddLength = inchi_max( INCHI_ADD_STR_LEN, max_len );
377
+ char *new_str = (char *)inchi_calloc( f->nAllocatedLength + nAddLength, sizeof(new_str[0]) );
378
+ if ( new_str ) {
379
+ if ( f->pStr ) {
380
+ if ( f->nUsedLength > 0 ) {
381
+ memcpy( new_str, f->pStr, sizeof(new_str[0])*f->nUsedLength );
382
+ }
383
+ inchi_free( f->pStr );
384
+ }
385
+ f->pStr = new_str;
386
+ f->nAllocatedLength += nAddLength;
387
+ } else {
388
+ return -1; /* failed */
389
+ }
390
+ }
391
+ /* output */
392
+ my_va_start( argList, lpszFormat );
393
+ ret = vsprintf( f->pStr + f->nUsedLength, lpszFormat, argList );
394
+ va_end(argList);
395
+ if ( ret >= 0 ) {
396
+ f->nUsedLength += ret;
397
+ }
398
+ return ret;
399
+ }
400
+ }
401
+ return -1;
402
+ }
403
+ #else
404
+ /*****************************************************************/
405
+ int inchi_print( INCHI_FILE* f, const char* lpszFormat, ... )
406
+ {
407
+ int ret=0, ret2=0;
408
+ /* char *p=NULL; */
409
+
410
+ va_list argList;
411
+
412
+ if ( f ) {
413
+ my_va_start( argList, lpszFormat );
414
+ ret = vfprintf( f, lpszFormat, argList );
415
+ va_end( argList );
416
+ } else {
417
+ /* printf( "\r" ); */
418
+ my_va_start( argList, lpszFormat );
419
+ //ret2 = vfprintf( stdout, lpszFormat, argList );
420
+ /* ret2 = vprintf( lpszFormat, argList ); */
421
+ va_end( argList );
422
+ }
423
+
424
+ #ifdef INCHI_LIB
425
+ if( FWPRINT )
426
+ {
427
+ my_va_start( argList, lpszFormat );
428
+ FWPRINT( lpszFormat, argList );
429
+ va_end( argList );
430
+ }
431
+ #endif
432
+ return ret? ret : ret2;
433
+ }
434
+ #endif
435
+
436
+
437
+ #ifdef INCHI_LIBRARY
438
+ /**********************************************************************/
439
+ /* This function's output should not be displayed in the output pane */
440
+ /**********************************************************************/
441
+ int inchi_print_nodisplay( INCHI_FILE* f, const char* lpszFormat, ... )
442
+ {
443
+ if ( f ) {
444
+ int ret=0, max_len;
445
+ va_list argList;
446
+ my_va_start( argList, lpszFormat );
447
+ max_len = GetMaxPrintfLength( lpszFormat, argList);
448
+ va_end( argList );
449
+
450
+ if ( max_len >= 0 ) {
451
+ if ( f->nAllocatedLength - f->nUsedLength <= max_len ) {
452
+ /* enlarge output string */
453
+ int nAddLength = inchi_max( INCHI_ADD_STR_LEN, max_len );
454
+ char *new_str = (char *)inchi_calloc( f->nAllocatedLength + nAddLength, sizeof(new_str[0]) );
455
+ if ( new_str ) {
456
+ if ( f->pStr ) {
457
+ if ( f->nUsedLength > 0 ) {
458
+ memcpy( new_str, f->pStr, sizeof(new_str[0])*f->nUsedLength );
459
+ }
460
+ inchi_free( f->pStr );
461
+ }
462
+ f->pStr = new_str;
463
+ f->nAllocatedLength += nAddLength;
464
+ } else {
465
+ return -1; /* failed */
466
+ }
467
+ }
468
+ /* output */
469
+ my_va_start( argList, lpszFormat );
470
+ ret = vsprintf( f->pStr + f->nUsedLength, lpszFormat, argList );
471
+ va_end(argList);
472
+ if ( ret >= 0 ) {
473
+ f->nUsedLength += ret;
474
+ }
475
+ return ret;
476
+ }
477
+ }
478
+ return -1;
479
+ }
480
+ #else
481
+ /**********************************************************************/
482
+ /* This function's output should not be displayed in the output pane */
483
+ /**********************************************************************/
484
+ int inchi_print_nodisplay( INCHI_FILE* f, const char* lpszFormat, ... )
485
+ {
486
+ int ret=0, ret2=0;
487
+ /* char *p=NULL; */
488
+
489
+ va_list argList;
490
+
491
+ if ( f ) {
492
+ my_va_start( argList, lpszFormat );
493
+ ret = vfprintf( f, lpszFormat, argList );
494
+ va_end( argList );
495
+ } else {
496
+ /* printf( "\r" ); */
497
+ my_va_start( argList, lpszFormat );
498
+ ret2 = vfprintf( stdout, lpszFormat, argList );
499
+ /* ret2 = vprintf( lpszFormat, argList ); */
500
+ va_end( argList );
501
+ }
502
+
503
+ return ret? ret : ret2;
504
+ }
505
+ #endif
506
+ #ifdef INCHI_LIBRARY
507
+ /*****************************************************************/
508
+ int my_fprintf( INCHI_FILE* f, const char* lpszFormat, ... )
509
+ {
510
+ if ( f ) {
511
+ int ret=0, max_len;
512
+ va_list argList;
513
+ my_va_start( argList, lpszFormat );
514
+ max_len = GetMaxPrintfLength( lpszFormat, argList);
515
+ va_end( argList );
516
+
517
+ if ( max_len >= 0 ) {
518
+ if ( f->nAllocatedLength - f->nUsedLength <= max_len ) {
519
+ /* enlarge output string */
520
+ int nAddLength = inchi_max( INCHI_ADD_STR_LEN, max_len );
521
+ char *new_str = (char *)inchi_calloc( f->nAllocatedLength + nAddLength, sizeof(new_str[0]) );
522
+ if ( new_str ) {
523
+ if ( f->pStr ) {
524
+ if ( f->nUsedLength > 0 ) {
525
+ memcpy( new_str, f->pStr, sizeof(new_str[0])*f->nUsedLength );
526
+ }
527
+ inchi_free( f->pStr );
528
+ }
529
+ f->pStr = new_str;
530
+ f->nAllocatedLength += nAddLength;
531
+ } else {
532
+ return -1; /* failed */
533
+ }
534
+ }
535
+ /* output */
536
+ my_va_start( argList, lpszFormat );
537
+ ret = vsprintf( f->pStr + f->nUsedLength, lpszFormat, argList );
538
+ va_end(argList);
539
+ if ( ret >= 0 ) {
540
+ f->nUsedLength += ret;
541
+ }
542
+ return ret;
543
+ }
544
+ }
545
+ return -1;
546
+ }
547
+ #else
548
+ /*****************************************************************/
549
+ int my_fprintf( INCHI_FILE* f, const char* lpszFormat, ... )
550
+ {
551
+ int ret=0, ret2=0;
552
+ va_list argList;
553
+
554
+ #ifndef INCHI_LIB
555
+ if ( f ) {
556
+ if ( f == stderr && lpszFormat && lpszFormat[0] && '\r' == lpszFormat[strlen(lpszFormat)-1] ) {
557
+ #define CONSOLE_LINE_LEN 80
558
+ #ifndef INCHI_ANSI_ONLY
559
+ char szLine[CONSOLE_LINE_LEN];
560
+ my_va_start( argList, lpszFormat );
561
+ ret = _vsnprintf( szLine, CONSOLE_LINE_LEN-1, lpszFormat, argList );
562
+ va_end( argList );
563
+ if ( ret < 0 ) {
564
+ /* output is longer than the console line */
565
+ strcpy(szLine+CONSOLE_LINE_LEN-4, "...\r");
566
+ }
567
+ fputs( szLine, f );
568
+ #else
569
+ my_va_start( argList, lpszFormat );
570
+ ret = vfprintf( f, lpszFormat, argList );
571
+ va_end( argList );
572
+ #endif
573
+ #undef CONSOLE_LINE_LEN
574
+ } else {
575
+ my_va_start( argList, lpszFormat );
576
+ ret = vfprintf( f, lpszFormat, argList );
577
+ va_end( argList );
578
+ }
579
+ }
580
+ if ( f != stderr ) {
581
+ my_va_start( argList, lpszFormat );
582
+ //ret2 = vfprintf( stderr, lpszFormat, argList );
583
+ va_end( argList );
584
+ }
585
+ #else
586
+ if ( f ) {
587
+ my_va_start( argList, lpszFormat );
588
+ ret = vfprintf( f, lpszFormat, argList );
589
+ va_end( argList );
590
+ }
591
+ #endif
592
+
593
+ return ret? ret : ret2;
594
+ }
595
+ #endif
596
+ #ifndef INCHI_ANSI_ONLY
597
+ /********************************************************************/
598
+ void FillTableParms( SET_DRAW_PARMS *sdp, INChI **cur_INChI, INChI_Aux **cur_INChI_Aux,
599
+ INCHI_MODE nMode, int bShowIsotopic, int indx )
600
+ {
601
+ TBL_DRAW_PARMS *tdp = sdp->tdp;
602
+ char (*ReqShownFound)[TDP_NUM_PAR] = tdp->ReqShownFound;
603
+ int i, j;
604
+ INChI_Stereo *Stereo;
605
+ int bShowTaut = (cur_INChI && cur_INChI[indx]->lenTautomer > 0)? 1 : 0;
606
+ int bRelRac = 0 != (nMode & (REQ_MODE_RELATIVE_STEREO | REQ_MODE_RACEMIC_STEREO ));
607
+
608
+ if ( !cur_INChI || !cur_INChI_Aux ) {
609
+ sdp->tdp->bDrawTbl = 0;
610
+ sdp->bOrigAtom = 1;
611
+ return;
612
+ }
613
+
614
+ /* Displayed */
615
+ ReqShownFound[ilSHOWN][itBASIC] = bShowTaut? 'T':'\0';
616
+ ReqShownFound[ilSHOWN][itISOTOPIC] = bShowIsotopic? 'I':'\0';
617
+ /*
618
+ ReqShownFound[ilSHOWN][itBASIC] = bShowTaut? 'T':'B';
619
+ ReqShownFound[ilSHOWN][itISOTOPIC] = bShowIsotopic? 'I':'N';
620
+ */
621
+ i = indx;
622
+ if ( cur_INChI[i] ) {
623
+ Stereo = bShowIsotopic? cur_INChI[i]->StereoIsotopic : cur_INChI[i]->Stereo;
624
+ } else {
625
+ Stereo = NULL;
626
+ }
627
+ #if( REL_RAC_STEREO_IGN_1_SC == 1 )
628
+ if ( Stereo && ( 0 < Stereo->nNumberOfStereoBonds ||
629
+ 0 < Stereo->nNumberOfStereoCenters-bRelRac ) ) {
630
+ ReqShownFound[ilSHOWN][itSTEREO] = 'S';
631
+ if ( Stereo->nNumberOfStereoCenters && Stereo->nCompInv2Abs == -1 &&
632
+ ( nMode & (REQ_MODE_RELATIVE_STEREO | REQ_MODE_RACEMIC_STEREO ) ) ) {
633
+ if ( Stereo->nNumberOfStereoCenters < 2 && !Stereo->nNumberOfStereoBonds ) {
634
+ ReqShownFound[ilSHOWN][itSTEREO] = '\0';
635
+ } else
636
+ if ( Stereo->nNumberOfStereoCenters >= 2 ) {
637
+ ReqShownFound[ilSHOWN][itSTEREO] = 's'; /* shown Inverted stereo */
638
+ }
639
+ }
640
+ #else /* REL_RAC_STEREO_IGN_1_SC == 0 */
641
+ if ( Stereo && ( Stereo->nNumberOfStereoBonds || Stereo->nNumberOfStereoCenters ) ) {
642
+ ReqShownFound[ilSHOWN][itSTEREO] = 'S';
643
+ if ( Stereo->nNumberOfStereoCenters && Stereo->nCompInv2Abs == -1 &&
644
+ ( nMode & (REQ_MODE_RELATIVE_STEREO | REQ_MODE_RACEMIC_STEREO ) ) ) {
645
+ /*
646
+ if ( Stereo->nNumberOfStereoCenters < 2 && !Stereo->nNumberOfStereoBonds ) {
647
+ ReqShownFound[ilSHOWN][itSTEREO] = '\0';
648
+ } else
649
+ if ( Stereo->nNumberOfStereoCenters >= 2 ) {
650
+ */
651
+ ReqShownFound[ilSHOWN][itSTEREO] = 's'; /* shown Inverted stereo */
652
+ /*
653
+ }
654
+ */
655
+ }
656
+ #endif /* REL_RAC_STEREO_IGN_1_SC */
657
+ } else {
658
+ ReqShownFound[ilSHOWN][itSTEREO] = '\0';
659
+ }
660
+ /*
661
+ ReqShownFound[ilSHOWN][itSTEREO] =
662
+ (bShowIsotopic? (cur_INChI[i] && cur_INChI[i]->StereoIsotopic &&
663
+ (cur_INChI[i]->StereoIsotopic->nNumberOfStereoBonds ||
664
+ cur_INChI[i]->StereoIsotopic->nNumberOfStereoCenters) )
665
+ :
666
+ (cur_INChI[i] && cur_INChI[i]->Stereo &&
667
+ (cur_INChI[i]->Stereo->nNumberOfStereoBonds ||
668
+ cur_INChI[i]->Stereo->nNumberOfStereoCenters) )
669
+ ) ? 'S':'\0';
670
+ */
671
+
672
+ /* remove zeroes between chars */
673
+ for ( i = j = 0; i < TDP_NUM_PAR; i ++ ) {
674
+ if ( ReqShownFound[ilSHOWN][i] >= ' ' ) {
675
+ ReqShownFound[ilSHOWN][j++] = ReqShownFound[ilSHOWN][i];
676
+ }
677
+ }
678
+ i = j;
679
+ for ( ; i < TDP_NUM_PAR; i ++ ) {
680
+ ReqShownFound[ilSHOWN][i] = '\0';
681
+ }
682
+
683
+ sdp->tdp->bDrawTbl = j? 1 : 0;
684
+ sdp->bOrigAtom = 0;
685
+ }
686
+ /********************************************************************/
687
+ void FillCompositeTableParms( SET_DRAW_PARMS *sdp, AT_NUMB StereoFlags,
688
+ INCHI_MODE nMode, int bShowIsotopic, int bShowTaut )
689
+ {
690
+ TBL_DRAW_PARMS *tdp = sdp->tdp;
691
+ char (*ReqShownFound)[TDP_NUM_PAR] = tdp->ReqShownFound;
692
+ int i, j;
693
+
694
+ /* Displayed */
695
+ ReqShownFound[ilSHOWN][itBASIC] = bShowTaut? 'T':'\0';
696
+ ReqShownFound[ilSHOWN][itISOTOPIC] = bShowIsotopic? 'I':'\0';
697
+ /*
698
+ ReqShownFound[ilSHOWN][itBASIC] = bShowTaut? 'T':'B';
699
+ ReqShownFound[ilSHOWN][itISOTOPIC] = bShowIsotopic? 'I':'N';
700
+ */
701
+ if ( StereoFlags & INF_STEREO ) {
702
+ ReqShownFound[ilSHOWN][itSTEREO] = 'S';
703
+ if ( (StereoFlags & INF_STEREO_INV) &&
704
+ ( nMode & (REQ_MODE_RELATIVE_STEREO | REQ_MODE_RACEMIC_STEREO ) ) ) {
705
+ if (StereoFlags & (INF_STEREO_REL | INF_STEREO_RAC) ) {
706
+ ReqShownFound[ilSHOWN][itSTEREO] = 's';
707
+ } else {
708
+ ReqShownFound[ilSHOWN][itSTEREO] = '\0'; /* shown Inverted stereo */
709
+ }
710
+ }
711
+ } else {
712
+ ReqShownFound[ilSHOWN][itSTEREO] = '\0';
713
+ }
714
+ /*
715
+ ReqShownFound[ilSHOWN][itSTEREO] =
716
+ (bShowIsotopic? (cur_INChI[i] && cur_INChI[i]->StereoIsotopic &&
717
+ (cur_INChI[i]->StereoIsotopic->nNumberOfStereoBonds ||
718
+ cur_INChI[i]->StereoIsotopic->nNumberOfStereoCenters) )
719
+ :
720
+ (cur_INChI[i] && cur_INChI[i]->Stereo &&
721
+ (cur_INChI[i]->Stereo->nNumberOfStereoBonds ||
722
+ cur_INChI[i]->Stereo->nNumberOfStereoCenters) )
723
+ ) ? 'S':'\0';
724
+ */
725
+
726
+ /* remove zeroes between chars */
727
+ for ( i = j = 0; i < TDP_NUM_PAR; i ++ ) {
728
+ if ( ReqShownFound[ilSHOWN][i] >= ' ' ) {
729
+ ReqShownFound[ilSHOWN][j++] = ReqShownFound[ilSHOWN][i];
730
+ }
731
+ }
732
+ i = j;
733
+ for ( ; i < TDP_NUM_PAR; i ++ ) {
734
+ ReqShownFound[ilSHOWN][i] = '\0';
735
+ }
736
+
737
+ sdp->tdp->bDrawTbl = j? 1 : 0;
738
+ sdp->bOrigAtom = 0;
739
+ }
740
+ #endif
741
+ /* IchiParm.c was here */
742
+ /*******************************************************************/
743
+ #ifndef INCHI_ANSI_ONLY
744
+ #ifndef INCHI_LIB
745
+ /*******************************************************************/
746
+ int DisplayStructure( inp_ATOM *at, int num_at, int num_removed_H,
747
+ int nNumRemovedProtons, NUM_H *nNumRemovedProtonsIsotopic,
748
+ int bIsotopic, int j /*bTautomeric*/,
749
+ INChI **cur_INChI, INChI_Aux **cur_INChI_Aux,
750
+ int bAbcNumbers, DRAW_PARMS *dp, INCHI_MODE nMode, char *szTitle )
751
+ {
752
+ INF_ATOM_DATA inf_data = {NULL,};
753
+ int err = -1;
754
+ if ( CreateInfoAtomData( &inf_data, num_at, 1 ) ) {
755
+ err = 0;
756
+ FillOutInfAtom( at, &inf_data, num_at, num_removed_H, nNumRemovedProtons,
757
+ nNumRemovedProtonsIsotopic, bIsotopic,
758
+ cur_INChI?cur_INChI[j]:NULL,
759
+ cur_INChI_Aux?cur_INChI_Aux[j]:NULL, bAbcNumbers, nMode);
760
+ FillTableParms( &dp->sdp, cur_INChI, cur_INChI_Aux, nMode, bIsotopic, j );
761
+ err = DisplayInputStructure( szTitle, at, &inf_data, num_at, dp );
762
+ FreeInfoAtomData( &inf_data );
763
+ }
764
+ return err;
765
+ }
766
+
767
+ /*******************************************************************/
768
+ int DisplayCompositeStructure( COMP_ATOM_DATA *composite_norm_data, int bIsotopic, int bTautomeric,
769
+ PINChI2 *pINChI2, PINChI_Aux2 *pINChI_Aux2,
770
+ int bAbcNumbers, DRAW_PARMS *dp, INCHI_MODE nMode, char *szTitle )
771
+ {
772
+ INF_ATOM_DATA inf_data;
773
+ int err = -1, ret;
774
+ memset( &inf_data, 0, sizeof(inf_data) );
775
+ if ( CreateInfoAtomData( &inf_data, (composite_norm_data+bTautomeric)->num_at,
776
+ (composite_norm_data+bTautomeric)->num_components ) ) {
777
+ ret = FillOutCompositeCanonInfAtom(composite_norm_data, &inf_data,
778
+ bIsotopic, bTautomeric,
779
+ pINChI2, pINChI_Aux2, bAbcNumbers, nMode);
780
+ if ( !ret ) {
781
+ goto exit_function; /* error */
782
+ }
783
+ if ( bTautomeric == TAUT_INI ) {
784
+ /*
785
+ FillOutInfAtom( (composite_norm_data+bTautomeric)->at, &inf_data, (composite_norm_data+bTautomeric)->num_at,
786
+ (composite_norm_data+bTautomeric)->num_removed_H,
787
+ (composite_norm_data+bTautomeric)->nNumRemovedProtons,
788
+ (composite_norm_data+bTautomeric)->nNumRemovedProtonsIsotopic, bIsotopic,
789
+ NULL, NULL, bAbcNumbers, nMode);
790
+ */
791
+ ;
792
+ } else {
793
+ /* real check for tautomeric components 02-04-2005 */
794
+ int m, nNumTautComponents = 0;
795
+ if ( 1 == bTautomeric ) {
796
+ for ( m = 0; m < composite_norm_data[TAUT_YES].num_components; m ++ ) {
797
+ if ( !pINChI2[m][TAUT_YES] )
798
+ continue;
799
+ if ( pINChI2[m][TAUT_YES]->bDeleted || pINChI2[m][TAUT_YES]->lenTautomer > 0 )
800
+ nNumTautComponents ++;
801
+ }
802
+ }
803
+ FillCompositeTableParms( &dp->sdp, inf_data.StereoFlags, nMode, bIsotopic, nNumTautComponents );
804
+ }
805
+ err = DisplayInputStructure( szTitle, (composite_norm_data+bTautomeric)->at, &inf_data, (composite_norm_data+bTautomeric)->num_at, dp );
806
+ FreeInfoAtomData( &inf_data );
807
+ }
808
+ exit_function:
809
+ return err;
810
+ }
811
+ #endif
812
+ #endif
813
+ /************************************************/
814
+ const char *ErrMsg( int nErrorCode )
815
+ {
816
+ const char *p;
817
+ static char szErrMsg[64];
818
+ switch( nErrorCode ) {
819
+ case 0: p = ""; break;
820
+ case CT_OVERFLOW: p = "ARRAY OVERFLOW"; break;
821
+ case CT_LEN_MISMATCH: p = "LENGTH_MISMATCH"; break;
822
+ case CT_OUT_OF_RAM: p = "Out of RAM"; break;
823
+ case CT_RANKING_ERR: p = "RANKING_ERR"; break;
824
+ case CT_ISOCOUNT_ERR: p = "ISOCOUNT_ERR"; break;
825
+ case CT_TAUCOUNT_ERR: p = "TAUCOUNT_ERR"; break;
826
+ case CT_ISOTAUCOUNT_ERR: p = "ISOTAUCOUNT_ERR"; break;
827
+ case CT_MAPCOUNT_ERR: p = "MAPCOUNT_ERR"; break;
828
+ case CT_TIMEOUT_ERR: p = "Time limit exceeded"; break;
829
+ case CT_ISO_H_ERR: p = "ISO_H_ERR"; break;
830
+ case CT_STEREOCOUNT_ERR: p = "STEREOCOUNT_ERR"; break;
831
+ case CT_ATOMCOUNT_ERR: p = "ATOMCOUNT_ERR"; break;
832
+ case CT_STEREOBOND_ERROR: p = "STEREOBOND_ERR"; break;
833
+ case CT_USER_QUIT_ERR: p = "User requested termination"; break;
834
+ case CT_REMOVE_STEREO_ERR: p = "REMOVE_STEREO_ERR"; break;
835
+ case CT_CALC_STEREO_ERR: p = "CALC_STEREO_ERR"; break;
836
+ case CT_STEREO_CANON_ERR: p = "STEREO_CANON_ERR"; break;
837
+ case CT_CANON_ERR: p = "CANON_ERR"; break;
838
+ /*case CT_CANON_ERR2: p = "CT_CANON_ERR2"; break;*/
839
+ case CT_UNKNOWN_ERR: p = "UNKNOWN_ERR"; break;
840
+ case BNS_RADICAL_ERR: p = "Cannot process free radical center"; break;
841
+
842
+ default:
843
+ if ( nErrorCode > CT_UNKNOWN_ERR ) {
844
+ sprintf( szErrMsg, "No description(%d)", nErrorCode );
845
+ p = szErrMsg;
846
+ } else {
847
+ sprintf( szErrMsg, "UNKNOWN_ERR(%d)", CT_UNKNOWN_ERR - nErrorCode );
848
+ p = szErrMsg;
849
+ }
850
+ break;
851
+ }
852
+ return p;
853
+ }
854
+ /***********************************************************************************/
855
+ #ifndef INCHI_ANSI_ONLY /* { */
856
+ /***********************************************************************************/
857
+ int SaveEquComponentsInfoAndSortOrder ( int iINChI, INCHI_SORT *pINChISort[TAUT_NUM], int *num_components,
858
+ ORIG_ATOM_DATA *orig_inp_data, ORIG_ATOM_DATA *prep_inp_data,
859
+ COMP_ATOM_DATA composite_norm_data[TAUT_NUM+1],
860
+ int bCompareComponents )
861
+ {
862
+ int nRet = 0, i, k, nNumDeleted;
863
+ /* equivalent components and sorting order */
864
+ /* bCompareComponents: bit = 1 => compare */
865
+ /* bit = 2 => compare non-isotopic */
866
+ /* bit = 4 => compare non-tautomeric */
867
+ int bCompareIsotopic, bCompareTaut, bCompareAlt;
868
+ ORIG_ATOM_DATA *inp_data = NULL;
869
+
870
+ if ( num_components[iINChI] <= 1 )
871
+ return 0;
872
+ #ifdef INCHI_LIB
873
+ if ( !DRAWDATA )
874
+ return 0;
875
+ #endif
876
+ if ( !(bCompareComponents & CMP_COMPONENTS) )
877
+ return 0;
878
+ bCompareIsotopic = !(bCompareComponents & CMP_COMPONENTS_NONISO);
879
+ bCompareTaut = (bCompareComponents & CMP_COMPONENTS_NONTAUT) ? TAUT_NON : TAUT_YES;
880
+ bCompareAlt = ALT_TAUT(bCompareTaut);
881
+ if ( num_components[iINChI] > 1 ) {
882
+ if ( prep_inp_data[iINChI].bSavedInINCHI_LIB[iINChI] && prep_inp_data[iINChI].bPreprocessed[iINChI] ) {
883
+ inp_data = prep_inp_data+iINChI;
884
+ } else
885
+ if ( orig_inp_data->bSavedInINCHI_LIB[iINChI] && !orig_inp_data->bPreprocessed[iINChI] ) {
886
+ inp_data = orig_inp_data;
887
+ } else {
888
+ inp_data = NULL;
889
+ }
890
+ if ( inp_data && !inp_data->nEquLabels && !prep_inp_data[iINChI].nSortedOrder ) {
891
+ int i1, i2, nSet;
892
+ AT_NUMB nAtNo;
893
+ AT_NUMB nNumAtoms = (AT_NUMB)inp_data->num_inp_atoms;
894
+ if ( (prep_inp_data[iINChI].nSortedOrder =
895
+ (AT_NUMB *)inchi_calloc(num_components[iINChI]+1,
896
+ sizeof(prep_inp_data[0].nSortedOrder[0])))) {
897
+ inp_data->nNumEquSets = 0;
898
+ for ( i1 = 0, nSet = 0; i1 < num_components[iINChI]; i1 = i2 ) {
899
+ nNumDeleted = (pINChISort[bCompareTaut][i1].pINChI[bCompareTaut] && pINChISort[bCompareTaut][i1].pINChI[bCompareTaut]->bDeleted);
900
+ for ( i2 = i1+1; i2 < num_components[iINChI]; i2 ++ ) {
901
+ /* isotopic/non-isotopic comparison does not separate equivalent components */
902
+ if ( CompINChI2( pINChISort[bCompareTaut]+i1, pINChISort[bCompareTaut]+i2, bCompareTaut, bCompareIsotopic ) ) {
903
+ break;
904
+ } else {
905
+ nNumDeleted += (pINChISort[bCompareTaut][i2].pINChI[bCompareTaut] && pINChISort[bCompareTaut][i2].pINChI[bCompareTaut]->bDeleted);
906
+ }
907
+ }
908
+ if ( i2 - i1 - nNumDeleted > 1 ) {
909
+ if ( inp_data->nEquLabels ||
910
+ (inp_data->nEquLabels = (AT_NUMB *)inchi_calloc(inp_data->num_inp_atoms+1,
911
+ sizeof(inp_data->nEquLabels[0]))) ) {
912
+ nSet ++; /* found i2-i1 equivalent components && memory has been allocated */
913
+ for ( i = i1; i < i2; i ++ ) {
914
+ INChI_Aux *pINChI_Aux;
915
+ if (pINChISort[bCompareTaut][i].pINChI[bCompareTaut] && pINChISort[bCompareTaut][i].pINChI[bCompareTaut]->bDeleted)
916
+ continue;
917
+ pINChI_Aux = (pINChISort[bCompareTaut][i].pINChI_Aux[bCompareTaut] &&
918
+ pINChISort[bCompareTaut][i].pINChI_Aux[bCompareTaut]->nNumberOfAtoms)?
919
+ pINChISort[bCompareTaut][i].pINChI_Aux[bCompareTaut]:
920
+ (pINChISort[bCompareTaut][i].pINChI_Aux[bCompareAlt] &&
921
+ pINChISort[bCompareTaut][i].pINChI_Aux[bCompareAlt]->nNumberOfAtoms)?
922
+ pINChISort[bCompareTaut][i].pINChI_Aux[bCompareAlt]:
923
+ (INChI_Aux *)NULL;
924
+ if ( pINChI_Aux && pINChI_Aux->nOrigAtNosInCanonOrd ) {
925
+ for ( k = 0; k < pINChI_Aux->nNumberOfAtoms; k ++ ) {
926
+ if ( (nAtNo = pINChI_Aux->nOrigAtNosInCanonOrd[k]) &&
927
+ nAtNo <= nNumAtoms ) {
928
+ inp_data->nEquLabels[nAtNo-1] = nSet;
929
+ }
930
+ }
931
+ }
932
+ }
933
+ } else {
934
+ return CT_OUT_OF_RAM;
935
+ }
936
+ }
937
+ }
938
+ nRet |= nSet? 1:0;
939
+ } else {
940
+ return CT_OUT_OF_RAM;
941
+ }
942
+ inp_data->nNumEquSets = nSet;
943
+ /* output order */
944
+ prep_inp_data[iINChI].nSortedOrder[0] = 0;
945
+ for ( i1 = 0; i1 < num_components[iINChI]; i1 ++ ) {
946
+ prep_inp_data[iINChI].nSortedOrder[i1+1] = pINChISort[TAUT_YES][i1].ord_number+1;
947
+ }
948
+ #ifdef INCHI_LIB /* { */
949
+ if ( DRAWDATA && GET_DRAWDATA && inp_data->nNumEquSets > 0 && inp_data->nEquLabels ) {
950
+ int nType = inp_data->bPreprocessed[iINChI]?
951
+ COMPONENT_ORIGINAL_PREPROCESSED :
952
+ COMPONENT_ORIGINAL;
953
+ struct DrawData *pDrawData = GET_DRAWDATA( 0, nType, iINChI);
954
+ if ( pDrawData && pDrawData->pWindowData && !pDrawData->pWindowData->nEquLabels ) {
955
+ /* copy equivalence data from inp_data to pDrawData->pWindowData */
956
+ if ( inp_data->nEquLabels &&
957
+ (pDrawData->pWindowData->nEquLabels = (AT_NUMB *)inchi_calloc(inp_data->num_inp_atoms,
958
+ sizeof(inp_data->nEquLabels[0])))) {
959
+ memcpy( pDrawData->pWindowData->nEquLabels, inp_data->nEquLabels,
960
+ inp_data->num_inp_atoms * sizeof(inp_data->nEquLabels[0]));
961
+ pDrawData->pWindowData->nNumEquSets = inp_data->nNumEquSets;
962
+ pDrawData->pWindowData->nCurEquLabel = 0;
963
+ }
964
+ }
965
+ }
966
+ #endif /* } INCHI_LIB */
967
+ }
968
+ }
969
+ return nRet;
970
+ }
971
+
972
+ /************************************************************************************************/
973
+ int DisplayTheWholeCompositeStructure( INPUT_PARMS *ip, STRUCT_DATA *sd, int num_inp, int iINChI,
974
+ PINChI2 *pINChI2, PINChI_Aux2 *pINChI_Aux2,
975
+ ORIG_ATOM_DATA *orig_inp_data, ORIG_ATOM_DATA *prep_inp_data,
976
+ COMP_ATOM_DATA composite_norm_data[TAUT_NUM+1] )
977
+ {
978
+ ORIG_ATOM_DATA *inp_data = NULL;
979
+ int jj, j, k, err = 0, nNumIntermediateTaut = 0, bDisplayTaut;
980
+ char szTitle[256];
981
+ int nNumTautComponents, m;
982
+
983
+ int bCompareIsotopic = !(ip->bCompareComponents & CMP_COMPONENTS_NONISO);
984
+ int bCompareTaut = (ip->bCompareComponents & CMP_COMPONENTS_NONTAUT) ? TAUT_NON : TAUT_YES;
985
+
986
+ if ( ip->bCompareComponents & CMP_COMPONENTS ) {
987
+ if ( prep_inp_data[iINChI].bSavedInINCHI_LIB[iINChI] && prep_inp_data[iINChI].bPreprocessed[iINChI] ) {
988
+ inp_data = prep_inp_data+iINChI;
989
+ } else
990
+ if ( orig_inp_data->bSavedInINCHI_LIB[iINChI] && !orig_inp_data->bPreprocessed[iINChI] ) {
991
+ inp_data = orig_inp_data;
992
+ }
993
+ }
994
+ /**************************************************************************
995
+ * display from one up to 4 structure pictures-results for all components *
996
+ * Enable buttons: *
997
+ * BN (non-tautomeric non-isotopic): inp_norm_data[0]->bExists *
998
+ * TN (tautomeric non-isotopic): inp_norm_data[1]->bExists *
999
+ * BI (non-tautomeric isotopic): inp_norm_data[0]->bExists && *
1000
+ * inp_norm_data[0]->bHasIsotopicLayer *
1001
+ * TI (tautomeric isotopic): inp_norm_data[1]->bExists && *
1002
+ * inp_norm_data[1]->bHasIsotopicLayer *
1003
+ **************************************************************************/
1004
+ for ( jj = 0; ip->bDisplayCompositeResults && !sd->bUserQuitComponentDisplay && jj <= TAUT_INI; jj ++ ) {
1005
+ /*for ( j = 0; ip->bDisplayCompositeResults && !sd->bUserQuitComponentDisplay && j <= TAUT_INI; j ++ )*/
1006
+ j = (jj==0)? TAUT_NON : (jj==1)? TAUT_INI : (jj==2)? TAUT_YES : -1;
1007
+ if ( j < 0 )
1008
+ continue;
1009
+ if ( composite_norm_data[j].bExists && composite_norm_data[j].num_components > 1 ) {
1010
+ bDisplayTaut = (!(ip->nMode & REQ_MODE_BASIC) && !j)? -1 : j;
1011
+ nNumTautComponents = 0;
1012
+ if ( bDisplayTaut ) {
1013
+ /* find whether the structure is actually tautomeric */
1014
+ for ( m = 0; m < composite_norm_data[TAUT_YES].num_components; m ++ ) {
1015
+ if ( !pINChI2[m][TAUT_YES] )
1016
+ continue;
1017
+ if ( pINChI2[m][TAUT_YES]->bDeleted || pINChI2[m][TAUT_YES]->lenTautomer > 0 )
1018
+ nNumTautComponents ++;
1019
+ }
1020
+ }
1021
+ for ( k = 0; k <= composite_norm_data[j].bHasIsotopicLayer && !sd->bUserQuitComponentDisplay; k ++ ) {
1022
+ /* added number of components, added another format for a single component case - DCh */
1023
+ int bMobileH = (bDisplayTaut>0 && nNumTautComponents);
1024
+ sprintf( szTitle, "%s Structure #%d%s%s.%s%s%s%s%s",
1025
+ j == TAUT_INI? "Preprocessed":"Result for", num_inp,
1026
+ bMobileH? ", mobile H":
1027
+ bDisplayTaut==0?", fixed H":"",
1028
+ /*j? ", mobile H":", fixed H",*/
1029
+ k? ", isotopic":"",
1030
+ SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), iINChI? " (Reconnected)":"");
1031
+ #ifndef INCHI_LIB
1032
+ /****** Display composite Result structure **************/
1033
+ nNumIntermediateTaut += (j == TAUT_INI ); /* display TAUT_INI (preprocessed) only once */
1034
+ if ( j != TAUT_INI || nNumIntermediateTaut == 1 ) {
1035
+ err = DisplayCompositeStructure( composite_norm_data, j==TAUT_INI? 1:k /* bIsotopic*/,
1036
+ j/*tautomeric*/,
1037
+ j==TAUT_INI? NULL:pINChI2, j==TAUT_INI? NULL:pINChI_Aux2,
1038
+ ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
1039
+ }
1040
+ if ( sd->bUserQuitComponentDisplay = (err==ESC_KEY) ) {
1041
+ break;
1042
+ }
1043
+
1044
+ if ( inp_data && inp_data->nEquLabels && inp_data->nNumEquSets && !sd->bUserQuitComponentDisplay &&
1045
+ ((j == bCompareTaut || bCompareTaut && j == TAUT_INI) ||
1046
+ bCompareTaut && !composite_norm_data[bCompareTaut].bExists) &&
1047
+ (k == bCompareIsotopic ||
1048
+ bCompareIsotopic && !composite_norm_data[j].bHasIsotopicLayer) ) {
1049
+ AT_NUMB nEquSet;
1050
+ int bDisplaySaved = ip->bDisplay;
1051
+ /****** Display Equ Sets of composite Result structure **************/
1052
+ for ( nEquSet = 1; nEquSet <= inp_data->nNumEquSets; nEquSet ++ ) {
1053
+ sprintf( szTitle, "Equ set %d of %d, %s Structure #%d%s%s.%s%s%s%s%s",
1054
+ nEquSet, inp_data->nNumEquSets,
1055
+ j == TAUT_INI? "Preprocessed":"Result for",
1056
+ num_inp,
1057
+ (bDisplayTaut>0 && nNumTautComponents)? ", mobile H": bDisplayTaut==0?", fixed H":"",
1058
+ /*j? ", mobile H":", fixed H",*/
1059
+ k? ", isotopic":"",
1060
+ SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), iINChI? " (Reconnected)":"");
1061
+ ip->dp.nEquLabels = inp_data->nEquLabels;
1062
+ ip->dp.nCurEquLabel = nEquSet;
1063
+ ip->dp.nNumEquSets = inp_data->nNumEquSets;
1064
+ ip->bDisplay = 1; /* force display if it was not requested */
1065
+ err = DisplayCompositeStructure( composite_norm_data, k, j,
1066
+ pINChI2, pINChI_Aux2,
1067
+ ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
1068
+ ip->dp.nEquLabels = NULL;
1069
+ ip->dp.nCurEquLabel = 0;
1070
+ ip->dp.nNumEquSets = 0;
1071
+ ip->bDisplay = bDisplaySaved; /* restore display option */
1072
+
1073
+ if ( sd->bUserQuitComponentDisplay = (err==ESC_KEY) ) {
1074
+ break;
1075
+ }
1076
+ }
1077
+ }
1078
+ #else
1079
+ if(DRAWDATA && j <= TAUT_YES)
1080
+ {
1081
+ struct DrawData vDrawData;
1082
+ vDrawData.pWindowData = CreateWinDataComposite_( composite_norm_data, k, j,
1083
+ pINChI2, pINChI_Aux2,
1084
+ ip->bAbcNumbers, &ip->dp, ip->nMode);
1085
+ /* vDrawData.pWindowData = CreateWinData_( composite_norm_data[j].at, composite_norm_data[j].num_at,
1086
+ k, j, pINChI[i], pINChI_Aux[i],ip->bAbcNumbers, &ip->dp, ip->nMode ); */
1087
+ if( vDrawData.pWindowData != NULL )
1088
+ {
1089
+ int nType;
1090
+ vDrawData.nComponent = 0;
1091
+ if( j == 0 )
1092
+ nType = (k == 0) ? COMPONENT_BN: COMPONENT_BI;
1093
+ else
1094
+ nType = (k == 0) ? COMPONENT_TN: COMPONENT_TI;
1095
+ vDrawData.nType = nType;
1096
+ vDrawData.bReconnected = iINChI; /* 0=>main; 1=>reconnected */
1097
+ vDrawData.szTitle = _strdup(szTitle);
1098
+ vDrawData.pWindowData->szTitle = _strdup(szTitle);
1099
+ if ( inp_data && inp_data->nEquLabels && inp_data->nNumEquSets &&
1100
+ (j == bCompareTaut || bCompareTaut && !composite_norm_data[bCompareTaut].bExists) &&
1101
+ (k == bCompareIsotopic || bCompareIsotopic && !composite_norm_data[j].bHasIsotopicLayer) &&
1102
+ (vDrawData.pWindowData->nEquLabels = (AT_NUMB *)inchi_calloc(inp_data->num_inp_atoms,
1103
+ sizeof(inp_data->nEquLabels[0])))) {
1104
+ memcpy( vDrawData.pWindowData->nEquLabels, inp_data->nEquLabels,
1105
+ inp_data->num_inp_atoms * sizeof(inp_data->nEquLabels[0]));
1106
+ vDrawData.pWindowData->nNumEquSets = inp_data->nNumEquSets;
1107
+ vDrawData.pWindowData->nCurEquLabel = 0;
1108
+ }
1109
+ DRAWDATA(&vDrawData);
1110
+ }
1111
+ } else
1112
+ if(DRAWDATA && GET_DRAWDATA && j == TAUT_INI)
1113
+ {
1114
+ struct DrawData vDrawData;
1115
+ struct DrawData *pDrawData;
1116
+
1117
+ if ( !(ip->bCompareComponents & CMP_COMPONENTS) ||
1118
+ (ip->bCompareComponents & CMP_COMPONENTS_NONTAUT) ||
1119
+ !k != !composite_norm_data[j].bHasIsotopicLayer ) {
1120
+
1121
+ continue;
1122
+ }
1123
+ /*
1124
+ vDrawData.pWindowData = CreateWinDataComposite_( composite_norm_data, k, j,
1125
+ pINChI2, pINChI_Aux2,
1126
+ ip->bAbcNumbers, &ip->dp, ip->nMode);
1127
+ */
1128
+ vDrawData.pWindowData = CreateWinDataComposite_( composite_norm_data, 1 /*k*/, j,
1129
+ NULL, NULL,
1130
+ ip->bAbcNumbers, &ip->dp, ip->nMode);
1131
+ if( vDrawData.pWindowData != NULL )
1132
+ {
1133
+ int nType = COMPONENT_ORIGINAL_PREPROCESSED;
1134
+ pDrawData = GET_DRAWDATA( 0, nType, iINChI);
1135
+ if ( pDrawData ) {
1136
+ FreeDrawData( pDrawData );
1137
+ pDrawData->pWindowData = vDrawData.pWindowData;
1138
+ vDrawData.pWindowData = NULL;
1139
+ } else {
1140
+ pDrawData = &vDrawData;
1141
+ }
1142
+
1143
+ /* vDrawData.pWindowData = CreateWinData_( composite_norm_data[j].at, composite_norm_data[j].num_at,
1144
+ k, j, pINChI[i], pINChI_Aux[i],ip->bAbcNumbers, &ip->dp, ip->nMode ); */
1145
+ pDrawData->nComponent = 0;
1146
+ pDrawData->nType = nType;
1147
+ pDrawData->bReconnected = iINChI; /* 0=>main; 1=>reconnected */
1148
+ pDrawData->szTitle = _strdup(szTitle);
1149
+ pDrawData->pWindowData->szTitle = _strdup(szTitle);
1150
+ if ( inp_data && inp_data->nEquLabels && inp_data->nNumEquSets &&
1151
+ /*(j == bCompareTaut || bCompareTaut && !composite_norm_data[bCompareTaut].bExists) &&*/
1152
+ /*(k == bCompareIsotopic || bCompareIsotopic && !composite_norm_data[j].bHasIsotopicLayer) &&*/
1153
+ (pDrawData->pWindowData->nEquLabels = (AT_NUMB *)inchi_calloc(inp_data->num_inp_atoms,
1154
+ sizeof(inp_data->nEquLabels[0])))) {
1155
+ memcpy( pDrawData->pWindowData->nEquLabels, inp_data->nEquLabels,
1156
+ inp_data->num_inp_atoms * sizeof(inp_data->nEquLabels[0]));
1157
+ pDrawData->pWindowData->nNumEquSets = inp_data->nNumEquSets;
1158
+ pDrawData->pWindowData->nCurEquLabel = 0;
1159
+ }
1160
+ if ( pDrawData == &vDrawData ) {
1161
+ DRAWDATA(pDrawData); /* there was no prepocessed structure */
1162
+ }
1163
+ }
1164
+ }
1165
+ #endif
1166
+ }
1167
+ }
1168
+ }
1169
+ return err;
1170
+ }
1171
+
1172
+ #endif /* }INCHI_ANSI_ONLY */
1173
+
1174
+
1175
+
1176
+ /***********************************************************************************/
1177
+ /* pINChI[INCHI_BAS] refers to either disconnected or original structure; */
1178
+ /* num_components[INCHI_BAS] > 0 if there was input structure */
1179
+ /***********************************************************************************/
1180
+ /* pINChI[INCHI_REC] refers to the reconnected structure, */
1181
+ /* and only if the inpur structure has been disconnected, that is,*/
1182
+ /* num_components[INCHI_REC] > 0 */
1183
+ /***********************************************************************************/
1184
+ int SortAndPrintINChI( INCHI_FILE *output_file, char *pStr, int nStrLen, INCHI_FILE *log_file,
1185
+ INPUT_PARMS *ip, ORIG_ATOM_DATA *orig_inp_data, ORIG_ATOM_DATA *prep_inp_data,
1186
+ COMP_ATOM_DATA composite_norm_data[INCHI_NUM][TAUT_NUM+1],
1187
+ ORIG_STRUCT *pOrigStruct, int num_components[INCHI_NUM],
1188
+ int num_non_taut[INCHI_NUM], int num_taut[INCHI_NUM],
1189
+ INCHI_MODE bTautFlags[INCHI_NUM], INCHI_MODE bTautFlagsDone[INCHI_NUM],
1190
+ NORM_CANON_FLAGS *pncFlags, int num_inp,
1191
+ PINChI2 *pINChI[INCHI_NUM], PINChI_Aux2 *pINChI_Aux[INCHI_NUM], int *pSortPrintINChIFlags )
1192
+ {
1193
+ INCHI_SORT *pINChISort[INCHI_NUM][TAUT_NUM];
1194
+ int j, i, k, k1, ret, iINChI, max_num_components;
1195
+ INCHI_MODE nMode;
1196
+ int bDisconnectedCoord = (0 != (bTautFlagsDone[0] & TG_FLAG_DISCONNECT_COORD_DONE));
1197
+ int bINChIOutputOptions0, bCurOption, bINChIOutputOptionsCur, bEmbedReconnected, bAnnInXmlBrackets;
1198
+ static char szAnnHdr[] = "InChI ANNOTATED CONTENTS";
1199
+
1200
+ ret = 1;
1201
+ for ( i = 0; i < INCHI_NUM; i ++ ) {
1202
+ for ( k = 0; k < TAUT_NUM; k ++ ) {
1203
+ bTautFlags[i] |= pncFlags->bTautFlags[i][k];
1204
+ bTautFlagsDone[i] |= pncFlags->bTautFlagsDone[i][k];
1205
+ }
1206
+ }
1207
+ nMode = ip->nMode;
1208
+ if ( !(nMode & (REQ_MODE_BASIC|REQ_MODE_TAUT)) ) {
1209
+ nMode |= (REQ_MODE_BASIC|REQ_MODE_TAUT);
1210
+ }
1211
+
1212
+ max_num_components = 0;
1213
+ for ( j = 0; j < INCHI_NUM; j ++ ) {
1214
+ if ( max_num_components < num_components[j] )
1215
+ max_num_components = num_components[j];
1216
+ }
1217
+ if ( max_num_components <= 0 )
1218
+ max_num_components = 1;
1219
+
1220
+ for ( j = 0, i = 0; j < INCHI_NUM; j ++ ) {
1221
+ if ( num_components[j] ) {
1222
+ for ( k1 = 0; k1 < TAUT_NUM; k1 ++ ) {
1223
+ pINChISort[j][k1] = (INCHI_SORT *)inchi_calloc(max_num_components, sizeof(pINChISort[0][0][0]) );
1224
+ i += !pINChISort[j][k1]; /* number of failed allocatons */
1225
+ }
1226
+ } else {
1227
+ for ( k1 = 0; k1 < TAUT_NUM; k1 ++ ) {
1228
+ pINChISort[j][k1] = NULL;
1229
+ }
1230
+ }
1231
+ }
1232
+ if ( i ) {
1233
+ ret = CT_OUT_OF_RAM;
1234
+ goto exit_function;
1235
+ }
1236
+
1237
+
1238
+ for ( j = 0; j < INCHI_NUM; j ++ ) {
1239
+
1240
+ if ( !num_components[j] ) {
1241
+ continue;
1242
+ }
1243
+
1244
+ iINChI = j;
1245
+
1246
+ #if( OUTPUT_CONNECTED_METAL_ONLY == 1 ) /* test: output connected as the only one INChI */
1247
+ if ( INCHI_BAS == j && num_components[INCHI_REC] ) {
1248
+ j = INCHI_REC;
1249
+ }
1250
+ #endif
1251
+
1252
+ /*j = INCHI_BAS; <- for debug only */
1253
+ /* for only normal or disconnected coord compounds */
1254
+ /* (j=0=INCHI_BAS => normal or disconnected, j=1=INCHI_REC => reconnected */
1255
+ for ( k1 = 0; k1 < TAUT_NUM; k1 ++ ) {
1256
+ for ( i = 0; i < num_components[j]; i ++ ) {
1257
+ for ( k = 0; k < TAUT_NUM; k ++ ) {
1258
+ pINChISort[j][k1][i].pINChI[k] = pINChI[j][i][k];
1259
+ pINChISort[j][k1][i].pINChI_Aux[k] = pINChI_Aux[j][i][k];
1260
+ }
1261
+ pINChISort[j][k1][i].ord_number = i;
1262
+ }
1263
+ }
1264
+ /* sort component INChIs */
1265
+ for ( k1 = 0; k1 < TAUT_NUM; k1 ++ ) {
1266
+ switch ( k1 ) {
1267
+ case TAUT_NON:
1268
+ qsort( pINChISort[j][k1], num_components[j], sizeof(pINChISort[0][0][0]), CompINChINonTaut2 );
1269
+ break;
1270
+ case TAUT_YES:
1271
+ qsort( pINChISort[j][k1], num_components[j], sizeof(pINChISort[0][0][0]), CompINChITaut2 );
1272
+ break;
1273
+ }
1274
+ }
1275
+ #ifndef INCHI_ANSI_ONLY
1276
+ /* find equivalent and wINChI display order; use requested in ip->bCompareComponents comparison */
1277
+ ret = SaveEquComponentsInfoAndSortOrder ( iINChI, pINChISort[j], num_components, orig_inp_data, prep_inp_data,
1278
+ composite_norm_data[j], ip->bCompareComponents );
1279
+ if ( RETURNED_ERROR( ret ) ) {
1280
+ ret = 0;
1281
+ goto exit_function;
1282
+ } else {
1283
+ ret = 1;
1284
+ }
1285
+ #endif
1286
+ }
1287
+
1288
+ bINChIOutputOptions0 = ip->bINChIOutputOptions &
1289
+ ~(INCHI_OUT_EMBED_REC |
1290
+ INCHI_OUT_XML |
1291
+ INCHI_OUT_PLAIN_TEXT |
1292
+ INCHI_OUT_PLAIN_TEXT_COMMENTS |
1293
+ INCHI_OUT_XML_TEXT_COMMENTS);
1294
+ bEmbedReconnected = ip->bINChIOutputOptions & INCHI_OUT_EMBED_REC;
1295
+
1296
+ for ( i = 0; i < 4; i ++ ) {
1297
+ switch( i ) {
1298
+ case 0:
1299
+ bCurOption = INCHI_OUT_XML;
1300
+ break;
1301
+ case 1:
1302
+ bCurOption = INCHI_OUT_PLAIN_TEXT;
1303
+ break;
1304
+ case 2:
1305
+ bCurOption = INCHI_OUT_PLAIN_TEXT_COMMENTS;
1306
+ break;
1307
+ case 3:
1308
+ bCurOption = INCHI_OUT_XML_TEXT_COMMENTS;
1309
+ break;
1310
+ default:
1311
+ continue;
1312
+ }
1313
+ if ( ip->bINChIOutputOptions & bCurOption ) {
1314
+ bAnnInXmlBrackets = 0;
1315
+ if ( i == 1 ) {
1316
+ ;/*bEmbedReconnected = 0;*/
1317
+ }
1318
+ if ( i == 3 ) {
1319
+ bCurOption = INCHI_OUT_XML; /* xml output as annotation */
1320
+ }
1321
+ bINChIOutputOptionsCur = bINChIOutputOptions0 | bCurOption;
1322
+ switch ( i ) {
1323
+ case 0:
1324
+ case 1:
1325
+ /* output INChI */
1326
+ bINChIOutputOptionsCur |= bEmbedReconnected;
1327
+ break;
1328
+ case 2:
1329
+ case 3:
1330
+ /* output annotation */
1331
+ bAnnInXmlBrackets = (i == 2 && (ip->bINChIOutputOptions & INCHI_OUT_XML ));
1332
+ if ( bAnnInXmlBrackets ) {
1333
+ inchi_print( output_file, "\n<%s>\n", szAnnHdr );
1334
+ } else {
1335
+ inchi_print( output_file, "\n==== %s ====\n", szAnnHdr );
1336
+ }
1337
+ bINChIOutputOptionsCur |= bEmbedReconnected;
1338
+ bINChIOutputOptionsCur &= ~INCHI_OUT_TABBED_OUTPUT;
1339
+ break;
1340
+ default:
1341
+ continue;
1342
+ }
1343
+
1344
+ ret &= OutputINChI2( pStr, nStrLen, pINChISort, INCHI_BAS /*iINChI*/, pOrigStruct,
1345
+ bDisconnectedCoord, OUT_TN, bINChIOutputOptionsCur, 0 != (bINChIOutputOptionsCur & INCHI_OUT_XML),
1346
+ ip->bAbcNumbers, ip->bCtPredecessors, ip->bNoStructLabels,
1347
+ num_components, num_non_taut, num_taut,
1348
+ output_file, log_file, num_inp,
1349
+ ip->pSdfLabel,ip->pSdfValue, ip->lSdfId, pSortPrintINChIFlags );
1350
+
1351
+ if ( ret && !(bINChIOutputOptionsCur & INCHI_OUT_EMBED_REC) ) {
1352
+ ret &= OutputINChI2( pStr, nStrLen, pINChISort, INCHI_REC /*iINChI*/, pOrigStruct,
1353
+ bDisconnectedCoord, OUT_TN, bINChIOutputOptionsCur, 0 != (bINChIOutputOptionsCur & INCHI_OUT_XML),
1354
+ ip->bAbcNumbers, ip->bCtPredecessors, ip->bNoStructLabels,
1355
+ num_components, num_non_taut, num_taut,
1356
+ output_file, log_file, num_inp,
1357
+ ip->pSdfLabel,ip->pSdfValue, ip->lSdfId, pSortPrintINChIFlags );
1358
+ }
1359
+ if ( bAnnInXmlBrackets ) {
1360
+ inchi_print( output_file, "</%s>\n\n", szAnnHdr );
1361
+ }
1362
+ if ( !ret ) {
1363
+ break;
1364
+ }
1365
+ }
1366
+ }
1367
+
1368
+ exit_function:
1369
+ for ( j = 0; j < INCHI_NUM; j ++ ) {
1370
+ for ( k1 = 0, i = 0; k1 < TAUT_NUM; k1 ++ ) {
1371
+ if ( pINChISort[j][k1] ) {
1372
+ inchi_free( pINChISort[j][k1] );
1373
+ }
1374
+ }
1375
+ }
1376
+ ret = ret? 0 : _IS_FATAL;
1377
+ return ret;
1378
+ }
1379
+ /**********************************************************************************/
1380
+ void FreeAllINChIArrays( PINChI2 *pINChI[INCHI_NUM], PINChI_Aux2 *pINChI_Aux[INCHI_NUM], int num_components[INCHI_NUM] )
1381
+ {
1382
+ int k;
1383
+ for ( k = 0; k < INCHI_NUM; k ++ ) {
1384
+ FreeINChIArrays( pINChI[k], pINChI_Aux[k], num_components[k] );
1385
+ num_components[k] = 0;
1386
+ if ( pINChI[k] ) {
1387
+ inchi_free( pINChI[k] );
1388
+ pINChI[k] = NULL;
1389
+ }
1390
+ if ( pINChI_Aux[k] ) {
1391
+ inchi_free( pINChI_Aux[k] );
1392
+ pINChI_Aux[k] = NULL;
1393
+ }
1394
+
1395
+ }
1396
+ }
1397
+ /**********************************************************************************/
1398
+ void FreeINChIArrays( PINChI2 *pINChI, PINChI_Aux2 *pINChI_Aux, int num_components )
1399
+ {
1400
+ int i, k;
1401
+ /* release allocated memory */
1402
+ if ( pINChI ) {
1403
+ for ( i = 0; i < num_components; i ++ ) {
1404
+ for ( k = 0; k < TAUT_NUM; k ++ ) {
1405
+ Free_INChI( &pINChI[i][k] );
1406
+ /*
1407
+ inchi_free( pINChI[i][k] );
1408
+ pINChI[i][k] = NULL;
1409
+ */
1410
+ }
1411
+ }
1412
+ }
1413
+ if ( pINChI_Aux ) {
1414
+ for ( i = 0; i < num_components; i ++ ) {
1415
+ for ( k = 0; k < TAUT_NUM; k ++ ) {
1416
+ Free_INChI_Aux( &pINChI_Aux[i][k] );
1417
+ /*
1418
+ inchi_free( pINChI_Aux[i][k] );
1419
+ pINChI_Aux[i][k] = NULL;
1420
+ */
1421
+ }
1422
+ }
1423
+ }
1424
+ }
1425
+
1426
+
1427
+ /**********************************************
1428
+ * output " L=V" or " L missing" or ""
1429
+ * The fprintf format string must contain %s%s%s%s
1430
+ */
1431
+ char gsMissing[] = "is missing";
1432
+ char gsEmpty[] = "";
1433
+ char gsSpace[] = " ";
1434
+ char gsEqual[] = "=";
1435
+
1436
+ #ifndef INCHI_LIBRARY
1437
+ /*********************************************************************************************************/
1438
+ void SplitTime( unsigned long ulTotalTime, int *hours, int *minutes, int *seconds, int *mseconds )
1439
+ {
1440
+ *mseconds = (int)(ulTotalTime % 1000);
1441
+ ulTotalTime /= 1000;
1442
+ *seconds = (int)(ulTotalTime % 60);
1443
+ ulTotalTime /= 60;
1444
+ *minutes = (int)(ulTotalTime % 60);
1445
+ ulTotalTime /= 60;
1446
+ *hours = (int)(ulTotalTime);
1447
+ }
1448
+ /*********************************************************************************************************/
1449
+ int ReadTheStructure( STRUCT_DATA *sd, INPUT_PARMS *ip, FILE *inp_file, ORIG_ATOM_DATA *orig_inp_data,
1450
+ /* for CML:*/ int inp_index, int *out_index )
1451
+ {
1452
+ inchiTime ulTStart;
1453
+ int nRet = 0, nRet2 = 0;
1454
+ int bGetOrigCoord = !(ip->bINChIOutputOptions & (INCHI_OUT_NO_AUX_INFO | INCHI_OUT_SHORT_AUX_INFO));
1455
+ INCHI_MODE InpAtomFlags = 0; /* reading Molfile may set FLAG_INP_AT_CHIRAL bit */
1456
+
1457
+ memset( sd, 0, sizeof(*sd) );
1458
+ switch ( ip->nInputType ) {
1459
+ case INPUT_MOLFILE:
1460
+ case INPUT_SDFILE:
1461
+ if ( orig_inp_data ) {
1462
+ if ( ip->pSdfValue && ip->pSdfValue[0] ) {
1463
+ /* Added 07-29-2003 to avoid inheriting exact value from prev. structure
1464
+ and to make reference to a (bad) structure with unknown ID Value */
1465
+ char *p, *q; /* q shadows prev declaration of const char *q */
1466
+ int n;
1467
+ if ( (p = strrchr( ip->pSdfValue, '+' )) &&
1468
+ '[' == *(p-1) && 0 < (n=strtol(p+1,&q,10)) && q[0] && ']'==q[0] && !q[1] ) {
1469
+ sprintf( p+1, "%d]", n+1 );
1470
+ } else {
1471
+ strcat( ip->pSdfValue, " [+1]" );
1472
+ }
1473
+ }
1474
+ InchiTimeGet( &ulTStart );
1475
+ sd->fPtrStart = (inp_file == stdin)? -1 : ftell( inp_file );
1476
+ /* read the original structure */
1477
+ nRet2 = MolfileToOrigAtom( inp_file, orig_inp_data, ip->bMergeAllInputStructures, bGetOrigCoord, ip->bDoNotAddH,
1478
+ ip->pSdfLabel, ip->pSdfValue, &ip->lSdfId, &ip->lMolfileNumber,
1479
+ &InpAtomFlags, &sd->nStructReadError, sd->pStrErrStruct );
1480
+
1481
+
1482
+ if ( !ip->bGetSdfileId || ip->lSdfId == 999999) ip->lSdfId = 0;
1483
+ if ( !ip->bGetMolfileNumber || ip->lMolfileNumber < 0 ) ip->lMolfileNumber = 0;
1484
+ sd->fPtrEnd = (inp_file == stdin)? -1 : ftell( inp_file );
1485
+ sd->ulStructTime += InchiTimeElapsed( &ulTStart );
1486
+ #if( bRELEASE_VERSION == 0 )
1487
+ sd->bExtract |= orig_inp_data->bExtract;
1488
+ #endif
1489
+ /* 2004-11-16: added Molfile Chiral Flag Mode */
1490
+ /* *****************************************************************************
1491
+ * Chiral flags are set in:
1492
+ * - RunICHI.c #1610 -- ReadTheStructure() -- cInChI, wInChI (here)
1493
+ * - e_IchiMain.c #273 -- main() -- C example of calling InChI dll
1494
+ * - inchi_dll.c #1662 -- ExtractOneStructure -- InChI dll code
1495
+ *******************************************************************************/
1496
+ /* 1. Highest precedence: Chiral Flag set by the user */
1497
+ if ( ip->bChiralFlag & FLAG_SET_INP_AT_CHIRAL ) {
1498
+ InpAtomFlags = FLAG_INP_AT_CHIRAL; /* forced by the user */
1499
+ } else
1500
+ if ( ip->bChiralFlag & FLAG_SET_INP_AT_NONCHIRAL ) {
1501
+ InpAtomFlags = FLAG_INP_AT_NONCHIRAL; /* forced by the user */
1502
+ } else
1503
+ if ( (InpAtomFlags & FLAG_INP_AT_CHIRAL) && (InpAtomFlags && FLAG_INP_AT_NONCHIRAL) ) {
1504
+ InpAtomFlags &= ~FLAG_INP_AT_NONCHIRAL;
1505
+ }
1506
+ /* save requested flags in the AuxInfo */
1507
+ sd->bChiralFlag &= ~( FLAG_INP_AT_CHIRAL | FLAG_INP_AT_NONCHIRAL );
1508
+ sd->bChiralFlag |= InpAtomFlags & ( FLAG_INP_AT_CHIRAL | FLAG_INP_AT_NONCHIRAL );
1509
+ /* quick fix: modify ip->nMode on the fly */
1510
+ /* 2. The user requested both Stereo AND Chiral flag */
1511
+ if ( (ip->nMode & REQ_MODE_CHIR_FLG_STEREO) && (ip->nMode & REQ_MODE_STEREO) ) {
1512
+ if ( InpAtomFlags & FLAG_INP_AT_CHIRAL ) {
1513
+ /* structure has chiral flag or the user said it is chiral */
1514
+ ip->nMode &= ~(REQ_MODE_RELATIVE_STEREO | REQ_MODE_RACEMIC_STEREO);
1515
+ sd->bChiralFlag |= FLAG_INP_AT_CHIRAL; /* write AuxInfo as chiral */
1516
+ } else {
1517
+ ip->nMode &= ~REQ_MODE_RACEMIC_STEREO;
1518
+ ip->nMode |= REQ_MODE_RELATIVE_STEREO;
1519
+ sd->bChiralFlag |= FLAG_INP_AT_NONCHIRAL; /* write AuxInfo as explicitly not chiral */
1520
+ }
1521
+ }
1522
+ } else {
1523
+ /* read the next original structure */
1524
+ int nStructReadError=0;
1525
+ if ( !ip->bMergeAllInputStructures ) {
1526
+ nRet2 = MolfileToOrigAtom( inp_file, NULL, 0, 0, 0,
1527
+ NULL, NULL, NULL, NULL,
1528
+ NULL, &nStructReadError, NULL );
1529
+ if ( nRet2 <= 0 && 10 < nStructReadError && nStructReadError < 20 ) {
1530
+ return _IS_EOF;
1531
+ }
1532
+ } else {
1533
+ return _IS_EOF;
1534
+ }
1535
+ }
1536
+ break;
1537
+ case INPUT_INCHI_XML:
1538
+ case INPUT_INCHI_PLAIN:
1539
+ if ( orig_inp_data ) {
1540
+ if ( ip->pSdfValue && ip->pSdfValue[0] ) {
1541
+ /* Added 07-29-2003 to avoid inheriting exact value from prev. structure
1542
+ and to make reference to a (bad) structure with unknown ID Value */
1543
+ char *p, *q;
1544
+ int n;
1545
+ if ( (p = strrchr( ip->pSdfValue, '+' )) &&
1546
+ '[' == *(p-1) && 0 < (n=strtol(p+1,&q,10)) && q[0] && ']'==q[0] && !q[1] ) {
1547
+ sprintf( p+1, "%d]", n+1 );
1548
+ } else {
1549
+ strcat( ip->pSdfValue, " [+1]" );
1550
+ }
1551
+ }
1552
+ InchiTimeGet( &ulTStart );
1553
+ sd->fPtrStart = (inp_file == stdin)? -1 : ftell( inp_file );
1554
+ /* read the original structure */
1555
+ nRet2 = INChIToOrigAtom( inp_file, orig_inp_data, ip->bMergeAllInputStructures,
1556
+ bGetOrigCoord, ip->bDoNotAddH,
1557
+ ip->nInputType, ip->pSdfLabel, ip->pSdfValue, &ip->lMolfileNumber,
1558
+ &InpAtomFlags, &sd->nStructReadError, sd->pStrErrStruct );
1559
+ /*if ( !ip->bGetSdfileId || ip->lSdfId == 999999) ip->lSdfId = 0;*/
1560
+ sd->fPtrEnd = (inp_file == stdin)? -1 : ftell( inp_file );
1561
+
1562
+ sd->ulStructTime += InchiTimeElapsed( &ulTStart );
1563
+ #if( bRELEASE_VERSION == 0 )
1564
+ sd->bExtract |= orig_inp_data->bExtract;
1565
+ #endif
1566
+ /* 2004-11-16: added Molfile Chiral Flag Mode */
1567
+ if ( ip->bChiralFlag & FLAG_SET_INP_AT_CHIRAL ) {
1568
+ InpAtomFlags = FLAG_INP_AT_CHIRAL; /* forced by the user */
1569
+ } else
1570
+ if ( ip->bChiralFlag & FLAG_SET_INP_AT_NONCHIRAL ) {
1571
+ InpAtomFlags = FLAG_INP_AT_NONCHIRAL; /* forced by the user */
1572
+ } else
1573
+ if ( (InpAtomFlags & FLAG_INP_AT_CHIRAL) && (InpAtomFlags && FLAG_INP_AT_NONCHIRAL) ) {
1574
+ InpAtomFlags &= ~FLAG_INP_AT_NONCHIRAL;
1575
+ }
1576
+ sd->bChiralFlag |= InpAtomFlags; /* copy chiral flag to AuxInfo */
1577
+ /* quick fix: modify ip->nMode on the fly */
1578
+ if ( (ip->nMode & REQ_MODE_CHIR_FLG_STEREO) && (ip->nMode & REQ_MODE_STEREO) ) {
1579
+ if ( InpAtomFlags & FLAG_INP_AT_CHIRAL ) {
1580
+ ip->nMode &= ~(REQ_MODE_RELATIVE_STEREO | REQ_MODE_RACEMIC_STEREO);
1581
+ } else {
1582
+ ip->nMode &= ~REQ_MODE_RACEMIC_STEREO;
1583
+ ip->nMode |= REQ_MODE_RELATIVE_STEREO;
1584
+ }
1585
+ }
1586
+ } else {
1587
+ /* read the next original structure */
1588
+ int nStructReadError=0;
1589
+ if ( !ip->bMergeAllInputStructures ) {
1590
+ nRet2 = INChIToOrigAtom( inp_file, NULL, 0, 0, 0,
1591
+ ip->nInputType, NULL, NULL, NULL, NULL, &nStructReadError, NULL );
1592
+ if ( nRet2 <= 0 && 10 < nStructReadError && nStructReadError < 20 ) {
1593
+ return _IS_EOF;
1594
+ }
1595
+ } else {
1596
+ return _IS_EOF;
1597
+ }
1598
+ }
1599
+ break;
1600
+
1601
+ #if( ADD_CMLPP == 1 )
1602
+ /* BILLY 8/6/04 */
1603
+ case INPUT_CMLFILE:
1604
+ if ( orig_inp_data ) {
1605
+
1606
+ InchiTimeGet( &ulTStart );
1607
+ /*
1608
+ if ( inp_index >= 0 ) {
1609
+ sd->fPtrStart = inp_index;
1610
+ } else {
1611
+ sd->fPtrStart = GetCmlStructIndex();
1612
+ }
1613
+ */
1614
+ sd->fPtrStart = -1; /* disable "CopyMOLfile() for CML input files */
1615
+ sd->fPtrEnd = -1;
1616
+ /* read the original structure */
1617
+ nRet = CmlfileToOrigAtom( inp_file, orig_inp_data, ip->bMergeAllInputStructures,
1618
+ bGetOrigCoord, ip->bDoNotAddH, inp_index, out_index,
1619
+ ip->pSdfLabel, ip->pSdfValue, &ip->lSdfId,
1620
+ &sd->nStructReadError, sd->pStrErrStruct );
1621
+
1622
+
1623
+ sd->ulStructTime += InchiTimeElapsed( &ulTStart );
1624
+ #if( bRELEASE_VERSION == 0 )
1625
+ sd->bExtract |= orig_inp_data->bExtract;
1626
+ #endif
1627
+ } else {
1628
+ /* read the next original structure */
1629
+ int nStructReadError=0;
1630
+ if ( !ip->bMergeAllInputStructures ) {
1631
+ nRet2 = CmlfileToOrigAtom( inp_file, NULL, 0, 0, 0, inp_index, out_index,
1632
+ NULL, NULL, NULL, &nStructReadError, NULL );
1633
+
1634
+ if ( nRet2 <= 0 && 10 < nStructReadError && nStructReadError < 20 ) {
1635
+ return _IS_EOF;
1636
+ }
1637
+ } else {
1638
+ return _IS_EOF;
1639
+ }
1640
+ }
1641
+ break;
1642
+ #endif
1643
+
1644
+ default:
1645
+ nRet = _IS_FATAL; /* wrong file type */
1646
+ }
1647
+ return nRet;
1648
+ }
1649
+ #endif
1650
+ /*****************************************************************************************************/
1651
+ int TreatReadTheStructureErrors( STRUCT_DATA *sd, INPUT_PARMS *ip, int nLogMask,
1652
+ FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
1653
+ ORIG_ATOM_DATA *orig_inp_data, int *num_inp, char *pStr, int nStrLen )
1654
+ {
1655
+ int nRet = _IS_OKAY;
1656
+ /* End of file */
1657
+ if ( 10 < sd->nStructReadError && sd->nStructReadError < 20 ) {
1658
+ if ( sd->pStrErrStruct[0] ) {
1659
+ my_fprintf( log_file, "%s inp structure #%d: End of file.%s%s%s%s \n", sd->pStrErrStruct, *num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
1660
+ }
1661
+ my_fprintf( log_file, "End of file detected after structure #%d. \n", *num_inp-1 );
1662
+ nRet = _IS_EOF;
1663
+ goto exit_function; /* end of file */
1664
+ }
1665
+
1666
+ /*(*num_inp) ++;*/
1667
+
1668
+ /* Skipping the structures */
1669
+ if ( *num_inp < ip->first_struct_number ) {
1670
+ #ifndef INCHI_LIBRARY
1671
+ if ( log_file != stderr ) {
1672
+ my_fprintf( stderr, "\rSkipping structure #%d.%s%s%s%s...", *num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue));
1673
+ }
1674
+ #endif
1675
+ nRet = sd->nErrorType = _IS_SKIP;
1676
+ goto exit_function;
1677
+ }
1678
+
1679
+ sd->nErrorType = GetInpStructErrorType( ip, sd->nStructReadError, sd->pStrErrStruct, orig_inp_data->num_inp_atoms );
1680
+
1681
+ /* init xml output */
1682
+ if ( (ip->bINChIOutputOptions & INCHI_OUT_XML) && !ip->bXmlStarted ) {
1683
+ OutputINChIXmlRootStartTag( output_file );
1684
+ ip->bXmlStarted ++;
1685
+ }
1686
+ /* init xml structure block */
1687
+ if ( (ip->bINChIOutputOptions & INCHI_OUT_XML) && !sd->bXmlStructStarted ) {
1688
+ if ( !OutputINChIXmlStructStartTag( output_file, pStr, 1, nStrLen, ip->bNoStructLabels,
1689
+ *num_inp, ip->pSdfLabel, ip->pSdfValue ) ) {
1690
+ my_fprintf( log_file, "Cannot create start xml tag for structure #%d.%s%s%s%s Terminating.\n", *num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
1691
+ sd->bXmlStructStarted = -1;
1692
+ nRet = _IS_FATAL;
1693
+ goto exit_function;
1694
+ }
1695
+ sd->bXmlStructStarted ++;
1696
+ }
1697
+
1698
+ /* Fatal error */
1699
+ if ( sd->nErrorType == _IS_FATAL ) {
1700
+ if ( nLogMask & LOG_MASK_FATAL )
1701
+ my_fprintf( log_file, "Fatal Error %d (aborted; %s) inp structure #%d.%s%s%s%s\n",
1702
+ sd->nStructReadError, sd->pStrErrStruct, *num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
1703
+ #if( bRELEASE_VERSION == 1 || EXTR_FLAGS == 0 )
1704
+ if ( prb_file && 0L <= sd->fPtrStart && sd->fPtrStart < sd->fPtrEnd && !ip->bSaveAllGoodStructsAsProblem ) {
1705
+ CopyMOLfile(inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file, *num_inp);
1706
+ }
1707
+ #endif
1708
+ /* goto exit_function; */
1709
+ }
1710
+ /* Non-fatal errors: do not produce INChI */
1711
+ if ( sd->nErrorType == _IS_ERROR ) { /* 70 => too many atoms */
1712
+ if ( nLogMask & LOG_MASK_ERR )
1713
+ my_fprintf( log_file, "Error %d (no %s; %s) inp structure #%d.%s%s%s%s\n",
1714
+ sd->nStructReadError, INCHI_NAME, sd->pStrErrStruct, *num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
1715
+ #if( bRELEASE_VERSION == 1 || EXTR_FLAGS == 0 )
1716
+ if ( prb_file && 0L <= sd->fPtrStart && sd->fPtrStart < sd->fPtrEnd && !ip->bSaveAllGoodStructsAsProblem) {
1717
+ CopyMOLfile(inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file, *num_inp);
1718
+ }
1719
+ #endif
1720
+ }
1721
+
1722
+ /* Warnings: try to produce INChI */
1723
+ if ( sd->nErrorType == _IS_WARNING ) {
1724
+ if ( nLogMask & LOG_MASK_WARN )
1725
+ my_fprintf( log_file, "Warning: (%s) inp structure #%d.%s%s%s%s\n",
1726
+ sd->pStrErrStruct, *num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
1727
+ }
1728
+
1729
+ /* xml error/warning processing; close xml struct block if error */
1730
+ if ( (ip->bINChIOutputOptions & INCHI_OUT_XML)
1731
+ #ifdef INCHI_LIB
1732
+ || (ip->bINChIOutputOptions & INCHI_OUT_WINCHI_WINDOW) && (ip->bINChIOutputOptions & INCHI_OUT_PLAIN_TEXT)
1733
+ #endif
1734
+ ) {
1735
+ if ( sd->nErrorType != _IS_OKAY && sd->nErrorType != _IS_WARNING ) {
1736
+ sd->nErrorType =
1737
+ ProcessStructError( output_file, log_file, /*sd->nStructReadError,*/
1738
+ sd->pStrErrStruct, sd->nErrorType, &sd->bXmlStructStarted, *num_inp, ip, pStr, nStrLen );
1739
+ }
1740
+ }
1741
+ exit_function:
1742
+ if ( nRet <= _IS_OKAY && sd->nErrorType > 0 ) {
1743
+ nRet = sd->nErrorType;
1744
+ }
1745
+ return nRet;
1746
+ }
1747
+ /******************************************************************************************************/
1748
+ int GetOneComponent( STRUCT_DATA *sd, INPUT_PARMS *ip, INCHI_FILE *log_file, INCHI_FILE *output_file,
1749
+ INP_ATOM_DATA *inp_cur_data,
1750
+ ORIG_ATOM_DATA *orig_inp_data, int i, int num_inp, char *pStr, int nStrLen )
1751
+ {
1752
+ inchiTime ulTStart;
1753
+ InchiTimeGet( &ulTStart );
1754
+ CreateInpAtomData( inp_cur_data, orig_inp_data->nCurAtLen[i], 0 );
1755
+ inp_cur_data->num_at = ExtractConnectedComponent( orig_inp_data->at, orig_inp_data->num_inp_atoms, i+1, inp_cur_data->at );
1756
+ sd->ulStructTime += InchiTimeElapsed( &ulTStart );
1757
+
1758
+ /* error processing */
1759
+ if ( inp_cur_data->num_at <= 0 || orig_inp_data->nCurAtLen[i] != inp_cur_data->num_at ) {
1760
+ /* log error message */
1761
+ AddMOLfileError(sd->pStrErrStruct, "Cannot extract Component");
1762
+ my_fprintf( log_file, "%s #%d structure #%d.%s%s%s%s\n", sd->pStrErrStruct, i+1, num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue));
1763
+ sd->nErrorCode = inp_cur_data->num_at < 0? inp_cur_data->num_at : (orig_inp_data->nCurAtLen[i] != inp_cur_data->num_at)? CT_ATOMCOUNT_ERR : CT_UNKNOWN_ERR;
1764
+ /* num_err ++; */
1765
+ sd->nErrorType = _IS_ERROR;
1766
+ if ( (ip->bINChIOutputOptions & INCHI_OUT_XML)
1767
+ #ifdef INCHI_LIB
1768
+ || (ip->bINChIOutputOptions & INCHI_OUT_WINCHI_WINDOW) && (ip->bINChIOutputOptions & INCHI_OUT_PLAIN_TEXT)
1769
+ #endif
1770
+ ) {
1771
+ /* xml error message */
1772
+ sd->nErrorType = ProcessStructError( output_file, log_file, /*sd->nErrorCode,*/ sd->pStrErrStruct,
1773
+ sd->nErrorType, &sd->bXmlStructStarted, num_inp, ip, pStr, nStrLen );
1774
+ }
1775
+ }
1776
+ return sd->nErrorType;
1777
+ }
1778
+ /*******************************************************************************************/
1779
+ int GetProcessingWarningsOneINChI(INChI *pINChI, INP_ATOM_DATA *inp_norm_data, char *pStrErrStruct)
1780
+ {
1781
+ int i, j;
1782
+ int nAmbiguousStereoAtoms, nAmbiguousStereoBonds;
1783
+ nAmbiguousStereoAtoms = 0;
1784
+ nAmbiguousStereoBonds = 0;
1785
+
1786
+ for ( i = 0; i < 2; i ++ ) {
1787
+ if ( !inp_norm_data->at )
1788
+ continue;
1789
+ for ( j = 0; j < pINChI->nNumberOfAtoms; j ++ ) {
1790
+ if ( inp_norm_data->at[j].bAmbiguousStereo & (AMBIGUOUS_STEREO_ATOM | AMBIGUOUS_STEREO_ATOM_ISO) ) {
1791
+ nAmbiguousStereoAtoms ++;
1792
+ }
1793
+ if ( inp_norm_data->at[j].bAmbiguousStereo & (AMBIGUOUS_STEREO_BOND | AMBIGUOUS_STEREO_BOND_ISO) ) {
1794
+ nAmbiguousStereoBonds ++;
1795
+ }
1796
+ }
1797
+ }
1798
+ if ( nAmbiguousStereoAtoms ) {
1799
+ AddMOLfileError(pStrErrStruct, "Ambiguous stereo:");
1800
+ AddMOLfileError(pStrErrStruct, "center(s)");
1801
+ }
1802
+ if ( nAmbiguousStereoBonds ) {
1803
+ AddMOLfileError(pStrErrStruct, "Ambiguous stereo:");
1804
+ AddMOLfileError(pStrErrStruct, "bond(s)");
1805
+ }
1806
+ return (nAmbiguousStereoAtoms || nAmbiguousStereoBonds);
1807
+ }
1808
+ /*******************************************************************************************/
1809
+ int GetProcessingWarnings(INChI *cur_INChI[], INP_ATOM_DATA **inp_norm_data, STRUCT_DATA *sd)
1810
+ {
1811
+ int i, ret = 0;
1812
+ for (i = 0; i < TAUT_NUM; i ++ ) {
1813
+ if ( cur_INChI[i] && cur_INChI[i]->nNumberOfAtoms>0 ) {
1814
+ ret |= GetProcessingWarningsOneINChI(cur_INChI[i], inp_norm_data[i], sd->pStrErrStruct);
1815
+ }
1816
+ }
1817
+ return ret;
1818
+ }
1819
+
1820
+ /*******************************************************************************************/
1821
+ int CreateOneComponentINChI( STRUCT_DATA *sd, INPUT_PARMS *ip, INP_ATOM_DATA *inp_cur_data, ORIG_ATOM_DATA *orig_inp_data,
1822
+ PINChI2 *pINChI, PINChI_Aux2 *pINChI_Aux, int iINChI,
1823
+ int i, int num_inp, INP_ATOM_DATA **inp_norm_data, NORM_CANON_FLAGS *pncFlags, INCHI_FILE *log_file )
1824
+ {
1825
+ inchiTime ulTStart, ulTEnd, *pulTEnd = NULL;
1826
+ int k, num_at, ret = 0;
1827
+ int bOrigCoord;
1828
+ INCHI_MODE bTautFlags = ip->bTautFlags;
1829
+ INCHI_MODE bTautFlagsDone = (ip->bTautFlagsDone | sd->bTautFlagsDone[INCHI_BAS]);
1830
+ INChI *cur_INChI[TAUT_NUM];
1831
+ INChI_Aux *cur_INChI_Aux[TAUT_NUM];
1832
+ long lElapsedTime;
1833
+ /*
1834
+ PINChI2 *pINChI = pINChI2[iINChI];
1835
+ PINChI_Aux2 *pINChI_Aux = pINChI_Aux2[iINChI];
1836
+ */
1837
+ InchiTimeGet( &ulTStart );
1838
+ bOrigCoord = !(ip->bINChIOutputOptions & (INCHI_OUT_NO_AUX_INFO | INCHI_OUT_SHORT_AUX_INFO));
1839
+
1840
+ for ( k = 0; k < TAUT_NUM; k ++ ) {
1841
+ cur_INChI[k] = NULL;
1842
+ cur_INChI_Aux[k] = NULL;
1843
+ }
1844
+ /* allocate memory for non-tautimeric (k=0) and tautomeric (k=1) results */
1845
+ for ( k = 0; k < TAUT_NUM; k ++ ) {
1846
+ int nAllocMode = (k==TAUT_YES? REQ_MODE_TAUT:0) |
1847
+ (bTautFlagsDone & ( TG_FLAG_FOUND_ISOTOPIC_H_DONE |
1848
+ TG_FLAG_FOUND_ISOTOPIC_ATOM_DONE ))?
1849
+ (ip->nMode & REQ_MODE_ISO):0;
1850
+
1851
+ if ( k==TAUT_NON && (ip->nMode & REQ_MODE_BASIC ) ||
1852
+ k==TAUT_YES && (ip->nMode & REQ_MODE_TAUT ) ) {
1853
+ /* alloc INChI and INChI_Aux */
1854
+ cur_INChI[k] = Alloc_INChI( inp_cur_data->at, inp_cur_data->num_at, &inp_cur_data->num_bonds,
1855
+ &inp_cur_data->num_isotopic, nAllocMode );
1856
+ cur_INChI_Aux[k] = Alloc_INChI_Aux( inp_cur_data->num_at,
1857
+ inp_cur_data->num_isotopic, nAllocMode, bOrigCoord );
1858
+ if ( cur_INChI_Aux[k] ) {
1859
+ cur_INChI_Aux[k]->bIsIsotopic = inp_cur_data->num_isotopic;
1860
+ }
1861
+ /* alloc memory for the output structure: non-tautomeric and tautomeric (for displaying) */
1862
+ CreateInpAtomData( inp_norm_data[k], inp_cur_data->num_at, k );
1863
+ } else {
1864
+ FreeInpAtomData( inp_norm_data[k] );
1865
+ }
1866
+ }
1867
+ lElapsedTime = InchiTimeElapsed( &ulTStart );
1868
+ if ( ip->msec_MaxTime ) {
1869
+ ip->msec_LeftTime -= lElapsedTime;
1870
+ }
1871
+ sd->ulStructTime += lElapsedTime;
1872
+
1873
+
1874
+ #if( !defined( INCHI_LIB ) && !defined( INCHI_LIBRARY ) )
1875
+ #if( TEST_RENUMB_ATOMS != 1 )
1876
+ /* log file / console output */
1877
+ if ( log_file != stderr ) {
1878
+ if ( ip->bDisplay )
1879
+ my_fprintf( log_file, "Component #%d structure #%d.%s%s%s%s...\n", i+1, num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
1880
+ else
1881
+ //my_fprintf( stderr, "Component #%d structure #%d.%s%s%s%s...\r", i+1, num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
1882
+ }
1883
+ #endif
1884
+ #endif
1885
+ /******************************************************
1886
+ *
1887
+ * Get one component canonical numberings, etc.
1888
+ *
1889
+ ******************************************************/
1890
+
1891
+ /*
1892
+ * Create_INChI() return value:
1893
+ * num_at <= 0: error code
1894
+ * num_at > 0: number of atoms (excluding terminal hydrogen atoms)
1895
+ * inp_norm_data[0] => non-tautomeric, inp_norm_data[1] => tautomeric
1896
+ */
1897
+ InchiTimeGet( &ulTStart );
1898
+ if ( ip->msec_MaxTime ) {
1899
+ ulTEnd = ulTStart;
1900
+ pulTEnd = &ulTEnd;
1901
+ if ( ip->msec_LeftTime > 0 ) {
1902
+ InchiTimeAddMsec( pulTEnd, ip->msec_LeftTime );
1903
+ }
1904
+ }
1905
+ num_at = Create_INChI( cur_INChI, cur_INChI_Aux, orig_inp_data, inp_cur_data->at,
1906
+ inp_norm_data,
1907
+ inp_cur_data->num_at,
1908
+ ip->nMode, &bTautFlags, &bTautFlagsDone, pulTEnd, sd->pStrErrStruct);
1909
+ SetConnectedComponentNumber( inp_cur_data->at, inp_cur_data->num_at, i+1 ); /* normalization alters structure component number */
1910
+ for ( k = 0; k < TAUT_NUM; k ++ ) {
1911
+ if ( cur_INChI_Aux[k] && cur_INChI_Aux[k]->nNumberOfAtoms > 0 ) {
1912
+ pncFlags->bNormalizationFlags[iINChI][k] |= cur_INChI_Aux[k]->bNormalizationFlags;
1913
+ pncFlags->bTautFlags[iINChI][k] |= cur_INChI_Aux[k]->bTautFlags;
1914
+ pncFlags->bTautFlagsDone[iINChI][k] |= cur_INChI_Aux[k]->bTautFlagsDone;
1915
+ pncFlags->nCanonFlags[iINChI][k] |= cur_INChI_Aux[k]->nCanonFlags;
1916
+ }
1917
+ }
1918
+
1919
+ /* Detect errors */
1920
+ if ( num_at < 0 ) {
1921
+ sd->nErrorCode = num_at;
1922
+ } else
1923
+ if ( num_at == 0 ) {
1924
+ sd->nErrorCode = -1;
1925
+ } else
1926
+ if ( cur_INChI[TAUT_NON] && cur_INChI[TAUT_NON]->nErrorCode ) {
1927
+ /* non-tautomeric error */
1928
+ sd->nErrorCode = cur_INChI[TAUT_NON]->nErrorCode;
1929
+ } else
1930
+ if ( cur_INChI[TAUT_YES] && cur_INChI[TAUT_YES]->nErrorCode ) {
1931
+ /* tautomeric error */
1932
+ sd->nErrorCode = cur_INChI[TAUT_YES]->nErrorCode;
1933
+ }
1934
+ #if( bRELEASE_VERSION == 0 )
1935
+ if ( cur_INChI[TAUT_NON] ) sd->bExtract |= cur_INChI[TAUT_NON]->bExtract;
1936
+ if ( cur_INChI[TAUT_YES] ) sd->bExtract |= cur_INChI[TAUT_YES]->bExtract;
1937
+ if ( (TG_FLAG_TEST_TAUT3_SALTS_DONE & bTautFlagsDone) ) {
1938
+ sd->bExtract |= EXTR_TEST_TAUT3_SALTS_DONE;
1939
+ }
1940
+ #endif
1941
+ /* detect and store stereo warnings */
1942
+ if ( !sd->nErrorCode ) {
1943
+ GetProcessingWarnings(cur_INChI, inp_norm_data, sd);
1944
+ }
1945
+
1946
+ lElapsedTime = InchiTimeElapsed( &ulTStart );
1947
+ if ( ip->msec_MaxTime ) {
1948
+ ip->msec_LeftTime -= lElapsedTime;
1949
+ }
1950
+ sd->ulStructTime += lElapsedTime;
1951
+ #ifndef INCHI_LIBRARY
1952
+ /* Display the results */
1953
+ if ( ip->bDisplay )
1954
+ eat_keyboard_input();
1955
+ #endif
1956
+ /* a) No matter what happened save the allocated INChI pointers */
1957
+ /* save the INChI of the current component */
1958
+
1959
+ InchiTimeGet( &ulTStart );
1960
+ for ( k = 0; k < TAUT_NUM; k ++ ) {
1961
+ pINChI[i][k] = cur_INChI[k];
1962
+ pINChI_Aux[i][k] = cur_INChI_Aux[k];
1963
+
1964
+ cur_INChI[k] = NULL;
1965
+ cur_INChI_Aux[k] = NULL;
1966
+ }
1967
+
1968
+ /* b) Count one component structure and/or INChI results only if there was no error */
1969
+ /* Set inp_norm_data[j]->num_removed_H = number of removed explicit H */
1970
+
1971
+ if ( !sd->nErrorCode ) {
1972
+
1973
+ /* find where the current processed structure is located */
1974
+ int cur_is_in_non_taut = (pINChI[i][TAUT_NON] && pINChI[i][TAUT_NON]->nNumberOfAtoms>0);
1975
+ int cur_is_in_taut = (pINChI[i][TAUT_YES] && pINChI[i][TAUT_YES]->nNumberOfAtoms>0);
1976
+ int cur_is_non_taut = cur_is_in_non_taut && 0 == pINChI[i][TAUT_NON]->lenTautomer ||
1977
+ cur_is_in_taut && 0 == pINChI[i][TAUT_YES]->lenTautomer;
1978
+ int cur_is_taut = cur_is_in_taut && 0 < pINChI[i][TAUT_YES]->lenTautomer;
1979
+ /*
1980
+ sd->bTautFlags[iINChI] |= bTautFlags;
1981
+ sd->bTautFlagsDone[iINChI] |= bTautFlagsDone;
1982
+ */
1983
+ if ( cur_is_non_taut + cur_is_taut ) {
1984
+ /* count tautomeric and non-tautomeric components of the structures */
1985
+ int j1 = cur_is_in_non_taut? TAUT_NON:TAUT_YES;
1986
+ int j2 = cur_is_in_taut? TAUT_YES:TAUT_NON;
1987
+ int j;
1988
+ sd->num_non_taut[iINChI] += cur_is_non_taut;
1989
+ sd->num_taut[iINChI] += cur_is_taut;
1990
+ for ( j = j1; j <= j2; j ++ ) {
1991
+ int bIsotopic = (pINChI[i][j]->nNumberOfIsotopicAtoms ||
1992
+ pINChI[i][j]->nNumberOfIsotopicTGroups ||
1993
+ pINChI[i][j]->nPossibleLocationsOfIsotopicH && pINChI[i][j]->nPossibleLocationsOfIsotopicH[0]>1);
1994
+ if ( j == TAUT_YES ) {
1995
+ bIsotopic |= (0 < pINChI_Aux[i][j]->nNumRemovedIsotopicH[0] +
1996
+ pINChI_Aux[i][j]->nNumRemovedIsotopicH[1] +
1997
+ pINChI_Aux[i][j]->nNumRemovedIsotopicH[2]);
1998
+ }
1999
+ inp_norm_data[j]->bExists = 1; /* j=0: non-taut exists, j=1: taut exists */
2000
+ inp_norm_data[j]->bHasIsotopicLayer = bIsotopic;
2001
+ /*inp_norm_data[j]->num_removed_H = inp_norm_data[j]->num_at - num_at;*/
2002
+ }
2003
+ }
2004
+ }
2005
+ /*
2006
+ return (sd->nErrorCode==CT_OUT_OF_RAM || sd->nErrorCode==CT_USER_QUIT_ERR)? _IS_FATAL :
2007
+ sd->nErrorCode? _IS_ERROR : 0;
2008
+ */
2009
+ if ( sd->nErrorCode==CT_OUT_OF_RAM || sd->nErrorCode==CT_USER_QUIT_ERR ) {
2010
+ ret = _IS_FATAL;
2011
+ } else
2012
+ if ( sd->nErrorCode ) {
2013
+ ret = _IS_ERROR;
2014
+ }
2015
+ lElapsedTime = InchiTimeElapsed( &ulTStart );
2016
+ if ( ip->msec_MaxTime ) {
2017
+ ip->msec_LeftTime -= lElapsedTime;
2018
+ }
2019
+ sd->ulStructTime += lElapsedTime;
2020
+ return ret;
2021
+ }
2022
+ /****************************************************************************************************/
2023
+ int TreatCreateOneComponentINChIError(STRUCT_DATA *sd, INPUT_PARMS *ip, ORIG_ATOM_DATA *orig_inp_data,
2024
+ int i, int num_inp,
2025
+ FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
2026
+ char *pStr, int nStrLen )
2027
+ {
2028
+ if ( sd->nErrorCode ) {
2029
+ AddMOLfileError(sd->pStrErrStruct, ErrMsg(sd->nErrorCode) );
2030
+ my_fprintf( log_file, "Error %d (%s) structure #%d component %d.%s%s%s%s\n",
2031
+ sd->nErrorCode, sd->pStrErrStruct, num_inp, i+1, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
2032
+ sd->nErrorType = (sd->nErrorCode==CT_OUT_OF_RAM || sd->nErrorCode==CT_USER_QUIT_ERR)? _IS_FATAL : _IS_ERROR;
2033
+ if ( (ip->bINChIOutputOptions & INCHI_OUT_XML)
2034
+ #ifdef INCHI_LIB
2035
+ || (ip->bINChIOutputOptions & INCHI_OUT_WINCHI_WINDOW) && (ip->bINChIOutputOptions & INCHI_OUT_PLAIN_TEXT)
2036
+ #endif
2037
+ ) {
2038
+ sd->nErrorType = ProcessStructError( output_file, log_file, /*sd->nErrorCode,*/ sd->pStrErrStruct,
2039
+ sd->nErrorType, &sd->bXmlStructStarted, num_inp, ip, pStr, nStrLen );
2040
+ /* save the problem structure */
2041
+ if ( prb_file && 0L <= sd->fPtrStart && sd->fPtrStart < sd->fPtrEnd && !ip->bSaveAllGoodStructsAsProblem ) {
2042
+ CopyMOLfile(inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file, num_inp);
2043
+ }
2044
+ } else {
2045
+ /* save the problem structure */
2046
+ if ( sd->nErrorCode && prb_file && 0L <= sd->fPtrStart && sd->fPtrStart < sd->fPtrEnd && !ip->bSaveAllGoodStructsAsProblem ) {
2047
+ CopyMOLfile(inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file, num_inp);
2048
+ }
2049
+ }
2050
+ }
2051
+ #ifndef INCHI_LIBRARY
2052
+ /* print the logfile record */
2053
+ if ( log_file && log_file != stderr && (sd->ulStructTime >= 1000 || sd->nErrorCode) ) {
2054
+ fprintf( log_file, "%10lu msec structure #%d.%s%s%s%s (%d component%s, %d atom%s, error=%d).\n",
2055
+ sd->ulStructTime, num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue),
2056
+ orig_inp_data->num_components, orig_inp_data->num_components==1?"":"s",
2057
+ orig_inp_data->num_inp_atoms, orig_inp_data->num_inp_atoms==1?"":"s", sd->nErrorCode );
2058
+ }
2059
+ #endif
2060
+ return sd->nErrorType;
2061
+ }
2062
+ /****************************************************************************************************/
2063
+ int TreatCreateINChIWarning(STRUCT_DATA *sd, INPUT_PARMS *ip, ORIG_ATOM_DATA *orig_inp_data, int num_inp,
2064
+ FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
2065
+ char *pStr, int nStrLen )
2066
+ {
2067
+ #if( bRELEASE_VERSION == 0 && (EXTR_FLAGS || EXTR_MASK) )
2068
+ if ( EXTR_MASK? ((sd->bExtract & EXTR_MASK) == EXTR_FLAGS) : (sd->bExtract & EXTR_FLAGS) ) {
2069
+ char szMsg[64];
2070
+ sprintf( szMsg, "ExtractStruct.code=0x%X", sd->bExtract);
2071
+ AddMOLfileError(sd->pStrErrStruct, szMsg);
2072
+ }
2073
+ #endif
2074
+ if ( !sd->nErrorCode && sd->pStrErrStruct[0] ) {
2075
+ my_fprintf( log_file, "Warning (%s) structure #%d.%s%s%s%s\n",
2076
+ sd->pStrErrStruct, num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
2077
+ sd->nErrorType = _IS_WARNING;
2078
+ if ( (ip->bINChIOutputOptions & INCHI_OUT_XML)
2079
+ #ifdef INCHI_LIB
2080
+ || (ip->bINChIOutputOptions & INCHI_OUT_WINCHI_WINDOW) && (ip->bINChIOutputOptions & INCHI_OUT_PLAIN_TEXT)
2081
+ #endif
2082
+ ) {
2083
+ sd->nErrorType = ProcessStructError( output_file, log_file, /*sd->nErrorCode,*/ sd->pStrErrStruct,
2084
+ sd->nErrorType, &sd->bXmlStructStarted, num_inp, ip, pStr, nStrLen );
2085
+ }
2086
+ /* save the structure as a problem structure if requested */
2087
+ if ( ip->bSaveWarningStructsAsProblem && !ip->bSaveAllGoodStructsAsProblem &&
2088
+ prb_file && 0L <= sd->fPtrStart && sd->fPtrStart < sd->fPtrEnd ) {
2089
+ CopyMOLfile(inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file, num_inp);
2090
+ }
2091
+ #if( bRELEASE_VERSION == 0 )
2092
+ /* otherwise extract the structure as a problem structure if requested */
2093
+ else
2094
+ if ( (EXTR_MASK? ((sd->bExtract & EXTR_MASK) == EXTR_FLAGS) : (sd->bExtract & EXTR_FLAGS)) && !ip->bSaveAllGoodStructsAsProblem &&
2095
+ prb_file && 0L <= sd->fPtrStart && sd->fPtrStart < sd->fPtrEnd ) {
2096
+ CopyMOLfile(inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file, num_inp);
2097
+ }
2098
+ #endif
2099
+ }
2100
+ #if( bRELEASE_VERSION != 1 && bOUTPUT_ONE_STRUCT_TIME == 1 )
2101
+ #ifndef INCHI_LIBRARY
2102
+ if ( log_file && log_file != stderr ) {
2103
+ fprintf( log_file, "%10lu msec structure %1dD #%d.%s%s%s%s (%d component%s, %d atom%s, error=%d).\n",
2104
+ sd->ulStructTime, orig_inp_data->num_dimensions, num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue),
2105
+ orig_inp_data->num_components, orig_inp_data->num_components==1?"":"s",
2106
+ orig_inp_data->num_inp_atoms, orig_inp_data->num_inp_atoms==1?"":"s", sd->nErrorCode );
2107
+ }
2108
+ #else
2109
+ if ( log_file ) {
2110
+ my_fprintf( log_file, "%10lu msec structure %1dD #%d.%s%s%s%s (%d component%s, %d atom%s, error=%d).\n",
2111
+ sd->ulStructTime, orig_inp_data->num_dimensions, num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue),
2112
+ orig_inp_data->num_components, orig_inp_data->num_components==1?"":"s",
2113
+ orig_inp_data->num_inp_atoms, orig_inp_data->num_inp_atoms==1?"":"s", sd->nErrorCode );
2114
+ }
2115
+ #endif
2116
+ #endif
2117
+ return sd->nErrorType;
2118
+ }
2119
+ /*******************************************************************************************/
2120
+ int DuplicateOrigAtom( ORIG_ATOM_DATA *new_orig_atom, ORIG_ATOM_DATA *orig_atom )
2121
+ {
2122
+ inp_ATOM *at = NULL;
2123
+ AT_NUMB *nCurAtLen = NULL;
2124
+ AT_NUMB *nOldCompNumber = NULL;
2125
+
2126
+ if ( new_orig_atom->at && new_orig_atom->num_inp_atoms >= orig_atom->num_inp_atoms ) {
2127
+ at = new_orig_atom->at;
2128
+ } else {
2129
+ at = (inp_ATOM *)inchi_calloc(orig_atom->num_inp_atoms+1, sizeof(at[0]));
2130
+ }
2131
+ if ( new_orig_atom->nOldCompNumber && new_orig_atom->num_components >= orig_atom->num_components ) {
2132
+ nCurAtLen = new_orig_atom->nCurAtLen;
2133
+ } else {
2134
+ nCurAtLen = (AT_NUMB *)inchi_calloc(orig_atom->num_components+1, sizeof(nCurAtLen[0]));
2135
+ }
2136
+ if ( new_orig_atom->nCurAtLen && new_orig_atom->num_components >= orig_atom->num_components ) {
2137
+ nOldCompNumber = new_orig_atom->nOldCompNumber;
2138
+ } else {
2139
+ nOldCompNumber = (AT_NUMB *)inchi_calloc(orig_atom->num_components+1, sizeof(nOldCompNumber[0]));
2140
+ }
2141
+
2142
+ if ( at && nCurAtLen && nOldCompNumber ) {
2143
+ /* copy */
2144
+ if ( orig_atom->at )
2145
+ memcpy( at, orig_atom->at, orig_atom->num_inp_atoms * sizeof(new_orig_atom->at[0]) );
2146
+ if ( orig_atom->nCurAtLen )
2147
+ memcpy( nCurAtLen, orig_atom->nCurAtLen, orig_atom->num_components*sizeof(nCurAtLen[0]) );
2148
+ if ( orig_atom->nOldCompNumber )
2149
+ memcpy( nOldCompNumber, orig_atom->nOldCompNumber, orig_atom->num_components*sizeof(nOldCompNumber[0]) );
2150
+ /* deallocate */
2151
+ if ( new_orig_atom->at && new_orig_atom->at != at )
2152
+ inchi_free( new_orig_atom->at );
2153
+ if ( new_orig_atom->nCurAtLen && new_orig_atom->nCurAtLen != nCurAtLen )
2154
+ inchi_free( new_orig_atom->nCurAtLen );
2155
+ if ( new_orig_atom->nOldCompNumber && new_orig_atom->nOldCompNumber != nOldCompNumber )
2156
+ inchi_free( new_orig_atom->nOldCompNumber );
2157
+
2158
+ *new_orig_atom = *orig_atom;
2159
+ new_orig_atom->at = at;
2160
+ new_orig_atom->nCurAtLen = nCurAtLen;
2161
+ new_orig_atom->nOldCompNumber = nOldCompNumber;
2162
+ /* data that are not to be copied */
2163
+ new_orig_atom->nNumEquSets = 0;
2164
+ memset(new_orig_atom->bSavedInINCHI_LIB, 0, sizeof(new_orig_atom->bSavedInINCHI_LIB));
2165
+ memset(new_orig_atom->bPreprocessed, 0, sizeof(new_orig_atom->bPreprocessed));
2166
+ /* arrays that are not to be copied */
2167
+ new_orig_atom->szCoord = NULL;
2168
+ new_orig_atom->nEquLabels = NULL;
2169
+ new_orig_atom->nSortedOrder = NULL;
2170
+ return 0;
2171
+ }
2172
+
2173
+ /* deallocate */
2174
+ if ( at && new_orig_atom->at != at )
2175
+ inchi_free( at );
2176
+ if ( nCurAtLen && new_orig_atom->nCurAtLen != nCurAtLen )
2177
+ inchi_free( nCurAtLen );
2178
+ if ( nOldCompNumber && new_orig_atom->nOldCompNumber != nOldCompNumber )
2179
+ inchi_free( nOldCompNumber );
2180
+
2181
+ return -1; /* failed */
2182
+ }
2183
+ #ifndef INCHI_LIBRARY
2184
+ /*******************************************************************************************/
2185
+ int GetOneStructure( STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle,
2186
+ FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
2187
+ ORIG_ATOM_DATA *orig_inp_data, int *num_inp, char *pStr, int nStrLen, STRUCT_FPTRS *struct_fptrs )
2188
+ {
2189
+ int nRet, inp_index, out_index, bUseFptr = (NULL != struct_fptrs);
2190
+
2191
+ FreeOrigAtData( orig_inp_data );
2192
+ /*
2193
+ FreeOrigAtData( orig_inp_data + 1 );
2194
+ FreeOrigAtData( orig_inp_data + 2 );
2195
+ */
2196
+
2197
+ /* added for INCHI_LIB early EOF detection */
2198
+ inp_index = -1;
2199
+ out_index = -1;
2200
+ if ( struct_fptrs ) {
2201
+ if ( inp_file == stdin ) {
2202
+ return _IS_FATAL;
2203
+ }
2204
+ if ( ip->nInputType == INPUT_CMLFILE ) {
2205
+ bUseFptr = 0;
2206
+ }
2207
+ /* initially allocate or increase length of struct_fptrs->fptr array */
2208
+ if ( !struct_fptrs->fptr || struct_fptrs->len_fptr <= struct_fptrs->cur_fptr+1 ) {
2209
+ INCHI_FPTR *new_fptr = (INCHI_FPTR *)inchi_calloc( struct_fptrs->len_fptr + ADD_LEN_STRUCT_FPTRS, sizeof(new_fptr[0]) );
2210
+ if ( new_fptr ) {
2211
+ if ( struct_fptrs->fptr ) {
2212
+ if ( struct_fptrs->len_fptr ) {
2213
+ memcpy( new_fptr, struct_fptrs->fptr, struct_fptrs->len_fptr*sizeof(new_fptr[0]));
2214
+ }
2215
+ inchi_free( struct_fptrs->fptr );
2216
+ } else {
2217
+ struct_fptrs->len_fptr = 0;
2218
+ struct_fptrs->cur_fptr = 0;
2219
+ struct_fptrs->max_fptr = 0;
2220
+ }
2221
+ struct_fptrs->len_fptr += ADD_LEN_STRUCT_FPTRS;
2222
+ struct_fptrs->fptr = new_fptr;
2223
+ } else {
2224
+ return _IS_FATAL; /* new_fptr allocation error */
2225
+ }
2226
+ }
2227
+ if ( struct_fptrs->fptr[struct_fptrs->cur_fptr] == EOF ) {
2228
+ return _IS_EOF;
2229
+ } else {
2230
+ if ( bUseFptr ) {
2231
+ if( fseek( inp_file, struct_fptrs->fptr[struct_fptrs->cur_fptr], SEEK_SET) ) {
2232
+ return _IS_FATAL;
2233
+ }
2234
+ if ( struct_fptrs->cur_fptr && struct_fptrs->max_fptr <= struct_fptrs->cur_fptr ) {
2235
+ return _IS_FATAL;
2236
+ }
2237
+ } else {
2238
+ inp_index = struct_fptrs->fptr[struct_fptrs->cur_fptr];
2239
+ out_index = EOF;
2240
+ }
2241
+ }
2242
+ *num_inp = struct_fptrs->cur_fptr; /* set structure count */
2243
+ }
2244
+
2245
+ nRet = ReadTheStructure( sd, ip, inp_file, orig_inp_data, inp_index, &out_index );
2246
+
2247
+ if ( !nRet ) {
2248
+ /*****************************************************
2249
+ * In case of no error output structure xml start tag
2250
+ * output read the structure errors and warnings
2251
+ *****************************************************/
2252
+ if ( ip->nInputType == INPUT_INCHI_PLAIN || ip->nInputType == INPUT_INCHI_XML ||
2253
+ ip->nInputType == INPUT_MOLFILE || ip->nInputType == INPUT_SDFILE) {
2254
+ if ( ip->lMolfileNumber ) {
2255
+ *num_inp = ip->lMolfileNumber;
2256
+ } else {
2257
+ *num_inp += 1;
2258
+ }
2259
+ } else {
2260
+ *num_inp += 1;
2261
+ }
2262
+ nRet = TreatReadTheStructureErrors( sd, ip, LOG_MASK_ALL, inp_file, log_file, output_file, prb_file,
2263
+ orig_inp_data, num_inp, pStr, nStrLen );
2264
+ }
2265
+
2266
+ /************************************************************/
2267
+ /* added for INCHI_LIB: look ahead for end of file detection */
2268
+ /************************************************************/
2269
+ if ( struct_fptrs && struct_fptrs->fptr && struct_fptrs->fptr[struct_fptrs->cur_fptr+1] <= 0 ) {
2270
+ int nRet2 = 0;
2271
+ INCHI_FPTR next_fptr;
2272
+ STRUCT_DATA sd2;
2273
+
2274
+ if ( nRet != _IS_EOF && nRet != _IS_FATAL ) {
2275
+ if ( inp_file == stdin || struct_fptrs->len_fptr <= struct_fptrs->cur_fptr+1 ) {
2276
+ return _IS_FATAL;
2277
+ }
2278
+ /* get next structure fptr */
2279
+ if ( bUseFptr ) {
2280
+ next_fptr = ftell( inp_file );
2281
+ } else {
2282
+ inp_index = out_index;
2283
+ out_index = EOF;
2284
+ }
2285
+ /* read the next structure */
2286
+ nRet2 = ReadTheStructure( &sd2, ip, inp_file, NULL, inp_index, &out_index );
2287
+ /* restore fptr to the next structure */
2288
+ if ( bUseFptr ) {
2289
+ if ( next_fptr != -1L ) {
2290
+ fseek( inp_file, next_fptr, SEEK_SET);
2291
+ }
2292
+ }
2293
+ #if ( ADD_CMLPP == 1 )
2294
+ else {
2295
+ if ( inp_index >= 0 ) {
2296
+ SetCmlStructIndex( inp_index ); /* so far nothing to do */
2297
+ }
2298
+ }
2299
+ #endif
2300
+ } else {
2301
+ /* treat current fatal error as end of file */
2302
+ struct_fptrs->fptr[struct_fptrs->cur_fptr] = EOF;
2303
+ }
2304
+ /* next is end of file or fatal */
2305
+ if ( nRet == _IS_EOF || nRet == _IS_FATAL ||
2306
+ nRet2 == _IS_EOF || nRet2 == _IS_FATAL ) {
2307
+ struct_fptrs->fptr[struct_fptrs->cur_fptr+1] = EOF;
2308
+ } else {
2309
+ struct_fptrs->fptr[struct_fptrs->cur_fptr+1] = bUseFptr? sd->fPtrEnd : inp_index;
2310
+ }
2311
+
2312
+ /* update struct_fptrs->max_fptr */
2313
+ if ( struct_fptrs->max_fptr <= struct_fptrs->cur_fptr+1 ) {
2314
+ struct_fptrs->max_fptr = struct_fptrs->cur_fptr+2;
2315
+ }
2316
+ }
2317
+
2318
+ switch ( nRet ) {
2319
+ case _IS_EOF:
2320
+ *num_inp -= 1;
2321
+ case _IS_FATAL:
2322
+ case _IS_ERROR:
2323
+ case _IS_SKIP:
2324
+ goto exit_function;
2325
+ }
2326
+
2327
+ /*
2328
+ if ( !orig_inp_data->num_dimensions ) {
2329
+ AddMOLfileError(sd->pStrErrStruct, "0D"); */ /* 0D-structure: no coordinates
2330
+ }
2331
+ */
2332
+
2333
+
2334
+ exit_function:
2335
+ return nRet;
2336
+ }
2337
+ #endif
2338
+ #if( TEST_RENUMB_ATOMS == 1 ) /* { */
2339
+ /************************************************************************************************/
2340
+ int RenumberingTestInit( RENUMB_DATA *pRenumbData, INP_ATOM_DATA *inp_cur_data )
2341
+ {
2342
+ int j;
2343
+ pRenumbData->ren_inp_norm_data[0] = &pRenumbData->ren_inp_norm_data1;
2344
+ pRenumbData->ren_inp_norm_data[1] = &pRenumbData->ren_inp_norm_data2;
2345
+ memset( pRenumbData->ren_INChI2, 0, sizeof( pRenumbData->ren_INChI2 ));
2346
+ memset( pRenumbData->ren_INChI_Aux, 0, sizeof( pRenumbData->ren_INChI_Aux ));
2347
+ memset( &pRenumbData->orig_inp_cur_data, 0, sizeof( pRenumbData->orig_inp_cur_data ));
2348
+ memset( &pRenumbData->saved_inp_cur_data, 0, sizeof( pRenumbData->saved_inp_cur_data ));
2349
+ memset( pRenumbData->ren_inp_norm_data[0], 0, sizeof( *pRenumbData->ren_inp_norm_data[0] ));
2350
+ memset( pRenumbData->ren_inp_norm_data[1], 0, sizeof( *pRenumbData->ren_inp_norm_data[1] ));
2351
+ #if( TEST_RENUMB_ATOMS_SAVE_LONGEST == 1 )
2352
+ memset( &pRenumbData->longest_inp_cur_data, 0, sizeof(pRenumbData->longest_inp_cur_data));
2353
+ #endif
2354
+ CopyInpAtomData( &pRenumbData->orig_inp_cur_data, inp_cur_data );
2355
+ pRenumbData->ren_counter = pRenumbData->orig_inp_cur_data.num_at * pRenumbData->orig_inp_cur_data.num_at;
2356
+ srand(1); /* for reproducibility */
2357
+ rand(); /* shift to avoid prev. sequences */
2358
+ pRenumbData->nComp = 0;
2359
+ /*ren_counter = 29;*/
2360
+ pRenumbData->new_ord = (AT_RANK *)inchi_calloc( pRenumbData->orig_inp_cur_data.num_at, sizeof(pRenumbData->new_ord[0]) );
2361
+ if ( pRenumbData->new_ord ) {
2362
+ for ( j = 0; j < pRenumbData->orig_inp_cur_data.num_at; j ++ ) {
2363
+ pRenumbData->new_ord[j] = (AT_RANK)j;
2364
+ }
2365
+ return 0;
2366
+ }
2367
+ return -1; /* out of RAM */
2368
+ }
2369
+ /************************************************************************************************/
2370
+ int RenumberingTestUninit( RENUMB_DATA *pRenumbData )
2371
+ {
2372
+ FreeInpAtomData( &pRenumbData->orig_inp_cur_data );
2373
+ #if( TEST_RENUMB_ATOMS_SAVE_LONGEST == 1 )
2374
+ FreeInpAtomData( &pRenumbData->longest_inp_cur_data );
2375
+ #endif
2376
+ inchi_free( pRenumbData->new_ord );
2377
+ return 0;
2378
+ }
2379
+ /************************************************************************************************/
2380
+ int RenumberingTest( PINChI2 *pINChI, PINChI_Aux2 *pINChI_Aux, ORIG_ATOM_DATA *orig_inp_data, int iINChI,
2381
+ RENUMB_DATA *pRenumbData, INP_ATOM_DATA *inp_cur_data, INP_ATOM_DATA **inp_norm_data,
2382
+ STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle, INCHI_FILE *log_file, INCHI_FILE *prb_file,
2383
+ int i, int num_inp, NORM_CANON_FLAGS *pncFlags)
2384
+ {
2385
+ int k, bLongerTime;
2386
+ CopyInpAtomData( &pRenumbData->saved_inp_cur_data, inp_cur_data );
2387
+ pRenumbData->nRet2 = 0;
2388
+ pRenumbData->num_taut0 = sd->num_taut[iINChI];
2389
+ pRenumbData->num_non_taut0 = sd->num_non_taut[iINChI];
2390
+ pRenumbData->ulMaxTime = 0;
2391
+ while ( -- pRenumbData->ren_counter >= 0 && !pRenumbData->nRet2 ) {
2392
+ pRenumbData->nComp ++;
2393
+ MakeNewOrd( pRenumbData->orig_inp_cur_data.num_at, pRenumbData->new_ord );
2394
+ RenumbInpAtomData( inp_cur_data, &pRenumbData->orig_inp_cur_data, pRenumbData->new_ord );
2395
+ #if( TEST_RENUMB_ATOMS_SAVE_LONGEST == 1 )
2396
+ CopyInpAtomData( &pRenumbData->longest_inp_cur_data, inp_cur_data );
2397
+ #endif
2398
+ if ( 470 == pRenumbData->nComp ) {
2399
+ int stop = 1; /* debug only */
2400
+ }
2401
+
2402
+ pRenumbData->nRet2 = CreateOneComponentINChI( sd, ip, inp_cur_data, NULL /*orig_inp_data*/,
2403
+ pRenumbData->ren_INChI2, pRenumbData->ren_INChI_Aux, iINChI,
2404
+ 0, num_inp, pRenumbData->ren_inp_norm_data, pncFlags, log_file );
2405
+ /*
2406
+ CreateOneComponentINChI( sd, ip, inp_cur_data, orig_inp_data, pINChI2[iINChI], pINChI_Aux2[iINChI], iINChI,
2407
+ i, num_inp, inp_norm_data, log_file );
2408
+ */
2409
+ if ( !pRenumbData->nRet2 ) {
2410
+ pRenumbData->c1 = CompareINChI( pINChI[i][TAUT_NON], pRenumbData->ren_INChI2[0][TAUT_NON],
2411
+ pINChI_Aux[i][TAUT_NON], pRenumbData->ren_INChI_Aux[0][TAUT_NON]);
2412
+ pRenumbData->c2 = CompareINChI( pINChI[i][TAUT_YES], pRenumbData->ren_INChI2[0][TAUT_YES],
2413
+ pINChI_Aux[i][TAUT_YES], pRenumbData->ren_INChI_Aux[0][TAUT_YES]);
2414
+ if ( pRenumbData->c1 || pRenumbData->c2 || pRenumbData->nRet2 ) {
2415
+
2416
+ /****** the renumbering result is different ******/
2417
+
2418
+ my_fprintf( log_file, "Compare (%d,%d) %d (err=%d) %s structure #%d component %d.%s%s%s%s\n",
2419
+ pRenumbData->c1, pRenumbData->c2,
2420
+ pRenumbData->nComp, pRenumbData->nRet2, INCHI_NAME,
2421
+ num_inp, i+1, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
2422
+ for ( k = 0; k < pRenumbData->orig_inp_cur_data.num_at; k ++ ) {
2423
+ my_fprintf( log_file, " %d", (int)pRenumbData->new_ord[k] );
2424
+ }
2425
+ my_fprintf( log_file, "\n" );
2426
+ pRenumbData->ren_counter = 0; /* force exit */
2427
+ pRenumbData->bRenumbErr = 1000*pRenumbData->c2 + pRenumbData->c1;
2428
+ }
2429
+ #if( TEST_RENUMB_ATOMS_SAVE_LONGEST == 1 )
2430
+ /* output time per this component */
2431
+ my_fprintf( stderr, "\rComp#%d str#%d/%d%s%s%s%s Ren %d/%d n(%lu:%lu)c(%lu:%lu)...\r",
2432
+ i+1, num_inp, iINChI, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), pRenumbData->nComp, pRenumbData->ren_counter+pRenumbData->nComp,
2433
+ pRenumbData->ren_INChI_Aux[0][TAUT_NON]->ulNormTime, pRenumbData->ren_INChI_Aux[0][TAUT_NON]->ulCanonTime,
2434
+ pRenumbData->ren_INChI_Aux[0][TAUT_YES]->ulNormTime, pRenumbData->ren_INChI_Aux[0][TAUT_YES]->ulCanonTime);
2435
+ #endif
2436
+ /* make sure the max. time is not overwritten */
2437
+ pRenumbData->ulCurTime0 = pRenumbData->ren_INChI_Aux[0][TAUT_NON]?
2438
+ (pRenumbData->ren_INChI_Aux[0][TAUT_NON]->ulNormTime
2439
+ + pRenumbData->ren_INChI_Aux[0][TAUT_NON]->ulCanonTime) : 0;
2440
+ pRenumbData->ulCurTime1 = pRenumbData->ren_INChI_Aux[0][TAUT_YES]?
2441
+ (pRenumbData->ren_INChI_Aux[0][TAUT_YES]->ulNormTime
2442
+ + pRenumbData->ren_INChI_Aux[0][TAUT_YES]->ulCanonTime) : 0;
2443
+ pRenumbData->ulCurTime = inchi_max( pRenumbData->ulCurTime0, pRenumbData->ulCurTime1 );
2444
+
2445
+ pRenumbData->ulCurTimeCanon0 = pRenumbData->ren_INChI_Aux[0][TAUT_NON]? pRenumbData->ren_INChI_Aux[0][TAUT_NON]->ulCanonTime : 0;
2446
+ pRenumbData->ulCurTimeCanon1 = pRenumbData->ren_INChI_Aux[0][TAUT_YES]? pRenumbData->ren_INChI_Aux[0][TAUT_YES]->ulCanonTime : 0;
2447
+ pRenumbData->ulCurTimeCanon = inchi_max( pRenumbData->ulCurTimeCanon0, pRenumbData->ulCurTimeCanon1);
2448
+
2449
+ pRenumbData->ulCurTimeNorm0 = pRenumbData->ren_INChI_Aux[0][TAUT_NON]? pRenumbData->ren_INChI_Aux[0][TAUT_NON]->ulNormTime:0;
2450
+ pRenumbData->ulCurTimeNorm1 = pRenumbData->ren_INChI_Aux[0][TAUT_YES]? pRenumbData->ren_INChI_Aux[0][TAUT_YES]->ulNormTime:0;
2451
+ pRenumbData->ulCurTimeNorm = inchi_max( pRenumbData->ulCurTimeNorm0, pRenumbData->ulCurTimeNorm1);
2452
+
2453
+
2454
+ bLongerTime = 0;
2455
+ if ( pRenumbData->ulCurTime > pRenumbData->ulMaxTime ) {
2456
+ pRenumbData->ulMaxTime = pRenumbData->ulCurTime;
2457
+ bLongerTime = 1;
2458
+ }
2459
+ if ( pRenumbData->ulMaxTimeCanon > pRenumbData->ulCurTimeCanon ) {
2460
+ pRenumbData->ulMaxTimeCanon = pRenumbData->ulCurTimeCanon;
2461
+ bLongerTime = 1;
2462
+ }
2463
+ if ( pRenumbData->ulMaxTimeNorm > pRenumbData->ulCurTimeCanon ) {
2464
+ pRenumbData->ulMaxTimeCanon = pRenumbData->ulCurTimeCanon;
2465
+ bLongerTime = 1;
2466
+ }
2467
+ #if( TEST_RENUMB_ATOMS_SAVE_LONGEST == 1 )
2468
+ if ( bLongerTime ) {
2469
+ char szLine[512];
2470
+ char szValue[512];
2471
+ //my_fprintf( stderr, "\n" );
2472
+ sprintf( szLine, "Comp#%d str#%d/%d%s%s%s%s Ren %d/%d n=%lu:%lu c=%lu:%lu",
2473
+ i+1, num_inp, iINChI, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), pRenumbData->nComp, pRenumbData->ren_counter+pRenumbData->nComp,
2474
+ pRenumbData->ren_INChI_Aux[0][TAUT_NON]->ulNormTime, pRenumbData->ren_INChI_Aux[0][TAUT_NON]->ulCanonTime,
2475
+ pRenumbData->ren_INChI_Aux[0][TAUT_YES]->ulNormTime, pRenumbData->ren_INChI_Aux[0][TAUT_YES]->ulCanonTime);
2476
+ sprintf( szValue, "%s (c%d/s%d/i%d, r%d/%d n=%lu:%lu c=%lu:%lu)",
2477
+ (ip->pSdfValue && ip->pSdfValue[0])? ip->pSdfValue:"unk",
2478
+ i+1, num_inp, iINChI, pRenumbData->nComp, pRenumbData->ren_counter+pRenumbData->nComp,
2479
+ pRenumbData->ren_INChI_Aux[0][TAUT_NON]->ulNormTime, pRenumbData->ren_INChI_Aux[0][TAUT_NON]->ulCanonTime,
2480
+ pRenumbData->ren_INChI_Aux[0][TAUT_YES]->ulNormTime, pRenumbData->ren_INChI_Aux[0][TAUT_YES]->ulCanonTime);
2481
+
2482
+ WriteToSDfile( &pRenumbData->longest_inp_cur_data, prb_file, szLine, NULL, ip->pSdfLabel, szValue );
2483
+ }
2484
+ #endif
2485
+
2486
+ #if ( TEST_RENUMB_SWITCH == 1 )
2487
+ if ( pRenumbData->c1 || pRenumbData->c2 || !pRenumbData->ren_counter ) {
2488
+ swap( (char*)&pINChI[i][TAUT_NON], (char*)&pRenumbData->ren_INChI2[0][TAUT_NON], sizeof(&pRenumbData->ren_INChI2[0][0]) );
2489
+ swap( (char*)&pINChI[i][TAUT_YES], (char*)&pRenumbData->ren_INChI2[0][TAUT_YES], sizeof(&pRenumbData->ren_INChI2[0][0]) );
2490
+ swap( (char*)&pINChI_Aux[i][TAUT_NON], (char*)&pRenumbData->ren_INChI_Aux[0][TAUT_NON], sizeof(&pRenumbData->ren_INChI_Aux[0][0]) );
2491
+ swap( (char*)&pINChI_Aux[i][TAUT_YES], (char*)&pRenumbData->ren_INChI_Aux[0][TAUT_YES], sizeof(&pRenumbData->ren_INChI_Aux[0][0]) );
2492
+ }
2493
+ #endif
2494
+ }
2495
+
2496
+ for ( k = 0; k < TAUT_NUM; k ++ ) {
2497
+ if ( pRenumbData->ren_INChI2[0][k] ) {
2498
+ Free_INChI(&pRenumbData->ren_INChI2[0][k]);
2499
+ /*
2500
+ inchi_free(pRenumbData->ren_INChI2[0][k]);
2501
+ pRenumbData->ren_INChI2[0][k] = NULL;
2502
+ */
2503
+ }
2504
+ if ( pRenumbData->ren_INChI_Aux[0][k] ) {
2505
+ Free_INChI_Aux(&pRenumbData->ren_INChI_Aux[0][k]);
2506
+ /*
2507
+ inchi_free(pRenumbData->ren_INChI_Aux[0][k]);
2508
+ pRenumbData->ren_INChI_Aux[0][k] = NULL;
2509
+ */
2510
+ }
2511
+ }
2512
+ }
2513
+ /* eliminate overcounting due to multiple renumberings/recalculations */
2514
+ pRenumbData->num_taut = sd->num_taut[iINChI] - pRenumbData->num_taut0;
2515
+ pRenumbData->num_non_taut = sd->num_non_taut[iINChI] - pRenumbData->num_non_taut0;
2516
+ sd->num_taut[iINChI] = pRenumbData->num_taut0;
2517
+ sd->num_non_taut[iINChI] = pRenumbData->num_non_taut0;
2518
+ if ( pRenumbData->num_taut % pRenumbData->nComp || pRenumbData->num_non_taut % pRenumbData->nComp ) {
2519
+ my_fprintf( log_file, "Compare (%d,%d) %d (err=%d) %s structure #%d component %d.%s%s%s%s\n",
2520
+ pRenumbData->num_non_taut % pRenumbData->nComp, pRenumbData->num_taut % pRenumbData->nComp,
2521
+ pRenumbData->nComp, 333, INCHI_NAME, num_inp, i+1, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
2522
+ }
2523
+ #if ( TEST_RENUMB_SWITCH == 1 ) /* { */
2524
+ CopyInpAtomData( inp_norm_data[TAUT_NON], pRenumbData->ren_inp_norm_data[TAUT_NON] );
2525
+ CopyInpAtomData( inp_norm_data[TAUT_YES], pRenumbData->ren_inp_norm_data[TAUT_YES] );
2526
+ /* renumbered input structure */
2527
+ #ifndef INCHI_ANSI_ONLY /* { */
2528
+ if ( /*ip->bDisplayEachComponentINChI &&*/ !pRenumbData->nRet2 ) {
2529
+ int err;
2530
+ err = DisplayStructure( inp_cur_data->at, inp_cur_data->num_at, 0, 0, 0, 0, NULL, NULL,
2531
+ ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
2532
+ sd->bUserQuitComponentDisplay = (err==ESC_KEY);
2533
+ if ( !err ) {
2534
+ my_fprintf( stderr, "Cannot display the structure\n");
2535
+ }
2536
+ }
2537
+ #endif /* } INCHI_ANSI_ONLY */
2538
+ #else /* } TEST_RENUMB_SWITCH { */
2539
+ CopyInpAtomData( inp_cur_data, &pRenumbData->saved_inp_cur_data );
2540
+ #endif /* } TEST_RENUMB_SWITCH */
2541
+ FreeInpAtomData( &pRenumbData->saved_inp_cur_data );
2542
+ FreeInpAtomData( pRenumbData->ren_inp_norm_data[TAUT_NON] );
2543
+ FreeInpAtomData( pRenumbData->ren_inp_norm_data[TAUT_YES] );
2544
+
2545
+ return pRenumbData->nRet2;
2546
+ }
2547
+ #endif /* } TEST_RENUMB_ATOMS */
2548
+
2549
+ /****************************************************************************/
2550
+ int bCheckUnusualValences( ORIG_ATOM_DATA *orig_at_data, int bAddIsoH, char *pStrErrStruct )
2551
+ {
2552
+ int i, val, num_found = 0;
2553
+ char msg[32];
2554
+ int len, num_H;
2555
+ inp_ATOM *at = ( orig_at_data && orig_at_data->num_inp_atoms > 0 )? orig_at_data->at : NULL;
2556
+
2557
+ if ( at ) {
2558
+ for ( i = 0, num_found = 0; i < orig_at_data->num_inp_atoms; i ++ ) {
2559
+ num_H = bAddIsoH? NUMH(at,i) : at[i].num_H;
2560
+ val = detect_unusual_el_valence( at[i].el_number, at[i].charge, at[i].radical,
2561
+ at[i].chem_bonds_valence, num_H, at[i].valence );
2562
+ if ( val ) {
2563
+ num_found ++;
2564
+ /* produce message */
2565
+ AddMOLfileError(pStrErrStruct, "Accepted unusual valence(s):");
2566
+ len = sprintf( msg, "%s", at[i].elname );
2567
+ if ( at[i].charge ) {
2568
+ len += sprintf( msg+len, "%+d", at[i].charge );
2569
+ }
2570
+ if ( at[i].radical ) {
2571
+ len += sprintf( msg + len, ",%s", at[i].radical == RADICAL_SINGLET? "s" :
2572
+ at[i].radical == RADICAL_DOUBLET? "d" :
2573
+ at[i].radical == RADICAL_TRIPLET? "t" : "?" );
2574
+ }
2575
+ len += sprintf( msg + len, "(%d)", val );
2576
+ AddMOLfileError(pStrErrStruct, msg);
2577
+ }
2578
+ }
2579
+ }
2580
+ return num_found;
2581
+ }
2582
+ /***************************************************************************/
2583
+ int PreprocessOneStructure( STRUCT_DATA *sd, INPUT_PARMS *ip, ORIG_ATOM_DATA *orig_inp_data, ORIG_ATOM_DATA *prep_inp_data )
2584
+ {
2585
+ int i;
2586
+ INCHI_MODE bTautFlags = 0;
2587
+ INCHI_MODE bTautFlagsDone = 0;
2588
+ /*************************************************/
2589
+ /* 1. copy orig_inp_data --> prep_inp_data */
2590
+ /*************************************************/
2591
+ if ( 0 > DuplicateOrigAtom( prep_inp_data, orig_inp_data ) ) {
2592
+ AddMOLfileError(sd->pStrErrStruct, "Out of RAM");
2593
+ sd->nStructReadError = 99;
2594
+ sd->nErrorType = _IS_FATAL;
2595
+ goto exit_function;
2596
+ }
2597
+ #if( bRELEASE_VERSION == 0 && (EXTR_HAS_METAL_ATOM & (EXTR_MASK | EXTR_FLAG) ) )
2598
+ if ( bHasMetalAtom( orig_inp_data ) ) {
2599
+ sd->bExtract |= EXTR_HAS_METAL_ATOM;
2600
+ }
2601
+ #endif
2602
+
2603
+ /*************************************************/
2604
+ /* 2. fix odd things in prep_inp_data */
2605
+ /*************************************************/
2606
+
2607
+ if ( 0 < fix_odd_things( prep_inp_data->num_inp_atoms, prep_inp_data->at ) ) {
2608
+ AddMOLfileError(sd->pStrErrStruct, "Charges were rearranged");
2609
+ if ( sd->nErrorType < _IS_WARNING ) {
2610
+ sd->nErrorType = _IS_WARNING;
2611
+ }
2612
+ sd->bTautFlagsDone[INCHI_BAS] |= TG_FLAG_FIX_ODD_THINGS_DONE;
2613
+ }
2614
+ #if( bRELEASE_VERSION == 0 && (EXTR_FLAGS & EXTR_HAS_FEATURE) )
2615
+ if ( bFoundFeature( prep_inp_data->at, prep_inp_data->num_inp_atoms ) ) {
2616
+ sd->bExtract |= EXTR_HAS_FEATURE;
2617
+ }
2618
+ #endif
2619
+
2620
+ /*******************************************************************
2621
+ * Find whether the structure can be disconnected or is a salt
2622
+ *******************************************************************/
2623
+
2624
+
2625
+ /* needs salt disconnection? */
2626
+ if ( ip->bTautFlags & TG_FLAG_DISCONNECT_SALTS ) {
2627
+ prep_inp_data->bDisconnectSalts = (0 < DisconnectSalts( prep_inp_data, 0 ));
2628
+ } else {
2629
+ prep_inp_data->bDisconnectSalts = 0;
2630
+ }
2631
+ /* needs metal disconnection? */
2632
+ if ( ip->bTautFlags & TG_FLAG_DISCONNECT_COORD ) {
2633
+ i = (0 != (ip->bTautFlags & TG_FLAG_CHECK_VALENCE_COORD));
2634
+ bMayDisconnectMetals( prep_inp_data, i, &bTautFlagsDone ); /* changes prep_inp_data->bDisconnectCoord */
2635
+ sd->bTautFlagsDone[INCHI_BAS] |= bTautFlagsDone; /* whether any disconnection has been rejected because of the metal proper valence */
2636
+ #if( bRELEASE_VERSION == 0 )
2637
+ if ( i && (bTautFlagsDone & TG_FLAG_CHECK_VALENCE_COORD_DONE) ) {
2638
+ sd->bExtract |= EXTR_METAL_WAS_NOT_DISCONNECTED;
2639
+ }
2640
+ #endif
2641
+ } else {
2642
+ prep_inp_data->bDisconnectCoord = 0;
2643
+ }
2644
+ orig_inp_data->bDisconnectSalts = prep_inp_data->bDisconnectSalts;
2645
+ orig_inp_data->bDisconnectCoord = prep_inp_data->bDisconnectCoord;
2646
+
2647
+ /*************************************************/
2648
+ /* 3. if( orig_inp_data->bDisconnectSalts ) then */
2649
+ /* -- disconnect salts in prep_inp_data */
2650
+ /*************************************************/
2651
+
2652
+ if ( ( ip->bTautFlags & TG_FLAG_DISCONNECT_SALTS ) && prep_inp_data->bDisconnectSalts &&
2653
+ 0 < (i=DisconnectSalts( prep_inp_data, 1 )) ) {
2654
+ AddMOLfileError(sd->pStrErrStruct, "Salt was disconnected");
2655
+ sd->bTautFlagsDone[INCHI_BAS] |= TG_FLAG_DISCONNECT_SALTS_DONE;
2656
+ if ( sd->nErrorType < _IS_WARNING ) {
2657
+ sd->nErrorType = _IS_WARNING;
2658
+ }
2659
+ if ( i = ReconcileAllCmlBondParities( prep_inp_data->at, prep_inp_data->num_inp_atoms, 0 ) ) {
2660
+ char szErrCode[16];
2661
+ sprintf( szErrCode, "%d", i);
2662
+ AddMOLfileError( sd->pStrErrStruct, "0D Parities Reconciliation failed:" );
2663
+ AddMOLfileError( sd->pStrErrStruct, szErrCode );
2664
+ }
2665
+ #if( bRELEASE_VERSION == 0 )
2666
+ sd->bExtract |= EXTR_SALT_WAS_DISCONNECTED;
2667
+ #endif
2668
+ } else {
2669
+ prep_inp_data->bDisconnectSalts = 0;
2670
+ }
2671
+
2672
+ /***********************************************************/
2673
+ /* mark the (disconnected) components in prep_inp_data */
2674
+ /***********************************************************/
2675
+
2676
+ prep_inp_data->num_components = MarkDisconnectedComponents( prep_inp_data, 0 );
2677
+
2678
+ if ( prep_inp_data->num_components < 0 ) {
2679
+ AddMOLfileError(sd->pStrErrStruct, "Out of RAM");
2680
+ sd->nStructReadError = 99;
2681
+ sd->nErrorType = _IS_FATAL;
2682
+ goto exit_function;
2683
+ }
2684
+
2685
+ /***********************************************************/
2686
+ /* Detect isotopic H on heteroatoms -- necessary condition */
2687
+ /* for global isotopic tautomerism */
2688
+ /***********************************************************/
2689
+
2690
+ if ( i = bNumHeterAtomHasIsotopicH( prep_inp_data->at, prep_inp_data->num_inp_atoms ) ) {
2691
+ if ( i & 1 ) {
2692
+ sd->bTautFlagsDone[INCHI_BAS] |= TG_FLAG_FOUND_ISOTOPIC_H_DONE;
2693
+ }
2694
+ if ( i & 2 ) {
2695
+ sd->bTautFlagsDone[INCHI_BAS] |= TG_FLAG_FOUND_ISOTOPIC_ATOM_DONE;
2696
+ }
2697
+ }
2698
+
2699
+
2700
+ /****************************************************************************/
2701
+ /* 4a. Detect unusual valences */
2702
+ /* should be called before metal disconnection */
2703
+ /****************************************************************************/
2704
+
2705
+
2706
+ if ( bCheckUnusualValences( prep_inp_data, 1, sd->pStrErrStruct ) ) {
2707
+ #if( bRELEASE_VERSION == 0 )
2708
+ sd->bExtract |= EXTR_UNUSUAL_VALENCES;
2709
+ #else
2710
+ ;
2711
+ #endif
2712
+ }
2713
+ /***********************************************************/
2714
+ /* 5. if( orig_inp_data->bDisconnectCoord ) then */
2715
+ /* -- copy prep_inp_data --> prep_inp_data+1 */
2716
+ /* -- disconnect metals in prep_inp_data */
2717
+ /***********************************************************/
2718
+
2719
+ if ( prep_inp_data->bDisconnectCoord ) {
2720
+
2721
+ prep_inp_data->num_components = MarkDisconnectedComponents( prep_inp_data, 0 );
2722
+ if ( prep_inp_data->num_components < 0 ) {
2723
+ AddMOLfileError(sd->pStrErrStruct, "Out of RAM");
2724
+ sd->nStructReadError = 99;
2725
+ sd->nErrorType = _IS_FATAL;
2726
+ goto exit_function;
2727
+ }
2728
+ /* save Reconnected structure in prep_inp_data+1 if requested */
2729
+ if ( 0 != ( ip->bTautFlags & TG_FLAG_RECONNECT_COORD) ) {
2730
+ if ( 0 > DuplicateOrigAtom( prep_inp_data+1, prep_inp_data ) ) {
2731
+ AddMOLfileError(sd->pStrErrStruct, "Out of RAM");
2732
+ sd->nStructReadError = 99;
2733
+ sd->nErrorType = _IS_FATAL;
2734
+ goto exit_function;
2735
+ }
2736
+ sd->bTautFlags[INCHI_REC] = sd->bTautFlags[INCHI_BAS];
2737
+ sd->bTautFlagsDone[INCHI_REC] = sd->bTautFlagsDone[INCHI_BAS];
2738
+ { /* remove "parity undefined in disconnected structure" flag from reconnected structure */
2739
+ int k, m, p;
2740
+ inp_ATOM *at = (prep_inp_data+1)->at;
2741
+ int num_at = (prep_inp_data+1)->num_inp_atoms;
2742
+ for ( k = 0; k < num_at; k ++ ) {
2743
+ for ( m = 0; m < MAX_NUM_STEREO_BONDS && (p=at[k].sb_parity[m]); m ++ ) {
2744
+ at[k].sb_parity[m] &= SB_PARITY_MASK;
2745
+ }
2746
+ }
2747
+ }
2748
+ }
2749
+
2750
+ /* make Disconnected structure in prep_inp_data */
2751
+ i = (0 != ( ip->bTautFlags & TG_FLAG_CHECK_VALENCE_COORD ));
2752
+ /* prep_inp_data->bDisconnectCoord > 1 means add prep_inp_data->bDisconnectCoord-1 explicit H atoms */
2753
+ if ( 0 < (i = DisconnectMetals( prep_inp_data, i, &bTautFlagsDone ) ) ) {
2754
+ AddMOLfileError(sd->pStrErrStruct, "Metal was disconnected");
2755
+ sd->bTautFlagsDone[INCHI_BAS] |= TG_FLAG_DISCONNECT_COORD_DONE;
2756
+ if ( sd->nErrorType < _IS_WARNING ) {
2757
+ sd->nErrorType = _IS_WARNING;
2758
+ }
2759
+ #if( bRELEASE_VERSION == 0 )
2760
+ sd->bExtract |= EXTR_METAL_WAS_DISCONNECTED;
2761
+ #endif
2762
+ /* last parm=1 means find link between unchanged by Metal Disconnection components */
2763
+ prep_inp_data->num_components = MarkDisconnectedComponents( prep_inp_data, 1 );
2764
+ if ( prep_inp_data->num_components < 0 ) {
2765
+ AddMOLfileError(sd->pStrErrStruct, "Out of RAM");
2766
+ sd->nStructReadError = 99;
2767
+ sd->nErrorType = _IS_FATAL;
2768
+ goto exit_function;
2769
+ }
2770
+
2771
+ { /* set parities for the disconnected structure */
2772
+ int k, m, p;
2773
+ inp_ATOM *at = (prep_inp_data)->at;
2774
+ int num_at = (prep_inp_data)->num_inp_atoms;
2775
+ for ( k = 0; k < num_at; k ++ ) {
2776
+ for ( m = 0; m < MAX_NUM_STEREO_BONDS && (p=at[k].sb_parity[m]); m ++ ) {
2777
+ if ( p & SB_PARITY_FLAG ) {
2778
+ at[k].sb_parity[m] = (p >> SB_PARITY_SHFT) & SB_PARITY_MASK;
2779
+ }
2780
+ }
2781
+ }
2782
+ }
2783
+
2784
+ if ( i = ReconcileAllCmlBondParities( prep_inp_data->at, prep_inp_data->num_inp_atoms, 1 ) ) {
2785
+ char szErrCode[16];
2786
+ sprintf( szErrCode, "%d", i);
2787
+ AddMOLfileError( sd->pStrErrStruct, "0D Parities Reconciliation failed:" );
2788
+ AddMOLfileError( sd->pStrErrStruct, szErrCode );
2789
+ }
2790
+
2791
+ #if ( REMOVE_ION_PAIRS_DISC_STRU == 1 )
2792
+ if ( 0 < remove_ion_pairs( prep_inp_data->num_inp_atoms, prep_inp_data->at ) ) {
2793
+ AddMOLfileError(sd->pStrErrStruct, "Charges were rearranged");
2794
+ if ( sd->nErrorType < _IS_WARNING ) {
2795
+ sd->nErrorType = _IS_WARNING;
2796
+ }
2797
+ sd->bTautFlagsDone[INCHI_REC] |= TG_FLAG_FIX_ODD_THINGS_DONE;
2798
+ sd->bTautFlagsDone[INCHI_BAS] |= TG_FLAG_FIX_ODD_THINGS_DONE;
2799
+ }
2800
+ #endif
2801
+
2802
+ /*
2803
+ if prep_inp_data->nOldCompNumber[i] = iINChI+1 > 0 then
2804
+ component #(i+1) in prep_inp_data is identical to component #(iINChI+1) in prep_inp_data+1
2805
+ */
2806
+ } else
2807
+ if ( i < 0 ) {
2808
+ AddMOLfileError(sd->pStrErrStruct, "Cannot disconnect metal error");
2809
+ sd->nStructReadError = i;
2810
+ sd->nErrorType = _IS_ERROR;
2811
+ goto exit_function;
2812
+ }
2813
+ } else
2814
+ { /* remove "disconnected structure parities" from the structure */
2815
+ int k, m, p;
2816
+ inp_ATOM *at = (prep_inp_data)->at;
2817
+ int num_at = (prep_inp_data)->num_inp_atoms;
2818
+ for ( k = 0; k < num_at; k ++ ) {
2819
+ for ( m = 0; m < MAX_NUM_STEREO_BONDS && (p=at[k].sb_parity[m]); m ++ ) {
2820
+ at[k].sb_parity[m] &= SB_PARITY_MASK;
2821
+ }
2822
+ }
2823
+ }
2824
+
2825
+
2826
+ exit_function:
2827
+
2828
+ if ( sd->nErrorType < _IS_ERROR && prep_inp_data ) {
2829
+
2830
+ if ( 0 < post_fix_odd_things( prep_inp_data->num_inp_atoms, prep_inp_data->at ) ) {
2831
+ AddMOLfileError(sd->pStrErrStruct, "Charges were rearranged");
2832
+ if ( sd->nErrorType < _IS_WARNING ) {
2833
+ sd->nErrorType = _IS_WARNING;
2834
+ }
2835
+ sd->bTautFlagsDone[INCHI_BAS] |= TG_FLAG_FIX_ODD_THINGS_DONE;
2836
+ }
2837
+ if ( (sd->bTautFlagsDone[INCHI_BAS] & TG_FLAG_DISCONNECT_COORD_DONE) &&
2838
+ (prep_inp_data+1)->at && (prep_inp_data+1)->num_inp_atoms > 0 ) {
2839
+ if ( 0 < post_fix_odd_things( (prep_inp_data+1)->num_inp_atoms, (prep_inp_data+1)->at ) ) {
2840
+ AddMOLfileError(sd->pStrErrStruct, "Charges were rearranged");
2841
+ if ( sd->nErrorType < _IS_WARNING ) {
2842
+ sd->nErrorType = _IS_WARNING;
2843
+ }
2844
+ sd->bTautFlagsDone[INCHI_REC] |= TG_FLAG_FIX_ODD_THINGS_DONE;
2845
+ sd->bTautFlagsDone[INCHI_BAS] |= TG_FLAG_FIX_ODD_THINGS_DONE;
2846
+ }
2847
+ }
2848
+ }
2849
+
2850
+ sd->bTautFlags[INCHI_BAS] |= bTautFlags; /* TG_FLAG_CHECK_VALENCE_COORD_DONE, TG_FLAG_MOVE_CHARGE_COORD_DONE */
2851
+ sd->bTautFlagsDone[INCHI_BAS] |= bTautFlagsDone; /* TG_FLAG_CHECK_VALENCE_COORD_DONE, TG_FLAG_MOVE_CHARGE_COORD_DONE */
2852
+ return sd->nErrorType;
2853
+ }
2854
+
2855
+ #ifndef INCHI_ANSI_ONLY /* { */
2856
+ /************************************************************************************************/
2857
+ int DisplayTheWholeStructure( STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle, FILE *inp_file, INCHI_FILE *log_file,
2858
+ ORIG_ATOM_DATA *orig_inp_data, int num_inp, int iINChI, int bShowStruct, int bINCHI_LIB_Flag )
2859
+ {
2860
+
2861
+ int bDisplayEqu = 0;
2862
+ #ifndef INCHI_LIB
2863
+ /* Displaying equivalent input structures when disconnection has been done: */
2864
+ /* in case of INCHI_LIB equivalence info is always unknown here and bOriginalReconnected=0 */
2865
+ int bOriginalReconnected = iINChI < 0 && orig_inp_data && orig_inp_data->nEquLabels &&
2866
+ (sd->bTautFlagsDone[INCHI_BAS] & TG_FLAG_DISCONNECT_COORD_DONE) &&
2867
+ (ip->bTautFlags & TG_FLAG_RECONNECT_COORD);
2868
+ const char *lpszType = bOriginalReconnected? " (Reconnected)" :
2869
+ (iINChI < 0 )? "" :
2870
+ (iINChI == INCHI_BAS )? " (Preprocessed)" :
2871
+ (iINChI == INCHI_REC )? " (Reconnected)" : "";
2872
+ int err = 0;
2873
+ /* Display the original structure */
2874
+ bDisplayEqu = bShowStruct && ip->bDisplay &&
2875
+ ip->dp.nEquLabels && 0 < ip->dp.nCurEquLabel && ip->dp.nCurEquLabel <= ip->dp.nNumEquSets;
2876
+ #else
2877
+ if(!DRAWDATA || !DRAWDATA_EXISTS)
2878
+ return 0;
2879
+ #endif
2880
+ #ifndef INCHI_LIBRARY
2881
+ /********************************************************************
2882
+ * Ask the user whether to process the input structure or quit
2883
+ */
2884
+ if ( ip->bDisplay && inp_file != stdin ) {
2885
+ if ( user_quit(bDisplayEqu?"Enter=Display identical components, Esc=Stop ?" : "Enter=Display, Esc=Stop ?", ip->ulDisplTime) ) {
2886
+ sd->bUserQuit = 1;
2887
+ goto exit_function;
2888
+ }
2889
+ }
2890
+ #endif
2891
+ /******************************************************
2892
+ * Display the whole input structure in console app
2893
+ */
2894
+ #ifndef INCHI_LIB
2895
+ if ( bShowStruct && ip->bDisplay ) {
2896
+ if ( bDisplayEqu ) {
2897
+ sprintf( szTitle, " Equ Set %d of %d, Input Structure #%d.%s%s%s%s%s",
2898
+ ip->dp.nCurEquLabel, ip->dp.nNumEquSets,
2899
+ num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), lpszType);
2900
+ } else {
2901
+ sprintf( szTitle, "Input Structure #%d.%s%s%s%s%s", num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), lpszType);
2902
+ }
2903
+ err = DisplayStructure( orig_inp_data->at, orig_inp_data->num_inp_atoms, 0, 0, NULL, 1/*isotopic*/, 0/*taut*/, NULL, NULL,
2904
+ ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
2905
+ sd->bUserQuitComponent = (err==ESC_KEY);
2906
+ if ( !err ) {
2907
+ my_fprintf( stderr, "Cannot display the structure\n");
2908
+ }
2909
+ }
2910
+ if( !bDisplayEqu ) {
2911
+ /* console output progress report */
2912
+ if ( ip->bDisplay && !sd->bUserQuitComponent ) {
2913
+ if ( iINChI == 1 ) {
2914
+ if ( ip->bDisplay )
2915
+ my_fprintf( log_file, "Processing (rec) structure #%d.%s%s%s%s...\n", num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
2916
+ else
2917
+ my_fprintf( stderr, "Processing (rec) structure #%d.%s%s%s%s...\r", num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
2918
+ } else {
2919
+ if ( ip->bDisplay )
2920
+ my_fprintf( log_file, "Processing structure #%d.%s%s%s%s...\n", num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
2921
+ else
2922
+ my_fprintf( stderr, "Processing structure #%d.%s%s%s%s...\r", num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
2923
+ }
2924
+ }
2925
+ }
2926
+ #endif
2927
+
2928
+
2929
+ /******************************************************
2930
+ * Store the whole input structure in GUI application
2931
+ */
2932
+ #ifdef INCHI_LIB
2933
+ if ( ip->bDisplay && bINCHI_LIB_Flag )
2934
+ #else
2935
+ if ( (ip->bDisplay || (ip->bCompareComponents & CMP_COMPONENTS)) && bINCHI_LIB_Flag )
2936
+ #endif
2937
+ {
2938
+ int bBit, k, bReconnected, nComponent, bPreprocessed;
2939
+ for ( bBit = 1, k = 0; k < 8; k ++, bBit <<= 1 ) {
2940
+ /******************************************************************************
2941
+ * bReconnected = k%2 (0 or 1)
2942
+ * nComponent = k/4 (0 or 1)
2943
+ * bPreprocessed = (k/2)%2 (0 or 1)
2944
+ ******************************************************************************/
2945
+ if ( !(bINCHI_LIB_Flag & bBit) ) {
2946
+ continue;
2947
+ }
2948
+ bReconnected = k%2;
2949
+ nComponent = k/4;
2950
+ bPreprocessed = ((k/2)%2);
2951
+
2952
+ sprintf( szTitle, "%s Structure #%d.%s%s%s%s",
2953
+ bPreprocessed? "Preprocessed" : bReconnected? "Reconnected" : "Input",
2954
+ num_inp,
2955
+ SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue));
2956
+
2957
+ #ifdef INCHI_LIB
2958
+ if(DRAWDATA && DRAWDATA_EXISTS)
2959
+ {
2960
+ struct DrawData vDrawData;
2961
+ int nType = bPreprocessed? COMPONENT_ORIGINAL_PREPROCESSED : COMPONENT_ORIGINAL;
2962
+ if ( DRAWDATA_EXISTS( nComponent, bPreprocessed, bReconnected ) ) {
2963
+ sd->nErrorType = _IS_FATAL;
2964
+ sd->nErrorCode = CT_UNKNOWN_ERR;
2965
+ return -1;
2966
+ }
2967
+ vDrawData.pWindowData = CreateWinData_( orig_inp_data->at, orig_inp_data->num_inp_atoms,
2968
+ 0, 0, NULL, 1, 0, NULL, NULL,
2969
+ ip->bAbcNumbers, &ip->dp, ip->nMode );
2970
+ if( vDrawData.pWindowData != NULL )
2971
+ {
2972
+ vDrawData.nComponent = nComponent;
2973
+ vDrawData.nType = nType; /* COMPONENT_ORIGINAL or COMPONENT_ORIGINAL_PREPROCESSED */
2974
+ vDrawData.bReconnected = bReconnected; /* 0=>main; 1=>reconnected */
2975
+ vDrawData.pWindowData->szTitle = _strdup(szTitle);
2976
+ vDrawData.szTitle = _strdup(szTitle);
2977
+ DRAWDATA(&vDrawData);
2978
+ if ( !nComponent ) {
2979
+ /* keep track of saved INCHI_LIB data */
2980
+ orig_inp_data->bSavedInINCHI_LIB[bReconnected] ++;
2981
+ orig_inp_data->bPreprocessed[bReconnected] = bPreprocessed;
2982
+ }
2983
+ }
2984
+ }
2985
+ #else
2986
+ if ( !nComponent ) {
2987
+ /* keep track of saved INCHI_LIB data */
2988
+ orig_inp_data->bSavedInINCHI_LIB[bReconnected] ++;
2989
+ orig_inp_data->bPreprocessed[bReconnected] = bPreprocessed;
2990
+ }
2991
+ #endif
2992
+
2993
+ }
2994
+ }
2995
+
2996
+ exit_function:
2997
+ return sd->bUserQuit;
2998
+ }
2999
+ #endif /* } INCHI_ANSI_ONLY */
3000
+ /************************************************************************************************/
3001
+ int ProcessOneStructure( STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle,
3002
+ PINChI2 *pINChI[INCHI_NUM], PINChI_Aux2 *pINChI_Aux[INCHI_NUM],
3003
+ FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
3004
+ ORIG_ATOM_DATA *orig_inp_data, ORIG_ATOM_DATA *prep_inp_data,
3005
+ int num_inp, char *pStr, int nStrLen )
3006
+ {
3007
+ int nRet = 0, nRet1, i, k, maxINChI=0;
3008
+ COMP_ATOM_DATA composite_norm_data[INCHI_NUM][TAUT_NUM+1]; /* [0]:non-taut, [1]:taut, [2]:intermediate taut struct */
3009
+ NORM_CANON_FLAGS ncFlags;
3010
+ NORM_CANON_FLAGS *pncFlags = &ncFlags;
3011
+ ORIG_STRUCT OrigStruct;
3012
+ ORIG_STRUCT *pOrigStruct = NULL;
3013
+ int bSortPrintINChIFlags = 0;
3014
+
3015
+ sd->bUserQuitComponent = 0;
3016
+ sd->bUserQuitComponentDisplay = 0;
3017
+ memset( composite_norm_data, 0, sizeof(composite_norm_data) );
3018
+ memset( pncFlags, 0, sizeof(*pncFlags) );
3019
+ /* ip->msec_LeftTime = ip->msec_MaxTime; */ /* start timeout countdown */
3020
+
3021
+ /* for testing only */
3022
+ #if( REMOVE_ION_PAIRS_ORIG_STRU == 1 )
3023
+ fix_odd_things( orig_inp_data->num_inp_atoms, orig_inp_data->at );
3024
+ #endif
3025
+
3026
+ /***** output MOLfile ***************/
3027
+ if ( ip->bINChIOutputOptions & INCHI_OUT_SDFILE_ONLY ) {
3028
+ char szNumber[32];
3029
+ #if ( !defined( INCHI_LIB ) && !defined( INCHI_LIBRARY ) )
3030
+ #if( TEST_RENUMB_ATOMS != 1 )
3031
+ /* log file / console output */
3032
+ if ( log_file != stderr ) {
3033
+ if ( ip->bDisplay )
3034
+ my_fprintf( log_file, "Writing structure #%d.%s%s%s%s...\n", num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
3035
+ else
3036
+ my_fprintf( stderr, "Writing structure #%d.%s%s%s%s...\r", num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
3037
+ }
3038
+ #endif
3039
+ #endif
3040
+ sprintf( szNumber, "Structure #%d", num_inp );
3041
+ WriteOrigAtomDataToSDfile( orig_inp_data, output_file, szNumber, NULL,
3042
+ (sd->bChiralFlag & FLAG_INP_AT_CHIRAL)? 1:0, ip->pSdfLabel, ip->pSdfValue );
3043
+ goto exit_function;
3044
+ }
3045
+
3046
+ /******* create full reversibility information **************/
3047
+ if ( !(ip->bINChIOutputOptions & (INCHI_OUT_NO_AUX_INFO | INCHI_OUT_SHORT_AUX_INFO)) ) {
3048
+ pOrigStruct = &OrigStruct;
3049
+ memset( pOrigStruct, 0, sizeof(*pOrigStruct));
3050
+ if ( FillOutOrigStruct( orig_inp_data, pOrigStruct, sd ) ) {
3051
+ AddMOLfileError(sd->pStrErrStruct, "Cannot interpret reversibility information");
3052
+ sd->nStructReadError = 99;
3053
+ sd->nErrorType = _IS_ERROR;
3054
+ nRet = _IS_ERROR;
3055
+ }
3056
+ }
3057
+ /* create INChI for each connected component of the structure and optionally display them */
3058
+ /* create INChI for the whole disconnected or original structure */
3059
+ if ( nRet != _IS_FATAL && nRet != _IS_ERROR ) {
3060
+ nRet1 = CreateOneStructureINChI( sd, ip, szTitle, pINChI, pINChI_Aux, INCHI_BAS,
3061
+ inp_file, log_file, output_file, prb_file,
3062
+ orig_inp_data, prep_inp_data, composite_norm_data,
3063
+ num_inp, pStr, nStrLen, pncFlags );
3064
+ nRet = inchi_max(nRet, nRet1);
3065
+ }
3066
+ if ( nRet != _IS_FATAL && nRet != _IS_ERROR ) {
3067
+ maxINChI = 1;
3068
+ }
3069
+
3070
+
3071
+ if ( nRet != _IS_FATAL && nRet != _IS_ERROR &&
3072
+ (sd->bTautFlagsDone[INCHI_BAS] & TG_FLAG_DISCONNECT_COORD_DONE) &&
3073
+ (ip->bTautFlags & TG_FLAG_RECONNECT_COORD) ) {
3074
+
3075
+ /* create INChI for the whole reconnected structure */
3076
+ nRet1 = CreateOneStructureINChI( sd, ip, szTitle, pINChI, pINChI_Aux, INCHI_REC,
3077
+ inp_file, log_file, output_file, prb_file,
3078
+ orig_inp_data, prep_inp_data, composite_norm_data,
3079
+ num_inp, pStr, nStrLen, pncFlags );
3080
+ nRet = inchi_max(nRet, nRet1);
3081
+ if ( nRet != _IS_FATAL && nRet != _IS_ERROR ) {
3082
+ maxINChI = 2;
3083
+ }
3084
+ }
3085
+
3086
+
3087
+ if ( nRet != _IS_FATAL && nRet != _IS_ERROR ) {
3088
+
3089
+ if ( (sd->bChiralFlag & FLAG_INP_AT_CHIRAL) &&
3090
+ (ip->nMode & REQ_MODE_STEREO) &&
3091
+ !(ip->nMode & (REQ_MODE_RELATIVE_STEREO | REQ_MODE_RACEMIC_STEREO)) &&
3092
+ !bIsStructChiral( pINChI, sd->num_components ) ) {
3093
+
3094
+ AddMOLfileError(sd->pStrErrStruct, "Not chiral");
3095
+ }
3096
+ /*************************************/
3097
+ /* Output err/warn messages */
3098
+ /*************************************/
3099
+ if ( /*!sd->nErrorCode &&*/ !sd->bUserQuitComponent && !sd->bUserQuit ) {
3100
+ /* if successful then returns 0, otherwise returns _IS_FATAL */
3101
+ /* exctract the structure if requested */
3102
+ nRet1 = TreatCreateINChIWarning(sd, ip, prep_inp_data, num_inp,
3103
+ inp_file, log_file, output_file, prb_file,pStr, nStrLen );
3104
+ nRet = inchi_max(nRet, nRet1);
3105
+ }
3106
+ }
3107
+
3108
+
3109
+ /************************************************/
3110
+ /* sort and print INChI for the whole structure */
3111
+ /************************************************/
3112
+
3113
+
3114
+ if ( nRet != _IS_FATAL && nRet != _IS_ERROR ) {
3115
+
3116
+ nRet1 = SortAndPrintINChI( output_file, pStr, nStrLen, log_file, ip, orig_inp_data, prep_inp_data,
3117
+ composite_norm_data, pOrigStruct,
3118
+ sd->num_components, sd->num_non_taut, sd->num_taut,
3119
+ sd->bTautFlags, sd->bTautFlagsDone, pncFlags, num_inp,
3120
+ pINChI, pINChI_Aux, &bSortPrintINChIFlags );
3121
+ nRet = inchi_max(nRet, nRet1);
3122
+ }
3123
+ #ifndef INCHI_ANSI_ONLY /* { */
3124
+
3125
+ /* display equivalent components on original or preprocessed structure(s) */
3126
+
3127
+ #ifndef INCHI_LIB
3128
+
3129
+ if ( nRet != _IS_FATAL && nRet != _IS_ERROR && /*ip->bDisplay &&*/
3130
+ (ip->bCompareComponents & CMP_COMPONENTS) && !sd->bUserQuit && !sd->bUserQuitComponent ) {
3131
+ int j, ret, ord;
3132
+ int bDisplaySaved = ip->bDisplay;
3133
+ ORIG_ATOM_DATA *inp_data;
3134
+ AT_NUMB nEquSet;
3135
+ for ( ord = -1; ord < INCHI_NUM; ord ++ ) {
3136
+ switch( ord ) {
3137
+ case -1:
3138
+ j = INCHI_BAS; /* preprocessed non-tautomeric */
3139
+ break;
3140
+ case 0:
3141
+ j = INCHI_REC; /* preprocessed tautomeric */
3142
+ break;
3143
+ case 1:
3144
+ j = -1; /* original input */
3145
+ break;
3146
+ default:
3147
+ continue;
3148
+ }
3149
+ inp_data = j < 0? orig_inp_data : prep_inp_data+j;
3150
+ if ( inp_data && inp_data->num_inp_atoms && inp_data->at &&
3151
+ inp_data->nEquLabels &&
3152
+ inp_data->nNumEquSets ) {
3153
+ for ( nEquSet = 1; nEquSet <= inp_data->nNumEquSets; nEquSet ++ ) {
3154
+ ip->dp.nEquLabels = inp_data->nEquLabels;
3155
+ ip->dp.nCurEquLabel = nEquSet;
3156
+ ip->dp.nNumEquSets = inp_data->nNumEquSets;
3157
+ ip->bDisplay = 1; /* force display if it was not requested */
3158
+ ret = DisplayTheWholeStructure( sd, ip, szTitle, inp_file, log_file, inp_data, num_inp,
3159
+ j, 1 /*bShowStructure*/, 0 );
3160
+ ip->dp.nEquLabels = NULL;
3161
+ ip->dp.nCurEquLabel = 0;
3162
+ ip->dp.nNumEquSets = 0;
3163
+ ip->bDisplay = bDisplaySaved; /* restore display option */
3164
+ if ( ret ) {
3165
+ /* user pressed Esc */
3166
+ goto exit_loop;
3167
+ }
3168
+ }
3169
+ }
3170
+ }
3171
+ exit_loop:;
3172
+ }
3173
+
3174
+ #endif
3175
+
3176
+
3177
+
3178
+ /* display composite results and equivalent components on composite results */
3179
+ if ( nRet != _IS_FATAL && nRet != _IS_ERROR && /*ip->bDisplay &&*/
3180
+ ip->bDisplayCompositeResults ) {
3181
+ int iINChI;
3182
+ for ( iINChI = 0; iINChI < maxINChI && !sd->bUserQuitComponentDisplay; iINChI ++ ) {
3183
+ DisplayTheWholeCompositeStructure( ip, sd, num_inp, iINChI,
3184
+ pINChI[iINChI], pINChI_Aux[iINChI],
3185
+ orig_inp_data, prep_inp_data,
3186
+ composite_norm_data[iINChI] );
3187
+ }
3188
+ #ifndef INCHI_LIB
3189
+ if( !ip->bDisplay && sd->bUserQuitComponentDisplay ) {
3190
+ sd->bUserQuit = 1;
3191
+ }
3192
+ #endif
3193
+ }
3194
+
3195
+ #endif /* } INCHI_ANSI_ONLY */
3196
+
3197
+
3198
+ /* XML struct end tag */
3199
+ if ( (ip->bINChIOutputOptions & INCHI_OUT_XML) && sd->bXmlStructStarted > 0 ) {
3200
+ if ( !OutputINChIXmlStructEndTag( output_file, pStr, nStrLen, 1 ) ) {
3201
+ my_fprintf( log_file, "Cannot create end xml tag for structure #%d.%s%s%s%s Terminating.\n", num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
3202
+ sd->bXmlStructStarted = -1; /* do not repeat same message */
3203
+ nRet = _IS_FATAL;
3204
+ } else {
3205
+ sd->bXmlStructStarted = 0; /* do not continue xml output for this structure */
3206
+ }
3207
+ }
3208
+ if ( nRet != _IS_FATAL && nRet != _IS_ERROR ) {
3209
+ /* Special mode: extract all good MOLfiles into the problem file
3210
+ * Do not extract any MOLfile that could not be processed (option /PGO)
3211
+ */
3212
+ if ( prb_file && 0L <= sd->fPtrStart && sd->fPtrStart < sd->fPtrEnd && ip->bSaveAllGoodStructsAsProblem ) {
3213
+ CopyMOLfile(inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file, 0);
3214
+ }
3215
+ #if( /*bRELEASE_VERSION != 1 &&*/ EXTR_FLAGS == EXTR_TRANSPOSITION_EXAMPLES && EXTR_MASK == EXTR_FLAGS )
3216
+ else
3217
+ if ( prb_file && (bSortPrintINChIFlags &
3218
+ ( FLAG_SORT_PRINT_TRANSPOS_BAS | FLAG_SORT_PRINT_TRANSPOS_REC ) )
3219
+ ) {
3220
+ CopyMOLfile(inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file, 0);
3221
+ }
3222
+ #endif
3223
+ }
3224
+ for ( i = 0; i < INCHI_NUM; i ++ ) {
3225
+ for ( k = 0; k < TAUT_NUM+1; k ++ ) {
3226
+ FreeCompAtomData( &composite_norm_data[i][k] );
3227
+ }
3228
+ }
3229
+ FreeOrigStruct( pOrigStruct);
3230
+
3231
+
3232
+ /*
3233
+ FreeInpAtomData( inp_cur_data );
3234
+ FreeInpAtomData( inp_norm_data[0] );
3235
+ FreeInpAtomData( inp_norm_data[1] );
3236
+ */
3237
+ exit_function:
3238
+
3239
+ return nRet;
3240
+ }
3241
+ /************************************************************************************************/
3242
+ int bIsStructChiral( PINChI2 *pINChI2[INCHI_NUM], int num_components[] )
3243
+ {
3244
+ int i, j, k;
3245
+ INChI *pINChI;
3246
+ INChI_Stereo *Stereo;
3247
+ for ( j = 0; j < INCHI_NUM; j ++ ) { /* disconnected / reconnected */
3248
+ if ( !num_components[j] ) {
3249
+ continue;
3250
+ }
3251
+ for ( i = 0; i < num_components[j]; i ++ ) { /* component */
3252
+ for ( k = 0; k < TAUT_NUM; k ++ ) { /* mobile/immobile H */
3253
+ if ( (pINChI = pINChI2[j][i][k]) &&
3254
+ !pINChI->bDeleted &&
3255
+ pINChI->nNumberOfAtoms > 0 ) {
3256
+
3257
+ if ( (Stereo = pINChI->Stereo) &&
3258
+ Stereo->t_parity &&
3259
+ Stereo->nNumberOfStereoCenters > 0 &&
3260
+ Stereo->nCompInv2Abs ) {
3261
+ return 1; /* inversion changed stereo */
3262
+ }
3263
+ if ( (Stereo = pINChI->StereoIsotopic) &&
3264
+ Stereo->t_parity &&
3265
+ Stereo->nNumberOfStereoCenters > 0 &&
3266
+ Stereo->nCompInv2Abs ) {
3267
+ return 1; /* inversion changed stereo */
3268
+ }
3269
+ }
3270
+ }
3271
+ }
3272
+ }
3273
+ return 0;
3274
+ }
3275
+ /************************************************************************************************/
3276
+ int CreateOneStructureINChI( STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle,
3277
+ PINChI2 *pINChI2[INCHI_NUM], PINChI_Aux2 *pINChI_Aux2[INCHI_NUM], int iINChI,
3278
+ FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
3279
+ ORIG_ATOM_DATA *orig_inp_data, ORIG_ATOM_DATA *prep_inp_data,
3280
+ COMP_ATOM_DATA composite_norm_data2[][TAUT_NUM+1],
3281
+ int num_inp, char *pStr, int nStrLen, NORM_CANON_FLAGS *pncFlags )
3282
+ {
3283
+ int i, j, k, /*m,*/ nRet = 0;
3284
+ #ifndef INCHI_LIB
3285
+ int n;
3286
+ #ifndef INCHI_ANSI_ONLY
3287
+ int err;
3288
+ #endif
3289
+ #endif
3290
+
3291
+ PINChI2 *pINChI = NULL;
3292
+ PINChI_Aux2 *pINChI_Aux = NULL;
3293
+
3294
+ INP_ATOM_DATA InpCurAtData;
3295
+ INP_ATOM_DATA *inp_cur_data;
3296
+
3297
+ INP_ATOM_DATA InpNormAtData, InpNormTautData;
3298
+ INP_ATOM_DATA *inp_norm_data[TAUT_NUM]; /* = { &InpNormAtData, &InpNormTautData }; */
3299
+ ORIG_ATOM_DATA *cur_prep_inp_data = prep_inp_data + iINChI;
3300
+ inchiTime ulTStart;
3301
+ #ifndef INCHI_ANSI_ONLY
3302
+ int bShowStructure = 0;
3303
+ int bStructurePreprocessed = 0; /* All changes except disconnection */
3304
+ int bStructureDisconnected = 0;
3305
+ int bAlsoOutputReconnected = 0, bINCHI_LIB_Flag = 0;
3306
+ COMP_ATOM_DATA *composite_norm_data = composite_norm_data2[iINChI];
3307
+ INP_ATOM_DATA2 *all_inp_norm_data = NULL;
3308
+ #endif
3309
+
3310
+ /*
3311
+ if ( orig_inp_data is NOT empty AND
3312
+ prep_inp_data[0] IS empty ) then:
3313
+
3314
+ 1. copy orig_inp_data --> prep_inp_data[0]
3315
+ 2. fix odd things in prep_inp_data[0]
3316
+ 3. if( orig_inp_data->bDisconnectSalts ) then
3317
+ -- disconnect salts in prep_inp_data[0]
3318
+ 4. move protons to neutralize charges on heteroatoms
3319
+ 5. if( orig_inp_data->bDisconnectCoord ) then
3320
+ -- copy prep_inp_data[0] --> prep_inp_data[1]
3321
+ -- disconnect metals in prep_inp_data[0]
3322
+
3323
+ [ This all is done in PreprocessOneStructure() ]
3324
+
3325
+ iINChI = 0
3326
+ =========
3327
+ (normal/disconnected layer)
3328
+
3329
+ 1. normalize prep_inp_data[0] in inp_norm_data[0,1]
3330
+ 2. create INChI[ iINChI ] out of inp_norm_data[0,1]
3331
+
3332
+
3333
+ iINChI = 1 AND orig_inp_data->bDisconnectCoord > 0
3334
+ =================================================
3335
+ (reconnected layer)
3336
+
3337
+ 1. normalize prep_inp_data[1] in inp_norm_data[0,1]
3338
+ 2. create INChI[ iINChI ] out of inp_norm_data[0,1]
3339
+
3340
+ */
3341
+
3342
+ #if( TEST_RENUMB_ATOMS == 1 )
3343
+ RENUMB_DATA RenumbData;
3344
+ RENUMB_DATA *pRenumbData = &RenumbData;
3345
+ #endif
3346
+
3347
+
3348
+ ip->msec_LeftTime = ip->msec_MaxTime; /* start timeout countdown for each component */
3349
+
3350
+ #if( TEST_RENUMB_ATOMS == 1 )
3351
+ memset( pRenumbData, 0, sizeof(*pRenumbData) );
3352
+ #endif
3353
+
3354
+ inp_cur_data = &InpCurAtData;
3355
+ inp_norm_data[TAUT_NON] = &InpNormAtData;
3356
+ inp_norm_data[TAUT_YES] = &InpNormTautData;
3357
+
3358
+ memset( inp_cur_data , 0, sizeof( *inp_cur_data ) );
3359
+ memset( inp_norm_data[TAUT_NON], 0, sizeof( *inp_norm_data[0] ) );
3360
+ memset( inp_norm_data[TAUT_YES], 0, sizeof( *inp_norm_data[0] ) );
3361
+
3362
+ #ifndef INCHI_ANSI_ONLY
3363
+ memset( composite_norm_data+TAUT_NON, 0, sizeof( composite_norm_data[0] ) );
3364
+ memset( composite_norm_data+TAUT_YES, 0, sizeof( composite_norm_data[0] ) );
3365
+ memset( composite_norm_data+TAUT_INI, 0, sizeof( composite_norm_data[0] ) );
3366
+ #endif
3367
+ if ( ip->bAllowEmptyStructure && !orig_inp_data->at && !orig_inp_data->num_inp_atoms ) {
3368
+ ;
3369
+ } else
3370
+ if ( !orig_inp_data->at || !orig_inp_data->num_inp_atoms ) {
3371
+ return 0; /* nothing to do */
3372
+ }
3373
+ if ( iINChI == 1 && orig_inp_data->bDisconnectCoord <= 0 ) {
3374
+ return 0;
3375
+ }
3376
+
3377
+ /* m = iINChI; */ /* orig_inp_data index */
3378
+
3379
+ if ( iINChI != INCHI_BAS && iINChI != INCHI_REC ) {
3380
+ AddMOLfileError(sd->pStrErrStruct, "Fatal undetermined program error");
3381
+ sd->nStructReadError = 97;
3382
+ nRet = sd->nErrorType = _IS_FATAL;
3383
+ goto exit_function;
3384
+ }
3385
+
3386
+ /*******************************************************************
3387
+ * *
3388
+ * *
3389
+ * Whole structure preprocessing: 1st step of the normalization *
3390
+ * *
3391
+ * Happen only on the first call to CreateOneStructureINChI() *
3392
+ * *
3393
+ * *
3394
+ *******************************************************************/
3395
+
3396
+ if ( (!prep_inp_data->at || !prep_inp_data->num_inp_atoms) && orig_inp_data->num_inp_atoms > 0 ) {
3397
+ /* the structure has not been preprocessed */
3398
+ if ( ip->msec_MaxTime ) {
3399
+ InchiTimeGet( &ulTStart );
3400
+ }
3401
+ PreprocessOneStructure( sd, ip, orig_inp_data, prep_inp_data );
3402
+ pncFlags->bTautFlags[iINChI][TAUT_YES] =
3403
+ pncFlags->bTautFlags[iINChI][TAUT_NON] = sd->bTautFlags[INCHI_BAS] | ip->bTautFlags;
3404
+ pncFlags->bTautFlagsDone[iINChI][TAUT_YES] =
3405
+ pncFlags->bTautFlagsDone[iINChI][TAUT_NON] = sd->bTautFlagsDone[INCHI_BAS] | ip->bTautFlagsDone;
3406
+
3407
+ #ifndef INCHI_ANSI_ONLY
3408
+ /* in this location the call happens once for each input structure, before preprocessing */
3409
+ bStructurePreprocessed = (0 != (sd->bTautFlagsDone[INCHI_BAS] & (
3410
+ TG_FLAG_MOVE_HPLUS2NEUTR_DONE |
3411
+ TG_FLAG_DISCONNECT_SALTS_DONE |
3412
+ TG_FLAG_MOVE_POS_CHARGES_DONE |
3413
+ TG_FLAG_FIX_ODD_THINGS_DONE )));
3414
+ bStructureDisconnected = (0 != (sd->bTautFlagsDone[INCHI_BAS] & TG_FLAG_DISCONNECT_COORD_DONE));
3415
+
3416
+ bShowStructure = ( bStructurePreprocessed ||
3417
+ bStructureDisconnected ||
3418
+ prep_inp_data[0].num_components > 1);
3419
+
3420
+ /* sd->bTautFlags[] contains output flags
3421
+ ip->bTautFlags contains input flags
3422
+ */
3423
+ bAlsoOutputReconnected = (sd->bTautFlagsDone[INCHI_BAS] & TG_FLAG_DISCONNECT_COORD_DONE) &&
3424
+ (ip->bTautFlags & TG_FLAG_RECONNECT_COORD);
3425
+ bINCHI_LIB_Flag = 0;
3426
+
3427
+ /*************** output structures to INCHI_LIB conditions *********************
3428
+ *
3429
+ * Send to INCHI_LIB:
3430
+ *
3431
+ * type component conditions
3432
+ *
3433
+ * COMPONENT_ORIGINAL #0: (num_components > 1)
3434
+ * COMPONENT_ORIGINAL_PREPROCESSED #0: (num_components > 1) && (preprocessed)
3435
+ * COMPONENT_ORIGINAL #1: (num_components = 1) && (preprocessed)
3436
+ *
3437
+ * Flags explanation:
3438
+ * MAIN => iINChI=0, RECN => iINChI=1 (Reconnected)
3439
+ * ORIG => Original, PREP => Preprocessed
3440
+ *
3441
+ * Possible flags: k
3442
+ *
3443
+ * COMP_ORIG_0_MAIN 0x0001 0 COMPONENT_ORIGINAL, bMain, component #0
3444
+ * COMP_ORIG_0_RECN 0x0002 1 COMPONENT_ORIGINAL, bRecn, component #0
3445
+ *
3446
+ * COMP_PREP_0_MAIN 0x0004 2 COMPONENT_ORIGINAL_PREPROCESSED, bMain, component #0
3447
+ * COMP_PREP_0_RECN 0x0008 3 COMPONENT_ORIGINAL_PREPROCESSED, bRecn, component #0
3448
+ *
3449
+ * COMP_ORIG_1_MAIN 0x0010 4 COMPONENT_ORIGINAL, bMain, component #1
3450
+ * COMP_ORIG_1_RECN 0x0020 5 COMPONENT_ORIGINAL, bRecn, component #1
3451
+ *
3452
+ * bReconnected = k%2 (0 or 1)
3453
+ * nComponent = k/4 (0 or 1)
3454
+ * bPreprocessed = (k/2)%2 (0 or 1)
3455
+ *
3456
+ ******************************************************************************/
3457
+ /* Original -> Main, component #0, Original */
3458
+ if ( prep_inp_data[INCHI_BAS].num_components > 1 ) {
3459
+ bINCHI_LIB_Flag |= COMP_ORIG_0_MAIN;
3460
+ } else
3461
+ /* Original -> Main, component #1, Original */
3462
+ if ( prep_inp_data[INCHI_BAS].num_components == 1 && bStructurePreprocessed ) {
3463
+ bINCHI_LIB_Flag |= COMP_ORIG_1_MAIN;
3464
+ /* preprocessed will be added when output canonicalization results */
3465
+ }
3466
+ if ( bAlsoOutputReconnected ) {
3467
+ /* Original -> Reconnected, component #0, Original */
3468
+ if ( prep_inp_data[INCHI_REC].num_components > 1 ) {
3469
+ bINCHI_LIB_Flag |= COMP_ORIG_0_RECN;
3470
+ } else
3471
+ /* Original -> Reconnected, component #1, Original */
3472
+ if ( prep_inp_data[INCHI_BAS].num_components == 1 && bStructurePreprocessed ) {
3473
+ bINCHI_LIB_Flag |= COMP_ORIG_1_RECN;
3474
+ /* preprocessed will be added when output canonicalization results */
3475
+ }
3476
+ }
3477
+ if ( ip->msec_MaxTime ) {
3478
+ ip->msec_LeftTime -= InchiTimeElapsed( &ulTStart );
3479
+ }
3480
+
3481
+ /* display the ORIGINAL, UN-PREPROCESSED structure */
3482
+ if ( DisplayTheWholeStructure( sd, ip, szTitle, inp_file, log_file, orig_inp_data, num_inp,
3483
+ -1, bShowStructure, bINCHI_LIB_Flag ) ) {
3484
+ goto exit_function;
3485
+ }
3486
+ #endif
3487
+ switch (sd->nErrorType) {
3488
+ case _IS_ERROR:
3489
+ case _IS_FATAL:
3490
+ /* error message */
3491
+ nRet = TreatReadTheStructureErrors( sd, ip, LOG_MASK_ALL, inp_file, log_file, output_file, prb_file,
3492
+ prep_inp_data, &num_inp, pStr, nStrLen );
3493
+ goto exit_cycle;
3494
+ }
3495
+ }
3496
+ /* tranfer flags from INChI_Aux to sd */
3497
+
3498
+
3499
+
3500
+
3501
+
3502
+ #ifndef INCHI_ANSI_ONLY /* { */
3503
+
3504
+ /******************************************/
3505
+ /* Displaying the structures */
3506
+ /* Only under WIN32 */
3507
+ /******************************************/
3508
+ if ( ip->bDisplayCompositeResults &&
3509
+ !sd->bUserQuitComponentDisplay && prep_inp_data[iINChI].num_components > 1) {
3510
+ all_inp_norm_data = (INP_ATOM_DATA2 *)inchi_calloc( prep_inp_data[iINChI].num_components, sizeof(all_inp_norm_data[0]));
3511
+ }
3512
+
3513
+
3514
+ /* Display the input structure AFTER PREPROCESSING */
3515
+ switch ( iINChI ) {
3516
+
3517
+ case INCHI_BAS:
3518
+ /*------------ Possibly disconnected structure -------------------*/
3519
+ bStructurePreprocessed = 0 != (sd->bTautFlagsDone[iINChI] & (
3520
+ TG_FLAG_MOVE_HPLUS2NEUTR_DONE |
3521
+ TG_FLAG_DISCONNECT_SALTS_DONE |
3522
+ TG_FLAG_MOVE_POS_CHARGES_DONE |
3523
+ TG_FLAG_MOVE_CHARGE_COORD_DONE |
3524
+ TG_FLAG_DISCONNECT_COORD_DONE |
3525
+ TG_FLAG_FIX_ODD_THINGS_DONE ));
3526
+ bINCHI_LIB_Flag = 0;
3527
+
3528
+ /* Preprocessed/Main -> Main, component #0, Preprocessed */
3529
+ if ( prep_inp_data[iINChI].num_components > 1 && bStructurePreprocessed ) {
3530
+ bINCHI_LIB_Flag |= COMP_PREP_0_MAIN;
3531
+ }
3532
+
3533
+ bShowStructure = ( bStructurePreprocessed && prep_inp_data[iINChI].num_components > 1);
3534
+ break;
3535
+
3536
+ case INCHI_REC:
3537
+ /*------------ Reconnected structure ------------------------------*/
3538
+ bAlsoOutputReconnected = (sd->bTautFlagsDone[INCHI_BAS] & TG_FLAG_DISCONNECT_COORD_DONE) &&
3539
+ (ip->bTautFlags & TG_FLAG_RECONNECT_COORD);
3540
+ if ( !bAlsoOutputReconnected ) {
3541
+ break;
3542
+ }
3543
+ bStructurePreprocessed = 0 != (sd->bTautFlagsDone[iINChI] & (
3544
+ TG_FLAG_MOVE_HPLUS2NEUTR_DONE |
3545
+ TG_FLAG_DISCONNECT_SALTS_DONE |
3546
+ TG_FLAG_MOVE_POS_CHARGES_DONE |
3547
+ TG_FLAG_FIX_ODD_THINGS_DONE ));
3548
+ bINCHI_LIB_Flag = 0;
3549
+
3550
+ /* Preprocessed/Reconnected -> Reconnected, component #0, Preprocessed */
3551
+ if ( prep_inp_data[iINChI].num_components > 1 && bStructurePreprocessed ) {
3552
+ bINCHI_LIB_Flag |= COMP_PREP_0_RECN;
3553
+ }
3554
+
3555
+ bShowStructure = ( bStructurePreprocessed && prep_inp_data[iINChI].num_components > 1 );
3556
+ break;
3557
+ default:
3558
+ bShowStructure = 0;
3559
+ }
3560
+ if ( prep_inp_data[iINChI].num_inp_atoms > 0 ) {
3561
+ if ( DisplayTheWholeStructure( sd, ip, szTitle, inp_file, log_file, prep_inp_data+iINChI, num_inp,
3562
+ iINChI, bShowStructure, bINCHI_LIB_Flag ) ) {
3563
+ goto exit_function;
3564
+ }
3565
+ }
3566
+ #endif /* } ifndef INCHI_ANSI_ONLY */
3567
+
3568
+
3569
+
3570
+ /* allocate pINChI[iINChI] and pINChI_Aux2[iINChI] -- arrays of pointers to INChI and INChI_Aux */
3571
+ /* assign values to sd->num_components[] */
3572
+ MYREALLOC2(PINChI2, PINChI_Aux2, pINChI2[iINChI], pINChI_Aux2[iINChI], sd->num_components[iINChI], cur_prep_inp_data->num_components, k);
3573
+ if ( k ) {
3574
+ AddMOLfileError(sd->pStrErrStruct, "Cannot allocate output data. Terminating");
3575
+ sd->nStructReadError = 99;
3576
+ sd->nErrorType = _IS_FATAL;
3577
+ goto exit_function;
3578
+ }
3579
+ pINChI = pINChI2[iINChI];
3580
+ pINChI_Aux = pINChI_Aux2[iINChI];
3581
+
3582
+ /**************************************************************************/
3583
+ /* */
3584
+ /* */
3585
+ /* M A I N C Y C L E: P R O C E S S C O M P O N E N T S */
3586
+ /* */
3587
+ /* */
3588
+ /* O N E B Y O N E */
3589
+ /* */
3590
+ /* */
3591
+ /**************************************************************************/
3592
+
3593
+ for ( i = 0, nRet = 0; !sd->bUserQuitComponent && i < cur_prep_inp_data->num_components; i ++ ) {
3594
+ if ( ip->msec_MaxTime ) {
3595
+ InchiTimeGet( &ulTStart );
3596
+ }
3597
+ #ifndef INCHI_LIB /* { */
3598
+ #if( bREUSE_INCHI == 1 )
3599
+ if ( iINChI == INCHI_REC && (!ip->bDisplay && !(ip->bCompareComponents & CMP_COMPONENTS) ||
3600
+ sd->bUserQuitComponentDisplay) ) {
3601
+ /* reconnected structure */
3602
+ int m = iINChI-1;
3603
+ /* find whether we have already calculated this INChI in basic (disconnected) layer */
3604
+ for ( j = n = 0; j < prep_inp_data[m].num_components; j ++ ) {
3605
+ if ( i+1 == prep_inp_data[m].nOldCompNumber[j] &&
3606
+ (pINChI2[m][j][TAUT_NON] || pINChI2[m][j][TAUT_YES]) ) {
3607
+ /* yes, we have already done this */
3608
+ if ( !n++ ) {
3609
+ memcpy( pINChI +i, pINChI2 [m]+j, sizeof(pINChI[0]));
3610
+ memcpy( pINChI_Aux+i, pINChI_Aux2[m]+j, sizeof(pINChI_Aux[0]));
3611
+ for ( k = 0; k < TAUT_NUM; k ++ ) {
3612
+ if ( pINChI[i][k] ) {
3613
+ pINChI[i][k]->nRefCount ++;
3614
+ if ( pINChI[i][k]->nNumberOfAtoms > 0 ) {
3615
+ switch( k ) {
3616
+ case TAUT_NON:
3617
+ sd->num_non_taut[iINChI] ++;
3618
+ break;
3619
+ case TAUT_YES:
3620
+ if ( pINChI[i][k]->lenTautomer > 0 ) {
3621
+ sd->num_taut[iINChI] ++;
3622
+ } else
3623
+ if ( !pINChI[i][TAUT_NON] || !pINChI[i][TAUT_NON]->nNumberOfAtoms ) {
3624
+ sd->num_non_taut[iINChI] ++;
3625
+ }
3626
+ break;
3627
+ }
3628
+ }
3629
+ }
3630
+ if ( pINChI_Aux[i][k] ) {
3631
+ pINChI_Aux[i][k]->nRefCount ++;
3632
+ }
3633
+ }
3634
+ }
3635
+ }
3636
+ }
3637
+ if ( n == 1 ) {
3638
+ continue;
3639
+ }
3640
+ if ( n > 1 ) { /* ith component is equivalent to more than one another component */
3641
+ AddMOLfileError(sd->pStrErrStruct, "Cannot distinguish components");
3642
+ sd->nStructReadError = 99;
3643
+ sd->nErrorType = _IS_ERROR;
3644
+ goto exit_function;
3645
+ }
3646
+ }
3647
+ #endif
3648
+ #endif /* } INCHI_LIB */
3649
+
3650
+ /*****************************************************/
3651
+ /* a) allocate memory and extract current component */
3652
+ /*****************************************************/
3653
+ nRet = GetOneComponent( sd, ip, log_file, output_file, inp_cur_data, cur_prep_inp_data, i, num_inp, pStr, nStrLen );
3654
+ if ( ip->msec_MaxTime ) {
3655
+ ip->msec_LeftTime -= InchiTimeElapsed( &ulTStart );
3656
+ }
3657
+ switch ( nRet ) {
3658
+ case _IS_ERROR:
3659
+ case _IS_FATAL:
3660
+ goto exit_cycle;
3661
+ }
3662
+ #ifndef INCHI_LIBRARY
3663
+ /* console request: Display the component? */
3664
+ if ( ip->bDisplay && inp_file != stdin ) {
3665
+ if ( user_quit("Enter=Display Component, Esc=Stop ?", ip->ulDisplTime) ) {
3666
+ sd->bUserQuitComponent = 1;
3667
+ break;
3668
+ }
3669
+ }
3670
+ #endif
3671
+ #ifndef INCHI_ANSI_ONLY /* { */
3672
+ /* b) Display the extracted original component structure */
3673
+ if ( inp_cur_data->at && ip->bDisplay && !sd->bUserQuitComponentDisplay ) {
3674
+ if ( cur_prep_inp_data->num_components == 1 ) {
3675
+ sprintf( szTitle, "%sInput Structure #%d.%s%s%s%s%s",
3676
+ bStructurePreprocessed? "Preprocessed ":"",
3677
+ num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), iINChI? " (Reconnected)":"");
3678
+ } else {
3679
+ sprintf( szTitle, "Component #%d of %d, Input Structure #%d.%s%s%s%s%s",
3680
+ i+1, cur_prep_inp_data->num_components,
3681
+ num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), iINChI? " (Reconnected)":"");
3682
+ }
3683
+ #ifndef INCHI_LIB
3684
+ err = DisplayStructure( inp_cur_data->at, inp_cur_data->num_at,
3685
+ 0, 0, NULL, 1/*isotopic*/, 0/*taut*/, NULL, NULL,
3686
+ ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
3687
+ sd->bUserQuitComponentDisplay = (err==ESC_KEY);
3688
+ if ( !err ) {
3689
+ my_fprintf( stderr, "Cannot display the structure\n");
3690
+ }
3691
+ #else
3692
+ if(DRAWDATA && DRAWDATA_EXISTS)
3693
+ {
3694
+ struct DrawData vDrawData;
3695
+ int nType = COMPONENT_ORIGINAL;
3696
+ vDrawData.pWindowData = CreateWinData_( inp_cur_data->at, inp_cur_data->num_at,
3697
+ 0, 0, NULL,
3698
+ 1 /* display isotopic if present */, 0, NULL, NULL,
3699
+ ip->bAbcNumbers, &ip->dp, ip->nMode );
3700
+ if( vDrawData.pWindowData != NULL )
3701
+ {
3702
+ if ( DRAWDATA_EXISTS ( i+1, nType, iINChI ) ) { /* i = component number */
3703
+ nType = COMPONENT_ORIGINAL_PREPROCESSED;
3704
+ }
3705
+ vDrawData.nComponent = i+1;
3706
+ vDrawData.nType = nType;
3707
+ vDrawData.bReconnected = iINChI; /* 0=>main; 1=>reconnected */
3708
+ vDrawData.szTitle = _strdup(szTitle);
3709
+ vDrawData.pWindowData->szTitle = _strdup(szTitle);
3710
+ DRAWDATA(&vDrawData);
3711
+ }
3712
+ }
3713
+ #endif
3714
+ }
3715
+ #endif /* } INCHI_ANSI_ONLY */
3716
+
3717
+ #if( TEST_RENUMB_ATOMS == 1 ) /* { */
3718
+ /****************************************************************************/
3719
+ /* R E N U M B E R I N G (testing only) Part I STARTS here */
3720
+ /****************************************************************************/
3721
+ RenumberingTestInit( pRenumbData, inp_cur_data );
3722
+ if ( log_file != stderr ) {
3723
+ if ( ip->bDisplay )
3724
+ my_fprintf( log_file, "Component #%d structure #%d.%s%s%s%s...\n", i+1, num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
3725
+ else
3726
+ my_fprintf( stderr, "Component #%d structure #%d.%s%s%s%s...\r", i+1, num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
3727
+ }
3728
+ /****************************************************************************/
3729
+ /* R E N U M B E R I N G (testing only) Part I ENDS here */
3730
+ /****************************************************************************/
3731
+ #endif /* } TEST_RENUMB_ATOMS */
3732
+
3733
+
3734
+ /*******************************************************************************/
3735
+ /* */
3736
+ /* N O R M A L I Z A T I O N a n d C A N O N I C A L I Z A T I O N */
3737
+ /* */
3738
+ /* (both tautomeric and non-tautomeric if requested) */
3739
+ /* */
3740
+ /*******************************************************************************/
3741
+ /* c) Create the component's INChI ( copies ip->bTautFlags into sd->bTautFlags)*/
3742
+ /*******************************************************************************/
3743
+ nRet = CreateOneComponentINChI( sd, ip, inp_cur_data, orig_inp_data, pINChI/*2[iINChI]*/, pINChI_Aux/*2[iINChI]*/, iINChI,
3744
+ i, num_inp, inp_norm_data, pncFlags, log_file );
3745
+
3746
+
3747
+ #if( TEST_RENUMB_ATOMS == 1 ) /* { */
3748
+ /****************************************************************************/
3749
+ /* R E N U M B E R I N G (testing only) Part II STARTS here */
3750
+ /****************************************************************************/
3751
+ if ( !nRet ) {
3752
+ nRet = RenumberingTest( pINChI/*2[iINChI]*/, pINChI_Aux/*2[iINChI]*/, orig_inp_data, iINChI, pRenumbData, inp_cur_data, inp_norm_data, sd, ip, szTitle, log_file, prb_file, i, num_inp, pncFlags);
3753
+ }
3754
+ RenumberingTestUninit( pRenumbData );
3755
+ /****************************************************************************/
3756
+ /* R E N U M B E R I N G (testing only) Part II ENDS here */
3757
+ /****************************************************************************/
3758
+ #endif /* } TEST_RENUMB_ATOMS */
3759
+
3760
+
3761
+ /* d) Display one component structure and/or INChI results only if there was no error */
3762
+ #ifndef INCHI_ANSI_ONLY /* { */
3763
+ if ( !nRet ) {
3764
+ /* output one component INChI to the stdout if requested */
3765
+ /*
3766
+ if ( ip->bDisplayEachComponentINChI ) {
3767
+ int cur_num_non_taut = (pINChI[i][TAUT_NON] && pINChI[i][TAUT_NON]->nNumberOfAtoms>0);
3768
+ int cur_num_taut = (pINChI[i][TAUT_YES] && pINChI[i][TAUT_YES]->nNumberOfAtoms>0);
3769
+ if ( ip->bDisplayEachComponentINChI && cur_num_non_taut + cur_num_taut ) {
3770
+ SortAndPrintINChI( stdout, pStr, nStrLen, NULL, ip, 1, cur_num_non_taut, cur_num_taut,
3771
+ num_inp, pINChI+i, pINChI_Aux+i );
3772
+ }
3773
+ }
3774
+ */
3775
+ /**************************************************************************
3776
+ * display from one up to 4 structure pictures-results for each component *
3777
+ * Enable buttons: *
3778
+ * BN (non-tautomeric non-isotopic): inp_norm_data[0]->bExists *
3779
+ * TN (tautomeric non-isotopic): inp_norm_data[1]->bExists *
3780
+ * BI (non-tautomeric isotopic): inp_norm_data[0]->bExists && *
3781
+ * inp_norm_data[0]->bHasIsotopicLayer *
3782
+ * TI (tautomeric isotopic): inp_norm_data[1]->bExists && *
3783
+ * inp_norm_data[1]->bHasIsotopicLayer *
3784
+ **************************************************************************/
3785
+ int bIsotopic, bTautomeric, bDisplayTaut, bHasIsotopicLayer, bFixedBondsTaut, m_max, m, nNumDisplayedFixedBondTaut=0;
3786
+ for ( j = 0; ip->bDisplay && !sd->bUserQuitComponentDisplay && j < TAUT_NUM; j ++ ) {
3787
+ if ( inp_norm_data[j]->bExists && !inp_norm_data[j]->bDeleted ) {
3788
+ bTautomeric = (pINChI[i][j]->lenTautomer > 0); /* same as (inp_norm_data[j]->bTautomeric > 0) */
3789
+ /* if requested tautomeric and no tautmerism found then do not say mobile or fixed H. 2004-10-27 */
3790
+ bDisplayTaut = (!(ip->nMode & REQ_MODE_BASIC) && !bTautomeric)? -1 : bTautomeric;
3791
+ bHasIsotopicLayer = (inp_norm_data[j]->bHasIsotopicLayer > 0);
3792
+ for ( k = 0; k <= bHasIsotopicLayer; k ++ ) {
3793
+ bIsotopic = (k > 0);
3794
+ m_max = inp_norm_data[j]->at_fixed_bonds && inp_norm_data[j]->bTautPreprocessed? 1 : 0;
3795
+ for ( m = m_max; 0 <= m; m -- ) {
3796
+ bFixedBondsTaut = (m>0);
3797
+ nNumDisplayedFixedBondTaut += bFixedBondsTaut; /* display only one time */
3798
+ /* added number of components, added another format for a single component case - DCh */
3799
+ if ( cur_prep_inp_data->num_components > 1 ) {
3800
+ sprintf( szTitle, "%s Component #%d of %d, Structure #%d%s%s.%s%s%s%s%s",
3801
+ bFixedBondsTaut? "Preprocessed":"Result for",
3802
+ i+1, cur_prep_inp_data->num_components, num_inp,
3803
+ bDisplayTaut==1? ", mobile H": bDisplayTaut==0?", fixed H":"",
3804
+ bIsotopic? ", isotopic":"",
3805
+ SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), iINChI? " (Reconnected)":"");
3806
+ } else {
3807
+ sprintf( szTitle, "%s Structure #%d%s%s.%s%s%s%s%s",
3808
+ bFixedBondsTaut? "Preprocessed":"Result for",
3809
+ num_inp,
3810
+ bDisplayTaut==1? ", mobile H": bDisplayTaut==0?", fixed H":"",
3811
+ bIsotopic? ", isotopic":"",
3812
+ SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), iINChI? " (Reconnected)":"");
3813
+ }
3814
+ #ifndef INCHI_LIB
3815
+ if ( bFixedBondsTaut && nNumDisplayedFixedBondTaut != 1 )
3816
+ continue;
3817
+ if ( bFixedBondsTaut ) {
3818
+ err = DisplayStructure( inp_norm_data[j]->at_fixed_bonds, inp_norm_data[j]->num_at,
3819
+ inp_norm_data[j]->num_removed_H,
3820
+ inp_norm_data[j]->nNumRemovedProtons,
3821
+ inp_norm_data[j]->nNumRemovedProtonsIsotopic,
3822
+ bHasIsotopicLayer, j, NULL, NULL,
3823
+ ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
3824
+ } else {
3825
+ err = DisplayStructure( inp_norm_data[j]->at, inp_norm_data[j]->num_at,
3826
+ 0, 0, NULL,
3827
+ k, j, pINChI[i], pINChI_Aux[i],
3828
+ ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
3829
+ }
3830
+ if ( sd->bUserQuitComponentDisplay = (err==ESC_KEY) ) {
3831
+ break;
3832
+ }
3833
+ #else
3834
+ if(DRAWDATA && !bFixedBondsTaut)
3835
+ {
3836
+ struct DrawData vDrawData;
3837
+ vDrawData.pWindowData = CreateWinData_( inp_norm_data[j]->at, inp_norm_data[j]->num_at,
3838
+ 0, 0, NULL,
3839
+ k, j, pINChI[i], pINChI_Aux[i],
3840
+ ip->bAbcNumbers, &ip->dp, ip->nMode );
3841
+ if( vDrawData.pWindowData != NULL )
3842
+ {
3843
+ int nType;
3844
+ vDrawData.nComponent = i+1;
3845
+ if( bTautomeric == 0 )
3846
+ nType = (bIsotopic == 0) ? COMPONENT_BN: COMPONENT_BI;
3847
+ else
3848
+ nType = (bIsotopic == 0) ? COMPONENT_TN: COMPONENT_TI;
3849
+ vDrawData.nType = nType;
3850
+ vDrawData.bReconnected = iINChI; /* 0=>main; 1=>reconnected */
3851
+ vDrawData.szTitle = _strdup(szTitle);
3852
+ vDrawData.pWindowData->szTitle = _strdup(szTitle);
3853
+ DRAWDATA(&vDrawData);
3854
+ }
3855
+ } else
3856
+ if(DRAWDATA && bFixedBondsTaut)
3857
+ {
3858
+ struct DrawData vDrawData;
3859
+ if ( (ip->bCompareComponents & CMP_COMPONENTS) &&
3860
+ !(ip->bCompareComponents & CMP_COMPONENTS_NONTAUT) &&
3861
+ !bIsotopic == !inp_norm_data[j]->bHasIsotopicLayer ) {
3862
+
3863
+ vDrawData.pWindowData =
3864
+ CreateWinData_( inp_norm_data[j]->at_fixed_bonds, inp_norm_data[j]->num_at,
3865
+ inp_norm_data[j]->num_removed_H,
3866
+ inp_norm_data[j]->nNumRemovedProtons,
3867
+ inp_norm_data[j]->nNumRemovedProtonsIsotopic,
3868
+ k, j, NULL, NULL,
3869
+ ip->bAbcNumbers, &ip->dp, ip->nMode );
3870
+ } else {
3871
+ continue;
3872
+ }
3873
+ if( vDrawData.pWindowData != NULL )
3874
+ {
3875
+ vDrawData.nComponent = i+1;
3876
+ vDrawData.nType = COMPONENT_ORIGINAL_PREPROCESSED;
3877
+ vDrawData.bReconnected = iINChI; /* 0=>main; 1=>reconnected */
3878
+ vDrawData.szTitle = _strdup(szTitle);
3879
+ vDrawData.pWindowData->szTitle = _strdup(szTitle);
3880
+ DRAWDATA(&vDrawData);
3881
+ }
3882
+ }
3883
+ #endif
3884
+ }
3885
+ }
3886
+ }
3887
+ }
3888
+
3889
+ /* save normalized components for composite display */
3890
+ if ( ip->bDisplayCompositeResults && all_inp_norm_data ) {
3891
+ for ( j = 0; j < TAUT_NUM; j ++ ) {
3892
+ if ( inp_norm_data[j]->bExists ) {
3893
+ all_inp_norm_data[i][j] = *inp_norm_data[j];
3894
+ memset( inp_norm_data[j], 0, sizeof(*inp_norm_data[0]) );
3895
+ }
3896
+ }
3897
+ }
3898
+
3899
+ }
3900
+ #endif /* } INCHI_ANSI_ONLY */
3901
+ if ( nRet ) {
3902
+ nRet = TreatCreateOneComponentINChIError(sd, ip, cur_prep_inp_data, i, num_inp,
3903
+ inp_file, log_file, output_file, prb_file,pStr, nStrLen );
3904
+
3905
+ break;
3906
+ }
3907
+ }
3908
+ /**************************************************************************/
3909
+ /* */
3910
+ /* */
3911
+ /* E N D O F T H E M A I N C Y C L E P R O C E S S I N G */
3912
+ /* */
3913
+ /* C O M P O N E N T S O N E B Y O N E */
3914
+ /* */
3915
+ /* */
3916
+ /**************************************************************************/
3917
+
3918
+
3919
+ exit_cycle:
3920
+
3921
+ #if( TEST_RENUMB_ATOMS == 1 ) /* { */
3922
+ if ( pRenumbData->bRenumbErr && (!nRet || nRet==_IS_WARNING) ) {
3923
+ sd->nErrorCode = pRenumbData->bRenumbErr;
3924
+ nRet = TreatCreateOneComponentINChIError(sd, ip, cur_prep_inp_data, -1, num_inp,
3925
+ inp_file, log_file, output_file, prb_file,pStr, nStrLen );
3926
+ /* nRet = _IS_ERROR; */
3927
+ sd->nErrorCode = 0;
3928
+ nRet = 0;
3929
+ }
3930
+ #endif /* } TEST_RENUMB_ATOMS */
3931
+ switch ( nRet ) {
3932
+
3933
+ case _IS_FATAL:
3934
+ case _IS_ERROR:
3935
+ break;
3936
+
3937
+ default:
3938
+
3939
+ #ifndef INCHI_ANSI_ONLY /* { */
3940
+ /* composite results picture(s) */
3941
+ if ( all_inp_norm_data ) {
3942
+ int res = CreateCompositeNormAtom( composite_norm_data, all_inp_norm_data, pINChI, pINChI_Aux,
3943
+ prep_inp_data[iINChI].num_components, ip->nMode );
3944
+ /*
3945
+ for ( i = 0; i < prep_inp_data[iINChI].num_components; i ++ ) {
3946
+ for ( k = 0; k < TAUT_NUM; k ++ ) {
3947
+ FreeInpAtomData( &all_inp_norm_data[i][k] );
3948
+ }
3949
+ }
3950
+ inchi_free( all_inp_norm_data );
3951
+ all_inp_norm_data = NULL;
3952
+ */
3953
+ }
3954
+ #endif /* } INCHI_ANSI_ONLY */
3955
+
3956
+ break;
3957
+ }
3958
+
3959
+
3960
+ #ifndef INCHI_ANSI_ONLY /* { */
3961
+ /* avoid memory leaks in case of error */
3962
+ if ( all_inp_norm_data ) {
3963
+ for ( i = 0; i < prep_inp_data[iINChI].num_components; i ++ ) {
3964
+ for ( k = 0; k < TAUT_NUM; k ++ ) {
3965
+ FreeInpAtomData( &all_inp_norm_data[i][k] );
3966
+ }
3967
+ }
3968
+ inchi_free( all_inp_norm_data );
3969
+ all_inp_norm_data = NULL;
3970
+ }
3971
+ #endif /* } INCHI_ANSI_ONLY */
3972
+
3973
+
3974
+ FreeInpAtomData( inp_cur_data );
3975
+ for ( i = 0; i < TAUT_NUM; i ++ ) {
3976
+ FreeInpAtomData( inp_norm_data[i] );
3977
+ }
3978
+
3979
+
3980
+ exit_function:
3981
+
3982
+ return nRet;
3983
+ }
3984
+
3985
+
3986
+
3987
+ #ifndef INCHI_ANSI_ONLY /* { */
3988
+ /****************************************************************************/
3989
+ int CreateCompositeNormAtom( COMP_ATOM_DATA *composite_norm_data, INP_ATOM_DATA2 *all_inp_norm_data,
3990
+ PINChI2 *pINChI, PINChI_Aux2 *pINChI_Aux, int num_components, INCHI_MODE nMode )
3991
+ {
3992
+ int i, j, jj, k, n, m, tot_num_at, tot_num_H, cur_num_at, cur_num_H, nNumRemovedProtons;
3993
+ int num_comp[TAUT_NUM+1], num_taut[TAUT_NUM+1], num_del[TAUT_NUM+1], num_at[TAUT_NUM+1], num_inp_at[TAUT_NUM+1];
3994
+ int ret = 0, indicator = 1;
3995
+ inp_ATOM *at, *at_from;
3996
+ memset( num_comp, 0, sizeof(num_comp) );
3997
+ memset( num_taut, 0, sizeof(num_taut) );
3998
+ memset( num_del, 0, sizeof(num_taut) );
3999
+ /* count taut and non-taut components */
4000
+ for ( j = 0; j < TAUT_NUM; j ++ ) {
4001
+ num_comp[j] = num_taut[j] = 0;
4002
+ for ( i = 0; i < num_components; i ++ ) {
4003
+ if ( all_inp_norm_data[i][j].bExists ) {
4004
+ num_del[j] += (0 != all_inp_norm_data[i][j].bDeleted );
4005
+ num_comp[j] ++;
4006
+ num_taut[j] += (0 != all_inp_norm_data[i][j].bTautomeric);
4007
+ }
4008
+ }
4009
+ }
4010
+ /* count intermediate taut structure components */
4011
+ if ( num_comp[TAUT_YES] > num_del[TAUT_YES] && num_taut[TAUT_YES] ) {
4012
+ /*
4013
+ num_comp[TAUT_INI] = num_comp[TAUT_YES] - num_del[TAUT_YES];
4014
+ */
4015
+
4016
+ for ( i = 0, j=TAUT_YES; i < num_components; i ++ ) {
4017
+ if ( all_inp_norm_data[i][j].bExists &&
4018
+ (all_inp_norm_data[i][j].bDeleted ||
4019
+ all_inp_norm_data[i][j].bTautomeric &&
4020
+ all_inp_norm_data[i][j].at_fixed_bonds &&
4021
+ all_inp_norm_data[i][j].bTautPreprocessed) ) {
4022
+ num_comp[TAUT_INI] ++;
4023
+ }
4024
+ }
4025
+
4026
+ }
4027
+ /* count atoms and allocate composite atom data */
4028
+ for ( jj = 0; jj <= TAUT_INI; jj ++ ) {
4029
+ num_at[jj] = num_inp_at[jj] = 0;
4030
+ j = inchi_min (jj, TAUT_YES);
4031
+ if ( num_comp[jj] ) {
4032
+ for ( i = 0; i < num_components; i ++ ) {
4033
+ if ( all_inp_norm_data[i][j].bDeleted )
4034
+ continue;
4035
+ /* find k = the normaized structure index */
4036
+ if ( jj == TAUT_INI ) {
4037
+ if ( all_inp_norm_data[i][j].bExists &&
4038
+ all_inp_norm_data[i][j].at_fixed_bonds ) {
4039
+ k = j;
4040
+ } else
4041
+ if ( all_inp_norm_data[i][ALT_TAUT(j)].bExists && !all_inp_norm_data[i][ALT_TAUT(j)].bDeleted &&
4042
+ !all_inp_norm_data[i][j].bDeleted ) {
4043
+ k = ALT_TAUT(j);
4044
+ } else
4045
+ if ( all_inp_norm_data[i][j].bExists ) {
4046
+ k = j;
4047
+ } else {
4048
+ continue;
4049
+ }
4050
+ } else {
4051
+ if ( all_inp_norm_data[i][j].bExists ) {
4052
+ k = j;
4053
+ } else
4054
+ if ( all_inp_norm_data[i][ALT_TAUT(j)].bExists && !all_inp_norm_data[i][ALT_TAUT(j)].bDeleted) {
4055
+ k = ALT_TAUT(j);
4056
+ } else {
4057
+ continue;
4058
+ }
4059
+ }
4060
+ num_inp_at[jj] += all_inp_norm_data[i][k].num_at; /* all atoms including terminal H */
4061
+ num_at[jj] += all_inp_norm_data[i][k].num_at - all_inp_norm_data[i][k].num_removed_H;
4062
+ }
4063
+ if ( num_inp_at[jj] ) {
4064
+ if ( !CreateCompAtomData( composite_norm_data+jj, num_inp_at[jj], num_components, jj == TAUT_INI ) )
4065
+ goto exit_error;
4066
+ composite_norm_data[jj].num_removed_H = num_inp_at[jj] - num_at[jj];
4067
+ }
4068
+ }
4069
+ }
4070
+ /* fill out composite atom */
4071
+ for ( jj = 0; jj <= TAUT_INI; jj ++, indicator <<= 1 ) {
4072
+ j = inchi_min (jj, TAUT_YES);
4073
+ if ( num_comp[jj] ) {
4074
+ tot_num_at = 0;
4075
+ tot_num_H = 0;
4076
+ for ( i = 0; i < num_components; i ++ ) {
4077
+ if ( all_inp_norm_data[i][j].bDeleted ) {
4078
+ composite_norm_data[jj].nNumRemovedProtons += all_inp_norm_data[i][j].nNumRemovedProtons;
4079
+ for ( n = 0; n < NUM_H_ISOTOPES; n ++ ) {
4080
+ composite_norm_data[jj].nNumRemovedProtonsIsotopic[n] += all_inp_norm_data[i][j].nNumRemovedProtonsIsotopic[n];
4081
+ }
4082
+ continue;
4083
+ }
4084
+ nNumRemovedProtons = 0;
4085
+ k = TAUT_NUM;
4086
+ /* find k = the normaized structure index */
4087
+ if ( jj == TAUT_INI ) {
4088
+ if ( all_inp_norm_data[i][j].bExists && all_inp_norm_data[i][j].at_fixed_bonds ) {
4089
+ k = j;
4090
+ } else
4091
+ if ( all_inp_norm_data[i][ALT_TAUT(j)].bExists ) {
4092
+ k = ALT_TAUT(j);
4093
+ } else
4094
+ if ( all_inp_norm_data[i][j].bExists && !all_inp_norm_data[i][ALT_TAUT(j)].bDeleted ) {
4095
+ k = j;
4096
+ } else {
4097
+ continue;
4098
+ }
4099
+ } else {
4100
+ if ( all_inp_norm_data[i][j].bExists ) {
4101
+ k = j;
4102
+ } else
4103
+ if ( all_inp_norm_data[i][ALT_TAUT(j)].bExists && !all_inp_norm_data[i][ALT_TAUT(j)].bDeleted ) {
4104
+ k = ALT_TAUT(j);
4105
+ } else {
4106
+ continue;
4107
+ }
4108
+ }
4109
+ /* copy main atoms */
4110
+ cur_num_H = all_inp_norm_data[i][k].num_removed_H; /* number of terminal H atoms */
4111
+ cur_num_at = all_inp_norm_data[i][k].num_at - cur_num_H; /* number of all but explicit terminal H atoms */
4112
+
4113
+ if ( (tot_num_at + cur_num_at) > num_at[jj] ||
4114
+ (num_at[jj] + tot_num_H + cur_num_H) > num_inp_at[jj] ) {
4115
+ goto exit_error; /* miscount */
4116
+ }
4117
+ at = composite_norm_data[jj].at+tot_num_at; /* points to the 1st destination atom */
4118
+ at_from = (jj == TAUT_INI && k == TAUT_YES && all_inp_norm_data[i][k].at_fixed_bonds)?
4119
+ all_inp_norm_data[i][k].at_fixed_bonds : all_inp_norm_data[i][k].at;
4120
+ memcpy( at, at_from, sizeof(composite_norm_data[0].at[0]) * cur_num_at ); /* copy atoms except terminal H */
4121
+ /* shift neighbors of main atoms */
4122
+ for ( n = 0; n < cur_num_at; n ++, at ++ ) {
4123
+ for ( m = 0; m < at->valence; m ++ ) {
4124
+ at->neighbor[m] += tot_num_at;
4125
+ }
4126
+ }
4127
+ /* copy explicit H */
4128
+ if ( cur_num_H ) {
4129
+ at = composite_norm_data[jj].at+num_at[jj]+tot_num_H; /* points to the 1st destination atom */
4130
+ memcpy( at, at_from+cur_num_at,
4131
+ sizeof(composite_norm_data[0].at[0]) * cur_num_H );
4132
+ /* shift neighbors of explicit H atoms */
4133
+ for ( n = 0; n < cur_num_H; n ++, at ++ ) {
4134
+ for ( m = 0; m < at->valence; m ++ ) {
4135
+ at->neighbor[m] += tot_num_at;
4136
+ }
4137
+ }
4138
+ }
4139
+ /* composite counts */
4140
+ composite_norm_data[jj].bHasIsotopicLayer |= all_inp_norm_data[i][k].bHasIsotopicLayer;
4141
+ composite_norm_data[jj].num_isotopic += all_inp_norm_data[i][k].num_isotopic;
4142
+ composite_norm_data[jj].num_bonds += all_inp_norm_data[i][k].num_bonds;
4143
+ composite_norm_data[jj].bTautomeric += (j == jj) && all_inp_norm_data[i][k].bTautomeric;
4144
+ composite_norm_data[jj].nNumRemovedProtons += all_inp_norm_data[i][k].nNumRemovedProtons;
4145
+ for ( n = 0; n < NUM_H_ISOTOPES; n ++ ) {
4146
+ composite_norm_data[jj].nNumRemovedProtonsIsotopic[n] += all_inp_norm_data[i][k].nNumRemovedProtonsIsotopic[n];
4147
+ composite_norm_data[jj].num_iso_H[n] += all_inp_norm_data[i][k].num_iso_H[n];
4148
+ }
4149
+ /*
4150
+ composite_norm_data[j].num_at += cur_num_at + cur_num_H;
4151
+ composite_norm_data[j].num_removed_H += cur_num_H;
4152
+ */
4153
+ /* total count */
4154
+ tot_num_at += cur_num_at;
4155
+ tot_num_H += cur_num_H;
4156
+ /* offset for the next component */
4157
+ if ( composite_norm_data[jj].nOffsetAtAndH ) {
4158
+ composite_norm_data[jj].nOffsetAtAndH[2*i] = tot_num_at;
4159
+ composite_norm_data[jj].nOffsetAtAndH[2*i+1] = num_at[jj]+tot_num_H;
4160
+ }
4161
+ }
4162
+ if ( tot_num_at != num_at[jj] ||
4163
+ num_at[jj] + tot_num_H != num_inp_at[jj] ) {
4164
+ goto exit_error; /* miscount */
4165
+ }
4166
+ composite_norm_data[jj].bExists = (tot_num_at>0);
4167
+ ret |= indicator;
4168
+ }
4169
+ }
4170
+ return ret;
4171
+
4172
+
4173
+
4174
+
4175
+
4176
+ exit_error:
4177
+ return ret;
4178
+ }
4179
+ #endif /* } INCHI_ANSI_ONLY */