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

📄 entries.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * entries.c :  manipulating the administrative `entries' file. * * ==================================================================== * Copyright (c) 2000-2006 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/. * ==================================================================== */#include <string.h>#include <assert.h>#include <apr_strings.h>#include "svn_xml.h"#include "svn_error.h"#include "svn_types.h"#include "svn_time.h"#include "svn_pools.h"#include "svn_path.h"#include "svn_ctype.h"#include "wc.h"#include "adm_files.h"#include "adm_ops.h"#include "entries.h"#include "lock.h"#include "svn_private_config.h"/** Overview **//* The administrative `entries' file tracks information about files   and subdirs within a particular directory.      See the section on the `entries' file in libsvn_wc/README, for   concrete information about the XML format.*//*--------------------------------------------------------------- *//*** reading and writing the entries file ***/static svn_wc_entry_t *alloc_entry(apr_pool_t *pool){  svn_wc_entry_t *entry = apr_pcalloc(pool, sizeof(*entry));  entry->revision = SVN_INVALID_REVNUM;  entry->copyfrom_rev = SVN_INVALID_REVNUM;  entry->cmt_rev = SVN_INVALID_REVNUM;  entry->kind = svn_node_none;  return entry;}/* If attribute ATTR_NAME appears in hash ATTS, set *ENTRY_FLAG to its * boolean value and add MODIFY_FLAG into *MODIFY_FLAGS, else set *ENTRY_FLAG * false.  ENTRY_NAME is the name of the WC-entry. */static svn_error_t *do_bool_attr(svn_boolean_t *entry_flag,             apr_uint32_t *modify_flags, apr_uint32_t modify_flag,             apr_hash_t *atts, const char *attr_name,             const char *entry_name){  const char *str = apr_hash_get(atts, attr_name, APR_HASH_KEY_STRING);  *entry_flag = FALSE;  if (str)    {      if (strcmp(str, "true") == 0)        *entry_flag = TRUE;      else if (strcmp(str, "false") == 0 || strcmp(str, "") == 0)        *entry_flag = FALSE;      else        return svn_error_createf          (SVN_ERR_ENTRY_ATTRIBUTE_INVALID, NULL,           _("Entry '%s' has invalid '%s' value"),           (entry_name ? entry_name : SVN_WC_ENTRY_THIS_DIR), attr_name);      *modify_flags |= modify_flag;    }  return SVN_NO_ERROR;}/* Read an escaped byte on the form 'xHH' from [*BUF, END), placing   the byte in *RESULT.  Advance *BUF to point after the escape   sequence. */static svn_error_t *read_escaped(char *result, char **buf, const char *end){  apr_uint64_t val;  char digits[3];  if (end - *buf < 3 || **buf != 'x' || ! svn_ctype_isxdigit((*buf)[1])      || ! svn_ctype_isxdigit((*buf)[2]))    return svn_error_create(SVN_ERR_WC_CORRUPT, NULL,                            _("Invalid escape sequence"));  (*buf)++;  digits[0] = *((*buf)++);  digits[1] = *((*buf)++);  digits[2] = 0;  if ((val = apr_strtoi64(digits, NULL, 16)) == 0)    return svn_error_create(SVN_ERR_WC_CORRUPT, NULL,                            _("Invalid escaped character"));  *result = val;  return SVN_NO_ERROR;}/* Read a field, possibly with escaped bytes, from [*BUF, END),   stopping at the terminator.  Place the read string in *RESULT, or set   *RESULT to NULL if it is the empty string.  Allocate the returned string   in POOL.  Advance *BUF to point after the terminator. */static svn_error_t *read_str(const char **result,         char **buf, const char *end,         apr_pool_t *pool){  svn_stringbuf_t *s = NULL;  const char *start;  if (*buf == end)    return svn_error_create(SVN_ERR_WC_CORRUPT, NULL,                            _("Unexpected end of entry"));  if (**buf == '\n')    {      *result = NULL;      (*buf)++;      return SVN_NO_ERROR;    }  start = *buf;  while (*buf != end && **buf != '\n')    {      if (**buf == '\\')        {          char c;          if (! s)            s = svn_stringbuf_ncreate(start, *buf - start, pool);          else            svn_stringbuf_appendbytes(s, start, *buf - start);          (*buf)++;          SVN_ERR(read_escaped(&c, buf, end));          svn_stringbuf_appendbytes(s, &c, 1);          start = *buf;        }      else        (*buf)++;    }  if (*buf == end)    return svn_error_create(SVN_ERR_WC_CORRUPT, NULL,                            _("Unexpected end of entry"));  if (s)    {      svn_stringbuf_appendbytes(s, start, *buf - start);      *result = s->data;    }  else    *result = apr_pstrndup(pool, start, *buf - start);  (*buf)++;  return SVN_NO_ERROR;}/* Read a field from [*BUF, END), terminated by a newline character.   The field may not contain escape sequences.  The field is not   copyed and the buffer is modified in place, by replacing the   terminator with a NUL byte.  Make *BUF point after the original   terminator. */static svn_error_t *read_val(const char **result,          char **buf, const char *end){  const char *start = *buf;  if (*buf == end)    return svn_error_create(SVN_ERR_WC_CORRUPT, NULL,                            _("Unexpected end of entry"));  if (**buf == '\n')    {      (*buf)++;      *result = NULL;      return SVN_NO_ERROR;    }  while (*buf != end && **buf != '\n')    (*buf)++;  if (*buf == end)    return svn_error_create(SVN_ERR_WC_CORRUPT, NULL,                            _("Unexpected end of entry"));  **buf = '\0';  *result = start;  (*buf)++;  return SVN_NO_ERROR;}  /* Read a boolean field from [*BUF, END), placing the result in   *RESULT.  If there is no boolean value (just a terminator), it   defaults to false.  Else, the value must match FIELD_NAME, in which   case *RESULT will be set to true.  Advance *BUF to point after the   terminator. */static svn_error_t *read_bool(svn_boolean_t *result, const char *field_name,          char **buf, const char *end){  const char *val;  SVN_ERR(read_val(&val, buf, end));  if (val)    {      if (strcmp(val, field_name) != 0)        return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,                                 _("Invalid value for field '%s'"),                                 field_name);      *result = TRUE;    }  else    *result = FALSE;  return SVN_NO_ERROR;}/* Read a revision number from [*BUF, END) stopping at the   terminator.  Set *RESULT to the revision number, or   SVN_INVALID_REVNUM if there is none.  Use POOL for temporary   allocations.  Make *BUF point after the terminator.  */static svn_error_t *read_revnum(svn_revnum_t *result,            char **buf,            const char *end,            apr_pool_t *pool){  const char *val;  SVN_ERR(read_val(&val, buf, end));  if (val)    *result = SVN_STR_TO_REV(val);  else    *result = SVN_INVALID_REVNUM;  return SVN_NO_ERROR;}/* Read a timestamp from [*BUF, END) stopping at the terminator.   Set *RESULT to the resulting timestamp, or 0 if there is none.  Use   POOL for temporary allocations.  Make *BUF point after the   terminator. */static svn_error_t *read_time(apr_time_t *result,          char **buf, const char *end,          apr_pool_t *pool){  const char *val;  SVN_ERR(read_val(&val, buf, end));  if (val)    SVN_ERR(svn_time_from_cstring(result, val, pool));  else    *result = 0;  return SVN_NO_ERROR;}/* Allocate an entry from POOL and read it from [*BUF, END).  The   buffer may be modified in place while parsing.  Return the new   entry in *NEW_ENTRY.  Advance *BUF to point at the end of the entry   record. */static svn_error_t *read_entry(svn_wc_entry_t **new_entry,           char **buf, const char *end,           apr_pool_t *pool){  svn_wc_entry_t *entry = alloc_entry(pool);  const char *name;  #define MAYBE_DONE if (**buf == '\f') goto done  /* Find the name and set up the entry under that name. */  SVN_ERR(read_str(&name, buf, end, pool));  entry->name = name ? name : SVN_WC_ENTRY_THIS_DIR;  /* Set up kind. */  {    const char *kindstr;    SVN_ERR(read_val(&kindstr, buf, end));    if (kindstr)      {        if (! strcmp(kindstr, SVN_WC__ENTRIES_ATTR_FILE_STR))          entry->kind = svn_node_file;        else if (! strcmp(kindstr, SVN_WC__ENTRIES_ATTR_DIR_STR))          entry->kind = svn_node_dir;        else          return svn_error_createf             (SVN_ERR_NODE_UNKNOWN_KIND, NULL,             _("Entry '%s' has invalid node kind"),             (name ? name : SVN_WC_ENTRY_THIS_DIR));      }    else      entry->kind = svn_node_none;  }  MAYBE_DONE;  /* Attempt to set revision (resolve_to_defaults may do it later, too) */  SVN_ERR(read_revnum(&entry->revision, buf, end, pool));  MAYBE_DONE;  /* Attempt to set up url path (again, see resolve_to_defaults). */  SVN_ERR(read_str(&entry->url, buf, end, pool));  MAYBE_DONE;  /* Set up repository root.  Make sure it is a prefix of url. */  SVN_ERR(read_str(&entry->repos, buf, end, pool));  if (entry->repos && entry->url      && ! svn_path_is_ancestor(entry->repos, entry->url))    return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,                             _("Entry for '%s' has invalid repository "                               "root"),                             name ? name : SVN_WC_ENTRY_THIS_DIR);  MAYBE_DONE;  /* Look for a schedule attribute on this entry. */  {    const char *schedulestr;    SVN_ERR(read_val(&schedulestr, buf, end));    entry->schedule = svn_wc_schedule_normal;    if (schedulestr)      {        if (! strcmp(schedulestr, SVN_WC__ENTRY_VALUE_ADD))          entry->schedule = svn_wc_schedule_add;        else if (! strcmp(schedulestr, SVN_WC__ENTRY_VALUE_DELETE))          entry->schedule = svn_wc_schedule_delete;        else if (! strcmp(schedulestr, SVN_WC__ENTRY_VALUE_REPLACE))          entry->schedule = svn_wc_schedule_replace;        else          return svn_error_createf             (SVN_ERR_ENTRY_ATTRIBUTE_INVALID, NULL,             _("Entry '%s' has invalid '%s' value"),             (name ? name : SVN_WC_ENTRY_THIS_DIR),             SVN_WC__ENTRY_ATTR_SCHEDULE);      }  }     MAYBE_DONE;    /* Attempt to set up text timestamp. */  SVN_ERR(read_time(&entry->text_time, buf, end, pool));  MAYBE_DONE;  /* Checksum. */  SVN_ERR(read_str(&entry->checksum, buf, end, pool));  MAYBE_DONE;  /* Setup last-committed values. */  SVN_ERR(read_time(&entry->cmt_date, buf, end, pool));  MAYBE_DONE;  SVN_ERR(read_revnum(&entry->cmt_rev, buf, end, pool));  MAYBE_DONE;  SVN_ERR(read_str(&entry->cmt_author, buf, end, pool));  MAYBE_DONE;  /* has-props flag. */  SVN_ERR(read_bool(&entry->has_props, SVN_WC__ENTRY_ATTR_HAS_PROPS,                    buf, end));  MAYBE_DONE;  /* has-prop-mods flag. */  SVN_ERR(read_bool(&entry->has_prop_mods, SVN_WC__ENTRY_ATTR_HAS_PROP_MODS,                    buf, end));  MAYBE_DONE;  /* cachable-props string. */  SVN_ERR(read_val(&entry->cachable_props, buf, end));  if (entry->cachable_props)    entry->cachable_props = apr_pstrdup(pool, entry->cachable_props);  MAYBE_DONE;  /* present-props string. */  SVN_ERR(read_val(&entry->present_props, buf, end));  if (entry->present_props)    entry->present_props = apr_pstrdup(pool, entry->present_props);  MAYBE_DONE;  /* Is this entry in a state of mental torment (conflict)? */  {    SVN_ERR(read_str(&entry->prejfile, buf, end, pool));    MAYBE_DONE;    SVN_ERR(read_str(&entry->conflict_old, buf, end, pool));    MAYBE_DONE;    SVN_ERR(read_str(&entry->conflict_new, buf, end, pool));    MAYBE_DONE;    SVN_ERR(read_str(&entry->conflict_wrk, buf, end, pool));    MAYBE_DONE;

⌨️ 快捷键说明

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