Parser for ONC RPC IDL. The grammar is taken from RFC1832, sections 5, and RFC1831, section 11.2. The output Python code (which requires rpchelp and rpc from the Pinefs distribution) contains a separate class (with rpchelp.Server as a base class) for every version defined in every program statement. To implement a service, for each version of each program, derive a class from the class named <prog>_<version>, with method names corresponding to the procedure names in the IDL you want to implement. (At instantiation, any procedure names defined in the IDL but neither implemented nor listed in the deliberately_unimplemented member will cause a warning to be printed.) Also, define a member function check_host_ok, which is passed (host name, credentials, verifier) on each call, and should return a true value if the call should be accepted, and false otherwise. To use instances of the server class, create a transport server (with the create_transport_server(port) function), and then, for every server instance you want associated with that port, call its register(transport_server) function, which will register with the local portmapper. (This architecture allows multiple versions of multiple programs all to listen on the same port, or for a single version to listen on, e.g, both a TCP and UDP port.) Member functions will be passed Python values, and should return a Python value. The correspondence between IDL datatypes and Python datatypes is: - base types uint, int, float, double are the same - void is None - an array (either fixed or var-length) is a Python sequence - an opaque or a string is a Python string - a structure is a Python instance, with IDL member names corresponding to Python attribute names - a union is a two-attribute instance, with one attribute named the name of the discriminant declaration, and the other named '_data' (with a value appropriate to the value of the discriminant). - an optional value (*) is either None, or the value - a linked list is special-cased, and turned into a Python list of structures without the link member. - const and enum declarations are top-level constant variables. IDL identifiers which are Python reserved words (or Python reserved words with 1 or more underscores suffixed) are escaped by appending an underscore. Top-level struct and union declarations generate Python declarations of the corresponding name, and calling the object bound to the name will generate an instance suitable for populating. (The class defines __slots__ to be the member names, and has, as attributes, any nested struct or union definitions. The packing/unpacking function don't require the use of this class, and, for the unnamed struct/union declarations created by declaring struct or union types as either return values or argument types in a procedure definition, you'll need to create your own classes, either by using rpchelp.struct_union_class_factory, or some other way.) Enum declarations nested inside struct or union declarations, or procedure definitions, generate top-level definitions. (I think this treatment of nested enum definitions is wrong, according to RFC1832 section 5.4, but I'm not sure.) Rpcgen doesn't support: - 'unsigned' as a synonym for 'unsigned int' - case fall-through in unions Neither seems to be defined in the grammar, but I should support them, and look around for an updated IDL specification.