[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] Re: Poor support for \ on windows from the C API?

From: D.J. Heap <dj_at_shadyvale.net>
Date: 2003-11-16 17:01:43 CET

Barry Scott wrote:
> DJ,
>
> There is a need for two functions. One to use when supplying input, the
> other to take output from svn and convert into native form.
>
> Maybe the output path version is simply a function that replaces each
> '/' with '\'? I believe I always know by context if its a URL or path
> and can avoid calling on a URL trivially.
>
> Barry
>

We already have those...svn_path_internal_style and svn_path_local_style
-- but they don't do case canonization or utf8 conversion or handle
urls. They seem to be for internal use mostly. Perhaps we should make
them more functional, though?

Here's a patch for converting input paths for the libraries. I agree
that we probably need one for the other direction, but I would like to
see what people think about this one.

Any objections or thoughts? If it looks like the direction is ok, then
I'll make a function for the other direction and clean them up a bit (to
use subpools for temp stuff mostly) and submit a real one.

DJ

Index: subversion/include/svn_path.h
===================================================================
--- subversion/include/svn_path.h (revision 7765)
+++ subversion/include/svn_path.h (working copy)
@@ -172,6 +172,14 @@
 const char *svn_path_canonicalize (const char *path, apr_pool_t *pool);
 
 
+/** Convert @a raw_target path or url to the library required form and return
+ * the results in @a *target, allocated in @a pool.
+ */
+svn_error_t *
+svn_path_convert_target (const char** target, const char *raw_target,
+ apr_pool_t *pool);
+
+
 /** Return an integer greater than, equal to, or less than 0, according
  * as @a path1 is greater than, equal to, or less than @a path2.
  */
Index: subversion/libsvn_subr/opt.c
===================================================================
--- subversion/libsvn_subr/opt.c (revision 7765)
+++ subversion/libsvn_subr/opt.c (working copy)
@@ -545,60 +545,32 @@
   for (i = 0; i < input_targets->nelts; i++)
     {
       const char *utf8_target = APR_ARRAY_IDX(input_targets, i, const char *);
- const char *target; /* after all processing is finished */
+ const char *raw_target;
+ const char *target;
 
+ /* convert from UTF-8 */
+ SVN_ERR (svn_path_cstring_from_utf8 (&raw_target, utf8_target,
+ pool));
+ /* canonicalize case, and change all separators to '/'. */
+ SVN_ERR (svn_path_convert_target (&target, raw_target, pool));
+ /* convert back to UTF-8. */
+ SVN_ERR (svn_path_cstring_to_utf8 (&utf8_target, target, pool));
+
       /* URLs and wc-paths get treated differently. */
- if (svn_path_is_url (utf8_target))
+ if (! svn_path_is_url (utf8_target))
         {
- /* No need to canonicalize a URL's case or path separators. */
- if (! svn_path_is_uri_safe (utf8_target))
- return svn_error_createf (SVN_ERR_BAD_URL, 0,
- "URL '%s' is not properly URI-encoded",
- utf8_target);
-
- /* strip any trailing '/' */
- target = svn_path_canonicalize (utf8_target, pool);
- }
- else /* not a url, so treat as a path */
- {
- const char *apr_target;
           const char *base_name;
- char *truenamed_target; /* APR-encoded */
- apr_status_t apr_err;
 
- /* canonicalize case, and change all separators to '/'. */
- SVN_ERR (svn_path_cstring_from_utf8 (&apr_target, utf8_target,
- pool));
- apr_err = apr_filepath_merge (&truenamed_target, "", apr_target,
- APR_FILEPATH_TRUENAME, pool);
-
- if (!apr_err)
- /* We have a canonicalized APR-encoded target now. */
- apr_target = truenamed_target;
- else if (APR_STATUS_IS_ENOENT (apr_err))
- /* It's okay for the file to not exist, that just means we
- have to accept the case given to the client. We'll use
- the original APR-encoded target. */
- ;
- else
- return svn_error_createf (apr_err, NULL,
- "Error resolving case of '%s'.",
- utf8_target);
-
- /* convert back to UTF-8. */
- SVN_ERR (svn_path_cstring_to_utf8 (&target, apr_target, pool));
- target = svn_path_canonicalize (target, pool);
-
           /* If this target is a Subversion administrative directory,
              skip it. TODO: Perhaps this check should not call the
              target a SVN admin dir unless svn_wc_check_wc passes on
              the target, too? */
- base_name = svn_path_basename (target, pool);
+ base_name = svn_path_basename (utf8_target, pool);
           if (! strcmp (base_name, SVN_WC_ADM_DIR_NAME))
             continue;
         }
 
- (*((const char **) apr_array_push (output_targets))) = target;
+ (*((const char **) apr_array_push (output_targets))) = utf8_target;
     }
 
 
Index: subversion/libsvn_subr/path.c
===================================================================
--- subversion/libsvn_subr/path.c (revision 7765)
+++ subversion/libsvn_subr/path.c (working copy)
@@ -133,6 +133,53 @@
   return apr_pstrmemdup (pool, path, len);
 }
 
+/* Library clients use this function to convert a raw input
+ path or url into the path format required. */
+svn_error_t *
+svn_path_convert_target (const char** target, const char *raw_target,
+ apr_pool_t *pool)
+{
+ /* URLs and wc-paths get treated differently. */
+ if (svn_path_is_url (raw_target))
+ {
+ SVN_ERR (svn_path_cstring_to_utf8 (target, raw_target, pool));
+ /* No need to canonicalize a URL's case or path separators. */
+ if (! svn_path_is_uri_safe (*target))
+ return svn_error_createf (SVN_ERR_BAD_URL, 0,
+ "URL '%s' is not properly URI-encoded",
+ target);
+ }
+ else /* not a url, so treat as a path */
+ {
+ const char *apr_target = raw_target;
+ char *truenamed_target; /* APR-encoded */
+ apr_status_t apr_err;
+
+ /* canonicalize case, and change all separators to '/'. */
+ apr_err = apr_filepath_merge (&truenamed_target, "", raw_target,
+ APR_FILEPATH_TRUENAME, pool);
+
+ if (!apr_err)
+ /* We have a canonicalized APR-encoded target now. */
+ apr_target = truenamed_target;
+ else if (APR_STATUS_IS_ENOENT (apr_err))
+ /* It's okay for the file to not exist, that just means we
+ have to accept the case given to the client. We'll use
+ the original APR-encoded target. */
+ ;
+ else
+ return svn_error_createf (apr_err, NULL,
+ "Error resolving case of '%s'.",
+ raw_target);
+
+ /* convert back to UTF-8. */
+ SVN_ERR (svn_path_cstring_to_utf8 (target, apr_target, pool));
+ }
+ /* strip any trailing '/' */
+ *target = svn_path_canonicalize (*target, pool);
+ return SVN_NO_ERROR;
+}
+
 
 #ifndef NDEBUG
 static svn_boolean_t

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sun Nov 16 17:02:49 2003

This is an archived mail posted to the Subversion Dev mailing list.