Using Flick

3.1 Introduction

Flick works in three phases, each implemented as a separate program: the front end, the presentation generator, and the back end. A Flick front end is simply a parser that translates some IDL input into an intermediate representation called an AOI (Abstract Object Interface, `.aoi') file. Next, a "presentation generator" determines how the constructs in the AOI file (the parsed IDL file) are to be mapped onto type and function definitions in the C or C++ programming language. In other words, the presentation generator determines how the generated stubs will appear -- e.g., the stubs' function prototypes -- and how they will interact with user code -- e.g., the stubs' parameter passing conventions. This information about the stubs is written into a PRES_C (Presentation in C/C++, `.prc') file. The final phase of compilation, the back end, reads a PRES_C file and produces the C or C++ code for the optimized stubs, written to use a particular transport system (e.g., TCP) and message format.

Flick has multiple implementations of each of the three phases described above. Flick has three separate front ends: one to parse CORBA IDL files, one to parse ONC RPC (Sun) IDL files, and one to parse MIG IDL files. There are five different presentation generators, implementing the CORBA (C and C++), ONC RPC, MIG, and Fluke1 mappings of IDL constructs onto C or C++. Finally, there are seven separate back ends for producing stubs that use IIOP (C and C++), ONC/TCP, Mach messages, Trapeze,2 Khazana-style messages,3 and Fluke IPC.

3.1.1 Flick Programs

Every compiler pass is implemented as a separate program. Once Flick has been built, links to these programs will be located in the bin subdirectory of your Flick build tree:

Front Ends

flick-fe-newcorba
The CORBA front end. Parses a CORBA IDL (`.idl') file and outputs an AOI file (`.aoi') to be read by the flick-c-pfe-corba, flick-c-pfe-corbaxx, or flick-c-pfe-fluke presentation generators.4
flick-fe-sun
The ONC RPC front end. Parses an ONC RPC IDL (`.x') file and outputs an AOI file to be read by the flick-c-pfe-sun presentation generator.
flick-c-fe-mig
The MIG front end/presentation generator. Parses a MIG IDL (`.defs') file and outputs a PRES_C file to be read by any back end. Note that flick-c-fe-mig is unique because it implements both the front end and presentation generation passes. These passes are combined because MIG IDL allows users to specify presentation attributes in addition to simply defining interfaces.

Presentation Generators

flick-c-pfe-corba
The CORBA C language presentation generator. Reads an AOI file generated by the CORBA front end and outputs a PRES_C (`.prc') file describing C stubs to be read by any C language back end (i.e., any back end except flick-c-pbe-iiopxx).
flick-c-pfe-corbaxx
The CORBA C++ presentation generator. Reads an AOI file generated by the CORBA front end and outputs a PRES_C (`.prc') file describing C++ stubs to be read by any C++ language back end (as of this writing, only flick-c-pbe-iiopxx).
flick-c-pfe-sun
The ONC RPC presentation generator. Reads an AOI file generated by the ONC RPC front end and outputs a PRES_C file describing C stubs to be read by any C language back end.
flick-c-pfe-fluke
The Fluke presentation generator, used with the Fluke operating system. Reads an AOI file generated by the CORBA front end and outputs a PRES_C file describing C stubs to be read by any C language back end.

Back Ends

flick-c-pbe-iiop
The IIOP back end for C code. Reads a PRES_C file and outputs either client stubs or server skeletons for use with Flick's IIOP runtime. The generated stubs use the IIOP transport and CDR data encoding.
flick-c-pbe-iiopxx
The IIOP back end for C++ stubs. Reads a PRES_C file and outputs either client stubs or server skeletons for use with TAO. The generated stubs use the IIOP transport and CDR data encoding.
flick-c-pbe-sun
The ONC/TCP back end for C stubs. Reads a PRES_C file and outputs either client stubs or server skeletons for use with Flick's ONC/TCP runtime. The generated stubs use the ONC/TCP transport and XDR data encoding.
flick-c-pbe-mach3mig
The Mach 3/MIG back end for C stubs. Reads a PRES_C file and outputs either client stubs or server skeletons for use with Mach. The generated stubs use Mach IPC and MIG-style typed data encoding.
flick-c-pbe-trapeze
The Trapeze back end for C stubs. Reads a PRES_C file and outputs either client stubs or server skeletons for use with Trapeze. The generated stubs use Trapeze messages and either CDR or XDR data encoding, depending on where the PRES_C file originated. (XDR is used for Sun-style stubs; CDR is used for CORBA and other stub styles.)
flick-c-pbe-khazana
The Khazana back end for C stubs. Reads a PRES_C file and outputs either client stubs or server skeletons for use within Khazana. The generated stubs use TCP and a CDR-like data encoding.
flick-c-pbe-fluke
The Fluke back end for C stubs. Reads a PRES_C file and outputs either client stubs or server skeletons for use with Fluke. The generated stubs use Fluke IPC and a CDR-like data encoding.

Other Tools

flick-aoid
The AOI dump utility. Reads an AOI file and outputs a human-readable dump of the parse tree (an `.aod' file). This program is used primarily to debug Flick.
flick-c-presd
The PRES_C dump utility. Reads a PRES_C file and outputs a human- readable dump of the interface presentation (a `.prd' file). This program is used primarily to debug Flick.

3.1.2 Common Command Line Options

All Flick programs support these command line arguments and options:

input
Read from the named input file. Every Flick program expects to receive the name of its input file on the command line. If no input file is specified, input is taken from stdin.
-o filename or --output filename
Write output to the specified file. If no output file is specified, the name of the output file will be constructed by concatenating the base name of the input file with a new, appropriate extension; e.g., if a presentation generator was told to read "foo.aoi", the name of the output file would be "foo.prc". If no input file is specified on the command line, output will be written to stdout.
-u or --usage or
-? or --help
Print a synopsis of all available flags and quit.
-v or --version
Print the version of the program and quit.

Warning: Flick's AOI and PRES_C file formats are binary file formats, not text file formats. Windows NT and Windows 95 distinguish binary streams from text streams, and set stdin and stdout to be text streams. Thus, under Windows, it is not possible to pipe AOI and PRES_C data between Flick compiler passes.

3.2 Front Ends

Flick's three front ends translate the CORBA, ONC RPC, and MIG IDLs into intermediate formats used as input to later stages of the compiler. The simplest way to use any of these front ends is to specify the IDL file on the command line:

flick-fe-newcorba foo.idl
Process the CORBA IDL file foo.idl to produce foo.aoi . The output AOI file can be input to the CORBA or Fluke presentation generators.
flick-fe-sun foo.x
Process the ONC RPC IDL file foo.x to produce foo.aoi . The resultant AOI file can be input to the ONC RPC presentation generator.
flick-c-fe-mig foo.defs
Process the MIG IDL file foo.defs to produce foo.prc . The MIG front end is special in that it produces a PRES_C file, not an AOI file.

3.2.1 Command Line Options

In addition to the standard flags supported by all Flick programs, the CORBA and ONC RPC front ends support the following two, mutually exclusive, flags:

-c flags or --cppflags flags
Pass flags to the C preprocessor. By default, all IDL files are piped through the C preprocessor before being parsed.
-n or --nocpp
Skip the C preprocessor and pass the IDL input directly to the front end.

The MIG front end supports the following flags in addition to the standard flags listed in Section 3.1.2:

-Idir
Specify an include directory for the C preprocessor.
-Dsym
Pass sym on to the C preprocessor. A value may be specified, e.g., -DDEBUG=2. The default value for sym is 1.
-Usym
Undefine symbol sym in the C preprocessor.
-Xcpp opt
Pass the command line option opt to the C preprocessor.
-c or --client
Generate client stubs only. The default is to generate both client stubs and server skeletons. This option cannot be combined with -s.
-s or --server
Generate server skeletons only. This option cannot be combined with -c.

3.2.2 Additional Comments

CORBA

The CORBA front end does not currently support certain CORBA data types (wchar, wstring, fixed, and native types) nor does it support CORBA contexts. It does, however, support the 64-bit "long long" and "unsigned long long" types.

ONC RPC

The ONC RPC front end allows only one argument to be passed to each operation. This conforms to the older specification of the Sun RPC language. (RFC 1831, which defines the "modern" ONC RPC IDL, allows for multiple arguments and in-argument-list type specifications.) Further, Flick's ONC RPC front end does not recognize the keywords hyper and quadruple that are described in RFC 1832. Flick's ONC RPC front end does not support the `%' directive that is offered by Sun's rpcgen IDL compiler.

MIG

The MIG front end/presentation generator is nearly complete but does not yet support all of the MIGisms you may love (or hate). The list of not-yet-implemented features is contained in the doc/BUGS file in the Flick source tree.

3.3 Presentation Generators

Flick has four different presentation generators: one to produce CORBA-style C language stubs, a second to produce CORBA-style C++ stubs, a third to produce ONC RPC (rpcgen-style) stubs, and a fourth to produce special stubs for use in Utah's Fluke operating system. (As previously mentioned, Flick's MIG-style presentation generator is conjoined with the MIG front end.) A presentation generator can be invoked to produce either the client-side stubs or the server-side dispatch function, but not both at the same time. Simply run a presentation generator twice, with different options, to produce both files; for example:
         flick-c-pfe-corba -c -o foo-client.prc foo.aoi     # make client
         flick-c-pfe-corba -s -o foo-server.prc foo.aoi     # make server

3.3.1 Command Line Options

Each presentation generator accepts the following options in addition to those described in Section 3.1.2:

-c or --client
Generate client stubs. This is the default if neither -c nor -s is specified. This option cannot be combined with -s.
-s or --server
Generate server skeletons. This option cannot be combined with -c.
-a or --async_stubs
Generate nonstandard "decomposed" stubs instead of normal, synchronous RPC stubs. This experimental feature is currently implemented only in the CORBA C language presentation generator.5

In addition, there are many, many options for changing the printf-like format strings that the presentation generator uses to produce the names of various presentation elements. (Use --usage to see them all.) These name format options exist only for short-term use; all of these options will eventually be replaced by a more general presentation-modification facility.

3.3.2 Additional Comments

General

There are still some unwarranted dependencies between certain front ends and presentation generators. Although the CORBA and ONC RPC front ends both produce AOI files, the CORBA and ONC RPC presentation generators are still "tuned" to the AOI constructs generated by the respective front ends. This means that at the moment, the CORBA and Fluke presentation generators can input only AOI files generated by the CORBA front end, and similarly, that the ONC RPC presentation generator can input only AOI files generated by the ONC RPC front end. This will eventually be corrected.

CORBA

The CORBA C language presentation generator does not produce CORBA-style allocator functions for constructed data types (as described in Section 14.8 of the CORBA 2.0 specification). Flick's CORBA runtime does provide a generic CORBA_alloc function, however, which takes a single argument indicating the number of bytes to be allocated.

3.4 Back Ends

Flick has seven separate, optimizing back ends to produce stubs that use IIOP (for C and C++ stubs), ONC/TCP, Mach 3 typed messages, Trapeze messages, Khazana-style messages, or Fluke IPC. As described in Section 3.3, Flick separates the client- and server-side presentations into two PRES_C files. This means that in order to generate both client and server code, you must run a back end twice: once on the client-side `.prc' file and once on the server-side `.prc' file. For instance, the two commands:
         flick-c-pbe-iiop foo-client.prc     # make client
         flick-c-pbe-iiop foo-server.prc     # make server

produce the client stubs (foo-client.c, foo-client.h) and then the server skeletons (foo-server.c, foo-server.h) using Flick's IIOP back end. Of course, it is important to use the same back end to produce both client and server code.

3.4.1 Command Line Options

All back ends support the following options in addition to the standard flags:

-h filename or --header filename
Output the header file to filename . If this is not specified, the name of the header file will be constructed from the name of the output `.c'/`.cc' file (which is specified with -o). If the output C/C++ file is stdout, the header will be inlined into the output.
-p prefix or --prefix prefix
Use prefix when including the generated header file from the generated C or C++ file, i.e.: #include "prefix header.h".
-s or --system_header
In the output C or C++ file, include the generated header as a system header rather than a user header, i.e., using <> rather than "".
-n filename or --inline filename
Allow "simple" presentation implementation functions to be inlined. This option allows us to support fast inline functions similar to those from TAO's IDL compiler. These functions are placed in filename , and included by the generated header or source depending on the compile-time directive __ACE_INLINE__.
--no_timestamp
Do not output timestamp information into the generated header and C/C++ code files. This option is useful for regression testing.
-i or --no_included_imple- mentations
Suppress the definition of stubs that are derived from interfaces that were #included by the IDL file that was processed by the front end. This option must be used with caution, as you may unintentionally cause Flick to omit functions that you need in order to compile your client or server application.
-d or --no_included_declarations
Suppress the declaration of stubs that are derived from interfaces that were #included by the IDL file that was processed by the front end. This option must also be used with caution, as you may unintentionally cause Flick to omit function declarations that you need in order to compile your client or server application.
-m or --all_mu_stubs
Generate all marshal and unmarshal stubs. Normally Flick generates only those that are actually used by the generated code. This option is useful mainly for debugging. The generated code is significantly larger if all marshal and unmarshal stubs are produced -- generally too large for practical use.
-P filename or --presentation_imple- mentation filename
Read the "presentation implementation" from filename . The presentation implementation (a `.scml' -- Source Code Markup Language -- file) describes how certain functions are to be created and written into the generated code. This option is normally not required because each back end has its own built-in default.
--nostdinc
Tell the back end not to search in the standard locations for SCML files. Again, this option is generally not used, unless one is implementing or testing Flick.
-I directory or --include directory
Look in directory for presentation implementation (`.scml') files. This option may be repeated in order to define a search path. Like -P, this option is normally not required because each back end automatically looks in the Flick installation directories for the SCML files it needs.
-f filename or --file filename
In the output C or C++ file, output: #include "filename ". This option is often used with the IIOP C++ back end; see Section 3.4.2 for more information.
-F filename or --File filename
In the output header file, output: #include "filename ". This option is often used with the IIOP C++ back end; see Section 3.4.2 for more information.
-D vardef or --define vardef
Use the variable definition vardef when reading the presentation implementation (SCML) files. This option may be repeated in order to define multiple variables.

3.4.2 Additional Comments

IIOP/C++ Back End Issues

The IIOP back end for C++, flick-c-pbe-iiopxx, is careful to generate client and server code that can be compiled into a single program (in order to support TAO "collocated" objects). However, a side effect is that the generated C++ files for client and server each need to #include the other's header file in order to compile. So, the IIOP back end for C++ is normally invoked like this:
         flick-c-pbe-iiopxx -h client.h -f server.h ...    # make client
         flick-c-pbe-iiopxx -h server.h -F client.h ...    # make server

where client.h and server.h are replaced with your names for the client and server header files, respectively.

The first command generates the client code and header files; the client's header file is named client.h and the generated client C++ file will #include "server.h". Similarly, the second command generates the server code and header files; the server's header file is named server.h and the server's header will #include "client.h". Note that one uses -f when generating the client and -F when generating the server. This is required in order to sequence the #includes properly.

Code Generation Issues

All of Flick's back ends produce code that is optimized for speed, and Flick is currently single-minded in pursuit of fast code. The current version of Flick largely overlooks other code generation issues that may be important to certain application domains:

Code Size.
Because Flick aggressively inlines code to marshal and unmarshal data, the size of the generated stub functions can be very large. The generated code becomes larger as the complexity of the IDL-defined interfaces increases. A future release of Flick will make better inlining decisions.
Code Complexity.
Flick-generated code is not intended to be human-readable, although the code is generally not too difficult for programmers to understand. Flick makes extensive use of the C preprocessor. Some compilers may have problems with Flick-generated code; for instance, we discovered that Microsoft Visual C++ 4.2 was unable to deal with deeply nested switch statements.
Thread Safety.
Flick does not generate thread-safe code. If your application is multithreaded, you will need to provide explicit locks around the Flick-generated stubs.
Error Handling.
Although the generated stubs generally handle errors in an appropriate manner, Flick's runtimes may fail an assert or exit in response to certain critical errors. A future release of Flick will better address error handling and recovery within the runtimes.

The doc/BUGS file in the Flick source tree lists known bugs with Flick's code generators.

Server Main Functions

The IIOP (C only), ONC/TCP, Khazana, and Trapeze back ends each produce a main function for the server, whereas the IIOP C++, Mach 3, and Fluke back ends do not. The assumption is that the former back ends will be used to generate "standalone" servers while the latter back ends will generate code for use in a more complex framework.

Mix-and-Match Problems

While it is possible to combine presentation generators and back ends in unusual ways -- e.g., create Sun-style ONC/TCP code for a CORBA-style presentation -- Flick's runtime libraries may not be able to handle unusual combinations. In this release we have focused on code generation for "matched" presentation and code generation, meaning:

These "mixed" combinations have also been tested and should work: