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