Home page Home page Home page Home page
Pixel Header R1 C1 Pixel
Pixel Header R2 C1 Pixel
Pixel Header R3 C1 Pixel
By Captain C | Wednesday, 27 May 2009 09:00 | 0 Comments
In the recent posting on OI initialization we touched upon the program loader process, or RTP27 as it's officially known. This is the stored procedure that is responsible for loading object code onto the OpenEngine program stack so it can be executed.

An integral part of this loading process is the SYSENV SYSPROCNAMES record, which is simply a list of all the stored procedures that OpenInsight considers to be system stored procedures. It is cached in memory during the engine boot process.

Under most circumstances you'll see RTP27 use the application inheritance chain to find the correct version of the object code to load - i.e. it parses @AppID appending an extracted application name to the specified program name until it finds the correct record in SYSOBJ or until it reaches the SYSPROG application.

For example, if the application inheritance chain looks like this:

Then RTP27 will search for the object code record for TESTPROC in SYSOBJ in the following order:

However, this is not the whole story: RTP27 first attempts to locate the program name in the cached SYSPROCNAMES list. If found then the SYSPROG version of the program is loaded - the application inheritance chain is never used. This is to prevent application specific programs with the same name as a system program from loading and possibly interfering with the system processes.

You may think this sort of thing doesn't happen, but on a recent site visit we moved an existing OI 4.1.3 system to version 9.0.0 (We did this the simple way - an APPBACKUP from 4.1.3 into a clean 9.0.0 system). One of the big issues we encountered during the upgrade process were naming conflicts: Being a well established system there were some stored procedures in the client application that had the same name as those found in the SYSPROG application. For example, the clients PlaceDialog() function conflicted with the SYSPROG PlaceDialog() function - the result? No dialogs were visible in the System Editor++ when run from the client app - ouch!

Of course I just said that SYSPROCNAMES protects system routines right? Unfortunately the OI 9.0.0 installation process installed a blank SYSPROCNAMES record which meant that nothing was protected. This has been corrected in the next release (OI 9.0.1 as of writing), but as a workaround for now simply copy the SYSPROCNAMES across from your OI 8.x system if you need to.

Compiler Protection and modifying SYSPROCNAMES

Just as it protects RTP27 at runtime the SYSPROCNAMES record also protects the system from accidental compilation and overwriting of system stored procedures: The compiler will not let you compile any stored procedure if it's name can be found in SYSPROCNAMES.

If you need to disable this feature for any reason you can modify the desired program name in SYSPROCNAMES (usually by inserting a ";" or "*" in front of it), saving the changes, and then rebooting OI (This is how the aforementioned client had programs in their own application with the same name as system programs). This will have the added effect of forcing RTP27 to load your modified version rather than the SYSPROG version at runtime. Bear in mind however that OI upgrades from Revelation will overwrite SYSPROCNAMES so make sure you remember any changes you make to it!

Labels: , , , ,

By Captain C | Friday, 22 May 2009 11:05 | 0 Comments
With the addition of this blog to our website we soon found the need to publish Basic+ source code along with technical articles, and, being bored of plain <pre> tags, we decided write a tool that would allow us to easily generate HTML for syntax-coloured Basic+ code. We also wanted something we could use on the Revelation Forum as well as on the blog.

Well, after digging up some old prototype syntax highlighting code and wrapping it in a simple form, the "Sprezzatura Basic+ Source Code HTML Publisher" was born. The bad news is the awful title - the good news is that we're giving it away so you can use it yourself if you wish. The rest of this post simply describes how to use it - if you want a copy then simply drop us a line and we'll send you one.

The installation is a standard setup.exe compiled with the RDK/NSIS on OI9, so it will ask you the usual questions such as the location of the target OI system and the login credentials etc. The software will be copied into the SYSPROG application - once you've got it installed into your copy of OI execute the ZZ_IDE_BP_PUBLISHER form to launch the Publisher.

Using the Publisher

The Publisher is composed of four tabs - publishing your Basic+ code to HTML is simply a matter of following this sequence:

  1. Enter the Basic+ source code you wish to publish in the Source Code tab.
  2. Click on the Styling Options tab and adjust any required CSS options.
  3. Click on the HTML Code tab to generate the actual HTML you will need to embed in your forum post - you can copy and paste this code as you wish.
  4. Click on the HTML Preview Tab to see how the generated HTML will look in a browser.

Source Code Tab

Use this tab to enter the source code you wish to publish. You can enter it directly, paste it from the clipboard, or use the "Open" button to load the contents of a Stored Procedure or Insert from the repository.

Styling Options Tab

This tab lets you define how you want your source formatted when it's published to HTML.

StyleSheet Options: This settings allows you to specify how you wish to use CSS with your published source code. You can use one of the following options:
  1. Generate in-line style tags: All CSS styling will be embedded within each HTML tag via a "style" attribute.
  2. Generate an embedded style sheet: The Publisher creates and embeds a stylesheet within a "style" tag containing the CSS attributes to apply to the source code. All the HTML in the source code tags use a "class" attribute to refer to the CSS in the embedded stylesheet. A list of class names used by the publisher is given at the end of this post.
  3. Generate class names only: The Publisher simply adds CSS class names to the source code HTML tags but doesn't generate an embedded stylesheet. The actual CSS is expected to be referenced and contained in an external stylesheet page. When using this option it is not possible to specify any individual CSS formatting for the source code, and the relevant sections of the tab page are disabled.
Use Link URL: This option is only enabled when Stylesheet Options is set to "Generate class names only". If a URL is entered here a <link> tag is added to the generated HTML that references the URL.

Add [ ] brackets: This option adds a "[" character to the beginning of the generated HTML and an "]" character afterwards. These two characters are necessary when adding your published source code to the revelation.com forum - when making a post anything between these two characters is considered to be raw HTML to be embedded in the posting. Without these it is considered to be text.

Overall CSS formatting: This group of options is applied to the <div> tag that surrounds the published source code. There are prompts for the most common CSS requirements, and a miscellaneous tag to allow ad-hoc CSS styles to be applied as required.

Syntax-specific CSS formatting: This group of options controls the formatting applied to each type of token found in the Basic+ code. Again, there are prompts for the most common CSS requirements, and a miscellaneous tag to allow ad-hoc CSS styles to be applied as required.

Replace tabs: When the Basic+ code is formatted to HTML all tab characters are translated to non-breaking space characters. This option allows you to specify how many spaces are used per tab character.

Include Line Numbers: Check this option to include line numbers in the published source code.

Save Styling Options: Click this button to save the styling options to a record in the SYSENV table. The Publisher automatically loads saved styling options when the form is created. Styling options are saved with a key structure like so:


If no user specific config record is found the Publisher attempts to load an application specific one:


The application inheritance chain is respected.

HTML Code Tab

When you click on this tab the Publisher processes the Basic+ source code and applies the CSS styling - the result is displayed in this tab.

Copy To Clipboard: This button copies the entire text to the clipboard so you can paste it into your post.

Save As: This button creates a very basic HTML document that contains the generated HTML and allows you to save it to disk.

HTML Preview Tab

This tab uses the ActiveX WebBrowser control to display a preview of the generated HTML.

Keywords and Styling

When the publisher processes your Basic+ code it breaks it up into tokens and applies the relevant CSS to each token found. If you elect to use a stylesheet with your source code rather than inline-styling a CSS class name is applied to each token. The CSS class name of each token and the type of token it applies to is listed below:

Syntax Token TypeCSS Class Name
Compiler DirectivebpDirective
System VariablebpSysVar
Debug StatementbpDebug
Dictionary FieldbpDict
Subroutine LabelbpLabel
Line NumberbpLineNo

The list of keywords using for publishing is contained in a record in the SYSENV table called CFG_ZZ_TCL_EDIT_BP_KEYWORDS. This record has four fields, each of which contain a multivalued list of words:
  1. Basic+ keywords
  2. System variable (@var) names
  3. Compiler directives (#define etc...)
  4. Debugger directives (i.e. the debug statement)

Labels: , , ,

By Captain C | 11:00 | 0 Comments
It is a common requirement in many applications to initialise data before the application itself begins to execute proper. Many OpenInsight applications are desktop applications, and as such have a “main” or “start-up” window. It is generally sufficient in these cases to initialise the data during the CREATE event of the start-up window, usually before anything is displayed to the user – this approach also has the advantage of knowing that both the Presentation Server (the part of OpenInsight responsible for displaying forms and controls) and OpenEngine are both fully booted and initialised themselves, which means all their features are available for use.

Of course, it is possible to use OpenEngine without using the Presentation Server, via such tools as OECGI, RevODBC, Xrev.dll and so on. In these cases another method is needed to initialise the data as there is no “main window” to speak of that we can hook into. Fortunately such a method does exist because OpenEngine provides a “Startup Procedure” facility (or “StartProc” as we’ll call it here) that allows you to nominate a stored procedure to be executed during the engine boot-up phase. Using this facility is actually quite simple, but there are some points to be aware of to use it successfully which is what we’ll be covering here.

Creating a StartProc

The first step is of course to create a stored procedure to initialise your system. When creating this procedure it must support one of the following two interfaces:

compile subroutine myStartProc( initflag, atstation ) 
   * // Do your stuff here 
compile subroutine myStartProc( initflag ) 
   * // Do your stuff here 

As you can see the Engine boot process will pass you one or two arguments depending on which interface you chose:

initFlag – If this is TRUE$ then it means that StartProc is being called for the first time during the engine bootup process. It can be called at subsequent points after the engine bootup process, usually as a side effect of running another procedure like swapping out the database. The points at which your StartProc can be called are:
  • During the actual engine bootup process. At this point initFlag will be TRUE$.

  • During a Swap_Database() call when changing the database. At this point initFlag will be FALSE$ or null (i.e. an empty string).

  • It is also possible for an application to call the Initialize() stored procedure “manually” to re-initialize itself. This is rare and is something you as a developer may want to do, but as Initialize() is the routine responsible for calling the your StartProc then expect it to be executed here as well.

atStation – When a StartProc is called during the engine boot phase (i.e. when initFlag is TRUE$) it is possible to use it to modify the contents of the @Station system variable. The system passes the StartProc what it considers @Station should be (usually this is the actual workstation name as set by Windows), but this may be overridden by altering this argument before the StartProc returns.

Installing a StartProc

Once you have created your procedure the next job is to tell your application about it. This is quite simple and is achieved by entering the name of the procedure in field 32 of your application environment record (documentation to this effect can be found in the ENVIRON_CONSTANTS insert record).

Care must be taken however, when dealing with an application outside of SYSPROG. When the StartProc is called there is a very good chance that it is called before the engine is fully booted, and one factor that impacts us here is that the @AppID variable will not be set. This in turn has consequences for the program loader (RTP27) which relies on @AppID to resolve program names using the application inheritance chain when searching for object code.

To overcome this the application suffix MUST be included when adding the StartProc name to the application environment name (The application suffix is the same as the suffix added to the program name when it is compiled and stored in SYSOBJ, minus the leading “$” character). The name should also be entered in uppercase.

  • You wish to specify a StartProc called MYSTARTUPPROC for the SYSPROG application and MYSTARTUPPROC was compiled in SYSPROG:

    Open up the ENV_SYSPROG record in the SYSENV table and enter MYSTARTUPPROC in field 32.

  • You wish to specify a StartProc called MYSTARTUPPROC for the MYAPP application and MYSTARTUPROC was compiled in the MYAPP application:

    Open up the ENV_MYAPP record in the SYSENV table and enter MYSTARTUPPROC*MYAPP in field 32.

  • You wish to specify a StartProc called MYSTARTUPPROC for the MYAPP2 application and MYSTARTUPROC was compiled in the MYAPP application:

    Open up the ENV_MYAPP2 record in the SYSENV table and enter MYSTARTUPPROC*MYAPP in field 32.

Calling other procedures from a StartProc

Just as care must be taken when specifying the StartProc for an application, the same can be said of calling programs from within the actual StartProc due to the limitations encountered by RTP27 as described above. If the StartProc only calls system procedures or procedures belonging to the SYSPROG application then there will be no changes needed to the StartProc code when calling them.

If you wish to call procedures compiled in a non-SYSPROG application however, the application suffix must be added to the procedure name to execute it, in the same manner as described above when adding a StartProc name to the environment record. Of course a “*” character is not valid in a procedure name and the compiler will reject it, so to get around this we can use the “call” and “function” statements instead. The modified stored procedure name can simply be loaded into a variable and then invoked with one of the afore-mentioned statements.


compile subroutine myStartProc( initflag, atstation )

   * // Call a subroutine MYSUB compiled in the MYAPP account
   procid = "MYSUB*MYAPP" ; * // Ensure UPPER CASE!
   arg1   = "Hello"
   arg2   = "World"
   call @procid( arg1, arg2 )

   * // Call a function MYFUNC compiled in the MYAPP account
   procid = "MYFUNC*MYAPP" ; * // Ensure UPPER CASE!
   arg1   = "Hello"
   arg2   = "World"
   retval = function( @procid( arg1, arg2 ) )


Labels: , ,

By Sprezz | Wednesday, 20 May 2009 08:00 | 0 Comments

Welcome to the inaugural posting of the new Sprezzatura blog. As we hinted in the last issue of SENL, production schedules became too protracted and we've decided to redirect our efforts into a more immediate media - namely blogging.

That isn't to say that we won't be continuing to add in depth articles from time to time - they may even make their initial appearance on this blog - it's just that when something happens that we consider to be worth commenting on, it's nice not to have to assemble an entire SENL to release it!

Hopefully you'll find the blog to be of interest and at the very least it'll help to keep you aware of where in the world Sprezz people are in case you want to meet up for a drink ;)

In the next few weeks we expect to see Andrew doing some work in the New York area before moving on to Chicago to do some work there. Following this he hopes to be somewhere in Texas! As the transatlantic flights will be covered this is an ideal opportunity to get some Sprezz consultancy without the added expense of transatlantic flights! So if you'd like him to drop by your office on his road trip drop us a line. Though having said that you can currently fly from London to New York for less than it costs to fly from New York to Houston! There's a price war out there on transatlantic flights and when you remove taxes and airport charges from the equation passengers are only being charged around $25 for the return flight.

In fact with prices being so cheap why not come over to Merry England for some sight seeing and one on one training - the dollar hasn't been this strong for quite some time so you'll be surprised how much buying power you'll have.

Labels: , ,

Pixel Footer R1 C1 Pixel