home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char RCSid[] = "$Header: edit.c,v 1.3 86/07/11 15:11:34 osadr Exp $";
- #endif
-
- /*
- * $Log: edit.c,v $
- * Revision 1.3 86/07/11 15:11:34 osadr
- * Removed Georgia Tech specific code.
- *
- * Revision 1.2 86/05/27 17:44:56 osadr
- * Removed flexnames dependancy; PREVLINE[2] --> PREVLN[2].
- * Improved the sysname() routine, particularly to use the nodename
- * member of the utsname structure under System V.
- *
- * Revision 1.1 86/05/06 13:37:16 osadr
- * Initial revision
- *
- *
- */
-
- /*
- ** edit.c
- **
- ** editor main routine, plus other routines used a lot.
- */
-
- #include "se.h"
- #include "extern.h"
-
- static char Savknm = DEFAULTNAME; /* saved mark name for < and > */
-
- /* edit --- main routine for screen editor */
-
- edit (argc, argv)
- int argc;
- char *argv[];
- {
- int cursav, status, len, cursor;
- int ckglob (), docmd (), doglob (), doread ();
- int getlst (), nextln (), prevln ();
- char lin[MAXLINE], term;
-
- watch (); /* display time of day */
-
- #ifdef LOG_USAGE
- log (); /* log who used the program */
- #endif
-
- serc (); /* execute commands in ./.serc or $HOME/.serc */
-
- status = OK;
-
- while (status == OK && Argno < argc)
- {
- strcpy (lin, argv[Argno]);
- loadstr (lin, Argno, POOPCOL, Ncols);
- if (lin[0] == '-')
- {
- len = strlen (lin) + 1;
- lin[len - 1] = '\n';
- lin[len] = EOS;
- len = 0;
- status = doopt (lin, &len);
- }
- else
- {
- dfltsopt (lin);
- status = doread (Lastln, lin, NO);
- }
- Argno++;
- }
-
- if (status == ERR)
- {
- if (Errcode == EHANGUP)
- hangup ();
- printverboseerrormessage ();
- }
- else
- Curln = min (1, Lastln);
-
- Buffer_changed = NO;
- First_affected = 1; /* maintained by updscreen & commands */
- updscreen ();
-
- if (status != ERR) /* leave offending file name or option */
- lin[0] = EOS;
- cursor = 0;
-
- /* main command loop */
- do {
- intrpt (); /* discard pending breaks (interrupts) */
- if (Lost_lines > GARB_THRESHOLD
- && (Lastln + Limcnt) / Lost_lines <= GARB_FACTOR)
- garbage_collect ();
-
- mswait (); /* check for pending messages */
- Cmdrow = Botrow + 1; /* reset the command line location */
- prompt ("cmd>");
- getcmd (lin, 0, &cursor, &term);
- remark (""); /* clear out any error messages */
-
- while (term == CURSOR_UP || term == CURSOR_DOWN
- || term == CURSOR_SAME)
- {
- switch (term) {
- case CURSOR_UP:
- if (Curln > 1)
- Curln--;
- else
- Curln = Lastln;
- break;
-
- case CURSOR_DOWN:
- if (Curln < Lastln)
- Curln++;
- else
- Curln = min (1, Lastln);
- break;
- }
- adjust_window (Curln, Curln);
- updscreen ();
- getcmd (lin, 0, &cursor, &term);
- }
-
- prompt (""); /* remove prompt */
-
- cursav = Curln; /* remember it in case of an error */
- Errcode = EEGARB; /* default error code for garbage at end */
-
- len = 0;
- if (getlst (lin, &len, &status) == OK)
- {
- if (ckglob (lin, &len, &status) == OK)
- doglob (lin, &len, &cursav, &status);
- else if (status != ERR)
- docmd (lin, len, NO, &status);
- }
- if (status == ERR)
- {
- if (Errcode == EHANGUP)
- hangup ();
- printverboseerrormessage ();
- Curln = min (cursav, Lastln);
- }
- else if (term != FUNNY)
- {
- cursor = 0;
- lin[0] = EOS;
- }
-
- adjust_window (Curln, Curln);
- updscreen ();
-
- } while (status != EOF);
-
- clrscreen ();
- clrbuf ();
- tflush ();
-
- return;
- }
-
-
- /* getlst --- collect line numbers (if any) at lin[*i], increment i */
-
- int getlst (lin, i, status)
- char lin[];
- int *i, *status;
- {
- int num;
- int getone ();
-
- Line2 = 0;
- for (Nlines = 0; getone (lin, i, &num, status) == OK; )
- {
- Line1 = Line2;
- Line2 = num;
- Nlines++;
- if (lin[*i] != ',' && lin[*i] != ';')
- break;
- if (lin[*i] == ';')
- Curln = num;
- (*i)++;
- }
-
- if (Nlines > 2)
- Nlines = 2;
-
- if (Nlines <= 1)
- Line1 = Line2;
-
- if (Line1 > Line2)
- {
- *status = ERR;
- Errcode = EBACKWARD;
- }
-
- if (*status != ERR)
- *status = OK;
-
- return (*status);
- }
-
-
- /* getnum --- convert one term to line number */
-
- int getnum (lin, i, pnum, status)
- char lin[];
- register int *i, *pnum, *status;
- {
- int j, ret;
- int ctoi (), optpat (), ptscan (), knscan (), getkn ();
- int k;
-
- ret = OK;
- SKIPBL (lin, *i);
- if (lin[*i] >= Rel_a && lin[*i] <= Rel_z && Absnos == NO)
- *pnum = Topln - Toprow + lin[*i] - Rel_a;
- else if (lin[*i] == CURLINE)
- *pnum = Curln;
- else if (lin[*i] == PREVLN || lin[*i] == PREVLN2)
- *pnum = Curln - 1;
- else if (lin[*i] == LASTLINE)
- *pnum = Lastln;
- else if (lin[*i] == SCAN || lin[*i] == BACKSCAN)
- {
- int missing_delim = YES;
-
- /* see if trailing delim supplied, since command can follow pattern */
- for (k = *i + 1; lin[k] != EOS; k++)
- if (lin[k] == ESCAPE)
- k++; /* skip esc, loop will skip escaped char */
- else if (lin[k] == lin[*i])
- {
- missing_delim = NO;
- break;
- }
- /* else
- continue */
-
- if (missing_delim == YES)
- {
- for (; lin[k] != EOS; k++)
- ;
- k--; /* k now at newline */
-
- /* supply trailing delim */
- lin[k] = lin[*i];
- lin[++k] = '\n';
- lin[++k] = EOS;
- Peekc = SKIP_RIGHT;
- }
-
- if (optpat (lin, i) == ERR)
- ret = ERR;
- else if (lin[*i] == SCAN)
- ret = ptscan (FORWARD, pnum);
- else
- ret = ptscan (BACKWARD, pnum);
- }
- else if (lin[*i] == SEARCH || lin[*i] == BACKSEARCH)
- {
- j = *i;
- (*i)++;
- if (getkn (lin, i, &Savknm, Savknm) == ERR)
- ret = ERR;
- else if (lin[j] == SEARCH)
- ret = knscan (FORWARD, pnum);
- else
- ret = knscan (BACKWARD, pnum);
- (*i)--;
- }
- else if (isdigit (lin[*i]))
- {
- *pnum = ctoi (lin, i);
- (*i)--;
- }
- else if (lin[*i] == TOPLINE)
- *pnum = Topln;
- else
- ret = EOF;
-
- if (ret == OK)
- (*i)++;
- *status = ret;
- return (ret);
- }
-
-
- /* getone --- evaluate one line number expression */
-
- int getone (lin, i, num, status)
- char lin[];
- register int *i, *num, *status;
- {
- int pnum, ret;
- int getnum ();
- char porm; /* "plus or minus" (sic) */
-
- ret = EOF; /* assume we won't find anything for now */
- *num = 0;
-
- if (getnum (lin, i, num, status) == OK) /* first term */
- {
- ret = OK; /* to indicate we've seen something */
- do { /* + or - terms */
- porm = EOS;
- SKIPBL (lin, *i);
- if (lin[*i] == '-' || lin[*i] == '+')
- {
- porm = lin[*i];
- (*i)++;
- }
- if (getnum (lin, i, &pnum, status) == OK)
- if (porm == '-')
- *num -= pnum;
- else
- *num += pnum;
- if (*status == EOF && porm != EOS) /* trailing + or - */
- *status = ERR;
- } while (*status == OK);
- }
-
- if (*num < 0 || *num > Lastln) /* make sure number is in range */
- {
- *status = ERR;
- Errcode = EORANGE;
- }
-
- if (*status == ERR)
- ret = ERR;
- else
- *status = ret;
-
- return (ret);
- }
-
-
- #ifndef OLD_SCRATCH
- #ifndef OLD_GLOB
- static int special_casing = NO;
- #endif
- #endif
-
- /* ckglob --- if global prefix, mark lines to be affected */
-
- int ckglob (lin, i, status)
- char lin[];
- int *i, *status;
- {
- register int line, tmp;
- int usepat, usemark;
- int defalt (), match (), optpat (), getkn ();
- register LINEDESC *k;
- LINEDESC *gettxt (), *getind ();
-
- *status = OK;
- usepat = EOF;
- usemark = EOF;
-
- #ifndef OLD_SCRATCH
- #ifndef OLD_GLOB
- if ( /* g/^/m0 or g/$/m0 -- special case the pathological */
- /* cases in order to save time */
- (lin[*i] == GLOBAL || lin[*i] == UCGLOBAL)
- && (lin[*i + 1] == lin[*i + 3])
- && (lin[*i + 2] == '^' || lin[*i + 2] == '$')
- && (lin[*i + 4] == MOVECOM || lin[*i + 4] == UCMOVECOM)
- && (lin[*i + 5] == '0' && lin[*i + 6] == '\n') )
- {
- special_casing = YES;
- remark ("GLOB");
- return (OK);
- }
- #endif
- #endif
- if (lin[*i] == GMARK || lin[*i] == XMARK) /* global markname prefix? */
- {
- if (lin[*i] == GMARK) /* tag lines with the specified markname */
- usemark = YES;
- else /* tag lines without the specified markname */
- usemark = NO;
- (*i)++;
- *status = getkn (lin, i, &Savknm, Savknm);
- }
-
- if (*status == OK) /* check for a pattern prefix too */
- {
- if (lin[*i] == GLOBAL || lin[*i] == UCGLOBAL)
- usepat = YES;
-
- if (lin[*i] == EXCLUDE || lin[*i] == UCEXCLUDE)
- usepat = NO;
-
- if (usepat != EOF)
- {
- (*i)++;
- if (optpat (lin, i) == ERR)
- *status = ERR;
- else
- (*i)++;
- }
- }
-
- if (*status == OK && usepat == EOF && usemark == EOF)
- *status = EOF;
- else if (*status == OK)
- defalt (1, Lastln);
-
- if (*status == OK) /* no errors so far, safe to proceed */
- {
- remark ("GLOB");
-
- k = Line0; /* unmark all lines preceeding range */
- for (line = 0; line < Line1; line++)
- {
- k -> Globmark = NO;
- k = NEXTLINE(k);
- }
-
- for (; line <= Line2; line++) /* mark lines in range */
- {
- if (intrpt ())
- {
- *status = ERR;
- return (*status);
- }
- tmp = NO;
- if (usemark == EOF
- || usemark == YES && k -> Markname == Savknm
- || usemark == NO && k -> Markname != Savknm)
- {
- if (usepat == EOF) /* no global pattern to look for */
- tmp = YES;
- else /* there is also a pattern to look for */
- {
- gtxt (k);
- if (match (Txt, Pat) == usepat)
- tmp = YES;
- }
- }
-
- k -> Globmark = tmp;
-
- k = NEXTLINE(k);
- }
-
- #ifdef OLD_SCRATCH
- /* mark remaining lines */
- for (; k != Line0; k = k -> Nextline)
- k -> Globmark = NO;
- #else
- /* mark remaining lines */
- for (; line <= Lastln; line++)
- {
- k -> Globmark = NO;
- k = NEXTLINE (k);
- }
- #endif
-
- remark ("");
- }
-
- return (*status);
- }
-
-
- /* doglob --- do command at lin[i] on all marked lines */
-
- int doglob (lin, i, cursav, status)
- char lin[];
- int *i, *cursav, *status;
- {
- register int istart, line;
- int docmd (), getlst (), nextln ();
- register LINEDESC *k;
- LINEDESC *getind ();
-
- #ifndef OLD_SCRATCH
- #ifndef OLD_GLOB
- if (special_casing)
- {
- /*
- remark ("Warp 7, Captain!");
- */
- /* not on the screen too long anyway */
- reverse (1, Lastln);
- Curln = Lastln;
- special_casing = NO;
- Buffer_changed = YES;
- First_affected = min (1, First_affected);
- remark ("");
- adjust_window (Curln, Curln);
- updscreen ();
- return (OK);
- }
- #endif
- #endif
- *status = OK;
- istart = *i;
- k = Line0;
- line = 0;
-
- do {
- line++;
- k = NEXTLINE(k);
- if (k -> Globmark == YES) /* line is marked */
- {
- k -> Globmark = NO; /* unmark the line */
- Curln = line;
- *cursav = Curln; /* remember where we are */
- *i = istart;
- if (getlst (lin, i, status) == OK)
- docmd (lin, *i, YES, status);
- line = 0; /* lines may have been moved */
- k = Line0;
- }
- if (intrpt ())
- *status = ERR;
- } while (line <= Lastln && *status == OK);
-
- return (*status);
- }
-
-
- /* ckchar --- look for ch or altch on lin at i, set flag if found */
-
- int ckchar (ch, altch, lin, i, flag, status)
- char ch, altch, lin[];
- int *i, *flag, *status;
- {
-
- if (lin[*i] == ch || lin[*i] == altch)
- {
- (*i)++;
- *flag = YES;
- }
- else
- *flag = NO;
-
- *status = OK;
- return (OK);
- }
-
-
- /* ckp --- check for "p" after command */
-
- int ckp (lin, i, pflag, status)
- char lin[];
- int i, *pflag, *status;
- {
-
- if (lin[i] == PRINT || lin[i] == UCPRINT)
- {
- i++;
- *pflag = YES;
- }
- else
- *pflag = NO;
-
- if (lin[i] == '\n')
- *status = OK;
- else
- *status = ERR;
-
- return (*status);
- }
-
-
- /* ckupd --- make sure it is ok to destroy the buffer */
-
- int ckupd (lin, i, cmd, status)
- char lin[], cmd;
- int *i, *status;
- {
- int flag;
- int ckchar ();
-
- *status = ckchar (ANYWAY, ANYWAY, lin, i, &flag, status);
- if (flag == NO && Buffer_changed == YES && Probation != cmd)
- {
- *status = ERR;
- Errcode = ESTUPID;
- Probation = cmd; /* if same command is repeated, */
- } /* we'll keep quiet */
-
- return (*status);
- }
-
-
- /* defalt --- set defaulted line numbers */
-
- defalt (def1, def2)
- int def1, def2;
- {
-
- if (Nlines == 0) /* no line numbers supplied, use defaults */
- {
- Line1 = def1;
- Line2 = def2;
- }
-
- return;
- }
-
-
- /* getfn --- get file name from lin[i]... */
-
- int getfn (lin, i, file)
- char lin[], file[];
- int i;
- {
- int j, k, ret;
-
- ret = ERR;
- if (lin[i + 1] == ' ')
- {
- j = i + 2; /* get new file name */
- SKIPBL (lin, j);
- for (k = 0; lin[j] != NEWLINE; k++, j++)
- file[k] = lin[j];
- file[k] = EOS;
- if (k > 0)
- ret = OK;
- }
- else if (lin[i + 1] == '\n' && Savfil[0] != EOS)
- {
- strcpy (file, Savfil); /* or old name */
- ret = OK;
- }
- else
- if (lin[i + 1] == '\n')
- Errcode = ENOFN;
- else
- Errcode = EFILEN;
-
- if (ret == OK && Savfil[1] == EOS)
- {
- strcpy (Savfil, file); /* save if no old one */
- mesg (Savfil, FILE_MSG);
- }
-
- return (ret);
- }
-
-
- /* getkn --- get mark name from lin[i], increment i */
-
- int getkn (lin, i, kname, dfltnm)
- char lin[], *kname, dfltnm;
- int *i;
- {
-
- if (lin[*i] == '\n' || lin[*i] == EOS)
- {
- *kname = dfltnm;
- return (EOF);
- }
-
- *kname = lin[*i];
- (*i)++;
- return (OK);
- }
-
-
- /* getrange --- get 'from' range for tlit command */
-
- int getrange (array, k, set, size, allbut)
- char array[], set[];
- int *k, size, *allbut;
- {
- int i, j;
- int addset ();
-
- Errcode = EBADLIST; /* preset error code */
-
- i = *k + 1;
- if (array[i] == NOTINCCL) /* check for negated character class */
- {
- *allbut = YES;
- i++;
- }
- else
- *allbut = NO;
-
- j = 0;
- filset (array[*k], array, &i, set, &j, size);
- if (array[i] != array[*k])
- {
- set[0] = EOS;
- return (ERR);
- }
- if (set[0] == EOS)
- {
- Errcode = ENOLIST;
- return (ERR);
- }
- if (j > 0 && addset (EOS, set, &j, size) == NO)
- {
- set[0] = EOS;
- return (ERR);
- }
-
- *k = i;
- Errcode = EEGARB;
-
- return (OK);
- }
-
-
- /* getrhs --- get substitution string for 's' command */
-
- int getrhs (lin, i, sub, gflag)
- char lin[], sub[];
- int *i, *gflag;
- {
- static char Subs[MAXPAT] = ""; /* saved replacement pattern */
- int j, maksub ();
- /* saved replacement pattern char */
-
-
- Errcode = EBADSUB;
-
- if (lin[*i] == EOS) /* missing the middle delimeter */
- return (ERR);
-
- if (lin[*i + 1] == '%' && (lin[*i + 2] == lin[*i]
- || lin[*i + 2] == '\n'))
- {
- /*
- * s//%/ --- should mean do the same thing as I did last time, even
- * s//&/ --- if I deleted something. So we comment out these lines.
- *
- if (Subs[0] == EOS)
- {
- Errcode = ENOSUB;
- return (ERR);
- }
- */
- strcpy (sub, Subs);
- *i += 2;
- if (lin[*i] == '\n')
- {
- /* fix it up for pattern matching routines */
- lin[*i] = lin[*i - 2];
- lin[*i + 1] = '\n';
- lin[*i + 2] = EOS;
- Peekc = SKIP_RIGHT;
- }
- }
- else /* not using saved substitution pattern */
- {
- if (lin[*i + 1] == '\n')
- {
- /* missing the trailing delimiter */
- /* pattern was empty */
- lin[*i + 1] = lin[*i]; /* supply missing delimiter */
- lin[*i + 2] = '\n';
- lin[*i + 3] = EOS;
- Peekc = SKIP_RIGHT;
- /* return (ERR); /* this is the original action */
- }
- else
- {
- /* stuff in pattern, check end of line */
- for (j = *i; lin[j] != EOS; j++)
- ;
- j -= 2; /* j now points to char before '\n' */
-
- if (lin[j] == 'p' || lin[j] == 'P')
- {
- --j;
- if (lin[j] == GLOBAL || lin[j] == UCGLOBAL)
- {
- if (j >= *i + 1 && lin[j-1] == lin[*i]
- && (lin[j-2] != ESCAPE
- || lin[j-3] == ESCAPE))
- ; /* leave alone */
- else
- {
- /* \<delim>gp\n is pattern */
- /* supply trailing delim */
- j += 2; /* j at \n */
- lin[j] = lin[*i];
- lin[++j] = '\n';
- lin[++j] = EOS;
- Peekc = SKIP_RIGHT;
- }
- }
- else if (j >= *i + 1 && lin[j] == lin[*i] &&
- (lin[j-1] != ESCAPE
- || lin[j-2] == ESCAPE))
- ; /* leave alone */
- else
- {
- /* \<delim>p\n is pattern */
- /* supply trailing delim */
- j += 2;
- lin[j] = lin[*i];
- lin[++j] = '\n';
- lin[++j] = EOS;
- Peekc = SKIP_RIGHT;
- }
- }
- else if (lin[j] == GLOBAL || lin[j] == UCGLOBAL)
- {
- --j;
- if (j >= *i + 1 && lin[j] == lin[*i] &&
- (lin[j-1] != ESCAPE
- || lin[j-2] == ESCAPE))
- ; /* leave alone */
- else
- {
- /* \<delim>g\n is pattern */
- /* supply trailing delim */
- j += 2; /* j at \n */
- lin[j] = lin[*i];
- lin[++j] = '\n';
- lin[++j] = EOS;
- Peekc = SKIP_RIGHT;
- }
- }
- else if ((lin[j] != lin[*i]) ||
- (lin[j] == lin[*i] &&
- lin[j-1] == ESCAPE && lin[j-2] != ESCAPE))
- {
- /* simply missing trailing delimeter */
- /* supply it */
- j++; /* j at \n */
- lin[j] = lin[*i];
- lin[++j] = '\n';
- lin[++j] = EOS;
- Peekc = SKIP_RIGHT;
- }
- /* else
- unescaped delim is there,
- leave well enough alone */
- }
-
- if ((*i = maksub (lin, *i + 1, lin[*i], sub)) == ERR)
- return (ERR);
-
- strcpy (Subs, sub); /* save pattern for later */
- }
-
- if (lin[*i + 1] == GLOBAL || lin[*i + 1] == UCGLOBAL)
- {
- (*i)++;
- *gflag = YES;
- }
- else
- *gflag = NO;
-
- Errcode = EEGARB; /* the default */
-
- return (OK);
-
- }
-
-
- /* getstr --- get string from lin at i, copy to dst, bump i */
-
- /*
- ** NOTE: this routine only called for doing the join command.
- ** therefore, don't do anything else with it.
- */
-
- int getstr (lin, i, dst, maxdst)
- char lin[], dst[];
- int *i, maxdst;
- {
- char delim;
- char esc ();
- int j, k, d;
-
- j = *i;
- Errcode = EBADSTR;
-
- delim = lin[j];
-
- if (delim == '\n')
- {
- lin[j] = '/';
- lin[++j] = ' '; /* join with a single blank */
- lin[++j] = '/';
- lin[++j] = '\n';
- lin[++j] = EOS;
- j = *i;
- delim = lin[j];
- Peekc = SKIP_RIGHT;
- /* now fall thru */
-
- /* return (ERR); /* old way */
- }
- else if ((delim == 'p' || delim == 'P') && lin[j + 1] == '\n') /* jp */
- {
- lin[j] = '/';
- lin[++j] = ' '; /* join with a single blank */
- lin[++j] = '/';
- lin[++j] = delim; /* 'p' or 'P' */
- lin[++j] = '\n';
- lin[++j] = EOS;
- j = *i;
- delim = lin[j];
- Peekc = SKIP_RIGHT;
- /* now fall thru */
- }
-
- if (lin[j + 1] == '\n') /* command was 'j/' */
- {
- dst[0] = EOS;
- Errcode = ENOERR;
- return (OK);
- /* return (ERR); /* old way */
- }
-
- /*
- * otherwise, stuff there in the string, try to allow for
- * a missing final delimiter.
- */
-
- for (k = j + 1; lin[k] != '\n'; k++)
- ; /* find end */
-
- k--; /* now points to char before newline */
-
- if (lin[k] == 'p' || lin[k] == 'P')
- {
- k--;
- if (lin[k] == delim &&
- (lin[k-1] != ESCAPE || lin[k-2] == ESCAPE))
- ; /* it's fine, leave it alone */
- else
- {
- /* ESCAPE delim p NEWLINE is the join string */
- /* supply trailing delimiter. */
- k += 2;
- lin[k] = delim;
- lin[++k] = '\n';
- lin[++k] = EOS;
- Peekc = SKIP_RIGHT;
- }
- }
- else if (lin[k] != delim || (lin[k-1] == ESCAPE && lin[k-2] != ESCAPE))
- {
- /* no delim and no p, or last char is escaped delim */
- k++;
- lin[k] = delim;
- lin[++k] = '\n';
- lin[++k] = EOS;
- Peekc = SKIP_RIGHT;
- }
- /* else
- delim is there
- leave well enough alone */
-
- /* code to actually do the join */
-
- for (k = j + 1; lin[k] != delim; k++) /* find end */
- {
- if (lin[k] == '\n' || lin[k] == EOS)
- if (delim == ' ')
- break;
- else
- return (ERR);
- esc (lin, &k);
- }
- if (k - j > maxdst)
- return (ERR);
-
- for (d = 0, j++; j < k; d++, j++)
- dst[d] = esc (lin, &j);
- dst[d] = EOS;
-
- *i = j;
- Errcode = EEGARB; /* the default */
-
- return (OK);
- }
-
-
- /* getwrd --- get next word from line at i; increment i */
-
- int getwrd (line, i, word, size)
- char line[], word[];
- int *i, size;
- {
- int j;
-
- SKIPBL (line, *i);
- j = 0;
- while (line[*i] != ' ' && line[*i] != '\n' && line[*i] != EOS)
- {
- if (j < size - 1)
- {
- word[j] = line[*i];
- j++;
- }
- (*i)++;
- }
- word[j] = EOS;
-
- return (j);
- }
-
-
- /* knscan --- scan for a line with a given mark name */
-
- int knscan (way, num)
- int way, *num;
- {
- int nextln ();
- LINEDESC *k;
- LINEDESC *getind ();
-
- *num = Curln;
- k = getind (*num);
- do {
- bump (num, &k, way);
- if (k -> Markname == Savknm)
- return (OK);
- } while (*num != Curln && ! intrpt ());
-
- if (Errcode = EEGARB)
- Errcode = EKNOTFND;
- return (ERR);
-
- }
-
-
- /* makset --- make set from array[k] in set */
-
- int makset (array, k, set, size)
- char array[], set[];
- int *k, size;
- {
- static char Tset[MAXPAT] = ""; /* saved translit dest range */
- int i, j;
- int l;
- int addset ();
-
- Errcode = EBADLIST;
-
- /*
- * try to allow missing delimiter for translit command.
- */
-
- if (array[*k] == EOS)
- return (ERR);
-
- if (array[*k + 1] == '%' && (array[*k + 2] == array[*k]
- || array[*k + 2] == '\n'))
- {
- strcpy (set, Tset);
- *k += 2;
- if (array[*k] == '\n')
- {
- /* fix it up for rest of the routines */
- array[*k] = array[*k - 2];
- array[*k+ 1] = '\n';
- array[*k+ 2] = EOS;
- }
- Peekc = SKIP_RIGHT;
- }
- else
- {
-
- for (l = *k; array[l] != EOS; l++)
- ;
- l -= 2; /* l now points to char before '\n' */
-
- if (l == *k) /* "y/.../\n" */
- {
- array[*k + 1] = array[*k]; /* add delimiter */
- array[*k + 2] = '\n';
- array[*k + 3] = EOS;
- Peekc = SKIP_RIGHT;
- }
- else if (array[l] == 'p' || array[l] == 'P')
- {
- --l;
- if (l >= *k + 1 && array[l] == array[*k] &&
- (array[l-1] != ESCAPE || array[l-2] == ESCAPE))
- ; /* leave alone */
- else
- {
- /* \<delim>p\n is set */
- /* supply trailing delim */
- l += 2;
- array[l] = array[*k];
- array[++l] = '\n';
- array[++l] = EOS;
- Peekc = SKIP_RIGHT;
- }
- }
- else if (array[l] != array[*k] /* no delim, and no p */
- || (array[l-1] == ESCAPE /* or last char is escaped delim */
- && array[l-2] != ESCAPE))
- {
- /* simply missing trailing delimeter */
- /* supply it */
- l++; /* l now at \n */
- array[l] = array[*k];
- array[++l] = '\n';
- array[++l] = EOS;
- Peekc = SKIP_RIGHT;
- }
- /* else
- delim is there,
- leave well enough alone */
-
- j = 0;
- i = *k + 1;
- filset (array[*k], array, &i, set, &j, size);
-
- if (array[i] != array[*k])
- return (ERR);
-
- if (addset (EOS, set, &j, size) == NO)
- return (ERR);
-
- strcpy (Tset, set); /* save for later */
- *k = i;
-
- }
-
- Errcode = EEGARB;
-
- return (OK);
- }
-
-
- /* optpat --- make pattern specified at lin[i] */
-
- int optpat (lin, i)
- char lin[];
- int *i;
- {
- int makpat ();
-
- if (lin[*i] == EOS)
- *i = ERR;
- else if (lin[*i + 1] == EOS)
- *i = ERR;
- else if (lin[*i + 1] == lin[*i]) /* repeated delimiter */
- (*i)++; /* leave existing pattern alone */
- else
- *i = makpat (lin, *i + 1, lin[*i], Pat);
-
- if (Pat [0] == EOS)
- {
- Errcode = ENOPAT;
- return (ERR);
- }
- if (*i == ERR)
- {
- Pat[0] = EOS;
- Errcode = EBADPAT;
- return (ERR);
- }
- return (OK);
- }
-
-
- /* ptscan --- scan for next occurrence of pattern */
-
- int ptscan (way, num)
- int way, *num;
- {
- LINEDESC *getind ();
- LINEDESC *k;
- int match ();
-
- *num = Curln;
- k = getind (*num);
- do {
- bump (num, &k, way);
- gtxt (k);
- if (match (Txt, Pat) == YES)
- return (OK);
- } while (*num != Curln && ! intrpt ());
-
- if (Errcode == EEGARB)
- Errcode = EPNOTFND;
-
- return (ERR);
- }
-
-
- /* settab --- set tab stops */
-
- int settab (str)
- char str[];
- {
- int i, j, n, maxstop, last, inc, ret;
- int ctoi ();
-
- for (i = 0; i < MAXLINE; i++) /* clear all tab stops */
- Tabstops[i] = NO;
-
- ret = OK;
- maxstop = 0;
- last = 1;
-
- i = 0;
- SKIPBL (str, i);
- while (str[i] != EOS && str[i] != '\n')
- {
- if (str[i] == '+') /* increment */
- {
- i++;
- inc = YES;
- }
- else
- inc = NO;
-
- n = ctoi (str, &i);
-
- if (n <= 0 || n >= MAXLINE)
- {
- ret = ERR;
- Errcode = ENONSENSE;
- break;
- }
-
- if (str[i] != ' ' && str[i] != '+' &&
- str[i] != '\n' && str[i] != EOS)
- {
- ret = ERR;
- Errcode = EBADTABS;
- break;
- }
-
- if (inc == YES)
- {
- for (j = last + n; j < MAXLINE; j += n)
- {
- Tabstops[j - 1] = YES;
- maxstop = max (j, maxstop);
- }
- }
- else
- {
- Tabstops[n - 1] = YES;
- last = n;
- maxstop = max (n, maxstop);
- }
- SKIPBL (str, i);
- } /* while ... */
-
- if (ret == ERR)
- maxstop = 0;
-
- if (maxstop == 0) /* no tab stops specified, use defaults */
- {
- for (i = 4; i < MAXLINE - 1; i += 4)
- Tabstops[i] = YES;
- maxstop = i - 4 + 1;
- }
-
- Tabstops[0] = YES; /* always set to YES */
-
- for (i = maxstop; i < MAXLINE; i++)
- Tabstops[i] = YES;
-
- return (ret);
- }
-
- /* serc --- read in ./.serc or $HOME/.serc and execute the commands in it. */
-
- /*
- * note that se's special control characters are NOT processed,
- * and therefore should NOT be used in one's .serc file.
- */
-
- static serc ()
- {
- char file[MAXLINE];
- char lin[MAXLINE];
- char *expand_env ();
- FILE *fp;
- int status = ENOERR;
- int len, cursav;
-
- strcpy (file, expand_env ("$HOME/.serc"));
-
- if ((fp = fopen ("./.serc", "r")) == NULL ||
- (fp = fopen (file, "r")) == NULL)
- return;
-
- while (fgets (lin, sizeof lin, fp) != NULL && status != EOF /*??*/)
- {
- if (lin[0] == '#' || lin[0] == '\n')
- continue; /* comment in .serc file */
-
- /* most of this code stolen from edit() */
- len = 0;
- cursav = Curln;
- if (getlst (lin, &len, &status) == OK)
- {
- if (ckglob (lin, &len, &status) == OK)
- doglob (lin, &len, &cursav, &status);
- else if (status != ERR)
- docmd (lin, len, NO, &status);
- }
- if (status == ERR)
- {
- if (Errcode == EHANGUP)
- hangup ();
- Curln = min (cursav, Lastln);
- }
- }
- fclose (fp);
- }
-
- #ifdef LOG_USAGE
-
- /* log -- log se usage */
-
-
- static log ()
- {
- static char logfile[] = "/usr/tmp/se.log"; /* a public file */
- char logname[MAXLINE], tod[26]; /* tod => time of day */
- long clock;
- FILE *fp;
- char *ctime ();
- long time ();
- int old_umask;
- #ifdef BSD
- char *getlogin ();
- #else
- char *cuserid ();
- #endif
-
- /* get the login name */
- #ifdef BSD
- strcpy (logname, getlogin ());
- #else
- cuserid (logname);
- #endif
-
- time (&clock);
- strcpy (tod, ctime (&clock)); /* see the manual on ctime(3C) */
- tod[24] = EOS; /* delete the '\n' at the end */
-
- old_umask = umask (0); /* allow writes for everyone */
- /* when first call creates the file */
-
- if ((fp = fopen (logfile, "a")) != NULL)
- {
- /* all ok, write out statistics */
- fprintf (fp, "%s used se on %s.\n", logname, tod);
- fclose (fp);
- }
- /* else
- don't do anything */
-
- umask (old_umask);
-
- }
- #endif
-
- /* sysname --- return a string telling us who we are */
-
- #ifdef USG
- #include <sys/utsname.h> /* stuff to find out who we are */
- #endif
-
- char *sysname ()
- {
- int i, j, k;
- char c;
- static char buf[MAXLINE] = "";
- FILE *fp;
- static char unknown[] = "unknown";
-
- #ifdef USG /* System V */
- static struct utsname whoarewe;
-
- uname (& whoarewe);
- return (whoarewe.nodename);
- #else
- #ifdef BSD4_2 /* Berkeley 4.2 */
- if (buf[0] != EOS)
- return (buf);
-
- j = sizeof (buf);
- k = gethostname (buf, & j);
- if (k != 0)
- return (unknown);
- else
- return (buf);
- #else /* Berkeley 4.1 */
- if (buf[0] != EOS)
- return (buf);
-
- if ((fp = fopen ("/usr/include/whoami.h", "r")) == NULL)
- return (unknown);
- else
- {
- auto char *cp;
- /*
- * file should contain a single line:
- * #define sysname "......"
- */
- while ((c = getc (fp)) != '"' && c != EOF)
- ;
- if (c == EOF)
- cp = unknown;
- else
- {
- for (i = 0; (c = getc (fp)) != '"' && c != EOF; i++)
- buf[i] = c;
- buf[i] = EOS;
- if (c == EOF && i == 0)
- cp = unknown;
- else
- cp = buf;
- }
- fclose (fp);
- return (cp);
- }
- #endif
- #endif
- }
-