|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.