|
|
1.1 root 1: /* Copyright (c) 1979 Regents of the University of California */
2: #include "ex.h"
3: #include "ex_re.h"
4: #include "ex_tty.h"
5: #include "ex_vis.h"
6:
7: /*
8: * Random routines, in alphabetical order.
9: */
10:
11: any(c, s)
12: int c;
13: register char *s;
14: {
15: register int x;
16:
17: while (x = *s++)
18: if (x == c)
19: return (1);
20: return (0);
21: }
22:
23: backtab(i)
24: register int i;
25: {
26: register int j;
27:
28: j = i % value(SHIFTWIDTH);
29: if (j == 0)
30: j = value(SHIFTWIDTH);
31: i -= j;
32: if (i < 0)
33: i = 0;
34: return (i);
35: }
36:
37: change()
38: {
39:
40: tchng++;
41: chng = tchng;
42: }
43:
44: /*
45: * Column returns the number of
46: * columns occupied by printing the
47: * characters through position cp of the
48: * current line.
49: */
50: column(cp)
51: register char *cp;
52: {
53:
54: if (cp == 0)
55: cp = &linebuf[LBSIZE - 2];
56: return (qcolumn(cp, (char *) 0));
57: }
58:
59: Copy(to, from, size)
60: register char *from, *to;
61: register int size;
62: {
63:
64: if (size > 0)
65: do
66: *to++ = *from++;
67: while (--size > 0);
68: }
69:
70: copyw(to, from, size)
71: register line *from, *to;
72: register int size;
73: {
74:
75: if (size > 0)
76: do
77: *to++ = *from++;
78: while (--size > 0);
79: }
80:
81: copywR(to, from, size)
82: register line *from, *to;
83: register int size;
84: {
85:
86: while (--size >= 0)
87: to[size] = from[size];
88: }
89:
90: ctlof(c)
91: int c;
92: {
93:
94: return (c == TRIM ? '?' : c | ('A' - 1));
95: }
96:
97: dingdong()
98: {
99:
100: if (VB)
101: putpad(VB);
102: else if (value(ERRORBELLS))
103: putch('\207');
104: }
105:
106: fixindent(indent)
107: int indent;
108: {
109: register int i;
110: register char *cp;
111:
112: i = whitecnt(genbuf);
113: cp = vpastwh(genbuf);
114: if (*cp == 0 && i == indent && linebuf[0] == 0) {
115: genbuf[0] = 0;
116: return (i);
117: }
118: CP(genindent(i), cp);
119: return (i);
120: }
121:
122: filioerr(cp)
123: char *cp;
124: {
125: register int oerrno = errno;
126:
127: lprintf("\"%s\"", cp);
128: errno = oerrno;
129: syserror();
130: }
131:
132: char *
133: genindent(indent)
134: register int indent;
135: {
136: register char *cp;
137:
138: for (cp = genbuf; indent >= value(TABSTOP); indent -= value(TABSTOP))
139: *cp++ = '\t';
140: for (; indent > 0; indent--)
141: *cp++ = ' ';
142: return (cp);
143: }
144:
145: getDOT()
146: {
147:
148: getline(*dot);
149: }
150:
151: line *
152: getmark(c)
153: register int c;
154: {
155: register line *addr;
156:
157: for (addr = one; addr <= dol; addr++)
158: if (names[c - 'a'] == (*addr &~ 01)) {
159: return (addr);
160: }
161: return (0);
162: }
163:
164: getn(cp)
165: register char *cp;
166: {
167: register int i = 0;
168:
169: while (isdigit(*cp))
170: i = i * 10 + *cp++ - '0';
171: if (*cp)
172: return (0);
173: return (i);
174: }
175:
176: ignnEOF()
177: {
178: register int c = getchar();
179:
180: if (c == EOF)
181: ungetchar(c);
182: }
183:
184: iswhite(c)
185: int c;
186: {
187:
188: return (c == ' ' || c == '\t');
189: }
190:
191: junk(c)
192: register int c;
193: {
194:
195: if (c && !value(BEAUTIFY))
196: return (0);
197: if (c >= ' ' && c != TRIM)
198: return (0);
199: switch (c) {
200:
201: case '\t':
202: case '\n':
203: case '\f':
204: return (0);
205:
206: default:
207: return (1);
208: }
209: }
210:
211: killed()
212: {
213:
214: killcnt(addr2 - addr1 + 1);
215: }
216:
217: killcnt(cnt)
218: register int cnt;
219: {
220:
221: if (inopen) {
222: notecnt = cnt;
223: notenam = notesgn = "";
224: return;
225: }
226: if (!notable(cnt))
227: return;
228: printf("%d lines", cnt);
229: if (value(TERSE) == 0) {
230: printf(" %c%s", Command[0] | ' ', Command + 1);
231: if (Command[strlen(Command) - 1] != 'e')
232: putchar('e');
233: putchar('d');
234: }
235: putNFL();
236: }
237:
238: lineno(a)
239: line *a;
240: {
241:
242: return (a - zero);
243: }
244:
245: lineDOL()
246: {
247:
248: return (lineno(dol));
249: }
250:
251: lineDOT()
252: {
253:
254: return (lineno(dot));
255: }
256:
257: markDOT()
258: {
259:
260: markpr(dot);
261: }
262:
263: markpr(which)
264: line *which;
265: {
266:
267: if ((inglobal == 0 || inopen) && which <= endcore) {
268: names['z'-'a'+1] = *which & ~01;
269: if (inopen)
270: ncols['z'-'a'+1] = cursor;
271: }
272: }
273:
274: markreg(c)
275: register int c;
276: {
277:
278: if (c == '\'' || c == '`')
279: return ('z' + 1);
280: if (c >= 'a' && c <= 'z')
281: return (c);
282: return (0);
283: }
284:
285: /*
286: * Mesg decodes the terse/verbose strings. Thus
287: * 'xxx@yyy' -> 'xxx' if terse, else 'xxx yyy'
288: * 'xxx|yyy' -> 'xxx' if terse, else 'yyy'
289: * All others map to themselves.
290: */
291: char *
292: mesg(str)
293: register char *str;
294: {
295: register char *cp;
296:
297: str = strcpy(genbuf, str);
298: for (cp = str; *cp; cp++)
299: switch (*cp) {
300:
301: case '@':
302: if (value(TERSE))
303: *cp = 0;
304: else
305: *cp = ' ';
306: break;
307:
308: case '|':
309: if (value(TERSE) == 0)
310: return (cp + 1);
311: *cp = 0;
312: break;
313: }
314: return (str);
315: }
316:
317: /*VARARGS2*/
318: merror(seekpt, i)
319: #ifdef VMUNIX
320: char *seekpt;
321: #else
322: # ifdef lint
323: char *seekpt;
324: # else
325: int seekpt;
326: # endif
327: #endif
328: int i;
329: {
330: register char *cp = linebuf;
331:
332: if (seekpt == 0)
333: return;
334: merror1(seekpt);
335: if (*cp == '\n')
336: putnl(), cp++;
337: if (inopen && CE)
338: vclreol();
339: if (SO && SE)
340: putpad(SO);
341: printf(mesg(cp), i);
342: if (SO && SE)
343: putpad(SE);
344: }
345:
346: merror1(seekpt)
347: #ifdef VMUNIX
348: char *seekpt;
349: #else
350: # ifdef lint
351: char *seekpt;
352: # else
353: int seekpt;
354: # endif
355: #endif
356: {
357:
358: #ifdef VMUNIX
359: strcpy(linebuf, seekpt);
360: #else
361: lseek(erfile, (long) seekpt, 0);
362: if (read(erfile, linebuf, 128) < 2)
363: CP(linebuf, "ERROR");
364: #endif
365: }
366:
367: morelines()
368: {
369:
370: if ((int) sbrk(1024 * sizeof (line)) == -1)
371: return (-1);
372: endcore += 1024;
373: return (0);
374: }
375:
376: nonzero()
377: {
378:
379: if (addr1 == zero) {
380: notempty();
381: error("Nonzero address required@on this command");
382: }
383: }
384:
385: notable(i)
386: int i;
387: {
388:
389: return (hush == 0 && !inglobal && i > value(REPORT));
390: }
391:
392:
393: notempty()
394: {
395:
396: if (dol == zero)
397: error("No lines@in the buffer");
398: }
399:
400:
401: netchHAD(cnt)
402: int cnt;
403: {
404:
405: netchange(lineDOL() - cnt);
406: }
407:
408: netchange(i)
409: register int i;
410: {
411: register char *cp;
412:
413: if (i > 0)
414: notesgn = cp = "more ";
415: else
416: notesgn = cp = "fewer ", i = -i;
417: if (inopen) {
418: notecnt = i;
419: notenam = "";
420: return;
421: }
422: if (!notable(i))
423: return;
424: printf(mesg("%d %slines@in file after %s"), i, cp, Command);
425: putNFL();
426: }
427:
428: putmark(addr)
429: line *addr;
430: {
431:
432: putmk1(addr, putline());
433: }
434:
435: putmk1(addr, n)
436: register line *addr;
437: int n;
438: {
439: register line *markp;
440:
441: *addr &= ~1;
442: for (markp = (anymarks ? names : &names['z'-'a'+1]);
443: markp <= &names['z'-'a'+1]; markp++)
444: if (*markp == *addr)
445: *markp = n;
446: *addr = n;
447: }
448:
449: char *
450: plural(i)
451: long i;
452: {
453:
454: return (i == 1 ? "" : "s");
455: }
456:
457: int qcount();
458: short vcntcol;
459:
460: qcolumn(lim, gp)
461: register char *lim, *gp;
462: {
463: register int x;
464: int (*OO)();
465:
466: OO = Outchar;
467: Outchar = qcount;
468: vcntcol = 0;
469: if (lim != NULL)
470: x = lim[1], lim[1] = 0;
471: pline(0);
472: if (lim != NULL)
473: lim[1] = x;
474: if (gp)
475: while (*gp)
476: putchar(*gp++);
477: Outchar = OO;
478: return (vcntcol);
479: }
480:
481: int
482: qcount(c)
483: int c;
484: {
485:
486: if (c == '\t') {
487: vcntcol += value(TABSTOP) - vcntcol % value(TABSTOP);
488: return;
489: }
490: vcntcol++;
491: }
492:
493: reverse(a1, a2)
494: register line *a1, *a2;
495: {
496: register line t;
497:
498: for (;;) {
499: t = *--a2;
500: if (a2 <= a1)
501: return;
502: *a2 = *a1;
503: *a1++ = t;
504: }
505: }
506:
507: save(a1, a2)
508: line *a1;
509: register line *a2;
510: {
511: register int more;
512:
513: undkind = UNDNONE;
514: undadot = dot;
515: more = (a2 - a1 + 1) - (unddol - dol);
516: while (more > (endcore - truedol))
517: if (morelines() < 0)
518: error("Out of memory@saving lines for undo - try using ed or re");
519: if (more)
520: (*(more > 0 ? copywR : copyw))(unddol + more + 1, unddol + 1,
521: (truedol - unddol));
522: unddol += more;
523: truedol += more;
524: copyw(dol + 1, a1, a2 - a1 + 1);
525: undkind = UNDALL;
526: unddel = a1 - 1;
527: undap1 = a1;
528: undap2 = a2 + 1;
529: }
530:
531: save12()
532: {
533:
534: save(addr1, addr2);
535: }
536:
537: saveall()
538: {
539:
540: save(one, dol);
541: }
542:
543: span()
544: {
545:
546: return (addr2 - addr1 + 1);
547: }
548:
549: sync()
550: {
551:
552: chng = 0;
553: tchng = 0;
554: xchng = 0;
555: }
556:
557:
558: skipwh()
559: {
560: register int wh;
561:
562: wh = 0;
563: while (iswhite(peekchar())) {
564: wh++;
565: ignchar();
566: }
567: return (wh);
568: }
569:
570: /*VARARGS2*/
571: smerror(seekpt, cp)
572: #ifdef lint
573: char *seekpt;
574: #else
575: int seekpt;
576: #endif
577: char *cp;
578: {
579:
580: if (seekpt == 0)
581: return;
582: merror1(seekpt);
583: if (inopen && CE)
584: vclreol();
585: if (SO && SE)
586: putpad(SO);
587: lprintf(mesg(linebuf), cp);
588: if (SO && SE)
589: putpad(SE);
590: }
591:
592: #define std_nerrs (sizeof std_errlist / sizeof std_errlist[0])
593:
594: #define error(i) i
595:
596: #ifdef lint
597: char *std_errlist[] = {
598: #else
599: #ifdef VMUNIX
600: char *std_errlist[] = {
601: #else
602: short std_errlist[] = {
603: #endif
604: #endif
605: error("Error 0"),
606: error("Not super-user"),
607: error("No such file or directory"),
608: error("No such process"),
609: error("Interrupted system call"),
610: error("Physical I/O error"),
611: error("No such device or address"),
612: error("Argument list too long"),
613: error("Exec format error"),
614: error("Bad file number"),
615: error("No children"),
616: error("No more processes"),
617: error("Not enough core"),
618: error("Permission denied"),
619: error("Bad address"),
620: error("Block device required"),
621: error("Mount device busy"),
622: error("File exists"),
623: error("Cross-device link"),
624: error("No such device"),
625: error("Not a directory"),
626: error("Is a directory"),
627: error("Invalid argument"),
628: error("File table overflow"),
629: error("Too many open files"),
630: error("Not a typewriter"),
631: error("Text file busy"),
632: error("File too large"),
633: error("No space left on device"),
634: error("Illegal seek"),
635: error("Read-only file system"),
636: error("Too many links"),
637: error("Broken pipe")
638: #ifndef QUOTA
639: , error("Math argument")
640: , error("Result too large")
641: #else
642: , error("Quota exceeded")
643: #endif
644: };
645:
646: #undef error
647:
648: char *
649: strend(cp)
650: register char *cp;
651: {
652:
653: while (*cp)
654: cp++;
655: return (cp);
656: }
657:
658: strcLIN(dp)
659: char *dp;
660: {
661:
662: CP(linebuf, dp);
663: }
664:
665: syserror()
666: {
667: register int e = errno;
668:
669: dirtcnt = 0;
670: putchar(' ');
671: if (e >= 0 && errno <= std_nerrs)
672: error(std_errlist[e]);
673: else
674: error("System error %d", e);
675: }
676:
677: char *
678: vfindcol(i)
679: int i;
680: {
681: register char *cp;
682: register int (*OO)() = Outchar;
683:
684: Outchar = qcount;
685: ignore(qcolumn(linebuf - 1, NOSTR));
686: for (cp = linebuf; *cp && vcntcol < i; cp++)
687: putchar(*cp);
688: if (cp != linebuf)
689: cp--;
690: Outchar = OO;
691: return (cp);
692: }
693:
694: char *
695: vskipwh(cp)
696: register char *cp;
697: {
698:
699: while (iswhite(*cp) && cp[1])
700: cp++;
701: return (cp);
702: }
703:
704:
705: char *
706: vpastwh(cp)
707: register char *cp;
708: {
709:
710: while (iswhite(*cp))
711: cp++;
712: return (cp);
713: }
714:
715: whitecnt(cp)
716: register char *cp;
717: {
718: register int i;
719:
720: i = 0;
721: for (;;)
722: switch (*cp++) {
723:
724: case '\t':
725: i += value(TABSTOP) - i % value(TABSTOP);
726: break;
727:
728: case ' ':
729: i++;
730: break;
731:
732: default:
733: return (i);
734: }
735: }
736:
737: #ifdef lint
738: Ignore(a)
739: char *a;
740: {
741:
742: a = a;
743: }
744:
745: Ignorf(a)
746: int (*a)();
747: {
748:
749: a = a;
750: }
751: #endif
752:
753: markit(addr)
754: line *addr;
755: {
756:
757: if (addr != dot && addr >= one && addr <= dol)
758: markDOT();
759: }
760:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.