Merge pull request #1315 from xexyl/1992-adrian-fixes
This commit is contained in:
5 files changed
+197
-79
No files matched your search
@@ -43,7 +43,7 @@ CSILENCE= -Wno-bitwise-op-parentheses -Wno-comment -Wno-deprecated-declarations
|
||||
-Wno-logical-op-parentheses -Wno-macro-redefined -Wno-parentheses \
|
||||
-Wno-return-type -Wno-uninitialized -Wno-unused-value -Wno-unused-variable \
|
||||
-Wno-unused-but-set-variable -Wno-unsequenced -Wno-unused-parameter \
|
||||
-Wno-empty-translation-unit
|
||||
-Wno-empty-translation-unit -Wno-implicit-int
|
||||
|
||||
# Common C compiler warning flags
|
||||
#
|
||||
@@ -118,7 +118,7 @@ PROG= ${ENTRY}
|
||||
#
|
||||
OBJ= ${PROG}.o
|
||||
DATA=
|
||||
TARGET= ${PROG}
|
||||
TARGET= ${PROG} adgrep
|
||||
#
|
||||
ALT_OBJ=
|
||||
ALT_TARGET=
|
||||
|
||||
+67
-49
@@ -4,6 +4,17 @@
|
||||
make all
|
||||
```
|
||||
|
||||
### Bugs and (Mis)features:
|
||||
|
||||
The current status of this entry is:
|
||||
|
||||
```
|
||||
STATUS: known bug - please help us fix
|
||||
STATUS: INABIAF - please **DO NOT** fix
|
||||
```
|
||||
|
||||
For more detailed information see [1992 adrian in bugs.md](/bugs.md#1992-adrian).
|
||||
|
||||
|
||||
### Try:
|
||||
|
||||
@@ -17,7 +28,8 @@ For the slow minded, try:
|
||||
./adsleep 32767
|
||||
```
|
||||
|
||||
NOTE: if you do not specify an arg to the program it will segfault.
|
||||
NOTE: if you do not specify an arg some of the programs such as `adsleep` it
|
||||
will very likely segfault do something funny. This is supposed to happen.
|
||||
|
||||
|
||||
## Judges' remarks:
|
||||
@@ -32,9 +44,9 @@ NOTE: Some compilers have had trouble optimizing this entry.
|
||||
|
||||
### ADrian's GREP (adgrep)
|
||||
|
||||
For those confused by the complexity of full-blown egrep style regular
|
||||
expressions, this program offers an alternative. It implements an
|
||||
equivalent search, using a deterministic finite automaton.
|
||||
For those confused by the complexity of full-blown `egrep(1)` style regular
|
||||
expressions, this program offers an alternative. It implements an equivalent
|
||||
search, using a deterministic finite automaton.
|
||||
|
||||
A deterministic finite automaton consists of a finite set of states,
|
||||
along with transition rules to move from one state to another, an initial
|
||||
@@ -48,25 +60,30 @@ accepting states, then the string is accepted.
|
||||
The deterministic finite automaton is specified as a series of rules for
|
||||
each state:
|
||||
|
||||
<state> chars1 <dest1> chars2 <dest2> ...
|
||||
```
|
||||
<state> chars1 <dest1> chars2 <dest2> ...
|
||||
```
|
||||
|
||||
`chars1` is a list of characters (only the first 8 are significant) which
|
||||
`chars1` is a list of characters (_only the first 8_ are significant) which
|
||||
should trigger a transition to `<dest1>`. `<dest1>` is another state which
|
||||
should have a similar specification somewhere. A state is accepting if
|
||||
it is specified in square brackets: `[final]`, and state strings are
|
||||
significant to only eight characters.
|
||||
it is specified in square brackets: `[final]`; state strings are
|
||||
significant to only eight characters like `chars1`.
|
||||
|
||||
|
||||
### Example 1: matches `^abc$`
|
||||
|
||||
<q0> a <q1> The first state to appear is the start state
|
||||
<q1> b <q2>
|
||||
<q2> c [q3]
|
||||
[q3]
|
||||
```
|
||||
<q0> a <q1> The first state to appear is the start state
|
||||
<q1> b <q2>
|
||||
<q2> c [q3]
|
||||
[q3]
|
||||
```
|
||||
|
||||
Technically, a deterministic finite automaton should have a rule for each
|
||||
possible input character at each state. To simplify descriptions of the
|
||||
automata, if no rule is present, the string will not be accepted. Also,
|
||||
the `'.'` character matches any character if it occurs first in the
|
||||
the `.` character matches any character if it occurs first in the
|
||||
character list.
|
||||
|
||||
|
||||
@@ -116,55 +133,55 @@ character list.
|
||||
[q5]
|
||||
```
|
||||
|
||||
|
||||
With the automaton specification in 'filename', invoke the program by
|
||||
With the automaton specification in `filename`, invoke the program by
|
||||
typing
|
||||
|
||||
```sh
|
||||
./adgrep 'filename'
|
||||
./adrian filename
|
||||
```
|
||||
|
||||
|
||||
It will read stdin and print out all the lines which the automaton
|
||||
It will read the file and print out all the lines which the automaton
|
||||
accepts. If the file cannot be opened, a system error message will
|
||||
be printed. If the input contains errors, then an error message along
|
||||
with the number of the offending line will be printed to stderr. The\
|
||||
number of rules for each state is limited to 17. If more than 17 rules\
|
||||
are present, you get the error `too_many_rules`, and the state that was\
|
||||
being processed is printed. Error `no_destination` occurs if you specify a\
|
||||
with the number of the offending line will be printed to stderr. The
|
||||
number of rules for each state is limited to 17. If more than 17 rules
|
||||
are present, you get the error `too_many_rules`, and the state that was
|
||||
being processed is printed. Error `no_destination` occurs if you specify a
|
||||
set of characters, but no destination state, and error `too_many_states`
|
||||
occurs if your automaton has more than 257 states.
|
||||
|
||||
Running:
|
||||
|
||||
```sh
|
||||
./adgrep from < your_mailbox
|
||||
./adrian from < your_mailbox
|
||||
```
|
||||
|
||||
will perform a function similar to that of the unix from command.
|
||||
will perform a function similar to that of the unix `from` command.
|
||||
|
||||
If no filename is specified on the command line, then `"adgrep.c"` is used
|
||||
as the specification for the automaton. (This file has been renamed\
|
||||
to `adrian.c` by the judges.) In this case, the program will search for\
|
||||
If no filename is specified on the command line, then `__FILE__` is used
|
||||
as the specification for the automaton. (Originally `"adgrep.c"` the file was renamed
|
||||
to `adrian.c` by the judges but for more portability the arg was changed to
|
||||
`__FILE__`.) In this case, the program will search for
|
||||
matches to the regular expression:
|
||||
|
||||
```
|
||||
^.[^|C][^w[Q]*(Q|[w[]c).*|^.[C|]$
|
||||
```
|
||||
|
||||
I suggest using `adgrep.c` as input, and storing the output in `adwc.c`:
|
||||
I suggest using `adrian.c` as input, and storing the output in `adwc.c`:
|
||||
|
||||
```sh
|
||||
./adgrep < adgrep.c > adwc.c
|
||||
./adrian < adrian.c > adwc.c
|
||||
```
|
||||
|
||||
Compiling the new file, `mywc.c`, yields a clone of the unix wc command. It
|
||||
runs on one file (defaulting to `"adgrep.c"` if no file is given) and
|
||||
displays the number of lines, words, and bytes in the input file.
|
||||
|
||||
Compiling the new file, `adwc.c`, yields a clone of the unix `wc` command. It
|
||||
runs on one file, defaulting to `"adrian.c"` if no file is given (again, this
|
||||
was changed to be `__FILE__`) and displays the number of lines, words, and bytes
|
||||
in the input file.
|
||||
|
||||
Another possibly interesting automaton can be created by slightly
|
||||
adjusting the `adgrep.c` file. Change the first line to read
|
||||
adjusting the `adrian.c` file. Change the first line to read
|
||||
|
||||
```c
|
||||
/* . echo| . */
|
||||
@@ -173,7 +190,7 @@ adjusting the `adgrep.c` file. Change the first line to read
|
||||
and repeat the process above
|
||||
|
||||
```sh
|
||||
./adgrep <adgrep.c > adecho.c
|
||||
./adrian <adrian.c > adecho.c
|
||||
```
|
||||
|
||||
The new file now contains all lines which match
|
||||
@@ -182,7 +199,7 @@ The new file now contains all lines which match
|
||||
^.[^5|m^]*[m^]([e=p,;]|[^e=+p,;].*)$
|
||||
```
|
||||
|
||||
Compile and run. This is an echo clone. Note the efficient algorithm
|
||||
Compile and run. This is an `echo(1)` clone. Note the efficient algorithm
|
||||
employed.
|
||||
|
||||
|
||||
@@ -199,10 +216,10 @@ you can search for matches to
|
||||
^.[^W]*W..*$
|
||||
```
|
||||
|
||||
By some freak happenstance, lines of adgrep.c which match this regular
|
||||
expression form a unix head command. It prints the first ten lines of
|
||||
the file specified on the command line (or adgrep.c if no file is
|
||||
specified).
|
||||
By some freak happenstance, lines of `adrian.c` which match this regular
|
||||
expression form a unix `head(1)` command. It prints the first ten lines of
|
||||
the file specified on the command line or adrian.c if no file is
|
||||
specified (again this was changed to `__FILE__`).
|
||||
|
||||
By setting the first line to
|
||||
|
||||
@@ -210,14 +227,14 @@ By setting the first line to
|
||||
/* . basename . */
|
||||
```
|
||||
|
||||
a clone of the unix basename command can be unearthed. The automaton will
|
||||
a clone of the unix `basename(1)` command can be unearthed. The automaton will
|
||||
search for
|
||||
|
||||
```
|
||||
^.[^j]*jr.*$
|
||||
```
|
||||
|
||||
on standard input. And the program which results by running adgrep.c
|
||||
on standard input. And the program which results by running `adrian.c`
|
||||
through this filter requires two parameters. The first is meant to be a
|
||||
filename, and the second, an extension. All leading pathname components
|
||||
are removed from the filename, and the extension is removed if present.
|
||||
@@ -235,11 +252,11 @@ you can search for
|
||||
^.[^(~][^s]*sl.*$
|
||||
```
|
||||
|
||||
Filtering adgrep.c through this search yields a clone of the sleep
|
||||
command. Invoke with a single integer parameter, and it will pause
|
||||
for that many seconds.
|
||||
Filtering `adrian.c` through this search yields a clone of the `sleep(1)`
|
||||
command. Invoke with a single integer parameter, and it will pause for that
|
||||
many seconds.
|
||||
|
||||
If either adbasename or adsleep is invoked with too few parameters,
|
||||
If either `adbasename` or `adsleep` is invoked with too few parameters,
|
||||
the program will print the error message:
|
||||
|
||||
> Segmentation fault (core dumped)
|
||||
@@ -248,15 +265,16 @@ the program will print the error message:
|
||||
machine.) The four programs which read from stdin require lines
|
||||
shorter than 999 characters.
|
||||
|
||||
The other info files are adrian.grep.[1-6] which contain the six
|
||||
The other info files are `adrian.grep.[1-6]` which contain the six
|
||||
examples that appear above, and from, which is used to emulate the
|
||||
unix from command. For reasons of clarity, the name "from" should
|
||||
probably not be changed if possible. I wouldn't want to be accused of\
|
||||
unix `from` command. For reasons of clarity, the name `"from"` should
|
||||
probably not be changed if possible. I wouldn't want to be accused of
|
||||
confusing people by giving the input files weird names.
|
||||
|
||||
If you want to change the default input filename (line 80) you must be
|
||||
careful to choose a name that doesn't match the wrong search patterns,
|
||||
introducing extra lines into one of the programs.
|
||||
introducing extra lines into one of the programs (again, this was changed to be
|
||||
`__FILE__`).
|
||||
|
||||
The program will produce at least one warning and possible several
|
||||
when compiled depending on the compiler.
|
||||
|
||||
@@ -23,7 +23,7 @@ int L=0,j= -28;
|
||||
void E(int i, int m,char*c)
|
||||
{
|
||||
for(; i<43; i+=3)
|
||||
putc("}|uutsrq`_^bji`[Zkediml[PO]a_M__]ISOYIRGTNR"[i]+i-9,stderr);
|
||||
putc(i["}|uutsrq`_^bji`[Zkediml[PO]a_M__]ISOYIRGTNR"]+i-9,stderr);
|
||||
fprintf(stderr,"(%d): %s\n" ,m,c);
|
||||
exit(1);
|
||||
}
|
||||
@@ -77,7 +77,7 @@ main(int sl,char *j[]){
|
||||
v(s = V[1]; if (*V=strrchr(s,'/'))s=*V+1; if(( !strncmp( s + (jr=strlen(s)) -
|
||||
(q=strlen(V[2]) ),V[2],q))&&jr!=q) s[jr-q] = 0; puts(s); )
|
||||
int e,p,C=0,Q ,basename;
|
||||
W= fopen(wc>= 2 ? V[1] : "adgrep.c","rt");
|
||||
W= fopen(wc>= 2 ? V[1] : __FILE__,"rt");if(!W)exit(1);
|
||||
echo| m^ e| 5| (int) .8| echo|
|
||||
wc |C ==o[o[C] .e] .
|
||||
e| e==+p,p; s[o[C] .e ]
|
||||
|
||||
@@ -707,6 +707,59 @@ when you're cheating it ends up winning! Can you figure that out as well?
|
||||
|
||||
# 1992
|
||||
|
||||
## 1992 adrian
|
||||
|
||||
### STATUS: known bug - please help us fix
|
||||
### Source code: [1992/adrian/westley.c](1992/westley/westley.c)
|
||||
### Information: [1992/adrian/README.md](1992/westley/README.md)
|
||||
|
||||
The author states that:
|
||||
|
||||
```
|
||||
If the input contains errors, then an error message along
|
||||
with the number of the offending line will be printed to stderr. The
|
||||
number of rules for each state is limited to 17. If more than 17 rules
|
||||
are present, you get the error 'too_many_rules', and the state that was
|
||||
being processed is printed. Error 'no_destination' occurs if you specify a
|
||||
set of characters, but no destination state, and error 'too_many_states'
|
||||
occurs if your automaton has more than 257 states.
|
||||
```
|
||||
|
||||
but only `no_destination` appears to occur. It is possible that this is invalid
|
||||
test cases but it's also possible it simply is a bug.
|
||||
|
||||
You are welcome to try and fix these problem(s).
|
||||
|
||||
|
||||
### STATUS: INABIAF - please **DO NOT** fix
|
||||
### Source code: [1992/adrian/westley.c](1992/westley/westley.c)
|
||||
### Information: [1992/adrian/README.md](1992/westley/README.md)
|
||||
|
||||
The author stated that if the file cannot be opened then it will print a system
|
||||
error but this is not the case unless it's showing a fault. However this was
|
||||
instead fixed by Cody as part of another problem that was detected so that the
|
||||
program just exits 1 if the file cannot be opened.
|
||||
|
||||
Also, if _some_ of the programs are not given an arg they will very likely crash
|
||||
or do something funny. For instance `adsleep` and `adbasename`. This is very
|
||||
simple to fix but the author explicitly noted that this will segfault and it is
|
||||
that that is the error message.
|
||||
|
||||
Another thing is that the code:
|
||||
|
||||
```c
|
||||
printf((W,Y));
|
||||
```
|
||||
|
||||
appears to be wrong because `W` is a `FILE *` and `Y` is a `char[]` but if one
|
||||
changes it to use `fprintf()` on the file (which, incidentally, is opened in
|
||||
read only mode which is another reason) with the `%s` specifier it will make
|
||||
`adhead` not work: it'll print nothing at all! So this code should not be
|
||||
changed either even if it appears to be wrong. Notice too a curious thing: if
|
||||
you did change it to fprintf, even if you have the right number of args, you'd
|
||||
have to remove the outer `()` pair.
|
||||
|
||||
|
||||
## 1992 gson
|
||||
|
||||
### STATUS: uses gets() - change to fgets() if possible
|
||||
|
||||
+73
-26
@@ -12,22 +12,22 @@ contributed thousands, that we wish to thank.
|
||||
We call out the extensive contributions of [Cody Boone
|
||||
Ferguson](https://www.ioccc.org/winners.html#Cody_Boone_Ferguson) who is
|
||||
responsible for most of the improvements and fixes including many **EXTREMELY
|
||||
CHALLENGING bug fixes** like
|
||||
HARD bug fixes** like
|
||||
[1988/phillipps](/thanks-for-fixes.md#1988phillipps-readmemd),
|
||||
[2001/anonymous](/thanks-for-fixes.md#2001anonymous-readmemd) and
|
||||
[2004/burley](/thanks-for-fixes.md#2004burley-readmemd), making entries like
|
||||
[1985/sicherman](/thanks-for-fixes.md#1985sicherman-readmemd) and
|
||||
[1986/wall](/thanks-for-fixes.md#1986wall-readmemd) not need `-traditional-cpp`
|
||||
(all **EXTREMELY CHALLENGING**), fixing entries to work with clang (some being
|
||||
**EXTREMELY CHALLENGING** like
|
||||
(all **EXTREMELY HARD**), fixing entries to work with clang (some being
|
||||
**EXTREMELY HARD** like
|
||||
[1991/dds](/thanks-for-fixes.md#1991dds-readmemd)) or as much as possible (like
|
||||
[1989/westley](/thanks-for-fixes.md#1989westley-readmemd), a true masterpiece
|
||||
that is **INCREDIBLY HARD, _MUCH, MUCH MORE SO_ than any other fix!**), porting
|
||||
entries to macOS (some being **EXTREMELY CHALLENGING** like
|
||||
entries to macOS (some being **EXTREMELY HARD** like
|
||||
[1998/schweikh1](/thanks-for-fixes.md#1998schweikh1-readmemd)), fixing code like
|
||||
[2001/herrmann2](/thanks-for-fixes.md#2001herrmann2-readmemd) to work in both
|
||||
32-bit/64-bit which *can be* **EXTREMELY CHALLENGING**, providing alternate code
|
||||
where useful/necessary, fixing where possible dead links or removing them,
|
||||
32-bit/64-bit which *can be* **EXTREMELY HARD**, providing alternate code
|
||||
where useful/necessary, fixing where possible/removing dead links,
|
||||
typo/consistency fixes, improving **ALL _Makefiles_** and writing
|
||||
[sgit](https://github.com/xexyl/sgit) that we installed locally to easily run
|
||||
`sed` on files in the repo to help build the website. **THANK YOU VERY MUCH**
|
||||
@@ -122,9 +122,15 @@ $ warning: this program uses gets(), which is unsafe.
|
||||
whereas without the warning it's much easier to see that it's a prompt.
|
||||
|
||||
In some entries this change is not possible, in one-liners it might make them
|
||||
too long and in some entries it's more complicated than others because of the
|
||||
annoying fact that for '"compatibility" reasons' `fgets()` retains the newline
|
||||
and `gets()` does not. Nevertheless some of the entries have been updated this
|
||||
too long (though it's also been possible to do this in some cases) and in some
|
||||
entries it's more complicated than others because of the annoying fact that for
|
||||
'"compatibility" reasons' `fgets()` retains the newline and `gets()` does not.
|
||||
Some entries like [1992/adrian](1992/adrian/README.md) are more complicated in
|
||||
other ways due to the code generating other output; and because of how it works
|
||||
it would generate code that could not be compiled, simply because of spaces
|
||||
being added (a number of other fixes in that entry were also made)!
|
||||
|
||||
Nevertheless some of the entries have been updated this
|
||||
way for the reasons described above and in the [FAQ](/faq.md).
|
||||
|
||||
|
||||
@@ -143,7 +149,7 @@ the second line starts with `o, world!\n"`.
|
||||
|
||||
By request, the original code is provided as
|
||||
[anonymous.alt.c](1984/anonymous/anonymous.alt.c) so that one can look at it and
|
||||
the famous tattoo:
|
||||
the famous tattoo which we also include here:
|
||||
|
||||

|
||||
|
||||
@@ -1299,27 +1305,68 @@ should have been removed.
|
||||
|
||||
## [1992/adrian](1992/adrian/adrian.c) ([README.md](1992/adrian/README.md]))
|
||||
|
||||
Cody changed the location that it used `gets()` to be `fgets()` instead to make
|
||||
it safer and to prevent annoying warnings during compiling, linking or runtime
|
||||
(interspersed with the program's output).
|
||||
Cody fixed the code so that it will try opening the file the code was compiled
|
||||
from (`__FILE__`), not `adgrep.c`, as
|
||||
the latter does not exist: `adgrep` is simply a link to `adrian` as `adgrep` is
|
||||
what the program was submitted as but the winner is `adrian`.
|
||||
|
||||
Not fixing this would cause the program to crash if no arg was specified as the
|
||||
file did not exist. In doing this, at first the change to check for a NULL file
|
||||
was added. Then it was noticed that the problem is that `adgrep.c` was an
|
||||
incorrect reference that was never fixed in any of the files, not the code or
|
||||
the documentation. A fun fact is that one can do:
|
||||
|
||||
```c
|
||||
W= fopen(wc>= 2 ? V[1] : __FILE__,"rt");if(!W)exit(1);
|
||||
```
|
||||
|
||||
but one _CANNOT_ do:
|
||||
|
||||
```c
|
||||
W= fopen(wc>= 2 ? V[1] : __FILE__,"rt");if(!W)exit(1);
|
||||
if (W==NULL)exit(1);
|
||||
```
|
||||
|
||||
because `adwc.c` will be empty! The difference is it is on a newline, the check.
|
||||
This is an example of how a simple change in code can break it and this is also
|
||||
true of another change as further below.
|
||||
|
||||
Cody also restored a slightly more obscure line of code that had been changed:
|
||||
|
||||
```diff
|
||||
- putc("}|uutsrq`_^bji`[Zkediml[PO]a_M__]ISOYIRGTNR"[i]+i-9,stderr);
|
||||
+ putc(i["}|uutsrq`_^bji`[Zkediml[PO]a_M__]ISOYIRGTNR"]+i-9,stderr);
|
||||
```
|
||||
|
||||
though it's questionable how much more (if at all) obscure that is.
|
||||
|
||||
Cody also changed the location that it used `gets()` to be `fgets()` instead to
|
||||
make it safer and to prevent annoying warnings during compiling, linking or
|
||||
runtime (interspersed with the program's output). This was complicated because
|
||||
of how the other source files are generated, as noted above; simply changing the
|
||||
code could cause invalid output in the program which made other files fail to
|
||||
compile (for this example specifically, see below).
|
||||
|
||||
One might think that simply changing the `gets()` to `fgets()` (with `stdin`)
|
||||
would work but it did not because `fgets()` stores the newline and `gets()` does
|
||||
not. That is well known but this code was relying on not having this newline
|
||||
(see also above).
|
||||
|
||||
With `fgets()` the code `if(A(Y)) puts(Y);` ended up printing an extra line
|
||||
which made the generation of some files (like `adhead.c`) fail to compile. Why?
|
||||
There was a blank line after a `\` at the end of the first line of a macro
|
||||
definition! Thus the code now first trims off the last character of the buffer
|
||||
read to get the same correct functionality but in a safe and non obnoxious way.
|
||||
|
||||
Later Cody improved the change to `fgets()` to make it slightly more like the
|
||||
original. This still requires the additional stripping of the newline inside the
|
||||
loop but now it uses what looks like before, just a call to `gets()`.
|
||||
|
||||
One might think that simply changing the `gets()` to `fgets()` (with `stdin`)
|
||||
would work but it did not because `fgets()` stores the newline and `gets()` does
|
||||
not. The code was relying on not having this newline. With `fgets()` the code
|
||||
`if(A(Y)) puts(Y);` ended up printing an extra line which made the generation of
|
||||
some files (like `adhead.c`) fail to compile. Why? There was a blank line after
|
||||
a `\` at the end of the first line of a macro definition! Thus the code now
|
||||
first trims off the last character of the buffer read to get the same correct
|
||||
functionality but in a safe way and non obnoxious way.
|
||||
|
||||
But the improvement so that it uses `gets()` could not be changed to have the
|
||||
macro do the removal of the extra line (as in with a comma operator or a `&&`)
|
||||
as this caused compilation errors with another generated file (`adwc.c`). Thus
|
||||
after the `gets()` call in the line that looks like:
|
||||
as this, as might be expected from the above, caused compilation errors with
|
||||
another generated file (`adwc.c`)! Thus after the `gets()` call in the line that
|
||||
looks like:
|
||||
|
||||
```c
|
||||
while( gets(Y) ){ Y[strlen(Y)-1]='\0'; if(A(Y)) puts(Y); }
|
||||
@@ -1327,8 +1374,8 @@ while( gets(Y) ){ Y[strlen(Y)-1]='\0'; if(A(Y)) puts(Y); }
|
||||
|
||||
one must keep the `Y[strlen(Y)-1]='\0';` part and keep it there.
|
||||
|
||||
This is a complex change due to the way the program and Makefile generate
|
||||
additional tools.
|
||||
These fixes are complex changes due to the way the program and Makefile generate
|
||||
the additional tools.
|
||||
|
||||
|
||||
## [1992/albert](1992/albert/albert.c) ([README.md](1992/albert/README.md]))
|
||||
|
||||
Reference in new issue
Block a user