|
|
1.1 root 1: /*% cc -c -O %
2: */
3: #include "vars.h"
4: char *next_new;
5: char *next_old;
6: int new_line;
7: int old_line;
8: char rhsbuf[RHSIZE];
9:
10: substitute(inglob, reg)
11: {
12: register int n, m;
13: register char *p;
14: char *q;
15: int *a1;
16: int gsubf;
17: extern int getsub();
18: int t, count, autop=0;
19:
20: count=0;
21: t = FALSE;
22: n=getnum();
23: gsubf = compsub(TRUE, &autop);
24: if(reg!= -1){ /* Substitution in a register */
25: cpstr(string[reg].str, linebuf);
26: loc2=0; /* signal execute to take line from linebuf */
27: a1=0;
28: goto Do_it;
29: }
30: for (a1 = addr1; a1 <= addr2 && reg==-1; a1++) {
31: Do_it:
32: if (execute(a1)) {
33: next_old=linebuf;
34: next_new=genbuf;
35: m=n;
36: do {
37: if (--m <= 0) {
38: dosub();
39: t = TRUE;
40: count++;
41: if (!gsubf)
42: break;
43: }
44: /* can't find something at EOL twice */
45: if (*loc2=='\0')
46: break;
47: /* can't match same location twice */
48: if (loc1==loc2)
49: loc2++;
50: } while (execute((int *)0));
51: if (m<=0) {
52: inglob |= TRUE;
53: p=next_old;
54: do ; while (*p++);
55: place(next_old,p,0);
56: if(reg==-1){
57: p=linebuf;
58: q=genbuf;
59: do ; while (*p++ = *q++);
60: replace(a1,putline());
61: m=append(getsub,a1);
62: a1 += m;
63: addr2 += m;
64: }else{
65: startstring();
66: copystring(genbuf);
67: setstring(reg);
68: }
69: }
70: }
71: }
72: if (!inglob)
73: error('s');
74: settruth(t);
75: setcount(count);
76: if(autop)
77: if(reg>=0)
78: puts(string[reg].str);
79: else{
80: addr1=addr2=dot;
81: display('p');
82: }
83: }
84:
85: compsub(subbing, autop)
86: int subbing;
87: int *autop;
88: {
89: register int seof, c;
90: char *rhsmagic;
91: register char *p;
92: int getsvc();
93:
94: *autop=FALSE;
95: seof = getchar();
96: if(subbing) {
97: compile(seof);
98: rhsmagic = "/&^\n\\123456789";
99: }
100: else
101: rhsmagic = "/\\\n";
102: rhsmagic[0] = seof;
103: p = rhsbuf;
104: startstring();
105: for (;;) {
106: c = getquote(rhsmagic, getsvc);
107: if (c=='\n' || c==EOF){
108: *autop=TRUE;
109: ungetchar('\n');
110: break;
111: }
112: if (c==seof)
113: break;
114: *p++ = c;
115: if (p >= &rhsbuf[RHSIZE])
116: error('l');
117: }
118: *p = 0;
119: dropstring();
120: setstring(SAVRHS);
121: if (subbing && nextchar() == 'g') {
122: getchar(); /* clear 'g' */
123: return(1);
124: }
125: return(0);
126: }
127: int getsub()
128: {
129: register char *p1, *p2;
130:
131: p1 = linebuf;
132: if ((p2 = linebp) == 0)
133: return(EOF);
134: do ; while (*p1++ = (*p2++ & 0177));
135: linebp = 0;
136: return(0);
137: }
138:
139: dosub()
140: {
141: register int c;
142: register char *p;
143:
144: place(next_old,loc1,0);
145: next_old=loc2;
146: p=rhsbuf;
147: while (c = *p++) {
148: if (c=='&' || (c == '^' && uflag))
149: place(loc1,loc2,c=='^');
150: else if ((c&0200) && (c &= 0177)>='1' && c<'1'+nbra)
151: place(braslist[c-'1'],braelist[c-'1'], 0);
152: else {
153: *next_new++ = c;
154: if (next_new >= genbuf+LBSIZE)
155: error('l');
156: }
157: }
158: }
159:
160: place(l1, l2, ucase)
161: register char *l1;
162: char *l2;
163: {
164: register char *sp;
165: register c;
166:
167: sp = next_new;
168: while (l1 < l2) {
169: *sp++ = (*l1++ & 0177);
170: if (sp >= &genbuf[LBSIZE])
171: error('l');
172: }
173: if(ucase){
174: for(l1 = next_new;l1 < sp;){
175: c = (*l1 & 0177);
176: if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')){
177: switch(uflag){
178: case 's':
179: *l1++ ^= 040;
180: break;
181: case 'u':
182: *l1++ &= ~040;
183: break;
184: case 'l':
185: *l1++ |= 040;
186: break;
187: default:
188: l1++;
189: }
190: }else{
191: l1++;
192: }
193: }
194: }
195: next_new = sp;
196: }
197:
198: undo()
199: {
200: register int *l;
201:
202: for (l=zero+1; l<=dol && (*l|01)!=new_line; l++)
203: ;
204: if (l>dol)
205: error('u');
206: replace(l,old_line);
207: dot=l;
208: }
209: replace(line,ptr)
210: register int *line;
211: register int ptr;
212: {
213: register int *p;
214:
215: *line |= 01;
216: for (p=names; p<names+NBUFS; p++)
217: if (*p == *line)
218: *p = ptr|01;
219: old_line = *line;
220: *line = ptr;
221: new_line = ptr | 01;
222: }
223: join()
224: {
225: register int *l;
226: register char *p, *q;
227: int rep;
228: int autop=FALSE;
229:
230: rep=FALSE;
231: if(nextchar() == '/'){
232: compsub(FALSE, &autop);
233: rep=TRUE;
234: }
235: p = genbuf;
236: for (l=addr1; ;) {
237: q = getline(*l++, linebuf);
238: while (*q) {
239: *p++ = *q++;
240: if (p >= genbuf + sizeof genbuf)
241: error('l');
242: }
243: if(l > addr2)
244: break;
245: if(rep) {
246: q = string[SAVRHS].str;
247: while (*q) {
248: *p++ = *q++;
249: if (p >= genbuf + sizeof genbuf)
250: error('l');
251: }
252: }
253: }
254: *p = '\0';
255: linebp=p=linebuf;
256: q=genbuf;
257: do ; while (*p++ = *q++);
258: getsub();
259: *(l=addr1++)=putline();
260: /* if you want marks preserved for join, change the above line to
261: /* the one commented out here.
262: /* problem: undo then undoes the join, but gets it wrong. Your choice.
263: replace(l=addr1++, putline());
264: */
265: if(l != addr2)
266: delete();
267: append(getsub, l);
268: if(autop){
269: addr1=addr2=dot;
270: display('p');
271: }
272: }
273:
274: int next_col(col,cp,input)
275: register int col;
276: register char *cp;
277: int input;
278: {
279: register c;
280:
281: c = *cp;
282: if (c=='\t')
283: col |= 07;
284: else if (c<' ' || c=='\177')
285: error('t'); /* invalid character in x data */
286: else
287: if (input && (c==ttybuf.sg_erase || c==ttybuf.sg_kill))
288: col++; /* One column for the backslash */
289: return (++col);
290: }
291:
292: xform()
293: {
294: register char *i, *m, *o;
295: int *line, insert, change, ic, mc, c;
296: char *tf, *tl;
297:
298: if(getchar() != '\n')
299: error('x');
300: for (line=addr1; line<=addr2; line++) {
301: getline(*line, linebuf);
302: change=FALSE;
303: dot=line;
304: for(;;){
305: puts(linebuf);
306: pushinp(XTTY, 0, FALSE);
307: m=rhsbuf;
308: while ((c = getchar())!='\n') {
309: if (c == EOF)
310: error('t'); /* unexpected EOF */
311: *m++ = c;
312: if (m==rhsbuf+RHSIZE-1)
313: error('l'); /* out of space */
314: }
315: *m='\0';
316: if (m==rhsbuf)
317: break;
318: change++;
319: i=linebuf;
320: o=genbuf;
321: do ; while (*o++ = *i++);
322: if (i+(m-rhsbuf) > linebuf+LBSIZE)
323: error('l'); /* out of space */
324: i=genbuf;
325: o=linebuf;
326: m=rhsbuf;
327: insert=FALSE;
328: ic=0;
329: mc=0;
330: while (*i && *m && !insert) {
331: if(*i=='\t' && *m!='#' && *m!='^' && *m!='$') {
332: ic=next_col(ic,i,FALSE);
333: tf=m;
334: tl=m;
335: do {
336: if (*m!=' ' && *m!='\t') {
337: if(*m=='%')
338: *m=' ';
339: tl=m+1;
340: }
341: mc=next_col(mc,m++,TRUE);
342: } while (ic>mc && *m && *m!='#' &&
343: *m!='^' && *m!='$');
344: if (ic>mc) {
345: ic=mc;
346: if (*m)
347: tl=m;
348: } else {
349: if (tl==m)
350: i++;
351: else
352: ic--;
353: }
354: while (tf!=tl)
355: *o++ = *tf++;
356: } else {
357: mc=next_col(mc,m,TRUE);
358: *o = *m;
359: switch (*m++) {
360: case ' ':
361: case '\t':
362: break;
363: case '^':
364: mc=ic;
365: insert++;
366: break;
367: case '$':
368: i="";
369: break;
370: case '#':
371: ic=next_col(ic,i++,FALSE);
372: while(*m=='#' && ic>mc)
373: mc=next_col(mc,m++,TRUE);
374: if (ic!=mc)
375: error('t');
376: break;
377: case '%':
378: *o = ' ';
379: /* fall through */
380: default:
381: o++;
382: ic=next_col(ic,i++,FALSE);
383: } /* switch */
384: } /* else */
385: for (;;) {
386: if (ic>mc && *m) {
387: if (*m!=' ' && *m!='\t')
388: error('t');
389: mc=next_col(mc,m++,TRUE);
390: } else if (mc>ic && *i) {
391: ic=next_col(ic,i,FALSE);
392: *o++ = *i++;
393: } else
394: break;
395: }
396: } /* while */
397: if (mc>ic && m[-1]=='\t')
398: *o++ = '\t';
399: if (insert && (*o++ = *m++) == '\0') {
400: replace(line,putline());
401: linebp=i;
402: append(getsub,line);
403: line++;
404: addr2++;
405: change = FALSE;
406: } else {
407: while (*m)
408: *o++ = *m++;
409: do ; while (*o++ = *i++);
410: }
411: }
412: if (change)
413: replace(line,putline());
414: } /* for */
415: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.