Pristine Ack-5.5
[Ack-5.5.git] / util / cmisc / GCIPM.c
1 /* $Id: GCIPM.c,v 1.5 1994/06/24 10:16:33 ceriel Exp $ */
2 /*
3  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4  * See the copyright notice in the ACK home directory, in the file "Copyright".
5  */
6 /*** Generic C Identifier Processing Module     ***/
7 /* IMPORT CheckId(char *, int), DoOption(char *), BeginOfProgram(), and
8    EndOfProgram().
9 */
10
11 #include <stdio.h>
12
13 extern CheckId();
14 extern DoOption();
15 extern BeginOfProgram(), EndOfProgram();
16
17 #define MAX_ID_LEN      256
18
19 char *ProgName;
20 int GCcopy;
21
22 main(argc, argv)
23         char *argv[];
24 {
25         char **nargv;
26         int nargc = 0;
27         FILE *fp;
28
29         ProgName = *argv++;
30         nargv = argv;
31
32         BeginOfProgram();
33         while (--argc > 0) {
34                 if ((*argv)[0] == '-') {
35                         DoOption(*argv++);
36                 }
37                 else {
38                         nargv[nargc++] = *argv++;
39                 }
40         }
41
42         if (nargc > 0) {
43                 while (nargc-- > 0) {
44                         if ((fp = fopen(*nargv, "r")) == NULL) {
45                                 fprintf(stderr, "%s: cannot read file \"%s\"\n",
46                                         ProgName, *nargv);
47                         }
48                         else {
49                                 DoFile(fp);
50                         }
51                         nargv++;
52                 }
53         }
54         else {
55                 DoFile(stdin);
56         }
57         EndOfProgram();
58         exit(0);
59 }
60
61 DoFile(fp)
62         FILE *fp;
63 {
64         register c;
65
66         while ((c = getc(fp)) != EOF) {
67                 switch (c) {
68
69                 case '"':
70                 case '\'':
71                         if (GCcopy) putchar(c);
72                         SkipString(fp, c);
73                         break;
74                 
75                 case '/':
76                         if (GCcopy) putchar(c);
77                         if ((c = getc(fp)) == '*') {
78                                 if (GCcopy) putchar(c);
79                                 SkipComment(fp);
80                         }
81                         else {
82                                 ungetc(c, fp);
83                         }
84                         break;
85
86                 default:
87                         if (StartId(c)) {
88                                 DoIdent(fp, c);
89                         }
90                         else if (StartNum(c)) {
91                                 if (GCcopy) putchar(c);
92                                 DoNum(fp, c);
93                         }
94                         else if (GCcopy) putchar(c);
95                         break;
96                 }
97         }
98         fclose(fp);
99 }
100
101 SkipString(fp, stopc)
102         FILE *fp;
103 {
104         register c;
105
106         while ((c = getc(fp)) != EOF) {
107                 if (GCcopy) putchar(c);
108                 if (c == stopc) {
109                         return;
110                 }
111
112                 if (c == '\\') {
113                         c = getc(fp);
114                         if (GCcopy) putchar(c);
115                 }
116         }
117 }
118
119 SkipComment(fp)
120         FILE *fp;
121 {
122         register c;
123
124         while ((c = getc(fp)) != EOF) {
125                 if (GCcopy) putchar(c);
126                 if (c == '*') {
127                         if ((c = getc(fp)) == '/') {
128                                 if (GCcopy) putchar(c);
129                                 return;
130                         }
131                         ungetc(c, fp);
132                 }
133         }
134 }
135
136 DoIdent(fp, s)
137         FILE *fp;
138 {
139         char id_buf[MAX_ID_LEN];
140         register cnt = 1;
141         register c;
142
143         id_buf[0] = s;
144
145         while ((c = getc(fp)) != EOF) {
146                 if (InId(c)) {
147                         id_buf[cnt++] = c;
148                 }
149                 else {
150                         ungetc(c, fp);
151                         id_buf[cnt] = '\0';
152                         CheckId(id_buf, cnt);
153                         return;
154                 }
155         }
156 }
157
158 StartId(c)
159 {
160         switch (c) {
161
162         case 'a': case 'b': case 'c': case 'd': case 'e':
163         case 'f': case 'g': case 'h': case 'i': case 'j':
164         case 'k': case 'l': case 'm': case 'n': case 'o':
165         case 'p': case 'q': case 'r': case 's': case 't':
166         case 'u': case 'v': case 'w': case 'x': case 'y':
167         case 'z':
168         case 'A': case 'B': case 'C': case 'D': case 'E':
169         case 'F': case 'G': case 'H': case 'I': case 'J':
170         case 'K': case 'L': case 'M': case 'N': case 'O':
171         case 'P': case 'Q': case 'R': case 'S': case 'T':
172         case 'U': case 'V': case 'W': case 'X': case 'Y':
173         case 'Z':
174         case '_':
175                 return 1;
176         
177         default:
178                 return 0;
179         }
180 }
181
182 InId(c)
183 {
184         switch (c) {
185
186         case 'a': case 'b': case 'c': case 'd': case 'e':
187         case 'f': case 'g': case 'h': case 'i': case 'j':
188         case 'k': case 'l': case 'm': case 'n': case 'o':
189         case 'p': case 'q': case 'r': case 's': case 't':
190         case 'u': case 'v': case 'w': case 'x': case 'y':
191         case 'z':
192         case 'A': case 'B': case 'C': case 'D': case 'E':
193         case 'F': case 'G': case 'H': case 'I': case 'J':
194         case 'K': case 'L': case 'M': case 'N': case 'O':
195         case 'P': case 'Q': case 'R': case 'S': case 'T':
196         case 'U': case 'V': case 'W': case 'X': case 'Y':
197         case 'Z':
198         case '_':
199         case '0': case '1': case '2': case '3': case '4':
200         case '5': case '6': case '7': case '8': case '9':
201                 return 1;
202         
203         default:
204                 return 0;
205         }
206 }
207
208 StartNum(c)
209 {
210         switch(c) {
211         case '0': case '1': case '2': case '3': case '4':
212         case '5': case '6': case '7': case '8': case '9':
213                 return 1;
214         }
215         return 0;
216 }
217
218 #define inrange(c, l, u)        ((unsigned)((c) - (l)) <= ((u) - (l)))
219 #define isdec(c) inrange(c, '0', '9')
220 #define isoct(c) inrange(c, '0', '7')
221 #define ishex(c) (isdec(c) || inrange(c, 'a', 'f') || inrange(c, 'A', 'F'))
222 #define getdec(c, fp)   do { c = getc((fp)); if (GCcopy) putchar(c);} while (isdec(c))
223 #define getoct(c, fp)   do { c = getc((fp)); if (GCcopy) putchar(c);} while (isoct(c))
224 #define gethex(c, fp)   do { c = getc((fp)); if (GCcopy) putchar(c);} while (ishex(c))
225
226 DoNum(fp, c)
227         register FILE *fp;
228 {
229         if (c != '0') {
230                 getdec(c, fp);
231                 if (c == '.')
232                         getdec(c, fp);
233                 if (c == 'e') {
234                         c = getc(fp);
235                         if (c == '+' || c == '-')
236                                 c = getc(fp);
237                         if (isdec(c))
238                                 getdec(c, fp);
239                 }
240         }
241         else {
242                 c = getc(fp);
243                 if (GCcopy) putchar(c);
244                 if (c == 'x' || c == 'X')
245                         gethex(c, fp);
246                 else
247                 if (isoct(c))
248                         getoct(c, fp);
249         }
250 }