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:
1 parent
fa02fba4e3
commit
cb02b4da5f
5 files changed
+138
-14
No files matched your search
@@ -1 +1,2 @@
|
|||||||
schweikh1
|
schweikh1
|
||||||
|
schweikh1.alt
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|
||||||
#################
|
#################
|
||||||
|
|||||||
@@ -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";
|
||||||
$_ = <>;
|
$_ = <>;
|
||||||
|
|||||||
@@ -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__);
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user