From 06080ca491088f5d3c1221a64a8d9d61f05dfbe1 Mon Sep 17 00:00:00 2001 From: Attila Kovacs Date: Sun, 10 Nov 2024 12:45:50 +0100 Subject: [PATCH] Add novas_planet_for_name() --- config.mk | 1 + include/novas.h | 4 +- src/super.c | 52 +++++++++++++++++++ test/src/test-errors.c | 16 ++++++ test/src/test-super.c | 114 ++++++++++++++++++++++++----------------- 5 files changed, 137 insertions(+), 50 deletions(-) diff --git a/config.mk b/config.mk index 3966ba66..8a69c285 100644 --- a/config.mk +++ b/config.mk @@ -21,6 +21,7 @@ CC ?= gcc CPPFLAGS += -I$(INC) # Base compiler options (if not defined externally...) +# -std=c99 may not be supported by some very old compilers... CFLAGS ?= -Os -Wall -std=c99 # Extra warnings (not supported on all compilers) diff --git a/include/novas.h b/include/novas.h index 75a26024..370c2339 100644 --- a/include/novas.h +++ b/include/novas.h @@ -1285,8 +1285,6 @@ int make_redshifted_object(const char *name, double ra, double dec, double z, ob double novas_z2v(double z); - -// in util.c double novas_v2z(double vel); double grav_redshift(double M_kg, double r_m); @@ -1299,6 +1297,8 @@ double novas_z_add(double z1, double z2); double novas_z_inv(double z); +enum novas_planet novas_planet_for_name(const char *name); + // <================= END of SuperNOVAS API =====================> diff --git a/src/super.c b/src/super.c index 3282ef8d..9e9424d9 100644 --- a/src/super.c +++ b/src/super.c @@ -8,6 +8,14 @@ * can live in a separate, more manageably sized, module. */ +// We'll use gcc major version as a proxy for the glibc library to decide which feature macro to use. +// gcc 5.1 was released 2015-04-22... +#if __GNUC__ >= 5 +# define _DEFAULT_SOURCE ///< strcasdecmp() feature macro starting glibc 2.20 (2014-09-08) +#else +# define _BSD_SOURCE ///< strcasecmp() feature macro for glibc <= 2.19 +#endif + #include #include #include @@ -1277,3 +1285,47 @@ double novas_z_inv(double z) { return 1.0 / (1.0 + z) - 1.0; } +/** + * Returns the NOVAS planet ID for a given name (case insensitive), or -1 if no match is found. + * + * @param name The planet name, or that for the "Sun", "Moon" or "SSB" (case insensitive). + * The spelled out "Solar System Barycenter" is also recognized with either spaces, + * hyphens ('-') or underscores ('_') separating the case insensitive words. + * @return The NOVAS major planet ID, or -1 (errno set to EINVAL) if the input name is + * NULL or if there is no match for the name provided. + * + * @author Attila Kovacs + * @since 1.2 + * + * @sa make_planet() + */ +enum novas_planet novas_planet_for_name(const char *name) { + static const char *fn = "novas_planet_for_name()"; + static const char *names[] = NOVAS_PLANET_NAMES_INIT; + + char *tok; + int i; + + if(!name) + return novas_error(-1, EINVAL, fn, "Input name is NULL"); + + if(!name[0]) + return novas_error(-1, EINVAL, fn, "Input name is empty"); + + for(i = 0; i < NOVAS_PLANETS; i++) + if(strcasecmp(name, (const char *) names[i]) == 0) + return i; + + // Check for Solar System Barycenter (and variants) + tok = strtok(strdup(name), " \t-_"); + if(strcasecmp("solar", tok) == 0) { + tok = strtok(NULL, " \t-_"); + if(tok && strcasecmp("system", tok) == 0) { + tok = strtok(NULL, " \t-_"); + if(tok && strcasecmp("barycenter", tok) == 0) + return NOVAS_SSB; + } + } + + return novas_error(-1, EINVAL, fn, "No match for name: '%s'", name); +} diff --git a/test/src/test-errors.c b/test/src/test-errors.c index ce1ba3ce..a74da61d 100644 --- a/test/src/test-errors.c +++ b/test/src/test-errors.c @@ -1478,6 +1478,20 @@ static int test_naif_to_novas_planet() { return n; } +static int test_planet_for_name() { + int n = 0; + + if(check("planet_for_name:NULL", -1, novas_planet_for_name(NULL))) n++; + if(check("planet_for_name:blah", -1, novas_planet_for_name(""))) n++; + if(check("planet_for_name:blah", -1, novas_planet_for_name("blah"))) n++; + if(check("planet_for_name:blah", -1, novas_planet_for_name("solar"))) n++; + if(check("planet_for_name:blah", -1, novas_planet_for_name("Solar flare"))) n++; + if(check("planet_for_name:blah", -1, novas_planet_for_name("Solar system"))) n++; + if(check("planet_for_name:blah", -1, novas_planet_for_name("Solar system size"))) n++; + + return n; +} + int main() { int n = 0; @@ -1606,6 +1620,8 @@ int main() { if(test_novas_to_dexxx_planet()) n++; if(test_naif_to_novas_planet()) n++; + if(test_planet_for_name()) n++; + if(n) fprintf(stderr, " -- FAILED %d tests\n", n); else fprintf(stderr, " -- OK\n"); diff --git a/test/src/test-super.c b/test/src/test-super.c index c74e89eb..65d030ea 100644 --- a/test/src/test-super.c +++ b/test/src/test-super.c @@ -2132,68 +2132,84 @@ static int test_z_inv() { } static int test_novas_to_naif_planet() { + int n = 0; - if(!is_ok("novas_to_naif_planet:ssb", novas_to_naif_planet(NOVAS_SSB) != NAIF_SSB)) return 1; - if(!is_ok("novas_to_naif_planet:sun", novas_to_naif_planet(NOVAS_SUN) != NAIF_SUN)) return 1; - if(!is_ok("novas_to_naif_planet:moon", novas_to_naif_planet(NOVAS_MOON) != NAIF_MOON)) return 1; - if(!is_ok("novas_to_naif_planet:earth", novas_to_naif_planet(NOVAS_EARTH) != NAIF_EARTH)) return 1; - if(!is_ok("novas_to_naif_planet:mercury", novas_to_naif_planet(NOVAS_MERCURY) != 199)) return 1; - if(!is_ok("novas_to_naif_planet:venus", novas_to_naif_planet(NOVAS_VENUS) != 299)) return 1; - if(!is_ok("novas_to_naif_planet:mars", novas_to_naif_planet(NOVAS_MARS) != 499)) return 1; - if(!is_ok("novas_to_naif_planet:jupiter", novas_to_naif_planet(NOVAS_JUPITER) != 599)) return 1; - if(!is_ok("novas_to_naif_planet:saturn", novas_to_naif_planet(NOVAS_SATURN) != 699)) return 1; - if(!is_ok("novas_to_naif_planet:uranus", novas_to_naif_planet(NOVAS_URANUS) != 799)) return 1; - if(!is_ok("novas_to_naif_planet:neptune", novas_to_naif_planet(NOVAS_NEPTUNE) != 899)) return 1; - if(!is_ok("novas_to_naif_planet:pluto", novas_to_naif_planet(NOVAS_PLUTO) != 999)) return 1; + if(!is_ok("novas_to_naif_planet:ssb", novas_to_naif_planet(NOVAS_SSB) != NAIF_SSB)) n++; + if(!is_ok("novas_to_naif_planet:sun", novas_to_naif_planet(NOVAS_SUN) != NAIF_SUN)) n++; + if(!is_ok("novas_to_naif_planet:moon", novas_to_naif_planet(NOVAS_MOON) != NAIF_MOON)) n++; + if(!is_ok("novas_to_naif_planet:earth", novas_to_naif_planet(NOVAS_EARTH) != NAIF_EARTH)) n++; + if(!is_ok("novas_to_naif_planet:mercury", novas_to_naif_planet(NOVAS_MERCURY) != 199)) n++; + if(!is_ok("novas_to_naif_planet:venus", novas_to_naif_planet(NOVAS_VENUS) != 299)) n++; + if(!is_ok("novas_to_naif_planet:mars", novas_to_naif_planet(NOVAS_MARS) != 499)) n++; + if(!is_ok("novas_to_naif_planet:jupiter", novas_to_naif_planet(NOVAS_JUPITER) != 599)) n++; + if(!is_ok("novas_to_naif_planet:saturn", novas_to_naif_planet(NOVAS_SATURN) != 699)) n++; + if(!is_ok("novas_to_naif_planet:uranus", novas_to_naif_planet(NOVAS_URANUS) != 799)) n++; + if(!is_ok("novas_to_naif_planet:neptune", novas_to_naif_planet(NOVAS_NEPTUNE) != 899)) n++; + if(!is_ok("novas_to_naif_planet:pluto", novas_to_naif_planet(NOVAS_PLUTO) != 999)) n++; - return 0; + return n; } static int test_novas_to_dexxx_planet() { + int n = 0; - if(!is_ok("novas_to_dexxx_planet:ssb", novas_to_dexxx_planet(NOVAS_SSB) != NAIF_SSB)) return 1; - if(!is_ok("novas_to_dexxx_planet:sun", novas_to_dexxx_planet(NOVAS_SUN) != NAIF_SUN)) return 1; - if(!is_ok("novas_to_dexxx_planet:moon", novas_to_dexxx_planet(NOVAS_MOON) != NAIF_MOON)) return 1; - if(!is_ok("novas_to_dexxx_planet:earth", novas_to_dexxx_planet(NOVAS_EARTH) != NAIF_EARTH)) return 1; - if(!is_ok("novas_to_dexxx_planet:mercury", novas_to_dexxx_planet(NOVAS_MERCURY) != 1)) return 1; - if(!is_ok("novas_to_dexxx_planet:venus", novas_to_dexxx_planet(NOVAS_VENUS) != 2)) return 1; - if(!is_ok("novas_to_dexxx_planet:mars", novas_to_dexxx_planet(NOVAS_MARS) != 4)) return 1; - if(!is_ok("novas_to_dexxx_planet:jupiter", novas_to_dexxx_planet(NOVAS_JUPITER) != 5)) return 1; - if(!is_ok("novas_to_dexxx_planet:saturn", novas_to_dexxx_planet(NOVAS_SATURN) != 6)) return 1; - if(!is_ok("novas_to_dexxx_planet:uranus", novas_to_dexxx_planet(NOVAS_URANUS) != 7)) return 1; - if(!is_ok("novas_to_dexxx_planet:neptune", novas_to_dexxx_planet(NOVAS_NEPTUNE) != 8)) return 1; - if(!is_ok("novas_to_dexxx_planet:pluto", novas_to_dexxx_planet(NOVAS_PLUTO) != 9)) return 1; + if(!is_ok("novas_to_dexxx_planet:ssb", novas_to_dexxx_planet(NOVAS_SSB) != NAIF_SSB)) n++; + if(!is_ok("novas_to_dexxx_planet:sun", novas_to_dexxx_planet(NOVAS_SUN) != NAIF_SUN)) n++; + if(!is_ok("novas_to_dexxx_planet:moon", novas_to_dexxx_planet(NOVAS_MOON) != NAIF_MOON)) n++; + if(!is_ok("novas_to_dexxx_planet:earth", novas_to_dexxx_planet(NOVAS_EARTH) != NAIF_EARTH)) n++; + if(!is_ok("novas_to_dexxx_planet:mercury", novas_to_dexxx_planet(NOVAS_MERCURY) != 1)) n++; + if(!is_ok("novas_to_dexxx_planet:venus", novas_to_dexxx_planet(NOVAS_VENUS) != 2)) n++; + if(!is_ok("novas_to_dexxx_planet:mars", novas_to_dexxx_planet(NOVAS_MARS) != 4)) n++; + if(!is_ok("novas_to_dexxx_planet:jupiter", novas_to_dexxx_planet(NOVAS_JUPITER) != 5)) n++; + if(!is_ok("novas_to_dexxx_planet:saturn", novas_to_dexxx_planet(NOVAS_SATURN) != 6)) n++; + if(!is_ok("novas_to_dexxx_planet:uranus", novas_to_dexxx_planet(NOVAS_URANUS) != 7)) n++; + if(!is_ok("novas_to_dexxx_planet:neptune", novas_to_dexxx_planet(NOVAS_NEPTUNE) != 8)) n++; + if(!is_ok("novas_to_dexxx_planet:pluto", novas_to_dexxx_planet(NOVAS_PLUTO) != 9)) n++; - return 0; + return n; } static int test_naif_to_novas_planet() { + int n = 0; - if(!is_ok("naif_to_novas_planet:ssb", naif_to_novas_planet(NAIF_SSB) != NOVAS_SSB)) return 1; - if(!is_ok("naif_to_novas_planet:sun", naif_to_novas_planet(NAIF_SUN) != NOVAS_SUN)) return 1; - if(!is_ok("naif_to_novas_planet:moon", naif_to_novas_planet(NAIF_MOON) != NOVAS_MOON)) return 1; - if(!is_ok("naif_to_novas_planet:earth", naif_to_novas_planet(NAIF_EARTH) != NOVAS_EARTH)) return 1; - if(!is_ok("naif_to_novas_planet:mercury", naif_to_novas_planet(199) != NOVAS_MERCURY)) return 1; - if(!is_ok("naif_to_novas_planet:venus", naif_to_novas_planet(299) != NOVAS_VENUS)) return 1; - if(!is_ok("naif_to_novas_planet:mars", naif_to_novas_planet(499) != NOVAS_MARS)) return 1; - if(!is_ok("naif_to_novas_planet:jupiter", naif_to_novas_planet(599) != NOVAS_JUPITER)) return 1; - if(!is_ok("naif_to_novas_planet:saturn", naif_to_novas_planet(699) != NOVAS_SATURN)) return 1; - if(!is_ok("naif_to_novas_planet:uranus", naif_to_novas_planet(799) != NOVAS_URANUS)) return 1; - if(!is_ok("naif_to_novas_planet:neptune", naif_to_novas_planet(899) != NOVAS_NEPTUNE)) return 1; - if(!is_ok("naif_to_novas_planet:pluto", naif_to_novas_planet(999) != NOVAS_PLUTO)) return 1; - if(!is_ok("naif_to_novas_planet:mercury", naif_to_novas_planet(1) != NOVAS_MERCURY)) return 1; - if(!is_ok("naif_to_novas_planet:venus", naif_to_novas_planet(2) != NOVAS_VENUS)) return 1; - if(!is_ok("naif_to_novas_planet:emb", naif_to_novas_planet(3) != -1)) return 1; - if(!is_ok("naif_to_novas_planet:mars", naif_to_novas_planet(4) != NOVAS_MARS)) return 1; - if(!is_ok("naif_to_novas_planet:jupiter", naif_to_novas_planet(5) != NOVAS_JUPITER)) return 1; - if(!is_ok("naif_to_novas_planet:saturn", naif_to_novas_planet(6) != NOVAS_SATURN)) return 1; - if(!is_ok("naif_to_novas_planet:uranus", naif_to_novas_planet(7) != NOVAS_URANUS)) return 1; - if(!is_ok("naif_to_novas_planet:neptune", naif_to_novas_planet(8) != NOVAS_NEPTUNE)) return 1; - if(!is_ok("naif_to_novas_planet:pluto", naif_to_novas_planet(9) != NOVAS_PLUTO)) return 1; + if(!is_ok("naif_to_novas_planet:ssb", naif_to_novas_planet(NAIF_SSB) != NOVAS_SSB)) n++; + if(!is_ok("naif_to_novas_planet:sun", naif_to_novas_planet(NAIF_SUN) != NOVAS_SUN)) n++; + if(!is_ok("naif_to_novas_planet:moon", naif_to_novas_planet(NAIF_MOON) != NOVAS_MOON)) n++; + if(!is_ok("naif_to_novas_planet:earth", naif_to_novas_planet(NAIF_EARTH) != NOVAS_EARTH)) n++; + if(!is_ok("naif_to_novas_planet:mercury", naif_to_novas_planet(199) != NOVAS_MERCURY)) n++; + if(!is_ok("naif_to_novas_planet:venus", naif_to_novas_planet(299) != NOVAS_VENUS)) n++; + if(!is_ok("naif_to_novas_planet:mars", naif_to_novas_planet(499) != NOVAS_MARS)) n++; + if(!is_ok("naif_to_novas_planet:jupiter", naif_to_novas_planet(599) != NOVAS_JUPITER)) n++; + if(!is_ok("naif_to_novas_planet:saturn", naif_to_novas_planet(699) != NOVAS_SATURN)) n++; + if(!is_ok("naif_to_novas_planet:uranus", naif_to_novas_planet(799) != NOVAS_URANUS)) n++; + if(!is_ok("naif_to_novas_planet:neptune", naif_to_novas_planet(899) != NOVAS_NEPTUNE)) n++; + if(!is_ok("naif_to_novas_planet:pluto", naif_to_novas_planet(999) != NOVAS_PLUTO)) n++; + if(!is_ok("naif_to_novas_planet:mercury", naif_to_novas_planet(1) != NOVAS_MERCURY)) n++; + if(!is_ok("naif_to_novas_planet:venus", naif_to_novas_planet(2) != NOVAS_VENUS)) n++; + if(!is_ok("naif_to_novas_planet:mars", naif_to_novas_planet(4) != NOVAS_MARS)) n++; + if(!is_ok("naif_to_novas_planet:jupiter", naif_to_novas_planet(5) != NOVAS_JUPITER)) n++; + if(!is_ok("naif_to_novas_planet:saturn", naif_to_novas_planet(6) != NOVAS_SATURN)) n++; + if(!is_ok("naif_to_novas_planet:uranus", naif_to_novas_planet(7) != NOVAS_URANUS)) n++; + if(!is_ok("naif_to_novas_planet:neptune", naif_to_novas_planet(8) != NOVAS_NEPTUNE)) n++; + if(!is_ok("naif_to_novas_planet:pluto", naif_to_novas_planet(9) != NOVAS_PLUTO)) n++; - return 0; + return n; } +static int test_planet_for_name() { + int n = 0; + + if(!is_ok("planet_for_name:mercury", novas_planet_for_name("mercury") != NOVAS_MERCURY)) n++; + if(!is_ok("planet_for_name:pluto", novas_planet_for_name("PLUTO") != NOVAS_PLUTO)) n++; + if(!is_ok("planet_for_name:sun", novas_planet_for_name("Sun") != NOVAS_SUN)) n++; + if(!is_ok("planet_for_name:moon", novas_planet_for_name("MooN") != NOVAS_MOON)) n++; + if(!is_ok("planet_for_name:ssb", novas_planet_for_name("SSB") != NOVAS_SSB)) n++; + if(!is_ok("planet_for_name:ssb1", novas_planet_for_name("Solar-system barycenter") != NOVAS_SSB)) n++; + + return n; +} + + int main(int argc, char *argv[]) { int n = 0; @@ -2257,6 +2273,8 @@ int main(int argc, char *argv[]) { if(test_novas_to_dexxx_planet()) n++; if(test_naif_to_novas_planet()) n++; + if(test_planet_for_name()) n++; + n += test_dates(); return n;