Improve my fixes to 1998/schweikh1

To make this slightly more portable still I have removed the hard-coding
of gcc to make it just be cc. In modern systems this should be fine.
This involved updating the magic numbers by subtracting one from each,
making them (in the primary version 43 and 45 and 94 and 96 in the
alternate code for macOS) but since one of the purposes of the fixes of
code include making them work in more systems I have made it use cc as
it should work (gcc is most likely in all systems anyway but it seemed
like a better idea for 2023).

I previously noted in the thanks-for-fixes.md that the mode in fopen()
could remain 44+__FILE__ (though as noted above it's now 43) but that I
had changed it to "r". This was a mistake and it is now restored though
again it is now 43 not 44.

The FILE * which was renamed to G has been changed back to H. Observe
how there is a macro with the same name. There was actually no need to
change it.

I have restored some of the control codes in the C preprocessor
directives. Unfortunately that is only prior to the #define because some
systems will give an annoying warning otherwise. For instance fedora
linux shows:

    schweikh1.c:6:8: warning: form feed in preprocessing directive
	6 | #define
		   x
		    )
		     ==
		       0
			?__LINE__:0){O
				      =__LINE__;break;}
						       }
	  |

and possibly vertical tab too.

So although it would be ideal to have them closer to the original I deem
that preventing warnings that cannot be, for whatever reason, disabled.

The thanks-for-fixes.md was updated for these changes and now includes
more details on the fixes to match the rest of the other entries (though
some might also be lacking in details).
This commit is contained in:
Cody Boone Ferguson committed 2023-10-15 05:39:49 -07:00
1 parent ec2c1b577e
commit 1b65c59cd4
5 files changed
+152 -68

No files matched your search

+1
View File
@@ -128,6 +128,7 @@ all: data ${TARGET}
${PROG}: ${PROG}.c
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
@echo "NOTE: for macOS use the alternate code through make alt. See README.md for details."
# alternative executable
#
+73 -30
View File
@@ -14,8 +14,9 @@ Germany
make all
```
An alternate version for this entry works with macOS. See the Alternate code
section below for more details.
There is an alternate version of this entry that will work with macOS. See the
[Alternate code](#alternate-code) section below for details on how it works and
how to use it.
## To run:
@@ -24,60 +25,100 @@ section below for more details.
./schweikh1
```
NOTE: a limitation with the entry was that it required `gcc` but this limitation
has been removed to make it more portable, requiring only `cc`.
### Alternate code:
As noted above the alternate version works with macOS but there are some
important notes as well as a description of how it works (spoilers for the
original version as well).
As noted above this entry will not work as it stands for macOS and there are
some important notes as well as a description of how the fixed version works
(the details of which are relevant to the original entry that no longer works as
well as the fixed version but are described in the context of the macOS
adjustments).
With a MacBook Pro Max with the M1 chip some header files report an
unsupported architecture and unsupported compiler (error, warning).
However the defines are still found okay.
#### macOS changes:
For this alternate version you will need the command line tools which you can
install like:
As an aside: if you have a Mac with the Apple chip, some of the header files
will report an unsupported architecture and unsupported compiler (error,
warning). This will not make the program abort, however, but even with an Intel
CPU though, the original entry will not work in macOS as it stands because
`/usr/include` is hard-coded in the code and macOS does not have it.
Nevertheless, although some of it would not work in other systems where
`/usr/include` exists, the `#define`s would still be found okay, at least until
a file was not found (this limitation was removed in both versions, see
[thanks-for-fixes.md](/thanks-for-fixes.md) for details).
However, as noted, macOS does **not** have `/usr/include` so this would not ever
work for macOS without some changes, described next. For macOS you will need the
command line tools installed which can be done like:
```sh
sudo xcode-select --install
```
Finally as far as how this works if you look at line 55 you see a funny command.
This goes for both versions. Now the key are two magic numbers, one on a
different line shortly below the string. In the original the numbers are,
respectively, 44 and 46. But how does this work? Well the string is:
An important point is that the original version hard-coded `gcc` but just like
the entry, the alternate version has also removed this limitation despite `gcc`
existing (though it's `clang`) in macOS.
Now as far as how this works if you look at the code of
[schweikh1.c](schweikh1.c), on line 55 you'll see a funny command (this goes for
the alternate version as well but a bit different).
Now the key is two magic numbers, one (two of this exist) on a different line shortly below the
string and the other a couple lines further below.
In the original the numbers are, respectively, 44 and 46, but with the gcc
limitation removed the numbers now are 43 and 45. But how does this work? Well
the command is:
```
"0gcc -ansi -E -dM -undef %s /usr/include/%s>r\0 ("
```
The first number means: the length starting from 0 up through the `>`. The
second number is the same starting point but up through the `\0` which is why
it's +2. But what happens if only the first number is updated? Most of the
output will be just `#define` by itself; in the cases where there was text after
that it was macros that certainly were not defined. There might have been other
errors as well.
which has been changed to be:
This allows for opening the right files. The problem with the macOS is
`/usr/include` does not exist: instead it's
```
"0cc -ansi -E -dM -undef %s /usr/include/%s>r\0 ("
```
Shortly below that you will see, as noted above, the numbers:
```c
if ((H = fopen (__FILE__+43, 43+__FILE__)))
while ((fgets (L, (int)sizeof L, H)) != 0) {
I[strcspn (I, 45+__FILE__)] = O = 0;
```
The first number in the above C means the length starting from 0 up through the
`>`. The second number is the same starting point but up through the `\0` which
is why it's `+2`. But what happens if only the first number is updated (from the
original)? Most of the output will be just `#define` by itself; in the cases
where there was text after that it was macros that certainly were not defined.
There might have been other errors as well.
Changing this for macOS allows for opening the right files; the problem with the
macOS is `/usr/include` does not exist: instead it's
`/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include` which is why
the different command line and the different numbers.
the different command line and the different numbers. The change of the numbers
can be found in the alternate code and the explanation is the same.
To use this version use:
```sh
make alt
```
Use `schweikh1.alt` as you would `schweikh1` above.
Bonus exercise: modify the code to provide a different compiler.
## Judges' remarks:
What does it do? It seems to print a list of system headers, perhaps
with words after them. Curiously, if you look at the list of words
defined in a given standard header, they are never printed directly
after that header's name. Ah-hah! It's a conformance test for the
after that header's name. Aha! It's a conformance test for the
standard headers.
This code is a wonder; it's a wonder that it compiles. I wonder
@@ -90,15 +131,17 @@ Do not read them if you want to figure this out yourself. "Amendment
One" refers to "NA1", the add-on to C89 which added some fairly
crufty internationalization support.
NOTE: Some non-gcc compilers that are not fully ANSI standard do not
compile this entry correctly. Using cc by default is not helpful
most of the time on this entry, because the program has a hardcoded
#### Historical note:
Some non-gcc compilers that were not fully ANSI standard did not
compile this entry correctly. Using cc by default was not helpful
most of the time on this entry, because the program had a hardcoded
gcc invocation anyway. Anyone who uses egcs and has no plain gcc
will need to frob the source anyway and can be expected to do the
right thing with `${CC}`. So use gcc.
right thing with `${CC}`. So one should have used gcc.
## Author's remarks
## Author's remarks:
Important! This program, if it compiles at all, is mis-compiled by many
compilers due to compiler bugs. It could be the "least likely
+10 -10
View File
@@ -3,9 +3,9 @@
/*#include H(dlib)*/
/*#include H(ring)*/
#define x ) == 0 ?__LINE__:0){O =__LINE__;break;} }
#define X(x) __LINE__ x __LINE__
#define t(a)\
#define x ) == 0 ?__LINE__:0){O =__LINE__;break;} }
#define X(x) __LINE__ x __LINE__
#define t(a)\
for (c = 0; c <n##a; ++c) { \
if (strchr (a[c], 0[__FILE__])) { if (*a[c] == 0[__FILE__]) { \
if (strcmp (a[c]+__LINE__, I + strlen (I) + __LINE__ - strlen (a[c]) x else { \
@@ -16,11 +16,11 @@ for (c = 0; c <n##a; ++c) { \
int
main (int C, char **V)
{
FILE *G;
FILE *H;
int c, ne, nn, S = C < 2 ? 060 : *V[1];
char f[__LINE__][X(*)], K[(X(*))*4], L[4*X(<<)],
e[X(<<)][3*__LINE__], n[X(<<)][3*__LINE__], F[__LINE__];
e[X(<<)][3*__LINE__], n[X(<<)][4*__LINE__], F[__LINE__];
if (freopen (__FILE__, "r", stdin) == 0) return __LINE__-13;
for (c = 0;;) {
@@ -52,17 +52,17 @@ O:
#line 8 "<%s>:\n"
char *I = L + __LINE__;
int O = printf (__FILE__, n[nn]) +
#line 2 "0gcc -ansi -E -dM -undef %s /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/%s>r\0 ("
#line 2 "0cc -ansi -E -dM -undef %s /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/%s>r\0 ("
sprintf (K, 1+__FILE__, f[S-*__FILE__] + __LINE__, n[nn]);
O += system (K);
if ((G = fopen (__FILE__+95, "r")))
while ((fgets (L, (int)sizeof L, G)) != 0) {
I[strcspn (I, 97+__FILE__)] = O = 0;
if ((H = fopen (__FILE__+94, __FILE__+94)))
while ((fgets (L, (int)sizeof L, H)) != 0) {
I[strcspn (I, 96+__FILE__)] = O = 0;
#line 1 "*r"
t (n) t (e)
if (0 == O) O = puts (L);
}
if (G != NULL) nn = fclose (G);
if (H != NULL) nn = fclose (H);
}
}
}
+9 -9
View File
@@ -3,9 +3,9 @@
/*#include H(dlib)*/
/*#include H(ring)*/
#define x ) == 0 ?__LINE__:0){O =__LINE__;break;} }
#define X(x) __LINE__ x __LINE__
#define t(a)\
#define x ) == 0 ?__LINE__:0){O =__LINE__;break;} }
#define X(x) __LINE__ x __LINE__
#define t(a)\
for (c = 0; c <n##a; ++c) { \
if (strchr (a[c], 0[__FILE__])) { if (*a[c] == 0[__FILE__]) { \
if (strcmp (a[c]+__LINE__, I + strlen (I) + __LINE__ - strlen (a[c]) x else { \
@@ -16,7 +16,7 @@ for (c = 0; c <n##a; ++c) { \
int
main (int C, char **V)
{
FILE *G;
FILE *H;
int c, ne, nn, S = C < 2 ? 060 : *V[1];
char f[__LINE__][X(*)], K[(X(*))*4], L[4*X(<<)],
@@ -52,17 +52,17 @@ O:
#line 8 "<%s>:\n"
char *I = L + __LINE__;
int O = printf (__FILE__, n[nn]) +
#line 2 "0gcc -ansi -E -dM -undef %s /usr/include/%s>r\0 ("
#line 2 "0cc -ansi -E -dM -undef %s /usr/include/%s>r\0 ("
sprintf (K, 1+__FILE__, f[S-*__FILE__] + __LINE__, n[nn]);
O += system (K);
if ((G = fopen (__FILE__+44, "r")))
while ((fgets (L, (int)sizeof L, G)) != 0) {
I[strcspn (I, 46+__FILE__)] = O = 0;
if ((H = fopen (__FILE__+43, 43+__FILE__)))
while ((fgets (L, (int)sizeof L, H)) != 0) {
I[strcspn (I, 45+__FILE__)] = O = 0;
#line 1 "*r"
t (n) t (e)
if (0 == O) O = puts (L);
}
if (G != NULL) nn = fclose (G);
if (H != NULL) nn = fclose (H);
}
}
}
+59 -19
View File
@@ -17,13 +17,13 @@ bug fixes** such as [2001/anonymous](2001/anonymous/README.md) and
compile with clang, fixing entries to work with macOS (some of which are **very
complicated** such as [1998/schweikh1](1998/schweikh1/README.md)), fixing code
to work with both 32-bit and 64-bit (such as
[2001/herrmann2](2001/herrmann2/README.md)) which can be **quite complicated**
(though not always even if it seems it), providing alternate code where useful
or necessary, fixing where possible dead links and otherwise removing them, typo
and consistency fixes, improving **ALL _Makefiles_** and writing the [sgit
tool](https://github.com/xexyl/sgit) that we installed locally and have used to
easily run `sed` on files in the repository to help build the website. Thank
you **very much** for your extensive efforts in helping improve the IOCCC
[2001/herrmann2](2001/herrmann2/README.md)) which *can be* **quite complicated
too** (though not always even if it seems it), providing alternate code where
useful or necessary, fixing where possible dead links and otherwise removing
them, typo and consistency fixes, improving **ALL _Makefiles_** and writing the
[sgit tool](https://github.com/xexyl/sgit) that we installed locally and have
used to easily run `sed` on files in the repository to help build the website.
Thank you **very much** for your extensive efforts in helping improve the IOCCC
presentation of past IOCCC winners and making many many past entries work with
modern systems!
@@ -921,20 +921,60 @@ segfault fixes should be made because the program is so beautiful.
## [1998/schweikh1](1998/schweikh1/schweikh1.c) ([README.md](1998/schweikh1/README.md]))
Cody fixed this for modern systems (it did not work at all). He also made it so
that if a file fails to open it does not return but rather skips the reading of
the file. Without this fix the entry did not work.
Cody fixed this for modern systems (it did not work at all) and added an
alternate version that works with macOS. Cody also made it ever so slightly more
portable by removing the hard-coding of `gcc`, instead hard-coding it `cc`. Doing
this not only lets it work with systems without `gcc` (though in macOS it does
exist but is actually `clang`) as `cc` always should.
What was wrong? The call to `freopen()` was incorrect with the second arg (the
mode) being instead `5+__FILE__`. It now is `"r"`. There was also a call to
`fopen()` that was wrong where the mode was instead `44+__FILE__`. Interestingly
enough though this did not seem to be an issue though I cannot explain why. He
notes that it works fine with `clang` as well as `gcc` (which is what is used
but in macOS - see below for alternate code - `gcc` is clang).
Getting this entry to work was quite complicated but is also very interesting.
To see how the macOS fixes works, see the README.md but do note that this
includes spoilers for both versions! The fixes to get it to work at all are
described next.
Additionally Cody provided an alternate version for macOS. The fix is
rather complicated but very interesting. See the README.md file for details on
how it works and how to use it.
So what was wrong with the original?
The call to `freopen()` was incorrect with the second arg (the mode) being
`5+__FILE__`; it is now `"r"`. (Observe that the mode to the `fopen()`
call is: `44+__FILE__`. This might seem incorrect and indeed it can be changed
to `"r"` as well but this was not actually necessary so once this was noticed it
was changed back to the original.)
Another important change is that the files are only closed if the `FILE *H` is
`!= NULL`. Without this check, because it's almost certain that some files will
not exist, it would dereference a NULL pointer and very likely crash or halt and
catch fire :-), preventing the entry from working. Notice how `H` is a funny
macro defined as:
```c
%:define H(x) <st%:%:x##.h>
```
and yet the `FILE *` can be called `H`! This might or might not make sense to
you but if it doesn't can you figure out why?
Another fix is that previously the program would `return 1` if a file failed to
open but for the same reason as above, it being very likely some files will not
exist, the return was removed so that if the statement of the `if` is true the
`while` loop run, rather than having the loop by itself. It was done this way to
make it as close to the original as possible and to maintain the obfuscation as
close as possible as well.
Also crucial, and the final fixes to make it work, is that the arrays `K` and
`L` had to be increased in size. They were originally (somewhat bewildering at
first glance) defined as `K[X(*)], L[X(<<)]` but they were changed to
`K[(X(*))*4], L[4*X(<<)]` though it is no longer clear just how necessary this
might be.
As noted, a limitation of `gcc` existing was removed by Cody to make it so that
`gcc` is not required as `cc` should exist in every system with a C compiler and
as the author stated: as long as the options `-E -dM` of the compiler prints out
the macros in the form of `gcc -dM` i.e. the lines are in the form `#define
MACRO value` it will work, assuming that compiler can run, of course.
As for the version for macOS, the even more complicated details are described in
the [Alternate code](1998/schweikh1/README#alternate-code) section of the
README.md file as these changes pertain to the described version therein.
## [1998/schweikh2](1998/schweikh2/schweikh2.c) ([README.md](1998/schweikh2/README.md]))