To keep track of attributes that are associated with Flick's intermediate data structures, Flick stores metadata in the intermediate files that it creates (i.e., aoi and pres_c files). Metadata allows Flick to track the sources and sinks (destinations) of objects, to describe relationships among those sources and sinks, to attach additional semantics or classifications to data, and so on. All of this information is stored in a format called meta.
Metadata is used to classify objects in the intermediate files so that Flick can partition its output in various ways. For example, Flick may put certain types of data in one file and other types of data in another. Alternately, Flick might completely suppress the output of certain kinds of data. The meta format is currently constrained to representing relatively simple attributes -- e.g., the input files associated with various objects -- but the meta language may be extended in the future to support more complex kinds of annotations.
The meta data structures are defined in mom/meta.x, and the library for manipulating meta data is contained in the directory libmeta.
meta provides two basic abstractions: io_files, representing input files,1 and data_channels, representing separate "streams" of data within a single file. These structures are used to classify data according to their source and purpose. An io_file is referenced by data structures that "arise" from the input file represented by the io_file object. A data_channel is used to classify the results generated by processing the input definitions. For example, multiple channels could be used to separate the client-side and server-side C declarations that result from a single idl definition.
In addition to the basic io_file and data_channel structures, meta defines structures for describing sets of files and channels. Sets are described by masks: patterns that may be used to find files and channels of interest.
The primary metadata objects are contained within arrays which are collected under a root object of type meta:
struct meta {
io_file files<>;
data_channel channels<>;
};
|
A reference to an io_file or data_channel is implemented as an integer index into the appropriate array within a meta structure.
typedef int io_file_index; typedef int data_channel_index; |
Other meta data structures, such as descriptions of file and channel sets, are not stored in the root meta structure but are instead stored where they are used.
Files are tracked with the io_file structure:
struct io_file {
string id<>; /* Filename */
unsigned int flags; /* Holds the above flags */
int references; /*
* How many other files have included
* this one
*/
io_file_index includes<>; /* References to included files */
};
|
The flags field contains a set of the following values:
The main set of io_file objects is generated by a Flick front end when it processes a root idl file. In addition, the front end will create any "builtin" files that it needs to indicate definitions that are known a priori to the front end. For example, the corba front end (described in Section 10.2) creates a builtin io_file to represent the source of the predefined CORBA::Object interface type. The set of io_files created by a front end encodes just about everything that Flick cares about from the files, from their names to their place(s) in the inclusion graph.
The io_file_mask structure describes a set of io_file objects:
struct io_file_mask {
unsigned int mask_flags; /* Flags specific to the mask */
string id<>; /* An identifier to match */
unsigned int set_flags; /*
* Match when all of these flags are
* set in the io_file
*/
unsigned int unset_flags; /*
* Match when all of these flags aren't
* set in the io_file
*/
};
|
This structure is supposed to be somewhat opaque; libmeta provides several functions for dealing with them. The construction of io_file_masks is handled by a tag list function (see Section 2.3.4) that sets all the fields and flags based on the tags passed in. For example, the following statement constructs an io_file_mask that matches only system files:
meta_make_file_mask(FMA_SetFlags, IO_FILE_SYSTEM, FMA_TAG_DONE); |
The meta_make_file_mask function is fully described in Section 3.3, below.
Channels are described by the data_channel structure:
struct data_channel {
io_file_index input; /* input for the channel */
string id<>; /* semantic id */
unsigned int flags; /* Holds the above flags */
io_file_index outputs<>; /*
* List of output files for
* the channel (unused)
*/
};
|
Note that the output field is currently unused, because io_files are currently used only for input files. The possible flags within the flags field are these:
The purpose of a channel is to describe a data path for some object, thus allowing Flick to classify it and determine its origin and destination. This knowledge is primarily useful for squelching idl definitions that should not appear in the output. For example, a Flick back end may need to suppress definitions and/or declarations that arise from idl system header files: the definitions of system objects may be built into the targeted rpc/rmi runtime library. Similarly, a user might ask Flick to suppress definitions that come from #included idl files, but to keep the corresponding declarations. This is useful when the included idl files are intended to be compiled separately.
Similar to io_files, channels can be selected with the help of a mask structure:
struct data_channel_mask {
unsigned int mask_flags; /* Flags for the mask */
io_file_mask *input; /* Input file mask */
string id<>; /* ID to match on */
unsigned int set_flags; /*
* Match when all of these flags are
* set in the io_file
*/
unsigned int unset_flags; /*
* Match when all of these flags aren't
* set in the io_file
*/
};
|
The meta library contains a relatively small number of functions of creating and manipulating meta data structures. The source code for the library is in the libmeta directory, and the library header file is mom/libmeta.h. The various meta library functions are summarized below.
The following functions are useful for manipulating files:
The tags and associated tag values for the meta_make_file_mask function are these:
An io_file_mask can specify at most one file name matching function: in other words, do not specify more than one of the above "ID" tags when creating a mask. In contrast, an io_file_mask can specify matching against both set and unset flags.
The following functions are useful for manipulating files:
The tags and associated tag values for the meta_make_channel_mask function are these:
In retrospect, it is apparent that the concept of a data_channel could be generalized to encompass the abilities of an io_file structure. Currently, the only real difference between the two structures is that a file can have multiple inputs -- the included files -- but that a channel can have only one. By allowing channels to have multiple inputs, Flick might be able to express the inclusion file graph as well as other dependencies between channels.