Reviews / articles about OS/2 |
Operating systems: ArcaOS, eComStation, IBM OS/2 Warp |
|
|
DATE: 2010-09-28 11:11:45 AUTHOR: Joseph Shrago
Preface This report covers certain aspects of working with configuration files (ini-files, profiles, registry, etc). Against the background of common ways of organizing such files, we’ll review the language for informational (non-executable) objects description (as well as its OS/2 API), that has been developed for specific task (drilling training simulator for OS/2), but is pretty universal. The most primitive description method "parameter"="value" is commonly used and well known. CONFIG.SYS file is a good example: SET
EPMPATH=C:\OS2\APPS;C:\opendoc\BIN;
PROTECTONLY=NO SHELL=C:\OS2\MDOS\COMMAND.COM C:\OS2\MDOS FCBS=16,8 RMSIZE=640 DEVICE=C:\OS2\MDOS\VEMM.SYS DOS=LOW,NOUMB DEVICE=C:\OS2\MDOS\VXMS.SYS /UMB DEVICE=C:\OS2\MDOS\VDPMI.SYS DEVICE=C:\OS2\MDOS\VDPX.SYS DEVICE=C:\OS2\MDOS\VWIN.SYS DEVICE=C:\OS2\MDOS\VW32S.SYS
This method has a drawback: there's no way to syntactically separate different objects' descriptions within one file. Still, it's easy to implement and in many cases suitable. But not always possible. Windows ini-files (Windows 3.11) introduced a slight improvement: sections. Named sections allow using structured descriptions and query description elements using two parameters "section name"-"parameter name", which is more convenient. Here's an example from SYSTEM.INI file for WIN-OS2 session:
[keyboard]
subtype= type=4 keyboard.dll=kbdru.dll oemansi.bin=xlat866.bin typeofswitch=2 secondkeyb.dll=kbdusx.dll [boot.description] keyboard.typ=Enhanced 101 or 102 key US and Non US keyboards mouse.drv=Microsoft, or IBM PS/2 network.drv=No Network Installed language.dll=Russian system.drv=MS-DOS System codepage=866 woafont.fon=Russian (866)
The disadvantages here are: syntactical indifference when dealing with variable number of entries within one section, and no nesting for section (which may be useful, since not all informational objects are linear). Of course, this may be implemented, but particular implementation will be a developer's quick wit, rather than the result of syntactical structure. The next step in the evolution of description scripts is registry (Windows 9x or higher), and OS/2 ini-files. Both allow tree structure (nesting) and storing objects of any type by using binary objects (defined by those who use them). To criticize existing implementations of such resource (it’s WINPRF.DLL in OS/2), we have to take into account requirements to the configuration files syntax in general. As mentioned before, the views expressed here are the result of working on scenario maintenance subsystem for drilling training simulator. A scenario for such training simulator contains all parameters, that define the initial state of the drill and borehole. It describes numerous independent parameters — hardware descriptors, rock and geological section descriptors as well as possible anomalies, scattered all over the borehole (to entertain the trainee) etc. The scenarios are to be created by the end users of the product. Therefore the descriptions and tools to create them have to be intuitive enough for non-programmer to use. Since the same hardware descriptions may be used in many scenarios, they has to be defined separately and linked from within the scenario. There are means provided for printing scenarios in good-looking readable form, to use them as operating instructions. These requirements resulted the creation of informationally associated software tools:
Change in the description of any object required correcting the software implementation of interconnected objects, which is not very convenient. This problem became obvious when developers have realized that simplifying a number of descriptions was a mistake and it would be nice to complement them. Problems described above serve as a good criticism when it comes to using Profile API for maintaining complex configurations. So we’ve defined the following requirements to configuring concept:
These requirements are fulfilled in our configuration files subsystem. It offers syntax, base objects, WPS-object for visualization and printing and an API for their software-based writing and reading. Informal Description: Any configuration file is rendered as a number of fields of certain types. Types are either simple or compound. Thus, configuration file itself is an object of a certain compound type (class). A syntax we offer for describing such classes operates with keywords, literals and comments. Literals are identical to ones in C++ : \xx, \\, \n, \t and special % literals. Comments are defined by symbols //, /*, */ and used same way as in C++.
The system deals with the following objects:
Objects' Description: IntField
= .
string
title = "" // name, displayed in the edit dialog
or when printing
int value = 0 // field value int min = 0 // minimum available integer value int max = 0 // maximum available integer value int delta = 0 // auto-change pitch in the edit dialog .
DoubleField
= .
string
title = "" // name, displayed in the edit dialog or when printing
double value = 0 // field value double min = 0 // minimum available double value double max = 0 // maximum available double value double coef = 0 // conversion factor (useful when editing certain // units of measuring, and using other) double delta = 0 // auto-change pitch in the edit dialog int decimals = 0 // number of symbols after decimal point, // displayed when editing and printing .
StringField
= .
int
max = 0 // maximum number of symbols in line
string title = "" // name, displayed in the edit dialog or when printing string value = "" // if the line is limited by \0 line delimiter // with single quotes '...' don't limited by \0 .
TextField
= . // same as StringField, but is textarea (MLE)
int
max = 0
string title = "" string value = "" .
RadioToggleField
= . // implementation of dialog element
string
title = ""
int value = 0 // contains the number of selected line group elements = . . // array of "string" type strings .
CheckBoxField
= . // implementation of dialog element
string
title = ""
int value = 0 // contains 1 if the element is selected .
ComboToggleField
= . // same as above for ComboBox object
string
title = ""
int value = 0 group elements = . . . ReferenceField class allows using multiple settings in one if, for example, software product consists of multiple tasks, and each has own configuration with individual and shared part. And vice versa, if the settings of one object are used by many others. ReferenceField
= . // object-reference to other object. drag&drop in the // dialog
string
title = ""
string class = "" // name of the class of the objects of which may fill this field // (multiple are possible - class0|class1|...) string value = "" // full path to file that contains object int value2 = 0 // WPS-objectid . ObjectListField class allows creating lists of reference objects if, for example, list of persons in the group or list of different network connections has specific settings. ObjectListField
list = . // example of object list
// ReferenceField of a certain class transient string title = "" transient group factory = . ReferenceField
rs = .
transient string title = "" transient group menu = . "Open"
"Close" . transient
string class = ""
.
string value = '' int value2 = 0 . "Add"
group
elements = .
"Delete" . .
.
When displaying dialog ObjectListField in the list there are values of element "string title" objects' descriptions, or value of element "name|value", is there's StringField name element in the description of reference object. Access to a password, set in PasswordField, is provided by exported function: rc=getPasswordFieldValue(*XObject,password,sizeof(password)); To describe rock images, we've implemented filling mask class: ColorMaskField
= .
string
title = ""
int fcolor = 0 // foreground color int bcolor = 0 // background color int width = 16 // width, points int height = 16 // height, points string value = '' // filling mask width*height .
Some data is predefined:
Using these types it is easy to create own description classes. For example, that's how class definition of the bottom-hole engine description looks like (on russian): DEngine
drill=.
string title="........ ........." DoubleField diam_zd =. title="....... ............." coef=0.001 decimals=1 delta=0.1 min=30 max=400. DoubleField leng_zd =. title="..... ............." coef=1 decimals=2 delta=0.01 max=50. DoubleField q_zd =. title="...... ............." coef=1000 decimals=1 delta=0.1 min=30 max=400. DoubleField dens_zd =. title="......... ........" coef=1000 decimals=2 delta=0.01 min=0.8 max=2.5. DoubleField loss_px_zd =. title="...... ........ .. ........ ...." coef=98100 min=1 max=200. DoubleField freq_nx_zd =. title="....... ........ .. ........ ...." coef=0.01666 min=10 max=999. DoubleField loss_pt_zd =. title="...... ........ ... .........." coef=98100 min=1 max=200. DoubleField moment_t_zd=. title="......... ......" coef=10 min=1 max=1500. ComboToggleField drop =. string
title ="... ........."
group
elements = .
string = "........ . .......... ......" string = "........ . ........ ......" string = "........ ........." . .
.
And that's the description for specific bottom-hole engine (/* comment */ in the first line is needed to interpret text as XObject): /*
XObject */
DEngine = . diam_zd
= .value = 30.0000.
leng_zd = .value = 0.0000. q_zd = .value = 30.0000. dens_zd = .value = 0.8000. loss_px_zd = .value = 1.0000. freq_nx_zd = .value = 10.0000. loss_pt_zd = .value = 1.0000. moment_t_zd = .value = 1.0000. drop = .value = 0. . This syntax demonstrates the possibility to make changes to each object and additional fields: min, max etc. Visualization Let's take a look at the visualization and printing we've mentioned before. We've created WPS-object that renders specifically organized parts of class descriptions as its property pages. To do so, we add special descriptors to class description: "group" with names "pages" (for dialog) and "sections" for printing. Here's a part of the class that describes the dialog: group
pages = .
namedgroup
= . // dialog page description
title
= "%MajorTab" // symbol % means MajorTab
namedgroup
= . // second page of the dialog
status = "Subtitle" elements = . string
= "name 1" // element of the class
.
string = "name 2" ... string = "name N" . title
= "MinorTab pages"
... //
other pages of the dialog
status = "Subtitle" elements = . string
= "name 1"
.
string = "name 2" ... string = "name N" . .
This is the part of description of bottom-hole engine (DEngine) class that refers to dialog and it's result:
Note the second tab — "Type". It is always created and allows choosing way (text/binary) of saving. The last one allows easily edit any field of object using text editor. And vice versa, any object may be created in the text editor and then saved as binary. When saving in binary, object saves only differences from base description. The other elements of description are inherited, that's why the size of binary XObject file is much less than the text one.
To describe object printing we use similarly organized group sections, and that's what we get when printing:
To print the object use the menu, or simply drag its icon onto printer's icon (folder). Here's the example output after printing one object. The same object, as ReferenceField inside the scenario, looks as follows: Usage: To use this configuring system, in the root or in the AMT_PATH environment variable directory one has to create file config.ini of the following content (we use our training simulator configuration as an example here):
/*
AMT */
group Config = . string
customer = "Customer Corp" // for (C)Copyright printout
int loglevel = 0 // -1 full debug output to \xobject.log // 0 no error messages output // 1 output warnings and error messages group classes = . string =
"common.ini" // description of the common classes
string = "DSTclass.ini" // drilling training simulator classes description string = "KRSclass.ini" // borehole extensive repairs training simulator classes description . .
This file is used by WPS-object AMTWPSXObject that implements dialogs and configuration objects printing. This object is associated with AMT extension. Copy all XObject support dynamic libraries into LIBPATH available in environment variable. And using this Rexx script, perform the registration: /*********************************************************************/
/* XObject registration utility */ /*********************************************************************/ Call RxFuncAdd 'SysLoadFuncs', 'REXXUTIL', 'SysLoadFuncs' Call SysLoadFuncs Say 'AMT XObjects to be registered' rc=SysRegisterObjectClass('AMTWpsObject', 'amtwpso') if rc then say 'AMTWpsObject registered' else say 'AMTWpsObject cannot be registered' Programming using API XObject When programming, it is required to read descriptions of used classes - for example, all config.ini and all files mentioned there, or only required for specific task. The following text gives and example of reading all classes libraries, described in config.ini:
#include
"common.h"
XObject *o_config; // for the script // function initializes XObject predefined classes subsystem // and returns number of classes in the library int InitXClasses(void) . char buf[256]="", *str; char *amtPath = getenv(AMT_PATH); int num=0; XOBJECT_INITIALIZE // loading classes libraries buf[0] = 0; if (amtPath) strcat(buf, amtPath); strcat(buf, "\\"); strcat(buf, AMT_CONFIG); o_config = XObject::loadObject(buf); if (!o_config) return 0; o_config = o_config->getGroupElement("classes"); for (int i = 0; igetGroupSize(); i++ ) .
return
num;
str = o_config->getGroupElement(i)->getStringValue(); if (str) .
.
buf[0] = 0; if (amtPath) strcat(buf, amtPath); strcat(buf, "\\"); strcat(buf, str); num += XObject::loadClasses(buf); . .
The following lines represent the idea of getting certain class elements of training simulator scenario: .
XObject methods also allow saving information, obtained by software. This simplifies visualization, printing and maintenance. The code below is the description of XObject class public objects: class
_Export XObject .
 
Kommentare:
|
|
|||||||||||||||||||||||||||||||
(C) OS2.GURU 2001-2021