Annotation of researchv9/jtools/src/sam/sam.c, revision 1.1

1.1     ! root        1: #include "sam.h"
        !             2: #include <setjmp.h>
        !             3: #include <signal.h>
        !             4: 
        !             5: typedef struct Patlist{
        !             6:        int     nalloc;
        !             7:        int     nused;
        !             8:        String  **ptr;
        !             9: }Patlist;
        !            10: 
        !            11: uchar  genbuf[BLOCKSIZE];
        !            12: char   *home;
        !            13: int    io;
        !            14: int    panicking;
        !            15: int    rescuing;
        !            16: Mod    modnum;
        !            17: String genstr;
        !            18: String rhs;
        !            19: String wd;
        !            20: String cmdstr;
        !            21: int    intr();
        !            22: int    rescue();
        !            23: char   *getenv();
        !            24: File   *current();
        !            25: File   *tofile();
        !            26: File   *getfile();
        !            27: File   *curfile;
        !            28: File   *flist;
        !            29: File   *cmd;
        !            30: jmp_buf        mainloop;
        !            31: Filelist tempfile;
        !            32: int    quitok=TRUE;
        !            33: Patlist        globstr;
        !            34: Patlist        pattern;
        !            35: int    downloaded;
        !            36: int    dflag;
        !            37: int    Rflag;
        !            38: int    zflag;
        !            39: char   *machine;
        !            40: int    dounlock;
        !            41: 
        !            42: main(argc, argv)
        !            43:        uchar *argv[];
        !            44: {
        !            45:        register i;
        !            46:        int (*onintr)();
        !            47:        while(argc>1 && argv[1][0]=='-'){
        !            48:                switch(argv[1][1]){
        !            49:                case 'd':
        !            50:                        dflag++;
        !            51:                        break;
        !            52:                case 'r':
        !            53:                        --argc, argv++;
        !            54:                        if(argc==1){
        !            55:                                dprint("usage: sam [-d] -r machine\n");
        !            56:                                return 1;
        !            57:                        }
        !            58:                        machine=(char *)argv[1];
        !            59:                        break;
        !            60:                case 'z':
        !            61:                        zflag++;
        !            62:                        break;
        !            63:                case 'R':
        !            64:                        Rflag++;
        !            65:                        break;
        !            66: #ifdef SUN
        !            67:                case 't':
        !            68:                case 'x':
        !            69:                case '=':
        !            70:                case 'W':
        !            71:                        sunarg(&argv, &argc);
        !            72:                        break;
        !            73: #endif
        !            74:                default:
        !            75:                        dprint("sam: unknown flag %c\n", argv[1][1]);
        !            76:                        return 1;
        !            77:                }
        !            78:                --argc, argv++;
        !            79:        }
        !            80:        allocinit();
        !            81:        Fstart();
        !            82:        strinit(&cmdstr);
        !            83:        strinit(&lastpat);
        !            84:        strinit(&lastregexp);
        !            85:        strinit(&genstr);
        !            86:        strinit(&rhs);
        !            87:        strinit(&wd);
        !            88:        gcnew(tempfile.ptr, 0);
        !            89:        strinit(&unixcmd);
        !            90:        straddc(&unixcmd, '\0');
        !            91:        home=getenv("HOME");
        !            92:        if(home==0)
        !            93:                home="/tmp";
        !            94:        if(!dflag){
        !            95:                if(machine)
        !            96: #ifdef SUN
        !            97:                        connectboot(machine,zflag); /* doesn't return */
        !            98: #else
        !            99:                        connectto(machine);
        !           100: #endif
        !           101:                if(!Rflag){
        !           102:                        if(!bootterm(zflag))
        !           103:                                return 1;
        !           104:                }
        !           105:                rawmode(1);
        !           106:                if(machine)
        !           107:                        join();
        !           108:                downloaded=1;
        !           109:        }
        !           110:        if(argc>1){
        !           111:                for(i=1; i<argc; i++)
        !           112:                        if(!setjmp(mainloop)){
        !           113:                                strdup(&genstr, argv[i]);
        !           114:                                Fsetname(newfile());
        !           115:                        }
        !           116:        }else if(!downloaded)
        !           117:                newfile()->state=Clean;
        !           118:        modnum++;
        !           119:        onintr=signal(SIGINT, intr);
        !           120:        if(onintr)
        !           121:                signal(SIGINT, onintr);
        !           122:        onintr=signal(SIGHUP, rescue);
        !           123:        if(onintr)
        !           124:                signal(SIGHUP, onintr);
        !           125:        if(file.nused)
        !           126:                current(file.ptr[0]);
        !           127:        (void)setjmp(mainloop);
        !           128:        cmdloop();
        !           129:        trytoquit();    /* if we already q'ed, quitok will be TRUE */
        !           130:        if(downloaded)
        !           131:                rawmode(0);
        !           132:        return 0;
        !           133: }
        !           134: panic(s)
        !           135:        char *s;
        !           136: {
        !           137:        if(!panicking++ && !setjmp(mainloop)){
        !           138:                dprint("sam: panic: %s\n", s);
        !           139:                rescue();
        !           140:        }
        !           141:        abort();
        !           142: }
        !           143: rescue(){
        !           144:        register i, nblank=0;
        !           145:        register File *f;
        !           146:        uchar buf[128];
        !           147:        signal(SIGHUP, SIG_IGN);
        !           148:        if(rescuing++)
        !           149:                exit(1);
        !           150:        io= -1;
        !           151:        for(i=0; i<file.nused; i++){
        !           152:                f=file.ptr[i];
        !           153:                if(f==cmd || f->nbytes==0 || f->state!=Dirty)
        !           154:                        continue;
        !           155:                if(io==-1){
        !           156:                        strcpy(buf, (uchar *)home);
        !           157:                        strcpy(buf+strlen(buf), (uchar *)"/sam.save");
        !           158:                        io=creat((char *)buf, 0777);
        !           159:                        if(io<0)
        !           160:                                return;
        !           161:                }
        !           162:                strcpy(buf, f->name.s);
        !           163:                if(buf[0]==0)
        !           164:                        sprint(buf, "nameless.%d", nblank++);
        !           165:                fprint(io, "/usr/jerq/lib/samsave '%s' $* <<'---%s'\n",
        !           166:                        (char *)buf, (char *)buf);
        !           167:                addr.r.p1=0, addr.r.p2=f->nbytes;
        !           168:                writeio(f);
        !           169:                fprint(io, "\n---%s\n", (char *)buf);
        !           170:        }
        !           171:        if(panicking)
        !           172:                abort();
        !           173:        exit(0);
        !           174: }
        !           175: hiccough(s)
        !           176:        char *s;
        !           177: {
        !           178:        if(rescuing)
        !           179:                exit(1);
        !           180:        if(s)
        !           181:                dprint("%s\n", s);
        !           182:        resetcmd();
        !           183:        resetxec();
        !           184:        compactok();
        !           185:        if(io>0)
        !           186:                close(io);
        !           187:        if(undobuf->nbytes)
        !           188:                Bdelete(undobuf, (Posn)0, undobuf->nbytes);
        !           189:        update();
        !           190:        if(curfile && curfile->state==Unread)
        !           191:                curfile->state=Clean;
        !           192:        dounlock=TRUE;
        !           193:        if(downloaded && curfile && curfile->state!=Unread)
        !           194:                outTs(Hcurrent, curfile->tag);
        !           195:        longjmp(mainloop, 1);
        !           196: }
        !           197: intr(){
        !           198:        signal(SIGINT, intr);
        !           199:        error(Eintr);
        !           200: }
        !           201: trytoclose(f)
        !           202:        register File *f;
        !           203: {
        !           204:        if(f==cmd)      /* possible? */
        !           205:                return;
        !           206:        if(f->state==Dirty && !f->closeok){
        !           207:                f->closeok=TRUE;
        !           208:                error_s(Emodified,
        !           209:                    f->name.s[0]?(char *)f->name.s : "nameless file");
        !           210:        }
        !           211:        if(downloaded && f->rasp)
        !           212:                outTs(Hclose, f->tag);
        !           213:        delfile(f);
        !           214:        if(f==curfile)
        !           215:                current((File *)0);
        !           216: }
        !           217: trytoquit(){
        !           218:        register c;
        !           219:        register File *f;
        !           220:        extern int eof;
        !           221:        if(!quitok)
        !           222:                for(c=0; c<file.nused; c++){
        !           223:                        f=file.ptr[c];
        !           224:                        if(f!=cmd && f->state==Dirty){
        !           225:                                quitok=TRUE;
        !           226:                                eof=FALSE;
        !           227:                                error(Echanges);
        !           228:                        }
        !           229:                }
        !           230: }
        !           231: load(f)
        !           232:        register File *f;
        !           233: {
        !           234:        Address saveaddr;
        !           235:        strdupstr(&genstr, &f->name);
        !           236:        filename(f);
        !           237:        if(f->name.s[0]){
        !           238:                saveaddr=addr;
        !           239:                edit(f, 'I');
        !           240:                addr=saveaddr;
        !           241:        }else
        !           242:                f->state=Clean;
        !           243:        Fupdate(f, FALSE, TRUE);
        !           244: }
        !           245: update(){
        !           246:        register i, anymod;
        !           247:        register File *f;
        !           248:        settempfile();
        !           249:        for(anymod=i=0; i<tempfile.nused; i++){
        !           250:                f=tempfile.ptr[i];
        !           251:                if(f==cmd)      /* cmd gets done in main() */
        !           252:                        continue;
        !           253:                if(f->mod==modnum && Fupdate(f, FALSE, downloaded))
        !           254:                        anymod++;
        !           255:                if(f->rasp)
        !           256:                        telldot(f);
        !           257:        }
        !           258:        if(anymod)
        !           259:                modnum++;
        !           260: }
        !           261: File *
        !           262: current(f)
        !           263:        register File *f;
        !           264: {
        !           265:        return curfile=f;
        !           266: }
        !           267: edit(f, cmd)
        !           268:        register File *f;
        !           269: {
        !           270:        register empty=TRUE;
        !           271:        Posn p;
        !           272:        int nonascii;
        !           273:        if(cmd=='r')
        !           274:                Fdelete(f, addr.r.p1, addr.r.p2);
        !           275:        if(cmd=='e' || cmd=='I'){
        !           276:                Fdelete(f, (Posn)0, f->nbytes);
        !           277:                addr.r.p2=f->nbytes;
        !           278:        }else if(f->nbytes!=0 || (f->name.s[0] && strcmp(genstr.s, f->name.s)!=0))
        !           279:                empty=FALSE;
        !           280:        if((io=open((char *)genstr.s, 0))<0)
        !           281:                error_s(Eopen, (char *)genstr.s);
        !           282:        p=readio(f, &nonascii, empty);
        !           283:        closeio((cmd=='e' || cmd=='I')? -1 : p);
        !           284:        if(cmd=='r')
        !           285:                f->dot.r.p1=addr.r.p2, f->dot.r.p2=addr.r.p2+p;
        !           286:        else
        !           287:                f->dot.r.p1=f->dot.r.p2=0;
        !           288:        quitok=f->closeok=empty;
        !           289:        state(f, empty && !nonascii? Clean : Dirty);
        !           290:        if(cmd=='e')
        !           291:                filename(f);
        !           292: }
        !           293: getname(f, s, save)
        !           294:        register File *f;
        !           295:        register String *s;
        !           296: {
        !           297:        register c, i;
        !           298:        strzero(&genstr);
        !           299:        if(s==0 || (c=s->s[0])==0){             /* no name provided */
        !           300:                if(f)
        !           301:                        strdupstr(&genstr, &f->name);
        !           302:                else
        !           303:                        straddc(&genstr, '\0');
        !           304:                goto Return;
        !           305:        }
        !           306:        if(c!=' ' && c!='\t')
        !           307:                error(Eblank);
        !           308:        for(i=0; (c=s->s[i])==' ' || c=='\t'; i++)
        !           309:                ;
        !           310:        while(s->s[i]>' ')
        !           311:                straddc(&genstr, s->s[i++]);
        !           312:        if(s->s[i])
        !           313:                error(Enewline);
        !           314:        straddc(&genstr, '\0');
        !           315:        if(f && (save || f->name.s[0]==0)){
        !           316:                Fsetname(f);
        !           317:                if(strcmp(f->name.s, genstr.s)){
        !           318:                        quitok=f->closeok=FALSE;
        !           319:                        f->inumber=0;
        !           320:                        f->date=0;
        !           321:                        state(f, Dirty); /* if it's 'e', fix later */
        !           322:                }
        !           323:        }
        !           324:     Return:
        !           325:        return genstr.n-1;      /* strlen(name) */
        !           326: }
        !           327: filename(f)
        !           328:        register File *f;
        !           329: {
        !           330:        dprint("%c%c%c %s\n", " '"[f->state==Dirty],
        !           331:                "-+"[f->rasp!=0], " ."[f==curfile], genstr.s);
        !           332: }
        !           333: undo()
        !           334: {
        !           335:        register File *f;
        !           336:        register i;
        !           337:        Mod max;
        !           338:        if((max=curfile->mod)==0)
        !           339:                return;
        !           340:        settempfile();
        !           341:        for(i=0; i<tempfile.nused; i++){
        !           342:                f=tempfile.ptr[i];
        !           343:                if(f!=cmd && f->mod==max)
        !           344:                        undostep(f);
        !           345:        }
        !           346: }
        !           347: undostep(f)
        !           348:        register File *f;
        !           349: {
        !           350:        register Buffer *t;
        !           351:        register changes;
        !           352:        Mark mark;
        !           353:        t=f->transcript;
        !           354:        changes=Fupdate(f, TRUE, TRUE);
        !           355:        Bread(t, (uchar *)&mark, sizeof mark, f->markp);
        !           356:        Bdelete(t, f->markp, t->nbytes);
        !           357:        f->markp=mark.p;
        !           358:        f->dot.r=mark.dot;
        !           359:        f->mark=mark.mark;
        !           360:        f->mod=mark.m;
        !           361:        f->closeok=mark.s1!=Dirty;
        !           362:        if(mark.s1==Dirty)
        !           363:                quitok=FALSE;
        !           364:        if(f->state==Clean && mark.s1==Clean && changes)
        !           365:                state(f, Dirty);
        !           366:        else
        !           367:                state(f, mark.s1);
        !           368: }
        !           369: cd(str)
        !           370:        String *str;
        !           371: {
        !           372:        register i;
        !           373:        register File *f;
        !           374:        readcmd(tempstr((uchar *)"/bin/pwd", 9));
        !           375:        strdupstr(&wd, &genstr);
        !           376:        if(wd.s[0]==0){
        !           377:                wd.n=0;
        !           378:                warn(Wpwd);
        !           379:        }else if(wd.s[wd.n-2]=='\n'){
        !           380:                --wd.n;
        !           381:                wd.s[wd.n-1]='/';
        !           382:        }
        !           383:        if(chdir(getname((File *)0, str, FALSE)? (char *)genstr.s : home))
        !           384:                syserror("chdir");
        !           385:        settempfile();
        !           386:        for(i=0; i<tempfile.nused; i++){
        !           387:                f=tempfile.ptr[i];
        !           388:                if(f!=cmd && f->name.s[0]!='/' && f->name.s[0]!=0){
        !           389:                        strinsert(&f->name, &wd, (Posn)0);
        !           390:                        sortname(f);
        !           391:                }
        !           392:        }
        !           393: }
        !           394: readcmd(s)
        !           395:        String *s;
        !           396: {
        !           397:        if(flist==0)
        !           398:                (flist=Fopen())->state=Clean;
        !           399:        addr.r.p1=0, addr.r.p2=flist->nbytes;
        !           400:        Unix(flist, '<', s, FALSE);
        !           401:        Fupdate(flist, FALSE, FALSE);
        !           402:        flist->mod=0;
        !           403:        strzero(&genstr);
        !           404:        strinsure(&genstr, flist->nbytes);
        !           405:        Fchars(flist, genstr.s, (Posn)0, flist->nbytes);
        !           406:        genstr.n=flist->nbytes;
        !           407:        straddc(&genstr, '\0');
        !           408: }
        !           409: loadflist(s)
        !           410:        register String *s;
        !           411: {
        !           412:        register c, i;
        !           413:        c=s->s[0];
        !           414:        for(i=0; s->s[i]==' ' || s->s[i]=='\t'; i++)
        !           415:                ;
        !           416:        if((c==' ' || c=='\t') && s->s[i]!='\n'){
        !           417:                if(s->s[i]=='<'){
        !           418:                        strdelete(s, 0L, (long)i+1);
        !           419:                        readcmd(s);
        !           420:                }else{
        !           421:                        strzero(&genstr);
        !           422:                        while((c=s->s[i++]) && c!='\n')
        !           423:                                straddc(&genstr, c);
        !           424:                        straddc(&genstr, '\0');
        !           425:                }
        !           426:        }else{
        !           427:                if(c!='\n')
        !           428:                        error(Eblank);
        !           429:                strdup(&genstr, (uchar *)"");
        !           430:        }
        !           431:        return genstr.s[0];
        !           432: }
        !           433: File *
        !           434: readflist(readall, delete)
        !           435: {
        !           436:        register Posn i;
        !           437:        register c;
        !           438:        register File *f;
        !           439:        for(i=0,f=0; f==0 || readall || delete; ){
        !           440:                strdelete(&genstr, (Posn)0, i);
        !           441:                for(i=0; (c=genstr.s[i])==' ' || c=='\t' || c=='\n'; i++)
        !           442:                        ;
        !           443:                if(i>=genstr.n)
        !           444:                        break;
        !           445:                strdelete(&genstr, (Posn)0, i);
        !           446:                for(i=0; (c=genstr.s[i]) && c!=' ' && c!='\t' && c!='\n'; i++)
        !           447:                        ;
        !           448:                if(i==0)
        !           449:                        break;
        !           450:                genstr.s[i++]=0;
        !           451:                f=lookfile();
        !           452:                if(delete){
        !           453:                        if(f==0)
        !           454:                                warn_s(Wfile, (char *)genstr.s);
        !           455:                        else
        !           456:                                trytoclose(f);
        !           457:                }else if(f==0 && readall)
        !           458:                        Fsetname(f=newfile());
        !           459:        }
        !           460:        return f;
        !           461: }
        !           462: File *
        !           463: tofile(s)
        !           464:        String *s;
        !           465: {
        !           466:        register File *f;
        !           467:        if(s->s[0]!=' ')
        !           468:                error(Eblank);
        !           469:        if(loadflist(s)==0)
        !           470:                f=lookfile();   /* empty string ==> nameless file */
        !           471:        else if((f=readflist(FALSE, FALSE))==0)
        !           472:                error_s(Emenu, (char *)genstr.s);
        !           473:        return current(f);
        !           474: }
        !           475: File *
        !           476: getfile(s)
        !           477:        String *s;
        !           478: {
        !           479:        register File *f;
        !           480:        if(loadflist(s)==0)
        !           481:                Fsetname(f=newfile());
        !           482:        else if((f=readflist(TRUE, FALSE))==0)
        !           483:                error(Eblank);
        !           484:        return current(f);
        !           485: }
        !           486: closefiles(f, s)
        !           487:        File *f;
        !           488:        register String *s;
        !           489: {
        !           490:        if(s->s[0]==0){
        !           491:                if(f==0)
        !           492:                        error(Enofile);
        !           493:                trytoclose(f);
        !           494:                return;
        !           495:        }
        !           496:        if(s->s[0]!=' ')
        !           497:                error(Eblank);
        !           498:        if(loadflist(s)==0)
        !           499:                error(Enewline);
        !           500:        readflist(FALSE, TRUE);
        !           501: }
        !           502: move(f, addr2)
        !           503:        register File *f;
        !           504:        Address addr2;
        !           505: {
        !           506:        if(addr.r.p2<=addr2.r.p2){
        !           507:                Fdelete(f, addr.r.p1, addr.r.p2);
        !           508:                copy(f, addr2);
        !           509:        }else if(addr.r.p1>=addr2.r.p2){
        !           510:                copy(f, addr2);
        !           511:                Fdelete(f, addr.r.p1, addr.r.p2);
        !           512:        }else
        !           513:                error(Eoverlap);
        !           514: }
        !           515: copy(f, addr2)
        !           516:        register File *f;
        !           517:        Address addr2;
        !           518: {
        !           519:        register Posn p;
        !           520:        register ni;
        !           521:        for(p=addr.r.p1; p<addr.r.p2; p+=ni){
        !           522:                ni=addr.r.p2-p;
        !           523:                if(ni>BLOCKSIZE)
        !           524:                        ni=BLOCKSIZE;
        !           525:                Fchars(f, genbuf, p, p+ni);
        !           526:                Finsert(addr2.f, tempstr(genbuf, ni), addr2.r.p2);
        !           527:        }
        !           528:        addr2.f->dot.r.p2=addr2.r.p2+(f->dot.r.p2-f->dot.r.p1);
        !           529:        addr2.f->dot.r.p1=addr2.r.p2;
        !           530: }
        !           531: Posn
        !           532: nlcount(f, p0, p1)
        !           533:        register File *f;
        !           534:        register Posn p0, p1;
        !           535: {
        !           536:        register Posn nl=0;
        !           537:        Fgetcset(f, p0);
        !           538:        while(p0++<p1)
        !           539:                if(Fgetc(f)=='\n')
        !           540:                        nl++;
        !           541:        return nl;
        !           542: }
        !           543: printposn(f, charsonly)
        !           544:        register File *f;
        !           545: {
        !           546:        register Posn l1, l2;
        !           547:        if(!charsonly){
        !           548:                l1=1+nlcount(f, (Posn)0, addr.r.p1);
        !           549:                l2=l1+nlcount(f, addr.r.p1, addr.r.p2);
        !           550:                /* check if addr ends with '\n' */
        !           551:                if(addr.r.p2>0 && addr.r.p2>addr.r.p1 && (Fgetcset(f, addr.r.p2-1),Fgetc(f)=='\n'))
        !           552:                        --l2;
        !           553:                dprint("%lud", l1);
        !           554:                if(l2!=l1)
        !           555:                        dprint(",%lud", l2);
        !           556:                dprint("; ");
        !           557:        }
        !           558:        dprint("#%lud", addr.r.p1);
        !           559:        if(addr.r.p2!=addr.r.p1)
        !           560:                dprint(",#%lud", addr.r.p2);
        !           561:        dprint("\n");
        !           562: }
        !           563: settempfile(){
        !           564:        if(tempfile.nalloc<file.nused){
        !           565:                gcfree((uchar *)tempfile.ptr);
        !           566:                gcnew(tempfile.ptr, file.nused);
        !           567:                tempfile.nalloc=file.nused;
        !           568:        }
        !           569:        tempfile.nused=file.nused;
        !           570:        bcopy((uchar *)&file.ptr[0], (uchar *)&file.ptr[file.nused],
        !           571:                (uchar *)&tempfile.ptr[0], 1);
        !           572: }

unix.superglobalmegacorp.com

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