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