Rob Siemborski wrote:
>
> On Thu, 25 Jul 2002, Blair Zajac wrote:
>
> > I started a patch to factor out the usage stuff for svnadmin and
> > svnlook, but it's way out of date, back in April revision 1642. If
> > somebody wants to pick it up where I stopped, I can send the diffs
> > out. I'm afraid they'll need a ton of integration into the current
> > tree.
>
> Since I started this whole thing, and it sounds simple enough (from a
> getting-to-know-the-code perspective), I'd be willing to take a look if
> you sent me the diffs.
Here you go. I don't have a log message yet for the work that I started.
The hardest part is that svn passes around a pointer to a large structure
specific for itself and its subcommands that I changed to a void * so that
it could be used by svnadmin and svnlook. There are also some static
functions for svn that needed to get moved into a public library and I
choose libsvn_subr.
The diff is large but a lot of it is just moving code around from one
file to another to get static functions into the library. I also
wouldn't try to apply it to the current tree, rather just copy what
was done and use the current tree.
Best,
Blair
--
Blair Zajac <blair@orcaware.com>
Web and OS performance plots - http://www.orcaware.com/orca/
Index: ./subversion/include/svn_getopt.h
===================================================================
--- ./subversion/include/svn_getopt.h
+++ ./subversion/include/svn_getopt.h Fri Mar 15 13:21:34 2002
@@ -0,0 +1,281 @@
+/*
+ * svn_getopt.h: command line processing and usage utilities
+ *
+ * ====================================================================
+ * 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/.
+ * ====================================================================
+ */
+
+/* ==================================================================== */
+
+
+#ifndef SVN_GETOPT_H
+#define SVN_GETOPT_H
+
+/*** Includes. ***/
+#include "apr_getopt.h"
+
+#include "svn_error.h"
+
+/*** Defines. ***/
+
+/* This is the maximum number of aliases a command can have. */
+#define SVN_CL__MAX_ALIASES 3
+
+/* This is the maximum number of options accepted by a single command.
+ Each value in the array is a unique enum which is the 2nd field in
+ the apr_getopt_option_t. */
+#define SVN_CL__MAX_OPTS 15
+
+
+/*** Command dispatch. ***/
+
+/* All client command functions conform to this prototype. ARGS
+ * contains the list of non command line options passed to the
+ * program. Most of the time ARGS will be a list of filenames and
+ * directories, a-la CVS (which really only becomes useful if you pass
+ * it into svn_cl__args_to_target_array() to convert ARGS to an APR
+ * array of svn_stringbuf_t * targets). To enable different programs
+ * to do common command line preprocessing for multiple command
+ * functions before calling the appropriate command function, OPT_DATA
+ * is a void * that can be used to pass arbitrary data in.
+ */
+struct svn_getopt_t;
+typedef svn_error_t *(svn_cl__cmd_proc_t) (struct svn_getopt_t *args,
+ void *opt_data,
+ apr_pool_t *pool);
+
+
+/* One element of the command dispatch table. The caller creates a
+ table of these for each command that the program supports. */
+typedef struct svn_cl__cmd_desc_t
+{
+ /* The full name of this command. */
+ const char *name;
+
+ /* The function this command invokes. */
+ svn_cl__cmd_proc_t *cmd_func;
+
+ /* A list of alias names for this command. */
+ const char *aliases[SVN_CL__MAX_ALIASES+1];
+
+ /* A brief string describing this command, for usage messages. */
+ const char *help;
+
+ /* A list of options accepted by this command. Each value in the
+ array is a unique enum (the 2nd field in apr_getopt_option_t). */
+ int valid_options[SVN_CL__MAX_OPTS];
+} svn_cl__cmd_desc_t;
+
+typedef struct svn_getopt_t {
+ apr_getopt_t *options;
+ const apr_getopt_option_t *option_table;
+ const svn_cl__cmd_desc_t *command_table;
+ int num_received_opts;
+ int received_opts[SVN_CL__MAX_OPTS];
+ const char* received_args[SVN_CL__MAX_OPTS];
+ const svn_cl__cmd_desc_t *subcommand;
+} svn_getopt_t;
+
+/*** Functions. ***/
+
+/* Initialize the arguments for parsing. This should be used in place
+ of apr_getopt_init(). */
+apr_status_t
+svn_getopt_init(svn_getopt_t **os, apr_pool_t *pool,
+ int argc, const char * const *argv,
+ const apr_getopt_option_t *option_table,
+ const svn_cl__cmd_desc_t *command_table);
+
+svn_error_t *
+svn_cl__help (svn_getopt_t *os, void *help_info_, apr_pool_t *pool);
+
+/* Given a command name COMMAND_NAME and a table of command dispatch
+ functions (svn_cl__cmd_desc_t[]), COMMAND_TABLE, and a pool POOL,
+ print the usage of the command. This function is also used by
+ subcommands that need to print a usage message. */
+void
+svn_cl__print_subcommand_help (const char *command_name,
+ const svn_getopt_t *os,
+ apr_pool_t *pool);
+
+/* Given a command name COMMAND_NAME and a table of command dispatch
+ functions (svn_cl__cmd_desc_t[]), COMMAND_TABLE, return a pointer
+ to the svn_cl__cmd_desc_t whose name matches COMMAND_NAME or NULL if
+ none mathces. COMMAND_NAME may be an alias. */
+const svn_cl__cmd_desc_t *
+svn_cl__get_canonical_command (const char *command_name,
+ const svn_cl__cmd_desc_t *command_table);
+
+/* Create a targets array and add all the remaining arguments
+ to it. We also process arguments passed in the --target file, if
+ specified, just as if they were passed on the command line. */
+apr_array_header_t *
+svn_cl__args_to_target_array (const svn_getopt_t *os,
+ apr_array_header_t *cmd_targets,
+ apr_pool_t *pool);
+
+/* Print the canonical command name for CMD, all its aliases,
+ and if HELP is set, print the help string for the command too. */
+void
+svn_cl__print_command_info (const svn_cl__cmd_desc_t *cmd_desc,
+ const svn_getopt_t *os,
+ svn_boolean_t help,
+ apr_pool_t *pool,
+ FILE *stream);
+
+/* Look up CODE in OPTION_TABLE. If any option in the table has this
+ enum code, return a pointer to the option. Else return NULL. */
+const apr_getopt_option_t *
+svn_cl__get_option_from_enum (int code,
+ const apr_getopt_option_t *option_table);
+
+
+
+/*** Miscellaneous utility commands ***/
+
+/* Parse all of the arguments from the command line args passed in by
+ the user. Put them into ARGS. */
+svn_error_t *
+svn_cl__parse_all_args (apr_array_header_t **args,
+ const svn_getopt_t *os,
+ const char *subcommand,
+ apr_pool_t *pool);
+
+/* Parse a given number of non-target arguments from the command line
+ args passed in by the user. Put them into the passed in ARGS
+ array. */
+svn_error_t *
+svn_cl__parse_num_args (apr_array_header_t **args,
+ const svn_getopt_t *os,
+ const char *subcommand,
+ int num_args,
+ apr_pool_t *pool);
+
+/* Print an option OPT nicely into a STRING allocated in POOL. If DOC
+ is set, include generic documentation string of option.*/
+void
+svn_cl__format_option (char **string,
+ const apr_getopt_option_t *opt,
+ svn_boolean_t doc,
+ apr_pool_t *pool);
+
+/* Create a SVN string from the char* and add it to the array. */
+void
+array_push_svn_stringbuf (apr_array_header_t *array,
+ const char *str,
+ apr_pool_t *pool);
+
+#if 0
+
+/* Look up CODE in OPTION_TABLE. If any option in the table has this
+ enum code, return a pointer to the option. Else return NULL. */
+const apr_getopt_option_t *
+svn_cl__get_option_from_enum (int code,
+ const apr_getopt_option_t *option_table);
+
+
+void svn_cl__push_implicit_dot_target (apr_array_header_t *targets,
+ apr_pool_t *pool);
+
+
+void
+svn_cl__subcommand_help (const char *subcommand,
+ apr_pool_t *pool);
+
+
+/*** Command-line output functions -- printing to the user. ***/
+
+/* Print a hash that maps property names (char *) to property values
+ (svn_stringbuf_t *). */
+void svn_cl__print_prop_hash (apr_hash_t *prop_hash, apr_pool_t *pool);
+
+/* Print out the property names in a hash that maps property names (char *)
+ to property values (svn_stringbuf_t *). */
+void svn_cl__print_prop_names (apr_hash_t *prop_hash, apr_pool_t *pool);
+
+/* Returns an editor that prints out events in an update or checkout. */
+svn_error_t *
+svn_cl__get_trace_update_editor (const svn_delta_edit_fns_t **editor,
+ void **edit_baton,
+ svn_stringbuf_t *initial_path,
+ apr_pool_t *pool);
+
+/* Returns an editor that prints out events in a commit. */
+svn_error_t *
+svn_cl__get_trace_commit_editor (const svn_delta_edit_fns_t **editor,
+ void **edit_baton,
+ svn_stringbuf_t *initial_path,
+ apr_pool_t *pool);
+
+
+/* Search for a text editor command in standard environment variables,
+ and invoke it to edit CONTENTS (using a temporary file based on
+ working copy directory BASE_DIR). Return the new contents in
+ EDITED_CONTENTS, or set EDITED_CONTENTS to NULL if no edit was
+ performed. Use POOL for all allocations. */
+svn_error_t *
+svn_cl__edit_externally (svn_stringbuf_t **edited_contents,
+ svn_stringbuf_t *base_dir,
+ const svn_string_t *contents,
+ apr_pool_t *pool);
+
+
+/* Our implementation of the 'auth info callback' routine,
+ as defined in svn_client.h. This callback is passed to any
+ libsvn_client routine that needs to authenticate against a
+ repository. */
+
+/* Display PROMPT to the user, and read a reply back from stdin,
+ allocated in POOL and returned in *RESULT. If HIDE is set, the
+ reply will not be echoed to the screen. BATON is ignored (but
+ required by the definition of svn_client_auth_info_callback_t.) */
+svn_error_t *
+svn_cl__prompt_user (char **result,
+ const char *prompt,
+ svn_boolean_t hide,
+ void *baton,
+ apr_pool_t *pool);
+
+/* Helper for subcommands: given parsed OPT_STATE arguments from the
+ command-line, put auth info into a structure to pass to libsvn_client. */
+svn_client_auth_baton_t *
+svn_cl__make_auth_baton (svn_cl__opt_state_t *opt_state,
+ apr_pool_t *pool);
+
+/* Fills in the first four characters of STR_STATUS with status code
+ characters, based on TEXT_STATUS, PROP_STATUS, LOCKED, and COPIED.*/
+void
+svn_cl__generate_status_codes (char *str_status,
+ enum svn_wc_status_kind text_status,
+ enum svn_wc_status_kind prop_status,
+ svn_boolean_t locked,
+ svn_boolean_t copied);
+
+
+/*** Notification functions to display results on the terminal. */
+
+void svn_cl__notify_func (void *baton,
+ svn_wc_notify_action_t action,
+ const char *path);
+void *svn_cl__make_notify_baton (apr_pool_t *pool);
+
+#endif
+
+#endif /* SVN_GETOPT_H */
+
+/*
+ * local variables:
+ * eval: (load-file "../../tools/dev/svn-dev.el")
+ * end:
+ */
Index: ./subversion/libsvn_subr/svn_getopt.c
===================================================================
--- ./subversion/libsvn_subr/svn_getopt.c
+++ ./subversion/libsvn_subr/svn_getopt.c Fri Mar 15 13:21:54 2002
@@ -0,0 +1,546 @@
+/*
+ * svn_getopt.c: command line processing and usage utility functions
+ *
+ * ====================================================================
+ * 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/.
+ * ====================================================================
+ */
+
+
+
+#include "svn_getopt.h"
+#include "svn_path.h"
+#include "svn_string.h"
+#include "svn_wc.h"
+#include "svn_version.h"
+
+#define DEFAULT_ARRAY_SIZE 5
+
+/* Return TRUE iff subcommand COMMAND has OPTION_CODE listed within
+ it. Else return FALSE. */
+static svn_boolean_t
+subcommand_takes_option (const svn_cl__cmd_desc_t *command,
+ int option_code)
+{
+ int i;
+
+ for (i = 0; i < SVN_CL__MAX_OPTS; i++)
+ {
+ if (command->valid_options[i] == option_code)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static svn_error_t *
+print_version_info (apr_pool_t *pool)
+{
+ void *ra_baton;
+ svn_stringbuf_t *descriptions;
+ static const char info[] =
+ "Copyright (C) 2000-2002 CollabNet.\n"
+ "Subversion is open source software, see http://subversion.tigris.org/\n";
+
+ printf ("Subversion Client, version %s\n", SVN_VERSION);
+ printf (" compiled %s, %s\n\n", __DATE__, __TIME__);
+ printf ("%s\n", info);
+
+ printf ("The following repository access (RA) modules are available:\n\n");
+
+ /* Get a hash full of all available RA libraries. */
+ SVN_ERR (svn_ra_init_ra_libs (&ra_baton, pool));
+
+ /* Get a descriptive list of them. */
+ SVN_ERR (svn_ra_print_ra_libraries (&descriptions, ra_baton, pool));
+
+ printf ("%s\n", descriptions->data);
+
+ return SVN_NO_ERROR;
+}
+
+
+/* Print a generic (non-command-specific) usage message. */
+static void
+svn_cl__print_generic_help (svn_getopt_t *os, apr_pool_t *pool, FILE *stream)
+{
+ static const char usage[] =
+ "usage: svn <subcommand> [options] [args]\n"
+ "Type \"svn help <subcommand>\" for help on a specific subcommand.\n"
+ "\n"
+ "Most subcommands take file and/or directory arguments, recursing\n"
+ "on the directories. If no arguments are supplied to such a\n"
+ "command, it will recurse on the current directory (inclusive) by\n"
+ "default.\n"
+ "\n"
+ "Available subcommands:\n";
+
+ static const char info[] =
+ "Subversion is a tool for revision control.\n"
+ "For additional information, see http://subversion.tigris.org\n";
+
+ int i = 0;
+
+ fprintf (stream, "%s", usage);
+
+ if (os)
+ {
+ const svn_cl__cmd_desc_t *command_table = os->command_table;
+ while (command_table[i].name)
+ {
+ fprintf (stream, " ");
+ svn_cl__print_command_info (command_table + i, os, FALSE, pool, stream);
+ fprintf (stream, "\n");
+ i++;
+ }
+ }
+
+ fprintf (stream, "\n");
+ fprintf (stream, "%s\n", info);
+}
+
+
+/* Print either generic help, or command-specific help for each
+ * command in os->args. OPT_STATE is only examined for the
+ * '--version' switch. If OS is null then generic help will always be
+ * printed.
+ *
+ * Unlike all the other command routines, ``help'' has its own
+ * option processing.
+ */
+typedef struct help_info_t {
+ apr_array_header_t *cmd_targets;
+ int version;
+} help_info_t;
+
+svn_error_t *
+svn_cl__help (svn_getopt_t *os,
+ void *help_info_,
+ apr_pool_t *pool)
+{
+ help_info_t *help_info = (help_info_t *)help_info_;
+ apr_array_header_t *targets = NULL;
+ int i;
+
+ if (os)
+ targets = svn_cl__args_to_target_array (os,
+ help_info ? help_info->cmd_targets : NULL,
+ pool);
+
+ if (targets && targets->nelts) /* help on subcommand(s) requested */
+ for (i = 0; i < targets->nelts; i++)
+ {
+ svn_stringbuf_t *this = (((svn_stringbuf_t **) (targets)->elts))[i];
+ svn_cl__print_subcommand_help (this->data, os, pool);
+ }
+ else if (help_info && help_info->version) /* just -v or --version */
+ SVN_ERR (print_version_info (pool));
+ else if (os && !targets->nelts) /* `-h', `--help', or `help' */
+ svn_cl__print_generic_help (os, pool, stdout);
+ else /* unknown option or cmd */
+ svn_cl__print_generic_help (os, pool, stderr);
+
+ return SVN_NO_ERROR;
+}
+
+
+/* Initialize the arguments for parsing. This should be used in place
+ of apr_getopt_init(). */
+apr_status_t
+svn_getopt_init(svn_getopt_t **os, apr_pool_t *pool,
+ int argc, const char * const *argv,
+ const apr_getopt_option_t *option_table,
+ const svn_cl__cmd_desc_t *command_table)
+{
+ apr_status_t apr_err;
+ const char *first_arg;
+ int i;
+
+ *os = apr_palloc(pool, sizeof(**os));
+ (*os)->option_table = option_table;
+ (*os)->command_table = command_table;
+ (*os)->num_received_opts = 0;
+ (*os)->received_args[0] = 0;
+ (*os)->received_opts[0] = 0;
+
+ apr_err = apr_getopt_init (&((*os)->options), pool, argc, argv);
+ if (apr_err != APR_SUCCESS) {
+ return apr_err;
+ }
+
+ /* Parse the options. */
+ (*os)->options->interleave = 1;
+ while (1)
+ {
+ int opt_id;
+ const char *opt_arg;
+
+ /* Parse the next option. */
+ apr_err = apr_getopt_long ((*os)->options, option_table,
+ &opt_id, &opt_arg);
+ if (APR_STATUS_IS_EOF (apr_err))
+ break;
+ else if (! APR_STATUS_IS_SUCCESS (apr_err))
+ {
+ svn_cl__help (NULL, NULL, pool);
+ return EXIT_FAILURE;
+ }
+
+ /* Stash the option code in an array before parsing it. */
+ (*os)->received_args[(*os)->num_received_opts] = opt_arg;
+ (*os)->received_opts[(*os)->num_received_opts] = opt_id;
+ ((*os)->num_received_opts)++;
+ }
+
+ /* Check if there are any remaining arguments on the command line. */
+ if ((*os)->options->ind >= (*os)->options->argc) {
+ fprintf (stderr, "subcommand argument required\n");
+ return EXIT_FAILURE;
+ }
+
+ /* Look for a subcommand in the first argument. */
+ first_arg = (*os)->options->argv[(*os)->options->ind++];
+ (*os)->subcommand = svn_cl__get_canonical_command (first_arg,
+ command_table);
+ if ((*os)->subcommand == NULL)
+ {
+ /* FIXME: should we print "unknown foo" ?? seems ok */
+ fprintf (stderr, "unknown command: %s\n", first_arg);
+ svn_cl__help (NULL, NULL, pool);
+ return EXIT_FAILURE;
+ }
+
+ /* Check if this subcommand wasn't passed any inappropriate
+ options. */
+ for (i=0; i<(*os)->num_received_opts; i++)
+ if (! subcommand_takes_option ((*os)->subcommand, (*os)->received_opts[i]))
+ {
+ char *optstr;
+ const apr_getopt_option_t *badopt =
+ svn_cl__get_option_from_enum ((*os)->received_opts[i], option_table);
+ svn_cl__format_option (&optstr, badopt, FALSE, pool);
+ fprintf (stderr,
+ "\nError: subcommand '%s' doesn't accept option '%s'\n\n",
+ (*os)->subcommand->name, optstr);
+ svn_cl__print_subcommand_help ((*os)->subcommand->name, *os, pool);
+ return EXIT_FAILURE;
+ }
+
+ return APR_SUCCESS;
+}
+
+
+/* Given a command name COMMAND_NAME and a table of command dispatch
+ functions (svn_cl__cmd_desc_t[]), COMMAND_TABLE, return a pointer
+ to the svn_cl__cmd_desc_t whose name matches COMMAND_NAME or NULL
+ if none mathces. COMMAND_NAME may be an alias. */
+const svn_cl__cmd_desc_t *
+svn_cl__get_canonical_command (const char *command_name,
+ const svn_cl__cmd_desc_t *command_table)
+{
+ int i = 0;
+
+ if (command_name == NULL)
+ return NULL;
+
+ while (command_table[i].name) {
+ int j;
+ if (strcmp (command_name, command_table[i].name) == 0)
+ return command_table + i;
+ for (j = 0;
+ (j < SVN_CL__MAX_ALIASES) && command_table[i].aliases[j];
+ j++)
+ if (strcmp (command_name, command_table[i].aliases[j]) == 0)
+ return command_table + i;
+
+ i++;
+ }
+
+ /* If we get here, there was no matching command name or alias. */
+ return NULL;
+}
+
+/* Create a targets array and add all the remaining arguments
+ to it. We also process arguments passed in the --target file, if
+ specified, just as if they were passed on the command line. */
+apr_array_header_t *
+svn_cl__args_to_target_array (const svn_getopt_t *os,
+ apr_array_header_t *cmd_targets,
+ apr_pool_t *pool)
+{
+ apr_getopt_t *options = os->options;
+ apr_array_header_t *targets =
+ apr_array_make (pool, DEFAULT_ARRAY_SIZE, sizeof (svn_stringbuf_t *));
+
+ /* Command line args take precendence. */
+ for (; options->ind < options->argc; options->ind++)
+ {
+ svn_stringbuf_t *target = svn_stringbuf_create (options->argv[options->ind],
+ pool);
+ svn_string_t tstr;
+
+ /* If this path looks like it would work as a URL in one of the
+ currently available RA libraries, we add it unconditionally
+ to the target array. */
+ tstr.data = target->data;
+ tstr.len = target->len;
+ if (! svn_path_is_url (&tstr))
+ {
+ const char *basename = svn_path_basename (target->data, pool);
+
+ /* If this target is a Subversion administrative directory,
+ skip it. TODO: Perhaps this check should not call the
+ target a SVN admin dir unless svn_wc_check_wc passes on
+ the target, too? */
+ if (! strcmp (basename, SVN_WC_ADM_DIR_NAME))
+ continue;
+ }
+ else
+ {
+ svn_path_canonicalize (target);
+ }
+ (*((svn_stringbuf_t **) apr_array_push (targets))) = target;
+ }
+
+ /* Now args from --targets, if any */
+ if (NULL != cmd_targets)
+ apr_array_cat(targets, cmd_targets);
+
+ /* kff todo: need to remove redundancies from targets before
+ passing it to the cmd_func. */
+
+ return targets;
+}
+
+/* Given a command name COMMAND_NAME and a table of command dispatch
+ functions (svn_cl__cmd_desc_t[]), COMMAND_TABLE, and a pool POOL,
+ print the usage of the command. This function is also used by
+ subcommands that need to print a usage message. */
+void
+svn_cl__print_subcommand_help (const char* command_name,
+ const svn_getopt_t *os,
+ apr_pool_t *pool)
+{
+ const svn_cl__cmd_desc_t *cmd =
+ svn_cl__get_canonical_command (command_name, os->command_table);
+
+ if (cmd)
+ svn_cl__print_command_info (cmd, os, TRUE, pool, stdout);
+ else
+ fprintf (stderr, "\"%s\": unknown command.\n\n", command_name);
+}
+
+
+/* Print an option OPT nicely into a STRING allocated in POOL. If DOC
+ is set, include generic documentation string of option.*/
+void
+svn_cl__format_option (char **string,
+ const apr_getopt_option_t *opt,
+ svn_boolean_t doc,
+ apr_pool_t *pool)
+{
+ char *opts;
+
+ if (opt == NULL)
+ *string = apr_psprintf (pool, "?");
+
+ if (opt->optch <= 255)
+ opts = apr_psprintf (pool, "-%c [--%s]", opt->optch, opt->name);
+ else
+ opts = apr_psprintf (pool, "--%s", opt->name);
+
+ if (opt->has_arg)
+ opts = apr_pstrcat (pool, opts, " arg", NULL);
+
+ if (doc)
+ opts = apr_pstrcat (pool, opts, ":\t", opt->description, NULL);
+
+ *string = opts;
+}
+
+/* Print the canonical command name for CMD, all its aliases,
+ and if HELP is set, print the help string for the command too. */
+void
+svn_cl__print_command_info (const svn_cl__cmd_desc_t *cmd_desc,
+ const svn_getopt_t *os,
+ svn_boolean_t help,
+ apr_pool_t *pool,
+ FILE *stream)
+{
+ const apr_getopt_option_t *option_table = os->option_table;
+ const svn_cl__cmd_desc_t *command_table = os->command_table;
+ const svn_cl__cmd_desc_t *canonical_cmd
+ = svn_cl__get_canonical_command (cmd_desc->name, command_table);
+ svn_boolean_t first_time;
+ int i;
+
+ /* Print the canonical command name. */
+ fputs (canonical_cmd->name, stream);
+
+ /* Print the list of aliases. */
+ first_time = TRUE;
+ for (i = 0; i < SVN_CL__MAX_ALIASES; i++)
+ {
+ if (canonical_cmd->aliases[i] == NULL)
+ break;
+
+ if (first_time) {
+ fprintf (stream, " (");
+ first_time = FALSE;
+ }
+ else
+ fprintf (stream, ", ");
+
+ fprintf (stream, "%s", canonical_cmd->aliases[i]);
+ }
+
+ if (! first_time)
+ fprintf (stream, ")");
+
+ if (help)
+ {
+ const apr_getopt_option_t *option;
+ svn_boolean_t have_options = FALSE;
+
+ fprintf (stream, ": %s", canonical_cmd->help);
+
+ /* Loop over all valid option codes attached to the subcommand */
+ for (i = 0; i < SVN_CL__MAX_OPTS; i++)
+ {
+ if (canonical_cmd->valid_options[i])
+ {
+ if (have_options == FALSE)
+ {
+ fprintf (stream, "\nValid options:\n");
+ have_options = TRUE;
+ }
+
+ /* convert each option code into an option */
+ option =
+ svn_cl__get_option_from_enum (canonical_cmd->valid_options[i],
+ option_table);
+
+ /* print the option's docstring */
+ if (option)
+ {
+ char *optstr;
+ svn_cl__format_option (&optstr, option, TRUE, pool);
+ fprintf (stream, " %s\n", optstr);
+ }
+ }
+ }
+
+ if (have_options)
+ fprintf (stream, "\n");
+ }
+}
+
+const apr_getopt_option_t *
+svn_cl__get_option_from_enum (int code,
+ const apr_getopt_option_t *option_table)
+{
+ int i;
+ const apr_getopt_option_t *opt = NULL;
+
+ for (i = 0; i < SVN_CL__MAX_OPTS; i++)
+ {
+ if (option_table[i].optch == code)
+ {
+ opt = &(option_table[i]);
+ break;
+ }
+ }
+
+ return opt;
+}
+
+/* Create a SVN string from the char* and add it to the array. */
+void
+array_push_svn_stringbuf (apr_array_header_t *array,
+ const char *str,
+ apr_pool_t *pool)
+{
+ (*((svn_stringbuf_t **) apr_array_push (array)))
+ = svn_stringbuf_create (str, pool);
+}
+
+/* Parse all of the arguments from the command line args passed in by
+ the user. Put them into ARGS. */
+svn_error_t *
+svn_cl__parse_all_args (apr_array_header_t **args,
+ const svn_getopt_t *os,
+ const char *subcommand,
+ apr_pool_t *pool)
+{
+ apr_getopt_t *options = os->options;
+
+ *args = apr_array_make (pool,
+ DEFAULT_ARRAY_SIZE,
+ sizeof (svn_stringbuf_t *));
+
+ if (options->ind >= options->argc)
+ {
+ svn_cl__print_subcommand_help (subcommand, os, pool);
+ return svn_error_create (SVN_ERR_CL_ARG_PARSING_ERROR, 0, 0, pool, "");
+ }
+
+ while (options->ind < options->argc)
+ {
+ array_push_svn_stringbuf (*args,
+ options->argv[options->ind++],
+ pool);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* Parse a given number of non-target arguments from the command line
+ args passed in by the user. Put them into the passed in ARGS
+ array. */
+svn_error_t *
+svn_cl__parse_num_args (apr_array_header_t **args,
+ const svn_getopt_t *os,
+ const char *subcommand,
+ int num_args,
+ apr_pool_t *pool)
+{
+ apr_getopt_t *options = os->options;
+ int i;
+
+ *args = apr_array_make (pool,
+ DEFAULT_ARRAY_SIZE,
+ sizeof (svn_stringbuf_t *));
+
+ /* loop for num_args and add each arg to the args array */
+ for (i = 0; i < num_args; i++)
+ {
+ if (options->ind >= options->argc)
+ {
+ svn_cl__print_subcommand_help (subcommand, os, pool);
+ return svn_error_create (SVN_ERR_CL_ARG_PARSING_ERROR,
+ 0, 0, pool, "");
+ }
+ array_push_svn_stringbuf (*args,
+ options->argv[options->ind++],
+ pool);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
+/* --------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../tools/dev/svn-dev.el")
+ * end:
+ */
Index: ./subversion/clients/cmdline/merge-cmd.c
===================================================================
--- ./subversion/clients/cmdline/merge-cmd.c
+++ ./subversion/clients/cmdline/merge-cmd.c Thu Apr 4 17:17:13 2002
@@ -35,10 +35,11 @@
/*** Code. ***/
svn_error_t *
-svn_cl__merge (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__merge (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
apr_array_header_t *options;
apr_array_header_t *targets;
apr_array_header_t *condensed_targets;
@@ -47,7 +48,7 @@
options = svn_cl__stringlist_to_array (opt_state->extensions, pool);
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
svn_cl__push_implicit_dot_target (targets, pool);
SVN_ERR (svn_path_remove_redundancies (&condensed_targets,
targets,
Index: ./subversion/clients/cmdline/cl.h
===================================================================
--- ./subversion/clients/cmdline/cl.h
+++ ./subversion/clients/cmdline/cl.h Thu Apr 4 16:13:23 2002
@@ -25,8 +25,8 @@
/*** Includes. ***/
#include <apr_tables.h>
-#include <apr_getopt.h>
+#include "svn_getopt.h"
#include "svn_wc.h"
#include "svn_client.h"
#include "svn_string.h"
@@ -84,7 +84,6 @@
svn_boolean_t verbose;
svn_boolean_t very_verbose;
svn_boolean_t update;
- apr_array_header_t *args;
/* TODO fixme. This still doesn't handle binary data from a file! */
svn_stringbuf_t *filedata;
svn_boolean_t help;
@@ -97,25 +96,6 @@
apr_array_header_t *targets;
} svn_cl__opt_state_t;
-
-/* All client command procedures conform to this prototype. OPT_STATE
- * likewise should hold the result of processing the options. OS is a
- * list of filenames and directories, a-la CVS (which really only
- * becomes useful if you pass it into svn_cl__args_to_target_array()
- * to convert OS to an APR arra of svn_stringbuf_t * targets).
- *
- * TARGETS is normalized by main before being passed to any command
- * (with the exception of svn_cl__help, which will oftentime be passed
- * an empty array of targets. That is, all duplicates are removed, and
- * all paths are made relative to the working copy root directory). */
-typedef svn_error_t *(svn_cl__cmd_proc_t) (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
- apr_pool_t *pool);
-
-
-
-
-
/* Declare all the command procedures */
svn_cl__cmd_proc_t
svn_cl__add,
@@ -125,7 +105,6 @@
svn_cl__copy,
svn_cl__delete,
svn_cl__diff,
- svn_cl__help,
svn_cl__import,
svn_cl__log,
svn_cl__merge,
@@ -143,11 +122,6 @@
svn_cl__update;
-/* Print a generic (non-command-specific) usage message. */
-void
-svn_cl__print_generic_help (apr_pool_t *pool, FILE *stream);
-
-
/* Print out commit information found in COMMIT_INFO to the console. */
void
svn_cl__print_commit_info (svn_client_commit_info_t *commit_info);
@@ -155,25 +129,10 @@
/*** Miscellaneous utility commands ***/
-/* Look up CODE in OPTION_TABLE. If any option in the table has this
- enum code, return a pointer to the option. Else return NULL. */
-const apr_getopt_option_t *
-svn_cl__get_option_from_enum (int code,
- const apr_getopt_option_t *option_table);
-
-
void svn_cl__push_svn_string (apr_array_header_t *array,
const char *str,
apr_pool_t *pool);
-/* Subcommands call this to pull any args left into the array of targets.
- This includes any extra args passed in the file specified by
- --targets. */
-apr_array_header_t*
-svn_cl__args_to_target_array (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
- apr_pool_t *pool);
-
/* Splits a list of whitespace-separated values into an apr_array_header_t */
apr_array_header_t*
svn_cl__stringlist_to_array (svn_stringbuf_t *buffer, apr_pool_t *pool);
@@ -185,23 +144,6 @@
void svn_cl__push_implicit_dot_target (apr_array_header_t *targets,
apr_pool_t *pool);
-svn_error_t *
-svn_cl__parse_num_args (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
- const char *subcommand,
- int num_args,
- apr_pool_t *pool);
-
-svn_error_t *
-svn_cl__parse_all_args (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
- const char *subcommand,
- apr_pool_t *pool);
-
-void
-svn_cl__subcommand_help (const char *subcommand,
- apr_pool_t *pool);
-
/*** Command-line output functions -- printing to the user. ***/
@@ -342,4 +284,3 @@
* eval: (load-file "../../../tools/dev/svn-dev.el")
* end:
*/
-
Index: ./subversion/clients/cmdline/checkout-cmd.c
===================================================================
--- ./subversion/clients/cmdline/checkout-cmd.c
+++ ./subversion/clients/cmdline/checkout-cmd.c Fri Mar 8 09:11:18 2002
@@ -34,16 +34,18 @@
/*** Code. ***/
svn_error_t *
-svn_cl__checkout (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__checkout (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
+ apr_array_header_t *args;
const svn_delta_editor_t *trace_editor;
void *trace_edit_baton;
int i;
svn_client_auth_baton_t *auth_baton;
- SVN_ERR (svn_cl__parse_all_args (os, opt_state, "checkout", pool));
+ SVN_ERR (svn_cl__parse_all_args (&args, os, "checkout", pool));
/* Put commandline auth info into a baton for libsvn_client. */
auth_baton = svn_cl__make_auth_baton (opt_state, pool);
@@ -88,11 +90,11 @@
(args->nelts == 1) or (args->nelts > 1). -Fitz
*/
- for (i = 0; i < opt_state->args->nelts; i++)
+ for (i = 0; i < args->nelts; i++)
{
svn_stringbuf_t *local_dir;
svn_stringbuf_t *repos_url
- = ((svn_stringbuf_t **) (opt_state->args->elts))[0];
+ = ((svn_stringbuf_t **) (args->elts))[0];
/* Canonicalize the URL. */
/* ### um. this function isn't really designed for URLs... */
Index: ./subversion/clients/cmdline/propdel-cmd.c
===================================================================
--- ./subversion/clients/cmdline/propdel-cmd.c
+++ ./subversion/clients/cmdline/propdel-cmd.c Thu Apr 4 17:10:06 2002
@@ -34,21 +34,23 @@
/*** Code. ***/
svn_error_t *
-svn_cl__propdel (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__propdel (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
+ apr_array_header_t *args;
svn_stringbuf_t *pname;
apr_array_header_t *targets;
int i;
- SVN_ERR (svn_cl__parse_num_args (os, opt_state, "propdel", 1, pool));
+ SVN_ERR (svn_cl__parse_num_args (&args, os, "propdel", 1, pool));
/* Get the property's name. */
- pname = ((svn_stringbuf_t **) (opt_state->args->elts))[0];
+ pname = ((svn_stringbuf_t **) (args->elts))[0];
/* Suck up all the remaining arguments into a targets array */
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
/* Add "." if user passed 0 file arguments */
svn_cl__push_implicit_dot_target (targets, pool);
Index: ./subversion/clients/cmdline/move-cmd.c
===================================================================
--- ./subversion/clients/cmdline/move-cmd.c
+++ ./subversion/clients/cmdline/move-cmd.c Thu Apr 4 16:13:23 2002
@@ -35,20 +35,21 @@
/*** Code. ***/
svn_error_t *
-svn_cl__move (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__move (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
apr_array_header_t *targets;
svn_stringbuf_t *src_path, *dst_path;
svn_client_auth_baton_t *auth_baton = NULL;
svn_client_commit_info_t *commit_info = NULL;
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
if (targets->nelts != 2)
{
- svn_cl__subcommand_help ("move", pool);
+ svn_cl__print_subcommand_help ("move", os, pool);
return svn_error_create (SVN_ERR_CL_ARG_PARSING_ERROR, 0, 0, pool, "");
}
Index: ./subversion/clients/cmdline/mkdir-cmd.c
===================================================================
--- ./subversion/clients/cmdline/mkdir-cmd.c
+++ ./subversion/clients/cmdline/mkdir-cmd.c Thu Apr 4 16:13:23 2002
@@ -35,16 +35,17 @@
/*** Code. ***/
svn_error_t *
-svn_cl__mkdir (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__mkdir (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
apr_array_header_t *targets;
svn_client_auth_baton_t *auth_baton = NULL;
int i;
svn_client_commit_info_t *commit_info = NULL;
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
/* Build an authentication object to give to libsvn_client. */
auth_baton = svn_cl__make_auth_baton (opt_state, pool);
@@ -66,7 +67,7 @@
}
else
{
- svn_cl__subcommand_help ("mkdir", pool);
+ svn_cl__print_subcommand_help ("mkdir", os, pool);
return svn_error_create (SVN_ERR_CL_ARG_PARSING_ERROR, 0, 0, pool, "");
}
Index: ./subversion/clients/cmdline/revert-cmd.c
===================================================================
--- ./subversion/clients/cmdline/revert-cmd.c
+++ ./subversion/clients/cmdline/revert-cmd.c Thu Mar 14 16:24:20 2002
@@ -33,15 +33,16 @@
/*** Code. ***/
svn_error_t *
-svn_cl__revert (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__revert (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
apr_array_header_t *targets;
int i;
svn_boolean_t recursive = opt_state->recursive;
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
/* Revert has no implicit dot-target `.', so don't you put that code
here! */
@@ -59,7 +60,7 @@
}
else
{
- svn_cl__subcommand_help ("revert", pool);
+ svn_cl__print_subcommand_help ("revert", os, pool);
return svn_error_create (SVN_ERR_CL_ARG_PARSING_ERROR, 0, 0, pool, "");
}
Index: ./subversion/clients/cmdline/diff-cmd.c
===================================================================
--- ./subversion/clients/cmdline/diff-cmd.c
+++ ./subversion/clients/cmdline/diff-cmd.c Tue Mar 12 18:08:15 2002
@@ -36,10 +36,11 @@
/* An svn_cl__cmd_proc_t to handle the 'diff' command. */
svn_error_t *
-svn_cl__diff (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__diff (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
apr_array_header_t *options;
apr_array_header_t *targets;
apr_array_header_t *condensed_targets;
@@ -50,7 +51,7 @@
options = svn_cl__stringlist_to_array (opt_state->extensions, pool);
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
svn_cl__push_implicit_dot_target (targets, pool);
SVN_ERR (svn_path_remove_redundancies (&condensed_targets,
targets,
Index: ./subversion/clients/cmdline/copy-cmd.c
===================================================================
--- ./subversion/clients/cmdline/copy-cmd.c
+++ ./subversion/clients/cmdline/copy-cmd.c Thu Apr 4 16:52:24 2002
@@ -35,10 +35,11 @@
/*** Code. ***/
svn_error_t *
-svn_cl__copy (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__copy (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
apr_array_header_t *targets;
svn_stringbuf_t *src_path, *dst_path;
svn_string_t path_str;
@@ -48,10 +49,10 @@
svn_boolean_t src_is_url, dst_is_url;
svn_client_commit_info_t *commit_info = NULL;
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
if (targets->nelts != 2)
{
- svn_cl__subcommand_help ("copy", pool);
+ svn_cl__print_subcommand_help ("copy", os, pool);
return svn_error_create (SVN_ERR_CL_ARG_PARSING_ERROR, 0, 0, pool, "");
}
Index: ./subversion/clients/cmdline/util.c
===================================================================
--- ./subversion/clients/cmdline/util.c
+++ ./subversion/clients/cmdline/util.c Thu Apr 4 16:13:24 2002
@@ -45,18 +45,6 @@
#define DEFAULT_ARRAY_SIZE 5
-/* Hmm. This should probably find its way into libsvn_subr -Fitz */
-/* Create a SVN string from the char* and add it to the array */
-static void
-array_push_svn_stringbuf (apr_array_header_t *array,
- const char *str,
- apr_pool_t *pool)
-{
- (*((svn_stringbuf_t **) apr_array_push (array)))
- = svn_stringbuf_create (str, pool);
-}
-
-
/* Some commands take an implicit "." string argument when invoked
* with no arguments. Those commands make use of this function to
* add "." to the target array if the user passes no args */
@@ -69,112 +57,6 @@
assert (targets->nelts);
}
-/* Parse a given number of non-target arguments from the
- * command line args passed in by the user. Put them
- * into the opt_state args array */
-svn_error_t *
-svn_cl__parse_num_args (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
- const char *subcommand,
- int num_args,
- apr_pool_t *pool)
-{
- int i;
-
- opt_state->args = apr_array_make (pool, DEFAULT_ARRAY_SIZE,
- sizeof (svn_stringbuf_t *));
-
- /* loop for num_args and add each arg to the args array */
- for (i = 0; i < num_args; i++)
- {
- if (os->ind >= os->argc)
- {
- svn_cl__subcommand_help (subcommand, pool);
- return svn_error_create (SVN_ERR_CL_ARG_PARSING_ERROR,
- 0, 0, pool, "");
- }
- array_push_svn_stringbuf (opt_state->args, os->argv[os->ind++], pool);
- }
-
- return SVN_NO_ERROR;
-}
-
-/* Parse all of the arguments from the command line args
- * passed in by the user. Put them into the opt_state
- * args array */
-svn_error_t *
-svn_cl__parse_all_args (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
- const char *subcommand,
- apr_pool_t *pool)
-{
- opt_state->args = apr_array_make (pool, DEFAULT_ARRAY_SIZE,
- sizeof (svn_stringbuf_t *));
-
- if (os->ind >= os->argc)
- {
- svn_cl__subcommand_help (subcommand, pool);
- return svn_error_create (SVN_ERR_CL_ARG_PARSING_ERROR, 0, 0, pool, "");
- }
-
- while (os->ind < os->argc)
- {
- array_push_svn_stringbuf (opt_state->args, os->argv[os->ind++], pool);
- }
-
- return SVN_NO_ERROR;
-}
-
-/* Create a targets array and add all the remaining arguments
- * to it. We also process arguments passed in the --target file, if
- * specified, just as if they were passed on the command line. */
-apr_array_header_t*
-svn_cl__args_to_target_array (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
- apr_pool_t *pool)
-{
- apr_array_header_t *targets =
- apr_array_make (pool, DEFAULT_ARRAY_SIZE, sizeof (svn_stringbuf_t *));
-
- /* Command line args take precendence. */
- for (; os->ind < os->argc; os->ind++)
- {
- svn_stringbuf_t *target = svn_stringbuf_create (os->argv[os->ind], pool);
- svn_string_t tstr;
-
- /* If this path looks like it would work as a URL in one of the
- currently available RA libraries, we add it unconditionally
- to the target array. */
- tstr.data = target->data;
- tstr.len = target->len;
- if (! svn_path_is_url (&tstr))
- {
- const char *basename = svn_path_basename (target->data, pool);
-
- /* If this target is a Subversion administrative directory,
- skip it. TODO: Perhaps this check should not call the
- target a SVN admin dir unless svn_wc_check_wc passes on
- the target, too? */
- if (! strcmp (basename, SVN_WC_ADM_DIR_NAME))
- continue;
- }
- else
- {
- svn_path_canonicalize (target);
- }
- (*((svn_stringbuf_t **) apr_array_push (targets))) = target;
- }
-
- /* Now args from --targets, if any */
- if (NULL != opt_state->targets)
- apr_array_cat(targets, opt_state->targets);
-
- /* kff todo: need to remove redundancies from targets before
- passing it to the cmd_func. */
-
- return targets;
-}
-
/* Convert a whitespace separated list of items into an apr_array_header_t */
apr_array_header_t*
svn_cl__stringlist_to_array(svn_stringbuf_t *buffer, apr_pool_t *pool)
Index: ./subversion/clients/cmdline/propget-cmd.c
===================================================================
--- ./subversion/clients/cmdline/propget-cmd.c
+++ ./subversion/clients/cmdline/propget-cmd.c Thu Mar 14 16:23:41 2002
@@ -34,22 +34,23 @@
/*** Code. ***/
svn_error_t *
-svn_cl__propget (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__propget (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
+ apr_array_header_t *args;
svn_stringbuf_t *propname;
apr_array_header_t *targets;
int i;
/* PROPNAME is first argument */
- SVN_ERR (svn_cl__parse_num_args (os, opt_state,
- "propget", 1, pool));
+ SVN_ERR (svn_cl__parse_num_args (&args, os, "propget", 1, pool));
- propname = ((svn_stringbuf_t **) (opt_state->args->elts))[0];
+ propname = ((svn_stringbuf_t **) (args->elts))[0];
/* suck up all the remaining arguments into a targets array */
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
/* Add "." if user passed 0 file arguments */
svn_cl__push_implicit_dot_target(targets, pool);
Index: ./subversion/clients/cmdline/log-cmd.c
===================================================================
--- ./subversion/clients/cmdline/log-cmd.c
+++ ./subversion/clients/cmdline/log-cmd.c Tue Mar 12 18:08:48 2002
@@ -166,15 +166,16 @@
svn_error_t *
-svn_cl__log (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__log (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
apr_array_header_t *targets;
svn_client_auth_baton_t *auth_baton;
struct log_message_receiver_baton lb;
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
/* Build an authentication object to give to libsvn_client. */
auth_baton = svn_cl__make_auth_baton (opt_state, pool);
Index: ./subversion/clients/cmdline/update-cmd.c
===================================================================
--- ./subversion/clients/cmdline/update-cmd.c
+++ ./subversion/clients/cmdline/update-cmd.c Thu Mar 14 16:25:20 2002
@@ -34,16 +34,17 @@
/*** Code. ***/
svn_error_t *
-svn_cl__update (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__update (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
apr_array_header_t *targets;
apr_array_header_t *condensed_targets;
int i;
svn_client_auth_baton_t *auth_baton;
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
/* Build an authentication baton to give to libsvn_client. */
auth_baton = svn_cl__make_auth_baton (opt_state, pool);
Index: ./subversion/clients/cmdline/cleanup-cmd.c
===================================================================
--- ./subversion/clients/cmdline/cleanup-cmd.c
+++ ./subversion/clients/cmdline/cleanup-cmd.c Tue Mar 12 18:06:36 2002
@@ -33,14 +33,15 @@
/*** Code. ***/
svn_error_t *
-svn_cl__cleanup (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__cleanup (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
apr_array_header_t *targets;
int i;
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
/* Add "." if user passed 0 arguments */
svn_cl__push_implicit_dot_target(targets, pool);
@@ -54,7 +55,7 @@
}
else
{
- svn_cl__subcommand_help ("cleanup", pool);
+ svn_cl__print_subcommand_help ("cleanup", os, pool);
return svn_error_create (SVN_ERR_CL_ARG_PARSING_ERROR, 0, 0, pool, "");
}
Index: ./subversion/clients/cmdline/add-cmd.c
===================================================================
--- ./subversion/clients/cmdline/add-cmd.c
+++ ./subversion/clients/cmdline/add-cmd.c Tue Mar 12 18:07:20 2002
@@ -36,16 +36,17 @@
/*** Code. ***/
svn_error_t *
-svn_cl__add (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__add (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
svn_error_t *err;
apr_array_header_t *targets;
int i;
svn_boolean_t recursive = opt_state->recursive;
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
if (targets->nelts)
{
@@ -76,7 +77,7 @@
}
else
{
- svn_cl__subcommand_help ("add", pool);
+ svn_cl__print_subcommand_help ("add", os, pool);
return svn_error_create (SVN_ERR_CL_ARG_PARSING_ERROR, 0, 0, pool, "");
}
Index: ./subversion/clients/cmdline/help-cmd.c
===================================================================
--- ./subversion/clients/cmdline/help-cmd.c
+++ ./subversion/clients/cmdline/.svn/empty-file Fri Mar 15 10:09:05 2002
@@ -1,103 +0,0 @@
-/*
- * help-cmd.c -- Provide help
- *
- * ====================================================================
- * 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_client.h"
-#include "svn_string.h"
-#include "svn_error.h"
-#include "svn_version.h"
-#include "cl.h"
-
-
-/*** Code. ***/
-
-static svn_error_t *
-print_version_info (apr_pool_t *pool)
-{
- void *ra_baton;
- svn_stringbuf_t *descriptions;
- static const char info[] =
- "Copyright (C) 2000-2002 CollabNet.\n"
- "Subversion is open source software, see http://subversion.tigris.org/\n";
-
- printf ("Subversion Client, version %s\n", SVN_VERSION);
- printf (" compiled %s, %s\n\n", __DATE__, __TIME__);
- printf ("%s\n", info);
-
- printf ("The following repository access (RA) modules are available:\n\n");
-
- /* Get a hash full of all available RA libraries. */
- SVN_ERR (svn_ra_init_ra_libs (&ra_baton, pool));
-
- /* Get a descriptive list of them. */
- SVN_ERR (svn_ra_print_ra_libraries (&descriptions, ra_baton, pool));
-
- printf ("%s\n", descriptions->data);
-
- return SVN_NO_ERROR;
-}
-
-
-
-/* Print either generic help, or command-specific help for each
- * command in os->args. OPT_STATE is only examined for the
- * '--version' switch. If OS is null then generic help will always be
- * printed.
- *
- * Unlike all the other command routines, ``help'' has its own
- * option processing.
- */
-svn_error_t *
-svn_cl__help (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
- apr_pool_t *pool)
-{
- apr_array_header_t *targets = NULL;
- int i;
-
- if (os)
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
-
- if (targets && targets->nelts) /* help on subcommand(s) requested */
- for (i = 0; i < targets->nelts; i++)
- {
- svn_stringbuf_t *this = (((svn_stringbuf_t **) (targets)->elts))[i];
- svn_cl__subcommand_help (this->data, pool);
- }
- else if (opt_state && opt_state->version) /* just -v or --version */
- SVN_ERR (print_version_info (pool));
- else if (os && !targets->nelts) /* `-h', `--help', or `help' */
- svn_cl__print_generic_help (pool, stdout);
- else /* unknown option or cmd */
- svn_cl__print_generic_help (pool, stderr);
-
- return SVN_NO_ERROR;
-}
-
-
-
-/*
- * local variables:
- * eval: (load-file "../../../tools/dev/svn-dev.el")
- * end:
- */
Index: ./subversion/clients/cmdline/commit-cmd.c
===================================================================
--- ./subversion/clients/cmdline/commit-cmd.c
+++ ./subversion/clients/cmdline/commit-cmd.c Thu Apr 4 16:50:40 2002
@@ -40,10 +40,11 @@
svn_error_t *
-svn_cl__commit (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__commit (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
apr_array_header_t *targets;
apr_array_header_t *condensed_targets;
svn_stringbuf_t *base_dir;
@@ -51,7 +52,7 @@
svn_client_commit_info_t *commit_info = NULL;
svn_revnum_t revnum;
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
/* Build an authentication object to give to libsvn_client. */
auth_baton = svn_cl__make_auth_baton (opt_state, pool);
Index: ./subversion/clients/cmdline/propset-cmd.c
===================================================================
--- ./subversion/clients/cmdline/propset-cmd.c
+++ ./subversion/clients/cmdline/propset-cmd.c Thu Mar 14 16:24:10 2002
@@ -34,10 +34,12 @@
/*** Code. ***/
svn_error_t *
-svn_cl__propset (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__propset (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
+ apr_array_header_t *args;
svn_stringbuf_t *propname;
const svn_string_t *propval = NULL;
apr_array_header_t *targets;
@@ -50,18 +52,18 @@
}
/* PROPNAME and PROPVAL expected as first 2 arguments if filedata
was NULL */
- SVN_ERR (svn_cl__parse_num_args (os, opt_state,
- "propset", num_args_wanted, pool));
+ SVN_ERR (svn_cl__parse_num_args (&args, os, "propset",
+ num_args_wanted, pool));
- propname = ((svn_stringbuf_t **) (opt_state->args->elts))[0];
+ propname = ((svn_stringbuf_t **) (args->elts))[0];
if (num_args_wanted == 2)
{
- svn_stringbuf_t *buf = ((svn_stringbuf_t **) (opt_state->args->elts))[1];
+ svn_stringbuf_t *buf = ((svn_stringbuf_t **) (args->elts))[1];
propval = svn_string_create_from_buf (buf, pool);
}
/* suck up all the remaining arguments into a targets array */
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
/* Add "." if user passed 0 file arguments */
svn_cl__push_implicit_dot_target(targets, pool);
Index: ./subversion/clients/cmdline/switch-cmd.c
===================================================================
--- ./subversion/clients/cmdline/switch-cmd.c
+++ ./subversion/clients/cmdline/switch-cmd.c Thu Mar 14 16:25:07 2002
@@ -35,10 +35,11 @@
svn_error_t *
-svn_cl__switch (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__switch (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
apr_array_header_t *targets;
svn_stringbuf_t *target = NULL, *switch_url = NULL;
svn_string_t str;
@@ -59,10 +60,10 @@
/* This command should discover (or derive) exactly two cmdline
arguments: a local path to update ("target"), and a new url to
switch to ("switch_url"). */
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
if (targets->nelts == 0)
{
- svn_cl__subcommand_help ("switch", pool);
+ svn_cl__print_subcommand_help ("switch", os, pool);
return svn_error_create (SVN_ERR_CL_ARG_PARSING_ERROR, 0, 0, pool, "");
}
if (targets->nelts == 1)
Index: ./subversion/clients/cmdline/delete-cmd.c
===================================================================
--- ./subversion/clients/cmdline/delete-cmd.c
+++ ./subversion/clients/cmdline/delete-cmd.c Thu Apr 4 16:13:24 2002
@@ -35,16 +35,17 @@
/*** Code. ***/
svn_error_t *
-svn_cl__delete (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__delete (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
apr_array_header_t *targets;
svn_client_auth_baton_t *auth_baton = NULL;
int i;
svn_client_commit_info_t *commit_info = NULL;
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
/* Build an authentication object to give to libsvn_client. */
auth_baton = svn_cl__make_auth_baton (opt_state, pool);
@@ -67,7 +68,7 @@
}
else
{
- svn_cl__subcommand_help ("delete", pool);
+ svn_cl__print_subcommand_help ("delete", os, pool);
return svn_error_create (SVN_ERR_CL_ARG_PARSING_ERROR, 0, 0, pool, "");
}
Index: ./subversion/clients/cmdline/import-cmd.c
===================================================================
--- ./subversion/clients/cmdline/import-cmd.c
+++ ./subversion/clients/cmdline/import-cmd.c Thu Apr 4 16:13:24 2002
@@ -34,10 +34,11 @@
/*** Code. ***/
svn_error_t *
-svn_cl__import (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__import (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
apr_array_header_t *targets;
svn_stringbuf_t *path;
svn_stringbuf_t *url;
@@ -81,7 +82,7 @@
* ### kff todo: review above behaviors.
*/
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
/* Get a repository url. */
if (targets->nelts < 1)
Index: ./subversion/clients/cmdline/proplist-cmd.c
===================================================================
--- ./subversion/clients/cmdline/proplist-cmd.c
+++ ./subversion/clients/cmdline/proplist-cmd.c Thu Mar 14 16:23:51 2002
@@ -34,14 +34,15 @@
/*** Code. ***/
svn_error_t *
-svn_cl__proplist (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__proplist (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
apr_array_header_t *targets;
int i;
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
/* Add "." if user passed 0 arguments */
svn_cl__push_implicit_dot_target(targets, pool);
Index: ./subversion/clients/cmdline/resolve-cmd.c
===================================================================
--- ./subversion/clients/cmdline/resolve-cmd.c
+++ ./subversion/clients/cmdline/resolve-cmd.c Thu Mar 14 16:35:03 2002
@@ -36,15 +36,16 @@
/*** Code. ***/
svn_error_t *
-svn_cl__resolve (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__resolve (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
svn_error_t *err;
apr_array_header_t *targets;
int i;
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
if (targets->nelts)
{
@@ -70,7 +71,7 @@
}
else
{
- svn_cl__subcommand_help ("resolve", pool);
+ svn_cl__print_subcommand_help ("resolve", os, pool);
return svn_error_create (SVN_ERR_CL_ARG_PARSING_ERROR, 0, 0, pool, "");
}
Index: ./subversion/clients/cmdline/status-cmd.c
===================================================================
--- ./subversion/clients/cmdline/status-cmd.c
+++ ./subversion/clients/cmdline/status-cmd.c Thu Mar 14 16:24:56 2002
@@ -34,17 +34,18 @@
/*** Code. ***/
svn_error_t *
-svn_cl__status (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__status (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
apr_hash_t *statushash;
apr_array_header_t *targets;
int i;
svn_client_auth_baton_t *auth_baton;
svn_revnum_t youngest = SVN_INVALID_REVNUM;
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
/* Build an authentication object to give to libsvn_client. */
auth_baton = svn_cl__make_auth_baton (opt_state, pool);
Index: ./subversion/clients/cmdline/main.c
===================================================================
--- ./subversion/clients/cmdline/main.c
+++ ./subversion/clients/cmdline/main.c Wed Mar 20 17:01:23 2002
@@ -72,41 +72,9 @@
{0, 0, 0}
};
-
-/* The maximum number of options that can be accepted by a subcommand;
- this is simply the number of unique switches that exist in the
- table above. */
-#define SVN_CL__MAX_OPTS sizeof(svn_cl__options)/sizeof(svn_cl__options[0])
-
-
/*** Command dispatch. ***/
-/* The maximum number of aliases a subcommand can have. */
-#define SVN_CL__MAX_ALIASES 3
-
-
-/* One element of the command dispatch table. */
-typedef struct svn_cl__cmd_desc_t
-{
- /* The full name of this command. */
- const char *name;
-
- /* The function this command invokes. */
- svn_cl__cmd_proc_t *cmd_func;
-
- /* A list of alias names for this command. */
- const char *aliases[SVN_CL__MAX_ALIASES];
-
- /* A brief string describing this command, for usage messages. */
- const char *help;
-
- /* A list of options accepted by this command. Each value in the
- array is a unique enum (the 2nd field in apr_getopt_option_t) */
- int valid_options[SVN_CL__MAX_OPTS];
-
-} svn_cl__cmd_desc_t;
-
/* Our array of available subcommands.
@@ -119,14 +87,14 @@
"Put files and directories under revision control, scheduling\n"
"them for addition to repository. They will be added in next commit.\n"
"usage: svn add [OPTIONS] [TARGETS]\n",
- {svn_cl__targets_opt, svn_cl__recursive_opt} },
+ {svn_cl__recursive_opt, svn_cl__recursive_opt, 0} },
- { "checkout", svn_cl__checkout, {"co"},
+ { "checkout", svn_cl__checkout, {"co", 0},
"Check out a working copy from a repository.\n"
"usage: svn checkout REPOS_URL\n",
{'d', 'r', 'D', 'q', 'n',
svn_cl__auth_username_opt, svn_cl__auth_password_opt,
- svn_cl__xml_file_opt } },
+ svn_cl__xml_file_opt, 0} },
{ "cleanup", svn_cl__cleanup, {0},
"Recursively clean up the working copy, removing locks, resuming\n"
@@ -134,16 +102,16 @@
"usage: svn cleanup [TARGETS]\n",
{0} },
- { "commit", svn_cl__commit, {"ci"},
+ { "commit", svn_cl__commit, {"ci", 0},
"Send changes from your working copy to the repository.\n"
"usage: svn commit [TARGETS]\n\n"
" Be sure to use one of -m or -F to send a log message;\n"
" the -r switch is only for use with --xml-file.\n",
{'m', 'F', 'q', svn_cl__targets_opt,
svn_cl__force_opt, svn_cl__auth_username_opt, svn_cl__auth_password_opt,
- svn_cl__xml_file_opt, 'r'} },
+ svn_cl__xml_file_opt, 'r', 0} },
- { "copy", svn_cl__copy, {"cp"},
+ { "copy", svn_cl__copy, {"cp", 0},
"Duplicate something in working copy or repos, remembering history.\n"
"usage: svn copy SRC DST.\n\n"
" SRC and DST can each be either a working copy (WC) path or URL:\n"
@@ -151,9 +119,9 @@
" WC -> URL: immediately commit a copy of WC to URL\n"
" URL -> WC: check out URL into WC, schedule for addition\n"
" URL -> URL: complete server-side copy; used to branch & tag\n",
- {'m', 'F', 'r', svn_cl__auth_username_opt, svn_cl__auth_password_opt} },
+ {'m', 'F', 'r', svn_cl__auth_username_opt, svn_cl__auth_password_opt, 0} },
- { "delete", svn_cl__delete, {"del", "remove", "rm"},
+ { "delete", svn_cl__delete, {"del", "remove", "rm", 0},
"Remove files and directories from version control.\n"
"usage: svn delete [TARGET | URL]\n\n"
" If run on a working-copy TARGET, item is scheduled for deletion\n"
@@ -161,19 +129,19 @@
" if --force is passed.) If run on URL, item is deleted from\n"
" repository via an immediate commit.\n",
{svn_cl__force_opt, 'm', 'F', svn_cl__targets_opt,
- svn_cl__auth_username_opt, svn_cl__auth_password_opt} },
+ svn_cl__auth_username_opt, svn_cl__auth_password_opt, 0} },
- { "diff", svn_cl__diff, {"di"},
+ { "diff", svn_cl__diff, {"di", 0},
"Display local changes in the working copy, or changes between the\n"
"working copy and the repository if a revision is given.\n"
"usage: svn diff [-r REV1[:REV2]] [TARGETS]\n",
{'r', 'D', 'x', 'n',
- svn_cl__auth_username_opt, svn_cl__auth_password_opt} },
-
- { "help", svn_cl__help, {"?", "h"},
+ svn_cl__auth_username_opt, svn_cl__auth_password_opt, 0} },
+
+ { "help", svn_cl__help, {"?", "h", 0},
"Display this usage message.\n"
"usage: svn help [SUBCOMMAND1 [SUBCOMMAND2] ...]\n",
- {svn_cl__version_opt} },
+ {svn_cl__version_opt, 0} },
/* We need to support "--help", "-?", and all that good stuff, of
course. But those options, since unknown, will result in the
help message being printed out anyway, so there's no need to
@@ -187,7 +155,7 @@
" directly. Otherwise, create NEW_ENTRY underneath REPOS_URL and\n"
" begin copy there. (-r is only needed if importing to --xml-file)\n",
{'F', 'm', 'q', svn_cl__auth_username_opt, svn_cl__auth_password_opt,
- svn_cl__xml_file_opt, 'r'} },
+ svn_cl__xml_file_opt, 'r', 0} },
{ "log", svn_cl__log, {0},
"Show the log messages for a set of revision(s) and/or file(s).\n"
@@ -205,62 +173,62 @@
"\n"
" svn log http://www.example.com/repo/project foo.c bar.c\n",
{'r', 'D', 'v', svn_cl__targets_opt, svn_cl__auth_username_opt,
- svn_cl__auth_password_opt} },
+ svn_cl__auth_password_opt, 0} },
{ "merge", svn_cl__merge, {0},
"Merge changes in the working copy. IMPLEMENTATION INCOMPLETE.\n"
"usage: svn merge [-r REV1[:REV2]] [TARGETS]\n",
{'r', 'D', 'x', 'n',
- svn_cl__auth_username_opt, svn_cl__auth_password_opt} },
+ svn_cl__auth_username_opt, svn_cl__auth_password_opt, 0} },
{ "mkdir", svn_cl__mkdir, {0},
"Create a new directory under revision control.\n"
"usage: mkdir [NEW_DIR | REPOS_URL].\n\n"
" Either create NEW_DIR in working copy scheduled for addition,\n"
" or create REPOS_URL via immediate commit.\n",
- {'m', 'F', svn_cl__auth_username_opt, svn_cl__auth_password_opt} },
+ {'m', 'F', svn_cl__auth_username_opt, svn_cl__auth_password_opt, 0} },
- { "move", svn_cl__move, {"mv", "rename", "ren"},
+ { "move", svn_cl__move, {"mv", "rename", "ren", 0},
"Move/rename something in working copy or repository.\n"
"usage: move SRC DST.\n\n"
" NOTE: this command is equivalent to a 'copy' and 'delete'.\n\n"
" SRC and DST can both be working copy (WC) paths or URLs:\n"
" WC -> WC: move and schedule for addition (with history)\n"
" URL -> URL: complete server-side rename.\n",
- {'m', 'F', 'r', svn_cl__auth_username_opt, svn_cl__auth_password_opt} },
+ {'m', 'F', 'r', svn_cl__auth_username_opt, svn_cl__auth_password_opt, 0} },
- { "propdel", svn_cl__propdel, {"pdel"},
+ { "propdel", svn_cl__propdel, {"pdel", 0},
"Remove property PROPNAME on files and directories.\n"
"usage: propdel PROPNAME [TARGETS]\n",
- {'q', svn_cl__recursive_opt} },
+ {'q', svn_cl__recursive_opt, 0} },
- { "propedit", svn_cl__propedit, {"pedit", "pe"},
+ { "propedit", svn_cl__propedit, {"pedit", "pe", 0},
"Edit property PROPNAME with $EDITOR on targets.\n"
"usage: propedit PROPNAME [TARGETS]\n",
{0} },
- { "propget", svn_cl__propget, {"pget", "pg"},
+ { "propget", svn_cl__propget, {"pget", "pg", 0},
"Print value of property PROPNAME on files or directories.\n"
"usage: propget PROPNAME [TARGETS]\n",
- {svn_cl__recursive_opt} },
+ {svn_cl__recursive_opt, 0} },
- { "proplist", svn_cl__proplist, {"plist", "pl"},
+ { "proplist", svn_cl__proplist, {"plist", "pl", 0},
"List all properties attached to files or directories.\n"
"usage: proplist [TARGETS]\n",
- {'v', svn_cl__recursive_opt} },
+ {'v', svn_cl__recursive_opt, 0} },
- { "propset", svn_cl__propset, {"pset", "ps"},
+ { "propset", svn_cl__propset, {"pset", "ps", 0},
"Set property PROPNAME to PROPVAL on files or directories.\n"
"usage: propset PROPNAME PROPVAL [TARGETS]\n\n"
" Use -F (instead of PROPVAL) to get the value from a file.\n",
- {'F', 'q', svn_cl__targets_opt, svn_cl__recursive_opt} },
+ {'F', 'q', svn_cl__targets_opt, svn_cl__recursive_opt, 0} },
{ "revert", svn_cl__revert, {0},
"Restore pristine working copy file (undo all local edits)\n"
"usage: revert TARGET1 [TARGET2 [TARGET3 ... ]]\n\n"
- " Note: this routine does not require network access, and \n"
+ " Note: this routine does not require network access, and\n"
" resolves any conflicted states.\n",
- {svn_cl__targets_opt, svn_cl__recursive_opt} },
+ {svn_cl__targets_opt, svn_cl__recursive_opt, 0} },
{ "resolve", svn_cl__resolve, {0},
"Remove 'conflicted' state on working copy files or directories.\n"
@@ -268,9 +236,9 @@
" Note: this routine does not semantically resolve conflict markers;\n"
" it merely removes conflict-related artifact files and allows TARGET\n"
" to be committed again.\n",
- {svn_cl__targets_opt} },
-
- { "status", svn_cl__status, {"stat", "st"},
+ {svn_cl__targets_opt, 0} },
+
+ { "status", svn_cl__status, {"stat", "st", 0},
"Print the status of working copy files and directories.\n"
"usage: svn status [TARGETS]\n\n"
" With no args, print only locally modified files (no network access).\n"
@@ -282,256 +250,28 @@
" _ * 965 970 sussman ./build.conf\n"
" M 965 687 joe ./buildcheck.sh\n",
{ 'u', 'v', 'n', 'q',
- svn_cl__auth_username_opt, svn_cl__auth_password_opt } },
+ svn_cl__auth_username_opt, svn_cl__auth_password_opt, 0} },
- { "switch", svn_cl__switch, {"sw"},
+ { "switch", svn_cl__switch, {"sw", 0},
"Update working copy to mirror a new URL\n"
"usage: switch [TARGET] REPOS_URL\n\n" /* ### should args be reversed? */
" Note: this is the way to move a working copy to a new branch.\n",
- {'r', 'n', svn_cl__force_opt} },
+ {'r', 'n', svn_cl__force_opt, 0} },
- { "update", svn_cl__update, {"up"},
+ { "update", svn_cl__update, {"up", 0},
"Bring changes from the repository into the working copy.\n"
"usage: update [TARGETS]\n\n"
" If no revision given, bring working copy up-to-date with HEAD rev.\n"
" Else synchronize working copy to revision given by -r or -D.\n",
{'r', 'D', 'n', svn_cl__auth_username_opt,
- svn_cl__auth_password_opt, svn_cl__xml_file_opt} },
+ svn_cl__auth_password_opt, svn_cl__xml_file_opt, 0} },
{ NULL, NULL, {0}, NULL, {0} }
};
-
-
-
-/* Return the entry in svn_cl__cmd_table whose name matches CMD_NAME,
- * or NULL if none. CMD_NAME may be an alias. */
-static const svn_cl__cmd_desc_t *
-svn_cl__get_canonical_command (const char *cmd_name)
-{
- int i = 0;
-
- if (cmd_name == NULL)
- return NULL;
-
- while (svn_cl__cmd_table[i].name) {
- int j;
- if (strcmp (cmd_name, svn_cl__cmd_table[i].name) == 0)
- return svn_cl__cmd_table + i;
- for (j = 0;
- (j < SVN_CL__MAX_ALIASES) && svn_cl__cmd_table[i].aliases[j];
- j++)
- if (strcmp (cmd_name, svn_cl__cmd_table[i].aliases[j]) == 0)
- return svn_cl__cmd_table + i;
-
- i++;
- }
-
- /* If we get here, there was no matching command name or alias. */
- return NULL;
-}
-
-
-
/*** 'help' processing ***/
-/* Print an option OPT nicely into a STRING allocated in POOL. If DOC
- is set, include generic documentation string of option.*/
-static void
-format_option (char **string,
- const apr_getopt_option_t *opt,
- svn_boolean_t doc,
- apr_pool_t *pool)
-{
- char *opts;
-
- if (opt == NULL)
- *string = apr_psprintf (pool, "?");
-
- if (opt->optch <= 255)
- opts = apr_psprintf (pool, "-%c [--%s]", opt->optch, opt->name);
- else
- opts = apr_psprintf (pool, "--%s", opt->name);
-
- if (opt->has_arg)
- opts = apr_pstrcat (pool, opts, " arg", NULL);
-
- if (doc)
- opts = apr_pstrcat (pool, opts, ":\t", opt->description, NULL);
-
- *string = opts;
-}
-
-
-
-const apr_getopt_option_t *
-svn_cl__get_option_from_enum (int code,
- const apr_getopt_option_t *option_table)
-{
- int i;
- const apr_getopt_option_t *opt = NULL;
-
- for (i = 0; i < SVN_CL__MAX_OPTS; i++)
- {
- if (option_table[i].optch == code)
- {
- opt = &(option_table[i]);
- break;
- }
- }
-
- return opt;
-}
-
-
-/* Return TRUE iff subcommand COMMAND has OPTION_CODE listed within
- it. Else return FALSE. */
-static svn_boolean_t
-subcommand_takes_option (const svn_cl__cmd_desc_t *command,
- int option_code)
-{
- int i;
-
- for (i = 0; i < SVN_CL__MAX_OPTS; i++)
- {
- if (command->valid_options[i] == option_code)
- return TRUE;
- }
- return FALSE;
-}
-
-
-/* Print the canonical command name for CMD, all its aliases,
- and if HELP is set, print the help string for the command too. */
-static void
-print_command_info (const svn_cl__cmd_desc_t *cmd_desc,
- svn_boolean_t help,
- apr_pool_t *pool,
- FILE *stream)
-{
- const svn_cl__cmd_desc_t *canonical_cmd
- = svn_cl__get_canonical_command (cmd_desc->name);
- svn_boolean_t first_time;
- int i;
-
- /* Print the canonical command name. */
- fputs (canonical_cmd->name, stream);
-
- /* Print the list of aliases. */
- first_time = TRUE;
- for (i = 0; i < SVN_CL__MAX_ALIASES; i++)
- {
- if (canonical_cmd->aliases[i] == NULL)
- break;
-
- if (first_time) {
- fprintf (stream, " (");
- first_time = FALSE;
- }
- else
- fprintf (stream, ", ");
-
- fprintf (stream, "%s", canonical_cmd->aliases[i]);
- }
-
- if (! first_time)
- fprintf (stream, ")");
-
- if (help)
- {
- const apr_getopt_option_t *option;
- svn_boolean_t have_options = FALSE;
-
- fprintf (stream, ": %s", canonical_cmd->help);
-
- /* Loop over all valid option codes attached to the subcommand */
- for (i = 0; i < SVN_CL__MAX_OPTS; i++)
- {
- if (canonical_cmd->valid_options[i])
- {
- if (have_options == FALSE)
- {
- fprintf (stream, "\nValid options:\n");
- have_options = TRUE;
- }
-
- /* convert each option code into an option */
- option =
- svn_cl__get_option_from_enum (canonical_cmd->valid_options[i],
- svn_cl__options);
-
- /* print the option's docstring */
- if (option)
- {
- char *optstr;
- format_option (&optstr, option, TRUE, pool);
- fprintf (stream, " %s\n", optstr);
- }
- }
- }
-
- if (have_options)
- fprintf (stream, "\n");
- }
-}
-
-
-
-/* Print a generic (non-command-specific) usage message. */
-void
-svn_cl__print_generic_help (apr_pool_t *pool, FILE *stream)
-{
- static const char usage[] =
- "usage: svn <subcommand> [options] [args]\n"
- "Type \"svn help <subcommand>\" for help on a specific subcommand.\n"
- "\n"
- "Most subcommands take file and/or directory arguments, recursing\n"
- "on the directories. If no arguments are supplied to such a\n"
- "command, it will recurse on the current directory (inclusive) by\n"
- "default.\n"
- "\n"
- "Available subcommands:\n";
-
- static const char info[] =
- "Subversion is a tool for revision control.\n"
- "For additional information, see http://subversion.tigris.org\n";
-
- int i = 0;
-
- fprintf (stream, "%s", usage);
- while (svn_cl__cmd_table[i].name)
- {
- fprintf (stream, " ");
- print_command_info (svn_cl__cmd_table + i, FALSE, pool, stream);
- fprintf (stream, "\n");
- i++;
- }
-
- fprintf (stream, "\n");
- fprintf (stream, "%s\n", info);
-
-}
-
-
-/* Helper function that will print the usage test of a subcommand
- * given the subcommand name as a char*. This function is also
- * used by subcommands that need to print a usage message */
-
-void
-svn_cl__subcommand_help (const char* subcommand,
- apr_pool_t *pool)
-{
- const svn_cl__cmd_desc_t *cmd =
- svn_cl__get_canonical_command (subcommand);
-
- if (cmd)
- print_command_info (cmd, TRUE, pool, stdout);
- else
- fprintf (stderr, "\"%s\": unknown command.\n\n", subcommand);
-}
-
-
/*** Parsing "X:Y"-style arguments. ***/
@@ -771,18 +511,13 @@
main (int argc, const char * const *argv)
{
int ret;
- apr_status_t apr_err;
svn_error_t *err;
apr_pool_t *pool;
- int opt_id;
- const char *opt_arg;
- apr_getopt_t *os;
+ svn_getopt_t *os;
svn_cl__opt_state_t opt_state;
- int received_opts[SVN_CL__MAX_OPTS];
- int i, num_opts = 0;
- const svn_cl__cmd_desc_t *subcommand = NULL;
svn_boolean_t log_under_version_control = FALSE;
svn_boolean_t log_is_pathname = FALSE;
+ int i;
/* FIXME: This is a first step towards support for localization in
`svn'. In real life, this call would be
@@ -797,11 +532,10 @@
the default locale at program startup.) */
setlocale (LC_ALL, "C");
-
apr_initialize ();
pool = svn_pool_create (NULL);
- memset (&opt_state, 0, sizeof (opt_state));
+ memset (&opt_state, 0, sizeof (opt_state));
opt_state.start_revision.kind = svn_client_revision_unspecified;
opt_state.end_revision.kind = svn_client_revision_unspecified;
@@ -814,24 +548,18 @@
}
/* Else, parse options. */
- apr_getopt_init (&os, pool, argc, argv);
- os->interleave = 1;
- while (1)
- {
- /* Parse the next option. */
- apr_err = apr_getopt_long (os, svn_cl__options, &opt_id, &opt_arg);
- if (APR_STATUS_IS_EOF (apr_err))
- break;
- else if (! APR_STATUS_IS_SUCCESS (apr_err))
- {
- svn_cl__help (NULL, NULL, pool);
- svn_pool_destroy (pool);
- return EXIT_FAILURE;
- }
+ if (APR_SUCCESS != svn_getopt_init (&os, pool, argc, argv, svn_cl__options, svn_cl__cmd_table))
+ {
+ svn_cl__help (NULL, NULL, pool);
+ svn_pool_destroy (pool);
+ return EXIT_FAILURE;
+ }
- /* Stash the option code in an array before parsing it. */
- received_opts[num_opts] = opt_id;
- num_opts++;
+ /* Handle specific command line option issues. */
+ for (i=0; i<os->num_received_opts; ++i)
+ {
+ const int opt_id = os->received_opts[i];
+ const char *opt_arg = os->received_args[i];
switch (opt_id) {
case 'm':
@@ -998,53 +726,22 @@
just typos/mistakes. Whatever the case, the subcommand to
actually run is svn_cl__help(). */
if (opt_state.help)
- subcommand = svn_cl__get_canonical_command ("help");
+ os->subcommand = svn_cl__get_canonical_command ("help", svn_cl__cmd_table);
/* If we're not running the `help' subcommand, then look for a
subcommand in the first argument. */
- if (subcommand == NULL)
+ if (os->subcommand == NULL)
{
- if (os->ind >= os->argc)
+ if (os->options->ind >= os->options->argc)
{
fprintf (stderr, "subcommand argument required\n");
svn_cl__help (NULL, NULL, pool);
svn_pool_destroy (pool);
return EXIT_FAILURE;
}
- else
- {
- const char *first_arg = os->argv[os->ind++];
- subcommand = svn_cl__get_canonical_command (first_arg);
- if (subcommand == NULL)
- {
- /* FIXME: should we print "unknown foo" ?? seems ok */
- fprintf (stderr, "unknown command: %s\n", first_arg);
- svn_cl__help (NULL, NULL, pool);
- svn_pool_destroy (pool);
- return EXIT_FAILURE;
- }
- }
}
- /* If we made it this far, then we definitely have the subcommand,
- so call it. But first check that it wasn't passed any
- inappropriate options. */
- for (i = 0; i < num_opts; i++)
- if (! subcommand_takes_option (subcommand, received_opts[i]))
- {
- char *optstr;
- const apr_getopt_option_t *badopt =
- svn_cl__get_option_from_enum (received_opts[i], svn_cl__options);
- format_option (&optstr, badopt, FALSE, pool);
- fprintf (stderr,
- "\nError: subcommand '%s' doesn't accept option '%s'\n\n",
- subcommand->name, optstr);
- svn_cl__subcommand_help (subcommand->name, pool);
- svn_pool_destroy(pool);
- return EXIT_FAILURE;
- }
-
- if (subcommand->cmd_func == svn_cl__commit)
+ if (os->subcommand->cmd_func == svn_cl__commit)
{
/* If the log message file is under revision control, that's
probably not what the user intended. */
@@ -1076,7 +773,7 @@
}
}
- err = (*subcommand->cmd_func) (os, &opt_state, pool);
+ err = (*os->subcommand->cmd_func) (os, &opt_state, pool);
if (err)
{
if (err->apr_err != SVN_ERR_CL_ARG_PARSING_ERROR)
Index: ./subversion/clients/cmdline/propedit-cmd.c
===================================================================
--- ./subversion/clients/cmdline/propedit-cmd.c
+++ ./subversion/clients/cmdline/propedit-cmd.c Thu Mar 14 16:22:22 2002
@@ -34,22 +34,24 @@
/*** Code. ***/
svn_error_t *
-svn_cl__propedit (apr_getopt_t *os,
- svn_cl__opt_state_t *opt_state,
+svn_cl__propedit (svn_getopt_t *os,
+ void *opt_state_,
apr_pool_t *pool)
{
+ svn_cl__opt_state_t *opt_state = (svn_cl__opt_state_t *)opt_state_;
+ apr_array_header_t *args;
svn_stringbuf_t *propname;
apr_array_header_t *targets;
int i;
/* Validate the input. */
- SVN_ERR (svn_cl__parse_num_args (os, opt_state, "propedit", 1, pool));
+ SVN_ERR (svn_cl__parse_num_args (&args, os, "propedit", 1, pool));
/* Get the property's name. */
- propname = ((svn_stringbuf_t **) (opt_state->args->elts))[0];
+ propname = ((svn_stringbuf_t **) (args->elts))[0];
/* Suck up all the remaining arguments into a targets array */
- targets = svn_cl__args_to_target_array (os, opt_state, pool);
+ targets = svn_cl__args_to_target_array (os, opt_state->targets, pool);
/* Add "." if user passed 0 file arguments */
svn_cl__push_implicit_dot_target (targets, pool);
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Thu Jul 25 21:32:45 2002