config.guess
config.sub
depcomp
-*.loT
\ No newline at end of file
+*.loT
+portable-rpcgen
+remote_protocol.x
+rpcgen_parse.c
+rpcgen_parse.h
+rpcgen_scan.c
rpc/rpc.h rpc/types.h rpc/xdr.h
libportablexdr_la_CFLAGS = -Wall -Werror -fno-strict-aliasing
libportablexdr_la_LDFLAGS = @MINGW_EXTRA_LDFLAGS@
+
+# Replacement 'rpcgen'. Don't call it 'rpcgen' however so that
+# we can avoid conflicting with the system rpcgen.
+BUILT_SOURCES = rpcgen_parse.h
+AM_YFLAGS = -d
+bin_PROGRAMS = portable-rpcgen
+portable_rpcgen_SOURCES = rpcgen_parse.y rpcgen_scan.l \
+ rpcgen_int.h rpcgen_main.c
+portable_rpcgen_CFLAGS = -Wall
+#portable_rpcgen_CFLAGS += -DYYDEBUG
-AC_INIT([portablexdr], [4.0.11])
+AC_INIT(portablexdr, 5.0.0)
AM_INIT_AUTOMAKE
AC_CONFIG_HEADERS([config.h])
AC_CANONICAL_HOST
AC_PROG_CC
-AC_CHECK_PROGS([AR], [ar])
+AC_CHECK_PROGS(AR, ar)
AC_PROG_INSTALL
AC_PROG_LIBTOOL
+AC_PROG_LEX
+AC_PROG_YACC
+
+dnl Look for an external 'cpp' program which can run on a file with any
+dnl extension. The normal CPP can only run on files with a '.c'
+dnl extension, therefore we prefer to use /usr/bin/cpp if it exists.
+AC_PATH_PROG([EXTCPP], [cpp], [no])
+if test "x$EXTCPP" = "xno"; then
+ AC_MSG_FAILURE([Cannot find a working 'cpp' (C preprocessor) program])
+fi
+AC_DEFINE_UNQUOTED([EXTCPP], ["$EXTCPP"],
+ [The C preprocessor command (may include command line options).])
+
MINGW_EXTRA_LDFLAGS=
case "$host" in
*-*-mingw*)
MINGW_EXTRA_LDFLAGS="-no-undefined"
;;
esac
-AC_SUBST([MINGW_EXTRA_LDFLAGS])
+AC_SUBST(MINGW_EXTRA_LDFLAGS)
AC_CHECK_HEADERS([arpa/inet.h sys/param.h])
AC_CHECK_FUNCS([ntohl htonl ntohs htons])
-AC_OUTPUT([Makefile])
+AC_OUTPUT(Makefile)
+
--- /dev/null
+/* -*- C -*-
+ * rpcgen - Generate XDR bindings automatically.
+ * Copyright (C) 2008 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef RPCGEN_INT_H
+#define RPCGEN_INT_H
+
+extern char *input_filename;
+
+/* Global functions used by the scanner. */
+extern void start_string (void);
+extern char *end_string (void);
+extern void add_char (int);
+extern void add_string (const char *);
+
+/* These functions print an error and then exit. */
+extern void error (const char *, ...)
+ __attribute__((noreturn, format(printf,1,2)));
+extern void perrorf (const char *, ...)
+ __attribute__((noreturn, format(printf,1,2)));
+
+#endif /* RPCGEN_INT_H */
--- /dev/null
+/* -*- C -*-
+ * rpcgen - Generate XDR bindings automatically.
+ * Copyright (C) 2008 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include "rpcgen_int.h"
+
+static void print_version (void);
+static void usage (const char *progname);
+static void do_rpcgen (const char *filename);
+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;
+
+ /* To enable debugging in the parser, you also need to compile
+ * with -DYYDEBUG
+ */
+#if 0
+ yydebug = 1;
+#endif
+
+ /* Note on command line arguments: We only support a small subset
+ * of command line arguments, because of the reduced functionality
+ * available in this version of rpcgen. However we accept the
+ * command line parameters from both GNU rpcgen and BSD rpcgen
+ * and print appropriate errors for any we don't understand.
+ */
+ while ((opt = getopt (argc, argv, "AD:IK:LMSTVchlmno:s:t")) != -1) {
+ switch (opt)
+ {
+ /*-- 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);
+
+ /*-- 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);
+
+ /*-- 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);
+
+ /*-- Options that we do support. --*/
+ case 'c':
+ case 'h':
+ case 'o':
+ ;
+
+ /* None of the other versions of rpcgen support a way to print
+ * the version number, which is extremely annoying because
+ * there are so many different variations of rpcgen around.
+ * So this option at least should be useful!
+ */
+ case 'V':
+ print_version ();
+ exit (0);
+
+ /*-- Usage case. --*/
+ default:
+ usage (argv[0]);
+ exit (1);
+ }
+ }
+
+ if (optind >= argc)
+ error ("expected name of input file after options");
+
+ while (optind < argc)
+ do_rpcgen (argv[optind++]);
+
+ exit (0);
+}
+
+static void
+print_version (void)
+{
+ printf ("PortableXDR rpcgen %s\n", PACKAGE_VERSION);
+}
+
+static void
+usage (const char *progname)
+{
+ print_version ();
+ printf
+ ("Generate XDR bindings automatically.\n"
+ "\n"
+ "Usage:\n"
+ " portable-rpcgen infile.x\n"
+ " portable-rpcgen -c|-h [-o outfile] infile.x\n"
+ " portable-rpcgen -V\n"
+ "\n"
+ "Options:\n"
+ " -c Generate C output file only.\n"
+ " -h Generate header output file only.\n"
+ " -o Name of output file (normally it is 'infile.[ch]').\n"
+ " -V Print the version and exit.\n"
+ "\n"
+ "In the first form, without -c or -h, we generate both output files.\n"
+ "\n"
+ "You can also list more than one input file on the command line, in\n"
+ "which case each input file is processed separately.\n"
+ "\n"
+ );
+ exit (0);
+}
+
+/* Called for each input file. */
+static void
+do_rpcgen (const char *filename)
+{
+ char *cmd;
+ int r;
+
+ free (input_filename);
+ input_filename = NULL;
+
+ cmd = make_cpp_command (filename);
+
+ yyin = popen (cmd, "r");
+ if (yyin == NULL)
+ perrorf ("%s", cmd);
+ free (cmd);
+
+ yyout = stdout;
+
+ /* Parse the input file. This either succeeds or exits with an error. */
+ r = yyparse ();
+ pclose (yyin);
+
+ if (r == 1)
+ error ("parsing failed, file is not a valid rpcgen input");
+ else if (r == 2)
+ error ("parsing failed because we ran out of memory");
+
+ free (input_filename);
+ input_filename = NULL;
+}
+
+/* Concatenate $EXTCPP and filename, and make sure the filename is
+ * quoted correctly. Tedious.
+ */
+static char *
+make_cpp_command (const char *filename)
+{
+ static const char good[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-.";
+#define is_good(c) (strchr (good, (c)) != NULL)
+ const char *p;
+
+ /* We can use start_string etc. because this function is only used
+ * outside the scanner.
+ */
+ start_string ();
+ add_string (EXTCPP);
+ add_char (' ');
+
+ for (p = filename; *p; p++) {
+ if (is_good (*p)) add_char (*p);
+ else {
+ add_char ('\\');
+ add_char (*p);
+ }
+ }
+
+ return end_string ();
+}
+
+/* Some fairly random functions which are used by the scanner for
+ * constructing strings, reporting errors, etc.
+ */
+
+/* The scanner sets this to the name of the input file (from cpp)
+ * if known.
+ */
+char *input_filename = NULL;
+
+static char *str = NULL;
+static int str_used, str_alloc;
+
+void
+start_string (void)
+{
+ if (str != NULL)
+ error ("scanner called start_string without calling end_string");
+
+ str_alloc = 128;
+ str_used = 0;
+ str = malloc (str_alloc);
+ if (!str) perrorf ("malloc");
+}
+
+char *
+end_string (void)
+{
+ char *s;
+
+ if (str == NULL)
+ error ("scanner called end_string without calling start_string");
+
+ s = realloc (str, str_used+1);
+ if (!s) perrorf ("realloc");
+
+ str = NULL;
+ s[str_used] = '\0';
+ return s;
+}
+
+void
+add_char (int c)
+{
+ str_used++;
+ while (str_used >= str_alloc) {
+ str_alloc <<= 1;
+ str = realloc (str, str_alloc);
+ if (!str) perrorf ("realloc");
+ }
+ str[str_used-1] = c;
+}
+
+void
+add_string (const char *s)
+{
+ int i = str_used;
+ int len = strlen (s);
+
+ str_used += len;
+ while (str_used >= str_alloc) {
+ str_alloc <<= 1;
+ str = realloc (str, str_alloc);
+ if (!str) perrorf ("realloc");
+ }
+ memcpy (str+i, s, len);
+}
+
+void
+error (const char *fs, ...)
+{
+ va_list arg;
+
+ if (input_filename == NULL)
+ fputs (PACKAGE, stderr);
+ else
+ fprintf (stderr, "%s:%d", input_filename, yylineno);
+ fputs (": ", stderr);
+
+ va_start (arg, fs);
+ vfprintf (stderr, fs, arg);
+ va_end (arg);
+
+ fputc ('\n', stderr);
+
+ exit (1);
+}
+
+void
+perrorf (const char *fs, ...)
+{
+ va_list arg;
+ int e = errno;
+
+ if (input_filename == NULL)
+ fputs (PACKAGE, stderr);
+ else
+ fprintf (stderr, "%s:%d", input_filename, yylineno);
+ fputs (": ", stderr);
+
+ va_start (arg, fs);
+ vfprintf (stderr, fs, arg);
+ va_end (arg);
+
+ fputs (": ", stderr);
+ errno = e;
+ perror (NULL);
+
+ exit (1);
+}
--- /dev/null
+/* rpcgen - Generate XDR bindings automatically. -*- text -*-
+ * Copyright (C) 2008 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+%{
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "rpcgen_int.h"
+
+extern void yyerror (const char *str);
+%}
+
+%union {
+ char *str;
+}
+
+%type <str> const
+
+%token STRUCT
+%token ENUM
+%token CONST
+%token TYPEDEF
+%token UNION
+%token SWITCH
+%token CASE
+%token DEFAULT
+%token PROGRAM
+
+%token UNSIGNED
+%token SIGNED
+%token CHAR
+%token SHORT
+%token INT
+%token HYPER
+%token DOUBLE
+%token STRING
+%token OPAQUE
+
+/* This is sometimes lumped together with the other types, but
+ * the special keyword void can only occur after "default:" in
+ * union statements.
+ */
+%token VOID
+
+%token <str> IDENT
+%token <str> INTLIT
+%token <str> STRLIT
+
+%%
+
+file : /* empty */
+ | stmts
+ ;
+
+/* Statements. */
+stmts : stmt ';'
+ | stmts stmt ';'
+ ;
+
+stmt : ENUM IDENT '{' enum_values '}'
+ | STRUCT IDENT '{' decls '}'
+ | UNION IDENT SWITCH '(' decl ')' '{' union_cases '}'
+ | TYPEDEF decl
+ | CONST IDENT '=' const
+ | PROGRAM
+ ;
+
+/* Declarations used inside structs and unions. eg. "int foo;" */
+decls : decl ';'
+ | decls decl ';'
+ ;
+
+decl : simple_decl
+ | fixed_array_decl
+ | variable_array_decl
+ | pointer_decl
+ ;
+
+simple_decl
+ : type_ident IDENT
+ ;
+
+fixed_array_decl
+ : type_ident IDENT '[' const ']'
+ ;
+
+variable_array_decl
+ : type_ident IDENT '<' const '>'
+ | type_ident IDENT '<' '>'
+ ;
+
+pointer_decl
+ : type_ident '*' IDENT
+ ;
+
+/* Enumerations. */
+enum_values
+ : enum_value
+ | enum_values ',' enum_value
+ ;
+
+enum_value
+ : IDENT
+ | IDENT '=' const
+ ;
+
+/* Case list inside a union. */
+union_cases
+ : union_case ';'
+ | union_cases union_case ';'
+ ;
+
+union_case
+ : CASE const ':' decl
+ | DEFAULT ':' VOID
+ | DEFAULT ':' decl
+ ;
+
+/* Constants, which may be integer literals or refer to previously
+ * defined constants (using "const" keyword).
+ * XXX In future we should probably allow computed constants.
+ */
+const : INTLIT
+ | IDENT
+ ;
+
+/* Types. */
+type_ident
+ : CHAR
+ | SIGNED CHAR
+ | UNSIGNED CHAR
+ | SHORT
+ | SIGNED SHORT
+ | UNSIGNED SHORT
+ | INT
+ | SIGNED INT
+ | UNSIGNED INT
+ | HYPER
+ | SIGNED HYPER
+ | UNSIGNED HYPER
+ | SIGNED
+ | UNSIGNED
+ | DOUBLE
+ | STRING
+ | OPAQUE
+ | IDENT
+ ;
+
+%%
+
+void
+yyerror (const char *str)
+{
+ error ("%s", str);
+}
--- /dev/null
+/* -*- C -*-
+ * rpcgen - Generate XDR bindings automatically.
+ * Copyright (C) 2008 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+%{
+#include <config.h>
+#include "rpcgen_parse.h"
+#include "rpcgen_int.h"
+%}
+
+%option noyywrap
+%option nounput
+%option yylineno
+
+HEXLIT "0x"[0-9a-fA-F]+
+DECLIT 0|[1-9][0-9]*
+INTLIT {HEXLIT}|{DECLIT}
+IDENT [a-zA-Z_][a-zA-Z_0-9]*
+WS [[:space:]]+
+
+%x cstring
+
+%%
+
+ /* # lineno "filename"
+ * cpp itself sets file and line numbers using these directives. We
+ * have to parse this ourselves, since these could occur anywhere in
+ * the input, eg. in the middle of a struct definition.
+ */
+^"#".*\n {
+ char *filename;
+ int lineno;
+
+ /* Allocate enough space to store the returned filename string. */
+ filename = malloc (strlen (yytext));
+ if (filename == NULL) perrorf ("malloc");
+
+ if (sscanf (yytext+2, "%d \"%[^\"]\"", &lineno, filename) == 2) {
+ yylineno = lineno - 1;
+ free (input_filename);
+ input_filename = filename;
+ }
+ else free (filename);
+ }
+
+ /* Anything on a line beginning with % is passed to the output. Again
+ * we have to handle this within the scanner.
+ */
+^"%".*\n fputs (yytext+1, yyout);
+
+ /* C string constants. */
+\" start_string(); BEGIN (cstring);
+<cstring>{
+ \" BEGIN (INITIAL); yylval.str = end_string(); return STRLIT;
+
+ \n error ("unterminated string constant");
+ <<EOF>> error ("unterminated string constant");
+
+ \\[0-7]{1,3} {
+ /* octal escape sequence */
+ int result;
+
+ (void) sscanf (yytext + 1, "%o", &result);
+
+ if (result > 0xff)
+ error ("octal constant is out of range");
+
+ add_char (result);
+ }
+
+ /* Does C allow these?? Maybe confusing it with OCaml.
+ \\x[0-9a-fA-F]{2} {
+ int result;
+
+ (void) sscanf( yytext + 1, "%x", &result );
+
+ add_char (result);
+ } */
+
+ \\[0-9]+ {
+ /* generate error - bad escape sequence; something
+ * like '\48' or '\0777777'
+ */
+ error ("bad escape sequence: %s\n", yytext);
+ }
+
+ \\n add_char ('\n');
+ \\t add_char ('\t');
+ \\r add_char ('\r');
+ \\b add_char ('\b');
+ \\f add_char ('\f');
+
+ /* Backslash followed by a literal newline character. */
+ \\\n add_char ('\n');
+
+ /* Unrecognised escape character - should be an error? */
+ \\. add_char (yytext[1]);
+
+ [^\\\n\"]+ {
+ add_string (yytext);
+ }
+}
+
+ /* Keywords. */
+struct return STRUCT;
+enum return ENUM;
+const return CONST;
+typedef return TYPEDEF;
+union return UNION;
+switch return SWITCH;
+case return CASE;
+default return DEFAULT;
+program return PROGRAM;
+
+unsigned return UNSIGNED;
+signed return SIGNED;
+char return CHAR;
+short return SHORT;
+int return INT;
+hyper return HYPER;
+double return DOUBLE;
+string return STRING;
+opaque return OPAQUE;
+
+void return VOID;
+
+ /* Identifiers. */
+{IDENT} { yylval.str = strdup (yytext); return IDENT; }
+
+ /* Numeric constants are tricky to scan accurately, so keep them as
+ * strings and pass them through directly to the C compiler.
+ */
+{INTLIT} { yylval.str = strdup (yytext); return INTLIT; }
+
+ /* Single characters with special meaning. */
+":"|";"|","|"{"|"}"|"("|")"|"["|"]"|"<"|">"|"="|"*" return yytext[0];
+
+ /* Ignore whitespace. */
+{WS}
+
+ /* Anything else is an error. */
+. error ("invalid character in input near '%c'", yytext[0]);