diff --git a/xa/ChangeLog b/xa/ChangeLog index 998c3c1..169bf18 100644 --- a/xa/ChangeLog +++ b/xa/ChangeLog @@ -383,3 +383,17 @@ xa-2.3.13 -- Cameron Kaiser 25 March 2022 +xa-2.3.14 + + * Fix a segfault when a recursive macro has a smaller arity than the + macro it references (thanks Emil Johansson for the report). + * Fix for recursive comments, which was a regression from 2.3.13 (note: + this may be reexamined for 2.4), and some improvements to the comment + parser to fix more edge cases. (Andre) + * Now you can just do 'make test TESTS=test,test,test' instead of running + ./tests/harness with specific options. ('make test' by itself of course + still works fine to run the whole suite.) + * Testsuite expanded. + +-- Cameron Kaiser 7 February 2023 + diff --git a/xa/Makefile b/xa/Makefile index 33d390e..ae0ccf3 100644 --- a/xa/Makefile +++ b/xa/Makefile @@ -4,7 +4,8 @@ CC = gcc LD = gcc # for testing. not to be used; build failures in misc/. #CFLAGS = -O2 -W -Wall -pedantic -ansi -CFLAGS = -O2 +#CFLAGS = -O2 -g +CFLAGS = -O2 LDFLAGS = -lc # for DOS? @@ -26,6 +27,8 @@ DOCDIR = $(DESTDIR)/share/doc MKDIR = mkdir -p INSTALL = install +TESTS=ALL + all: killxa xa uncpk killxa: @@ -53,7 +56,7 @@ clean: (cd src && ${MAKE} clean) (cd loader && ${MAKE} clean) (cd misc && ${MAKE} mrproper) - rm -f xa *.exe *.o65 *.s + rm -f xa *.exe *.o65 *.s core install: xa uncpk $(MKDIR) $(BINDIR) @@ -63,7 +66,9 @@ install: xa uncpk #$(MKDIR) $(DOCDIR)/xa65 dist: clean - cd .. ; tar cvf xa-2.3.13.tar xa-2.3.13 ; gzip xa-2.3.13.tar + cd .. ; tar cvf xa-2.3.14.tar xa-2.3.14 ; gzip xa-2.3.14.tar test: xa uncpk - cd tests && ./harness -make="$(MAKE)" -cc="$(CC)" -cflags="$(CFLAGS)" + cd tests && ./harness \ + -tests="$(TESTS)" \ + -make="$(MAKE)" -cc="$(CC)" -cflags="$(CFLAGS)" diff --git a/xa/man/file65.1 b/xa/man/file65.1 index 7e292a2..603db67 100644 --- a/xa/man/file65.1 +++ b/xa/man/file65.1 @@ -51,7 +51,7 @@ Show version of program. This manual page was written by David Weinehall and Cameron Kaiser . Original xa package (C)1989-1997 Andre Fachat. Additional changes -(C)1989-2006 Andre Fachat, Jolse Maginnis, David Weinehall and +(C)1989-2023 Andre Fachat, Jolse Maginnis, David Weinehall and Cameron Kaiser. The current maintainer is Cameron Kaiser. .SH WEBSITE diff --git a/xa/man/ldo65.1 b/xa/man/ldo65.1 index 87e0b36..594ce92 100644 --- a/xa/man/ldo65.1 +++ b/xa/man/ldo65.1 @@ -53,7 +53,7 @@ Show version of program. This manual page was written by David Weinehall and Cameron Kaiser . Original xa package (C)1989-1997 Andre Fachat. Additional changes -(C)1989-2006 Andre Fachat, Jolse Maginnis, David Weinehall and +(C)1989-2023 Andre Fachat, Jolse Maginnis, David Weinehall and Cameron Kaiser. The current maintainer is Cameron Kaiser. .SH WEBSITE diff --git a/xa/man/printcbm.1 b/xa/man/printcbm.1 index db252e9..a327a4c 100644 --- a/xa/man/printcbm.1 +++ b/xa/man/printcbm.1 @@ -30,7 +30,7 @@ Show version of program. .SH AUTHOR This manual page was written by David Weinehall . Original xa package (C)1989-1997 Andre Fachat. Additional changes -(C)1989-2006 Andre Fachat, Jolse Maginnis, David Weinehall and +(C)1989-2023 Andre Fachat, Jolse Maginnis, David Weinehall and Cameron Kaiser. The current maintainer is Cameron Kaiser. .SH WEBSITE diff --git a/xa/man/reloc65.1 b/xa/man/reloc65.1 index ba891a9..6a90214 100644 --- a/xa/man/reloc65.1 +++ b/xa/man/reloc65.1 @@ -61,7 +61,7 @@ Show version of program. This manual page was written by David Weinehall and Cameron Kaiser . Original xa package (C)1989-1997 Andre Fachat. Additional changes -(C)1989-2006 Andre Fachat, Jolse Maginnis, David Weinehall and +(C)1989-2023 Andre Fachat, Jolse Maginnis, David Weinehall and Cameron Kaiser. The current maintainer is Cameron Kaiser. .SH WEBSITE diff --git a/xa/man/uncpk.1 b/xa/man/uncpk.1 index 20b905e..3be6e34 100644 --- a/xa/man/uncpk.1 +++ b/xa/man/uncpk.1 @@ -70,7 +70,7 @@ List contents of archive This manual page was written by David Weinehall and Cameron Kaiser . Original xa package (C)1989-1997 Andre Fachat. Additional changes -(C)1989-2006 Andre Fachat, Jolse Maginnis, David Weinehall and +(C)1989-2023 Andre Fachat, Jolse Maginnis, David Weinehall and Cameron Kaiser. The current maintainer is Cameron Kaiser. .SH WEBSITE diff --git a/xa/man/xa.1 b/xa/man/xa.1 index 5b060e3..2729ce1 100644 --- a/xa/man/xa.1 +++ b/xa/man/xa.1 @@ -982,7 +982,7 @@ This manual page was written by David Weinehall , Andre Fachat and Cameron Kaiser . Original xa package (C)1989-1997 Andre Fachat. Additional changes -(C)1989-2021 Andre Fachat, Jolse Maginnis, David Weinehall, +(C)1989-2023 Andre Fachat, Jolse Maginnis, David Weinehall, Cameron Kaiser. The official maintainer is Cameron Kaiser. .SH 30 YEARS OF XA diff --git a/xa/src/xa.c b/xa/src/xa.c index 02e305e..7d5a1b7 100644 --- a/xa/src/xa.c +++ b/xa/src/xa.c @@ -55,9 +55,9 @@ #define ANZWARN 13 #define programname "xa" -#define progversion "v2.3.13" +#define progversion "v2.3.14" #define authors "Written by Andre Fachat, Jolse Maginnis, David Weinehall and Cameron Kaiser" -#define copyright "Copyright (C) 1989-2022 Andre Fachat, Jolse Maginnis, David Weinehall\nand Cameron Kaiser." +#define copyright "Copyright (C) 1989-2023 Andre Fachat, Jolse Maginnis, David Weinehall\nand Cameron Kaiser." /* exported globals */ int ncmos, cmosfl, w65816, n65816; diff --git a/xa/src/xap.c b/xa/src/xap.c index 4dff224..bdde75e 100644 --- a/xa/src/xap.c +++ b/xa/src/xap.c @@ -59,7 +59,6 @@ static int pp_undef(char*); #define ANZBEF 13 #define VALBEF 6 -static int ungeteof = 0; static int quotebs = 0; static int inquote = 0; @@ -589,6 +588,10 @@ int pp_replace(char *to, char *ti, int a,int b) if (++j>10) errout(E_ORECMAC); } + if (liste[rlist+i].replace == NULL) { + errout(E_ANZPAR); + return E_ANZPAR; + } (void)strcpy(liste[rlist+i].replace, nfto); #ifdef DEBUG_RECMAC printf("FINAL: -%s=%s\n",liste[rlist+i].search,liste[rlist+i].replace); @@ -926,39 +929,6 @@ int pgetline(char *t) errout(E_OPENPP); } - /* handle the double-slash comment (like in C++) */ - /* get p past any quoted strings */ - p = strchr(in_line, '/'); - if (p != NULL) { - q = strchr(in_line, '"'); - for(;;) { - /* no more quotes to skip, or slashes before quotes */ - if (q == NULL || (p < q)) { - if (p[1] == '/') { - /* truncate line, done with loop */ - *p = 0; - break; - } else { - /* wasn't //, but could be later */ - p++; - } - } else { - /* quote before slash, so skip string */ - q++; - while (*q != 0 && *q != '"') { - if (*q == '\\') q++; - if (*q != 0) q++; - } - if (*q == 0) break; /* oops */ - q++; - p = q; - } - - p = strchr(p, '/'); - if (p == NULL) break; /* never mind */ - if (q != NULL) q = strchr(q, '"'); - } - } if(!er || loopfl) { in_line[0]='\0'; @@ -984,79 +954,123 @@ int pgetline(char *t) /*************************************************************************/ -/* this is the most disgusting code I have ever written, but Andre drove me -to it because I can't think of any other F$%Y#*U(%&Y##^#KING way to fix the -last line bug ... a very irritated Cameron */ - -/* however, it also solved the problem of open #ifdefs not bugging out */ - -/* #define DEBUG_EGETC */ -int egetc(FILE *fp) { - int c; - - c = getc(fp); - if (c == EOF) { - if (ungeteof) { -#ifdef DEBUG_EGETC - fprintf(stderr, "eof claimed\n"); -#endif - return c; - } else { -#ifdef DEBUG_EGETC - fprintf(stderr, "got eof!!\n"); -#endif - ungeteof = 1; - return '\n'; - } - } - ungeteof = 0; - return c; -} - /* smart getc that can skip C comment blocks */ int rgetc(FILE *fp) { - static int c,cc,d,fl; - cc=0; - fl=0; + int incomment; + int c; + static int d; + static int d_isvalid = 0; + static int last = 0; + + incomment=0; do { - while((c=egetc(fp))==13); /* remove ^M for unices */ + restart: - /* flag if we're in a quoted string */ - if(c=='"' && !quotebs) inquote ^= 1; -#if(0) -/* implement backslashed quotes for 2.4 */ - if(c=='\\') quotebs=1; else quotebs=0; -#endif + /* we had a look-ahead to see if two-char sequence was received? */ + if (d_isvalid) { + c = d; + d_isvalid = 0; + } else { + c = getc(fp); + } + while(c==13) { + c = getc(fp); + }; /* remove ^M for unices */ - if(!inquote && fl && (c=='*')) - { - if((d=egetc(fp))!='/') - ungetc(d,fp); - else - { - fl--; - while((c=egetc(fp))==13); - } - } + /* a newlinebreaks any quote */ + if (c == '\n') { + inquote = 0; - /* in comment block */ - if(c=='\n') - { - flist[fsp].fline++; - nlf=1; - } else + flist[fsp].fline++; + nlf=1; + } + + /* check for start of comment anyway, to allow for nestesd comments */ if(!inquote && c=='/') { - if((d=egetc(fp))!='*') - ungetc(d,fp); - else - fl++; + d = getc(fp); + + // C++ double slash comment + if (d == '/') { + do { + c = getc(fp); + } while (c != '\n' && c != EOF); + } else + if (d == '*') { + /* start block comment */ + incomment++; + /* convene normal processing */ + goto restart; + } else { + d_isvalid = 1; + } } - } while(fl && (c!=EOF)); + + /* here we are in a dilemma. If we interpret quotes in comments, + * this may break end-of-block comment when singular quotes are + * in a comment. If we don't interpret quotes in a comment, + * a quoted string with end-of-comment in it may break when + * commented. + * + * Unfortunately GeckOS has quotes in comments, and in an inconsistent way. + * + * #define E_FILLNAM <-34 / * illegal name (joker "*","?","\"") * / + * + * ... except if we handle backslash-escaped quotes? No, then this breaks + * in apps/lsh/lsh.a65:347 + * + * / * TODO: interpret "\" escape codes, shell variables * / + * + * But I guess for 2.4 it is ok to break things like this. + */ + + if (!incomment) { + /* not in comment */ + + /* flag if we're in a quoted string */ + /* but only if quote isnot escaped with backslash */ + if(c=='"' && last!='\\' && !quotebs) { + inquote ^= 1; + } + +#if(0) +/* implement backslashed quotes for 2.4 */ + if(c=='\\') quotebs=1; else quotebs=0; +#endif + + + + } else { + /* in comment */ + + /* check for end of comment */ + /* note: incomment only set true if not quoted, and quote not changed in comment */ + if((!inquote) && (c=='*')) + { + if((d=getc(fp))!='/') { + d_isvalid = 1; + } else { + incomment--; + /* convene normal processing */ + goto restart; + } + } + + } + + /* force newline at the end of a file */ + if (c == EOF && last != EOF) { + last = EOF; + c = '\n'; + } else { + last = c; + } + + } while(incomment && (c!=EOF)); return(c-'\t'?c:' '); } diff --git a/xa/tests/README b/xa/tests/README index c773221..fad09fc 100644 --- a/xa/tests/README +++ b/xa/tests/README @@ -44,6 +44,8 @@ linkr/ Test linking using .dsb and generated code csapiec/ Test on pointer arithmetic in relocating mode math/ Math tests (currently divide by zero, thanks Frederic Cambus) alxl/ Various '816 width tests (includes Samuel Falvo's test) +pparity/ Tests of preprocessor macro arity (with Emil Johansson's test) +recucom/ Recursive comments test Cameron Kaiser, André Fachat diff --git a/xa/tests/harness b/xa/tests/harness index ddcacbb..8662f1b 100755 --- a/xa/tests/harness +++ b/xa/tests/harness @@ -8,7 +8,9 @@ $ENV{'CC'} = $cc; $ENV{'CFLAGS'} = $cflags; $|++; +$ntests = 0; $dtests = $tests || "ALL"; +$tests = '' if ($tests eq "ALL"); print <<"EOF"; CC = $cc @@ -43,12 +45,14 @@ W: while($x = readdir(D)) { } system("$make clean"); print STDOUT "=" x 35, " PASSED! ", "=" x 35, "\n"; + $ntests++; } elsif (-e "ok" && -e "test.s") { unlink("a.o65"); &failed("../../xa test.s"); &failed("../hextool -cmp=ok < a.o65"); unlink("a.o65"); print STDOUT "PASSED\n"; + $ntests++; } else { print STDOUT "ignored\n"; } @@ -56,8 +60,12 @@ W: while($x = readdir(D)) { } closedir(D); print STDOUT "=" x 79, "\n"; -print STDOUT "\n## ALL TESTS PASS ##\n"; -exit 0; +if ($ntests) { # ntestacy is a terrible thing + print STDOUT "\n## ALL SELECTED TESTS PASS ($dtests, n=$ntests) ##\n"; + exit 0; +} +print STDOUT "\n## NO TESTS WERE RUN ##\n"; +exit 1; sub failed { system(@_);