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