GmOcean - Oct 15, 2014 11:52
I was recently trying to make a universal sprintf type function utilizing replacestr command, and found that it wasn't working properly. Namely, the " count " argument wasn't working properly, rather at all.[code=auto:0]
//===============================================================
// replacestr <input>, <search>, <replace>{, <usecase>{, <count>}}
//
// Note: Finds all instances of <search> in <input> and replaces
// with <replace>. If specified will only replace as many
// instances as specified in <count>. By default will be case
// sensitive.
//---------------------------------------------------------------
BUILDIN(replacestr)
{
const char *input = script_getstr(st, 2);
const char *find = script_getstr(st, 3);
const char *replace = script_getstr(st, 4);
size_t inputlen = strlen(input);
size_t findlen = strlen(find);
struct StringBuf output;
bool usecase = true;
int count = 0;
int numFinds = 0;
int i = 0, f = 0;
if(findlen == 0) {
ShowError("script:replacestr: Invalid search length.\n");
st->state = END;
return false;
}
if(script_hasdata(st, 5)) {
if( script_isinttype(st,5) ) {
usecase = script_getnum(st, 5) != 0;
} else {
ShowError("script:replacestr: Invalid usecase value. Expected int.\n");
st->state = END;
return false;
}
}
if(script_hasdata(st, 6)) {
if (!script_isinttype(st, 5) || (count = script_getnum(st, 6) == 0)) {
ShowError("script:replacestr: Invalid count value. Expected int.\n");
st->state = END;
return false;
}
}
StrBuf->Init(&output);
for(; i < inputlen; i++) {
if(count && count == numFinds) {
break; //found enough, stop looking
}
for(f = 0; f <= findlen; f++) {
if(f == findlen) { //complete match
numFinds++;
StrBuf->AppendStr(&output, replace);
i += findlen - 1;
break;
} else {
if(usecase) {
if((i + f) > inputlen || input[i + f] != find[f]) {
StrBuf->Printf(&output, "%c", input[i]);
break;
}
} else {
if(((i + f) > inputlen || input[i + f] != find[f]) && TOUPPER(input[i+f]) != TOUPPER(find[f])) {
StrBuf->Printf(&output, "%c", input[i]);
break;
}
}
}
}
}
//append excess after enough found
if(i < inputlen)
StrBuf->AppendStr(&output, &(input[i]));
script_pushstrcopy(st, StrBuf->Value(&output));
StrBuf->Destroy(&output);
return true;
}
[/code]
That's a copy of the src from the master revision on github. And even when running the example use in script_commands.txt it didn't work.
However changing this part here made it work:[code=auto:0]
if(script_hasdata(st, 6)) {
count = script_getnum(st, 6);
if (count == 0) {
ShowError("script:replacestr: Invalid count value. Expected int.\n");
st->state = END;
return false;
}
}
[/code]
This was confirmed by cross testing between rAthena and Hercules. The changes are identical to what rAthena has, and it works on their revision. After making the changes on herc, it also worked here.
Dastgir - Oct 15, 2014 13:18
Only the count doesn't work, and all else works.
Maybe a Typo:[code=:0]
if (!script_isinttype(st, 5) || (count = script_getnum(st, 6) == 0)) {
[/code]
see that [b],5[/b]
This post has been edited by
Dastgir
on Oct 15, 2014 13:22
Dastgir - Oct 15, 2014 13:58
Fixed@ [url="https://github.com/HerculesWS/Hercules/commit/6c8bafc1b0c191084a1a2aa1dc3ddcc89c928707"]https://github.com/HerculesWS/Hercules/commit/6c8bafc1b0c191084a1a2aa1dc3ddcc89c928707[/url]