You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2011/02/21 21:40:50 UTC

svn commit: r1073138 [5/9] - in /subversion/branches/ignore-mergeinfo-log: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ notes/ notes/wc-ng/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversio...

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/dirent_uri.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/dirent_uri.c?rev=1073138&r1=1073137&r2=1073138&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/dirent_uri.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/dirent_uri.c Mon Feb 21 20:40:44 2011
@@ -473,22 +473,34 @@ canonicalize(path_type_t type, const cha
 
   while (*src)
     {
-      /* Parse each segment, find the closing '/' */
+      /* Parse each segment, finding the closing '/' (which might look
+         like '%2F' for URIs).  */
       const char *next = src;
-      while (*next && (*next != '/'))
-        ++next;
+      apr_size_t slash_len = 0;
 
+      while (*next
+             && (next[0] != '/')
+             && (! (type == type_uri && next[0] == '%' && next[1] == '2' &&
+                    canonicalize_to_upper(next[2]) == 'F')))
+        {
+          ++next;
+        }
+
+      /* Record how long our "slash" is. */
+      if (next[0] == '/')
+        slash_len = 1;
+      else if (type == type_uri && next[0] == '%')
+        slash_len = 3;
+      
       seglen = next - src;
 
-      if (seglen == 0 || (seglen == 1 && src[0] == '.'))
+      if (seglen == 0 
+          || (seglen == 1 && src[0] == '.')
+          || (type == type_uri && seglen == 3 && src[0] == '%' && src[1] == '2'
+              && canonicalize_to_upper(src[2]) == 'E'))
         {
-          /* Noop segment, so do nothing. */
-        }
-      else if (type == type_uri && seglen == 3
-               && src[0] == '%' && src[1] == '2'
-               && canonicalize_to_upper(src[2]) == 'E')
-        {
-          /* '%2E' is equivalent to '.', so this is a noop segment */
+          /* Empty or noop segment, so do nothing.  (For URIs, '%2E'
+             is equivalent to '.').  */
         }
 #ifdef SVN_USE_DOS_PATHS
       /* If this is the first path segment of a file:// URI and it contains a
@@ -507,17 +519,15 @@ canonicalize(path_type_t type, const cha
       else
         {
           /* An actual segment, append it to the destination path */
-          if (*next)
-            seglen++;
           memcpy(dst, src, seglen);
           dst += seglen;
+          if (slash_len)
+            *(dst++) = '/';
           canon_segments++;
         }
 
       /* Skip over trailing slash to the next segment. */
-      src = next;
-      if (*src)
-        src++;
+      src = next + slash_len;
     }
 
   /* Remove the trailing slash if there was at least one

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/hash.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/hash.c?rev=1073138&r1=1073137&r2=1073138&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/hash.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/hash.c Mon Feb 21 20:40:44 2011
@@ -354,8 +354,9 @@ svn_hash_read(apr_hash_t *hash,
 
           /* Now read that much into a buffer, + 1 byte for null terminator */
           keybuf = apr_palloc(pool, keylen + 1);
-          SVN_ERR(svn_io_file_read_full(srcfile,
-                                        keybuf, keylen, &num_read, pool));
+          SVN_ERR(svn_io_file_read_full2(srcfile,
+                                         keybuf, keylen,
+                                         &num_read, NULL, pool));
           ((char *) keybuf)[keylen] = '\0';
 
           /* Suck up extra newline after key data */
@@ -379,9 +380,9 @@ svn_hash_read(apr_hash_t *hash,
 
               /* Again, 1 extra byte for the null termination. */
               valbuf = apr_palloc(pool, vallen + 1);
-              SVN_ERR(svn_io_file_read_full(srcfile,
-                                            valbuf, vallen,
-                                            &num_read, pool));
+              SVN_ERR(svn_io_file_read_full2(srcfile,
+                                             valbuf, vallen,
+                                             &num_read, NULL, pool));
               ((char *) valbuf)[vallen] = '\0';
 
               /* Suck up extra newline after val data */

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/io.c?rev=1073138&r1=1073137&r2=1073138&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/io.c Mon Feb 21 20:40:44 2011
@@ -1546,8 +1546,8 @@ io_set_file_perms(const char *path,
 #ifdef WIN32
 #if APR_HAS_UNICODE_FS
 /* copy of the apr function utf8_to_unicode_path since apr doesn't export this one */
-apr_status_t svn_utf8_to_unicode_path(apr_wchar_t* retstr, apr_size_t retlen, 
-                                  const char* srcstr)
+static apr_status_t io_utf8_to_unicode_path(apr_wchar_t* retstr, apr_size_t retlen, 
+                                            const char* srcstr)
 {
     /* TODO: The computations could preconvert the string to determine
      * the true size of the retstr, but that's a memory over speed
@@ -1565,7 +1565,7 @@ apr_status_t svn_utf8_to_unicode_path(ap
     apr_wchar_t *t = retstr;
     apr_status_t rv;
 
-    /* This is correct, we don't twist the filename if it is will
+    /* This is correct, we don't twist the filename if it will
      * definately be shorter than 248 characters.  It merits some 
      * performance testing to see if this has any effect, but there
      * seem to be applications that get confused by the resulting
@@ -1610,10 +1610,10 @@ apr_status_t svn_utf8_to_unicode_path(ap
 }
 #endif
 
-apr_status_t apr_win_file_attrs_set(const char *fname,
-                                    DWORD attributes,
-                                    DWORD attr_mask,
-                                    apr_pool_t *pool)
+static apr_status_t io_win_file_attrs_set(const char *fname,
+                                          DWORD attributes,
+                                          DWORD attr_mask,
+                                          apr_pool_t *pool)
 {
     /* this is an implementation of apr_file_attrs_set() but one
        that uses the proper Windows attributes instead of the apr
@@ -1628,9 +1628,9 @@ apr_status_t apr_win_file_attrs_set(cons
 #if APR_HAS_UNICODE_FS
     IF_WIN_OS_IS_UNICODE
     {
-        if (rv = svn_utf8_to_unicode_path(wfname,
-                                          sizeof(wfname) / sizeof(wfname[0]),
-                                          fname))
+        if (rv = io_utf8_to_unicode_path(wfname,
+                                         sizeof(wfname) / sizeof(wfname[0]),
+                                         fname))
             return rv;
         flags = GetFileAttributesW(wfname);
     }
@@ -1645,8 +1645,8 @@ apr_status_t apr_win_file_attrs_set(cons
     if (flags == 0xFFFFFFFF)
         return apr_get_os_error();
 
-    flags |= (attributes & attr_mask);
     flags &= ~attr_mask;
+    flags |= (attributes & attr_mask);
 
 #if APR_HAS_UNICODE_FS
     IF_WIN_OS_IS_UNICODE
@@ -3016,6 +3016,17 @@ svn_io_file_getc(char *ch, apr_file_t *f
 
 
 svn_error_t *
+svn_io_file_putc(char ch, apr_file_t *file, apr_pool_t *pool)
+{
+  return do_io_file_wrapper_cleanup
+    (file, apr_file_putc(ch, file),
+     N_("Can't write file '%s'"),
+     N_("Can't write stream"),
+     pool);
+}
+
+
+svn_error_t *
 svn_io_file_info_get(apr_finfo_t *finfo, apr_int32_t wanted,
                      apr_file_t *file, apr_pool_t *pool)
 {
@@ -3040,12 +3051,23 @@ svn_io_file_read(apr_file_t *file, void 
 
 
 svn_error_t *
-svn_io_file_read_full(apr_file_t *file, void *buf,
-                      apr_size_t nbytes, apr_size_t *bytes_read,
-                      apr_pool_t *pool)
+svn_io_file_read_full2(apr_file_t *file, void *buf,
+                       apr_size_t nbytes, apr_size_t *bytes_read,
+                       svn_boolean_t *hit_eof,
+                       apr_pool_t *pool)
 {
+  apr_status_t status = apr_file_read_full(file, buf, nbytes, bytes_read);
+  if (hit_eof)
+    if (APR_STATUS_IS_EOF(status))
+      {
+        *hit_eof = TRUE;
+        return SVN_NO_ERROR;
+      }
+    else
+      *hit_eof = FALSE;
+
   return do_io_file_wrapper_cleanup
-    (file, apr_file_read_full(file, buf, nbytes, bytes_read),
+    (file, status,
      N_("Can't read file '%s'"),
      N_("Can't read stream"),
      pool);
@@ -3081,25 +3103,25 @@ svn_io_file_write_full(apr_file_t *file,
                        apr_size_t nbytes, apr_size_t *bytes_written,
                        apr_pool_t *pool)
 {
-  apr_status_t rv = apr_file_write_full(file, buf, nbytes, bytes_written);
-
 #ifdef WIN32
 #define MAXBUFSIZE 30*1024
-  if (rv == APR_FROM_OS_ERROR(ERROR_NOT_ENOUGH_MEMORY)
-      && nbytes > MAXBUFSIZE)
-    {
-      apr_size_t bw = 0;
-      *bytes_written = 0;
-
-      do {
-        rv = apr_file_write_full(file, buf,
-                                 nbytes > MAXBUFSIZE ? MAXBUFSIZE : nbytes, &bw);
-        *bytes_written += bw;
-        buf = (char *)buf + bw;
-        nbytes -= bw;
-      } while (rv == APR_SUCCESS && nbytes > 0);
-    }
+  apr_status_t rv;
+  apr_size_t bw = 0;
+  apr_size_t to_write = nbytes;
+
+  do {
+    bw = to_write > MAXBUFSIZE ? MAXBUFSIZE : to_write;
+    rv = apr_file_write(file, buf, &bw);
+    buf = (char *)buf + bw;
+    to_write -= bw;
+  } while (rv == APR_SUCCESS && to_write > 0);
+
+  /* bytes_written may actually be NULL */
+  if (bytes_written)
+    *bytes_written = nbytes - to_write;
 #undef MAXBUFSIZE
+#else
+  apr_status_t rv = apr_file_write_full(file, buf, nbytes, bytes_written);
 #endif
 
   return svn_error_return(do_io_file_wrapper_cleanup(
@@ -3334,14 +3356,12 @@ dir_make(const char *path, apr_fileperms
 #else 
     /* on Windows, use our wrapper so we can also set the 
        FILE_ATTRIBUTE_NOT_CONTENT_INDEXED attribute */
-    status = apr_win_file_attrs_set(path_apr,
-                                    FILE_ATTRIBUTE_HIDDEN | 
-                                    FILE_ATTRIBUTE_NOT_CONTENT_INDEXED |
-                                    FILE_ATTRIBUTE_DIRECTORY,
-                                    FILE_ATTRIBUTE_HIDDEN | 
-                                    FILE_ATTRIBUTE_NOT_CONTENT_INDEXED |
-                                    FILE_ATTRIBUTE_DIRECTORY,
-                                    pool);
+    status = io_win_file_attrs_set(path_apr,
+                                   FILE_ATTRIBUTE_HIDDEN | 
+                                   FILE_ATTRIBUTE_NOT_CONTENT_INDEXED,
+                                   FILE_ATTRIBUTE_HIDDEN | 
+                                   FILE_ATTRIBUTE_NOT_CONTENT_INDEXED,
+                                   pool);
 
 #endif
       if (status)
@@ -3773,8 +3793,8 @@ contents_identical_p(svn_boolean_t *iden
   char *buf2 = apr_palloc(pool, SVN__STREAM_CHUNK_SIZE);
   apr_file_t *file1_h = NULL;
   apr_file_t *file2_h = NULL;
-  svn_boolean_t done1 = FALSE;
-  svn_boolean_t done2 = FALSE;
+  svn_boolean_t eof1 = FALSE;
+  svn_boolean_t eof2 = FALSE;
 
   SVN_ERR(svn_io_file_open(&file1_h, file1, APR_READ, APR_OS_DEFAULT,
                            pool));
@@ -3788,39 +3808,32 @@ contents_identical_p(svn_boolean_t *iden
                                         svn_io_file_close(file1_h, pool)));
 
   *identical_p = TRUE;  /* assume TRUE, until disproved below */
-  while (! (done1 || done2))
+  while (!err && !eof1 && !eof2)
     {
-      err = svn_io_file_read_full(file1_h, buf1,
-                                  SVN__STREAM_CHUNK_SIZE, &bytes_read1, pool);
-      if (err && APR_STATUS_IS_EOF(err->apr_err))
-        {
-          svn_error_clear(err);
-          err = NULL;
-          done1 = TRUE;
-        }
-      else if (err)
-        break;
+      err = svn_io_file_read_full2(file1_h, buf1,
+                                   SVN__STREAM_CHUNK_SIZE, &bytes_read1,
+                                   &eof1, pool);
+      if (err)
+          break;
 
-      err = svn_io_file_read_full(file2_h, buf2,
-                                  SVN__STREAM_CHUNK_SIZE, &bytes_read2, pool);
-      if (err && APR_STATUS_IS_EOF(err->apr_err))
-        {
-          svn_error_clear(err);
-          err = NULL;
-          done2 = TRUE;
-        }
-      else if (err)
-        break;
+      err = svn_io_file_read_full2(file2_h, buf2,
+                                   SVN__STREAM_CHUNK_SIZE, &bytes_read2,
+                                   &eof2, pool);
+      if (err)
+          break;
 
-      if ((bytes_read1 != bytes_read2)
-          || (done1 != done2)
-          || (memcmp(buf1, buf2, bytes_read1)))
+      if ((bytes_read1 != bytes_read2) || memcmp(buf1, buf2, bytes_read1))
         {
           *identical_p = FALSE;
           break;
         }
     }
 
+  /* Special case: one file being a prefix of the other and the shorter
+   * file's size is a multiple of SVN__STREAM_CHUNK_SIZE. */
+  if (!err && (eof1 != eof2))
+    *identical_p = FALSE;
+
   return svn_error_return(
            svn_error_compose_create(
                 err,

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/sqlite.c?rev=1073138&r1=1073137&r2=1073138&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/sqlite.c Mon Feb 21 20:40:44 2011
@@ -63,6 +63,15 @@ sqlite_tracer(void *data, const char *sq
 }
 #endif
 
+#ifdef SQLITE3_PROFILE
+/* An sqlite execution timing callback. */
+static void
+sqlite_profiler(void *data, const char *sql, sqlite3_uint64 duration)
+{
+  /*  sqlite3 *db3 = data; */
+  SVN_DBG(("[%.3f] sql=\"%s\"\n", 1e-9 * duration, sql));
+}
+#endif
 
 struct svn_sqlite__db_t
 {
@@ -917,6 +926,9 @@ svn_sqlite__open(svn_sqlite__db_t **db, 
 #ifdef SQLITE3_DEBUG
   sqlite3_trace((*db)->db3, sqlite_tracer, (*db)->db3);
 #endif
+#ifdef SQLITE3_PROFILE
+  sqlite3_profile((*db)->db3, sqlite_profiler, (*db)->db3);
+#endif
 
   SVN_ERR(exec_sql(*db,
               "PRAGMA case_sensitive_like=1;"
@@ -987,15 +999,16 @@ svn_sqlite__close(svn_sqlite__db_t *db)
   return svn_error_wrap_apr(result, NULL);
 }
 
-svn_error_t *
-svn_sqlite__with_transaction(svn_sqlite__db_t *db,
-                             svn_sqlite__transaction_callback_t cb_func,
-                             void *cb_baton,
-                             apr_pool_t *scratch_pool /* NULL allowed */)
+/* The body of svn_sqlite__with_transaction() and
+   svn_sqlite__with_immediate_transaction(), which see. */
+static svn_error_t *
+with_transaction(svn_sqlite__db_t *db,
+                 svn_sqlite__transaction_callback_t cb_func,
+                 void *cb_baton,
+                 apr_pool_t *scratch_pool /* NULL allowed */)
 {
   svn_error_t *err;
 
-  SVN_ERR(exec_sql(db, "BEGIN TRANSACTION;"));
   err = cb_func(cb_baton, db, scratch_pool);
 
   /* Commit or rollback the sqlite transaction. */
@@ -1051,6 +1064,28 @@ svn_sqlite__with_transaction(svn_sqlite_
 }
 
 svn_error_t *
+svn_sqlite__with_transaction(svn_sqlite__db_t *db,
+                             svn_sqlite__transaction_callback_t cb_func,
+                             void *cb_baton,
+                             apr_pool_t *scratch_pool /* NULL allowed */)
+{
+  SVN_ERR(exec_sql(db, "BEGIN TRANSACTION;"));
+  return svn_error_return(with_transaction(db, cb_func, cb_baton,
+                                           scratch_pool));
+}
+
+svn_error_t *
+svn_sqlite__with_immediate_transaction(svn_sqlite__db_t *db,
+                                       svn_sqlite__transaction_callback_t cb_func,
+                                       void *cb_baton,
+                                       apr_pool_t *scratch_pool /* NULL allowed */)
+{
+  SVN_ERR(exec_sql(db, "BEGIN IMMEDIATE TRANSACTION;"));
+  return svn_error_return(with_transaction(db, cb_func, cb_baton,
+                                           scratch_pool));
+}
+
+svn_error_t *
 svn_sqlite__with_lock(svn_sqlite__db_t *db,
                       svn_sqlite__transaction_callback_t cb_func,
                       void *cb_baton,

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/stream.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/stream.c?rev=1073138&r1=1073137&r2=1073138&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/stream.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/stream.c Mon Feb 21 20:40:44 2011
@@ -49,9 +49,11 @@ struct svn_stream_t {
   void *baton;
   svn_read_fn_t read_fn;
   svn_write_fn_t write_fn;
+  svn_skip_fn_t skip_fn;
   svn_close_fn_t close_fn;
   svn_io_mark_fn_t mark_fn;
   svn_io_seek_fn_t seek_fn;
+  svn_io_buffered_fn_t buffered_fn;
 };
 
 
@@ -65,10 +67,12 @@ svn_stream_create(void *baton, apr_pool_
   stream = apr_palloc(pool, sizeof(*stream));
   stream->baton = baton;
   stream->read_fn = NULL;
+  stream->skip_fn = NULL;
   stream->write_fn = NULL;
   stream->close_fn = NULL;
   stream->mark_fn = NULL;
   stream->seek_fn = NULL;
+  stream->buffered_fn = NULL;
   return stream;
 }
 
@@ -86,6 +90,11 @@ svn_stream_set_read(svn_stream_t *stream
   stream->read_fn = read_fn;
 }
 
+void
+svn_stream_set_skip(svn_stream_t *stream, svn_skip_fn_t skip_fn)
+{
+  stream->skip_fn = skip_fn;
+}
 
 void
 svn_stream_set_write(svn_stream_t *stream, svn_write_fn_t write_fn)
@@ -111,6 +120,13 @@ svn_stream_set_seek(svn_stream_t *stream
   stream->seek_fn = seek_fn;
 }
 
+void
+svn_stream_set_buffered(svn_stream_t *stream,
+                        svn_io_buffered_fn_t buffered_fn)
+{
+  stream->buffered_fn = buffered_fn;
+}
+
 svn_error_t *
 svn_stream_read(svn_stream_t *stream, char *buffer, apr_size_t *len)
 {
@@ -120,6 +136,14 @@ svn_stream_read(svn_stream_t *stream, ch
 
 
 svn_error_t *
+svn_stream_skip(svn_stream_t *stream, apr_size_t *count)
+{
+  SVN_ERR_ASSERT(stream->skip_fn != NULL);
+  return stream->skip_fn(stream->baton, count);
+}
+
+
+svn_error_t *
 svn_stream_write(svn_stream_t *stream, const char *data, apr_size_t *len)
 {
   SVN_ERR_ASSERT(stream->write_fn != NULL);
@@ -134,6 +158,12 @@ svn_stream_reset(svn_stream_t *stream)
             svn_stream_seek(stream, NULL));
 }
 
+svn_boolean_t
+svn_stream_supports_mark(svn_stream_t *stream)
+{
+  return stream->mark_fn == NULL ? FALSE : TRUE;
+}
+
 svn_error_t *
 svn_stream_mark(svn_stream_t *stream, svn_stream_mark_t **mark,
                 apr_pool_t *pool)
@@ -145,7 +175,7 @@ svn_stream_mark(svn_stream_t *stream, sv
 }
 
 svn_error_t *
-svn_stream_seek(svn_stream_t *stream, svn_stream_mark_t *mark)
+svn_stream_seek(svn_stream_t *stream, const svn_stream_mark_t *mark)
 {
   if (stream->seek_fn == NULL)
     return svn_error_create(SVN_ERR_STREAM_SEEK_NOT_SUPPORTED, NULL, NULL);
@@ -153,6 +183,15 @@ svn_stream_seek(svn_stream_t *stream, sv
   return stream->seek_fn(stream->baton, mark);
 }
 
+svn_boolean_t 
+svn_stream_buffered(svn_stream_t *stream)
+{
+  if (stream->buffered_fn == NULL)
+    return FALSE;
+
+  return stream->buffered_fn(stream->baton);
+}
+
 svn_error_t *
 svn_stream_close(svn_stream_t *stream)
 {
@@ -406,6 +445,31 @@ svn_stream_contents_same2(svn_boolean_t 
                                     svn_stream_close(stream2)));
 }
 
+
+/*** Stream implementation utilities ***/
+
+/* Skip data from any stream by reading and simply discarding it. */
+static svn_error_t *
+skip_default_handler(void *baton, apr_size_t *count, svn_read_fn_t read_fn)
+{
+  apr_size_t total_bytes_read = 0;
+  apr_size_t bytes_read = 1;
+  char buffer[4096];
+  svn_error_t *err = SVN_NO_ERROR;
+  apr_size_t to_read = *count;
+
+  while ((to_read > 0) && !err && (bytes_read > 0))
+    {
+      bytes_read = sizeof(buffer) < to_read ? sizeof(buffer) : to_read;
+      err = read_fn(baton, buffer, &bytes_read);
+      total_bytes_read += bytes_read;
+      to_read -= bytes_read;
+    }
+
+  *count = total_bytes_read;
+  return err;
+}
+
 
 
 /*** Generic readable empty stream ***/
@@ -417,6 +481,12 @@ read_handler_empty(void *baton, char *bu
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+skip_handler_empty(void *baton, apr_size_t *count)
+{
+  *count = 0;
+  return SVN_NO_ERROR;
+}
 
 static svn_error_t *
 write_handler_empty(void *baton, const char *data, apr_size_t *len)
@@ -432,11 +502,17 @@ mark_handler_empty(void *baton, svn_stre
 }
 
 static svn_error_t *
-seek_handler_empty(void *baton, svn_stream_mark_t *mark)
+seek_handler_empty(void *baton, const svn_stream_mark_t *mark)
 {
   return SVN_NO_ERROR;
 }
 
+static svn_boolean_t
+buffered_handler_empty(void *baton)
+{
+  return FALSE;
+}
+
 
 svn_stream_t *
 svn_stream_empty(apr_pool_t *pool)
@@ -445,9 +521,11 @@ svn_stream_empty(apr_pool_t *pool)
 
   stream = svn_stream_create(NULL, pool);
   svn_stream_set_read(stream, read_handler_empty);
+  svn_stream_set_skip(stream, skip_handler_empty);
   svn_stream_set_write(stream, write_handler_empty);
   svn_stream_set_mark(stream, mark_handler_empty);
   svn_stream_set_seek(stream, seek_handler_empty);
+  svn_stream_set_buffered(stream, buffered_handler_empty);
   return stream;
 }
 
@@ -519,6 +597,12 @@ read_handler_disown(void *baton, char *b
 }
 
 static svn_error_t *
+skip_handler_disown(void *baton, apr_size_t *count)
+{
+  return svn_stream_skip(baton, count);
+}
+
+static svn_error_t *
 write_handler_disown(void *baton, const char *buffer, apr_size_t *len)
 {
   return svn_stream_write(baton, buffer, len);
@@ -531,20 +615,28 @@ mark_handler_disown(void *baton, svn_str
 }
 
 static svn_error_t *
-seek_handler_disown(void *baton, svn_stream_mark_t *mark)
+seek_handler_disown(void *baton, const svn_stream_mark_t *mark)
 {
   return svn_stream_seek(baton, mark);
 }
 
+static svn_boolean_t
+buffered_handler_disown(void *baton)
+{
+  return svn_stream_buffered(baton);
+}
+
 svn_stream_t *
 svn_stream_disown(svn_stream_t *stream, apr_pool_t *pool)
 {
   svn_stream_t *s = svn_stream_create(stream, pool);
 
   svn_stream_set_read(s, read_handler_disown);
+  svn_stream_set_skip(s, skip_handler_disown);
   svn_stream_set_write(s, write_handler_disown);
   svn_stream_set_mark(s, mark_handler_disown);
   svn_stream_set_seek(s, seek_handler_disown);
+  svn_stream_set_buffered(s, buffered_handler_disown);
 
   return s;
 }
@@ -567,13 +659,49 @@ read_handler_apr(void *baton, char *buff
 {
   struct baton_apr *btn = baton;
   svn_error_t *err;
+  svn_boolean_t eof;
 
-  err = svn_io_file_read_full(btn->file, buffer, *len, len, btn->pool);
-  if (err && APR_STATUS_IS_EOF(err->apr_err))
+  if (*len == 1)
     {
-      svn_error_clear(err);
-      err = SVN_NO_ERROR;
+      err = svn_io_file_getc(buffer, btn->file, btn->pool);
+      if (err)
+        {
+          *len = 0;
+          if (APR_STATUS_IS_EOF(err->apr_err))
+            {
+              svn_error_clear(err);
+              err = SVN_NO_ERROR;
+            }
+        }
     }
+  else
+    err = svn_io_file_read_full2(btn->file, buffer, *len, len,
+                                 &eof, btn->pool);
+
+  return err;
+}
+
+static svn_error_t *
+skip_handler_apr(void *baton, apr_size_t *count)
+{
+  struct baton_apr *btn = baton;
+  apr_off_t offset = *count;
+  apr_off_t new_pos = *count;
+  apr_off_t current = 0;
+  svn_error_t *err;
+
+  /* so far, we have not moved anything */
+  *count = 0;
+
+  SVN_ERR(svn_io_file_seek(btn->file, APR_CUR, &current, btn->pool));
+  err = svn_io_file_seek(btn->file, APR_CUR, &new_pos, btn->pool);
+
+  /* Irrespective of errors, return the number of bytes we actually moved.
+   * If no new position has been returned from seek(), assume that no move
+   * happend and keep the *count==0 set earlier.
+   */
+  if ((offset != new_pos) || (current == 0))
+    *count = new_pos - current;
 
   return err;
 }
@@ -582,8 +710,18 @@ static svn_error_t *
 write_handler_apr(void *baton, const char *data, apr_size_t *len)
 {
   struct baton_apr *btn = baton;
+  svn_error_t *err;
+
+  if (*len == 1)
+    {
+      err = svn_io_file_putc(*data, btn->file, btn->pool);
+      if (err)
+        *len = 0;
+    }
+  else
+    err = svn_io_file_write_full(btn->file, data, *len, len, btn->pool);
 
-  return svn_io_file_write_full(btn->file, data, *len, len, btn->pool);
+  return err;
 }
 
 static svn_error_t *
@@ -608,26 +746,23 @@ mark_handler_apr(void *baton, svn_stream
 }
 
 static svn_error_t *
-seek_handler_apr(void *baton, svn_stream_mark_t *mark)
+seek_handler_apr(void *baton, const svn_stream_mark_t *mark)
 {
   struct baton_apr *btn = baton;
+  apr_off_t offset = (mark != NULL) ? ((const struct mark_apr *)mark)->off : 0;
 
-  if (mark != NULL)
-    {
-      struct mark_apr *mark_apr;
-
-      mark_apr = (struct mark_apr *)mark;
-      SVN_ERR(svn_io_file_seek(btn->file, APR_SET, &mark_apr->off, btn->pool));
-    }
-  else
-    {
-      apr_off_t offset = 0;
-      SVN_ERR(svn_io_file_seek(btn->file, APR_SET, &offset, btn->pool));
-    }
+  SVN_ERR(svn_io_file_seek(btn->file, APR_SET, &offset, btn->pool));
 
   return SVN_NO_ERROR;
 }
 
+static svn_boolean_t
+buffered_handler_apr(void *baton)
+{
+  struct baton_apr *btn = baton;
+  return (apr_file_flags_get(btn->file) & APR_BUFFERED) != 0;
+}
+
 svn_error_t *
 svn_stream_open_readonly(svn_stream_t **stream,
                          const char *path,
@@ -700,8 +835,10 @@ svn_stream_from_aprfile2(apr_file_t *fil
   stream = svn_stream_create(baton, pool);
   svn_stream_set_read(stream, read_handler_apr);
   svn_stream_set_write(stream, write_handler_apr);
+  svn_stream_set_skip(stream, skip_handler_apr);
   svn_stream_set_mark(stream, mark_handler_apr);
   svn_stream_set_seek(stream, seek_handler_apr);
+  svn_stream_set_buffered(stream, buffered_handler_apr);
 
   if (! disown)
     svn_stream_set_close(stream, close_handler_apr);
@@ -876,6 +1013,13 @@ read_handler_gz(void *baton, char *buffe
   return SVN_NO_ERROR;
 }
 
+/* Skip data from a compressed stream by reading and discarding it. */
+static svn_error_t *
+skip_handler_gz(void *baton, apr_size_t *count)
+{
+  return skip_default_handler(baton, count, read_handler_gz);
+}
+
 /* Compress data and write it to the substream */
 static svn_error_t *
 write_handler_gz(void *baton, const char *buffer, apr_size_t *len)
@@ -989,6 +1133,7 @@ svn_stream_compressed(svn_stream_t *stre
 
   zstream = svn_stream_create(baton, pool);
   svn_stream_set_read(zstream, read_handler_gz);
+  svn_stream_set_skip(zstream, skip_handler_gz);
   svn_stream_set_write(zstream, write_handler_gz);
   svn_stream_set_close(zstream, close_handler_gz);
 
@@ -1031,6 +1176,13 @@ read_handler_checksum(void *baton, char 
 
 
 static svn_error_t *
+skip_handler_checksum(void *baton, apr_size_t *count)
+{
+  return skip_default_handler(baton, count, read_handler_checksum);
+}
+
+
+static svn_error_t *
 write_handler_checksum(void *baton, const char *buffer, apr_size_t *len)
 {
   struct checksum_stream_baton *btn = baton;
@@ -1104,6 +1256,7 @@ svn_stream_checksummed2(svn_stream_t *st
 
   s = svn_stream_create(baton, pool);
   svn_stream_set_read(s, read_handler_checksum);
+  svn_stream_set_skip(s, skip_handler_checksum);
   svn_stream_set_write(s, write_handler_checksum);
   svn_stream_set_close(s, close_handler_checksum);
   return s;
@@ -1127,6 +1280,13 @@ read_handler_md5(void *baton, char *buff
 }
 
 static svn_error_t *
+skip_handler_md5(void *baton, apr_size_t *count)
+{
+  struct md5_stream_baton *btn = baton;
+  return svn_stream_skip(btn->proxy, count);
+}
+
+static svn_error_t *
 write_handler_md5(void *baton, const char *buffer, apr_size_t *len)
 {
   struct md5_stream_baton *btn = baton;
@@ -1186,6 +1346,7 @@ svn_stream_checksummed(svn_stream_t *str
    * want them) after it closes BATON->proxy. */
   s = svn_stream_create(baton, pool);
   svn_stream_set_read(s, read_handler_md5);
+  svn_stream_set_skip(s, skip_handler_md5);
   svn_stream_set_write(s, write_handler_md5);
   svn_stream_set_close(s, close_handler_md5);
   return s;
@@ -1219,6 +1380,17 @@ read_handler_stringbuf(void *baton, char
 }
 
 static svn_error_t *
+skip_handler_stringbuf(void *baton, apr_size_t *count)
+{
+  struct stringbuf_stream_baton *btn = baton;
+  apr_size_t left_to_read = btn->str->len - btn->amt_read;
+
+  *count = (*count > left_to_read) ? left_to_read : *count;
+  btn->amt_read += *count;
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
 write_handler_stringbuf(void *baton, const char *data, apr_size_t *len)
 {
   struct stringbuf_stream_baton *btn = baton;
@@ -1242,15 +1414,15 @@ mark_handler_stringbuf(void *baton, svn_
 }
 
 static svn_error_t *
-seek_handler_stringbuf(void *baton, svn_stream_mark_t *mark)
+seek_handler_stringbuf(void *baton, const svn_stream_mark_t *mark)
 {
   struct stringbuf_stream_baton *btn = baton;
 
   if (mark != NULL)
     {
-      struct stringbuf_stream_mark *stringbuf_stream_mark;
+      const struct stringbuf_stream_mark *stringbuf_stream_mark;
 
-      stringbuf_stream_mark = (struct stringbuf_stream_mark *)mark;
+      stringbuf_stream_mark = (const struct stringbuf_stream_mark *)mark;
       btn->amt_read = stringbuf_stream_mark->pos;
     }
   else
@@ -1259,6 +1431,12 @@ seek_handler_stringbuf(void *baton, svn_
   return SVN_NO_ERROR;
 }
 
+static svn_boolean_t
+buffered_handler_stringbuf(void *baton)
+{
+  return TRUE;
+}
+
 svn_stream_t *
 svn_stream_from_stringbuf(svn_stringbuf_t *str,
                           apr_pool_t *pool)
@@ -1274,9 +1452,11 @@ svn_stream_from_stringbuf(svn_stringbuf_
   baton->amt_read = 0;
   stream = svn_stream_create(baton, pool);
   svn_stream_set_read(stream, read_handler_stringbuf);
+  svn_stream_set_skip(stream, skip_handler_stringbuf);
   svn_stream_set_write(stream, write_handler_stringbuf);
   svn_stream_set_mark(stream, mark_handler_stringbuf);
   svn_stream_set_seek(stream, seek_handler_stringbuf);
+  svn_stream_set_buffered(stream, buffered_handler_stringbuf);
   return stream;
 }
 
@@ -1318,15 +1498,15 @@ mark_handler_string(void *baton, svn_str
 }
 
 static svn_error_t *
-seek_handler_string(void *baton, svn_stream_mark_t *mark)
+seek_handler_string(void *baton, const svn_stream_mark_t *mark)
 {
   struct string_stream_baton *btn = baton;
 
   if (mark != NULL)
     {
-      struct string_stream_mark *marker;
+      const struct string_stream_mark *marker;
 
-      marker = (struct string_stream_mark *)mark;
+      marker = (const struct string_stream_mark *)mark;
       btn->amt_read = marker->pos;
     }
   else
@@ -1335,6 +1515,23 @@ seek_handler_string(void *baton, svn_str
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+skip_handler_string(void *baton, apr_size_t *count)
+{
+  struct string_stream_baton *btn = baton;
+  apr_size_t left_to_read = btn->str->len - btn->amt_read;
+
+  *count = (*count > left_to_read) ? left_to_read : *count;
+  btn->amt_read += *count;
+  return SVN_NO_ERROR;
+}
+
+static svn_boolean_t
+buffered_handler_string(void *baton)
+{
+  return TRUE;
+}
+
 svn_stream_t *
 svn_stream_from_string(const svn_string_t *str,
                        apr_pool_t *pool)
@@ -1352,6 +1549,8 @@ svn_stream_from_string(const svn_string_
   svn_stream_set_read(stream, read_handler_string);
   svn_stream_set_mark(stream, mark_handler_string);
   svn_stream_set_seek(stream, seek_handler_string);
+  svn_stream_set_skip(stream, skip_handler_string);
+  svn_stream_set_buffered(stream, buffered_handler_string);
   return stream;
 }
 
@@ -1373,6 +1572,22 @@ svn_stream_for_stdout(svn_stream_t **out
 
 
 svn_error_t *
+svn_stream_for_stderr(svn_stream_t **err, apr_pool_t *pool)
+{
+  apr_file_t *stderr_file;
+  apr_status_t apr_err;
+
+  apr_err = apr_file_open_stderr(&stderr_file, pool);
+  if (apr_err)
+    return svn_error_wrap_apr(apr_err, "Can't open stderr");
+
+  *err = svn_stream_from_aprfile2(stderr_file, TRUE, pool);
+
+  return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
 svn_string_from_stream(svn_string_t **result,
                        svn_stream_t *stream,
                        apr_pool_t *result_pool,

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/subst.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/subst.c?rev=1073138&r1=1073137&r2=1073138&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/subst.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/subst.c Mon Feb 21 20:40:44 2011
@@ -1249,6 +1249,29 @@ translated_stream_read(void *baton,
   return SVN_NO_ERROR;
 }
 
+/* Implements svn_skip_fn_t. */
+static svn_error_t *
+translated_stream_skip(void *baton,
+                       apr_size_t *count)
+{
+  apr_size_t total_bytes_read = 0;
+  apr_size_t bytes_read = 1;
+  char buffer[SVN__STREAM_CHUNK_SIZE];
+  svn_error_t *err = SVN_NO_ERROR;
+  apr_size_t to_read = *count;
+
+  while ((to_read > 0) && !err && (bytes_read > 0))
+    {
+      bytes_read = sizeof(buffer) < to_read ? sizeof(buffer) : to_read;
+      err = translated_stream_read(baton, buffer, &bytes_read);
+      total_bytes_read += bytes_read;
+      to_read -= bytes_read;
+    }
+
+  *count = total_bytes_read;
+  return err;
+}
+
 /* Implements svn_write_fn_t. */
 static svn_error_t *
 translated_stream_write(void *baton,
@@ -1316,13 +1339,13 @@ translated_stream_mark(void *baton, svn_
 
 /* Implements svn_io_seek_fn_t. */
 static svn_error_t *
-translated_stream_seek(void *baton, svn_stream_mark_t *mark)
+translated_stream_seek(void *baton, const svn_stream_mark_t *mark)
 {
   struct translated_stream_baton *b = baton;
 
   if (mark != NULL)
     {
-      mark_translated_t *mt = (mark_translated_t *)mark;
+      const mark_translated_t *mt = (const mark_translated_t *)mark;
 
       /* Flush output buffer if necessary. */
       if (b->written)
@@ -1360,6 +1383,14 @@ translated_stream_seek(void *baton, svn_
   return SVN_NO_ERROR;
 }
 
+/* Implements svn_io_buffered_fn_t. */
+static svn_boolean_t
+translated_stream_buffered(void *baton)
+{
+  struct translated_stream_baton *b = baton;
+  return svn_stream_buffered(b->stream);
+}
+
 svn_error_t *
 svn_subst_read_specialfile(svn_stream_t **stream,
                            const char *path,
@@ -1465,10 +1496,12 @@ stream_translated(svn_stream_t *stream,
 
   /* Setup the stream methods */
   svn_stream_set_read(s, translated_stream_read);
+  svn_stream_set_skip(s, translated_stream_skip);
   svn_stream_set_write(s, translated_stream_write);
   svn_stream_set_close(s, translated_stream_close);
   svn_stream_set_mark(s, translated_stream_mark);
   svn_stream_set_seek(s, translated_stream_seek);
+  svn_stream_set_buffered(s, translated_stream_buffered);
 
   return s;
 }

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/svn_string.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/svn_string.c?rev=1073138&r1=1073137&r2=1073138&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/svn_string.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/svn_string.c Mon Feb 21 20:40:44 2011
@@ -135,9 +135,18 @@ create_string(const char *data, apr_size
 svn_string_t *
 svn_string_ncreate(const char *bytes, apr_size_t size, apr_pool_t *pool)
 {
+  void *mem;
   char *data;
+  svn_string_t *new_string;
+
+  /* Allocate memory for svn_string_t and data in one chunk. */
+  mem = apr_palloc(pool, sizeof(*new_string) + size + 1);
+  data = (char*)mem + sizeof(*new_string);
+
+  new_string = mem;
+  new_string->data = data;
+  new_string->len = size;
 
-  data = apr_palloc(pool, size + 1);
   memcpy(data, bytes, size);
 
   /* Null termination is the convention -- even if we suspect the data
@@ -145,8 +154,7 @@ svn_string_ncreate(const char *bytes, ap
      call.  Heck, that's why they call it the caller! */
   data[size] = '\0';
 
-  /* wrap an svn_string_t around the new data */
-  return create_string(data, size, pool);
+  return new_string;
 }
 
 
@@ -631,6 +639,22 @@ svn_boolean_t svn_cstring_match_glob_lis
   return FALSE;
 }
 
+svn_boolean_t
+svn_cstring_match_list(const char *str, const apr_array_header_t *list)
+{
+  int i;
+
+  for (i = 0; i < list->nelts; i++)
+    {
+      const char *this_str = APR_ARRAY_IDX(list, i, char *);
+
+      if (strcmp(this_str, str) == 0)
+        return TRUE;
+    }
+
+  return FALSE;
+}
+
 int svn_cstring_count_newlines(const char *msg)
 {
   int count = 0;

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/win32_crypto.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/win32_crypto.c?rev=1073138&r1=1073137&r2=1073138&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/win32_crypto.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/win32_crypto.c Mon Feb 21 20:40:44 2011
@@ -322,6 +322,28 @@ svn_auth_get_windows_ssl_client_cert_pw_
 /* CryptoApi.                                                            */
 /*-----------------------------------------------------------------------*/
 
+/* Helper to create CryptoAPI CERT_CONTEXT from base64 encoded BASE64_CERT.
+ * Returns NULL on error.
+ */
+static PCCERT_CONTEXT
+certcontext_from_base64(const char *base64_cert, apr_pool_t *pool)
+{
+  PCCERT_CONTEXT cert_context = NULL;
+  int cert_len;
+  BYTE *binary_cert;
+
+  /* Use apr-util as CryptStringToBinaryA is available only on XP+. */
+  binary_cert = apr_palloc(pool,
+                           apr_base64_decode_len(base64_cert));
+  cert_len = apr_base64_decode((char*)binary_cert, base64_cert);
+
+  /* Parse the certificate into a context. */
+  cert_context = CertCreateCertificateContext
+    (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, binary_cert, cert_len);
+
+  return cert_context;
+}
+
 /* Helper for windows_ssl_server_trust_first_credentials for validating
  * certificate using CryptoApi. Sets *OK_P to TRUE if base64 encoded ASCII_CERT
  * certificate considered as valid.
@@ -334,19 +356,11 @@ windows_validate_certificate(svn_boolean
   PCCERT_CONTEXT cert_context = NULL;
   CERT_CHAIN_PARA chain_para;
   PCCERT_CHAIN_CONTEXT chain_context = NULL;
-  int cert_len;
-  BYTE *binary_cert;
 
   *ok_p = FALSE;
 
-  /* Use apr-util as CryptStringToBinaryA is available only on XP+. */
-  binary_cert = apr_palloc(pool,
-                           apr_base64_decode_len(ascii_cert));
-  cert_len = apr_base64_decode((char*)binary_cert, ascii_cert);
-
   /* Parse the certificate into a context. */
-  cert_context = CertCreateCertificateContext
-    (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, binary_cert, cert_len);
+  cert_context = certcontext_from_base64(ascii_cert, pool);
 
   if (cert_context)
     {

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/adm_crawler.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/adm_crawler.c?rev=1073138&r1=1073137&r2=1073138&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/adm_crawler.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/adm_crawler.c Mon Feb 21 20:40:44 2011
@@ -1260,16 +1260,13 @@ svn_wc__internal_transmit_text_deltas(co
       if (tempfile)
         svn_error_clear(svn_io_remove_file2(*tempfile, TRUE, scratch_pool));
 
-      return svn_error_createf(SVN_ERR_WC_CORRUPT_TEXT_BASE, NULL,
-                               _("Checksum mismatch for text base of '%s':\n"
-                                 "   expected:  %s\n"
-                                 "     actual:  %s\n"),
-                               svn_dirent_local_style(local_abspath,
-                                                      scratch_pool),
-                               svn_checksum_to_cstring_display(
-                                 expected_md5_checksum, scratch_pool),
-                               svn_checksum_to_cstring_display(
-                                 verify_checksum, scratch_pool));
+      return svn_error_create(SVN_ERR_WC_CORRUPT_TEXT_BASE,
+            svn_checksum_mismatch_err(expected_md5_checksum, verify_checksum,
+                            scratch_pool,
+                            _("Checksum mismatch for text base of '%s'"),
+                            svn_dirent_local_style(local_abspath,
+                                                   scratch_pool)),
+            NULL);
     }
 
   /* Now, handle that delta transmission error if any, so we can stop

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/context.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/context.c?rev=1073138&r1=1073137&r2=1073138&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/context.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/context.c Mon Feb 21 20:40:44 2011
@@ -59,7 +59,7 @@ close_ctx_apr(void *data)
 
 svn_error_t *
 svn_wc_context_create(svn_wc_context_t **wc_ctx,
-                      svn_config_t *config,
+                      const svn_config_t *config,
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool)
 {

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/props.c?rev=1073138&r1=1073137&r2=1073138&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/props.c Mon Feb 21 20:40:44 2011
@@ -1711,6 +1711,7 @@ read_dir_props(const char *local_abspath
   SVN_ERR(svn_wc__db_read_props_of_immediates(b->db, local_abspath,
                                               b->receiver_func,
                                               b->receiver_baton,
+                                              NULL, NULL,
                                               scratch_pool));
   return SVN_NO_ERROR;
 }
@@ -1725,47 +1726,41 @@ svn_wc__prop_list_recursive(svn_wc_conte
                             void *cancel_baton,
                             apr_pool_t *scratch_pool)
 {
-  struct read_dir_props_baton read_dir_baton;
-
-  if (depth <= svn_depth_immediates)
-    {
-      apr_hash_t *props;
-
-      SVN_ERR(svn_wc__db_read_props(&props, wc_ctx->db, local_abspath,
-                                    scratch_pool, scratch_pool));
-      if (receiver_func && props && apr_hash_count(props) > 0)
-        SVN_ERR((*receiver_func)(receiver_baton, local_abspath, props,
-                                 scratch_pool));
-      if (depth == svn_depth_empty)
-        return SVN_NO_ERROR;
-    }
-
-  if (depth == svn_depth_files)
+  switch (depth)
     {
+    case svn_depth_empty:
+      {
+        apr_hash_t *props;
+
+        SVN_ERR(svn_wc__db_read_props(&props, wc_ctx->db, local_abspath,
+                                      scratch_pool, scratch_pool));
+        if (receiver_func && props && apr_hash_count(props) > 0)
+          SVN_ERR((*receiver_func)(receiver_baton, local_abspath, props,
+                                   scratch_pool));
+      }
+      break;
+    case  svn_depth_files:
       SVN_ERR(svn_wc__db_read_props_of_files(wc_ctx->db, local_abspath,
                                              receiver_func, receiver_baton,
+                                             cancel_func, cancel_baton,
                                              scratch_pool));
-      return SVN_NO_ERROR;
-    }
-
-  if (depth == svn_depth_immediates)
-    {
+      break;
+    case svn_depth_immediates:
       SVN_ERR(svn_wc__db_read_props_of_immediates(wc_ctx->db, local_abspath,
-                                                  receiver_func,
-                                                  receiver_baton,
+                                                  receiver_func, receiver_baton,
+                                                  cancel_func, cancel_baton,
                                                   scratch_pool));
-      return SVN_NO_ERROR;
+      break;
+    case svn_depth_infinity:
+      SVN_ERR(svn_wc__db_read_props_recursive(wc_ctx->db, local_abspath,
+                                              receiver_func, receiver_baton,
+                                              cancel_func, cancel_baton,
+                                              scratch_pool));
+      break;
+    default:
+      SVN_ERR_MALFUNCTION();
     }
 
-  read_dir_baton.db = wc_ctx->db;
-  read_dir_baton.root_abspath = local_abspath;
-  read_dir_baton.receiver_func = receiver_func;
-  read_dir_baton.receiver_baton = receiver_baton;
-
-  SVN_ERR(svn_wc__internal_walk_children(wc_ctx->db, local_abspath, FALSE,
-                                         read_dir_props, &read_dir_baton,
-                                         depth, cancel_func, cancel_baton,
-                                         scratch_pool));
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/questions.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/questions.c?rev=1073138&r1=1073137&r2=1073138&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/questions.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/questions.c Mon Feb 21 20:40:44 2011
@@ -198,16 +198,14 @@ compare_and_verify(svn_boolean_t *modifi
       if (verify_checksum && node_checksum)
         {
           if (checksum && !svn_checksum_match(checksum, node_checksum))
-            {
-              return svn_error_createf(SVN_ERR_WC_CORRUPT_TEXT_BASE, NULL,
-                   _("Checksum mismatch indicates corrupt text base for file: "
-                     "'%s':\n"
-                     "   expected:  %s\n"
-                     "     actual:  %s\n"),
-                  svn_dirent_local_style(versioned_file_abspath, scratch_pool),
-                  svn_checksum_to_cstring_display(node_checksum, scratch_pool),
-                  svn_checksum_to_cstring_display(checksum, scratch_pool));
-            }
+            return svn_error_create(SVN_ERR_WC_CORRUPT_TEXT_BASE,
+                    svn_checksum_mismatch_err(node_checksum, checksum,
+                                              scratch_pool,
+                                _("Checksum mismatch indicates corrupt "
+                                  "text base for file: '%s'"),
+                                svn_dirent_local_style(versioned_file_abspath,
+                                                       scratch_pool)),
+                    NULL);
         }
     }
   else

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/status.c?rev=1073138&r1=1073137&r2=1073138&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/status.c Mon Feb 21 20:40:44 2011
@@ -695,13 +695,21 @@ assemble_unversioned(svn_wc_status3_t **
 {
   svn_wc_status3_t *stat;
   const svn_wc_conflict_description2_t *tree_conflict;
+  svn_error_t *err;
 
   /* Find out whether the path is a tree conflict victim.
      This function will set tree_conflict to NULL if the path
      is not a victim. */
-  SVN_ERR(svn_wc__db_op_read_tree_conflict(&tree_conflict,
-                                           db, local_abspath,
-                                           scratch_pool, scratch_pool));
+  err = svn_wc__db_op_read_tree_conflict(&tree_conflict,
+                                         db, local_abspath,
+                                         scratch_pool, scratch_pool);
+  
+  if (path_kind == svn_node_dir && 
+      err && 
+      err->apr_err == SVN_ERR_WC_UPGRADE_REQUIRED)
+    svn_error_clear(err);
+  else
+    SVN_ERR(err);
 
   /* return a fairly blank structure. */
   stat = apr_pcalloc(result_pool, sizeof(**status));

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/update_editor.c?rev=1073138&r1=1073137&r2=1073138&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/update_editor.c Mon Feb 21 20:40:44 2011
@@ -4046,14 +4046,10 @@ close_file(void *file_baton,
   if (fb->new_text_base_md5_checksum && expected_md5_checksum
       && !svn_checksum_match(expected_md5_checksum,
                              fb->new_text_base_md5_checksum))
-    return svn_error_createf(SVN_ERR_CHECKSUM_MISMATCH, NULL,
-            _("Checksum mismatch for '%s':\n"
-              "   expected:  %s\n"
-              "     actual:  %s\n"),
-            svn_dirent_local_style(fb->local_abspath, pool),
-            expected_md5_digest,
-            svn_checksum_to_cstring_display(fb->new_text_base_md5_checksum,
-                                            pool));
+    return svn_checksum_mismatch_err(expected_md5_checksum,
+                            fb->new_text_base_md5_checksum, pool,
+                            _("Checksum mismatch for '%s'"),
+                            svn_dirent_local_style(fb->local_abspath, pool));
 
   SVN_ERR(svn_wc_read_kind(&kind, eb->wc_ctx, fb->local_abspath, TRUE, pool));
   if (kind == svn_node_none && ! fb->adding_file)
@@ -4233,7 +4229,7 @@ close_file(void *file_baton,
              from some random file means the fileinfo does NOT correspond to
              the pristine (in which case, the fileinfo will be cleared for
              safety's sake).  */
-          record_fileinfo = install_from == NULL;
+          record_fileinfo = (install_from == NULL);
 
           SVN_ERR(svn_wc__wq_build_file_install(&work_item,
                                                 eb->db,
@@ -5596,7 +5592,7 @@ svn_wc_add_repos_file4(svn_wc_context_t 
     /* If new contents were provided, then we do NOT want to record the
        file information. We assume the new contents do not match the
        "proper" values for TRANSLATED_SIZE and LAST_MOD_TIME.  */
-    record_fileinfo = new_contents == NULL;
+    record_fileinfo = (new_contents == NULL);
 
     /* Install the working copy file (with appropriate translation) from
        the appropriate source. SOURCE_ABSPATH will be NULL, indicating an

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/upgrade.c?rev=1073138&r1=1073137&r2=1073138&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/upgrade.c Mon Feb 21 20:40:44 2011
@@ -1137,6 +1137,13 @@ bump_to_24(void *baton, svn_sqlite__db_t
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+bump_to_25(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
+{
+  SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_25));
+  return SVN_NO_ERROR;
+}
+
 
 struct upgrade_data_t {
   svn_sqlite__db_t *sdb;
@@ -1263,8 +1270,6 @@ upgrade_to_wcng(void **dir_baton,
          entries_write_new() writes in current format rather than
          f12. Thus, this function bumps a working copy all the way to
          current.  */
-      SVN_ERR(svn_wc__db_temp_reset_format(SVN_WC__VERSION, db,
-                                           data->root_abspath, scratch_pool));
       SVN_ERR(svn_wc__db_wclock_obtain(db, data->root_abspath, 0, FALSE,
                                        scratch_pool));
     }
@@ -1404,6 +1409,12 @@ svn_wc__upgrade_sdb(int *result_format,
         *result_format = 24;
         /* FALLTHROUGH  */
 
+      case 24:
+        SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_25, &bb,
+                                             scratch_pool));
+        *result_format = 25;
+        /* FALLTHROUGH  */
+
       /* ### future bumps go here.  */
 #if 0
       case XXX-1:

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/wc-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/wc-metadata.sql?rev=1073138&r1=1073137&r2=1073138&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/wc-metadata.sql Mon Feb 21 20:40:44 2011
@@ -483,6 +483,16 @@ CREATE TABLE NODES (
 
 CREATE INDEX I_NODES_PARENT ON NODES (wc_id, parent_relpath, op_depth);
 
+/* Many queries have to filter the nodes table to pick only that version
+   of each node with the highest (most "current") op_depth.  This view
+   does the heavy lifting for such queries. */
+CREATE VIEW NODES_CURRENT AS
+  SELECT * FROM nodes
+    JOIN (SELECT wc_id, local_relpath, MAX(op_depth) AS op_depth FROM nodes
+          GROUP BY wc_id, local_relpath) AS filter
+    ON nodes.wc_id = filter.wc_id
+      AND nodes.local_relpath = filter.local_relpath
+      AND nodes.op_depth = filter.op_depth;
 
 -- STMT_CREATE_NODES_TRIGGERS
 
@@ -595,6 +605,21 @@ UPDATE pristine SET refcount =
 
 PRAGMA user_version = 24;
 
+/* ------------------------------------------------------------------------- */
+
+/* Format 25 introduces the NODES_CURRENT view. */
+
+-- STMT_UPGRADE_TO_25
+DROP VIEW IF EXISTS NODES_CURRENT;
+CREATE VIEW NODES_CURRENT AS
+  SELECT * FROM nodes
+    JOIN (SELECT wc_id, local_relpath, MAX(op_depth) AS op_depth FROM nodes
+          GROUP BY wc_id, local_relpath) AS filter
+    ON nodes.wc_id = filter.wc_id
+      AND nodes.local_relpath = filter.local_relpath
+      AND nodes.op_depth = filter.op_depth;
+
+PRAGMA user_version = 25;
 
 /* ------------------------------------------------------------------------- */
 

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/wc-queries.sql?rev=1073138&r1=1073137&r2=1073138&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/wc-queries.sql Mon Feb 21 20:40:44 2011
@@ -145,6 +145,14 @@ VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, 
 SELECT local_relpath FROM nodes
 WHERE wc_id = ?1 AND parent_relpath = ?2 AND op_depth = ?3;
 
+-- STMT_SELECT_GE_OP_DEPTH_CHILDREN
+SELECT 1 FROM nodes
+WHERE wc_id = ?1 AND parent_relpath = ?2
+  AND (op_depth > ?3 OR (op_depth = ?3 AND presence != 'base-deleted'))
+UNION
+SELECT 1 FROM ACTUAL_NODE
+WHERE wc_id = ?1 AND parent_relpath = ?2;
+
 -- STMT_SELECT_NODE_CHILDREN
 SELECT local_relpath FROM nodes
 WHERE wc_id = ?1 AND parent_relpath = ?2;
@@ -330,10 +338,19 @@ WHERE wc_id = ?1 AND local_relpath = ?2 
 DELETE FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2;
 
+-- STMT_DELETE_NODES_RECURSIVE
+DELETE FROM nodes
+WHERE wc_id = ?1 AND (local_relpath = ?2 OR local_relpath LIKE ?3 ESCAPE '#')
+  AND op_depth >= ?4;
+
 -- STMT_DELETE_ACTUAL_NODE
 DELETE FROM actual_node
 WHERE wc_id = ?1 AND local_relpath = ?2;
 
+-- STMT_DELETE_ACTUAL_NODE_RECURSIVE
+DELETE FROM actual_node
+WHERE wc_id = ?1 AND (local_relpath = ?2 OR local_relpath LIKE ?3 ESCAPE '#');
+
 -- STMT_DELETE_ACTUAL_NODE_WITHOUT_CONFLICT
 DELETE FROM actual_node
 WHERE wc_id = ?1 AND local_relpath = ?2
@@ -557,9 +574,13 @@ WHERE wc_id = ?1 AND local_relpath = ?2;
   AND op_depth = (SELECT MAX(op_depth) FROM nodes
                   WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > 0);
 
--- STMT_UPDATE_OP_DEPTH_RECURSIVE
-UPDATE nodes SET op_depth = ?3
-WHERE wc_id = ?1 AND local_relpath LIKE ?2 ESCAPE '#' AND op_depth = ?3 + 1;
+-- STMT_UPDATE_OP_DEPTH_REDUCE_RECURSIVE
+UPDATE nodes SET op_depth = ?3 - 1
+WHERE wc_id = ?1 AND local_relpath LIKE ?2 ESCAPE '#' AND op_depth = ?3;
+
+-- STMT_UPDATE_OP_DEPTH_INCREASE_RECURSIVE
+UPDATE nodes SET op_depth = ?3 + 1
+WHERE wc_id = ?1 AND local_relpath LIKE ?2 ESCAPE '#' AND op_depth = ?3;
 
 -- STMT_UPDATE_OP_DEPTH
 UPDATE nodes SET op_depth = ?4
@@ -648,6 +669,9 @@ FROM actual_node
 WHERE wc_id = ?1 AND (local_relpath = ?2 OR local_relpath LIKE ?3 ESCAPE '#')
   AND tree_conflict_data IS NULL;
 
+-- STMT_SELECT_ACTUAL_CHILDREN
+SELECT 1 FROM actual_node WHERE wc_id = ?1 AND parent_relpath = ?2;
+
 /* ------------------------------------------------------------------------- */
 
 /* these are used in entries.c  */
@@ -726,6 +750,61 @@ SELECT 1 FROM nodes WHERE op_depth > 0;
 UPDATE nodes SET checksum = ?4
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3;
 
+/* ------------------------------------------------------------------------- */
+/* PROOF OF CONCEPT: Complex queries for callback walks, caching results
+                     in a temporary table. */
+
+-- STMT_CLEAR_NODE_PROPS_CACHE
+DROP TABLE IF EXISTS temp__node_props_cache;
+
+-- STMT_CACHE_NODE_PROPS_RECURSIVE
+CREATE TEMPORARY TABLE temp__node_props_cache AS
+  SELECT local_relpath, kind, properties FROM nodes_current
+  WHERE wc_id = ?1
+    AND (?2 = '' OR local_relpath = ?2 OR local_relpath LIKE ?2 || '/%')
+    AND local_relpath NOT IN (
+      SELECT local_relpath FROM actual_node WHERE wc_id = ?1)
+    AND (presence = 'normal' OR presence = 'incomplete');
+CREATE UNIQUE INDEX temp__node_props_cache_unique
+  ON temp__node_props_cache (local_relpath);
+
+-- STMT_CACHE_ACTUAL_PROPS_RECURSIVE
+INSERT INTO temp__node_props_cache (local_relpath, kind, properties)
+  SELECT A.local_relpath, N.kind, A.properties
+  FROM actual_node AS A JOIN nodes_current AS N
+    ON A.wc_id = N.wc_id AND A.local_relpath = N.local_relpath
+       AND (N.presence = 'normal' OR N.presence = 'incomplete')
+  WHERE A.wc_id = ?1
+    AND (?2 = '' OR A.local_relpath = ?2 OR A.local_relpath LIKE ?2 || '/%')
+    AND A.local_relpath NOT IN
+      (SELECT local_relpath FROM temp__node_props_cache);
+
+-- STMT_CACHE_NODE_PROPS_OF_CHILDREN
+CREATE TEMPORARY TABLE temp__node_props_cache AS
+  SELECT local_relpath, kind, properties FROM nodes_current
+  WHERE wc_id = ?1
+    AND (local_relpath = ?2 OR parent_relpath = ?2)
+    AND local_relpath NOT IN (
+      SELECT local_relpath FROM actual_node WHERE wc_id = ?1)
+    AND (presence = 'normal' OR presence = 'incomplete');
+CREATE UNIQUE INDEX temp__node_props_cache_unique
+  ON temp__node_props_cache (local_relpath);
+
+-- STMT_CACHE_ACTUAL_PROPS_OF_CHILDREN
+INSERT INTO temp__node_props_cache (local_relpath, kind, properties)
+  SELECT A.local_relpath, N.kind, A.properties
+  FROM actual_node AS A JOIN nodes_current AS N
+    ON A.wc_id = N.wc_id AND A.local_relpath = N.local_relpath
+       AND (N.presence = 'normal' OR N.presence = 'incomplete')
+  WHERE A.wc_id = ?1
+    AND (A.local_relpath = ?2 OR A.parent_relpath = ?2)
+    AND A.local_relpath NOT IN
+      (SELECT local_relpath FROM temp__node_props_cache);
+
+-- STMT_SELECT_RELEVANT_PROPS_FROM_CACHE
+SELECT local_relpath, kind, properties FROM temp__node_props_cache
+ORDER BY local_relpath;
+
 
 /* ------------------------------------------------------------------------- */
 

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/wc.h?rev=1073138&r1=1073137&r2=1073138&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/wc.h (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/wc.h Mon Feb 21 20:40:44 2011
@@ -141,7 +141,7 @@ extern "C" {
  * Please document any further format changes here.
  */
 
-#define SVN_WC__VERSION 24
+#define SVN_WC__VERSION 25
 
 
 /* Formats <= this have no concept of "revert text-base/props".  */