Commit | Line | Data |
---|---|---|
ad787160 C |
1 | /* @(#)rpc_util.c 2.1 88/08/01 4.0 RPCSRC */ |
2 | /* | |
3 | * Sun RPC is a product of Sun Microsystems, Inc. and is provided for | |
4 | * unrestricted use provided that this legend is included on all tape | |
5 | * media and as a part of the software program in whole or part. Users | |
6 | * may copy or modify Sun RPC without charge, but are not authorized | |
7 | * to license or distribute it to anyone else except as part of a product or | |
8 | * program developed by the user. | |
9 | * | |
10 | * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE | |
11 | * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR | |
12 | * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. | |
13 | * | |
14 | * Sun RPC is provided with no support and without any obligation on the | |
15 | * part of Sun Microsystems, Inc. to assist in its use, correction, | |
16 | * modification or enhancement. | |
17 | * | |
18 | * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE | |
19 | * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC | |
20 | * OR ANY PART THEREOF. | |
21 | * | |
22 | * In no event will Sun Microsystems, Inc. be liable for any lost revenue | |
23 | * or profits or other special, indirect and consequential damages, even if | |
24 | * Sun has been advised of the possibility of such damages. | |
25 | * | |
26 | * Sun Microsystems, Inc. | |
27 | * 2550 Garcia Avenue | |
28 | * Mountain View, California 94043 | |
29 | */ | |
30 | #ifndef lint | |
31 | static char sccsid[] = "@(#)rpc_util.c 1.5 87/06/24 (C) 1987 SMI"; | |
32 | #endif | |
33 | ||
34 | /* | |
35 | * rpc_util.c, Utility routines for the RPC protocol compiler | |
36 | * Copyright (C) 1987, Sun Microsystems, Inc. | |
37 | */ | |
38 | #include <stdio.h> | |
39 | #include "rpc_scan.h" | |
40 | #include "rpc_parse.h" | |
41 | #include "rpc_util.h" | |
42 | ||
43 | char curline[MAXLINESIZE]; /* current read line */ | |
44 | char *where = curline; /* current point in line */ | |
45 | int linenum = 0; /* current line number */ | |
46 | ||
47 | char *infilename; /* input filename */ | |
48 | ||
49 | #define NFILES 4 | |
50 | char *outfiles[NFILES]; /* output file names */ | |
51 | int nfiles; | |
52 | ||
53 | FILE *fout; /* file pointer of current output */ | |
54 | FILE *fin; /* file pointer of current input */ | |
55 | ||
56 | list *defined; /* list of defined things */ | |
57 | ||
58 | /* | |
59 | * Reinitialize the world | |
60 | */ | |
61 | reinitialize() | |
62 | { | |
63 | bzero(curline, MAXLINESIZE); | |
64 | where = curline; | |
65 | linenum = 0; | |
66 | defined = NULL; | |
67 | } | |
68 | ||
69 | /* | |
70 | * string equality | |
71 | */ | |
72 | streq(a, b) | |
73 | char *a; | |
74 | char *b; | |
75 | { | |
76 | return (strcmp(a, b) == 0); | |
77 | } | |
78 | ||
79 | /* | |
80 | * find a value in a list | |
81 | */ | |
82 | char * | |
83 | findval(lst, val, cmp) | |
84 | list *lst; | |
85 | char *val; | |
86 | int (*cmp) (); | |
87 | ||
88 | { | |
89 | for (; lst != NULL; lst = lst->next) { | |
90 | if ((*cmp) (lst->val, val)) { | |
91 | return (lst->val); | |
92 | } | |
93 | } | |
94 | return (NULL); | |
95 | } | |
96 | ||
97 | /* | |
98 | * store a value in a list | |
99 | */ | |
100 | void | |
101 | storeval(lstp, val) | |
102 | list **lstp; | |
103 | char *val; | |
104 | { | |
105 | list **l; | |
106 | list *lst; | |
107 | ||
108 | for (l = lstp; *l != NULL; l = (list **) & (*l)->next); | |
109 | lst = ALLOC(list); | |
110 | lst->val = val; | |
111 | lst->next = NULL; | |
112 | *l = lst; | |
113 | } | |
114 | ||
115 | ||
116 | static | |
117 | findit(def, type) | |
118 | definition *def; | |
119 | char *type; | |
120 | { | |
121 | return (streq(def->def_name, type)); | |
122 | } | |
123 | ||
124 | ||
125 | static char * | |
126 | fixit(type, orig) | |
127 | char *type; | |
128 | char *orig; | |
129 | { | |
130 | definition *def; | |
131 | ||
132 | def = (definition *) FINDVAL(defined, type, findit); | |
133 | if (def == NULL || def->def_kind != DEF_TYPEDEF) { | |
134 | return (orig); | |
135 | } | |
136 | switch (def->def.ty.rel) { | |
137 | case REL_VECTOR: | |
138 | return (def->def.ty.old_type); | |
139 | case REL_ALIAS: | |
140 | return (fixit(def->def.ty.old_type, orig)); | |
141 | default: | |
142 | return (orig); | |
143 | } | |
144 | } | |
145 | ||
146 | char * | |
147 | fixtype(type) | |
148 | char *type; | |
149 | { | |
150 | return (fixit(type, type)); | |
151 | } | |
152 | ||
153 | char * | |
154 | stringfix(type) | |
155 | char *type; | |
156 | { | |
157 | if (streq(type, "string")) { | |
158 | return ("wrapstring"); | |
159 | } else { | |
160 | return (type); | |
161 | } | |
162 | } | |
163 | ||
164 | void | |
165 | ptype(prefix, type, follow) | |
166 | char *prefix; | |
167 | char *type; | |
168 | int follow; | |
169 | { | |
170 | if (prefix != NULL) { | |
171 | if (streq(prefix, "enum")) { | |
172 | f_print(fout, "enum "); | |
173 | } else { | |
174 | f_print(fout, "struct "); | |
175 | } | |
176 | } | |
177 | if (streq(type, "bool")) { | |
178 | f_print(fout, "bool_t "); | |
179 | } else if (streq(type, "string")) { | |
180 | f_print(fout, "char *"); | |
181 | } else { | |
182 | f_print(fout, "%s ", follow ? fixtype(type) : type); | |
183 | } | |
184 | } | |
185 | ||
186 | ||
187 | static | |
188 | typedefed(def, type) | |
189 | definition *def; | |
190 | char *type; | |
191 | { | |
192 | if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) { | |
193 | return (0); | |
194 | } else { | |
195 | return (streq(def->def_name, type)); | |
196 | } | |
197 | } | |
198 | ||
199 | isvectordef(type, rel) | |
200 | char *type; | |
201 | relation rel; | |
202 | { | |
203 | definition *def; | |
204 | ||
205 | for (;;) { | |
206 | switch (rel) { | |
207 | case REL_VECTOR: | |
208 | return (!streq(type, "string")); | |
209 | case REL_ARRAY: | |
210 | return (0); | |
211 | case REL_POINTER: | |
212 | return (0); | |
213 | case REL_ALIAS: | |
214 | def = (definition *) FINDVAL(defined, type, typedefed); | |
215 | if (def == NULL) { | |
216 | return (0); | |
217 | } | |
218 | type = def->def.ty.old_type; | |
219 | rel = def->def.ty.rel; | |
220 | } | |
221 | } | |
222 | } | |
223 | ||
224 | ||
225 | static char * | |
226 | locase(str) | |
227 | char *str; | |
228 | { | |
229 | char c; | |
230 | static char buf[100]; | |
231 | char *p = buf; | |
232 | ||
233 | while (c = *str++) { | |
234 | *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c; | |
235 | } | |
236 | *p = 0; | |
237 | return (buf); | |
238 | } | |
239 | ||
240 | ||
241 | void | |
242 | pvname(pname, vnum) | |
243 | char *pname; | |
244 | char *vnum; | |
245 | { | |
246 | f_print(fout, "%s_%s", locase(pname), vnum); | |
247 | } | |
248 | ||
249 | ||
250 | /* | |
251 | * print a useful (?) error message, and then die | |
252 | */ | |
253 | void | |
254 | error(msg) | |
255 | char *msg; | |
256 | { | |
257 | printwhere(); | |
258 | f_print(stderr, "%s, line %d: ", infilename, linenum); | |
259 | f_print(stderr, "%s\n", msg); | |
260 | crash(); | |
261 | } | |
262 | ||
263 | /* | |
264 | * Something went wrong, unlink any files that we may have created and then | |
265 | * die. | |
266 | */ | |
267 | crash() | |
268 | { | |
269 | int i; | |
270 | ||
271 | for (i = 0; i < nfiles; i++) { | |
272 | (void) unlink(outfiles[i]); | |
273 | } | |
274 | exit(1); | |
275 | } | |
276 | ||
277 | ||
278 | void | |
279 | record_open(file) | |
280 | char *file; | |
281 | { | |
282 | if (nfiles < NFILES) { | |
283 | outfiles[nfiles++] = file; | |
284 | } else { | |
285 | f_print(stderr, "too many files!\n"); | |
286 | crash(); | |
287 | } | |
288 | } | |
289 | ||
290 | static char expectbuf[100]; | |
291 | static char *toktostr(); | |
292 | ||
293 | /* | |
294 | * error, token encountered was not the expected one | |
295 | */ | |
296 | void | |
297 | expected1(exp1) | |
298 | tok_kind exp1; | |
299 | { | |
300 | s_print(expectbuf, "expected '%s'", | |
301 | toktostr(exp1)); | |
302 | error(expectbuf); | |
303 | } | |
304 | ||
305 | /* | |
306 | * error, token encountered was not one of two expected ones | |
307 | */ | |
308 | void | |
309 | expected2(exp1, exp2) | |
310 | tok_kind exp1, exp2; | |
311 | { | |
312 | s_print(expectbuf, "expected '%s' or '%s'", | |
313 | toktostr(exp1), | |
314 | toktostr(exp2)); | |
315 | error(expectbuf); | |
316 | } | |
317 | ||
318 | /* | |
319 | * error, token encountered was not one of 3 expected ones | |
320 | */ | |
321 | void | |
322 | expected3(exp1, exp2, exp3) | |
323 | tok_kind exp1, exp2, exp3; | |
324 | { | |
325 | s_print(expectbuf, "expected '%s', '%s' or '%s'", | |
326 | toktostr(exp1), | |
327 | toktostr(exp2), | |
328 | toktostr(exp3)); | |
329 | error(expectbuf); | |
330 | } | |
331 | ||
332 | void | |
333 | tabify(f, tab) | |
334 | FILE *f; | |
335 | int tab; | |
336 | { | |
337 | while (tab--) { | |
338 | (void) fputc('\t', f); | |
339 | } | |
340 | } | |
341 | ||
342 | ||
343 | ||
344 | static token tokstrings[] = { | |
345 | {TOK_IDENT, "identifier"}, | |
346 | {TOK_CONST, "const"}, | |
347 | {TOK_RPAREN, ")"}, | |
348 | {TOK_LPAREN, "("}, | |
349 | {TOK_RBRACE, "}"}, | |
350 | {TOK_LBRACE, "{"}, | |
351 | {TOK_LBRACKET, "["}, | |
352 | {TOK_RBRACKET, "]"}, | |
353 | {TOK_STAR, "*"}, | |
354 | {TOK_COMMA, ","}, | |
355 | {TOK_EQUAL, "="}, | |
356 | {TOK_COLON, ":"}, | |
357 | {TOK_SEMICOLON, ";"}, | |
358 | {TOK_UNION, "union"}, | |
359 | {TOK_STRUCT, "struct"}, | |
360 | {TOK_SWITCH, "switch"}, | |
361 | {TOK_CASE, "case"}, | |
362 | {TOK_DEFAULT, "default"}, | |
363 | {TOK_ENUM, "enum"}, | |
364 | {TOK_TYPEDEF, "typedef"}, | |
365 | {TOK_INT, "int"}, | |
366 | {TOK_SHORT, "short"}, | |
367 | {TOK_LONG, "long"}, | |
368 | {TOK_UNSIGNED, "unsigned"}, | |
369 | {TOK_DOUBLE, "double"}, | |
370 | {TOK_FLOAT, "float"}, | |
371 | {TOK_CHAR, "char"}, | |
372 | {TOK_STRING, "string"}, | |
373 | {TOK_OPAQUE, "opaque"}, | |
374 | {TOK_BOOL, "bool"}, | |
375 | {TOK_VOID, "void"}, | |
376 | {TOK_PROGRAM, "program"}, | |
377 | {TOK_VERSION, "version"}, | |
378 | {TOK_EOF, "??????"} | |
379 | }; | |
380 | ||
381 | static char * | |
382 | toktostr(kind) | |
383 | tok_kind kind; | |
384 | { | |
385 | token *sp; | |
386 | ||
387 | for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++); | |
388 | return (sp->str); | |
389 | } | |
390 | ||
391 | ||
392 | ||
393 | static | |
394 | printbuf() | |
395 | { | |
396 | char c; | |
397 | int i; | |
398 | int cnt; | |
399 | ||
400 | # define TABSIZE 4 | |
401 | ||
402 | for (i = 0; c = curline[i]; i++) { | |
403 | if (c == '\t') { | |
404 | cnt = 8 - (i % TABSIZE); | |
405 | c = ' '; | |
406 | } else { | |
407 | cnt = 1; | |
408 | } | |
409 | while (cnt--) { | |
410 | (void) fputc(c, stderr); | |
411 | } | |
412 | } | |
413 | } | |
414 | ||
415 | ||
416 | static | |
417 | printwhere() | |
418 | { | |
419 | int i; | |
420 | char c; | |
421 | int cnt; | |
422 | ||
423 | printbuf(); | |
424 | for (i = 0; i < where - curline; i++) { | |
425 | c = curline[i]; | |
426 | if (c == '\t') { | |
427 | cnt = 8 - (i % TABSIZE); | |
428 | } else { | |
429 | cnt = 1; | |
430 | } | |
431 | while (cnt--) { | |
432 | (void) fputc('^', stderr); | |
433 | } | |
434 | } | |
435 | (void) fputc('\n', stderr); | |
436 | } |