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