summaryrefslogtreecommitdiff
path: root/history
diff options
context:
space:
mode:
Diffstat (limited to 'history')
-rw-r--r--history/history.1234
-rw-r--r--history/history.c341
2 files changed, 0 insertions, 575 deletions
diff --git a/history/history.1 b/history/history.1
deleted file mode 100644
index 18ed28f..0000000
--- a/history/history.1
+++ /dev/null
@@ -1,234 +0,0 @@
-.\" history.1
-.\"-------
-.\" See rc.1 for man page portability notes.
-.\"-------
-.\" Dd distance to space vertically before a "display"
-.\" These are what n/troff use for interparagraph distance
-.\"-------
-.if t .nr Dd .4v
-.if n .nr Dd 1v
-.\"-------
-.\" Ds begin a display, indented .5 inches from the surrounding text.
-.\"
-.\" Note that uses of Ds and De may NOT be nested.
-.\"-------
-.de Ds
-.\" .RS \\$1
-.sp \\n(Ddu
-.in +0.5i
-.nf
-..
-.\"-------
-.\" De end a display (no trailing vertical spacing)
-.\"-------
-.de De
-.fi
-.in
-.\" .RE
-..
-.\"-------
-.\" I stole the Xf macro from the -man macros on my machine (originally
-.\" "}S", I renamed it so that it won't conflict).
-.\"-------
-.\" Set Cf to the name of the constant width font.
-.\" It will be "C" or "(CW", typically.
-.\" NOTEZ BIEN the lines defining Cf must have no trailing white space:
-.\"-------
-.if t .ds Cf C
-.if n .ds Cf R
-.\"-------
-.\" Rc - Alternate Roman and Courier
-.\"-------
-.de Rc
-.Xf R \\*(Cf \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
-..
-.\"-------
-.\" Ic - Alternate Italic and Courier
-.\"-------
-.de Ic
-.Xf I \\*(Cf \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
-..
-.\"-------
-.\" Bc - Alternate Bold and Courier
-.\"-------
-.de Bc
-.Xf B \\*(Cf \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
-..
-.\"-------
-.\" Cr - Alternate Courier and Roman
-.\"-------
-.de Cr
-.Xf \\*(Cf R \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
-..
-.\"-------
-.\" Ci - Alternate Courier and Italic
-.\"-------
-.de Ci
-.Xf \\*(Cf I \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
-..
-.\"-------
-.\" Cb - Alternate Courier and Bold
-.\"-------
-.de Cb
-.Xf \\*(Cf B \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
-..
-.\"-------
-.\" Xf - Alternate fonts
-.\"
-.\" \$1 - first font
-.\" \$2 - second font
-.\" \$3 - desired word with embedded font changes, built up by recursion
-.\" \$4 - text for first font
-.\" \$5 - \$9 - remaining args
-.\"
-.\" Every time we are called:
-.\"
-.\" If there is something in \$4
-.\" then Call ourself with the fonts switched,
-.\" with a new word made of the current word (\$3) and \$4
-.\" rendered in the first font,
-.\" and with the remaining args following \$4.
-.\" else We are done recursing. \$3 holds the desired output
-.\" word. We emit \$3, change to Roman font, and restore
-.\" the point size to the default.
-.\" fi
-.\"
-.\" Use Xi to add a little bit of space after italic text.
-.\"-------
-.de Xf
-.ds Xi
-.\"-------
-.\" I used to test for the italic font both by its font position
-.\" and its name. Now just test by its name.
-.\"
-.\" .if "\\$1"2" .if !"\\$5"" .ds Xi \^
-.\"-------
-.if "\\$1"I" .if !"\\$5"" .ds Xi \^
-.\"-------
-.\" This is my original code to deal with the recursion.
-.\" Evidently some nroffs can't deal with it.
-.\"-------
-.\" .ie !"\\$4"" \{\
-.\" . Xf \\$2 \\$1 "\\$3\\f\\$1\\$4\\*(Xi" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
-.\" .\}
-.\" .el \{\\$3
-.\" . ft R \" Restore the default font, since we don't know
-.\" . \" what the last font change was.
-.\" . ps 10 \" Restore the default point size, since it might
-.\" . \" have been changed by an argument to this macro.
-.\" .\}
-.\"-------
-.\" Here is more portable (though less pretty) code to deal with
-.\" the recursion.
-.\"-------
-.if !"\\$4"" .Xf \\$2 \\$1 "\\$3\\f\\$1\\$4\\*(Xi" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
-.if "\\$4"" \\$3\fR\s10
-..
-.TH HISTORY 1 "30 July 1991"
-.SH NAME
-\-, \-\|\-, \-p, \-\|\-p \- shell history programs
-.SH SYNOPSIS
-.B \-
-.RI [ pattern ...]
-.RI [ substitution ...]
-.SH DESCRIPTION
-This set of programs provides a crude history mechanism for the shell
-.IR rc (1).
-It is based on the v8 UNIX programs
-.IR = ,
-.IR == ,
-etc.
-.PP
-The program
-.RI `` \- ''
-runs the shell on the command it is requested to find.
-The program
-.RI `` \-\|\- ''
-edits that command first.
-The programs
-.RI `` \-p ''
-and
-.RI `` \-\|\-p ''
-are similar, except that they print the final command on their standard
-output instead of running the shell.
-.PP
-The commands work by looking for a file
-named by the environment variable
-.Cr $history ,
-and by searching for previous commands in this file.
-Old commands can be edited,
-or simply re-executed according to the rules below:
-.PP
-A command is searched for by examining the lines in
-.Cr $history
-in reverse order.
-Lines which contain a previous invocation of the history
-program itself are ignored.
-If one or more
-.I pattern
-is supplied on the command line,
-then the patterns are used as a means of
-limiting the search.
-Patterns match any substring of a previous command,
-and if more than one pattern is present then all patterns must be
-matched before a command is selected.
-.PP
-Substitutions may also be specified on the command line.
-These have the syntax:
-.Ds
-.Ic old : new
-.De
-.PP
-(Note that the
-.I old
-pattern is used as a search-limiting pattern also.)
-Substitutions happen on the first match.
-.PP
-Finally, a command may be edited in a crude line-mode fashion:
-The line to be edited is printed out, and below it the user
-supplies modifications to the command:
-.TP
-.B any character
-Replaces the character above.
-.TP
-.B space or tab
-Skips over the above character(s).
-.TP
-.B #
-Deletes one character.
-.TP
-.B %
-Replaces one character with a space.
-.TP
-.B ^
-Inserts the rest of the typed line just before the character.
-.TP
-.B $
-Deletes the rest of the line from that character on, and replaces
-it with the rest of the typed line.
-.TP
-.B +
-Appends the rest of the typed line.
-.TP
-.B \-
-Backs up to a previous command satisfying the same matching
-constraints.
-.TP
-.B end of file
-If an end-of-file is read from the keyboard by the editor,
-it aborts with exit status 1 and does not produce any output.
-.SH EXAMPLES
-The history programs work best when their output is reinterpreted by
-the shell using an
-.Cr eval
-command.
-This can be achieved by writing a shell function to perform the
-reinterpretation:
-.Ds
-.Cr "fn - -- {"
-.Cr " comm = \`{$0^p $*}"
-.Cr " if (! ~ $#comm 0) {"
-.Cr " echo $comm >[1=2]"
-.Cr " eval $comm"
-.Cr " }"
-.Cr "}"
diff --git a/history/history.c b/history/history.c
deleted file mode 100644
index e6aa29d..0000000
--- a/history/history.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- history.c -- primitive history mechanism
-
- Paul Haahr & Byron Rakitzis, July 1991.
-
- This program mimics the att v8 = and == history programs.
- The edit() algorithm was adapted from a similar program
- that Boyd Roberts wrote, but otherwise all the code has
- been written from scratch.
-
- edit() was subsequently redone by Hugh Redelmeier in order
- to correctly deal with tab characters in the source line.
-
- BUGS:
- There is an implicit assumption that commands are no
- more than 1k characters long.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-static char *id = "@(#) history.c 8/91";
-
-#undef FALSE
-#undef TRUE
-typedef enum { FALSE, TRUE } bool;
-
-#define CHUNKSIZE 65536
-
-static struct {
- char *old, *new;
-} *replace;
-
-static char **search, *progname, *history;
-static char me; /* typically ':' or '-' */
-static bool editit = FALSE, printit = FALSE;
-static int nreplace = 0, nsearch = 0;
-static FILE *fp;
-
-static void *ealloc(size_t n) {
- void *p = (void *) malloc(n);
- if (p == NULL) {
- perror("malloc");
- exit(1);
- }
- return p;
-}
-
-static void *erealloc(void *p, size_t n) {
- p = (void *) realloc(p, n);
- if (p == NULL) {
- perror("realloc");
- exit(1);
- }
- return p;
-}
-
-static char *newstr() {
- return ealloc((size_t)1024);
-}
-
-static char *basename(char *s) {
- char *t = strrchr(s, '/');
- return (t == NULL) ? s : t + 1;
-}
-
-/* stupid O(n^2) substring matching routine */
-
-static char *isin(char *target, char *pattern) {
- size_t plen = strlen(pattern);
- size_t tlen = strlen(target);
- for (; tlen >= plen; target++, --tlen)
- if (strncmp(target, pattern, plen) == 0)
- return target;
- return NULL;
-}
-
-/* replace the first match in the string with "new" */
-static char *sub(char *s, char *old, char *new) {
- char *t, *u;
-
- t = isin(s, old);
- u = newstr();
-
- *t = '\0';
- while (*old != '\0')
- old++, t++;
- strcpy(u, s);
- strcat(u, new);
- strcat(u, t);
- return u;
-}
-
-static char *edit(char *s) {
- char *final, *f, *end;
- int col;
- bool ins;
-
-start:
- fprintf(stderr, "%s\n", s);
- f = final = newstr();
- end = s + strlen(s);
- col = 0;
- ins = FALSE;
-
- for (;; col++) {
- int c = getchar();
-
- if (c == me && col == 0) {
- int peekc = getchar();
- if (peekc == '\n')
- return NULL;
- ungetc(peekc, stdin);
- }
- if (c == '\n') {
- if (col == 0)
- return s;
-
- while (s < end) /* copy remainder of string */
- *f++ = *s++;
- *f = '\0';
- s = final;
- goto start;
- } else if (ins || s>=end) {
- /* col need not be accurate -- tabs need not be interpreted */
- *f++ = c;
- } else {
- switch (c) {
- case '+':
- while (s < end)
- *f++ = *s++;
- *f = '\0';
- continue;
- case '%':
- c = ' ';
- /* FALLTHROUGH */
- default:
- *f++ = c;
- break;
- case EOF:
- exit(1);
- /* NOTREACHED */
- case ' ':
- if (*s == '\t') {
- int oldcol = col;
-
- for (;; col++) {
- int peekc;
-
- if ((col&07) == 07) {
- *f++ = '\t'; /* we spaced past a tab */
- break;
- }
- peekc = getchar();
- if (peekc != ' ') {
- ungetc(peekc, stdin);
- if (peekc != '\n') {
- /* we spaced partially into a tab */
- do {
- *f++ = ' ';
- oldcol++;
- } while (oldcol <= col);
- }
- break;
- }
- }
- } else {
- *f++ = *s;
- }
- break;
- case '#':
- break;
- case '$':
- end = s; /* truncate s */
- continue; /* skip incrementing s */
- case '^':
- ins = TRUE;
- continue; /* skip incrementing s */
- case '\t':
- for (;; col++) {
- if ((*f++ = s<end? *s++ : '\t') == '\t') {
- col = col | 07; /* advance to before next tabstop */
- }
- if ((col&07) == 07) /* stop before tabstop */
- break;
- }
- continue; /* skip incrementing s */
- }
- if (s<end && (*s!='\t' || (col&07)==07))
- s++;
- }
- }
-}
-
-static char *readhistoryfile(char **last) {
- char *buf;
- size_t count, size;
- long nread;
-
- if ((history = getenv("history")) == NULL) {
- fprintf(stderr, "$history not set\n");
- exit(1);
- }
- fp = fopen(history, "r+");
- if (fp == NULL) {
- perror(history);
- exit(1);
- }
-
- size = 0;
- count = 0;
- buf = ealloc(size = CHUNKSIZE);
- while ((nread = fread(buf + count, sizeof (char), size - count, fp)) > 0) {
- count += nread;
- if (size - count == 0)
- buf = erealloc(buf, size *= 4);
- }
- if (nread == -1) {
- perror(history);
- exit(1);
- }
- *last = buf + count;
- return buf;
-}
-
-static char *getcommand() {
- char *s, *t;
- static char *hist = NULL, *last;
-
- if (hist == NULL) {
- hist = readhistoryfile(&last);
- *--last = '\0'; /* trim final newline */
- }
-
-again: s = last;
- if (s < hist)
- return NULL;
- while (*--s != '\n')
- if (s <= hist) {
- last = hist - 1;
- return hist;
- }
- *s = '\0';
- last = s++;
-
- /*
- * if the command contains the "me" character at the start of the line
- * or after any of [`{|()@] then try again
- */
-
- for (t = s; *t != '\0'; t++)
- if (*t == me) {
- char *u = t - 1;
- while (u >= s && (*u == ' ' || *u == '\t'))
- --u;
- if (u < s)
- goto again;
- switch (*u) {
- case '`': case '@':
- case '(': case ')':
- case '{': case '|':
- goto again;
- default:
- break;
- }
- }
- return s;
-}
-
-int main(int argc, char **argv) {
- int i;
- char *s;
-
- s = progname = basename(argv[0]);
- me = *s++;
- if (*s == me) {
- s++;
- editit = TRUE;
- }
- if (*s == 'p') {
- s++;
- printit = TRUE;
- }
-/* Nahh...
- if (*s != '\0') {
- fprintf(stderr, "\"%s\": bad name for history program\n", progname);
- exit(1);
- }
-*/
-
- if (argc > 1) {
- replace = ealloc((argc - 1) * sizeof *replace);
- search = ealloc((argc - 1) * sizeof *search);
- }
- for (i = 1; i < argc; i++)
- if ((s = strchr(argv[i], ':')) == NULL)
- search[nsearch++] = argv[i];
- else {
- *(char *)s = '\0'; /* do we confuse ps too much? */
- replace[nreplace].old = argv[i];
- replace[nreplace].new = s + 1;
- nreplace++;
- }
-
-next: s = getcommand();
- if (s == NULL) {
- fprintf(stderr, "command not matched\n");
- return 1;
- }
- for (i = 0; i < nsearch; i++)
- if (!isin(s, search[i]))
- goto next;
- for (i = 0; i < nreplace; i++)
- if (!isin(s, replace[i].old))
- goto next;
- else
- s = sub(s, replace[i].old, replace[i].new);
- if (editit) {
- s = edit(s);
- if (s == NULL)
- goto next;
- }
- fseek(fp, 0, 2); /* 2 == end of file. i.e., append command to $history */
- fprintf(fp, "%s\n", s);
- fclose(fp);
- if (printit)
- printf("%s\n", s);
- else {
- char *shell = getenv("SHELL");
-
- if (!editit)
- fprintf(stderr, "%s\n", s);
- if (shell == NULL)
- shell = "/bin/sh";
- execl(shell, basename(shell), "-c", s, NULL);
- perror(shell);
- exit(1);
- }
- return 0;
-}