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 #ifndef __INHCH_API_H__
41 #define __INHCH_API_H__
42 
43 
44 
45 
46 /*^^^ Post-1.02b fix - thanks to David Foss */
47 #ifndef FIND_RING_SYSTEMS
48 #define FIND_RING_SYSTEMS 1
49 #endif
50 #ifndef FIND_RINS_SYSTEMS_DISTANCES
51 #define FIND_RINS_SYSTEMS_DISTANCES 0
52 #endif
53 
54 
55 /* radical definitions */
56 typedef enum tagINCHIRadical {
57    INCHI_RADICAL_NONE    = 0,
58    INCHI_RADICAL_SINGLET = 1,
59    INCHI_RADICAL_DOUBLET = 2,
60    INCHI_RADICAL_TRIPLET = 3
61 } inchi_Radical;
62 
63 /* bond type definitions */
64 typedef enum tagINCHIBondType {
65    INCHI_BOND_TYPE_NONE    =  0,
66    INCHI_BOND_TYPE_SINGLE  =  1,
67    INCHI_BOND_TYPE_DOUBLE  =  2,
68    INCHI_BOND_TYPE_TRIPLE  =  3,
69    INCHI_BOND_TYPE_ALTERN  =  4  /* avoid by all means */
70 } inchi_BondType;
71 /* 2D stereo definitions */
72 typedef enum tagINCHIBondStereo2D {
73    /* stereocenter-related; positive: the sharp end points to this atom  */
74    INCHI_BOND_STEREO_NONE           =  0,
75    INCHI_BOND_STEREO_SINGLE_1UP     =  1,
76    INCHI_BOND_STEREO_SINGLE_1EITHER =  4,
77    INCHI_BOND_STEREO_SINGLE_1DOWN   =  6,
78    /* stereocenter-related; negative: the sharp end points to the opposite atom  */
79    INCHI_BOND_STEREO_SINGLE_2UP     = -1,
80    INCHI_BOND_STEREO_SINGLE_2EITHER = -4,
81    INCHI_BOND_STEREO_SINGLE_2DOWN   = -6,
82    /* stereobond-related */
83    INCHI_BOND_STEREO_DOUBLE_EITHER  =  3 /* unknown stereobond geometry */
84 } inchi_BondStereo2D;
85 
86 /*************************************************************************
87  * Notes on using INCHI_BOND_STEREO_SINGLE_*  from inchi_BondStereo2D    *
88  *                                                                       *
89  * These stereo markings are used by InChI to characterize a stereogenic *
90  * atom if and only if all neighbors of this atom have same z-coordinate *
91  * as this atom (that is, in case of 2D fragment).                       *
92  * The only exception is INCHI_BOND_STEREO_SINGLE_?EITHER marking which  *
93  * always assigns to the atom an "unknown" parity (u).                   *
94  *                                                                       *
95  * Note the behavior which is default for InChI software v.1.04/03/02std *
96  * (at -NEWPSOFF option is not supplied) 2D stereo interpretation:       *
97  * only bonds that have sharp end pointing to the stereogenic atom are   *
98  * considered as being out of plane and only sharp ends of               *
99  * INCHI_BOND_STEREO_SINGLE_?EITHER bonds are considered to determine    *
100  * whether the stereochemistry is unknown.                               *
101  *************************************************************************/
102 
103 /* sizes definitions */
104 #define MAXVAL                   20 /* max number of bonds per atom                 */
105 #define ATOM_EL_LEN               6 /* length of ASCIIZ element symbol field        */
106 #define NUM_H_ISOTOPES            3 /* number of hydrogen isotopes: protium, D, T   */
107 #define ISOTOPIC_SHIFT_FLAG   10000 /* add to isotopic mass if isotopic_mass =      */
108                                     /* (isotopic mass - average atomic mass)        */
109 #define ISOTOPIC_SHIFT_MAX      100 /* max abs(isotopic mass - average atomic mass) */
110 
111 #ifndef INCHI_US_CHAR_DEF
112 typedef signed char   S_CHAR;
113 typedef unsigned char U_CHAR;
114 #define INCHI_US_CHAR_DEF
115 #endif
116 
117 #ifndef INCHI_US_SHORT_DEF
118 typedef signed short   S_SHORT;
119 typedef unsigned short U_SHORT;
120 #define INCHI_US_SHORT_DEF
121 #endif
122 
123 typedef  S_SHORT AT_NUM;            /* atom number; starts from 0 */
124 
125 /*************************************************
126  *
127  *
128  *  A T O M S   a n d   C O N N E C T I V I T Y
129  *
130  *
131  *************************************************/
132 
133 typedef struct tagInchiAtom {
134     /* atom coordinates */
135     double x;
136     double y;
137     double z;
138     /* connectivity */
139     AT_NUM  neighbor[MAXVAL];     /* adjacency list: ordering numbers of */
140                                   /*            the adjacent atoms, >= 0 */
141     S_CHAR  bond_type[MAXVAL];    /* inchi_BondType */
142     /* 2D stereo */
143     S_CHAR  bond_stereo[MAXVAL];  /* inchi_BondStereo2D; negative if the */
144                                   /* sharp end points to opposite atom */
145     /* other atom properties */
146     char    elname[ATOM_EL_LEN];  /* zero-terminated chemical element name:*/
147                                   /* "H", "Si", etc. */
148     AT_NUM  num_bonds;            /* number of neighbors, bond types and bond*/
149                                   /* stereo in the adjacency list */
150     S_CHAR  num_iso_H[NUM_H_ISOTOPES+1]; /* implicit hydrogen atoms */
151                                   /* [0]: number of implicit non-isotopic H
152                                        (exception: num_iso_H[0]=-1 means INCHI
153                                        adds implicit H automatically),
154                                      [1]: number of implicit isotopic 1H (protium),
155                                      [2]: number of implicit 2H (deuterium),
156                                      [3]: number of implicit 3H (tritium) */
157     AT_NUM  isotopic_mass;        /* 0 => non-isotopic; isotopic mass or  */
158                                   /* ISOTOPIC_SHIFT_FLAG + mass - (average atomic mass) */
159     S_CHAR  radical;              /* inchi_Radical */
160     S_CHAR  charge;               /* positive or negative; 0 => no charge */
161 }inchi_Atom;
162 
163 /*******************************************************************
164  * Notes: 1. Atom ordering numbers (i, k, and atom[i].neighbor[j] below)
165  *           start from zero; max. ordering number is (num_atoms-1).
166  *        2. inchi_Atom atom[i] is connected to the atom[atom[i].neighbor[j]]
167  *           by a bond that has type atom[i].bond_type[j] and 2D stereo type
168  *           atom[i].bond_stereo[j] (in case of no stereo
169  *           atom[i].bond_stereo[j] = INCHI_BOND_STEREO_NONE)
170  *           Index j is in the range 0 <= j <= (atom[i].num_bonds-1)
171  *        3. Any connection (represented by atom[i].neighbor[j],
172  *           atom[i].bond_type[j], and atom[i].bond_stereo[j])
173  *           should be present in one or both adjacency list:
174  *             if k = atom[i].neighbor[j] then i may or may not be present in
175  *           atom[k].neighbor[] list. For example, the adjacency lists may be
176  *           populated with only such neighbors that atom[i].neighbor[j] < i
177  *           All elements of an adjacency list must be different, that is,
178  *           a bond must be specified in an adjacency list only once.
179  *        4. in Molfiles usually
180  *           (number of implicit H) = Valence - SUM(bond_type[])
181  *        5. Seemingly illogical order of the inchi_Atom members was
182  *           chosen in an attempt to avoid alignment problems when
183  *           accessing inchi_Atom from unrelated to C programming
184  *           languages such as Visual Basic.
185  *******************************************************************/
186 
187 /*******************************************************************
188     0D Stereo Parity and Type definitions
189  *******************************************************************
190             Note:
191             =====
192             o Below #A is the ordering number of atom A, starting from 0
193             o See parity values corresponding to 'o', 'e', and 'u' in
194               inchi_StereoParity0D definition below)
195 
196            =============================================
197             stereogenic bond >A=B< or cumulene >A=C=C=B<
198            =============================================
199 
200                                  neighbor[4]  : {#X,#A,#B,#Y} in this order
201      X                           central_atom : NO_ATOM
202       \            X      Y      type         : INCHI_StereoType_DoubleBond
203        A==B         \    /
204            \         A==B
205             Y
206 
207     parity= 'e'    parity= 'o'   unknown parity = 'u'
208 
209     Limitations:
210     ============
211     o Atoms A and B in cumulenes MUST be connected by a chain of double bonds;
212       atoms A and B in a stereogenic 'double bond' may be connected by a double,
213       single, or alternating bond.
214     o One atom may belong to up to 3 stereogenic bonds (i.g. in a fused
215       aromatic structure).
216     o Multiple stereogenic bonds incident to any given atom should
217       either all except possibly one have (possibly different) defined
218       parities ('o' or 'e') or should all have an unknown parity 'u'.
219 
220       Note on parities of alternating stereobonds
221       ===========================================
222                                                      D--E
223       In large rings  (see Fig. 1, all              //   \\
224       atoms are C) all alternating bonds         B--C      F--G
225       are treated as stereogenic.              //              \\
226       To avoid "undefined" bond parities      A                  H
227       for bonds BC, DE, FG, HI, JK, LM, AN     \               /
228       it is recommended to mark them with       N==M       J==I
229       parities.                                     \     /
230                                                       L==K    Fig. 1
231       Such a marking will make
232       the stereochemical layer unambiguous
233       and it will be different from the          B--C      F--G
234       stereochemical layer of the second       //   \\   //    \\
235       structure (Fig. 2).                     A      D--E        H
236                                                \               /
237                                                 N==M       J==I
238       By default, double and alternating            \     /
239       bonds in 8-member and greater rings             L==K    Fig. 2
240       are treated by InChI as stereogenic.
241 
242 
243            =============================================
244             tetrahedral atom
245            =============================================
246 
247    4 neighbors
248 
249             X                    neighbor[4] : {#W, #X, #Y, #Z}
250             |                    central_atom: #A
251          W--A--Y                 type        : INCHI_StereoType_Tetrahedral
252             |
253             Z
254    parity: if (X,Y,Z) are clockwize when seen from W then parity is 'e' otherwise 'o'
255    Example (see AXYZW above): if W is above the plane XYZ then parity = 'e'
256 
257    3 neighbors
258 
259               Y          Y       neighbor[4] : {#A, #X, #Y, #Z}
260              /          /        central_atom: #A
261          X--A  (e.g. O=S   )     type        : INCHI_StereoType_Tetrahedral
262              \          \
263               Z          Z
264 
265    parity: if (X,Y,Z) are clockwize when seen from A then parity is 'e',
266                                                           otherwise 'o'
267    unknown parity = 'u'
268    Example (see AXYZ above): if A is above the plane XYZ then parity = 'e'
269    This approach may be used also in case of an implicit H attached to A.
270 
271            =============================================
272             allene
273            =============================================
274 
275        X       Y                 neighbor[4]  : {#X,#A,#B,#Y}
276         \     /                  central_atom : #C
277          A=C=B                   type         : INCHI_StereoType_Allene
278 
279                                       Y      X
280                                       |      |
281      when seen from A along A=C=B:  X-A    Y-A
282 
283                           parity:   'e'    'o'
284 
285    parity: if A, B, Y are clockwise when seen from X then parity is 'e',
286                                                           otherwise 'o'
287    unknown parity = 'u'
288    Example (see XACBY above): if X on the diagram is above the plane ABY
289                                                       then parity is 'o'
290 
291    Limitations
292    ===========
293    o Atoms A and B in allenes MUST be connected by a chain of double bonds;
294 
295    ==============================================
296    Note. Correspondence to CML 0D stereo parities
297    ==============================================
298    a list of 4 atoms corresponds to CML atomRefs4
299 
300    tetrahedral atom
301    ================
302        CML atomParity > 0 <=> INCHI_PARITY_EVEN
303        CML atomParity < 0 <=> INCHI_PARITY_ODD
304 
305                                     | 1   1   1   1  |  where xW is x-coordinate of
306                                     | xW  xX  xY  xZ |  atom W, etc. (xyz is a
307        CML atomParity = determinant | yW  yX  yY  yZ |  'right-handed' Cartesian
308                                     | zW  zX  xY  zZ |  coordinate system)
309 
310    allene (not yet defined in CML)
311    ===============================
312    the parity corresponds to the sign of the following determinant
313    in exactly same way as for tetrahedral atoms:
314 
315        | 1   1   1   1  |  where bonds and neighbor[4] array are
316        | xX  xA  xB  xY |  same as defined above for allenes
317        | yX  yA  yB  yY |  Obviously, the parity is same for
318        | zX  zA  xB  zY |  {#X,#A,#B,#Y} and {#Y,#B,#A,#X}
319                            because of the even number of column permutations.
320 
321    stereogenic double bond and (not yet defined in CML) cumulenes
322    ==============================================================
323        CML 'C' (cis)      <=> INCHI_PARITY_ODD
324        CML 'T' (trans)    <=> INCHI_PARITY_EVEN
325 
326 
327    How InChI uses 0D parities
328    ==========================
329 
330    1. 0D parities are used if all atom coordinates are zeroes.
331 
332    In addition to that:
333 
334    2. 0D parities are used for Stereobonds, Allenes, or Cumulenes if:
335 
336    2a. A bond to the end-atom is shorter than MIN_BOND_LEN=0.000001
337    2b. A ratio of two bond lengths to the end-atom is smaller than MIN_SINE=0.03
338    2c. In case of a linear fragment X-A=B end-atom A is treated as satisfying 2a-b
339 
340        0D parities are used if 2a or 2b or 2c applies to one or both end-atoms.
341 
342    3. 0D parities are used for Tetrahedral Atoms if at least one of 3a-c is true:
343 
344    3a. One of bonds to the central atom is shorter than MIN_BOND_LEN=0.000001
345    3b. A ratio of two bond lengths to the central atom is smaller than MIN_SINE=0.03
346    3c. The four neighbors are almost in one plane or the central atom and
347        its only 3 explicit neighbors are almost in one plane
348 
349    Notes on 0D parities and 'undefined' stereogenic elements
350    =========================================================
351 
352    If 0D parity is to be used according to 1-3 but    CH3     CH3
353    has not been provided then the corresponding         \    /
354    stereogenic element is considered 'undefined'.        C=CH
355                                                         /
356    For example, if in the structure (Fig. 3)           H
357    the explicit H has been moved so that it                Fig. 3
358    has same coordinates as atom >C= (that is,
359    the length of the bond H-C became zero)
360    then the double bond is assigned 'undefined'       CH3      CH3
361    parity which by default is omitted from the          \     /
362    Identifier.                                           CH=CH
363 
364    However, the structure on Fig. 4 will have double        Fig. 4
365    bond parity 'o' and its parity in the Identifier is (-).
366 
367    Notes on 0D parities in structures containing metals
368    ====================================================
369    Since InChI disconnects bonds to metals the 0D parities upon the
370    disconnection may change in several different ways:
371 
372    1) previously non-stereogenic bond may become stereogenic:
373 
374          \     /                            \     /
375           CH==CH          disconnection      CH==CH
376            \ /               ======>
377             M                                  M
378 
379      before the disconnection:    after the disconnection:
380      atoms C have valence=5 and   the double bond may become
381      the double bond is not       stereogenic
382      recognized as stereogenic
383 
384    2) previously stereogenic bond may become non-stereogenic:
385 
386        M                           M(+)
387         \    /                             /
388          N==C      disconnection    (-)N==C
389              \        ======>              \
390 
391    3) Oddball structures, usually resulting from projecting 3D
392       structures on the plane, may contain fragment like that
393       depicted on Fig. 5:
394 
395               M   A                      M   A
396               |\ /   B                      /   B
397               | X   /     disconnection    /   /
398               |/ \ /         ======>      /   /
399               C===C                      C===C
400              Fig. 5
401      (X stands for bond intersection)
402 
403      A-C=C-B parity is              A-C=C-B parity is
404      trans (e)                      cis (o) or undefined
405      because the bond               because C valence = 3,
406      orientation is same            not 4.
407      as on Fig, 6 below:
408 
409           A       M
410            \     /     Removal of M from the structure
411             C===C      on Fig. 5 changes the geometry from trans
412            /     \     to cis.
413           M'      B    Removal of M and M' from the structure
414           Fig. 6       on Fig. 6 does not change the A-C=C-B
415                        geometry: it is trans.
416 
417    To resolve the problem InChI API accepts the second parity
418    corresponding to the metal-disconnected structure.
419    To store both bond parities use left shift by 3 bits:
420 
421    inchi_Stereo0D::parity = ParityOfConnected | (ParityOfDisconnected<<3)
422 
423    In case when only disconnected structure parity exists set
424    ParityOfConnected = INCHI_PARITY_UNDEFINED.
425    This is the only case when INCHI_PARITY_UNDEFINED parity
426    may be fed to the InChI.
427 
428    In cases when the bond parity in a disconnected structure exists and
429    differs from the parity in the connected structure the atoms A and B
430    should be non-metals.
431 
432 ****************************************************************************/
433 
434 #define NO_ATOM          (-1) /* non-existent (central) atom */
435 
436 /* 0D parity types */
437 typedef enum tagINCHIStereoType0D {
438    INCHI_StereoType_None        = 0,
439    INCHI_StereoType_DoubleBond  = 1,
440    INCHI_StereoType_Tetrahedral = 2,
441    INCHI_StereoType_Allene      = 3
442 } inchi_StereoType0D;
443 
444 /* 0D parities */
445 typedef enum tagINCHIStereoParity0D {
446    INCHI_PARITY_NONE      = 0,
447    INCHI_PARITY_ODD       = 1,  /* 'o' */
448    INCHI_PARITY_EVEN      = 2,  /* 'e' */
449    INCHI_PARITY_UNKNOWN   = 3,  /* 'u' */ /* (see also readinch.c)
450                                           used in: Extract0DParities, INChITo_Atom  */
451    INCHI_PARITY_UNDEFINED = 4   /* '?' -- should not be used; however, see Note above */
452 } inchi_StereoParity0D;
453 
454 
455 /*************************************************
456  *
457  *
458  *  0D - S T E R E O  (if no coordinates given)
459  *
460  *
461  *************************************************/
462 
463 
464 typedef struct tagINCHIStereo0D {
465     AT_NUM  neighbor[4];    /* 4 atoms always */
466     AT_NUM  central_atom;   /* central tetrahedral atom or a central */
467                             /* atom of allene; otherwise NO_ATOM */
468     S_CHAR  type;           /* inchi_StereoType0D */
469     S_CHAR  parity;         /* inchi_StereoParity0D: may be a combination of two parities: */
470                             /* ParityOfConnected | (ParityOfDisconnected << 3), see Note above */
471 }inchi_Stereo0D;
472 
473 
474 
475 
476 /*************************************************
477  *
478  *
479  *  I N C h I    D L L     I n p u t
480  *
481  *
482  *************************************************/
483 
484 
485 /* Structure -> InChI, GetINCHI() / GetStdINCHI() */
486 typedef struct tagINCHI_Input {
487     /* the caller is responsible for the data allocation and deallocation */
488     inchi_Atom     *atom;         /* array of num_atoms elements */
489     inchi_Stereo0D *stereo0D;     /* array of num_stereo0D 0D stereo elements or NULL */
490     char           *szOptions;    /* InChI options: space-delimited; each is preceded by */
491                                   /* '/' or '-' depending on OS and compiler */
492     AT_NUM          num_atoms;    /* number of atoms in the structure < 1024 */
493     AT_NUM          num_stereo0D; /* number of 0D stereo elements */
494 }inchi_Input;
495 
496 /* InChI -> Structure, GetStructFromINCHI()/GetStructFromStdINCHI() */
497 typedef struct tagINCHI_InputINCHI {
498     /* the caller is responsible for the data allocation and deallocation */
499     char *szInChI;     /* InChI ASCIIZ string to be converted to a strucure */
500     char *szOptions;   /* InChI options: space-delimited; each is preceded by */
501                        /* '/' or '-' depending on OS and compiler */
502 } inchi_InputINCHI;
503 
504 
505 /*************************************************
506  *
507  *
508  *  I N C h I     D L L     O u t p u t
509  *
510  *
511  *************************************************/
512 
513 /* Structure -> InChI */
514 typedef struct tagINCHI_Output {
515     /* zero-terminated C-strings allocated by GetStdINCHI() */
516     /* to deallocate all of them call FreeStdINCHI() (see below) */
517     char *szInChI;     /* InChI ASCIIZ string */
518     char *szAuxInfo;   /* Aux info ASCIIZ string */
519     char *szMessage;   /* Error/warning ASCIIZ message */
520     char *szLog;       /* log-file ASCIIZ string, contains a human-readable list */
521                        /* of recognized options and possibly an Error/warning message */
522 } inchi_Output;
523 
524 /* InChI -> Structure */
525 typedef struct tagINCHI_OutputStruct {
526     /* 4 pointers are allocated by GetStructFromINCHI()/GetStructFromStdINCHI()     */
527     /* to deallocate all of them call FreeStructFromStdINCHI()/FreeStructFromStdINCHI() */
528     inchi_Atom     *atom;         /* array of num_atoms elements */
529     inchi_Stereo0D *stereo0D;     /* array of num_stereo0D 0D stereo elements or NULL */
530     AT_NUM          num_atoms;    /* number of atoms in the structure < 1024 */
531     AT_NUM          num_stereo0D; /* number of 0D stereo elements */
532     char           *szMessage;    /* Error/warning ASCIIZ message */
533     char           *szLog;        /* log-file ASCIIZ string, contains a human-readable list */
534                                   /* of recognized options and possibly an Error/warning message */
535     unsigned long  WarningFlags[2][2]; /* warnings, see INCHIDIFF in inchicmp.h */
536                                        /* [x][y]: x=0 => Reconnected if present in InChI otherwise Disconnected/Normal
537                                                   x=1 => Disconnected layer if Reconnected layer is present
538                                                   y=1 => Main layer or Mobile-H
539                                                   y=0 => Fixed-H layer
540                                         */
541 }inchi_OutputStruct;
542 
543 
544 
545 
546 /*************************************************
547  *
548  *
549  *  I N C h I      D L L     I n t e r f a c e
550  *
551  *
552  *************************************************/
553 
554 #if (defined( _WIN32 ) && defined( _MSC_VER ) && defined(BUILD_LINK_AS_DLL) )
555     /* Win32 & MS VC ++, compile and link as a DLL */
556     #ifdef _USRDLL
557         /* InChI library dll */
558         #define INCHI_API __declspec(dllexport)
559         #define EXPIMP_TEMPLATE
560         #define INCHI_DECL __stdcall
561      #else
562         /* calling the InChI dll program */
563         #define INCHI_API __declspec(dllimport)
564         #define EXPIMP_TEMPLATE extern
565         #define INCHI_DECL __stdcall
566      #endif
567 #else
568     /* create a statically linked InChI library or link to an executable */
569     #define INCHI_API
570     #define EXPIMP_TEMPLATE
571     #define INCHI_DECL
572 #endif
573 
574 /*^^^ Return codes for
575         GetINCHI
576         GetStdINCHI
577         Get_inchi_Input_FromAuxInfo
578         Get_std_inchi_Input_FromAuxInfo
579         GetStructFromINCHI
580         GetStructFromStdINCHI
581 */
582 typedef enum tagRetValGetINCHI {
583     inchi_Ret_SKIP    = -2, /* not used in InChI library */
584     inchi_Ret_EOF     = -1, /* no structural data has been provided */
585     inchi_Ret_OKAY    =  0, /* Success; no errors or warnings */
586     inchi_Ret_WARNING =  1, /* Success; warning(s) issued */
587     inchi_Ret_ERROR   =  2, /* Error: no InChI has been created */
588     inchi_Ret_FATAL   =  3, /* Severe error: no InChI has been created (typically, memory allocation failure) */
589     inchi_Ret_UNKNOWN =  4, /* Unknown program error */
590     inchi_Ret_BUSY    =  5  /* Previuos call to InChI has not returned yet */
591 
592 } RetValGetINCHI;
593 
594 /*^^^ Return codes for CheckINCHI */
595 typedef enum tagRetValCheckINCHI
596 {
597     INCHI_VALID_STANDARD     =   0,
598     INCHI_VALID_NON_STANDARD =  -1,
599     INCHI_INVALID_PREFIX     =   1,
600     INCHI_INVALID_VERSION    =   2,
601     INCHI_INVALID_LAYOUT     =   3,
602     INCHI_FAIL_I2I           =   4
603 
604 } RetValCheckINCHI;
605 
606 
607 
608 /* to compile all InChI code as a C++ code #define COMPILE_ALL_CPP */
609 #ifndef COMPILE_ALL_CPP
610 #ifdef __cplusplus
611 extern "C" {
612 #endif
613 #endif
614 
615 
616 /*^^^ InChI PREFIX */
617 #define INCHI_STRING_PREFIX "InChI="
618 #define LEN_INCHI_STRING_PREFIX 6
619 
620 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
621 Format:
622 
623     Standard InChI starts with: InChI=1S/
624     Non-standard one with:      InChI=1/
625     Empty std InChI:            InChI=1S//
626     Empty InChI:                InChI=1//
627                                 AuxInfo=1//
628  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
629 
630 
631 
632 
633 /* EXPORTED FUNCTIONS */
634 
635 
636 
637 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
638 GetINCHI / GetStdINCHI
639 
640 
641     inchi_Input is created by the user; strings in inchi_Output are allocated and deallocated by InChI
642     inchi_Output does not need to be initilized out to zeroes; see FreeNCHI()/FreeSTDINCHI() on how to deallocate it
643 
644 
645     Valid options for GetINCHI:
646     (use - instead of / for O.S. other than MS Windows)
647 
648     Structure perception (compatible with stdInChI)
649         /NEWPSOFF   /DoNotAddH   /SNon
650     Stereo interpretation (lead to generation of non-standard InChI)
651         /SRel /SRac /SUCF /ChiralFlagON /ChiralFlagOFF
652     InChI creation options (lead to generation of non-standard InChI)
653         /SUU /SLUUD   /FixedH  /RecMet  /KET /15T
654 
655 
656     GetINCHI produces standard InChI if no InChI creation/stereo modification options
657     are specified. Inveresely, if any of SUU/SLUUD/RecMet/FixedH/Ket/15T/SRel/SRac/SUCF
658     options are specified, generated InChI will be non-standard one.
659 
660 
661     GetStdINCHI produces standard InChI only.
662     The valid structure perception options are:
663         /NEWPSOFF   /DoNotAddH   /SNon
664 
665 
666     Other options are:
667         /AuxNone    Omit auxiliary information (default: Include)
668         /Wnumber    Set time-out per structure in seconds; W0 means unlimited
669                     In InChI library the default value is unlimited
670         /OutputSDF  Output SDfile instead of InChI
671         /WarnOnEmptyStructure
672                     Warn and produce empty InChI for empty structure
673         /SaveOpt    Save custom InChI creation options (non-standard InChI)
674 
675  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
676 EXPIMP_TEMPLATE INCHI_API int INCHI_DECL GetINCHI( inchi_Input *inp, inchi_Output *out );
677 EXPIMP_TEMPLATE INCHI_API int INCHI_DECL GetStdINCHI( inchi_Input *inp, inchi_Output *out );
678 
679 
680 
681 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
682 FreeINCHI / FreeStdINCHI
683 
684     should be called to deallocate char* pointers
685     obtained from each GetINCHI /GetStdINCHI call
686 
687 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
688 EXPIMP_TEMPLATE INCHI_API void INCHI_DECL FreeINCHI ( inchi_Output *out );
689 EXPIMP_TEMPLATE INCHI_API void INCHI_DECL FreeStdINCHI ( inchi_Output *out );
690 
691 
692 
693 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
694 GetStringLength
695 
696     helper: get string length
697 
698 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
699 EXPIMP_TEMPLATE INCHI_API int INCHI_DECL GetStringLength( char *p );
700 
701 
702 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
703 GetStructFromINCHI / GetStructFromStdINCHI
704 
705     inchi_Inputinchi_InputINCHI is created by the user; pointers in inchi_OutputStruct are allocated and deallocated by InChI
706     inchi_OutputStruct does not need to be initilized out to zeroes; see FreeStructFromStdINCHI() on how to deallocate it
707     Option /Inchi2Struct is not needed for GetStructFromINCHI()/GetStructFromStdINCHI()
708 
709 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
710 EXPIMP_TEMPLATE INCHI_API int INCHI_DECL GetStructFromINCHI( inchi_InputINCHI *inpInChI, inchi_OutputStruct *outStruct );
711 EXPIMP_TEMPLATE INCHI_API int INCHI_DECL GetStructFromStdINCHI( inchi_InputINCHI *inpInChI, inchi_OutputStruct *outStruct );
712 
713 
714 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
715 FreeStructFromINCHI / FreeStructFromStdINCHI
716 
717     should be called to deallocate pointers obtained from each
718     GetStructFromStdINCHI / GetStructFromINCHI
719 
720 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
721 EXPIMP_TEMPLATE INCHI_API void INCHI_DECL FreeStructFromINCHI( inchi_OutputStruct *out );
722 EXPIMP_TEMPLATE INCHI_API void INCHI_DECL FreeStructFromStdINCHI( inchi_OutputStruct *out );
723 
724 
725 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
726 GetINCHIfromINCHI
727 
728     GetINCHIfromINCHI does same as -InChI2InChI option: converts InChI into InChI for validation purposes
729     It may also be used to filter out specific layers. For instance, /Snon would remove stereochemical layer
730     Omitting /FixedH and/or /RecMet would remove Fixed-H or Reconnected layers
731     To keep all InChI layers use options string "/FixedH /RecMet"; option /InChI2InChI is not needed
732     inchi_InputINCHI is created by the user; strings in inchi_Output are allocated and deallocated by InChI
733     inchi_Output does not need to be initilized out to zeroes; see FreeINCHI() on how to deallocate it
734 
735     Note: there is no explicit tool to conversion from/to standard InChI
736 
737 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
738 EXPIMP_TEMPLATE INCHI_API int INCHI_DECL GetINCHIfromINCHI( inchi_InputINCHI *inpInChI, inchi_Output *out );
739 
740 #ifndef COMPILE_ALL_CPP
741 #ifdef __cplusplus
742 }
743 #endif
744 #endif
745 
746 
747 /*****************************************************************
748  *
749  *
750  *   C o n v e r s i o n:   InChI  AuxInfo string => inchi_Input
751  *
752  *
753  *****************************************************************/
754 
755 #ifndef STR_ERR_LEN
756 #define STR_ERR_LEN     256
757 #endif
758 
759 typedef struct tagInchiInpData {
760     inchi_Input *pInp;    /* a pointer to pInp that has all items 0 or NULL */
761     int          bChiral; /* 1 => the structure was marked as chiral, 2=> not chiral, 0=> not marked */
762     char         szErrMsg[STR_ERR_LEN];
763 } InchiInpData;
764 
765 /* to compile all InChI code as a C++ code #define COMPILE_ALL_CPP */
766 #ifndef COMPILE_ALL_CPP
767 #ifdef __cplusplus
768 extern "C" {
769 #endif
770 #endif
771 
772 
773 
774 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
775 Get_inchi_Input_FromAuxInfo / Get_std_inchi_Input_FromAuxInfo
776 
777 Input:
778     szInchiAuxInfo: contains ASCIIZ string of InChI output for a single
779                    structure or only the AuxInfo line
780     bDoNotAddH:    if 0 then InChI will be allowed to add implicit H
781     bDiffUnkUndfStereo
782                    if not 0, use different labels for unknown and undefined stereo
783     pInchiInp:     should have a valid pointer pInchiInp->pInp to an empty
784                    (all members = 0) inchi_Input structure
785 
786 Output:
787     pInchiInp:     The following members of pInp may be filled during the call:
788                    atom, num_atoms, stereo0D, num_stereo0D
789     Return value:  see RetValGetINCHI
790 
791 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
792 EXPIMP_TEMPLATE INCHI_API int INCHI_DECL Get_inchi_Input_FromAuxInfo(
793                                                         char *szInchiAuxInfo,
794                                                         int bDoNotAddH,
795                                                         int bDiffUnkUndfStereo,
796                                                         InchiInpData *pInchiInp );
797 EXPIMP_TEMPLATE INCHI_API int INCHI_DECL Get_std_inchi_Input_FromAuxInfo( char *szInchiAuxInfo,
798                                                         int bDoNotAddH,
799                                                         InchiInpData *pInchiInp );
800 
801 
802 
803 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
804 Free_inchi_Input / Free_std_inchi_Input
805 
806     To deallocate and write zeroes into the changed members of pInchiInp->pInp call
807     Free_std_inchi_Input( inchi_Input *pInp )
808 
809 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
810 EXPIMP_TEMPLATE INCHI_API void INCHI_DECL Free_inchi_Input( inchi_Input *pInp );
811 EXPIMP_TEMPLATE INCHI_API void INCHI_DECL Free_std_inchi_Input( inchi_Input *pInp );
812 
813 
814 
815 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
816 CheckINCHI
817 
818 Check if the string represents valid InChI/standard InChI.
819 Input:
820     szINCHI     source InChI
821     strict      if 0, just briefly check for proper layout (prefix, version, etc.)
822                 The result may not be strict.
823                 If not 0, try to perform InChI2InChI conversion and
824                 returns success if a resulting InChI string exactly match source.
825                 The result may be 'false alarm' due to imperfectness of conversion.
826 Returns:
827     success/errors codes
828 
829 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
830 EXPIMP_TEMPLATE INCHI_API int INCHI_DECL CheckINCHI(const char *szINCHI, const int strict);
831 
832 
833 #ifndef COMPILE_ALL_CPP
834 #ifdef __cplusplus
835 }
836 #endif
837 #endif
838 
839 
840 
841 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
842 
843                                 InChIKey API
844 
845 
846     InChIKey description
847 
848 
849 
850     The InChIKey is a character signature based on a hash code of the InChI string.
851     Standard InChIKey is produced out of standard InChI.
852     Non-standard InChIKey is produced out of non-standard InChI.
853 
854                     AAAAAAAAAAAAAA-BBBBBBBBCD-P
855 
856 
857     InChIKey layout is as follows:
858 
859     AAAAAAAAAAAAAA
860         First block (14 letters)
861         Encodes molecular skeleton (connectivity)
862 
863     BBBBBBBB
864         Second block (8 letters)
865         Encodes tautomers, stereochemistry, isotopomers, reconnected layer
866     C
867         'S' for standard
868         'N' for non-standard
869     D
870         InChI version ('A' for 1)
871     P - (de)protonation flag
872         Protonization encoding:
873         N 0
874         O +1 P +2 Q +3 R +4 S +5 T +6 U +7 V +8 W +9 X +10 Y +11 Z +12
875         M -1 L-2 K -3 J -4 I -5 H -6 G -7 F -8 E -9 D -10 C -11 B -12
876         A < -12 or > +12
877 
878 
879     All symbols except delimiter (dash, that is, minus) are uppercase English
880     letters representing a "base 26" encoding.
881 
882 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
883 
884 
885 /*^^^ Return codes for key generation procedure */
886 #define INCHIKEY_OK 0
887 #define INCHIKEY_UNKNOWN_ERROR 1
888 #define INCHIKEY_EMPTY_INPUT 2
889 #define INCHIKEY_INVALID_INCHI_PREFIX 3
890 #define INCHIKEY_NOT_ENOUGH_MEMORY 4
891 #define INCHIKEY_INVALID_INCHI 20
892 #define INCHIKEY_INVALID_STD_INCHI 21
893 
894 
895 /*^^^ Return codes for CheckINCHIKey */
896 typedef enum tagRetValGetINCHIKey
897 {
898     INCHIKEY_VALID_STANDARD     =   0,
899     INCHIKEY_VALID_NON_STANDARD =  -1,
900     INCHIKEY_INVALID_LENGTH     =   1,
901     INCHIKEY_INVALID_LAYOUT     =   2,
902     INCHIKEY_INVALID_VERSION    =   3
903 } RetValCheckINCHIKeyv;
904 
905 
906 
907 /* EXPORTED FUNCTIONS */
908 
909 
910 
911 /* To compile all InChI code as a C++ code #define COMPILE_ALL_CPP */
912 
913 #ifndef COMPILE_ALL_CPP
914 #ifdef __cplusplus
915 extern "C" {
916 #endif
917 #endif
918 
919 
920 
921 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
922 GetINCHIKeyFromINCHI
923 
924 Calculate InChIKey by InChI string.
925 
926 Input:
927         szINCHISource
928             source InChI string
929         xtra1
930             =1 calculate hash extension (up to 256 bits; 1st block)
931         xtra2
932             =1 calculate hash extension (up to 256 bits; 2nd block)
933 
934 Output:
935         szINCHIKey
936             InChIKey string
937             The user-supplied buffer szINCHIKey should be at least 28 bytes long.
938         szXtra1
939             hash extension (up to 256 bits; 1st block) string
940             Caller should allocate space for 64 characters + trailing NULL
941         szXtra2
942             hash extension (up to 256 bits; 2nd block) string
943             Caller should allocate space for 64 characters + trailing NULL
944 
945 Returns:
946         success/errors codes
947 
948 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
949 EXPIMP_TEMPLATE INCHI_API int INCHI_DECL GetINCHIKeyFromINCHI(const char* szINCHISource,
950                                                               const int xtra1,
951                                                               const int xtra2,
952                                                               char* szINCHIKey,
953                                                               char* szXtra1,
954                                                               char* szXtra2);
955 
956 
957 
958 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
959 GetStdINCHIKeyFromStdINCHI
960 
961     "Standard" counterpart
962 
963     For compatibility with v. 1.02std, no extra hash calculation is allowed.
964     To calculate extra hash(es), use GetINCHIKeyFromINCHI with stdInChI as input.
965 
966 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
967 EXPIMP_TEMPLATE INCHI_API int INCHI_DECL GetStdINCHIKeyFromStdINCHI(const char* szINCHISource,
968                                                                     char* szINCHIKey);
969 
970 
971 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
972 CheckINCHIKey
973 
974 Check if the string represents valid InChIKey.
975 Input:
976         szINCHIKey
977             source InChIKey string
978 Returns:
979         success/errors codes
980 
981 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
982 EXPIMP_TEMPLATE INCHI_API int INCHI_DECL CheckINCHIKey(const char *szINCHIKey);
983 
984 #ifndef COMPILE_ALL_CPP
985 #ifdef __cplusplus
986 }
987 #endif
988 #endif
989 
990 
991 
992 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
993 
994                           Modularized InChI generation API
995 
996 
997 
998     Note. Functions with STDINCHIGEN prefix are
999     retained for compatibility with v. 1.02std
1000 
1001 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
1002 
1003 
1004 
1005 
1006 /*^^^ Data structures holding intermediate (normalization) results */
1007 
1008 #ifndef MAX_NUM_STEREO_ATOM_NEIGH
1009 #define MAX_NUM_STEREO_ATOM_NEIGH 4
1010 #endif
1011 #ifndef MAX_NUM_STEREO_BONDS
1012 #define MAX_NUM_STEREO_BONDS      3
1013 #endif
1014 #ifndef INCHI_NUM
1015 #define INCHI_NUM            2    /* = array size; member indexes: */
1016 #endif
1017 
1018 
1019 typedef unsigned short AT_NUMBR;
1020 typedef signed short NUM_HS;
1021 typedef unsigned long INCHI_MODES;
1022 
1023 typedef struct tagNormAtom
1024 {
1025     char          elname[ATOM_EL_LEN];      /* chem. element name */
1026     U_CHAR        el_number;                /* number of the element in the Periodic Table */
1027     AT_NUMBR      neighbor[MAXVAL];         /* positions (from 0) of the neighbors in the NORM_ATOM array */
1028     AT_NUMBR      orig_at_number;           /* original atom number, starts from 1 */
1029     AT_NUMBR      orig_compt_at_numb;       /* atom number within a component before terminal H removal */
1030     S_CHAR        bond_stereo[MAXVAL];      /* 1=Up,4=Either,6=Down (this atom is at the pointing wedge)
1031                                                negative => on the opposite side of the wedge; 3=Either double bond  */
1032     U_CHAR        bond_type[MAXVAL];        /* 1=single, 2=double, 3=triple, 4=1/2 (bond order is 1 or 2) */
1033                                             /* 5=1/2/3, 6=1/3, 7=2/3, 8=tautomeric, 9=1/2 non-stereogenic */
1034 
1035     S_CHAR        valence;                  /* number of bonds = number of neighbors not greater than MAXVAL */
1036     S_CHAR        chem_bonds_valence;       /* sum of bond types (1,2,3); type 4 needs special treatment */
1037     S_CHAR        num_H;                    /* number of adjacent implicit hydrogen atoms including D and T    */
1038     S_CHAR        num_iso_H[NUM_H_ISOTOPES];/* number of adjacent implicit 1H(protium), 2H(D), 3H(T) < 16 */
1039     S_CHAR        iso_atw_diff;             /* =0 => natural isotopic abundances  */
1040                                             /* >0 => (isotopic mass) - (rounded average atomic mass) + 1 */
1041                                             /* <0 => (isotopic mass) - (rounded average atomic mass) */
1042     S_CHAR        charge;                   /* charge */
1043     S_CHAR        radical;                  /* RADICAL_SINGLET, RADICAL_DOUBLET, or RADICAL_TRIPLET */
1044     S_CHAR        bAmbiguousStereo;         /* flag of detected stereo ambiguity */
1045     S_CHAR        cFlags;                   /* AT_FLAG_ISO_H_POINT: atom may have exchangeable isotopic H */
1046     AT_NUMBR      at_type;                  /* ATT_NONE, ATT_ACIDIC, etc. See InChI normalization code */
1047     AT_NUMBR      component;                /* number of the structure component > 0 */
1048     AT_NUMBR      endpoint;                 /* id of a tautomeric group */
1049     AT_NUMBR      c_point;                  /* id of a positive charge group */
1050     double        x;                        /* x coordinate */
1051     double        y;                        /* y coordinate */
1052     double        z;                        /* x coordinate */
1053     /*---------  0D parities ----------*/
1054     S_CHAR        bUsed0DParity;            /* bit=1 => stereobond; bit=2 => stereocenter */
1055     /*-----  tetrahedral stereo parity */
1056     S_CHAR        p_parity;                 /* tetrahedral (sp3) cml parity */
1057     AT_NUMBR      p_orig_at_num[MAX_NUM_STEREO_ATOM_NEIGH]; /* orig_at_number of each neighbor > 0; 0=> no neighbor */
1058     /*----- stereo bond (SB) parities */
1059     S_CHAR        sb_ord[MAX_NUM_STEREO_BONDS];  /* neighbor[] index of another end of this SB, starts from 0 */
1060     S_CHAR        sn_ord[MAX_NUM_STEREO_BONDS];  /* neighbor[] index of a bond that is not this SB; starts from 0;
1061                                                   -1 means the neighbor is a removed explicit H */
1062     /* atoms on both ends of a stereobond have same parity => trans/T/E/2, diff. parities => cis/C/Z/1 */
1063     S_CHAR        sb_parity[MAX_NUM_STEREO_BONDS];       /* parities of stereobonds (sp2) incident to this atom */
1064     AT_NUMBR      sn_orig_at_num[MAX_NUM_STEREO_BONDS];  /* orig_at_number of sn_ord[] neighbor > 0 */
1065 
1066 #if ( FIND_RING_SYSTEMS == 1 )
1067     S_CHAR  bCutVertex;                    /* is the atom a cut-vertex or not */
1068     AT_NUMBR nRingSystem;                  /* starts from 1; number of a ring system */
1069     AT_NUMBR nNumAtInRingSystem;           /* number of atoms in a ring system to which this at belongs */
1070     AT_NUMBR nBlockSystem;                 /* ambiguous if the atom is a cut-vertex: better apply this to bonds */
1071 
1072 #if ( FIND_RINS_SYSTEMS_DISTANCES == 1 )
1073     AT_NUMBR nDistanceFromTerminal;        /* not used */
1074 #endif
1075 
1076 #endif
1077 } NORM_ATOM;
1078 
1079 
1080 
1081 typedef struct tagNormAtomData
1082 {
1083     NORM_ATOM *at;                  /* atom list */
1084     NORM_ATOM *at_fixed_bonds;      /* atom list with added or removed protons only */
1085     int       num_at;               /* number of atoms except removed terminal H */
1086     int       num_removed_H;        /* number of removed H; at[] has (num_at+num_removed_H) elements */
1087     int       num_bonds;
1088     int       num_isotopic;         /* number of isotopic atoms */
1089     int       bExists;              /* for internal use */
1090     int       bDeleted;             /* for internal use */
1091     int       bHasIsotopicLayer;
1092     int       bTautomeric;
1093     int       bTautPreprocessed;    /* for internal use */
1094     int       nNumRemovedProtons;
1095     NUM_HS    nNumRemovedProtonsIsotopic[NUM_H_ISOTOPES];
1096                                     /* isotopic composition of removed protons, not included in num_iso_H[] */
1097     NUM_HS    num_iso_H[NUM_H_ISOTOPES];
1098                                     /* isotopic H on tautomeric atoms and those
1099                                        in nIsotopicEndpointAtomNumber */
1100     INCHI_MODES bTautFlags;         /* for internal use */
1101     INCHI_MODES bTautFlagsDone;     /* for internal use */
1102     INCHI_MODES bNormalizationFlags;/* for internal use */
1103 } NORM_ATOMS;
1104 
1105 
1106 typedef struct tagINCHIGEN_DATA
1107 {
1108 
1109     char          pStrErrStruct[STR_ERR_LEN]; /* intermediate log (warning/error report) */
1110     int           num_components[INCHI_NUM];  /* number of allocated INChI, INChI_Aux data structures */
1111                                               /* index=0 => disconnected, 1 => reconnected structure */
1112 
1113     /*^^^ The results of normalization stage */
1114     /*^^^ for each member of pair disconnected/reconnected structures: */
1115     NORM_ATOMS   *NormAtomsNontaut[INCHI_NUM];
1116     NORM_ATOMS   *NormAtomsTaut[INCHI_NUM];
1117 
1118 } INCHIGEN_DATA;
1119 
1120 
1121 /*^^^ InChI Generator Handle */
1122 
1123 typedef void* INCHIGEN_HANDLE;
1124 
1125 
1126 
1127 
1128 /* EXPORTED FUNCTIONS */
1129 
1130 
1131 
1132 /* to compile all InChI code as a C++ code #define COMPILE_ALL_CPP */
1133 #ifndef COMPILE_ALL_CPP
1134 #ifdef __cplusplus
1135 extern "C" {
1136 #endif
1137 #endif
1138 
1139 
1140 
1141 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1142 INCHIGEN_Create / STDINCHIGEN_Create
1143 
1144     InChI Generator: create generator
1145     Returns handle of generator object or NULL on failure
1146 
1147 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
1148 EXPIMP_TEMPLATE INCHI_API
1149 INCHIGEN_HANDLE INCHI_DECL INCHIGEN_Create(void);
1150 EXPIMP_TEMPLATE INCHI_API
1151 INCHIGEN_HANDLE INCHI_DECL STDINCHIGEN_Create(void);
1152 
1153 
1154 
1155 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1156 INCHIGEN_Setup / STDINCHIGEN_Setup
1157 
1158     InChI Generator: setup
1159 
1160 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
1161 EXPIMP_TEMPLATE INCHI_API int INCHI_DECL INCHIGEN_Setup(INCHIGEN_HANDLE HGen,
1162                                                         INCHIGEN_DATA * pGenData,
1163                                                         inchi_Input * pInp);
1164 EXPIMP_TEMPLATE INCHI_API int INCHI_DECL STDINCHIGEN_Setup(INCHIGEN_HANDLE HGen,
1165                                                            INCHIGEN_DATA * pGenData,
1166                                                            inchi_Input * pInp);
1167 
1168 
1169 
1170 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1171 INCHIGEN_DoNormalization / STDINCHIGEN_DoNormalization
1172 
1173     InChI Generator: structure normalization stage
1174 
1175 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
1176 EXPIMP_TEMPLATE INCHI_API int INCHI_DECL INCHIGEN_DoNormalization(INCHIGEN_HANDLE HGen,
1177                                                                      INCHIGEN_DATA * pGenData);
1178 EXPIMP_TEMPLATE INCHI_API int INCHI_DECL STDINCHIGEN_DoNormalization(INCHIGEN_HANDLE HGen,
1179                                                                      INCHIGEN_DATA * pGenData);
1180 
1181 
1182 
1183 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1184 INCHIGEN_DoCanonicalization / STDINCHIGEN_DoCanonicalization
1185 
1186     InChI Generator: structure canonicalization stage
1187 
1188 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
1189 EXPIMP_TEMPLATE INCHI_API int INCHI_DECL INCHIGEN_DoCanonicalization
1190                                 (INCHIGEN_HANDLE HGen, INCHIGEN_DATA * pGenData);
1191 EXPIMP_TEMPLATE INCHI_API int INCHI_DECL STDINCHIGEN_DoCanonicalization
1192                                 (INCHIGEN_HANDLE HGen, INCHIGEN_DATA * pGenData);
1193 
1194 
1195 
1196 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1197 INCHIGEN_DoSerialization / STDINCHIGEN_DoSerialization
1198 
1199     InChI Generator: InChI serialization stage
1200 
1201 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
1202 EXPIMP_TEMPLATE INCHI_API int INCHI_DECL INCHIGEN_DoSerialization(INCHIGEN_HANDLE HGen,
1203                                                                   INCHIGEN_DATA * pGenData,
1204                                                                   inchi_Output * pResults);
1205 EXPIMP_TEMPLATE INCHI_API int INCHI_DECL STDINCHIGEN_DoSerialization(INCHIGEN_HANDLE HGen,
1206                                                                      INCHIGEN_DATA * pGenData,
1207                                                                      inchi_Output * pResults);
1208 
1209 
1210 
1211 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1212 INCHIGEN_DoSerialization / STDINCHIGEN_DoSerialization
1213 
1214     InChI Generator: reset stage (use before get next structure)
1215 
1216 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
1217 EXPIMP_TEMPLATE INCHI_API
1218 void INCHI_DECL INCHIGEN_Reset(INCHIGEN_HANDLE HGen,
1219                                INCHIGEN_DATA * pGenData,
1220                                inchi_Output * pResults);
1221 EXPIMP_TEMPLATE INCHI_API
1222 void INCHI_DECL STDINCHIGEN_Reset(INCHIGEN_HANDLE HGen,
1223                                INCHIGEN_DATA * pGenData,
1224                                inchi_Output * pResults);
1225 
1226 
1227 
1228 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1229 INCHIGEN_DoSerialization / STDINCHIGEN_DoSerialization
1230 
1231     InChI Generator: destroy generator
1232 
1233 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
1234 EXPIMP_TEMPLATE INCHI_API void INCHI_DECL INCHIGEN_Destroy(INCHIGEN_HANDLE HGen);
1235 EXPIMP_TEMPLATE INCHI_API void INCHI_DECL STDINCHIGEN_Destroy(INCHIGEN_HANDLE HGen);
1236 
1237 
1238 
1239 
1240 
1241 #ifndef COMPILE_ALL_CPP
1242 #ifdef __cplusplus
1243 }
1244 #endif
1245 #endif
1246 
1247 
1248 
1249 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1250 
1251 Prototypes for C calling conventions:
1252 
1253     int  GetINCHI( inchi_Input *inp, inchi_Output *out );
1254     int  GetStdINCHI( inchi_Input *inp, inchi_Output *out );
1255     void FreeINCHI( inchi_Output *out );
1256     void FreeStdINCHI( inchi_Output *out );
1257     int  GetStringLength( char *p );
1258     int  Get_inchi_Input_FromAuxInfo
1259      ( char *szInchiAuxInfo, int bDoNotAddH, int bDiffUnkUndfStereo, InchiInpData *pInchiInp );
1260     int  Get_std_inchi_Input_FromAuxInfo
1261      ( char *szInchiAuxInfo, int bDoNotAddH, int bDiffUnkUndfStereo,InchiInpData *pInchiInp );
1262     void Free_inchi_Input( inchi_Input *pInp );
1263     void Free_std_inchi_Input( inchi_Input *pInp );
1264     int GetStructFromINCHI( inchi_InputINCHI *inpInChI, inchi_OutputStruct *outStruct );
1265     int GetStructFromStdINCHI( inchi_InputINCHI *inpInChI, inchi_OutputStruct *outStruct );
1266     void FreeStructFromStdINCHI( inchi_OutputStruct *out );
1267 
1268 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
1269 
1270 
1271 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1272 
1273 Win32 Dumpbin export information
1274 
1275     ordinal hint RVA      name
1276 cdecl
1277           1    0 000B7EAB CheckINCHI
1278           2    1 000B7221 CheckINCHIKey
1279           3    2 000B7C62 FreeINCHI
1280           4    3 000B7B04 FreeStdINCHI
1281           5    4 000B72B7 FreeStructFromINCHI
1282           6    5 000B7BC2 FreeStructFromStdINCHI
1283           7    6 000B7E33 Free_inchi_Input
1284           8    7 000B7C58 Free_std_inchi_Input
1285           9    8 000B727B GetINCHI
1286          10    9 000B75B4 GetINCHIKeyFromINCHI
1287          11    A 000B757D GetINCHIfromINCHI
1288          12    B 000B8211 GetStdINCHI
1289          13    C 000B7F0A GetStdINCHIKeyFromStdINCHI
1290          14    D 000B77CB GetStringLength
1291          15    E 000B7CA3 GetStructFromINCHI
1292          16    F 000B778A GetStructFromStdINCHI
1293          17   10 000B7DAC Get_inchi_Input_FromAuxInfo
1294          18   11 000B7D6B Get_std_inchi_Input_FromAuxInfo
1295          19   12 000B7D6B INCHIGEN_Create
1296          20   13 000B7F2D INCHIGEN_Destroy
1297          21   14 000B7F23 INCHIGEN_DoCanonicalization
1298          22   15 000B7F23 INCHIGEN_DoNormalization
1299          23   16 000B714A INCHIGEN_DoSerialization
1300          24   17 000B7FCD INCHIGEN_Reset
1301          25   18 000B7FCD INCHIGEN_Setup
1302          26   19 000B7EA6 STDINCHIGEN_Create
1303          27   1A 000B7EA6 STDINCHIGEN_Destroy
1304          28   1B 000B711D STDINCHIGEN_DoCanonicalization
1305          29   1C 000B7073 STDINCHIGEN_DoNormalization
1306          30   1D 000B7FC3 STDINCHIGEN_DoSerialization
1307          31   1E 000B7668 STDINCHIGEN_Reset
1308          32   1F 000B7438 STDINCHIGEN_Setup
1309 __stdcall or PASCAL
1310          33   20 000B7DFC _CheckINCHI@8
1311          34   21 000B7802 _CheckINCHIKey@4
1312          35   22 000B7F73 _FreeINCHI@4
1313          36   23 000B7F82 _FreeStdINCHI@4
1314          37   24 000B75E1 _FreeStructFromINCHI@4
1315          38   25 000B7B81 _FreeStructFromStdINCHI@4
1316          39   26 000B7B86 _Free_inchi_Input@4
1317          40   27 000B7A96 _Free_std_inchi_Input@4
1318          41   28 000B7B5E _GetINCHI@8
1319          42   29 000B7285 _GetINCHIKeyFromINCHI@24
1320          43   2A 000B758C _GetINCHIfromINCHI@8
1321          44   2B 000B7CDA _GetStdINCHI@8
1322          45   2C 000B7979 _GetStdINCHIKeyFromStdINCHI@8
1323          46   2D 000B7BA4 _GetStringLength@4
1324          47   2E 000B70A5 _GetStructFromINCHI@8
1325          48   2F 000B79B0 _GetStructFromStdINCHI@8
1326          49   30 000B8022 _Get_inchi_Input_FromAuxInfo@16
1327          50   31 000B76E0 _Get_std_inchi_Input_FromAuxInfo@12
1328          51   32 000B7230 _INCHIGEN_Create@0
1329          52   33 000B760E _INCHIGEN_Destroy@4
1330          53   34 000B7087 _INCHIGEN_DoCanonicalization@8
1331          54   35 000B70B4 _INCHIGEN_DoNormalization@8
1332          55   36 000B72D5 _INCHIGEN_DoSerialization@12
1333          56   37 000B7FE1 _INCHIGEN_Reset@12
1334          57   38 000B7163 _INCHIGEN_Setup@12
1335          58   39 000B7159 _STDINCHIGEN_Create@0
1336          59   3A 000B78A7 _STDINCHIGEN_Destroy@4
1337          60   3B 000B72F3 _STDINCHIGEN_DoCanonicalization@8
1338          61   3C 000B737A _STDINCHIGEN_DoNormalization@8
1339          62   3D 000B7B72 _STDINCHIGEN_DoSerialization@12
1340          63   3E 000B7654 _STDINCHIGEN_Reset@12
1341          64   3F 000B75FF _STDINCHIGEN_Setup@12
1342 
1343 
1344     Note. Currently there is no callback function for aborting, progress, etc.
1345 
1346 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
1347 
1348 #endif /* __INHCH_API_H__ */
1349