Annotation of 43BSDReno/contrib/jove/c.c, revision 1.1.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.