Annotation of researchv10no/cmd/f2c/niceprintf.c, revision 1.1.1.1

1.1       root        1: /****************************************************************
                      2: Copyright 1990, 1991, 1993 by AT&T Bell Laboratories and Bellcore.
                      3: 
                      4: Permission to use, copy, modify, and distribute this software
                      5: and its documentation for any purpose and without fee is hereby
                      6: granted, provided that the above copyright notice appear in all
                      7: copies and that both that the copyright notice and this
                      8: permission notice and warranty disclaimer appear in supporting
                      9: documentation, and that the names of AT&T Bell Laboratories or
                     10: Bellcore or any of their entities not be used in advertising or
                     11: publicity pertaining to distribution of the software without
                     12: specific, written prior permission.
                     13: 
                     14: AT&T and Bellcore disclaim all warranties with regard to this
                     15: software, including all implied warranties of merchantability
                     16: and fitness.  In no event shall AT&T or Bellcore be liable for
                     17: any special, indirect or consequential damages or any damages
                     18: whatsoever resulting from loss of use, data or profits, whether
                     19: in an action of contract, negligence or other tortious action,
                     20: arising out of or in connection with the use or performance of
                     21: this software.
                     22: ****************************************************************/
                     23: 
                     24: #include "defs.h"
                     25: #include "names.h"
                     26: #include "output.h"
                     27: 
                     28: #define TOO_LONG_INDENT (2 * tab_size)
                     29: #define MAX_INDENT 44
                     30: #define MIN_INDENT 22
                     31: static int last_was_newline = 0;
                     32: int indent = 0;
                     33: int in_comment = 0;
                     34: int in_define = 0;
                     35:  extern int gflag1;
                     36:  extern char *file_name;
                     37: 
                     38:  static int
                     39: write_indent(fp, use_indent, extra_indent, start, end)
                     40:  FILE *fp;
                     41:  int use_indent, extra_indent;
                     42:  char *start, *end;
                     43: {
                     44:     int ind, tab;
                     45: 
                     46:     if (gflag1 && last_was_newline)
                     47:        fprintf(fp, "#line %ld \"%s\"\n", lineno, file_name);
                     48:     if (in_define == 1) {
                     49:        in_define = 2;
                     50:        use_indent = 0;
                     51:        }
                     52:     if (last_was_newline && use_indent) {
                     53:        if (*start == '\n') do {
                     54:                putc('\n', fp);
                     55:                if (++start > end)
                     56:                        return;
                     57:                }
                     58:                while(*start == '\n');
                     59: 
                     60:        ind = indent <= MAX_INDENT
                     61:                ? indent
                     62:                : MIN_INDENT + indent % (MAX_INDENT - MIN_INDENT);
                     63: 
                     64:        tab = ind + extra_indent;
                     65: 
                     66:        while (tab > 7) {
                     67:            putc ('\t', fp);
                     68:            tab -= 8;
                     69:        } /* while */
                     70: 
                     71:        while (tab-- > 0)
                     72:            putc (' ', fp);
                     73:     } /* if last_was_newline */
                     74: 
                     75:     while (start <= end)
                     76:        putc (*start++, fp);
                     77: } /* write_indent */
                     78: 
                     79: 
                     80: /*VARARGS2*/
                     81: int margin_printf (fp, a, b, c, d, e, f, g)
                     82: FILE *fp;
                     83: char *a;
                     84: long b, c, d, e, f, g;
                     85: {
                     86:     ind_printf (0, fp, a, b, c, d, e, f, g);
                     87: } /* margin_printf */
                     88: 
                     89: /*VARARGS2*/
                     90: int nice_printf (fp, a, b, c, d, e, f, g)
                     91: FILE *fp;
                     92: char *a;
                     93: long b, c, d, e, f, g;
                     94: {
                     95:     ind_printf (1, fp, a, b, c, d, e, f, g);
                     96: } /* nice_printf */
                     97: 
                     98: 
                     99: #define  max_line_len c_output_line_length
                    100:                /* 74Number of characters allowed on an output
                    101:                                   line.  This assumes newlines are handled
                    102:                                   nicely, i.e. a newline after a full text
                    103:                                   line on a terminal is ignored */
                    104: 
                    105: /* output_buf   holds the text of the next line to be printed.  It gets
                    106:    flushed when a newline is printed.   next_slot   points to the next
                    107:    available location in the output buffer, i.e. where the next call to
                    108:    nice_printf will have its output stored */
                    109: 
                    110: static char *output_buf;
                    111: static char *next_slot;
                    112: static char *string_start;
                    113: 
                    114: static char *word_start = NULL;
                    115: static int cursor_pos = 0;
                    116: static int In_string = 0;
                    117: 
                    118:  void
                    119: np_init()
                    120: {
                    121:        next_slot = output_buf = Alloc(MAX_OUTPUT_SIZE);
                    122:        memset(output_buf, 0, MAX_OUTPUT_SIZE);
                    123:        }
                    124: 
                    125:  static char *
                    126: adjust_pointer_in_string(pointer)
                    127:  register char *pointer;
                    128: {
                    129:        register char *s, *s1, *se, *s0;
                    130: 
                    131:        /* arrange not to break \002 */
                    132:        s1 = string_start ? string_start : output_buf;
                    133:        for(s = s1; s < pointer; s++) {
                    134:                s0 = s1;
                    135:                s1 = s;
                    136:                if (*s == '\\') {
                    137:                        se = s++ + 4;
                    138:                        if (se > pointer)
                    139:                                break;
                    140:                        if (*s < '0' || *s > '7')
                    141:                                continue;
                    142:                        while(++s < se)
                    143:                                if (*s < '0' || *s > '7')
                    144:                                        break;
                    145:                        --s;
                    146:                        }
                    147:                }
                    148:        return s0 - 1;
                    149:        }
                    150: 
                    151: /* ANSI says strcpy's behavior is undefined for overlapping args,
                    152:  * so we roll our own fwd_strcpy: */
                    153: 
                    154:  static void
                    155: fwd_strcpy(t, s)
                    156:  register char *t, *s;
                    157: { while(*t++ = *s++); }
                    158: 
                    159: /* isident -- true iff character could belong to a unit.  C allows
                    160:    letters, numbers and underscores in identifiers.  This also doubles as
                    161:    a check for numeric constants, since we include the decimal point and
                    162:    minus sign.  The minus has to be here, since the constant "10e-2"
                    163:    cannot be broken up.  The '.' also prevents structure references from
                    164:    being broken, which is a quite acceptable side effect */
                    165: 
                    166: #define isident(x) (Tr[x] & 1)
                    167: #define isntident(x) (!Tr[x])
                    168: 
                    169: int ind_printf (use_indent, fp, a, b, c, d, e, f, g)
                    170: int use_indent;
                    171: FILE *fp;
                    172: char *a;
                    173: long b, c, d, e, f, g;
                    174: {
                    175:     extern int max_line_len;
                    176:     extern FILEP c_file;
                    177:     extern char tr_tab[];      /* in output.c */
                    178:     register char *Tr = tr_tab;
                    179:     int ch, inc, ind;
                    180:     static int extra_indent, last_indent, set_cursor = 1;
                    181: 
                    182:     cursor_pos += indent - last_indent;
                    183:     last_indent = indent;
                    184:     sprintf (next_slot, a, b, c, d, e, f, g);
                    185: 
                    186:     if (fp != c_file) {
                    187:        fprintf (fp,"%s", next_slot);
                    188:        return 1;
                    189:     } /* if fp != c_file */
                    190: 
                    191:     do {
                    192:        char *pointer;
                    193: 
                    194: /* The   for   loop will parse one output line */
                    195: 
                    196:        if (set_cursor) {
                    197:                ind = indent <= MAX_INDENT
                    198:                        ? indent
                    199:                        : MIN_INDENT + indent % (MAX_INDENT - MIN_INDENT);
                    200:                cursor_pos = ind + extra_indent;
                    201:                set_cursor = 0;
                    202:                }
                    203:        if (in_comment)
                    204:                for (pointer = next_slot; *pointer && *pointer != '\n' &&
                    205:                                cursor_pos <= max_line_len; pointer++)
                    206:                        cursor_pos++;
                    207:        else
                    208:           for (pointer = next_slot; *pointer && *pointer != '\n' &&
                    209:                cursor_pos <= max_line_len; pointer++) {
                    210: 
                    211:            /* Update state variables here */
                    212: 
                    213:            if (In_string) {
                    214:                switch(*pointer) {
                    215:                        case '\\':
                    216:                                if (++cursor_pos > max_line_len) {
                    217:                                        cursor_pos -= 2;
                    218:                                        --pointer;
                    219:                                        goto overflow;
                    220:                                        }
                    221:                                ++pointer;
                    222:                                break;
                    223:                        case '"':
                    224:                                In_string = 0;
                    225:                                word_start = 0;
                    226:                        }
                    227:                }
                    228:            else switch (*pointer) {
                    229:                case '"':
                    230:                        if (cursor_pos + 5 > max_line_len) {
                    231:                                word_start = 0;
                    232:                                --pointer;
                    233:                                goto overflow;
                    234:                                }
                    235:                        In_string = 1;
                    236:                        string_start = word_start = pointer;
                    237:                        break;
                    238:                case '\'':
                    239:                        if (pointer[1] == '\\')
                    240:                                if ((ch = pointer[2]) >= '0' && ch <= '7')
                    241:                                        for(inc = 3; pointer[inc] != '\''
                    242:                                                && ++inc < 5;);
                    243:                                else
                    244:                                        inc = 3;
                    245:                        else
                    246:                                inc = 2;
                    247:                        /*debug*/ if (pointer[inc] != '\'')
                    248:                        /*debug*/  fatalstr("Bad character constant %.10s",
                    249:                                        pointer);
                    250:                        if ((cursor_pos += inc) > max_line_len) {
                    251:                                cursor_pos -= inc;
                    252:                                word_start = 0;
                    253:                                --pointer;
                    254:                                goto overflow;
                    255:                                }
                    256:                        word_start = pointer;
                    257:                        pointer += inc;
                    258:                        break;
                    259:                case '\t':
                    260:                    cursor_pos = 8 * ((cursor_pos + 8) / 8) - 1;
                    261:                    break;
                    262:                default: {
                    263: 
                    264: /* HACK  Assumes that all characters in an atomic C token will be written
                    265:    at the same time.  Must check for tokens first, since '-' is considered
                    266:    part of an identifier; checking isident first would mean breaking up "->" */
                    267: 
                    268:                    if (word_start) {
                    269:                        if (isntident(*(unsigned char *)pointer))
                    270:                                word_start = NULL;
                    271:                        }
                    272:                    else if (isident(*(unsigned char *)pointer))
                    273:                        word_start = pointer;
                    274:                    break;
                    275:                } /* default */
                    276:            } /* switch */
                    277:            cursor_pos++;
                    278:        } /* for pointer = next_slot */
                    279:  overflow:
                    280:        if (*pointer == '\0') {
                    281: 
                    282: /* The output line is not complete, so break out and don't output
                    283:    anything.  The current line fragment will be stored in the buffer */
                    284: 
                    285:            next_slot = pointer;
                    286:            break;
                    287:        } else {
                    288:            char last_char;
                    289:            int in_string0 = In_string;
                    290: 
                    291: /* If the line was too long, move   pointer   back to the character before
                    292:    the current word.  This allows line breaking on word boundaries.  Make
                    293:    sure that 80 character comment lines get broken up somehow.  We assume
                    294:    that any non-string 80 character identifier must be in a comment.
                    295: */
                    296: 
                    297:            if (*pointer == '\n')
                    298:                in_define = 0;
                    299:            else if (word_start && word_start > output_buf)
                    300:                if (In_string)
                    301:                        if (string_start && pointer - string_start < 5)
                    302:                                pointer = string_start - 1;
                    303:                        else {
                    304:                                pointer = adjust_pointer_in_string(pointer);
                    305:                                string_start = 0;
                    306:                                }
                    307:                else if (word_start == string_start
                    308:                                && pointer - string_start >= 5) {
                    309:                        pointer = adjust_pointer_in_string(next_slot);
                    310:                        In_string = 1;
                    311:                        string_start = 0;
                    312:                        }
                    313:                else
                    314:                        pointer = word_start - 1;
                    315:            else if (cursor_pos > max_line_len) {
                    316: #ifndef ANSI_Libraries
                    317:                extern char *strchr();
                    318: #endif
                    319:                if (In_string) {
                    320:                        pointer = adjust_pointer_in_string(pointer);
                    321:                        if (string_start && pointer > string_start)
                    322:                                string_start = 0;
                    323:                        }
                    324:                else if (strchr("&*+-/<=>|", *pointer)
                    325:                        && strchr("!%&*+-/<=>^|", pointer[-1])) {
                    326:                        pointer -= 2;
                    327:                        if (strchr("<>", *pointer)) /* <<=, >>= */
                    328:                                pointer--;
                    329:                        }
                    330:                else {
                    331:                        if (word_start)
                    332:                                while(isident(*(unsigned char *)pointer))
                    333:                                        pointer++;
                    334:                        pointer--;
                    335:                        }
                    336:                }
                    337:            last_char = *pointer;
                    338:            write_indent(fp, use_indent, extra_indent, output_buf, pointer);
                    339:            next_slot = output_buf;
                    340:            if (In_string && !string_start && Ansi == 1 && last_char != '\n')
                    341:                *next_slot++ = '"';
                    342:            fwd_strcpy(next_slot, pointer + 1);
                    343: 
                    344: /* insert a line break */
                    345: 
                    346:            if (last_char == '\n') {
                    347:                if (In_string)
                    348:                        last_was_newline = 0;
                    349:                else {
                    350:                        last_was_newline = 1;
                    351:                        extra_indent = 0;
                    352:                        }
                    353:                }
                    354:            else {
                    355:                extra_indent = TOO_LONG_INDENT;
                    356:                if (In_string && !string_start) {
                    357:                        if (Ansi == 1) {
                    358:                                fprintf(fp, "\"\n");
                    359:                                use_indent = 1;
                    360:                                last_was_newline = 1;
                    361:                                }
                    362:                        else {
                    363:                                fprintf(fp, "\\\n");
                    364:                                last_was_newline = 0;
                    365:                                }
                    366:                        In_string = in_string0;
                    367:                        }
                    368:                else {
                    369:                        if (in_define)
                    370:                                putc('\\', fp);
                    371:                        putc ('\n', fp);
                    372:                        last_was_newline = 1;
                    373:                        }
                    374:            } /* if *pointer != '\n' */
                    375: 
                    376:            if (In_string && Ansi != 1 && !string_start)
                    377:                cursor_pos = 0;
                    378:            else
                    379:                set_cursor = 1;
                    380: 
                    381:            string_start = word_start = NULL;
                    382: 
                    383:        } /* else */
                    384: 
                    385:     } while (*next_slot);
                    386: 
                    387:     return 0;
                    388: } /* ind_printf */

unix.superglobalmegacorp.com

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