; ; >>>>>>-- COMMAND LINE HISTORY PROCESSING FOR CP/M PLUS --<<<<<< ; ; (C) Copyright 1986 by Michael D. Kersenbrock, 18625 S.W. Hennig ; Court, Aloha, Oregon 97006 All rights Reserved. ; ; Personal non-commercial use and distribution of this software ; is permitted so long as the above Copyright notice is maintained ; with this and subsequent copies. ; ; History (no pun intended, but noted): ; ; Version 1.0 - September 1986 Original release ; ; ; This was written first in psuedo HLL code, then hand coded into assembly ; language. That psuedo-HLL code is included below as comment lines. ; ;Note: No matter how efficiently written, this isn't really practical without ; a ramdisk or a fast hard disk. No strong effort is done to minimize ; the file size (and thus disk speed) because it isn't likely to ; acceptably fast with a floppy (regardless). I use a FAST 720K ramdisk. ; Actually, I have tried it with my floppy, and it isn't too bad at all ; but then, the floppy IS cache'd. I did my own cacheing over and above ; CP/M 3.0's (didn't like theirs), so I don't know how it works with ; DRI's version of cache. I have 178K of floppy-file cacheing. ; ; This history implements "!!", "!pattern", "!number" for command ; substitution, and implements the command 'h' to give a list of ; previous commands and their numbers. ; ; These examples use '!' as the history command character, this is ; the same as Berkeley-UNIX's (tm of AT&T) CSH shell. This CP/M ; implementation uses '|' interchangeably. The functions implemented ; are: ; ; !! Repeat last command, similar to ^W ; ; ! Repeat last command that starts with ; the given pattern. ; ; ! Repeat command numbered ; ; EACH OF THE ABOVE THREE: append the rest of ; "this line" to the substituted line. Example: ; ; If command #40 were: "COMPILE -O -C", then ; "!40 ROUTINE.C" would result in: ; "COMPILE -O -C ROUTINE.C" ; ; h Command that gives numbered command history ; list to be used with the above command. ; ; When a history-substitution is made for a command, the new ; command line is presented to the console for editing in a ; similar fashion to the banked-^W command (unlike csh). ; ; With the substitutions, the rest of the calling command line ; (if any) is added onto the substitution-replacement line. ; ; If you don't want submit files to store their internal-commands ; into the history record, put a space in front of those commands. ; ; If the file ": CCP.EXT" exists, then that program is ; loaded into memory at address 6000H, then executed with HBUFFER ; and CMDLINE address-pointers passed on the stack "above" the ; return address. CMDLINE's pointer is "just" above the return address. ; ; ; Data structure "buffer" has 42 CMDSIZE-byte records numbered 0-41. ; ; defns: when file is read in, ; record 1: contains the last command number ; record 2: contains the last command ; then... ; record 0: is where last command nr is moved to ; record 1: is where "translated" current command ; is built. ; ; ;History file format: ; ; One command line per RECSIZE byte logical record. ; ; First sector contains the current command number (1-byte) ; ; Second sector contains the last command ; Third sector contains the command before last ; (etc.) ; ; If the first byte of a sector is a null, we have ; "reached the end" of the history (null-commands are ; not stored). ; ; The file saves the last 40 command lines. ; ; A "command-line" has the first byte being the byte count, ; and a null-terminator just after the last "real" byte. ; ; If a substituted command line is modified by the line ; editor (when given the opportunity), then this new changed ; version will be put into the history along with the one ; "fetched" from history. ; ; Pattern: String of non-space and non-control characters ; ; ; ; This history routine is called with a newly gotten command in the ; CMDLINE buffer. This routine will play games with the buffer (possibly ; modifying its contents), then return. ; ; if (Command length == 0 || cmd starts w/' ' or ':') { ; return(); ; } ; buffer is cleared to nulls ; Check to see if "temp:Historyx.dat" exists ; ; if (exists) { ; readfile into data buffer starting at record-1 point ; } ; ; read command number from record-1, and write it to record-0 ; reset substitution and error flags; ; if (first-char == '!') { ; if (2nd char == '!') { ; copy line at record-2 to record-1; ; copy rest of cmdline onto end of the record-1 line; ; set substitution flag; ; } ; else if (rest up to a terminator is numeric) { ; translate number to binary; ; if ( command number wanted is NOT in our list ) { ; clear cmd line ; print "not found" ; set errorflag; ; break out from first level 'if' ; } ; else { ; copy record[(cmdnr-number+1)] to record-1; ; copy rest of cmdline onto end of the record-1 line; ; set substitution flag; ; } ; } ; else { ; search (bottom-up) for a string match (no white space) ; if (found) { ; copy that line to record-1; ; copy rest of cmd line onto end of record-1 line ; set substitution flag; ; } ; else { ; clear cmd line ; print "not found" ; set errorflag; ; break out from first level 'if' ; } ; } ; copy record-1 to cmdline; ; ; } ; else if (1st char == 'h' && 2rd char == terminator) { ; reset substitution flag, and set err flag ; print cmd lines w/numbers to screen ; } ; else { ; copy cmdline to record-1 ; } ; if (not ERRORFLAG) { ; increment command number at 0 ; ; if (first-char-of-cmd is printable, and not ' ' or ':') { ; write buffer starting at record0 (bumps last one out) ; } ; } ; else { ; reset command line; ; } ; ; if (substitution flag set) { ; calculate checksum of cmdline; ; set DMA address to cmdline; ; set DE to zero and call function 10 (edit substitution line); ; if (new checksum != old checksum) { ; go through self again; ; } ; } ; ; command line now contains command line, ready for "normal" processing. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;; END OF HISTORY MODULE ;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;