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