misc: initial import 1.0.0

Wed, 21 Oct 2020 15:27:50 +0200

author
David Demelier <markand@malikania.fr>
date
Wed, 21 Oct 2020 15:27:50 +0200
changeset 0
e5fc6565dce0
child 1
8fef9c38dee7

misc: initial import

.hgignore file | annotate | diff | comparison | revisions
CHANGES.md file | annotate | diff | comparison | revisions
INSTALL.md file | annotate | diff | comparison | revisions
LICENSE.md file | annotate | diff | comparison | revisions
Makefile file | annotate | diff | comparison | revisions
README.md file | annotate | diff | comparison | revisions
bcc.1 file | annotate | diff | comparison | revisions
bcc.c file | annotate | diff | comparison | revisions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Wed Oct 21 15:27:50 2020 +0200
@@ -0,0 +1,14 @@
+# bcc executable.
+\.o$
+^bcc$
+^bcc-\d\.\d.\d\.tar\.xz(\.asc)?$
+
+# vim/emacs specific.
+^tags$
+^tags.lock$
+^tags.temp$
+\.swp$
+\.swo$
+
+# macOS specific.
+\.DS_Store$
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CHANGES.md	Wed Oct 21 15:27:50 2020 +0200
@@ -0,0 +1,5 @@
+bcc CHANGES
+===========
+
+bcc current
+-----------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/INSTALL.md	Wed Oct 21 15:27:50 2020 +0200
@@ -0,0 +1,21 @@
+bcc INSTALL
+===========
+
+Installation instructions.
+
+Requirements
+------------
+
+- C11, a C11 compiler (GCC, Clang),
+- POSIX make, a POSIX make implementation,
+- POSIX getopt, the utility make use of `getopt(3)`.
+
+Basic installation
+------------------
+
+Quick install.
+
+	$ tar xvzf bcc-x.y.z-tar.xz
+	$ cd bcc-x.y.z
+	$ make
+	# sudo make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LICENSE.md	Wed Oct 21 15:27:50 2020 +0200
@@ -0,0 +1,16 @@
+bcc ISC LICENSE
+===============
+
+Copyright (c) 2020 David Demelier <markand@malikania.fr>
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile	Wed Oct 21 15:27:50 2020 +0200
@@ -0,0 +1,60 @@
+#
+# Makefile -- basic makefile for bcc
+#
+# Copyright (c) 2020 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+.POSIX:
+
+# User options.
+CC=             cc
+CFLAGS=         -Wall -Wextra -DNDEBUG -D_XOPEN_SOURCE=700 -O3 -std=c11 -pedantic
+
+# Installation paths.
+PREFIX=         /usr/local
+BINDIR=         ${PREFIX}/bin
+MANDIR=         ${PREFIX}/share/man
+
+VERSION=        1.0.0
+SRCS=           bcc.c
+OBJS=           ${SRCS:.c=.o}
+
+.SUFFIXES:
+.SUFFIXES: .o .c
+
+all: bcc
+
+.c.o:
+	${CC} ${CFLAGS} -c $< -o $@
+
+bcc: ${OBJS}
+	${CC} -o $@ ${OBJS}${LDFLAGS}
+
+dist: clean
+	mkdir bcc-${VERSION}
+	cp CHANGES.md INSTALL.md LICENSE.md Makefile README.md bcc.1 bcc.c bcc-${VERSION}
+	tar -cJf bcc-${VERSION}.tar.xz bcc-${VERSION}
+	rm -rf bcc-${VERSION}
+
+install:
+	mkdir -p ${DESTDIR}${BINDIR}
+	cp bcc ${DESTDIR}${BINDIR}
+	mkdir -p ${DESTDIR}${MANDIR}/man1
+	cp bcc.1 ${DESTDIR}${MANDIR}/man1
+
+clean:
+	rm -f bcc ${OBJS} bcc-${VERSION}.tar.xz
+
+.PHONY: all clean dist install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.md	Wed Oct 21 15:27:50 2020 +0200
@@ -0,0 +1,25 @@
+bcc
+===
+
+Simple tool to convert any file into a C or C++ array for direct inclusion into
+the source code.
+
+Quick usage
+-----------
+
+Example: convert a image for embedding.
+
+	bcc -scu mario.png mario > mario.h
+
+Now, you can include mario.h file and use `mario` C array, `sizeof (mario)` is
+also possible.
+
+Documentation
+-------------
+
+See bcc(1) manual page.
+
+Author
+------
+
+David Demelier <markand@malikania.fr>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bcc.1	Wed Oct 21 15:27:50 2020 +0200
@@ -0,0 +1,98 @@
+.\"
+.\" Copyright (c) 2020 David Demelier <markand@malikania.fr>
+.\"
+.\" Permission to use, copy, modify, and/or distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd October 21, 2020
+.Dt BCC 1
+.Os
+.\" NAME
+.Sh NAME
+.Nm bcc
+.Nd binary to C/C++ arrays converter
+.\" SYNOPSIS
+.Sh SYNOPSIS
+.Nm bcc
+.Op Fl 0csu
+.Op Fl I Ar tab-indent
+.Op Fl i Ar space-indent
+.Ar filename
+.Ar variable
+.\" DESCRIPTION
+.Sh DESCRIPTION
+The
+.Nm
+utility converts the
+.Ar input
+file into a C or C++ array named
+.Ar variable
+that can be embedded as-is in the source code. A special
+.Ar -
+value can be passed as input which will read standard input instead.
+.Pp
+The
+.Ar variable
+can contain any character but only ones that are allowed in the C standard will
+be kept, other will be replaced with a
+.Dq _ .
+Also, the extension (by finding the first .) is removed as well. This can be
+handy when generating a lots of file based on their names during a build
+process.
+.Pp
+Note: you must still not start a variable name with digits.
+.Pp
+The following options are available:
+.Bl -tag -width indent-xxxxxxxx
+.It Fl 0
+Terminate the generated array with a trailing NUL.
+.It Fl c
+Generates a
+.Em const
+array.
+.It Fl s
+Generate a
+.Em static
+array.
+.It Fl u
+Use an
+.Em unsigned
+char rather than
+.Em signed .
+.It Fl I Ar tab-indent
+.Ar tab-indent
+count as leading indents.
+.It Fl i Ar space-indent
+.Ar space-indent
+count as leading indents.
+.El
+.\" EXAMPLES
+.Sh EXAMPLES
+Create a static, const, unsigned array from an image.
+.Bd -literal -offset indent
+bcc -scu image.png image > image.h
+.Ed
+.Pp
+Create a modifiable array from a text file as a NUL terminated string.
+.Bd -literal -offset indent
+bcc -0 text.txt text > text.h
+.Ed
+.\" HISTORY
+.Sh HISTORY
+The
+.Nm
+tool is inspired by
+.Nm xxd
+utility but offers more flexibility over the the generated code.
+.\" SEE ALSO
+.Sh SEE ALSO
+.Xr xxd 1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bcc.c	Wed Oct 21 15:27:50 2020 +0200
@@ -0,0 +1,176 @@
+/*
+ * bcc.c -- binary to C/C++ arrays converter
+ *
+ * Copyright (c) 2020 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdnoreturn.h>
+#include <string.h>
+#include <unistd.h>
+
+static const char *charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_";
+static char findentchar = '\t';
+static int findent = 1;
+static bool fconst;
+static bool fnull;
+static bool fstatic;
+static bool funsigned;
+
+noreturn static void
+usage(void)
+{
+	fprintf(stderr, "usage: bcc [-0csu] [-I tab-indent] [-i space-indent] input variable\n");
+	exit(1);
+}
+
+noreturn static void
+die(const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	fputs("abort: ", stderr);
+	vfprintf(stderr, fmt, ap);
+	va_end(ap);
+	exit(1);
+}
+
+static char *
+mangle(char *variable)
+{
+	char *p;
+	size_t pos;
+
+	/* Remove extension. */
+	if ((p = strrchr(variable, '.')))
+		*p = '\0';
+
+	/* Remove disallowed characters. */
+	while ((pos = strspn(variable, charset)) != strlen(variable))
+		variable[pos] = '_';
+
+	return variable;
+}
+
+static void
+indent(void)
+{
+	for (int i = 0; i < findent; ++i)
+		putchar(findentchar);
+}
+
+static void
+put(int ch)
+{
+	if (funsigned)
+		printf("0x%02hhx", (unsigned char)ch);
+	else
+		printf("%hhd", (signed char)ch);
+}
+
+static void
+process(const char *input, const char *variable)
+{
+	FILE *fp;
+	int ch, col = 0;
+
+	if (strcmp(input, "-") == 0)
+		fp = stdin;
+	else if (!(fp = fopen(input, "rb")))
+		die("%s: %s\n", input, strerror(errno));
+
+	if (fstatic)
+		printf("static ");
+	if (fconst)
+		printf("const ");
+
+	printf(funsigned ? "unsigned " : "signed ");
+	printf("char %s[] = {\n", variable);
+
+	for (ch = fgetc(fp); ch != EOF; ) {
+		if (col == 0)
+			indent();
+
+		put(ch);
+
+		if ((ch = fgetc(fp)) != EOF || fnull)
+			printf(",%s", col < 3 ? " " : "");
+
+		if (++col == 4) {
+			col = 0;
+			putchar('\n');
+		}
+
+		/* Add final '\0' if required. */
+		if (ch == EOF && fnull) {
+			if (col++ == 0)
+				indent();
+
+			put(0);
+		}
+	}
+
+	if (col != 0)
+		printf("\n");
+
+	puts("};");
+	fclose(fp);
+}
+
+int
+main(int argc, char **argv)
+{
+	int ch;
+
+	while ((ch = getopt(argc, argv, "0cI:i:su")) != -1) {
+		switch (ch) {
+		case '0':
+			fnull = true;
+			break;
+		case 'c':
+			fconst = true;
+			break;
+		case 'I':
+			findentchar = '\t';
+			findent = atoi(optarg);
+			break;
+		case 'i':
+			findentchar = ' ';
+			findent = atoi(optarg);
+			break;
+		case 's':
+			fstatic = true;
+			break;
+		case 'u':
+			funsigned = true;
+			break;
+		default:
+			break;
+		}
+	}
+
+	argc -= optind;
+	argv += optind;
+
+	if (argc < 2)
+		usage();
+
+	process(argv[0], mangle(argv[1]));
+}

mercurial