FreePascal: Identifier not found "MEMW" - freepascal

I am migrating a Turbo Pascal application into Free Pascal 32 bit for Windows 7 operating system. Whenever I compiled unit file in Free Pascal, the compiler shows error message:
Identifier not found `MEMW`.
Can anybody help me on this? My code is shown below, is there any option to implement the same thing?
PROCEDURE window_object.appear;
VAR
width_offset,
height_offset : BYTE;
current_location : location_pointer;
BEGIN
current_location:=first_location;
FOR height_offset:=y TO (y+y_offset-1) DO
BEGIN
FOR width_offset:=x TO (x+x_offset-1) DO
BEGIN
**MEMW[$B800:(width_offset-1)*2
+(height_offset-1)*160]:=current_location^.code;**
current_location:=current_location^.next;
END;
END;
current_location^.next:=NIL;
END;

Access to the DOS screen at $B800 is only possible in DOS versions.
DOS versions are only supported in dosboxes of Win98, so not supported under Windows NT variants like NT4/W2k/XP/w2003,vista,w2008,w7,w8(.1)
In general, code relying on DOS direct screen access schould be rewritten to use the video unit.
The Video unit is platform independent, and maintains a virtual screen buffer. The VideoBuf variable allows direct access to it. Procedural variables can be used to minimize the needed modifications:
Recently I made a simple unit for the TP dialedit program (which is a Turbo Vision application).
For this to work, the main program needs
to call video.initvideo on startup
video.donevideo on shutdown.
Non Turbo Vision programs need to also call updatescreen(false) to update the screen (e.g. as the last line in your function)
The unit:
unit videord;
// emulates three param screen[] array for dialedit.
// can't be in dialedit since procedural properties aren't allowed in $mode tp
interface
uses Video;
function videoreadchar(x,y,z:integer):char;
// Coordinates are 1 based, z=0 gets the character, z=1 gets the attribute.
property screen[x,y,z:integer]:char read videoreadchar;
implementation
function videoreadchar(x,y,z:integer):char;
Var
P: Integer;
begin
P:=((X-1)+(Y-1)*ScreenWidth);
videoreadchar:=pchar(#VideoBuf^[P])[z];
end;
end.

Related

How to use Eiffel functions?

So I'm just starting to learn Eiffel. One of the first exercises in the book I'm using says to make a function that does base^exp without using ^. I've copied my code below.
class
APPLICATION
inherit
ARGUMENTS
create
make
feature {NONE} -- Initialization
make
-- Run application.
do
create power(2;3)
printf("2 to the power of 3 is " + answer)
end
power(base : REAL; exp : INTEGER) : REAL
-- computers base raised to the bower of exp without using ^
local
remain : INTEGER
do
remain := exp
if remain = 0 then
result := 1
else
from
until
remain = 0
loop
result := result * result
remain := remain -1
end
end
end
end
How do I use this? Do I need it on the same level as feature{NONE}'s make? I know how I'm calling it is wrong, and I can't find anything in the chapter I just read, or online on how to pass parameters into it or how to use it's results.
There are several issues with the original code:
create is used to create an object, but you are not going to create anything, but to get a result of a computation of the function power by calling it. Therefore the keyword create is not needed.
You are using an entity answer to report the result of evaluation on a screen. However it is not declared anywhere. I believe the proper place would be a local variable declaration section.
The entity answer is not initialized to the result of the function power. This is usually done by an assignment instruction.
Feature arguments are separated by a comma, not by a semicolon.
From the original code it's unclear what is the type of the variable answer. Assuming it matches the type of the function power, before adding it to a string, it needs to be converted to a string. This is done by calling the feature out.
The standard feature for printing a string to a console is print, not printf.
Combining the critical points above, we get
make
-- Run application.
local
answer: REAL
do
answer := power(2, 3)
print ("2 to the power of 3 is " + answer.out)
end
After that the code can be compiled. Now less critical points:
It is a good style to put features to a dedicated feature clauses, so I would add a line like feature -- Basic operations before the feature power.
The implementation of the feature power has at least two problems. I'm not going to detail them here, but would give two hints instead:
by default numeric Result is initialized to 0, this needs to be taken into account for operations that use it without first assigning any other value
even though an argument base is passed to the function power it remains unused in the original version of the code

Attaching to datasets previously created by another thread

this is a question similar to this one but with a different background.
Compiler: Delphi 2010, soon Delphi XE5.
I have built a nice application that manages data on a remote MySQL server through the ZEOS components.
Since the connection could fail and SQL be slow I have used the neat OmniThreadLibrary to create an SQL server watchdog and to offload a lot of "read only" tables loading to threads.
As of now I have three data modules manually created before the main form shows, each with their independent TZConnection and some TZReadOnlyQuery components linked to the same data module TZConnection. Each thread instantiates its related data module from within itself and then executes the queries.
The watchdog is working quite well, but I have some doubts about the second part, that is the "read only" tables thread. The queries work already but I have yet to use their results in the main application business code, where I have to insert and update data on other tables.
In my plans I get all these "read only" dataset read and loaded before the main application even connects to them (the whole inter-thread state machine is done already). In theory there should be no concurrency issue as the "read only" tables thread has finished its task and is now being idle.
But I don't know what happens if at this point I connect a control or another dataset / datasource / whatever from the main form to the idle-threaded data module.
Will I mess up because the main form TZSession is not the same of the threaded data module? Will I get rare & nasty access violations to be discovered ONLY after having delivered the application (of course!). Basically with what kind of confidence or precautions should I access a query component created in another thread, assuming only the main application does it and only for reading data? Is it even possible / healthy at all? Or am I missing some "best practices" way of doing it?
Thanks in advance.
I am going to post how I have done it. It'll be "terse" (it's still a monumental wall of text!) due to lack of time, if you find something being too obscure feel free to ask. I don't pretend to have written neither the best nor the quickest nor the best formatted code. Just use it as your starting point.
Short recap of the problem domain: having a software that "pre-opens" tables at startup using a thread. This lets the software stay responsive and even perform other non database related startup tasks.
I have tested this program for 1 month now and the database components used are enough to prove it's not just a "toy demo" ready to break as you add your 3rd dataset.
Ingredients:
As stated above: Delphi 2010+ (I am now running this in RAD Studio XE5 Ultimate) but could probably work with earlier versions. I just did not test them.
ZEOS library, 7 and upwards should work including the latest 7.2 alpha.
OmniThreadLibrary
In my case I also used JVCL but that's only because I needed some specific data source events the basic components don't offer.
IDE, non code portion
create 2 data modules that will host the database components: one is for the "preload", threaded portion, the other for the "runtime", read write portion that will be basically the one used by the program users to perform their tasks.
create 1 unit where to store the thread worker code
create 1 or more form(s) that will constitute your application.
The two data modules would look like this:
Preload module, to be managed by the worker thread.
Portion of the main database module. It includes several additional datasets that the preload module cannot preload. Those are typically "dynamic" datasets whose queries are directly affected by interaction with the users.
The main database module's components started as copy and paste of the preload module so it does not take twice as long to prepare both.
Both the preload and the main database modules come with a ConnectToDatabase and DisconnectFromDatabase procedures that perform all the steps required to have the system up and running.
Very important!
The preload module performs the "true" queries in a separate thread and fills in their related TClientDataSets. Its components have no events attached. I only use them as blind "static" data containers.
The main database module will just "attach" to the preload module components.
In example: whereas the preload module cdsProducts ClientDataSet performs a "true database query" with the
cdsProduct => dspProduct => qryProduct
chain, the main database module cdsProduct just takes the preload module's cdsProduct data without performing any query at all (otherwise what'd be the point, performing queries twice?).
You see how counter-intuitively enough, the main database module cdsProduct comes with a linked TDataSetProvider and query components as well. Why? Because I use them to write modified data back.
That is, we have three program phases:
Startup, where the preload data module performs the queries (in a thread) and that's it. No events managed, all read only.
Running-start phase, where the main database module (in the VCL thread) copies the data gathered in 1 into its ClientDataSets.
Running phase, where the users interact with the main database module's ClientDataSets. When they need to save data (and only then), the main database module's DataSetProviders and queries are engaged. They only write.
I could have skipped the whole ClientDataSet => Provider => Query chain for some of those ClientDataSets but most of them require some huge data processing, must update many joined tables by hand and so on, so I just used the full stack.
Code portion
Lets get to some more nitty-gritty details. I can't post the whole stuff since it's a commercial application so I'll only paste some significant snippets.
Threaded, preload data module
procedure TModDBPreload.ConnectToDatabase;
begin
dbcEShop.Connect;
SendStatusMessage('Loading languages archive');
qryLanguage.Open;
qryLanguage.First;
SearchOptions := [loCaseInsensitive];
ModApplicationCommon.ApplicationLocaleInfo.Lock;
...
try
...
// All the queries parameters needing a language id need to be assigned to the locked LocaleInfo object
qryGeoZone.Params.ParamByName('language_id').AsInteger := ModApplicationCommon.ApplicationLocaleInfo.LocaleIDForQueries;
cdsGeoZones.Params.ParamByName('language_id').AsInteger := ModApplicationCommon.ApplicationLocaleInfo.LocaleIDForQueries;
...
finally
ModApplicationCommon.ApplicationLocaleInfo.Unlock;
end;
SendStatusMessage('Loading countries archive');
cdsGeoZones.Open;
cdsGeoZones.First;
SendStatusMessage('Loading currencies archive');
qryCurrency.Open;
qryCurrency.First;
Sleep(100);
SendStatusMessage('Loading products archive');
cdsProduct.Open;
cdsProduct.First;
...
end;
The above snippet could use a lot of explanations. In particular:
SendStatusMessage('Loading languages archive');
is a thread sending an end user friendly update string to be shown on a status line. Of course the status line is managed by the main VCL thread. How to do it? I'll show it later.
qryLanguage.Open;
qryLanguage.First;
...
cdsGeoZones.Open;
cdsGeoZones.First;
Not all the datasets need to be managed for the whole application duration. Only those that need are managed by ClientDataSets.
The "First" calls happen because I don't know if the server back end will change. Some database drivers, DLLs, (expecially) ODBC connectors etc. etc. don't perform the actual heavy lifting during Open but at the first cursor operation.
Therefore I make sure it happens, even if the current driver does not strictly need it.
The Sleep(100) is there to let the users and the developers see the messages when opening small tables. May be removed once the software is final, of course.
The Lock, try / finally clauses etc. are there to remind you that we are in a thread and some resources are best accessed with some precautions. In this specific case we have other threads (irrelevant for this article, thus not covered) so we have to protect some data structures.
In particular, I have "borrowed" the basic Delphi thread safe list locking mechanism paradygm so the method names are also the same.
OmniThreadLibrary based preload module thread worker
Here is the most relevant / didactic code:
type
TDBPreloadWorker = class(TOmniWorker)
protected
ThreadModDatabase : TModDBPreload;
FStatusString : string;
public
constructor Create;
function Initialize : boolean; override;
procedure Cleanup; override;
procedure SendStatusMessage(anID : Word; aValue : string = ''); overload;
procedure SendStatusMessage(aValue : string); overload;
procedure DisconnectFromDatabase;
procedure OMSendMessage(var msg: TOmniMessage); message MSG_SEND_MESSAGE;
procedure OMDisconnectFromDatabase(var msg: TOmniMessage); message MSG_DISCONNECT_FROM_DATABASE;
procedure OMUpdateStateMachine(var msg: TOmniMessage); message MSG_UPDATE_STATE_MACHINE;
end;
...
constructor TDBPreloadWorker.Create;
begin
Inherited;
FStatusString := 'Connecting to server...';
ThreadModDatabase := Nil;
end;
function TDBPreloadWorker.Initialize : boolean;
begin
ThreadModDatabase := TModDBPreload.Create(Nil);
ModDBPreload := ThreadModDatabase;
ThreadModDatabase.DBPreloadWorker := Self;
DisconnectFromDatabase; // In case of leftover Active := true from designing the software
Result := true;
end;
procedure TDBPreloadWorker.Cleanup;
begin
DisconnectFromDatabase;
ThreadModDatabase.Free;
ThreadModDatabase := Nil;
end;
procedure TDBPreloadWorker.SendStatusMessage(anID : Word; aValue : string);
begin
FStatusString := aValue; // Stored in case the main application polls a status update
Task.Comm.Send(anID, aValue);
end;
procedure TDBPreloadWorker.SendStatusMessage(aValue : string);
begin
SendStatusMessage(MSG_GENERAL_RESPONSE, aValue);
end;
procedure TDBPreloadWorker.DisconnectFromDatabase;
begin
if Assigned(ThreadModDatabase) then
ThreadModDatabase.DisconnectFromDatabase;
end;
procedure TDBPreloadWorker.OMSendMessage(var msg: TOmniMessage);
begin
Task.Comm.Send(MSG_GENERAL_RESPONSE, FStatusString);
end;
procedure TDBPreloadWorker.OMDisconnectFromDatabase(var msg: TOmniMessage);
begin
...
DisconnectFromDatabase;
end;
procedure TDBPreloadWorker.OMSendMessage(var msg: TOmniMessage);
begin
Task.Comm.Send(MSG_GENERAL_RESPONSE, FStatusString);
end;
procedure TDBPreloadWorker.OMUpdateStateMachine(var msg: TOmniMessage);
begin
Task.Comm.Send(MSG_GENERAL_RESPONSE, FStatusString); // Needed to show the pre-loaded status
if Assigned(ThreadModDatabase) then
begin
try
ThreadModDatabase.ConnectToDatabase;
SendStatusMessage('Reading database tables...');
if not ThreadModDatabase.QueryExecute then
begin
raise Exception.Create('Consistency check: the database does not return the expected values');
end;
SendStatusMessage(MSG_SUCCESS, 'Tables have been succesfully read');
SendStatusMessage(MSG_TASK_COMPLETED);
except
On E : Exception do
begin
DisconnectFromDatabase;
SendStatusMessage(MSG_TASK_FAILURE, E.Message);
end;
end;
end;
end;
Some code deserves further explanations:
function TDBPreloadWorker.Initialize : boolean;
creates the preload data module. That is, everything is self contained in the thread's context and does not clash with others.
procedure TDBPreloadWorker.SendStatusMessage(anID : Word; aValue : string);
this is how to send a message (by the way, it's not limited to strings) to the main VCL thread by means of the OmniThreadLibrary.
procedure TDBPreloadWorker.OMUpdateStateMachine(var msg: TOmniMessage);
this is the main preload data module initialization management code. It performs handshaking with the VCL main thread and basically plays as one of the state machines I have implemented in the program.
For those wondering where all those constants come from: they are declared in a separate file included by all the threads related classes. They are simple, free to choose integers:
const
MSG_GENERAL_RESPONSE = 0;
MSG_SEND_MESSAGE = 1;
MSG_SHUTDOWN = 2;
MSG_SUCCESS = $20;
MSG_ABORT = $30;
MSG_RETRY = $31;
MSG_TASK_COMPLETED = $40;
MSG_FAILURE = $8020;
MSG_ABORTED = $8030;
MSG_TASK_FAILURE = $8040;
MSG_UPDATE_STATE_MACHINE = 9;
MSG_TIMER_1 = 10;
MSG_DISCONNECT_FROM_DATABASE = 99;
Main form side preload management code
The various threads are spawned at program start. A TOmniEventMonitor has its OnTaskMessage event pointing to:
procedure TFrmMain.monDBPreloadTaskMessage(const task: IOmniTaskControl;
const msg: TOmniMessage);
var
MessageString : string;
ComponentsNewState : boolean;
begin
MessageString := msg.MsgData.AsString;
if Length(MessageString) > 0 then
UpdateStatusBar(MessageString);
if task = FDBPreloadWorkerControl then
begin
if (msg.MsgID = MSG_TASK_COMPLETED) or (msg.MsgID = MSG_TASK_FAILURE) then
begin
ComponentsNewState := (msg.MsgID = MSG_TASK_COMPLETED);
// Unlike for the watchdog, the preload thread is not terminated
// The data is needed by the program till its end
// DBPreloadTerminate;
// Lets the main database queries be started
DBPreloadSuccess := (msg.MsgID = MSG_TASK_COMPLETED);
MainViewEnabled := ComponentsNewState;
if msg.MsgID = MSG_TASK_FAILURE then
begin
if MessageDlg('Unable to load the data tables from the database server', mtError, [mbRetry, mbAbort], 0) = mrAbort then
Close
else
// Reinitialize the preload thread.
...
end;
end;
end;
end;
This is the totally simple procedure that in the end gets called in order to update the main form's status bar:
procedure TFrmMain.UpdateStatusBar(Value : string);
begin
pnlStatusBar.SimpleText := Value;
pnlStatusBar.Update;
Application.ProcessMessages;
end;
Main database module management code
Last but not least, here is how to actually "attach" to the preload data module ClientDataSets. Call this code from the main form and the foundations of your application are basically done!
procedure TModDatabase.ConnectToDatabase;
procedure ConnectDataSet(CDS : TClientDataSet; PreloadDataSet : TClientDataSet; RuntimeDataSet : TZAbstractRODataset; SetLanguage : boolean = false);
begin
// Only required by datasets needing a locale_id parameter
if (SetLanguage) then
begin
CDS.Params.ParamByName('language_id').AsInteger := ModApplicationCommon.ApplicationLocaleInfo.LocaleIDForQueries;
RuntimeDataSet.ParamByName('language_id').AsInteger := ModApplicationCommon.ApplicationLocaleInfo.LocaleIDForQueries;
end;
CDS.Data := PreloadDataSet.Data;
CDS.Active := true;
end;
begin
DisconnectFromDatabase;
dbcEShop.Connect;
UpdateStatusBar('Setting up products archive');
ConnectDataSet(cdsProduct, ModDBPreload.cdsProduct, qryProduct, true);
UpdateStatusBar('Setting up products options archive');
ConnectDataSet(cdsProductOption, ModDBPreload.cdsProductOption, qryProductOption);
UpdateStatusBar('Setting up options archive');
ConnectDataSet(cdsOption, ModDBPreload.cdsOption, qryOption);
UpdateStatusBar('Setting up options descriptions archive');
ConnectDataSet(cdsOptionDescription, ModDBPreload.cdsOptionDescription, qryOptionDescription, true);
...
I hope to have posted enough information to give out an idea about the whole process. Please feel free to ask any questions and sorry for the lexicon, English is my fourth language.

How to manage exceptions when using gtkada

When I'm using gtkada and my GUI is running, no exception is managed and the program always crashes. The message is
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
A test code is as follows:
with GLib; use GLib;
with Gtk.Label; use Gtk.Label;
with Gtk.Window; use Gtk.Window;
with Gtk.Frame; use Gtk.Frame;
with Gtk.Button; use Gtk.Button;
with Gtk.Widget; use Gtk.Widget;
with Gtk.Handlers;
with Gtk.Main;
procedure gui_test_4 is
Window : Gtk_Window;
Label : Gtk_Label;
Frame : Gtk_Frame;
Button_S : Gtk_Button;
General_Error : exception;
package Handlers is new Gtk.Handlers.Callback (Gtk_Widget_Record);
package Return_Handlers is
new Gtk.Handlers.Return_Callback (Gtk_Widget_Record, Boolean);
function Delete_Event (Widget : access Gtk_Widget_Record'Class)
return Boolean is
begin
return False;
end Delete_Event;
procedure Destroy (Widget : access Gtk_Widget_Record'Class) is
begin
Gtk.Main.Main_Quit;
end Destroy;
procedure Clicked (Widget : access Gtk_Widget_Record'Class) is
begin
raise General_Error;
exception
when General_Error =>
null;
end Clicked;
begin
Gtk.Main.Init;
Gtk.Window.Gtk_New (Window);
Set_Default_Size (Window, 200, 200);
Gtk.Window.Set_Title (Window, "GUI_Test_4");
Gtk_New (Frame);
Add (Window, Frame);
Gtk_New (Button_S, "Try");
Add (Frame, Button_S);
Return_Handlers.Connect
( Window,
"delete_event",
Return_Handlers.To_Marshaller (Delete_Event'Access)
);
Handlers.Connect
( Window,
"destroy",
Handlers.To_Marshaller (Destroy'Access)
);
Handlers.Connect
( Button_S,
"clicked",
Handlers.To_Marshaller (Clicked'Access)
);
Show_All (Window);
Show (Window);
Gtk.Main.Main;
end gui_test_4;
When the button is pressed, an exception is raised, but it should be managed in the same procedure, but instead of that, the complete program crashes.
Any idea how to solve this problem?
Thanks
Looks like a job for the debugger to me.
In the comments it was mentioned that others are able to successfully run and build this same code. That could mean that your version of GTKAda has issues. It could instead mean that there's a real bug in there, but how/if it expresses depends on what garbage values happened to be loaded into what memory areas when the program starts up.
You might start off by making sure you have the latest version of GTKAda. But after that, fire up the debugger and try to see where its crashing. Note that in Ada programs often crashes happen during package elaboration before the first line of code in your main even gets called. If you are using Gnat you can step through the elaboration process in GDB as well though. With other compilers, you may have to find some elaboration code to try to put breakpoints into to catch it early enough.

Tcl info exists

I have a curious case of Tcl that perhaps I just don't understand.
The following code is done at the top level (not inside of any procedure):
if {![info exists g_log_file_name]} {
set g_log_file_name "default.txt"
}
What I hope it would do is to declare a global variable with some value if it wasn't declared yet (which can be done at some other script or C application). However, the if statement always false. I ran on Tcl 7.4.
What may be the problem?
Thank you so much.
% info level
0
% info exists g_log_file_name
0
% set g_log_file_name whatever
whatever
% info exists g_log_file_name
1
Hence the reason you observe is probably because the variable is really always unset at the time your if command is executed.
Possible reasons for this I can imagine are:
It's just not set: literally, no code attempt to do this;
The external code sets some other variable: name mismatch;
The external code sets a variable in some other interpreter: in a C code embedding Tcl, there can be any number of Tcl interpreters active at any moment (and those are free to create child interpreters as well);
I'm not sure abot the long forgotten version of Tcl you have at hand, but 8.x has the trace command which can be used to log accesses to a particular variable—you could try to use it to see what happens.

IronPython Memory Leak When Calling Function With More Than 13 Parameters

I'm using IronPython 2.6.2 for .NET 4.0 as a scripting platform within a C#/WPF application. Scripts can include their own function definitions, class definitions, etc. I'm not restricting what can be written.
A memory leak appeared in the scripting piece recently after a script change. After commenting out more and more code, we determined that defining and calling a function with more than 13 parameters causes a memory leak. So if you call a function with 14 parameters IronPython will leak.
Here is some sample code on a timer running every 100ms:
_Timer.Enabled = false;
try
{
var engine = Python.CreateEngine();
engine.Execute("def SomeFunc(paramI, paramII, paramIII, paramIV, paramV, paramVI, paramVII, paramVIII, paramIX, paramX, paramXI, paramXII, paramXIII, paramXIV):\r\n\tpass\r\nSomeFunc(1,2,3,4,5,6,7,8,9,10,11,12,13,14)");
//engine.Execute("def SomeFunc(paramI, paramII, paramIII, paramIV, paramV, paramVI, paramVII, paramVIII, paramIX, paramX, paramXI, paramXII, paramXIII):\r\n\tpass\r\nSomeFunc(1,2,3,4,5,6,7,8,9,10,11,12,13)");
// With and without the following line makes no difference
engine.Runtime.Shutdown();
this.Dispatcher.Invoke((Action)delegate()
{
this.Title = DateTime.Now.ToString();
});
}
catch (Exception)
{
}
_Timer.Enabled = true;
Note that I have a 14-parameter version of the script and below it is a commented-out 13-parameter version. The Python script is basically this:
def SomeFunc(paramI, paramII, paramIII, paramIV, paramV, paramVI, paramVII, paramVIII, paramIX, paramX, paramXI, paramXII, paramXIII, paramXIV):
pass
SomeFunc(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
I've tried with and without engine.Runtime.Shutdown() but it makes no difference. The 14-parameter version's memory will climb rapidly and the 13-parameter version's memory will climb slightly and then stabilize.
Any thoughts?
Thanks
- Shaun
There's a magic number of parameters in IronPython - less than that is a different (faster) code path than more. It sounds like there are still some bugs in the fallback code. Can you please open an issue with a self-contained test case?
Looking at the latest code I would think the boundary would be at 15. Can you try again on 2.7 Beta 2 and see if the results are the same?