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

📄 entries.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * entries.c :  manipulating the administrative `entries' file.
 *
 * ====================================================================
 * Copyright (c) 2000-2004 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 "wc.h"
#include "adm_files.h"
#include "adm_ops.h"
#include "entries.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.
*/


/*--------------------------------------------------------------- */


/*** Initialization of the entries file. ***/

svn_error_t *
svn_wc__entries_init (const char *path,
                      const char *uuid,
                      const char *url,
                      svn_revnum_t initial_rev,
                      apr_pool_t *pool)
{
  apr_file_t *f = NULL;
  svn_stringbuf_t *accum = NULL;
  apr_hash_t *atts = apr_hash_make (pool);
  char *initial_revstr =  apr_psprintf (pool, "%ld",
                                        initial_rev);

  /* Create the entries file, which must not exist prior to this. */
  SVN_ERR (svn_wc__open_adm_file (&f, path, SVN_WC__ADM_ENTRIES,
                                  (APR_WRITE | APR_CREATE | APR_EXCL), pool));

  /* Make a the XML standard header, to satisfy bureacracy. */
  svn_xml_make_header (&accum, pool);

  /* Open the file's top-level form. */
  svn_xml_make_open_tag (&accum,
                         pool,
                         svn_xml_normal,
                         SVN_WC__ENTRIES_TOPLEVEL,
                         "xmlns",
                         SVN_XML_NAMESPACE,
                         NULL);

  /* Add an entry for the dir itself.  The directory has no name.  It
     might have a UUID, but otherwise only the revision and default
     ancestry are present as XML attributes, and possibly an
     'incomplete' flag if the revnum is > 0. */

  apr_hash_set (atts, SVN_WC__ENTRY_ATTR_KIND, 
                sizeof (SVN_WC__ENTRY_ATTR_KIND) - 1,
                SVN_WC__ENTRIES_ATTR_DIR_STR);
  apr_hash_set (atts, SVN_WC__ENTRY_ATTR_URL,
                sizeof (SVN_WC__ENTRY_ATTR_URL) - 1,
                url);
  apr_hash_set (atts, SVN_WC__ENTRY_ATTR_REVISION,
                sizeof (SVN_WC__ENTRY_ATTR_REVISION) - 1,
                initial_revstr);

  if (uuid)
    apr_hash_set (atts, SVN_WC__ENTRY_ATTR_UUID,
                  sizeof (SVN_WC__ENTRY_ATTR_UUID) - 1,
                  uuid);
    
  if (initial_rev > 0)
    apr_hash_set (atts, SVN_WC__ENTRY_ATTR_INCOMPLETE,
                  sizeof (SVN_WC__ENTRY_ATTR_INCOMPLETE) - 1,
                  "true");
  
  svn_xml_make_open_tag_hash (&accum, pool, svn_xml_self_closing,
                              SVN_WC__ENTRIES_ENTRY, atts);

  /* Close the top-level form. */
  svn_xml_make_close_tag (&accum,
                          pool,
                          SVN_WC__ENTRIES_TOPLEVEL);

  SVN_ERR_W (svn_io_file_write_full (f, accum->data, accum->len, NULL, pool),
             apr_psprintf (pool, 
                           _("Error writing entries file for '%s'"), path));

  /* Now we have a `entries' file with exactly one entry, an entry
     for this dir.  Close the file and sync it up. */
  SVN_ERR (svn_wc__close_adm_file (f, path, SVN_WC__ADM_ENTRIES, 1, pool));

  return SVN_NO_ERROR;
}


/*--------------------------------------------------------------- */

/*** reading and writing the entries file ***/

struct entries_accumulator
{
  /* Keys are entry names, vals are (struct svn_wc_entry_t *)'s. */
  apr_hash_t *entries; 

  /* The parser that's parsing it, for signal_expat_bailout(). */
  svn_xml_parser_t *parser;

  /* Should we include 'deleted' entries in the hash? */
  svn_boolean_t show_hidden;

  /* Don't leave home without one. */
  apr_pool_t *pool;
};


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;
}


svn_error_t *
svn_wc__atts_to_entry (svn_wc_entry_t **new_entry,
                       apr_uint32_t *modify_flags,
                       apr_hash_t *atts,
                       apr_pool_t *pool)
{
  svn_wc_entry_t *entry = alloc_entry (pool);
  const char *name;
  
  *modify_flags = 0;

  /* Find the name and set up the entry under that name. */
  name = apr_hash_get (atts, SVN_WC__ENTRY_ATTR_NAME, APR_HASH_KEY_STRING);
  /* XXX Replace the obsolete "svn:this_dir".
     XXX This code should go away by 1.0 */
  {
    if (name && strcmp (name, "svn:this_dir") == 0)
      name = SVN_WC_ENTRY_THIS_DIR;
  }
  entry->name = name ? name : SVN_WC_ENTRY_THIS_DIR;

  /* Attempt to set revision (resolve_to_defaults may do it later, too) */
  {
    const char *revision_str
      = apr_hash_get (atts, SVN_WC__ENTRY_ATTR_REVISION, APR_HASH_KEY_STRING);

    if (revision_str)
      {
        entry->revision = SVN_STR_TO_REV (revision_str);
        *modify_flags |= SVN_WC__ENTRY_MODIFY_REVISION;
      }
    else
      entry->revision = SVN_INVALID_REVNUM;
  }

  /* Attempt to set up url path (again, see resolve_to_defaults). */
  {
    entry->url
      = apr_hash_get (atts, SVN_WC__ENTRY_ATTR_URL, APR_HASH_KEY_STRING);

    if (entry->url)
      *modify_flags |= SVN_WC__ENTRY_MODIFY_URL;
  }

  /* Set up kind. */
  {
    const char *kindstr
      = apr_hash_get (atts, SVN_WC__ENTRY_ATTR_KIND, APR_HASH_KEY_STRING);

    entry->kind = svn_node_none;
    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));
        *modify_flags |= SVN_WC__ENTRY_MODIFY_KIND;
      }
  }

  /* Look for a schedule attribute on this entry. */
  {
    const char *schedulestr
      = apr_hash_get (atts, SVN_WC__ENTRY_ATTR_SCHEDULE, APR_HASH_KEY_STRING);
    
    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 if (! strcmp (schedulestr, ""))
          entry->schedule = svn_wc_schedule_normal;
        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);

        *modify_flags |= SVN_WC__ENTRY_MODIFY_SCHEDULE;
      }
  }   
  
  /* Is this entry in a state of mental torment (conflict)? */
  {
    if ((entry->prejfile 
         = apr_hash_get (atts, SVN_WC__ENTRY_ATTR_PREJFILE, 
                         APR_HASH_KEY_STRING)))
      *modify_flags |= SVN_WC__ENTRY_MODIFY_PREJFILE;

    if ((entry->conflict_old 
         = apr_hash_get (atts, SVN_WC__ENTRY_ATTR_CONFLICT_OLD, 
                         APR_HASH_KEY_STRING)))
      *modify_flags |= SVN_WC__ENTRY_MODIFY_CONFLICT_OLD;

    if ((entry->conflict_new 
         = apr_hash_get (atts, SVN_WC__ENTRY_ATTR_CONFLICT_NEW, 
                         APR_HASH_KEY_STRING)))
      *modify_flags |= SVN_WC__ENTRY_MODIFY_CONFLICT_NEW;

    if ((entry->conflict_wrk 
         = apr_hash_get (atts, SVN_WC__ENTRY_ATTR_CONFLICT_WRK, 
                         APR_HASH_KEY_STRING)))
      *modify_flags |= SVN_WC__ENTRY_MODIFY_CONFLICT_WRK;
  }

  /* Is this entry copied? */
  {
    const char *copiedstr, *revstr;
      
    copiedstr = apr_hash_get (atts, SVN_WC__ENTRY_ATTR_COPIED, 
                              APR_HASH_KEY_STRING);
        
    entry->copied = FALSE;
    if (copiedstr)
      {
        if (! strcmp (copiedstr, "true"))
          entry->copied = TRUE;
        else if (! strcmp (copiedstr, "false"))
          entry->copied = FALSE;
        else if (! strcmp (copiedstr, ""))
          entry->copied = FALSE;
        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_COPIED);

        *modify_flags |= SVN_WC__ENTRY_MODIFY_COPIED;
      }

    entry->copyfrom_url = apr_hash_get (atts, SVN_WC__ENTRY_ATTR_COPYFROM_URL,
                                        APR_HASH_KEY_STRING);
    if (entry->copyfrom_url)
      *modify_flags |= SVN_WC__ENTRY_MODIFY_COPYFROM_URL;

    revstr = apr_hash_get (atts, SVN_WC__ENTRY_ATTR_COPYFROM_REV, 
                           APR_HASH_KEY_STRING);
    if (revstr)
      {
        entry->copyfrom_rev = SVN_STR_TO_REV (revstr);
        *modify_flags |= SVN_WC__ENTRY_MODIFY_COPYFROM_REV;
      }
  }

  /* Is this entry deleted? */
  {
    const char *deletedstr;
      
    deletedstr = apr_hash_get (atts, SVN_WC__ENTRY_ATTR_DELETED, 
                               APR_HASH_KEY_STRING);
        
    entry->deleted = FALSE;
    if (deletedstr)
      {
        if (! strcmp (deletedstr, "true"))
          entry->deleted = TRUE;
        else if (! strcmp (deletedstr, "false"))
          entry->deleted = FALSE;
        else if (! strcmp (deletedstr, ""))
          entry->deleted = FALSE;
        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_DELETED);

        *modify_flags |= SVN_WC__ENTRY_MODIFY_DELETED;
      }
  }

  /* Is this entry absent? */
  {
    const char *absentstr;
      
    absentstr = apr_hash_get (atts, SVN_WC__ENTRY_ATTR_ABSENT, 
                               APR_HASH_KEY_STRING);
        
    entry->absent = FALSE;
    if (absentstr)
      {
        if (! strcmp (absentstr, "true"))
          entry->absent = TRUE;
        else if (! strcmp (absentstr, "false"))
          entry->absent = FALSE;
        else if (! strcmp (absentstr, ""))
          entry->absent = FALSE;
        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_ABSENT);

        *modify_flags |= SVN_WC__ENTRY_MODIFY_ABSENT;
      }
  }

⌨️ 快捷键说明

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