NAME
stubgen - code generator for Database wrapper classes
SYNOPSIS
stubgen [-v]
category definition_file [-h header_dir] [-cc body_dir] [-t template_dir] [-r report_file] [-o out_file]
where category is one of
bridge
for bridge classes,
bridge-data
for bridge data classes
facade
for opaque facade classes,
client_prefix for client facade classes
OPTIONS
Options can be placed in any order, anywhere on the command line.
|
|
Verbose |
header_dir |
Specifies the directory into which generated header files (.h) will be placed. If this option is omitted, no header files will be generated. |
body_dir |
Specifies the directory into which generated implementation files (.cc) and an Imakefile fragment will be placed. If this option is omitted, no implementation files will be generated. |
template_dir |
Specifies the directory where the template files are located. |
report_file |
Requests the generation of a report which is placed in report_file. |
log_file |
Requests creation of a list of generated files which is placed in log_file |
include_prefix |
Overrides the standard prefix used in generating values for certain variables (see "Variables" for details.) |
DESCRIPTION
stubgen
parses the definition_file and generates C++ source code for the specified category of classes. If the -h option was specified, C++ header files are generated for each qualified database entity. If the -cc option was specified, C++ implementation files are generated for each qualified database entity. Thus one can simply parse the definition_file by omitting both options.
Qualified database entities are those which match the category according to the following rules:
|
Category |
Qualified Entities |
Generated Classes |
|
All entities |
Bridge (<Entity>Bridge) |
|
All entities |
Opaque Facade (<Entity>) |
|
All entities |
Client Facade (TEST<Entity>) |
|
client_prefix |
Entities having at least one method whose access list contains the client_prefix or which are available to all clients. |
Client Facade (<client_prefix><Entity>) |
Code is generated by expanding template files. stubgen uses the following rule to determine the location of the template files:
-t option was specified use the directory supplied with that option.stubgen executable is located.Normally users of stubgen need not tinker with the templates. They are documented here for completeness.
FILES
|
Entity.cc |
Template for Opaque Façade implementation |
|
Entity.h |
Template for Opaque Facade header |
|
EntityBridge.cc |
Template for Bridge implementation |
|
EntityBridge.h |
Template for Bridge header |
|
ClientEntity.cc |
Template for Client Facade implementation |
|
ClientEntity.h |
Template for Client Facade header |
|
Category.imk |
Template for generated Imakefile |
BACKGROUND
Each persistent class (a "Database Entity") is implemented by a family of related classes as illustrated in Figure 1. The roles of each class are described below.

Figure 1: Implementation of Database Entities
oby<Entity>An Objectivity persistent class. Responsible for most of the Database Entity’s functionality, and for storage of its persistent state. The interface to this class is defined entirely in terms of types recognized by Objectivity. In particular no <Entity> or <Entity>Bridge classes cross this interface.
<Entity>BridgeA transient C++ class which functions as a surrogate for the oby<Entity>. Access to the corresponding oby<Entity> is via an Objectivity handle, ooHandle(oby<Entity>) embedded in the <Entity>BridgeData object. Responsible for:
a) Data type conversion of oby<Entity> method parameters and return values.
b) Translation of oby<Entity> error status returns into C++ exceptions. (Objectivity reports errors via status codes rather than by throwing exceptions).
c) Management of Objectivity databases and transactions. This role includes coordinating with other Objectivity clients on the use of a federated database and the state of the current transaction. (Objectivity only allows one open federation and one active transaction per Unix process). This coordination is accomplished via interaction with a collection of Objectivity Management objects.
d) Implementing those aspects of the Database Entity’s functionality that would otherwise require the oby<Entity> class to know about <Entity> or <Entity>Bridge classes. For instance, the visitor pattern is implemented by the Bridge class with the assistance of Objectivity iterators.
<Entity>A transient C++ class which functions as an abstract class from which client interface classes (<Client><Entity>) are derived. This class implements the common features of all client interfaces:
a) Provide compile-time decoupling of the Client and the Database. The include file for <Entity> does not #include <Entity>Bridge. Thus changes in the implementation of <Entity>Bridge simply require relinking of the client, rather than recompilation and relinking.
b) Automate the memory management of <Entity>Bridge, which is always allocated on the heap. (This functionality is accomplished by reference counting, inherited from Handle/HandleBody).
c) Provide the client with a model of the Database Entity as a concrete class.
<Client><Entity>A transient C++ class which represents the Database Entity for a particular client. It provides that subset of the Database Entity’s interface which is accessible by the client.
DEFINITION FILE
The definition file provides all of the information needed to generate the C++ code. It is formatted as an ASCII file. The syntax and semantic of the definition language is presented below.
The Definition File consists of a sequence of comments and directives. Comments always occupy a single physical line, which must begin with the character, ‘#’. Directives always occupy at least one physical line (i.e. no more than one directive per physical line). If a directive occupies more than one physical line, then all but the last physical line must end with a continuation character, ‘\’, as the last non white-space character of the line.
Directives consist of fields separated by the field separation character, ‘|’. The first field of a directive is a keyword identifying the directive’s type. The number and contents of the remaining fields depends upon the directive’s type. The directives are summarized in the following table:
Table 1: Definition File Directives
|
Directive |
Role |
|
type |
Declares a type (other than a Database Entity) used by some method of an Entity. |
|
entity |
Declares the name of a Database Entity. |
|
default-entity |
Identifies the Database Entity to which following method directives apply. |
|
method |
Declares a method of the current default Database Entity. |
(The entries in the table are in order of appearance in a Definition File.)
The syntax of the directives is given using extended BNF using the following conventions:
Terminal-Font. In the following syntax definitions, the field separation character is represented by the non-terminal, sep.
sep ::= ‘|’
Type Directive
This directive provides information about types (Other than the classes representing Database Entities), which are used in the interface of some Database Entity. (Built in C++ types are not introduced by a Type Directive
Syntax:
TypeDirective ::= type sep TypeName sep TypeKind sep TypeHeader
TypeName ::= The C++ identifier for the type.
TypeKind ::= class | typedef
TypeHeader ::= The filespec of the include file containing the type’s C++ declaration.
Example:
type|RWBoolean|typedef|rw/types.h
type|RWCString|class|rw/cstring.h
stubgen
uses the class/typedef distinction given by TypeKind to optimize generated header files. If a type of kind, class, is not passed by value in the interface of the generated class, then the header file for that type is not #included in the generated header file. Instead a C++ forward declaration of the class is generated.Entity Directive
This directive declares all of the Database Entities for which code can be generated. A Default-Entity Directive which references an undeclared Database Entity will be flagged as an error during the loading of the Definition File.
Syntax:
EntityDirective ::= entity sep EntityName
EntityName ::= C++ identifier for the Database Entity
Example:
entity|Foo
entity|Bar
The C++ names of the various classes representing the Database Entity are derived according to the conventions illustrated in Figure 1 where the value of EntityName is substituted for <Entity>.
File names for the generated classes are then derived from the class names by lowercasing the class name.
Default Entity Directive
This directive establishes the name of the Database Entity to which subsequent Method Directives implicitly refer. The EntityName specified here must have appeared in a prior Entity Directive. If not, an error message is issued.
Syntax:
DefaultEntityDirective ::= default-entity sep [ EntityName ]
EntityName ::= C++ identifier for the Database Entity
Example:
default-entity|Foo
# Methods for Foo declared here
default-entity|
If EntityName is omitted, there is no default entity, and subsequent Method Directives will generate error messages to this effect. The example illustrates the recommended practice of undefining the default entity so that the omission of a subsequent Default Entity directive will cause errors during Definition File loading.
Method Directive
This directive defines a method of the default entity. It provides the information needed to generate C++ source code for that method.
Syntax:
MethodDirective ::= MethodOpcode sep [ MethodQualifiers ] sep MethodName sep [ MethodType ] sep [ ArgumentList ] sep [ AccessList ]
MethodOpcode ::= method [ BodyVersion ]
MethodQualifiers ::= [ static ] [ const ]
MethodName ::= C++ method identifier
MethodType ::= TypeDecl
ArgumentList ::= ArgumentDecl { , ArgumentDecl }
ArgumentDecl ::= TypeDecl ArgumentName
ArgumentName ::= C++ method argument identifier
TypeDecl ::= [ const ] TypeName [ & | * ]
TypeName ::= C++ type identifier
AccessList ::= AccessKey { , AccessKey }
AccessKey ::= ALL | ClientPrefix
ClientPrefix ::= The standard prefix for a given client.
MethodOpcode
The keyword, nocode, indicates that no code will be generated for this method in the <Entity>Bridge class. (However code will be generated in each of the other classes).
BodyVersion
This token is a string which identifies an alternative version of the method’s expansion in the various templates. If the template contains an $alt-method directive which references the BodyVersion, then the corresponding expansion text will be used instead of the default text. (If the template does not contain such an $alt-method directive, the default text is used anyway)
MethodQualifiers
The keyword, const, indicates that the method is a ‘const’ method. The declaration of the method will be postfixed with "const"
The keyword, static, indicates that the method is a class method (C++ static method).
MethodType
This field specifies the return type of the method. The default value is "void"
ArgumentList
This field defines the method’s arguments in format similar to that used by C++ (The only difference is the restrictions imposed by TypeDecl on the format of the argument type declarations.). In other words, the argument list is a comma separated list of argument declarations, each consisting of an argument type declaration and an argument name.
AccessList
This field defines which clients are granted access to this method. It is a comma separated list of AccessKeys. The presence of a ClientPrefix (say SC) in the list indicates that the corresponding client (e.g. the SemanticChecker) has access to this method, and hence it will appear in the public section of the corresponding <Client><Entity> class.
The reserved key, ALL, indicates that the method is accessible to all clients.
If the AccessList is empty, the method is not accessible to any client (except TEST).
NOTE: The client prefix, TEST, is implicitly placed on all methods, allowing a test client to have access to the full Database interface.
TEMPLATES
Templates are schematic representations of C++ header and implementation files, and Imakefiles which are expanded by a specialized macro processor within stubgen.
A Template consists of a sequence of source lines and directives. Directives always begin with a ‘$’ followed by the directive name. All other lines are considered to be source lines.
Source lines may contain variable references which are replaced with the value of the corresponding variable when the source line is expanded for output. The process of outputting expanded source lines is called ‘expanding the template’.
Variables are symbolic names for text strings which are to be substituted whereever a reference to that variable occurs. The text string associated with a variable is called its value. The value of a variable may not contain variable references. Variable references have the following syntax:
No whitespace is allowed inside the braces enclosing the VariableName.
There are a large number of predefined variables. Additionally, variables may be defined via the $define directive (see below)
|
Variable |
Value |
Directive |
|
Date |
The current date & time when the file is generated |
|
|
File |
The name of the file being generated. |
|
|
Entity |
Name of the Entity’s Opaque Facade class |
|
|
EntityHeader |
Name of the header file for the Opaque Facade class |
|
|
EntityBridge |
Name of the Entity’s Bridge class |
|
|
EntityBridgeHeader |
Name of the header file for the Bridge class |
|
|
ObyEntity |
Name of the Entity’s Objectivity class |
|
|
ObyEntityHeader |
Name of the header file for the Objectivity class |
|
|
ClientEntity |
Name of the Entity’s Client Facade class |
|
|
ClientEntityHeader |
Name of the header file for the Client Facade class |
|
|
ClassHeaderKey |
C++ preprocessor symbol to be used in the "smart include" mechanism of the class’s header file |
|
|
ExternalClass |
Name of the current external class |
|
|
Header |
Name of the current include file |
|
|
MethodType |
Return type of the current method |
|
|
MethodName |
Name of the method. |
|
|
MethodSignature |
Signature of the current method |
|
|
MethodCall |
Invocation of the current method |
|
|
Return |
if MethodType == "void" then "" else "return " |
|
|
SourceFile |
Name of a generated implementation file without .cc |
|
|
CodeTag (b) |
String identifying the category of code being generatd |
|
The variables representing header files (e.g. EntityHeader) have a value of the form: PathPrefix/ClassName.h where PathPrefix is empty unless specified by the -p option and ClassName is the name of the class defined by the header file.
Directives
Directives tell stubgen to take special actions when expanding a template. Many of them cause stubgen to repeatedly expand a section of the template, supplying different values for directive specific macros on each iteration. Unlike Definition File directives, Template directives must occupy a single physical line.
Table 3: Template Directives
|
Directive |
Use |
Scope |
|
$define |
Define new variables |
|
|
$includes |
Iterate over all include files required by the entity |
C++ |
|
$forwards |
Iterate over all external classes not passed by value |
C++ |
|
$methods |
Iterate over all object methods of the class |
C++ |
|
$alt-method (b) |
Specify named alternative expansion of a method |
C++ |
|
$sources |
Iterate over all generated implementation files |
Imake |
$methods directiveThis directive is used to define new variables within a template.
Syntax
DefineDirective ::= $define VariableName Delim VariableDefinition Delim
VariableName ::= A sequence of alphanumerics and "_"
Delim ::= the first non-whitespace character following VariableName
VariableDefinition ::= All the text between Delim
The VariableDefinition can contain whitespace. It can contain variable references which will be expanded at the time the directive is processed. References to the variable being defined will result in a warning, and will be expanded to the empty string.
The Delim can be abutted to the VariableName
Example
The following directives all define the variable, obyClass, as the expansion of "ooHandle($[ObyEntity])"
$define obyClass%ooHandle($[ObyEntity])%
$define obyClass %ooHandle($[ObyEntity])%
$define obyClass "ooHandle($[ObyEntity])"
$includes Directive
This directive is used to generate C++ #include directives for the header files needed by the template.
For a header file template, this list consists of headers for all types (including DatabaseEntity classes) which are used in the declaration of the generated class’s methods, except for classes which are never passed by value either as a method return or argument. The names of these latter classes can be visited by use of the $forwards directive within the same template.
For an implementation file template, this list consists of headers for all of those types that were omitted in the implementation template, i.e. headers of those classes which are never passed by value either as a method return or argument. This policy assumes that the implementation file template will #include the header of the class.
Syntax
IncludesDirective ::= $includes newline SourceLines newline $end-includes
The $includes and $end-includes directives bracket a sequence of source lines which will be repeatedly expanded, once for each header file. See Table 2 for those template variables which are defined within the SourceLines of this directive.
Do not place any other directives within the SourceLines.
Example
$includes
#include <$[Header]>
$end-includes
The above example will generate #include directives for all of the include files needed by the generated source file (If the template itself contains occurrences of types, then the template must also contain the appropriate '#include' directives. Stubgen does not attempt to parse the template itself.)
$forwards Directive
This directive is used to generate C++ forward declarations for classes needed by the template.
For a header file template, this list consists of those classes which are never passed by value either as return or argument in the generated methods.
For an implementation file, this list is always empty.
Syntax
ForwardsDirective ::= $forwards newline SourceLines newline $end-includes
The $forwards and $end-forwards directives bracket a sequence of source lines which will be repeatedly expanded, once for each class. See Table 2 for those template variables which are defined within the SourceLines of this directive.
Do not place any other directives within the SourceLines.
Example
$forwards
class $[ExternalClass];
$end-forwards
The above example will generate forward declarations for all of the external classes referenced by the generated methods of a header file
$methods Directive
This directive is used to generate C++ declarations and definitions of the qualified, non-static methods extracted from the Definition File.
Syntax
MethodsDirective ::= $methods newline ExpansionText newline $end-methods
ExpansionText ::= { SourceLine | AltMethodDirective }
The $methods and $end-methods directives bracket a sequence of source lines which will be repeatedly expanded, once for each qualified non-static method extracted from the Definition File. See Table 2 for those template variables which are defined within the SourceLines of this directive.
The ExpansionText defines one or more (possibly empty) sequences of SourceLines, one of which will be expanded for each qualified non-static method extracted from the Definition File. (See Table 2 for those template variables which are defined within the SourceLines of this directive). The first sequence (between the $methods and the first $alt-method or $end-methods directive) is called the default text for the method. The subsequent sequences (between an $alt-method and the next $alt-method or $end-methods directive), are called alternate texts for the method. Each alternate text is identified by one or more AltTags. The same AltTag cannot appear in more than one $alt-method directive within a $methods directive.
For a given method, the alternate text which has a tag matching the BodyVersion of the method is used. If no such text can be found, the default text is used. Consequently, methods having no BodyVersion will always used the default text.
Example: Header File
$methods
$[MethodType] $[MethodSigniture];
$end-methods
The above sequence will generate the declarations of all generated methods within a header file.
Example: Implementation File - Bridge Class:
$methods
// Name: $[MethodName]
$[MethodType]
$[EntityBridge]::$[MethodSignature]
{
$[Return]obyEntity_->$[MethodCall];
}
$alt-method returns-entity
//Name:$[MethodName]
$[MethodType]
$[EntityBridge]::$[MethodSignature]
{
ooHandle(oby$[MethodType]) result =
obyEntity_->$[MethodCall];
return $[MethodType]Bridge::make(result);
}
$alt-method static
// Name: $[MethodName]
$[MethodType]
$[EntityBridge]::$[MethodSigniture]
{
$[Return]$[ObyEntity]::$[MethodCall];
}
$alt-method static-returns-entity
//Name:$[MethodName]
$[MethodType]
$[EntityBridge]::$[MethodSignature]
{
ooHandle(oby$[MethodType]) result
=$[ObyEntity]::$[MethodCall];
return $[MethodType]Bridge::make(result);
}
$alt-method nocode
$end-methodsThe above sequence will generate the definitions of all generated methods within an implementation file. (The variable, Return expands to an empty string if the MethodType expands to ‘void’, otherwise it expands to ‘return ‘ )
The default, is for non-static methods which do not return an entity.
The alternative, returns-entity, is used for non-static methods known to return a generic facade to some entity. In this case the return value from the Objectivity class is an ooHandle which must be converted to a generic facade.
The alternative, static, is used for methods which are static and do not return an entity.
The alternative, static-returns-entity, is for static methods known to return a generic facade to an entity.
The alternative, no-code, is used for methods which will be implemented manually in a separate file.
$sources Directive
This directive is used to generate dependencies in the Imakefile which is companion to a set of implementation files.
Syntax
SourcesDirective ::= $sources newline SourceLines newline $end-sources
The $sources and $end-sources directives bracket a sequence of source lines which will be repeatedly expanded, once for each implementation file that was generated from the Definition File. See Table 2 for those template variables which are defined within the SourceLines of this directive.
Do not place any other directives within the SourceLines.
Example: Header File
$sources
EZCompile( $[SourceFile],STUBGEN)
$end-sources
The above sequence will generate compilation directives for all of the generated implementation files of a given category.