From 86bd6b9addc7650560826e3c21c7b393567d3cc0 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sat, 15 May 2021 19:48:19 +0200 Subject: [PATCH 01/20] Added executable list for all targets and print a message when certain samples are not available for a target (instead of failing). This makes "make SYS=" in samples recursively work for all supported targets. --- samples/Makefile | 152 ++++++++++++++++++++++++++++++++++---- samples/geos/Makefile | 35 +++++++-- samples/geos/grc/Makefile | 29 ++++++-- samples/tutorial/Makefile | 48 +++++++++++- 4 files changed, 234 insertions(+), 30 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index 6e89cb802..e8b9824d8 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -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,141 @@ 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 \ + diodemo + +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 +343,10 @@ 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: + @echo "warning: generic samples not available for" $(SYS) + disk: $(DISK_$(SYS)) all: diff --git a/samples/geos/Makefile b/samples/geos/Makefile index 00841ee8f..9ad555565 100644 --- a/samples/geos/Makefile +++ b/samples/geos/Makefile @@ -37,17 +37,42 @@ DIRLIST = grc define SUBDIR_recipe -@$(MAKE) -C $(dir) --no-print-directory $@ +@$(MAKE) SYS=$(SYS) -C $(dir) --no-print-directory $@ endef # SUBDIR_recipe +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 - $(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) +ifneq ($(EXELIST_$(SYS)),) +samples: $(EXELIST_$(SYS)) + $(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) +else +samples: + @echo "warning: geos samples not available for" $(SYS) +endif + + bitmap.c: logo.pcx $(SP) -r logo.pcx -c geos-bitmap -w bitmap.c,ident=bitmap diff --git a/samples/geos/grc/Makefile b/samples/geos/grc/Makefile index 81f9ca045..0a432fd89 100644 --- a/samples/geos/grc/Makefile +++ b/samples/geos/grc/Makefile @@ -1,4 +1,8 @@ +# Run 'make SYS='; 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,31 @@ 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: + @echo "warning: grc sample not available for" $(SYS) +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) diff --git a/samples/tutorial/Makefile b/samples/tutorial/Makefile index 2c4bcb988..39b2d6e8c 100644 --- a/samples/tutorial/Makefile +++ b/samples/tutorial/Makefile @@ -31,10 +31,56 @@ 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: + @echo "warning: tutorial sample not available for" $(SYS) clean: @$(DEL) hello 2>$(NULLDEV) From aecb01986a6c7154ce6e81ac1f319c9193eee979 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sun, 16 May 2021 15:45:34 +0200 Subject: [PATCH 02/20] fix list of executables for geos-apple --- samples/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index e8b9824d8..90fba50c9 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -271,8 +271,7 @@ EXELIST_geos-cbm = \ diodemo EXELIST_geos-apple = \ - ascii \ - diodemo + ascii EXELIST_lunix = \ notavailable From 53f0552fe71f1aed5534c8e04f99fb0fa75256cf Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sun, 16 May 2021 17:12:50 +0200 Subject: [PATCH 03/20] fix warnings --- samples/nachtm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/samples/nachtm.c b/samples/nachtm.c index 0b962fa5d..02801da24 100644 --- a/samples/nachtm.c +++ b/samples/nachtm.c @@ -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); From 4ba3ff3048e0baffac77f671c6947afdeee775df Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sun, 16 May 2021 18:23:23 +0200 Subject: [PATCH 04/20] redirect c64 to geos-cbm and apple2enh to geos-apple when given with SYS= on the command line, as suggested by oliver --- samples/geos/Makefile | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/samples/geos/Makefile b/samples/geos/Makefile index 9ad555565..a894c5d01 100644 --- a/samples/geos/Makefile +++ b/samples/geos/Makefile @@ -3,6 +3,17 @@ # 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 +endif +ifeq "$(SYS)" "apple2enh" + override SYS = geos-apple +endif +endif + # Just the usual way to find out if we're # using cmd.exe to execute make rules. ifneq ($(shell echo),) From a9af6aa74334483c09fd367ab01c5d4358ab7120 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sun, 16 May 2021 18:29:45 +0200 Subject: [PATCH 05/20] fix warnings --- samples/geos/geosver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/geos/geosver.c b/samples/geos/geosver.c index 1402d148e..3d68798a2 100644 --- a/samples/geos/geosver.c +++ b/samples/geos/geosver.c @@ -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); From 43ca88726344b82065bf83dd5b693f7b6006c94e Mon Sep 17 00:00:00 2001 From: acqn Date: Sun, 16 May 2021 16:06:52 +0800 Subject: [PATCH 06/20] Fixed 'case'/'default' labels in non-compound 'switch' body statement. --- src/cc65/function.c | 2 +- src/cc65/stmt.c | 177 ++++++++++++++++++++++++++------------------ src/cc65/stmt.h | 2 +- src/cc65/swstmt.c | 2 +- 4 files changed, 106 insertions(+), 77 deletions(-) diff --git a/src/cc65/function.c b/src/cc65/function.c index 4e61cc1d3..452181af9 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -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 diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index ccb113978..022a8475c 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -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; } diff --git a/src/cc65/stmt.h b/src/cc65/stmt.h index 04ef728a3..8cff99d92 100644 --- a/src/cc65/stmt.h +++ b/src/cc65/stmt.h @@ -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 diff --git a/src/cc65/swstmt.c b/src/cc65/swstmt.c index 3878f7b67..ee0bd1a85 100644 --- a/src/cc65/swstmt.c +++ b/src/cc65/swstmt.c @@ -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) { From 1450f146a50ac257eea145607801d4f6b1cb4bfb Mon Sep 17 00:00:00 2001 From: acqn Date: Sun, 16 May 2021 16:09:45 +0800 Subject: [PATCH 07/20] Fixed '[]', '()' '.' and '->' operators following a postfix increment/decrement. --- src/cc65/expr.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index a63214f49..b68b3abbb 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -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; } From ce487651b09901fbd69183e69425d830505900e8 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sun, 16 May 2021 22:24:35 +0200 Subject: [PATCH 08/20] as suggested by Oliver: - only output messages if MAKELEVEL is 0 - indent nested ifeq - use if (,) syntax --- samples/Makefile | 4 +++- samples/geos/Makefile | 20 ++++++++++++-------- samples/geos/grc/Makefile | 4 +++- samples/tutorial/Makefile | 5 ++++- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index 90fba50c9..f1e7a1e0b 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -344,7 +344,9 @@ samples: $(EXELIST_$(SYS)) # empty target used to skip systems that will not work with any program in this dir notavailable: - @echo "warning: generic samples not available for" $(SYS) +ifeq ($(MAKELEVEL),0) + @echo "info: generic samples not available for" $(SYS) +endif disk: $(DISK_$(SYS)) diff --git a/samples/geos/Makefile b/samples/geos/Makefile index a894c5d01..0bf862ca7 100644 --- a/samples/geos/Makefile +++ b/samples/geos/Makefile @@ -5,13 +5,15 @@ 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 -endif -ifeq "$(SYS)" "apple2enh" - override SYS = geos-apple -endif +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 @@ -80,7 +82,9 @@ samples: $(EXELIST_$(SYS)) $(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) else samples: - @echo "warning: geos samples not available for" $(SYS) + ifeq ($(MAKELEVEL),0) + @echo "info: geos samples not available for" $(SYS) + endif endif diff --git a/samples/geos/grc/Makefile b/samples/geos/grc/Makefile index 0a432fd89..4ad4f00a6 100644 --- a/samples/geos/grc/Makefile +++ b/samples/geos/grc/Makefile @@ -41,7 +41,9 @@ ifneq ($(EXELIST_$(SYS)),) samples: $(EXELIST_$(SYS)) else samples: - @echo "warning: grc sample not available for" $(SYS) + ifeq ($(MAKELEVEL),0) + @echo "info: grc sample not available for" $(SYS) + endif endif test.s: test.grc diff --git a/samples/tutorial/Makefile b/samples/tutorial/Makefile index 39b2d6e8c..911988db5 100644 --- a/samples/tutorial/Makefile +++ b/samples/tutorial/Makefile @@ -81,6 +81,9 @@ hello: hello.c text.s # empty target used to skip systems that will not work with any program in this dir notavailable: - @echo "warning: tutorial sample not available for" $(SYS) +ifeq ($(MAKELEVEL),0) + @echo "info: tutorial sample not available for" $(SYS) +endif + clean: @$(DEL) hello 2>$(NULLDEV) From 5fc9d3f048f8897bce1c56a4359af1221f6141b9 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sun, 16 May 2021 22:57:28 +0200 Subject: [PATCH 09/20] change driver _install calls from taking "void*" to "const void*" --- include/em.h | 2 +- include/joystick.h | 2 +- include/serial.h | 2 +- include/tgi.h | 2 +- libsrc/em/em-kernel.s | 2 +- libsrc/joystick/joy-kernel.s | 2 +- libsrc/serial/ser-kernel.s | 2 +- libsrc/tgi/tgi-kernel.s | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/em.h b/include/em.h index b151800ae..47bd23222 100644 --- a/include/em.h +++ b/include/em.h @@ -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); diff --git a/include/joystick.h b/include/joystick.h index b6771c381..963c9ba95 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -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); diff --git a/include/serial.h b/include/serial.h index 990f66521..58943d507 100644 --- a/include/serial.h +++ b/include/serial.h @@ -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); diff --git a/include/tgi.h b/include/tgi.h index 135ef63f1..2ef65b856 100644 --- a/include/tgi.h +++ b/include/tgi.h @@ -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); diff --git a/libsrc/em/em-kernel.s b/libsrc/em/em-kernel.s index c982dac88..d5be0ae23 100644 --- a/libsrc/em/em-kernel.s +++ b/libsrc/em/em-kernel.s @@ -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 */ diff --git a/libsrc/joystick/joy-kernel.s b/libsrc/joystick/joy-kernel.s index c2d50c8d8..53d475c57 100644 --- a/libsrc/joystick/joy-kernel.s +++ b/libsrc/joystick/joy-kernel.s @@ -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 */ diff --git a/libsrc/serial/ser-kernel.s b/libsrc/serial/ser-kernel.s index 4c5b455b6..b6c57a3b5 100644 --- a/libsrc/serial/ser-kernel.s +++ b/libsrc/serial/ser-kernel.s @@ -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 */ diff --git a/libsrc/tgi/tgi-kernel.s b/libsrc/tgi/tgi-kernel.s index 3a388b6dc..cbd655279 100644 --- a/libsrc/tgi/tgi-kernel.s +++ b/libsrc/tgi/tgi-kernel.s @@ -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. */ From d2da30a7e25cb6f918af10b6d69dbabdc369512a Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sun, 16 May 2021 23:38:17 +0200 Subject: [PATCH 10/20] give the "samples" target something to do to supress the "nothing to be done for 'samples'" message --- samples/geos/Makefile | 4 +++- samples/geos/grc/Makefile | 3 +++ samples/tutorial/Makefile | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/samples/geos/Makefile b/samples/geos/Makefile index 0bf862ca7..e792c52f1 100644 --- a/samples/geos/Makefile +++ b/samples/geos/Makefile @@ -84,10 +84,12 @@ 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 diff --git a/samples/geos/grc/Makefile b/samples/geos/grc/Makefile index 4ad4f00a6..9dd9ebc5e 100644 --- a/samples/geos/grc/Makefile +++ b/samples/geos/grc/Makefile @@ -43,6 +43,9 @@ 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 diff --git a/samples/tutorial/Makefile b/samples/tutorial/Makefile index 911988db5..af5062588 100644 --- a/samples/tutorial/Makefile +++ b/samples/tutorial/Makefile @@ -83,6 +83,9 @@ hello: hello.c text.s 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: From c53059468e8a96e4ade3781aa87a0faa5f1abc4a Mon Sep 17 00:00:00 2001 From: mrdudz Date: Mon, 17 May 2021 14:25:18 +0200 Subject: [PATCH 11/20] fix documentation for the driver _init calls --- doc/funcref.sgml | 6 +++--- doc/tgi.sgml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 4d1a278b0..2cb8bbf44 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -3410,7 +3410,7 @@ loaded. / - / - / - / - Date: Mon, 17 May 2021 14:25:33 +0200 Subject: [PATCH 12/20] added a missing comment --- test/misc/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/test/misc/Makefile b/test/misc/Makefile index 397635afd..b17c69f5c 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -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) From 4a57656f692c5fb08fe80e0c665d852d8e32388b Mon Sep 17 00:00:00 2001 From: mrdudz Date: Mon, 17 May 2021 14:40:09 +0200 Subject: [PATCH 13/20] add test for issue #1504 --- test/val/bug1504.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 test/val/bug1504.c diff --git a/test/val/bug1504.c b/test/val/bug1504.c new file mode 100644 index 000000000..bd93c7387 --- /dev/null +++ b/test/val/bug1504.c @@ -0,0 +1,13 @@ + +/* bug #1504 - Some compilation failures */ + +#include + +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; +} From d14148ab4f9d8d1d52025eac31bfc09d977fbaa7 Mon Sep 17 00:00:00 2001 From: Greg King Date: Mon, 17 May 2021 19:48:47 -0400 Subject: [PATCH 14/20] Restricted commit b9a3c7888822732a0de92741cfe1a3e1b6bb272f to classic-style Assembly macros. .include will work at expansion-time for .define macros. --- src/ca65/macro.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 34d87e65f..d6c807035 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -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 */ From 6d560f42366ecbd12f05f6ce121ffa7685497114 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Tue, 18 May 2021 15:16:14 +0200 Subject: [PATCH 15/20] change prototype for GraphicsString() to void __fastcall__ GraphicsString(const void *myGfxString); --- doc/geos.sgml | 2 +- include/geos/ggraph.h | 2 +- libsrc/geos-common/graph/graphicsstring.s | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/geos.sgml b/doc/geos.sgml index 11ff9c534..f7943f8cd 100644 --- a/doc/geos.sgml +++ b/doc/geos.sgml @@ -205,7 +205,7 @@ see them together in the filling box in GeoPaint. GraphicsString

- 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. diff --git a/include/geos/ggraph.h b/include/geos/ggraph.h index ec9fb0fa1..b550d6ca1 100644 --- a/include/geos/ggraph.h +++ b/include/geos/ggraph.h @@ -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); diff --git a/libsrc/geos-common/graph/graphicsstring.s b/libsrc/geos-common/graph/graphicsstring.s index 86c74f1a6..282649284 100644 --- a/libsrc/geos-common/graph/graphicsstring.s +++ b/libsrc/geos-common/graph/graphicsstring.s @@ -3,7 +3,7 @@ ; ; 25.12.99 -; void GraphicsString (char *myString); +; void GraphicsString (const void *myString); .export _GraphicsString From 0ae1aad3d3705b5cbae0d0ff74fae711bc505f52 Mon Sep 17 00:00:00 2001 From: Olli Savia Date: Wed, 19 May 2021 21:08:43 +0300 Subject: [PATCH 16/20] Fix typo: VIAx_CR -> VIAx_ACR --- asminc/vic20.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asminc/vic20.inc b/asminc/vic20.inc index 41a935238..7184ab6ee 100644 --- a/asminc/vic20.inc +++ b/asminc/vic20.inc @@ -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 From 681c9594cc37581c50d48b67364398bdedeae4bf Mon Sep 17 00:00:00 2001 From: Christian Groessler Date: Fri, 21 May 2021 01:45:55 +0200 Subject: [PATCH 17/20] libsrc/atari5200/crt0.s: fix formatting --- libsrc/atari5200/crt0.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/atari5200/crt0.s b/libsrc/atari5200/crt0.s index 9538d3bb4..8f6e02273 100644 --- a/libsrc/atari5200/crt0.s +++ b/libsrc/atari5200/crt0.s @@ -44,4 +44,4 @@ _exit: jsr donelib ; Run module destructors ; A 5200 program isn't supposed to exit. -halt: jmp halt +halt: jmp halt From 663268dca98856a0280a49cc0582a77cd511a05f Mon Sep 17 00:00:00 2001 From: Greg King Date: Fri, 21 May 2021 03:32:43 -0400 Subject: [PATCH 18/20] Syncronize the Supervision crt0.s with its ld65 config files. .segment "VECTOR" -> "VECTORS". Fixes #1506. --- libsrc/supervision/crt0.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/supervision/crt0.s b/libsrc/supervision/crt0.s index 203c681b8..fbae1fc46 100644 --- a/libsrc/supervision/crt0.s +++ b/libsrc/supervision/crt0.s @@ -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 From e13f57e86c37ae2601bed1d980fc1fa73915ff3b Mon Sep 17 00:00:00 2001 From: mrdudz Date: Fri, 21 May 2021 16:09:10 +0200 Subject: [PATCH 19/20] added another testcase for issue #1462 --- test/todo/bug1462-2.c | 51 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 test/todo/bug1462-2.c diff --git a/test/todo/bug1462-2.c b/test/todo/bug1462-2.c new file mode 100644 index 000000000..df94cfc59 --- /dev/null +++ b/test/todo/bug1462-2.c @@ -0,0 +1,51 @@ + +/* issue #1462 - Bit-fields are still broken */ +/* even the = operation is buggy in certain ways */ + +#include + +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; +} From b08dc28cc1cb2241515d69ccdd89a3ac31afc788 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sat, 22 May 2021 22:34:52 +0200 Subject: [PATCH 20/20] another testcase related to issue #1462 --- test/todo/bug1462-3.c | 95 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 test/todo/bug1462-3.c diff --git a/test/todo/bug1462-3.c b/test/todo/bug1462-3.c new file mode 100644 index 000000000..b75d568b9 --- /dev/null +++ b/test/todo/bug1462-3.c @@ -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 + +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; +} +