diff options
| author | Tomasz Kramkowski <tk@the-tk.com> | 2018-03-28 00:09:21 +0100 | 
|---|---|---|
| committer | Tomasz Kramkowski <tk@the-tk.com> | 2018-03-28 00:11:22 +0100 | 
| commit | 933cf4f0a47306ee4b0c1ac728173a576cc2ebe1 (patch) | |
| tree | 6fd7446f4bc2a230d3d5bc24eae0dde4a6eefbbc | |
| download | bie-master.tar.gz bie-master.tar.xz bie-master.zip  | |
| -rw-r--r-- | .gitignore | 13 | ||||
| -rw-r--r-- | LICENSE | 20 | ||||
| -rw-r--r-- | Makefile | 43 | ||||
| -rw-r--r-- | README | 56 | ||||
| -rw-r--r-- | bie.1.in | 70 | ||||
| -rw-r--r-- | bie.c | 134 | 
6 files changed, 336 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..54eb42b --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +*.o +bie + +*.d + +tags +TAGS + +config.mk + +eprintf.h +eprintf.c +bie.1 @@ -0,0 +1,20 @@ +Copyright 2018 Tomasz Kramkowski <tk@the-tk.com> + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..982352c --- /dev/null +++ b/Makefile @@ -0,0 +1,43 @@ +# Copyright (C) 2018 Tomasz Kramkowski <tk@the-tk.com> +# SPDX-License-Identifier: MIT +-include config.mk + +PROG := bie +MANPAGE := $(PROG).1 +VERSION != git describe --tags 2>/dev/null || echo "v0.1" + +EPRINTF_PATH ?= ../eprintf +PKG_CONFIG ?= pkg-config +LN ?= ln -sf + +CPPFLAGS += -DVERSION=\"$(VERSION)\" +CFLAGS += -std=c11 -MMD -MP + +OBJ := bie.o eprintf.o +DEP := $(OBJ:.o=.d) + +prefix ?= /usr/local +exec_prefix ?= $(prefix) +bindir = $(exec_prefix)/bin +datarootdir = $(prefix)/share +mandir = $(datarootdir)/man +man1dir = $(mandir)/man1 + +all: $(PROG) $(MANPAGE) +$(PROG): $(OBJ) +bie.o: eprintf.h +$(MANPAGE): $(MANPAGE).in +	m4 -DVERSION=$(VERSION) $^ >$@ + +install: $(PROG) $(MANPAGE) +	install -Dm755 -s $(PROG) -t $(DESTDIR)$(bindir) +	install -Dm644 $(MANPAGE) -t $(DESTDIR)$(man1dir) + +clean: +	$(RM) $(OBJ) $(DEP) $(PROG) $(MANPAGE) + +include $(EPRINTF_PATH)/module.mk + +-include $(DEP) + +.PHONY: all install clean @@ -0,0 +1,56 @@ +	  		     _     _ +			    | |   (_) +			    | |__  _  ___ +			    | '_ \| |/ _ \ +			    | |_) | |  __/ +			    |_.__/|_|\___| + +--------------------------------------------------------------------- + +bie is a tool for generating a simple indexed flat archive. + +Example: +======== + +$ echo "foo" >a +$ dd if=/dev/urandom of=b bs=30 count=1 +$ zlib-flate -compress <bie.c >c +$ bie archive.bie archive.idx a b c +$ hexdump -C archive.bie +00000000  66 6f 6f 0a 00 00 00 00  00 00 00 00 00 00 00 00  |foo.............| +00000010  1b c9 01 82 4f df 1a ec  01 2a dc 0e 3e f1 e7 52  |....O....*..>..R| +00000020  ed e3 99 3e 70 b0 eb 6f  f8 20 49 ba b9 8d 00 00  |...>p..o. I.....| +00000030  78 9c 95 54 6d 6f d3 30  10 fe 9c fc 8a a3 a8 6b  |x..Tmo.0.......k| +00000040  d2 76 5d 37 10 42 7d 19  2f a5 43 15 65 a0 ad 93  |.v]7.B}./.C.e...| +00000050  40 6c 1a 21 71 5a ab 89  1d c5 4e c7 c6 fa df b9  |@l.!qZ....N.....| +... SNIP ... +$ cat archive.idx +BIE_ENTRY(a, 0, 4) +BIE_ENTRY(b, 16, 30) +BIE_ENTRY(c, 48, 750) + +Use: +==== + +Create an archive and index from a list of files you wish to access +from your program. + +Use the CPP or another macro processor to expand BIE_ENTRY to some +code which stores this information in your program. + +Read the archive into memory (or link it in) and use the offset and +size data from the index to read from the archive. + +Dependencies: +============= + +eprintf - https://the-tk.com/cgit/eprintf/ +Place in a directory adjacent to the location of the bie sources or +override EPRINTF_PATH in config.mk + +Compilation and Installation: +============================= + +$ echo prefix=/usr >config.mk +$ make +# make install diff --git a/bie.1.in b/bie.1.in new file mode 100644 index 0000000..3dc9eef --- /dev/null +++ b/bie.1.in @@ -0,0 +1,70 @@ +.\" Copyright (C) 2018 Tomasz Kramkowski <tk@the-tk.com> +.\" SPDX-License-Identifier: MIT +.TH "BIE" "1" "2018-03-27" "bie VERSION" "bie Manual" + +.SH "NAME" +bie \- a tool for generating an indexed flat archive + +.SH "SYNOPSIS" +.B bie +.RB [ -hv ] +.RB [ -- ] +.I output index input... + +.SH "DESCRIPTION" +.I output +is the destination of the flat archive. +.I index +is the destination of the index file. +.I input +is the list of files to archive. +.P +The output is a concatenation of the contents of all the input files +with each file aligned to as 16 byte boundary. The format of the index +file is a list of macro calls to BIE_ENTRY with the parameters being +the name, the offset and the size of each input file. +.P +An appropriate definition of BIE_ENTRY should be provided to make use +of this information. +.P +The name of each input file will be slugified to remove any characters +which are not valid inside a C identifier (leading digits are +removed). The slugification process leaves alphanumeric characters +alone, replaces punctuation and spaces with underscores and removes +any other characters. Any resulting leading underscores are dropped. +.P +.B bie +does not attempt to fix name collisions. + +.SH "OPTIONS" +.B -h +.RS +Show help. +.RE + +.B -v +.RS +Show version and license information. +.RE + +.SH "EXAMPLES" +bie assets.bie assets.idx a b c +.RS +This will instruct +.B bie +to read the contents of the files named a, b and c and to generate an +assets.bie which is a concatenation of the aligned file contents of a, +b and c and to generate an assets.idx which might look like this: + +.nf +BIE_ENTRY(a, 0, 10) +BIE_ENTRY(b, 16, 30) +BIE_ENTRY(c, 48, 100) +.fi +.RE + +.SH "SEE ALSO" +.BR ld (1), +.BR zlib-flate (1) +.SH AUTHOR +Tomasz Kramkowski <tk@the-tk.com> @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2018 Tomasz Kramkowski <tk@the-tk.com> + * SPDX-License-Identifier: MIT + */ +#include <ctype.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> + +#include "eprintf.h" + +#ifndef VERSION +#define VERSION "v0.1" +#endif + +enum { +	ALIGN = 16, +}; + +static const char *usage = "[-hv] [--] output map input..."; + +static void help(void) +{ +	fprintf(stderr, +		"Options:\n" +		"    -h  Show this help.\n" +		"    -v  Show version and license information.\n" +		"\n" +		"Please check the bie(1) man page for more information.\n"); +} + +static void version(void) +{ +	fprintf(stderr, +		"bie %s\n" +		"Copyright (C) 2018 Tomasz Kramkowski <tk@the-tk.com>\n" +		"Licensed under the MIT license <https://opensource.org/licenses/MIT>\n" +		"There is NO WARRANTY, to the extent permitted by law.\n", +		VERSION); +} + +static void slug(FILE *f, const char *text) +{ +	bool leading = true; +	int c; + +	while (c = *text++, c != '\0') { +		if (isalpha(c)) { +			leading = false; +			fputc(c, f); +			continue; +		} +		if (leading) continue; +		if (isdigit(c)) +			fputc(c, f); +		else if (ispunct(c) || isspace(c)) +			fputc('_', f); +	} +} + +static void mapentry(FILE *map, const char *name, size_t pos, size_t size) +{ +	fprintf(map, "BIE_ENTRY("); +	slug(map, name); +	fprintf(map, ", %zu, %zu)\n", pos, size); +} + +static size_t dumpfile(FILE *dest, FILE *src) +{ +	size_t size = 0; +	int c; + +	while (c = fgetc(src), c != EOF) { +		size++; +		fputc(c, dest); +	} + +	return size; +} + +int main(int argc, char **argv) +{ +	const char *argv0 = argv[0] != NULL ? argv[0] : "bie"; +	FILE *dest, *map; +	size_t pos = 0; + +	setprogname(argv0); + +	for (argv++, argc--; argv[0] != NULL && argv[0][0] == '-' && +		     argv[0][1] != '-' && argv[0][2] == '\0'; argv++, argc--) { +		switch (argv[0][1]) { +		case 'h': +			fprintf(stderr, "Usage: %s %s\n", argv0, usage); +			help(); +			return EXIT_SUCCESS; +		case 'v': +			version(); +			return EXIT_SUCCESS; +		} +	} + +	if (argc < 3) +		eprintf("Invalid argument count\nUsage: %s %s", argv0, usage); + +	dest = fopen(argv[0], "wb"); +	if (dest == NULL) +		eprintf("Could not open `%s':", argv[0]); + +	map = fopen(argv[1], "w"); +	if (map == NULL) +		eprintf("Could not open `%s':", argv[1]); + +	for (int i = 2; i < argc; i++) { +		size_t size; +		FILE *src; + +		src = fopen(argv[i], "rb"); +		if (src == NULL) +			eprintf("Could not open `%s':", argv[i]); +		size = dumpfile(dest, src); +		fclose(src); +		mapentry(map, argv[i], pos, size); +		pos += size; +		if (pos % ALIGN) { +			size_t pad = ALIGN - pos % ALIGN; +			for (size_t i = 0; i < pad; i++) +				fputc(0, dest); +			pos += pad; +		} +	} + +	fclose(map); +	fclose(dest); +}  | 
