Annotation of 43BSD/contrib/B/src/bed/inse.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
                      2: static char rcsid[] = "$Header: inse.c,v 2.4 85/02/14 13:27:09 timo Exp $";
                      3: 
                      4: /*
                      5:  * Subroutines (refinements) for ins_string() (see que2.c).
                      6:  */
                      7: 
                      8: #include "b.h"
                      9: #include "feat.h"
                     10: #include "bobj.h"
                     11: #include "node.h"
                     12: #include "gram.h"
                     13: #include "supr.h"
                     14: #include "tabl.h"
                     15: 
                     16: #include <ctype.h>
                     17: 
                     18: 
                     19: /*
                     20:  * Try to insert the character c in the focus *pp.
                     21:  */
                     22: 
                     23: Visible bool
                     24: insguess(pp, c, ep)
                     25:        path *pp;
                     26:        char c;
                     27:        environ *ep;
                     28: {
                     29:        path pa = parent(*pp);
                     30:        node n;
                     31:        int sympa = pa ? symbol(tree(pa)) : Rootsymbol;
                     32:        int ich = ichild(*pp);
                     33:        struct classinfo *ci = table[sympa].r_class[ich-1];
                     34:        classptr cp;
                     35:        string *rp;
                     36:        int code = Code(c);
                     37:        int sym;
                     38:        char buf[2];
                     39: 
                     40: #ifdef USERSUGG
                     41:        if (isinclass(Suggestion, ci)) {
                     42:                if (setsugg(pp, c, ep))
                     43:                        return Yes;
                     44:        }
                     45: #endif USERSUGG
                     46:        for (cp = ci->c_insert; *cp; cp += 2) {
                     47:                if (cp[0] == code)
                     48:                        break;
                     49:        }
                     50:        if (!*cp)
                     51:                return No;
                     52:        sym = cp[1];
                     53:        if (sym >= LEXICAL) {
                     54:                buf[0] = c;
                     55:                buf[1] = 0;
                     56:                replace(pp, (node) mk_text(buf));
                     57:                ep->mode = VHOLE;
                     58:                ep->s1 = 2*ich;
                     59:                ep->s2 = 1;
                     60:                return Yes;
                     61:        }
                     62:        Assert(sym < TABLEN);
                     63:        rp = table[sym].r_repr;
                     64:        n = table[sym].r_node;
                     65:        if (Fw_zero(rp[0])) {
                     66:                buf[0] = c;
                     67:                buf[1] = 0;
                     68:                setchild(&n, 1, (node) mk_text(buf));
                     69:                replace(pp, n);
                     70:                ep->mode = VHOLE;
                     71:                ep->s1 = 2;
                     72:                ep->s2 = 1;
                     73:                return Yes;
                     74:        }
                     75:        replace(pp, n);
                     76:        if (c == '\n' || c == '\r') {
                     77:                ep->mode = SUBSET;
                     78:                ep->s1 = ep->s2 = 2;
                     79:        }
                     80:        else {
                     81:                ep->mode = FHOLE;
                     82:                ep->s1 = 1;
                     83:                ep->s2 = 1;
                     84:        }
                     85:        return Yes;
                     86: }
                     87: 
                     88: 
                     89: /*
                     90:  * Test whether character `c' may be inserted in position `s2' in
                     91:  * child `ich' of node `n'; that child must be a Text.
                     92:  */
                     93: 
                     94: Visible bool
                     95: mayinsert(n, ich, s2, c)
                     96:        node n;
                     97:        int ich;
                     98:        int s2;
                     99:        register char c;
                    100: {
                    101:        int sympa = symbol(n);
                    102:        struct classinfo *ci;
                    103:        register classptr cp;
                    104:        register value v = (value) child(n, ich);
                    105:        register char c1;
                    106:        bool maycontinue();
                    107:        bool maystart();
                    108:        register bool (*fun1)() = s2 > 0 ? maystart : maycontinue;
                    109:        register bool (*fun)() = s2 > 0 ? maycontinue : maystart;
                    110: 
                    111:        Assert(v && v->type == Tex);
                    112:        Assert(sympa > 0 && sympa < TABLEN);
                    113:        ci = table[sympa].r_class[ich-1];
                    114:        Assert(ci && ci->c_class);
                    115:        c1 = Str(v)[0];
                    116:        for (cp = ci->c_class; *cp; ++cp) {
                    117:                if (*cp >= LEXICAL && (*fun1)(c1, *cp)) {
                    118:                        if ((*fun)(c, *cp))
                    119:                                return Yes;
                    120:                }
                    121:        }
                    122:        return No;
                    123: }
                    124: 
                    125: 
                    126: /*
                    127:  * Change a Fixed into a Variable node, given a string pointer variable
                    128:  * which contains the next characters to be inserted.
                    129:  * If the change is not appropriate, No is returned.
                    130:  * Otherwise, as many (though maybe zero) characters from the string
                    131:  * as possible will have been incorporated in the string node.
                    132:  */
                    133: 
                    134: Visible bool
                    135: soften(ep, pstr, alt_c)
                    136:        environ *ep;
                    137:        string *pstr;
                    138:        int alt_c;
                    139: {
                    140:        path pa = parent(ep->focus);
                    141:        node n;
                    142:        int sympa = pa ? symbol(tree(pa)) : Rootsymbol;
                    143:        struct classinfo *ci;
                    144:        register classptr cp;
                    145:        register int code;
                    146:        string repr;
                    147:        register struct table *tp;
                    148:        char buf[1024];
                    149: 
                    150:        if (ep->mode == VHOLE && (ep->s1&1))
                    151:                ep->mode = FHOLE;
                    152:        if (ep->mode != FHOLE || ep->s1 != 1 || ep->s2 <= 0 || !issuggestion(ep))
                    153:                return No;
                    154:        n = tree(ep->focus);
                    155:        repr = noderepr(n)[0];
                    156:        if (!repr || !isupper(repr[0]))
                    157:                return No;
                    158:        code = Code(repr[0]);
                    159:        ci = table[sympa].r_class[ichild(ep->focus) - 1];
                    160:        n = Nnil;
                    161:        for (cp = ci->c_insert; *cp; cp += 2) {
                    162:                if (cp[0] != code)
                    163:                        continue;
                    164:                if (cp[1] >= TABLEN)
                    165:                        continue;
                    166:                tp = &table[cp[1]];
                    167:                if (Fw_zero(tp->r_repr[0])) {
                    168:                        Assert(tp->r_class[0]->c_class[0] >= LEXICAL);
                    169:                        n = tp->r_node;
                    170:                        break;
                    171:                }
                    172:        }
                    173:        if (!n)
                    174:                return No;
                    175:        strncpy(buf, repr, ep->s2);
                    176:        buf[ep->s2] = 0;
                    177:        setchild(&n, 1, (node) mk_text(buf));
                    178:        if (!mayinsert(n, 1, ep->s2, repr[ep->s2])) {
                    179:                if (!**pstr || !mayinsert(n, 1, ep->s2, **pstr)
                    180:                        && (!alt_c || !mayinsert(n, 1, ep->s2, alt_c))) {
                    181:                        noderelease(n); /* Don't forget! */
                    182:                        return No;
                    183:                }
                    184:        }
                    185:        if (**pstr && mayinsert(n, 1, ep->s2, **pstr)) {
                    186:                do {
                    187:                        buf[ep->s2] = **pstr;
                    188:                        ++*pstr;
                    189:                        ++ep->s2;
                    190:                } while (ep->s2 < sizeof buf - 1 && **pstr
                    191:                                && mayinsert(n, 1, ep->s2, **pstr));
                    192:                buf[ep->s2] = 0;
                    193:                setchild(&n, 1, (node) mk_text(buf));
                    194:        }
                    195:        replace(&ep->focus, n);
                    196:        ep->mode = VHOLE;
                    197:        ep->s1 = 2;
                    198:        return Yes;
                    199: }
                    200: 
                    201: 
                    202: /*
                    203:  * Renew suggestion, or advance in old suggestion.
                    204:  * Return Yes if *pstr has been advanced.
                    205:  */
                    206: 
                    207: Visible bool
                    208: resuggest(ep, pstr, alt_c)
                    209:        environ *ep;
                    210:        string *pstr;
                    211:        int alt_c;
                    212: {
                    213:        struct table *tp;
                    214:        struct classinfo *ci;
                    215:        classptr cp;
                    216:        path pa;
                    217:        node nn;
                    218:        node n = tree(ep->focus);
                    219:        register string *oldrp = noderepr(n);
                    220:        register int ich = ep->s1/2;
                    221:        register string str = oldrp[ich];
                    222:        int oldsym = symbol(n);
                    223:        int childsym[MAXCHILD];
                    224:        string *newrp;
                    225:        int sympa;
                    226:        register int sym;
                    227:        int symfound = -1;
                    228:        register int i;
                    229:        int code;
                    230:        char buf[15]; /* Should be sufficient for all fixed texts */
                    231:        bool ok;
                    232:        bool anyok = No;
                    233: 
                    234:        if (!str || !**pstr || !issuggestion(ep))
                    235:                return No;
                    236:        /***** Change this if commands can be prefixes of others! *****/
                    237:        /***** Well, they can!
                    238:        if (!c)
                    239:                return No;
                    240:                *****/
                    241:        if (ich > 0 && ifmatch(ep, pstr, str, alt_c))
                    242:                /* Shortcut: sec. keyword, exact match will do just fine */
                    243:                return Yes;
                    244:        if (ep->s2 <= 0 || Fw_zero(oldrp[0]))
                    245:                return No;
                    246:        if (**pstr != ' ' && !isupper(**pstr)
                    247:                && !alt_c && **pstr != '"' && **pstr != '\'')
                    248:                /* Shortcut: not a keyword, must match exactly */
                    249:                return ifmatch(ep, pstr, str, alt_c);
                    250:        for (i = 0; i < ich; ++i) { /* Preset some stuff for main loop */
                    251:                if (!oldrp[i])
                    252:                        oldrp[i] = "";
                    253:                childsym[i] = symbol(child(n, i+1));
                    254:        }
                    255:        Assert(ep->s2 + 1 < sizeof buf);
                    256:        strcpy(buf, oldrp[ich]);
                    257:        buf[ep->s2] = alt_c ? alt_c : **pstr;
                    258:        buf[ep->s2 + 1] = 0;
                    259:        pa = parent(ep->focus);
                    260:        sympa = pa ? symbol(tree(pa)) : Rootsymbol;
                    261:        ci = table[sympa].r_class[ichild(ep->focus) - 1];
                    262:        code = Code(oldrp[0][0]);
                    263: 
                    264:        for (cp = ci->c_insert; *cp; cp += 2) {
                    265:                if (cp[0] != code)
                    266:                        continue;
                    267:                sym = cp[1];
                    268:                if (sym >= TABLEN)
                    269:                        continue;
                    270:                if (sym == oldsym) {
                    271:                        anyok = Yes;
                    272:                        continue;
                    273:                }
                    274:                tp = &table[sym];
                    275:                newrp = tp->r_repr;
                    276:                ok = Yes;
                    277:                for (i = 0; i < ich; ++i) {
                    278:                        str = newrp[i];
                    279:                        if (!str)
                    280:                                str = "";
                    281:                        if (!Strequ(str, oldrp[i])
                    282:                                || childsym[i] != Optional && childsym[i] != Hole
                    283:                                        && !isinclass(childsym[i], tp->r_class[i])) {
                    284:                                ok = No;
                    285:                                break;
                    286:                        }
                    287:                }
                    288:                if (!ok)
                    289:                        continue;
                    290:                str = newrp[i];
                    291:                if (!str || !Strnequ(str, buf, ep->s2+1))
                    292:                        continue;
                    293:                if (anyok) {
                    294:                        if (Strequ(str, oldrp[ich]))
                    295:                                continue; /* Same as it was: no new suggestion */
                    296:                        symfound = sym;
                    297:                        break;
                    298:                }
                    299:                else if (symfound < 0 && !Strequ(str, oldrp[ich]))
                    300:                        symfound = sym;
                    301:        }
                    302: 
                    303:        if (symfound < 0)
                    304:                return ifmatch(ep, pstr, oldrp[ich], alt_c);
                    305:        nn = table[symfound].r_node;
                    306:        for (i = 1; i <= ich; ++i) { /* Copy children to the left of the focus */
                    307:                sym = symbol(child(n, i));
                    308:                if (sym == Optional || sym == Hole)
                    309:                        continue;
                    310:                setchild(&nn, i, nodecopy(child(n, i)));
                    311:        }
                    312:        replace(&ep->focus, nn);
                    313:        str = newrp[ich];
                    314:        do { /* Find easy continuation */
                    315:                ++ep->s2;
                    316:                ++*pstr;
                    317:        } while (**pstr && **pstr == str[ep->s2]);
                    318:        return Yes;
                    319: }
                    320: 
                    321: 
                    322: /*
                    323:  * Refinement for resuggest(): see if there is a match, and if so, find
                    324:  * longest match.
                    325:  */
                    326: 
                    327: Hidden bool
                    328: ifmatch(ep, pstr, str, alt_c)
                    329:        register environ *ep;
                    330:        register string *pstr;
                    331:        register string str;
                    332:        register int alt_c;
                    333: {
                    334:        register int c = str[ep->s2];
                    335: 
                    336:        if (c != **pstr && (!alt_c || c != alt_c))
                    337:                return No;
                    338:        do {
                    339:                ++ep->s2;
                    340:                ++*pstr;
                    341:        } while (**pstr && **pstr == str[ep->s2]);
                    342:        return Yes;
                    343: }

unix.superglobalmegacorp.com

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