Module Name: src Committed By: rillig Date: Sat Sep 25 17:11:24 UTC 2021
Modified Files: src/usr.bin/indent: Makefile args.c indent.c indent.h indent_globs.h io.c lexi.c parse.c pr_comment.c Log Message: indent: prepare for lint's strict bool mode Before C99, C had no boolean type. Instead, indent used int for that, just like many other programs. Even with C99, bool and int can be used interchangeably in many situations, such as querying '!i' or '!ptr' or 'cond == 0'. Since January 2021, lint provides the strict bool mode, which makes bool a non-arithmetic type that is incompatible with any other type. Having clearly separate types helps in understanding the code. To migrate indent to strict bool mode, the first step is to apply all changes that keep the resulting binary the same. Since sizeof(bool) is 1 and sizeof(int) is 4, the type ibool serves as an intermediate type. For now it is defined to int, later it will become bool. The current code compiles cleanly in C99 and C11 mode, as well as in lint's strict bool mode. There are a few tricky places: In args.c in 'struct pro', there are two types of options: boolean and integer. Boolean options point to a bool variable, integer options point to an int variable. To keep the current structure of the code, the pointer has been changed to 'void *'. To ensure type safety, the definition of the options is done via preprocessor magic, which in C11 mode ensures the correct pointer types. (Add CFLAGS+=-std=gnu11 at the very bottom of the Makefile.) In indent.c in process_preprocessing, a boolean variable is post-incremented. That variable is only assigned to another variable, and that variable is only used in a boolean context. To provoke a different behavior between the '++' and the '= true', the source code to be indented would need 1 << 32 preprocessing directives, which is unlikely to happen in practice. In io.c in dump_line, the variables ps.in_stmt and ps.in_decl only ever get the values 0 and 1. For these values, the expressions 'a & ~b' and 'a && !b' are equivalent, in all versions of C. The compiler may generate different code for them, though. In io.c in parse_indent_comment, the assignment to inhibit_formatting takes place in integer context. If the compiler is smart enough to detect the possible values of on_off, it may generate the same code before and after the change, but that is rather unlikely. The second step of the migration will be to replace ibool with bool, step by step, just in case there are any hidden gotchas in the code, such as sizeof or pointer casts. No change to the resulting binary. To generate a diff of this commit: cvs rdiff -u -r1.12 -r1.13 src/usr.bin/indent/Makefile cvs rdiff -u -r1.24 -r1.25 src/usr.bin/indent/args.c cvs rdiff -u -r1.72 -r1.73 src/usr.bin/indent/indent.c cvs rdiff -u -r1.20 -r1.21 src/usr.bin/indent/indent.h cvs rdiff -u -r1.28 -r1.29 src/usr.bin/indent/indent_globs.h cvs rdiff -u -r1.59 -r1.60 src/usr.bin/indent/io.c cvs rdiff -u -r1.53 -r1.54 src/usr.bin/indent/lexi.c cvs rdiff -u -r1.23 -r1.24 src/usr.bin/indent/parse.c cvs rdiff -u -r1.42 -r1.43 src/usr.bin/indent/pr_comment.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.