]> git.saurik.com Git - apple/xnu.git/blame - SETUP/decomment/decomment.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / SETUP / decomment / decomment.c
CommitLineData
316670eb
A
1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
0a7de745 5 *
316670eb
A
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.
0a7de745 13 *
316670eb
A
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."
0a7de745 21 *
316670eb
A
22 * @APPLE_LICENSE_HEADER_END@
23 */
24/*
25 * decomment.c
26 *
0a7de745 27 * Removes all comments and (optionally) whitespace from an input file.
316670eb
A
28 * Writes result on stdout.
29 */
0a7de745 30
316670eb 31#include <stdio.h>
0a7de745 32#include <ctype.h> /* for isspace */
316670eb
A
33#include <libc.h>
34
35/*
36 * State of input scanner.
37 */
38typedef enum {
39 IS_NORMAL,
0a7de745
A
40 IS_SLASH, // encountered opening '/'
41 IS_IN_COMMENT, // within / * * / comment
42 IS_STAR, // encountered closing '*'
43 IS_IN_END_COMMENT // within / / comment
316670eb
A
44} input_state_t;
45
46static void usage(char **argv);
47
0a7de745
A
48int
49main(int argc, char **argv)
316670eb
A
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;
0a7de745
A
57
58 if (argc < 2) {
316670eb 59 usage(argv);
0a7de745
A
60 }
61 for (arg = 2; arg < argc; arg++) {
62 switch (argv[arg][0]) {
63 case 'r':
64 remove_whitespace++;
316670eb 65 break;
0a7de745
A
66 default:
67 usage(argv);
316670eb 68 }
0a7de745
A
69 }
70
316670eb 71 fp = fopen(argv[1], "r");
0a7de745 72 if (!fp) {
316670eb
A
73 fprintf(stderr, "Error opening %s\n", argv[1]);
74 perror("fopen");
75 exit(1);
76 }
0a7de745 77 for (;;) {
316670eb 78 bufchar = getc_unlocked(fp);
0a7de745 79 if (bufchar == EOF) {
316670eb 80 break;
0a7de745 81 }
316670eb 82
0a7de745
A
83 switch (input_state) {
84 case IS_NORMAL:
85 if (bufchar == '/') {
86 /*
316670eb
A
87 * Might be start of a comment.
88 */
89 input_state = IS_SLASH;
0a7de745
A
90 } else {
91 if (!(remove_whitespace && isspace(bufchar))) {
316670eb
A
92 putchar_unlocked(bufchar);
93 }
94 }
95 break;
0a7de745
A
96
97 case IS_SLASH:
98 switch (bufchar) {
99 case '*':
100 /*
316670eb
A
101 * Start of normal comment.
102 */
103 input_state = IS_IN_COMMENT;
104 break;
0a7de745
A
105
106 case '/':
107 /*
316670eb
A
108 * Start of 'to-end-of-line' comment.
109 */
110 input_state = IS_IN_END_COMMENT;
111 break;
0a7de745
A
112
113 default:
114 /*
316670eb
A
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('/');
0a7de745 121 if (!(remove_whitespace && isspace(bufchar))) {
316670eb
A
122 putchar_unlocked(bufchar);
123 }
124 input_state = IS_NORMAL;
125 break;
126 }
127 break;
0a7de745
A
128
129 case IS_IN_COMMENT:
130 if (bufchar == '*') {
131 /*
316670eb
A
132 * Maybe ending comment...
133 */
0a7de745 134 input_state = IS_STAR;
316670eb 135 }
0a7de745
A
136 break;
137
138
139 case IS_STAR:
140 switch (bufchar) {
141 case '/':
316670eb
A
142 /*
143 * End of normal comment.
144 */
145 input_state = IS_NORMAL;
146 break;
0a7de745
A
147
148 case '*':
149 /*
316670eb
A
150 * Still could be one char away from end
151 * of comment.
152 */
153 break;
0a7de745
A
154
155 default:
156 /*
316670eb
A
157 * Still inside comment, no end in sight.
158 */
159 input_state = IS_IN_COMMENT;
160 break;
161 }
162 break;
0a7de745
A
163
164 case IS_IN_END_COMMENT:
165 if (bufchar == '\n') {
316670eb 166 /*
0a7de745 167 * End of comment. Emit the newline if
316670eb
A
168 * appropriate.
169 */
0a7de745 170 if (!remove_whitespace) {
316670eb
A
171 putchar_unlocked(bufchar);
172 }
173 input_state = IS_NORMAL;
174 }
175 break;
316670eb 176 } /* switch input_state */
0a7de745
A
177 } /* main read loop */
178
316670eb
A
179 /*
180 * Done.
181 */
0a7de745 182 return exit_code;
316670eb
A
183}
184
0a7de745
A
185static void
186usage(char **argv)
316670eb
A
187{
188 printf("usage: %s infile [r(emove whitespace)]\n", argv[0]);
189 exit(1);
190}