added first draft of formatter

This commit is contained in:
Steffen Vogel 2013-02-15 22:46:44 +01:00
parent aad0b9104b
commit 98e1df869d
9 changed files with 194 additions and 105 deletions

View file

@ -1,6 +1,6 @@
bin_PROGRAMS = calcelestial
calcelestial_SOURCES = calcelestial.c objects.c helpers.c
calcelestial_SOURCES = calcelestial.c objects.c helpers.c formatter.c
calcelestial_LDADD = -lm -lnova
if GEONAMES_SUPPORT

View file

@ -66,10 +66,10 @@ CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(bindir)"
PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
am__calcelestial_SOURCES_DIST = calcelestial.c objects.c helpers.c \
geonames.c
formatter.c geonames.c
@GEONAMES_SUPPORT_TRUE@am__objects_1 = geonames.$(OBJEXT)
am_calcelestial_OBJECTS = calcelestial.$(OBJEXT) objects.$(OBJEXT) \
helpers.$(OBJEXT) $(am__objects_1)
helpers.$(OBJEXT) formatter.$(OBJEXT) $(am__objects_1)
calcelestial_OBJECTS = $(am_calcelestial_OBJECTS)
am__DEPENDENCIES_1 =
@GEONAMES_SUPPORT_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
@ -187,7 +187,7 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
calcelestial_SOURCES = calcelestial.c objects.c helpers.c \
calcelestial_SOURCES = calcelestial.c objects.c helpers.c formatter.c \
$(am__append_1)
calcelestial_LDADD = -lm -lnova $(am__append_2)
@GEONAMES_SUPPORT_TRUE@geonames_SOURCES = geonames_main.c geonames.c
@ -284,6 +284,7 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/calcelestial.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/formatter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geonames.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geonames_main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helpers.Po@am__quote@

View file

@ -43,12 +43,13 @@
#include "../config.h"
#include "objects.h"
#include "helpers.h"
#include "formatter.h"
enum mode {
MODE_NOW,
MODE_RISE,
MODE_SET,
MODE_TRANSIT
enum moment {
MOMENT_NOW,
MOMENT_RISE,
MOMENT_SET,
MOMENT_TRANSIT
};
extern long timezone;
@ -70,9 +71,9 @@ static struct option long_options[] = {
{0}
};
static char *long_options_descs[] = {
"calculate for given object/planet",
"calculate rise/set with given twilight (nautic|civil|astronomical)",
static const char *long_options_descs[] = {
"calculate for given object/planet (sun, moon, uranus, ...)",
"calculate rise/set with given twilight (nautic, civil, astronomical)",
"calculate with given time (eg. 2011-12-25)",
"use rise/set/transit time for position calculation",
"output format (see strftime (3))",
@ -86,7 +87,7 @@ static char *long_options_descs[] = {
"show version"
};
void version () {
void version() {
printf("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION);
printf("libnova %s\n", LIBNOVA_VERSION);
}
@ -96,7 +97,7 @@ void usage() {
printf("Options:\n");
struct option *op = long_options;
char **desc = long_options_descs;
const char **desc = long_options_descs;
while (op->name && desc) {
printf(" -%c, --%s%s%s\n", op->val, op->name, (strlen(op->name) <= 7) ? "\t\t" : "\t", *desc);
op++;
@ -110,17 +111,18 @@ void usage() {
int main(int argc, char *argv[]) {
/* default options */
double horizon = LN_SOLAR_STANDART_HORIZON; /* 50 Bogenminuten; no twilight, normal sunset/rise */
char *format = "%H:%M:%S";
char *format = "%Y-%m-%d %H:%M:%S";
char *query = NULL;
bool error = false;
enum mode mode = MODE_NOW;
enum object obj = OBJECT_INVALID;
bool verbose = false;
double jd;
struct tm date = { 0 };
struct ln_rst_time rst;
enum moment moment = MOMENT_NOW;
enum object obj = OBJECT_INVALID;
struct ln_lnlat_posn obs = { DBL_MAX, DBL_MAX };
struct object_details result;
tzset();
@ -132,8 +134,7 @@ int main(int argc, char *argv[]) {
/* parse command line arguments */
while (1) {
int optidx;
int c = getopt_long(argc, argv, "+hvt:d:f:a:o:q:z:p:", long_options, &optidx);
int c = getopt_long(argc, argv, "+hvt:d:f:a:o:q:z:p:m:H:", long_options, NULL);
/* detect the end of the options. */
if (c == -1) break;
@ -150,34 +151,35 @@ int main(int argc, char *argv[]) {
horizon = LN_SOLAR_ASTRONOMICAL_HORIZON;
}
else {
fprintf(stderr, "invalid twilight: %s\n", optarg);
error = true;
char *endptr;
horizon = strtod(optarg, &endptr);
if (endptr == optarg) {
fprintf(stderr, "invalid twilight: %s\n", optarg);
error = true;
}
}
break;
case 't':
if (strptime(optarg, "%Y-%m-%d", &date) == NULL) {
fprintf(stderr, "invalid date: %s\n", optarg);
error = true;
}
else {
time_t t = mktime(&date);
jd = ln_get_julian_from_timet(&t);
#ifdef DEBUG
char date_str[64];
strftime(date_str, 64, "%Y-%m-%d", &date);
printf("parsed date: %s\n", date_str);
#endif
{
struct tm date;
if (strptime(optarg, "%Y-%m-%d %H:%M:%S", &date) == NULL) {
fprintf(stderr, "invalid date: %s\n", optarg);
error = true;
}
else {
time_t t = mktime(&date);
jd = ln_get_julian_from_timet(&t);
}
}
break;
case 'm':
if (strcmp(optarg, "now") == 0) mode = MODE_NOW;
else if (strcmp(optarg, "rise") == 0) mode = MODE_RISE;
else if (strcmp(optarg, "set") == 0) mode = MODE_SET;
else if (strcmp(optarg, "transit") == 0) mode = MODE_TRANSIT;
if (strcmp(optarg, "now") == 0) moment = MOMENT_NOW;
else if (strcmp(optarg, "rise") == 0) moment = MOMENT_RISE;
else if (strcmp(optarg, "set") == 0) moment = MOMENT_SET;
else if (strcmp(optarg, "transit") == 0) moment = MOMENT_TRANSIT;
else {
fprintf(stderr, "invalid moment: %s\n", optarg);
error = true;
@ -256,7 +258,6 @@ int main(int argc, char *argv[]) {
}
#ifdef DEBUG
{
char date_str[64];
time_t t;
ln_get_timet_from_julian(jd, &t);
@ -268,56 +269,25 @@ int main(int argc, char *argv[]) {
printf("for object: %d\n", obj);
printf("with horizon: %f\n", horizon);
printf("with timezone: UTC +%dh\n", timezone / -3600);
}
#endif
if (object_rst(obj, jd, horizon, &obs, &rst) == 1) {
fprintf(stderr, "object is circumpolar\n");
return EXIT_CIRCUMPOLAR;
}
switch (mode) {
case MODE_NOW: jd = jd; break; /* use given (current) date */
case MODE_RISE: jd = rst.rise; break;
case MODE_SET: jd = rst.set; break;
case MODE_TRANSIT: jd = rst.transit; break;
}
// calculate position
struct object_details result;
object_pos(obj, jd, &obs, &result);
struct ln_hms ra;
ln_deg_to_hms(result.equ.ra, &ra);
double az = result.hrz.az + 180;
az -= (int) (az / 360) * 360;
char date_str[64];
printf("diam = %f\n", result.diameter);
printf("dist = %f au\n", result.distance);
printf("dist = %f km\n", AU_METERS * result.distance);
printf("az = %s\n", ln_get_humanr_location(az));
printf("alt = %s\n", ln_get_humanr_location(result.hrz.alt));
printf("ra = %dh%dm%fs\n", ra.hours, ra.minutes, ra.seconds);
printf("dec = %s\n", ln_get_humanr_location(result.equ.dec));
printf("rise = %s\n", strfjd(date_str, sizeof(date_str), "%H:%M:%S", rst.rise));
printf("set = %s\n", strfjd(date_str, sizeof(date_str), "%H:%M:%S", rst.set));
printf("transit = %s\n", strfjd(date_str, sizeof(date_str), "%H:%M:%S", rst.transit));
printf("daytime = %s\n", strfjddur(date_str, sizeof(date_str), "%H:%M:%S", rst.set - rst.rise));
printf("nighttime = %s\n", strfjddur(date_str, sizeof(date_str), "%H:%M:%S", rst.rise - rst.set));
/*if (strstr(format, "%R") != NULL) {
snprintf(timestamp_str, sizeof(timestamp_str), "%lu", seconds);
format = strreplace(format, "%s", timestamp_str);
if (object_rst(obj, jd, horizon, &obs, &result.rst) == 1) {
if (moment != MOMENT_NOW) {
fprintf(stderr, "object is circumpolar\n");
return EXIT_CIRCUMPOLAR;
}
if (strstr(format, "%E") != NULL) {
snprintf(timestamp_str, sizeof(timestamp_str), "%lu", seconds);
format = strreplace(format, "%s", timestamp_str);
}*/
}
else switch (moment) {
case MOMENT_NOW: result.jd = jd; break;
case MOMENT_RISE: result.jd = result.rst.rise; break;
case MOMENT_SET: result.jd = result.rst.set; break;
case MOMENT_TRANSIT: result.jd = result.rst.transit; break;
}
result.obs = obs;
object_pos(obj, result.jd, &obs, &result);
format_result(format, &result);
return EXIT_SUCCESS;
}

79
src/formatter.c Normal file
View file

@ -0,0 +1,79 @@
/**
* Formatter
*
* @copyright 2012 Steffen Vogel
* @license http://www.gnu.org/licenses/gpl.txt GNU Public License
* @author Steffen Vogel <post@steffenvogel.de>
* @link http://www.steffenvogel.de/2012/03/14/cron-jobs-fur-sonnenauf-untergang/
*/
/*
* This file is part of calcelestial
*
* calcelestial 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
* any later version.
*
* calcelestial 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 result.
*
* You should have received a copy of the GNU General Public License
* along with calcelestial. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "objects.h"
#include "helpers.h"
#include "formatter.h"
void format_result(const char *format, struct object_details *result) {
char buffer[128];
char *local_format = strdup(format);
int i;
struct ln_hms ra;
/* convert results */
ln_deg_to_hms(result->equ.ra, &ra);
ln_get_hrz_from_equ(&result->equ, &result->obs, result->jd, &result->hrz);
result->azidir = ln_hrz_to_nswe(&result->hrz);
result->hrz.az = ln_range_degrees(result->hrz.az + 180);
struct specifiers specifiers[] = {
{"%J", &result->jd, DOUBLE},
{"§r", &result->equ.ra, DOUBLE},
{"§d", &result->equ.dec, DOUBLE},
{"§a", &result->hrz.az, DOUBLE},
{"§h", &result->hrz.alt, DOUBLE},
{"§d", &result->diameter, DOUBLE},
{"§e", &result->distance, DOUBLE},
{"§t", &result->tz, INTEGER},
{"§A", &result->obs.lat, DOUBLE},
{"§O", &result->obs.lng, DOUBLE},
{"§s", (void *) result->azidir, STRING},
{"§§", "§", STRING},
{0}
};
for (i = 0; specifiers[i].token; i++) {
if (strstr(local_format, specifiers[i].token) != NULL) {
switch (specifiers[i].format) {
case DOUBLE: snprintf(buffer, sizeof(buffer), "%." PRECISION "f", * (double *) specifiers[i].data); break;
case STRING: snprintf(buffer, sizeof(buffer), "%s", (char *) specifiers[i].data); break;
case INTEGER: snprintf(buffer, sizeof(buffer), "%d", * (int *) specifiers[i].data); break;
}
local_format = strreplace(local_format, specifiers[i].token, buffer);
}
}
strfjd(buffer, sizeof(buffer), local_format, result->jd);
printf("%s\n", buffer);
free(local_format);
}

43
src/formatter.h Normal file
View file

@ -0,0 +1,43 @@
/**
* Formatter
*
* @copyright 2012 Steffen Vogel
* @license http://www.gnu.org/licenses/gpl.txt GNU Public License
* @author Steffen Vogel <post@steffenvogel.de>
* @link http://www.steffenvogel.de/2012/03/14/cron-jobs-fur-sonnenauf-untergang/
*/
/*
* This file is part of calcelestial
*
* calcelestial 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
* any later version.
*
* calcelestial 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 calcelestial. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _FORMATTER_H_
#define _FORMATTER_H_
#include <libnova/libnova.h>
#define PRECISION "3"
enum specifier_fmt { DOUBLE, STRING, INTEGER };
struct specifiers {
const char *token;
void *data;
enum specifier_fmt format;
};
void format_result(const char *format, struct object_details *result);
#endif /* _FORMATTER_H_ */

View file

@ -81,7 +81,7 @@ char * strfjd(char *s, size_t max, const char *format, double jd) {
return s;
}
char * strreplace(char *subject, char *search, char *replace) {
char * strreplace(char *subject, const char *search, const char *replace) {
int new_len = strlen(subject);
int search_len = strlen(search);
int replace_len = strlen(replace);

View file

@ -28,6 +28,6 @@
char * strfjddur(char *s, size_t max, const char *format, double jd);
char * strfjd(char *s, size_t max, const char *format, double jd);
char * strreplace(char *subject, char *search, char *replace);
char * strreplace(char *subject, const char *search, const char *replace);
#endif /* _HELPERS_H_ */

View file

@ -75,7 +75,6 @@ enum object object_from_name(const char *name, bool casesen) {
void object_pos_sun(double jd, struct ln_lnlat_posn *obs, struct object_details *details) {
ln_get_solar_equ_coords(jd, &details->equ);
ln_get_hrz_from_equ(&details->equ, obs, jd, &details->hrz);
details->distance = ln_get_earth_solar_dist(jd);
details->diameter = ln_get_solar_sdiam(jd);
@ -83,7 +82,6 @@ void object_pos_sun(double jd, struct ln_lnlat_posn *obs, struct object_details
void object_pos_moon(double jd, struct ln_lnlat_posn *obs, struct object_details *details) {
ln_get_lunar_equ_coords(jd, &details->equ);
ln_get_hrz_from_equ(&details->equ, obs, jd, &details->hrz);
details->distance = ln_get_lunar_earth_dist(jd) / AU_METERS;
details->diameter = ln_get_lunar_sdiam(jd);
@ -91,7 +89,6 @@ void object_pos_moon(double jd, struct ln_lnlat_posn *obs, struct object_details
void object_pos_mars(double jd, struct ln_lnlat_posn *obs, struct object_details *details) {
ln_get_mars_equ_coords(jd, &details->equ);
ln_get_hrz_from_equ(&details->equ, obs, jd, &details->hrz);
details->distance = ln_get_mars_earth_dist(jd);
details->diameter = ln_get_mars_sdiam(jd);
@ -99,7 +96,6 @@ void object_pos_mars(double jd, struct ln_lnlat_posn *obs, struct object_details
void object_pos_neptune(double jd, struct ln_lnlat_posn *obs, struct object_details *details) {
ln_get_neptune_equ_coords(jd, &details->equ);
ln_get_hrz_from_equ(&details->equ, obs, jd, &details->hrz);
details->distance = ln_get_neptune_earth_dist(jd);
details->diameter = ln_get_neptune_sdiam(jd);
@ -107,7 +103,6 @@ void object_pos_neptune(double jd, struct ln_lnlat_posn *obs, struct object_deta
void object_pos_jupiter(double jd, struct ln_lnlat_posn *obs, struct object_details *details) {
ln_get_jupiter_equ_coords(jd, &details->equ);
ln_get_hrz_from_equ(&details->equ, obs, jd, &details->hrz);
details->distance = ln_get_jupiter_earth_dist(jd);
details->diameter = ln_get_jupiter_equ_sdiam(jd);
@ -115,7 +110,6 @@ void object_pos_jupiter(double jd, struct ln_lnlat_posn *obs, struct object_deta
void object_pos_mercury(double jd, struct ln_lnlat_posn *obs, struct object_details *details) {
ln_get_mercury_equ_coords(jd, &details->equ);
ln_get_hrz_from_equ(&details->equ, obs, jd, &details->hrz);
details->distance = ln_get_mercury_earth_dist(jd);
details->diameter = ln_get_mercury_sdiam(jd);
@ -123,7 +117,6 @@ void object_pos_mercury(double jd, struct ln_lnlat_posn *obs, struct object_deta
void object_pos_uranus(double jd, struct ln_lnlat_posn *obs, struct object_details *details) {
ln_get_uranus_equ_coords(jd, &details->equ);
ln_get_hrz_from_equ(&details->equ, obs, jd, &details->hrz);
details->distance = ln_get_uranus_earth_dist(jd);
details->diameter = ln_get_uranus_sdiam(jd);
@ -131,7 +124,6 @@ void object_pos_uranus(double jd, struct ln_lnlat_posn *obs, struct object_detai
void object_pos_saturn(double jd, struct ln_lnlat_posn *obs, struct object_details *details) {
ln_get_saturn_equ_coords(jd, &details->equ);
ln_get_hrz_from_equ(&details->equ, obs, jd, &details->hrz);
details->distance = ln_get_saturn_earth_dist(jd);
details->diameter = ln_get_saturn_equ_sdiam(jd);
@ -139,7 +131,6 @@ void object_pos_saturn(double jd, struct ln_lnlat_posn *obs, struct object_detai
void object_pos_venus(double jd, struct ln_lnlat_posn *obs, struct object_details *details) {
ln_get_venus_equ_coords(jd, &details->equ);
ln_get_hrz_from_equ(&details->equ, obs, jd, &details->hrz);
details->distance = ln_get_venus_earth_dist(jd);
details->diameter = ln_get_venus_sdiam(jd);
@ -147,7 +138,6 @@ void object_pos_venus(double jd, struct ln_lnlat_posn *obs, struct object_detail
void object_pos_pluto(double jd, struct ln_lnlat_posn *obs, struct object_details *details) {
ln_get_pluto_equ_coords(jd, &details->equ);
ln_get_hrz_from_equ(&details->equ, obs, jd, &details->hrz);
details->distance = ln_get_pluto_earth_dist(jd);
details->diameter = ln_get_pluto_sdiam(jd);

View file

@ -47,12 +47,18 @@ enum object {
};
struct object_details {
struct ln_rst_time rst; /* rise/set/transit time in JD */
double jd; /* julian date of observation */
double tz; /* timezone of observer */
double diameter; /* in arc seconds */
double distance; /* in AU */
struct ln_lnlat_posn obs; /* observer */
struct ln_rst_time rst; /* rise/set/transit time in JD */
struct ln_equ_posn equ;
struct ln_hrz_posn hrz;
double diameter; /* in arc seconds */
double distance; /* in AU */
const char *azidir; /* direction of azimuth - like N,S,W,E,NSW,.. */
};
enum object object_from_name(const char *name, bool casesen);