home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / qtawkos2.zip / QTAUTL.ZIP / more.exp < prev    next >
Text File  |  1993-10-19  |  23KB  |  633 lines

  1. # QTAwk "more" utility
  2. #
  3. # Display one screen of a file at a time
  4. #
  5. # Command Line Parameters Available: (Note: must precede on command line
  6. #   with "--" option to prevent QTAwk from trying to recognize)
  7. #   ansi = FALSE --> turn off use of ANSI.SYS display driver
  8. #   -ppath    --> use "path" to locate files to read
  9. #   +/r.e.[/] --> read first file until locate match to r.e. regular expression
  10. #   -ffilename --> filename specifies file name for replacement/highlight
  11. #           commands
  12. #
  13. #
  14. # "commands" allow user to:
  15. #   [Qq](uit)?       -> quit
  16. #   [Hh](elp)?       -> diplay help
  17. #   [Ff](ile)?       -> skip to next file
  18. #   [Rr](edraw)?   -> re-draw last screen
  19. #   [Nn](umbers)?  -> turn line numbers on/off
  20. #   [Tt](abs)?       -> turn tab substitution on/off
  21. #   [Cc](ontext)?  -> display search/match/highlight r.e.
  22. #   {_d}+       -> go to {_d} line, {_d} > current line number
  23. #   {_d}*l       -> skip {_d} lines
  24. #   {_d}*s       -> skip {_d} screens
  25. #   {_d}*/r/       -> go to {_d} next match of r.e.
  26. #   {_d}*m       -> go to {_d} next match of last r.e. entered as above
  27. #   {_d}*p       -> set number of lines prior to match to display
  28. #   {_d}*d       -> set display line length to {_d}, default 79
  29. #   h{_d}/r/       -> Highlight text matching r.e.
  30. #   a{_d}/r/s/       -> replace matching string
  31. #   [Ii](nit)?       -> re-initialize
  32. #              - line numbering
  33. #              - tab expansion
  34. #              - display line length
  35. #              - prior lines (to match)
  36. #              - search/highlight/replace patterns
  37. #     if optional {_d}* not entered - default to 1
  38. #
  39. # Use the getdir function to find files matching the pattern(s) passed.
  40. # Patterns follow the wildcard syntax of DOS expanded to allow the use
  41. # of character classes, and to allow characters after the '*' wildcard.
  42. # DOS does not recognize characters following the '*'. Must also enclose
  43. # filename specifications in quotes, "fn", to prevent expansion by the QTAwk
  44. # wild card expansion routine. For example the DOS wildcard expression for
  45. # all file names starting with 'c' and ending with 't' or 'p' and with an
  46. # extension of "exp" would be:
  47. #   "c*[pt].exp"
  48. # this is translated into the regular expression syntax:
  49. #   /^C[!\X001-\X021."\/\\\[\]:|<>+=;,]*[PT]\.EXP$/
  50. #
  51. # Multiple patterns may also be specified:
  52. #   QTAwk -fmore.exp -- "[gdh]*.(hlp|txt)" "*(dir|bnc).exp"
  53. #
  54. #
  55. BEGIN {
  56.     local p_indx = 0;
  57.     local sub_dir = ""; # default to current sub-directory
  58.     local fnames;
  59.     local files_found;
  60.     local cnames, cindex = 0;
  61.     local ipat;
  62.     local i, j, cmd_line;
  63.  
  64.     # Set The Standard Error File
  65.     stderr = "stderr";
  66.  
  67.     # NOTE: Use '\x0ff' In ANSI Sequences Below. The '\x0ff' Will Get
  68.     # Translated To '[' Before Being Printed. Use '\x0ff' Character
  69.     # So That '[' May Be Used In Search And High Lighted Text Regular
  70.     # Expressions Without Being Substituted For. This Assumes That
  71.     # The '\x0ff' Character Will Probably Not Be In A Search Pattern
  72.     # Or High Lighted Text Pattern.
  73.     # Set ANSI Strings For Text Highlighting
  74.     ### Turn On Use Of ANSI.SYS Display Driver
  75.     ansi = TRUE;
  76.     Red_on_Black    = "\x01b\x0ff0;31;40m";
  77.     Green_on_Black  = "\x01b\x0ff0;32;40m";
  78.     Yellow_on_Black = "\x01b\x0ff0;33;40m";
  79.     Blue_on_Black   = "\x01b\x0ff0;34;40m";
  80.     Magenta_Black   = "\x01b\x0ff0;35;40m";
  81.     Cyan_on_Black   = "\x01b\x0ff0;36;40m";
  82.     White_Black     = "\x01b\x0ff0;37;40m";
  83.     Black_on_Red    = "\x01b\x0ff0;30;41m";
  84.     Green_on_Red    = "\x01b\x0ff0;32;41m";
  85.  
  86.     # Set ANSI Strings For Text Highlighting - Bold Text
  87.     Red_on_Blackh   = "\x01b\x0ff1;31;40m";
  88.     Green_on_Blackh = "\x01b\x0ff1;32;40m";
  89.     Yellow_on_Blackh= "\x01b\x0ff1;33;40m";
  90.     Blue_on_Blackh  = "\x01b\x0ff1;34;40m";
  91.     Magenta_Blackh  = "\x01b\x0ff1;35;40m";
  92.     Cyan_on_Blackh  = "\x01b\x0ff1;36;40m";
  93.     White_Blackh    = "\x01b\x0ff1;37;40m";
  94.     Black_on_Redh   = "\x01b\x0ff1;30;41m";
  95.     Green_on_Redh   = "\x01b\x0ff1;32;41m";
  96.  
  97.     # Echo Input
  98. #    ECHO_INPUT = TRUE;
  99.  
  100.     # Set Displayed Line Length
  101.     display_length = def_display_length = 79;
  102.  
  103.     # Flag For Expanding Tabs
  104.     sub_tabs = FALSE;
  105.  
  106.     # Set Number Of Lines On Screen
  107.     screen_size = 25;
  108.  
  109.     # Set Number Of Lines To Display Prior To Line Matching R.E.
  110.     prior_lines = dprior_lines = 2;
  111.  
  112.     # Set Array Members For Highlighting Phrases
  113.     High_Text[1] = Red_on_Blackh;
  114.     High_Text[2] = Green_on_Blackh;
  115.     High_Text[3] = Yellow_on_Blackh;
  116.     High_Text[4] = Blue_on_Blackh;
  117.     High_Text[5] = Magenta_Blackh;
  118.     High_Text[6] = Cyan_Blackh;
  119.     High_Text[7] = White_Blackh;
  120.     High_Text[8] = Black_on_Redh;
  121.     High_Text[9] = Green_on_Redh;
  122.  
  123.     # Set ANSI Sequence For Normal Text
  124.     Normal  = White_on_Blue = "\x01b\x0ff0;37;44m";
  125.  
  126.     blank_line = /^\f?{_w}*$/;
  127.     skipping_blank = FALSE;
  128.  
  129.     if ( ARGC == 1 ) {
  130.     cmd_help;
  131.     exit 1;
  132.     }
  133.  
  134.     init_sre = FALSE;
  135.  
  136.     # Set The Regular Expressions For Recognizing "Commands"
  137.     ANSI       = /^[Aa]([Nn][Ss][Ii])?$/;
  138.     Quit       = /^[Qq](uit)?$/;
  139.     Help       = /^[Hh](elp)?$/;
  140.     Re_display = /^[Rr](edraw)?$/;
  141.     Next_file  = /^[Ff](ile)?$/;
  142.     Numbersl   = /^[Nn](umbers)?$/;
  143.     Sub_Tabs   = /^[Tt](abs)?$/;
  144.     Review_P   = /^[Cc](ontext)?$/;
  145.     Skip_blank = /^[Bb](lank)?$/;
  146.     GoTo_line  = /^{_d}+$/;
  147.     Skip_lines = /^{_d}*l$/;
  148.     Skip_scrn  = /^{_d}*s$/;
  149.     Match_RE   = /^{_d}*\//;
  150.     RE_reset   = /^{_d}*m$/;
  151.     Prior_cmd  = /^{_d}*p$/;
  152.     Display_L  = /^{_d}*d$/;
  153.     High_RE    = /^h{_w}*{_d}*{_w}*\//;
  154.     Replace_RE = /^r{_w}*{_d}*{_w}*\//;
  155.     Init_RE    = /^[Ii](nit)?$/;
  156.  
  157.     highlight = FALSE;
  158.     replace_txt = FALSE;
  159.  
  160.     # Set Regular Expressions For Command Line Options
  161.     # Must Precede These On The Command Line To Qtawk With "--"
  162.     # To Prevent Qtawk From Recognizing
  163.     Set_path = /^[-\/][Pp]/;
  164.     Red_cmds = /^[-\/][Ff]/;
  165.     RE_cmd   = /^\+\//;
  166.  
  167.     # Set Regular Expression For Recognizing Leading Digits In A Command
  168.     ldg_digits = /^{_w}*{_d}+/;
  169.  
  170.     # DOS Filename Wild Card Search Pattern
  171.     wild_cards = /[\*\?]/;
  172.  
  173.     # Specify Legal Filename Characters By Excluding Those Which Are Illegal
  174.     legal_chars = /[!\x001-\x021."\/\\\[\]:|<>+=;,]/;
  175.  
  176.     for ( i = 1 ; i < ARGC ; i++ ) {
  177.     ipat = ARGV[i];
  178.     switch ( ipat ) {
  179.         case Set_path:
  180.         sub(Set_path,"",ipat);
  181.         if ( length(ipat) == 0 ) ipat = ARGV[++i];
  182.         sub_dir ∩= ipat;
  183.         # check for trailing back-slash on path
  184.         if ( sub_dir !~ /\\$/ ) sub_dir ∩= '\\';
  185.         break;
  186.         case RE_cmd:
  187.         sub(/^\+/,"",ipat);
  188.         execute_cmd(ipat);
  189.         init_sre = TRUE;
  190.         break;
  191.         case Red_cmds:
  192.         sub(Red_cmds,"",ipat);
  193.         if ( length(ipat) == 0 ) ipat = ARGV[++i];
  194.         while ( fgetline(ipat,cmd_line) > 0 )
  195.           if ( cmd_line !~ /^{_w}*#/ ) execute_cmd(replace(cmd_line));
  196.         close(ipat);
  197.         break;
  198.         default:
  199.         #
  200.         # Convert DOS Filename Wild Card Characters To Appropriate Regular
  201.         # Expression Operators And Escape Extension Period To Prevent
  202.         # Interpretation As R.E. "Any Character" Operator - Other R.E.
  203.         # Operators Allowed.
  204.         #
  205.         ipat = strupr(ipat);
  206.         if ( ipat ~~ wild_cards ) {
  207.         gsub(/\./,"\\.",ipat);
  208.         gsub(/\*/,"{legal_chars}*",ipat);
  209.         gsub(/\?/,"{legal_chars}?",ipat);
  210.         #
  211.         # the following line will convert the command line strings
  212.         # into regular expressions. This is to prevent the constant
  213.         # conversion of a string into a regular expression in the
  214.         # "getdir" function.
  215.         #
  216.         execute("pattern[" ∩ ++p_indx ∩ "] = /^" ∩ ipat ∩ "$/;");
  217.         } else cnames[++cindex] = ARGV[i];
  218.         break;
  219.     }
  220.     }
  221.     # If You Want To See The R.E. For The Files Un-comment The Following Line
  222. #    for ( i in pattern ) print "Searching For: " ∩ replace(pattern[i]);
  223.     # Delete Command Line Arguments - Will Replace With Directory Search Below
  224.     while ( 1 in ARGV ) delete ARGV[1];
  225.     i = 1;
  226.     if ( cindex )
  227.     for ( cindex in cnames )
  228.         if ( j = findfile(files_found,cnames[cindex]) ) {
  229. #         ARGV[i++] = "file_size=" ∩ files_found[1]["size"];
  230. #         ARGV[i++] = "file_date=" ∩ files_found[1]["date"];
  231. #         ARGV[i++] = "file_time=" ∩ files_found[1]["time"];
  232.         ARGV[i++] = cnames[cindex];
  233.         }
  234.     if ( p_indx ) {
  235.         #
  236.         # Go Find Matching Files And Print Names
  237.         #
  238.     for ( j in pattern ) print pattern[j];
  239.     fnames = getdir(sub_dir,pattern);
  240.     for ( j in fnames ) {
  241.         # use command line assignment to set file size for each file
  242. #         ARGV[i++] = "file_size=" ∩ fnames[j]["size"];
  243. #         ARGV[i++] = "file_date=" ∩ fnames[j]["date"];
  244. #         ARGV[i++] = "file_time=" ∩ fnames[j]["time"];
  245.         ARGV[i++] = sub_dir ∩ fnames[j]["name"];
  246. #         print fnames[j]["name"],fnames[j]["size"],fnames[j]["date"],fnames[j]["time"];
  247.     }
  248.     }
  249.  
  250.     # Check For NO Directory Entries Which Match - Exit
  251.     # If Do Not Exit, Then QTAwk Will Read From Standard Input - With No
  252.     # Prompt - It Will Appear As If The Machine Has Hung. A Ctrl-Z Will
  253.     # Input An End-Of-File And Terminate, But User Probably Not Expecting
  254.     # To Have To Do That
  255.     if ( i == 1 ) {
  256.     print "No Directory Entries Match filename Specifications";
  257.     exit;
  258.     }
  259.  
  260.     # Set The Number Of Command Arguments
  261.     ARGC = i;
  262. }
  263.  
  264. INITIAL {
  265.     line_count = 1;
  266.     searching_re = init_sre;
  267.     exit_endfile = init_sre = FALSE;
  268.     amt_read = 0;
  269.     cls;
  270.     FILEDATE = sdate("%m/%d/%y",FILEDATE);
  271.     FILETIME = stime("%H:%M",FILETIME);
  272.     print "=====> " ∩ FILENAME ∩ " : " ∩ FILESIZE ∩ " : " ∩ FILEDATE ∩ " : " ∩ FILETIME ∩ " <=====";
  273. }
  274.  
  275. skipping_blank && blank_line {
  276.     if ( !searching_re && !print_blank ) print_blank = TRUE;
  277.     last_screen[row++] = "";
  278.     next;
  279. }
  280.  
  281. searching_re {
  282.     if ( $0 ~~ Search_pat ) {
  283.     # Here If Found Match In R.E. Search
  284.     match_found++;
  285.     if ( !--searching_re ) {
  286.         printf("                          \r");
  287.         row += line_count += re_draw(match_last);
  288.         last_screen = match_last;
  289.         cycle;
  290.     } else printf("%6u : Match: %3u/%3u\r",FNR,match_found,searching_re);
  291.       } else {
  292.     # here if searching for r.e., but current line does not match
  293.     # 'rotate' storage array an tack current line on end
  294.     printf("%6u\r",FNR);
  295.     match_last[1] = $0;
  296.     rotate(match_last);
  297.     }
  298.     next;
  299. }
  300.  
  301.     {
  302.     local i;
  303.     local inp;
  304.     local hdr = line_numbers ? FNR ∩ ": " : "";
  305.     local dl;
  306.  
  307.     print_blank = FALSE;
  308.     amt_read += length + 2; # added 2 to size read to account for CR/LF
  309.     dl = hdr ∩ $0;
  310.     # Set Line To Be Displayed, Truncate To Keep From Overflowing Display Line
  311.     # Will Still Overflow On Some Lines Since Tabs Are Counted As A Single
  312.     # Character Here, But Expanded By DOS On Output To Display. Could Replace
  313.     # Tabs With A Single Blank To Prevent This From Happening
  314.     if ( length(dl) > display_length ) dl = substr(dl,1,display_length);
  315.     if ( !searching_re ) {
  316.       # Here When Not Searching For Regular Expression Or Have Found
  317.       #
  318.       # Check If Translating Horizontal Tabs To Blanks - Do If TRUE
  319.     if ( sub_tabs ) dl = stran(dl,' ','\t');
  320.       # Check If ANSI.SYS Display Driver Being Used
  321.     if ( ansi ) {
  322.         # If A Search Pattern Exists - High-light
  323.         if ( Search_pat ) gsub(Search_pat,Red_on_Black ∩ "$$0" ∩ Normal,dl);
  324.         # Put In High Light ANSI Sequences For High Lighted Text
  325.         if ( highlight ) gsub(High_pat,High_Text[MATCH_INDEX + 0] ∩ "$$0" ∩ Normal,dl);
  326.         # Replace Matching Strings
  327.         if ( replace_txt ) gsub(Replace_pat,Replace_par[MATCH_INDEX + 0],dl);
  328.         # Translate '\x0ff' Character To '[' For ANSI Sequences
  329.         dl = stran(dl,'[','\x0ff');
  330.     }
  331.     print dl;
  332.     # Store Display Line
  333.     last_screen[row++] = $0;
  334.     # Check If Last Line On Screen
  335.     if ( ++line_count >= screen_size ) {
  336.         percent_rd = (int((1000.0 * amt_read)/FILESIZE) + 5)/ 10;
  337.         while ( TRUE ) {
  338.         printf("%s : %u%% : %lu : %s : %s : %u <-> Command (h for help)─┘",FILENAME,percent_rd,FILESIZE,FILEDATE,FILETIME,FNR);
  339.         fgetline("stdin",inp);
  340.         if ( length(inp) > 0 ) {
  341.             execute_cmd(inp);
  342.             if ( break_loop ) {
  343.             break_loop = FALSE;
  344.             break;
  345.             }
  346.         } else break;
  347.         }
  348.         cls;
  349.         line_count = 1;
  350.         deletea last_screen;
  351.         row = 0;
  352.     }
  353.       }
  354. }
  355.  
  356. FINAL {
  357.     for ( ++line_count ; ++line_count < screen_size ; ) print "";
  358.     print "=====> " ∩ FILENAME ∩ " <=====";
  359.     if ( !exit_endfile ) {
  360.     printf("%s <-> Press Enter",FILENAME);
  361.     fgetline("stdin",inp);
  362.     }
  363.     exit_endfile = FALSE;
  364. }
  365.  
  366. # Function To Check For Valid Command And Execute
  367. function execute_cmd(cmd_str) {
  368.     local i, j;
  369.     local scrn_m = 1;
  370.     local digits = FALSE;
  371.  
  372.     # Delete Leading/Trailing White Space From Command String
  373.     cmd_str = strim(cmd_str);
  374.     # NOTE: If Leading Digits On Command, Find
  375.     #        Add 0 To Digits To Convert To Integer. Otherwise If Only One
  376.     #        Digit, "substr" Function Returns A Character Value. Incrementing
  377.     #        A Character Value With '++' Operator Gives Next Character In ASCII
  378.     #        Sequence, Decrementing With '--' Gives Previous Character.
  379.     if ( cmd_str ~~ ldg_digits ) {
  380.     digits = substr(cmd_str,MSTART,MLENGTH) + 0;
  381.     cmd_str = strim(deletec(cmd_str,MSTART,MLENGTH));
  382.     }
  383.     if ( cmd_str ) {
  384.     switch ( cmd_str ) {
  385.         case ANSI:
  386.         ansi = !ansi;
  387.         break;
  388.         case Skip_blank:
  389.         skipping_blank = !skipping_blank;
  390.         break;
  391.         case Numbersl:
  392.         # toggle line numbering on/off
  393.         line_numbers = !line_numbers;
  394.         break;
  395.         case Help:
  396.         help;
  397.         break;
  398.         case GoTo_line:
  399.         if ( digits > FNR ) skip_ahead(digits - FNR - 1);
  400.         break_loop = TRUE;
  401.         break;
  402.         case Quit:
  403.         exit_endfile = TRUE;
  404.         exit;
  405.         break;
  406.         case Re_display:
  407.         cls;
  408.         re_draw(last_screen);
  409.         break;
  410.         case Next_file:
  411.         deletea last_screen;
  412.         exit_endfile = TRUE;
  413.         endfile;
  414.         break;
  415.         case Prior_cmd:
  416.         prior_lines = digits ? digits : dprior_lines;
  417.         deletea match_last;
  418.         break;
  419.         case Skip_scrn:
  420.         scrn_m = screen_size;
  421.         case Skip_lines:
  422.         skip_cnt = 1;
  423.         if ( digits ) skip_cnt = digits;
  424.         skip_ahead(skip_cnt * scrn_m);
  425.         break_loop = TRUE;
  426.         break;
  427.         case Match_RE:
  428.         if ( cmd_str !~ /\/$/ ) cmd_str ∩= '/';
  429.         execute("Search_pat = " ∩ cmd_str ∩ ";");
  430.         case RE_reset:
  431.         if ( Search_pat ) {
  432.             searching_re = digits ? digits : TRUE;
  433.             match_found = 0;
  434.             for ( j = prior_lines , i = 1 ; j ; i++ , j-- )
  435.               match_last[i] = last_screen[screen_size - j];
  436.         }
  437.         break_loop = TRUE;
  438.         break;
  439.         case High_RE:
  440.         cmd_str = deletec(cmd_str,1,1);
  441.         if ( cmd_str ~~ ldg_digits ) {
  442.             digits = substr(cmd_str,MSTART,MLENGTH) + 0;
  443.             cmd_str = strim(deletec(cmd_str,MSTART,MLENGTH));
  444.             if ( !digits ) digits = 1;
  445.         } else digits = 1;
  446.         if ( digits < 10 ) {
  447.             if ( cmd_str !~ /\/$/ ) cmd_str ∩= '/';
  448.             execute("High_pat[digits] = " ∩ cmd_str ∩ ";");
  449.           } else {
  450.             cmd_str ~~ /\/[!\/]+\//; # set MSTART/MLENGTH
  451.             i = substr(cmd_str,MSTART,MLENGTH);
  452.             cmd_str = substr(cmd_str,MSTART + MLENGTH);
  453.             sub(/\/$/,"",cmd_str);
  454.             execute("High_pat[digits] = " ∩ i ∩ ";");
  455.             execute("High_Text[digits] = \"" ∩ cmd_str ∩ "\";");
  456.         }
  457.         highlight = TRUE;
  458.         break;
  459.         case Review_P:
  460.         if ( Search_pat ) print "Search Pattern: /" ∩ Search_pat ∩ '/';
  461.         if ( highlight ) for ( i in High_pat ) print "High Lighted Pattern (" ∩ i ∩ "): /" ∩ High_pat[i] ∩ '/';
  462.         if ( replace_txt )
  463.             for ( i in Replace_pat ) {
  464.             print "Replace Pattern (" ∩ i ∩ "): /" ∩ Replace_pat[i] ∩ '/';
  465.             print "Replace String  (" ∩ i ∩ "): \"" ∩ Replace_par[i] ∩ '"';
  466.             }
  467.         break;
  468.         case Display_L:
  469.         if ( digits ) display_length = digits;
  470.           else display_length = def_display_length;
  471.         break;
  472.         case Sub_Tabs:
  473.         sub_tabs = !sub_tabs;
  474.         break;
  475.         case Replace_RE:
  476.         cmd_str = deletec(cmd_str,1,1);
  477.         if ( cmd_str ~~ ldg_digits ) {
  478.             digits = substr(cmd_str,MSTART,MLENGTH) + 0;
  479.             cmd_str = strim(deletec(cmd_str,MSTART,MLENGTH));
  480.             if ( !digits ) digits = 1;
  481.         } else digits = 1;
  482.         if ( cmd_str ~~ /\/[!\/]+\// ) {
  483.             i = substr(cmd_str,MSTART,MLENGTH);
  484.             cmd_str = substr(cmd_str,MSTART + MLENGTH);
  485.             sub(/\/$/,"",cmd_str);
  486.             execute("Replace_pat[digits] = " ∩ i ∩ ";");
  487.             execute("Replace_par[digits] = \"" ∩ cmd_str ∩ "\";");
  488.         }
  489.         replace_txt = TRUE;
  490.         break;
  491.         case Init_RE:
  492.         deletea(High_pat);
  493.         deletea(Replace_pat);
  494.         deletea(Replace_par);
  495.         highlight = FALSE;
  496.         replace_txt = FALSE;
  497.         display_length = def_display_length;
  498.         prior_lines = dprior_lines;
  499.         searching_re = line_numbers = sub_tabs = Search_pat = FALSE;
  500.         break;
  501.     }
  502.       } else if ( digits > FNR ) {
  503.     skip_ahead(digits - FNR - 1);
  504.     break_loop = TRUE;
  505.     }
  506. }
  507.  
  508. # Function To Redraw Screen
  509. function re_draw(screen) {
  510.     local j = 0;
  511.     local k = 0;
  512.     local i, n;
  513.     local cl;
  514.  
  515.     for ( i in screen ) k++;
  516.     j = FNR - k + 1;
  517.     for ( i in screen ) {
  518.     if ( skipping_blank && (screen[i] ~~ blank_line) ) {
  519.         j++;
  520.         continue;
  521.     }
  522.     cl = (line_numbers ? j++ ∩ ": " : "") ∩ screen[i];
  523.     if ( sub_tabs ) cl = stran(cl," ","\t");
  524.     if ( length(cl) > display_length ) cl = substr(cl,1,display_length);
  525.     # Check If ANSI.SYS Display Driver Being Used
  526.     if ( ansi ) {
  527.         if ( Search_pat ) gsub(Search_pat,Red_on_Black ∩ "$$0" ∩ Normal,cl);
  528.         gsub(High_pat,High_Text[MATCH_INDEX + 0] ∩ "$$0" ∩ Normal,cl);
  529.         gsub(Replace_pat,Replace_par[MATCH_INDEX + 0],cl);
  530.         cl = stran(cl,'[','\x0ff');
  531.     }
  532.     print cl;
  533.     }
  534.     return k;
  535. }
  536.  
  537. # Function To Skip Ahead Number Of Lines In Current File Specified
  538. function skip_ahead(lines) {
  539.     local dummy;
  540.     local gl;
  541.  
  542.     cls;
  543.     while ( lines-- ) {
  544.     # Read Next Line, Check For Input And Not EOF
  545.     if ( (gl = getline(dummy)) <= 0 ) {
  546.         exit_endfile = TRUE;
  547.         break;
  548.     }
  549.     # Added 2 To Size Read To Account For CR/LF
  550.     amt_read += length(dummy) + 2;
  551.     printf("%u\r",FNR);
  552.     }
  553. }
  554.  
  555. function help() {
  556.     local tabs = sub_tabs ? "ON" : "OFF";
  557.  
  558.     cls;
  559.     print "\x01b[1;32;40mMORE\x01b[0;37;44m File Function Commands";
  560.     print "Commands: (i stands for an integer matched by {_d}.)";
  561.     print "i* means the integer is optional  (match {_d}*) - 1 defaults.";
  562.     print "i+ means the integer is mandatory (match {_d}+) - no default.";
  563.     print "[\x01b[1;32;40mAa\x01b[0;37;44m](ansi)?   -> Toggle Text Highlighting.";
  564.     print "[\x01b[1;32;40mQq\x01b[0;37;44m](uit)?    -> exit to DOS.";
  565.     print "[\x01b[1;32;40mBb\x01b[0;37;44m](lank)?   -> toggle skip blank line flag. Currently: " ∩ (skipping_blank ? "TRUE" : "FALSE");
  566.     print "[\x01b[1;32;40mRr\x01b[0;37;44m](edraw)?  -> re-display last screen.";
  567.     print "[\x01b[1;32;40mFf\x01b[0;37;44m](ile)?    -> proceed to next file.";
  568.     print "[\x01b[1;32;40mNn\x01b[0;37;44m](umbers)? -> turn line numbers on/off.";
  569.     print "[\x01b[1;32;40mTt\x01b[0;37;44m](abs)?    -> Sub. Tabs - toggle on/off, starts off. Currently: " ∩ tabs;
  570.     print "                 if on, replace tabs with blank";
  571.     print "[\x01b[1;32;40mCc\x01b[0;37;44m](ontext)? -> Review Search and High Lighted Text Patterns";
  572.     print "[\x01b[1;32;40mIi\x01b[0;37;44m](nit)?    -> re-Initialize";
  573.     print "\x01b[1;32;40mi+\x01b[0;37;44m            -> Go To Line number i, if i > current line number.";
  574.     print "\x01b[1;32;40mi*l\x01b[0;37;44m           -> skip forward i Lines.";
  575.     print "\x01b[1;32;40mi*s\x01b[0;37;44m           -> skip forward i Screens.";
  576.     print "\x01b[1;32;40mi*/r/\x01b[0;37;44m         -> search for ith expression. If found begin";
  577.     print "                 display starting 'p' lines before matching line.";
  578.     print "\x01b[1;32;40mi*m\x01b[0;37;44m           -> search for next ith Match to previous";
  579.     print "                 regular expression.";
  580.     print "\x01b[1;32;40mi*p\x01b[0;37;44m           -> set number of lines prior to match to display";
  581.     print "                 defaults to 2 if i not specified.";
  582.     print "\x01b[1;32;40mi*d\x01b[0;37;44m           -> set display line length to i, 79 default";
  583.     print "\x01b[1;32;40mhi*/r/\x01b[0;37;44m        -> High-light text matching ith expression";
  584.     print "\x01b[1;32;40mri*/r/s/\x01b[0;37;44m      -> Replace r with string s";
  585. }
  586.  
  587. # Function To Clear Screen And Home Cursor
  588. # NOTE: MUST Have ANSI.SYS Device Driver Installed To Work
  589. function cls() {
  590.     # Clear Screen And Home Cursor String
  591.     local _cls_ = "\x01b[2J";
  592.  
  593.     fprintf(stderr,_cls_);
  594. }
  595.  
  596. # Include Directory Searching Functions
  597. #include <dirsrch.exp>
  598.  
  599. # Function To Display Command Line Help
  600. function cmd_help() {
  601.     cls;
  602.     print "Usage:";
  603.     print "\x01b[1;32;40mQTAwk -fmore.exp -- [-ppath] [+/r.e.[/]] file1 file2 ...\x01b[0;37;44m";
  604.     print "Options:";
  605.     print " ppath - specifiy path to find files";
  606.     print " +/r.e./ - specify regular expression for starting search";
  607.     print "Commands:";
  608.     print "i below stands for an integer matched by {_d}.";
  609.     print "i* means the integer is optional  (match {_d}*) - 1 defaults.";
  610.     print "i+ means the integer is mandatory (match {_d}+) - no default.";
  611.     print "[\x01b[1;32;40mAa\x01b[0;37;44m](ansi)?   -> Toggle Text Highlighting.";
  612.     print "[\x01b[1;32;40mQq\x01b[0;37;44m](uit)?    -> exit to DOS.";
  613.     print "[\x01b[1;32;40mRr\x01b[0;37;44m](edraw)?  -> re-display last screen.";
  614.     print "[\x01b[1;32;40mFf\x01b[0;37;44m](ile)?    -> proceed to next file.";
  615.     print "[\x01b[1;32;40mNn\x01b[0;37;44m](umbers)? -> turn line numbers on/off.";
  616.     print "[\x01b[1;32;40mTt\x01b[0;37;44m](abs)?    -> Sub. Tabs - toggle on/off, starts off, currently:" ∩ tabs;
  617.     print "                 if on, replace tabs with blank";
  618.     print "[\x01b[1;32;40mCc\x01b[0;37;44m](ontext)? -> Review Search and High Lighted Text Patterns";
  619.     print "[\x01b[1;32;40mIi\x01b[0;37;44m](nit)?    -> re-Initialize";
  620.     print "\x01b[1;32;40mi+\x01b[0;37;44m            -> Go To Line number i, if i > current line number.";
  621.     print "\x01b[1;32;40mi*l\x01b[0;37;44m           -> skip forward i Lines.";
  622.     print "\x01b[1;32;40mi*s\x01b[0;37;44m           -> skip forward i Screens.";
  623.     print "\x01b[1;32;40mi*/r/\x01b[0;37;44m         -> search for ith expression. If found begin";
  624.     print "                 display starting 'p' lines before matching line.";
  625.     print "\x01b[1;32;40mi*m\x01b[0;37;44m           -> search for next ith Match to previous";
  626.     print "                 regular expression.";
  627.     print "\x01b[1;32;40mi*p\x01b[0;37;44m           -> set number of lines prior to match to display";
  628.     print "                 defaults to 2 if i not specified.";
  629.     print "\x01b[1;32;40mi*d\x01b[0;37;44m           -> set display line length to i, 79 default";
  630.     print "\x01b[1;32;40mhi*/r/\x01b[0;37;44m        -> High-light text matching ith expression";
  631.     print "\x01b[1;32;40mri*/r/s/\x01b[0;37;44m      -> Replace r with string s";
  632. }
  633.