From c8c1dd403de2698ee055f1a9b93b18ea04a189fc Mon Sep 17 00:00:00 2001 From: Cody Boone Ferguson <53008573+xexyl@users.noreply.github.com> Date: Wed, 22 Mar 2023 06:18:31 -0700 Subject: [PATCH] 2004/burley compiles with clang + try fixing it main() had one arg, a char *, and this is against clang requirements. There was no inclusion of setjmp.h and so the longjmp() function implicitly returned int and was allowed to take the wrong number of args. It should return void however and this caused a problem with binary expressions. The comma operator has been used for this but it might be a problem in that by having ,1 after each it will make expressions that could turn out to be false to be incorrect. The longjmp() was being called with one arg which was an element of an int[4][1000]. This is obviously incorrect but at some point it worked. Without the prototype this is not a problem but both before (gcc) and after the compiler fix (with gcc and clang) it did not work with linux (in this case fedora) or macOS. The code as it now stands has the same problem as it did before the compilation fix: it lets you input a bet but then it does not accept any input after that; it prints nothing more but it should print a new hand. This issue has been put in bugs.md. My guess (in my tired head) is it has to do with the abuse of the longjmp() and/or the comma operator making the expressions always 1 (at least that side of the expression, thus if it gets to the longjmp() part it will always be 1). Perhaps it should be ,0? I don't know but I might try that next (I would guess it should be whatever an implicit int would return without a return statement but that's just a guess). But given that it stops working at the same spot perhaps it's not the comma operator. Maybe the function needs to be broken up into several but I don't know and that might or might not be worth the effort. Finally it returned main() itself but now it returns poke() which has the body of what main used to be. See bugs.md for more details. --- 2004/burley/Makefile | 4 +-- 2004/burley/README.md | 18 +++++++++-- 2004/burley/burley.c | 70 +++++++++++++++++++++++-------------------- bugs.md | 27 +++++++++++++++++ 4 files changed, 81 insertions(+), 38 deletions(-) diff --git a/2004/burley/Makefile b/2004/burley/Makefile index 0cb754225..05f26bb24 100644 --- a/2004/burley/Makefile +++ b/2004/burley/Makefile @@ -64,7 +64,7 @@ X11_INCDIR= /opt/X11/include # #CSILENCE= CSILENCE= -Wno-bitwise-op-parentheses -Wno-char-subscripts -Wno-error \ - -Wno-implicit-function-declaration -Wno-int-to-pointer-cast + -Wno-implicit-function-declaration -Wno-int-to-pointer-cast -Wno-unused-value # Common C compiler warning flags # @@ -98,7 +98,7 @@ CDEFINE= # Include files that are needed to compile # -CINCLUDE= +CINCLUDE= -include stdio.h -include setjmp.h -include string.h -include time.h -include stdlib.h #CINCLUDE= -include stdlib.h #CINCLUDE= -include stdio.h #CINCLUDE= -include stdlib.h -include stdio.h diff --git a/2004/burley/README.md b/2004/burley/README.md index 009f7fbc6..227d37b1c 100644 --- a/2004/burley/README.md +++ b/2004/burley/README.md @@ -11,19 +11,31 @@ make ``` -### To run: +[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) fixed this to compile with +clang which requires that the first arg of main() be an int and the remaining +args to be a `char **`. He notes that he could not get the entry to work with +gcc before the fix and it does not work with clang either; see +[/bugs.md](/bugs.md) for information here. Thank you Cody for your assistance! + + + +## To run: ```sh ./burley ``` -### Try: +NOTE: you need to input a number first. See judges' comments below for +information on how to play. + + +## Try: ```sh echo "Do or do not. There is no try." ``` -## Judges' comments +## Judges' comments: This is a draw poker program. You start with $100. Input alternates between your bet and which cards to keep. Example: diff --git a/2004/burley/burley.c b/2004/burley/burley.c index 3fd9bdcb6..cdaa2c222 100644 --- a/2004/burley/burley.c +++ b/2004/burley/burley.c @@ -1,77 +1,78 @@ char a[80]; -int e[4],g[5],c=100,h,i,j,k,b,f,s,t,p[4][1000]; -int main(char*d){ -return main((char*)(srand(time(&h)), +int e[4],g[5],c=100,h,i,j,k,b,f,s,t; +jmp_buf p[4]; +int poke(char *d){ +return poke((char*)((srand(time((time_t*)&h)), setjmp(p[2]), -(k=atoi((gets(a), +(k=atoi((fgets(a,sizeof a, stdin), a+strspn(a," -")))) &&(b=k), b||++b, j+=-j, d=(char*)(&j), setjmp(p[1]), -1<<1>j&&(k&=4>>3, +1<<1>j&&((k&=4>>3, i=1<>9)%0x4, +k&&(((--i<5&&1&k)&&(s=(rand()>>9)%0x4, setjmp(p[0]), t+=(rand()>>3)%015-t, -e[s]&(1<>=1, i+=1<<1, -longjmp(p[3])), +longjmp(p[3],4)),1), setjmp(p[0]), putchar(0x20+!putchar(012+"(.7-A,G+@*J)/"[(017&(i=g[4-k]))*013%13])), -++k^005&&longjmp(p[0]), +++k^005&&(longjmp(p[0],1),1), putchar('\n'), setjmp(p[3]), putchar(0x1F+!!putchar(("BCDHS"[g[--k]>>4]))), -k&&longjmp(p[3]), +k&&(longjmp(p[3],4),1), putchar('\n'), j+=1<<0, -1^j||(d=(char*)gets(a)), -longjmp(p[1])), +1^j||(d=(char*)fgets(a,sizeof a, stdin)), +longjmp(p[1],2)),1), s=1==(f=0), i=0<<1, setjmp(p[3]), -i<4&&(j=i+1, +i<4&&((j=i+1, setjmp(p[1]), -j<5&&((017&g[j])>(g[i]&15)&&(k=g[i], +j<5&&(((017&g[j])>(g[i]&15)&&(k=g[i], g[i]=g[j], g[j]=k), j++, -longjmp(p[1])), +longjmp(p[1],2)),1), i++, -longjmp(p[3])), +longjmp(p[3],4)),1), setjmp(p[0]), -i--&&!((g[1+i]^g[i])>>4)&&longjmp(p[0]), +i--&&!((g[1+i]^g[i])>>4)&&(longjmp(p[0],1),1), setjmp(p[1]), ---j&&(!(k=(g[j]&15)-(g[j-1]&017)+1)||(!(j-1)&&(8==-k)))&&longjmp(p[1]), +--j&&(!(k=(g[j]&15)-(g[j-1]&017)+1)||(!(j-1)&&(8==-k)))&&(longjmp(p[1],2),1), s+=3*!j|!(++i^17), (j*=i*=4)&&(i=1), setjmp(p[3]), -5-j<2&&(j=0, +5-j<2&&((j=0, setjmp(p[1]), -5-i>j&&((g[j]^g[j+1])&0xf?g[j]^=g[j]:(s+=((g[j]&0xf)>8&&f++, +5-i>j&&(((g[j]^g[j+1])&0xf?g[j]^=g[j]:(s+=((g[j]&0xf)>8&&f++, !!g[j]*i)), j++, -longjmp(p[1])), +longjmp(p[1],2)),1), i++, -longjmp(p[3])), +longjmp(p[3],4)),1), s=1^s?"AACEDJQZHello World"[s]-'A':!!f, -s+=(!i)*(6+12*s-!!s*(g[2]&017^0xa?8:-192)), +s+=(!i)*(6+12*s-!!s*((g[2]&017)^0xa?8:-192)), s--, s*=b, printf("$%d (%d) \n", @@ -79,12 +80,15 @@ c+=s, s+b), i=0, setjmp(p[0]), -6>i&&(j=1, +6>i&&((j=1, setjmp(p[1]), -0<=j&&(e[i+j]^=*(i-j+e+(j<<1)), +0<=j&&((e[i+j]^=*(i-j+e+(j<<1)), --j, -longjmp(p[1])), -i+=++i, -longjmp(p[0])), -longjmp(p[2]))); +longjmp(p[1],2)),1), +i+=i+1, +longjmp(p[0],1)),1), +longjmp(p[2],3)),1)); } +int main(int argc, char**d){ +(void)argc; +return poke((char*)d); } diff --git a/bugs.md b/bugs.md index e7af6ea82..1528649fa 100644 --- a/bugs.md +++ b/bugs.md @@ -33,6 +33,33 @@ related to making it work under macOS as all that did was removing some invalid prototypes and use `printf()` instead of the invalid pointer to it (incompatible type). +### [2004/burley](2004/burley/burley.c) ([README.md](2004/burley/README.md)) + +This entry did not compile with clang but [Cody Boone +Ferguson](/winners.html#Cody_Boone_Ferguson) fixed this problem. He notes however that +prior to (with gcc) and after the fix (gcc, clang) it does not work: it allows +input of the bet and then it prints the hand but it does not do anything with +your next move. He provides the following notes: + +0. Originally the `jmp_buf` was just an `int p[4][1000]`. +1. The `setjmp.h` header file was not included so the calls to `longjmp()` had +not only the wrong number of arguments but also implicitly returned int when it +actually returns void. This means that the comma operator had to be used to get +the binary expressions to work. It might be this is part of the problem. +2. Another possible problem is the abuse of `setjmp()` and `longjmp()` which is +known to be a problem, at least as he interprets it in his tired head (and less +experience with `longjmp`). In particular: +> The longjmp() routines may not be called after the routine which called the +> setjmp() routines returns. +3. The main() originally returned a call to main() which appeared to be an +infinite recursion at least as it was; now it returns a call to poke() which has the same number +and type of args (1, `char *`) that main() had. This appears to not be an +infinite recursion but I might be reading it wrong. Perhaps that is the problem? +4. As well main() had only one arg, a `char *`, and there were (seemingly) +needless casts to `char *` from gets(). +5. The code no longer uses `gets()` but `fgets()`; this is not the problem +however. + ### [2014/vik](2014/vik/prog.c) ([README.md](2014/vik/README.md))