|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ T e ┃
Length: 26346 (0x66ea) Types: TextFile Names: »edit.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/se/edit.c«
#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 }