Annotation of src/usr.bin/rpcgen/rpc_util.c, Revision 1.16
1.16 ! deraadt 1: /* $OpenBSD: rpc_util.c,v 1.15 2010/09/01 14:43:34 millert Exp $ */
1.1 deraadt 2: /* $NetBSD: rpc_util.c,v 1.6 1995/08/29 23:05:57 cgd Exp $ */
1.15 millert 3:
1.1 deraadt 4: /*
1.15 millert 5: * Copyright (c) 2010, Oracle America, Inc.
1.1 deraadt 6: *
1.15 millert 7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions are
9: * met:
1.1 deraadt 10: *
1.15 millert 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.
1.1 deraadt 20: *
1.15 millert 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.
1.1 deraadt 33: */
34:
35: /*
1.7 deraadt 36: * rpc_util.c, Utility routines for the RPC protocol compiler
1.1 deraadt 37: */
38: #include <stdio.h>
39: #include <stdlib.h>
40: #include <string.h>
41: #include <ctype.h>
1.7 deraadt 42: #include <unistd.h>
1.1 deraadt 43: #include "rpc_scan.h"
44: #include "rpc_parse.h"
45: #include "rpc_util.h"
46:
47: #define ARGEXT "argument"
48:
1.8 millert 49: static void printwhere(void);
1.1 deraadt 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: /*
1.7 deraadt 67: * Reinitialize the world
1.1 deraadt 68: */
1.7 deraadt 69: void
1.1 deraadt 70: reinitialize()
71: {
72: memset(curline, 0, MAXLINESIZE);
73: where = curline;
74: linenum = 0;
75: defined = NULL;
76: }
77:
78: /*
1.7 deraadt 79: * string equality
1.1 deraadt 80: */
1.7 deraadt 81: int
1.1 deraadt 82: streq(a, b)
83: char *a;
84: char *b;
85: {
86: return (strcmp(a, b) == 0);
87: }
88:
89: /*
1.7 deraadt 90: * find a value in a list
1.1 deraadt 91: */
92: definition *
93: findval(lst, val, cmp)
94: list *lst;
95: char *val;
1.11 deraadt 96: int (*cmp) (definition *, char *);
1.1 deraadt 97: {
1.7 deraadt 98:
1.1 deraadt 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: /*
1.7 deraadt 108: * store a value in a list
1.1 deraadt 109: */
110: void
111: storeval(lstp, val)
112: list **lstp;
113: definition *val;
114: {
115: list **l;
116: list *lst;
117:
1.10 deraadt 118: for (l = lstp; *l != NULL; l = (list **) & (*l)->next)
119: ;
1.1 deraadt 120: lst = ALLOC(list);
1.10 deraadt 121: if (lst == NULL) {
122: fprintf(stderr, "failed in alloc\n");
123: exit(1);
124: }
1.1 deraadt 125: lst->val = val;
126: lst->next = NULL;
127: *l = lst;
128: }
129:
1.7 deraadt 130: static int
1.12 deraadt 131: findit(definition *def, char *type)
1.1 deraadt 132: {
133: return (streq(def->def_name, type));
134: }
135:
136: static char *
1.12 deraadt 137: fixit(char *type, char *orig)
1.1 deraadt 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 *
156: fixtype(type)
157: char *type;
158: {
159: return (fixit(type, type));
160: }
161:
162: char *
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
174: ptype(prefix, type, follow)
175: char *prefix;
176: char *type;
177: int follow;
178: {
179: if (prefix != NULL) {
180: if (streq(prefix, "enum")) {
1.9 deraadt 181: fprintf(fout, "enum ");
1.1 deraadt 182: } else {
1.9 deraadt 183: fprintf(fout, "struct ");
1.1 deraadt 184: }
185: }
186: if (streq(type, "bool")) {
1.9 deraadt 187: fprintf(fout, "bool_t ");
1.1 deraadt 188: } else if (streq(type, "string")) {
1.9 deraadt 189: fprintf(fout, "char *");
1.1 deraadt 190: } else {
1.9 deraadt 191: fprintf(fout, "%s ", follow ? fixtype(type) : type);
1.1 deraadt 192: }
193: }
194:
1.7 deraadt 195: static int
1.12 deraadt 196: typedefed(definition *def, char *type)
1.1 deraadt 197: {
1.10 deraadt 198: if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL)
1.1 deraadt 199: return (0);
1.10 deraadt 200: else
1.1 deraadt 201: return (streq(def->def_name, type));
202: }
203:
1.7 deraadt 204: int
1.1 deraadt 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);
1.10 deraadt 221: if (def == NULL)
1.1 deraadt 222: return (0);
223: type = def->def.ty.old_type;
224: rel = def->def.ty.rel;
225: }
226: }
227: }
228:
229: char *
230: locase(str)
231: char *str;
232: {
233: char c;
234: static char buf[100];
235: char *p = buf;
236:
1.10 deraadt 237: while ((c = *str++))
1.1 deraadt 238: *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
239: *p = 0;
240: return (buf);
241: }
242:
243: void
244: pvname_svc(pname, vnum)
245: char *pname;
246: char *vnum;
247: {
1.9 deraadt 248: fprintf(fout, "%s_%s_svc", locase(pname), vnum);
1.1 deraadt 249: }
250:
251: void
252: pvname(pname, vnum)
253: char *pname;
254: char *vnum;
255: {
1.9 deraadt 256: fprintf(fout, "%s_%s", locase(pname), vnum);
1.1 deraadt 257: }
258:
259: /*
1.7 deraadt 260: * print a useful (?) error message, and then die
1.1 deraadt 261: */
262: void
263: error(msg)
264: char *msg;
265: {
266: printwhere();
1.9 deraadt 267: fprintf(stderr, "%s, line %d: ", infilename, linenum);
268: fprintf(stderr, "%s\n", msg);
1.1 deraadt 269: crash();
270: }
271:
272: /*
273: * Something went wrong, unlink any files that we may have created and then
1.7 deraadt 274: * die.
1.1 deraadt 275: */
1.7 deraadt 276: void
1.1 deraadt 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
288: record_open(file)
289: char *file;
290: {
291: if (nfiles < NFILES) {
292: outfiles[nfiles++] = file;
293: } else {
1.9 deraadt 294: fprintf(stderr, "too many files!\n");
1.1 deraadt 295: crash();
296: }
297: }
298:
299: static char expectbuf[100];
1.12 deraadt 300: static char *toktostr(tok_kind);
1.1 deraadt 301:
302: /*
1.7 deraadt 303: * error, token encountered was not the expected one
1.1 deraadt 304: */
305: void
306: expected1(exp1)
307: tok_kind exp1;
308: {
1.9 deraadt 309: snprintf(expectbuf, sizeof expectbuf, "expected '%s'",
1.10 deraadt 310: toktostr(exp1));
1.1 deraadt 311: error(expectbuf);
312: }
313:
314: /*
1.7 deraadt 315: * error, token encountered was not one of two expected ones
1.1 deraadt 316: */
317: void
318: expected2(exp1, exp2)
319: tok_kind exp1, exp2;
320: {
1.9 deraadt 321: snprintf(expectbuf, sizeof expectbuf, "expected '%s' or '%s'",
1.10 deraadt 322: toktostr(exp1), toktostr(exp2));
1.1 deraadt 323: error(expectbuf);
324: }
325:
326: /*
1.7 deraadt 327: * error, token encountered was not one of 3 expected ones
1.1 deraadt 328: */
329: void
330: expected3(exp1, exp2, exp3)
331: tok_kind exp1, exp2, exp3;
332: {
1.9 deraadt 333: snprintf(expectbuf, sizeof expectbuf, "expected '%s', '%s' or '%s'",
1.10 deraadt 334: toktostr(exp1), toktostr(exp2), toktostr(exp3));
1.1 deraadt 335: error(expectbuf);
336: }
337:
338: void
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 *
1.12 deraadt 386: toktostr(tok_kind kind)
1.1 deraadt 387: {
388: token *sp;
389:
1.10 deraadt 390: for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++)
391: ;
1.1 deraadt 392: return (sp->str);
393: }
394:
1.7 deraadt 395: static void
1.12 deraadt 396: printbuf(void)
1.1 deraadt 397: {
398: char c;
399: int i;
400: int cnt;
401:
402: # define TABSIZE 4
403:
1.7 deraadt 404: for (i = 0; (c = curline[i]); i++) {
1.1 deraadt 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
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:
1.7 deraadt 439: char *
440: make_argname(pname, vname)
1.1 deraadt 441: char *pname;
442: char *vname;
443: {
444: char *name;
1.9 deraadt 445: int len = strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3;
1.7 deraadt 446:
1.9 deraadt 447: name = (char *)malloc(len);
1.1 deraadt 448: if (!name) {
1.10 deraadt 449: fprintf(stderr, "failed in malloc\n");
1.1 deraadt 450: exit(1);
451: }
1.9 deraadt 452: snprintf(name, len, "%s_%s_%s", locase(pname), vname, ARGEXT);
1.1 deraadt 453: return(name);
454: }
455:
456: bas_type *typ_list_h;
457: bas_type *typ_list_t;
458:
459: void
1.10 deraadt 460: add_type(len, type)
1.1 deraadt 461: int len;
462: char *type;
463: {
464: bas_type *ptr;
465:
466: if ((ptr = (bas_type *)malloc(sizeof(bas_type))) == (bas_type *)NULL) {
1.10 deraadt 467: fprintf(stderr, "failed in malloc\n");
1.1 deraadt 468: exit(1);
469: }
470:
1.10 deraadt 471: ptr->name = type;
472: ptr->length = len;
473: ptr->next = NULL;
1.1 deraadt 474: if (typ_list_t == NULL) {
1.10 deraadt 475: typ_list_t = ptr;
476: typ_list_h = ptr;
1.1 deraadt 477: } else {
1.10 deraadt 478: typ_list_t->next = ptr;
479: typ_list_t = ptr;
1.1 deraadt 480: }
481: }
482:
483: bas_type *
484: find_type(type)
485: char *type;
486: {
487: bas_type * ptr;
488:
1.7 deraadt 489: ptr = typ_list_h;
1.1 deraadt 490:
491: while (ptr != NULL) {
1.10 deraadt 492: if (strcmp(ptr->name, type) == 0)
1.1 deraadt 493: return(ptr);
494: else
1.10 deraadt 495: ptr = ptr->next;
1.1 deraadt 496: }
497: return(NULL);
498: }
499: