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:	extrafuns.c
 * DESCRIPTION:	special LPMOO builtins
 */

# ifdef FUNCDEF
FUNCDEF(0, "toliteral", 1, 2)
# else

/*
 * NAME:	bfun->toliteral()
 * DESCRIPTION:	convert argument into a literal string
 */
varargs
MOOVAL b_toliteral(mixed *info, MOOVAL arg1, MOOVAL etc...)
{
  return STR(moo2str(arg1, sizeof(etc) ? TRUTHOF(etc[0]) : 1));
}
# endif

# ifdef FUNCDEF
FUNCDEF(0, "fromliteral", 1, 1)
# else

/*
 * NAME:	bfun->fromliteral()
 * DESCRIPTION:	convert a literal string to a MOO value
 */
varargs
MOOVAL b_fromliteral(mixed *info, MOOVAL arg)
{
  MOOVAL result;

  ASSERT(arg, STR);

  return str2moo(STRVAL(arg));
}
# endif

# ifdef FUNCDEF
FUNCDEF(0, "tofloat", 1, 1)
# else

/*
 * NAME:	bfun->tofloat()
 * DESCRIPTION:	convert argument to a float
 */
varargs
MOOVAL b_tofloat(mixed *info, MOOVAL arg)
{
  switch (TYPEOF(arg))
    {
    case T_NUM:
      return FLT((float) NUMVAL(arg));

    case T_STR:
      {
	string str;
	float flt;
	int i, sz;

	/* this is unnecessarily complex, but mocks
	   the behavior of tonum() and toobj() */

	sz = strlen(str = STRVAL(arg));
	while (i < sz && (str[i] == ' ' || str[i] == '\t'))
	  ++i;
	sscanf(str[i ..], "%f%s", flt, str);
	i = 0, sz = strlen(str);
	while (i < sz && (str[i] == ' ' || str[i] == '\t'))
	  ++i;

	if (i < sz)
	  return FLT(0.0);
	else
	  return FLT(flt);
      }

    case T_FLT:
      return arg;

    case T_OBJ:
      return FLT((float) OBJVAL(arg));

    case T_ERR:
      return FLT((float) ERRVAL(arg));

    default:
      return RAISE(E_TYPE);
    }
}
# endif

/* floating point support */

# ifdef FUNCDEF
FUNCDEF(0, "floor", 1, 1)
# else

/*
 * NAME:	bfun->floor()
 * DESCRIPTION:	round to minus infinity
 */
varargs
MOOVAL b_floor(mixed *info, MOOVAL arg)
{
  float x;

  if (NUMP(arg))
    x = (float) NUMVAL(arg);
  else
    {
      ASSERT(arg, FLT);
      x = FLTVAL(arg);
    }

  return FLT(floor(x));
}
# endif

# ifdef FUNCDEF
FUNCDEF(0, "ceil", 1, 1)
# else

/*
 * NAME:	bfun->ceil()
 * DESCRIPTION:	round to plus infinity
 */
varargs
MOOVAL b_ceil(mixed *info, MOOVAL arg)
{
  float x;

  if (NUMP(arg))
    x = (float) NUMVAL(arg);
  else
    {
      ASSERT(arg, FLT);
      x = FLTVAL(arg);
    }

  return FLT(ceil(x));
}
# endif

# ifdef FUNCDEF
FUNCDEF(0, "frexp", 1, 1)
# else

/*
 * NAME:	bfun->frexp()
 * DESCRIPTION:	split floating point value
 */
varargs
MOOVAL b_frexp(mixed *info, MOOVAL arg)
{
  float x;

  if (NUMP(arg))
    x = (float) NUMVAL(arg);
  else
    {
      ASSERT(arg, FLT);
      x = FLTVAL(arg);
    }

  /* same representation */
  return LST(frexp(x));
}
# endif

# ifdef FUNCDEF
FUNCDEF(0, "ldexp", 2, 2)
# else

/*
 * NAME:	bfun->ldexp()
 * DESCRIPTION:	rejoin floating point value
 */
varargs
MOOVAL b_ldexp(mixed *info, MOOVAL arg1, MOOVAL arg2)
{
  float flt, x;

  if (NUMP(arg1))
    x = (float) NUMVAL(arg1);
  else
    {
      ASSERT(arg1, FLT);
      x = FLTVAL(arg1);
    }
  ASSERT(arg2, NUM);

  return catch(flt = ldexp(x, NUMVAL(arg2))) ? RAISE(E_OVERFL) : FLT(flt);
}
# endif

# ifdef FUNCDEF
FUNCDEF(0, "modf", 1, 1)
# else

/*
 * NAME:	bfun->modf()
 * DESCRIPTION:	split floating point value
 */
varargs
MOOVAL b_modf(mixed *info, MOOVAL arg)
{
  float x;

  if (NUMP(arg))
    x = (float) NUMVAL(arg);
  else
    {
      ASSERT(arg, FLT);
      x = FLTVAL(arg);
    }

  /* same representation */
  return LST(modf(x));
}
# endif

# ifdef FUNCDEF
FUNCDEF(0, "exp", 1, 1)
# else

/*
 * NAME:	bfun->exp()
 * DESCRIPTION:	compute exponentiation
 */
varargs
MOOVAL b_exp(mixed *info, MOOVAL arg)
{
  float flt, x;

  if (NUMP(arg))
    x = (float) NUMVAL(arg);
  else
    {
      ASSERT(arg, FLT);
      x = FLTVAL(arg);
    }

  switch (catch(flt = exp(x)))
    {
    case 0:
      return FLT(flt);
    case "Result too large":
      return RAISE(E_OVERFL);
    default:
      return RAISE(E_INVARG);
    }
}
# endif

# ifdef FUNCDEF
FUNCDEF(0, "log", 1, 1)
# else

/*
 * NAME:	bfun->log()
 * DESCRIPTION:	compute natural logarithm
 */
varargs
MOOVAL b_log(mixed *info, MOOVAL arg)
{
  float flt, x;

  if (NUMP(arg))
    x = (float) NUMVAL(arg);
  else
    {
      ASSERT(arg, FLT);
      x = FLTVAL(arg);
    }

  switch (catch(flt = log(x)))
    {
    case 0:
      return FLT(flt);
    case "Result too large":
      return RAISE(E_OVERFL);
    default:
      return RAISE(E_INVARG);
    }
}
# endif

# ifdef FUNCDEF
FUNCDEF(0, "log10", 1, 1)
# else

/*
 * NAME:	bfun->log10()
 * DESCRIPTION:	computer logarithm base 10
 */
varargs
MOOVAL b_log10(mixed *info, MOOVAL arg)
{
  float flt, x;

  if (NUMP(arg))
    x = (float) NUMVAL(arg);
  else
    {
      ASSERT(arg, FLT);
      x = FLTVAL(arg);
    }

  switch (catch(flt = log10(x)))
    {
    case 0:
      return FLT(flt);
    case "Result too large":
      return RAISE(E_OVERFL);
    default:
      return RAISE(E_INVARG);
    }
}
# endif

# ifdef FUNCDEF
FUNCDEF(0, "pow", 2, 2)
# else

/*
 * NAME:	bfun->pow()
 * DESCRIPTION:	compute exponential power
 */
varargs
MOOVAL b_pow(mixed *info, MOOVAL arg1, MOOVAL arg2)
{
  float x, y, flt;

  if (NUMP(arg1))
    x = (float) NUMVAL(arg1);
  else
    {
      ASSERT(arg1, FLT);
      x = FLTVAL(arg1);
    }

  if (NUMP(arg2))
    y = (float) NUMVAL(arg2);
  else
    {
      ASSERT(arg2, FLT);
      y = FLTVAL(arg2);
    }

  if (y == 0.0)
    return FLT(1.0);
  if (x == 0.0)
    return FLT(0.0);

  switch (catch(flt = exp(log(x) * y)))
    {
    case 0:
      return FLT(flt);
    case "Result too large":
      return RAISE(E_OVERFL);
    default:
      return RAISE(E_INVARG);
    }
}
# endif

# ifdef FUNCDEF
FUNCDEF(0, "sin", 1, 1)
# else

/*
 * NAME:	bfun->sin()
 * DESCRIPTION:	compute sine
 */
varargs
MOOVAL b_sin(mixed *info, MOOVAL arg)
{
  float x;

  if (NUMP(arg))
    x = (float) NUMVAL(arg);
  else
    {
      ASSERT(arg, FLT);
      x = FLTVAL(arg);
    }

  return FLT(sin(x));
}
# endif

# ifdef FUNCDEF
FUNCDEF(0, "cos", 1, 1)
# else

/*
 * NAME:	bfun->cos()
 * DESCRIPTION:	compute cosine
 */
varargs
MOOVAL b_cos(mixed *info, MOOVAL arg)
{
  float x;

  if (NUMP(arg))
    x = (float) NUMVAL(arg);
  else
    {
      ASSERT(arg, FLT);
      x = FLTVAL(arg);
    }

  return FLT(cos(x));
}
# endif

# ifdef FUNCDEF
FUNCDEF(0, "tan", 1, 1)
# else

/*
 * NAME:	bfun->tan()
 * DESCRIPTION:	compute tangent
 */
varargs
MOOVAL b_tan(mixed *info, MOOVAL arg)
{
  float x;

  if (NUMP(arg))
    x = (float) NUMVAL(arg);
  else
    {
      ASSERT(arg, FLT);
      x = FLTVAL(arg);
    }

  return FLT(tan(x));
}
# endif

# ifdef FUNCDEF
FUNCDEF(0, "atan", 1, 1)
# else

/*
 * NAME:	bfun->atan()
 * DESCRIPTION:	compute arctangent
 */
varargs
MOOVAL b_atan(mixed *info, MOOVAL arg)
{
  float x;

  if (NUMP(arg))
    x = (float) NUMVAL(arg);
  else
    {
      ASSERT(arg, FLT);
      x = FLTVAL(arg);
    }

  return FLT(atan(x));
}
# endif

/* table support */

# ifdef FUNCDEF
FUNCDEF(0, "tablemap", 2, 2)
# else

/*
 * NAME:	bfun->tablemap()
 * DESCRIPTION:	create a table
 */
varargs
MOOVAL b_tablemap(mixed *info, MOOVAL arg1, MOOVAL arg2)
{
  mapping map;
  MOOVAL *list1, *list2;
  int i;

  ASSERT(arg1, LST);
  ASSERT(arg2, LST);

  list1 = LSTVAL(arg1);
  list2 = LSTVAL(arg2);

  if ((i = sizeof(list1)) != sizeof(list2))
    return RAISE(E_INVARG);

  map = TNEW();

  while (i--)
    TINSERT(map, list1[i], list2[i]);

  return TBL(map);
}
# endif

# ifdef FUNCDEF
FUNCDEF(0, "tableinsert", 3, 3)
# else

/*
 * NAME:	bfun->tableinsert()
 * DESCRIPTION:	insert a new item into a table
 */
varargs
MOOVAL b_tableinsert(mixed *info, MOOVAL arg1, MOOVAL arg2, MOOVAL arg3)
{
  mapping table;

  ASSERT(arg1, TBL);

  TINSERT(table = TBLVAL(arg1) + TNEW(), arg2, arg3);

  return TBL(table);
}
# endif

# ifdef FUNCDEF
FUNCDEF(0, "tabledelete", 2, 2)
# else

/*
 * NAME:	bfun->tabledelete()
 * DESCRIPTION:	delete an item from a table
 */
varargs
MOOVAL b_tabledelete(mixed *info, MOOVAL arg1, MOOVAL arg2)
{
  mapping table;

  ASSERT(arg1, TBL);

  TDELETE(table = TBLVAL(arg1) + TNEW(), arg2);

  return TBL(table);
}
# endif

# ifdef FUNCDEF
FUNCDEF(0, "tablekeys", 1, 1)
# else

/*
 * NAME:	bfun->tablekeys()
 * DESCRIPTION:	return the keys of a table
 */
varargs
MOOVAL b_tablekeys(mixed *info, MOOVAL arg)
{
  ASSERT(arg, TBL);

  return TKEYS(TBLVAL(arg));
}
# endif

# ifdef FUNCDEF
FUNCDEF(0, "tablevalues", 1, 1)
# else

/*
 * NAME:	bfun->tablevalues()
 * DESCRIPTION:	return the values of a table
 */
varargs
MOOVAL b_tablevalues(mixed *info, MOOVAL arg)
{
  ASSERT(arg, TBL);

  return TVALUES(TBLVAL(arg));
}
# endif

/* buffer support */

# ifdef FUNCDEF
FUNCDEF(0, "tobuf", 0, -1)
# else

/*
 * NAME:	bfun->tobuf()
 * DESCRIPTION:	convert to a buffer value
 */
varargs
MOOVAL b_tobuf(mixed *info, MOOVAL args...)
{
  MOOVAL arg;
  string buf, c;
  int i, sz;

  buf = "";
  c   = "x";

  for (i = 0, sz = sizeof(args); i < sz; ++i)
    {
      switch (TYPEOF(arg = args[i]))
	{
	case T_NUM:
	  c[0] = NUMVAL(arg);
	  buf += c;
	  break;

	case T_STR:
	  buf += STRVAL(arg);
	  break;

	case T_BUF:
	  buf += BUFVAL(arg);
	  break;

	default:
	  return RAISE(E_TYPE);
	}
    }

  return BUF(buf);
}
# endif

/* multiple-port listening support */

# ifdef FUNCDEF
FUNCDEF(0, "listen", 1, 3)
# else

/*
 * NAME:	bfun->listen()
 * DESCRIPTION:	open a network port
 */
varargs
MOOVAL b_listen(mixed *info, MOOVAL arg, MOOVAL etc...)
{
  MOOVAL obj;
  object ob;
  int result;
  string protocol;

  if (sizeof(etc))
    obj = etc[0];
  else
    obj = OBJ(0);

  if (OBJP(arg))  /* backwards compatibility */
    {
      MOOVAL tmp;

      tmp = arg;
      arg = obj;
      obj = tmp;
    }

  ASSERT(arg, NUM);
  ASSERT(obj, OBJ);

  if (sizeof(etc) > 1)
    {
      ASSERT(etc[1], STR);
      switch (tolower(STRVAL(etc[1])))
	{
	case "telnet":
	  protocol = "telnet";
	  break;
	case "binary":
	  protocol = "tcp";
	  break;
	default:
	  return RAISE(E_INVARG);
	}
    }
  else
    protocol = "tcp";

  if (! WIZARDP(info) ||
      ! DRIVER->query_net() ||
      ! CONFIG->query(CF_MPORT_LISTENING))
    return RAISE(E_PERM);

  GET_VALID_OBJ(ob, OBJVAL(obj));

  result = DRIVER->listen(ob, NUMVAL(arg), protocol);
  return (result == E_NONE) ? NUM(0) : RAISE(result);
}
# endif

# ifdef FUNCDEF
FUNCDEF(0, "unlisten", 1, 1)
# else

/*
 * NAME:	bfun->unlisten()
 * DESCRIPTION:	stop listening on a network port
 */
varargs
MOOVAL b_unlisten(mixed *info, MOOVAL arg)
{
  int result;

  ASSERT(arg, NUM);

  if (! WIZARDP(info) ||
      ! DRIVER->query_net() ||
      ! CONFIG->query(CF_MPORT_LISTENING))
    return RAISE(E_PERM);

  result = DRIVER->unlisten(NUMVAL(arg));
  return (result == E_NONE) ? NUM(0) : RAISE(result);
}
# endif

/* miscellaneous proprietary functions below */