.- 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@