int e_TreatReadTheStructureErrors( STRUCT_DATA *sd, INPUT_PARMS *ip, INCHI_IOSTREAM *inp_file, INCHI_IOSTREAM* log_file, INCHI_IOSTREAM* output_file, INCHI_IOSTREAM *prb_file, inchi_Input *pInp, long *num_inp ) { int nRet = _IS_OKAY; /* End of file */ if ( 10 < sd->nStructReadError && sd->nStructReadError < 20 ) { nRet = _IS_EOF; goto exit_function; /* end of file */ } /* Skipping the structures */ if ( *num_inp < ip->first_struct_number ) { if ( log_file->f != stderr ) { inchi_fprintf( stderr, "\rSkipping structure #%ld.%s%s%s%s...\r", *num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue)); } nRet = sd->nErrorType = _IS_SKIP; goto exit_function; } sd->nErrorType = e_GetInpStructErrorType( ip, sd->nStructReadError, sd->pStrErrStruct, pInp->num_atoms ); /* Fatal error */ if ( sd->nErrorType == _IS_FATAL ) { inchi_ios_eprint( log_file, "Fatal Error %d (aborted; %s) inp structure #%ld.%s%s%s%s\n", sd->nStructReadError, sd->pStrErrStruct, *num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) ); #if( bRELEASE_VERSION == 1 || EXTR_FLAGS == 0 ) if ( prb_file->f && 0L <= sd->fPtrStart && sd->fPtrStart < sd->fPtrEnd && !ip->bSaveAllGoodStructsAsProblem ) { e_CopyMOLfile(inp_file->f, sd->fPtrStart, sd->fPtrEnd, prb_file->f, *num_inp); } #endif /* goto exit_function; */ } /* Non-fatal errors: do not produce INChI */ if ( sd->nErrorType == _IS_ERROR ) { /* 70 => too many atoms */ inchi_ios_eprint( log_file, "Error %d (no INChI; %s) inp structure #%ld.%s%s%s%s\n", sd->nStructReadError, sd->pStrErrStruct, *num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) ); #if( bRELEASE_VERSION == 1 || EXTR_FLAGS == 0 ) if ( prb_file->f && 0L <= sd->fPtrStart && sd->fPtrStart < sd->fPtrEnd && !ip->bSaveAllGoodStructsAsProblem) { e_CopyMOLfile(inp_file->f, sd->fPtrStart, sd->fPtrEnd, prb_file->f, *num_inp); } #endif } /* Warnings: try to produce INChI */ if ( sd->nErrorType == _IS_WARNING ) { inchi_ios_eprint( log_file, "Warning: (%s) inp structure #%ld.%s%s%s%s\n", sd->pStrErrStruct, *num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) ); } exit_function: if ( nRet <= _IS_OKAY && sd->nErrorType > 0 ) { nRet = sd->nErrorType; } return nRet; }
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Local helper. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ int e_MakeOutputHeader( char *pSdfLabel, char *pSdfValue, long lSdfId, long num_inp, char *pStr1, char *pStr2 ) { int tot_len1 = 0, tot_len2 = 0; pStr1[0] = '\0'; if ( !(pSdfLabel && pSdfLabel[0]) && !(pSdfValue && pSdfValue[0]) ) { tot_len1 = sprintf( pStr1, "Structure: %ld", num_inp ); tot_len2 = sprintf( pStr2, "structure #%ld", num_inp ); } else { tot_len1 = sprintf( pStr1, "Structure: %ld.%s%s%s%s", num_inp, SDF_LBL_VAL(pSdfLabel, pSdfValue) ); tot_len2 = sprintf( pStr2, "structure #%ld.%s%s%s%s", num_inp, SDF_LBL_VAL(pSdfLabel, pSdfValue) ); if (lSdfId) { tot_len1 += sprintf( pStr1 + tot_len1, ":%ld", lSdfId ); tot_len2 += sprintf( pStr2 + tot_len2, ":%ld", lSdfId ); } } return tot_len1; }
int process_single_input( int argc, char *argv[ ] ) /**************************************************/ { /**************************************/ #endif /* #if ( BUILD_WITH_AMI == 1 ) */ /**************************************/ /* if not in AMI mode, main() starts here */ int bReleaseVersion = bRELEASE_VERSION; const int nStrLen = INCHI_SEGM_BUFLEN; int nRet = 0, nRet1; int i, k; long num_err, num_output, num_inp; /* long rcPict[4] = {0,0,0,0}; */ unsigned long ulDisplTime = 0; /* infinite, milliseconds */ unsigned long ulTotalProcessingTime = 0; char szTitle[MAX_SDF_HEADER+MAX_SDF_VALUE+256]; char szSdfDataValue[MAX_SDF_VALUE+1]; char *pStr = NULL; INPUT_PARMS inp_parms; INPUT_PARMS *ip = &inp_parms; STRUCT_DATA struct_data; STRUCT_DATA *sd = &struct_data; ORIG_ATOM_DATA OrigAtData; /* 0=> disconnected, 1=> original */ ORIG_ATOM_DATA *orig_inp_data = &OrigAtData; ORIG_ATOM_DATA PrepAtData[2]; /* 0=> disconnected, 1=> original */ ORIG_ATOM_DATA *prep_inp_data = PrepAtData; PINChI2 *pINChI[INCHI_NUM]; PINChI_Aux2 *pINChI_Aux[INCHI_NUM]; INCHI_IOSTREAM outputstr, logstr, prbstr, instr; INCHI_IOSTREAM *pout=&outputstr, *plog = &logstr, *pprb = &prbstr, *inp_file = &instr; #ifdef TARGET_EXE_STANDALONE char ik_string[256]; /*^^^ Resulting InChIKey string */ int ik_ret=0; /*^^^ InChIKey-calc result code */ int xhash1, xhash2; char szXtra1[65], szXtra2[65]; int inchi_ios_type = INCHI_IOSTREAM_STRING; #else int inchi_ios_type = INCHI_IOSTREAM_FILE; #endif /* internal tests --- */ #ifndef TEST_FPTRS STRUCT_FPTRS *pStructPtrs = NULL; #else STRUCT_FPTRS struct_fptrs, *pStructPtrs =&struct_fptrs; /* INCHI_LIB debug only */ #endif #if ( defined(REPEAT_ALL) && REPEAT_ALL > 0 ) int num_repeat = REPEAT_ALL; #endif #if ( TRACE_MEMORY_LEAKS == 1 ) _CrtSetDbgFlag(_CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF); /* for execution outside the VC++ debugger uncomment one of the following two */ /*#define MY_REPORT_FILE _CRTDBG_FILE_STDERR */ /*#define MY_REPORT_FILE _CRTDBG_FILE_STDOUT */ #ifdef MY_REPORT_FILE _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE ); _CrtSetReportFile( _CRT_WARN, MY_REPORT_FILE ); _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE ); _CrtSetReportFile( _CRT_ERROR, MY_REPORT_FILE ); _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE ); _CrtSetReportFile( _CRT_ASSERT, MY_REPORT_FILE ); #else _CrtSetReportMode(_CRT_WARN | _CRT_ERROR, _CRTDBG_MODE_DEBUG); #endif /* turn on floating point exceptions */ { /* Get the default control word. */ int cw = _controlfp( 0,0 ); /* Set the exception masks OFF, turn exceptions on. */ /*cw &=~(EM_OVERFLOW|EM_UNDERFLOW|EM_INEXACT|EM_ZERODIVIDE|EM_DENORMAL);*/ cw &=~(EM_OVERFLOW|EM_UNDERFLOW|EM_ZERODIVIDE|EM_DENORMAL); /* Set the control word. */ _controlfp( cw, MCW_EM ); } #endif #if ( defined(REPEAT_ALL) && REPEAT_ALL > 0 ) repeat: inchi_ios_close(inp_file); inchi_ios_close(pout); inchi_ios_close(plog); inchi_ios_close(pprb); pStr = NULL; #endif /* --- internal tests */ sd->bUserQuit = 0; #if ( defined( _WIN32 ) && defined( _CONSOLE ) && !defined( COMPILE_ANSI_ONLY ) ) if ( SetConsoleCtrlHandler( MyHandlerRoutine, 1 ) ) ConsoleQuit = WasInterrupted; #endif num_inp = 0; num_err = 0; num_output = 0; inchi_ios_init(inp_file, INCHI_IOSTREAM_FILE, NULL); inchi_ios_init(pout, inchi_ios_type, NULL); inchi_ios_init(plog, inchi_ios_type, stdout); inchi_ios_init(pprb, inchi_ios_type, NULL); if ( argc == 1 || argc==2 && ( argv[1][0]==INCHI_OPTION_PREFX ) && (!strcmp(argv[1]+1, "?") || !stricmp(argv[1]+1, "help") ) ) { HelpCommandLineParms(plog); inchi_ios_flush(plog); return 0; } /* original input structure */ memset( orig_inp_data , 0, sizeof( *orig_inp_data ) ); memset( prep_inp_data , 0, 2*sizeof( *prep_inp_data ) ); memset( pINChI, 0, sizeof(pINChI ) ); memset( pINChI_Aux, 0, sizeof(pINChI_Aux) ); memset( szSdfDataValue , 0, sizeof( szSdfDataValue ) ); plog->f = stderr; if ( 0 > ReadCommandLineParms( argc, (const char **)argv, ip, szSdfDataValue, &ulDisplTime, bReleaseVersion, plog) ) /* explicitly cast to (const char **) to avoid a warning about "incompatible pointer type":*/ { goto exit_function; } if ( !OpenFiles( &(inp_file->f), &(pout->f), &(plog->f), &(pprb->f), ip ) ) { goto exit_function; } if ( ip->bNoStructLabels ) { ip->pSdfLabel = NULL; ip->pSdfValue = NULL; } else if ( ip->nInputType == INPUT_INCHI_XML || ip->nInputType == INPUT_INCHI_PLAIN || ip->nInputType == INPUT_CMLFILE || ip->nInputType == INPUT_INCHI ) { /* the input may contain both the header and the label of the structure */ if ( !ip->pSdfLabel ) ip->pSdfLabel = ip->szSdfDataHeader; if ( !ip->pSdfValue ) ip->pSdfValue = szSdfDataValue; } inchi_ios_eprint( plog, "The command line used:\n\""); for(k=0; k<argc-1; k++) inchi_ios_eprint( plog, "%-s ",argv[k]); inchi_ios_eprint( plog, "%-s\"\n", argv[argc-1]); PrintInputParms(plog,ip); inchi_ios_flush2(plog, stderr); if ( !( pStr = (char*) inchi_malloc(nStrLen) ) ) { inchi_ios_eprint( plog, "Cannot allocate output buffer. Terminating\n"); inchi_ios_flush2(plog, stderr); goto exit_function; } pStr[0] = '\0'; #if ( READ_INCHI_STRING == 1 ) if ( ip->nInputType == INPUT_INCHI ) { memset( sd, 0, sizeof(*sd) ); ReadWriteInChI( inp_file, pout, plog, ip, sd, NULL, NULL, NULL, 0, NULL); inchi_ios_flush2(plog, stderr); ulTotalProcessingTime = sd->ulStructTime; num_inp = sd->fPtrStart; num_err = sd->fPtrEnd; goto exit_function; } #endif ulTotalProcessingTime = 0; if ( pStructPtrs ) { memset ( pStructPtrs, 0, sizeof(pStructPtrs[0]) ); /* debug: set CML reading sequence pStructPtrs->fptr = (INCHI_FPTR *)inchi_calloc(16, sizeof(INCHI_FPTR)); for ( i = 0; i < 15; i ++ ) pStructPtrs->fptr[i] = 15-i; pStructPtrs->cur_fptr = 7; pStructPtrs->len_fptr = 16; pStructPtrs->max_fptr = 14; */ } /**********************************************************************************************/ /* Main cycle : read input structures and create their INChI */ /**********************************************************************************************/ while ( !sd->bUserQuit && !bInterrupted ) { if ( ip->last_struct_number && num_inp >= ip->last_struct_number ) { nRet = _IS_EOF; /* simulate end of file */ goto exit_function; } /* read one structure from input and display optionally it */ nRet = GetOneStructure( sd, ip, szTitle, inp_file, plog, pout, pprb, orig_inp_data, &num_inp, pStr, nStrLen, pStructPtrs ); inchi_ios_flush2(plog, stderr); if ( pStructPtrs ) pStructPtrs->cur_fptr ++; if ( sd->bUserQuit ) break; switch ( nRet ) { case _IS_FATAL: num_err ++; case _IS_EOF: goto exit_function; case _IS_ERROR: num_err ++; case _IS_SKIP: continue; } /* create INChI for each connected component of the structure and optionally display them */ /* output INChI for the whole structure */ nRet1 = ProcessOneStructure( sd, ip, szTitle, pINChI, pINChI_Aux, inp_file, plog, pout, pprb, orig_inp_data, prep_inp_data, num_inp, pStr, nStrLen, 0 /* save_opt_bits */); inchi_ios_flush2(plog, stderr); #ifdef TARGET_EXE_STANDALONE /* correctly treat tabbed output with InChIKey */ if ( ip->bINChIOutputOptions & INCHI_OUT_TABBED_OUTPUT ) if ( ip->bCalcInChIHash != INCHIHASH_NONE ) if (pout->s.pStr) if (pout->s.nUsedLength>0) if (pout->s.pStr[pout->s.nUsedLength-1]=='\n') /* replace LF with TAB */ pout->s.pStr[pout->s.nUsedLength-1] = '\t'; #endif /* free INChI memory */ FreeAllINChIArrays( pINChI, pINChI_Aux, sd->num_components ); /* free structure data */ FreeOrigAtData( orig_inp_data ); FreeOrigAtData( prep_inp_data ); FreeOrigAtData( prep_inp_data+1 ); ulTotalProcessingTime += sd->ulStructTime; nRet = inchi_max(nRet, nRet1); switch ( nRet ) { case _IS_FATAL: num_err ++; goto exit_function; case _IS_ERROR: num_err ++; continue; } #ifdef TARGET_EXE_STANDALONE if ( ip->bCalcInChIHash != INCHIHASH_NONE ) { char *buf = NULL; size_t slen = pout->s.nUsedLength; extract_inchi_substring(&buf, pout->s.pStr, slen); if (NULL==buf) { ik_ret = INCHIKEY_NOT_ENOUGH_MEMORY; } else { xhash1 = xhash2 = 0; if ( ( ip->bCalcInChIHash == INCHIHASH_KEY_XTRA1 ) || ( ip->bCalcInChIHash == INCHIHASH_KEY_XTRA1_XTRA2 ) ) xhash1 = 1; if ( ( ip->bCalcInChIHash == INCHIHASH_KEY_XTRA2 ) || ( ip->bCalcInChIHash == INCHIHASH_KEY_XTRA1_XTRA2 ) ) xhash2 = 1; ik_ret = GetINCHIKeyFromINCHI(buf, xhash1, xhash2, ik_string, szXtra1, szXtra2); inchi_free(buf); } if (ik_ret==INCHIKEY_OK) { /* NB: correctly treat tabbed output with InChIKey & hash extensions */ char csep = '\n'; #ifdef TARGET_EXE_STANDALONE if ( ip->bINChIOutputOptions & INCHI_OUT_TABBED_OUTPUT ) csep = '\t'; #endif inchi_ios_print(pout, "InChIKey=%-s",ik_string); if ( xhash1 ) inchi_ios_print(pout, "%cXHash1=%-s",csep,szXtra1); if ( xhash2 ) inchi_ios_print(pout, "%cXHash2=%-s",csep,szXtra2); inchi_ios_print(pout, "\n"); } else { inchi_ios_print(plog, "Warning (Could not compute InChIKey: ", num_inp); switch(ik_ret) { case INCHIKEY_UNKNOWN_ERROR: inchi_ios_print(plog, "unresolved error)"); break; case INCHIKEY_EMPTY_INPUT: inchi_ios_print(plog, "got an empty string)"); break; case INCHIKEY_INVALID_INCHI_PREFIX: case INCHIKEY_INVALID_INCHI: case INCHIKEY_INVALID_STD_INCHI: inchi_ios_print(plog, "got non-InChI string)"); break; case INCHIKEY_NOT_ENOUGH_MEMORY: inchi_ios_print(plog, "not enough memory to treat the string)"); break; default:inchi_ios_print(plog, "internal program error)"); break; } inchi_ios_print(plog, " structure #%-lu.\n", num_inp); if ( ip->bINChIOutputOptions & INCHI_OUT_TABBED_OUTPUT ) inchi_ios_print(pout, "\n"); } inchi_ios_flush(pout); inchi_ios_flush2(plog, stderr); } else inchi_ios_flush(pout); #endif /* --- debug only --- if ( pStructPtrs->cur_fptr > 5 ) { pStructPtrs->cur_fptr = 5; } */ } /* end of main cycle - while ( !sd->bUserQuit && !bInterrupted ) */ exit_function: if ( (ip->bINChIOutputOptions & INCHI_OUT_XML) && sd->bXmlStructStarted > 0 ) { if ( !OutputINChIXmlStructEndTag( pout, pStr, nStrLen, 1 ) ) { inchi_ios_eprint( plog, "Cannot create end xml tag for structure #%ld.%s%s%s%s Terminating.\n", num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) ); inchi_ios_flush2(plog, stderr); sd->bXmlStructStarted = -1; /* do not repeat same message */ } } if ( (ip->bINChIOutputOptions & INCHI_OUT_XML) && ip->bXmlStarted ) { OutputINChIXmlRootEndTag( pout ); inchi_ios_flush(pout); ip->bXmlStarted = 0; } /* avoid memory leaks in case of fatal error */ if ( pStructPtrs && pStructPtrs->fptr ) { inchi_free( pStructPtrs->fptr ); } /* free INChI memory */ FreeAllINChIArrays( pINChI, pINChI_Aux, sd->num_components ); /* free structure data */ FreeOrigAtData( orig_inp_data ); FreeOrigAtData( prep_inp_data ); FreeOrigAtData( prep_inp_data+1 ); #if ( ADD_CMLPP == 1 ) /* BILLY 8/6/04 */ /* free CML memory */ FreeCml (); FreeCmlDoc( 1 ); #endif /* close output(s) */ inchi_ios_close(inp_file); inchi_ios_close(pout); inchi_ios_close(pprb); { int hours, minutes, seconds, mseconds; SplitTime( ulTotalProcessingTime, &hours, &minutes, &seconds, &mseconds ); inchi_ios_eprint( plog, "Finished processing %ld structure%s: %ld error%s, processing time %d:%02d:%02d.%02d\n", num_inp, num_inp==1?"":"s", num_err, num_err==1?"":"s", hours, minutes, seconds,mseconds/10); inchi_ios_flush2(plog, stderr); } inchi_ios_close(plog); if ( pStr ) inchi_free( pStr ); /* frees */ for ( i = 0; i < MAX_NUM_PATHS; i ++ ) { if ( ip->path[i] ) { free( (void*) ip->path[i] ); /* cast deliberately discards 'const' qualifier */ ip->path[i] = NULL; } } SetBitFree( ); /* internal tests --- */ #if ( defined(REPEAT_ALL) && REPEAT_ALL > 0 ) if ( num_repeat-- > 0 ) goto repeat; #endif /* --- internal tests */ #if ( bRELEASE_VERSION != 1 && defined(_DEBUG) ) if ( inp_file->f && inp_file->f != stdin ) { user_quit("Press Enter to exit ?", ulDisplTime); } #endif #if ( ( BUILD_WITH_AMI==1 ) && defined( _WIN32 ) && defined( _CONSOLE ) && !defined( COMPILE_ANSI_ONLY ) ) if ( bInterrupted ) return CTRL_STOP_EVENT; #endif return 0; }