|
|
1.1 ! root 1: static char sccsid[] = "@(#)indent.c 4.1 (Berkeley) 10/21/82"; ! 2: ! 3: /* ! 4: ! 5: Copyright (C) 1976 ! 6: by the ! 7: Board of Trustees ! 8: of the ! 9: University of Illinois ! 10: ! 11: All rights reserved ! 12: ! 13: ! 14: NAME: ! 15: indent main program ! 16: ! 17: FUNCTION: ! 18: This is the main program of the indent program. Indent will take a C ! 19: program source and reformat it into a semi-reasonable form. ! 20: ! 21: ALGORITHM: ! 22: The routine lexi scans tokens and passes them back one at a time to the ! 23: main routine. The subroutine parse takes care of much of the work of ! 24: figuring indentation level. ! 25: ! 26: 1) Call lexi ! 27: 2) Enter a monster switch statement on the code returned by lexi. If ! 28: the indentation level for the line yet to be printed should be ! 29: changed, set the variable ind_level. If the indentation level for ! 30: the following line should be changed, set the variable i_l_follow. ! 31: ! 32: PARAMETERS: ! 33: None ! 34: ! 35: RETURNS: ! 36: Nothing ! 37: ! 38: GLOBALS: ! 39: be_save = ! 40: break_comma ! 41: bp_save = ! 42: btype_2 = ! 43: code_lines ! 44: com_ind = ! 45: com_lines ! 46: dec_nest = ! 47: decl_com_ind = ! 48: decl_on_line = ! 49: i_l_follow = ! 50: in_decl = ! 51: ind_level = ! 52: ind_size = ! 53: ind_stmt = ! 54: last_u_d = ! 55: leave_comma = ! 56: line_no = ! 57: ljust_decl = ! 58: max_col = ! 59: out_coms ! 60: out_lines ! 61: p_l_follow = ! 62: paren_level = ! 63: pcase = ! 64: sc_end = ! 65: unindent_displace = ! 66: use_ff = ! 67: verbose = ! 68: ! 69: CALLS: ! 70: atoi (lib) ! 71: cmp ! 72: creat (lib) ! 73: dump_line ! 74: eqin ! 75: fill_buffer ! 76: lexi ! 77: open (lib) ! 78: parse ! 79: pr_comment ! 80: printf (lib) ! 81: seek (lib) ! 82: time (lib) ! 83: ! 84: CALLED BY: ! 85: No one (main routine) ! 86: ! 87: HISTORY: ! 88: November 1976 D A Willcox of CAC Initial coding ! 89: 12/9/76 D A Willcox of CAC Fixed defaults for decl_com_ind ! 90: to be 8 less than com_ind if ! 91: left justifying declarations ! 92: 12/9/76 D A Willcox of CAC Fixed processing of nested ! 93: <c>?<s>:<s> constructs ! 94: 1/7/77 D A Willcox of CAC Added check for overwrite of ! 95: input file ! 96: Added code to handle -br and -bl ! 97: parameters ! 98: */ ! 99: #include "indent_globs.h"; ! 100: #include "indent_codes.h"; ! 101: ! 102: /* #define dolog 1 /* if this define is removed, then the code to ! 103: produce a log file will be removed */ ! 104: ! 105: struct templ { /* this is a template for the list of ! 106: command line args */ ! 107: char *str; /* pointer to string which is a valid ! 108: command line arg */ ! 109: int code; /* code to be used in switch for processing ! 110: this arg */ ! 111: }; ! 112: ! 113: ! 114: struct templ options[] = ! 115: { /* warning - because of the way that this ! 116: table is scanned, if one entry is an ! 117: initial substring of another, then the ! 118: longer entry should occur first */ ! 119: "-cd", 4, ! 120: "-c", 2, ! 121: "-l", 1, ! 122: "-i", 3, ! 123: "-v", 5, ! 124: "-nv", 6, ! 125: "-dj", 7, ! 126: "-d", 13, /* unindented comment placement */ ! 127: "-ndj", 8, ! 128: "-bc", 10, /* break after command in decl */ ! 129: "-nbc", 9, /* don't break after comma */ ! 130: "-br", 14, /* put brace on right of stmt */ ! 131: "-bl", 15, /* put brace on left by itself */ ! 132: "-st", 16, /* use the standard input and output ! 133: files */ ! 134: 0, 0 ! 135: }; ! 136: ! 137: ! 138: char *in_name = "Standard Input"; ! 139: /* will always point to name of input file ! 140: */ ! 141: char *out_name = "Standard Output"; ! 142: /* will always point to name of output file ! 143: */ ! 144: char bakfile[32] = ""; ! 145: ! 146: main (argc, argv) ! 147: int argc; ! 148: char **argv; ! 149: { ! 150: ! 151: int dec_ind; /* current indentation for declarations */ ! 152: int di_stack[20]; /* a stack of structure indentation levels ! 153: */ ! 154: int flushed_nl; /* used when buffering up comments to ! 155: remember that a newline was passed over ! 156: */ ! 157: int force_nl; /* when true, code must be broken */ ! 158: int hd_type; /* used to store type of stmt for if (...), ! 159: for (...), etc */ ! 160: register int i; /* local loop counter */ ! 161: int in_or_st; /* Will be true iff there has been a ! 162: declarator (e.g. int or char) and no ! 163: left paren since the last semicolon. ! 164: When true, a { is starting a structure ! 165: definition or an initialization list */ ! 166: register int j; /* local loop counter */ ! 167: int scase; /* set to true when we see a case, so we ! 168: will know what to do with the following ! 169: colon */ ! 170: int sp_sw; /* when true, we are in the expressin of ! 171: if(...), while(...), etc. */ ! 172: int squest; /* when this is positive, we have seen a ? ! 173: without the matching : in a <c>?<s>:<s> ! 174: construct */ ! 175: register char *t_ptr; /* used for copying tokens */ ! 176: int type_code; /* the type of token, returned by lexi */ ! 177: int want_blank; /* set to true when the following token ! 178: should be prefixed by a blank. (Said ! 179: prefixing is ignored in some cases.) */ ! 180: ! 181: #ifdef dolog /* include declarations needed for log */ ! 182: int log_fid; /* fid of log file */ ! 183: ! 184: struct logtmpl { /* structure of a log entry */ ! 185: int tvec[2]; /* time of execution */ ! 186: char inp; /* input fid */ ! 187: char outp; /* output fid */ ! 188: int nout; /* # output lines */ ! 189: int ncom; /* # comments */ ! 190: int wcom; /* # lines w/ comments */ ! 191: int wcode; /* # lines w/code */ ! 192: char mc; /* max line size */ ! 193: char ci; /* comment indentation */ ! 194: char inds; /* indent size */ ! 195: char dci; /* decl comment indentation */ ! 196: char verb; /* verbose */ ! 197: char ljus; /* left just */ ! 198: char lvcom; /* leave commas */ ! 199: char unin; /* unindented comment indentation */ ! 200: char uid; /* the user id */ ! 201: char bropt; /* btype_2 */ ! 202: int reserved[2]; ! 203: }; ! 204: ! 205: struct logtmpl logent; ! 206: #endif ! 207: ! 208: /*-----------------------------------------------*\ ! 209: | INITIALIZATION ! 210: \*-----------------------------------------------*/ ! 211: ! 212: ! 213: combuf[0] = codebuf[0] = labbuf[0] = ' '; ! 214: /* set up code, label, and comment buffers */ ! 215: combuf[1] = codebuf[1] = labbuf[1] = '\0'; ! 216: s_lab = e_lab = labbuf + 1; ! 217: s_code = e_code = codebuf + 1; ! 218: s_com = e_com = combuf + 1; ! 219: ! 220: buf_ptr = buf_end = in_buffer; ! 221: line_no = 1; ! 222: had_eof = in_decl = decl_on_line = break_comma = false; ! 223: sp_sw = force_nl = false; ! 224: in_or_st = false; ! 225: bl_line = true; ! 226: dec_ind = 0; ! 227: di_stack[dec_nest = 0] = 0; ! 228: want_blank = in_stmt = ind_stmt = false; ! 229: ! 230: ! 231: scase = pcase = false; ! 232: squest = 0; ! 233: sc_end = 0; ! 234: bp_save = 0; ! 235: be_save = 0; ! 236: ! 237: input = -1; ! 238: output = -1; ! 239: ljust_decl = d_ljust; ! 240: ! 241: ! 242: ! 243: /*--------------------------------------------------*\ ! 244: | COMMAND LINE SCAN ! 245: \*--------------------------------------------------*/ ! 246: ! 247: max_col = d_max_col; /* set up some default values */ ! 248: com_ind = d_com_ind; ! 249: ind_size = d_ind_size; ! 250: verbose = d_verbose; ! 251: decl_com_ind = 0; /* if this is not set to some positive ! 252: value by an arg, we will set this equal ! 253: to com_ind */ ! 254: btype_2 = d_btype_2; ! 255: unindent_displace = d_unindent; ! 256: leave_comma = d_leave_comma; ! 257: ! 258: set_profile (); ! 259: ! 260: for (i = 1; i < argc; ++i) { ! 261: /* look thru args (if any) for changes to defaults */ ! 262: if (argv[i][0] != '-') {/* no flag on parameter */ ! 263: if (input < 0) { /* we must have the input file */ ! 264: in_name = argv[i]; /* remember name of input ! 265: file */ ! 266: input = open (in_name, 0); ! 267: if (input < 0) { /* check for open error */ ! 268: printf ("Can't open %s\n", argv[i]); ! 269: exit (); ! 270: } ! 271: continue; ! 272: } ! 273: else ! 274: if (output < 0) { /* we have the output file */ ! 275: out_name = argv[i]; /* remember name of output file */ ! 276: if (cmp (in_name, out_name) == 0) { /* attempt to ! 277: overwright the file */ ! 278: printf ("Input and output files must be different\n"); ! 279: exit (); ! 280: } ! 281: output = creat (out_name, 0644); ! 282: if (output < 0) { /* check for create error */ ! 283: printf ("Can't create %s\n", argv[i]); ! 284: exit (); ! 285: } ! 286: continue; ! 287: } ! 288: ! 289: printf ("Unknown parameter: %s\n", argv[i]); ! 290: exit (); ! 291: } ! 292: else ! 293: set_option (argv[i]); ! 294: ! 295: } /* end of for */ ! 296: ! 297: if (input < 0) { ! 298: printf ("Usage: indent file [ outfile ] [ options ]\n"); ! 299: exit (); ! 300: } ! 301: if (output < 0) { ! 302: out_name = in_name; ! 303: bakcopy (); ! 304: } ! 305: ! 306: if (com_ind <= 1) ! 307: com_ind = 2; /* don't put normal comments before column ! 308: 2 */ ! 309: ! 310: if (decl_com_ind <= 0) /* if not specified by user, set this */ ! 311: decl_com_ind = ljust_decl ? (com_ind <= 10 ? 2 : com_ind - 8) : com_ind; ! 312: ! 313: fill_buffer (); /* get first batch of stuff into input ! 314: buffer */ ! 315: ! 316: parse (semicolon); ! 317: /*----------------------------------------------------- ! 318: | START OF MAIN LOOP ! 319: \*----------------------------------------------------*/ ! 320: ! 321: while (1) { /* this is the main loop. it will go until ! 322: we reach eof */ ! 323: type_code = lexi (); /* lexi reads one token. The actual ! 324: characters read are stored in "token". ! 325: lexi returns a code indicating the type ! 326: of token */ ! 327: ! 328: /* ! 329: * The following code moves everything following an if (), while (), ! 330: * else, etc. up to the start of the following stmt to a buffer. This ! 331: * allows proper handling of both kinds of brace placement. ! 332: */ ! 333: ! 334: flushed_nl = false; ! 335: while (search_brace) { /* if we scanned an if(), while(), etc., we ! 336: might need to copy stuff into a buffer ! 337: *//* we must loop, copying stuff into save_com, until we find the ! 338: start of the stmt which follows the if, or whatever */ ! 339: switch (type_code) { ! 340: case newline: ! 341: ++line_no; ! 342: flushed_nl = true; ! 343: case form_feed: ! 344: break; /* form feeds and newlines found here will ! 345: be ignored */ ! 346: ! 347: case lbrace: /* this is a brace that starts the compound ! 348: stmt */ ! 349: if (sc_end == 0) { ! 350: /* ignore buffering if a comment wasn't stored up */ ! 351: search_brace = false; ! 352: goto check_type; ! 353: } ! 354: ! 355: if (btype_2) { ! 356: save_com[0] = '{'; ! 357: /* we either want to put the brace right after the if ! 358: */ ! 359: goto sw_buffer; ! 360: /* go to common code to get out of this loop */ ! 361: } ! 362: ! 363: default: /* it is the start of a normal statment */ ! 364: if (flushed_nl) ! 365: /* if we flushed a newline, make sure it is ! 366: put back */ ! 367: force_nl = true; ! 368: ! 369: if (sc_end == 0) { ! 370: /* ignore buffering if comment wasn't saved up */ ! 371: search_brace = false; ! 372: goto check_type; ! 373: } ! 374: ! 375: if (force_nl) { ! 376: /* if we should insert a nl here, put it into the ! 377: buffer */ ! 378: force_nl = false; ! 379: --line_no; ! 380: /* this will be re-increased when the nl is read from ! 381: the buffer */ ! 382: *sc_end++ = '\n'; ! 383: *sc_end++ = ' '; ! 384: if (verbose && !flushed_nl) ! 385: /* print error msg if the line was not ! 386: already broken */ ! 387: printf ("%d: Line broken\n", line_no); ! 388: flushed_nl = false; ! 389: } ! 390: ! 391: for (t_ptr = token; *t_ptr; ++t_ptr) ! 392: *sc_end++ = *t_ptr; ! 393: /* copy token into temp buffer */ ! 394: ! 395: sw_buffer: ! 396: search_brace = false; ! 397: /* stop looking for start of stmt */ ! 398: bp_save = buf_ptr; ! 399: /* save current input buffer */ ! 400: be_save = buf_end; ! 401: buf_ptr = save_com; ! 402: /* fix so that subsequent calls to lexi will take tokens ! 403: out of save_com */ ! 404: *sc_end++ = ' '; ! 405: /* add trailing blank, just in case */ ! 406: buf_end = sc_end; ! 407: sc_end = 0; ! 408: break; ! 409: ! 410: case comment: /* we have a comment, so we must copy it ! 411: into the buffer */ ! 412: if (sc_end == 0) { ! 413: /* if this is the first comment, we must set up the ! 414: buffer */ ! 415: save_com[0] = save_com[1] = ' '; ! 416: sc_end = &(save_com[2]); ! 417: } ! 418: else { ! 419: *sc_end++ = '\n'; ! 420: /* add newline between comments */ ! 421: *sc_end++ = ' '; ! 422: --line_no; ! 423: } ! 424: ! 425: *sc_end++ = '/'; ! 426: /* copy in start of comment */ ! 427: *sc_end++ = '*'; ! 428: ! 429: for (;;) { /* loop until we get to the end of the ! 430: comment */ ! 431: *sc_end = *buf_ptr++; ! 432: if (buf_ptr >= buf_end) ! 433: fill_buffer (); ! 434: ! 435: if (*sc_end++ == '*' && *buf_ptr == '/') ! 436: break; ! 437: /* we are at end of comment */ ! 438: ! 439: if (sc_end >= &(save_com[sc_size])) { ! 440: /* check for temp buffer overflow */ ! 441: printf ("%d: Internal buffer overflow.\n", ! 442: line_no); ! 443: printf ("Move big comment from right after if,\ ! 444: while, or whatever.\n"); ! 445: exit (); ! 446: } ! 447: } ! 448: ! 449: *sc_end++ = '/'; ! 450: /* add ending slash */ ! 451: if (++buf_ptr >= buf_end)/* get past / in buffer */ ! 452: fill_buffer (); ! 453: break; ! 454: } /* end of switch */ ! 455: ! 456: if (type_code != 0)/* we must make this check, just in case ! 457: there was an unexpected EOF */ ! 458: type_code = lexi (); ! 459: /* read another token */ ! 460: } /* end of while (serach_brace) */ ! 461: check_type: ! 462: ! 463: if (type_code == 0) { /* we got eof */ ! 464: if (s_lab != e_lab || s_code != e_code ! 465: || s_com != e_com)/* must dump end of line */ ! 466: dump_line (); ! 467: if (i_l_follow != 0)/* check for balanced braces */ ! 468: printf ("%d too few }'s\n", i_l_follow); ! 469: ! 470: #ifdef dolog /* only include this stuff if we want to ! 471: keep a log */ ! 472: log_fid = open ("/mnt/net/willcox/indent/indent_log", 1); ! 473: /* open the log file */ ! 474: if (log_fid >= 0) { ! 475: seek (log_fid, 0, 2); ! 476: /* point to end of log */ ! 477: time (logent.tvec); ! 478: /* get current time */ ! 479: logent.inp = input; ! 480: /* set up the log entry */ ! 481: logent.outp = output; ! 482: logent.nout = out_lines; ! 483: logent.ncom = out_coms; ! 484: logent.wcom = com_lines; ! 485: logent.wcode = code_lines; ! 486: logent.mc = max_col; ! 487: logent.ci = com_ind; ! 488: logent.inds = ind_size; ! 489: logent.dci = decl_com_ind; ! 490: logent.verb = verbose; ! 491: logent.ljus = ljust_decl; ! 492: logent.lvcom = leave_comma; ! 493: logent.unin = unindent_displace; ! 494: logent.uid = getuid (); ! 495: logent.bropt = btype_2; ! 496: write (log_fid, &logent, sizeof logent); ! 497: } ! 498: #endif ! 499: if (verbose) { ! 500: printf ("There were %d output lines and %d comments\n", ! 501: out_lines, out_coms); ! 502: printf ("(Lines with comments)/(Lines with code): %6.3f\n", ! 503: (1.0 * com_lines) / code_lines); ! 504: } ! 505: ! 506: exit (); ! 507: } ! 508: ! 509: if ( ! 510: (type_code != comment) && ! 511: (type_code != newline) && ! 512: (type_code != preesc) && ! 513: (type_code != form_feed)) { ! 514: if ( ! 515: force_nl ! 516: && ! 517: (type_code != semicolon) && ! 518: ( ! 519: type_code != lbrace ! 520: || ! 521: !btype_2 ! 522: )) { /* we should force a broken line here */ ! 523: if (verbose && !flushed_nl) ! 524: printf ("%d: Line broken\n", line_no); ! 525: flushed_nl = false; ! 526: dump_line (); ! 527: want_blank = false; ! 528: /* don't insert blank at line start */ ! 529: force_nl = false; ! 530: } ! 531: ! 532: in_stmt = true; /* turn on flag which causes an extra level ! 533: of indentation. this is turned off by a ! 534: ; or } */ ! 535: if (s_com != e_com) { ! 536: /* the turkey has embedded a comment in a line. fix it */ ! 537: *e_code++ = ' '; ! 538: for (t_ptr = s_com; *t_ptr; ++t_ptr) ! 539: *e_code++ = *t_ptr; ! 540: *e_code++ = ' '; ! 541: *e_code = '\0';/* null terminate code sect */ ! 542: want_blank = false; ! 543: e_com = s_com; ! 544: } ! 545: } ! 546: else ! 547: if (type_code != comment) ! 548: /* preserve force_nl thru a comment */ ! 549: force_nl = false; ! 550: /* cancel forced newline after newline, form feed, etc */ ! 551: ! 552: ! 553: ! 554: /*----------------------------------------------------*\ ! 555: | do switch on type of token scanned ! 556: \*----------------------------------------------------*/ ! 557: switch (type_code) { /* now, decide what to do with the token */ ! 558: ! 559: case form_feed: /* found a form feed in line */ ! 560: use_ff = true; /* a form feed is treated much like a ! 561: newline */ ! 562: dump_line (); ! 563: want_blank = false; ! 564: break; ! 565: ! 566: case newline: ! 567: dump_line (); ! 568: ++line_no; /* keep track of input line number */ ! 569: want_blank = false; ! 570: break; ! 571: ! 572: case lparen: /* got a ( or [ */ ! 573: ++p_l_follow; /* count parens to make Healy happy */ ! 574: if (want_blank && *token != '[') ! 575: /* don't put space in front of square ! 576: bracket */ ! 577: *e_code++ = ' '; ! 578: ! 579: if (in_decl) ! 580: while ((e_code - s_code) < dec_ind) ! 581: *e_code++ = ' '; ! 582: ! 583: *e_code++ = token[0]; ! 584: want_blank = false; ! 585: if (in_or_st && *token == '(') { ! 586: /* this is a kluge to make sure that declarations will be ! 587: aaigned right if proc decl has an explicit type on it, ! 588: i.e. "int a(x) {..." */ ! 589: parse (semicolon); ! 590: /* I said this was a kluge... */ ! 591: in_or_st = false; ! 592: /* turn off flag for structure decl or initialization */ ! 593: } ! 594: ! 595: break; ! 596: ! 597: case rparen: /* got a ) or ] */ ! 598: if (--p_l_follow < 0) { ! 599: p_l_follow = 0; ! 600: printf ("%d: Extra %c\n", line_no, *token); ! 601: } ! 602: ! 603: if (e_code == s_code)/* if the paren starts the line */ ! 604: paren_level = p_l_follow; ! 605: /* then indent it */ ! 606: ! 607: *e_code++ = token[0]; ! 608: want_blank = true; ! 609: ! 610: if (sp_sw && (p_l_follow == 0)) { ! 611: /* check for end of if (...), or some such */ ! 612: sp_sw = false; ! 613: force_nl = true; ! 614: /* must force newline after if */ ! 615: last_u_d = true; ! 616: /* inform lexi that a following operator is unary */ ! 617: in_stmt = false; ! 618: /* don't use stmt continuation indentation */ ! 619: ! 620: parse (hd_type); ! 621: /* let parser worry about if, or whatever */ ! 622: } ! 623: ! 624: search_brace = btype_2; ! 625: /* this should insure that constructs such as main(){... and ! 626: int[]{... have their braces put in the right place */ ! 627: break; ! 628: ! 629: case unary_op: /* this could be any unary operation */ ! 630: if (want_blank) ! 631: *e_code++ = ' '; ! 632: ! 633: if (in_decl) { /* if this is a unary op in a *//* ! 634: declaration, we should indent this token ! 635: */ ! 636: for (i = 0; token[i]; ++i); ! 637: /* find length of token */ ! 638: while ((e_code - s_code) < (dec_ind - i)) ! 639: *e_code++ = ' '; ! 640: /* pad it */ ! 641: } ! 642: ! 643: for (t_ptr = token; *t_ptr; ++t_ptr) ! 644: *e_code++ = *t_ptr; ! 645: /* move the token to buffer */ ! 646: want_blank = false; ! 647: break; ! 648: ! 649: case binary_op: /* any binary operation */ ! 650: do_binary: ! 651: if (want_blank) ! 652: *e_code++ = ' '; ! 653: for (t_ptr = token; *t_ptr; ++t_ptr) ! 654: *e_code++ = *t_ptr; ! 655: /* move the operator */ ! 656: want_blank = true; ! 657: break; ! 658: ! 659: case postop: /* got a trailing ++ or -- */ ! 660: *e_code++ = token[0]; ! 661: *e_code++ = token[1]; ! 662: want_blank = true; ! 663: break; ! 664: ! 665: case question: /* got a ? */ ! 666: squest++; /* this will be used when a later colon ! 667: appears so we can distinguish the ! 668: <c>?<n>:<n> construct */ ! 669: if (want_blank) ! 670: *e_code++ = ' '; ! 671: *e_code++ = '?'; ! 672: want_blank = true; ! 673: break; ! 674: ! 675: case casestmt: /* got word 'case' or 'default' */ ! 676: scase = true; /* so we can process the later colon ! 677: properly */ ! 678: if (want_blank) ! 679: *e_code++ = ' '; ! 680: for (t_ptr = token; *t_ptr; ++t_ptr) ! 681: *e_code++ = *t_ptr; ! 682: want_blank = true; ! 683: break; ! 684: ! 685: case colon: /* got a ':' */ ! 686: if (squest > 0) { ! 687: /* it is part of the <c>?<n>: <n> construct */ ! 688: --squest; ! 689: if (want_blank) ! 690: *e_code++ = ' '; ! 691: *e_code++ = ':'; ! 692: want_blank = true; ! 693: break; ! 694: } ! 695: ! 696: in_stmt = false; ! 697: /* seeing a label does not imply we are in a stmt */ ! 698: for (t_ptr = s_code; *t_ptr; ++t_ptr) ! 699: *e_lab++ = *t_ptr; ! 700: /* turn everything so far into a label */ ! 701: e_code = s_code; ! 702: *e_lab++ = ':'; ! 703: *e_lab++ = ' '; ! 704: *e_lab = '\0'; ! 705: ! 706: force_nl = pcase = scase; ! 707: /* pcase will be used by dump_line to decide how to indent the ! 708: label. force_nl will force a case n: to be on a line by ! 709: itself */ ! 710: scase = false; ! 711: want_blank = false; ! 712: break; ! 713: ! 714: case semicolon: /* got a ';' */ ! 715: in_or_st = false; ! 716: /* we are not in an initialization or structure declaration */ ! 717: scase = false; /* these will only need resetting in a ! 718: error */ ! 719: squest = 0; ! 720: ! 721: if (in_decl && s_code == e_code) ! 722: /* align this in a declaration */ ! 723: while ((e_code - s_code) < (dec_ind - 1)) ! 724: *e_code++ = ' '; ! 725: ! 726: in_decl = (dec_nest > 0); ! 727: /* if we were in a first level structure declaration, we ! 728: aren't any more */ ! 729: ! 730: if ((!sp_sw || hd_type != forstmt) && p_l_follow > 0) { ! 731: /* This should be true iff there were unbalanced parens in ! 732: the stmt. It is a bit complicated, because the ! 733: semicolon might be in a for stmt */ ! 734: printf ("%d: Unbalanced parens\n", line_no); ! 735: p_l_follow = 0; ! 736: if (sp_sw) { ! 737: /* this is a check for a if, while, etc. with ! 738: unbalanced parens */ ! 739: sp_sw = false; ! 740: parse (hd_type); ! 741: /* don't lose the if, or whatever */ ! 742: } ! 743: } ! 744: ! 745: *e_code++ = ';'; ! 746: want_blank = true; ! 747: in_stmt = (p_l_follow > 0); ! 748: /* we are no longer in the middle of a stmt */ ! 749: ! 750: if (!sp_sw) { /* if not if for (;;) */ ! 751: parse (semicolon); ! 752: /* let parser know about end of stmt */ ! 753: force_nl = true; ! 754: /* force newline after a end of stmt */ ! 755: } ! 756: ! 757: break; ! 758: ! 759: case lbrace: /* got a { */ ! 760: in_stmt = false; ! 761: /* don't indent the { */ ! 762: force_nl = true; ! 763: /* force other stuff on same line as { onto new line */ ! 764: ! 765: if (s_code != e_code && !btype_2) { ! 766: /* bracket is not alone on line */ ! 767: if (verbose) ! 768: printf ("%d: Line broken\n", line_no); ! 769: dump_line (); ! 770: want_blank = false; ! 771: } ! 772: ! 773: if (p_l_follow > 0) { ! 774: /* check for preceeding unbalanced parens */ ! 775: printf ("%d: Unbalanced parens\n", line_no); ! 776: p_l_follow = 0; ! 777: if (sp_sw) { ! 778: /* check for unclosed if, for, etc. */ ! 779: sp_sw = false; ! 780: parse (hd_type); ! 781: ind_level = i_l_follow; ! 782: } ! 783: } ! 784: ! 785: if (s_code == e_code) ! 786: ind_stmt = false; ! 787: /* don't put extra indentation on line with '{' */ ! 788: if (in_decl && in_or_st) { ! 789: /* this is either a structure declaration or an init */ ! 790: di_stack[dec_nest++] = dec_ind; ! 791: dec_ind = 0; ! 792: } ! 793: else ! 794: decl_on_line = false; ! 795: /* we can't be in the middle of a declaration, so don't do ! 796: special indentation of comments */ ! 797: ! 798: parse (lbrace);/* let parser know about this */ ! 799: if (want_blank)/* put a blank before { if { is not at ! 800: start of line */ ! 801: *e_code++ = ' '; ! 802: want_blank = false; ! 803: *e_code++ = '{'; ! 804: break; ! 805: ! 806: case rbrace: /* got a } */ ! 807: if (p_l_follow) { ! 808: /* check for unclosed if, for, else. */ ! 809: printf ("%d: Unbalanced parens\n", line_no); ! 810: p_l_follow = 0; ! 811: sp_sw = false; ! 812: } ! 813: ! 814: if (s_code != e_code) { ! 815: /* } must be first on line */ ! 816: if (verbose) ! 817: printf ("%d: Line broken\n", line_no); ! 818: dump_line (); ! 819: } ! 820: ! 821: *e_code++ = '}'; ! 822: want_blank = true; ! 823: in_stmt = ind_stmt = false; ! 824: ! 825: if (dec_nest > 0) { ! 826: /* we are in multi-level structure declaration */ ! 827: dec_ind = di_stack[--dec_nest]; ! 828: in_decl = true; ! 829: } ! 830: ! 831: parse (rbrace);/* let parser know about this */ ! 832: break; ! 833: ! 834: case swstmt: /* got keyword "switch" */ ! 835: sp_sw = true; ! 836: hd_type = swstmt; ! 837: /* keep this for when we have seen the expression */ ! 838: goto copy_id; /* go move the token into buffer */ ! 839: ! 840: case sp_paren: /* token is if, while, for */ ! 841: sp_sw = true; /* the interesting stuff is done after the ! 842: expression is scanned */ ! 843: hd_type = (*token == 'i' ? ifstmt : ! 844: (*token == 'w' ? whilestmt : forstmt)); ! 845: /* remember the type of header for later use by parser */ ! 846: goto copy_id; /* copy the token into line */ ! 847: ! 848: case sp_nparen: /* got else, do */ ! 849: in_stmt = false; ! 850: if (e_code != s_code) { ! 851: /* make sure this starts a line */ ! 852: if (verbose) ! 853: printf ("%d: Line broken\n", line_no); ! 854: dump_line (); ! 855: want_blank = false; ! 856: } ! 857: ! 858: force_nl = true; ! 859: /* also, following stuff must go onto new line */ ! 860: parse (*token == 'e' ? elselit : dolit); ! 861: /* pass token on to parser */ ! 862: goto copy_id; /* move the token into line */ ! 863: ! 864: case decl: /* we have a declaration type (int, ! 865: register, etc.) */ ! 866: parse (decl); /* let parser worry about indentation */ ! 867: in_or_st = true; ! 868: /* this might be a structure or initialization declaration */ ! 869: in_decl = decl_on_line = true; ! 870: for (i = 0; token[i++];); ! 871: /* get length of token */ ! 872: ! 873: if (i <= 3) ! 874: i = 4; ! 875: ! 876: dec_ind = ((e_code - s_code + i) / ind_size + 1) * ind_size; ! 877: /* this will tell us how far to indent subsequent identifiers ! 878: */ ! 879: goto copy_id; ! 880: ! 881: case ident: /* got an identifier or constant */ ! 882: if (in_decl) { /* if we are in a declaration, we must ! 883: indent identifier */ ! 884: if (want_blank) ! 885: *e_code++ = ' '; ! 886: want_blank = false; ! 887: ! 888: while ((e_code - s_code) < dec_ind) ! 889: *e_code++ = ' '; ! 890: } ! 891: else ! 892: if (sp_sw && p_l_follow == 0) { ! 893: /* check for if expr w/o parens *//* this will make ! 894: JRM's obsurd "for ever" statements work */ ! 895: sp_sw = false; ! 896: force_nl = true; ! 897: last_u_d = true; ! 898: in_stmt = false; ! 899: parse (hd_type); ! 900: } ! 901: ! 902: copy_id: ! 903: if (want_blank) ! 904: *e_code++ = ' '; ! 905: for (t_ptr = token; *t_ptr; ++t_ptr) ! 906: *e_code++ = *t_ptr; ! 907: want_blank = true; ! 908: break; ! 909: ! 910: case period: /* treat a period kind of like a binary ! 911: operation */ ! 912: *e_code++ = '.'; ! 913: /* move the period into line */ ! 914: want_blank = false; ! 915: /* don't put a blank after a period */ ! 916: break; ! 917: ! 918: case comma: ! 919: want_blank = (s_code != e_code); ! 920: /* only put blank after comma if comma does not start the line ! 921: */ ! 922: if (in_decl) /* align these in a declaration */ ! 923: while ((e_code - s_code) < (dec_ind - 1)) ! 924: *e_code++ = ' '; ! 925: ! 926: *e_code++ = ','; ! 927: ! 928: if (break_comma && p_l_follow == 0 && !leave_comma) ! 929: force_nl = true; ! 930: ! 931: break; ! 932: ! 933: case preesc: /* got the character '#' */ ! 934: if ( ! 935: (s_com != e_com) || ! 936: (s_lab != e_lab) || ! 937: (s_code != e_code)) { ! 938: /* true iff the '#' was not at start of the line */ ! 939: printf ("%d: What is this # doing here?\n", line_no); ! 940: goto do_binary; ! 941: /* treat it as a binary operator */ ! 942: } ! 943: ! 944: *e_lab++ = '#';/* move whole line to 'label' buffer */ ! 945: while (*buf_ptr != '\n') { ! 946: *e_lab = *buf_ptr++; ! 947: if (buf_ptr >= buf_end) ! 948: fill_buffer (); ! 949: ! 950: if (*e_lab++ == '/' && *buf_ptr == '*') { ! 951: /* check for comment on preprocessor line */ ! 952: e_lab - = 2; ! 953: /* skip back over slash */ ! 954: while (*e_lab == '\t' || *e_lab == ' ') ! 955: --e_lab; ! 956: /* strip off trailing blanks and tabs */ ! 957: *(++e_lab) = '\0'; ! 958: /* null terminate the line */ ! 959: if (++buf_ptr >= buf_end) ! 960: /* space past start of comment */ ! 961: fill_buffer (); ! 962: col_1 = false; ! 963: /* don't let pr_comment think that this comment starts ! 964: in column 1 */ ! 965: decl_on_line = true; ! 966: /* treat this as a declaration for comment placement ! 967: purposes */ ! 968: goto proc_comment; ! 969: /* go process the comment */ ! 970: } ! 971: } ! 972: ! 973: *e_lab = '\0'; /* null terminate line */ ! 974: pcase = false; ! 975: break; /* subsequent processing of the newline ! 976: character will cause the line to be ! 977: printed */ ! 978: ! 979: case comment: /* we have gotten a /* this is a biggie */ ! 980: proc_comment: ! 981: pr_comment (); ! 982: break; ! 983: } /* end of big switch stmt */ ! 984: ! 985: *e_code = '\0'; /* make sure code section is null ! 986: terminated */ ! 987: ! 988: } /* end of main while (1) loop */ ! 989: }; ! 990: ! 991: /* ! 992: * copy input file to backup file ! 993: * if in_name is /blah/blah/blah/file, then backup file ! 994: * will be ".Bfile" ! 995: * then make the backup file the input and original ! 996: * input file the output ! 997: */ ! 998: bakcopy () { ! 999: int n, ! 1000: bakchn; ! 1001: char buff[512]; ! 1002: register char *p; ! 1003: ! 1004: /* construct file name .Bfile */ ! 1005: for (p = in_name; *p; p++);/* skip to end of string */ ! 1006: while (p > in_name && *p != '/')/* find last '/' */ ! 1007: p--; ! 1008: if (*p == '/') ! 1009: p++; ! 1010: sprintf (bakfile, ".B%s", p); ! 1011: ! 1012: /* copy in_name to backup file */ ! 1013: bakchn = creat (bakfile, 0600); ! 1014: if (bakchn < 0) { ! 1015: printf ("can't create backup file \"%s\"\n", bakfile); ! 1016: exit (); ! 1017: } ! 1018: while (n = read (input, buff, 512)) ! 1019: write (bakchn, buff, n); ! 1020: close (bakchn); ! 1021: close (input); ! 1022: ! 1023: /* re-open backup file as the input file */ ! 1024: input = open (bakfile, 0); ! 1025: if (input < 0) { ! 1026: printf ("can't re-open backup file\n"); ! 1027: exit (); ! 1028: } ! 1029: ! 1030: /* now the original input file will be the output */ ! 1031: output = creat (in_name, 0644); ! 1032: if (output < 0) { ! 1033: printf ("can't create %s\n", in_name); ! 1034: unlink (bakfile); ! 1035: exit (); ! 1036: } ! 1037: } ! 1038: ! 1039: ! 1040: set_option (arg) ! 1041: char *arg; ! 1042: { ! 1043: register j; ! 1044: for (j = 0; options[j].str != 0; ++j) { ! 1045: /* look thru list of possible options */ ! 1046: if (eqin (options[j].str, arg)) { ! 1047: set_var (j, arg); ! 1048: break; /* get out of for loop */ ! 1049: } ! 1050: } ! 1051: ! 1052: if (options[j].str == 0) { /* illegal arg given */ ! 1053: printf ("Unknown parameter: %s\n", arg); ! 1054: exit (); ! 1055: } ! 1056: } ! 1057: ! 1058: ! 1059: set_var (j, arg) ! 1060: char *arg; ! 1061: { ! 1062: switch (options[j].code) { ! 1063: case 1: /* have -lnnn */ ! 1064: max_col = atoi (&arg[2]); ! 1065: break; ! 1066: case 2: /* have -cnnn */ ! 1067: com_ind = atoi (&arg[2]); ! 1068: break; ! 1069: case 3: /* have -innn */ ! 1070: ind_size = atoi (&arg[2]); ! 1071: break; ! 1072: case 4: /* have -cdnnn */ ! 1073: decl_com_ind = atoi (&arg[3]); ! 1074: break; ! 1075: case 5: /* have -v */ ! 1076: verbose = true; ! 1077: break; ! 1078: case 6: /* have -nv */ ! 1079: verbose = false; ! 1080: break; ! 1081: case 7: /* have -dj */ ! 1082: ljust_decl = true; ! 1083: break; ! 1084: case 8: /* have -ndj */ ! 1085: ljust_decl = false; ! 1086: break; ! 1087: case 9: /* -nbc */ ! 1088: leave_comma = true; ! 1089: break; ! 1090: case 10: /* -bc */ ! 1091: leave_comma = false; ! 1092: break; ! 1093: case 13: /* -dnnn */ ! 1094: unindent_displace = atoi (&arg[2]); ! 1095: break; ! 1096: case 14: /* -br */ ! 1097: btype_2 = true; ! 1098: break; ! 1099: case 15: /* -bl */ ! 1100: btype_2 = false; ! 1101: break; ! 1102: case 16: ! 1103: if(input<0) input = 0; ! 1104: if(output<0) output = 1; ! 1105: break; ! 1106: } ! 1107: } ! 1108: ! 1109: ! 1110: /* ! 1111: * GETPRO - get profile file ! 1112: * profile file is max 127 characters ! 1113: */ ! 1114: getpro (name, buf) ! 1115: char *name, /* profile file name, as in '.indent.pro' ! 1116: */ ! 1117: *buf; /* will receive contents of .pro file */ ! 1118: { ! 1119: register chn, ! 1120: n; ! 1121: char file[32]; ! 1122: ! 1123: file[0] = 0; ! 1124: strcat (file, getenv ("HOME")); ! 1125: strcat (file, "/"); ! 1126: strcat (file, name); ! 1127: chn = open (file, 0); ! 1128: if (chn < 0) ! 1129: return (-1); ! 1130: n = read (chn, buf, 127); ! 1131: if (n < 0) ! 1132: return (-1); ! 1133: buf[n--] = 0; /* null terminate line */ ! 1134: if (buf[n] == '\n') ! 1135: buf[n] = 0; ! 1136: close (chn); ! 1137: return (0); ! 1138: } ! 1139: ! 1140: ! 1141: /* ! 1142: * strip off arguments in a string: ! 1143: * p is address of a character pointer ! 1144: * nextchr returns pointer to front of first arg ! 1145: * arg is null terminated. ! 1146: * p is reset to after arg for subsequent calls ! 1147: */ ! 1148: char *nxtarg (p) ! 1149: char **p; ! 1150: { ! 1151: register char *f, ! 1152: *b; ! 1153: f = b = *p; ! 1154: while (*f && (*f == ' ' || *f == '\t')) ! 1155: f++; ! 1156: while (*b && (*b != ' ' && *b != '\t')) ! 1157: b++; ! 1158: if (*b != 0) ! 1159: *b++ = 0; ! 1160: *p = b; ! 1161: return (f); ! 1162: } ! 1163: ! 1164: ! 1165: set_profile () { ! 1166: char line[128], ! 1167: *b; ! 1168: register char *f; ! 1169: extern char *nxtarg (); ! 1170: ! 1171: if (getpro (".indent.pro", line) < 0) ! 1172: return; ! 1173: b = line; ! 1174: if(verbose) printf ("profile: %s\n", b); ! 1175: while (*(f = nxtarg (&b))) ! 1176: set_option (f); ! 1177: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.