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