Mercurial > bcc
changeset 0:e5fc6565dce0 1.0.0
misc: initial import
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 21 Oct 2020 15:27:50 +0200 |
parents | |
children | 8fef9c38dee7 |
files | .hgignore CHANGES.md INSTALL.md LICENSE.md Makefile README.md bcc.1 bcc.c |
diffstat | 8 files changed, 415 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /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])); +}