Fix 1991/dds
This was a fun one! There were up to three segfaults fixed and with
clang the generated file could not be compiled. The latter part was
fixed with (unfortunately) something of a hack. I explain below and in
the README.md how to change that part to use just cc if you have gcc
(macOS gcc is actually 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 I did not want to inadvertently mess
something up I 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!
This commit is contained in:
1 parent
93561d7704
commit
56b31286d1
3 files changed
+34
-10
No files matched your search
+5
-1
@@ -62,7 +62,7 @@ CDEFINE=
|
||||
|
||||
# Include files that are needed to compile
|
||||
#
|
||||
CINCLUDE=
|
||||
CINCLUDE= -include stdio.h
|
||||
|
||||
# Optimization
|
||||
#
|
||||
@@ -80,6 +80,7 @@ LIBS=
|
||||
#
|
||||
CC= cc
|
||||
|
||||
CSILENCE= -Wno-implicit-function-declaration
|
||||
# Compiler add-ons or replacements for clang only
|
||||
#
|
||||
ifeq ($(CC),clang)
|
||||
@@ -131,6 +132,9 @@ all: data ${TARGET}
|
||||
${PROG}: ${PROG}.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LIBS}
|
||||
|
||||
a: a.c
|
||||
${CC} ${CFLAGS} -Wno-return-type $< -o $@ ${LIBS}
|
||||
|
||||
# alternative executable
|
||||
#
|
||||
alt: data ${ALT_TARGET}
|
||||
|
||||
+23
-3
@@ -14,7 +14,27 @@
|
||||
### To run
|
||||
|
||||
./dds basic_program
|
||||
./a.out
|
||||
./a
|
||||
|
||||
[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!
|
||||
|
||||
|
||||
## Judges' comments
|
||||
|
||||
@@ -24,8 +44,8 @@ Make and run as follows:
|
||||
|
||||
For example, the author suggests trying:
|
||||
|
||||
dds LANDER.BAS
|
||||
a.out
|
||||
./dds LANDER.BAS
|
||||
./a
|
||||
|
||||
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?
|
||||
|
||||
+6
-6
@@ -1,7 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#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%[Q<nbj\
|
||||
char s[]="Qjou!s\\311^-g\\311^-n\\311^-c\\::^-q-ma%mO1JBHm%BQ-aP1J[O1HB%[Q<nbj\
|
||||
o)*|gps)<<*txjudi)m*|aQdbtf!::::;sfuvso<aQefgbvmu;aQ<m,,a%CQ<csfbla%bQ<aN2!Q\
|
||||
\ndbtf!aP2Q;m>aP2Q<a%!D12J!JGJHJOJQJFJSJJJMHS%HD12D12N3!N4\nJUJT%UQm>aP4HC%T\
|
||||
Qs\\q,,^>m,2<m>aP4HC%SD12N1\nJNQm>s\\..q^aHC%NHb%GN1!D32P3%RN1UP1D12JPQUaP1H\
|
||||
@@ -10,8 +10,8 @@ R%PN4\nQ<g\\(aP3Q(^>aP2Q,2<n\\(aP3Q(^>aP4Hb%OD12D12N2!N3\nJVP3Q,,<jg)aP3Q=>n\
|
||||
aP1Q*aHb%FN1\nQm>::::aHC%VP3Q>bupj)hfut)c**aHb%JD12JON1!Qjg)a%LN1UP1D12JIQUa\
|
||||
P1HL%IQ*m>aN2!N2\nP2Q<fmtf!m,,aHC%MN1!N2>P2Q>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(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]++;}}}
|
||||
[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]++;}}}
|
||||
Reference in new issue
Block a user