Module: sip-router Branch: andrei/cdefs2doc Commit: ea1f8a283ee6a4077b70b1894c7baa260fa1852e URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=ea1f8a28...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Andrei Pelinescu-Onciul andrei@iptel.org Date: Tue Jan 12 20:48:09 2010 +0100
doc: select doc generator fix flags processing
- fixes based on Jan's select decoding explanations (included in the code as a comment), select.c/resolve_select() and Libor's ser_objdump (http://git.sip-router.org/cgi-bin/gitweb.cgi?p=ser;a=blob;f=ser_objdump/sele...) - '{}' are now used to mark optional parameters
---
doc/scripts/cdefs2doc/dump_selects.pl | 159 +++++++++++++++++++++++++++++---- 1 files changed, 140 insertions(+), 19 deletions(-)
diff --git a/doc/scripts/cdefs2doc/dump_selects.pl b/doc/scripts/cdefs2doc/dump_selects.pl index 1dccee5..4adcf20 100755 --- a/doc/scripts/cdefs2doc/dump_selects.pl +++ b/doc/scripts/cdefs2doc/dump_selects.pl @@ -141,6 +141,84 @@ sub expr_op0{ }
+# constants (from select.h) +use constant { + MAX_SELECT_PARAMS => 32, + MAX_NESTED_CALLS => 4, +}; + +use constant DIVERSION_MASK => 0x00FF; +use constant { + DIVERSION => 1<<8, + SEL_PARAM_EXPECTED => 1<<9, + CONSUME_NEXT_STR => 1<<10, + CONSUME_NEXT_INT => 1<<11, + CONSUME_ALL => 1<<12, + OPTIONAL => 1<<13, + NESTED => 1<<14, + FIXUP_CALL => 1<<15, +}; + +use constant { + SEL_PARAM_INT => 0, + SEL_PARAM_STR => 1, + SEL_PARAM_DIV => 2, + SEL_PARAM_PTR => 3, +}; + + + +# Select rules (pasted from one email from Jan): +# Roughly the rules are as follows: +# * The first component of the row tells the select compiler in what state the +# row can be considered. +# * The second component tells the compiler what type of components is expected +# for the row to match. SEL_PARAM_STR means that .foo should follow, +# SEL_PARAM_INT means that [1234] should follow. +# * The third component is the string to be matched for string components and +# STR_NULL if the next expected component is an integer. +# * The fourth component is a function name. This is either the function to be +# called if this is the last rule all constrains are met, or it is the next +# state to transition into if we are not processing the last component of the +# select identifier. +# +# * The fifth rule are flags that can impose further constrains on how the +# given line is to be used. Some of them are: +# +# - CONSUME_NEXT_INT - This tells the compiler that there must be at least one +# more component following the current one, but it won't transition into the +# next state, instead the current function will "consume" the integer as +# parameters. +# +# - CONSUME_NEXT_STR - Same as previous, but the next component must be a +# string. +# - SEL_PARAM_EXPECTED - The current row must not be last and there must be +# another row to transition to. +# +# - OPTIONAL - There may or may not be another component, but in any case the +# compiler does not transition into another state (row). This can be used +# together with CONSUME_NEXT_{STR,INT} to implement optional parameters, for +# example .param could return a string of all parameters, while .param.abc +# will only return the value of parameter abc. +# +# - NESTED - When this flag is present in a rule then it means that the +# previous function should be called before the current one. The original +# idea was that all select identifiers would only resolve to one function +# call, however, it turned out to be inconvenient in some cases so we added +# this. This is typically used in selects that have URIs as components. In +# that case it is desirable to support all subcomponents for uri selects, but +# it does not make sense to reimplement them for every single case. In that +# case the uri components sets NESTED flags which causes the "parent" +# function to be called first. The "parent" function extracts only the URI +# which is then passed to the corresponding URI parsing function. The word +# NESTED here means "nested function call". +# +# - CONSUME_ALL - Any number of select identifier components may follow and +# they may be of any types. This flag causes the function on the current row +# to be called and it is up to the function to handle the remainder of the +# select identifier. + +
# generate all select strings starting with a specific "root" function sub gen_selects @@ -154,32 +232,75 @@ sub gen_selects @matches = grep(${$_}[0] eq $root, @sel_exports); for $m (@matches) { + my $s=""; ($prev, $type, $name, $new_f, $flags)=@$m; - if (($flags & (1024|2048|4096)) && $name ne ""){ - if ($flags & 1024){ - $name.="[string]"; - }elsif ($flags & 2048){ - $name.="[integer]"; + if (!($flags & NESTED) || + (($flags & NESTED) && ($type !=SEL_PARAM_INT))){ + # Note: unamed NESTED params are not allowed --andrei + if ($type==SEL_PARAM_INT){ + $s.="[integer]"; }else{ - $name.="[]" + if ($name ne "") { + $s.=(($prev eq "0" || $prev eq "")?"@":".") . $name; + }elsif (!($flags & NESTED)){ + $s.=".<string>"; + } } } - if ($new_f eq "" || - $new_f eq "0" - ){ - push @ret, $name; - }else{ - if ($name eq ""){ - @sel=gen_selects($new_f); + if ( !($flags & NESTED) && + ($flags & (CONSUME_NEXT_STR|CONSUME_NEXT_INT|CONSUME_ALL)) ){ + #process params + if ($flags & OPTIONAL){ + $s.="{"; + } + # add param name + if ($flags & CONSUME_NEXT_STR){ + $s.="["string"]"; + }elsif ($flags & CONSUME_NEXT_INT){ + $s.="[integer]"; }else{ - @sel=map("$name.$_", gen_selects($new_f)); + $s.=".*"; # CONSUME_ALL + } + if ($flags & OPTIONAL){ + $s.="}"; } - if (@sel > 0) { - push(@ret, $name) if (! (($flags & (512|16384)) || - ($name eq ""))); - push @ret, @sel; + } + + if (!($flags & SEL_PARAM_EXPECTED)){ + # if optional terminal add it to the list along with all the + # variants + if ($new_f eq "" || $new_f eq "0"){ + push @ret, $s; }else{ - push @ret, $name; + if ($s eq ""){ + @sel=gen_selects($new_f); + }else{ + @sel=map("$s$_", gen_selects($new_f)); + } + if (@sel > 0) { + push(@ret, $s) if (!($s eq "")); + push @ret, @sel; + }else{ + if ($flags & NESTED) { + $s.="*"; + } + push @ret, $s; + } + } + }else{ + # non-terminal + if (!($new_f eq "" || $new_f eq "0")){ + if ($s eq ""){ + @sel=gen_selects($new_f); + }else{ + @sel=map("$s$_", gen_selects($new_f)); + } + if (@sel > 0) { + push @ret, @sel; + }elsif ($flags & NESTED){ + $s.="*"; + push @ret, $s; + } } } }