Version 0.2.0 from FTP
authorMark Spencer <markster@digium.com>
Fri, 6 Sep 2002 15:22:51 +0000 (15:22 +0000)
committerMark Spencer <markster@digium.com>
Fri, 6 Sep 2002 15:22:51 +0000 (15:22 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@519 65c4cc65-6c06-0410-ace0-fbb531ad65f3

README.variables [new file with mode: 0755]
doc/README.variables [new file with mode: 0755]
include/asterisk/linkedlists.h [new file with mode: 0755]

diff --git a/README.variables b/README.variables
new file mode 100755 (executable)
index 0000000..9dbafd1
--- /dev/null
@@ -0,0 +1,135 @@
+GENERAL ENCHANCEMENTS TO EXTENSION LOGIC : 
+
+QUOTING: 
+
+exten => s,5,BackGround,blabla
+
+The parameter (blabla) can be quoted ("blabla"). In this case, a 
+comma does not terminate the field. 
+
+Also, characters special to variable substitution, expression evaluation, etc
+(see below), can be quoted. For example, to literally use a $ on the 
+string "$1231", quote it with a preceeding \. Special characters that must
+be quoted to be used, are [ ] $ " \. (to write \ itself, use \\). 
+
+VARIABLES: 
+
+Parameter strings can include variables. Variable names are arbitrary strings. 
+They are stored in the respective channel structure. 
+
+To set a variable to a particular value, do : 
+
+;exten => 1,2,SetVar,varname=value
+
+You can substitute the value of a variable everywhere using ${variablename}.
+For example, to stringwise append $lala to $blabla and store result in $koko, 
+do: 
+
+;exten => 1,2,SetVar,koko=${blabla}${lala}
+
+There are also the following special variables: 
+
+${CALLERID}    Caller ID
+${EXTEN}       Current extension
+${CONTEXT}      Current context
+${PRIORITY}    Current priority
+
+There are two reference modes - reference by value and reference by name. 
+To refer to a variable with its name (as an argument to a function that 
+requires a variable), just write the name. To refer to the variable's value, 
+enclose it inside ${}. For example, SetVar takes as the first argument 
+(before the =) a variable name, so: 
+
+;exten => 1,2,SetVar,koko=lala
+;exten => 1,3,SetVar,${koko}=blabla
+
+stores to the variable "koko" the value "lala" and to variable "lala" the 
+value "blabla". 
+
+In fact, everything contained ${here} is just replaced with the value of 
+the variable "here". 
+
+EXPRESSIONS: 
+
+Everything contained inside a bracket pair prefixed by a $ (like $[this]) is 
+considered as an expression and it is evaluated. Evaluation works similar to 
+(but is done on a later stage than) variable substitution: the expression 
+(including the square brackets) is replaced by the result of the expression 
+evaluation. The arguments and operands of the expression MUST BE separated 
+with spaces (take care NOT to leave ANY spaces between opening and closing 
+square brackets and the first and last arguments). 
+
+For example, after the sequence: 
+
+exten => 1,1,SetVar,"lala=$[1 + 2]";
+exten => 1,2,SetVar,"koko=$[2 * ${lala}]";
+
+the value of variable koko is "6".
+
+Operators are listed below in order of increasing precedence.  Operators
+with equal precedence are grouped within { } symbols.
+
+     expr1 | expr2
+             Return the evaluation of expr1 if it is neither an empty string
+             nor zero; otherwise, returns the evaluation of expr2.
+
+     expr1 & expr2
+             Return the evaluation of expr1 if neither expression evaluates to
+             an empty string or zero; otherwise, returns zero.
+
+     expr1 {=, >, >=, <, <=, !=} expr2
+             Return the results of integer comparison if both arguments are
+             integers; otherwise, returns the results of string comparison
+             using the locale-specific collation sequence.  The result of each
+             comparison is 1 if the specified relation is true, or 0 if the
+             relation is false.
+
+     expr1 {+, -} expr2
+             Return the results of addition or subtraction of integer-valued
+             arguments.
+
+     expr1 {*, /, %} expr2
+             Return the results of multiplication, integer division, or
+             remainder of integer-valued arguments.
+
+     expr1 : expr2
+             The `:' operator matches expr1 against expr2, which must be a
+             regular expression.  The regular expression is anchored to the
+             beginning of  the string with an implicit `^'.
+
+             If the match succeeds and the pattern contains at least one regu-
+             lar expression subexpression `\(...\)', the string correspond-
+             ing to `\1' is returned; otherwise the matching operator
+             returns the number of characters matched.  If the match fails and
+             the pattern contains a regular expression subexpression the null
+             string is returned; otherwise 0.
+
+Parentheses are used for grouping in the usual manner.
+
+The parser must be parsed with bison (bison is REQUIRED - yacc cannot 
+produce pure parsers, which are reentrant) 
+
+CONDITIONALS
+
+There is one conditional operator - the conditional goto : 
+
+;exten => 1,2,gotoif,condition?label1:label2
+
+If condition is true go to label1, else go to label2. Labels are interpreted
+exactly as in the normal goto command.
+
+"condition" is just a string. If the string is empty or "0", the condition
+is considered to be false, if it's anything else, the condition is true. 
+This is designed to be used together with the expression syntax described 
+above, eg : 
+
+exten => 1,2,gotoif,$[${CALLERID} = 123456]?2|1:3|1
+
+
+Example of use : 
+
+exten => s,2,SetVar,"vara=1"
+exten => s,3,SetVar,"varb=$[${vara} + 2]"
+exten => s,4,SetVar,"varc=$[${varb} * 2]"
+exten => s,5,GotoIf,"$[${varc} = 6]?99|1:s|6";
+
diff --git a/doc/README.variables b/doc/README.variables
new file mode 100755 (executable)
index 0000000..9dbafd1
--- /dev/null
@@ -0,0 +1,135 @@
+GENERAL ENCHANCEMENTS TO EXTENSION LOGIC : 
+
+QUOTING: 
+
+exten => s,5,BackGround,blabla
+
+The parameter (blabla) can be quoted ("blabla"). In this case, a 
+comma does not terminate the field. 
+
+Also, characters special to variable substitution, expression evaluation, etc
+(see below), can be quoted. For example, to literally use a $ on the 
+string "$1231", quote it with a preceeding \. Special characters that must
+be quoted to be used, are [ ] $ " \. (to write \ itself, use \\). 
+
+VARIABLES: 
+
+Parameter strings can include variables. Variable names are arbitrary strings. 
+They are stored in the respective channel structure. 
+
+To set a variable to a particular value, do : 
+
+;exten => 1,2,SetVar,varname=value
+
+You can substitute the value of a variable everywhere using ${variablename}.
+For example, to stringwise append $lala to $blabla and store result in $koko, 
+do: 
+
+;exten => 1,2,SetVar,koko=${blabla}${lala}
+
+There are also the following special variables: 
+
+${CALLERID}    Caller ID
+${EXTEN}       Current extension
+${CONTEXT}      Current context
+${PRIORITY}    Current priority
+
+There are two reference modes - reference by value and reference by name. 
+To refer to a variable with its name (as an argument to a function that 
+requires a variable), just write the name. To refer to the variable's value, 
+enclose it inside ${}. For example, SetVar takes as the first argument 
+(before the =) a variable name, so: 
+
+;exten => 1,2,SetVar,koko=lala
+;exten => 1,3,SetVar,${koko}=blabla
+
+stores to the variable "koko" the value "lala" and to variable "lala" the 
+value "blabla". 
+
+In fact, everything contained ${here} is just replaced with the value of 
+the variable "here". 
+
+EXPRESSIONS: 
+
+Everything contained inside a bracket pair prefixed by a $ (like $[this]) is 
+considered as an expression and it is evaluated. Evaluation works similar to 
+(but is done on a later stage than) variable substitution: the expression 
+(including the square brackets) is replaced by the result of the expression 
+evaluation. The arguments and operands of the expression MUST BE separated 
+with spaces (take care NOT to leave ANY spaces between opening and closing 
+square brackets and the first and last arguments). 
+
+For example, after the sequence: 
+
+exten => 1,1,SetVar,"lala=$[1 + 2]";
+exten => 1,2,SetVar,"koko=$[2 * ${lala}]";
+
+the value of variable koko is "6".
+
+Operators are listed below in order of increasing precedence.  Operators
+with equal precedence are grouped within { } symbols.
+
+     expr1 | expr2
+             Return the evaluation of expr1 if it is neither an empty string
+             nor zero; otherwise, returns the evaluation of expr2.
+
+     expr1 & expr2
+             Return the evaluation of expr1 if neither expression evaluates to
+             an empty string or zero; otherwise, returns zero.
+
+     expr1 {=, >, >=, <, <=, !=} expr2
+             Return the results of integer comparison if both arguments are
+             integers; otherwise, returns the results of string comparison
+             using the locale-specific collation sequence.  The result of each
+             comparison is 1 if the specified relation is true, or 0 if the
+             relation is false.
+
+     expr1 {+, -} expr2
+             Return the results of addition or subtraction of integer-valued
+             arguments.
+
+     expr1 {*, /, %} expr2
+             Return the results of multiplication, integer division, or
+             remainder of integer-valued arguments.
+
+     expr1 : expr2
+             The `:' operator matches expr1 against expr2, which must be a
+             regular expression.  The regular expression is anchored to the
+             beginning of  the string with an implicit `^'.
+
+             If the match succeeds and the pattern contains at least one regu-
+             lar expression subexpression `\(...\)', the string correspond-
+             ing to `\1' is returned; otherwise the matching operator
+             returns the number of characters matched.  If the match fails and
+             the pattern contains a regular expression subexpression the null
+             string is returned; otherwise 0.
+
+Parentheses are used for grouping in the usual manner.
+
+The parser must be parsed with bison (bison is REQUIRED - yacc cannot 
+produce pure parsers, which are reentrant) 
+
+CONDITIONALS
+
+There is one conditional operator - the conditional goto : 
+
+;exten => 1,2,gotoif,condition?label1:label2
+
+If condition is true go to label1, else go to label2. Labels are interpreted
+exactly as in the normal goto command.
+
+"condition" is just a string. If the string is empty or "0", the condition
+is considered to be false, if it's anything else, the condition is true. 
+This is designed to be used together with the expression syntax described 
+above, eg : 
+
+exten => 1,2,gotoif,$[${CALLERID} = 123456]?2|1:3|1
+
+
+Example of use : 
+
+exten => s,2,SetVar,"vara=1"
+exten => s,3,SetVar,"varb=$[${vara} + 2]"
+exten => s,4,SetVar,"varc=$[${varb} * 2]"
+exten => s,5,GotoIf,"$[${varc} = 6]?99|1:s|6";
+
diff --git a/include/asterisk/linkedlists.h b/include/asterisk/linkedlists.h
new file mode 100755 (executable)
index 0000000..c1a3d9d
--- /dev/null
@@ -0,0 +1,81 @@
+#ifndef ASTERISK_LINKEDLISTS_H
+#define ASTERISK_LINKEDLISTS_H
+
+#include <pthread.h>
+
+#define AST_LIST_LOCK(head)                                            \
+       ast_pthread_mutex_lock(&head->lock) 
+       
+#define AST_LIST_UNLOCK(head)                                          \
+       ast_pthread_mutex_unlock(&head->lock)
+
+#define AST_LIST_HEAD(name, type)                                      \
+struct name {                                                          \
+       struct type *first;                                             \
+       pthread_mutex_t lock;                                           \
+}
+
+#define AST_LIST_HEAD_INITIALIZER(head)                                        \
+       { NULL, PTHREAD_MUTEX_INITIALIZER }
+       
+#define AST_LIST_HEAD_SET(head,entry) do {                             \
+       (head)->first=(entry);                                          \
+       pthread_mutex_init(&(head)->lock,NULL);                         \
+} while (0)
+
+#define AST_LIST_ENTRY(type)                                           \
+struct {                                                               \
+       struct type *next;                                              \
+}
+#define        AST_LIST_FIRST(head)    ((head)->first)
+
+#define AST_LIST_NEXT(elm, field)      ((elm)->field.next)
+
+#define        AST_LIST_EMPTY(head)    (AST_LIST_FIRST(head) == NULL)
+
+#define AST_LIST_TRAVERSE(head,var,field)                              \
+       for((var) = (head)->first; (var); (var) = (var)->field.next)
+
+#define AST_LIST_HEAD_INIT(head) {                                             \
+       (head)->first = NULL;                                           \
+       pthread_mutex_init(&(head)->lock,NULL);                         \
+}
+
+#define AST_LIST_INSERT_AFTER(listelm, elm, field) do {                \
+       (elm)->field.next = (listelm)->field.next;                      \
+       (listelm)->field.next = (elm);                          \
+} while (0)
+
+#define AST_LIST_INSERT_HEAD(head, elm, field) do {                    \
+               (elm)->field.next = (head)->first;                      \
+               (head)->first = (elm);                                  \
+} while (0)
+
+#define AST_LIST_INSERT_TAIL(head, elm, type, field) do {             \
+      struct type *curelm = (head)->first;                            \
+      while ( curelm->field.next!=NULL ) {                            \
+              curelm=curelm->field.next;                              \
+      }                                                               \
+      AST_LIST_INSERT_AFTER(curelm,elm,field);                        \
+} while (0)
+
+
+#define AST_LIST_REMOVE_HEAD(head, field) do {                                 \
+               (head)->first = (head)->first->field.next;                      \
+       } while (0)
+
+#define AST_LIST_REMOVE(head, elm, type, field) do {                   \
+       if ((head)->first == (elm)) {                                   \
+               AST_LIST_REMOVE_HEAD((head), field);                    \
+       }                                                               \
+       else {                                                          \
+               struct type *curelm = (head)->first;                    \
+               while( curelm->field.next != (elm) )                    \
+                       curelm = curelm->field.next;                    \
+               curelm->field.next =                                    \
+                   curelm->field.next->field.next;                     \
+       }                                                               \
+} while (0)
+
+#endif