diff options
| author | John Vogel <jvogel4@stny.rr.com> | 2024-07-07 11:04:55 -0400 |
|---|---|---|
| committer | John Vogel <jvogel4@stny.rr.com> | 2024-07-07 11:05:36 -0400 |
| commit | 02db4af5a25b782ced5d2c44321fb0e091763c52 (patch) | |
| tree | e4771bb295e974f589ef3271fe90cca4dc312968 /dbm_dump | |
| parent | 3338e5fdfae80928be8b9f5cc33aa4d526cad609 (diff) | |
| download | my-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/APKBUILD | 27 | ||||
| -rw-r--r-- | dbm_dump/dbm_dump.1 | 191 | ||||
| -rw-r--r-- | dbm_dump/dbm_dump.c | 252 |
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++), §p, "sect", 0); + printf("page sect "); + dump_lst(§p); + 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, §p, "arch0", 0); + pchk(desc0, &archp, "desc0", 0); + } else + pchk(desc0, §p, "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++), ¯op.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; +} |
