diff options
author | IIMarckus <iimarckus@gmail.com> | 2014-11-04 00:03:18 -0700 |
---|---|---|
committer | IIMarckus <iimarckus@gmail.com> | 2014-11-04 00:03:18 -0700 |
commit | a84cf98b220804685f900e603d4b1c8434c99c9d (patch) | |
tree | 887a874662c056791711407dd0e74ba0706373e2 /utils/cattbl.c | |
parent | 8962ac790608bc9c7d901ed867ef94df66b4a8e4 (diff) |
Utility improvements.
Diffstat (limited to 'utils/cattbl.c')
-rw-r--r-- | utils/cattbl.c | 79 |
1 files changed, 62 insertions, 17 deletions
diff --git a/utils/cattbl.c b/utils/cattbl.c index 494b6b9..99a7349 100644 --- a/utils/cattbl.c +++ b/utils/cattbl.c @@ -15,6 +15,8 @@ */ #include <err.h> +#include <errno.h> +#include <limits.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -33,48 +35,91 @@ int main(int argc, char *argv[]) { int i, runsum, numptrs; + long size; uint32_t *ptrs, *runsums; FILE **f; uint8_t buf[8192]; + char *ep; - if (argc < 2) { - errx(1, "Usage: cattbl file ..."); + if (argc < 3) { + errx(1, "Usage: cattbl size file ..."); } - f = reallocarray(NULL, argc - 1, sizeof *f); - ptrs = reallocarray(NULL, argc - 1, sizeof *ptrs); - runsums = reallocarray(NULL, argc - 1, sizeof *runsums); + size = strtol(argv[1], &ep, 0); + if (argv[1][0] == '\0' || *ep != '\0') { + errx(1, "invalid size '%s'", argv[1]); + } + if (errno == ERANGE && (size == LONG_MAX || size == LONG_MIN)) { + errx(1, "invalid size '%s'", argv[1]); + } + + argc -= 2; + argv += 2; + + f = reallocarray(NULL, argc, sizeof *f); + ptrs = reallocarray(NULL, argc, sizeof *ptrs); + runsums = reallocarray(NULL, argc, sizeof *runsums); numptrs = 0; putuint32BE(0, stdout); putuint32BE(0, stdout); - runsum = 16 + 16 * (argc - 1); - for (i = 1; i < argc; ++i) { - f[i - 1] = fopen(argv[i], "rb"); - if (f[i - 1] == NULL) { + runsum = 16 + 16 * (argc); + for (i = 0; i < argc; ++i) { + if (i > 0 && strcmp(argv[i], argv[i - 1]) == 0) { + runsums[i] = runsums[i - 1]; + ptrs[i] = ptrs[i - 1]; + continue; + } + f[i] = fopen(argv[i], "rb"); + if (f[i] == NULL) { err(1, "Could not open file '%s'", argv[i]); } - fseek(f[i - 1], 0, SEEK_END); - runsums[i - 1] = runsum; - runsum += ftell(f[i - 1]); - ptrs[i - 1] = ftell(f[i - 1]); - fseek(f[i - 1], 0, SEEK_SET); + fseek(f[i], 0, SEEK_END); + runsums[i] = runsum; + runsum += ftell(f[i]); + while (runsum % 16) { + ++runsum; + } + ptrs[i] = ftell(f[i]); + fseek(f[i], 0, SEEK_SET); } putuint32BE(runsum, stdout); - putuint32BE(argc - 1, stdout); - for (i = 0; i < argc - 1; ++i) { + putuint32BE(argc, stdout); + for (i = 0; i < argc; ++i) { + while (ptrs[i] % 16) { + ++ptrs[i]; + } putuint32BE(runsums[i], stdout); putuint32BE(ptrs[i], stdout); putuint32BE(0, stdout); putuint32BE(0, stdout); } - for (i = 0; i < argc - 1; ++i) { + for (i = 0; i < argc; ++i) { + if (i > 0 && strcmp(argv[i], argv[i - 1]) == 0) { + continue; + } size_t n; while ((n = fread(buf, sizeof *buf, sizeof buf, f[i])) > 0) if (fwrite(buf, sizeof *buf, n, stdout) != n) ; + while (ftell(stdout) % 16) { + fputc(0xff, stdout); + } + } + + int padspace; + padspace = size - ftell(stdout); + for (i = 0; i < sizeof buf; ++i) { + buf[i] = 0xff; + } + while (padspace > sizeof buf) { + fwrite(buf, sizeof *buf, sizeof buf, stdout); + padspace -= sizeof buf; } + fwrite(buf, sizeof *buf, padspace, stdout); + + return 0; } |