rev |
line source |
yuuji@0
|
1 /* ========================================================================
|
yuuji@0
|
2 * Copyright 1988-2006 University of Washington
|
yuuji@0
|
3 *
|
yuuji@0
|
4 * Licensed under the Apache License, Version 2.0 (the "License");
|
yuuji@0
|
5 * you may not use this file except in compliance with the License.
|
yuuji@0
|
6 * You may obtain a copy of the License at
|
yuuji@0
|
7 *
|
yuuji@0
|
8 * http://www.apache.org/licenses/LICENSE-2.0
|
yuuji@0
|
9 *
|
yuuji@0
|
10 *
|
yuuji@0
|
11 * ========================================================================
|
yuuji@0
|
12 */
|
yuuji@0
|
13
|
yuuji@0
|
14 /*
|
yuuji@0
|
15 * Program: unANSIify
|
yuuji@0
|
16 *
|
yuuji@0
|
17 * Author: Mark Crispin
|
yuuji@0
|
18 * Networks and Distributed Computing
|
yuuji@0
|
19 * Computing & Communications
|
yuuji@0
|
20 * University of Washington
|
yuuji@0
|
21 * 4545 15th Ave NE
|
yuuji@0
|
22 * Seattle, WA 98105-4527
|
yuuji@0
|
23 * Internet: MRC@CAC.Washington.EDU
|
yuuji@0
|
24 *
|
yuuji@0
|
25 * Date: 1 June 1995
|
yuuji@0
|
26 * Last Edited: 30 August 2006
|
yuuji@0
|
27 */
|
yuuji@0
|
28
|
yuuji@0
|
29
|
yuuji@0
|
30 /* This program is designed to make traditional C sources out of my source
|
yuuji@0
|
31 * files which use ANSI syntax. This program depends heavily upon knowledge
|
yuuji@0
|
32 * of the way I write code, and is not a general purpose tool. I hope that
|
yuuji@0
|
33 * someday someone will provide a general purpose tool...
|
yuuji@0
|
34 */
|
yuuji@0
|
35
|
yuuji@0
|
36 #include <stdio.h>
|
yuuji@0
|
37
|
yuuji@0
|
38 #define LINELENGTH 1000
|
yuuji@0
|
39
|
yuuji@0
|
40
|
yuuji@0
|
41 /* Find first non-whitespace
|
yuuji@0
|
42 * Accepts: string
|
yuuji@0
|
43 * Returns: 0 if no non-whitespace found, or pointer to non-whitespace
|
yuuji@0
|
44 */
|
yuuji@0
|
45
|
yuuji@0
|
46 char *fndnws (s)
|
yuuji@0
|
47 char *s;
|
yuuji@0
|
48 {
|
yuuji@0
|
49 while ((*s == ' ') || (*s == '\t'))
|
yuuji@0
|
50 if ((*s++ == '\n') || !*s) return (char *) 0;
|
yuuji@0
|
51 return s;
|
yuuji@0
|
52 }
|
yuuji@0
|
53
|
yuuji@0
|
54
|
yuuji@0
|
55 /* Find first whitespace
|
yuuji@0
|
56 * Accepts: string
|
yuuji@0
|
57 * Returns: 0 if no whitespace found, or pointer to whitespace
|
yuuji@0
|
58 */
|
yuuji@0
|
59
|
yuuji@0
|
60 char *fndws (s)
|
yuuji@0
|
61 char *s;
|
yuuji@0
|
62 {
|
yuuji@0
|
63 while ((*s != ' ') && (*s != '\t'))
|
yuuji@0
|
64 if ((*s++ == '\n') || !*s) return (char *) 0;
|
yuuji@0
|
65 return s;
|
yuuji@0
|
66 }
|
yuuji@0
|
67
|
yuuji@0
|
68
|
yuuji@0
|
69 /* Find end of commend
|
yuuji@0
|
70 * Accepts: string
|
yuuji@0
|
71 * Returns: -1 if end of comment found, else 0
|
yuuji@0
|
72 */
|
yuuji@0
|
73
|
yuuji@0
|
74 int fndcmt (s)
|
yuuji@0
|
75 char *s;
|
yuuji@0
|
76 {
|
yuuji@0
|
77 while (*s && (*s != '\n'))
|
yuuji@0
|
78 if ((*s++ == '*') && (*s == '/')) return -1;
|
yuuji@0
|
79 return 0;
|
yuuji@0
|
80 }
|
yuuji@0
|
81
|
yuuji@0
|
82 /* Output a line
|
yuuji@0
|
83 * Accepts: string
|
yuuji@0
|
84 */
|
yuuji@0
|
85
|
yuuji@0
|
86 void poot (s)
|
yuuji@0
|
87 char *s;
|
yuuji@0
|
88 {
|
yuuji@0
|
89 if (s) fputs (s,stdout);
|
yuuji@0
|
90 }
|
yuuji@0
|
91
|
yuuji@0
|
92
|
yuuji@0
|
93 /* Skip prefix
|
yuuji@0
|
94 * Accepts: string
|
yuuji@0
|
95 * Returns: updated string
|
yuuji@0
|
96 */
|
yuuji@0
|
97
|
yuuji@0
|
98 char *skipfx (s)
|
yuuji@0
|
99 char *s;
|
yuuji@0
|
100 {
|
yuuji@0
|
101 char c,*t = s,*tt;
|
yuuji@0
|
102 /* skip leading whitespace too */
|
yuuji@0
|
103 while ((*s == ' ') || (*s == '\t')) *s++;
|
yuuji@0
|
104 if (s != t) {
|
yuuji@0
|
105 c = *s; /* save character */
|
yuuji@0
|
106 *s = '\0'; /* tie off prefix */
|
yuuji@0
|
107 poot (t); /* output prefix */
|
yuuji@0
|
108 *s = c; /* restore character */
|
yuuji@0
|
109 }
|
yuuji@0
|
110 /* a typedef? */
|
yuuji@0
|
111 if (((s[0] == 't') && (s[1] == 'y') && (s[2] == 'p') && (s[3] == 'e') &&
|
yuuji@0
|
112 (s[4] == 'd') && (s[5] == 'e') && (s[6] == 'f')) &&
|
yuuji@0
|
113 (t = fndws (s)) && (t = fndnws (t))) {
|
yuuji@0
|
114 if ((t[0] == 'u') && (t[1] == 'n') && (t[2] == 's') && (t[3] == 'i') &&
|
yuuji@0
|
115 (t[4] == 'g') && (t[5] == 'n') && (t[6] == 'e') && (t[7] == 'd') &&
|
yuuji@0
|
116 (tt = fndws (t+7)) && (tt = fndnws (tt))) t = tt;
|
yuuji@0
|
117 c = *t; /* save character */
|
yuuji@0
|
118 *t = '\0'; /* tie off prefix */
|
yuuji@0
|
119 poot (s); /* output prefix */
|
yuuji@0
|
120 *t = c; /* restore character */
|
yuuji@0
|
121 s = t; /* new string pointer */
|
yuuji@0
|
122 }
|
yuuji@0
|
123 /* static with known prefix */
|
yuuji@0
|
124 else if (((s[0] == 's') && (s[1] == 't') && (s[2] == 'a') &&
|
yuuji@0
|
125 (s[3] == 't') && (s[4] == 'i') && (s[5] == 'c') &&
|
yuuji@0
|
126 (s[6] == ' ')) &&
|
yuuji@0
|
127 (((s[7] == 'u') && (s[8] == 'n') && (s[9] == 's') &&
|
yuuji@0
|
128 (s[10] == 'i') && (s[11] == 'g') && (s[12] == 'n') &&
|
yuuji@0
|
129 (s[13] == 'e') && (s[14] == 'd')) ||
|
yuuji@0
|
130 ((s[7] == 's') && (s[8] == 't') && (s[9] == 'r') &&
|
yuuji@0
|
131 (s[10] == 'u') && (s[11] == 'c') && (s[12] == 't')) ||
|
yuuji@0
|
132 ((s[7] == 'd') && (s[8] == 'o')) ||
|
yuuji@0
|
133 ((s[9] == 'e') && (s[10] == 'l') && (s[11] == 's') &&
|
yuuji@0
|
134 (s[12] == 'e'))) &&
|
yuuji@0
|
135 (t = fndws (s)) && (t = fndnws (t)) &&
|
yuuji@0
|
136 (t = fndws (t)) && (t = fndnws (t))) {
|
yuuji@0
|
137 c = *t; /* save character */
|
yuuji@0
|
138 *t = '\0'; /* tie off prefix */
|
yuuji@0
|
139 poot (s); /* output prefix */
|
yuuji@0
|
140 *t = c; /* restore character */
|
yuuji@0
|
141 s = t; /* new string pointer */
|
yuuji@0
|
142 }
|
yuuji@0
|
143 /* one of the known prefixes? */
|
yuuji@0
|
144 else if ((((s[0] == 'u') && (s[1] == 'n') && (s[2] == 's') &&
|
yuuji@0
|
145 (s[3] == 'i') && (s[4] == 'g') && (s[5] == 'n') &&
|
yuuji@0
|
146 (s[6] == 'e') && (s[7] == 'd')) ||
|
yuuji@0
|
147 ((s[0] == 's') && (s[1] == 't') && (s[2] == 'r') &&
|
yuuji@0
|
148 (s[3] == 'u') && (s[4] == 'c') && (s[5] == 't')) ||
|
yuuji@0
|
149 ((s[0] == 's') && (s[1] == 't') && (s[2] == 'a') &&
|
yuuji@0
|
150 (s[3] == 't') && (s[4] == 'i') && (s[5] == 'c')) ||
|
yuuji@0
|
151 ((s[0] == 'd') && (s[1] == 'o')) ||
|
yuuji@0
|
152 ((s[0] == 'e') && (s[1] == 'l') && (s[2] == 's') &&
|
yuuji@0
|
153 (s[3] == 'e'))) &&
|
yuuji@0
|
154 (t = fndws (s)) && (t = fndnws (t))) {
|
yuuji@0
|
155 c = *t; /* save character */
|
yuuji@0
|
156 *t = '\0'; /* tie off prefix */
|
yuuji@0
|
157 poot (s); /* output prefix */
|
yuuji@0
|
158 *t = c; /* restore character */
|
yuuji@0
|
159 s = t; /* new string pointer */
|
yuuji@0
|
160 }
|
yuuji@0
|
161 /* may look like a proto, but isn't */
|
yuuji@0
|
162 else if ((s[0] == 'r') && (s[1] == 'e') && (s[2] == 't') && (s[3] == 'u') &&
|
yuuji@0
|
163 (s[4] == 'r') && (s[5] == 'n')) {
|
yuuji@0
|
164 poot (s);
|
yuuji@0
|
165 return 0;
|
yuuji@0
|
166 }
|
yuuji@0
|
167 return s;
|
yuuji@0
|
168 }
|
yuuji@0
|
169
|
yuuji@0
|
170 /* UnANSI a line
|
yuuji@0
|
171 * Accepts: string
|
yuuji@0
|
172 */
|
yuuji@0
|
173
|
yuuji@0
|
174 void unansi (s)
|
yuuji@0
|
175 char *s;
|
yuuji@0
|
176 {
|
yuuji@0
|
177 char c,*t = s,*u,*v;
|
yuuji@0
|
178 while (t[1] && (t[1] != '\n')) t++;
|
yuuji@0
|
179 switch (*t) {
|
yuuji@0
|
180 case ',': /* continued on next line? */
|
yuuji@0
|
181 /* slurp remainder of line */
|
yuuji@0
|
182 fgets (t + 1,LINELENGTH - (t + 1 - s),stdin);
|
yuuji@0
|
183 unansi (s); /* try again */
|
yuuji@0
|
184 break;
|
yuuji@0
|
185 case ';': /* function prototype? */
|
yuuji@0
|
186 /* yes, tie it off */
|
yuuji@0
|
187 *(fndws (fndnws (fndws (fndnws (s))))) = '\0';
|
yuuji@0
|
188 printf ("%s ();\n",s); /* and output non-ANSI form */
|
yuuji@0
|
189 break;
|
yuuji@0
|
190 case ')':
|
yuuji@0
|
191 *t = '\0'; /* tie off args */
|
yuuji@0
|
192 if (*(t = fndnws (fndws (fndnws (fndws (fndnws (s)))))) == '(') {
|
yuuji@0
|
193 *t++ = '\0'; /* tie off */
|
yuuji@0
|
194 while ((*t == ' ') || (*t == '\t')) t++;
|
yuuji@0
|
195 if ((t[0] == 'v') && (t[1] == 'o') && (t[2] == 'i') && (t[3] == 'd') &&
|
yuuji@0
|
196 !t[4]) *t = '\0'; /* make void be same as null */
|
yuuji@0
|
197 printf ("%s(",s); /* output start of function */
|
yuuji@0
|
198 s = t;
|
yuuji@0
|
199 while (*s) { /* for each argument */
|
yuuji@0
|
200 while ((*s == ' ') || (*s == '\t')) s++;
|
yuuji@0
|
201 for (u = v = s; (*u && (*u != ',') && (*u != '[')); u++)
|
yuuji@0
|
202 if ((*u == ' ') || (*u == '\t')) v = u;
|
yuuji@0
|
203 c = *u; /* remember delimiter */
|
yuuji@0
|
204 *u = '\0'; /* tie off argument name */
|
yuuji@0
|
205 while (*++v == '*'); /* remove leading pointer indication */
|
yuuji@0
|
206 fputs (v,stdout); /* write variable name */
|
yuuji@0
|
207 *(s = u) = c; /* restore delimiter */
|
yuuji@0
|
208 while (*s && (*s != ',')) *s++;
|
yuuji@0
|
209 if (*s) fputc (*s++,stdout);
|
yuuji@0
|
210 }
|
yuuji@0
|
211 puts (")"); /* end of function */
|
yuuji@0
|
212 while (*t) { /* for each argument */
|
yuuji@0
|
213 fputs (" ",stdout);
|
yuuji@0
|
214 while ((*t == ' ') || (*t == '\t')) t++;
|
yuuji@0
|
215 while (*t && (*t != ',')) fputc (*t++,stdout);
|
yuuji@0
|
216 puts (";");
|
yuuji@0
|
217 if (*t == ',') t++;
|
yuuji@0
|
218 }
|
yuuji@0
|
219 }
|
yuuji@0
|
220 else printf ("%s)",s); /* say what?? */
|
yuuji@0
|
221 break;
|
yuuji@0
|
222 default: /* doesn't look like a function */
|
yuuji@0
|
223 poot (s);
|
yuuji@0
|
224 }
|
yuuji@0
|
225 }
|
yuuji@0
|
226
|
yuuji@0
|
227 main ()
|
yuuji@0
|
228 {
|
yuuji@0
|
229 char *s,*t,line[LINELENGTH];
|
yuuji@0
|
230 int c;
|
yuuji@0
|
231 while (s = fgets (line,LINELENGTH,stdin)) switch (line[0]) {
|
yuuji@0
|
232 case '/': /* comment */
|
yuuji@0
|
233 if ((s[1] != '*') || fndcmt (s+2)) poot (line);
|
yuuji@0
|
234 else do poot (line);
|
yuuji@0
|
235 while (!fndcmt (line) && (s = fgets (line,LINELENGTH,stdin)));
|
yuuji@0
|
236 break;
|
yuuji@0
|
237 case '{': /* open function */
|
yuuji@0
|
238 case '}': /* close function */
|
yuuji@0
|
239 case '\f': /* formfeed */
|
yuuji@0
|
240 case '\n': /* newline */
|
yuuji@0
|
241 case '#': /* preprocessor command */
|
yuuji@0
|
242 poot (line);
|
yuuji@0
|
243 break;
|
yuuji@0
|
244 case '\t': /* whitespace */
|
yuuji@0
|
245 case ' ':
|
yuuji@0
|
246 /* look like function arg def in structure? */
|
yuuji@0
|
247 if ((t = skipfx (line)) && (s = fndws (t)) && (s = fndnws (s)) &&
|
yuuji@0
|
248 (((*s == '(') && (s[1] == '*')) ||
|
yuuji@0
|
249 ((*s == '*') && (s[1] == '(') && (s[2] == '*'))) &&
|
yuuji@0
|
250 (s = fndws (s)) && (s[-1] == ')') && (s = fndnws (s)) && (*s == '('))
|
yuuji@0
|
251 unansi (t);
|
yuuji@0
|
252 else poot (t);
|
yuuji@0
|
253 break;
|
yuuji@0
|
254 default: /* begins with anything else */
|
yuuji@0
|
255 /* look like function proto or def? */
|
yuuji@0
|
256 if ((t = skipfx (line)) && (s = fndws (t)) && (s = fndnws (s)) &&
|
yuuji@0
|
257 (s = fndws (s)) && (s = fndnws (s)) && (*s == '('))
|
yuuji@0
|
258 unansi (t);
|
yuuji@0
|
259 else poot (t);
|
yuuji@0
|
260 break;
|
yuuji@0
|
261 }
|
yuuji@0
|
262 }
|