Blame


1 b3994ec5 2003-12-11 devnull #include <u.h>
2 b3994ec5 2003-12-11 devnull #include <libc.h>
3 b3994ec5 2003-12-11 devnull #include <draw.h>
4 b3994ec5 2003-12-11 devnull #include <thread.h>
5 b3994ec5 2003-12-11 devnull #include <cursor.h>
6 b3994ec5 2003-12-11 devnull #include <mouse.h>
7 b3994ec5 2003-12-11 devnull #include <keyboard.h>
8 b3994ec5 2003-12-11 devnull #include <frame.h>
9 b3994ec5 2003-12-11 devnull #include <fcall.h>
10 b3994ec5 2003-12-11 devnull #include <plumb.h>
11 67dbeee5 2017-10-10 rsc #include <libsec.h>
12 b3994ec5 2003-12-11 devnull #include "dat.h"
13 b3994ec5 2003-12-11 devnull #include "fns.h"
14 b3994ec5 2003-12-11 devnull
15 b3994ec5 2003-12-11 devnull enum
16 b3994ec5 2003-12-11 devnull {
17 b3994ec5 2003-12-11 devnull None = 0,
18 b3994ec5 2003-12-11 devnull Fore = '+',
19 cbeb0b26 2006-04-01 devnull Back = '-'
20 b3994ec5 2003-12-11 devnull };
21 b3994ec5 2003-12-11 devnull
22 b3994ec5 2003-12-11 devnull enum
23 b3994ec5 2003-12-11 devnull {
24 b3994ec5 2003-12-11 devnull Char,
25 cbeb0b26 2006-04-01 devnull Line
26 b3994ec5 2003-12-11 devnull };
27 b3994ec5 2003-12-11 devnull
28 b3994ec5 2003-12-11 devnull int
29 b3994ec5 2003-12-11 devnull isaddrc(int r)
30 b3994ec5 2003-12-11 devnull {
31 ff4512ee 2011-07-11 rsc if(r && utfrune("0123456789+-/$.#,;?", r)!=nil)
32 b3994ec5 2003-12-11 devnull return TRUE;
33 b3994ec5 2003-12-11 devnull return FALSE;
34 b3994ec5 2003-12-11 devnull }
35 b3994ec5 2003-12-11 devnull
36 b3994ec5 2003-12-11 devnull /*
37 b3994ec5 2003-12-11 devnull * quite hard: could be almost anything but white space, but we are a little conservative,
38 b3994ec5 2003-12-11 devnull * aiming for regular expressions of alphanumerics and no white space
39 b3994ec5 2003-12-11 devnull */
40 b3994ec5 2003-12-11 devnull int
41 b3994ec5 2003-12-11 devnull isregexc(int r)
42 b3994ec5 2003-12-11 devnull {
43 b3994ec5 2003-12-11 devnull if(r == 0)
44 b3994ec5 2003-12-11 devnull return FALSE;
45 b3994ec5 2003-12-11 devnull if(isalnum(r))
46 b3994ec5 2003-12-11 devnull return TRUE;
47 b3994ec5 2003-12-11 devnull if(utfrune("^+-.*?#,;[]()$", r)!=nil)
48 b3994ec5 2003-12-11 devnull return TRUE;
49 b3994ec5 2003-12-11 devnull return FALSE;
50 b3994ec5 2003-12-11 devnull }
51 b3994ec5 2003-12-11 devnull
52 3d6e5cb5 2017-11-02 rsc // nlcounttopos starts at q0 and advances nl lines,
53 3d6e5cb5 2017-11-02 rsc // being careful not to walk past the end of the text,
54 3d6e5cb5 2017-11-02 rsc // and then nr chars, being careful not to walk past
55 3d6e5cb5 2017-11-02 rsc // the end of the current line.
56 3d6e5cb5 2017-11-02 rsc // It returns the final position.
57 3d6e5cb5 2017-11-02 rsc long
58 3d6e5cb5 2017-11-02 rsc nlcounttopos(Text *t, long q0, long nl, long nr)
59 3d6e5cb5 2017-11-02 rsc {
60 3d6e5cb5 2017-11-02 rsc while(nl > 0 && q0 < t->file->b.nc) {
61 3d6e5cb5 2017-11-02 rsc if(textreadc(t, q0++) == '\n')
62 3d6e5cb5 2017-11-02 rsc nl--;
63 3d6e5cb5 2017-11-02 rsc }
64 3d6e5cb5 2017-11-02 rsc if(nl > 0)
65 3d6e5cb5 2017-11-02 rsc return q0;
66 3d6e5cb5 2017-11-02 rsc while(nr > 0 && q0 < t->file->b.nc && textreadc(t, q0) != '\n') {
67 3d6e5cb5 2017-11-02 rsc q0++;
68 3d6e5cb5 2017-11-02 rsc nr--;
69 3d6e5cb5 2017-11-02 rsc }
70 3d6e5cb5 2017-11-02 rsc return q0;
71 3d6e5cb5 2017-11-02 rsc }
72 3d6e5cb5 2017-11-02 rsc
73 b3994ec5 2003-12-11 devnull Range
74 012a8a02 2004-10-22 devnull number(uint showerr, Text *t, Range r, int line, int dir, int size, int *evalp)
75 b3994ec5 2003-12-11 devnull {
76 b3994ec5 2003-12-11 devnull uint q0, q1;
77 b3994ec5 2003-12-11 devnull
78 b3994ec5 2003-12-11 devnull if(size == Char){
79 b3994ec5 2003-12-11 devnull if(dir == Fore)
80 b3994ec5 2003-12-11 devnull line = r.q1+line;
81 b3994ec5 2003-12-11 devnull else if(dir == Back){
82 b3994ec5 2003-12-11 devnull if(r.q0==0 && line>0)
83 b3994ec5 2003-12-11 devnull r.q0 = t->file->b.nc;
84 b3994ec5 2003-12-11 devnull line = r.q0 - line;
85 b3994ec5 2003-12-11 devnull }
86 b3994ec5 2003-12-11 devnull if(line<0 || line>t->file->b.nc)
87 b3994ec5 2003-12-11 devnull goto Rescue;
88 b3994ec5 2003-12-11 devnull *evalp = TRUE;
89 be22ae2d 2004-03-26 devnull return range(line, line);
90 b3994ec5 2003-12-11 devnull }
91 b3994ec5 2003-12-11 devnull q0 = r.q0;
92 b3994ec5 2003-12-11 devnull q1 = r.q1;
93 b3994ec5 2003-12-11 devnull switch(dir){
94 b3994ec5 2003-12-11 devnull case None:
95 b3994ec5 2003-12-11 devnull q0 = 0;
96 b3994ec5 2003-12-11 devnull q1 = 0;
97 b3994ec5 2003-12-11 devnull Forward:
98 b3994ec5 2003-12-11 devnull while(line>0 && q1<t->file->b.nc)
99 b3994ec5 2003-12-11 devnull if(textreadc(t, q1++) == '\n' || q1==t->file->b.nc)
100 b3994ec5 2003-12-11 devnull if(--line > 0)
101 b3994ec5 2003-12-11 devnull q0 = q1;
102 2bc9a13f 2013-07-31 rsc if(line==1 && q1==t->file->b.nc) // 6 goes to end of 5-line file
103 2bc9a13f 2013-07-31 rsc break;
104 b3994ec5 2003-12-11 devnull if(line > 0)
105 b3994ec5 2003-12-11 devnull goto Rescue;
106 b3994ec5 2003-12-11 devnull break;
107 b3994ec5 2003-12-11 devnull case Fore:
108 b3994ec5 2003-12-11 devnull if(q1 > 0)
109 012a8a02 2004-10-22 devnull while(q1<t->file->b.nc && textreadc(t, q1-1) != '\n')
110 b3994ec5 2003-12-11 devnull q1++;
111 b3994ec5 2003-12-11 devnull q0 = q1;
112 b3994ec5 2003-12-11 devnull goto Forward;
113 b3994ec5 2003-12-11 devnull case Back:
114 b3994ec5 2003-12-11 devnull if(q0 < t->file->b.nc)
115 b3994ec5 2003-12-11 devnull while(q0>0 && textreadc(t, q0-1)!='\n')
116 b3994ec5 2003-12-11 devnull q0--;
117 b3994ec5 2003-12-11 devnull q1 = q0;
118 b3994ec5 2003-12-11 devnull while(line>0 && q0>0){
119 b3994ec5 2003-12-11 devnull if(textreadc(t, q0-1) == '\n'){
120 b3994ec5 2003-12-11 devnull if(--line >= 0)
121 b3994ec5 2003-12-11 devnull q1 = q0;
122 b3994ec5 2003-12-11 devnull }
123 b3994ec5 2003-12-11 devnull --q0;
124 b3994ec5 2003-12-11 devnull }
125 a5841359 2007-03-26 devnull /* :1-1 is :0 = #0, but :1-2 is an error */
126 a5841359 2007-03-26 devnull if(line > 1)
127 b3994ec5 2003-12-11 devnull goto Rescue;
128 b3994ec5 2003-12-11 devnull while(q0>0 && textreadc(t, q0-1)!='\n')
129 b3994ec5 2003-12-11 devnull --q0;
130 b3994ec5 2003-12-11 devnull }
131 b3994ec5 2003-12-11 devnull *evalp = TRUE;
132 be22ae2d 2004-03-26 devnull return range(q0, q1);
133 b3994ec5 2003-12-11 devnull
134 b3994ec5 2003-12-11 devnull Rescue:
135 012a8a02 2004-10-22 devnull if(showerr)
136 b3994ec5 2003-12-11 devnull warning(nil, "address out of range\n");
137 b3994ec5 2003-12-11 devnull *evalp = FALSE;
138 b3994ec5 2003-12-11 devnull return r;
139 b3994ec5 2003-12-11 devnull }
140 b3994ec5 2003-12-11 devnull
141 b3994ec5 2003-12-11 devnull
142 b3994ec5 2003-12-11 devnull Range
143 012a8a02 2004-10-22 devnull regexp(uint showerr, Text *t, Range lim, Range r, Rune *pat, int dir, int *foundp)
144 b3994ec5 2003-12-11 devnull {
145 b3994ec5 2003-12-11 devnull int found;
146 b3994ec5 2003-12-11 devnull Rangeset sel;
147 b3994ec5 2003-12-11 devnull int q;
148 b3994ec5 2003-12-11 devnull
149 b3994ec5 2003-12-11 devnull if(pat[0] == '\0' && rxnull()){
150 012a8a02 2004-10-22 devnull if(showerr)
151 012a8a02 2004-10-22 devnull warning(nil, "no previous regular expression\n");
152 b3994ec5 2003-12-11 devnull *foundp = FALSE;
153 b3994ec5 2003-12-11 devnull return r;
154 b3994ec5 2003-12-11 devnull }
155 b3994ec5 2003-12-11 devnull if(pat[0] && rxcompile(pat) == FALSE){
156 b3994ec5 2003-12-11 devnull *foundp = FALSE;
157 b3994ec5 2003-12-11 devnull return r;
158 b3994ec5 2003-12-11 devnull }
159 b3994ec5 2003-12-11 devnull if(dir == Back)
160 b3994ec5 2003-12-11 devnull found = rxbexecute(t, r.q0, &sel);
161 b3994ec5 2003-12-11 devnull else{
162 b3994ec5 2003-12-11 devnull if(lim.q0 < 0)
163 b3994ec5 2003-12-11 devnull q = Infinity;
164 b3994ec5 2003-12-11 devnull else
165 b3994ec5 2003-12-11 devnull q = lim.q1;
166 b3994ec5 2003-12-11 devnull found = rxexecute(t, nil, r.q1, q, &sel);
167 b3994ec5 2003-12-11 devnull }
168 012a8a02 2004-10-22 devnull if(!found && showerr)
169 b3994ec5 2003-12-11 devnull warning(nil, "no match for regexp\n");
170 b3994ec5 2003-12-11 devnull *foundp = found;
171 b3994ec5 2003-12-11 devnull return sel.r[0];
172 b3994ec5 2003-12-11 devnull }
173 b3994ec5 2003-12-11 devnull
174 b3994ec5 2003-12-11 devnull Range
175 012a8a02 2004-10-22 devnull address(uint showerr, Text *t, Range lim, Range ar, void *a, uint q0, uint q1, int (*getc)(void*, uint), int *evalp, uint *qp)
176 b3994ec5 2003-12-11 devnull {
177 b3994ec5 2003-12-11 devnull int dir, size, npat;
178 b3994ec5 2003-12-11 devnull int prevc, c, nc, n;
179 b3994ec5 2003-12-11 devnull uint q;
180 b3994ec5 2003-12-11 devnull Rune *pat;
181 b3994ec5 2003-12-11 devnull Range r, nr;
182 b3994ec5 2003-12-11 devnull
183 b3994ec5 2003-12-11 devnull r = ar;
184 b3994ec5 2003-12-11 devnull q = q0;
185 b3994ec5 2003-12-11 devnull dir = None;
186 b3994ec5 2003-12-11 devnull size = Line;
187 b3994ec5 2003-12-11 devnull c = 0;
188 b3994ec5 2003-12-11 devnull while(q < q1){
189 b3994ec5 2003-12-11 devnull prevc = c;
190 b3994ec5 2003-12-11 devnull c = (*getc)(a, q++);
191 b3994ec5 2003-12-11 devnull switch(c){
192 b3994ec5 2003-12-11 devnull default:
193 b3994ec5 2003-12-11 devnull *qp = q-1;
194 b3994ec5 2003-12-11 devnull return r;
195 b3994ec5 2003-12-11 devnull case ';':
196 b3994ec5 2003-12-11 devnull ar = r;
197 b3994ec5 2003-12-11 devnull /* fall through */
198 b3994ec5 2003-12-11 devnull case ',':
199 b3994ec5 2003-12-11 devnull if(prevc == 0) /* lhs defaults to 0 */
200 b3994ec5 2003-12-11 devnull r.q0 = 0;
201 b3994ec5 2003-12-11 devnull if(q>=q1 && t!=nil && t->file!=nil) /* rhs defaults to $ */
202 b3994ec5 2003-12-11 devnull r.q1 = t->file->b.nc;
203 b3994ec5 2003-12-11 devnull else{
204 012a8a02 2004-10-22 devnull nr = address(showerr, t, lim, ar, a, q, q1, getc, evalp, &q);
205 b3994ec5 2003-12-11 devnull r.q1 = nr.q1;
206 b3994ec5 2003-12-11 devnull }
207 b3994ec5 2003-12-11 devnull *qp = q;
208 b3994ec5 2003-12-11 devnull return r;
209 b3994ec5 2003-12-11 devnull case '+':
210 b3994ec5 2003-12-11 devnull case '-':
211 b3994ec5 2003-12-11 devnull if(*evalp && (prevc=='+' || prevc=='-'))
212 b3994ec5 2003-12-11 devnull if((nc=(*getc)(a, q))!='#' && nc!='/' && nc!='?')
213 012a8a02 2004-10-22 devnull r = number(showerr, t, r, 1, prevc, Line, evalp); /* do previous one */
214 b3994ec5 2003-12-11 devnull dir = c;
215 b3994ec5 2003-12-11 devnull break;
216 b3994ec5 2003-12-11 devnull case '.':
217 b3994ec5 2003-12-11 devnull case '$':
218 b3994ec5 2003-12-11 devnull if(q != q0+1){
219 b3994ec5 2003-12-11 devnull *qp = q-1;
220 b3994ec5 2003-12-11 devnull return r;
221 b3994ec5 2003-12-11 devnull }
222 b3994ec5 2003-12-11 devnull if(*evalp)
223 b3994ec5 2003-12-11 devnull if(c == '.')
224 b3994ec5 2003-12-11 devnull r = ar;
225 b3994ec5 2003-12-11 devnull else
226 be22ae2d 2004-03-26 devnull r = range(t->file->b.nc, t->file->b.nc);
227 b3994ec5 2003-12-11 devnull if(q < q1)
228 b3994ec5 2003-12-11 devnull dir = Fore;
229 b3994ec5 2003-12-11 devnull else
230 b3994ec5 2003-12-11 devnull dir = None;
231 b3994ec5 2003-12-11 devnull break;
232 b3994ec5 2003-12-11 devnull case '#':
233 b3994ec5 2003-12-11 devnull if(q==q1 || (c=(*getc)(a, q++))<'0' || '9'<c){
234 b3994ec5 2003-12-11 devnull *qp = q-1;
235 b3994ec5 2003-12-11 devnull return r;
236 b3994ec5 2003-12-11 devnull }
237 b3994ec5 2003-12-11 devnull size = Char;
238 b3994ec5 2003-12-11 devnull /* fall through */
239 b3994ec5 2003-12-11 devnull case '0': case '1': case '2': case '3': case '4':
240 b3994ec5 2003-12-11 devnull case '5': case '6': case '7': case '8': case '9':
241 b3994ec5 2003-12-11 devnull n = c -'0';
242 b3994ec5 2003-12-11 devnull while(q<q1){
243 a82a8b63 2018-09-19 r nc = (*getc)(a, q++);
244 a82a8b63 2018-09-19 r if(nc<'0' || '9'<nc){
245 b3994ec5 2003-12-11 devnull q--;
246 b3994ec5 2003-12-11 devnull break;
247 b3994ec5 2003-12-11 devnull }
248 a82a8b63 2018-09-19 r n = n*10+(nc-'0');
249 b3994ec5 2003-12-11 devnull }
250 b3994ec5 2003-12-11 devnull if(*evalp)
251 012a8a02 2004-10-22 devnull r = number(showerr, t, r, n, dir, size, evalp);
252 b3994ec5 2003-12-11 devnull dir = None;
253 b3994ec5 2003-12-11 devnull size = Line;
254 b3994ec5 2003-12-11 devnull break;
255 b3994ec5 2003-12-11 devnull case '?':
256 b3994ec5 2003-12-11 devnull dir = Back;
257 b3994ec5 2003-12-11 devnull /* fall through */
258 b3994ec5 2003-12-11 devnull case '/':
259 b3994ec5 2003-12-11 devnull npat = 0;
260 b3994ec5 2003-12-11 devnull pat = nil;
261 b3994ec5 2003-12-11 devnull while(q<q1){
262 b3994ec5 2003-12-11 devnull c = (*getc)(a, q++);
263 b3994ec5 2003-12-11 devnull switch(c){
264 b3994ec5 2003-12-11 devnull case '\n':
265 b3994ec5 2003-12-11 devnull --q;
266 b3994ec5 2003-12-11 devnull goto out;
267 b3994ec5 2003-12-11 devnull case '\\':
268 b3994ec5 2003-12-11 devnull pat = runerealloc(pat, npat+1);
269 b3994ec5 2003-12-11 devnull pat[npat++] = c;
270 b3994ec5 2003-12-11 devnull if(q == q1)
271 b3994ec5 2003-12-11 devnull goto out;
272 b3994ec5 2003-12-11 devnull c = (*getc)(a, q++);
273 b3994ec5 2003-12-11 devnull break;
274 b3994ec5 2003-12-11 devnull case '/':
275 b3994ec5 2003-12-11 devnull goto out;
276 b3994ec5 2003-12-11 devnull }
277 b3994ec5 2003-12-11 devnull pat = runerealloc(pat, npat+1);
278 b3994ec5 2003-12-11 devnull pat[npat++] = c;
279 b3994ec5 2003-12-11 devnull }
280 b3994ec5 2003-12-11 devnull out:
281 b3994ec5 2003-12-11 devnull pat = runerealloc(pat, npat+1);
282 b3994ec5 2003-12-11 devnull pat[npat] = 0;
283 b3994ec5 2003-12-11 devnull if(*evalp)
284 012a8a02 2004-10-22 devnull r = regexp(showerr, t, lim, r, pat, dir, evalp);
285 b3994ec5 2003-12-11 devnull free(pat);
286 b3994ec5 2003-12-11 devnull dir = None;
287 b3994ec5 2003-12-11 devnull size = Line;
288 b3994ec5 2003-12-11 devnull break;
289 b3994ec5 2003-12-11 devnull }
290 b3994ec5 2003-12-11 devnull }
291 b3994ec5 2003-12-11 devnull if(*evalp && dir != None)
292 012a8a02 2004-10-22 devnull r = number(showerr, t, r, 1, dir, Line, evalp); /* do previous one */
293 b3994ec5 2003-12-11 devnull *qp = q;
294 b3994ec5 2003-12-11 devnull return r;
295 b3994ec5 2003-12-11 devnull }