diff --git a/include/filefuncs.h b/include/filefuncs.h index a995c4ef7..ebfa32899 100644 --- a/include/filefuncs.h +++ b/include/filefuncs.h @@ -47,10 +47,18 @@ void LogError(LOG_INFO *LogInfo, const int mode, const char *fmt, ...); void sw_message(const char *msg); -void check_errno( - const char *valMsg1, char *valMsg2, const char *endPtr, LOG_INFO *LogInfo +unsigned long int sw_strtoul( + const char *str, const char *errMsg, LOG_INFO *LogInfo ); +long int sw_strtol(const char *str, const char *errMsg, LOG_INFO *LogInfo); + +int sw_strtoi(const char *str, const char *errMsg, LOG_INFO *LogInfo); + +double sw_strtod(const char *str, const char *errMsg, LOG_INFO *LogInfo); + +float sw_strtof(const char *str, const char *errMsg, LOG_INFO *LogInfo); + int key_to_id(const char *key, const char **possibleKeys, int numPossKeys); void set_hasKey( diff --git a/src/SW_Carbon.c b/src/SW_Carbon.c index c6fcce4fb..cfaa5ac99 100644 --- a/src/SW_Carbon.c +++ b/src/SW_Carbon.c @@ -25,7 +25,6 @@ in SW_VegProd.c and SW_Flow_lib.c. #include "include/SW_VegProd.h" // for BIO_INDEX, WUE_INDEX #include // for pow #include // for sscanf, FILE -#include // for strtol, strtod #include // for strcmp, memset /* =================================================== */ @@ -94,7 +93,7 @@ void SW_CBN_read( double ppm = 1.; int existing_years[MAX_NYEAR] = {0}; short fileWasEmpty = 1; - char *MyFileName, inbuf[MAX_FILENAMESIZE], *endPtr; + char *MyFileName, inbuf[MAX_FILENAMESIZE]; MyFileName = InFiles[eCarbon]; f = OpenFile(MyFileName, "r", LogInfo); @@ -134,8 +133,7 @@ void SW_CBN_read( return; /* Exit prematurely due to error */ } - year = (int) strtol(yearStr, &endPtr, 10); - check_errno(MyFileName, yearStr, endPtr, LogInfo); + year = sw_strtoi(yearStr, MyFileName, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } @@ -155,14 +153,13 @@ void SW_CBN_read( return; /* Exit prematurely due to error */ } - year = (int) strtol(yearStr, &endPtr, 10); - check_errno(MyFileName, yearStr, endPtr, LogInfo); + year = sw_strtoi(yearStr, MyFileName, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } - (void - ) year; /* Silence clang-tidy clang-analyzer-deadcode.DeadStores */ + /* Silence clang-tidy clang-analyzer-deadcode.DeadStores */ + (void) year; continue; // Skip to the ppm values } @@ -186,14 +183,12 @@ void SW_CBN_read( return; /* Exit prematurely due to error */ } - year = (int) strtol(yearStr, &endPtr, 10); - check_errno(MyFileName, yearStr, endPtr, LogInfo); + year = sw_strtoi(yearStr, MyFileName, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } - ppm = strtod(ppmStr, &endPtr); - check_errno(MyFileName, ppmStr, endPtr, LogInfo); + ppm = sw_strtod(ppmStr, MyFileName, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } diff --git a/src/SW_Domain.c b/src/SW_Domain.c index 4083a4812..c8b9cebf4 100644 --- a/src/SW_Domain.c +++ b/src/SW_Domain.c @@ -203,7 +203,7 @@ void SW_DOM_read(SW_DOMAIN *SW_Domain, LOG_INFO *LogInfo) { FILE *f; int y, keyID; - char inbuf[LARGE_VALUE], *MyFileName, *endPtr; + char inbuf[LARGE_VALUE], *MyFileName; char key[15], value[LARGE_VALUE]; // 15 - Max key size int intRes = 0, scanRes; double doubleRes = 0.; @@ -241,12 +241,11 @@ void SW_DOM_read(SW_DOMAIN *SW_Domain, LOG_INFO *LogInfo) { doDoubleConv = (Bool) (keyID >= 9 && keyID <= 12); if (doDoubleConv) { - doubleRes = strtod(value, &endPtr); + doubleRes = sw_strtod(value, MyFileName, LogInfo); } else { - intRes = (int) strtol(value, &endPtr, 10); + intRes = sw_strtoi(value, MyFileName, LogInfo); } - check_errno(MyFileName, value, endPtr, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } diff --git a/src/SW_Main.c b/src/SW_Main.c index b9e66e493..aeb0f664e 100644 --- a/src/SW_Main.c +++ b/src/SW_Main.c @@ -26,7 +26,6 @@ #include "include/SW_Output.h" // for SW_OUT_close_files, SW_OUT_creat... #include "include/SW_Weather.h" // for SW_WTH_finalize_all_weather #include "include/Times.h" // for SW_WT_ReportTime, SW_WT_StartTime -#include // for errno #include // for NULL, stdout @@ -54,7 +53,6 @@ int main(int argc, char **argv) { Bool EchoInits = swFALSE; unsigned long userSUID; - errno = 0; // Start overall wall time SW_WT_StartTime(&SW_WallTime); diff --git a/src/SW_Main_lib.c b/src/SW_Main_lib.c index 69075c992..c553d875c 100644 --- a/src/SW_Main_lib.c +++ b/src/SW_Main_lib.c @@ -140,7 +140,8 @@ void sw_init_args( * -q=quiet, don't print "Check logfile" * at end of program. */ - char str[1024], *endPtr; + char str[1024]; + const char *errMsg = "command-line"; /* valid options */ char const *opts[] = {"-d", "-f", "-e", "-q", "-v", "-h", "-s", "-t", "-r"}; @@ -254,8 +255,7 @@ void sw_init_args( break; case 6: /* -s */ - *userSUID = (unsigned long) strtoll(str, &endPtr, 10); - check_errno(NULL, str, endPtr, LogInfo); + *userSUID = sw_strtoul(str, errMsg, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } @@ -264,8 +264,7 @@ void sw_init_args( * (currently, unsigned long) */ /* Expect that conversion of string to double results in the * same value as conversion of userSUID to double */ - doubleUserSUID = strtod(str, &endPtr); - check_errno(NULL, str, endPtr, LogInfo); + doubleUserSUID = sw_strtod(str, errMsg, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } @@ -284,8 +283,7 @@ void sw_init_args( break; case 7: /* -t */ - *wallTimeLimit = strtod(str, &endPtr); - check_errno(NULL, str, endPtr, LogInfo); + *wallTimeLimit = sw_strtod(str, errMsg, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } diff --git a/src/SW_Markov.c b/src/SW_Markov.c index 1d32d9f79..29e2d2968 100644 --- a/src/SW_Markov.c +++ b/src/SW_Markov.c @@ -529,7 +529,7 @@ Bool SW_MKV_read_prob( int lineno = 0, day, x, index; RealF wet, dry, avg, std; RealF *floatVals[4] = {&wet, &dry, &avg, &std}; - char inbuf[MAX_FILENAMESIZE], *endPtr; + char inbuf[MAX_FILENAMESIZE]; char dayStr[4] = {'\0'}, inFloatStrs[4][20] = {{'\0'}}; /* note that Files.read() must be called prior to this. */ @@ -554,15 +554,14 @@ Bool SW_MKV_read_prob( inFloatStrs[3] ); - day = (int) strtol(dayStr, &endPtr, 10); - check_errno(MyFileName, dayStr, endPtr, LogInfo); + day = sw_strtoi(dayStr, MyFileName, LogInfo); if (LogInfo->stopRun) { return swFALSE; // Exit function prematurely due to error } for (index = 0; index < numFloatInStrings; index++) { - *(floatVals[index]) = strtof(inFloatStrs[index], &endPtr); - check_errno(MyFileName, inFloatStrs[index], endPtr, LogInfo); + *(floatVals[index]) = + sw_strtof(inFloatStrs[index], MyFileName, LogInfo); if (LogInfo->stopRun) { return swFALSE; // Exit function prematurely due to error } @@ -673,7 +672,7 @@ Bool SW_MKV_read_cov(char *InFiles[], SW_MARKOV *SW_Markov, LOG_INFO *LogInfo) { RealF *floatVals[] = { &t1, &t2, &t3, &t4, &t5, &t6, &cfxw, &cfxd, &cfnw, &cfnd }; - char weekStr[3] = {'\0'}, inFloatStrs[10][20] = {{'\0'}}, *endPtr; + char weekStr[3] = {'\0'}, inFloatStrs[10][20] = {{'\0'}}; const int numFloatVals = 10; char *MyFileName = InFiles[eMarkovCov]; @@ -717,15 +716,14 @@ Bool SW_MKV_read_cov(char *InFiles[], SW_MARKOV *SW_Markov, LOG_INFO *LogInfo) { return swFALSE; // Exit function prematurely due to error } - week = (int) strtol(weekStr, &endPtr, 10); - check_errno(MyFileName, weekStr, endPtr, LogInfo); + week = sw_strtoi(weekStr, MyFileName, LogInfo); if (LogInfo->stopRun) { return swFALSE; // Exit function prematurely due to error } for (index = 0; index < numFloatVals; index++) { - *(floatVals[index]) = strtof(inFloatStrs[index], &endPtr); - check_errno(MyFileName, inFloatStrs[index], endPtr, LogInfo); + *(floatVals[index]) = + sw_strtof(inFloatStrs[index], MyFileName, LogInfo); if (LogInfo->stopRun) { return swFALSE; // Exit function prematurely due to error } diff --git a/src/SW_Model.c b/src/SW_Model.c index 5dea0b817..973ea3b25 100644 --- a/src/SW_Model.c +++ b/src/SW_Model.c @@ -47,7 +47,6 @@ #include "include/SW_Files.h" // for eModel #include "include/Times.h" // for Time_get_lastdoy_y, Time_init_model #include // for FILE -#include // for strtod #include // for memcpy @@ -115,7 +114,7 @@ void SW_MDL_read(SW_MODEL *SW_Model, char *InFiles[], LOG_INFO *LogInfo) { */ FILE *f; int lineno; - char *MyFileName, inbuf[MAX_FILENAMESIZE], *endPtr; + char *MyFileName, inbuf[MAX_FILENAMESIZE]; double value; MyFileName = InFiles[eModel]; @@ -132,8 +131,7 @@ void SW_MDL_read(SW_MODEL *SW_Model, char *InFiles[], LOG_INFO *LogInfo) { lineno = 0; while (GetALine(f, inbuf, MAX_FILENAMESIZE)) { if (lineno <= 4) { - value = strtod(inbuf, &endPtr); - check_errno(MyFileName, inbuf, endPtr, LogInfo); + value = sw_strtod(inbuf, MyFileName, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } diff --git a/src/SW_Output.c b/src/SW_Output.c index 6d70239da..5272fb556 100644 --- a/src/SW_Output.c +++ b/src/SW_Output.c @@ -2802,7 +2802,7 @@ void SW_OUT_read( char msg[200]; /* space for uppercase conversion */ char upkey[50], upsum[4]; - char inbuf[MAX_FILENAMESIZE], *endPtr; + char inbuf[MAX_FILENAMESIZE]; int first, last = -1; /* first doy for output */ char *MyFileName = InFiles[eOutput]; @@ -2916,15 +2916,13 @@ void SW_OUT_read( outfile[0] = '\0'; #endif - first = (int) strtol(firstStr, &endPtr, 10); - check_errno(MyFileName, firstStr, endPtr, LogInfo); + first = sw_strtoi(firstStr, MyFileName, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } if (Str_CompareI(lastStr, (char *) "END") != 0) { - last = (int) strtol(lastStr, &endPtr, 10); - check_errno(MyFileName, lastStr, endPtr, LogInfo); + last = sw_strtoi(lastStr, MyFileName, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } diff --git a/src/SW_Site.c b/src/SW_Site.c index fd590b6f5..a7c88b799 100644 --- a/src/SW_Site.c +++ b/src/SW_Site.c @@ -1321,7 +1321,7 @@ void SW_SIT_read( #endif LyrIndex r; Bool too_many_regions = swFALSE; - char inbuf[MAX_FILENAMESIZE], *endPtr; + char inbuf[MAX_FILENAMESIZE]; int intRes = 0; double doubleRes = 0.; float floatRes = 0.; @@ -1341,7 +1341,7 @@ void SW_SIT_read( strLine = (Bool) (lineno == 35 || lineno == 37 || lineno == 38); - if (!strLine) { + if (!strLine && lineno <= 38) { /* Check to see if the line number contains a double or integer * value */ doFloatConv = (Bool) (lineno >= 14 && lineno <= 21); @@ -1350,15 +1350,14 @@ void SW_SIT_read( (Bool) (!doFloatConv && ((lineno >= 0 && lineno <= 2) || (lineno >= 5 && lineno <= 31))); - if (doFloatConv) { - floatRes = strtof(inbuf, &endPtr); - } else if (doDoubleConv) { - doubleRes = strtod(inbuf, &endPtr); + if (doDoubleConv) { + doubleRes = sw_strtod(inbuf, MyFileName, LogInfo); + } else if (doFloatConv) { + floatRes = sw_strtof(inbuf, MyFileName, LogInfo); } else { - intRes = (int) strtol(inbuf, &endPtr, 10); + intRes = sw_strtoi(inbuf, MyFileName, LogInfo); } - check_errno(MyFileName, inbuf, endPtr, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } @@ -1528,14 +1527,12 @@ void SW_SIT_read( x = sscanf(inbuf, "%9s %9s", rgnStr[0], rgnStr[1]); if (x == 2) { - region = (int) strtol(rgnStr[0], &endPtr, 10); - check_errno(MyFileName, rgnStr[0], endPtr, LogInfo); + region = sw_strtoi(rgnStr[0], MyFileName, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } - rgnlow = (int) strtol(rgnStr[1], &endPtr, 10); - check_errno(MyFileName, rgnStr[1], endPtr, LogInfo); + rgnlow = sw_strtoi(rgnStr[1], MyFileName, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } @@ -1631,7 +1628,7 @@ void SW_LYR_read(SW_SITE *SW_Site, char *InFiles[], LOG_INFO *LogInfo) { int x, k, index; RealF dmin = 0.0, dmax, evco, trco_veg[NVEGTYPES], psand, pclay, soildensity, imperm, soiltemp, f_gravel; - char inbuf[MAX_FILENAMESIZE], *endPtr; + char inbuf[MAX_FILENAMESIZE]; char inFloatStrs[12][20] = {{'\0'}}; float *inFloatVals[] = { &dmax, @@ -1693,8 +1690,8 @@ void SW_LYR_read(SW_SITE *SW_Site, char *InFiles[], LOG_INFO *LogInfo) { /* Convert float strings to floats */ for (index = 0; index < numFloatInStrings; index++) { - *(inFloatVals[index]) = strtof(inFloatStrs[index], &endPtr); - check_errno(MyFileName, inFloatStrs[index], endPtr, LogInfo); + *(inFloatVals[index]) = + sw_strtof(inFloatStrs[index], MyFileName, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } @@ -1960,7 +1957,7 @@ void SW_SWRC_read(SW_SITE *SW_Site, char *InFiles[], LOG_INFO *LogInfo) { LyrIndex lyrno = 0, k; int x, index; RealF tmp_swrcp[SWRC_PARAM_NMAX]; - char inbuf[MAX_FILENAMESIZE], *endPtr; + char inbuf[MAX_FILENAMESIZE]; char swrcpFloatStrs[6][20] = {{'\0'}}; const int numFloatInStrings = 6; @@ -2003,8 +2000,8 @@ void SW_SWRC_read(SW_SITE *SW_Site, char *InFiles[], LOG_INFO *LogInfo) { /* Convert float strings to floats */ for (index = 0; index < numFloatInStrings; index++) { - tmp_swrcp[index] = strtof(swrcpFloatStrs[index], &endPtr); - check_errno(MyFileName, swrcpFloatStrs[index], endPtr, LogInfo); + tmp_swrcp[index] = + sw_strtof(swrcpFloatStrs[index], MyFileName, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } diff --git a/src/SW_Sky.c b/src/SW_Sky.c index 5ae125d7a..67a44cddd 100644 --- a/src/SW_Sky.c +++ b/src/SW_Sky.c @@ -43,7 +43,6 @@ #include "include/SW_Files.h" // for eSky #include "include/Times.h" // for isleapyear, interpolate_monthlyV... #include // for sscanf, FILE -#include // for strtod /* =================================================== */ /* Global Function Definitions */ @@ -71,7 +70,7 @@ void SW_SKY_read(char *InFiles[], SW_SKY *SW_Sky, LOG_INFO *LogInfo) { FILE *f; int lineno = 0, x = 0, k, index; RealD tmp[MAX_MONTHS]; - char *MyFileName, inbuf[MAX_FILENAMESIZE], *endPtr; + char *MyFileName, inbuf[MAX_FILENAMESIZE]; char tmpStrs[MAX_MONTHS][20] = {{'\0'}}; MyFileName = InFiles[eSky]; @@ -111,8 +110,7 @@ void SW_SKY_read(char *InFiles[], SW_SKY *SW_Sky, LOG_INFO *LogInfo) { } for (index = 0; index < MAX_MONTHS; index++) { - tmp[index] = strtod(tmpStrs[index], &endPtr); - check_errno(MyFileName, tmpStrs[index], endPtr, LogInfo); + tmp[index] = sw_strtod(tmpStrs[index], MyFileName, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } diff --git a/src/SW_SoilWater.c b/src/SW_SoilWater.c index 1792b4f6c..f4dd7a711 100644 --- a/src/SW_SoilWater.c +++ b/src/SW_SoilWater.c @@ -1307,7 +1307,7 @@ void SW_SWC_read( */ FILE *f; int lineno = 0, nitems = 4; - char inbuf[MAX_FILENAMESIZE], *endPtr; + char inbuf[MAX_FILENAMESIZE]; int inBufintRes = 0; Bool convertInput; @@ -1321,8 +1321,7 @@ void SW_SWC_read( convertInput = (Bool) (lineno >= 0 && lineno <= 3 && lineno != 1); if (convertInput) { - inBufintRes = (int) strtol(inbuf, &endPtr, 10); - check_errno(MyFileName, inbuf, endPtr, LogInfo); + inBufintRes = sw_strtoi(inbuf, MyFileName, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } @@ -1428,7 +1427,7 @@ void read_swc_hist( FILE *f; int x, lyr = 0, recno = 0, doy = 0, index; RealF swc = 0., st_err = 0.; - char fname[MAX_FILENAMESIZE], inbuf[MAX_FILENAMESIZE], *endPtr; + char fname[MAX_FILENAMESIZE], inbuf[MAX_FILENAMESIZE]; char varStrs[4][20] = {{'\0'}}; int *inBufIntVals[] = {&doy, &lyr}; float *inBufFloatVals[] = {&swc, &st_err}; @@ -1487,14 +1486,13 @@ void read_swc_hist( } for (index = 0; index < numInValsPerType; index++) { - *(inBufIntVals[index]) = (int) strtol(varStrs[index], &endPtr, 10); - check_errno(fname, varStrs[index], endPtr, LogInfo); + *(inBufIntVals[index]) = sw_strtoi(varStrs[index], fname, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } - *(inBufFloatVals[index]) = strtof(varStrs[index + 2], &endPtr); - check_errno(fname, varStrs[index], endPtr, LogInfo); + *(inBufFloatVals[index]) = + sw_strtof(varStrs[index + 2], fname, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } diff --git a/src/SW_VegEstab.c b/src/SW_VegEstab.c index c6d83124b..1c55b2362 100644 --- a/src/SW_VegEstab.c +++ b/src/SW_VegEstab.c @@ -570,7 +570,7 @@ static void read_spp( FILE *f; int lineno = 0; char name[80]; /* only allow 4 char sppnames */ - char inbuf[MAX_FILENAMESIZE], *endPtr; + char inbuf[MAX_FILENAMESIZE]; int inBufintRes; double inBufFloatVal; @@ -601,12 +601,11 @@ static void read_spp( (lineno >= 5 && lineno <= 11)); if (doIntConv) { - inBufintRes = (int) strtol(inbuf, &endPtr, 10); + inBufintRes = sw_strtoi(inbuf, infile, LogInfo); } else { - inBufFloatVal = strtof(inbuf, &endPtr); + inBufFloatVal = sw_strtof(inbuf, infile, LogInfo); } - check_errno(infile, inbuf, endPtr, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } diff --git a/src/SW_VegProd.c b/src/SW_VegProd.c index f9f3ff5b7..ab3d9f39d 100644 --- a/src/SW_VegProd.c +++ b/src/SW_VegProd.c @@ -167,7 +167,7 @@ void SW_VPD_read(SW_VEGPROD *SW_VegProd, char *InFiles[], LOG_INFO *LogInfo) { const int line_help = 28; RealF help_veg[NVEGTYPES], help_bareGround = 0., litt, biom, pctl, laic; RealF *monBioVals[] = {&litt, &biom, &pctl, &laic}; - char *MyFileName, inbuf[MAX_FILENAMESIZE], *endPtr; + char *MyFileName, inbuf[MAX_FILENAMESIZE]; char vegStrs[NVEGTYPES][20] = {{'\0'}}, bareGroundStr[20] = {'\0'}; char *startOfErrMsg; char vegMethodStr[20] = {'\0'}; @@ -213,16 +213,14 @@ void SW_VPD_read(SW_VEGPROD *SW_VegProd, char *InFiles[], LOG_INFO *LogInfo) { } ForEachVegType(k) { - help_veg[k] = strtof(vegStrs[k], &endPtr); - check_errno(MyFileName, vegStrs[k], endPtr, LogInfo); + help_veg[k] = sw_strtof(vegStrs[k], MyFileName, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } } if (x == NVEGTYPES + 1) { - help_bareGround = strtof(bareGroundStr, &endPtr); - check_errno(MyFileName, bareGroundStr, endPtr, LogInfo); + help_bareGround = sw_strtof(bareGroundStr, MyFileName, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } @@ -246,8 +244,7 @@ void SW_VPD_read(SW_VEGPROD *SW_VegProd, char *InFiles[], LOG_INFO *LogInfo) { } SW_VegProd->veg_method = - (int) strtol(vegMethodStr, &endPtr, 10); - check_errno(MyFileName, vegMethodStr, endPtr, LogInfo); + sw_strtoi(vegMethodStr, MyFileName, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } @@ -472,8 +469,8 @@ void SW_VPD_read(SW_VEGPROD *SW_VegProd, char *InFiles[], LOG_INFO *LogInfo) { } for (index = 0; index < numMonthVals; index++) { - *(monBioVals[index]) = strtof(vegStrs[index], &endPtr); - check_errno(MyFileName, vegStrs[index], endPtr, LogInfo); + *(monBioVals[index]) = + sw_strtof(vegStrs[index], MyFileName, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } diff --git a/src/SW_Weather.c b/src/SW_Weather.c index 8154dce33..d8d57d9aa 100644 --- a/src/SW_Weather.c +++ b/src/SW_Weather.c @@ -91,7 +91,6 @@ #include "include/SW_Markov.h" // for SW_MKV_today #include "include/SW_SoilWater.h" // for SW_SWC_adjust_snow #include "include/Times.h" // for Time_get_lastdoy_y, Time_days_i... -#include // for errno #include // for exp, fmin, fmax #include // for NULL, sscanf, FILE, fclose, fopen #include // for free @@ -1705,7 +1704,7 @@ void SW_WTH_setup( int lineno = 0, month, x, index; RealD sppt, stmax, stmin; RealD sky, wind, rH, actVP, shortWaveRad; - char inbuf[MAX_FILENAMESIZE], *endPtr; + char inbuf[MAX_FILENAMESIZE]; int inBufintRes = 0; double inBufdoubleRes = 0.; @@ -1730,11 +1729,11 @@ void SW_WTH_setup( if (lineno <= 22) { if (doIntConv) { - inBufintRes = (int) strtol(inbuf, &endPtr, 10); + inBufintRes = sw_strtoi(inbuf, MyFileName, LogInfo); } else { - inBufdoubleRes = strtod(inbuf, &endPtr); + inBufdoubleRes = sw_strtod(inbuf, MyFileName, LogInfo); } - check_errno(MyFileName, inbuf, endPtr, LogInfo); + if (LogInfo->stopRun) { return; // Exit function prematurely due to error } @@ -1896,12 +1895,13 @@ void SW_WTH_setup( for (index = 0; index < numInDefaultVars; index++) { if (index == 0) { - month = (int) strtol(weathInputStrs[index], &endPtr, 10); + month = + sw_strtoi(weathInputStrs[index], MyFileName, LogInfo); } else { *(inFloatVals[index - 1]) = - strtod(weathInputStrs[index], &endPtr); + sw_strtod(weathInputStrs[index], MyFileName, LogInfo); } - check_errno(MyFileName, weathInputStrs[index], endPtr, LogInfo); + if (LogInfo->stopRun) { return; // Exit function prematurely due to error } @@ -2229,7 +2229,7 @@ void read_weather_hist( double es, e, relHum, tempSlope, svpVal; - char fname[MAX_FILENAMESIZE], inbuf[MAX_FILENAMESIZE], *endPtr; + char fname[MAX_FILENAMESIZE], inbuf[MAX_FILENAMESIZE]; char weathInStrs[15][20]; @@ -2238,7 +2238,7 @@ void read_weather_hist( f = fopen(fname, "r"); if (isnull(f)) { - errno = 0; // no weather input file (use generator) --> reset errno + // no weather input file --> use generator return; } @@ -2292,13 +2292,14 @@ void read_weather_hist( for (index = 0; index < n_input_forcings + 1; index++) { if (index == 0) { - doy = (int) strtol(weathInStrs[index], &endPtr, 10); + doy = sw_strtoi(weathInStrs[index], fname, LogInfo); } else { - weathInput[index - 1] = strtod(weathInStrs[index], &endPtr); + weathInput[index - 1] = + sw_strtod(weathInStrs[index], fname, LogInfo); } - check_errno(fname, weathInStrs[index], endPtr, LogInfo); if (LogInfo->stopRun) { + CloseFile(&f, LogInfo); return; // Exit function prematurely due to error } } diff --git a/src/SW_netCDF.c b/src/SW_netCDF.c index 6963d5949..7325b5435 100644 --- a/src/SW_netCDF.c +++ b/src/SW_netCDF.c @@ -233,7 +233,7 @@ static void nc_read_atts( Bool hasKeys[NUM_ATT_IN_KEYS] = {swFALSE}; FILE *f; - char inbuf[LARGE_VALUE], value[LARGE_VALUE], *endPtr; + char inbuf[LARGE_VALUE], value[LARGE_VALUE]; char key[35]; // 35 - Max key size char *MyFileName; int keyID; @@ -302,12 +302,11 @@ static void nc_read_atts( if (doIntConv || doDoubleConv) { if (doIntConv) { - inBufintRes = (int) strtol(value, &endPtr, 10); + inBufintRes = sw_strtoi(value, MyFileName, LogInfo); } else { - inBufdoubleRes = strtod(value, &endPtr); + inBufdoubleRes = sw_strtod(value, MyFileName, LogInfo); } - check_errno(MyFileName, value, endPtr, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } @@ -411,14 +410,12 @@ static void nc_read_atts( return; /* Exit prematurely due to error */ } - num1 = strtod(numOneStr, &endPtr); - check_errno(MyFileName, numOneStr, endPtr, LogInfo); + num1 = sw_strtod(numOneStr, MyFileName, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } - num2 = strtod(numTwoStr, &endPtr); - check_errno(MyFileName, numTwoStr, endPtr, LogInfo); + num2 = sw_strtod(numTwoStr, MyFileName, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } @@ -4781,7 +4778,7 @@ void SW_NC_read_out_vars( int varNumUnits; int index, estVar; char *copyStr = NULL; - char input[NOUT_VAR_INPUTS][MAX_ATTVAL_SIZE] = {"\0"}, *endPtr; + char input[NOUT_VAR_INPUTS][MAX_ATTVAL_SIZE] = {"\0"}; char establn[MAX_ATTVAL_SIZE] = {"\0"}; int scanRes = 0, defToLocalInd = 0; // in readLineFormat: 255 must be equal to MAX_ATTVAL_SIZE - 1 @@ -4848,8 +4845,7 @@ void SW_NC_read_out_vars( // Check if the variable was requested to be output // Store attribute information for each variable (including names) - doOutputVal = (int) strtol(input[doOutInd], &endPtr, 10); - check_errno(MyFileName, input[doOutInd], endPtr, LogInfo); + doOutputVal = sw_strtoi(input[doOutInd], MyFileName, LogInfo); if (LogInfo->stopRun) { return; // Exit function prematurely due to error } diff --git a/src/filefuncs.c b/src/filefuncs.c index b0d7edde5..b44654872 100644 --- a/src/filefuncs.c +++ b/src/filefuncs.c @@ -17,10 +17,12 @@ #include // for assert #include // for isspace #include // for dirent, closedir, DIR, opendir, re... -#include // for errno, ENOENT, ERANGE +#include // for errno, ERANGE +#include // for LONG_MIN, LONG_MAX, INT_MIN, INT_MAX +#include // for HUGE_VAL, HUGE_VALF #include // for va_end, va_start #include // for NULL, fclose, FILE, fopen, EOF -#include // for free +#include // for free, strtod, strtof, strtol #include // for strlen, strrchr, strcpy, strchr #include // for stat, mkdir, S_ISDIR, S_ISREG #include // for chdir @@ -249,66 +251,199 @@ void sw_message(const char *msg) { } /** -@brief Throw error if `errno` or `endPtr` indicate an error - -This function generates an error (via `LogInfo`) if - - errno is not equal to 0, or - - endPtr (resulting from a call to `strtod()` or related function) - is not empty or does not point to whitespace - -@param[in] valMsg1 First message string; for instance, the input file name - that contains the value that threw the error -@param[in] valMsg2 Second message string; for instance, the input text - that caused the error when converting -@param[in] endPtr Resulting pointer after attempting to convert a numeric - value, e.g., with a call to `strtod()` or related function +@brief Convert string to unsigned long integer with error handling + +This function implements cert-err34-c +"Detect errors when converting a string to a number". + +@param[in] str Pointer to string to be converted. +@param[in] errMsg Pointer to string included in error message. @param[out] LogInfo Holds information on warnings and errors */ -void check_errno( - const char *valMsg1, char *valMsg2, const char *endPtr, LOG_INFO *LogInfo +unsigned long int sw_strtoul( + const char *str, const char *errMsg, LOG_INFO *LogInfo ) { - Bool failedStrToNum = - (Bool) (isnull(endPtr) ? swFALSE : (*endPtr != 0 && !isspace(*endPtr))); + unsigned long int resul = ULONG_MAX; + char *endStr; - const char *tmpMsg1 = - isnull(valMsg1) ? (const char *) "command-line arguments" : valMsg1; + errno = 0; + resul = strtoul(str, &endStr, 10); - if (errno == 0 && failedStrToNum) { + if (endStr == str || '\0' != *endStr) { LogError( - LogInfo, LOGERROR, "Processing '%s' within '%s'.", valMsg2, tmpMsg1 + LogInfo, + LOGERROR, + "%s: converting '%s' to unsigned long integer failed.", + errMsg, + str ); - } else if (errno != 0) { - switch (errno) { - case ERANGE: - LogError( - LogInfo, - LOGERROR, - "Processing '%s' within '%s': result too large.", - valMsg2, - tmpMsg1 - ); - break; + } else if (ULONG_MAX == resul && ERANGE == errno) { + LogError( + LogInfo, + LOGERROR, + "%s: '%s' out of range of type unsigned long integer.", + errMsg, + str + ); + } - case ENOENT: - LogError( - LogInfo, LOGERROR, "No such file or directory '%s'.", valMsg1 - ); - break; + return resul; +} + +/** +@brief Convert string to long integer with error handling + +This function implements cert-err34-c +"Detect errors when converting a string to a number". + +@param[in] str Pointer to string to be converted. +@param[in] errMsg Pointer to string included in error message. +@param[out] LogInfo Holds information on warnings and errors +*/ +long int sw_strtol(const char *str, const char *errMsg, LOG_INFO *LogInfo) { + long int resl = LONG_MIN; + char *endStr; - default: + errno = 0; + + resl = strtol(str, &endStr, 10); + + if (endStr == str || '\0' != *endStr) { + LogError( + LogInfo, + LOGERROR, + "%s: converting '%s' to long integer failed.", + errMsg, + str + ); + + } else if ((LONG_MIN == resl || LONG_MAX == resl) && ERANGE == errno) { + LogError( + LogInfo, + LOGERROR, + "%s: '%s' out of range of type long integer.", + errMsg, + str + ); + } + + return resl; +} + +/** +@brief Convert string to integer with error handling + +This function implements cert-err34-c +"Detect errors when converting a string to a number". + +@param[in] str Pointer to string to be converted. +@param[in] errMsg Pointer to string included in error message. +@param[out] LogInfo Holds information on warnings and errors +*/ +int sw_strtoi(const char *str, const char *errMsg, LOG_INFO *LogInfo) { + long int resl; + int resi = INT_MIN; + + resl = sw_strtol(str, errMsg, LogInfo); + + if (!LogInfo->stopRun) { + if (resl > INT_MAX || resl < INT_MIN) { LogError( LogInfo, LOGERROR, - "Processing '%s' within '%s': error code %d.", - valMsg2, - tmpMsg1, - errno + "%s: '%s' out of range of type integer.", + errMsg, + str ); - break; + + } else { + resi = (int) resl; } } + + return resi; +} + +/** +@brief Convert string to double with error handling + +This function implements cert-err34-c +"Detect errors when converting a string to a number". + +@param[in] str Pointer to string to be converted. +@param[in] errMsg Pointer to string included in error message. +@param[out] LogInfo Holds information on warnings and errors +*/ +double sw_strtod(const char *str, const char *errMsg, LOG_INFO *LogInfo) { + double resd = HUGE_VAL; + char *endStr; + + errno = 0; + + resd = strtod(str, &endStr); + + if (endStr == str || '\0' != *endStr) { + LogError( + LogInfo, + LOGERROR, + "%s: converting '%s' to double failed.", + errMsg, + str + ); + + } else if (HUGE_VAL == resd && ERANGE == errno) { + LogError( + LogInfo, + LOGERROR, + "%s: '%s' out of range of type double.", + errMsg, + str + ); + } + + return resd; +} + +/** +@brief Convert string to float with error handling + +This function implements cert-err34-c +"Detect errors when converting a string to a number". + +@param[in] str Pointer to string to be converted. +@param[in] errMsg Pointer to string included in error message. +@param[out] LogInfo Holds information on warnings and errors +*/ +float sw_strtof(const char *str, const char *errMsg, LOG_INFO *LogInfo) { + float resf = HUGE_VALF; + char *endStr; + + errno = 0; + + resf = strtof(str, &endStr); + + if (endStr == str || '\0' != *endStr) { + LogError( + LogInfo, + LOGERROR, + "%s: converting '%s' to float failed.", + errMsg, + str + ); + + } else if (HUGE_VALF == resf && ERANGE == errno) { + LogError( + LogInfo, + LOGERROR, + "%s: '%s' out of range of type float.", + errMsg, + str + ); + } + + return resf; } /**************************************************************/ @@ -380,7 +515,7 @@ FILE *OpenFile(const char *name, const char *mode, LOG_INFO *LogInfo) { fp = fopen(name, mode); if (isnull(fp)) { // Report error if file couldn't be opened - check_errno(name, NULL, NULL, LogInfo); + LogError(LogInfo, LOGERROR, "Cannot open file '%s'", name); } return (fp); } @@ -420,9 +555,6 @@ Bool FileExists(const char *name) { result = S_ISREG(statbuf.st_mode) ? swTRUE : swFALSE; } - // we are not interested here in errno (-> reset); we return TRUE/FALSE - errno = 0; - return (result); } @@ -462,6 +594,7 @@ Bool ChDir(const char *dname) { #define mkdir(d, m) mkdir(d, m) #endif +// Errors are reported via LogInfo void MkDir(const char *dname, LOG_INFO *LogInfo) { /* make a path with 'mkdir -p' -like behavior. provides an * interface for portability problems. @@ -485,7 +618,6 @@ void MkDir(const char *dname, LOG_INFO *LogInfo) { char *c; /* duplicate of dname so we don't change it */ const char *delim = "\\/"; /* path separators */ char buffer[MAX_ERROR]; - int resMkdir = 0; int startIndex = 0, strLen = 0; // For `sw_strtok()` @@ -509,13 +641,11 @@ void MkDir(const char *dname, LOG_INFO *LogInfo) { for (i = 0; i < n; i++) { strcat(buffer, a[i]); if (!DirExists(buffer)) { - resMkdir = mkdir(buffer, 0777); - if (0 == resMkdir) { - // directory successfully created -> reset errno - errno = 0; - } else { + if (0 != mkdir(buffer, 0777)) { // directory failed to create -> report error - check_errno(buffer, NULL, NULL, LogInfo); + LogError( + LogInfo, LOGERROR, "Failed to create directory '%s'", buffer + ); goto freeMem; // Exit function prematurely due to error } } @@ -539,7 +669,6 @@ Bool RemoveFiles(const char *fspec, LOG_INFO *LogInfo) { * eg: /here/now/fi*les, /here/now/files* * or /here/now/files * Returns TRUE if all files removed, FALSE otherwise. - * Check errno if return is FALSE. */ char **flist, fname[FILENAME_MAX]; diff --git a/tests/gtests/sw_testhelpers.cc b/tests/gtests/sw_testhelpers.cc index 5e3d9ee2a..22a270a70 100644 --- a/tests/gtests/sw_testhelpers.cc +++ b/tests/gtests/sw_testhelpers.cc @@ -169,7 +169,6 @@ int setup_testGlobalSoilwatTemplate() { // userSUID: 0 means no user input for suid, i.e., entire simulation domain userSUID = 0; - errno = 0; SW_CTL_setup_domain(userSUID, &template_SW_Domain, &LogInfo); if (LogInfo.stopRun) { diff --git a/tests/gtests/sw_testhelpers.h b/tests/gtests/sw_testhelpers.h index 079193515..4e32b1fa4 100644 --- a/tests/gtests/sw_testhelpers.h +++ b/tests/gtests/sw_testhelpers.h @@ -5,7 +5,6 @@ #include "include/SW_Domain.h" // for SW_DOM_deconstruct, SW_DOM_deepCopy #include "include/SW_Main_lib.h" // for sw_fail_on_error, sw_init_logs #include "gtest/gtest.h" // for Test -#include // for errno #include // for memcpy, NULL @@ -63,8 +62,6 @@ class AllTestFixture : public ::testing::Test { // (that were set up by `setup_testGlobalSoilwatTemplate()`) to // test fixture local variables void SetUp() override { - errno = 0; - sw_init_logs(NULL, &LogInfo); SW_DOM_deepCopy(&template_SW_Domain, &SW_Domain, &LogInfo);