summaryrefslogtreecommitdiff
path: root/utils/cattbl.c
diff options
context:
space:
mode:
authorIIMarckus <iimarckus@gmail.com>2014-11-04 00:03:18 -0700
committerIIMarckus <iimarckus@gmail.com>2014-11-04 00:03:18 -0700
commita84cf98b220804685f900e603d4b1c8434c99c9d (patch)
tree887a874662c056791711407dd0e74ba0706373e2 /utils/cattbl.c
parent8962ac790608bc9c7d901ed867ef94df66b4a8e4 (diff)
Utility improvements.
Diffstat (limited to 'utils/cattbl.c')
-rw-r--r--utils/cattbl.c79
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;
}