# 2.11BSD#431 - /usr/src/ucb/ex/ex_vops3.c

##### Functions

    endPS             X
    endsent           X
    isa               X
    lbrack            X
    lfind             X
    lindent           X
    lmatchp           X
    lnext             X
    lskipa1           X
    lskipatom         X
    lskipbal          X
    lsmatch           X
    ltosol1           X
    ltosolid          X

##### Variables

    llimit            X
    wasend            X

       1: /*
       2:  * Copyright (c) 1980 Regents of the University of California.
       3:  * All rights reserved.  The Berkeley software License Agreement
       4:  * specifies the terms and conditions for redistribution.
       5:  */
       6:
       7: #if !defined(lint) && defined(DOSCCS)
       8: static char *sccsid = "@(#)ex_vops3.c	7.3 (Berkeley) 6/7/85";
       9: #endif
      10:
      11: #include "ex.h"
      12: #include "ex_tty.h"
      13: #include "ex_vis.h"
      14:
      15: /*
      16:  * Routines to handle structure.
      17:  * Operations supported are:
      18:  *	( ) { } [ ]
      19:  *
      20:  * These cover:		LISP		TEXT
      21:  *	( )		s-exprs		sentences
      22:  *	{ }		list at same	paragraphs
      23:  *	[ ]		defuns		sections
      24:  *
      25:  * { and } for C used to attempt to do something with matching {}'s, but
      26:  * I couldn't find definitions which worked intuitively very well, so I
      27:  * scrapped this.
      28:  *
      29:  * The code here is very hard to understand.
      30:  */
      31: line    *llimit;
      32: int (*lf)();
      33:
      34: #ifdef LISPCODE
      35: int lindent();
      36: #endif
      37:
      38: bool    wasend;
      39:
      40: /*
      41:  * Find over structure, repeated count times.
      42:  * Don't go past line limit.  F is the operation to
      43:  * be performed eventually.  If pastatom then the user said {}
      44:  * rather than (), implying past atoms in a list (or a paragraph
      45:  * rather than a sentence.
      46:  */
      47: lfind(pastatom, cnt, f, limit)
      48:     bool pastatom;
      49:     int cnt, (*f)();
      50:     line *limit;
      51: {
      52:     register int c;
      53:     register int rc = 0;
      54:     char save[LBSIZE];
      55:
      56:     /*
      57: 	 * Initialize, saving the current line buffer state
      58: 	 * and computing the limit; a 0 argument means
      59: 	 * directional end of file.
      60: 	 */
      61:     wasend = 0;
      62:     lf = f;
      63:     strcpy(save, linebuf);
      64:     if (limit == 0)
      65:         limit = dir < 0 ? one : dol;
      66:     llimit = limit;
      67:     wdot = dot;
      68:     wcursor = cursor;
      69:
      70:     if (pastatom >= 2) {
      71:         while (cnt > 0 && word(f, cnt))
      72:             cnt--;
      73:         if (pastatom == 3)
      74:             eend(f);
      75:         if (dot == wdot) {
      76:             wdot = 0;
      77:             if (cursor == wcursor)
      78:                 rc = -1;
      79:         }
      80:     }
      81: #ifdef LISPCODE
      82:     else if (!value(LISP)) {
      83: #else
      84:     else {
      85: #endif
      86:         char *icurs;
      87:         line *idot;
      88:
      89:         if (linebuf[0] == 0) {
      90:             do
      91:                 if (!lnext())
      92:                     goto ret;
      93:             while (linebuf[0] == 0);
      94:             if (dir > 0) {
      95:                 wdot--;
      96:                 linebuf[0] = 0;
      97:                 wcursor = linebuf;
      98:                 /*
      99: 				 * If looking for sentence, next line
     100: 				 * starts one.
     101: 				 */
     102:                 if (!pastatom) {
     103:                     icurs = wcursor;
     104:                     idot = wdot;
     105:                     goto begin;
     106:                 }
     107:             }
     108:         }
     109:         icurs = wcursor;
     110:         idot = wdot;
     111:
     112:         /*
     113: 		 * Advance so as to not find same thing again.
     114: 		 */
     115:         if (dir > 0) {
     116:             if (!lnext()) {
     117:                 rc = -1;
     118:                 goto ret;
     119:             }
     120:         } else
     121:             ignore(lskipa1(""));
     122:
     123:         /*
     124: 		 * Count times find end of sentence/paragraph.
     125: 		 */
     126: begin:
     127:         for (;;) {
     128:             while (!endsent(pastatom))
     129:                 if (!lnext())
     130:                     goto ret;
     131:             if (!pastatom || wcursor == linebuf && endPS())
     132:                 if (--cnt <= 0)
     133:                     break;
     134:             if (linebuf[0] == 0) {
     135:                 do
     136:                     if (!lnext())
     137:                         goto ret;
     138:                 while (linebuf[0] == 0);
     139:             } else
     140:                 if (!lnext())
     141:                     goto ret;
     142:         }
     143:
     144:         /*
     145: 		 * If going backwards, and didn't hit the end of the buffer,
     146: 		 * then reverse direction.
     147: 		 */
     148:         if (dir < 0 && (wdot != llimit || wcursor != linebuf)) {
     149:             dir = 1;
     150:             llimit = dot;
     151:             /*
     152: 			 * Empty line needs special treatement.
     153: 			 * If moved to it from other than begining of next line,
     154: 			 * then a sentence starts on next line.
     155: 			 */
     156:             if (linebuf[0] == 0 && !pastatom &&
     157:                (wdot != dot - 1 || cursor != linebuf)) {
     158:                 lnext();
     159:                 goto ret;
     160:             }
     161:         }
     162:
     163:         /*
     164: 		 * If we are not at a section/paragraph division,
     165: 		 * advance to next.
     166: 		 */
     167:         if (wcursor == icurs && wdot == idot || wcursor != linebuf || !endPS())
     168:             ignore(lskipa1(""));
     169:     }
     170: #ifdef LISPCODE
     171:     else {
     172:         c = *wcursor;
     173:         /*
     174: 		 * Startup by skipping if at a ( going left or a ) going
     175: 		 * right to keep from getting stuck immediately.
     176: 		 */
     177:         if (dir < 0 && c == '(' || dir > 0 && c == ')') {
     178:             if (!lnext()) {
     179:                 rc = -1;
     180:                 goto ret;
     181:             }
     182:         }
     183:         /*
     184: 		 * Now chew up repitition count.  Each time around
     185: 		 * if at the beginning of an s-exp (going forwards)
     186: 		 * or the end of an s-exp (going backwards)
     187: 		 * skip the s-exp.  If not at beg/end resp, then stop
     188: 		 * if we hit a higher level paren, else skip an atom,
     189: 		 * counting it unless pastatom.
     190: 		 */
     191:         while (cnt > 0) {
     192:             c = *wcursor;
     193:             if (dir < 0 && c == ')' || dir > 0 && c == '(') {
     194:                 if (!lskipbal("()"))
     195:                     goto ret;
     196:                 /*
     197:  				 * Unless this is the last time going
     198: 				 * backwards, skip past the matching paren
     199: 				 * so we don't think it is a higher level paren.
     200: 				 */
     201:                 if (dir < 0 && cnt == 1)
     202:                     goto ret;
     203:                 if (!lnext() || !ltosolid())
     204:                     goto ret;
     205:                 --cnt;
     206:             } else if (dir < 0 && c == '(' || dir > 0 && c == ')')
     207:                 /* Found a higher level paren */
     208:                 goto ret;
     209:             else {
     210:                 if (!lskipatom())
     211:                     goto ret;
     212:                 if (!pastatom)
     213:                     --cnt;
     214:             }
     215:         }
     216:     }
     217: #endif
     218: ret:
     219:     strcLIN(save);
     220:     return (rc);
     221: }
     222:
     223: /*
     224:  * Is this the end of a sentence?
     225:  */
     226: endsent(pastatom)
     227:     bool pastatom;
     228: {
     229:     register char *cp = wcursor;
     230:     register int c, d;
     231:
     232:     /*
     233: 	 * If this is the beginning of a line, then
     234: 	 * check for the end of a paragraph or section.
     235: 	 */
     236:     if (cp == linebuf)
     237:         return (endPS());
     238:
     239:     /*
     240: 	 * Sentences end with . ! ? not at the beginning
     241: 	 * of the line, and must be either at the end of the line,
     242: 	 * or followed by 2 spaces.  Any number of intervening ) ] ' "
     243: 	 * characters are allowed.
     244: 	 */
     245:     if (!any(c = *cp, ".!?"))
     246:         goto tryps;
     247:     do
     248:         if ((d = *++cp) == 0)
     249:             return (1);
     250:     while (any(d, ")]'"));
     251:     if (*cp == 0 || *cp++ == ' ' && *cp == ' ')
     252:         return (1);
     253: tryps:
     254:     if (cp[1] == 0)
     255:         return (endPS());
     256:     return (0);
     257: }
     258:
     259: /*
     260:  * End of paragraphs/sections are respective
     261:  * macros as well as blank lines and form feeds.
     262:  */
     263: endPS()
     264: {
     265:
     266:     return (linebuf[0] == 0 ||
     267:         isa(svalue(PARAGRAPHS)) || isa(svalue(SECTIONS)));
     268:
     269: }
     270:
     271: #ifdef LISPCODE
     272: lindent(addr)
     273:     line *addr;
     274: {
     275:     register int i;
     276:     char *swcurs = wcursor;
     277:     line *swdot = wdot;
     278:
     279: again:
     280:     if (addr > one) {
     281:         register char *cp;
     282:         register int cnt = 0;
     283:
     284:         addr--;
     285:         getline(*addr);
     286:         for (cp = linebuf; *cp; cp++)
     287:             if (*cp == '(')
     288:                 cnt++;
     289:             else if (*cp == ')')
     290:                 cnt--;
     291:         cp = vpastwh(linebuf);
     292:         if (*cp == 0)
     293:             goto again;
     294:         if (cnt == 0)
     295:             return (whitecnt(linebuf));
     296:         addr++;
     297:     }
     298:     wcursor = linebuf;
     299:     linebuf[0] = 0;
     300:     wdot = addr;
     301:     dir = -1;
     302:     llimit = one;
     303:     lf = lindent;
     304:     if (!lskipbal("()"))
     305:         i = 0;
     306:     else if (wcursor == linebuf)
     307:         i = 2;
     308:     else {
     309:         register char *wp = wcursor;
     310:
     311:         dir = 1;
     312:         llimit = wdot;
     313:         if (!lnext() || !ltosolid() || !lskipatom()) {
     314:             wcursor = wp;
     315:             i = 1;
     316:         } else
     317:             i = 0;
     318:         i += column(wcursor) - 1;
     319:         if (!inopen)
     320:             i--;
     321:     }
     322:     wdot = swdot;
     323:     wcursor = swcurs;
     324:     return (i);
     325: }
     326: #endif
     327:
     328: lmatchp(addr)
     329:     line *addr;
     330: {
     331:     register int i;
     332:     register char *parens, *cp;
     333:
     334:     for (cp = cursor; !any(*cp, "({[)}]");)
     335:         if (*cp++ == 0)
     336:             return (0);
     337:     lf = 0;
     338:     parens = any(*cp, "()") ? "()" : any(*cp, "[]") ? "[]" : "{}";
     339:     if (*cp == parens[1]) {
     340:         dir = -1;
     341:         llimit = one;
     342:     } else {
     343:         dir = 1;
     344:         llimit = dol;
     345:     }
     346:     if (addr)
     347:         llimit = addr;
     348:     if (splitw)
     349:         llimit = dot;
     350:     wcursor = cp;
     351:     wdot = dot;
     352:     i = lskipbal(parens);
     353:     return (i);
     354: }
     355:
     356: lsmatch(cp)
     357:     char *cp;
     358: {
     359:     char save[LBSIZE];
     360:     register char *sp = save;
     361:     register char *scurs = cursor;
     362:
     363:     wcursor = cp;
     364:     strcpy(sp, linebuf);
     365:     *wcursor = 0;
     366:     strcpy(cursor, genbuf);
     367:     cursor = strend(linebuf) - 1;
     368:     if (lmatchp(dot - vcline)) {
     369:         register int i = insmode;
     370:         register int c = outcol;
     371:         register int l = outline;
     372:
     373:         if (!MI)
     374:             endim();
     375:         vgoto(splitw ? WECHO : LINE(wdot - llimit), column(wcursor) - 1);
     376:         flush();
     377:         sleep(1);
     378:         vgoto(l, c);
     379:         if (i)
     380:             goim();
     381:     }
     382:     else {
     383:         strcLIN(sp);
     384:         strcpy(scurs, genbuf);
     385:         if (!lmatchp((line *) 0))
     386:             beep();
     387:     }
     388:     strcLIN(sp);
     389:     wdot = 0;
     390:     wcursor = 0;
     391:     cursor = scurs;
     392: }
     393:
     394: ltosolid()
     395: {
     396:
     397:     return (ltosol1("()"));
     398: }
     399:
     400: ltosol1(parens)
     401:     register char *parens;
     402: {
     403:     register char *cp;
     404:
     405:     if (*parens && !*wcursor && !lnext())
     406:         return (0);
     407:     while (isspace(*wcursor) || (*wcursor == 0 && *parens))
     408:         if (!lnext())
     409:             return (0);
     410:     if (any(*wcursor, parens) || dir > 0)
     411:         return (1);
     412:     for (cp = wcursor; cp > linebuf; cp--)
     413:         if (isspace(cp[-1]) || any(cp[-1], parens))
     414:             break;
     415:     wcursor = cp;
     416:     return (1);
     417: }
     418:
     419: lskipbal(parens)
     420:     register char *parens;
     421: {
     422:     register int level = dir;
     423:     register int c;
     424:
     425:     do {
     426:         if (!lnext()) {
     427:             wdot = NOLINE;
     428:             return (0);
     429:         }
     430:         c = *wcursor;
     431:         if (c == parens[1])
     432:             level--;
     433:         else if (c == parens[0])
     434:             level++;
     435:     } while (level);
     436:     return (1);
     437: }
     438:
     439: lskipatom()
     440: {
     441:
     442:     return (lskipa1("()"));
     443: }
     444:
     445: lskipa1(parens)
     446:     register char *parens;
     447: {
     448:     register int c;
     449:
     450:     for (;;) {
     451:         if (dir < 0 && wcursor == linebuf) {
     452:             if (!lnext())
     453:                 return (0);
     454:             break;
     455:         }
     456:         c = *wcursor;
     457:         if (c && (isspace(c) || any(c, parens)))
     458:             break;
     459:         if (!lnext())
     460:             return (0);
     461:         if (dir > 0 && wcursor == linebuf)
     462:             break;
     463:     }
     464:     return (ltosol1(parens));
     465: }
     466:
     467: lnext()
     468: {
     469:
     470:     if (dir > 0) {
     471:         if (*wcursor)
     472:             wcursor++;
     473:         if (*wcursor)
     474:             return (1);
     475:         if (wdot >= llimit) {
     476:             if (lf == vmove && wcursor > linebuf)
     477:                 wcursor--;
     478:             return (0);
     479:         }
     480:         wdot++;
     481:         getline(*wdot);
     482:         wcursor = linebuf;
     483:         return (1);
     484:     } else {
     485:         --wcursor;
     486:         if (wcursor >= linebuf)
     487:             return (1);
     488: #ifdef LISPCODE
     489:         if (lf == lindent && linebuf[0] == '(')
     490:             llimit = wdot;
     491: #endif
     492:         if (wdot <= llimit) {
     493:             wcursor = linebuf;
     494:             return (0);
     495:         }
     496:         wdot--;
     497:         getline(*wdot);
     498:         wcursor = linebuf[0] == 0 ? linebuf : strend(linebuf) - 1;
     499:         return (1);
     500:     }
     501: }
     502:
     503: lbrack(c, f)
     504:     register int c;
     505:     int (*f)();
     506: {
     507:     register line *addr;
     508:
     509:     addr = dot;
     510:     for (;;) {
     511:         addr += dir;
     512:         if (addr < one || addr > dol) {
     513:             addr -= dir;
     514:             break;
     515:         }
     516:         getline(*addr);
     517:         if (linebuf[0] == '{' ||
     518: #ifdef LISPCODE
     519:             value(LISP) && linebuf[0] == '(' ||
     520: #endif
     521:             isa(svalue(SECTIONS))) {
     522:             if (c == ']' && f != vmove) {
     523:                 addr--;
     524:                 getline(*addr);
     525:             }
     526:             break;
     527:         }
     528:         if (c == ']' && f != vmove && linebuf[0] == '}')
     529:             break;
     530:     }
     531:     if (addr == dot)
     532:         return (0);
     533:     if (f != vmove)
     534:         wcursor = c == ']' ? strend(linebuf) : linebuf;
     535:     else
     536:         wcursor = 0;
     537:     wdot = addr;
     538:     vmoving = 0;
     539:     return (1);
     540: }
     541:
     542: isa(cp)
     543:     register char *cp;
     544: {
     545:
     546:     if (linebuf[0] != '.')
     547:         return (0);
     548:     for (; cp[0] && cp[1]; cp += 2)
     549:         if (linebuf[1] == cp[0]) {
     550:             if (linebuf[2] == cp[1])
     551:                 return (1);
     552:             if (linebuf[2] == 0 && cp[1] == ' ')
     553:                 return (1);
     554:         }
     555:     return (0);
     556: }

#### Defined functions

endPS defined in line 263; used 4 times

- in line 131, 167, 237, 255

endsent defined in line 226; used 1 times

- in line 128

isa defined in line 542; used 3 times

- in line 267(2), 521

lbrack defined in line 503; used 1 times

- in /usr/src/ucb/ex/ex_voper.c line 262

lfind defined in line 47; used 4 times

- in /usr/src/ucb/ex/ex_voper.c line 164, 181, 196, 215

lindent defined in line 272; used 8 times

- in line 35, 303, 489
- in /usr/src/ucb/ex/ex_cmdsub.c line 450
- in /usr/src/ucb/ex/ex_get.c line 148
- in /usr/src/ucb/ex/ex_vops.c line 480, 655
- in /usr/src/ucb/ex/ex_vops2.c line 325

lmatchp defined in line 328; used 3 times

- in line 368, 385
- in /usr/src/ucb/ex/ex_voper.c line 225

lnext defined in line 467; used 20 times

- in line 91, 116, 129, 136-140(2), 158, 178, 203, 313, 405-408(2), 426, 452, 459
- in /usr/src/ucb/ex/ex_voper.c line 757, 772-775(2), 797-800(2), 808

lskipa1 defined in line 445; used 3 times

- in line 121, 168, 442

lskipatom defined in line 439; used 2 times

- in line 210, 313

lskipbal defined in line 419; used 3 times

- in line 194, 304, 352

lsmatch defined in line 356; used 1 times

- in /usr/src/ucb/ex/ex_vops2.c line 831

ltosol1 defined in line 400; used 2 times

- in line 397, 464

ltosolid defined in line 394; used 2 times

- in line 203, 313

#### Defined variables

llimit defined in line 31; used 13 times

- in line 66, 148-150(2), 302, 312, 341-349(4), 375, 475, 490-492(2)

sccsid defined in line 8; never used
wasend defined in line 38; used 1 times

- in line 61

Last modified: 1991-09-08 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1770 |