SAVESCREEN() and RESTSCREEN don't work (Harbour 3.0)

495 views
Skip to first unread message

Chris Gonnerman

unread,
Aug 24, 2011, 8:48:11 AM8/24/11
to harbou...@googlegroups.com
I have a substantial codebase in FlagShip which I'm transferring to Harbour, and it makes extensive use of the SAVESCREEN() and RESTSCREEN() functions.  The problem is, in Harbour 3.0, they do nothing.  Restoring a screen that I've saved makes no visible change at all.

Here's a sample which I've just tested:
procedure main

clear

@ 5,10 say "You should see this."

scrn = savescreen()

@ 6,10 say "You should NOT see this"

restscreen(scrn)

dummy = " "
@ 7,10 get dummy
read
I built it on my Ubuntu Maverick Linux 64 bit system, using a built-from-source Harbour 3.0.0 install, with these commands:

    harbour test.prg
    gcc -I/usr/local/include/harbour -L/usr/local/lib/harbour -lharbour -o tester test.c


If you replace the savescreen() and restscreen() functions with save screen and restore screen statements, it works fine.  However, my existing codebase makes use of the functions to allow utility features to save and restore screens, AND to allow external programs that mess up the screen to be used.  As a result, I can't depend on the single internal buffer that the statements use.

Anyone know what's wrong here?  The function definitions in the source are brief, but cryptic.

-- Chris.

Chris Gonnerman

unread,
Aug 24, 2011, 10:41:39 AM8/24/11
to harbou...@googlegroups.com
Okay, I'm replying to my own post.  I admit, I don't understand the Harbour C source; the macros that set up functions are strange, and I don't understand what's going on in valtype.c at all.  However... instrumenting the code to see where it goes wrong, well, that's EASY.  I added #include <stdio.h> to saverest.c, then amended the RESTSCREEN function like this:

HB_FUNC( RESTSCREEN )
{
   if( HB_ISCHAR( 5 ) )
   {
      int iTop, iLeft, iBottom, iRight;
      HB_BOOL fNoCheck = HB_FALSE;

      hb_getScreenRange( &iTop, &iBottom, fNoCheck, HB_TRUE );
      hb_getScreenRange( &iLeft, &iRight, fNoCheck, HB_FALSE );

      hb_gtRest( iTop, iLeft, iBottom, iRight, hb_parc( 5 ) );
   } else {
        FILE *fp;
        fp = fopen("egad.txt","w");
        fprintf(fp, "nope\n");
        fclose(fp);
   }
}
Yes, when I run the rebuilt test.prg with this modified code, egad.txt does indeed get created and filled with the word "nope."  SO... whatever it is that HB_ISCHAR(5) does, it's coming back FALSE and the function is a no-op.  It raises no error indication otherwise.

HB_ISCHAR looks like this:
HB_FUNC( HB_ISCHAR )
{
   hb_retl( ( hb_parinfo( 1 ) & ( HB_IT_MEMO | HB_IT_STRING ) ) == HB_IT_STRING );
}
Working with context clues, it appears that the value 5 in the call in RESTSCREEN is being treated as a binary value (see the bitwise and &) which is binary 101.  Assuming I'm not misunderstanding what hb_parinfo(1) does... I'm assuming it's extracting the value of the first parameter, which is 5.  Possibly I have that wrong.

It's anded with HB_IT_MEMO | HB_IT_STRING.  Here's the relevant bits from hbapi.h:
#define HB_IT_STRING    ( ( HB_TYPE ) 0x00400 )
#define HB_IT_MEMOFLAG  ( ( HB_TYPE ) 0x00800 )
#define HB_IT_MEMO      ( HB_IT_MEMOFLAG | HB_IT_STRING )
Now, this is nuts.  HB_IT_MEMO is defined in terms of HB_IT_STRING, so the code in HB_ISCHAR is a bit odd... HB_IT_MEMO | HB_IT_STRING is exactly the same as HB_IT_MEMO, and after bitwise anding it with the result of hb_parinfo(1), we check to see if it is exactly equal to HB_IT_STRING.  If for some reason the result of hb_parinfo(1) were equal to HB_IT_MEMO, then the result of this comparison to HB_IT_STRING would be FALSE.  So why bother with HB_IT_MEMO at all?

I'm beginning to think this is something for the developers.  It's giving me a headache.

-- Chris.


Viktor Szakáts

unread,
Aug 24, 2011, 10:45:57 AM8/24/11
to harbou...@googlegroups.com
Hi,

Harbour is aimed to be compatible with Clipper 5, so where FlagShip 
is not Clipper compatible, Harbour isn't as well. This is expecially true 
for "dirty" (parameter or behavior) extensions like this particular case.


Modify your code to be Clipper compatible, or it's also possible to 
extend hbfship contrib lib with modified versions of RESTSCREEN()/SAVESCREEN() 
under names FS_RESTSCREEN()/FS_SAVESCREEN().

Viktor

Chris Gonnerman

unread,
Aug 24, 2011, 10:57:39 AM8/24/11
to harbou...@googlegroups.com
AHA. So. If the SAVESCREEN() and RESTSCREEN() functions were in the
documentation (I couldn't find them on the Harbour website), I'd have
instantly seen the problem.

I don't have Clipper documentation available, just the docs on the
Harbour website and my copy of the FlagShip manual. As you can see, I
got a ways into the source code... I'm sure I'd have figured it out
eventually.

Thanks!

-- Chris.

Andrzej P. Wozniak

unread,
Aug 24, 2011, 11:53:01 AM8/24/11
to harbou...@googlegroups.com
From: Viktor Szakáts <harbo...@syenar.hu>

> http://www.ousob.com/ng/sum87/ng26423.php
^^^^^
It's a link to Clipper Summer'87 NG.
It should be http://www.ousob.com/ng/clguide/ng5fc0d.php and here we
can see:
/----
If you specify no coordinates, the entire screen (i.e., from 0,0 to
MAXROW(), MAXCOL()) is saved.
\----
For restscreen we have got http://www.ousob.com/ng/clguide/ng5ce37.php
and:
/----
If the
<cScreen> was saved without coordinates to preserve the entire screen,
no screen coordinates are necessary with RESTSCREEN().
\----

That way screen coordinates in Clipper 5.x are optional so this code:

scrn := savescreen()
restscreen(scrn)

should be valid and give the same results for both Flagship and Clipper
5.x, I think. Am I wrong?

--
Regards from The Harbour Project mirror in Poland
Andrzej P. Woźniak

------

Hosting klatka.pl 4GB za jedyne 40 zl za rok i domena gratis


Massimo Belgrano

unread,
Aug 24, 2011, 12:15:59 PM8/24/11
to harbou...@googlegroups.com
i suggest buy the documentaion


2011/8/24 Chris Gonnerman <ch...@gonnerman.org>


--
You received this message because you are subscribed to the Google
Groups "Harbour Users" group.
Unsubscribe: harbour-users+unsubscribe@googlegroups.com
Web: http://groups.google.com/group/harbour-users



--
Massimo Belgrano

Przemysław Czerpak

unread,
Aug 24, 2011, 11:13:17 AM8/24/11
to harbou...@googlegroups.com
On Wed, 24 Aug 2011, Chris Gonnerman wrote:

Hi,

> AHA. So. If the SAVESCREEN() and RESTSCREEN() functions were in
> the documentation (I couldn't find them on the Harbour website), I'd
> have instantly seen the problem.
> I don't have Clipper documentation available, just the docs on the
> Harbour website and my copy of the FlagShip manual. As you can see,
> I got a ways into the source code... I'm sure I'd have figured it
> out eventually.

FSMAN is all what you need in such case.

From FlagShip manual:
Syntax 1:
NIL = RESTSCREEN ([expN1], [expN2], [expN3], [expN4], varS5)
Syntax 2:
NIL = RESTSCREEN (varS5)
[...]
Compatibility:
[...]
Syntax 2 is not supported by C5.

So it's documented in FSMAN that this syntax is local FlagShip extension.
Unlike some unintentional incompatibilities in FS, extensions like above
are usually well documented. Always check compatibility section.

best regards,
Przemek

Chris Gonnerman

unread,
Aug 24, 2011, 9:15:56 PM8/24/11
to harbou...@googlegroups.com
On 08/24/2011 10:53 AM, Andrzej P. Wozniak wrote:
> It should be http://www.ousob.com/ng/clguide/ng5fc0d.php and here we
> can see:
> /----
> If you specify no coordinates, the entire screen (i.e., from 0,0 to
> MAXROW(), MAXCOL()) is saved.
> \----
> For restscreen we have got http://www.ousob.com/ng/clguide/ng5ce37.php
> and:
> /----
> If the
> <cScreen> was saved without coordinates to preserve the entire screen,
> no screen coordinates are necessary with RESTSCREEN().
> \----
>
> That way screen coordinates in Clipper 5.x are optional so this code:
>
> scrn := savescreen()
> restscreen(scrn)
>
> should be valid and give the same results for both Flagship and Clipper
> 5.x, I think. Am I wrong?
AHA, again. So given this information, Harbour *isn't* as Clipper 5
compatible as FlagShip, at least in this tiny area.

Or in other words, I wasn't actually wrong to expect that to work.

Changing the RTL source should be easy enough, now that I see how it is
supposed to work... or I can just go with the coordinates throughout my
codebase. Hmm. Easier to fix the RTL. Who do I submit patches to?

-- Chris.

Chris Gonnerman

unread,
Aug 24, 2011, 9:18:22 PM8/24/11
to harbou...@googlegroups.com
On 08/24/2011 10:53 AM, Andrzej P. Wozniak wrote:
> It should be http://www.ousob.com/ng/clguide/ng5fc0d.php and here we
> can see:
>
> ... hack hack hack ...

>
> should be valid and give the same results for both Flagship and Clipper
> 5.x, I think. Am I wrong?
Hmm... or did this functionality change between Clipper 5.0 and the 5.2
version those docs are for?

Dunno. Never really did "real" Clipper 5; went from Summer '87 to
Quicksilver to FlagShip. I'm all messed up.

-- Chris.


Viktor Szakáts

unread,
Aug 25, 2011, 4:51:25 AM8/25/11
to harbou...@googlegroups.com
> > should be valid and give the same results for both Flagship and Clipper
> > 5.x, I think. Am I wrong?
> AHA, again. So given this information, Harbour *isn't* as Clipper 5
> compatible as FlagShip, at least in this tiny area.

No. FlagShip has quite a few differences compared to Clipper/Harbour, 
one of them is they require the parameters, while in FlagShip they are 
optional. The return value is also different, plus FlagShip has an extra 
5th parameter. So, basically only the name is the same.

This is clearly written under posted documentation links.

> Or in other words, I wasn't actually wrong to expect that to work.
>
> Changing the RTL source should be easy enough, now that I see how it is
> supposed to work... or I can just go with the coordinates throughout my
> codebase. Hmm. Easier to fix the RTL. Who do I submit patches to?

There is nothing to patch or fix in core RTL. As I wrote, if any, it should 
be implemented as replacement functions in hbfship contrib lib, under 
mentioned names. Or modify your code to be Clipper compatible, 
or use something available in Clipper, f.e. SAVE SCREEN command.

Viktor

Massimo Belgrano

unread,
Aug 25, 2011, 5:15:32 AM8/25/11
to harbou...@googlegroups.com
IMO The way of flagship of adding a parameter to existing clipper function is bad
when you port your source from fship to anoter xbase compiler (harbour,xharbour,xbase) the patamerer added is very difficult to found
another compiler will have a parameter addedd for different function
similar situation for 5rd HB_AEVAL or 3rd AINS parameter

Harbour typically choice is not adding parameter to original clipper 5 function

2011/8/25 Viktor Szakáts <harbo...@syenar.hu>
> --
> You received this message because you are subscribed to the Google
> Groups "Harbour Users" group.
> Unsubscribe: harbour-user...@googlegroups.com

Massimo Belgrano

unread,
Aug 25, 2011, 5:20:53 AM8/25/11
to harbou...@googlegroups.com
A complete Clipper reference can be found at the following address:

http://www.itlnet.net/programming/program/Reference/c53g01c/menu.html

Viktor Szakáts

unread,
Aug 25, 2011, 5:23:43 AM8/25/11
to harbou...@googlegroups.com
> IMO The way of flagship of adding a parameter to existing clipper function is bad
> when you port your source from fship to anoter xbase compiler (harbour,xharbour,xbase) the patamerer added is very difficult to found
> another compiler will have a parameter addedd for different function
> similar situation for 5rd HB_AEVAL or 3rd AINS parameter

> Harbour typically choice is not adding parameter to original clipper 5 function

Exactly. It's classic "dirty" extension we avoid in Harbour by any means.

Anyhow it can implemented, with the mentioned, isolated method developed 
for such cases.

Viktor

Viktor Szakáts

unread,
Aug 25, 2011, 5:33:13 AM8/25/11
to harbou...@googlegroups.com
> Hmm... or did this functionality change between Clipper 5.0 and the 5.2 
version those docs are for?

Easy to check:

Apparently the problem is not the coordinates, which 
are optional also in C5 and Harbour.

The problem is that FlagShip extended RESTSCREEN() 
to accept the buffer as first parameter, while in Harbour/Clipper 
in must be 5th.

So this should work in Clipper/Harbour:
    RESTSCREEN( ,,,, scrn )

The rest of what I wrote stays true, FS_RESTSCREEN() 
could be implemented which would accept FS compatible 
parameter/behavior extensions.

Viktor

Przemysław Czerpak

unread,
Aug 25, 2011, 5:26:48 AM8/25/11
to harbou...@googlegroups.com
On Wed, 24 Aug 2011, Andrzej P. Wozniak wrote:
> From: Viktor Szakáts <harbo...@syenar.hu>
> > http://www.ousob.com/ng/sum87/ng26423.php
> ^^^^^
> It's a link to Clipper Summer'87 NG.
> It should be http://www.ousob.com/ng/clguide/ng5fc0d.php and here we
> can see:
> /----
> If you specify no coordinates, the entire screen (i.e., from 0,0 to
> MAXROW(), MAXCOL()) is saved.
> \----
> For restscreen we have got http://www.ousob.com/ng/clguide/ng5ce37.php
> and:
> /----
> If the
> <cScreen> was saved without coordinates to preserve the entire screen,
> no screen coordinates are necessary with RESTSCREEN().
> \----
>
> That way screen coordinates in Clipper 5.x are optional so this code:
>
> scrn := savescreen()
> restscreen(scrn)
>
> should be valid and give the same results for both Flagship and Clipper
> 5.x, I think. Am I wrong?

Yes you are. Read above documentation again where all is correctly
explained:
RESTSCREEN( [<nTop>], [<nLeft>],
[<nBottom>], [<nRight>], <cScreen> ) -> NIL

You may omit coordinates in RESTSCREEN() function but you have
to put screen buffer in the 5-th parameter.
so restscreen(scrn) was never supported by any clipper, clip, xbase++,
[x]Harbour versions and only restscreen(,,,,scrn) works.
restscreen(scrn) is local FlagShip extension and it is documented in
FlagShip documentations (FSMAN).

best regards,
Przemek

Chris Gonnerman

unread,
Aug 25, 2011, 8:27:53 AM8/25/11
to harbou...@googlegroups.com
On 08/25/2011 04:33 AM, Viktor Szakáts wrote:
> Hmm... or did this functionality change between Clipper 5.0 and the 5.2 
version those docs are for?

Easy to check:
See, here's a lot of my problem... using a simple Google search, I do find that site, but I didn't realize they had such comprehensive documentation; the page title that comes up starts "ClipX - Blinker 5.10..." and so I passed over it.  I wouldn't have caused so much trouble had I been able to find decent docs.

The problem is that FlagShip extended RESTSCREEN() 
to accept the buffer as first parameter, while in Harbour/Clipper 
in must be 5th.
And here is what I misunderstood.  I didn't get that the syntax defined on the documentation page made the parameters optional, but the commas mandatory.  Hey, it's been years since I did much xBase programming, and as I've noted, I jumped around a lot.  In fact, the last xBase I spent any time working in was FoxPro, and you know THAT had to mess me up.
The rest of what I wrote stays true, FS_RESTSCREEN() 
could be implemented which would accept FS compatible 
parameter/behavior extensions.
Nah.  If I have to globally replace it in the source files, I might as well globally replace it with valid Clipper/Harbour code.

Thanks, and sorry for the confusion.

-- Chris.


Reply all
Reply to author
Forward
0 new messages