1 /*
2  * International Chemical Identifier (InChI)
3  * Version 1
4  * Software version 1.04
5  * September 9, 2011
6  *
7  * The InChI library and programs are free software developed under the
8  * auspices of the International Union of Pure and Applied Chemistry (IUPAC).
9  * Originally developed at NIST. Modifications and additions by IUPAC
10  * and the InChI Trust.
11  *
12  * IUPAC/InChI-Trust Licence for the International Chemical Identifier (InChI)
13  * Software version 1.0.
14  * Copyright (C) IUPAC and InChI Trust Limited
15  *
16  * This library is free software; you can redistribute it and/or modify it under the
17  * terms of the IUPAC/InChI Trust Licence for the International Chemical Identifier
18  * (InChI) Software version 1.0; either version 1.0 of the License, or
19  * (at your option) any later version.
20  *
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
24  * See the IUPAC/InChI Trust Licence for the International Chemical Identifier (InChI)
25  * Software version 1.0 for more details.
26  *
27  * You should have received a copy of the IUPAC/InChI Trust Licence for the
28  * International Chemical Identifier (InChI) Software version 1.0 along with
29  * this library; if not, write to:
30  *
31  * The InChI Trust
32  * c/o FIZ CHEMIE Berlin
33  * Franklinstrasse 11
34  * 10587 Berlin
35  * GERMANY
36  *
37  */
38 
39 
40 
41 
42 #ifndef __MODE_H__
43 #define __MODE_H__
44 
45 #include <stdio.h>
46 
47 
48 
49 
50 /*******************/
51 /*                 */
52 /*  BUILD TARGETS  */
53 /*                 */
54 /*******************/
55 
56 /*	Valid targets are:
57 
58 TARGET_EXE_STANDALONE
59     Stand-alone executable inchi-1[.exe]
60 TARGET_API_LIB
61     Library (libinchi) for using InChI API described in inchi_api.h
62 TARGET_EXE_USING_API
63     Executable (INCHI_MAIN) which uses API library (e.g., libinchi.dll)
64 TARGET_LIB_FOR_WINCHI
65     library for wInChI
66 
67     Select and uncomment one from the list below. */
68 
69 
70 /* #define TARGET_EXE_STANDALONE 1 */
71 #define TARGET_API_LIB
72 /* #define TARGET_EXE_USING_API */
73 /* #define TARGET_LIB_FOR_WINCHI 1 */
74 
75 
76 /****************************/
77 /*                          */
78 /*  BUILD OPTIONS/FEATURES  */
79 /*                          */
80 /****************************/
81 
82 /*	Possible options are:
83 
84 BUILD_LINK_AS_DLL
85     Link library as a Win32 DLL or to eliminate stricmp duplication
86     (use with TARGET_API_LIB or TARGET_EXE_USING_API)
87 
88 BUILD_WITH_ENG_OPTIONS
89     Expose engineering options
90 
91 BUILD_WITH_AMI
92     Turns on AMI (Allow Multiple Inputs) mode for standalone executable
93 
94     Select and uncomment whichever are necessary from the list below. */
95 
96 
97 /* #define BUILD_LINK_AS_DLL */
98 
99 /* #define BUILD_WITH_ENG_OPTIONS 1 */
100 
101 #ifndef BUILD_WITH_AMI
102 /* this allows BUILD_WITH_AMI be #defined in a makefile */
103 /* #define BUILD_WITH_AMI 1 */
104 #endif
105 /* NB:  AMI mode is only for stand-alone executable */
106 #ifndef TARGET_EXE_STANDALONE
107 #ifdef BUILD_WITH_AMI
108 #undef BUILD_WITH_AMI
109 #endif
110 #endif
111 
112 
113 
114 /* CML input is not supported started from v. 1.04 */
115 /* set ADD_CMLPPP to zero to override possble makefile define */
116 #define ADD_CMLPP 0
117 #if 0 /* obsolete */
118 #ifndef ADD_CMLPP
119 /* this allows ADD_CMLPP be #defined in a makefile */
120 #define ADD_CMLPP        1
121 #endif
122 #if ( ADD_CMLPP == 1 )
123 #ifdef USE_CMLPPDLL
124 /* 1200 is VC++ 6.0 version, 1300 is VC++ .NET; USE_CMLPPDLL may be #defined in a makefile*/
125 #if ( defined(_WIN32) && defined(_MSC_VER) && _MSC_VER >= 1200 )
126 #define MSC_DELAY_LOAD_CMLPPDLL
127 #endif
128 #endif
129 #endif
130 #endif
131 
132 
133 
134 
135 /*****************************/
136 /*                           */
137 /* COMPILE OPTIONS/FEATURES  */
138 /*                           */
139 /*****************************/
140 
141 /*	Possible options are:
142 
143 COMPILE_ANSI_ONLY
144     Unconditionally force ANSI-89 C, no Win32 specific code
145 
146 COMPILE_ADD_NON_ANSI_FUNCTIONS
147     Use with COMPILE_ANSI_ONLY to add stricmp(), etc., see util.c
148 
149 COMPILE_ALL_CPP
150     allow C++ compilation/linkage of functions prototyped in .h files
151 
152 MS VC compiler pragmas
153 
154     Select and uncomment whichever are necessary from the list below. */
155 
156 
157 /* #define COMPILE_ANSI_ONLY */
158 #if ( !defined(_MSC_VER) || defined(TARGET_API_LIB))  /* non-Microsoft GNU C, BCC, etc. compilers */
159 #ifndef COMPILE_ANSI_ONLY
160 #define COMPILE_ANSI_ONLY
161 #endif
162 #endif
163 #ifdef COMPILE_ANSI_ONLY
164 /*#define COMPILE_ADD_NON_ANSI_FUNCTIONS */
165 #endif
166 
167 
168 /* #define COMPILE_ALL_CPP */
169 
170 #ifdef _MSC_VER
171 /*
172 ========== disable MS VC++ 6.0 Level 4 compiler warnings: ==============
173  C4706: assignment within conditional expression
174  C4127: conditional expression is constant
175  C4244: '=' : conversion from 'int ' to '???', possible loss of data
176  C4267: '=' : conversion from 'size_t' to 'int', possible loss of data
177  C4701: local variable '???' may be used without having been initialized (removed)
178  C4514: unreferenced inline/local function has been removed (C++)
179  C4100: 'identifier' : unreferenced formal parameter
180  C4786: 'identifier' : identifier was truncated to 'number' characters in the debug information
181  C4996: 'identifier' was declared deprecated
182 ========================================================================
183 */
184    #pragma warning( disable : 4706 4127 4514 4100 4786 4996 4244 4267 )
185 #endif
186 
187 
188 
189 /* TARGET_ID_STRING */
190 #define TARGET_ID_STRING ", Software version 1.04 (API Library) Build of September 9, 2011"
191 
192 
193 
194 #ifndef COMPILE_ALL_CPP
195 #ifdef __cplusplus
196 extern "C" {
197 #endif
198 #endif
199 
200 
201 
202 
203 /*********************/
204 /*                   */
205 /*  INCHI ALGORITHM  */
206 /*                   */
207 /*********************/
208 
209 #define INCHI_VERSION       "1"
210 
211 #if 0	/* obsolete */
212 /*#define INCHI_VERSION     "0.9Beta"  */
213 /*#define INCHI_VERSION     "0.91Beta" */  /* 10-10-2002: sent to Jonathan Goodman */
214 /*#define INCHI_VERSION     "0.92Beta" */  /* 11-15-2002: added Hill notation; sent to S.Heller & S.Stein */
215 /*#define INCHI_VERSION     "0.93Beta" */  /* 12-09-2002: Fixed isotopic canon. bug & chiralanes; sent to S.Heller & A. McNaught */
216 /*#define INCHI_VERSION     "0.931Beta" */  /* Non-BNS without salts released to PMR 01-2003 */
217 /*#define INCHI_VERSION     "0.932Beta" */      /* Released to CAS 04-01-2003:
218                                             * - Improved taut. definitions as compared to 01-2003;
219                                             * - fixed bug: non-isotopic components' stereo missing from isotopic stereo
220                                             * - fixed bug: couldn't properly read Unix files (EOL = LF instead of CR/LF)
221                                             *   (effective only for MS VC++, Borland and MinGW/GCC compiles that accept "rb" mode of fopen)
222                                             *   DJGPP/GCC does not seem to need this fix.
223                                             */
224 /*==== Release version ===*/
225 /*#define INCHI_VERSION     "0.94Beta" */       /* 02-27-2003: Balanced network search to find alt paths and non-stereo bonds;
226                                                       Implemented salts disconnection; added (-) to taut groups */
227 /*#define INCHI_VERSION     "1.12Beta" */       /* 1.12: 07-06-2004: sort order: No H formula,..; Pointed end stereo ON, Aggressive (de)protonation OFF */
228                                                 /* 1.11: 05-19-2004: annotated plain text output, fixed bugs */
229                                                 /* 1.1:  04-08-2004: variable protonation version */
230                                                 /* 1.01: 12-23-2003 protected bonds, isotopic canonicalization in GetBaseCanonRanking() */
231                                                 /* 1.02: 01-26-2004 fixed new isotopic tgroup canon bug, molfile merge bug */
232 
233 /*#define INCHI_VERSION       "1.0RC"*/             /* 02-07-2005 v1.0 Release Candidate */
234 #endif
235 
236 #define INCHI_NAME          "InChI"
237 #if 0	/* obsolete */
238 #define INCHI_REC_NAME      "ReChI"
239 #endif
240 
241 #define INCHI_NAM_VER_DELIM "="
242 
243 #ifdef _WIN32
244 #define   INCHI_OPTION_PREFX  '/'
245 #define   INCHI_PATH_DELIM    '\\'
246 #else
247 #define   INCHI_OPTION_PREFX  '-'
248 #define   INCHI_PATH_DELIM    '/'
249 #endif
250 
251 #define   INCHI_ALT_OPT_PREFIX  '-'
252 #define   INCHI_ACD_LABS_PREFIX '-'
253 
254 #define bRELEASE_VERSION  1    /* 1=> release version; comment out to disable */
255 #ifndef bRELEASE_VERSION
256 #define bRELEASE_VERSION  0    /* 0=> debug version */
257 #endif
258 
259 
260 /* display (non-canonical) c-groups, display orig at numbers */
261 #if ( bRELEASE_VERSION == 1 )
262 #define DISPLAY_DEBUG_DATA_C_POINT 0  /* disabled release version for now */
263 #define DISPLAY_ORIG_AT_NUMBERS    1  /* 1 => in an uncanonicalized components display orig. atom numbers (default) */
264 #else
265 #define DISPLAY_DEBUG_DATA_C_POINT 1  /* debug: 1=>display (non-canonically numbered) c-groups, 0=>do not display */
266 #define DISPLAY_ORIG_AT_NUMBERS    1  /* 0 => in an uncanonicalized components display ordering atom numbers (debug) */
267 #endif
268 
269 #if ( DISPLAY_DEBUG_DATA_C_POINT > 0 )
270 #define DISPLAY_DEBUG_DATA         DISPLAY_DEBUG_DATA_C_POINT
271 #endif
272 
273 
274 
275 /* BUG FIXES */
276 
277 /**************************/
278 /* bug fixes in v1.00     */
279 /**************************/
280 #define FIX_ChCh_STEREO_CANON_BUG     1  /* 1=> (NEEDED) */
281 #define ADD_ChCh_STEREO_CANON_CHK     0  /* 1 is NOT needed; let it always be 0 */
282 #define FIX_ChCh_CONSTIT_CANON_BUG    1  /* 1=> (NEEDED) */
283 #define FIX_EITHER_STEREO_IN_AUX_INFO 1  /* 1=> fix bug: Either stereobond direction in Aux_Info; 0=> do not fix */
284 #define FIX_NORM_BUG_ADD_ION_PAIR     1  /* 1=> (NEEDED) fix bug: Miscount number of charges when creating an ion pair */
285 #define FIX_REM_PROTON_COUNT_BUG      1  /* 1=> (NEEDED) check for number of actually removed protons and issue an error if mismatch */
286 #define FIX_READ_AUX_MEM_LEAK         1
287 #define FIX_READ_LONG_LINE_BUG        1  /* 1=> (NEEDED) prevent failure when reading AuxInfo and InChI is too long */
288 #define FIX_N_V_METAL_BONDS_GPF       1  /* 1=> (NEEDED) InChI v1 GPF bug fix */
289 #define BNS_RAD_SEARCH                1  /* 1=> prevent normalization failures due to radical centers */
290 
291 /*******************************/
292 /* bug fixes in post-v1.00     */
293 /*******************************/
294 #define FIX_ODD_THINGS_REM_Plus_BUG   0
295 #define FIX_N_MINUS_NORN_BUG          0
296 #define FIX_CANCEL_CHARGE_COUNT_BUG   0
297 #define FIX_2D_STEREO_BORDER_CASE     0
298 #define FIX_REM_ION_PAIRS_Si_BUG      0
299 #define FIX_STEREO_SCALING_BUG        0
300 #define FIX_EMPTY_LAYER_BUG           0
301 #define FIX_EITHER_DB_AS_NONSTEREO    0
302 #define FIX_BOND23_IN_TAUT            0
303 #define FIX_TACN_POSSIBLE_BUG         0
304 #define FIX_KEEP_H_ON_NH_ANION        0
305 #define FIX_AVOID_ADP                 0
306 /* may change InChI */
307 #define FIX_NUM_TG                    0  /* increase number of t-groups for isothiocyanate */
308 /* changes InChI for isothiocyanate */
309 #define FIX_CPOINT_BOND_CAP2          0
310 
311 /*******************************/
312 /* bug fixes in post-v1.02b    */
313 /*******************************/
314 
315 #define FIX_ISO_FIXEDH_BUG            1 /* (2007-09-24) 1=> Fix bug: missing fixed-H iso segment in case of single removed D(+) */
316 #define FIX_ISO_FIXEDH_BUG_READ       0 /* (2007-09-24) 1=> Accommodate this InChI bug in reading InChI */
317 #define FIX_DALKE_BUGS                1
318 #define FIX_TRANSPOSITION_CHARGE_BUG  1	/* (2008-01-02) fix bug that leads to missed charge in some cases when /o is present */
319 #define FIX_I2I_STEREOCONVERSION_BUG  1 /* (2008-03-06)   1=> Fix bug of i2i conversion SAbs-->(SRel||Srac) */
320 #define FIX_I2I_STEREOCONVERSION_BUG2 1 /* (2008-04-02)   1=> Fix bug of i2i conversion (missed empty /t) */
321 #define FIX_I2I_STEREOCONVERSION_BUG3 1 /* (2008-04-10)   1=> Fix bug of i2i conversion */
322                                         /* (missed repeating /s in FI after F for multi-component case) */
323 #define FIX_TERM_H_CHRG_BUG           1 /* (2008-06-06) IPl) */
324                                         /* fix bug: in some cases (dependent on ordering
325                                         numbers), moving a charge from terminal H to heavy
326                                         atom resulted in neutralizing H but not adjusting
327                                         charge of heavy atom */
328 
329 
330 #define FIX_AROM_RADICAL              1 /* (2011-05-09) 1=> Fix bug which leads for different InChI */
331                                         /* on atomic permitations for systems containing radical at */
332                                         /* atom in aromatic ring */
333 
334 
335 #if ( !defined(TARGET_API_LIB) && !defined(TARGET_EXE_USING_API) )
336 #define I2S_MODIFY_OUTPUT             1  /* 1=> Allow various InChI2InChI output types from cInChI */
337 #else
338 #define I2S_MODIFY_OUTPUT             0  /* 0=> Always */
339 #endif
340 
341 
342 #define FIX_NP_MINUS_BUG  1         /* 2010-03-11 DCh */
343 
344 /**************************/
345 /* additions to v1.00     */
346 /**************************/
347 #define FIX_ADJ_RAD                 0
348 
349 #define SDF_OUTPUT_V2000            1  /* 1=>always output V2000 SDfile, 0=>only if needed */
350 #define SDF_OUTPUT_DT               1  /* 1=> all option -SdfAtomsDT to output D and T into SDfile */
351 #define CHECK_AROMBOND2ALT          1  /* 1=> check whether arom->alt bond conversion succeeded */
352 
353 #ifdef TARGET_LIB_FOR_WINCHI
354 #define READ_INCHI_STRING           0  /* 1=> input InChI string and process it */
355 #else
356 #define READ_INCHI_STRING           1  /* 1=> input InChI string and process it */
357 #endif
358 
359 /****************************************************/
360 /* disabled extra external calls to InChI algorithm */
361 /****************************************************/
362 #define INCLUDE_NORMALIZATION_ENTRY_POINT  0
363 
364 /**************************/
365 /* Normalization settings */
366 /**************************/
367 
368 /* post version 1 features */
369 #define KETO_ENOL_TAUT             1 /* include keto-enol tautomerism */
370 #define TAUT_15_NON_RING           1 /* 1,5 tautomerism with endpoints not in ring */
371 
372 /* v.1.04 : still experimental but may be exposed (set to 1) */
373 #define UNDERIVATIZE               0 /* split to possible underivatized fragments */
374 #define RING2CHAIN                 0 /* open rings R-C(-OH)-O-R => R-C(=O) OH-R   */
375 
376 /* post-2004-04-27 features */
377 #define HAL_ACID_H_XCHG            1 /* allow iso H exchange to HX (X=halogen) and H2Y (Y=halcogen) */
378 #define CANON_FIXH_TRANS           1 /* produce canonical fixed-H transposition */
379 #define STEREO_WEDGE_ONLY          1 /* 1=> only pointed ends stereo bonds define stereo; 0=> both ends */
380 
381 /* current new (with respect to v1.12 Beta) preprocessing */
382 #define REMOVE_ION_PAIRS_EARLY     1 /* 1=> new preprocessing: step 1 before disconnecting metals in fix_odd_things() */
383 #define REMOVE_ION_PAIRS_DISC_STRU 1 /* 1=> new post-preprocessing: remove charhes after metal disconnection */
384 #define REMOVE_ION_PAIRS_FIX_BONDS 1 /* 1=> step2: set unchangeable bonds around removed ion pairs */
385 #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 */
386 #define N_V_STEREOBONDS            1 /* 1=> detect stereobonds incident to N(V); 0 => don't */
387 /* for testing */
388 #define REMOVE_ION_PAIRS_ORIG_STRU 0 /* 0=> normal mode (default)
389                                       * 1=> testing mode only: remove ion pairs from the original structure
390                                       *     to save the changes in the output Molfile (/OutputSDF) or AuxInfo
391                                       *     NIP=No Ion Pairs
392                                       */
393 /* salts treatment */
394 #define DISCONNECT_SALTS            1  /* 1=>disconnect metal atoms from salts, 0=>dont */
395 #define TEST_REMOVE_S_ATOMS         1  /* 1=>default: after merging into one group test &
396                                         *    remove unreachable,
397                                         * 0=> old version: test only before merging into one t-group */
398 #define CHARGED_SALTS_ONLY          1  /* 1=>(default)do not test far salts tautomerism if
399                                         *     no negative charge(s) present */
400 #define BNS_PROTECT_FROM_TAUT       1  /* 1=> do not allow testing of bonds to acetyl or nitro */
401 #define BNS_MARK_EDGE_2_DISCONNECT  1  /* 1=> mark edge as temp forbidden instead of disconnection */
402 
403 #define REPLACE_ALT_WITH_TAUT       1  /* 1 => replace alt bonds with tautomeric bonds in case of standard t-groups */
404 #define MOVE_CHARGES                1  /* 1 => take moveable charges into account */
405 #define NEUTRALIZE_ENDPOINTS        1  /* 1 => before checking whether an H is moveable make 2 endpoints neutral */
406                                        /*      implemented only if CHECK_TG_ALT_PATH = 0, defined in ichi_bns.c  */
407 #define FIX_H_CHECKING_TAUT         1  /* 1 => Fix moveable H or (-) before checking if taut. exchange is possible */
408 #define ALWAYS_ADD_TG_ON_THE_FLY    1  /* 1 => disables radical calcellation by taut-charge movement */
409 #define IGNORE_SINGLE_ENDPOINTS     1  /* 1 => see FindAccessibleEndPoints() in INChITaut.c */
410 
411 /* recently added -- begin */
412 #define INCL_NON_SALT_CANDIDATATES   1  /* 1=> allow H and (-) migrate between "acidic" O and
413                                          *     other possible endpoints */
414 #define SALT_WITH_PROTONS            1  /* 1=> (new new) include proton migrarion C-SH, =C-OH, NH+ */
415 #define OPPOSITE_CHARGE_IN_CGROUP    1  /* 1=> allow N(-) in (+) c-group, 0=> disallow */
416 #define MOVE_PPLUS_TO_REMOVE_PROTONS 0  /* 0=> default; 1=> (disabled) add P/P+ charge group during
417                                          *     'hard' proton removal */
418 #define ADD_MOVEABLE_O_PLUS          1  /* 1=> allow charges on O(+) to move */
419 /* recently added -- end */
420 
421 #define DISCONNECT_METALS           1  /* make main layer disconnected */
422 #define RECONNECT_METALS            0  /* 1=> by default add reconnected layer in case of coord.
423                                         *     compound disconnection */
424 #define CHECK_METAL_VALENCE         0  /* 1=> disconnect only metals that have abnormal valence */
425 #define bREUSE_INCHI                1  /* 1=> do not recalulate INChI for components in reconnected
426                                         *     structure that are same as in the connected one */
427 #define OUTPUT_CONNECTED_METAL_ONLY 0  /* 0=> default; 1 => (debug) create only reconnected or
428                                         *     initial struct. output */
429 #define EMBED_REC_METALS_INCHI      1  /* 1=> (default) output Reconnected embedded in Disconnected INChI;
430                                         * 0=> separate output */
431 
432 #define bOUTPUT_ONE_STRUCT_TIME     1  /* 1 => output each structure time (non-release only) */
433 
434 
435 
436 /* constants and array sizes */
437 
438 #define INCHI_NUM            2    /* = array size; member indexes: */
439 #define INCHI_BAS            0    /* 0 => disconnected or normal */
440 #define INCHI_REC            1    /* 1 => reconnected */
441 
442 #define TAUT_NUM            2    /* = array size; member indexes: */
443 #define TAUT_NON            0    /* 0 => normal structure */
444 #define TAUT_YES            1    /* 1 => tautomeric */
445 #define TAUT_INI            2    /* 2 => intermediate tautomeric structure */
446 #define ALT_TAUT(X)        ((X)>TAUT_YES? TAUT_YES : 1-(X))  /* was (1-(X)) */
447 
448 /* INChI output modes */
449 #define OUT_N1              0    /* non-tautomeric only */
450 #define OUT_T1              1    /* tautomeric if present otherwise non-tautomeric */
451 #define OUT_NT              2    /* only non-taut representations of tautomeric */
452 #define OUT_TN              3    /* tautomeric if present otherwise non-tautomeric;
453                                     separately output non-taut representations of tautomeric if present */
454 #define OUT_NN              4    /* only non-taut representations: non-taut else tautomeric */
455 
456 /* OUT_TN = OUT_T1 + OUT_NT */
457 
458 /* torture test */
459 
460 #define TEST_RENUMB_ATOMS           0    /* 1 => heavy duty test by multiple renumbering of atoms */
461 #define TEST_RENUMB_NEIGH           1    /* 1 => randomly permutate neighbors */
462 #define TEST_RENUMB_SWITCH          0    /* 1 => display & output another (different) picture */
463 #define TEST_RENUMB_ATOMS_SAVE_LONGEST 0 /* 1 => save the component with largest processing time into the problem file */
464 
465 
466 /* stereo */
467 
468 #define NEW_STEREOCENTER_CHECK      1    /* 1 => add new stereocenter categories (see bCanInpAtomBeAStereoCenter(...)) */
469 #define MIN_SB_RING_SIZE            8    /* do not assume stereo bonds in rings containing 3..MIN_SB_RING_SIZE-1 atoms */
470 
471 #define REMOVE_KNOWN_NONSTEREO      1 /* 1=> check in advance known stereo to remove parities from non-stereogenic elements */
472 #define REMOVE_CALC_NONSTEREO       1 /* 1=> check new stereo numberings to remove parities from non-stereogenic elements */
473 #define PROPAGATE_ILL_DEF_STEREO    1 /* 1=> if at least one of the pair of constitutionally identical (far) neighbors */
474                                       /*     (of the tested atom) has ill-defined stereo parity and another has any */
475                                       /*     stereo parity then set the parity of the tested atom to ill-defined value. */
476 
477 #define ONLY_DOUBLE_BOND_STEREO     0  /* 1=> no alt bond stereo, no taut. bond attachment to stereo bond */
478                                        /* 0=> allow other definitions (below) to be active */
479 #define ONE_BAD_SB_NEIGHBOR         1  /* 1 => allow 1 "bad" bond type neighbor to a stereobond atom. 2004-06-02 */
480 
481 /* more stereo settings */
482 #define BREAK_ONE_MORE_SC_TIE       1   /* break one more tie when comparing possible stereocenter neighbors */
483 #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 */
484 #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) */
485 
486 #define STEREO_CENTER_BONDS_NORM   1   /* set length of the bonds around a stereocenter = 1 before getting the parity  */
487 #define STEREO_CENTER_BOND4_NORM   0   /* set length of the added bond around a stereocenter = 1 before getting the parity  */
488 #define NORMALIZE_INP_COORD        0   /* 0=>keep unchanged, 1 => make atom coordinates integer values, avg bond len=20 */
489 
490 /* recent stereo */
491 #define STEREO_WEDGE_ONLY          1 /* 1=> only pointed ends stereo bonds define stereo; 0=> both ends 1.12Beta */
492 #define CHECK_C2v_S4_SYMM          0 /* post-1.12Beta 1=> check if a stereocenter has C2v or S4 symmetry; 0=>old mode */
493 
494 #define EQL_H_NUM_TOGETHER          1 /* 1=> output 1-3,5H2 intead of 1-3H2,5H2 (CT_MODE_EQL_H_TOGETHER)  */
495 #define ABC_CT_NUM_CLOSURES         1 /* 1=> in coinnections compressed format output decimal number of closures instead of '-' */
496 
497 /* temporary fix */
498 #define SINGLET_IS_TRIPLET          1 /* 'singlet' means two electrons make a lone pair instead of 2 bonds
499                                          its effect on valence is same as the effect of a triplet */
500 
501 /* defug: find structures where canonical partition is different from equitable */
502 #define FIND_CANON_NE_EQUITABLE     0  /* 0=>normal mode */
503                                        /* 1=> extract (set EXTR_FLAGS = (EXTR_CANON_NE_EQUITABLE)*/
504                                        /*     set cmd line options: /onlynonTAUT /: /UNCHARGEDACIDS:1 /DISCONSALT:0 /MOVEPOS:0 /DISCONMETAL:0 */
505 
506 /* Debug: definitions for the extraction of the structures to the problem file */
507 
508 /* definition of the flags for structure extraction to the
509    problem file (for debugging and non-standard searching) */
510 #define EXTR_KNOWN_USED_TO_REMOVE_PARITY  0x000001
511 #define EXTR_CALC_USED_TO_REMOVE_PARITY   0x000002
512 #define EXTR_2EQL2CENTER_TO_REMOVE_PARITY 0x000004
513 #define EXTR_HAS_ATOM_WITH_DEFINED_PARITY 0x000008
514 #define EXTR_REMOVE_PARITY_WARNING        0x000010
515 #define EXTR_SALT_WAS_DISCONNECTED        0x000020
516 #define EXTR_SALT_PROTON_MOVED            0x000040
517 #define EXTR_SALT_PROTON_MOVE_ERR_WARN    0x000080
518 #define EXTR_METAL_WAS_DISCONNECTED       0x000100
519 #define EXTR_METAL_WAS_NOT_DISCONNECTED   0x000200
520 #define EXTR_NON_TRIVIAL_STEREO           0x000400 /* (Inv != Abs stereo) && (parities can't be obtained by inverting them) */
521 #define EXTR_UNUSUAL_VALENCES             0x000800
522 #define EXTR_HAS_METAL_ATOM               0x001000
523 #define EXTR_TEST_TAUT3_SALTS_DONE        0x002000 /* non-oxygen t-points used to discover tautomerism of merged t-groups */
524 #define EXTR_CANON_NE_EQUITABLE           0x004000 /* find structures where canonical partition is different from equitable */
525 #define EXTR_HAS_PROTON_PN                0x008000 /* has movable H+ attached to N or P */
526 #define EXTR_HAS_FEATURE                  0x010000 /* found a feature */
527 #define EXTR_TAUT_TREATMENT_CHARGES       0x020000 /* tautomeric treatment of charges */
528 #define EXTR_TRANSPOSITION_EXAMPLES       0x040000 /* extract structures that have different mobile-H and fixed-H orders */
529 
530 /* define conditions of structure extraction to the problem file */
531 #define EXTR_MASK                        0 /*EXTR_TAUT_TREATMENT_CHARGES*/ /*(EXTR_HAS_FEATURE)*/ /*(EXTR_UNUSUAL_VALENCES | EXTR_HAS_METAL_ATOM)*/ /* 0 to disable */
532 #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) */
533 
534 
535 #define ENTITY_REFS_IN_XML_MESSAGES 1 /* 1=> replace ' " < > & in error/warning messages with xml entity references */
536 
537 /* added tautomeric structures */
538 
539 #define TAUT_TROPOLONE_7            1  /* 1=> tautomeric 7-member rings ON */
540 #define TAUT_TROPOLONE_5            1  /* 1=> taut. similar to tropolone, 5-member ring */
541 #define TAUT_4PYRIDINOL_RINGS       1  /* 1=> OH-C5H4N rings tautomerism */
542 #define TAUT_PYRAZOLE_RINGS         1  /* 1=> tautomerizm in pyrazole rings */
543 /* limitation on tautomerism detection: */
544 #define TAUT_IGNORE_EQL_ENDPOINTS   0  /* 0=> even though 2 endpoints belong to same t-group check
545                                               them to find more alt bonds (new)
546                                           1=> ignore and do not check (old mode) */
547 #define TAUT_RINGS_ATTACH_CHAIN     1  /* 1=> allow only chain attachments to tautomeric endpoints */
548                                        /*     (except pyrazole, where is no tautomeric attachment) */
549                                        /* 0=> allow taut. attachments from same ring system. Default=1 */
550 
551 #define FIND_RING_SYSTEMS           1  /* 1 => find and mark ring systems, blocks, cut-vertices */
552                                        /* Needed for 5- and 6-member ring tautomers and in other places */
553 
554 #define FIND_RINS_SYSTEMS_DISTANCES 0  /* 1 => find ring system and atom distance from terminal */
555 #define USE_DISTANCES_FOR_RANKING   0  /* 1 => rank ring systems according to distances from terminal */
556 
557 #define DISPLAY_RING_SYSTEMS        0  /* 1 => for debug only; displays: */
558                                        /* "block no"/"ring system no"/"cut-vertex (num. intersecting blocks-1)" */
559                                        /* instead of ranks */
560 /* consistency */
561 
562 #if ( bRELEASE_VERSION==1 && bOUTPUT_ONE_STRUCT_TIME==1)
563 #undef bOUTPUT_ONE_STRUCT_TIME
564 #define bOUTPUT_ONE_STRUCT_TIME 0
565 #endif
566 
567 /* consistency: bRELEASE_VERSION==1 needs FIND_RING_SYSTEMS=1 */
568 #if ( bRELEASE_VERSION==1 && FIND_RING_SYSTEMS!=1 )
569 #ifdef FIND_RING_SYSTEMS
570 #undef FIND_RING_SYSTEMS
571 #endif
572 #define FIND_RING_SYSTEMS 1
573 #endif
574 
575 /* consistency: FIND_RINS_SYSTEMS_DISTANCES needs FIND_RING_SYSTEMS  */
576 #if ( FIND_RING_SYSTEMS != 1 )
577 
578 #if ( FIND_RINS_SYSTEMS_DISTANCES == 1 )
579 #undef  FIND_RINS_SYSTEMS_DISTANCES
580 #define FIND_RINS_SYSTEMS_DISTANCES 0
581 #endif
582 
583 #endif
584 
585 /* consistency: USE_DISTANCES_FOR_RANKING and DISPLAY_RING_SYSTEMS need FIND_RINS_SYSTEMS_DISTANCES */
586 #if ( FIND_RINS_SYSTEMS_DISTANCES != 1 )
587 
588 #if ( USE_DISTANCES_FOR_RANKING == 1 )
589 #undef  USE_DISTANCES_FOR_RANKING
590 #define USE_DISTANCES_FOR_RANKING 0
591 #endif
592 
593 #if ( DISPLAY_RING_SYSTEMS == 1 )
594 #undef  DISPLAY_RING_SYSTEMS
595 #define DISPLAY_RING_SYSTEMS 0
596 #endif
597 
598 #endif
599 
600 
601 #if ( FIND_RING_SYSTEMS==1 && (TAUT_TROPOLONE_7==1 || TAUT_TROPOLONE_5==1 || TAUT_4PYRIDINOL_RINGS==1 || TAUT_PYRAZOLE_RINGS) )
602 #define TAUT_OTHER 1
603 #else
604 #define TAUT_OTHER 0
605 #endif
606 
607 #define APPLY_IMPLICIT_H_DOWN_RULE 0   /* 1=> if 3 non-H atoms around stereocenter are in same plane */
608                                        /*     then add "down" hydrogen to obtain sterecenter oparity */
609                                        /* 0=> Implicit H stereo is unknown if all bonds to 3 non-H atoms */
610                                        /*     are in XY plane */
611 #define ALLOW_TAUT_ATTACHMENTS_TO_STEREO_BONDS 1 /* 1=> consider bond in an alternating circuit stereogenic */
612                                                  /*     even though it has adjacent tautomeric atom(s) */
613 
614 #define IGNORE_TGROUP_WITHOUT_H   1    /* ignore tautomeric groups containing charges only */
615 
616 #if ( DISCONNECT_SALTS == 1 )
617 #define REMOVE_TGROUP_CHARGE      0    /* 0: do not remove charge information from tautomeric groups */
618 #else
619 #define REMOVE_TGROUP_CHARGE      1    /* 1: remove charge information from tautomeric groups */
620 #endif
621 
622 #if ( REMOVE_TGROUP_CHARGE == 1 )
623 #define INCHI_T_NUM_MOVABLE  1
624 #else
625 #define INCHI_T_NUM_MOVABLE  2
626 #endif
627 
628 /******************************************/
629 /*   define canonicalization modes here   */
630 /******************************************/
631 
632 #define USE_AUX_RANKING        1 /* 1=> get auxiliary ranking to accelerate canonicalization of H layers */
633 #define USE_AUX_RANKING_ALL    1 /* 1=> include all vertices in CellGetMinNode() selection 0=> only vertices with highest ranks */
634 
635 #define USE_ISO_SORT_KEY_HFIXED  0  /* 0=> normal mode: merge isotopic taut H to isotopic atom sorting key in
636                                            taut H-fixed canonicalization;
637                                        1=> add one more "string" iso_sort_Hfixed to the canonicalization */
638 
639 /************************
640   questionable behavior
641  ************************/
642 #define REL_RAC_STEREO_IGN_1_SC  0 /* 1=> drop from InChI sp3 stereo in components that have a single stereocenter */
643                                    /* 0=> old-old mode (all such sp3 stereo is in the Identifier) */
644 /* internal definitions; see also REQ_MODE_BASIC etc in ichi.h */
645 #define CMODE_CT                 0x000001
646 #define CMODE_ISO                0x000002
647 #define CMODE_ISO_OUT            0x000004 /* obsolete ? */
648 #define CMODE_STEREO             0x000008
649 #define CMODE_ISO_STEREO         0x000010
650 #define CMODE_TAUT               0x000020
651 #define CMODE_NOEQ_STEREO        0x000040 /* 5-24-2002: do not use stereo equivalence to accelerate */
652 #define CMODE_REDNDNT_STEREO     0x000080 /* 6-11-2002: do not check for redundant stereo elements */
653 #define CMODE_NO_ALT_SBONDS      0x000100 /* 6-14-2002: do not assign stereo to alternating bonds */
654 /* new 10-10-2003 */
655 #define CMODE_RELATIVE_STEREO    0x000200    /* REL All Relative Stereo */
656 #define CMODE_RACEMIC_STEREO     0x000400    /* RAC All Racemic Stereo */
657 #define CMODE_SC_IGN_ALL_UU      0x000800    /* IAUSC Ignore stereocenters if All Undef/Unknown */
658 #define CMODE_SB_IGN_ALL_UU      0x001000    /* IAUSC Ignore stereobonds if All Undef/Unknown */
659 /* end of 10-10-2003 */
660 
661 /* external definitions */
662 #define CANON_MODE_CT         (CMODE_CT)
663 #define CANON_MODE_TAUT       (CMODE_CT|CMODE_TAUT)
664 #define CANON_MODE_ISO        (CMODE_CT|CMODE_ISO|CMODE_ISO_OUT)
665 #define CANON_MODE_STEREO     (CMODE_CT|CMODE_STEREO)
666 #define CANON_MODE_ISO_STEREO (CMODE_CT|CMODE_ISO|CMODE_ISO_OUT|CMODE_ISO_STEREO)
667 
668 #define CANON_MODE_MASK       0x00FF  /* used to determine canonicalization mode */
669 
670 /*************************************************
671  * from d_norm.c
672  */
673 
674 /* implemented definitions for CT_ATOMID */
675 #define CT_ATOMID_DONTINCLUDE   1
676 #define CT_ATOMID_IS_INITRANK   2
677 #define CT_ATOMID_IS_CURRANK    3
678 
679 /***************************************
680  * canonicalization settings  I
681  ***************************************/
682 
683 #define CANON_TAUTOMERS                1  /* 1=> process tautomers */
684 #define HYDROGENS_IN_INIT_RANKS        1  /* 1=> include num_H in initial ranking */
685 
686 #define DOUBLE_BOND_NEIGH_LIST    0  /* 1 => include double bond neighbor in NeighList 2 times */
687 #define INCL_NON_6AROM            1  /* 1 => mark all arom. bonds; 0=>mark arom. bonds only in 6-member rings */
688 
689 #define CT_SMALLEST             /* minimal CT */
690 
691 #define CT_NEIGH_SMALLER        /* in CT, include neighbors with smaller ranks */
692 
693 #define CT_ATOMID          CT_ATOMID_IS_CURRANK /*CT_ATOMID_DONTINCLUDE */
694 
695 #define CT_NEIGH_INCREASE               /* in CT, neighbors ranks increase  */
696 
697 #define USE_SYMMETRY_TO_ACCELERATE 1   /*1 => for fast CT canonicalization, to avoid full enumeration */
698 
699 /* dependent definitions due to settings */
700 
701 #ifdef CT_SMALLEST
702 #define CT_GREATER_THAN    >
703 #define CT_INITVALUE      ~0
704 #define BEST_PARITY        1  /* odd */
705 #define WORSE_PARITY       2
706 #else
707 #define CT_GREATER_THAN    <
708 #define CT_INITVALUE       0
709 #define BEST_PARITY        2  /* even */
710 #define WORSE_PARITY       1
711 #endif
712 
713 #ifdef CT_NEIGH_SMALLER
714 #define CT_NEIGH_SMALLER_THAN <
715 #else
716 #define CT_NEIGH_SMALLER_THAN >
717 #endif
718 
719 /* verify corectness of dependent settings */
720 #if !defined( CT_ATOMID )
721   #error  You have to #define CT_ATOMID
722 #else
723 #if ( defined( CT_ATOMID ) && CT_ATOMID==CT_ATOMID_DONTINCLUDE )
724   #error  CT_DELIMITER should be #defined if CT_ATOMID is not included
725 #endif
726 #endif
727 
728 /***************************************
729  * canonicalization settings  II
730  ***************************************/
731 /* from extr_ct.h */
732 #define ALL_ALT_AS_AROMATIC         1  /* 1 => all altrnate bonds (even in cyclooctateraene) treat as aromatic */
733                                        /*      and set DOUBLE_BOND_NEIGH_LIST = 0 */
734 #define ANY_ATOM_IN_ALT_CYCLE       1  /* 1=> accept any atom in alternating bond circuit, 0=>only some */
735 
736 #define EXCL_ALL_AROM_BOND_PARITY   0  /* 1 => any arom atom cannot belong to stereo bond. */
737                                        /*      This has presedence over ADD_6MEMB_AROM_BOND_PARITY=1 */
738                                        /* 0 => include arom bonds parities according to */
739                                        /*      ADD_6MEMB_AROM_BOND_PARITY definition */
740 
741 #if ( EXCL_ALL_AROM_BOND_PARITY == 0 )
742 #define ADD_6MEMB_AROM_BOND_PARITY  1  /* 1 => all arom bonds are stereo bonds */
743                                        /* 0 => only those arom bonds which do not belong to */
744                                        /*      6-member arom rings are stereo bonds */
745 #else
746 #define ADD_6MEMB_AROM_BOND_PARITY  0  /* 0 => standard; 1 => meaningless: ignore parities of non-6-member ring alt. bonds */
747 #endif
748 
749 #define CML_NUM_AT_IN_ATREF4      4
750 #define MAX_NUM_STEREO_BONDS      3
751 #define MAX_NUM_STEREO_BOND_NEIGH 3
752 #define MIN_NUM_STEREO_BOND_NEIGH 2
753 
754 #define MAX_NUM_STEREO_ATOM_NEIGH 4
755 #define STEREO_AT_MARK            8 /* > MAX_NUM_STEREO_BONDS */
756 
757 #if ( ONLY_DOUBLE_BOND_STEREO == 1 )  /* { */
758 
759 #ifdef ALLOW_TAUT_ATTACHMENTS_TO_STEREO_BONDS
760 #undef ALLOW_TAUT_ATTACHMENTS_TO_STEREO_BONDS
761 #define ALLOW_TAUT_ATTACHMENTS_TO_STEREO_BONDS 0
762 #endif
763 
764 #ifdef EXCL_ALL_AROM_BOND_PARITY
765 #undef EXCL_ALL_AROM_BOND_PARITY
766 #define EXCL_ALL_AROM_BOND_PARITY 1
767 #endif
768 
769 #ifdef ADD_6MEMB_AROM_BOND_PARITY
770 #undef ADD_6MEMB_AROM_BOND_PARITY
771 #define ADD_6MEMB_AROM_BOND_PARITY 0
772 #endif
773 
774 #endif /* } ONLY_DOUBLE_BOND_STEREO */
775 
776 /* dependent definitions due to settings */
777 #if ( ALL_ALT_AS_AROMATIC == 1 && DOUBLE_BOND_NEIGH_LIST != 0 )
778 #undef DOUBLE_BOND_NEIGH_LIST
779 #define DOUBLE_BOND_NEIGH_LIST 0
780 #endif
781 
782 
783 /*************************************
784  * Drawing
785  */
786 
787 #define DRAW_AROM_TAUT  1              /* 1=> draw distinct aromatic & tautomer bonds, 0=> don't */
788 
789 /******************************************************/
790 /*       C O M M O N     D E F I N I T I O N S        */
791 /******************************************************/
792 
793 
794 /* input bTautFlags flags */
795 #define TG_FLAG_TEST_TAUT__ATOMS         0x00000001   /* find regular tautomerism */
796 #define TG_FLAG_DISCONNECT_SALTS         0x00000002   /* DISCONNECT_SALTS disconnect */
797 #define TG_FLAG_TEST_TAUT__SALTS         0x00000004   /* DISCONNECT_SALTS if possible find long-range H/(-) taut. on =C-OH, >C=O    */
798 #define TG_FLAG_MOVE_POS_CHARGES         0x00000008   /* MOVE_CHARGES allow long-range movement of N(+), P(+) charges           */
799 #define TG_FLAG_TEST_TAUT2_SALTS         0x00000010   /* TEST_REMOVE_S_ATOMS multi-attachement long-range H/(-) taut. on =C-OH, >C=O   */
800 #define TG_FLAG_ALLOW_NO_NEGTV_O         0x00000020   /* CHARGED_SALTS_ONLY=0 (debug) find long-range H-only tautomerism on =C-OH, >C=O */
801 #define TG_FLAG_MERGE_TAUT_SALTS         0x00000040   /* DISCONNECT_SALTS merge all "salt"-t-groups and other =C-OH into one t-group */
802 
803 #define TG_FLAG_ALL_TAUTOMERIC          (TG_FLAG_TEST_TAUT__ATOMS| \
804                                          TG_FLAG_TEST_TAUT__SALTS| \
805                                          TG_FLAG_TEST_TAUT2_SALTS| \
806                                          TG_FLAG_MERGE_TAUT_SALTS)
807 
808 #define TG_FLAG_DISCONNECT_COORD         0x00000080   /* find "coord. centers" and disconnect them */
809 #define TG_FLAG_RECONNECT_COORD          0x00000100   /* reconnect disconnected "coord. centers" */
810 #define TG_FLAG_CHECK_VALENCE_COORD      0x00000200   /* do not disconnect "coord. centers" with usual valence */
811 #define TG_FLAG_MOVE_HPLUS2NEUTR         0x00000400   /* move protons to neutralize */
812 #define TG_FLAG_VARIABLE_PROTONS         0x00000800   /* add/remove protons to neutralize */
813 #define TG_FLAG_HARD_ADD_REM_PROTONS     0x00001000   /* add/remove protons to neutralize in hard way */
814 #define TG_FLAG_POINTED_EDGE_STEREO      0x00002000   /* only pointed edge of stereo bond defines stereo */
815 #if ( FIX_ADJ_RAD == 1 )
816 #define TG_FLAG_FIX_ADJ_RADICALS         0x00004000   /* remove adjacent radical-doubletes, fix valence */
817 #endif
818 #define TG_FLAG_PHOSPHINE_STEREO         0x00008000   /* add phosphine sp3 stereo */
819 #define TG_FLAG_ARSINE_STEREO            0x00010000   /* add arsine sp3 stereo */
820 #define TG_FLAG_H_ALREADY_REMOVED        0x00020000   /* processing structure restored from InChI */
821 #define TG_FLAG_FIX_SP3_BUG              0x00040000   /* fix sp3 stereo bug: overlapping 2D stereo bond & coordinate scaling */
822 
823 #define TG_FLAG_KETO_ENOL_TAUT           0x00080000   /* turn on keto-enol tautomerism detection */
824 #define TG_FLAG_1_5_TAUT                 0x00100000   /* turn on 1,5 tautomerism detection */
825 
826 /*^^^ FB2 */
827 #define TG_FLAG_FIX_ISO_FIXEDH_BUG       0x00200000   /* fix bug found after v.102b (isotopic H representation)  */
828 #define TG_FLAG_FIX_TERM_H_CHRG_BUG      0x00400000   /* fix bug found after v.102b (moving H charge in 'remove_terminal_HDT') */
829 
830 /* output bTautFlags flags */
831 
832 #define TG_FLAG_MOVE_HPLUS2NEUTR_DONE    0x00000001   /* protons have been moved to neutralize */
833 #define TG_FLAG_TEST_TAUT__ATOMS_DONE    0x00000002
834 #define TG_FLAG_DISCONNECT_SALTS_DONE    0x00000004
835 #define TG_FLAG_TEST_TAUT__SALTS_DONE    0x00000008   /* multiple H tautomerism */
836 #define TG_FLAG_MOVE_POS_CHARGES_DONE    0x00000010
837 #define TG_FLAG_TEST_TAUT2_SALTS_DONE    0x00000020   /* merged t-groups */
838 #define TG_FLAG_ALLOW_NO_NEGTV_O_DONE    0x00000040
839 #define TG_FLAG_MERGE_TAUT_SALTS_DONE    0x00000080   /* added non-taut O to taut groups */
840 
841 #define TG_FLAG_ALL_SALT_DONE          (TG_FLAG_TEST_TAUT__SALTS_DONE | \
842                                         TG_FLAG_TEST_TAUT2_SALTS_DONE | \
843                                         TG_FLAG_MERGE_TAUT_SALTS_DONE )
844 
845 #define TG_FLAG_DISCONNECT_COORD_DONE    0x00000100   /* found and disconnected "coord. centers" */
846 #define TG_FLAG_CHECK_VALENCE_COORD_DONE 0x00000200   /* did not disconnect "coord. centers" with usual valence */
847 #define TG_FLAG_MOVE_CHARGE_COORD_DONE   0x00000400   /* changed charge of a disconnected ligand to fit its valence */
848 #define TG_FLAG_FIX_ODD_THINGS_DONE      0x00000800   /* fixed drawing ambiguities in fix_odd_things */
849 #define TG_FLAG_TEST_TAUT3_SALTS_DONE    0x00001000   /* merged t-groups + non-O taut atoms */
850 #define TG_FLAG_FOUND_SALT_CHARGES_DONE  0x00002000   /* not assigned: preprocessing detected possibility of salt-type tautomerism */
851 #define TG_FLAG_FOUND_ISOTOPIC_H_DONE    0x00004000   /* preprocessing detected isotopic H on "good" heteroatoms or isotopic H(+) */
852 #define TG_FLAG_FOUND_ISOTOPIC_ATOM_DONE 0x00008000   /* preprocessing detected isotopic H on "good" heteroatoms or isotopic H(+) */
853 #if ( FIX_ADJ_RAD == 1 )
854 #define TG_FLAG_FIX_ADJ_RADICALS_DONE    0x00010000
855 #endif
856 
857 #if ( READ_INCHI_STRING == 1 )
858 #define READ_INCHI_OUTPUT_INCHI          0x00000001
859 #define READ_INCHI_SPLIT_OUTPUT          0x00000002
860 #define READ_INCHI_KEEP_BALANCE_P        0x00000004
861 #define READ_INCHI_TO_STRUCTURE          0x00000008
862 #endif
863 
864 
865 
866 
867 /*********/
868 /*       */
869 /*  I/O  */
870 /*       */
871 /*********/
872 
873 typedef struct tagOutputString
874 {
875     char *pStr;
876     int  nAllocatedLength;
877     int  nUsedLength;
878     int  nPtr;
879 } INCHI_OUTPUT;
880 
881 typedef struct tagOutputStream
882 {
883     /* output is directed either to resizable string buffer: */
884     INCHI_OUTPUT s;
885     /* or to the plain file: */
886     FILE* f;
887     int type;
888 } INCHI_IOSTREAM;
889 /* INCHI_IOSTREAM.type values */
890 #define INCHI_IOSTREAM_NONE 0
891 #define INCHI_IOSTREAM_STRING 1
892 #define INCHI_IOSTREAM_FILE 2
893 
894 
895 
896 
897 /***********/
898 /*         */
899 /*  DEBUG  */
900 /*         */
901 /***********/
902 
903 #if ( defined(_WIN32) && defined(_DEBUG) && defined(_MSC_VER) /*&& !defined(COMPILE_ANSI_ONLY)*/ )
904 /* debug: memory leaks tracking */
905 #ifndef TARGET_LIB_FOR_WINCHI
906 #ifndef DO_NOT_TRACE_MEMORY_LEAKS
907 #define TRACE_MEMORY_LEAKS          1    /* 1=>trace, 0 => do not trace (Debug only) */
908 #else
909 #define TRACE_MEMORY_LEAKS          0
910 #endif
911 #else
912 #define TRACE_MEMORY_LEAKS          1    /* 1=>trace, **ALWAYS** =1 for TARGET_LIB_FOR_WINCHI */
913 #endif
914 #else /* not MSC and not Debug */
915 #define TRACE_MEMORY_LEAKS          0    /* 0: do not change */
916 #endif
917 
918 
919 /* memory leaks tracking */
920 #define INCHI_HEAPCHK          /* default: no explicit heap checking during the execution */
921 
922 #if ( TRACE_MEMORY_LEAKS == 1 )
923 #ifdef _DEBUG
924 
925 #define   inchi_malloc(s)         _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
926 #define   inchi_calloc(c, s)      _calloc_dbg(c, s, _NORMAL_BLOCK, __FILE__, __LINE__)
927 #define   inchi_free(p)           _free_dbg(p, _NORMAL_BLOCK)
928 
929 #ifdef TARGET_EXE_USING_API
930 /* INChI_MAIN specific */
931 #define e_inchi_malloc(a)   inchi_malloc(a)
932 #define e_inchi_calloc(a,b) inchi_calloc(a,b)
933 #define e_inchi_free(a)     inchi_free(a)
934 #endif
935 
936 /*#define  _CRTDBG_MAP_ALLOC*/  /* standard VC++ tool -- does not work with inchi_malloc(), etc */
937 
938 #include <crtdbg.h>
939 
940 /* to enable heap checking: #define CHECK_WIN32_VC_HEAP above #include "mode.h" in each source file or here */
941 #ifdef CHECK_WIN32_VC_HEAP
942 /* -- Confirms the integrity of the memory blocks allocated in the debug heap  -- */
943 #undef INCHI_HEAPCHK
944 #define INCHI_HEAPCHK \
945 do { \
946     int tmp = _crtDbgFlag; \
947     _crtDbgFlag |= _CRTDBG_ALLOC_MEM_DF; \
948     _ASSERT( _CrtCheckMemory( ) ); \
949     _crtDbgFlag = tmp; \
950 } while(0);
951 
952 /*  -- less thorough than _CrtCheckMemory() check: check minimal consistency of the heap -- */
953 /*
954 #include <malloc.h>
955 #define INCHI_HEAPCHK \
956 do {\
957    int heapstatus = _heapchk(); \
958    _ASSERT( heapstatus != _HEAPBADBEGIN && heapstatus != _HEAPBADNODE && heapstatus != _HEAPBADPTR); \
959 } while(0);
960 */
961 #endif
962 
963 #else
964 #undef  TRACE_MEMORY_LEAKS
965 #define TRACE_MEMORY_LEAKS 0
966 #endif  /* _DEBUG */
967 #endif  /* TRACE_MEMORY_LEAKS */
968 
969 
970 
971 /***********/
972 /*         */
973 /*  ALLOC  */
974 /*         */
975 /***********/
976 
977 #ifdef TARGET_EXE_USING_API
978 /* INChI_MAIN specific */
979 #ifndef inchi_malloc
980 #define inchi_malloc   e_inchi_malloc
981 #endif
982 #ifndef inchi_calloc
983 #define inchi_calloc   e_inchi_calloc
984 #endif
985 #ifndef inchi_free
986 #define inchi_free     e_inchi_free
987 #endif
988 
989 #ifndef e_inchi_malloc
990 #define e_inchi_malloc malloc
991 #endif
992 #ifndef e_inchi_calloc
993 #define e_inchi_calloc calloc
994 #endif
995 #ifndef e_inchi_free
996 #define e_inchi_free(X) do{ if(X) free(X); }while(0)
997 #endif
998 
999 #else /* not TARGET_EXE_USING_API */
1000 
1001 #ifndef inchi_malloc
1002 #define inchi_malloc   malloc
1003 #endif
1004 #ifndef inchi_calloc
1005 #define inchi_calloc   calloc
1006 #endif
1007 #ifndef inchi_free
1008 #define inchi_free(X)  do{ if(X) free(X); }while(0)
1009 #endif
1010 
1011 #endif /* TARGET_EXE_USING_API */
1012 
1013 /* allocation/deallocation */
1014 #define USE_ALLOCA 0
1015 
1016 #if ( USE_ALLOCA == 1 )
1017 #define qmalloc(X) _alloca(X)
1018 #define qfree(X)   do{(X)=NULL;}while(0)
1019 #else
1020 #define qmalloc(X) inchi_malloc(X)
1021 #define qfree(X)   do{if(X){inchi_free(X);(X)=NULL;}}while(0)
1022 #endif
1023 
1024 #if ( defined(_MSC_VER) && _MSC_VER >= 800 )
1025 #define fast_alloc(X) _alloca(X)
1026 #define fast_free(X)
1027 #else
1028 #define fast_alloc(X) inchi_malloc(X)
1029 #define fast_free(X)  inchi_free(X)
1030 #endif
1031 
1032 #define qzfree(X)   do{if(X){inchi_free(X);(X)=NULL;}}while(0)
1033 
1034 /* rellocation */
1035 
1036 #define MYREALLOC2(PTRTYPE1, PTRTYPE2, PTR1, PTR2, LEN1, LEN2, ERR) \
1037     do { \
1038         if( (LEN1) <= (LEN2) ) {\
1039             PTRTYPE1 * newPTR1 = (PTRTYPE1 *)inchi_calloc( (LEN2)+1, sizeof(PTRTYPE1) );\
1040             PTRTYPE2 * newPTR2 = (PTRTYPE2 *)inchi_calloc( (LEN2)+1, sizeof(PTRTYPE2) );\
1041             if ( newPTR1 && newPTR2 ) { \
1042                 if ( (PTR1) && (LEN1) > 0 ) \
1043                     (memcpy) ( newPTR1, (PTR1), (LEN1) * sizeof(PTRTYPE1) ); \
1044                 if ( (PTR2) && (LEN1) > 0 ) \
1045                     (memcpy) ( newPTR2, (PTR2), (LEN1) * sizeof(PTRTYPE2) ); \
1046                 if ( PTR1 ) \
1047                     inchi_free(PTR1);  \
1048                 if ( PTR2 ) \
1049                     inchi_free(PTR2);  \
1050                 (PTR1) = newPTR1; \
1051                 (PTR2) = newPTR2; \
1052                 (LEN1) = (LEN2);  \
1053                 (ERR)  = 0; \
1054             } else {        \
1055                 (ERR)  = 1; \
1056             }               \
1057         } else { (ERR) = 0; } \
1058     } while(0)
1059 
1060 
1061 
1062 
1063 #ifndef COMPILE_ALL_CPP
1064 #ifdef __cplusplus
1065 }
1066 #endif
1067 #endif
1068 
1069 
1070 #endif /* __MODE_H__ */
1071