/*
* $Id: class_tp.txt 4098 2001-06-18 18:41:11Z dholm $
*/
/* NOTE: - Please use these template for your new files, replace parts
between curly braces {} with the appropriate text.
- You can find a history at the end of the file. */
FILE HEADER TEMPLATE
====================
/*
* Harbour Project source code:
* {one-liner description about the purpose of this source file}
*
* Copyright 2000 {list of individual authors and e-mail addresses}
* www - http://www.harbour-project.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
*
* As a special exception, the Harbour Project gives permission for
* additional uses of the text contained in its release of Harbour.
*
* The exception is that, if you link the Harbour libraries with other
* files to produce an executable, this does not by itself cause the
* resulting executable to be covered by the GNU General Public License.
* Your use of that executable is in no way restricted on account of
* linking the Harbour library code into it.
*
* This exception does not however invalidate any other reasons why
* the executable file might be covered by the GNU General Public License.
*
* This exception applies only to the code released by the Harbour
* Project under the name Harbour. If you copy code from other
* Harbour Project or Free Software Foundation releases into a copy of
* Harbour, as the General Public License permits, the exception does
* not apply to the code that you add in this way. To avoid misleading
* anyone as to the status of such modified files, you must delete
* this exception notice from them.
*
* If you write modifications of your own for Harbour, it is your choice
* whether to permit this exception to apply to your modifications.
* If you do not wish that, delete this exception notice.
*
*/
FILE HEADER TEMPLATE (OPTIONAL ADDITION FOR PARTIAL COPYRIGHTS)
===============================================================
/*
* The following parts are Copyright of the individual authors.
* www - http://www.harbour-project.org
*
* Copyright 2000 {name} <{e-mail address}>
* {function or subsystem name}
*
* See doc/license.txt for licensing terms.
*
*/
CLASS HEADER TEMPLATE
========================
/* $CLASSDOC$
* $FUNCNAME$
*
* $CATEGORY$
*
* $ONELINER$
*
* $CONSTRUCTOR$
*
* $ARGUMENTS$
*
* $RETURNS$
*
* $DESCRIPTION$
*
* $DATALINK$
*
* $DATANOLINK$
*
* $METHODSLINK$
*
* $METHODSNOLINK$
*
* $EXAMPLES$
*
* $TESTS$
*
* $STATUS$
*
* $COMPLIANCE$
*
* $PLATFORMS$
*
* $FILES$
*
* $SEEALSO$
*
* $END$
*/
/* $CLASSDOC$
* $METHOD$
*
* $CATEGORY$
*
* $ONELINER$
*
* $SYNTAX$
*
* $ARGUMENTS$
*
* $RETURNS$
*
* $DESCRIPTION$
*
* $END$
*/
/* $CLASSDOC$
* $DATA$
*
* $CATEGORY$
*
* $ONELINER$
*
* $DESCRIPTION$
*
* $END$
*/
c:\harbour\doc\cmdline.txt
/*
* $Id: cmdline.txt 9243 2008-08-25 21:36:00Z vszakats $
*/
Harbour switch handling spec
============================
This spec goes for CLIPPERCMD, HARBOURCMD, Harbour
compiler and #pragma directives in the source code.
The command line always overrides the envvar.
Note that some switches are not accepted in envvar,
some others in #pragmas.
First the parser should start to step through
all the tokens in the string separated by
whitespace. (or just walk through all argv[])
1.) If the token begins with "-", it
should be treated as a new style switch.
One or more switch characters can follow
this. The "-" sign inside the token
will turn off the switch.
If the switch has an argument all the following
characters are treated as part of the argument.
The "/" sign has no special meaning here.
-wn ( W N )
-w-n ( !W N )
-wi/harbour/include/ ( W I=/harbour/include/ )
-wi/harbour/include/n ( W I=/harbour/include/n )
-wes0n ( W ES=0 N )
-wen ( W [invalid switch: e] N )
-wesn ( W ES=default(0) N )
-wses ( W S ES=default(0) )
-wess ( W ES=default(0) S )
- ( [invalid switch] )
-w-n-p ( !W !N P )
-w-n-p- ( !W !N !P )
-w- -w -w- ( finally: !W )
2.) If the token begins with "/", it
should be treated as a compatibility style switch.
The parser scans the token for the next "/" sign or EOS
and treats the resulting string as one switch.
This means that a switch with an argument containing
"/" sign has some limitations. This may be solved by
allowing the usage of quote characters. This is mostly
a problem on systems which use "/" as path separator.
The "-" sign has no special meaning here, it can't be
used to disable a switch.
/w/n ( W N )
/wo/n ( [invalid switch: wo] N )
/ihello/world/ ( I=hello [invalid switch: world] [invalid switch: /] )
/i"hello/world/"/w ( I=hello/world/ W )
/ihello\world\ ( I=hello\world\ )
3.) If the token begins with anything else it should
be skipped.
The Harbour switches are always case insensitive.
In the Harbour commandline the two style can be used together:
harbour -wnes2 /gc0/q0 -iC:\hello
Exceptions:
- Handlig of the /CREDIT undocumented switch
on Harbour command line is unusual, check the current code
for this.
- The CLIPPER, HARBOUR and Harbour application
command line parsing is a different beast,
see cmdarg.c for a NOTE.
Just some examples for the various accepted forms:
//F20 == /F20 == F20 == F:20 == F20X
//TMPPATH:C:\hello
F20//TMPPATH:/temp///F:30000000 NOIDLE
F0NOIDLEX10
SQUAWKNOIDLE
"//" should always be used on the command line.
Viktor Szakats
c:\harbour\doc\codebloc.txt
/*
* $Id: codebloc.txt 2175 2000-02-13 11:13:27Z vszel $
*/
The Harbour implementation of codeblocks.
Ryszard Glab
Compilation of a codeblock.
During compile time the codeblock is stored in the following form:
- the header
- the stream of pcode bytes
The header stores information about referenced local variables.
+0: the pcode byte for _PUSHBLOCK
+1: the number of bytes that defines a codeblock
+3: number of codeblock parameters (declared between || in a codeblock)
+5: number of used local variables declared in procedure/function where
the codeblock is created
+7: the list of procedure/function local variables positions on the eval
stack of procedure/function. Every local variable used in a codeblock
occupies 2 bytes in this list. When nested codeblocks are used then this
list is created for the outermost codeblock only.
+x: The stream of pcode bytes follows the header.
+y: the pcode byte for _ENDBLOCK
Creation of a codeblock.
When HB_P_PUSHBLOCK opcode is executed then the HB_ITEM structure is created
and placed on the eval stack. The type of item is IT_BLOCK. The value of this
item is a pointer to HB_CODEBLOCK structure. Additionally this item stores the
base of static variables defined for the current function/procedure - this
is used during a codeblock evaluation when the evaluation is called from a code
from other PRG module. Also the number of expected parameters is stored.
The HB_CODEBLOCK structure stores a pointer to the pcodes stream that is
executed during a codeblock evaluation. It stores also the pointer to a table
with local variables references. Values of all local variables defined in a
procedure and used in a codeblock are replaced with a reference to a
value stored in a global memory variables pool. This allows the correct access
to detached local variables in a codeblock returned from this function (either
directly in RETURN statement or indirectly by assigning it to a static or
memvar variable. This automatic and unconditional replace is required because
there is no safe method to find if a codeblock will be accessed from an outside
of a function where it is created.
When nested codeblocks are used then only the outermost codeblock creates
the table - all inner codeblock uses this table. The first element of this
table contains a reference counter for this table. It allows to share the table
between nested codeblock - the table is deleted if there is no more references
to it. This is caused by the fact that a inner codeblock can be created during
evaluation of outer codeblock when local variables don't exist like in this
example:
PROCEDUE MAIN()
PRIVATE foo, bar
Test()
EVAL( foo )
EVAL( bar )
PROCEDURE Test()
LOCAL a:='FOO', b:='BAR'
foo ={ || a + ( bar:=EVAL( {|| b} ) ) }
RETURN
Evaluation of a codeblock.
Parameters passed to a codeblock are placed on the eval stack before a
codeblock evaluation. They are accessed just like usual function
parameters. When a codeblock parameter is referenced then its position on the
eval stack is used. When a procedure local variable is referenced then the
index into the table of local variables positions (copied from the header) is
used. The negative value is used as an index to distinguish it from the
reference to a codeblock parameter.
Incompatbility with the Clipper.
1) Detached locals passed by reference
There is a little difference between the handling of variables passed by
the reference in a codeblock.
The following code explains it (thanks to David G. Holm)
Function Main()
Local nTest
Local bBlock1 := MakeBlock()
Local bBlock2 := {|| DoThing( @nTest ), qout("From Main: ", nTest ) }
eval( bBlock1 )
eval( bBlock2 )
Return( NIL )
Function MakeBlock()
Local nTest
Return( {|| DoThing( @nTest ), qout("From MakeBlock: ", nTest ) } )
Function DoThing( n )
n := 42
Return( NIL )
In Clipper it produces:
From MakeBlock: NIL
From Main: 42
In Harbour it produces (it is the correct output, IMHO)
From MakeBlock: 42
From Main: 42
2) Scope of undeclared variables
Consider the following code:
PROCEDURE MAIN()
LOCAL cb
cb :=Detach()
? EVAL( cb, 10 )
RETURN
FUNCTION Detach()
LOCAL b:={|x| x+a}
LOCAL a:=0
RETURN b
In Clipper the 'a' variable in a codeblock has the *local* scope however in
Harbour the 'a' variable has the *private* scope. As a result, in Clipper
this code will print 10 and in Harbour it will raise 'argument error' in
'+' operation.
This will be true also when the 'a' variable will be declared as PRIVATE
PROCEDURE MAIN()
LOCAL cb
PRIVATE a
cb :=Detach()
? EVAL( cb, 10)
RETURN
The above code also prints 10 in Clipper (even if compiled with -a or -v
switches)
c:\harbour\doc\codestyl.txt
/*
* $Id: codestyl.txt 9252 2008-08-26 11:33:03Z vszakats $
*/
/* Please note the following comments we may use everywhere
NOTE: Notes
TODO: something should be added here
TOFIX: something needs to be fixed
OBSOLETE: something could be removed from here
QUESTION: I had some questions at this point but I could not get an answer
OPT: something is commented out to improve performance
As an example: */
Harbour Coding Standards
========================
(based heavily on coding standards placed in PHP)
Code Implementation
-------------------
[0] Document your code in source files and the manual. [tm]
[1] Functions that are given pointers to resources should not free them
For instance, function int mail(char *to, char *from) should NOT free
to and/or from.
Exceptions:
- The function's designated behavior is freeing that resource.
E.g. hb_xfree()
- The function is given a boolean argument, that controls whether or not
the function may free its arguments (if true - the function must free its
arguments, if false - it must not)
[2] Functions that are tightly integrated with other functions within the
same module, and rely on each other non-trivial behavior, should be
documented as such and declared 'static'. They should be avoided if
possible.
[3] Use definitions and macros whenever possible, so that constants have
meaningful names and can be easily manipulated.
Use TRUE instead of 1 (in boolean context)
Use FALSE instead of 0 (in boolean context)
Use NULL instead of 0 (in pointer context)
Always use 'HB_' prefix for definitions of new datatypes and macros.
Use either 'PHB_' prefix for datatypes that are pointers.
e.g.
HB_ITEM
PHB_ITEM
[4] When writing functions that deal with strings, be sure to remember
that Harbour holds the length property of each string, and that it
shouldn't be calculated with strlen(). Write your functions in a such
a way so that they'll take advantage of the length property, both
for efficiency and in order for them to be binary-safe.
Functions that change strings and obtain their new lengths while
doing so, should return that new length, so it doesn't have to be
recalculated with strlen()
[5] NEVER USE strncat(). If you're absolutely sure you know what you're doing,
check its man page again, and only then, consider using it, and even then,
try avoiding it.
[6] Use assert(). Not only does good assertion catch bugs, but it also
helps with code readability.
- Do not use assert for error handling. Use assert only for the
condition that must be always true.
- Do not use assignments in assert conditions. If you assign inside an
assert condition, you risk an elusive bug that would be very difficult
to spot in a debug build, due to the side effect of the assignment.
Function calls in assert conditions may also cause this problem, if
they modify one of their arguments or global variables.
[7] When commenting out code using a #if statement, do NOT use 0 only. Instead
use "_0". For example, #if FOO_0, where FOO is your
cvs user foo. This allows easier tracking of why code was commented out,
especially in bundled libraries.
[8] Use hb_xgrab()/hb_xalloc(), hb_xfree(), hb_xrealloc(), hb_xsize() to
manage memory allocations. These functions implement an internal
"safety-net" mechanism that ensures the deallocation of any unfreed
memory at the end of an application. They also provide useful
allocation and overflow information while running in debug mode.
Naming Conventions
------------------
[1] Function names for user-level functions defined in C code should be
enclosed with in the HB_FUNC() macro. They should be in uppercase.
The name should be prefixed with 'HB_' if this function is an
extension to functions set defined in Clipper
Abbreviations should not be used when they greatly decrease the
readability of the function name itself.
[2] Variable names must be meaningful. One letter variable names must be
avoided, except for places where the variable has no real meaning or
a trivial meaning (e.g. for (i=0; i<100; i++) ...).
[3] Variable names should use so-called Hungarian notation. Use lowercase
letters however use underscores to separate between words.
Good:
pMemoryPtr
Bad:
p_memory_ptr
[4] Static variables should be prefixed with 's_'
[5] Global variables (variables shared beetwen modules) should be
prefixed with 'hb_', e.g. hb_vm_bDebug, hb_gc_pStart
Syntax and indentation
----------------------
[1] Never use C++ style comments (i.e. // comment). Always use C-style
comments instead. Harbour is written in C, and is aimed at compiling
under any ANSI-C compliant compiler. Even though many compilers
accept C++-style comments in C code, you have to ensure that your
code would compile with other compilers as well.
[2] Don't use K&R-style. Of course, we can't and don't want to
force anybody to use a style he or she is not used to, but,
at the very least, when you write code that goes into the core
of Harbour or one of its standard modules, please don't use the K&R
style. This applies to just about everything, starting with
indentation and comment styles and up to function declaration
syntax.
(see also http://www.tuxedo.org/~esr/jargon/html/entry/indent-style.html)
[3] Be generous with whitespace and braces. Always prefer:
if( foo )
{
bar;
}
to:
if(foo)bar;
and to:
if( foo )
bar;
Keep one empty line between the variable declaration section and
the statements in a block, as well as between logical statement
groups in a block. Maintain at least one empty line between
two functions, preferably two.
[4] When indenting, use three spaces. It is important to maintain
consistency in indenture so that definitions, comments, and
control structures line up correctly.
Documentation
--------------
[1] Whenever be possible document yourself functions you developed.
Usually is hard to understand code wrotted by other person, moreover
when it involve some obscure algorithm, system's vars or attributes
or data unavailable for the documentator.
This is particularly evident for low level functions.
[2] After some time function was wrotted, work become more difficult because
it's need it to read the code several times (even for the own developer).
This is evident when variables don't have useful names (and uses only
letters).
Because that, please DO NOT leave functions without documentation.
[3] If function made calls to other non-documented functions, and the
original developer are not available anymore, could be so hard and even
impossible to document it.
[4] Tracking which functions are documented and which are not, and if they
are total or partially documented are a waste of resources in time and
people.
[5] If you are the developer of the function don't worry by your narrative
skills, concentrate in what functions do, which arguments it gets,
which are its purpose and specially what information function returns.
[6] If you are the developer of the function, and you are using system's
functions or vars undocumented, please explain it as much as possible.
If you use a obscure or strange algorithm (i.e md5 ) please explain what
it does and how it works.
[7] Notes, remarks and explainings enclose always between the /* */ pair,
please don't use the double bar // because it difficults portability.
[8] Remember... documentation it's a much time consuming work, usually
takes more time writing the documentation of a function that writing
the function itself.
c:\harbour\doc\c_std.txt
/*
* $Id: c_std.txt 2421 2000-03-28 01:35:23Z vszel $
*/
+++Date last modified: 05-Jul-1997
Standard C functions defined by ANSI (ISO/IEC 9899:1990)
abort() abs() acos() asctime()
asin() assert() atan() atan2()
atexit() atof() atoi() atol()
bsearch() calloc() ceil() clearerr()
clock() cos() cosh() ctime()
difftime() div() exit() exp()
fabs() fclose() feof() ferror()
fflush() fgetc() fgetpos() fgets()
floor() fmod() fopen() fprintf()
fputc() fputs() fread() free()
freopen() frexp() fscanf() fseek()
fsetpos() ftell() fwrite() getc()
getchar() getenv() gets() gmtime()
isalnum() isalpha() iscntrl() isdigit()
isgraph() islower() isprint() ispunct()
isspace() isupper() isxdigit() labs()
ldexp() ldiv() localeconv() localtime()
log() log10() longjmp() malloc()
mblen() mbstowcs() mbtowc() memchr()
memcmp() memcpy() memmove() memset()
mktime() modf() perror() pow()
printf() putc() putchar() puts()
qsort() raise() rand() realloc()
remove() rename() rewind() scanf()
setbuf() setjmp() setlocale() setvbuf()
signal() sin() sinh() sprintf()
sqrt() srand() sscanf() strcat()
strchr() strcmp() strcoll() strcpy()
strcspn() strerror() strftime() strlen()
strncat() strncmp() strncpy() strpbrk()
strrchr() strspn() strstr() strtod()
strtok() strtol() strtoul() strxfrm()
system() tan() tanh() time()
tmpfile() tmpnam() tolower() toupper()
ungetc() va_arg() va_end() va_start()
vfprintf() vprintf() vsprintf() wcstombs()
wctomb()
Additional C numeric functions defined by NCEG
feclearexcepts() fegetenv() fegetexcept() fegetprec()
fegetround() feprocentry() feprocexit() feraiseexcept()
fesetenv() fesetexcept() fesetprec() fesetround()
fetestexcept()
Additional C functions defined by Posix.1
access() alarm() cfgetispeed() cfgetospeed()
cfsetispeed() cfsetospeed() chdir() chmod()
chown() close() closedir() creat()
ctermid() cuserid() dup() dup2()
execl() execle() execlp() execv()
execve() execvp() _exit() fcntl()
fdopen() fileno() fork() fpathconf()
fstat() getcwd() getegid() geteuid()
getgid() getgrgid() getgrnam() getgroups()
getlogin() getpgrp() getpid() getppid()
getpwnam() getpwuid() getuid() kill()
link() lseek() mkdir() mkfifo()
open() opendir() pause() pipe()
read() readdir() rewinddir() rmdir()
setgid() setpgid() setsid() setuid()
sigaction() sigaddset() sigemptyset() sigfillset()
sigismember() siglongjmp() sigpending() sigprocmask()
sigsetjmp() sigsuspend() sleep() stat()
sysconf() tcdrain() tcflow() tcflush()
tcgetattr() tcgetpgrp() tcsendbreak() tcsetattr()
tcsetpgrp() times() ttyname() tzset()
umask() uname() unlink() utime()
wait() waitpid() write()
Standard functions added by the draft C++ standard
terminate() unexpected()
Standard C keywords and operators defined by ANSI (ISO/IEC 9899:1990)
! != % %=
& && &= ()
* *= + ++
+= , - --
-= -> . /
/= < << <<=
> >> >>= ?:
[] ^ ^= |
|= || ~ auto
break case char const
continue default do double
else enum extern float
for goto if int
long register return short
signed sizeof static struct
switch typedef union unsigned
void volatile while
Standard C preprocessor instructions defined by ANSI (ISO/IEC 9899:1990)
# ## #define #elif
#else #endif #error #if
#if !defined #if defined #ifdef #ifndef
#include #line #pragma #undef
__DATE__ __FILE__ __LINE__ __STDC__
__TIME__
Standard C trigraph sequences defined by ANSI (ISO/IEC 9899:1990)
??= means # ??( means [ ??/ means \ ??) means ]
??' means ^ ??< means { ??! means | ??> means }
??- means ~
Standard ANSI C character constant escape sequences
\a Alert ASCII BEL (Ctrl-G)
\b Backspace ASCII BS (Ctrl-H)
\f Form feed ASCII FF (Ctrl-L)
\n New line ASCII NL (Ctrl-J)
\r Carriage return ASCII CR (Ctrl-M)
\t Horizontal tab ASCII TAB (Ctrl-I)
\v Vertical tab ASCII VT (Ctrl-K)
\\ Literal backslash
\' Literal apostrophe
\" Literal quotation mark
\? Literal Question mark
\<1-3 octal digits> Char value in octal
\x<1-2 hex digits> Char value in hex
Standard keywords and operators added by the draft C++ standard
->* .* :: asm
catch class delete delete[]
friend inline new operator
private protected public template
this throw try virtual
Standard C macros defined by ANSI (ISO/IEC 9899:1990)
BUFSIZ CHAR_BIT CHAR_MAX CHAR_MIN
CLOCKS_PER_SEC DBL_DIG DBL_EPSILON DBL_MANT_DIG
DBL_MAX DBL_MAX_10_EXP DBL_MAX_EXP DBL_MIN
DBL_MIN_10_EXP DBL_MIN_EXP EDOM EOF
ERANGE EXIT_FAILURE EXIT_SUCCESS FILENAME_MAX
FLT_DIG FLT_EPSILON FLT_MANT_DIG FLT_MAX
FLT_MAX_10_EXP FLT_MAX_EXP FLT_MIN FLT_MIN_10_EXP FLT_MIN_EXP
FLT_RADIX FLT_ROUNDS FOPEN_MAX HUGE_VAL INT_MAX
INT_MIN _IOFBF _IOLBF _IONBF
L_tmpnam LC_ALL LC_COLLATE LC_CTYPE
LC_MONETARY LC_NUMERIC LC_TIME LDBL_DIG
LDBL_EPSILON LDBL_MANT_DIG LDBL_MAX LDBL_MAX_10_EXP
LDBL_MAX_EXP LDBL_MIN LDBL_MIN_10_EXP LDBL_MIN_EXP
LONG_MAX LONG_MIN MB_CUR_MAX MB_LEN_MAX
NDEBUG NULL RAND_MAX SCHAR_MAX
SCHAR_MIN SEEK_CUR SEEK_END SEEK_SET
SHRT_MAX SHRT_MIN SIG_DFL SIG_ERR
SIG_IGN SIBGABRT SIGFPE SIGILL
SIGINT SIGSEGV SIGTERM TMP_MAX
UCHAR_MAX UINT_MAX ULONG_MAX USHRT_MAX
offsetof()
Additional C numeric macros defined by NCEG
FE_ALL_EXCEPT FE_DBLPREC FE_DIVBYZERO FE_DOWNWARD
FE_FLTPREC FE_INEXACT FE_INVALID FE_LDBLPREC
FE_OVERFLOW FE_TONEAREST FE_TOWARDZERO FE_UNDERFLOW
FE_UPWARD fpclassify() FP_INFINITE FP_NANQ
FP_NANS FP_NORMAL FP_SUBNORMAL FP_ZERO
INFINITY isfinite() isnan() isnormal()
NAN NANS __FPCE_IEEE__ __FPCE__
Additional C macros defined in Posix.1
ARG_MAX B0 B50 B75
B110 B134 B150 B200
B300 B600 B1200 B1800
B2400 B4800 B9600 B19200
B38400 BRKINT CHILD_MAX CLK_TCK
CLOCAL CREAD CS5 CS6
CS7 CS8 CSIZE CSTOPB
E2BIG EACCESS EAGAIN EBADF
EBUSY ECHILD ECHO ECHOE
ECHOK ECHONL EDEADLK EEXIST
EFAULT EFBIG EINTR EINVAL
EIO EISDIR EMFILE EMLINK
ENAMETOOLONG ENFILE ENODEV ENOENT
ENOEXEC ENOLCK ENOMEM ENOSPC
ENOTDIR ENOTEMPTY ENOTTY ENXIO
EPERM EPIPE EROFS ESPIPE
ESRCH EXDEV FD_CLOEXEC F_DUPFD
F_GETFD F_GETFL F_GETLK F_OK
F_RDLCK F_SETFD F_SETFL F_SETLK
F_SETLKW F_UNLCK F_WRLCK HUPCL
ICANON ICRNL IEXTEN IGNBRK
IGNCR IGNPAR IGNLCR INPCK
ISIG ISTRIP IXOFF IXON
LDBL_DIG LDBL_EPSILON LDBL_MANT_DIG LDBL_MAX
LDBL_MAX_10_EXP LDBL_MAX_EXP LDBL_MIN LDBL_MIN_10_EXP
LDBL_MIN_EXP LINK_MAX L_ctermid MAX_CANON
MAX_INPUT NAME_MAX NCCS NGROUPS_MAX
NOFLSH OPEN_MAX OPOST O_ACCMODE
O_APPEND O_CREAT O_EXCL O_NOCTTY
O_NONBLOCK O_RDONLY O_RDWR O_TRUNC
O_WRONLY PARENB PARMRK PARODD
PATH_MAX PIPE_BUF R_OK SA_NOCLDSTOP
SIGARLM SIGCHLD SIGCONT SIGHUP
SIGKILL SIGPIPE SIGQUIT SIGSTOP
SIGTSTP SIGTTIN SIGTTOU SIGUSR1
SIGUSR2 SIG_BLOCK SIG_SETMASK SIG_UNBLOCK
SSIZE_MAX STDERR_FILENO STDIN_FILENO STDOUT_FILENO
STREAM_MAX S_IRGRP S_IROTH S_IRUSR
S_IRWXG S_IRWXO S_IRWXU S_ISBLK
S_ISCHR S_ISDIR S_ISFIFO S_ISGID
S_ISREGSUID S_IWGRP S_IWOTH S_IWUSR
S_IXGRP S_IXOTH S_IXUSR TCIFLUSH
TCIOFF TCIOFLUSH TCION TCOFLUSH
TCOFF TCOON TCSADRAIN TCSAFLUSH
TCSANOW TOSTOP TZNAME_MAX VEOF
VEOL VERASE VINTR VKILL
VMIN VQUIT VSTART VSTOP
VSUSP VTIME WEXITSTATUS WIFEXITED
WIFSIGNALED WIFSTOPPED WNOHANG WSTOPSIG
WTERMSIG WUNTRACED W_OK X_OK
_PC_MAX_CANON _PC_MAX_INPUT _PC_NAME_MAX _PC_NO_TRUNC
_PC_PATH_MAX _PC_PIPE_BUF _PC_VDISABLE _POSIX_ARG_MAX
_POSIX_CHILD_MAX _POSIX_JOB_CONTROL _POSIX_LINK_MAX _POSIX_MAX_CANON
_POSIX_MAX_INPUT _POSIX_NAME_MAX _POSIX_NGROUPS_MAX _POSIX_NO_TRUNC
_POSIX_OPEN_MAX _POSIX_PATH_MAX _POSIX_SAVED_IDS _POSIX_SSIZE_MAX
_POSIX_STREAM_MAX _POSIX_TZNAME_MAX _POSIX_VDISABLE _POSIX_VERSION
_SC_ARG_MAX _SC_CHILD_MAX _SC_CLK_TCK _SC_JOB_CONTROL
_SC_NGROUPS_MAX _SC_OPEN_MAX _SC_SAVED_IDS _SC_STREAM_MAX
_SC_TZNAME_MAX _SC_VERSION
_PC_CHOWN_RESTRICTED
_POSIX_CHOWN_RESTRICTED
Standard C defined data types in ANSI (ISO/IEC 9899:1990)
clock_t div_t FILE fpos_t
jmp_buf struct lconv ldiv_t ptrdiff_t
sig_atomic_t size_t time_t struct tm
va_list wchar_t
Additional C data types defined by NCEG
fenv_t fexcept_t
Additional C data types defined in Posix.1
cc_t dev_t DIR gid_t
ino_t mode_t nlink_t off_t
pid_t struct passwd sigjmp_buf sigset_t
sigaction speed_t ssize_t struct stat
tcflag_t struct termios uid_t struct utsname
Standard C global variables in ANSI (ISO/IEC 9899:1990)
errno stderr stdin stdout
c:\harbour\doc\destruct.txt
/*
* $Id: destruct.txt 7819 2007-10-13 00:12:25Z druzus $
*/
Destructors
===========
Destructors are special methods executed just before the object
will be destroyed. It means that a programmer _has_to_ pay a special
attention to the destructor's code and _NEVER_ store the reference
to SELF object in external items. The piece of memory where
the instance of class (object) is held, will be freed when
the destructor finishes, so any references to SELF object will
point to uninitialized memory or memory allocated for other
structures. Sooner or later (probably in a next GC pass) these
references will be accessed, causing GPFs or some other unpredictable
problems.
Harbour implementation
======================
General destructor activation
-----------------------------
Each object item has a reference counter. When it reaches 0 the object
is destroyed and if it has destructor message then this message will be
executed just before freeing the memory. After executing destructor HVM
checks if a programmer didn't store the reference to the object being
destroyed somewhere, and if he did then RT error is generated.
It's possible to detect such situation by simply checking the reference
counter. Such situation is not dangerous for HVM integrity because the
memory is not freed - instead the object is converted to an empty array.
Though it does not mean that the application is valid. A programmer stored
a reference to SELF object somewhere and when he will try to access it as
an object, some other RT errors will be generated.
For sure such programs have to be fixed.
It's the not the only one situation when destructors can be executed.
It's possible to create cyclic references between some complex items
so the reference counters will never reach 0 even if the items are not
longer accessible by application. To avoid memory leaks, such items are
destroyed by Garbage Collector in a special way. GC scans all items known
to HVM and marks them as used, then destroys all items which are not marked.
The reference counters in such items are greater then zero and cannot
be directly used to detect bugs in a user code. So GC collects all
unaccessible items and then executes cleanup functions for each of them,
and finally checks if reference counters reached zero before it will
free the memory blocks. If they didn't then RT error is generated for
the first memory block. All items which are still accessible, are not
freed and if GC can recognize a type of an item then it will also try to
convert it to some empty form (f.e. empty array).
The destructors are executed from cleanup functions so they all will be
executed and then, if there is sth wrong, RT error will be generated for
the first memory block which was copied to some external structures.
Please note that the order in which destructors are executed by GC
can be diffrent then some logical order defined by an application. HVM
does not know anything about programmer's ideas so a programmer has to
create a code which will be safe for such situations. HVM only guaranties
that destructors will be executed only once for each object.
This also cannot break HVM integrity for standard object items which are
represented as arrays. But if the problem is inside cleanup function of
a GC POINTER item, which has a structure unknown to HVM, then any further
behavior can be unpredictible if a programmer, who created such pointer
items, doesn't support such situation himslef in his C code. It's a good
practice to add some type of marker to body of memory allocated by
hb_gcAlloc() to detect bugs in .prg code destructors which may keep
pointers to freed POINTER item (these could be destructors of differ
object items).
In such case GC will not free the block so cleanup function (not object
destructor) will be executed second time when the buggy reference will be
cleared. Such marker can help to make clean-up function safe for such
situation. It's a programmer's implementation decision if such pointer item
should be still valid and work like before or drop its capacities after
first cleanup function execution. Anyhow the code should expect such
situation.
In summary, Harbour destructor implementation should be able to detect
bugs in destructor and keep HVM integrity. But we are not able to
guarantiee that nothing wrong will happen with 3-rd party code which
uses POINTER items scanned by GC, which are not safe for .prg code
bugs in destructors and repeated cleanup function execution.
Exiting the application and HVM closing
---------------------------------------
When HVM exits all items on HVM stack (local variables and parameters)
are cleaned. Then HVM clears all memvar items.
After these two steps HVM executes GC and all items which are not longer
accessible will be freed. Then HVM closes RDD system.
It's the last moment when object destructors can be executed, because
in next steps, the classy subsystem is closed and all static variables
cleared. So for all items which still exist as STATIC variables or in
some other structures, the object destructors will not be executed.
Clearing STATIC variables before closing classy subsystem will not help
because STATIC variables are integral part of this subsystem.
Anomalies and excpetions
------------------------
In some situations HVM may clear items when exception apear, f.e.
BREAK or QUIT request. In such case executing the exception type
is stored and destructors are executed and finally the exception
restored. But in destructors code new exception can appear. In such
case HVM will give higher priority to QUIT request. If both exception
are BREAK then the one from destructor is taken because it could
overwrite the error object created before destructor.
Inheritance
-----------
If class has more then one destructor inherited from other classes
then all destructors are executed in reverted order. First current
class destructor (if any) and then super class destructors.
Defining destructors in CLASS definition code
---------------------------------------------
CREATE CLASS ...
...
DESTRUCTOR
...
ENDCLASS
Przemyslaw Czerpak (druzus/at/priv.onet.pl)
c:\harbour\doc\dirstruc.txt
/*
* $Id: dirstruc.txt 9378 2008-09-14 10:19:59Z vszakats $
*/
Harbour directory structure
===========================
Follow are the various directories that exist under the Harbour tree.
Under each directory exist in this list there is also a special directory
named .svn, which should normally ignored since it is used by the SVN to keep
track of all files (read the FAQ if you don't know what SVN is).
- Main Harbour directory. Contain all the various
| make file and Changelog (=changes history) files.
|
+---bin - Executable and build scripts.
| | Should contain harbour.exe and other executable. (*)
| |
| +---b32 -
| |
| +---vc -
|
+---config - Configuration Files (.cf) for the GNU Make system.
| |
| +---bsd - Configuration files specific to FreeBSD.
| |
| +---darwin - Configuration files specific to BSD/Darwin.
| |
| +---dos - Configuration files specific to DOS.
| |
| +---hpux - Configuration files specific to HP-UX.
| |
| +---linux - Configutation files specific to GNU/Linux.
| |
| +---os2 - Configutation files specific to OS/2.
| |
| +---sunos - Configutation files specific to SunOS.
| |
| +---w32 - Configutation files specific to MS Windows.
|
+---contrib - Miscellaneous contribution files. Those are not
| | part of the official Harbour project.
| |
| +---examples - Sample files and small applications.
| | |
| | +---dbu - Make files (without source) for CA-Cl*pper DBU.
| | |
| | +---guestbk - Harbour Guests Book.
| | |
| | +---hbsqlit2 - Interface for SQLite 2.x library.
| | | |
| | | +---tests - Test programs.
| | |
| | +---hscript - Harbour Script.
| | |
| | +---misc - A few humble demonstration.
| | |
| | +---pe - Editor.
| | |
| | +---hbpp - Harbour Preprocessor as a standalone module.
| | |
| | +---rdddbt - DBFDBT RDD.
| |
| |---gtalleg - GT subsystem based on Allegro with graphic
| | extensions.
| |
| +---gtwvg - GT subsystem for Windows GUI using GDI functions.
| | |
| | +---tests - Demo program and sample images.
| |
| +---hbapollo - Wrapper functions for VistaSoftware's Apollo
| | | database driver.
| | |
| | +---tests - Test programs.
| |
| +---hbbmcdx - DBFCDX RDD with bitmap filters compatible with
| | CA-Cl*pper 5.3
| |
| +---hbbtree - BTree library.
| | |
| | +---doc - HB_BTree C and Harbour API documentation.
| | |
| | +---tests - HB_BTree api test programs.
| |
| +---hbclip - Harbour Compatibility Library (HCL) for
| | CA-Cl*pper 5.x
| |
| +---hbclipsm - Miscellaneous contribution files.
| | |
| | +---tests - Test programs.
| |
| +---hbct - CA-T**ls Compatible Library for Harbour.
| | |
| | +---tests - Test programs.
| |
| +---hbcurl - libcurl 'easy' API - Harbour interface.
| | |
| | +---tests - Test programs.
| |
| +---hbfbird - Harbour Low Level api for Firebird and Interbase
| | | RDBMS.
| | |
| | +---tests - Test programs.
| |
| +---hbfimage - Wrapper for FreeImage.
| | |
| | +---tests - Test program and sample images.
| | |
| | +-imgs_out - Output directory used by the test program.
| |
| +---hbgd - HBGD wrapper for gdLibrary.
| | |
| | +---doc - Help and license files.
| | |
| | +---tests - Test programs and samples.
| | |
| | +-digits - Digits images for counter test program.
| | |
| | +-imgs_in - Sample images.
| | |
| | +-imgs_out - Output directory.
| |
| +---hbgf - Harbour GUI framework.
| | |
| | +---hbgfgtk - Implementation for GTK+ environment.
| | |
| | +---hbgfos2 - Implementation for OS/2 Presentation Manager
| | | environment.
| | |
| | +---hbgfwin - Implementation for Windowns environment.
| | |
| | +---tests - Test programs.
| |
| +---hbgt - GT library port to Harbour.
| | |
| | +---doc - Documents for the GT library.
| | |
| | +---en - English documentation.
| |
| +---hbmisc - Miscellaneous contribution.
| | |
| | +---doc - Documents for above contribution.
| | | |
| | | +---en - English documentation.
| | |
| | +---tests - Test programs.
| |
| +---hbmsql - Harbour mSQL access classes.
| | |
| | +---tests - Test programs.
| |
| +---hbmysql - Harbour MySQL access classes.
| | |
| | +---tests - Test program.
| | |
| | +---utils - Converts a .dbf file into a MySQL table.
| |
| +---hbmzip - Wrapper functions for minizip library.
| | |
| | +---tests - Test programs.
| |
| +---hbnf - Nanforum library port for Harbour.
| | |
| | +---tests - Test program.
| |
| +---hbodbc - ODBS Access Class Demonstration.
| | |
| | +---tests - Test programs.
| |
| +---hbole - Windows OLE Automation library.
| | |
| | +---tests - Demonstration program.
| |
| +---hbpgsql - Harbour Low Level API for Postgres RDBMS.
| | |
| | +---tests - Test programs.
| |
| +---hbsqlit3 - Interface for SQLite 3.x library.
| | |
| | +---sqlite3 - An amalgamation of SQLite core library.
| | |
| | +---tests - Test programs.
| |
| +---hbtip - TIP Class oriented Internet Protocol library.
| | |
| | +---tests - Test programs.
| |
| +---hbtpathy - Telepathy serial communication port for Harbour.
| | |
| | +---tests - Test program.
| |
| +---hbvpdf - PDF library written in PRG.
| | |
| | +---tests - Test programs.
| | |
| | +---files - Sample files for testing.
| |
| +---hbw32 - Collection of Windows specific utility functions.
| | |
| | +---tests - Test programs.
| |
| +---hbwhat - What is a library for ccessing all of Windows API
| | from PRG level.
| |
| +---hbziparc - Compatibility interface with ZipArchive general
| | | purpose compression library to work with ZIP files.
| | |
| | +---tests - Test programs.
| | |
| | +---zlib - Stub to plug Harbour ZLIB without the need to
| | modify ZipArchive sources.
| |
| +---rddado - ADORDD - RDD to automatically manage Microsoft ADO.
| | |
| | +---tests - Test programs.
| |
| +---rddads - RDD for Advantage Database Server.
| | |
| | +---doc - Documents for Advantage Database Server RDD.
| | | |
| | | +---en - English documentation.
| | |
| | +---tests - Test programs.
| |
| +---xhb - xHarbour compatibility libarary. To allow programs
| which where written using some xHarcour extensions,
| to be complied by Harbour.
|
+---debian - Packaging information for Debian GNU/Linux.
|
+---doc - Documentation and white-paper.
| |
| +---en - English documentation.
| |
| +---es - Spanish documentation.
| |
| +---man - Man pages.
|
+---include - Include files for both Harbour and C.
|
+---lib - Run-Time libraries binaries for each platform. (*)
| |
| +---b32 -
| |
| +---vc -
|
+---obj - Object files. (*)
| |
| +---b32 -
| |
| +---vc -
|
+---source - All source files reside underneath.
| |
| +---codepage - National codepage collection.
| |
| +---common - Common function and Expression Optimizer.
| |
| +---compiler - Harbour compiler module.
| |
| +---debug - Debugger.
| |
| +---hbextern - Library with all function binding available for
| | .prg code
| |
| +---hbpcre - Harbour implementation of the Perl Compatible
| | Regular Expressions (PCRE) library.
| |
| +---hbzlib - Harbour implementation of the ZLIB data
| | compression library.
| |
| +---lang - National language message support files.
| |
| +---macro - Macro compiler.
| |
| +---main - Harbour compiler main source.
| |
| +---pp - Harbour Preprocessor.
| |
| +---rdd - Replaceable Database Driver (RDD).
| | |
| | +---dbfcdx - DBFCDX RDD.
| | |
| | +---dbffpt - DBFFPT RDD.
| | |
| | +---dbfntx - DBFNTX RDD.
| | |
| | +---hbsix - SIX compatible functions.
| | |
| | +---hsx - HiPer-SEEK / CFTS compatible library.
| | |
| | +---nulsys - NULL RDD.
| | |
| | +---usrrdd - USRRDD which allows to create a new RDD at PRG level.
| | |
| | +---example - Usage examples.
| | |
| | +---rdds - A set of simple RDD's all written in PRG.
| |
| +---rtl - Run-Time libraries functions and various General
| | | Terminal (GT) implementation
| | |
| | +---gtcgi - GT subsystem aimed at cgi-bin applications.
| | |
| | +---gtcrs - GT subsystem based on ncurses.
| | |
| | +---gtdos - GT subsystem for DOS compilers.
| | |
| | +---gtgui - Minimal GT for Windows GUI programs.
| | |
| | +---gtos2 - GT subsystem for OS/2 compilers.
| | |
| | +---gtpca - GT subsystem for ANSI terminals.
| | |
| | +---gtsln - GT subsystem based on slang.
| | |
| | +---gtstd - GT subsystem for plain ANSI C stream IO.
| | |
| | +---gttrm - GT subsystem for terminal. It does not use
| | | termcap/terminfo for terminal escape sequences,
| | | but rather hard coded ones for basic capabilities.
| | |
| | +---gtwin - GT subsystem for Windows compilers (Console).
| | |
| | +---gtwvt - GT subsystem for Windows using GUI windows instead of
| | | Console.
| | |
| | +---gtxwc - GT subsystem for XWindow Console.
| | |
| | +---gt_tpl - GT subsystem template.
| |
| +---vm - Harbour Virtual Machine and internal Run-Time
| | library functions.
| |
| +---mainstd - mainstd library for MinGW build.
| |
| +---mainwin - mainwin library for MinGW build.
|
|
+---tests - Test programs.
| |
| +---bldtest - Simple C program to check if Harbour can be compiled
| | on the current machine, system and C compiler.
| |
| +---hbpptest - Regression tests for the preprocessor.
| |
| +---multifnc - Overloading C functions test.
|
+---utils - Utilities and tools that are part of Harbour.
|
+---hbdoc - Documentation generation tool.
|
+---hbextern - hbextern.ch generator.
|
+---hbmake - Harbour Make utility.
|
+---hbrun - Standalone Harbour Portable Object file runner,
| and a "dot prompt" console for the Harbour language.
|
+---hbtest - Regression tests for the Run-Time library.
Legend:
=======
(*) Should exist in a final build or if you build them yourself, in
normal SVN distribution this directory is empty or does not contain
all files.
Chen Kedem
/*
* $Id: gmake.txt 9411 2008-09-16 03:18:31Z vszakats $
*/
INTRODUCTION
============
This file explains the philosophy for the GNU-make based build system
for Harbour, and gives instructions on how to use it.
PHILOSOPHY
==========
This build system is based on GNU-make, the idea being that GNU-make
is freely available for every platform you can dream up, and it is
usually more powerful than any native make.
Each directory in the project contains one makefile, called Makefile,
which lists the data (file names, directory names, etc.) that is used
to determine how to bring every target up to date within that
directory. There are no rules in the Makefiles, to keep them
platform-independent. The rules themselves are included from the
"appropriate" configuration file.
For example, the following was the Makefile for an early version
of the VM library:
-- Cut here ---------------------------------------
#
# $Id: gmake.txt 9411 2008-09-16 03:18:31Z vszakats $
#
ROOT = ../../
C_SOURCES=\
dynsym.c \
hvm.c \
initsymb.c \
LIB=vm
include $(TOP)$(ROOT)config/lib.cf
-- Cut here ---------------------------------------
What this means is:
* The root of the source directory is in ../../; that is where the
config/ directory lives, with all the real rules to make the
targets.
* The only sources in this directory are C sources (three files).
* The library name is "vm". This will be translated to a real file
name depending on the rules file: "libvm.a" on Unix, "VM.LIB" on
DOS.
* The final line includes the rules file. In this case, we include a
set of rules to build a library.
Let's look at another Makefile, this one for the Harbour compiler:
-- Cut here ---------------------------------------
#
# $Id: gmake.txt 9411 2008-09-16 03:18:31Z vszakats $
#
ROOT = ../../
YACC_SOURCE=harbour.y
LEX_SOURCE=harbour.l
C_SOURCES=\
genobj32.c \
C_MAIN=harbour.c
include $(TOP)$(ROOT)config/bin.cf
-- Cut here ---------------------------------------
Notice how we now have other kinds of source files: yacc sources and
lex sources. Also, since this is a Makefile for a stand-alone
executable, we indicate the name for the file containing the "main"
function, which also defines the executable name. The rules included
in this Makefile are those appropriate to build a stand-alone binary.
One final Makefile, this one from the source directory:
#
# $Id: gmake.txt 9411 2008-09-16 03:18:31Z vszakats $
#
-- Cut here ---------------------------------------
ROOT = ../
DIRS=\
compiler \
hbpp \
rtl \
vm \
rdd \
tools \
include $(ROOT)config/dir.cf
-- Cut here ---------------------------------------
This Makefile is used to traverse the subdirectories hanging from the
current directory. It simply lists all the subdirectories to be
traversed.
Now. let's take a look at the rules themselves. They all live in the
config/ directory, with the following structure:
config/: The generic configuration files.
config/w32: Configuration files for Windows platforms.
Finally, you will notice one thing: the build system compiles
everything into a subdirectory (for example, w32/gcc for Windows
files compiled with gcc). This has two advantages:
1. It allows you to compile for multiple platforms/compilers at the
same time.
2. It creates all temporary, object, binary, intermediate, etc. files
in the subdirectory; cleaning up is very easy.
USAGE
=====
To use the system, you need to install GNU-make 3.75 or later on your
system. To check this, type "make -v"; you should see
GNU Make version 3.75, by Richard Stallman and Roland McGrath.
...
Then, you must set a couple of environment variables that indicate
your architecture and compiler.
For gcc on Win95/WinNT with the Cygwin library:
Notes: The CYGWIN environment variable must include "noglob" in order
to avoid having Harbour or programs created with Harbour expand
wildcard command line arguments (this is checked at run-time!)
HB_ARCHITECTURE w32
HB_COMPILER gcc
HB_GT_LIB gtwin
CYGWIN noglob
C_USR -mwin32
L_USR -mwin32
For gcc on Win95/WinNT with the MinGW library:
HB_ARCHITECTURE w32
HB_COMPILER mingw
HB_GT_LIB gtwin
For MSVC on Win95/WinNT:
Notes: gnu make is case sensitive! If your editor converts
harbour.c to HARBOUR.C when it saves the file, then gnu make
_will_not_work.
If you have MAKE_MODE in your dos environment, make sure it is
not set to unix
For best results, in your copy of make_gnu.bat, also set:
C_USR=-TP
HB_ARCHITECTURE w32
HB_COMPILER msvc
HB_GT_LIB gtwin
For GCC on BSD:
HB_ARCHITECTURE bsd
HB_COMPILER gcc
HB_GT_LIB gtstd
Notes:
1) You have to have bison and gmake installed in order to build
Harbour for BSD. The file doc/howtobsd.txt gives an overview
of what is required.
2) If you have an ncurses library or a slang library, you may
want to try one of the following two values for HB_GT_LIB:
gtcrs
gtsln
In which case you'll also need to export HB_SCREEN_LIB with
the name of the appropriate screen library, if it doesn't
match the default value in config/bsd/gcc.cf
For GCC on Linux:
HB_ARCHITECTURE linux
HB_COMPILER gcc
HB_GT_LIB gtstd
Notes:
1) If you have an ncurses library or a slang library, you may
want to try one of the following two values for HB_GT_LIB:
gtcrs
gtsln
In which case you'll also need to export HB_SCREEN_LIB with
the name of the appropriate screen library, if it doesn't
match the default value in config/linux/gcc.cf.
2) If you want to take advantage of compiler cache programs
(such as http://ccaache.samba.org), you may set environment
variable HB_CCACHE with the value containing the name of program.
For GCC on OS/2 for VIO mode:
Note: You must point C_INCLUDE_PATH to the EMX include directory and
you must also point LIBRARY_PATH to the EMX library directory.
HB_ARCHITECTURE os2
HB_COMPILER gcc
HB_GT_LIB gtos2
For GCC on OS/2 for PM mode:
Note: Harbour does not get built in PM mode, but Harbour programs do.
Note: You must point C_INCLUDE_PATH to the EMX include directory and
you must also point LIBRARY_PATH to the EMX library directory.
HB_ARCHITECTURE os2
HB_COMPILER gcc
HB_GT_LIB os2pm
For IBM Visual Age C++ on OS/2 for PM mode:
Note: Harbour does not get built in PM mode, but Harbour programs do.
Note: You must create an empty unistd.h in the IBMCPP\INCLUDE directory.
HB_ARCHITECTURE os2
HB_COMPILER icc
HB_GT_LIB os2pm
For Borland C++ 5.5
HB_ARCHITECTURE w32
HB_COMPILER bcc32
HB_GT_LIB gtwin
For Borland C++ 3.x
HB_ARCHITECTURE dos
HB_COMPILER bcc16
HB_GT_LIB gtdos
For DJGPP (GCC port for DOS)
HB_ARCHITECTURE dos
HB_COMPILER djgpp
HB_GT_LIB gtdos
For Watcom C/C++ 10.x (default Makefile creates DOS4G extender executables)
HB_ARCHITECTURE dos
HB_COMPILER watcom
HB_GT_LIB gtdos
Note: It is possible that you will have to increase the space reserved for
DOS environment variables in order to successfuly run make utility
(Add for example:
SHELL=C:\COMMAND.COM C:\ E=2048 /P
to your CONFIG.SYS )
If you issue a "make install", it will try to install your doc, header,
executable and library files into directories given by
HB_BIN_INSTALL
HB_DOC_INSTALL
HB_LIB_INSTALL
HB_INC_INSTALL
You can set those as environment variables too. There is no default for
HB_DOC_INSTALL, so if you don't define it, then the doc files will not be
installed.
The most used targets are these:
* all: Same as typing "make" without arguments. It will usually try to
compile and link the obvious target in the directory.
* clean: Clean up everything made by make.
* install: Install stuff into the appropriate directories.
NOTES
=====
In order to get a clean build after making source changes or after
receiving updated source files, you must use the following two steps:
1) make -r clean
3) make -r
Without the first step, changes to the Harbour compiler and/or various
include files will not be reflected in any object modules created from
Harbour source code.
The -r option isn't strictly necessary, but it does signficantly reduce
the number of rules that make has to evaluate otherwise, which may give
a performance boost on a slow system.
To rebuild only a part of Harbour, go to the appropriate source directory
and then run 'make -r'. For example, to rebuild all of Harbour, but not
the test programs, change to the 'source' directory. To rebuild only the
test programs, change to the 'test' directory.
If you are using a DOS-based operating system, then you can build any
program in tests/working by using the build batch file. For example,
'build scroll' will rebuild the scroll.prg program and then run it. This
can also be used for modules that aren't in the Makefile. You can also
pass parameters to the program. For example, 'build readfile harbour.ini'
will rebuild the readfile.prg program and run it with 'harbour.ini' as a
command line parameter.
c:\harbour\doc\gtapi.txt
/*
* $Id: gtapi.txt 9411 2008-09-16 03:18:31Z vszakats $
*/
GT API functions
================
By Bil Simser (Fri, 14 May 1999)
Using the gt API requires two steps.
The gt API interface is kept in gtapi.c. This houses the gt API and
does not have any platform or compiler specific information. This file
should (read:will) never change except to add new _gt functions. This
file will be used by Harbour or Harbour functions and must be linked
into the RTL.
The second step requires you to link in your platform specific
implementation of the _gt functions. These are functions named with
gtxxxxxx convention and are called by the _gt functions in gtapi.c.
I've provided the following files to implement the console functions:
gtdos.c - DOS implemenation
gtwin.c - Windows 95/NT implementation
gtos2.c - OS/2 implementation
gtxxx.c - Generic template for implementation
If you wish to port the gt functions to another platform, just take the
gtxxx.c and populate it with calls to your OSes functions. Call the file
something appropriate (gtmac.c, gtnext.c or whatever) and add it to
that platforms makefile.
The API supports a dozen or so compilers on three platforms. You only
have to change the gtxxx.c files to implement your platform.
The API needs to be initialized for Windows to setup the Input and Output
handles. These are done in _gtInit() and should always be called. Not sure
how this will be implemented (if at all) into Harbour but it needs to happen
or else you won't see any output under Windows.
There's a test section at the end of gtapi.c. I didn't want to keep
rebuilding
Harbour to build a PRG test and PRGs shouldn't call the _gt functions
directly anyway. Just compile gtapi.c alone with a #define of TEST to see
the output (or build a PRG test if you want).
You must include gtapi.c and one of the platform implementation files
to compile sucessfully!
There are exceptions for various compilers in the platform implementation
files so if you're using a compiler that doesn't support certain routines
or syntax just stick in your changes and surround it with an
#if defined(__XXX__) call.
This is a complete set of gt functions as defined by Clipper. That is
there are no new _gt functions added. But this is not a complete
implementation. I do not know what _gtBegin or _gtEnd will do for
instance. Yes, they buffer the display but what does that really mean
under the covers? Perhaps someone needs to implement a screen buffer
to write to in order to achive this but the issue that immediately comes
to mind is how to initialize the size of this buffer?
The files are attached but I will NOT be checking them into cvs for the
following reasons:
1. There is already a gtapi.c file and under no circumstances will I ever
overwrite someones code. If the author wants to remove his file and check
this in then be my guest.
2. This is my vision of how "I" think the gt API should be implemented.
Perhaps it isn't Antonio's or anyone elses so review it and if you feel
that it deserves being put into Harbour I'll leave that up to you.
TODO:
The following functions are not implemented in gtapi.c:
_gtPostExt
_gtPreExt
_gtScroll
_gtSetBlink
_gtSetMode
The following functions don't work in gtapi.c:
_gtSave
_gtRestore
You get garbage on the screen in DOS mode. Two Harbour functions are
included in the gtapi.c file, ROW() and COL() to get started.
You also may notice that I didn't include any NanFor document headers or
even any cvs macros. The jury is still out on that so I'll leave that to the
reader.
I release this to anyone who wants it. If you feel you don't like the
implementation and want to pursue a different approach, please do.
By not checking this in I'm not forcing anyone to use it.
If however you do feel it's a good start
(or a better start than what we have)
the please check it in and start writing those other terminal functions
(DEVPOS, etc.)
Best regards,
Bil.
How to get rid of unwanted console in Windows GUI applications
==============================================================
By Przemyslaw Czerpak (druzus/at/priv.onet.pl)
Do not use GTWIN :-)
GTWIN is a driver for users who wants to write CUI applications and
should give them all possible features. GUI libraries do not have to
use GT drivers if they don't need any GT functionality, or if they
don't want to give users support for standard Clipper/Harbour functions
which operate on GT resources.
Harbour application can work without any GT driver. In such case all
functions which operates on GT resources are redirected to meta GT
driver (GTNUL) which is part of RTL library. This driver makes all
operations on memory buffer and only OUTSTD()/OUTERR() output is sent
outside. All GT drivers inherits from GTNUL or from other GTs but in
the inheritance chain the first GT driver is always GTNUL.
Because there is no hard coded bindings between core code and other GT
drivers, then by default only GTNUL will be linked. So if you will want
to use some real GT you will have to add to your code:
REQUEST HB_GT_
Setting the default GT driver is done exactly the same as setting the
default RDD. In RDD it request DBFNTX by default. It is done inside a
module with RDDSYS() symbol, and core code contains:
REQUEST RDDSYS
Something like that is also done by Clipper. If you add to your code
RDDSYS symbol, then the default RDD will not be linked because your
RDDSYS will overload the default one (of course if it will be linked
before the one in core code). So it's enough to write something like:
ANNOUNCE RDDSYS
or:
PROC RDDSYS; RETURN
Both gives the same effect, and default RDD (DBFNTX) will not be linked.
Exactly the same I've done in GT subsystem. HB_GTSYS() makes exactly
the same job as RDDSYS() but for GT. This symbol is requested by core
code and in the module where it is defined it request default build GT
driver or if it's not set then default GT driver for given platform.
For Windows it looks like:
ANNOUNCE HB_GTSYS
REQUEST HB_GT_WIN
This causes that normal console applications do not have to explicitly
request GT driver and the one set in the module with HB_GTSYS is always
linked. If you do not want to link the GT driver then you have to make
the same as for RDD and add to your code:
ANNOUNCE HB_GTSYS
or:
PROC HB_GTSYS; RETURN
In such case your final application will not have any GT driver. If you
want to use GTNUL as base, you should add:
REQUEST HB_GT_NUL
Though IMHO this request should be part of GUI library core code. You
can link with your application more then one GT driver. It's enough
that you add more lines with:
REQUEST HB_GT_
For example, compile this code:
/*** t.prg ***/
REQUEST HB_GT_WIN
REQUEST HB_GT_WVT
PROC MAIN()
? HB_GTVERSION(), HB_GTVERSION(1)
TONE( 200, 3 )
TONE( 300, 3 )
TONE( 500, 3 )
INKEY( 0 )
RETURN
and link it as Windows GUI application. Then simply execute:
t //GTWIN
and:
t //GTWVT
Most of Windows linkers execute startup initialization code in the
order of linked modules, so the first linked GT driver will be the
default one. But you can control it also from your application, by
requesting HB_GT__DEFAULT symbol (I do not like this name because
it cannot be used with 10 character symbols so I'm ready for any other
positions). For example, if you add to your code:
REQUEST HB_GT_NUL_DEFAULT
Then GTNUL will be the default GT driver, and even if you would not
disable GTWIN and link it with your application, GTWIN will not be
activated but GTNUL.
It could be intentional, because if your application is linked with more
GTs, then you can also set the default one when you start your
application using //GT switch, or HB_GT environment variable. So
you can create GUI application which will set the default GT driver to
NUL and will not activate GTWIN, and when you'll want to enable debug
messages, you simply run:
myprog //GTWIN
and debug messages will use the GTWIN console window. You can think of
other situations when it could be useful to have full functional GT
driver in GUI application. You can even create mixed GUI/CUI code in one
program.
And finally, the TONE() function problem.
Low level TONE code is part of GT driver. In the past, GUI libraries in
Windows were linked the whole GTWIN driver and only TONE were used. It
was possible because someone blocked GTWIN to work with application
linked as Windows GUI programs. Now, GTWIN can be used with any
applications, and I do not want reduce its functionality. So GUI
libraries which needs TONE should have their own GT driver which will
support it. Now, such GT driver can also give much more features for
final users, because it allow to integrate GUI library with standard
Clipper screen functions.
How to create such base GUI GT driver?
See as example GTGUI in source/rtl/gtgui/gtgui.c
It supports only TONE and CLIPBOARD operations.
GUI libraries can use it or create other GT driver inheriting from
this one.
NOTE: source/rtl/gtgui/gtdef.c is a hack which overloads the default
Harbour build time GT driver and should not be replicated.
gtnul - base GT driver from which each other inherits.
it gives screen buffer functionality but does not
produce any screen output from disp*() commands
Only outStd()/outErr() are supported.
It's present on all platforms and i always linked.
gtcgi - very simple GT driver which does not make any output
formatting and simply send it as to stdout.
Supported by all platforms.
gtstd - it uses stdout output but tries to support full screen output but
without collor support and cursor shape. It format text to number
of row and columns if is able to detect these values on given
platform.
Supported by all platforms.
gtpca - It's PCANSI terminal GT - it works in similar way to ANSI GT
driver in Clipper though keyboard input is not fully supported.
Now GTTRM can make all GTPCA job and much more.
Supported by all platforms.
gtdos - GT driver for DOS - it uses BIOS and direct hardware screen output
so it's very similar to Clipper one - in practice due to the same
environment you will noticed that all small details of Clipper
GT drivers are replicated here. You can think about it like 100%
Clipper compatible.
Supported only by DOS builds.
gtos2 - GT driver for OS2 - It's sth like GTWIN but for other OS.
Supported only by OS2 builds.
gtwin - GT driver for MS-Windows console window.
Supported only by MS-WINDOWS (W95 or higher) builds.
gtcrs - GT driver for platforms which supports curses or compatible
(ncurses) library - in practice POSIX systems.
Supported by POSIX systems (mostly different *nixes)
gtsln - GT driver for platforms which supports slang library.
It's like GTCRS but instead of CURSES it uses SLANG.
Supported by POSIX systems (mostly different *nixes).
It supports Unicode input/output if compiled with slang
version which also supports it.
gttrm - it's like GTCRS and GTSLN but it does not use any external
terminal library like SLANG or CURSES and it does not use
any external database to extract terminal capabilities so
it can be compiled on any POSIX system - I'll add support
also for DOS/Windows in the future. It should automatically
detect UTF-8 terminal mode and switch internally to Unicode
mode if necessary. In theory is less functional then GTCRS
and GTSLN because I hard coded escape sequences only for few
terminals but because I added support also for some non
standard terminal extensions and I'm using very limited set
of output sequences then it usually works better then GTCRS
and GTSLN.
Supported by POSIX systems (mostly different *nixes)
gtwvt - GT driver for MS-Windows. It creates its own GUI window
instead of using MS-console window. It allows to change
font, window size, etc.
Supported only by MS-WINDOWS (W95 or higher) builds.
is a pure console implementation of traditional Clipper terminal
taking Windows API as its base console IO protocols. Its OI are
rendered in a Windows window and hence all of MSDN is available
for use with GTWVT.
To let the memory refreshed, I must remind
everybody that it is a superb work of Peter Rees contributed
to xHarbour on 22nd December 2003.
GTWVG - GUI emulation of GTWVT. It implements itself on top of GTWVT.
GTWVG ( WVTGUI in xHarbour ) offers functions and classes to
present a console application look like a windows one.
It renderes GUI elements on top of Clipper elements
( GETS, BROWSERS, BOXES, LINES ) which makes them
feel like a Windows element. GTWVG can be used with existing
code just adding some more code but without sacrificing or
modifying old one.
Also all IO commands can be rendered on top of the GUI elements
gtxwc - GT driver for X-Window. It's like GTWVT but for nixes.
Additionaly it has set of predefined vector characters
(box and arrowd drawing characters) which can be used
instead of the one defined in font. It means that you
will have all boxes and arrows you know from DOS ans CP437
even if you chose font which does not have them. Additionally
it support some simple graphic output. See tests/gfx.prg
for simple program which demonstrates it.
Supported by POSIX systems (mostly different *nixes)
gtalleg- GT driver which uses alegro library for input/output.
It's also GUI driver which support HB_GFX*() drawing.
Multi platform, works on all platforms for which allegro
library has been ported: MS-Win, DOS, VESA, X11, FB, SDL, ...
gtgui - pseudo GT driver which adds to GTNUL Clipboard and Tone
functionality. If you are using some MS-Windows GUI library
and you still want to use TONE() function or GTI_CLIPBOARD
actions then link this GT driver with your application.
If you do not want to use TONE() or GTI_CLIPBOARD then
do not link it - it will be only waste of memory.
gtctw - GT driver which adds CT3 Window functionality to any other
GT driver from which it inherits. It's activated automatically
when you execute first W*() function.
In similar way in Harbour it's possible to add support for
GTWVW inheriting from GTWVT.
Some of the GT drivers support additional functionality with hb_gtInfo()
interface.
See include/hbgtinfo.ch for different actions.
Best regards,
Przemek
c:\harbour\doc\hbmake.txt
/*
* $Id: hbmake.txt 9411 2008-09-16 03:18:31Z vszakats $
*/
Hbmake Readme
Hbmake is an powerful make system for Harbour. It include an Editor mode for
the creation of the make file.
Hbmake support the follow Switchs
-b Use BCC as the C compiler. This options is default under Windows
-g Use GCC as the C compiler. This options is default under OS/2
-gl Use GCC as the C compiler on Linux
-v Use MSVC as the C compiler
-D Define an macro. Multiple macros can be used in an single line
Ex:
-DOB=c.obj;d.obj
and also Multiple -D is also supported
-p Print all command and defines
-f Force all files to be rebuild
-e Open the editor mode.
-ex Open the editor mode in extended mode
-el Open the editor mode for creating libraries.
-elx Open the editor mode for creating librariesin extented mode.
-i Ignore errors returned by commands
-r Recurse directories for source code
The hbmake dont support old styles .rmk/.lnk Files. hbmake create it own when the editor mode is used with include both compile and link sections on the same file.
Now How to use the editor mode
go to the directory from with the application source that you to
convert.
call hbmake .bc -e
this will evoke hbmake editor mode.
then select your OS,C Compiler
If you need an Graphic library such as FWH or C4W, select the appropiate box, if you also use rddads. also check this box.
Select the harbour compiler options that you also what to use, along
with
the defaut values
Select the files that will be part of your app
then select the main file
then the new make file is create.
then call hbmake .bc
If you have compiler errors use hbmake .bc -f
Linux user need to create the harbour.cfg file in /etc or /usr/local/etc with the follow lines
CC=gcc
CFLAGS=-c -I/usr/include/harbour (this line must match your harbour include directory)
VERBOSE=YES
DELTMP=YES
c:\harbour\doc\hdr_tpl.txt
/*
* $Id: hdr_tpl.txt 9191 2008-08-19 13:11:22Z vszakats $
*/
/* NOTE: - Please use these template for your new files, replace parts
between curly braces {} with the appropriate text.
- You can find a history at the end of the file. */
FILE HEADER TEMPLATE
====================
/*
* Harbour Project source code:
* {one-liner description about the purpose of this source file}
*
* Copyright 2001 {list of individual authors and e-mail addresses}
* www - http://www.harbour-project.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
*
* As a special exception, the Harbour Project gives permission for
* additional uses of the text contained in its release of Harbour.
*
* The exception is that, if you link the Harbour libraries with other
* files to produce an executable, this does not by itself cause the
* resulting executable to be covered by the GNU General Public License.
* Your use of that executable is in no way restricted on account of
* linking the Harbour library code into it.
*
* This exception does not however invalidate any other reasons why
* the executable file might be covered by the GNU General Public License.
*
* This exception applies only to the code released by the Harbour
* Project under the name Harbour. If you copy code from other
* Harbour Project or Free Software Foundation releases into a copy of
* Harbour, as the General Public License permits, the exception does
* not apply to the code that you add in this way. To avoid misleading
* anyone as to the status of such modified files, you must delete
* this exception notice from them.
*
* If you write modifications of your own for Harbour, it is your choice
* whether to permit this exception to apply to your modifications.
* If you do not wish that, delete this exception notice.
*
*/
FILE HEADER TEMPLATE (OPTIONAL ADDITION FOR PARTIAL COPYRIGHTS)
===============================================================
/*
* The following parts are Copyright of the individual authors.
* www - http://www.harbour-project.org
*
* Copyright 2001 {name} <{e-mail address}>
* {function or subsystem name}
*
* See doc/license.txt for licensing terms.
*
*/
FUNCTION HEADER TEMPLATE
========================
/* $DOC$
* $FUNCNAME$
*
* $CATEGORY$
*
* $ONELINER$
*
* $SYNTAX$
*
* $ARGUMENTS$
*
* $RETURNS$
*
* $DESCRIPTION$
*
* $EXAMPLES$
*
* $TESTS$
*
* $STATUS$
*
* $COMPLIANCE$
*
* $PLATFORMS$
*
* $FILES$
*
* $SEEALSO$
*
* $END$
*/
FUNCTION HEADER EXAMPLE
=======================
/* $DOC$
* $FUNCNAME$
* IsLeapYr()
* $CATEGORY$
* Dates
* $ONELINER$
* Test if a date falls in a leap year.
* $SYNTAX$
* IsLeapYr( [] ) --> lIsLeap
* $ARGUMENTS$
* is an optional date. If not supplied is defaults to the
* value returned from date().
* $RETURNS$
* TRUE if falls in a leap year, FALSE if not.
* $DESCRIPTION$
* IsLeapYr() can be used to check if a given year is a leap year.
* $EXAMPLES$
* // Check if it's a leap year.
*
* If IsLeapYr()
* ? "One extra day before you get paid this Feb!!"
* Else
* ? "A normal year"
* EndIf
* $TESTS$
* valtype( IsLeapYr( date() ) ) == "L"
* valtype( IsLeapYr( ctod( "" ) ) ) == "L"
* valtype( IsLeapYr() ) == "L"
* IsLeapYr( SToD( "20000101" ) )
* !IsLeapYr( SToD( "19000101" ) )
* IsLeapYr( SToD( "19841231" ) )
* !IsLeapYr()
* $STATUS$
* C
* $COMPLIANCE$
* IsLeapYr() works exactly like CA-Cl*pper's IsLeapYr(), if your
* CA-Cl*pper doesn't have such a function you're probably in a
* different universe from the author of this function.
* $PLATFORMS$
* All
* $FILES$
*
* $SEEALSO$
* Date() IsWeekend() IsHarbourFinished() IsApocalypse()
* $END$
*/
/* ------------------------------------------------------------------------- */
/*
* ChangeLog:
*
* V 1.15 Viktor Szakats Name correction
* V 1.14 David G. Holm Second year 2000 chaned to 2001
* V 1.13 David G. Holm Year changed to 2001 from 2000.
* License changed to be compatible with
* the Guile 1.4 license (the old one
* was based on an earlier Guile).
* V 1.12 Viktor Szakats Year changed to 2000 from 1999.
* V 1.11 Viktor Szakats $FILES$ added.
* V 1.10 Viktor Szakats $PLATFORMS$ added.
* V 1.9 Viktor Szakats Small format changes.
* V 1.8 Viktor Szakats licence -> license
* V 1.7 Viktor Szakats History separated from the file header
* template. Slight changes in the format
* of the header. Removed "(proposal)"
* from the top of the file. Added partial
* copyright header template.
* V 1.6 Viktor Szakats RCS Id section separated from
* Licenc text.
* V 1.5 Viktor Szakats Small name correction.
* V 1.4 David G. Holm Removed "(C)" from Copyright notice
* Put author's name rather than date
* next to each version number, because
* the RCS tracks dates, but only tracks
* CVS user names, not author names.
* V 1.3 Viktor Szakats Description line changed to be a
* template, too.
* V 1.2 David G. Holm Added HRL/HVM license exception for
* executables. Added GNU web site.
* Replaced "?" in copyright statement
* with "(list of individual authors)".
* V 1.1 Viktor Szakats Added templates for file and function
* headers. Committed to CVS.
* V 1.0 Viktor Szakats Initial version.
*
*/
c:\harbour\doc\howtobld.txt
/*
* $Id: howtobld.txt 9191 2008-08-19 13:11:22Z vszakats $
*/
In the last phase of install process if bash shell is available in the
system then few bash scripts are created to make compiling and linking
with Harbour a little easier. There are compiler and linker wrappers
called "hbcc", "hbcmp", "hblnk" and "hbmk".
"hbcc" is a wrapper to the C compiler only. It sets all flags
and paths necessary to compile .c files which include Harbour header
files. The result of its work is an object file.
Use "hbcmp" exactly as you would use the harbour compiler itself.
The main difference with hbcmp is that it results in an object file,
not a C file that needs compiling down to an object. hbcmp also
ensures that the harbour include directory is seen by the harbour compiler.
"hblnk" simply takes a list of object files and links them together
with the harbour virtual machine and run-time library to produce an
executable. The executable will be given the basename of the first object
file if not directly set by the "-o" command line switch.
"hbmk" tries to produce an executable from your .prg file. It's a simple
equivalent of cl.bat from the CA-Cl*pper distribution.
All these scripts accept command line switches:
-o # output file name
-static # link with static Harbour libs
-fullstatic # link with all static libs
-shared # link with shared libs (default)
-mt # link with multi-thread libs
-gt # link with GT driver, can be repeated to
# link with more GTs. The first one will be
# the default at runtime
-xbgtk # link with xbgtk library (xBase GTK+ interface)
-hwgui # link with HWGUI library (GTK+ interface)
-l # link with library
-L # additional path to search for libraries
-fmstat # link with the memory statistics lib
-nofmstat # do not link with the memory statistics lib (default)
-[no]strip # strip (no strip) binaries
-main= # set the name of main program function/procedure.
# if not set then 'MAIN' is used or if it doesn't
# exist the name of first public function/procedure
# in first linked object module (link)
Link options work only with "hblnk" and "hbmk" and have no effect
in "hbcc" and "hbcmp".
Other options are passed to Harbour/C compiler/linker.
An example compile/link session looks like:
----------------------------------------------------------------------
druzus@uran:~/tmp$ cat foo.prg
function main()
? "Hello, World!"
return nil
druzus@uran:~/tmp$ hbcmp foo
Harbour Compiler Alpha build 46.2 (Flex)
Copyright 1999-2006, http://www.harbour-project.org/
Compiling 'foo.prg'...
Lines 5, Functions/Procedures 2
Generating C source output to 'foo.c'... Done.
druzus@uran:~/tmp$ hblnk foo.o
druzus@uran:~/tmp$ strip foo
druzus@uran:~/tmp$ ls -l foo
-rwxrwxr-x 1 druzus druzus 3824 maj 17 02:46 foo
----------------------------------------------------------------------
or using hbmk only:
----------------------------------------------------------------------
druzus@uran:~/tmp$ cat foo.prg
function main()
? "Hello, World!"
return nil
druzus@uran:~/tmp$ hbmk foo
Harbour Compiler Alpha build 46.2 (Flex)
Copyright 1999-2006, http://www.harbour-project.org/
Compiling 'foo.prg'...
Lines 5, Functions/Procedures 2
Generating C source output to 'foo.c'... Done.
druzus@uran:~/tmp$ ls -l foo
-rwxrwxr-x 1 druzus druzus 3824 maj 17 02:46 foo
----------------------------------------------------------------------
You will find additional wonderful tools: /usr/bin/hbrun
You can run clipper/xbase compatible source files with it
if you only put in their first line:
#!/usr/bin/hbrun
For example:
----------------------------------------------------------------------
druzus@uran:~/tmp$ cat foo.prg
#!/usr/bin/hbrun
function main()
? "Hello, World!, This is a script !!! :-)"
?
return nil
druzus@uran:~/tmp$ chmod +x foo.prg
druzus@uran:~/tmp$ ./foo.prg
Hello, World!, This is a script !!! :-)
druzus@uran:~/tmp$
I hope you will find this information useful,
Przemyslaw Czerpak (druzus/at/priv.onet.pl)
c:\harbour\doc\howtobsd.txt
/*
* $Id: howtobsd.txt 5610 2002-08-02 16:36:20Z dholm $
*/
HOW TO CONFIGURE FreeBSD TO BUILD HARBOUR
-----------------------------------------
First, you'll need to have the developer tools installed. Then you'll need
to install bison and gmake. If you installed the ports collection, then all
you need to do to install bison and gmake is to run the following commands,
which may require that you run su root first to get the correct permissions.
cd /usr/ports/devel/bison
make
make install
make clean
cd /usr/ports/devel/gmake
make
make install
make clean
If you want to use the GTSLN library instead of GTSTD or GTCRS, then you
also need to install libslang. If you installed the ports collection, then
all you need to do to install libslang is to run the following commands,
which may require that you run su first to get the correct permissions.
cd /usr/ports/devel/libslang
make
make install
make clean
Then read the doc/gmake.txt file for generic GNU make instructions and the
specific Harbour settings needed for BSD. When you want to build Harbour,
be sure to run 'gmake -r' at the command line instead of 'make -r'.
David G. Holm
c:\harbour\doc\howtomak.txt
/*
* $Id: howtomak.txt 9188 2008-08-17 15:04:11Z vszakats $
*/
HOW TO BUILD HARBOUR FROM THE SOURCE
------------------------------------
You'll need these:
- Flex
- Bison 1.28 or upper (set BISON_SIMPLE envvar to point to bison.simple)
- A supported (check make_gnu.bat for a list) C compiler
(with all the envvars set (PATH, LIB, INCLUDE, etc...))
- GNU-make if you want to use it with some other C compiler than GCC
(as GCC already comes with GNU-make)
- Harbour source
- Around 10-15MB of free disk space for each separate platform/compiler
combinations.
To build Harbour using GNU-make:
- Set the required two envvars (check MAKE_GNU.* for them)
- Run make_gnu.*
To build Harbour using non-GNU make with BCC 4.x, 5.x:
- make_b32.bat
To build Harbour using non-GNU make with MSVC:
- make_vc.bat
To build a final executable, see above, but use bin/bld*.*
instead of make*.*
Viktor Szakats
c:\harbour\doc\howtorel.txt
/*
* $Id: howtorel.txt 6676 2006-05-30 09:09:17Z ckedem $
*/
How to create and tag a new release
===================================
By Przemyslaw Czerpak (druzus/at/priv.onet.pl)
1. Make full update of your local CVS copy with:
cvs -z3 update -A -P -d -R harbour
with the above unused empty directories will be removed
from your repository copy.
Please check if all your files are unmodified. You can redirect
stdout output from cvs command to a file to see if all files are
exactly the same.
2. Update files which contain harbour release number. Now these are:
harbour.spec
include/hbver.h
3. Set proper release date in whatsnew.txt and if necessary update
release informations. Also add the exact tag name to this file,
for example "tag: build46".
4. Update ChangeLog file and commit your modifications.
5. Update hbver.h with ChangeLog file ID and your last entry ID.
6. Tag the CVS tree with the new release tag:
cvs tag -t -F -D
for example:
cvs tag -t -F -D "2006-05-29 16:00" build46
With the above you can also "re-tag" already set tag so be careful
and use re-tag repository _only_ if it's really necessary.
With properly tagged CVS any one who wants to create Harbour release
binaries should make:
cvs -z3 co -r harbour
for example:
cvs -z3 co -r "build46" harbour
to be sure that local repository copy is exactly the same as the one
tagged as new release. The first commit after cvs tagging should also
change the version number and ChangeLog IDs in harbour.spec and
include/hbver.h for easier locating possible mistakes when release
binaries are created.
c:\harbour\doc\howtosvn.txt
/*
* $Id: howtosvn.txt 8253 2008-01-31 11:36:57Z rglab $
*/
HOW TO USE THE SVN
------------------
Content
=======
1.1 Here's how to prepare for uploading to the SVN server
1.2 Here's how to upload your changes to the SVN server
1.3 Here's how to format your ChangeLog entries
1.4 Here's how to use the SVN server in anonymous read-only mode
1.5 Things to do to avoid damaging the SourceForge SVN tree
1.6 How to add SVN ID to new files
1.1 Here's how to prepare for uploading to the SVN server
=========================================================
by Viktor Szakats
1) Read the Harbour FAQ (http://www.harbour-project.org/faq), monitor the
mailing-list (http://www.harbour-project.org/faq/harbour34.html),
consult with the developers, make contributions. This way your chances
are high to get a RW access to the repository.
2) Before uploading anything you'll need Developer (RW) status for the
Harbour SVN server. To get this please make a request on the list,
or contact the Harbour Administrators. Note that getting Developer
status is not an automatic process.
3) You'll need an SVN client for your platform.
4) Do a complete checkout to get the fresh source tree.
1.2 Here's how to upload your changes to the SVN server
=======================================================
by Viktor Szakats
1) Do the changes in the source, and in parallel modify ChangeLog
2) Go online (if needed)
3) SVN UPDATE
4) Resolve all conflicts
5) Copy the last ChangeLog entry to the clipboard
6) SVN COMMIT --editor-cmd notepad.exe --username sfuser
Change notepad.exe to the editor of your choice and platform.
Change "sfuser" to your sf.net username.
7) New email message, paste the new ChangeLog entry
8) Copy and paste the ChangeLog entry header to the subject after
"CHANGELOG: "
9) The SVN pops up a window with the changed filenames
10) Check if all the changed filenames are referred in the ChangeLog entry,
if not, make the corrections and start again
11) Paste the ChangeLog entry header to the SVN window, save, exit
12) SVN is now uploading,
if there are any errors, make the corrections and start again
13) Always check if the upload session ended without errors.
14) Send the email message containing the changes
15) Go offline (if needed)
alternative method:
by Ryszard Glab
1) Do the changes in the source
2) Run SVN UPDATE redirecting the output into a file
(for example: "SVN update -d >.log"
3) Resolve all conflicts, run SVN update again (see point 2), recompile
all sources, fix all errors
4) Run SVN STATUS redirecting the output into a file
(for example: "svn status >.log"
5) Copy all names of modifed, added or deleted files (files marked with
'M', 'A' or 'D' flag) from update log into a ChangeLog
6) Write necessary comments in the ChangeLog
7) Save all your changes from ChangeLog into a file
8) Run SVN UPDATE again
9) Commit changes running:
SVN commit -F file_with_saved_ChangeLog_changes --username sfuser
10) Mail file_with_saved_ChangeLog_changes as an email body (do not
send it as an attachment) to the harbour list
Important notes:
1) *Always* add a ChangeLog entry when committing to the SVN.
2) When adding a new file to the SVN, always use lower case 8.3
filenames (*), add a SVN ID header to the file, don't use tabs
in the file, end the file with a newline char.
Possibly consult other Developers about the new filename and file
placement.
Add the new filename to the related makefiles.
(*) There are some exceptions: ChangeLog.*, Makefile, COPYING,
ERRATA and TODO for example.
1.3 Here's how to format your ChangeLog entries
===============================================
by Viktor Szakats
- Always add new entries to the top of the ChangeLog file.
- Add an entry header using this format:
YYYY-MM-DD HH:MM UTC[-|+]hhmm Your Full Name
For example:
2000-05-27 23:12 UTC+0100 Viktor Szakats
- Add a entry body which lists all filenames changed, all of
them with full path spec. Mention the name of the changed function or
macro. Describe what you've changed, the reasons, and other comments
and explanations you find useful. If the change needs some related work
to be done by someone else (documentation, makefile), make a clear note
about this.
Group the related changes into logical sections separated by empty lines.
Sample:
* dir/filenam1.txt
+ dir/filenam2.txt
- dir/filenam3.txt
* Changed, bla-bla
! Fixed
% Optimized
+ Added
- Removed
; Comment
Note that using these specific marks is preferred although not a
requirement.
- Leave an empty line between the header and body and one after the body.
1.4 Here's how to use the SVN server in anonymous read-only mode
================================================================
Please read the following FAQ entry:
http://www.harbour-project.org/faq/harbour25.html
1.5 Things to do to avoid damaging the SourceForge SVN tree
===========================================================
by David G. Holm
1) Always do your Harbour development using your local SVN tree. Do not
do your development outside your local SVN tree and then copy your
changes into your local SVN tree to commit them, because that leads
easily to accidentally overwriting changes made by others, because
you didn't notice that a module that you were also working on was
changed by someone else. By always doing Harbour development using
your local SVN tree, changes made by others will be merged with your
changes and you only need to recompile and retest before committing.
2) Always run 'SVN update' from the 'harbour' directory before you run
'SVN commit'. Ideally, you should redirect the output from the update
to a file and look at the results to confirm that you are ready to do
a commit. Any files marked M, A or D are files that you have modified
or are adding or deleting. Confirm that you have comments for all of
them in your ChangeLog entry. If you see many modules marked P or U,
then you need to recompile and retest before you commit your changes.
If you see any conflicts reported in the update output, then you need
to resolve them before committing. SVN is generally good at merging
changes, so you probably won't see conflicts very often, but if you
edit the ChangeLog file before you run 'SVN update' and other changes
have been committed by others, then ChangeLog will have conflicts. To
resolve those conflicts, simply remove the conflict markers. What I do
to avoid conflicts to ChangeLog is to record my changes in changes.txt
and then copy them into ChangeLog between the update and the commit.
1.6 How to add SVN ID to new files
==================================
by Maurilio Longo
When a new file is added to SVN tree it has not a SVN ID.
SVN IDs look like this:
/*
* $Id: howtosvn.txt 8253 2008-01-31 11:36:57Z rglab $
*/
To add one to a file lacking it simply put as first lines:
/*
* Chr(36) + "Id" + Chr(36)
*/
I can't write it here because SVN server would change it as soon as I
commit this file, but second line should not have Chr(36) but $ signs
and no spaces between dollar sign and Id.
as soon as you commit your file SVN ID string will be expanded
by SVN server to full length.
Note that last dollar sign is mandatory.
Run these commands and commit:
svn propset svn:keywords "Author Date Id Revision" "filename"
svn propset svn:eol-style native "filename"
c:\harbour\doc\hrb_faq.txt
/*
* $Id: hrb_faq.txt 9243 2008-08-25 21:36:00Z vszakats $
*/
.hrb FAQ list 1999/05/19:
Current only available in a 32bit Intel version.
HRB structure (also known as Harbour Portable Objects) and
Runner (also known as TugBoat, Stubbing Executables (not yet) )
To create a runner :
C:..> bld32exe runner
Once the runner is created,
To create a .hrb and run it :
C:..> hbrun
If you just want to run a .hrb file :
C:..> runner
If you just want to create a .hrb file :
Use command-line switch -gHRB when invoking Harbour
To see the contents of a .hrb file :
C:..> clipper readhrb /n/a/w {I am sorry}
C:..> blinker @readhrb
C:..> readhrb {What do mean consistent}
If it goes too fast a readhrb.out is created containing the screen
output.
To run a .hrb file within a .prg (only possible if the .prg is compiled as a
.hrb file) :
HB_Run( )
-------------------------------------------------------------------------------
HRB structure (also known as Harbour Portable Objects) and
Runner (also known as TugBoat, Stubbing Executables (not yet) )
Version 1.0
The ultimate version will of course feature more, but let's just stick to the
minimal requirements.
The .hrb structure consists :
Long containing the number of symbols
{
Name of symbol
Scope of symbol
Link type :
0 = NO_LINK (ie DATA symbol)
1 = FUNCTION* in .prg itself
2 = EXTERN. Link function pointer at run-time.
}
Long containing the number of functions
{
Name of function
Length of function
PCode of function
}
* Since the module name itself is a symbol during compilation. ProcName()
was recognized as an internal function.
During the run-time link the runner therefore checks whether the compiler
has correctly identified a symbol as contained in .prg itself.
c:\harbour\doc\lang_id.txt
/*
* $Id: lang_id.txt 2175 2000-02-13 11:13:27Z vszel $
*/
Language codes
==============
RFC ID Name ISO Language ID
------ ------------------------------ ---------------
AA Afar AA
AB Abkhazian AB
AF Afrikaans AF
AM Amharic AM
AR Arabic AR
AR-AE Arabic (U.A.E.) AR
AR-BH Arabic (Bahrain) AR
AR-DZ Arabic (Algeria) AR
AR-EG Arabic (Egypt) AR
AR-IQ Arabic (Iraq) AR
AR-JO Arabic (Jordan) AR
AR-KW Arabic (Kuwait) AR
AR-LB Arabic (Lebanon) AR
AR-LY Arabic (Libya) AR
AR-MA Arabic (Morocco) AR
AR-OM Arabic (Oman) AR
AR-QA Arabic (Qatar) AR
AR-SA Arabic (Saudi Arabia) AR
AR-SY Arabic (Syria) AR
AR-TN Arabic (Tunisia) AR
AR-YE Arabic (Yemen) AR
AS Assamese AS
AY Aymara AY
AZ Azerbaijani AZ
BA Bashkir BA
BE Byelorussian BE
BG Bulgarian BG
BH Bihari BH
BI Bislama BI
BN Bengali, Bangla BN
BO Tibetan BO
BR Breton BR
CA Catalan CA
CO Corsican CO
CS Czech CS
CY Welsh CY
DA Danish DA
DE German DE
DE-AT German (Austria) DE
DE-CH German (Swiss) DE
DE-LI German (Liechtenstein) DE
DE-LU German (Luxembourg) DE
DZ Bhutani DZ
EL Greek EL
EN English EN
EN-AU English (Australian) EN
EN-BZ English (Belize) EN
EN-CA English (Canadian) EN
EN-GB English (British) EN
EN-IE English (Ireland) EN
EN-JM English (Jamaica) EN
EN-JP English (Japan) EN
EN-NZ English (New Zealand) EN
EN-TT English (Trinidad) EN
EN-US English (USA) EN
EN-ZA English (South Africa) EN
EO Esperanto EO
ES Spanish ES
ES-AR Spanish (Argentina) ES
ES-BO Spanish (Bolivia) ES
ES-CL Spanish (Chile) ES
ES-CO Spanish (Colombia) ES
ES-CR Spanish (Costa Rica) ES
ES-DO Spanish (Dominican Republic) ES
ES-EC Spanish (Ecuador) ES
ES-GT Spanish (Guatemala) ES
ES-HN Spanish (Honduras) ES
ES-MX Spanish (Mexican) ES
ES-NI Spanish (Nicaragua) ES
ES-PA Spanish (Panama) ES
ES-PE Spanish (Peru) ES
ES-PR Spanish (Puerto Rico) ES
ES-PY Spanish (Paraguay) ES
ES-SV Spanish (El Salvador) ES
ES-UY Spanish (Uruguay) ES
ES-VE Spanish (Venezuela) ES
ET Estonian ET
EU Basque EU
FA Persian FA
FI Finnish FI
FJ Fiji FJ
FO Faeroese FO
FR French FR
FR-BE French (Belgian) FR
FR-CA French (Canadian) FR
FR-CH French (Swiss) FR
FR-LU French (Luxembourg) FR
FY Frisian FY
GA Irish GA
GD Scots Gaelic GD
GL Galician GL
GN Guarani GN
GU Gujarati GU
HA Hausa HA
HE Hebrew HE
HI Hindi HI
HR Croatian HR
HU Hungarian HU
HY Armenian HY
IA Interlingua IA
ID Indonesian ID
IE Interlingue IE
IK Inupiak IK
IN Indonesian (-) IN
IS Icelandic IS
IT Italian IT
IT-CH Italian (Swiss) IT
IU Inuktitut IU
IW Hebrew (-) IW
JA Japanese JA
JI Yiddish (-) JI
JW Javanese JW
KA Georgian KA
KK Kazakh KK
KL Greenlandic KL
KM Cambodian KM
KN Kannada KN
KO Korean KO
KS Kashmiri KS
KU Kurdish KU
KY Kirghiz KY
LA Latin LA
LN Lingala LN
LO Laothian LO
LT Lithuanian LT
LV Latvian, Lettish LV
MG Malagasy MG
MI Maori MI
MK Macedonian MK
ML Malayalam ML
MN Mongolian MN
MO Moldavian MO
MR Marathi MR
MS Malay MS
MT Maltese MT
MY Burmese MY
NA Nauru NA
NE Nepali NE
NL Dutch NL
NL-BE Dutch (Belgian) NL
NO Norwegian NO
NO-BOK Norwegian (bokmal) NO
NO-NYN Norwegian (Nynorsk) NO
OC Occitan OC
OM (Afan) Oromo OM
OR Oriya OR
PA Punjabi PA
PL Polish PL
PS Pashto, Pushto PS
PT Portuguese PT
PT-BR Portuguese (Brazilian) PT
QU Quechua QU
RM Rhaeto-Romance RM
RN Kirundi RN
RO Romanian RO
RO-MO Romanian (Moldavia) RO
RU Russian RU
RU-MO Russian (Moldavia) RU
RW Kinyarwanda RW
SA Sanskrit SA
SD Sindhi SD
SG Sangro SG
SH Serbo-Croatian SH
SI Singhalese SI
SK Slovak SK
SL Slovenian SL
SM Samoan SM
SN Shona SN
SO Somali SO
SQ Albanian SQ
SR Serbian SR
SS Siswati SS
ST Sesotho ST
SU Sundanese SU
SV Swedish SV
SV-FI Swedish (Finland) SV
SW Swahili SW
TA Tamil TA
TE Tegulu TE
TG Tajik TG
TH Thai TH
TI Tigrinya TI
TK Turkmen TK
TL Tagalog TL
TN Setswana TN
TO Tonga TO
TR Turkish TR
TS Tsonga TS
TT Tatar TT
TW Twi TW
UG Uigur UG
UK Ukrainian UK
UR Urdu UR
UZ Uzbek UZ
VI Vietnamese VI
VO Volapuk VO
WO Wolof WO
XH Xhosa XH
YI Yiddish YI
YO Yoruba YO
ZA Zhuang ZA
ZH Chinese ZH
ZH-CN Chinese (PRC) ZH
ZH-HK Chinese (Hong Kong) ZH
ZH-SG Chinese (Singapore) ZH
ZH-TW Chinese (Taiwan) ZH
ZU Zulu ZU
c:\harbour\doc\license.txt
/*
* $Id: license.txt 8113 2007-12-01 02:42:32Z vszakats $
*/
THE HARBOUR PROJECT COMPILER LICENSE
====================================
Note: This license applies to most of the files in the source/compiler
directory.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit
their web site at http://www.gnu.org/).
THE HARBOUR PROJECT LIBRARY LICENSE
===================================
Note: This license applies to most of the files in the include directory,
source directory, and subdirectories.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this software; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
As a special exception, the Harbour Project gives permission for
additional uses of the text contained in its release of Harbour.
The exception is that, if you link the Harbour libraries with other
files to produce an executable, this does not by itself cause the
resulting executable to be covered by the GNU General Public License.
Your use of that executable is in no way restricted on account of
linking the Harbour library code into it.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License.
This exception applies only to the code released by the Harbour
Project under the name Harbour. If you copy code from other
Harbour Project or Free Software Foundation releases into a copy of
Harbour, as the General Public License permits, the exception does
not apply to the code that you add in this way. To avoid misleading
anyone as to the status of such modified files, you must delete
this exception notice from them.
If you write modifications of your own for Harbour, it is your choice
whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice.
THE OLD HARBOUR PROJECT LIBRARY LICENSE
=======================================
Note: This license only applies to the following files:
source\rtl\philes.c
source\rtl\binnum.c
source\lang\msgeu.c
source\lang\msgsl437.c
source\lang\msgsl852.c
source\lang\msgsliso.c
source\lang\msgslwin.c
source\lang\msgsr852.c
source\lang\msgsriso.c
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version, with one exception:
The exception is that if you link the Harbour Runtime Library (HRL)
and/or the Harbour Virtual Machine (HVM) with other files to produce
an executable, this does not by itself cause the resulting executable
to be covered by the GNU General Public License. Your use of that
executable is in no way restricted on account of linking the HRL
and/or HVM code into it.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit
their web site at http://www.gnu.org/).
THE HARBOUR PROJECT CONTRIB LICENSE
===================================
There is no one single license that applies to the Harbour Project
contrib files. Some files use the Harbour Project Compiler license.
Some files use the Harbour Project Library license. Some files use
the old Harbour Project Library license. Some files may even use other
types of free software or open source software licenses. Some files
have been donated to the public domain. If you use any of the contrib
files, you need to investigate the license that applies to each file.
c:\harbour\doc\linux1st.txt
/*
* $Id: linux1st.txt 9182 2008-08-16 11:21:56Z vszakats $
*/
Linux primer
============
Ubuntu/Debian distro
--------------------
Packages needed to cleanly build Harbour:
(Tested with Ubuntu 7.04 and 8.04)
For GTCRS terminal lib:
sudo apt-get install libncurses-dev
For GTSLN terminal lib:
sudo apt-get install libslang2-dev
For GTXWC terminal lib:
sudo apt-get install libx11-dev
For console mouse support in GTTRM, GTSLN and GTCRS:
sudo apt-get install libgpmg1-dev
For contrib/hbodbc lib:
sudo apt-get install unixodbc-dev
For contrib/hbcurl lib:
sudo apt-get install libcurl4-openssl-dev
or
sudo apt-get install libcurl4-gnutls-dev
For contrib/hbfbird lib:
sudo apt-get install libfirebird2.0-dev
For contrib/hbfimage lib:
sudo apt-get install libfreeimage-dev
For contrib/hbgd lib:
sudo apt-get install libgd2-xpm-dev
or
sudo apt-get install libgd-xpm-dev
For contrib/hbmysql lib:
sudo apt-get install libmysqlclient15-dev
For contrib/hbpgsql lib:
sudo apt-get install libpq-dev
For contrib/hbgf/hbgfgtk lib:
sudo apt-get install libgtk2.0-dev
sudo apt-get install libglib2.0-dev
For contrib/rddads lib:
Download and install 'Advantage Client Engine API for Linux' package
(f.e. aceapi-9.00.0.0.tar.gz)
For contrib/hbhpdf lib:
Download and './configure', 'make install' libharu
from http://libharu.org/
openSUSE distro
---------------
You'll need these packages to compile certain contribs and optional
Harbour modules:
- xorg-x11-devel
- postgresql-devel
- gtk2-devel
- ncurses-devel
- slang-devel
- unixodbc-devel
- gd-devel
- libmysqlclient-devel
For contrib/rddads lib:
Download and install 'Advantage Client Engine API for Linux' package
(f.e. aceapi-9.00.0.0.tar.gz)
For contrib/libharu:
- Download and './configure', 'make install' libharu
from http://libharu.org/
- libpng-devel
- zlib-devel
Notes by Scott Johnson
-------------------------------------------------
Ok, I finally got something to run. The code I compiled was standard
Clipper 5.2 code pulled directly from a dos/win box and was working
properly there.
I'm compiling under Debian Sarge which for their own reasons are using
the Alpha Build 44.0. It was installed with the standard apt-get
harbour. I did this to pretty much ensure that the install wasn't
tainted by any of my previous attempts at getting this to work.
The first thing I checked was for the bld.sh. it didn't exist so I did
the cut/paste thing from this list (thank you) and set out on my
adventure.
First off, set your environment variables. If you want to set this up
for your shell to do it automagically go for it. That's beyond what I
want to cover here.
export HB_ARCHITECTURE=linux
export HB_BIN_INSTALL=/usr/bin
export HB_LIB_INSTALL=/usr/lib/harbour
export HB_INC_INSTALL=/usr/include/harbour
export HB_COMPILER=gcc
export HB_GT_LIB=gtcrs
Since we created the bld.sh from scratch, I dropped it in the /usr/bin
directory where the rest of the harbour binaries exist.
chmod +x bld.sh
Now I go to where my actual clipper/harbour source code is.
The files I have are inv.prg, csrc.prg, cmenu.prg and citem.prg. The
dbf files are already created and exist in the same directory, but
that's just me. I pulled those over with the dos application.
Next, I issued the following command
bld.sh inv csrc cmenu citem
This ran through it's gyrations, made the c source and attempted to link
it. Hey, this is great although it bombed out with an unresolved
external to dbfdbt. Ok, so that's a library. I can do this
I jumped into the bld.sh file and hunted down the gcc line. It's quite
a ways down into the file, but you'll need to find the one appropriate
for your system (mind was right after the last check for GT_LIB where it
leaves it as gtstd if you don't set something.
On the gcc line, you'll see a section like "-L$HB_LIB_INSTALL -ldebug"
and so on; add "-ldbfdbt" (without the quotes of course). I added it
right after -lrdd, but I don't know if that's important or not. Maybe
somebody can correct me there.
After I saved it, I went back and issued the same bld.sh command as I
did above, and lo! It just worked.
./inv
As a side note, gtstd is probably not going to be very helpful for you
in linux if you have any SAY/GET's as screen positioning (especially if
you use xterm) won't be handled correctly. Same with gtpca. Gtcrs
seemed to work properly in my environment.
I know this is pretty sparse as far as any kind of documentation is
concerned, and I might be doing things I don't need to, and not doing
things that make people cringe. It's a start though and maybe some
folks can clean it up a bit and add/remove things that are important.
At least this worked on my particular Debian system. Your mileage may
vary and other distributions will probably have their own setups and
issues.
c:\harbour\doc\pcode.txt
/*
* $Id: pcode.txt 2248 2000-03-02 11:58:22Z vszel $
*/
The Clipper OBJ and pcode model (GNU|Open|Clipper project)
==========================================================
Let's consider the following Clipper sample Test.prg:
function Main()
? "Hello world!"
return nil
Once it gets compiled into a OBJ, what is there inside it?
In fact, what we get is the equivalent to the following C language
application:
SYMBOL symbols[] = { ... };
void MAIN( void )
{
BYTE pcode[] = { ... };
VirtualMachine( pcode, symbols );
}
Basically, Test.prg source code has been converted into a sequence
of pcode bytes contained in the array pcode[] = { ... }. All our MAIN()
function does is invoke, at run-time, a Clipper VirtualMachine() that will
process those pcode bytes.
Let's review the Test.prg pcode structure in more detail:
0000 (2A) LINE 0 2A 00 00
0003 (2A) LINE 3 2A 03 00
0006 (13) SYMF [QOUT] 13 02 00
0009 (01) PUSHC "Hello world!" 01 ...
0018 (27) DO(1) 27 01 00
001B (2A) LINE 5 2A 05 00
001E (7B) UNDEF 7B
001F (79) SAVE_RET 79
0020 (1E) JMP 0023 1E 00 00
0023 (60) ENDPROC 60
We could define a hbpcode.h file to better read that pcode:
hbpcode.h
#define LINE 0x2A
#define SYMF 0x13
#define PUSHC 0x01
#define DO 0x27
#define UNDEF 0x7B
...
So finally it will look like:
BYTE pcode[] = { LINE, 0, 0,
LINE, 3, 0,
SYMF, 2, 0,
PUSHC, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!', '0',
DO, 1, 0,
LINE, 5, 0,
UNDEF,
SAVE_RET,
JMP, 0, 0,
ENDPROC };
And what is SYMBOL symbols[] ? Clipper creates a symbol table in
the OBJ that later on will be used to create a dynamic symbol table
shared by the entire application. Each of those symbols has the following
structure:
typedef struct
{
char * szName; // Clipper in fact keeps an array here (11 bytes).
BYTE bScope;
LPVOID pVoid;
} SYMBOL;
#define PUBLIC 0 // the scope of the function!
SYMBOL symbols[] = { { "MAIN", PUBLIC, MAIN },
{ "QQOUT", PUBLIC, QQOUT } };
Let's remember that the name of a function (MAIN, QQOUT) is the address of the
function, so our symbol table will be ready to use it to jump and execute any
linked function.
In fact, the pcode SYMF 2, 0 in our sample, will instruct the VirtualMachine()
to use the 2 symbol, which is QQOUT.
Let's read the pcode:
LINE 0, 0 => We are located at line 0
LINE 3, 0 => We are located at line 3
SYMF 2, 0 => We are going to call QQOUT from our symbol table
PUSHC ... => This string is going to be used as a parameter
DO 1, 0 => ok, jump to QQOUT and remember we have just supplied 1 parameter
LINE 5, 0 => We are back from QQOUT and we are located at line 5
UNDEF => we are going to return this value (NIL)
SAVE_RET => Ok, return it
JMP 0 => We don't jump to elsewhere, just continue to next pcode byte
ENDPROC => This is the end. We have completed this function execution
All these instructions will be evaluated from our VirtualMachine() function
(Clipper names it _plankton()). All functions end using ENDPROC, so when
the VirtualMachine() finds ENDPROC it knows it has reached the end of a
function pcode.
Now that we clearly understand this basic model we are ready to start
implementing 'production rules' on our yacc (clipper.y) syntax to generate
the specific output file (test.c) with the above structure (or we could
easily just generate the OBJ file for it).
to be continued...
Antonio Linares
www.fivetech.com
c:\harbour\doc\pp.txt
/*
* $Id: pp.txt 6906 2006-11-13 19:49:57Z druzus $
*/
PP description
==============
By Przemyslaw Czerpak (druzus/at/priv.onet.pl)
Hi All,
I collected this text from notes I created when I was analyzing
Clipper PP and then I was updating it in few places. Sorry but
I do not have enough energy to check it and update. It's much
shorter then I planed and it does not contain many important
things I encoded in new PP code. Sorry you will have to look at
new code because now I do not want to think about PP any more.
After last days I hate PP and I'd be very happy if I could forget
about it for at least few days. I spend much more time on it then
I planed and I'm really frustrated with the brain off job I was
making in last days.
-----------------------------------------------------------------------------
1. Clipper's PP is a lexer which divides source code into tokens
and then operates on these tokens and not on text data. This is the
main reason why current [x]Harbour PP cannot be Clipper compatible.
Tokenization is the fundamental condition which implicates a lot of
Clipper PP behavior and as long as we do not replicate it then we
will never be able to be Clipper compatible them.
Even such simple code cannot be well preprocessed and compiler by
current [x]Harbour PP:
#define a -1
? 1-a
and it cannot be fixed with current code without breaking some
other things, f.e. match markers which depends on number of spaces
between tokens. So at start we have to forget about updating current PP.
It will never be Clipper compatible and cannot be because it's not a
lexer.
2. During dividing input data to tokens and later in finding match patterns
Clipper PP always try to allocate the biggest possible set of input data
as a given type even if it can break some possible other method of
input data serialization. This can be seen in wild match marker <*marker*>
behavior or optional clause in match pattern, operator tokenization, etc.
It greatly simplify the code though introduce some limitations,
f.e.:
#xcommand CMD [FROM] FROM <*x*> => ? #
or:
#xcommand CMD , => ? #
or:
#xcommand CMD <*x*> END => ? #
are accepted by Clipper PP but they cannot match any line.
3. Preprocessor should extract all quoted strings and create separated
tokens from them. The string tokens contents cannot be modified later
by any rules. Quoting by [] create string tokens when it's not just
after keyword, macro or one of closing brackets: ) } ]
We will have to change it to keep working already existing extensions
like accessing string characters with [] operator so I suggest to change
this condition and not create string token when it follows also constant
value of any type - not only strings. It will be usable for scalar
classes and overloading [] operator, f.e. someone can create LOGICAL
class where:
.T.[1] => ".T.", .T.[2] => "TRUE", .T.[3] => "YES"
The opening square bracket '[' has to be closed with ']' in the same line.
Such quoting has very high priority like normal string quoting. f.e:
? [ ; // /* ]
should generate:
QOUT( " ; // /* " )
This implicates one important thing: PP has to read whole physical
line from file, then convert it to tokens and if necessary (';' is the
last token after preprocessing) read next line(s).
There is also one exception to the above. When Clipper PP finds '['
character and previous token is keyword or macro then it always checks
for closing bracket and if in scanned text it will find odd numbers
of other text delimiters ('") then ignore the type of previous token
and always creates strings. This behavior breaks some valid code. F.e.
Clipper cannot compile code like:
x := a[ f("]") ] $ "test"
or:
x := a[ f( "'" ) ] $ "test"
If it find closing ']' without odd number of other text delimiters
then it creates differ token then for other opening square brackets '['
open_array_index which has differ meaning in later preprocessing
and allow to convert group of tokens inside to string by compiler.
If something is not recognized by preprocessor as string token or
open_array_index then it should never become string token. It doesn't
matter how it will be preprocessed later, f.e.:
#define O1 [
#define O2 ]
? O1 b O2
should generate:
QOUT( [ b ] )
not:
QOUT( " b " )
but:
#command A => ?
A [ b ]
generate also:
QOUT( [ b ] )
and in this case Clipper compiler makes conversion to string.
It means that only at initial line preprocessing preprocessor decides
what can or cannot be string token. I think that we do not have to
exactly replicate this behavior and we should allow string conversion
also when '[' is not marked as open_array_index in final preprocessor
pass which will create string token from the group of tokens inside '['
and ']' tokens using the initial stringify condition which checks type
of token before.
In fact with new PP such operation will be done by still existing
lexer after preprocessing and converting the preprocessed token to string
which is then once again divided into tokens by FLEX or SIMPLEX. It's
redundant and because neither FLEX nor SIMPLEX are MT safe and both
have limitations like maximum line size we will not be able to fully
benefit from the new code (read below about it).
4. # directives tokenization.
In #define directive strings in result pattern cannot be quoted by [].
They always will be used as array index or (in #[x]command
and #[x]translate) as optional expression (when not quoted by '\').
Characters like [] are not allowed in #define match pattern.
Quoting by [] in #[x]command and #[x]translate match pattern
produce optional clause. The left square bracket can be quoted by \ to
disable this special meaning and in such case Clipper PP
generates array tokens but they are not marked as open_array_index
when in the code they are. It causes that in code like
#command A B\[C] => QOUT("A B[C]")
A B[C]
A B[C] is not preprocessed because in #command match pattern '[' is
not open_array_index and PP cannot find matching tokens.
Anyhow it's possible to create passing match pattern which will use [].
It's enough to create matching pattern for the code which have [] not
translated to string and not bound
with keyword. As I wrote above it will be possible when '[' is after
one of the closing brackets: ')', '}' or ']', f.e.:
#command A }\[C] => QOUT("A }[C]")
A }[C]
Will be perfectly translated. For me it seems to be limitation of
Clipper PP implementation (probably it's a side effect of some internal
solutions) or a bug. Not something intentionally designed. It's highly
possible it's a hack to pass to compiler some additional information
about preprocessed tokens because in Clipper PP seems to be also the
compiler lexer. I do not think that we should try to keep strict
compatibility in PP translation and also introduce the array ID tokens
before preprocessing. Such operation can be done after preprocessing
but this is differ subject.
The important conclusion is that #directives should be preprocessed
in differ way then normal lines. In general # as first line token disable
using [] as string delimiters.
5. Clipper allow to quote strings using also back apostrophe (`) as
string begin marker and normal apostrophe as string end marker, f.e:
? `Hello World'
works perfectly.
6. String tokens can be part of match pattern as any other tokens, they
are not case sensitive during preprocessing so it's important to early
detect and convert data inside [] to string token.
7. NIL is preprocessed rather as keyword then constant value. At least it
behaves like a keyword and I cannot find anything what can suggest
something differ.
8. Numbers are not converted and stored as other tokens in literal
form. It's important to not change the numbers representation or
compiler will have problems with calculating declared size and
decimal places. The number tokens can be in the following form:
[0-9]*[\.[0-9]+]. Token is ended on first character which does not
pass the above expression and this is the first character of next
token. This behavior will interact with Harbour extensions for
hexadecimal numbers 0x[0-9A-Z] and date constants 0d[0-9] and we
will have to generate separated tokens for them. For strict compatibility
we can disable it and create final tokens after preprocessing but I do
not think we have to be such strictly compatible.
9. Logical value is a single token, .N. is translated to .F. and
.Y. to .T.
10. Multi character operators are parsed as single token. It's important
to keep the list of such operators and properly pars them at beginning
or later we will have problems.
11. Clipper PP allow to use only characters in ASCII range from 32 to 125
and some control codes with special meaning.
'\n' is line terminator
'\t' when not inside quoted string is converted to 4 spaces
'\r' is always stripped, also from quoted strings
'\0' stop line processing, like '\n' but the rest of line is ignored
^z (chr(26)) works _exactly_ like '\n'
All other characters are illegal
12. All characters which are not keyword, string, numbers and know
operators are used as some pseudo binary operator tokens. We allow to
use characters with ASCII code greater then 125 then I suggest to define
for these characters new token called TEXT so they will not be pseudo
operators and still will could use them.
13. Clipper have special macro token which marks all input data in the
following form: [&[.[]]]+[&]
It's a single token which has special meaning in preprocessing and
we have to replicate it.
14. The expression is a list of keywords, macros and constant values
separated by one or more of other tokens. If the other token is
one of binary operators which is marked that need valid expression
in some internal PP table then PP check if next token is keyword,
number, string or operator marked as left unary followed by non operator
token and if it's not then end the expression.
AFAIK only -, --, ++, & operators are marked as left unary operators
and +, !, @ don't what can break some expressions.
Also the above behavior causes that '-' cannot be repeated many times
as left unary operator (multiple negation) what can break some valid
expressions too. The following tokens are marked as binary operators
which needs valid expression as next token: +, -, *, /, %, ^
The expression can be groped in (), {}, or [] and in such case
PP looks for corresponding closing bracket but it does not respect
other type of brackets and not update nested other bracket counters
only for the currently processed pair. As long as the expression is not
part of some other preprocessor rule which will change number
of different brackets then it seems to be safe because at this level
all strings should be separated tokens and each valid Clipper expression
correctly closes brackets. User should only be careful with using []
for strings quoting - see above conversion to strings. '[' works like
a group operator only if it's not the first token. See below operators
which cannot much regular match marker.
The groped expression list is also ended when end of line is reach or ';'
token. The ',' and closing brackets ), ], } tokens end the expression when
bracket counter is 0.
Some operators like :=, +=, -=, /=, *=, %=, ^=, **=, =, ==, and [ if
is not marked as open_array_index cannot match regular match marker as
first token, seems that they are marked as needing left side expression.
Of course closing tokens ',', ';', ')', '}', ']' also cannot match
regular match marker as first token.
Tokens are equal only if after preprocessing they have the same type and
the same value. It means that "!=" is equal to "<>" but not equal with "#"
There is exception to this rule in restricted match marker and macro token
15. Match markers.
regular match marker, matches non empty expression, cannot
match single closing parenthesis and some operators, see above.
list match marker, matches maximal number of comma separated
regular match markers, if the last token in parsed expression
is operator which need right valid expression and next token
is not such valid expression then it stops checking for
farther expressions even if the next token is comma,
it accepts empty separated regular expressions but cannot be
empty itself. It cannot also much anything starting with
closing bracket or some operators, see above, it's the same
behavior as in regular much marker.
restricted match marker, checks if next token(s) is/are
exactly the same as one of the word in pattern. Words are
comma separated expressions. Word can be empty but as both
markers above it cannot match anything starting with closing
bracket or some chosen operators (see above). If the last
token in one of restricted expression in the marker is '&'
then it has special meaning. It will match any macro tokens.
But only in such case. If it's not the last token in one
of comma separated expressions then it will work like any
other ones.
<*idMarker*> wild match marker, matches all tokens to the end of input
line, the expression should not be stopped by ; token
or any other ones. It's the only one marker which will match
expressions starting with closing brackets and operators which
need left side expression.
<(idMarker)> extended expression match marker matches any number of tokens
which do not have leading spaces until end of token list,
comma (,) and or (;). Empty expressions are not allowed.
It cannot match closing bracket: ')' and ']' but can match '}'
and some operators. It cannot match expressions
starting with '[' token and if the expressions start with
'(' token then it drops the rule which check spaces but
maps the same tokens as regular match marker.
When the expression is created from tokens and match marker is followed
by non optional token(s) then the expression is immediately finished when
the first token following match marker is found and parentheses
counter is 0. This additional stop condition does not work for wild
match markers: <*idMarker*> which can be used only as the last part
of match pattern or the pattern will never much anything. We can add
here some extension to allow defining stop condition for wild match
markers in the future. It will not interact with Clipper compatibility
because rules which have some additional tokens in match pattern after
wild marker do not work with Clipper PP at all.
The non optional token which can stop the expression is passed as
stop condition also to all nested optional match expressions which
are just before it and this token is used instead of other stop tokens
which can exist inside nested optional match pattern. This code
illustrates it. Clipper does not preprocess the TR2.
#xtranslate TR1 [ D] => ! [#] !
#xtranslate TR2 [ D] C => ! [#] !
#xcommand CMD <*x*> => QOUT( # )
proc main()
CMD $ TR1 a + b + c + d c
CMD $ TR2 a + b + c + d c
return
There is also a hidden aspects of match markers defined by result
pattern. Each match marker can have one of four possible states:
1. ignore matched expression - when it's not part of result pattern
We do not need any special case to implement this - it will be
enough to not define result holder for such markers
2. accept only one matched expression and refuse accepting any other
- when it's used at least once inside non optional part of result
pattern
3. accept multiple matched expression - when it's used only in optional
part of result pattern
4. accept first matched expression and ignore others - in such way
works repeated markers in #define directive with pseudo function.
Harbour PP does not allow to repeat the same much marker in #define
pseudo function generating error so such situation never happens.
In new PP we can keep current behavior or simply not define result
holder for repeated markers just like in point 1 above.
PP tries to allocate as much expressions for each match marker as possible
and finally checks if point 2 above was not broken and if it does then
refuse to accept whole rule even if it was possible to find a valid match
in differ way.
16. Result markers.
Regular result marker - inserts matched result as is
without any modifications. The first token inherits
number of leading spaces from the result pattern.
# Dumb stringify result marker - converts all matched
tokens to single string token even if they are comma
separated expressions. Clear number of leading spaces
for the first token before creating string. If there
are no matching tokens then create empty string token.
Finally copy number of leading spaces from result
pattern to the new string token and insert it.
<"idMarker"> Normal stringify result marker - converts each comma
separated expression in matched result into string tokens
using the same rules as for dump stringify with the exception
to macro tokens expressions starting with '&' followed by '('.
The macro tokens are stringify in differ way. If macro
does not have any internal '&' characters and has at most
one '.' as last character then as result non quited keyword
is generated. Otherwise it generate strings with stripped first
'&' character.
If expression starts with '&' token followed by single
'(' then '&' token is stripped and the rest of tokens copied
as is.
<(idMarker)> Smart stringify result marker - converts each comma separated
expression in matched result into string tokens using the same
rules as for normal stringify with the exception to expressions
which start with string or '(' token. In Such case it does not
make any conversions to string and copy expression as is.
<{idMarker}> Blockify result marker - converts each comma separated
expression in matched result into codeblock token by simple
adding "{||" prefix and "}" suffix. The expression is not
modified at all. Leading spaces in first '{' token are
inherited from result pattern. If the expression starts with
'{' token followed by '|' then Clipper PP recognize it as
codeblock and does not add prefix and suffix.
<.idMarker.> Logify result marker - unlike Clipper documentation says
it only checks if match pattern passed the test and not
is not empty and then insert logical token .T. otherwise .F.
Leading spaces in new token are inherited from result pattern.
The Dumb stringify result marker format is a little bit differ then all
others. It needs a special token '#' before '<'. Clipper PP strips all
'#' tokens which are before result marker token '<' and if the result
marker was the regular one then it's converted to stringify dump otherwise
the marker type is unchanged.
When substitution is done then optional parts are repeated as many times
as the biggest number of accepted multiple matched expressions in the match
markers which are in the processed optional part. After each repeating
tokens are shifted but only if marker accepted more then one value.
This is the only one condition. The type or state of marker is unimportant.
The above shows that there is no correlation between type of match
marker and type of result marker. The type of conversion depends only
on contents of marked expression(s) and type of result marker.
Clipper does not support nested optional result patterns. I can add such
support but I do not know if it's necessary. To keep the base rules used
by Clipper PP the external optional pattern should be repeated as many
times as maximum number of repeating in one of its nested optional
patterns. It can be usable in some seldom cases for someone who knows
what will happen but IMHO in most cases it will create problems so probably
refusing such expressions is the best choice.
In optional clauses you can observe one Clipper bug I do not want to
replicate. When Clipper PP finds '[' then it will take all other tokens
until first unquoted ']'. If it finds it then preprocess tokens inside
as new result pattern but sets flag that other nested clauses are
forbidden. But when it extracts tokens for new optional result pattern
then it strips quote characters so when optional pattern is preprocessed
then all '[' tokens even properly quoted in source code will cause C2073
error. Clipper also does not respect the context of preprocessed tokens
when it looks for optional pattern so it will break restricted match
markers which contains ']' token. For me it's nothing more then to pure
implementation which should be fixed.
Some dipper tests shows also other bugs in Clipper PP when matched tokens
ends with ','.
In such case the blockify result marker does not create empty codeblock
for the last token when for all empty expressions before they does.
The same is with normal and smart stringify result markers but here it's
also yet another problem when there is more commas at the end. The last
one is converted to the string token with comma inside "," ;-)
I do not think we should replicate such behaviors though it seems to
be quite easy because they look like simple bugs which can appear in
the most trivial implementation of some conditions.
In general I think that many of Clipper PP behaviors even the documented
ones was not intentionally designed. Just simply someone in the past
created preprocessor and then the same person or probably someone else
documented - more or less precisely - some side effects and even bugs
of this implementation as expected behavior.
17. Storing real expression strings for later stringify operation in PP
output and stringify result patterns.
* Tabs are replaced by 4 spaces.
* Only one leading space is left from the lines concatenated with ;
* Each token should have counter with number of leading spaces
* When result pattern is created all repeated spaces are replaced by
a single one.
In #define pseudo functions there is small difference to the above.
In result pattern number of spaces before parameter(s) and token before
is significant and stored with pattern definition. The maximum number of
spaces between keywords is not 1 but 2.
* During result markers substitution the original number of leading
spaces in match marker token should overwrite number of leading
spaces in first substituted token
18. TEXT [TO [PRINTER | FILE <(fileName)>]] / ENDTEXT
It enables in Clipper PP special stream output. It work in differ way
then our implementation. Clipper PP preprocess whole lines. When it
finds:
TEXT ,
command then he set special mode for next lines so they will not be
divided to tokens in standard way but whole lines will
be converted to string toke until special marker (ENDTEXT at the beginning
of line) will not be found. But if the line with TEXT token has some other
commands after ; then they are preprocessed in normal way. The new mode
will effect _ONLY_ the next lines which will be read from file not
currently preprocessed one. So we are not Clipper compatible here and I
will change it. The above means that Clipper PP already supports the
starting function Ryszard implemented in #pragma __text. Just simply
it's enough to add it TEXT , after ';' token.
19. The optional match patterns can be nested and each nested submatch
pattern is fully functional match pattern and only operates on the
same markers as parent pattern. If optional match pattern is followed
by another ones then they can match expressions which are any
combination of these patterns which will pass aggressive allocation
(see point 2 above) with one exception. Clipper PP tries to detect
optional match patterns which contain only match markers and always
gives them the lowest priority and if it detect more then one of
such patterns in the series of not separated optional patterns generate
an error.
The optional match patterns are one of the weakest point of current PP.
Even such simple code:
#xcommand CMD [IN [GET] [PUT]] => ? #
CMD sth IN PUT GET
Is not well preprocessed.
20. rule have to begin with non empty token or the rule will never be used.
Generate warning for such rules? or maybe add support for such rules
to implement some language extensions, f.e. clasfunc{p1,p2,p3}
21. translation algorithm used by Clipper PP
Initiate token list
Do
get line stripping comments and dividing line to tokens
While last token in list is ;
Do While not empty token list
Do
If the first token is # then
parse # directive and remove all line tokens
break
EndIf
Do
Do
For each keyword token check if it match:
#define
If token(s) can be substituted then substitute
Next
While anything substituted
Do
For each token check if it match:
#[x]translate
If token(s) can be substituted then substitute
Next
While anything substituted
If anything substituted
continue
Do While 1-st token match some #[x]command pattern
substitute
EndDo
While anything substituted
Output processed token until the last one or ; token
If 1-st token is '#'
continue
Remove all tokens in the list until the last one or ; token
break
While True
EndDo
Output EOL
The above algorithm is differ then the one used by [x]Harbour and this is
the next reason why we are not Clipper compatible in substitution precedence.
This code illustrate the problem:
#define RULE( p ) ? "define value", p
#translate RULE(
) => ? "translate value",
#command RULE(
) => ? "command value",
#define DEF( p ) RULE( p )
#translate TRS(
) => RULE(
)
#command CMD(
) => RULE(
)
proc main()
DEF("def")
TRS("trs")
CMD("cmd")
return
Compile it by Clipper and [x]Harbour and compare the results.
Next important thing is that Clipper preprocess all indirect #directive body.
It means that in Clipper is not possible to execute indirect #undef DEFNAME
because if DEFNAME is already defined then it will be preprocessed and as
result we will have #undef before PP execute this #
directive. We can replicate this behavior but personally I do not like it.
for me it's a limitation not a feature and I do not want to replicate it.
So as I would like to define additional stop condition for line tokens
preprocessing: ';' followed by '#'.
I do not want to make all ';' the stop condition like in current [x]Harbour
PP because the same stop condition has to be used in wild match marker.
In Clipper it matches the text to the end if line. In new PP it will match
the text to the end of line or next # directive. I think it will give
reasonable compatibility level and the body of indirect # directive will
not be preprocessed. Please note that programmer still will be able to
force preprocessing of indirect # directive body using additional
preprocessor rule(s) and even control the preprocessing level f.e.:
#define PREPROCESS_DIRECTIVE DO_DIRECTIVE
#xcommand HASH_DIRECTIVE [<*x*>] => PREPROCESS_DIRECTIVE
#xcommand DO_DIRECTIVE [<*x*>] => \#
#define NEWCMD MYCMD
#xcommand CREATEDIRECTIVE => HASH_DIRECTIVE xcommand NEWCMD \ => ;;
QOUT( "INDIRECT # DIRECTIVE", #\ )
CREATEDIRECTIVE
MYCMD Hello
The second problem is stop condition in # directive body. When PP finds #
as first token then always remove all tokens to the end of line and take
them as part of # directive or ignore. It does not respect ';' token as
command separator. This also causes pleasure side effects, f.e. it's
not possible to insert indirect # directive without breaking commands
after it because they will be always used as part of the inserted #
directive by PP. Here I strongly prefer to define the following behavior:
direct #define, #[x]translate and #[x]command always accept tokens to the
end of line ignoring ';'. Just like in Clipper. All other #directive will
respect ';' as end of # directive - It will cause that ';' cannot be used
in #error and #stdout. If it's a problem then I can define add support for
quoting ';' by '\' for this command and be default keep Clipper
compatibility for not quoted ';' and end rule for quoted ones or by default
use unquoted ';' as end of command and display others. Current Harbour
PP always stop #error and #stdout on ; what is not Clipper compatible and
so far I haven't seen that people reported it as bug so probably it's not
big problem.
Indirect #define, #[x]translate and #[x]command will also respect ';'
as end of command. If user will need to use multiple commands in result
pattern of indirect # directive then it will be enough to define ';' as
some other preprocessor rule, .f.e:
#define EOC ;;
#xcommand CREATECMD => #xcommand NEWCMD => QOUT("1") EOC QOUT("2")
CREATECMD
NEWCMD
This will give programmer full control on preprocessed data when in
Clipper the indirect # directive seems to be a hack added later and
can be used only in very limited way. F.e. in Class(y) as workaround
for Clipper PP behavior #include is used to execute# directive directly
from included files.
22. #define exception. I do not understand why Clipper has it.
during substitution if substituted token is:
'#' 'define'
then it replaces all tokens from current position to the end of line.
It's quite possible that it's a work around for some side effects with
indirect directive in Clipper PP described above. Anyhow it's not
complex solution so I will not replicate it.
23. Conditional compilation.
a. #if[n]def directive pushes on the conditional statement stack current
conditional compilation flag and create new one. If the flag already
disabled preprocessing then the new flag have condition which cannot
be changed by #else.
b. #endif directive pops this value. If conditional statement stack was
empty then error is generated: "Error C2069 #endif does not match #endif".
c. #else directive reverts the current conditional statement flag if its
status allow modifications by #else
If conditional statement stack was empty then error is generated:
"Error C2070 #else does not match #ifdef"
If the conditional compilation flag is set then Clipper PP ignores all
parsed tokens except #if, #endif, #else directive.
The conditional compilation flag and stack are global for all included
files so one can set the new condition and other change or pop it.
In Clipper #if[n]def has to be separate statement in a line
additional token or line concatenators (;) are not allowed. #endif
and #else have to be the first token in the line all tokens after are
ignored to the end of line, command separator ';' is also ignored.
24. NOTE is not an instruction keyword but whole like comments and has
to be stripped at beginning. It has higher priority then /* */
It does not have its special meaning when is used after ;
25. Suggested extensions:
- Higher priority for multi line comments /* */ stripping then in Clipper
where line concatenation (;) is interpreted before /* */. Just like now.
IMHO we should not replicate exact Clipper behavior here.
a. Add #pragma operator directive to define new multi character operators.
Such feature will allow to remove from FLEX/SIMPLEX the hack for ::
translation to Self and define safely other operators which will be
used as single token. Now it's impossible so things like @: matches
@ :
b. token concatenation with new PP operator/marker or automatic in some
chosen cases, f.e. no spaces between two tokens and both tokens are
valid keywords
c. Something to stop result pattern definition in # directives and begin
new command. ; does not interrupt it but it's included to result pattern.
The result pattern works like wild match marker: <*resultPattern*>
It should work also for #define. Maybe it should be global token to
stop all wild markers. We can add special status for ; token. Such
token will have to also break loops with #define and #[x]translate
processing or we will never be able to make from #undef SOME_DEFINE
indirect PP rule used when SOME_DEFINE exists - just simply SOME_DEFINE
will be preprocessed earlier to the defined value.
Such special status can be added automatically when ; token is followed
by # or ; is quoted by \
d. already existing xHarbour extensions:
#[x]unTrasnslate, #[x]unCommand
but modified to locate match pattern which can cover exactly the same
data.
#if
but working with integer to allow using 64bit ones which are broken
due to conversion to double. The semantic for expressions will be
similar to C one with the exception to ! (not) operator precedence.
I do not think that Clipper/xbase users are familiar with the exact
not operator precedence in C which is differ then the one in xbase
world.
e. modified version of Harbour's
#pragma {__text, __stream, __cstream, __endtext}
f. other, see in the code.
-----------------------------------------------------------------------------
Other things you can see in the new PP code. I was adding comments or
using HB_C52_STRICT macro to mark the most important things. In few places
I had to break Clipper compatibility to keep FLEX working. Just simply
I cannot generate preprocessed line in exactly the same form as Clipper
does because FLEX or SIMPLEX will not be able to decode it.
best regards,
Przemek
2006-11-08
-----------------------------------------------------------------------------
c:\harbour\doc\pragma.txt
/*
* $Id: pragma.txt 6629 2006-03-10 11:16:12Z rglab $
*/
INTRODUCTION
============
This file explains what is and how to use the #pragma directive
with Harbour. Primarily, it gives you control over the compiler's
command-line switches within your source code.
WHAT IS
=======
The #pragma is a directive used inside the source code in many compilers
to change the behavior of the compiler at compile time.
USAGE
=====
Currently the #pragma directive can be used in two ways: the switch mode
and the command mode.
The syntax is: #pragma [=On/Off] or
#pragma -CompilerFlag[+|-]
You can use both modes mixed in the same module and upper/lower case
without worry.
To enable or disable a command or a switch you simply do:
* Command mode Switch mode
--------------------------------------------------------------
* #pragma =On/Off #pragma /+/-
Example: #pragma AddDebugInfo=Off /* Suppress debug info */
#pragma /B+ /* Add debug info from here */
IMPLEMENTATION
==============
This is the list of the supported commands and switches:
* Command Switch
-----------------------------------------------
* AUTOMEMVARS = /A<+/->
* DEBUGINFO = /B<+/->
* ENABLEWARNINGS = /W<+/->
* EXITSEVERITY = /E
* FORCEMEMVARS = /V<+/->
* LINEINFO = /L<+/->
* NOSTARTPROC = /N<+/->
* PREPROCESSING = /P<+/->
* WARNINGLEVEL = /W
* SHORTCUTTING = /Z<+/->
The switches have the same behavior as the corresponding compiler ones
and the commands are synonyms for the switches.
* TRACEPRAGMAS
This command shows pragma activity at compile time when enabled.
NOTE: You can use the abbreviated command mode by typing only the
first eight chars.
NOTES
=====
This directive is not supported in the standalone version of the Harbour
preprocessor.
EXAMPLES
========
#pragma NoStartProc=Off
/* #pragma /N- */
function Test()
return nil
This is the same as calling Harbour with the -n switch in the command line,
but with the great benefit that if you forgot to pass the switch, it will
be used anyway because it is included inside the source.
===========
Dec 1, 1999
Regards,
Jose Lalin
SPECIAL PRAGMAS
===============
These pragmas allows to control the processing of PRG source within
the preprocessor. The special handling is done with a text enclosed
beetwen the '#pragma ' and '#pragma __endtext'
#pragma __text
--------------
Syntax:
#pragma __text '|' [LineOutputCode] '|' [FinallyCode] '|' [StartupCode]
Every line of text is stringified using '[' and ']' markers and is
passed to 'LineOutputCode' using C '%s' formating code. The result
text is passed further to the syntax analyzer. The 'StartupCode'
is returned at the very beginning of procesing. The 'FinallyCode'
is returned at the end. If 'LineOutputCode' is ommited then all
lines are ignored.
For example, this pragma is used to implement TEXT/ENDTEXT command
#command TEXT => #pragma __text|Qout(%s)|QQout()
#command TEXT TO PRINTER => ;
#pragma __text|Qout(%s)|__TextRestore()|__TextSave("PRINTER")
#command TEXT TO FILE => ;
#pragma __text|Qout(%s)|__TextRestore()|__TextSave(<"file">)
#pragma __stream
----------------
Syntax:
#pragma __stream '|' [JoinLineCode] '|' [EndingCode] '|' [StartingCode]
All lines are joined together. The result text is stringified and is
appended to 'StartingCode'. Finally the 'EndingCode' is appended.
The resulting text is returned for further syntax analysis.
For example:
#command TEXT TO VAR => ;
#pragma __stream|%s||:=
TEXT TO VAR v
This is 'example' text with ''""[] embeded
ENDTEXT
The above example is preprocessed into:
v:=[This is 'example' text with ''""[] embeded]
#pragma __cstream
----------------
Syntax:
#pragma __cstream '|' [JoinLineCode] '|' [EndingCode] '|' [StartingCode]
This is simmilar to '#pragma __stream' with the additional convertion
of C esc sequences e.g \n \t \r \b
For example:
#command TEXT TO VAR => ;
#pragma __stream|%s||:=
TEXT TO VAR v
This is 'example' text with ''""[] embeded and C \n
sequence
ENDTEXT
? v
The above example is preprocessed into:
v:=[This is 'example' text with ''""[] embeded and C \nsequence]
qout(v)
and at runtime the following is printed:
This is 'example' text with ''""[] embeded and C
sequence
#pragma __endtext
-----------------
Syntax:
#pragma __endtext
This pragma is used to finish the special processing defined with
#pragma [__text | __stream | __cstream]
The following command is hardcoded in the preprocessor:
#xcommand ENDTEXT => #pragma __endtext
#pragma RECURSELEVEL
--------------------
Syntax:
#pragma RECURSELEVEL
This pragma sets the maximum number of preprocess iterations during
the source code translation. The dfault value is 1024.
This is the same as /r= command line switch
For example:
#pragma RECURSELEVEL 2048
c:\harbour\doc\readme.txt
/*
* $Id: readme.txt 9191 2008-08-19 13:11:22Z vszakats $
*/
Welcome to Harbour
==================
Harbour is a free software compiler for the xBase superset language often
referred to as Clipper (the language that is implemented by the compiler
CA-Cl*pper). The goal of the Harbour project is to produce a cross platform
CA-Cl*pper compatible compiler.
The Harbour web site is at . If you
have any problems with this copy of Harbour please visit our web site and
ensure that you are using the latest release.
If you have any questions about Harbour please be sure to read the FAQ
. Also, please be sure to read the
documentation that comes with Harbour, you should find it in the same
directory in which you found this file.
If you are reading this file as part of a source distribution of harbour you
probably want to start by reading dirstruc.txt because this is your map to
the harbour source directories.
c:\harbour\doc\statics.txt
/*
* $Id: statics.txt 2203 2000-02-17 11:11:52Z lculik $
*/
I just started implementing Classes and objects creation when I realized
Harbour is not managing static variables yet (Harbour recognizes them but
does not generate the proper pcode for them).
So I would like to make an introduction to static variables management as
it is a sophisticated system that Harbour is going to implement.
It is something publically known that Clipper static variables are
located at the bottom of the data segment. This has caused all kinds of
troubles. This is why when I designed Five I did it in a way that could not
cause any trouble in the future.
In Harbour all static variables (and I mean on all PRGs) are stored in
just one Harbour array (a Clipper language array), this guarantees that we
may have as many static variables as desired without limits (just limited
by the available memory). This aStatics array is not visible from the
application (PRG level).
Basically what happens when a function is called and that function uses
static variables, is that the stack sets a pointer to that array section
where our statics are, so from that moment on, accessing a static1, static2,
... is accessing some elements on that array:
static1 = statics[ statics_base_for_this_function + 1 ]
...
staticn = statics[ statics_base_for_this_function + n ]
In order to implement this we just use two new pcode opcodes: _STATICS,
_SFRAME. _STATICS makes the global statics array grow enough to hold our new
defined statics:
_STATICS --> ASize( aStatics, Len( aStatics ) + )
_SFRAME --> tell the stack from what location into aStatics are ours.
_STATICS is just called once for an entire PRG from an init function
named _INITSTATICS (STATICS$ and SINIT in Clipper). That function stores in
a tricky place (its own function pointer in the symbol table!) our statics
base, and later on _SFRAME simply takes it from there and sets it in the
stack. That _INITSTATICS function will perform whatever initialization our
global statics may have defined in that PRG).
You are going to see the code for all these. I just wanted to provide a
clear idea about how Harbour does its magic :-)
Antonio
c:\harbour\doc\tracing.txt
/*
* $Id: tracing.txt 5582 2002-07-14 16:44:37Z walito $
*/
INTRODUCTION
============
This file explains how to enable tracing in Harbour.
TRACING
=======
Harbour implements tracing by adding calls to the following macro in
the C code:
HB_TRACE(level, ("printf-style parameters", arg1, arg2));
The level specified for the HB_TRACE call affects harbour in two ways:
compilation time and run time.
COMPILATION TIME
================
At compilation time, the macro checks whether the preprocessor
constant HB_TR_LEVEL is set to any of the following values:
#define HB_TR_ALWAYS 0
#define HB_TR_FATAL 1
#define HB_TR_ERROR 2
#define HB_TR_WARNING 3
#define HB_TR_INFO 4
#define HB_TR_DEBUG 5
#define HB_TR_LEVEL_ALWAYS 0
#define HB_TR_LEVEL_FATAL 1
#define HB_TR_LEVEL_ERROR 2
#define HB_TR_LEVEL_WARNING 3
#define HB_TR_LEVEL_INFO 4
#define HB_TR_LEVEL_DEBUG 5
If it is not set to any of these, the macro is set to the value of
HB_TR_DEFAULT, which is currently set (in hbtrace.h) to HB_TR_WARNING.
Whether the user explicitly sets HB_TR_LEVEL or it is set by the
compiler, its effect is as follows: any calls in the code with a level
higher than HB_TR_LEVEL are obliterated from the code; these calls
simply disappear, and there is no effect in the code performance
thereafter.
RUN TIME
========
At run time, the user can set the environment variable HB_TR_LEVEL to
one of
HB_TR_ALWAYS
HB_TR_FATAL
HB_TR_ERROR
HB_TR_WARNING
HB_TR_INFO
HB_TR_DEBUG
with the following effect: any calls to HB_TRACE that were left by the
compiler and which have a level lower or equal to HB_TR_LEVEL will
print its arguments on stderr.
EXAMPLES
========
HB_TR_LEVEL HB_TR_LEVEL Description
compilation run-time
----------- ----------- ----------------------------------------
HB_TR_INFO HB_TR_ERROR All calls with levels HB_DEBUG are
or erased from the code, so they have no
HB_TR_LEVEL_INFO performance effect; only calls with
levels HB_TR_ERROR, HB_TR_FATAL and
HB_TR_ALWAYS are printed.
HB_TR_WARNING HB_TR_INFO All calls with levels HB_INFO and
or HB_DEBUG are erased from the code, so
HB_TR_LEVEL_WARNING they have no performance effect; only
calls with levels HB_TR_WARNING,
HB_TR_ERROR, HB_TR_FATAL and
HB_TR_ALWAYS are printed. Notice how
setting HB_TR_INFO at run-time has no
effect, since the code was compiled with
a lower tracing level.
For example, I compile Harbour on WinNT with gcc (MINGW32), so I
usually set the C_USR environment variable like this:
export C_USR='-DHARBOUR_USE_WIN_GTAPI -DHB_TR_LEVEL=HB_TR_INFO'
or for other OS (eg: DOS, WIN9x)
SET C_USR=-DHARBOUR_USR_WIN_GTAPI -DHB_TR_LEVEL_INFO
and make sure I have all the tracing for the INFO, WARNING, ERROR,
FATAL and ALWAYS levels. If I get too much information, at run-time I
can set an environment variable like this:
export HB_TR_LEVEL=HB_TR_WARNING
or for other OS (eg: DOS, WIN9x)
SET HB_TR_LEVEL=HB_TR_WARNING
and get rid of all the tracing for the INFO level. In this case, all
the calls to the tracing function for the INFO level will be done
anyway, so there will be a performance hit.
USAGE
=====
When Harbour is compiled/run with some level of tracing and then used
to compile a regular Harbour application, the app will output LOTS of
tracing information to stderr. If you are using a sensible command
shell (such as bash) you can redirect stderr to a file like this:
my_app 2>trace.txt
REDIRECTION
===========
The output generated while tracing goes to stderr by default. You can
control this at run-time by setting the environment variable
HB_TR_OUTPUT to the name of a file where you would like the tracing
output to be directed. If there is any problem opening the file for
writing, the output reverts to stderr.
When it happens an error and the controller of errors of harbour cannot
intercept it (eg: GPF), it can happen that part of information of tracing
it is not written. This problem is avoided setting the environment
variable HB_TR_FLUSH to 1 (one). This makes that every time that one
record is sent to write, don't remain in the buffer, but rather it is
writen in the file before continuing with the execution.
This set can produce an important reduction of speed of execution.
TRACING THE PREPROCESSOR AND COMPILER
=====================================
Usually, you will not want tracing enabled in the preprocessor and
compiler; otherwise, you will see the trace output while compiling
Harbour itself. If you REALLY want to enable tracing in the
preprocessor and/or compiler, you must define, in addition to
HB_TR_LEVEL as described above, the following variable, and then
recompile the preprocessor/compiler:
HB_TRACE_UTILS
The value is of no importance.
TRACING AND RUNTIME
===================
It is also possible to enable and disable tracing at run-time, and to
query and set the trace level. From C code:
* To query the current tracing state, and optionally change the
current state to a given value (which should be in the range [0,1],
otherwise the current state remains unchanged):
hb_tracestate(state);
Therefore, to just query the current state, you can safely call
current_state = hb_tracestate(-1);
To turn tracing completely off:
hb_tracestate(0);
To turn tracing back on:
hb_tracestate(1);
* To query the current tracing level, and optionally change the
current level to a given value (which should be in the range [0,5],
otherwise the current level remains unchanged):
hb_tracelevel(level);
Therefore, to just query the current level, you can safely call
current_level = hb_tracelevel(-1);
There are wrapper functions callable from Clipper code:
current_state := HB_TRACESTATE( [new_state] )
current_level := HB_TRACELEVEL( [new_level] )
c:\harbour\doc\transfrm.txt
/*
* $Id: transfrm.txt 5581 2002-07-14 16:43:48Z walito $
*/
Addendum Clipper documentation. Original transform docs are too limited :
/* TODO: Make a real document out of this */
NUMBERS
The following functions mean something :
@X DB after negative numbers
@( Quotes around negative numbers
@) Quotes around negative numbers without leading spaces
@B Left justified
@C CR after positive numbers
@E Exchange . and , (Not in US/UK manual, does work !)
@Z Return spaces if value is 0
New addition :
@0 Make a zero padded string out of the number.
@L Same of previous.
The following templates mean something to numbers :
9 Digit
# Digit
. Dot
$ Pad left with $
* Pad left with *
, Comma (Real pathetic. Just like Clipper)
The following bugs have been fixed : (Just like xBase++ did !)
@( Does not give incorrect results when it should overflow
@D Ignored. So it should be !
The default string is not properly formatted :
Decimals issue currently being debated. Besides it is a STR problem.
LOGICALS
The following functions mean something :
@R Show remainder
The following templates mean something :
Y Y/N
# T/F (Also isn't the NG)
L T/F
STRINGS
The following functions mean something :
@! Upper case
@R Show remainder
The following templates mean something :
! Upper
# 9 Digit
A N X Text
DATES
Uses SET DATE FORMAT
Uses SET CENTURY
The following functions mean something :
@E Use British date format
/* QUESTION :
Clipper appears to reverse the MM and DD parts of the
date, regardless of SET DATE FORMAT, because if the
date format is British, using @E displays the date in
American. Harbour always treats @E as British.
So is Harbour's behaviour a bug fix or a bug?
*/
c:\harbour\doc\vm.txt
/*
* $Id: vm.txt 2248 2000-03-02 11:58:22Z vszel $
*/
The Harbour virtual machine (VM)
Question :
If a VM description is desirable, how should it be structured? (I
propose plain text, with two main sections: VM description, Opcodes. The
"Opcodes" section would describe every opcode: mnemonic, code, operands,
description. I think I can maintain this section.)
Answer :
The VM is formed by the main execution loop and several subsystems, each of
which could be theoretically replaced, supposing that you respect the
interface of each subsystem.
The main execution loop is defined in the C function named VirtualMachine(),
which receives two parameters: the pcode instructions to execute and the
local symbol table (a portion of the OBJs (static) symbol table) used by
that pcode: (please review hbpcode.h for the currently implemented pcode
opcodes)
VM( pcode, local symbols )
The VM may invoke the VM (itself) again. This lets the Clipper language
access Clipper functions and methods and external C language functions again
and again. The VM organizes these multiple accesses in an ordered and
fully controlled way, and implements services to access these multiple
execution levels (ProcName(), ProcLine(), debugging, and stack variables
access).
The VM subsystems are continuously used by the main execution loop. Let's
review these VM subsystems:
The startup: Controls the initialization of the different VM subsystems.
It is invoked at the beginning of the application. It also controls the
exiting of the application.
The stack: The VM does not use the stack of the computer directly, it uses
instead its own stack for manipulating values (parameters, returned values,
and symbols) as a hardware stack does.
The static symbol table: Created by the compiler at compile time (and
grouped by the linker on OBJs), this subsystem is responsible for an
immediate access to functions location and it is highly related to the
dynamic symbol table at runtime. It contains many duplicated symbols that
will be optimized by the dynamic symbol table.
The dynamic symbol table: Dynamically generated from the startup subsystem
at the beginning of the application. It organizes in an efficient way the
static symbol table creating an alphabetical index that allows a dicotomic
search of symbols. This subsystem is responsible for quick access to symbols
(functions, variables, fields and workareas aliases).
The static and public variables: Responsible for storing public and static
variables.
The memory: Responsible for allocating, reallocating, locking, unlocking and
freeing memory.
The extend system: Defines the interface (_parc(), ..., _retc() ) from low
level (C language) to high level (Clipper language). This subsystem is
responsible for connecting in a proper way C language functions to the
entire application.
Multidimensional arrays: This subsystem allows the creation of arrays, and
the services to manipulate these arrays in all ways. The arrays are
extensively used by the Clipper language and also they are the foundation of
the Objects (Objects are just arrays related to a specific Class).
The Objects engine: Responsible for the creation of Classes and Objects. It
also defines the way to access a specific Class method to be invoked by the
VM and provides all kind of Classes information that may be requested at
runtime.
The macro subsystem: it implements a reduced compiler that may be used at
runtime to generate pcode to be used by the application. In fact it is a
portion of the harbour yacc specifications.
The workareas subsystem: Responsible for databases management. It defines
the locations where the used workareas will be stored and provides all the
functions to access those workareas. It also implements the interface to the
replaceable database drivers.
Question :
Will Harbour opcodes mimic the Clipper ones? (will there be a 1:1
relation between them?) If so, are Clipper opcodes described somewhere?
Answer:
Clipper language pcode opcodes
DEFINE NAME VALOR BYTES
#define NOP 0x00 1
#define PUSHC 0x01 3 + literal
#define PUSHN 0x05 3
#define POPF 0x06 3
#define POPM 0x07 3
#define POPQF 0x08 3
#define PUSHA 0x09 3
#define PUSHF 0x0A 3
#define PUSHM 0x0B 3
#define PUSHMR 0x0C 3
#define PUSHP 0x0D 3
#define PUSHQF 0x0E 3
#define PUSHV 0x0F 3
#define SFRAME 0x10 3
#define SINIT 0x11 3
#define SYMBOL 0x12 3
#define SYMF 0x13 3
#define BEGIN_SEQ 0x19 3
#define JDBG 0x1A 3
#define JF 0x1B 3
#define JFPT 0x1C 3
#define JISW 0x1D 3
#define JMP 0x1E 3
#define JNEI 0x1F 3
#define JT 0x20 3
#define JTPF 0x21 3
#define PUSHBL 0x23 3
#define ARRAYATI 0x24 3
#define ARRAYPUTI 0x25 3
#define CALL 0x26 3
#define DO 0x27 3
#define FRAME 0x28 3
#define FUNC 0x29 3
#define LINE 0x2A 3
#define MAKEA 0x2B 3
#define MAKELA 0x2C 3
#define PARAMS 0x2D 3
#define POPFL 0x2E 3
#define POPL 0x2F 3
#define POPS 0x30 3
#define PRIVATES 0x31 3
#define PUBLICS 0x33 3
#define PUSHFL 0x34 3
#define PUSHFLR 0x35 3
#define PUSHI 0x36 3
#define PUSHL 0x37 3
#define PUSHLR 0x38 3
#define PUSHS 0x39 3
#define PUSHSR 0x3A 3
#define PUSHW 0x3B 3
#define SEND 0x3C 3
#define XBLOCK 0x3D 3
#define MPOPF 0x4A 5
#define MPOPM 0x4B 5
#define MPOPQF 0x4C 5
#define MPUSHA 0x4D 5
#define MPUSHF 0x4E 5
#define MPUSHM 0x4F 5
#define MPUSHMR 0x50 5
#define MPUSHP 0x51 5
#define MPUSHQF 0x52 5
#define MPUSHV 0x53 5
#define MSYMBOL 0x54 5
#define MSYMF 0x55 5
#define ABS 0x56 1
#define AND 0x57 1
#define ARRAYAT 0x58 1
#define ARRAYPUT 0x59 1
#define BREAK 0x5A 1
#define DEC 0x5B 1
#define DIVIDE 0x5C 1
#define DOOP 0x5D 1
#define EEQ 0x5E 1
#define ENDBLOCK 0x5F 1
#define ENDPROC 0x60 1
#define END_SEQ 0x61 1
#define EQ 0x62 1
#define EVENTS 0x63 1
#define FALSE 0x64 1
#define GE 0x65 1
#define GT 0x66 1
#define INC 0x67 1
#define LE 0x68 1
#define LT 0x69 1
#define MINUS 0x6A 1
#define MULT 0x6B 1
#define NE 0x6C 1
#define NEGATE 0x6E 1
#define NOP2 0x6F 1
#define NOT 0x70 1
#define NULL 0x71 1
#define ONE1 0x72 1
#define OR 0x73 1
#define PCOUNT 0x74 1
#define PLUS 0x75 1
#define POP 0x76 1
#define PUSHRV 0x77 1
#define QSELF 0x78 1
#define SAVE_RET 0x79 1
#define TRUE 0x7A 1
#define UNDEF 0x7B 1
#define ZER0 0x7C 1
#define ZZBLOCK 0x7D 1
#define AXPRIN 0x7E 1
#define AXPROUT 0x7F 1
#define BOF 0x80 1
#define DELETED 0x81 1
#define EOF 0x82 1
#define FCOUNT 0x83 1
#define FIELDNAME 0x84 1
#define FLOCK 0x85 1
#define FOUND 0x86 1
#define FSELECT0 0x87 1
#define FSELECT1 0x88 1
#define LASTREC 0x89 1
#define LOCK 0x8A 1
#define RECNO 0x8B 1
#define BNAMES 0x8C 1
#define LNAMES 0x8D 1
#define SNAMES 0x8E 1
#define SRCNAME 0x8F 1
#define TYPE 0x90 1
#define WAVE 0x91 1
#define WAVEA 0x92 1
#define WAVEF 0x93 1
#define WAVEL 0x94 1
#define WAVEP 0x95 1
#define WAVEPOP 0x96 1
#define WAVEPOPF 0x97 1
#define WAVEPOPQ 0x98 1
#define WAVEQ 0x99 1
#define WSYMBOL 0x9A 1
#define AADD 0x9B 1
#define ASC 0x9C 1
#define AT 0x9D 1
#define CDOW 0x9E 1
#define CHR 0x9F 1
#define CMONTH 0xA0 1
#define CTOD 0xA1 1
#define DATE 0xA2 1
#define DAY 0xA3 1
#define DOW 0xA4 1
#define DTOC 0xA5 1
#define DTOS 0xA6 1
#define EMPTY 0xA7 1
#define QEXP 0xA8 1
#define EXPON 0xA9 1
#define INSTR 0xAA 1
#define INT 0xAB 1
#define LEFT 0xAC 1
#define LEN 0xAD 1
#define LOGQ 0xAE 1
#define LOWER 0xAF 1
#define LTRIM 0xB0 1
#define MAX 0xB1 1
#define MIN 0xB2 1
#define MODULUS 0xB3 1
#define MONTH 0xB4 1
#define REPLICATE 0xB5 1
#define ROUND 0xB6 1
#define SECONDS 0xB7 1
#define SPACE 0xB8 1
#define QSQRT 0xB9 1
#define STR1 0xBA 1
#define STR2 0xBB 1
#define STR3 0xBC 1
#define SUB2 0xBD 1
#define SUB3 0xBE 1
#define TIME 0xBF 1
#define TRIM 0xC0 1
#define UPPER 0xC1 1
#define VAL 0xC2 1
#define VALTYPE 0xC3 1
#define WORD 0xC4 1
#define YEAR 0xC5 1
#define TRANS 0xC6 1
#define COL 0xC7 1
#define DEVPOS 0xC8 1
#define INKEY0 0xC9 1
#define INKEY1 0xCA 1
#define PCOL 0xCB 1
#define PROW 0xCC 1
#define ROW 0xCD 1
#define SETPOS 0xCE 1
#define SETPOSBS 0xCF 1
Harbour will not implement all of them as we want to provide the highest
freedom to programers to extend and modify Harbour as needed. In example:
Clipper language uses opcodes for: Row(), Col(), Upper(), Space(),
Replicate(), InKey(), Year(), Month(), etc... where we may just call a
standard C function, that uses the standard extend system and that may be
easily modified. So Harbour will use much less opcodes than the Clipper
language. This will also help to have a simpler and easier to maintain
compiler and VM.
Question :
I see that, for example, Harbour has an opcode named "PUSHWORD"(06),
while Valkyre calls it "PUSHW"(3B): Different names, different codes.
Isn't it desirable that Harbour pCode be binary-compatible with Clipper? I
mean, by doing so, Harbour VM could interpret Clipper pCode and
vice-versa.
Answer :
Harbour opcodes are defined in hbpcode.h. We are trying to use very easy to
remember mnemonics, so PUSHWORD seems easier than PUSHW. The opcodes values
are meaningless as they are just used by a C language switch sentence (in
fact there is a powerful optimization which is to use the pcode opcodes
themselves as an index to a VM functions pointers array, so VM execution
speed may increase. Clipper uses it).
We are not fully implementing the Clipper language OBJs model (i.e. to
provide identifiers names length higher than 10 chars) so Harbour OBJs will
not be supported by Clipper and viceversa.
sorry for such a long message :-)
Antonio
for tables to insert the content of another
file
----------------------------------------------------------------------
Version 0.32 Alpha Build 32 (2000-03-07)
- New Borland make files
- Many make and build processes fixes, enhancements, warning fixes
- Borland, MSVC and GNU-make processes don't collide anymore
- PP now supports code in header files
- Docs separated from the source
- Docs enhanced
- Compiler and macro fixes
- FRM and LBL support
- TBrowse fixes
- HBDOC improvments
- Some mouse support added
- New C include file names
- Many other small fixes and changes
- PP __DATE__ and __TIME__ support
- __TYPEFILE() added
----------------------------------------------------------------------
Version 0.31a Alpha Build 31a (2000-02-02) tag: build31a
- Bugs fixed
----------------------------------------------------------------------
Version 0.31 Alpha Build 31 (2000-01-27) tag: build31
- Added macro support
- Many changes, fixes, and enhancements to compiler internals
- Many changes, fixes, and enhancements to RDD system
- Many changes, fixes, and enhancements to the GT API system
- Improved SETCURSOR() and SET( _SET_CURSOR )
- Added FIELDBLOCK() and FIELDWBLOCK()
- The Harbour '-w' command line option can set the maximal level of reported
warnings. The following levels are supported currently:
'-w0' - no warnings
'-w' or '-w1' - Clipper compatible warnings
'-w2' - some useful warnings missed in Clipper
'-w3' - warnings generated for Harbour language extensions
- The 'libs' directory is now named 'lib'
- The 'runner' program is now named 'hbrun'
- Some include files now have an 'hb' prefix in the name
- db_brows significantly enhanced
- Regression testing enhanced and expanded, replacing several standalone
test modules. Now in tests/regress directory
- Added FSETDEVMOD()
- Added READINSERT()
- Added MEMOLINE()
- Added undocumented DISPOUTAT()
- Added DEFPATH() and __DEFPATH()
- Enhanced VERSION() to optionally include the compiler version used to
create Harbour
- Enhanced OS() to include more Windows version details
- Added __INPUT(), __WAIT(), and SETTYPEAHEAD()
- Added several undocumented __BOX*() functions
- Added HB_VALTOSTR()
- Improved Windows INKEY() support
- Added missing Clipper 5.3 SETs:
_SET_VIDEOMODE
_SET_MBLOCKSIZE
_SET_MFILEEXT
_SET_STRICTREAD
_SET_OPTIMIZE
_SET_AUTOPEN
_SET_AUTORDER
- Added undocumented GETE()
- Compatibility functions added:
__CLASSNEW()
__CLASSINSTANCE()
__CLASSADD()
__CLASSNAME()
__CLASSSEL()
__CLEAR()
__ATCLEAR()
- Added ANNOUNCE CLIPPER520 and ANNOUNCE CLIPPER530
- Added PROCFILE()
- Added national message related functions:
ISAFFIRM(), ISNEGATIVE(), NATIONMSG(), _NATSORTVER(), _NATMSGVER()
- Added Harbour compiler tracing (i.e., debug output)
- Many changes, fixes, and enhancements to documentation
- Program added to extract documentation from source code and create NG,
HLP, OS2, IPF and TROFF output files
- Compile time expression optimizer
- Some preprocessor fixes
- Added ADS RDD
- Added TYPE() function
- MlCount() and MlPos() functions
- Get system completely finished
- Added HARBOURCMD/CLIPPERCMD environment variables
- Added support for #pragma directives
- Enhanced Getenv() function
- Added //BUILD app command line option
----------------------------------------------------------------------
Version 0.30 Alpha Build 30 (1999-09-30)
- RDD support
- Support for MEM files
- The debugger
- Support for BEGIN/END/RECOVER/BREAK statements
- The preprocessor supports changed order of keywords in xcommand/xtranslate
- Error handler supports retry/substitute operations
- Support for aliased expressions
- Support for FIELD variables
- Support for canceling the application by pressing Alt-C
- Enhanced ITEM API
- Support for internal command line options '//'
- Severe speed improvement
- Better Directory() compatibility
- Redirected output works now
- Even more Preprocessor compatibility
- Set HARBOUR= in environment to override Set CLIPPER= settings
- Rudimentary Unix keyboard support added
- Tone support added
- SET KEY support was added
- Extensive regression test suite added (RTL_TEST)
- Array handling fixed and made Clipper compatible
- Ragged array declaration and initialization support added
- FileSys API extensions, more C5.3 compatible functions added
- Compiler command line compatibility enhanced
- Internal errors made uniform
- Source code cleanup and formatting
- Many new functions, samples and bug fixes
----------------------------------------------------------------------
Version 0.29 Alpha Build 29 (1999-07-27)
- Support for these compilers:
C++ Builder
DJGPP for Dos/Windows
MacIntosh
BC 3.1, 4.0, 4.5, 5.2
GCC OS/2
GCC Win32
MS VC
GCC Linux / Unix
IBM C
Watcom C/C++ 10
- New INI file support
- Enhanced support for MEMVAR's
- Added support for PUBLIC, PRIVATE and PARAMETERS
- Added support for empty arguments in functions.
- Added colors support
- Added support for concatenation operator "-"
- Added support to generate runtime errors in functions
----------------------------------------------------------------------
Version 0.28 Alpha Build 28 (1999-07-18)
- Added support for MS Visual C++
- First support for Apple Macintosh
- Almost complete preprocessor
- Error handling improved
- Extend Library complete
- First version of OOPS syntax added
- MEMVAR support started
- Pre processor available as a run-time function
- Rich Text Format Class added
- Many Terminal functions created
- Many national modules added
- Many new functions
- Many bug fixes
----------------------------------------------------------------------
Version 0.27a Alpha Build 27a (1999-06-19)
- Corrected build numbers in Harbour.exe
- Corrected a little bug in HScript.prg
----------------------------------------------------------------------
Version 0.27 Alpha Build 27 (1999-06-18)
- Added new directory with GNU MAKE files for GCC on Linux
- Added support for Watcom C/C++ compiler
- Harbour compiles fine on Linux now
- Optional Strong Typed Variables
- New DosShell function for DOS, OS/2 & Windows
- First release of hScript added. Internet Scripting Samples!
- Integrated preprocessor into compiler
- Check on non used variables in codeblocks
- Extended syntax for AllTrim and RTrim
- Many resolved bugs
- Many new functions
----------------------------------------------------------------------
Version 0.26 Alpha Build 26 (1999-06-12)
- Check for non used declared variable
- Better support for different platforms and compilers.
- New Inifiles class
- Support for IBM C++ compiler for OS/2
- harb26.zip includes runner.exe now
So NO NEED for any external software to run Harbour PRG's!
- Many resolved Bugs
- Many new functions
- New National language message files
- New TestBank. It compiles ALL Harbour samples
-
c:\harbour\doc\windll.txt
/*
* $Id: windll.txt 9411 2008-09-16 03:18:31Z vszakats $
*/
Windows 32-bit DLLs with Harbour code
=====================================
Programs created with Clipper or Harbour are traditionally a
monolithic EXE containing all executable code. This includes
the Virtual Machine (VM) and the RunTime Library (RTL) as well as
your own code. Running under Windows with Harbour, you
can now also create and use Windows DLLs that contain PRG code.
Harbour supports Windows DLLs in 3 ways.
1) Self-contained DLLs containing functions from any platform.
(These are not what we call a "harbour.dll", although they may
be named that. The DLL entry points are different.)
These have the VM/RTL inside them and can be used by any other
Windows program. You can create a .lib for static linking,
or use GetProcAddress as in any standard Windows DLL.
Calling Harbour/Prg functions directly is limited to
those that take no parameters unless you include C functions
in the DLL that take parameters and then call the PRG-level
code.
To do static linking, do this to create the .lib:
implib harbour.lib harbour.dll
For the Borland C platform, use that library and import32.lib
and cw32.lib from Borland, and you are ready to go.
See contrib\delphi\hbdll for an example of a Delphi program that can
use all of Harbour's functionality by accessing a self-contained DLL.
bld_sdll.bat is used there to create the DLL.
2) PCode EXEs using a Harbour.dll
A Harbour.dll is designed to be called from a Harbour app.
A pcode EXE is a small Harbour executable that does not contain the
VM/RTL. To execute its functions, it must load and access a
Harbour.dll.
If you want dynamic linking, then use this to execute a Harbour
dynamically loaded pcode DLL function or procedure:
HB_DllDo( [,] ) --> []
This lets you have all your common code in a DLL, and have lots
of small EXEs that use it. Realize however that, even though this
may be a nice way to manage your code, each EXE may
load its own image of the Harbour.dll into memory at runtime.
In terms of Windows memory, there may not be a benefit to using pcode
EXEs over monolithic EXEs. But it may be a worthwhile maintenance
benefit to have lots of replaceable small exes.
3) PCode DLLs used from traditional EXEs
A pcode DLL does not contain the VM/RTL.
It is a library of Harbour-compiled PRG code that uses the VM/RTL
of the EXE that calls it. This has the benefit of having
replaceable modules in DLLs that don't necessarily require updating
your EXE.
The following is clipped from a msg by Antonio Linares to the Harbour
developer list explaining some of the details:
Please notice that there are three different Windows DLL entry points:
+ source/vm/
* maindll.c Windows self-contained DLL entry point
* maindllh.c Windows Harbour DLL entry point (harbour.dll)
* maindllp.c Windows pcode DLL entry point and VM/RTL routing functions
> * maindll.c Windows self-contained DLL entry point
To produce Harbour code, as DLLs, that may be used
from other programming languages applications (as VB,
Delphi, C++, etc...)
> * maindllh.c Windows Harbour DLL entry point (harbour.dll)
To produce Harbour.dll, to be just used from small pcode Harbour EXEs
> * maindllp.c Windows pcode DLL entry point and VM/RTL routing
To produce small pcode DLLs, to be used just from Harbour EXE apps.
maindllp.c is the entry point for the Harbour pcode DLLs. pcode DLLs
are quite small DLLs, that just contain pcode and/or C (using extend
api) functions.
mainwin.c is the entry point for Windows EXEs, not for DLLs.
You may use maindll.c, maindllh.c or maindllp.c based on
your needs.
If you are looking to build a Harbour.dll, then you must use
maindllh.c