# 2.11BSD#431 - /usr/src/new/PORT/B/src/bed/inse.c

##### Functions

    ifmatch           X
    insguess          X
    mayinsert         X
    resuggest         X
    soften            X

       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: }

#### Defined functions

ifmatch defined in line 327; used 3 times

- in line 241, 249, 304

insguess defined in line 23; used 2 times

- in /usr/src/new/PORT/B/src/bed/que1.c line 334-337(2)

mayinsert defined in line 94; used 9 times

- in line 178-185(4), 191
- in /usr/src/new/PORT/B/src/bed/deco.c line 108
- in /usr/src/new/PORT/B/src/bed/que1.c line 362
- in /usr/src/new/PORT/B/src/bed/que2.c line 537, 543

resuggest defined in line 207; used 1 times

- in /usr/src/new/PORT/B/src/bed/que2.c line 511

soften defined in line 134; used 4 times

- in /usr/src/new/PORT/B/src/bed/edit.c line 110
- in /usr/src/new/PORT/B/src/bed/ins2.c line 64, 208
- in /usr/src/new/PORT/B/src/bed/que2.c line 511

#### Defined variables

rcsid defined in line 2; never used

Last modified: 1985-08-27 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1000 |