/* Fast Artificial Neural Network Library (fann) Copyright (C) 2003-2016 Steffen Nissen (steffen.fann@gmail.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include "config.h" #include "fann.h" #ifdef _MSC_VER #define vsnprintf _vsnprintf #define snprintf _snprintf #endif /* define path max if not defined */ #if defined(_WIN32) && !defined(__MINGW32__) #define PATH_MAX _MAX_PATH #endif #ifndef PATH_MAX #ifdef _POSIX_PATH_MAX #define PATH_MAX _POSIX_PATH_MAX #else #define PATH_MAX 4096 #endif #endif FANN_EXTERNAL FILE * FANN_API fann_default_error_log = (FILE *)-1; /* resets the last error number */ FANN_EXTERNAL void FANN_API fann_reset_errno(struct fann_error *errdat) { errdat->errno_f = FANN_E_NO_ERROR; } /* resets the last errstr */ FANN_EXTERNAL void FANN_API fann_reset_errstr(struct fann_error *errdat) { if(errdat->errstr != NULL) free(errdat->errstr); errdat->errstr = NULL; } /* returns the last error number */ FANN_EXTERNAL enum fann_errno_enum FANN_API fann_get_errno(struct fann_error *errdat) { return errdat->errno_f; } /* returns the last errstr */ FANN_EXTERNAL char *FANN_API fann_get_errstr(struct fann_error *errdat) { char *errstr = errdat->errstr; fann_reset_errno(errdat); fann_reset_errstr(errdat); return errstr; } /* change where errors are logged to */ FANN_EXTERNAL void FANN_API fann_set_error_log(struct fann_error *errdat, FILE * log_file) { if(errdat == NULL) fann_default_error_log = log_file; else errdat->error_log = log_file; } /* prints the last error to stderr */ FANN_EXTERNAL void FANN_API fann_print_error(struct fann_error *errdat) { if(errdat->errno_f != FANN_E_NO_ERROR && errdat->errstr != NULL) { fprintf(stderr, "FANN Error %d: %s", errdat->errno_f, errdat->errstr); } } /* INTERNAL FUNCTION Populate the error information */ void fann_error(struct fann_error *errdat, const enum fann_errno_enum errno_f, ...) { va_list ap; size_t errstr_max = FANN_ERRSTR_MAX + PATH_MAX - 1; char errstr[FANN_ERRSTR_MAX + PATH_MAX]; FILE * error_log = fann_default_error_log; if(errdat != NULL) errdat->errno_f = errno_f; va_start(ap, errno_f); switch (errno_f) { case FANN_E_NO_ERROR: return; case FANN_E_CANT_OPEN_CONFIG_R: vsnprintf(errstr, errstr_max, "Unable to open configuration file \"%s\" for reading.\n", ap); break; case FANN_E_CANT_OPEN_CONFIG_W: vsnprintf(errstr, errstr_max, "Unable to open configuration file \"%s\" for writing.\n", ap); break; case FANN_E_WRONG_CONFIG_VERSION: vsnprintf(errstr, errstr_max, "Wrong version of configuration file, aborting read of configuration file \"%s\".\n", ap); break; case FANN_E_CANT_READ_CONFIG: vsnprintf(errstr, errstr_max, "Error reading \"%s\" from configuration file \"%s\".\n", ap); break; case FANN_E_CANT_READ_NEURON: vsnprintf(errstr, errstr_max, "Error reading neuron info from configuration file \"%s\".\n", ap); break; case FANN_E_CANT_READ_CONNECTIONS: vsnprintf(errstr, errstr_max, "Error reading connections from configuration file \"%s\".\n", ap); break; case FANN_E_WRONG_NUM_CONNECTIONS: vsnprintf(errstr, errstr_max, "ERROR connections_so_far=%d, total_connections=%d\n", ap); break; case FANN_E_CANT_OPEN_TD_W: vsnprintf(errstr, errstr_max, "Unable to open train data file \"%s\" for writing.\n", ap); break; case FANN_E_CANT_OPEN_TD_R: vsnprintf(errstr, errstr_max, "Unable to open train data file \"%s\" for writing.\n", ap); break; case FANN_E_CANT_READ_TD: vsnprintf(errstr, errstr_max, "Error reading info from train data file \"%s\", line: %d.\n", ap); break; case FANN_E_CANT_ALLOCATE_MEM: strcpy(errstr, "Unable to allocate memory.\n"); break; case FANN_E_CANT_TRAIN_ACTIVATION: strcpy(errstr, "Unable to train with the selected activation function.\n"); break; case FANN_E_CANT_USE_ACTIVATION: strcpy(errstr, "Unable to use the selected activation function.\n"); break; case FANN_E_TRAIN_DATA_MISMATCH: strcpy(errstr, "Training data must be of equivalent structure.\n"); break; case FANN_E_CANT_USE_TRAIN_ALG: strcpy(errstr, "Unable to use the selected training algorithm.\n"); break; case FANN_E_TRAIN_DATA_SUBSET: vsnprintf(errstr, errstr_max, "Subset from %d of length %d not valid in training set of length %d.\n", ap); break; case FANN_E_INDEX_OUT_OF_BOUND: vsnprintf(errstr, errstr_max, "Index %d is out of bound.\n", ap); break; case FANN_E_SCALE_NOT_PRESENT: strcpy(errstr, "Scaling parameters not present.\n"); break; case FANN_E_INPUT_NO_MATCH: vsnprintf(errstr, errstr_max, "The number of input neurons in the ann (%d) and data (%d) don't match\n", ap); break; case FANN_E_OUTPUT_NO_MATCH: vsnprintf(errstr, errstr_max, "The number of output neurons in the ann (%d) and data (%d) don't match\n", ap); break; case FANN_E_WRONG_PARAMETERS_FOR_CREATE: strcpy(errstr, "The parameters for create_standard are wrong, either too few parameters provided or a negative/very high value provided.\n"); break; } va_end(ap); if(errdat != NULL) { if(errdat->errstr == NULL) { errdat->errstr = (char*)malloc(strlen(errstr) + 1); } else if(strlen(errdat->errstr) < strlen(errstr)) { errdat->errstr = (char*)realloc(errdat->errstr, strlen(errstr) + 1); } /* allocation failed */ if(errdat->errstr == NULL) { fprintf(stderr, "Unable to allocate memory.\n"); return; } strcpy(errdat->errstr, errstr); error_log = errdat->error_log; } if(error_log == (FILE *)-1) /* This is the default behavior and will give stderr */ { fprintf(stderr, "FANN Error %d: %s", errno_f, errstr); } else if(error_log != NULL) { fprintf(error_log, "FANN Error %d: %s", errno_f, errstr); } } /* INTERNAL FUNCTION Initialize an error data strcuture */ void fann_init_error_data(struct fann_error *errdat) { errdat->errstr = NULL; errdat->errno_f = FANN_E_NO_ERROR; errdat->error_log = fann_default_error_log; }