You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by Karl Fogel <kf...@galois.collab.net> on 2000/11/14 21:45:43 UTC
Re: The next step in a table driven client
Actually (I apologize if I'm just being dense, here) I'm not sure I
understand the proposal completely..
I like the idea that only main() has to parse the options, and then
passes along the information postparsed to the subcommand, especially
given that so many options have a common meaning across subcommands.
However, I don't understand the mechanism by which this is happening;
specifically, the mechanism by which main() passes the information
along. It sounds like it's at least partially genericized, but what
about option/arg combinations that are specific to a given
subcommand. How are those passed? Are we going to make the
subcommand procedure type variadic?
As an experiment, could you try writing the log entry in advance and
posting it? Obviously, it doesn't have to be 100% the same as what
you actually end up doing, but knowing how the data structures are
going to change would probably clear up these things, for me and
(maybe) for others.
-K
Bruce Korb <bk...@sco.COM> writes:
> In preparation for ultimately doing some sort of
> table thingey for options, I want to lay some ground work
> now. To do this, I want to make a struct type that
> contains all the data currently used in the client
> options, plus the command enumeration type. Each
> command table entry would have a pointer to a struct
> of this type with just the command enumeration filled
> in. The current option processing code would be called
> from main() instead of the command procedures. The command
> procedures would receive only command arguments (the
> options stripped off). With this done, changing the
> underlying option processing should no longer perterb
> much of any other code (especially the command implementation
> procedures.)
>
> I'll stick a slight rewording of this email
> into the CVS log when I do this, ok? :-)
Re: The next step in a table driven client
Posted by Karl Fogel <kf...@galois.collab.net>.
Regrets -- Bruce, et al, I am out of the office tomorrow. Go ahead
and try stuff in the client/ dir, then; if the changes are going to be
big, just "cvs tag" first, so we have a marker before them.
I'll be coding Thursday, in a big way. :-)
Good luck,
-K
Bruce Korb <bk...@cruzio.com> writes:
> My proposal is to *not* do anything significant. :-)
> Instead, it is merely to isolate it so that experimentation
> becomes easy. Then, I will experiment a little bit and
> come up with a proposal. Whatever proposal would be something
> that specified the acceptable/required options to an
> option processing engine that would be driven by that
> something, rather than command name. The resulting state
> would get handed back to the implementation procedures in
> any of a myriad of ways.
>
> For the time being, this is far and away the most trivial
> to implement and use for an experimental framework:
>
> typedef struct svn_cl__opt_state_t {
> svn_string_t *xml_file;
> svn_string_t *target;
> svn_string_t *ancestor_path;
> svn_boolean_t force;
> svn_cl__command cmd;
> const char *use_text;
> } svn_cl__opt_state_t;
>
> a pointer to this struct gets added to the command descriptor.
> The option processing routine takes this ptr as an argument, instead
> of the addresses of each of the fields. It is trivial and gets me
> closer to where I want to go, even if the destination still has haze.
>
> > 3. Remaining arguments are files and dirs. Have a single function
> > that removes redundancies from this set (if you're recursing
> > into bar anyway, then mentioning bar/foo.c is pointless), and
> > passes it along to the command as the keys in a hash table.
>
> cute idea. Certainly not today, tho.
>
> > Greg Stein <gs...@lyra.org> writes:
> > > I'd suggest passing the options information to the command in
> > > a hash table. The command can simply do something like
> > > apr_hash_get(hash, "v") to get the information.
>
> > > Throw in a bit of default value handling, long/short option
> > > handling, and you're set.
>
> Yeah, easy. It's only software. But too ambitious for tonight.
>
> > > The second part would be determining what is possible for a given command
> > > and providing errors/warnings for options that don't match up properly.
>
> Right now, I'll do that just with the command code enumeration.
> The real implementation will do something better.
>
> > > On Tue, Nov 14, 2000 at 03:45:43PM -0600, Karl Fogel wrote:
> > > > Actually (I apologize if I'm just being dense, here) I'm not sure I
> > > > understand the proposal completely..
>
> Probably because it is a baby step proposal and you are looking
> for a stride instead? :)
>
> > > > I like the idea that only main() has to parse the options, and then
> > > > passes along the information postparsed to the subcommand, especially
> > > > given that so many options have a common meaning across subcommands.
> > > >
> > > > However, I don't understand the mechanism by which this is happening;
> > > > specifically, the mechanism by which main() passes the information
> > > > along. It sounds like it's at least partially genericized,
>
> Not a bit of that. The code will be essentially unchanged, except
> the main() routine will have access to the command code enumeration
> and will pass it to the arg processing routine, instead of the
> separate command procedures. This is a _very_ tiny step.
>
> > > > How are those [data] passed? Are we going to make the
> > > > subcommand procedure type variadic?
>
> One big struct.
>
> > > > As an experiment, could you try writing the log entry in advance and
> > > > posting it?
>
> Humm. This was *supposed* to be a first approximation:
>
> > > > > In preparation for ultimately doing some sort of
> > > > > table thingey for options, I want to lay some ground work
> > > > > now. To do this, I want to make a struct type that
> > > > > contains all the data currently used in the client
> > > > > options, plus the command enumeration type. Each
> > > > > command table entry would have a pointer to a struct
> > > > > of this type with just the command enumeration filled
> > > > > in. The current option processing code would be called
> > > > > from main() instead of the command procedures. The command
> > > > > procedures would receive only command arguments (the
> > > > > options stripped off). With this done, changing the
> > > > > underlying option processing should no longer perterb
> > > > > much of any other code (especially the command implementation
> > > > > procedures.)
>
> static svn_cl__cmd_desc_t cmd_table[] = {
> /* add */
> { "add", NULL, svn_cl__add, &add_cmd_opt_state },
> { "ad", "add", svn_cl__add, &add_cmd_opt_state },
> { "new", "add", svn_cl__add, &add_cmd_opt_state },
> .....[etc.]
Re: The next step in a table driven client
Posted by Karl Fogel <kf...@galois.collab.net>.
Well, Ben offered me a ride home, so now I'm not rushing to catch a
train and can respond with content this time. :-)
> My proposal is to *not* do anything significant. :-)
> Instead, it is merely to isolate it so that experimentation
> becomes easy. Then, I will experiment a little bit and
> come up with a proposal. Whatever proposal would be something
> that specified the acceptable/required options to an
> option processing engine that would be driven by that
> something, rather than command name. The resulting state
> would get handed back to the implementation procedures in
> any of a myriad of ways.
Sounds like a good plan.
> For the time being, this is far and away the most trivial
> to implement and use for an experimental framework:
>
> typedef struct svn_cl__opt_state_t {
> svn_string_t *xml_file;
> svn_string_t *target;
> svn_string_t *ancestor_path;
> svn_boolean_t force;
> svn_cl__command cmd;
> const char *use_text;
> } svn_cl__opt_state_t;
Sure -- we can add stuff as necessary.
> a pointer to this struct gets added to the command descriptor.
> The option processing routine takes this ptr as an argument, instead
> of the addresses of each of the fields. It is trivial and gets me
> closer to where I want to go, even if the destination still has haze.
See what you mean, agree.
> > 3. Remaining arguments are files and dirs. Have a single function
> > that removes redundancies from this set (if you're recursing
> > into bar anyway, then mentioning bar/foo.c is pointless), and
> > passes it along to the command as the keys in a hash table.
>
> cute idea. Certainly not today, tho.
Yah. I'll write it within the next week, I'm pretty sure -- it's not
hard, it's something every command needs, and it'll make testing
easier. Don't worry about it for now.
> Probably because it is a baby step proposal and you are looking
> for a stride instead? :)
I think that's what was going on, yes. The step looks good, I doubt
we'd have to take any of it back. Go for it...
> Not a bit of that. The code will be essentially unchanged, except
> the main() routine will have access to the command code enumeration
> and will pass it to the arg processing routine, instead of the
> separate command procedures. This is a _very_ tiny step.
:-)
I understand the proposal totally, now, sorry if I was being dense.
+1. Seems winning to me,
-Karl
Re: The next step in a table driven client
Posted by Bruce Korb <bk...@cruzio.com>.
Karl Fogel wrote:
>
> Greg Stein <gs...@lyra.org> writes:
> > > a pointer to this struct gets added to the command descriptor.
> > > The option processing routine takes this ptr as an argument, instead
> > > of the addresses of each of the fields. It is trivial and gets me
> > > closer to where I want to go, even if the destination still has haze.
> >
> > -0 on this approach.
> >
> > The hash table has longer term growth and seems just as simple.
>
> I think I'm agnostic on the question of hash vs struct...
>
> One nice thing about the struct is that it spells out which things are
> common to all commands -- those are the fields in the struct.
>
> On the other hand, you have to keep adding fields. And some things
> are common to only a subset of commands, so what's the threshold for
> inclusion in the struct?...
>
> Hmm. Yes, I see what you mean, Greg. I guess I've swung around to
> the hash table p.o.v., then (separate from the filename/dirname hash,
> of course).
>
> Bruce, any objections? Is there some reason to prefer the struct
> approach, that we're missing?
1. I would have to learn how to use it
2. It won't live very long anyway.
3. I have to finish before you chew up the code on Thursday :-)
4. It has to be trivial to switch the data passing mechanism,
so it doesn't really matter
Re: The next step in a table driven client
Posted by Bruce Korb <bk...@cruzio.com>.
Greg Stein wrote:
> That said, I am -0 (not a full -1) on the use of hash vs. struct. I'd much
> rather see a hash table, but I'm not coding it (creation or consumption), so
> I'm not going to be (too much of) a pest here :-)
OK I'll pound out a hack tomorrow after work.
I'm done for today. Cheers,
Bruce
Re: The next step in a table driven client
Posted by Greg Stein <gs...@lyra.org>.
On Tue, Nov 14, 2000 at 05:53:08PM -0600, Karl Fogel wrote:
> Greg Stein <gs...@lyra.org> writes:
> > > a pointer to this struct gets added to the command descriptor.
> > > The option processing routine takes this ptr as an argument, instead
> > > of the addresses of each of the fields. It is trivial and gets me
> > > closer to where I want to go, even if the destination still has haze.
> >
> > -0 on this approach.
> >
> > The hash table has longer term growth and seems just as simple.
>
> I think I'm agnostic on the question of hash vs struct...
>
> One nice thing about the struct is that it spells out which things are
> common to all commands -- those are the fields in the struct.
Solvable with svn_client_get_option(longname, cmd_data). When that function
is seen in the code, it is just as obvious as cmd_data->longname.
> On the other hand, you have to keep adding fields. And some things
> are common to only a subset of commands, so what's the threshold for
> inclusion in the struct?...
Right.
> Hmm. Yes, I see what you mean, Greg. I guess I've swung around to
> the hash table p.o.v., then (separate from the filename/dirname hash,
> of course).
The most general mechanism is:
*) a hash table for options
*) an array for the non-option stuff (URLs, files, dirs, tag names, etc)
A struct can make sense to wrap these two pieces up along with "purely
global" items such as "verbose". In other words:
struct cmd_stuff_t {
apr_hash_t *options;
apr_array_header_t *args;
svn_boolean_t verbose;
}
Effectively, the parsing stuff just preprocesses a few flags such as
'verbose' out of the hash table.
That said, I am -0 (not a full -1) on the use of hash vs. struct. I'd much
rather see a hash table, but I'm not coding it (creation or consumption), so
I'm not going to be (too much of) a pest here :-)
Cheers,
-g
--
Greg Stein, http://www.lyra.org/
Re: The next step in a table driven client
Posted by Karl Fogel <kf...@galois.collab.net>.
Greg Stein <gs...@lyra.org> writes:
> > a pointer to this struct gets added to the command descriptor.
> > The option processing routine takes this ptr as an argument, instead
> > of the addresses of each of the fields. It is trivial and gets me
> > closer to where I want to go, even if the destination still has haze.
>
> -0 on this approach.
>
> The hash table has longer term growth and seems just as simple.
I think I'm agnostic on the question of hash vs struct...
One nice thing about the struct is that it spells out which things are
common to all commands -- those are the fields in the struct.
On the other hand, you have to keep adding fields. And some things
are common to only a subset of commands, so what's the threshold for
inclusion in the struct?...
Hmm. Yes, I see what you mean, Greg. I guess I've swung around to
the hash table p.o.v., then (separate from the filename/dirname hash,
of course).
Bruce, any objections? Is there some reason to prefer the struct
approach, that we're missing?
-K
Re: The next step in a table driven client
Posted by Greg Stein <gs...@lyra.org>.
I'd much rather see a hash table than One Big Mother Structure that had the
union of all possible flags and options. A hash table seems quite simple.
On Tue, Nov 14, 2000 at 06:55:59PM -0800, Bruce Korb wrote:
>
> My proposal is to *not* do anything significant. :-)
> Instead, it is merely to isolate it so that experimentation
> becomes easy.
Right.
> Then, I will experiment a little bit and
> come up with a proposal. Whatever proposal would be something
> that specified the acceptable/required options to an
> option processing engine that would be driven by that
> something, rather than command name.
Makes complete sense. But my emphasis in this note is to suggest using a
hash table, which is orthogonal to command parsing/driving.
> The resulting state
> would get handed back to the implementation procedures in
> any of a myriad of ways.
>
> For the time being, this is far and away the most trivial
> to implement and use for an experimental framework:
>
> typedef struct svn_cl__opt_state_t {
> svn_string_t *xml_file;
> svn_string_t *target;
> svn_string_t *ancestor_path;
> svn_boolean_t force;
> svn_cl__command cmd;
> const char *use_text;
> } svn_cl__opt_state_t;
>
> a pointer to this struct gets added to the command descriptor.
> The option processing routine takes this ptr as an argument, instead
> of the addresses of each of the fields. It is trivial and gets me
> closer to where I want to go, even if the destination still has haze.
-0 on this approach.
The hash table has longer term growth and seems just as simple.
>...
> > Greg Stein <gs...@lyra.org> writes:
> > > I'd suggest passing the options information to the command in
> > > a hash table. The command can simply do something like
> > > apr_hash_get(hash, "v") to get the information.
>
> > > Throw in a bit of default value handling, long/short option
> > > handling, and you're set.
>
> Yeah, easy. It's only software. But too ambitious for tonight.
Yes, those are certainly second round additions. The initial question seemed
to focus on how to pass option/command data between the parser and the
command functions.
> > > The second part would be determining what is possible for a given command
> > > and providing errors/warnings for options that don't match up properly.
>
> Right now, I'll do that just with the command code enumeration.
> The real implementation will do something better.
Right-o.
Cheers,
-g
--
Greg Stein, http://www.lyra.org/
Re: The next step in a table driven client
Posted by Bruce Korb <bk...@cruzio.com>.
My proposal is to *not* do anything significant. :-)
Instead, it is merely to isolate it so that experimentation
becomes easy. Then, I will experiment a little bit and
come up with a proposal. Whatever proposal would be something
that specified the acceptable/required options to an
option processing engine that would be driven by that
something, rather than command name. The resulting state
would get handed back to the implementation procedures in
any of a myriad of ways.
For the time being, this is far and away the most trivial
to implement and use for an experimental framework:
typedef struct svn_cl__opt_state_t {
svn_string_t *xml_file;
svn_string_t *target;
svn_string_t *ancestor_path;
svn_boolean_t force;
svn_cl__command cmd;
const char *use_text;
} svn_cl__opt_state_t;
a pointer to this struct gets added to the command descriptor.
The option processing routine takes this ptr as an argument, instead
of the addresses of each of the fields. It is trivial and gets me
closer to where I want to go, even if the destination still has haze.
> 3. Remaining arguments are files and dirs. Have a single function
> that removes redundancies from this set (if you're recursing
> into bar anyway, then mentioning bar/foo.c is pointless), and
> passes it along to the command as the keys in a hash table.
cute idea. Certainly not today, tho.
> Greg Stein <gs...@lyra.org> writes:
> > I'd suggest passing the options information to the command in
> > a hash table. The command can simply do something like
> > apr_hash_get(hash, "v") to get the information.
> > Throw in a bit of default value handling, long/short option
> > handling, and you're set.
Yeah, easy. It's only software. But too ambitious for tonight.
> > The second part would be determining what is possible for a given command
> > and providing errors/warnings for options that don't match up properly.
Right now, I'll do that just with the command code enumeration.
The real implementation will do something better.
> > On Tue, Nov 14, 2000 at 03:45:43PM -0600, Karl Fogel wrote:
> > > Actually (I apologize if I'm just being dense, here) I'm not sure I
> > > understand the proposal completely..
Probably because it is a baby step proposal and you are looking
for a stride instead? :)
> > > I like the idea that only main() has to parse the options, and then
> > > passes along the information postparsed to the subcommand, especially
> > > given that so many options have a common meaning across subcommands.
> > >
> > > However, I don't understand the mechanism by which this is happening;
> > > specifically, the mechanism by which main() passes the information
> > > along. It sounds like it's at least partially genericized,
Not a bit of that. The code will be essentially unchanged, except
the main() routine will have access to the command code enumeration
and will pass it to the arg processing routine, instead of the
separate command procedures. This is a _very_ tiny step.
> > > How are those [data] passed? Are we going to make the
> > > subcommand procedure type variadic?
One big struct.
> > > As an experiment, could you try writing the log entry in advance and
> > > posting it?
Humm. This was *supposed* to be a first approximation:
> > > > In preparation for ultimately doing some sort of
> > > > table thingey for options, I want to lay some ground work
> > > > now. To do this, I want to make a struct type that
> > > > contains all the data currently used in the client
> > > > options, plus the command enumeration type. Each
> > > > command table entry would have a pointer to a struct
> > > > of this type with just the command enumeration filled
> > > > in. The current option processing code would be called
> > > > from main() instead of the command procedures. The command
> > > > procedures would receive only command arguments (the
> > > > options stripped off). With this done, changing the
> > > > underlying option processing should no longer perterb
> > > > much of any other code (especially the command implementation
> > > > procedures.)
static svn_cl__cmd_desc_t cmd_table[] = {
/* add */
{ "add", NULL, svn_cl__add, &add_cmd_opt_state },
{ "ad", "add", svn_cl__add, &add_cmd_opt_state },
{ "new", "add", svn_cl__add, &add_cmd_opt_state },
.....[etc.]
Re: The next step in a table driven client
Posted by Karl Fogel <kf...@galois.collab.net>.
+1 on that.
There's the secondary issue of how to pass filename/dirname arguments
to the commands. All the commands behave like CVS by default (recurse
on dirs, implied ".", and all that). So I was thinking about a series
of steps like this:
1. Parse out all the options and their arguments, put them
somewhere. Anything remaining on the command line is a direct
(non-option) argument to the command.
2. Parse out non-file/non-dir arguments (such as the property name
in a propset command, for example), put them somewhere.
3. Remaining arguments are files and dirs. Have a single function
that removes redundancies from this set (if you're recursing
into bar anyway, then mentioning bar/foo.c is pointless), and
passes it along to the command as the keys in a hash table.
The cool thing is that if the command needs to return information
about individual entities, it can do so via the same hash table,
either sticking values on the existing keys, and/or creating new
keys. The "status" command does this, for example.
-K
Greg Stein <gs...@lyra.org> writes:
> I'd suggest passing the options information to the command in a hash table.
> The command can simply do something like apr_hash_get(hash, "v") to get the
> information.
>
> Throw in a bit of default value handling, long/short option handling, and
> you're set. The apr_hash_t would create an excellent division between option
> processing and option consumption.
>
> The second part would be determining what is possible for a given command
> and providing errors/warnings for options that don't match up properly.
>
> Cheers,
> -g
>
> On Tue, Nov 14, 2000 at 03:45:43PM -0600, Karl Fogel wrote:
> > Actually (I apologize if I'm just being dense, here) I'm not sure I
> > understand the proposal completely..
> >
> > I like the idea that only main() has to parse the options, and then
> > passes along the information postparsed to the subcommand, especially
> > given that so many options have a common meaning across subcommands.
> >
> > However, I don't understand the mechanism by which this is happening;
> > specifically, the mechanism by which main() passes the information
> > along. It sounds like it's at least partially genericized, but what
> > about option/arg combinations that are specific to a given
> > subcommand. How are those passed? Are we going to make the
> > subcommand procedure type variadic?
> >
> > As an experiment, could you try writing the log entry in advance and
> > posting it? Obviously, it doesn't have to be 100% the same as what
> > you actually end up doing, but knowing how the data structures are
> > going to change would probably clear up these things, for me and
> > (maybe) for others.
> >
> > -K
> >
> > Bruce Korb <bk...@sco.COM> writes:
> > > In preparation for ultimately doing some sort of
> > > table thingey for options, I want to lay some ground work
> > > now. To do this, I want to make a struct type that
> > > contains all the data currently used in the client
> > > options, plus the command enumeration type. Each
> > > command table entry would have a pointer to a struct
> > > of this type with just the command enumeration filled
> > > in. The current option processing code would be called
> > > from main() instead of the command procedures. The command
> > > procedures would receive only command arguments (the
> > > options stripped off). With this done, changing the
> > > underlying option processing should no longer perterb
> > > much of any other code (especially the command implementation
> > > procedures.)
> > >
> > > I'll stick a slight rewording of this email
> > > into the CVS log when I do this, ok? :-)
>
> --
> Greg Stein, http://www.lyra.org/
Re: The next step in a table driven client
Posted by Greg Stein <gs...@lyra.org>.
I'd suggest passing the options information to the command in a hash table.
The command can simply do something like apr_hash_get(hash, "v") to get the
information.
Throw in a bit of default value handling, long/short option handling, and
you're set. The apr_hash_t would create an excellent division between option
processing and option consumption.
The second part would be determining what is possible for a given command
and providing errors/warnings for options that don't match up properly.
Cheers,
-g
On Tue, Nov 14, 2000 at 03:45:43PM -0600, Karl Fogel wrote:
> Actually (I apologize if I'm just being dense, here) I'm not sure I
> understand the proposal completely..
>
> I like the idea that only main() has to parse the options, and then
> passes along the information postparsed to the subcommand, especially
> given that so many options have a common meaning across subcommands.
>
> However, I don't understand the mechanism by which this is happening;
> specifically, the mechanism by which main() passes the information
> along. It sounds like it's at least partially genericized, but what
> about option/arg combinations that are specific to a given
> subcommand. How are those passed? Are we going to make the
> subcommand procedure type variadic?
>
> As an experiment, could you try writing the log entry in advance and
> posting it? Obviously, it doesn't have to be 100% the same as what
> you actually end up doing, but knowing how the data structures are
> going to change would probably clear up these things, for me and
> (maybe) for others.
>
> -K
>
> Bruce Korb <bk...@sco.COM> writes:
> > In preparation for ultimately doing some sort of
> > table thingey for options, I want to lay some ground work
> > now. To do this, I want to make a struct type that
> > contains all the data currently used in the client
> > options, plus the command enumeration type. Each
> > command table entry would have a pointer to a struct
> > of this type with just the command enumeration filled
> > in. The current option processing code would be called
> > from main() instead of the command procedures. The command
> > procedures would receive only command arguments (the
> > options stripped off). With this done, changing the
> > underlying option processing should no longer perterb
> > much of any other code (especially the command implementation
> > procedures.)
> >
> > I'll stick a slight rewording of this email
> > into the CVS log when I do this, ok? :-)
--
Greg Stein, http://www.lyra.org/