[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] svn cat

From: Vladimir Prus <ghost_at_cs.msu.su>
Date: 2002-11-13 10:17:06 CET

The following patch works quite OK for me. There are two problems:
1. I did not written any tests, and don't have the time right now.
Maybe later. (BTW, I don't see any tests of "ls")

2. If I do

    svn cat some-file

then *repository* version of that file is printed. Printing wc version
seems doable in a couple of lines, but I don't know which behaviour is
best.

Log message:
Implement the 'cat' command.

* subversion/include/svn_error_codes.h
    (SVN_ERR_CLIENT_CAT_OF_DIRECTORY): New error code.

* subversion/include/svn_client.h
    (svn_client_cat): New function.

* subversion/libsvn_client/cat.c: New file.

* subversion/clients/cmdline/cl.h
    (svn_cl__cat): New command.

* subversion/clients/cmdline/cat-cmd.c: New file

* subversion/clients/cmdline/main.c: Add 'cat' to
    the list of command and document it.

Patch:
Index: subversion/include/svn_error_codes.h
===================================================================
--- subversion/include/svn_error_codes.h (revision 3772)
+++ subversion/include/svn_error_codes.h (working copy)
@@ -50,16 +50,16 @@
  #if defined(SVN_ERROR_BUILD_ARRAY)

  #define SVN_ERROR_START \
- static const err_defn error_table[] = { \
- { SVN_WARNING, "Warning" },
+ static const err_defn error_table[] = { \
+ { SVN_WARNING, "Warning" },
  #define SVN_ERRDEF(num, offset, str) { num, str },
  #define SVN_ERROR_END { 0, NULL } };

  #elif !defined(SVN_ERROR_ENUM_DEFINED)

  #define SVN_ERROR_START \
- typedef enum svn_errno_t { \
- SVN_WARNING = APR_OS_START_USERERR + 1,
+ typedef enum svn_errno_t { \
+ SVN_WARNING = APR_OS_START_USERERR + 1,
  #define SVN_ERRDEF(num, offset, str) num = offset,
  #define SVN_ERROR_END SVN_ERR_LAST } svn_errno_t;

@@ -600,6 +600,11 @@
    SVN_ERRDEF (SVN_ERR_CLIENT_MODIFIED,
                SVN_ERR_CLIENT_CATEGORY_START + 6,
                "Attempting restricted operation for modified resource")
+
+ SVN_ERRDEF (SVN_ERR_CLIENT_CAT_OF_DIRECTORY,
+ SVN_ERR_CLIENT_CATEGORY_START + 7,
+ "Invoked 'cat' operation on a directory")
+

    /* misc errors */

Index: subversion/include/svn_client.h
===================================================================
--- subversion/include/svn_client.h (revision 3772)
+++ subversion/include/svn_client.h (working copy)
@@ -935,6 +935,21 @@
                 apr_pool_t *pool);

+/* Output the content of file identified by URL and REVISION to
+ the stream OUT.
+
+ Use AUTH_BATON to authenticate against the repository.
+
+ Perform all allocations from POOL.
+*/
+svn_error_t *
+svn_client_cat (svn_stream_t* out,
+ const char *url,
+ const svn_opt_revision_t *revision,
+ svn_client_auth_baton_t *auth_baton,
+ apr_pool_t *pool);
+
+
  #ifdef __cplusplus
  }
  #endif /* __cplusplus */
Index: subversion/libsvn_client/cat.c
===================================================================
--- subversion/libsvn_client/cat.c (working copy)
+++ subversion/libsvn_client/cat.c (working copy)
@@ -0,0 +1,82 @@
+/*
+ * cat.c: implementation of the 'cat' command
+ *
+ * ====================================================================
+ * Copyright (c) 2000-2002 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/.
+ * ====================================================================
+ */
+
+/* ==================================================================== */
+
+
+
+/*** Includes. ***/
+
+#include <assert.h>
+
+#include "svn_wc.h"
+#include "svn_client.h"
+#include "svn_string.h"
+#include "svn_error.h"
+#include "svn_path.h"
+#include "svn_io.h"
+#include "client.h"
+
+
+
+/*** Code. ***/
+
+svn_error_t *
+svn_client_cat (svn_stream_t* out,
+ const char *url,
+ const svn_opt_revision_t *revision,
+ svn_client_auth_baton_t *auth_baton,
+ apr_pool_t *pool)
+{
+ svn_ra_plugin_t *ra_lib;
+ void *ra_baton, *session;
+ svn_revnum_t rev;
+ svn_node_kind_t url_kind;
+
+ /* Get the RA library that handles URL. */
+ SVN_ERR (svn_ra_init_ra_libs (&ra_baton, pool));
+ SVN_ERR (svn_ra_get_ra_library (&ra_lib, ra_baton, url, pool));
+
+ /* Open a repository session to the URL. */
+ SVN_ERR (svn_client__open_ra_session (&session, ra_lib, url, NULL, NULL,
+ NULL, FALSE, FALSE,
+ auth_baton, pool));
+
+ /* Resolve REVISION into a real revnum. */
+ SVN_ERR (svn_client__get_revision_number (&rev, ra_lib, session,
+ revision, NULL, pool));
+ if (! SVN_IS_VALID_REVNUM (rev))
+ SVN_ERR (ra_lib->get_latest_revnum (session, &rev));
+
+ /* Decide if the URL is a file or directory. */
+ SVN_ERR (ra_lib->check_path (&url_kind, session, "", rev));
+
+ if (url_kind == svn_node_dir)
+
+ return svn_error_createf(SVN_ERR_CLIENT_CAT_OF_DIRECTORY, 0, NULL,
+ "URL \"%s\" refers to directory", url);
+
+ /* Get the file */
+ SVN_ERR (ra_lib->get_file(session, "", rev, out, NULL, NULL));
+
+ SVN_ERR (ra_lib->close (session));
+
+
+
+ return SVN_NO_ERROR;
+}
Index: subversion/clients/cmdline/cl.h
===================================================================
--- subversion/clients/cmdline/cl.h (revision 3772)
+++ subversion/clients/cmdline/cl.h (working copy)
@@ -130,7 +130,8 @@
    svn_cl__resolve,
    svn_cl__status,
    svn_cl__switch,
- svn_cl__update;
+ svn_cl__update,
+ svn_cl__cat;

  /* See definition in main.c for documentation. */
Index: subversion/clients/cmdline/cat-cmd.c
===================================================================
--- subversion/clients/cmdline/cat-cmd.c (working copy)
+++ subversion/clients/cmdline/cat-cmd.c (working copy)
@@ -0,0 +1,74 @@
+/*
+ * cat-cmd.c -- Print the content of a file or URL.
+ *
+ * ====================================================================
+ * Copyright (c) 2000-2002 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/.
+ * ====================================================================
+ */
+
+/* ==================================================================== */
+
+
+
+/*** Includes. ***/
+
+#include "svn_wc.h"
+#include "svn_client.h"
+#include "svn_string.h"
+#include "svn_path.h"
+#include "svn_delta.h"
+#include "svn_error.h"
+#include "cl.h"
+
+
+/*** Code. ***/
+
+/* This implements the `svn_opt_subcommand_t' interface. */
+svn_error_t *
+svn_cl__cat (apr_getopt_t *os,
+ void *baton,
+ apr_pool_t *pool)
+{
+ svn_cl__opt_state_t *opt_state = baton;
+ apr_array_header_t *targets;
+ int i;
+ svn_client_auth_baton_t *auth_baton;
+
+ SVN_ERR (svn_opt_args_to_target_array (&targets, os,
+ opt_state->targets,
+ &(opt_state->start_revision),
+ &(opt_state->end_revision),
+ FALSE, pool));
+
+ /* Build an authentication baton to give to libsvn_client. */
+ auth_baton = svn_cl__make_auth_baton (opt_state, pool);
+
+ for (i = 0; i < targets->nelts; i++)
+ {
+ const char *target = ((const char **) (targets->elts))[i];
+ svn_stream_t *out = svn_stream_from_stdio (stdout, pool);
+ const char *URL;
+
+ SVN_ERR (svn_cl__get_url_from_target (&URL, target, pool));
+ if (! URL)
+ return svn_error_createf (SVN_ERR_ENTRY_MISSING_URL, 0, NULL,
+ "'%s' has no URL", target);
+
+ SVN_ERR (svn_client_cat
+ (out,
+ URL, &(opt_state->start_revision),
+ auth_baton, pool));
+ }
+
+ return SVN_NO_ERROR;
+}
Index: subversion/clients/cmdline/main.c
===================================================================
--- subversion/clients/cmdline/main.c (revision 3772)
+++ subversion/clients/cmdline/main.c (working copy)
@@ -117,6 +117,13 @@
      "usage: svn add TARGETS\n",
      {svn_cl__targets_opt, 'R', 'q'} },

+ { "cat", svn_cl__cat, {0},
+ "Output the content of specified files or URLS.\n"
+ "usage: svn add TARGETS\n\n"
+ "When working copy file is specified, the repository version of\n"
+ "that file is printed\n",
+ {'r'} },
+
    { "checkout", svn_cl__checkout, {"co"},
      "Check out a working copy from a repository.\n"
      "usage: svn checkout REPOS_URL [REPOS_URL...] [DESTINATION]\n"
@@ -626,8 +633,8 @@
          }
          break;
        case svn_cl__targets_opt:
- {
- svn_stringbuf_t *buffer, *buffer_utf8;
+ {
+ svn_stringbuf_t *buffer, *buffer_utf8;

            /* We need to convert to UTF-8 now, even before we divide
               the targets into an array, because otherwise we wouldn't
@@ -639,15 +646,15 @@
              err = svn_stringbuf_from_file (&buffer, utf8_opt_arg, pool);
            if (! err)
              err = svn_utf_stringbuf_to_utf8 (&buffer_utf8, buffer, pool);
- if (err)
- {
- svn_handle_error (err, stdout, FALSE);
- svn_pool_destroy (pool);
- return EXIT_FAILURE;
- }
- opt_state.targets = svn_cstring_split (buffer_utf8->data, "\n\r",
+ if (err)
+ {
+ svn_handle_error (err, stdout, FALSE);
+ svn_pool_destroy (pool);
+ return EXIT_FAILURE;
+ }
+ opt_state.targets = svn_cstring_split (buffer_utf8->data, "\n\r",
                                                   TRUE, pool);
- }
+ }
          break;
        case svn_cl__force_opt:
          opt_state.force = TRUE;

- Volodya

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Wed Nov 13 10:17:22 2002

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.