Frank Heckenbach a écrit:
Prof A Olowofoyeku (The African Chief) wrote: 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.)
To summarize, the correct translation, with a test program would be ------------------------------------------------------------------------
program teststruc;
{$define DWORD cardinal}
type LDT_ENTRY = packed record LimitLow: WORD; BaseLow: WORD; HighWord: packed record case integer of 1: (Bytes: packed record BaseMid: BYTE; Flags1: BYTE; Flags2: BYTE; BaseHi: BYTE end); 2: (Bits: packed record BaseMid: DWORD(8); C_Type: DWORD(5); Dpl: DWORD(2); Pres: DWORD(1); LimitHi: DWORD(4); Sys: DWORD(1); Reserved_0: DWORD(1); Default_Big: DWORD(1); Granularity: DWORD(1); BaseHi: DWORD(8) end) end; end;
type PLDT_ENTRY = ^LDT_ENTRY; LPLDT_ENTRY = PLDT_ENTRY;
var ldt:LDT_ENTRY;
begin with ldt.HighWord do begin with Bytes do begin BaseMid:=$DE; Flags1 :=$AD; Flags2 :=$BE; BaseHi :=$EF; end; with Bits do writeln(BaseMid,' ', C_Type,' ', Dpl,' ', Pres,' ', LimitHi,' ', Sys,' ', Reserved_0,' ', Default_Big,' ', Granularity,' ', BaseHi); end; readln end.
-------------------------------------------------------------------------
You may check that it is strictly equivalent to
--------------------------------------------------------------------------- #include <stdio.h>
#define WORD unsigned short #define BYTE char #define DWORD unsigned
typedef struct _LDT_ENTRY { WORD LimitLow; WORD BaseLow; union { struct { BYTE BaseMid; BYTE Flags1; BYTE Flags2; BYTE BaseHi; } Bytes; struct { DWORD BaseMid:8; DWORD Type:5; DWORD Dpl:2; DWORD Pres:1; DWORD LimitHi:4; DWORD Sys:1; DWORD Reserved_0:1; DWORD Default_Big:1; DWORD Granularity:1; DWORD BaseHi:8; } Bits; } HighWord; } LDT_ENTRY,*PLDT_ENTRY,*LPLDT_ENTRY;
int main(void) { // struct _LDT_ENTRY ldt; LDT_ENTRY ldt; // equivalent declarations
ldt.HighWord.Bytes.BaseMid = 0xDE; ldt.HighWord.Bytes.Flags1 = 0xAD; ldt.HighWord.Bytes.Flags2 = 0xBE; ldt.HighWord.Bytes.BaseHi = 0xEF;
printf("%d %d %d %d %d %d %d %d %d %d\n", ldt.HighWord.Bits.BaseMid, ldt.HighWord.Bits.Type, ldt.HighWord.Bits.Dpl, ldt.HighWord.Bits.Pres, ldt.HighWord.Bits.LimitHi, ldt.HighWord.Bits.Sys, ldt.HighWord.Bits.Reserved_0, ldt.HighWord.Bits.Default_Big, ldt.HighWord.Bits.Granularity, ldt.HighWord.Bits.BaseHi);
return 0; }
---------------------------------------------------------------------------
I know no C equivalent to with in Pascal ... With respect to my first idea, besides the confusions between types and variables corrected by Franck, it adds no extra type identifier (which would be very problematic with generic identifiers like Bytes, Bits etc). It can be fully automated, because it is systematic: union -> case integer of ... struct -> packed record ... Type -> C_Type: it is the only case here where some kind of prefixing is mandatory. There is inly a finite (small) list of these. The only problem I see is the restriction by pascal to only one case variant in a record. I suppose C has no restriction on the number of union inside a struct. This can be solved only by some extra types.
Maurice