|
|
1.1 root 1: /*% cc -c -O %
2: */
3: #include "vars.h"
4: char digits[] = "0123456789"; /* getnum() & atoi() work even on non-ASCII systems */
5: getnum()
6: {
7: register n, i;
8: n=0;
9: while((i=posn(nextchar(), digits)) >= 0){
10: getchar();
11: n = n*10 + i;
12: }
13: return(n);
14: }
15:
16: getsigned(){
17: register sign;
18: if(nextchar()=='-'){
19: getchar();
20: sign = -1;
21: }
22: else
23: sign = 1;
24: return(getnum()*sign);
25: }
26:
27: atoi(s)
28: register char *s;
29: {
30: register n, i;
31: int sign;
32:
33: n = 0;
34: sign = 1;
35: if(*s == '-'){
36: sign = -1;
37: s++;
38: }
39: while(*s){
40: i = posn(*s++, digits);
41: if(i < 0)
42: return(sign*n); /* error handling done elsewhere */
43: n = n*10 + i;
44: }
45: return(sign*n);
46: }
47:
48: alldigs(s)
49: register char *s;
50: {
51: if(*s == '-')
52: s++;
53: while(*s)
54: if(posn(*s++, digits) < 0)
55: return(FALSE);
56: return(TRUE);
57: }
58:
59: char bname[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~";
60: getname(e)
61: {
62: int getc();
63: return(getnm(e, getc));
64: }
65: getaz(e)
66: {
67: int getchar();
68: return(getnm(e, getchar));
69: }
70: getnm(e, f)
71: int (*f)();
72: {
73: register i;
74: i = posn((*f)(), bname);
75: if(i < 0)
76: error(e);
77: return(i);
78: }
79: char special[] = "xgBbBcfFlprzN\"\\'";
80: int qcount;
81: int afterq;
82: getchar()
83: {
84: register c;
85: register peek;
86:
87: peek=peekc;
88: c=getc();
89: if(tflag && !peek && stackp!= &stack[0]){
90: if(c==EOF)
91: puts("[*EOF*]");
92: else
93: putchar(c);
94: }
95: return(c);
96: }
97: getc()
98: {
99: register c;
100: register struct buffer *bufp;
101: register struct stack *sp;
102: int *lp;
103: int numeric;
104: int delta;
105: int literal;
106: int i;
107: char *p;
108: static char bufbuf[LBSIZE];
109:
110: if(c = peekc) /* assignment = */
111: peekc = 0;
112: else if(qcount) {
113: --qcount;
114: c = '\\';
115: } else if(c = afterq) /* assignment = */
116: afterq = 0;
117: else {
118: for(;;popinp()){
119: sp=stackp;
120: switch(sp->type){
121: case TTY:
122: case XTTY:
123: if(cprflag && sp == &stack[0] &&
124: lastttyc == '\n')
125: write(2, "*", 1);
126: c = ttyc();
127: if(sp != &stack[0] && c == '\n') {
128: if(stackp->type == TTY)
129: continue;
130: else /* XTTY */
131: popinp();
132: }
133: break;
134: case GLOB:
135: if ((c = *stackp->globp++) == 0){
136: popinp();
137: c = EOF;
138: }
139: break;
140: case STRING:
141: case BFILEN:
142: case PAT:
143: case RHS:
144: case BRWS:
145: case FILEN:
146: if(string[sp->strname].len < sp->charno){
147: c=EOF;
148: continue;
149: }
150: c=string[sp->strname].str[sp->charno++];
151: if(c==0)
152: continue;
153: break;
154: case BUF:
155: bufp=sp->bufptr;
156: if(bufp==curbuf)
157: syncbuf();
158: lp=bufp->zero+sp->lineno;
159: if(bbempty){
160: if(lp>bufp->dol)
161: continue;
162: p = getline(*lp, bufbuf);
163: bbempty = FALSE;
164: for(i=sp->charno; i-- && *p; p++)
165: ;
166: }else
167: p = bufbuf+sp->charno;
168: sp->charno++;
169: if((c = *p) == '\0'){
170: /*
171: * Leave the last newline in the buffer out.
172: */
173: bbempty = TRUE;
174: if(lp>=bufp->dol)
175: continue;
176: sp->lineno++;
177: sp->charno=0;
178: c='\n';
179: }
180: }
181: break;
182: }
183: literal = FALSE;
184: if(c == '\\' && !stackp->literal){
185: Getc:
186: c = getc();
187: i = posn(c, cspec);
188: switch(i) {
189: case LITERAL:
190: if(posn(peekc=getc(), "bfFlprz!") >= 0)
191: literal = TRUE;
192: goto Getc; /* business as usual... */
193: case QUOTE:
194: c = '\\';
195: break;
196: case NEWL:
197: c = '\n';
198: break;
199: case STRING:
200: delta = 0;
201: numeric = 0;
202: c = getc();
203: if(c == '#'){
204: numeric++;
205: c = getc();
206: }
207: if(c == '+' || c == '-'){
208: delta = 1;
209: if(c == '-')
210: delta = -delta;
211: c=getc();
212: }
213: ungetchar(c);
214: c = getname('z');
215: if(delta){
216: if(numeric){
217: if(!alldigs(string[c].str))
218: error('#');
219: numset(c, atoi(string[c].str)+delta);
220: } else
221: strinc(c, delta);
222: }
223: pushinp(i, c, literal);
224: literal = FALSE;
225: c=getc();
226: break;
227: case BUF:
228: case BFILEN:
229: c = getname(cspec[i]);
230: if(i == BUF)
231: bbempty = TRUE;
232: /* fall through */
233: case TTY:
234: case FILEN:
235: case PAT:
236: case RHS:
237: pushinp(i, c, literal);
238: literal = FALSE;
239: /* fall through */
240: case NOTHING:
241: c = getc();
242: break;
243: case CURBN:
244: c = bname[curbuf-buffer];
245: break;
246: case BACKSLASH:
247: qcount++;
248: break;
249: default:
250: afterq = c;
251: c = '\\';
252: break;
253: }
254: }
255: }
256: lastc = c;
257: return(c);
258: }
259: ttyc()
260: {
261: char c;
262: initflag = 0;
263: if(read(0, &c, 1) > 0)
264: lastttyc = c&0177;
265: else
266: lastttyc = EOF;
267: return(lastttyc);
268: }
269: posn(c, s)
270: register char c;
271: register char *s;
272: {
273: register char *is;
274: is = s;
275: while(*s)
276: if(c == *s++)
277: return(s - is - 1);
278: return(-1);
279: }
280: pushinp(type, arg, literal)
281: register arg;
282: {
283: register struct stack *s;
284:
285: s = ++stackp;
286: if(s == stack+STACKSIZE)
287: error('l');
288: stackp->literal = literal;
289: if(tflag){
290: putchar('[');
291: if(literal)
292: putchar('\'');
293: putchar(cspec[type]);
294: }
295: s->type=type;
296: s->charno = 0;
297: switch(type){
298: case BFILEN:
299: s->strname = FILE(arg);
300: break;
301: case STRING:
302: s->strname = arg;
303: break;
304: case FILEN:
305: s->strname = savedfile;
306: break;
307: case PAT:
308: s->strname = SAVPAT;
309: break;
310: case RHS:
311: s->strname = SAVRHS;
312: break;
313: case BRWS:
314: s->strname = BROWSE;
315: break;
316: case BUF:
317: if((s->bufptr=buffer+arg) == curbuf && appflag)
318: error('\\');
319: s->lineno=1;
320: break;
321: case GLOB:
322: s->globp = (char *)arg;
323: break;
324: }
325: if(tflag){
326: if(type==BFILEN || type==STRING || type==BUF)
327: putchar(bname[arg]);
328: putchar('=');
329: }
330: }
331: popinp(){
332: if(stackp->type == BUF)
333: bbempty = TRUE;
334: if(tflag){
335: putchar(']');
336: flush();
337: }
338: --stackp;
339: }
340: gettty()
341: {
342: register c, gf;
343: register char *p;
344: p = linebuf;
345: gf = stackp->type;
346: while((c=getchar()) != '\n') {
347: if (c==EOF) {
348: if (gf == GLOB)
349: peekc=c;
350: return(c);
351: }
352: if (c == 0)
353: continue;
354: *p++ = c;
355: if (p >= &linebuf[LBSIZE-2])
356: error('l');
357: }
358: *p++ = 0;
359: if (!oneline && linebuf[0]=='.' && linebuf[1]==0)
360: return(EOF);
361: return(0);
362: }
363: getquote(p, f)
364: register char *p;
365: int (*f)();
366: {
367: register c;
368: c = (*f)();
369: if(c == '\\') {
370: if(peekc == 0)
371: nextchar(); /* prime peekc */
372: if(posn(peekc, p) >= 0) {
373: c = peekc | 0200;
374: (*f)(); /* clear peekc */
375: }
376: }
377: return(c);
378: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.