From 151d8340a748a4dac7752ebcd38983b2887f5f0c Mon Sep 17 00:00:00 2001 From: Dan Risacher Date: Fri, 16 Sep 2022 12:59:34 -0400 Subject: [PATCH] Switch to C++ to C. Thanks Michael Stilkerich; I never liked C++ anyway. --- SunwaitPi.vcxproj | 8 +- makefile | 14 +- openwrt/Makefile | 10 +- print.cpp => print.c | 92 ++++------ print.h | 6 +- sunriset.cpp => sunriset.c | 32 ++-- sunwait.cpp => sunwait.c | 332 +++++++++++++------------------------ sunwait.h | 9 +- 8 files changed, 186 insertions(+), 317 deletions(-) rename print.cpp => print.c (82%) rename sunriset.cpp => sunriset.c (95%) rename sunwait.cpp => sunwait.c (80%) diff --git a/SunwaitPi.vcxproj b/SunwaitPi.vcxproj index 2ee444c..96c1d2b 100644 --- a/SunwaitPi.vcxproj +++ b/SunwaitPi.vcxproj @@ -74,9 +74,9 @@ - - - + + + @@ -94,4 +94,4 @@ - \ No newline at end of file + diff --git a/makefile b/makefile index 40a32f0..80f656e 100755 --- a/makefile +++ b/makefile @@ -3,19 +3,23 @@ # 08/12/2014 IFC 0.6 No changes since 0.5 # 02/05/2015 IFC 0.7 No changes since 0.5, still # 10/03/2020 TLJ 0.9 Move headers to fix build on osx +# 2022-09-16 DRR 0.91 Accept changes from @mstilkerich Michael Stilkerich switches to C from C++ # - +CFLAGS=-c -Wall -std=c99 -O2 -Wextra -pedantic CXXFLAGS=-c -Wall LDFLAGS= -lm -SOURCES=sunwait.cpp sunriset.cpp print.cpp +SOURCES=sunwait.c sunriset.c print.c HEADERS=sunwait.h sunriset.h print.h -OBJECTS=$(SOURCES:.cpp=.o) +OBJECTS=$(SOURCES:.c=.o) EXECUTABLE=sunwait -all: $(SOURCES) $(EXECUTABLE) +all: $(EXECUTABLE) + +.c.o: + $(CC) $(CFLAGS) $< -o $@ $(EXECUTABLE): $(OBJECTS) - $(CXX) $(OBJECTS) -o $@ $(LDFLAGS) + $(CC) $(OBJECTS) -o $@ $(LDFLAGS) clean: rm -f *.o sunwait diff --git a/openwrt/Makefile b/openwrt/Makefile index e132ba1..a49905b 100644 --- a/openwrt/Makefile +++ b/openwrt/Makefile @@ -17,7 +17,7 @@ define Package/sunwait CATEGORY:=Utilities TITLE:=Sunwait URL:=URL:=https://github.com/risacher/sunwait - DEPENDS:=+libstdcpp +libc + DEPENDS:=+libc endef define Package/sunwait/description @@ -25,10 +25,10 @@ define Package/sunwait/description endef define Build/Compile - $(TARGET_CC) $(TARGET_CPPFLAGS) -o $(PKG_BUILD_DIR)/sunwait.o -c $(PKG_BUILD_DIR)/sunwait.cpp - $(TARGET_CC) $(TARGET_CPPFLAGS) -o $(PKG_BUILD_DIR)/sunriset.o -c $(PKG_BUILD_DIR)/sunriset.cpp - $(TARGET_CC) $(TARGET_CPPFLAGS) -o $(PKG_BUILD_DIR)/print.o -c $(PKG_BUILD_DIR)/print.cpp - $(TARGET_CC) $(TARGET_LDFLAGS) -o $(PKG_BUILD_DIR)/$1 $(PKG_BUILD_DIR)/sunwait.o $(PKG_BUILD_DIR)/sunriset.o $(PKG_BUILD_DIR)/print.o -lm -lstdc++ + $(TARGET_CC) $(TARGET_CPPFLAGS) -o $(PKG_BUILD_DIR)/sunwait.o -c $(PKG_BUILD_DIR)/sunwait.c + $(TARGET_CC) $(TARGET_CPPFLAGS) -o $(PKG_BUILD_DIR)/sunriset.o -c $(PKG_BUILD_DIR)/sunriset.c + $(TARGET_CC) $(TARGET_CPPFLAGS) -o $(PKG_BUILD_DIR)/print.o -c $(PKG_BUILD_DIR)/print.c + $(TARGET_CC) $(TARGET_LDFLAGS) -o $(PKG_BUILD_DIR)/$1 $(PKG_BUILD_DIR)/sunwait.o $(PKG_BUILD_DIR)/sunriset.o $(PKG_BUILD_DIR)/print.o -lm endef define Package/sunwait/install diff --git a/print.cpp b/print.c similarity index 82% rename from print.cpp rename to print.c index ee1d88d..ffb9c49 100755 --- a/print.cpp +++ b/print.c @@ -1,17 +1,17 @@ /* -** print.cpp (of sunwait) +** print.c (of sunwait) ** ** Who Ver When What ** IFC 0.5 04-12-2014 Fix my 1st release of sunwait for windows and port to linux ** IFC 0.6 08-12-2014 Add timezone for output of timings ** IFC 0.7 30-04-2015 Fix timexone and DST trouble - and problems near dateline ** IFC 0.8 2015-05-27 Resolve 'dodgy day' and cleanup +** DRR 0.91 2022-09-16 Accept change to C from mstilkerich Michael Stilkerich ** */ #include -#include #include #include @@ -24,17 +24,9 @@ static const char* cComma = ", "; #define NO_OFFSET 0.0 -inline double myDayLength (const double pDouble1, const double pDouble2) -{ return myAbs (pDouble1 - pDouble2); -} - -inline double myDayLength (const targetStruct *pTarget) -{ return pTarget->diurnalArc; -} - // The user-specified offset reduces the diurnal arc, at sunrise AND sunset. // But make sure dawn aways is before dusk. The offset can mess that up. -double diurnalArcWithOffset1 (const double pDiurnalArc, const double pOffset) +static double diurnalArcWithOffset1 (const double pDiurnalArc, const double pOffset) { double arcWithOffset = pDiurnalArc - pOffset - pOffset; if (arcWithOffset >= 24.0) return 24.0; if (arcWithOffset <= 0.0) return 0.0; @@ -46,7 +38,7 @@ double diurnalArcWithOffset (const runStruct *pRun, const targetStruct *pTarget) } // What time, in hours UTC, is the offset sunrise? -double getOffsetRiseHourUTC1 (const double pSouthHourUTC, const double pDiurnalArc, const double pOffsetHour) +static double getOffsetRiseHourUTC1 (const double pSouthHourUTC, const double pDiurnalArc, const double pOffsetHour) { return pSouthHourUTC - diurnalArcWithOffset1 (pDiurnalArc, pOffsetHour)/2.0; } // Simpler to use form @@ -55,7 +47,7 @@ double getOffsetRiseHourUTC (const runStruct *pRun, const targetStruct *pTarget) } // What time, in hours UTC, is the offset sunset? -double getOffsetSetHourUTC1 (const double pSouthHourUTC, const double pDiurnalArc, const double pOffsetHour) +static double getOffsetSetHourUTC1 (const double pSouthHourUTC, const double pDiurnalArc, const double pOffsetHour) { return pSouthHourUTC + diurnalArcWithOffset1 (pDiurnalArc, pOffsetHour)/2.0; } // Simpler to use form @@ -64,11 +56,11 @@ double getOffsetSetHourUTC (const runStruct *pRun, const targetStruct *pTarget) } -void print_a_time +static void print_a_time ( const OnOff pGmt_OnOff , const time_t *pMidnightTimet , const double pEventHour -) +) { struct tm tmpTm; char tmpBuffer [80]; @@ -89,12 +81,12 @@ void print_a_time printf ("%s", tmpBuffer); } -void print_a_sun_time +static void print_a_sun_time ( const OnOff pGmt_OnOff , const time_t *pMidnightTimet , const double pEventHour , const double pOffsetDiurnalArc -) +) { // A positive offset reduces the diurnal arc if (pOffsetDiurnalArc <= 0.0 || pOffsetDiurnalArc >= 24.0) printf ("--:--"); @@ -102,26 +94,22 @@ void print_a_sun_time print_a_time (pGmt_OnOff, pMidnightTimet, pEventHour); } -void print_times -( const OnOff pGmt -, const OnOff pSunrise -, const OnOff pSunset -, const time_t pMidnightTimet -, const double pSouthHour -, const double pDiurnalArc -, const double pOffset -, const char *pSeparator -) -{ double offsetDiurnalArc = diurnalArcWithOffset1 (pDiurnalArc, pOffset); - double riseHour = getOffsetRiseHourUTC1 (pSouthHour, pDiurnalArc, pOffset); - double setHour = getOffsetSetHourUTC1 (pSouthHour, pDiurnalArc, pOffset); +static void print_times +( const runStruct *pRun +, const targetStruct *pTarget +, const double pOffsetHour +, const char *pSeparator +) +{ double offsetDiurnalArc = diurnalArcWithOffset1 (pTarget->diurnalArc, pOffsetHour); + double riseHour = getOffsetRiseHourUTC1 (pTarget->southHourUTC, pTarget->diurnalArc, pOffsetHour); + double setHour = getOffsetSetHourUTC1 (pTarget->southHourUTC, pTarget->diurnalArc, pOffsetHour); - if (pSunrise == ONOFF_ON) - print_a_sun_time (pGmt, &pMidnightTimet, riseHour, offsetDiurnalArc); - if (pSunrise == ONOFF_ON && pSunset == ONOFF_ON) + if (pRun->reportSunrise == ONOFF_ON) + print_a_sun_time (pRun->utc, &pRun->targetTimet, riseHour, offsetDiurnalArc); + if (pRun->reportSunrise == ONOFF_ON && pRun->reportSunset == ONOFF_ON) printf ("%s", pSeparator); - if (pSunset == ONOFF_ON) - print_a_sun_time (pGmt, &pMidnightTimet, setHour, offsetDiurnalArc); + if (pRun->reportSunset == ONOFF_ON) + print_a_sun_time (pRun->utc, &pRun->targetTimet, setHour, offsetDiurnalArc); if (offsetDiurnalArc >= 24.0) printf (" (Midnight sun)"); else if (offsetDiurnalArc <= 0.0) printf (" (Polar night)"); @@ -129,24 +117,6 @@ void print_times printf ("\n"); } -inline void print_times -( const runStruct *pRun -, const targetStruct *pTarget -, const double pOffsetHour -, const char *pSeparator -) -{ print_times - ( pRun->utc - , pRun->reportSunrise - , pRun->reportSunset - , pRun->targetTimet - , pTarget->southHourUTC - , pTarget->diurnalArc - , pOffsetHour - , pSeparator - ); -} - inline void print_twilight ( const double pDayLength , const double pTwilightLength @@ -161,7 +131,7 @@ inline void print_twilight void generate_report (const runStruct *pRun) { /* - ** Generate and save sunrise and sunset times for target + ** Generate and save sunrise and sunset times for target */ targetStruct tmpTarget; @@ -173,7 +143,7 @@ void generate_report (const runStruct *pRun) double twilightAngleTarget = tmpTarget.twilightAngle; /* - ** Now generate the report + ** Now generate the report */ struct tm nowTm; @@ -190,19 +160,19 @@ void generate_report (const runStruct *pRun) } printf ("\n"); - + strftime (buffer, 80, "%d-%b-%Y %H:%M %Z", &nowTm); - printf + printf (" Current Date and Time: %s\n", buffer); printf ("\n\nTarget Information ...\n\n"); - printf + printf (" Location: %10.6fN, %10.6fE\n" , pRun->latitude , pRun->longitude ); - + strftime (buffer, 80, "%d-%b-%Y", &targetTm); printf (" Date: %s\n", buffer); @@ -231,14 +201,14 @@ void generate_report (const runStruct *pRun) else printf(" Twilight angle: %5.2f degrees (custom angle)\n", twilightAngleTarget); printf (" Day with twilight: "); print_times (pRun, &tmpTarget, NO_OFFSET, cTo); - + if (pRun->offsetHour != NO_OFFSET) { printf (" Day with twilight & offset: "); print_times (pRun, &tmpTarget, pRun->offsetHour, cTo); } printf (" It is: %s\n", isDay (pRun) == ONOFF_ON ? "Day (or twilight)" : "Night"); /* - ** Generate times for different types of twilight + ** Generate times for different types of twilight */ targetStruct daylightTarget; diff --git a/print.h b/print.h index 30f6a48..897b87c 100755 --- a/print.h +++ b/print.h @@ -4,6 +4,7 @@ // 08-12-2014 IFC 0.6 No changes from 0.5 // 02-05-2015 IFC 0.7 No changes from 0.5, still // 2015-05-27 IFC 0.8 Resolve 'dodgy day' and cleanup +// 2022-09-16 DRR 0.91 Convert to C courtesy mstilkerich // #ifndef PRINT_H @@ -12,15 +13,12 @@ #include "sunwait.h" #include "sunriset.h" -void generate_report (const runStruct *pRun); +void generate_report(const runStruct *pRun); void print_list (const runStruct *pRun); -double diurnalArcWithOffsetX (const double pDiurnalArc, const double pOffset); double diurnalArcWithOffset (const runStruct *pRun, const targetStruct *pTarget); -double getOffsetRiseHourUTCX (const double pSouthHourUTC, const double pDiurnalArc, const double pOffsetHour); double getOffsetRiseHourUTC (const runStruct *pRun, const targetStruct *pTarget); -double getOffsetSetHourUTCX (const double pSouthHourUTC, const double pDiurnalArc, const double pOffsetHour); double getOffsetSetHourUTC (const runStruct *pRun, const targetStruct *pTarget); diff --git a/sunriset.cpp b/sunriset.c similarity index 95% rename from sunriset.cpp rename to sunriset.c index f7f7974..e16c335 100755 --- a/sunriset.cpp +++ b/sunriset.c @@ -13,20 +13,18 @@ ** IFC 08-12-2014 0.6 Add timezone for output of timings ** IFC 29-04-2015 0.7 Fix for timezone (esp near date line) and more debug ** IFC 2015-05-27 0.8 Resolve 'dodgy day' and cleanup +** DRR 2022-09-16 0.91 Move to C courtesy mstilkerich ** */ #include -#include // Linux -#include + #include #include #include "sunwait.h" #include "sunriset.h" -using namespace std; - /************************************************************************/ /* Note: Eastern longitude positive, Western longitude negative */ /* Northern latitude positive, Southern latitude negative */ @@ -92,18 +90,18 @@ void sunriset (const runStruct *pRun, targetStruct *pTarget) /* compute the diurnal arc that the sun traverses to reach the specified altitide altit: */ double cost = (sind(altitude) - sind(pRun->latitude) * sind(sdec)) / (cosd(pRun->latitude) * cosd(sdec)); - if (abs(int(cost)) < 1.0) + if (cost > -1.0 && cost < 1.0) diurnalArc = 2*acosd(cost)/15.0; /* Diurnal arc, hours */ - else if (cost>=1.0) + else if (cost >= 1.0) diurnalArc = 0.0; // Polar Night else diurnalArc = 24.0; // Midnight Sun if (pRun->debug == ONOFF_ON) - { printf ("Debug: sunriset.cpp: Sun directly south: %f UTC, Diurnal Arc = %f hours\n", southHour, diurnalArc); - printf ("Debug: sunriset.cpp: Days since 2000: %li\n", pTarget->daysSince2000); - if (diurnalArc >= 24.0) printf ("Debug: sunriset.cpp: No rise or set: Midnight Sun\n"); - if (diurnalArc <= 0.0) printf ("Debug: sunriset.cpp: No rise or set: Polar Night\n"); + { printf ("Debug: %s: Sun directly south: %f UTC, Diurnal Arc = %f hours\n", __FILE__, southHour, diurnalArc); + printf ("Debug: %s: Days since 2000: %li\n", __FILE__, pTarget->daysSince2000); + if (diurnalArc >= 24.0) printf ("Debug: %s: No rise or set: Midnight Sun\n", __FILE__); + if (diurnalArc <= 0.0) printf ("Debug: %s: No rise or set: Polar Night\n", __FILE__); } // Error Check - just make sure odd things don't happen (causing trouble further on) @@ -150,22 +148,22 @@ void sun_RA_dec (const double d, double *RA, double *dec, double *r) double lon, obl_ecl; double xs, ys; double xe, ye, ze; - + /* Compute Sun's ecliptical coordinates */ sunpos (d, &lon, r); - + /* Compute ecliptic rectangular coordinates */ xs = *r * cosd(lon); ys = *r * sind(lon); /* Compute obliquity of ecliptic (inclination of Earth's axis) */ obl_ecl = 23.4393 - 3.563E-7 * d; - + /* Convert to equatorial rectangular coordinates - x is unchanged */ xe = xs; ye = ys * cosd(obl_ecl); ze = ys * sind(obl_ecl); - + /* Convert to spherical coordinates */ *RA = atan2d(ye, xe); *dec = atan2d(ze, sqrt(xe*xe + ye*ye)); @@ -203,7 +201,7 @@ double fixLatitude (const double x) else if (y <= (double) 270.0) y = (double) 180.0 - y; else if (y <= (double) 360.0) y = y - (double) 360.0; - // Linux compile of sunwait doesn't like 90, Windows is OK. + // Linux compile of sunwait doesn't like 90, Windows is OK. // Let's just wiggle things a little bit to make things OK. if (y == (double) 90.0) y = (double) 89.9999999; else if (y == (double) -90.0) y = (double) -89.9999999; @@ -260,11 +258,11 @@ unsigned long daysSince2000 (const time_t *pTimet) struct tm tmpTm; myUtcTime (pTimet, &tmpTm); - + unsigned int yearsSince2000 = tmpTm.tm_year - 100; // Get year, but tm_year starts from 1900 // Calucate number of leap days, but - - // yearsSince2000 - 1 + // yearsSince2000 - 1 // Don't include this year as tm_yday includes this year's leap day in the next bit unsigned int leapDaysSince2000 diff --git a/sunwait.cpp b/sunwait.c similarity index 80% rename from sunwait.cpp rename to sunwait.c index 1b20ff0..8cb9fb8 100755 --- a/sunwait.cpp +++ b/sunwait.c @@ -25,28 +25,40 @@ const double VERSION=0.91; // <<<<<<<<< CHANGE ME #include #include -#include +#include +#include #include -#include #include +#include // Windows #if defined _WIN32 || defined _WIN64 - #include -#endif +#include +static void sleepSeconds(unsigned int seconds) +{ + Sleep(1000u * seconds); +} // Linux -#if defined __linux__ || defined __APPLE__ - #include +#elif defined __linux__ || defined __APPLE__ || defined __unix__ +#include + +static void sleepSeconds(unsigned int seconds) +{ + while (seconds > 0u) { + seconds = sleep(seconds); + } +} +#else +// die with an error - otherwise, the compilation will appear to succeed, but +// the resulting program will not work correctly +#error "Unsupported platform" #endif #include "sunwait.h" #include "sunriset.h" #include "print.h" -using namespace std; - - /* ** Define global: ** 'runStruct' structure allows pretty much everything to be carted simply around functions. @@ -57,23 +69,22 @@ using namespace std; runStruct gRun; runStruct *pRun; -void print_version () +static void print_version () { - printf ("Sunwait for Windows. Version %f (IFC).\n", VERSION); - printf ("Code Contributors: P.Schlyter, D.Risacher, D.MacMillan and I.Craig.\n"); + printf ("Sunwait Version %f.\n", VERSION); + printf ("Code Contributors: P.Schlyter, D.Risacher, D.MacMillan, I.Craig, et al.\n"); printf ("\n"); printf (" Sunset is the instant at which the upper edge of the Sun disappears below the horizon.\n"); printf (" Civil twilight is the period from sunset until the geometric centre of the sun is 6° below the horizon.\n"); printf (" Nautical twilight is the period when the geometric centre of the sun is between 6° and 12° below the horizon.\n"); printf (" Astronomical twilight is the period when the geometric centre of the sun is between 12° and 18° below the horizon.\n"); printf (" Night is period when the geometric center of the sun falls 18° below the horizon.\n"); - } /* -** It's very useful to have this here +** It's very useful to have this here */ -void print_usage () +static void print_usage () { printf ("Calculate sunrise and sunset times for the current or targetted day.\n"); printf ("The times can be adjusted either for twilight or fixed durations.\n"); printf ("\n"); @@ -144,17 +155,17 @@ void print_usage () printf ("\n"); } -void myToLower (char *arg) +static void stringToLower (char *arg) { for (unsigned int i=0; i < strlen (arg); i++) arg[i] = tolower (arg[i]); } -void myToLower (const int argc, char *argv[]) +static void stringsToLower (const int argc, char *argv[]) { for (int i=1; i < argc; i++) - myToLower (argv [i]); + stringToLower (argv [i]); } -boolean myIsNumber (const char *arg) +static bool myIsNumber (const char *arg) { bool digitSet = false; for (int i=0; ; i++) { switch (arg[i]) @@ -178,7 +189,7 @@ boolean myIsNumber (const char *arg) return false; /* Shouldn't get here */ } -boolean myIsSignedNumber (const char *arg) +static bool myIsSignedNumber (const char *arg) { bool digitSet = false; for (int i=0; ; i++) { switch (arg[i]) @@ -202,7 +213,7 @@ boolean myIsSignedNumber (const char *arg) return false; /* Shouldn't get here */ } -boolean myIsSignedFloat (const char *arg) +static bool myIsSignedFloat (const char *arg) { bool digitSet = false; for (int i=0; ; i++) { switch (arg[i]) @@ -227,51 +238,7 @@ boolean myIsSignedFloat (const char *arg) return false; /* Shouldn't get here */ } -boolean myIsSignedFloat (const char *pArg, double *pDouble) -{ double number = 0; - int exponent = 0; - bool negative = false; - bool exponentSet = false; - for (int i=0; ; i++) - { switch (pArg[i]) - { - case '0': number = (number*10) + 0; exponentSet?exponent++:true; break; - case '1': number = (number*10) + 1; exponentSet?exponent++:true; break; - case '2': number = (number*10) + 2; exponentSet?exponent++:true; break; - case '3': number = (number*10) + 3; exponentSet?exponent++:true; break; - case '4': number = (number*10) + 4; exponentSet?exponent++:true; break; - case '5': number = (number*10) + 5; exponentSet?exponent++:true; break; - case '6': number = (number*10) + 6; exponentSet?exponent++:true; break; - case '7': number = (number*10) + 7; exponentSet?exponent++:true; break; - case '8': number = (number*10) + 8; exponentSet?exponent++:true; break; - case '9': number = (number*10) + 9; exponentSet?exponent++:true; break; - case '.': case ',': - exponentSet = true; - exponent = 0; // May be: N36.513679 (not right, but it'll do) - break; - case '+': - if (i>0) return false; // Sign only at start - negative = false; - break; - case '-': - if (i>0) return false; // Sign only at start - negative = true; - break; - case '\0': /* Exit */ - /* Place decimal point in number */ - if (exponentSet && exponent > 0) number = number / pow (10, (double) exponent); - if (negative) number = -number; - *pDouble = number; - return true; /* All done */ - break; - default: - return false; - } - } - return false; /* Shouldn't get to here */ -} - -boolean isBearing (runStruct *pRun, const char *pArg) +static bool isBearing (runStruct *pRun, const char *pArg) { double bearing = 0; int exponent = 0; bool negativeBearing = false; @@ -324,7 +291,7 @@ boolean isBearing (runStruct *pRun, const char *pArg) else if (compass == 'W') { bearing = 360 - bearing; compass = 'E'; } /* It's almost done, assign bearing to appropriate global */ - if (compass == 'N') pRun->latitude = fixLatitude (bearing); + if (compass == 'N') pRun->latitude = fixLatitude (bearing); else if (compass == 'E') pRun->longitude = fixLongitude (bearing); else return false; return true; /* All done */ @@ -336,7 +303,7 @@ boolean isBearing (runStruct *pRun, const char *pArg) return false; /* Shouldn't get to here */ } -boolean isOffset (runStruct *pRun, const char *pArg) +static bool isOffset (runStruct *pRun, const char *pArg) { int colon = 0, number0 = 0, number1 = 0, number2 = 0; bool negativeOffset = false; double returnOffset = 0.0; @@ -382,56 +349,43 @@ boolean isOffset (runStruct *pRun, const char *pArg) return false; /* Shouldn't get here */ } - /* -** time_t converted to struct tm. Using GMT (UTC) time. +** time_t converted to struct tm. Using GMT (UTC) time. */ void myUtcTime (const time_t *pTimet, struct tm *pTm) { - /* Windows code: Start */ - #if defined _WIN32 || defined _WIN64 - errno_t err; - err = _gmtime64_s (pTm, pTimet); - if (err) { printf ("Error: Invalid Argument to _gmtime64_s ().\n"); exit (EXIT_ERROR); } - #endif - /* Windows code: End */ - - /* Linux code: Start */ - #if defined __linux__ || defined __APPLE__ - gmtime_r (pTimet, pTm); - #endif - /* Linux code: End */ + struct tm *tms = gmtime(pTimet); + + if (tms != NULL) { + *pTm = *tms; + } else { + perror("could not convert time to UTC"); + exit(EXIT_ERROR); + } } /* -** time_t converted to struct tm. Using local time. +** time_t converted to struct tm. Using local time. */ void myLocalTime (const time_t *pTimet, struct tm *pTm) { - /* Windows code: Start */ - #if defined _WIN32 || defined _WIN64 - errno_t err; - err = _localtime64_s (pTm, pTimet); - if (err) { printf ("Error: Invalid Argument to _gmtime64_s ().\n"); exit (EXIT_ERROR); } - #endif - /* Windows code: End */ - - /* Linux code: Start */ - #if defined __linux__ || defined __APPLE__ - localtime_r (pTimet, pTm); - #endif - /* Linux code: End */ + struct tm *tms = localtime(pTimet); + if (tms != NULL) { + *pTm = *tms; + } else { + perror("could not convert time to local time"); + exit (EXIT_ERROR); + } } /* ** A "struct tm" time can be different from UTC because of TimeZone -** or Daylight Savings. This function gives the difference - unit: hours. +** or Daylight Savings. This function gives the difference - unit: hours. ** ** Usage: ** Add the UTC bias to convert from local-time to UTC. -** ptrTm is set */ -double getUtcBiasHours (const time_t *pTimet) +static double getUtcBiasHours (const time_t *pTimet) { struct tm utcTm; double utcBiasHours = 0.0; @@ -439,60 +393,17 @@ double getUtcBiasHours (const time_t *pTimet) // Populate "struct tm" with UTC data for the given day myUtcTime (pTimet, &utcTm); - /* Windows code: Start */ - #if defined _WIN32 || defined _WIN64 - struct tm utcNoonTm, localNoonTm; - - // Keep to the same day given, but go for noon. Daylight savings changes usually happen in the early hours. - // mktime() changes the values in "struct tm", so I need to use a private one anyway. - utcTm.tm_hour = 12; - utcTm.tm_min = 0; - utcTm.tm_sec = 0; - - // Now convert this time to time_t (which is always, by definition, UTC), - // so I can run both of the two functions I can use that differentiate between timezones, using the same UTC moment. - time_t noonTimet = mktime (&utcTm); // Unfortunately this is noonTimet is local time. It's the best I can do. - // If it was UTC, all locations on earth are within the same day at noon. - // (Because UTC = GMT. Noon GMT +/- 12hrs nestles upto, but not across, the dateline) - // Local-time 'days' (away from GMT) will probably cross the date line. - - myLocalTime (&noonTimet, &localNoonTm); // Generate 'struct tm' for local time - myUtcTime (&noonTimet, &utcNoonTm); // Generate 'struct tm' for UTC - - // This is not nice, but Visual Studio does not support "strftime(%z)" (get UTC bias) like linux does. - // I'll figure out the UTC bias by comparing readings of local time to UTC for the same moment. - - // Although localTm and utcTm may be different, some secret magic ensures that mktime() will bring - // them back to the same time_t value (as it should: they identify the same moment, just in different timezones). - // I'll just have to work out the utcBias using the differing 'struct tm' values. It isn't pretty. - - utcBiasHours = (localNoonTm.tm_hour - utcNoonTm.tm_hour) - + (localNoonTm.tm_min - utcNoonTm.tm_min) / 60.0; - - // The day may be different between the two times, especially if the local timezone is near the dateline. - // Rollover of tm_yday (from 365 to 0) is a further problem, but no bias is ever more than 24 hours - that wouldn't make sense. - - if (localNoonTm.tm_year > utcNoonTm.tm_year) utcBiasHours += 24.0; // Local time is in a new year, utc isn't: so local time is a day ahead - else if (localNoonTm.tm_year < utcNoonTm.tm_year) utcBiasHours -= 24.0; // Local time is in old year, utc is new year: so local time is a day behind - else utcBiasHours += (localNoonTm.tm_yday - utcNoonTm.tm_yday)*24.0; // Year has not changed, so we can use tm_yday normaly - #endif - /* Windows code: End */ - - /* Linux code: Start */ - #if defined __linux__ || defined __APPLE__ - char buffer [80]; - signed long int tmpLong = 0; - - mktime (&utcTm); // Let "mktime()" do it's magic - - strftime (buffer, 80, "%z", &utcTm); - - if (strlen (buffer) > 0 && myIsNumber (buffer)) - { tmpLong = atol (buffer); - utcBiasHours = (int)(tmpLong/100 + (tmpLong%100)/60.0); - } - #endif - /* Linux code: End */ + char buffer[80]; + signed long int tmpLong = 0; + + mktime(&utcTm); // Let "mktime()" do its magic + + strftime (buffer, 80, "%z", &utcTm); + + if (strlen (buffer) > 0 && myIsNumber (buffer)) { + tmpLong = atol (buffer); + utcBiasHours = (int)(tmpLong/100 + (tmpLong%100)/60.0); + } return utcBiasHours; } @@ -500,7 +411,7 @@ double getUtcBiasHours (const time_t *pTimet) /* ** Debug: What's the time (include timezone)? */ -void myDebugTime (const char * pTitleChar, const time_t *pTimet) +static void myDebugTime (const char * pTitleChar, const time_t *pTimet) { if (pRun->debug == ONOFF_ON) { struct tm tmpLocalTm, tmpUtcTm; char utcBuffer [80]; @@ -527,7 +438,7 @@ void myDebugTime (const char * pTitleChar, const time_t *pTimet) ** In effect, this function is going to shave upto 24 hours off a time ** returning 00:00 UTC on the day given. */ -time_t getMidnightUTC (const time_t *pTimet, const runStruct *pRun) +static time_t getMidnightUTC (const time_t *pTimet, const runStruct *pRun) { struct tm tmpTm; // Convert target "struct tm" to time_t. It'll be set to midnight local time, on the target day. @@ -547,7 +458,7 @@ time_t getMidnightUTC (const time_t *pTimet, const runStruct *pRun) tmpTm.tm_sec += myRound (pRun->utcBiasHours * 3600.0); // Let mktime() do it's magic - return mktime (&tmpTm); + return mktime (&tmpTm); } /* @@ -644,19 +555,19 @@ int main (int argc, char *argv[]) /* ** - ** Parse command line arguments + ** Parse command line arguments ** */ - // Change to all lowercase, just to make life easier ... - myToLower (argc, argv); + // Change to all lowercase, just to make life easier ... + stringsToLower (argc, argv); // Look for debug being activated ... for (int i=1; i < argc; i++) if (!strcmp (argv [i], "debug")) pRun->debug = ONOFF_ON; // For each argument for (int i=1; i < argc; i++) - { + { char *arg = argv[i]; // Echo argument, if in debug @@ -753,7 +664,7 @@ int main (int argc, char *argv[]) else if (!strcmp (arg, "m") && i+1 99) - { printf ("Error: \"Year\" must be between 0 and 99: %u\n", yearInt); + { printf ("Error: \"Year\" must be between 0 and 99: %u\n", yearInt); exit (EXIT_ERROR); } targetTm.tm_year = yearInt + 100; @@ -838,13 +749,13 @@ int main (int argc, char *argv[]) if (monInt != NOT_SET) { if (monInt < 1 || monInt > 12) - { printf ("Error: \"Month\" must be between 1 and 12: %u\n", monInt); + { printf ("Error: \"Month\" must be between 1 and 12: %u\n", monInt); exit (EXIT_ERROR); } targetTm.tm_mon = monInt-1; // We need month 0 to 11, not 1 to 12 } if (pRun->debug == ONOFF_ON) printf ("Debug: Target mon set to: %u\n", targetTm.tm_mon); - + if (mdayInt != NOT_SET) { if (mdayInt < 1 || mdayInt > 31) { printf ("Error: \"Day of month\" must be between 1 and 31: %u\n", mdayInt); @@ -853,7 +764,7 @@ int main (int argc, char *argv[]) targetTm.tm_mday = mdayInt; } if (pRun->debug == ONOFF_ON) printf ("Debug: Target mday set to: %u\n", targetTm.tm_mday); - + // Set target time to the start of the UTC day targetTm.tm_hour = 0; targetTm.tm_min = 0; @@ -865,7 +776,7 @@ int main (int argc, char *argv[]) targetTm.tm_isdst = -1; // -1 means: mktime() must work it out. 0=DST not in effect. 1=DST in effect. (Daylight Savings) // Convert target "struct tm" to time_t. It'll be set to midnight local time, on the target day. - pRun->targetTimet = mktime (&targetTm); + pRun->targetTimet = mktime (&targetTm); // Shave off (add) UTC offset, so that time_t is converted from midnight local-time to midnight UTC on the target day targetTm.tm_sec += myRound (pRun->utcBiasHours * 60.0 * 60.0); @@ -893,13 +804,13 @@ int main (int argc, char *argv[]) */ if (pRun->latitude == NOT_SET) - { if (pRun->debug == ONOFF_ON) printf ("Debug: latitude not set. Default applied.\n"); - pRun->latitude = DEFAULT_LATITUDE; + { if (pRun->debug == ONOFF_ON) printf ("Debug: latitude not set. Default applied.\n"); + pRun->latitude = DEFAULT_LATITUDE; } - if (pRun->longitude == NOT_SET) - { if (pRun->debug == ONOFF_ON) printf ("Debug: longitude not set. Default applied.\n"); - pRun->longitude = DEFAULT_LONGITUDE; + if (pRun->longitude == NOT_SET) + { if (pRun->debug == ONOFF_ON) printf ("Debug: longitude not set. Default applied.\n"); + pRun->longitude = DEFAULT_LONGITUDE; } // /* Co-ordinates must be in 0 to 360 range */ // IFC 2014-12-02: Removed as done in isBearing() @@ -912,7 +823,7 @@ int main (int argc, char *argv[]) } /* - ** Check: Twilight Angle + ** Check: Twilight Angle */ if (pRun->twilightAngle == NOT_SET) @@ -946,7 +857,7 @@ int main (int argc, char *argv[]) */ // IF no function requested THEN default to "usage" - if + if ( pRun->functionList == ONOFF_OFF && pRun->functionPoll == ONOFF_OFF && pRun->functionUsage == ONOFF_OFF @@ -968,38 +879,38 @@ int main (int argc, char *argv[]) ** OK - we're all done figuring out what to do - let's do it */ - if (pRun->functionVersion == ONOFF_ON) + if (pRun->functionVersion == ONOFF_ON) { if (pRun->debug == ONOFF_ON) printf ("Debug: Function selected: Version\n"); - print_version (); - exitCode = EXIT_OK; + print_version (); + exitCode = EXIT_OK; } - if (pRun->functionUsage == ONOFF_ON) + if (pRun->functionUsage == ONOFF_ON) { if (pRun->debug == ONOFF_ON) printf ("Debug: Function selected: Usage\n"); - print_usage (); - exitCode = EXIT_OK; + print_usage (); + exitCode = EXIT_OK; } if (pRun->functionReport == ONOFF_ON) { if (pRun->debug == ONOFF_ON) printf ("Debug: Function selected: Report\n"); generate_report (pRun); - exitCode = EXIT_OK; + exitCode = EXIT_OK; } - if (pRun->functionList == ONOFF_ON) + if (pRun->functionList == ONOFF_ON) { if (pRun->debug == ONOFF_ON) printf ("Debug: Function selected: List\n"); - print_list (pRun); - exitCode = EXIT_OK; + print_list (pRun); + exitCode = EXIT_OK; } if (pRun->functionWait == ONOFF_ON) { if (pRun->debug == ONOFF_ON) printf ("Debug: Function selected: Wait\n"); - exitCode = wait (pRun); + exitCode = sunwait (pRun); } - if (pRun->functionPoll == ONOFF_ON) + if (pRun->functionPoll == ONOFF_ON) { if (pRun->debug == ONOFF_ON) printf ("Debug: Function selected: Poll\n"); - exitCode = poll (pRun); + exitCode = sunpoll (pRun); if (exitCode == EXIT_DAY) printf ("DAY\n"); else if (exitCode == EXIT_NIGHT) printf ("NIGHT\n"); else if (exitCode == EXIT_OK) printf ("OK\n"); @@ -1012,8 +923,9 @@ int main (int argc, char *argv[]) /* ** Simply check if we think now/current-time is night OR day (day includes twilight) */ -inline int poll (const runStruct *pRun) -{ return isDay (pRun) == ONOFF_ON ? EXIT_DAY : EXIT_NIGHT; +inline int sunpoll (const runStruct *pRun) +{ + return isDay (pRun) == ONOFF_ON ? EXIT_DAY : EXIT_NIGHT; } /* @@ -1024,11 +936,11 @@ inline int poll (const runStruct *pRun) ** A user-specified offset messes around with daylength too. ** Exit immediately if its a polar day or midnight sun (including offset). */ -int wait (const runStruct *pRun) +int sunwait (const runStruct *pRun) { /* ** Calculate start/end of twilight for given twilight type/angle. - ** For latitudes near poles, the sun might not pass through specified twilight angle that day. + ** For latitudes near poles, the sun might not pass through specified twilight angle that day. ** For big longitudes, it's quite likely the sun is up at midnight UTC: this means we have to calculate successive days. */ @@ -1052,18 +964,18 @@ int wait (const runStruct *pRun) tomorrow.southHourUTC += 24; // Calculate duration (seconds) from "now" to "midnight UTC on the target day". [difftime (end, beginning)] - long waitMidnightUTC = static_cast (difftime (pRun->targetTimet, pRun->nowTimet)); + long waitMidnightUTC = (long) (difftime (pRun->targetTimet, pRun->nowTimet)); // Calculate duration to wait for each day's rise and set (seconds) // (targetTimet is set to midnight on the target day) - long waitRiseYesterday = waitMidnightUTC + static_cast ( 3600.0 * getOffsetRiseHourUTC (pRun, &yesterday) ); - long waitSetYesterday = waitMidnightUTC + static_cast ( 3600.0 * getOffsetSetHourUTC (pRun, &yesterday) ); - long waitRiseToday = waitMidnightUTC + static_cast ( 3600.0 * getOffsetRiseHourUTC (pRun, &today) ); - long waitSetToday = waitMidnightUTC + static_cast ( 3600.0 * getOffsetSetHourUTC (pRun, &today) ); - long waitRiseTomorrow = waitMidnightUTC + static_cast ( 3600.0 * getOffsetRiseHourUTC (pRun, &tomorrow) ); - long waitSetTomorrow = waitMidnightUTC + static_cast ( 3600.0 * getOffsetSetHourUTC (pRun, &tomorrow) ); - - // Determine next sunrise and sunset + long waitRiseYesterday = waitMidnightUTC + (long) ( 3600.0 * getOffsetRiseHourUTC (pRun, &yesterday) ); + long waitSetYesterday = waitMidnightUTC + (long) ( 3600.0 * getOffsetSetHourUTC (pRun, &yesterday) ); + long waitRiseToday = waitMidnightUTC + (long) ( 3600.0 * getOffsetRiseHourUTC (pRun, &today) ); + long waitSetToday = waitMidnightUTC + (long) ( 3600.0 * getOffsetSetHourUTC (pRun, &today) ); + long waitRiseTomorrow = waitMidnightUTC + (long) ( 3600.0 * getOffsetRiseHourUTC (pRun, &tomorrow) ); + long waitSetTomorrow = waitMidnightUTC + (long) ( 3600.0 * getOffsetSetHourUTC (pRun, &tomorrow) ); + + // Determine next sunrise and sunset // (we may be in DAY, so the next event is sunset - followed by sunrise) long waitRiseSeconds = 0; @@ -1095,7 +1007,7 @@ int wait (const runStruct *pRun) else if (waitSetToday > 0) { double diurnalArc = diurnalArcWithOffset (pRun, &today); exitPolar = diurnalArc <= 0.0 || diurnalArc >= 24.0; } else { double diurnalArc = diurnalArcWithOffset (pRun, &tomorrow); exitPolar = diurnalArc <= 0.0 || diurnalArc >= 24.0; } - if (exitPolar) + if (exitPolar) { if (pRun->debug == ONOFF_ON) printf ("Debug: Polar region or large offset: No sunrise today, there's nothing to wait for!\n"); return EXIT_ERROR; } @@ -1113,7 +1025,7 @@ int wait (const runStruct *pRun) { waitSeconds = waitRiseSeconds < waitSetSeconds ? waitRiseSeconds : waitSetSeconds; } // Don't wait if event has passed (or next going to occur soon [6hrs]) - if (waitSeconds <= 0) + if (waitSeconds <= 0) { if (pRun->debug == ONOFF_ON) printf ("Debug: Event already passed today, can't wait for that!\n"); return EXIT_ERROR; } @@ -1127,23 +1039,11 @@ int wait (const runStruct *pRun) waitSeconds = 10; } else if (pRun->functionPoll == ONOFF_ON) waitSeconds += 60; // Make more sure that a subsequent POLL works properly (wink ;-) - + /* ** Sleep (wait) until the event is expected */ - - /* Windows code: Start */ - #if defined _WIN32 || defined _WIN64 - waitSeconds *= 1000; // Convert hours to milliseconds for Windows - Sleep ((DWORD) waitSeconds); // Windows-only . waitSec is tested positive or zero - #endif - /* Windows code: End */ - - /* Linux code: Start */ - #if defined __linux__ || defined __APPLE__ - sleep (waitSeconds); // Linux-only (seconds OK) - #endif - /* Linux code: End */ + sleepSeconds(waitSeconds); return EXIT_OK; } diff --git a/sunwait.h b/sunwait.h index a07d8bc..4b979b6 100755 --- a/sunwait.h +++ b/sunwait.h @@ -16,7 +16,6 @@ #define DEFAULT_LATITUDE 40.108306 #define DEFAULT_LONGITUDE -89.7427 /* South Side School, Champaign, IL, USA */ -#define boolean bool #define NOT_SET 9999999 #define SET 1111111 @@ -26,7 +25,7 @@ typedef enum } OnOff; typedef struct -{ +{ double latitude; // Degrees N - Global position double longitude; // Degrees E - Global position @@ -59,7 +58,7 @@ typedef struct } runStruct; typedef struct -{ +{ // "Input" data double twilightAngle; // Degrees. -ve = below horizon. Can be: daylight, civil, nautical, astronomical, or custom. unsigned long daysSince2000; // The sunrise calculation needs this: days from start of 2000 to targetTimet @@ -84,8 +83,8 @@ void myLocalTime (const time_t * ptrTimet, struct tm * ptrTm); OnOff isDay (const runStruct *pRun); -int poll (const runStruct *pRun); -int wait (const runStruct *pRun); +int sunpoll (const runStruct *pRun); +int sunwait (const runStruct *pRun); #endif