summaryrefslogtreecommitdiff
path: root/dbm_dump
diff options
context:
space:
mode:
authorJohn Vogel <jvogel4@stny.rr.com>2024-07-07 11:04:55 -0400
committerJohn Vogel <jvogel4@stny.rr.com>2024-07-07 11:05:36 -0400
commit02db4af5a25b782ced5d2c44321fb0e091763c52 (patch)
treee4771bb295e974f589ef3271fe90cca4dc312968 /dbm_dump
parent3338e5fdfae80928be8b9f5cc33aa4d526cad609 (diff)
downloadmy-aports-02db4af5a25b782ced5d2c44321fb0e091763c52.tar.gz
local/dbm_dump: new aport
From openbsd's regress/usr.bin/mandoc/db/dbm_dump/.
Diffstat (limited to 'dbm_dump')
-rw-r--r--dbm_dump/APKBUILD27
-rw-r--r--dbm_dump/dbm_dump.1191
-rw-r--r--dbm_dump/dbm_dump.c252
3 files changed, 470 insertions, 0 deletions
diff --git a/dbm_dump/APKBUILD b/dbm_dump/APKBUILD
new file mode 100644
index 0000000..3f644d8
--- /dev/null
+++ b/dbm_dump/APKBUILD
@@ -0,0 +1,27 @@
+# Maintainer: John Vogel <jvogel4@stny.rr.com>
+pkgname=dbm_dump
+pkgver=1.3
+pkgrel=0
+pkgdesc="openbsd's dbm_dump - function to dump mandoc database"
+url="https://mandoc.bsd.lv/"
+arch="all"
+license="ISC"
+makedepends="mandoc-dev"
+subpackages="$pkgname-doc"
+source="dbm_dump.c dbm_dump.1"
+options="!check"
+builddir="$srcdir"
+
+build() {
+ gcc $CFLAGS -o dbm_dump "$srcdir"/dbm_dump.c \
+ $LDFLAGS -lmandoc_compat -lmandoc_db -lmandoc
+}
+
+package() {
+ install -D -m 755 -t "$pkgdir/usr/bin" dbm_dump
+ install -D -m 644 -t "$pkgdir/usr/share/man/man1" "$srcdir"/dbm_dump.1
+}
+sha512sums="
+cc05d8df7f35d281896be827187b5a7e363d132202ca59c693bbbece8959023f84db8a3cd1f9bce6031b72a374935981927165c3aad8bb5d15e55fed9b7b1603 dbm_dump.c
+c6e60af1fef5e4a485747a1a0417d0c0142c5cd286931e8335f165c430c18468e772d189f536fd15e21e0a4e1712a48e079f51cf7adbb6b5aed802111a0abc41 dbm_dump.1
+"
diff --git a/dbm_dump/dbm_dump.1 b/dbm_dump/dbm_dump.1
new file mode 100644
index 0000000..4b58977
--- /dev/null
+++ b/dbm_dump/dbm_dump.1
@@ -0,0 +1,191 @@
+.\" $OpenBSD: dbm_dump.1,v 1.1 2016/07/30 10:56:13 schwarze Exp $
+.\"
+.\" Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
+.\"
+.\" Permission to use, copy, modify, and 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 $Mdocdate: July 30 2016 $
+.Dt DBM_DUMP 1
+.Os
+.Sh NAME
+.Nm dbm_dump
+.Nd dump a mandoc.db(5) file
+.Sh SYNOPSIS
+.Nm dbm_dump
+.Ar file
+.Sh DESCRIPTION
+The
+.Nm
+utility reads a
+.Xr mandoc_db 5
+database from the given
+.Ar file
+and dumps it to the standard output in a format that is suitable for
+.Xr diff 1 .
+.Pp
+Offsets are given in bytes, zero-based, and printed in hexadecimal numbers.
+Counts are printed in decimal numbers.
+.Pp
+Each non-empty table - the PAGES table, the MACROS table, and any
+MACRO table - is preceded and followed by a line beginning with
+three equal signs
+.Pq Sq === .
+Empty tables produce no output.
+.Pp
+In the PAGES table, an entry may produce four or five lines of output,
+depending on whether an
+.Fa arch
+value is present.
+Each
+.Fa name
+value is preceded by one or more attributes in square brackets,
+telling what kind of a name it is:
+.Pp
+.Bl -tag -width 1n -compact -offset indent
+.It Sy f
+a file name
+.It Sy h
+a header line name taken from a
+.Ic \&Dt
+or
+.Ic \&TH
+macro
+.It Sy 1
+the name from the first
+.Ic \&Nm
+macro in the NAME section
+.It Sy t
+a title name: a name from any
+.Ic \&Nm
+macro in the NAME section
+.It Sy s
+any name from a
+.Ic \&Nm
+macro in the SYNOPSIS section
+.El
+.Pp
+In each MACRO table, macro values are followed by the primary name
+of each page in which they occur.
+This does not uniquely identify the pages because several pages
+may share the same primary name.
+.Sh FILES
+The header files
+.Qq Pa mansearch.h ,
+.Qq Pa dbm_map.h ,
+and
+.Qq Pa dbm.h
+and the object files
+.Pa dbm_map.o
+and
+.Pa dbm.o
+from the
+.Xr mandoc 1
+build are required to compile and link
+.Nm .
+.Sh EXIT STATUS
+.Ex -std
+It fails when no argument or more than one argument is given or when
+.Fn dbm_open
+fails.
+The pointer jumps described below
+.Sx DIAGNOSTICS
+do not imply failure.
+.Sh EXAMPLES
+Several examples of
+.Nm
+output can be found in the directory
+.Pa /usr/src/regress/usr.bin/mandoc/db/out/ .
+Standard output is saved in files with the extension
+.Pa *.dout ,
+standard error is collected in the file
+.Pa all.derr .
+.Sh DIAGNOSTICS
+The function
+.Fn dbm_open
+detects various kinds of issues with the file format
+and reports them on the standard error output.
+.Pp
+Otherwise, the
+.Nm
+utility checks that the input file contains no holes
+and that no pointers point backwards.
+For each violation, the following message is printed:
+.Pp
+.D1 Ar pointer Sy jumps from Ar expected Sy to Ar specified
+.Pp
+Here,
+.Ar pointer
+specifies what the dubious pointer is supposed to point to:
+.Pp
+.Bl -tag -width macros -compact
+.It Sy name0
+the primary name of the first page
+.It Sy name
+the primary name of another page
+.It Sy sect0
+the first section of the first page
+.It Sy sect
+the first section of another page
+.It Sy arch0
+the first architecture of the first architecture-specific page
+.It Sy arch
+the first architecture of another page
+.It Sy desc0
+the one-line description of the first page
+.It Sy desc
+the one-line description of another page
+.It Sy file0
+the first filename of the first page
+.It Sy file
+the first filename of another page
+.It Sy macros
+the number of macro tables
+.It Sy macro0
+the number of entries in the first macro table
+.It Sy macro
+the number of entries in another macro table
+.It Sy value0
+the first value of a macro
+.It Sy value
+another value of a macro
+.It Sy pages0
+the list of pointers to pages mentioning the first macro value
+.It Sy pages
+the list of pointers to pages mentioning another macro value
+.It Sy end
+the final magic
+.El
+.Pp
+The hexadecimal 32-bit integers
+.Ar expected
+and
+.Ar specified
+give the byte offset of a specific data element in the file;
+respectively, the one
+.Ar expected
+from the end of the preceding data in the file and the one actually
+.Ar found
+when reading the location where the pointer ought to be.
+If
+.Ar found
+is greater than
+.Ar expected ,
+there is a hole, and the file could theoretically still be usable,
+even though it is not likely to be correct.
+If
+.Ar found
+is less than
+.Ar expected ,
+the file is corrupt because it contains a backward pointer.
+.Sh AUTHORS
+.An Ingo Schwarze Aq Mt schwarze@openbsd.org
diff --git a/dbm_dump/dbm_dump.c b/dbm_dump/dbm_dump.c
new file mode 100644
index 0000000..a2e7fbe
--- /dev/null
+++ b/dbm_dump/dbm_dump.c
@@ -0,0 +1,252 @@
+/* $OpenBSD: dbm_dump.c,v 1.3 2024/05/14 00:31:48 schwarze Exp $ */
+/*
+ * Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ * Function to dump an on-disk read-only mandoc database
+ * in diff(1)able format for debugging purposes.
+ *
+ * 2024/06/18 modified to build on alpine linux (just includes) jvogel
+ */
+#include <endian.h>
+#include <err.h>
+#include <regex.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <mandoc/mansearch.h>
+#include <mandoc/dbm_map.h>
+#include <mandoc/dbm.h>
+
+union ptr {
+ const char *c;
+ const int32_t *i;
+};
+
+static void dump(void);
+static const char *dump_macro(union ptr, int32_t);
+static const char *dump_macros(union ptr);
+static const char *dump_pages(union ptr);
+static void dump_str(const char **);
+static void dump_lst(const char **);
+static void pchk(const char *, const char **, const char *, int);
+
+
+int
+main(int argc, char *argv[])
+{
+ if (argc != 2)
+ errx(1, "usage: dump filename");
+ if (dbm_open(argv[1]) == -1)
+ err(1, "%s", argv[1]);
+ dump();
+ dbm_close();
+ return 0;
+}
+
+static void
+dump(void)
+{
+ union ptr p, macros, end;
+
+ p.i = dbm_getint(0);
+ printf("initial magic 0x%08x\n", be32toh(*p.i++));
+ printf("version 0x%08x\n", be32toh(*p.i++));
+ printf("macros offset 0x%08x\n", be32toh(*p.i));
+ macros.i = dbm_get(*p.i++);
+ printf("end offset 0x%08x\n", be32toh(*p.i));
+ end.i = dbm_get(*p.i++);
+ p.c = dump_pages(p);
+ pchk(macros.c, &p.c, "macros", 3);
+ p.c = dump_macros(p);
+ pchk(end.c, &p.c, "end", 0);
+ printf("final magic 0x%08x\n", be32toh(*p.i));
+}
+
+static const char *
+dump_pages(union ptr p)
+{
+ const char *name0, *sect0, *arch0, *desc0, *file0;
+ const char *namep, *sectp, *archp, *descp, *filep;
+ int32_t i, npages;
+
+ npages = be32toh(*p.i++);
+ printf("page count %d\n", npages);
+ if (npages == 0)
+ return p.c;
+ namep = name0 = dbm_get(p.i[0]);
+ sectp = sect0 = dbm_get(p.i[1]);
+ archp = arch0 = p.i[2] == 0 ? NULL : dbm_get(p.i[2]);
+ descp = desc0 = dbm_get(p.i[3]);
+ filep = file0 = dbm_get(p.i[4]);
+ printf("=== PAGES ===\n");
+ for (i = 0; i < npages; i++) {
+ pchk(dbm_get(*p.i++), &namep, "name", 0);
+ printf("page name ");
+ dump_lst(&namep);
+ pchk(dbm_get(*p.i++), &sectp, "sect", 0);
+ printf("page sect ");
+ dump_lst(&sectp);
+ if (*p.i++) {
+ if (arch0 == NULL)
+ archp = arch0 = dbm_get(p.i[-1]);
+ else
+ pchk(dbm_get(p.i[-1]), &archp, "arch", 0);
+ printf("page arch ");
+ dump_lst(&archp);
+ }
+ pchk(dbm_get(*p.i++), &descp, "desc", 0);
+ printf("page desc # ");
+ dump_str(&descp);
+ printf("\npage file ");
+ pchk(dbm_get(*p.i++), &filep, "file", 0);
+ if (filep == NULL) {
+ printf("# (NULL)\n");
+ continue;
+ }
+ switch(*filep++) {
+ case 1:
+ printf("src ");
+ break;
+ case 2:
+ printf("cat ");
+ break;
+ default:
+ printf("UNKNOWN FORMAT %d ", filep[-1]);
+ break;
+ }
+ dump_lst(&filep);
+ }
+ printf("=== END OF PAGES ===\n");
+ pchk(name0, &p.c, "name0", 0);
+ pchk(sect0, &namep, "sect0", 0);
+ if (arch0 != NULL) {
+ pchk(arch0, &sectp, "arch0", 0);
+ pchk(desc0, &archp, "desc0", 0);
+ } else
+ pchk(desc0, &sectp, "desc0", 0);
+ pchk(file0, &descp, "file0", 0);
+ return filep;
+}
+
+static const char *
+dump_macros(union ptr p)
+{
+ union ptr macro0, macrop;
+ int32_t i, nmacros;
+
+ nmacros = be32toh(*p.i++);
+ printf("macros count %d\n", nmacros);
+ if (nmacros == 0)
+ return p.c;
+ macrop.i = macro0.i = dbm_get(*p.i);
+ printf("=== MACROS ===\n");
+ for (i = 0; i < nmacros; i++) {
+ pchk(dbm_get(*p.i++), &macrop.c, "macro", 0);
+ macrop.c = dump_macro(macrop, i);
+ }
+ printf("=== END OF MACROS ===\n");
+ pchk(macro0.c, &p.c, "macro0", 0);
+ return macrop.c;
+}
+
+static const char *
+dump_macro(union ptr p, int32_t im)
+{
+ union ptr page0, pagep;
+ const char *val0, *valp;
+ int32_t i, nentries;
+
+ nentries = be32toh(*p.i++);
+ printf("macro %02d entry count %d\n", im, nentries);
+ if (nentries == 0)
+ return p.c;
+ valp = val0 = dbm_get(p.i[0]);
+ pagep.i = page0.i = dbm_get(p.i[1]);
+ printf("=== MACRO %02d ===\n", im);
+ for (i = 0; i < nentries; i++) {
+ pchk(dbm_get(*p.i++), &valp, "value", 0);
+ printf("macro %02d # ", im);
+ dump_str(&valp);
+ pchk(dbm_get(*p.i++), &pagep.c, "pages", 0);
+ while (*pagep.i++ != 0)
+ printf("# %s ", (char *)dbm_get(
+ *(int32_t *)dbm_get(pagep.i[-1])) + 1);
+ printf("\n");
+ }
+ printf("=== END OF MACRO %02d ===\n", im);
+ pchk(val0, &p.c, "value0", 0);
+ pchk(page0.c, &valp, "page0", 3);
+ return pagep.c;
+}
+
+static void
+dump_str(const char **cp)
+{
+ if (*cp == NULL) {
+ printf("(NULL)");
+ return;
+ }
+ if ((unsigned char)**cp <= NAME_MASK) {
+ putchar('[');
+ if (**cp & NAME_FILE)
+ putchar('f');
+ if (**cp & NAME_HEAD)
+ putchar('h');
+ if (**cp & NAME_FIRST)
+ putchar('1');
+ if (**cp & NAME_TITLE)
+ putchar('t');
+ if (**cp & NAME_SYN)
+ putchar('s');
+ putchar(']');
+ (*cp)++;
+ }
+ while (**cp != '\0')
+ putchar(*(*cp)++);
+ putchar(' ');
+ (*cp)++;
+}
+
+static void
+dump_lst(const char **cp)
+{
+ if (*cp == NULL) {
+ printf("# (NULL)\n");
+ return;
+ }
+ while (**cp != '\0') {
+ printf("# ");
+ dump_str(cp);
+ }
+ (*cp)++;
+ printf("\n");
+}
+
+static void
+pchk(const char *want, const char **got, const char *name, int fuzz)
+{
+ if (want == NULL) {
+ warnx("%s wants (NULL), ignoring", name);
+ return;
+ }
+ if (*got == NULL)
+ warnx("%s jumps from (NULL) to 0x%x", name,
+ be32toh(dbm_addr(want)));
+ else if (*got > want || *got + fuzz < want)
+ warnx("%s jumps from 0x%x to 0x%x", name,
+ be32toh(dbm_addr(*got)), be32toh(dbm_addr(want)));
+ *got = want;
+}