diff --git a/.github/workflows/build_and_run_unit_test.yml b/.github/workflows/build_and_run_unit_test.yml index b979268..4c678d6 100644 --- a/.github/workflows/build_and_run_unit_test.yml +++ b/.github/workflows/build_and_run_unit_test.yml @@ -36,13 +36,13 @@ jobs: run: | cd ./test make clean - make 'CFLAGS=-g -fsanitize=address -Werror' + make 'CFLAGS=-g -Og -fsanitize=address -Werror' ./run_bmi_unit_test - name: Build and Run Standalone run: | cd src/ make clean - make 'CFLAGS=-g -fsanitize=address -Werror' + make 'CFLAGS=-g -Og -fsanitize=address -Werror' cd .. ./run_bmi diff --git a/.github/workflows/ngen_integration.yaml b/.github/workflows/ngen_integration.yaml index acf7915..194dec9 100644 --- a/.github/workflows/ngen_integration.yaml +++ b/.github/workflows/ngen_integration.yaml @@ -99,7 +99,7 @@ jobs: mod-dir: " extern/topmodel/" targets: "topmodelbmi" initialize: "false" - cmake-flags: "CFLAGS='-g -fsanitize=address -Werror'" + cmake-flags: "-DCMAKE_C_FLAGS='-g -Og -fsanitize=address -Werror'" - name: Run petbmi, topmodelbmi run: | diff --git a/include/topmodel.h b/include/topmodel.h index ad11ebb..e53a6e6 100755 --- a/include/topmodel.h +++ b/include/topmodel.h @@ -42,7 +42,7 @@ extern void init_discharge_array(int stand_alone, int *num_delay, double *Q0, do int *num_time_delay_histo_ords, double **time_delay_histogram, double **Q); -extern void init(FILE *in_param_fptr, FILE *output_fptr, char *subcat, int stand_alone, +extern int init(FILE *in_param_fptr, FILE *output_fptr, char *subcat, int stand_alone, int num_channels, int num_topodex_values, int yes_print_output, double area, double **time_delay_histogram, double *cum_dist_area_with_dist, double dt, @@ -54,7 +54,7 @@ extern void init(FILE *in_param_fptr, FILE *output_fptr, char *subcat, int stand double **deficit_root_zone,double *szq,double **Q, double *sbar, double *bal); -extern void inputs(FILE *input_fptr, int *nstep, double *dt, double **rain, +extern int inputs(FILE *input_fptr, int *nstep, double *dt, double **rain, double **pe, double **Qobs, double **Q, double **contrib_area); extern void topmod(FILE *output_fptr, int nstep, int num_topodex_values, @@ -69,7 +69,7 @@ extern void topmod(FILE *output_fptr, int nstep, int num_topodex_values, double *sump, double *sumae, double *sumq, double *sumrz, double *sumuz, double *quz, double *qb, double *qof, double *p, double *ep); -extern void tread(FILE *subcat_fptr,FILE *output_fptr,char *subcat, +extern int tread(FILE *subcat_fptr,FILE *output_fptr,char *subcat, int *num_topodex_values,int *num_channels,double *area, double **dist_area_lnaotb, double **lnaotb, int yes_print_output, int stand_alone, double **cum_dist_area_with_dist, double *tl, diff --git a/src/bmi_topmodel.c b/src/bmi_topmodel.c index a8bfbc3..a87a2ed 100755 --- a/src/bmi_topmodel.c +++ b/src/bmi_topmodel.c @@ -291,8 +291,10 @@ int init_config(const char* config_file, topmodel_model* model) if (model->stand_alone == TRUE){ /* READ IN nstep, DT and RAINFALL, PE, QOBS INPUTS */ - inputs(model->input_fptr, &model->nstep, &model->dt, &model->rain, &model->pe, - &model->Qobs, &model->Q, &model->contrib_area); + ret = inputs(model->input_fptr, &model->nstep, &model->dt, &model->rain, &model->pe, + &model->Qobs, &model->Q, &model->contrib_area); + if (ret != 0) + return BMI_FAILURE; fclose(model->input_fptr); } else { @@ -324,13 +326,15 @@ int init_config(const char* config_file, topmodel_model* model) fclose(model->subcat_fptr); - init(model->params_fptr,model->output_fptr,model->subcat,model->stand_alone, model->num_channels, model->num_topodex_values, + ret = init(model->params_fptr,model->output_fptr,model->subcat,model->stand_alone, model->num_channels, model->num_topodex_values, model->yes_print_output,model->area,&model->time_delay_histogram,model->cum_dist_area_with_dist, model->dt,model->tl,model->dist_from_outlet,&model->num_time_delay_histo_ords,&model->num_delay, &model->szm,&model->t0,&model->chv,&model->rv,&model->td, &model->srmax, &model->Q0,&model->sr0,&model->infex,&model->xk0,&model->hf,&model->dth, &model->stor_unsat_zone,&model->deficit_local,&model->deficit_root_zone, &model->szq,&model->Q,&model->sbar, &model->bal); + if (ret != 0) + return BMI_FAILURE; fclose(model->params_fptr); diff --git a/src/topmodel.c b/src/topmodel.c index cc9f4e6..58414bb 100755 --- a/src/topmodel.c +++ b/src/topmodel.c @@ -396,9 +396,14 @@ return; } -extern void inputs(FILE *input_fptr, int *nstep, double *dt, double **r, +#define TOPMODEL_CHECK_FGETS(x) do { str_ret = x; if (str_ret == NULL) return 1; } while (0) +#define TOPMODEL_CHECK_FSCANF(k, x) do { ret = x; if (ret != k) return 1; } while (0) + +extern int inputs(FILE *input_fptr, int *nstep, double *dt, double **r, double **pe, double **Qobs, double **Q, double **contrib_area) { +char* str_ret; +int ret; /*************************************************************** * SUBROUTINE INPUTS @@ -406,8 +411,7 @@ extern void inputs(FILE *input_fptr, int *nstep, double *dt, double **r, * This subroutine must read in rainfall, pe and observed * discharges for T = 1,NSTEP with time step DT hours ****************************************************************/ -int i; -fscanf(input_fptr,"%d %lf",nstep,dt); +TOPMODEL_CHECK_FSCANF(2, fscanf(input_fptr,"%d %lf",nstep,dt)); /* allocate memory for arrays */ /* TODO: When running on large scales, modify to allocate size via 'num_time_delay_histo_ords' @@ -427,22 +431,24 @@ d_alloc(contrib_area,(*nstep)); //--------------------------------------- // Note: Loop count starts at 1, not 0! //--------------------------------------- -for(i=1;i<=(*nstep);i++) +for(int i=1;i<=(*nstep);i++) { - fscanf(input_fptr,"%lf %lf %lf",&(*r)[i],&(*pe)[i],&(*Qobs)[i]); - + TOPMODEL_CHECK_FSCANF(3, fscanf(input_fptr,"%lf %lf %lf",&(*r)[i],&(*pe)[i],&(*Qobs)[i])); + (*Q)[i]=0.0; } -return; +return 0; } -extern void tread(FILE *subcat_fptr,FILE *output_fptr,char *subcat, +extern int tread(FILE *subcat_fptr,FILE *output_fptr,char *subcat, int *num_topodex_values,int *num_channels,double *area, double **dist_area_lnaotb,double **lnaotb, int yes_print_output, int stand_alone, double **cum_dist_area_with_dist,double *tl, double **dist_from_outlet) { +char* str_ret; +int ret; /************************************************************** SUBROUTINE TREAD @@ -454,14 +460,14 @@ int j; // NJF This won't work unless the first line of subcat file has already been consumed // Should probably document this behavior for this function... -fgets(subcat,256,subcat_fptr); /* do twice to read in line-feed */ -fgets(subcat,256,subcat_fptr); +TOPMODEL_CHECK_FGETS(fgets(subcat,256,subcat_fptr)); /* do twice to read in line-feed */ +TOPMODEL_CHECK_FGETS(fgets(subcat,256,subcat_fptr)); if (yes_print_output == TRUE && stand_alone == TRUE) { fprintf(output_fptr,"Subcatchment : %s\n",subcat); } -fscanf(subcat_fptr,"%d %lf",num_topodex_values,area); +TOPMODEL_CHECK_FSCANF(2, fscanf(subcat_fptr,"%d %lf",num_topodex_values,area)); //Setup the topoindex arrays if(*num_topodex_values > WARN_TOPODEX_INCREMENTS){ @@ -488,7 +494,7 @@ if((*lnaotb) == NULL){ tarea = 0; //Accumulate area as it is read for(j=1;j<=(*num_topodex_values);j++) { - fscanf(subcat_fptr,"%lf %lf",&(*dist_area_lnaotb)[j],&(*lnaotb)[j]); + TOPMODEL_CHECK_FSCANF(2, fscanf(subcat_fptr,"%lf %lf",&(*dist_area_lnaotb)[j],&(*lnaotb)[j])); tarea += (*dist_area_lnaotb)[j]; } /* dist_area_lnaotb IS DISTRIBUTION OF AREA WITH LN(A/TANB) */ @@ -512,7 +518,7 @@ for(j=2;j<=(*num_topodex_values);j++) (*dist_area_lnaotb)[(*num_topodex_values)+1]=0.0; /* READ CHANNEL NETWORK DATA */ -fscanf(subcat_fptr,"%d",num_channels); +TOPMODEL_CHECK_FSCANF(1, fscanf(subcat_fptr,"%d",num_channels)); if(*num_channels > WARN_NUM_SUBCATCHMENTS){ printf("WARNING: Number of channels, %d, is greater than %d\n", @@ -532,8 +538,8 @@ if((*dist_from_outlet) == NULL){ for(j=1;j<=(*num_channels);j++) { - fscanf(subcat_fptr,"%lf %lf", - &(*cum_dist_area_with_dist)[j],&(*dist_from_outlet)[j]); + TOPMODEL_CHECK_FSCANF(2, fscanf(subcat_fptr,"%lf %lf", + &(*cum_dist_area_with_dist)[j],&(*dist_from_outlet)[j])); } /* cum_dist_area_with_dist IS CUMULATIVE DISTRIBUTION OF AREA WITH dist_from_outlet */ /* dist_from_outlet[1] is distance from subcatchment outlet */ @@ -545,7 +551,7 @@ if(yes_print_output==TRUE && stand_alone==TRUE) fprintf(output_fptr,"SUMAC = %8.2lf\n",sumac); } -return; +return 0; } @@ -916,7 +922,7 @@ extern void init_water_balance(int num_topodex_values, double dt, double *sr0, * @params[out] bal, pointer of type double, residual of water balance * */ -extern void init(FILE *in_param_fptr, FILE *output_fptr, char *subcat, int stand_alone, +extern int init(FILE *in_param_fptr, FILE *output_fptr, char *subcat, int stand_alone, int num_channels, int num_topodex_values, int yes_print_output, double area, double **time_delay_histogram, double *cum_dist_area_with_dist, double dt, double tl, double *dist_from_outlet, int *num_time_delay_histo_ords, @@ -925,7 +931,8 @@ extern void init(FILE *in_param_fptr, FILE *output_fptr, char *subcat, int stand double **stor_unsat_zone, double **deficit_local, double **deficit_root_zone,double *szq, double **Q, double *sbar, double *bal) { - +char* str_ret; +int ret; /*************************************************************** SUBROUTINE INIT @@ -936,12 +943,12 @@ double sumar; int ir; /* read in run parameters */ -fgets(subcat,256,in_param_fptr); +TOPMODEL_CHECK_FGETS(fgets(subcat,256,in_param_fptr)); printf("subcat: %s\n", subcat); -fscanf(in_param_fptr,"%lf %lf %lf %lf %lf %lf %lf %lf %d %lf %lf %lf", - szm,t0,td,chv,rv,srmax,Q0,sr0,infex,xk0,hf,dth); +TOPMODEL_CHECK_FSCANF(12, fscanf(in_param_fptr,"%lf %lf %lf %lf %lf %lf %lf %lf %d %lf %lf %lf", + szm,t0,td,chv,rv,srmax,Q0,sr0,infex,xk0,hf,dth)); #if TOPMODEL_DEBUG >= 1 printf("\n\nCalibratable parameters from params*.dat:\n"); @@ -1008,7 +1015,7 @@ if(yes_print_output==TRUE && stand_alone == TRUE) } -return; +return 0; }