lpmoo-1.2/etc/
lpmoo-1.2/mudlib/
lpmoo-1.2/mudlib/etc/
lpmoo-1.2/mudlib/include/
lpmoo-1.2/mudlib/include/moo/
lpmoo-1.2/mudlib/lpc/
lpmoo-1.2/mudlib/std/auto/
lpmoo-1.2/mudlib/std/bfuns/
/*
 * 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];
}