From a7b2a92fc245c8e9b2a7807ce23911377aef5591 Mon Sep 17 00:00:00 2001 From: Spiro Trikaliotis Date: Tue, 21 Jun 2022 22:23:10 +0200 Subject: [PATCH] isequal: add --wildcards option --- test/asm/listing/Makefile | 4 +- test/asm/listing/ref/040-align.ld65err-ref | 2 +- test/isequal.c | 292 ++++++++++++++++++++- 3 files changed, 281 insertions(+), 17 deletions(-) diff --git a/test/asm/listing/Makefile b/test/asm/listing/Makefile index 1b54bafef..d3dc21409 100644 --- a/test/asm/listing/Makefile +++ b/test/asm/listing/Makefile @@ -79,7 +79,7 @@ ifneq ($(wildcard ref/$1.ld65err-ref),) -diff -u ref/$1.ld65err-ref $$(@:.bin=.ld65-err) @echo @echo - $(ISEQUAL) ref/$1.ld65err-ref $$(@:.bin=.ld65-err) + $(ISEQUAL) --wildcards ref/$1.ld65err-ref $$(@:.bin=.ld65-err) else ifneq ($(wildcard $(WORKDIR)/$1.ld65-err),) $(ISEQUAL) --empty $$(@:.bin=.ld65-err) @@ -106,7 +106,7 @@ else endif ifneq ($(wildcard ref/$1.ld65err-ref),) - $(ISEQUAL) ref/$1.ld65err-ref $$(@:.bin=.list-ld65-err) + $(ISEQUAL) --wildcards ref/$1.ld65err-ref $$(@:.bin=.list-ld65-err) else ifneq ($(wildcard $(WORKDIR)/$1.list-ld65-err),) $(ISEQUAL) --empty $$(@:.bin=.list-ld65-err) diff --git a/test/asm/listing/ref/040-align.ld65err-ref b/test/asm/listing/ref/040-align.ld65err-ref index 4fa8ee839..ac8d96432 100644 --- a/test/asm/listing/ref/040-align.ld65err-ref +++ b/test/asm/listing/ref/040-align.ld65err-ref @@ -1 +1 @@ -ld65: Warning: /home/spiro/Work/tmp/cc65.spiro.testcases-ca65/cfg/none.cfg:18: Segment 'CODE' isn't aligned properly; the resulting executable might not be functional. +ld65: Warning: <<<#PATH#>>>:<<<#INTEGER#>>>: Segment 'CODE' isn't aligned properly; the resulting executable might not be functional. diff --git a/test/isequal.c b/test/isequal.c index 2d6cf5253..6d98701bd 100644 --- a/test/isequal.c +++ b/test/isequal.c @@ -5,14 +5,67 @@ #include #include +#define ARRAYSIZE(_x) (sizeof _x / sizeof _x[0]) + +typedef int wildcardfunc(FILE * f2); + +struct wildcardtype { + char * name; + wildcardfunc * func; +}; + + +static int wildcard_path(FILE * f1); +static int wildcard_integer(FILE * f1); + +struct wildcardtype wildcards[] = { + { "PATH", wildcard_path }, + { "INTEGER", wildcard_integer } +}; + +static wildcardfunc * currentwildcardfunc = 0; + static int binary = 0; static int empty = 0; static int skiplines_left = 0; static int skiplines_right = 0; +static int use_wildcards = 0; static char * filename_left = 0; static char * filename_right = 0; -int handleargparameter(int offset, char * parameter) +/* LOOKAHEADBUFFERSIZE must be a power of 2, because the wrap-around for the + indices requires this! +*/ +#define LOOKAHEADBUFFERSIZE 0x80 +#define WILDCARDCHAR_OPEN '<' +#define WILDCARDCHAR_INTERNAL '#' +#define WILDCARDCHAR_CLOSE '>' + +#define WILDCARDCHAR_OPEN_CLOSE_COUNT 3 +#define WILDCARDNAME_MAXLENGTH 20 + +static char lookaheadbuffer[LOOKAHEADBUFFERSIZE] = { 0 }; +static int lookaheadindexread = 0; +static int lookaheadindexwrite = 0; + +static int wildcardendchar; + +wildcardfunc * findwildcardfunc(char * wildcardname) +{ + wildcardfunc * func = NULL; + + unsigned int i; + + for (i = 0; i < ARRAYSIZE(wildcards); ++i) { + if (strcmp(wildcards[i].name, wildcardname) == 0) { + func = wildcards[i].func; + } + } + + return func; +} + +static int handleargparameter(int offset, char * parameter) { long number = -1; char * endptr = NULL; @@ -30,13 +83,14 @@ int handleargparameter(int offset, char * parameter) return number; } -int handleparameter(int argc, char *argv[]) +static int handleparameter(int argc, char *argv[]) { static const char opt_binary[] = "--binary"; static const char opt_empty[] = "--empty"; static const char opt_skipleft[] = "--skipleft"; static const char opt_skipright[] = "--skipright"; static const char opt_skip[] = "--skip"; + static const char opt_wildcards[] = "--wildcards"; static const char len_skipleft = sizeof opt_skipleft - 1; static const char len_skipright = sizeof opt_skipright - 1; @@ -57,7 +111,7 @@ int handleparameter(int argc, char *argv[]) binary = 1; } else if (strcmp(argv[argindex], opt_empty) == 0) { - if (binary || skiplines_left || skiplines_right) { + if (binary || skiplines_left || skiplines_right || use_wildcards) { fprintf(stderr, "--binary cannot go with other options.\n"); exit(1); } @@ -93,6 +147,13 @@ int handleparameter(int argc, char *argv[]) fprintf(stderr, "%s: you must specify the number of lines\n", opt_skip); } } + else if (strcmp(argv[argindex], opt_wildcards) == 0) { + if (binary) { + fprintf(stderr, "--wildcards cannot go with --binary.\n"); + exit(1); + } + use_wildcards = 1; + } ++argindex; } @@ -117,7 +178,7 @@ int handleparameter(int argc, char *argv[]) 0x0d (CR) classic MacOS */ -int getnext(FILE *f) +static int getnext(FILE *f) { int c = fgetc(f); if (!binary && c == 0x0d) { @@ -133,7 +194,7 @@ int getnext(FILE *f) return c; } -void skiplines(FILE *f, int skipcount) +static void skiplines(FILE *f, int skipcount) { int c; @@ -149,6 +210,213 @@ void skiplines(FILE *f, int skipcount) } } +static int comparefiles(FILE *f1, FILE *f2) +{ + for(;;) { + if (feof(f1) && feof(f2)) { + return EXIT_SUCCESS; + } else if (feof(f1) || feof(f2)) { + return EXIT_FAILURE; + } + if (getnext(f1) != getnext(f2)) { + return EXIT_FAILURE; + } + } +} + +static int lookaheadbufferisempty(void) +{ + return lookaheadindexread == lookaheadindexwrite; +} + +static char lookaheadbufferread(void) +{ + char ch; + + if (lookaheadbufferisempty()) { + fprintf(stderr, "### want to take from lookahead buffer, but it is empty --> aborting!\n"); + exit(EXIT_FAILURE); + } + + ch = lookaheadbuffer[lookaheadindexread]; + + /* advance read pointer, with wrap-around */ + lookaheadindexread = (lookaheadindexread + 1) & (sizeof lookaheadbuffer - 1); + + return ch; +} + +static void lookaheadbufferwrite(char ch) +{ + lookaheadbuffer[lookaheadindexwrite] = ch; + + /* advance write pointer, with wrap-around */ + lookaheadindexwrite = (lookaheadindexwrite + 1) & (sizeof lookaheadbuffer - 1); + + if (lookaheadbufferisempty()) { + fprintf(stderr, "### lookahead buffer ovrrun, aborting!\n"); + exit(EXIT_FAILURE); + } +} + +static int processwildcardchar(FILE *f1) +{ + int countwildcardchar = 1; + int foundwildcard = 0; + int ch; + + static char wildcardname[WILDCARDNAME_MAXLENGTH + 1]; + unsigned int wildcardnamenextindex; + + while ((ch = getnext(f1)) == WILDCARDCHAR_OPEN) { + ++countwildcardchar; + if (feof(f1)) { + break; + } + } + + if (countwildcardchar == WILDCARDCHAR_OPEN_CLOSE_COUNT) { + if (ch == WILDCARDCHAR_INTERNAL) { + /* we found a wildcard! */ + foundwildcard = 1; + } + } + else { + if (ch == WILDCARDCHAR_OPEN) { + ch = -1; + } + } + + if (foundwildcard) { + char c; + + /* we found a wildcard init sequence; now check which wildcard it is */ + + wildcardnamenextindex = 0; + wildcardname[WILDCARDNAME_MAXLENGTH] = 0; + + c = getnext(f1); + while (c != WILDCARDCHAR_INTERNAL && c != 0x0a && !feof(f1)) { + wildcardname[wildcardnamenextindex] = c; + if (++wildcardnamenextindex >= WILDCARDNAME_MAXLENGTH) { + wildcardname[WILDCARDNAME_MAXLENGTH] = 0; + fprintf(stderr, "wildcard '%s' is too long!\n", wildcardname); + exit(EXIT_FAILURE); + } + c = getnext(f1); + } + + wildcardname[wildcardnamenextindex] = 0; + + if (c == WILDCARDCHAR_INTERNAL) { + int countwildcardcharclose = 0; + + fprintf(stderr, "Found wildcard '%s'\n", wildcardname); + + while ((c = getnext(f1)) == WILDCARDCHAR_CLOSE && !feof(f1)) { + ++countwildcardcharclose; + } + + wildcardendchar = c; /* remember next char */ + + currentwildcardfunc = findwildcardfunc(wildcardname); + if (currentwildcardfunc == NULL) { + fprintf(stderr, "Wildcard '%s' is unknown!\n", wildcardname); + exit(EXIT_FAILURE); + } + } + else { + fprintf(stderr, "Thought I found wildcard '%s', but it does not end.\n", wildcardname); + } + } + + if (!foundwildcard) { + int i; + + /* no wildcard; restore the chars */ + for (i = 0; i < countwildcardchar; ++i) { + lookaheadbufferwrite(WILDCARDCHAR_OPEN); + } + + if (ch >= 0) { + lookaheadbufferwrite(ch); + } + } + + return foundwildcard; +} + +static int wildcard_path(FILE * f2) +{ + int isstillwildcard = 1; + + int ch = getnext(f2); + + if ((ch == wildcardendchar) || ch < ' ' || ch > 126) { + /* this is not a path char anymore, abort the wildcard processing */ + isstillwildcard = 0; + + if (ch != wildcardendchar) { + exit(EXIT_FAILURE); + } + } + + return isstillwildcard; +} + +static int wildcard_integer(FILE * f2) +{ + int isstillwildcard = 1; + int ch = getnext(f2); + + if ((ch == wildcardendchar) || ch < '0' || ch > '9') { + /* this is not a digit anymore, abort the wildcard processing */ + isstillwildcard = 0; + + if (ch != wildcardendchar) { + exit(EXIT_FAILURE); + } + } + + return isstillwildcard; +} + +static int comparefileswithwildcards(FILE *f1, FILE *f2) +{ + static int iswildcard = 0; + + for(;;) { + int c1; + + if (lookaheadbufferisempty() && !iswildcard && feof(f1) && feof(f2)) { + return EXIT_SUCCESS; + } else if (((lookaheadbufferisempty() && !iswildcard && feof(f1))) || feof(f2)) { + return EXIT_FAILURE; + } + + if (iswildcard) { + /* f1 has a wildcard; process that */ + iswildcard = currentwildcardfunc(f2); + } + else { + /* f1 does not have a wildcard; process the next char (unless it starts a wildcard) */ + if (lookaheadbufferisempty()) { + c1 = getnext(f1); + if (c1 == WILDCARDCHAR_OPEN) { + iswildcard = processwildcardchar(f1); + continue; + } + } + else { + c1 = lookaheadbufferread(); + } + if (c1 != getnext(f2)) { + return EXIT_FAILURE; + } + } + } +} + int main(int argc, char *argv[]) { FILE *f1, *f2; @@ -183,15 +451,11 @@ int main(int argc, char *argv[]) if (skiplines_right) { skiplines(f2, skiplines_right); } - for(;;) { - if (feof(f1) && feof(f2)) { - return EXIT_SUCCESS; - } else if (feof(f1) || feof(f2)) { - return EXIT_FAILURE; - } - if (getnext(f1) != getnext(f2)) { - return EXIT_FAILURE; - } + if (use_wildcards) { + return comparefileswithwildcards(f1, f2); + } + else { + return comparefiles(f1, f2); } } }