Summary:ASTERISK-04276: [patch] add new function STRSTR returning position of substring in string
Reporter:Gregory Hinton Nietsky (irroot)Labels:
Date Opened:2005-05-25 16:56:15Date Closed:2011-06-07 14:05:16
Versions:Frequency of
Environment:Attachments:( 0) func_strpos3
Description:pretty funky toy based on strstr() to return the position of a substring in a string as per my request on asterisk-dev
Comments:By: Gregory Hinton Nietsky (irroot) 2005-05-25 17:02:11

ive updated my first copy with one that returns a "0" if there is no match makes cheking easier

some examples ...

a macro to do call forwarding either based on callerid or supplied number
... the first example can be achived in other ways i prefer to keep it simple

;to forward all calls to a alternate number dial *21* followed by the
;number to forward and to cancel dial *21
;the number can be *21*<EXTEN>*<number to forward to>
exten => _*21*X.,1,Macro(fwdim,${CALLERIDNUM},${EXTEN:4})
exten => *21,1,Macro(fwdim,${CALLERIDNUM})

exten => s,1,GotoIF(${EXISTS(${ARG2})}?:del)
exten => s,n,GotoIf($[${STRPOS(*,${ARG2})} > 0]?new)
exten => s,n,SET(CFIM=${ARG2})
exten => s,n,SET(FWD=${ARG1})
exten => s,n,Goto(fwd)
exten => s,n(new),SET(NUMBER=${STRPOS(*,${ARG2})})
exten => s,n,SET(FWD=${ARG2:0:${NUMBER}})
exten => s,n,SET(TMP=${ARG2:${NUMBER}})
exten => s,n,SET(CFIM=${TMP:1})
exten => s,n(fwd),Macro(authuser,${FWD})
exten => s,n,SET(RTDB(${FWD}/CFIM)=${CFIM})
exten => s,n,Background(call-fwd-unconditional)
exten => s,n,Background(activated)
exten => s,n,Hangup
exten => s,n(del),SET(RTDB(${ARG1}/CFIM)=)
exten => s,n,Macro(authuser,${ARG1})
exten => s,n,Background(call-fwd-unconditional)
exten => s,n,Background(de-activated)
exten => s,n,Hangup

By: Kevin P. Fleming (kpfleming) 2005-06-02 22:44:10

This line of code:

+ position = strlen(argv[1])-strlen(strpos);

can be simplified to:

 position = strpos - argv[1];

Also, do you have a disclaimer on file?

By: Tilghman Lesher (tilghman) 2005-06-03 14:12:58

Since this is pretty much just a wrapper for strstr(3), wouldn't it make sense to call the function name STRSTR() ?  While you're at it, you might implement STRCASESTR() with essentially the same code, but with a single substitution.

By: Kevin P. Fleming (kpfleming) 2005-06-03 14:54:50

If it was called STRSTR, would users potentially expect it to actually _return_ the located substring, as strstr() does?

By: Tilghman Lesher (tilghman) 2005-06-03 15:20:44

I don't think so.  What strstr(3) returns is really a pointer (a position) or NULL.

Also, for non-existence, the function should return -1, not 0.  If the substring were found at the first position, wouldn't it return 0 (meaning no offset)?

By: Kevin P. Fleming (kpfleming) 2005-06-03 15:26:37

Well, in C, a pointer is both a position _and_ the substring itself. I can see value in STRSTR() actually returning the found substring, since it's very, very likely that nearly all users of this function are just going to use the returned value to take a substring of the original string anyway.

Anyone else want to jump in with their opinion?

By: Tilghman Lesher (tilghman) 2005-06-03 16:16:24

I suspect far more usage of strstr(3) is to treat the return value as a boolean.  We're not interested in the substring, since we already know what that is (after all, we passed it in); we're interested in whether it was found or not.

It should mirror the functionality of Perl's POSIX::strstr() which is a logical model to follow.

By: Kevin P. Fleming (kpfleming) 2005-06-03 17:04:33

Yes, I agree with that.

OK, then it should be STRSTR, and return -1 when the string is not found, or a zero-based index when it is found. STRCASESTR would do the same thing, with the obvious change to case-insensitivity.

By: Gregory Hinton Nietsky (irroot) 2005-06-04 02:47:58

ill work on the case version soon prehaps by passing a option to STRSTR to make it case sensitive ... ok it now returns a -1 or the position and the modification sugested has been made.

i dont have a disclaimer on file and should it be required i am more than willing to comply ...

By: Michael Jerris (mikej) 2005-06-04 05:27:18

A disclaimer will definately be necessary for this.  Details can be found in news on the homepage of the site.

By: Tilghman Lesher (tilghman) 2005-06-04 10:01:26

irroot:  it's actually pretty easy to modify the behavior based upon the function name, because the function name is passed as an argument (char *cmd) to the underlying C function:

if (!strcmp(cmd, "STRSTR") {
   strpos = strstr(argv[1], argv[0]);
} else {
   strpos = strcasestr(argv[1], argv[0]);

By: Gregory Hinton Nietsky (irroot) 2005-06-05 02:56:15

i was thinking along the lines of simplifying function namespace as many of the users are not C litirate ... it might make sense to us to wrap C functions and expose them in the dial plan the target users might prefer a reduced namespace ... and by passing say a i option to allow this might be more correct as this is the way other apps and functions operate.

either approach is simple but what is the more correct asterisk way ??

By: Kevin P. Fleming (kpfleming) 2005-06-05 10:31:59

I'd much prefer to see separate function names, rather than an extra argument.

By: Michael Jerris (mikej) 2005-06-23 06:37:19

irroot, we need updated patch and confirmation of disclaimer for this to move forward please.

By: Michael Jerris (mikej) 2005-06-23 14:27:47

Suspended pending disclaimer and updated patch.  Please re-open when these are ready.