rino 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. data/Rakefile +1 -1
  2. data/ext/extconf.rb +1 -24
  3. data/ext/libinchi.so +0 -0
  4. data/ext/src/aux2atom.h +120 -39
  5. data/ext/src/comdef.h +3 -3
  6. data/ext/src/dispstru.c +2547 -0
  7. data/ext/src/dispstru.h +73 -0
  8. data/ext/src/extr_ct.h +5 -2
  9. data/ext/src/ichi.h +27 -11
  10. data/ext/src/ichi_bns.c +1800 -254
  11. data/ext/src/ichi_bns.h +205 -4
  12. data/ext/src/ichican2.c +197 -86
  13. data/ext/src/ichicano.c +8 -13
  14. data/ext/src/ichicano.h +2 -2
  15. data/ext/src/ichicans.c +11 -6
  16. data/ext/src/ichicant.h +2 -2
  17. data/ext/src/ichicomn.h +2 -2
  18. data/ext/src/ichicomp.h +19 -4
  19. data/ext/src/ichidrp.h +9 -5
  20. data/ext/src/ichierr.h +5 -3
  21. data/ext/src/ichiisot.c +2 -2
  22. data/ext/src/ichimain.c +461 -0
  23. data/ext/src/ichimain.h +23 -15
  24. data/ext/src/ichimak2.c +6 -6
  25. data/ext/src/ichimake.c +843 -42
  26. data/ext/src/ichimake.h +4 -2
  27. data/ext/src/ichimap1.c +5 -5
  28. data/ext/src/ichimap2.c +2 -2
  29. data/ext/src/ichimap4.c +34 -21
  30. data/ext/src/ichinorm.c +11 -5
  31. data/ext/src/ichinorm.h +3 -2
  32. data/ext/src/ichiparm.c +2 -2
  33. data/ext/src/ichiparm.h +232 -30
  34. data/ext/src/ichiprt1.c +35 -11
  35. data/ext/src/ichiprt2.c +78 -7
  36. data/ext/src/ichiprt3.c +300 -120
  37. data/ext/src/ichiqueu.c +17 -2
  38. data/ext/src/ichiread.c +6932 -0
  39. data/ext/src/ichiring.c +3 -2
  40. data/ext/src/ichiring.h +2 -2
  41. data/ext/src/ichirvr1.c +4891 -0
  42. data/ext/src/ichirvr2.c +6344 -0
  43. data/ext/src/ichirvr3.c +5499 -0
  44. data/ext/src/ichirvr4.c +3177 -0
  45. data/ext/src/ichirvr5.c +1166 -0
  46. data/ext/src/ichirvr6.c +1287 -0
  47. data/ext/src/ichirvr7.c +2319 -0
  48. data/ext/src/ichirvrs.h +882 -0
  49. data/ext/src/ichisize.h +2 -2
  50. data/ext/src/ichisort.c +5 -5
  51. data/ext/src/ichister.c +281 -86
  52. data/ext/src/ichister.h +9 -3
  53. data/ext/src/ichitaut.c +208 -9
  54. data/ext/src/ichitaut.h +13 -11
  55. data/ext/src/ichitime.h +16 -2
  56. data/ext/src/inchicmp.h +107 -0
  57. data/ext/src/inpdef.h +6 -3
  58. data/ext/src/libinchi_wrap.c +912 -0
  59. data/ext/src/lreadmol.h +34 -31
  60. data/ext/src/mode.h +244 -7
  61. data/ext/src/mol2atom.c +1060 -0
  62. data/ext/src/mol2atom.h +31 -0
  63. data/ext/src/readinch.c +239 -0
  64. data/ext/src/readmol.c +28 -0
  65. data/ext/src/{e_readmol.h → readmol.h} +7 -9
  66. data/ext/src/runichi.c +251 -177
  67. data/ext/src/strutil.c +444 -238
  68. data/ext/src/strutil.h +150 -11
  69. data/ext/src/util.c +176 -118
  70. data/ext/src/util.h +15 -3
  71. data/lib/rino.rb +71 -3
  72. data/test/test.rb +33 -4
  73. metadata +22 -34
  74. data/ext/ruby_inchi_main.so +0 -0
  75. data/ext/src/e_0dstereo.c +0 -3014
  76. data/ext/src/e_0dstereo.h +0 -31
  77. data/ext/src/e_comdef.h +0 -57
  78. data/ext/src/e_ctl_data.h +0 -147
  79. data/ext/src/e_ichi_io.c +0 -498
  80. data/ext/src/e_ichi_io.h +0 -40
  81. data/ext/src/e_ichi_parms.c +0 -37
  82. data/ext/src/e_ichi_parms.h +0 -41
  83. data/ext/src/e_ichicomp.h +0 -50
  84. data/ext/src/e_ichierr.h +0 -40
  85. data/ext/src/e_ichimain.c +0 -593
  86. data/ext/src/e_ichisize.h +0 -43
  87. data/ext/src/e_inchi_atom.c +0 -75
  88. data/ext/src/e_inchi_atom.h +0 -33
  89. data/ext/src/e_inpdef.h +0 -41
  90. data/ext/src/e_mode.h +0 -706
  91. data/ext/src/e_mol2atom.c +0 -649
  92. data/ext/src/e_readinch.c +0 -58
  93. data/ext/src/e_readmol.c +0 -54
  94. data/ext/src/e_readstru.c +0 -251
  95. data/ext/src/e_readstru.h +0 -33
  96. data/ext/src/e_util.c +0 -284
  97. data/ext/src/e_util.h +0 -61
  98. data/ext/src/ichilnct.c +0 -286
  99. data/ext/src/inchi_api.h +0 -670
  100. data/ext/src/inchi_dll.c +0 -1480
  101. data/ext/src/inchi_dll.h +0 -34
  102. data/ext/src/inchi_dll_main.c +0 -23
  103. data/ext/src/inchi_dll_main.h +0 -31
  104. data/ext/src/ruby_inchi_main.c +0 -558
@@ -1,1480 +0,0 @@
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 "mode.h"
11
-
12
- #include <stdio.h>
13
- #include <stdlib.h>
14
- #include <string.h>
15
- #include <ctype.h>
16
- #include <stdarg.h>
17
- #include <errno.h>
18
- #include <limits.h>
19
- #include <float.h>
20
- #include <math.h>
21
-
22
- #include "inpdef.h"
23
- #include "ichi.h"
24
- #include "strutil.h"
25
- #include "util.h"
26
- #include "ichierr.h"
27
- #include "ichimain.h"
28
- #include "extr_ct.h"
29
-
30
- #include "ichicomp.h"
31
- #include "inchi_api.h"
32
- #include "inchi_dll.h"
33
-
34
- /*************************************************************************
35
- *
36
- * Local protopypes
37
- *
38
- *************************************************************************/
39
-
40
-
41
- int SetAtomProperties( inp_ATOM *at, MOL_COORD *szCoord, inchi_Atom *ati,
42
- int a1, int *nDim, char *pStrErr, int *err );
43
- int SetBondProperties( inp_ATOM *at, inchi_Atom *ati, int a1, int j,
44
- int nNumAtoms, int *nNumBonds, char *pStrErr, int *err );
45
- int SetAtomAndBondProperties( inp_ATOM *at, inchi_Atom *ati, int a1,
46
- int bDoNotAddH, char *pStrErr, int *err );
47
- void SetNumImplicitH(inp_ATOM* at, int num_atoms);
48
- int Extract0DParities( inp_ATOM *at, int nNumAtoms, inchi_Stereo0D *stereo0D,
49
- int num_stereo0D, char *pStrErr, int *err );
50
- int parse_options_string ( char *cmd, const char *argv[], int maxargs );
51
-
52
- /*************************************************************************/
53
-
54
- int bInterrupted = 0;
55
-
56
- #if( defined( _WIN32 ) && defined( _CONSOLE ) )
57
-
58
- #ifndef INCHI_ANSI_ONLY
59
- BOOL WINAPI MyHandlerRoutine(
60
- DWORD dwCtrlType /* control signal type */
61
- ) {
62
- if ( dwCtrlType == CTRL_C_EVENT ||
63
- dwCtrlType == CTRL_BREAK_EVENT ||
64
- dwCtrlType == CTRL_CLOSE_EVENT ||
65
- dwCtrlType == CTRL_LOGOFF_EVENT ) {
66
- bInterrupted = 1;
67
- return TRUE;
68
- }
69
- return FALSE;
70
- }
71
- #endif
72
- int WasInterrupted(void) {
73
- #ifdef _DEBUG
74
- if ( bInterrupted ) {
75
- int stop=1; /* for debug only <BRKPT> */
76
- }
77
- #endif
78
- return bInterrupted;
79
- }
80
-
81
- #endif
82
-
83
-
84
- /********************************************************************
85
- *
86
- * INCHI API: DEALLOCATE INCHI OUTPUT
87
- *
88
- ********************************************************************/
89
- void INCHI_DECL FreeINCHI( inchi_Output *out )
90
- {
91
- if ( out->szInChI ) {
92
- inchi_free( out->szInChI );
93
- }
94
- if ( out->szLog ) {
95
- inchi_free( out->szLog );
96
- }
97
- if ( out->szMessage ) {
98
- inchi_free( out->szMessage );
99
- }
100
- memset( out, 0, sizeof(*out) );
101
- }
102
- /********************************************************************/
103
- #define INCHI_MAX_NUM_ARG 32
104
- /********************************************************************
105
- *
106
- * INCHI API: MAIN ENTRY POINT
107
- *
108
- ********************************************************************/
109
-
110
- int bLibInchiSemaphore = 0;
111
-
112
- int INCHI_DECL GetINCHI( inchi_Input *inp, inchi_Output *out )
113
- {
114
-
115
- STRUCT_DATA struct_data;
116
- STRUCT_DATA *sd = &struct_data;
117
- FILE *inp_file = NULL;
118
- INCHI_FILE inchi_file[3];
119
- INCHI_FILE *output_file = inchi_file, *log_file = inchi_file+1, *prb_file = inchi_file+2;
120
- char szTitle[MAX_SDF_HEADER+MAX_SDF_VALUE+256];
121
-
122
- int i, num_inp, num_err, num_output;
123
- char szSdfDataValue[MAX_SDF_VALUE+1];
124
- PINChI2 *pINChI[INCHI_NUM];
125
- PINChI_Aux2 *pINChI_Aux[INCHI_NUM];
126
-
127
- unsigned long ulDisplTime = 0; /* infinite, milliseconds */
128
- unsigned long ulTotalProcessingTime = 0;
129
-
130
- INPUT_PARMS inp_parms;
131
- INPUT_PARMS *ip = &inp_parms;
132
-
133
- ORIG_ATOM_DATA OrigAtData; /* 0=> disconnected, 1=> original */
134
- ORIG_ATOM_DATA *orig_inp_data = &OrigAtData;
135
- ORIG_ATOM_DATA PrepAtData[2]; /* 0=> disconnected, 1=> original */
136
- ORIG_ATOM_DATA *prep_inp_data = PrepAtData;
137
- int bReleaseVersion = bRELEASE_VERSION;
138
- const int nStrLen = 64000;
139
- char *pStr = NULL;
140
- int nRet = 0, nRet1;
141
-
142
- STRUCT_FPTRS *pStructPtrs = NULL;
143
-
144
- #if ( defined(REPEAT_ALL) && REPEAT_ALL > 0 )
145
- int num_repeat = REPEAT_ALL;
146
- #endif
147
-
148
- const char *argv[INCHI_MAX_NUM_ARG+1];
149
- int argc;
150
- char *szOptions = NULL;
151
-
152
- if ( bLibInchiSemaphore ) { /* does not work properly under sufficient stress */
153
- return inchi_Ret_BUSY;
154
- }
155
- bLibInchiSemaphore = 1;
156
-
157
- #if( TRACE_MEMORY_LEAKS == 1 )
158
- _CrtSetDbgFlag(_CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF);
159
- /* for execution outside the VC++ debugger uncomment one of the following two */
160
- #ifdef MY_REPORT_FILE
161
- _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
162
- _CrtSetReportFile( _CRT_WARN, MY_REPORT_FILE );
163
- _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
164
- _CrtSetReportFile( _CRT_ERROR, MY_REPORT_FILE );
165
- _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
166
- _CrtSetReportFile( _CRT_ASSERT, MY_REPORT_FILE );
167
- #else
168
- _CrtSetReportMode(_CRT_WARN | _CRT_ERROR, _CRTDBG_MODE_DEBUG);
169
- #endif
170
-
171
- /* turn on floating point exceptions */
172
- {
173
- /* Get the default control word. */
174
- int cw = _controlfp( 0,0 );
175
-
176
- /* Set the exception masks OFF, turn exceptions on. */
177
- /*cw &=~(EM_OVERFLOW|EM_UNDERFLOW|EM_INEXACT|EM_ZERODIVIDE|EM_DENORMAL);*/
178
- cw &=~(EM_OVERFLOW|EM_UNDERFLOW|EM_ZERODIVIDE|EM_DENORMAL);
179
-
180
- /* Set the control word. */
181
- _controlfp( cw, MCW_EM );
182
-
183
- }
184
- #endif
185
-
186
-
187
- #if( defined( _WIN32 ) && defined( _CONSOLE ) && !defined( INCHI_ANSI_ONLY ) )
188
- if ( SetConsoleCtrlHandler( MyHandlerRoutine, 1 ) ) {
189
- ConsoleQuit = WasInterrupted;
190
- }
191
- #endif
192
-
193
- memset( inchi_file, 0, sizeof(inchi_file) );
194
-
195
- #if ( defined(REPEAT_ALL) && REPEAT_ALL > 0 )
196
- repeat:
197
- inp_file = output_file = log_file = prb_file = NULL;
198
- pStr = NULL;
199
- #endif
200
-
201
- num_inp = 0;
202
- num_err = 0;
203
- num_output = 0;
204
- sd->bUserQuit = 0;
205
-
206
- /* clear original input structure */
207
- memset( pINChI, 0, sizeof(pINChI ) );
208
- memset( pINChI_Aux, 0, sizeof(pINChI_Aux) );
209
- memset( sd, 0, sizeof(*sd) );
210
- memset( ip, 0, sizeof(*ip) );
211
- memset( orig_inp_data , 0, sizeof( *orig_inp_data ) );
212
- memset( prep_inp_data , 0, 2*sizeof( *prep_inp_data ) );
213
- memset( szSdfDataValue , 0, sizeof( szSdfDataValue ) );
214
-
215
- if ( !out ) {
216
- nRet = _IS_ERROR;
217
- goto exit_function;
218
- }
219
- memset( out, 0, sizeof(*out) );
220
-
221
- /* options */
222
- if ( inp && inp->szOptions ) {
223
- szOptions = (char*)inchi_malloc( strlen(inp->szOptions) + 1 );
224
- if ( szOptions ) {
225
- strcpy( szOptions, inp->szOptions );
226
- argc = parse_options_string ( szOptions, argv, INCHI_MAX_NUM_ARG );
227
- } else {
228
- nRet = _IS_FATAL;
229
- goto translate_RetVal; /* emergency exit */
230
- }
231
- } else {
232
- argc = 1;
233
- argv[0] = "";
234
- argv[1] = NULL;
235
- }
236
-
237
- if ( argc == 1
238
- #ifdef INCHI_LIBRARY
239
- && (!inp || inp->num_atoms <= 0 || !inp->atom)
240
- #endif
241
- || argc==2 && ( argv[1][0]==INCHI_OPTION_PREFX ) &&
242
- (!strcmp(argv[1]+1, "?") || !stricmp(argv[1]+1, "help") ) ) {
243
- HelpCommandLineParms(log_file);
244
- out->szLog = log_file->pStr;
245
- memset( log_file, 0, sizeof(*log_file) );
246
- nRet = _IS_EOF;
247
- goto translate_RetVal;
248
- }
249
-
250
- nRet1 = ReadCommandLineParms( argc, argv, ip, szSdfDataValue, &ulDisplTime, bReleaseVersion, log_file );
251
- if ( szOptions ) {
252
- inchi_free( szOptions );
253
- szOptions = NULL;
254
- }
255
- /* INChI DLL specific */
256
- ip->bNoStructLabels = 1;
257
-
258
- if ( 0 > nRet1 ) {
259
- goto exit_function;
260
- }
261
- #ifndef INCHI_LIBRARY
262
- if ( !OpenFiles( &inp_file, &output_file, &log_file, &prb_file, ip ) ) {
263
- goto exit_function;
264
- }
265
- #endif
266
- if ( ip->bNoStructLabels ) {
267
- ip->pSdfLabel = NULL;
268
- ip->pSdfValue = NULL;
269
- } else
270
- if ( ip->nInputType == INPUT_INCHI_XML || ip->nInputType == INPUT_INCHI_PLAIN || ip->nInputType == INPUT_CMLFILE ) {
271
- /* the input may contain both the header and the label of the structure */
272
- if ( !ip->pSdfLabel )
273
- ip->pSdfLabel = ip->szSdfDataHeader;
274
- if ( !ip->pSdfValue )
275
- ip->pSdfValue = szSdfDataValue;
276
- }
277
- PrintInputParms( log_file, ip );
278
- if ( !(pStr = (char*)inchi_malloc(nStrLen))) {
279
- my_fprintf( log_file, "Cannot allocate output buffer. Terminating\n");
280
- goto exit_function;
281
- }
282
- pStr[0] = '\0';
283
-
284
- /**********************************************************************************************/
285
- /* Main cycle */
286
- /* read input structures and create their INChI */
287
- ulTotalProcessingTime = 0;
288
-
289
- if ( pStructPtrs ) {
290
- memset ( pStructPtrs, 0, sizeof(pStructPtrs[0]) );
291
- }
292
-
293
- /* === TOMORROW: remove while cycling and convert inp to orig_inp_data ==== */
294
- #ifdef INCHI_LIBRARY
295
- if ( !sd->bUserQuit && !bInterrupted )
296
- #else
297
- while ( !sd->bUserQuit && !bInterrupted )
298
- #endif
299
- {
300
- if ( ip->last_struct_number && num_inp >= ip->last_struct_number ) {
301
- nRet = _IS_EOF; /* simulate end of file */
302
- goto exit_function;
303
- }
304
-
305
- #ifndef INCHI_LIBRARY
306
- /* read one structure from input and display optionally it */
307
- nRet = GetOneStructure( sd, ip, szTitle, inp_file, log_file, output_file, prb_file,
308
- orig_inp_data, &num_inp, pStr, nStrLen, pStructPtrs );
309
- #else
310
- nRet = ExtractOneStructure( sd, ip, szTitle, inp, log_file, output_file, prb_file,
311
- orig_inp_data, &num_inp, pStr, nStrLen );
312
- #endif
313
-
314
-
315
- if ( pStructPtrs ) {
316
- pStructPtrs->cur_fptr ++;
317
- }
318
-
319
- #ifndef INCHI_LIBRARY
320
- if ( sd->bUserQuit ) {
321
- break;
322
- }
323
- #endif
324
- switch ( nRet ) {
325
- case _IS_FATAL:
326
- num_err ++;
327
- goto exit_function;
328
- case _IS_EOF:
329
- goto exit_function;
330
- case _IS_ERROR:
331
- num_err ++;
332
- goto exit_function;
333
- #ifndef INCHI_LIBRARY
334
- case _IS_SKIP:
335
- continue;
336
- #endif
337
- }
338
-
339
- /* create INChI for each connected component of the structure and optionally display them */
340
- /* output INChI for the whole structure */
341
- nRet1 = ProcessOneStructure( sd, ip, szTitle, pINChI, pINChI_Aux,
342
- inp_file, log_file, output_file, prb_file,
343
- orig_inp_data, prep_inp_data,
344
- num_inp, pStr, nStrLen );
345
-
346
- /* free INChI memory */
347
- FreeAllINChIArrays( pINChI, pINChI_Aux, sd->num_components );
348
- /* free structure data */
349
- FreeOrigAtData( orig_inp_data );
350
- FreeOrigAtData( prep_inp_data );
351
- FreeOrigAtData( prep_inp_data+1 );
352
-
353
- ulTotalProcessingTime += sd->ulStructTime;
354
- nRet = inchi_max(nRet, nRet1);
355
- switch ( nRet ) {
356
- case _IS_FATAL:
357
- num_err ++;
358
- goto exit_function;
359
- case _IS_ERROR:
360
- num_err ++;
361
- #ifndef INCHI_LIBRARY
362
- continue;
363
- #endif
364
- }
365
-
366
- }
367
-
368
- exit_function:
369
- if ( (ip->bINChIOutputOptions & INCHI_OUT_XML) && sd->bXmlStructStarted > 0 ) {
370
- if ( !OutputINChIXmlStructEndTag( output_file, pStr, nStrLen, 1 ) ) {
371
- 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) );
372
- sd->bXmlStructStarted = -1; /* do not repeat same message */
373
- }
374
- }
375
-
376
-
377
- if ( (ip->bINChIOutputOptions & INCHI_OUT_XML) && ip->bXmlStarted ) {
378
- OutputINChIXmlRootEndTag( output_file );
379
- ip->bXmlStarted = 0;
380
- }
381
-
382
-
383
- /* avoid memory leaks in case of fatal error */
384
- if ( pStructPtrs && pStructPtrs->fptr ) {
385
- inchi_free( pStructPtrs->fptr );
386
- }
387
-
388
- /* free INChI memory */
389
- FreeAllINChIArrays( pINChI, pINChI_Aux, sd->num_components );
390
- /* free structure data */
391
- FreeOrigAtData( orig_inp_data );
392
- FreeOrigAtData( prep_inp_data );
393
- FreeOrigAtData( prep_inp_data+1 );
394
-
395
- #if( ADD_CMLPP == 1 )
396
- /* BILLY 8/6/04 */
397
- /* free CML memory */
398
- FreeCml ();
399
- FreeCmlDoc( 1 );
400
- #endif
401
-
402
- #ifndef INCHI_LIBRARY
403
- if ( inp_file && inp_file != stdin) {
404
- fclose ( inp_file );
405
- }
406
- if ( prb_file ) {
407
- fclose ( prb_file );
408
- }
409
- if ( output_file && output_file != stdout ) {
410
- fclose( output_file );
411
- }
412
-
413
- if ( log_file )
414
- {
415
- int hours, minutes, seconds, mseconds;
416
- SplitTime( ulTotalProcessingTime, &hours, &minutes, &seconds, &mseconds );
417
- my_fprintf( log_file, "Finished processing %d structure%s: %d error%s, processing time %d:%02d:%02d.%02d\n",
418
- num_inp, num_inp==1?"":"s",
419
- num_err, num_err==1?"":"s",
420
- hours, minutes, seconds,mseconds/10);
421
- }
422
-
423
- if ( log_file && log_file != stderr ) {
424
- fclose( log_file );
425
- }
426
- #endif
427
-
428
- if ( pStr ) {
429
- inchi_free( pStr );
430
- }
431
-
432
- for ( i = 0; i < MAX_NUM_PATHS; i ++ ) {
433
- if ( ip->path[i] ) {
434
- inchi_free( (void*) ip->path[i] ); /* cast deliberately discards 'const' qualifier */
435
- ip->path[i] = NULL;
436
- }
437
- }
438
-
439
- SetBitFree( );
440
-
441
-
442
- #if ( defined(REPEAT_ALL) && REPEAT_ALL > 0 )
443
- if ( num_repeat-- > 0 ) {
444
- goto repeat;
445
- }
446
- #endif
447
-
448
- #ifndef INCHI_LIBRARY
449
- #if( bRELEASE_VERSION != 1 && defined(_DEBUG) )
450
- if ( inp_file && inp_file != stdin ) {
451
- user_quit("Press Enter to exit ?", ulDisplTime);
452
- }
453
- #endif
454
- #endif
455
-
456
-
457
- #ifdef INCHI_LIBRARY
458
- /* output */
459
- if ( sd->pStrErrStruct[0] ) {
460
- if ( out && (out->szMessage = (char *)inchi_malloc( strlen(sd->pStrErrStruct) + 1 )) ) {
461
- strcpy( out->szMessage, sd->pStrErrStruct );
462
- }
463
- }
464
- if ( output_file->pStr && output_file->nUsedLength > 0 && out ) {
465
- char *p;
466
- out->szInChI = output_file->pStr;
467
- out->szAuxInfo = NULL;
468
- for ( p = strchr(out->szInChI, '\n'); p; p = strchr(p+1, '\n') ) {
469
- if ( !memcmp( p, "\nAuxInfo", 8 ) ) {
470
- *p = '\0'; /* remove LF after INChI */
471
- out->szAuxInfo = p+1; /* save pointer to AuxInfo */
472
- } else
473
- if ( out->szAuxInfo || !p[1]) { /* remove LF after aux info or from the last char */
474
- *p = '\0';
475
- break;
476
- }
477
- }
478
- output_file->pStr = NULL;
479
- }
480
- if ( log_file->pStr && log_file->nUsedLength > 0 ) {
481
- while ( log_file->nUsedLength && '\n' == log_file->pStr[log_file->nUsedLength-1] ) {
482
- log_file->pStr[-- log_file->nUsedLength] = '\0'; /* remove last LF */
483
- }
484
- if ( out ) {
485
- out->szLog = log_file->pStr;
486
- log_file->pStr = NULL;
487
- }
488
- }
489
- if ( output_file->pStr )
490
- inchi_free( output_file->pStr );
491
- if ( log_file->pStr )
492
- inchi_free( log_file->pStr );
493
-
494
-
495
- #endif
496
-
497
- translate_RetVal:
498
-
499
- switch (nRet) {
500
- case _IS_SKIP : nRet = inchi_Ret_SKIP ; break; /* not used in INChI dll */
501
- case _IS_EOF : nRet = inchi_Ret_EOF ; break; /* no structural data has been provided */
502
- case _IS_OKAY : nRet = inchi_Ret_OKAY ; break; /* Success; break; no errors or warnings */
503
- case _IS_WARNING: nRet = inchi_Ret_WARNING; break; /* Success; break; warning(s) issued */
504
- case _IS_ERROR : nRet = inchi_Ret_ERROR ; break; /* Error: no INChI has been created */
505
- case _IS_FATAL : nRet = inchi_Ret_FATAL ; break; /* Severe error: no INChI has been created (typically; break; memory allocation failed) */
506
- case _IS_UNKNOWN:
507
- default : nRet = inchi_Ret_UNKNOWN; break; /* Unlnown program error */
508
- }
509
- bLibInchiSemaphore = 0;
510
- return nRet;
511
- }
512
-
513
-
514
- /*************************************************************************/
515
- /******************************** from readmol.c *************************/
516
- /*************************************************************************/
517
- int AddMOLfileError( char *pStrErr, const char *szMsg )
518
- {
519
- if ( pStrErr && szMsg && szMsg[0] ) {
520
- int lenStrErr = strlen( pStrErr );
521
- int lenMsg = strlen( szMsg );
522
- char *p = strstr( pStrErr, szMsg );
523
- if ( p && (p==pStrErr || *(p-1) == ' ' && (*(p-2) == ';' || *(p-2) == ':' )) &&
524
- (p+lenMsg == pStrErr+lenStrErr ||
525
- p[lenMsg] == ';' && p[lenMsg+1] == ' ' ||
526
- p[lenMsg-1]==':' && p[lenMsg]==' ') ) {
527
- return 1; /* reject duplicates */
528
- }
529
- if ( lenStrErr + lenMsg + 2*(lenStrErr > 0) < STR_ERR_LEN ) {
530
- /* enough room to add */
531
- if (lenStrErr > 0) {
532
- if ( pStrErr[lenStrErr-1] != ':' ) {
533
- strcat( pStrErr, ";" );
534
- }
535
- strcat( pStrErr, " " );
536
- }
537
- strcat( pStrErr, szMsg );
538
- return 1;
539
- }
540
- /* no room */
541
- if ( strstr( pStrErr, "..." ) ) {
542
- return 0; /* no room mark has already been set */
543
- }
544
- if ( lenStrErr + 3 < STR_ERR_LEN ) {
545
- strcat( pStrErr, "..." );
546
- }
547
- }
548
- return 0;
549
- }
550
- /****************************************************************/
551
- int CopyMOLfile(FILE *inp_file, long fPtrStart, long fPtrEnd, INCHI_FILE *prb_file, long lNumb)
552
- {
553
- return 0; /* dummy */
554
- }
555
- /****************************************************************/
556
- /************************** from mol2atom.c *********************/
557
- /****************************************************************/
558
- void SetNumImplicitH(inp_ATOM* at, int num_atoms)
559
- {
560
- int bNonMetal;
561
- int a1/*, n1*/;
562
-
563
- /* special valences */
564
- for ( bNonMetal = 0; bNonMetal < 2; bNonMetal ++ ) {
565
- for ( a1 = 0; a1 < num_atoms; a1 ++ ) {
566
- int bHasMetalNeighbor /*, j*/;
567
- if ( bNonMetal != is_el_a_metal( at[a1].el_number ) ) {
568
- continue; /* first process all metals, after that all non-metals */
569
- }
570
-
571
- bHasMetalNeighbor = 0;
572
- /***********************************************************************
573
- * Set number of hydrogen atoms
574
- */
575
- at[a1].num_H = get_num_H( at[a1].elname, at[a1].num_H, at[a1].num_iso_H,
576
- at[a1].charge, at[a1].radical,
577
- at[a1].chem_bonds_valence,
578
- 0, /* instead of valence entered by the user: it does not exist here*/
579
- (at[a1].at_type & 1) /* bAliased */,
580
- !(at[a1].at_type & 2) /* bDoNotAddH */,
581
- bHasMetalNeighbor );
582
- at[a1].at_type = 0;
583
- }
584
- }
585
- }
586
-
587
- /******************************************************************************************************/
588
- void FreeInpAtom( inp_ATOM **at )
589
- {
590
- if ( at && *at ) {
591
- inchi_free( *at );
592
- *at = NULL;
593
- }
594
- }
595
- /******************************************************************************************************/
596
- inp_ATOM *CreateInpAtom( int num_atoms )
597
- {
598
- /*
599
- void *p = inchi_calloc(num_atoms, sizeof(inp_ATOM) );
600
- if ( p == (void*)0x009143A8 ) {
601
- int stop = 1;
602
- }
603
- return (inp_ATOM* )p;
604
- */
605
- return (inp_ATOM* ) inchi_calloc(num_atoms, sizeof(inp_ATOM) );
606
- }
607
- /******************************************************************************************************/
608
- void FreeInpAtomData( INP_ATOM_DATA *inp_at_data )
609
- {
610
- FreeInpAtom( &inp_at_data->at );
611
- FreeInpAtom( &inp_at_data->at_fixed_bonds );
612
- memset( inp_at_data, 0, sizeof(*inp_at_data) );
613
- }
614
- /******************************************************************************************************/
615
- int CreateInpAtomData( INP_ATOM_DATA *inp_at_data, int num_atoms, int create_at_fixed_bonds )
616
- {
617
- FreeInpAtomData( inp_at_data );
618
- if ( (inp_at_data->at = CreateInpAtom( num_atoms )) &&
619
- (!create_at_fixed_bonds || (inp_at_data->at_fixed_bonds = CreateInpAtom( num_atoms) ) ) ) {
620
- inp_at_data->num_at = num_atoms;
621
- return 1;
622
- }
623
- FreeInpAtomData( inp_at_data );
624
- return 0;
625
- }
626
- /******************************************************************************************************/
627
- void FreeCompAtomData( COMP_ATOM_DATA *inp_at_data )
628
- {
629
- FreeInpAtom( &inp_at_data->at );
630
- if ( inp_at_data->nOffsetAtAndH )
631
- inchi_free( inp_at_data->nOffsetAtAndH );
632
- memset( inp_at_data, 0, sizeof(*inp_at_data) );
633
- }
634
- /******************************************************************************************************/
635
- #if( TEST_RENUMB_ATOMS == 1 ) /* { */
636
- /******************************************************************************************************/
637
- int CopyInpAtomData( INP_ATOM_DATA *dest_inp_at_data, INP_ATOM_DATA *src_inp_at_data )
638
- {
639
- int ret = 1;
640
- if ( !dest_inp_at_data->at || dest_inp_at_data->num_at != src_inp_at_data->num_at ) {
641
- ret = CreateInpAtomData( dest_inp_at_data, src_inp_at_data->num_at, (NULL != src_inp_at_data->at_fixed_bonds) );
642
- } else {
643
- inp_ATOM *at = dest_inp_at_data->at; /* save ptr to already allocated memory */
644
- inp_ATOM *at2 = dest_inp_at_data->at_fixed_bonds;
645
- *dest_inp_at_data = *src_inp_at_data; /* copy all other (scalar) data */
646
- dest_inp_at_data->at = at; /* restore ptr to already allocated memory */
647
- dest_inp_at_data->at_fixed_bonds = at2;
648
- }
649
- if ( ret ) {
650
- memcpy( dest_inp_at_data->at, src_inp_at_data->at,
651
- src_inp_at_data->num_at*sizeof(dest_inp_at_data->at[0]) );
652
- if ( dest_inp_at_data->at_fixed_bonds && src_inp_at_data->at_fixed_bonds ) {
653
- memcpy( dest_inp_at_data->at_fixed_bonds, src_inp_at_data->at_fixed_bonds,
654
- src_inp_at_data->num_at*sizeof(dest_inp_at_data->at_fixed_bonds[0]) );
655
- }
656
- }
657
- return ret;
658
- }
659
- /******************************************************************************************************/
660
- void RenumbInpAtomData( INP_ATOM_DATA *dest_inp_at_data, INP_ATOM_DATA *src_inp_at_data, AT_RANK *new_ord )
661
- {
662
- int j, n, m, val;
663
- #if( TEST_RENUMB_NEIGH == 1 )
664
- int i, k;
665
- #endif
666
- int num_atoms = src_inp_at_data->num_at;
667
- inp_ATOM *dest_at = dest_inp_at_data->at;
668
- for ( n = 0; n < num_atoms; n ++ ) {
669
- m = new_ord[n];
670
- dest_at[m] = src_inp_at_data->at[n];
671
- dest_at[m].orig_compt_at_numb = (AT_NUMB)(m+1); /* new ordering number within the component */
672
- val = dest_at[m].valence;
673
- for ( j = 0; j < val; j ++ ) {
674
- dest_at[m].neighbor[j] = new_ord[dest_at[m].neighbor[j]];
675
- }
676
- #if( TEST_RENUMB_NEIGH == 1 )
677
- for ( i = 0; i < 3*val; i ++ ) {
678
- j = (rand() * val) / (RAND_MAX+1);
679
- k = (rand() * val) / (RAND_MAX+1);
680
- if ( j >= val || k >= val || j == k ) {
681
- continue;
682
- }
683
- swap( (char*)&dest_at[m].neighbor[j], (char*)&dest_at[m].neighbor[k], sizeof(dest_at[0].neighbor[0]) );
684
- swap( (char*)&dest_at[m].bond_stereo[j], (char*)&dest_at[m].bond_stereo[k], sizeof(dest_at[0].bond_stereo[0]) );
685
- swap( (char*)&dest_at[m].bond_type[j], (char*)&dest_at[m].bond_type[k], sizeof(dest_at[0].bond_type[0]) );
686
- /* adjust stereo bond links */
687
- if ( dest_at[m].sb_parity[0] ) {
688
- int a;
689
- for ( a = 0; a < MAX_NUM_STEREO_BONDS && dest_at[m].sb_parity[a]; a ++ ) {
690
-
691
- if ( k == (int)dest_at[m].sb_ord[a] ) {
692
- dest_at[m].sb_ord[a] = j;
693
- } else
694
- if ( j == (int)dest_at[m].sb_ord[a] ) {
695
- dest_at[m].sb_ord[a] = k;
696
- }
697
-
698
- if ( k == (int)dest_at[m].sn_ord[a] ) {
699
- dest_at[m].sn_ord[a] = j;
700
- } else
701
- if ( j == (int)dest_at[m].sn_ord[a] ) {
702
- dest_at[m].sn_ord[a] = k;
703
- }
704
- }
705
- }
706
- }
707
- #endif
708
- }
709
-
710
- }
711
- /******************************************************************************************************/
712
- void MakeNewOrd( int num_atoms, AT_RANK *new_ord )
713
- {
714
- int i, j, k;
715
- for ( i = 0; i < 3*num_atoms; i ++ ) {
716
- j = (rand() * num_atoms) / (RAND_MAX+1);
717
- k = (rand() * num_atoms) / (RAND_MAX+1);
718
- if ( j >= num_atoms || k >= num_atoms || j == k ) {
719
- continue;
720
- }
721
- swap( (char*)&new_ord[j], (char*)&new_ord[k], sizeof(new_ord[0]) );
722
- }
723
- }
724
- #endif /* } TEST_RENUMB_ATOMS == 1 */
725
- /**********************************************************************************/
726
- void FreeOrigAtData( ORIG_ATOM_DATA *orig_at_data )
727
- {
728
- if ( !orig_at_data )
729
- return;
730
- FreeInpAtom( &orig_at_data->at );
731
- if ( orig_at_data->nCurAtLen ) {
732
- inchi_free( orig_at_data->nCurAtLen );
733
- }
734
- if ( orig_at_data->nOldCompNumber ) {
735
- inchi_free( orig_at_data->nOldCompNumber );
736
- }
737
- if ( orig_at_data->szCoord ) {
738
- inchi_free( orig_at_data->szCoord );
739
- }
740
- if ( orig_at_data->nEquLabels ) {
741
- inchi_free( orig_at_data->nEquLabels );
742
- }
743
- if ( orig_at_data->nSortedOrder ) {
744
- inchi_free( orig_at_data->nSortedOrder );
745
- }
746
- memset( orig_at_data, 0, sizeof(*orig_at_data) );
747
- }
748
- /********************************************************************/
749
-
750
- #define REPEAT_ALL 0
751
- /********************************************************************/
752
- int parse_options_string ( char *cmd, const char *argv[], int maxargs )
753
- {
754
- char *p;
755
- char *pArgCurChar;
756
- int bInsideQuotes;
757
- int bCopyCharToArg;
758
- int nNumBackSlashes;
759
- int i;
760
-
761
- i = 0;
762
- argv[i++] = ""; /* zeroth argument is not used */
763
- p = cmd;
764
- bInsideQuotes = 0;
765
-
766
- /* arguments, one by one */
767
- while( i < maxargs-1 ) {
768
- /* bypass spaces */
769
- while ( *p == ' ' || *p == '\t' )
770
- p ++;
771
- if ( !*p )
772
- break;
773
- /* scan an argument */
774
- argv[i++] = pArgCurChar = p; /* store preliminary ptr to arg */
775
- while ( 1 ) {
776
- bCopyCharToArg = 1;
777
- nNumBackSlashes = 0;
778
- while (*p == '\\') {
779
- ++p;
780
- ++nNumBackSlashes;
781
- }
782
- /* each pair of backslashes => one backslash; one more backslash => literal quote */
783
- if ( *p == '\"' ) {
784
- /* one " found */
785
- if ( nNumBackSlashes % 2 == 0 ) {
786
- if (bInsideQuotes) {
787
- if (*(p+1) == '\"') {
788
- p++;
789
- } else {
790
- bCopyCharToArg = 0;
791
- }
792
- } else {
793
- bCopyCharToArg = 0;
794
- }
795
- bInsideQuotes = !bInsideQuotes;
796
- }
797
- nNumBackSlashes /= 2; /* divide nNumBackSlashes by two */
798
- }
799
- while (nNumBackSlashes--) {
800
- *pArgCurChar++ = '\\';
801
- }
802
- if (!*p) {
803
- break;
804
- }
805
- if (!bInsideQuotes && (*p == ' ' || *p == '\t')) {
806
- p ++;
807
- /* move to the next char because this char may become
808
- * zero due to *pArgCurChar++ = '\0'; line below */
809
- break;
810
- }
811
- if (bCopyCharToArg) {
812
- *pArgCurChar++ = *p;
813
- }
814
- ++p;
815
- }
816
- *pArgCurChar++ = '\0'; /* argument zero termination */
817
- }
818
- /* The last argument is NULL */
819
- argv[i] = NULL;
820
- return i;
821
- }
822
- /*****************************************************************/
823
- #define MIN_BOND_LENGTH (1.0e-6)
824
- int SetAtomProperties( inp_ATOM *at, MOL_COORD *szCoord, inchi_Atom *ati, int a1, int *nDim, char *pStrErr, int *err )
825
- {
826
- S_CHAR cRadical;
827
- /* element, check later */
828
-
829
- strcpy( at[a1].elname, ati[a1].elname );
830
-
831
- /* charge */
832
-
833
- at[a1].charge = ati[a1].charge;
834
-
835
- /* radical */
836
-
837
- switch ( ati[a1].radical ) {
838
- case INCHI_RADICAL_NONE:
839
- cRadical = 0;
840
- break;
841
- case INCHI_RADICAL_SINGLET:
842
- #if( SINGLET_IS_TRIPLET == 1) /* 'singlet' means two electrons make a lone pair instead of 2 bonds*/
843
- /* its effect on valence is same as the effect of a triplet */
844
- cRadical = RADICAL_TRIPLET;
845
- #else
846
- cRadical = RADICAL_SINGLET;
847
- #endif
848
- break;
849
- case INCHI_RADICAL_DOUBLET:
850
- cRadical = RADICAL_DOUBLET;
851
- break;
852
- case INCHI_RADICAL_TRIPLET:
853
- cRadical = RADICAL_TRIPLET;
854
- break;
855
- default:
856
- {
857
- char szRadicalType[16];
858
- sprintf( szRadicalType, "%d", ati[a1].radical );
859
- MOLFILE_ERR_SET (*err, 0, "Radical center type ignored:");
860
- MOLFILE_ERR_SET (*err, 0, szRadicalType);
861
- *err |= 8; /* Unrecognized Radical replaced with non-radical */
862
- cRadical = 0;
863
- }
864
- break;
865
- }
866
- at[a1].radical = cRadical;
867
-
868
- /* coordinates */
869
- at[a1].x = ati[a1].x;
870
- at[a1].y = ati[a1].y;
871
- at[a1].z = ati[a1].z;
872
-
873
- if ( szCoord ) {
874
- /* store text coordinates */
875
- char str[32];
876
- MOL_COORD * coord_p = szCoord + a1;
877
- WriteCoord( str, ati[a1].x );
878
- memcpy( *coord_p, str, 10 );
879
- WriteCoord( str, ati[a1].y );
880
- memcpy( *coord_p+10, str, 10 );
881
- WriteCoord( str, ati[a1].z );
882
- memcpy( *coord_p+20, str, 10 );
883
- }
884
-
885
- if ( MIN_BOND_LENGTH < fabs(ati[a1].x) || MIN_BOND_LENGTH < fabs(ati[a1].y) || MIN_BOND_LENGTH < fabs(ati[a1].z) ) {
886
- if ( MIN_BOND_LENGTH < fabs(ati[a1].z) ) {
887
- *nDim |= 3;
888
- } else {
889
- *nDim |= 2;
890
- }
891
- }
892
-
893
- /* orig. at. number */
894
- at[a1].orig_at_number = a1+1;
895
- return 0;
896
- #undef MIN_BOND_LENGTH
897
- }
898
- /*********************************************************************/
899
- int SetBondProperties( inp_ATOM *at, inchi_Atom *ati, int a1, int j,
900
- int nNumAtoms, int *nNumBonds, char *pStrErr, int *err )
901
- {
902
- int a2;
903
- S_CHAR cBondType, cStereoType1, cStereoType2;
904
- AT_NUMB *p1, *p2;
905
- int n1, n2;
906
-
907
- /* bond type */
908
- switch( ati[a1].bond_type[j] ) {
909
- case INCHI_BOND_TYPE_SINGLE:
910
- cBondType = BOND_TYPE_SINGLE;
911
- break;
912
- case INCHI_BOND_TYPE_DOUBLE:
913
- cBondType = BOND_TYPE_DOUBLE;
914
- break;
915
- case INCHI_BOND_TYPE_TRIPLE:
916
- cBondType = BOND_TYPE_TRIPLE;
917
- break;
918
- case INCHI_BOND_TYPE_ALTERN:
919
- cBondType = BOND_TYPE_ALTERN;
920
- break;
921
- default:
922
- {
923
- char szBondType[16];
924
- sprintf( szBondType, "%d", ati[a1].bond_type[j] );
925
- MOLFILE_ERR_SET (*err, 0, "Unrecognized bond type:");
926
- MOLFILE_ERR_SET (*err, 0, szBondType);
927
- *err |= 8; /* Unrecognized Bond type replaced with single bond */
928
- cBondType = BOND_TYPE_SINGLE;
929
- }
930
- break;
931
- }
932
-
933
- /* 2D stereo */
934
-
935
- switch( ati[a1].bond_stereo[j] ) {
936
- /* stereocenter-related; positive: the sharp end points to this atom */
937
- case INCHI_BOND_STEREO_NONE:
938
- cStereoType1 = 0;
939
- cStereoType2 = 0;
940
- break;
941
- case INCHI_BOND_STEREO_SINGLE_1UP:
942
- cStereoType1 = STEREO_SNGL_UP;
943
- cStereoType2 = -STEREO_SNGL_UP;
944
- break;
945
- case INCHI_BOND_STEREO_SINGLE_1EITHER:
946
- cStereoType1 = STEREO_SNGL_EITHER;
947
- cStereoType2 = -STEREO_SNGL_EITHER;
948
- break;
949
- case INCHI_BOND_STEREO_SINGLE_1DOWN:
950
- cStereoType1 = STEREO_SNGL_DOWN;
951
- cStereoType2 = -STEREO_SNGL_DOWN;
952
- break;
953
- /* stereocenter-related; negative: the sharp end points to the opposite atom */
954
- case INCHI_BOND_STEREO_SINGLE_2UP:
955
- cStereoType1 = -STEREO_SNGL_UP;
956
- cStereoType2 = STEREO_SNGL_UP;
957
- break;
958
- case INCHI_BOND_STEREO_SINGLE_2EITHER:
959
- cStereoType1 = -STEREO_SNGL_EITHER;
960
- cStereoType2 = STEREO_SNGL_EITHER;
961
- break;
962
- case INCHI_BOND_STEREO_SINGLE_2DOWN:
963
- cStereoType1 = -STEREO_SNGL_DOWN;
964
- cStereoType2 = STEREO_SNGL_DOWN;
965
- break;
966
- /* stereobond-related */
967
- case INCHI_BOND_STEREO_DOUBLE_EITHER:
968
- case -INCHI_BOND_STEREO_DOUBLE_EITHER:
969
- cStereoType1 = STEREO_DBLE_EITHER;
970
- cStereoType2 = STEREO_DBLE_EITHER;
971
- break;
972
- default:
973
- {
974
- char szBondType[16];
975
- sprintf( szBondType, "%d", ati[a1].bond_stereo[j] );
976
- MOLFILE_ERR_SET (*err, 0, "Unrecognized bond stereo:");
977
- MOLFILE_ERR_SET (*err, 0, szBondType);
978
- *err |= 8; /* Unrecognized Bond stereo replaced with non-stereo bond */
979
- cStereoType1 = 0;
980
- cStereoType2 = 0;
981
- }
982
- break;
983
- }
984
-
985
- /* neighbor */
986
-
987
- if ( ati[a1].neighbor[j] < 0 || ati[a1].neighbor[j] >= nNumAtoms ) {
988
- *err |= 1; /* bond for impossible atom number(s); ignored */
989
- MOLFILE_ERR_SET (*err, 0, "Bond to nonexistent atom");
990
- goto err_exit;
991
- }
992
- a2 = (AT_NUMB) ati[a1].neighbor[j];
993
- if ( a2 == a1 ) {
994
- *err |= 1; /* bond for impossible atom number(s); ignored */
995
- MOLFILE_ERR_SET (*err, 0, "Atom has a bond to itself");
996
- goto err_exit;
997
- }
998
-
999
- /* consistency check; locate the bond in the opposite atom */
1000
-
1001
- p1 = is_in_the_list( at[a1].neighbor, (AT_NUMB)a2, at[a1].valence );
1002
- p2 = is_in_the_list( at[a2].neighbor, (AT_NUMB)a1, at[a2].valence );
1003
- if ( p1 && p2 ) {
1004
- n1 = (p1 - at[a1].neighbor);
1005
- n2 = (p2 - at[a2].neighbor);
1006
- if ( n1+1 < at[a1].valence && is_in_the_list( at[a1].neighbor+n1+1, (AT_NUMB)a2, at[a1].valence-n1-1 ) ||
1007
- n2+1 < at[a2].valence && is_in_the_list( at[a2].neighbor+n2+1, (AT_NUMB)a1, at[a2].valence-n2-1 ) ) {
1008
- MOLFILE_ERR_SET (*err, 0, "Multiple bonds between two atoms");
1009
- *err |= 2; /* multiple bonds between atoms */
1010
- } else
1011
- if ( n1 < at[a1].valence && n2 < at[a2].valence &&
1012
- cBondType == at[a2].bond_type[n2] &&
1013
- cBondType == at[a1].bond_type[n1] &&
1014
- cStereoType1 == at[a1].bond_stereo[n1] &&
1015
- cStereoType2 == at[a2].bond_stereo[n2] ) {
1016
- /*MOLFILE_ERR_SET (*err, 0, "Duplicated bond(s) between two atoms");*/
1017
- } else {
1018
- MOLFILE_ERR_SET (*err, 0, "Multiple bonds between two atoms");
1019
- *err |= 2; /* multiple bonds between atoms */
1020
- }
1021
- } else
1022
- if ( (p1 || p2) && (p1 || at[a1].valence < MAXVAL) && (p2 || at[a2].valence < MAXVAL) ) {
1023
- n1 = p1? (p1 - at[a1].neighbor) : at[a1].valence ++;
1024
- n2 = p2? (p2 - at[a2].neighbor) : at[a2].valence ++;
1025
- /* the bond is present in one atom only: possibly program error */
1026
- if ( p1 && (cBondType != at[a1].bond_type[n1] || at[a1].bond_stereo[n1] != cStereoType1 )||
1027
- p2 && (cBondType != at[a2].bond_type[n2] || at[a2].bond_stereo[n2] != cStereoType2 ) ) {
1028
- MOLFILE_ERR_SET (*err, 0, "Multiple bonds between two atoms");
1029
- *err |= 2; /* multiple bonds between atoms */
1030
- } else {
1031
- MOLFILE_ERR_SET (*err, 0, "Duplicated bond(s) between two atoms");
1032
- /* warning */
1033
- }
1034
- } else
1035
- if ( !p1 && !p2 && at[a1].valence < MAXVAL && at[a2].valence < MAXVAL ) {
1036
- n1 = at[a1].valence ++;
1037
- n2 = at[a2].valence ++;
1038
- (*nNumBonds) ++;
1039
- } else {
1040
- char szMsg[64];
1041
- *err |= 4; /* too large number of bonds. Some bonds ignored. */
1042
- sprintf( szMsg, "Atom '%s' has more than %d bonds",
1043
- at[a1].valence>= MAXVAL? at[a1].elname:at[a2].elname, MAXVAL );
1044
- MOLFILE_ERR_SET (*err, 0, szMsg);
1045
- goto err_exit;
1046
- }
1047
-
1048
- /* store the connection */
1049
-
1050
- /* bond type */
1051
- at[a1].bond_type[n1] =
1052
- at[a2].bond_type[n2] = cBondType;
1053
- /* connection */
1054
- at[a1].neighbor[n1] = (AT_NUMB)a2;
1055
- at[a2].neighbor[n2] = (AT_NUMB)a1;
1056
- /* stereo */
1057
- at[a1].bond_stereo[n1] = cStereoType1; /* >0: the wedge (pointed) end is at this atom */
1058
- at[a2].bond_stereo[n2] = cStereoType2; /* <0: the wedge (pointed) end is at the opposite atom */
1059
- return 0;
1060
- err_exit:
1061
- return 1;
1062
- }
1063
- /******************************************************************/
1064
- int SetAtomAndBondProperties( inp_ATOM *at, inchi_Atom *ati, int a1,
1065
- int bDoNotAddH, char *pStrErr, int *err )
1066
- {
1067
- int valence, chem_valence, num_alt_bonds, j, n1;
1068
- int nRadical, nCharge;
1069
- static int el_number_H = 0;
1070
-
1071
- if ( !el_number_H ) {
1072
- el_number_H = get_periodic_table_number( "H" );
1073
- }
1074
-
1075
- nRadical = nCharge = 0;
1076
- valence = at[a1].valence;
1077
- chem_valence = num_alt_bonds = 0;
1078
- for ( j = 0; j < valence; j ++ ) {
1079
- if ( at[a1].bond_type[j] <= BOND_TYPE_TRIPLE ) {
1080
- chem_valence += at[a1].bond_type[j];
1081
- } else {
1082
- num_alt_bonds ++;
1083
- }
1084
- }
1085
- switch( num_alt_bonds ) {
1086
- case 0:
1087
- break;
1088
- case 2:
1089
- chem_valence += 3; /* -C= */
1090
- break;
1091
- case 3:
1092
- chem_valence += 4; /* >C= */
1093
- break;
1094
- default:
1095
- {
1096
- char szMsg[64];
1097
- *err |= 8; /* wrong number of alt. bonds */
1098
- sprintf( szMsg, "Atom '%s' has %d alternating bonds",
1099
- at[a1].elname, num_alt_bonds );
1100
- MOLFILE_ERR_SET (*err, 0, szMsg);
1101
- }
1102
- break;
1103
- }
1104
- at[a1].chem_bonds_valence = chem_valence;
1105
-
1106
- /* aliased hydrogen atoms */
1107
- if ( ERR_ELEM == (n1 = get_periodic_table_number( at[a1].elname ) ) ) {
1108
- /* Case when elname contains more than 1 element: extract number of H if possible */
1109
- if ( extract_ChargeRadical( at[a1].elname, &nRadical, &nCharge ) ) {
1110
- if ( nRadical && at[a1].radical && nRadical != at[a1].radical ||
1111
- nCharge && at[a1].charge && nCharge != at[a1].charge ) {
1112
- MOLFILE_ERR_SET (*err, 0, "Ignored charge/radical redefinition:");
1113
- MOLFILE_ERR_SET (*err, 0, ati[a1].elname);
1114
- } else {
1115
- if ( nRadical )
1116
- at[a1].radical = nRadical;
1117
- if ( nCharge )
1118
- at[a1].charge = nCharge;
1119
- }
1120
- }
1121
- at[a1].num_H = extract_H_atoms( at[a1].elname, at[a1].num_iso_H );
1122
- if ( !at[a1].elname[0] && NUMH(at, a1) ) {
1123
- /* alias contains only H. Added 2004-07-21, fixed 2004-07-22
1124
- * move the heaviest isotope to the "central atom"
1125
- * Note: this must be consistent with H-H treatment in remove_terminal_HDT()
1126
- */
1127
- strcpy( at[a1].elname, "H" );
1128
- if ( NUM_ISO_H(at,a1) ) {
1129
- for ( j = NUM_H_ISOTOPES-1; 0 <= j; j -- ) {
1130
- if ( at[a1].num_iso_H[j] ) {
1131
- at[a1].num_iso_H[j] --;
1132
- at[a1].iso_atw_diff = 1 + j;
1133
- break;
1134
- }
1135
- }
1136
- } else {
1137
- at[a1].num_H --;
1138
- }
1139
- }
1140
- if ( ERR_ELEM == (n1 = get_periodic_table_number( at[a1].elname ) ) ) {
1141
- n1 = 0;
1142
- }
1143
- if ( n1 ) {
1144
- at[a1].at_type |= 1; /* "Aliased" atom: data in the element name */
1145
- MOLFILE_ERR_SET (*err, 0, "Parsed compound atom(s):");
1146
- MOLFILE_ERR_SET (*err, 0, ati[a1].elname);
1147
- }
1148
- }
1149
-
1150
- at[a1].el_number = (U_CHAR) n1;
1151
- if ( !n1 ) {
1152
- *err |= 64; /* Unrecognized aromatic bond(s) replaced with single */
1153
- MOLFILE_ERR_SET (*err, 0, "Unknown element(s):");
1154
- MOLFILE_ERR_SET (*err, 0, at[a1].elname);
1155
- } else
1156
- /* replace explicit D or T with isotopic H (added 2003-06-02) */
1157
- if ( el_number_H == n1 && !at[a1].iso_atw_diff ) {
1158
- switch( at[a1].elname[0] ) {
1159
- case 'D':
1160
- at[a1].iso_atw_diff = 2;
1161
- mystrncpy( at[a1].elname, "H", sizeof(at->elname) );
1162
- break;
1163
- case 'T':
1164
- at[a1].iso_atw_diff = 3;
1165
- mystrncpy( at[a1].elname, "H", sizeof(at->elname) );
1166
- break;
1167
- case 'H':
1168
- if ( 1 <= ati[a1].isotopic_mass ) {
1169
- AT_NUM iso_atw_diff;
1170
- if ( ISOTOPIC_SHIFT_FLAG - ISOTOPIC_SHIFT_MAX <= ati[a1].isotopic_mass &&
1171
- ISOTOPIC_SHIFT_FLAG + ISOTOPIC_SHIFT_MAX >= ati[a1].isotopic_mass ) {
1172
- /* ati[a1].isotopic_mass is isotopic iso_atw_diff + ISOTOPIC_SHIFT_FLAG */
1173
- iso_atw_diff = ati[a1].isotopic_mass - ISOTOPIC_SHIFT_FLAG;
1174
- } else {
1175
- /* ati[a1].isotopic_mass is isotopic mass */
1176
- iso_atw_diff = get_atw_from_elnum( (int) at[a1].el_number );
1177
- iso_atw_diff = ati[a1].isotopic_mass - iso_atw_diff;
1178
- }
1179
- if ( iso_atw_diff >= 0 )
1180
- iso_atw_diff ++;
1181
- /* reproduce Bug04: allowed non-terminal H heavier than T */
1182
- if ( 1 <= iso_atw_diff &&
1183
- (at[a1].valence != 1 || iso_atw_diff <= NUM_H_ISOTOPES) ) {
1184
- at[a1].iso_atw_diff = (S_CHAR)iso_atw_diff;
1185
- }
1186
- }
1187
- }
1188
- } else
1189
- /* isotopic shift */
1190
- if ( ati[a1].isotopic_mass ) {
1191
- AT_NUM iso_atw_diff;
1192
- if ( ISOTOPIC_SHIFT_FLAG - ISOTOPIC_SHIFT_MAX <= ati[a1].isotopic_mass &&
1193
- ISOTOPIC_SHIFT_FLAG + ISOTOPIC_SHIFT_MAX >= ati[a1].isotopic_mass ) {
1194
- /* ati[a1].isotopic_mass is isotopic iso_atw_diff + ISOTOPIC_SHIFT_FLAG */
1195
- iso_atw_diff = ati[a1].isotopic_mass - ISOTOPIC_SHIFT_FLAG;
1196
- } else {
1197
- /* ati[a1].isotopic_mass is isotopic mass */
1198
- iso_atw_diff = get_atw_from_elnum( (int) at[a1].el_number );
1199
- iso_atw_diff = ati[a1].isotopic_mass - iso_atw_diff;
1200
- }
1201
- if ( iso_atw_diff >= 0 )
1202
- iso_atw_diff ++;
1203
- at[a1].iso_atw_diff = (S_CHAR)iso_atw_diff;
1204
- }
1205
-
1206
- /* add implicit hydrogen atoms flag */
1207
-
1208
- if ( ati[a1].num_iso_H[0] == -1 ) {
1209
- if ( !bDoNotAddH ) {
1210
- at[a1].at_type |= 2; /* user requested to add H */
1211
- }
1212
- } else {
1213
- at[a1].num_H = ati[a1].num_iso_H[0];
1214
- }
1215
- for ( j = 0; j < NUM_H_ISOTOPES; j ++ ) {
1216
- at[a1].num_iso_H[j] = ati[a1].num_iso_H[j+1];
1217
- }
1218
- if ( num_alt_bonds ) {
1219
- /* atom has aromatic bonds AND the chemical valence is not known */
1220
- int num_H = NUMH(at, a1);
1221
- int chem_valence_alt = at[a1].chem_bonds_valence + num_H;
1222
- int bUnusualValenceArom =
1223
- detect_unusual_el_valence( (int)at[a1].el_number, at[a1].charge,
1224
- at[a1].radical, chem_valence_alt,
1225
- num_H, at[a1].valence );
1226
- int bUnusualValenceNoArom =
1227
- detect_unusual_el_valence( (int)at[a1].el_number, at[a1].charge,
1228
- at[a1].radical, chem_valence_alt-1,
1229
- num_H, at[a1].valence );
1230
- if ( bUnusualValenceArom && !bUnusualValenceNoArom ) {
1231
- /* typically NH in 5-member aromatic ring */
1232
- at[a1].chem_bonds_valence --;
1233
- }
1234
- }
1235
-
1236
- return 0;
1237
- }
1238
- /****************************************************************************************/
1239
- int ExtractOneStructure( STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle,
1240
- inchi_Input *inp, INCHI_FILE *log_file, INCHI_FILE *output_file,
1241
- INCHI_FILE *prb_file, ORIG_ATOM_DATA *orig_inp_data, int *num_inp,
1242
- char *pStr, int nStrLen )
1243
- {
1244
- int *err = &sd->nStructReadError;
1245
- char *pStrErr = sd->pStrErrStruct;
1246
- inp_ATOM *at = NULL;
1247
- MOL_COORD *szCoord = NULL;
1248
- inchi_Atom *ati = NULL;
1249
- int nNumAtoms = 0;
1250
- int a1, j, valence, nDim, nNumBonds, nRet = 0;
1251
-
1252
- /********************************************************
1253
- *
1254
- * Extract the structure
1255
- *
1256
- ********************************************************/
1257
-
1258
- FreeOrigAtData( orig_inp_data );
1259
- nDim = 0;
1260
- nNumBonds = 0;
1261
-
1262
- if ( !inp || (nNumAtoms = inp->num_atoms) <= 0 || !(ati = inp->atom) ) {
1263
- MOLFILE_ERR_SET (*err, 0, "Empty structure");
1264
- *err = 98;
1265
- goto err_exit;
1266
- }
1267
- if ( nNumAtoms >= MAX_ATOMS ) {
1268
- MOLFILE_ERR_SET (*err, 0, "Too many atoms");
1269
- *err = 70;
1270
- orig_inp_data->num_inp_atoms = -1;
1271
- goto err_exit;
1272
- }
1273
-
1274
- at = (inp_ATOM *) inchi_calloc( nNumAtoms, sizeof(at[0]) );
1275
- szCoord = (MOL_COORD *) inchi_calloc (inchi_max(nNumAtoms, 1), sizeof (MOL_COORD));
1276
-
1277
- if ( !at || !szCoord ) {
1278
- MOLFILE_ERR_SET (*err, 0, "Out of RAM");
1279
- *err = -1;
1280
- goto err_exit;
1281
- }
1282
- /********************************************************
1283
- *
1284
- * Extract typical for Molfile structural data
1285
- *
1286
- ********************************************************/
1287
- /* extract atoms and bonds */
1288
- for ( a1 = 0; a1 < nNumAtoms; a1 ++ ) {
1289
- /* extract atoms */
1290
- SetAtomProperties( at, szCoord, ati, a1, &nDim, pStrErr, err );
1291
- if ( *err ) {
1292
- goto err_exit;
1293
- }
1294
- /* extract connections */
1295
- valence = ati[a1].num_bonds;
1296
- for ( j = 0; j < valence; j ++ ) {
1297
- SetBondProperties( at, ati, a1, j, nNumAtoms, &nNumBonds, pStrErr, err );
1298
- }
1299
- if ( *err ) {
1300
- goto err_exit;
1301
- }
1302
- }
1303
-
1304
- orig_inp_data->num_inp_atoms = nNumAtoms;
1305
- orig_inp_data->num_inp_bonds = nNumBonds;
1306
- orig_inp_data->num_dimensions = nDim;
1307
-
1308
- /* extract elements, chemical valences, implicit H, isotopic shifts */
1309
- for ( a1 = 0; a1 < nNumAtoms; a1 ++ ) {
1310
- /* set temp flags in at[a1].at_type (1: data in atom name; 2: request to add H) */
1311
- SetAtomAndBondProperties( at, ati, a1, ip->bDoNotAddH, pStrErr, err );
1312
- if ( *err ) {
1313
- goto err_exit;
1314
- }
1315
- }
1316
- /* clear temp flags in at[].at_type; add implicit H */
1317
- SetNumImplicitH( at, nNumAtoms );
1318
- if ( *err ) {
1319
- goto err_exit;
1320
- }
1321
-
1322
- /********************************************************
1323
- *
1324
- * Extract the 0D parities (typical for CML)
1325
- *
1326
- ********************************************************/
1327
- Extract0DParities( at, nNumAtoms, inp->stereo0D, inp->num_stereo0D, pStrErr, err );
1328
- if ( *err ) {
1329
- goto err_exit;
1330
- }
1331
- orig_inp_data->at = at; at = NULL;
1332
- orig_inp_data->num_dimensions = nDim;
1333
- orig_inp_data->num_inp_atoms = nNumAtoms;
1334
- orig_inp_data->num_inp_bonds = nNumBonds;
1335
- orig_inp_data->szCoord = szCoord; szCoord = NULL;
1336
-
1337
- /* chiral flag */
1338
- /* *****************************************************************************
1339
- * Chiral flags are set in:
1340
- * - RunICHI.c #1610 -- ReadTheStructure() -- cInChI, wInChI
1341
- * - e_IchiMain.c #273 -- main() -- C example of calling InChI dll
1342
- * - inchi_dll.c #1662 -- ExtractOneStructure -- InChI dll code (here)
1343
- *******************************************************************************/
1344
- if ( (ip->nMode & REQ_MODE_CHIR_FLG_STEREO) && (ip->nMode & REQ_MODE_STEREO) ) {
1345
- if ( ip->bChiralFlag & FLAG_SET_INP_AT_CHIRAL ) {
1346
- /* absolute stereo */
1347
- ip->nMode &= ~(REQ_MODE_RELATIVE_STEREO | REQ_MODE_RACEMIC_STEREO);
1348
- sd->bChiralFlag &= ~FLAG_INP_AT_NONCHIRAL;
1349
- sd->bChiralFlag |= FLAG_INP_AT_CHIRAL; /* write AuxInfo as chiral */
1350
- } else
1351
- /*if ( ip->bChiralFlag & FLAG_SET_INP_AT_NONCHIRAL )*/ {
1352
- /* relative stereo */
1353
- ip->nMode &= ~(REQ_MODE_RACEMIC_STEREO);
1354
- ip->nMode |= REQ_MODE_RELATIVE_STEREO;
1355
- sd->bChiralFlag &= ~FLAG_INP_AT_CHIRAL;
1356
- sd->bChiralFlag |= FLAG_INP_AT_NONCHIRAL; /* write AuxInfo as non-chiral */
1357
- }
1358
- } else
1359
- if ( ip->bChiralFlag & FLAG_SET_INP_AT_CHIRAL ) {
1360
- sd->bChiralFlag &= ~FLAG_INP_AT_NONCHIRAL;
1361
- sd->bChiralFlag |= FLAG_INP_AT_CHIRAL; /* write AuxInfo as chiral */
1362
- } else
1363
- if ( ip->bChiralFlag & FLAG_SET_INP_AT_NONCHIRAL ) {
1364
- sd->bChiralFlag &= ~FLAG_INP_AT_CHIRAL;
1365
- sd->bChiralFlag |= FLAG_INP_AT_NONCHIRAL; /* write AuxInfo as non-chiral */
1366
- }
1367
-
1368
- *num_inp += 1;
1369
-
1370
- err_exit:
1371
-
1372
- if ( at )
1373
- inchi_free( at );
1374
- if ( szCoord )
1375
- inchi_free( szCoord );
1376
-
1377
- nRet = TreatReadTheStructureErrors( sd, ip, LOG_MASK_NO_WARN, NULL, log_file, output_file, prb_file,
1378
- orig_inp_data, num_inp, pStr, nStrLen );
1379
-
1380
- return nRet;
1381
-
1382
- }
1383
- /********************************************************/
1384
- int INCHI_DECL GetStringLength( char *p )
1385
- {
1386
- if ( p ) {
1387
- return strlen(p);
1388
- } else {
1389
- return 0;
1390
- }
1391
- }
1392
- #if( defined( _WIN32 ) && defined( _MSC_VER ) && _MSC_VER >= 800 && defined(_USRDLL) && defined(INCHI_LINK_AS_DLL) )
1393
- /* Win32 & MS VC ++, compile and link as a DLL */
1394
- /*********************************************************/
1395
- /* C calling conventions export from Win32 dll */
1396
- /*********************************************************/
1397
- /* prototypes */
1398
- int cdecl_GetINCHI( inchi_Input *inp, inchi_Output *out );
1399
- void cdecl_FreeINCHI( inchi_Output *out );
1400
- int cdecl_GetStringLength( char *p );
1401
- int cdecl_Get_inchi_Input_FromAuxInfo
1402
- ( char *szInchiAuxInfo, int bDoNotAddH, InchiInpData *pInchiInp );
1403
- void cdecl_Free_inchi_Input( inchi_Input *pInp );
1404
-
1405
- /* implementation */
1406
- /* vc6_libinchi.def provides export withou cdecl_ prefixes */
1407
- /********************************************************/
1408
- int cdecl_GetINCHI( inchi_Input *inp, inchi_Output *out )
1409
- {
1410
- return GetINCHI( inp, out );
1411
- }
1412
- /********************************************************/
1413
- void cdecl_FreeINCHI( inchi_Output *out )
1414
- {
1415
- FreeINCHI( out );
1416
- }
1417
- /********************************************************/
1418
- int cdecl_GetStringLength( char *p )
1419
- {
1420
- return GetStringLength( p );
1421
- }
1422
- /********************************************************/
1423
- int cdecl_Get_inchi_Input_FromAuxInfo
1424
- ( char *szInchiAuxInfo, int bDoNotAddH, InchiInpData *pInchiInp )
1425
- {
1426
- return Get_inchi_Input_FromAuxInfo
1427
- ( szInchiAuxInfo, bDoNotAddH, pInchiInp );
1428
- }
1429
- /********************************************************/
1430
- void cdecl_Free_inchi_Input( inchi_Input *pInp )
1431
- {
1432
- Free_inchi_Input( pInp );
1433
- }
1434
- #endif
1435
-
1436
- #if( defined(__GNUC__) && __GNUC__ >= 3 && defined(__MINGW32__) && defined(_WIN32) )
1437
- #include <windows.h>
1438
- /*********************************************************/
1439
- /* Pacal calling conventions export from Win32 dll */
1440
- /*********************************************************/
1441
- /* prototypes */
1442
- int PASCAL pasc_GetINCHI( inchi_Input *inp, inchi_Output *out );
1443
- void PASCAL pasc_FreeINCHI( inchi_Output *out );
1444
- int PASCAL pasc_GetStringLength( char *p );
1445
- int PASCAL pasc_Get_inchi_Input_FromAuxInfo
1446
- ( char *szInchiAuxInfo, int bDoNotAddH, InchiInpData *pInchiInp );
1447
- void PASCAL pasc_Free_inchi_Input( inchi_Input *pInp );
1448
-
1449
- /* implementation */
1450
- /* vc6_libinchi.def provides export withou PASCAL pasc_ prefixes */
1451
- /********************************************************/
1452
- int PASCAL pasc_GetINCHI( inchi_Input *inp, inchi_Output *out )
1453
- {
1454
- return GetINCHI( inp, out );
1455
- }
1456
- /********************************************************/
1457
- void PASCAL pasc_FreeINCHI( inchi_Output *out )
1458
- {
1459
- FreeINCHI( out );
1460
- }
1461
- /********************************************************/
1462
- int PASCAL pasc_GetStringLength( char *p )
1463
- {
1464
- return GetStringLength( p );
1465
- }
1466
- /********************************************************/
1467
- int PASCAL pasc_Get_inchi_Input_FromAuxInfo
1468
- ( char *szInchiAuxInfo, int bDoNotAddH, InchiInpData *pInchiInp )
1469
- {
1470
- return Get_inchi_Input_FromAuxInfo
1471
- ( szInchiAuxInfo, bDoNotAddH, pInchiInp );
1472
- }
1473
- /********************************************************/
1474
- void PASCAL pasc_Free_inchi_Input( inchi_Input *pInp )
1475
- {
1476
- Free_inchi_Input( pInp );
1477
- }
1478
- #endif
1479
-
1480
-