Blame


1 76193d7c 2003-09-30 devnull #include "sam.h"
2 76193d7c 2003-09-30 devnull #include "parse.h"
3 76193d7c 2003-09-30 devnull
4 76193d7c 2003-09-30 devnull Address addr;
5 76193d7c 2003-09-30 devnull String lastpat;
6 76193d7c 2003-09-30 devnull int patset;
7 76193d7c 2003-09-30 devnull File *menu;
8 76193d7c 2003-09-30 devnull
9 76193d7c 2003-09-30 devnull File *matchfile(String*);
10 76193d7c 2003-09-30 devnull Address charaddr(Posn, Address, int);
11 76193d7c 2003-09-30 devnull
12 76193d7c 2003-09-30 devnull Address
13 76193d7c 2003-09-30 devnull address(Addr *ap, Address a, int sign)
14 76193d7c 2003-09-30 devnull {
15 76193d7c 2003-09-30 devnull File *f = a.f;
16 76193d7c 2003-09-30 devnull Address a1, a2;
17 76193d7c 2003-09-30 devnull
18 76193d7c 2003-09-30 devnull do{
19 76193d7c 2003-09-30 devnull switch(ap->type){
20 76193d7c 2003-09-30 devnull case 'l':
21 76193d7c 2003-09-30 devnull case '#':
22 76193d7c 2003-09-30 devnull a = (*(ap->type=='#'?charaddr:lineaddr))(ap->num, a, sign);
23 76193d7c 2003-09-30 devnull break;
24 76193d7c 2003-09-30 devnull
25 76193d7c 2003-09-30 devnull case '.':
26 76193d7c 2003-09-30 devnull a = f->dot;
27 76193d7c 2003-09-30 devnull break;
28 76193d7c 2003-09-30 devnull
29 76193d7c 2003-09-30 devnull case '$':
30 522b0689 2003-09-30 devnull a.r.p1 = a.r.p2 = f->b.nc;
31 76193d7c 2003-09-30 devnull break;
32 76193d7c 2003-09-30 devnull
33 76193d7c 2003-09-30 devnull case '\'':
34 76193d7c 2003-09-30 devnull a.r = f->mark;
35 76193d7c 2003-09-30 devnull break;
36 76193d7c 2003-09-30 devnull
37 76193d7c 2003-09-30 devnull case '?':
38 76193d7c 2003-09-30 devnull sign = -sign;
39 76193d7c 2003-09-30 devnull if(sign == 0)
40 76193d7c 2003-09-30 devnull sign = -1;
41 76193d7c 2003-09-30 devnull /* fall through */
42 76193d7c 2003-09-30 devnull case '/':
43 76193d7c 2003-09-30 devnull nextmatch(f, ap->are, sign>=0? a.r.p2 : a.r.p1, sign);
44 76193d7c 2003-09-30 devnull a.r = sel.p[0];
45 76193d7c 2003-09-30 devnull break;
46 76193d7c 2003-09-30 devnull
47 76193d7c 2003-09-30 devnull case '"':
48 76193d7c 2003-09-30 devnull a = matchfile(ap->are)->dot;
49 76193d7c 2003-09-30 devnull f = a.f;
50 76193d7c 2003-09-30 devnull if(f->unread)
51 76193d7c 2003-09-30 devnull load(f);
52 76193d7c 2003-09-30 devnull break;
53 76193d7c 2003-09-30 devnull
54 76193d7c 2003-09-30 devnull case '*':
55 522b0689 2003-09-30 devnull a.r.p1 = 0, a.r.p2 = f->b.nc;
56 76193d7c 2003-09-30 devnull return a;
57 76193d7c 2003-09-30 devnull
58 76193d7c 2003-09-30 devnull case ',':
59 76193d7c 2003-09-30 devnull case ';':
60 76193d7c 2003-09-30 devnull if(ap->left)
61 76193d7c 2003-09-30 devnull a1 = address(ap->left, a, 0);
62 76193d7c 2003-09-30 devnull else
63 76193d7c 2003-09-30 devnull a1.f = a.f, a1.r.p1 = a1.r.p2 = 0;
64 76193d7c 2003-09-30 devnull if(ap->type == ';'){
65 76193d7c 2003-09-30 devnull f = a1.f;
66 76193d7c 2003-09-30 devnull a = a1;
67 76193d7c 2003-09-30 devnull f->dot = a1;
68 76193d7c 2003-09-30 devnull }
69 76193d7c 2003-09-30 devnull if(ap->next)
70 76193d7c 2003-09-30 devnull a2 = address(ap->next, a, 0);
71 76193d7c 2003-09-30 devnull else
72 522b0689 2003-09-30 devnull a2.f = a.f, a2.r.p1 = a2.r.p2 = f->b.nc;
73 76193d7c 2003-09-30 devnull if(a1.f != a2.f)
74 76193d7c 2003-09-30 devnull error(Eorder);
75 76193d7c 2003-09-30 devnull a.f = a1.f, a.r.p1 = a1.r.p1, a.r.p2 = a2.r.p2;
76 76193d7c 2003-09-30 devnull if(a.r.p2 < a.r.p1)
77 76193d7c 2003-09-30 devnull error(Eorder);
78 76193d7c 2003-09-30 devnull return a;
79 76193d7c 2003-09-30 devnull
80 76193d7c 2003-09-30 devnull case '+':
81 76193d7c 2003-09-30 devnull case '-':
82 76193d7c 2003-09-30 devnull sign = 1;
83 76193d7c 2003-09-30 devnull if(ap->type == '-')
84 76193d7c 2003-09-30 devnull sign = -1;
85 76193d7c 2003-09-30 devnull if(ap->next==0 || ap->next->type=='+' || ap->next->type=='-')
86 76193d7c 2003-09-30 devnull a = lineaddr(1L, a, sign);
87 76193d7c 2003-09-30 devnull break;
88 76193d7c 2003-09-30 devnull default:
89 76193d7c 2003-09-30 devnull panic("address");
90 76193d7c 2003-09-30 devnull return a;
91 76193d7c 2003-09-30 devnull }
92 76193d7c 2003-09-30 devnull }while(ap = ap->next); /* assign = */
93 76193d7c 2003-09-30 devnull return a;
94 76193d7c 2003-09-30 devnull }
95 76193d7c 2003-09-30 devnull
96 76193d7c 2003-09-30 devnull void
97 76193d7c 2003-09-30 devnull nextmatch(File *f, String *r, Posn p, int sign)
98 76193d7c 2003-09-30 devnull {
99 76193d7c 2003-09-30 devnull compile(r);
100 76193d7c 2003-09-30 devnull if(sign >= 0){
101 76193d7c 2003-09-30 devnull if(!execute(f, p, INFINITY))
102 76193d7c 2003-09-30 devnull error(Esearch);
103 76193d7c 2003-09-30 devnull if(sel.p[0].p1==sel.p[0].p2 && sel.p[0].p1==p){
104 522b0689 2003-09-30 devnull if(++p>f->b.nc)
105 76193d7c 2003-09-30 devnull p = 0;
106 76193d7c 2003-09-30 devnull if(!execute(f, p, INFINITY))
107 76193d7c 2003-09-30 devnull panic("address");
108 76193d7c 2003-09-30 devnull }
109 76193d7c 2003-09-30 devnull }else{
110 76193d7c 2003-09-30 devnull if(!bexecute(f, p))
111 76193d7c 2003-09-30 devnull error(Esearch);
112 76193d7c 2003-09-30 devnull if(sel.p[0].p1==sel.p[0].p2 && sel.p[0].p2==p){
113 76193d7c 2003-09-30 devnull if(--p<0)
114 522b0689 2003-09-30 devnull p = f->b.nc;
115 76193d7c 2003-09-30 devnull if(!bexecute(f, p))
116 76193d7c 2003-09-30 devnull panic("address");
117 76193d7c 2003-09-30 devnull }
118 76193d7c 2003-09-30 devnull }
119 76193d7c 2003-09-30 devnull }
120 76193d7c 2003-09-30 devnull
121 76193d7c 2003-09-30 devnull File *
122 76193d7c 2003-09-30 devnull matchfile(String *r)
123 76193d7c 2003-09-30 devnull {
124 76193d7c 2003-09-30 devnull File *f;
125 76193d7c 2003-09-30 devnull File *match = 0;
126 76193d7c 2003-09-30 devnull int i;
127 76193d7c 2003-09-30 devnull
128 76193d7c 2003-09-30 devnull for(i = 0; i<file.nused; i++){
129 76193d7c 2003-09-30 devnull f = file.filepptr[i];
130 76193d7c 2003-09-30 devnull if(f == cmd)
131 76193d7c 2003-09-30 devnull continue;
132 76193d7c 2003-09-30 devnull if(filematch(f, r)){
133 76193d7c 2003-09-30 devnull if(match)
134 76193d7c 2003-09-30 devnull error(Emanyfiles);
135 76193d7c 2003-09-30 devnull match = f;
136 76193d7c 2003-09-30 devnull }
137 76193d7c 2003-09-30 devnull }
138 76193d7c 2003-09-30 devnull if(!match)
139 76193d7c 2003-09-30 devnull error(Efsearch);
140 76193d7c 2003-09-30 devnull return match;
141 76193d7c 2003-09-30 devnull }
142 76193d7c 2003-09-30 devnull
143 76193d7c 2003-09-30 devnull int
144 76193d7c 2003-09-30 devnull filematch(File *f, String *r)
145 76193d7c 2003-09-30 devnull {
146 76193d7c 2003-09-30 devnull char *c, buf[STRSIZE+100];
147 76193d7c 2003-09-30 devnull String *t;
148 76193d7c 2003-09-30 devnull
149 76193d7c 2003-09-30 devnull c = Strtoc(&f->name);
150 76193d7c 2003-09-30 devnull sprint(buf, "%c%c%c %s\n", " '"[f->mod],
151 76193d7c 2003-09-30 devnull "-+"[f->rasp!=0], " ."[f==curfile], c);
152 76193d7c 2003-09-30 devnull free(c);
153 76193d7c 2003-09-30 devnull t = tmpcstr(buf);
154 76193d7c 2003-09-30 devnull Strduplstr(&genstr, t);
155 76193d7c 2003-09-30 devnull freetmpstr(t);
156 76193d7c 2003-09-30 devnull /* A little dirty... */
157 76193d7c 2003-09-30 devnull if(menu == 0)
158 76193d7c 2003-09-30 devnull menu = fileopen();
159 522b0689 2003-09-30 devnull bufreset(&menu->b);
160 522b0689 2003-09-30 devnull bufinsert(&menu->b, 0, genstr.s, genstr.n);
161 76193d7c 2003-09-30 devnull compile(r);
162 522b0689 2003-09-30 devnull return execute(menu, 0, menu->b.nc);
163 76193d7c 2003-09-30 devnull }
164 76193d7c 2003-09-30 devnull
165 76193d7c 2003-09-30 devnull Address
166 76193d7c 2003-09-30 devnull charaddr(Posn l, Address addr, int sign)
167 76193d7c 2003-09-30 devnull {
168 76193d7c 2003-09-30 devnull if(sign == 0)
169 76193d7c 2003-09-30 devnull addr.r.p1 = addr.r.p2 = l;
170 76193d7c 2003-09-30 devnull else if(sign < 0)
171 76193d7c 2003-09-30 devnull addr.r.p2 = addr.r.p1-=l;
172 76193d7c 2003-09-30 devnull else if(sign > 0)
173 76193d7c 2003-09-30 devnull addr.r.p1 = addr.r.p2+=l;
174 522b0689 2003-09-30 devnull if(addr.r.p1<0 || addr.r.p2>addr.f->b.nc)
175 76193d7c 2003-09-30 devnull error(Erange);
176 76193d7c 2003-09-30 devnull return addr;
177 76193d7c 2003-09-30 devnull }
178 76193d7c 2003-09-30 devnull
179 76193d7c 2003-09-30 devnull Address
180 76193d7c 2003-09-30 devnull lineaddr(Posn l, Address addr, int sign)
181 76193d7c 2003-09-30 devnull {
182 76193d7c 2003-09-30 devnull int n;
183 76193d7c 2003-09-30 devnull int c;
184 76193d7c 2003-09-30 devnull File *f = addr.f;
185 76193d7c 2003-09-30 devnull Address a;
186 76193d7c 2003-09-30 devnull Posn p;
187 76193d7c 2003-09-30 devnull
188 76193d7c 2003-09-30 devnull a.f = f;
189 76193d7c 2003-09-30 devnull if(sign >= 0){
190 76193d7c 2003-09-30 devnull if(l == 0){
191 76193d7c 2003-09-30 devnull if(sign==0 || addr.r.p2==0){
192 76193d7c 2003-09-30 devnull a.r.p1 = a.r.p2 = 0;
193 76193d7c 2003-09-30 devnull return a;
194 76193d7c 2003-09-30 devnull }
195 76193d7c 2003-09-30 devnull a.r.p1 = addr.r.p2;
196 76193d7c 2003-09-30 devnull p = addr.r.p2-1;
197 76193d7c 2003-09-30 devnull }else{
198 76193d7c 2003-09-30 devnull if(sign==0 || addr.r.p2==0){
199 76193d7c 2003-09-30 devnull p = (Posn)0;
200 76193d7c 2003-09-30 devnull n = 1;
201 76193d7c 2003-09-30 devnull }else{
202 76193d7c 2003-09-30 devnull p = addr.r.p2-1;
203 76193d7c 2003-09-30 devnull n = filereadc(f, p++)=='\n';
204 76193d7c 2003-09-30 devnull }
205 76193d7c 2003-09-30 devnull while(n < l){
206 522b0689 2003-09-30 devnull if(p >= f->b.nc)
207 76193d7c 2003-09-30 devnull error(Erange);
208 76193d7c 2003-09-30 devnull if(filereadc(f, p++) == '\n')
209 76193d7c 2003-09-30 devnull n++;
210 76193d7c 2003-09-30 devnull }
211 76193d7c 2003-09-30 devnull a.r.p1 = p;
212 76193d7c 2003-09-30 devnull }
213 522b0689 2003-09-30 devnull while(p < f->b.nc && filereadc(f, p++)!='\n')
214 76193d7c 2003-09-30 devnull ;
215 76193d7c 2003-09-30 devnull a.r.p2 = p;
216 76193d7c 2003-09-30 devnull }else{
217 76193d7c 2003-09-30 devnull p = addr.r.p1;
218 76193d7c 2003-09-30 devnull if(l == 0)
219 76193d7c 2003-09-30 devnull a.r.p2 = addr.r.p1;
220 76193d7c 2003-09-30 devnull else{
221 76193d7c 2003-09-30 devnull for(n = 0; n<l; ){ /* always runs once */
222 76193d7c 2003-09-30 devnull if(p == 0){
223 76193d7c 2003-09-30 devnull if(++n != l)
224 76193d7c 2003-09-30 devnull error(Erange);
225 76193d7c 2003-09-30 devnull }else{
226 76193d7c 2003-09-30 devnull c = filereadc(f, p-1);
227 76193d7c 2003-09-30 devnull if(c != '\n' || ++n != l)
228 76193d7c 2003-09-30 devnull p--;
229 76193d7c 2003-09-30 devnull }
230 76193d7c 2003-09-30 devnull }
231 76193d7c 2003-09-30 devnull a.r.p2 = p;
232 76193d7c 2003-09-30 devnull if(p > 0)
233 76193d7c 2003-09-30 devnull p--;
234 76193d7c 2003-09-30 devnull }
235 76193d7c 2003-09-30 devnull while(p > 0 && filereadc(f, p-1)!='\n') /* lines start after a newline */
236 76193d7c 2003-09-30 devnull p--;
237 76193d7c 2003-09-30 devnull a.r.p1 = p;
238 76193d7c 2003-09-30 devnull }
239 76193d7c 2003-09-30 devnull return a;
240 76193d7c 2003-09-30 devnull }