| /* svn_path.h: a path manipulation library |
| * |
| * ==================================================================== |
| * Copyright (c) 2000-2002 CollabNet. All rights reserved. |
| * |
| * This software is licensed as described in the file COPYING, which |
| * you should have received as part of this distribution. The terms |
| * are also available at http://subversion.tigris.org/license-1.html. |
| * If newer versions of this license are posted there, you may use a |
| * newer version instead, at your option. |
| * |
| * This software consists of voluntary contributions made by many |
| * individuals. For exact contribution history, see the revision |
| * history and logs, available at http://subversion.tigris.org/. |
| * ==================================================================== |
| */ |
| |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif /* __cplusplus */ |
| |
| #ifndef SVN_PATH_H |
| #define SVN_PATH_H |
| |
| |
| |
| #include <apr_pools.h> |
| #include <apr_tables.h> |
| #include "svn_string.h" |
| #include "svn_error.h" |
| |
| |
| /*** Notes: |
| * |
| * No result path ever ends with a separator, no matter whether the |
| * path is a file or directory, because we always canonicalize() it. |
| * |
| * todo: this library really needs a test suite! |
| ***/ |
| |
| /* Convert PATH from the local style to the canonical internal style. */ |
| void svn_path_internal_style (svn_stringbuf_t *path); |
| |
| /* Convert PATH from the canonical internal style to the local style. */ |
| void svn_path_local_style (svn_stringbuf_t *path); |
| |
| |
| /* Join a base path (BASE) with a component (COMPONENT), allocated in POOL. |
| |
| If either BASE or COMPONENT is the empty string, then the other argument |
| will be copied and returned. |
| |
| If the COMPONENT is an absolute path, then it is copied and returned. |
| Exactly one slash character ('/') is used to joined the components, |
| accounting for any trailing slash in BASE. If BASE has multiple trailing |
| slashes, then the result will also have multiple slashes (svn_path_join |
| just won't add more). |
| |
| Note that the contents of BASE are not examined, so it is possible to |
| use this function for constructing URLs, or for relative URLs or |
| repository paths. |
| |
| This function is NOT appropriate for native (local) file paths. Only |
| for "internal" paths, since it uses '/' for the separator. Further, |
| an absolute path (for COMPONENT) is based on a leading '/' character. |
| Thus, an "absolute URI" for the COMPONENT won't be detected. An |
| absolute URI can only be used for the base. |
| */ |
| char *svn_path_join (const char *base, |
| const char *component, |
| apr_pool_t *pool); |
| |
| /* Join multiple components onto a BASE path, allocated in POOL. The |
| components are terminated by a NULL. |
| |
| If any component is the empty string, it will be ignored. |
| |
| If any component is an absolute path, then it resets the base and |
| further components will be appended to it. |
| |
| See svn_path_join() for further notes about joining paths. |
| */ |
| char *svn_path_join_many (apr_pool_t *pool, const char *base, ...); |
| |
| |
| /* Get the basename of the specified PATH. The basename is defined as |
| the last component of the path (ignoring any trailing slashes). If |
| the PATH is root ("/"), then that is returned. Otherwise, the |
| returned value will have no slashes in it. |
| |
| Example: svn_path_basename("/foo/bar") -> "bar" |
| |
| The returned basename will be allocated in POOL. |
| |
| Note: if an empty string is passed, then an empty string will be returned. |
| */ |
| char *svn_path_basename (const char *path, apr_pool_t *pool); |
| |
| |
| /* Add a COMPONENT (a null-terminated C-string) to PATH. COMPONENT is |
| allowed to contain directory separators. |
| |
| If PATH is non-empty, append the appropriate directory separator |
| character, and then COMPONENT. If PATH is empty, simply set it to |
| COMPONENT; don't add any separator character. |
| |
| If the result ends in a separator character, then remove the separator. */ |
| void svn_path_add_component (svn_stringbuf_t *path, |
| const svn_stringbuf_t *component); |
| |
| /* Same as `svn_path_add_component', except that the COMPONENT argument is |
| a C-style '\0'-terminated string, not an svn_stringbuf_t. */ |
| void svn_path_add_component_nts (svn_stringbuf_t *path, |
| const char *component); |
| |
| /* Remove one component off the end of PATH. */ |
| void svn_path_remove_component (svn_stringbuf_t *path); |
| |
| |
| |
| /* Divide PATH into *DIRPATH and *BASENAME, return them by reference, |
| * in their own storage in POOL. |
| * |
| * If DIRPATH or BASENAME is null, then that one will not be used. |
| * |
| * DIRPATH or BASENAME may be PATH's own address, but they may not |
| * both be PATH's address; in fact, in general they must not be the |
| * same, or the results are undefined. |
| * |
| * The separator between DIRPATH and BASENAME is not included in |
| * either of the new names. |
| */ |
| void svn_path_split (const svn_stringbuf_t *path, |
| svn_stringbuf_t **dirpath, |
| svn_stringbuf_t **basename, |
| apr_pool_t *pool); |
| |
| |
| /* Return non-zero iff PATH is empty or represents the current |
| directory -- that is, if it is NULL or if prepending it as a |
| component to an existing path would result in no meaningful |
| change. */ |
| int svn_path_is_empty (const svn_stringbuf_t *path); |
| |
| |
| /* Remove trailing separators that don't affect the meaning of the path. |
| (At some future point, this may make other semantically inoperative |
| transformations.) */ |
| void svn_path_canonicalize (svn_stringbuf_t *path); |
| |
| |
| /* Return an integer greater than, equal to, or less than 0, according |
| as PATH1 is greater than, equal to, or less than PATH2. */ |
| int svn_path_compare_paths (const svn_stringbuf_t *path1, |
| const svn_stringbuf_t *path2); |
| |
| |
| /* Return the longest common path shared by both PATH1 and PATH2. If |
| there's no common ancestor, return NULL. */ |
| svn_stringbuf_t *svn_path_get_longest_ancestor (const svn_stringbuf_t *path1, |
| const svn_stringbuf_t *path2, |
| apr_pool_t *pool); |
| |
| /* Convert RELATIVE path to an absolute path and return the results in |
| *PABSOLUTE. */ |
| svn_error_t * |
| svn_path_get_absolute(svn_stringbuf_t **pabsolute, |
| const svn_stringbuf_t *relative, |
| apr_pool_t *pool); |
| |
| /* Return the path part of PATH in *PDIRECTORY, and the file part in *PFILE. |
| If PATH is a directory, it will be returned through PDIRECTORY, and *PFILE |
| will be the empty string (not NULL). */ |
| svn_error_t * |
| svn_path_split_if_file(svn_stringbuf_t *path, |
| svn_stringbuf_t **pdirectory, |
| svn_stringbuf_t **pfile, |
| apr_pool_t *pool); |
| |
| /* Find the common prefix of the paths in TARGETS, and remove redundancies. |
| * |
| * The elements in TARGETS must be existing files or directories. |
| * |
| * If there are multiple targets, or exactly one target and it's not a |
| * directory, then |
| * |
| * - *PBASENAME is set to the absolute path of the common parent |
| * directory of all of those targets, and |
| * |
| * - If PCONDENSED_TARGETS is non-null, *PCONDENSED_TARGETS is set |
| * to an array of targets relative to *PBASENAME, with |
| * redundancies removed (meaning that none of these targets will |
| * be the same as, nor have an ancestor/descendant relationship |
| * with, any of the other targets; nor will any of them be the |
| * same as *PBASENAME). Else if PCONDENSED_TARGETS is null, it is |
| * left untouched. |
| * |
| * Else if there is exactly one directory target, then |
| * |
| * - *PBASENAME is set to that directory, and |
| * |
| * - If PCONDENSED_TARGETS is non-null, *PCONDENSED_TARGETS is set |
| * to an array containing zero elements. Else if |
| * PCONDENSED_TARGETS is null, it is left untouched. |
| * |
| * If there are no items in TARGETS, *PBASENAME and (if applicable) |
| * *PCONDENSED_TARGETS will be NULL. |
| * |
| * NOTE: There is no guarantee that *PBASENAME is within a working |
| * copy. |
| */ |
| svn_error_t * |
| svn_path_condense_targets (svn_stringbuf_t **pbasename, |
| apr_array_header_t **pcondensed_targets, |
| const apr_array_header_t *targets, |
| apr_pool_t *pool); |
| |
| |
| /* Copy a list of TARGETS, one at a time, into PCONDENSED_TARGETS, |
| omitting any targets that are found earlier in the list, or whose |
| ancestor is found earlier in the list. Ordering of targets in the |
| original list is preserved in the condensed list of targets. Use |
| POOL for any allocations. |
| |
| How does this differ in functionality from svn_path_condense_targets? |
| |
| Here's the short version: |
| |
| 1. Disclaimer: if you wish to debate the following, talk to Karl. :-) |
| Order matters for updates because a multi-arg update is not |
| atomic, and CVS users are used to, when doing 'cvs up targetA |
| targetB' seeing targetA get updated, then targetB. I think the |
| idea is that if you're in a time-sensitive or flaky-network |
| situation, a user can say, "I really *need* to update |
| wc/A/D/G/tau, but I might as well update my whole working copy if |
| I can." So that user will do 'svn up wc/A/D/G/tau wc', and if |
| something dies in the middles of the 'wc' update, at least the |
| user has 'tau' up-to-date. |
| |
| 2. Also, we have this notion of an anchor and a target for updates |
| (the anchor is where the update editor is rooted, the target is |
| the actual thing we want to update). I needed a function that |
| would NOT screw with my input paths so that I could tell the |
| difference between someone being in A/D and saying 'svn up G' and |
| being in A/D/G and saying 'svn up .' -- believe it or not, these |
| two things don't mean the same thing. svn_path_condense_targets |
| plays with absolute paths (which is fine, so does |
| svn_path_remove_redundancies), but the difference is that it |
| actually tweaks those targets to be relative to the "grandfather |
| path" common to all the targets. Updates don't require a |
| "grandfather path" at all, and even if it did, the whole |
| conversion to an absolute path drops the crucial difference |
| between saying "i'm in foo, update bar" and "i'm in foo/bar, |
| update '.'" |
| */ |
| svn_error_t * |
| svn_path_remove_redundancies (apr_array_header_t **pcondensed_targets, |
| const apr_array_header_t *targets, |
| apr_pool_t *pool); |
| |
| |
| /* Decompose PATH into an array of svn_stringbuf_t components, allocated |
| in POOL. STYLE indicates the dir separator to split the string on. |
| If PATH is absolute, the first component will be a lone dir |
| separator (the root directory). */ |
| apr_array_header_t *svn_path_decompose (const svn_stringbuf_t *path, |
| apr_pool_t *pool); |
| |
| |
| |
| /* Test if PATH2 is a child of PATH1. |
| If not, return NULL. |
| If so, return the "remainder" path. (The substring which, when |
| appended to PATH1, yields PATH2 -- minus the dirseparator. ) */ |
| svn_stringbuf_t *svn_path_is_child (const svn_stringbuf_t *path1, |
| const svn_stringbuf_t *path2, |
| apr_pool_t *pool); |
| |
| /* Compare PATH to an array of const char * URL SCHEMES (like "file", |
| "http", etc.) to determine if PATH looks like a URL. If so, return |
| the matching scheme used by PATH, else return NULL. Returned |
| values point to the allocations in SCHEMES. */ |
| svn_boolean_t svn_path_is_url (const svn_string_t *path); |
| |
| /* Return TRUE if PATH is URI-safe, FALSE otherwise. */ |
| svn_boolean_t svn_path_is_uri_safe (const svn_string_t *path); |
| |
| /* Return a URI-encoded copy of PATH, allocated in POOL. */ |
| svn_stringbuf_t *svn_path_uri_encode (const svn_string_t *path, |
| apr_pool_t *pool); |
| |
| /* Return a URI-decoded copy of PATH, allocated in POOL. */ |
| svn_stringbuf_t *svn_path_uri_decode (const svn_string_t *path, |
| apr_pool_t *pool); |
| |
| |
| #endif /* SVN_PATH_H */ |
| |
| #ifdef __cplusplus |
| } |
| #endif /* __cplusplus */ |
| |
| |
| /* ---------------------------------------------------------------- |
| * local variables: |
| * eval: (load-file "../../tools/dev/svn-dev.el") |
| * end: |
| */ |