/* * 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]; }