|
|
1.1 root 1: /*% cc -c -O %
2: */
3: #include "vars.h"
4: #define OUT 10
5: #define BACKWARD 11
6: #define FORWARD 12
7: char jumpcs[] = "0123456789o`'";
8: jump() /* this should be pronounced with a Swedish accent */
9: {
10: register int i;
11: register cond;
12: register c;
13:
14: if(stackp->type==TTY)
15: error('y');
16: c = getchar();
17: cond = TRUE;
18: if(c=='t' || c=='f'){
19: cond = ((c=='t') == truth());
20: c = getchar();
21: }
22: i = posn(c, jumpcs);
23: if(i==-1){ /* to handle y[tf] without labels for globals */
24: ungetchar(c);
25: if(cond){
26: while((c = getc())!='\n')
27: if(c==EOF)
28: return;
29: }
30: }
31: else if(i<=9){
32: stacktype(BUF);
33: ungetchar(c);
34: i = getnum();
35: stacktype(BUF); /* we may have popped stack! */
36: if(cond){
37: /* getchar will handle problems if off end of buffer */
38: bbempty = TRUE;
39: stackp->lineno = i;
40: stackp->charno = 0;
41: }
42: }
43: else if(i==OUT){
44: if(cond){
45: if(stackp==stack)
46: error('y');
47: if(stackp->type==GLOB){
48: --nestlevel;
49: stackp->globp = "";
50: }else
51: popinp();
52: }
53: }
54: else if(i==FORWARD || i==BACKWARD){
55: stacktype(BUF);
56: getlabel(); /* must eat label even if not yumping */
57: stacktype(BUF);
58: if(cond)
59: search(i==FORWARD);
60: }
61: }
62: stacktype(t)
63: {
64: if(stackp->type != t)
65: error('y');
66: }
67: getlabel(){
68: register char *p, c;
69: p = genbuf;
70: for(c=getchar(); posn(c," \"\t\n")<0; c=getchar()){
71: *p++ = c;
72: *p = '\0';
73: }
74: if(p==genbuf)
75: error('y');
76: }
77: int *looper(a1,a2,str,dir)
78: register int *a1, *a2;
79: register char *str;
80: {
81: register char *p1;
82: register char *p2;
83: while(dir ? a1<=a2 : a1>=a2){
84: p2 = getline(*a1, linebuf);
85: while(*p2==' ' || *p2=='\t')
86: p2++;
87: if(*p2++=='"' && *p2!=' ' && *p2!='\t' && *p2!='\0') {
88: for(p1=str; *p2 && (*p1 == *p2); p2++)
89: p1++;
90: if(*p1==0 && (*p2==0 || *p2==' ' || *p2=='\t'))
91: return(a1);
92: }
93: if(dir)
94: a1++;
95: else
96: --a1;
97: }
98: return((int *)0);
99: }
100: search(forward)
101: {
102: register int *a1;
103: struct buffer *bufp;
104: bufp = stackp->bufptr;
105: if(forward){
106: if((a1 = looper(bufp->zero + (stackp->lineno + 1),
107: bufp->dol,genbuf,1))==0){
108: a1 = looper(bufp->zero + 1,bufp->zero + (stackp->lineno - 1),genbuf,1);
109: }
110: }else{
111: if((a1 = looper(bufp->zero + (stackp->lineno - 1),
112: bufp->zero + 1,genbuf,0))==0){
113: a1 = looper(bufp->dol,bufp->zero + stackp->lineno + 1,genbuf,0);
114: }
115: }
116: if(a1){
117: stackp->lineno = a1 - bufp->zero;
118: stackp->charno = 0;
119: }
120: }
121: int pchar;
122: setapp()
123: {
124: register c;
125: c=getchar();
126: if(posn(c, lchars)>=0) {
127: pchar = c;
128: c = getchar();
129: }
130: if(c==' ' || c=='\t'){
131: oneline++;
132: if(c=='\t')
133: ungetchar(c);
134: }
135: else if(c!='\n')
136: error('x');
137: }
138: #define LDCHUNK 512
139: append(f, a)
140: int (*f)();
141: int *a;
142: {
143: register *a1, *a2, *rdot;
144: int nline, tl;
145: struct integer { int iint; };
146: appflag++;
147: nline = 0;
148: dot = a;
149: while ((*f)()==0) {
150: if (lastdol>=endcore) {
151: if (sbrk(LDCHUNK*(sizeof *endcore))==(char *)-1)
152: error('c');
153: endcore += LDCHUNK;
154: }
155: tl = putline();
156: nline++;
157: lock++;
158: ++dol;
159: a1 = ++lastdol;
160: fixbufs(1);
161: a2 = a1+1;
162: rdot = ++dot;
163: while (a1 > rdot)
164: *--a2 = *--a1;
165: *rdot = tl;
166: unlock();
167: if(oneline)
168: break;
169: }
170: appflag=0;
171: oneline=0;
172: if(pchar) {
173: a1 = addr1; addr1 = dot;
174: a2 = addr2; addr2 = dot;
175: display(pchar);
176: pchar = 0;
177: addr1 = a1; addr2 = a2;
178: }
179: return(nline);
180: }
181: char bformat = 'p';
182: bcom()
183: {
184: register dir, n;
185: register psize;
186: register *olddot=addr2; /* for b. */
187: dir=1;
188: if((peekc=getchar())!='\n'){ /* really nextchar() */
189: if (peekc=='-' || peekc=='+' || peekc=='.') {
190: if(peekc=='-')
191: dir= -1;
192: else if(peekc=='.')
193: dir=0;
194: getchar(); /* eat peekc */
195: }
196: if((n=getnum())>0)
197: pagesize=n;
198: }
199: psize=pagesize;
200: if(dir==0)
201: psize/=2;
202: if(posn(nextchar(), lchars)>=0)
203: bformat=getchar();
204: if(dir<=0) {
205: if((addr1=addr2-(psize-1))<=zero)
206: addr1=zero+1;
207: if(dir==0){
208: display(bformat);
209: puts("^^^^^");
210: addr2++;
211: }
212: }
213: if (dir>=0) {
214: addr1=addr2;
215: if((addr2+=(psize-1))>dol)
216: addr2=dol;
217: }
218: display(bformat);
219: if(dir==0)
220: dot=olddot;
221: }
222: delete()
223: {
224: register *a1, *a2, *a3;
225: setdot();
226: a1 = addr1;
227: a2 = addr2;
228: if(a1==zero) {
229: if(a2!=zero)
230: *(a1++);
231: else
232: return; /* 0,$d on an empty buffer */
233: }
234: *(a2++);
235: a3 = lastdol;
236: lock++;
237: dol -= a2 - a1;
238: lastdol -= a2 - a1;
239: fixbufs(a1-a2);
240: do
241: *a1++ = *a2++;
242: while (a2<=a3);
243: a1 = addr1;
244: if (a1 > dol)
245: a1 = dol;
246: dot = a1;
247: unlock();
248: modified();
249: }
250: allnums()
251: {
252: register int i;
253: register char *p;
254: setdot();
255: for(i=0; i<NBUFS; i++){
256: p = string[i].str;
257: if(*p!='\0' && alldigs(p)){
258: putct(bname[i]);
259: puts(p);
260: }
261: }
262: }
263: numcom(z)
264: {
265: register n;
266: register struct string *sp;
267: register char *l;
268: char c;
269: int numeric;
270: extern char digits[]; /* defined in getchar.c = "0123456789" */
271:
272: /*
273: * Must generate error if attempt is made to do arithmetic on
274: * a register which is not numeric; this is done by remembering
275: * (via `numeric') whether the initial string was numeric or not.
276: */
277: sp = &string[z];
278: numeric = alldigs(sp->str);
279: n = atoi(sp->str);
280: for(;;){
281: switch(c=getchar()){
282: default:
283: goto Done;
284: case ':':
285: n=getsigned();
286: goto Not_numeric;
287: case 'a':
288: n=addr2-zero;
289: goto Not_numeric;
290: case 'r':
291: if(z+1>=NBUFS)
292: error('z');
293: n = addr1-zero;
294: numset(z+1, addr2-zero);
295: goto Not_numeric;
296: case 'n':
297: nonzero();
298: l = getline(*addr2,linebuf);
299: do; while(*l++);
300: n = l - linebuf - 1;
301: goto Not_numeric;
302: case 'P':
303: n = getpid();
304: Not_numeric:
305: numeric = TRUE; /* It's numeric now! */
306: break;
307:
308: case 'p':
309: if(n<0)
310: putchar('-');
311: putdn(abs(n));
312: goto Numeric;
313: case '+':
314: n += getsigned();
315: goto Numeric;
316: case '-':
317: n -= getsigned();
318: goto Numeric;
319: case '*':
320: n *= getsigned();
321: goto Numeric;
322: case '/':
323: n /= getsigned();
324: goto Numeric;
325: case '%':
326: n %= getsigned();
327: goto Numeric;
328: case '!':
329: if(posn(c=getchar(), "=><")<0)
330: error('#');
331: settruth(condition(n, getsigned(), c, 1));
332: goto Numeric;
333: case '<':
334: case '>':
335: case '=':
336: settruth(condition(n, getsigned(), c, 0));
337: Numeric:
338: if(numeric == FALSE)
339: error('#');
340: break;
341: }
342: }
343: Done:
344: ungetchar(c);
345: numset(z, n);
346: }
347: condition(n, m, cond, negate)
348: register n, m, cond, negate;
349: {
350: int retval;
351: if(cond=='=')
352: retval = (n==m);
353: else if(cond=='<')
354: retval = (n<m);
355: else if(cond=='>')
356: retval = (n>m);
357: else
358: error("!");
359: return(negate^retval);
360: }
361: numset(z, n)
362: register z;
363: register n;
364: {
365: startstring();
366: numbuild(n);
367: setstring(z);
368: }
369: numbuild(n)
370: register n;
371: {
372: register i;
373: if(n<0){
374: addstring('-');
375: n = -n;
376: }
377: i = n/10;
378: if(i)
379: numbuild(i);
380: addstring(n%10+'0');
381: }
382: strcom(z)
383: {
384: register char *q;
385: register n;
386: int getchar();
387: register struct string *sp;
388: int cond, c, negate;
389: setdot();
390: sp = &string[z];
391: if(nextchar()=='#'){
392: getchar(); /* eat the '#' */
393: numcom(z);
394: return;
395: }
396: negate=FALSE;
397: switch(cond=getchar()){
398: default:
399: error('x');
400: case 'p':
401: puts(sp->str);
402: break;
403: case 'l':
404: putl(sp->str);
405: break;
406: case ':':
407: startstring();
408: for(;;){
409: c = getquote("\n", getchar);
410: if(c=='\n'){
411: setstring(z);
412: return;
413: }
414: addstring(c&0177);
415: }
416: case '\'':
417: startstring();
418: dupstring(getname('z'));
419: setstring(z);
420: break;
421: case '.':
422: nonzero();
423: startstring();
424: copystring(getline(*addr2, linebuf));
425: setstring(z);
426: break;
427: case '/':
428: nonzero();
429: compile('/');
430: if(execute(addr2)==0){
431: clearstring(z);
432: settruth(FALSE);
433: return;
434: }
435: q = loc1;
436: startstring();
437: while(q < loc2)
438: addstring(*q++);
439: setstring(z);
440: settruth(TRUE);
441: return;
442: case 's':
443: substitute(stackp!=&stack[0], z);
444: return;
445: case '+':
446: strinc(z, getsigned());
447: break;
448: case '-':
449: strinc(z, -getsigned());
450: break;
451: case 'n':
452: setcount(sp->len);
453: break;
454: case 'e':
455: startstring();
456: addstring(lasterr);
457: setstring(z);
458: break;
459: case '(':
460: n=getsigned();
461: if(abs(n) > sp->len)
462: error('[');
463: if(n>=0){
464: sp->str += n;
465: sp->len -= n;
466: }
467: else{
468: sp->str += sp->len+n;
469: sp->len = -n;
470: }
471: break;
472: case ')':
473: n=getsigned();
474: if(abs(n) > sp->len)
475: error('[');
476: if(n<0){
477: sp->str[sp->len+n]='\0';
478: sp->len += n;
479: } else if(n==0)
480: clearstring(z);
481: else {
482: sp->str[n]='\0';
483: sp->len=n;
484: }
485: break;
486: case '[':
487: cpstr(sp->str, linebuf);
488: loc2=0; /* Tell execute that it's already in linebuf */
489: compile(getchar());
490: if(execute(0)==0){
491: settruth(FALSE);
492: setcount(-1);
493: } else {
494: settruth(TRUE);
495: setcount(loc2-linebuf-1);
496: }
497: return;
498: case 'C':
499: startstring();
500: clean(z);
501: setstring(z);
502: break;
503: case '!':
504: if(posn(cond=getchar(), "=><")<0)
505: error('x');
506: negate=TRUE;
507: case '=':
508: case '<':
509: case '>':
510: settruth(FALSE);
511: q=sp->str;
512: for(;;){
513: c=getchar();
514: if(c=='\n' && *q==0){
515: if(cond == '=')
516: settruth(!negate);
517: return;
518: }
519: if(*q++!=c){
520: if(cond=='<')
521: settruth(negate ^ (*--q < c));
522: else if(cond=='>')
523: settruth(negate ^ (*--q > c));
524: while(c!='\n')
525: c=getchar();
526: return;
527: }
528: }
529: case '{':
530: q = genbuf;
531: while(posn(c=getchar(), "} \t\n")<0 && c!=EOF)
532: *q++ = c;
533: *q = '\0';
534: if((q=getenv(genbuf)) == 0)
535: clearstring(z);
536: else{
537: startstring();
538: copystring(q);
539: setstring(z);
540: }
541: break;
542: /* end of switch */
543: }
544: }
545: strinc(z, n)
546: {
547: register char *q;
548: q=string[z].str;
549: while(*q)
550: *q++ += n;
551: }
552: locn(ap, aq)
553: char *ap, *aq;
554: {
555: register char *p, *q, *lastq;
556: p=ap;
557: q=aq;
558: for(;;){
559: lastq=q;
560: while(*p==*q){
561: if(*p++==0 || *p==0)
562: return(lastq - aq);
563: q++;
564: }
565: if(*q==0)
566: return(-1);
567: p=ap;
568: q=lastq+1;
569: }
570: }
571: #define EMPTY (TRUE+1) /* ==> ignore this buf in G/V */
572: ncom(c)
573: {
574: register struct buffer *bufp;
575: struct buffer *stop;
576: register char *f, *lp;
577: int globflag;
578:
579: setnoaddr();
580: syncbuf();
581: globflag = FALSE;
582: if(c == 'f')
583: stop = bufp = curbuf;
584: else{
585: bufp = buffer;
586: stop = buffer+NBUFS-1;
587: if(c=='G')
588: globflag = TRUE;
589: }
590: do{
591: lp = linebuf;
592: f = string[FILE(bufp-buffer)].str;
593: if(c=='N' && (!bufp->cflag || *f==0))
594: continue;
595: if(bufp->dol==bufp->zero && *f=='\0'){
596: if(globflag)
597: bufp->gmark = EMPTY;
598: if(globflag || bufp!=curbuf)
599: continue;
600: }
601: *lp++ = bname[bufp-buffer];
602: *lp++ = (bufp->cflag) ? '\'' : ' ';
603: *lp++ = (bufp==curbuf) ? '.' : ' ';
604: numset(FILEBUF, bufp->dol-bufp->zero);
605: cpstr(string[FILEBUF].str, lp);
606: lp += string[FILEBUF].len;
607: f = string[FILE(bufp-buffer)].str; /* in case strings got g.c.'d */
608: if(*f)
609: *lp++ = '\t';
610: if(globflag){
611: cpstr(f, lp);
612: loc2 = 0; /* ==> we are about to search for 1st time */
613: bufp->gmark = execute((int *)0);
614: } else {
615: *lp = '\0';
616: lp = linebuf;
617: while(*lp)
618: putchar(*lp++);
619: putl(f);
620: }
621: }while(bufp++!=stop);
622: }
623: allstrs()
624: {
625: register int i;
626: char *p;
627: setdot();
628: for(i=0; i<NBUFS; i++){
629: p=string[i].str;
630: if(*p!=0){
631: putct(bname[i]);
632: putl(p);
633: }
634: }
635: putct('P');
636: putl(string[SAVPAT].str);
637: putct('R');
638: putl(string[SAVRHS].str);
639: if(*string[BROWSE].str) {
640: putct('B');
641: putl(string[BROWSE].str);
642: }
643: }
644: /*
645: * clean (string) to support zaC
646: * strips leading and trailing white space from a string
647: * and replaces interior white space by single blanks
648: */
649: clean(z) {
650: register char *s;
651: register char *d;
652: register char c;
653: d = genbuf;
654: for (s = string[z].str; (c = *s) == ' ' || c == '\t'; s++);
655: while (c = *s++) {
656: if (c == ' ' || c == '\t') {
657: *d++ = ' ';
658: while(*s == ' ' || *s == '\t')
659: s++;
660: } else {
661: *d++ = c;
662: }
663: }
664: while (d > genbuf && d[-1] == ' ')
665: --d;
666: *d = 0;
667: copystring(genbuf);
668: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.