summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--bin/.gitignore1
-rw-r--r--bin/Makefile1
-rw-r--r--bin/c.sh83
-rw-r--r--bin/man1/c.140
4 files changed, 125 insertions, 0 deletions
diff --git a/bin/.gitignore b/bin/.gitignore
index 540d14ec..96bd6068 100644
--- a/bin/.gitignore
+++ b/bin/.gitignore
@@ -4,6 +4,7 @@ aes
 beef
 bit
 bri
+c
 config.mk
 dtch
 edit
diff --git a/bin/Makefile b/bin/Makefile
index c170d07b..d9cce459 100644
--- a/bin/Makefile
+++ b/bin/Makefile
@@ -21,6 +21,7 @@ LDLIBS.title = -lcurl
 BINS += aes
 BINS += beef
 BINS += bit
+BINS += c
 BINS += dtch
 BINS += edit
 BINS += glitch
diff --git a/bin/c.sh b/bin/c.sh
new file mode 100644
index 00000000..f3e651ba
--- /dev/null
+++ b/bin/c.sh
@@ -0,0 +1,83 @@
+#!/bin/sh
+set -eu
+
+temp=$(mktemp -d)
+trap 'rm -r "$temp"' EXIT
+
+exec 3>>"${temp}/run.c"
+
+cat >&3 <<EOF
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <locale.h>
+#include <math.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#include <fcntl.h>
+#include <strings.h>
+#include <unistd.h>
+EOF
+
+while getopts 'e:i:' opt; do
+	case "$opt" in
+		(e) expr=$OPTARG;;
+		(i) echo "#include <${OPTARG}>" >&3;;
+		(?) exit 1;;
+	esac
+done
+shift $((OPTIND - 1))
+
+cat >&3 <<EOF
+int main(int argc, char *argv[]) {
+	(void)argc;
+	(void)argv;
+	$*;
+EOF
+
+if [ -n "${expr:-}" ]; then
+	cat >&3 <<EOF
+	printf(
+		_Generic(
+			${expr},
+			char *: "%s\n",
+			wchar_t *: "%ls\n",
+			signed char: "%hhd\n",
+			short: "%hd\n",
+			int: "%d\n",
+			long: "%ld\n",
+			long long: "%lld\n",
+			unsigned char: "%hhu\n",
+			unsigned short: "%hu\n",
+			unsigned int: "%u\n",
+			unsigned long: "%lu\n",
+			unsigned long long: "%llu\n",
+			double: "%g\n",
+			default: "%p\n"
+		),
+		${expr}
+	);
+EOF
+fi
+
+if [ $# -eq 0 -a -z "${expr:-}" ]; then
+	cat >&3
+fi
+
+echo '}' >&3
+
+cat >"${temp}/Makefile" <<EOF
+CFLAGS += -Wall -Wextra -Wpedantic
+EOF
+
+make -s -C "${temp}" run
+"${temp}/run"
diff --git a/bin/man1/c.1 b/bin/man1/c.1
new file mode 100644
index 00000000..3ae10945
--- /dev/null
+++ b/bin/man1/c.1
@@ -0,0 +1,40 @@
+.Dd May 31, 2020
+.Dt C 1
+.Os
+.
+.Sh NAME
+.Nm c
+.Nd run C
+.
+.Sh SYNOPSIS
+.Nm
+.Op Fl e Ar expr
+.Op Fl i Ar include
+.Op Ar stmts ...
+.
+.Sh DESCRIPTION
+The
+.Nm
+utility compiles and runs
+C statements wrapped in
+.Fn main
+with common includes.
+If no
+.Ar expr
+or
+.Ar stmts
+are provided,
+statements are read from standard input.
+.
+.Pp
+The arguments are as follows:
+.Bl -tag -width Ds
+.It Fl e Ar expr
+Print the result of the C expression
+.Ar expr
+after executing
+.Ar stmts .
+.It Fl i Ar include
+Add the include file
+.Ar include .
+.El