Fix fix on fix of 1990/tbr
When I added the 'gets()' and 'exit()' macros to make the code look more
like the original I accidentally left out a space between 'gets(x)' and
'fgets(...' so that it looked like:
#define gets(x)fgets((x),512,stdin)
which I believe is incorrect. It now looks instead like:
#define gets(x) fgets((x),512,stdin)
The compact version that the authors provided was compile fixed quite
some time back but I never added the exit macro to match the original
more closely.
Also since the compact version was meant to be identical in function of
the entry and since that entry was changed to use fgets() (by the macro
gets()) I decided it would be better to make it use fgets() also, also
through redefining gets(). To make the line length closer in match to
the original compact version I changed the code to be two lines. This
wasn't necessary to do, as I recall, in the entry itself though it's
possible it was and I just managed to get the ASCII art the same or
almost the same.
The thanks-for-fixes.md file was updated for this change but
unfortunately I had made some changes yesterday that I forgot about
(just rewording) in another entry so that will also be in this commit.
This commit is contained in:
1 parent
4454a491ba
commit
44728e695b
4 files changed
+51
-26
No files matched your search
+11
-6
@@ -23,7 +23,8 @@ make all
|
|||||||
NOTE: globs do not work with this entry. Why?
|
NOTE: globs do not work with this entry. Why?
|
||||||
|
|
||||||
NOTE: `exit` does not work and neither does `logout`. To exit try sending ctrl-d
|
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:
|
## Try:
|
||||||
@@ -41,6 +42,10 @@ vi tbr.c
|
|||||||
What happens if you try using `cd -` to return to previous directory? What about
|
What happens if you try using `cd -` to return to previous directory? What about
|
||||||
`cd` with no args?
|
`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:
|
## Judges' remarks:
|
||||||
|
|
||||||
@@ -51,7 +56,7 @@ Shell source was a major inspiration for the formation of the IOCCC back in
|
|||||||
1984?
|
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:
|
of the program which we include below:
|
||||||
|
|
||||||
```c
|
```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;}
|
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
|
It has the `exit()` returns void fix as well as the `gets()` to `fgets()` fix
|
||||||
applied.
|
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
|
This program is a rudimentary shell. It does I/O redirection, pipes
|
||||||
and cd. It flags errors on failed `chdir()`, `open()`, `creat()`,
|
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
|
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
|
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()`,
|
Recursion is sneakily employed to avoid a second call to `fork()`,
|
||||||
and the line is parsed in a fairly bizarre fashion: backwards. The
|
and the line is parsed in a fairly bizarre fashion: backwards. The
|
||||||
|
|||||||
+5
-3
@@ -1,11 +1,13 @@
|
|||||||
#define D ,close(
|
#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]=
|
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;);}
|
32]=m[*m=124[m]=9]=6;e(-8),((gets(1+(c=q)),(c+1)[strlen(c+1)-1]='\0'),1)||
|
||||||
r(t,o){*i=i[2]=0;for(u=v+98;m[*--c]^9;m[*c]&32?i[*c&2]=
|
(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=
|
*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?
|
++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
|
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
|
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;}
|
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 exit(x) exit((x)),0
|
||||||
#define D ,close(
|
#define D ,close(
|
||||||
|
|
||||||
|
|||||||
+34
-16
@@ -231,10 +231,13 @@ README.md file.
|
|||||||
|
|
||||||
## [1988/dale](1988/dale/dale.c) ([README.md](1988/dale/README.md]))
|
## [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
|
Cody fixed this twisted entry (as we called it :-) ) for modern compilers,
|
||||||
were two problems to address. One was that the entry required `-traditional-cpp`
|
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 <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
|
```c
|
||||||
#define a(x)get/***/x/***/id())
|
#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++;
|
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
|
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
|
||||||
```c
|
it's done differently, using the C token paste operator `##`. It's done like
|
||||||
for/*/(;;);/*/k()){O/*/*/c);
|
thus:
|
||||||
```
|
|
||||||
|
|
||||||
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:
|
|
||||||
|
|
||||||
```diff
|
```diff
|
||||||
--- i/1988/dale/dale.c
|
--- i/1988/dale/dale.c
|
||||||
@@ -271,10 +269,20 @@ a` like this diff shows:
|
|||||||
+#define a(x)get##x##id())
|
+#define a(x)get##x##id())
|
||||||
```
|
```
|
||||||
|
|
||||||
What is quite fun is that at least some C pre-processors can form these
|
The second is that
|
||||||
constructs!
|
|
||||||
|
|
||||||
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
|
```c
|
||||||
#define _ define
|
#define _ define
|
||||||
@@ -290,7 +298,11 @@ so Cody changed the lines to be in the form of:
|
|||||||
#define foo bar
|
#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]))
|
## [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
|
could be removed (thus removing an extra `exit()` call) and it now almost looks
|
||||||
like the same as the original.
|
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]))
|
## [1990/theorem](1990/theorem/theorem.c) ([README.md](1990/theorem/README.md]))
|
||||||
|
|
||||||
Cody fixed this to compile with modern systems.
|
Cody fixed this to compile with modern systems.
|
||||||
|
|||||||
Reference in new issue
Block a user