Here's a slightly updated version of my code. Half-awake this morning I
realized a subtle bug in the internationalization code: I guaranteed
longest matches for the C locale by (for example) ordering the test for
"%d years ago" before the test "%d years" and then picking the first
match. For translated phrases, there's no guarantee that this ordering
still holds. So I added a tiny bit of code to ensure that we don't depend
on phrase ordering to select the longest match any more. This would be a
10-line patch except for the fact that I can't easily generate this.
So the complete deal (not too big, all things considered) is attached and
appended to this message in the usual way.
--s
genetic Hawk plutonium operative Blair NSA insurgent atomic Columbia
$400 million in gold bullion Sigint Nazi NRA KGB United Nations Iraq
( 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/26 17:21:14
@@ -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/26 17:21:14
@@ -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/26 17:21:14
@@ -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/26 17:21:14
@@ -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/26 17:21:14
@@ -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/26 17:21:14
@@ -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/configure.in
===================================================================
RCS file: /home/cvspublic/apr/configure.in,v
retrieving revision 1.361
diff -u -p -r1.361 configure.in
--- apr/configure.in 2001/08/17 13:35:34 1.361
+++ apr/configure.in 2001/08/26 17:21:10
@@ -593,6 +593,7 @@ fi
AC_CHECK_FUNCS(hstrerror)
AC_CHECK_FUNCS(memmove, [ have_memmove="1" ], [have_memmove="0" ])
AC_CHECK_FUNCS(mkstemp)
+AC_CHECK_FUNCS(strptime)
AC_SUBST(fork)
AC_SUBST(have_inet_addr)
Index: apr/libapr.dsp
===================================================================
RCS file: /home/cvspublic/apr/libapr.dsp,v
retrieving revision 1.42
diff -u -p -r1.42 libapr.dsp
--- apr/libapr.dsp 2001/08/26 05:21:49 1.42
+++ apr/libapr.dsp 2001/08/26 17:21:10
@@ -366,6 +366,10 @@ SOURCE=.\threadproc\win32\threadpriv.c
# PROP Default_Filter ""
# Begin Source File
+SOURCE=.\time\unix\strtime.c
+# End Source File
+# Begin Source File
+
SOURCE=.\time\win32\access.c
# End Source File
# Begin Source File
Index: apr/docs/doxygen.conf
===================================================================
RCS file: /home/cvspublic/apr/docs/doxygen.conf,v
retrieving revision 1.2
diff -u -p -r1.2 doxygen.conf
--- apr/docs/doxygen.conf 2001/08/14 04:05:16 1.2
+++ apr/docs/doxygen.conf 2001/08/26 17:21:10
@@ -19,4 +19,4 @@ OPTIMIZE_OUTPUT_FOR_C=YES
FULL_PATH_NAMES=YES
# some autoconf guru needs to make configure set this correctly...
-STRIP_FROM_PATH=/home/rbb/httpd-2.0/srclib/apr
+STRIP_FROM_PATH=/home/cananian/src/subversion/apr
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/26 17:21:10
@@ -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/test/testtime.c
===================================================================
RCS file: /home/cvspublic/apr/test/testtime.c,v
retrieving revision 1.25
diff -u -p -r1.25 testtime.c
--- apr/test/testtime.c 2001/08/01 21:06:26 1.25
+++ apr/test/testtime.c 2001/08/26 17:21:10
@@ -58,6 +58,8 @@
#include "apr_lib.h"
#include <errno.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include "test_apr.h"
#define STR_SIZE 45
@@ -68,7 +70,7 @@ int main(void)
apr_exploded_time_t xt, xt2;
apr_time_t imp;
apr_pool_t *p;
- char *str, *str2;
+ char *str, *str2, *cp;
apr_size_t sz;
apr_int32_t hr_off = -5 * 3600; /* 5 hours in seconds */
apr_int64_t hr_off_64;
@@ -178,6 +180,199 @@ int main(void)
printf("OK\n");
printf(" ( %lld - %lld = %lld )\n", imp, now, imp - now);
+ /* A better test for apr_explode_time; we're more picky here
+ * on what exactly we accept. */
+ now = ((apr_time_t)998751752) * APR_USEC_PER_SEC;
+ STD_TEST_NEQ(" apr_explode_time (GMT -4 hours) for given time",
+ apr_explode_time(&xt, now, -4*3600))
+ if (/* 11:02:32.0 */
+ xt.tm_usec != 0 ||
+ xt.tm_sec != 32 ||
+ xt.tm_min != 2 ||
+ xt.tm_hour != 11 ||
+ /* 2001-08-25 */
+ xt.tm_mday != 25 ||
+ xt.tm_mon != 7 ||
+ xt.tm_year != 101 ||
+ /* saturday, 237th day of the year, no dst, GMT -0400 */
+ xt.tm_wday != 6 ||
+ xt.tm_yday != 236 ||
+ xt.tm_isdst != 0 ||
+ xt.tm_gmtoff != -14400) {
+ apr_strftime(str, &sz, STR_SIZE, "%T %A %d %B %Y", &xt);
+ printf("apr_explode_time returned wrong result:\n"
+ "\t\tshould have returned 11:02:32 Saturday 25 August 2001\n"
+ "\t\tactually returned %s\n",
+ str);
+ exit(-1);
+ }
+
+ /* Tests for strptime; we test strftime indirectly here too. */
+
+ /* -- test 24H day date month year format -- */
+ STD_TEST_NEQ(" apr_strftime (24H day date month year)",
+ apr_strftime(str, &sz, STR_SIZE, "%T %A %e %B %Y", &xt))
+ printf(" ( %s )\n", str);
+ TEST_NEQ(" Checking strftime result for correctness",
+ strcmp(str, "11:02:32 Saturday 25 August 2001"), 0,
+ "OK", "Failed")
+ /* ----------------------- */
+ xt2.tm_usec = xt2.tm_sec = xt2.tm_min = xt2.tm_hour =
+ xt2.tm_mday = xt2.tm_mon = xt2.tm_year = xt2.tm_wday = xt2.tm_yday = 1;
+ STD_TEST_NEQ(" apr_strptime (24H day date month year)",
+ apr_strptime(str, &cp, "%T %A %d %B %Y", &xt2));
+ if (cp==NULL) {
+ MSG_AND_EXIT("apr_strptime failed to parse string.\n");
+ }
+ if (*cp!='\0') {
+ MSG_AND_EXIT("apr_strptime failed to parse string completely.\n");
+ }
+ if (/* 11:02:32 */
+ xt2.tm_sec != 32 ||
+ xt2.tm_min != 2 ||
+ xt2.tm_hour != 11) {
+ MSG_AND_EXIT("apr_strptime parsed time incorrectly\n");
+ }
+ if (/* 2001-08-25 */
+ xt2.tm_mday != 25 ||
+ xt2.tm_mon != 7 ||
+ xt2.tm_year != 101) {
+ MSG_AND_EXIT("apr_strptime parsed date incorrectly\n");
+ }
+ if (/* saturday, 237th day of the year */
+ xt2.tm_wday != 6 ||
+ xt2.tm_yday != 236) {
+ MSG_AND_EXIT("apr_strptime failed to set the weekday and year-day "
+ "fields\n");
+ }
+ /* -- test 24H format with locale specifiers -- */
+ xt2.tm_usec = xt2.tm_sec = xt2.tm_min = xt2.tm_hour =
+ xt2.tm_mday = xt2.tm_mon = xt2.tm_year = xt2.tm_wday = xt2.tm_yday = 1;
+ STD_TEST_NEQ(" apr_strptime (locale specifiers)",
+ apr_strptime(str, &cp, "%OH:%OM:%OS %A %Od %B %EY", &xt2));
+ if (cp==NULL) {
+ MSG_AND_EXIT("apr_strptime failed to parse string.\n");
+ }
+ if (*cp!='\0') {
+ MSG_AND_EXIT("apr_strptime failed to parse string completely.\n");
+ }
+ if (/* 11:02:32 */
+ xt2.tm_sec != 32 ||
+ xt2.tm_min != 2 ||
+ xt2.tm_hour != 11) {
+ MSG_AND_EXIT("apr_strptime parsed time incorrectly\n");
+ }
+ if (/* 2001-08-25 */
+ xt2.tm_mday != 25 ||
+ xt2.tm_mon != 7 ||
+ xt2.tm_year != 101) {
+ MSG_AND_EXIT("apr_strptime parsed date incorrectly\n");
+ }
+ if (/* saturday, 237th day of the year */
+ xt2.tm_wday != 6 ||
+ xt2.tm_yday != 236) {
+ MSG_AND_EXIT("apr_strptime failed to set the weekday and year-day "
+ "fields\n");
+ }
+
+ /* -- test parsing of month/day-of-week abbreviations -- */
+ STD_TEST_NEQ(" apr_strftime (abbreviated month/day-of-week)",
+ apr_strftime(str, &sz, STR_SIZE, "%a %b", &xt))
+ printf(" ( %s )\n", str);
+ /* ----------------------- */
+ xt2.tm_usec = xt2.tm_sec = xt2.tm_min = xt2.tm_hour =
+ xt2.tm_mday = xt2.tm_mon = xt2.tm_year = xt2.tm_wday = xt2.tm_yday = 1;
+ STD_TEST_NEQ(" apr_strptime (abbreviated month/day-of-week)",
+ apr_strptime(str, &cp, "%a %b", &xt2));
+ if (cp==NULL) {
+ MSG_AND_EXIT("apr_strptime failed to parse string.\n");
+ }
+ if (*cp!='\0') {
+ MSG_AND_EXIT("apr_strptime failed to parse string completely.\n");
+ }
+ if (/* saturday in august */
+ xt2.tm_mon != 7 ||
+ xt2.tm_wday != 6) {
+ MSG_AND_EXIT("apr_strptime failed to parse string correctly.\n");
+ }
+
+ /* -- test 12-hour time and weekday number -- */
+ STD_TEST_NEQ(" apr_strftime (12-hour time, weekday number)",
+ apr_strftime(str, &sz, STR_SIZE, "%I %p %w", &xt))
+ printf(" ( %s )\n", str);
+ /* ----------------------- */
+ xt2.tm_usec = xt2.tm_sec = xt2.tm_min = xt2.tm_hour =
+ xt2.tm_mday = xt2.tm_mon = xt2.tm_year = xt2.tm_wday = xt2.tm_yday = 1;
+ STD_TEST_NEQ(" apr_strptime (12-hour time, weekday number)",
+ apr_strptime(str, &cp, "%I %p %w", &xt2));
+ if (cp==NULL) {
+ MSG_AND_EXIT("apr_strptime failed to parse string.\n");
+ }
+ if (*cp!='\0') {
+ MSG_AND_EXIT("apr_strptime failed to parse string completely.\n");
+ }
+ if (/* 11am, saturday */
+ xt2.tm_hour != 11 ||
+ xt2.tm_wday != 6) {
+ MSG_AND_EXIT("apr_strptime failed to parse string correctly.\n");
+ }
+
+ /* -- test 12-hour time, in the afternoon and the percent character */
+ xt.tm_hour = 15;
+ STD_TEST_NEQ(" apr_strftime (12-hour time, percent character)",
+ apr_strftime(str, &sz, STR_SIZE, "%% %l %p %%", &xt))
+ printf(" ( %s )\n", str);
+ /* ----------------------- */
+ xt2.tm_usec = xt2.tm_sec = xt2.tm_min = xt2.tm_hour =
+ xt2.tm_mday = xt2.tm_mon = xt2.tm_year = xt2.tm_wday = xt2.tm_yday = 1;
+ STD_TEST_NEQ(" apr_strptime (12-hour time, percent character)",
+ apr_strptime(str, &cp, "%% %I %p %%", &xt2));
+ if (cp==NULL) {
+ MSG_AND_EXIT("apr_strptime failed to parse string.\n");
+ }
+ if (*cp!='\0') {
+ MSG_AND_EXIT("apr_strptime failed to parse string completely.\n");
+ }
+ if (/* 3pm */
+ xt2.tm_hour != 15) {
+ MSG_AND_EXIT("apr_strptime failed to parse string correctly.\n");
+ }
+
+ /* -- test parsing of tricky squashed-together no-space formats -- */
+ xt.tm_hour = 15;
+ STD_TEST_NEQ(" apr_strftime (squashed)",
+ apr_strftime(str, &sz, STR_SIZE, "%Y%m%dT%H%M%S.0Z", &xt))
+ printf(" ( %s )\n", str);
+ /* ----------------------- */
+ xt2.tm_usec = xt2.tm_sec = xt2.tm_min = xt2.tm_hour =
+ xt2.tm_mday = xt2.tm_mon = xt2.tm_year = xt2.tm_wday = xt2.tm_yday = 1;
+ STD_TEST_NEQ(" apr_strptime (squashed)",
+ apr_strptime(str, &cp, "%Y%m%dT%H%M%S.0Z", &xt2));
+ if (cp==NULL) {
+ MSG_AND_EXIT("apr_strptime failed to parse string.\n");
+ }
+ if (*cp!='\0') {
+ MSG_AND_EXIT("apr_strptime failed to parse string completely.\n");
+ }
+ if (/* 11:02:32 */
+ xt2.tm_sec != 32 ||
+ xt2.tm_min != 2 ||
+ xt2.tm_hour != 15) {
+ MSG_AND_EXIT("apr_strptime parsed time incorrectly\n");
+ }
+ if (/* 2001-08-25 */
+ xt2.tm_mday != 25 ||
+ xt2.tm_mon != 7 ||
+ xt2.tm_year != 101) {
+ MSG_AND_EXIT("apr_strptime parsed date incorrectly\n");
+ }
+ if (/* saturday, 237th day of the year */
+ xt2.tm_wday != 6 ||
+ xt2.tm_yday != 236) {
+ MSG_AND_EXIT("apr_strptime failed to set the weekday and year-day "
+ "fields\n");
+ }
+
printf("\nTest Complete.\n");
return 0;
}
Index: apr/time/unix/Makefile.in
===================================================================
RCS file: /home/cvspublic/apr/time/unix/Makefile.in,v
retrieving revision 1.21
diff -u -p -r1.21 Makefile.in
--- apr/time/unix/Makefile.in 2001/01/09 11:06:26 1.21
+++ apr/time/unix/Makefile.in 2001/08/26 17:21:10
@@ -1,5 +1,5 @@
-TARGETS = time.lo timestr.lo
+TARGETS = time.lo timestr.lo strtime.lo
# bring in rules.mk for standard functionality
@INCLUDE_RULES@
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/26 17:21:10
@@ -167,6 +167,10 @@ apr_status_t apr_ctime(char *date_str, a
return APR_SUCCESS;
}
+/* note the this strftime function doesn't handle %z or %Z in the
+ * correct way if HAVE_GMTOFF or HAVE___OFFSET is not defined, as
+ * timezone information should be taken from the apr_exploded_time_t,
+ * not the environment. */
apr_status_t apr_strftime(char *s, apr_size_t *retsize, apr_size_t max,
const char *format, apr_exploded_time_t *xt)
{
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
- APPLICATION/octet-stream attachment: svn.tgz
Received on Sat Oct 21 14:36:37 2006