[Home]

Summary:ASTERISK-10208: Unable to use variables containing times
Reporter:K Anderson (kanderson)Labels:
Date Opened:2007-08-30 18:38:34Date Closed:2007-09-02 21:43:14
Priority:MinorRegression?No
Status:Closed/CompleteComponents:Functions/func_logic
Versions:Frequency of
Occurrence
Related
Issues:
Environment:Attachments:( 0) 20070831__bug10613.diff.txt
Description:Due to the syntax of the function IF I am unable to use it (or any other) logic functions to make decisions on variables holding times.  Example:

Set(REDIRECT_TIME=${ODBC_PREF(${MACRO_CONTEXT}|${MACRO_EXTEN}|REDIRECT_TIME)})
Set(REDIRECT_TIME=${IF($["REDIRECT_TIME" != ""]?${REDIRECT_TIME}:"*|*|*|*")})
GotoIfTime(${REDIRECT_TIME}}?INSIDE_RANGE)

1. A odbc connection is used to query a MySQL table for this context/extensions REDIRECT_TIME.
2. If there was no return from the MySQL then use wildcards (works) otherwise use the time found (broken)
3. Goto based on the time

In this example if the MySQL holds a time then func if incorrectly uses the first ':' (8:00-17:00|mon-fri) effectively making the if statement:
           ^


IF REDIRECT_TIME ? 8 : 00-17:00|mon-fri

Which fails.  After looking into the source code I (albeit not a programmer) recommend either not striping quotes first (if present) or using a regex to find the last occurance of ':'
Comments:By: Jason Parker (jparker) 2007-08-30 21:02:12

$["REDIRECT_TIME" != ""] is always going to evaluate as true.

Do you perhaps mean $["${REDIRECT_TIME}" != ""] ?

By: K Anderson (kanderson) 2007-08-30 21:36:02

Sorry, typo while writing report.  Yes, I meant the variable is not blank, as posted would always evaluate as true.  However, the issue is not with the conditional engine but rather what is set as 'iftrue', 'iffalse' when there are multiple colons.  I did realize that the last occurance of the colon would not be a good test as the last return is optional.  I would like to recommend a regex such as "(.{1,})\\?(.*):(.{1,})".  as that would force the proper format and adapt to optional fields. Or similar, I think that wouldn't work for dates as the false value (note the above is untested and written on the fly).  Anyway, sorry about the typo.

By: Tilghman Lesher (tilghman) 2007-08-31 11:35:45

If we use the standard parsing functions, at least it's possible, although the amount of escaping you may have to do might be slightly insane.

By: K Anderson (kanderson) 2007-08-31 13:07:02

Applied the above patch but still had the same problem.  I created a test using the above code (but corrected the variable in second line) which produced the erroneous output:

   -- Executing [s@macro-CEP:9] Set("Local/CEP@099-99fc,2", "REDIRECT_TIME=8:00-21:00|mon-fri") in new stack
   -- Executing [s@macro-CEP:10] Set("Local/CEP@099-99fc,2", "REDIRECT_TIME=8") in new stack

As you can see the func if incorrectly sets REDIRECT_TIME to '8' because that is the first occurance of the true/false delimiter ':' even though it is both within quotes and valid.

Note the above was preformed with the uploaded 20070831_bug10613.diff applied but as it did not correct the problem I have since reverted.

I wish I new C better but if you where to implement the changes I am suggesting in perl it would look like this (notice this too is untested and written on the fly):

if ($data =~ m/(.*)\?"(.*)":"(.*)"/) {
$expr = $1;
$iftrue = $2;
$iffalse = $3;
} else {
$data =~ s/"//g;
@expr_split = split(/?/, $data);
$expr = @expr_split[0];
@return_split = split(/:/, @expr_split[1]);
$iftrue = @return_split[0];
$iffalse = @return_split[1];
}

Basicly if there are '"' around the 'iftrue' and 'iffalse' in the func if call then treat it as a group otherwise preform as normal.

By: Tilghman Lesher (tilghman) 2007-08-31 13:35:43

Like I said, you need escaping:

exten => 124,1,Set(mytime=8:30-17:00)
exten => 124,n,Set(mybtime=${IF(${mytime}?${mytime}:)})
exten => 124,n,Set(mybtime=${IF(${mytime}?"${mytime}":foo)})
exten => 124,n,Set(mybtime=${IF(${mytime}?\"${mytime}\":foo)})
exten => 124,n,Set(mybtime=${IF(${mytime}?\\\"${mytime}\\\":foo)})

This last one is probably what you're going to have to use to get it to work correctly in 1.4.  The second one (with quotes, but no backslashes) is what you can use in trunk, because we made some changes for sanity sake.

However, you still have yet another problem, which is that you CANNOT set the '|' character in a variable in 1.4.  Period.  Impossible.  It just does not support it and it is the reason why we have made the above changes for trunk.

What you'll probably have to do to get around this restriction is to use the ${SET()} dialplan function, as it does not have this limitation.

By: Digium Subversion (svnbot) 2007-08-31 13:58:39

Repository: asterisk
Revision: 81415

------------------------------------------------------------------------
r81415 | tilghman | 2007-08-31 13:58:39 -0500 (Fri, 31 Aug 2007) | 2 lines

The IF() function was not allowing true values that had embedded colons (closes issue ASTERISK-10208)

------------------------------------------------------------------------

By: Digium Subversion (svnbot) 2007-09-02 21:43:14

Repository: asterisk
Revision: 81431

------------------------------------------------------------------------
r81431 | tilghman | 2007-09-02 21:43:12 -0500 (Sun, 02 Sep 2007) | 10 lines

Merged revisions 81415 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r81415 | tilghman | 2007-08-31 14:16:52 -0500 (Fri, 31 Aug 2007) | 2 lines

The IF() function was not allowing true values that had embedded colons (closes issue ASTERISK-10208)

........

------------------------------------------------------------------------