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

📄 prop_commands.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 3 页
字号:
      item->prop_hash = prop_hash;
      
      *((svn_client_proplist_item_t **) apr_array_push (list)) = item;
    }
}


/* Helper for the remote case of svn_client_proplist.
 *
 * Push a new 'svn_client_proplist_item_t *' item onto PROPLIST,
 * containing the properties for "TARGET_PREFIX/TARGET_RELATIVE" in
 * REVNUM, obtained using RA_LIB and SESSION.  The item->node_name
 * will be "TARGET_PREFIX/TARGET_RELATIVE", and the value will be a
 * hash mapping 'const char *' property names onto 'svn_string_t *'
 * property values.  
 *
 * Allocate the new item and its contents in POOL.
 * Do all looping, recursion, and temporary work in SCRATCHPOOL.
 *
 * KIND is the kind of the node at "TARGET_PREFIX/TARGET_RELATIVE".
 *
 * If RECURSE is true and KIND is svn_node_dir, then recurse.
 */
static svn_error_t *
remote_proplist (apr_array_header_t *proplist,
                 const char *target_prefix,
                 const char *target_relative,
                 svn_node_kind_t kind,
                 svn_revnum_t revnum,
                 svn_ra_plugin_t *ra_lib,
                 void *session,
                 svn_boolean_t recurse,
                 apr_pool_t *pool,
                 apr_pool_t *scratchpool)
{
  apr_hash_t *dirents;
  apr_hash_t *prop_hash, *final_hash;
  apr_hash_index_t *hi;
 
  if (kind == svn_node_dir)
    {
      SVN_ERR (ra_lib->get_dir (session, target_relative, revnum,
                                (recurse ? &dirents : NULL),
                                NULL, &prop_hash, scratchpool));
    }
  else if (kind == svn_node_file)
    {
      SVN_ERR (ra_lib->get_file (session, target_relative, revnum,
                                 NULL, NULL, &prop_hash, scratchpool));
    }
  else
    {
      return svn_error_createf
        (SVN_ERR_NODE_UNKNOWN_KIND, NULL,
         _("Unknown node kind for '%s'"),
         svn_path_join (target_prefix, target_relative, pool));
    }
  
  /* Filter out non-regular properties, since the RA layer returns all
     kinds.  Copy regular properties keys/vals from the prop_hash
     allocated in SCRATCHPOOL to the "final" hash allocated in POOL. */
  final_hash = apr_hash_make (pool);
  for (hi = apr_hash_first (scratchpool, prop_hash);
       hi;
       hi = apr_hash_next (hi))
    {
      const void *key;
      apr_ssize_t klen;
      void *val;
      svn_prop_kind_t prop_kind;      
      const char *name;
      svn_string_t *value;

      apr_hash_this (hi, &key, &klen, &val);
      prop_kind = svn_property_kind (NULL, (const char *) key);
      
      if (prop_kind == svn_prop_regular_kind)
        {
          name = apr_pstrdup (pool, (const char *) key);
          value = svn_string_dup ((svn_string_t *) val, pool);
          apr_hash_set (final_hash, name, klen, value);
        }
    }
  
  push_props_on_list (proplist, final_hash,
                      svn_path_join (target_prefix, target_relative,
                                     scratchpool),
                      pool);
  
  if (recurse && (kind == svn_node_dir) && (apr_hash_count (dirents) > 0))
    {
      apr_pool_t *subpool = svn_pool_create (scratchpool);
      
      for (hi = apr_hash_first (scratchpool, dirents);
           hi;
           hi = apr_hash_next (hi))
        {
          const void *key;
          void *val;
          const char *this_name;
          svn_dirent_t *this_ent;
          const char *new_target_relative;

          svn_pool_clear (subpool);

          apr_hash_this (hi, &key, NULL, &val);
          this_name = key;
          this_ent = val;

          new_target_relative = svn_path_join (target_relative,
                                               this_name, subpool);

          SVN_ERR (remote_proplist (proplist,
                                    target_prefix,
                                    new_target_relative,
                                    this_ent->kind,
                                    revnum,
                                    ra_lib,
                                    session,
                                    recurse,
                                    pool,
                                    subpool));
        }

      svn_pool_destroy (subpool);
    }

  return SVN_NO_ERROR;
}


/* Push an 'svn_client_proplist_item_t *' item onto PROP_LIST, where
 * item->node_name is an 'svn_stringbuf_t *' created from NODE_NAME,
 * and item->prop_hash is the property hash for NODE_NAME.
 *
 * If PRISTINE is true, get base props, else get working props.
 *
 * Allocate the item and its contents in POOL.
 */
static svn_error_t *
add_to_proplist (apr_array_header_t *prop_list,
                 const char *node_name,
                 svn_wc_adm_access_t *adm_access,
                 svn_boolean_t pristine,
                 apr_pool_t *pool)
{
  apr_hash_t *hash;

  SVN_ERR (pristine_or_working_props (&hash, node_name, adm_access, pristine,
                                      pool));
  push_props_on_list (prop_list, hash, node_name, pool);

  return SVN_NO_ERROR;
}

/* A baton for proplist_walk_cb. */
struct proplist_walk_baton
{
  svn_boolean_t pristine;  /* Select base rather than working props. */
  svn_wc_adm_access_t *base_access;  /* Access for the tree being walked. */
  apr_array_header_t *props;  /* Out: array of svn_client_proplist_item_t. */
};

/* An entries-walk callback for svn_client_proplist.
 * 
 * For the path given by PATH and ENTRY,
 * populate wb->PROPS with a svn_client_proplist_item_t for each path,
 * where "wb" is the WALK_BATON of type "struct proplist_walk_baton *".
 * If wb->PRISTINE is true, use the base values, else use the working values.
 */
static svn_error_t *
proplist_walk_cb (const char *path,
                  const svn_wc_entry_t *entry,
                  void *walk_baton,
                  apr_pool_t *pool)
{
  struct proplist_walk_baton *wb = walk_baton;

  /* We're going to receive dirents twice;  we want to ignore the
     first one (where it's a child of a parent dir), and only use
     the second one (where we're looking at THIS_DIR).  */
  if ((entry->kind == svn_node_dir)
      && (strcmp (entry->name, SVN_WC_ENTRY_THIS_DIR) != 0))
    return SVN_NO_ERROR;

  /* Ignore the entry if it does not exist at the time of interest. */
  if (entry->schedule
      == (wb->pristine ? svn_wc_schedule_add : svn_wc_schedule_delete))
    return SVN_NO_ERROR;

  path = apr_pstrdup (wb->props->pool, path);
  SVN_ERR (add_to_proplist (wb->props, path, wb->base_access,
                            wb->pristine, wb->props->pool));

  return SVN_NO_ERROR;
}


/* Note: this implementation is very similar to svn_client_propget. */
svn_error_t *
svn_client_proplist (apr_array_header_t **props,
                     const char *target, 
                     const svn_opt_revision_t *revision,
                     svn_boolean_t recurse,
                     svn_client_ctx_t *ctx,
                     apr_pool_t *pool)
{
  svn_wc_adm_access_t *adm_access;
  const svn_wc_entry_t *node;
  const char *utarget;  /* target, or the url for target */
  const char *url;
  svn_revnum_t revnum;

  *props = apr_array_make (pool, 5, sizeof (svn_client_proplist_item_t *));

  SVN_ERR (maybe_convert_to_url (&utarget, target, revision, pool));

  /* Iff utarget is a url, that means we must use it, that is, the
     requested property information is not available locally. */
  if (svn_path_is_url (utarget))
    {
      void *session;
      svn_ra_plugin_t *ra_lib;
      svn_node_kind_t kind;

      /* Get an RA plugin for this filesystem object. */
      SVN_ERR (svn_client__ra_lib_from_path (&ra_lib, &session, &revnum,
                                             &url, target, revision,
                                             ctx, pool));
      
      SVN_ERR (ra_lib->check_path (session, "", revnum, &kind, pool));

      SVN_ERR (remote_proplist (*props, url, "",
                                kind, revnum, ra_lib, session,
                                recurse, pool, svn_pool_create (pool)));
    }
  else  /* working copy path */
    {
      svn_boolean_t pristine;

      SVN_ERR (svn_wc_adm_probe_open2 (&adm_access, NULL, target,
                                       FALSE, recurse ? -1 : 0, pool));
      SVN_ERR (svn_wc_entry (&node, target, adm_access, FALSE, pool));
      if (! node)
        return svn_error_createf 
          (SVN_ERR_UNVERSIONED_RESOURCE, NULL,
           _("'%s' is not under version control"), target);
      
      SVN_ERR (svn_client__get_revision_number
               (&revnum, NULL, NULL, revision, target, pool));

      if ((revision->kind == svn_opt_revision_committed)
          || (revision->kind == svn_opt_revision_base))
        {
          pristine = TRUE;
        }
      else  /* must be the working revision */
        {
          pristine = FALSE;
        }

      /* Fetch, recursively or not. */
      if (recurse && (node->kind == svn_node_dir))
        {
          static const svn_wc_entry_callbacks_t walk_callbacks
            = { proplist_walk_cb };
          struct proplist_walk_baton wb;

          wb.base_access = adm_access;
          wb.props = *props;
          wb.pristine = pristine;

          SVN_ERR (svn_wc_walk_entries (target, adm_access,
                                        &walk_callbacks, &wb, FALSE, pool));
        }
      else 
        SVN_ERR (add_to_proplist (*props, target, adm_access, pristine, pool));
      
      SVN_ERR (svn_wc_adm_close (adm_access));
    }

  return SVN_NO_ERROR;
}


svn_error_t *
svn_client_revprop_list (apr_hash_t **props,
                         const char *URL,
                         const svn_opt_revision_t *revision,
                         svn_revnum_t *set_rev,
                         svn_client_ctx_t *ctx,
                         apr_pool_t *pool)
{
  void *ra_baton, *session;
  svn_ra_plugin_t *ra_lib;
  apr_hash_t *proplist;

  /* Open an RA session for the URL. Note that we don't have a local
     directory, nor a place to put temp files. */
  SVN_ERR (svn_ra_init_ra_libs (&ra_baton, pool));
  SVN_ERR (svn_ra_get_ra_library (&ra_lib, ra_baton, URL, pool));
  SVN_ERR (svn_client__open_ra_session (&session, ra_lib, URL, NULL,
                                        NULL, NULL, FALSE, TRUE,
                                        ctx, pool));

  /* Resolve the revision into something real, and return that to the
     caller as well. */
  SVN_ERR (svn_client__get_revision_number
           (set_rev, ra_lib, session, revision, NULL, pool));

  /* The actual RA call. */
  SVN_ERR (ra_lib->rev_proplist (session, *set_rev, &proplist, pool));

  *props = proplist;
  return SVN_NO_ERROR;
}

⌨️ 快捷键说明

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