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