Possibility to create extended codeblocks (ie including control structures such as: if, do while,...) with marco (&) operator

370 views
Skip to first unread message

Diego Risi

unread,
May 31, 2014, 6:55:25 AM5/31/14
to harbou...@googlegroups.com
Hello,
I'm not an Harbour developer but I found several users, including myself, that would be interested in the possibility of create extended codeblocks (ie including control structures such as: if, do while,...) with marco (&) operator.
An extended codeblock looks like the following:  
local cBlock := {||
           if .t.
              qout("test OK")
           endif
          }

If you try to build at runtime this codeblock with the following statement:
local cBlock := &('{ || if .t.'+chr(13)+chr(10)+'  qout("test OK")'+chr(13)+chr(10)+'endif }')
you get the error:
"Error BASE/1449  Syntax error: &"

As the ability to dynamically define codeblock is undoubtedly one of the historic strengths of Clipper (and therefore of Harbour), it would be desirable to the extent of the potential of macro operator "&" in order to create extended codeblocks from strings.
Thank you for your attention.
Diego Risi

Diego Risi

unread,
Jun 1, 2014, 3:30:24 PM6/1/14
to harbou...@googlegroups.com
not having seen the immediate publication of this post, I've added another one, so I kindly ask the forum administrator to delete this post and I ask users to answer (eventually) just on the other.
Diego Risi

Klas Engwall

unread,
Jun 1, 2014, 4:04:49 PM6/1/14
to harbou...@googlegroups.com
Hi Diego,

> not having seen the immediate publication of this post, I've added
> another one, so I kindly ask the forum administrator to delete this post
> and I ask users to answer (eventually) just on the other.

Around 50% of all members and probably 100% of your intended audience
receive the forum messages via email, so removing messages in the web
interface makes very little difference other than adding to the confusion.

Regards,
Klas

Alejandro Padrino

unread,
Jun 1, 2014, 9:35:35 PM6/1/14
to harbou...@googlegroups.com
hello diego,

first of all, i love xbase macros.  you can make all you want with it within xbase languaje rules.  but some things of your code samples is wrong.  you can not use macro operator through a local variable.  you can use macro operator only in private and public variable statements.  you can not use macro operator to literal strings.  try to put literal strings into a string variable and call that variable with macro operator.  if source code within string variable is right with xbase rules, you can execute that string.  for this there are some limited features to declare new memory variables and some other things (and you can avoid some of these things).  all this is valid for clipper and harbour.  regards.  :-)

Alexander S.Kresin

unread,
Jun 3, 2014, 3:38:43 AM6/3/14
to harbou...@googlegroups.com
Diego Risi writes:
>
> If you try to build at runtime this codeblock with the following statement:
> local cBlock := &('{ || if .t.'+chr(13)+chr(10)+' qout("test
> OK")'+chr(13)+chr(10)+'endif }')
> you get the error:
> "Error BASE/1449 Syntax error: &"
>
> As the ability to dynamically define codeblock is undoubtedly one of the
> historic strengths of Clipper (and therefore of Harbour), it would be
> desirable to the extent of the potential of macro operator "&" in order
> to create extended codeblocks from strings.

The same functionality can be realized, using the hb_compile...() and
hb_hrbRun() functions:

REQUEST QOUT
FUNCTION Main
Local cBuf, buf
cBuf := 'Function A1'+chr(13)+chr(10)+'if .t.'+chr(13)+chr(10)+'
qout("test > OK")'+chr(13)+chr(10)+'endif'+chr(13)+chr(10)+'Return'
buf := hb_compileFromBuf( cBuf, "harbour", "/n" )
hb_hrbRun( buf )

RETURN nil


A bit more info is available here:
http://www.kresin.ru/en/hrbfaq_3.html#Doc6

Regards, Alexander.

Klas Engwall

unread,
Jun 3, 2014, 6:58:50 PM6/3/14
to harbou...@googlegroups.com
Hi Alexander,

> The same functionality can be realized, using the hb_compile...() and
> hb_hrbRun() functions:
>
> REQUEST QOUT
> FUNCTION Main
> Local cBuf, buf
> cBuf := 'Function A1'+chr(13)+chr(10)+'if .t.'+chr(13)+chr(10)+'
> qout("test > OK")'+chr(13)+chr(10)+'endif'+chr(13)+chr(10)+'Return'
> buf := hb_compileFromBuf( cBuf, "harbour", "/n" )
> hb_hrbRun( buf )
> RETURN nil

Based on previous messages here and on Viktor's comments in hbmk2.prg I
thought that hb_CompileFromBuf() was restricted to use with the GPL
license only, but apparently that is only true if the source code is
read from a .prg file and compiled at runtime. So building the source
code at runtime and then compiling it with hb_CompileFromBuf() is OK for
closed source applications, right?

Regards,
Klas

Przemyslaw Czerpak

unread,
Jun 3, 2014, 9:07:07 PM6/3/14
to harbou...@googlegroups.com
On Wed, 04 Jun 2014, Klas Engwall wrote:

Hi,
No it isn't. Just to clarify:
Most of Harbour source code is published on GPL + Harbour exception
license with exception to these files:

cmdcheck.c
genc.c
genhrb.c
harbour.y -> { harbour.yyc, harbour.yyh }
hbfunchk.c
hbgenerr.c
hbident.c
hbmain.c
hbpcode.c
hbusage.c

Above files uses only pure GPL license and are part of Harbour
compiler binaries and Harbour compiler library.

Few years ago I rewrote significant part of Harbour compiler code
so now it's possible to use Harbour as embedded compilefr in other
applications, i.e. HBMK2. A lot of new code I published on GPL +
Harbour extension license (in fact all new files I started from
scratch). Anyhow the significant part of my work are inside above
files and I kept original author license though quite often I was
adding new functions or rewriting existing ones in from scratch.
I asked on this forum other authors for public declaration that
they agree to change the license. In practice without any effect.
As result we have to accept that above code is pure GPL code and
all hb_compile*() functions uses internally above files. It means
that they have to respect the GPL license. Unlike many people thinks
GPL does not mean that you have to public your code on open source
license. It only means that anyone using program with GPL code
may ask its author to give him the rest of code used in application
and he will have rights to publish it on GPL license. Application
authors are not slaves of GPL license so it does not mean that they
have to make it for ever and always for free. They can ask for
reasonable gratification for delivering source code just to cover
the cost of people and medias necessary to realize such job.
I hope that it's clear. If not then read details in GPL text.

Long time ago the status of compiler files was disused on Harbour
forum and significant authors agreed that missing Harbour exception
in license of core compiler files will protect Harbour community
against people who can add few minor extensions dedicated for some
chosen goals, i.e. port for new platform and begin to sell Harbour
fork as new commercial project ignoring GPL license. Now after over
ten years and few rather unpleasing incidences personally I think
that the final effect is far from the initial goal so I have in plans
to rewrite above files (at least the code which is not mine) on new
license: GPL + Harbour extension.
Anyhow now anyone using Harbour compiler library or distributing
binary version of Harbour compiler has to fully respect GPL license
in his final products and deliver all his source files used to create
final project for their users or customers requests on conditions
described in GPL license.

best regards,
Przemek

Alejandro Padrino

unread,
Jun 3, 2014, 9:35:07 PM6/3/14
to harbou...@googlegroups.com
Diego and Klas,

functions can't be created at runtime.  Some commands (if, for example) can be emulated at runtime only in the part of conditional statement.  But not all commands can be called from macro operator.  Some commands need to build own structure from a function (public).  You can call a function from macro operator.

vszakats

unread,
Jun 4, 2014, 5:43:00 AM6/4/14
to harbou...@googlegroups.com
> REQUEST QOUT 
> FUNCTION Main
> Local cBuf, buf
> cBuf := 'Function A1'+chr(13)+chr(10)+'if .t.'+chr(13)+chr(10)+'
> qout("test > OK")'+chr(13)+chr(10)+'endif'+chr(13)+chr(10)+'Return'
> buf := hb_compileFromBuf( cBuf, "harbour", "/n" )
> hb_hrbRun( buf )
> RETURN nil

Based on previous messages here and on Viktor's comments in hbmk2.prg I
thought that hb_CompileFromBuf() was restricted to use with the GPL
license only, but apparently that is only true if the source code is
read from a .prg file and compiled at runtime. So building the source

Sorry, this isn't so. Calling the function is only allowed from GPL-ed 
code, wherever the bytes are coming from, which are passed to it as 
parameters.

This is true for all of these functions:
hb_compile()
hb_compileBuf()
hb_compileFromBuff()

--Viktor

Klas Engwall

unread,
Jun 4, 2014, 3:53:57 PM6/4/14
to harbou...@googlegroups.com
Hi Przemek,

Thanks for the in-depth explanation, including the summary of the "old
politics", which is nowadays hard to find.

Regards,
Klas

Diego Risi

unread,
Jun 7, 2014, 3:09:23 PM6/7/14
to harbou...@googlegroups.com
Hi Alexander,

thank you for the suggestion to use the "hb_compileFromBuf", but it does not have the same execution speed of compilation with macro "&".
I am also pleased that my argument has allowed to investigate issues related to the GPL license.
Regards,
Diego

Diego Risi

unread,
Aug 21, 2014, 1:39:50 PM8/21/14
to harbou...@googlegroups.com
Hello,
I created myself a function (see attached file) that achieves the purpose of this post.


Il giorno sabato 31 maggio 2014 12:55:25 UTC+2, Diego Risi ha scritto:
The function takes as input an array whose elements correspond to a program with control structures IF-THEN-ELSE and produces as output a string that can be compiled with the macro operator (&). 
On the basis of my function I hope that the developers evaluate to incorporate in Harbour this feature (suitably modified, and if necessary expanded to handle the other control structures: FOR, DO WHILE, DO CASE), which, from what I have seen, seems to be very useful.
The attached program can be compiled and provides a simple test of the above function. 
I remain confident in waiting for a response from Harbour developers, whose work I very much appreciate.
Regards.
Diego
buildStr4macro.prg
Reply all
Reply to author
Forward
0 new messages