From 9455a29dc5f3a944e0306c8e6c4357e9e274d04a Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Wed, 23 Jan 2013 15:14:17 -0500 Subject: [PATCH] safe-strto.c: Add safe_strtoc() for parsing complex arguments Because people may wish to use safe-strto on systems that don't support the more recent complex.h (from C99) or may wish to avoid linking to libm, I've masked code related to safe_strtoc() behind HAVE_COMPLEX. If you define this symbol, you get safe_strtoc(), but have to link against libm. If you don't define this symbol, you don't get safe_strtoc(). To turn on the symbol for this project, I've created config.h. Usually such a config header would be created via the GNU Autotools suite (e.g. `./configure`). --- config.h | 25 +++++++++++++++++++++++++ safe-strto.c | 39 +++++++++++++++++++++++++++++++++++++-- safe-strto.h | 4 ++++ 3 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 config.h diff --git a/config.h b/config.h new file mode 100644 index 0000000..6501584 --- /dev/null +++ b/config.h @@ -0,0 +1,25 @@ +/* +Safe string-to-* conversion + +Copyright (C) 2013 W. Trevor King + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +#define HAVE_COMPLEX /* enable safe_strtoc() */ + +#endif /* _CONFIG_H_ */ diff --git a/safe-strto.c b/safe-strto.c index 6a63dbe..e104bb5 100644 --- a/safe-strto.c +++ b/safe-strto.c @@ -17,10 +17,15 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include /* for strtod(), exit(), EXIT_* */ +#include /* for strtod(), exit(), EXIT_*, free() */ #include /* for stderr, *printf(), perror() */ #include /* for errno */ -#include "safe-strto.h" /* check safe_strto*() declarations */ +#include "config.h" /* enabling safe_strtoc() */ +#ifdef HAVE_COMPLEX +# include /* for strdup(), strtok_r() */ +# include /* for the complex type qualifier */ +#endif /* HAVE_COMPLEX */ +#include "safe-strto.h" /* check safe_strto*() declarations */ long int safe_strtol(const char *str, int base, const char *name) { @@ -59,3 +64,33 @@ double safe_strtod(const char *str, const char *name) } return x; } + +#ifdef HAVE_COMPLEX + +double complex safe_strtoc(const char *str, const char *name) +{ + char *real, *imag, *tail, *saveptr; + char *local_str; + double complex z; + + local_str = strdup(str); + if (!local_str) { + fprintf(stderr, "could not duplicate %s for %s\n", str, name); + perror("strdup"); + exit(EXIT_FAILURE); + } + real = strtok_r(local_str, ",", &saveptr); + imag = strtok_r(NULL, ",", &saveptr); + tail = strtok_r(NULL, ",", &saveptr); + if (!real || !imag || tail) { /* '', 'x', or 'x,y,z...' */ + fprintf(stderr, "invalid value for %s (%s), use 'REAL,IMAGE'\n", + str, name); + free(local_str); + exit(EXIT_FAILURE); + } + z = safe_strtod(real, name) + I * safe_strtod(imag, name); + free(local_str); + return z; +} + +#endif /* HAVE_COMPLEX */ diff --git a/safe-strto.h b/safe-strto.h index e163843..e11219d 100644 --- a/safe-strto.h +++ b/safe-strto.h @@ -23,4 +23,8 @@ along with this program. If not, see . long int safe_strtol(const char *str, int base, const char *name); double safe_strtod(const char *str, const char *name); +#ifdef HAVE_COMPLEX +double complex safe_strtoc(const char *str, const char *name); +#endif /* HAVE_COMPLEX */ + #endif /* _SAFE_STRTO_H_ */ -- 2.26.2