Fix segfault in 1993/plummer
Now it just does nothing if two args are not given to the program. It seems better to me that it shouldn't crash because of invalid input unless that's a feature. This is why I've been doing this for other entries as well. It would be problematic to the program to add a usage string but I can at least make a check first. Another thought I had was adding to the Makefile a warning for entries like this but perhaps both would be the best way to go about it so that users would know that they had to give certain input for it to work. I don't known but this is a start anyway. I also fixed the formatting of the README.md file.
This commit is contained in:
1 parent
bc2e636366
commit
c79aa3081c
2 files changed
+59
-55
No files matched your search
+58
-54
@@ -13,69 +13,73 @@
|
|||||||
|
|
||||||
./plummer number arg
|
./plummer number arg
|
||||||
|
|
||||||
where:
|
where:
|
||||||
|
|
||||||
number a number (try 21701)
|
number is a number (try 21701)
|
||||||
arg any argument
|
arg is any argument
|
||||||
|
|
||||||
## Judges' comments
|
[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) added a check in the
|
||||||
|
code so that it will not segfault if not enough args are specified. Thank you
|
||||||
|
Cody!
|
||||||
|
|
||||||
|
## Judges' comments:
|
||||||
|
|
||||||
For extra credit: What happens when 'number' contains non-numeric
|
For extra credit: What happens when 'number' contains non-numeric
|
||||||
characters, and why?
|
characters, and why?
|
||||||
|
|
||||||
## Author's comments
|
## Author's comments
|
||||||
|
|
||||||
This program prints out all numbers up to a given number of digits
|
This program prints out all numbers up to a given number of digits
|
||||||
on a single line. When the largest number is reached, the program
|
on a single line. When the largest number is reached, the program
|
||||||
starts again with 0. It takes two arguments: the first argument
|
starts again with 0. It takes two arguments: the first argument
|
||||||
specifies the number to start counting from and uses leading 0's to
|
specifies the number to start counting from and uses leading 0's to
|
||||||
indicate the number of digits, the second argument can be anything
|
indicate the number of digits, the second argument can be anything
|
||||||
but must be present.
|
but must be present.
|
||||||
|
|
||||||
Variable names are single characters chosen for their similarity to
|
Variable names are single characters chosen for their similarity to
|
||||||
other characters (O for 0, l for 1, S for 5 (in some fonts), and _
|
other characters (O for 0, l for 1, S for 5 (in some fonts), and _
|
||||||
for ... well nothing really, but it is easy to miss). To prevent
|
for ... well nothing really, but it is easy to miss). To prevent
|
||||||
the need for strlen(), the fact that argv is laid out sequentially
|
the need for `strlen()`, the fact that argv is laid out sequentially
|
||||||
is exploited (ie. argv[i + 1] == argv[i] + strlen(argv[i]) + 1).
|
is exploited (ie. `argv[i + 1] == argv[i] + strlen(argv[i]) + 1`).
|
||||||
This is not portable (by the books), but it seems to work
|
This is not portable (by the books), but it seems to work
|
||||||
everywhere I try (actually, for vms, that only holds for i > 1).
|
everywhere I try (actually, for vms, that only holds for `i > 1`).
|
||||||
Also, I depend on the fact that a carriage return causes the line
|
Also, I depend on the fact that a carriage return causes the line
|
||||||
just written to be overwritten. lint (and most compilers) complain
|
just written to be overwritten. lint (and most compilers) complain
|
||||||
that there is no control path leading to a return from main(). At
|
that there is no control path leading to a return from main(). At
|
||||||
125 characters, it still fits on a single line (for those of us who
|
125 characters, it still fits on a single line (for those of us who
|
||||||
don't mind ruining our eyes with 132 column screens).
|
don't mind ruining our eyes with 132 column screens).
|
||||||
|
|
||||||
The first statement points the base of l (the argument vector) to
|
The first statement points the base of `l` (the argument vector) to
|
||||||
be the first argument by incrementing it. It then assigns O to
|
be the first argument by incrementing it. It then assigns `O` to
|
||||||
point to the character before the first character of the second
|
point to the character before the first character of the second
|
||||||
argument which also happens to be the null termination of the first
|
argument which also happens to be the null termination of the first
|
||||||
argument. *O gets a \r assigned to it. Finally 0 is assigned to
|
argument. `*O` gets a `\r` assigned to it. Finally `0` is assigned to
|
||||||
the first character of the second argument which has the effect of
|
the first character of the second argument which has the effect of
|
||||||
null terminating the first argument after the carriage return had
|
null terminating the first argument after the carriage return had
|
||||||
removed its null termination. I really tried to make the last part
|
removed its null termination. I really tried to make the last part
|
||||||
of that statement part of the original expression, but the best I
|
of that statement part of the original expression, but the best I
|
||||||
could do was attach it with a comma (against the advice of K&R).
|
could do was attach it with a comma (against the advice of K&R).
|
||||||
The for loop runs the next for loop continuously (actually until
|
The for loop runs the next for loop continuously (actually until
|
||||||
the machine crashes or the user gets tired of seeing the
|
the machine crashes or the user gets tired of seeing the
|
||||||
counting). The next for loop is the meat of the program. In the
|
counting). The next for loop is the meat of the program. In the
|
||||||
initialization statement, the string pointed to by l (the first
|
initialization statement, the string pointed to by `l` (the first
|
||||||
argument containing the digits used for counting followed by a \r)
|
argument containing the digits used for counting followed by a `\r`)
|
||||||
is printed, and _ is started at the least significant digit in the
|
is printed, and `_` is started at the least significant digit in the
|
||||||
string. In the test portion, _ is insured not to be past the
|
string. In the test portion, `_` is insured not to be past the
|
||||||
beginning of the string (the most significant digit), and the digit
|
beginning of the string (the most significant digit), and the digit
|
||||||
pointed to by _ is incremented and checked to be sure that it _is_
|
pointed to by `_` is incremented and checked to be sure that it _is_
|
||||||
greater than '9' (written here as (S+*O+S)*S). If the test fails,
|
greater than `9` (written here as `(S+*O+S)*S`). If the test fails,
|
||||||
either the string has been incremented or each digit in the string
|
either the string has been incremented or each digit in the string
|
||||||
has been reset to '0'. If the test succeeded, the iteration
|
has been reset to `0`. If the test succeeded, the iteration
|
||||||
statement assigns '0' (written here as (S+*O)*S (which has the
|
statement assigns `0` (written here as `(S+*O)*S` (which has the
|
||||||
added bonus of having the code be a cry for help)) to *_ and
|
added bonus of having the code be a cry for help)) to `*_` and
|
||||||
decrements _ to point to the next more significant digit to be
|
decrements `_` to point to the next more significant digit to be
|
||||||
incremented; it is done only when a carry situation results (*_ has
|
incremented; it is done only when a carry situation results (`*_` has
|
||||||
been incremented past '9').
|
been incremented past `9`).
|
||||||
|
|
||||||
The inspiration for this program came from actual code which dealt
|
The inspiration for this program came from actual code which dealt
|
||||||
with scanning for a unique temporary filename by appending a
|
with scanning for a unique temporary filename by appending a
|
||||||
successively larger number to the end of a string.
|
successively larger number to the end of a string.
|
||||||
|
|
||||||
## Copyright and CC BY-SA 4.0 License:
|
## Copyright and CC BY-SA 4.0 License:
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
char*_,*O;main(S,l)char**l;{*(O=*(l+++S-1)-1)=13,*l[1]=0;for(;;)for(printf(*l),_=O-1;_>=*l&&++*_>(S+*O+S)*S;*_--=(S+*O)*S);}
|
char*_,*O;main(S,l)char**l;{if(S>2){*(O=*(l+++S-1)-1)=13,*l[1]=0;for(;;)for(printf(*l),_=O-1;_>=*l&&++*_>(S+*O+S)*S;*_--=(S+*O)*S);}}
|
||||||
Reference in new issue
Block a user