2
* International Union of Pure and Applied Chemistry (IUPAC)
3
2
* International Chemical Identifier (InChI)
5
* Software version 1.01
4
* Software version 1.02-beta
8
* The InChI library and programs are free software developed under the
9
* auspices of the International Union of Pure and Applied Chemistry (IUPAC);
10
* you can redistribute this software and/or modify it under the terms of
11
* the GNU Lesser General Public License as published by the Free Software
13
* http://www.opensource.org/licenses/lgpl-license.php
11
18
#include <stdlib.h>
12
19
#include <string.h>
359
375
#define INCHI_ADD_STR_LEN 32768
360
376
#endif /* INCHI_LIBRARY */
379
/*#ifdef INCHI_LIBRARY*/
380
#if ( defined(INCHI_LIBRARY) || defined(BUILD_CINCHI_WITH_INCHIKEY) )
363
381
/*****************************************************************/
364
382
int inchi_print( INCHI_FILE* f, const char* lpszFormat, ... )
595
return ret? ret : ret2;
627
return ret? ret : ret2;
632
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
634
int my_fileprintf( FILE* f, const char* lpszFormat, ... )
643
if ( f == stderr && lpszFormat && lpszFormat[0] && '\r' == lpszFormat[strlen(lpszFormat)-1] ) {
644
#define CONSOLE_LINE_LEN 80
646
#ifndef INCHI_ANSI_ONLY
647
char szLine[CONSOLE_LINE_LEN];
648
my_va_start( argList, lpszFormat );
649
ret = _vsnprintf( szLine, CONSOLE_LINE_LEN-1, lpszFormat, argList );
652
/* output is longer than the console line */
653
strcpy(szLine+CONSOLE_LINE_LEN-4, "...\r");
657
my_va_start( argList, lpszFormat );
658
ret = vfprintf( f, lpszFormat, argList );
662
#undef CONSOLE_LINE_LEN
664
my_va_start( argList, lpszFormat );
665
ret = vfprintf( f, lpszFormat, argList );
669
if ( f && f != stderr ) { /* disabled stderr output in case f == NULL. 11-23-2005 */
670
my_va_start( argList, lpszFormat );
671
ret2 = vfprintf( stderr, lpszFormat, argList );
676
return ret? ret : ret2;
598
679
#ifndef INCHI_ANSI_ONLY
599
680
/********************************************************************/
600
681
void FillTableParms( SET_DRAW_PARMS *sdp, INChI **cur_INChI, INChI_Aux **cur_INChI_Aux,
746
827
#ifndef INCHI_ANSI_ONLY
747
828
#ifndef INCHI_LIB
748
829
/*******************************************************************/
749
int DisplayStructure( inp_ATOM *at, int num_at, int num_removed_H,
830
int DisplayStructure( inp_ATOM *at, int num_at, int num_removed_H, int bAdd_DT_to_num_H,
750
831
int nNumRemovedProtons, NUM_H *nNumRemovedProtonsIsotopic,
751
832
int bIsotopic, int j /*bTautomeric*/,
752
833
INChI **cur_INChI, INChI_Aux **cur_INChI_Aux,
757
838
if ( CreateInfoAtomData( &inf_data, num_at, 1 ) ) {
759
FillOutInfAtom( at, &inf_data, num_at, num_removed_H, nNumRemovedProtons,
760
nNumRemovedProtonsIsotopic, bIsotopic,
840
FillOutInfAtom( at, &inf_data, num_at, num_removed_H, bAdd_DT_to_num_H,
841
nNumRemovedProtons, nNumRemovedProtonsIsotopic, bIsotopic,
761
842
cur_INChI?cur_INChI[j]:NULL,
762
843
cur_INChI_Aux?cur_INChI_Aux[j]:NULL, bAbcNumbers, nMode);
763
844
FillTableParms( &dp->sdp, cur_INChI, cur_INChI_Aux, nMode, bIsotopic, j );
786
867
if ( bTautomeric == TAUT_INI ) {
788
869
FillOutInfAtom( (composite_norm_data+bTautomeric)->at, &inf_data, (composite_norm_data+bTautomeric)->num_at,
789
(composite_norm_data+bTautomeric)->num_removed_H,
870
(composite_norm_data+bTautomeric)->num_removed_H, bAdd_DT_to_num_H,
790
871
(composite_norm_data+bTautomeric)->nNumRemovedProtons,
791
872
(composite_norm_data+bTautomeric)->nNumRemovedProtonsIsotopic, bIsotopic,
792
873
NULL, NULL, bAbcNumbers, nMode);
838
919
case CT_CALC_STEREO_ERR: p = "CALC_STEREO_ERR"; break;
839
920
case CT_STEREO_CANON_ERR: p = "STEREO_CANON_ERR"; break;
840
921
case CT_CANON_ERR: p = "CANON_ERR"; break;
841
case CT_WRONG_FORMULA: p = "Wrong or missing chemical formula"; break;
922
case CT_WRONG_FORMULA: p = "Wrong or missing chemical formula"; break;
842
923
/*case CT_CANON_ERR2: p = "CT_CANON_ERR2"; break;*/
843
924
case CT_UNKNOWN_ERR: p = "UNKNOWN_ERR"; break;
844
case BNS_RADICAL_ERR: p = "Cannot process free radical center"; break;
925
case BNS_RADICAL_ERR: p = "Cannot process free radical center"; break;
926
case BNS_ALTBOND_ERR: p = "Cannot process aromatic bonds"; break;
847
929
if ( nErrorCode > CT_UNKNOWN_ERR ) {
1283
1365
#ifndef INCHI_ANSI_ONLY
1284
1366
/* find equivalent and wINChI display order; use requested in ip->bCompareComponents comparison */
1285
1367
ret = SaveEquComponentsInfoAndSortOrder ( iINChI, pINChISort[j], num_components, orig_inp_data, prep_inp_data,
1286
composite_norm_data[j], ip->bCompareComponents );
1368
#if( FIX_DALKE_BUGS == 1 )
1369
composite_norm_data? composite_norm_data[j]:NULL,
1371
composite_norm_data[j],
1373
ip->bCompareComponents );
1287
1374
if ( RETURNED_ERROR( ret ) ) {
1289
1376
goto exit_function;
1691
1782
/*****************************************************************************************************/
1692
1783
int TreatReadTheStructureErrors( STRUCT_DATA *sd, INPUT_PARMS *ip, int nLogMask,
1693
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
1784
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file,
1785
FILE *prb_file, /*^^^ was: INCHI_FILE */
1694
1786
ORIG_ATOM_DATA *orig_inp_data, long *num_inp, char *pStr, int nStrLen )
1696
1788
int nRet = _IS_OKAY;
1709
1801
/* Skipping the structures */
1710
1802
if ( *num_inp < ip->first_struct_number ) {
1711
#ifndef INCHI_LIBRARY
1804
#if ( !defined(INCHI_LIBRARY) && !defined(BUILD_CINCHI_WITH_INCHIKEY) )
1805
/*^^^ #ifndef INCHI_LIBRARY */
1712
1806
if ( log_file != stderr ) {
1713
1807
my_fprintf( stderr, "\rSkipping structure #%ld.%s%s%s%s...", *num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue));
1752
1846
if ( sd->nErrorType == _IS_ERROR ) { /* 70 => too many atoms */
1753
1847
if ( nLogMask & LOG_MASK_ERR )
1754
1848
my_fprintf( log_file, "Error %d (no %s; %s) inp structure #%ld.%s%s%s%s\n",
1755
sd->nStructReadError, INCHI_NAME, sd->pStrErrStruct, *num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
1849
sd->nStructReadError, (ip->bINChIOutputOptions & INCHI_OUT_SDFILE_ONLY)?"Molfile":INCHI_NAME,
1850
sd->pStrErrStruct, *num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
1756
1851
#if( bRELEASE_VERSION == 1 || EXTR_FLAGS == 0 )
1757
1852
if ( prb_file && 0L <= sd->fPtrStart && sd->fPtrStart < sd->fPtrEnd && !ip->bSaveAllGoodStructsAsProblem) {
1758
1853
CopyMOLfile(inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file, *num_inp);
1910
2005
sd->ulStructTime += lElapsedTime;
1913
#if( !defined( INCHI_LIB ) && !defined( INCHI_LIBRARY ) )
2008
/*^^^#if( !defined( INCHI_LIB ) && !defined( INCHI_LIBRARY ) ) */
2009
#if( !defined( INCHI_LIB ) && !defined( INCHI_LIBRARY ) && !defined(BUILD_CINCHI_WITH_INCHIKEY) )
1914
2010
#if( TEST_RENUMB_ATOMS != 1 )
1915
2011
/* log file / console output */
1916
2012
if ( log_file && log_file != stderr ) { /* NULL log_file now ignored. 11-23-2005 */
2061
2157
/****************************************************************************************************/
2062
2158
int TreatCreateOneComponentINChIError(STRUCT_DATA *sd, INPUT_PARMS *ip, ORIG_ATOM_DATA *orig_inp_data,
2063
2159
int i, long num_inp,
2064
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
2160
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file,
2161
FILE *prb_file, /*^^^ was: INCHI_FILE */
2065
2162
char *pStr, int nStrLen )
2067
2164
if ( sd->nErrorCode ) {
2090
#ifndef INCHI_LIBRARY
2187
/*^^^ #ifndef INCHI_LIBRARY */
2188
#if( !defined( INCHI_LIBRARY ) && !defined(BUILD_CINCHI_WITH_INCHIKEY) )
2091
2189
/* print the logfile record */
2092
2190
if ( log_file && log_file != stderr && (sd->ulStructTime >= 1000 || sd->nErrorCode) ) {
2093
2191
fprintf( log_file, "%10lu msec structure #%ld.%s%s%s%s (%d component%s, %d atom%s, error=%d).\n",
2101
2199
/****************************************************************************************************/
2102
2200
int TreatCreateINChIWarning(STRUCT_DATA *sd, INPUT_PARMS *ip, ORIG_ATOM_DATA *orig_inp_data, long num_inp,
2103
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
2201
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file,
2202
FILE *prb_file, /*^^^ was: INCHI_FILE */
2104
2203
char *pStr, int nStrLen )
2106
2205
#if( bRELEASE_VERSION == 0 && (EXTR_FLAGS || EXTR_MASK) )
2222
2321
#ifndef INCHI_LIBRARY
2223
2322
/*******************************************************************************************/
2224
2323
int GetOneStructure( STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle,
2225
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
2324
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file,
2325
FILE *prb_file, /*^^^ was: INCHI_FILE */
2226
2326
ORIG_ATOM_DATA *orig_inp_data, long *num_inp, char *pStr, int nStrLen, STRUCT_FPTRS *struct_fptrs )
2228
2328
int nRet, inp_index, out_index, bUseFptr = (NULL != struct_fptrs);
2579
2679
if ( /*ip->bDisplayEachComponentINChI &&*/ !pRenumbData->nRet2 ) {
2582
err = DisplayStructure( inp_cur_data->at, inp_cur_data->num_at, 0, 0, NULL. 1, 0, NULL, NULL,
2682
err = DisplayStructure( inp_cur_data->at, inp_cur_data->num_at, 0, 1, 0, NULL. 1, 0, NULL, NULL,
2583
2683
ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
2585
err = DisplayStructure( inp_cur_data->at, inp_cur_data->num_at, 0, 0, NULL, 1/*isotopic*/, 0/*taut*/, NULL, NULL,
2685
err = DisplayStructure( inp_cur_data->at, inp_cur_data->num_at, 0, 1, 0, NULL, 1/*isotopic*/, 0/*taut*/, NULL, NULL,
2586
2686
ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
2587
2687
if ( pRenumbData->c1 || pRenumbData->c2 ) {
2588
2688
len = strlen(szTitle);
2589
2689
strcat( szTitle, " (Renumbered)" );
2590
2690
err = DisplayStructure( pRenumbData->longest_inp_cur_data.at, pRenumbData->longest_inp_cur_data.num_at,
2591
0, 0, NULL, 1, 0, NULL, NULL, ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
2691
0, 1, 0, NULL, 1, 0, NULL, NULL, ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
2592
2692
szTitle[len] = '\0';
2594
2694
sd->bUserQuitComponentDisplay = (err==ESC_KEY);
2962
3062
/******************************************************
2963
3063
* Display the whole input structure in console app
3065
/*^^^ #ifndef INCHI_LIB */
3066
#if( !defined( INCHI_LIB ) && !defined(BUILD_CINCHI_WITH_INCHIKEY) )
2966
3067
if ( bShowStruct && ip->bDisplay ) {
2967
3068
if ( bDisplayEqu ) {
2968
3069
sprintf( szTitle, " Equ Set %d of %d, Input Structure #%ld.%s%s%s%s%s",
2972
3073
sprintf( szTitle, "Input Structure #%ld.%s%s%s%s%s", num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), lpszType);
2974
err = DisplayStructure( orig_inp_data->at, orig_inp_data->num_inp_atoms, 0, 0, NULL, 1/*isotopic*/, 0/*taut*/, NULL, NULL,
3075
err = DisplayStructure( orig_inp_data->at, orig_inp_data->num_inp_atoms, 0, 1, 0, NULL, 1/*isotopic*/, 0/*taut*/, NULL, NULL,
2975
3076
ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
2976
3077
sd->bUserQuitComponent = (err==ESC_KEY);
3038
3139
vDrawData.pWindowData = CreateWinData_( orig_inp_data->at, orig_inp_data->num_inp_atoms,
3039
0, 0, NULL, 1, 0, NULL, NULL,
3140
0, 1 /* bAdd_DT_to_num_H */, 0, NULL, 1, 0, NULL, NULL,
3040
3141
ip->bAbcNumbers, &ip->dp, ip->nMode );
3041
3142
if( vDrawData.pWindowData != NULL )
3071
3172
/************************************************************************************************/
3072
3173
int ProcessOneStructure( STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle,
3073
3174
PINChI2 *pINChI[INCHI_NUM], PINChI_Aux2 *pINChI_Aux[INCHI_NUM],
3074
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
3175
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file,
3176
FILE *prb_file, /*^^^ was: INCHI_FILE */
3075
3177
ORIG_ATOM_DATA *orig_inp_data, ORIG_ATOM_DATA *prep_inp_data,
3076
3178
long num_inp, char *pStr, int nStrLen )
3082
3184
ORIG_STRUCT OrigStruct;
3083
3185
ORIG_STRUCT *pOrigStruct = NULL;
3084
3186
int bSortPrintINChIFlags = 0;
3187
#if ( RING2CHAIN == 1 || UNDERIVATIZE == 1 )
3086
3190
sd->bUserQuitComponent = 0;
3087
3191
sd->bUserQuitComponentDisplay = 0;
3088
3192
memset( composite_norm_data, 0, sizeof(composite_norm_data) );
3094
3198
fix_odd_things( orig_inp_data->num_inp_atoms, orig_inp_data->at, 0 );
3201
#if( UNDERIVATIZE == 1 ) /***** post v.1 feature *****/
3202
if ( ip->bUnderivatize && 0 > (ret2=underivatize( orig_inp_data )) ) {
3203
long num_inp2 = num_inp;
3204
AddMOLfileError(sd->pStrErrStruct, "Underivatization error");
3205
sd->nStructReadError = 99;
3206
sd->nErrorType = _IS_ERROR;
3208
TreatReadTheStructureErrors( sd, ip, LOG_MASK_ALL, inp_file, log_file, output_file, prb_file,
3209
prep_inp_data, &num_inp2, pStr, nStrLen );
3210
goto exit_function; /* output only if derivatives found */
3212
#endif /* UNDERIVATIZE == 1 */
3213
#if( RING2CHAIN == 1 ) /***** post v.1 feature *****/
3214
if ( ip->bRing2Chain && 0 > (ret1 = Ring2Chain( orig_inp_data )) ) {
3215
long num_inp2 = num_inp;
3216
AddMOLfileError(sd->pStrErrStruct, "Ring to chain error");
3217
sd->nStructReadError = 99;
3218
sd->nErrorType = _IS_ERROR;
3220
TreatReadTheStructureErrors( sd, ip, LOG_MASK_ALL, inp_file, log_file, output_file, prb_file,
3221
prep_inp_data, &num_inp2, pStr, nStrLen );
3222
goto exit_function; /* output only if derivatives found */
3224
#endif /* RING2CHAIN == 1 */
3225
#if ( RING2CHAIN == 1 || UNDERIVATIZE == 1 ) /***** post v.1 feature *****/
3226
if ( ip->bIngnoreUnchanged && !ret1 && !ret2 ) {
3227
goto exit_function; /* output only if derivatives or ring/chain found */
3229
#endif /* RING2CHAIN == 1 || UNDERIVATIZE == 1 */
3097
3232
/***** output MOLfile ***************/
3098
3233
if ( ip->bINChIOutputOptions & INCHI_OUT_SDFILE_ONLY ) {
3099
3234
char szNumber[32];
3100
#if ( !defined( INCHI_LIB ) && !defined( INCHI_LIBRARY ) )
3235
int ret1a=0, ret2a=0; /* for derivatives and ring-chain */
3236
/*^^^ #if ( !defined( INCHI_LIB ) && !defined( INCHI_LIBRARY ) ) */
3237
#if( !defined( INCHI_LIB ) && !defined( INCHI_LIBRARY ) && !defined(BUILD_CINCHI_WITH_INCHIKEY) )
3101
3238
#if( TEST_RENUMB_ATOMS != 1 )
3102
3239
/* log file / console output */
3103
3240
if ( log_file != stderr ) {
3111
sprintf( szNumber, "Structure #%ld", num_inp );
3112
WriteOrigAtomDataToSDfile( orig_inp_data, output_file, szNumber, NULL,
3248
ret1a = sprintf( szNumber, "Structure #%ld", num_inp );
3249
ret2a = WriteOrigAtomDataToSDfile( orig_inp_data, output_file, szNumber, NULL,
3113
3250
(sd->bChiralFlag & FLAG_INP_AT_CHIRAL)? 1:0,
3114
3251
(ip->bINChIOutputOptions & INCHI_OUT_SDFILE_ATOMS_DT)? 1:0, ip->pSdfLabel, ip->pSdfValue );
3115
3252
goto exit_function;
3347
3484
/************************************************************************************************/
3348
3485
int CreateOneStructureINChI( STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle,
3349
3486
PINChI2 *pINChI2[INCHI_NUM], PINChI_Aux2 *pINChI_Aux2[INCHI_NUM], int iINChI,
3350
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
3487
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file,
3488
FILE *prb_file, /*^^^ was: INCHI_FILE */
3351
3489
ORIG_ATOM_DATA *orig_inp_data, ORIG_ATOM_DATA *prep_inp_data,
3352
3490
COMP_ATOM_DATA composite_norm_data2[][TAUT_NUM+1],
3353
3491
long num_inp, char *pStr, int nStrLen, NORM_CANON_FLAGS *pncFlags )
3755
3893
#ifndef INCHI_LIB
3756
3894
err = DisplayStructure( inp_cur_data->at, inp_cur_data->num_at,
3757
0, 0, NULL, 1/*isotopic*/, 0/*taut*/, NULL, NULL,
3895
0, 1, 0, NULL, 1/*isotopic*/, 0/*taut*/, NULL, NULL,
3758
3896
ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
3759
3897
sd->bUserQuitComponentDisplay = (err==ESC_KEY);
3899
#if( !defined(BUILD_CINCHI_WITH_INCHIKEY) )
3761
3900
my_fprintf( stderr, "Cannot display the structure\n");
3764
3904
if(DRAWDATA && DRAWDATA_EXISTS)
3766
3906
struct DrawData vDrawData;
3767
3907
int nType = COMPONENT_ORIGINAL;
3768
3908
vDrawData.pWindowData = CreateWinData_( inp_cur_data->at, inp_cur_data->num_at,
3909
0, 1 /* bAdd_DT_to_num_H */, 0, NULL,
3770
3910
1 /* display isotopic if present */, 0, NULL, NULL,
3771
3911
ip->bAbcNumbers, &ip->dp, ip->nMode );
3772
3912
if( vDrawData.pWindowData != NULL )
3889
4029
if ( bFixedBondsTaut ) {
3890
4030
err = DisplayStructure( inp_norm_data[j]->at_fixed_bonds, inp_norm_data[j]->num_at,
3891
inp_norm_data[j]->num_removed_H,
4031
inp_norm_data[j]->num_removed_H, 0 /*bAdd_DT_to_num_H*/,
3892
4032
inp_norm_data[j]->nNumRemovedProtons,
3893
4033
inp_norm_data[j]->nNumRemovedProtonsIsotopic,
3894
4034
bHasIsotopicLayer, j, NULL, NULL,
3895
4035
ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
3897
4037
err = DisplayStructure( inp_norm_data[j]->at, inp_norm_data[j]->num_at,
4038
0, 0 /*bAdd_DT_to_num_H*/, 0, NULL,
3899
4039
k, j, pINChI[i], pINChI_Aux[i],
3900
4040
ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
3908
4048
struct DrawData vDrawData;
3909
4049
vDrawData.pWindowData = CreateWinData_( inp_norm_data[j]->at, inp_norm_data[j]->num_at,
4050
0, 0 /* bAdd_DT_to_num_H */, 0, NULL,
3911
4051
k, j, pINChI[i], pINChI_Aux[i],
3912
4052
ip->bAbcNumbers, &ip->dp, ip->nMode );
3913
4053
if( vDrawData.pWindowData != NULL )
3935
4075
vDrawData.pWindowData =
3936
4076
CreateWinData_( inp_norm_data[j]->at_fixed_bonds, inp_norm_data[j]->num_at,
3937
4077
inp_norm_data[j]->num_removed_H,
4078
0 /* bAdd_DT_to_num_H */,
3938
4079
inp_norm_data[j]->nNumRemovedProtons,
3939
4080
inp_norm_data[j]->nNumRemovedProtonsIsotopic,
3940
4081
k, j, NULL, NULL,