tonyb@tektools.UUCP (Tony Birnseth) (12/12/86)
Index: /bin/csh 4.3BSD Description: The csh manual page declares that history references are relative to the the previous history event specified on a line. A history reference may be given without an event specification, e.g. `!$'. In this case the reference is to the previous command unless a previous history reference occurred on the same line in which case this form repeats the previous reference. Thus `!?foo?^ !$' gives the first and last arguments from the command matching `?foo?'. This is not the observed behavior. !$ always references the the last argument of the *previous* command. Additionally, the history command should accept 3 arguments, but only accepts 2. 'history -r -f 3'. The code says it should be invoked as 'history -rf 3' but that's an unreasonable restriction. Repeat by: % echo this is foo this is foo % echo this is bar this is bar % !?foo?^ !$ this bar # this should have been 'this foo' Fix: Change the argument count in sh.init.c from 2 to 3. Change the point at which the last event is assigned. Increment the event counter on errors. Do some other fooling around with the event counter to compensate for the change. Apply the following diffs to sh.c, sh.hist.c and sh.init.c and add '-DTEK_HIST -DTEK_BUGS' to the 'DEFS' in the Makefile. The '-DTEK_HIST' will add the functionality described in the man page to csh. The '-DTEK_BUGS' will include the bug fix for the history argument counter. *** /tmp/,RCSt1027842 Thu Dec 11 17:02:54 1986 --- sh.c Thu Dec 11 12:05:17 1986 *************** *** 742,748 printprompt(); } err = 0; ! /* * Echo not only on VERBOSE, but also with history expansion. * If there is a lexical error then we forego history echo. --- 742,748 ----- printprompt(); } err = 0; ! #ifdef TEK_HIST /* * Initialize the last event here so that relative history * accesses (ie !$ !*) remain relative. *************** *** 744,749 err = 0; /* * Echo not only on VERBOSE, but also with history expansion. * If there is a lexical error then we forego history echo. */ --- 744,755 ----- err = 0; #ifdef TEK_HIST /* + * Initialize the last event here so that relative history + * accesses (ie !$ !*) remain relative. + */ + lastev = eventno; + #endif /* TEK_HIST */ + /* * Echo not only on VERBOSE, but also with history expansion. * If there is a lexical error then we forego history echo. */ *************** *** 773,778 * Print lexical error messages, except when sourcing * history lists. */ if (!enterhist && err) error(err); --- 779,785 ----- * Print lexical error messages, except when sourcing * history lists. */ + #ifdef TEK_HIST if (!enterhist && err) /* * It would be nice if we could bury eventno++ in *************** *** 774,780 * history lists. */ if (!enterhist && err) ! error(err); /* * If had a history command :p modifier then --- 781,793 ----- */ #ifdef TEK_HIST if (!enterhist && err) ! /* ! * It would be nice if we could bury eventno++ in ! * error(). ! * To many "uninteresting events" use error() to ! * jump back here. ! */ ! eventno++, error(err); /* * If had a history command :p modifier then *************** *** 781,786 * this is as far as we should go */ if (justpr) reset(); alias(¶ml); --- 794,808 ----- * this is as far as we should go */ if (justpr) + eventno++, reset(); + #else /* ! TEK_HIST */ + if (!enterhist && err) + error(err); + /* + * If had a history command :p modifier then + * this is as far as we should go + */ + if (justpr) reset(); #endif /* TEK_HIST */ alias(¶ml); *************** *** 782,788 */ if (justpr) reset(); ! alias(¶ml); /* --- 804,810 ----- */ if (justpr) reset(); ! #endif /* TEK_HIST */ alias(¶ml); /* *************** *** 789,794 * Parse the words of the input into a parse tree. */ t = syntax(paraml.next, ¶ml, 0); if (err) error(err); --- 811,817 ----- * Parse the words of the input into a parse tree. */ t = syntax(paraml.next, ¶ml, 0); + #ifndef TEK_HIST if (err) error(err); #else /* TEK_HIST */ *************** *** 791,796 t = syntax(paraml.next, ¶ml, 0); if (err) error(err); /* * Execute the parse tree --- 814,822 ----- #ifndef TEK_HIST if (err) error(err); + #else /* TEK_HIST */ + if (err) + eventno++, error(err); /* * Increment the acutal event number here. *************** *** 792,797 if (err) error(err); /* * Execute the parse tree */ --- 818,833 ----- if (err) eventno++, error(err); + /* + * Increment the acutal event number here. + * If we waited till after execute(), interupted commands + * would not get their history counter incremented. + * We pad the eventno when savehist() above calls enthist() + * to place the current command in the history list. + */ + if ( t && intty && !whyles ) + eventno++; + #endif /* TEK_HIST */ /* * Execute the parse tree */ *** /tmp/,RCSt1027857 Thu Dec 11 17:03:12 1986 --- sh.hist.c Thu Dec 11 12:43:28 1986 *************** *** 44,49 hp->Hnext = np->Hnext, hfree(np); else hp = np; (void) enthist(++eventno, sp, 1); } --- 44,52 ----- hp->Hnext = np->Hnext, hfree(np); else hp = np; + #ifdef TEK_HIST + (void) enthist(eventno + 1, sp, 1); + #else (void) enthist(++eventno, sp, 1); #endif } *************** *** 45,50 else hp = np; (void) enthist(++eventno, sp, 1); } struct Hist * --- 48,54 ----- (void) enthist(eventno + 1, sp, 1); #else (void) enthist(++eventno, sp, 1); + #endif } struct Hist * *** /tmp/,RCSt1027862 Thu Dec 11 17:03:14 1986 --- sh.init.c Thu Dec 11 12:47:00 1986 *************** *** 118,123 #ifdef VFORK "hashstat", hashstat, 0, 0, #endif "history", dohist, 0, 2, "if", doif, 1, INF, "jobs", dojobs, 0, 1, --- 121,129 ----- #ifdef VFORK "hashstat", hashstat, 0, 0, #endif + #ifdef TEK_BUGS + "history", dohist, 0, 3, + #else /* ! TEK_BUGS */ "history", dohist, 0, 2, #endif /* TEK_BUGS */ "if", doif, 1, INF, *************** *** 119,124 "hashstat", hashstat, 0, 0, #endif "history", dohist, 0, 2, "if", doif, 1, INF, "jobs", dojobs, 0, 1, "kill", dokill, 1, INF, --- 125,131 ----- "history", dohist, 0, 3, #else /* ! TEK_BUGS */ "history", dohist, 0, 2, + #endif /* TEK_BUGS */ "if", doif, 1, INF, "jobs", dojobs, 0, 1, "kill", dokill, 1, INF,