Module: sip-router
Branch: andrei/cdefs2doc
Commit: ea1f8a283ee6a4077b70b1894c7baa260fa1852e
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=ea1f8a2…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)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/sel…)
- '{}' 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;
+ }
}
}
}