rino 0.1.0

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