Remove sunrpc compatibility
[openafs.git] / src / rxgen / rpc_main.c
1 /* @(#)rpc_main.c       1.4 87/11/30 3.9 RPCSRC */
2 /*
3  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
4  * unrestricted use provided that this legend is included on all tape
5  * media and as a part of the software program in whole or part.  Users
6  * may copy or modify Sun RPC without charge, but are not authorized
7  * to license or distribute it to anyone else except as part of a product or
8  * program developed by the user.
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  * rpc_main.c, Top level of the RPC protocol compiler.
33  * Copyright (C) 1987, Sun Microsystems, Inc.
34  */
35
36 #include <afsconfig.h>
37 #include <afs/param.h>
38
39 #include <roken.h>
40
41 #include <limits.h>
42 #include <ctype.h>
43
44 #include "rpc_scan.h"
45 #include "rpc_parse.h"
46 #include "rpc_util.h"
47
48 #define EXTEND  1               /* alias for TRUE */
49
50 struct commandline {
51     int ansic_flag;
52     int brief_flag;
53     int cflag;
54     int hflag;
55     int Cflag;
56     int Sflag;
57     int rflag;
58     int kflag;
59     int pflag;
60     int dflag;
61     int xflag;
62     int yflag;
63     int uflag;
64     char *infile;
65     char *outfile;
66 };
67
68 #define MAXCPPARGS      256     /* maximum number of arguments to cpp */
69
70 char *prefix = "";
71 static char *IncludeDir[MAXCPPARGS];
72 int nincludes = 0;
73 char *OutFileFlag = "";
74 char OutFile[256];
75 char Sflag = 0, Cflag = 0, hflag = 0, cflag = 0, kflag = 0, uflag = 0;
76 char ansic_flag = 0;            /* If set, build ANSI C style prototypes */
77 char brief_flag = 0;            /* If set, shorten names */
78 char zflag = 0;                 /* If set, abort server stub if rpc call returns non-zero */
79 char xflag = 0;                 /* if set, add stats code to stubs */
80 char yflag = 0;                 /* if set, only emit function name arrays to xdr file */
81 int debug = 0;
82 static int pclose_fin = 0;
83 static char *cmdname;
84 #ifdef PATH_CPP
85 static char *CPP = PATH_CPP;
86 #else
87 #ifdef AFS_NT40_ENV
88 static char *CPP = "cl /EP /C /nologo";
89 #else
90 static char *CPP = "/lib/cpp";
91 #endif
92 #endif
93
94 /*
95  * Running "cpp" directly on DEC OSF/1 does not define anything; the "cc"
96  * driver is responsible.  To compensate (and allow for other definitions
97  * which should always be passed to "cpp"), place definitions which whould
98  * always be passed to "rxgen" in this string.
99  */
100 static char *CPPFLAGS = "-C"
101 #ifdef  AFS_ALPHA_ENV
102 #ifdef  __alpha
103     " -D__alpha"
104 #endif /* __alpha */
105 #ifdef  OSF
106     " -DOSF"
107 #endif /* OSF */
108 #endif
109 ;
110
111 #include "AFS_component_version_number.c"
112
113 /* static prototypes */
114 static char *extendfile(char *file, char *ext);
115 static void open_output(char *infile, char *outfile);
116 static void open_input(char *infile, char *define);
117 static void c_output(char *infile, char *define, int extend, char *outfile,
118                      int append);
119 static void h_output(char *infile, char *define, int extend, char *outfile,
120                      int append);
121 static int parseargs(int argc, char *argv[], struct commandline *cmd);
122 static void C_output(char *infile, char *define, int extend, char *outfile,
123                      int append);
124 static void S_output(char *infile, char *define, int extend, char *outfile,
125                      int append);
126 static char *uppercase(char *str);
127
128 int
129 main(int argc, char *argv[])
130 {
131     struct commandline cmd;
132     char *ep;
133
134     ep = getenv("RXGEN_CPPCMD");
135     if (ep)
136         CPP = ep;
137 #ifdef  AFS_AIX32_ENV
138     /*
139      * The following signal action for AIX is necessary so that in case of a
140      * crash (i.e. core is generated) we can include the user's data section
141      * in the core dump. Unfortunately, by default, only a partial core is
142      * generated which, in many cases, isn't too useful.
143      */
144     struct sigaction nsa;
145
146     sigemptyset(&nsa.sa_mask);
147     nsa.sa_handler = SIG_DFL;
148     nsa.sa_flags = SA_FULLDUMP;
149     sigaction(SIGSEGV, &nsa, NULL);
150 #endif
151     reinitialize();
152     if (!parseargs(argc, argv, &cmd)) {
153         f_print(stderr, "usage: %s infile\n", cmdname);
154         f_print(stderr,
155                 "       %s [-c | -h | -C | -S | -r | -b | -k | -p | -d | -z | -u] [-Pprefix] [-Idir] [-o outfile] [infile]\n",
156                 cmdname);
157         f_print(stderr, "       %s [-o outfile] [infile]\n",
158                 cmdname);
159         exit(1);
160     }
161     OutFileFlag = cmd.outfile;
162     if (OutFileFlag)
163         strcpy(OutFile, cmd.outfile);
164     if (cmd.cflag) {
165         OutFileFlag = NULL;
166         c_output(cmd.infile, "-DRPC_XDR", !EXTEND, cmd.outfile, 0);
167     } else if (cmd.hflag) {
168         h_output(cmd.infile, "-DRPC_HDR", !EXTEND, cmd.outfile, 0);
169     } else if (cmd.Cflag) {
170         OutFileFlag = NULL;
171         C_output(cmd.infile, "-DRPC_CLIENT", !EXTEND, cmd.outfile, 1);
172     } else if (cmd.Sflag) {
173         OutFileFlag = NULL;
174         S_output(cmd.infile, "-DRPC_SERVER", !EXTEND, cmd.outfile, 1);
175     } else {
176         if (OutFileFlag && (strrchr(OutFile, '.') == NULL))
177             strcat(OutFile, ".");
178         if (cmd.rflag) {
179             C_output((OutFileFlag ? OutFile : cmd.infile), "-DRPC_CLIENT",
180                      EXTEND, ".cs.c", 1);
181             reinitialize();
182             S_output((OutFileFlag ? OutFile : cmd.infile), "-DRPC_SERVER",
183                      EXTEND, ".ss.c", 1);
184             reinitialize();
185         } else {
186             reinitialize();
187             c_output((OutFileFlag ? OutFile : cmd.infile), "-DRPC_XDR",
188                      EXTEND, ".xdr.c", 0);
189             reinitialize();
190             h_output((OutFileFlag ? OutFile : cmd.infile), "-DRPC_HDR",
191                      EXTEND, ".h", 0);
192             reinitialize();
193             C_output((OutFileFlag ? OutFile : cmd.infile), "-DRPC_CLIENT",
194                      EXTEND, ".cs.c", 1);
195             reinitialize();
196             S_output((OutFileFlag ? OutFile : cmd.infile), "-DRPC_SERVER",
197                      EXTEND, ".ss.c", 1);
198             reinitialize();
199         }
200     }
201     if (fin && pclose_fin) {
202         /* the cpp command we called returned a non-zero exit status */
203         if (pclose(fin)) {
204             crash();
205         }
206     }
207     exit(0);
208 }
209
210 /*
211  * add extension to filename
212  */
213 static char *
214 extendfile(char *file, char *ext)
215 {
216     char *res;
217     char *p;
218     char *sname;
219
220     res = alloc(strlen(file) + strlen(ext) + 1);
221     if (res == NULL) {
222         abort();
223     }
224     p = (char *)strrchr(file, '.');
225     if (p == NULL) {
226         p = file + strlen(file);
227     }
228     sname = (char *)strrchr(file, '/');
229     if (sname == NULL)
230         sname = file;
231     else
232         sname++;
233     strcpy(res, sname);
234     strcpy(res + (p - sname), ext);
235     return (res);
236 }
237
238 /*
239  * Open output file with given extension
240  */
241 static void
242 open_output(char *infile, char *outfile)
243 {
244     if (outfile == NULL) {
245         fout = stdout;
246         return;
247     }
248     if (infile != NULL && streq(outfile, infile)) {
249         f_print(stderr, "%s: output would overwrite %s\n", cmdname, infile);
250         crash();
251     }
252     fout = fopen(outfile, "w");
253     if (fout == NULL) {
254         f_print(stderr, "%s: unable to open ", cmdname);
255         perror(outfile);
256         crash();
257     }
258     record_open(outfile);
259 }
260
261 /*
262  * Open input file with given define for C-preprocessor
263  */
264 static void
265 open_input(char *infile, char *define)
266 {
267     char *cpp_cmdline;
268     int i, l = 0;
269
270     if (debug == 0) {
271         infilename = (infile == NULL) ? "<stdin>" : infile;
272         l = strlen(CPP) + strlen(CPPFLAGS) + strlen(define) + 3;
273         for (i = 0; i < nincludes; i++)
274             l += strlen(IncludeDir[i]) + 1;
275         l += strlen(infile) + 1;
276         cpp_cmdline = malloc(l);
277         if (!cpp_cmdline) {
278           perror("Unable to allocate space for cpp command line");
279           crash();
280         }
281
282         sprintf(cpp_cmdline, "%s %s %s", CPP, CPPFLAGS, define);
283         l = strlen(cpp_cmdline);
284         for (i = 0; i < nincludes; i++) {
285             cpp_cmdline[l++] = ' ';
286             strcpy(cpp_cmdline + l, IncludeDir[i]);
287             l += strlen(IncludeDir[i]);
288         }
289         cpp_cmdline[l++] = ' ';
290         strcpy(cpp_cmdline + l, infile);
291
292         fin = popen(cpp_cmdline, "r");
293         if (fin == NULL)
294             perror("popen");
295         pclose_fin = 1;
296
297     } else {
298         if (infile == NULL) {
299             fin = stdin;
300             return;
301         }
302         fin = fopen(infile, "r");
303     }
304     if (fin == NULL) {
305         f_print(stderr, "%s: ", cmdname);
306         perror(infilename);
307         crash();
308     }
309 }
310
311 /*
312  * Compile into an XDR routine output file
313  */
314 static void
315 c_output(char *infile, char *define, int extend, char *outfile, int append)
316 {
317     definition *def;
318     char *include;
319     char *outfilename;
320     long tell;
321     char fullname[1024];
322     char *currfile = (OutFileFlag ? OutFile : infile);
323     int i, j;
324
325     open_input(infile, define);
326     cflag = 1;
327     memset(fullname, 0, sizeof(fullname));
328     if (append) {
329         strcpy(fullname, prefix);
330         strcat(fullname, infile);
331     } else
332         strcpy(fullname, infile);
333     outfilename = extend ? extendfile(fullname, outfile) : outfile;
334     open_output(infile, outfilename);
335     f_print(fout, "/* Machine generated file -- Do NOT edit */\n\n");
336     if (xflag) {
337         if (kflag) {
338             f_print(fout, "#include \"afsconfig.h\"\n");
339             f_print(fout, "#include \"afs/param.h\"\n");
340         } else {
341             f_print(fout, "#include <afsconfig.h>\n");
342             f_print(fout, "#include <afs/param.h>\n");
343             f_print(fout, "#include <roken.h>\n");
344         }
345         f_print(fout, "#ifdef AFS_NT40_ENV\n");
346         f_print(fout, "#define AFS_RXGEN_EXPORT __declspec(dllexport)\n");
347         f_print(fout, "#endif /* AFS_NT40_ENV */\n");
348     }
349     if (currfile && (include = extendfile(currfile, ".h"))) {
350         if (kflag) {
351             f_print(fout, "#include \"%s\"\n\n", include);
352         } else
353             f_print(fout, "#include \"%s\"\n\n", include);
354         free(include);
355     } else {
356         /* In case we can't include the interface's own header file... */
357         if (kflag) {
358             f_print(fout, "#include \"h/types.h\"\n");
359             f_print(fout, "#include \"h/socket.h\"\n");
360             f_print(fout, "#include \"h/file.h\"\n");
361             f_print(fout, "#include \"h/stat.h\"\n");
362             f_print(fout, "#include \"netinet/in.h\"\n");
363             f_print(fout, "#include \"h/time.h\"\n");
364             f_print(fout, "#include \"rx/xdr.h\"\n");
365             f_print(fout, "#include \"afs/rxgen_consts.h\"\n");
366         } else {
367             f_print(fout, "#include <rx/xdr.h>\n");
368         }
369     }
370
371     tell = ftell(fout);
372     while ((def = get_definition())) {
373         if (!yflag) {
374             if ((!IsRxgenDefinition(def)) && def->def_kind != DEF_CUSTOMIZED)
375                 emit(def);
376         }
377     }
378
379     /*
380      * Print out array containing list of all functions in the interface
381      * in order
382      */
383
384     if (xflag) {
385         for (j = 0; j <= PackageIndex; j++) {
386             f_print(fout, "AFS_RXGEN_EXPORT\n");
387             f_print(fout, "const char *%sfunction_names[] = {\n",
388                     PackagePrefix[j]);
389
390             for (i = 0; i < no_of_stat_funcs_header[j]; i++) {
391                 if (i == 0) {
392                     f_print(fout, "\t\"%s\"", function_list[j][i]);
393                 } else {
394                     f_print(fout, ",\n\t\"%s\"", function_list[j][i]);
395                 }
396             }
397
398
399             f_print(fout, "\n};\n");
400         }
401         er_Proc_CodeGeneration();
402     }
403
404     if (extend && tell == ftell(fout)) {
405         (void)unlink(outfilename);
406     }
407     cflag = 0;
408 }
409
410 /*
411  * Compile into an XDR header file
412  */
413 static void
414 h_output(char *infile, char *define, int extend, char *outfile, int append)
415 {
416     definition *def;
417     char *outfilename;
418     long tell;
419     char fullname[1024], *p;
420
421     open_input(infile, define);
422     hflag = 1;
423     memset(fullname, 0, sizeof(fullname));
424     if (append) {
425         strcpy(fullname, prefix);
426         strcat(fullname, infile);
427     } else
428         strcpy(fullname, infile);
429     outfilename = extend ? extendfile(fullname, outfile) : outfile;
430     open_output(infile, outfilename);
431     strcpy(fullname, outfilename);
432     if ((p = strchr(fullname, '.')))
433         *p = '\0';
434     f_print(fout, "/* Machine generated file -- Do NOT edit */\n\n");
435     f_print(fout, "#ifndef      _RXGEN_%s_\n", uppercase(fullname));
436     f_print(fout, "#define      _RXGEN_%s_\n\n", uppercase(fullname));
437     f_print(fout, "#ifdef       KERNEL\n");
438     f_print(fout,
439             "/* The following 'ifndefs' are not a good solution to the vendor's omission of surrounding all system includes with 'ifndef's since it requires that this file is included after the system includes...*/\n");
440     f_print(fout, "#include <afsconfig.h>\n");
441     f_print(fout, "#include \"afs/param.h\"\n");
442     f_print(fout, "#ifdef       UKERNEL\n");
443     f_print(fout, "#include \"afs/sysincludes.h\"\n");
444     f_print(fout, "#include \"rx/xdr.h\"\n");
445     f_print(fout, "#include \"rx/rx.h\"\n");
446     if (xflag) {
447         f_print(fout, "#include \"rx/rx_globals.h\"\n");
448     }
449     if (brief_flag) {
450         f_print(fout, "#include \"rx/rx_opaque.h\"\n");
451     }
452     f_print(fout, "#else        /* UKERNEL */\n");
453     f_print(fout, "#include \"h/types.h\"\n");
454     f_print(fout, "#ifndef      SOCK_DGRAM  /* XXXXX */\n");
455     f_print(fout, "#include \"h/socket.h\"\n");
456     f_print(fout, "#endif\n");
457     f_print(fout, "#ifndef      DTYPE_SOCKET  /* XXXXX */\n");
458     f_print(fout, "#ifndef AFS_LINUX22_ENV\n");
459     f_print(fout, "#include \"h/file.h\"\n");
460     f_print(fout, "#endif\n");
461     f_print(fout, "#endif\n");
462     f_print(fout, "#ifndef      S_IFMT  /* XXXXX */\n");
463     f_print(fout, "#include \"h/stat.h\"\n");
464     f_print(fout, "#endif\n");
465     f_print(fout, "#if defined (AFS_OBSD_ENV) && !defined (MLEN)\n");
466     f_print(fout, "#include \"sys/mbuf.h\"\n");
467     f_print(fout, "#endif\n");
468     f_print(fout, "#ifndef      IPPROTO_UDP /* XXXXX */\n");
469     f_print(fout, "#include \"netinet/in.h\"\n");
470     f_print(fout, "#endif\n");
471     f_print(fout, "#ifndef      DST_USA  /* XXXXX */\n");
472     f_print(fout, "#include \"h/time.h\"\n");
473     f_print(fout, "#endif\n");
474     f_print(fout, "#ifndef AFS_LINUX22_ENV\n");
475     f_print(fout, "#include \"rpc/types.h\"\n");
476     f_print(fout, "#endif /* AFS_LINUX22_ENV */\n");
477     f_print(fout, "#ifndef      XDR_GETLONG /* XXXXX */\n");
478     f_print(fout, "#ifdef AFS_LINUX22_ENV\n");
479     f_print(fout, "#ifndef quad_t\n");
480     f_print(fout, "#define quad_t __quad_t\n");
481     f_print(fout, "#define u_quad_t __u_quad_t\n");
482     f_print(fout, "#endif\n");
483     f_print(fout, "#endif\n");
484     f_print(fout, "#include \"rx/xdr.h\"\n");
485     f_print(fout, "#endif /* XDR_GETLONG */\n");
486     f_print(fout, "#endif   /* UKERNEL */\n");
487     f_print(fout, "#include \"afs/rxgen_consts.h\"\n");
488     f_print(fout, "#include \"afs_osi.h\"\n");
489     f_print(fout, "#include \"rx/rx.h\"\n");
490     if (xflag) {
491         f_print(fout, "#include \"rx/rx_globals.h\"\n");
492     }
493     if (brief_flag) {
494         f_print(fout, "#include \"rx/rx_opaque.h\"\n");
495     }
496     f_print(fout, "#else        /* KERNEL */\n");
497     f_print(fout, "#include <afs/param.h>\n");
498     f_print(fout, "#include <afs/stds.h>\n");
499     f_print(fout, "#include <sys/types.h>\n");
500     f_print(fout, "#include <rx/xdr.h>\n");
501     f_print(fout, "#include <rx/rx.h>\n");
502     if (xflag) {
503         f_print(fout, "#include <rx/rx_globals.h>\n");
504     }
505     if (brief_flag) {
506         f_print(fout, "#include <rx/rx_opaque.h>\n");
507     }
508     f_print(fout, "#include <afs/rxgen_consts.h>\n");
509     if (uflag)
510         f_print(fout, "#include <ubik.h>\n");
511     f_print(fout, "#endif       /* KERNEL */\n\n");
512     f_print(fout, "#ifdef AFS_NT40_ENV\n");
513     f_print(fout, "#ifndef AFS_RXGEN_EXPORT\n");
514     f_print(fout, "#define AFS_RXGEN_EXPORT __declspec(dllimport)\n");
515     f_print(fout, "#endif /* AFS_RXGEN_EXPORT */\n");
516     f_print(fout, "#else /* AFS_NT40_ENV */\n");
517     f_print(fout, "#define AFS_RXGEN_EXPORT\n");
518     f_print(fout, "#endif /* AFS_NT40_ENV */\n\n");
519     tell = ftell(fout);
520     while ((def = get_definition())) {
521         print_datadef(def);
522     }
523     h_Proc_CodeGeneration();
524     h_opcode_stats();
525     hflag = 0;
526     f_print(fout, "#endif       /* _RXGEN_%s_ */\n", uppercase(fullname));
527     if (extend && tell == ftell(fout)) {
528         (void)unlink(outfilename);
529     }
530 }
531
532 static void
533 C_output(char *infile, char *define, int extend, char *outfile, int append)
534 {
535     char *include;
536     char *outfilename;
537     char fullname[1024];
538     long tell;
539     char *currfile = (OutFileFlag ? OutFile : infile);
540
541     Cflag = 1;
542     open_input(infile, define);
543     memset(fullname, 0, sizeof(fullname));
544     if (append) {
545         strcpy(fullname, prefix);
546         strcat(fullname, infile);
547     } else
548         strcpy(fullname, infile);
549     outfilename = extend ? extendfile(fullname, outfile) : outfile;
550     open_output(infile, outfilename);
551     f_print(fout, "/* Machine generated file -- Do NOT edit */\n\n");
552     if (currfile && (include = extendfile(currfile, ".h"))) {
553         if (kflag) {
554             f_print(fout, "#include \"%s\"\n\n", include);
555         } else {
556             f_print(fout, "#include <afsconfig.h>\n");
557             f_print(fout, "#include <afs/param.h>\n");
558             f_print(fout, "#include <roken.h>\n");
559             f_print(fout, "#include <afs/opr.h>\n");
560             f_print(fout, "#ifdef AFS_PTHREAD_ENV\n");
561             f_print(fout, "# include <opr/lock.h>\n");
562             f_print(fout, "#endif\n");
563             f_print(fout, "#include \"%s\"\n\n", include);
564         }
565         free(include);
566     } else {
567         if (kflag) {
568             f_print(fout, "#include \"h/types.h\"\n");
569             f_print(fout, "#include \"h/socket.h\"\n");
570             f_print(fout, "#include \"h/file.h\"\n");
571             f_print(fout, "#include \"h/stat.h\"\n");
572             f_print(fout, "#include \"netinet/in.h\"\n");
573             f_print(fout, "#include \"h/time.h\"\n");
574             f_print(fout, "#include \"rpc/types.h\"\n");
575             f_print(fout, "#include \"rx/xdr.h\"\n");
576             f_print(fout, "#include \"afs/rxgen_consts.h\"\n");
577             f_print(fout, "#include \"afs/afs_osi.h\"\n");
578             f_print(fout, "#include \"rx/rx.h\"\n");
579             if (xflag) {
580                 f_print(fout, "#include \"rx/rx_globals.h\"\n");
581             }
582             if (brief_flag) {
583                 f_print(fout, "#include \"rx/rx_opaque.h\"\n");
584             }
585         } else {
586             f_print(fout, "#include <sys/types.h>\n");
587             f_print(fout, "#include <rx/xdr.h>\n");
588             f_print(fout, "#include <rx/rx.h>\n");
589             if (xflag) {
590                 f_print(fout, "#include <rx/rx_globals.h>\n");
591             }
592             if (brief_flag) {
593                 f_print(fout, "#include <rx/rx_opaque.h\"\n");
594             }
595             f_print(fout, "#include <afs/rxgen_consts.h>\n");
596         }
597     }
598
599     tell = ftell(fout);
600     while (get_definition())
601         continue;
602     if (extend && tell == ftell(fout)) {
603         (void)unlink(outfilename);
604     }
605
606     Cflag = 0;
607 }
608
609 static void
610 S_output(char *infile, char *define, int extend, char *outfile, int append)
611 {
612     char *include;
613     char *outfilename;
614     char fullname[1024];
615     definition *def;
616     long tell;
617     char *currfile = (OutFileFlag ? OutFile : infile);
618
619     Sflag = 1;
620     open_input(infile, define);
621     memset(fullname, 0, sizeof(fullname));
622     if (append) {
623         strcpy(fullname, prefix);
624         strcat(fullname, infile);
625     } else
626         strcpy(fullname, infile);
627     outfilename = extend ? extendfile(fullname, outfile) : outfile;
628     open_output(infile, outfilename);
629     f_print(fout, "/* Machine generated file -- Do NOT edit */\n\n");
630     if (currfile && (include = extendfile(currfile, ".h"))) {
631         if (kflag) {
632             f_print(fout, "#include \"%s\"\n", include);
633         } else {
634             f_print(fout, "#include <afsconfig.h>\n");
635             f_print(fout, "#include <afs/param.h>\n");
636             f_print(fout, "#include <roken.h>\n");
637             f_print(fout, "#include \"%s\"\n\n", include);
638         }
639         free(include);
640     } else {
641         if (kflag) {
642             f_print(fout, "#include \"h/types.h\"\n");
643             f_print(fout, "#include \"h/socket.h\"\n");
644             f_print(fout, "#include \"h/file.h\"\n");
645             f_print(fout, "#include \"h/stat.h\"\n");
646             f_print(fout, "#include \"netinet/in.h\"\n");
647             f_print(fout, "#include \"h/time.h\"\n");
648             f_print(fout, "#include \"rpc/types.h\"\n");
649             f_print(fout, "#include \"rx/xdr.h\"\n");
650             f_print(fout, "#include \"afs/rxgen_consts.h\"\n");
651             f_print(fout, "#include \"afs/afs_osi.h\"\n");
652             f_print(fout, "#include \"rx/rx.h\"\n");
653             if (xflag) {
654                 f_print(fout, "#include \"rx/rx_globals.h\"\n");
655             }
656             if (brief_flag) {
657                 f_print(fout, "#include \"rx/rx_opaque.h\"\n");
658             }
659         } else {
660             f_print(fout, "#include <sys/types.h>\n");
661             f_print(fout, "#include <rx/xdr.h>\n");
662             f_print(fout, "#include <rx/rx.h>\n");
663             if (xflag) {
664                 f_print(fout, "#include <rx/rx_globals.h>\n");
665             }
666             if (brief_flag) {
667                 f_print(fout, "#include <rx/rx_opaque.h>\n");
668             }
669             f_print(fout, "#include <afs/rxgen_consts.h>\n");
670         }
671     }
672
673     tell = ftell(fout);
674     fflush(fout);
675     while ((def = get_definition())) {
676         fflush(fout);
677         print_datadef(def);
678     }
679
680     er_Proc_CodeGeneration();
681
682     if (extend && tell == ftell(fout)) {
683         (void)unlink(outfilename);
684     }
685     Sflag = 0;
686 }
687
688 static char *
689 uppercase(char *str)
690 {
691     static char max_size[100];
692     char *pnt;
693     int len = (int)strlen(str);
694
695     for (pnt = max_size; len > 0; len--, str++) {
696         *pnt++ = (islower(*str) ? toupper(*str) : *str);
697     }
698     *pnt = '\0';
699     return max_size;
700 }
701
702 /*
703  * Parse command line arguments
704  */
705 static int
706 parseargs(int argc, char *argv[], struct commandline *cmd)
707 {
708     int i;
709     int j;
710     char c;
711     char flag[(1 << (8 * sizeof(char)))];
712     int nflags;
713
714     cmdname = argv[0];
715     cmd->infile = cmd->outfile = NULL;
716     if (argc < 2) {
717         return (0);
718     }
719     memset(flag, 0, sizeof(flag));
720     cmd->outfile = NULL;
721     for (i = 1; i < argc; i++) {
722         if (argv[i][0] != '-') {
723             if (cmd->infile) {
724                 return (0);
725             }
726             cmd->infile = argv[i];
727         } else {
728             for (j = 1; argv[i][j] != 0; j++) {
729                 c = argv[i][j];
730                 switch (c) {
731                 case 'A':
732                 case 'c':
733                 case 'h':
734                 case 'C':
735                 case 'S':
736                 case 'b':
737                 case 'r':
738                 case 'k':
739                 case 'p':
740                 case 'd':
741                 case 'u':
742                 case 'x':
743                 case 'y':
744                 case 'z':
745                     if (flag[(int)c]) {
746                         return (0);
747                     }
748                     flag[(int)c] = 1;
749                     break;
750                 case 'o':
751                     if (argv[i][j - 1] != '-' || argv[i][j + 1] != 0) {
752                         return (0);
753                     }
754                     flag[(int)c] = 1;
755                     if (++i == argc) {
756                         return (0);
757                     }
758                     if (cmd->outfile) {
759                         return (0);
760                     }
761                     cmd->outfile = argv[i];
762                     goto nextarg;
763                 case 'P':
764                     if (argv[i][j - 1] != '-')
765                         return (0);
766                     prefix = &argv[i][j + 1];
767                     goto nextarg;
768                 case 'I':
769                     if (nincludes >= MAXCPPARGS) {
770                         f_print(stderr, "Too many -I arguments\n");
771                         return (0);
772                     }
773                     if (argv[i][j - 1] != '-')
774                         return (0);
775                     IncludeDir[nincludes++] = &argv[i][j - 1];
776                     goto nextarg;
777                 default:
778                     return (0);
779                 }
780             }
781           nextarg:
782             ;
783         }
784     }
785     cmd->ansic_flag = ansic_flag = flag['A'];
786     cmd->brief_flag = brief_flag = flag['b'];
787     cmd->cflag = cflag = flag['c'];
788     cmd->hflag = hflag = flag['h'];
789     cmd->xflag = xflag = flag['x'];
790     cmd->yflag = yflag = flag['y'];
791     cmd->Cflag = Cflag = flag['C'];
792     cmd->Sflag = Sflag = flag['S'];
793     cmd->rflag = flag['r'];
794     cmd->uflag = uflag = flag['u'];
795     cmd->kflag = kflag = flag['k'];
796     cmd->pflag = flag['p'];
797     cmd->dflag = debug = flag['d'];
798     zflag = flag['z'];
799     if (cmd->pflag)
800         combinepackages = 1;
801     nflags =
802         cmd->cflag + cmd->hflag + cmd->Cflag + cmd->Sflag + cmd->rflag;
803     if (nflags == 0) {
804         if (cmd->outfile != NULL || cmd->infile == NULL) {
805             return (0);
806         }
807     } else if (nflags > 1) {
808         return (0);
809     }
810     return (1);
811 }