From e54c806e73bb94746cd4cd833413002c51952678 Mon Sep 17 00:00:00 2001 From: fachat Date: Fri, 17 Aug 2012 13:50:00 +0200 Subject: [PATCH] fix double slash comment handling --- xa/src/xap.c | 88 ++++++++++++++++++++++++++++-------- xa/tests/ppdefines/Makefile | 2 +- xa/tests/ppdefines/test3.a65 | 11 +++++ xa/tests/ppdefines/test4.a65 | 13 ++++++ xa/tests/ppdefines/test5.a65 | 33 ++++++++++++++ 5 files changed, 128 insertions(+), 19 deletions(-) create mode 100644 xa/tests/ppdefines/test3.a65 create mode 100644 xa/tests/ppdefines/test4.a65 create mode 100644 xa/tests/ppdefines/test5.a65 diff --git a/xa/src/xap.c b/xa/src/xap.c index 3a103d3..27f7c03 100644 --- a/xa/src/xap.c +++ b/xa/src/xap.c @@ -952,6 +952,51 @@ int icl_open(char *tt) return(0); } +/* + * parses the current line for double-slash comments, + * handling single- and double-quotes appropriately + * shortens the line if a comment is found, returns + * the new line length. + */ +int double_slash_comments(char *line) { + int p = 0; + int qfl = 0; // if set, contains the current quote char (others are then ignored) + char c; + + while (line[p] != 0) { + c = line[p]; + if (c == qfl) { + // always in quote, c==0 not possible due to loop condition + // found matching quote char, so end of quote + qfl = 0; + } else + if ((c == '\'' || c == '"') && !qfl) { + // not in quote, but finding quote char + qfl = c; + } + if (c == '^' && qfl) { + // xa65 escape character in strings (quoted) + if (line[p+1] != 0) { + // skip the next char in test + p++; + } + } + if (c == '/' && !qfl) { + // found '/' outside quote + if (line[p+1] == '/') { + // gotcha + //printf("shorten at %d: %s\n", p, line); + // shorten line + line[p] = 0; + // return new length + return p; + } + } + p++; + } + return p; +} + int pgetline(char *t) { int c,er=E_OK; @@ -963,15 +1008,25 @@ int pgetline(char *t) filep =flist+fsp; do { - c=fgetline(in_line, MAXLINE, &rlen, flist[fsp].filep); - /* continuation lines */ - tlen = rlen; - while(c=='\n' && tlen && in_line[tlen-1]=='\\') { - c=fgetline(in_line + tlen-1, MAXLINE-tlen, &rlen, flist[fsp].filep); - tlen += rlen-1; + int is_continuation = 0; + tlen = 0; // start of current line in in_line[] + do { + c=fgetline(in_line + tlen, MAXLINE, &rlen, flist[fsp].filep); + + /* check for continuation lines */ + is_continuation = ((c == '\n') && (rlen > 0) && (in_line[tlen + rlen - 1]=='\\')); + if (is_continuation) { + // cut off the continuation character + rlen--; + in_line[tlen + rlen] = 0; } - if(in_line[0]=='#' || in_line[0] == altppchar) - { + rlen = double_slash_comments(in_line + tlen); + + tlen += rlen; + } while (is_continuation); + + if(in_line[0]=='#' || in_line[0] == altppchar) + { if (in_line[1]==' ') { /* cpp comment -- pp_comand doesn't handle this right */ er=pp_cpp(in_line+1); @@ -985,10 +1040,10 @@ int pgetline(char *t) } } } - } else + } else er=1; - if(c==EOF) { + if(c==EOF) { if (loopfl && fsp) { char bletch[MAXLINE]; sprintf(bletch, @@ -1005,14 +1060,6 @@ int pgetline(char *t) errout(E_OPENPP); } - /* handle the double-slash comment (like in C++) */ - p = strchr(in_line, '/'); - if (p != NULL) { - if (p[1] == '/') { - *p = 0; /* terminate string */ - } - } - if(!er || loopfl) { in_line[0]='\0'; } @@ -1112,6 +1159,11 @@ int rgetc(FILE *fp) return(c-'\t'?c:' '); } +/** + * Note that the line returned is always zero-terminated, + * the rlen out parameter is just convenience, so that + * a further strlen() can be saved + */ int fgetline(char *t, int len, int *rlen, FILE *fp) { static int c,i; diff --git a/xa/tests/ppdefines/Makefile b/xa/tests/ppdefines/Makefile index 2d8bd02..73b8dde 100644 --- a/xa/tests/ppdefines/Makefile +++ b/xa/tests/ppdefines/Makefile @@ -1,7 +1,7 @@ XA=../../xa -all: test1 test2 clean +all: test1 test2 test3 test4 test5 clean clean: rm a.o65 diff --git a/xa/tests/ppdefines/test3.a65 b/xa/tests/ppdefines/test3.a65 new file mode 100644 index 0000000..6046fc5 --- /dev/null +++ b/xa/tests/ppdefines/test3.a65 @@ -0,0 +1,11 @@ + +#define GD_DEVICE 0x01 // Get device descriptor for Device +#define GD_CONFIGURATION 0x02 // Get device descriptor for Configuration +#define GD_STRING 0x03 // Get device descriptor for String + + *=$c000 + + lda #GD_DEVICE ; test + + lda #GD_CONFIGURATION+$10 + diff --git a/xa/tests/ppdefines/test4.a65 b/xa/tests/ppdefines/test4.a65 new file mode 100644 index 0000000..0d1df86 --- /dev/null +++ b/xa/tests/ppdefines/test4.a65 @@ -0,0 +1,13 @@ + + ; same as test3, only there is a colon in the "//" comment + +#define GD_DEVICE 0x01 // Get device descriptor: Device +#define GD_CONFIGURATION 0x02 // Get device descriptor: Configuration +#define GD_STRING 0x03 // Get device descriptor: String + + *=$c000 + + lda #GD_DEVICE ; test + + lda #GD_CONFIGURATION+$10 + diff --git a/xa/tests/ppdefines/test5.a65 b/xa/tests/ppdefines/test5.a65 new file mode 100644 index 0000000..edfe192 --- /dev/null +++ b/xa/tests/ppdefines/test5.a65 @@ -0,0 +1,33 @@ + + // this tests the double-slash quote in lines with various disturbances... + + lda #1 // test1 + + lda #2/1 // test2 with a constant division + + lda #3*2 // test3 with multi + + lda #4<<1 // test with shift left + lda #4>>1 // test with shift right + + lda #"/" // test with quotes + + lda #'/' // test with single quotes + + .byt "/", "/", '/' // test with multiple quotes + + ; test with comments in quotes + .byt "//" // test with comment in quotes + + ; tests with escaped and quoted quotes + .byt "^"" ; test xa65 specific escape code + .byt "^"" // test + + .byt '"' ; test xa65 specific escape code + .byt '"' // test + + .byt "'" ; test xa65 specific escape code + .byt "'" // test + + .byt '^'' ; test xa65 specific escape code + .byt '^'' // test