PostgreSQL Source Code git master
Loading...
Searching...
No Matches
indent.c File Reference
#include "c.h"
#include <sys/param.h>
#include <err.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "indent_globs.h"
#include "indent_codes.h"
#include "indent.h"
Include dependency graph for indent.c:

Go to the source code of this file.

Macros

#define DECLARE_INDENT_GLOBALS   1
 

Functions

static void bakcopy (void)
 
static void indent_declaration (int cur_dec_ind, int tabs_to_var)
 
int main (int argc, char **argv)
 

Variables

const charin_name = "Standard Input"
 
const charout_name = "Standard Output"
 
char bakfile [MAXPGPATH] = ""
 

Macro Definition Documentation

◆ DECLARE_INDENT_GLOBALS

#define DECLARE_INDENT_GLOBALS   1

Definition at line 50 of file indent.c.

Function Documentation

◆ bakcopy()

static void bakcopy ( void  )
static

Definition at line 1204 of file indent.c.

1205{
1206 int n,
1207 bakchn;
1208 char buff[8 * 1024];
1209 const char *p;
1210
1211 /* construct file name .Bfile */
1212 for (p = in_name; *p; p++); /* skip to end of string */
1213 while (p > in_name && *p != '/') /* find last '/' */
1214 p--;
1215 if (*p == '/')
1216 p++;
1217 sprintf(bakfile, "%s.BAK", p);
1218
1219 /* copy in_name to backup file */
1220 bakchn = creat(bakfile, 0600);
1221 if (bakchn < 0)
1222 err(1, "%s", bakfile);
1223 while ((n = read(fileno(input), buff, sizeof(buff))) > 0)
1224 if (write(bakchn, buff, n) != n)
1225 err(1, "%s", bakfile);
1226 if (n < 0)
1227 err(1, "%s", in_name);
1228 close(bakchn);
1229 fclose(input);
1230
1231 /* re-open backup file as the input file */
1232 input = fopen(bakfile, "r");
1233 if (input == NULL)
1234 err(1, "%s", bakfile);
1235 /* now the original input file will be the output */
1236 output = fopen(in_name, "wb");
1237 if (output == NULL) {
1238 unlink(bakfile);
1239 err(1, "%s", in_name);
1240 }
1241}
void err(int eval, const char *fmt,...)
Definition err.c:43
const char * in_name
Definition indent.c:59
char bakfile[MAXPGPATH]
Definition indent.c:63
FILE * input
FILE * output
#define close(a)
Definition win32.h:12
#define write(a, b, c)
Definition win32.h:14
#define read(a, b, c)
Definition win32.h:13
#define sprintf
Definition port.h:262
static int fb(int x)

References bakfile, close, err(), fb(), in_name, input, output, read, sprintf, and write.

Referenced by main().

◆ indent_declaration()

static void indent_declaration ( int  cur_dec_ind,
int  tabs_to_var 
)
static

Definition at line 1244 of file indent.c.

1245{
1246 int pos = e_code - s_code;
1247 char *startpos = e_code;
1248
1249 /*
1250 * get the tab math right for indentations that are not multiples of tabsize
1251 */
1252 if ((ps.ind_level * ps.ind_size) % tabsize != 0) {
1253 pos += (ps.ind_level * ps.ind_size) % tabsize;
1255 }
1256 if (tabs_to_var) {
1257 int tpos;
1258
1260 while ((tpos = tabsize * (1 + pos / tabsize)) <= cur_dec_ind) {
1261 *e_code++ = (!postgres_tab_rules ||
1262 tpos != pos + 1 ||
1263 cur_dec_ind >= tpos + tabsize) ? '\t' : ' ';
1264 pos = tpos;
1265 }
1266 }
1267 CHECK_SIZE_CODE(cur_dec_ind - pos + 1);
1268 while (pos < cur_dec_ind) {
1269 *e_code++ = ' ';
1270 pos++;
1271 }
1272 if (e_code == startpos && ps.want_blank) {
1273 *e_code++ = ' ';
1274 ps.want_blank = false;
1275 }
1276}
int tabsize
int postgres_tab_rules
#define CHECK_SIZE_CODE(desired_size)
char * e_code
struct parser_state ps
char * s_code
static XLogRecPtr startpos

References CHECK_SIZE_CODE, e_code, fb(), parser_state::ind_level, parser_state::ind_size, postgres_tab_rules, ps, s_code, startpos, tabsize, and parser_state::want_blank.

Referenced by main().

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 66 of file indent.c.

67{
68 int dec_ind; /* current indentation for declarations */
69 int di_stack[20]; /* a stack of structure indentation levels */
70 int force_nl; /* when true, code must be broken */
71 int hd_type = 0; /* used to store type of stmt for if (...),
72 * for (...), etc */
73 int i; /* local loop counter */
74 int scase; /* set to true when we see a case, so we will
75 * know what to do with the following colon */
76 int sp_sw; /* when true, we are in the expression of
77 * if(...), while(...), etc. */
78 int squest; /* when this is positive, we have seen a ?
79 * without the matching : in a <c>?<s>:<s>
80 * construct */
81 const char *t_ptr; /* used for copying tokens */
82 int tabs_to_var; /* true if using tabs to indent to var name */
83 int type_code; /* the type of token, returned by lexi */
84
85 int last_else = 0; /* true iff last keyword was an else */
86 const char *profile_name = NULL;
87 struct parser_state transient_state; /* a copy for lookup */
88
89
90 /*-----------------------------------------------*\
91 | INITIALIZATION |
92 \*-----------------------------------------------*/
93
94 found_err = 0;
95
96 ps.p_stack[0] = stmt; /* this is the parser's stack */
97 ps.last_nl = true; /* this is true if the last thing scanned was
98 * a newline */
100 combuf = (char *) malloc(bufsize);
101 if (combuf == NULL)
102 err(1, NULL);
103 labbuf = (char *) malloc(bufsize);
104 if (labbuf == NULL)
105 err(1, NULL);
106 codebuf = (char *) malloc(bufsize);
107 if (codebuf == NULL)
108 err(1, NULL);
109 tokenbuf = (char *) malloc(bufsize);
110 if (tokenbuf == NULL)
111 err(1, NULL);
113 l_com = combuf + bufsize - 5;
114 l_lab = labbuf + bufsize - 5;
115 l_code = codebuf + bufsize - 5;
116 l_token = tokenbuf + bufsize - 5;
117 combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and
118 * comment buffers */
119 combuf[1] = codebuf[1] = labbuf[1] = '\0';
120 ps.else_if = 1; /* Default else-if special processing to on */
121 s_lab = e_lab = labbuf + 1;
122 s_code = e_code = codebuf + 1;
123 s_com = e_com = combuf + 1;
124 s_token = e_token = tokenbuf + 1;
125
126 in_buffer = (char *) malloc(10);
127 if (in_buffer == NULL)
128 err(1, NULL);
131 line_no = 1;
133 sp_sw = force_nl = false;
134 ps.in_or_st = false;
135 ps.bl_line = true;
136 dec_ind = 0;
137 di_stack[ps.dec_nest = 0] = 0;
138 ps.want_blank = ps.in_stmt = ps.ind_stmt = false;
139
140 scase = ps.pcase = false;
141 squest = 0;
142 sc_end = NULL;
143 bp_save = NULL;
144 be_save = NULL;
145
146 output = NULL;
147 tabs_to_var = 0;
148
149 /*--------------------------------------------------*\
150 | COMMAND LINE SCAN |
151 \*--------------------------------------------------*/
152
153#ifdef undef
154 max_col = 78; /* -l78 */
155 lineup_to_parens = 1; /* -lp */
156 lineup_to_parens_always = 0; /* -nlpl */
157 ps.ljust_decl = 0; /* -ndj */
158 ps.com_ind = 33; /* -c33 */
159 star_comment_cont = 1; /* -sc */
160 ps.ind_size = 8; /* -i8 */
161 verbose = 0;
162 ps.decl_indent = 16; /* -di16 */
163 ps.local_decl_indent = -1; /* if this is not set to some nonnegative value
164 * by an arg, we will set this equal to
165 * ps.decl_ind */
166 ps.indent_parameters = 1; /* -ip */
167 ps.decl_com_ind = 0; /* if this is not set to some positive value
168 * by an arg, we will set this equal to
169 * ps.com_ind */
170 btype_2 = 1; /* -br */
171 cuddle_else = 1; /* -ce */
172 ps.unindent_displace = 0; /* -d0 */
173 ps.case_indent = 0; /* -cli0 */
174 format_block_comments = 1; /* -fcb */
175 format_col1_comments = 1; /* -fc1 */
176 procnames_start_line = 1; /* -psl */
177 proc_calls_space = 0; /* -npcs */
178 comment_delimiter_on_blankline = 1; /* -cdb */
179 ps.leave_comma = 1; /* -nbc */
180#endif
181
182 for (i = 1; i < argc; ++i)
183 if (strcmp(argv[i], "-npro") == 0)
184 break;
185 else if (argv[i][0] == '-' && argv[i][1] == 'P' && argv[i][2] != '\0')
186 profile_name = argv[i]; /* non-empty -P (set profile) */
187 set_defaults();
188 if (i >= argc)
190
191 for (i = 1; i < argc; ++i) {
192
193 /*
194 * look thru args (if any) for changes to defaults
195 */
196 if (argv[i][0] != '-') {/* no flag on parameter */
197 if (input == NULL) { /* we must have the input file */
198 in_name = argv[i]; /* remember name of input file */
199 input = fopen(in_name, "r");
200 if (input == NULL) /* check for open error */
201 err(1, "%s", in_name);
202 continue;
203 }
204 else if (output == NULL) { /* we have the output file */
205 out_name = argv[i]; /* remember name of output file */
206 if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite
207 * the file */
208 errx(1, "input and output files must be different");
209 }
210 output = fopen(out_name, "wb");
211 if (output == NULL) /* check for create error */
212 err(1, "%s", out_name);
213 continue;
214 }
215 errx(1, "unknown parameter: %s", argv[i]);
216 }
217 else
218 set_option(argv[i]);
219 } /* end of for */
220 if (input == NULL)
221 input = stdin;
222 if (output == NULL) {
223 if (input == stdin)
224 output = stdout;
225 else {
227 bakcopy();
228 }
229 }
230
231 if (ps.com_ind <= 1)
232 ps.com_ind = 2; /* dont put normal comments before column 2 */
233 if (block_comment_max_col <= 0)
235 if (ps.local_decl_indent < 0) /* if not specified by user, set this */
237 if (ps.decl_com_ind <= 0) /* if not specified by user, set this */
238 ps.decl_com_ind = ps.ljust_decl ? (ps.com_ind <= 10 ? 2 : ps.com_ind - 8) : ps.com_ind;
239 if (continuation_indent == 0)
241 fill_buffer(); /* get first batch of stuff into input buffer */
242
244 {
245 char *p = buf_ptr;
246 int col = 1;
247
248 while (1) {
249 if (*p == ' ')
250 col++;
251 else if (*p == '\t')
252 col = tabsize * (1 + (col - 1) / tabsize) + 1;
253 else
254 break;
255 p++;
256 }
257 if (col > ps.ind_size)
259 }
260
261 /*
262 * START OF MAIN LOOP
263 */
264
265 while (1) { /* this is the main loop. it will go until we
266 * reach eof */
267 int comment_buffered = false;
268
269 type_code = lexi(&ps); /* lexi reads one token. The actual
270 * characters read are stored in "token". lexi
271 * returns a code indicating the type of token */
272
273 /*
274 * The following code moves newlines and comments following an if (),
275 * while (), else, etc. up to the start of the following stmt to
276 * a buffer. This allows proper handling of both kinds of brace
277 * placement (-br, -bl) and cuddling "else" (-ce).
278 */
279
280 while (ps.search_brace) {
281 switch (type_code) {
282 case newline:
283 if (sc_end == NULL) {
285 save_com[0] = save_com[1] = ' ';
286 sc_end = &save_com[2];
287 }
288 *sc_end++ = '\n';
289 /*
290 * We may have inherited a force_nl == true from the previous
291 * token (like a semicolon). But once we know that a newline
292 * has been scanned in this loop, force_nl should be false.
293 *
294 * However, the force_nl == true must be preserved if newline
295 * is never scanned in this loop, so this assignment cannot be
296 * done earlier.
297 */
298 force_nl = false;
299 break;
300 case form_feed:
301 break;
302 case comment:
303 if (sc_end == NULL) {
304 /*
305 * Copy everything from the start of the line, because
306 * pr_comment() will use that to calculate original
307 * indentation of a boxed comment.
308 */
310 save_com = sc_buf + (buf_ptr - in_buffer - 4);
311 save_com[0] = save_com[1] = ' ';
312 sc_end = &save_com[2];
313 }
314 comment_buffered = true;
315 *sc_end++ = '/'; /* copy in start of comment */
316 *sc_end++ = '*';
317 for (;;) { /* loop until we get to the end of the comment */
318 *sc_end = *buf_ptr++;
319 if (buf_ptr >= buf_end)
320 fill_buffer();
321 if (*sc_end++ == '*' && *buf_ptr == '/')
322 break; /* we are at end of comment */
323 if (sc_end >= &save_com[sc_size]) { /* check for temp buffer
324 * overflow */
325 diag2(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever");
326 fflush(output);
327 exit(1);
328 }
329 }
330 *sc_end++ = '/'; /* add ending slash */
331 if (++buf_ptr >= buf_end) /* get past / in buffer */
332 fill_buffer();
333 break;
334 case lbrace:
335 /*
336 * Put KNF-style lbraces before the buffered up tokens and
337 * jump out of this loop in order to avoid copying the token
338 * again under the default case of the switch below.
339 */
340 if (sc_end != NULL && btype_2) {
341 save_com[0] = '{';
342 /*
343 * Originally the lbrace may have been alone on its own
344 * line, but it will be moved into "the else's line", so
345 * if there was a newline resulting from the "{" before,
346 * it must be scanned now and ignored.
347 */
348 while (isspace((unsigned char)*buf_ptr)) {
349 if (++buf_ptr >= buf_end)
350 fill_buffer();
351 if (*buf_ptr == '\n')
352 break;
353 }
354 goto sw_buffer;
355 }
357 default: /* it is the start of a normal statement */
358 {
359 int remove_newlines;
360
362 /* "} else" */
363 (type_code == sp_nparen && *token == 'e' &&
364 e_code != s_code && e_code[-1] == '}')
365 /* "else if" */
366 || (type_code == sp_paren && *token == 'i' &&
367 last_else && ps.else_if);
368 if (remove_newlines)
369 force_nl = false;
370 if (sc_end == NULL) { /* ignore buffering if
371 * comment wasn't saved up */
372 ps.search_brace = false;
373 goto check_type;
374 }
375 while (sc_end > save_com && isblank((unsigned char)sc_end[-1])) {
376 sc_end--;
377 }
381 while (sc_end > save_com && sc_end[-1] == '\n') {
382 sc_end--;
383 }
384 }
385 if (force_nl) { /* if we should insert a nl here, put
386 * it into the buffer */
387 force_nl = false;
388 --line_no; /* this will be re-increased when the
389 * newline is read from the buffer */
390 *sc_end++ = '\n';
391 *sc_end++ = ' ';
392 if (verbose) /* print error msg if the line was
393 * not already broken */
394 diag2(0, "Line broken");
395 }
396 for (t_ptr = token; *t_ptr; ++t_ptr)
397 *sc_end++ = *t_ptr;
398
399 sw_buffer:
400 ps.search_brace = false; /* stop looking for start of
401 * stmt */
402 bp_save = buf_ptr; /* save current input buffer */
404 buf_ptr = save_com; /* fix so that subsequent calls to
405 * lexi will take tokens out of
406 * save_com */
407 *sc_end++ = ' ';/* add trailing blank, just in case */
408 buf_end = sc_end;
409 sc_end = NULL;
410 break;
411 }
412 } /* end of switch */
413 /*
414 * We must make this check, just in case there was an unexpected
415 * EOF.
416 */
417 if (type_code != 0) {
418 /*
419 * The only intended purpose of calling lexi() below is to
420 * categorize the next token in order to decide whether to
421 * continue buffering forthcoming tokens. Once the buffering
422 * is over, lexi() will be called again elsewhere on all of
423 * the tokens - this time for normal processing.
424 *
425 * Calling it for this purpose is a bug, because lexi() also
426 * changes the parser state and discards leading whitespace,
427 * which is needed mostly for comment-related considerations.
428 *
429 * Work around the former problem by giving lexi() a copy of
430 * the current parser state and discard it if the call turned
431 * out to be just a look ahead.
432 *
433 * Work around the latter problem by copying all whitespace
434 * characters into the buffer so that the later lexi() call
435 * will read them.
436 */
437 if (sc_end != NULL) {
438 while (*buf_ptr == ' ' || *buf_ptr == '\t') {
439 *sc_end++ = *buf_ptr++;
440 if (sc_end >= &save_com[sc_size]) {
441 errx(1, "input too long");
442 }
443 }
444 if (buf_ptr >= buf_end) {
445 fill_buffer();
446 }
447 }
449 type_code = lexi(&transient_state); /* read another token */
450 if (type_code != newline && type_code != form_feed &&
451 type_code != comment && !transient_state.search_brace) {
453 }
454 }
455 } /* end of while (search_brace) */
456 last_else = 0;
458 if (type_code == 0) { /* we got eof */
459 if (s_lab != e_lab || s_code != e_code
460 || s_com != e_com) /* must dump end of line */
461 dump_line();
462 if (ps.tos > 1) /* check for balanced braces */
463 diag2(1, "Stuff missing from end of file");
464
465 if (verbose) {
466 printf("There were %d output lines and %d comments\n",
468 printf("(Lines with comments)/(Lines with code): %6.3f\n",
469 (1.0 * ps.com_lines) / code_lines);
470 }
471 fflush(output);
473 }
474 if (
475 (type_code != comment) &&
476 (type_code != newline) &&
477 (type_code != preesc) &&
478 (type_code != form_feed)) {
479 if (force_nl &&
480 (type_code != semicolon) &&
481 (type_code != lbrace || !btype_2)) {
482 /* we should force a broken line here */
483 if (verbose)
484 diag2(0, "Line broken");
485 dump_line();
486 ps.want_blank = false; /* dont insert blank at line start */
487 force_nl = false;
488 }
489 ps.in_stmt = true; /* turn on flag which causes an extra level of
490 * indentation. this is turned off by a ; or
491 * '}' */
492 if (s_com != e_com) { /* the turkey has embedded a comment
493 * in a line. fix it */
494 int len = e_com - s_com;
495
496 CHECK_SIZE_CODE(len + 3);
497 *e_code++ = ' ';
499 e_code += len;
500 *e_code++ = ' ';
501 *e_code = '\0'; /* null terminate code sect */
502 ps.want_blank = false;
503 e_com = s_com;
504 }
505 }
506 else if (type_code != comment) /* preserve force_nl thru a comment */
507 force_nl = false; /* cancel forced newline after newline, form
508 * feed, etc */
509
510
511
512 /*-----------------------------------------------------*\
513 | do switch on type of token scanned |
514 \*-----------------------------------------------------*/
515 CHECK_SIZE_CODE(3); /* maximum number of increments of e_code
516 * before the next CHECK_SIZE_CODE or
517 * dump_line() is 2. After that there's the
518 * final increment for the null character. */
519 switch (type_code) { /* now, decide what to do with the token */
520
521 case form_feed: /* found a form feed in line */
522 ps.use_ff = true; /* a form feed is treated much like a newline */
523 dump_line();
524 ps.want_blank = false;
525 break;
526
527 case newline:
528 if (ps.last_token != comma || ps.p_l_follow > 0
529 || !ps.leave_comma || ps.block_init || !break_comma || s_com != e_com) {
530 dump_line();
531 ps.want_blank = false;
532 }
533 ++line_no; /* keep track of input line number */
534 break;
535
536 case lparen: /* got a '(' or '[' */
537 /* count parens to make Healy happy */
538 if (++ps.p_l_follow == nitems(ps.paren_indents)) {
539 diag3(0, "Reached internal limit of %d unclosed parens",
541 ps.p_l_follow--;
542 }
543 if (*token == '[')
544 /* not a function pointer declaration or a function call */;
545 else if (ps.in_decl && !ps.block_init && !ps.dumped_decl_indent &&
546 ps.procname[0] == '\0' && ps.paren_level == 0) {
547 /* function pointer declarations */
549 ps.dumped_decl_indent = true;
550 }
551 else if (ps.want_blank &&
552 ((ps.last_token != ident && ps.last_token != funcname) ||
553 /* offsetof (1) is never allowed a space; sizeof (2) gets
554 * one iff -bs; all other keywords (>2) always get a space
555 * before lparen */
556 ps.keyword + Bill_Shannon > 2))
557 *e_code++ = ' ';
558 ps.want_blank = false;
559 *e_code++ = token[0];
562 && ps.paren_indents[0] < 2 * ps.ind_size)
563 ps.paren_indents[0] = 2 * ps.ind_size;
564 if (ps.in_or_st && *token == '(' && ps.tos <= 2) {
565 /*
566 * this is a kluge to make sure that declarations will be
567 * aligned right if proc decl has an explicit type on it, i.e.
568 * "int a(x) {..."
569 */
570 parse(semicolon); /* I said this was a kluge... */
571 ps.in_or_st = false; /* turn off flag for structure decl or
572 * initialization */
573 }
574 /*
575 * parenthesized type following sizeof or offsetof is not a cast,
576 * and we assume the same for any other non-keyword identifier,
577 * to support macros that take types
578 */
579 if (ps.last_token == ident &&
580 (ps.keyword == 0 || ps.keyword == 1 || ps.keyword == 2))
582 break;
583
584 case rparen: /* got a ')' or ']' */
585 if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.not_cast_mask) {
586 ps.last_u_d = true;
587 ps.cast_mask &= (1 << ps.p_l_follow) - 1;
589 } else
590 ps.want_blank = true;
591 ps.not_cast_mask &= (1 << ps.p_l_follow) - 1;
592 if (--ps.p_l_follow < 0) {
593 ps.p_l_follow = 0;
594 diag3(0, "Extra %c", *token);
595 }
596 if (e_code == s_code) /* if the paren starts the line */
597 ps.paren_level = ps.p_l_follow; /* then indent it */
598
599 *e_code++ = token[0];
600
601 if (sp_sw && (ps.p_l_follow == 0)) { /* check for end of if
602 * (...), or some such */
603 sp_sw = false;
604 force_nl = true;/* must force newline after if */
605 ps.last_u_d = true; /* inform lexi that a following
606 * operator is unary */
607 ps.in_stmt = false; /* dont use stmt continuation
608 * indentation */
609
610 parse(hd_type); /* let parser worry about if, or whatever */
611 }
612 ps.search_brace = btype_2; /* this should ensure that constructs
613 * such as main(){...} and int[]{...}
614 * have their braces put in the right
615 * place */
616 break;
617
618 case unary_op: /* this could be any unary operation */
620 ps.procname[0] == '\0' && ps.paren_level == 0) {
621 /* pointer declarations */
622
623 /*
624 * if this is a unary op in a declaration, we should indent
625 * this token
626 */
627 for (i = 0; token[i]; ++i)
628 /* find length of token */;
630 ps.dumped_decl_indent = true;
631 }
632 else if (ps.want_blank)
633 *e_code++ = ' ';
634
635 {
636 int len = e_token - s_token;
637
640 e_code += len;
641 }
642 ps.want_blank = false;
643 break;
644
645 case binary_op: /* any binary operation */
646 {
647 int len = e_token - s_token;
648
649 CHECK_SIZE_CODE(len + 1);
650 if (ps.want_blank)
651 *e_code++ = ' ';
653 e_code += len;
654 }
655 ps.want_blank = true;
656 break;
657
658 case postop: /* got a trailing ++ or -- */
659 *e_code++ = token[0];
660 *e_code++ = token[1];
661 ps.want_blank = true;
662 break;
663
664 case question: /* got a ? */
665 squest++; /* this will be used when a later colon
666 * appears so we can distinguish the
667 * <c>?<n>:<n> construct */
668 if (ps.want_blank)
669 *e_code++ = ' ';
670 *e_code++ = '?';
671 ps.want_blank = true;
672 break;
673
674 case casestmt: /* got word 'case' or 'default' */
675 scase = true; /* so we can process the later colon properly */
676 goto copy_id;
677
678 case colon: /* got a ':' */
679 if (squest > 0) { /* it is part of the <c>?<n>: <n> construct */
680 --squest;
681 if (ps.want_blank)
682 *e_code++ = ' ';
683 *e_code++ = ':';
684 ps.want_blank = true;
685 break;
686 }
687 if (ps.in_or_st) {
688 *e_code++ = ':';
689 ps.want_blank = false;
690 break;
691 }
692 ps.in_stmt = false; /* seeing a label does not imply we are in a
693 * stmt */
694 /*
695 * turn everything so far into a label
696 */
697 {
698 int len = e_code - s_code;
699
700 CHECK_SIZE_LAB(len + 3);
702 e_lab += len;
703 *e_lab++ = ':';
704 *e_lab = '\0';
705 e_code = s_code;
706 }
707 force_nl = ps.pcase = scase; /* ps.pcase will be used by
708 * dump_line to decide how to
709 * indent the label. force_nl
710 * will force a case n: to be
711 * on a line by itself */
712 scase = false;
713 ps.want_blank = false;
714 break;
715
716 case semicolon: /* got a ';' */
717 if (ps.dec_nest == 0)
718 ps.in_or_st = false;/* we are not in an initialization or
719 * structure declaration */
720 scase = false; /* these will only need resetting in an error */
721 squest = 0;
722 if (ps.last_token == rparen)
724 ps.cast_mask = 0;
725 ps.not_cast_mask = 0;
726 ps.block_init = 0;
729
730 if (ps.in_decl && s_code == e_code && !ps.block_init &&
732 /* indent stray semicolons in declarations */
734 ps.dumped_decl_indent = true;
735 }
736
737 ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level
738 * structure declaration, we
739 * arent any more */
740
741 if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0) {
742
743 /*
744 * This should be true iff there were unbalanced parens in the
745 * stmt. It is a bit complicated, because the semicolon might
746 * be in a for stmt
747 */
748 diag2(1, "Unbalanced parens");
749 ps.p_l_follow = 0;
750 if (sp_sw) { /* this is a check for an if, while, etc. with
751 * unbalanced parens */
752 sp_sw = false;
753 parse(hd_type); /* dont lose the if, or whatever */
754 }
755 }
756 *e_code++ = ';';
757 ps.want_blank = true;
758 ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the
759 * middle of a stmt */
760
761 if (!sp_sw) { /* if not if for (;;) */
762 parse(semicolon); /* let parser know about end of stmt */
763 force_nl = true;/* force newline after an end of stmt */
764 }
765 break;
766
767 case lbrace: /* got a '{' */
768 ps.in_stmt = false; /* dont indent the {} */
769 if (!ps.block_init)
770 force_nl = true;/* force other stuff on same line as '{' onto
771 * new line */
772 else if (ps.block_init_level <= 0)
774 else
776
777 if (s_code != e_code && !ps.block_init) {
778 if (!btype_2) {
779 dump_line();
780 ps.want_blank = false;
781 }
782 else if (ps.in_parameter_declaration && !ps.in_or_st) {
783 ps.i_l_follow = 0;
784 if (function_brace_split) { /* dump the line prior to the
785 * brace ... */
786 dump_line();
787 ps.want_blank = false;
788 } else /* add a space between the decl and brace */
789 ps.want_blank = true;
790 }
791 }
794
795 if (ps.p_l_follow > 0) { /* check for preceding unbalanced
796 * parens */
797 diag2(1, "Unbalanced parens");
798 ps.p_l_follow = 0;
799 if (sp_sw) { /* check for unclosed if, for, etc. */
800 sp_sw = false;
801 parse(hd_type);
803 }
804 }
805 if (s_code == e_code)
806 ps.ind_stmt = false; /* dont put extra indentation on line
807 * with '{' */
808 if (ps.in_decl && ps.in_or_st) { /* this is either a structure
809 * declaration or an init */
811 if (++ps.dec_nest == nitems(di_stack)) {
812 diag3(0, "Reached internal limit of %d struct levels",
814 ps.dec_nest--;
815 }
816 /* ? dec_ind = 0; */
817 }
818 else {
819 ps.decl_on_line = false; /* we can't be in the middle of
820 * a declaration, so don't do
821 * special indentation of
822 * comments */
827 ps.in_decl = false;
828 }
829 dec_ind = 0;
830 parse(lbrace); /* let parser know about this */
831 if (ps.want_blank) /* put a blank before '{' if '{' is not at
832 * start of line */
833 *e_code++ = ' ';
834 ps.want_blank = false;
835 *e_code++ = '{';
836 ps.just_saw_decl = 0;
837 break;
838
839 case rbrace: /* got a '}' */
840 if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be
841 * omitted in
842 * declarations */
844 if (ps.p_l_follow) {/* check for unclosed if, for, else. */
845 diag2(1, "Unbalanced parens");
846 ps.p_l_follow = 0;
847 sp_sw = false;
848 }
849 ps.just_saw_decl = 0;
851 if (s_code != e_code && !ps.block_init) { /* '}' must be first on
852 * line */
853 if (verbose)
854 diag2(0, "Line broken");
855 dump_line();
856 }
857 *e_code++ = '}';
858 ps.want_blank = true;
859 ps.in_stmt = ps.ind_stmt = false;
860 if (ps.dec_nest > 0) { /* we are in multi-level structure
861 * declaration */
864 ps.just_saw_decl = 2;
865 ps.in_decl = true;
866 }
868 parse(rbrace); /* let parser know about this */
870 && ps.il[ps.tos] >= ps.ind_level;
871 if (ps.tos <= 1 && blanklines_after_procs && ps.dec_nest <= 0)
873 break;
874
875 case swstmt: /* got keyword "switch" */
876 sp_sw = true;
877 hd_type = swstmt; /* keep this for when we have seen the
878 * expression */
879 goto copy_id; /* go move the token into buffer */
880
881 case sp_paren: /* token is if, while, for */
882 sp_sw = true; /* the interesting stuff is done after the
883 * expression is scanned */
884 hd_type = (*token == 'i' ? ifstmt :
885 (*token == 'w' ? whilestmt : forstmt));
886
887 /*
888 * remember the type of header for later use by parser
889 */
890 goto copy_id; /* copy the token into line */
891
892 case sp_nparen: /* got else, do */
893 ps.in_stmt = false;
894 if (*token == 'e') {
895 if (e_code != s_code && (!cuddle_else || e_code[-1] != '}')) {
896 if (verbose)
897 diag2(0, "Line broken");
898 dump_line();/* make sure this starts a line */
899 ps.want_blank = false;
900 }
901 force_nl = true;/* also, following stuff must go onto new line */
902 last_else = 1;
903 parse(elselit);
904 }
905 else {
906 if (e_code != s_code) { /* make sure this starts a line */
907 if (verbose)
908 diag2(0, "Line broken");
909 dump_line();
910 ps.want_blank = false;
911 }
912 force_nl = true;/* also, following stuff must go onto new line */
913 last_else = 0;
914 parse(dolit);
915 }
916 goto copy_id; /* move the token into line */
917
918 case type_def:
919 case storage:
921 goto copy_id;
922
923 case structure:
924 if (ps.p_l_follow > 0)
925 goto copy_id;
927 case decl: /* we have a declaration type (int, etc.) */
928 parse(decl); /* let parser worry about indentation */
929 if (ps.last_token == rparen && ps.tos <= 1) {
930 if (s_code != e_code) {
931 dump_line();
932 ps.want_blank = 0;
933 }
934 }
937 ps.ind_stmt = 0;
938 }
939 ps.in_or_st = true; /* this might be a structure or initialization
940 * declaration */
941 ps.in_decl = ps.decl_on_line = true;
942 if ( /* !ps.in_or_st && */ ps.dec_nest <= 0)
943 ps.just_saw_decl = 2;
945 for (i = 0; token[i++];); /* get length of token */
946
947 if (ps.ind_level == 0 || ps.dec_nest > 0) {
948 /* global variable or struct member in local variable */
950 tabs_to_var = (use_tabs ? ps.decl_indent > 0 : 0);
951 } else {
952 /* local variable */
955 }
956 goto copy_id;
957
958 case funcname:
959 case ident: /* got an identifier or constant */
960 if (ps.in_decl) {
961 if (type_code == funcname) {
962 ps.in_decl = false;
964 *e_code = '\0';
965 dump_line();
966 }
967 else if (ps.want_blank) {
968 *e_code++ = ' ';
969 }
970 ps.want_blank = false;
971 }
972 else if (!ps.block_init && !ps.dumped_decl_indent &&
973 ps.paren_level == 0) { /* if we are in a declaration, we
974 * must indent identifier */
976 ps.dumped_decl_indent = true;
977 ps.want_blank = false;
978 }
979 }
980 else if (sp_sw && ps.p_l_follow == 0) {
981 sp_sw = false;
982 force_nl = true;
983 ps.last_u_d = true;
984 ps.in_stmt = false;
985 parse(hd_type);
986 }
987 copy_id:
988 {
989 int len = e_token - s_token;
990
991 CHECK_SIZE_CODE(len + 1);
992 if (ps.want_blank)
993 *e_code++ = ' ';
995 e_code += len;
996 }
997 if (type_code != funcname)
998 ps.want_blank = true;
999 break;
1000
1001 case strpfx:
1002 {
1003 int len = e_token - s_token;
1004
1005 CHECK_SIZE_CODE(len + 1);
1006 if (ps.want_blank)
1007 *e_code++ = ' ';
1009 e_code += len;
1010 }
1011 ps.want_blank = false;
1012 break;
1013
1014 case period: /* treat a period kind of like a binary
1015 * operation */
1016 *e_code++ = '.'; /* move the period into line */
1017 ps.want_blank = false; /* dont put a blank after a period */
1018 break;
1019
1020 case comma:
1021 ps.want_blank = (s_code != e_code); /* only put blank after comma
1022 * if comma does not start the
1023 * line */
1024 if (ps.in_decl && ps.procname[0] == '\0' && !ps.block_init &&
1026 /* indent leading commas and not the actual identifiers */
1028 ps.dumped_decl_indent = true;
1029 }
1030 *e_code++ = ',';
1031 if (ps.p_l_follow == 0) {
1032 if (ps.block_init_level <= 0)
1033 ps.block_init = 0;
1034 if (break_comma && (!ps.leave_comma ||
1036 max_col - tabsize))
1037 force_nl = true;
1038 }
1039 break;
1040
1041 case preesc: /* got the character '#' */
1042 if ((s_com != e_com) ||
1043 (s_lab != e_lab) ||
1044 (s_code != e_code))
1045 dump_line();
1046 CHECK_SIZE_LAB(1);
1047 *e_lab++ = '#'; /* move whole line to 'label' buffer */
1048 {
1049 int in_comment = 0;
1050 int com_start = 0;
1051 char quote = 0;
1052 int com_end = 0;
1053
1054 while (*buf_ptr == ' ' || *buf_ptr == '\t') {
1055 buf_ptr++;
1056 if (buf_ptr >= buf_end)
1057 fill_buffer();
1058 }
1059 while (*buf_ptr != '\n' || (in_comment && !had_eof)) {
1060 CHECK_SIZE_LAB(2);
1061 *e_lab = *buf_ptr++;
1062 if (buf_ptr >= buf_end)
1063 fill_buffer();
1064 switch (*e_lab++) {
1065 case BACKSLASH:
1066 if (!in_comment) {
1067 *e_lab++ = *buf_ptr++;
1068 if (buf_ptr >= buf_end)
1069 fill_buffer();
1070 }
1071 break;
1072 case '/':
1073 if (*buf_ptr == '*' && !in_comment && !quote) {
1074 in_comment = 1;
1075 *e_lab++ = *buf_ptr++;
1076 com_start = e_lab - s_lab - 2;
1077 }
1078 break;
1079 case '"':
1080 if (quote == '"')
1081 quote = 0;
1082 break;
1083 case '\'':
1084 if (quote == '\'')
1085 quote = 0;
1086 break;
1087 case '*':
1088 if (*buf_ptr == '/' && in_comment) {
1089 in_comment = 0;
1090 *e_lab++ = *buf_ptr++;
1091 com_end = e_lab - s_lab;
1092 }
1093 break;
1094 }
1095 }
1096
1097 while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
1098 e_lab--;
1099 if (e_lab - s_lab == com_end && bp_save == NULL) {
1100 /* comment on preprocessor line */
1101 if (sc_end == NULL) { /* if this is the first comment,
1102 * we must set up the buffer */
1103 save_com = sc_buf;
1104 sc_end = &save_com[0];
1105 }
1106 else {
1107 *sc_end++ = '\n'; /* add newline between
1108 * comments */
1109 *sc_end++ = ' ';
1110 --line_no;
1111 }
1113 errx(1, "input too long");
1116 e_lab = s_lab + com_start;
1117 while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
1118 e_lab--;
1119 bp_save = buf_ptr; /* save current input buffer */
1120 be_save = buf_end;
1121 buf_ptr = save_com; /* fix so that subsequent calls to
1122 * lexi will take tokens out of
1123 * save_com */
1124 *sc_end++ = ' '; /* add trailing blank, just in case */
1125 buf_end = sc_end;
1126 sc_end = NULL;
1127 }
1128 CHECK_SIZE_LAB(1);
1129 *e_lab = '\0'; /* null terminate line */
1130 ps.pcase = false;
1131 }
1132
1133 if (strncmp(s_lab, "#if", 3) == 0) { /* also ifdef, ifndef */
1134 if ((size_t)ifdef_level < nitems(state_stack)) {
1137 }
1138 else
1139 diag2(1, "#if stack overflow");
1140 }
1141 else if (strncmp(s_lab, "#el", 3) == 0) { /* else, elif */
1142 if (ifdef_level <= 0)
1143 diag2(1, s_lab[3] == 'i' ? "Unmatched #elif" : "Unmatched #else");
1144 else {
1145 match_state[ifdef_level - 1] = ps;
1146 ps = state_stack[ifdef_level - 1];
1147 }
1148 }
1149 else if (strncmp(s_lab, "#endif", 6) == 0) {
1150 if (ifdef_level <= 0)
1151 diag2(1, "Unmatched #endif");
1152 else
1153 ifdef_level--;
1154 } else {
1155 struct directives {
1156 int size;
1157 const char *string;
1158 }
1159 recognized[] = {
1160 {7, "include"},
1161 {6, "define"},
1162 {5, "undef"},
1163 {4, "line"},
1164 {5, "error"},
1165 {6, "pragma"}
1166 };
1167 int d = nitems(recognized);
1168 while (--d >= 0)
1169 if (strncmp(s_lab + 1, recognized[d].string, recognized[d].size) == 0)
1170 break;
1171 if (d < 0) {
1172 diag2(1, "Unrecognized cpp directive");
1173 break;
1174 }
1175 }
1179 }
1180 else {
1183 }
1184 break; /* subsequent processing of the newline
1185 * character will cause the line to be printed */
1186
1187 case comment: /* we have gotten a / followed by * this is a biggie */
1188 pr_comment();
1189 break;
1190 } /* end of big switch stmt */
1191
1192 *e_code = '\0'; /* make sure code section is null terminated */
1195 } /* end of main while (1) loop */
1196}
void set_profile(const char *profile_name)
Definition args.c:176
void set_defaults(void)
Definition args.c:246
#define pg_fallthrough
Definition c.h:144
void errx(int eval, const char *fmt,...)
Definition err.c:58
static void bakcopy(void)
Definition indent.c:1204
const char * out_name
Definition indent.c:61
static void indent_declaration(int cur_dec_ind, int tabs_to_var)
Definition indent.c:1244
int compute_code_target(void)
Definition io.c:223
void parse(int)
Definition parse.c:49
int lexi(struct parser_state *)
Definition lexi.c:216
void diag2(int, const char *)
Definition io.c:590
void diag3(int, const char *, int)
Definition io.c:573
int count_spaces_until(int, char *, char *)
Definition io.c:517
void pr_comment(void)
Definition pr_comment.c:79
void alloc_typenames(void)
Definition lexi.c:677
void fill_buffer(void)
Definition io.c:346
void dump_line(void)
Definition io.c:61
#define nitems(x)
Definition indent.h:31
#define comma
#define form_feed
#define stmt
#define lparen
#define whilestmt
#define swstmt
#define sp_nparen
#define ifhead
#define rbrace
#define colon
#define postop
#define ifstmt
#define period
#define comment
#define question
#define lbrace
#define semicolon
#define ident
#define type_def
#define preesc
#define structure
#define forstmt
#define funcname
#define dolit
#define binary_op
#define elselit
#define casestmt
#define storage
#define newline
#define sp_paren
#define decl
#define unary_op
#define strpfx
#define rparen
char * l_token
int star_comment_cont
char * e_com
char * tokenbuf
char * codebuf
int procnames_start_line
int block_comment_max_col
#define sc_size
int use_tabs
int blanklines_after_procs
int format_col1_comments
char * in_buffer
int space_after_cast
char * l_com
int had_eof
int btype_2
int lineup_to_parens
char * s_com
int postfix_blankline_requested
char * l_lab
struct parser_state state_stack[5]
char sc_buf[sc_size]
int proc_calls_space
char * buf_ptr
int prefix_blankline_requested
char * in_buffer_limit
char * save_com
char * e_token
int line_no
#define bufsize
int found_err
int Bill_Shannon
int extra_expression_indent
char * l_code
char * e_lab
char * labbuf
int function_brace_split
char * buf_end
char * s_lab
char * combuf
int max_col
int format_block_comments
int comment_delimiter_on_blankline
#define CHECK_SIZE_LAB(desired_size)
struct parser_state match_state[5]
int n_real_blanklines
char * s_token
int blanklines_around_conditional_compilation
char * sc_end
int break_comma
char * be_save
int swallow_optional_blanklines
int cuddle_else
#define BACKSLASH
int continuation_indent
int code_lines
char * bp_save
int ifdef_level
int lineup_to_parens_always
int blanklines_after_declarations_at_proctop
int i
Definition isn.c:77
bool set_option
static int verbose
const void size_t len
#define printf(...)
Definition port.h:266
char string[11]
#define malloc(a)
char procname[100]
int p_stack[256]
int in_parameter_declaration
short paren_indents[20]

References alloc_typenames(), BACKSLASH, bakcopy(), be_save, Bill_Shannon, binary_op, parser_state::bl_line, blanklines_after_declarations_at_proctop, blanklines_after_procs, blanklines_around_conditional_compilation, block_comment_max_col, parser_state::block_init, parser_state::block_init_level, bp_save, break_comma, btype_2, buf_end, buf_ptr, bufsize, parser_state::case_indent, casestmt, parser_state::cast_mask, CHECK_SIZE_CODE, CHECK_SIZE_LAB, code_lines, codebuf, colon, parser_state::com_ind, parser_state::com_lines, combuf, comma, comment, comment_delimiter_on_blankline, compute_code_target(), continuation_indent, count_spaces_until(), cuddle_else, parser_state::dec_nest, decl, parser_state::decl_com_ind, parser_state::decl_indent, parser_state::decl_on_line, diag2(), diag3(), dolit, dump_line(), parser_state::dumped_decl_indent, e_code, e_com, e_lab, e_token, parser_state::else_if, elselit, err(), errx(), extra_expression_indent, fb(), fill_buffer(), form_feed, format_block_comments, format_col1_comments, forstmt, found_err, funcname, function_brace_split, had_eof, i, parser_state::i_l_follow, ident, ifdef_level, ifhead, ifstmt, parser_state::il, in_buffer, in_buffer_limit, parser_state::in_decl, in_name, parser_state::in_or_st, parser_state::in_parameter_declaration, parser_state::in_stmt, parser_state::ind_level, parser_state::ind_size, parser_state::ind_stmt, indent_declaration(), parser_state::indent_parameters, input, parser_state::just_saw_decl, parser_state::keyword, l_code, l_com, l_lab, l_token, labbuf, parser_state::last_nl, parser_state::last_token, parser_state::last_u_d, lbrace, parser_state::leave_comma, len, lexi(), line_no, lineup_to_parens, lineup_to_parens_always, parser_state::ljust_decl, parser_state::local_decl_indent, lparen, malloc, match_state, max_col, n_real_blanklines, newline, nitems, parser_state::not_cast_mask, parser_state::out_coms, parser_state::out_lines, out_name, output, parser_state::p_l_follow, parser_state::p_stack, parser_state::paren_indents, parser_state::paren_level, parse(), parser_state::pcase, period, pg_fallthrough, postfix_blankline_requested, postop, pr_comment(), preesc, prefix_blankline_requested, printf, proc_calls_space, parser_state::procname, procnames_start_line, ps, question, rbrace, rparen, s_code, s_com, s_lab, s_token, save_com, sc_buf, sc_end, sc_size, parser_state::search_brace, semicolon, set_defaults(), set_option, set_profile(), sp_nparen, sp_paren, space_after_cast, star_comment_cont, state_stack, stmt, storage, strpfx, structure, swallow_optional_blanklines, swstmt, tabsize, tokenbuf, parser_state::tos, type_def, unary_op, parser_state::unindent_displace, parser_state::use_ff, use_tabs, verbose, parser_state::want_blank, and whilestmt.

Variable Documentation

◆ bakfile

char bakfile[MAXPGPATH] = ""

Definition at line 63 of file indent.c.

Referenced by bakcopy().

◆ in_name

const char* in_name = "Standard Input"

Definition at line 59 of file indent.c.

Referenced by bakcopy(), and main().

◆ out_name

const char* out_name = "Standard Output"

Definition at line 61 of file indent.c.

Referenced by main().