* harbour/bin/hb-func.sh
+ added linker parametrs to hbcc
* harbour/include/hbapi.h
+ added hb_retclenAdoptRaw()
* harbour/include/hbapifs.h
* harbour/source/common/hbfsapi.c
* changed first parameters of hb_fsAddSearchPath() to const char *
* harbour/include/hbclass.ch
* update for new PP. I think that now we can try to create final
version of our OOP rules.
* harbour/include/hbdefs.h
+ added UCHAR and SCHAR typedefs
* harbour/include/hbrddcdx.h
* indenting
* harbour/source/rdd/workarea.c
! fixed minor typo
* harbour/source/common/hbdate.c
* harbour/source/rtl/dates.c
* moved hb_dateToday() and hb_dateTimeStr() from RTL to COMMON library
- harbour/include/hbpp.h
- harbour/source/pp/ppcomp.c
- harbour/source/pp/ppcore.c
- harbour/source/pp/pplib.c
- harbour/source/pp/pptable.c
- harbour/source/pp/pragma.c
* harbour/utils/hbpp/Makefile
* harbour/utils/hbpp/hbpp.c
+ harbour/utils/hbpp/hbpp.h
+ harbour/utils/hbpp/ppcomp.c
+ harbour/utils/hbpp/ppcore.c
+ harbour/utils/hbpp/pplib.c
+ harbour/utils/hbpp/pptable.c
+ harbour/utils/hbpp/pragma.c
* moved all PP code to harbour/utils/hbpp
It's interesting and working preprocessor and the code can be
usable for some other things so I do not want to remove it.
Probablly we should move it to contrib/hbpptext
* harbour/include/hbcomp.h
* harbour/include/hberrors.h
* harbour/include/hbsetup.ch
+ harbour/include/hbpp.h
+ harbour/include/hbstdgen.ch
* harbour/source/common/hbstr.c
* harbour/source/compiler/Makefile
* harbour/source/compiler/cmdcheck.c
* harbour/source/compiler/harbour.c
* harbour/source/compiler/harbour.l
* harbour/source/compiler/hbgenerr.c
+ harbour/source/compiler/ppcomp.c
* harbour/source/pp/Makefile
+ harbour/source/pp/ppcore.c
+ harbour/source/pp/pplib.c
+ harbour/source/pp/ppgen.c
+ New PP code written from scratch. It works in similar way to
Clipper PP even the error codes are replicated. The code is MT
safe does not have any limitation on size of preprocessed code,
line, etc. It's also Clipper compatible lexer. It means that
we do not longer need FLEX or SIMPLEX which can be replaced
by new PP after some small modifications. Anyhow I haven't
decided to make it myself. I would like to agree with with the
rest of developers. I will be very happy if such modifications
will be done by someone else, Ryszard?
Meanwhile I current PP join on output the line tokens and give
the string line to FLEX/SIMPLEX. It does not have any sense and
all FLEX/SIMPLEX limitations are still existing. Ryszard, even
if we keep it then I hope you can remove at least FLEX line buffer
and use the one returned from PP.
Because string tokens in parsed line are converted to text which is
later once again decoded to tokens by FLEX I had to introduce new
string format which supports embedded string delimiters. I chose
modified version of xHarbour extension with escaped strings e"<sting>"
so now FLEX understand such strings and decode them like C escaped
strings. It means that you can use them also in the .prg code f.e.:
outstd( e"Hello\n\rWorld" )
The new PP is also noticeable faster. You should see the difference
compiling long files. The build in PP rules are generated automatically
by ppgen program created from source/pp/ppgen.c
I had to add to GNU source/pp/Makefile these two lines:
pptable.c : ppgen$(EXE_EXT)
./ppgen$(EXE_EXT) $(TOP)$(ROOT)include/hbstdgen.ch -opptable.c -q
Sth like that will have to be done also in non GNU make system.
Now Harbour can be compiled only using GNU make.
Marek can you update non GNU make files? I would like to leave this
modification to you or other developers who can test it.
It was quite big modification and I do not believe that I haven't
make any mistakes but I hope that in few weeks I'll fix any reported
bugs and it will resolve any PP problems.
TODO:
* error messages
create one common list of errors and warnings and keep it
in common library. PP and compiler can still generate different
errors with the same number. It can be confusing for the users
and hard to document and add i18n translations.
If possible we should also try to keep Clipper error numbers.
In new PP code I added Clipper error numbers but I cannot use
them until compiler code is not updated.
We should aslo remove the ctype passed to error functions and
hack with first character in warning messages and use only
error number. The codes from 1000 to 1999 should be warnings
where range 1000:1099 is activated by -w, 1100:1199 by -w1,
1200:1299 by -w2, etc. 2000:2999 are errors and 3000:3999
fatal errors. All compiler functions which generate an error
should expect that error function will not stop the compiler
but return and cleanly finished their job. It's necessary for
MT support in compiler and making compiler part of some other
programs which may still work and compile different source code.
* FLEX/SIMPLEX
remove them at all and add some final pass to PP to create
more precise tokens for grammar parser or at least add better
integration to remove some redundant code and existing limits.
* hb_inLine() support - it's broken in new PP but as I can see
it was never working correctly. I can add a hack to PP to support
hb_inLine() but I'm not sure it's worth to do. Maybe in few days.
+ harbour/include/std.ch
+ added new std.ch. It was created without using Clipper's std.ch.
It's quite possible that some rules are wrong and should be fixed
so please help. Anyhow I created a set of programs based on new PP
code generating all possible combinations of different commands I
collected from different source code, documentation and match patterns
of rules I was adding to new std.ch and then I was comparing .ppo
files generated by Clipper and Harbour so I do not expect any bigger
problems then some minor typos. I had to introduce some modifications
in spacing as workaround for FLEX/SIMPLEX which cannot properly decode
text preprocessed by Clipper after stringify.
* harbour/utils/hbpptest/pretest.prg
* updated for new PP
It reports 16 wrong translations but some of them are valid
and some others are caused by escaped string e"..." (one of hack
for FLEX/SIMPLEX support)
I also had to remove all spaces in comparison the results
because they were not Clipper ocmpatible at all. Ryszard please
look at it.
259 lines
9.1 KiB
C
259 lines
9.1 KiB
C
/*
|
|
* $Id$
|
|
*/
|
|
|
|
/*
|
|
* Harbour Project source code:
|
|
* Compiler parse errors & warnings messages
|
|
*
|
|
* Copyright 1999 {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 of the License, or
|
|
* (at your option) any later version, with one exception:
|
|
*
|
|
* 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/).
|
|
*
|
|
*/
|
|
|
|
#include "hbcomp.h"
|
|
|
|
extern char *yytext;
|
|
|
|
/* Table with parse errors */
|
|
char * hb_comp_szErrors[] =
|
|
{
|
|
"Statement not allowed outside of procedure or function",
|
|
"Redefinition of procedure or function: \'%s\'",
|
|
"Duplicate variable declaration: \'%s\'",
|
|
"%s declaration follows executable statement",
|
|
"Outer codeblock variable is out of reach: \'%s\'",
|
|
"Invalid numeric format '.'",
|
|
"Unterminated string: \'%s\'",
|
|
"Redefinition of predefined function %s: \'%s\'",
|
|
"Illegal variable \'%s\' initializer: \'%s\'",
|
|
"ENDIF does not match IF",
|
|
"ENDDO does not match WHILE",
|
|
"ENDCASE does not match DO CASE",
|
|
"NEXT does not match FOR",
|
|
"ELSE does not match IF",
|
|
"ELSEIF does not match IF",
|
|
"Syntax error: \'%s\'",
|
|
"Unclosed control structures",
|
|
"%s statement with no loop in sight",
|
|
"Syntax error: \'%s\' in: \'%s\'",
|
|
"Incomplete statement: %s",
|
|
"Incorrect number of arguments: %s %s",
|
|
"Invalid lvalue: \'%s\'",
|
|
"Invalid use of \'@\' (pass by reference): \'%s\'",
|
|
"Formal parameters already declared",
|
|
"Invalid %s from within of SEQUENCE code",
|
|
"Unterminated array index",
|
|
"Could not allocate %s byte(s)",
|
|
"Could not reallocate %s byte(s)",
|
|
"Freeing a NULL memory pointer",
|
|
"Syntax error: \"%s at \'%s\'\"",
|
|
"Jump offset too long",
|
|
"Can't create output file: \'%s\'",
|
|
"Can't create preprocessed output file: \'%s\'",
|
|
"Bad command line option: \'%s\'",
|
|
"Bad command line parameter: \'%s\'",
|
|
"Invalid filename: \'%s\'",
|
|
"Mayhem in CASE handler",
|
|
"Operation not supported for this data type: \'%s\'",
|
|
"Invalid alias expression: \'%s\'",
|
|
"Invalid array index expression: \'%s\'",
|
|
"Bound error: \'%s\'",
|
|
"Macro of declared symbol: \'%s\'",
|
|
"Invalid selector in send: \'%s\'",
|
|
"ANNOUNCEd procedure \'%s\' must be a public symbol",
|
|
"Jump PCode not found",
|
|
"CASE or OTHERWISE does not match DO CASE",
|
|
"Code block contains both macro and declared symbol references \'%s\'",
|
|
"GET contains complex macro",
|
|
"Unterminated inline block in function: \'%s\'",
|
|
"Too many inline blocks %s",
|
|
"Inline C requires C output generation, use -gc[n]",
|
|
"Too many local variables [%s] or parameters [%s]",
|
|
"Too many enumerate variables in FOR EACH loop",
|
|
"Incorrect number of enumerate variables",
|
|
"CASE requires either numeric or string constant",
|
|
"String too long for SWITCH",
|
|
"Invalid date constant \'%s\'",
|
|
"Memory buffer overflow",
|
|
"Memory corruption detected",
|
|
"Implicit send operator with no WITH OBJECT in sight",
|
|
"Input buffer overflow"
|
|
};
|
|
|
|
/* Table with parse warnings */
|
|
/* NOTE: The first character stores the warning's level that triggers this
|
|
* warning. The warning's level is set by -w<n> command line option.
|
|
*/
|
|
char * hb_comp_szWarnings[] =
|
|
{
|
|
"1Ambiguous reference: \'%s\'",
|
|
"1Ambiguous reference, assuming memvar: \'%s\'",
|
|
"2Variable: \'%s\' declared but not used in function: \'%s\'",
|
|
"2Codeblock parameter: \'%s\' declared but not used in function: \'%s\'",
|
|
"1RETURN statement with no return value in function",
|
|
"1Procedure returns value",
|
|
"1Function \'%s\' does not end with RETURN statement",
|
|
"3Incompatible type in assignment to: \'%s\' expected: \'%s\'",
|
|
"3Incompatible operand type: \'%s\' expected: \'%s\'",
|
|
"3Incompatible operand types: \'%s\' and: \'%s\'",
|
|
"4Suspicious type in assignment to: \'%s\' expected: \'%s\'",
|
|
"4Suspicious operand type: \'unknown\' expected: \'%s\'",
|
|
"3Can\'t use array index with non-array",
|
|
"3Incompatible return type: \'%s\' expected: \'%s\'",
|
|
"4Suspicious return type: \'%s\' expected: \'%s\'",
|
|
"3Invalid number of parameters: %s expected: %s",
|
|
"3Incompatible parameter: %s expected: \'%s\'",
|
|
"4Suspicious parameter: %s expected: \'%s\'",
|
|
"3Duplicate declaration of %s \'%s\'",
|
|
"3Function \'%s\' conflicting with its declaration",
|
|
"3Variable \'%s\' used but never initialized",
|
|
"3Value of Variable \'%s\' never used",
|
|
"3Incompatible type in assignment to declared array element expected: \'%s\'",
|
|
"4Suspicious type in assignment to declared array element expected: \'%s\'",
|
|
"3Class \'%s\' not known in declaration of \'%s\'",
|
|
"3Message \'%s\' not known in class \'%s\'",
|
|
"0Meaningless use of expression: \'%s\'",
|
|
"2Unreachable code",
|
|
"1Redundant \'ANNOUNCE %s\' statement ignored",
|
|
"0Duplicate variable \'%s\' in nested FOR loop",
|
|
"0Invalid variable \'%s\' for enumerator message"
|
|
};
|
|
|
|
void hb_compGenError( char * szErrors[], char cPrefix, int iError, const char * szError1, const char * szError2 )
|
|
{
|
|
int iLine = hb_comp_iLine - 1;
|
|
|
|
if( cPrefix != 'F' && hb_comp_bError )
|
|
return;
|
|
|
|
if( hb_comp_files.pLast && hb_comp_files.pLast->szFileName )
|
|
fprintf( hb_comp_errFile, "\r%s(%i) ", hb_comp_files.pLast->szFileName, iLine );
|
|
|
|
fprintf( hb_comp_errFile, "Error %c%04i ", cPrefix, iError );
|
|
fprintf( hb_comp_errFile, szErrors[ iError - 1 ], szError1, szError2 );
|
|
fprintf( hb_comp_errFile, "\n" );
|
|
|
|
hb_comp_iErrorCount++;
|
|
hb_comp_bError = TRUE;
|
|
|
|
/* fatal error - exit immediately */
|
|
if( cPrefix == 'F' )
|
|
{
|
|
hb_compMainExit();
|
|
exit( EXIT_FAILURE );
|
|
}
|
|
}
|
|
|
|
void hb_compGenWarning( char * szWarnings[], char cPrefix, int iWarning, const char * szWarning1, const char * szWarning2)
|
|
{
|
|
char * szText = szWarnings[ iWarning - 1 ];
|
|
int iLine = hb_comp_iLine - 1;
|
|
|
|
if( ( szText[ 0 ] - '0' ) <= hb_comp_iWarnings )
|
|
{
|
|
if( hb_comp_files.pLast && hb_comp_files.pLast->szFileName )
|
|
fprintf( hb_comp_errFile, "\r%s(%i) ", hb_comp_files.pLast->szFileName, iLine );
|
|
|
|
fprintf( hb_comp_errFile, "Warning %c%04i ", cPrefix, iWarning );
|
|
fprintf( hb_comp_errFile, szText + 1, szWarning1, szWarning2 );
|
|
fprintf( hb_comp_errFile, "\n" );
|
|
|
|
hb_comp_bAnyWarning = TRUE; /* report warnings at exit */
|
|
}
|
|
}
|
|
|
|
HB_EXPR_PTR hb_compErrorLValue( HB_EXPR_PTR pExpr )
|
|
{
|
|
char * szDesc = hb_compExprDescription( pExpr );
|
|
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_INVALID_LVALUE, szDesc, NULL );
|
|
return pExpr;
|
|
}
|
|
|
|
HB_EXPR_PTR hb_compErrorType( HB_EXPR_PTR pExpr )
|
|
{
|
|
char * szDesc = hb_compExprDescription( pExpr );
|
|
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_INVALID_TYPE, szDesc, NULL );
|
|
return pExpr;
|
|
}
|
|
|
|
HB_EXPR_PTR hb_compErrorIndex( HB_EXPR_PTR pExpr )
|
|
{
|
|
char * szDesc = hb_compExprDescription( pExpr );
|
|
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_INVALID_INDEX, szDesc, NULL );
|
|
return pExpr;
|
|
}
|
|
|
|
HB_EXPR_PTR hb_compErrorBound( HB_EXPR_PTR pExpr )
|
|
{
|
|
char * szDesc = hb_compExprDescription( pExpr );
|
|
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_INVALID_BOUND, szDesc, NULL );
|
|
return pExpr;
|
|
}
|
|
|
|
HB_EXPR_PTR hb_compErrorSyntax( HB_EXPR_PTR pExpr )
|
|
{
|
|
char * szDesc = hb_compExprDescription( pExpr );
|
|
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_SYNTAX, szDesc, NULL );
|
|
return pExpr;
|
|
}
|
|
|
|
HB_EXPR_PTR hb_compErrorAlias( HB_EXPR_PTR pExpr )
|
|
{
|
|
char * szDesc = hb_compExprDescription( pExpr );
|
|
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_INVALID_ALIAS, szDesc, NULL );
|
|
return pExpr;
|
|
}
|
|
|
|
HB_EXPR_PTR hb_compErrorStatic( char * szVarName, HB_EXPR_PTR pExpr )
|
|
{
|
|
char * szDesc = hb_compExprDescription( pExpr );
|
|
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_ILLEGAL_INIT, szVarName, szDesc );
|
|
return pExpr;
|
|
}
|
|
|
|
void hb_compErrorDuplVar( char * szVarName )
|
|
{
|
|
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_VAR_DUPL, szVarName, NULL );
|
|
}
|
|
|
|
HB_EXPR_PTR hb_compWarnMeaningless( HB_EXPR_PTR pExpr )
|
|
{
|
|
char * szDesc = hb_compExprDescription( pExpr );
|
|
hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_MEANINGLESS, szDesc, NULL );
|
|
return pExpr;
|
|
}
|
|
|
|
void hb_compErrorCodeblock( char * szBlock )
|
|
{
|
|
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_BLOCK, szBlock, NULL );
|
|
hb_comp_bError = FALSE; /* clear error flag for this line */
|
|
}
|
|
|
|
void hb_compErrorMacro( char *szText )
|
|
{
|
|
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_BAD_MACRO, szText, NULL );
|
|
}
|
|
|
|
HB_EXPR_PTR hb_compErrorRefer( HB_EXPR_PTR pExpr, char *szAlias )
|
|
{
|
|
char * szDesc = hb_compExprDescription( pExpr );
|
|
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_INVALID_REFER, szAlias, szDesc );
|
|
return pExpr;
|
|
}
|