diff --git a/src/calcelestial.c b/src/calcelestial.c index f520eb2..8baffb6 100644 --- a/src/calcelestial.c +++ b/src/calcelestial.c @@ -119,6 +119,7 @@ int main(int argc, char *argv[]) { int tz = INT_MAX; // char *format = "time: %Y-%m-%d %H:%M:%S az: §a (§s) alt: §h"; char *format = "%H:%M"; + char *obj_str = basename(argv[0]); char *query = NULL; bool error = false; bool utc = false; @@ -134,9 +135,6 @@ int main(int argc, char *argv[]) { struct ln_lnlat_posn obs = { DBL_MAX, DBL_MAX }; struct object_details result; - /* parse planet/obj */ - obj = object_from_name(basename(argv[0])); - /* parse command line arguments */ while (1) { int c = getopt_long(argc, argv, "+hvnut:d:f:a:o:q:z:p:m:H:", long_options, NULL); @@ -210,7 +208,7 @@ int main(int argc, char *argv[]) { #endif case 'p': - obj = object_from_name(optarg); + obj_str = optarg; break; case 'z': @@ -236,12 +234,11 @@ int main(int argc, char *argv[]) { error = true; } } - - /* validate obj */ - if (obj == OBJECT_INVALID) { - fprintf(stderr, "invalid object, use --object\n"); - error = true; - } + + /* Parse planet/obj */ + obj = object_lookup(obj_str); + if (!obj) + usage_error("invalid or missing object, use --object"); #ifdef GEONAMES_SUPPORT /* lookup place at http://geonames.org */ diff --git a/src/objects.c b/src/objects.c index 845b5a4..18db378 100644 --- a/src/objects.c +++ b/src/objects.c @@ -27,133 +27,53 @@ #include "objects.h" -const char* objects[] = { - NULL, /* invalid */ - "sun", - "moon", - "mars", - "neptune", - "jupiter", - "mercury", - "uranus", - "saturn", - "venus", - "pluto" +static struct object { + const char *name; + int (*rst)(double JD, struct ln_lnlat_posn *observer, struct ln_rst_time *rst); + void (*equ_coords)(double JD, struct ln_equ_posn *position); + double (*earth_dist)(double JD); + double (*sdiam)(double JD); +} objects[] = { + { "sun", 0 /* special case */, ln_get_solar_equ_coords, ln_get_earth_solar_dist, ln_get_solar_sdiam }, + { "moon", ln_get_lunar_rst, ln_get_lunar_equ_coords, ln_get_lunar_earth_dist, ln_get_lunar_sdiam }, + { "mars", ln_get_mars_rst, ln_get_mars_equ_coords, ln_get_mars_earth_dist, ln_get_mars_sdiam }, + { "neptune", ln_get_neptune_rst, ln_get_neptune_equ_coords, ln_get_neptune_earth_dist, ln_get_neptune_sdiam }, + { "jupiter", ln_get_jupiter_rst, ln_get_jupiter_equ_coords, ln_get_jupiter_earth_dist, ln_get_jupiter_equ_sdiam }, + { "mercury", ln_get_mercury_rst, ln_get_mercury_equ_coords, ln_get_mercury_earth_dist, ln_get_mercury_sdiam }, + { "uranus", ln_get_uranus_rst, ln_get_uranus_equ_coords, ln_get_uranus_earth_dist, ln_get_uranus_sdiam }, + { "saturn", ln_get_saturn_rst, ln_get_saturn_equ_coords, ln_get_saturn_earth_dist, ln_get_saturn_equ_sdiam }, + { "venus", ln_get_venus_rst, ln_get_venus_equ_coords, ln_get_venus_earth_dist, ln_get_venus_sdiam }, + { "pluto", ln_get_pluto_rst, ln_get_pluto_equ_coords, ln_get_pluto_earth_dist, ln_get_pluto_sdiam } }; -void object_pos(enum object obj, double jd, struct object_details *details) { - switch (obj) { - case OBJECT_SUN: return object_pos_sun(jd, details); - case OBJECT_MOON: return object_pos_moon(jd, details); - case OBJECT_MARS: return object_pos_mars(jd, details); - case OBJECT_NEPTUNE: return object_pos_neptune(jd, details); - case OBJECT_JUPITER: return object_pos_jupiter(jd, details); - case OBJECT_MERCURY: return object_pos_mercury(jd, details); - case OBJECT_URANUS: return object_pos_uranus(jd, details); - case OBJECT_SATURN: return object_pos_saturn(jd, details); - case OBJECT_VENUS: return object_pos_venus(jd, details); - case OBJECT_PLUTO: return object_pos_pluto(jd, details); - default: ; - } -} - -int object_rst(enum object obj, double jd, double horizon, struct ln_lnlat_posn *obs, struct ln_rst_time *rst) { - switch (obj) { - case OBJECT_SUN: return ln_get_solar_rst_horizon(jd, obs, horizon, rst); - case OBJECT_MOON: return ln_get_lunar_rst(jd, obs, rst); - case OBJECT_MARS: return ln_get_mars_rst(jd, obs, rst); - case OBJECT_NEPTUNE: return ln_get_neptune_rst(jd, obs, rst); - case OBJECT_JUPITER: return ln_get_jupiter_rst(jd, obs, rst); - case OBJECT_MERCURY: return ln_get_mercury_rst(jd, obs, rst); - case OBJECT_URANUS: return ln_get_uranus_rst(jd, obs, rst); - case OBJECT_SATURN: return ln_get_saturn_rst(jd, obs, rst); - case OBJECT_VENUS: return ln_get_venus_rst(jd, obs, rst); - case OBJECT_PLUTO: return ln_get_pluto_rst(jd, obs, rst); - default: return -1; - } -} - -enum object object_from_name(const char *name) { +const struct object * object_lookup(const char *name) +{ int c; - for (c = 1; c <= OBJECTS; c++) { - if (strcmp(objects[c], name) == 0) { - return (enum object) c; - } + for (c = 0; c <= sizeof(objects) / sizeof(objects[0]); c++) { + if (strcmp(objects[c].name, name) == 0) + return &objects[c]; } - return OBJECT_INVALID; + return NULL; } -const char * object_to_name(enum object obj) { - return objects[obj]; +const char * object_name(const struct object *o) +{ + return o->name; } -void object_pos_sun(double jd, struct object_details *details) { - ln_get_solar_equ_coords(jd, &details->equ); +void object_pos(const struct object *o, double jd, struct object_details *details) +{ + o->equ_coords(jd, &details->equ); - details->distance = ln_get_earth_solar_dist(jd); - details->diameter = ln_get_solar_sdiam(jd); + details->distance = o->earth_dist(jd); + details->diameter = o->sdiam(jd); } -void object_pos_moon(double jd, struct object_details *details) { - ln_get_lunar_equ_coords(jd, &details->equ); - - details->distance = ln_get_lunar_earth_dist(jd) / AU_METERS; - details->diameter = ln_get_lunar_sdiam(jd); -} - -void object_pos_mars(double jd, struct object_details *details) { - ln_get_mars_equ_coords(jd, &details->equ); - - details->distance = ln_get_mars_earth_dist(jd); - details->diameter = ln_get_mars_sdiam(jd); -} - -void object_pos_neptune(double jd, struct object_details *details) { - ln_get_neptune_equ_coords(jd, &details->equ); - - details->distance = ln_get_neptune_earth_dist(jd); - details->diameter = ln_get_neptune_sdiam(jd); -} - -void object_pos_jupiter(double jd, struct object_details *details) { - ln_get_jupiter_equ_coords(jd, &details->equ); - - details->distance = ln_get_jupiter_earth_dist(jd); - details->diameter = ln_get_jupiter_equ_sdiam(jd); -} - -void object_pos_mercury(double jd, struct object_details *details) { - ln_get_mercury_equ_coords(jd, &details->equ); - - details->distance = ln_get_mercury_earth_dist(jd); - details->diameter = ln_get_mercury_sdiam(jd); -} - -void object_pos_uranus(double jd, struct object_details *details) { - ln_get_uranus_equ_coords(jd, &details->equ); - - details->distance = ln_get_uranus_earth_dist(jd); - details->diameter = ln_get_uranus_sdiam(jd); -} - -void object_pos_saturn(double jd, struct object_details *details) { - ln_get_saturn_equ_coords(jd, &details->equ); - - details->distance = ln_get_saturn_earth_dist(jd); - details->diameter = ln_get_saturn_equ_sdiam(jd); -} - -void object_pos_venus(double jd, struct object_details *details) { - ln_get_venus_equ_coords(jd, &details->equ); - - details->distance = ln_get_venus_earth_dist(jd); - details->diameter = ln_get_venus_sdiam(jd); -} - -void object_pos_pluto(double jd, struct object_details *details) { - ln_get_pluto_equ_coords(jd, &details->equ); - - details->distance = ln_get_pluto_earth_dist(jd); - details->diameter = ln_get_pluto_sdiam(jd); -} +int object_rst(const struct object *o, double jd, double horizon, struct ln_lnlat_posn *obs, struct ln_rst_time *rst) +{ + if (o->sdiam == ln_get_solar_sdiam) + return ln_get_solar_rst_horizon(jd, obs, horizon, rst); /* special case */ + else + return o->rst(jd, obs, rst); +} \ No newline at end of file diff --git a/src/objects.h b/src/objects.h index 832b06b..a593a1c 100644 --- a/src/objects.h +++ b/src/objects.h @@ -30,22 +30,7 @@ #include -#define AU_METERS 149597870.7 -#define OBJECTS 10 - -enum object { - OBJECT_INVALID, - OBJECT_SUN, - OBJECT_MOON, - OBJECT_MARS, - OBJECT_NEPTUNE, - OBJECT_JUPITER, - OBJECT_MERCURY, - OBJECT_URANUS, - OBJECT_SATURN, - OBJECT_VENUS, - OBJECT_PLUTO -}; +struct object; struct object_details { double jd; /* julian date of observation */ @@ -62,21 +47,10 @@ struct object_details { const char *azidir; /* direction of azimuth - like N,S,W,E,NSW,.. */ }; -enum object object_from_name(const char *name); -const char * object_to_name(enum object obj); +const struct object * object_lookup(const char *name); +const char * object_name(const struct object *o); -void object_pos(enum object obj, double jd, struct object_details *details); -int object_rst(enum object obj, double jd, double horizon, struct ln_lnlat_posn *obs, struct ln_rst_time *rst); - -void object_pos_sun(double jd, struct object_details *details); -void object_pos_moon(double jd, struct object_details *details); -void object_pos_mars(double jd, struct object_details *details); -void object_pos_neptune(double jd, struct object_details *details); -void object_pos_jupiter(double jd, struct object_details *details); -void object_pos_mercury(double jd, struct object_details *details); -void object_pos_uranus(double jd, struct object_details *details); -void object_pos_saturn(double jd, struct object_details *details); -void object_pos_venus(double jd, struct object_details *details); -void object_pos_pluto(double jd, struct object_details *details); +void object_pos(const struct object *o, double jd, struct object_details *details); +int object_rst(const struct object *o, double jd, double horizon, struct ln_lnlat_posn *obs, struct ln_rst_time *rst); #endif /* _OBJECTS_H_ */