Annotation of 43BSDReno/contrib/jove/c.c, revision 1.1

1.1     ! root        1: /***************************************************************************
        !             2:  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
        !             3:  * is provided to you without charge, and with no warranty.  You may give  *
        !             4:  * away copies of JOVE, including sources, provided that this notice is    *
        !             5:  * included in all the files.                                              *
        !             6:  ***************************************************************************/
        !             7: 
        !             8: /* Contains commands for C mode.  Paren matching routines are in here. */
        !             9: 
        !            10: #include "jove.h"
        !            11: #include "re.h"
        !            12: #include "ctype.h"
        !            13: #include "disp.h"
        !            14: 
        !            15: private int
        !            16:        backslashed proto((char *, int));
        !            17: private void
        !            18: #if defined(CMT_FMT)
        !            19:        FillComment proto((char *format)),
        !            20: #endif
        !            21:        do_expr proto((int, int)),
        !            22:        FindMatch proto((int)),
        !            23:        parse_cmt_fmt proto((char *)),
        !            24:        strip_c proto((char *, char *));
        !            25: 
        !            26: extern void
        !            27:        FSexpr(),
        !            28:        FList(),
        !            29:        BSexpr(),
        !            30:        BList();
        !            31: 
        !            32: private int
        !            33: backslashed(lp, cpos)
        !            34: register char  *lp;
        !            35: register int   cpos;
        !            36: {
        !            37:        register int    cnt = 0;
        !            38: 
        !            39:        while (cpos > 0 && lp[--cpos] == '\\')
        !            40:                cnt += 1;
        !            41:        return (cnt % 2);
        !            42: }
        !            43: 
        !            44: private char   *p_types = "(){}[]";
        !            45: private int    mp_kind;
        !            46: #define MP_OKAY                0
        !            47: #define MP_MISMATCH    1
        !            48: #define MP_UNBALANCED  2
        !            49: #define MP_INCOMMENT   3
        !            50: 
        !            51: void
        !            52: mp_error()
        !            53: {
        !            54:        switch (mp_kind) {
        !            55:        case MP_MISMATCH:
        !            56:                message("[Mismatched parentheses]");
        !            57:                break;
        !            58: 
        !            59:        case MP_UNBALANCED:
        !            60:                message("[Unbalanced parenthesis]");
        !            61:                break;
        !            62: 
        !            63:        case MP_INCOMMENT:
        !            64:                message("[Inside a comment]");
        !            65:                break;
        !            66: 
        !            67:        case MP_OKAY:
        !            68:        default:
        !            69:                return;
        !            70:        }
        !            71:        rbell();
        !            72: }
        !            73: 
        !            74: /* Search from the current position for the paren that matches p_type.
        !            75:    Search in the direction dir.  If can_mismatch is YES then it is okay
        !            76:    to have mismatched parens.  If stop_early is YES then when an open
        !            77:    paren is found at the beginning of a line, it is assumed that there
        !            78:    is no point in backing up further.  This is so when you hit tab or
        !            79:    LineFeed outside, in-between procedure/function definitions, it won't
        !            80:    sit there searching all the way to the beginning of the file for a
        !            81:    match that doesn't exist.  {forward,backward}-s-expression are the
        !            82:    only ones that insist on getting the "true" story. */
        !            83: 
        !            84: Bufpos *
        !            85: m_paren(p_type, dir, can_mismatch, can_stop)
        !            86: int    p_type;
        !            87: register int   dir;
        !            88: int    can_mismatch;
        !            89: int    can_stop;
        !            90: {
        !            91:        static Bufpos   ret;
        !            92:        Bufpos  savedot,
        !            93:                *sp;
        !            94:        struct RE_block re_blk;
        !            95:        int     count = 0;
        !            96:        register char   *lp,
        !            97:                        c;
        !            98:        char    p_match,
        !            99:                re_str[128],
        !           100:                *cp,
        !           101:                quote_c = 0;
        !           102:        register int    c_char;
        !           103:        int     in_comment = -1,
        !           104:                stopped = NO;
        !           105: 
        !           106:        swritef(re_str, "[(){}[\\]%s]", (MajorMode(CMODE)) ? "/\"'" : "\"");
        !           107:        REcompile(re_str, 1, &re_blk);
        !           108:        if ((cp = strchr(p_types, p_type)) != NIL)
        !           109:                p_match = cp[dir];
        !           110:        else
        !           111:                complain("[Cannot match %c's]", p_type);
        !           112:        DOTsave(&savedot);
        !           113: 
        !           114:        /* To make things a little faster I avoid copying lines into
        !           115:           linebuf by setting curline and curchar by hand.  Warning:
        !           116:           this is slightly to very risky.  When I did this there were
        !           117:           lots of problems with procedures that expect the contents of
        !           118:           curline to be in linebuf. */
        !           119:        while (count >= 0) {
        !           120:                sp = docompiled(dir, &re_blk);
        !           121:                if (sp == 0)
        !           122:                        break;
        !           123:                lp = lbptr(sp->p_line);
        !           124: 
        !           125:                curline = sp->p_line;
        !           126:                curchar = sp->p_char;   /* here's where I cheat */
        !           127: 
        !           128:                c_char = curchar;
        !           129:                if (dir == FORWARD)
        !           130:                        c_char -= 1;
        !           131:                if (backslashed(lp, c_char))
        !           132:                        continue;
        !           133:                c = lp[c_char];
        !           134:                /* check if this is a comment (if we're not inside quotes) */
        !           135:                if (quote_c == 0 && c == '/') {
        !           136:                        int     new_ic = in_comment;
        !           137: 
        !           138:                        /* close comment */
        !           139:                        if ((c_char != 0) && lp[c_char - 1] == '*') {
        !           140:                                new_ic = (dir == FORWARD) ? NO : YES;
        !           141:                                if (new_ic == NO && in_comment == -1) {
        !           142:                                        count = 0;
        !           143:                                        quote_c = 0;
        !           144:                                }
        !           145:                        } else if (lp[c_char + 1] == '*') {
        !           146:                                new_ic = (dir == FORWARD) ? YES : NO;
        !           147:                                if (new_ic == NO && in_comment == -1) {
        !           148:                                        count = 0;
        !           149:                                        quote_c = 0;
        !           150:                                }
        !           151:                        }
        !           152:                        in_comment = new_ic;
        !           153:                }
        !           154:                if (in_comment == YES)
        !           155:                        continue;
        !           156:                if (c == '"' || c == '\'') {
        !           157:                        if (quote_c == c)
        !           158:                                quote_c = 0;
        !           159:                        else if (quote_c == 0)
        !           160:                                quote_c = c;
        !           161:                }
        !           162:                if (quote_c != 0)
        !           163:                        continue;
        !           164:                if (isopenp(c)) {
        !           165:                        count += dir;
        !           166:                        if (c_char == 0 && can_stop == YES && count >= 0) {
        !           167:                                stopped = YES;
        !           168:                                break;
        !           169:                        }
        !           170:                } else if (isclosep(c))
        !           171:                        count -= dir;
        !           172:        }
        !           173: 
        !           174:        ret.p_line = curline;
        !           175:        ret.p_char = curchar;
        !           176: 
        !           177:        curline = savedot.p_line;
        !           178:        curchar = savedot.p_char;       /* here's where I undo it */
        !           179: 
        !           180:        if (count >= 0)
        !           181:                mp_kind = MP_UNBALANCED;
        !           182:        else if (c != p_match)
        !           183:                mp_kind = MP_MISMATCH;
        !           184:        else
        !           185:                mp_kind = MP_OKAY;
        !           186: 
        !           187:        /* If we stopped (which means we were allowed to stop) and there
        !           188:           was an error, we clear the error so no error message is printed.
        !           189:           An error should be printed ONLY when we are sure about the fact,
        !           190:           namely we didn't stop prematurely HOPING that it was the right
        !           191:           answer. */
        !           192:        if (stopped && mp_kind != MP_OKAY) {
        !           193:                mp_kind = MP_OKAY;
        !           194:                return 0;
        !           195:        }
        !           196:        if (mp_kind == MP_OKAY || (mp_kind == MP_MISMATCH && can_mismatch == YES))
        !           197:                return &ret;
        !           198:        return 0;
        !           199: }
        !           200: 
        !           201: private void
        !           202: do_expr(dir, skip_words)
        !           203: register int   dir;
        !           204: int    skip_words;
        !           205: {
        !           206:        register char   c,
        !           207:                        syntax = (dir == FORWARD) ? _Op : _Cl;
        !           208: 
        !           209:        if (dir == BACKWARD)
        !           210:                b_char(1);
        !           211:        c = linebuf[curchar];
        !           212:        for (;;) {
        !           213:                if (!skip_words && ismword(c)) {
        !           214:                    WITH_TABLE(curbuf->b_major)
        !           215:                    if (dir == FORWARD)
        !           216:                        f_word(1);
        !           217:                    else
        !           218:                        b_word(1);
        !           219:                    END_TABLE();
        !           220:                    break;
        !           221:                } else if (has_syntax(c, syntax)) {
        !           222:                        FindMatch(dir);
        !           223:                        break;
        !           224:                }
        !           225:                f_char(dir);
        !           226:                if (eobp() || bobp())
        !           227:                        return;
        !           228:                c = linebuf[curchar];
        !           229:        }
        !           230: }
        !           231: 
        !           232: void
        !           233: FSexpr()
        !           234: {
        !           235:        register int    num = arg_value();
        !           236: 
        !           237:        if (num < 0) {
        !           238:                set_arg_value(-num);
        !           239:                BSexpr();
        !           240:        }
        !           241:        while (--num >= 0)
        !           242:                do_expr(FORWARD, NO);
        !           243: }
        !           244: 
        !           245: void
        !           246: FList()
        !           247: {
        !           248:        register int    num = arg_value();
        !           249: 
        !           250:        if (num < 0) {
        !           251:                set_arg_value(-num);
        !           252:                BList();
        !           253:        }
        !           254:        while (--num >= 0)
        !           255:                do_expr(FORWARD, YES);
        !           256: }
        !           257: 
        !           258: void
        !           259: BSexpr()
        !           260: {
        !           261:        register int    num = arg_value();
        !           262: 
        !           263:        if (num < 0) {
        !           264:                negate_arg_value();
        !           265:                FSexpr();
        !           266:        }
        !           267:        while (--num >= 0)
        !           268:                do_expr(BACKWARD, NO);
        !           269: }
        !           270: 
        !           271: void
        !           272: BList()
        !           273: {
        !           274:        register int    num = arg_value();
        !           275: 
        !           276:        if (num < 0) {
        !           277:                negate_arg_value();
        !           278:                FList();
        !           279:        }
        !           280:        while (--num >= 0)
        !           281:                do_expr(BACKWARD, YES);
        !           282: }
        !           283: 
        !           284: void
        !           285: BUpList()
        !           286: {
        !           287:        Bufpos  *mp;
        !           288:        char    c = (MajorMode(CMODE) ? '}' : ')');
        !           289: 
        !           290:        mp = m_paren(c, BACKWARD, NO, YES);
        !           291:        if (mp == 0)
        !           292:                mp_error();
        !           293:        else
        !           294:                SetDot(mp);
        !           295: }
        !           296: 
        !           297: void
        !           298: FDownList()
        !           299: {
        !           300:        Bufpos  *sp;
        !           301:        char    *sstr = (MajorMode(CMODE) ? "[{([\\])}]" : "[()]"),
        !           302:                *lp;
        !           303: 
        !           304:        sp = dosearch(sstr, FORWARD, YES);
        !           305:        if (sp != 0)
        !           306:                lp = lcontents(sp->p_line);
        !           307:        if (sp == 0 || has_syntax(lp[sp->p_char - 1], _Cl))
        !           308:                complain("[No contained expression]");
        !           309:        SetDot(sp);
        !           310: }
        !           311: 
        !           312: /* Move to the matching brace or paren depending on the current position
        !           313:    in the buffer. */
        !           314: 
        !           315: private void
        !           316: FindMatch(dir)
        !           317: int    dir;
        !           318: {
        !           319:        register Bufpos *bp;
        !           320:        register char   c = linebuf[curchar];
        !           321: 
        !           322:        if ((strchr(p_types, c) == 0) ||
        !           323:            (backslashed(linebuf, curchar)))
        !           324:                complain((char *) 0);
        !           325:        if (dir == FORWARD)
        !           326:                f_char(1);
        !           327:        bp = m_paren(c, dir, YES, NO);
        !           328:        if (dir == FORWARD)
        !           329:                b_char(1);
        !           330:        if (bp != 0)
        !           331:                SetDot(bp);
        !           332:        mp_error();     /* if there is an error the user wants to
        !           333:                           know about it */
        !           334: }
        !           335: 
        !           336: #define ALIGN_ARGS     (-1)
        !           337: 
        !           338: /* If CArgIndent == ALIGN_ARGS then the indentation routine will
        !           339:    indent a continued line by lining it up with the first argument.
        !           340:    Otherwise, it will indent CArgIndent characters past the indent
        !           341:    of the first line of the procedure call. */
        !           342: 
        !           343: int    CArgIndent = ALIGN_ARGS;
        !           344: 
        !           345: /* indent for C code */
        !           346: Bufpos *
        !           347: c_indent(brace)
        !           348: int    brace;
        !           349: {
        !           350:        Bufpos  *bp;
        !           351:        int     new_indent = 0,
        !           352:                current_indent,
        !           353:                increment;
        !           354: 
        !           355:        if (brace == NO)
        !           356:                increment = CIndIncrmt;
        !           357:        else
        !           358:                increment = 0;
        !           359:        /* Find matching paren, which may be a mismatch now.  If it
        !           360:           is not a matching curly brace then it is a paren (most likely).
        !           361:           In that case we try to line up the arguments to a procedure
        !           362:           or inside an of statement. */
        !           363:        if ((bp = m_paren('}', BACKWARD, YES, YES)) != NIL) {
        !           364:                Bufpos  save;
        !           365:                int     matching_indent;
        !           366: 
        !           367:                DOTsave(&save);
        !           368:                SetDot(bp);             /* go to matching paren */
        !           369:                ToIndent();
        !           370:                matching_indent = calc_pos(linebuf, curchar);
        !           371:                SetDot(bp);
        !           372:                switch (linebuf[curchar]) {
        !           373:                case '{':
        !           374:                        new_indent = matching_indent;
        !           375:                        if (!bolp()) {
        !           376:                                b_char(1);
        !           377:                                /* If we're not within the indent then we
        !           378:                                   can assume that there is either a C keyword
        !           379:                                   line DO on the line before the brace, or
        !           380:                                   there is a parenthesized expression.  If
        !           381:                                   that's the case we want to go backward
        !           382:                                   over that to the beginning of the expression
        !           383:                                   so that we can get the correct indent for
        !           384:                                   this matching brace.  This handles wrapped
        !           385:                                   if statements, etc. */
        !           386:                                if (!within_indent()) {
        !           387:                                        Bufpos  savematch;
        !           388: 
        !           389:                                        savematch = *bp;
        !           390: 
        !           391:                                        do_expr(BACKWARD, NO);
        !           392:                                        ToIndent();
        !           393:                                        new_indent = calc_pos(linebuf, curchar);
        !           394: 
        !           395:                                        /* do_expr() calls b_paren, which
        !           396:                                           returns a pointer to a structure,
        !           397:                                           and that pointer is in BP so we
        !           398:                                           have to save away the matching
        !           399:                                           paren and restore it in the
        !           400:                                           following line ... sigh */
        !           401:                                        *bp = savematch;
        !           402:                                }
        !           403:                        }
        !           404:                        if (brace == NO)
        !           405:                                new_indent += (increment - (new_indent % increment));
        !           406:                        break;
        !           407:                        
        !           408:                case '(':
        !           409:                        if (CArgIndent == ALIGN_ARGS) {
        !           410:                                f_char(1);
        !           411:                                new_indent = calc_pos(linebuf, curchar);
        !           412:                        } else
        !           413:                                new_indent = matching_indent + CArgIndent;
        !           414:                        break;
        !           415:                }
        !           416:                SetDot(&save);
        !           417:        }
        !           418: 
        !           419:        /* new_indent is the "correct" place to indent.  Now we check to
        !           420:           see if what we consider as the correct place to indent is to
        !           421:           the LEFT of where we already are.  If it is, and we are NOT
        !           422:           handling a brace, then we assume that the person wants to tab
        !           423:           in further than what we think is right (for some reason) and
        !           424:           so we allow that. */
        !           425: 
        !           426:        ToIndent();
        !           427:        current_indent = calc_pos(linebuf, curchar);
        !           428:        if (brace == NO && new_indent <= current_indent)
        !           429:                new_indent = current_indent + (increment - (current_indent % increment));
        !           430:        Bol();
        !           431:        DelWtSpace();                   /* nice uniform Tabs*Space* */
        !           432:        n_indent(new_indent);
        !           433: 
        !           434:        return bp;
        !           435: }
        !           436: 
        !           437: static void
        !           438: re_indent(incr)
        !           439: int    incr;
        !           440: {
        !           441:        Line    *l1, *l2, *lp;
        !           442:        int     c1, c2;
        !           443:        Mark    *m = CurMark();
        !           444:        Bufpos  savedot;
        !           445: 
        !           446:        DOTsave(&savedot);
        !           447:        l1 = curline;
        !           448:        c1 = curchar;
        !           449:        l2 = m->m_line;
        !           450:        c2 = m->m_char;
        !           451:        (void) fixorder(&l1, &c1, &l2, &c2);
        !           452:        for (lp = l1; lp != l2->l_next; lp = lp->l_next) {
        !           453:                int     indent;
        !           454: 
        !           455:                SetLine(lp);
        !           456:                ToIndent();
        !           457:                indent = calc_pos(linebuf, curchar);
        !           458:                if (indent != 0 || linebuf[0] != '\0')
        !           459:                        n_indent(indent + incr);
        !           460:        }
        !           461:        SetDot(&savedot);
        !           462: }
        !           463: 
        !           464: void
        !           465: LRShift()
        !           466: {
        !           467:        int     amnt;
        !           468: 
        !           469:        if (is_an_arg())
        !           470:                amnt = arg_value();
        !           471:        else
        !           472:                amnt = CIndIncrmt;
        !           473:        re_indent(-amnt);
        !           474: }
        !           475: 
        !           476: void
        !           477: RRShift()
        !           478: {
        !           479:        int     amnt;
        !           480: 
        !           481:        if (is_an_arg())
        !           482:                amnt = arg_value();
        !           483:        else
        !           484:                amnt = CIndIncrmt;
        !           485:        re_indent(amnt);
        !           486: }
        !           487: 
        !           488: #if defined(CMT_FMT)
        !           489: 
        !           490: char   CmtFmt[80] = "/*%n%! * %c%!%n */";
        !           491: 
        !           492: void
        !           493: Comment()
        !           494: {
        !           495:        FillComment(CmtFmt);
        !           496: }
        !           497: 
        !           498: /* Strip leading and trailing white space.  Skip over any imbedded '\r's. */
        !           499: 
        !           500: private void
        !           501: strip_c(from, to)
        !           502: char   *from,
        !           503:        *to;
        !           504: {
        !           505:        register char   *fr_p = from,
        !           506:                        *to_p = to,
        !           507:                        c;
        !           508: 
        !           509:        while ((c = *fr_p) != '\0') {
        !           510:                if (c == ' ' || c == '\t' || c == '\r')
        !           511:                        fr_p += 1;
        !           512:                else
        !           513:                        break;
        !           514:        }
        !           515:        while ((c = *fr_p) != '\0') {
        !           516:                if (c != '\r')
        !           517:                        *to_p++ = c;
        !           518:                fr_p += 1;
        !           519:        }
        !           520:        while (--to_p >= to)
        !           521:                if (*to_p != ' ' && *to_p != '\t')
        !           522:                        break;
        !           523:        *++to_p = '\0';
        !           524: }
        !           525: 
        !           526: private char   open_c[20],     /* the open comment format string */
        !           527:                open_pat[20],   /* the search pattern for open comment */
        !           528:                l_header[20],   /* the prefix for each comment line */
        !           529:                l_trailer[20],  /* the suffix ... */
        !           530:                close_c[20],
        !           531:                close_pat[20];
        !           532: 
        !           533: private char   *const comment_body[] = {
        !           534:        open_c,
        !           535:        l_header,
        !           536:        l_trailer,
        !           537:        close_c
        !           538: };
        !           539: 
        !           540: private int    nlflags;
        !           541: 
        !           542: /* Fill in the data structures above from the format string.  Don't return
        !           543:    if there's trouble. */
        !           544: 
        !           545: private void
        !           546: parse_cmt_fmt(str)
        !           547: char   *str;
        !           548: {
        !           549:        register char   *fmtp = str;
        !           550:        register char   *const *c_body = comment_body,
        !           551:                        *body_p = *c_body;
        !           552:        int     c,
        !           553:                newlines = 1;
        !           554: 
        !           555:        /* pick apart the comment string */
        !           556:        while ((c = *fmtp++) != '\0') {
        !           557:                if (c != '%') {
        !           558:                        *body_p++ = c;
        !           559:                        continue;
        !           560:                }
        !           561:                switch(c = *fmtp++) {
        !           562:                case 'n':
        !           563:                        if (newlines == 2 || newlines == 3)
        !           564:                                complain("%n not allowed in line header or trailer: %s",
        !           565:                                  fmtp - 2);
        !           566:                        nlflags += newlines;
        !           567:                        *body_p++ = '\r';
        !           568:                        break;
        !           569:                case 't':
        !           570:                        *body_p++ = '\t';
        !           571:                        break;
        !           572:                case '%':
        !           573:                        *body_p++ = '%';
        !           574:                        break;
        !           575:                case '!':
        !           576:                case 'c':
        !           577:                        newlines += 1;
        !           578:                        *body_p++ = '\0';
        !           579:                        body_p = *++c_body;
        !           580:                        break;
        !           581:                default:
        !           582:                        complain("[Unknown comment escape: %%%c]", c);
        !           583:                        break;
        !           584:                }
        !           585:        }
        !           586:        *body_p = '\0';
        !           587:        /* make search patterns */
        !           588:        strip_c(open_c, open_pat);
        !           589:        strip_c(close_c, close_pat);
        !           590: }
        !           591: 
        !           592: #define NL_IN_OPEN_C  ((nlflags % 4) == 1)
        !           593: #define NL_IN_CLOSE_C (nlflags >= 4)
        !           594: 
        !           595: private void
        !           596: FillComment(format)
        !           597: char   *format;
        !           598: {
        !           599:        int     saveRMargin,
        !           600:                indent_pos,
        !           601:                close_at_dot = NO;
        !           602:        size_t  header_len,
        !           603:                trailer_len;
        !           604:        register char   *cp;
        !           605:        static char     inside_err[] = "[Must be between %s and %s to re-format]";
        !           606:        Bufpos  open_c_pt,
        !           607:                close_c_pt,
        !           608:                tmp_bp,
        !           609:                *match_o,
        !           610:                *match_c;
        !           611:        Mark    *entry_mark,
        !           612:                *open_c_mark,
        !           613:                *savedot;
        !           614: 
        !           615:        parse_cmt_fmt(format);
        !           616:        /* figure out if we're "inside" a comment */
        !           617:        if ((match_o = dosearch(open_pat, BACKWARD, 0)) == 0)
        !           618:                complain("No opening %s to match to.", open_pat);
        !           619:        open_c_pt = *match_o;
        !           620:        if ((match_c = dosearch(close_pat, BACKWARD, NO)) != 0 &&
        !           621:            inorder(open_c_pt.p_line, open_c_pt.p_char,
        !           622:                    match_c->p_line, match_c->p_char))
        !           623:                complain(inside_err, open_pat, close_pat);
        !           624:        if ((match_o = dosearch(open_pat, FORWARD, NO)) != 0) {
        !           625:                tmp_bp = *match_o;
        !           626:                match_o = &tmp_bp;
        !           627:        }
        !           628:        if ((match_c = dosearch(close_pat, FORWARD, 0)) != (Bufpos *) 0)
        !           629:                close_c_pt = *match_c;
        !           630: 
        !           631:        /* Here's where we figure out whether to format from dot or from
        !           632:           the close comment.  Note that we've already searched backwards to
        !           633:           find the open comment symbol for the comment we are formatting.
        !           634:           The open symbol mentioned below refers to the possible existence
        !           635:           of the next comment.  There are 5 cases:
        !           636:                1) no open or close symbol              ==> dot
        !           637:                2) open, but no close symbol            ==> dot
        !           638:                3) close, but no open                   ==> close
        !           639:                4) open, close are inorder              ==> dot
        !           640:                5) open, close are not inorder          ==> close */
        !           641: 
        !           642: 
        !           643:        if (match_o == (Bufpos *) 0) {
        !           644:                if (match_c == (Bufpos *) 0)
        !           645:                        close_at_dot = YES;
        !           646:        } else if (match_c == (Bufpos *) 0)
        !           647:                close_at_dot = YES;
        !           648:        else if (inorder(match_o->p_line, match_o->p_char,
        !           649:                 match_c->p_line, match_c->p_char))
        !           650:                close_at_dot = YES;
        !           651:        if (close_at_dot) {
        !           652:                close_c_pt.p_line = curline;
        !           653:                close_c_pt.p_char = curchar;
        !           654:        } else {
        !           655:                SetDot(match_c);
        !           656:        }
        !           657:        SetDot(&open_c_pt);
        !           658:        open_c_mark = MakeMark(curline, curchar, M_FLOATER);
        !           659:        indent_pos = calc_pos(linebuf, curchar);
        !           660:        /* search for a close comment; delete it if it exits */
        !           661:        SetDot(&close_c_pt);
        !           662:        if (close_at_dot == 0)
        !           663:                del_char(BACKWARD, (int)strlen(close_pat), NO);
        !           664:        entry_mark = MakeMark(curline, curchar, M_FLOATER);
        !           665:        ToMark(open_c_mark);
        !           666:        /* always separate the comment body from anything preceeding it */
        !           667:        LineInsert(1);
        !           668:        DelWtSpace();
        !           669:        Bol();
        !           670:        for (cp = open_c; *cp; cp++) {
        !           671:                if (*cp == '\r') {
        !           672:                        if (!eolp())
        !           673:                                LineInsert(1);
        !           674:                        else
        !           675:                                line_move(FORWARD, 1, NO);
        !           676:                } else if (*cp == ' ' || *cp == '\t') {
        !           677:                        if (linebuf[curchar] != *cp)
        !           678:                                insert_c(*cp, 1);
        !           679:                } else
        !           680:                        /* Since we matched the open comment string on this
        !           681:                           line, we don't need to worry about crossing line
        !           682:                           boundaries. */
        !           683:                        curchar += 1;
        !           684:        }
        !           685:        savedot = MakeMark(curline, curchar, M_FLOATER);
        !           686: 
        !           687:        /* We need to strip the line header pattern of leading white space
        !           688:           since we need to match the line after all of its leading
        !           689:           whitespace is gone. */
        !           690:        for (cp = l_header; *cp && (isspace(*cp)); cp++)
        !           691:                ;
        !           692:        header_len = strlen(cp);
        !           693:        trailer_len = strlen(l_trailer);
        !           694: 
        !           695:        /* Strip each comment line of the open and close comment strings
        !           696:           before reformatting it. */
        !           697: 
        !           698:        do {
        !           699:                Bol();
        !           700:                DelWtSpace();
        !           701:                if (header_len && strncmp(linebuf, cp, header_len)==0)
        !           702:                        del_char(FORWARD, (int)header_len, NO);
        !           703:                if (trailer_len) {
        !           704:                        Eol();
        !           705:                        if (((size_t)curchar > trailer_len) &&
        !           706:                            (strncmp(&linebuf[curchar - trailer_len],
        !           707:                                      l_trailer, trailer_len)==0))
        !           708:                                del_char(BACKWARD, (int)trailer_len, NO);
        !           709:                }
        !           710:                if (curline->l_next != 0)
        !           711:                        line_move(FORWARD, 1, NO);
        !           712:                else
        !           713:                        break;
        !           714:        } while (curline != entry_mark->m_line->l_next);
        !           715: 
        !           716:        do_set_mark(savedot->m_line, savedot->m_char);
        !           717:        ToMark(entry_mark);
        !           718:        saveRMargin = RMargin;
        !           719:        RMargin = saveRMargin - strlen(l_header) -
        !           720:                  strlen(l_trailer) - indent_pos + 2;
        !           721:        do_rfill(NO);
        !           722:        RMargin = saveRMargin;
        !           723:        /* get back to the start of the comment */
        !           724:        PopMark();
        !           725:        do {
        !           726:                if (curline == open_c_mark->m_line->l_next) {
        !           727:                        ;
        !           728:                } else {
        !           729:                        Bol();
        !           730:                        n_indent(indent_pos);
        !           731:                        ins_str(l_header, NO);
        !           732:                }
        !           733:                Eol();
        !           734:                if (!NL_IN_CLOSE_C && (curline == entry_mark->m_line))
        !           735:                        ;
        !           736:                else
        !           737:                        ins_str(l_trailer, NO);
        !           738:                if (curline->l_next != 0)
        !           739:                        line_move(FORWARD, 1, NO);
        !           740:                else
        !           741:                        break;
        !           742:        } while (curline != entry_mark->m_line->l_next);
        !           743:        /* handle the close comment symbol */
        !           744:        if (curline == entry_mark->m_line->l_next) {
        !           745:                line_move(BACKWARD, 1, NO);
        !           746:                Eol();
        !           747:        }
        !           748:        DelWtSpace();
        !           749:        /* if the addition of the close symbol would cause the line to be
        !           750:           too long, put the close symbol on the next line. */
        !           751:        if (!(NL_IN_CLOSE_C) &&
        !           752:          (int)strlen(close_c) + calc_pos(linebuf, curchar) > RMargin) {
        !           753:                LineInsert(1);
        !           754:                n_indent(indent_pos);
        !           755:        }
        !           756:        for (cp = close_c; *cp; cp++) {
        !           757:                if (*cp == '\r') {
        !           758:                        LineInsert(1);
        !           759:                        n_indent(indent_pos);
        !           760:                } else
        !           761:                        insert_c(*cp, 1);
        !           762:        }
        !           763:        ToMark(open_c_mark);
        !           764:        Eol();
        !           765:        del_char(FORWARD, 1, NO);
        !           766: }
        !           767: 
        !           768: #endif /* CMT_FMT */
        !           769: 

unix.superglobalmegacorp.com

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