/*
* NAME: eefun.c
* DESCRIPTION: extended efuns
*/
# include <dgd/float.h>
/*
* NAME: flt2str()
* DESCRIPTION: return a visual string representation for a float (approximate)
*/
static
string flt2str(float flt)
{
string str;
int i, c;
str = (string) flt;
for (i = strlen(str); i--; )
if ((c = str[i]) == '.' || c == 'e')
return str;
return str + ".0";
}
/*
* NAME: flt2internal()
* DESCRIPTION: return a precise string representation for a float
*/
static
string flt2internal(float flt)
{
mixed *split;
float mant;
int exp, v1, v2;
split = frexp(flt);
mant = split[0];
exp = split[1];
mant = ldexp(mant, FLT_MANT_DIG + 1);
v1 = (int) (mant / 65536.0);
v2 = (int) (mant - (float) v1 * 65536.0);
return (string) v1 + "/" + (string) v2 + "/" + (string) exp;
}
/*
* NAME: internal2flt()
* DESCRIPTION: perform inverse of flt2internal()
*/
static
float internal2flt(string data)
{
int v1, v2, exp;
if (sscanf(data, "%d/%d/%d", v1, v2, exp) != 3)
error("Invalid argument");
return ldexp((float) v1 * 65536.0 + (float) v2, exp - FLT_MANT_DIG - 1);
}
/*
* NAME: atoi()
* DESCRIPTION: convert a string to an integer
*/
static
int atoi(string str)
{
int i;
if (str && sscanf(str, "%d", i) == 1)
return i;
else
return 0;
}
/*
* NAME: flatten_array()
* DESCRIPTION: return a flat array given a nested array
*/
static
mixed *flatten_array(mixed *arr)
{
mixed *new_arr;
int i, sz;
new_arr = ({ });
for (i = 0, sz = sizeof(arr); i < sz; ++i) {
mixed elt;
elt = arr[i];
if (arrayp(elt))
new_arr += flatten_array(elt);
else
new_arr += ({ elt });
}
return new_arr;
}
/*
* NAME: shallow_copy()
* DESCRIPTION: return a new value which is a copy of another
*/
static
mixed shallow_copy(mixed arg)
{
switch (typeof(arg))
{
case T_ARRAY:
return arg + ({ });
case T_MAPPING:
return arg + ([ ]);
default:
return arg;
}
}
/*
* NAME: deepen_shallow_copy()
* DESCRIPTION: replace elements of a complex type with copies
*/
static
mixed deepen_shallow_copy(mixed arg)
{
int i, sz;
mixed *keys, *values;
switch (typeof(arg))
{
case T_ARRAY:
for (i = 0, sz = sizeof(arg); i < sz; ++i)
arg[i] = deepen_shallow_copy(shallow_copy(arg[i]));
return arg;
case T_MAPPING:
keys = map_indices(arg);
values = map_values(arg);
for (i = 0, sz = sizeof(keys); i < sz; ++i)
arg[keys[i]] = deepen_shallow_copy(shallow_copy(values[i]));
return arg;
default:
return arg;
}
}
/*
* NAME: deep_copy()
* DESCRIPTION: return a recursive copy of a value
*/
static
mixed deep_copy(mixed arg)
{ return deepen_shallow_copy(shallow_copy(arg)); }
/*
* NAME: base_object()
* DESCRIPTION: return the name of the master object for a clone
*/
static
varargs string base_object(object ob)
{
string name, base;
int id;
if (ob == 0)
ob = this_object();
name = object_name(ob);
if (sscanf(name, "%s#%d", base, id) == 2)
return base;
return name;
}
/*
* NAME: dir_name()
* DESCRIPTION: return the directory portion of a pathname
*/
static
string dir_name(string file)
{
string *path;
int sz;
if (file == 0)
return 0;
path = explode(file, "/");
sz = strlen(file);
if (sz > 0 && file[0] == '/')
path = ({ "" }) + path;
if (sz > 1 && file[sz - 1] == '/')
path += ({ "" });
sz = sizeof(path);
file = implode((sz > 1) ? path[0 .. sz - 2] :
(sz > 0) ? ({ "." }) : ({ }), "/");
return (file == "" ? "/" : file);
}
/*
* NAME: base_name()
* DESCRIPTION: return the filename portion of a pathname
*/
static
string base_name(string file)
{
string *path;
int sz;
if (file == 0)
return 0;
path = explode(file, "/");
sz = strlen(file);
if (sz > 0 && file[sz - 1] == '/')
path += ({ "" });
sz = sizeof(path);
return((sz > 0) ? path[sz - 1] : "");
}
/*
* NAME: file_size()
* DESCRIPTION: return just the size of a file
*/
static
int file_size(string file)
{
int *stats;
if (file == 0)
return -1;
stats = get_dir(file)[1];
if (sizeof(stats) != 1)
return -1;
return stats[0];
}
/*
* NAME: assert_dir()
* DESCRIPTION: create the specified directory, including any needed parents
*/
static
int assert_dir(string dir)
{
int sz;
if (dir == 0)
return 0;
if (dir == "/")
return 1;
sz = file_size(dir);
if (sz == -2)
return 1;
if (sz != -1)
return 0;
return (make_dir(dir) ||
(assert_dir(dir_name(dir)) && make_dir(dir)));
}
/*
* NAME: file_stat()
* DESCRIPTION: return the last modification time of a file
*/
static
int file_stat(string file)
{
int *stats;
if (file == 0)
return -1;
stats = get_dir(file)[2];
if (sizeof(stats) != 1)
return -1;
return stats[0];
}