From 7257727dfa75fd89a903d4028abd2988f5d7c673 Mon Sep 17 00:00:00 2001 From: Cody Boone Ferguson <53008573+xexyl@users.noreply.github.com> Date: Sat, 21 Oct 2023 10:40:19 -0700 Subject: [PATCH] Fix 1991/dds for clang Looking at the author's remarks (which I hadn't checked yet) I was able to determine how to get the code to disable warnings when compiling the generated C code. The text !.Xop.fssps!.Xop.sfuvso.uzqf!.Xop.jnqmjdju.gvodujpo.efdmbsbujpo had to be added to the string 'q' and then system(q-6); had to be changed to system(q-69); to disable the warnings that clang (at least in macOS - not sure elsewhere) ended up being errors due to the forcing of -Wno-error. An important point is that the placement of that text does matter due to the code: *o=fopen(q-3,"w"); If the file name is not at the end then what will happen is the 'a.c' file will not be created as the end of the string 's' will not be (when decrypted) 'a.c'. At that point the compilation would fail as there is no file to compile that is created. Thus the end of the string has to be: !.Xop.fssps!.Xop.sfuvso.uzqf!.Xop.jnqmjdju.gvodujpo.efdmbsbujpo!b/d With this the file can be generated and compiled with both gcc and clang even if -Werror would otherwise cause problems. The alt code has been removed and the Makefile no longer has alt code nor does it have the 'a' rule. --- 1991/dds/.gitignore | 2 -- 1991/dds/Makefile | 7 ++--- 1991/dds/README.md | 62 +-------------------------------------------- 1991/dds/dds.alt.c | 17 ------------- 1991/dds/dds.c | 5 ++-- bugs.md | 11 ++++---- thanks-for-fixes.md | 49 +++++++++++++++++++++++++++-------- 7 files changed, 50 insertions(+), 103 deletions(-) delete mode 100644 1991/dds/dds.alt.c diff --git a/1991/dds/.gitignore b/1991/dds/.gitignore index c71d12ad5..f21a07919 100644 --- a/1991/dds/.gitignore +++ b/1991/dds/.gitignore @@ -1,6 +1,4 @@ dds -dds.alt -a a.c a.out dds.orig diff --git a/1991/dds/Makefile b/1991/dds/Makefile index 18f4f0064..1975e8fad 100644 --- a/1991/dds/Makefile +++ b/1991/dds/Makefile @@ -114,8 +114,8 @@ OBJ= ${PROG}.o DATA= TARGET= ${PROG} # -ALT_OBJ= ${PROG}.alt.o -ALT_TARGET= ${PROG}.alt +ALT_OBJ= +ALT_TARGET= ################# @@ -132,9 +132,6 @@ all: data ${TARGET} ${PROG}: ${PROG}.c ${CC} ${CFLAGS} $< -o $@ ${LDFLAGS} -a: a.c - ${CC} ${CFLAGS} -Wno-return-type $< -o a.out ${LDFLAGS} - # alternative executable # alt: data ${ALT_TARGET} diff --git a/1991/dds/README.md b/1991/dds/README.md index 027fadb0c..6d207b022 100644 --- a/1991/dds/README.md +++ b/1991/dds/README.md @@ -12,9 +12,6 @@ Mastodon: make all ``` -There is an alt version for those who use `clang`. See [Alternate -code](#alternate-code) below. - ## To run: ```sh @@ -22,23 +19,9 @@ code](#alternate-code) below. ./a.out 2>/dev/null ``` -The segfault which was always triggered was due to the code `*q>' '&&(*q)--;`. -This seems odd at first glance but it's pointing to `s` which was read-only -memory as a `char *s`. It's now a `char s[]`. - - -NOTE: for `clang` you'll likely have to use the alternate code described below. - - ## Try: -With gcc, make and run as follows: - -```sh -make dds -``` - -For example, the author suggests trying: +The author suggests trying: ```sh ./dds LANDER.BAS 2>/dev/null @@ -55,49 +38,6 @@ You'll get errors yes but what does the generated file look like? What about other types of files? -### Alternate code: - -This alternate code allows this entry to work successfully even with clang. -Unfortunately it's something of a hack or maybe even a kludge. This however -seems important because it works well and allows for not messing with the `s` -string which is quite complicated. Even changing the length could break -functionality and indeed the length would have to be longer for this to work -with clang. - -How does it work? The original code (which you will see in [dds.c](dds.c)) does -a `return system(q-6);` which equates to `return system("cc a.c");` but clang by -default, at least in macOS, has default `-Werror` and there were some warnings. -This means that the compilation failed with clang (because it didn't use `make` -so no [Makefile](Makefile) was used). In particular it would fail (at least with -[LANDER.BAS](LANDER.BAS)) due to a return from `main()` without a return value -and the use of functions not yet declared. - -Now as noted since the string `s` is complicated and to not inadvertently mess -something up it was changed so that the code uses `system("make a");` and then an -appropriate rule was added to the Makefile. Thus for the alternative version you -now need both `make` and `cc`. If you use gcc you can just use the original -version. - -#### To build: - -```sh -make alt -``` - -#### To run: - -```sh -./dds.alt some_basic_program.bas 2>/dev/null -./a.out 2>/dev/null -``` - -#### Try: - -```sh -./dds LANDER.BAS 2>/dev/null -./a.out 2>/dev/null -``` - ### INABIAF - it's not a bug it's a feature! :-) Please note that if the BASIC file cannot be opened for reading or the output diff --git a/1991/dds/dds.alt.c b/1991/dds/dds.alt.c deleted file mode 100644 index 4ae041ae1..000000000 --- a/1991/dds/dds.alt.c +++ /dev/null @@ -1,17 +0,0 @@ -#include -#define Q r=R[*p++-'0'];while( -#define B ;break;case -char s[]="Qjou!s\\311^-g\\311^-n\\311^-c\\::^-q-ma%mO1JBHm%BQ-aP1J[O1HB%[QaP2QaP4HC%T\ -Qs\\q,,^>m,2aP4HC%SD12N1\nJNQm>s\\..q^aHC%NHb%GN1!D32P3%RN1UP1D12JPQUaP1H\ -R%PN4\nQaP2Q,2aP4Hb%OD12D12N2!N3\nJVP3Q,,n\ -\\(aP3Q(^*m>g\\(aP3Q(^::::aHC%VP3Q>bupj)hfut)c**aHb%JD12JON1!Qjg)a%LN1UP1D12JIQUa\ -P1HL%IQ*m>aN2!N2\nP2QP2Q>aN2\nP2Hbdd!b/d";int k;char R[4][99] -;main(c,v)char**v;{char*p,*r,*q;for(q=s;*q;q++)*q>' '&&(*q)--;{FILE*i=fopen(v -[1],"r"),*o=fopen(q-3,"w");for(p=s;;p++)switch(*p++){B'M':Q(k=fgetc(i))!=EOF -&&k!=*p)*r++=k;if(k==EOF){fputs("}}\n",o);fclose(o);return system("make a");}*r=0 -B'P':while(*p!='`')fputc(*p++,o)B'O':Q*r)fputc(*r++,o);p--B'C':k=0;Q k<*p-'0' -)(*r++=fgetc(i),k++);*r=0 B'I':k= *p;if(**R==k)goto G B'G':k= *p;G:p=s;while( -*p!='$'||p[1]!= k)p++;p++B'N':R[*p-'0'][0]++;}}} diff --git a/1991/dds/dds.c b/1991/dds/dds.c index 504cc658c..f9e5dce46 100644 --- a/1991/dds/dds.c +++ b/1991/dds/dds.c @@ -8,10 +8,11 @@ Qs\\q,,^>m,2aP4HC%SD12N1\nJNQm>s\\..q^aHC%NHb%GN1!D32P3%RN1UP1D12JPQUaP1H\ R%PN4\nQaP2Q,2aP4Hb%OD12D12N2!N3\nJVP3Q,,n\ \\(aP3Q(^*m>g\\(aP3Q(^::::aHC%VP3Q>bupj)hfut)c**aHb%JD12JON1!Qjg)a%LN1UP1D12JIQUa\ -P1HL%IQ*m>aN2!N2\nP2QP2Q>aN2\nP2Hbdd!b/d";int k;char R[4][99] +P1HL%IQ*m>aN2!N2\nP2QP2Q>aN2\nP2Hbdd!.Xop.fssps!.Xop.sfu\ +vso.uzqf!.Xop.jnqmjdju.gvodujpo.efdmbsbujpo!b/d";int k;char R[4][99] ;main(c,v)char**v;{char*p,*r,*q;for(q=s;*q;q++)*q>' '&&(*q)--;{FILE*i=fopen(v [1],"r"),*o=fopen(q-3,"w");for(p=s;;p++)switch(*p++){B'M':Q(k=fgetc(i))!=EOF -&&k!=*p)*r++=k;if(k==EOF){fputs("}}\n",o);fclose(o);return system(q-6);}*r=0 +&&k!=*p)*r++=k;if(k==EOF){fputs("}}\n",o);fclose(o);return system(q-69);}*r=0 B'P':while(*p!='`')fputc(*p++,o)B'O':Q*r)fputc(*r++,o);p--B'C':k=0;Q k<*p-'0' )(*r++=fgetc(i),k++);*r=0 B'I':k= *p;if(**R==k)goto G B'G':k= *p;G:p=s;while( *p!='$'||p[1]!= k)p++;p++B'N':R[*p-'0'][0]++;}}} diff --git a/bugs.md b/bugs.md index 87e28b8dd..5a354ae02 100644 --- a/bugs.md +++ b/bugs.md @@ -685,7 +685,6 @@ This entry will also enter an infinite loop if input is not a number > 0. # 1991 ## [1991/dds](1991/dds/dds.c) ([README.md)(1991/dds/README.md)) -## [1991/dds.alt](1991/dds/dds.alt.c) ([README.md)(1991/dds/README.md)) ## STATUS: INABIAF - please **DO NOT** fix If the BASIC file cannot be opened for reading or the output file cannot be @@ -693,14 +692,14 @@ opened for writing the program will very likely crash or do something funny. This is not a bug but a feature. Please do not fix this except for the challenge to yourself. -Please also note that for `clang` you have to use [dds.alt](1991/dds/dds.alt.c) not -[dds.c](1991/dds/dds.c). - ## STATUS: uses gets() - change to fgets() if possible That being said the compiled code uses `gets()` not `fgets()`. Can you fix this? -You might find that the `s` array is relevant but if you do change it please -make sure to test all functionality! +It's quite complicated to do: the `s` array is certainly relevant and you can +see a bit of the magic in the [thanks](/thanks-for-fixes.md) and the README.md +file for how it works. It's easy enough to get the code to refer to `fgets()` +and call it correctly but it might take more work to get the generated code +sorted. This will be looked at later. ## [1991/westley](1991/westley/westley.c) ([README.md](1991/westley/README.md)) ## STATUS: INABIAF - please **DO NOT** fix diff --git a/thanks-for-fixes.md b/thanks-for-fixes.md index 9a86d8716..7ccc17472 100644 --- a/thanks-for-fixes.md +++ b/thanks-for-fixes.md @@ -15,10 +15,11 @@ responsible for many of the improvements including many **very complicated bug fixes** like [1988/phillipps](1988/phillipps/README.md), [2001/anonymous](2001/anonymous/README.md) and [2004/burley](2004/burley/README.md), making entries like -[1986/wall](1986/wall/README.md) not require `-traditional-cpp` (all **very -complicated fixes**), fixing entries to compile with clang, porting entries to -macOS, some being **very complicated** like -[1998/schweikh1](1998/schweikh1/README.md), fixing code like +[1986/wall](1986/wall/README.md) not need `-traditional-cpp` (all **very +complicated fixes**), fixing entries to work with clang (some being **very +complicated** like [1991/dds](1991/dds/README.md)), porting entries to +macOS (some being **very complicated** like +[1998/schweikh1](1998/schweikh1/README.md)), fixing code like [2001/herrmann2](2001/herrmann2/README.md) to work in both 32-bit/64-bit which *can be* **very complicated**, providing alternate code where useful/necessary, fixing where possible dead links or removing them, typo/consistency fixes, @@ -787,14 +788,42 @@ slightly more like the original, even though it's unused. ## [1991/dds](1991/dds/dds.c) ([README.md](1991/dds/README.md])) Cody fixed a segfault that prevented this entry from working in any condition -and he also made an [alternate version](1991/dds/dds.alt.c) that works with -`clang`. +and he also made it work for clang. Clang (at least in some systems?) defaults +to having `-Wno-error` and the code that the entry generates had some warnings +that were causing compilation to fail as it just ran `cc a.c`. It ran it by what +was once `system(q-6);` but with clang this was not enough.. -The alternate code, described in the README.md file, is what is needed -for clang. Reading it might be instructive even if you have gcc. +The following had to be added to the string `s` (which to fix the segfault was +changed from `char*s` to `char s[]`): + +``` +!.Xop.fssps!.Xop.sfuvso.uzqf!.Xop.jnqmjdju.gvodujpo.efdmbsbujpo +``` +and then the call to `system()` had to be changed to: + +```c +system(q-69); +``` + +An important point is that the placement of this string in the `s` array does +matter. This is because of the code: + +```c +*o=fopen(q-3,"w"); +``` + +which means the file name that translates to `a.c` has to be at the end of the +string. Thus the end of the string actually looks like: + +``` +!.Xop.fssps!.Xop.sfuvso.uzqf!.Xop.jnqmjdju.gvodujpo.efdmbsbujpo!b/d +``` + +With these changes in place it will compile and work with both gcc and clang. +The key to the string is that it rotates the character by `+1`. This was not +immediately clear until reading the author's remarks so there was an alt version +that was something of a kludge, running `make a` instead. -Later on Cody improved the fix for clang by a slight modification to the -Makefile so that the compiled program is the same as with gcc: `a.out`. ## [1991/fine](1991/fine/fine.c) ([README.md](1991/fine/README.md))