1sunifdef(1) User Commmands sunifdef(1)
2
3
4
6 sunifdef - simplify C preprocessor source files
7
9 sunifdef [-v ⎪ --version]
10
11 sunifdef [-h ⎪ --help]
12
13 sunifdef [OPTION...] [files...]
14
16 sunifdef is a more powerful successor of the FreeBSD unifdef tool.
17 sunifdef is a preprocessor of C or C++ preprocessor source files (or
18 more briefly a preprocessor of C/C++ source files).
19
20 From the commandline arguments it takes a set of assumptions about the
21 symbols to be defined, or undefined, for the CPP. From the commandline
22 it also takes one or more source files. It parses these source files to
23 pick out conditional preprocessor directives (#if,#ifdef,#ifn‐
24 def,#else,#elif,#endif). It applies the specified assumptions to these
25 directives in attempt to evaluate them. Directives that cannot be fully
26 evaluated on the basis of the assumptions are simplified as much as
27 possible. Directives that can be fully evaluated are eliminated, and
28 the source text that they control is either retained or deleted in
29 accordance with the evaluation, mimicking the behaviour of the CPP.
30
31 sunifdef also detects #define and #undef directives and checks them for
32 consistency with the specified assumptions. If a #define or #undef
33 directive repeats one of the assumptions it is deleted on output; if it
34 conflicts with any of the assumptions then it may be deleted or
35 replaced with a diagnostic comment or a diagnostic #error, depending on
36 commandline options.
37
38 For each source file, an output file is generated that reflects the
39 simplifications arising from the specified assumptions. The command
40
41 sunifdef -DFOO bar.c
42
43 will write on the standard output a revision of the file bar.c that has
44 been purged as far as possible of preprocessor constructions controlled
45 by the truth-value of defined(FOO). This revision is equivalent to
46 bar.c on the assumption that FOO is defined. With appropriate options
47 and inputs, you can use a sunifdef command to perform wholesale removal
48 of redundant preprocessor complexities from a C or C++ source tree. See
49 the EXAMPLES section.
50
52 -h,--help
53 Display a usage summary and exit.
54
55 -v,--version
56 Display version information and exit.
57
58 -s[f⎪a][l], --symbols [first ⎪ all][,locate]
59 Output a list of symbols that are determinative for the truth value
60 of #if conditions.
61
62 f, first: List only the first occurrence of the symbol on input.
63
64 a, all: List all occurrences of the symbol on input.
65
66 l, locate: Report the file and line number of each listed occur‐
67 rence.
68
69 fargfile, --file argfile
70 Read (more) arguments from file argfile. Arguments may be written
71 free-form, separated by whitespace, in argfile. These arguments
72 will be parsed exactly as if they were listed on the commandline at
73 the position of -fargfile.
74
75 -Dmacro[=string], --define macro[=string]
76 Assume that #define macro[=string] is in force for processing the
77 input file(s).
78
79 -Umacro, --undef macro
80 Assume that #undef macro is in force for processing the input
81 file(s).
82
83 -r, --replace
84 Replace each input file with the corresponding output file. You
85 must specify this option to process multiple input files.
86
87 The option changes the default behaviour of the command when no
88 input files are specified. In this case, input is acquired from the
89 standard input. If -r is not specified, then a single input file is
90 read from the standard input. If -r is specified then the names of
91 the input files are read from the standard input. Note that
92 --recurse implies --replace.
93
94 If the names of the input files are read from stdin, the filenames
95 are delimited by whitespace unless enclosed in double-quotes.
96
97 -R, --recurse
98 Recurse into directories to find input files. Implies --replace.
99 The input files may include directories with this option: otherwise
100 a directory provokes a non-fatal error.
101
102 All files within a directory (and within subdirectories) will be
103 selected for input unless the --filter option is given: otherwise
104 all files (including subdirectories) will be selected that match
105 the --filter option.
106
107 When --recurse is in effect, sunifdef builds a graph of all unique
108 input files once and for all as it parses the filenames that are
109 explicitly supplied and before it processes any of them. New files
110 that may later appear in input directories during execution will
111 not be processed, and files that have disappeared from input direc‐
112 tories when they are due to be processed will provoke fatal errors.
113
114 -Fext1[,ext2...], --filter ext1[,ext2...]
115 Process only input files that have one of the file extensions
116 ext1,ext2... A file extension may be any terminal segment of a
117 filename that follows a '.'.
118
119 -Bsuffix, --backup suffix
120 Backup each input file before replacing it, the backup file having
121 the same name as the input file with suffix appended to it.
122
123 -x[d⎪c⎪e], --conflict [delete ⎪ comment ⎪ error]
124 Select the action to be taken when a #define or #undef directive is
125 encountered in an input file that conflicts with one of the -D or
126 -U assumptions:
127
128 d, delete: Delete the conflicting directive.
129
130 c, comment: Replace the conflicting directive with a diagnostic
131 comment (default).
132
133 e, error: Replace the conflicting directive with a diagnostic
134 #error directive.
135
136 -g[p⎪i⎪w⎪e⎪a], --gag [progress ⎪ info ⎪ warning ⎪ error ⎪ abend]
137 Suppress diagnostics no worse than [progress ⎪ info ⎪ warning ⎪
138 error ⎪ abend].
139
140 -gs, --gag summary.
141 Suppress summary diagnostics at end of input.
142
143 -V, --verbose
144 Output all diagnostics,
145
146 If neither -V nor -garg is specified defaults are -gp -gi -gs.
147
148 -n[u⎪e[d]], --constant [unk ⎪ eval[,del]]
149 Select the policy for processing constants in #if directives:
150
151 u, unk: Treat constants as unknowns, i.e. like macros that are not
152 subject to any assumptions (default).
153
154 e[d], eval[,del]: Evaluate constants [and optionally eliminate
155 them].
156
157 -c, --complement
158 Ouput the lines that ought to be dropped and vice versa.
159
160 -d, --debug
161 Write debugging information to stderr.
162
163 -k[d⎪b⎪c], --discard [drop ⎪ blank ⎪ comment]
164 Select the policy for discarding lines from output:
165
166 d, drop: Drop discarded lines.
167
168 b, blank: Blank discarded lines.
169
170 c, comment: Comment out discarded lines.
171
172 -K, --keepgoing
173 If a parse error is encountered in an input file, continue process‐
174 ing subsequent input files. An event of severity abend will termi‐
175 nate processing regardless of --keepgoing.
176
177 -P, --pod
178 Apart from CPP directives, input is to be treated as Plain Old
179 Data. C/C++ comments and quotations will not be parsed.
180
181 -l, --line
182 Output #line directives in place of discarded lines to preserve the
183 line numbers of retained lines.
184
186 sunifdef -DUNIX -UWIN32 foo.c
187 sunifdef --define UNIX --undef WIN32 foo.c
188 Simplify the file foo.c assuming that the symbol UNIX is defined
189 and the symbol WIN32 is undefined. Write the simplified file to
190 stdout. By default diagnostic messages whose severity is warning or
191 higher will be output and no summary diagnostics will be output.
192 All diagnostics are written to stderr.
193
194 sunifdef -DUNIX=1 -UWIN32 foo.c
195 sunifdef --define UNIX=1 --undef WIN32 foo.c
196 Like the previous example, but the symbol UNIX is defined as 1.
197
198 sunifdef -gw -DUNIX -UWIN32 foo.c
199 sunifdef --gag warn --define UNIX --undef WIN32 foo.c
200 Like the first example, but suppress all diagnostics (--gag) whose
201 severity is warning or lower that would otherwise be written to
202 stderr.
203
204 sunifdef -gw -DUNIX -UWIN32 foo.c
205 sunifdef --gag warn --define UNIX --undef WIN32 foo.c
206 Like the first example, but suppress all diagnostics (--gag) whose
207 severity is warning or lower that would otherwise be written to
208 stderr.
209
210 sunifdef -gw -gs -DUNIX -UWIN32 foo.c
211 sunifdef --gag warn -gag summary --define UNIX --undef WIN32 foo.c
212 Like the previous example, but also suppress all summary diagnos‐
213 tics that would otherwise be written to stderr after processing is
214 finished (--gag summary).
215
216 sunifdef -V -DUNIX -UWIN32 foo.c
217 sunifdef --verbose --define UNIX --undef WIN32 foo.c
218 Like the previous example, but write all diagnostics at all severi‐
219 ties to stderr, as well as summary diagnostics (--verbose).
220
221 sunifdef -DUNIX -UWIN32 < bar.c
222 sunifdef --define UNIX --undef WIN32 < bar.c
223 Like the previous example, but write only the default diagnostics
224 to stderr and read the input file from stdin (in this case redi‐
225 rected from bar.c)
226
227 sunifdef -r -DUNIX -UWIN32 foo.c bar.c
228 sunifdef --replace --define UNIX --undef WIN32 foo.c bar.c
229 Like the previous example, but --replace causes each input file to
230 be replaced with the corresponding simplified output file. With
231 this option multiple input files - foo.c, bar.c - can be supplied.
232
233 sunifdef -r -DUNIX -UWIN32 < filelist.txt
234 sunifdef --replace --define UNIX --undef WIN32 < filelist.txt
235 Like the previous example, but read the list of input filenames
236 from stdin (in this case redirected from filelist.txt)
237
238 sunifdef -r -B.bak -DUNIX -UWIN32 < filelist.txt
239 sunifdef --replace --backup ".bak" --define UNIX --undef WIN32 <
240 filelist.txt
241 Like the previous example, but create a backup of each input file
242 with the extension .bak (--backup ".bak").
243
244 sunifdef -R -DUNIX -UWIN32 foo.c somedir bar.h otherdir
245 sunifdef --recurse --define UNIX --undef WIN32 foo.c somedir bar.h oth‐
246 erdir
247 The --recurse option implies --replace and causes sunifdef to find
248 additional input files by searching recursively within the directo‐
249 ries somedir and otherdir
250
251 sunifdef -R -Fc,h -DUNIX -UWIN32 foo.c somedir bar.h otherdir
252 sunifdef --recurse --filter c,h --define UNIX --undef WIN32 foo.c
253 somedir bar.h otherdir
254 Like the previous example, but select only input files that have
255 one of the extensions .c or .h (--filter c,h).
256
257 sunifdef -R -Fc,h -K -DUNIX -UWIN32 foo.c somedir bar.h otherdir
258 sunifdef --recurse --filter c,h --keepgoing --define UNIX --undef WIN32
259 foo.c somedir bar.h otherdir
260 Like the previous example, but keep going through parse errors
261 (--keepgoing). Processing of the input file in error will be aban‐
262 doned but subsequent input files will be processed.
263
264 sunifdef -R -Fc,h -sf foo.c somedir bar.h otherdir
265 sunifdef --recurse --filter c,h --symbols first foo.c somedir bar.h
266 otherdir
267 Recursively select all the .c and .h files from foo.c, somedir,
268 bar.h, otherdir and write on stderr a list of all the symbols that
269 influence the truth-values of #if, #else, #elif conditions. Report
270 only the first occurrence of each symbol.
271
272 sunifdef -R -Fc,h -sfl foo.c somedir bar.h otherdir
273 sunifdef --recurse --filter c,h --symbols first,locate foo.c somedir
274 bar.h otherdir
275 Like the previous example, but report the file and line number of
276 each reported symbol (--symbols first,locate)
277
278 sunifdef -R -Fc,h -sal foo.c somedir bar.h otherdir
279 sunifdef --recurse --filter c,h --symbols all,locate foo.c somedir
280 bar.h otherdir
281 Like the previous example, but report all occurrences of the sym‐
282 bols (--symbols first,locate)
283
284 sunifdef -P -DUNIX -UWIN32 data.txt
285 sunifdef --pod --define UNIX --undef WIN32 data.txt
286 Process the file data.txt with the assumptions --define UNIX and
287 --undef WIN32 parsing the text (other than #-directives) as Plain
288 Old Data, rather than C/C++ source. C/C++ comments and quotations
289 will not be recognised.
290
291 sunifdef -R -fargs.txt foo.c somedir bar.h otherdir
292 sunifdef -R --file args.txt foo.c somedir bar.h otherdir
293 Interprolate the contents of the file args.txt into the command‐
294 line, replacing --file args.txt and then execute the resulting com‐
295 mand.
296
297 sunifdef -fargs.txt
298 sunifdef --file args.txt
299 Substite the contents of the file args.txt for --file args.txt and
300 then execute the resulting command.
301
303 Diagnostics written to stderr are classified by severity. Each diagnos‐
304 tic includes a distinct hexadecimal code of the form "0xXXXXX" that
305 encodes its severity. The 5 severities are:
306 progress: Progress messages ("0xXXXXX & 0x00800" is true)
307
308 info: Noteworthy information ("0xXXXXX & 0x01000" is true)
309
310 warning: Indicating problematic input ("0xXXXXX & 0x02000" is true)
311
312 error: Indicating invalid input ("0xXXXXX & 0x04000" is true)
313
314 abend: Indicating a fatal environment or internal error ("0xXXXXX &
315 0x08000" is true)
316
317 Unless --gag summary is in force, sunifdef can write summary diagnos‐
318 tics at the end of processing. A summary diagnostic has a hexadecimal
319 code S that encodes one of the severities and in addition S "& 0x10000"
320 is true. Even if --gag summary is not in force, a summary will not be
321 written if its severity is suppressed by one of the specified or
322 default --gag options. Since all summaries have severity info or warn‐
323 ing, this means that by default no summaries will appear and to obtain
324 all summaries you must specify --verbose. The summaries include:
325 info: The number of input files that were reached and the number
326 that were not reached (due to abend).
327
328 info: The number of input files reached that were abandoned (due to
329 errors).
330
331 If there was no abend or error, then additional summaries are written
332 (unless suppressed) indicating each of the following outcomes that has
333 occurred:
334 info: Input lines were dropped on output.
335
336 info: Input lines were changed on output.
337
338 warning: Input lines were changed to #error directives.
339
340 warning: Unconditional #error directives were output.
341
342 sunifdef returns a system code SC of which the low order half of the
343 low order byte is always meaningful:
344 SC "& 1": Informational diagnostics accrued.
345
346 SC "& 2": Warnings diagnostics accrued.
347
348 SC "& 4": Error diagnostics accrued. (Input files provoking errors
349 will be unchanged notwithstanding the --replace option.)
350
351 SC "& 8": An abend occurred. Some input files may not have been
352 reached.
353
354 If no error or abend is indicated, then the high order half of the low
355 order byte is also meaningful:
356 SC "& 16": Input lines were dropped on output. SC "& 32": Input
357 lines were changed on output. SC "& 64": Input lines were changed
358 to #error directives. SC "& 128": Unconditional #error directives
359 were output.
360
361 The system code reflects diagnostics that were provoked even if they
362 were not actually output due to --gag options.
363
365 The conditional operator ?...:... is not parsed.
366
367 Trigraphs are not parsed.
368
369 #define and #undef directives that are found to be active are not fac‐
370 tored into the evalation of subsequent #if directives.
371
372 Please report bugs to bugs dot sunifdef at strudl dot org
373
375 Mike Kinghan imk at strudl dot org
376
378 FreeBSD unifdef(1)
379
380
381
382JANUARY 2008 strudl.org sunifdef(1)