Re: awk: implement mktime() function

2020-08-23 Thread Jason McIntyre
On Sun, Aug 23, 2020 at 10:25:37AM -0600, Todd C. Miller wrote:
> Both gawk and mawk include mktime() in their time functions.
> We have strftime() and systime() but no mktime().  The following
> diff makes our awk more compatible with other implementations.
> 
>  - todd
> 

hi/

i think the text is fine. could you add mktime to the list of
extensions in STANDARDS too?

jmc

> Index: usr.bin/awk/awk.1
> ===
> RCS file: /cvs/src/usr.bin/awk/awk.1,v
> retrieving revision 1.56
> diff -u -p -u -r1.56 awk.1
> --- usr.bin/awk/awk.1 24 Jul 2020 01:57:06 -  1.56
> +++ usr.bin/awk/awk.1 23 Aug 2020 16:22:46 -
> @@ -684,6 +684,41 @@ This version of
>  provides the following functions for obtaining and formatting time
>  stamps.
>  .Bl -tag -width indent
> +.It Fn mktime datespec
> +Converts
> +.Fa datespec
> +into a timestamp in the same form as a value returned by
> +.Fn systime .
> +The
> +.Fa datespec
> +is a string composed of six or seven numbers separated by whitespace:
> +.Bd -literal -offset indent
> + MM DD HH MM SS [DST]
> +.Ed
> +.Pp
> +The fields in
> +.Fa datespec
> +are as follows:
> +.Bl -tag -width ""
> +.It YYY
> +Year: a four-digit year, including the century.
> +.It MM
> +Month: a number from 1 to 12.
> +.It DD
> +Day: a number from 1 to 31.
> +.It HH
> +Hour: a number from 0 to 23.
> +.It MM
> +Minute: a number from 0 to 59.
> +.It SS
> +Second: a number from 0 to 60 (permitting a leap second).
> +.It DST
> +Daylight Saving Time: a positive or zero value indicates that
> +DST is or is not in effect.
> +If DST is not specified, or is negative,
> +.Fn mktime
> +will attempt to determine the correct value.
> +.El
>  .It Fn strftime "[format [, timestamp]]"
>  Formats
>  .Ar timestamp
> @@ -696,6 +731,8 @@ manual page, as well as any arbitrary te
>  The
>  .Ar timestamp
>  must be in the same form as a value returned by
> +.Fn mktime
> +and
>  .Fn systime .
>  If
>  .Ar timestamp



awk: implement mktime() function

2020-08-23 Thread Todd C . Miller
Both gawk and mawk include mktime() in their time functions.
We have strftime() and systime() but no mktime().  The following
diff makes our awk more compatible with other implementations.

 - todd

Index: usr.bin/awk/awk.1
===
RCS file: /cvs/src/usr.bin/awk/awk.1,v
retrieving revision 1.56
diff -u -p -u -r1.56 awk.1
--- usr.bin/awk/awk.1   24 Jul 2020 01:57:06 -  1.56
+++ usr.bin/awk/awk.1   23 Aug 2020 16:22:46 -
@@ -684,6 +684,41 @@ This version of
 provides the following functions for obtaining and formatting time
 stamps.
 .Bl -tag -width indent
+.It Fn mktime datespec
+Converts
+.Fa datespec
+into a timestamp in the same form as a value returned by
+.Fn systime .
+The
+.Fa datespec
+is a string composed of six or seven numbers separated by whitespace:
+.Bd -literal -offset indent
+ MM DD HH MM SS [DST]
+.Ed
+.Pp
+The fields in
+.Fa datespec
+are as follows:
+.Bl -tag -width ""
+.It YYY
+Year: a four-digit year, including the century.
+.It MM
+Month: a number from 1 to 12.
+.It DD
+Day: a number from 1 to 31.
+.It HH
+Hour: a number from 0 to 23.
+.It MM
+Minute: a number from 0 to 59.
+.It SS
+Second: a number from 0 to 60 (permitting a leap second).
+.It DST
+Daylight Saving Time: a positive or zero value indicates that
+DST is or is not in effect.
+If DST is not specified, or is negative,
+.Fn mktime
+will attempt to determine the correct value.
+.El
 .It Fn strftime "[format [, timestamp]]"
 Formats
 .Ar timestamp
@@ -696,6 +731,8 @@ manual page, as well as any arbitrary te
 The
 .Ar timestamp
 must be in the same form as a value returned by
+.Fn mktime
+and
 .Fn systime .
 If
 .Ar timestamp
Index: usr.bin/awk/awk.h
===
RCS file: /cvs/src/usr.bin/awk/awk.h,v
retrieving revision 1.26
diff -u -p -u -r1.26 awk.h
--- usr.bin/awk/awk.h   26 Jun 2020 15:57:39 -  1.26
+++ usr.bin/awk/awk.h   22 Aug 2020 21:17:49 -
@@ -160,6 +160,7 @@ extern Cell *symtabloc; /* SYMTAB */
 #define FRSHIFT20
 #define FSYSTIME   21
 #define FSTRFTIME  22
+#define FMKTIME23
 
 /* Node:  parse tree is made of nodes, with Cell's at bottom */
 
Index: usr.bin/awk/lex.c
===
RCS file: /cvs/src/usr.bin/awk/lex.c,v
retrieving revision 1.25
diff -u -p -u -r1.25 lex.c
--- usr.bin/awk/lex.c   30 Jul 2020 17:45:44 -  1.25
+++ usr.bin/awk/lex.c   22 Aug 2020 21:18:16 -
@@ -75,6 +75,7 @@ const Keyword keywords[] = {  /* keep sor
{ "log",FLOG,   BLTIN },
{ "lshift", FLSHIFT,BLTIN },
{ "match",  MATCHFCN,   MATCHFCN },
+   { "mktime", FMKTIME,BLTIN },
{ "next",   NEXT,   NEXT },
{ "nextfile",   NEXTFILE,   NEXTFILE },
{ "or", FFOR,   BLTIN },
Index: usr.bin/awk/run.c
===
RCS file: /cvs/src/usr.bin/awk/run.c,v
retrieving revision 1.67
diff -u -p -u -r1.67 run.c
--- usr.bin/awk/run.c   11 Aug 2020 16:57:05 -  1.67
+++ usr.bin/awk/run.c   22 Aug 2020 21:35:49 -
@@ -1594,7 +1594,7 @@ Cell *bltin(Node **a, int n)  /* builtin 
FILE *fp;
int status = 0;
time_t tv;
-   struct tm *tm;
+   struct tm *tm, tmbuf;
 
t = ptoi(a[0]);
x = execute(a[1]);
@@ -1748,6 +1748,26 @@ Cell *bltin(Node **a, int n) /* builtin 
u = EOF;
else
u = fflush(fp);
+   break;
+   case FMKTIME:
+   memset(, 0, sizeof(tmbuf));
+   tm = 
+   t = sscanf(getsval(x), "%d %d %d %d %d %d %d",
+   >tm_year, >tm_mon, >tm_mday, >tm_hour,
+   >tm_min, >tm_sec, >tm_isdst);
+   switch (t) {
+   case 6:
+   tmbuf.tm_isdst = -1;/* let mktime figure it out */
+   /* FALLTHROUGH */
+   case 7:
+   tm->tm_year -= 1900;
+   tm->tm_mon--;
+   u = mktime(tm);
+   break;
+   default:
+   u = -1;
+   break;
+   }
break;
case FSYSTIME:
u = time((time_t *) 0);