gmslWriteClass
The Write Service Class
Section titled “The Write Service Class”The Write service class contains the basic methods needed to write structured reports and text files of various sorts using binary information. It is used very extensively by gmBasic during every phase of its operation and is fully exposed via gmSL. Ultimately, at any given point in time, only one coded output report can be written at one time. Logically, a structured text output, be it a free-form text representation or a tabular representation containing fixed fields, is viewed as having four levels:
| Level | Description |
|---|---|
| File | There are 5 totally independent file structures that may be in use. Initially only 1 of these, unit 1, is active. It is managed via the gmPL Output statement. Internally, gmBasic uses unit 5 as a scratch output file. This unit is never left open outside of a given task within the process. The other units are available as needed. (Note to tool implementers that there is a constant WRT_PROVIDERS, currently set to 5, that may be changed when doing a tool build. It is unit 1 and unit WRT_PROVIDERS whose use is restricted to gmBasic.) Each file has a physical file associated with it, which is either a named file or the Standard Output file. At any given point in time only one file unit is active, unit 1 is always the default, and all write operations are performed on that unit. The term selected unit is used to refer to the currently active one. |
| Stream | By default records are written to the physical file associated with the selected unit; however, in many cases what is needed is an internal representation of what is to be written to the file. This representation, referred to as a text stream, can then be saved, edited, audited, and perhaps eventually physically written to a file. At any point in time, the selected unit is either writing to its physical file or to a text stream. During its life a file unit can spawn as many text streams as desired, but can only process one at a time. |
| Record | Each file unit has a record buffer associated with it. This buffer stores the characters being written until it is physically written to the active stream or is disposed of in some other manner such as being copied to the runtime data queue. Low level methods in this service class all add their output to the record associated with the selected unit. The records in the different units are completely independent of each other. The maximum number of characters that may stored in a record at one time is 8192. (Note to tool implementers there is a constant MAX_BUFFER that defines this value.) |
| Field | Ultimately each method that adds characters to a record is said to be “writing a field” at the back of the record of the selected unit. Characters can be entered into fields either free-form, or left-justified in a fixed-width field with a white space to the right, or right-justified in a fixed-width field with white space to the left. |
Write_ChangeMargin Method
Section titled “Write_ChangeMargin Method”gmSL: void Write_ChangeMargin(int delta)
When authoring gmBasic does not attempt to reproduce the leading white space in the source code;
rather, it keeps track of the margin nesting level via the p and q escape characters
in the surface patterns or via calls to this method and then uses this margin level times the indentation
width specified via the Select Indent attribute to determine the number of leading blanks or tabs
to add.
This method adds the value of delta to the current margin level. If delta is negative,
the indentation will be decreased, and if it is positive, the indentation will be increased. If the
computed margin level ends up being negative, it is set back to zero.
As an example, the following method displays unindented and indented lines.
void DemoWriteChangeMargin(string comment) { Write_Line("Unindented Line: " + comment); Write_ChangeMargin(1); Write_Line("Indented Line: " + comment); Write_ChangeMargin(-1); Write_Line("Unindented Line: " + comment); }Then the gmPL statements
<Select Indent="3" /> <Output Status="New" Filename="Demo001.out" /> <RunCommand Id="scmCode.DemoWriteChangeMargin" prams="Indent is selected at 3"/> <Select Indent="8" /> <Output Status="Old" Filename="Demo001.out" /> <RunCommand Id="scmCode.DemoWriteChangeMargin" prams="Indent is selected at 8"/> <Select Indent="0" /> <Output Status="Old" Filename="Demo001.out" /> <RunCommand Id="scmCode.DemoWriteChangeMargin" prams="Indent is selected at 0"/>generate the following output
Unindented Line: Indent is selected at 3 Indented Line: Indent is selected at 3 Unindented Line: Indent is selected at 3 Unindented Line: Indent is selected at 8 Indented Line: Indent is selected at 8 Unindented Line: Indent is selected at 8 Unindented Line: Indent is selected at 0 Indented Line: Indent is selected at 0 Unindented Line: Indent is selected at 0Note that the value of the selected indent is applied when the output file is opened. Using the Old status forces this open to occur while still writing to the back of the file.
Write_Character Method
Section titled “Write_Character Method”gmSL: void Write_Character(int charValue
This method appends the ASCII character whose display code is specified by charValue to the current
output record. No actual write occurs at this time.
Note that if called from gmSL with a string argument, the string is not converted to an integer
as would be the normal convention; rather, the value of the first character in the string is passed.
As an example the following displays a character value
Sub DemoWriteCharacter(ByVal theCharacter) Write_Text "Character Value is: " Write_Character(theCharacter) Write_Record End SubNote that the parameter theCharacter is not typed in the code; therefore, it will take on its type based on the type of the argument passed in as shown in the following
<Output Status="New" Filename="Demo002.out" /> <RunCommand Id="vbCode.DemoWriteCharacter" prams="65"/> <RunCommand Id="vbCode.DemoWriteCharacter" prams="F"/> <RunCommand Id="vbCode.DemoWriteCharacter" prams="'65'"/>which produces the following output
Character Value is: A Character Value is: F Character Value is: 6A is the character with display code 65; whereas the string ‘65’ simply has its first character displayed.
Write_CloseFile Method
Section titled “Write_CloseFile Method”gmSL: void Write_CloseFile()
The Write_CloseFile method closes the selected unit and any physical file associated with that unit.
Upon completion, unit 1, the unit associated with the gmPL Output statement, becomes the
selected unit.
The following code opens and writes records to three different files — two files that it maintains
under units 2 and 3 and the file associated with the Output statement. The important point made
in this example are the two writes done after the file closings. It is these writes that go to the
Output file.
void DemoWriteSelect(string file1,string file2) { Write_OpenFile(2,file1,True,OutStyle.Text); Write_OpenFile(3,file2,True,OutStyle.Text); Write_Select(2); Write_Line("Line 1 in File " + file1); Write_Select(3); Write_Line("Line 1 in File " + file2); Write_Select(2); Write_Line("Line 2 in File " + file1); Write_CloseFile(); Write_Line("Line 1 in Output File"); Write_Select(3); Write_Line("Line 2 in File " + file2); Write_CloseFile(); Write_Line("Line 2 in Output File");}The following gmPL statements then write output to three different files.
<Output Status="New" Filename="Demo017.out" /> <RunCommand Id="scmCode.DemoWriteSelect" prams="Demo017A.out;Demo017B.out" />and the results are as expected. The file Demo017A.out contains
Line 1 in File Demo017A.out Line 2 in File Demo017A.outand file Demo017B.out contains
Line 1 in File Demo017B.out Line 2 in File Demo017B.outand file Demo017.out, the Output file contains
Line 1 in Output File Line 2 in Output FileWrite_CloseStream Method
Section titled “Write_CloseStream Method”gmSL: int Write_CloseStream()
In gmBasic authored records are stored in text buffers within the current storage area. The CloseStream method closes the currently open text buffer and returns its integer handle. This handle must be saved by the caller to be used later to either reopen the text buffer or to physically write it to a file. If writes are currently being sent directly to the file specified in the Output statement, then this method does nothing.
The following code shows how text buffers as used.
void DemoWriteTextStreams(string theAuthor) { int textRoot; Handle textStream;
Write_Line("Write record to Output file before opening a text buffer"); Write_OpenStream(); #TextStart Hello World This is a message from (%= theAuthor %) GoodBye World #TextEnd textRoot = Write_CloseStream(); Write_Line("Write another record then write content of text buffer"); textStream = Text_Open(Store_GetHandle(),textRoot); Write_TextStream(textStream,0,0); Text_Close(textStream); }The records both before and after the write to the text buffer go to the Output file before the buffer itself is written using the Write_TextStream() method. Note it is the return value from this method that is needed to open the text buffer for later use. This code then
<Output Status="New" Filename="Demo003.out" /> <RunCommand Id="scmCode.DemoWriteTextStreams" prams="Kilroy"/>produces the following output.
Write record to Output file before opening a text buffer Write another record then write content of text buffer Hello World This is a message from Kilroy GoodBye WorldNotice also that the #TextStart .. #TextEnd block behaves in the same manner as text written explicitly using the Write service class.
Write_Field Method
Section titled “Write_Field Method”gmSL: void Write_Field(string strValue, int nString, int iField)
This method is the lowest level utility within the Write service class. It appends a specified field of
characters to the current output record. No actual write occurs at this time. Within that field the
content of strValue may be preceded or followed by white space. nString specifies the
number of characters from strValue that are to be used. iField specifies how the characters
from strValue should be entered:
| Value | Meaning |
|---|---|
| 0 | Simply append the characters to the current content of the output record. |
| +n | Right justify the characters in a field n characters wide appended to the back of the current record. |
| -n | Left justify the characters in a field n characters wide appended to the back of the current record. |
Note that when called via gmSL if nString is set to zero, then the length of the string will be used.
The following code uses this method to display a string in various ways
void DemoWriteField(string aLongString) { Write_Field(aLongString,0,0); Write_Record(); Write_Field(aLongString,5,0); Write_Record(); Write_Text("LEFT("); Write_Field(aLongString,10,-12); Write_Text(")RIGHT"); Write_Record(); Write_Text("LEFT("); Write_Field(aLongString,10,12); Write_Text(")RIGHT"); Write_Record(); }When called as follows
<Output Status="New" Filename="Demo004.out" /> <RunCommand Id="scmCode.DemoWriteField" prams="Kilroy was here"/>it produces this output
Kilroy was here Kilro LEFT(Kilroy was )RIGHT LEFT( Kilroy was)RIGHTWrite_Integer Method
Section titled “Write_Integer Method”gmSL: void Write_Integer(int iValue, int iField)
This method appends the base 10 display form of iValue in a specified field of characters
to the current output record. No actual write occurs at this time. No special formatting flags are
available. iField specifies how the characters of the display form should be entered:
| Value | Meaning |
|---|---|
| 0 | Simply append the characters to the current content of the output record. |
| +n | Right justify the characters in a field n characters wide appended to the back of the current record. |
| -n | Left justify the characters in a field n characters wide appended to the back of the current record. |
The following code uses this method to display an integer value in various ways
void DemoWriteInteger(int iValue) { Write_Text("LEFT("); Write_Integer(iValue,0); Write_Text(")RIGHT"); Write_Record(); Write_Text("LEFT("); Write_Integer(iValue,-10); Write_Text(")RIGHT"); Write_Record(); Write_Text("LEFT("); Write_Integer(iValue,10); Write_Text(")RIGHT"); Write_Record(); }When called as follows
<Output Status="New" Filename="Demo005.out" /> <RunCommand Id="scmCode.DemoWriteInteger" prams="12345" />it produces this output
LEFT(12345)RIGHT LEFT(12345 )RIGHT LEFT( 12345)RIGHTWrite_Line Method
Section titled “Write_Line Method”gmSL: void Write_Line(string strValue)
This method appends all characters from strValue to the current output record and then writes
the result either to the currently open text buffer or to the file specified in the Output statement.
No formatting is applied to the string.
The following code contrasts using a TextBlock versus using Write_Line() and Write_ChangeMargin().
void DemoWriteLine(string theAuthor) { #TextStart Hello World This is a message from (%= theAuthor %) GoodBye World #TextEnd Write_Line("Hello World"); Write_ChangeMargin(1); Write_Line("This is a message from " + theAuthor); Write_ChangeMargin(-1); Write_Line("GoodBye World"); }When called as follows
<Output Status="New" Filename="Demo007.out" /> <RunCommand Id="scmCode.DemoWriteLine" prams="Kilroy" />it produces this output
Hello World This is a message from Kilroy GoodBye World Hello World This is a message from Kilroy GoodBye WorldWrite_LogMessage Method
Section titled “Write_LogMessage Method”gmSL: void Write_LogMessage(string message) ****
The Write_LogMessage method writes a string message to the file. This is the same file used by
gmBasic for its messages. The following gmPL script shows how this method might be used to
debug a malfunctioning script.
<gmBasic> <Storage Action="Create" /> <gmsl>Write_LogSetName("Demo018.log")</gmsl> <gmsl>Write_LogMessage("<!-- translation options ")</gmsl> <Select progress="1" /> <Select DevEnv="VS2010" /> <Select Dialect="csh" /> <Select BuildFile="global" /> <gmsl>Write_LogMessage("<!-- directories for deployment and external assemblies -->")</gmsl> <Select DeployLocation="c:\gmProj\lab\deploy\externs\CrashV1003_csh" /> <Select Library="c:\gmProj\lab\deploy\externs" /> <select Target="c:\gmProj\lab\idf\FromCode" /> <Select Local="c:\gmProj\lab\idf\FromCode" /> <Select System="c:\gmProj\lab\idf\FromIdl" /> <gmsl>Write_LogMessage("<!-- processing commands -->")</gmsl> <Compile Project="c:\gmSrc\GMTest\CrashV1003\CrashV1003.vbp" /> <gmsl>Write_LogSetName(Null)</gmsl> <Analyse /> <gmsl>Write_LogMessage("<!-- authoring commands -->")</gmsl> <Output Status="New" Filename="Demo018.bnd" /> <Author /> <Storage Action="Close" /> <gmsl>Write_LogMessage("<!-- End of script -->")</gmsl> </gmBasic>Note first of all, that gmSL command mode is being used in this script. Though the logging methods
can be used in runtime code as desired for messages, they are also ideal for direct use within scripts.
Running this script produces this Demo018.log file
<!-- translation options <!-- directories for deployment and external assemblies --> <!-- processing commands --> Processing file: c:\gmSrc\GMTest\CrashV1003\CrashV1003.vbp Loading reference:[stdole2.tlb] c:\gmProj\lab\idf\FromIdl\stdole2.tlb.xml Loading reference:[scrrun.dll] c:\gmProj\lab\idf\FromIdl\scrrun.dll.xml Reprocessing file: c:\gmSrc\GMTest\CrashV1003\clsCrashV1003.cls Reprocessing file: c:\gmSrc\GMTest\CrashV1003\clsCrashV1003.clsand then sends these remaining messages to Standard output.
<!-- authoring commands --> <!-- End of script -->Note that the messages written by this method coexist with the messages written by gmBasic and both use the same file.
Write_LogSetName
Section titled “Write_LogSetName”gmSL: void Write_LogSetName(string fileName)
The Write_LogSetName methods sets a fileName for the file to receive all messages — progress,
warning, error, etc. — written during a given run. It also receives all messages written via the
Write_LogMessage() method. By default log messages are simply written to the Standard Output file;
however, when set to a named file, that file is opened for append access prior to each write and is then
closed after the write. This ensures that no output sent to a named log file is lost in cases where abnormal
exits are occurring. To set the log file back to using Standard Output pass it either Null or
Nothing.
The following script reproduced from the discussion of the Write_LogMessage() shows these two types
of calls.
<gmBasic> <Storage Action="Create" /> <gmsl>Write_LogSetName("Demo018.log")</gmsl> <gmsl>Write_LogMessage("<!-- translation options ")</gmsl> <Select progress="1" /> <Select DevEnv="VS2010" /> <Select Dialect="csh" /> <Select BuildFile="global" /> <gmsl>Write_LogMessage("<!-- directories for deployment and external assemblies -->")</gmsl> <Select DeployLocation="c:\gmProj\lab\deploy\externs\CrashV1003_csh" /> <Select Library="c:\gmProj\lab\deploy\externs" /> <select Target="c:\gmProj\lab\idf\FromCode" /> <Select Local="c:\gmProj\lab\idf\FromCode" /> <Select System="c:\gmProj\lab\idf\FromIdl" /> <gmsl>Write_LogMessage("<!-- processing commands -->")</gmsl> <Compile Project="c:\gmSrc\GMTest\CrashV1003\CrashV1003.vbp" /> <gmsl>Write_LogSetName(Null)</gmsl> <Analyse /> <gmsl>Write_LogMessage("<!-- authoring commands -->")</gmsl> <Output Status="New" Filename="Demo018.bnd" /> <Author /> <Storage Action="Close" /> <gmsl>Write_LogMessage("<!-- End of script -->")</gmsl> </gmBasic>Write_NText Method
Section titled “Write_NText Method”gmSL: void Write_NText(string strValue, int nText)
This method appends the first nText characters from strValue to the current output record.
No actual write occurs at this time. No formatting is applied to the string. Note that care must be
taken that nText does not exceed the length of strValue. Since gmSL supports a string
type, this method is rarely needed. It is intended primarily for use by gmNI.
The following code uses this method to display an a string value fully and in truncated form
void DemoWriteNText(string aLongString) { Write_Text(aLongString); Write_Record(); Write_NText(aLongString,5); Write_Record(); }When called as follows
<Output Status="New" Filename="Demo006.out" /> <RunCommand Id="scmCode.DemoWriteNText" prams="Kilroy was here" />****it produces this output
Kilroy was here KilroWrite_OpenFile Method
Section titled “Write_OpenFile Method”gmSL: void Write_OpenFile(int unit, string fileName,bool statusNew,gmsl.OutStyle syntax)
****There are 5 totally independent file structures that may be in use. The Write_OpenFilegmPL Output statement which uses unit 1.
The Unit parameter specifies which file unit is to be used. It must be a value between 1 and 5, though as the example below will show using unit 1 is equivalent to using the Output statement. The fileName parameter is the name of the file to be opened, and the statusNew parameter, if True request that a new file be created as opposed to opening an existing file for append access. The syntax parameter specifies the output style to be used when producing tabular reports. They can be produced in one of three styles: Tabbed simple tab delimited; Text text tabular; or Html html tabular.
The procedure below sows a simple method that could be used as a replacement for the gmPL Output statement.
void DemoWriteOpenFile(string fileName, bool statusNew) { Write_OpenFile(1,fileName,statusNew,OutStyle.Text); }and when used as follows
<gmBasic> <Storage Action="Create" /> <Select GlobalSettings="GmslCode.vbi" /> <LoadEnvironment /> <RunCommand Id="scmCode.DemoWriteOpenFile" prams="Demo016.out;.T." /> <RunCommand Id="vbCode.DemoWriteCharacter" prams="65"/> <RunCommand Id="vbCode.DemoWriteCharacter" prams="F"/> <RunCommand Id="vbCode.DemoWriteCharacter" prams="'65'"/> <Storage Action="Close" /> </gmBasic>produces the same output as the statement
<Output Status="New" Filename="Demo016.out" />would have produced.
Write_OpenStream Method
Section titled “Write_OpenStream Method”gmSL: void Write_OpenStream()
In gmBasic authored records are stored in text buffers within the current storage area. The OpenStream method creates such a text buffer and makes it the current output stream. All subsequent writes will go to this stream until it is closed. At which point the current output stream will revert to the file specified in the Output statement.
The following code shows how text buffers as used.
void DemoWriteTextStreams(string theAuthor) { int textRoot; Handle textStream;
Write_Line("Write record to Output file before opening a text buffer"); Write_OpenStream(); #TextStart Hello World This is a message from (%= theAuthor %) GoodBye World #TextEnd textRoot = Write_CloseStream(); Write_Line("Write another record then write content of text buffer"); textStream = Text_Open(Store_GetHandle(),textRoot); Write_TextStream(textStream,0,0); Text_Close(textStream); }The records both before and after the write to the text buffer go to the Output file before the buffer itself is written using the Write_TextStream() method. This code then
<Output Status="New" Filename="Demo003.out" /> <RunCommand Id="scmCode.DemoWriteTextStreams" prams="Kilroy"/>produces the following output.
Write record to Output file before opening a text buffer Write another record then write content of text buffer Hello World This is a message from Kilroy GoodBye WorldWrite_Pattern Method
Section titled “Write_Pattern Method”gmSL: void Write_Pattern(string PatString, int nPattern, string Parameters)
This method enters the pattern string PatString starting at the current location in
into the current output record using editing directives within the string along with parameters
defined in Parameters. nPattern contains the number of characters in PatString
to be used. Parameters contains a semicolon-delimited string containing parameters
referenced via their number. If the PatString contains no such references it may be empty.
No actual write occurs at this time.
Directives within PatString are enclosed in % signs. The following are recognized:
| Directive | Meaning |
|---|---|
| %% | Enter a percent sign |
| %USR_VERSION% | Platform specified user version identifier |
| %PRM_VERSION% | Platform specified system version identifier |
| %PRM_BUILDID% | Platform build signature string |
| %DATE% | Current date using currently selected formatting options |
| %TIME% | Current time using currently selected formatting options |
| %envname% | Value of environment variable envname. It must begin with an alphabetic character and may contain no more than 31 characters. |
| %nd | Enter the nth (1-based) parameter string |
Note that when called via gmSL if nPattern is set to zero, then the length of PatString will be used.
The following code shows how a pattern can be used.
void DemoWritePattern(string what, string whom) { Write_Pattern("The event %1d happened at %TIME% on %DATE% to %2d", 0, what + ";" + Whom); Write_Record(); }As an example, the following commands
<Output Status="New" Filename="Demo008.out" /> <RunCommand Id="scmCode.DemoWritePattern" prams="Got Lost;Kilroy" />produce the output
The event Got Lost happened at 13:33:03 on 2013-01-02 to KilroyNote that in this case the use of semicolons within the RunCommand prams attribute interferes with the use of semicolons in the Parameters parameter here, so some care must be taken.
Write_Record Method
Section titled “Write_Record Method”gmSL: void Write_Record()
This method completes the authoring of the current output record and then writes the result either to the currently open text buffer or to the file specified in the Output statement. The steps performed before the write include: first, special codes that are used to represent single and double quotes in either escaped or un escaped form must be converted to the final form required by the target language; second, if the echo translation flag is set then the current margin nesting level and the record are written to the log file; third, if the author is writing ASP code then the record must be checked for a transition into or out or VBSCRIPT; and fourth, if the record is longer that the Select MaxOutputWidth value then it is broken into multiple records using the conventions of the target language.
The following code contrasts using Write_Text() and Write_Record() with using Write_Line().
void DemoWriteRecord(string theAuthor) { Write_Line("This is a message from " + theAuthor); Write_Text("This is a message from "); Write_Text(theAuthor); Write_Record(); Write_Text("This is a message from " + theAuthor); Write_Record(); }Using this, the following commands
<Output Status="New" Filename="Demo009.out" /> <RunCommand Id="scmCode.DemoWriteRecord" prams="Kilroy" />produce this set of identical lines
This is a message from Kilroy This is a message from Kilroy This is a message from KilroyWrite_Select Method
Section titled “Write_Select Method”gmSL: int Write_Select(int unit)
The Write_Select method selects one the available file structures as the current unit. All successive
write support will be performed by this unit until another call to this service is made or until the
unit is closed. Note that this service only selects the unit it does not open its output channels or change
it in any way. The unit parameter is the unit sequence number of the desired file structure. It must
have a value between 1 and 5. Note that unit 1 is connected to the gmPL Output statement and should
be used with care. Unit 5 is used by gmBasic as a temporary scratch unit — not open between tasks —
and should only be used in the same way here.
The following code, reproduced from the discussion of Write_CloseFile() shows how this method can
be used to flip back and forth between different files.
void DemoWriteSelect(string file1,string file2) { Write_OpenFile(2,file1,True,OutStyle.Text); Write_OpenFile(3,file2,True,OutStyle.Text); Write_Select(2); Write_Line("Line 1 in File " + file1); Write_Select(3); Write_Line("Line 1 in File " + file2); Write_Select(2); Write_Line("Line 2 in File " + file1); Write_CloseFile(); Write_Line("Line 1 in Output File"); Write_Select(3); Write_Line("Line 2 in File " + file2); Write_CloseFile(); Write_Line("Line 2 in Output File");}Write_SetIndentation Method
Section titled “Write_SetIndentation Method”gmSL: void Write_SetIndentation(int indent, int offset)
This method sets the indentation widths for the current output stream. There are two width values: indent which specifies the number of spaces to indent per indentation level (a value of zero means use tabs); and offset which is used when a record is longer than the desired line-width. The following line can be set off this many additional spaces.
When an output file is first created, the default indent value is the Select Indent attribute and the default offset value is zero. When an text buffer is opened the initial values are the values from the current output file. The values specified here take immediate effect and can be changed within the same write sequence.
Consider the following code that writes an un indented line and then an indented one
void DemoWriteSetIndentation(string comment, int indent) { Write_SetIndentation(indent,0); Write_Line("Unindented Line: " + comment); Write_ChangeMargin(1); Write_Line("Indented Line: " + comment); Write_ChangeMargin(-1); }when called multiple times using various indent values
<Output Status="New" Filename="Demo010.out" /> <RunCommand Id="scmCode.DemoWriteSetIndentation" prams="Hello World;8" /> <RunCommand Id="scmCode.DemoWriteSetIndentation" prams="Hello World;1" /> <RunCommand Id="scmCode.DemoWriteSetIndentation" prams="Hello World;(%= Select.Indent %)" />produces the following output
Unindented Line: Hello World Indented Line: Hello World Unindented Line: Hello World Indented Line: Hello World Unindented Line: Hello World Indented Line: Hello WorldThe quantity Select.Indent sets the indentation level back to its original value.
Write_TableCell Method
Section titled “Write_TableCell Method”gmSL: void Write_TableCell()
In many complex output situations it is often desirable to nest the output streams so that complex outputs can be nested within each other or can be constructed with independent sets of logic. This method allows for the writing of complex data cells within data tables. Rather than writing the current output record and thus clearing its internal buffers so that another record can be written, this method pushes the content of the current output record onto the runtime data queue and then clears it. Once a series of cells have been written, then the Write_TableRow() method writes a data row to the currently active output stream using the form required by the Output Syntax attribute set for it.
This method writes a table whose data cells contain information about all of the user defined variables in a completed translation.
Sub DemoWriteTable() Dim iRoot As Integer Dim levels(19) As Integer
DataQueue_SetBottom() Write_Text "Audit of Variables in " & Store_GetDataName() & " storage area" Write_TableCell() Write_TableTitle() DataQueue_PushString("Lev") DataQueue_PushInteger(3) DataQueue_PushString("Address") DataQueue_PushInteger(8) DataQueue_PushString("Full Symbol Identifier") DataQueue_PushInteger(-100) Write_TableHeadings()
iRoot = Store_FindFirstChild(levels,0) Do while(iRoot <> 0) If Store_GetObjectType(iRoot) = ObjectType.VARIABLE Then Write_Integer(levels(0) - 1, 0) Write_TableCell() Write_Integer(iRoot,0) Write_TableCell() Write_Text(Symbol_FullName(iRoot,-1)) Write_TableCell() Write_TableRow() End If iRoot = Store_FindNextChild(levels) Loop Write_TableEnd() DataQueue_ClearBottom(1) End SubA gmPL script that might use this method is as follows
<gmBasic> <Storage Action="Open" Identifier="fmstock1.vbi" /> <Select GlobalSettings="GmslCode.vbi" /> <LoadEnvironment /> <Output Status="New" Filename="Demo011.out" stripTrail="on" /> <RunCommand Id="vbCode.DemoWriteTable" /> <Storage Action="Close" /> </gmBasic>By convention all of the sample codes are compiled into a global settings file GmslCode.vbi. The class within that file which contains VB code is called vbCode. The fmstock1.vbi file is as it was produced within the FMSTOCK sample code. Nothing special was done to make it usable here. The Open action opens that file with Read Only permission. An abstract of the output follows.
Audit of Variables in fmstock1.vbi storage area: Lev | Address | Full Symbol Identifier --- | ------- | ---------------------- 4 | 227293 | FMStocks_DB.Helpers.RegisterEventSource.lpUNCServerName 4 | 227382 | FMStocks_DB.Helpers.RegisterEventSource.lpSourceName 4 | 232756 | FMStocks_DB.Helpers.DeregisterEventSource.hEventLog ... 3 | 253093 | FMStocks_DB.logDebugMSG.strSource 3 | 253123 | FMStocks_DB.logDebugMSG.strMSG 2 | 264958 | FMStocks_DB.COMSVCSLib_AppServerThe actual cells written by the Write_TableCell method are the individual entries in each row of the table.
Write_TableEnd Method
Section titled “Write_TableEnd Method”gmSL: void Write_TableEnd()
gmVB: Sub Write_TableEnd()
gmNI: void Write_TableEnd(void);
This method ends the authoring of a table of values. If the Output Syntax is Html then the Html closing tags are written; else this method does nothing.
Using the DemoWriteTable() subroutine with this script
<gmBasic> <Storage Action="Open" Identifier="fmstock1.vbi" /> <Select GlobalSettings="GmslCode.vbi" /> <LoadEnvironment /> <Output Status="New" Filename="Demo012.html" Syntax="html" /> <RunCommand Id="vbCode.DemoWriteTable" /> <Output Status="Close" /> <Storage Action="Close" /> </gmBasic>generates an output table with records like the following
<html> ... <center><p><h4>Audit of Variables in fmstock1.vbi storage area</h4></p></center> <center><table cellpadding="2" cellspacing="0" bordercolor="#5B5F8B" border="1"> <tr> <th rowspan="1" colspan="1" class="spanner" nowrap="nowrap">Lev</th> <th rowspan="1" colspan="1" class="spanner" nowrap="nowrap">Address</th> <th rowspan="1" colspan="1" class="spanner" nowrap="nowrap">Full Symbol Identifier</th> </tr> <tr> <td align="right" class="cell-odd" nowrap="nowrap">4</td> <td align="right" class="cell-odd" nowrap="nowrap">227293</td> <td align="left" class="cell-odd" nowrap="nowrap">FMStocks_DB.Helpers.RegisterEventSource.lpUNCServerName</td> </tr> ... <tr> <td align="right" class="cell-odd" nowrap="nowrap">2</td> <td align="right" class="cell-odd" nowrap="nowrap">264958</td> <td align="left" class="cell-odd" nowrap="nowrap">FMStocks_DB.COMSVCSLib_AppServer</td> </tr> </table></center> </body> </html>In this output the lines at the top before the title and those below the end of the table are produced by the gmPL Output statement. It is the closing table and center entries that are made by the Write_TableEnd() method. When writing code like DemoWriteTable() it is important to remember that its actual output form will be determined at gmPL RunCommand time so always include calls to methods like Write_TableEnd() in case the caller decides to use Html syntax.
Write_TableHeadings Method
Section titled “Write_TableHeadings Method”gmSL: void Write_TableHeadings()
gmVB: Sub Write_TableHeadings()
gmNI: void Write_TableHeadings(void);
This method writes a column heading to the currently active output stream using the form required by the Output Syntax attribute set for it. The column headings themselves and their desired widths are stored in the runtime data queue. Reviewing again the DemoWriteTable() subprogram
Sub DemoWriteTable() Dim iRoot As Integer Dim levels(19) As Integer
DataQueue_SetBottom() Write_Text "Audit of Variables in " & Store_GetDataName() & " storage area" Write_TableCell() Write_TableTitle() DataQueue_PushString("Lev") DataQueue_PushInteger(3) DataQueue_PushString("Address") DataQueue_PushInteger(8) DataQueue_PushString("Full Symbol Identifier") DataQueue_PushInteger(-100) Write_TableHeadings()
iRoot = Store_FindFirstChild(levels,0) Do while(iRoot <> 0) If Store_GetObjectType(iRoot) = ObjectType.VARIABLE Then Write_Integer(levels(0) - 1, 0) Write_TableCell() Write_Integer(iRoot,0) Write_TableCell() Write_Text(Symbol_FullName(iRoot,-1)) Write_TableCell() Write_TableRow() End If iRoot = Store_FindNextChild(levels) Loop Write_TableEnd() DataQueue_ClearBottom(1) End SubIt is the DataQueue service class calls that set up the call to Write_TableHeadings which expects the find a series of (String, Integer) pairs in the data queue. The number of pairs defines the number of columns in the table, each string entry defines the column heading, and the integer entry defines the field width and orientation to the used as follows:
| Value | Meaning |
|---|---|
| +n | Right justify the characters in a cell n characters wide. |
| -n | Left justify the characters in a cell n characters wide. |
These values are actually only used when the Output Syntax is Text; however, since this syntax choice does not take effect until gmPL runtime, the values should always be supplied with reasonable values.
Write_TableRow Method
Section titled “Write_TableRow Method”gmSL: void Write_TableRow()
gmVB: Sub Write_TableRow()
gmNI: void Write_TableRow(void);
This method writes a data row to the currently active output stream using the form required by the Output Syntax attribute set for it. The cell content making up the data row are stored as strings on the runtime data queue. Reviewing again the DemoWriteTable() subprogram
Sub DemoWriteTable() Dim iRoot As Integer Dim levels(19) As Integer
DataQueue_SetBottom() Write_Text "Audit of Variables in " & Store_GetDataName() & " storage area" Write_TableCell() Write_TableTitle() DataQueue_PushString("Lev") DataQueue_PushInteger(3) DataQueue_PushString("Address") DataQueue_PushInteger(8) DataQueue_PushString("Full Symbol Identifier") DataQueue_PushInteger(-100) Write_TableHeadings()
iRoot = Store_FindFirstChild(levels,0) Do while(iRoot <> 0) If Store_GetObjectType(iRoot) = ObjectType.VARIABLE Then Write_Integer(levels(0) - 1, 0) Write_TableCell() Write_Integer(iRoot,0) Write_TableCell() Write_Text(Symbol_FullName(iRoot,-1)) Write_TableCell() Write_TableRow() End If iRoot = Store_FindNextChild(levels) Loop Write_TableEnd() DataQueue_ClearBottom(1) End SubThe individual calls to Write_TableRow() assume that they have been preceded by as many calls to Write_DataCell() as there were columns defined in the table via the DataQueue calls and the final call to Write_TableHeadings(). The actual output produced by this method is determined at gmPL runtime depending upon the setting of the Output Syntax attribute. Previous topics have shown the output for Text (see Write_TableCell()) and Html (see Write_TableEnd()). The script here uses Tabbed syntax.
<gmBasic> <Storage Action="Open" Identifier="fmstock1.vbi" /> <Select GlobalSettings="GmslCode.vbi" /> <LoadEnvironment /> <Output Status="New" Filename="Demo013.out" Syntax="Tabbed" /> <RunCommand Id="vbCode.DemoWriteTable" /> <Output Status="Close" /> <Storage Action="Close" /> </gmBasic>The following is an abstract of the output produced, note that the white space is produced by the tabs.
Audit of Variables in fmstock1.vbi storage area Lev Address Full Symbol Identifier 4 227293 FMStocks_DB.Helpers.RegisterEventSource.lpUNCServerName 4 227382 FMStocks_DB.Helpers.RegisterEventSource.lpSourceName 4 232756 FMStocks_DB.Helpers.DeregisterEventSource.hEventLog ... 3 253093 FMStocks_DB.logDebugMSG.strSource 3 253123 FMStocks_DB.logDebugMSG.strMSG 2 264958 FMStocks_DB.COMSVCSLib_AppServerRegardless of the output syntax used, it is implemented at runtime when the various Write_Table methods are used. It is important to remember this when writing code that uses them.
Write_TableTitle Method
Section titled “Write_TableTitle Method”gmSL: void Write_TableTitle()
gmVB: Sub Write_TableTitle()
gmNI: void Write_TableTitle(void);
This method writes a title for a table of values along with any other control information that may be needed to begin the actual table display to the currently active output stream using the form required by the Output Syntax attribute set for it. The title itself is stored on the runtime data queue prior to the call to this method. The easiest way to do this is via the Write_TableCell() method though the DataQueue_PushString() could be used as well. Reviewing again the DemoWriteTable() subprogram,
Sub DemoWriteTable() Dim iRoot As Integer Dim levels(19) As Integer
DataQueue_SetBottom() Write_Text "Audit of Variables in " & Store_GetDataName() & " storage area" Write_TableCell() Write_TableTitle() ....the actual form of the output depends upon the Output Syntax attribute. For Text a colon is added to the back of the title string.
Audit of Variables in fmstock1.vbi storage area:For tabbed the title string is unadorned.
Audit of Variables in fmstock1.vbi storage areaFor Html it is displayed as an h4 centered heading.
<center><p><h4>Audit of Variables in fmstock1.vbi storage area</h4></p></center>Write_Text Method
Section titled “Write_Text Method”gmSL: void Write_Text(string strValue)
gmVB: Sub Write_Text(ByVal strValue As String)
gmNI: void Write_Text(char* strValue);
This method appends all characters from strValue to the current output record. No actual write occurs at this time. No formatting is applied to the string; however, the engine supporting gmSL performs concatenation and automatic conversions to string when processing addition within contexts that expect string arguments. For example the following code uses Write_Text
void DemoWriteText(int opcValue) { tOpcInfo opcInfo;
opcInfo = Opcode_GetInfo(opcValue); Write_Text("The Opcode " + opcInfo.ident + " has value " + opcInfo.value); Write_Record(); Write_Text(" length = " + opcInfo.length); Write_Record(); Write_Text(" ident = " + opcInfo.ident); Write_Record(); Write_Text(" value = " + opcInfo.value); Write_Record(); Write_Text(" type = " + Symbol_NamedEntryLabel("opcTypes",opcInfo.type)); Write_Record(); Write_Text(" role = " + Symbol_NamedEntryLabel("opcRoles",opcInfo.role)); Write_Record(); }to describe operation code properties. When called as follows
<Output Status="New" Filename="Demo014.out" /> <RunCommand Id="scmCode.DemoWriteText" prams="5"/> <RunCommand Id="scmCode.DemoWriteText" prams="13"/> <RunCommand Id="scmCode.DemoWriteText" prams="170"/>the following output is produced.
The Opcode LIC has value 5 length = 17 ident = LIC value = 5 type = ShortValue role = LoadInt The Opcode ADD has value 13 length = 17 ident = ADD value = 13 type = Arithmetic role = Binary The Opcode USC has value 170 length = 17 ident = USC value = 170 type = DoubleByte role = ClsrefWrite_TextStream Method
Section titled “Write_TextStream Method”gmSL: void Write_TextStream(Handle textStream, int host, int margin)
gmVB: Sub Write_TextStream(ByVal textStream As Handle, ByVal host As Integer, ByVal margin As Integer)
gmNI: void Write_TextStream(void* textStream,int host, int margin)
This method writes the content of a text stream buffer to the current output file. The textStream parameter is obtained from one of the Text service class methods Text_Open() or Text_Create(). It is the handle to the text stream buffer to be written. The host parameter is the root offset of the symbol to which the text stream belongs. It may simply be zero. If nonzero, it is used to log this message
SYSERR#6067: Text storage malformed for <identifier of symbol>in case the text stream is malformed. The margin parameter is the starting indentation margin to be used while writing the text stream. When gmBasic writes text streams it does not insert any leading white space to show marginal indentation; rather it simply records the margin level for each line. It is when the text stream is actually written that the margin level times the indentation width white space is actually applied to the front of the record. When doing this, the value of margin is added to the margin value recorded for each line.
The following method shows how the translation associated with a class file can be authored.
void DemoAuthorTextStream(int classRoot) { tInfoFile classFile; Handle textStream;
classFile = Store_GetVector(classRoot); textStream = Text_Open(Store_GetHandle(),classFile.tranBase); Write_TextStream(textStream,classRoot,0); Text_Close(textStream); }In the following script
<gmBasic> <Storage Action="Open" Identifier="fmstock1.vbi" /> <Select GlobalSettings="GmslCode.vbi" /> <LoadEnvironment /> <Output Status="New" Filename="Demo015.out" /> <RunCommand Id="vbCode.DemoAuthorTextStream" prams="(%= Symbol_FindIdentifier("[C:\gmSrc\fmstocks\vb6\FMStocks_DB\Version.cls]",0) %)" /> <Storage Action="Close" /> </gmBasic>the gmPL preprocessor executes the Symbol_FindIdentifier method which returns the root offset of the specified symbol and inserts it in string form in the prams attribute. The RunCommand then passes that root offset as an integer value to the DemoAuthorTextStream() method. That method then writes the translation associated with the class just as it was produced when the actual translation script was executed. Here is an abstract of that output
cat >C:\gmProj\FmStocks\Deploy\FmStock1_csh\Version.cs <<'!)(!' using System; using System.Drawing; ... namespace FMStocks_DB { public class Version { private const string m_modName = "FMStocks_DB.Version"; public string ConnectionString() { string ConnectionString = "";
DBHelper dbh = null; try { MigrationSupport.Utils.ClearErrorObject(); dbh = new FMStocks_DB.DBHelper(); ConnectionString = dbh.GetConnectionString(); dbh = null; return ConnectionString;
} catch(Exception exc) { MigrationSupport.Utils.SetErrorObject(exc); Helpers.RaiseError(m_modName,"ConnectionString()","",0,false); } return ConnectionString; } ... } !)(!