.-
help for ^p_vlists^                                @net:from http://www.stata.com/users/wwg!http://www.stata.com/users/wwg@
.-

Parse multiple varlists
-----------------------

	^p_vlists^ desc desc ... desc ^:^ string

where

	desc is  { ^varname^ | ^varlist^ | ^varname(^...^)^ | ^varlist(^...^)^ } 

and  ^varname()^ and ^varlist()^ are coded as defined by ^syntax^; see help @syntax@.
string is typically coded as ^`0'^.  

One set of square brackets may be coded to indicate the varlist(s) are
optional, e.g.,

	^p_vlists [varlist varlist] : `0'^
or
	^p_vlists varlist [varlist] : `0'^
or
	^p_vlists varlist varlist [varlist] : `0'^
or
	^p_vlists varlist [varlist varlist] : `0'^
or
	^p_vlists [varlist varlist varlist] : `0'^


Description
-----------

^p_vlists^ is a programmer's command to assist parsing commands of the form

	mycmd ^(^varlist^)^ ^(^varlist^)^ ...

For instance, the full syntax of mycmd might be 

	mycmd ^(^varlist^)^ ^(^varlist^)^ ^if^ exp ^in^ range [^,^ ^nocons^tant]

and if it were, the mycmd code would read 

	^program define^ mycmd
		^version 6^
		^p_vlists varlist varlist : `0'^
		^local 0  `s(rest)'^
		^syntax [if] [in] [, NOCONStant]^
		^local v1 `s(v1)'^
		^local v2 `s(v2)'^
		...
	^end^

This code would allow the user to type

	. ^mycmd (mpg weight) (displ rseat) if mpg>20^
or
	. ^mycmd mpg weight (displ rseat) if mpg>20^
or
	. ^mycmd (mpg weight) displ rseat if mpg>20^

That is, the user could type one set of parentheses or two.  However, 

	. ^mycmd mpg weight if mpg>20^

would be an error because "mpg varlist" would be interpreted as the first
varlist and two varlists are required:

	. ^mycmd mpg weight if mpg>20^
	too few varlists specified
	r(102);

If the syntax of mycmd were 

	mycmd ^(^varlist^)^ [^(^varlist^)^] ^if^ exp ^in^ range [^,^ ^nocons^tant]

which is to say, if the second varlist was optional, the ^p_vlists^ command in
the above program could be changed from

		^p_vlists varlist varlist : `0'^
to
		^p_vlists varlist [varlist] : `0'^

Now if the user typed 

	. ^mycmd mpg weight if mpg>20^
or
	. ^mycmd (mpg weight) if mpg>20^

neither would be considered an error; the user specified that the first varlist
is "mpg weight" and the second is empty.

^p_vlists^ treats the ^varname^ directive specially.  If you coded 

		^p_vlists varname varlist : `0'^

then if the user typed 

	. ^mycmd mpg weight if mpg>20^

it would be interpreted as if the user typed 

	. ^mycmd (mpg) (weight) if mpg>20^

and if the user typed 

	. ^mycmd mpg weight displ if mpg>20^

it would be interpreted as if the user typed 

	. ^mycmd (mpg) (weight displ) if mpg>20^

p_vlists does not look ahead, however.  Consider 

		^p_vlists varlist varname : `0'^

If the user typed 

	. ^mycmd mpg weight displ if mpg>20^

it would be considered an error because the first varlist would consume "mpg
weight displ" leaving nothing for the second.  The user would need to type

	. ^mycmd (mpg weight) displ if mpg>20^



Saved results
-------------

^p_vlists^ returns in ^s()^

	^s(n)^      the number of varlists specified by the user.
        ^s(v1)^     the first varlist, expanded
        ^s(v2)^     the second varlist, expanded
	...
	^s(rest)^   the rest of the command line, unparsed

^p_vlists^ returns the error "too few varlists specified", r(102), if the 
user does not specify at least as many varlists as are required.

Note the proper way to use ^p_vlists^ is 

	^p_vlists^ ... ^: `0'^
	^local 0 `rest'^
	^syntax ...^

You must do this even when the syntax diagram for the command being
implemented allows nothing following the varlists, in which case the code
should read

	^p_vlists^ ... ^: `0'^
	^local 0 `rest'^
	^syntax^

or

	^p_vlists^ ... ^: `0'^
	^if `"`rest'"' ~= "" {^
		^di in red "too many varlists specified"^
		^exit 103^
	^}^

The user might specify too many varlists and if the user does, ^p_vlists^ will
not notice the mistake.  ^p_vlists^ will simply return in ^s(rest)^ the unparsed
part.


Also see
--------

On-line:  help for @syntax@, @args@, @gettoken@, @tokenize@
