Commit | Line | Data |
---|---|---|
6fc53266 TL |
1 | #include "r.h" |
2 | #define BUFSIZE 512 | |
3 | char ibuf[BUFSIZE]; | |
4 | char *ip = ibuf; | |
5 | ||
6 | char type[] = { | |
7 | 0, CRAP, CRAP, CRAP, CRAP, CRAP, CRAP, CRAP, | |
8 | CRAP, '\t', '\n', CRAP, CRAP, CRAP, CRAP, CRAP, | |
9 | CRAP, CRAP, CRAP, CRAP, CRAP, CRAP, CRAP, CRAP, | |
10 | CRAP, CRAP, CRAP, CRAP, CRAP, CRAP, CRAP, CRAP, | |
11 | ' ', '!', '"', '#', '$', '%', '&', '\'', | |
12 | '(', ')', '*', '+', ',', '-', '.', '/', | |
13 | DIG, DIG, DIG, DIG, DIG, DIG, DIG, DIG, | |
14 | DIG, DIG, ':', ';', '<', '=', '>', '?', | |
15 | '@', LET, LET, LET, LET, LET, LET, LET, | |
16 | LET, LET, LET, LET, LET, LET, LET, LET, | |
17 | LET, LET, LET, LET, LET, LET, LET, LET, | |
18 | LET, LET, LET, '[', '\\', ']', '^', '_', | |
19 | '`', LET, LET, LET, LET, LET, LET, LET, | |
20 | LET, LET, LET, LET, LET, LET, LET, LET, | |
21 | LET, LET, LET, LET, LET, LET, LET, LET, | |
22 | LET, LET, LET, '{', '|', '}', '~', 0, | |
23 | }; | |
24 | ||
25 | gtok(s) char *s; { /* get token into s */ | |
26 | register c, t; | |
27 | register char *p; | |
28 | struct nlist *q; | |
29 | ||
30 | for(;;) { | |
31 | p = s; | |
32 | *p++ = c = getchr(); | |
33 | switch(t = type[c]) { | |
34 | case 0: | |
35 | if (infptr > 0) { | |
36 | fclose(infile[infptr]); | |
37 | infptr--; | |
38 | continue; | |
39 | } | |
40 | if (svargc > 1) { | |
41 | svargc--; | |
42 | svargv++; | |
43 | if (infile[infptr] != stdin) | |
44 | fclose(infile[infptr]); | |
45 | if( (infile[infptr] = fopen(*svargv,"r")) == NULL ) | |
46 | cant(*svargv); | |
47 | linect[infptr] = 0; | |
48 | curfile[infptr] = *svargv; | |
49 | continue; | |
50 | } | |
51 | return(EOF); /* real eof */ | |
52 | case ' ': | |
53 | case '\t': | |
54 | while ((c = getchr()) == ' ' || c == '\t') | |
55 | ; /* skip others */ | |
56 | if (c == COMMENT || c == '_') { | |
57 | putbak(c); | |
58 | continue; | |
59 | } | |
60 | if (c != '\n') { | |
61 | putbak(c); | |
62 | *p = '\0'; | |
63 | return(' '); | |
64 | } else { | |
65 | *s = '\n'; | |
66 | *(s+1) = '\0'; | |
67 | return(*s); | |
68 | } | |
69 | case '_': | |
70 | while ((c = getchr()) == ' ' || c == '\t') | |
71 | ; | |
72 | if (c == COMMENT) { | |
73 | putbak(c); | |
74 | gtok(s); /* recursive */ | |
75 | } | |
76 | else if (c != '\n') | |
77 | putbak(c); | |
78 | continue; | |
79 | case LET: | |
80 | case DIG: | |
81 | while ((t=type[*p = getchr()]) == LET || t == DIG) | |
82 | p++; | |
83 | putbak(*p); | |
84 | *p = '\0'; | |
85 | if ((q = lookup(s))->name != NULL && q->ydef == 0) { /* found but not keyword */ | |
86 | if (q->def != fcnloc) { /* not "function" */ | |
87 | pbstr(q->def); | |
88 | continue; | |
89 | } | |
90 | getfname(); /* recursive gtok */ | |
91 | } | |
92 | for (p=s; *p; p++) | |
93 | if (*p>='A' && *p<='Z') | |
94 | *p += 'a' - 'A'; | |
95 | for (p=s; *p; p++) | |
96 | if (*p < '0' || *p > '9') | |
97 | return(LET); | |
98 | return(DIG); | |
99 | case '[': | |
100 | *p = '\0'; | |
101 | return('{'); | |
102 | case ']': | |
103 | *p = '\0'; | |
104 | return('}'); | |
105 | case '$': | |
106 | case '\\': | |
107 | if ((*p = getchr()) == '(' || *p == ')') { | |
108 | putbak(*p=='(' ? '{' : '}'); | |
109 | continue; | |
110 | } | |
111 | if (*p == '"' || *p == '\'') | |
112 | p++; | |
113 | else | |
114 | putbak(*p); | |
115 | *p = '\0'; | |
116 | return('$'); | |
117 | case COMMENT: | |
118 | comment[comptr++] = 'c'; | |
119 | while ((comment[comptr++] = getchr()) != '\n') | |
120 | ; | |
121 | flushcom(); | |
122 | *s = '\n'; | |
123 | *(s+1) = '\0'; | |
124 | return(*s); | |
125 | case '"': | |
126 | case '\'': | |
127 | for (; (*p = getchr()) != c; p++) { | |
128 | if (*p == '\\') | |
129 | *++p = getchr(); | |
130 | if (*p == '\n') { | |
131 | error("missing quote"); | |
132 | putbak('\n'); | |
133 | break; | |
134 | } | |
135 | } | |
136 | *p++ = c; | |
137 | *p = '\0'; | |
138 | return(QUOTE); | |
139 | case '%': | |
140 | while ((*p = getchr()) != '\n') | |
141 | p++; | |
142 | putbak(*p); | |
143 | *p = '\0'; | |
144 | return('%'); | |
145 | case '>': case '<': case '=': case '!': case '^': | |
146 | return(peek(p, '=')); | |
147 | case '&': | |
148 | return(peek(p, '&')); | |
149 | case '|': | |
150 | return(peek(p, '|')); | |
151 | case CRAP: | |
152 | continue; | |
153 | default: | |
154 | *p = '\0'; | |
155 | return(*s); | |
156 | } | |
157 | } | |
158 | } | |
159 | ||
160 | gnbtok(s) char *s; { | |
161 | register c; | |
162 | while ((c = gtok(s)) == ' ' || c == '\t') | |
163 | ; | |
164 | return(c); | |
165 | } | |
166 | ||
167 | getfname() { | |
168 | while (gtok(fcname) == ' ') | |
169 | ; | |
170 | pbstr(fcname); | |
171 | putbak(' '); | |
172 | } | |
173 | ||
174 | peek(p, c1) char *p, c1; { | |
175 | register c; | |
176 | c = *(p-1); | |
177 | if ((*p = getchr()) == c1) | |
178 | p++; | |
179 | else | |
180 | putbak(*p); | |
181 | *p = '\0'; | |
182 | return(c); | |
183 | } | |
184 | ||
185 | pbstr(str) | |
186 | register char *str; | |
187 | { | |
188 | register char *p; | |
189 | ||
190 | p = str; | |
191 | while (*p++); | |
192 | --p; | |
193 | if (ip >= &ibuf[BUFSIZE]) { | |
194 | error("pushback overflow"); | |
195 | exit(1); | |
196 | } | |
197 | while (p > str) | |
198 | putbak(*--p); | |
199 | } | |
200 | ||
201 | getchr() { | |
202 | register c; | |
203 | ||
204 | if (ip > ibuf) | |
205 | return(*--ip); | |
206 | c = getc(infile[infptr]); | |
207 | if (c == '\n') | |
208 | linect[infptr]++; | |
209 | if (c == EOF) | |
210 | return(0); | |
211 | return(c); | |
212 | } |