\label{sec.get_options}
<<get options>>=
+<<safe strto*>>
void get_options(int argc, char **argv,
double *pP, double *pT_max, double *pDt_max, double *pV,
double *pX_step, state_t **pStop_state, environment_t *env,
}
}
break;
- case 't': *pT_max = atof(optarg); break;
- case 'd': *pDt_max = atof(optarg); break;
- case 'P': *pP = atof(optarg); break;
- case 'v': *pV = atof(optarg); break;
- case 'x': *pX_step = atof(optarg); break;
- case 'T': env->T = atof(optarg); break;
- case 'C': env->T = atof(optarg)+273.15; break;
+ case 't': *pT_max = safe_strtod(optarg, "-t"); break;
+ case 'd': *pDt_max = safe_strtod(optarg, "-d"); break;
+ case 'P': *pP = safe_strtod(optarg, "-P"); break;
+ case 'v': *pV = safe_strtod(optarg, "-v"); break;
+ case 'x': *pX_step = safe_strtod(optarg, "-x"); break;
+ case 'T': env->T = safe_strtod(optarg, "-T"); break;
+ case 'C': env->T = safe_strtod(optarg, "-C")+273.15; break;
case 's':
parse_list_string(optarg, SEP, '{', '}', &num_strings, &strings);
assert(num_strings >= 2 && num_strings <= 4);
}
tension_model = index_tension_model(n_tension_models, tension_models, strings[1]);
if (num_strings == 4)
- tension_group = atoi(strings[2]);
+ tension_group = safe_strtoi(strings[2], optarg);
else
tension_group = 0;
if (num_strings >= 3)
free_parsed_list(num_strings, strings);
break;
case 'N':
- n = atoi(optarg);
+ n = safe_strtoi(optarg, "-N");
#ifdef DEBUG
fprintf(stderr, "%s:\tadding %d domains to %s\n", __FUNCTION__, n, S(*pState_list)->name);
#endif
} while (0);
@
+First we define some safe string parsing functions. Currently these
+abort on any irregularity, but in the future they could print error
+messages, etc. [[static]] because the functions are currently
+defined in each [[*.c]] file that uses them, but perhaps they should
+be moved to [[utils.h/c]] or some such instead\ldots
+
+<<safe strto*>>=
+static int safe_strtoi(const char *s, const char *description) {
+ char *endp = NULL;
+ long int ret;
+ assert(s != NULL);
+ ret = strtol(s, &endp, 10);
+ if (endp[0] != '\0') { //strlen(endp) > 0) {
+ fprintf(stderr, "Error: unparsable '%s' while parsing '%s' for %s\n",
+ endp, s, description);
+ assert(1==0); //strlen(endp) == 0);
+ } else if (errno == ERANGE) {
+ fprintf(stderr, "Error: '%s' out of range for %s\n", s, description);
+ assert(errno != ERANGE);
+ }
+ return (int) ret;
+}
+
+static double safe_strtod(const char *s, const char *description) {
+ char *endp = NULL;
+ double ret;
+ assert(s != NULL);
+ ret = strtod(s, &endp);
+ if (endp[0] != '\0') { //strlen(endp) > 0) {
+ fprintf(stderr, "Error: unparsable '%s' while parsing '%s' for %s\n",
+ endp, s, description);
+ assert(1==0); //strlen(endp) == 0);
+ } else if (errno == ERANGE) {
+ fprintf(stderr, "Error: '%s' out of range for %s\n", s, description);
+ assert(errno != ERANGE);
+ }
+ return ret;
+}
+
+@
+
\phantomsection
\appendix
\addcontentsline{toc}{section}{Appendicies}
We include [[math.h]], so don't forget to link to the libm with `-lm'.
<<includes>>=
#include <assert.h> /* assert() */
-#include <stdlib.h> /* malloc(), free(), rand() */
+#include <stdlib.h> /* malloc(), free(), rand(), strto*() */
#include <stdio.h> /* fprintf(), stdout */
#include <string.h> /* strlen, strtok() */
#include <math.h> /* exp(), M_PI, sqrt() */
#include <sys/types.h> /* pid_t (returned by getpid()) */
#include <unistd.h> /* getpid() (for seeding rand()), getopt() */
+#include <errno.h> /* errno, ERANGE (for safe_strto*()) */
#include "global.h"
#include "list.h"
#include "tension_balance.h"
@
<<parse check includes>>=
-#include <stdlib.h> /* EXIT_SUCCESS and EXIT_FAILURE, atof() */
-#include <stdio.h> /* printf() */
-#include <assert.h> /* assert() */
-#include <string.h> /* strlen() */
+#include <stdlib.h> /* EXIT_SUCCESS and EXIT_FAILURE */
+#include <stdio.h> /* printf() */
+#include <assert.h> /* assert() */
+#include <string.h> /* strlen() */
<<check includes>>
#include "parse.h"
@
@
<<string eval check includes>>=
-#include <stdlib.h> /* EXIT_SUCCESS and EXIT_FAILURE, atof() */
-#include <stdio.h> /* printf() */
-#include <assert.h> /* assert() */
-#include <string.h> /* strlen() */
-#include <signal.h> /* SIGKILL */
+#include <stdlib.h> /* EXIT_SUCCESS and EXIT_FAILURE */
+#include <stdio.h> /* printf() */
+#include <assert.h> /* assert() */
+#include <string.h> /* strlen() */
+#include <signal.h> /* SIGKILL */
<<check includes>>
#include "string_eval.h"
@
void *string_create_const_tension_param_t(char **param_strings)
{
- return create_const_tension_param_t(atof(param_strings[0]));
+ return create_const_tension_param_t(
+ safe_strtod(param_strings[0],__FUNCTION__));
}
void destroy_const_tension_param_t(void *p)
void *string_create_hooke_param_t(char **param_strings)
{
- return create_hooke_param_t(atof(param_strings[0]));
+ return create_hooke_param_t(safe_strtod(param_strings[0], __FUNCTION__));
}
void destroy_hooke_param_t(void *p)
void *string_create_wlc_param_t(char **param_strings)
{
- return create_wlc_param_t(atof(param_strings[0]), atof(param_strings[1]));
+ return create_wlc_param_t(safe_strtod(param_strings[0], __FUNCTION__),
+ safe_strtod(param_strings[1], __FUNCTION__));
}
void destroy_wlc_param_t(void *p /* wlc_param_t * */)
void *string_create_fjc_param_t(char **param_strings)
{
- return create_fjc_param_t(atof(param_strings[0]), atof(param_strings[1]));
+ return create_fjc_param_t(safe_strtod(param_strings[0], __FUNCTION__),
+ safe_strtod(param_strings[1], __FUNCTION__));
}
void destroy_fjc_param_t(void *p)
<<tension model includes>>=
#include <assert.h> /* assert() */
-#include <stdlib.h> /* NULL */
+#include <stdlib.h> /* NULL, strto*() */
#include <math.h> /* HUGE_VAL, sqrt(), exp() */
#include <stdio.h> /* fprintf(), stdout */
+#include <errno.h> /* errno, ERANGE */
#include "global.h"
#include "list.h"
#include "tension_balance.h" /* oneD_*() */
@
<<tension model functions>>=
+<<safe strto*>>
<<constant tension functions>>
<<hooke functions>>
<<worm-like chain functions>>
<<tension model utility includes>>=
#include <stdlib.h>
#include <stdio.h>
-#include <string.h> /* strlen() */
-#include <assert.h> /* assert() */
+#include <string.h> /* strlen() */
+#include <assert.h> /* assert() */
+#include <errno.h> /* errno, ERANGE */
#include "global.h"
#include "parse.h"
#include "list.h"
@
<<tension model utility getopt functions>>=
+<<safe strto*>>
<<index tension model>>
<<tension model utility help>>
<<tension model utility get options>>
/* setup defaults */
prog_name = argv[0];
- env->T = 300.0; /* K */
- *Fmax = 1e5;
- *Xmax = 1e-6;
+ env->T = 300.0; /* K */
+ *Fmax = 1e5; /* N */
+ *Xmax = 1e-6; /* m */
*flags = 0;
*model = tension_models;
while ((c=getopt(argc, argv, options)) != -1) {
switch(c) {
- case 'T': env->T = atof(optarg); break;
- case 'C': env->T = atof(optarg)+273.15; break;
+ case 'T': env->T = safe_strtod(optarg, "-T"); break;
+ case 'C': env->T = safe_strtod(optarg, "-C")+273.15; break;
case 'm':
tension_model = index_tension_model(n_tension_models, tension_models, optarg);
*model = tension_models+tension_model;
case 'a':
tension_models[tension_model].params = optarg;
break;
- case 'F': *Fmax = atof(optarg); break;
- case 'X': *Xmax = atof(optarg); break;
- case 'V': *flags |= VFLAG; break;
+ case 'F': *Fmax = safe_strtod(optarg, "-F"); break;
+ case 'X': *Xmax = safe_strtod(optarg, "-X"); break;
+ case 'V': *flags |= VFLAG; break;
case '?':
fprintf(stderr, "unrecognized option '%c'\n", optopt);
/* fall through to default case */
void *string_create_const_k_param_t(char **param_strings)
{
- return create_const_k_param_t(atof(param_strings[0]));
+ return create_const_k_param_t(safe_strtod(param_strings[0], __FUNCTION__));
}
void destroy_const_k_param_t(void *p /* const_k_param_t * */)
void *string_create_bell_param_t(char **param_strings)
{
- return create_bell_param_t(atof(param_strings[0]), atof(param_strings[1]));
+ return create_bell_param_t(safe_strtod(param_strings[0], __FUNCTION__),
+ safe_strtod(param_strings[1], __FUNCTION__));
}
void destroy_bell_param_t(void *p /* bell_param_t * */)
void *string_create_kbell_param_t(char **param_strings)
{
- return create_kbell_param_t(atof(param_strings[0]), atof(param_strings[1]));
+ return create_kbell_param_t(safe_strtod(param_strings[0], __FUNCTION__),
+ safe_strtod(param_strings[1], __FUNCTION__));
}
void destroy_kbell_param_t(void *p /* kbell_param_t * */)
fprintf(in, "F = %g; T = %g\n", F, T);
sprintf(input, "print repr(%s)\n", fn); /* repr() to keep full precision */
string_eval(in, out, input, 80, output);
- return atof(output);
+ return safe_strtod(output, __FUNCTION__);
}
double kramers_E_fn(FILE *in, FILE *out, char *fn, double F, double T, double x)
fprintf(in, "F = %g;T = %g;x = %g\n", F, T, x);
sprintf(input, "print repr(%s)\n", fn); /* repr() to keep full precision */
string_eval(in, out, input, 80, output);
- return atof(output);
+ return safe_strtod(output, __FUNCTION__);
}
double kramers_E(double F, environment_t *env, void *kramers_params, double x)
/* takes an array of 4 functions: {"(1,2),(2,0),..."} */
void *string_create_kramers_param_t(char **param_strings)
{
- return create_kramers_param_t(atof(param_strings[0]),
+ return create_kramers_param_t(safe_strtod(param_strings[0], __FUNCTION__),
param_strings[2],
param_strings[3],
param_strings[4],
//printf("create kramers integ. D: %s, knots: %s, x in [%s, %s]\n",
// param_strings[0],param_strings[1],param_strings[2],param_strings[3]);
void *E_params = string_create_spline_param_t(param_strings+1);
- return create_kramers_integ_param_t(atof(param_strings[0]),
- atof(param_strings[2]),
- atof(param_strings[3]),
- &spline_eval, E_params,
- destroy_spline_param_t);
+ return create_kramers_integ_param_t(
+ safe_strtod(param_strings[0], __FUNCTION__),
+ safe_strtod(param_strings[2], __FUNCTION__),
+ safe_strtod(param_strings[3], __FUNCTION__),
+ &spline_eval, E_params, destroy_spline_param_t);
}
void destroy_kramers_integ_param_t(void *params)
@
<<k model includes>>=
-#include <assert.h> /* assert() */
-#include <stdlib.h> /* NULL, malloc() */
-#include <math.h> /* HUGE_VAL, sqrt(), exp() */
-#include <stdio.h> /* fprintf(), stdout */
-#include <string.h> /* strlen(), strcpy() */
+#include <assert.h> /* assert() */
+#include <stdlib.h> /* NULL, malloc(), strto*() */
+#include <math.h> /* HUGE_VAL, sqrt(), exp() */
+#include <stdio.h> /* fprintf(), stdout */
+#include <string.h> /* strlen(), strcpy() */
+#include <errno.h> /* errno, ERANGE */
#include <gsl/gsl_integration.h>
#include <gsl/gsl_spline.h>
#include "global.h"
@
<<k model functions>>=
+<<safe strto*>>
<<null k functions>>
<<const k functions>>
<<bell k functions>>
@
<<k model check includes>>=
-#include <stdlib.h> /* EXIT_SUCCESS and EXIT_FAILURE, atof() */
-#include <stdio.h> /* sprintf() */
-#include <assert.h> /* assert() */
-#include <math.h> /* exp() */
+#include <stdlib.h> /* EXIT_SUCCESS, EXIT_FAILURE */
+#include <stdio.h> /* sprintf() */
+#include <assert.h> /* assert() */
+#include <math.h> /* exp() */
+#include <errno.h> /* errno, ERANGE */
<<check includes>>
#include "global.h"
#include "k_model.h"
@
<<k model test suite>>=
+<<safe strto*>>
<<const k tests>>
<<bell k tests>>
<<k model suite definition>>
params[0] = knot[i];
p = string_create_const_k_param_t(params);
for ( F=Fm; F<FM; F+=dF ) {
- fail_unless(const_k(F, &env, p)==atof(knot[i]),
+ fail_unless(const_k(F, &env, p)==safe_strtod(knot[i], __FUNCTION__),
"const_k(%g, %g, &{%s}) = %g != %s",
F, T, knot[i], const_k(F, &env, p), knot[i]);
}
for( i=0; i < sizeof(knot)/sizeof(char *); i++) {
params[0] = knot[i];
p = string_create_bell_param_t(params);
- fail_unless(bell_k(F, &env, p)==atof(knot[i]),
+ fail_unless(bell_k(F, &env, p)==safe_strtod(knot[i], __FUNCTION__),
"bell_k(%g, %g, &{%s,%s}) = %g != %s",
F, T, knot[i], dx, bell_k(F, &env, p), knot[i]);
destroy_bell_param_t(p);
char *knot[] = {"1","2","3","4","5","6"};
char *dx="1";
char *params[] = {knot[0], dx};
- double F= k_B*T/atof(dx);
+ double F= k_B*T/safe_strtod(dx, __FUNCTION__);
void *p = NULL;
environment_t env;
char param_string[80];
for( i=0; i < sizeof(knot)/sizeof(char *); i++) {
params[0] = knot[i];
p = string_create_bell_param_t(params);
- CHECK_ERR(1e-6, atof(knot[i])*exp(1.0), bell_k(F, &env, p));
- //fail_unless(bell_k(F, &env, p)==atof(knot[i])*exp(1.0),
+ CHECK_ERR(1e-6, safe_strtod(knot[i], __FUNCTION__)*exp(1.0), bell_k(F, &env, p));
+ //fail_unless(bell_k(F, &env, p)==safe_strtod(knot[i], __FUNCTION__)*exp(1.0),
// "bell_k(%g, %g, &{%s,%s}) = %g != %g",
- // F, T, knot[i], dx, bell_k(F, &env, p), atof(knot[i])*exp(1.0));
+ // F, T, knot[i], dx, bell_k(F, &env, p), safe_strtod(knot[i], __FUNCTION__)*exp(1.0));
destroy_bell_param_t(p);
}
}
<<k model utility includes>>=
#include <stdlib.h>
#include <stdio.h>
-#include <string.h> /* strlen() */
-#include <assert.h> /* assert() */
+#include <string.h> /* strlen() */
+#include <assert.h> /* assert() */
+#include <errno.h> /* errno, ERANGE */
#include "global.h"
#include "parse.h"
#include "string_eval.h"
@
<<k model utility getopt functions>>=
+<<safe strto*>>
<<index k model>>
<<k model utility help>>
<<k model utility get options>>
/* setup defaults */
prog_name = argv[0];
- env->T = 300.0; /* K */
+ env->T = 300.0; /* K */
*mode = M_K_OF_F;
*flags = 0;
*model = k_models;
- *Fmax = 1e-9;
+ *Fmax = 1e-9; /* N */
*special_xmax = 1e-8;
*special_xmin = 0.0;
while ((c=getopt(argc, argv, options)) != -1) {
switch(c) {
- case 'T': env->T = atof(optarg); break;
- case 'C': env->T = atof(optarg)+273.15; break;
+ case 'T': env->T = safe_strtod(optarg, "-T"); break;
+ case 'C': env->T = safe_strtod(optarg, "-C")+273.15; break;
case 'k':
k_model = index_k_model(n_k_models, k_models, optarg);
*model = k_models+k_model;
case 'K':
k_models[k_model].params = optarg;
break;
- case 'm': *mode = M_K_OF_F; break;
- case 'M': *mode = M_SPECIAL; break;
- case 'F': *Fmax = atof(optarg); break;
- case 'x': *special_xmin = atof(optarg); break;
- case 'X': *special_xmax = atof(optarg); break;
- case 'V': *flags |= VFLAG; break;
+ case 'm': *mode = M_K_OF_F; break;
+ case 'M': *mode = M_SPECIAL; break;
+ case 'F': *Fmax = safe_strtod(optarg, "-F"); break;
+ case 'x': *special_xmin = safe_strtod(optarg, "-x"); break;
+ case 'X': *special_xmax = safe_strtod(optarg, "-X"); break;
+ case 'V': *flags |= VFLAG; break;
case '?':
fprintf(stderr, "unrecognized option '%c'\n", optopt);
/* fall through to default case */