Annotation of 43BSDTahoe/ucb/indent/io.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1980 Regents of the University of California.
                      3:  * Copyright (c) 1976 Board of Trustees of the University of Illinois.
                      4:  * All rights reserved.
                      5:  *
                      6:  * Redistribution and use in source and binary forms are permitted
                      7:  * provided that the above copyright notice and this paragraph are
                      8:  * duplicated in all such forms and that any documentation,
                      9:  * advertising materials, and other materials related to such
                     10:  * distribution and use acknowledge that the software was developed
                     11:  * by the University of California, Berkeley and the University
                     12:  * of Illinois, Urbana.  The name of either
                     13:  * University may not be used to endorse or promote products derived
                     14:  * from this software without specific prior written permission.
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     16:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     17:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     18:  */
                     19: 
                     20: #ifndef lint
                     21: static char sccsid[] = "@(#)io.c       5.7 (Berkeley) 6/29/88";
                     22: #endif /* not lint */
                     23: 
                     24: /*
                     25:  * FILE NAME:
                     26:  *     io.c
                     27:  * PURPOSE:
                     28:  *     Contains routines to handle i/o related stuff for indent.
                     29:  * GLOBALS:
                     30:  *     None
                     31:  * FUNCTIONS:
                     32:  *     dump_line
                     33:  *     fill_buffer
                     34:  *     pad_output
                     35:  *     count_spaces
                     36:  *     eqin
                     37:  *     cmp
                     38:  *
                     39:  */
                     40: /*-
                     41:  *
                     42:  *                       Copyright (C) 1976
                     43:  *                             by the
                     44:  *                       Board of Trustees
                     45:  *                             of the
                     46:  *                     University of Illinois
                     47:  *
                     48:  *                      All rights reserved
                     49:  *
                     50:  *
                     51:  * NAME:
                     52:  *     dump_line
                     53:  *
                     54:  * FUNCTION:
                     55:  *     Does the actual printing of the stored up line
                     56:  *
                     57:  * ALGORITHM:
                     58:  *     For each of the label, code, and comment sections which are used on 
                     59:  *     this line:
                     60:  *
                     61:  *     1) Use pad_output to get the section aligned properly.
                     62:  *     2) write the section
                     63:  *
                     64:  *     The indentation level used for the code is set by ps.ind_level.  After
                     65:  *     printing, ps.ind_level is set to ps.i_l_follow.
                     66:  *
                     67:  *     An extra level of indentation is added if ps.ind_stmt is 1.  After 
                     68:  *     printing, ps.ind_stmt is set to 1 iff the line just printed has an
                     69:  *     unterminated, non-declaration statement.
                     70:  *
                     71:  * HISTORY:
                     72:  *     initial coding  November 1976   D A Willcox of CAC
                     73:  *
                     74:  */
                     75: #include "indent_globs.h"
                     76: 
                     77: 
                     78: 
                     79: int         ff = 014;          /* used to write a form feed */
                     80: int         comment_open;
                     81: static      paren_target;
                     82: 
                     83: dump_line()
                     84: {                              /* dump_line is the routine that actually
                     85:                                 * effects the printing of the new source.
                     86:                                 * It prints the label section, followed
                     87:                                 * by the code section with the
                     88:                                 * appropriate nesting level, followed by
                     89:                                 * any comments */
                     90:     register int cur_col,
                     91:                 temp_col,
                     92:                 target_col;
                     93: 
                     94:     if (ps.procname[0]) {
                     95:        if (troff)
                     96:            fprintf(output, ".Pr \"%s\"\n", ps.procname);
                     97:        ps.ind_level = 0;
                     98:        ps.procname[0] = 0;
                     99:     }
                    100:     if (s_code == e_code && s_lab == e_lab && s_com == e_com) {
                    101:        if (suppress_blanklines>0) suppress_blanklines--;
                    102:        else {
                    103:        ps.bl_line = true;
                    104:        n_real_blanklines++;
                    105:        }
                    106:     }
                    107:     else if (!inhibit_formatting) {
                    108:        suppress_blanklines = 0;
                    109:        ps.bl_line = false;
                    110:        if (prefix_blankline_requested)
                    111:            if (swallow_optional_blanklines) {
                    112:                if (n_real_blanklines == 1)
                    113:                    n_real_blanklines = 0;
                    114:            }
                    115:            else {
                    116:                if (n_real_blanklines == 0)
                    117:                    n_real_blanklines = 1;
                    118:            }
                    119:        while (--n_real_blanklines >= 0)
                    120:            putc('\n', output);
                    121:        n_real_blanklines = 0;
                    122:        if (ps.ind_level == 0)
                    123:            ps.ind_stmt = 0;    /* this is a class A kludge. dont do
                    124:                                 * additional statement indentation if we
                    125:                                 * are at bracket level 0 */
                    126: 
                    127:        if (e_lab != s_lab || e_code != s_code)
                    128:            ++code_lines;       /* keep count of lines with code */
                    129: 
                    130: 
                    131:        if (e_lab != s_lab) {   /* print lab, if any */
                    132:            if (comment_open) {
                    133:                comment_open = 0;
                    134:                fprintf(output, ".*/\n");
                    135:            }
                    136:            while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
                    137:                e_lab--;
                    138:            cur_col = pad_output(1, compute_label_target());
                    139:            fprintf(output, "%.*s", e_lab - s_lab, s_lab);
                    140:            cur_col = count_spaces(cur_col, s_lab);
                    141:        }
                    142:        else
                    143:            cur_col = 1;        /* there is no label section */
                    144: 
                    145:        ps.pcase = false;
                    146: 
                    147:        if (s_code != e_code) { /* print code section, if any */
                    148:            register char *p;
                    149: 
                    150:            if (comment_open) {
                    151:                comment_open = 0;
                    152:                fprintf(output, ".*/\n");
                    153:            }
                    154:            target_col = compute_code_target();
                    155:            {
                    156:                register    i;
                    157: 
                    158:                for (i = 0; i < ps.p_l_follow; i++)
                    159:                    if (ps.paren_indents[i] >= 0)
                    160:                        ps.paren_indents[i] = -(ps.paren_indents[i] + target_col);
                    161:            }
                    162:            cur_col = pad_output(cur_col, target_col);
                    163:            for (p = s_code; p < e_code; p++)
                    164:                if (*p == (char)0200)
                    165:                    fprintf(output, "%d", target_col * 7);
                    166:                else
                    167:                    putc(*p, output);
                    168:            cur_col = count_spaces(cur_col, s_code);
                    169:        }
                    170:        if (s_com != e_com)
                    171:            if (troff) {
                    172:                register char *p;
                    173: 
                    174:                if (e_com[-1] == '/' && e_com[-2] == '*')
                    175:                    e_com -= 2;
                    176:                while (e_com > s_com && e_com[-1] == ' ')
                    177:                    e_com--;
                    178:                *e_com = 0;
                    179:                p = s_com;
                    180:                while (*p == ' ')
                    181:                    p++;
                    182:                if (p[0] == '/' && p[1] == '*')
                    183:                    p += 2;
                    184:                else if (p[0] == '*')
                    185:                    p += p[1] == '/' ? 2 : 1;
                    186:                while (*p == ' ')
                    187:                    p++;
                    188:                if (*p == 0)
                    189:                    goto inhibit_newline;
                    190:                if (!comment_open) {
                    191:                    if ('a' <= *p && *p <= 'z')
                    192:                        *p = *p + 'A' - 'a';
                    193:                    if (s_code != e_code || s_lab != e_lab) {
                    194:                        fprintf(output, "\\c\n./* %dp 1 %dp\n",
                    195:                                ps.com_col * 7, target_col * 7);
                    196:                    }
                    197:                    else
                    198:                        fprintf(output, "./* %dp 0 %dp\n",
                    199:                                ps.com_col * 7, target_col * 7);
                    200:                }
                    201:                comment_open = 1;
                    202:                while (*p) {
                    203:                    if (*p == BACKSLASH)
                    204:                        putc(BACKSLASH, output);
                    205:                    putc(*p++, output);
                    206:                }
                    207:            }
                    208:            else {              /* print comment, if any */
                    209:                register    target = ps.com_col;
                    210:                register char *com_st = s_com;
                    211: 
                    212:                target += ps.comment_delta;
                    213:                while (target <= 0)
                    214:                    if (*s_com == ' ')
                    215:                        target++, s_com++;
                    216:                    else if (*s_com == '\t')
                    217:                        target = ((target - 1) & ~7) + 9, s_com++;
                    218:                    else
                    219:                        target = 1;
                    220:                if (cur_col > target) { /* if comment cant fit on this
                    221:                                         * line, put it on next line */
                    222:                    putc('\n', output);
                    223:                    cur_col = 1;
                    224:                    ++ps.out_lines;
                    225:                }
                    226:                cur_col = pad_output(cur_col, target);
                    227:                if (!ps.box_com) {
                    228:                    if (star_comment_cont && com_st[1] != '*')
                    229:                        if (com_st[1] == ' ' && com_st[0] == ' ')
                    230:                            com_st[1] = '*';
                    231:                        else
                    232:                            fwrite(" * ", com_st[0] == '\t' ? 2 : com_st[0] == '*' ? 1 : 3, 1, output);
                    233:                }
                    234:                fwrite(com_st, e_com - com_st, 1, output);
                    235:                ps.comment_delta = ps.n_comment_delta;
                    236:                cur_col = count_spaces(cur_col, com_st);
                    237:                ++ps.com_lines; /* count lines with comments */
                    238:            }
                    239:        if (ps.use_ff)
                    240:            putc('\014', output);
                    241:        else
                    242:            putc('\n', output);
                    243: inhibit_newline:
                    244:        ++ps.out_lines;
                    245:        if (ps.just_saw_decl == 1 && blanklines_after_declarations) {
                    246:            prefix_blankline_requested = 1;
                    247:            ps.just_saw_decl = 0;
                    248:        }
                    249:        else
                    250:            prefix_blankline_requested = postfix_blankline_requested;
                    251:        postfix_blankline_requested = 0;
                    252:     }
                    253:     ps.decl_on_line = ps.in_decl;      /* if we are in the middle of a
                    254:                                         * declaration, remember that fact
                    255:                                         * for proper comment indentation */
                    256:     ps.ind_stmt = ps.in_stmt & ~ps.in_decl;    /* next line should be
                    257:                                                 * indented if we have not
                    258:                                                 * completed this stmt and
                    259:                                                 * if we are not in the
                    260:                                                 * middle of a declaration */
                    261:     ps.use_ff = false;
                    262:     ps.dumped_decl_indent = 0;
                    263:     *(e_lab = s_lab) = '\0';   /* reset buffers */
                    264:     *(e_code = s_code) = '\0';
                    265:     *(e_com = s_com) = '\0';
                    266:     ps.ind_level = ps.i_l_follow;
                    267:     ps.paren_level = ps.p_l_follow;
                    268:     paren_target = -ps.paren_indents[ps.paren_level - 1];
                    269:     return;
                    270: };
                    271: 
                    272: compute_code_target() {
                    273:     register    target_col = ps.ind_size * ps.ind_level + 1;
                    274: 
                    275:     if (ps.paren_level)
                    276:        if (!lineup_to_parens)
                    277:            target_col += continuation_indent * ps.paren_level;
                    278:        else {
                    279:            register    w;
                    280:            register    t = paren_target;
                    281: 
                    282:            if ((w = count_spaces(t, s_code) - max_col) > 0
                    283:                && count_spaces(target_col, s_code) <= max_col) {
                    284:                t -= w + 1;
                    285:                if (t > target_col)
                    286:                    target_col = t;
                    287:            }
                    288:            else
                    289:                target_col = t;
                    290:        }
                    291:     else if (ps.ind_stmt)
                    292:        target_col += continuation_indent;
                    293:     return target_col;
                    294: }
                    295: 
                    296: compute_label_target()
                    297: {
                    298:     return
                    299:        ps.pcase ? (int) (case_ind * ps.ind_size) +1
                    300:        : *s_lab == '#' ? 1
                    301:        : ps.ind_size * (ps.ind_level - label_offset) +1;
                    302: }
                    303: 
                    304: 
                    305: /*
                    306:  * Copyright (C) 1976 by the Board of Trustees of the University of
                    307:  * Illinois 
                    308:  *
                    309:  * All rights reserved 
                    310:  *
                    311:  *
                    312:  * NAME: fill_buffer 
                    313:  *
                    314:  * FUNCTION: Reads one block of input into input_buffer 
                    315:  *
                    316:  * HISTORY: initial coding     November 1976   D A Willcox of CAC 1/7/77
                    317:  * A Willcox of CAC    Added check for switch back to partly full input
                    318:  * buffer from temporary buffer 
                    319:  *
                    320:  */
                    321: int
                    322: fill_buffer()
                    323: {                              /* this routine reads stuff from the input */
                    324:     int         count;
                    325:     register char *p;
                    326:     register int i;
                    327:     register FILE *f = input;
                    328: 
                    329:     if (bp_save != 0) {                /* there is a partly filled input buffer
                    330:                                 * left */
                    331:        buf_ptr = bp_save;      /* dont read anything, just switch buffers */
                    332:        buf_end = be_save;
                    333:        bp_save = be_save = 0;
                    334:        if (buf_ptr < buf_end)
                    335:            return;             /* only return if there is really
                    336:                                 * something in this buffer */
                    337:     }
                    338:     p = in_buffer;
                    339:     buf_ptr = p;
                    340:     while ((*p++ = i = getc(f)) != EOF && i != '\n');
                    341:     if (i == EOF) {
                    342:        p[-1] = ' ';
                    343:        *p++ = '\n';
                    344:        had_eof = true;
                    345:     }
                    346:     buf_end = p;
                    347:     if (p[-2] == '/' && p[-3] == '*') {
                    348:        if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0)
                    349:            fill_buffer();      /* flush indent error message */
                    350:        else {
                    351:            int         com = 0;
                    352: 
                    353:            p = in_buffer;
                    354:            while (*p == ' ' || *p == '\t')
                    355:                p++;
                    356:            if (*p == '/' && p[1] == '*') {
                    357:                p += 2;
                    358:                while (*p == ' ' || *p == '\t')
                    359:                    p++;
                    360:                if (p[0] == 'I' && p[1] == 'N' && p[2] == 'D' && p[3] == 'E'
                    361:                    && p[4] == 'N' && p[5] == 'T') {
                    362:                    p += 6;
                    363:                    while (*p == ' ' || *p == '\t')
                    364:                        p++;
                    365:                    if (*p == '*')
                    366:                        com = 1;
                    367:                    else if (*p == 'O')
                    368:                        if (*++p == 'N')
                    369:                            p++, com = 1;
                    370:                        else if (*p == 'F' && *++p == 'F')
                    371:                            p++, com = 2;
                    372:                    while (*p == ' ' || *p == '\t')
                    373:                        p++;
                    374:                    if (p[0] == '*' && p[1] == '/' && p[2] == '\n' && com) {
                    375:                        if (s_com != e_com || s_lab != e_lab || s_code != e_code)
                    376:                            dump_line();
                    377:                        if (!(inhibit_formatting = com - 1)) {
                    378:                            n_real_blanklines = 0;
                    379:                            postfix_blankline_requested = 0;
                    380:                            prefix_blankline_requested = 0;
                    381:                            suppress_blanklines = 1;
                    382:                        }
                    383:                    }
                    384:                }
                    385:            }
                    386:        }
                    387:     }
                    388:     if (inhibit_formatting) {
                    389:        p = in_buffer;
                    390:        do
                    391:            putc(*p, output);
                    392:        while (*p++ != '\n');
                    393:     }
                    394:     return;
                    395: };
                    396: 
                    397: /*
                    398:  * Copyright (C) 1976 by the Board of Trustees of the University of
                    399:  * Illinois 
                    400:  *
                    401:  * All rights reserved 
                    402:  *
                    403:  *
                    404:  * NAME: pad_output 
                    405:  *
                    406:  * FUNCTION: Writes tabs and spaces to move the current column up to the
                    407:  * desired position. 
                    408:  *
                    409:  * ALGORITHM: Put tabs and/or blanks into pobuf, then write pobuf. 
                    410:  *
                    411:  * PARAMETERS: current         integer         The current column target
                    412:  * nteger              The desired column 
                    413:  *
                    414:  * RETURNS: Integer value of the new column.  (If current >= target, no
                    415:  * action is taken, and current is returned. 
                    416:  *
                    417:  * GLOBALS: None 
                    418:  *
                    419:  * CALLS: write (sys) 
                    420:  *
                    421:  * CALLED BY: dump_line 
                    422:  *
                    423:  * HISTORY: initial coding     November 1976   D A Willcox of CAC 
                    424:  *
                    425:  */
                    426: pad_output(current, target)    /* writes tabs and blanks (if necessary)
                    427:                                 * to get the current output position up
                    428:                                 * to the target column */
                    429:     int         current;       /* the current column value */
                    430:     int         target;                /* position we want it at */
                    431: {
                    432:     register int curr;         /* internal column pointer */
                    433:     register int tcur;
                    434: 
                    435:     if (troff)
                    436:        fprintf(output, "\\h'|%dp'", (target - 1) * 7);
                    437:     else {
                    438:        if (current >= target)
                    439:            return (current);   /* line is already long enough */
                    440:        curr = current;
                    441:        while ((tcur = ((curr - 1) & tabmask) + tabsize + 1) <= target) {
                    442:            putc('\t', output);
                    443:            curr = tcur;
                    444:        }
                    445:        while (curr++ < target)
                    446:            putc(' ', output);  /* pad with final blanks */
                    447:     }
                    448:     return (target);
                    449: };
                    450: 
                    451: /*
                    452:  * Copyright (C) 1976 by the Board of Trustees of the University of
                    453:  * Illinois 
                    454:  *
                    455:  * All rights reserved 
                    456:  *
                    457:  *
                    458:  * NAME: count_spaces 
                    459:  *
                    460:  * FUNCTION: Find out where printing of a given string will leave the current
                    461:  * character position on output. 
                    462:  *
                    463:  * ALGORITHM: Run thru input string and add appropriate values to current
                    464:  * position. 
                    465:  *
                    466:  * RETURNS: Integer value of position after printing "buffer" starting in
                    467:  * column "current". 
                    468:  *
                    469:  * HISTORY: initial coding     November 1976   D A Willcox of CAC 
                    470:  *
                    471:  */
                    472: int
                    473: count_spaces(current, buffer)
                    474: 
                    475: /*
                    476:  * this routine figures out where the character position will be after
                    477:  * printing the text in buffer starting at column "current" 
                    478:  */
                    479:     int         current;
                    480:     char       *buffer;
                    481: {
                    482:     register char *buf;                /* used to look thru buffer */
                    483:     register int cur;          /* current character counter */
                    484: 
                    485:     cur = current;
                    486: 
                    487:     for (buf = buffer; *buf != '\0'; ++buf) {
                    488:        switch (*buf) {
                    489: 
                    490:            case '\n':
                    491:            case 014:           /* form feed */
                    492:                cur = 1;
                    493:                break;
                    494: 
                    495:            case '\t':
                    496:                cur = ((cur - 1) & tabmask) + tabsize + 1;
                    497:                break;
                    498: 
                    499:            case '':           /* this is a backspace */
                    500:                --cur;
                    501:                break;
                    502: 
                    503:            default:
                    504:                ++cur;
                    505:                break;
                    506:        }                       /* end of switch */
                    507:     }                          /* end of for loop */
                    508:     return (cur);
                    509: };
                    510: 
                    511: int    found_err;
                    512: diag(level, msg, a, b)
                    513: {
                    514:     if (level)
                    515:        found_err = 1;
                    516:     if (output == stdout) {
                    517:        fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no);
                    518:        fprintf(stdout, msg, a, b);
                    519:        fprintf(stdout, " */\n");
                    520:     }
                    521:     else {
                    522:        fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no);
                    523:        fprintf(stderr, msg, a, b);
                    524:        fprintf(stderr, "\n");
                    525:     }
                    526: }

unix.superglobalmegacorp.com

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