Annotation of 43BSD/contrib/B/src/bed/ins2.c, revision 1.1

1.1     ! root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
        !             2: static char rcsid[] = "$Header: ins2.c,v 2.4 84/10/26 12:08:24 guido Exp $";
        !             3: 
        !             4: /*
        !             5:  * B editor -- Insert characters from keyboard.
        !             6:  */
        !             7: 
        !             8: #include "b.h"
        !             9: #include "bobj.h"
        !            10: #include "node.h"
        !            11: #include "supr.h"
        !            12: #include "queu.h"
        !            13: #include "gram.h"
        !            14: #include "tabl.h"
        !            15: 
        !            16: 
        !            17: /*
        !            18:  * Insert a character.
        !            19:  */
        !            20: 
        !            21: Visible bool
        !            22: ins_char(ep, c, alt_c)
        !            23:        register environ *ep;
        !            24:        int c;
        !            25:        int alt_c;
        !            26: {
        !            27:        auto queue q = Qnil;
        !            28:        auto queue qf = Qnil;
        !            29:        auto value copyout();
        !            30:        auto string str;
        !            31:        char buf[2];
        !            32:        int where;
        !            33:        bool spwhere;
        !            34: 
        !            35:        higher(ep);
        !            36:        shrink(ep);
        !            37:        if (index("({[`'\"", c) && !ishole(ep)) {
        !            38:                /* Surround something.  Wonder what will happen! */
        !            39:                qf = (queue) copyout(ep);
        !            40:                if (!delbody(ep)) {
        !            41:                        qrelease(qf);
        !            42:                        return No;
        !            43:                }
        !            44:        }
        !            45:        fixit(ep);
        !            46:        ep->changed = Yes;
        !            47:        buf[0] = c;
        !            48:        buf[1] = 0;
        !            49:        if (!ins_string(ep, buf, &q, alt_c))
        !            50:                return No;
        !            51:        if (!emptyqueue(q) || !emptyqueue(qf)) {
        !            52:                /* Slight variation on app_queue */
        !            53:                if (!emptyqueue(qf) && emptyqueue(q))
        !            54:                        ritevhole(ep); /* Wizardry.  Why does this work? */
        !            55:                spwhere = ep->spflag;
        !            56:                ep->spflag = No;
        !            57:                where = focoffset(ep);
        !            58:                markpath(&ep->focus, 1);
        !            59:                ep->spflag = spwhere;
        !            60:                if (ep->mode == FHOLE && ep->s2 > 0) {
        !            61:                        /* If we just caused a suggestion, insert the remains
        !            62:                           after the suggested text, not after its first character. */
        !            63:                        str = "";
        !            64:                        if (!soften(ep, &str, 0)) {
        !            65:                                ep->mode = ATEND;
        !            66:                                leftvhole(ep);
        !            67:                                if (symbol(tree(ep->focus)) == Hole) {
        !            68:                                        ep->mode = ATBEGIN;
        !            69:                                        leftvhole(ep);
        !            70:                                }
        !            71:                        }
        !            72:                }
        !            73:                if (!emptyqueue(q)) { /* Re-insert stuff queued by ins_string */
        !            74:                        if (!ins_queue(ep, &q, &q))
        !            75:                                return No;
        !            76:                        where += spwhere;
        !            77:                        spwhere = No;
        !            78:                }
        !            79:                if (!emptyqueue(qf)) { /* Re-insert deleted old focus */
        !            80:                        firstmarked(&ep->focus, 1) || Abort();
        !            81:                        fixfocus(ep, where);
        !            82:                        if (!ins_queue(ep, &qf, &qf))
        !            83:                                return No;
        !            84:                }
        !            85:                firstmarked(&ep->focus, 1) || Abort();
        !            86:                unmkpath(&ep->focus, 1);
        !            87:                ep->spflag = No;
        !            88:                fixfocus(ep, where + spwhere);
        !            89:        }
        !            90:        return Yes;
        !            91: }
        !            92: 
        !            93: 
        !            94: /*
        !            95:  * Insert a newline.
        !            96:  */
        !            97: 
        !            98: Visible bool
        !            99: ins_newline(ep)
        !           100:        register environ *ep;
        !           101: {
        !           102:        register node n;
        !           103:        register int sym;
        !           104:        auto bool mayindent;
        !           105: 
        !           106:        ep->changed = Yes;
        !           107:        if (!fiddle(ep, &mayindent))
        !           108:                return No;
        !           109:        for (;;) {
        !           110:                switch (ep->mode) {
        !           111: 
        !           112:                case VHOLE:
        !           113:                        ep->mode = ATEND;
        !           114:                        continue;
        !           115: 
        !           116:                case FHOLE:
        !           117:                        ep->s2 = lenitem(ep);
        !           118:                        if (!fix_move(ep))
        !           119:                                return No;
        !           120:                        continue;
        !           121: 
        !           122:                case ATEND:
        !           123:                        if (!joinstring(&ep->focus, "\n", No, 0, mayindent)) {
        !           124:                                if (!move_on(ep))
        !           125:                                        return No;
        !           126:                                continue;
        !           127:                        }
        !           128:                        s_downi(ep, 2);
        !           129:                        s_downi(ep, 1);
        !           130:                        ep->mode = WHOLE;
        !           131:                        Assert((sym = symbol(tree(ep->focus))) == Hole || sym == Optional);
        !           132:                        return Yes;
        !           133: 
        !           134:                case ATBEGIN:
        !           135:                        n = tree(ep->focus);
        !           136:                        if (Type(n) == Tex) {
        !           137:                                ep->mode = ATEND;
        !           138:                                continue;
        !           139:                        }
        !           140:                        sym = symbol(n);
        !           141:                        if (sym == Hole || sym == Optional) {
        !           142:                                ep->mode = WHOLE;
        !           143:                                continue;
        !           144:                        }
        !           145:                        n = nodecopy(n);
        !           146:                        if (!fitstring(&ep->focus, "\n", 0)) {
        !           147:                                if (!down(&ep->focus))
        !           148:                                        ep->mode = ATEND;
        !           149:                                noderelease(n);
        !           150:                                continue;
        !           151:                        }
        !           152:                        s_downrite(ep);
        !           153:                        if (fitnode(&ep->focus, n)) {
        !           154:                                noderelease(n);
        !           155:                                s_up(ep);
        !           156:                                s_down(ep);
        !           157:                                ep->mode = WHOLE;
        !           158:                                return Yes;
        !           159:                        }
        !           160:                        s_up(ep);
        !           161:                        s_down(ep);
        !           162:                        if (!fitnode(&ep->focus, n)) {
        !           163:                                noderelease(n);
        !           164: #ifndef NDEBUG
        !           165:                                debug("[Sorry, I don't see how to insert a newline here]");
        !           166: #endif NDEBUG
        !           167:                                return No;
        !           168:                        }
        !           169:                        noderelease(n);
        !           170:                        ep->mode = ATBEGIN;
        !           171:                        return Yes;
        !           172: 
        !           173:                case WHOLE:
        !           174:                        Assert((sym = symbol(tree(ep->focus))) == Hole || sym == Optional);
        !           175:                        if (!fitstring(&ep->focus, "\n", 0)) {
        !           176:                                ep->mode = ATEND;
        !           177:                                continue;
        !           178:                        }
        !           179:                        s_downi(ep, 1);
        !           180:                        Assert((sym = symbol(tree(ep->focus))) == Hole || sym == Optional);
        !           181:                        ep->mode = WHOLE;
        !           182:                        return Yes;
        !           183: 
        !           184:                default:
        !           185:                        Abort();
        !           186: 
        !           187:                }
        !           188:        }
        !           189: }
        !           190: 
        !           191: 
        !           192: /*
        !           193:  * Refinement for ins_newline() to do the initial processing.
        !           194:  */
        !           195: 
        !           196: Hidden bool
        !           197: fiddle(ep, pmayindent)
        !           198:        register environ *ep;
        !           199:        bool *pmayindent;
        !           200: {
        !           201:        register int level;
        !           202:        auto string str = "";
        !           203: 
        !           204:        higher(ep);
        !           205:        while (rnarrow(ep))
        !           206:                ;
        !           207:        fixit(ep);
        !           208:        soften(ep, &str, 0);
        !           209:        higher(ep);
        !           210:        *pmayindent = Yes;
        !           211:        if (atdedent(ep)) {
        !           212:                *pmayindent = No;
        !           213:                s_up(ep);
        !           214:                level = Level(ep->focus);
        !           215:                delfocus(&ep->focus);
        !           216:                if (symbol(tree(ep->focus)) == Hole) {
        !           217:                        if (hackhack(ep))
        !           218:                                return Yes;
        !           219:                }
        !           220:                while (Level(ep->focus) >= level) {
        !           221:                        if (!nexthole(ep)) {
        !           222:                                ep->mode = ATEND;
        !           223:                                break;
        !           224:                        }
        !           225:                }
        !           226:                if (ep->mode == ATEND) {
        !           227:                        leftvhole(ep);
        !           228:                        ep->mode = ATEND;
        !           229:                        while (Level(ep->focus) >= level) {
        !           230:                                if (!up(&ep->focus))
        !           231:                                        return No;
        !           232:                        }
        !           233:                }
        !           234:                return Yes;
        !           235:        }
        !           236:        return Yes;
        !           237: }
        !           238: 
        !           239: 
        !           240: /*
        !           241:  * "Hier komen de houthakkers."
        !           242:  *
        !           243:  * Incredibly ugly hack to delete a join whose second child begins with \n,
        !           244:  * such as a suite after an IF, FOR or WHILE or  unit heading.
        !           245:  * Inspects the parent node.
        !           246:  * If this has rp[0] ands rp[1] both empty, replace it by its first child.
        !           247:  * (caller assures this makes sense).
        !           248:  * Return Yes if this happened AND rp[1] contained a \t.
        !           249:  */
        !           250: 
        !           251: Hidden Procedure
        !           252: hackhack(ep)
        !           253:        environ *ep;
        !           254: {
        !           255:        node n;
        !           256:        int ich = ichild(ep->focus);
        !           257:        string *rp;
        !           258: 
        !           259:        if (!up(&ep->focus))
        !           260:                return No;
        !           261:        higher(ep);
        !           262:        rp = noderepr(tree(ep->focus));
        !           263:        if (!Fw_zero(rp[0]) || !Fw_zero(rp[1])) {
        !           264:                s_downi(ep, ich);
        !           265:                return No;
        !           266:        }
        !           267:        n = nodecopy(firstchild(tree(ep->focus)));
        !           268:        delfocus(&ep->focus);
        !           269:        replace(&ep->focus, n);
        !           270:        ep->mode = ATEND;
        !           271:        return rp[1] && rp[1][0] == '\t';
        !           272: }
        !           273:        
        !           274: 
        !           275: /*
        !           276:  * Refinement for fiddle() to find out whether we are at a possible
        !           277:  * decrease-indentation position.
        !           278:  */
        !           279: 
        !           280: Hidden bool
        !           281: atdedent(ep)
        !           282:        register environ *ep;
        !           283: {
        !           284:        register path pa;
        !           285:        register node npa;
        !           286:        register int i;
        !           287:        register int sym = symbol(tree(ep->focus));
        !           288: 
        !           289:        if (sym != Hole && sym != Optional)
        !           290:                return No;
        !           291:        if (ichild(ep->focus) != 1)
        !           292:                return No;
        !           293:        switch (ep->mode) {
        !           294:        case FHOLE:
        !           295:                if (ep->s1 != 1 || ep->s2 != 0)
        !           296:                        return No;
        !           297:                break;
        !           298:        case ATBEGIN:
        !           299:        case WHOLE:
        !           300:        case SUBSET:
        !           301:                break;
        !           302:        default:
        !           303:                return No;
        !           304:        }
        !           305:        pa = parent(ep->focus);
        !           306:        if (!pa)
        !           307:                return No;
        !           308:        npa = tree(pa);
        !           309:        if (fwidth(noderepr(npa)[0]) >= 0)
        !           310:                return No;
        !           311:        for (i = nchildren(npa); i > 1; --i) {
        !           312:                sym = symbol(child(npa, i));
        !           313:                if (sym != Hole && sym != Optional)
        !           314:                        return No;
        !           315:        }
        !           316:        return Yes; /* Sigh! */
        !           317: }
        !           318: 
        !           319: /*
        !           320:  * Refinement for ins_node() and fiddle() to find the next hole,
        !           321:  * skipping blank space only.
        !           322:  */
        !           323: 
        !           324: Hidden bool
        !           325: nexthole(ep)
        !           326:        register environ *ep;
        !           327: {
        !           328:        register node n;
        !           329:        register int ich;
        !           330:        register string repr;
        !           331: 
        !           332:        do {
        !           333:                ich = ichild(ep->focus);
        !           334:                if (!up(&ep->focus))
        !           335:                        return No;
        !           336:                higher(ep);
        !           337:                n = tree(ep->focus);
        !           338:                repr = noderepr(n)[ich];
        !           339:                if (!Fw_zero(repr) && !allspaces(repr))
        !           340:                        return No;
        !           341:        } while (ich >= nchildren(n));
        !           342:        s_downi(ep, ich+1);
        !           343:        return Yes;
        !           344: }

unix.superglobalmegacorp.com

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