diff --git a/bin/++ b/bin/++ new file mode 100755 index 0000000..e6952b5 --- /dev/null +++ b/bin/++ @@ -0,0 +1,3 @@ +#!/bin/sh + +add $1 1 diff --git a/bin/abs b/bin/abs new file mode 100755 index 0000000..f4d77b4 --- /dev/null +++ b/bin/abs @@ -0,0 +1,15 @@ +#!/bin/sh + +! eq $# 1 \ + && printf "Usage: %b [integer]\n" "$0" >/dev/stderr \ + && exit 1 + +! stris int "$1" \ + && printf "%b: %b: Not an integer\n" "$0" "$1" >/dev/stderr \ + && exit 1 + +lt $1 0 \ + && printf "%b\n" $(multiply $1 -1) \ + || printf "%b\n" $1 + +exit 0 diff --git a/bin/bak b/bin/bak new file mode 100755 index 0000000..8ea90ec --- /dev/null +++ b/bin/bak @@ -0,0 +1,24 @@ +#!/bin/sh +set -e + +argv0="$0" [ -n "$SUFFIX" ] \ + || SUFFIX=".bak" + +shift 1 + +while [ -n "$0" ]; do + if [ -e "$0$SUFFIX" ] && ! [ -d "$0$SUFFIX" ]; then + "$argv0" "$0$SUFFIX" \ + || exit $? + elif [ -d "$0$SUFFIX" ]; then + printf "%s: %s: Cannot bak directories.\n" "$argv0" "$0" 1>&2 + exit 64 # sysexits(3) EX_USAGE + elif ! [ -e "$0" ]; then + printf "%s: %s: File does not exit.\n" "$argv0" "$0" 1>&2 + exit 64 + fi + + mv "$0" "$0$SUFFIX" \ + || exit $? + shift 1 +done diff --git a/bin/calculate b/bin/calculate new file mode 100755 index 0000000..caa5c38 Binary files /dev/null and b/bin/calculate differ diff --git a/bin/cat b/bin/cat new file mode 100755 index 0000000..a96140e --- /dev/null +++ b/bin/cat @@ -0,0 +1,13 @@ +#!/bin/sh + +alias dd="dd bs=1 2>/dev/null" + +if [ -z "$1" ]; then + dd "$TMPSRC" + +cc -o "$TMPOUT" "$TMPSRC" + +dd bs=1 2>/dev/null | "$TMPOUT" diff --git a/bin/head b/bin/head new file mode 100755 index 0000000..84b6540 --- /dev/null +++ b/bin/head @@ -0,0 +1,61 @@ +#!/bin/sh + +length=10 # default length + +# core [input] [output] [length] +core() { + sed $3q <"$1" >"$2" +} + +usage() { + printf "Usage: %b [-h] [-n number]\n" "$1" + exit 1 +} + +argc=$# +argv0="$0" +output="/dev/stdout" + +while getopts 'hn:' c; do + case $c in + (h) usage "$0";; + (n) + stris uint "$OPTARG" \ + && length=$OPTARG \ + || usage "$argv0" + ;; + (:) + printf "%b: \"-$OPTARG\" requires an argument (number)\n" "$argv0" >/dev/stderr + exit 1;; + (?) + stris uint $OPTOPT >/dev/null \ + && printf "%b: This program doesn't support -[number] arguments as they're not POSIX\n" "$argv0" >/dev/stderr \ + || usage "$argv0" + exit 1;; + esac +done + +if eq $OPTIND $(add $argc 1); then # no file specified, assume stdin + core /dev/stdin "$output" $length + exit 0 +fi + +shift $OPTIND +temp0="$0" + +while true; do + ! [ -e "$0" ] \ + && printf "%b: %b: File does not exist\n" "$argv0" "$0" >/dev/stderr \ + && exit 1 + + [ -n "$1" ] && ! streq "$0" "$temp0" \ + && printf "\n" >"$output" + [ -n "$1" ] \ + && printf "==> %b <==\n" "$0" >"$output" + + core "$0" "$output" $length + + [ -n "$1" ] && shift 1 || break +done + +exit 0 diff --git a/bin/id b/bin/id new file mode 100755 index 0000000..ac53031 Binary files /dev/null and b/bin/id differ diff --git a/bin/levenshtein b/bin/levenshtein new file mode 100755 index 0000000..24b193a Binary files /dev/null and b/bin/levenshtein differ diff --git a/bin/man b/bin/man new file mode 100755 index 0000000..3f7b62d --- /dev/null +++ b/bin/man @@ -0,0 +1,87 @@ +#!/bin/sh + +argv0="$0" + +die() { printf "$*" >/dev/stderr && exit 1; } + +# A lot of these break convention when recording errors because this tries to +# imitate other implementations. +[ -n "$1" ] || die "What manual page do you want?\nFor example, try 'man man'.\n" + +[ -n "$LANG" ] || LANG="C" + +[ -n "$MANPATH" ] || MANPATH="/usr/share/man" +[ -d "$MANPATH" ] || die "$0: \$MANPATH: $MANPATH: Does not exist\n" +[ -n "$MANSECTIONS" ] \ + && default_mansections="$MANSECTIONS" \ + || default_mansections="1nl830254967" +[ -d "$MANPATH"/"$LANG" ] \ + && MANDIR="$MANPATH/$LANG" \ + || MANDIR="$MANPATH" + +if [ -z "$PAGER" ]; then + for prog in $(printf " +less +more +cat +dd + "); do + if which "$prog" >/dev/null 2>&1; then + PAGER="$prog" + break + fi + done +fi + +man() { + eq $# 2 || die "$argv0: man() called with $# arguments. Expected 2. This is a programmer error\n" + MANSECTIONS="$1" + NAME="$2" + + # the way manpages are laid out SUCKS + # so, yeah, each man section is one character. which means it's totally + # bueno to just iterate over the string like this. but $MANDIR/man1 can + # have both man.1.gz AND man.1p.gz. ARGH!!!! + for SECTION in $(printf "$MANSECTIONS" | sed 's/\(.\)/\1\n/g'); do + PAGE="$(find "$MANDIR/man$SECTION" -type f 2>/dev/null | grep "\/$NAME\.\|\/$NAME$" | sed q)" + [ -z "$PAGE" ] || break + done + + ! [ -n "$PAGE" ] \ + && printf "No manual entry for $NAME\n" \ + && return 1 + + case "$(file -bir --no-buffer "$PAGE")" in + ("text/"*) + COMMAND="cat" ;; + ("application/gzip"*) + COMMAND="zcat" ;; + (*) + die "$argv0: $PAGE: Unknown file type.\n" ;; + esac + + $COMMAND "$PAGE" | nroff -man | $PAGER +} + +# this seems to be what the popular man does +# so like `man foo -k bar` will show the manpages for foo, -k, and bar +# expected behavior imo would be manpage for foo, then gist for bar +# but let's not break things +if streq "$1" "-k"; then # -k + printf "Not yet implemented\n" && exit 1 +else # not -k + while gt $# 0; do + if eq $(fdivide $# 2) 0 && gt 1 $# || ! stris int "$1"; then + MANSECTIONS="$default_mansections" + NAME="$1" + SHIFTING=1 + elif gt 1 $(fdivide $# 2); then + MANSECTIONS="$1" + NAME="$2" + SHIFTING=2 + else exit 0 # no more args + fi + man "$MANSECTIONS" "$NAME" + shift $SHIFTING + done +fi diff --git a/bin/mod b/bin/mod new file mode 100755 index 0000000..bbb63e4 --- /dev/null +++ b/bin/mod @@ -0,0 +1,13 @@ +#!/bin/sh + +! eq $# 2 && printf "Usage: $0 [dividend] [divisor]\n" >/dev/stderr && exit 1 + +! stris int "$1" && printf "$0: $1: Not an integer\n" >/dev/stderr && exit 1 +! stris int "$2" && printf "$0: $2: Not an integer\n" >/dev/stderr && exit 1 + +dividend=$1 +divisor=$2 + +# (% a b) == (- a (* b (// a b))) +printf "%b\n" $(subtract $dividend $(multiply $divisor $(fdivide $dividend $divisor))) +exit 0 diff --git a/bin/pow b/bin/pow new file mode 100755 index 0000000..3158f07 --- /dev/null +++ b/bin/pow @@ -0,0 +1,26 @@ +#!/bin/sh + +! eq $# 2 && printf "Usage: $0 [base] [exponent]\n" >/dev/stderr && exit 1 + +! stris int "$1" && printf -- "%b: %b: Not an integer\n" "$0" "$1" >/dev/stderr && exit 1 +! stris int "$2" && printf -- "%b: %b: Not an integer\n" "$0" "$2" >/dev/stderr && exit 1 + +base=$1 +exponent=$2 + +result=1 + +while gt $exponent 0; do + result=$(multiply $result $base) + exponent=$(-- $exponent) +done + +if ! eq $result $(abs $result) && eq $base $(abs $base); then + printf "$0: Result is unexpectedly negative, possible integer overflow\n" >/dev/stderr && exit 1 +elif eq $result 0 && ! eq $base 0; then + printf "$0: Result is unexpectedly zero, possible integer overflow\n" >/dev/stderr && exit 1 +else + printf "%b\n" $result +fi + +exit 0 diff --git a/bin/runlength b/bin/runlength new file mode 100755 index 0000000..9e4c0c9 Binary files /dev/null and b/bin/runlength differ diff --git a/bin/seq b/bin/seq new file mode 100755 index 0000000..3b4ab1d --- /dev/null +++ b/bin/seq @@ -0,0 +1,44 @@ +#!/bin/sh + +argv0="$0" + +nai() { + printf "$argv0: $1: Not an integer\n" + exit 1 +} + +usage() { + printf "Usage:\n \ + $argv0 [last] + $argv0 [first] [last] + $argv0 [first] [increment] [last]\n" \ + >/dev/stderr + exit 1 +} + +[ -n "$1" ] || usage +if [ -n "$3" ]; then + stris int "$3" \ + || nai "$3" \ + && last=$3 + stris int "$2" \ + || nai "$2" \ + && increment=$2 + stris int "$1" \ + || nai "$1" \ + && first=$1 +elif [ -n "$2" ]; then + stris int "$2" \ + || nai "$2" \ + && last=$2 + stris int "$1" \ + || nai "$1" \ + && first=$1 + increment=1 +else + stris int "$1" \ + || nai "$1" \ + && last=$1 + first=1 + increment=1 +fi diff --git a/bin/subtract b/bin/subtract new file mode 100755 index 0000000..e0d4b45 --- /dev/null +++ b/bin/subtract @@ -0,0 +1,14 @@ +#!/bin/sh + +# science speak from wikipedia +! eq $# 2 && printf "Usage: $0 [minuend] [subtrahend]\n" >/dev/stderr && exit 1 + +! stris int "$1" && printf "$0: $1: Not an integer\n" >/dev/stderr && exit 1 +! stris int "$2" && printf "$0: $2: Not an integer\n" >/dev/stderr && exit 1 + +minuend=$1 +subtrahend=$2 + +# (- a b) == (+ a (* b -1)) +printf "%b\n" $(add $minuend $(multiply $subtrahend -1)) +exit 0 diff --git a/bin/true b/bin/true new file mode 100755 index 0000000..e69de29 diff --git a/bin/uwu b/bin/uwu new file mode 100755 index 0000000..2fc7f0f --- /dev/null +++ b/bin/uwu @@ -0,0 +1,10 @@ +#!/bin/sh + +# Simple script of substitutions to uwuify English. +# Not a great use of disk... +dd 2>/dev/null \ +| sed \ + -e 's/l/w/g' \ + -e 's/r/w/g' \ + -e 's/smaww/smol/g' \ + -e 's/wove/wuv/g'