Hi all.
In looking at the way the command line client parses
arguments passed in from the user, I found a block of
code in main.c that seems rather error prone:
if ((targets->nelts == 0)
&& ( (subcommand->cmd_code == svn_cl__commit_command)
|| (subcommand->cmd_code == svn_cl__proplist_command)
|| (subcommand->cmd_code == svn_cl__propget_command)
|| (subcommand->cmd_code == svn_cl__status_command)
|| (subcommand->cmd_code == svn_cl__update_command)))
{
(*((svn_string_t **) apr_array_push (targets)))
= svn_string_create (".", pool);
}
It is adding a "." argument if the command type if the
command type is one of the commands that takes an
implicit dot. This seems to be a bad idea since the
main() function needs to know about every possible
command and it is easy to miss one. For example,
the diff command is not included in this list.
It really should be, `svn diff` should really
work the same as `cvs diff`. It seems like a
much better solution would be to do this
implicit dot check inside the functions that
actually need to do it. Here is my patch to
implement this change. Note that I did not
reformat spaces and added a FIXME not for the
for loops that were in an if block before. This
is so that the patch is more clear, I can
send another patch to fix the spacing if/when
this one gets added.
Mo DeJong
Red Hat Inc
2001-03-05 Mo DeJong <mdejong@redhat.com>
* subversion/client/cl.h (push_implicit_dot_target):
Add header for new method defined in main.c.
* subversion/client/commit-cmd.c (svn_cl__commit):
Call push_implicit_dot_target.
* subversion/client/diff-cmd.c (svn_cl__diff):
Call push_implicit_dot_target.
* subversion/client/main.c: #include <assert.h>,
define push_implicit_dot_target. Remove error
prone block of code to push implicit dot target
by comparing to known commands.
* subversion/client/propget-cmd.c (svn_cl__propget):
* subversion/client/proplist-cmd.c (svn_cl__proplist):
* subversion/client/status-cmd.c (svn_cl__status):
* subversion/client/update-cmd.c (svn_cl__update):
Call push_implicit_dot_target.
Index: subversion/client/cl.h
===================================================================
RCS file: /cvs/subversion/subversion/client/cl.h,v
retrieving revision 1.34
diff -u -r1.34 cl.h
--- subversion/client/cl.h 2001/03/04 18:36:00 1.34
+++ subversion/client/cl.h 2001/03/06 05:55:53
@@ -172,6 +172,8 @@
const svn_cl__cmd_desc_t *
svn_cl__get_canonical_command (const char *cmd);
+void push_implicit_dot_target(apr_array_header_t *targets, apr_pool_t *pool);
+
#endif /* SVN_CL_H */
Index: subversion/client/commit-cmd.c
===================================================================
RCS file: /cvs/subversion/subversion/client/commit-cmd.c,v
retrieving revision 1.11
diff -u -r1.11 commit-cmd.c
--- subversion/client/commit-cmd.c 2001/02/06 00:45:51 1.11
+++ subversion/client/commit-cmd.c 2001/03/06 05:55:53
@@ -37,7 +37,11 @@
svn_error_t *err;
int i;
- if (targets->nelts)
+ /* Add "." if user passed 0 arguments */
+ push_implicit_dot_target(targets, pool);
+
+ /* FIXME: reformat block to remove extra spaces */
+
for (i = 0; i < targets->nelts; i++)
{
svn_string_t *target = ((svn_string_t **) (targets->elts))[i];
@@ -61,14 +65,6 @@
if (err)
return err;
}
- else
- {
- fprintf (stderr, "svn commit: arguments required\n");
- err = svn_cl__help (opt_state, targets, pool);
- if (err)
- return err;
- }
-
return SVN_NO_ERROR;
}
Index: subversion/client/diff-cmd.c
===================================================================
RCS file: /cvs/subversion/subversion/client/diff-cmd.c,v
retrieving revision 1.1
diff -u -r1.1 diff-cmd.c
--- subversion/client/diff-cmd.c 2001/01/26 14:21:06 1.1
+++ subversion/client/diff-cmd.c 2001/03/06 05:55:53
@@ -37,7 +37,11 @@
svn_error_t *err;
int i;
- if (targets->nelts)
+ /* Add "." if user passed 0 arguments */
+ push_implicit_dot_target(targets, pool);
+
+ /* FIXME: reformat block to remove extra spaces */
+
for (i = 0; i < targets->nelts; i++)
{
svn_string_t *target = ((svn_string_t **) (targets->elts))[i];
@@ -45,14 +49,6 @@
err = svn_cl__print_file_diff (target, pool);
if (err) return err;
}
- else
- {
- fprintf (stderr, "svn diff: arguments required\n");
- err = svn_cl__help (opt_state, targets, pool);
- if (err)
- return err;
- }
-
return SVN_NO_ERROR;
}
Index: subversion/client/main.c
===================================================================
RCS file: /cvs/subversion/subversion/client/main.c,v
retrieving revision 1.62
diff -u -r1.62 main.c
--- subversion/client/main.c 2001/03/04 18:23:38 1.62
+++ subversion/client/main.c 2001/03/06 05:55:54
@@ -19,6 +19,7 @@
/*** Includes. ***/
#include <string.h>
+#include <assert.h>
#include <apr_strings.h>
#include <apr_getopt.h>
@@ -121,6 +122,18 @@
};
+/* 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 */
+void push_implicit_dot_target(apr_array_header_t *targets, apr_pool_t *pool)
+{
+ if (targets->nelts == 0) {
+ (*((svn_string_t **) apr_array_push (targets)))
+ = svn_string_create (".", pool);
+ }
+ assert(targets->nelts);
+}
+
/* Return the entry in svn_cl__cmd_table whose name matches CMD_NAME,
* or null if none. CMD_NAME may be an alias, in which case the alias
* entry will be returned (so caller may need to canonicalize result). */
@@ -396,25 +409,10 @@
const char *this_arg = os->argv[os->ind];
(*((svn_string_t **) apr_array_push (targets)))
= svn_string_create (this_arg, pool);
- }
-
- /* Certain commands have an implied `.' as argument, if nothing else
- is specified. */
- if ((targets->nelts == 0)
- && ( (subcommand->cmd_code == svn_cl__commit_command)
- || (subcommand->cmd_code == svn_cl__proplist_command)
- || (subcommand->cmd_code == svn_cl__propget_command)
- || (subcommand->cmd_code == svn_cl__status_command)
- || (subcommand->cmd_code == svn_cl__update_command)))
- {
- (*((svn_string_t **) apr_array_push (targets)))
- = svn_string_create (".", pool);
- }
- else
- {
- /* kff todo: need to remove redundancies from targets before
- passing it to the cmd_func. */
}
+
+ /* kff todo: need to remove redundancies from targets before
+ passing it to the cmd_func. */
/* Run the subcommand. */
err = (*subcommand->cmd_func) (&opt_state, targets, pool);
Index: subversion/client/propget-cmd.c
===================================================================
RCS file: /cvs/subversion/subversion/client/propget-cmd.c,v
retrieving revision 1.8
diff -u -r1.8 propget-cmd.c
--- subversion/client/propget-cmd.c 2001/03/04 18:07:45 1.8
+++ subversion/client/propget-cmd.c 2001/03/06 05:55:54
@@ -39,7 +39,11 @@
svn_error_t *err;
int i;
- if (targets->nelts)
+ /* Add "." if user passed 0 file arguments */
+ push_implicit_dot_target(targets, pool);
+
+ /* FIXME: reformat block to remove extra spaces */
+
for (i = 0; i < targets->nelts; i++)
{
svn_string_t *value;
@@ -54,13 +58,6 @@
value);
svn_cl__print_prop_hash (prop_hash, pool);
}
- else
- {
- fprintf (stderr, "svn propget: arguments required\n");
- err = svn_cl__help (opt_state, targets, pool);
- if (err)
- return err;
- }
return SVN_NO_ERROR;
}
Index: subversion/client/proplist-cmd.c
===================================================================
RCS file: /cvs/subversion/subversion/client/proplist-cmd.c,v
retrieving revision 1.9
diff -u -r1.9 proplist-cmd.c
--- subversion/client/proplist-cmd.c 2001/02/08 12:32:41 1.9
+++ subversion/client/proplist-cmd.c 2001/03/06 05:55:54
@@ -37,7 +37,11 @@
svn_error_t *err;
int i;
- if (targets->nelts)
+ /* Add "." if user passed 0 arguments */
+ push_implicit_dot_target(targets, pool);
+
+ /* FIXME: reformat block to remove extra spaces */
+
for (i = 0; i < targets->nelts; i++)
{
svn_string_t *target = ((svn_string_t **) (targets->elts))[i];
@@ -49,13 +53,6 @@
svn_cl__print_prop_hash (prop_hash, pool);
}
- else
- {
- fprintf (stderr, "svn proplist: arguments required\n");
- err = svn_cl__help (opt_state, targets, pool);
- if (err)
- return err;
- }
return SVN_NO_ERROR;
}
Index: subversion/client/status-cmd.c
===================================================================
RCS file: /cvs/subversion/subversion/client/status-cmd.c,v
retrieving revision 1.9
diff -u -r1.9 status-cmd.c
--- subversion/client/status-cmd.c 2001/01/08 18:55:39 1.9
+++ subversion/client/status-cmd.c 2001/03/06 05:55:54
@@ -38,7 +38,11 @@
apr_hash_t *statushash;
int i;
- if (targets->nelts)
+ /* Add "." if user passed 0 arguments */
+ push_implicit_dot_target(targets, pool);
+
+ /* FIXME: reformat block to remove extra spaces */
+
for (i = 0; i < targets->nelts; i++)
{
svn_string_t *target = ((svn_string_t **) (targets->elts))[i];
@@ -54,14 +58,6 @@
svn_cl__print_status_list (statushash, pool);
}
- else
- {
- fprintf (stderr, "svn status: arguments required\n");
- err = svn_cl__help (opt_state, targets, pool);
- if (err)
- return err;
- }
-
return SVN_NO_ERROR;
}
Index: subversion/client/update-cmd.c
===================================================================
RCS file: /cvs/subversion/subversion/client/update-cmd.c,v
retrieving revision 1.11
diff -u -r1.11 update-cmd.c
--- subversion/client/update-cmd.c 2001/02/06 00:45:51 1.11
+++ subversion/client/update-cmd.c 2001/03/06 05:55:54
@@ -37,7 +37,11 @@
svn_error_t *err;
int i;
- if (targets->nelts)
+ /* Add "." if user passed 0 arguments */
+ push_implicit_dot_target(targets, pool);
+
+ /* FIXME: reformat block to remove extra spaces */
+
for (i = 0; i < targets->nelts; i++)
{
svn_string_t *target = ((svn_string_t **) (targets->elts))[i];
@@ -59,13 +63,6 @@
if (err)
return err;
}
- else
- {
- fprintf (stderr, "svn update: arguments required\n");
- err = svn_cl__help (opt_state, targets, pool);
- if (err)
- return err;
- }
return SVN_NO_ERROR;
}
Received on Sat Oct 21 14:36:25 2006