Defmod Extension

Tony van der Hoff OSLib at mk-net.demon.co.uk
Wed Nov 1 11:11:48 GMT 2000


On Tue, 31 Oct 2000, at 11:38:39, Jonathan Coxhead
<jonathan at doves.demon.co.uk> wrote on the subject "Defmod Extension":

>   Tony wrote ...
>
> | 1. I propose to extend DefMod to accept macro definitions in swi files,
> | so that I can define some macros to use for filling in the various
> | offset fields in (for instance) toolbox object templates.
>
>   Could you describe what you want to achieve by the change in more detail?
>
Yes, please forgive me if I'm telling you things you already know ;-)

The toolbox modules define templates, which describe an object. These
are used both in the res file, and in in-memory object descriptors.
Whilst I have hit the problem specifically in generating resource files,
it also applies to in-memory resource generation.

These templates consist of a standard header, followed by an object-
specific part.

The header part is defined by OSLib as:
TYPE
   Toolbox_ResourceFileObject = .Struct
   (  Toolbox_Class: class_no,
      .Bits: flags,
      .Int: version,
      [Toolbox_NameLimit] .Char: name,
      .Int: size,
      .Int: header_size,
      .Int: body_size,
      .Int: object ...
   );

Here, |header_size| is the size of the resulting base structure, and is,
in fact the offset of the object-specific part from the beginning of the
structure.

|body_size| is the size of the derived structure; i.e. it includes the
object-specific members, but no string and message tables. 

|size| is the total file size of the object, including its string and
message tables, which, I think, can be ignored for this discussion.

Whilst it is easy enough for a programmer to calculate the contents of
these ints at compile time using (in C) |sizeof| statements, it is not
necessarily clear which structure to take the size of; particularly as
we have introduced a plethora of similar-looking structures with the
incorrect sizes. If he were to use sizeof(toolbox_resource_file_object),
he'd end up with a possibly incorrect offset to the data.

What I would therefore ideally like to provide is a set of constants,
which can be assigned to these fields at runtime. It would possible to
simply assign some CONSTs to fulfil this purpose, but hardly desirable
as that would negate the whole purpose of these offsets, namely to
provide for future changes in the structure sizes. So, I would like to
be able to calculate these offsets at compile time.

Ideally, DefMod should perform this task, and allocate the value to a
CONST. However, it seems to me that this is a bit much to expect from
DefMod (I would be pleased to be shown to be wrong :-), so, the next
best thing would be for the target language to do it. Hence macros -
hardly ideal, as you point out; show me the right way!

>   The neat thing about the SWI files is that they are language-independent
<snip>
That is true, but I felt that we'd already started drifting away from
that ideal by introducing macros for the ..._MEMBERS declarations. On
reflection, this was an incorrect assumption.
>
>   For example, if there's ever going to be a native C++ interface, we will 
>be able to express the base/extension mechanism, which is expressed in C by 
>generating macros ending in _MEMBERS, as class inheritance. That was the 
>real point of doing it that way---it's an expression of an object-oriented 
>design, which just happens to have a macro implementation when it targets a 
>non-O O language (C).
>
Yes, you'll recall that I asked you a couple of weeks ago why we'd done
it that way. That wasn't your answer then ;-)

<snip>

> | 
> | struct wimp_window_base
> | { wimp_WINDOW_MEMBERS
> | };
>
>   This all looks good too.
>
> | This gets a bit silly for, say, toolbox_action_header, where we now have
> | toolbox_action_header_base; this would really have been better named
> | toolbox_action_base, but for backwards compatibility I see no other
> | simple solution.
>
>   Here's what I've done when I want to introduce a new naming convention:
>
>      (a) Define the new (preferred) name ("a") as the thing.
>
>      (b) Introduce a typedef of the old name ("b"). DefMod allows this as
>
>             TYPE b = a
>
>      (c) Forget about the old name "b" and the naming convention that
>          implied it---in other words, don't continue the old naming
>          convention in new software, just use the new from now on. (This
>          is only relevant when writing a new module.)
>
>   So you would implement your new scheme, but add
>
>      TYPE Toolbox_ActionHeaderBase = Toolbox_ActionBase "Compatibility"
>
>to "toolbox.swi".

I don't think I explained myself very well, or maybe I'm just
misunderstanding you, but I don't see how that helps. The problem is
this (using toolbox_action as an example):

Toolbox_Action was defined long ago, and is therefore immutable as a
name. When, for V6.0, we decided to separate out the header and extended
parts, we  called the definition, which includes the repeated member,
Toolbox_ActionHeader. Maybe this was not the right choice of name;
ideally it would have been Toolbox_Action, but we're stuck with it.

Unfortunately, the resultant |toolbox_action_header| structure contains
an [UNKNOWN] array of the repeated member, and as UNKNOWN evaluates to
1, it is *not*, in fact, the required header. I'm assuming this was
deliberate, to support backward compatibility for other structs (such as
Wimp_Window), otherwise we could simply call it a bug, and fix it.
In any case, it has rendered the chosen name illogical, as it does not
correctly describe the use of the structure, and I think this is the
root of the problem.

Also emitted is our macro, TOOLBOX_ACTION_HEADER_MEMBERS, which does
contain just the header members. So, to fulfil the object of all this,
and get our required header, we need a new struct, just made up from
this macro. I've done this in cheader by simply taking the C name of the
defined struct (i.e |toolbox_action_header| ), and suffixing it with
|_base|, which results in the ungainly and tautologous name
|toolbox_action_header_base|. 

In the case of Wimp_Window, we get a wimp_window_base, and all looks
fine. So, unless you can see a better way, I think we're stuck with the
silly name.

Thanks for your valuable support and advice, Jonathan.

cheers, Tony
-- 
Tony van der Hoff         |  mailto:OSLib at mk-net.demon.co.uk
Buckinghamshire, England  |  http://www.mk-net.demon.co.uk/oslib/
----------------------------------------------------------------



More information about the oslib-team mailing list