The African Chief wrote:
For the other type declarations, I suggest you use the more modern GPC integer types (as invented some months ago), rather than the old style __modifiers__. (Also for real types.)
Frankly, I am totally lost as far as that is concerned. Is there any authoritative list of all the numerical types?
I assume Peter's description in the announcement of GPC-970624 in 199706250026.CAA18851@agnes.dida.physik.uni-essen.de can be considered authoritative:
--- BEGIN QUOTE ---
* GPC has new integer types now. Below is a table with their sizes in bits and their equivalents in (GNU) C.
The size is the same for all platforms I have access to, but I am not sure whether this will always and everywhere be the case. However, compatibility to GNU C is guaranteed to work to the extend of the GNU GPL. ;-) The `*Int' types are signed (integer), the `*Card' types unsigned (cardinal numbers). The `*Word' types are unsigned, too, but should be thought of having undefined sign; they are intended to be used where signedness does not matter.
Bits Signed Unsigned undefined (GNU) C equivalent
8 ByteInt ByteCard Byte [signed|unsigned] char 16 ShortInt ShortCard ShortWord short [unsigned] int 32 Integer Cardinal Word [unsigned] int 32 MedInt MedCard MedWord long [unsigned] int 64 LongInt LongCard LongWord long long [unsigned] int 64 LongestInt LongestCard LongestWord long long [unsigned] int
In addition, you can define the number of bits for `Integer', `Cardinal', and `Word' types by putting it in parentheses,
Type Int16 = Integer ( 16 ); (* 16 bits *)
Unsigned17 = Cardinal ( 17 ); (* 17 bits; stored in 32 bits *) (* except when in packed arrays *) (* and records (or on machines *) (* with 17-bit registers:-). *)
Answer = Word ( 42 ); (* Stored in 64 bits *)
The size is rounded up to the next unit the machine can access, usually a power of 2 with 8 bits being the smallest possible size.
* Subrange types can be packed now:
Type Foo: -12..127; (* Takes 4 bytes (fast access) *) Bar: packed -12..127; (* Takes 1 byte (saves memory) *)
--- END QUOTE ---
So I suppose, for "portable" BP compatibility, the "(n)" variants are best suited:
type ShortInt = Integer (8); Byte = Cardinal (8); Word = Cardinal (16); LongInt = Integer (32); Comp = Integer (64); Integer = Integer (16);
const MaxInt = $7FFF; {@@ better: High(Integer) as soon as High will be built-in} MaxLongInt = $7FFFFFFF; {@@ High(LongInt)}
For the C integers, you can use the table above (e.g. "long = MedInt").
Single, Double and Extended are built-in already. Real can be left as it is (which is either Single or Double, dependent on a swicth, IIRC), or generally defined to Double, I don't know -- it's not 100% the same as in BP, anyway...
Pointer is also built-in, BTW.
Procedures assgined to procedural variables can be in the main program now, so you can remove this comment for ExitProc.
I am still having some problems with this.
Can you show us an example where this is a problem, so it can be fixed?
Another detail concerning ExitProc: There is a little difference between how BP's and GPC's system.pas handle them. BP sets them to NIL before calling an ExitProc. The effect is, when an exit proc "forgets" to assign the next one to ExitProc, the chain will abort rather than infinitely calling the same exit proc. I think the following would be 100% compatible:
to end do begin var Tmp: Pointer; while ExitProc<>nil do begin InOutRes := 0; Tmp := ExitProc; ExitProc := NIL; PProcedure (Tmp)^ end end;
The following program demonstrates the effect:
program x; {$ifdef __GPC__}uses system;{$else}{$f+}{$endif}
var Next1, Next2: Pointer;
procedure e1; begin ExitProc:=Next1; Writeln('ExitProc1') end;
procedure e2; begin (* ExitProc:=Next2; *) Writeln('ExitProc2') end;
begin Next1 := ExitProc; ExitProc := @e1; Next2 := ExitProc; ExitProc := @e2; end.
Assign is built-in now, so you can remove it from system.pas.
Done. Does it now cater for all file types?
Currently only Text files and typed files (which are the same internally in GPC). Untyped files are very different (as declared in system.pas), a fact I'm not very happy with. I think, they will be changed to be like typed files, but probably not until GPC 2.1...
Basically, DOS is a beast of a unit to implement - especially the Findxxx functions. There are still problems with a "DIR" listing using these functions if there are .EXE files in the list. There are all sorts of other problems as well. I don't think it will ever be portable. I have given up on the DOS unit. If someone else wants to do it, please feel free!
I see the problems. I suppose, *if* we can make a C header to Pascal translator (which is a very difficult task), we can make use of some (hopefully portable) C system functions to emulate most of Dos (though this will probably require some amount of additional Pascal code)... I think this is a task to face after 2.1...
Unit Printer:
can be written now (at least for DJGPP).
Done!
BTW: Do you close the printer file it in a "to end do" statement? BP, AFAIK, doesn't do so, but it's better to do.
Ok - thanks. I note Frank's comments - and so I will leave "Val" alone. Frank - will your "Val" procedure deal with reals as well?
Yes, there are different versions for the 10 basic integer types and the 3 real types (shortreal, real, longreal), which will all be "overloaded" to the name "Val". Integer subranges should also work then, bit fields (fields of packed records/arrays that are not complete bytes) might not work until some time later...
Yes, it is. This is how it is implemented in "AddNull", which was in the strings unit before, but I have now moved it into the system unit, since the system unit also uses that functionality.
Any thoughts on whether the system unit should now export this AddNull function so that it can be available globally? This would introduce something which is not in the BP system unit.
I'm not sure if it should, since something like this will be built-in later, so programs shouldn't rely on the version in system.pas. Besides, I think, the name "AddNull" could be unclear or ambiguous (though I doubt someone would write a procedure of this name operating on numbers... ;-). I'd rather call it something like "Str2CString" or so...
PS: - another point entirely; is there a switch that will enable a particular unit (in this case SYSTEM.PAS) to be used automatically, without putting it manually in the USES clause of every source file? I am looking for something like
"--auto-use=xxx.pas,yyy.pas,f:\gpc\zzz.pas",
which I can then use from the command line, or put into to GPCC.CFG file.
I agree, I'd also like to have this -- especially for the system unit. It's planned to make this, perhaps even until 2.1.
Frank Heckenbach wrote:
I assume Peter's description in the announcement of GPC-970624 in 199706250026.CAA18851@agnes.dida.physik.uni-essen.de can be considered authoritative:
--- BEGIN QUOTE ---
- GPC has new integer types now. Below is a table with their sizes in bits and their equivalents in (GNU) C.
[....]
Yes, that is authoritative enough :-) Thanks!
Procedures assgined to procedural variables can be in the main program now, so you can remove this comment for ExitProc.
I am still having some problems with this.
Can you show us an example where this is a problem, so it can be fixed?
I had a problem with it in TESTMEM.PAS in the new bpcompat. However, I have since discovered that the problem lies in mixing the use of "ExitProc", and "AddExitProc" in the same program. Use one or the other, and the problem disappears. Use both == infinite loop.
Another detail concerning ExitProc: There is a little difference between how BP's and GPC's system.pas handle them. BP sets them to NIL before calling an ExitProc. The effect is, when an exit proc "forgets" to assign the next one to ExitProc, the chain will abort rather than infinitely calling the same exit proc. I think the following would be 100% compatible:
to end do begin var Tmp: Pointer; while ExitProc<>nil do begin InOutRes := 0; Tmp := ExitProc; ExitProc := NIL; PProcedure (Tmp)^ end end;
Okay - thanks. I have replaced the code in SYSTEM.PAS with this one.
Assign is built-in now, so you can remove it from system.pas.
Actually, the CygWin32 version still does not have it - so I have left it there (to be compiled only if __CYGWIN32__ is defined).
Unit Printer:
can be written now (at least for DJGPP).
Done!
BTW: Do you close the printer file it in a "to end do" statement? BP, AFAIK, doesn't do so, but it's better to do.
Yes, I do. I have not seen BP's implementation. I only read about it in the help file and wrote some code to do the same thing (i.e., assign, and rewrite the Lst variable in a "to begin do" statement, and then close it in a "to end do" statement). This is all that the unit does (and from what I can see, that is all it needs to do).
Yes, it is. This is how it is implemented in "AddNull", which was in the strings unit before, but I have now moved it into the system unit, since the system unit also uses that functionality.
Any thoughts on whether the system unit should now export this AddNull function so that it can be available globally? This would introduce something which is not in the BP system unit.
I'm not sure if it should, since something like this will be built-in later, so programs shouldn't rely on the version in system.pas. Besides, I think, the name "AddNull" could be unclear or ambiguous (though I doubt someone would write a procedure of this name operating on numbers... ;-). I'd rather call it something like "Str2CString" or so...
Since all that it does is add a null terminator, perhaps I can call it "AddNullTerminator". The problem is that if it is not exported in the SYSTEM unit, then I have to implement it in several units, because the use of that functionality is widespread.
Best regards, The Chief -------- Dr. Abimbola A. Olowofoyeku (The African Chief) Email: laa12@keele.ac.uk Author of: Chief's Installer Pro 4.01 for Win16 and Win32: Winner of PC PLUS Magazine Gold Award (April 1995 U.K. edition) http://ourworld.compuserve.com/homepages/African_Chief/
ftp://ftp.demon.co.uk/pub/ibmpc/win3/apps/chief/pro/chief401.zip