Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Fix dialplan expression formatting #128

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 27 additions & 27 deletions docs/Configuration/Dialplan/Expressions/Expressions-Examples.md
Original file line number Diff line number Diff line change
@@ -7,32 +7,32 @@ pageid: 4620379

| Expression | Result | Note |
| --- | --- | --- |
| "One Thousand Five Hundred" =~ "(T[Expressions Examples^ ])" | Thousand | |
| "One Thousand Five Hundred" =~ "T[Expressions Examples^ ]" | 8 | |
| "One Thousand Five Hundred" : "T[Expressions Examples^ ]" | 0 | |
| "8015551212" : "(...)" | 801 | |
| "3075551212":"...(...)" | 555 | |
| ! "One Thousand Five Hundred" =~ "T[Expressions Examples^ ]" | 0 | Because it applies to the string, which is non-null, which it turns to "0", and then looks for the pattern in the "0", and doesn't find it |
| !( "One Thousand Five Hundred" : "T[Expressions Examples^ ]+" ) | 1 | Because the string doesn't start with a word starting with T, so the match evals to 0, and the ! operator inverts it to 1 |
| 2 + 8 / 2 | 6 | Because of operator precedence; the division is done first, then the addition |
| 2+8/2 | 6 | Spaces aren't necessary |
| (2+8)/2 | 5 | |
| (3+8)/2 | 5.5 | |
| TRUNC((3+8)/2) | 5 | |
| FLOOR(2.5) | 2 | |
| FLOOR(-2.5) | -3 | |
| CEIL(2.5) | 3 | |
| CEIL(-2.5) | -2 | |
| ROUND(2.5) | 3 | |
| ROUND(3.5) | 4 | |
| ROUND(-2.5) | -3 | |
| RINT(2.5) | 2 | |
| RINT(3.5) | 4 | |
| RINT(-2.5) | -2 | |
| RINT(-3.5) | -4 | |
| TRUNC(2.5) | 2 | |
| TRUNC(3.5) | 3 | |
| TRUNC(-3.5) | -3 | |
| `"One Thousand Five Hundred" =~ "(T[^ ])"` | Thousand | |
| `"One Thousand Five Hundred" =~ "T[^ ]"` | 8 | |
| `"One Thousand Five Hundred" : "T[^ ]"` | 0 | |
| `"8015551212" : "(...)"` | 801 | |
| `"3075551212":"...(...)"` | 555 | |
| `! "One Thousand Five Hundred" =~ "T[^ ]"` | 0 | Because it applies to the string, which is non-null, which it turns to "0", and then looks for the pattern in the "0", and doesn't find it |
| `!( "One Thousand Five Hundred" : "T[^ ]+" )` | 1 | Because the string doesn't start with a word starting with T, so the match evals to 0, and the ! operator inverts it to 1 |
| `2 + 8 / 2` | 6 | Because of operator precedence; the division is done first, then the addition |
| `2+8/2` | 6 | Spaces aren't necessary |
| `(2+8)/2` | 5 | |
| `(3+8)/2` | 5.5 | |
| `TRUNC((3+8)/2)` | 5 | |
| `FLOOR(2.5)` | 2 | |
| `FLOOR(-2.5)` | -3 | |
| `CEIL(2.5)` | 3 | |
| `CEIL(-2.5)` | -2 | |
| `ROUND(2.5)` | 3 | |
| `ROUND(3.5)` | 4 | |
| `ROUND(-2.5)` | -3 | |
| `RINT(2.5)` | 2 | |
| `RINT(3.5)` | 4 | |
| `RINT(-2.5)` | -2 | |
| `RINT(-3.5)` | -4 | |
| `TRUNC(2.5)` | 2 | |
| `TRUNC(3.5)` | 3 | |
| `TRUNC(-3.5)` | -3 | |

Of course, all of the above examples use constants, but would work the same if any of the numeric or string constants were replaced with a variable reference ${CALLERID(num)}, for instance.
Of course, all of the above examples use constants, but would work the same if any of the numeric or string constants were replaced with a variable reference, e.g. `${CALLERID(num)}`.

46 changes: 21 additions & 25 deletions docs/Configuration/Dialplan/Expressions/Operators.md
Original file line number Diff line number Diff line change
@@ -5,35 +5,31 @@ pageid: 4620368

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
* `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 floating point comparison if both arguments are numbers; 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
* `expr1 {+, -} expr2`
Return the results of addition or subtraction of floating point-valued arguments.
* expr1 {\*, /, %} expr2
* `expr1 {\*, /, %} expr2`
Return the results of multiplication, floating point division, or remainder of arguments.
* - expr1
Return the result of subtracting expr1 from 0. This, the unary minus operator, is right associative, and has the same precedence as the ! operator.
* ! expr1
Return the result of a logical complement of expr1. In other words, if expr1 is null, 0, an empty string, or the string "0", return a 1. Otherwise, return a 0. It has the same precedence as the unary minus operator, and is also right associative.
* 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 regular expression subexpression `', the string corresponing 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.

Normally, the double quotes wrapping a string are left as part of the string. This is disastrous to the : operator. Therefore, before the regex match is made, beginning and ending double quote characters are stripped from both the pattern and the string.

* expr1 =~ expr2
Exactly the same as the ':' operator, except that the match is not anchored to the beginning of the string. Pardon any similarity to seemingly similar operators in other programming languages! The ":" and "=~" operators share the same precedence.
* expr1 ? expr2 :: expr3
Traditional Conditional operator. If expr1 is a number that evaluates to 0 (false), expr3 is result of the this expression evaluation. Otherwise, expr2 is the result. If expr1 is a string, and evaluates to an empty string, or the two characters (""), then expr3 is the result. Otherwise, expr2 is the result. In Asterisk, all 3 exprs will be "evaluated"; if expr1 is "true", expr2 will be the result of the "evaluation" of this expression. expr3 will be the result otherwise. This operator has the lowest precedence.
* expr1 ~~ expr2
Concatenation operator. The two exprs are evaluated and turned into strings, stripped of surrounding double quotes, and are turned into a single string with no invtervening spaces. This operator is new to trunk after 1.6.0; it is not needed in existing extensions.conf code. Because of the way asterisk evaluates [ ] constructs (recursively, bottom- up), no is ever present when the contents of a [] is evaluated. Thus, tokens are usually already merged at evaluation time. But, in AEL, various exprs are evaluated raw, and [] are gathered and treated as tokens. And in AEL, no two tokens can sit side by side without an intervening operator. So, in AEL, concatenation must be explicitly specified in expressions. This new operator will play well into future plans, where expressions ( constructs) are merged into a single grammar.
* `- expr1`
Return the result of subtracting `expr1` from 0. This, the unary minus operator, is right associative, and has the same precedence as the `!` operator.
* `! expr1`
Return the result of a logical complement of `expr1`. In other words, if `expr1` is null, 0, an empty string, or the string "0", return a 1. Otherwise, return a 0. It has the same precedence as the unary minus operator, and is also right associative.
* `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 regular expression match group `()`, the string corresponing 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 match group the null string is returned; otherwise 0.
Normally, the double quotes wrapping a string are left as part of the string. This is disastrous to the : operator. Therefore, before the regex match is made, beginning and ending double quote characters are stripped from both the pattern and the string.
* `expr1 =~ expr2`
Exactly the same as the `:` operator, except that the match is not anchored to the beginning of the string. Pardon any similarity to seemingly similar operators in other programming languages! The `:` and `=~` operators share the same precedence.
* `expr1 ? expr2 :: expr3`
Traditional Conditional operator. If `expr1` is a number that evaluates to 0 (false), `expr3` is result of the this expression evaluation. Otherwise, `expr2` is the result. If `expr1` is a string, and evaluates to an empty string, or the two characters `""`, then `expr3` is the result. Otherwise, `expr2` is the result. In Asterisk, all 3 exprs will be "evaluated"; if `expr1` is "true", `expr2` will be the result of the "evaluation" of this expression. `expr3` will be the result otherwise. This operator has the lowest precedence.
* `expr1 ~~ expr2`
Concatenation operator. The two exprs are evaluated and turned into strings, stripped of surrounding double quotes, and are turned into a single string with no invtervening spaces. This operator is new to trunk after 1.6.0; it is not needed in existing `extensions.conf` code. Because of the way asterisk evaluates `$[ ]` constructs (recursively, bottom-up), no ` ` is ever present when the contents of a `[]` is evaluated. Thus, tokens are usually already merged at evaluation time. But, in AEL, various exprs are evaluated raw, and `[]` are gathered and treated as tokens. And in AEL, no two tokens can sit side by side without an intervening operator. So, in AEL, concatenation must be explicitly specified in expressions. This new operator will play well into future plans, where expressions (`$[ ]` constructs) are merged into a single grammar.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about this whole paragraph. A bunch of stuff got chewed up during some import process, I tried to reconstruct it as best as I understood, but it still doesn't really make total sense to me.


Parentheses are used for grouping in the usual manner.

Operator precedence is applied as one would expect in any of the C or C derived languages.