|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1985 Sun Microsystems, Inc. ! 3: * Copyright (c) 1980 The Regents of the University of California. ! 4: * Copyright (c) 1976 Board of Trustees of the University of Illinois. ! 5: * All rights reserved. ! 6: * ! 7: * Redistribution and use in source and binary forms are permitted ! 8: * provided that: (1) source distributions retain this entire copyright ! 9: * notice and comment, and (2) distributions including binaries display ! 10: * the following acknowledgement: ``This product includes software ! 11: * developed by the University of California, Berkeley and its contributors'' ! 12: * in the documentation or other materials provided with the distribution ! 13: * and in all advertising materials mentioning features or use of this ! 14: * software. Neither the name of the University nor the names of its ! 15: * contributors may be used to endorse or promote products derived ! 16: * from this software without specific prior written permission. ! 17: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 18: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 19: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 20: */ ! 21: ! 22: #ifndef lint ! 23: char copyright[] = ! 24: "@(#) Copyright (c) 1985 Sun Microsystems, Inc.\n\ ! 25: @(#) Copyright (c) 1980 The Regents of the University of California.\n\ ! 26: @(#) Copyright (c) 1976 Board of Trustees of the University of Illinois.\n\ ! 27: All rights reserved.\n"; ! 28: #endif /* not lint */ ! 29: ! 30: #ifndef lint ! 31: static char sccsid[] = "@(#)indent.c 5.15 (Berkeley) 6/1/90"; ! 32: #endif /* not lint */ ! 33: ! 34: #include <sys/param.h> ! 35: #include "indent_globs.h" ! 36: #include "indent_codes.h" ! 37: #include <ctype.h> ! 38: ! 39: char *in_name = "Standard Input"; /* will always point to name of input ! 40: * file */ ! 41: char *out_name = "Standard Output"; /* will always point to name ! 42: * of output file */ ! 43: char bakfile[MAXPATHLEN] = ""; ! 44: ! 45: main(argc, argv) ! 46: int argc; ! 47: char **argv; ! 48: { ! 49: ! 50: extern int found_err; /* flag set in diag() on error */ ! 51: int dec_ind; /* current indentation for declarations */ ! 52: int di_stack[20]; /* a stack of structure indentation levels */ ! 53: int flushed_nl; /* used when buffering up comments to remember ! 54: * that a newline was passed over */ ! 55: int force_nl; /* when true, code must be broken */ ! 56: int hd_type; /* used to store type of stmt for if (...), ! 57: * for (...), etc */ ! 58: register int i; /* local loop counter */ ! 59: int scase; /* set to true when we see a case, so we will ! 60: * know what to do with the following colon */ ! 61: int sp_sw; /* when true, we are in the expressin of ! 62: * if(...), while(...), etc. */ ! 63: int squest; /* when this is positive, we have seen a ? ! 64: * without the matching : in a <c>?<s>:<s> ! 65: * construct */ ! 66: register char *t_ptr; /* used for copying tokens */ ! 67: int type_code; /* the type of token, returned by lexi */ ! 68: ! 69: int last_else = 0; /* true iff last keyword was an else */ ! 70: ! 71: ! 72: /*-----------------------------------------------*\ ! 73: | INITIALIZATION | ! 74: \*-----------------------------------------------*/ ! 75: ! 76: ! 77: ps.p_stack[0] = stmt; /* this is the parser's stack */ ! 78: ps.last_nl = true; /* this is true if the last thing scanned was ! 79: * a newline */ ! 80: ps.last_token = semicolon; ! 81: combuf = (char *) malloc(bufsize); ! 82: labbuf = (char *) malloc(bufsize); ! 83: codebuf = (char *) malloc(bufsize); ! 84: tokenbuf = (char *) malloc(bufsize); ! 85: l_com = combuf + bufsize - 5; ! 86: l_lab = labbuf + bufsize - 5; ! 87: l_code = codebuf + bufsize - 5; ! 88: l_token = tokenbuf + bufsize - 5; ! 89: combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and ! 90: * comment buffers */ ! 91: combuf[1] = codebuf[1] = labbuf[1] = '\0'; ! 92: ps.else_if = 1; /* Default else-if special processing to on */ ! 93: s_lab = e_lab = labbuf + 1; ! 94: s_code = e_code = codebuf + 1; ! 95: s_com = e_com = combuf + 1; ! 96: s_token = e_token = tokenbuf + 1; ! 97: ! 98: in_buffer = (char *) malloc(10); ! 99: in_buffer_limit = in_buffer + 8; ! 100: buf_ptr = buf_end = in_buffer; ! 101: line_no = 1; ! 102: had_eof = ps.in_decl = ps.decl_on_line = break_comma = false; ! 103: sp_sw = force_nl = false; ! 104: ps.in_or_st = false; ! 105: ps.bl_line = true; ! 106: dec_ind = 0; ! 107: di_stack[ps.dec_nest = 0] = 0; ! 108: ps.want_blank = ps.in_stmt = ps.ind_stmt = false; ! 109: ! 110: ! 111: scase = ps.pcase = false; ! 112: squest = 0; ! 113: sc_end = 0; ! 114: bp_save = 0; ! 115: be_save = 0; ! 116: ! 117: output = 0; ! 118: ! 119: ! 120: ! 121: /*--------------------------------------------------*\ ! 122: | COMMAND LINE SCAN | ! 123: \*--------------------------------------------------*/ ! 124: ! 125: #ifdef undef ! 126: max_col = 78; /* -l78 */ ! 127: lineup_to_parens = 1; /* -lp */ ! 128: ps.ljust_decl = 0; /* -ndj */ ! 129: ps.com_ind = 33; /* -c33 */ ! 130: star_comment_cont = 1; /* -sc */ ! 131: ps.ind_size = 8; /* -i8 */ ! 132: verbose = 0; ! 133: ps.decl_indent = 16; /* -di16 */ ! 134: ps.indent_parameters = 1; /* -ip */ ! 135: ps.decl_com_ind = 0; /* if this is not set to some positive value ! 136: * by an arg, we will set this equal to ! 137: * ps.com_ind */ ! 138: btype_2 = 1; /* -br */ ! 139: cuddle_else = 1; /* -ce */ ! 140: ps.unindent_displace = 0; /* -d0 */ ! 141: ps.case_indent = 0; /* -cli0 */ ! 142: format_col1_comments = 1; /* -fc1 */ ! 143: procnames_start_line = 1; /* -psl */ ! 144: proc_calls_space = 0; /* -npcs */ ! 145: comment_delimiter_on_blankline = 1; /* -cdb */ ! 146: ps.leave_comma = 1; /* -nbc */ ! 147: #endif ! 148: ! 149: for (i = 1; i < argc; ++i) ! 150: if (strcmp(argv[i], "-npro") == 0) ! 151: break; ! 152: set_defaults(); ! 153: if (i >= argc) ! 154: set_profile(); ! 155: ! 156: for (i = 1; i < argc; ++i) { ! 157: ! 158: /* ! 159: * look thru args (if any) for changes to defaults ! 160: */ ! 161: if (argv[i][0] != '-') {/* no flag on parameter */ ! 162: if (input == 0) { /* we must have the input file */ ! 163: in_name = argv[i]; /* remember name of input file */ ! 164: input = fopen(in_name, "r"); ! 165: if (input == 0) /* check for open error */ ! 166: err(in_name); ! 167: continue; ! 168: } ! 169: else if (output == 0) { /* we have the output file */ ! 170: out_name = argv[i]; /* remember name of output file */ ! 171: if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite ! 172: * the file */ ! 173: fprintf(stderr, "indent: input and output files must be different\n"); ! 174: exit(1); ! 175: } ! 176: output = fopen(out_name, "w"); ! 177: if (output == 0) /* check for create error */ ! 178: err(out_name); ! 179: continue; ! 180: } ! 181: fprintf(stderr, "indent: unknown parameter: %s\n", argv[i]); ! 182: exit(1); ! 183: } ! 184: else ! 185: set_option(argv[i]); ! 186: } /* end of for */ ! 187: if (input == 0) { ! 188: fprintf(stderr, "indent: usage: indent file [ outfile ] [ options ]\n"); ! 189: exit(1); ! 190: } ! 191: if (output == 0) ! 192: if (troff) ! 193: output = stdout; ! 194: else { ! 195: out_name = in_name; ! 196: bakcopy(); ! 197: } ! 198: if (ps.com_ind <= 1) ! 199: ps.com_ind = 2; /* dont put normal comments before column 2 */ ! 200: if (troff) { ! 201: if (bodyf.font[0] == 0) ! 202: parsefont(&bodyf, "R"); ! 203: if (scomf.font[0] == 0) ! 204: parsefont(&scomf, "I"); ! 205: if (blkcomf.font[0] == 0) ! 206: blkcomf = scomf, blkcomf.size += 2; ! 207: if (boxcomf.font[0] == 0) ! 208: boxcomf = blkcomf; ! 209: if (stringf.font[0] == 0) ! 210: parsefont(&stringf, "L"); ! 211: if (keywordf.font[0] == 0) ! 212: parsefont(&keywordf, "B"); ! 213: writefdef(&bodyf, 'B'); ! 214: writefdef(&scomf, 'C'); ! 215: writefdef(&blkcomf, 'L'); ! 216: writefdef(&boxcomf, 'X'); ! 217: writefdef(&stringf, 'S'); ! 218: writefdef(&keywordf, 'K'); ! 219: } ! 220: if (block_comment_max_col <= 0) ! 221: block_comment_max_col = max_col; ! 222: if (ps.decl_com_ind <= 0) /* if not specified by user, set this */ ! 223: ps.decl_com_ind = ps.ljust_decl ? (ps.com_ind <= 10 ? 2 : ps.com_ind - 8) : ps.com_ind; ! 224: if (continuation_indent == 0) ! 225: continuation_indent = ps.ind_size; ! 226: fill_buffer(); /* get first batch of stuff into input buffer */ ! 227: ! 228: parse(semicolon); ! 229: { ! 230: register char *p = buf_ptr; ! 231: register col = 1; ! 232: ! 233: while (1) { ! 234: if (*p == ' ') ! 235: col++; ! 236: else if (*p == '\t') ! 237: col = ((col - 1) & ~7) + 9; ! 238: else ! 239: break; ! 240: p++; ! 241: } ! 242: if (col > ps.ind_size) ! 243: ps.ind_level = ps.i_l_follow = col / ps.ind_size; ! 244: } ! 245: if (troff) { ! 246: register char *p = in_name, ! 247: *beg = in_name; ! 248: ! 249: while (*p) ! 250: if (*p++ == '/') ! 251: beg = p; ! 252: fprintf(output, ".Fn \"%s\"\n", beg); ! 253: } ! 254: /* ! 255: * START OF MAIN LOOP ! 256: */ ! 257: ! 258: while (1) { /* this is the main loop. it will go until we ! 259: * reach eof */ ! 260: int is_procname; ! 261: ! 262: type_code = lexi(); /* lexi reads one token. The actual ! 263: * characters read are stored in "token". lexi ! 264: * returns a code indicating the type of token */ ! 265: is_procname = ps.procname[0]; ! 266: ! 267: /* ! 268: * The following code moves everything following an if (), while (), ! 269: * else, etc. up to the start of the following stmt to a buffer. This ! 270: * allows proper handling of both kinds of brace placement. ! 271: */ ! 272: ! 273: flushed_nl = false; ! 274: while (ps.search_brace) { /* if we scanned an if(), while(), ! 275: * etc., we might need to copy stuff ! 276: * into a buffer we must loop, copying ! 277: * stuff into save_com, until we find ! 278: * the start of the stmt which follows ! 279: * the if, or whatever */ ! 280: switch (type_code) { ! 281: case newline: ! 282: ++line_no; ! 283: flushed_nl = true; ! 284: case form_feed: ! 285: break; /* form feeds and newlines found here will be ! 286: * ignored */ ! 287: ! 288: case lbrace: /* this is a brace that starts the compound ! 289: * stmt */ ! 290: if (sc_end == 0) { /* ignore buffering if a comment wasnt ! 291: * stored up */ ! 292: ps.search_brace = false; ! 293: goto check_type; ! 294: } ! 295: if (btype_2) { ! 296: save_com[0] = '{'; /* we either want to put the brace ! 297: * right after the if */ ! 298: goto sw_buffer; /* go to common code to get out of ! 299: * this loop */ ! 300: } ! 301: case comment: /* we have a comment, so we must copy it into ! 302: * the buffer */ ! 303: if (!flushed_nl || sc_end != 0) { ! 304: if (sc_end == 0) { /* if this is the first comment, we ! 305: * must set up the buffer */ ! 306: save_com[0] = save_com[1] = ' '; ! 307: sc_end = &(save_com[2]); ! 308: } ! 309: else { ! 310: *sc_end++ = '\n'; /* add newline between ! 311: * comments */ ! 312: *sc_end++ = ' '; ! 313: --line_no; ! 314: } ! 315: *sc_end++ = '/'; /* copy in start of comment */ ! 316: *sc_end++ = '*'; ! 317: ! 318: for (;;) { /* loop until we get to the end of the comment */ ! 319: *sc_end = *buf_ptr++; ! 320: if (buf_ptr >= buf_end) ! 321: fill_buffer(); ! 322: ! 323: if (*sc_end++ == '*' && *buf_ptr == '/') ! 324: break; /* we are at end of comment */ ! 325: ! 326: if (sc_end >= &(save_com[sc_size])) { /* check for temp buffer ! 327: * overflow */ ! 328: diag(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever."); ! 329: fflush(output); ! 330: exit(1); ! 331: } ! 332: } ! 333: *sc_end++ = '/'; /* add ending slash */ ! 334: if (++buf_ptr >= buf_end) /* get past / in buffer */ ! 335: fill_buffer(); ! 336: break; ! 337: } ! 338: default: /* it is the start of a normal statment */ ! 339: if (flushed_nl) /* if we flushed a newline, make sure it is ! 340: * put back */ ! 341: force_nl = true; ! 342: if (type_code == sp_paren && *token == 'i' ! 343: && last_else && ps.else_if ! 344: || type_code == sp_nparen && *token == 'e' ! 345: && e_code != s_code && e_code[-1] == '}') ! 346: force_nl = false; ! 347: ! 348: if (sc_end == 0) { /* ignore buffering if comment wasnt ! 349: * saved up */ ! 350: ps.search_brace = false; ! 351: goto check_type; ! 352: } ! 353: if (force_nl) { /* if we should insert a nl here, put it into ! 354: * the buffer */ ! 355: force_nl = false; ! 356: --line_no; /* this will be re-increased when the nl is ! 357: * read from the buffer */ ! 358: *sc_end++ = '\n'; ! 359: *sc_end++ = ' '; ! 360: if (verbose && !flushed_nl) /* print error msg if the line ! 361: * was not already broken */ ! 362: diag(0, "Line broken"); ! 363: flushed_nl = false; ! 364: } ! 365: for (t_ptr = token; *t_ptr; ++t_ptr) ! 366: *sc_end++ = *t_ptr; /* copy token into temp buffer */ ! 367: ps.procname[0] = 0; ! 368: ! 369: sw_buffer: ! 370: ps.search_brace = false; /* stop looking for start of ! 371: * stmt */ ! 372: bp_save = buf_ptr; /* save current input buffer */ ! 373: be_save = buf_end; ! 374: buf_ptr = save_com; /* fix so that subsequent calls to ! 375: * lexi will take tokens out of ! 376: * save_com */ ! 377: *sc_end++ = ' ';/* add trailing blank, just in case */ ! 378: buf_end = sc_end; ! 379: sc_end = 0; ! 380: break; ! 381: } /* end of switch */ ! 382: if (type_code != 0) /* we must make this check, just in case there ! 383: * was an unexpected EOF */ ! 384: type_code = lexi(); /* read another token */ ! 385: /* if (ps.search_brace) ps.procname[0] = 0; */ ! 386: if ((is_procname = ps.procname[0]) && flushed_nl ! 387: && !procnames_start_line && ps.in_decl ! 388: && type_code == ident) ! 389: flushed_nl = 0; ! 390: } /* end of while (search_brace) */ ! 391: last_else = 0; ! 392: check_type: ! 393: if (type_code == 0) { /* we got eof */ ! 394: if (s_lab != e_lab || s_code != e_code ! 395: || s_com != e_com) /* must dump end of line */ ! 396: dump_line(); ! 397: if (ps.tos > 1) /* check for balanced braces */ ! 398: diag(1, "Stuff missing from end of file."); ! 399: ! 400: if (verbose) { ! 401: printf("There were %d output lines and %d comments\n", ! 402: ps.out_lines, ps.out_coms); ! 403: printf("(Lines with comments)/(Lines with code): %6.3f\n", ! 404: (1.0 * ps.com_lines) / code_lines); ! 405: } ! 406: fflush(output); ! 407: exit(found_err); ! 408: } ! 409: if ( ! 410: (type_code != comment) && ! 411: (type_code != newline) && ! 412: (type_code != preesc) && ! 413: (type_code != form_feed)) { ! 414: if (force_nl && ! 415: (type_code != semicolon) && ! 416: (type_code != lbrace || !btype_2)) { ! 417: /* we should force a broken line here */ ! 418: if (verbose && !flushed_nl) ! 419: diag(0, "Line broken"); ! 420: flushed_nl = false; ! 421: dump_line(); ! 422: ps.want_blank = false; /* dont insert blank at line start */ ! 423: force_nl = false; ! 424: } ! 425: ps.in_stmt = true; /* turn on flag which causes an extra level of ! 426: * indentation. this is turned off by a ; or ! 427: * '}' */ ! 428: if (s_com != e_com) { /* the turkey has embedded a comment ! 429: * in a line. fix it */ ! 430: *e_code++ = ' '; ! 431: for (t_ptr = s_com; *t_ptr; ++t_ptr) { ! 432: CHECK_SIZE_CODE; ! 433: *e_code++ = *t_ptr; ! 434: } ! 435: *e_code++ = ' '; ! 436: *e_code = '\0'; /* null terminate code sect */ ! 437: ps.want_blank = false; ! 438: e_com = s_com; ! 439: } ! 440: } ! 441: else if (type_code != comment) /* preserve force_nl thru a comment */ ! 442: force_nl = false; /* cancel forced newline after newline, form ! 443: * feed, etc */ ! 444: ! 445: ! 446: ! 447: /*-----------------------------------------------------*\ ! 448: | do switch on type of token scanned | ! 449: \*-----------------------------------------------------*/ ! 450: CHECK_SIZE_CODE; ! 451: switch (type_code) { /* now, decide what to do with the token */ ! 452: ! 453: case form_feed: /* found a form feed in line */ ! 454: ps.use_ff = true; /* a form feed is treated much like a newline */ ! 455: dump_line(); ! 456: ps.want_blank = false; ! 457: break; ! 458: ! 459: case newline: ! 460: if (ps.last_token != comma || ps.p_l_follow > 0 ! 461: || !ps.leave_comma || ps.block_init || !break_comma || s_com != e_com) { ! 462: dump_line(); ! 463: ps.want_blank = false; ! 464: } ! 465: ++line_no; /* keep track of input line number */ ! 466: break; ! 467: ! 468: case lparen: /* got a '(' or '[' */ ! 469: ++ps.p_l_follow; /* count parens to make Healy happy */ ! 470: if (ps.want_blank && *token != '[' && ! 471: (ps.last_token != ident || proc_calls_space ! 472: || (ps.its_a_keyword && (!ps.sizeof_keyword || Bill_Shannon)))) ! 473: *e_code++ = ' '; ! 474: if (ps.in_decl && !ps.block_init) ! 475: if (troff && !ps.dumped_decl_indent && !is_procname && ps.last_token == decl) { ! 476: ps.dumped_decl_indent = 1; ! 477: sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); ! 478: e_code += strlen(e_code); ! 479: } ! 480: else { ! 481: while ((e_code - s_code) < dec_ind) { ! 482: CHECK_SIZE_CODE; ! 483: *e_code++ = ' '; ! 484: } ! 485: *e_code++ = token[0]; ! 486: } ! 487: else ! 488: *e_code++ = token[0]; ! 489: ps.paren_indents[ps.p_l_follow - 1] = e_code - s_code; ! 490: if (sp_sw && ps.p_l_follow == 1 && extra_expression_indent ! 491: && ps.paren_indents[0] < 2 * ps.ind_size) ! 492: ps.paren_indents[0] = 2 * ps.ind_size; ! 493: ps.want_blank = false; ! 494: if (ps.in_or_st && *token == '(' && ps.tos <= 2) { ! 495: /* ! 496: * this is a kluge to make sure that declarations will be ! 497: * aligned right if proc decl has an explicit type on it, i.e. ! 498: * "int a(x) {..." ! 499: */ ! 500: parse(semicolon); /* I said this was a kluge... */ ! 501: ps.in_or_st = false; /* turn off flag for structure decl or ! 502: * initialization */ ! 503: } ! 504: if (ps.sizeof_keyword) ! 505: ps.sizeof_mask |= 1 << ps.p_l_follow; ! 506: break; ! 507: ! 508: case rparen: /* got a ')' or ']' */ ! 509: rparen_count--; ! 510: if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.sizeof_mask) { ! 511: ps.last_u_d = true; ! 512: ps.cast_mask &= (1 << ps.p_l_follow) - 1; ! 513: } ! 514: ps.sizeof_mask &= (1 << ps.p_l_follow) - 1; ! 515: if (--ps.p_l_follow < 0) { ! 516: ps.p_l_follow = 0; ! 517: diag(0, "Extra %c", *token); ! 518: } ! 519: if (e_code == s_code) /* if the paren starts the line */ ! 520: ps.paren_level = ps.p_l_follow; /* then indent it */ ! 521: ! 522: *e_code++ = token[0]; ! 523: ps.want_blank = true; ! 524: ! 525: if (sp_sw && (ps.p_l_follow == 0)) { /* check for end of if ! 526: * (...), or some such */ ! 527: sp_sw = false; ! 528: force_nl = true;/* must force newline after if */ ! 529: ps.last_u_d = true; /* inform lexi that a following ! 530: * operator is unary */ ! 531: ps.in_stmt = false; /* dont use stmt continuation ! 532: * indentation */ ! 533: ! 534: parse(hd_type); /* let parser worry about if, or whatever */ ! 535: } ! 536: ps.search_brace = btype_2; /* this should insure that constructs ! 537: * such as main(){...} and int[]{...} ! 538: * have their braces put in the right ! 539: * place */ ! 540: break; ! 541: ! 542: case unary_op: /* this could be any unary operation */ ! 543: if (ps.want_blank) ! 544: *e_code++ = ' '; ! 545: ! 546: if (troff && !ps.dumped_decl_indent && ps.in_decl && !is_procname) { ! 547: sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); ! 548: ps.dumped_decl_indent = 1; ! 549: e_code += strlen(e_code); ! 550: } ! 551: else { ! 552: char *res = token; ! 553: ! 554: if (ps.in_decl && !ps.block_init) { /* if this is a unary op ! 555: * in a declaration, we ! 556: * should indent this ! 557: * token */ ! 558: for (i = 0; token[i]; ++i); /* find length of token */ ! 559: while ((e_code - s_code) < (dec_ind - i)) { ! 560: CHECK_SIZE_CODE; ! 561: *e_code++ = ' '; /* pad it */ ! 562: } ! 563: } ! 564: if (troff && token[0] == '-' && token[1] == '>') ! 565: res = "\\(->"; ! 566: for (t_ptr = res; *t_ptr; ++t_ptr) { ! 567: CHECK_SIZE_CODE; ! 568: *e_code++ = *t_ptr; ! 569: } ! 570: } ! 571: ps.want_blank = false; ! 572: break; ! 573: ! 574: case binary_op: /* any binary operation */ ! 575: if (ps.want_blank) ! 576: *e_code++ = ' '; ! 577: { ! 578: char *res = token; ! 579: ! 580: if (troff) ! 581: switch (token[0]) { ! 582: case '<': ! 583: if (token[1] == '=') ! 584: res = "\\(<="; ! 585: break; ! 586: case '>': ! 587: if (token[1] == '=') ! 588: res = "\\(>="; ! 589: break; ! 590: case '!': ! 591: if (token[1] == '=') ! 592: res = "\\(!="; ! 593: break; ! 594: case '|': ! 595: if (token[1] == '|') ! 596: res = "\\(br\\(br"; ! 597: else if (token[1] == 0) ! 598: res = "\\(br"; ! 599: break; ! 600: } ! 601: for (t_ptr = res; *t_ptr; ++t_ptr) { ! 602: CHECK_SIZE_CODE; ! 603: *e_code++ = *t_ptr; /* move the operator */ ! 604: } ! 605: } ! 606: ps.want_blank = true; ! 607: break; ! 608: ! 609: case postop: /* got a trailing ++ or -- */ ! 610: *e_code++ = token[0]; ! 611: *e_code++ = token[1]; ! 612: ps.want_blank = true; ! 613: break; ! 614: ! 615: case question: /* got a ? */ ! 616: squest++; /* this will be used when a later colon ! 617: * appears so we can distinguish the ! 618: * <c>?<n>:<n> construct */ ! 619: if (ps.want_blank) ! 620: *e_code++ = ' '; ! 621: *e_code++ = '?'; ! 622: ps.want_blank = true; ! 623: break; ! 624: ! 625: case casestmt: /* got word 'case' or 'default' */ ! 626: scase = true; /* so we can process the later colon properly */ ! 627: goto copy_id; ! 628: ! 629: case colon: /* got a ':' */ ! 630: if (squest > 0) { /* it is part of the <c>?<n>: <n> construct */ ! 631: --squest; ! 632: if (ps.want_blank) ! 633: *e_code++ = ' '; ! 634: *e_code++ = ':'; ! 635: ps.want_blank = true; ! 636: break; ! 637: } ! 638: if (ps.in_decl) { ! 639: *e_code++ = ':'; ! 640: ps.want_blank = false; ! 641: break; ! 642: } ! 643: ps.in_stmt = false; /* seeing a label does not imply we are in a ! 644: * stmt */ ! 645: for (t_ptr = s_code; *t_ptr; ++t_ptr) ! 646: *e_lab++ = *t_ptr; /* turn everything so far into a label */ ! 647: e_code = s_code; ! 648: *e_lab++ = ':'; ! 649: *e_lab++ = ' '; ! 650: *e_lab = '\0'; ! 651: ! 652: force_nl = ps.pcase = scase; /* ps.pcase will be used by ! 653: * dump_line to decide how to ! 654: * indent the label. force_nl ! 655: * will force a case n: to be ! 656: * on a line by itself */ ! 657: scase = false; ! 658: ps.want_blank = false; ! 659: break; ! 660: ! 661: case semicolon: /* got a ';' */ ! 662: ps.in_or_st = false;/* we are not in an initialization or ! 663: * structure declaration */ ! 664: scase = false; /* these will only need resetting in a error */ ! 665: squest = 0; ! 666: if (ps.last_token == rparen && rparen_count == 0) ! 667: ps.in_parameter_declaration = 0; ! 668: ps.cast_mask = 0; ! 669: ps.sizeof_mask = 0; ! 670: ps.block_init = 0; ! 671: ps.block_init_level = 0; ! 672: ps.just_saw_decl--; ! 673: ! 674: if (ps.in_decl && s_code == e_code && !ps.block_init) ! 675: while ((e_code - s_code) < (dec_ind - 1)) { ! 676: CHECK_SIZE_CODE; ! 677: *e_code++ = ' '; ! 678: } ! 679: ! 680: ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level ! 681: * structure declaration, we ! 682: * arent any more */ ! 683: ! 684: if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0) { ! 685: ! 686: /* ! 687: * This should be true iff there were unbalanced parens in the ! 688: * stmt. It is a bit complicated, because the semicolon might ! 689: * be in a for stmt ! 690: */ ! 691: diag(1, "Unbalanced parens"); ! 692: ps.p_l_follow = 0; ! 693: if (sp_sw) { /* this is a check for a if, while, etc. with ! 694: * unbalanced parens */ ! 695: sp_sw = false; ! 696: parse(hd_type); /* dont lose the if, or whatever */ ! 697: } ! 698: } ! 699: *e_code++ = ';'; ! 700: ps.want_blank = true; ! 701: ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the ! 702: * middle of a stmt */ ! 703: ! 704: if (!sp_sw) { /* if not if for (;;) */ ! 705: parse(semicolon); /* let parser know about end of stmt */ ! 706: force_nl = true;/* force newline after a end of stmt */ ! 707: } ! 708: break; ! 709: ! 710: case lbrace: /* got a '{' */ ! 711: ps.in_stmt = false; /* dont indent the {} */ ! 712: if (!ps.block_init) ! 713: force_nl = true;/* force other stuff on same line as '{' onto ! 714: * new line */ ! 715: else if (ps.block_init_level <= 0) ! 716: ps.block_init_level = 1; ! 717: else ! 718: ps.block_init_level++; ! 719: ! 720: if (s_code != e_code && !ps.block_init) { ! 721: if (!btype_2) { ! 722: dump_line(); ! 723: ps.want_blank = false; ! 724: } ! 725: else if (ps.in_parameter_declaration && !ps.in_or_st) { ! 726: ps.i_l_follow = 0; ! 727: dump_line(); ! 728: ps.want_blank = false; ! 729: } ! 730: } ! 731: if (ps.in_parameter_declaration) ! 732: prefix_blankline_requested = 0; ! 733: ! 734: if (ps.p_l_follow > 0) { /* check for preceeding unbalanced ! 735: * parens */ ! 736: diag(1, "Unbalanced parens"); ! 737: ps.p_l_follow = 0; ! 738: if (sp_sw) { /* check for unclosed if, for, etc. */ ! 739: sp_sw = false; ! 740: parse(hd_type); ! 741: ps.ind_level = ps.i_l_follow; ! 742: } ! 743: } ! 744: if (s_code == e_code) ! 745: ps.ind_stmt = false; /* dont put extra indentation on line ! 746: * with '{' */ ! 747: if (ps.in_decl && ps.in_or_st) { /* this is either a structure ! 748: * declaration or an init */ ! 749: di_stack[ps.dec_nest++] = dec_ind; ! 750: /* ? dec_ind = 0; */ ! 751: } ! 752: else { ! 753: ps.decl_on_line = false; /* we cant be in the middle of ! 754: * a declaration, so dont do ! 755: * special indentation of ! 756: * comments */ ! 757: if (blanklines_after_declarations_at_proctop ! 758: && ps.in_parameter_declaration) ! 759: postfix_blankline_requested = 1; ! 760: ps.in_parameter_declaration = 0; ! 761: } ! 762: dec_ind = 0; ! 763: parse(lbrace); /* let parser know about this */ ! 764: if (ps.want_blank) /* put a blank before '{' if '{' is not at ! 765: * start of line */ ! 766: *e_code++ = ' '; ! 767: ps.want_blank = false; ! 768: *e_code++ = '{'; ! 769: ps.just_saw_decl = 0; ! 770: break; ! 771: ! 772: case rbrace: /* got a '}' */ ! 773: if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be ! 774: * omitted in ! 775: * declarations */ ! 776: parse(semicolon); ! 777: if (ps.p_l_follow) {/* check for unclosed if, for, else. */ ! 778: diag(1, "Unbalanced parens"); ! 779: ps.p_l_follow = 0; ! 780: sp_sw = false; ! 781: } ! 782: ps.just_saw_decl = 0; ! 783: ps.block_init_level--; ! 784: if (s_code != e_code && !ps.block_init) { /* '}' must be first on ! 785: * line */ ! 786: if (verbose) ! 787: diag(0, "Line broken"); ! 788: dump_line(); ! 789: } ! 790: *e_code++ = '}'; ! 791: ps.want_blank = true; ! 792: ps.in_stmt = ps.ind_stmt = false; ! 793: if (ps.dec_nest > 0) { /* we are in multi-level structure ! 794: * declaration */ ! 795: dec_ind = di_stack[--ps.dec_nest]; ! 796: if (ps.dec_nest == 0 && !ps.in_parameter_declaration) ! 797: ps.just_saw_decl = 2; ! 798: ps.in_decl = true; ! 799: } ! 800: prefix_blankline_requested = 0; ! 801: parse(rbrace); /* let parser know about this */ ! 802: ps.search_brace = cuddle_else && ps.p_stack[ps.tos] == ifhead ! 803: && ps.il[ps.tos] >= ps.ind_level; ! 804: if (ps.tos <= 1 && blanklines_after_procs && ps.dec_nest <= 0) ! 805: postfix_blankline_requested = 1; ! 806: break; ! 807: ! 808: case swstmt: /* got keyword "switch" */ ! 809: sp_sw = true; ! 810: hd_type = swstmt; /* keep this for when we have seen the ! 811: * expression */ ! 812: goto copy_id; /* go move the token into buffer */ ! 813: ! 814: case sp_paren: /* token is if, while, for */ ! 815: sp_sw = true; /* the interesting stuff is done after the ! 816: * expression is scanned */ ! 817: hd_type = (*token == 'i' ? ifstmt : ! 818: (*token == 'w' ? whilestmt : forstmt)); ! 819: ! 820: /* ! 821: * remember the type of header for later use by parser ! 822: */ ! 823: goto copy_id; /* copy the token into line */ ! 824: ! 825: case sp_nparen: /* got else, do */ ! 826: ps.in_stmt = false; ! 827: if (*token == 'e') { ! 828: if (e_code != s_code && (!cuddle_else || e_code[-1] != '}')) { ! 829: if (verbose) ! 830: diag(0, "Line broken"); ! 831: dump_line();/* make sure this starts a line */ ! 832: ps.want_blank = false; ! 833: } ! 834: force_nl = true;/* also, following stuff must go onto new line */ ! 835: last_else = 1; ! 836: parse(elselit); ! 837: } ! 838: else { ! 839: if (e_code != s_code) { /* make sure this starts a line */ ! 840: if (verbose) ! 841: diag(0, "Line broken"); ! 842: dump_line(); ! 843: ps.want_blank = false; ! 844: } ! 845: force_nl = true;/* also, following stuff must go onto new line */ ! 846: last_else = 0; ! 847: parse(dolit); ! 848: } ! 849: goto copy_id; /* move the token into line */ ! 850: ! 851: case decl: /* we have a declaration type (int, register, ! 852: * etc.) */ ! 853: parse(decl); /* let parser worry about indentation */ ! 854: if (ps.last_token == rparen && ps.tos <= 1) { ! 855: ps.in_parameter_declaration = 1; ! 856: if (s_code != e_code) { ! 857: dump_line(); ! 858: ps.want_blank = 0; ! 859: } ! 860: } ! 861: if (ps.in_parameter_declaration && ps.indent_parameters && ps.dec_nest == 0) { ! 862: ps.ind_level = ps.i_l_follow = 1; ! 863: ps.ind_stmt = 0; ! 864: } ! 865: ps.in_or_st = true; /* this might be a structure or initialization ! 866: * declaration */ ! 867: ps.in_decl = ps.decl_on_line = true; ! 868: if ( /* !ps.in_or_st && */ ps.dec_nest <= 0) ! 869: ps.just_saw_decl = 2; ! 870: prefix_blankline_requested = 0; ! 871: for (i = 0; token[i++];); /* get length of token */ ! 872: ! 873: /* ! 874: * dec_ind = e_code - s_code + (ps.decl_indent>i ? ps.decl_indent ! 875: * : i); ! 876: */ ! 877: dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i; ! 878: goto copy_id; ! 879: ! 880: case ident: /* got an identifier or constant */ ! 881: if (ps.in_decl) { /* if we are in a declaration, we must indent ! 882: * identifier */ ! 883: if (ps.want_blank) ! 884: *e_code++ = ' '; ! 885: ps.want_blank = false; ! 886: if (is_procname == 0 || !procnames_start_line) { ! 887: if (!ps.block_init) ! 888: if (troff && !ps.dumped_decl_indent) { ! 889: sprintf(e_code, "\n.De %dp+\200p\n", dec_ind * 7); ! 890: ps.dumped_decl_indent = 1; ! 891: e_code += strlen(e_code); ! 892: } ! 893: else ! 894: while ((e_code - s_code) < dec_ind) { ! 895: CHECK_SIZE_CODE; ! 896: *e_code++ = ' '; ! 897: } ! 898: } ! 899: else { ! 900: if (dec_ind && s_code != e_code) ! 901: dump_line(); ! 902: dec_ind = 0; ! 903: ps.want_blank = false; ! 904: } ! 905: } ! 906: else if (sp_sw && ps.p_l_follow == 0) { ! 907: sp_sw = false; ! 908: force_nl = true; ! 909: ps.last_u_d = true; ! 910: ps.in_stmt = false; ! 911: parse(hd_type); ! 912: } ! 913: copy_id: ! 914: if (ps.want_blank) ! 915: *e_code++ = ' '; ! 916: if (troff && ps.its_a_keyword) { ! 917: e_code = chfont(&bodyf, &keywordf, e_code); ! 918: for (t_ptr = token; *t_ptr; ++t_ptr) { ! 919: CHECK_SIZE_CODE; ! 920: *e_code++ = keywordf.allcaps && islower(*t_ptr) ! 921: ? toupper(*t_ptr) : *t_ptr; ! 922: } ! 923: e_code = chfont(&keywordf, &bodyf, e_code); ! 924: } ! 925: else ! 926: for (t_ptr = token; *t_ptr; ++t_ptr) { ! 927: CHECK_SIZE_CODE; ! 928: *e_code++ = *t_ptr; ! 929: } ! 930: ps.want_blank = true; ! 931: break; ! 932: ! 933: case period: /* treat a period kind of like a binary ! 934: * operation */ ! 935: *e_code++ = '.'; /* move the period into line */ ! 936: ps.want_blank = false; /* dont put a blank after a period */ ! 937: break; ! 938: ! 939: case comma: ! 940: ps.want_blank = (s_code != e_code); /* only put blank after comma ! 941: * if comma does not start the ! 942: * line */ ! 943: if (ps.in_decl && is_procname == 0 && !ps.block_init) ! 944: while ((e_code - s_code) < (dec_ind - 1)) { ! 945: CHECK_SIZE_CODE; ! 946: *e_code++ = ' '; ! 947: } ! 948: ! 949: *e_code++ = ','; ! 950: if (ps.p_l_follow == 0) { ! 951: if (ps.block_init_level <= 0) ! 952: ps.block_init = 0; ! 953: if (break_comma && (!ps.leave_comma || compute_code_target() + (e_code - s_code) > max_col - 8)) ! 954: force_nl = true; ! 955: } ! 956: break; ! 957: ! 958: case preesc: /* got the character '#' */ ! 959: if ((s_com != e_com) || ! 960: (s_lab != e_lab) || ! 961: (s_code != e_code)) ! 962: dump_line(); ! 963: *e_lab++ = '#'; /* move whole line to 'label' buffer */ ! 964: { ! 965: int in_comment = 0; ! 966: int com_start = 0; ! 967: char quote = 0; ! 968: int com_end = 0; ! 969: ! 970: while (*buf_ptr == ' ' || *buf_ptr == '\t') { ! 971: buf_ptr++; ! 972: if (buf_ptr >= buf_end) ! 973: fill_buffer(); ! 974: } ! 975: while (*buf_ptr != '\n' || in_comment) { ! 976: CHECK_SIZE_LAB; ! 977: *e_lab = *buf_ptr++; ! 978: if (buf_ptr >= buf_end) ! 979: fill_buffer(); ! 980: switch (*e_lab++) { ! 981: case BACKSLASH: ! 982: if (troff) ! 983: *e_lab++ = BACKSLASH; ! 984: if (!in_comment) { ! 985: *e_lab++ = *buf_ptr++; ! 986: if (buf_ptr >= buf_end) ! 987: fill_buffer(); ! 988: } ! 989: break; ! 990: case '/': ! 991: if (*buf_ptr == '*' && !in_comment && !quote) { ! 992: in_comment = 1; ! 993: *e_lab++ = *buf_ptr++; ! 994: com_start = e_lab - s_lab - 2; ! 995: } ! 996: break; ! 997: case '"': ! 998: if (quote == '"') ! 999: quote = 0; ! 1000: break; ! 1001: case '\'': ! 1002: if (quote == '\'') ! 1003: quote = 0; ! 1004: break; ! 1005: case '*': ! 1006: if (*buf_ptr == '/' && in_comment) { ! 1007: in_comment = 0; ! 1008: *e_lab++ = *buf_ptr++; ! 1009: com_end = e_lab - s_lab; ! 1010: } ! 1011: break; ! 1012: } ! 1013: } ! 1014: ! 1015: while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) ! 1016: e_lab--; ! 1017: if (e_lab - s_lab == com_end && bp_save == 0) { /* comment on ! 1018: * preprocessor line */ ! 1019: if (sc_end == 0) /* if this is the first comment, we ! 1020: * must set up the buffer */ ! 1021: sc_end = &(save_com[0]); ! 1022: else { ! 1023: *sc_end++ = '\n'; /* add newline between ! 1024: * comments */ ! 1025: *sc_end++ = ' '; ! 1026: --line_no; ! 1027: } ! 1028: bcopy(s_lab + com_start, sc_end, com_end - com_start); ! 1029: sc_end += com_end - com_start; ! 1030: if (sc_end >= &save_com[sc_size]) ! 1031: abort(); ! 1032: e_lab = s_lab + com_start; ! 1033: while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) ! 1034: e_lab--; ! 1035: bp_save = buf_ptr; /* save current input buffer */ ! 1036: be_save = buf_end; ! 1037: buf_ptr = save_com; /* fix so that subsequent calls to ! 1038: * lexi will take tokens out of ! 1039: * save_com */ ! 1040: *sc_end++ = ' '; /* add trailing blank, just in case */ ! 1041: buf_end = sc_end; ! 1042: sc_end = 0; ! 1043: } ! 1044: *e_lab = '\0'; /* null terminate line */ ! 1045: ps.pcase = false; ! 1046: } ! 1047: ! 1048: if (strncmp(s_lab, "#if", 3) == 0) { ! 1049: if (blanklines_around_conditional_compilation) { ! 1050: register c; ! 1051: prefix_blankline_requested++; ! 1052: while ((c = getc(input)) == '\n'); ! 1053: ungetc(c, input); ! 1054: } ! 1055: if (ifdef_level < sizeof state_stack / sizeof state_stack[0]) { ! 1056: match_state[ifdef_level].tos = -1; ! 1057: state_stack[ifdef_level++] = ps; ! 1058: } ! 1059: else ! 1060: diag(1, "#if stack overflow"); ! 1061: } ! 1062: else if (strncmp(s_lab, "#else", 5) == 0) ! 1063: if (ifdef_level <= 0) ! 1064: diag(1, "Unmatched #else"); ! 1065: else { ! 1066: match_state[ifdef_level - 1] = ps; ! 1067: ps = state_stack[ifdef_level - 1]; ! 1068: } ! 1069: else if (strncmp(s_lab, "#endif", 6) == 0) { ! 1070: if (ifdef_level <= 0) ! 1071: diag(1, "Unmatched #endif"); ! 1072: else { ! 1073: ifdef_level--; ! 1074: ! 1075: #ifdef undef ! 1076: /* ! 1077: * This match needs to be more intelligent before the ! 1078: * message is useful ! 1079: */ ! 1080: if (match_state[ifdef_level].tos >= 0 ! 1081: && bcmp(&ps, &match_state[ifdef_level], sizeof ps)) ! 1082: diag(0, "Syntactically inconsistant #ifdef alternatives."); ! 1083: #endif ! 1084: } ! 1085: if (blanklines_around_conditional_compilation) { ! 1086: postfix_blankline_requested++; ! 1087: n_real_blanklines = 0; ! 1088: } ! 1089: } ! 1090: break; /* subsequent processing of the newline ! 1091: * character will cause the line to be printed */ ! 1092: ! 1093: case comment: /* we have gotten a /* this is a biggie */ ! 1094: if (flushed_nl) { /* we should force a broken line here */ ! 1095: flushed_nl = false; ! 1096: dump_line(); ! 1097: ps.want_blank = false; /* dont insert blank at line start */ ! 1098: force_nl = false; ! 1099: } ! 1100: pr_comment(); ! 1101: break; ! 1102: } /* end of big switch stmt */ ! 1103: ! 1104: *e_code = '\0'; /* make sure code section is null terminated */ ! 1105: if (type_code != comment && type_code != newline && type_code != preesc) ! 1106: ps.last_token = type_code; ! 1107: } /* end of main while (1) loop */ ! 1108: } ! 1109: ! 1110: /* ! 1111: * copy input file to backup file if in_name is /blah/blah/blah/file, then ! 1112: * backup file will be ".Bfile" then make the backup file the input and ! 1113: * original input file the output ! 1114: */ ! 1115: bakcopy() ! 1116: { ! 1117: int n, ! 1118: bakchn; ! 1119: char buff[8 * 1024]; ! 1120: register char *p; ! 1121: ! 1122: /* construct file name .Bfile */ ! 1123: for (p = in_name; *p; p++); /* skip to end of string */ ! 1124: while (p > in_name && *p != '/') /* find last '/' */ ! 1125: p--; ! 1126: if (*p == '/') ! 1127: p++; ! 1128: sprintf(bakfile, "%s.BAK", p); ! 1129: ! 1130: /* copy in_name to backup file */ ! 1131: bakchn = creat(bakfile, 0600); ! 1132: if (bakchn < 0) ! 1133: err(bakfile); ! 1134: while (n = read(fileno(input), buff, sizeof buff)) ! 1135: if (write(bakchn, buff, n) != n) ! 1136: err(bakfile); ! 1137: if (n < 0) ! 1138: err(in_name); ! 1139: close(bakchn); ! 1140: fclose(input); ! 1141: ! 1142: /* re-open backup file as the input file */ ! 1143: input = fopen(bakfile, "r"); ! 1144: if (input == 0) ! 1145: err(bakfile); ! 1146: /* now the original input file will be the output */ ! 1147: output = fopen(in_name, "w"); ! 1148: if (output == 0) { ! 1149: unlink(bakfile); ! 1150: err(in_name); ! 1151: } ! 1152: } ! 1153: ! 1154: err(msg) ! 1155: char *msg; ! 1156: { ! 1157: extern int errno; ! 1158: char *strerror(); ! 1159: ! 1160: (void)fprintf(stderr, "indent: %s: %s\n", msg, strerror(errno)); ! 1161: exit(1); ! 1162: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.