Merge pull request #1035 from xexyl/1990-tbr-fix-fix-on-fix
This commit is contained in:
5 files changed
+52
-27
No files matched your search
+11
-6
@@ -23,7 +23,8 @@ make all
|
||||
NOTE: globs do not work with this entry. Why?
|
||||
|
||||
NOTE: `exit` does not work and neither does `logout`. To exit try sending ctrl-d
|
||||
or ctrl-c (or kill it from another terminal :-) ).
|
||||
or ctrl-c (or kill it from another terminal :-) ). But why does it not work with
|
||||
just `exit` or `logout`? Hint: see the authors' remarks.
|
||||
|
||||
|
||||
## Try:
|
||||
@@ -41,6 +42,10 @@ vi tbr.c
|
||||
What happens if you try using `cd -` to return to previous directory? What about
|
||||
`cd` with no args?
|
||||
|
||||
### TNABTAF - they're not a bug they're a feature! :-)
|
||||
|
||||
The authors include a section called [BUGS](#bugs) that, because they were
|
||||
documented, are not considered bugs as such in the context of the contest.
|
||||
|
||||
## Judges' remarks:
|
||||
|
||||
@@ -51,7 +56,7 @@ Shell source was a major inspiration for the formation of the IOCCC back in
|
||||
1984?
|
||||
|
||||
|
||||
The author supplied us with a slightly smaller unformatted version
|
||||
The authors supplied us with a slightly smaller unformatted version
|
||||
of the program which we include below:
|
||||
|
||||
```c
|
||||
@@ -67,11 +72,11 @@ r(o,0)D o)D*f):4,wait(0):(o?dup2(*f,0)D*f)D o):*i?1 D
|
||||
e(x){x<0?write(2,"?\n$ "-x/4,2),x+1||(exit(1),0):5;}
|
||||
```
|
||||
|
||||
It has the `exit()` returns void fix but not the `gets()` to `fgets()` fix
|
||||
applied.
|
||||
It has the `exit()` returns void fix as well as the `gets()` to `fgets()` fix
|
||||
applied to it to make it functionally equivalent like the authors intended.
|
||||
|
||||
|
||||
## Author's remarks:
|
||||
## Authors' remarks:
|
||||
|
||||
This program is a rudimentary shell. It does I/O redirection, pipes
|
||||
and cd. It flags errors on failed `chdir()`, `open()`, `creat()`,
|
||||
@@ -87,7 +92,7 @@ system calls) a question mark is printed.
|
||||
|
||||
The error value of `chdir()` is doubled so that we don't exit from the parent
|
||||
shell on a `chdir()` error (since `e()` exits on `-1` errors only). All other
|
||||
system call failures exit since they are from subshells.
|
||||
system call failures exit since they are from sub-shells.
|
||||
|
||||
Recursion is sneakily employed to avoid a second call to `fork()`,
|
||||
and the line is parsed in a fairly bizarre fashion: backwards. The
|
||||
|
||||
+5
-3
@@ -1,11 +1,13 @@
|
||||
#define D ,close(
|
||||
#define exit(x) exit((x)),0
|
||||
#define gets(x) fgets((x),512,stdin)
|
||||
char*c,q[512],m[256],*v[99],**u,*i[3];int f[2],p;main(){for(m[m[60]=m[62]=
|
||||
32]=m[*m=124[m]=9]=6;e(-8),gets(1+(c=q))||(exit(0),0);r(0,0))for(;*++c;);}
|
||||
r(t,o){*i=i[2]=0;for(u=v+98;m[*--c]^9;m[*c]&32?i[*c&2]=
|
||||
32]=m[*m=124[m]=9]=6;e(-8),((gets(1+(c=q)),(c+1)[strlen(c+1)-1]='\0'),1)||
|
||||
(exit(0));r(0,0))for(;*++c;);}r(t,o){*i=i[2]=0;for(u=v+98;m[*--c]^9;m[*c]&32?i[*c&2]=
|
||||
*u,u-v^98&&++u:3)if(!m[*c]){for(*++c=0;!m[*--c];);*--u=
|
||||
++c;}u-v^98?strcmp(*u,"cd")?*c?pipe(f),o=f[1]:1,(p=fork())?e(p),o?
|
||||
r(o,0)D o)D*f):4,wait(0):(o?dup2(*f,0)D*f)D o):*i?1 D
|
||||
0),e(open(*i,0)):5,t?dup2(t,1)D t):i[2]?9 D
|
||||
1),e(creat(i[2],438)):2,e(execvp(*u,u))):e(chdir(u[1])*2):6;}
|
||||
e(x){x<0?write(2,"?\n$ "-x/4,2),x+1||(exit(1),0):5;}
|
||||
e(x){x<0?write(2,"?\n$ "-x/4,2),x+1||(exit(1)):5;}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#define gets(x)fgets((x),512,stdin)
|
||||
#define gets(x) fgets((x),512,stdin)
|
||||
#define exit(x) exit((x)),0
|
||||
#define D ,close(
|
||||
|
||||
|
||||
+34
-16
@@ -231,10 +231,13 @@ README.md file.
|
||||
|
||||
## [1988/dale](1988/dale/dale.c) ([README.md](1988/dale/README.md]))
|
||||
|
||||
Cody fixed this twisted entry (as we called it :-) ) for modern compilers. There
|
||||
were two problems to address. One was that the entry required `-traditional-cpp`
|
||||
Cody fixed this twisted entry (as we called it :-) ) for modern compilers,
|
||||
including making it no longer require `-traditional-cpp`. There were two
|
||||
problems here to fix, which Cody did.
|
||||
|
||||
One, as noted above, was that the entry required `-traditional-cpp`
|
||||
(which <strike>not all compilers support</strike> `clang` does not support)
|
||||
which Cody fixed. It needed that option because of two things it did:
|
||||
It needed that option in modern systems because of two things it did:
|
||||
|
||||
```c
|
||||
#define a(x)get/***/x/***/id())
|
||||
@@ -248,15 +251,10 @@ p Z=chroot("/");L(!a(u)execv((q(v="/ipu6ljov"),v),C);Z-=kill(l);
|
||||
case_2:L(!--V){O/*/*/c*c+c);wait(A+c*c-c);L(!Z)f(A,"\n",c);return(A*getgid());};C++;
|
||||
```
|
||||
|
||||
no longer works to create `getuid()` and `getgid()`. The second is that
|
||||
|
||||
```c
|
||||
for/*/(;;);/*/k()){O/*/*/c);
|
||||
```
|
||||
|
||||
cannot form `fork())` in modern C compilers. One can put those in directly but
|
||||
using the C paste token operator `##` also solves the problem of the `#define
|
||||
a` like this diff shows:
|
||||
This macro, `a`, formed the functions (the names) `getuid()` and `getgid()`, but
|
||||
this no longer works. The code still uses the macro `a` to form the names but
|
||||
it's done differently, using the C token paste operator `##`. It's done like
|
||||
thus:
|
||||
|
||||
```diff
|
||||
--- i/1988/dale/dale.c
|
||||
@@ -271,10 +269,20 @@ a` like this diff shows:
|
||||
+#define a(x)get##x##id())
|
||||
```
|
||||
|
||||
What is quite fun is that at least some C pre-processors can form these
|
||||
constructs!
|
||||
The second is that
|
||||
|
||||
The other problem was that modern compilers do not allow directives like:
|
||||
```c
|
||||
for/*/(;;);/*/k()){O/*/*/c);
|
||||
```
|
||||
|
||||
cannot form `fork())` in modern C compilers. Since it was not done through a
|
||||
macro it was simply changed to be 'fork()', rather than adding a new macro.
|
||||
|
||||
(What is quite fun is that at least some C pre-processors can form these
|
||||
constructs! Can you figure out why this is?)
|
||||
|
||||
The other problem that could not be resolved by the `-traditional-cpp` was that
|
||||
modern compilers do not allow directives like:
|
||||
|
||||
```c
|
||||
#define _ define
|
||||
@@ -290,7 +298,11 @@ so Cody changed the lines to be in the form of:
|
||||
#define foo bar
|
||||
```
|
||||
|
||||
See the README.md file for details on the original code.
|
||||
However, to keep the entry as close to as possible in look, Cody kept the `_`
|
||||
macro in place it's just no longer used.
|
||||
|
||||
See the README.md file for details on the original code, provided as an alt
|
||||
version in case you have an older compiler or wish to try `-traditional-cpp`.
|
||||
|
||||
|
||||
## [1988/isaak](1988/isaak/isaak.c) ([README.md](1988/isaak/README.md]))
|
||||
@@ -498,6 +510,12 @@ couple macros that redefine `exit()` and `gets()` a whole binary expression
|
||||
could be removed (thus removing an extra `exit()` call) and it now almost looks
|
||||
like the same as the original.
|
||||
|
||||
Additionally, Cody fixed the shortened version provided by the author in the
|
||||
same way as the original entry, first the compile fix and then later on making
|
||||
it look more like the original by redefining `exit` and also redefining `gets()`
|
||||
to be `fgets()` in the same way that the original entry is. This way the alt
|
||||
version is equivalent in function, like the author intended, but more compact.
|
||||
|
||||
## [1990/theorem](1990/theorem/theorem.c) ([README.md](1990/theorem/README.md]))
|
||||
|
||||
Cody fixed this to compile with modern systems.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# ioccc_status.sh - quickly update status.json file
|
||||
#
|
||||
# Written by Cody Boone Ferguson in 2023
|
||||
# Written by Cody Boone Ferguson in 2023:
|
||||
#
|
||||
# @xexyl
|
||||
# https://xexyl.net Cody Boone Ferguson
|
||||
|
||||
Reference in new issue
Block a user