⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 path.c

📁 subversion-1.4.5.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
svn_path_compare_paths(const char *path1,                       const char *path2){  apr_size_t path1_len = strlen(path1);  apr_size_t path2_len = strlen(path2);  apr_size_t min_len = ((path1_len < path2_len) ? path1_len : path2_len);  apr_size_t i = 0;  assert(is_canonical(path1, path1_len));  assert(is_canonical(path2, path2_len));  /* Skip past common prefix. */  while (i < min_len && path1[i] == path2[i])    ++i;  /* Are the paths exactly the same? */  if ((path1_len == path2_len) && (i >= min_len))    return 0;      /* Children of paths are greater than their parents, but less than     greater siblings of their parents. */  if ((path1[i] == '/') && (path2[i] == 0))    return 1;  if ((path2[i] == '/') && (path1[i] == 0))    return -1;  if (path1[i] == '/')    return -1;  if (path2[i] == '/')    return 1;  /* Common prefix was skipped above, next character is compared to     determine order.  We need to use an unsigned comparison, though,     so a "next character" of NULL (0x00) sorts numerically     smallest. */  return (unsigned char)(path1[i]) < (unsigned char)(path2[i]) ? -1 : 1;}/* Return the string length of the longest common ancestor of PATH1 and PATH2.   * * This function handles everything except the URL-handling logic  * of svn_path_get_longest_ancestor, and assumes that PATH1 and  * PATH2 are *not* URLs.   * * If the two paths do not share a common ancestor, return 0.  * * New strings are allocated in POOL. */static apr_size_tget_path_ancestor_length(const char *path1,                         const char *path2,                         apr_pool_t *pool){  apr_size_t path1_len, path2_len;  apr_size_t i = 0;  apr_size_t last_dirsep = 0;    path1_len = strlen(path1);  path2_len = strlen(path2);  if (SVN_PATH_IS_EMPTY(path1) || SVN_PATH_IS_EMPTY(path2))    return 0;  while (path1[i] == path2[i])    {      /* Keep track of the last directory separator we hit. */      if (path1[i] == '/')        last_dirsep = i;      i++;      /* If we get to the end of either path, break out. */      if ((i == path1_len) || (i == path2_len))        break;    }  /* last_dirsep is now the offset of the last directory separator we     crossed before reaching a non-matching byte.  i is the offset of     that non-matching byte. */  if (((i == path1_len) && (path2[i] == '/'))           || ((i == path2_len) && (path1[i] == '/'))           || ((i == path1_len) && (i == path2_len)))    return i;  else    return last_dirsep;}char *svn_path_get_longest_ancestor(const char *path1,                              const char *path2,                              apr_pool_t *pool){  svn_boolean_t path1_is_url, path2_is_url;  path1_is_url = svn_path_is_url(path1);  path2_is_url = svn_path_is_url(path2);  if (path1_is_url && path2_is_url)     {      apr_size_t path_ancestor_len;       apr_size_t i = 0;      /* Find ':' */      while (1)        {          /* No shared protocol => no common prefix */          if (path1[i] != path2[i])            return apr_pmemdup(pool, SVN_EMPTY_PATH,                                sizeof(SVN_EMPTY_PATH));          if (path1[i] == ':')             break;          /* They're both URLs, so EOS can't come before ':' */          assert((path1[i] != '\0') && (path2[i] != '\0'));          i++;        }      i += 3;  /* Advance past '://' */      path_ancestor_len = get_path_ancestor_length(path1 + i, path2 + i,                                                    pool);      if (path_ancestor_len == 0)        return apr_pmemdup(pool, SVN_EMPTY_PATH, sizeof(SVN_EMPTY_PATH));      else        return apr_pstrndup(pool, path1, path_ancestor_len + i);     }  else if ((! path1_is_url) && (! path2_is_url))    {       return apr_pstrndup(pool, path1,                           get_path_ancestor_length(path1, path2, pool));    }  else    {      /* A URL and a non-URL => no common prefix */      return apr_pmemdup(pool, SVN_EMPTY_PATH, sizeof(SVN_EMPTY_PATH));    }}const char *svn_path_is_child(const char *path1,                  const char *path2,                  apr_pool_t *pool){  apr_size_t i;  /* assert (is_canonical (path1, strlen (path1)));  ### Expensive strlen */  /* assert (is_canonical (path2, strlen (path2)));  ### Expensive strlen */  /* Allow "" and "foo" to be parent/child */  if (SVN_PATH_IS_EMPTY(path1))               /* "" is the parent  */    {      if (SVN_PATH_IS_EMPTY(path2)            /* "" not a child    */          || path2[0] == '/')                  /* "/foo" not a child */        return NULL;      else        return apr_pstrdup(pool, path2);      /* everything else is child */    }  /* Reach the end of at least one of the paths.  How should we handle     things like path1:"foo///bar" and path2:"foo/bar/baz"?  It doesn't     appear to arise in the current Subversion code, it's not clear to me     if they should be parent/child or not. */  for (i = 0; path1[i] && path2[i]; i++)    if (path1[i] != path2[i])      return NULL;  /* There are two cases that are parent/child          ...      path1[i] == '\0'          .../foo  path2[i] == '/'      or          /        path1[i] == '\0'          /foo     path2[i] != '/'  */  if (path1[i] == '\0' && path2[i])    {      if (path2[i] == '/')        return apr_pstrdup(pool, path2 + i + 1);      else if (i == 1 && path1[0] == '/')        return apr_pstrdup(pool, path2 + 1);    }  /* Otherwise, path2 isn't a child. */  return NULL;}svn_boolean_tsvn_path_is_ancestor(const char *path1, const char *path2){  apr_size_t path1_len = strlen(path1);  /* If path1 is empty and path2 is not absoulte, then path1 is an ancestor. */  if (SVN_PATH_IS_EMPTY(path1))    return *path2 != '/';  /* If path1 is a prefix of path2, then:     - If path1 ends in a path separator,     - If the paths are of the same length     OR     - path2 starts a new path component after the common prefix,     then path1 is an ancestor. */  if (strncmp(path1, path2, path1_len) == 0)    return path1[path1_len - 1] == '/'      || (path2[path1_len] == '/' || path2[path1_len] == '\0');  return FALSE;}apr_array_header_t *svn_path_decompose(const char *path,                   apr_pool_t *pool){  apr_size_t i, oldi;  apr_array_header_t *components =     apr_array_make(pool, 1, sizeof(const char *));  /* assert (is_canonical (path, strlen (path)));  ### Expensive strlen */  if (SVN_PATH_IS_EMPTY(path))    return components;  /* ### Should we return a "" component? */  /* If PATH is absolute, store the '/' as the first component. */  i = oldi = 0;  if (path[i] == '/')    {      char dirsep = '/';      *((const char **) apr_array_push(components))        = apr_pstrmemdup(pool, &dirsep, sizeof(dirsep));      i++;      oldi++;      if (path[i] == '\0') /* path is a single '/' */        return components;    }  do    {      if ((path[i] == '/') || (path[i] == '\0'))        {          if (SVN_PATH_IS_PLATFORM_EMPTY(path + oldi, i - oldi))            *((const char **) apr_array_push(components)) = SVN_EMPTY_PATH;          else            *((const char **) apr_array_push(components))              = apr_pstrmemdup(pool, path + oldi, i - oldi);          i++;          oldi = i;  /* skipping past the dirsep */          continue;        }      i++;    }  while (path[i-1]);  return components;}svn_boolean_tsvn_path_is_single_path_component(const char *name){  /* assert (is_canonical (name, strlen (name)));  ### Expensive strlen */  /* Can't be empty or `..'  */  if (SVN_PATH_IS_EMPTY(name)      || (name[0] == '.' && name[1] == '.' && name[2] == '\0'))    return FALSE;  /* Slashes are bad, m'kay... */  if (strchr(name, '/') != NULL)    return FALSE;  /* It is valid.  */  return TRUE;}svn_boolean_tsvn_path_is_backpath_present(const char *path){  int len = strlen(path);    if (! strcmp(path, ".."))    return TRUE;  if (! strncmp(path, "../", 3))    return TRUE;    if (strstr(path, "/../") != NULL)    return TRUE;  if (len >= 3      && (! strncmp(path + len - 3, "/..", 3)))    return TRUE;  return FALSE;}/*** URI Stuff ***//* Examine PATH as a potential URI, and return a substring of PATH   that immediately follows the (scheme):// portion of the URI, or   NULL if PATH doesn't appear to be a valid URI.  The returned value   is not alloced -- it shares memory with PATH. */static const char *skip_uri_scheme(const char *path){  apr_size_t j;  for (j = 0; path[j]; ++j)    if (path[j] == ':' || path[j] == '/')       break;  if (j > 0 && path[j] == ':' && path[j+1] == '/' && path[j+2] == '/')    return path + j + 3;  return NULL;}svn_boolean_t svn_path_is_url(const char *path){  /* ### This function is reaaaaaaaaaaaaaally stupid right now.     We're just going to look for:         (scheme)://(optional_stuff)     Where (scheme) has no ':' or '/' characters.     Someday it might be nice to have an actual URI parser here.  */  return skip_uri_scheme(path) ? TRUE : FALSE;}/* Here is the BNF for path components in a URI. "pchar" is a   character in a path component.      pchar       = unreserved | escaped |                     ":" | "@" | "&" | "=" | "+" | "$" | ","      unreserved  = alphanum | mark      mark        = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"   Note that "escaped" doesn't really apply to what users can put in   their paths, so that really means the set of characters is:      alphanum | mark | ":" | "@" | "&" | "=" | "+" | "$" | "," */static const char uri_char_validity[256] = {  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0, 1, 0, 0, 1, 0, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 0, 0, 1, 0, 0,  /* 64 */  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 0, 0, 0, 0, 1,  0, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 0, 0, 0, 1, 0,  /* 128 */  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  /* 192 */  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,};svn_boolean_t svn_path_is_uri_safe(const char *path){  apr_size_t i;  /* Skip the URI scheme. */  path = skip_uri_scheme(path);  /* No scheme?  Get outta here. */  if (! path)    return FALSE;  /* Skip to the first slash that's after the URI scheme. */  path = strchr(path, '/');  /* If there's no first slash, then there's only a host portion;     therefore there couldn't be any uri-unsafe characters after the     host... so return true. */  if (path == NULL)    return TRUE;  for (i = 0; path[i]; i++)    {      /* Allow '%XX' (where each X is a hex digit) */      if (path[i] == '%')        {          if (apr_isxdigit(path[i + 1]) && apr_isxdigit(path[i + 2]))            {              i += 2;              continue;            }          return FALSE;        }      else if (! uri_char_validity[((unsigned char)path[i])])        {          return FALSE;        }    }   return TRUE;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -