Fix 'e' feature of 2015/burton + formatting
The program is supposed to echo stdin to stdout if the program name
starts with 'e'. This was only possible if one do something like:
PATH=$PATH:.
echo '5*5+17' | eprog
because otherwise the first char would be '.' not 'e'.
This was done by using basename(3) and -include libgen.h (in the
Makefile so as to not modify the code more than is necessary).
The Makefile now copies 'prog' to 'eprog' and 'prog' to 'calc'. It also
copies 'prog.alt' to 'eprog.alt' and 'ecalc.alt' as this is what the
program is documented as.
Format fix the calc.1 man page and remove calc.man. This is so that the
formatting is correct and also so as to not have to maintain more than
one copy of the same text (which was almost certainly already out of
sync as I did not update calc.man when I added calc.1 exactly for the
reason that I deleted calc.man).
The try.sh script has been updated and so has the try.this.txt file that
try.sh uses.
This should complete the review of 2015/burton if I'm not very much
mistaken.
This commit is contained in:
1 parent
0ce39fe068
commit
0335c04e15
10 files changed
+107
-110
No files matched your search
@@ -1,6 +1,12 @@
|
||||
#
|
||||
# sort with: sort -d -u
|
||||
*.dSYM
|
||||
calc
|
||||
calc.alt
|
||||
ecalc
|
||||
ecalc.alt
|
||||
eprog
|
||||
eprog.alt
|
||||
indent
|
||||
indent.c
|
||||
indent.o
|
||||
|
||||
+14
-3
@@ -63,7 +63,7 @@ CDEFINE=
|
||||
|
||||
# Include files that are needed to compile
|
||||
#
|
||||
CINCLUDE=
|
||||
CINCLUDE= -include libgen.h
|
||||
|
||||
# Optimization
|
||||
#
|
||||
@@ -114,10 +114,10 @@ PROG= prog
|
||||
#
|
||||
OBJ= ${PROG}.o
|
||||
DATA=
|
||||
TARGET= ${PROG}
|
||||
TARGET= ${PROG} eprog
|
||||
#
|
||||
ALT_OBJ= ${PROG}.alt.o
|
||||
ALT_TARGET= ${PROG}.alt
|
||||
ALT_TARGET= ${PROG}.alt eprog.alt
|
||||
|
||||
|
||||
#################
|
||||
@@ -134,6 +134,11 @@ all: data ${TARGET}
|
||||
|
||||
${PROG}: ${PROG}.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
|
||||
${CP} -f $@ calc
|
||||
|
||||
eprog: ${PROG}
|
||||
${CP} -f ${PROG} $@
|
||||
${CP} -f ${PROG} ecalc
|
||||
|
||||
# alternative executable
|
||||
#
|
||||
@@ -143,6 +148,12 @@ alt: data ${ALT_TARGET}
|
||||
${PROG}.alt: ${PROG}.alt.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
|
||||
|
||||
eprog.alt: ${PROG}.alt
|
||||
${CP} -f ${PROG}.alt $@
|
||||
${CP} -f ${PROG}.alt ecalc.alt
|
||||
|
||||
|
||||
|
||||
# data files
|
||||
#
|
||||
data: ${DATA}
|
||||
|
||||
@@ -223,7 +223,7 @@ If the program name begins with an `e`, it echoes `stdin` to `stdout`.
|
||||
This allows for a convenient test suite:
|
||||
|
||||
```sh
|
||||
ln -s prog eprog
|
||||
ln -sf prog eprog
|
||||
PATH=. eprog < test.in | diff - test.out
|
||||
```
|
||||
|
||||
|
||||
+20
-15
@@ -11,18 +11,20 @@ The result is printed on
|
||||
as both a decimal value and its hex equivalent.
|
||||
Results are presented as 32-bit values, displaying as 64-bits only if necessary.
|
||||
If the program name begins with
|
||||
.I e
|
||||
.B e
|
||||
the input is also copied to
|
||||
.BR stdout .
|
||||
.BR stdin
|
||||
is read if there are no arguments.
|
||||
.PP
|
||||
Constants may be decimal, octal or hex.
|
||||
There are 26 registers, initialized to zero, named A-Z; the most recent result is always remembered in the register
|
||||
.IR .
|
||||
There are 26 registers, initialized to zero, named
|
||||
.B A-Z\c
|
||||
; the most recent result is always remembered in the register
|
||||
.BR .
|
||||
(dot).
|
||||
Assignments are silent; the character
|
||||
.IR $
|
||||
.I $
|
||||
will print a table of the non-zero registers.
|
||||
.PP
|
||||
All input is case-insensitive.
|
||||
@@ -30,7 +32,7 @@ Semicolons and/or newlines separate statements.
|
||||
Whitespace is ignored, except newlines cannot occur within expressions.
|
||||
Comments are introduced with
|
||||
.I #
|
||||
and extend through the following newline.
|
||||
and extend through the end of the line.
|
||||
.PP
|
||||
Operator precedence is as found in Go:
|
||||
OR and XOR are treated as additive, SHIFTing and AND are multiplicative.
|
||||
@@ -45,45 +47,48 @@ Supported operations in decreasing precedence:
|
||||
forced precedence
|
||||
.TQ
|
||||
.B \- + ! ~ ?
|
||||
unary plus/minus, not, compl, byteswap
|
||||
unary minus/plus, not, compl, byte-swap
|
||||
.TQ
|
||||
.B * / % & << >> >>>
|
||||
mul, div, mod, bitand, shift: left, right, unsigned right
|
||||
mul, div, mod, bitand, left shift, right shift, unsigned right shift
|
||||
.TQ
|
||||
.B + \- | ^
|
||||
add, sub, bitor, xor
|
||||
.TQ
|
||||
.B =
|
||||
assignment ([a-z] = expr)
|
||||
assignment (\c
|
||||
.I [a-z] = expr\c
|
||||
)
|
||||
.SH EXAMPLES
|
||||
.PP
|
||||
Display the decimal value of 0x42:
|
||||
Display the decimal value of
|
||||
.BR 0x42 :
|
||||
.sp
|
||||
.RS
|
||||
.ft B
|
||||
$ calc 0x42
|
||||
calc 0x42
|
||||
.br
|
||||
66 0x00000042
|
||||
.ft R
|
||||
66 0x00000042
|
||||
.RE
|
||||
.PP
|
||||
What is the mask value for 22 bits?
|
||||
.sp
|
||||
.RS
|
||||
.ft B
|
||||
$ calc '1<<22-1'
|
||||
calc '1<<22-1'
|
||||
.br
|
||||
4194303 0x003fffff
|
||||
.ft R
|
||||
4194303 0x003fffff
|
||||
.RE
|
||||
.PP
|
||||
What is the integer value of byte-swapped 0x11223344?
|
||||
.RS
|
||||
.ft B
|
||||
$ calc ?0x11223344
|
||||
calc ?0x11223344
|
||||
.br
|
||||
1144201745 0x44332211
|
||||
.ft R
|
||||
1144201745 0x44332211
|
||||
.RE
|
||||
.PP
|
||||
Some canned expressions:
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
NAME
|
||||
calc - an integer expression calculator that outputs in both hex and decimal
|
||||
|
||||
SYNOPSIS
|
||||
calc [expr]
|
||||
|
||||
DESCRIPTION
|
||||
calc presents a simple signed integer expression calculator.
|
||||
The result is printed on stdout as both a decimal value and its hex equivalent.
|
||||
Results are presented as 32-bit values, displaying as 64-bits only if necessary.
|
||||
If the program name begins with 'e', the input is also copied to stdout.
|
||||
stdin is read if there are no arguments.
|
||||
|
||||
Constants may be decimal, octal or hex.
|
||||
There are 26 registers, initialized to zero, named A-Z;
|
||||
the most recent result is always remembered in the register '.' (dot).
|
||||
Assignments are silent; the character '$' will print a table of the non-zero registers.
|
||||
|
||||
All input is case-insensitive.
|
||||
Semicolons and/or newlines separate statements.
|
||||
Whitespace is ignored, except newlines cannot occur within expressions.
|
||||
Comments are introduced with '#' and extend through the following newline.
|
||||
|
||||
Operator precedence is as found in Go:
|
||||
OR and XOR are treated as additive, SHIFTing and AND are multiplicative.
|
||||
This allows a more natural expression without parentheses,
|
||||
as in `a&0xff | b<<8'.
|
||||
|
||||
Supported operations in decreasing precedence:
|
||||
|
||||
() forced precedence
|
||||
- + ! ~ ? unary plus/minus, not, compl, byteswap
|
||||
* / % & << >> >>> mul, div, mod, bitand, shift: left, right, unsigned right
|
||||
+ - | ^ add, sub, bitor, xor
|
||||
= assignment ([a-z] = expr)
|
||||
|
||||
EXAMPLES
|
||||
Display the decimal value of 0x42
|
||||
|
||||
$ calc 0x42
|
||||
66 0x00000042
|
||||
|
||||
What is the mask value for 22 bits?
|
||||
|
||||
$ calc '1<<22-1'
|
||||
4194303 0x003fffff
|
||||
|
||||
What is the integer value of byte-swapped 0x11223344?
|
||||
|
||||
$ calc ?0x11223344
|
||||
1144201745 0x44332211
|
||||
|
||||
Some canned expressions:
|
||||
|
||||
cat <<! | ecalc
|
||||
# multiple assignments
|
||||
a=32;n=10;c=50;m=100;$
|
||||
7+7/7+7*7-7 # pedmas
|
||||
m|a-a*3 # convenient precedence
|
||||
?(1<<14|1<<9)-1<<4-1<<3
|
||||
57005<<16+48879
|
||||
-1 >> 32 # signed shift
|
||||
-1 >>> 32 # unsigned shift
|
||||
!
|
||||
|
||||
BUGS
|
||||
An assignment with certain types of syntax error will replace the registers with a
|
||||
partial evaluation:
|
||||
|
||||
calc 'a = 1; a; a = 3 4; a'
|
||||
1 0x00000001
|
||||
syntax error
|
||||
3 0x00000003
|
||||
|
||||
Command line expressions longer than 64 characters will give a syntax error.
|
||||
|
||||
SEE ALSO
|
||||
https://golang.org/
|
||||
@@ -87,7 +87,8 @@ I H long long Z;
|
||||
n>>a
|
||||
?h(n)<<a|h(n>>a
|
||||
):h(n):g(n); } Q main(Q x
|
||||
,L**K){ V*A; q(K); W(w())**
|
||||
,L**K){ V*A; *K=basename(
|
||||
*K); q(K); W(w())**
|
||||
K-c*c-b||p(B),_i(!setjmp(l)?T=B
|
||||
,M(((A=(*o=m()==c-~s&&(j=a|T[-b])&&
|
||||
s-m()==~s)?&o[j-a*u]:(T=B,&_)),*A=F())
|
||||
|
||||
+2
-1
@@ -87,7 +87,8 @@ I H long long Z;
|
||||
n>>a
|
||||
?h(n)<<a|h(n>>a
|
||||
):h(n):g(n); } Q main(Q x
|
||||
,L**K){ V*A; q(K); W(w())**
|
||||
,L**K){V*A; *K=basename(
|
||||
*K);q(K); W(w())**
|
||||
K-c*c-b||p(B),_i(!setjmp(l)?T=B
|
||||
,M(((A=(*o=m()==c-~s&&(j=a|T[-b])&&
|
||||
c-m()==-c)?&o[j-a*u]:(T=B,&_)),*A=F())
|
||||
|
||||
+18
-10
@@ -15,11 +15,11 @@ make CC="$CC" all >/dev/null || exit 1
|
||||
# clear screen after compilation so that only the entry is shown
|
||||
clear
|
||||
|
||||
echo "$ ./prog '?0x3343<<2'" 1>&2
|
||||
./prog '?0x3343<<2'
|
||||
echo "$ ./calc '?0x3343<<2'" 1>&2
|
||||
./calc '?0x3343<<2'
|
||||
|
||||
echo "$ echo '?0x3343<<2' | ./prog" 1>&2
|
||||
echo '?0x3343<<2' | ./prog
|
||||
echo "$ echo '?0x3343<<2' | ./ecalc" 1>&2
|
||||
echo '?0x3343<<2' | ./ecalc
|
||||
|
||||
|
||||
echo "$ grep '[0-9]' prog.c" 1>&2
|
||||
@@ -27,9 +27,9 @@ read -r -n 1 -p "Press any key to continue (notice how there are no digits!): "
|
||||
echo 1>&2
|
||||
grep -c '[0-9]' prog.c
|
||||
|
||||
read -r -n 1 -p "Press any key to run: ./prog < test.in: "
|
||||
read -r -n 1 -p "Press any key to run: ./calc < test.in: "
|
||||
echo 1>&2
|
||||
./prog < test.in
|
||||
./calc < test.in
|
||||
echo 1>&2
|
||||
|
||||
read -r -n 1 -p "Press any key to show try.this.txt: "
|
||||
@@ -37,11 +37,19 @@ echo 1>&2
|
||||
cat try.this.txt
|
||||
echo 1>&2
|
||||
|
||||
read -r -n 1 -p "Press any key to run: ./prog < try.this.txt: "
|
||||
read -r -n 1 -p "Press any key to run: ./calc < try.this.txt: "
|
||||
echo 1>&2
|
||||
./prog < try.this.txt
|
||||
./calc < try.this.txt
|
||||
|
||||
read -r -n 1 -p "Press any key to show the hex value of 42: "
|
||||
echo 1>&2
|
||||
echo "$ ./prog 42" 1>&2
|
||||
./prog 42
|
||||
echo "$ ./calc 42" 1>&2
|
||||
./calc 42
|
||||
|
||||
read -r -n 1 -p "Press any key to run: ./calc '1<<22-1' (show mask value for 22 bits): "
|
||||
echo 1>&2
|
||||
./calc '1<<22-1'
|
||||
|
||||
read -r -n 1 -p "Press any key to run: ./calc ?0x11223344 (byte-swapped value of 0x11223344): "
|
||||
echo 1>&2
|
||||
./calc ?0x11223344
|
||||
@@ -4,3 +4,13 @@ a << 16 + b
|
||||
a=0xdeadbeef
|
||||
b=0xcafe
|
||||
a << 16 + b
|
||||
|
||||
# multiple assignments
|
||||
a=32;n=10;c=50;m=100;$
|
||||
7+7/7+7*7-7 # pedmas
|
||||
m|a-a*3 # convenient precedence
|
||||
?(1<<14|1<<9)-1<<4-1<<3
|
||||
57005<<16+48879
|
||||
-1 >> 32 # signed shift
|
||||
-1 >>> 32 # unsigned shift
|
||||
!
|
||||
+34
-1
@@ -3798,10 +3798,43 @@ output.
|
||||
|
||||
## <a name="2015_burton"></a>[2015/endoh3](/2015/burton/prog.c) ([README.md](/2015/burton/README.md]))
|
||||
|
||||
[Cody](#cody) added the [try.sh](/2015/burton/try.sh) script. This involved
|
||||
|
||||
[Cody](#cody) fixed the code so one can make use of the echo feature, where the
|
||||
first character of the filename starts with `e`. The only way it would work
|
||||
before that is if one did something like:
|
||||
|
||||
```sh
|
||||
ln -sf prog eprog
|
||||
PATH=$PATH:. ; eprog '...'
|
||||
```
|
||||
|
||||
since otherwise the first character would not be `e` but rather a dot
|
||||
(`./eprog`). This was done by adding to the Makefile `-include libgen.h` and
|
||||
adding to `main()` after the variable declaration (`V*A;`) the code:
|
||||
|
||||
```c
|
||||
*K=basename(*K);
|
||||
```
|
||||
|
||||
This was done for both the [prog.c](/2015/burton/prog.c) and
|
||||
[prog.alt.c](/2015/burton/prog.alt.c). The Makefile was also updated to build
|
||||
`eprog` and `eprog.alt` to make use of the feature more easily. Each is a new
|
||||
target (first in `TARGET` and second in `ALT_TARGET`) which have a prerequisite
|
||||
of `${PROG}` and `${PROG}.alt` respectively and which copies `prog` and
|
||||
`prog.alt` to `eprog` and `eprog.alt` respectively. With these changes now one
|
||||
can easily use the echo feature the author implemented.
|
||||
|
||||
Cody also added the [try.sh](/2015/burton/try.sh) script. This involved
|
||||
adding a text file, [try.this.txt](/2015/burton/try.this.txt).
|
||||
|
||||
Cody also added [calc.1](/2015/burton/calc.1) in place of `calc.man` to have
|
||||
proper formatting (in the style of `man(1)`). The `calc.man` was removed so as
|
||||
to not have to maintain two copies of the same text.
|
||||
|
||||
Cody updated the Makefile to copy the `prog` to `calc` and `prog.alt` to
|
||||
`calc.alt`. `ecalc` and `ecalc.alt` also work. This is because the program is
|
||||
called `calc` and is in documentation including the man page. Thus one only need
|
||||
add a `./` to the commands in the man page/README.md.
|
||||
|
||||
|
||||
## <a name="2015_dogon"></a>[2015/endoh3](/2015/dogon/prog.c) ([README.md](/2015/dogon/README.md]))
|
||||
|
||||
Reference in new issue
Block a user