From e1b0a416a9ffdc095fb3d80319d61c257fdcc8a9 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Sat, 11 Jan 2014 11:13:25 -0800 Subject: [PATCH] SCP: Generalized DATE and TIME variable insertion adding support for ISO 8601 date values. Inspired by Christian Gauger-Cosgrove. ISO 8601 support without requiring C99 strftime functionality. %DATE% yyyy-mm-dd %TIME% hh:mm:ss %DATETIME% yyyy-mm-ddThh:mm:ss %LDATE% mm/dd/yy (Locale Formatted) %LTIME% hh:mm:ss am/pm (Locale Formatted) %CTIME% Www Mmm dd hh:mm:ss yyyy (Locale Formatted) %DATE_YYYY% yyyy (0000-9999) %DATE_YY% yy (00-99) %DATE_MM% mm (01-12) %DATE_DD% dd (01-31) %DATE_WW% ww (01-53) ISO 8601 week number %DATE_WYYYY% yyyy (0000-9999) ISO 8601 week year number %DATE_D% d (1-7) ISO 8601 day of week %DATE_JJJ% jjj (001-366) day of year %TIME_HH% hh (00-23) %TIME_MM% mm (00-59) %TIME_SS% ss (00-59) --- README.md | 19 +++++++++-- scp.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++---- sim_defs.h | 4 +++ 3 files changed, 106 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 7644b355..f0ec72ac 100644 --- a/README.md +++ b/README.md @@ -212,7 +212,7 @@ The "!" command (execute a command on the local OS), now returns the command's e #### Command Processing Enhancements ##### Environment variable insertion -Built In variables %DATE%, %TIME%, %STIME%, %CTIME%, %STATUS%, %TSTATUS%, %SIM_VERIFY%, %SIM_QUIET%, %SIM_MESSAGE% +Built In variables %DATE%, %TIME%, %DATETIME%, %LDATE%, %LTIME%, %CTIME%, %DATE_YYYY%, %DATE_YY%, %DATE_MM%, %DATE_DD%, %DATE_D%, %DATE_WYYYY%, %DATE_WW%, %TIME_HH%, %TIME_MM%, %TIME_SS%, %STATUS%, %TSTATUS%, %SIM_VERIFY%, %SIM_QUIET%, %SIM_MESSAGE% Command Aliases Token "%0" expands to the command file name. @@ -230,8 +230,21 @@ Command Aliases %DATE% yyyy-mm-dd %TIME% hh:mm:ss - %STIME% hh_mm_ss - %CTIME% Www Mmm dd hh:mm:ss yyyy + %DATETIME% yyyy-mm-ddThh:mm:ss + %LDATE% mm/dd/yy (Locale Formatted) + %LTIME% hh:mm:ss am/pm (Locale Formatted) + %CTIME% Www Mmm dd hh:mm:ss yyyy (Locale Formatted) + %DATE_YYYY% yyyy (0000-9999) + %DATE_YY% yy (00-99) + %DATE_MM% mm (01-12) + %DATE_DD% dd (01-31) + %DATE_WW% ww (01-53) ISO 8601 week number + %DATE_WYYYY% yyyy (0000-9999) ISO 8601 week year number + %DATE_D% d (1-7) ISO 8601 day of week + %DATE_JJJ% jjj (001-366) day of year + %TIME_HH% hh (00-23) + %TIME_MM% mm (00-59) + %TIME_SS% ss (00-59) %STATUS% Status value from the last command executed %TSTATUS% The text form of the last status value %SIM_VERIFY% The Verify/Verbose mode of the current Do command file diff --git a/scp.c b/scp.c index 79760db0..6ddf0e49 100644 --- a/scp.c +++ b/scp.c @@ -1785,7 +1785,11 @@ char gbuf[CBUFSIZE]; char *ip = instr, *op, *ap, *oend, *istart, *tmpbuf; char rbuf[CBUFSIZE]; int i; +time_t now; +struct tm *tmnow; +time(&now); +tmnow = localtime(&now); tmpbuf = (char *)malloc(instr_size); op = tmpbuf; oend = tmpbuf + instr_size - 2; @@ -1842,11 +1846,7 @@ for (; *ip && (op < oend); ) { ip += 1 + strlen (gbuf); if (*ip == '%') ++ip; if (!ap) { - time_t now; - struct tm *tmnow; - - time(&now); - tmnow = localtime(&now); + /* ISO 8601 format date/time info */ if (!strcmp ("DATE", gbuf)) { sprintf (rbuf, "%4d-%02d-%02d", tmnow->tm_year+1900, tmnow->tm_mon+1, tmnow->tm_mday); ap = rbuf; @@ -1855,13 +1855,92 @@ for (; *ip && (op < oend); ) { sprintf (rbuf, "%02d:%02d:%02d", tmnow->tm_hour, tmnow->tm_min, tmnow->tm_sec); ap = rbuf; } - else if (!strcmp ("STIME", gbuf)) { - sprintf (rbuf, "%02d_%02d_%02d", tmnow->tm_hour, tmnow->tm_min, tmnow->tm_sec); + else if (!strcmp ("DATETIME", gbuf)) { + sprintf (rbuf, "%04d-%02d-%02dT%02d:%02d:%02d", tmnow->tm_year+1900, tmnow->tm_mon+1, tmnow->tm_mday, tmnow->tm_hour, tmnow->tm_min, tmnow->tm_sec); + ap = rbuf; + } + /* Locale oriented formatted date/time info */ + if (!strcmp ("LDATE", gbuf)) { + strftime (rbuf, sizeof(rbuf), "%x", tmnow); + ap = rbuf; + } + else if (!strcmp ("LTIME", gbuf)) { +#if defined(HAVE_C99_STRFTIME) + strftime (rbuf, sizeof(rbuf), "%r", tmnow); +#else + strftime (rbuf, sizeof(rbuf), "%p", tmnow); + if (rbuf[0]) + strftime (rbuf, sizeof(rbuf), "%I:%M:%S %p", tmnow); + else + strftime (rbuf, sizeof(rbuf), "%H:%M:%S", tmnow); +#endif ap = rbuf; } else if (!strcmp ("CTIME", gbuf)) { +#if defined(HAVE_C99_STRFTIME) + strftime (rbuf, sizeof(rbuf), "%c", tmnow); +#else strcpy (rbuf, ctime(&now)); rbuf[strlen (rbuf)-1] = '\0'; /* remove trailing \n */ +#endif + ap = rbuf; + } + /* Separate Date/Time info */ + else if (!strcmp ("DATE_YYYY", gbuf)) {/* Year (0000-9999) */ + strftime (rbuf, sizeof(rbuf), "%Y", tmnow); + ap = rbuf; + } + else if (!strcmp ("DATE_YY", gbuf)) {/* Year (00-99) */ + strftime (rbuf, sizeof(rbuf), "%y", tmnow); + ap = rbuf; + } + else if (!strcmp ("DATE_MM", gbuf)) {/* Month number (01-12) */ + strftime (rbuf, sizeof(rbuf), "%m", tmnow); + ap = rbuf; + } + else if (!strcmp ("DATE_DD", gbuf)) {/* Day of Month (01-31) */ + strftime (rbuf, sizeof(rbuf), "%d", tmnow); + ap = rbuf; + } + else if (!strcmp ("DATE_D", gbuf)) { /* ISO 8601 weekday number (1-7) */ + sprintf (rbuf, "%d", (tmnow->tm_wday ? tmnow->tm_wday : 7)); + ap = rbuf; + } + else if ((!strcmp ("DATE_WW", gbuf)) || /* ISO 8601 week number (01-53) */ + (!strcmp ("DATE_WYYYY", gbuf))) {/* ISO 8601 week year number (0000-9999) */ + int iso_yr = tmnow->tm_year + 1900; + int iso_wk = (tmnow->tm_yday + 11 - (tmnow->tm_wday ? tmnow->tm_wday : 7))/7;; + + if (iso_wk == 0) { + iso_yr = iso_yr - 1; + tmnow->tm_yday += 365 + ((iso_yr % 4) == 0) ? 1 : 0; /* Adjust for Leap Year (Correct thru 2099) */ + iso_wk = (tmnow->tm_yday + 11 - (tmnow->tm_wday ? tmnow->tm_wday : 7))/7; + } + else + if ((iso_wk == 53) && (((31 - tmnow->tm_mday) + tmnow->tm_wday) < 4)) { + ++iso_yr; + iso_wk = 1; + } + if (!strcmp ("DATE_WW", gbuf)) + sprintf (rbuf, "%02d", iso_wk); + else + sprintf (rbuf, "%04d", iso_yr); + ap = rbuf; + } + else if (!strcmp ("DATE_JJJ", gbuf)) {/* day of year (001-366) */ + strftime (rbuf, sizeof(rbuf), "%j", tmnow); + ap = rbuf; + } + else if (!strcmp ("TIME_HH", gbuf)) {/* Hour of day (00-23) */ + strftime (rbuf, sizeof(rbuf), "%H", tmnow); + ap = rbuf; + } + else if (!strcmp ("TIME_MM", gbuf)) {/* Minute of hour (00-59) */ + strftime (rbuf, sizeof(rbuf), "%M", tmnow); + ap = rbuf; + } + else if (!strcmp ("TIME_SS", gbuf)) {/* Second of minute (00-59) */ + strftime (rbuf, sizeof(rbuf), "%S", tmnow); ap = rbuf; } else if (!strcmp ("STATUS", gbuf)) { diff --git a/sim_defs.h b/sim_defs.h index e60eb18e..ae6b177f 100644 --- a/sim_defs.h +++ b/sim_defs.h @@ -219,6 +219,10 @@ typedef uint32 t_addr; #define HAVE_GLOB #endif +#if defined (__linux) || defined (VMS) || defined (__APPLE__) +#define HAVE_C99_STRFTIME 1 +#endif + /* Stubs for inlining */ #define SIM_INLINE