Annotation of researchv9/jtools/src/sam/address.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.