lima-1.0b5/
lima-1.0b5/driver/
lima-1.0b5/driver/ChangeLog.old/
lima-1.0b5/driver/Win32/
lima-1.0b5/driver/compat/
lima-1.0b5/driver/include/
lima-1.0b5/driver/testsuite/
lima-1.0b5/driver/testsuite/clone/
lima-1.0b5/driver/testsuite/command/
lima-1.0b5/driver/testsuite/data/
lima-1.0b5/driver/testsuite/etc/
lima-1.0b5/driver/testsuite/include/
lima-1.0b5/driver/testsuite/inherit/
lima-1.0b5/driver/testsuite/inherit/master/
lima-1.0b5/driver/testsuite/log/
lima-1.0b5/driver/testsuite/single/
lima-1.0b5/driver/testsuite/single/tests/compiler/
lima-1.0b5/driver/testsuite/single/tests/efuns/
lima-1.0b5/driver/testsuite/single/tests/operators/
lima-1.0b5/driver/testsuite/u/
lima-1.0b5/driver/tmp/
lima-1.0b5/etc/
lima-1.0b5/lib/WWW/help/
lima-1.0b5/lib/cmds/
lima-1.0b5/lib/cmds/create/
lima-1.0b5/lib/cmds/player/attic/
lima-1.0b5/lib/contrib/bboard/
lima-1.0b5/lib/contrib/boards/
lima-1.0b5/lib/contrib/marriage/
lima-1.0b5/lib/contrib/roommaker/
lima-1.0b5/lib/contrib/transient_effect/
lima-1.0b5/lib/daemons/channel/
lima-1.0b5/lib/daemons/imud/
lima-1.0b5/lib/data/
lima-1.0b5/lib/data/config/
lima-1.0b5/lib/data/links/
lima-1.0b5/lib/data/news/
lima-1.0b5/lib/data/players/
lima-1.0b5/lib/data/secure/
lima-1.0b5/lib/domains/
lima-1.0b5/lib/domains/std/2.4.5/maze1/
lima-1.0b5/lib/domains/std/2.4.5/npc/
lima-1.0b5/lib/domains/std/2.4.5/post_dir/
lima-1.0b5/lib/domains/std/2.4.5/sub/
lima-1.0b5/lib/domains/std/camera/
lima-1.0b5/lib/domains/std/config/
lima-1.0b5/lib/domains/std/cult/
lima-1.0b5/lib/domains/std/effects/
lima-1.0b5/lib/domains/std/misc/
lima-1.0b5/lib/domains/std/monsters/
lima-1.0b5/lib/domains/std/recorder/
lima-1.0b5/lib/domains/std/rooms/
lima-1.0b5/lib/domains/std/rooms/beach/
lima-1.0b5/lib/domains/std/rooms/labyrinth/
lima-1.0b5/lib/domains/std/school/
lima-1.0b5/lib/domains/std/school/O/
lima-1.0b5/lib/domains/std/spells/
lima-1.0b5/lib/domains/std/spells/stock-mage/
lima-1.0b5/lib/domains/std/spells/stock-priest/
lima-1.0b5/lib/help/
lima-1.0b5/lib/help/admin/
lima-1.0b5/lib/help/hints/General_Questions/
lima-1.0b5/lib/help/hints/Pirate_Quest/
lima-1.0b5/lib/help/player/
lima-1.0b5/lib/help/player/bin/
lima-1.0b5/lib/help/player/quests/
lima-1.0b5/lib/help/wizard/
lima-1.0b5/lib/help/wizard/coding/guilds/
lima-1.0b5/lib/help/wizard/coding/rooms/
lima-1.0b5/lib/help/wizard/lib/daemons/
lima-1.0b5/lib/help/wizard/lib/lfun/
lima-1.0b5/lib/help/wizard/lib/std/
lima-1.0b5/lib/help/wizard/mudos_doc/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/interactive/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/parsing/
lima-1.0b5/lib/help/wizard/mudos_doc/concepts/
lima-1.0b5/lib/help/wizard/mudos_doc/driver/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/arrays/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/buffers/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/compile/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/filesystem/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/floats/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/functions/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/general/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/mappings/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/mixed/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/numbers/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/parsing/
lima-1.0b5/lib/help/wizard/mudos_doc/lpc/constructs/
lima-1.0b5/lib/help/wizard/mudos_doc/lpc/types/
lima-1.0b5/lib/include/driver/
lima-1.0b5/lib/log/
lima-1.0b5/lib/obj/admtool/
lima-1.0b5/lib/obj/admtool/internal/
lima-1.0b5/lib/obj/admtool/mudinfo/
lima-1.0b5/lib/obj/admtool/secure/
lima-1.0b5/lib/obj/secure/
lima-1.0b5/lib/obj/secure/cmd/
lima-1.0b5/lib/obj/secure/mailers/
lima-1.0b5/lib/obj/secure/shell/
lima-1.0b5/lib/obj/secure/shell/classes/
lima-1.0b5/lib/obj/tasktool/
lima-1.0b5/lib/obj/tasktool/internal/
lima-1.0b5/lib/open/
lima-1.0b5/lib/secure/
lima-1.0b5/lib/secure/cgi/
lima-1.0b5/lib/secure/modules/
lima-1.0b5/lib/secure/simul_efun/
lima-1.0b5/lib/std/adversary/
lima-1.0b5/lib/std/adversary/advancement/
lima-1.0b5/lib/std/adversary/armor/
lima-1.0b5/lib/std/adversary/blows/
lima-1.0b5/lib/std/adversary/death/
lima-1.0b5/lib/std/adversary/formula/
lima-1.0b5/lib/std/adversary/health/
lima-1.0b5/lib/std/adversary/pulse/
lima-1.0b5/lib/std/adversary/wield/
lima-1.0b5/lib/std/classes/event_info/
lima-1.0b5/lib/std/container/
lima-1.0b5/lib/std/living/
lima-1.0b5/lib/std/modules/contrib/
lima-1.0b5/lib/std/patterns/
lima-1.0b5/lib/std/race/
lima-1.0b5/lib/std/race/restricted/
lima-1.0b5/lib/std/room/
lima-1.0b5/lib/tmp/
lima-1.0b5/lib/trans/
lima-1.0b5/lib/trans/admincmds/
lima-1.0b5/lib/trans/obj/
lima-1.0b5/lib/wiz/
/* Do not remove the headers from this file! see /USAGE for more info. */

/*
** edit_ob.c
**
** Based on a text-entry facility by Rust.  
** Transformed and rewritten by Deathblade on 8/23/94 to use the
** new input system facilities.
**
** Usage:
**     new(EDIT_OB, EDIT_FILE, fname, func)
** or  new(EDIT_OB, EDIT_TEXT, text, func)
**
** "func" will be evaluated when the editing is complete.  One
** parameter will be passed, which will be zero if the editing
** was aborted for some reason.  Otherwise, it will be a single
** string specifying the file name, or an array of strings
** holding the lines of text.
*/

#include <mudlib.h>
#include <playerflags.h>
#include <edit.h>

inherit M_ACCESS;
inherit M_INPUT;

#define HEADER \
"Begin typing your text. ~q to abort, . or ** to end, ~h for help.\n"+\
"-----------------------------------------------------------------\n"

private string* buf;

private int already_editing;

private string client_fname;
private function client_func;


private string tmp_fname()
{
  return "/tmp/edit_ob." + this_user()->query_userid();
}

private string * read_strings(string fname, int messages)
{
  int size;

  size = file_size(fname);
  if ( messages )
  {
    if ( size == -2 )
      write("File is a directory. Ignoring.\n");
    else if ( size == -1 )
      write("File not found.\n");
    else if ( size == 0 )
      write("File is empty.\n");
    else
      write("Ok.\n");
  }
  if ( size <= 0 )
    return ({ });

  return explode(read_file(fname), "\n");
}

varargs private string build_string(int flag)
{
  switch (sizeof(buf))
  {
    case 0:
      return (flag & 1) ? "**No text!\n" : "";
    default:
	    if (flag & 2)
        return "[" + (sizeof(buf)-15) + " lines not displayed, please trim (~e)]\n" + implode(buf[<15..], "\n") + "\n";
/* WARNING - falls through */
    case 1..20:
      return implode(buf, "\n") + "\n";
  }
}

private void end_edit(int aborted)
{
  mixed arg;

  if ( client_fname )
  {
    rm(client_fname);

    if ( !aborted )
    {
      write_file(client_fname, build_string(1));
      arg = client_fname;
    }
  }
  else if ( !aborted )
    arg = buf;

/*
** Clear up this information before dispatching the callback.  The
** callback may want to push new modal handlers or something.
*/
  if( !already_editing && this_body() )
    this_body()->clear_flag(F_IN_EDIT);
  modal_pop();

  evaluate(client_func, arg);

  destruct();
}

private nomask void end_ed()
{
  string tmp_file;

  tmp_file = tmp_fname();
  buf = read_strings(tmp_file, 0);
  rm(tmp_file);

  write("Continue editing file.\n");
}

private void handle_escape(string str)
{
  string tmp;
  string tmp_file;

  switch ( str[1] )
  {
    case 'q':
      write("Edit aborted.\n");
      end_edit(1);
      return;

    case 'r':
      if(wizardp(this_user()))
        buf += read_strings(evaluate_path(str[3..]), 1);
      return;

    case 'w':
      if(wizardp(this_user()))
      {
        tmp = build_string();
        if(!write_file(evaluate_path(str[3..]),tmp))
          write("Unable to write to file.\n");
        else
         write("Ok.\n");
      }
      return;

    case 'h':
      write(
        "Help for editor:\n. or **\t\texit editor\n~q\t\tabort edit.\n~h\t\tthis help.\n"+
        "~e\t\tenter line by line editor.\n~p\t\tdisplay edit buffer.\n");
      if(wizardp(this_user()))
        write("~w <file>\twrite buffer to specified file.\n~r <file>\tread file into buffer.\n");
      write("\n\n");
      return;

    case 'p':
      write(build_string() + "\n");
      return;

    case 'e':
      tmp_file = tmp_fname();
      write_file(tmp_file, build_string());
      new(ED_SESSION)->begin_editing(tmp_file, !this_user()->query_privilege(),
          (: end_ed :));
      return;
  }
}

private nomask void parse_edit(mixed str)
{
  if(str == -1)
    destruct(this_object());
  if ( str[0] == '~' )
  {
    handle_escape(str);
    return;
  }

  if ( str == "." || str == "**" )
  {
    end_edit(0);
    return;
  }

  buf += ({ str });
}

private void begin_edit(string *text, function continuation)
{
  if(this_body())
  {
    if ( this_body()->test_flag(F_IN_EDIT) )
    {
      already_editing = 1;
      write("Warning! You are already marked as editing.\n");
    }
    else
      this_body()->set_flag(F_IN_EDIT);
  }
  buf = text ? text : ({ });
  client_func = continuation;

  write(HEADER + build_string(2));
  modal_push((: parse_edit :), "");	/* empty prompt */
}


void create(int kind, mixed text, function continuation)
{
  set_privilege(1);

  switch ( kind )
  {
    case 0:	// blueprint
      return;

    case EDIT_TEXT:
      if ( stringp(text) )
	      text = explode(text, "\n");
      break;

    case EDIT_FILE:
      client_fname = text;
      text = read_strings(text, 0);
      break;

    default:
      error("Bad argument 2 to new(EDIT_OB, ...)\n");
  }

  begin_edit(text, continuation);
}