Blob
1 #include "sam.h"2 #include "parse.h"4 Address addr;5 String lastpat;6 int patset;7 File *menu;9 File *matchfile(String*);10 Address charaddr(Posn, Address, int);12 Address13 address(Addr *ap, Address a, int sign)14 {15 File *f = a.f;16 Address a1, a2;18 do{19 switch(ap->type){20 case 'l':21 case '#':22 a = (*(ap->type=='#'?charaddr:lineaddr))(ap->num, a, sign);23 break;25 case '.':26 a = f->dot;27 break;29 case '$':30 a.r.p1 = a.r.p2 = f->b.nc;31 break;33 case '\'':34 a.r = f->mark;35 break;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, sign);44 a.r = sel.p[0];45 break;47 case '"':48 a = matchfile(ap->are)->dot;49 f = a.f;50 if(f->unread)51 load(f);52 break;54 case '*':55 a.r.p1 = 0, a.r.p2 = f->b.nc;56 return a;58 case ',':59 case ';':60 if(ap->left)61 a1 = address(ap->left, a, 0);62 else63 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 else72 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;80 case '+':81 case '-':82 sign = 1;83 if(ap->type == '-')84 sign = -1;85 if(ap->next==0 || ap->next->type=='+' || ap->next->type=='-')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 }96 void97 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 }121 File *122 matchfile(String *r)123 {124 File *f;125 File *match = 0;126 int i;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 }143 int144 filematch(File *f, String *r)145 {146 char *c, buf[STRSIZE+100];147 String *t;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 }165 Address166 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 }179 Address180 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;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 start after a newline */236 p--;237 a.r.p1 = p;238 }239 return a;240 }