#!/bin/sh
PATH=
dd=/bin/dd
rm=/bin/rm
tmp=/tmp/silly.$$
ed=/tmp/ed.$$
trap "$rm -f $tmp $tmp.1 $tmp.2 $tmp.3 $tmp.4 $tmp.5 $tmp.6 $ed.a $ed.b $ed.c; exit" 0 1 2 3
unset rm
saveIFS="$IFS"
Echo () {
case "$1" in
-n) shift
$dd of=$tmp 2>/dev/null <<EOF
$@
EOF
IFS="+"
set `$dd if=$tmp bs=1 of=/dev/null skip=1 2>&1`
IFS="$saveIFS"
$dd if=$tmp bs=1 count=$1 2>/dev/null
;;
*) $dd 2>/dev/null <<EOF
$@
EOF
;;
esac
}
true () {
return 0
}
false () {
return 1
}
zero () {
( trap 'go=false' 13
go=true
while $go
do
$dd "if=$0"
case "$?" in
0) ;;
*) go=false ;;
esac
done
) 2>/dev/null
}
add () {
result="$1"
shift
$dd if=/dev/null of=$tmp bs=1 2>/dev/null
for n in "$@"
do
case "$n" in
0) ;;
*) zero | $dd of=$tmp.1 bs=1 "count=$n" 2>/dev/null
( $dd if=$tmp; $dd if=$tmp.1 ) 2>/dev/null | $dd of=$tmp.2 2>/dev/null
$dd if=$tmp.2 of=$tmp 2>/dev/null
;;
esac
done
IFS="+"
set `$dd if=$tmp bs=1 of=/dev/null 2>&1`
IFS="$saveIFS"
eval $result='$1'
}
subtract () {
result="$1"
zero | $dd of=$tmp bs=1 "count=$2" 2>/dev/null
IFS="+"
set `$dd if=$tmp bs=1 of=/dev/null "skip=$3" 2>&1`
IFS="$saveIFS"
case "$1" in
dd*) set 0 ;;
esac
eval $result='$1'
}
multiply () {
result="$1"
zero | $dd "bs=$2" of=$tmp "count=$3" 2>/dev/null
IFS="+"
set `$dd if=$tmp bs=1 of=/dev/null 2>&1`
IFS="$saveIFS"
eval $result='$1'
}
divide () {
result="$1"
zero | $dd bs=1 of=$tmp "count=$2" 2>/dev/null
IFS="+"
set `$dd if=$tmp "bs=$3" of=/dev/null 2>&1`
IFS="$saveIFS"
eval $result='$1'
}
compare () {
res="$1"
n1="$2"
n2="$3"
subtract somename "$n1" "$n2"
case "$somename" in
0) ;;
*) eval $res=gt; return;
esac
subtract somename "$n2" "$n1"
case "$somename" in
0) ;;
*) eval $res=lt; return;
esac
eval $res=eq
}
lt () {
n1="$1"
n2="$2"
subtract somename "$n2" "$n1"
case "$somename" in
0) return 1 ;;
esac
return 0
}
le () {
n1="$1"
n2="$2"
subtract somename "$n1" "$n2"
case "$somename" in
0) return 0 ;;
esac
return 1
}
gt () {
n1="$1"
n2="$2"
subtract somename "$n1" "$n2"
case "$somename" in
0) return 1 ;;
esac
return 0
}
ge () {
n1="$1"
n2="$2"
subtract somename "$n2" "$n1"
case "$somename" in
0) return 0 ;;
esac
return 1
}
open () {
file="$1"
set `$dd "if=$file" of=/dev/null 2>&1`
case "$1" in
dd*) return 1
esac
go=true
len=0
while $go
do
case "`$dd "if=$file" bs=1 skip=$len count=1 2>/dev/null`" in
?*) go=true ;;
*) go=false ;;
esac
add len 1 $len
done
$dd "if=$file" bs=1 count=$len of=$ed.c 2>/dev/null
$dd "if=$file" bs=1 skip=$len of=$ed.b 2>/dev/null
$dd if=/dev/null of=$ed.a 2>/dev/null
lineno=1
}
save () {
$dd "if=$1" "of=$1.bak" 2>/dev/null
( $dd if=$ed.a; $dd if=$ed.c; $dd if=$ed.b ) > "$1" 2>/dev/null
}
replace () {
$dd if=$ed.c of=$tmp.1 bs=1 "count=$1" 2>/dev/null
( $dd if=$ed.c "skip=$1" bs=1 | $dd of=$tmp.2 bs=1 "skip=$2" ) 2>/dev/null
shift
shift
( $dd if=$tmp.1; Echo -n "$@"; $dd if=$tmp.2 ) > $tmp.3 2>/dev/null
$dd if=$tmp.3 of=$ed.c 2>/dev/null
}
rstring () {
n="$1"
shift;
$dd if=/dev/null of=$tmp.4 2>/dev/null
$dd if=$ed.c of=$tmp.5 2>/dev/null
string="$1"
shift
$dd of=$tmp.6 2>/dev/null <<EOF
$@
EOF
while :
do
case "`$dd if=$tmp.5 2>/dev/null`" in
$string*)
if lt $n 2
then
Echo -n "$@" > $tmp.2
Echo -n "$string" > $tmp.1
IFS="+"
set `$dd bs=1 if=$tmp.1 of=/dev/null 2>&1`
IFS="$saveIFS"
slen=$1
IFS="+"
( $dd if=$tmp.4; $dd if=$tmp.2; $dd if=$tmp.5 bs=1 skip=$slen ) \
2>/dev/null > $tmp
$dd if=$tmp of=$ed.c 2>/dev/null
return 0
else
subtract n $n 1
( $dd if=$tmp.4; $dd if=$tmp.5 bs=1 count=1 ) > $tmp 2>/dev/null
$dd if=$tmp of=$tmp.4 2>/dev/null
$dd if=$tmp.5 of=$tmp bs=1 skip=1 2>/dev/null
$dd if=$tmp of=$tmp.5 2>/dev/null
fi
;;
?*) ( $dd if=$tmp.4; $dd if=$tmp.5 bs=1 count=1 ) > $tmp 2>/dev/null
$dd if=$tmp of=$tmp.4 2>/dev/null
$dd if=$tmp.5 of=$tmp bs=1 skip=1 2>/dev/null
$dd if=$tmp of=$tmp.5 2>/dev/null
;;
*) return 1
;;
esac
done
}
next () {
add l $lineno 1
( $dd if=$ed.a; $dd if=$ed.c ) 2>/dev/null > $tmp.3
$dd if=$ed.b of=$tmp.4 2>/dev/null
open $tmp.4
$dd if=$tmp.3 of=$ed.a 2>/dev/null
lineno=$l
}
delete () {
l=$lineno
$dd if=$ed.a 2>/dev/null > $tmp.1
$dd if=$ed.b of=$tmp.2 2>/dev/null
open $tmp.2
$dd if=$tmp.1 of=$ed.a 2>/dev/null
lineno=$l
}
insert () {
( $dd if=$ed.a; Echo "$@" ) 2>/dev/null > $tmp.1
$dd if=$tmp.1 of=$ed.a 2>/dev/null
add lineno $lineno 1
}
prev () {
case "$lineno" in
1) ;;
*) subtract lineno $lineno 1
IFS='+'
set `$dd if=$ed.a of=/dev/null bs=1 2>&1`
IFS="$saveIFS"
size=$1
case "$size" in
0) return ;;
esac
subtract size $size 1
case "$size" in
0) ;;
*) subtract size1 $size 1
case "`$dd if=$ed.a bs=1 skip=$size count=1 2>/dev/null`" in
?*) ;;
*) size=$size1 ;;
esac
;;
esac
go=true
while $go
do
case "$size" in
0) go=false ;;
*) case "`$dd if=$ed.a bs=1 skip=$size count=1 2>/dev/null`" in
?*) go=true; subtract size $size 1 ;;
*) go=false; add size $size 1 ;;
esac
;;
esac
done
( $dd if=$ed.c; $dd if=$ed.b ) 2>/dev/null > $tmp.5
$dd if=$tmp.5 of=$ed.b 2>/dev/null
case "$size" in
0) $dd if=$ed.a of=$ed.c 2>/dev/null
$dd if=/dev/null of=$tmp.5 2>/dev/null
;;
*) $dd if=$ed.a of=$ed.c bs=1 skip=$size 2>/dev/null
$dd if=$ed.a of=$tmp.5 bs=1 count=$size 2>/dev/null
;;
esac
$dd if=$tmp.5 of=$ed.a 2>/dev/null
;;
esac
}
goto () {
rl="$1"
compare bla "$rl" $lineno
case "$bla" in
eq) return
;;
gt) while gt "$rl" $lineno
do
next
done
;;
lt) while lt "$rl" $lineno
do
prev
done
;;
esac
}
lineout () {
Echo -n "$lineno: "
$dd if=$ed.c 2>/dev/null
}
state=closed
name=
autoprint=true
while true
do
Echo -n '> '
read cmd arg
case "$cmd:$state" in
open:open) Echo "There is a file open already" ;;
open:*) if open "$arg"
then state=open; name="$arg"; $autoprint
else Echo "Cannot open $arg"
fi
;;
new:open) Echo "There is a file open already" ;;
new:*) open "$arg"
state=open
name="$arg"
$autoprint
;;
close:changed) Echo "Use 'discard' or 'save'" ;;
close:closed) Echo "Closed already" ;;
close:*) state=closed ;;
save:closed) Echo "There isn't a file to save" ;;
save:*) case "$arg" in
?*) save "$arg" ;;
*) save "$name" ;;
esac
state=open
;;
discard:changed) Echo "Your problem!"; state=closed ;;
discard:*) state=closed ;;
print:closed) Echo "No current file" ;;
print:*) lineout ;;
goto:closed) Echo "No current file" ;;
goto:*) goto "$arg"; $autoprint ;;
next:closed) Echo "No current file" ;;
next:*) next; $autoprint ;;
prev:closed) Echo "No current file" ;;
prev:*) prev; $autoprint ;;
name:closed) Echo "No current file" ;;
name:*) name="$arg" ;;
replace:closed) Echo "No current file" ;;
replace:*) if rstring 1 $arg
then state=changed; $autoprint
else Echo "Not found"
fi
;;
nreplace:closed) Echo "No current file" ;;
nreplace:*) if rstring $arg
then state=changed; $autoprint
else Echo "Not found"
fi
;;
delete:closed) Echo "No current file" ;;
delete:*) delete; state=changed; $autoprint ;;
insert:closed) Echo "No current file" ;;
insert:*) insert "$arg"; prev; state=changed; $autoprint ;;
quit:changed) Echo "Use 'save' or 'discard'" ;;
quit:*) Echo "bye"; exit;;
autoprint:*) autoprint="lineout" ;;
noprint:*) autoprint="" ;;
:*) ;;
*) Echo "Command not understood" ;;
esac
done