The ModulaTor logo 7KB

The ModulaTor

Oberon-2 and Modula-2 Technical Publication

Ubaye's First Independent Modula-2 & Oberon-2 Journal! Nr. 11, Dec-1995


Working with AlphaOberon

by Günter Dotzel, ModulaWare

last revised 10-Oct-1997

Developing and using AlphaOberon applications is pretty much the same as with other Oberon System implementations. Because the Oberon System sits on-top of an existing operating system, it hides all operating system specific details. The advantage of this abstraction is, that one gains flexibility through dynamic module loading and portability even for hyper-text. There are however some rules to obey to avoid frustration.

1. File attributes: When a file is created under AlphaOberon, the OpenVMS file attributes are set according to the file name extension. Having the appropriate file attribute set is only necessary, if you want to process files which are generated under AlphaOberon with OpenVMS tools (edit, print, search, ...)

AlphaOberon file attributes and associated file name extensions (not case sensitive):

Stream_CR: .mod, .text, .tool, .def, .log, .trap, .codetext, .txt., .lis
Stream_LF: .ps, .ps_lis
others are Stream_UDF (undefined)

The Oberon text files with the extensions .Mod, .Text, .Tool, etc. are usually not plain ascii text files. They contain a non-ascii header which provides information about text formatting, font, color, file time-stamp, version, folds and other hyper-text elements. These texts files shall not be modified with any editor other than the Oberon System editors (Edit, XE, etc.). Otherwise it is not guaranted that the non-ascii file header is still consistent with the file content. This may result in a corrupted (i.e. in most cases a truncated) file when further processed within the Oberon System.

Apart from the non-ascii file header, XE.Store and Edit.Store separates text file records with CR.

2. The Oberon texts concept: The Oberon text files are extensible hyper-texts. These text files are platform independent and portable to other Oberon implementations. They may involve loading of font files and modules (code files). When a text file uses for example so-called fold elements, it is no longer possible to process the file directly with conventional tools such as a text editor provided by the operating system. This is not a limitation of OpenVMS or AlphaOberon. The Oberon System provides tools such as

- Folds.Expand,
- EditTools.InsertCR (to break a paragraph into lines), and
- EditTools.StoreAscii (writes a plain-ascii text file without Oberon text header; terminates each record with LF (independent from associated file attribute).
- EditTools.StorePlain (same as EditTools.StoreAscii, but terminates each record with CR).

to prepare a text file for processing with conventional tools. Normally, the formatting and font information as well as embedded graphics, illustrations and hyper-text links are lost with EditTools.StoreAscii and EditTools.StorePlain.

It is possible to use any conventional editor to develop Oberon-2 programs. DEC's TPU/EVE editor and most other text editors under OpenVMS create variable record length files by default. To convert accentuated characters from the DEC extended character set to the Oberon character set, use VMSTools.FromDec and VMSTools.ToDec. All Oberon Systems use the same character set independent from the host operating system.

Oberon-2 source files are are compiled with the OpenVMS AXP Oberon-2 compiler (A2O). A2O can be invoked from the command line or under AlphaOberon with the command Compiler.Compile or Folds.Compile. See also 6. below.

AlphaOberon can read OpenVMS' variable record length files by creating and copying their contents to an intermediate stream file. This is necessary, because otherwise the length of a file and positioning in files would not work as expected by the Oberon System. Files created with procedure Files.New get the file attributes as described in 1. above. There is however the possibility to use the low-level and operating system dependend module Unix or RMSAccess to create other file types available under OpenVMS. Here is the result of Browser.ShowDef applied to RMSAccess:


DEFINITION RMSAccess;

  IMPORT SYSTEM, RMSTypes;

  TYPE
    ADDRESS = SYSTEM.SIGNED_64;
    BYTE = SYSTEM.BYTE;
    FACset = SYSTEM.BYTE;
    FILE = RMSTypes.FAB;
    FOPset = SET;
    NAME = RMSTypes.NAM;
    ORGtype = SHORTINT;
    QUADWORD = SYSTEM.QUADWORD;
    RATset = SYSTEM.BYTE;
    RFAtype = RMSTypes.RFAtype;
    RFMtype = SHORTINT;
    ROPset = SET;
    SHORTWORD = SYSTEM.SHORTWORD;
    SHRset = SYSTEM.BYTE;
    STREAM = RMSTypes.RAB;
    WORD = SYSTEM.LONGWORD;

  PROCEDURE Close (VAR f: RMSTypes.FAB;
    VAR status: LONGINT);
   
  PROCEDURE Connect (VAR f: RMSTypes.FAB;
    VAR s: RMSTypes.RAB;
    rop: SET;
    VAR status: LONGINT);
   
  PROCEDURE Create (VAR f: RMSTypes.FAB;
    VAR n: RMSTypes.NAM;
    fna: ARRAY OF CHAR;
    fac: SYSTEM.BYTE;
    fop: SET;
    shr, rat: SYSTEM.BYTE;
    rfm, org: SHORTINT;
    mrs, fsz, xab: SYSTEM.SIGNED_64;
    VAR rna: ARRAY OF CHAR;
    VAR status: LONGINT);
   
  PROCEDURE Delete (VAR s: RMSTypes.RAB;
    VAR status: LONGINT);
   
  PROCEDURE Disconnect (VAR s: RMSTypes.RAB;
    VAR status: LONGINT);
   
  PROCEDURE Erase (VAR f: RMSTypes.FAB;
    fna: ARRAY OF CHAR;
    VAR status: LONGINT);
   
  PROCEDURE Extend (VAR f: RMSTypes.FAB;
    incr: LONGINT;
    VAR status: LONGINT);
   
  PROCEDURE Find (VAR s: RMSTypes.RAB;
    VAR status: LONGINT);
   
  PROCEDURE Flush (VAR s: RMSTypes.RAB;
    VAR status: LONGINT);
   
  PROCEDURE Free (VAR s: RMSTypes.RAB;
    VAR status: LONGINT);
   
  PROCEDURE Get (VAR s: RMSTypes.RAB;
    record: SYSTEM.SIGNED_64;
    VAR size: SYSTEM.SIGNED_64;
    VAR status: LONGINT);
   
  PROCEDURE GetPos (VAR s: RMSTypes.RAB;
    VAR rfa: RMSTypes.RFAtype;
    VAR status: LONGINT);
   
  PROCEDURE Handler (VAR sigargs, mechargs: SignalArray): SYSTEM.SIGNED_64;
   
  PROCEDURE InitFab (VAR f: RMSTypes.FAB);
   
  PROCEDURE InitNam (VAR n: RMSTypes.NAM);
   
  PROCEDURE InitRab (VAR r: RMSTypes.RAB);
   
  PROCEDURE InitXabAll (VAR x: RMSTypes.XABALL);
   
  PROCEDURE InitXabDat (VAR x: RMSTypes.XABDAT);
   
  PROCEDURE InitXabFhc (VAR x: RMSTypes.XABFHC);
   
  PROCEDURE InitXabKey (VAR x: RMSTypes.XABKEY);
   
  PROCEDURE InitXabPro (VAR x: RMSTypes.XABPRO);
   
  PROCEDURE InitXabRdt (VAR x: RMSTypes.XABRDT);
   
  PROCEDURE InitXabSum (VAR x: RMSTypes.XABSUM);
   
  PROCEDURE Nxtvol (VAR s: RMSTypes.RAB;
    VAR status: LONGINT);
   
  PROCEDURE Open (VAR f: RMSTypes.FAB;
    VAR n: RMSTypes.NAM;
    fna: ARRAY OF CHAR;
    fac: SYSTEM.BYTE;
    fop: SET;
    shr: SYSTEM.BYTE;
    xab: SYSTEM.SIGNED_64;
    VAR rna: ARRAY OF CHAR;
    VAR status: LONGINT);
   
  PROCEDURE Parse (VAR f: RMSTypes.FAB;
    VAR n: RMSTypes.NAM;
    fna: ARRAY OF CHAR;
    dna: ARRAY OF CHAR;
    VAR rna: ARRAY OF CHAR;
    VAR status: LONGINT);
   
  PROCEDURE Put (VAR s: RMSTypes.RAB;
    record, size: SYSTEM.SIGNED_64;
    VAR status: LONGINT);
   
  PROCEDURE Read (VAR s: RMSTypes.RAB;
    blocknr, buffer: SYSTEM.SIGNED_64;
    VAR size: SYSTEM.SIGNED_64;
    VAR status: LONGINT);
   
  PROCEDURE Release (VAR s: RMSTypes.RAB;
    rfa: RMSTypes.RFAtype;
    VAR status: LONGINT);
   
  PROCEDURE Rename (VAR oldf, newf: RMSTypes.FAB;
    oldnam, newnam: ARRAY OF CHAR;
    VAR status: LONGINT);
   
  PROCEDURE Rewind (VAR s: RMSTypes.RAB;
    VAR status: LONGINT);
   
  PROCEDURE SetFileBlock (VAR f: RMSTypes.FAB;
    VAR n: RMSTypes.NAM;
    VAR fna: ARRAY OF CHAR;
    VAR rna: ARRAY OF CHAR);
   
  PROCEDURE SetPos (VAR s: RMSTypes.RAB;
    rfa: RMSTypes.RFAtype;
    VAR status: LONGINT);
   
  PROCEDURE ShowIOStatus (op, filnam: ARRAY OF CHAR;
    sts, stv: SYSTEM.LONGWORD);
   
  PROCEDURE SignalIOStatus (op, filnam: ARRAY OF CHAR;
    sts, stv: SYSTEM.LONGWORD);
   
  PROCEDURE Space (VAR s: RMSTypes.RAB;
    blocknr: SYSTEM.SIGNED_64;
    VAR status: LONGINT);
   
  PROCEDURE Truncate (VAR s: RMSTypes.RAB;
    VAR status: LONGINT);
   
  PROCEDURE Update (VAR s: RMSTypes.RAB;
    record, size: SYSTEM.SIGNED_64;
    VAR status: LONGINT);
   
  PROCEDURE Write (VAR s: RMSTypes.RAB;
    blocknr, buffer, size: SYSTEM.SIGNED_64;
    VAR status: LONGINT);

END RMSAccess.
From its interface, module Unix is more or less the same as in implementations of the Oberon System under the Unix operating system. Module Unix serves to hide the underlying operating system's file system and system services. AlphaOberon's module Unix imports RMSAccess to access OpenVMS Record Management Services (RMS).

3. Printing: When invoking Edit.Print, the Oberon System produces PostScript files. In order to be able to copy these files directly to the printer or print queue under OpenVMS, these files get the Stream_LF attribute. The general syntax for the printer tool is "Edit.Print 'Driver'.'FileSpec' *"

Examples for AlphaOberon:

"Edit.Print PSPrinter.Out.PS_LIS *" produces the PostScript file Out.PS_LIS

"Edit.Print PSPrinter.$PRINTER:Out.PS *" copies the PostScript file directly to the logical name $PRINTER. Those who can print PostScript files directly can use GhostScript interpreter (free GNU software, available for all platforms).

4. File access: All input files are opened with read access. Output files are opened with write access, which means that they are locked for other users.

The Oberon System does not release a file as long as there is a reference to it. When the garbage collector (GC) is called, it closes those files which are still open but have no longer a reference to the associated file handle. So a file may still be locked, even if you closed the associated text window. You may close no-longer referenced files on demand by calling "System.Collect" which invokes the GC manually. Note, that the "System.Recall" mechanism does not allow to immediately release a file even if it's associated text window is closed.

5. File name conversion: The file name syntax under OpenVMS does not allow more than one dot ".". The Oberon System and tools use names such as "system.menu.text" quite often. It is undesirable to modify otherwise portable sources of any Oberon tool, just to change the file name syntax to "system_menu.text". So AlphaOberon converts names which contains more than one dot automatically, replacing all but the last dot by an underscore "_".

The user should know this is file name conversion mechanism. For example:

"AsciiCoder.Decode x.y.z: will overwrite the file x_y.z

6. Compilation command qualifiers: When the Oberon compiler is invoked with Compiler.Compile or Folds.Compile, AlphaOberon currently spawns a process with the compilation command

$set com oberon$system:a2o.cld


$a2o/oberon/IEEE/obj=nl: /check=(indexcheck, 
  NOoverflowcheck, NOrangecheck, typecheck, pointerinit, 
  asserteval, stackcheck) /optimize=(rotatescratch) 
  /pointersize=64 /debug 
The other compilation options are those set to default in the command language definition file A2O.CLD. The option /Debug is default, which automatically disables the Alpha instruction scheduler. The command file is called compiler_compile.com and the output of the spawned process is directed to the file compiler_log.lis. When compilation errors are detected, this text file is copied to the Oberon log window. Error messages are displayed by indicating the offending position in the source line in the traditional style of stand-alone compilers. If the indicated error position is wrong, in most cases this is due to different tab-settings in the source. In order to make corrections, the position in the corresponding source window can easily be located for example, by selecting the listing's source line in the log window and searching it in the source window.

Note, that the qualifier /Oberon_LoadFile implies /Ieee and /check=(pointerinit, heapinit), which is a GC requirement and disallows disassembling /machine_code.

To avoid re-loading of the compilers image file H2O.EXE (or H2O_Eval.EXE for the evaluation kit) each time when the compiler is invoked, it is recommended to install the compiler as a shareable image.

To allow the generation of a new symbol file, use the qualifier /SymFile (command line compilation) or "Compiler.Compile */s" (Compiler.Tool).

When not using module Coroutines, disable stack-overflow check: "Compiler.Compile */c". This shortens each procedure entry code.

The default options for the /optimize qualifier is (rotatescratch). To enable the instruction scheduler, use "Compiler.Compile */o/d", which turns off the generation of the symbol table in the Oberon load file needed by the run-time debugger Debug. This means, you can't debug any module which was compiled with the instruction schedule enabled.

7. Recommended Oberon Editor XE: XE is the recommended editor for program development in the Oberon System. It features so-called LocElems (see menu-element "Loc" in the XE menu line), which pops-up (MM click) a window with an alphabetical list of all procedures in the source. Selecting a procedure results in moving the position/caret to the declaration of this procedure. LocElems adapt to texts and can also show and locate paragraphs (Parcs). To achieve this, activate the command "TextLoc.Install" and locating text sections then works for all files which have the extension .Text.

8. Backup file naming: Although OpenVMS has file versions, AlphaOberon keeps the mechanism of renaming the source file when creating a new version (AsciiCoder, XE, Edit, Coco ...), i.e. these tools were not modified to generate a new version and to suppress renaming. Where possible, any changes in the source code of portable applications and tools are avoided. So the decision, whether a file will be renamed or not, is decided by the tools and not by the Alpha Oberon System.

The Oberon software is (assumed to be) portable! There are many tools and applications which rename files because they don't know that they are running under OpenVMS which could do versions. The tools are compiled under AlphaOberon as we get them from ETHZ or University of Linz or other sources. If we would do any changes, we would need to apply the same changes for every update which we get.

Also, the number of available tools is so large that it would be a big effort to check all sources whether OpenVMS file versions could be used or not.

Example: With the editor and AsciiCoder, a file x.Mod is to be written. If x.Mod exists already, it is renamed to x.Mod_Bak, before creating x.Mod.

The file version numbering is maintained for the Oberon symbol and load files. But there are other Oberon applications which don't care about renaming an existing file and just overwrite it. Under OpenVMS, this will create a new version of the file, of course only if the version limit of the directory or the file is set to be greater than one.

9. File versions limits: It is recommended to set the file version limits for Oberon load files (*.OLF) and symbol files (*.SYN) to at least two. For load files, a new version can be generated, even when the old load file is still open (i.e. locked). For symbol files, two versions are needed at compile time, to determine whether a module's interfaces changed. (Remember that there are no definition modules as in Modula-2. Definition modules are generated automatically in Oberon by the Browser or by the Def tool.) The compiler generates always a new symbol file and then compares the old and the new symbol file. If, except for the time stamp (module key), the files are different, this means that the module interface changed and hence the new symbol file is kept, otherwise, if they are equal, the new is deleted and the old is kept. Use the following OpenVMS command to set the version limist.


  $ set file *.syn,*.olf/version=2/log 
or after creating a user directory:

  $ set directory []/version=2/log 
10. Working directory: New files are created on the default directory. Use System.ChangeDirectory to set a new default directory. But you can open/create files on other directories, even over Decnet. But if you use the OpenVMS file specification syntax "node::device:[dir]file.ext" or "logical_name:file.ext" in your Oberon sources, your program will no longer be portable to other operating systems.

The situation is different for existing applications such as Edit or XE. You can specify logical names in front of file names. For example, "XE.Open dev:file.ext" will open that file and when storing the file, XE.Store will create the new file on the device and directory "dev". This works for local or remote devices and directories.

There are some restrictions for remote files, because OpenVMS does not support renaming files from the local host to remote hosts via Decnet. In certain cases, the Oberon editor copies a remote input file "dev:file.ext" to a work file on the default directory and when storing the file, the editor tries to rename the work file to the input file specification.

If storing a text fails, a trap viewer will be displayed. In this case you can still save the text you modified on a local device/directory. Assume the menu-bar is [dev:file.ext | Edit.Close... Edit.Store]. By deleting the logical name specification "dev:" in the menu bar of the window with the mouse (select - ML and delete ML/MR), you get the caret and with it the focus to the window's title line and you can store the text to "file.ext". Or you can insert another logical name or device specification by typing for example "dev1:" before "file.ext". Edit.Store takes the file specification in the window's title.

The file lookup strategy in AlphaOberon: If the file name is not prefixed with any node (::), device or logical name (:) or directory ("[", "<") specification, the default directory is tried and if not found, the logical name "oberon$dir_list:" is prepended. This strategy is applied to all files to be opened, be it system or user, text or binary/code files. The logical name "oberon$dir_list" is normally defined as a search list (see command procedure Setup.com).

If no explicit device or logical name is specified in XE.Open or Edit.Open and the file is not on the default directory, but can be opened via "oberon$dir_list:" from another directory, device or node, XE.Store or Edit.Store create the new file on the default directory!

In AlphaOberon, the file open/close trace is still enabled for test purposes on the console window from where you started Oberon. You can switch from AlphaOberon back to the terminal window on the Alpha Workstation under OSF/Motif by typing ALT-F3 (V6.2, V7.0) or ALT-TAB (V7.1).

To check the setup of the search list try the DCL command


  $dir oberon$dir_list:system.tool 
to see whether you got the search list defined correctly.

If the above directory command finds the file "system.tool", AlphaOberon will also be able to open it (if the file protection allows at least read-acces to the user; if the file is accessed remotely via Decnet, make sure that there are enough system resources at the file server; Oberon opens quite a lot of files and closes them only occasionally, when the GC is called).

It is recommended to set the default directory before starting Oberon and let the search list point to your default directory and in sequence to the directory where the files from the AlphaOberon distribution kit are located.

11. Incompatibilities: There are two different incompatible modules, both called PictElems. One was created at ETH-Zuerich and the other at University Linz. AlphaOberon uses the ETHZ version. The Linz version is Mac specific and not portable. As a consequence, AlphaOberon will not work properly, i.e., it ignores PictElems contained in texts created with the Linz Oberon System for the Mac. To resolve this module name clash, the PictElems from Linz were renamed to MacPictElems (early 1995). But care should be taken when processing texts created with Oberon on the Mac before (for example Debug.Text tries to open files with funny syntax).

The Oberon System uses a medium sized font map (font.map), but some applications such as Dialogs.Text and the Oberon0 system require original font mapping. In this case, start AlphaOberon with the command


  $ Oberon/font=normal.map 
Also, pay attention, if using long file/pathnames, especially in combination with larger fonts: the menu line of the editor should show you the "Store"-command (upper right corner), otherwise you are probably not capable to store a modified text without shortening the file name in the menu bar by selecting a part of the file name with the mouse (ML) and deleting it (ML/MR).

12. Collection of AlphaOberon Tools: The number of portable tools available with source code for the Oberon System V4 from various institutes and individuals is immense. Most contributions come from ETHZ and University Linz. AlphaOberon contains a huge collection of pre-compiled tools and text Elems (LineSorter, Def, Debug (symbolic run-time debugger) Class, VersionElems, BalloonElems, HandlerElems, IndexElems, LinkElems, MarkElems (see elem_guide.text), LocElems (former ProgElems), RX, Scenarios, Automatic, CrazyFillers).

Disclaimer: As customary in the computer business, we have to state explicitly that in no event shall ModulaWare or Guenter Dotzel be liable for any loss of profit or any other commercial damage, including but not limited to special, incidental, consequential or other damages. ModulaWare or Guenter Dotzel specifically disclaim all other warranties, expressed or implied, including but not limited to the implied warranties of merchantability and fitness for a particular purpose, related to defects in the software.

Because most of the additional tools, examples and games are available to the public domain via various ftp-servers and because most of the tools did not require any modification, the current release of AlphaOberon does not include the source code of these tools. However some Oberon-2 examples are provided. ModulaWare tries to keep the module collection consistent and up-to-date.

Some tools like Linz's OberonD and metaprogramming facilities (Ref) which need some platform specific modifications will be added to AlphaOberon when time permits it. The most ugly and non-portable modules I found are DirectoryElems and Directories, because these are too PC/Windows specific. I don't want to blame anybody and maybe my viewpoint is wrong, but I find it amazing, how the culture of an underlying operating system (Windows) penetrates applications developed for a once "designed-to-be" portable Oberon System.


The ModulaTor Forum

Recommended Reading

by Günter Dotzel

How I found Freedom in an unfree world - A handbook for personal liberty, by Harry Brown, 1997 edition.
Quote from the book's cover: Freedom is living your own life as you want to live it. You can have that freedom now, without waiting to change the world or the people around you. Harry Brown shows how to minimize the government's intrusions in your life, how to reduce the demands others make upon your time and resources and how to deal with people who call you selfish when you don't give them what they selfishly want.
Most of all, he shows that you don't have to convince others to let you be free. The decisions are entirely yours. He explains how to make plans and set goals that rely on your actions - that don't depend on others for their success.

Economics in one Lesson, by Henry Hazlitt, 1978.
In the best tradition of Frederic Bastiat, this book begins with a broken window to explain an elementary fallacy, why destruction does not improve the economy. He shows how the price system works and what's wrong with tariffs, minimum wages, unions, and government price fixing.


IMPRESSUM: The ModulaTor is an unrefereed journal. Technical papers are to be taken as working papers and personal rather than organizational statements. Items are printed at the discretion of the Editor based upon his judgement on the interest and relevancy to the readership. Letters, announcements, and other items of professional interest are selected on the same basis. Office of publication. The Editor of The ModulaTor is Günter Dotzel; he can be reached at mailto:[email deleted due to spam]


Home | Site_index | Legal | OpenVMS_compiler | Alpha_Oberon_System | ModulaTor | Bibliography | Oberon[-2]_links | Modula-2_links |

Amazon.com [3KB] [Any browser]

Books Music Video Enter keywords...


Amazon.com logo

Webdesign by www.otolo.com/webworx, 07-Dec-1998