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

📄 props.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 4 页
字号:
    {
      if (! APR_STATUS_IS_ENOENT (err->apr_err)
          && ! APR_STATUS_IS_ENOTDIR (err->apr_err))
        return err;

      /* nonexistent */
      svn_error_clear (err);
      *empty_p = TRUE;
    }
  else
    {


      /* If we remove props from a propfile, eventually the file will
         contain nothing but "END\n" */
      if (finfo.filetype == APR_REG && finfo.size == 4)  
        *empty_p = TRUE;

      else
        *empty_p = FALSE;

      /* If the size is < 4, then something is corrupt.
         If the size is between 4 and 16, then something is corrupt,
         because 16 is the -smallest- the file can possibly be if it
         contained only one property.  So long as we say it is "not
         empty", we will discover such corruption later when we try
         to read the properties from the file. */
    }

  return SVN_NO_ERROR;
}


/* Simple wrapper around empty_props_p, and inversed. */
svn_error_t *
svn_wc__has_props (svn_boolean_t *has_props,
                   const char *path,
                   svn_wc_adm_access_t *adm_access,
                   apr_pool_t *pool)
{
  svn_boolean_t is_empty;
  const char *prop_path;

  SVN_ERR (svn_wc__prop_path (&prop_path, path, adm_access, FALSE, pool));
  SVN_ERR (empty_props_p (&is_empty, prop_path, pool));

  if (is_empty)
    *has_props = FALSE;
  else
    *has_props = TRUE;

  return SVN_NO_ERROR;
}


svn_error_t *
svn_wc_props_modified_p (svn_boolean_t *modified_p,
                         const char *path,
                         svn_wc_adm_access_t *adm_access,
                         apr_pool_t *pool)
{
  svn_boolean_t bempty, wempty;
  const char *prop_path;
  const char *prop_base_path;
  svn_boolean_t different_filesizes, equal_timestamps;
  const svn_wc_entry_t *entry;
  apr_pool_t *subpool = svn_pool_create (pool);

  /* First, get the paths of the working and 'base' prop files. */
  SVN_ERR (svn_wc__prop_path (&prop_path, path, adm_access, FALSE, subpool));
  SVN_ERR (svn_wc__prop_base_path (&prop_base_path, path, adm_access, FALSE,
                                   subpool));

  /* Decide if either path is "empty" of properties. */
  SVN_ERR (empty_props_p (&wempty, prop_path, subpool));
  SVN_ERR (empty_props_p (&bempty, prop_base_path, subpool));

  /* If something is scheduled for replacement, we do *not* want to
     pay attention to any base-props;  they might be residual from the
     old deleted file. */
  SVN_ERR (svn_wc_entry (&entry, path, adm_access, TRUE, subpool));  
  if (entry && (entry->schedule == svn_wc_schedule_replace))
    {
      *modified_p = wempty ? FALSE : TRUE;
      goto cleanup;        
    }

  /* Easy out:  if the base file is empty, we know the answer
     immediately. */
  if (bempty)
    {
      if (! wempty)
        {
          /* base is empty, but working is not */
          *modified_p = TRUE;
          goto cleanup;
        }
      else
        {
          /* base and working are both empty */
          *modified_p = FALSE;
          goto cleanup;
        }
    }

  /* OK, so the base file is non-empty.  One more easy out: */
  if (wempty)
    {
      /* base exists, working is empty */
      *modified_p = TRUE;
      goto cleanup;
    }

  /* At this point, we know both files exists.  Therefore we have no
     choice but to start checking their contents. */
  
  /* There are at least three tests we can try in succession. */
  
  /* Easy-answer attempt #1:  (### this stat's the files again) */
  
  /* Check if the local and prop-base file have *definitely* different
     filesizes. */
  SVN_ERR (svn_io_filesizes_different_p (&different_filesizes,
                                         prop_path,
                                         prop_base_path,
                                         subpool));
  if (different_filesizes) 
    {
      *modified_p = TRUE;
      goto cleanup;
    }
  
  /* Easy-answer attempt #2:  (### this stat's the files again) */
      
  /* See if the local file's prop timestamp is the same as the one
     recorded in the administrative directory.  */
  SVN_ERR (svn_wc__timestamps_equal_p (&equal_timestamps, path, adm_access,
                                       svn_wc__prop_time, subpool));
  if (equal_timestamps)
    {
      *modified_p = FALSE;
      goto cleanup;
    }
  
  /* Last ditch attempt:  */
  
  /* If we get here, then we know that the filesizes are the same,
     but the timestamps are different.  That's still not enough
     evidence to make a correct decision;  we need to look at the
     files' contents directly.

     However, doing a byte-for-byte comparison won't work.  The two
     properties files may have the *exact* same name/value pairs, but
     arranged in a different order.  (Our hashdump format makes no
     guarantees about ordering.)

     Therefore, rather than use contents_identical_p(), we use
     svn_prop_diffs(). */
  {
    apr_array_header_t *local_propchanges;
    apr_hash_t *localprops = apr_hash_make (subpool);
    apr_hash_t *baseprops = apr_hash_make (subpool);

    /* ### Amazingly, this stats the files again! */
    SVN_ERR (svn_wc__load_prop_file (prop_path, localprops, subpool));
    SVN_ERR (svn_wc__load_prop_file (prop_base_path,
                                     baseprops,
                                     subpool));
    SVN_ERR (svn_prop_diffs (&local_propchanges, localprops, 
                             baseprops, subpool));
                                         
    if (local_propchanges->nelts > 0)
      *modified_p = TRUE;
    else
      *modified_p = FALSE;

    /* If it turns out that there are no differences then we might be able
       to "repair" the prop-time in the entries file and avoid the
       expensive file contents comparison next time.

       ### Unlike the text-time in svn_wc_text_modified_p the only
       ### "legitimate" way to produce a prop-time variation with no
       ### corresponding property variation, is by using the Subversion
       ### property interface.  Perhaps those functions should detect the
       ### change that restores the pristine values and reset the
       ### prop-time?  This code would still be needed, to handle someone
       ### or something manually changing the timestamp on the
       ### prop-base. */
    if (! *modified_p && svn_wc_adm_locked (adm_access))
      {
        svn_wc_entry_t tmp;
        SVN_ERR (svn_io_file_affected_time (&tmp.prop_time, prop_path, pool));
        SVN_ERR (svn_wc__entry_modify (adm_access,
                                       (entry->kind == svn_node_dir
                                        ? SVN_WC_ENTRY_THIS_DIR
                                        : svn_path_basename (path, pool)),
                                       &tmp, SVN_WC__ENTRY_MODIFY_PROP_TIME,
                                       TRUE, pool));
      }
  }
 
 cleanup:
  svn_pool_destroy (subpool);
  
  return SVN_NO_ERROR;
}



svn_error_t *
svn_wc_get_prop_diffs (apr_array_header_t **propchanges,
                       apr_hash_t **original_props,
                       const char *path,
                       svn_wc_adm_access_t *adm_access,
                       apr_pool_t *pool)
{
  const char *prop_path, *prop_base_path;
  apr_array_header_t *local_propchanges;
  apr_hash_t *localprops = apr_hash_make (pool);
  apr_hash_t *baseprops = apr_hash_make (pool);


  SVN_ERR (svn_wc__prop_path (&prop_path, path, adm_access, FALSE, pool));
  SVN_ERR (svn_wc__prop_base_path (&prop_base_path, path, adm_access, FALSE,
                                   pool));

  SVN_ERR (svn_wc__load_prop_file (prop_path, localprops, pool));
  SVN_ERR (svn_wc__load_prop_file (prop_base_path, baseprops, pool));

  if (original_props != NULL)
    *original_props = baseprops;

  /* At this point, if either of the propfiles are non-existent, then
     the corresponding hash is simply empty. */
  
  if (propchanges != NULL)
    {
      SVN_ERR (svn_prop_diffs (&local_propchanges, localprops, 
                               baseprops, pool));      
      *propchanges = local_propchanges;
    }

  return SVN_NO_ERROR;
}



/** Externals **/

svn_error_t *
svn_wc_parse_externals_description2 (apr_array_header_t **externals_p,
                                     const char *parent_directory,
                                     const char *desc,
                                     apr_pool_t *pool)
{
  apr_array_header_t *lines = svn_cstring_split (desc, "\n\r", TRUE, pool);
  int i;
  
  if (externals_p)
    *externals_p = apr_array_make (pool, 1, sizeof (svn_wc_external_item_t *));

  for (i = 0; i < lines->nelts; i++)
    {
      const char *line = APR_ARRAY_IDX (lines, i, const char *);
      apr_array_header_t *line_parts;
      svn_wc_external_item_t *item;

      if ((! line) || (line[0] == '#'))
        continue;

      /* else proceed */

      line_parts = svn_cstring_split (line, " \t", TRUE, pool);

      item = apr_palloc (pool, sizeof (*item));

      if (line_parts->nelts < 2)
        goto parse_error;

      else if (line_parts->nelts == 2)
        {
          /* No "-r REV" given. */
          item->target_dir = APR_ARRAY_IDX (line_parts, 0, const char *);
          item->url = APR_ARRAY_IDX (line_parts, 1, const char *);
          item->revision.kind = svn_opt_revision_head;
        }
      else if ((line_parts->nelts == 3) || (line_parts->nelts == 4))
        {
          /* We're dealing with one of these two forms:
           * 
           *    TARGET_DIR  -rN  URL
           *    TARGET_DIR  -r N  URL
           * 
           * Handle either way.
           */

          const char *r_part_1 = NULL, *r_part_2 = NULL;

          item->target_dir = APR_ARRAY_IDX (line_parts, 0, const char *);
          item->revision.kind = svn_opt_revision_number;

          if (line_parts->nelts == 3)
            {
              r_part_1 = APR_ARRAY_IDX (line_parts, 1, const char *);
              item->url = APR_ARRAY_IDX (line_parts, 2, const char *);
            }
          else  /* nelts == 4 */
            {
              r_part_1 = APR_ARRAY_IDX (line_parts, 1, const char *);
              r_part_2 = APR_ARRAY_IDX (line_parts, 2, const char *);
              item->url = APR_ARRAY_IDX (line_parts, 3, const char *);
            }

          if ((! r_part_1) || (r_part_1[0] != '-') || (r_part_1[1] != 'r'))
            goto parse_error;

          if (! r_part_2)  /* "-rN" */
            {
              if (strlen (r_part_1) < 3)
                goto parse_error;
              else
                item->revision.value.number = SVN_STR_TO_REV (r_part_1 + 2);
            }
          else             /* "-r N" */
            {
              if (strlen (r_part_2) < 1)
                goto parse_error;
              else
                item->revision.value.number = SVN_STR_TO_REV (r_part_2);
            }
        }
      else    /* too many items on line */
        goto parse_error;

      if (0)
        {
        parse_error:
          return svn_error_createf
            (SVN_ERR_CLIENT_INVALID_EXTERNALS_DESCRIPTION, NULL,
             _("Error parsing %s property on '%s': '%s'"),
             SVN_PROP_EXTERNALS, parent_directory, line);
        }

      item->target_dir = svn_path_canonicalize
        (svn_path_internal_style (item->target_dir, pool), pool);
      {
        if (item->target_dir[0] == '\0' || item->target_dir[0] == '/'
            || svn_path_is_backpath_present (item->target_dir))
          return svn_error_createf
            (SVN_ERR_CLIENT_INVALID_EXTERNALS_DESCRIPTION, NULL,
             _("Invalid %s property on '%s': "
               "target involves '.' or '..' or is an absolute path"),
             SVN_PROP_EXTERNALS, parent_directory);
      }

      item->url = svn_path_canonicalize (item->url, pool);

      if (externals_p)
        APR_ARRAY_PUSH (*externals_p, svn_wc_external_item_t *) = item;
    }

  return SVN_NO_ERROR;
}


svn_error_t *
svn_wc_parse_externals_description (apr_hash_t **externals_p,
                                    const char *parent_directory,
                                    const char *desc,
                                    apr_pool_t *pool)
{
  apr_array_header_t *list;
  int i;

  SVN_ERR (svn_wc_parse_externals_description2 (externals_p ? &list : NULL,
                                                parent_directory, desc, pool));

  /* Store all of the items into the hash if that was requested. */
  if (externals_p)
    {
      *externals_p = apr_hash_make (pool);
      for (i = 0; i < list->nelts; i++)
        {
          svn_wc_external_item_t *item;
          item = APR_ARRAY_IDX (list, i, svn_wc_external_item_t *);

          apr_hash_set (*externals_p, item->target_dir,
                        APR_HASH_KEY_STRING, item);
        }
    }
  return SVN_NO_ERROR;
}

⌨️ 快捷键说明

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