From 64ff8b7c09255744824e678821eb1eba2f24daea Mon Sep 17 00:00:00 2001 From: Cody Boone Ferguson <53008573+xexyl@users.noreply.github.com> Date: Tue, 28 Mar 2023 04:35:40 -0700 Subject: [PATCH] Improve fix on 1991/dds - add alt code The dds.c now does return system(q-6); and the dds.alt.c does the return system("make a");. This way those who have gcc (more people than not most likely) they can use it like originally designed. Those with clang can use the alt target in almost the same way only instead of a.out use just a. Updated the README>md to explain everything. Updated the .gitignore with some globs that should have been there all along ('a' and 'dds.alt' being the ones that are new). --- 1991/dds/.gitignore | 4 +++ 1991/dds/Makefile | 4 +-- 1991/dds/README.md | 74 ++++++++++++++++++++++++++++++++------------- 1991/dds/dds.alt.c | 17 +++++++++++ 1991/dds/dds.c | 2 +- 5 files changed, 77 insertions(+), 24 deletions(-) create mode 100644 1991/dds/dds.alt.c diff --git a/1991/dds/.gitignore b/1991/dds/.gitignore index d7985d043..2118681f1 100644 --- a/1991/dds/.gitignore +++ b/1991/dds/.gitignore @@ -1 +1,5 @@ dds +dds.alt +a +a.c +a.out diff --git a/1991/dds/Makefile b/1991/dds/Makefile index c6c26c061..a4bed896d 100644 --- a/1991/dds/Makefile +++ b/1991/dds/Makefile @@ -114,8 +114,8 @@ OBJ= ${PROG}.o DATA= TARGET= ${PROG} # -ALT_OBJ= -ALT_TARGET= +ALT_OBJ= ${PROG}.alt.o +ALT_TARGET= ${PROG}.alt ################# diff --git a/1991/dds/README.md b/1991/dds/README.md index d68f03fb5..c4143d72f 100644 --- a/1991/dds/README.md +++ b/1991/dds/README.md @@ -11,41 +11,73 @@ make all -### To run +## To run: ./dds basic_program - ./a + ./a.out [Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) fixed some segfaults in this entry as well as making it so `a` (was `a.out`, see below) can be generated -(as in the program did not work, at least with clang). The first 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[]`. The second and third segfaults were caused if a file was -not specified (or it the one specified did not exist or couldn't be opened for -some reason) and if the output file could not be opened for writing. The -allowing the generated code to compile with clang is something of a hack -unfortunately. The code `return system(q-6);` ended up doing `return system("cc -a.c");` but depending on the compiler this would trigger errors due to no -function prototype specified and also a case where main() had a `return;` -without any return value. Because the string `s` is complicated and because Cody -did not want to inadvertently mess something up he changed that code to -`system("make a");` and then added the right rule to the Makefile. Thus you now -need both `make` and `cc`. If you use gcc you may change the system() call to -what was given in this description to get a more authentic feel. If you do this -you must then run `./a.out` not `./a`! Thank you Cody for your assistance! +(as in the program did not work, at least with clang). The alternative code, +described below, is what is needed for clang. Reading it might be instructive +even if you have gcc. +The first 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[]`. The second and third +segfaults were caused if a file was not specified (or it the one specified did +not exist or couldn't be opened for some reason) and if the output file could +not be opened for writing. -## Judges' comments +Thank you Cody for your assistance! -Make and run as follows: +## Try: + +With gcc, make and run as follows: make dds For example, the author suggests trying: ./dds LANDER.BAS - ./a + ./a.out + +### Alternative code: + +The alternative code, provided by Cody, allows this entry to work successfully +even with clang. He notes that 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. For all Cody knows +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 code, which you will see in `dds.c`, `return system(q-6);` +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. In particular it would fail (at least with +`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 because Cody did not want +to inadvertently mess something up he changed that code to `system("make a");` +and then added the right rule to the Makefile. Thus for the alternative version +you now need both `make` and `cc`. If you use gcc you may change the system() +call to what was given in this description to get a more authentic feel. If you +do this you must then run `./a.out` not `./a`! Thus to use the alternative +version: + +```sh +make clobber alt +./dds.alt LANDER.BAS +./a +``` + +Thank you Cody for your assistance! + + +## Judges' comments: + +## Try: Notice that a file a.c has been generated. Can you tell how a.c was produced? How does a.c relate to LANDER.BAS? diff --git a/1991/dds/dds.alt.c b/1991/dds/dds.alt.c new file mode 100644 index 000000000..6956c2d9d --- /dev/null +++ b/1991/dds/dds.alt.c @@ -0,0 +1,17 @@ +#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");if(!i||!o)return 1;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 6956c2d9d..888ff412b 100644 --- a/1991/dds/dds.c +++ b/1991/dds/dds.c @@ -12,6 +12,6 @@ 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");if(!i||!o)return 1;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); +system(q-6);}*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]++;}}}