Define USE_NSCD.
[kopensolaris-gnu/glibc.git] / sunrpc / rpc_cout.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 or with the express written consent of
8  * Sun Microsystems, Inc.
9  *
10  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13  *
14  * Sun RPC is provided with no support and without any obligation on the
15  * part of Sun Microsystems, Inc. to assist in its use, correction,
16  * modification or enhancement.
17  *
18  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20  * OR ANY PART THEREOF.
21  *
22  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23  * or profits or other special, indirect and consequential damages, even if
24  * Sun has been advised of the possibility of such damages.
25  *
26  * Sun Microsystems, Inc.
27  * 2550 Garcia Avenue
28  * Mountain View, California  94043
29  */
30
31 /*
32  * From: @(#)rpc_cout.c 1.13 89/02/22 (C) 1987 SMI
33  */
34 char cout_rcsid[] =
35   "$Id$";
36
37 /*
38  * rpc_cout.c, XDR routine outputter for the RPC protocol compiler
39  */
40 #include <ctype.h>
41 #include <stdio.h>
42 #include <string.h>
43 #include "rpc_parse.h"
44 #include "rpc_util.h"
45 #include "proto.h"
46
47 static void emit_enum(definition *def);
48 static void emit_program(const definition *def);
49 static void emit_union(const definition *def);
50 static void emit_struct(definition *def);
51 static void emit_typedef(const definition *def);
52 static int findtype(const definition *def, const char *type);
53 static int undefined(const char *type);
54 static void print_generic_header(const char *procname, int pointerp);
55 static void print_ifopen(int indent, const char *name);
56 static void print_ifarg(const char *arg);
57 static void print_ifsizeof(const char *prefix, const char *type);
58 static void print_ifclose(int indent);
59 static void print_ifstat(int indent, const char *prefix, const char *type,
60                          relation rel, const char *amax,
61                          const char *objname, const char *name);
62 static void print_stat(int indent, const declaration *dec);
63 static void print_header(const definition *def);
64 static void print_trailer(void);
65 static char *upcase(const char *str);
66
67 /*
68  * Emit the C-routine for the given definition
69  */
70 void
71 emit(definition *def)
72 {
73         if (def->def_kind == DEF_CONST) {
74                 return;
75         }
76         if (def->def_kind == DEF_PROGRAM) {
77                 emit_program(def);
78                 return;
79         }
80         if (def->def_kind == DEF_TYPEDEF)
81           {
82           /* now we need to handle declarations like
83                 struct typedef foo foo;
84              since we don't want this to be expanded
85              into 2 calls to xdr_foo */
86
87             if (strcmp(def->def.ty.old_type,def->def_name)==0)
88               return;
89           };
90
91         print_header(def);
92         switch (def->def_kind) {
93         case DEF_UNION:
94                 emit_union(def);
95                 break;
96         case DEF_ENUM:
97                 emit_enum(def);
98                 break;
99         case DEF_STRUCT:
100                 emit_struct(def);
101                 break;
102         case DEF_TYPEDEF:
103                 emit_typedef(def);
104                 break;
105         default:
106                 /* can't happen */
107                 break;
108         }
109         print_trailer();
110 }
111
112 static int
113 findtype(const definition *def, const char *type)
114 {
115         if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) {
116                 return (0);
117         } else {
118                 return (streq(def->def_name, type));
119         }
120 }
121
122 static int
123 undefined(const char *type)
124 {
125         definition *def;
126         def = (definition *) FINDVAL(defined, type, findtype);
127         return (def == NULL);
128 }
129
130
131 static void
132 print_generic_header(const char *procname, int pointerp)
133 {
134         f_print(fout, "\n");
135         f_print(fout, "bool_t\n");
136         if (Cflag) {
137            f_print(fout, "xdr_%s(", procname);
138            f_print(fout, "XDR *xdrs, ");
139            f_print(fout, "%s ", procname);
140            if( pointerp )
141              f_print(fout, "*");
142            f_print(fout, "objp)\n{\n\n");
143         } else {
144           f_print(fout, "xdr_%s(xdrs, objp)\n", procname);
145           f_print(fout, "\tXDR *xdrs;\n");
146           f_print(fout, "\t%s ", procname);
147           if( pointerp )
148             f_print(fout, "*");
149           f_print(fout, "objp;\n{\n\n");
150         }
151 }
152
153 static void
154 print_header(const definition *def)
155 {
156         print_generic_header(def->def_name,
157                              def->def_kind != DEF_TYPEDEF ||
158                              !isvectordef(def->def.ty.old_type,
159                                           def->def.ty.rel));
160
161         /* Now add Inline support */
162
163         if(inlineflag == 0 )
164                 return;
165         /*May cause lint to complain. but  ... */
166         f_print(fout, "\t register long *buf;\n\n");
167 }
168
169 static void
170 print_prog_header(const proc_list *plist)
171 {
172         print_generic_header(plist->args.argname, 1 );
173 }
174
175 static void
176 print_trailer(void)
177 {
178         f_print(fout, "\treturn TRUE;\n");
179         f_print(fout, "}\n");
180 }
181
182
183 static void
184 print_ifopen(int indent, const char *name)
185 {
186         tabify(fout, indent);
187         f_print(fout, " if (!xdr_%s(xdrs", name);
188 }
189
190 static void
191 print_ifarg(const char *arg)
192 {
193         f_print(fout, ", %s", arg);
194 }
195
196 static void
197 print_ifsizeof(const char *prefix, const char *type)
198 {
199         if (streq(type, "bool")) {
200                 f_print(fout, ", sizeof(bool_t), (xdrproc_t)xdr_bool");
201         }
202         else {
203                 f_print(fout, ", sizeof(");
204                 if (undefined(type) && prefix) {
205                         f_print(fout, "%s ", prefix);
206                 }
207                 f_print(fout, "%s), (xdrproc_t)xdr_%s", type, type);
208         }
209 }
210
211 static void
212 print_ifclose(int indent)
213 {
214         f_print(fout, ")) {\n");
215         tabify(fout, indent);
216         f_print(fout, "\t return FALSE;\n");
217         tabify(fout, indent);
218         f_print(fout, " }\n");
219 }
220
221 static void
222 print_ifstat(int indent, const char *prefix, const char *type, relation rel,
223              const char *amax, const char *objname, const char *name)
224 {
225         const char *alt = NULL;
226
227         switch (rel) {
228         case REL_POINTER:
229                 print_ifopen(indent, "pointer");
230                 print_ifarg("(char **)");
231                 f_print(fout, "%s", objname);
232                 print_ifsizeof(prefix, type);
233                 break;
234         case REL_VECTOR:
235                 if (streq(type, "string")) {
236                         alt = "string";
237                 } else if (streq(type, "opaque")) {
238                         alt = "opaque";
239                 }
240                 if (alt) {
241                         print_ifopen(indent, alt);
242                         print_ifarg(objname);
243                 } else {
244                         print_ifopen(indent, "vector");
245                         print_ifarg("(char *)");
246                         f_print(fout, "%s", objname);
247                 }
248                 print_ifarg(amax);
249                 if (!alt) {
250                         print_ifsizeof(prefix, type);
251                 }
252                 break;
253         case REL_ARRAY:
254                 if (streq(type, "string")) {
255                         alt = "string";
256                 } else if (streq(type, "opaque")) {
257                         alt = "bytes";
258                 }
259                 if (streq(type, "string")) {
260                         print_ifopen(indent, alt);
261                         print_ifarg(objname);
262                 } else {
263                         if (alt) {
264                                 print_ifopen(indent, alt);
265                         } else {
266                                 print_ifopen(indent, "array");
267                         }
268                         print_ifarg("(char **)");
269                         if (*objname == '&') {
270                                 f_print(fout, "%s.%s_val, (u_int *)%s.%s_len",
271                                         objname, name, objname, name);
272                         } else {
273                                 f_print(fout, "&%s->%s_val, (u_int *)&%s->%s_len",
274                                         objname, name, objname, name);
275                         }
276                 }
277                 print_ifarg(amax);
278                 if (!alt) {
279                         print_ifsizeof(prefix, type);
280                 }
281                 break;
282         case REL_ALIAS:
283                 print_ifopen(indent, type);
284                 print_ifarg(objname);
285                 break;
286         }
287         print_ifclose(indent);
288 }
289
290 static void
291 emit_enum(definition *def)
292 {
293         (void)def;
294
295         print_ifopen(1, "enum");
296         print_ifarg("(enum_t *)objp");
297         print_ifclose(1);
298 }
299
300 static void
301 emit_program(const definition *def)
302 {
303         decl_list *dl;
304         version_list *vlist;
305         proc_list *plist;
306
307         for (vlist = def->def.pr.versions; vlist != NULL;vlist = vlist->next)
308           for(plist = vlist->procs; plist != NULL; plist = plist->next) {
309                   if (!newstyle || plist->arg_num < 2)
310                     continue; /* old style, or single argument */
311                   print_prog_header(plist);
312                   for (dl = plist->args.decls; dl != NULL;
313                        dl = dl->next)
314                           print_stat(1,&dl->decl);
315                   print_trailer();
316           }
317 }
318
319 static void
320 emit_union(const definition *def)
321 {
322   declaration *dflt;
323   case_list *cl;
324   declaration *cs;
325   char *object;
326   const char *vecformat = "objp->%s_u.%s";
327   const char *format = "&objp->%s_u.%s";
328
329   print_stat(1,&def->def.un.enum_decl);
330   f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name);
331   for (cl = def->def.un.cases; cl != NULL; cl = cl->next) {
332
333     f_print(fout, "\tcase %s:\n", cl->case_name);
334     if(cl->contflag == 1)       /* a continued case statement */
335       continue;
336     cs = &cl->case_decl;
337     if (!streq(cs->type, "void")) {
338       object = alloc(strlen(def->def_name) + strlen(format) +
339                      strlen(cs->name) + 1);
340       if (isvectordef(cs->type, cs->rel)) {
341         s_print(object, vecformat, def->def_name,
342                 cs->name);
343       } else {
344         s_print(object, format, def->def_name,
345                 cs->name);
346       }
347       print_ifstat(2, cs->prefix, cs->type, cs->rel, cs->array_max,
348                    object, cs->name);
349       free(object);
350     }
351     f_print(fout, "\t\tbreak;\n");
352   }
353   dflt = def->def.un.default_decl;
354   if (dflt != NULL) {
355     if (!streq(dflt->type, "void")) {
356       f_print(fout, "\tdefault:\n");
357       object = alloc(strlen(def->def_name) + strlen(format) +
358                      strlen(dflt->name) + 1);
359       if (isvectordef(dflt->type, dflt->rel)) {
360         s_print(object, vecformat, def->def_name,
361                 dflt->name);
362       } else {
363         s_print(object, format, def->def_name,
364                 dflt->name);
365       }
366
367       print_ifstat(2, dflt->prefix, dflt->type, dflt->rel,
368                    dflt->array_max, object, dflt->name);
369       free(object);
370       f_print(fout, "\t\tbreak;\n");
371     }
372 #ifdef __GNU_LIBRARY__
373     else {
374       f_print(fout, "\tdefault:\n");
375       f_print(fout, "\t\tbreak;\n");
376     }
377 #endif
378   } else {
379     f_print(fout, "\tdefault:\n");
380     f_print(fout, "\t\treturn FALSE;\n");
381   }
382
383   f_print(fout, "\t}\n");
384 }
385
386 /* this may be const.  i haven't traced this one through yet. */
387
388 static void
389 emit_struct(definition *def)
390 {
391         decl_list *dl;
392         int i,j,size,flag;
393         decl_list *cur = NULL,*psav;
394         bas_type *ptr;
395         char *sizestr;
396         const char *plus;
397         char ptemp[256];
398         int can_inline;
399
400
401         if(inlineflag  == 0)    {
402                 for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
403                         print_stat(1,&dl->decl);
404         }
405
406         else    {
407
408                 for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
409                         if(dl->decl.rel == REL_VECTOR){
410                                 f_print(fout,"\t int i;\n");
411                                 break;
412                         }
413
414                 size=0;can_inline=0;
415                 for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
416                         if((dl->decl.prefix == NULL) && ((ptr=find_type(dl->decl.type))!= NULL) &&               ((dl->decl.rel == REL_ALIAS)||(dl->decl.rel == REL_VECTOR))){
417
418                                 if(dl->decl.rel == REL_ALIAS)
419                                         size+=ptr->length;
420                                 else {
421                                         can_inline=1;
422                                         break; /* can be inlined */
423                                 };
424                         }
425                         else {
426                                 if(size >= inlineflag){
427                                         can_inline=1;
428                                         break; /* can be inlined */
429                                 }
430                                 size=0;
431                         }
432                 if(size > inlineflag)
433                         can_inline=1;
434
435                 if(can_inline == 0){ /* can not inline, drop back to old mode */
436                         for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
437                                 print_stat(1,&dl->decl);
438                         return;
439                 };
440
441                 flag=PUT;
442                 for(j=0; j<2; j++){
443
444                         if(flag == PUT)
445                                 f_print(fout,"\n\t if (xdrs->x_op == XDR_ENCODE) {\n");
446                         else
447                                 f_print(fout,"\n \t return TRUE;\n\t} else if (xdrs->x_op == XDR_DECODE) {\n");
448
449
450                         i=0;
451                         size=0;
452                         sizestr=NULL;
453                         for (dl = def->def.st.decls; dl != NULL; dl = dl->next) { /* xxx */
454
455                                 /* now walk down the list and check for basic types */
456                                 if((dl->decl.prefix == NULL) && ((ptr=find_type(dl->decl.type))!= NULL) &&               ((dl->decl.rel == REL_ALIAS)||(dl->decl.rel == REL_VECTOR))){
457                                         if(i ==0 )
458                                                 cur=dl;
459                                         i++;
460
461                                         if(dl->decl.rel == REL_ALIAS)
462                                                 size+=ptr->length;
463                                         else {
464                                                 /* this is required to handle arrays */
465
466                                                 if(sizestr == NULL)
467                                                         plus = " ";
468                                                 else
469                                                         plus = "+";
470
471                                                 if(ptr->length != 1)
472                                                         s_print(ptemp," %s %s * %d",plus,dl->decl.array_max,ptr->length);
473                                                 else
474                                                         s_print(ptemp," %s %s ",plus,dl->decl.array_max);
475
476                                                 /*now concatenate to sizestr !!!! */
477                                                 if (sizestr == NULL)
478                                                         sizestr=strdup(ptemp);
479                                                 else{
480                                                         sizestr=realloc(sizestr,strlen(sizestr)+strlen(ptemp)+1);
481                                                         if(sizestr == NULL){
482
483                                                                 f_print(stderr, "Fatal error : no memory \n");
484                                                                 crash();
485                                                         };
486                                                         sizestr=strcat(sizestr,ptemp); /*build up length of array */
487
488                                                 }
489                                         }
490
491                                 }
492                                 else{
493                                         if(i > 0 )
494                                                 if(sizestr == NULL && size < inlineflag){
495                                                         /* don't expand into inline code if size < inlineflag */
496                                                         while(cur != dl){
497                                                                 print_stat(1,&cur->decl);
498                                                                 cur=cur->next;
499                                                         }
500                                                 }
501                                                 else{
502
503
504
505                                                         /* were already looking at a xdr_inlineable structure */
506                                                         if(sizestr == NULL)
507                                                                 f_print(fout,"\t buf = XDR_INLINE(xdrs,%d * BYTES_PER_XDR_UNIT);",
508                                                                         size);
509                                                         else
510                                                                 if(size == 0)
511                                                                         f_print(fout,
512                                                                                 "\t buf = XDR_INLINE(xdrs,%s * BYTES_PER_XDR_UNIT);",
513                                                                                 sizestr);
514                                                                 else
515                                                                         f_print(fout,
516                                                                                 "\t buf = XDR_INLINE(xdrs,(%d + %s)* BYTES_PER_XDR_UNIT);",
517                                                                                 size,sizestr);
518
519                                                         f_print(fout,"\n\t   if (buf == NULL) {\n");
520
521                                                         psav=cur;
522                                                         while(cur != dl){
523                                                                 print_stat(2,&cur->decl);
524                                                                 cur=cur->next;
525                                                         }
526
527                                                         f_print(fout,"\n\t  }\n\t  else {\n");
528
529                                                         cur=psav;
530                                                         while(cur != dl){
531                                                                 emit_inline(&cur->decl,flag);
532                                                                 cur=cur->next;
533                                                         }
534
535                                                         f_print(fout,"\t  }\n");
536                                                 }
537                                         size=0;i=0;sizestr=NULL;
538                                         print_stat(1,&dl->decl);
539                                 }
540
541                         }
542                         if(i > 0 )
543                                 if(sizestr == NULL && size < inlineflag){
544                                         /* don't expand into inline code if size < inlineflag */
545                                         while(cur != dl){
546                                                 print_stat(1,&cur->decl);
547                                                 cur=cur->next;
548                                         }
549                                 }
550                                 else{
551
552                                         /* were already looking at a xdr_inlineable structure */
553                                         if(sizestr == NULL)
554                                                 f_print(fout,"\t\tbuf = XDR_INLINE(xdrs,%d * BYTES_PER_XDR_UNIT);",
555                                                         size);
556                                         else
557                                                 if(size == 0)
558                                                         f_print(fout,
559                                                                 "\t\tbuf = XDR_INLINE(xdrs,%s * BYTES_PER_XDR_UNIT);",
560                                                                 sizestr);
561                                                 else
562                                                         f_print(fout,
563                                                                 "\t\tbuf = XDR_INLINE(xdrs,(%d + %s)* BYTES_PER_XDR_UNIT);",
564                                                                 size,sizestr);
565
566                                         f_print(fout,"\n\t\tif (buf == NULL) {\n");
567
568                                         psav=cur;
569                                         while(cur != NULL){
570                                                 print_stat(2,&cur->decl);
571                                                 cur=cur->next;
572                                         }
573                                         f_print(fout,"\n\t  }\n\t  else {\n");
574
575                                         cur=psav;
576                                         while(cur != dl){
577                                                 emit_inline(&cur->decl,flag);
578                                                 cur=cur->next;
579                                         }
580
581                                         f_print(fout,"\t  }\n");
582
583                                 }
584                         flag=GET;
585                 }
586                 f_print(fout,"\t return TRUE;\n\t}\n\n");
587
588                 /* now take care of XDR_FREE case */
589
590                 for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
591                         print_stat(1,&dl->decl);
592         }
593 }
594
595
596 static void
597 emit_typedef(const definition *def)
598 {
599         const char *prefix = def->def.ty.old_prefix;
600         const char *type = def->def.ty.old_type;
601         const char *amax = def->def.ty.array_max;
602         relation rel = def->def.ty.rel;
603
604
605         print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name);
606 }
607
608 static void
609 print_stat(int indent, const declaration *dec)
610 {
611         const char *prefix = dec->prefix;
612         const char *type = dec->type;
613         const char *amax = dec->array_max;
614         relation rel = dec->rel;
615         char name[256];
616
617         if (isvectordef(type, rel)) {
618                 s_print(name, "objp->%s", dec->name);
619         } else {
620                 s_print(name, "&objp->%s", dec->name);
621         }
622         print_ifstat(indent, prefix, type, rel, amax, name, dec->name);
623 }
624
625
626 void
627 emit_inline(declaration *decl, int flag)
628 {
629
630 /*check whether an array or not */
631
632 switch(decl->rel)
633   {
634  case  REL_ALIAS :
635   emit_single_in_line(decl,flag,REL_ALIAS);
636   break;
637  case REL_VECTOR :
638    f_print(fout,"\t\t{ register %s *genp; \n",decl->type);
639    f_print(fout,"\t\t  for ( i = 0,genp=objp->%s;\n \t\t\ti < %s; i++){\n\t\t",
640            decl->name,decl->array_max);
641   emit_single_in_line(decl,flag,REL_VECTOR);
642     f_print(fout,"\t\t   }\n\t\t };\n");
643
644   default:
645     /* ?... do nothing I guess */
646   }
647 }
648
649 void
650 emit_single_in_line(declaration *decl, int flag, relation rel)
651 {
652         char *upp_case1;
653         const char *upp_case;
654
655         if (flag == PUT) {
656             f_print(fout,"\t\t IXDR_PUT_");
657         }
658         else {
659             if(rel== REL_ALIAS) {
660                 f_print(fout, "\t\t objp->%s = IXDR_GET_", decl->name);
661             }
662             else {
663                 f_print(fout,"\t\t *genp++ = IXDR_GET_");
664             }
665         }
666
667         upp_case1 = upcase(decl->type);
668         upp_case = upp_case1;
669
670         /* hack  - XX */
671         if (!strcmp(upp_case, "INT")) upp_case="LONG";
672         if (!strcmp(upp_case, "U_INT")) upp_case="U_LONG";
673
674         if (flag == PUT) {
675             if (rel==REL_ALIAS) {
676                 f_print(fout,"%s(buf,objp->%s);\n",upp_case,decl->name);
677             }
678             else {
679                 f_print(fout,"%s(buf,*genp++);\n",upp_case);
680             }
681         }
682         else {
683             f_print(fout,"%s(buf);\n",upp_case);
684         }
685
686         free(upp_case1);
687 }
688
689
690 static char *upcase(const char *str) {
691     char *ptr, *hptr;
692     ptr = malloc(strlen(str));
693     if (ptr == NULL) {
694         f_print(stderr,"malloc failed\n");
695         exit(1);
696     }
697     hptr=ptr;
698     while (*str != 0) {
699         *ptr++ = toupper(*str++);
700     }
701     *ptr=0;
702     return hptr;
703 }