mirror of
https://github.com/fachat/xa65.git
synced 2025-02-06 03:29:58 +00:00
update to official xa-2.3.13
This commit is contained in:
parent
5d66d3a11a
commit
b5c1e9b902
20
xa/ChangeLog
20
xa/ChangeLog
@ -363,3 +363,23 @@ xa-2.3.11
|
||||
|
||||
-- Cameron Kaiser <ckaiser@floodgap.com> 4 May 2020
|
||||
|
||||
xa-2.3.12
|
||||
|
||||
* Regression fix for address size validation in 65816 mode (thanks Sam
|
||||
Falvo; we had a pending fix for this but I like his test case).
|
||||
* Testsuite expanded.
|
||||
|
||||
-- Cameron Kaiser <ckaiser@floodgap.com> 26 November 2021
|
||||
|
||||
xa-2.3.13
|
||||
|
||||
* Fix // and /* */ in quoted strings. Incredible no one ever hit this
|
||||
before (thanks ZornsLemma).
|
||||
* Segfault fixes for file65, reloc65 and xa. Remember, kids, if you ever
|
||||
run xa as root all kittens will die. Please save the kittens (thanks
|
||||
Stephen Kitt).
|
||||
* Just compare to null in the preprocessor (thanks Bas Wassink).
|
||||
* Testsuite expanded.
|
||||
|
||||
-- Cameron Kaiser <ckaiser@floodgap.com> 25 March 2022
|
||||
|
||||
|
@ -53,7 +53,7 @@ clean:
|
||||
(cd src && ${MAKE} clean)
|
||||
(cd loader && ${MAKE} clean)
|
||||
(cd misc && ${MAKE} mrproper)
|
||||
rm -f xa *.exe *.o65
|
||||
rm -f xa *.exe *.o65 *.s
|
||||
|
||||
install: xa uncpk
|
||||
$(MKDIR) $(BINDIR)
|
||||
@ -63,7 +63,7 @@ install: xa uncpk
|
||||
#$(MKDIR) $(DOCDIR)/xa65
|
||||
|
||||
dist: clean
|
||||
cd .. ; tar cvf xa-2.3.12.tar xa-2.3.12 ; gzip xa-2.3.12.tar
|
||||
cd .. ; tar cvf xa-2.3.13.tar xa-2.3.13 ; gzip xa-2.3.13.tar
|
||||
|
||||
test: xa uncpk
|
||||
cd tests && ./harness -make="$(MAKE)" -cc="$(CC)" -cflags="$(CFLAGS)"
|
||||
|
@ -101,13 +101,14 @@ int main(int argc, char *argv[]) {
|
||||
rompar = 1;
|
||||
if(argv[i][1]=='A') rompar++;
|
||||
if(argv[i][2]) romoff = atoi(argv[i]+2);
|
||||
else romoff = atoi(argv[++i]);
|
||||
else if(i + 1 < argc) romoff = atoi(argv[++i]);
|
||||
else fprintf(stderr,"%s: missing offset\n",programname);
|
||||
break;
|
||||
case 'P':
|
||||
xapar = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"file65: %s unknown option\n",argv[i]);
|
||||
fprintf(stderr,"%s: %s unknown option\n",programname,argv[i]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
@ -84,6 +84,7 @@ int main(int argc, char *argv[]) {
|
||||
FILE *fp;
|
||||
int tflag = 0, dflag = 0, bflag = 0, zflag = 0;
|
||||
int tbase = 0, dbase = 0, bbase = 0, zbase = 0;
|
||||
int *base;
|
||||
char *outfile = "a.o65";
|
||||
int extract = 0;
|
||||
|
||||
@ -108,37 +109,40 @@ int main(int argc, char *argv[]) {
|
||||
switch(argv[i][1]) {
|
||||
case 'o':
|
||||
if(argv[i][2]) outfile=argv[i]+2;
|
||||
else outfile=argv[++i];
|
||||
else if(i + 1 < argc) outfile=argv[++i];
|
||||
else fprintf(stderr,"%s: missing output file\n",programname);
|
||||
break;
|
||||
case 'X':
|
||||
extract=3;
|
||||
break;
|
||||
case 'b':
|
||||
base=NULL;
|
||||
switch(argv[i][2]) {
|
||||
case 't':
|
||||
tflag= 1;
|
||||
if(argv[i][3]) tbase = atoi(argv[i]+3);
|
||||
else tbase = atoi(argv[++i]);
|
||||
base=&tbase;
|
||||
break;
|
||||
case 'd':
|
||||
dflag= 1;
|
||||
if(argv[i][3]) dbase = atoi(argv[i]+3);
|
||||
else dbase = atoi(argv[++i]);
|
||||
base=&dbase;
|
||||
break;
|
||||
case 'b':
|
||||
bflag= 1;
|
||||
if(argv[i][3]) bbase = atoi(argv[i]+3);
|
||||
else bbase = atoi(argv[++i]);
|
||||
base=&bbase;
|
||||
break;
|
||||
case 'z':
|
||||
zflag= 1;
|
||||
if(argv[i][3]) zbase = atoi(argv[i]+3);
|
||||
else zbase = atoi(argv[++i]);
|
||||
base=&zbase;
|
||||
break;
|
||||
default:
|
||||
printf("Unknown segment type '%c' - ignored!\n", argv[i][2]);
|
||||
break;
|
||||
}
|
||||
if (base != NULL) {
|
||||
if(argv[i][3]) *base = atoi(argv[i]+3);
|
||||
else if(i + 1 < argc) *base = atoi(argv[++i]);
|
||||
else fprintf(stderr,"%s: missing address\n",programname);
|
||||
}
|
||||
break;
|
||||
case 'x': /* extract segment */
|
||||
switch(argv[i][2]) {
|
||||
@ -158,7 +162,7 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"reloc65: %s unknown option, use '-?' for help\n",argv[i]);
|
||||
fprintf(stderr,"%s: %s unknown option, use '-?' for help\n",programname,argv[i]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
44
xa/src/xa.c
44
xa/src/xa.c
@ -55,9 +55,9 @@
|
||||
#define ANZWARN 13
|
||||
|
||||
#define programname "xa"
|
||||
#define progversion "v2.3.12"
|
||||
#define progversion "v2.3.13"
|
||||
#define authors "Written by Andre Fachat, Jolse Maginnis, David Weinehall and Cameron Kaiser"
|
||||
#define copyright "Copyright (C) 1989-2021 Andre Fachat, Jolse Maginnis, David Weinehall\nand Cameron Kaiser."
|
||||
#define copyright "Copyright (C) 1989-2022 Andre Fachat, Jolse Maginnis, David Weinehall\nand Cameron Kaiser."
|
||||
|
||||
/* exported globals */
|
||||
int ncmos, cmosfl, w65816, n65816;
|
||||
@ -218,8 +218,12 @@ int main(int argc,char *argv[])
|
||||
case 'O': /* output charset */
|
||||
{
|
||||
char *name = NULL;
|
||||
if (argv[i][2] == 0) {
|
||||
name = argv[++i];
|
||||
if (argv[i][2] == 0) {
|
||||
if (i + 1 < argc) name = argv[++i];
|
||||
else {
|
||||
fprintf(stderr, "-O requires an argument\n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
name = argv[i]+2;
|
||||
}
|
||||
@ -231,7 +235,13 @@ int main(int argc,char *argv[])
|
||||
case 'A': /* make text segment start so that text relocation
|
||||
is not necessary when _file_ starts at adr */
|
||||
romable = 2;
|
||||
if(argv[i][2]==0) romaddr = atoi(argv[++i]);
|
||||
if(argv[i][2]==0) {
|
||||
if (i + 1 < argc) romaddr = atoi(argv[++i]);
|
||||
else {
|
||||
fprintf(stderr, "-A requires an argument\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else romaddr = atoi(argv[i]+2);
|
||||
break;
|
||||
case 'G':
|
||||
@ -276,28 +286,44 @@ int main(int argc,char *argv[])
|
||||
break;
|
||||
case 'I':
|
||||
if(argv[i][2]==0) {
|
||||
reg_include(argv[++i]);
|
||||
if (i + 1 < argc) reg_include(argv[++i]);
|
||||
else {
|
||||
fprintf(stderr, "-I requires an argument\n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
reg_include(argv[i]+2);
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
if(argv[i][2]==0) {
|
||||
ofile=argv[++i];
|
||||
if (i + 1 < argc) ofile=argv[++i];
|
||||
else {
|
||||
fprintf(stderr, "-o requires an argument\n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
ofile=argv[i]+2;
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
if(argv[i][2]==0) {
|
||||
lfile=argv[++i];
|
||||
if (i + 1 < argc) lfile=argv[++i];
|
||||
else {
|
||||
fprintf(stderr, "-l requires an argument\n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
lfile=argv[i]+2;
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
if(argv[i][2]==0) {
|
||||
efile=argv[++i];
|
||||
if (i + 1 < argc) efile=argv[++i];
|
||||
else {
|
||||
fprintf(stderr, "-e requires an argument\n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
efile=argv[i]+2;
|
||||
}
|
||||
|
58
xa/src/xap.c
58
xa/src/xap.c
@ -60,6 +60,8 @@ static int pp_undef(char*);
|
||||
#define VALBEF 6
|
||||
|
||||
static int ungeteof = 0;
|
||||
static int quotebs = 0;
|
||||
static int inquote = 0;
|
||||
|
||||
static char *cmd[]={ "echo","include","define","undef","printdef","print",
|
||||
"ifdef","ifndef","else","endif",
|
||||
@ -792,7 +794,7 @@ int pp_open(char *name)
|
||||
flist[0].filep=fp;
|
||||
flist[0].flinep=NULL;
|
||||
|
||||
return(((long)fp)==0l);
|
||||
return (fp == NULL);
|
||||
}
|
||||
|
||||
void pp_close(void)
|
||||
@ -875,6 +877,7 @@ int pgetline(char *t)
|
||||
int c,er=E_OK;
|
||||
int rlen, tlen;
|
||||
char *p = 0;
|
||||
char *q = 0;
|
||||
|
||||
loopfl =0; /* set if additional fetch needed */
|
||||
|
||||
@ -924,12 +927,38 @@ int pgetline(char *t)
|
||||
}
|
||||
|
||||
/* handle the double-slash comment (like in C++) */
|
||||
p = strchr(in_line, '/');
|
||||
if (p != NULL) {
|
||||
if (p[1] == '/') {
|
||||
*p = 0; /* terminate string */
|
||||
/* 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';
|
||||
@ -987,15 +1016,22 @@ int egetc(FILE *fp) {
|
||||
/* smart getc that can skip C comment blocks */
|
||||
int rgetc(FILE *fp)
|
||||
{
|
||||
static int c,d,fl;
|
||||
|
||||
static int c,cc,d,fl;
|
||||
cc=0;
|
||||
fl=0;
|
||||
|
||||
do
|
||||
{
|
||||
while((c=egetc(fp))==13); /* remove ^M for unices */
|
||||
|
||||
if(fl && (c=='*'))
|
||||
/* 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
|
||||
|
||||
if(!inquote && fl && (c=='*'))
|
||||
{
|
||||
if((d=egetc(fp))!='/')
|
||||
ungetc(d,fp);
|
||||
@ -1005,12 +1041,14 @@ int rgetc(FILE *fp)
|
||||
while((c=egetc(fp))==13);
|
||||
}
|
||||
}
|
||||
|
||||
/* in comment block */
|
||||
if(c=='\n')
|
||||
{
|
||||
flist[fsp].fline++;
|
||||
nlf=1;
|
||||
} else
|
||||
if(c=='/')
|
||||
if(!inquote && c=='/')
|
||||
{
|
||||
if((d=egetc(fp))!='*')
|
||||
ungetc(d,fp);
|
||||
|
12
xa/src/xat.c
12
xa/src/xat.c
@ -2111,7 +2111,7 @@ static void tg_hex(signed char *s, int *l, int *v)
|
||||
static int tg_asc(signed char *s, signed char *t, int *q, int *p, int *na1, int *na2,int n)
|
||||
{
|
||||
|
||||
int er=E_OK,i=0,j=0;
|
||||
int er=E_OK,i=0,j=0,bs=0;
|
||||
|
||||
signed char delimiter = s[i++];
|
||||
|
||||
@ -2122,8 +2122,16 @@ fprintf(stderr, "tg_asc token = %i\n", n);
|
||||
t[j++]='"'; /* pass2 token for string */
|
||||
j++; /* skip place for length */
|
||||
|
||||
while(s[i]!='\0' && s[i]!=delimiter)
|
||||
while(s[i]!='\0' && (bs || s[i]!=delimiter))
|
||||
{
|
||||
|
||||
#if(0)
|
||||
/* implement backslashed quotes for 2.4 */
|
||||
if(n != Kbin && s[i] == '\\' && !bs) {
|
||||
fprintf(stderr, "B"); bs=1; i++; continue;
|
||||
} else bs=0;
|
||||
#endif
|
||||
|
||||
/* do NOT convert for Kbin or Kaasc, or for initial parse */
|
||||
if (!n || n == Kbin || n == Kaasc) {
|
||||
t[j++]=s[i];
|
||||
|
@ -55,6 +55,7 @@ W: while($x = readdir(D)) {
|
||||
chdir("..");
|
||||
}
|
||||
closedir(D);
|
||||
print STDOUT "=" x 79, "\n";
|
||||
print STDOUT "\n## ALL TESTS PASS ##\n";
|
||||
exit 0;
|
||||
|
||||
|
BIN
xa/tests/stringcom/ok
Normal file
BIN
xa/tests/stringcom/ok
Normal file
Binary file not shown.
21
xa/tests/stringcom/test.s
Normal file
21
xa/tests/stringcom/test.s
Normal file
@ -0,0 +1,21 @@
|
||||
* = $e00
|
||||
.byt 10/2 // watchs // phlegm
|
||||
/* .word 10/2 */ .word 65536/2
|
||||
// .byt 9/9 // yo mama
|
||||
// .asc "FAIL"
|
||||
.asc "SIEx256SN" // foo
|
||||
.asc "SIE/256SN" // bar
|
||||
.asc "SIE//256SN" // bar
|
||||
.asc "SIEy256SN" // baz
|
||||
.asc "PASS/*PASS*///PASS//PASS"
|
||||
|
||||
#if(0)
|
||||
/* enable when backslashed quotes are supported in 2.4 */
|
||||
.asc "PASS\"\\PASS/*PASS*///PASS//\"\\PASS"
|
||||
#endif
|
||||
|
||||
.asc "SIE/*256*/N"
|
||||
/* .asc "SIE/*256*/N"
|
||||
.asc "FAIL"
|
||||
*/ .asc "PASS" // .asc "FAIL" /* .asc "FAIL*/" */
|
||||
|
Loading…
x
Reference in New Issue
Block a user