Registry Statement Summary
Registry is either a terminal or nonterminal command statement that occurs in both command and reference scripts. The registry is a directory which stores named settings and options for a variety of special uses within
gmBasicor within user specified runtime Dlls. It contains a simple hierarchical set of name-value pairs stored under a type identifier. The values are either simple strings or a text buffer.
The attributes of the Registrystatement are as follows:
Attribute | Description |
Type | This attribute contains the identifier of the "special use" of the name-value pair being entered. If it is omitted, then the value LibName is supplied. Though gmBasic, itself uses a set of these types which are reserved, any other identifiers may be used. They are simple identifiers beginning with a letter and containing only letters and numbers. They are not case-sensitive. |
Source | This attribute contains the source name of the pair to which a target value is to be assigned. It may have any content. If a given pair is intended to be unique within a given type, then its name must be unique within that type only. They are not case-sensitive. |
Target | This attribute is used only with the terminal form of the statement. It contains the target value of the pair. It may have any content and need not be unique. At any given time a given source with a given type can have only one target. If the target attribute is missing or empty then the name value pair is treated as though it no longer exists within its location. |
For the nonterminal form of the
Registry statement the records in the scope of the statement are entered into a text buffer in raw form and that buffer is then associated with the source name. Any
gmSLprocessing which these raw statements might undergo is performed when they are used not here where they are simply stored.
The current, globalsettings, and language storage areas all contain registries. Which registry is searched for a given type depends upon the type. They are as follows. Dependency: Specify a possibly omitted include file dependency
Dependency is a terminal registry type that is stored in the current storage area. Many ASP sites suffer from what is called "Omitted Include Syndrome". That is they contain code that depends on other includes, but not all of these needed includes are in the scope of every pageslice. This is particularly troublesome when the omitted includes contain variable declarations or scripted classes. The registry
Dependencytype is used to deal with this syndrome.
The attributes of the Dependencytype are as follows:
Attribute | Description |
Source | Pathname of include with a dependency |
Target | Pathname of include depended upon |
The tool processes this registry type as follows:
- Before loading a reference to an include, determine if that include has a Dependency target entry. If the target include has already been loaded into the application being loaded, do nothing.
- If the target has not yet been loaded, load the target as if there had been an #include of target above the reference to source in the active pageslice.
- If target is also a source in another registry dependency type recursively process that dependency as well.
- If source is already loaded do not load it again. This is needed because a target include may well follow the source -- i.e. not actually be an omitted include file -- in an include sequence and will thus already have been loaded by this algorithm.
Since the algorithm does not require that dependent includes precede their sources, it is not expected to cycle. However, sites with cyclic include references do exist which may well be complicated by the aggressive use of this facility -- so user beware.
EditFile: Supply a set of Fix statements for a specified file
EditFile is a nonterminal registry type that is stored in the globalsettings storage area. Very large code sites consisting of many, often shared, code files that require fixes need a way to organize these fixes. The simple use of general script templates to apply to all jobs in a migration set requires that each command script processed by
gmBasic include all fixes for all jobs. In these template script files
Fixstatements are skipped if their host is not defined in the job at hand. In processing these, the search for the host has to be performed and the actual statements being skipped have to be checked for the termination record. These are trivial operations for small sites, but can quickly build up for large sites.
The EditFile source attribute specifies the full pathname of the file to be edited. The actual Fixstatements then form the target text buffer.
theme | Eclipse |
<Registry type="EditFile" source="Pathname of file to be fixed" >
<Fix>
fix statements
</Fix>
</Registry>
|
When a source file is initially loaded, be it a code file, or a VBP project file, or a web file, the globalsettings registry is checked for an EditFile on its full pathname. If present, the fixes are applied to the file using the standard facilities of the Fixstatement.
The other advantage of using EditFile as opposed to the Compile Fix statement is that it is file specific not compilation set specific. Compile fix, for example, cannot edit the project file directly in its raw form as EditFile can. In the case of web files they are first converted into compilable form before they are presented to the compiler for processing. This form is close to the form of the raw web page, but it is sometimes difficult to construct the fix specifications correctly. EditFile simply sees the web file when it is loaded before any other processing occurs. FixType: Fix the type of a source component
FixType is a terminal registry type that is stored in the current storage area. It is used to fix the types of source code symbols when they are first encountered.
gmBasic uses
FixType registry statements when it authors the
TypeInference reference script; however, they can also easily be entered into command scripts or be authored via
gmNI.
The attributes of the FixTypetype are as follows:
Attribute | Description |
Source | The possibly qualified identifier of a source code symbol whose type is the be fixed. Each time a new symbol reference is encountered gmBasic forms its fully qualified identifier, namespace.class.member.[..]. This identifier is then checked for a FixType target. If not found, the namespace component is removed from the fully qualified identifier, and that is checked for a target, and so on. Thus, depending upon how this attribute is written it can fix the type of only one symbol or of many symbols that have the same name. |
Target | The type to be applied to symbols whose identifiers match the source. This is either an identifier of one of the built in types or it is the qualified identifier of a user or external type. |
The checks for the
FixType registry entries are made during pass1 of the compiler when it encounters the definition of a variable or subprogram that is specified as
VARIANT or
OBJECT. They are also made by the pass2 compiler when it encounters the reference to an undeclared variable,
FixStatus: Specify an ASP page status
FixStatus is a terminal registry type that is stored in the current storage area. It is used to change the translation status of a web page to
UserControlas opposed to a code class or a regular aspx page.
The attributes of the FixStatustype are as follows:
Attribute | Description |
Source | The full pathname of the asp page whose status is to change. |
Target | An identifier for the status desired. At this time the only entry is UserControl which means to translate the page as a usercontrol. |
The
FixStatus entries are checked for at compile time, so they must precede the first compile statement that will load the file.
Guid: Define the value of a GUID
Guid is a terminal registry type that is stored either in the current storage area or the language storage area. The user storage area is checked first. Entries of this type are checked for by the
gmSL.Runtime.Guid() method, which has one string parameter
GuidName. That method attempts to find a
Guidtype entry whose source matches its parameter. If found, the target value is the guid to be used. If not found a new guid is generated and used.
The attributes of the Guidtype are as follows:
Attribute | Description |
Source | The logical name of the guid being sought. At the present time authoring methods within gmBasic seek the following logical names: Project, ProjectType1, ProjectType2, Flavor, and Interfaces. All have default values registered in the language file. Users can add additional logical names as needed. |
Target | The actual GUID to be used for the logical name. |
The default values for the logical names currently being used are
theme | Eclipse
<Registry type="guid" source="Project" target="{7EE74E01-07B7-4C4F-B053-895BB67A3A51}" />
<Registry type="guid" source="ProjectType1" target="{349C5851-65DF-11DA-9384-00065B846F21}" />
<Registry type="guid" source="ProjectType2" target="{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}" />
<Registry type="guid" source="Flavor" target="{349C5851-65DF-11DA-9384-00065B846F21}" />
<Registry type="guid" source="Interfaces" target="{447E0939-9DC6-40F4-A30E-26DC252607D3}" />
|
To change them, simply add an equivalent statement to the command script that does the authoring. Such entries are often put in the environment files loaded by scripts. IdfStatus: Specify the Interface Description File status of an external
IdfStatus is a terminal registry type that is stored in the current storage area. Reference scripts describing an external component like a Dll, or an ocx, or an olb, or a tlb are referred to as
IDFs -- "Interface Description Files". The IdfStatus specifies how references to these components are to be treated. There four possible target settings --
Build,
Migrate,
Interop and
External. When the
Buildfile Select is
local or
global then the default IdfStatus is
Build and the tool will author external dependencies as stub files or stub projects respectively. When
BuildFile is
off then the default IdfStatus is
Migrate and the tool will author external dependencies as an assembly reference. The
Interop setting is an intermediate one which says that any Mig files associated with the reference should be ignored. The
Externalstatus blocks the authoring of stubs completely.
This attribute overrides the default status of the reference. The attributes of the IdfStatustype are as follows:
Attribute | Description |
Source | The identifier of the external component whose default status is to be overridden. |
Target | One of the status identifiers: Build, Migrate, Interop or External. |
MigrationSupport has special status in the system. The registry entry
themelinenumbers | Eclipse |
<Registry type="IdfStatus" source="MigrationSupport.dll" target="External" />
|
or adding the attribute idfStatus="external" to the library command causes MigrationSupport.dll to behave as other libraries do. Include: Specify the path to an include file
Include is a terminal registry type is stored in the current storage area. When
gmBasic loads include files from ASP pages it first forms the full name of the include based on the pathname of the including file. Once this has been formed, the registry is checked for an
Includeentry that can specify a different pathname.
The attributes of the Includetype are as follows:
Attribute | Description |
Source | The pathname of the include as it would be formed by combining it with the pathname of the including file. |
Target | The actual pathname to be used for the include. |
LibName: Specify a library name or file name
LibName is a terminal registry type that is stored in the current storage area. It is used to change the name of an external component from the way it is being referenced either in the project file or in the source code into the name of the component describing it in the migration. External libraries are ultimately identified via their filename like
mso.dll or
msword9.olb or
mscomctl.ocx or
msado20.tlb. There are, however, in the windows registries at the home sites often alternative
ProgIds registered for these names. It is these
ProgIds that are used in the codes. The first reason for using the this registry type is to reconvert the
ProgIdsback into the local filenames.
The second reason for using the LibName registry type is to supply the name of a migrated description of the component to the translation scripts. Thus, if mscomctl.ocx has a migrated description in a file GM.mscomctl.ocx, then this type is used to make the switch.
The third reason is that source code bases often reference different versions of what is logically the same external component. For example there might be references to both msado25.tlb and msado21.tlb. In the translations the two get mixed and as such their classes are viewed as being different. Also redundant migration instructions need to be constructed. A set of statements like
theme | Eclipse
<Registry type="libname" source="msado15.dll" target="msado26.tlb"/>
<Registry type="libname" source="msado20.tlb" target="msado26.tlb"/>
<Registry type="libname" source="msado21.tlb" target="msado26.tlb"/>
<Registry type="libname" source="msado25.tlb" target="msado26.tlb"/>
<Registry type="libname" source="msado27.tlb" target="msado26.tlb"/>
|
resolves these problems.
The attributes of the Libnametype are as follows:
Attribute | Description |
Source | The pathname or ProgId of the external as it appears in the source code or project file. |
Target | The actual library local filename to be used to load the reference script that describes the external. |
OverLoadArgument: Specify types for arguments to be overloaded
OverLoadArgumentis a terminal registry type that is stored in the globalsettings area. It is used to specify that individual subprogram arguments be overloaded to accept a list of differ types.
The attributes of the OverLoadArgumenttype are as follows:
Attribute | Description |
Source | This attribute contains the fully qualified name of the argument -- i.e. project_identifier.class_identifier.subprogram_identifier.argument_identifier -- that is to be overloaded. |
Target | This attribute contains a comma-delimited list of the types to be allowed for the overloaded argument. |
The registry is checked for the
OverLoadArgument entry for a subprogram argument, either in a source file or in a reference script. If a target entry is found in the registry, then the list of types is processed and stored within the symbol table entry for that argument.
ProgId: Resolve a ProgId
ProgId is a terminal registry type that is stored in the current storage area. It is used to resolve the
ProgId argument value passed to the VB6 CreateObject method. The VB6 CreateObject method
CreateObject(progid As string,[servername As string])
creates and returns a reference to an ActiveX object. The
ProgId argument contains the application name and class name of the object to create. If the ProgId can be determined,
gmBasic scans the
ProgIdentries in the registry for any substitutions.
The attributes of the ProgIdtype are as follows:
Attribute | Description |
Source | The identifier of the ProgId as determined from the call to CreateObject. |
Target | The identifier to be substituted for the ProgId to resolve its reference. |
RefactorFile: Supply a set of Refactor statements for a specified file
RefactorFile is a nonterminal registry type that is stored in the globalsettings storage area. Very large code sites consisting of many, often shared, code files whose symbols require refactoring organize these statements. The simple use of general script templates to apply to all jobs in a migration set requires that each command script processed by
gmBasiccheck all refactoring statements for all jobs. In processing these, the symbol search has to be performed for each. This is a trivial operation for small sites, but can quickly build up for large sites.
The RefactorFile source attribute specifies the full pathname of the file whose symbols are to be refactored. The actual Refactorstatements then form the target text buffer.
theme | Eclipse
<Registry type="RefactorFile" source="Pathname of file to be refactored" >
<Refactor>
refactor statements
</Refactor>
</Registry>
|
The registry is checked once for a RefactorFile entry for each class, module, form, or ASP file after the symbols for that file have been loaded but before and code has been compiled. There is nothing special about the refactor statements themselves. They behave exactly the same as Refactor statements placed within a Compilestatement for a code project containing the specified file. Thus, the entry
theme | Eclipse
<Registry type="RefactorFile" source="\code\vb6\CommonFunctions.cls" >
<Refactor>
<FixType identifier="SortCollection.aObject" type="Interfaces.Icbn_Compare" />
</Refactor>
</Registry>
|
in a selected global settings file is identical to the following in a translation script
theme | Eclipse
<Compile project="\code\vb6\VariousCommonFunctions.vbp" >
<Refactor fileFilter="[\code\vb6\CommonFunctions.cls]">
<FixType identifier="SortCollection.aObject" type="Interfaces.Icbn_Compare" />
</Refactor>
</Compile>
|
Note the need in the FileFilter attribute for the square brackets surrounding the filename. They are supplied for the registry filename which must not contain those the brackets. SharedFile: Specifies that a file is shared and should only be processed once
SharedFile is a terminal registry type that is stored in the globalsettings storage area. The statements themselves are authored by the
SharedFileutility statement. It is used to identify those files that are used by more than one VB6 project and to identify which project should be the only one that processes it. The other projects then refer to the components in the shared file as though they were external library components.
The attributes of the SharedFiletype are as follows:
Attribute | Description |
Source | The full pathname of a code file that is shared by multiple code project. |
Target | The full pathname of a project file that is to be defining project for the shared file. |
The
SharedFile statement description contains a detailed discussion.
UsesInterfaces: Specifies that a project file uses certain interfaces
UsesInterfaces is a terminal registry type is stored in the globalsettings storage area. It is used to resolve references between independent projects that do not correspond to the build order -- i.e., a reference by a project early in the build order to one later in the order. These can even become circular references. A
circularreference occurs when two projects reference each other either directly or indirectly via intermediate references. Clearly no rearrangement of the build order can be made to resolve circular references. To make this workable under .NET a migration is needed that uses interfaces to describe those classes that are being referenced before they are defined. Codes that use these interfaces must now reference the interface classes and not the concrete classes; and codes that define classes that are to be used in interface form must define those interfaces.
For example, assume a small system consisting of two projects Project1 and Project2 is built in that order. The problem is that Project1 references a class2 in Project2 and Project2 references a class1 in Project1. To resolve this, gmBasic creates an interface for class2 that defines the public methods of that class in project2 and any references to class2 in Project1 are changed into references to the interface class as opposed to the concrete class. Now when gmBasic processes Project2 it makes certain that Project2implements the interface class in the concrete code for that class.
The first problem is to determine what information is needed to perform the uses interfaces migration and how that information can be specified. The information needed is a list of projects that must use interfaces along with a list of which projects supply those interfaces. In the example described above then the list would be
theme | Eclipse
project1 usesInterfaces project2
project2 usesInterfaces project1
|
Note that the list is in build order since some of the low level symbol referencing migrations are dependent on this order. The UsesInterfacesregistry type is used to store the list.
The attributes of the UsesInterfacestype are as follows:
Attribute | Description |
Source | This attribute contains the Exename32 name of the using project. |
Target | This attribute contains a comma-delimited list of the Exename32 names of the supplying projects. |
The symbol table retains the order in which the registry commands are entered under a given type, so determining order of entry is simple. In the present case then the registry statements would be as follows.
theme | Eclipse <Registry type="UsesInterfaces" source="Project1.dll" target="Project2.dll" />
<Registry type="UsesInterfaces" source="Project2.dll" target="Project1.dll" />
|
If a given project must reference more that one other project via an interface, then the target entry may contain a comma-delimited list. This might look as follows.
theme | Eclipse |
<Registry type="UsesInterfaces" source="Project2.dll"
target="Project1.dll,Project3.dll,Project4.dll" />
|
The Exename32 attributes are used to reference projects, not their filenames. This is because within referencing projects the library name is needed. It is the Exename32 attribute that supplies this name. Though the worse case scenario is a circular reference, the approach here does not assume this. Rather as each project code is processed, if its Exename32 is one of the target UsesInterfaces entries then all global classes in that project are classified as supplying an interface and all classes referenced in library files whose library name is one of the source are classified as usingan interface.
At this point in time the UsesInterfaces list must be constructed by hand. The BuildOrder report does detect ordering problems but that detection does not appear to have enough information at this time. The basic rule is that if a project references a class from an earlier project either as the type of a method or as the type of a parameter to a method or as an instantiation within a method, then an interface must be used.