Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / usr.bin / rpcgen / rpc_hout.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  * @(#)rpc_hout.c 1.12 89/02/22 (C) 1987 SMI
30  */
31
32 #ident  "@(#)rpc_hout.c 1.16    94/04/25 SMI"
33
34 /*
35  * rpc_hout.c, Header file outputter for the RPC protocol compiler
36  * Copyright (C) 1987, Sun Microsystems, Inc.
37  */
38 #include <stdio.h>
39 #include <ctype.h>
40 #include "rpc_parse.h"
41 #include "rpc_util.h"
42
43 void storexdrfuncdecl __P(( char *, int ));
44 static void pconstdef __P(( definition * ));
45 static void pstructdef __P(( definition * ));
46 static void puniondef __P(( definition * ));
47 static void pprogramdef __P(( definition * ));
48 static void pstructdef __P(( definition * ));
49 static void penumdef __P(( definition * ));
50 static void ptypedef __P(( definition * ));
51 static void pdefine __P(( char *, char * ));
52 static int undefined2 __P(( char *, char * ));
53 static void parglist __P(( proc_list *, char * ));
54 static void pprocdef __P(( proc_list *, version_list *, char *, int, int ));
55 void pdeclaration __P(( char *, declaration *, int, char * ));
56
57 static char RESULT[] = "clnt_res";
58
59
60 /*
61  * Print the C-version of an xdr definition
62  */
63 void
64 print_datadef(def)
65         definition *def;
66 {
67
68         if (def->def_kind == DEF_PROGRAM)  /* handle data only */
69                 return;
70
71         if (def->def_kind != DEF_CONST) {
72                 f_print(fout, "\n");
73         }
74         switch (def->def_kind) {
75         case DEF_STRUCT:
76                 pstructdef(def);
77                 break;
78         case DEF_UNION:
79                 puniondef(def);
80                 break;
81         case DEF_ENUM:
82                 penumdef(def);
83                 break;
84         case DEF_TYPEDEF:
85                 ptypedef(def);
86                 break;
87         case DEF_PROGRAM:
88                 pprogramdef(def);
89                 break;
90         case DEF_CONST:
91                 pconstdef(def);
92                 break;
93         }
94         if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) {
95             storexdrfuncdecl(def->def_name,
96                              def->def_kind != DEF_TYPEDEF ||
97                              !isvectordef(def->def.ty.old_type,
98                                           def->def.ty.rel));
99         }
100 }
101
102
103 void
104 print_funcdef(def)
105         definition *def;
106 {
107         switch (def->def_kind) {
108         case DEF_PROGRAM:
109                 f_print(fout, "\n");
110                 pprogramdef(def);
111                 break;
112         default:
113         }
114 }
115
116 /* store away enough information to allow the XDR functions to be spat
117     out at the end of the file */
118
119 void
120 storexdrfuncdecl(name, pointerp)
121 char *name;
122 int pointerp;
123 {
124         xdrfunc * xdrptr;
125
126         xdrptr = (xdrfunc *) malloc(sizeof (struct xdrfunc));
127
128         xdrptr->name = name;
129         xdrptr->pointerp = pointerp;
130         xdrptr->next = NULL;
131
132         if (xdrfunc_tail == NULL){
133                 xdrfunc_head = xdrptr;
134                 xdrfunc_tail = xdrptr;
135         } else {
136                 xdrfunc_tail->next = xdrptr;
137                 xdrfunc_tail = xdrptr;
138         }
139
140
141 }
142
143 void
144 print_xdr_func_def(name, pointerp, i)
145 char* name;
146 int pointerp;
147 int i;
148 {
149         if (i == 2) {
150                 f_print(fout, "extern bool_t xdr_%s();\n", name);
151                 return; 
152         }
153         else  
154                 f_print(fout, "extern  bool_t xdr_%s(XDR *, %s%s);\n", name,
155                         name, pointerp ? "*" : "");
156
157
158 }
159
160
161 static void
162 pconstdef(def)
163         definition *def;
164 {
165         pdefine(def->def_name, def->def.co);
166 }
167
168 /* print out the definitions for the arguments of functions in the
169     header file
170 */
171 static void
172 pargdef(def)
173         definition *def;
174 {
175         decl_list *l;
176         version_list *vers;
177         char *name;
178         proc_list *plist;
179
180
181         for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
182                         for (plist = vers->procs; plist != NULL;
183                             plist = plist->next) {
184
185                                 if (!newstyle || plist->arg_num < 2) {
186                                         continue; /* old style or single args */
187                                 }
188                                 name = plist->args.argname;
189                                 f_print(fout, "struct %s {\n", name);
190                                 for (l = plist->args.decls;
191                                     l != NULL; l = l->next) {
192                                         pdeclaration(name, &l->decl, 1,
193                                                      ";\n");
194                                 }
195                                 f_print(fout, "};\n");
196                                 f_print(fout, "typedef struct %s %s;\n",
197                                         name, name);
198                                 storexdrfuncdecl(name, 1);
199                                 f_print(fout, "\n");
200                         }
201                 }
202 }
203
204
205 static void
206 pstructdef(def)
207         definition *def;
208 {
209         decl_list *l;
210         char *name = def->def_name;
211
212         f_print(fout, "struct %s {\n", name);
213         for (l = def->def.st.decls; l != NULL; l = l->next) {
214                 pdeclaration(name, &l->decl, 1, ";\n");
215         }
216         f_print(fout, "};\n");
217         f_print(fout, "typedef struct %s %s;\n", name, name);
218 }
219
220 static void
221 puniondef(def)
222         definition *def;
223 {
224         case_list *l;
225         char *name = def->def_name;
226         declaration *decl;
227
228         f_print(fout, "struct %s {\n", name);
229         decl = &def->def.un.enum_decl;
230         if (streq(decl->type, "bool")) {
231                 f_print(fout, "\tbool_t %s;\n", decl->name);
232         } else {
233                 f_print(fout, "\t%s %s;\n", decl->type, decl->name);
234         }
235         f_print(fout, "\tunion {\n");
236         for (l = def->def.un.cases; l != NULL; l = l->next) {
237             if (l->contflag == 0)
238                 pdeclaration(name, &l->case_decl, 2, ";\n");
239         }
240         decl = def->def.un.default_decl;
241         if (decl && !streq(decl->type, "void")) {
242                 pdeclaration(name, decl, 2, ";\n");
243         }
244         f_print(fout, "\t} %s_u;\n", name);
245         f_print(fout, "};\n");
246         f_print(fout, "typedef struct %s %s;\n", name, name);
247 }
248
249 static void
250 pdefine(name, num)
251         char *name;
252         char *num;
253 {
254         f_print(fout, "#define\t%s %s\n", name, num);
255 }
256
257 static void
258 puldefine(name, num)
259         char *name;
260         char *num;
261 {
262         f_print(fout, "#define\t%s ((unsigned long)(%s))\n", name, num);
263 }
264
265 static int
266 define_printed(stop, start)
267         proc_list *stop;
268         version_list *start;
269 {
270         version_list *vers;
271         proc_list *proc;
272
273         for (vers = start; vers != NULL; vers = vers->next) {
274                 for (proc = vers->procs; proc != NULL; proc = proc->next) {
275                         if (proc == stop) {
276                                 return (0);
277                         } else if (streq(proc->proc_name, stop->proc_name)) {
278                                 return (1);
279                         }
280                 }
281         }
282         abort();
283         /* NOTREACHED */
284 }
285
286 static void
287 pfreeprocdef(char * name, char *vers, int mode)
288 {
289         f_print(fout, "extern int ");
290         pvname(name, vers);
291         if (mode == 1)
292                 f_print(fout,"_freeresult(SVCXPRT *, xdrproc_t, caddr_t);\n");
293         else
294                 f_print(fout,"_freeresult();\n");
295
296
297 }
298
299 static void
300 pprogramdef(def)
301         definition *def;
302 {
303         version_list *vers;
304         proc_list *proc;
305         int i;
306         char *ext;
307
308         pargdef(def);
309
310         puldefine(def->def_name, def->def.pr.prog_num);
311         for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
312                 if (tblflag) {
313                         f_print(fout,
314                                 "extern struct rpcgen_table %s_%s_table[];\n",
315                                 locase(def->def_name), vers->vers_num);
316                         f_print(fout,
317                                 "extern %s_%s_nproc;\n",
318                                 locase(def->def_name), vers->vers_num);
319                 }
320                 puldefine(vers->vers_name, vers->vers_num);
321
322                 /*
323                  * Print out 2 definitions, one for ANSI-C, another for 
324                  * old K & R C
325                  */
326
327                 if(!Cflag){
328                         ext = "extern  ";
329                         for (proc = vers->procs; proc != NULL;
330                              proc = proc->next) {
331                                 if (!define_printed(proc,
332                                                     def->def.pr.versions)) {
333                                         puldefine(proc->proc_name,
334                                                   proc->proc_num);
335                                 }
336                                 f_print(fout, "%s", ext);
337                                 pprocdef(proc, vers, NULL, 0, 2);
338                                 
339                                 if (mtflag) {
340                                         f_print(fout, "%s", ext);
341                                         pprocdef(proc, vers, NULL, 1, 2);
342                                 }
343                         }
344                         pfreeprocdef(def->def_name, vers->vers_num, 2);
345                         
346                 } else {
347                         for (i = 1; i < 3; i++){
348                                 if (i == 1){
349                                         f_print(fout, "\n#if defined(__STDC__) || defined(__cplusplus)\n");
350                                         ext = "extern  ";
351                                 }else{
352                                         f_print(fout, "\n#else /* K&R C */\n");
353                                         ext = "extern  ";
354                                 }
355
356                                 for (proc = vers->procs; proc != NULL;
357                                      proc = proc->next) {
358                                         if (!define_printed(proc,
359                                                             def->def.pr.versions)) {
360                                                 puldefine(proc->proc_name,
361                                                           proc->proc_num);
362                                         }
363                                         f_print(fout, "%s", ext);
364                                         pprocdef(proc, vers, "CLIENT *", 0, i);
365                                         f_print(fout, "%s", ext);
366                                         pprocdef(proc, vers, "struct svc_req *", 1, i);
367                                 }
368                         pfreeprocdef(def->def_name, vers->vers_num, i);
369                         }
370                         f_print(fout, "#endif /* K&R C */\n");
371                 }
372         }
373 }
374
375 static void
376 pprocdef(proc, vp, addargtype, server_p, mode)
377         proc_list *proc;
378         version_list *vp;
379         char* addargtype;
380         int server_p;
381         int mode;
382 {
383         if (mtflag) {/* Print MT style stubs */
384                 if (server_p)
385                         f_print(fout, "bool_t ");
386                 else
387                         f_print(fout, "enum clnt_stat ");
388         } else {
389                 ptype(proc->res_prefix, proc->res_type, 1);
390                 f_print(fout, "* ");
391         }
392         if (server_p)
393                 pvname_svc(proc->proc_name, vp->vers_num);
394         else
395                 pvname(proc->proc_name, vp->vers_num);
396
397         /*
398          *  mode  1 = ANSI-C, mode 2 = K&R C
399          */
400         if ( mode == 1)
401                 parglist(proc, addargtype);
402         else
403                 f_print(fout, "();\n");
404 }
405
406
407
408 /* print out argument list of procedure */
409 static void
410 parglist(proc, addargtype)
411         proc_list *proc;
412     char* addargtype;
413 {
414         decl_list *dl;
415
416         f_print(fout, "(");
417         if (proc->arg_num < 2 && newstyle &&
418             streq(proc->args.decls->decl.type, "void")) {
419                 /* 0 argument in new style:  do nothing*/
420         }
421         else {
422                 for (dl = proc->args.decls; dl != NULL; dl = dl->next) {
423                         ptype(dl->decl.prefix, dl->decl.type, 1);
424                         if (!newstyle)
425                                 f_print(fout, "*");
426                         /* old style passes by reference */
427                         f_print(fout, ", ");
428                 }
429         }
430
431         if (mtflag)  {
432                 ptype(proc->res_prefix, proc->res_type, 1);
433                 f_print(fout, "*, ");
434         }
435
436         f_print(fout, "%s);\n", addargtype);
437
438 }
439
440 static void
441 penumdef(def)
442         definition *def;
443 {
444         char *name = def->def_name;
445         enumval_list *l;
446         char *last = NULL;
447         int count = 0;
448
449         f_print(fout, "enum %s {\n", name);
450         for (l = def->def.en.vals; l != NULL; l = l->next) {
451                 f_print(fout, "\t%s", l->name);
452                 if (l->assignment) {
453                         f_print(fout, " = %s", l->assignment);
454                         last = l->assignment;
455                         count = 1;
456                 } else {
457                         if (last == NULL) {
458                                 f_print(fout, " = %d", count++);
459                         } else {
460                                 f_print(fout, " = %s + %d", last, count++);
461                         }
462                 }
463                 if (l->next)
464                         f_print(fout, ",\n");
465                 else
466                         f_print(fout, "\n");
467         }
468         f_print(fout, "};\n");
469         f_print(fout, "typedef enum %s %s;\n", name, name);
470 }
471
472 static void
473 ptypedef(def)
474         definition *def;
475 {
476         char *name = def->def_name;
477         char *old = def->def.ty.old_type;
478         char prefix[8]; /* enough to contain "struct ", including NUL */
479         relation rel = def->def.ty.rel;
480
481
482         if (!streq(name, old)) {
483                 if (streq(old, "string")) {
484                         old = "char";
485                         rel = REL_POINTER;
486                 } else if (streq(old, "opaque")) {
487                         old = "char";
488                 } else if (streq(old, "bool")) {
489                         old = "bool_t";
490                 }
491                 if (undefined2(old, name) && def->def.ty.old_prefix) {
492                         s_print(prefix, "%s ", def->def.ty.old_prefix);
493                 } else {
494                         prefix[0] = 0;
495                 }
496                 f_print(fout, "typedef ");
497                 switch (rel) {
498                 case REL_ARRAY:
499                         f_print(fout, "struct {\n");
500                         f_print(fout, "\tu_int %s_len;\n", name);
501                         f_print(fout, "\t%s%s *%s_val;\n", prefix, old, name);
502                         f_print(fout, "} %s", name);
503                         break;
504                 case REL_POINTER:
505                         f_print(fout, "%s%s *%s", prefix, old, name);
506                         break;
507                 case REL_VECTOR:
508                         f_print(fout, "%s%s %s[%s]", prefix, old, name,
509                                 def->def.ty.array_max);
510                         break;
511                 case REL_ALIAS:
512                         f_print(fout, "%s%s %s", prefix, old, name);
513                         break;
514                 }
515                 f_print(fout, ";\n");
516         }
517 }
518
519 void
520 pdeclaration(name, dec, tab, separator)
521         char *name;
522         declaration *dec;
523         int tab;
524         char *separator;
525 {
526         char buf[8];    /* enough to hold "struct ", include NUL */
527         char *prefix;
528         char *type;
529
530         if (streq(dec->type, "void")) {
531                 return;
532         }
533         tabify(fout, tab);
534         if (streq(dec->type, name) && !dec->prefix) {
535                 f_print(fout, "struct ");
536         }
537         if (streq(dec->type, "string")) {
538                 f_print(fout, "char *%s", dec->name);
539         } else {
540                 prefix = "";
541                 if (streq(dec->type, "bool")) {
542                         type = "bool_t";
543                 } else if (streq(dec->type, "opaque")) {
544                         type = "char";
545                 } else {
546                         if (dec->prefix) {
547                                 s_print(buf, "%s ", dec->prefix);
548                                 prefix = buf;
549                         }
550                         type = dec->type;
551                 }
552                 switch (dec->rel) {
553                 case REL_ALIAS:
554                         f_print(fout, "%s%s %s", prefix, type, dec->name);
555                         break;
556                 case REL_VECTOR:
557                         f_print(fout, "%s%s %s[%s]", prefix, type, dec->name,
558                                 dec->array_max);
559                         break;
560                 case REL_POINTER:
561                         f_print(fout, "%s%s *%s", prefix, type, dec->name);
562                         break;
563                 case REL_ARRAY:
564                         f_print(fout, "struct {\n");
565                         tabify(fout, tab);
566                         f_print(fout, "\tu_int %s_len;\n", dec->name);
567                         tabify(fout, tab);
568                         f_print(fout,
569                                 "\t%s%s *%s_val;\n", prefix, type, dec->name);
570                         tabify(fout, tab);
571                         f_print(fout, "} %s", dec->name);
572                         break;
573                 }
574         }
575         f_print(fout, separator);
576 }
577
578 static int
579 undefined2(type, stop)
580         char *type;
581         char *stop;
582 {
583         list *l;
584         definition *def;
585
586         for (l = defined; l != NULL; l = l->next) {
587                 def = (definition *) l->val;
588                 if (def->def_kind != DEF_PROGRAM) {
589                         if (streq(def->def_name, stop)) {
590                                 return (1);
591                         } else if (streq(def->def_name, type)) {
592                                 return (0);
593                         }
594                 }
595         }
596         return (1);
597 }