home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-07-13 | 23.4 KB | 1,042 lines |
- Path: uunet!husc6!necntc!ncoast!allbery
- From: tcjones@watdragon.UUCP (Crocodile Dundee)
- Newsgroups: comp.sources.misc
- Subject: e - a friendly interface to vi
- Message-ID: <4848@ncoast.UUCP>
- Date: 13 Oct 87 02:45:52 GMT
- Sender: allbery@ncoast.UUCP
- Organization: U. of Waterloo, Ontario
- Lines: 1029
- Approved: allbery@ncoast.UUCP
- X-Archive: comp.sources.misc/8710/9
-
- here is a little thing i use all the time to get into vi without having
- to type a filename terribly often. all in the name of fewer keystrokes.
- try it.
-
- - terry.
-
-
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- # Contents: README Makefile MANIFEST edoc e.c
-
- echo x - README
- sed 's/^@//' > "README" <<'@//E*O*F README//'
- basically e is a little thingamy to let you get into vi with more ease.
- i find it useful - even given a shell with history. it keeps a short history
- of the files that have been vi'ed most recently in each directory. thus it is
- nice to be able to do
-
- cd somewhere
- e
-
- and get straight into the file you were last working on in the directory
- somewhere.
-
-
- there is some documentation and examples in the file edoc.
- before compiling you should change the
- #define VI "/usr/ucb/vi"
- line in e.c if your vi is located elsewhere.
- and the DEST line in Makefile.
-
- this will run just fine on 4.[23] but i suspect other versions will have
- a little trouble. the readdir/opendir stuff of BSD is used for spelling
- corrections and can be easily rewritten for nonBSD - or you can simply comment
- out the last two functions of e.c [spell_help() and sp_dist()] and all
- references to them at the cost of faster but maybe a less helpful program.
-
- this appears free of major bugs (famous last words) - i'd really like to hear
- about anything that goes wrong &/| fixes/enhancements. comments on what is
- wrong and how it could be better/faster are also welcome...
-
- terry jones
-
-
- ----------------------here's every email address i can find---------------------
- USENET : {ihnp4,allegra,decvax,utzoo,utcsri}!watmath!watdragon!tcjones
- UUCP : {ihnp4,decvax,utzoo}!watmath!watdragon!tcjones
- CSNET : tcjones%watdragon@waterloo.csnet
- ARPA : tcjones%watdragon%waterloo.csnet@csnet-relay.arpa
- Internet: tcjones@er.waterloo.edu
- Bitnet : tcjones@watdragon
- CDNnet : tcjones@er.waterloo.cdn
- from oz : tcjones@er.waterloo.cdn@munnari
-
- SNAIL : Terry Jones/Department of Computer Science
- MAIL /University of Waterloo/Waterloo/Ontario/Canada/N2L 3G1
- PHONENET: 1 519 885-6686 (work?) or 1 519 884-6338 (home)
- --------------------------------------------------------------------------------
- @//E*O*F README//
- chmod u=rw,g=r,o=r README
-
- echo x - Makefile
- sed 's/^@//' > "Makefile" <<'@//E*O*F Makefile//'
- CC = cc
- CFLAGS = -O
- DEST = /u/tcjones/bin/e
- SOURCE = e.c
-
- $(DEST) : $(SOURCE)
-
- $(DEST):
- $(CC) $(CFLAGS) -o $(DEST) $(SOURCE)
- strip $(DEST)
- @//E*O*F Makefile//
- chmod u=rw,g=rx,o=rx Makefile
-
- echo x - MANIFEST
- sed 's/^@//' > "MANIFEST" <<'@//E*O*F MANIFEST//'
- edoc
- e.c
- Makefile
- MANIFEST
- @//E*O*F MANIFEST//
- chmod u=rw,g=r,o=r MANIFEST
-
- echo x - edoc
- sed 's/^@//' > "edoc" <<'@//E*O*F edoc//'
- e is an interface to vi that maintains a history of the most recently e'ed
- files for each directory. it is used with exactly the same syntax etc as vi is.
- a file called .e is kept in each directory. this contains the history and is
- kept to a small length (<10 lines). spelling corrections are suggested for
- simple mistakes (omitted character, interchanged characters, extra character).
- the history file is rearranged with each use to place the last e'ed file at
- the end of the list. duplicate entries are removed (in most situations).
- a list of the command line variations is given below.
-
-
- e [vi's the last file that was e'ed in this directory]
-
- e - [prints the history for this directory and allows selection
- of a previous file - or a new one]
-
- e . [prints the history for this directory without asking for input]
-
- e -t tag [the usual tag entry to vi]
-
- e -r [invokes vi -r]
-
- e -r file [invokes vi -r file]
-
- e -pat [vi's the last file that was e'ed with the string 'pat' on
- the command line]
-
- e +cmd [vi's the last file that was e'ed in this directory but executes
- 'cmd' on the way into vi]
-
- e file [vi's the file and adds it to the history list. minor spelling
- corrections are suggested if 'file' does not exist but is close
- (in spelling) to some file that does]
-
- e files [vi's the files and adds them (as a single entry) to the history]
-
-
- "features".
- ==========
- when using "e -" the terminal is put into cbreak mode. if the first
- character typed is a digit (in the acceptable range of history items)
- then you will get the history item without further ado. thus if you
- have a file called 4play and you try and "e" it from within a "e -"
- then you'll probably end up it the wrong place.
-
- also the history length must be less than or equal to 9 (the code sets
- it to 8 at present (HIST_LINES)). this, i find, is enough but you may want
- more. the problem with having more is that with "e -" you go into cbreak
- and the first digit entered is taken to mean i want the nth last file. this
- saves the need for hitting return. do what you will, but i like it this way.
- with the history being kept as a most recently used list 8 file names
- should be enough.
-
- the numbering on "e -" and "e ." is slightly different. the "e -" option
- is meant so that you can look at the number next to the file name and hit
- it easily. with "e ." you see what files you would get if you did a "e -3" (etc)
- and so it makes sense that "e -1" should give the second last file. that way you
- can pop in and out of two files by repeated "e -1"'s (if you don't do ctrl-^).
- once again, that's the way it is...
-
- examples.
- =========
- with a ".e" file containing
-
- fred.c [5]: fred.c
- jane [4]: jane
- alison "e ." will give [3]: alison
- +/main pete.c [2]: +/main pete.c
- bigmac [1]: bigmac
- fries juice [0]: fries juice
-
- so "e" will get you fries and then juice.
- "e -" will present the above and ask for a number (RETURN=0).
- "e -ali" will get you alison.
- "e +/ketchup" will get you fries and juice, searching for ketchup in fries.
- "e bigamc" will ask if you want to correct to bigmac. n or N
- will do the correction, q or Q will quit, anything else will go ahead.
-
-
- to be added?
- ============
- allow backspacing on a select line.
- uncompress and recompress .Z files automatically?
- plenty of fancy things
- a man page
- @//E*O*F edoc//
- chmod u=rw,g=rx,o=rx edoc
-
- echo x - e.c
- sed 's/^@//' > "e.c" <<'@//E*O*F e.c//'
- /*
- * e.c - a friendly interface to vi
- *
- * Terry Jones {ihnp4,allegra,decvax,utzoo,utcsri}!watmath!watdragon!tcjones
- * Department of Computer Science
- * University of Waterloo
- * Waterloo, Ontario, Canada. N2L 3G1
- *
- *
- * best vi'ed with ts=4 sw=4
- * to compile: cc -o e -O e.c
- */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/file.h>
- #include <sys/dir.h>
- #include <sys/inode.h>
- #include <sgtty.h>
- #include <strings.h>
- #include <signal.h>
- #include <ctype.h>
-
- #define VI "/usr/ucb/vi"
- #define HIST ".e"
- #define HIST_LINES 8
- #define HIST_CHARS 512
- #define ARG_CHARS 100
- #define MAX_ARGS 10
- #define RUBOUT '\077'
-
- char history[HIST_CHARS];
- char arg[ARG_CHARS];
- char *hist[HIST_LINES];
- char temp[HIST_CHARS];
- char *tmp_file="._vihistXXXXXX";
-
- void
- do_vi(thing)
- char *thing;
- {
- /* split the arguments in 'thing' up and exec vi on them */
- char *args[MAX_ARGS];
- char *this,*next;
- register i;
-
- args[0]=VI;
- args[1]=thing;
-
- i=1;
- while (*thing!='\0'&&(thing=index(thing,' '))!=NULL){
- *thing++='\0';
- if (*thing!='\0'){
- args[++i]=thing;
- }
- }
- args[++i]=NULL;
-
- if (execvp(VI,args)==-1){
- perror(VI);
- exit(1);
- }
- }
-
- main(c,v)
- int c;
- char **v;
- {
- char *last_file();
- extern clean_up();
-
- /* make sure we reset the terminal on our way out if we get interrupted */
- if (signal(SIGINT, SIG_IGN) != SIG_IGN){
- signal(SIGINT, clean_up);
- }
-
- switch (c){
- case 1:
- /* just go and vi the last file that was vi'ed */
- last_file();
- do_vi(arg);
- break;
-
- case 2:
- switch ((*++v)[0]){
- case '-':
- if ((c=(*v)[1])=='\0'){
- /* this is a select from history, ask what they want */
- ask_hist();
- do_vi(arg);
- }
- else if (isdigit(c)){
- /* get the nth last file from the history and vi it */
- nth_hist(c-'0');
- do_vi(arg);
- }
- else if (c=='t'&&(*v)[2]=='\0'){
- /* this is an empty tag - ignore it */
- do_vi(*v);
- }
- else if (c=='r'&&(*v)[2]=='\0'){
- /* a recover, just pass it to vi and don't interfere */
- do_vi(*v);
- }
- else{
- /* this is a pattern - try to match it */
- find_match(++*v);
- do_vi(arg);
- }
- break;
-
- case '+':
- /* a command, put it before the last file name etc */
- insert_command(*v);
- do_vi(arg);
- break;
-
- case '.':
- /* just give a history list if there is only a dot */
- if ((*v)[1]=='\0'){
- register ct;
- register i;
-
- read_hist();
- ct=split_hist();
-
- for (i=0;i<ct;i++){
- fprintf(stderr,"\t[%d]: %s\n",ct-i-1,hist[ct-i-1]);
- }
- exit(0);
- }
- /*
- WARNING!
- the switch falls through in the case where there is a
- pattern that starts with a period
- */
-
- default :
- /* looks like it's just a plain old file name. vi it! */
- normal(*v);
- do_vi(arg);
- break;
- }
- default:
- /* a bunch of arguments, fix the history & vi them all as normal */
- multiple(c,v);
- do_vi(arg);
- break;
- }
- }
-
-
-
- read_hist()
- {
- /*
- read the history file and break it up into lines in the global variable
- 'history'. do the appropriate checks to see that it exists etc...
- */
-
- register vh;
- register bytes;
- register offset;
- struct stat buf;
-
- /*
- if there is no history file then say so and get out of here - they
- had nobusiness asking for access to the history
- */
- if ((vh=open(HIST,O_RDONLY))==-1){
- perror(HIST);
- exit(1);
- }
-
- /* stat it */
- if (fstat(vh,&buf)==-1){
- perror(HIST);
- exit(1);
- }
-
- /*
- set 'offset' so that we can read the last portion of the history
- file only. if there are less than HIST_CHARS characters in the
- file then we will start reading at 0, otherwise at HIST_CHARS
- characters before the end of the file.
- */
- offset=(int)buf.st_size-HIST_CHARS<0 ? 0 : buf.st_size-HIST_CHARS;
-
- /* move to that place in the file */
- if (lseek(vh,(long)offset,L_SET)==-1){
- perror(HIST);
- exit(1);
- }
-
- /* and READ! */
- if ((bytes=read(vh,history,HIST_CHARS))==-1){
- perror(HIST);
- exit(1);
- }
-
- /* if we didn't come up with ANYTHING we may as well leave */
- if (!bytes){
- fprintf(stderr,"Empty %s file.\n",HIST);
- exit(1);
- }
-
- /* zap the newline (which should be there) for now */
- if (history[--bytes]=='\n'){
- history[bytes]='\0';
- }
-
- /* and get out of here */
- return(bytes);
- }
-
- char *
- last_file()
- {
- /*
- get the last name from the 'history' array and put it into 'arg'
- */
-
- read_hist();
- if (index(history,'\n')==NULL){
- if (*history=='\0'){
- fprintf(stderr,"%s: badly formatted.\n",HIST);
- exit(1);
- }
- else{
- sprintf(arg,"%s",history);
- }
- }
- else{
- sprintf(arg,"%s",rindex(history,'\n')+1);
- }
- }
-
- split_hist()
- {
- /*
- set the array of pointers in 'hist' to point to the succesive names
- in the 'history' array. these are delimited (presumably) by newlines
- and so they're easy to catch...
-
- what in fact is done is that the history array is copied and we set
- the pointers up and set the newlines to be '\0' s. this way we don't
- mess up the history array as we will want it intact later on (maybe).
- */
-
- char *tmp;
- register count;
-
- /* copy it */
- sprintf(temp,"%s",history);
-
- /*
- now run through breaking it up, setting pointers and return the number
- of lines we found.
- */
- for (count=0;count<HIST_LINES;count++){
- if ((tmp=hist[count]=rindex(temp,'\n'))==NULL){
- break;
- }
- *tmp='\0';
- hist[count]++;
- }
- if (count<HIST_LINES){
- hist[count++]=temp;
- }
- return(count);
- }
-
- nth_hist(n)
- int n;
- {
- /*
- get the nth last filename from the list. make use (of course) of
- read_hist and split_hist.
- */
- register count;
- register i;
-
- read_hist();
- count=split_hist();
- if (n>count-1){
- if (count>1){
- fprintf(stderr,"Only %d history items exist.\n",count);
- }
- else{
- fprintf(stderr,"Only one history item exists.\n");
- }
- exit(1);
- }
- sprintf(arg,"%s",hist[n]);
-
- /* rebuild the history with the selected name at the bottom */
- reconstruct(n,count);
- }
-
- ask_hist()
- {
- /*
- ask the outside world which of the files in the history is wanted.
- set the terminal to cbreak.
- */
- register i;
- register count;
- char *last;
- register option;
- struct sgttyb blk;
-
- /* read and split the history file */
- read_hist();
- count=split_hist();
-
- /* print the history */
- for (i=0;i<count;i++){
- fprintf(stderr,"\t[%d]: %s\n",count-i,hist[count-i-1]);
- }
-
- /* give them a prompt (of sorts) */
- fprintf(stderr,"select -> ");
-
- /* set the terminal up */
- set_term();
-
- /* get their response */
- option=getc(stdin);
-
- /* make the terminal 'safe' again */
- unset_term();
-
- /*
- process the option and put the appropriate file name into the
- arg variable.
- */
- if (option=='\n'){
- /* they want the last file of the list */
- fprintf(stderr,"%s\n",hist[0]);
- sprintf(arg,"%s",hist[0]);
- return;
- }
- else if (option==RUBOUT){
- /* they want to leave */
- fprintf(stderr,"\n");
- exit(1);
- }
- else if (option>='1'&&option<='0'+count){
- /* they have requested a file by it's number */
- option=option-'0';
- fprintf(stderr,"%s\n",hist[option-1]);
- sprintf(arg,"%s",hist[option-1]);
- }
- else{
- /*
- looks like they want to name a specific file. echo the
- characters back to the screen.
- */
- fprintf(stderr,"%c",option);
- arg[0]=option;
- i=1;
- while ((arg[i]=getc(stdin))!='\n'){
- i++;
- }
- arg[i]='\0';
- option=count-1; /* a kludge for the history re-make to follow */
-
- /* seeing as they typed in the name, try and help with spelling */
- spell_help();
- }
-
- /* rebuild the history with the selected name at the bottom */
- reconstruct(option-1,count);
- }
-
- FILE *
- get_temp()
- {
- /* get ourselves a temporary file for the reconstructed history */
- FILE *fp,*fopen();
-
- mktemp(tmp_file);
- if ((fp=fopen(tmp_file,"w"))==NULL){
- perror(tmp_file);
- exit(1);
- }
- return(fp);
- }
-
- close_temp(fp)
- FILE *fp;
- {
- /* move the temporary file to be the new history */
- FILE *fclose();
-
- if (fclose(fp)==(FILE *)EOF){
- fprintf(stderr,"Could not close %s\n",tmp_file);
- exit(1);
- }
-
- if (rename(tmp_file,HIST)!=0){
- perror("rename");
- exit(1);
- }
- }
-
- set_term()
- {
- /* go into cbreak and no echo mode */
- struct sgttyb blk;
-
- gtty(0, &blk);
- blk.sg_flags |= CBREAK;
- blk.sg_flags ^= ECHO;
- stty(0, &blk);
- }
-
- unset_term()
- {
- /* get out of cbreak and no echo */
- struct sgttyb blk;
-
- gtty(0, &blk);
- blk.sg_flags &= ~CBREAK;
- blk.sg_flags ^= ECHO;
- stty(0, &blk);
- }
-
- match(argument,pattern)
- char *argument;
- char *pattern;
- {
- /*
- boneheaded but easy pattern matcher. just see if the 'pattern'
- exists anywhere in the 'argument'. boyer-moore who?
- */
- register length=strlen(pattern);
-
- while (strlen(argument)>=length){
- if (!strncmp(argument++,pattern,length)){
- return(1);
- }
- }
- return(0);
- }
-
- find_match(pattern)
- char *pattern;
- {
- /*
- find the name in the history list that contains the 'pattern'.
- if it exists then put it into the 'arg' variable and otherwise
- announce that a match couldn't be found and leave.
- */
- register count;
- register i;
-
- /* read and split the history file */
- read_hist();
- count=split_hist();
-
- /* try for a match with each file in turn (note that we are working
- from most-recently-used backwards - probably a good thing)
- */
- for (i=0;i<count;i++){
- if (match(hist[i],pattern)){
- sprintf(arg,"%s",hist[i]);
- reconstruct(i,count);
- return;
- }
- }
-
- /* we couldn't match so get out of here */
- fprintf(stderr,"Unable to match with \"%s\"\n",pattern);
- exit(1);
- }
-
- insert_command(command)
- char *command;
- {
- /*
- they want the last file in the history but want to preceed it
- this time with a command - no problems here.
- */
- register count;
- char *place;
-
- /* read and split the history */
- read_hist();
- count=split_hist();
-
- /*
- if there was already a command there (indicated by a '+') then we
- want to get rid of it. if there is a '+' but no ' ' after it then
- the history file is in disarray and we will not try to recover
- */
- if (*hist[0]=='+'){
- if ((place=index(hist[0],' '))==NULL){
- fprintf("Serious weirdenss in insert_command\n");
- exit(1);
- }
- /* move over white space - if there is any */
- while (*place==' '||*place=='\t'){
- place++;
- }
- }
- else{
- /* there was no command preceeding the last file in the history */
- place=hist[0];
- }
-
- /* put the new command and the filename into 'arg' */
- sprintf(arg,"%s %s",command,place);
-
- /* rebuild the history with the selected command and name at the bottom */
- reconstruct(0,count);
- }
-
- reconstruct(except,count)
- int except;
- int count;
- {
- /*
- reconstruct history file excepting the 'except' last.
- so just copy all lines but the 'except'th last and then put in 'arg'
- which contains the new line for the history
- */
- register i;
- FILE *tv,*get_temp();
-
- /* get a temporary file */
- tv=get_temp();
-
- /* put in the line we still want */
- for (i=count-1;i>=0;i--){
- if (i!=except){
- fprintf(tv,"%s\n",hist[i]);
- }
- }
-
- /* put in the new line from 'arg' */
- fprintf(tv,"%s\n",arg);
-
- /* rename the temporary to be the new history file */
- close_temp(tv);
- }
-
- normal(string)
- char *string;
- {
- /*
- a normal filename was found, put it into arg. first of all if there
- is a history and the file is already in it (which means they could
- have gotten to this file in other ways), then reconstruct the history
- as though they had. also offer spelling help.
- */
- register count;
- register i;
-
- /* put it into 'arg' */
- sprintf(arg,"%s",string);
-
- /* if there is a history file */
- if (got_vi()){
-
- /* read it and split it up */
- read_hist();
- count=split_hist();
-
- /* if it is in the history then reconstruct and return */
- for (i=0;i<count;i++){
- if (!strcmp(hist[i],arg)){
- reconstruct(i,count);
- return;
- }
- }
-
- /* it's not in the history, help with spelling then reconstruct */
- spell_help();
- reconstruct(HIST_LINES,count);
- }
- else{
-
- /*
- there is no history around so help with spelling and set up a
- history for next time.
- */
- spell_help();
- new_vi();
- }
-
- }
-
- multiple(number, args)
- int number;
- char **args;
- {
- /*
- there were several names on the command line so we just strcat them
- into the 'arg' array.
- */
- register count;
- register i;
-
- *arg='\0';
- while (--number){
- strcat(arg,*++args);
- if (number>1){
- strcat(arg," ");
- }
- }
-
- /*
- now if there is a history file and we can find an identical line
- then reconstruct with that line at the bottom.
- */
- if (got_vi()){
- read_hist();
- count=split_hist();
- for (i=0;i<count;i++){
- if (!strcmp(hist[i],arg)){
- reconstruct(i,count);
- return;
- }
- }
- /*
- rebuild, including everything but the counth last (i.e. make
- a new history by omitting the oldest file in the current one and
- putting 'arg' on the end.
- */
- reconstruct(HIST_LINES,count);
- }
- else{
- /* there was no history file so try to give them one for next time */
- new_vi();
- }
- }
-
- got_vi()
- {
- /* indicate if there is a history file that they own or otherwise */
- struct stat buf;
-
- if (stat(HIST,&buf)==-1){
- return(0);
- }
- else{
- return(getuid()==buf.st_uid);
- }
- }
-
- new_vi()
- {
- /* attempt to make a new history file - several things could go wrong */
- FILE *vh,*fopen(),*fclose();
- struct stat buf;
-
- /* if you can't read the current directory, get out */
- if (stat(".",&buf)==-1){
- perror("stat");
- exit(1);
- }
-
- /* if you own the directory (you can't normally get a history in /tmp) */
- if (getuid()==buf.st_uid){
-
- /* if we can't make a history, get out */
- if ((vh=fopen(HIST,"w"))==NULL){
- perror(HIST);
- exit(1);
- }
-
- /* put in the 'arg' that we will be vi'ing in a second */
- fprintf(vh,"%s\n",arg);
-
- /* close the history */
- if (fclose(vh)==(FILE *)EOF){
- fprintf(stderr,"Could not close %s\n",VI);
- exit(1);
- }
-
- /* give the history some protection - for those who want it! */
- if (chmod(HIST,IREAD|IWRITE)==-1){
- perror("chmod");
- exit(1);
- }
- }
- }
-
- clean_up()
- {
- /* just get out after making sure things are tidy */
- fprintf(stderr,"Interrupt.\n");
- unlink(tmp_file);
- unset_term();
- exit(1);
- }
-
- spell_help()
- {
- /*
- unashamedly stolen (and modified) from "The UNIX Programming
- Environment" - Kernighan and Pike
-
- read the directory and if the file they want (in 'arg') does not
- exist then see if there is one that does that has similar spelling
- to what they requested. offer the change and handle the reply.
- */
-
- char new[ARG_CHARS];
- register dist=3;
- register new_dist;
- DIR *dp, *opendir();
- struct direct *readdir();
- struct direct *entry;
- register len;
- struct stat buf;
-
- /* if the file already exists just return - they don't need help */
- if (stat(arg,&buf)==0){
- return;
- }
-
- /* if the current directory can't be read then return */
- if ((dp=opendir("."))==NULL){
- return;
- }
-
- /* get the length of what we are seeking to cut down on strcmping time */
- len=strlen(arg);
-
- for (entry=readdir(dp);entry!=NULL;entry=readdir(dp)){
-
- /* if this entry has length = sought length +/- 1 then it may be ok */
- if (entry->d_ino&&entry->d_namlen>=len-1&&entry->d_namlen<=len+1){
-
- /* get the 'distance' between what we want and this file name */
- new_dist=sp_dist(entry->d_name,arg);
-
- /* if this name is close enough and better than our current best */
- if (new_dist<=dist&&new_dist!=3){
-
- if (!new_dist){
- /* if the dist is 0 then they are identical */
- closedir(dp);
- return;
- }
- /* remember the new name and distance */
- strcpy(new,entry->d_name);
- dist=new_dist;
- }
- }
- }
-
- /* close up. if we got no suitable result then simply return */
- closedir(dp);
- if (dist==3){
- return;
- }
-
- /* offer them "new" */
- set_term();
- fprintf(stderr,"correct to %s [y]? ",new);
-
- /* process the reply */
- switch (getc(stdin)){
- case 'N':
- case 'n':
- fprintf(stderr,"no\n");
- break;
- case 'q':
- case 'Q':
- fprintf(stderr,"quit\n");
- unset_term();
- exit(0);
- break;
- default :
- fprintf(stderr,"yes\n");
- strcpy(arg,new);
- }
- unset_term();
- }
-
- sp_dist(s,t)
- char *s;
- char *t;
- {
- /*
- stolen from the same place as spell_help() above.
-
- work out the distance between the strings 's' and 't' according
- to the rough metric that
-
- identical = 0
- interchanged characters = 1
- wrong character/extra character/missing character = 2
- forget it = 3
- */
-
- while (*s++==*t){
- if (*t++=='\0'){
- /* identical */
- return(0);
- }
- }
-
- if (*--s){
- if (*t){
- if (s[1]&&t[1]&&*s==t[1]&&*t==s[1]&&!strcmp(s+2,t+2)){
- /* interchanged chars */
- return(1);
- }
- if (!strcmp(s+1,t+1)){
- /* wrong char */
- return(2);
- }
- }
- if (!strcmp(s+1,t)){
- /* extra char in 't' */
- return(2);
- }
- }
- if (!strcmp(s,t+1)){
- /* extra char in 's' */
- return(2);
- }
-
- /* forget it */
- return(3);
- }
- @//E*O*F e.c//
- chmod u=rw,g=rx,o=rx e.c
-
- echo Inspecting for damage in transit...
- temp=/tmp/shar$$; dtemp=/tmp/.shar$$
- trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
- cat > $temp <<\!!!
- 45 262 1867 README
- 10 23 141 Makefile
- 4 4 27 MANIFEST
- 84 627 3415 edoc
- 831 2311 16691 e.c
- 974 3227 22141 total
- !!!
- wc README Makefile MANIFEST edoc e.c | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
- if [ -s $dtemp ]
- then echo "Ouch [diff of wc output]:" ; cat $dtemp
- else echo "No problems found."
- fi
- exit 0
-
- ZZ
-