2
* International Chemical Identifier (InChI)
4
* Software version 1.03
7
* Originally developed at NIST
8
* Modifications and additions by IUPAC and the InChI Trust
10
* The InChI library and programs are free software developed under the
11
* auspices of the International Union of Pure and Applied Chemistry (IUPAC);
12
* you can redistribute this software and/or modify it under the terms of
13
* the GNU Lesser General Public License as published by the Free Software
15
* http://www.opensource.org/licenses/lgpl-2.1.php
34
BUILD TARGET IS DETERMINED BY THE FOLLOWING DEFINES:
36
if (defined) compile/build
37
------------- -------------
39
INCHI_LIBRARY library (libinchi) for using InChI API described in inchi_api.h
41
INCHI_LINK_AS_DLL INChI library as a Win32 DLL or to eliminate stricmp duplication
43
INCHI_MAIN INCHI_MAIN.exe that calls INCHI_DLL.dll
46
InChI stand-alone executable
60
/* make stand-alone command-line executable */
61
/* #define INCHI_STANDALONE_EXE 1 */
63
/* uncomment to create a library for using INChI API described in inchi_api.h */
66
/* uncomment to use INChI library as a Win32 DLL or to eliminate stricmp duplication */
67
/* #define INCHI_LINK_AS_DLL */
69
/* Uncomment to compile INCHI_MAIN.exe that calls INCHI_DLL.dll */
70
/* #define INCHI_MAIN */
73
/* Uncomment to show engineering options in help screen */
74
/* #define ENABLE_ENGINEERING_OPTIONS 1 */
76
/* uncomment to unconditionally force ANSI-89 C, no Win32 specific code */
77
/* #define INCHI_ANSI_ONLY */
79
#ifdef INCHI_ANSI_ONLY
80
/*#define ADD_NON_ANSI_FUNCTIONS */ /* uncomment to add stricmp(), etc., see util.c */
84
#if(!defined(_MSC_VER) || defined(INCHI_LIBRARY)) /* non-Microsoft GNU C, BCC, etc. compilers */
85
#ifndef INCHI_ANSI_ONLY
86
#define INCHI_ANSI_ONLY
90
/*#define INCHI_ALL_CPP*/ /* uncomment to allow C++ compilation/linkage of functions prototyped in .h files */
94
========== disable MS VC++ 6.0 Level 4 compiler warnings: ==============
95
C4706: assignment within conditional expression
96
C4127: conditional expression is constant
97
C4244: '=' : conversion from 'int ' to '???', possible loss of data
98
C4701: local variable '???' may be used without having been initialized (removed)
99
C4514: unreferenced inline/local function has been removed (C++)
100
C4100: 'identifier' : unreferenced formal parameter
101
C4786: 'identifier' : identifier was truncated to 'number' characters in the debug information
102
C4996: 'identifier' was declared deprecated
103
========================================================================
105
#pragma warning( disable : 4706 4127 4514 4100 4786 4996 )
109
#define BUILD_INFO ", Software version 1.03"
112
#define bRELEASE_VERSION 1 /* 1=> release version; comment out to disable */
114
#ifndef bRELEASE_VERSION
115
#define bRELEASE_VERSION 0 /* 0=> debug version */
119
/* this allows ADD_CMLPP be #defined in a makefile */
120
#define ADD_CMLPP 0 /* 1 => add CMLPP input */
123
#if ( ADD_CMLPP == 1 )
125
/* 1200 is VC++ 6.0 version, 1300 is VC++ .NET; USE_CMLPPDLL may be #defined in a makefile*/
126
#if ( defined(_WIN32) && defined(_MSC_VER) && _MSC_VER >= 1200 )
127
#define MSC_DELAY_LOAD_CMLPPDLL
132
/* display (non-canonical) c-groups, display orig at numbers */
133
#if( bRELEASE_VERSION == 1 )
134
#define DISPLAY_DEBUG_DATA_C_POINT 0 /* disabled release version for now */
135
#define DISPLAY_ORIG_AT_NUMBERS 1 /* 1 => in an uncanonicalized components display orig. atom numbers (default) */
137
#define DISPLAY_DEBUG_DATA_C_POINT 1 /* debug: 1=>display (non-canonically numbered) c-groups, 0=>do not display */
138
#define DISPLAY_ORIG_AT_NUMBERS 1 /* 0 => in an uncanonicalized components display ordering atom numbers (debug) */
141
#if ( DISPLAY_DEBUG_DATA_C_POINT > 0 )
142
#define DISPLAY_DEBUG_DATA DISPLAY_DEBUG_DATA_C_POINT
146
/**************************/
147
/* bug fixes in v1.00 */
148
/**************************/
149
#define FIX_ChCh_STEREO_CANON_BUG 1 /* 1=> (NEEDED) */
150
#define ADD_ChCh_STEREO_CANON_CHK 0 /* 1 is NOT needed; let it always be 0 */
151
#define FIX_ChCh_CONSTIT_CANON_BUG 1 /* 1=> (NEEDED) */
152
#define FIX_EITHER_STEREO_IN_AUX_INFO 1 /* 1=> fix bug: Either stereobond direction in Aux_Info; 0=> do not fix */
153
#define FIX_NORM_BUG_ADD_ION_PAIR 1 /* 1=> (NEEDED) fix bug: Miscount number of charges when creating an ion pair */
154
#define FIX_REM_PROTON_COUNT_BUG 1 /* 1=> (NEEDED) check for number of actually removed protons and issue an error if mismatch */
155
#define FIX_READ_AUX_MEM_LEAK 1
156
#define FIX_READ_LONG_LINE_BUG 1 /* 1=> (NEEDED) prevent failure when reading AuxInfo and InChI is too long */
157
#define FIX_N_V_METAL_BONDS_GPF 1 /* 1=> (NEEDED) InChI v1 GPF bug fix */
158
#define BNS_RAD_SEARCH 1 /* 1=> prevent normalization failures due to radical centers */
160
/*******************************/
161
/* bug fixes in post-v1.00 */
162
/*******************************/
163
#define FIX_ODD_THINGS_REM_Plus_BUG 0
164
#define FIX_N_MINUS_NORN_BUG 0
165
#define FIX_CANCEL_CHARGE_COUNT_BUG 0
166
#define FIX_2D_STEREO_BORDER_CASE 0
167
#define FIX_REM_ION_PAIRS_Si_BUG 0
168
#define FIX_STEREO_SCALING_BUG 0
169
#define FIX_EMPTY_LAYER_BUG 0
170
#define FIX_EITHER_DB_AS_NONSTEREO 0
171
#define FIX_BOND23_IN_TAUT 0
172
#define FIX_TACN_POSSIBLE_BUG 0
173
#define FIX_KEEP_H_ON_NH_ANION 0
174
#define FIX_AVOID_ADP 0
175
/* may change InChI */
176
#define FIX_NUM_TG 0 /* increase number of t-groups for isothiocyanate */
177
/* changes InChI for isothiocyanate */
178
#define FIX_CPOINT_BOND_CAP2 0
180
/*******************************/
181
/* bug fixes in post-v1.02b */
182
/*******************************/
184
#define FIX_ISO_FIXEDH_BUG 1 /* (2007-09-24) 1=> Fix bug: missing fixed-H iso segment in case of single removed D(+) */
185
#define FIX_ISO_FIXEDH_BUG_READ 0 /* (2007-09-24) 1=> Accommodate this InChI bug in reading InChI */
186
#define FIX_DALKE_BUGS 1
187
#define FIX_TRANSPOSITION_CHARGE_BUG 1 /* (2008-01-02) fix bug that leads to missed charge in some cases when /o is present */
188
#define FIX_I2I_STEREOCONVERSION_BUG 1 /* (2008-03-06) 1=> Fix bug of i2i conversion SAbs-->(SRel||Srac) */
189
#define FIX_I2I_STEREOCONVERSION_BUG2 1 /* (2008-04-02) 1=> Fix bug of i2i conversion (missed empty /t) */
190
#define FIX_I2I_STEREOCONVERSION_BUG3 1 /* (2008-04-10) 1=> Fix bug of i2i conversion */
191
/* (missed repeating /s in FI after F for multi-component case) */
192
#define FIX_TERM_H_CHRG_BUG 1 /* (2008-06-06) IPl) */
193
/* fix bug: in some cases (dependent on ordering
194
numbers), moving a charge from terminal H to heavy
195
atom resulted in neutralizing H but not adjusting
196
charge of heavy atom */
199
#if( !defined(INCHI_LIBRARY) && !defined(INCHI_MAIN) )
200
#define I2S_MODIFY_OUTPUT 1 /* 1=> Allow various InChI2InChI output types from cInChI */
202
#define I2S_MODIFY_OUTPUT 0 /* 0=> Always */
205
#define FIX_NP_MINUS_BUG 1 /* 2010-03-11 DCh */
207
/**************************/
208
/* additions to v1.00 */
209
/**************************/
210
#define FIX_ADJ_RAD 0
212
#define SDF_OUTPUT_V2000 1 /* 1=>always output V2000 SDfile, 0=>only if needed */
213
#define SDF_OUTPUT_DT 1 /* 1=> all option -SdfAtomsDT to output D and T into SDfile */
214
#define CHECK_AROMBOND2ALT 1 /* 1=> check whether arom->alt bond conversion succeeded */
217
#define READ_INCHI_STRING 0 /* 1=> input InChI string and process it */
219
#define READ_INCHI_STRING 1 /* 1=> input InChI string and process it */
222
/****************************************************/
223
/* disabled extra external calls to InChI algorithm */
224
/****************************************************/
225
#define INCLUDE_NORMALIZATION_ENTRY_POINT 0
227
/**************************/
228
/* Normalization settings */
229
/**************************/
231
/* post version 1 features */
232
#define KETO_ENOL_TAUT 1 /* include keto-enol tautomerism */
233
#define TAUT_15_NON_RING 1 /* 1,5 tautomerism with endpoints not in ring */
235
/* v.1.03 : still experimental but may be exposed (set to 1) */
236
#define UNDERIVATIZE 0 /* split to possible underivatized fragments */
237
#define RING2CHAIN 0 /* open rings R-C(-OH)-O-R => R-C(=O) OH-R */
239
/* post-2004-04-27 features */
240
#define HAL_ACID_H_XCHG 1 /* allow iso H exchange to HX (X=halogen) and H2Y (Y=halcogen) */
241
#define CANON_FIXH_TRANS 1 /* produce canonical fixed-H transposition */
242
#define STEREO_WEDGE_ONLY 1 /* 1=> only pointed ends stereo bonds define stereo; 0=> both ends */
244
/* current new (with respect to v1.12 Beta) preprocessing */
245
#define REMOVE_ION_PAIRS_EARLY 1 /* 1=> new preprocessing: step 1 before disconnecting metals in fix_odd_things() */
246
#define REMOVE_ION_PAIRS_DISC_STRU 1 /* 1=> new post-preprocessing: remove charhes after metal disconnection */
247
#define REMOVE_ION_PAIRS_FIX_BONDS 1 /* 1=> step2: set unchangeable bonds around removed ion pairs */
248
#define S_VI_O_PLUS_METAL_FIX_BOND 1 /* 1=> count double bond M-O(+)=S as O=S in S(VI) ans S(VIII) fixing bonds */
249
#define N_V_STEREOBONDS 1 /* 1=> detect stereobonds incident to N(V); 0 => don't */
251
#define REMOVE_ION_PAIRS_ORIG_STRU 0 /* 0=> normal mode (default)
252
* 1=> testing mode only: remove ion pairs from the original structure
253
* to save the changes in the output Molfile (/OutputSDF) or AuxInfo
256
/* salts treatment */
257
#define DISCONNECT_SALTS 1 /* 1=>disconnect metal atoms from salts, 0=>dont */
258
#define TEST_REMOVE_S_ATOMS 1 /* 1=>default: after merging into one group test &
259
* remove unreachable,
260
* 0=> old version: test only before merging into one t-group */
261
#define CHARGED_SALTS_ONLY 1 /* 1=>(default)do not test far salts tautomerism if
262
* no negative charge(s) present */
263
#define BNS_PROTECT_FROM_TAUT 1 /* 1=> do not allow testing of bonds to acetyl or nitro */
264
#define BNS_MARK_EDGE_2_DISCONNECT 1 /* 1=> mark edge as temp forbidden instead of disconnection */
266
#define REPLACE_ALT_WITH_TAUT 1 /* 1 => replace alt bonds with tautomeric bonds in case of standard t-groups */
267
#define MOVE_CHARGES 1 /* 1 => take moveable charges into account */
268
#define NEUTRALIZE_ENDPOINTS 1 /* 1 => before checking whether an H is moveable make 2 endpoints neutral */
269
/* implemented only if CHECK_TG_ALT_PATH = 0, defined in ichi_bns.c */
270
#define FIX_H_CHECKING_TAUT 1 /* 1 => Fix moveable H or (-) before checking if taut. exchange is possible */
271
#define ALWAYS_ADD_TG_ON_THE_FLY 1 /* 1 => disables radical calcellation by taut-charge movement */
272
#define IGNORE_SINGLE_ENDPOINTS 1 /* 1 => see FindAccessibleEndPoints() in INChITaut.c */
274
/* recently added -- begin */
275
#define INCL_NON_SALT_CANDIDATATES 1 /* 1=> allow H and (-) migrate between "acidic" O and
276
* other possible endpoints */
277
#define SALT_WITH_PROTONS 1 /* 1=> (new new) include proton migrarion C-SH, =C-OH, NH+ */
278
#define OPPOSITE_CHARGE_IN_CGROUP 1 /* 1=> allow N(-) in (+) c-group, 0=> disallow */
279
#define MOVE_PPLUS_TO_REMOVE_PROTONS 0 /* 0=> default; 1=> (disabled) add P/P+ charge group during
280
* 'hard' proton removal */
281
#define ADD_MOVEABLE_O_PLUS 1 /* 1=> allow charges on O(+) to move */
282
/* recently added -- end */
284
#define DISCONNECT_METALS 1 /* make main layer disconnected */
285
#define RECONNECT_METALS 0 /* 1=> by default add reconnected layer in case of coord.
286
* compound disconnection */
287
#define CHECK_METAL_VALENCE 0 /* 1=> disconnect only metals that have abnormal valence */
288
#define bREUSE_INCHI 1 /* 1=> do not recalulate INChI for components in reconnected
289
* structure that are same as in the connected one */
290
#define OUTPUT_CONNECTED_METAL_ONLY 0 /* 0=> default; 1 => (debug) create only reconnected or
291
* initial struct. output */
292
#define EMBED_REC_METALS_INCHI 1 /* 1=> (default) output Reconnected embedded in Disconnected INChI;
293
* 0=> separate output */
295
#define bOUTPUT_ONE_STRUCT_TIME 1 /* 1 => output each structure time (non-release only) */
298
/*#define INCHI_VERSION "0.9Beta" */
299
/*#define INCHI_VERSION "0.91Beta" */ /* 10-10-2002: sent to Jonathan Goodman */
300
/*#define INCHI_VERSION "0.92Beta" */ /* 11-15-2002: added Hill notation; sent to S.Heller & S.Stein */
301
/*#define INCHI_VERSION "0.93Beta" */ /* 12-09-2002: Fixed isotopic canon. bug & chiralanes; sent to S.Heller & A. McNaught */
302
/*#define INCHI_VERSION "0.931Beta" */ /* Non-BNS without salts released to PMR 01-2003 */
303
/*#define INCHI_VERSION "0.932Beta" */ /* Released to CAS 04-01-2003:
304
* - Improved taut. definitions as compared to 01-2003;
305
* - fixed bug: non-isotopic components' stereo missing from isotopic stereo
306
* - fixed bug: couldn't properly read Unix files (EOL = LF instead of CR/LF)
307
* (effective only for MS VC++, Borland and MinGW/GCC compiles that accept "rb" mode of fopen)
308
* DJGPP/GCC does not seem to need this fix.
310
/*==== Release version ===*/
311
/*#define INCHI_VERSION "0.94Beta" */ /* 02-27-2003: Balanced network search to find alt paths and non-stereo bonds;
312
Implemented salts disconnection; added (-) to taut groups */
313
/*#define INCHI_VERSION "1.12Beta" */ /* 1.12: 07-06-2004: sort order: No H formula,..; Pointed end stereo ON, Aggressive (de)protonation OFF */
314
/* 1.11: 05-19-2004: annotated plain text output, fixed bugs */
315
/* 1.1: 04-08-2004: variable protonation version */
316
/* 1.01: 12-23-2003 protected bonds, isotopic canonicalization in GetBaseCanonRanking() */
317
/* 1.02: 01-26-2004 fixed new isotopic tgroup canon bug, molfile merge bug */
319
/*#define INCHI_VERSION "1.0RC"*/ /* 02-07-2005 v1.0 Release Candidate */
321
#define INCHI_VERSION "1"
322
#define INCHI_NAME "InChI"
323
#define INCHI_REC_NAME "ReChI"
325
#define INCHI_NAM_VER_DELIM "="
327
/* constants and array sizes */
329
#define INCHI_NUM 2 /* = array size; member indexes: */
330
#define INCHI_BAS 0 /* 0 => disconnected or normal */
331
#define INCHI_REC 1 /* 1 => reconnected */
333
#define TAUT_NUM 2 /* = array size; member indexes: */
334
#define TAUT_NON 0 /* 0 => normal structure */
335
#define TAUT_YES 1 /* 1 => tautomeric */
336
#define TAUT_INI 2 /* 2 => intermediate tautomeric structure */
337
#define ALT_TAUT(X) ((X)>TAUT_YES? TAUT_YES : 1-(X)) /* was (1-(X)) */
339
/* INChI output modes */
340
#define OUT_N1 0 /* non-tautomeric only */
341
#define OUT_T1 1 /* tautomeric if present otherwise non-tautomeric */
342
#define OUT_NT 2 /* only non-taut representations of tautomeric */
343
#define OUT_TN 3 /* tautomeric if present otherwise non-tautomeric;
344
separately output non-taut representations of tautomeric if present */
345
#define OUT_NN 4 /* only non-taut representations: non-taut else tautomeric */
347
/* OUT_TN = OUT_T1 + OUT_NT */
351
#define TEST_RENUMB_ATOMS 0 /* 1 => heavy duty test by multiple renumbering of atoms */
352
#define TEST_RENUMB_NEIGH 1 /* 1 => randomly permutate neighbors */
353
#define TEST_RENUMB_SWITCH 0 /* 1 => display & output another (different) picture */
354
#define TEST_RENUMB_ATOMS_SAVE_LONGEST 0 /* 1 => save the component with largest processing time into the problem file */
356
#if ( defined(_WIN32) && defined(_DEBUG) && defined(_MSC_VER) /*&& !defined(INCHI_ANSI_ONLY)*/ )
357
/* debug: memory leaks tracking */
360
#ifndef DO_NOT_TRACE_MEMORY_LEAKS
361
#define TRACE_MEMORY_LEAKS 1 /* 1=>trace, 0 => do not trace (Debug only) */
363
#define TRACE_MEMORY_LEAKS 0
368
#define TRACE_MEMORY_LEAKS 1 /* 1=>trace, **ALWAYS** =1 for INCHI_LIB */
372
#else /* not MSC and not Debug */
374
#define TRACE_MEMORY_LEAKS 0 /* 0: do not change */
380
#define NEW_STEREOCENTER_CHECK 1 /* 1 => add new stereocenter categories (see bCanInpAtomBeAStereoCenter(...)) */
381
#define MIN_SB_RING_SIZE 8 /* do not assume stereo bonds in rings containing 3..MIN_SB_RING_SIZE-1 atoms */
383
#define REMOVE_KNOWN_NONSTEREO 1 /* 1=> check in advance known stereo to remove parities from non-stereogenic elements */
384
#define REMOVE_CALC_NONSTEREO 1 /* 1=> check new stereo numberings to remove parities from non-stereogenic elements */
385
#define PROPAGATE_ILL_DEF_STEREO 1 /* 1=> if at least one of the pair of constitutionally identical (far) neighbors */
386
/* (of the tested atom) has ill-defined stereo parity and another has any */
387
/* stereo parity then set the parity of the tested atom to ill-defined value. */
389
#define ONLY_DOUBLE_BOND_STEREO 0 /* 1=> no alt bond stereo, no taut. bond attachment to stereo bond */
390
/* 0=> allow other definitions (below) to be active */
391
#define ONE_BAD_SB_NEIGHBOR 1 /* 1 => allow 1 "bad" bond type neighbor to a stereobond atom. 2004-06-02 */
393
/* more stereo settings */
394
#define BREAK_ONE_MORE_SC_TIE 1 /* break one more tie when comparing possible stereocenter neighbors */
395
#define BREAK_ALSO_NEIGH_TIE 0 /* post 1.12Beta 2004-08-20: if fixed neighbor has equ neighbors, fix the one with smaller canon. rank */
396
#define BREAK_ALSO_NEIGH_TIE_ROTATE 1 /* post 1.12Beta 2004-09-02: break the second in 2nd psition; 1 works, 0 does not (example:MFCD01085607) */
398
#define STEREO_CENTER_BONDS_NORM 1 /* set length of the bonds around a stereocenter = 1 before getting the parity */
399
#define STEREO_CENTER_BOND4_NORM 0 /* set length of the added bond around a stereocenter = 1 before getting the parity */
400
#define NORMALIZE_INP_COORD 0 /* 0=>keep unchanged, 1 => make atom coordinates integer values, avg bond len=20 */
403
#define STEREO_WEDGE_ONLY 1 /* 1=> only pointed ends stereo bonds define stereo; 0=> both ends 1.12Beta */
404
#define CHECK_C2v_S4_SYMM 0 /* post-1.12Beta 1=> check if a stereocenter has C2v or S4 symmetry; 0=>old mode */
406
#define EQL_H_NUM_TOGETHER 1 /* 1=> output 1-3,5H2 intead of 1-3H2,5H2 (CT_MODE_EQL_H_TOGETHER) */
407
#define ABC_CT_NUM_CLOSURES 1 /* 1=> in coinnections compressed format output decimal number of closures instead of '-' */
410
#define SINGLET_IS_TRIPLET 1 /* 'singlet' means two electrons make a lone pair instead of 2 bonds
411
its effect on valence is same as the effect of a triplet */
413
/* defug: find structures where canonical partition is different from equitable */
414
#define FIND_CANON_NE_EQUITABLE 0 /* 0=>normal mode */
415
/* 1=> extract (set EXTR_FLAGS = (EXTR_CANON_NE_EQUITABLE)*/
416
/* set cmd line options: /onlynonTAUT /: /UNCHARGEDACIDS:1 /DISCONSALT:0 /MOVEPOS:0 /DISCONMETAL:0 */
418
/* Debug: definitions for the extraction of the structures to the problem file */
420
/* definition of the flags for structure extraction to the
421
problem file (for debugging and non-standard searching) */
422
#define EXTR_KNOWN_USED_TO_REMOVE_PARITY 0x000001
423
#define EXTR_CALC_USED_TO_REMOVE_PARITY 0x000002
424
#define EXTR_2EQL2CENTER_TO_REMOVE_PARITY 0x000004
425
#define EXTR_HAS_ATOM_WITH_DEFINED_PARITY 0x000008
426
#define EXTR_REMOVE_PARITY_WARNING 0x000010
427
#define EXTR_SALT_WAS_DISCONNECTED 0x000020
428
#define EXTR_SALT_PROTON_MOVED 0x000040
429
#define EXTR_SALT_PROTON_MOVE_ERR_WARN 0x000080
430
#define EXTR_METAL_WAS_DISCONNECTED 0x000100
431
#define EXTR_METAL_WAS_NOT_DISCONNECTED 0x000200
432
#define EXTR_NON_TRIVIAL_STEREO 0x000400 /* (Inv != Abs stereo) && (parities can't be obtained by inverting them) */
433
#define EXTR_UNUSUAL_VALENCES 0x000800
434
#define EXTR_HAS_METAL_ATOM 0x001000
435
#define EXTR_TEST_TAUT3_SALTS_DONE 0x002000 /* non-oxygen t-points used to discover tautomerism of merged t-groups */
436
#define EXTR_CANON_NE_EQUITABLE 0x004000 /* find structures where canonical partition is different from equitable */
437
#define EXTR_HAS_PROTON_PN 0x008000 /* has movable H+ attached to N or P */
438
#define EXTR_HAS_FEATURE 0x010000 /* found a feature */
439
#define EXTR_TAUT_TREATMENT_CHARGES 0x020000 /* tautomeric treatment of charges */
440
#define EXTR_TRANSPOSITION_EXAMPLES 0x040000 /* extract structures that have different mobile-H and fixed-H orders */
442
/* define conditions of structure extraction to the problem file */
443
#define EXTR_MASK 0 /*EXTR_TAUT_TREATMENT_CHARGES*/ /*(EXTR_HAS_FEATURE)*/ /*(EXTR_UNUSUAL_VALENCES | EXTR_HAS_METAL_ATOM)*/ /* 0 to disable */
444
#define EXTR_FLAGS 0 /*EXTR_TAUT_TREATMENT_CHARGES*/ /*(EXTR_HAS_FEATURE)*/ /*(EXTR_HAS_PROTON_PN)*/ /*(EXTR_UNUSUAL_VALENCES)*/ /*(EXTR_CANON_NE_EQUITABLE)*/ /*(EXTR_TEST_TAUT3_SALTS_DONE)*/ /*(EXTR_HAS_METAL_ATOM)*/ /* (EXTR_NON_TRIVIAL_STEREO)*/ /*(EXTR_METAL_WAS_DISCONNECTED)*/ /* (EXTR_REMOVE_PARITY_WARNING)*/ /*(EXTR_HAS_ATOM_WITH_DEFINED_PARITY) */
447
#define ENTITY_REFS_IN_XML_MESSAGES 1 /* 1=> replace ' " < > & in error/warning messages with xml entity references */
449
/* added tautomeric structures */
451
#define TAUT_TROPOLONE_7 1 /* 1=> tautomeric 7-member rings ON */
452
#define TAUT_TROPOLONE_5 1 /* 1=> taut. similar to tropolone, 5-member ring */
453
#define TAUT_4PYRIDINOL_RINGS 1 /* 1=> OH-C5H4N rings tautomerism */
454
#define TAUT_PYRAZOLE_RINGS 1 /* 1=> tautomerizm in pyrazole rings */
455
/* limitation on tautomerism detection: */
456
#define TAUT_IGNORE_EQL_ENDPOINTS 0 /* 0=> even though 2 endpoints belong to same t-group check
457
them to find more alt bonds (new)
458
1=> ignore and do not check (old mode) */
459
#define TAUT_RINGS_ATTACH_CHAIN 1 /* 1=> allow only chain attachments to tautomeric endpoints */
460
/* (except pyrazole, where is no tautomeric attachment) */
461
/* 0=> allow taut. attachments from same ring system. Default=1 */
463
#define FIND_RING_SYSTEMS 1 /* 1 => find and mark ring systems, blocks, cut-vertices */
464
/* Needed for 5- and 6-member ring tautomers and in other places */
466
#define FIND_RINS_SYSTEMS_DISTANCES 0 /* 1 => find ring system and atom distance from terminal */
467
#define USE_DISTANCES_FOR_RANKING 0 /* 1 => rank ring systems according to distances from terminal */
469
#define DISPLAY_RING_SYSTEMS 0 /* 1 => for debug only; displays: */
470
/* "block no"/"ring system no"/"cut-vertex (num. intersecting blocks-1)" */
471
/* instead of ranks */
474
#if( bRELEASE_VERSION==1 && bOUTPUT_ONE_STRUCT_TIME==1)
475
#undef bOUTPUT_ONE_STRUCT_TIME
476
#define bOUTPUT_ONE_STRUCT_TIME 0
479
/* consistency: bRELEASE_VERSION==1 needs FIND_RING_SYSTEMS=1 */
480
#if( bRELEASE_VERSION==1 && FIND_RING_SYSTEMS!=1 )
481
#ifdef FIND_RING_SYSTEMS
482
#undef FIND_RING_SYSTEMS
484
#define FIND_RING_SYSTEMS 1
487
/* consistency: FIND_RINS_SYSTEMS_DISTANCES needs FIND_RING_SYSTEMS */
488
#if( FIND_RING_SYSTEMS != 1 )
490
#if( FIND_RINS_SYSTEMS_DISTANCES == 1 )
491
#undef FIND_RINS_SYSTEMS_DISTANCES
492
#define FIND_RINS_SYSTEMS_DISTANCES 0
497
/* consistency: USE_DISTANCES_FOR_RANKING and DISPLAY_RING_SYSTEMS need FIND_RINS_SYSTEMS_DISTANCES */
498
#if( FIND_RINS_SYSTEMS_DISTANCES != 1 )
500
#if( USE_DISTANCES_FOR_RANKING == 1 )
501
#undef USE_DISTANCES_FOR_RANKING
502
#define USE_DISTANCES_FOR_RANKING 0
505
#if( DISPLAY_RING_SYSTEMS == 1 )
506
#undef DISPLAY_RING_SYSTEMS
507
#define DISPLAY_RING_SYSTEMS 0
513
#if( FIND_RING_SYSTEMS==1 && (TAUT_TROPOLONE_7==1 || TAUT_TROPOLONE_5==1 || TAUT_4PYRIDINOL_RINGS==1 || TAUT_PYRAZOLE_RINGS) )
519
#define APPLY_IMPLICIT_H_DOWN_RULE 0 /* 1=> if 3 non-H atoms around stereocenter are in same plane */
520
/* then add "down" hydrogen to obtain sterecenter oparity */
521
/* 0=> Implicit H stereo is unknown if all bonds to 3 non-H atoms */
522
/* are in XY plane */
523
#define ALLOW_TAUT_ATTACHMENTS_TO_STEREO_BONDS 1 /* 1=> consider bond in an alternating circuit stereogenic */
524
/* even though it has adjacent tautomeric atom(s) */
526
#define IGNORE_TGROUP_WITHOUT_H 1 /* ignore tautomeric groups containing charges only */
528
#if ( DISCONNECT_SALTS == 1 )
529
#define REMOVE_TGROUP_CHARGE 0 /* 0: do not remove charge information from tautomeric groups */
531
#define REMOVE_TGROUP_CHARGE 1 /* 1: remove charge information from tautomeric groups */
534
#if ( REMOVE_TGROUP_CHARGE == 1 )
535
#define INCHI_T_NUM_MOVABLE 1
537
#define INCHI_T_NUM_MOVABLE 2
540
/******************************************/
541
/* define canonicalization modes here */
542
/******************************************/
544
#define USE_AUX_RANKING 1 /* 1=> get auxiliary ranking to accelerate canonicalization of H layers */
545
#define USE_AUX_RANKING_ALL 1 /* 1=> include all vertices in CellGetMinNode() selection 0=> only vertices with highest ranks */
547
#define USE_ISO_SORT_KEY_HFIXED 0 /* 0=> normal mode: merge isotopic taut H to isotopic atom sorting key in
548
taut H-fixed canonicalization;
549
1=> add one more "string" iso_sort_Hfixed to the canonicalization */
551
/************************
552
questionable behavior
553
************************/
554
#define REL_RAC_STEREO_IGN_1_SC 0 /* 1=> drop from InChI sp3 stereo in components that have a single stereocenter */
555
/* 0=> old-old mode (all such sp3 stereo is in the Identifier) */
556
/* internal definitions; see also REQ_MODE_BASIC etc in ichi.h */
557
#define CMODE_CT 0x000001
558
#define CMODE_ISO 0x000002
559
#define CMODE_ISO_OUT 0x000004 /* obsolete ? */
560
#define CMODE_STEREO 0x000008
561
#define CMODE_ISO_STEREO 0x000010
562
#define CMODE_TAUT 0x000020
563
#define CMODE_NOEQ_STEREO 0x000040 /* 5-24-2002: do not use stereo equivalence to accelerate */
564
#define CMODE_REDNDNT_STEREO 0x000080 /* 6-11-2002: do not check for redundant stereo elements */
565
#define CMODE_NO_ALT_SBONDS 0x000100 /* 6-14-2002: do not assign stereo to alternating bonds */
567
#define CMODE_RELATIVE_STEREO 0x000200 /* REL All Relative Stereo */
568
#define CMODE_RACEMIC_STEREO 0x000400 /* RAC All Racemic Stereo */
569
#define CMODE_SC_IGN_ALL_UU 0x000800 /* IAUSC Ignore stereocenters if All Undef/Unknown */
570
#define CMODE_SB_IGN_ALL_UU 0x001000 /* IAUSC Ignore stereobonds if All Undef/Unknown */
571
/* end of 10-10-2003 */
573
/* external definitions */
574
#define CANON_MODE_CT (CMODE_CT)
575
#define CANON_MODE_TAUT (CMODE_CT|CMODE_TAUT)
576
#define CANON_MODE_ISO (CMODE_CT|CMODE_ISO|CMODE_ISO_OUT)
577
#define CANON_MODE_STEREO (CMODE_CT|CMODE_STEREO)
578
#define CANON_MODE_ISO_STEREO (CMODE_CT|CMODE_ISO|CMODE_ISO_OUT|CMODE_ISO_STEREO)
580
#define CANON_MODE_MASK 0x00FF /* used to determine canonicalization mode */
582
/*************************************************
586
/* implemented definitions for CT_ATOMID */
587
#define CT_ATOMID_DONTINCLUDE 1
588
#define CT_ATOMID_IS_INITRANK 2
589
#define CT_ATOMID_IS_CURRANK 3
591
/***************************************
592
* canonicalization settings I
593
***************************************/
595
#define CANON_TAUTOMERS 1 /* 1=> process tautomers */
596
#define HYDROGENS_IN_INIT_RANKS 1 /* 1=> include num_H in initial ranking */
598
#define DOUBLE_BOND_NEIGH_LIST 0 /* 1 => include double bond neighbor in NeighList 2 times */
599
#define INCL_NON_6AROM 1 /* 1 => mark all arom. bonds; 0=>mark arom. bonds only in 6-member rings */
601
#define CT_SMALLEST /* minimal CT */
603
#define CT_NEIGH_SMALLER /* in CT, include neighbors with smaller ranks */
605
#define CT_ATOMID CT_ATOMID_IS_CURRANK /*CT_ATOMID_DONTINCLUDE */
607
#define CT_NEIGH_INCREASE /* in CT, neighbors ranks increase */
609
#define USE_SYMMETRY_TO_ACCELERATE 1 /*1 => for fast CT canonicalization, to avoid full enumeration */
611
/* dependent definitions due to settings */
614
#define CT_GREATER_THAN >
615
#define CT_INITVALUE ~0
616
#define BEST_PARITY 1 /* odd */
617
#define WORSE_PARITY 2
619
#define CT_GREATER_THAN <
620
#define CT_INITVALUE 0
621
#define BEST_PARITY 2 /* even */
622
#define WORSE_PARITY 1
625
#ifdef CT_NEIGH_SMALLER
626
#define CT_NEIGH_SMALLER_THAN <
628
#define CT_NEIGH_SMALLER_THAN >
631
/* verify corectness of dependent settings */
632
#if !defined( CT_ATOMID )
633
#error You have to #define CT_ATOMID
635
#if( defined( CT_ATOMID ) && CT_ATOMID==CT_ATOMID_DONTINCLUDE )
636
#error CT_DELIMITER should be #defined if CT_ATOMID is not included
640
/***************************************
641
* canonicalization settings II
642
***************************************/
644
#define ALL_ALT_AS_AROMATIC 1 /* 1 => all altrnate bonds (even in cyclooctateraene) treat as aromatic */
645
/* and set DOUBLE_BOND_NEIGH_LIST = 0 */
646
#define ANY_ATOM_IN_ALT_CYCLE 1 /* 1=> accept any atom in alternating bond circuit, 0=>only some */
648
#define EXCL_ALL_AROM_BOND_PARITY 0 /* 1 => any arom atom cannot belong to stereo bond. */
649
/* This has presedence over ADD_6MEMB_AROM_BOND_PARITY=1 */
650
/* 0 => include arom bonds parities according to */
651
/* ADD_6MEMB_AROM_BOND_PARITY definition */
653
#if ( EXCL_ALL_AROM_BOND_PARITY == 0 )
654
#define ADD_6MEMB_AROM_BOND_PARITY 1 /* 1 => all arom bonds are stereo bonds */
655
/* 0 => only those arom bonds which do not belong to */
656
/* 6-member arom rings are stereo bonds */
658
#define ADD_6MEMB_AROM_BOND_PARITY 0 /* 0 => standard; 1 => meaningless: ignore parities of non-6-member ring alt. bonds */
661
#define CML_NUM_AT_IN_ATREF4 4
662
#define MAX_NUM_STEREO_BONDS 3
663
#define MAX_NUM_STEREO_BOND_NEIGH 3
664
#define MIN_NUM_STEREO_BOND_NEIGH 2
666
#define MAX_NUM_STEREO_ATOM_NEIGH 4
667
#define STEREO_AT_MARK 8 /* > MAX_NUM_STEREO_BONDS */
669
#if( ONLY_DOUBLE_BOND_STEREO == 1 ) /* { */
671
#ifdef ALLOW_TAUT_ATTACHMENTS_TO_STEREO_BONDS
672
#undef ALLOW_TAUT_ATTACHMENTS_TO_STEREO_BONDS
673
#define ALLOW_TAUT_ATTACHMENTS_TO_STEREO_BONDS 0
676
#ifdef EXCL_ALL_AROM_BOND_PARITY
677
#undef EXCL_ALL_AROM_BOND_PARITY
678
#define EXCL_ALL_AROM_BOND_PARITY 1
681
#ifdef ADD_6MEMB_AROM_BOND_PARITY
682
#undef ADD_6MEMB_AROM_BOND_PARITY
683
#define ADD_6MEMB_AROM_BOND_PARITY 0
686
#endif /* } ONLY_DOUBLE_BOND_STEREO */
688
/* dependent definitions due to settings */
689
#if( ALL_ALT_AS_AROMATIC == 1 && DOUBLE_BOND_NEIGH_LIST != 0 )
690
#undef DOUBLE_BOND_NEIGH_LIST
691
#define DOUBLE_BOND_NEIGH_LIST 0
695
/*************************************
699
#define DRAW_AROM_TAUT 1 /* 1=> draw distinct aromatic & tautomer bonds, 0=> don't */
701
/******************************************************/
702
/* C O M M O N D E F I N I T I O N S */
703
/******************************************************/
706
/* input bTautFlags flags */
707
#define TG_FLAG_TEST_TAUT__ATOMS 0x00000001 /* find regular tautomerism */
708
#define TG_FLAG_DISCONNECT_SALTS 0x00000002 /* DISCONNECT_SALTS disconnect */
709
#define TG_FLAG_TEST_TAUT__SALTS 0x00000004 /* DISCONNECT_SALTS if possible find long-range H/(-) taut. on =C-OH, >C=O */
710
#define TG_FLAG_MOVE_POS_CHARGES 0x00000008 /* MOVE_CHARGES allow long-range movement of N(+), P(+) charges */
711
#define TG_FLAG_TEST_TAUT2_SALTS 0x00000010 /* TEST_REMOVE_S_ATOMS multi-attachement long-range H/(-) taut. on =C-OH, >C=O */
712
#define TG_FLAG_ALLOW_NO_NEGTV_O 0x00000020 /* CHARGED_SALTS_ONLY=0 (debug) find long-range H-only tautomerism on =C-OH, >C=O */
713
#define TG_FLAG_MERGE_TAUT_SALTS 0x00000040 /* DISCONNECT_SALTS merge all "salt"-t-groups and other =C-OH into one t-group */
715
#define TG_FLAG_ALL_TAUTOMERIC (TG_FLAG_TEST_TAUT__ATOMS| \
716
TG_FLAG_TEST_TAUT__SALTS| \
717
TG_FLAG_TEST_TAUT2_SALTS| \
718
TG_FLAG_MERGE_TAUT_SALTS)
720
#define TG_FLAG_DISCONNECT_COORD 0x00000080 /* find "coord. centers" and disconnect them */
721
#define TG_FLAG_RECONNECT_COORD 0x00000100 /* reconnect disconnected "coord. centers" */
722
#define TG_FLAG_CHECK_VALENCE_COORD 0x00000200 /* do not disconnect "coord. centers" with usual valence */
723
#define TG_FLAG_MOVE_HPLUS2NEUTR 0x00000400 /* move protons to neutralize */
724
#define TG_FLAG_VARIABLE_PROTONS 0x00000800 /* add/remove protons to neutralize */
725
#define TG_FLAG_HARD_ADD_REM_PROTONS 0x00001000 /* add/remove protons to neutralize in hard way */
726
#define TG_FLAG_POINTED_EDGE_STEREO 0x00002000 /* only pointed edge of stereo bond defines stereo */
727
#if( FIX_ADJ_RAD == 1 )
728
#define TG_FLAG_FIX_ADJ_RADICALS 0x00004000 /* remove adjacent radical-doubletes, fix valence */
730
#define TG_FLAG_PHOSPHINE_STEREO 0x00008000 /* add phosphine sp3 stereo */
731
#define TG_FLAG_ARSINE_STEREO 0x00010000 /* add arsine sp3 stereo */
732
#define TG_FLAG_H_ALREADY_REMOVED 0x00020000 /* processing structure restored from InChI */
733
#define TG_FLAG_FIX_SP3_BUG 0x00040000 /* fix sp3 stereo bug: overlapping 2D stereo bond & coordinate scaling */
735
#define TG_FLAG_KETO_ENOL_TAUT 0x00080000 /* turn on keto-enol tautomerism detection */
736
#define TG_FLAG_1_5_TAUT 0x00100000 /* turn on 1,5 tautomerism detection */
739
#define TG_FLAG_FIX_ISO_FIXEDH_BUG 0x00200000 /* fix bug found after v.102b (isotopic H representation) */
740
#define TG_FLAG_FIX_TERM_H_CHRG_BUG 0x00400000 /* fix bug found after v.102b (moving H charge in 'remove_terminal_HDT') */
742
/* output bTautFlags flags */
744
#define TG_FLAG_MOVE_HPLUS2NEUTR_DONE 0x00000001 /* protons have been moved to neutralize */
745
#define TG_FLAG_TEST_TAUT__ATOMS_DONE 0x00000002
746
#define TG_FLAG_DISCONNECT_SALTS_DONE 0x00000004
747
#define TG_FLAG_TEST_TAUT__SALTS_DONE 0x00000008 /* multiple H tautomerism */
748
#define TG_FLAG_MOVE_POS_CHARGES_DONE 0x00000010
749
#define TG_FLAG_TEST_TAUT2_SALTS_DONE 0x00000020 /* merged t-groups */
750
#define TG_FLAG_ALLOW_NO_NEGTV_O_DONE 0x00000040
751
#define TG_FLAG_MERGE_TAUT_SALTS_DONE 0x00000080 /* added non-taut O to taut groups */
753
#define TG_FLAG_ALL_SALT_DONE (TG_FLAG_TEST_TAUT__SALTS_DONE | \
754
TG_FLAG_TEST_TAUT2_SALTS_DONE | \
755
TG_FLAG_MERGE_TAUT_SALTS_DONE )
757
#define TG_FLAG_DISCONNECT_COORD_DONE 0x00000100 /* found and disconnected "coord. centers" */
758
#define TG_FLAG_CHECK_VALENCE_COORD_DONE 0x00000200 /* did not disconnect "coord. centers" with usual valence */
759
#define TG_FLAG_MOVE_CHARGE_COORD_DONE 0x00000400 /* changed charge of a disconnected ligand to fit its valence */
760
#define TG_FLAG_FIX_ODD_THINGS_DONE 0x00000800 /* fixed drawing ambiguities in fix_odd_things */
761
#define TG_FLAG_TEST_TAUT3_SALTS_DONE 0x00001000 /* merged t-groups + non-O taut atoms */
762
#define TG_FLAG_FOUND_SALT_CHARGES_DONE 0x00002000 /* not assigned: preprocessing detected possibility of salt-type tautomerism */
763
#define TG_FLAG_FOUND_ISOTOPIC_H_DONE 0x00004000 /* preprocessing detected isotopic H on "good" heteroatoms or isotopic H(+) */
764
#define TG_FLAG_FOUND_ISOTOPIC_ATOM_DONE 0x00008000 /* preprocessing detected isotopic H on "good" heteroatoms or isotopic H(+) */
765
#if( FIX_ADJ_RAD == 1 )
766
#define TG_FLAG_FIX_ADJ_RADICALS_DONE 0x00010000
769
#if( READ_INCHI_STRING == 1 )
770
#define READ_INCHI_OUTPUT_INCHI 0x00000001
771
#define READ_INCHI_SPLIT_OUTPUT 0x00000002
772
#define READ_INCHI_KEEP_BALANCE_P 0x00000004
773
#define READ_INCHI_TO_STRUCTURE 0x00000008
779
#define INCHI_OPTION_PREFX '/'
780
#define INCHI_PATH_DELIM '\\'
784
#define INCHI_OPTION_PREFX '-'
785
#define INCHI_PATH_DELIM '/'
789
#define INCHI_ALT_OPT_PREFIX '-'
790
#define INCHI_ACD_LABS_PREFIX '-'
792
typedef struct tagOutputString {
794
int nAllocatedLength;
800
typedef struct tagOutputStream
802
/* output is directed either to resizable string buffer: */
804
/* or to the plain file: */
808
/* INCHI_IOSTREAM.type values */
809
#define INCHI_IOSTREAM_NONE 0
810
#define INCHI_IOSTREAM_STRING 1
811
#define INCHI_IOSTREAM_FILE 2
814
/* memory leaks tracking */
815
#define INCHI_HEAPCHK /* default: no explicit heap checking during the execution */
817
#if( TRACE_MEMORY_LEAKS == 1 )
820
#define inchi_malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
821
#define inchi_calloc(c, s) _calloc_dbg(c, s, _NORMAL_BLOCK, __FILE__, __LINE__)
822
#define inchi_free(p) _free_dbg(p, _NORMAL_BLOCK)
825
/* INChI_MAIN specific */
826
#define e_inchi_malloc(a) inchi_malloc(a)
827
#define e_inchi_calloc(a,b) inchi_calloc(a,b)
828
#define e_inchi_free(a) inchi_free(a)
831
/*#define _CRTDBG_MAP_ALLOC*/ /* standard VC++ tool -- does not work with inchi_malloc(), etc */
835
/* to enable heap checking: #define CHECK_WIN32_VC_HEAP above #include "mode.h" in each source file or here */
836
#ifdef CHECK_WIN32_VC_HEAP
837
/* -- Confirms the integrity of the memory blocks allocated in the debug heap -- */
839
#define INCHI_HEAPCHK \
841
int tmp = _crtDbgFlag; \
842
_crtDbgFlag |= _CRTDBG_ALLOC_MEM_DF; \
843
_ASSERT( _CrtCheckMemory( ) ); \
847
/* -- less thorough than _CrtCheckMemory() check: check minimal consistency of the heap -- */
850
#define INCHI_HEAPCHK \
852
int heapstatus = _heapchk(); \
853
_ASSERT( heapstatus != _HEAPBADBEGIN && heapstatus != _HEAPBADNODE && heapstatus != _HEAPBADPTR); \
860
#undef TRACE_MEMORY_LEAKS
861
#define TRACE_MEMORY_LEAKS 0
863
#endif /* TRACE_MEMORY_LEAKS */
866
/* INChI_MAIN specific */
868
#define inchi_malloc e_inchi_malloc
871
#define inchi_calloc e_inchi_calloc
874
#define inchi_free e_inchi_free
877
#ifndef e_inchi_malloc
878
#define e_inchi_malloc malloc
880
#ifndef e_inchi_calloc
881
#define e_inchi_calloc calloc
884
#define e_inchi_free(X) do{ if(X) free(X); }while(0)
887
#else /* not INCHI_MAIN */
890
#define inchi_malloc malloc
893
#define inchi_calloc calloc
896
#define inchi_free(X) do{ if(X) free(X); }while(0)
899
#endif /* INCHI_MAIN */
901
/* allocation/deallocation */
904
#if( USE_ALLOCA == 1 )
905
#define qmalloc(X) _alloca(X)
906
#define qfree(X) do{(X)=NULL;}while(0)
908
#define qmalloc(X) inchi_malloc(X)
909
#define qfree(X) do{if(X){inchi_free(X);(X)=NULL;}}while(0)
912
#if( defined(_MSC_VER) && _MSC_VER >= 800 )
913
#define fast_alloc(X) _alloca(X)
916
#define fast_alloc(X) inchi_malloc(X)
917
#define fast_free(X) inchi_free(X)
920
#define qzfree(X) do{if(X){inchi_free(X);(X)=NULL;}}while(0)
924
#define MYREALLOC2(PTRTYPE1, PTRTYPE2, PTR1, PTR2, LEN1, LEN2, ERR) \
926
if( (LEN1) <= (LEN2) ) {\
927
PTRTYPE1 * newPTR1 = (PTRTYPE1 *)inchi_calloc( (LEN2)+1, sizeof(PTRTYPE1) );\
928
PTRTYPE2 * newPTR2 = (PTRTYPE2 *)inchi_calloc( (LEN2)+1, sizeof(PTRTYPE2) );\
929
if ( newPTR1 && newPTR2 ) { \
930
if ( (PTR1) && (LEN1) > 0 ) \
931
(memcpy) ( newPTR1, (PTR1), (LEN1) * sizeof(PTRTYPE1) ); \
932
if ( (PTR2) && (LEN1) > 0 ) \
933
(memcpy) ( newPTR2, (PTR2), (LEN1) * sizeof(PTRTYPE2) ); \
945
} else { (ERR) = 0; } \
948
#ifndef INCHI_ALL_CPP
955
#endif /* __MODE_H__ */