foundation2_fluffos_v1/
foundation2_fluffos_v1/bin/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/ChangeLog.old/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/Win32/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/compat/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/compat/simuls/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/include/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/clone/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/command/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/data/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/etc/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/include/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/inherit/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/inherit/master/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/log/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/single/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/single/tests/compiler/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/single/tests/efuns/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/single/tests/operators/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/u/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/tmp/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/windows/
foundation2_fluffos_v1/lib/cfg/
foundation2_fluffos_v1/lib/cmds/adm/
foundation2_fluffos_v1/lib/daemon/save/
foundation2_fluffos_v1/lib/daemon/services/
foundation2_fluffos_v1/lib/daemon/soul/
foundation2_fluffos_v1/lib/doc/build/
foundation2_fluffos_v1/lib/doc/classes/
foundation2_fluffos_v1/lib/doc/driver/
foundation2_fluffos_v1/lib/doc/driver/applies/
foundation2_fluffos_v1/lib/doc/driver/applies/interactive/
foundation2_fluffos_v1/lib/doc/driver/concepts/
foundation2_fluffos_v1/lib/doc/driver/driver/
foundation2_fluffos_v1/lib/doc/driver/efuns/arrays/
foundation2_fluffos_v1/lib/doc/driver/efuns/buffers/
foundation2_fluffos_v1/lib/doc/driver/efuns/calls/
foundation2_fluffos_v1/lib/doc/driver/efuns/compile/
foundation2_fluffos_v1/lib/doc/driver/efuns/filesystem/
foundation2_fluffos_v1/lib/doc/driver/efuns/floats/
foundation2_fluffos_v1/lib/doc/driver/efuns/functions/
foundation2_fluffos_v1/lib/doc/driver/efuns/general/
foundation2_fluffos_v1/lib/doc/driver/efuns/mappings/
foundation2_fluffos_v1/lib/doc/driver/efuns/numbers/
foundation2_fluffos_v1/lib/doc/driver/efuns/parsing/
foundation2_fluffos_v1/lib/doc/driver/lpc/constructs/
foundation2_fluffos_v1/lib/doc/driver/lpc/types/
foundation2_fluffos_v1/lib/doc/driver/platforms/
foundation2_fluffos_v1/lib/doc/efun/
foundation2_fluffos_v1/lib/doc/etc/
foundation2_fluffos_v1/lib/doc/faq/
foundation2_fluffos_v1/lib/doc/help/creator/
foundation2_fluffos_v1/lib/doc/help/player/
foundation2_fluffos_v1/lib/doc/lpc/basic/
foundation2_fluffos_v1/lib/doc/lpc/data_types/
foundation2_fluffos_v1/lib/doc/lpc/etc/
foundation2_fluffos_v1/lib/doc/lpc/intermediate/
foundation2_fluffos_v1/lib/doc/lpc/types/
foundation2_fluffos_v1/lib/doc/mudlib/
foundation2_fluffos_v1/lib/doc/mudlib/Features/
foundation2_fluffos_v1/lib/domains/Examples/armour/
foundation2_fluffos_v1/lib/domains/Examples/etc/
foundation2_fluffos_v1/lib/domains/Examples/npc/
foundation2_fluffos_v1/lib/domains/Examples/room/
foundation2_fluffos_v1/lib/domains/Examples/virtual/
foundation2_fluffos_v1/lib/domains/Examples/virtual/exaA/
foundation2_fluffos_v1/lib/domains/Examples/virtual/exaB/
foundation2_fluffos_v1/lib/domains/Examples/weapon/
foundation2_fluffos_v1/lib/domains/School/doc/
foundation2_fluffos_v1/lib/domains/School/room/
foundation2_fluffos_v1/lib/domains/School/room/Classes/
foundation2_fluffos_v1/lib/domains/School/room/Offices/
foundation2_fluffos_v1/lib/domains/Standard/
foundation2_fluffos_v1/lib/domains/Standard/pools/
foundation2_fluffos_v1/lib/domains/Standard/std/
foundation2_fluffos_v1/lib/domains/Standard/xtra/
foundation2_fluffos_v1/lib/include/
foundation2_fluffos_v1/lib/lib/obj/
foundation2_fluffos_v1/lib/news/
foundation2_fluffos_v1/lib/save/
foundation2_fluffos_v1/lib/secure/cfg/
foundation2_fluffos_v1/lib/secure/cmds/player/
foundation2_fluffos_v1/lib/secure/lib/
foundation2_fluffos_v1/old/
foundation2_fluffos_v1/win32/
/*  /lib/user/more.c
    from Foundation II
    inherited player functions for paging files and string arrays
    created by Descartes of Borg 931204
*/

#include "more.h"

static private mapping More;

void create() { More = ([]); }

varargs int more(mixed what, string cl, function endmore, mixed args) {
    string *tmp;

    if(!pointerp(what) && !stringp(what))
      return notify_fail("Unknown file reference.\n");
    if(More["lines"]) More = ([]);
    if(!(More["class"] = cl)) More["class"] = "info";
    if(!(More["screen"]=to_int((string)this_object()->GetEnvVar("LINES"))))
      More["screen"] = 20;
    if(stringp(what)) {
        if(sizeof(tmp = (string *)this_object()->wild_card(what)) != 1)
          return notify_fail("Ambiguous file reference.\n");
        if(file_size(tmp[0]) < 1)
          return notify_fail("Ambiguous file reference.\n");
        More["total"] = sizeof(More["lines"] =
          explode(read_file(tmp[0]), "\n"));
    }
    else if(pointerp(what))
      More["total"] = sizeof(More["lines"] = what);
    else return notify_fail("Illegal file reference.\n");
    if(creatorp(this_object()) && tmp && tmp[0])
      message(More["class"], "--==** "+tmp[0]+" **==--", this_object());
    if(!More["total"]) {
        More = ([]);
        if( functionp(endmore) ) evaluate(endmore, args);
        return 1;
    }
    More["current"] = 0;
    if(functionp(endmore)) More["endfun"] = endmore;
    More["args"] = args;
    do_more(" ");
    return 1;
}

static void do_more(string cmd) {
    string args;
    int i, x;

    if(!cmd || cmd == "" || cmd == "\r" || cmd == "\n") cmd = " ";
    if((x = strlen(cmd)) > 1) {
        args = cmd[1..x-1];
        cmd = cmd[0..0];
    }
    switch(cmd) {
        case " ": break;
        case "b": case "B":
          More["current"] -= More["screen"]*2;
          if(More["current"] < 0) More["current"] = 0;
          break;
        case "<": More["current"] = 0; break;
        case ">": More["current"] = More["total"]-1; break;
        case "/":
          if(GetEnvVar("MORE") == "off") regexp_fwd(args);
          else input_to("regexp_fwd");
          return;
        case "?":
            if(GetEnvVar("MORE") == "off") regexp_bkwd(args);
            else input_to("regexp_bkwd");
            return;
        case "n":
          if(!More["regexp"] || More["regexp"] == "") {
            message(More["class"], "\nNo previous search.", this_object());
            if(GetEnvVar("MORE") == "off") input_to("do_more");
            else get_char("do_more");
            return;
          }
          if(More["regexp"][0] == '/')
            regexp_fwd(More["regexp"][1..strlen(More["regexp"])-1]);
          else regexp_bkwd(More["regexp"][1..strlen(More["regexp"])-1]);
          return;
        case "=":
          message(More["class"], "\nCurrent line: "+
            More["current"], this_object());
          if(GetEnvVar("MORE") == "off") input_to("do_more");
          else get_char("do_more");
          return;
        case "v": case "V":
          message(More["class"], "\nNightmare Mudlib \"more\" "+
            "version 2.1 by Descartes of Borg 931204.", this_object());
          if(GetEnvVar("MORE") == "off") input_to("do_more");
          else get_char("do_more");
          return;
        case "h": case "H":
            do_help();
            if(GetEnvVar("MORE") == "off") input_to("do_more");
            else get_char("do_more");
            return;
        case "Q": case "q":
          message(More["class"], "", this_object());
          if( functionp(More["endfun"]) )
            (*More["endfun"])(More["args"]);
          More = ([]);
          return;
        default:
          message(More["class"], "\nUnrecognized command.", this_object());
          if(GetEnvVar("MORE") == "off") input_to("do_more");
          else get_char("do_more");
          return;
    }
    message(More["class"], "", this_object());
    for(i=More["current"];
      i<More["current"] + More["screen"]; i++) {
        if(i>= More["total"]) {
          if(functionp(More["endfun"]) )
              (*More["endfun"])(More["args"]);
          More = ([]);
          return;
        }
        message(More["class"], More["lines"][i], this_object());
    }
    if((More["current"] = i) >= More["total"]) {
        if(functionp(More["endfun"]) ) 
            (*More["endfun"])(More["args"]);
        More = ([]);
        return;
    }
    More["current"] = i;
    message("prompt", "%^B_WHITE%^BLACK%^--More-- ("+
      to_int(percent(More["current"], More["total"]))+"%) ", this_object());
    if(GetEnvVar("MORE") == "off") input_to("do_more");
    else get_char("do_more");
    return;
}

void do_help() {
    message("Nhelp",
      "Help for the \"more\" utility:\n\n"
      "<spacebar> Display the next page of text.\n"
      "B or b     Display the previous page of text.\n"
      "<          Goto the beginning of the document.\n"
      ">          Goto the end of the document.\n"
      "=          Display the current line number.\n"
      "/<exp>     Goto the next line with the expression <exp> in it.\n"
      "?<exp>     Goto the previous line with the expression <exp> in it.\n"
      "v or V     See the version information about this pager.\n"
      "h or H     This help screen.\n"
      "q or Q     Quit out of the pager.\n", this_object()
    );
}

static void regexp_fwd(string str) {
    string *matches;
    int i;

    More["regexp"] = "/"+str;
    if(!sizeof(matches = regexp(More["lines"][More["current"]..More["total"]-1], str))) {
        message(More["class"], "\nPattern not found.\n", this_object());
        if(GetEnvVar("MORE") == "off") input_to("do_more");
        else get_char("do_more");
        return;
    }
    for(i=More["current"]; i<More["total"]; i++) {
        if(More["lines"][i] != matches[0]) continue;
        More["current"] = i;
        break;
    }
    message(More["class"], "\nSkipping to line "+More["current"]+"...",
      this_object());
    do_more(" ");
}

static void regexp_bkwd(string str) {
    string *matches;
    int i;

    More["regexp"] = "?"+str;
    if(!sizeof(matches=regexp(More["lines"][0..More["current"]], str))) {
        message(More["class"], "\nPattern not found.", this_object());
        if(GetEnvVar("MORE") == "off") input_to("do_more");
        else get_char("do_more");
        return;
    }
    More["current"] = member_array(matches[0],More["lines"][0..More["current"]]);
    message(More["class"], "\n...Backing up...", this_object());
    do_more(" ");
}

string GetEnvVar(string val) { return 0; }