1
0
mirror of https://github.com/cc65/cc65.git synced 2025-01-11 11:30:13 +00:00

Merge branch 'cc65:master' into master

This commit is contained in:
polluks2 2021-05-22 23:39:34 +02:00
commit 4865caa593
32 changed files with 570 additions and 146 deletions

View File

@ -90,7 +90,7 @@ VIA1_T1LH := VIA1+$7 ; Timer 1 latch, high byte
VIA1_T2CL := VIA1+$8 ; Timer 2, low byte
VIA1_T2CH := VIA1+$9 ; Timer 2, high byte
VIA1_SR := VIA1+$A ; Shift register
VIA1_CR := VIA1+$B ; Auxiliary control register
VIA1_ACR := VIA1+$B ; Auxiliary control register
VIA1_PCR := VIA1+$C ; Peripheral control register
VIA1_IFR := VIA1+$D ; Interrupt flag register
VIA1_IER := VIA1+$E ; Interrupt enable register
@ -112,7 +112,7 @@ VIA2_T1LH := VIA2+$7 ; Timer 1 latch, high byte
VIA2_T2CL := VIA2+$8 ; Timer 2, low byte
VIA2_T2CH := VIA2+$9 ; Timer 2, high byte
VIA2_SR := VIA2+$A ; Shift register
VIA2_CR := VIA2+$B ; Auxiliary control register
VIA2_ACR := VIA2+$B ; Auxiliary control register
VIA2_PCR := VIA2+$C ; Peripheral control register
VIA2_IFR := VIA2+$D ; Interrupt flag register
VIA2_IER := VIA2+$E ; Interrupt enable register

View File

@ -3410,7 +3410,7 @@ loaded.
<descrip>
<tag/Function/Install an already loaded extended memory driver.
<tag/Header/<tt/<ref id="em.h" name="em.h">/
<tag/Declaration/<tt/unsigned char _fastcall__ em_install (void* driver);/
<tag/Declaration/<tt/unsigned char _fastcall__ em_install (const void* driver);/
<tag/Description/The function installs an already loaded extended memory driver
and returns an error code. The function may be used to install a driver linked
statically to the program.
@ -4733,7 +4733,7 @@ There's no way to check for the number of actually connected joysticks.
<descrip>
<tag/Function/Install an already loaded driver and return an error code.
<tag/Header/<tt/<ref id="joystick.h" name="joystick.h">/
<tag/Declaration/<tt/unsigned char __fastcall__ joy_install (void* driver);/
<tag/Declaration/<tt/unsigned char __fastcall__ joy_install (const void* driver);/
<tag/Description/The function installs a driver that was already loaded into
memory (or linked statically to the program). It returns an error code
(<tt/JOY_ERR_OK/ in case of success).
@ -6198,7 +6198,7 @@ while (ser_get(&amp;ch) == SER_ERR_NO_DATA)
<descrip>
<tag/Function/Install an already loaded driver and return an error code.
<tag/Header/<tt/<ref id="serial.h" name="serial.h">/
<tag/Declaration/<tt/unsigned char __fastcall__ ser_install (void* driver);/
<tag/Declaration/<tt/unsigned char __fastcall__ ser_install (const void* driver);/
<tag/Description/The function installs a driver that was already loaded into
memory (or linked statically to the program). It returns an error code
(<tt/SER_ERR_OK/ in case of success).

View File

@ -205,7 +205,7 @@ see them together in the filling box in GeoPaint.
<sect2>GraphicsString
<p>
<tt/void GraphicsString (char *myGString)/
<tt/void GraphicsString (const void *myGString)/
<p>
One of the more powerfull routines of GEOS. This function calls other graphic functions depending
on the given command string. See the structures chapter for a more detailed description.

View File

@ -555,7 +555,7 @@ tgi_init(); //Set up the default palette and clear the screen.
<descrip>
<tag/Function/Install an already loaded driver and return an error code.
<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/
<tag/Declaration/<tt/unsigned char __fastcall__ tgi_install (void* driver);/
<tag/Declaration/<tt/unsigned char __fastcall__ tgi_install (const void* driver);/
<tag/Description/The function installs a driver that was already loaded into
memory (or linked statically to the program). It returns an error code
(<tt/TGI_ERR_OK/ in case of success).

View File

@ -82,7 +82,7 @@ unsigned char __fastcall__ em_load_driver (const char* driver);
unsigned char em_unload (void);
/* Uninstall, then unload the currently loaded driver. */
unsigned char __fastcall__ em_install (void* driver);
unsigned char __fastcall__ em_install (const void* driver);
/* Install an already loaded driver. Return an error code. */
unsigned char em_uninstall (void);

View File

@ -43,7 +43,7 @@ void __fastcall__ BitOtherClip(void *proc1, void *proc2, char skipl,
char skipr, unsigned skiptop,
struct iconpic *myIcon);
void __fastcall__ GraphicsString(char *myGfxString);
void __fastcall__ GraphicsString(const void *myGfxString);
#ifdef __GEOS_CBM__
void SetNewMode(void);

View File

@ -89,7 +89,7 @@ unsigned char __fastcall__ joy_load_driver (const char* driver);
unsigned char joy_unload (void);
/* Uninstall, then unload the currently loaded driver. */
unsigned char __fastcall__ joy_install (void* driver);
unsigned char __fastcall__ joy_install (const void* driver);
/* Install an already loaded driver. Return an error code. */
unsigned char joy_uninstall (void);

View File

@ -136,7 +136,7 @@ unsigned char __fastcall__ ser_load_driver (const char* driver);
unsigned char ser_unload (void);
/* Uninstall, then unload the currently loaded driver. */
unsigned char __fastcall__ ser_install (void* driver);
unsigned char __fastcall__ ser_install (const void* driver);
/* Install an already loaded driver. Return an error code. */
unsigned char ser_uninstall (void);

View File

@ -82,7 +82,7 @@ void tgi_unload (void);
** necessary.
*/
void __fastcall__ tgi_install (void* driver);
void __fastcall__ tgi_install (const void* driver);
/* Install an already loaded driver. */
void tgi_uninstall (void);

View File

@ -44,4 +44,4 @@ _exit: jsr donelib ; Run module destructors
; A 5200 program isn't supposed to exit.
halt: jmp halt
halt: jmp halt

View File

@ -36,7 +36,7 @@ emd_sig: .byte $65, $6d, $64, EMD_API_VERSION ; "emd", version
;----------------------------------------------------------------------------
; unsigned char __fastcall__ em_install (void* driver);
; unsigned char __fastcall__ em_install (const void* driver);
; /* Install the driver once it is loaded */

View File

@ -3,7 +3,7 @@
;
; 25.12.99
; void GraphicsString (char *myString);
; void GraphicsString (const void *myString);
.export _GraphicsString

View File

@ -33,7 +33,7 @@ joy_sig: .byte $6A, $6F, $79, JOY_API_VERSION ; "joy", version
.code
;----------------------------------------------------------------------------
; unsigned char __fastcall__ joy_install (void* driver);
; unsigned char __fastcall__ joy_install (const void* driver);
; /* Install the driver once it is loaded */

View File

@ -39,7 +39,7 @@ ser_sig: .byte $73, $65, $72, SER_API_VERSION ; "ser", version
.code
;----------------------------------------------------------------------------
; unsigned char __fastcall__ ser_install (void* driver);
; unsigned char __fastcall__ ser_install (const void* driver);
; /* Install the driver once it is loaded */

View File

@ -67,13 +67,13 @@ not_dma:
; Removing this segment gives only a warning.
.segment "FFF0"
.proc reset32kcode
lda #(6<<5) | SV_LCD_ON | SV_NMI_ENABLE_ON
lda #(6<<5) | SV_LCD_ON | SV_NMI_ENABLE_ON
sta sv_bank
; Now, the 32Kbyte image can reside in the top of 64Kbyte and 128Kbyte ROMs.
jmp reset
.endproc
.segment "VECTOR"
.segment "VECTORS"
.word nmi
.word reset32kcode

View File

@ -88,7 +88,7 @@ tgi_sig: .byte $74, $67, $69, TGI_API_VERSION ; "tgi", version
.code
;----------------------------------------------------------------------------
; void __fastcall__ tgi_install (void* driver);
; void __fastcall__ tgi_install (const void* driver);
; /* Install an already loaded driver. */

View File

@ -159,21 +159,6 @@ DIRLIST = tutorial geos
# --------------------------------------------------------------------------
# Lists of executables
EXELIST_c64 = \
ascii \
enumdevdir \
fire \
gunzip65 \
hello \
mandelbrot \
mousedemo \
multdemo \
nachtm \
ovrldemo \
plasma \
sieve \
tgidemo
EXELIST_apple2 = \
ascii \
diodemo \
@ -204,10 +189,140 @@ EXELIST_atarixl = $(EXELIST_atari)
EXELIST_atari2600 = \
atari2600hello
EXELIST_atmos = \
ascii \
hello \
mandelbrot \
sieve
EXELIST_bbc = \
notavailable
EXELIST_c64 = \
ascii \
enumdevdir \
fire \
gunzip65 \
hello \
mandelbrot \
mousedemo \
multdemo \
nachtm \
ovrldemo \
plasma \
sieve \
tgidemo
EXELIST_c128 = \
ascii \
enumdevdir \
fire \
gunzip65 \
hello \
mandelbrot \
mousedemo \
nachtm \
plasma \
sieve \
tgidemo
EXELIST_c16 = \
ascii \
enumdevdir \
hello
EXELIST_cbm510 = \
ascii \
fire \
gunzip65 \
hello \
mousedemo \
nachtm \
plasma \
sieve
EXELIST_cbm610 = \
ascii \
gunzip65 \
hello \
nachtm \
sieve
EXELIST_creativision = \
ascii \
hello
EXELIST_cx16 = \
ascii \
enumdevdir \
gunzip65 \
hello \
mandelbrot \
mousedemo \
sieve \
tgidemo
EXELIST_gamate = \
hello
EXELIST_geos-cbm = \
ascii \
diodemo
EXELIST_geos-apple = \
ascii
EXELIST_lunix = \
notavailable
EXELIST_lynx = \
notavailable
EXELIST_nes = \
hello
EXELIST_osic1p = \
notavailable
EXELIST_pce = \
hello
EXELIST_pet = \
ascii \
enumdevdir \
hello \
sieve
EXELIST_plus4 = \
ascii \
enumdevdir \
gunzip65 \
hello \
plasma \
sieve
EXELIST_sim6502 = \
gunzip65
EXELIST_sim65c02 = $(EXELIST_sim6502)
EXELIST_supervision = \
supervisionhello
EXELIST_telestrat = \
ascii \
gunzip65 \
hello
EXELIST_vic20 = \
ascii \
enumdevdir \
hello \
mandelbrot \
sieve \
tgidemo
# Unlisted targets will try to build everything.
# That lets us learn what they cannot build, and what settings
# we need to use for programs that can be built and run.
@ -227,6 +342,12 @@ endef # SUBDIR_recipe
samples: $(EXELIST_$(SYS))
$(foreach dir,$(DIRLIST),$(SUBDIR_recipe))
# empty target used to skip systems that will not work with any program in this dir
notavailable:
ifeq ($(MAKELEVEL),0)
@echo "info: generic samples not available for" $(SYS)
endif
disk: $(DISK_$(SYS))
all:

View File

@ -3,6 +3,19 @@
# var. to build for another target system.
SYS ?= geos-cbm
# If SYS was given on the commandline, redirect "c64" to "geos-cbm" and
# "apple2enh" to "geos-apple"
ifeq ($(origin SYS),command line)
ifeq ($(SYS),c64)
override SYS = geos-cbm
$(info GEOS: c64 -> geos-cbm)
endif
ifeq ($(SYS),apple2enh)
override SYS = geos-apple
$(info GEOS: apple2enh -> geos-apple)
endif
endif
# Just the usual way to find out if we're
# using cmd.exe to execute make rules.
ifneq ($(shell echo),)
@ -37,16 +50,45 @@ DIRLIST = grc
define SUBDIR_recipe
@$(MAKE) -C $(dir) --no-print-directory $@
@$(MAKE) SYS=$(SYS) -C $(dir) --no-print-directory $@
endef # SUBDIR_recipe
# omitted: dialog.c grphstr.c inittab.c menu.c
EXELIST_geos-cbm = \
bitmap-demo.cvt \
filesel.cvt \
geosver.cvt \
getid.cvt \
hello1.cvt \
hello2.cvt \
overlay-demo.cvt \
vector-demo.cvt \
yesno.cvt
EXELIST_geos-apple = \
bitmap-demo.cvt \
filesel.cvt \
hello1.cvt \
hello2.cvt \
overlay-demo.cvt \
vector-demo.cvt \
yesno.cvt
# omitted: dialog.c grphstr.c inittab.c menu.c
# TODO: geosconio.cvt rmvprot.cvt
samples: bitmap-demo.cvt filesel.cvt geosver.cvt getid.cvt hello1.cvt hello2.cvt \
overlay-demo.cvt vector-demo.cvt yesno.cvt
ifneq ($(EXELIST_$(SYS)),)
samples: $(EXELIST_$(SYS))
$(foreach dir,$(DIRLIST),$(SUBDIR_recipe))
else
samples:
ifeq ($(MAKELEVEL),0)
@echo "info: geos samples not available for" $(SYS)
else
# suppress the "nothing to be done for 'samples' message
@echo > $(NULLDEV)
endif
endif
bitmap.c: logo.pcx
$(SP) -r logo.pcx -c geos-bitmap -w bitmap.c,ident=bitmap

View File

@ -8,8 +8,8 @@ struct window wholeScreen = {0, SC_PIX_HEIGHT-1, 0, SC_PIX_WIDTH-1};
void main (void)
{
unsigned char os = get_ostype();
unsigned char *machine = NULL;
unsigned char *version = NULL;
char *machine = NULL;
char *version = NULL;
unsigned char good = 1;
SetPattern(0);

View File

@ -1,4 +1,8 @@
# Run 'make SYS=<target>'; or, set a SYS env.
# var. to build for another target system.
SYS ?= geos-cbm
# Just the usual way to find out if we're
# using cmd.exe to execute make rules.
ifneq ($(shell echo),)
@ -29,22 +33,36 @@ else
GRC := $(if $(wildcard ../../../bin/grc65*),../../../bin/grc65,grc65)
endif
samples: test.s vlir.cvt
EXELIST_geos-cbm = \
test.s \
vlir.cvt
ifneq ($(EXELIST_$(SYS)),)
samples: $(EXELIST_$(SYS))
else
samples:
ifeq ($(MAKELEVEL),0)
@echo "info: grc sample not available for" $(SYS)
else
# suppress the "nothing to be done for 'samples' message
@echo > $(NULLDEV)
endif
endif
test.s: test.grc
$(GRC) -s test.s test.grc
vlir.cvt: vlir.grc vlir0.s vlir1.s vlir2.s
# using seperate calls here for demonstration purposes:
$(GRC) -t geos-cbm -s vlir.s vlir.grc
$(AS) -t geos-cbm vlir.s
$(AS) -t geos-cbm vlir0.s
$(AS) -t geos-cbm vlir1.s
$(AS) -t geos-cbm vlir2.s
$(LD) -t geos-cbm -o vlir.cvt vlir.o vlir0.o vlir1.o vlir2.o geos-cbm.lib
$(GRC) -t $(SYS) -s vlir.s vlir.grc
$(AS) -t $(SYS) vlir.s
$(AS) -t $(SYS) vlir0.s
$(AS) -t $(SYS) vlir1.s
$(AS) -t $(SYS) vlir2.s
$(LD) -t $(SYS) -o vlir.cvt vlir.o vlir0.o vlir1.o vlir2.o $(SYS).lib
# you can also do the above in one command:
# $(CL) -t geos-cbm -o vlir.cvt vlir.grc vlir0.s vlir1.s vlir2.s
# $(CL) -t $(SYS) -o vlir.cvt vlir.grc vlir0.s vlir1.s vlir2.s
clean:
@$(DEL) test.s test.h 2>$(NULLDEV)

View File

@ -972,12 +972,12 @@ static void MakeNiceScreen (void)
/* Clear the screen hide the cursor, set colors */
#ifdef __CBM610__
textcolor (COLOR_WHITE);
(void)textcolor (COLOR_WHITE);
#else
textcolor (COLOR_GRAY3);
(void)textcolor (COLOR_GRAY3);
#endif
bordercolor (COLOR_BLACK);
bgcolor (COLOR_BLACK);
(void)bordercolor (COLOR_BLACK);
(void)bgcolor (COLOR_BLACK);
clrscr ();
cursor (0);

View File

@ -31,10 +31,62 @@ else
LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
endif
samples: hello
EXELIST_atari2600 = \
notavailable
EXELIST_bbc = \
notavailable
EXELIST_creativision = \
notavailable
EXELIST_gamate = \
notavailable
EXELIST_geos-cbm = \
notavailable
EXELIST_geos-apple = \
notavailable
EXELIST_lunix = \
notavailable
EXELIST_lynx = \
notavailable
EXELIST_nes = \
notavailable
EXELIST_osic1p = \
notavailable
EXELIST_pce = \
notavailable
EXELIST_supervision = \
notavailable
# Unlisted targets will try to build everything.
# That lets us learn what they cannot build, and what settings
# we need to use for programs that can be built and run.
ifndef EXELIST_$(SYS)
EXELIST_$(SYS) := ${patsubst %.c,%,$(wildcard *.c)}
endif
samples: $(EXELIST_$(SYS))
hello: hello.c text.s
$(CL) -t $(SYS) -o hello hello.c text.s
# empty target used to skip systems that will not work with any program in this dir
notavailable:
ifeq ($(MAKELEVEL),0)
@echo "info: tutorial sample not available for" $(SYS)
else
# suppress the "nothing to be done for 'samples' message
@echo > $(NULLDEV)
endif
clean:
@$(DEL) hello 2>$(NULLDEV)

View File

@ -438,9 +438,7 @@ void MacDef (unsigned Style)
/* Parse the parameter list */
if (HaveParams) {
while (CurTok.Tok == TOK_IDENT) {
/* Create a struct holding the identifier */
IdDesc* I = NewIdDesc (&CurTok.SVal);
@ -449,6 +447,7 @@ void MacDef (unsigned Style)
M->Params = I;
} else {
IdDesc* List = M->Params;
while (1) {
if (SB_Compare (&List->Id, &CurTok.SVal) == 0) {
Error ("Duplicate symbol '%m%p'", &CurTok.SVal);
@ -490,9 +489,8 @@ void MacDef (unsigned Style)
** the .LOCAL command is detected and removed, at this time.
*/
while (1) {
/* Check for include */
if (CurTok.Tok == TOK_INCLUDE) {
if (CurTok.Tok == TOK_INCLUDE && Style == MAC_STYLE_CLASSIC) {
/* Include another file */
NextTok ();
/* Name must follow */
@ -529,9 +527,7 @@ void MacDef (unsigned Style)
/* Check for a .LOCAL declaration */
if (CurTok.Tok == TOK_LOCAL && Style == MAC_STYLE_CLASSIC) {
while (1) {
IdDesc* I;
/* Skip .local or comma */
@ -570,6 +566,7 @@ void MacDef (unsigned Style)
if (CurTok.Tok == TOK_IDENT) {
unsigned Count = 0;
IdDesc* I = M->Params;
while (I) {
if (SB_Compare (&I->Id, &CurTok.SVal) == 0) {
/* Local param name, replace it */

View File

@ -80,6 +80,8 @@ static GenDesc GenOASGN = { TOK_OR_ASSIGN, GEN_NOPUSH, g_or };
static void parseadd (ExprDesc* Expr, int DoArrayRef);
static void PostInc (ExprDesc* Expr);
static void PostDec (ExprDesc* Expr);
@ -88,6 +90,7 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef);
/*****************************************************************************/
static unsigned GlobalModeFlags (const ExprDesc* Expr)
/* Return the addressing mode flags for the given expression */
{
@ -1510,7 +1513,8 @@ static void hie11 (ExprDesc *Expr)
Primary (Expr);
/* Check for a rhs */
while (CurTok.Tok == TOK_LBRACK || CurTok.Tok == TOK_LPAREN ||
while (CurTok.Tok == TOK_INC || CurTok.Tok == TOK_DEC ||
CurTok.Tok == TOK_LBRACK || CurTok.Tok == TOK_LPAREN ||
CurTok.Tok == TOK_DOT || CurTok.Tok == TOK_PTR_REF) {
switch (CurTok.Tok) {
@ -1554,6 +1558,14 @@ static void hie11 (ExprDesc *Expr)
StructRef (Expr);
break;
case TOK_INC:
PostInc (Expr);
break;
case TOK_DEC:
PostDec (Expr);
break;
default:
Internal ("Invalid token in hie11: %d", CurTok.Tok);
@ -2106,13 +2118,6 @@ void hie10 (ExprDesc* Expr)
/* An expression */
hie11 (Expr);
/* Handle post increment */
switch (CurTok.Tok) {
case TOK_INC: PostInc (Expr); break;
case TOK_DEC: PostDec (Expr); break;
default: break;
}
}
break;
}

View File

@ -644,7 +644,7 @@ void NewFunc (SymEntry* Func, FuncDesc* D)
/* Now process statements in this block */
while (CurTok.Tok != TOK_RCURLY && CurTok.Tok != TOK_CEOF) {
Statement (0);
AnyStatement (0);
}
/* If this is not a void function, and not the main function in a C99

View File

@ -163,7 +163,7 @@ static int IfStatement (void)
TestResult = TestInParens (Label1, 0);
/* Parse the if body */
GotBreak = Statement (0);
GotBreak = AnyStatement (0);
/* Else clause present? */
if (CurTok.Tok != TOK_ELSE) {
@ -195,7 +195,7 @@ static int IfStatement (void)
g_defcodelabel (Label1);
/* Total break only if both branches had a break. */
GotBreak &= Statement (0);
GotBreak &= AnyStatement (0);
/* Generate the label for the else clause */
g_defcodelabel (Label2);
@ -225,7 +225,7 @@ static void DoStatement (void)
g_defcodelabel (LoopLabel);
/* Parse the loop body */
Statement (0);
AnyStatement (0);
/* Output the label for a continue */
g_defcodelabel (ContinueLabel);
@ -283,7 +283,7 @@ static void WhileStatement (void)
g_defcodelabel (LoopLabel);
/* Loop body */
Statement (&PendingToken);
AnyStatement (&PendingToken);
/* Emit the while condition label */
g_defcodelabel (CondLabel);
@ -509,7 +509,7 @@ static void ForStatement (void)
/* Loop body */
g_defcodelabel (BodyLabel);
Statement (&PendingToken);
AnyStatement (&PendingToken);
/* If we had an increment expression, move the code to the bottom of
** the loop. In this case we don't need to jump there at the end of
@ -536,17 +536,20 @@ static void ForStatement (void)
static int CompoundStatement (void)
static int CompoundStatement (int* PendingToken)
/* Compound statement. Allow any number of statements inside braces. The
** function returns true if the last statement was a break or return.
*/
{
int GotBreak;
int GotBreak = 0;
/* Remember the stack at block entry */
int OldStack = StackPtr;
unsigned OldBlockStackSize = CollCount (&CurrentFunc->LocalsBlockStack);
/* Skip '{' */
NextToken ();
/* Enter a new lexical level */
EnterBlockLevel ();
@ -554,16 +557,15 @@ static int CompoundStatement (void)
DeclareLocals ();
/* Now process statements in this block */
GotBreak = 0;
while (CurTok.Tok != TOK_RCURLY) {
if (CurTok.Tok != TOK_CEOF) {
GotBreak = Statement (0);
GotBreak = AnyStatement (0);
} else {
break;
}
}
/* Clean up the stack. */
/* Clean up the stack if the codeflow may reach the end */
if (!GotBreak) {
g_space (StackPtr - OldStack);
}
@ -583,12 +585,80 @@ static int CompoundStatement (void)
/* Leave the lexical level */
LeaveBlockLevel ();
/* Skip '}' */
CheckTok (TOK_RCURLY, "'}' expected", PendingToken);
return GotBreak;
}
int Statement (int* PendingToken)
static void Statement (int* PendingToken)
/* Single-line statement */
{
ExprDesc Expr;
unsigned PrevErrorCount;
CodeMark Start, End;
/* Remember the current error count and code position */
PrevErrorCount = ErrorCount;
GetCodePos (&Start);
/* Actual statement */
ED_Init (&Expr);
Expr.Flags |= E_NEED_NONE;
Expression0 (&Expr);
/* If the statement didn't generate code, and is not of type
** void, emit a warning.
*/
GetCodePos (&End);
if (!ED_YetToLoad (&Expr) &&
!ED_MayHaveNoEffect (&Expr) &&
CodeRangeIsEmpty (&Start, &End) &&
IS_Get (&WarnNoEffect) &&
PrevErrorCount == ErrorCount) {
Warning ("Expression result unused");
}
CheckSemi (PendingToken);
}
static int ParseAnyLabels (void)
/* Return -1 if there are any labels with a statement */
{
unsigned PrevErrorCount = ErrorCount;
int HasLabels = 0;
for (;;) {
if (CurTok.Tok == TOK_IDENT && NextTok.Tok == TOK_COLON) {
/* C 'goto' label */
DoLabel ();
} else if (CurTok.Tok == TOK_CASE) {
/* C 'case' label */
CaseLabel ();
} else if (CurTok.Tok == TOK_DEFAULT) {
/* C 'default' label */
DefaultLabel ();
} else {
/* No labels */
break;
}
HasLabels = 1;
}
if (HasLabels) {
if (PrevErrorCount != ErrorCount || CheckLabelWithoutStatement ()) {
return -1;
}
}
return 0;
}
int AnyStatement (int* PendingToken)
/* Statement parser. Returns 1 if the statement does a return/break, returns
** 0 otherwise. If the PendingToken pointer is not NULL, the function will
** not skip the terminating token of the statement (closing brace or
@ -598,40 +668,27 @@ int Statement (int* PendingToken)
** NULL, the function will skip the token.
*/
{
ExprDesc Expr;
int GotBreak;
unsigned PrevErrorCount;
CodeMark Start, End;
ED_Init (&Expr);
/* Assume no pending token */
if (PendingToken) {
*PendingToken = 0;
}
/* Check for a label. A label is always part of a statement, it does not
/* Handle any labels. A label is always part of a statement, it does not
** replace one.
*/
while (CurTok.Tok == TOK_IDENT && NextTok.Tok == TOK_COLON) {
/* Handle the label */
DoLabel ();
if (CheckLabelWithoutStatement ()) {
return 0;
}
if (ParseAnyLabels ()) {
return 0;
}
switch (CurTok.Tok) {
case TOK_LCURLY:
NextToken ();
GotBreak = CompoundStatement ();
CheckTok (TOK_RCURLY, "'{' expected", PendingToken);
return GotBreak;
case TOK_IF:
return IfStatement ();
case TOK_SWITCH:
SwitchStatement ();
break;
case TOK_WHILE:
WhileStatement ();
break;
@ -640,10 +697,15 @@ int Statement (int* PendingToken)
DoStatement ();
break;
case TOK_SWITCH:
SwitchStatement ();
case TOK_FOR:
ForStatement ();
break;
case TOK_GOTO:
GotoStatement ();
CheckSemi (PendingToken);
return 1;
case TOK_RETURN:
ReturnStatement ();
CheckSemi (PendingToken);
@ -659,55 +721,22 @@ int Statement (int* PendingToken)
CheckSemi (PendingToken);
return 1;
case TOK_FOR:
ForStatement ();
break;
case TOK_GOTO:
GotoStatement ();
CheckSemi (PendingToken);
return 1;
case TOK_SEMI:
/* Ignore it */
CheckSemi (PendingToken);
break;
case TOK_PRAGMA:
DoPragma ();
break;
case TOK_CASE:
CaseLabel ();
CheckLabelWithoutStatement ();
case TOK_SEMI:
/* Empty statement. Ignore it */
CheckSemi (PendingToken);
break;
case TOK_DEFAULT:
DefaultLabel ();
CheckLabelWithoutStatement ();
break;
case TOK_LCURLY:
return CompoundStatement (PendingToken);
default:
/* Remember the current error count and code position */
PrevErrorCount = ErrorCount;
GetCodePos (&Start);
/* Actual statement */
Expr.Flags |= E_NEED_NONE;
Expression0 (&Expr);
/* If the statement didn't generate code, and is not of type
** void, emit a warning.
*/
GetCodePos (&End);
if (!ED_YetToLoad (&Expr) &&
!ED_MayHaveNoEffect (&Expr) &&
CodeRangeIsEmpty (&Start, &End) &&
IS_Get (&WarnNoEffect) &&
PrevErrorCount == ErrorCount) {
Warning ("Expression result unused");
}
CheckSemi (PendingToken);
/* Simple statement */
Statement (PendingToken);
break;
}
return 0;
}

View File

@ -44,7 +44,7 @@
int Statement (int* PendingToken);
int AnyStatement (int* PendingToken);
/* Statement parser. Returns 1 if the statement does a return/break, returns
** 0 otherwise. If the PendingToken pointer is not NULL, the function will
** not skip the terminating token of the statement (closing brace or

View File

@ -148,7 +148,7 @@ void SwitchStatement (void)
/* Parse the following statement, which may actually be a compound
** statement if there is a curly brace at the current input position
*/
HaveBreak = Statement (&RCurlyBrace);
HaveBreak = AnyStatement (&RCurlyBrace);
/* Check if we had any labels */
if (CollCount (SwitchData.Nodes) == 0 && SwitchData.DefaultLabel == 0) {

View File

@ -64,6 +64,7 @@ $(WORKDIR)/bug760.$1.$2.prg: bug760.c | $(WORKDIR)
$(if $(QUIET),echo misc/bug760.$1.$2.prg)
$(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR)
# should compile, but gives an error
$(WORKDIR)/bug1437.$1.$2.prg: bug1437.c | $(WORKDIR)
@echo "FIXME: " $$@ "currently does not compile."
$(if $(QUIET),echo misc/bug1437.$1.$2.prg)

51
test/todo/bug1462-2.c Normal file
View File

@ -0,0 +1,51 @@
/* issue #1462 - Bit-fields are still broken */
/* even the = operation is buggy in certain ways */
#include <stdio.h>
typedef struct {
signed int a : 3;
signed int b : 3;
signed int c : 3;
} T;
int failures = 0;
T *f(T *t)
{
t->a = 0;
t->c = 0;
return t;
}
void test(void)
{
T a = { 7, 0, 7 };
T *p = &a;
a.b = f(p)->a;
if (a.a != 0) {
++failures;
}
printf("%d\n", a.a);
if (p->b != 0) {
++failures;
}
printf("%d\n", p->b);
if ((&a)->c != 0) {
++failures;
}
printf("%d\n", (&a)->c);
printf("Failures: %d\n", failures);
}
int main(void)
{
test();
return failures;
}

95
test/todo/bug1462-3.c Normal file
View File

@ -0,0 +1,95 @@
/* issue #1462 - Bit-fields are still broken */
/* More testson "op= expression result value" that a naive fix might fail with */
#include <stdio.h>
typedef struct {
signed int a : 3;
unsigned int b : 3;
signed int c : 3;
unsigned int d : 3;
} T1;
typedef struct {
signed int a : 3;
signed int b : 3;
signed int c : 3;
signed int d : 3;
} T2;
int failures1 = 0;
int failures2 = 0;
void test1(void)
{
T1 a = { 3, 3, 3, 3 };
int i;
i = a.a += a.b + a.c;
if (i != 1) {
++failures1;
}
printf("i = %d, a.a = %d\n", i, a.a);
i = a.b *= -1;
if (i != 5 || a.b != 5) {
++failures1;
}
printf("i = %d, a.b = %d\n", i, a.b);
i = a.c * -1;
if (i != -3) {
++failures1;
}
printf("i = %d, a.c = %d\n", i, a.c);
i = a.d ^= -1;
if (i != 4 || a.d != 4) {
++failures1;
}
printf("i = %d, a.d = %d\n", i, a.d);
printf("Failures: %d\n", failures1);
}
void test2(void)
{
T2 b = { 3, 3, 4, 4 };
int i;
i = b.a++;
if (i != 3 || b.a != -4) {
++failures2;
}
printf("i = %d, b.a = %d\n", i, b.a);
i = ++b.b;
if (i != -4 || b.b != -4) {
++failures2;
}
printf("i = %d, b.b = %d\n", i, b.b);
i = b.c--;
if (i != -4 || b.c != 3) {
++failures2;
}
printf("i = %d, b.c = %d\n", i, b.c);
i = --b.d;
if (i != 3 || b.d != 3) {
++failures2;
}
printf("i = %d, b.d = %d\n", i, b.d);
printf("Failures: %d\n", failures2);
}
int main(void)
{
test1();
test2();
return failures1 + failures2;
}

13
test/val/bug1504.c Normal file
View File

@ -0,0 +1,13 @@
/* bug #1504 - Some compilation failures */
#include <stdio.h>
int main(void)
{
int i = 0, *p = &i;
switch (i) case 0: case 1: i = 21; /* Should be OK but fails */
p++[0] += 21; /* Should be OK but fails */
printf("%d\n", i);
return i != 42;
}