Fix 1998/schweikh1 and add alt code for macOS

This was a fun one to figure out and fix!

The original code did not work; there were several things wrong with it
as below. The macOS version was even more complicated but also fun and
also described below.

The problem with the original was a bad call to freopen() where the arg
parameter was actually 5+__FILE__ when it should be "r" (though of
course it used to work fine). A call to fopen() had a similar mode:
44+__FILE__ though this actually did not seem to affect the output. But
it didn't work with macOS at all. The following is some of what I put in
the README.md so that one can see here too what was wrong. Spoilers for
the original entry (at least some spoilers) are here!

For this alternative version you will need the command line tools which
you can install like:

```sh
sudo xcode-select --install
```

This how it 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:

	"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. Somehow it was basic intuition that made me figure out these
two numbers and a quick test confirmed it. 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.

This 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.
This commit is contained in:
Cody Boone Ferguson committed 2023-03-26 06:29:52 -07:00
1 parent fa02fba4e3
commit cb02b4da5f
5 files changed
+138 -14

No files matched your search

+1
View File
@@ -1 +1,2 @@
schweikh1 schweikh1
schweikh1.alt
+2 -2
View File
@@ -142,8 +142,8 @@ OBJ= ${PROG}.o
DATA= info DATA= info
TARGET= ${PROG} TARGET= ${PROG}
# #
ALT_OBJ= ALT_OBJ= ${PROG}.alt.o
ALT_TARGET= ALT_TARGET= ${PROG}.alt
################# #################
+56 -3
View File
@@ -12,11 +12,63 @@
make all make all
### To run [Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) 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.
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 alternative code - `gcc` is clang).
Additionally Cody provided an alternative version for macOS. See below for the
alternative version. Thank you Cody for your assistance!
### Alternative code:
As noted above [Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) made an
alternative version that 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).
Cody said that at least with his 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.
For this alternative version you will need the command line tools which you can
install 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:
"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.
This 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.
To use this version use `schweikh1.alt` instead.
### To run:
./schweikh1 ./schweikh1
## Judges' comments ## Judges' comments:
What does it do? It seems to print a list of system headers, perhaps 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 with words after them. Curiously, if you look at the list of words
@@ -88,7 +140,7 @@
macros are explicitly enumerated. In a compliant implementation no other macros are explicitly enumerated. In a compliant implementation no other
macros can be defined, because you could write strictly conforming macros can be defined, because you could write strictly conforming
programs that may fail to compile due to syntax errors: suppose programs that may fail to compile due to syntax errors: suppose
<stdio.h> defines PIPE_BUF, then the conforming `<stdio.h>` defines `PIPE_BUF`, then the conforming
#include <assert.h> #include <assert.h>
#include <stdio.h> /* <- or where the bogus macro is defined */ #include <stdio.h> /* <- or where the bogus macro is defined */
@@ -193,6 +245,7 @@
counter but decided to err on the side of safety. I use a perl counter but decided to err on the side of safety. I use a perl
script to compute the character count according to the rules. script to compute the character count according to the rules.
The advantages of an independent clean room approach... The advantages of an independent clean room approach...
#!/usr/bin/perl -w #!/usr/bin/perl -w
$/ = "\0"; $/ = "\0";
$_ = <>; $_ = <>;
+70
View File
@@ -0,0 +1,70 @@
%:define H(x) <st%:%:x##.h>
/*#include H(dio)*/
/*#include H(dlib)*/
/*#include H(ring)*/
#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 { \
if (strncmp (a[c], I, strlen (a[c])-__LINE__ x \
} else { if (strcmp (a[c], I x }
#line 4 "info\0r"
int
main (int C, char **V)
{
FILE *G;
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__];
if (freopen (__FILE__, "r", stdin) == 0) return __LINE__-13;
for (c = 0;;) {
#line 1 "#\n"
if (!fgets (f[c], (int)sizeof *f, stdin)) return __LINE__; if (*f[c] == 0[__FILE__]) continue; if (*f[c] != __LINE__[__FILE__]) { f[c][strlen (f[c]) - __LINE__] = 2[__FILE__];
++c;
} else
break;
}
for (ne = 0;;) {
do {
#line 1 "#%s%s"
if (!fgets (L, (int)sizeof L, stdin)) return __LINE__; } while (*L == 0[__FILE__]); switch (sscanf (L, __LINE__+__FILE__, F, e[ne])) { default: goto O;
case __LINE__: switch (strchr (F, S)!=0) case 1: ++ne;
}
}
O:
nn = 0;
while ((fgets (L, (int) sizeof L, stdin)) != 0) {
char A[__LINE__], f3; if (*L == 0[__FILE__]) continue;
#line 1 "%s%s %c"
switch (sscanf (L, __FILE__, A, n[nn], &f3)) {
case __LINE__: if (strchr (A, S)) ++nn; break;
case __LINE__:
if (strchr (A, S)) {
#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 ("
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;
#line 1 "*r"
t (n) t (e)
if (0 == O) O = puts (L);
}
if (G != NULL) nn = fclose (G);
}
}
}
return remove (1+__FILE__);
}
+9 -9
View File
@@ -3,9 +3,9 @@
/*#include H(dlib)*/ /*#include H(dlib)*/
/*#include H(ring)*/ /*#include H(ring)*/
#define x ) == 0 ?__LINE__:0){O =__LINE__;break;} } #define x ) == 0 ?__LINE__:0){O =__LINE__;break;} }
#define X(x) __LINE__ x __LINE__ #define X(x) __LINE__ x __LINE__
#define t(a)\ #define t(a)\
for (c = 0; c <n##a; ++c) { \ for (c = 0; c <n##a; ++c) { \
if (strchr (a[c], 0[__FILE__])) { if (*a[c] == 0[__FILE__]) { \ 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 { \ if (strcmp (a[c]+__LINE__, I + strlen (I) + __LINE__ - strlen (a[c]) x else { \
@@ -16,13 +16,13 @@ for (c = 0; c <n##a; ++c) { \
int int
main (int C, char **V) main (int C, char **V)
{ {
FILE *H; FILE *G;
int c, ne, nn, S = C < 2 ? 060 : *V[1]; int c, ne, nn, S = C < 2 ? 060 : *V[1];
char f[__LINE__][X(*)], K[X(*)], L[X(<<)], 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(<<)][3*__LINE__], F[__LINE__];
if (freopen (__FILE__, 5+__FILE__, stdin) == 0) return __LINE__-13; if (freopen (__FILE__, "r", stdin) == 0) return __LINE__-13;
for (c = 0;;) { for (c = 0;;) {
#line 1 "#\n" #line 1 "#\n"
if (!fgets (f[c], (int)sizeof *f, stdin)) return __LINE__; if (*f[c] == 0[__FILE__]) continue; if (*f[c] != __LINE__[__FILE__]) { f[c][strlen (f[c]) - __LINE__] = 2[__FILE__]; if (!fgets (f[c], (int)sizeof *f, stdin)) return __LINE__; if (*f[c] == 0[__FILE__]) continue; if (*f[c] != __LINE__[__FILE__]) { f[c][strlen (f[c]) - __LINE__] = 2[__FILE__];
@@ -55,14 +55,14 @@ O:
#line 2 "0gcc -ansi -E -dM -undef %s /usr/include/%s>r\0 (" #line 2 "0gcc -ansi -E -dM -undef %s /usr/include/%s>r\0 ("
sprintf (K, 1+__FILE__, f[S-*__FILE__] + __LINE__, n[nn]); sprintf (K, 1+__FILE__, f[S-*__FILE__] + __LINE__, n[nn]);
O += system (K); O += system (K);
if ((H = fopen (__FILE__+44, 44+__FILE__)) == 0) return 1; if ((G = fopen (__FILE__+44, "r")))
while ((fgets (L, (int)sizeof L, H)) != 0) { while ((fgets (L, (int)sizeof L, G)) != 0) {
I[strcspn (I, 46+__FILE__)] = O = 0; I[strcspn (I, 46+__FILE__)] = O = 0;
#line 1 "*r" #line 1 "*r"
t (n) t (e) t (n) t (e)
if (0 == O) O = puts (L); if (0 == O) O = puts (L);
} }
nn = fclose (H); if (G != NULL) nn = fclose (G);
} }
} }
} }