RISCOS.com

www.riscos.com Technical Support:
Programmer's Reference Manual

 

MessageTrans


Introduction and Overview

The MessageTrans module provides facilities for you to separate text messages from the main body of an application. The messages are held in a text file, and the application refers to them using tokens.

Using this module makes it much easier to prepare versions of your program to supply to different international markets. Changing your application's textual output becomes a simple matter of editing its messages file using your favourite text editor.

MessageTrans is not available in RISC OS 2.

Summary of MessageTrans facilities

The module provides SWIs to

  • get information about a message file
  • open a message file
  • look up a text message in the file by its token
  • look up a text message in the file by its token, and then GSTrans it
  • look up a text message in the file by its token, and convert it to an error block
  • look up text messages in the file by their tokens, and convert them to a menu structure
  • close a message file.

It also provides a service call to ease the handling of message files over (for example) a module reinitialisation.

Technical Details

Message file descriptors

MessageTrans uses a file descriptor to refer to message files. A file descriptor consists of a 4-word data structure. A file descriptor is always passed to MessageTrans as a pointer to this data structure.

We recommend that when your application stores a file descriptor, it uses a fifth word to keep a record of the file's status (ie whether or not it is open).

Global messages

If MessageTrans is passed a null pointer to a file descriptor, it uses a file of global messages, held in Resources:$.Resources.Global.Messages. Obviously, if any of these messages are suitable for your application, you should use them; this will save on RAM usage, and on any future effort in translating these messages.

Message file format

Message files contain a series of one-line token / value pairs, terminated by character 10 (an ASCII linefeed).

<file> ::= { <line> }*
<line> ::= <tokline> | '#' <comment><nl> | <nl>
<tokline> ::= <token> { '/'<token> | <nl><token> }* : <value><nl>
<token> ::= <tokchar> { <tokchar> }*
<tokchar> ::= <char> | <wildcard>
<char> ::= any character > ' 'except ',', ')', ':', '?' or '/'
<wildcard> ::= '?' (matches any character)
<comment> ::= { <anychar> }*
<anychar> ::= any character except <nl>
<nl> ::= character code 10
<value> ::= { <anychar> | '%0' | '%1' | '%2' | '%3' | '%%' }*

Note that the spaces in the above description are purely to improve readability - in fact spaces are significant inside tokens, so should only really appear in <comment> and <value>.

Alternative tokens

Alternative tokens are separated by '/' or <nl>. If any of the alternative tokens before the next ':' in the file match the token supplied in a call, the value after the next ':' up to the following <nl> is returned.

Wildcards

The '?' character in a token in the file matches any character in the token supplied to be matched.

Case significance

Case is significant.

Parameter substitution

Most MessageTrans SWIs support parameter substitution. If R2 is not 0 on entry, '%0', '%1', '%2' and '%3' are substituted with the parameters supplied in R4...R7, except where the relevant register is 0, in which case the text is left alone. '%%' is converted to '%'; otherwise if no parameter substitution occurs the text is left alone. No other substitution is performed on the string.

Example file

# This is an example message file
TOK1:This value is obtained only for "TOK1".
TOK2
TOK3/TOK4:This value is obtained for "TOK2","TOK3" or "TOK4"
TOK?:This value is obtained for "TOK<not 1,2,3 or 4>"
ANOTHER:Parameter in R4 = %0, parameter in R5 = %1.
MENUTITLE:Title of menu
MENUITEM1:First item in menu
MENUITEM2:Second item in menu
MENUITEM3:Third item in menu

Unmatchable tokens

There are a number of actions MessageTrans may take if it fails to find a match in the specified file. In order they are:

  1. Search for the token in the file of global messages.
  2. Use a default string (see below).
  3. Generate an error (see below).
Supplying default strings

Whenever you have to supply MessageTrans with a token to be matched, you can also supply a default string to be used if MessageTrans is unable to match the token. The syntax is:

token:default

That is, the token and its default value are separated by a ':'. The default value must be null terminated.

Errors

MessageTrans generates the error 'Message token xxx not found' if it is totally unable to supply any string equivalent to a token. This error is also given if the string to be returned is on the last line of the file, and does not have a terminating ASCII linefeed.

Service_Reset

Since MessageTrans does not close message files on a soft reset, applications that do not wish their message files to be open once they leave the desktop should call MessageTrans_CloseFile for all their open files at this point. However, it is perfectly legal for message files to be left open over a soft reset.

Service_MessageFileClosed

If a messages file is held in ResourceFS, MessageTrans does not make a copy of the message file, but instead directly accesses the file. Service_MessageFileClosed is used to notify MessageTrans that the ResourceFS file has been removed for one reason or another.

Service Call


Service_MessageFileClosed
(Service Call &5E)

Message files have been closed

On entry

R0 = 0, or - under RISC OS 3 (version 3.00) only - the 4-word data structure passed to MessageTrans_OpenFile
R1 = &5E (reason code)

On exit

All registers are preserved

Use

This call is issued by MessageTrans as a broadcast to warn that all message files have been closed. You must not claim it.

If your application has any direct pointers into message data, it should re-initialise itself by calling MessageTrans_OpenFile again to re-open the file, and recache its pointers. If it has used MessageTrans_MakeMenus, it should call Wimp_GetMenuState to see if its menu tree is open, and delete it using Wimp_CreateMenu (-1) if so.

You only need to act on this service call if you are using direct pointers into the message file data. Otherwise, the MessageTrans module will make a note in the file descriptor that the file has been closed, and simply re-open it when you next call MessageTrans_Lookup or MessageTrans_MakeMenus on that file.

We recommended that you don't use direct pointers into message file data (eg indirected icons with MessageTrans_MakeMenus) if your application cannot trap service calls. You can still use such indirected icons, if you provide a buffer pointer in R2 on entry to MessageTrans_OpenFile (so that the message file data is copied into the buffer).

Under RISC OS 3 (version 3.00) this service call is instead issued for each open message file that is not held in the user's own buffer. It tells the application that its file data has been thrown away, for example if the file is held inside a module which is then reloaded. The file is identified by the 4-word data structure passed to MessageTrans_OpenFile. If you recognise this value, you should claim the service call and act accordingly.

SWI Calls


MessageTrans_FileInfo
(SWI &41500)

Gives information about a message file

On entry

R1 = pointer to filename

On exit

R0 = flag word:

bit 0 set => file is held in memory (can be accessed directly)
bits 1-31 reserved (ignore them)
R2 = size of buffer required to hold file

Interrupts

Interrupt status is unaltered
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

SWI is re-entrant

Use

This call gives information about a message file, telling you if it is held in memory, and the size of buffer that is required to hold the file. If the file is held in memory, and you require read-only access, you need not use a buffer to access it.

Related SWIs

MessageTrans_OpenFile

Related vectors

None


MessageTrans_OpenFile
(SWI &41501)

Opens a message file

On entry

R0 = pointer to file descriptor, held in the RMA if R2=0 on entry
R1 = pointer to filename, held in the RMA if R2=0 on entry
R2 = pointer to buffer to hold file data

0 => allocate some space in the RMA, or use the file directly if possible

On exit

--

Interrupts

Interrupt status is unaltered
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

SWI is re-entrant

Use

This call opens a message file for subsequent use by the MessageTrans module.

The error 'Message file already open' is generated if R0 points to a structure already known to MessageTrans (ie already open).

An application may decide that it would like to buffer the file in its own workspace (rather than the RMA) if it needs to be loaded, or use the file directly if it is already in memory. To do this:

SYS "MessageTrans_FileInfo",,filename$ TO flags%,,size%
IF flags% AND 1 THEN buffer%=0 ELSE buffer%=FNalloc(size%)
SYS "OS_Module",6,,,17+LENfilename$ TO ,,filedesc%
$(filedesc%+16)=filename$
SYS "MessageTrans_OpenFile",filedesc%,filedesc%+16,buffer%

where FNalloc() allocates a buffer of a given size, by using the Wimp_SlotSize or 'END=' command. Note that in fact the filename and file descriptor only need to be in the RMA if R2=0 on entry to MessageTrans_OpenFile.

Furthermore, if R2=0 on entry to this SWI, and the application uses direct pointers into the file (rather than copying the messages out) or uses MessageTrans_MakeMenus, it should also trap Service_MessageFileClosed, in case the file is unloaded.

Related SWIs

MessageTrans_FileInfo, MessageTrans_CloseFile

Related vectors

None


MessageTrans_Lookup
(SWI &41502)

Translates a message token into a string

On entry

R0 = pointer to file descriptor passed to MessageTrans_OpenFile, or 0 to use global messages file
R1 = pointer to token, terminated by character 0, 10 or 13
R2 = pointer to buffer to hold result (0 => don't copy it)
R3 = size of buffer (if R2 non-zero)
R4 = pointer to parameter 0 (0 => don't substitute for '%0')
R5 = pointer to parameter 1 (0 => don't substitute for '%1')
R6 = pointer to parameter 2 (0 => don't substitute for '%2')
R7 = pointer to parameter 3 (0 => don't substitute for '%3')

On exit

R0 preserved
R1 = pointer to terminator of token
R2 = pointer to result string (read-only with no substitution if R2=0 on entry)
R3 = size of result before terminator

Interrupts

Interrupt status is unaltered
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

SWI is re-entrant

Use

This call translates a message token into a string, with optional parameter substitution. If the token is not found in the given message file, it is then looked up in the global messages file; see the chapter entitled Global messages.

Your application must have previously called MessageTrans_OpenFile, although you can still call this SWI if the file has been automatically closed by the system, because the system will also automatically re-open the file.

See the chapter entitled Message file format for further details of the file format used to hold message tokens and their corresponding strings.

Related SWIs

MessageTrans_ErrorLookup, MessageTrans_GSLookup

Related vectors

None


MessageTrans_MakeMenus
(SWI &41503)

Sets up a menu structure from a definition containing references to tokens

On entry

R0 = pointer to file descriptor passed to MessageTrans_OpenFile, or 0 to use global messages file
R1 = pointer to menu definition (see below)
R2 = pointer to buffer to hold menu structure
R3 = size of buffer

On exit

R0, R1 preserved
R2 = pointer to end of constructed menu structure
R3 = bytes remaining in buffer (0 if call was successful)

Interrupts

Interrupt status is unaltered
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

SWI is re-entrant

Use

This call sets up a menu structure from a definition containing references to tokens, and also sets up appropriate widths for the menu and any submenus. Parameter substitution is not allowed.

The menu structure created can then be passed directly to Wimp_CreateMenu.

Your application must have previously called MessageTrans_OpenFile, although you can still call this SWI if the file has been automatically closed by the system, because the system will also automatically re-open the file.

A 'Buffer overflow' error is generated if the buffer provided for the menu structure is too small.

The menu definition consists of one or more submenu definitions, terminated by a null byte. Each submenu definition consists of a title definition followed by one or more menu item definitions. A title definition has the following structure:

Bytes Meaning
n token for menu title, terminated by character 0, 10 or 13
1 menu title foreground and frame colour
1 menu title background colour
1 menu work area foreground colour
1 menu work area background colour
1 height of following menu items
1 vertical gap between items

and a menu item definition has this structure:

Bytes Meaning
m token for menu item, terminated by character 0, 10 or 13
word-align to here (addr := (addr+3) AND (NOT 3))
4 menu flags (bit 7 set => last item)
4 offset from RAM menu start to RAM submenu start (0 => no submenu)
4 icon flags

If the icon flags have bit 8 clear (ie they are not indirected), the message text for the icon will be read into the 12-byte block that forms the icon data; otherwise the icon data will be set up to point to the message text inside the file data. In the latter case they are read-only.

If the menu item flags bit 2 is set (writable) and the icon is indirected, the 3 words of the icondata in the RAM buffer are assumed to have already been set up by the calling program. The result of looking up the message token is copied into the buffer indicated by the first word of the icon data (truncated if it gets bigger than the buffer size indicated in [icondata,#8]).

See the chapter entitled Message file format for further details of the file format used to hold message tokens and their corresponding strings.

For a more complete definition of the flags etc used in the menu definition, see the definition of Wimp_CreateMenu.

Related SWIs

None

Related vectors

None


MessageTrans_CloseFile
(SWI &41504)

Closes a message file

On entry

R0 = pointer to file descriptor passed to MessageTrans_OpenFile

On exit

--

Interrupts

Interrupt status is unaltered
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

SWI is re-entrant

Use

This call closes a message file.

Related SWIs

MessageTrans_OpenFile

Related vectors

None


MessageTrans_EnumerateTokens
(SWI &41505)

Enumerates tokens that match a wildcarded token

On entry

R0 = pointer to file descriptor passed to MessageTrans_OpenFile
R1 = pointer to (wildcarded) token, terminated by character 0, 10, 13 or ':'
R2 = pointer to buffer to hold result
R3 = size of buffer
R4 = index (zero for first call)

On exit

R0, R1 preserved
R2 preserved, or zero if no further matching tokens found
R3 = length of result excluding terminator (if R2 [NOT EQUAL] 0)
R4 = index for next call (non-zero)

Interrupts

Interrupt status is unaltered
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

SWI is re-entrant

Use

This call successively enumerates tokens that match a wildcarded token. Each successive call places a token in the buffer pointed to by R2, with the same terminator as that used for the wildcarded token that it matches. To enumerate all matching tokens, you should set R4 to zero, and repeatedly call this SWI until R2 is zero on exit.

Valid wildcards in the supplied token are:

Wildcard Meaning
? match 1 character
* match 0 or more characters

See the chapter entitled Message file format for further details of the file format used to hold message tokens and their corresponding strings.

You cannot pass R0 = 0 to enumerate the global message tokens.

Related SWIs

None

Related vectors

None


MessageTrans_ErrorLookup
(SWI &41506)

Translates a message token within an error block

On entry

R0 = pointer to error block (word aligned)
R1 = pointer to file descriptor passed to MessageTrans_OpenFile, or 0 to use global messages file
R2 = pointer to buffer to hold result (0 => use internal buffer)
R3 = buffer size (if R2 non-zero)
R4 = pointer to parameter 0 (0 => don't substitute for '%0')
R5 = pointer to parameter 1 (0 => don't substitute for '%1')
R6 = pointer to parameter 2 (0 => don't substitute for '%2')
R7 = pointer to parameter 3 (0 => don't substitute for '%3')

On exit

R0 = pointer to error buffer used
V flag set

Interrupts

Interrupt status is unaltered
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

SWI is re-entrant

Use

This call translates a message token within an error block, with optional parameter substitution. If the token is not found in the given message file, it is then looked up in the global messages file; see the chapter entitled Global messages.

On entry the error block must contain:

Offset Contents
0 error number
4 null terminated token

On exit the token is translated to the corresponding string. To test for successful error lookup, you should check the error number returned in the error block.

If R2 is 0 on entry, MessageTrans will use one of its internal buffers for the result. There are 10 buffers for foreground processes and 2 for calls made from within IRQ processes. MessageTrans will cycle between these buffers.

Your application must have previously called MessageTrans_OpenFile, although you can still call this SWI if the file has been automatically closed by the system, because the system will also automatically re-open the file.

See the chapter entitled Message file format for further details of the file format used to hold message tokens and their corresponding strings.

Related SWIs

MessageTrans_Lookup, MessageTrans_GSLookup, MessageTrans_CopyError

Related vectors

None


MessageTrans_GSLookup
(SWI &41507)

Translates a message token into a string, GSTrans'ing it

On entry

R0 = pointer to file descriptor passed to MessageTrans_OpenFile, or 0 to use global messages file
R1 = pointer to token, terminated by character 0, 10 or 13
R2 = pointer to buffer to hold result (0 => don't copy it)
R3 = size of buffer (if R2 non-zero)
R4 = pointer to parameter 0 (0 => don't substitute for '%0')
R5 = pointer to parameter 1 (0 => don't substitute for '%1')
R6 = pointer to parameter 2 (0 => don't substitute for '%2')
R7 = pointer to parameter 3 (0 => don't substitute for '%3')

On exit

R0, R1 preserved
R2 = pointer to result string (read-only with no substitution if R2=0 on entry)
R3 = size of result before terminator

Interrupts

Interrupts are enabled
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

SWI is not re-entrant

Use

This call translates a message token into a string, with optional parameter substitution. If the token is not found in the given message file, it is then looked up in the global messages file; see the chapter entitled Global messages. The string is GSTrans'd after parameter substitution; this needs an intermediate buffer, and so will fail if one cannot be allocated from the RMA.

Your application must have previously called MessageTrans_OpenFile, although you can still call this SWI if the file has been automatically closed by the system, because the system will also automatically re-open the file.

See the chapter entitled Message file format for further details of the file format used to hold message tokens and their corresponding strings.

Calling this SWI with R2=0 is exactly equivalent to calling MessageTrans_Lookup with R2=0

Related SWIs

OS_GSTrans, MessageTrans_Lookup, MessageTrans_ErrorLookup

Related vectors

None


MessageTrans_CopyError
(SWI &41508)

Copies an error to one of the MessageTrans internal buffers

On entry

R0 = pointer to error block (word aligned)

On exit

R0 = pointer to error buffer used

Interrupts

Interrupt status is unaltered
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

SWI is re-entrant

Use

This call copies an error to one of the MessageTrans internal buffers. There are 10 buffers for foreground processes and 2 for calls made from within IRQ processes. MessageTrans will cycle between these buffers.

Related SWIs

MessageTrans_ErrorLookup

Related vectors

None

This edition Copyright © 3QD Developments Ltd 2015
Last Edit: Tue,03 Nov 2015