Virtual Pascal GetDate returns Type mismatch? - pascal

I'm trying to port a DOS Pascal app to Windows using Virtual Pascal and working fairly well until this simple procedure:
PROCEDURE SysDate(VAR dt : datetype);
VAR
A,B,C,D : WORD;
BEGIN
GETDATE(A,B,C,D);
DT.YEAR := A;
DT.MONTH := B;
DT.DAY := C;
END;
caused this error:
Error 26: Type mismatch
GETDATE(A,B,C,D);
...........^
Any ideas what may be causing it? I searched the source for virtual pascal and the dos unit is the only thing defining GetDate() and defines all the variables as WORD as it should.

Related

Change default type of int in Pascal with fpc and VS Code

I'm using Free Pascal Compiler (fpc) with VS Code. While playing around I discovered, that the standard type for integer is smallint, when declaring a variable like this:
var i: integer;
When I use longint
the highest value is 2147483647.
Is there a way to change the standard to 'longint', when using 'integer' in the declaration?
For clarification please see the following program:
program Test(output);
var
i: longint;
j: smallint;
k: integer;
begin
i := 234234234;
j := 234234234;
k := 234234234;
writeln(i);
writeln(j);
writeln(k)
end.
The output on my machine is:
234234234
8570
8570
so integer and smallint have the same range which is unusual if I'm not mistaken.
The default FPC dialect is a Turbo Pascal compatible dialect.
Switch to a delphi mode with a -Sd parameter or {$Mode delphi} in the source.
You can add the -Sd parameter to the fpc.cfg if you don't want to enter each time.

Virtual Method Table on Free Pascal

What I'm trying to do is to get the list of fields in a class without an instance... for example:
TAClass=class
a_: Integer;
b_: Integer;
constructor (a,b Integer);
end;
I'm not being able to get the fieldTable from the VMT:
ovmt: PVmt;
ftable: PVmtFieldTable;
finfo: PVmtFieldEntry;
ovmt:=PVmt(TAClass);
ftable := ovmt^.vfieldtable
finfo := ftable^.fields[0]
this way I'm not gettig the list of fields
any help is welcome,
thanks in advance
Afaik the field tables in classic delphi and FPC only work for published fields. Published fields must be class fields (value types like integer must go via properties). Newer Delphi's also allow RTTI for non published fields, but that works differently (different untis), and FPC doesn't support that yet.
I hacked together a small demonstration example since the help for typinfo seems to be light on examples. Note the tpersistent derivation.
{$mode delphi}
uses typinfo,classes;
type
TAClass=class(Tpersistent)
a: tstringlist;
b: tlist;
end;
var
ovmt: PVmt;
FieldTable: PVMTFieldTable;
PVMTFieldEntry;
i: longint;
begin
ovmt := PVmt(TAClass);
while ovmt <> nil do
begin
FieldTable := PVMTFieldTable(ovmt^.vFieldTable);
if FieldTable <> nil then
begin
FieldInfo := #FieldTable^.Fields[0];
for i := 0 to FieldTable^.Count - 1 do
begin
writeln(fieldinfo^.name);
FieldInfo := PvmtFieldEntry(PByte(#FieldInfo^.Name) + 1 + Length(FieldInfo^.Name));
end;
end;
{ Try again with the parent class type }
ovmt:=ovmt^.vParent;
end;
end.

UNIT expected but PROGRAM found

program MouseInput;
Uses WinCrt,Mouse, sysutils,Graph;
Var
GraphicsDriver, GraphicsMode,
ErrCode : smallint;
x, y: word;
Begin
x:=GetMouseX;
Y:=GetMouseY;
Writeln('Initialising Graphics, please wait...');
GraphicsDriver := Detect;
InitGraph(GraphicsDriver, GraphicsMode,'');
x := GetmouseX();
y := GetmouseY();
OuttextXY(0,0,inttostr(x));
readln();
end.
i have this code, but this syntax error occurs:
1 / 1 mouse.pas
Fatal: Syntax error, UNIT expected but PROGRAM found
but this is a program not a unit ?
if i change Mouse to WinMouse it goes away, but throws out other errors saying identifier not found GETMOUSEX and GETMOUSEY
If you look in the folder units/rtl, you will find the unit files 'mouse.o' and 'mouse.ppu'. I think there is a conflict between the file names, because the compiler expects another unit file to update these. By changing the name of your file to 'mousetest.pas' the compiler did everything fine.

Why does the compiler expect ")" where I've put "," in my function declaration?

In my AS-level computing course we're using Turbo Pascal, and for extension work I've been given the task of making a Blackjack/21 style card game. I decided to make a unit for general card game data structures:
unit CardLib;
interface
type
CardSuite = (clubs, diamonds, hearts, spades);
Card = record
name:String;
value:Integer;
suite:CardSuite;
end;
CardDeck = object
cards: Array[0..51] of Card;
freeIndex: Integer;
constructor init;
procedure addNewCard(suite:CardSuite, name:String, value:Integer);
procedure addCard(c:Card);
function drawCard:Card;
destructor done;
end;
CardHand = object
cards: Array[0..51] of Card;
freeIndex: Integer;
constructor init(deck:CardDeck, size:Integer);
function getLowestTotal:Integer; {Aces are worth 1}
function getHighestTotal:Integer; {Aces are worth 11}
procedure addCard(c:Card);
destructor done;
end;
...
I'm compiling this code with Free Pascal in Turbo Pascal compatibility mode, but I'm getting the following error:
CardLib.pas(18,39) Fatal: Syntax error, ")" expected but "," found
Fatal: Compilation aborted
Error: /usr/bin/ppcarm returned an error exitcode (normal if you did not specify a source file to be compiled)
If I comment out the addNewCard procedure, I get the same error in the CardHand constructor instead. Any ideas what's causing this?
Use semicolons to separate the parameters.
procedure addNewCard(suite:CardSuite; name:String; value:Integer);

TNetSharingManager access violation problem

I'm trying to compile this project in Delphi 2010, which uses TNetSharingManager. I have imported the type library and tried compiling it, but unfortunately I'm getting an Access Violation in this function:
function TNetSharingManager.GetDefaultInterface: INetSharingManager;
begin
if FIntf = nil then
Connect;
Assert(FIntf nil, 'DefaultInterface is NULL. Component is not connected to Server. You must call "Connect" or "ConnectTo" before this operation');
Result := FIntf;
end;
(part of NETCONLib_TLB)
The error is in : if FIntf = nil then for some odd reason..
The code which is calling it:
procedure TForm1.GetConnectionList(Strings,IdList: TStrings);
var
pEnum: IEnumVariant;
vNetCon: OleVARIANT;
dwRetrieved: Cardinal;
pUser: NETCONLib_TLB.PUserType1;
NetCon : INetConnection;
begin
Strings.Clear;
IdList.Clear;
pEnum := ( NetSharingManager.EnumEveryConnection._NewEnum as IEnumVariant);
while (pEnum.Next(1, vNetCon, dwRetrieved) = S_OK) do
begin
(IUnknown(vNetCon) as INetConnection).GetProperties(pUser);
NetCon := (IUnknown(vNetCon) as INetConnection);
if (pUser.Status in [NCS_CONNECTED,NCS_CONNECTING])//remove if you want disabled NIC cards also
and (pUser.MediaType in [NCM_LAN,NCM_SHAREDACCESSHOST_LAN,NCM_ISDN] )
and (GetMacAddress(GuidToString(pUser.guidId))'' ) then
begin
//we only want valid network cards that are enabled
Strings.Add(pUser.pszwName );
IdList.Add(GuidToString(pUser.guidId));
end;
end;
end;
I don't understand why I cannot compare with nil. Any ideas?
It is likely the TNetSharingManager object itself has actually died (or wasn't created in the first place) when that error is triggered. The FIntF = nil expression is the first reference to an actual field of the class, i.e. it will be pointing into invalid address space.
[Edit] I download the source and followed the steps to import the TLB (Delphi 2010). To execute the appilcation, I had to (a) run Delphi as an admin, because I'm not a power user by default and (b) had to add a check for pUser <> nil because the final getProperties returns a nil-structure, but other than that the code run fine. So unfortunately, I can't seem to reproduce your problem.
Rereading your question, are you getting an AV while compiling?

Resources