]> git.saurik.com Git - apple/xnu.git/blob - SETUP/decomment/decomment.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / SETUP / decomment / decomment.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License."
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 /*
25 * decomment.c
26 *
27 * Removes all comments and (optionally) whitespace from an input file.
28 * Writes result on stdout.
29 */
30
31 #include <stdio.h>
32 #include <ctype.h> /* for isspace */
33 #include <libc.h>
34
35 /*
36 * State of input scanner.
37 */
38 typedef enum {
39 IS_NORMAL,
40 IS_SLASH, // encountered opening '/'
41 IS_IN_COMMENT, // within / * * / comment
42 IS_STAR, // encountered closing '*'
43 IS_IN_END_COMMENT // within / / comment
44 } input_state_t;
45
46 static void usage(char **argv);
47
48 int
49 main(int argc, char **argv)
50 {
51 FILE *fp;
52 char bufchar;
53 input_state_t input_state = IS_NORMAL;
54 int exit_code = 0;
55 int remove_whitespace = 0;
56 int arg;
57
58 if (argc < 2) {
59 usage(argv);
60 }
61 for (arg = 2; arg < argc; arg++) {
62 switch (argv[arg][0]) {
63 case 'r':
64 remove_whitespace++;
65 break;
66 default:
67 usage(argv);
68 }
69 }
70
71 fp = fopen(argv[1], "r");
72 if (!fp) {
73 fprintf(stderr, "Error opening %s\n", argv[1]);
74 perror("fopen");
75 exit(1);
76 }
77 for (;;) {
78 bufchar = getc_unlocked(fp);
79 if (bufchar == EOF) {
80 break;
81 }
82
83 switch (input_state) {
84 case IS_NORMAL:
85 if (bufchar == '/') {
86 /*
87 * Might be start of a comment.
88 */
89 input_state = IS_SLASH;
90 } else {
91 if (!(remove_whitespace && isspace(bufchar))) {
92 putchar_unlocked(bufchar);
93 }
94 }
95 break;
96
97 case IS_SLASH:
98 switch (bufchar) {
99 case '*':
100 /*
101 * Start of normal comment.
102 */
103 input_state = IS_IN_COMMENT;
104 break;
105
106 case '/':
107 /*
108 * Start of 'to-end-of-line' comment.
109 */
110 input_state = IS_IN_END_COMMENT;
111 break;
112
113 default:
114 /*
115 * Not the start of comment. Emit the '/'
116 * we skipped last char in case we were
117 * entering a comment this time, then the
118 * current char.
119 */
120 putchar_unlocked('/');
121 if (!(remove_whitespace && isspace(bufchar))) {
122 putchar_unlocked(bufchar);
123 }
124 input_state = IS_NORMAL;
125 break;
126 }
127 break;
128
129 case IS_IN_COMMENT:
130 if (bufchar == '*') {
131 /*
132 * Maybe ending comment...
133 */
134 input_state = IS_STAR;
135 }
136 break;
137
138
139 case IS_STAR:
140 switch (bufchar) {
141 case '/':
142 /*
143 * End of normal comment.
144 */
145 input_state = IS_NORMAL;
146 break;
147
148 case '*':
149 /*
150 * Still could be one char away from end
151 * of comment.
152 */
153 break;
154
155 default:
156 /*
157 * Still inside comment, no end in sight.
158 */
159 input_state = IS_IN_COMMENT;
160 break;
161 }
162 break;
163
164 case IS_IN_END_COMMENT:
165 if (bufchar == '\n') {
166 /*
167 * End of comment. Emit the newline if
168 * appropriate.
169 */
170 if (!remove_whitespace) {
171 putchar_unlocked(bufchar);
172 }
173 input_state = IS_NORMAL;
174 }
175 break;
176 } /* switch input_state */
177 } /* main read loop */
178
179 /*
180 * Done.
181 */
182 return exit_code;
183 }
184
185 static void
186 usage(char **argv)
187 {
188 printf("usage: %s infile [r(emove whitespace)]\n", argv[0]);
189 exit(1);
190 }