I'm working on small project in Pascal for school.
I'm using Lazaruz 1.0.2
I have problem with wirteLn function when writing to file.
After some time it just stops writing to file.
Take for example this program:
var oFile: Text;
i: LongWord;
begin
Assign(oFile, 'test.txt');
ReWrite(oFile);
for i:=1 to 4096 do
WriteLn(oFile, 'ThisIsTest');
CloseFile(oFile);//Added as suggested
end.
This is output:
...
4072 ThisIsTest
4073 ThisIsTest
4074 ThisIsTest
4075 ThisIsTe
As you can see it just stops at the middle of sentence and it is not writing all.
All depends on how long is one WriteLn insturction and how many times it is called.
How to fix it?
I tried to use WinApi function from "Windows" module called WriteFile but I failed to pass last 3 arguments to it.
BIG UPDATE
Thanks. That works (Closing file) in that example. But I have little bit more complex program where I'm passing opened file handle to functions that are writing to it via "var". And even after closing that file at the and does nothing. It is strange.
You should Close(oFile) at the end of your program to be sure the output is flushed.
It's also possible to update a file without closing it by adding (in this example)
Flush(oFile);
after a Writeln
This is useful where you might have a long file and want to make sure it's updated regularly. Of course, you should still close the file when finished.
Related
I'm using Virtual Pascal on Windows and have a weird problem whereby if an attempt to Reset() any file that doesn't exist causes the WriteLn() to CRT fail. Example:
{$I+}
program TestIt;
uses Printer; { attempts to open LPT1 as Lst but LPT1 doesn't exist on system }
begin
{ Generates a RunTime Error with $I+ and no output with $I- }
writeln('Test It');
end.
This also fails:
program TestIt;
var
SomeFile : text;
begin
{$I-}
Assign(SomeFile, 'a:\filepath_not_exist');
{ Without $I- the Reset generates a RunTime Error as expected }
Reset(SomeFile);
{$I+}
{ Generates a RunTime Error with $I+ and no output with $I- }
writeln('Test It');
end.
This works as expected:
{$I+}
program TestIt;
begin
writeln('Test It');
end.
Any ideas why this may be happening and how to fix it? Is the source available for WriteLn() or Assign() ? I'm able to change the Printer unit to not Reset() to work around it until needing to get printing working but I don't think failure to open a file should cause the screen output to stop working.
Probably the error state is kept in some variable (which is queried by ioresult) and might cause an error to be raised in the next I/O function. If you don't do automatic error checking ($I+) you must call ioresult after every operation.
Such implementation is not ideal (if errors from the opening using "somefile" spill into a writeln to a second(output) file as happens in the second example), but it happens, specially in older compilers, and specially on targets that are less dos-like.
Also, not existing drive errors are much harder to cache than non existing files. Keep those cases fundamentally apart.
You can test this theory by trying to reset state by querying ioresult just before the action in the hope it resets the state.
Afaik VP is dead for almost a decade now. What you see (read: download) is what you get.
As stated in previous questions, I'm quite new at Progress-4GL development.
I've just created a windows (*.w file), together with a procedure file (*.p file), which are based on an include file (*.i file).
I've done something wrong and I get an error message, copy-paste reveals the following:
---------------------------
Fout
---------------------------
** Begin positie voor SUBSTRING, OVERLAY, enz. moet 1 of groter zijn. (82)
---------------------------
OK
---------------------------
As you can see, this is the Dutch translation of error 82:
** Starting position for SUBSTRING, OVERLAY, etc. must be 1 or greater. (82)
The SUBSTRING, OVERLAY, etc, functions require that the start position (second argument) be greater than or equal to 1.
P
I'd like to know which procedure/function is launching this error message. I'm working with the AppBuilder release 11.6 and the corresponding procedure editor, so the debugging possibilities are very limited. One thing I'm thinking of, is taking a dump of the Windows process, in order to determine the call stack, but I'm not sure how to do this. I also tried using Process Explorer and check the stack of the individual stacks of the threads inside the "procwin32.exe" process, but I'm not sure how to proceed.
By the way, I'm regularly adding message boxes to my code, which look as follows (just an example):
MESSAGE "begin procedure combobox-value-changed" VIEW-AS ALERT-BOX.
As you see, the name of the procedure is hardcoded, while in other programming languages (like C++) the procedure/function name can be shown as follows:
OUTPUT("begin procedure %s", __FUNCTION__);
Next to __FUNCTION__, C++ also knows __FILE__ (for filename) and __LINE__ (for line number).
Do such predefined values also exist in Progress 4GL, preferably release 11.6 or previous?
As ABL code is not compiled into Windows byte-code a windows debugger will not be really helpful.
You should start by adding the -debugalert startup parameter to prowin/prowin32.exe. Or add this
ASSIGN SESSION:DEBUG-ALERT = TRUE .
That will add a HELP button to all (error) messages which will open a dialog with the ABL stack trace.
As you'Re using include files, be aware that the line numbers referenced in the stack-trace are based on the debug listing, not the actual source code. So execute
COMPILE myfile.w DEBUG-LIST c:\temp\myfile.debuglist .
to receive the debug-listing file with the correct line numbers.
Are you aware of the visual debugger that's available for the AVM? https://docs.progress.com/de-DE/bundle/openedge-abl-troubleshoot-applications-117/page/Introduction.html
%DLC%\bin\proDebugger.bat
Or the Compile -> Debug menu in the AppBuilder.
It looks a bit antique, but usually does it's job.
Debugging needs to be enabled as an Administrator in proenv:
prodebugenable -enable-all
Of course the grass is greener when you switch to Progress Developer Studio as your IDE.
Regarding the second part of your question. See the PROGRAM-NAME function.
message
program-name(1) skip
program-name(2)
.
Additionally see the {} preprocessor name reference.
message 'file: {&file-name} line: {&line-number}'.
Look at the following four programs. Build them with Freepascal under Windows and run, redirecting output to any file, and noticing the time it would take.
My results are: all the programs run approximately the same time (about 6 seconds), although the fourth does 100 times more bytes of output. This means that the fourth program runs much faster per byte of output than the tree others.
For the second program the reason of slowness is obvious: the flush call. For the third program the reason is not so obvious, but it may be reasonable to assume that each call to writeln to stdout flushes the output buffer implicitly.
However, it is not clear why the first program is so slower than the fourth. However, the fact that adding flush(output); (see program 2) does not change the timing much seems to mean that FPC flushes the output buffer even after every write, this would explain all the behaviour. This happens only when output is to stdout, even redirected; if I explicitly output to a particular file using assign/rewrite, then the program without flush runs much faster than the program with flush — as should be expected.
Under Linux the running times are 0.01s, 0.65s, 0.01s, 0.30s (output being 100 times bigger). Here clearly flush() slows program down, so under Linux FPC seems not to flush stdout each time.
I have tried to google whether FPC really flushes stdout buffer on every output (be it write or writeln), but have found no information except the comment in the example program from flush function documentation at http://www.freepascal.org/docs-html/rtl/system/flush.html, the comment mentions that a writeln to 'output' always causes a flush [as opposed to write]. However, the example there does not produce the intended output neither under Windows, neither under Linux. In fact, the output seems to be flushed after every write and writeln under Windows, redirected or not, and under Linux too when the output is not redirected. Under Linux with redirected output it seems there is no implicit flushing at all.
So, my questions are:
Is it true that FPC flushes the output buffer after every output, be it write or writeln, on Windows whether the output is redirected to file or not?
If yes, then is there any way to turn this off (some compiler directive, or a workaround)? I still need to keep the output to stdout, so that if I start the program without any redirections, it will output text to the console. (I understand that I might see it appearing at strange times as a result of buffering, it is not a problem.)
If no, then why the first program runs much slower then the fourth?
My system is Windows XP with FPC 2.6.4 under VirtualBox under Kubuntu 14.04, and Kubuntu 14.04 itself with FPC 2.6.2. I had no chance trying to run it on a real Windows machine, but I have some reasons to believe that the situation is the same there.
The programs:
var i,j:integer;
s:string;
begin
for j:=1 to 1000 do begin
for i:=1 to 10 do
write('!');
end;
end.
var i,j:integer;
s:string;
begin
for j:=1 to 1000 do begin
for i:=1 to 10 do begin
write('!');
flush(output);
end;
end;
end.
var i,j:integer;
s:string;
begin
for j:=1 to 1000 do begin
for i:=1 to 10 do
writeln('!');
end;
end.
var i,j:integer;
s:string;
begin
for j:=1 to 10000 do begin
s:='';
for i:=1 to 100 do
s:=s+'!';
write(s);
end;
end.
To prevent flushing of Stdout, insert the following code snippets into your program:
// Textrec is defined in sysutils
uses
sysutils;
// ...
// disabled flushing after each write(ln) on Output, do this at the start of the program
Textrec(Output).FlushFunc:=nil;
But be aware that this means that writelns might not be completed before the program ends.
You can even accelerate the program further by increasing the output buffer of stdout:
// define buffer
var
buf : array[1..100000] of byte;
// ...
// install buffer, do this at the start of the program
SetTextBuf(Output,buf,sizeof(buf));
I've been doing some research, but I only find more and more ways to do what I want and I don't understand any of them.
What code do I need to assemble into an .exe to return 5 to the command line?
I want an exe that, when called, prints 5 .
Research:
printf "5", 0
It requires to link with 2 libraries, and I want to keep it simple.
move ebx, 5 ; or move ax, 5
ret
Why would this print 5 ? This loads a register whith a value 5 and returns. Nothing else.
Could someone explain me the difference between those ways of returning 5?
What would be most appropiate for a very simple Windows EXE executable?
I couldn't get the answers in the questions already asked in StackOverflow.
NOTE, I use: Win 7, WinAsam, MASM
THANKS!
Why not use printf? On windows, it is part of the MS C Runtime that is part of windows now.
Using the Windows API, you would use:
GetStdHandle
And one of the following:
WriteConsole
WriteConsoleOutput
WriteConsoleOutputAttribute
WriteConsoleOutputCharacter
WriteFile
All depends on how you want to do it.
moving something into a register does not print anything, you have to tell the OS to print it.
If you find something that you don't understand, do some research on it, read the documentation, code comments, play around with the code changing things and see how it works.
Running matlab R2010B on Windows 7 Enterprise
In matlab scripts, I save a bunch of results to a word file and then at the end, close and quit word. The code I use is:
WordFname = ['BatInfoDoc' sprintf('%0.3f',now) '.doc']; % serialnumbered filenames
WordFile = fullfile(pwd,WordFname);
WordApp = actxserver('Word.Application');
WordDoc = WordApp.Documents.Add;
WordDoc.SaveAs2(WordFile);
....
WordApp.Selection.TypeText([title2 title3 title4 title5 title6]);
WordApp.Selection.TypeParagraph;
then finally at the end of the script
WordDoc.Close;
WordApp.Quit;
The problem I have is that through my development process, I often crash the matlab script and wind up leaving orphaned WINWORD.EXE processes, each one of which keeps a lock on the file it had been writing.
Up until now I have been using TaskManager to kill these processes one at a time by hand. Having been developing all morning, I find myself with around 20 files I can't delete because they are locked by about 11 orphaned WINWORD.EXE processes!
My question(s):
1) Is there an elegant way to handle the file writing and saving and closing and so on so I don't lock up files and processes when my script crashes out before I get to the part where I close the file and quit word?
2) Is there an elegant way to determine the bad processes from within matlab script and go through and delete them from within a matlab script? That is, can I code my matlab so it cleans up after itself?
ADDED A FEW MINUTES LATER:
By the way, I would prefer NOT to enclose all my code in a big try-catch and then close the windows after I've caught my error. The problem with this is I do like to go to debug mode on error, and caught errors don't bring me to debug mode.
Straight after you create Wordapp, use c = onCleanup(#()Wordapp.Quit). When your function exits, either naturally or with a crash, c will be deleted and its function will execute, quitting Word. If this is part of a script rather than a function, you can manually delete c to quit.
Also - while developing/debugging, I would set Wordapp.Visible to true so you can manually close word if necessary. Set back to false for production.
Use a handle class to delete them automatically.
classdef SafeWord < handle
properties(Access=public)
WordApp;
end
methods(Access=public)
function this = SafeWord(WordApp)
this.WordApp= WordApp;
end
function delete(this)
this.WordDoc.Close;
this.WordApp.Quit;
end
end
end
And the use case:
sw = SafeWord(Word.Application());
WordApplication = sw.WordApp;
% Do something here
% When sw ends its lifecycle, it calls delete.
Here is a related question.