1*7ab27030SDavid du Colombier #include <u.h>
2*7ab27030SDavid du Colombier #include <libc.h>
3*7ab27030SDavid du Colombier #include <draw.h>
4*7ab27030SDavid du Colombier #include <memdraw.h>
5*7ab27030SDavid du Colombier #include <thread.h>
6*7ab27030SDavid du Colombier #include <cursor.h>
7*7ab27030SDavid du Colombier #include <mouse.h>
8*7ab27030SDavid du Colombier #include <keyboard.h>
9*7ab27030SDavid du Colombier #include <frame.h>
10*7ab27030SDavid du Colombier #include <plumb.h>
11*7ab27030SDavid du Colombier #include <html.h>
12*7ab27030SDavid du Colombier #include "dat.h"
13*7ab27030SDavid du Colombier #include "fns.h"
14*7ab27030SDavid du Colombier
15*7ab27030SDavid du Colombier void del(Text *, Text *, int, int, Rune *, int);
16*7ab27030SDavid du Colombier void delcol(Text *, Text *, int, int, Rune *, int);
17*7ab27030SDavid du Colombier void cut(Text *, Text *, int, int, Rune *, int);
18*7ab27030SDavid du Colombier void exit(Text *, Text *, int, int, Rune *, int);
19*7ab27030SDavid du Colombier void get(Text *, Text *, int, int, Rune *, int);
20*7ab27030SDavid du Colombier void go(Text *,Text *, int, int, Rune *, int);
21*7ab27030SDavid du Colombier void google(Text *,Text *, int, int, Rune *, int);
22*7ab27030SDavid du Colombier void new(Text*, Text *, int, int, Rune *, int);
23*7ab27030SDavid du Colombier void newcol(Text*, Text *, int, int, Rune *, int);
24*7ab27030SDavid du Colombier void paste(Text *, Text *, int, int, Rune *, int);
25*7ab27030SDavid du Colombier void sort(Text *, Text *, int, int, Rune *, int);
26*7ab27030SDavid du Colombier void stop(Text *, Text *, int, int, Rune *, int);
27*7ab27030SDavid du Colombier void debug(Text *, Text *, int, int, Rune *, int);
28*7ab27030SDavid du Colombier
29*7ab27030SDavid du Colombier typedef struct Exectab Exectab;
30*7ab27030SDavid du Colombier struct Exectab
31*7ab27030SDavid du Colombier {
32*7ab27030SDavid du Colombier Rune *name;
33*7ab27030SDavid du Colombier void (*fn)(Text *, Text *, int, int, Rune *, int);
34*7ab27030SDavid du Colombier int flag1;
35*7ab27030SDavid du Colombier int flag2;
36*7ab27030SDavid du Colombier };
37*7ab27030SDavid du Colombier
38*7ab27030SDavid du Colombier Exectab exectab[] = {
39*7ab27030SDavid du Colombier { L"Back", go, FALSE, XXX },
40*7ab27030SDavid du Colombier { L"Cut", cut, TRUE, TRUE },
41*7ab27030SDavid du Colombier { L"Debug", debug, XXX, XXX },
42*7ab27030SDavid du Colombier { L"Del", del, XXX, XXX },
43*7ab27030SDavid du Colombier { L"Delcol", delcol, FALSE, TRUE },
44*7ab27030SDavid du Colombier { L"Exit", exit, XXX, XXX },
45*7ab27030SDavid du Colombier { L"Get", get, XXX, XXX },
46*7ab27030SDavid du Colombier { L"Google", google, XXX, XXX },
47*7ab27030SDavid du Colombier { L"New", new, XXX, XXX },
48*7ab27030SDavid du Colombier { L"Newcol", newcol, XXX, XXX },
49*7ab27030SDavid du Colombier { L"Next", go, TRUE, XXX },
50*7ab27030SDavid du Colombier { L"Paste", paste, TRUE, XXX },
51*7ab27030SDavid du Colombier { L"Snarf", cut, TRUE, FALSE },
52*7ab27030SDavid du Colombier { L"Stop", stop, XXX, XXX },
53*7ab27030SDavid du Colombier { L"Sort", sort, XXX, XXX },
54*7ab27030SDavid du Colombier { nil, nil, 0, 0 },
55*7ab27030SDavid du Colombier };
56*7ab27030SDavid du Colombier
57*7ab27030SDavid du Colombier static
58*7ab27030SDavid du Colombier Exectab*
lookup(Rune * r,int n)59*7ab27030SDavid du Colombier lookup(Rune *r, int n)
60*7ab27030SDavid du Colombier {
61*7ab27030SDavid du Colombier Exectab *e;
62*7ab27030SDavid du Colombier int nr;
63*7ab27030SDavid du Colombier
64*7ab27030SDavid du Colombier r = skipbl(r, n, &n);
65*7ab27030SDavid du Colombier if(n == 0)
66*7ab27030SDavid du Colombier return nil;
67*7ab27030SDavid du Colombier findbl(r, n, &nr);
68*7ab27030SDavid du Colombier nr = n-nr;
69*7ab27030SDavid du Colombier for(e=exectab; e->name; e++)
70*7ab27030SDavid du Colombier if(runeeq(r, nr, e->name, runestrlen(e->name)) == TRUE)
71*7ab27030SDavid du Colombier return e;
72*7ab27030SDavid du Colombier return nil;
73*7ab27030SDavid du Colombier }
74*7ab27030SDavid du Colombier
75*7ab27030SDavid du Colombier int
isexecc(int c)76*7ab27030SDavid du Colombier isexecc(int c)
77*7ab27030SDavid du Colombier {
78*7ab27030SDavid du Colombier if(isalnum(c))
79*7ab27030SDavid du Colombier return 1;
80*7ab27030SDavid du Colombier return c=='<' || c=='|' || c=='>';
81*7ab27030SDavid du Colombier }
82*7ab27030SDavid du Colombier
83*7ab27030SDavid du Colombier void
execute(Text * t,uint aq0,uint aq1,Text *)84*7ab27030SDavid du Colombier execute(Text *t, uint aq0, uint aq1, Text *)
85*7ab27030SDavid du Colombier {
86*7ab27030SDavid du Colombier uint q0, q1;
87*7ab27030SDavid du Colombier Rune *r, *s;
88*7ab27030SDavid du Colombier Exectab *e;
89*7ab27030SDavid du Colombier int c, n;
90*7ab27030SDavid du Colombier
91*7ab27030SDavid du Colombier q0 = aq0;
92*7ab27030SDavid du Colombier q1 = aq1;
93*7ab27030SDavid du Colombier if(q1 == q0){ /* expand to find word (actually file name) */
94*7ab27030SDavid du Colombier /* if in selection, choose selection */
95*7ab27030SDavid du Colombier if(t->q1>t->q0 && t->q0<=q0 && q0<=t->q1){
96*7ab27030SDavid du Colombier q0 = t->q0;
97*7ab27030SDavid du Colombier q1 = t->q1;
98*7ab27030SDavid du Colombier }else{
99*7ab27030SDavid du Colombier while(q1<t->rs.nr && isexecc(c=t->rs.r[q1]) && c!=':')
100*7ab27030SDavid du Colombier q1++;
101*7ab27030SDavid du Colombier while(q0>0 && isexecc(c=t->rs.r[q0-1]) && c!=':')
102*7ab27030SDavid du Colombier q0--;
103*7ab27030SDavid du Colombier if(q1 == q0)
104*7ab27030SDavid du Colombier return;
105*7ab27030SDavid du Colombier }
106*7ab27030SDavid du Colombier }
107*7ab27030SDavid du Colombier r = runemalloc(q1-q0);
108*7ab27030SDavid du Colombier runemove(r, t->rs.r+q0, q1-q0);
109*7ab27030SDavid du Colombier e = lookup(r, q1-q0);
110*7ab27030SDavid du Colombier if(e){
111*7ab27030SDavid du Colombier s = skipbl(r, q1-q0, &n);
112*7ab27030SDavid du Colombier s = findbl(s, n, &n);
113*7ab27030SDavid du Colombier s = skipbl(s, n, &n);
114*7ab27030SDavid du Colombier (*e->fn)(t, seltext, e->flag1, e->flag2, s, n);
115*7ab27030SDavid du Colombier }
116*7ab27030SDavid du Colombier free(r);
117*7ab27030SDavid du Colombier }
118*7ab27030SDavid du Colombier
119*7ab27030SDavid du Colombier void
newcol(Text * et,Text *,int,int,Rune *,int)120*7ab27030SDavid du Colombier newcol(Text *et, Text *, int, int, Rune *, int)
121*7ab27030SDavid du Colombier {
122*7ab27030SDavid du Colombier Column *c;
123*7ab27030SDavid du Colombier
124*7ab27030SDavid du Colombier c = rowadd(et->row, nil, -1);
125*7ab27030SDavid du Colombier if(c)
126*7ab27030SDavid du Colombier winsettag(coladd(c, nil, nil, -1));
127*7ab27030SDavid du Colombier }
128*7ab27030SDavid du Colombier
129*7ab27030SDavid du Colombier void
delcol(Text * t,Text *,int,int,Rune *,int)130*7ab27030SDavid du Colombier delcol(Text *t, Text *, int, int, Rune *, int)
131*7ab27030SDavid du Colombier {
132*7ab27030SDavid du Colombier Column *c;
133*7ab27030SDavid du Colombier
134*7ab27030SDavid du Colombier c = t->col;
135*7ab27030SDavid du Colombier if(c==nil || colclean(c)==0)
136*7ab27030SDavid du Colombier return;
137*7ab27030SDavid du Colombier
138*7ab27030SDavid du Colombier rowclose(c->row, c, TRUE);
139*7ab27030SDavid du Colombier }
140*7ab27030SDavid du Colombier
141*7ab27030SDavid du Colombier void
del(Text * et,Text *,int flag1,int,Rune *,int)142*7ab27030SDavid du Colombier del(Text *et, Text *, int flag1, int, Rune *, int)
143*7ab27030SDavid du Colombier {
144*7ab27030SDavid du Colombier if(et->w==nil)
145*7ab27030SDavid du Colombier return;
146*7ab27030SDavid du Colombier
147*7ab27030SDavid du Colombier if(flag1 || winclean(et->w, FALSE))
148*7ab27030SDavid du Colombier colclose(et->col, et->w, TRUE);
149*7ab27030SDavid du Colombier }
150*7ab27030SDavid du Colombier
151*7ab27030SDavid du Colombier void
sort(Text * et,Text *,int,int,Rune *,int)152*7ab27030SDavid du Colombier sort(Text *et, Text *, int, int, Rune *, int)
153*7ab27030SDavid du Colombier {
154*7ab27030SDavid du Colombier if(et->col)
155*7ab27030SDavid du Colombier colsort(et->col);
156*7ab27030SDavid du Colombier }
157*7ab27030SDavid du Colombier
158*7ab27030SDavid du Colombier void
exit(Text *,Text *,int,int,Rune *,int)159*7ab27030SDavid du Colombier exit(Text *, Text *, int, int, Rune *, int)
160*7ab27030SDavid du Colombier {
161*7ab27030SDavid du Colombier sendul(cexit, 0);
162*7ab27030SDavid du Colombier threadexits(nil);
163*7ab27030SDavid du Colombier }
164*7ab27030SDavid du Colombier
165*7ab27030SDavid du Colombier void
debug(Text *,Text *,int,int,Rune *,int)166*7ab27030SDavid du Colombier debug(Text *, Text *, int, int, Rune *, int)
167*7ab27030SDavid du Colombier {
168*7ab27030SDavid du Colombier Column *c;
169*7ab27030SDavid du Colombier int i, j;
170*7ab27030SDavid du Colombier
171*7ab27030SDavid du Colombier for(j=0; j<row.ncol; j++){
172*7ab27030SDavid du Colombier c = row.col[j];
173*7ab27030SDavid du Colombier for(i=0; i<c->nw; i++){
174*7ab27030SDavid du Colombier fprint(2, "Col: %d; Win: %d\n", j, i);
175*7ab27030SDavid du Colombier windebug(c->w[i]);
176*7ab27030SDavid du Colombier }
177*7ab27030SDavid du Colombier }
178*7ab27030SDavid du Colombier }
179*7ab27030SDavid du Colombier
180*7ab27030SDavid du Colombier void
stop(Text * t,Text *,int,int,Rune *,int)181*7ab27030SDavid du Colombier stop(Text *t, Text *, int, int, Rune *, int)
182*7ab27030SDavid du Colombier {
183*7ab27030SDavid du Colombier if(t==nil || t->w==nil)
184*7ab27030SDavid du Colombier return;
185*7ab27030SDavid du Colombier
186*7ab27030SDavid du Colombier pageabort(&t->w->page);
187*7ab27030SDavid du Colombier }
188*7ab27030SDavid du Colombier
189*7ab27030SDavid du Colombier void
get(Text * t,Text *,int,int,Rune *,int)190*7ab27030SDavid du Colombier get(Text *t, Text *, int, int, Rune *, int)
191*7ab27030SDavid du Colombier {
192*7ab27030SDavid du Colombier Window *w;
193*7ab27030SDavid du Colombier int dohist;
194*7ab27030SDavid du Colombier
195*7ab27030SDavid du Colombier if(t==nil || t->w==nil)
196*7ab27030SDavid du Colombier return;
197*7ab27030SDavid du Colombier w = t->w;
198*7ab27030SDavid du Colombier if(w->url.rs.nr == 0)
199*7ab27030SDavid du Colombier return;
200*7ab27030SDavid du Colombier
201*7ab27030SDavid du Colombier dohist = FALSE;
202*7ab27030SDavid du Colombier if(w->page.url==nil || runestreq(w->page.url->act, w->url.rs)==FALSE)
203*7ab27030SDavid du Colombier dohist = TRUE;
204*7ab27030SDavid du Colombier
205*7ab27030SDavid du Colombier pageget(&w->page, &w->url.rs, nil, HGet, dohist);
206*7ab27030SDavid du Colombier }
207*7ab27030SDavid du Colombier
208*7ab27030SDavid du Colombier void
go(Text * et,Text * t,int isnext,int,Rune *,int)209*7ab27030SDavid du Colombier go(Text *et, Text *t, int isnext, int, Rune *, int)
210*7ab27030SDavid du Colombier {
211*7ab27030SDavid du Colombier if(et!=nil && et->w!=nil)
212*7ab27030SDavid du Colombier t = et;
213*7ab27030SDavid du Colombier if(t==nil || t->w==nil)
214*7ab27030SDavid du Colombier return;
215*7ab27030SDavid du Colombier
216*7ab27030SDavid du Colombier wingohist(t->w, isnext);
217*7ab27030SDavid du Colombier }
218*7ab27030SDavid du Colombier
219*7ab27030SDavid du Colombier void
cut(Text *,Text * t,int dosnarf,int docut,Rune *,int)220*7ab27030SDavid du Colombier cut(Text *, Text *t, int dosnarf, int docut, Rune *, int)
221*7ab27030SDavid du Colombier {
222*7ab27030SDavid du Colombier Runestr rs;
223*7ab27030SDavid du Colombier uint u;
224*7ab27030SDavid du Colombier
225*7ab27030SDavid du Colombier if(selpage){
226*7ab27030SDavid du Colombier if(dosnarf && !docut && !eqpt(selpage->top, selpage->bot))
227*7ab27030SDavid du Colombier pagesnarf(selpage);
228*7ab27030SDavid du Colombier return;
229*7ab27030SDavid du Colombier }
230*7ab27030SDavid du Colombier if(t==nil){
231*7ab27030SDavid du Colombier /* can only happen if seltext == nil */
232*7ab27030SDavid du Colombier return;
233*7ab27030SDavid du Colombier }
234*7ab27030SDavid du Colombier if(t->q0 > t->q1){
235*7ab27030SDavid du Colombier u = t->q0;
236*7ab27030SDavid du Colombier t->q0 = t->q1;
237*7ab27030SDavid du Colombier t->q1 =u;
238*7ab27030SDavid du Colombier }
239*7ab27030SDavid du Colombier
240*7ab27030SDavid du Colombier if(t->q0 == t->q1)
241*7ab27030SDavid du Colombier return;
242*7ab27030SDavid du Colombier
243*7ab27030SDavid du Colombier if(dosnarf){
244*7ab27030SDavid du Colombier rs.nr = t->q1-t->q0;
245*7ab27030SDavid du Colombier rs.r = runemalloc(rs.nr);
246*7ab27030SDavid du Colombier runemove(rs.r, t->rs.r+t->q0, rs.nr);
247*7ab27030SDavid du Colombier putsnarf(&rs);
248*7ab27030SDavid du Colombier closerunestr(&rs);
249*7ab27030SDavid du Colombier }
250*7ab27030SDavid du Colombier if(docut){
251*7ab27030SDavid du Colombier textdelete(t, t->q0, t->q1);
252*7ab27030SDavid du Colombier textsetselect(t, t->q0, t->q0);
253*7ab27030SDavid du Colombier if(t->w)
254*7ab27030SDavid du Colombier textscrdraw(t);
255*7ab27030SDavid du Colombier }else if(dosnarf) /* Snarf command */
256*7ab27030SDavid du Colombier argtext = t;
257*7ab27030SDavid du Colombier }
258*7ab27030SDavid du Colombier
259*7ab27030SDavid du Colombier void
paste(Text *,Text * t,int selectall,int,Rune *,int)260*7ab27030SDavid du Colombier paste(Text *, Text *t, int selectall, int, Rune *, int)
261*7ab27030SDavid du Colombier {
262*7ab27030SDavid du Colombier Runestr rs;
263*7ab27030SDavid du Colombier uint q1;
264*7ab27030SDavid du Colombier
265*7ab27030SDavid du Colombier if(t == nil)
266*7ab27030SDavid du Colombier return;
267*7ab27030SDavid du Colombier
268*7ab27030SDavid du Colombier getsnarf(&rs);
269*7ab27030SDavid du Colombier if(rs.nr == 0)
270*7ab27030SDavid du Colombier return;
271*7ab27030SDavid du Colombier
272*7ab27030SDavid du Colombier cut(t, t, FALSE, TRUE, nil, 0);
273*7ab27030SDavid du Colombier textinsert(t, t->q0, rs.r, rs.nr);
274*7ab27030SDavid du Colombier q1 = t->q0+rs.nr;
275*7ab27030SDavid du Colombier if(selectall)
276*7ab27030SDavid du Colombier textsetselect(t, t->q0, q1);
277*7ab27030SDavid du Colombier else
278*7ab27030SDavid du Colombier textsetselect(t, q1, q1);
279*7ab27030SDavid du Colombier if(t->w)
280*7ab27030SDavid du Colombier textscrdraw(t);
281*7ab27030SDavid du Colombier
282*7ab27030SDavid du Colombier closerunestr(&rs);
283*7ab27030SDavid du Colombier }
284*7ab27030SDavid du Colombier
285*7ab27030SDavid du Colombier typedef struct Expand Expand;
286*7ab27030SDavid du Colombier
287*7ab27030SDavid du Colombier struct Expand
288*7ab27030SDavid du Colombier {
289*7ab27030SDavid du Colombier uint q0;
290*7ab27030SDavid du Colombier uint q1;
291*7ab27030SDavid du Colombier Rune *name;
292*7ab27030SDavid du Colombier int nname;
293*7ab27030SDavid du Colombier int jump;
294*7ab27030SDavid du Colombier union{
295*7ab27030SDavid du Colombier Text *at;
296*7ab27030SDavid du Colombier Rune *ar;
297*7ab27030SDavid du Colombier };
298*7ab27030SDavid du Colombier int (*agetc)(void*, uint);
299*7ab27030SDavid du Colombier int a0;
300*7ab27030SDavid du Colombier int a1;
301*7ab27030SDavid du Colombier };
302*7ab27030SDavid du Colombier
303*7ab27030SDavid du Colombier int
expand(Text * t,uint q0,uint q1,Expand * e)304*7ab27030SDavid du Colombier expand(Text *t, uint q0, uint q1, Expand *e)
305*7ab27030SDavid du Colombier {
306*7ab27030SDavid du Colombier memset(e, 0, sizeof *e);
307*7ab27030SDavid du Colombier
308*7ab27030SDavid du Colombier /* if in selection, choose selection */
309*7ab27030SDavid du Colombier e->jump = TRUE;
310*7ab27030SDavid du Colombier if(q1==q0 && t->q1>t->q0 && t->q0<=q0 && q0<=t->q1){
311*7ab27030SDavid du Colombier q0 = t->q0;
312*7ab27030SDavid du Colombier q1 = t->q1;
313*7ab27030SDavid du Colombier if(t->what == Tag)
314*7ab27030SDavid du Colombier e->jump = FALSE;
315*7ab27030SDavid du Colombier }
316*7ab27030SDavid du Colombier if(q0 == q1){
317*7ab27030SDavid du Colombier while(q1<t->rs.nr && isalnum(t->rs.r[q1]))
318*7ab27030SDavid du Colombier q1++;
319*7ab27030SDavid du Colombier while(q0>0 && isalnum(t->rs.r[q0-1]))
320*7ab27030SDavid du Colombier q0--;
321*7ab27030SDavid du Colombier }
322*7ab27030SDavid du Colombier e->q0 = q0;
323*7ab27030SDavid du Colombier e->q1 = q1;
324*7ab27030SDavid du Colombier return q1 > q0;
325*7ab27030SDavid du Colombier }
326*7ab27030SDavid du Colombier
327*7ab27030SDavid du Colombier void
look3(Text * t,uint q0,uint q1)328*7ab27030SDavid du Colombier look3(Text *t, uint q0, uint q1)
329*7ab27030SDavid du Colombier {
330*7ab27030SDavid du Colombier Expand e;
331*7ab27030SDavid du Colombier Text *ct;
332*7ab27030SDavid du Colombier Runestr rs;
333*7ab27030SDavid du Colombier char buf[32];
334*7ab27030SDavid du Colombier Rune *r, c;
335*7ab27030SDavid du Colombier uint p;
336*7ab27030SDavid du Colombier int n;
337*7ab27030SDavid du Colombier
338*7ab27030SDavid du Colombier ct = seltext;
339*7ab27030SDavid du Colombier if(ct == nil)
340*7ab27030SDavid du Colombier ct = seltext = t;
341*7ab27030SDavid du Colombier if(expand(t, q0, q1, &e) == FALSE)
342*7ab27030SDavid du Colombier return;
343*7ab27030SDavid du Colombier if(plumbsendfd >= 0){
344*7ab27030SDavid du Colombier /* send whitespace-delimited word to plumber */
345*7ab27030SDavid du Colombier buf[0] = '\0';
346*7ab27030SDavid du Colombier if(q1 == q0){
347*7ab27030SDavid du Colombier if(t->q1>t->q0 && t->q0<=q0 && q0<=t->q1){
348*7ab27030SDavid du Colombier q0 = t->q0;
349*7ab27030SDavid du Colombier q1 = t->q1;
350*7ab27030SDavid du Colombier }else{
351*7ab27030SDavid du Colombier p = q0;
352*7ab27030SDavid du Colombier while(q0>0 && (c=t->rs.r[q0-1])!=L' ' && c!=L'\t' && c!=L'\n')
353*7ab27030SDavid du Colombier q0--;
354*7ab27030SDavid du Colombier while(q1<t->rs.nr && (c=t->rs.r[q1])!=L' ' && c!=L'\t' && c!=L'\n')
355*7ab27030SDavid du Colombier q1++;
356*7ab27030SDavid du Colombier if(q1 == q0)
357*7ab27030SDavid du Colombier return;
358*7ab27030SDavid du Colombier sprint(buf, "click=%d", p-q0);
359*7ab27030SDavid du Colombier }
360*7ab27030SDavid du Colombier }
361*7ab27030SDavid du Colombier rs.r = runemalloc(q1-q0);
362*7ab27030SDavid du Colombier runemove(rs.r, t->rs.r+q0, q1-q0);
363*7ab27030SDavid du Colombier rs.nr = q1-q0;
364*7ab27030SDavid du Colombier if(plumbrunestr(&rs, buf) >= 0){
365*7ab27030SDavid du Colombier closerunestr(&rs);
366*7ab27030SDavid du Colombier return;
367*7ab27030SDavid du Colombier }
368*7ab27030SDavid du Colombier /* plumber failed to match; fall through */
369*7ab27030SDavid du Colombier }
370*7ab27030SDavid du Colombier if(t == ct)
371*7ab27030SDavid du Colombier textsetselect(ct, e.q1, e.q1);
372*7ab27030SDavid du Colombier n = e.q1 - e.q0;
373*7ab27030SDavid du Colombier r = runemalloc(n);
374*7ab27030SDavid du Colombier runemove(r, t->rs.r+e.q0, n);
375*7ab27030SDavid du Colombier if(search(ct, r, n) && e.jump)
376*7ab27030SDavid du Colombier moveto(mousectl, addpt(frptofchar(ct, ct->p0), Pt(4, ct->font->height-4)));
377*7ab27030SDavid du Colombier
378*7ab27030SDavid du Colombier free(r);
379*7ab27030SDavid du Colombier }
380*7ab27030SDavid du Colombier
381*7ab27030SDavid du Colombier int
search(Text * ct,Rune * r,uint n)382*7ab27030SDavid du Colombier search(Text *ct, Rune *r, uint n)
383*7ab27030SDavid du Colombier {
384*7ab27030SDavid du Colombier uint q, nb, maxn;
385*7ab27030SDavid du Colombier int around;
386*7ab27030SDavid du Colombier Rune *s, *b, *c;
387*7ab27030SDavid du Colombier
388*7ab27030SDavid du Colombier if(n==0 || n>ct->rs.nr || 2*n>RBUFSIZE)
389*7ab27030SDavid du Colombier return FALSE;
390*7ab27030SDavid du Colombier
391*7ab27030SDavid du Colombier maxn = max(n*2, RBUFSIZE);
392*7ab27030SDavid du Colombier s = runemalloc(RBUFSIZE);
393*7ab27030SDavid du Colombier b = s;
394*7ab27030SDavid du Colombier nb = 0;
395*7ab27030SDavid du Colombier b[nb] = 0;
396*7ab27030SDavid du Colombier around = 0;
397*7ab27030SDavid du Colombier q = ct->q1;
398*7ab27030SDavid du Colombier for(;;){
399*7ab27030SDavid du Colombier if(q >= ct->rs.nr){
400*7ab27030SDavid du Colombier q = 0;
401*7ab27030SDavid du Colombier around = 1;
402*7ab27030SDavid du Colombier nb = 0;
403*7ab27030SDavid du Colombier b[nb] = 0;
404*7ab27030SDavid du Colombier }
405*7ab27030SDavid du Colombier if(nb > 0){
406*7ab27030SDavid du Colombier c = runestrchr(b, r[0]);
407*7ab27030SDavid du Colombier if(c == nil){
408*7ab27030SDavid du Colombier q += nb;
409*7ab27030SDavid du Colombier nb = 0;
410*7ab27030SDavid du Colombier b[nb] = 0;
411*7ab27030SDavid du Colombier if(around && q>=ct->q1)
412*7ab27030SDavid du Colombier break;
413*7ab27030SDavid du Colombier continue;
414*7ab27030SDavid du Colombier }
415*7ab27030SDavid du Colombier q += (c-b);
416*7ab27030SDavid du Colombier nb -= (c-b);
417*7ab27030SDavid du Colombier b = c;
418*7ab27030SDavid du Colombier }
419*7ab27030SDavid du Colombier /* reload if buffer covers neither string nor rest of file */
420*7ab27030SDavid du Colombier if(nb<n && nb!=ct->rs.nr-q){
421*7ab27030SDavid du Colombier nb = ct->rs.nr-q;
422*7ab27030SDavid du Colombier if(nb >= maxn)
423*7ab27030SDavid du Colombier nb = maxn-1;
424*7ab27030SDavid du Colombier runemove(s, ct->rs.r+q, nb);
425*7ab27030SDavid du Colombier b = s;
426*7ab27030SDavid du Colombier b[nb] = '\0';
427*7ab27030SDavid du Colombier }
428*7ab27030SDavid du Colombier /* this runeeq is fishy but the null at b[nb] makes it safe */
429*7ab27030SDavid du Colombier if(runeeq(b, n, r, n) == TRUE){
430*7ab27030SDavid du Colombier if(ct->w)
431*7ab27030SDavid du Colombier textshow(ct, q, q+n, 1);
432*7ab27030SDavid du Colombier else{
433*7ab27030SDavid du Colombier ct->q0 = q;
434*7ab27030SDavid du Colombier ct->q1 = q+n;
435*7ab27030SDavid du Colombier }
436*7ab27030SDavid du Colombier seltext = ct;
437*7ab27030SDavid du Colombier free(s);
438*7ab27030SDavid du Colombier return TRUE;
439*7ab27030SDavid du Colombier }
440*7ab27030SDavid du Colombier if(around && q>=ct->q1)
441*7ab27030SDavid du Colombier break;
442*7ab27030SDavid du Colombier --nb;
443*7ab27030SDavid du Colombier b++;
444*7ab27030SDavid du Colombier q++;
445*7ab27030SDavid du Colombier }
446*7ab27030SDavid du Colombier free(s);
447*7ab27030SDavid du Colombier return FALSE;
448*7ab27030SDavid du Colombier }
449*7ab27030SDavid du Colombier
450*7ab27030SDavid du Colombier Window*
lookpage(Rune * s,int n)451*7ab27030SDavid du Colombier lookpage(Rune *s, int n)
452*7ab27030SDavid du Colombier {
453*7ab27030SDavid du Colombier int i, j;
454*7ab27030SDavid du Colombier Window *w;
455*7ab27030SDavid du Colombier Column *c;
456*7ab27030SDavid du Colombier Page *p;
457*7ab27030SDavid du Colombier
458*7ab27030SDavid du Colombier /* avoid terminal slash on directories */
459*7ab27030SDavid du Colombier if(n>1 && s[n-1] == '/')
460*7ab27030SDavid du Colombier --n;
461*7ab27030SDavid du Colombier for(j=0; j<row.ncol; j++){
462*7ab27030SDavid du Colombier c = row.col[j];
463*7ab27030SDavid du Colombier for(i=0; i<c->nw; i++){
464*7ab27030SDavid du Colombier w = c->w[i];
465*7ab27030SDavid du Colombier p = &w->page;
466*7ab27030SDavid du Colombier if(p->url && runeeq(p->url->src.r, p->url->src.nr, s, n))
467*7ab27030SDavid du Colombier if(w->col != nil)
468*7ab27030SDavid du Colombier return w;
469*7ab27030SDavid du Colombier }
470*7ab27030SDavid du Colombier }
471*7ab27030SDavid du Colombier return nil;
472*7ab27030SDavid du Colombier }
473*7ab27030SDavid du Colombier
474*7ab27030SDavid du Colombier Window *
openpage(Page * p,Runestr * rs)475*7ab27030SDavid du Colombier openpage(Page *p, Runestr *rs)
476*7ab27030SDavid du Colombier {
477*7ab27030SDavid du Colombier Window *w;
478*7ab27030SDavid du Colombier
479*7ab27030SDavid du Colombier if(!validurl(rs->r))
480*7ab27030SDavid du Colombier return nil;
481*7ab27030SDavid du Colombier
482*7ab27030SDavid du Colombier w = lookpage(rs->r, rs->nr);
483*7ab27030SDavid du Colombier if(w){
484*7ab27030SDavid du Colombier p = &w->page;
485*7ab27030SDavid du Colombier if(!p->col->safe && Dy(p->r)==0) /* window is obscured by full-column window */
486*7ab27030SDavid du Colombier colgrow(p->col, p->col->w[0], 1);
487*7ab27030SDavid du Colombier }else{
488*7ab27030SDavid du Colombier w = makenewwindow(p);
489*7ab27030SDavid du Colombier winsettag(w);
490*7ab27030SDavid du Colombier pageget(&w->page, rs, nil, HGet, TRUE);
491*7ab27030SDavid du Colombier }
492*7ab27030SDavid du Colombier return w;
493*7ab27030SDavid du Colombier }
494*7ab27030SDavid du Colombier
495*7ab27030SDavid du Colombier void
plumblook(Plumbmsg * m)496*7ab27030SDavid du Colombier plumblook(Plumbmsg *m)
497*7ab27030SDavid du Colombier {
498*7ab27030SDavid du Colombier Runestr rs;
499*7ab27030SDavid du Colombier
500*7ab27030SDavid du Colombier if(m->ndata >= BUFSIZE){
501*7ab27030SDavid du Colombier fprint(2, "insanely long file name (%d bytes) in plumb message (%.32s...)\n", m->ndata, m->data);
502*7ab27030SDavid du Colombier return;
503*7ab27030SDavid du Colombier }
504*7ab27030SDavid du Colombier if(m->data[0] == '\0')
505*7ab27030SDavid du Colombier return;
506*7ab27030SDavid du Colombier
507*7ab27030SDavid du Colombier bytetorunestr(m->data, &rs);
508*7ab27030SDavid du Colombier openpage(nil, &rs);
509*7ab27030SDavid du Colombier closerunestr(&rs);
510*7ab27030SDavid du Colombier }
511*7ab27030SDavid du Colombier
512*7ab27030SDavid du Colombier void
new(Text * et,Text *,int,int,Rune *,int)513*7ab27030SDavid du Colombier new(Text *et, Text *, int, int, Rune *, int)
514*7ab27030SDavid du Colombier {
515*7ab27030SDavid du Colombier if(et->col != nil)
516*7ab27030SDavid du Colombier winsettag(coladd(et->col, nil, nil, -1));
517*7ab27030SDavid du Colombier }
518*7ab27030SDavid du Colombier
519*7ab27030SDavid du Colombier void
google(Text *,Text *,int,int,Rune * arg,int narg)520*7ab27030SDavid du Colombier google(Text *, Text *, int, int, Rune *arg, int narg)
521*7ab27030SDavid du Colombier {
522*7ab27030SDavid du Colombier Runestr rs;
523*7ab27030SDavid du Colombier Rune *s;
524*7ab27030SDavid du Colombier
525*7ab27030SDavid du Colombier s = ucvt(arg);
526*7ab27030SDavid du Colombier rs.r = runesmprint("http://www.google.com/search?hl=en&ie=UTF-8&q=%.*S", narg, s);
527*7ab27030SDavid du Colombier rs.nr = runestrlen(rs.r);
528*7ab27030SDavid du Colombier openpage(nil, &rs);
529*7ab27030SDavid du Colombier free(s);
530*7ab27030SDavid du Colombier closerunestr(&rs);
531*7ab27030SDavid du Colombier }
532