/*
* string.c
*
* Some handy string functions
*
* (C) Frank Schmidt, Jesus@NorseMUD
*
*/
/* capitalize first letter in a string */
static string capitalize(string str) {
if (str[0] >= 'a' && str[0] <= 'z')
str[0] += 'A' - 'a';
return str;
}
/* lowercase first letter in a string */
static string decapitalize(string str) {
if (str[0] >= 'A' && str[0] <= 'Z')
str[0] += 'a' - 'A';
return str;
}
/* capitalize all letters in a string */
static string toupper(string str) {
int i, diff;
diff = 'A' - 'a';
for (i=strlen(str); --i>=0; )
if (str[i] >= 'a' && str[i] <= 'z')
str[i] += diff;
return str;
}
/* lowercase all letters in a string */
static string tolower(string str) {
int i, diff;
diff = 'a' - 'A';
for (i=strlen(str); --i>=0; )
if (str[i] >= 'A' && str[i] <= 'Z')
str[i] += diff;
return str;
}
/* extract a substring from a string,
accepts negative values and out of bounds
*/
static string extract_string(string str, int from, int to) {
int sz;
sz = strlen(str);
if (to < 0)
to = sz+to;
else if (to >= sz)
to = sz-1;
if (to < from || from >= sz)
return "";
if (from <= 0) return str[..to];
return str[from..to];
}
/* nifty function that returns all but the part you specify,
accepts negative values and out of bounds
*/
static string exclude_string(string str, int from, int to) {
string fore;
int sz;
sz = strlen(str);
if (to < 0)
to = sz+to;
else if (to >= sz)
to = sz-1;
if (to < from || from >= sz)
return str;
if (from > 0)
fore = str[..from-1];
else
fore = "";
if (to >= sz-1) return fore;
return fore + str[to+1..];
}
/* inserts string into a string safely,
accepts out of bounds values
*/
static string insert_string(string str, string what, int where) {
if (where <= 0)
return what + str;
if (where >= strlen(str))
return str + what;
return str[..where-1] + what + str[where..];
}
/* compare if <one> is a part of <two> (common one way)
*/
static int strcocmp(string one, string two) {
int sz1;
sz1 = strlen(one);
if (sz1 <= strlen(two)) {
if (sz1 > 0)
return one == two[..sz1-1];
}
return 0;
}
/* compare if <one> or <two> is a part of one another (both ways) */
static int strccmp(string one, string two) {
int sz1, sz2;
sz1 = strlen(one);
sz2 = strlen(two);
if (sz1 < sz2) {
if (sz1 > 0)
return one == two[..sz1-1];
}
else {
if (sz2 > 0)
return two == one[..sz2-1];
}
return 0;
}
/* compare two strings lexically */
static int strcmp(string one, string two) {
int sz1, sz2, size, i;
sz1 = strlen(one);
sz2 = strlen(two);
size = min(sz1, sz2);
/* compare each element until difference is found */
for (; i < size; ++i) {
int o, t;
if ((o=one[i]) > (t=two[i]))
return 1;
else if (o < t)
return -1;
}
/* decide final relationship */
if (sz1 > sz2) return 1;
if (sz1 < sz2) return -1;
return 0;
}
/* search for a string within a string at occurence <num>
accepts negative number
*/
#if 1
/* FAST VERSION */
static varargs int strsrch(string str1, string str2, int num) {
if (num >= 0) {
string t;
int i, s2len;
s2len = strlen(str2);
i = -s2len;
do {
/* using sscanf is fast from the left */
if (sscanf(str1, "%s"+str2+"%s", t, str1) >= 1) {
i += strlen(t)+s2len;
if (!str1) str1 = "";
}
else
return -1;
} while (num-- > 0);
return i;
}
else {
int sz;
mixed *expl;
if ((sz=::sizeof(expl = big_explode(str1, str2))) > -num) {
/* use implode() to avoid counting length of first separator */
return strlen(implode(expl[..sz+num-1], str2));
}
}
return -1;
}
#else
/* SLOW VERSION */
static varargs int strsrch(string str1, mixed str2, int num) {
int i, sz1, sz2;
if (num >= 0) {
/* scan from forwards */
if (stringp(str2)) {
sz2 = strlen(str2)-1;
sz1 = strlen(str1)-sz2;
do {
for (; i < sz1; ++i)
if (str1[i..i+sz2] == str2)
/* found a match */
break;
} while (num-- > 0);
}
else {
/* scan for character */
sz1 = strlen(str1);
do {
for (; i < sz1; ++i)
if (str1[i] == str2)
/* found a match */
break;
} while (num-- > 0);
}
/* return final index */
if (i < sz1) return i;
return -1;
}
else {
/* scan backwards */
if (stringp(str2)) {
sz2 = strlen(str2)-1;
i = strlen(str1)-sz2;
do {
while (--i >= 0)
if (str1[i..i+sz2] == str2)
/* found a match */
break;
} while (++num < 0);
}
else {
/* scan for character */
i=strlen(str1);
do {
while (--i >= 0)
if (str1[i] == str2)
/* found a match */
break;
} while (++num < 0);
}
return i;
}
/* should never make it here, but who cares? */
return -1;
}
#endif
/* replace patterns within a string, optional <max> occurences from left or right
accepts negative number, defaults to replacing ALL occurences
*/
static varargs string replace_string(string str, mixed patt, string repl, int max) {
if (max == 0) {
/* replace ALL (fastest) */
return big_implode(big_explode(str, patt), repl);
}
else {
int sz;
string *expl;
/* replace n occurences from left (positive <max>) or right (negative <max>) */
sz = ::sizeof(expl = big_explode(str, patt));
if (max >= 0) {
if (max < sz)
/* from left (concatenating with implode() using ({""}) as bridge) */
return implode(expl[..max-1]+({""}), repl)+implode(expl[max..], patt);
}
else if (max > -sz) {
/* from right (concatenating with implode() using ({""}) as bridge) */
return implode(expl[..sz+max-1], patt)+implode(({""})+expl[sz+max..], repl);
}
/* replacing all anyways, since max is bigger than occurences found */
return big_implode(expl, repl);
}
}
/* return a string filled with <fyll> with length of <n> */
static string fill_string(string fyll, int n) {
int i;
if (n <= 0 || !(i=strlen(fyll)))
return "";
/* expand fillstring until it gets big enough */
while (i < n) {
fyll += fyll;
fyll += fyll;
i += i;
}
return fyll[..n-1];
}
/* strip string for whitespaces */
static varargs string strip_string(string raw, string whitespace) {
string *words;
/* default whitespace */
if (!whitespace)
whitespace = " ";
/* get rid of nasty spaces between each word and at ends of string */
return implode(explode(raw,whitespace)-({""}), whitespace);
}
#ifndef atoi
/* convert a string to an integer */
static int atoi(string str) {
return (int)str;
}
#endif
#ifndef atof
/* convert a string to a float */
static float atof(string str) {
return (float)str;
}
#endif
/* return a visual string representation for a float (approximate) */
static string float2str(float flt) {
string str;
int i, c;
str = (string) flt;
if (strsrch(str, ".") >= 0 || strsrch(str, "e") >= 0)
return str;
return str + ".0";
}