X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=rpcgen_main.c;h=b7970fbb82070c31b8b57c8b9401a0b0adbbd18a;hb=b92428b2c1588d37e8c1eb42a4548fa3524c6b22;hp=6ad467f97c9b35a39838e4494749e877ff3da738;hpb=e9558f1dd242f2eb6a528c5509f1f8911fffe5d7;p=portablexdr.git diff --git a/rpcgen_main.c b/rpcgen_main.c index 6ad467f..b7970fb 100644 --- a/rpcgen_main.c +++ b/rpcgen_main.c @@ -29,26 +29,22 @@ #include "rpcgen_int.h" +enum output_mode output_mode; + static void print_version (void); static void usage (const char *progname); -static void do_rpcgen (const char *filename); +static void do_rpcgen (const char *filename, const char *out); static char *make_cpp_command (const char *filename); -/* Symbols exported from the scanner. */ -extern FILE *yyin, *yyout; -extern int yyparse (void); -extern int yylineno; -extern int yydebug; - int main (int argc, char *argv[]) { int opt; + char *filename; + int output_modes = 0; + char *out = NULL; - /* To enable debugging in the parser, you also need to compile - * with -DYYDEBUG - */ -#if 0 +#if YYDEBUG yydebug = 1; #endif @@ -64,21 +60,34 @@ main (int argc, char *argv[]) /*-- Options supported by any rpcgen that we don't support. --*/ case 'D': case 'T': case 'K': case 'l': case 'm': case 't': case 's': - error ("option '%c' is not supported by this PortableXDR rpcgen.\nYou may need to use an alternative rpcgen program instead.", opt); + error ("option '%c' is not supported by this PortableXDR rpcgen.\n" + "You may need to use an alternative rpcgen program instead.", + opt); /*-- Options supported only by GNU rpcgen that we don't support. --*/ case 'I': case 'n': - error ("option '%c' is not supported by this PortableXDR rpcgen.\nIf you were expecting to use GNU rpcgen, try /usr/bin/rpcgen on a GNU host.", opt); + error ("option '%c' is not supported by this PortableXDR rpcgen.\n" + "If you were expecting to use GNU rpcgen, try /usr/bin/rpcgen on a GNU host.", + opt); /*-- Options supported only by BSD rpcgen that we don't support. --*/ case 'A': case 'M': case 'L': case 'S': - error ("option '%c' is not supported by this PortableXDR rpcgen.\nIf you were expecting to use BSD rpcgen, try /usr/bin/rpcgen on a BSD host.", opt); + error ("option '%c' is not supported by this PortableXDR rpcgen.\n" + "If you were expecting to use BSD rpcgen, try /usr/bin/rpcgen on a BSD host.", + opt); /*-- Options that we do support. --*/ case 'c': + output_modes |= 1 << output_c; + break; + case 'h': + output_modes |= 1 << output_h; + break; + case 'o': - ; + out = optarg; + break; /* None of the other versions of rpcgen support a way to print * the version number, which is extremely annoying because @@ -99,8 +108,25 @@ main (int argc, char *argv[]) if (optind >= argc) error ("expected name of input file after options"); - while (optind < argc) - do_rpcgen (argv[optind++]); + while (optind < argc) { + filename = argv[optind++]; + + if (output_modes == 0) { + output_mode = output_h; + do_rpcgen (filename, out); + output_mode = output_c; + do_rpcgen (filename, out); + } else { + if ((output_modes & (1 << output_h)) != 0) { + output_mode = output_h; + do_rpcgen (filename, out); + } + if ((output_modes & (1 << output_c)) != 0) { + output_mode = output_c; + do_rpcgen (filename, out); + } + } + } exit (0); } @@ -138,16 +164,58 @@ usage (const char *progname) exit (0); } +/* This is a global so the error functions can delete the output file. */ +const char *output_filename = NULL; +int unlink_output_filename; + /* Called for each input file. */ static void -do_rpcgen (const char *filename) +do_rpcgen (const char *filename, const char *out) { - char *cmd; - int r; + char *cmd, *t = NULL; + int r, len; + const char *ext; + + /* Open the output file. */ + switch (output_mode) { + case output_c: ext = ".c"; break; + case output_h: ext = ".h"; break; + default: error ("internal error in do_rpcgen / output_mode"); + } + + if (out && strcmp (out, "-") == 0) { + output_filename = NULL; + unlink_output_filename = 0; + yyout = stdout; + } + else if (out) { + output_filename = out; + unlink_output_filename = 1; + yyout = fopen (output_filename, "w"); + if (yyout == NULL) + perrorf ("%s", output_filename); + } + else { + len = strlen (filename); + t = malloc (len + 3); + if (t == NULL) + perrorf ("malloc"); + strcpy (t, filename); + if (len >= 2 && strcmp (t + len - 2, ".x") == 0) + strcpy (t + len - 2, ext); + else + strcat (t, ext); + output_filename = t; + unlink_output_filename = 1; + yyout = fopen (output_filename, "w"); + if (yyout == NULL) + perrorf ("%s", output_filename); + } free (input_filename); input_filename = NULL; + /* Make the CPP command and open a pipe. */ cmd = make_cpp_command (filename); yyin = popen (cmd, "r"); @@ -155,9 +223,9 @@ do_rpcgen (const char *filename) perrorf ("%s", cmd); free (cmd); - yyout = stdout; + gen_prologue (filename); - /* Parse the input file. This either succeeds or exits with an error. */ + /* Parse the input file, this also generates the output as a side-effect. */ r = yyparse (); pclose (yyin); @@ -166,8 +234,17 @@ do_rpcgen (const char *filename) else if (r == 2) error ("parsing failed because we ran out of memory"); + gen_epilogue (); + + if (yyout != stdout) + fclose (yyout); + output_filename = NULL; + unlink_output_filename = 0; + free (input_filename); input_filename = NULL; + + free (t); } /* Concatenate $EXTCPP and filename, and make sure the filename is @@ -270,6 +347,9 @@ error (const char *fs, ...) { va_list arg; + if (output_filename && unlink_output_filename) + unlink (output_filename); + if (input_filename == NULL) fputs (PACKAGE, stderr); else @@ -291,6 +371,9 @@ perrorf (const char *fs, ...) va_list arg; int e = errno; + if (output_filename && unlink_output_filename) + unlink (output_filename); + if (input_filename == NULL) fputs (PACKAGE, stderr); else