When taking a substring and a negative length is provided, instead of just

ignoring it, allow this to mean that we want that many characters off of
the end of the string so that ${EXTEN:0:$[${LEN(${EXTEN}) - 1]} can become
${EXTEN:0:-1}.  (issue #7586, Corydon)


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@39659 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.4
Russell Bryant 19 years ago
parent 781f9dbcaf
commit 2f2cce01d2

@ -139,8 +139,12 @@ previous example).
;Save the numbers 555 to the 'number' variable ;Save the numbers 555 to the 'number' variable
exten => _9X.,1,Set(number=${EXTEN:-7:3}) exten => _9X.,1,Set(number=${EXTEN:-7:3})
If a negative length value is entered, it is ignored and Asterisk will match If a negative length value is entered, Asterisk will remove that many characters
to the end of the string. from the end of the string.
;Set pin to everything but the trailing #.
exten => _XXXX#,1,Set(pin=${EXTEN:0:-1})
___________________________ ___________________________
EXPRESSIONS: EXPRESSIONS:
--------------------------- ---------------------------

22
pbx.c

@ -36,6 +36,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include <errno.h> #include <errno.h>
#include <time.h> #include <time.h>
#include <sys/time.h> #include <sys/time.h>
#include <limits.h>
#include "asterisk/lock.h" #include "asterisk/lock.h"
#include "asterisk/cli.h" #include "asterisk/cli.h"
@ -1020,9 +1021,6 @@ static struct ast_exten *pbx_find_extension(struct ast_channel *chan,
return NULL; return NULL;
} }
/* Note that it's negative -- that's important later. */
#define DONT_HAVE_LENGTH 0x80000000
/*! \brief extract offset:length from variable name. /*! \brief extract offset:length from variable name.
* Returns 1 if there is a offset:length part, which is * Returns 1 if there is a offset:length part, which is
* trimmed off (values go into variables) * trimmed off (values go into variables)
@ -1032,7 +1030,7 @@ static int parse_variable_name(char *var, int *offset, int *length, int *isfunc)
int parens=0; int parens=0;
*offset = 0; *offset = 0;
*length = DONT_HAVE_LENGTH; *length = INT_MAX;
*isfunc = 0; *isfunc = 0;
for (; *var; var++) { for (; *var; var++) {
if (*var == '(') { if (*var == '(') {
@ -1053,8 +1051,8 @@ static int parse_variable_name(char *var, int *offset, int *length, int *isfunc)
* *
* offset < 0 means start from the end of the string and set the beginning * offset < 0 means start from the end of the string and set the beginning
* to be that many characters back. * to be that many characters back.
* length is the length of the substring, -1 means unlimited * length is the length of the substring. A value less than 0 means to leave
* (we take any negative value). * that many off the end.
* Always return a copy in workspace. * Always return a copy in workspace.
*/ */
static char *substring(const char *value, int offset, int length, char *workspace, size_t workspace_len) static char *substring(const char *value, int offset, int length, char *workspace, size_t workspace_len)
@ -1064,12 +1062,12 @@ static char *substring(const char *value, int offset, int length, char *workspac
ast_copy_string(workspace, value, workspace_len); /* always make a copy */ ast_copy_string(workspace, value, workspace_len); /* always make a copy */
lr = strlen(ret); /* compute length after copy, so we never go out of the workspace */
/* Quick check if no need to do anything */ /* Quick check if no need to do anything */
if (offset == 0 && length < 0) /* take the whole string */ if (offset == 0 && length >= lr) /* take the whole string */
return ret; return ret;
lr = strlen(ret); /* compute length after copy, so we never go out of the workspace */
if (offset < 0) { /* translate negative offset into positive ones */ if (offset < 0) { /* translate negative offset into positive ones */
offset = lr + offset; offset = lr + offset;
if (offset < 0) /* If the negative offset was greater than the length of the string, just start at the beginning */ if (offset < 0) /* If the negative offset was greater than the length of the string, just start at the beginning */
@ -1083,6 +1081,12 @@ static char *substring(const char *value, int offset, int length, char *workspac
ret += offset; /* move to the start position */ ret += offset; /* move to the start position */
if (length >= 0 && length < lr - offset) /* truncate if necessary */ if (length >= 0 && length < lr - offset) /* truncate if necessary */
ret[length] = '\0'; ret[length] = '\0';
else if (length < 0) {
if (lr > offset - length) /* After we remove from the front and from the rear, is there anything left? */
ret[lr + length - offset] = '\0';
else
ret[0] = '\0';
}
return ret; return ret;
} }

Loading…
Cancel
Save