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