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