1 /* $OpenBSD: rpc_util.c,v 1.17 2015/08/20 22:32:41 deraadt Exp $ */
2 /* $NetBSD: rpc_util.c,v 1.6 1995/08/29 23:05:57 cgd Exp $ */
3
4 /*
5 * Copyright (c) 2010, Oracle America, Inc.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials
16 * provided with the distribution.
17 * * Neither the name of the "Oracle America, Inc." nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
28 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 /*
36 * rpc_util.c, Utility routines for the RPC protocol compiler
37 */
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <ctype.h>
42 #include <unistd.h>
43 #include "rpc_scan.h"
44 #include "rpc_parse.h"
45 #include "rpc_util.h"
46
47 #define ARGEXT "argument"
48
49 static void printwhere(void);
50
51 char curline[MAXLINESIZE]; /* current read line */
52 char *where = curline; /* current point in line */
53 int linenum = 0; /* current line number */
54
55 char *infilename; /* input filename */
56
57 #define NFILES 7
58 char *outfiles[NFILES]; /* output file names */
59 int nfiles;
60
61 FILE *fout; /* file pointer of current output */
62 FILE *fin; /* file pointer of current input */
63
64 list *defined; /* list of defined things */
65
66 /*
67 * Reinitialize the world
68 */
69 void
reinitialize()70 reinitialize()
71 {
72 memset(curline, 0, MAXLINESIZE);
73 where = curline;
74 linenum = 0;
75 defined = NULL;
76 }
77
78 /*
79 * string equality
80 */
81 int
streq(a,b)82 streq(a, b)
83 char *a;
84 char *b;
85 {
86 return (strcmp(a, b) == 0);
87 }
88
89 /*
90 * find a value in a list
91 */
92 definition *
findval(lst,val,cmp)93 findval(lst, val, cmp)
94 list *lst;
95 char *val;
96 int (*cmp) (definition *, char *);
97 {
98
99 for (; lst != NULL; lst = lst->next) {
100 if ((*cmp) (lst->val, val)) {
101 return (lst->val);
102 }
103 }
104 return (NULL);
105 }
106
107 /*
108 * store a value in a list
109 */
110 void
storeval(lstp,val)111 storeval(lstp, val)
112 list **lstp;
113 definition *val;
114 {
115 list **l;
116 list *lst;
117
118 for (l = lstp; *l != NULL; l = (list **) & (*l)->next)
119 ;
120 lst = malloc(sizeof(list));
121 if (lst == NULL) {
122 fprintf(stderr, "failed in alloc\n");
123 exit(1);
124 }
125 lst->val = val;
126 lst->next = NULL;
127 *l = lst;
128 }
129
130 static int
findit(definition * def,char * type)131 findit(definition *def, char *type)
132 {
133 return (streq(def->def_name, type));
134 }
135
136 static char *
fixit(char * type,char * orig)137 fixit(char *type, char *orig)
138 {
139 definition *def;
140
141 def = (definition *) FINDVAL(defined, type, findit);
142 if (def == NULL || def->def_kind != DEF_TYPEDEF) {
143 return (orig);
144 }
145 switch (def->def.ty.rel) {
146 case REL_VECTOR:
147 return (def->def.ty.old_type);
148 case REL_ALIAS:
149 return (fixit(def->def.ty.old_type, orig));
150 default:
151 return (orig);
152 }
153 }
154
155 char *
fixtype(type)156 fixtype(type)
157 char *type;
158 {
159 return (fixit(type, type));
160 }
161
162 char *
stringfix(type)163 stringfix(type)
164 char *type;
165 {
166 if (streq(type, "string")) {
167 return ("wrapstring");
168 } else {
169 return (type);
170 }
171 }
172
173 void
ptype(prefix,type,follow)174 ptype(prefix, type, follow)
175 char *prefix;
176 char *type;
177 int follow;
178 {
179 if (prefix != NULL) {
180 if (streq(prefix, "enum")) {
181 fprintf(fout, "enum ");
182 } else {
183 fprintf(fout, "struct ");
184 }
185 }
186 if (streq(type, "bool")) {
187 fprintf(fout, "bool_t ");
188 } else if (streq(type, "string")) {
189 fprintf(fout, "char *");
190 } else {
191 fprintf(fout, "%s ", follow ? fixtype(type) : type);
192 }
193 }
194
195 static int
typedefed(definition * def,char * type)196 typedefed(definition *def, char *type)
197 {
198 if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL)
199 return (0);
200 else
201 return (streq(def->def_name, type));
202 }
203
204 int
isvectordef(type,rel)205 isvectordef(type, rel)
206 char *type;
207 relation rel;
208 {
209 definition *def;
210
211 for (;;) {
212 switch (rel) {
213 case REL_VECTOR:
214 return (!streq(type, "string"));
215 case REL_ARRAY:
216 return (0);
217 case REL_POINTER:
218 return (0);
219 case REL_ALIAS:
220 def = (definition *) FINDVAL(defined, type, typedefed);
221 if (def == NULL)
222 return (0);
223 type = def->def.ty.old_type;
224 rel = def->def.ty.rel;
225 }
226 }
227 }
228
229 char *
locase(str)230 locase(str)
231 char *str;
232 {
233 char c;
234 static char buf[100];
235 char *p = buf;
236
237 while ((c = *str++))
238 *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
239 *p = 0;
240 return (buf);
241 }
242
243 void
pvname_svc(pname,vnum)244 pvname_svc(pname, vnum)
245 char *pname;
246 char *vnum;
247 {
248 fprintf(fout, "%s_%s_svc", locase(pname), vnum);
249 }
250
251 void
pvname(pname,vnum)252 pvname(pname, vnum)
253 char *pname;
254 char *vnum;
255 {
256 fprintf(fout, "%s_%s", locase(pname), vnum);
257 }
258
259 /*
260 * print a useful (?) error message, and then die
261 */
262 void
error(msg)263 error(msg)
264 char *msg;
265 {
266 printwhere();
267 fprintf(stderr, "%s, line %d: ", infilename, linenum);
268 fprintf(stderr, "%s\n", msg);
269 crash();
270 }
271
272 /*
273 * Something went wrong, unlink any files that we may have created and then
274 * die.
275 */
276 void
crash()277 crash()
278 {
279 int i;
280
281 for (i = 0; i < nfiles; i++) {
282 (void) unlink(outfiles[i]);
283 }
284 exit(1);
285 }
286
287 void
record_open(file)288 record_open(file)
289 char *file;
290 {
291 if (nfiles < NFILES) {
292 outfiles[nfiles++] = file;
293 } else {
294 fprintf(stderr, "too many files!\n");
295 crash();
296 }
297 }
298
299 static char expectbuf[100];
300 static char *toktostr(tok_kind);
301
302 /*
303 * error, token encountered was not the expected one
304 */
305 void
expected1(exp1)306 expected1(exp1)
307 tok_kind exp1;
308 {
309 snprintf(expectbuf, sizeof expectbuf, "expected '%s'",
310 toktostr(exp1));
311 error(expectbuf);
312 }
313
314 /*
315 * error, token encountered was not one of two expected ones
316 */
317 void
expected2(exp1,exp2)318 expected2(exp1, exp2)
319 tok_kind exp1, exp2;
320 {
321 snprintf(expectbuf, sizeof expectbuf, "expected '%s' or '%s'",
322 toktostr(exp1), toktostr(exp2));
323 error(expectbuf);
324 }
325
326 /*
327 * error, token encountered was not one of 3 expected ones
328 */
329 void
expected3(exp1,exp2,exp3)330 expected3(exp1, exp2, exp3)
331 tok_kind exp1, exp2, exp3;
332 {
333 snprintf(expectbuf, sizeof expectbuf, "expected '%s', '%s' or '%s'",
334 toktostr(exp1), toktostr(exp2), toktostr(exp3));
335 error(expectbuf);
336 }
337
338 void
tabify(f,tab)339 tabify(f, tab)
340 FILE *f;
341 int tab;
342 {
343 while (tab--) {
344 (void) fputc('\t', f);
345 }
346 }
347
348 static token tokstrings[] = {
349 {TOK_IDENT, "identifier"},
350 {TOK_CONST, "const"},
351 {TOK_RPAREN, ")"},
352 {TOK_LPAREN, "("},
353 {TOK_RBRACE, "}"},
354 {TOK_LBRACE, "{"},
355 {TOK_LBRACKET, "["},
356 {TOK_RBRACKET, "]"},
357 {TOK_STAR, "*"},
358 {TOK_COMMA, ","},
359 {TOK_EQUAL, "="},
360 {TOK_COLON, ":"},
361 {TOK_SEMICOLON, ";"},
362 {TOK_UNION, "union"},
363 {TOK_STRUCT, "struct"},
364 {TOK_SWITCH, "switch"},
365 {TOK_CASE, "case"},
366 {TOK_DEFAULT, "default"},
367 {TOK_ENUM, "enum"},
368 {TOK_TYPEDEF, "typedef"},
369 {TOK_INT, "int"},
370 {TOK_SHORT, "short"},
371 {TOK_LONG, "long"},
372 {TOK_UNSIGNED, "unsigned"},
373 {TOK_DOUBLE, "double"},
374 {TOK_FLOAT, "float"},
375 {TOK_CHAR, "char"},
376 {TOK_STRING, "string"},
377 {TOK_OPAQUE, "opaque"},
378 {TOK_BOOL, "bool"},
379 {TOK_VOID, "void"},
380 {TOK_PROGRAM, "program"},
381 {TOK_VERSION, "version"},
382 {TOK_EOF, "??????"}
383 };
384
385 static char *
toktostr(tok_kind kind)386 toktostr(tok_kind kind)
387 {
388 token *sp;
389
390 for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++)
391 ;
392 return (sp->str);
393 }
394
395 static void
printbuf(void)396 printbuf(void)
397 {
398 char c;
399 int i;
400 int cnt;
401
402 # define TABSIZE 4
403
404 for (i = 0; (c = curline[i]); i++) {
405 if (c == '\t') {
406 cnt = 8 - (i % TABSIZE);
407 c = ' ';
408 } else {
409 cnt = 1;
410 }
411 while (cnt--) {
412 (void) fputc(c, stderr);
413 }
414 }
415 }
416
417 static void
printwhere()418 printwhere()
419 {
420 int i;
421 char c;
422 int cnt;
423
424 printbuf();
425 for (i = 0; i < where - curline; i++) {
426 c = curline[i];
427 if (c == '\t') {
428 cnt = 8 - (i % TABSIZE);
429 } else {
430 cnt = 1;
431 }
432 while (cnt--) {
433 (void) fputc('^', stderr);
434 }
435 }
436 (void) fputc('\n', stderr);
437 }
438
439 char *
make_argname(pname,vname)440 make_argname(pname, vname)
441 char *pname;
442 char *vname;
443 {
444 char *name;
445 int len = strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3;
446
447 name = malloc(len);
448 if (!name) {
449 fprintf(stderr, "failed in malloc\n");
450 exit(1);
451 }
452 snprintf(name, len, "%s_%s_%s", locase(pname), vname, ARGEXT);
453 return(name);
454 }
455
456 bas_type *typ_list_h;
457 bas_type *typ_list_t;
458
459 void
add_type(len,type)460 add_type(len, type)
461 int len;
462 char *type;
463 {
464 bas_type *ptr;
465
466 if ((ptr = malloc(sizeof(bas_type))) == (bas_type *)NULL) {
467 fprintf(stderr, "failed in malloc\n");
468 exit(1);
469 }
470
471 ptr->name = type;
472 ptr->length = len;
473 ptr->next = NULL;
474 if (typ_list_t == NULL) {
475 typ_list_t = ptr;
476 typ_list_h = ptr;
477 } else {
478 typ_list_t->next = ptr;
479 typ_list_t = ptr;
480 }
481 }
482
483 bas_type *
find_type(type)484 find_type(type)
485 char *type;
486 {
487 bas_type * ptr;
488
489 ptr = typ_list_h;
490
491 while (ptr != NULL) {
492 if (strcmp(ptr->name, type) == 0)
493 return(ptr);
494 else
495 ptr = ptr->next;
496 }
497 return(NULL);
498 }
499
500