Prof A Olowofoyeku (The African Chief) wrote:
Here are some examples:
typedef enum _CM_ERROR_CONTROL_TYPE { IgnoreError=SERVICE_ERROR_IGNORE, NormalError=SERVICE_ERROR_NORMAL, SevereError=SERVICE_ERROR_SEVERE, CriticalError=SERVICE_ERROR_CRITICAL } SERVICE_ERROR_TYPE;
In this case, one just does something like: Const IgnoreError = SERVICE_ERROR_IGNORE; (in cases where it is sufficient to just refer to "IgnoreError" in the code) - but I have no idea how to translate the enum itself as defined.
Simply as Integer (that's what enums in C basically are).
Now, we could discuss enums with specified values as a GPC extension. (I know I'm opening another can of worms, but currently there are so many worms around, I hope they'll eat each other ... ;-)
The perhaps obvious syntax
type Foo = (a = 3, b = 5);
is not a good idea since it's too close (too much read-ahead required) to:
type Foo = (a = 3) .. True;
Using `value' or `:=' instead of `=' might work, though.
Then again, it would not actually be a useful translation for this C type in general, since as I said C enums are really integers, i.e., they must be assignment-compatible with plain integers (which Pascal enums aren't). (The same is true for C "Booleans" in some situations, BTW.)
Maurice Lombardi wrote:
type tHighWord = packed record case integer of 1: (Bytes: tBytes); 2: (Bits: tBits) end;
type tLDT_ENTRY = packed record
type LDT_ENTRY = ...
LimitLow: WORD; BaseLow: WORD; HighWord: tHighWord; end;
type PLDT_ENTRY = ^LDT_ENTRY; LPLDT_ENTRY = PLDT_ENTRY;
Not so easy to implement automatically, however. It needs extra identifiers for type and var of this type: I do not understand enough C to say if HighWord, Bytes and Bits are type names or variable names which can be used to refer to the struct coponent as a whole (I guess the second).
Yes (field names, more precisely).
The other names are types, not variables (see my corrections), BTW.
But it's true, in general you might need some additional identifiers when translating. I suppose this can always be done by automatically adding some prefixes.
Finally Type cannot be an identifier: it is replaced by Typ.
That's why I think an automatic translator should add some prefix to every identifier (such as `C_...'). (The Pascal interface can then still map those for which it's useful, to more readable identifiers.)
Prof. A Olowofoyeku (The African Chief) wrote:
On 19 Dec 2002 at 13:10, Maurice Lombardi wrote:
{$define DWORD cardinal}
Actually, that has to be defined as a type - because it is used throughout (in other units as well).
He did so because of the `DWORD(8)'. To satisfy both requirements, just do:
type DWORD = Cardinal;
[...]
BaseMid: Cardinal(8);
type tBits = packed record BaseMid: DWORD(8); Typ: DWORD(5); Dpl: DWORD(2);
[...]
I see - so that is what those colons mean. In this case, the on-going discussions about what to do with this syntax become even more pertinent.
Indeed, that's the only case where specified sizes are really needed in C interfacing. With this in mind, some of my previous comments might become clearer.
As others suggested, packed subranges could replace `Integer/Cardinal/Word(n)' (which includes the present case). This leaves only `Boolean(n)', and as I said, I severely doubt anyone ever uses an explicit bitfield larger than 1 bit with Boolean semantics in C (and if this happens once in a lifetime, the additional `<> 0' in Pascal is not worth the trouble of discussion).
But again, I have no problem with the `Foo(n)' semantics, only the syntax is problematic (for at least 3 reasons so far).
Frank