<commit_before>/*
 * depth_filter_editor.c -- provide a svn_delta_editor_t which wraps
 *                          another editor and provides depth-based filtering
 *
 * ====================================================================
 * 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 "svn_delta.h"



/*** Batons, and the Toys That Create Them ***/

struct edit_baton
{
  const svn_delta_editor_t *wrapped_editor;
  void *wrapped_edit_baton;
  svn_depth_t requested_depth;
  svn_boolean_t has_target;
  int actual_depth;
};

struct node_baton
{
  svn_boolean_t filtered;
  void *edit_baton;
  void *wrapped_baton;
};

/* Allocate and return a new node_baton structure, populated via the
   the input to this helper function. */
static struct node_baton *
make_node_baton(void *edit_baton,
                svn_boolean_t filtered,
                apr_pool_t *pool)
{
  struct node_baton *b = apr_palloc(pool, sizeof(*b));
  b->edit_baton = edit_baton;
  b->wrapped_baton = NULL;
  b->filtered = filtered;
  return b;
}

static svn_boolean_t
okay_to_edit(struct edit_baton *eb,
             struct node_baton *pb,
             svn_node_kind_t kind)
{
  int effective_depth;

  if (pb->filtered)
    return FALSE;

  effective_depth = eb->actual_depth - (eb->has_target ? 1 : 0);
  switch (eb->requested_depth)
    {
    case svn_depth_infinity:
      return TRUE;
    case svn_depth_empty:
      return (kind == svn_node_dir && effective_depth <= 0);
    case svn_depth_files:
      return ((effective_depth <= 0)
              || (kind == svn_node_file && effective_depth == 1));
    case svn_depth_immediates:
      return (effective_depth <= 1);
    default:
      break;
    }
  abort();
}



/*** Editor Functions ***/

static svn_error_t *
set_target_revision(void *edit_baton,
                    svn_revnum_t target_revision,
                    apr_pool_t *pool)
{
  struct edit_baton *eb = edit_baton;

  /* Nothing depth-y to filter here. */
 return eb->wrapped_editor->set_target_revision(eb->wrapped_edit_baton,
                                                target_revision, pool);
}

static svn_error_t *
open_root(void *edit_baton,
          svn_revnum_t base_revision,
          apr_pool_t *pool,
          void **root_baton)
{
  struct edit_baton *eb = edit_baton;
  struct node_baton *b;

  /* The root node always gets through cleanly. */
  b = make_node_baton(edit_baton, FALSE, pool);
  SVN_ERR(eb->wrapped_editor->open_root(eb->wrapped_edit_baton, base_revision,
                                        pool, &b->wrapped_baton));

  eb->actual_depth++;
  *root_baton = b;
  return SVN_NO_ERROR;
}

static svn_error_t *
delete_entry(const char *path,
             svn_revnum_t base_revision,
             void *parent_baton,
             apr_pool_t *pool)
{
  struct node_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;

  /* Don't delete children of filtered nodes. */
  if (pb->filtered)
    return SVN_NO_ERROR;

  /* ### FIXME: Because we don't know the type of the entry, we don't
     know if it's okay to really delete it or not.  For example, if
     we're filtering for depth=files and this is a delete of a
     subdirectory, we don't want to really delete the thing. */
  if (eb->requested_depth == svn_depth_infinity)
    SVN_ERR(eb->wrapped_editor->delete_entry(path, base_revision,
                                             pb->wrapped_baton, pool));

  return SVN_NO_ERROR;
}

static svn_error_t *
add_directory(const char *path,
              void *parent_baton,
              const char *copyfrom_path,
              svn_revnum_t copyfrom_revision,
              apr_pool_t *pool,
              void **child_baton)
{
  struct node_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;
  struct node_baton *b = NULL;

  /* Check for sufficient depth. */
  if (okay_to_edit(eb, pb, svn_node_dir))
    {
      b = make_node_baton(eb, FALSE, pool);
      SVN_ERR(eb->wrapped_editor->add_directory(path, pb->wrapped_baton,
                                                copyfrom_path,<commit_msg>* libsvn_delta/depth_filter_editor.c   (okay_to_edit): Move the "infinity" case to the bottom, and note     that it shouldn't get hit anyway (though there's no danger if it does).   (delete_entry): Use okay_to_edit(), but claim the to-be-deleted item     is a file.  Update the FIXME comment to explain why this isn't ideal.<commit_after>/*
 * depth_filter_editor.c -- provide a svn_delta_editor_t which wraps
 *                          another editor and provides depth-based filtering
 *
 * ====================================================================
 * 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 "svn_delta.h"



/*** Batons, and the Toys That Create Them ***/

struct edit_baton
{
  const svn_delta_editor_t *wrapped_editor;
  void *wrapped_edit_baton;
  svn_depth_t requested_depth;
  svn_boolean_t has_target;
  int actual_depth;
};

struct node_baton
{
  svn_boolean_t filtered;
  void *edit_baton;
  void *wrapped_baton;
};

/* Allocate and return a new node_baton structure, populated via the
   the input to this helper function. */
static struct node_baton *
make_node_baton(void *edit_baton,
                svn_boolean_t filtered,
                apr_pool_t *pool)
{
  struct node_baton *b = apr_palloc(pool, sizeof(*b));
  b->edit_baton = edit_baton;
  b->wrapped_baton = NULL;
  b->filtered = filtered;
  return b;
}

static svn_boolean_t
okay_to_edit(struct edit_baton *eb,
             struct node_baton *pb,
             svn_node_kind_t kind)
{
  int effective_depth;

  if (pb->filtered)
    return FALSE;

  effective_depth = eb->actual_depth - (eb->has_target ? 1 : 0);
  switch (eb->requested_depth)
    {
    case svn_depth_empty:
      return (kind == svn_node_dir && effective_depth <= 0);
    case svn_depth_files:
      return ((effective_depth <= 0)
              || (kind == svn_node_file && effective_depth == 1));
    case svn_depth_immediates:
      return (effective_depth <= 1);
    case svn_depth_infinity:
      return TRUE; /* Shouldn't reach; see svn_delta_depth_filter_editor() */
    default:
      break;
    }
  abort();
}



/*** Editor Functions ***/

static svn_error_t *
set_target_revision(void *edit_baton,
                    svn_revnum_t target_revision,
                    apr_pool_t *pool)
{
  struct edit_baton *eb = edit_baton;

  /* Nothing depth-y to filter here. */
 return eb->wrapped_editor->set_target_revision(eb->wrapped_edit_baton,
                                                target_revision, pool);
}

static svn_error_t *
open_root(void *edit_baton,
          svn_revnum_t base_revision,
          apr_pool_t *pool,
          void **root_baton)
{
  struct edit_baton *eb = edit_baton;
  struct node_baton *b;

  /* The root node always gets through cleanly. */
  b = make_node_baton(edit_baton, FALSE, pool);
  SVN_ERR(eb->wrapped_editor->open_root(eb->wrapped_edit_baton, base_revision,
                                        pool, &b->wrapped_baton));

  eb->actual_depth++;
  *root_baton = b;
  return SVN_NO_ERROR;
}

static svn_error_t *
delete_entry(const char *path,
             svn_revnum_t base_revision,
             void *parent_baton,
             apr_pool_t *pool)
{
  struct node_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;

  /* ### FIXME: We don't know the type of the entry, which ordinarily
     doesn't matter, but is a key (*the* key, in fact) distinction
     between depth "files" and depths "immediates".  If the server is
     telling us to delete a subdirectory and our requested depth was
     "immediates", that's fine; if our requested depth was "files",
     though, this deletion shouldn't survive filtering.  For now,
     we'll claim to our helper function that the to-be-deleted thing
     is a file because that's the conservative route to take. */
  if (okay_to_edit(eb, pb, svn_node_file))
    SVN_ERR(eb->wrapped_editor->delete_entry(path, base_revision,
                                             pb->wrapped_baton, pool));

  return SVN_NO_ERROR;
}

static svn_error_t *
add_directory(const char *path,
              void *parent_baton,
              const char *copyfrom_path,
              svn_revnum_t copyfrom_revision,
              apr_pool_t *pool,
              void **child_baton)
{
  struct node_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;
  struct node_baton *b = NULL;

  /* Check for sufficient depth. */
  if (okay_to_edit(eb, pb, svn_node_dir))
    {
      b = make_node_baton(eb, FALSE, pool);
      SVN_ERR(eb->wrapped_editor->add_directory(path, pb->wrapped_baton,
                                                copyfrom_path,
{'fraction_non_alphanumeric': 0.11462530217566479, 'fraction_numerical': 0.0030217566478646252, 'mean_word_length': 2.823257604928764, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3391909', 'n_tokens_mistral': 3209, 'n_tokens_neox': 3121, 'n_words': 862}