You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by "C. Scott Ananian" <ca...@lesser-magoo.lcs.mit.edu> on 2001/08/25 00:36:16 UTC

Latest version of svn_parse_date.

Appended is a patch representing my latest work on the svn_parse_date
replacement.  The attached .tgz should also be untarred from the root
subversion directory to create the files
  subversion/libsvn_subr/svn_date.c
  subversion/tests/libsvn_subr/date-test.c
which can't be included in the patch due to permissions, etc, etc.

New features:
 1) code is completely APR-ized.  apr_strptime is defined and
    svn_parse_date only uses APR functions.  Portability++.
 2) test suite created for the parser.  this both serves to illustrate
    some examples of input formats, as well as the validate that
    parsing occurs correctly.
 3) I put a lot of thought into calendar weirdnesses, and the current
    code should handle leap years, leap seconds, shifts to daylight
    savings time, and even stranger things correctly (as long as
    your system's implementation of localtime (as used under the
    covers by APR) handles them correctly).
New limitations:
 1) More work needed on apr_strptime: I need to add autoconf checks
    for the native strptime function, and fall back to a replacement
    (not yet written).
 2) I've got a new internationalization scheme that should better
    address noun declension, etc, issues.  I haven't implemented
    it yet.

I'd appreciate it if the APR gurus could look over the patches to APR in
particular and let me know if they see any problems with the direction I'm
going.
  --s

arrangements Minister smuggle mail drop DES Castro MI6 Echelon biowarfare 
colonel plutonium Qaddafi Saddam Hussein quiche India General LA blowfish 
              ( http://lesser-magoo.lcs.mit.edu/~cananian )

Index: autogen.sh
===================================================================
RCS file: /usr/local/tigris/data/helm/cvs/repository/subversion/autogen.sh,v
retrieving revision 1.47
diff -u -p -r1.47 autogen.sh
--- autogen.sh	2001/08/16 19:45:44	1.47
+++ autogen.sh	2001/08/25 00:20:52
@@ -102,23 +102,6 @@ cp $ltfile ac-helpers/libtool.m4
 # any old aclocal.m4 left over from prior build so it doesn't cause errors.
 rm -f aclocal.m4
 
-# Produce getdate.c from getdate.y.
-# Again, this means that "developers" who run autogen.sh need either
-# yacc or bison -- but not people who compile sourceballs, since `make
-# dist` will include getdate.c.
-echo "Creating getdate.c..."
-bison -o subversion/libsvn_subr/getdate.c subversion/libsvn_subr/getdate.y
-if [ $? -ne 0 ]; then
-    yacc -o subversion/libsvn_subr/getdate.c subversion/libsvn_subr/getdate.y
-    if [ $? -ne 0 ]; then
-        echo
-        echo "   Error:  can't find either bison or yacc."
-        echo "   One of these is needed to generate the date parser."
-        echo
-        exit 1
-    fi
-fi
-
 # Create the file detailing all of the build outputs for SVN.
 #
 # Note: this dependency on Python is fine: only SVN developers use autogen.sh
Index: build.conf
===================================================================
RCS file: /usr/local/tigris/data/helm/cvs/repository/subversion/build.conf,v
retrieving revision 1.31
diff -u -p -r1.31 build.conf
--- build.conf	2001/08/17 16:31:21	1.31
+++ build.conf	2001/08/25 00:20:52
@@ -269,6 +269,15 @@ install = test
 group = programs
 libs = libsvn_test libsvn_delta libsvn_subr $(SVN_APR_LIBS) libexpat
 
+# test svn_parse_date function.
+[date-test]
+type = exe
+path = subversion/tests/libsvn_subr
+sources = date-test.c
+install = test
+group = programs
+libs = libsvn_test libsvn_delta libsvn_subr $(SVN_APR_LIBS) libexpat
+
 
 ### Tests that are simply broken (fix?)  ----------
 
Index: subversion/clients/cmdline/main.c
===================================================================
RCS file: /usr/local/tigris/data/helm/cvs/repository/subversion/subversion/clients/cmdline/main.c,v
retrieving revision 1.16
diff -u -p -r1.16 main.c
--- subversion/clients/cmdline/main.c	2001/08/24 22:47:26	1.16
+++ subversion/clients/cmdline/main.c	2001/08/25 00:20:52
@@ -244,14 +244,29 @@ main (int argc, const char * const *argv
         opt_state.revision = (svn_revnum_t) atoi (opt_arg);
         break;
       case 'D':
-        /* svn_parse_date() originates in getdate.y; while I'd love to
-           change it to const char *, that turns out to be a little
-           more complex than just adding the qualifier.  So for now,
-           I'm casting to get rid of the compilation warning, and have
-           filed issue #408 so we don't forget about this.  -kff  */
-        apr_ansi_time_to_apr_time (&opt_state.date,
-                                   svn_parse_date ((char *) opt_arg, NULL));
-        break;
+	{
+	  apr_time_t now, then;
+	  /* XXX: If we evaluate -D multiple times in the course of
+	   * an operation, we probably want to use the same 'now'
+	   * value every time, instead of always using the current time. */
+	  now = apr_time_now();
+	  apr_err = svn_parse_date(opt_arg, now, &then);
+	  if (APR_STATUS_IS_SUCCESS (apr_err))
+	    {
+              opt_state.date = then;
+	    }
+	  else
+	    {
+	      err = svn_error_createf (SVN_ERR_CL_ARG_PARSING_ERROR,
+				       0, NULL, pool,
+				       "Invalid date specification `%s'",
+				       opt_arg);
+	      svn_handle_error (err, stderr, FALSE);
+	      /* XXX: this should be fatal?  Otherwise we may
+	       * commit/checkout wrong versions? */
+	    }
+	  break;
+	}
       case 'v':
         opt_state.version = TRUE;
       case 'h':
@@ -309,6 +324,10 @@ main (int argc, const char * const *argv
                                      "The locale `%s' can not be set",
                                      opt_arg);
             svn_handle_error (err, stderr, FALSE);
+	    /* XXX: this should be fatal?  Otherwise we may
+	     * commit/checkout wrong versions? (because we specified
+	     * date strings etc according to a locale which wasn't actually
+	     * set? */
           }
         break;
       default:
Index: subversion/include/svn_time.h
===================================================================
RCS file: /usr/local/tigris/data/helm/cvs/repository/subversion/subversion/include/svn_time.h,v
retrieving revision 1.2
diff -u -p -r1.2 svn_time.h
--- subversion/include/svn_time.h	2001/07/04 12:12:20	1.2
+++ subversion/include/svn_time.h	2001/08/25 00:20:52
@@ -38,16 +38,15 @@ svn_stringbuf_t *svn_time_to_string (apr
 apr_time_t svn_time_from_string (svn_stringbuf_t *timestr);
 
 
-/* Needed by getdate.y parser */
-struct getdate_time {
-  time_t time;
-  short timezone;
-};
-
-/* The one interface in our getdate.y parser;  convert human-readable
-   date TEXT into a standard C time_t.  The 2nd argument is unused;
-   we always pass NULL. */
-time_t svn_parse_date (char *text, struct getdate_time *now);
+/* The one public interface of the date parser:  convert human-readable
+   date TEXT into a standard C time_t.  Note that 'now' is passed as
+   a parameter so that you can use this routine to find out how SVN
+   *would have* parsed some string at some *arbitrary* time: relative
+   times should always parse the same even if svn_parse_date is called
+   multiple times during a computation of finite length.  For this reason,
+   the 'now' parameter is *mandatory*. Returns 0 on success. */
+apr_status_t svn_parse_date (const char *text, const apr_time_t now,
+                             apr_time_t * result);
 
 #endif /* SVN_TIME_H */
 
Index: subversion/tests/libsvn_subr/.cvsignore
===================================================================
RCS file: /usr/local/tigris/data/helm/cvs/repository/subversion/subversion/tests/libsvn_subr/.cvsignore,v
retrieving revision 1.10
diff -u -p -r1.10 .cvsignore
--- subversion/tests/libsvn_subr/.cvsignore	2001/06/08 21:31:23	1.10
+++ subversion/tests/libsvn_subr/.cvsignore	2001/08/25 00:20:52
@@ -8,4 +8,5 @@ stringtest
 target-test
 stream-test
 path-test
+date-test
 z
Index: www/project_tasks.html
===================================================================
RCS file: /usr/local/tigris/data/helm/cvs/repository/subversion/www/project_tasks.html,v
retrieving revision 1.8
diff -u -p -r1.8 project_tasks.html
--- www/project_tasks.html	2001/07/25 15:53:08	1.8
+++ www/project_tasks.html	2001/08/25 00:20:52
@@ -119,46 +119,6 @@ Here are the tasks:
    </li>
    <p>
 
-   <!-- ---------------------------------------------------------- -->
-
-   <li> <b>Fix up date parsing library issues</b> <p>
-   </li>
-   This task is probably small, but will require some investigation
-   and list discussion first probably.  The basic issue is this: Ben
-   took the getdate.y date grammar file from CVS (that file has always
-   been in the public domain) and imported it into Subversion.  So now
-   Subversion has CVS's date parsing capabilities, which are good, but
-   not perfect.  Aside from the functionality issues, there's also the
-   problem that getdate.c needs to be automatically generated from
-   getdate.y, and it would be better to have a .c file that we edit
-   directly, than a .y file which causes Subversion developers to be
-   dependent on having the correct version of Yacc/Bison/Whatever
-   installed.
-   <p>
-   This message from Branko summarizes the issues pretty well; read
-   it, then move back and forth in the thread to get some context and
-   a sense of what people see as the solution domain right now:
-   <p>
-   <a
-  href="http://subversion.tigris.org/servlets/ReadMsg?msgId=31147&listName=dev"
-   >http://subversion.tigris.org/servlets/ReadMsg?msgId=31147&listName=dev</a>
-   <p>
-
-   <!-- ---------------------------------------------------------- -->
-
-   <li> <b>Constify svn_parse_date()'s first parameter</b> <p>
-   </li>
-   This is
-   <a
-   href="http://subversion.tigris.org/issues/show_bug.cgi?id=408">issue
-   #408</a>, the description is:
-   <p>
-   The first argument of svn_parse_date() should be const.  However,
-   because the function originates in getdate.y and that parameter is
-   related to the global yyInput variable, there may be more to this
-   change than just adding the qualifier...
-   <p>
-
 <!-- template for further items: -->
 <!--
 
Index: apr/include/apr_time.h
===================================================================
RCS file: /home/cvspublic/apr/include/apr_time.h,v
retrieving revision 1.41
diff -u -p -r1.41 apr_time.h
--- apr/include/apr_time.h	2001/08/24 17:55:45	1.41
+++ apr/include/apr_time.h	2001/08/25 00:14:43
@@ -228,6 +228,27 @@ APR_DECLARE(apr_status_t) apr_strftime(c
                                        apr_size_t max, const char *format, 
                                        apr_exploded_time_t *tm);
 
+/**
+ * converts a string representation of time to an exploded time
+ * similar to X/OPEN standard strptime function.  retptr gets
+ * NULL if apr_strptime fails to match all of the format string,
+ * or a pointer to the first character not processed in the format
+ * string otherwise (points to '\0' if the format string matches the
+ * complete input string).  This function does not initialize exploded
+ * time but only stores the values specified by the format string,
+ * although implementations on some platforms will recompute fields
+ * such as tm_wday and tm_yday if any of the year, month, or day
+ * elements are changed.
+ * @param s string to parse
+ * @param retptr returns the end of parsed section of s
+ * @param format The format for the time string
+ * @param tm The parsed time
+ * @deffunc apr_status_t apr_strptime(const char *s, char **retptr, const char *format, apr_exploded_time_t *tm)
+ */
+APR_DECLARE(apr_status_t) apr_strptime(const char *s, char **retptr,
+				       const char *format,
+                                       apr_exploded_time_t *tm);
+
 #ifdef __cplusplus
 }
 #endif
Index: apr/time/unix/timestr.c
===================================================================
RCS file: /home/cvspublic/apr/time/unix/timestr.c,v
retrieving revision 1.23
diff -u -p -r1.23 timestr.c
--- apr/time/unix/timestr.c	2001/04/12 22:44:42	1.23
+++ apr/time/unix/timestr.c	2001/08/25 00:14:43
@@ -189,3 +189,56 @@ apr_status_t apr_strftime(char *s, apr_s
     (*retsize) = strftime(s, max, format, &tm);
     return APR_SUCCESS;
 }
+
+#define APR_HAS_STRPTIME /* XXX: TEMPORARY, FOR DEBUGGING */
+#ifdef APR_HAS_STRPTIME
+/* this works iff:
+ *  a) system has (working) strptime function
+ *  b) apr_os_exp_time is same as struct tm
+ *  c) apr_os_exp_time_put ignores pool argument.
+ * Note that GNU glibc incorrectly handled %OI argument before
+ * 10-aug-2001, and so fails test (a). */
+/* XXX: how do i check the above? */
+apr_status_t apr_strptime(const char *s, char **retptr,
+			  const char *format, apr_exploded_time_t *tm)
+{
+  struct tm os_tm, *os_tmp = &os_tm;
+  apr_status_t status;
+  status = apr_os_exp_time_get(&os_tmp, tm);
+  if (status != APR_SUCCESS) goto bail;
+  (*retptr) = strptime(s, format, os_tmp);
+  if (NULL == (*retptr)) {
+    status = APR_EBADDATE;
+    goto bail;
+  }
+  /* versions of glibc before 10-aug-2001 contain bug parsing %OI */
+  /* see cvs log for revision 1.34 of libc/time/strptime.c */
+  /* so test for this bug and work-around it if necessary */
+  {
+    struct tm test = os_tm;
+    test.tm_hour=0; /* protect against *really* broken strptime */
+    strptime ("8", "%OI", &test);
+    if (test.tm_hour == 7) /* BUGGY GLIBC! */
+      {                         
+	const char *cp;
+	/* first determine whether the format string contains %OI,
+	 * necessitating a fixup. */
+	int needs_fixup=0;
+	for (cp = format; *cp && !needs_fixup; cp++)
+	  if (*cp=='%' && *++cp=='O' && *++cp=='I')
+	    needs_fixup=1;
+	if (needs_fixup)
+	  {
+	    /* fixup the bug, sigh. */
+	    os_tm.tm_hour = os_tm.tm_hour + 1;
+	    if (os_tm.tm_hour == 12 || os_tm.tm_hour == 24)
+	      os_tm.tm_hour -= 12;
+	  }
+      }
+  }
+  /* -- end bug workaround -- */
+  status = apr_os_exp_time_put(tm, &os_tmp, NULL/*craaazy*/);
+ bail:
+  return status;
+}
+#endif

Re: [SVN-DEV] Re: Latest version of svn_parse_date.

Posted by kf...@collab.net.
"C. Scott Ananian" <ca...@lesser-magoo.lcs.mit.edu> writes:
> 'cvs diff' will only include files in the patch generated if they have
> been 'cvs add'ed.  Since 'cvs add' doesn't modify anything but the working
> copy, most 'anonymous cvs access' installations allow 'cvs add'.  In this
> case, I'd 'cvs add' my three new files and then use 'cvs diff -N' to
> generate the complete patch.
> 
> But subversion's CVS installation won't allow 'cvs add' and so I can't
> generate the full diff.

Now I understand; thanks for the explanation.

-K

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

RE: [SVN-DEV] Re: Latest version of svn_parse_date.

Posted by "C. Scott Ananian" <ca...@lesser-magoo.lcs.mit.edu>.
On Mon, 27 Aug 2001, Sander Striker wrote:

> I mostly check out a tree and then make a copy.
> I use the copy to implement my stuff and then diff -ru the original
> against the copy, generating a full patch.  You don't need cvs
> diff for that.

but you then lose out on all the features CVS provides.  The APR and SVN
configure scripts, for example, have been modified quite a bit since I
started work on the getdate replacement.  'cvs update' has done a
fantastic job of managing those merges so that I don't have to.

I could, of course, use multiple CVS trees, one for unsullied source and
one each for every patch I was working on (I have at least three
outstanding at the moment) and 'cvs update' them all simultaneously before
using plain-diff to create patches (not forgetting to include -X flags to
substitute for the many .cvsignore files in the repository)...

...but this seems too much work.  So I'm just tar'ing up the new files.
  --s

General Suharto spy early warning Chechnya DC Yeltsin jihad nuclear 
RUCKUS CIA Rijndael genetic India $400 million in gold bullion Peking 
              ( http://lesser-magoo.lcs.mit.edu/~cananian )
 --
 "These students are going to have to find out what law and order is
 all about."  -- Brig. General Robert Canterbury, Noon, May 4, 1970,
 minutes before his troops shot 13 unarmed Kent State students, killing 4.
 --
            [http://www.cs.cmu.edu/~dst/DeCSS/Gallery/]
#!/usr/bin/perl -w
# 526-byte qrpff, Keith Winstein and Marc Horowitz <si...@mit.edu>
# MPEG 2 PS VOB file on stdin -> descrambled output on stdout
# arguments: title key bytes in least to most-significant order
$_='while(read+STDIN,$_,2048){$a=29;$c=142;if((@a=unx"C*",$_)[20]&48){$h=5;
$_=unxb24,join"",@b=map{xB8,unxb8,chr($_^$a[--$h+84])}@ARGV;s/...$/1$&/;$d=
unxV,xb25,$_;$b=73;$e=256|(ord$b[4])<<9|ord$b[3];$d=$d>>8^($f=($t=255)&($d
>>12^$d>>4^$d^$d/8))<<17,$e=$e>>8^($t&($g=($q=$e>>14&7^$e)^$q*8^$q<<6))<<9
,$_=(map{$_%16or$t^=$c^=($m=(11,10,116,100,11,122,20,100)[$_/16%8])&110;$t
^=(72,@z=(64,72,$a^=12*($_%16-2?0:$m&17)),$b^=$_%64?12:0,@z)[$_%8]}(16..271))
[$_]^(($h>>=8)+=$f+(~$g&$t))for@a[128..$#a]}print+x"C*",@a}';s/x/pack+/g;eval


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

RE: [SVN-DEV] Re: Latest version of svn_parse_date.

Posted by Sander Striker <st...@apache.org>.
> On 27 Aug 2001 kfogel@collab.net wrote:
>
> > "C. Scott Ananian" <ca...@lesser-magoo.lcs.mit.edu> writes:
> > > replacement.  The attached .tgz should also be untarred from the root
> > > subversion directory to create the files
> > >   subversion/libsvn_subr/svn_date.c
> > >   subversion/tests/libsvn_subr/date-test.c
> > > which can't be included in the patch due to permissions, etc, etc.
> >
> > ?  Can you explain some more?  I'm not sure what "due to permissions"
> > means here, was somewhat surprised that you're having a problem
> > including new files in a patch... Or is that not what's going on?
>
> 'cvs diff' will only include files in the patch generated if they have
> been 'cvs add'ed.  Since 'cvs add' doesn't modify anything but the working
> copy, most 'anonymous cvs access' installations allow 'cvs add'.  In this
> case, I'd 'cvs add' my three new files and then use 'cvs diff -N' to
> generate the complete patch.
>
> But subversion's CVS installation won't allow 'cvs add' and so I can't
> generate the full diff.

I mostly check out a tree and then make a copy.
I use the copy to implement my stuff and then diff -ru the original
against the copy, generating a full patch.  You don't need cvs
diff for that.

Sander

>   --s
>
> assassination tonight Waihopai insurgent kibo Khaddafi Attache atomic
> counter-intelligence DES IDEA WTO payment Yakima munitions President
>               ( http://lesser-magoo.lcs.mit.edu/~cananian )
>  --
>  "These students are going to have to find out what law and order is
>  all about."  -- Brig. General Robert Canterbury, Noon, May 4, 1970,
>  minutes before his troops shot 13 unarmed Kent State students, killing 4.
>  --
>             [http://www.cs.cmu.edu/~dst/DeCSS/Gallery/]
> #!/usr/bin/perl -w
> # 526-byte qrpff, Keith Winstein and Marc Horowitz <si...@mit.edu>
> # MPEG 2 PS VOB file on stdin -> descrambled output on stdout
> # arguments: title key bytes in least to most-significant order
> $_='while(read+STDIN,$_,2048){$a=29;$c=142;if((@a=unx"C*",$_)[20]&
> 48){$h=5;
> $_=unxb24,join"",@b=map{xB8,unxb8,chr($_^$a[--$h+84])}@ARGV;s/...$
> /1$&/;$d=
> unxV,xb25,$_;$b=73;$e=256|(ord$b[4])<<9|ord$b[3];$d=$d>>8^($f=($t=255)&($d
> >>12^$d>>4^$d^$d/8))<<17,$e=$e>>8^($t&($g=($q=$e>>14&7^$e)^$q*8^$q<<6))<<9
> ,$_=(map{$_%16or$t^=$c^=($m=(11,10,116,100,11,122,20,100)[$_/16%8])&110;$t
> ^=(72,@z=(64,72,$a^=12*($_%16-2?0:$m&17)),$b^=$_%64?12:0,@z)[$_%8]
> }(16..271))
> [$_]^(($h>>=8)+=$f+(~$g&$t))for@a[128..$#a]}print+x"C*",@a}';s/x/p
> ack+/g;eval
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
> For additional commands, e-mail: dev-help@subversion.tigris.org
>
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: [SVN-DEV] Re: Latest version of svn_parse_date.

Posted by "C. Scott Ananian" <ca...@lesser-magoo.lcs.mit.edu>.
On 27 Aug 2001 kfogel@collab.net wrote:

> "C. Scott Ananian" <ca...@lesser-magoo.lcs.mit.edu> writes:
> > replacement.  The attached .tgz should also be untarred from the root
> > subversion directory to create the files
> >   subversion/libsvn_subr/svn_date.c
> >   subversion/tests/libsvn_subr/date-test.c
> > which can't be included in the patch due to permissions, etc, etc.
> 
> ?  Can you explain some more?  I'm not sure what "due to permissions"
> means here, was somewhat surprised that you're having a problem
> including new files in a patch... Or is that not what's going on?

'cvs diff' will only include files in the patch generated if they have
been 'cvs add'ed.  Since 'cvs add' doesn't modify anything but the working
copy, most 'anonymous cvs access' installations allow 'cvs add'.  In this
case, I'd 'cvs add' my three new files and then use 'cvs diff -N' to
generate the complete patch.

But subversion's CVS installation won't allow 'cvs add' and so I can't
generate the full diff.
  --s

assassination tonight Waihopai insurgent kibo Khaddafi Attache atomic 
counter-intelligence DES IDEA WTO payment Yakima munitions President 
              ( http://lesser-magoo.lcs.mit.edu/~cananian )
 --
 "These students are going to have to find out what law and order is
 all about."  -- Brig. General Robert Canterbury, Noon, May 4, 1970,
 minutes before his troops shot 13 unarmed Kent State students, killing 4.
 --
            [http://www.cs.cmu.edu/~dst/DeCSS/Gallery/]
#!/usr/bin/perl -w
# 526-byte qrpff, Keith Winstein and Marc Horowitz <si...@mit.edu>
# MPEG 2 PS VOB file on stdin -> descrambled output on stdout
# arguments: title key bytes in least to most-significant order
$_='while(read+STDIN,$_,2048){$a=29;$c=142;if((@a=unx"C*",$_)[20]&48){$h=5;
$_=unxb24,join"",@b=map{xB8,unxb8,chr($_^$a[--$h+84])}@ARGV;s/...$/1$&/;$d=
unxV,xb25,$_;$b=73;$e=256|(ord$b[4])<<9|ord$b[3];$d=$d>>8^($f=($t=255)&($d
>>12^$d>>4^$d^$d/8))<<17,$e=$e>>8^($t&($g=($q=$e>>14&7^$e)^$q*8^$q<<6))<<9
,$_=(map{$_%16or$t^=$c^=($m=(11,10,116,100,11,122,20,100)[$_/16%8])&110;$t
^=(72,@z=(64,72,$a^=12*($_%16-2?0:$m&17)),$b^=$_%64?12:0,@z)[$_%8]}(16..271))
[$_]^(($h>>=8)+=$f+(~$g&$t))for@a[128..$#a]}print+x"C*",@a}';s/x/pack+/g;eval



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: Latest version of svn_parse_date.

Posted by kf...@collab.net.
"C. Scott Ananian" <ca...@lesser-magoo.lcs.mit.edu> writes:
> replacement.  The attached .tgz should also be untarred from the root
> subversion directory to create the files
>   subversion/libsvn_subr/svn_date.c
>   subversion/tests/libsvn_subr/date-test.c
> which can't be included in the patch due to permissions, etc, etc.

?  Can you explain some more?  I'm not sure what "due to permissions"
means here, was somewhat surprised that you're having a problem
including new files in a patch... Or is that not what's going on?

Thanks,
-Karl

> New features:
>  1) code is completely APR-ized.  apr_strptime is defined and
>     svn_parse_date only uses APR functions.  Portability++.
>  2) test suite created for the parser.  this both serves to illustrate
>     some examples of input formats, as well as the validate that
>     parsing occurs correctly.
>  3) I put a lot of thought into calendar weirdnesses, and the current
>     code should handle leap years, leap seconds, shifts to daylight
>     savings time, and even stranger things correctly (as long as
>     your system's implementation of localtime (as used under the
>     covers by APR) handles them correctly).
> New limitations:
>  1) More work needed on apr_strptime: I need to add autoconf checks
>     for the native strptime function, and fall back to a replacement
>     (not yet written).
>  2) I've got a new internationalization scheme that should better
>     address noun declension, etc, issues.  I haven't implemented
>     it yet.
> 
> I'd appreciate it if the APR gurus could look over the patches to APR in
> particular and let me know if they see any problems with the direction I'm
> going.
>   --s
> 
> arrangements Minister smuggle mail drop DES Castro MI6 Echelon biowarfare 
> colonel plutonium Qaddafi Saddam Hussein quiche India General LA blowfish 
>               ( http://lesser-magoo.lcs.mit.edu/~cananian )
> 
> Index: autogen.sh
> ===================================================================
> RCS file: /usr/local/tigris/data/helm/cvs/repository/subversion/autogen.sh,v
> retrieving revision 1.47
> diff -u -p -r1.47 autogen.sh
> --- autogen.sh	2001/08/16 19:45:44	1.47
> +++ autogen.sh	2001/08/25 00:20:52
> @@ -102,23 +102,6 @@ cp $ltfile ac-helpers/libtool.m4
>  # any old aclocal.m4 left over from prior build so it doesn't cause errors.
>  rm -f aclocal.m4
>  
> -# Produce getdate.c from getdate.y.
> -# Again, this means that "developers" who run autogen.sh need either
> -# yacc or bison -- but not people who compile sourceballs, since `make
> -# dist` will include getdate.c.
> -echo "Creating getdate.c..."
> -bison -o subversion/libsvn_subr/getdate.c subversion/libsvn_subr/getdate.y
> -if [ $? -ne 0 ]; then
> -    yacc -o subversion/libsvn_subr/getdate.c subversion/libsvn_subr/getdate.y
> -    if [ $? -ne 0 ]; then
> -        echo
> -        echo "   Error:  can't find either bison or yacc."
> -        echo "   One of these is needed to generate the date parser."
> -        echo
> -        exit 1
> -    fi
> -fi
> -
>  # Create the file detailing all of the build outputs for SVN.
>  #
>  # Note: this dependency on Python is fine: only SVN developers use autogen.sh
> Index: build.conf
> ===================================================================
> RCS file: /usr/local/tigris/data/helm/cvs/repository/subversion/build.conf,v
> retrieving revision 1.31
> diff -u -p -r1.31 build.conf
> --- build.conf	2001/08/17 16:31:21	1.31
> +++ build.conf	2001/08/25 00:20:52
> @@ -269,6 +269,15 @@ install = test
>  group = programs
>  libs = libsvn_test libsvn_delta libsvn_subr $(SVN_APR_LIBS) libexpat
>  
> +# test svn_parse_date function.
> +[date-test]
> +type = exe
> +path = subversion/tests/libsvn_subr
> +sources = date-test.c
> +install = test
> +group = programs
> +libs = libsvn_test libsvn_delta libsvn_subr $(SVN_APR_LIBS) libexpat
> +
>  
>  ### Tests that are simply broken (fix?)  ----------
>  
> Index: subversion/clients/cmdline/main.c
> ===================================================================
> RCS file: /usr/local/tigris/data/helm/cvs/repository/subversion/subversion/clients/cmdline/main.c,v
> retrieving revision 1.16
> diff -u -p -r1.16 main.c
> --- subversion/clients/cmdline/main.c	2001/08/24 22:47:26	1.16
> +++ subversion/clients/cmdline/main.c	2001/08/25 00:20:52
> @@ -244,14 +244,29 @@ main (int argc, const char * const *argv
>          opt_state.revision = (svn_revnum_t) atoi (opt_arg);
>          break;
>        case 'D':
> -        /* svn_parse_date() originates in getdate.y; while I'd love to
> -           change it to const char *, that turns out to be a little
> -           more complex than just adding the qualifier.  So for now,
> -           I'm casting to get rid of the compilation warning, and have
> -           filed issue #408 so we don't forget about this.  -kff  */
> -        apr_ansi_time_to_apr_time (&opt_state.date,
> -                                   svn_parse_date ((char *) opt_arg, NULL));
> -        break;
> +	{
> +	  apr_time_t now, then;
> +	  /* XXX: If we evaluate -D multiple times in the course of
> +	   * an operation, we probably want to use the same 'now'
> +	   * value every time, instead of always using the current time. */
> +	  now = apr_time_now();
> +	  apr_err = svn_parse_date(opt_arg, now, &then);
> +	  if (APR_STATUS_IS_SUCCESS (apr_err))
> +	    {
> +              opt_state.date = then;
> +	    }
> +	  else
> +	    {
> +	      err = svn_error_createf (SVN_ERR_CL_ARG_PARSING_ERROR,
> +				       0, NULL, pool,
> +				       "Invalid date specification `%s'",
> +				       opt_arg);
> +	      svn_handle_error (err, stderr, FALSE);
> +	      /* XXX: this should be fatal?  Otherwise we may
> +	       * commit/checkout wrong versions? */
> +	    }
> +	  break;
> +	}
>        case 'v':
>          opt_state.version = TRUE;
>        case 'h':
> @@ -309,6 +324,10 @@ main (int argc, const char * const *argv
>                                       "The locale `%s' can not be set",
>                                       opt_arg);
>              svn_handle_error (err, stderr, FALSE);
> +	    /* XXX: this should be fatal?  Otherwise we may
> +	     * commit/checkout wrong versions? (because we specified
> +	     * date strings etc according to a locale which wasn't actually
> +	     * set? */
>            }
>          break;
>        default:
> Index: subversion/include/svn_time.h
> ===================================================================
> RCS file: /usr/local/tigris/data/helm/cvs/repository/subversion/subversion/include/svn_time.h,v
> retrieving revision 1.2
> diff -u -p -r1.2 svn_time.h
> --- subversion/include/svn_time.h	2001/07/04 12:12:20	1.2
> +++ subversion/include/svn_time.h	2001/08/25 00:20:52
> @@ -38,16 +38,15 @@ svn_stringbuf_t *svn_time_to_string (apr
>  apr_time_t svn_time_from_string (svn_stringbuf_t *timestr);
>  
>  
> -/* Needed by getdate.y parser */
> -struct getdate_time {
> -  time_t time;
> -  short timezone;
> -};
> -
> -/* The one interface in our getdate.y parser;  convert human-readable
> -   date TEXT into a standard C time_t.  The 2nd argument is unused;
> -   we always pass NULL. */
> -time_t svn_parse_date (char *text, struct getdate_time *now);
> +/* The one public interface of the date parser:  convert human-readable
> +   date TEXT into a standard C time_t.  Note that 'now' is passed as
> +   a parameter so that you can use this routine to find out how SVN
> +   *would have* parsed some string at some *arbitrary* time: relative
> +   times should always parse the same even if svn_parse_date is called
> +   multiple times during a computation of finite length.  For this reason,
> +   the 'now' parameter is *mandatory*. Returns 0 on success. */
> +apr_status_t svn_parse_date (const char *text, const apr_time_t now,
> +                             apr_time_t * result);
>  
>  #endif /* SVN_TIME_H */
>  
> Index: subversion/tests/libsvn_subr/.cvsignore
> ===================================================================
> RCS file: /usr/local/tigris/data/helm/cvs/repository/subversion/subversion/tests/libsvn_subr/.cvsignore,v
> retrieving revision 1.10
> diff -u -p -r1.10 .cvsignore
> --- subversion/tests/libsvn_subr/.cvsignore	2001/06/08 21:31:23	1.10
> +++ subversion/tests/libsvn_subr/.cvsignore	2001/08/25 00:20:52
> @@ -8,4 +8,5 @@ stringtest
>  target-test
>  stream-test
>  path-test
> +date-test
>  z
> Index: www/project_tasks.html
> ===================================================================
> RCS file: /usr/local/tigris/data/helm/cvs/repository/subversion/www/project_tasks.html,v
> retrieving revision 1.8
> diff -u -p -r1.8 project_tasks.html
> --- www/project_tasks.html	2001/07/25 15:53:08	1.8
> +++ www/project_tasks.html	2001/08/25 00:20:52
> @@ -119,46 +119,6 @@ Here are the tasks:
>     </li>
>     <p>
>  
> -   <!-- ---------------------------------------------------------- -->
> -
> -   <li> <b>Fix up date parsing library issues</b> <p>
> -   </li>
> -   This task is probably small, but will require some investigation
> -   and list discussion first probably.  The basic issue is this: Ben
> -   took the getdate.y date grammar file from CVS (that file has always
> -   been in the public domain) and imported it into Subversion.  So now
> -   Subversion has CVS's date parsing capabilities, which are good, but
> -   not perfect.  Aside from the functionality issues, there's also the
> -   problem that getdate.c needs to be automatically generated from
> -   getdate.y, and it would be better to have a .c file that we edit
> -   directly, than a .y file which causes Subversion developers to be
> -   dependent on having the correct version of Yacc/Bison/Whatever
> -   installed.
> -   <p>
> -   This message from Branko summarizes the issues pretty well; read
> -   it, then move back and forth in the thread to get some context and
> -   a sense of what people see as the solution domain right now:
> -   <p>
> -   <a
> -  href="http://subversion.tigris.org/servlets/ReadMsg?msgId=31147&listName=dev"
> -   >http://subversion.tigris.org/servlets/ReadMsg?msgId=31147&listName=dev</a>
> -   <p>
> -
> -   <!-- ---------------------------------------------------------- -->
> -
> -   <li> <b>Constify svn_parse_date()'s first parameter</b> <p>
> -   </li>
> -   This is
> -   <a
> -   href="http://subversion.tigris.org/issues/show_bug.cgi?id=408">issue
> -   #408</a>, the description is:
> -   <p>
> -   The first argument of svn_parse_date() should be const.  However,
> -   because the function originates in getdate.y and that parameter is
> -   related to the global yyInput variable, there may be more to this
> -   change than just adding the qualifier...
> -   <p>
> -
>  <!-- template for further items: -->
>  <!--
>  
> Index: apr/include/apr_time.h
> ===================================================================
> RCS file: /home/cvspublic/apr/include/apr_time.h,v
> retrieving revision 1.41
> diff -u -p -r1.41 apr_time.h
> --- apr/include/apr_time.h	2001/08/24 17:55:45	1.41
> +++ apr/include/apr_time.h	2001/08/25 00:14:43
> @@ -228,6 +228,27 @@ APR_DECLARE(apr_status_t) apr_strftime(c
>                                         apr_size_t max, const char *format, 
>                                         apr_exploded_time_t *tm);
>  
> +/**
> + * converts a string representation of time to an exploded time
> + * similar to X/OPEN standard strptime function.  retptr gets
> + * NULL if apr_strptime fails to match all of the format string,
> + * or a pointer to the first character not processed in the format
> + * string otherwise (points to '\0' if the format string matches the
> + * complete input string).  This function does not initialize exploded
> + * time but only stores the values specified by the format string,
> + * although implementations on some platforms will recompute fields
> + * such as tm_wday and tm_yday if any of the year, month, or day
> + * elements are changed.
> + * @param s string to parse
> + * @param retptr returns the end of parsed section of s
> + * @param format The format for the time string
> + * @param tm The parsed time
> + * @deffunc apr_status_t apr_strptime(const char *s, char **retptr, const char *format, apr_exploded_time_t *tm)
> + */
> +APR_DECLARE(apr_status_t) apr_strptime(const char *s, char **retptr,
> +				       const char *format,
> +                                       apr_exploded_time_t *tm);
> +
>  #ifdef __cplusplus
>  }
>  #endif
> Index: apr/time/unix/timestr.c
> ===================================================================
> RCS file: /home/cvspublic/apr/time/unix/timestr.c,v
> retrieving revision 1.23
> diff -u -p -r1.23 timestr.c
> --- apr/time/unix/timestr.c	2001/04/12 22:44:42	1.23
> +++ apr/time/unix/timestr.c	2001/08/25 00:14:43
> @@ -189,3 +189,56 @@ apr_status_t apr_strftime(char *s, apr_s
>      (*retsize) = strftime(s, max, format, &tm);
>      return APR_SUCCESS;
>  }
> +
> +#define APR_HAS_STRPTIME /* XXX: TEMPORARY, FOR DEBUGGING */
> +#ifdef APR_HAS_STRPTIME
> +/* this works iff:
> + *  a) system has (working) strptime function
> + *  b) apr_os_exp_time is same as struct tm
> + *  c) apr_os_exp_time_put ignores pool argument.
> + * Note that GNU glibc incorrectly handled %OI argument before
> + * 10-aug-2001, and so fails test (a). */
> +/* XXX: how do i check the above? */
> +apr_status_t apr_strptime(const char *s, char **retptr,
> +			  const char *format, apr_exploded_time_t *tm)
> +{
> +  struct tm os_tm, *os_tmp = &os_tm;
> +  apr_status_t status;
> +  status = apr_os_exp_time_get(&os_tmp, tm);
> +  if (status != APR_SUCCESS) goto bail;
> +  (*retptr) = strptime(s, format, os_tmp);
> +  if (NULL == (*retptr)) {
> +    status = APR_EBADDATE;
> +    goto bail;
> +  }
> +  /* versions of glibc before 10-aug-2001 contain bug parsing %OI */
> +  /* see cvs log for revision 1.34 of libc/time/strptime.c */
> +  /* so test for this bug and work-around it if necessary */
> +  {
> +    struct tm test = os_tm;
> +    test.tm_hour=0; /* protect against *really* broken strptime */
> +    strptime ("8", "%OI", &test);
> +    if (test.tm_hour == 7) /* BUGGY GLIBC! */
> +      {                         
> +	const char *cp;
> +	/* first determine whether the format string contains %OI,
> +	 * necessitating a fixup. */
> +	int needs_fixup=0;
> +	for (cp = format; *cp && !needs_fixup; cp++)
> +	  if (*cp=='%' && *++cp=='O' && *++cp=='I')
> +	    needs_fixup=1;
> +	if (needs_fixup)
> +	  {
> +	    /* fixup the bug, sigh. */
> +	    os_tm.tm_hour = os_tm.tm_hour + 1;
> +	    if (os_tm.tm_hour == 12 || os_tm.tm_hour == 24)
> +	      os_tm.tm_hour -= 12;
> +	  }
> +      }
> +  }
> +  /* -- end bug workaround -- */
> +  status = apr_os_exp_time_put(tm, &os_tmp, NULL/*craaazy*/);
> + bail:
> +  return status;
> +}
> +#endif
> 
> ---559023410-1144747756-998699776=:29151
> Content-Type: APPLICATION/octet-stream; name="svn.tgz"
> Content-Transfer-Encoding: BASE64
> Content-ID: <Pi...@miris.lcs.mit.edu>
> Content-Description: 
> Content-Disposition: attachment; filename="svn.tgz"
> 
> H4sIALDthjsAA+w9a1cbR5b5Opz9EWXvAT3QGwyxGCWHwcTjPQZ8jFg7yWY5
> re4S6rgf2n4gFMf/fe+jqrtaagFGODOZsU5Q1PW4devWfVd1OU5H1zKK3TBo
> e+4ovg4u43QUtfGHYyWyZX+z/qfT7XT29na/6cBnf+H/+OtZr/NNZ39nt/ts
> D353of3+fnf3G9F5hLHv/KRxYkVCfGNbgRW4VrCq3V31f9JPu74h6iJf7r4Q
> 1cBK0sjyhGcFV6l1JWsC68TUAj4JrkQUpokbyBZ2LHws25bTJBZ+GCciHItk
> IsU4jHwLyrhOOmI0F0sd4TNJkmm/3Z7NZi05j25adui3X5wdtV9cvjy9GL56
> 3X55fnG50/r78AR6I4DBI3wQzlE4nUfu1SQRVbsmesCQTfjqiqOWOLfDJBGH
> vO4tIQ49T1DTWEQyltG1dFoKm+HEjUUcjpOZFUkBvz3XlkEM87Vi4cjYjtwR
> PLgBE8X1pDg6e/Pjq9OXDTGbuPYEgczDVMSTMPUcMbGuJQxiS/eaYQDxFU0B
> uOPGCQCEZQgRryGATGTkxwgEx7e8OBTWteV61ghGshJN3jiT9lbiXkVu3Aqj
> q7bCtdltTRLfo3V9NRaBnMlIqOZxNrZqTONMYaEBPZhSJBuEvm/NRYq1CKQA
> AeYOjS2ngehA00iEU8L/ERezvfEfGxv/6Qa2lzpS/NWKYZGS1uQ7oyxOHNBz
> UFbgvnYdGVUAVZPQQzh5B2jtBom30EN1uJJJIm8S6uHIMUiFOHzz9vLd4enw
> 8nz49oeL0yMDdmD70wb+8GTQEDKxS/udHJ+Y/XzpxzJZ3fx8+OLVmTGFGBTV
> uDgFaxpdzqwgUXOAltPU82LkRgtYGjnSGoXAcEu9mFR/+Qt0wUc3dtwrF5Dh
> h3hq2SWdEteXRXIp3LBS3ky90JEOtbpMxJYYR64MnHgZjoyiICwAMuCA1k7S
> +BJwQUqcXxwdHZ+f51TSgJ6iZmOEnpasN1SiVpOXrOCiMAmT+VQqTmrX63Xx
> RhfGLSxG4mGPKCYIIAGxizJGALSyg3aIn2sXUN14dX727V6nCwzDo4LGAclK
> hD0BC1RHRmoILtFkBAIF4axhPtdB9aReMq0d3DbGyIq/3BheaFuefBz4SNCJ
> 9KagKMZpYCeka5CyyJWa0vek5+Xwpxdl+JTxXT3x70nBx4Fq0oxalxKOftft
> 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
> 
> ---559023410-1144747756-998699776=:29151
> Content-Type: text/plain; charset=us-ascii
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
> For additional commands, e-mail: dev-help@subversion.tigris.org
> ---559023410-1144747756-998699776=:29151--

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org