commit cae0536

xplshn  ·  2026-08-18 20:14:54 +0000 UTC
parent 25e5f43
working login, passwd, fdisk, ld, as, cc1, ip, ifconfig, b3sum

Signed-off-by: xplshn <anto@xplshn.com.ar>
367 files changed,  +15793, -9317
+14, -1
 1@@ -29,12 +29,25 @@ cmd/dev/config.h
 2 cmd/dev/cc/config.h
 3 cmd/dev/version.h
 4 
 5-# build system generated files
 6+# build system generated files (genconfig.sh and ninqu)
 7 scripts/mk/config.mk
 8 scripts/mk/config.kv
 9+scripts/mk/config.set
10+scripts/mk/features.h
11 scripts/mk/rules.mk
12+shared/libutil/nofork_list.h
13 deps.mk
14 
15+# compiler dependency files
16+*.d
17+
18+# python bytecode
19+__pycache__/
20+*.pyc
21+
22+# generated man pages
23+man/man*/
24+
25 # ninja backend generator output and state
26 build.ninja
27 .ninja_log
+1, -1
1@@ -52,7 +52,7 @@ $(NINQU): $(NINQU_SRC) cmd/dev/ninqu/ninqu.h scripts/mk/config.set $(NINQU_LIB_S
2 FORCE:
3 
4 # ninqu generates build.ninja if ninja/samu is available and execs that
5-# instead of running its own backend, but you can use make BACKEND=internal
6+# instead of running its own backend, but you can use make backend=internal
7 # to force the internal one to be used anyways
8 %: $(NINQU) FORCE
9 	$(NINQU) $(JOBS) $@
+31, -16
  1@@ -1,11 +1,11 @@
  2 # posix: POSIX 2024
  3 PRESET_FEATURES=all
  4 
  5-# subset  of: posix xsi net pseudo extra linux dev
  6-PRESET_UTILS="posix xsi net pseudo extra linux"
  7+# subset of: posix xsi net pseudo extra linux dev
  8+PRESET_UTILS="posix xsi net pseudo extra linux dev"
  9 
 10 # installation paths
 11-VERSION=2026-06-08T05-53-UTC-03
 12+VERSION=2026-08-09T03-56-UTC-03
 13 PREFIX=/usr/local
 14 MANPREFIX=/usr/local/share/man
 15 
 16@@ -13,12 +13,12 @@ MANPREFIX=/usr/local/share/man
 17 CC=cc
 18 CFLAGS="-std=c99 -Wall -Wextra -pedantic"
 19 LDFLAGS=""
 20-LDLIBS="-lcrypt -lresolv"
 21+LDLIBS=""
 22 AR=ar
 23 ARFLAGS="rc"
 24 RANLIB=ranlib
 25 
 26-# --- preset expansion: do not edit below ---
 27+# preset expansion: do not edit below
 28 
 29 case "$PRESET_FEATURES" in
 30 posix)
 31@@ -52,6 +52,11 @@ posix)
 32     FEATURE_DEPMOD_ALIAS=0;           FEATURE_DEPMOD_SYMBOLS=0
 33     FEATURE_TAR_TTY_SAFE=0;           FEATURE_TAR_NOFOLLOW=0
 34     FEATURE_READLINK_REALPATH=0;      FEATURE_UMOUNT_OPTIONS=0
 35+    FEATURE_LN_RELATIVE=0
 36+    FEATURE_LN_NO_TARGET_DIR=0
 37+    FEATURE_BC_QUIET=0
 38+    FEATURE_BC_MULTICHAR=0
 39+    FEATURE_BC_ESCAPES=0
 40     FEATURE_TAR_TO_STDOUT=0;          FEATURE_TAR_KEEP_OLD=0
 41     FEATURE_TAR_STRIP_COMPONENTS=0;   FEATURE_TAR_FILES_FROM=0
 42     FEATURE_TAR_EXCLUDE_FROM=0;       FEATURE_IP_ROUTE_ADD_DEL=0
 43@@ -87,6 +92,11 @@ common)
 44     FEATURE_DEPMOD_ALIAS=1;           FEATURE_DEPMOD_SYMBOLS=1
 45     FEATURE_TAR_TTY_SAFE=1;           FEATURE_TAR_NOFOLLOW=1
 46     FEATURE_READLINK_REALPATH=1;      FEATURE_UMOUNT_OPTIONS=1
 47+    FEATURE_LN_RELATIVE=1
 48+    FEATURE_LN_NO_TARGET_DIR=1
 49+    FEATURE_BC_QUIET=1
 50+    FEATURE_BC_MULTICHAR=1
 51+    FEATURE_BC_ESCAPES=1
 52     FEATURE_TAR_TO_STDOUT=1;          FEATURE_TAR_KEEP_OLD=1
 53     FEATURE_TAR_STRIP_COMPONENTS=1;   FEATURE_TAR_FILES_FROM=1
 54     FEATURE_TAR_EXCLUDE_FROM=1;       FEATURE_IP_ROUTE_ADD_DEL=1
 55@@ -124,6 +134,11 @@ all)
 56     FEATURE_DEPMOD_ALIAS=1;           FEATURE_DEPMOD_SYMBOLS=1
 57     FEATURE_TAR_TTY_SAFE=1;           FEATURE_TAR_NOFOLLOW=1
 58     FEATURE_READLINK_REALPATH=1;      FEATURE_UMOUNT_OPTIONS=1
 59+    FEATURE_LN_RELATIVE=1
 60+    FEATURE_LN_NO_TARGET_DIR=1
 61+    FEATURE_BC_QUIET=1
 62+    FEATURE_BC_MULTICHAR=1
 63+    FEATURE_BC_ESCAPES=1
 64     FEATURE_TAR_TO_STDOUT=1;          FEATURE_TAR_KEEP_OLD=1
 65     FEATURE_TAR_STRIP_COMPONENTS=1;   FEATURE_TAR_FILES_FROM=1
 66     FEATURE_TAR_EXCLUDE_FROM=1;       FEATURE_IP_ROUTE_ADD_DEL=1
 67@@ -154,37 +169,37 @@ for _p in $PRESET_UTILS; do
 68 done
 69 unset _p
 70 
 71-# --- per-item overrides (after preset expansion) ---
 72-# BUILD_POSIX_SH=0       # disable a tool when its group is active
 73-# BUILD_DEV_AS=1         # enable a tool whose group isnt in PRESET_UTILS
 74+# per-item overrides (after preset expansion)
 75+# BUILD_POSIX_SH=0 # disable a tool when its group is active
 76+# BUILD_DEV_AS=1 # enable a tool whose group isnt in PRESET_UTILS
 77 FEATURE_SH_HISTEDIT=1
 78 
 79 # FEATURE_NOEXEC: when set to 1, wexec/wpopen/wsystem can execute registered
 80 # tool mains directly inside the forked child process (skipping execve)
 81-# This is equivalent to Busybox noexec applet support
 82-# This applies to ALL commands contained within aruu-box, you may also
 83+# this is equivalent to busybox noexec applet support
 84+# this applies to ALL commands contained within aruu-box, you may also
 85 # specify if some specific command is not an attack vector to also be nofork
 86 # via enabling FEATURE_NOFORK=1 and specifying those commands in NOFORK_LIST
 87 #
 88-#FEATURE_NOEXEC=1
 89+# FEATURE_NOEXEC=1
 90 #
 91 # FEATURE_NOEXEC_OVERRIDE: only meaningful when FEATURE_NOEXEC=1
 92 # when set to 1, ARUU_NOEXEC=0 in the environment forces fork+exec at runtime
 93 #
 94-#FEATURE_NOEXEC_OVERRIDE=1
 95+# FEATURE_NOEXEC_OVERRIDE=1
 96 #
 97 # FEATURE_NOFORK: when set to 1, wexecvp/wexecv can run simple commands
 98 # (like cat, echo, pwd, test) directly in the current process without spawning
 99-# a subprocess (noexec+nofork). This is equivalent to Busybox nofork applet support
100+# a subprocess (noexec+nofork). this is equivalent to busybox nofork applet support
101 #
102-#FEATURE_NOFORK=1
103+# FEATURE_NOFORK=1
104 #
105 # FEATURE_NOFORK_OVERRIDE: only meaningful when FEATURE_NOFORK=1
106 # when set to 1, ARUU_NOFORK=0 in the environment forces fork for nofork commands
107 # even tho they will still not do execvp() call at runtime
108 # unless FEATURE_NOEXEC_OVERRIDE was enabled at build time and ARUU_NOEXEC=0
109 #
110-#FEATURE_NOFORK_OVERRIDE=1
111+# FEATURE_NOFORK_OVERRIDE=1
112 #
113 # NOFORK_LIST: list of builtins that can run without fork (noexec+nofork)
114 #
115@@ -246,5 +261,5 @@ CPPFLAGS_TLS=$(echo "$CPPFLAGS_TLS" | xargs)
116 LDFLAGS_TLS=$(echo "$LDFLAGS_TLS" | xargs)
117 LDLIBS_TLS=$(echo "$LDLIBS_TLS" | xargs)
118 
119-# Makes Ninqu try them in this order:
120+# makes ninqu try them in this order:
121 NINJA_TRY="${NINJA_TRY:-samu,ninja}"
+9, -9
 1@@ -270,14 +270,14 @@ expand_rule(const char *name)
 2     int            r_literal = rule_is_literal(r);
 3 
 4     /* run a codegen producer before globbing only when its own
 5-     * output feeds this rules glob, so a step like POSIX_BC_C
 6-     * (produces cmd/posix/bc.c) finishes before glob_all() looks
 7-     * for cmd/posix/bc.c. anything else in extra_deps (a library to
 8-     * link, a header some other rule includes) never needs to run
 9-     * here, expand_rule() on it just registers its instances so
10-     * the resolve_input_token() pass in finalize_inst() can wire up
11-     * dep_rule_names for backend scheduling. skipped in
12-     * summary mode since -S must not execute */
13+ * output feeds this rules glob, so a step like POSIX_BC_C
14+ * (produces cmd/posix/bc.c) finishes before glob_all() looks
15+ * for cmd/posix/bc.c. anything else in extra_deps (a library to
16+ * link, a header some other rule includes) never needs to run
17+ * here, expand_rule() on it just registers its instances so
18+ * the resolve_input_token() pass in finalize_inst() can wire up
19+ * dep_rule_names for backend scheduling. skipped in
20+ * summary mode since -S must not execute */
21     if (!summary_mode) {
22       for (j = 0; j < r->extra_deps.n; j++) {
23         char *tok = kv_expand(r->extra_deps.v[j]);
24@@ -368,7 +368,7 @@ expand_rule(const char *name)
25     struct KvStore ov;
26 
27     /* non-glob rules have no MATCH/DIR/BASE to expose, so the
28-     * overlay only carries IN/OUT for build_cmd */
29+ * overlay only carries IN/OUT for build_cmd */
30     setup_inst(inst, r);
31     memset(&ov, 0, sizeof ov);
32     local_overlay = &ov;
+1, -1
1@@ -116,7 +116,7 @@ gate_eval(struct Gate *g)
2   return 0;
3 }
4 
5-/* expand every $(...) so a gate like build_$(BASESTEM) resolves
6+/* expand every $(...) so a gate like build_$(basestem) resolves
7  * against the active overlay before evaluation */
8 struct Gate *
9 gate_materialize(struct Gate *g)
+1, -1
1@@ -120,7 +120,7 @@ main(int argc, char *argv[])
2     return failed_any ? 1 : 0;
3   }
4 
5-  /* BACKEND=internal forces executor. otherwise generate file and exec backend binary */
6+  /* backend=internal forces executor. otherwise generate file and exec backend binary */
7   if (strcmp(kv_get_or("BACKEND", "auto"), "internal") != 0) {
8     char                 *bin;
9     const struct Backend *be = backend_resolve(&bin);
+10, -10
 1@@ -52,11 +52,11 @@ fprint_shell_word_plain(FILE *f, const char *s)
 2  * so neither lets a real newline survive inside the value. POSIX
 3  * single quotes cannot help either, there is no escape processing
 4  * inside them, so a backslash-n written between quotes stays two
 5- * literal characters, not a newline, once the shell reads it back.
 6+ * literal characters, not a newline, once the shell reads it back
 7  *
 8  * the fix is to not carry the newline in quoted text at all: emit
 9  * a command substitution that runs the word through `printf '%b'`,
10- * whose %b directive is POSIX-specified to expand backslash escapes
11+ * whose %b directive is posix-specified to expand backslash escapes
12  * (including \n) in its argument at runtime. the argument to printf
13  * is itself single-quoted using the same rules as the plain case,
14  * plus doubling any backslash so it survives as data rather than
15@@ -82,9 +82,9 @@ fprint_shell_word(FILE *f, const char *s)
16   }
17 
18   /* wrapped in double quotes so the shell treats the substitutions
19-   * result as one word instead of splitting it on whitespace, which
20-   * is exactly what an unquoted $(...) would do to a multi-line
21-   * result */
22+ * result as one word instead of splitting it on whitespace, which
23+ * is exactly what an unquoted $(...) would do to a multi-line
24+ * result */
25   fputs("\"$$(printf '%b' '", f);
26   for (; *s; s++) {
27     if (*s == '\'')
28@@ -220,17 +220,17 @@ emit_command(FILE *f, struct Inst *inst)
29  * inst_stale() never consults dep_inst for staleness either, only
30  * (in)/(stale_extra), so mirroring that as a plain (not order-only)
31  * prerequisite list is what makes ninjas own mtime check agree
32- * with ninqus.
33+ * with ninqus
34  *
35  * ninja only knows build outputs, never ninqus rule/group/meta
36- * names, so `ninja LIBUTIL` (what the Makefile forwards $@ as) has
37+ * names, so `ninja LIBUTIL` (what the makefile forwards $@ as) has
38  * nothing to resolve against on its own. wanted carries the literal
39  * command-line words ninqu itself was invoked with, one phony alias
40  * per word makes that name buildable too. when more than one target
41  * was requested in the same invocation every alias points at the
42  * whole combined closure rather than just its own slice, since
43  * insts[] no longer remembers which instance came from which wanted
44- * name, thats fine for the Makefiles own use (always one target
45+ * name, thats fine for the makefiles own use (always one target
46  * per invocation), just slightly conservative for a multi-target
47  * `ninqu -G ninja a b` run */
48 void
49@@ -292,8 +292,8 @@ emit_ninja(const char *path, struct StrList *wanted)
50         char         depbuf[1024];
51         const char  *depout = inst_target(dep, inst->dep_inst[k], depbuf, sizeof depbuf);
52         /* a rule ref that is also a real (dep ...) input already
53-         * forces both order and staleness, listing it again as
54-         * order-only is pure noise */
55+ * forces both order and staleness, listing it again as
56+ * order-only is pure noise */
57         if (sl_has(&inst->in, depout) || sl_has(&inst->stale_extra, depout))
58           continue;
59         if (!printed_bar) {
+1, -1
1@@ -95,7 +95,7 @@ void          lex_swallow_dollar(struct SLex *lx, char *buf, size_t *blen, size_
2 void          lex_string(struct SLex *lx, char *buf, size_t bsz);
3 const char   *find_dollar_close(const char *inner);
4 
5-/* gate: (not X) | (and X...) | (or X...) | bare var */
6+/* gate: (not x) | (and x...) | (or x...) | bare var */
7 enum GKind { G_TRUE, G_VAR, G_NOT, G_AND, G_OR };
8 
9 struct Gate {
+9, -9
 1@@ -27,7 +27,7 @@ sole_atom(struct SNode *node, const char *msg)
 2 }
 3 
 4 /* a dep operand is a bare atom, a (rule NAME) stored as @NAME, or
 5- * an (after X...) whose operands are order-only */
 6+ * an (after x...) whose operands are order-only */
 7 static void
 8 parse_dep_item(struct SNode *item, struct StrList *hard, struct StrList *ord, int allow_after)
 9 {
10@@ -158,10 +158,10 @@ process_rule_body(struct Rule *r, const char *name, struct SNode *form, int star
11     apply_rule_clause(r, name, form->kids[i]);
12 }
13 
14-/* (if EXPR clause...) splices its clauses in when EXPR is true.
15- * reuses the gate grammar so there is one condition language.
16+/* (if EXPR clause...) splices its clauses in when EXPR is true
17+ * reuses the gate grammar so there is one condition language
18  * a $(...) in the condition is rejected: splicing per glob match
19- * would mean deferring cmd/dep construction, which no rule needs.
20+ * would mean deferring cmd/dep construction, which no rule needs
21  * use (gate ...) on a separate rule for a per-instance condition */
22 static void
23 apply_if_clause(struct Rule *r, const char *name, struct SNode *clause)
24@@ -247,13 +247,13 @@ apply_rule_clause(struct Rule *r, const char *name, struct SNode *clause)
25     );
26   } else if (strcmp(h, "group") == 0) {
27     /* display-only: shows up in (query rules) output, no effect on
28-     * resolution. (member ...) below is the enforcing one. the two
29-     * are separate because several rules used (group ...) this way
30-     * before namespacing existed */
31+ * resolution. (member ...) below is the enforcing one. the two
32+ * are separate because several rules used (group ...) this way
33+ * before namespacing existed */
34     strlcpy(r->group_name, sole_atom(clause, "(group NAME) takes one name"), sizeof r->group_name);
35   } else if (strcmp(h, "member") == 0) {
36     /* (member GROUP [ALIAS]) hides the bare name from the command
37-     * line. ALIAS defaults to the rule own name */
38+ * line. ALIAS defaults to the rule own name */
39     if (clause->nkids < 2 || clause->nkids > 3 || clause->kids[1]->kind != S_ATOM)
40       eprintf("manifest: rule %s: (member GROUP [ALIAS]) needs a group name\n", name);
41     strlcpy(r->member_of, clause->kids[1]->atom, sizeof r->member_of);
42@@ -384,7 +384,7 @@ parse_set(struct SNode *form)
43   kv_set_manifest(form->kids[1]->atom, form->kids[2]->atom);
44 }
45 
46-/* (list) and (append) keep a space-joined string in the kv store.
47+/* (list) and (append) keep a space-joined string in the kv store
48  * a $(NAME) alone in a command splits back into argv entries */
49 static void
50 parse_list_or_append(struct SNode *form, int append)
+4, -4
 1@@ -101,8 +101,8 @@ resolve_member_path(const char *w)
 2   return r;
 3 }
 4 
 5-/* META.TARGET applies META overrides then resolves TARGET.
 6- * META alone applies META then falls back to (group default).
 7+/* META.TARGET applies META overrides then resolves TARGET
 8+ * META alone applies META then falls back to (group default)
 9  * anything else is a plain group or rule name */
10 void
11 resolve_wanted(const char *w)
12@@ -140,8 +140,8 @@ resolve_wanted(const char *w)
13   }
14 
15   /* a rule that declared (member ...) does not resolve by bare name
16-   * from the command line, only through GROUP/ALIAS or transitively
17-   * via its owning group ref list */
18+ * from the command line, only through GROUP/ALIAS or transitively
19+ * via its owning group ref list */
20   {
21     struct Rule *br = rule_find(w);
22     if (br && br->member_of[0])
+7, -4564
   1@@ -1,4557 +1,12 @@
   2-/* See LICENSE file for copyright and license details. */
   3-
   4-#if defined(__x86_64__) && (defined(__clang__) || (defined(__GNUC__) && !defined(__TINYC__)))
   5-#define BLAKE3_X86_SIMD 1
   6-#else
   7-#define BLAKE3_X86_SIMD 0
   8-#endif
   9-
  10-#include "arg.h"
  11-#include "util.h"
  12-
  13-#include <assert.h>
  14-#if BLAKE3_X86_SIMD
  15-#include <immintrin.h>
  16-#endif
  17-#include <stdint.h>
  18-#include <stdio.h>
  19-#include <stdlib.h>
  20-#include <string.h>
  21-
  22-#define BLAKE3_VERSION_STRING "1.5.0"
  23-#define BLAKE3_KEY_LEN        32
  24-#define BLAKE3_OUT_LEN        32
  25-#define BLAKE3_BLOCK_LEN      64
  26-#define BLAKE3_CHUNK_LEN      1024
  27-#define BLAKE3_MAX_DEPTH      54
  28-
  29-#if BLAKE3_X86_SIMD
  30-#define MAX_SIMD_DEGREE 16
  31-#else
  32-#define MAX_SIMD_DEGREE 1
  33-#endif
  34-
  35-#define MAX_SIMD_DEGREE_OR_2 (MAX_SIMD_DEGREE > 2 ? MAX_SIMD_DEGREE : 2)
  36-
  37-enum Blake3Flags {
  38-  CHUNK_START         = 1 << 0,
  39-  CHUNK_END           = 1 << 1,
  40-  PARENT              = 1 << 2,
  41-  ROOT                = 1 << 3,
  42-  KEYED_HASH          = 1 << 4,
  43-  DERIVE_KEY_CONTEXT  = 1 << 5,
  44-  DERIVE_KEY_MATERIAL = 1 << 6
  45-};
  46-
  47-struct Blake3ChunkState {
  48-  uint32_t cv[8];
  49-  uint64_t chunk_counter;
  50-  uint8_t  buf[BLAKE3_BLOCK_LEN];
  51-  uint8_t  buf_len;
  52-  uint8_t  blocks_compressed;
  53-  uint8_t  flags;
  54-};
  55-
  56-struct Blake3Hasher {
  57-  uint32_t                key[8];
  58-  struct Blake3ChunkState chunk;
  59-  uint8_t                 cv_stack_len;
  60-  uint8_t                 cv_stack[(BLAKE3_MAX_DEPTH + 1) * BLAKE3_OUT_LEN];
  61-};
  62-
  63-void blake3_hasher_update(struct Blake3Hasher *self, const void *input, size_t input_len);
  64-void blake3_hasher_finalize(const struct Blake3Hasher *self, uint8_t *out, size_t out_len);
  65-
  66-struct Output {
  67-  uint32_t input_cv[8];
  68-  uint64_t counter;
  69-  uint8_t  block[BLAKE3_BLOCK_LEN];
  70-  uint8_t  block_len;
  71-  uint8_t  flags;
  72-};
  73-
  74-static const uint32_t IV[8] = {
  75-    0x6A09E667UL,
  76-    0xBB67AE85UL,
  77-    0x3C6EF372UL,
  78-    0xA54FF53AUL,
  79-    0x510E527FUL,
  80-    0x9B05688CUL,
  81-    0x1F83D9ABUL,
  82-    0x5BE0CD19UL
  83-};
  84-
  85-static const uint8_t MSG_SCHEDULE[7][16] = {
  86-    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
  87-    {2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8},
  88-    {3, 4, 10, 12, 13, 2, 7, 14, 6, 5, 9, 0, 11, 15, 8, 1},
  89-    {10, 7, 12, 9, 14, 3, 13, 15, 4, 0, 11, 2, 5, 8, 1, 6},
  90-    {12, 13, 9, 11, 15, 10, 14, 8, 7, 2, 5, 3, 0, 1, 6, 4},
  91-    {9, 14, 11, 5, 8, 12, 15, 1, 13, 3, 0, 10, 2, 6, 4, 7},
  92-    {11, 15, 5, 0, 1, 9, 8, 6, 14, 10, 2, 12, 3, 4, 7, 13},
  93-};
  94-
  95-static inline uint32_t
  96-load32(const void *src)
  97-{
  98-  const uint8_t *p = (const uint8_t *)src;
  99-
 100-  return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) | ((uint32_t)(p[2]) << 16)
 101-         | ((uint32_t)(p[3]) << 24);
 102-}
 103-
 104-static inline void
 105-store32(void *dst, uint32_t w)
 106-{
 107-  uint8_t *p = (uint8_t *)dst;
 108-
 109-  p[0] = (uint8_t)(w >> 0);
 110-  p[1] = (uint8_t)(w >> 8);
 111-  p[2] = (uint8_t)(w >> 16);
 112-  p[3] = (uint8_t)(w >> 24);
 113-}
 114-
 115-static inline void
 116-store_cv_words(uint8_t bytes_out[32], uint32_t cv_words[8])
 117-{
 118-  store32(&bytes_out[0 * 4], cv_words[0]);
 119-  store32(&bytes_out[1 * 4], cv_words[1]);
 120-  store32(&bytes_out[2 * 4], cv_words[2]);
 121-  store32(&bytes_out[3 * 4], cv_words[3]);
 122-  store32(&bytes_out[4 * 4], cv_words[4]);
 123-  store32(&bytes_out[5 * 4], cv_words[5]);
 124-  store32(&bytes_out[6 * 4], cv_words[6]);
 125-  store32(&bytes_out[7 * 4], cv_words[7]);
 126-}
 127-
 128-static inline uint32_t
 129-counter_low(uint64_t counter)
 130-{
 131-  return (uint32_t)counter;
 132-}
 133-
 134-static inline uint32_t
 135-counter_high(uint64_t counter)
 136-{
 137-  return (uint32_t)(counter >> 32);
 138-}
 139-
 140-/* forward declarations */
 141-#if BLAKE3_X86_SIMD
 142-void blake3_compress_in_place_sse2(
 143-    uint32_t      cv[8],
 144-    const uint8_t block[BLAKE3_BLOCK_LEN],
 145-    uint8_t       block_len,
 146-    uint64_t      counter,
 147-    uint8_t       flags
 148-);
 149-void blake3_compress_xof_sse2(
 150-    const uint32_t cv[8],
 151-    const uint8_t  block[BLAKE3_BLOCK_LEN],
 152-    uint8_t        block_len,
 153-    uint64_t       counter,
 154-    uint8_t        flags,
 155-    uint8_t        out[64]
 156-);
 157-void blake3_hash_many_sse2(
 158-    const uint8_t *const *inputs,
 159-    size_t                num_inputs,
 160-    size_t                blocks,
 161-    const uint32_t        key[8],
 162-    uint64_t              counter,
 163-    int                   increment_counter,
 164-    uint8_t               flags,
 165-    uint8_t               flags_start,
 166-    uint8_t               flags_end,
 167-    uint8_t              *out
 168-);
 169-
 170-void blake3_compress_in_place_sse41(
 171-    uint32_t      cv[8],
 172-    const uint8_t block[BLAKE3_BLOCK_LEN],
 173-    uint8_t       block_len,
 174-    uint64_t      counter,
 175-    uint8_t       flags
 176-);
 177-void blake3_compress_xof_sse41(
 178-    const uint32_t cv[8],
 179-    const uint8_t  block[BLAKE3_BLOCK_LEN],
 180-    uint8_t        block_len,
 181-    uint64_t       counter,
 182-    uint8_t        flags,
 183-    uint8_t        out[64]
 184-);
 185-void blake3_hash_many_sse41(
 186-    const uint8_t *const *inputs,
 187-    size_t                num_inputs,
 188-    size_t                blocks,
 189-    const uint32_t        key[8],
 190-    uint64_t              counter,
 191-    int                   increment_counter,
 192-    uint8_t               flags,
 193-    uint8_t               flags_start,
 194-    uint8_t               flags_end,
 195-    uint8_t              *out
 196-);
 197-
 198-void blake3_hash_many_avx2(
 199-    const uint8_t *const *inputs,
 200-    size_t                num_inputs,
 201-    size_t                blocks,
 202-    const uint32_t        key[8],
 203-    uint64_t              counter,
 204-    int                   increment_counter,
 205-    uint8_t               flags,
 206-    uint8_t               flags_start,
 207-    uint8_t               flags_end,
 208-    uint8_t              *out
 209-);
 210-
 211-void blake3_compress_in_place_avx512(
 212-    uint32_t      cv[8],
 213-    const uint8_t block[BLAKE3_BLOCK_LEN],
 214-    uint8_t       block_len,
 215-    uint64_t      counter,
 216-    uint8_t       flags
 217-);
 218-void blake3_compress_xof_avx512(
 219-    const uint32_t cv[8],
 220-    const uint8_t  block[BLAKE3_BLOCK_LEN],
 221-    uint8_t        block_len,
 222-    uint64_t       counter,
 223-    uint8_t        flags,
 224-    uint8_t        out[64]
 225-);
 226-void blake3_hash_many_avx512(
 227-    const uint8_t *const *inputs,
 228-    size_t                num_inputs,
 229-    size_t                blocks,
 230-    const uint32_t        key[8],
 231-    uint64_t              counter,
 232-    int                   increment_counter,
 233-    uint8_t               flags,
 234-    uint8_t               flags_start,
 235-    uint8_t               flags_end,
 236-    uint8_t              *out
 237-);
 238-#endif
 239-
 240-void blake3_compress_in_place_portable(
 241-    uint32_t      cv[8],
 242-    const uint8_t block[BLAKE3_BLOCK_LEN],
 243-    uint8_t       block_len,
 244-    uint64_t      counter,
 245-    uint8_t       flags
 246-);
 247-void blake3_compress_xof_portable(
 248-    const uint32_t cv[8],
 249-    const uint8_t  block[BLAKE3_BLOCK_LEN],
 250-    uint8_t        block_len,
 251-    uint64_t       counter,
 252-    uint8_t        flags,
 253-    uint8_t        out[64]
 254-);
 255-void blake3_hash_many_portable(
 256-    const uint8_t *const *inputs,
 257-    size_t                num_inputs,
 258-    size_t                blocks,
 259-    const uint32_t        key[8],
 260-    uint64_t              counter,
 261-    int                   increment_counter,
 262-    uint8_t               flags,
 263-    uint8_t               flags_start,
 264-    uint8_t               flags_end,
 265-    uint8_t              *out
 266-);
 267-
 268-void blake3_compress_in_place(
 269-    uint32_t      cv[8],
 270-    const uint8_t block[BLAKE3_BLOCK_LEN],
 271-    uint8_t       block_len,
 272-    uint64_t      counter,
 273-    uint8_t       flags
 274-);
 275-void blake3_compress_xof(
 276-    const uint32_t cv[8],
 277-    const uint8_t  block[BLAKE3_BLOCK_LEN],
 278-    uint8_t        block_len,
 279-    uint64_t       counter,
 280-    uint8_t        flags,
 281-    uint8_t        out[64]
 282-);
 283-void blake3_hash_many(
 284-    const uint8_t *const *inputs,
 285-    size_t                num_inputs,
 286-    size_t                blocks,
 287-    const uint32_t        key[8],
 288-    uint64_t              counter,
 289-    int                   increment_counter,
 290-    uint8_t               flags,
 291-    uint8_t               flags_start,
 292-    uint8_t               flags_end,
 293-    uint8_t              *out
 294-);
 295-
 296-/* portable implementations */
 297-static inline uint32_t
 298-rotr32(uint32_t w, uint32_t c)
 299-{
 300-  return (w >> c) | (w << (32 - c));
 301-}
 302-
 303-static inline void
 304-g_portable(uint32_t *state, size_t a, size_t b, size_t c, size_t d, uint32_t x, uint32_t y)
 305-{
 306-  state[a] = state[a] + state[b] + x;
 307-  state[d] = rotr32(state[d] ^ state[a], 16);
 308-  state[c] = state[c] + state[d];
 309-  state[b] = rotr32(state[b] ^ state[c], 12);
 310-  state[a] = state[a] + state[b] + y;
 311-  state[d] = rotr32(state[d] ^ state[a], 8);
 312-  state[c] = state[c] + state[d];
 313-  state[b] = rotr32(state[b] ^ state[c], 7);
 314-}
 315-
 316-static inline void
 317-round_fn_portable(uint32_t state[16], const uint32_t *msg, size_t round)
 318-{
 319-  const uint8_t *schedule = MSG_SCHEDULE[round];
 320-
 321-  g_portable(state, 0, 4, 8, 12, msg[schedule[0]], msg[schedule[1]]);
 322-  g_portable(state, 1, 5, 9, 13, msg[schedule[2]], msg[schedule[3]]);
 323-  g_portable(state, 2, 6, 10, 14, msg[schedule[4]], msg[schedule[5]]);
 324-  g_portable(state, 3, 7, 11, 15, msg[schedule[6]], msg[schedule[7]]);
 325-
 326-  g_portable(state, 0, 5, 10, 15, msg[schedule[8]], msg[schedule[9]]);
 327-  g_portable(state, 1, 6, 11, 12, msg[schedule[10]], msg[schedule[11]]);
 328-  g_portable(state, 2, 7, 8, 13, msg[schedule[12]], msg[schedule[13]]);
 329-  g_portable(state, 3, 4, 9, 14, msg[schedule[14]], msg[schedule[15]]);
 330-}
 331-
 332-static inline void
 333-compress_pre_portable(
 334-    uint32_t       state[16],
 335-    const uint32_t cv[8],
 336-    const uint8_t  block[BLAKE3_BLOCK_LEN],
 337-    uint8_t        block_len,
 338-    uint64_t       counter,
 339-    uint8_t        flags
 340-)
 341-{
 342-  uint32_t block_words[16];
 343-
 344-  block_words[0]  = load32(block + 4 * 0);
 345-  block_words[1]  = load32(block + 4 * 1);
 346-  block_words[2]  = load32(block + 4 * 2);
 347-  block_words[3]  = load32(block + 4 * 3);
 348-  block_words[4]  = load32(block + 4 * 4);
 349-  block_words[5]  = load32(block + 4 * 5);
 350-  block_words[6]  = load32(block + 4 * 6);
 351-  block_words[7]  = load32(block + 4 * 7);
 352-  block_words[8]  = load32(block + 4 * 8);
 353-  block_words[9]  = load32(block + 4 * 9);
 354-  block_words[10] = load32(block + 4 * 10);
 355-  block_words[11] = load32(block + 4 * 11);
 356-  block_words[12] = load32(block + 4 * 12);
 357-  block_words[13] = load32(block + 4 * 13);
 358-  block_words[14] = load32(block + 4 * 14);
 359-  block_words[15] = load32(block + 4 * 15);
 360-
 361-  state[0]  = cv[0];
 362-  state[1]  = cv[1];
 363-  state[2]  = cv[2];
 364-  state[3]  = cv[3];
 365-  state[4]  = cv[4];
 366-  state[5]  = cv[5];
 367-  state[6]  = cv[6];
 368-  state[7]  = cv[7];
 369-  state[8]  = IV[0];
 370-  state[9]  = IV[1];
 371-  state[10] = IV[2];
 372-  state[11] = IV[3];
 373-  state[12] = counter_low(counter);
 374-  state[13] = counter_high(counter);
 375-  state[14] = (uint32_t)block_len;
 376-  state[15] = (uint32_t)flags;
 377-
 378-  round_fn_portable(state, &block_words[0], 0);
 379-  round_fn_portable(state, &block_words[0], 1);
 380-  round_fn_portable(state, &block_words[0], 2);
 381-  round_fn_portable(state, &block_words[0], 3);
 382-  round_fn_portable(state, &block_words[0], 4);
 383-  round_fn_portable(state, &block_words[0], 5);
 384-  round_fn_portable(state, &block_words[0], 6);
 385-}
 386-
 387-void
 388-blake3_compress_in_place_portable(
 389-    uint32_t      cv[8],
 390-    const uint8_t block[BLAKE3_BLOCK_LEN],
 391-    uint8_t       block_len,
 392-    uint64_t      counter,
 393-    uint8_t       flags
 394-)
 395-{
 396-  uint32_t state[16];
 397-
 398-  compress_pre_portable(state, cv, block, block_len, counter, flags);
 399-  cv[0] = state[0] ^ state[8];
 400-  cv[1] = state[1] ^ state[9];
 401-  cv[2] = state[2] ^ state[10];
 402-  cv[3] = state[3] ^ state[11];
 403-  cv[4] = state[4] ^ state[12];
 404-  cv[5] = state[5] ^ state[13];
 405-  cv[6] = state[6] ^ state[14];
 406-  cv[7] = state[7] ^ state[15];
 407-}
 408-
 409-void
 410-blake3_compress_xof_portable(
 411-    const uint32_t cv[8],
 412-    const uint8_t  block[BLAKE3_BLOCK_LEN],
 413-    uint8_t        block_len,
 414-    uint64_t       counter,
 415-    uint8_t        flags,
 416-    uint8_t        out[64]
 417-)
 418-{
 419-  uint32_t state[16];
 420-
 421-  compress_pre_portable(state, cv, block, block_len, counter, flags);
 422-
 423-  store32(&out[0 * 4], state[0] ^ state[8]);
 424-  store32(&out[1 * 4], state[1] ^ state[9]);
 425-  store32(&out[2 * 4], state[2] ^ state[10]);
 426-  store32(&out[3 * 4], state[3] ^ state[11]);
 427-  store32(&out[4 * 4], state[4] ^ state[12]);
 428-  store32(&out[5 * 4], state[5] ^ state[13]);
 429-  store32(&out[6 * 4], state[6] ^ state[14]);
 430-  store32(&out[7 * 4], state[7] ^ state[15]);
 431-  store32(&out[8 * 4], state[8] ^ cv[0]);
 432-  store32(&out[9 * 4], state[9] ^ cv[1]);
 433-  store32(&out[10 * 4], state[10] ^ cv[2]);
 434-  store32(&out[11 * 4], state[11] ^ cv[3]);
 435-  store32(&out[12 * 4], state[12] ^ cv[4]);
 436-  store32(&out[13 * 4], state[13] ^ cv[5]);
 437-  store32(&out[14 * 4], state[14] ^ cv[6]);
 438-  store32(&out[15 * 4], state[15] ^ cv[7]);
 439-}
 440-
 441-static inline void
 442-hash_one_portable(
 443-    const uint8_t *input,
 444-    size_t         blocks,
 445-    const uint32_t key[8],
 446-    uint64_t       counter,
 447-    uint8_t        flags,
 448-    uint8_t        flags_start,
 449-    uint8_t        flags_end,
 450-    uint8_t        out[BLAKE3_OUT_LEN]
 451-)
 452-{
 453-  uint32_t cv[8];
 454-  uint8_t  block_flags;
 455-
 456-  memcpy(cv, key, BLAKE3_KEY_LEN);
 457-  block_flags = flags | flags_start;
 458-  while (blocks > 0) {
 459-    if (blocks == 1) {
 460-      block_flags |= flags_end;
 461-    }
 462-    blake3_compress_in_place_portable(cv, input, BLAKE3_BLOCK_LEN, counter, block_flags);
 463-    input = &input[BLAKE3_BLOCK_LEN];
 464-    blocks -= 1;
 465-    block_flags = flags;
 466-  }
 467-  store_cv_words(out, cv);
 468-}
 469-
 470-void
 471-blake3_hash_many_portable(
 472-    const uint8_t *const *inputs,
 473-    size_t                num_inputs,
 474-    size_t                blocks,
 475-    const uint32_t        key[8],
 476-    uint64_t              counter,
 477-    int                   increment_counter,
 478-    uint8_t               flags,
 479-    uint8_t               flags_start,
 480-    uint8_t               flags_end,
 481-    uint8_t              *out
 482-)
 483-{
 484-  while (num_inputs > 0) {
 485-    hash_one_portable(inputs[0], blocks, key, counter, flags, flags_start, flags_end, out);
 486-    if (increment_counter) {
 487-      counter += 1;
 488-    }
 489-    inputs += 1;
 490-    num_inputs -= 1;
 491-    out = &out[BLAKE3_OUT_LEN];
 492-  }
 493-}
 494-
 495-/* cpu features detection */
 496-enum { SSE2 = 1 << 0, SSE41 = 1 << 1, AVX2 = 1 << 2, AVX512 = 1 << 3 };
 497-
 498-static int blake3_cpu_features = 0;
 499-static int blake3_cpu_detected = 0;
 500-
 501-#if BLAKE3_X86_SIMD
 502-#include <cpuid.h>
 503-
 504-static void
 505-blake3_cpuid(uint32_t out[4], uint32_t id, uint32_t sid)
 506-{
 507-  __cpuid_count(id, sid, out[0], out[1], out[2], out[3]);
 508-}
 509-
 510-static uint64_t
 511-blake3_xgetbv(void)
 512-{
 513-  uint32_t eax, edx;
 514-
 515-  __asm__ volatile("xgetbv" : "=a"(eax), "=d"(edx) : "c"(0));
 516-  return ((uint64_t)edx << 32) | eax;
 517-}
 518-#endif
 519-
 520-static void
 521-blake3_detect_cpu_features(void)
 522-{
 523-#if BLAKE3_X86_SIMD
 524-  enum { EAX, EBX, ECX, EDX };
 525-  uint32_t regs[4];
 526-  uint64_t xcr0;
 527-  int      features = 0;
 528-
 529-  blake3_cpuid(regs, 1, 0);
 530-  if (regs[EDX] & (1UL << 26))
 531-    features |= SSE2;
 532-  if (regs[ECX] & (1UL << 19))
 533-    features |= SSE41;
 534-  /* osxsave */
 535-  if (regs[ECX] & (1UL << 27)) {
 536-    blake3_cpuid(regs, 0, 0);
 537-    if (regs[EAX] >= 7) {
 538-      blake3_cpuid(regs, 7, 0);
 539-      xcr0 = blake3_xgetbv();
 540-      /* avx2 and xcr0 sse, avx */
 541-      if ((regs[EBX] & (1UL << 5)) && (xcr0 & 0x06) == 0x06)
 542-        features |= AVX2;
 543-      /* avx512f, avx512vl and xcr0 opmask, zmm_hi256,
 544-       * hi16_zmm */
 545-      if ((regs[EBX] & (1UL << 31 | 1UL << 16)) && (xcr0 & 0xe0) == 0xe0)
 546-        features |= AVX512;
 547-    }
 548-  }
 549-  blake3_cpu_features = features;
 550-#endif
 551-  blake3_cpu_detected = 1;
 552-}
 553-
 554-#if BLAKE3_X86_SIMD
 555-__attribute__((constructor)) static void
 556-blake3_init_cpu(void)
 557-{
 558-  if (!blake3_cpu_detected)
 559-    blake3_detect_cpu_features();
 560-}
 561-#endif
 562-
 563-#if BLAKE3_X86_SIMD
 564-#if defined(__clang__)
 565-#pragma clang attribute push(__attribute__((target("sse2"))), apply_to = function)
 566-#elif defined(__GNUC__)
 567-#pragma GCC push_options
 568-#pragma GCC target("sse2")
 569-#endif
 570-#define DEGREE_SSE2 4
 571-
 572-#define _mm_shuffle_ps2(a, b, c)                                                                   \
 573-  (_mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), (c))))
 574-
 575-static inline __m128i
 576-loadu_sse2(const uint8_t src[16])
 577-{
 578-  return _mm_loadu_si128((const __m128i *)src);
 579-}
 580-
 581-static inline void
 582-storeu_sse2(__m128i src, uint8_t dest[16])
 583-{
 584-  _mm_storeu_si128((__m128i *)dest, src);
 585-}
 586-
 587-static inline __m128i
 588-addv_sse2(__m128i a, __m128i b)
 589-{
 590-  return _mm_add_epi32(a, b);
 591-}
 592-
 593-static inline __m128i
 594-xorv_sse2(__m128i a, __m128i b)
 595-{
 596-  return _mm_xor_si128(a, b);
 597-}
 598-
 599-static inline __m128i
 600-set1_sse2(uint32_t x)
 601-{
 602-  return _mm_set1_epi32((int32_t)x);
 603-}
 604-
 605-static inline __m128i
 606-set4_sse2(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
 607-{
 608-  return _mm_setr_epi32((int32_t)a, (int32_t)b, (int32_t)c, (int32_t)d);
 609-}
 610-
 611-static inline __m128i
 612-rot16_sse2(__m128i x)
 613-{
 614-  return _mm_shufflehi_epi16(_mm_shufflelo_epi16(x, 0xB1), 0xB1);
 615-}
 616-
 617-static inline __m128i
 618-rot12_sse2(__m128i x)
 619-{
 620-  return xorv_sse2(_mm_srli_epi32(x, 12), _mm_slli_epi32(x, 32 - 12));
 621-}
 622-
 623-static inline __m128i
 624-rot8_sse2(__m128i x)
 625-{
 626-  return xorv_sse2(_mm_srli_epi32(x, 8), _mm_slli_epi32(x, 32 - 8));
 627-}
 628-
 629-static inline __m128i
 630-rot7_sse2(__m128i x)
 631-{
 632-  return xorv_sse2(_mm_srli_epi32(x, 7), _mm_slli_epi32(x, 32 - 7));
 633-}
 634-
 635-static inline void
 636-g1_sse2(__m128i *row0, __m128i *row1, __m128i *row2, __m128i *row3, __m128i m)
 637-{
 638-  *row0 = addv_sse2(addv_sse2(*row0, m), *row1);
 639-  *row3 = xorv_sse2(*row3, *row0);
 640-  *row3 = rot16_sse2(*row3);
 641-  *row2 = addv_sse2(*row2, *row3);
 642-  *row1 = xorv_sse2(*row1, *row2);
 643-  *row1 = rot12_sse2(*row1);
 644-}
 645-
 646-static inline void
 647-g2_sse2(__m128i *row0, __m128i *row1, __m128i *row2, __m128i *row3, __m128i m)
 648-{
 649-  *row0 = addv_sse2(addv_sse2(*row0, m), *row1);
 650-  *row3 = xorv_sse2(*row3, *row0);
 651-  *row3 = rot8_sse2(*row3);
 652-  *row2 = addv_sse2(*row2, *row3);
 653-  *row1 = xorv_sse2(*row1, *row2);
 654-  *row1 = rot7_sse2(*row1);
 655-}
 656-
 657-static inline void
 658-diagonalize_sse2(__m128i *row0, __m128i *row2, __m128i *row3)
 659-{
 660-  *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE(2, 1, 0, 3));
 661-  *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE(1, 0, 3, 2));
 662-  *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE(0, 3, 2, 1));
 663-}
 664-
 665-static inline void
 666-undiagonalize_sse2(__m128i *row0, __m128i *row2, __m128i *row3)
 667-{
 668-  *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE(0, 3, 2, 1));
 669-  *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE(1, 0, 3, 2));
 670-  *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE(2, 1, 0, 3));
 671-}
 672-
 673-static inline __m128i
 674-blend_epi16_sse2(__m128i a, __m128i b, const int16_t imm8)
 675-{
 676-  const __m128i bits = _mm_set_epi16(0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01);
 677-  __m128i       mask = _mm_set1_epi16(imm8);
 678-
 679-  mask = _mm_and_si128(mask, bits);
 680-  mask = _mm_cmpeq_epi16(mask, bits);
 681-  return _mm_or_si128(_mm_and_si128(mask, b), _mm_andnot_si128(mask, a));
 682-}
 683-
 684-static inline void
 685-compress_pre_sse2(
 686-    __m128i        rows[4],
 687-    const uint32_t cv[8],
 688-    const uint8_t  block[BLAKE3_BLOCK_LEN],
 689-    uint8_t        block_len,
 690-    uint64_t       counter,
 691-    uint8_t        flags
 692-)
 693-{
 694-  __m128i m0, m1, m2, m3;
 695-  __m128i t0, t1, t2, t3, tt;
 696-
 697-  rows[0] = loadu_sse2((uint8_t *)&cv[0]);
 698-  rows[1] = loadu_sse2((uint8_t *)&cv[4]);
 699-  rows[2] = set4_sse2(IV[0], IV[1], IV[2], IV[3]);
 700-  rows[3] =
 701-      set4_sse2(counter_low(counter), counter_high(counter), (uint32_t)block_len, (uint32_t)flags);
 702-
 703-  m0 = loadu_sse2(&block[sizeof(__m128i) * 0]);
 704-  m1 = loadu_sse2(&block[sizeof(__m128i) * 1]);
 705-  m2 = loadu_sse2(&block[sizeof(__m128i) * 2]);
 706-  m3 = loadu_sse2(&block[sizeof(__m128i) * 3]);
 707-
 708-  /* round 1 */
 709-  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(2, 0, 2, 0));
 710-  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t0);
 711-  t1 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 3, 1));
 712-  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
 713-  diagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 714-  t2 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(2, 0, 2, 0));
 715-  t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2, 1, 0, 3));
 716-  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t2);
 717-  t3 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 1, 3, 1));
 718-  t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(2, 1, 0, 3));
 719-  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
 720-  undiagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 721-  m0 = t0;
 722-  m1 = t1;
 723-  m2 = t2;
 724-  m3 = t3;
 725-
 726-  /* round 2 */
 727-  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
 728-  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
 729-  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t0);
 730-  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
 731-  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
 732-  t1 = blend_epi16_sse2(tt, t1, 0xCC);
 733-  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
 734-  diagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 735-  t2 = _mm_unpacklo_epi64(m3, m1);
 736-  tt = blend_epi16_sse2(t2, m2, 0xC0);
 737-  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
 738-  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t2);
 739-  t3 = _mm_unpackhi_epi32(m1, m3);
 740-  tt = _mm_unpacklo_epi32(m2, t3);
 741-  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
 742-  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
 743-  undiagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 744-  m0 = t0;
 745-  m1 = t1;
 746-  m2 = t2;
 747-  m3 = t3;
 748-
 749-  /* round 3 */
 750-  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
 751-  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
 752-  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t0);
 753-  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
 754-  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
 755-  t1 = blend_epi16_sse2(tt, t1, 0xCC);
 756-  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
 757-  diagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 758-  t2 = _mm_unpacklo_epi64(m3, m1);
 759-  tt = blend_epi16_sse2(t2, m2, 0xC0);
 760-  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
 761-  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t2);
 762-  t3 = _mm_unpackhi_epi32(m1, m3);
 763-  tt = _mm_unpacklo_epi32(m2, t3);
 764-  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
 765-  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
 766-  undiagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 767-  m0 = t0;
 768-  m1 = t1;
 769-  m2 = t2;
 770-  m3 = t3;
 771-
 772-  /* round 4 */
 773-  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
 774-  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
 775-  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t0);
 776-  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
 777-  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
 778-  t1 = blend_epi16_sse2(tt, t1, 0xCC);
 779-  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
 780-  diagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 781-  t2 = _mm_unpacklo_epi64(m3, m1);
 782-  tt = blend_epi16_sse2(t2, m2, 0xC0);
 783-  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
 784-  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t2);
 785-  t3 = _mm_unpackhi_epi32(m1, m3);
 786-  tt = _mm_unpacklo_epi32(m2, t3);
 787-  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
 788-  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
 789-  undiagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 790-  m0 = t0;
 791-  m1 = t1;
 792-  m2 = t2;
 793-  m3 = t3;
 794-
 795-  /* round 5 */
 796-  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
 797-  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
 798-  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t0);
 799-  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
 800-  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
 801-  t1 = blend_epi16_sse2(tt, t1, 0xCC);
 802-  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
 803-  diagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 804-  t2 = _mm_unpacklo_epi64(m3, m1);
 805-  tt = blend_epi16_sse2(t2, m2, 0xC0);
 806-  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
 807-  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t2);
 808-  t3 = _mm_unpackhi_epi32(m1, m3);
 809-  tt = _mm_unpacklo_epi32(m2, t3);
 810-  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
 811-  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
 812-  undiagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 813-  m0 = t0;
 814-  m1 = t1;
 815-  m2 = t2;
 816-  m3 = t3;
 817-
 818-  /* round 6 */
 819-  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
 820-  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
 821-  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t0);
 822-  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
 823-  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
 824-  t1 = blend_epi16_sse2(tt, t1, 0xCC);
 825-  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
 826-  diagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 827-  t2 = _mm_unpacklo_epi64(m3, m1);
 828-  tt = blend_epi16_sse2(t2, m2, 0xC0);
 829-  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
 830-  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t2);
 831-  t3 = _mm_unpackhi_epi32(m1, m3);
 832-  tt = _mm_unpacklo_epi32(m2, t3);
 833-  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
 834-  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
 835-  undiagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 836-  m0 = t0;
 837-  m1 = t1;
 838-  m2 = t2;
 839-  m3 = t3;
 840-
 841-  /* round 7 */
 842-  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
 843-  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
 844-  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t0);
 845-  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
 846-  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
 847-  t1 = blend_epi16_sse2(tt, t1, 0xCC);
 848-  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
 849-  diagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 850-  t2 = _mm_unpacklo_epi64(m3, m1);
 851-  tt = blend_epi16_sse2(t2, m2, 0xC0);
 852-  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
 853-  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t2);
 854-  t3 = _mm_unpackhi_epi32(m1, m3);
 855-  tt = _mm_unpacklo_epi32(m2, t3);
 856-  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
 857-  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
 858-  undiagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 859-}
 860-
 861-void
 862-blake3_compress_in_place_sse2(
 863-    uint32_t      cv[8],
 864-    const uint8_t block[BLAKE3_BLOCK_LEN],
 865-    uint8_t       block_len,
 866-    uint64_t      counter,
 867-    uint8_t       flags
 868-)
 869-{
 870-  __m128i rows[4];
 871-
 872-  compress_pre_sse2(rows, cv, block, block_len, counter, flags);
 873-  storeu_sse2(xorv_sse2(rows[0], rows[2]), (uint8_t *)&cv[0]);
 874-  storeu_sse2(xorv_sse2(rows[1], rows[3]), (uint8_t *)&cv[4]);
 875-}
 876-
 877-void
 878-blake3_compress_xof_sse2(
 879-    const uint32_t cv[8],
 880-    const uint8_t  block[BLAKE3_BLOCK_LEN],
 881-    uint8_t        block_len,
 882-    uint64_t       counter,
 883-    uint8_t        flags,
 884-    uint8_t        out_buf[64]
 885-)
 886-{
 887-  __m128i rows[4];
 888-
 889-  compress_pre_sse2(rows, cv, block, block_len, counter, flags);
 890-  storeu_sse2(xorv_sse2(rows[0], rows[2]), &out_buf[0]);
 891-  storeu_sse2(xorv_sse2(rows[1], rows[3]), &out_buf[16]);
 892-  storeu_sse2(xorv_sse2(rows[2], loadu_sse2((uint8_t *)&cv[0])), &out_buf[32]);
 893-  storeu_sse2(xorv_sse2(rows[3], loadu_sse2((uint8_t *)&cv[4])), &out_buf[48]);
 894-}
 895-
 896-static inline void
 897-round_fn_sse2(__m128i v[16], __m128i m[16], size_t r)
 898-{
 899-  v[0]  = addv_sse2(v[0], m[(size_t)MSG_SCHEDULE[r][0]]);
 900-  v[1]  = addv_sse2(v[1], m[(size_t)MSG_SCHEDULE[r][2]]);
 901-  v[2]  = addv_sse2(v[2], m[(size_t)MSG_SCHEDULE[r][4]]);
 902-  v[3]  = addv_sse2(v[3], m[(size_t)MSG_SCHEDULE[r][6]]);
 903-  v[0]  = addv_sse2(v[0], v[4]);
 904-  v[1]  = addv_sse2(v[1], v[5]);
 905-  v[2]  = addv_sse2(v[2], v[6]);
 906-  v[3]  = addv_sse2(v[3], v[7]);
 907-  v[12] = xorv_sse2(v[12], v[0]);
 908-  v[13] = xorv_sse2(v[13], v[1]);
 909-  v[14] = xorv_sse2(v[14], v[2]);
 910-  v[15] = xorv_sse2(v[15], v[3]);
 911-  v[12] = rot16_sse2(v[12]);
 912-  v[13] = rot16_sse2(v[13]);
 913-  v[14] = rot16_sse2(v[14]);
 914-  v[15] = rot16_sse2(v[15]);
 915-  v[8]  = addv_sse2(v[8], v[12]);
 916-  v[9]  = addv_sse2(v[9], v[13]);
 917-  v[10] = addv_sse2(v[10], v[14]);
 918-  v[11] = addv_sse2(v[11], v[15]);
 919-  v[4]  = xorv_sse2(v[4], v[8]);
 920-  v[5]  = xorv_sse2(v[5], v[9]);
 921-  v[6]  = xorv_sse2(v[6], v[10]);
 922-  v[7]  = xorv_sse2(v[7], v[11]);
 923-  v[4]  = rot12_sse2(v[4]);
 924-  v[5]  = rot12_sse2(v[5]);
 925-  v[6]  = rot12_sse2(v[6]);
 926-  v[7]  = rot12_sse2(v[7]);
 927-  v[0]  = addv_sse2(v[0], m[(size_t)MSG_SCHEDULE[r][1]]);
 928-  v[1]  = addv_sse2(v[1], m[(size_t)MSG_SCHEDULE[r][3]]);
 929-  v[2]  = addv_sse2(v[2], m[(size_t)MSG_SCHEDULE[r][5]]);
 930-  v[3]  = addv_sse2(v[3], m[(size_t)MSG_SCHEDULE[r][7]]);
 931-  v[0]  = addv_sse2(v[0], v[4]);
 932-  v[1]  = addv_sse2(v[1], v[5]);
 933-  v[2]  = addv_sse2(v[2], v[6]);
 934-  v[3]  = addv_sse2(v[3], v[7]);
 935-  v[12] = xorv_sse2(v[12], v[0]);
 936-  v[13] = xorv_sse2(v[13], v[1]);
 937-  v[14] = xorv_sse2(v[14], v[2]);
 938-  v[15] = xorv_sse2(v[15], v[3]);
 939-  v[12] = rot8_sse2(v[12]);
 940-  v[13] = rot8_sse2(v[13]);
 941-  v[14] = rot8_sse2(v[14]);
 942-  v[15] = rot8_sse2(v[15]);
 943-  v[8]  = addv_sse2(v[8], v[12]);
 944-  v[9]  = addv_sse2(v[9], v[13]);
 945-  v[10] = addv_sse2(v[10], v[14]);
 946-  v[11] = addv_sse2(v[11], v[15]);
 947-  v[4]  = xorv_sse2(v[4], v[8]);
 948-  v[5]  = xorv_sse2(v[5], v[9]);
 949-  v[6]  = xorv_sse2(v[6], v[10]);
 950-  v[7]  = xorv_sse2(v[7], v[11]);
 951-  v[4]  = rot7_sse2(v[4]);
 952-  v[5]  = rot7_sse2(v[5]);
 953-  v[6]  = rot7_sse2(v[6]);
 954-  v[7]  = rot7_sse2(v[7]);
 955-
 956-  v[0]  = addv_sse2(v[0], m[(size_t)MSG_SCHEDULE[r][8]]);
 957-  v[1]  = addv_sse2(v[1], m[(size_t)MSG_SCHEDULE[r][10]]);
 958-  v[2]  = addv_sse2(v[2], m[(size_t)MSG_SCHEDULE[r][12]]);
 959-  v[3]  = addv_sse2(v[3], m[(size_t)MSG_SCHEDULE[r][14]]);
 960-  v[0]  = addv_sse2(v[0], v[5]);
 961-  v[1]  = addv_sse2(v[1], v[6]);
 962-  v[2]  = addv_sse2(v[2], v[7]);
 963-  v[3]  = addv_sse2(v[3], v[4]);
 964-  v[15] = xorv_sse2(v[15], v[0]);
 965-  v[12] = xorv_sse2(v[12], v[1]);
 966-  v[13] = xorv_sse2(v[13], v[2]);
 967-  v[14] = xorv_sse2(v[14], v[3]);
 968-  v[15] = rot16_sse2(v[15]);
 969-  v[12] = rot16_sse2(v[12]);
 970-  v[13] = rot16_sse2(v[13]);
 971-  v[14] = rot16_sse2(v[14]);
 972-  v[10] = addv_sse2(v[10], v[15]);
 973-  v[11] = addv_sse2(v[11], v[12]);
 974-  v[8]  = addv_sse2(v[8], v[13]);
 975-  v[9]  = addv_sse2(v[9], v[14]);
 976-  v[5]  = xorv_sse2(v[5], v[10]);
 977-  v[6]  = xorv_sse2(v[6], v[11]);
 978-  v[7]  = xorv_sse2(v[7], v[8]);
 979-  v[4]  = xorv_sse2(v[4], v[9]);
 980-  v[5]  = rot12_sse2(v[5]);
 981-  v[6]  = rot12_sse2(v[6]);
 982-  v[7]  = rot12_sse2(v[7]);
 983-  v[4]  = rot12_sse2(v[4]);
 984-  v[0]  = addv_sse2(v[0], m[(size_t)MSG_SCHEDULE[r][9]]);
 985-  v[1]  = addv_sse2(v[1], m[(size_t)MSG_SCHEDULE[r][11]]);
 986-  v[2]  = addv_sse2(v[2], m[(size_t)MSG_SCHEDULE[r][13]]);
 987-  v[3]  = addv_sse2(v[3], m[(size_t)MSG_SCHEDULE[r][15]]);
 988-  v[0]  = addv_sse2(v[0], v[5]);
 989-  v[1]  = addv_sse2(v[1], v[6]);
 990-  v[2]  = addv_sse2(v[2], v[7]);
 991-  v[3]  = addv_sse2(v[3], v[4]);
 992-  v[15] = xorv_sse2(v[15], v[0]);
 993-  v[12] = xorv_sse2(v[12], v[1]);
 994-  v[13] = xorv_sse2(v[13], v[2]);
 995-  v[14] = xorv_sse2(v[14], v[3]);
 996-  v[15] = rot8_sse2(v[15]);
 997-  v[12] = rot8_sse2(v[12]);
 998-  v[13] = rot8_sse2(v[13]);
 999-  v[14] = rot8_sse2(v[14]);
1000-  v[10] = addv_sse2(v[10], v[15]);
1001-  v[11] = addv_sse2(v[11], v[12]);
1002-  v[8]  = addv_sse2(v[8], v[13]);
1003-  v[9]  = addv_sse2(v[9], v[14]);
1004-  v[5]  = xorv_sse2(v[5], v[10]);
1005-  v[6]  = xorv_sse2(v[6], v[11]);
1006-  v[7]  = xorv_sse2(v[7], v[8]);
1007-  v[4]  = xorv_sse2(v[4], v[9]);
1008-  v[5]  = rot7_sse2(v[5]);
1009-  v[6]  = rot7_sse2(v[6]);
1010-  v[7]  = rot7_sse2(v[7]);
1011-  v[4]  = rot7_sse2(v[4]);
1012-}
1013-
1014-static inline void
1015-transpose_vecs_sse2(__m128i vecs[DEGREE_SSE2])
1016-{
1017-  __m128i ab_01 = _mm_unpacklo_epi32(vecs[0], vecs[1]);
1018-  __m128i ab_23 = _mm_unpackhi_epi32(vecs[0], vecs[1]);
1019-  __m128i cd_01 = _mm_unpacklo_epi32(vecs[2], vecs[3]);
1020-  __m128i cd_23 = _mm_unpackhi_epi32(vecs[2], vecs[3]);
1021-
1022-  __m128i abcd_0 = _mm_unpacklo_epi64(ab_01, cd_01);
1023-  __m128i abcd_1 = _mm_unpackhi_epi64(ab_01, cd_01);
1024-  __m128i abcd_2 = _mm_unpacklo_epi64(ab_23, cd_23);
1025-  __m128i abcd_3 = _mm_unpackhi_epi64(ab_23, cd_23);
1026-
1027-  vecs[0] = abcd_0;
1028-  vecs[1] = abcd_1;
1029-  vecs[2] = abcd_2;
1030-  vecs[3] = abcd_3;
1031-}
1032-
1033-static inline void
1034-transpose_msg_vecs_sse2(const uint8_t *const *inputs, size_t block_offset, __m128i out_msg[16])
1035-{
1036-  size_t i;
1037-
1038-  out_msg[0]  = loadu_sse2(&inputs[0][block_offset + 0 * sizeof(__m128i)]);
1039-  out_msg[1]  = loadu_sse2(&inputs[1][block_offset + 0 * sizeof(__m128i)]);
1040-  out_msg[2]  = loadu_sse2(&inputs[2][block_offset + 0 * sizeof(__m128i)]);
1041-  out_msg[3]  = loadu_sse2(&inputs[3][block_offset + 0 * sizeof(__m128i)]);
1042-  out_msg[4]  = loadu_sse2(&inputs[0][block_offset + 1 * sizeof(__m128i)]);
1043-  out_msg[5]  = loadu_sse2(&inputs[1][block_offset + 1 * sizeof(__m128i)]);
1044-  out_msg[6]  = loadu_sse2(&inputs[2][block_offset + 1 * sizeof(__m128i)]);
1045-  out_msg[7]  = loadu_sse2(&inputs[3][block_offset + 1 * sizeof(__m128i)]);
1046-  out_msg[8]  = loadu_sse2(&inputs[0][block_offset + 2 * sizeof(__m128i)]);
1047-  out_msg[9]  = loadu_sse2(&inputs[1][block_offset + 2 * sizeof(__m128i)]);
1048-  out_msg[10] = loadu_sse2(&inputs[2][block_offset + 2 * sizeof(__m128i)]);
1049-  out_msg[11] = loadu_sse2(&inputs[3][block_offset + 2 * sizeof(__m128i)]);
1050-  out_msg[12] = loadu_sse2(&inputs[0][block_offset + 3 * sizeof(__m128i)]);
1051-  out_msg[13] = loadu_sse2(&inputs[1][block_offset + 3 * sizeof(__m128i)]);
1052-  out_msg[14] = loadu_sse2(&inputs[2][block_offset + 3 * sizeof(__m128i)]);
1053-  out_msg[15] = loadu_sse2(&inputs[3][block_offset + 3 * sizeof(__m128i)]);
1054-
1055-  for (i = 0; i < 4; i++) {
1056-    _mm_prefetch((const void *)&inputs[i][block_offset + 256], _MM_HINT_T0);
1057-  }
1058-  transpose_vecs_sse2(&out_msg[0]);
1059-  transpose_vecs_sse2(&out_msg[4]);
1060-  transpose_vecs_sse2(&out_msg[8]);
1061-  transpose_vecs_sse2(&out_msg[12]);
1062-}
1063-
1064-static inline void
1065-load_counters_sse2(uint64_t counter, int increment_counter, __m128i *out_lo, __m128i *out_hi)
1066-{
1067-  const __m128i mask  = _mm_set1_epi32(-increment_counter);
1068-  const __m128i add0  = _mm_set_epi32(3, 2, 1, 0);
1069-  const __m128i add1  = _mm_and_si128(mask, add0);
1070-  __m128i       l     = _mm_add_epi32(_mm_set1_epi32((int32_t)counter), add1);
1071-  __m128i       carry = _mm_cmpgt_epi32(
1072-      _mm_xor_si128(add1, _mm_set1_epi32(0x80000000)), _mm_xor_si128(l, _mm_set1_epi32(0x80000000))
1073-  );
1074-  __m128i h = _mm_sub_epi32(_mm_set1_epi32((int32_t)(counter >> 32)), carry);
1075-
1076-  *out_lo = l;
1077-  *out_hi = h;
1078-}
1079-
1080-void
1081-blake3_hash4_sse2(
1082-    const uint8_t *const *inputs,
1083-    size_t                blocks,
1084-    const uint32_t        key[8],
1085-    uint64_t              counter,
1086-    int                   increment_counter,
1087-    uint8_t               flags,
1088-    uint8_t               flags_start,
1089-    uint8_t               flags_end,
1090-    uint8_t              *out_bytes
1091-)
1092-{
1093-  __m128i h_vecs[8];
1094-  __m128i counter_low_vec, counter_high_vec;
1095-  uint8_t block_flags;
1096-  size_t  block;
1097-
1098-  h_vecs[0] = set1_sse2(key[0]);
1099-  h_vecs[1] = set1_sse2(key[1]);
1100-  h_vecs[2] = set1_sse2(key[2]);
1101-  h_vecs[3] = set1_sse2(key[3]);
1102-  h_vecs[4] = set1_sse2(key[4]);
1103-  h_vecs[5] = set1_sse2(key[5]);
1104-  h_vecs[6] = set1_sse2(key[6]);
1105-  h_vecs[7] = set1_sse2(key[7]);
1106-
1107-  load_counters_sse2(counter, increment_counter, &counter_low_vec, &counter_high_vec);
1108-  block_flags = flags | flags_start;
1109-
1110-  for (block = 0; block < blocks; block++) {
1111-    __m128i block_len_vec;
1112-    __m128i block_flags_vec;
1113-    __m128i msg_vecs[16];
1114-    __m128i v[16];
1115-
1116-    if (block + 1 == blocks) {
1117-      block_flags |= flags_end;
1118-    }
1119-    block_len_vec   = set1_sse2(BLAKE3_BLOCK_LEN);
1120-    block_flags_vec = set1_sse2(block_flags);
1121-    transpose_msg_vecs_sse2(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs);
1122-
1123-    v[0]  = h_vecs[0];
1124-    v[1]  = h_vecs[1];
1125-    v[2]  = h_vecs[2];
1126-    v[3]  = h_vecs[3];
1127-    v[4]  = h_vecs[4];
1128-    v[5]  = h_vecs[5];
1129-    v[6]  = h_vecs[6];
1130-    v[7]  = h_vecs[7];
1131-    v[8]  = set1_sse2(IV[0]);
1132-    v[9]  = set1_sse2(IV[1]);
1133-    v[10] = set1_sse2(IV[2]);
1134-    v[11] = set1_sse2(IV[3]);
1135-    v[12] = counter_low_vec;
1136-    v[13] = counter_high_vec;
1137-    v[14] = block_len_vec;
1138-    v[15] = block_flags_vec;
1139-
1140-    round_fn_sse2(v, msg_vecs, 0);
1141-    round_fn_sse2(v, msg_vecs, 1);
1142-    round_fn_sse2(v, msg_vecs, 2);
1143-    round_fn_sse2(v, msg_vecs, 3);
1144-    round_fn_sse2(v, msg_vecs, 4);
1145-    round_fn_sse2(v, msg_vecs, 5);
1146-    round_fn_sse2(v, msg_vecs, 6);
1147-
1148-    h_vecs[0] = xorv_sse2(v[0], v[8]);
1149-    h_vecs[1] = xorv_sse2(v[1], v[9]);
1150-    h_vecs[2] = xorv_sse2(v[2], v[10]);
1151-    h_vecs[3] = xorv_sse2(v[3], v[11]);
1152-    h_vecs[4] = xorv_sse2(v[4], v[12]);
1153-    h_vecs[5] = xorv_sse2(v[5], v[13]);
1154-    h_vecs[6] = xorv_sse2(v[6], v[14]);
1155-    h_vecs[7] = xorv_sse2(v[7], v[15]);
1156-
1157-    block_flags = flags;
1158-  }
1159-
1160-  transpose_vecs_sse2(&h_vecs[0]);
1161-  transpose_vecs_sse2(&h_vecs[4]);
1162-  storeu_sse2(h_vecs[0], &out_bytes[0 * sizeof(__m128i)]);
1163-  storeu_sse2(h_vecs[4], &out_bytes[1 * sizeof(__m128i)]);
1164-  storeu_sse2(h_vecs[1], &out_bytes[2 * sizeof(__m128i)]);
1165-  storeu_sse2(h_vecs[5], &out_bytes[3 * sizeof(__m128i)]);
1166-  storeu_sse2(h_vecs[2], &out_bytes[4 * sizeof(__m128i)]);
1167-  storeu_sse2(h_vecs[6], &out_bytes[5 * sizeof(__m128i)]);
1168-  storeu_sse2(h_vecs[3], &out_bytes[6 * sizeof(__m128i)]);
1169-  storeu_sse2(h_vecs[7], &out_bytes[7 * sizeof(__m128i)]);
1170-}
1171-
1172-static inline void
1173-hash_one_sse2(
1174-    const uint8_t *input,
1175-    size_t         blocks,
1176-    const uint32_t key[8],
1177-    uint64_t       counter,
1178-    uint8_t        flags,
1179-    uint8_t        flags_start,
1180-    uint8_t        flags_end,
1181-    uint8_t        out_bytes[BLAKE3_OUT_LEN]
1182-)
1183-{
1184-  uint32_t cv[8];
1185-  uint8_t  block_flags;
1186-
1187-  memcpy(cv, key, BLAKE3_KEY_LEN);
1188-  block_flags = flags | flags_start;
1189-  while (blocks > 0) {
1190-    if (blocks == 1) {
1191-      block_flags |= flags_end;
1192-    }
1193-    blake3_compress_in_place_sse2(cv, input, BLAKE3_BLOCK_LEN, counter, block_flags);
1194-    input = &input[BLAKE3_BLOCK_LEN];
1195-    blocks -= 1;
1196-    block_flags = flags;
1197-  }
1198-  memcpy(out_bytes, cv, BLAKE3_OUT_LEN);
1199-}
1200-
1201-void
1202-blake3_hash_many_sse2(
1203-    const uint8_t *const *inputs,
1204-    size_t                num_inputs,
1205-    size_t                blocks,
1206-    const uint32_t        key[8],
1207-    uint64_t              counter,
1208-    int                   increment_counter,
1209-    uint8_t               flags,
1210-    uint8_t               flags_start,
1211-    uint8_t               flags_end,
1212-    uint8_t              *out_bytes
1213-)
1214-{
1215-  while (num_inputs >= DEGREE_SSE2) {
1216-    blake3_hash4_sse2(
1217-        inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out_bytes
1218-    );
1219-    if (increment_counter) {
1220-      counter += DEGREE_SSE2;
1221-    }
1222-    inputs += DEGREE_SSE2;
1223-    num_inputs -= DEGREE_SSE2;
1224-    out_bytes = &out_bytes[DEGREE_SSE2 * BLAKE3_OUT_LEN];
1225-  }
1226-  while (num_inputs > 0) {
1227-    hash_one_sse2(inputs[0], blocks, key, counter, flags, flags_start, flags_end, out_bytes);
1228-    if (increment_counter) {
1229-      counter += 1;
1230-    }
1231-    inputs += 1;
1232-    num_inputs -= 1;
1233-    out_bytes = &out_bytes[BLAKE3_OUT_LEN];
1234-  }
1235-}
1236-#if defined(__clang__)
1237-#pragma clang attribute pop
1238-#elif defined(__GNUC__)
1239-#pragma GCC pop_options
1240-#endif
1241-
1242-#if defined(__clang__)
1243-#pragma clang attribute push(__attribute__((target("sse4.1"))), apply_to = function)
1244-#elif defined(__GNUC__)
1245-#pragma GCC push_options
1246-#pragma GCC target("sse4.1")
1247-#endif
1248-#define DEGREE_SSE41 4
1249-
1250-#define _mm_shuffle_ps2_sse41(a, b, c)                                                             \
1251-  (_mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), (c))))
1252-
1253-static inline __m128i
1254-loadu_sse41(const uint8_t src[16])
1255-{
1256-  return _mm_loadu_si128((const __m128i *)src);
1257-}
1258-
1259-static inline void
1260-storeu_sse41(__m128i src, uint8_t dest[16])
1261-{
1262-  _mm_storeu_si128((__m128i *)dest, src);
1263-}
1264-
1265-static inline __m128i
1266-addv_sse41(__m128i a, __m128i b)
1267-{
1268-  return _mm_add_epi32(a, b);
1269-}
1270-
1271-static inline __m128i
1272-xorv_sse41(__m128i a, __m128i b)
1273-{
1274-  return _mm_xor_si128(a, b);
1275-}
1276-
1277-static inline __m128i
1278-set1_sse41(uint32_t x)
1279-{
1280-  return _mm_set1_epi32((int32_t)x);
1281-}
1282-
1283-static inline __m128i
1284-set4_sse41(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
1285-{
1286-  return _mm_setr_epi32((int32_t)a, (int32_t)b, (int32_t)c, (int32_t)d);
1287-}
1288-
1289-static inline __m128i
1290-rot16_sse41(__m128i x)
1291-{
1292-  return _mm_shuffle_epi8(x, _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2));
1293-}
1294-
1295-static inline __m128i
1296-rot12_sse41(__m128i x)
1297-{
1298-  return xorv_sse41(_mm_srli_epi32(x, 12), _mm_slli_epi32(x, 32 - 12));
1299-}
1300-
1301-static inline __m128i
1302-rot8_sse41(__m128i x)
1303-{
1304-  return _mm_shuffle_epi8(x, _mm_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1));
1305-}
1306-
1307-static inline __m128i
1308-rot7_sse41(__m128i x)
1309-{
1310-  return xorv_sse41(_mm_srli_epi32(x, 7), _mm_slli_epi32(x, 32 - 7));
1311-}
1312-
1313-static inline void
1314-g1_sse41(__m128i *row0, __m128i *row1, __m128i *row2, __m128i *row3, __m128i m)
1315-{
1316-  *row0 = addv_sse41(addv_sse41(*row0, m), *row1);
1317-  *row3 = xorv_sse41(*row3, *row0);
1318-  *row3 = rot16_sse41(*row3);
1319-  *row2 = addv_sse41(*row2, *row3);
1320-  *row1 = xorv_sse41(*row1, *row2);
1321-  *row1 = rot12_sse41(*row1);
1322-}
1323-
1324-static inline void
1325-g2_sse41(__m128i *row0, __m128i *row1, __m128i *row2, __m128i *row3, __m128i m)
1326-{
1327-  *row0 = addv_sse41(addv_sse41(*row0, m), *row1);
1328-  *row3 = xorv_sse41(*row3, *row0);
1329-  *row3 = rot8_sse41(*row3);
1330-  *row2 = addv_sse41(*row2, *row3);
1331-  *row1 = xorv_sse41(*row1, *row2);
1332-  *row1 = rot7_sse41(*row1);
1333-}
1334-
1335-static inline void
1336-diagonalize_sse41(__m128i *row0, __m128i *row2, __m128i *row3)
1337-{
1338-  *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE(2, 1, 0, 3));
1339-  *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE(1, 0, 3, 2));
1340-  *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE(0, 3, 2, 1));
1341-}
1342-
1343-static inline void
1344-undiagonalize_sse41(__m128i *row0, __m128i *row2, __m128i *row3)
1345-{
1346-  *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE(0, 3, 2, 1));
1347-  *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE(1, 0, 3, 2));
1348-  *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE(2, 1, 0, 3));
1349-}
1350-
1351-static inline void
1352-compress_pre_sse41(
1353-    __m128i        rows[4],
1354-    const uint32_t cv[8],
1355-    const uint8_t  block[BLAKE3_BLOCK_LEN],
1356-    uint8_t        block_len,
1357-    uint64_t       counter,
1358-    uint8_t        flags
1359-)
1360-{
1361-  __m128i m0, m1, m2, m3;
1362-  __m128i t0, t1, t2, t3, tt;
1363-
1364-  rows[0] = loadu_sse41((uint8_t *)&cv[0]);
1365-  rows[1] = loadu_sse41((uint8_t *)&cv[4]);
1366-  rows[2] = set4_sse41(IV[0], IV[1], IV[2], IV[3]);
1367-  rows[3] =
1368-      set4_sse41(counter_low(counter), counter_high(counter), (uint32_t)block_len, (uint32_t)flags);
1369-
1370-  m0 = loadu_sse41(&block[sizeof(__m128i) * 0]);
1371-  m1 = loadu_sse41(&block[sizeof(__m128i) * 1]);
1372-  m2 = loadu_sse41(&block[sizeof(__m128i) * 2]);
1373-  m3 = loadu_sse41(&block[sizeof(__m128i) * 3]);
1374-
1375-  /* round 1 */
1376-  t0 = _mm_shuffle_ps2_sse41(m0, m1, _MM_SHUFFLE(2, 0, 2, 0));
1377-  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t0);
1378-  t1 = _mm_shuffle_ps2_sse41(m0, m1, _MM_SHUFFLE(3, 1, 3, 1));
1379-  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t1);
1380-  diagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1381-  t2 = _mm_shuffle_ps2_sse41(m2, m3, _MM_SHUFFLE(2, 0, 2, 0));
1382-  t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2, 1, 0, 3));
1383-  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t2);
1384-  t3 = _mm_shuffle_ps2_sse41(m2, m3, _MM_SHUFFLE(3, 1, 3, 1));
1385-  t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(2, 1, 0, 3));
1386-  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t3);
1387-  undiagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1388-  m0 = t0;
1389-  m1 = t1;
1390-  m2 = t2;
1391-  m3 = t3;
1392-
1393-  /* round 2 */
1394-  t0 = _mm_shuffle_ps2_sse41(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
1395-  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
1396-  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t0);
1397-  t1 = _mm_shuffle_ps2_sse41(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
1398-  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
1399-  t1 = _mm_blend_epi16(tt, t1, 0xCC);
1400-  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t1);
1401-  diagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1402-  t2 = _mm_unpacklo_epi64(m3, m1);
1403-  tt = _mm_blend_epi16(t2, m2, 0xC0);
1404-  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
1405-  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t2);
1406-  t3 = _mm_unpackhi_epi32(m1, m3);
1407-  tt = _mm_unpacklo_epi32(m2, t3);
1408-  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
1409-  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t3);
1410-  undiagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1411-  m0 = t0;
1412-  m1 = t1;
1413-  m2 = t2;
1414-  m3 = t3;
1415-
1416-  /* round 3 */
1417-  t0 = _mm_shuffle_ps2_sse41(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
1418-  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
1419-  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t0);
1420-  t1 = _mm_shuffle_ps2_sse41(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
1421-  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
1422-  t1 = _mm_blend_epi16(tt, t1, 0xCC);
1423-  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t1);
1424-  diagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1425-  t2 = _mm_unpacklo_epi64(m3, m1);
1426-  tt = _mm_blend_epi16(t2, m2, 0xC0);
1427-  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
1428-  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t2);
1429-  t3 = _mm_unpackhi_epi32(m1, m3);
1430-  tt = _mm_unpacklo_epi32(m2, t3);
1431-  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
1432-  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t3);
1433-  undiagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1434-  m0 = t0;
1435-  m1 = t1;
1436-  m2 = t2;
1437-  m3 = t3;
1438-
1439-  /* round 4 */
1440-  t0 = _mm_shuffle_ps2_sse41(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
1441-  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
1442-  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t0);
1443-  t1 = _mm_shuffle_ps2_sse41(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
1444-  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
1445-  t1 = _mm_blend_epi16(tt, t1, 0xCC);
1446-  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t1);
1447-  diagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1448-  t2 = _mm_unpacklo_epi64(m3, m1);
1449-  tt = _mm_blend_epi16(t2, m2, 0xC0);
1450-  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
1451-  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t2);
1452-  t3 = _mm_unpackhi_epi32(m1, m3);
1453-  tt = _mm_unpacklo_epi32(m2, t3);
1454-  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
1455-  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t3);
1456-  undiagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1457-  m0 = t0;
1458-  m1 = t1;
1459-  m2 = t2;
1460-  m3 = t3;
1461-
1462-  /* round 5 */
1463-  t0 = _mm_shuffle_ps2_sse41(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
1464-  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
1465-  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t0);
1466-  t1 = _mm_shuffle_ps2_sse41(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
1467-  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
1468-  t1 = _mm_blend_epi16(tt, t1, 0xCC);
1469-  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t1);
1470-  diagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1471-  t2 = _mm_unpacklo_epi64(m3, m1);
1472-  tt = _mm_blend_epi16(t2, m2, 0xC0);
1473-  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
1474-  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t2);
1475-  t3 = _mm_unpackhi_epi32(m1, m3);
1476-  tt = _mm_unpacklo_epi32(m2, t3);
1477-  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
1478-  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t3);
1479-  undiagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1480-  m0 = t0;
1481-  m1 = t1;
1482-  m2 = t2;
1483-  m3 = t3;
1484-
1485-  /* round 6 */
1486-  t0 = _mm_shuffle_ps2_sse41(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
1487-  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
1488-  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t0);
1489-  t1 = _mm_shuffle_ps2_sse41(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
1490-  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
1491-  t1 = _mm_blend_epi16(tt, t1, 0xCC);
1492-  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t1);
1493-  diagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1494-  t2 = _mm_unpacklo_epi64(m3, m1);
1495-  tt = _mm_blend_epi16(t2, m2, 0xC0);
1496-  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
1497-  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t2);
1498-  t3 = _mm_unpackhi_epi32(m1, m3);
1499-  tt = _mm_unpacklo_epi32(m2, t3);
1500-  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
1501-  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t3);
1502-  undiagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1503-  m0 = t0;
1504-  m1 = t1;
1505-  m2 = t2;
1506-  m3 = t3;
1507-
1508-  /* round 7 */
1509-  t0 = _mm_shuffle_ps2_sse41(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
1510-  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
1511-  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t0);
1512-  t1 = _mm_shuffle_ps2_sse41(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
1513-  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
1514-  t1 = _mm_blend_epi16(tt, t1, 0xCC);
1515-  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t1);
1516-  diagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1517-  t2 = _mm_unpacklo_epi64(m3, m1);
1518-  tt = _mm_blend_epi16(t2, m2, 0xC0);
1519-  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
1520-  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t2);
1521-  t3 = _mm_unpackhi_epi32(m1, m3);
1522-  tt = _mm_unpacklo_epi32(m2, t3);
1523-  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
1524-  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t3);
1525-  undiagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1526-}
1527-
1528-void
1529-blake3_compress_in_place_sse41(
1530-    uint32_t      cv[8],
1531-    const uint8_t block[BLAKE3_BLOCK_LEN],
1532-    uint8_t       block_len,
1533-    uint64_t      counter,
1534-    uint8_t       flags
1535-)
1536-{
1537-  __m128i rows[4];
1538-
1539-  compress_pre_sse41(rows, cv, block, block_len, counter, flags);
1540-  storeu_sse41(xorv_sse41(rows[0], rows[2]), (uint8_t *)&cv[0]);
1541-  storeu_sse41(xorv_sse41(rows[1], rows[3]), (uint8_t *)&cv[4]);
1542-}
1543-
1544-void
1545-blake3_compress_xof_sse41(
1546-    const uint32_t cv[8],
1547-    const uint8_t  block[BLAKE3_BLOCK_LEN],
1548-    uint8_t        block_len,
1549-    uint64_t       counter,
1550-    uint8_t        flags,
1551-    uint8_t        out_buf[64]
1552-)
1553-{
1554-  __m128i rows[4];
1555-
1556-  compress_pre_sse41(rows, cv, block, block_len, counter, flags);
1557-  storeu_sse41(xorv_sse41(rows[0], rows[2]), &out_buf[0]);
1558-  storeu_sse41(xorv_sse41(rows[1], rows[3]), &out_buf[16]);
1559-  storeu_sse41(xorv_sse41(rows[2], loadu_sse41((uint8_t *)&cv[0])), &out_buf[32]);
1560-  storeu_sse41(xorv_sse41(rows[3], loadu_sse41((uint8_t *)&cv[4])), &out_buf[48]);
1561-}
1562-
1563-static inline void
1564-round_fn_sse41(__m128i v[16], __m128i m[16], size_t r)
1565-{
1566-  v[0]  = addv_sse41(v[0], m[(size_t)MSG_SCHEDULE[r][0]]);
1567-  v[1]  = addv_sse41(v[1], m[(size_t)MSG_SCHEDULE[r][2]]);
1568-  v[2]  = addv_sse41(v[2], m[(size_t)MSG_SCHEDULE[r][4]]);
1569-  v[3]  = addv_sse41(v[3], m[(size_t)MSG_SCHEDULE[r][6]]);
1570-  v[0]  = addv_sse41(v[0], v[4]);
1571-  v[1]  = addv_sse41(v[1], v[5]);
1572-  v[2]  = addv_sse41(v[2], v[6]);
1573-  v[3]  = addv_sse41(v[3], v[7]);
1574-  v[12] = xorv_sse41(v[12], v[0]);
1575-  v[13] = xorv_sse41(v[13], v[1]);
1576-  v[14] = xorv_sse41(v[14], v[2]);
1577-  v[15] = xorv_sse41(v[15], v[3]);
1578-  v[12] = rot16_sse41(v[12]);
1579-  v[13] = rot16_sse41(v[13]);
1580-  v[14] = rot16_sse41(v[14]);
1581-  v[15] = rot16_sse41(v[15]);
1582-  v[8]  = addv_sse41(v[8], v[12]);
1583-  v[9]  = addv_sse41(v[9], v[13]);
1584-  v[10] = addv_sse41(v[10], v[14]);
1585-  v[11] = addv_sse41(v[11], v[15]);
1586-  v[4]  = xorv_sse41(v[4], v[8]);
1587-  v[5]  = xorv_sse41(v[5], v[9]);
1588-  v[6]  = xorv_sse41(v[6], v[10]);
1589-  v[7]  = xorv_sse41(v[7], v[11]);
1590-  v[4]  = rot12_sse41(v[4]);
1591-  v[5]  = rot12_sse41(v[5]);
1592-  v[6]  = rot12_sse41(v[6]);
1593-  v[7]  = rot12_sse41(v[7]);
1594-  v[0]  = addv_sse41(v[0], m[(size_t)MSG_SCHEDULE[r][1]]);
1595-  v[1]  = addv_sse41(v[1], m[(size_t)MSG_SCHEDULE[r][3]]);
1596-  v[2]  = addv_sse41(v[2], m[(size_t)MSG_SCHEDULE[r][5]]);
1597-  v[3]  = addv_sse41(v[3], m[(size_t)MSG_SCHEDULE[r][7]]);
1598-  v[0]  = addv_sse41(v[0], v[4]);
1599-  v[1]  = addv_sse41(v[1], v[5]);
1600-  v[2]  = addv_sse41(v[2], v[6]);
1601-  v[3]  = addv_sse41(v[3], v[7]);
1602-  v[12] = xorv_sse41(v[12], v[0]);
1603-  v[13] = xorv_sse41(v[13], v[1]);
1604-  v[14] = xorv_sse41(v[14], v[2]);
1605-  v[15] = xorv_sse41(v[15], v[3]);
1606-  v[12] = rot8_sse41(v[12]);
1607-  v[13] = rot8_sse41(v[13]);
1608-  v[14] = rot8_sse41(v[14]);
1609-  v[15] = rot8_sse41(v[15]);
1610-  v[8]  = addv_sse41(v[8], v[12]);
1611-  v[9]  = addv_sse41(v[9], v[13]);
1612-  v[10] = addv_sse41(v[10], v[14]);
1613-  v[11] = addv_sse41(v[11], v[15]);
1614-  v[4]  = xorv_sse41(v[4], v[8]);
1615-  v[5]  = xorv_sse41(v[5], v[9]);
1616-  v[6]  = xorv_sse41(v[6], v[10]);
1617-  v[7]  = xorv_sse41(v[7], v[11]);
1618-  v[4]  = rot7_sse41(v[4]);
1619-  v[5]  = rot7_sse41(v[5]);
1620-  v[6]  = rot7_sse41(v[6]);
1621-  v[7]  = rot7_sse41(v[7]);
1622-
1623-  v[0]  = addv_sse41(v[0], m[(size_t)MSG_SCHEDULE[r][8]]);
1624-  v[1]  = addv_sse41(v[1], m[(size_t)MSG_SCHEDULE[r][10]]);
1625-  v[2]  = addv_sse41(v[2], m[(size_t)MSG_SCHEDULE[r][12]]);
1626-  v[3]  = addv_sse41(v[3], m[(size_t)MSG_SCHEDULE[r][14]]);
1627-  v[0]  = addv_sse41(v[0], v[5]);
1628-  v[1]  = addv_sse41(v[1], v[6]);
1629-  v[2]  = addv_sse41(v[2], v[7]);
1630-  v[3]  = addv_sse41(v[3], v[4]);
1631-  v[15] = xorv_sse41(v[15], v[0]);
1632-  v[12] = xorv_sse41(v[12], v[1]);
1633-  v[13] = xorv_sse41(v[13], v[2]);
1634-  v[14] = xorv_sse41(v[14], v[3]);
1635-  v[15] = rot16_sse41(v[15]);
1636-  v[12] = rot16_sse41(v[12]);
1637-  v[13] = rot16_sse41(v[13]);
1638-  v[14] = rot16_sse41(v[14]);
1639-  v[10] = addv_sse41(v[10], v[15]);
1640-  v[11] = addv_sse41(v[11], v[12]);
1641-  v[8]  = addv_sse41(v[8], v[13]);
1642-  v[9]  = addv_sse41(v[9], v[14]);
1643-  v[5]  = xorv_sse41(v[5], v[10]);
1644-  v[6]  = xorv_sse41(v[6], v[11]);
1645-  v[7]  = xorv_sse41(v[7], v[8]);
1646-  v[4]  = xorv_sse41(v[4], v[9]);
1647-  v[5]  = rot12_sse41(v[5]);
1648-  v[6]  = rot12_sse41(v[6]);
1649-  v[7]  = rot12_sse41(v[7]);
1650-  v[4]  = rot12_sse41(v[4]);
1651-  v[0]  = addv_sse41(v[0], m[(size_t)MSG_SCHEDULE[r][9]]);
1652-  v[1]  = addv_sse41(v[1], m[(size_t)MSG_SCHEDULE[r][11]]);
1653-  v[2]  = addv_sse41(v[2], m[(size_t)MSG_SCHEDULE[r][13]]);
1654-  v[3]  = addv_sse41(v[3], m[(size_t)MSG_SCHEDULE[r][15]]);
1655-  v[0]  = addv_sse41(v[0], v[5]);
1656-  v[1]  = addv_sse41(v[1], v[6]);
1657-  v[2]  = addv_sse41(v[2], v[7]);
1658-  v[3]  = addv_sse41(v[3], v[4]);
1659-  v[15] = xorv_sse41(v[15], v[0]);
1660-  v[12] = xorv_sse41(v[12], v[1]);
1661-  v[13] = xorv_sse41(v[13], v[2]);
1662-  v[14] = xorv_sse41(v[14], v[3]);
1663-  v[15] = rot8_sse41(v[15]);
1664-  v[12] = rot8_sse41(v[12]);
1665-  v[13] = rot8_sse41(v[13]);
1666-  v[14] = rot8_sse41(v[14]);
1667-  v[10] = addv_sse41(v[10], v[15]);
1668-  v[11] = addv_sse41(v[11], v[12]);
1669-  v[8]  = addv_sse41(v[8], v[13]);
1670-  v[9]  = addv_sse41(v[9], v[14]);
1671-  v[5]  = xorv_sse41(v[5], v[10]);
1672-  v[6]  = xorv_sse41(v[6], v[11]);
1673-  v[7]  = xorv_sse41(v[7], v[8]);
1674-  v[4]  = xorv_sse41(v[4], v[9]);
1675-  v[5]  = rot7_sse41(v[5]);
1676-  v[6]  = rot7_sse41(v[6]);
1677-  v[7]  = rot7_sse41(v[7]);
1678-  v[4]  = rot7_sse41(v[4]);
1679-}
1680-
1681-static inline void
1682-transpose_vecs_sse41(__m128i vecs[DEGREE_SSE41])
1683-{
1684-  __m128i ab_01 = _mm_unpacklo_epi32(vecs[0], vecs[1]);
1685-  __m128i ab_23 = _mm_unpackhi_epi32(vecs[0], vecs[1]);
1686-  __m128i cd_01 = _mm_unpacklo_epi32(vecs[2], vecs[3]);
1687-  __m128i cd_23 = _mm_unpackhi_epi32(vecs[2], vecs[3]);
1688-
1689-  __m128i abcd_0 = _mm_unpacklo_epi64(ab_01, cd_01);
1690-  __m128i abcd_1 = _mm_unpackhi_epi64(ab_01, cd_01);
1691-  __m128i abcd_2 = _mm_unpacklo_epi64(ab_23, cd_23);
1692-  __m128i abcd_3 = _mm_unpackhi_epi64(ab_23, cd_23);
1693-
1694-  vecs[0] = abcd_0;
1695-  vecs[1] = abcd_1;
1696-  vecs[2] = abcd_2;
1697-  vecs[3] = abcd_3;
1698-}
1699-
1700-static inline void
1701-transpose_msg_vecs_sse41(const uint8_t *const *inputs, size_t block_offset, __m128i out_msg[16])
1702-{
1703-  size_t i;
1704-
1705-  out_msg[0]  = loadu_sse41(&inputs[0][block_offset + 0 * sizeof(__m128i)]);
1706-  out_msg[1]  = loadu_sse41(&inputs[1][block_offset + 0 * sizeof(__m128i)]);
1707-  out_msg[2]  = loadu_sse41(&inputs[2][block_offset + 0 * sizeof(__m128i)]);
1708-  out_msg[3]  = loadu_sse41(&inputs[3][block_offset + 0 * sizeof(__m128i)]);
1709-  out_msg[4]  = loadu_sse41(&inputs[0][block_offset + 1 * sizeof(__m128i)]);
1710-  out_msg[5]  = loadu_sse41(&inputs[1][block_offset + 1 * sizeof(__m128i)]);
1711-  out_msg[6]  = loadu_sse41(&inputs[2][block_offset + 1 * sizeof(__m128i)]);
1712-  out_msg[7]  = loadu_sse41(&inputs[3][block_offset + 1 * sizeof(__m128i)]);
1713-  out_msg[8]  = loadu_sse41(&inputs[0][block_offset + 2 * sizeof(__m128i)]);
1714-  out_msg[9]  = loadu_sse41(&inputs[1][block_offset + 2 * sizeof(__m128i)]);
1715-  out_msg[10] = loadu_sse41(&inputs[2][block_offset + 2 * sizeof(__m128i)]);
1716-  out_msg[11] = loadu_sse41(&inputs[3][block_offset + 2 * sizeof(__m128i)]);
1717-  out_msg[12] = loadu_sse41(&inputs[0][block_offset + 3 * sizeof(__m128i)]);
1718-  out_msg[13] = loadu_sse41(&inputs[1][block_offset + 3 * sizeof(__m128i)]);
1719-  out_msg[14] = loadu_sse41(&inputs[2][block_offset + 3 * sizeof(__m128i)]);
1720-  out_msg[15] = loadu_sse41(&inputs[3][block_offset + 3 * sizeof(__m128i)]);
1721-
1722-  for (i = 0; i < 4; i++) {
1723-    _mm_prefetch((const void *)&inputs[i][block_offset + 256], _MM_HINT_T0);
1724-  }
1725-  transpose_vecs_sse41(&out_msg[0]);
1726-  transpose_vecs_sse41(&out_msg[4]);
1727-  transpose_vecs_sse41(&out_msg[8]);
1728-  transpose_vecs_sse41(&out_msg[12]);
1729-}
1730-
1731-static inline void
1732-load_counters_sse41(uint64_t counter, int increment_counter, __m128i *out_lo, __m128i *out_hi)
1733-{
1734-  const __m128i mask  = _mm_set1_epi32(-increment_counter);
1735-  const __m128i add0  = _mm_set_epi32(3, 2, 1, 0);
1736-  const __m128i add1  = _mm_and_si128(mask, add0);
1737-  __m128i       l     = _mm_add_epi32(_mm_set1_epi32((int32_t)counter), add1);
1738-  __m128i       carry = _mm_cmpgt_epi32(
1739-      _mm_xor_si128(add1, _mm_set1_epi32(0x80000000)), _mm_xor_si128(l, _mm_set1_epi32(0x80000000))
1740-  );
1741-  __m128i h = _mm_sub_epi32(_mm_set1_epi32((int32_t)(counter >> 32)), carry);
1742-
1743-  *out_lo = l;
1744-  *out_hi = h;
1745-}
1746-
1747-void
1748-blake3_hash4_sse41(
1749-    const uint8_t *const *inputs,
1750-    size_t                blocks,
1751-    const uint32_t        key[8],
1752-    uint64_t              counter,
1753-    int                   increment_counter,
1754-    uint8_t               flags,
1755-    uint8_t               flags_start,
1756-    uint8_t               flags_end,
1757-    uint8_t              *out_bytes
1758-)
1759-{
1760-  __m128i h_vecs[8];
1761-  __m128i counter_low_vec, counter_high_vec;
1762-  uint8_t block_flags;
1763-  size_t  block;
1764-
1765-  h_vecs[0] = set1_sse41(key[0]);
1766-  h_vecs[1] = set1_sse41(key[1]);
1767-  h_vecs[2] = set1_sse41(key[2]);
1768-  h_vecs[3] = set1_sse41(key[3]);
1769-  h_vecs[4] = set1_sse41(key[4]);
1770-  h_vecs[5] = set1_sse41(key[5]);
1771-  h_vecs[6] = set1_sse41(key[6]);
1772-  h_vecs[7] = set1_sse41(key[7]);
1773-
1774-  load_counters_sse41(counter, increment_counter, &counter_low_vec, &counter_high_vec);
1775-  block_flags = flags | flags_start;
1776-
1777-  for (block = 0; block < blocks; block++) {
1778-    __m128i block_len_vec;
1779-    __m128i block_flags_vec;
1780-    __m128i msg_vecs[16];
1781-    __m128i v[16];
1782-
1783-    if (block + 1 == blocks) {
1784-      block_flags |= flags_end;
1785-    }
1786-    block_len_vec   = set1_sse41(BLAKE3_BLOCK_LEN);
1787-    block_flags_vec = set1_sse41(block_flags);
1788-    transpose_msg_vecs_sse41(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs);
1789-
1790-    v[0]  = h_vecs[0];
1791-    v[1]  = h_vecs[1];
1792-    v[2]  = h_vecs[2];
1793-    v[3]  = h_vecs[3];
1794-    v[4]  = h_vecs[4];
1795-    v[5]  = h_vecs[5];
1796-    v[6]  = h_vecs[6];
1797-    v[7]  = h_vecs[7];
1798-    v[8]  = set1_sse41(IV[0]);
1799-    v[9]  = set1_sse41(IV[1]);
1800-    v[10] = set1_sse41(IV[2]);
1801-    v[11] = set1_sse41(IV[3]);
1802-    v[12] = counter_low_vec;
1803-    v[13] = counter_high_vec;
1804-    v[14] = block_len_vec;
1805-    v[15] = block_flags_vec;
1806-
1807-    round_fn_sse41(v, msg_vecs, 0);
1808-    round_fn_sse41(v, msg_vecs, 1);
1809-    round_fn_sse41(v, msg_vecs, 2);
1810-    round_fn_sse41(v, msg_vecs, 3);
1811-    round_fn_sse41(v, msg_vecs, 4);
1812-    round_fn_sse41(v, msg_vecs, 5);
1813-    round_fn_sse41(v, msg_vecs, 6);
1814-
1815-    h_vecs[0] = xorv_sse41(v[0], v[8]);
1816-    h_vecs[1] = xorv_sse41(v[1], v[9]);
1817-    h_vecs[2] = xorv_sse41(v[2], v[10]);
1818-    h_vecs[3] = xorv_sse41(v[3], v[11]);
1819-    h_vecs[4] = xorv_sse41(v[4], v[12]);
1820-    h_vecs[5] = xorv_sse41(v[5], v[13]);
1821-    h_vecs[6] = xorv_sse41(v[6], v[14]);
1822-    h_vecs[7] = xorv_sse41(v[7], v[15]);
1823-
1824-    block_flags = flags;
1825-  }
1826-
1827-  transpose_vecs_sse41(&h_vecs[0]);
1828-  transpose_vecs_sse41(&h_vecs[4]);
1829-  storeu_sse41(h_vecs[0], &out_bytes[0 * sizeof(__m128i)]);
1830-  storeu_sse41(h_vecs[4], &out_bytes[1 * sizeof(__m128i)]);
1831-  storeu_sse41(h_vecs[1], &out_bytes[2 * sizeof(__m128i)]);
1832-  storeu_sse41(h_vecs[5], &out_bytes[3 * sizeof(__m128i)]);
1833-  storeu_sse41(h_vecs[2], &out_bytes[4 * sizeof(__m128i)]);
1834-  storeu_sse41(h_vecs[6], &out_bytes[5 * sizeof(__m128i)]);
1835-  storeu_sse41(h_vecs[3], &out_bytes[6 * sizeof(__m128i)]);
1836-  storeu_sse41(h_vecs[7], &out_bytes[7 * sizeof(__m128i)]);
1837-}
1838-
1839-static inline void
1840-hash_one_sse41(
1841-    const uint8_t *input,
1842-    size_t         blocks,
1843-    const uint32_t key[8],
1844-    uint64_t       counter,
1845-    uint8_t        flags,
1846-    uint8_t        flags_start,
1847-    uint8_t        flags_end,
1848-    uint8_t        out_bytes[BLAKE3_OUT_LEN]
1849-)
1850-{
1851-  uint32_t cv[8];
1852-  uint8_t  block_flags;
1853-
1854-  memcpy(cv, key, BLAKE3_KEY_LEN);
1855-  block_flags = flags | flags_start;
1856-  while (blocks > 0) {
1857-    if (blocks == 1) {
1858-      block_flags |= flags_end;
1859-    }
1860-    blake3_compress_in_place_sse41(cv, input, BLAKE3_BLOCK_LEN, counter, block_flags);
1861-    input = &input[BLAKE3_BLOCK_LEN];
1862-    blocks -= 1;
1863-    block_flags = flags;
1864-  }
1865-  memcpy(out_bytes, cv, BLAKE3_OUT_LEN);
1866-}
1867-
1868-void
1869-blake3_hash_many_sse41(
1870-    const uint8_t *const *inputs,
1871-    size_t                num_inputs,
1872-    size_t                blocks,
1873-    const uint32_t        key[8],
1874-    uint64_t              counter,
1875-    int                   increment_counter,
1876-    uint8_t               flags,
1877-    uint8_t               flags_start,
1878-    uint8_t               flags_end,
1879-    uint8_t              *out_bytes
1880-)
1881-{
1882-  while (num_inputs >= DEGREE_SSE41) {
1883-    blake3_hash4_sse41(
1884-        inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out_bytes
1885-    );
1886-    if (increment_counter) {
1887-      counter += DEGREE_SSE41;
1888-    }
1889-    inputs += DEGREE_SSE41;
1890-    num_inputs -= DEGREE_SSE41;
1891-    out_bytes = &out_bytes[DEGREE_SSE41 * BLAKE3_OUT_LEN];
1892-  }
1893-  while (num_inputs > 0) {
1894-    hash_one_sse41(inputs[0], blocks, key, counter, flags, flags_start, flags_end, out_bytes);
1895-    if (increment_counter) {
1896-      counter += 1;
1897-    }
1898-    inputs += 1;
1899-    num_inputs -= 1;
1900-    out_bytes = &out_bytes[BLAKE3_OUT_LEN];
1901-  }
1902-}
1903-#if defined(__clang__)
1904-#pragma clang attribute pop
1905-#elif defined(__GNUC__)
1906-#pragma GCC pop_options
1907-#endif
1908-
1909-#if defined(__clang__)
1910-#pragma clang attribute push(__attribute__((target("avx2"))), apply_to = function)
1911-#elif defined(__GNUC__)
1912-#pragma GCC push_options
1913-#pragma GCC target("avx2")
1914-#endif
1915-#define DEGREE_AVX2 8
1916-
1917-static inline __m256i
1918-loadu_avx2(const uint8_t src[32])
1919-{
1920-  return _mm256_loadu_si256((const __m256i *)src);
1921-}
1922-
1923-static inline void
1924-storeu_avx2(__m256i src, uint8_t dest[32])
1925-{
1926-  _mm256_storeu_si256((__m256i *)dest, src);
1927-}
1928-
1929-static inline __m256i
1930-addv_avx2(__m256i a, __m256i b)
1931-{
1932-  return _mm256_add_epi32(a, b);
1933-}
1934-
1935-static inline __m256i
1936-xorv_avx2(__m256i a, __m256i b)
1937-{
1938-  return _mm256_xor_si256(a, b);
1939-}
1940-
1941-static inline __m256i
1942-set1_avx2(uint32_t x)
1943-{
1944-  return _mm256_set1_epi32((int32_t)x);
1945-}
1946-
1947-static inline __m256i
1948-rot16_avx2(__m256i x)
1949-{
1950-  return _mm256_shuffle_epi8(
1951-      x,
1952-      _mm256_set_epi8(
1953-          13,
1954-          12,
1955-          15,
1956-          14,
1957-          9,
1958-          8,
1959-          11,
1960-          10,
1961-          5,
1962-          4,
1963-          7,
1964-          6,
1965-          1,
1966-          0,
1967-          3,
1968-          2,
1969-          13,
1970-          12,
1971-          15,
1972-          14,
1973-          9,
1974-          8,
1975-          11,
1976-          10,
1977-          5,
1978-          4,
1979-          7,
1980-          6,
1981-          1,
1982-          0,
1983-          3,
1984-          2
1985-      )
1986-  );
1987-}
1988-
1989-static inline __m256i
1990-rot12_avx2(__m256i x)
1991-{
1992-  return _mm256_or_si256(_mm256_srli_epi32(x, 12), _mm256_slli_epi32(x, 32 - 12));
1993-}
1994-
1995-static inline __m256i
1996-rot8_avx2(__m256i x)
1997-{
1998-  return _mm256_shuffle_epi8(
1999-      x,
2000-      _mm256_set_epi8(
2001-          12,
2002-          15,
2003-          14,
2004-          13,
2005-          8,
2006-          11,
2007-          10,
2008-          9,
2009-          4,
2010-          7,
2011-          6,
2012-          5,
2013-          0,
2014-          3,
2015-          2,
2016-          1,
2017-          12,
2018-          15,
2019-          14,
2020-          13,
2021-          8,
2022-          11,
2023-          10,
2024-          9,
2025-          4,
2026-          7,
2027-          6,
2028-          5,
2029-          0,
2030-          3,
2031-          2,
2032-          1
2033-      )
2034-  );
2035-}
2036-
2037-static inline __m256i
2038-rot7_avx2(__m256i x)
2039-{
2040-  return _mm256_or_si256(_mm256_srli_epi32(x, 7), _mm256_slli_epi32(x, 32 - 7));
2041-}
2042-
2043-static inline void
2044-round_fn_avx2(__m256i v[16], __m256i m[16], size_t r)
2045-{
2046-  v[0]  = addv_avx2(v[0], m[(size_t)MSG_SCHEDULE[r][0]]);
2047-  v[1]  = addv_avx2(v[1], m[(size_t)MSG_SCHEDULE[r][2]]);
2048-  v[2]  = addv_avx2(v[2], m[(size_t)MSG_SCHEDULE[r][4]]);
2049-  v[3]  = addv_avx2(v[3], m[(size_t)MSG_SCHEDULE[r][6]]);
2050-  v[0]  = addv_avx2(v[0], v[4]);
2051-  v[1]  = addv_avx2(v[1], v[5]);
2052-  v[2]  = addv_avx2(v[2], v[6]);
2053-  v[3]  = addv_avx2(v[3], v[7]);
2054-  v[12] = xorv_avx2(v[12], v[0]);
2055-  v[13] = xorv_avx2(v[13], v[1]);
2056-  v[14] = xorv_avx2(v[14], v[2]);
2057-  v[15] = xorv_avx2(v[15], v[3]);
2058-  v[12] = rot16_avx2(v[12]);
2059-  v[13] = rot16_avx2(v[13]);
2060-  v[14] = rot16_avx2(v[14]);
2061-  v[15] = rot16_avx2(v[15]);
2062-  v[8]  = addv_avx2(v[8], v[12]);
2063-  v[9]  = addv_avx2(v[9], v[13]);
2064-  v[10] = addv_avx2(v[10], v[14]);
2065-  v[11] = addv_avx2(v[11], v[15]);
2066-  v[4]  = xorv_avx2(v[4], v[8]);
2067-  v[5]  = xorv_avx2(v[5], v[9]);
2068-  v[6]  = xorv_avx2(v[6], v[10]);
2069-  v[7]  = xorv_avx2(v[7], v[11]);
2070-  v[4]  = rot12_avx2(v[4]);
2071-  v[5]  = rot12_avx2(v[5]);
2072-  v[6]  = rot12_avx2(v[6]);
2073-  v[7]  = rot12_avx2(v[7]);
2074-  v[0]  = addv_avx2(v[0], m[(size_t)MSG_SCHEDULE[r][1]]);
2075-  v[1]  = addv_avx2(v[1], m[(size_t)MSG_SCHEDULE[r][3]]);
2076-  v[2]  = addv_avx2(v[2], m[(size_t)MSG_SCHEDULE[r][5]]);
2077-  v[3]  = addv_avx2(v[3], m[(size_t)MSG_SCHEDULE[r][7]]);
2078-  v[0]  = addv_avx2(v[0], v[4]);
2079-  v[1]  = addv_avx2(v[1], v[5]);
2080-  v[2]  = addv_avx2(v[2], v[6]);
2081-  v[3]  = addv_avx2(v[3], v[7]);
2082-  v[12] = xorv_avx2(v[12], v[0]);
2083-  v[13] = xorv_avx2(v[13], v[1]);
2084-  v[14] = xorv_avx2(v[14], v[2]);
2085-  v[15] = xorv_avx2(v[15], v[3]);
2086-  v[12] = rot8_avx2(v[12]);
2087-  v[13] = rot8_avx2(v[13]);
2088-  v[14] = rot8_avx2(v[14]);
2089-  v[15] = rot8_avx2(v[15]);
2090-  v[8]  = addv_avx2(v[8], v[12]);
2091-  v[9]  = addv_avx2(v[9], v[13]);
2092-  v[10] = addv_avx2(v[10], v[14]);
2093-  v[11] = addv_avx2(v[11], v[15]);
2094-  v[4]  = xorv_avx2(v[4], v[8]);
2095-  v[5]  = xorv_avx2(v[5], v[9]);
2096-  v[6]  = xorv_avx2(v[6], v[10]);
2097-  v[7]  = xorv_avx2(v[7], v[11]);
2098-  v[4]  = rot7_avx2(v[4]);
2099-  v[5]  = rot7_avx2(v[5]);
2100-  v[6]  = rot7_avx2(v[6]);
2101-  v[7]  = rot7_avx2(v[7]);
2102-
2103-  v[0]  = addv_avx2(v[0], m[(size_t)MSG_SCHEDULE[r][8]]);
2104-  v[1]  = addv_avx2(v[1], m[(size_t)MSG_SCHEDULE[r][10]]);
2105-  v[2]  = addv_avx2(v[2], m[(size_t)MSG_SCHEDULE[r][12]]);
2106-  v[3]  = addv_avx2(v[3], m[(size_t)MSG_SCHEDULE[r][14]]);
2107-  v[0]  = addv_avx2(v[0], v[5]);
2108-  v[1]  = addv_avx2(v[1], v[6]);
2109-  v[2]  = addv_avx2(v[2], v[7]);
2110-  v[3]  = addv_avx2(v[3], v[4]);
2111-  v[15] = xorv_avx2(v[15], v[0]);
2112-  v[12] = xorv_avx2(v[12], v[1]);
2113-  v[13] = xorv_avx2(v[13], v[2]);
2114-  v[14] = xorv_avx2(v[14], v[3]);
2115-  v[15] = rot16_avx2(v[15]);
2116-  v[12] = rot16_avx2(v[12]);
2117-  v[13] = rot16_avx2(v[13]);
2118-  v[14] = rot16_avx2(v[14]);
2119-  v[10] = addv_avx2(v[10], v[15]);
2120-  v[11] = addv_avx2(v[11], v[12]);
2121-  v[8]  = addv_avx2(v[8], v[13]);
2122-  v[9]  = addv_avx2(v[9], v[14]);
2123-  v[5]  = xorv_avx2(v[5], v[10]);
2124-  v[6]  = xorv_avx2(v[6], v[11]);
2125-  v[7]  = xorv_avx2(v[7], v[8]);
2126-  v[4]  = xorv_avx2(v[4], v[9]);
2127-  v[5]  = rot12_avx2(v[5]);
2128-  v[6]  = rot12_avx2(v[6]);
2129-  v[7]  = rot12_avx2(v[7]);
2130-  v[4]  = rot12_avx2(v[4]);
2131-  v[0]  = addv_avx2(v[0], m[(size_t)MSG_SCHEDULE[r][9]]);
2132-  v[1]  = addv_avx2(v[1], m[(size_t)MSG_SCHEDULE[r][11]]);
2133-  v[2]  = addv_avx2(v[2], m[(size_t)MSG_SCHEDULE[r][13]]);
2134-  v[3]  = addv_avx2(v[3], m[(size_t)MSG_SCHEDULE[r][15]]);
2135-  v[0]  = addv_avx2(v[0], v[5]);
2136-  v[1]  = addv_avx2(v[1], v[6]);
2137-  v[2]  = addv_avx2(v[2], v[7]);
2138-  v[3]  = addv_avx2(v[3], v[4]);
2139-  v[15] = xorv_avx2(v[15], v[0]);
2140-  v[12] = xorv_avx2(v[12], v[1]);
2141-  v[13] = xorv_avx2(v[13], v[2]);
2142-  v[14] = xorv_avx2(v[14], v[3]);
2143-  v[15] = rot8_avx2(v[15]);
2144-  v[12] = rot8_avx2(v[12]);
2145-  v[13] = rot8_avx2(v[13]);
2146-  v[14] = rot8_avx2(v[14]);
2147-  v[10] = addv_avx2(v[10], v[15]);
2148-  v[11] = addv_avx2(v[11], v[12]);
2149-  v[8]  = addv_avx2(v[8], v[13]);
2150-  v[9]  = addv_avx2(v[9], v[14]);
2151-  v[5]  = xorv_avx2(v[5], v[10]);
2152-  v[6]  = xorv_avx2(v[6], v[11]);
2153-  v[7]  = xorv_avx2(v[7], v[8]);
2154-  v[4]  = xorv_avx2(v[4], v[9]);
2155-  v[5]  = rot7_avx2(v[5]);
2156-  v[6]  = rot7_avx2(v[6]);
2157-  v[7]  = rot7_avx2(v[7]);
2158-  v[4]  = rot7_avx2(v[4]);
2159-}
2160-
2161-static inline void
2162-transpose_vecs_avx2(__m256i vecs[DEGREE_AVX2])
2163-{
2164-  __m256i ab_0145 = _mm256_unpacklo_epi32(vecs[0], vecs[1]);
2165-  __m256i ab_2367 = _mm256_unpackhi_epi32(vecs[0], vecs[1]);
2166-  __m256i cd_0145 = _mm256_unpacklo_epi32(vecs[2], vecs[3]);
2167-  __m256i cd_2367 = _mm256_unpackhi_epi32(vecs[2], vecs[3]);
2168-  __m256i ef_0145 = _mm256_unpacklo_epi32(vecs[4], vecs[5]);
2169-  __m256i ef_2367 = _mm256_unpackhi_epi32(vecs[4], vecs[5]);
2170-  __m256i gh_0145 = _mm256_unpacklo_epi32(vecs[6], vecs[7]);
2171-  __m256i gh_2367 = _mm256_unpackhi_epi32(vecs[6], vecs[7]);
2172-
2173-  __m256i abcd_04 = _mm256_unpacklo_epi64(ab_0145, cd_0145);
2174-  __m256i abcd_15 = _mm256_unpackhi_epi64(ab_0145, cd_0145);
2175-  __m256i abcd_26 = _mm256_unpacklo_epi64(ab_2367, cd_2367);
2176-  __m256i abcd_37 = _mm256_unpackhi_epi64(ab_2367, cd_2367);
2177-  __m256i efgh_04 = _mm256_unpacklo_epi64(ef_0145, gh_0145);
2178-  __m256i efgh_15 = _mm256_unpackhi_epi64(ef_0145, gh_0145);
2179-  __m256i efgh_26 = _mm256_unpacklo_epi64(ef_2367, gh_2367);
2180-  __m256i efgh_37 = _mm256_unpackhi_epi64(ef_2367, gh_2367);
2181-
2182-  vecs[0] = _mm256_permute2x128_si256(abcd_04, efgh_04, 0x20);
2183-  vecs[1] = _mm256_permute2x128_si256(abcd_15, efgh_15, 0x20);
2184-  vecs[2] = _mm256_permute2x128_si256(abcd_26, efgh_26, 0x20);
2185-  vecs[3] = _mm256_permute2x128_si256(abcd_37, efgh_37, 0x20);
2186-  vecs[4] = _mm256_permute2x128_si256(abcd_04, efgh_04, 0x31);
2187-  vecs[5] = _mm256_permute2x128_si256(abcd_15, efgh_15, 0x31);
2188-  vecs[6] = _mm256_permute2x128_si256(abcd_26, efgh_26, 0x31);
2189-  vecs[7] = _mm256_permute2x128_si256(abcd_37, efgh_37, 0x31);
2190-}
2191-
2192-static inline void
2193-transpose_msg_vecs_avx2(const uint8_t *const *inputs, size_t block_offset, __m256i out_msg[16])
2194-{
2195-  size_t i;
2196-
2197-  out_msg[0]  = loadu_avx2(&inputs[0][block_offset + 0 * sizeof(__m256i)]);
2198-  out_msg[1]  = loadu_avx2(&inputs[1][block_offset + 0 * sizeof(__m256i)]);
2199-  out_msg[2]  = loadu_avx2(&inputs[2][block_offset + 0 * sizeof(__m256i)]);
2200-  out_msg[3]  = loadu_avx2(&inputs[3][block_offset + 0 * sizeof(__m256i)]);
2201-  out_msg[4]  = loadu_avx2(&inputs[4][block_offset + 0 * sizeof(__m256i)]);
2202-  out_msg[5]  = loadu_avx2(&inputs[5][block_offset + 0 * sizeof(__m256i)]);
2203-  out_msg[6]  = loadu_avx2(&inputs[6][block_offset + 0 * sizeof(__m256i)]);
2204-  out_msg[7]  = loadu_avx2(&inputs[7][block_offset + 0 * sizeof(__m256i)]);
2205-  out_msg[8]  = loadu_avx2(&inputs[0][block_offset + 1 * sizeof(__m256i)]);
2206-  out_msg[9]  = loadu_avx2(&inputs[1][block_offset + 1 * sizeof(__m256i)]);
2207-  out_msg[10] = loadu_avx2(&inputs[2][block_offset + 1 * sizeof(__m256i)]);
2208-  out_msg[11] = loadu_avx2(&inputs[3][block_offset + 1 * sizeof(__m256i)]);
2209-  out_msg[12] = loadu_avx2(&inputs[4][block_offset + 1 * sizeof(__m256i)]);
2210-  out_msg[13] = loadu_avx2(&inputs[5][block_offset + 1 * sizeof(__m256i)]);
2211-  out_msg[14] = loadu_avx2(&inputs[6][block_offset + 1 * sizeof(__m256i)]);
2212-  out_msg[15] = loadu_avx2(&inputs[7][block_offset + 1 * sizeof(__m256i)]);
2213-
2214-  for (i = 0; i < 8; i++) {
2215-    _mm_prefetch((const void *)&inputs[i][block_offset + 256], _MM_HINT_T0);
2216-  }
2217-  transpose_vecs_avx2(&out_msg[0]);
2218-  transpose_vecs_avx2(&out_msg[8]);
2219-}
2220-
2221-static inline void
2222-load_counters_avx2(uint64_t counter, int increment_counter, __m256i *out_lo, __m256i *out_hi)
2223-{
2224-  const __m256i mask  = _mm256_set1_epi32(-increment_counter);
2225-  const __m256i add0  = _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0);
2226-  const __m256i add1  = _mm256_and_si256(mask, add0);
2227-  __m256i       l     = _mm256_add_epi32(_mm256_set1_epi32((int32_t)counter), add1);
2228-  __m256i       carry = _mm256_xor_si256(add1, _mm256_set1_epi32(0x80000000));
2229-  __m256i       comp  = _mm256_xor_si256(l, _mm256_set1_epi32(0x80000000));
2230-  __m256i       gt    = _mm256_cmpgt_epi32(carry, comp);
2231-  __m256i       h     = _mm256_sub_epi32(_mm256_set1_epi32((int32_t)(counter >> 32)), gt);
2232-
2233-  *out_lo = l;
2234-  *out_hi = h;
2235-}
2236-
2237-void
2238-blake3_hash8_avx2(
2239-    const uint8_t *const *inputs,
2240-    size_t                blocks,
2241-    const uint32_t        key[8],
2242-    uint64_t              counter,
2243-    int                   increment_counter,
2244-    uint8_t               flags,
2245-    uint8_t               flags_start,
2246-    uint8_t               flags_end,
2247-    uint8_t              *out_bytes
2248-)
2249-{
2250-  __m256i h_vecs[8];
2251-  __m256i counter_low_vec, counter_high_vec;
2252-  uint8_t block_flags;
2253-  size_t  block;
2254-
2255-  h_vecs[0] = set1_avx2(key[0]);
2256-  h_vecs[1] = set1_avx2(key[1]);
2257-  h_vecs[2] = set1_avx2(key[2]);
2258-  h_vecs[3] = set1_avx2(key[3]);
2259-  h_vecs[4] = set1_avx2(key[4]);
2260-  h_vecs[5] = set1_avx2(key[5]);
2261-  h_vecs[6] = set1_avx2(key[6]);
2262-  h_vecs[7] = set1_avx2(key[7]);
2263-
2264-  load_counters_avx2(counter, increment_counter, &counter_low_vec, &counter_high_vec);
2265-  block_flags = flags | flags_start;
2266-
2267-  for (block = 0; block < blocks; block++) {
2268-    __m256i block_len_vec;
2269-    __m256i block_flags_vec;
2270-    __m256i msg_vecs[16];
2271-    __m256i v[16];
2272-
2273-    if (block + 1 == blocks) {
2274-      block_flags |= flags_end;
2275-    }
2276-    block_len_vec   = set1_avx2(BLAKE3_BLOCK_LEN);
2277-    block_flags_vec = set1_avx2(block_flags);
2278-    transpose_msg_vecs_avx2(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs);
2279-
2280-    v[0]  = h_vecs[0];
2281-    v[1]  = h_vecs[1];
2282-    v[2]  = h_vecs[2];
2283-    v[3]  = h_vecs[3];
2284-    v[4]  = h_vecs[4];
2285-    v[5]  = h_vecs[5];
2286-    v[6]  = h_vecs[6];
2287-    v[7]  = h_vecs[7];
2288-    v[8]  = set1_avx2(IV[0]);
2289-    v[9]  = set1_avx2(IV[1]);
2290-    v[10] = set1_avx2(IV[2]);
2291-    v[11] = set1_avx2(IV[3]);
2292-    v[12] = counter_low_vec;
2293-    v[13] = counter_high_vec;
2294-    v[14] = block_len_vec;
2295-    v[15] = block_flags_vec;
2296-
2297-    round_fn_avx2(v, msg_vecs, 0);
2298-    round_fn_avx2(v, msg_vecs, 1);
2299-    round_fn_avx2(v, msg_vecs, 2);
2300-    round_fn_avx2(v, msg_vecs, 3);
2301-    round_fn_avx2(v, msg_vecs, 4);
2302-    round_fn_avx2(v, msg_vecs, 5);
2303-    round_fn_avx2(v, msg_vecs, 6);
2304-
2305-    h_vecs[0] = xorv_avx2(v[0], v[8]);
2306-    h_vecs[1] = xorv_avx2(v[1], v[9]);
2307-    h_vecs[2] = xorv_avx2(v[2], v[10]);
2308-    h_vecs[3] = xorv_avx2(v[3], v[11]);
2309-    h_vecs[4] = xorv_avx2(v[4], v[12]);
2310-    h_vecs[5] = xorv_avx2(v[5], v[13]);
2311-    h_vecs[6] = xorv_avx2(v[6], v[14]);
2312-    h_vecs[7] = xorv_avx2(v[7], v[15]);
2313-
2314-    block_flags = flags;
2315-  }
2316-
2317-  transpose_vecs_avx2(h_vecs);
2318-  storeu_avx2(h_vecs[0], &out_bytes[0 * sizeof(__m256i)]);
2319-  storeu_avx2(h_vecs[1], &out_bytes[1 * sizeof(__m256i)]);
2320-  storeu_avx2(h_vecs[2], &out_bytes[2 * sizeof(__m256i)]);
2321-  storeu_avx2(h_vecs[3], &out_bytes[3 * sizeof(__m256i)]);
2322-  storeu_avx2(h_vecs[4], &out_bytes[4 * sizeof(__m256i)]);
2323-  storeu_avx2(h_vecs[5], &out_bytes[5 * sizeof(__m256i)]);
2324-  storeu_avx2(h_vecs[6], &out_bytes[6 * sizeof(__m256i)]);
2325-  storeu_avx2(h_vecs[7], &out_bytes[7 * sizeof(__m256i)]);
2326-}
2327-
2328-void
2329-blake3_hash_many_avx2(
2330-    const uint8_t *const *inputs,
2331-    size_t                num_inputs,
2332-    size_t                blocks,
2333-    const uint32_t        key[8],
2334-    uint64_t              counter,
2335-    int                   increment_counter,
2336-    uint8_t               flags,
2337-    uint8_t               flags_start,
2338-    uint8_t               flags_end,
2339-    uint8_t              *out_bytes
2340-)
2341-{
2342-  while (num_inputs >= DEGREE_AVX2) {
2343-    blake3_hash8_avx2(
2344-        inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out_bytes
2345-    );
2346-    if (increment_counter) {
2347-      counter += DEGREE_AVX2;
2348-    }
2349-    inputs += DEGREE_AVX2;
2350-    num_inputs -= DEGREE_AVX2;
2351-    out_bytes = &out_bytes[DEGREE_AVX2 * BLAKE3_OUT_LEN];
2352-  }
2353-  blake3_hash_many_sse41(
2354-      inputs,
2355-      num_inputs,
2356-      blocks,
2357-      key,
2358-      counter,
2359-      increment_counter,
2360-      flags,
2361-      flags_start,
2362-      flags_end,
2363-      out_bytes
2364-  );
2365-}
2366-#if defined(__clang__)
2367-#pragma clang attribute pop
2368-#elif defined(__GNUC__)
2369-#pragma GCC pop_options
2370-#endif
2371-
2372-#if defined(__clang__)
2373-#pragma clang attribute push(__attribute__((target("avx512f,avx512vl"))), apply_to = function)
2374-#elif defined(__GNUC__)
2375-#pragma GCC push_options
2376-#pragma GCC target("avx512f,avx512vl")
2377-#endif
2378-static inline __m128i
2379-loadu_128_avx512(const uint8_t src[16])
2380-{
2381-  return _mm_loadu_si128((const __m128i *)src);
2382-}
2383-
2384-static inline __m256i
2385-loadu_256_avx512(const uint8_t src[32])
2386-{
2387-  return _mm256_loadu_si256((const __m256i *)src);
2388-}
2389-
2390-static inline __m512i
2391-loadu_512_avx512(const uint8_t src[64])
2392-{
2393-  return _mm512_loadu_si512((const __m512i *)src);
2394-}
2395-
2396-static inline void
2397-storeu_128_avx512(__m128i src, uint8_t dest[16])
2398-{
2399-  _mm_storeu_si128((__m128i *)dest, src);
2400-}
2401-
2402-static inline void
2403-storeu_256_avx512(__m256i src, uint8_t dest[32])
2404-{
2405-  _mm256_storeu_si256((__m256i *)dest, src);
2406-}
2407-
2408-static inline __m128i
2409-add_128_avx512(__m128i a, __m128i b)
2410-{
2411-  return _mm_add_epi32(a, b);
2412-}
2413-
2414-static inline __m256i
2415-add_256_avx512(__m256i a, __m256i b)
2416-{
2417-  return _mm256_add_epi32(a, b);
2418-}
2419-
2420-static inline __m512i
2421-add_512_avx512(__m512i a, __m512i b)
2422-{
2423-  return _mm512_add_epi32(a, b);
2424-}
2425-
2426-static inline __m128i
2427-xor_128_avx512(__m128i a, __m128i b)
2428-{
2429-  return _mm_xor_si128(a, b);
2430-}
2431-
2432-static inline __m256i
2433-xor_256_avx512(__m256i a, __m256i b)
2434-{
2435-  return _mm256_xor_si256(a, b);
2436-}
2437-
2438-static inline __m512i
2439-xor_512_avx512(__m512i a, __m512i b)
2440-{
2441-  return _mm512_xor_si512(a, b);
2442-}
2443-
2444-static inline __m128i
2445-set1_128_avx512(uint32_t x)
2446-{
2447-  return _mm_set1_epi32((int32_t)x);
2448-}
2449-
2450-static inline __m256i
2451-set1_256_avx512(uint32_t x)
2452-{
2453-  return _mm256_set1_epi32((int32_t)x);
2454-}
2455-
2456-static inline __m512i
2457-set1_512_avx512(uint32_t x)
2458-{
2459-  return _mm512_set1_epi32((int32_t)x);
2460-}
2461-
2462-static inline __m128i
2463-set4_avx512(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
2464-{
2465-  return _mm_setr_epi32((int32_t)a, (int32_t)b, (int32_t)c, (int32_t)d);
2466-}
2467-
2468-static inline __m128i
2469-rot16_128_avx512(__m128i x)
2470-{
2471-  return _mm_ror_epi32(x, 16);
2472-}
2473-
2474-static inline __m256i
2475-rot16_256_avx512(__m256i x)
2476-{
2477-  return _mm256_ror_epi32(x, 16);
2478-}
2479-
2480-static inline __m512i
2481-rot16_512_avx512(__m512i x)
2482-{
2483-  return _mm512_ror_epi32(x, 16);
2484-}
2485-
2486-static inline __m128i
2487-rot12_128_avx512(__m128i x)
2488-{
2489-  return _mm_ror_epi32(x, 12);
2490-}
2491-
2492-static inline __m256i
2493-rot12_256_avx512(__m256i x)
2494-{
2495-  return _mm256_ror_epi32(x, 12);
2496-}
2497-
2498-static inline __m512i
2499-rot12_512_avx512(__m512i x)
2500-{
2501-  return _mm512_ror_epi32(x, 12);
2502-}
2503-
2504-static inline __m128i
2505-rot8_128_avx512(__m128i x)
2506-{
2507-  return _mm_ror_epi32(x, 8);
2508-}
2509-
2510-static inline __m256i
2511-rot8_256_avx512(__m256i x)
2512-{
2513-  return _mm256_ror_epi32(x, 8);
2514-}
2515-
2516-static inline __m512i
2517-rot8_512_avx512(__m512i x)
2518-{
2519-  return _mm512_ror_epi32(x, 8);
2520-}
2521-
2522-static inline __m128i
2523-rot7_128_avx512(__m128i x)
2524-{
2525-  return _mm_ror_epi32(x, 7);
2526-}
2527-
2528-static inline __m256i
2529-rot7_256_avx512(__m256i x)
2530-{
2531-  return _mm256_ror_epi32(x, 7);
2532-}
2533-
2534-static inline __m512i
2535-rot7_512_avx512(__m512i x)
2536-{
2537-  return _mm512_ror_epi32(x, 7);
2538-}
2539-
2540-static inline void
2541-g1_avx512(__m128i *row0, __m128i *row1, __m128i *row2, __m128i *row3, __m128i m)
2542-{
2543-  *row0 = add_128_avx512(add_128_avx512(*row0, m), *row1);
2544-  *row3 = xor_128_avx512(*row3, *row0);
2545-  *row3 = rot16_128_avx512(*row3);
2546-  *row2 = add_128_avx512(*row2, *row3);
2547-  *row1 = xor_128_avx512(*row1, *row2);
2548-  *row1 = rot12_128_avx512(*row1);
2549-}
2550-
2551-static inline void
2552-g2_avx512(__m128i *row0, __m128i *row1, __m128i *row2, __m128i *row3, __m128i m)
2553-{
2554-  *row0 = add_128_avx512(add_128_avx512(*row0, m), *row1);
2555-  *row3 = xor_128_avx512(*row3, *row0);
2556-  *row3 = rot8_128_avx512(*row3);
2557-  *row2 = add_128_avx512(*row2, *row3);
2558-  *row1 = xor_128_avx512(*row1, *row2);
2559-  *row1 = rot7_128_avx512(*row1);
2560-}
2561-
2562-static inline void
2563-diagonalize_avx512(__m128i *row0, __m128i *row2, __m128i *row3)
2564-{
2565-  *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE(2, 1, 0, 3));
2566-  *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE(1, 0, 3, 2));
2567-  *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE(0, 3, 2, 1));
2568-}
2569-
2570-static inline void
2571-undiagonalize_avx512(__m128i *row0, __m128i *row2, __m128i *row3)
2572-{
2573-  *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE(0, 3, 2, 1));
2574-  *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE(1, 0, 3, 2));
2575-  *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE(2, 1, 0, 3));
2576-}
2577-
2578-static inline void
2579-compress_pre_avx512(
2580-    __m128i        rows[4],
2581-    const uint32_t cv[8],
2582-    const uint8_t  block[BLAKE3_BLOCK_LEN],
2583-    uint8_t        block_len,
2584-    uint64_t       counter,
2585-    uint8_t        flags
2586-)
2587-{
2588-  __m128i m0, m1, m2, m3;
2589-  __m128i t0, t1, t2, t3;
2590-
2591-  rows[0] = loadu_128_avx512((const uint8_t *)&cv[0]);
2592-  rows[1] = loadu_128_avx512((const uint8_t *)&cv[4]);
2593-  rows[2] = set4_avx512(IV[0], IV[1], IV[2], IV[3]);
2594-  rows[3] = set4_avx512(
2595-      counter_low(counter), counter_high(counter), (uint32_t)block_len, (uint32_t)flags
2596-  );
2597-
2598-  m0 = loadu_128_avx512(&block[sizeof(__m128i) * 0]);
2599-  m1 = loadu_128_avx512(&block[sizeof(__m128i) * 1]);
2600-  m2 = loadu_128_avx512(&block[sizeof(__m128i) * 2]);
2601-  m3 = loadu_128_avx512(&block[sizeof(__m128i) * 3]);
2602-
2603-  /* round 1 */
2604-  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(2, 0, 2, 0));
2605-  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t0);
2606-  t1 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 3, 1));
2607-  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t1);
2608-  diagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2609-  t2 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(2, 0, 2, 0));
2610-  t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2, 1, 0, 3));
2611-  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t2);
2612-  t3 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 1, 3, 1));
2613-  t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(2, 1, 0, 3));
2614-  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t3);
2615-  undiagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2616-  m0 = t0;
2617-  m1 = t1;
2618-  m2 = t2;
2619-  m3 = t3;
2620-
2621-  /* round 2 */
2622-  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
2623-  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
2624-  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t0);
2625-  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
2626-  t1 = _mm_blend_epi16(m0, t1, 0xCC);
2627-  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t1);
2628-  diagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2629-  t2 = _mm_unpacklo_epi64(m3, m1);
2630-  t2 = _mm_blend_epi16(t2, m2, 0xC0);
2631-  t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1, 3, 2, 0));
2632-  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t2);
2633-  t3 = _mm_unpackhi_epi32(m1, m3);
2634-  t3 = _mm_unpacklo_epi32(m2, t3);
2635-  t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(0, 1, 3, 2));
2636-  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t3);
2637-  undiagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2638-  m0 = t0;
2639-  m1 = t1;
2640-  m2 = t2;
2641-  m3 = t3;
2642-
2643-  /* round 3 */
2644-  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
2645-  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
2646-  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t0);
2647-  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
2648-  t1 = _mm_blend_epi16(m0, t1, 0xCC);
2649-  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t1);
2650-  diagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2651-  t2 = _mm_unpacklo_epi64(m3, m1);
2652-  t2 = _mm_blend_epi16(t2, m2, 0xC0);
2653-  t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1, 3, 2, 0));
2654-  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t2);
2655-  t3 = _mm_unpackhi_epi32(m1, m3);
2656-  t3 = _mm_unpacklo_epi32(m2, t3);
2657-  t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(0, 1, 3, 2));
2658-  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t3);
2659-  undiagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2660-  m0 = t0;
2661-  m1 = t1;
2662-  m2 = t2;
2663-  m3 = t3;
2664-
2665-  /* round 4 */
2666-  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
2667-  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
2668-  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t0);
2669-  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
2670-  t1 = _mm_blend_epi16(m0, t1, 0xCC);
2671-  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t1);
2672-  diagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2673-  t2 = _mm_unpacklo_epi64(m3, m1);
2674-  t2 = _mm_blend_epi16(t2, m2, 0xC0);
2675-  t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1, 3, 2, 0));
2676-  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t2);
2677-  t3 = _mm_unpackhi_epi32(m1, m3);
2678-  t3 = _mm_unpacklo_epi32(m2, t3);
2679-  t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(0, 1, 3, 2));
2680-  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t3);
2681-  undiagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2682-  m0 = t0;
2683-  m1 = t1;
2684-  m2 = t2;
2685-  m3 = t3;
2686-
2687-  /* round 5 */
2688-  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
2689-  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
2690-  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t0);
2691-  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
2692-  t1 = _mm_blend_epi16(m0, t1, 0xCC);
2693-  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t1);
2694-  diagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2695-  t2 = _mm_unpacklo_epi64(m3, m1);
2696-  t2 = _mm_blend_epi16(t2, m2, 0xC0);
2697-  t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1, 3, 2, 0));
2698-  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t2);
2699-  t3 = _mm_unpackhi_epi32(m1, m3);
2700-  t3 = _mm_unpacklo_epi32(m2, t3);
2701-  t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(0, 1, 3, 2));
2702-  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t3);
2703-  undiagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2704-  m0 = t0;
2705-  m1 = t1;
2706-  m2 = t2;
2707-  m3 = t3;
2708-
2709-  /* round 6 */
2710-  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
2711-  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
2712-  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t0);
2713-  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
2714-  t1 = _mm_blend_epi16(m0, t1, 0xCC);
2715-  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t1);
2716-  diagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2717-  t2 = _mm_unpacklo_epi64(m3, m1);
2718-  t2 = _mm_blend_epi16(t2, m2, 0xC0);
2719-  t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1, 3, 2, 0));
2720-  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t2);
2721-  t3 = _mm_unpackhi_epi32(m1, m3);
2722-  t3 = _mm_unpacklo_epi32(m2, t3);
2723-  t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(0, 1, 3, 2));
2724-  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t3);
2725-  undiagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2726-  m0 = t0;
2727-  m1 = t1;
2728-  m2 = t2;
2729-  m3 = t3;
2730-
2731-  /* round 7 */
2732-  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
2733-  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
2734-  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t0);
2735-  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
2736-  t1 = _mm_blend_epi16(m0, t1, 0xCC);
2737-  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t1);
2738-  diagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2739-  t2 = _mm_unpacklo_epi64(m3, m1);
2740-  t2 = _mm_blend_epi16(t2, m2, 0xC0);
2741-  t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1, 3, 2, 0));
2742-  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t2);
2743-  t3 = _mm_unpackhi_epi32(m1, m3);
2744-  t3 = _mm_unpacklo_epi32(m2, t3);
2745-  t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(0, 1, 3, 2));
2746-  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t3);
2747-  undiagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2748-}
2749-
2750-void
2751-blake3_compress_in_place_avx512(
2752-    uint32_t      cv[8],
2753-    const uint8_t block[BLAKE3_BLOCK_LEN],
2754-    uint8_t       block_len,
2755-    uint64_t      counter,
2756-    uint8_t       flags
2757-)
2758-{
2759-  __m128i rows[4];
2760-
2761-  compress_pre_avx512(rows, cv, block, block_len, counter, flags);
2762-  storeu_128_avx512(xor_128_avx512(rows[0], rows[2]), (uint8_t *)&cv[0]);
2763-  storeu_128_avx512(xor_128_avx512(rows[1], rows[3]), (uint8_t *)&cv[4]);
2764-}
2765-
2766-void
2767-blake3_compress_xof_avx512(
2768-    const uint32_t cv[8],
2769-    const uint8_t  block[BLAKE3_BLOCK_LEN],
2770-    uint8_t        block_len,
2771-    uint64_t       counter,
2772-    uint8_t        flags,
2773-    uint8_t        out_buf[64]
2774-)
2775-{
2776-  __m128i rows[4];
2777-
2778-  compress_pre_avx512(rows, cv, block, block_len, counter, flags);
2779-  storeu_128_avx512(xor_128_avx512(rows[0], rows[2]), &out_buf[0]);
2780-  storeu_128_avx512(xor_128_avx512(rows[1], rows[3]), &out_buf[16]);
2781-  storeu_128_avx512(
2782-      xor_128_avx512(rows[2], loadu_128_avx512((const uint8_t *)&cv[0])), &out_buf[32]
2783-  );
2784-  storeu_128_avx512(
2785-      xor_128_avx512(rows[3], loadu_128_avx512((const uint8_t *)&cv[4])), &out_buf[48]
2786-  );
2787-}
2788-
2789-static inline void
2790-round_fn4_avx512(__m128i v[16], __m128i m[16], size_t r)
2791-{
2792-  v[0]  = add_128_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][0]]);
2793-  v[1]  = add_128_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][2]]);
2794-  v[2]  = add_128_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][4]]);
2795-  v[3]  = add_128_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][6]]);
2796-  v[0]  = add_128_avx512(v[0], v[4]);
2797-  v[1]  = add_128_avx512(v[1], v[5]);
2798-  v[2]  = add_128_avx512(v[2], v[6]);
2799-  v[3]  = add_128_avx512(v[3], v[7]);
2800-  v[12] = xor_128_avx512(v[12], v[0]);
2801-  v[13] = xor_128_avx512(v[13], v[1]);
2802-  v[14] = xor_128_avx512(v[14], v[2]);
2803-  v[15] = xor_128_avx512(v[15], v[3]);
2804-  v[12] = rot16_128_avx512(v[12]);
2805-  v[13] = rot16_128_avx512(v[13]);
2806-  v[14] = rot16_128_avx512(v[14]);
2807-  v[15] = rot16_128_avx512(v[15]);
2808-  v[8]  = add_128_avx512(v[8], v[12]);
2809-  v[9]  = add_128_avx512(v[9], v[13]);
2810-  v[10] = add_128_avx512(v[10], v[14]);
2811-  v[11] = add_128_avx512(v[11], v[15]);
2812-  v[4]  = xor_128_avx512(v[4], v[8]);
2813-  v[5]  = xor_128_avx512(v[5], v[9]);
2814-  v[6]  = xor_128_avx512(v[6], v[10]);
2815-  v[7]  = xor_128_avx512(v[7], v[11]);
2816-  v[4]  = rot12_128_avx512(v[4]);
2817-  v[5]  = rot12_128_avx512(v[5]);
2818-  v[6]  = rot12_128_avx512(v[6]);
2819-  v[7]  = rot12_128_avx512(v[7]);
2820-  v[0]  = add_128_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][1]]);
2821-  v[1]  = add_128_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][3]]);
2822-  v[2]  = add_128_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][5]]);
2823-  v[3]  = add_128_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][7]]);
2824-  v[0]  = add_128_avx512(v[0], v[4]);
2825-  v[1]  = add_128_avx512(v[1], v[5]);
2826-  v[2]  = add_128_avx512(v[2], v[6]);
2827-  v[3]  = add_128_avx512(v[3], v[7]);
2828-  v[12] = xor_128_avx512(v[12], v[0]);
2829-  v[13] = xor_128_avx512(v[13], v[1]);
2830-  v[14] = xor_128_avx512(v[14], v[2]);
2831-  v[15] = xor_128_avx512(v[15], v[3]);
2832-  v[12] = rot8_128_avx512(v[12]);
2833-  v[13] = rot8_128_avx512(v[13]);
2834-  v[14] = rot8_128_avx512(v[14]);
2835-  v[15] = rot8_128_avx512(v[15]);
2836-  v[8]  = add_128_avx512(v[8], v[12]);
2837-  v[9]  = add_128_avx512(v[9], v[13]);
2838-  v[10] = add_128_avx512(v[10], v[14]);
2839-  v[11] = add_128_avx512(v[11], v[15]);
2840-  v[4]  = xor_128_avx512(v[4], v[8]);
2841-  v[5]  = xor_128_avx512(v[5], v[9]);
2842-  v[6]  = xor_128_avx512(v[6], v[10]);
2843-  v[7]  = xor_128_avx512(v[7], v[11]);
2844-  v[4]  = rot7_128_avx512(v[4]);
2845-  v[5]  = rot7_128_avx512(v[5]);
2846-  v[6]  = rot7_128_avx512(v[6]);
2847-  v[7]  = rot7_128_avx512(v[7]);
2848-
2849-  v[0]  = add_128_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][8]]);
2850-  v[1]  = add_128_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][10]]);
2851-  v[2]  = add_128_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][12]]);
2852-  v[3]  = add_128_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][14]]);
2853-  v[0]  = add_128_avx512(v[0], v[5]);
2854-  v[1]  = add_128_avx512(v[1], v[6]);
2855-  v[2]  = add_128_avx512(v[2], v[7]);
2856-  v[3]  = add_128_avx512(v[3], v[4]);
2857-  v[15] = xor_128_avx512(v[15], v[0]);
2858-  v[12] = xor_128_avx512(v[12], v[1]);
2859-  v[13] = xor_128_avx512(v[13], v[2]);
2860-  v[14] = xor_128_avx512(v[14], v[3]);
2861-  v[15] = rot16_128_avx512(v[15]);
2862-  v[12] = rot16_128_avx512(v[12]);
2863-  v[13] = rot16_128_avx512(v[13]);
2864-  v[14] = rot16_128_avx512(v[14]);
2865-  v[10] = add_128_avx512(v[10], v[15]);
2866-  v[11] = add_128_avx512(v[11], v[12]);
2867-  v[8]  = add_128_avx512(v[8], v[13]);
2868-  v[9]  = add_128_avx512(v[9], v[14]);
2869-  v[5]  = xor_128_avx512(v[5], v[10]);
2870-  v[6]  = xor_128_avx512(v[6], v[11]);
2871-  v[7]  = xor_128_avx512(v[7], v[8]);
2872-  v[4]  = xor_128_avx512(v[4], v[9]);
2873-  v[5]  = rot12_128_avx512(v[5]);
2874-  v[6]  = rot12_128_avx512(v[6]);
2875-  v[7]  = rot12_128_avx512(v[7]);
2876-  v[4]  = rot12_128_avx512(v[4]);
2877-  v[0]  = add_128_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][9]]);
2878-  v[1]  = add_128_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][11]]);
2879-  v[2]  = add_128_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][13]]);
2880-  v[3]  = add_128_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][15]]);
2881-  v[0]  = add_128_avx512(v[0], v[5]);
2882-  v[1]  = add_128_avx512(v[1], v[6]);
2883-  v[2]  = add_128_avx512(v[2], v[7]);
2884-  v[3]  = add_128_avx512(v[3], v[4]);
2885-  v[15] = xor_128_avx512(v[15], v[0]);
2886-  v[12] = xor_128_avx512(v[12], v[1]);
2887-  v[13] = xor_128_avx512(v[13], v[2]);
2888-  v[14] = xor_128_avx512(v[14], v[3]);
2889-  v[15] = rot8_128_avx512(v[15]);
2890-  v[12] = rot8_128_avx512(v[12]);
2891-  v[13] = rot8_128_avx512(v[13]);
2892-  v[14] = rot8_128_avx512(v[14]);
2893-  v[10] = add_128_avx512(v[10], v[15]);
2894-  v[11] = add_128_avx512(v[11], v[12]);
2895-  v[8]  = add_128_avx512(v[8], v[13]);
2896-  v[9]  = add_128_avx512(v[9], v[14]);
2897-  v[5]  = xor_128_avx512(v[5], v[10]);
2898-  v[6]  = xor_128_avx512(v[6], v[11]);
2899-  v[7]  = xor_128_avx512(v[7], v[8]);
2900-  v[4]  = xor_128_avx512(v[4], v[9]);
2901-  v[5]  = rot7_128_avx512(v[5]);
2902-  v[6]  = rot7_128_avx512(v[6]);
2903-  v[7]  = rot7_128_avx512(v[7]);
2904-  v[4]  = rot7_128_avx512(v[4]);
2905-}
2906-
2907-static inline void
2908-round_fn8_avx512(__m256i v[16], __m256i m[16], size_t r)
2909-{
2910-  v[0]  = add_256_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][0]]);
2911-  v[1]  = add_256_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][2]]);
2912-  v[2]  = add_256_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][4]]);
2913-  v[3]  = add_256_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][6]]);
2914-  v[0]  = add_256_avx512(v[0], v[4]);
2915-  v[1]  = add_256_avx512(v[1], v[5]);
2916-  v[2]  = add_256_avx512(v[2], v[6]);
2917-  v[3]  = add_256_avx512(v[3], v[7]);
2918-  v[12] = xor_256_avx512(v[12], v[0]);
2919-  v[13] = xor_256_avx512(v[13], v[1]);
2920-  v[14] = xor_256_avx512(v[14], v[2]);
2921-  v[15] = xor_256_avx512(v[15], v[3]);
2922-  v[12] = rot16_256_avx512(v[12]);
2923-  v[13] = rot16_256_avx512(v[13]);
2924-  v[14] = rot16_256_avx512(v[14]);
2925-  v[15] = rot16_256_avx512(v[15]);
2926-  v[8]  = add_256_avx512(v[8], v[12]);
2927-  v[9]  = add_256_avx512(v[9], v[13]);
2928-  v[10] = add_256_avx512(v[10], v[14]);
2929-  v[11] = add_256_avx512(v[11], v[15]);
2930-  v[4]  = xor_256_avx512(v[4], v[8]);
2931-  v[5]  = xor_256_avx512(v[5], v[9]);
2932-  v[6]  = xor_256_avx512(v[6], v[10]);
2933-  v[7]  = xor_256_avx512(v[7], v[11]);
2934-  v[4]  = rot12_256_avx512(v[4]);
2935-  v[5]  = rot12_256_avx512(v[5]);
2936-  v[6]  = rot12_256_avx512(v[6]);
2937-  v[7]  = rot12_256_avx512(v[7]);
2938-  v[0]  = add_256_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][1]]);
2939-  v[1]  = add_256_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][3]]);
2940-  v[2]  = add_256_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][5]]);
2941-  v[3]  = add_256_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][7]]);
2942-  v[0]  = add_256_avx512(v[0], v[4]);
2943-  v[1]  = add_256_avx512(v[1], v[5]);
2944-  v[2]  = add_256_avx512(v[2], v[6]);
2945-  v[3]  = add_256_avx512(v[3], v[7]);
2946-  v[12] = xor_256_avx512(v[12], v[0]);
2947-  v[13] = xor_256_avx512(v[13], v[1]);
2948-  v[14] = xor_256_avx512(v[14], v[2]);
2949-  v[15] = xor_256_avx512(v[15], v[3]);
2950-  v[12] = rot8_256_avx512(v[12]);
2951-  v[13] = rot8_256_avx512(v[13]);
2952-  v[14] = rot8_256_avx512(v[14]);
2953-  v[15] = rot8_256_avx512(v[15]);
2954-  v[8]  = add_256_avx512(v[8], v[12]);
2955-  v[9]  = add_256_avx512(v[9], v[13]);
2956-  v[10] = add_256_avx512(v[10], v[14]);
2957-  v[11] = add_256_avx512(v[11], v[15]);
2958-  v[4]  = xor_256_avx512(v[4], v[8]);
2959-  v[5]  = xor_256_avx512(v[5], v[9]);
2960-  v[6]  = xor_256_avx512(v[6], v[10]);
2961-  v[7]  = xor_256_avx512(v[7], v[11]);
2962-  v[4]  = rot7_256_avx512(v[4]);
2963-  v[5]  = rot7_256_avx512(v[5]);
2964-  v[6]  = rot7_256_avx512(v[6]);
2965-  v[7]  = rot7_256_avx512(v[7]);
2966-
2967-  v[0]  = add_256_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][8]]);
2968-  v[1]  = add_256_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][10]]);
2969-  v[2]  = add_256_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][12]]);
2970-  v[3]  = add_256_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][14]]);
2971-  v[0]  = add_256_avx512(v[0], v[5]);
2972-  v[1]  = add_256_avx512(v[1], v[6]);
2973-  v[2]  = add_256_avx512(v[2], v[7]);
2974-  v[3]  = add_256_avx512(v[3], v[4]);
2975-  v[15] = xor_256_avx512(v[15], v[0]);
2976-  v[12] = xor_256_avx512(v[12], v[1]);
2977-  v[13] = xor_256_avx512(v[13], v[2]);
2978-  v[14] = xor_256_avx512(v[14], v[3]);
2979-  v[15] = rot16_256_avx512(v[15]);
2980-  v[12] = rot16_256_avx512(v[12]);
2981-  v[13] = rot16_256_avx512(v[13]);
2982-  v[14] = rot16_256_avx512(v[14]);
2983-  v[10] = add_256_avx512(v[10], v[15]);
2984-  v[11] = add_256_avx512(v[11], v[12]);
2985-  v[8]  = add_256_avx512(v[8], v[13]);
2986-  v[9]  = add_256_avx512(v[9], v[14]);
2987-  v[5]  = xor_256_avx512(v[5], v[10]);
2988-  v[6]  = xor_256_avx512(v[6], v[11]);
2989-  v[7]  = xor_256_avx512(v[7], v[8]);
2990-  v[4]  = xor_256_avx512(v[4], v[9]);
2991-  v[5]  = rot12_256_avx512(v[5]);
2992-  v[6]  = rot12_256_avx512(v[6]);
2993-  v[7]  = rot12_256_avx512(v[7]);
2994-  v[4]  = rot12_256_avx512(v[4]);
2995-  v[0]  = add_256_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][9]]);
2996-  v[1]  = add_256_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][11]]);
2997-  v[2]  = add_256_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][13]]);
2998-  v[3]  = add_256_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][15]]);
2999-  v[0]  = add_256_avx512(v[0], v[5]);
3000-  v[1]  = add_256_avx512(v[1], v[6]);
3001-  v[2]  = add_256_avx512(v[2], v[7]);
3002-  v[3]  = add_256_avx512(v[3], v[4]);
3003-  v[15] = xor_256_avx512(v[15], v[0]);
3004-  v[12] = xor_256_avx512(v[12], v[1]);
3005-  v[13] = xor_256_avx512(v[13], v[2]);
3006-  v[14] = xor_256_avx512(v[14], v[3]);
3007-  v[15] = rot8_256_avx512(v[15]);
3008-  v[12] = rot8_256_avx512(v[12]);
3009-  v[13] = rot8_256_avx512(v[13]);
3010-  v[14] = rot8_256_avx512(v[14]);
3011-  v[10] = add_256_avx512(v[10], v[15]);
3012-  v[11] = add_256_avx512(v[11], v[12]);
3013-  v[8]  = add_256_avx512(v[8], v[13]);
3014-  v[9]  = add_256_avx512(v[9], v[14]);
3015-  v[5]  = xor_256_avx512(v[5], v[10]);
3016-  v[6]  = xor_256_avx512(v[6], v[11]);
3017-  v[7]  = xor_256_avx512(v[7], v[8]);
3018-  v[4]  = xor_256_avx512(v[4], v[9]);
3019-  v[5]  = rot7_256_avx512(v[5]);
3020-  v[6]  = rot7_256_avx512(v[6]);
3021-  v[7]  = rot7_256_avx512(v[7]);
3022-  v[4]  = rot7_256_avx512(v[4]);
3023-}
3024-
3025-static inline void
3026-round_fn16_avx512(__m512i v[16], __m512i m[16], size_t r)
3027-{
3028-  v[0]  = add_512_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][0]]);
3029-  v[1]  = add_512_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][2]]);
3030-  v[2]  = add_512_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][4]]);
3031-  v[3]  = add_512_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][6]]);
3032-  v[0]  = add_512_avx512(v[0], v[4]);
3033-  v[1]  = add_512_avx512(v[1], v[5]);
3034-  v[2]  = add_512_avx512(v[2], v[6]);
3035-  v[3]  = add_512_avx512(v[3], v[7]);
3036-  v[12] = xor_512_avx512(v[12], v[0]);
3037-  v[13] = xor_512_avx512(v[13], v[1]);
3038-  v[14] = xor_512_avx512(v[14], v[2]);
3039-  v[15] = xor_512_avx512(v[15], v[3]);
3040-  v[12] = rot16_512_avx512(v[12]);
3041-  v[13] = rot16_512_avx512(v[13]);
3042-  v[14] = rot16_512_avx512(v[14]);
3043-  v[15] = rot16_512_avx512(v[15]);
3044-  v[8]  = add_512_avx512(v[8], v[12]);
3045-  v[9]  = add_512_avx512(v[9], v[13]);
3046-  v[10] = add_512_avx512(v[10], v[14]);
3047-  v[11] = add_512_avx512(v[11], v[15]);
3048-  v[4]  = xor_512_avx512(v[4], v[8]);
3049-  v[5]  = xor_512_avx512(v[5], v[9]);
3050-  v[6]  = xor_512_avx512(v[6], v[10]);
3051-  v[7]  = xor_512_avx512(v[7], v[11]);
3052-  v[4]  = rot12_512_avx512(v[4]);
3053-  v[5]  = rot12_512_avx512(v[5]);
3054-  v[6]  = rot12_512_avx512(v[6]);
3055-  v[7]  = rot12_512_avx512(v[7]);
3056-  v[0]  = add_512_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][1]]);
3057-  v[1]  = add_512_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][3]]);
3058-  v[2]  = add_512_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][5]]);
3059-  v[3]  = add_512_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][7]]);
3060-  v[0]  = add_512_avx512(v[0], v[4]);
3061-  v[1]  = add_512_avx512(v[1], v[5]);
3062-  v[2]  = add_512_avx512(v[2], v[6]);
3063-  v[3]  = add_512_avx512(v[3], v[7]);
3064-  v[12] = xor_512_avx512(v[12], v[0]);
3065-  v[13] = xor_512_avx512(v[13], v[1]);
3066-  v[14] = xor_512_avx512(v[14], v[2]);
3067-  v[15] = xor_512_avx512(v[15], v[3]);
3068-  v[12] = rot8_512_avx512(v[12]);
3069-  v[13] = rot8_512_avx512(v[13]);
3070-  v[14] = rot8_512_avx512(v[14]);
3071-  v[15] = rot8_512_avx512(v[15]);
3072-  v[8]  = add_512_avx512(v[8], v[12]);
3073-  v[9]  = add_512_avx512(v[9], v[13]);
3074-  v[10] = add_512_avx512(v[10], v[14]);
3075-  v[11] = add_512_avx512(v[11], v[15]);
3076-  v[4]  = xor_512_avx512(v[4], v[8]);
3077-  v[5]  = xor_512_avx512(v[5], v[9]);
3078-  v[6]  = xor_512_avx512(v[6], v[10]);
3079-  v[7]  = xor_512_avx512(v[7], v[11]);
3080-  v[4]  = rot7_512_avx512(v[4]);
3081-  v[5]  = rot7_512_avx512(v[5]);
3082-  v[6]  = rot7_512_avx512(v[6]);
3083-  v[7]  = rot7_512_avx512(v[7]);
3084-
3085-  v[0]  = add_512_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][8]]);
3086-  v[1]  = add_512_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][10]]);
3087-  v[2]  = add_512_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][12]]);
3088-  v[3]  = add_512_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][14]]);
3089-  v[0]  = add_512_avx512(v[0], v[5]);
3090-  v[1]  = add_512_avx512(v[1], v[6]);
3091-  v[2]  = add_512_avx512(v[2], v[7]);
3092-  v[3]  = add_512_avx512(v[3], v[4]);
3093-  v[15] = xor_512_avx512(v[15], v[0]);
3094-  v[12] = xor_512_avx512(v[12], v[1]);
3095-  v[13] = xor_512_avx512(v[13], v[2]);
3096-  v[14] = xor_512_avx512(v[14], v[3]);
3097-  v[15] = rot16_512_avx512(v[15]);
3098-  v[12] = rot16_512_avx512(v[12]);
3099-  v[13] = rot16_512_avx512(v[13]);
3100-  v[14] = rot16_512_avx512(v[14]);
3101-  v[10] = add_512_avx512(v[10], v[15]);
3102-  v[11] = add_512_avx512(v[11], v[12]);
3103-  v[8]  = add_512_avx512(v[8], v[13]);
3104-  v[9]  = add_512_avx512(v[9], v[14]);
3105-  v[5]  = xor_512_avx512(v[5], v[10]);
3106-  v[6]  = xor_512_avx512(v[6], v[11]);
3107-  v[7]  = xor_512_avx512(v[7], v[8]);
3108-  v[4]  = xor_512_avx512(v[4], v[9]);
3109-  v[5]  = rot12_512_avx512(v[5]);
3110-  v[6]  = rot12_512_avx512(v[6]);
3111-  v[7]  = rot12_512_avx512(v[7]);
3112-  v[4]  = rot12_512_avx512(v[4]);
3113-  v[0]  = add_512_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][9]]);
3114-  v[1]  = add_512_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][11]]);
3115-  v[2]  = add_512_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][13]]);
3116-  v[3]  = add_512_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][15]]);
3117-  v[0]  = add_512_avx512(v[0], v[5]);
3118-  v[1]  = add_512_avx512(v[1], v[6]);
3119-  v[2]  = add_512_avx512(v[2], v[7]);
3120-  v[3]  = add_512_avx512(v[3], v[4]);
3121-  v[15] = xor_512_avx512(v[15], v[0]);
3122-  v[12] = xor_512_avx512(v[12], v[1]);
3123-  v[13] = xor_512_avx512(v[13], v[2]);
3124-  v[14] = xor_512_avx512(v[14], v[3]);
3125-  v[15] = rot8_512_avx512(v[15]);
3126-  v[12] = rot8_512_avx512(v[12]);
3127-  v[13] = rot8_512_avx512(v[13]);
3128-  v[14] = rot8_512_avx512(v[14]);
3129-  v[10] = add_512_avx512(v[10], v[15]);
3130-  v[11] = add_512_avx512(v[11], v[12]);
3131-  v[8]  = add_512_avx512(v[8], v[13]);
3132-  v[9]  = add_512_avx512(v[9], v[14]);
3133-  v[5]  = xor_512_avx512(v[5], v[10]);
3134-  v[6]  = xor_512_avx512(v[6], v[11]);
3135-  v[7]  = xor_512_avx512(v[7], v[8]);
3136-  v[4]  = xor_512_avx512(v[4], v[9]);
3137-  v[5]  = rot7_512_avx512(v[5]);
3138-  v[6]  = rot7_512_avx512(v[6]);
3139-  v[7]  = rot7_512_avx512(v[7]);
3140-  v[4]  = rot7_512_avx512(v[4]);
3141-}
3142-
3143-#define LO_IMM8 0x88
3144-#define HI_IMM8 0xdd
3145-
3146-static inline __m512i
3147-unpack_lo_128_avx512(__m512i a, __m512i b)
3148-{
3149-  return _mm512_shuffle_i32x4(a, b, LO_IMM8);
3150-}
3151-
3152-static inline __m512i
3153-unpack_hi_128_avx512(__m512i a, __m512i b)
3154-{
3155-  return _mm512_shuffle_i32x4(a, b, HI_IMM8);
3156-}
3157-
3158-static inline void
3159-transpose_vecs_512_avx512(__m512i vecs[16])
3160-{
3161-  __m512i ab_0 = _mm512_unpacklo_epi32(vecs[0], vecs[1]);
3162-  __m512i ab_2 = _mm512_unpackhi_epi32(vecs[0], vecs[1]);
3163-  __m512i cd_0 = _mm512_unpacklo_epi32(vecs[2], vecs[3]);
3164-  __m512i cd_2 = _mm512_unpackhi_epi32(vecs[2], vecs[3]);
3165-  __m512i ef_0 = _mm512_unpacklo_epi32(vecs[4], vecs[5]);
3166-  __m512i ef_2 = _mm512_unpackhi_epi32(vecs[4], vecs[5]);
3167-  __m512i gh_0 = _mm512_unpacklo_epi32(vecs[6], vecs[7]);
3168-  __m512i gh_2 = _mm512_unpackhi_epi32(vecs[6], vecs[7]);
3169-  __m512i ij_0 = _mm512_unpacklo_epi32(vecs[8], vecs[9]);
3170-  __m512i ij_2 = _mm512_unpackhi_epi32(vecs[8], vecs[9]);
3171-  __m512i kl_0 = _mm512_unpacklo_epi32(vecs[10], vecs[11]);
3172-  __m512i kl_2 = _mm512_unpackhi_epi32(vecs[10], vecs[11]);
3173-  __m512i mn_0 = _mm512_unpacklo_epi32(vecs[12], vecs[13]);
3174-  __m512i mn_2 = _mm512_unpackhi_epi32(vecs[12], vecs[13]);
3175-  __m512i op_0 = _mm512_unpacklo_epi32(vecs[14], vecs[15]);
3176-  __m512i op_2 = _mm512_unpackhi_epi32(vecs[14], vecs[15]);
3177-
3178-  __m512i abcd_0 = _mm512_unpacklo_epi64(ab_0, cd_0);
3179-  __m512i abcd_1 = _mm512_unpackhi_epi64(ab_0, cd_0);
3180-  __m512i abcd_2 = _mm512_unpacklo_epi64(ab_2, cd_2);
3181-  __m512i abcd_3 = _mm512_unpackhi_epi64(ab_2, cd_2);
3182-  __m512i efgh_0 = _mm512_unpacklo_epi64(ef_0, gh_0);
3183-  __m512i efgh_1 = _mm512_unpackhi_epi64(ef_0, gh_0);
3184-  __m512i efgh_2 = _mm512_unpacklo_epi64(ef_2, gh_2);
3185-  __m512i efgh_3 = _mm512_unpackhi_epi64(ef_2, gh_2);
3186-  __m512i ijkl_0 = _mm512_unpacklo_epi64(ij_0, kl_0);
3187-  __m512i ijkl_1 = _mm512_unpackhi_epi64(ij_0, kl_0);
3188-  __m512i ijkl_2 = _mm512_unpacklo_epi64(ij_2, kl_2);
3189-  __m512i ijkl_3 = _mm512_unpackhi_epi64(ij_2, kl_2);
3190-  __m512i mnop_0 = _mm512_unpacklo_epi64(mn_0, op_0);
3191-  __m512i mnop_1 = _mm512_unpackhi_epi64(mn_0, op_0);
3192-  __m512i mnop_2 = _mm512_unpacklo_epi64(mn_2, op_2);
3193-  __m512i mnop_3 = _mm512_unpackhi_epi64(mn_2, op_2);
3194-
3195-  __m512i abcdefgh_0 = unpack_lo_128_avx512(abcd_0, efgh_0);
3196-  __m512i abcdefgh_1 = unpack_lo_128_avx512(abcd_1, efgh_1);
3197-  __m512i abcdefgh_2 = unpack_lo_128_avx512(abcd_2, efgh_2);
3198-  __m512i abcdefgh_3 = unpack_lo_128_avx512(abcd_3, efgh_3);
3199-  __m512i abcdefgh_4 = unpack_hi_128_avx512(abcd_0, efgh_0);
3200-  __m512i abcdefgh_5 = unpack_hi_128_avx512(abcd_1, efgh_1);
3201-  __m512i abcdefgh_6 = unpack_hi_128_avx512(abcd_2, efgh_2);
3202-  __m512i abcdefgh_7 = unpack_hi_128_avx512(abcd_3, efgh_3);
3203-  __m512i ijklmnop_0 = unpack_lo_128_avx512(ijkl_0, mnop_0);
3204-  __m512i ijklmnop_1 = unpack_lo_128_avx512(ijkl_1, mnop_1);
3205-  __m512i ijklmnop_2 = unpack_lo_128_avx512(ijkl_2, mnop_2);
3206-  __m512i ijklmnop_3 = unpack_lo_128_avx512(ijkl_3, mnop_3);
3207-  __m512i ijklmnop_4 = unpack_hi_128_avx512(ijkl_0, mnop_0);
3208-  __m512i ijklmnop_5 = unpack_hi_128_avx512(ijkl_1, mnop_1);
3209-  __m512i ijklmnop_6 = unpack_hi_128_avx512(ijkl_2, mnop_2);
3210-  __m512i ijklmnop_7 = unpack_hi_128_avx512(ijkl_3, mnop_3);
3211-
3212-  vecs[0]  = unpack_lo_128_avx512(abcdefgh_0, ijklmnop_0);
3213-  vecs[1]  = unpack_lo_128_avx512(abcdefgh_1, ijklmnop_1);
3214-  vecs[2]  = unpack_lo_128_avx512(abcdefgh_2, ijklmnop_2);
3215-  vecs[3]  = unpack_lo_128_avx512(abcdefgh_3, ijklmnop_3);
3216-  vecs[4]  = unpack_lo_128_avx512(abcdefgh_4, ijklmnop_4);
3217-  vecs[5]  = unpack_lo_128_avx512(abcdefgh_5, ijklmnop_5);
3218-  vecs[6]  = unpack_lo_128_avx512(abcdefgh_6, ijklmnop_6);
3219-  vecs[7]  = unpack_lo_128_avx512(abcdefgh_7, ijklmnop_7);
3220-  vecs[8]  = unpack_hi_128_avx512(abcdefgh_0, ijklmnop_0);
3221-  vecs[9]  = unpack_hi_128_avx512(abcdefgh_1, ijklmnop_1);
3222-  vecs[10] = unpack_hi_128_avx512(abcdefgh_2, ijklmnop_2);
3223-  vecs[11] = unpack_hi_128_avx512(abcdefgh_3, ijklmnop_3);
3224-  vecs[12] = unpack_hi_128_avx512(abcdefgh_4, ijklmnop_4);
3225-  vecs[13] = unpack_hi_128_avx512(abcdefgh_5, ijklmnop_5);
3226-  vecs[14] = unpack_hi_128_avx512(abcdefgh_6, ijklmnop_6);
3227-  vecs[15] = unpack_hi_128_avx512(abcdefgh_7, ijklmnop_7);
3228-}
3229-
3230-static inline void
3231-transpose_msg_vecs16_avx512(const uint8_t *const *inputs, size_t block_offset, __m512i out_msg[16])
3232-{
3233-  size_t i;
3234-
3235-  out_msg[0]  = loadu_512_avx512(&inputs[0][block_offset]);
3236-  out_msg[1]  = loadu_512_avx512(&inputs[1][block_offset]);
3237-  out_msg[2]  = loadu_512_avx512(&inputs[2][block_offset]);
3238-  out_msg[3]  = loadu_512_avx512(&inputs[3][block_offset]);
3239-  out_msg[4]  = loadu_512_avx512(&inputs[4][block_offset]);
3240-  out_msg[5]  = loadu_512_avx512(&inputs[5][block_offset]);
3241-  out_msg[6]  = loadu_512_avx512(&inputs[6][block_offset]);
3242-  out_msg[7]  = loadu_512_avx512(&inputs[7][block_offset]);
3243-  out_msg[8]  = loadu_512_avx512(&inputs[8][block_offset]);
3244-  out_msg[9]  = loadu_512_avx512(&inputs[9][block_offset]);
3245-  out_msg[10] = loadu_512_avx512(&inputs[10][block_offset]);
3246-  out_msg[11] = loadu_512_avx512(&inputs[11][block_offset]);
3247-  out_msg[12] = loadu_512_avx512(&inputs[12][block_offset]);
3248-  out_msg[13] = loadu_512_avx512(&inputs[13][block_offset]);
3249-  out_msg[14] = loadu_512_avx512(&inputs[14][block_offset]);
3250-  out_msg[15] = loadu_512_avx512(&inputs[15][block_offset]);
3251-
3252-  for (i = 0; i < 16; i++) {
3253-    _mm_prefetch((const void *)&inputs[i][block_offset + 256], _MM_HINT_T0);
3254-  }
3255-  transpose_vecs_512_avx512(out_msg);
3256-}
3257-
3258-static inline void
3259-load_counters16_avx512(uint64_t counter, int increment_counter, __m512i *out_lo, __m512i *out_hi)
3260-{
3261-  const __m512i mask   = _mm512_set1_epi32(-increment_counter);
3262-  const __m512i deltas = _mm512_set_epi32(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
3263-  const __m512i masked_deltas = _mm512_and_si512(deltas, mask);
3264-  const __m512i low_words = _mm512_add_epi32(_mm512_set1_epi32((int32_t)counter), masked_deltas);
3265-  const __m512i carries =
3266-      _mm512_srli_epi32(_mm512_andnot_si512(low_words, _mm512_set1_epi32((int32_t)counter)), 31);
3267-  const __m512i high_words = _mm512_add_epi32(_mm512_set1_epi32((int32_t)(counter >> 32)), carries);
3268-
3269-  *out_lo = low_words;
3270-  *out_hi = high_words;
3271-}
3272-
3273-void
3274-blake3_hash16_avx512(
3275-    const uint8_t *const *inputs,
3276-    size_t                blocks,
3277-    const uint32_t        key[8],
3278-    uint64_t              counter,
3279-    int                   increment_counter,
3280-    uint8_t               flags,
3281-    uint8_t               flags_start,
3282-    uint8_t               flags_end,
3283-    uint8_t              *out_bytes
3284-)
3285-{
3286-  __m512i h_vecs[8];
3287-  __m512i counter_low_vec, counter_high_vec;
3288-  uint8_t block_flags;
3289-  size_t  block;
3290-
3291-  h_vecs[0] = set1_512_avx512(key[0]);
3292-  h_vecs[1] = set1_512_avx512(key[1]);
3293-  h_vecs[2] = set1_512_avx512(key[2]);
3294-  h_vecs[3] = set1_512_avx512(key[3]);
3295-  h_vecs[4] = set1_512_avx512(key[4]);
3296-  h_vecs[5] = set1_512_avx512(key[5]);
3297-  h_vecs[6] = set1_512_avx512(key[6]);
3298-  h_vecs[7] = set1_512_avx512(key[7]);
3299-
3300-  load_counters16_avx512(counter, increment_counter, &counter_low_vec, &counter_high_vec);
3301-  block_flags = flags | flags_start;
3302-
3303-  for (block = 0; block < blocks; block++) {
3304-    __m512i block_len_vec;
3305-    __m512i block_flags_vec;
3306-    __m512i msg_vecs[16];
3307-    __m512i v[16];
3308-
3309-    if (block + 1 == blocks) {
3310-      block_flags |= flags_end;
3311-    }
3312-    block_len_vec   = set1_512_avx512(BLAKE3_BLOCK_LEN);
3313-    block_flags_vec = set1_512_avx512(block_flags);
3314-    transpose_msg_vecs16_avx512(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs);
3315-
3316-    v[0]  = h_vecs[0];
3317-    v[1]  = h_vecs[1];
3318-    v[2]  = h_vecs[2];
3319-    v[3]  = h_vecs[3];
3320-    v[4]  = h_vecs[4];
3321-    v[5]  = h_vecs[5];
3322-    v[6]  = h_vecs[6];
3323-    v[7]  = h_vecs[7];
3324-    v[8]  = set1_512_avx512(IV[0]);
3325-    v[9]  = set1_512_avx512(IV[1]);
3326-    v[10] = set1_512_avx512(IV[2]);
3327-    v[11] = set1_512_avx512(IV[3]);
3328-    v[12] = counter_low_vec;
3329-    v[13] = counter_high_vec;
3330-    v[14] = block_len_vec;
3331-    v[15] = block_flags_vec;
3332-
3333-    round_fn16_avx512(v, msg_vecs, 0);
3334-    round_fn16_avx512(v, msg_vecs, 1);
3335-    round_fn16_avx512(v, msg_vecs, 2);
3336-    round_fn16_avx512(v, msg_vecs, 3);
3337-    round_fn16_avx512(v, msg_vecs, 4);
3338-    round_fn16_avx512(v, msg_vecs, 5);
3339-    round_fn16_avx512(v, msg_vecs, 6);
3340-
3341-    h_vecs[0] = xor_512_avx512(v[0], v[8]);
3342-    h_vecs[1] = xor_512_avx512(v[1], v[9]);
3343-    h_vecs[2] = xor_512_avx512(v[2], v[10]);
3344-    h_vecs[3] = xor_512_avx512(v[3], v[11]);
3345-    h_vecs[4] = xor_512_avx512(v[4], v[12]);
3346-    h_vecs[5] = xor_512_avx512(v[5], v[13]);
3347-    h_vecs[6] = xor_512_avx512(v[6], v[14]);
3348-    h_vecs[7] = xor_512_avx512(v[7], v[15]);
3349-
3350-    block_flags = flags;
3351-  }
3352-
3353-  __m512i padded[16] = {
3354-      h_vecs[0],
3355-      h_vecs[1],
3356-      h_vecs[2],
3357-      h_vecs[3],
3358-      h_vecs[4],
3359-      h_vecs[5],
3360-      h_vecs[6],
3361-      h_vecs[7],
3362-      set1_512_avx512(0),
3363-      set1_512_avx512(0),
3364-      set1_512_avx512(0),
3365-      set1_512_avx512(0),
3366-      set1_512_avx512(0),
3367-      set1_512_avx512(0),
3368-      set1_512_avx512(0),
3369-      set1_512_avx512(0),
3370-  };
3371-  transpose_vecs_512_avx512(padded);
3372-  _mm256_mask_storeu_epi32(
3373-      &out_bytes[0 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[0])
3374-  );
3375-  _mm256_mask_storeu_epi32(
3376-      &out_bytes[1 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[1])
3377-  );
3378-  _mm256_mask_storeu_epi32(
3379-      &out_bytes[2 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[2])
3380-  );
3381-  _mm256_mask_storeu_epi32(
3382-      &out_bytes[3 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[3])
3383-  );
3384-  _mm256_mask_storeu_epi32(
3385-      &out_bytes[4 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[4])
3386-  );
3387-  _mm256_mask_storeu_epi32(
3388-      &out_bytes[5 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[5])
3389-  );
3390-  _mm256_mask_storeu_epi32(
3391-      &out_bytes[6 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[6])
3392-  );
3393-  _mm256_mask_storeu_epi32(
3394-      &out_bytes[7 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[7])
3395-  );
3396-  _mm256_mask_storeu_epi32(
3397-      &out_bytes[8 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[8])
3398-  );
3399-  _mm256_mask_storeu_epi32(
3400-      &out_bytes[9 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[9])
3401-  );
3402-  _mm256_mask_storeu_epi32(
3403-      &out_bytes[10 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[10])
3404-  );
3405-  _mm256_mask_storeu_epi32(
3406-      &out_bytes[11 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[11])
3407-  );
3408-  _mm256_mask_storeu_epi32(
3409-      &out_bytes[12 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[12])
3410-  );
3411-  _mm256_mask_storeu_epi32(
3412-      &out_bytes[13 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[13])
3413-  );
3414-  _mm256_mask_storeu_epi32(
3415-      &out_bytes[14 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[14])
3416-  );
3417-  _mm256_mask_storeu_epi32(
3418-      &out_bytes[15 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[15])
3419-  );
3420-}
3421-
3422-static inline void
3423-transpose_msg_vecs8_avx512(const uint8_t *const *inputs, size_t block_offset, __m256i out_msg[16])
3424-{
3425-  out_msg[0]  = loadu_256_avx512(&inputs[0][block_offset]);
3426-  out_msg[1]  = loadu_256_avx512(&inputs[1][block_offset]);
3427-  out_msg[2]  = loadu_256_avx512(&inputs[2][block_offset]);
3428-  out_msg[3]  = loadu_256_avx512(&inputs[3][block_offset]);
3429-  out_msg[4]  = loadu_256_avx512(&inputs[4][block_offset]);
3430-  out_msg[5]  = loadu_256_avx512(&inputs[5][block_offset]);
3431-  out_msg[6]  = loadu_256_avx512(&inputs[6][block_offset]);
3432-  out_msg[7]  = loadu_256_avx512(&inputs[7][block_offset]);
3433-  out_msg[8]  = loadu_256_avx512(&inputs[0][block_offset + 32]);
3434-  out_msg[9]  = loadu_256_avx512(&inputs[1][block_offset + 32]);
3435-  out_msg[10] = loadu_256_avx512(&inputs[2][block_offset + 32]);
3436-  out_msg[11] = loadu_256_avx512(&inputs[3][block_offset + 32]);
3437-  out_msg[12] = loadu_256_avx512(&inputs[4][block_offset + 32]);
3438-  out_msg[13] = loadu_256_avx512(&inputs[5][block_offset + 32]);
3439-  out_msg[14] = loadu_256_avx512(&inputs[6][block_offset + 32]);
3440-  out_msg[15] = loadu_256_avx512(&inputs[7][block_offset + 32]);
3441-
3442-  transpose_vecs_avx2(out_msg);
3443-}
3444-
3445-static inline void
3446-load_counters8_avx512(uint64_t counter, int increment_counter, __m256i *out_lo, __m256i *out_hi)
3447-{
3448-  const __m256i mask = _mm256_set1_epi32(-increment_counter);
3449-  const __m256i add0 = _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0);
3450-  const __m256i add1 = _mm256_and_si256(mask, add0);
3451-  __m256i       l    = _mm256_add_epi32(_mm256_set1_epi32((int32_t)counter), add1);
3452-  __m256i       carry =
3453-      _mm256_srli_epi32(_mm256_andnot_si256(l, _mm256_set1_epi32((int32_t)counter)), 31);
3454-  __m256i h = _mm256_add_epi32(_mm256_set1_epi32((int32_t)(counter >> 32)), carry);
3455-
3456-  *out_lo = l;
3457-  *out_hi = h;
3458-}
3459-
3460-void
3461-blake3_hash8_avx512(
3462-    const uint8_t *const *inputs,
3463-    size_t                blocks,
3464-    const uint32_t        key[8],
3465-    uint64_t              counter,
3466-    int                   increment_counter,
3467-    uint8_t               flags,
3468-    uint8_t               flags_start,
3469-    uint8_t               flags_end,
3470-    uint8_t              *out_bytes
3471-)
3472-{
3473-  __m256i h_vecs[8];
3474-  __m256i counter_low_vec, counter_high_vec;
3475-  uint8_t block_flags;
3476-  size_t  block;
3477-
3478-  h_vecs[0] = set1_256_avx512(key[0]);
3479-  h_vecs[1] = set1_256_avx512(key[1]);
3480-  h_vecs[2] = set1_256_avx512(key[2]);
3481-  h_vecs[3] = set1_256_avx512(key[3]);
3482-  h_vecs[4] = set1_256_avx512(key[4]);
3483-  h_vecs[5] = set1_256_avx512(key[5]);
3484-  h_vecs[6] = set1_256_avx512(key[6]);
3485-  h_vecs[7] = set1_256_avx512(key[7]);
3486-
3487-  load_counters8_avx512(counter, increment_counter, &counter_low_vec, &counter_high_vec);
3488-  block_flags = flags | flags_start;
3489-
3490-  for (block = 0; block < blocks; block++) {
3491-    __m256i block_len_vec;
3492-    __m256i block_flags_vec;
3493-    __m256i msg_vecs[16];
3494-    __m256i v[16];
3495-
3496-    if (block + 1 == blocks) {
3497-      block_flags |= flags_end;
3498-    }
3499-    block_len_vec   = set1_256_avx512(BLAKE3_BLOCK_LEN);
3500-    block_flags_vec = set1_256_avx512(block_flags);
3501-    transpose_msg_vecs8_avx512(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs);
3502-
3503-    v[0]  = h_vecs[0];
3504-    v[1]  = h_vecs[1];
3505-    v[2]  = h_vecs[2];
3506-    v[3]  = h_vecs[3];
3507-    v[4]  = h_vecs[4];
3508-    v[5]  = h_vecs[5];
3509-    v[6]  = h_vecs[6];
3510-    v[7]  = h_vecs[7];
3511-    v[8]  = set1_256_avx512(IV[0]);
3512-    v[9]  = set1_256_avx512(IV[1]);
3513-    v[10] = set1_256_avx512(IV[2]);
3514-    v[11] = set1_256_avx512(IV[3]);
3515-    v[12] = counter_low_vec;
3516-    v[13] = counter_high_vec;
3517-    v[14] = block_len_vec;
3518-    v[15] = block_flags_vec;
3519-
3520-    round_fn8_avx512(v, msg_vecs, 0);
3521-    round_fn8_avx512(v, msg_vecs, 1);
3522-    round_fn8_avx512(v, msg_vecs, 2);
3523-    round_fn8_avx512(v, msg_vecs, 3);
3524-    round_fn8_avx512(v, msg_vecs, 4);
3525-    round_fn8_avx512(v, msg_vecs, 5);
3526-    round_fn8_avx512(v, msg_vecs, 6);
3527-
3528-    h_vecs[0] = xor_256_avx512(v[0], v[8]);
3529-    h_vecs[1] = xor_256_avx512(v[1], v[9]);
3530-    h_vecs[2] = xor_256_avx512(v[2], v[10]);
3531-    h_vecs[3] = xor_256_avx512(v[3], v[11]);
3532-    h_vecs[4] = xor_256_avx512(v[4], v[12]);
3533-    h_vecs[5] = xor_256_avx512(v[5], v[13]);
3534-    h_vecs[6] = xor_256_avx512(v[6], v[14]);
3535-    h_vecs[7] = xor_256_avx512(v[7], v[15]);
3536-
3537-    block_flags = flags;
3538-  }
3539-
3540-  transpose_vecs_avx2(h_vecs);
3541-  storeu_256_avx512(h_vecs[0], &out_bytes[0 * sizeof(__m256i)]);
3542-  storeu_256_avx512(h_vecs[1], &out_bytes[1 * sizeof(__m256i)]);
3543-  storeu_256_avx512(h_vecs[2], &out_bytes[2 * sizeof(__m256i)]);
3544-  storeu_256_avx512(h_vecs[3], &out_bytes[3 * sizeof(__m256i)]);
3545-  storeu_256_avx512(h_vecs[4], &out_bytes[4 * sizeof(__m256i)]);
3546-  storeu_256_avx512(h_vecs[5], &out_bytes[5 * sizeof(__m256i)]);
3547-  storeu_256_avx512(h_vecs[6], &out_bytes[6 * sizeof(__m256i)]);
3548-  storeu_256_avx512(h_vecs[7], &out_bytes[7 * sizeof(__m256i)]);
3549-}
3550-
3551-static inline void
3552-transpose_msg_vecs4_avx512(const uint8_t *const *inputs, size_t block_offset, __m128i out_msg[16])
3553-{
3554-  out_msg[0]  = loadu_128_avx512(&inputs[0][block_offset]);
3555-  out_msg[1]  = loadu_128_avx512(&inputs[1][block_offset]);
3556-  out_msg[2]  = loadu_128_avx512(&inputs[2][block_offset]);
3557-  out_msg[3]  = loadu_128_avx512(&inputs[3][block_offset]);
3558-  out_msg[4]  = loadu_128_avx512(&inputs[0][block_offset + 16]);
3559-  out_msg[5]  = loadu_128_avx512(&inputs[1][block_offset + 16]);
3560-  out_msg[6]  = loadu_128_avx512(&inputs[2][block_offset + 16]);
3561-  out_msg[7]  = loadu_128_avx512(&inputs[3][block_offset + 16]);
3562-  out_msg[8]  = loadu_128_avx512(&inputs[0][block_offset + 32]);
3563-  out_msg[9]  = loadu_128_avx512(&inputs[1][block_offset + 32]);
3564-  out_msg[10] = loadu_128_avx512(&inputs[2][block_offset + 32]);
3565-  out_msg[11] = loadu_128_avx512(&inputs[3][block_offset + 32]);
3566-  out_msg[12] = loadu_128_avx512(&inputs[0][block_offset + 48]);
3567-  out_msg[13] = loadu_128_avx512(&inputs[1][block_offset + 48]);
3568-  out_msg[14] = loadu_128_avx512(&inputs[2][block_offset + 48]);
3569-  out_msg[15] = loadu_128_avx512(&inputs[3][block_offset + 48]);
3570-
3571-  transpose_vecs_sse2(out_msg);
3572-}
3573-
3574-static inline void
3575-load_counters4_avx512(uint64_t counter, int increment_counter, __m128i *out_lo, __m128i *out_hi)
3576-{
3577-  const __m128i mask  = _mm_set1_epi32(-increment_counter);
3578-  const __m128i add0  = _mm_set_epi32(3, 2, 1, 0);
3579-  const __m128i add1  = _mm_and_si128(mask, add0);
3580-  __m128i       l     = _mm_add_epi32(_mm_set1_epi32((int32_t)counter), add1);
3581-  __m128i       carry = _mm_srli_epi32(_mm_andnot_si128(l, _mm_set1_epi32((int32_t)counter)), 31);
3582-  __m128i       h     = _mm_add_epi32(_mm_set1_epi32((int32_t)(counter >> 32)), carry);
3583-
3584-  *out_lo = l;
3585-  *out_hi = h;
3586-}
3587-
3588-void
3589-blake3_hash4_avx512(
3590-    const uint8_t *const *inputs,
3591-    size_t                blocks,
3592-    const uint32_t        key[8],
3593-    uint64_t              counter,
3594-    int                   increment_counter,
3595-    uint8_t               flags,
3596-    uint8_t               flags_start,
3597-    uint8_t               flags_end,
3598-    uint8_t              *out_bytes
3599-)
3600-{
3601-  __m128i h_vecs[8];
3602-  __m128i counter_low_vec, counter_high_vec;
3603-  uint8_t block_flags;
3604-  size_t  block;
3605-
3606-  h_vecs[0] = set1_128_avx512(key[0]);
3607-  h_vecs[1] = set1_128_avx512(key[1]);
3608-  h_vecs[2] = set1_128_avx512(key[2]);
3609-  h_vecs[3] = set1_128_avx512(key[3]);
3610-  h_vecs[4] = set1_128_avx512(key[4]);
3611-  h_vecs[5] = set1_128_avx512(key[5]);
3612-  h_vecs[6] = set1_128_avx512(key[6]);
3613-  h_vecs[7] = set1_128_avx512(key[7]);
3614-
3615-  load_counters4_avx512(counter, increment_counter, &counter_low_vec, &counter_high_vec);
3616-  block_flags = flags | flags_start;
3617-
3618-  for (block = 0; block < blocks; block++) {
3619-    __m128i block_len_vec;
3620-    __m128i block_flags_vec;
3621-    __m128i msg_vecs[16];
3622-    __m128i v[16];
3623-
3624-    if (block + 1 == blocks) {
3625-      block_flags |= flags_end;
3626-    }
3627-    block_len_vec   = set1_128_avx512(BLAKE3_BLOCK_LEN);
3628-    block_flags_vec = set1_128_avx512(block_flags);
3629-    transpose_msg_vecs4_avx512(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs);
3630-
3631-    v[0]  = h_vecs[0];
3632-    v[1]  = h_vecs[1];
3633-    v[2]  = h_vecs[2];
3634-    v[3]  = h_vecs[3];
3635-    v[4]  = h_vecs[4];
3636-    v[5]  = h_vecs[5];
3637-    v[6]  = h_vecs[6];
3638-    v[7]  = h_vecs[7];
3639-    v[8]  = set1_128_avx512(IV[0]);
3640-    v[9]  = set1_128_avx512(IV[1]);
3641-    v[10] = set1_128_avx512(IV[2]);
3642-    v[11] = set1_128_avx512(IV[3]);
3643-    v[12] = counter_low_vec;
3644-    v[13] = counter_high_vec;
3645-    v[14] = block_len_vec;
3646-    v[15] = block_flags_vec;
3647-
3648-    round_fn4_avx512(v, msg_vecs, 0);
3649-    round_fn4_avx512(v, msg_vecs, 1);
3650-    round_fn4_avx512(v, msg_vecs, 2);
3651-    round_fn4_avx512(v, msg_vecs, 3);
3652-    round_fn4_avx512(v, msg_vecs, 4);
3653-    round_fn4_avx512(v, msg_vecs, 5);
3654-    round_fn4_avx512(v, msg_vecs, 6);
3655-
3656-    h_vecs[0] = xor_128_avx512(v[0], v[8]);
3657-    h_vecs[1] = xor_128_avx512(v[1], v[9]);
3658-    h_vecs[2] = xor_128_avx512(v[2], v[10]);
3659-    h_vecs[3] = xor_128_avx512(v[3], v[11]);
3660-    h_vecs[4] = xor_128_avx512(v[4], v[12]);
3661-    h_vecs[5] = xor_128_avx512(v[5], v[13]);
3662-    h_vecs[6] = xor_128_avx512(v[6], v[14]);
3663-    h_vecs[7] = xor_128_avx512(v[7], v[15]);
3664-
3665-    block_flags = flags;
3666-  }
3667-
3668-  transpose_vecs_sse2(h_vecs);
3669-  storeu_128_avx512(h_vecs[0], &out_bytes[0 * sizeof(__m128i)]);
3670-  storeu_128_avx512(h_vecs[1], &out_bytes[2 * sizeof(__m128i)]);
3671-  storeu_128_avx512(h_vecs[2], &out_bytes[4 * sizeof(__m128i)]);
3672-  storeu_128_avx512(h_vecs[3], &out_bytes[6 * sizeof(__m128i)]);
3673-  storeu_128_avx512(h_vecs[4], &out_bytes[1 * sizeof(__m128i)]);
3674-  storeu_128_avx512(h_vecs[5], &out_bytes[3 * sizeof(__m128i)]);
3675-  storeu_128_avx512(h_vecs[6], &out_bytes[5 * sizeof(__m128i)]);
3676-  storeu_128_avx512(h_vecs[7], &out_bytes[7 * sizeof(__m128i)]);
3677-}
3678-
3679-static inline void
3680-hash_one_avx512(
3681-    const uint8_t *input,
3682-    size_t         blocks,
3683-    const uint32_t key[8],
3684-    uint64_t       counter,
3685-    uint8_t        flags,
3686-    uint8_t        flags_start,
3687-    uint8_t        flags_end,
3688-    uint8_t        out_bytes[BLAKE3_OUT_LEN]
3689-)
3690-{
3691-  uint32_t cv[8];
3692-  uint8_t  block_flags;
3693-
3694-  memcpy(cv, key, BLAKE3_KEY_LEN);
3695-  block_flags = flags | flags_start;
3696-  while (blocks > 0) {
3697-    if (blocks == 1) {
3698-      block_flags |= flags_end;
3699-    }
3700-    blake3_compress_in_place_avx512(cv, input, BLAKE3_BLOCK_LEN, counter, block_flags);
3701-    input = &input[BLAKE3_BLOCK_LEN];
3702-    blocks -= 1;
3703-    block_flags = flags;
3704-  }
3705-  memcpy(out_bytes, cv, BLAKE3_OUT_LEN);
3706-}
3707-
3708-void
3709-blake3_hash_many_avx512(
3710-    const uint8_t *const *inputs,
3711-    size_t                num_inputs,
3712-    size_t                blocks,
3713-    const uint32_t        key[8],
3714-    uint64_t              counter,
3715-    int                   increment_counter,
3716-    uint8_t               flags,
3717-    uint8_t               flags_start,
3718-    uint8_t               flags_end,
3719-    uint8_t              *out_bytes
3720-)
3721-{
3722-  while (num_inputs >= 16) {
3723-    blake3_hash16_avx512(
3724-        inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out_bytes
3725-    );
3726-    if (increment_counter) {
3727-      counter += 16;
3728-    }
3729-    inputs += 16;
3730-    num_inputs -= 16;
3731-    out_bytes = &out_bytes[16 * BLAKE3_OUT_LEN];
3732-  }
3733-  while (num_inputs >= 8) {
3734-    blake3_hash8_avx512(
3735-        inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out_bytes
3736-    );
3737-    if (increment_counter) {
3738-      counter += 8;
3739-    }
3740-    inputs += 8;
3741-    num_inputs -= 8;
3742-    out_bytes = &out_bytes[8 * BLAKE3_OUT_LEN];
3743-  }
3744-  while (num_inputs >= 4) {
3745-    blake3_hash4_avx512(
3746-        inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out_bytes
3747-    );
3748-    if (increment_counter) {
3749-      counter += 4;
3750-    }
3751-    inputs += 4;
3752-    num_inputs -= 4;
3753-    out_bytes = &out_bytes[4 * BLAKE3_OUT_LEN];
3754-  }
3755-  while (num_inputs > 0) {
3756-    hash_one_avx512(inputs[0], blocks, key, counter, flags, flags_start, flags_end, out_bytes);
3757-    if (increment_counter) {
3758-      counter += 1;
3759-    }
3760-    inputs += 1;
3761-    num_inputs -= 1;
3762-    out_bytes = &out_bytes[BLAKE3_OUT_LEN];
3763-  }
3764-}
3765-#if defined(__clang__)
3766-#pragma clang attribute pop
3767-#elif defined(__GNUC__)
3768-#pragma GCC pop_options
3769-#endif
3770-#endif
3771-
3772-/* dispatch functions */
3773-void
3774-blake3_compress_in_place(
3775-    uint32_t      cv[8],
3776-    const uint8_t block[BLAKE3_BLOCK_LEN],
3777-    uint8_t       block_len,
3778-    uint64_t      counter,
3779-    uint8_t       flags
3780-)
3781-{
3782-#if BLAKE3_X86_SIMD
3783-  if (!blake3_cpu_detected)
3784-    blake3_detect_cpu_features();
3785-  if (blake3_cpu_features & AVX512) {
3786-    blake3_compress_in_place_avx512(cv, block, block_len, counter, flags);
3787-    return;
3788-  }
3789-  if (blake3_cpu_features & SSE41) {
3790-    blake3_compress_in_place_sse41(cv, block, block_len, counter, flags);
3791-    return;
3792-  }
3793-  if (blake3_cpu_features & SSE2) {
3794-    blake3_compress_in_place_sse2(cv, block, block_len, counter, flags);
3795-    return;
3796-  }
3797-#endif
3798-  blake3_compress_in_place_portable(cv, block, block_len, counter, flags);
3799-}
3800-
3801-void
3802-blake3_compress_xof(
3803-    const uint32_t cv[8],
3804-    const uint8_t  block[BLAKE3_BLOCK_LEN],
3805-    uint8_t        block_len,
3806-    uint64_t       counter,
3807-    uint8_t        flags,
3808-    uint8_t        out[64]
3809-)
3810-{
3811-#if BLAKE3_X86_SIMD
3812-  if (!blake3_cpu_detected)
3813-    blake3_detect_cpu_features();
3814-  if (blake3_cpu_features & AVX512) {
3815-    blake3_compress_xof_avx512(cv, block, block_len, counter, flags, out);
3816-    return;
3817-  }
3818-  if (blake3_cpu_features & SSE41) {
3819-    blake3_compress_xof_sse41(cv, block, block_len, counter, flags, out);
3820-    return;
3821-  }
3822-  if (blake3_cpu_features & SSE2) {
3823-    blake3_compress_xof_sse2(cv, block, block_len, counter, flags, out);
3824-    return;
3825-  }
3826-#endif
3827-  blake3_compress_xof_portable(cv, block, block_len, counter, flags, out);
3828-}
3829-
3830-void
3831-blake3_hash_many(
3832-    const uint8_t *const *inputs,
3833-    size_t                num_inputs,
3834-    size_t                blocks,
3835-    const uint32_t        key[8],
3836-    uint64_t              counter,
3837-    int                   increment_counter,
3838-    uint8_t               flags,
3839-    uint8_t               flags_start,
3840-    uint8_t               flags_end,
3841-    uint8_t              *out
3842-)
3843-{
3844-#if BLAKE3_X86_SIMD
3845-  if (!blake3_cpu_detected)
3846-    blake3_detect_cpu_features();
3847-  if (blake3_cpu_features & AVX512) {
3848-    blake3_hash_many_avx512(
3849-        inputs,
3850-        num_inputs,
3851-        blocks,
3852-        key,
3853-        counter,
3854-        increment_counter,
3855-        flags,
3856-        flags_start,
3857-        flags_end,
3858-        out
3859-    );
3860-    return;
3861-  }
3862-  if (blake3_cpu_features & AVX2) {
3863-    blake3_hash_many_avx2(
3864-        inputs,
3865-        num_inputs,
3866-        blocks,
3867-        key,
3868-        counter,
3869-        increment_counter,
3870-        flags,
3871-        flags_start,
3872-        flags_end,
3873-        out
3874-    );
3875-    return;
3876-  }
3877-  if (blake3_cpu_features & SSE41) {
3878-    blake3_hash_many_sse41(
3879-        inputs,
3880-        num_inputs,
3881-        blocks,
3882-        key,
3883-        counter,
3884-        increment_counter,
3885-        flags,
3886-        flags_start,
3887-        flags_end,
3888-        out
3889-    );
3890-    return;
3891-  }
3892-  if (blake3_cpu_features & SSE2) {
3893-    blake3_hash_many_sse2(
3894-        inputs,
3895-        num_inputs,
3896-        blocks,
3897-        key,
3898-        counter,
3899-        increment_counter,
3900-        flags,
3901-        flags_start,
3902-        flags_end,
3903-        out
3904-    );
3905-    return;
3906-  }
3907-#endif
3908-  blake3_hash_many_portable(
3909-      inputs,
3910-      num_inputs,
3911-      blocks,
3912-      key,
3913-      counter,
3914-      increment_counter,
3915-      flags,
3916-      flags_start,
3917-      flags_end,
3918-      out
3919-  );
3920-}
3921-
3922-size_t
3923-blake3_simd_degree(void)
3924-{
3925-#if BLAKE3_X86_SIMD
3926-  if (!blake3_cpu_detected)
3927-    blake3_detect_cpu_features();
3928-  if (blake3_cpu_features & AVX512)
3929-    return 16;
3930-  if (blake3_cpu_features & AVX2)
3931-    return 8;
3932-  if (blake3_cpu_features & SSE41)
3933-    return 4;
3934-  if (blake3_cpu_features & SSE2)
3935-    return 4;
3936-#endif
3937-  return 1;
3938-}
3939-
3940-/* core hasher implementation */
3941-const char *
3942-blake3_version(void)
3943-{
3944-  return BLAKE3_VERSION_STRING;
3945-}
3946-
3947-static inline void
3948-chunk_state_init(struct Blake3ChunkState *self, const uint32_t key[8], uint8_t flags)
3949-{
3950-  memcpy(self->cv, key, BLAKE3_KEY_LEN);
3951-  self->chunk_counter = 0;
3952-  memset(self->buf, 0, BLAKE3_BLOCK_LEN);
3953-  self->buf_len           = 0;
3954-  self->blocks_compressed = 0;
3955-  self->flags             = flags;
3956-}
3957-
3958-static inline void
3959-chunk_state_reset(struct Blake3ChunkState *self, const uint32_t key[8], uint64_t chunk_counter)
3960-{
3961-  memcpy(self->cv, key, BLAKE3_KEY_LEN);
3962-  self->chunk_counter     = chunk_counter;
3963-  self->blocks_compressed = 0;
3964-  memset(self->buf, 0, BLAKE3_BLOCK_LEN);
3965-  self->buf_len = 0;
3966-}
3967-
3968-static inline size_t
3969-chunk_state_len(const struct Blake3ChunkState *self)
3970-{
3971-  return (BLAKE3_BLOCK_LEN * (size_t)self->blocks_compressed) + ((size_t)self->buf_len);
3972-}
3973-
3974-static inline size_t
3975-chunk_state_fill_buf(struct Blake3ChunkState *self, const uint8_t *input, size_t input_len)
3976-{
3977-  size_t   take = BLAKE3_BLOCK_LEN - ((size_t)self->buf_len);
3978-  uint8_t *dest;
3979-
3980-  if (take > input_len) {
3981-    take = input_len;
3982-  }
3983-  dest = self->buf + ((size_t)self->buf_len);
3984-  memcpy(dest, input, take);
3985-  self->buf_len += (uint8_t)take;
3986-  return take;
3987-}
3988-
3989-static inline uint8_t
3990-chunk_state_maybe_start_flag(const struct Blake3ChunkState *self)
3991-{
3992-  if (self->blocks_compressed == 0) {
3993-    return CHUNK_START;
3994-  } else {
3995-    return 0;
3996-  }
3997-}
3998-
3999-static inline struct Output
4000-make_output(
4001-    const uint32_t input_cv[8],
4002-    const uint8_t  block[BLAKE3_BLOCK_LEN],
4003-    uint8_t        block_len,
4004-    uint64_t       counter,
4005-    uint8_t        flags
4006-)
4007-{
4008-  struct Output ret;
4009-
4010-  memcpy(ret.input_cv, input_cv, 32);
4011-  memcpy(ret.block, block, BLAKE3_BLOCK_LEN);
4012-  ret.block_len = block_len;
4013-  ret.counter   = counter;
4014-  ret.flags     = flags;
4015-  return ret;
4016-}
4017-
4018-static inline void
4019-output_chaining_value(const struct Output *self, uint8_t cv[32])
4020-{
4021-  uint32_t cv_words[8];
4022-
4023-  memcpy(cv_words, self->input_cv, 32);
4024-  blake3_compress_in_place(cv_words, self->block, self->block_len, self->counter, self->flags);
4025-  store_cv_words(cv, cv_words);
4026-}
4027-
4028-static inline void
4029-output_root_bytes(const struct Output *self, uint64_t seek, uint8_t *out, size_t out_len)
4030-{
4031-  uint64_t output_block_counter = seek / 64;
4032-  size_t   offset_within_block  = seek % 64;
4033-  uint8_t  wide_buf[64];
4034-  size_t   available_bytes;
4035-  size_t   memcpy_len;
4036-
4037-  while (out_len > 0) {
4038-    blake3_compress_xof(
4039-        self->input_cv,
4040-        self->block,
4041-        self->block_len,
4042-        output_block_counter,
4043-        self->flags | ROOT,
4044-        wide_buf
4045-    );
4046-    available_bytes = 64 - offset_within_block;
4047-    if (out_len > available_bytes) {
4048-      memcpy_len = available_bytes;
4049-    } else {
4050-      memcpy_len = out_len;
4051-    }
4052-    memcpy(out, wide_buf + offset_within_block, memcpy_len);
4053-    out += memcpy_len;
4054-    out_len -= memcpy_len;
4055-    output_block_counter += 1;
4056-    offset_within_block = 0;
4057-  }
4058-}
4059-
4060-static inline void
4061-chunk_state_update(struct Blake3ChunkState *self, const uint8_t *input, size_t input_len)
4062-{
4063-  size_t take;
4064-
4065-  if (self->buf_len > 0) {
4066-    take = chunk_state_fill_buf(self, input, input_len);
4067-    input += take;
4068-    input_len -= take;
4069-    if (input_len > 0) {
4070-      blake3_compress_in_place(
4071-          self->cv,
4072-          self->buf,
4073-          BLAKE3_BLOCK_LEN,
4074-          self->chunk_counter,
4075-          self->flags | chunk_state_maybe_start_flag(self)
4076-      );
4077-      self->blocks_compressed += 1;
4078-      self->buf_len = 0;
4079-      memset(self->buf, 0, BLAKE3_BLOCK_LEN);
4080-    }
4081-  }
4082-
4083-  while (input_len > BLAKE3_BLOCK_LEN) {
4084-    blake3_compress_in_place(
4085-        self->cv,
4086-        input,
4087-        BLAKE3_BLOCK_LEN,
4088-        self->chunk_counter,
4089-        self->flags | chunk_state_maybe_start_flag(self)
4090-    );
4091-    self->blocks_compressed += 1;
4092-    input += BLAKE3_BLOCK_LEN;
4093-    input_len -= BLAKE3_BLOCK_LEN;
4094-  }
4095-
4096-  take = chunk_state_fill_buf(self, input, input_len);
4097-  input += take;
4098-  input_len -= take;
4099-}
4100-
4101-static inline struct Output
4102-chunk_state_output(const struct Blake3ChunkState *self)
4103-{
4104-  uint8_t block_flags = self->flags | chunk_state_maybe_start_flag(self) | CHUNK_END;
4105-
4106-  return make_output(self->cv, self->buf, self->buf_len, self->chunk_counter, block_flags);
4107-}
4108-
4109-static inline struct Output
4110-parent_output(const uint8_t block[BLAKE3_BLOCK_LEN], const uint32_t key[8], uint8_t flags)
4111-{
4112-  return make_output(key, block, BLAKE3_BLOCK_LEN, 0, flags | PARENT);
4113-}
4114-
4115-static unsigned int
4116-highest_one(uint64_t x)
4117-{
4118-#if defined(__GNUC__) || defined(__clang__)
4119-  return 63 ^ __builtin_clzll(x);
4120-#else
4121-  unsigned int c = 0;
4122-  if (x & 0xffffffff00000000ULL) {
4123-    x >>= 32;
4124-    c += 32;
4125-  }
4126-  if (x & 0x00000000ffff0000ULL) {
4127-    x >>= 16;
4128-    c += 16;
4129-  }
4130-  if (x & 0x000000000000ff00ULL) {
4131-    x >>= 8;
4132-    c += 8;
4133-  }
4134-  if (x & 0x00000000000000f0ULL) {
4135-    x >>= 4;
4136-    c += 4;
4137-  }
4138-  if (x & 0x000000000000000cULL) {
4139-    x >>= 2;
4140-    c += 2;
4141-  }
4142-  if (x & 0x0000000000000002ULL) {
4143-    c += 1;
4144-  }
4145-  return c;
4146-#endif
4147-}
4148-
4149-static inline uint64_t
4150-round_down_to_power_of_2(uint64_t x)
4151-{
4152-  return 1ULL << highest_one(x | 1);
4153-}
4154-
4155-static inline size_t
4156-left_len(size_t content_len)
4157-{
4158-  size_t full_chunks = (content_len - 1) / BLAKE3_CHUNK_LEN;
4159-
4160-  return round_down_to_power_of_2(full_chunks) * BLAKE3_CHUNK_LEN;
4161-}
4162-
4163-static inline size_t
4164-compress_chunks_parallel(
4165-    const uint8_t *input,
4166-    size_t         input_len,
4167-    const uint32_t key[8],
4168-    uint64_t       chunk_counter,
4169-    uint8_t        flags,
4170-    uint8_t       *out
4171-)
4172-{
4173-  const uint8_t *chunks_array[MAX_SIMD_DEGREE];
4174-  size_t         input_position   = 0;
4175-  size_t         chunks_array_len = 0;
4176-
4177-  assert(0 < input_len);
4178-  assert(input_len <= MAX_SIMD_DEGREE * BLAKE3_CHUNK_LEN);
4179-
4180-  while (input_len - input_position >= BLAKE3_CHUNK_LEN) {
4181-    chunks_array[chunks_array_len] = &input[input_position];
4182-    input_position += BLAKE3_CHUNK_LEN;
4183-    chunks_array_len += 1;
4184-  }
4185-
4186-  blake3_hash_many(
4187-      chunks_array,
4188-      chunks_array_len,
4189-      BLAKE3_CHUNK_LEN / BLAKE3_BLOCK_LEN,
4190-      key,
4191-      chunk_counter,
4192-      1,
4193-      flags,
4194-      CHUNK_START,
4195-      CHUNK_END,
4196-      out
4197-  );
4198-
4199-  if (input_len > input_position) {
4200-    uint64_t                counter = chunk_counter + (uint64_t)chunks_array_len;
4201-    struct Blake3ChunkState chunk_state;
4202-    struct Output           output;
4203-
4204-    chunk_state_init(&chunk_state, key, flags);
4205-    chunk_state.chunk_counter = counter;
4206-    chunk_state_update(&chunk_state, &input[input_position], input_len - input_position);
4207-    output = chunk_state_output(&chunk_state);
4208-    output_chaining_value(&output, &out[chunks_array_len * BLAKE3_OUT_LEN]);
4209-    return chunks_array_len + 1;
4210-  } else {
4211-    return chunks_array_len;
4212-  }
4213-}
4214-
4215-static inline size_t
4216-compress_parents_parallel(
4217-    const uint8_t *child_chaining_values,
4218-    size_t         num_chaining_values,
4219-    const uint32_t key[8],
4220-    uint8_t        flags,
4221-    uint8_t       *out
4222-)
4223-{
4224-  const uint8_t *parents_array[MAX_SIMD_DEGREE_OR_2];
4225-  size_t         parents_array_len = 0;
4226-
4227-  assert(2 <= num_chaining_values);
4228-  assert(num_chaining_values <= 2 * MAX_SIMD_DEGREE_OR_2);
4229-
4230-  while (num_chaining_values - (2 * parents_array_len) >= 2) {
4231-    parents_array[parents_array_len] =
4232-        &child_chaining_values[2 * parents_array_len * BLAKE3_OUT_LEN];
4233-    parents_array_len += 1;
4234-  }
4235-
4236-  blake3_hash_many(parents_array, parents_array_len, 1, key, 0, 0, flags | PARENT, 0, 0, out);
4237-
4238-  if (num_chaining_values > 2 * parents_array_len) {
4239-    memcpy(
4240-        &out[parents_array_len * BLAKE3_OUT_LEN],
4241-        &child_chaining_values[2 * parents_array_len * BLAKE3_OUT_LEN],
4242-        BLAKE3_OUT_LEN
4243-    );
4244-    return parents_array_len + 1;
4245-  } else {
4246-    return parents_array_len;
4247-  }
4248-}
4249-
4250-static inline size_t
4251-blake3_compress_subtree_wide(
4252-    const uint8_t *input,
4253-    size_t         input_len,
4254-    const uint32_t key[8],
4255-    uint64_t       chunk_counter,
4256-    uint8_t        flags,
4257-    uint8_t       *out
4258-)
4259-{
4260-  size_t degree;
4261-
4262-  if (input_len <= (size_t)blake3_simd_degree() * BLAKE3_CHUNK_LEN) {
4263-    return compress_chunks_parallel(input, input_len, key, chunk_counter, flags, out);
4264-  }
4265-
4266-  degree = blake3_simd_degree();
4267-  if (degree > 1) {
4268-    size_t child_len   = round_down_to_power_of_2(input_len - 1) / degree;
4269-    size_t cvs_written = 0;
4270-
4271-    if (child_len < BLAKE3_CHUNK_LEN) {
4272-      child_len = BLAKE3_CHUNK_LEN;
4273-    }
4274-
4275-    while (input_len > 0) {
4276-      size_t take = child_len;
4277-      size_t sub_cvs;
4278-
4279-      if (take > input_len) {
4280-        take = input_len;
4281-      }
4282-      sub_cvs = blake3_compress_subtree_wide(
4283-          input, take, key, chunk_counter, flags, &out[cvs_written * BLAKE3_OUT_LEN]
4284-      );
4285-      cvs_written += sub_cvs;
4286-      chunk_counter += take / BLAKE3_CHUNK_LEN;
4287-      input += take;
4288-      input_len -= take;
4289-    }
4290-
4291-    while (cvs_written > 2) {
4292-      cvs_written = compress_parents_parallel(out, cvs_written, key, flags, out);
4293-    }
4294-    return cvs_written;
4295-  } else {
4296-    /* fallback when simd degree is 1 */
4297-    size_t left      = left_len(input_len);
4298-    size_t right     = input_len - left;
4299-    size_t left_cvs  = blake3_compress_subtree_wide(input, left, key, chunk_counter, flags, out);
4300-    size_t right_cvs = blake3_compress_subtree_wide(
4301-        input + left,
4302-        right,
4303-        key,
4304-        chunk_counter + (left / BLAKE3_CHUNK_LEN),
4305-        flags,
4306-        &out[left_cvs * BLAKE3_OUT_LEN]
4307-    );
4308-
4309-    return left_cvs + right_cvs;
4310-  }
4311-}
4312-
4313-static void
4314-compress_subtree_to_parent_node(
4315-    const uint8_t *input,
4316-    size_t         input_len,
4317-    const uint32_t key[8],
4318-    uint64_t       chunk_counter,
4319-    uint8_t        flags,
4320-    uint8_t        out[2 * BLAKE3_OUT_LEN]
4321-)
4322-{
4323-  uint8_t cv_array[2 * MAX_SIMD_DEGREE_OR_2 * BLAKE3_OUT_LEN];
4324-  size_t  num_cvs =
4325-      blake3_compress_subtree_wide(input, input_len, key, chunk_counter, flags, cv_array);
4326-
4327-  assert(num_cvs >= 2);
4328-  while (num_cvs > 2) {
4329-    num_cvs = compress_parents_parallel(cv_array, num_cvs, key, flags, cv_array);
4330-  }
4331-  memcpy(out, cv_array, 2 * BLAKE3_OUT_LEN);
4332-}
4333-
4334-static inline void
4335-hasher_init_base(struct Blake3Hasher *self, const uint32_t key[8], uint8_t flags)
4336-{
4337-  memcpy(self->key, key, BLAKE3_KEY_LEN);
4338-  chunk_state_init(&self->chunk, key, flags);
4339-  self->cv_stack_len = 0;
4340-}
4341-
4342-void
4343-blake3_hasher_init(struct Blake3Hasher *self)
4344-{
4345-  if (!blake3_cpu_detected)
4346-    blake3_detect_cpu_features();
4347-  hasher_init_base(self, IV, 0);
4348-}
4349-
4350-static inline void
4351-load_key_words(const uint8_t key[BLAKE3_KEY_LEN], uint32_t key_words[8])
4352-{
4353-  key_words[0] = load32(&key[0 * 4]);
4354-  key_words[1] = load32(&key[1 * 4]);
4355-  key_words[2] = load32(&key[2 * 4]);
4356-  key_words[3] = load32(&key[3 * 4]);
4357-  key_words[4] = load32(&key[4 * 4]);
4358-  key_words[5] = load32(&key[5 * 4]);
4359-  key_words[6] = load32(&key[6 * 4]);
4360-  key_words[7] = load32(&key[7 * 4]);
4361-}
4362-
4363-void
4364-blake3_hasher_init_keyed(struct Blake3Hasher *self, const uint8_t key[BLAKE3_KEY_LEN])
4365-{
4366-  uint32_t key_words[8];
4367-
4368-  load_key_words(key, key_words);
4369-  hasher_init_base(self, key_words, KEYED_HASH);
4370-}
4371-
4372-void
4373-blake3_hasher_init_derive_key_raw(
4374-    struct Blake3Hasher *self, const void *context, size_t context_len
4375-)
4376-{
4377-  struct Blake3Hasher context_hasher;
4378-  uint8_t             context_key[BLAKE3_KEY_LEN];
4379-  uint32_t            context_key_words[8];
4380-
4381-  hasher_init_base(&context_hasher, IV, DERIVE_KEY_CONTEXT);
4382-  blake3_hasher_update(&context_hasher, context, context_len);
4383-  blake3_hasher_finalize(&context_hasher, context_key, BLAKE3_KEY_LEN);
4384-  load_key_words(context_key, context_key_words);
4385-  hasher_init_base(self, context_key_words, DERIVE_KEY_MATERIAL);
4386-}
4387-
4388-static inline unsigned int
4389-popcnt(uint64_t x)
4390-{
4391-#if defined(__GNUC__) || defined(__clang__)
4392-  return __builtin_popcountll(x);
4393-#else
4394-  unsigned int count = 0;
4395-  while (x != 0) {
4396-    count += 1;
4397-    x &= x - 1;
4398-  }
4399-  return count;
4400-#endif
4401-}
4402-
4403-void
4404-blake3_hasher_init_derive_key(struct Blake3Hasher *self, const char *context)
4405-{
4406-  blake3_hasher_init_derive_key_raw(self, context, strlen(context));
4407-}
4408-
4409-static inline void
4410-hasher_merge_cv_stack(struct Blake3Hasher *self, uint64_t total_len)
4411-{
4412-  size_t post_merge_stack_len = (size_t)popcnt(total_len);
4413-
4414-  while (self->cv_stack_len > post_merge_stack_len) {
4415-    uint8_t      *parent_node = &self->cv_stack[(self->cv_stack_len - 2) * BLAKE3_OUT_LEN];
4416-    struct Output output      = parent_output(parent_node, self->key, self->chunk.flags);
4417-
4418-    output_chaining_value(&output, parent_node);
4419-    self->cv_stack_len -= 1;
4420-  }
4421-}
4422-
4423-static inline void
4424-hasher_push_cv(struct Blake3Hasher *self, uint8_t new_cv[BLAKE3_OUT_LEN], uint64_t chunk_counter)
4425-{
4426-  hasher_merge_cv_stack(self, chunk_counter);
4427-  memcpy(&self->cv_stack[self->cv_stack_len * BLAKE3_OUT_LEN], new_cv, BLAKE3_OUT_LEN);
4428-  self->cv_stack_len += 1;
4429-}
4430-
4431-void
4432-blake3_hasher_update(struct Blake3Hasher *self, const void *input, size_t input_len)
4433-{
4434-  const uint8_t *input_bytes;
4435-
4436-  if (input_len == 0) {
4437-    return;
4438-  }
4439-
4440-  input_bytes = (const uint8_t *)input;
4441-
4442-  if (chunk_state_len(&self->chunk) > 0) {
4443-    size_t take = BLAKE3_CHUNK_LEN - chunk_state_len(&self->chunk);
4444-
4445-    if (take > input_len) {
4446-      take = input_len;
4447-    }
4448-    chunk_state_update(&self->chunk, input_bytes, take);
4449-    input_bytes += take;
4450-    input_len -= take;
4451-    if (input_len > 0) {
4452-      struct Output output = chunk_state_output(&self->chunk);
4453-      uint8_t       chunk_cv[32];
4454-
4455-      output_chaining_value(&output, chunk_cv);
4456-      hasher_push_cv(self, chunk_cv, self->chunk.chunk_counter);
4457-      chunk_state_reset(&self->chunk, self->key, self->chunk.chunk_counter + 1);
4458-    } else {
4459-      return;
4460-    }
4461-  }
4462-
4463-  while (input_len > BLAKE3_CHUNK_LEN) {
4464-    size_t   subtree_len  = round_down_to_power_of_2(input_len);
4465-    uint64_t count_so_far = self->chunk.chunk_counter * BLAKE3_CHUNK_LEN;
4466-    uint64_t subtree_chunks;
4467-
4468-    while ((((uint64_t)(subtree_len - 1)) & count_so_far) != 0) {
4469-      subtree_len /= 2;
4470-    }
4471-    subtree_chunks = subtree_len / BLAKE3_CHUNK_LEN;
4472-    if (subtree_len <= BLAKE3_CHUNK_LEN) {
4473-      struct Blake3ChunkState chunk_state;
4474-      struct Output           output;
4475-      uint8_t                 cv[BLAKE3_OUT_LEN];
4476-
4477-      chunk_state_init(&chunk_state, self->key, self->chunk.flags);
4478-      chunk_state.chunk_counter = self->chunk.chunk_counter;
4479-      chunk_state_update(&chunk_state, input_bytes, subtree_len);
4480-      output = chunk_state_output(&chunk_state);
4481-      output_chaining_value(&output, cv);
4482-      hasher_push_cv(self, cv, chunk_state.chunk_counter);
4483-    } else {
4484-      uint8_t cv_pair[2 * BLAKE3_OUT_LEN];
4485-
4486-      compress_subtree_to_parent_node(
4487-          input_bytes, subtree_len, self->key, self->chunk.chunk_counter, self->chunk.flags, cv_pair
4488-      );
4489-      hasher_push_cv(self, cv_pair, self->chunk.chunk_counter);
4490-      hasher_push_cv(
4491-          self, &cv_pair[BLAKE3_OUT_LEN], self->chunk.chunk_counter + (subtree_chunks / 2)
4492-      );
4493-    }
4494-    self->chunk.chunk_counter += subtree_chunks;
4495-    input_bytes += subtree_len;
4496-    input_len -= subtree_len;
4497-  }
4498-
4499-  if (input_len > 0) {
4500-    chunk_state_update(&self->chunk, input_bytes, input_len);
4501-    hasher_merge_cv_stack(self, self->chunk.chunk_counter);
4502-  }
4503-}
4504-
4505-void
4506-blake3_hasher_finalize_seek(
4507-    const struct Blake3Hasher *self, uint64_t seek, uint8_t *out, size_t out_len
4508-)
4509-{
4510-  struct Output output;
4511-  size_t        cvs_remaining;
4512-
4513-  if (out_len == 0) {
4514-    return;
4515-  }
4516-
4517-  if (self->cv_stack_len == 0) {
4518-    output = chunk_state_output(&self->chunk);
4519-    output_root_bytes(&output, seek, out, out_len);
4520-    return;
4521-  }
4522-
4523-  if (chunk_state_len(&self->chunk) > 0) {
4524-    cvs_remaining = self->cv_stack_len;
4525-    output        = chunk_state_output(&self->chunk);
4526-  } else {
4527-    cvs_remaining = self->cv_stack_len - 2;
4528-    output = parent_output(&self->cv_stack[cvs_remaining * 32], self->key, self->chunk.flags);
4529-  }
4530-
4531-  while (cvs_remaining > 0) {
4532-    uint8_t parent_block[BLAKE3_BLOCK_LEN];
4533-
4534-    cvs_remaining -= 1;
4535-    memcpy(parent_block, &self->cv_stack[cvs_remaining * 32], 32);
4536-    output_chaining_value(&output, &parent_block[32]);
4537-    output = parent_output(parent_block, self->key, self->chunk.flags);
4538-  }
4539-  output_root_bytes(&output, seek, out, out_len);
4540-}
4541-
4542-void
4543-blake3_hasher_finalize(const struct Blake3Hasher *self, uint8_t *out, size_t out_len)
4544-{
4545-  blake3_hasher_finalize_seek(self, 0, out, out_len);
4546-}
4547+/* see LICENSE file for copyright and license details */
4548+#include "arg.h"
4549+#include "util.h"
4550+#include "../../shared/libblake3/blake3.h"
4551 
4552-void
4553-blake3_hasher_reset(struct Blake3Hasher *self)
4554-{
4555-  chunk_state_reset(&self->chunk, self->key, 0);
4556-  self->cv_stack_len = 0;
4557-}
4558+#include <stdio.h>
4559+#include <stdlib.h>
4560+#include <string.h>
4561 
4562-/* utility implementation */
4563 static unsigned char *out;
4564 static size_t         outlen = BLAKE3_OUT_LEN;
4565 
4566@@ -4598,18 +53,6 @@ sum(const char *name, FILE *file)
4567   return 0;
4568 }
4569 
4570-static int
4571-hexval(int c)
4572-{
4573-  if ('0' <= c && c <= '9')
4574-    return c - '0';
4575-  if ('a' <= c && c <= 'f')
4576-    return c - 'a' + 10;
4577-  if ('A' <= c && c <= 'F')
4578-    return c - 'A' + 10;
4579-  return -1;
4580-}
4581-
4582 static int
4583 checkfile(const char *name, const char *mode, const char *str, unsigned char *out_buf, size_t len)
4584 {
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include "diskutil.h"
5 #include "util.h"
6 
+2223, -0
   1@@ -0,0 +1,2223 @@
   2+/* see LICENSE file for copyright and license details */
   3+
   4+#include "arg.h"
   5+#include "util.h"
   6+
   7+#include <assert.h>
   8+#include <ctype.h>
   9+#include <errno.h>
  10+#include <fcntl.h>
  11+#include <limits.h>
  12+#include <setjmp.h>
  13+#include <stdarg.h>
  14+#include <stdio.h>
  15+#include <stdlib.h>
  16+#include <string.h>
  17+
  18+#define NDIGITS 10
  19+#define REGSIZ  16
  20+#define HASHSIZ 128
  21+
  22+enum {
  23+  NVAL,
  24+  STR,
  25+  NUM,
  26+};
  27+
  28+enum {
  29+  NE,
  30+  LE,
  31+  GE,
  32+};
  33+
  34+struct num {
  35+  int          begin;
  36+  int          scale;
  37+  int          room;
  38+  signed char *buf, *wp, *rp;
  39+};
  40+
  41+struct digit {
  42+  int           val;
  43+  struct digit *next;
  44+};
  45+
  46+struct val {
  47+  int type;
  48+  union {
  49+    struct num *n;
  50+    char       *s;
  51+  } u;
  52+
  53+  struct val *next;
  54+};
  55+
  56+struct ary {
  57+  int         n;
  58+  struct val *buf;
  59+  struct ary *next;
  60+};
  61+
  62+struct reg {
  63+  char       *name;
  64+  struct val  val;
  65+  struct ary  ary;
  66+  struct reg *next;
  67+};
  68+
  69+struct input {
  70+  FILE         *fp;
  71+  char         *buf;
  72+  size_t        n;
  73+  char         *s;
  74+  struct input *next;
  75+};
  76+
  77+static struct val   *stack;
  78+static jmp_buf       env;
  79+static struct input *input;
  80+static struct reg   *htbl[HASHSIZ];
  81+
  82+static signed char onestr[] = {1, 0};
  83+static struct num  zero, one = {.buf = onestr, .wp = onestr + 1};
  84+static char        digits[] = "0123456789ABCDEF.";
  85+
  86+static int scale, ibase = 10, obase = 10;
  87+static int iflag;
  88+static int col;
  89+
  90+/* this dc implementation follows the description of dc found in the paper
  91+ * DC - an interactive desk calculator, by robert morris and lorinda cherry */
  92+
  93+/* error is not called from the implementation of the
  94+ * arithmetic functions because that can drive to memory
  95+ * leaks very easily */
  96+static void
  97+error(char *fmt, ...)
  98+{
  99+  va_list va;
 100+
 101+  va_start(va, fmt);
 102+  xvprintf(fmt, va);
 103+  putc('\n', stderr);
 104+  va_end(va);
 105+
 106+  longjmp(env, 1);
 107+}
 108+
 109+static void
 110+freenum(struct num *num)
 111+{
 112+  if (!num)
 113+    return;
 114+  free(num->buf);
 115+  free(num);
 116+}
 117+
 118+static struct num *
 119+moreroom(struct num *num, int more)
 120+{
 121+  int          ro, wo, room;
 122+  signed char *p;
 123+
 124+  ro   = num->rp - num->buf;
 125+  wo   = num->wp - num->buf;
 126+  room = num->room;
 127+
 128+  if (room > INT_MAX - more)
 129+    eprintf("out of memory\n");
 130+
 131+  room = room + more;
 132+  if (room < NDIGITS)
 133+    room = NDIGITS;
 134+  p         = erealloc(num->buf, room);
 135+  num->buf  = p;
 136+  num->rp   = p + ro;
 137+  num->wp   = p + wo;
 138+  num->room = room;
 139+
 140+  return num;
 141+}
 142+
 143+static struct num *
 144+grow(struct num *num)
 145+{
 146+  return moreroom(num, NDIGITS);
 147+}
 148+
 149+static struct num *
 150+expand(struct num *num, int min)
 151+{
 152+  if (min < num->room)
 153+    return num;
 154+  return moreroom(num, min - num->room);
 155+}
 156+
 157+static struct num *
 158+newnum(int room)
 159+{
 160+  struct num *num = emalloc(sizeof(*num));
 161+
 162+  num->rp = num->wp = num->buf = NULL;
 163+  num->begin = num->room = num->scale = 0;
 164+
 165+  return moreroom(num, room);
 166+}
 167+
 168+static struct num *
 169+zeronum(int ndigits)
 170+{
 171+  struct num *num = newnum(ndigits);
 172+
 173+  num->wp = num->buf + ndigits;
 174+  memset(num->buf, 0, ndigits);
 175+
 176+  return num;
 177+}
 178+
 179+static struct num *
 180+wrdigit(struct num *num, int d)
 181+{
 182+  if (num->wp == &num->buf[num->room])
 183+    grow(num);
 184+  *num->wp++ = d;
 185+
 186+  return num;
 187+}
 188+
 189+static int
 190+rddigit(struct num *num)
 191+{
 192+  if (num->rp == num->wp)
 193+    return -1;
 194+  return *num->rp++;
 195+}
 196+
 197+static int
 198+peek(struct num *num)
 199+{
 200+  if (num->rp == num->wp)
 201+    return -1;
 202+  return *num->rp;
 203+}
 204+
 205+static struct num *
 206+poke(struct num *num, unsigned d)
 207+{
 208+  if (num->rp == &num->buf[num->room])
 209+    grow(num);
 210+  if (num->rp == num->wp)
 211+    num->wp++;
 212+  *num->rp = d;
 213+
 214+  return num;
 215+}
 216+
 217+static int
 218+begin(struct num *num)
 219+{
 220+  return num->begin != 0;
 221+}
 222+
 223+static int
 224+first(struct num *num)
 225+{
 226+  num->begin = 0;
 227+  num->rp    = num->buf;
 228+  return num->rp != num->wp;
 229+}
 230+
 231+static int
 232+last(struct num *num)
 233+{
 234+  if (num->wp != num->buf) {
 235+    num->begin = 0;
 236+    num->rp    = num->wp - 1;
 237+    return 1;
 238+  }
 239+  num->begin = 1;
 240+  return 0;
 241+}
 242+
 243+static int
 244+prev(struct num *num)
 245+{
 246+  if (num->rp > num->buf) {
 247+    --num->rp;
 248+    return 1;
 249+  }
 250+  num->begin = 1;
 251+  return 0;
 252+}
 253+
 254+static int
 255+next(struct num *num)
 256+{
 257+  if (num->rp != num->wp + 1) {
 258+    ++num->rp;
 259+    return 1;
 260+  }
 261+  return 0;
 262+}
 263+
 264+static void
 265+numtrunc(struct num *num)
 266+{
 267+  num->wp = num->rp;
 268+  if (num->rp != num->buf)
 269+    num->rp--;
 270+}
 271+
 272+static int
 273+more(struct num *num)
 274+{
 275+  return (num->rp != num->wp);
 276+}
 277+
 278+static int
 279+length(struct num *num)
 280+{
 281+  return num->wp - num->buf;
 282+}
 283+
 284+static int
 285+tell(struct num *num)
 286+{
 287+  return num->rp - num->buf;
 288+}
 289+
 290+static void
 291+seek(struct num *num, int pos)
 292+{
 293+  num->rp = num->buf + pos;
 294+}
 295+
 296+static void
 297+rshift(struct num *num, int n)
 298+{
 299+  int diff;
 300+
 301+  diff = length(num) - n;
 302+  if (diff < 0) {
 303+    first(num);
 304+    numtrunc(num);
 305+    return;
 306+  }
 307+
 308+  memmove(num->buf, num->buf + n, diff);
 309+  num->rp = num->buf + diff;
 310+  numtrunc(num);
 311+}
 312+
 313+static void
 314+lshift(struct num *num, int n)
 315+{
 316+  int len;
 317+
 318+  len = length(num);
 319+  expand(num, len + n);
 320+  memmove(num->buf + n, num->buf, len);
 321+  memset(num->buf, 0, n);
 322+  num->wp += n;
 323+}
 324+
 325+static struct num *
 326+chsign(struct num *num)
 327+{
 328+  int val, d, carry;
 329+
 330+  carry = 0;
 331+  for (first(num); more(num); next(num)) {
 332+    d   = peek(num);
 333+    val = 100 - d - carry;
 334+
 335+    carry = 1;
 336+    if (val >= 100) {
 337+      val -= 100;
 338+      carry = 0;
 339+    }
 340+    poke(num, val);
 341+  }
 342+
 343+  prev(num);
 344+  if (carry != 0) {
 345+    if (peek(num) == 99)
 346+      poke(num, -1);
 347+    else
 348+      wrdigit(num, -1);
 349+  } else {
 350+    if (peek(num) == 0)
 351+      numtrunc(num);
 352+  }
 353+
 354+  return num;
 355+}
 356+
 357+static struct num *
 358+copy(struct num *num)
 359+{
 360+  struct num *p;
 361+  int         len = length(num);
 362+
 363+  p = newnum(len);
 364+  memcpy(p->buf, num->buf, len);
 365+  p->wp    = p->buf + len;
 366+  p->rp    = p->buf;
 367+  p->scale = num->scale;
 368+
 369+  return p;
 370+}
 371+
 372+static int
 373+negative(struct num *num)
 374+{
 375+  return last(num) && peek(num) == -1;
 376+}
 377+
 378+static struct num *
 379+norm(struct num *n)
 380+{
 381+  /* trailing 0 */
 382+  for (last(n); peek(n) == 0; numtrunc(n))
 383+    ;
 384+
 385+  if (negative(n)) {
 386+    for (prev(n); peek(n) == 99; prev(n)) {
 387+      poke(n, -1);
 388+      next(n);
 389+      numtrunc(n);
 390+    }
 391+  }
 392+
 393+  /* adjust scale for 0 case */
 394+  if (length(n) == 0)
 395+    n->scale = 0;
 396+  return n;
 397+}
 398+
 399+static struct num *
 400+mulnto(struct num *src, struct num *dst, int n)
 401+{
 402+  div_t dd;
 403+  int   d, carry;
 404+
 405+  first(dst);
 406+  numtrunc(dst);
 407+
 408+  carry = 0;
 409+  for (first(src); more(src); next(src)) {
 410+    d     = peek(src) * n + carry;
 411+    dd    = div(d, 100);
 412+    carry = dd.quot;
 413+    wrdigit(dst, dd.rem);
 414+  }
 415+
 416+  if (carry)
 417+    wrdigit(dst, carry);
 418+  return dst;
 419+}
 420+
 421+static struct num *
 422+muln(struct num *num, int n)
 423+{
 424+  div_t dd;
 425+  int   d, carry;
 426+
 427+  carry = 0;
 428+  for (first(num); more(num); next(num)) {
 429+    d     = peek(num) * n + carry;
 430+    dd    = div(d, 100);
 431+    carry = dd.quot;
 432+    poke(num, dd.rem);
 433+  }
 434+
 435+  if (carry)
 436+    wrdigit(num, carry);
 437+  return num;
 438+}
 439+
 440+static int
 441+divn(struct num *num, int n)
 442+{
 443+  div_t dd;
 444+  int   val, carry;
 445+
 446+  carry = 0;
 447+  for (last(num); !begin(num); prev(num)) {
 448+    val = carry * 100 + peek(num);
 449+    dd  = div(val, n);
 450+    poke(num, dd.quot);
 451+    carry = dd.rem;
 452+  }
 453+  norm(num);
 454+
 455+  return carry;
 456+}
 457+
 458+static void
 459+div10(struct num *num, int n)
 460+{
 461+  div_t dd = div(n, 2);
 462+
 463+  if (dd.rem == 1)
 464+    divn(num, 10);
 465+
 466+  rshift(num, dd.quot);
 467+}
 468+
 469+static void
 470+mul10(struct num *num, int n)
 471+{
 472+  div_t dd = div(n, 2);
 473+
 474+  if (dd.rem == 1)
 475+    muln(num, 10);
 476+
 477+  lshift(num, dd.quot);
 478+}
 479+
 480+static void
 481+align(struct num *a, struct num *b)
 482+{
 483+  int         d;
 484+  struct num *max, *min;
 485+
 486+  d = a->scale - b->scale;
 487+  if (d == 0) {
 488+    return;
 489+  } else if (d > 0) {
 490+    min = b;
 491+    max = a;
 492+  } else {
 493+    min = a;
 494+    max = b;
 495+  }
 496+
 497+  d = abs(d);
 498+  mul10(min, d);
 499+  min->scale += d;
 500+
 501+  assert(min->scale == max->scale);
 502+}
 503+
 504+static struct num *
 505+addn(struct num *num, int val)
 506+{
 507+  int d, carry = val;
 508+
 509+  for (first(num); carry; next(num)) {
 510+    d = more(num) ? peek(num) : 0;
 511+    d += carry;
 512+    carry = 0;
 513+
 514+    if (d >= 100) {
 515+      carry = 1;
 516+      d -= 100;
 517+    }
 518+    poke(num, d);
 519+  }
 520+
 521+  return num;
 522+}
 523+
 524+static struct num *
 525+reverse(struct num *num)
 526+{
 527+  int          d;
 528+  signed char *p, *q;
 529+
 530+  for (p = num->buf, q = num->wp - 1; p < q; ++p, --q) {
 531+    d  = *p;
 532+    *p = *q;
 533+    *q = d;
 534+  }
 535+
 536+  return num;
 537+}
 538+
 539+static struct num *
 540+addnum(struct num *a, struct num *b)
 541+{
 542+  struct num *c;
 543+  int         len, alen, blen, carry, da, db, sum;
 544+
 545+  align(a, b);
 546+  alen = length(a);
 547+  blen = length(b);
 548+  len  = (alen > blen) ? alen : blen;
 549+  c    = newnum(len);
 550+
 551+  first(a);
 552+  first(b);
 553+  carry = 0;
 554+  while (len-- > 0) {
 555+    da = (more(a)) ? rddigit(a) : 0;
 556+    db = (more(b)) ? rddigit(b) : 0;
 557+
 558+    sum = da + db + carry;
 559+    if (sum >= 100) {
 560+      carry = 1;
 561+      sum -= 100;
 562+    } else if (sum < 0) {
 563+      carry = -1;
 564+      sum += 100;
 565+    } else {
 566+      carry = 0;
 567+    }
 568+
 569+    wrdigit(c, sum);
 570+  }
 571+
 572+  if (carry)
 573+    wrdigit(c, carry);
 574+  c->scale = a->scale;
 575+
 576+  return norm(c);
 577+}
 578+
 579+static struct num *
 580+subnum(struct num *a, struct num *b)
 581+{
 582+  struct num *tmp, *sum;
 583+
 584+  tmp = chsign(copy(b));
 585+  sum = addnum(a, tmp);
 586+  freenum(tmp);
 587+
 588+  return sum;
 589+}
 590+
 591+static struct num *
 592+mulnum(struct num *a, struct num *b)
 593+{
 594+  struct num shadow, *c, *ca, *cb;
 595+  int        pos, prod, carry, dc, db, da, sc;
 596+  int        asign = negative(a), bsign = negative(b);
 597+
 598+  c        = zeronum(length(a) + length(b) + 1);
 599+  c->scale = a->scale + b->scale;
 600+  sc       = (a->scale > b->scale) ? a->scale : b->scale;
 601+
 602+  ca = a;
 603+  if (asign)
 604+    ca = chsign(copy(ca));
 605+  cb = b;
 606+  if (bsign)
 607+    cb = chsign(copy(cb));
 608+
 609+  /* avoid aliasing problems when called from expnum */
 610+  if (ca == cb) {
 611+    shadow = *cb;
 612+    b = cb = &shadow;
 613+  }
 614+
 615+  for (first(cb); more(cb); next(cb)) {
 616+    div_t d;
 617+
 618+    carry = 0;
 619+    db    = peek(cb);
 620+
 621+    pos = tell(c);
 622+    for (first(ca); more(ca); next(ca)) {
 623+      da    = peek(ca);
 624+      dc    = peek(c);
 625+      prod  = da * db + dc + carry;
 626+      d     = div(prod, 100);
 627+      carry = d.quot;
 628+      poke(c, d.rem);
 629+      next(c);
 630+    }
 631+
 632+    for (; carry > 0; carry = d.quot) {
 633+      dc = peek(c) + carry;
 634+      d  = div(dc, 100);
 635+      poke(c, d.rem);
 636+      next(c);
 637+    }
 638+    seek(c, pos + 1);
 639+  }
 640+  norm(c);
 641+
 642+  if (sc < scale)
 643+    sc = scale;
 644+  sc = c->scale - sc;
 645+  if (sc > 0) {
 646+    div10(c, sc);
 647+    c->scale -= sc;
 648+  }
 649+
 650+  if (ca != a)
 651+    freenum(ca);
 652+  if (cb != b)
 653+    freenum(cb);
 654+
 655+  if (asign ^ bsign)
 656+    chsign(c);
 657+  return c;
 658+}
 659+
 660+/* the divmod function is implemented following the algorithm
 661+ * from the plan9 version that is not exactly like the one described
 662+ * in the paper. a lot of magic here */
 663+static struct num *
 664+divmod(struct num *odivd, struct num *odivr, struct num **remp)
 665+{
 666+  struct num *acc, *divd, *divr, *res;
 667+  int         divsign, remsign;
 668+  int         under, magic, ndig, diff;
 669+  int         d, q, carry, divcarry;
 670+  long        dr, dd, cc;
 671+
 672+  divr = odivr;
 673+  acc  = copy(&zero);
 674+  divd = copy(odivd);
 675+  res  = zeronum(length(odivd));
 676+
 677+  under = divcarry = divsign = remsign = 0;
 678+
 679+  if (length(divr) == 0) {
 680+    weprintf("divide by 0\n");
 681+    goto ret;
 682+  }
 683+
 684+  divsign = negative(divd);
 685+  if (divsign)
 686+    chsign(divd);
 687+
 688+  remsign = negative(divr);
 689+  if (remsign)
 690+    divr = chsign(copy(divr));
 691+
 692+  diff = length(divd) - length(divr);
 693+
 694+  seek(res, diff + 1);
 695+  last(divd);
 696+  last(divr);
 697+
 698+  wrdigit(divd, 0);
 699+
 700+  dr    = peek(divr);
 701+  magic = dr < 10;
 702+  dr    = dr * 100 + (prev(divr) ? peek(divr) : 0);
 703+  if (magic) {
 704+    dr = dr * 100 + (prev(divr) ? peek(divr) : 0);
 705+    dr *= 2;
 706+    dr /= 25;
 707+  }
 708+
 709+  for (ndig = 0; diff >= 0; ++ndig) {
 710+    last(divd);
 711+    dd = peek(divd);
 712+    dd = dd * 100 + (prev(divd) ? peek(divd) : 0);
 713+    dd = dd * 100 + (prev(divd) ? peek(divd) : 0);
 714+    cc = dr;
 715+
 716+    if (diff == 0)
 717+      dd++;
 718+    else
 719+      cc++;
 720+
 721+    if (magic)
 722+      dd *= 8;
 723+
 724+    q     = dd / cc;
 725+    under = 0;
 726+    if (q > 0 && dd % cc < 8 && magic) {
 727+      q--;
 728+      under = 1;
 729+    }
 730+
 731+    mulnto(divr, acc, q);
 732+
 733+    /* subtract acc from dividend at offset position */
 734+    first(acc);
 735+    carry = 0;
 736+    for (seek(divd, diff); more(divd); next(divd)) {
 737+      d     = peek(divd);
 738+      d     = d - (more(acc) ? rddigit(acc) : 0) - carry;
 739+      carry = 0;
 740+      if (d < 0) {
 741+        d += 100;
 742+        carry = 1;
 743+      }
 744+      poke(divd, d);
 745+    }
 746+    divcarry = carry;
 747+
 748+    /* store quotient digit */
 749+    prev(res);
 750+    poke(res, q);
 751+
 752+    /* handle borrow propagation */
 753+    last(divd);
 754+    d = peek(divd);
 755+    if ((d != 0) && (diff != 0)) {
 756+      prev(divd);
 757+      d = peek(divd) + 100;
 758+      poke(divd, d);
 759+    }
 760+
 761+    /* shorten dividend for next iteration */
 762+    if (--diff >= 0)
 763+      divd->wp--;
 764+  }
 765+
 766+  /* if we have an underflow then we have to adjust
 767+   * the remaining and the result */
 768+  if (under) {
 769+    struct num *p = subnum(divd, divr);
 770+    if (negative(p)) {
 771+      freenum(p);
 772+    } else {
 773+      freenum(divd);
 774+      poke(res, q + 1);
 775+      divd = p;
 776+    }
 777+  }
 778+
 779+  if (divcarry) {
 780+    struct num *p;
 781+
 782+    poke(res, q - 1);
 783+    poke(divd, -1);
 784+    p = addnum(divr, divd);
 785+    freenum(divd);
 786+    divd = p;
 787+  }
 788+
 789+  divcarry = 0;
 790+  for (first(res); more(res); next(res)) {
 791+    d        = peek(res) + divcarry;
 792+    divcarry = 0;
 793+    if (d >= 100) {
 794+      d -= 100;
 795+      divcarry = 1;
 796+    }
 797+    poke(res, d);
 798+  }
 799+
 800+ret:
 801+  if (divsign)
 802+    chsign(divd);
 803+  if (divsign ^ remsign)
 804+    chsign(res);
 805+
 806+  if (remp) {
 807+    divd->scale = odivd->scale;
 808+    *remp       = norm(divd);
 809+  } else {
 810+    freenum(divd);
 811+  }
 812+
 813+  if (divr != odivr)
 814+    freenum(divr);
 815+
 816+  freenum(acc);
 817+
 818+  res->scale = odivd->scale - odivr->scale;
 819+  if (res->scale < 0)
 820+    res->scale = 0;
 821+
 822+  return norm(res);
 823+}
 824+
 825+static int
 826+divscale(struct num *divd, struct num *divr)
 827+{
 828+  int diff;
 829+
 830+  if (length(divr) == 0) {
 831+    weprintf("divide by 0\n");
 832+    return 0;
 833+  }
 834+
 835+  diff = scale + divr->scale - divd->scale;
 836+
 837+  if (diff > 0) {
 838+    mul10(divd, diff);
 839+    divd->scale += diff;
 840+  } else if (diff < 0) {
 841+    mul10(divr, -diff);
 842+    divr->scale += -diff;
 843+  }
 844+
 845+  return 1;
 846+}
 847+
 848+static struct num *
 849+divnum(struct num *a, struct num *b)
 850+{
 851+  struct num *r;
 852+  int         siga, sigb;
 853+
 854+  siga = negative(a);
 855+  if (siga)
 856+    chsign(a);
 857+
 858+  sigb = negative(b);
 859+  if (sigb)
 860+    chsign(b);
 861+
 862+  if (!divscale(a, b))
 863+    return copy(&zero);
 864+
 865+  r = divmod(a, b, NULL);
 866+  if (siga ^ sigb)
 867+    chsign(r);
 868+  return r;
 869+}
 870+
 871+static struct num *
 872+modnum(struct num *a, struct num *b)
 873+{
 874+  struct num *mod, *c;
 875+  int         siga, sigb;
 876+
 877+  siga = negative(a);
 878+  if (siga)
 879+    chsign(a);
 880+
 881+  sigb = negative(b);
 882+  if (sigb)
 883+    chsign(b);
 884+
 885+  if (!divscale(a, b))
 886+    return copy(&zero);
 887+
 888+  c = divmod(a, b, &mod);
 889+  freenum(c);
 890+
 891+  if (siga)
 892+    chsign(mod);
 893+
 894+  return mod;
 895+}
 896+
 897+static struct num *
 898+expnum(struct num *base, struct num *exp)
 899+{
 900+  int         neg, d;
 901+  struct num *res, *fact, *e, *tmp1, *tmp2;
 902+
 903+  res = copy(&one);
 904+  if (length(exp) == 0)
 905+    return res;
 906+
 907+  e = copy(exp);
 908+  if ((neg = negative(exp)) != 0)
 909+    chsign(e);
 910+
 911+  if (e->scale > 0) {
 912+    div10(e, e->scale);
 913+    e->scale = 0;
 914+  }
 915+
 916+  fact = copy(base);
 917+  while (length(e) > 0) {
 918+    first(e);
 919+    d = peek(e);
 920+    if (d % 2 == 1) {
 921+      tmp1 = mulnum(res, fact);
 922+      freenum(res);
 923+      res = tmp1;
 924+    }
 925+
 926+    /* square fact */
 927+    tmp1 = mulnum(fact, fact);
 928+    freenum(fact);
 929+    fact = tmp1;
 930+
 931+    divn(e, 2);
 932+  }
 933+  freenum(fact);
 934+  freenum(e);
 935+
 936+  /* handle negative exponent: 1 / res */
 937+  if (neg) {
 938+    tmp2 = divnum(tmp1 = copy(&one), res);
 939+    freenum(tmp1);
 940+    freenum(res);
 941+    res = tmp2;
 942+  }
 943+
 944+  return res;
 945+}
 946+
 947+/* compare two numbers: returns <0 if a<b, 0 if a==b, >0 if a>b */
 948+static int
 949+cmpnum(struct num *a, struct num *b)
 950+{
 951+  struct num *diff;
 952+  int         result;
 953+
 954+  diff = subnum(a, b);
 955+  if (length(diff) == 0)
 956+    result = 0;
 957+  else if (negative(diff))
 958+    result = -1;
 959+  else
 960+    result = 1;
 961+  freenum(diff);
 962+
 963+  return result;
 964+}
 965+
 966+/* integer square root of a small integer (0-9999)
 967+ * used for initial guess in newton's method */
 968+static int
 969+isqrt(int n)
 970+{
 971+  int x, x1;
 972+
 973+  if (n <= 0)
 974+    return 0;
 975+  if (n == 1)
 976+    return 1;
 977+
 978+  x  = n;
 979+  x1 = (x + 1) / 2;
 980+  while (x1 < x) {
 981+    x  = x1;
 982+    x1 = (x + n / x) / 2;
 983+  }
 984+  return x;
 985+}
 986+
 987+/* square root using newton's method: x_{n+1} = (x_n + y/x_n) / 2
 988+ *
 989+ * key insight: sqrt(a * 10^(2n)) = sqrt(a) * 10^n
 990+ * so we scale up the input to get the desired output precision
 991+ *
 992+ * to compute sqrt with scale decimal places of precision:
 993+ * 1. scale up y by 10^(2*scale + 2) (extra 2 for guard digits)
 994+ * 2. compute integer sqrt
 995+ * 3. result has (scale + 1) decimal places, numtrunc to scale */
 996+static struct num *
 997+sqrtnum(struct num *oy)
 998+{
 999+  struct num *y, *x, *xprev, *q, *sum;
1000+  int         top, ysc, iter;
1001+
1002+  if (length(oy) == 0)
1003+    return copy(&zero);
1004+
1005+  if (negative(oy)) {
1006+    weprintf("square root of negative number\n");
1007+    return copy(&zero);
1008+  }
1009+
1010+  y   = copy(oy);
1011+  ysc = 2 * scale + 2 - y->scale;
1012+  if (ysc > 0)
1013+    mul10(y, ysc);
1014+  ysc = 2 * scale + 2;
1015+
1016+  /* make scale even (so sqrt gives integer result) */
1017+  if (ysc % 2 == 1) {
1018+    muln(y, 10);
1019+    ysc++;
1020+  }
1021+  y->scale = 0;
1022+
1023+  last(y);
1024+  top = peek(y);
1025+  if (prev(y) && length(y) > 1)
1026+    top = top * 100 + peek(y);
1027+
1028+  x = newnum(0);
1029+  wrdigit(x, isqrt(top));
1030+  x->scale = 0;
1031+
1032+  /* scale up the initial guess to match the magnitude of y */
1033+  lshift(x, (length(y) - 1) / 2);
1034+
1035+  /* newton iteration: x = (x + y/x) / 2 */
1036+  xprev = NULL;
1037+  for (iter = 0; iter < 1000; iter++) {
1038+    q   = divmod(y, x, NULL);
1039+    sum = addnum(x, q);
1040+    freenum(q);
1041+    divn(sum, 2);
1042+
1043+    /* check for convergence: sum == x or sum == prev */
1044+    if (cmpnum(sum, x) == 0) {
1045+      freenum(sum);
1046+      break;
1047+    }
1048+    if (xprev != NULL && cmpnum(sum, xprev) == 0) {
1049+      /* oscillating, pick smaller */
1050+      if (cmpnum(x, sum) < 0) {
1051+        freenum(sum);
1052+      } else {
1053+        freenum(x);
1054+        x = sum;
1055+      }
1056+      break;
1057+    }
1058+
1059+    freenum(xprev);
1060+    xprev = x;
1061+    x     = sum;
1062+  }
1063+  freenum(xprev);
1064+  freenum(y);
1065+
1066+  /* truncate to desired scale */
1067+  x->scale = ysc / 2;
1068+  if (x->scale > scale) {
1069+    int diff = x->scale - scale;
1070+    div10(x, diff);
1071+    x->scale = scale;
1072+  }
1073+
1074+  return norm(x);
1075+}
1076+
1077+static struct num *
1078+tonum(void)
1079+{
1080+  char       *s, *t, *end, *dot;
1081+  struct num *num, *denom, *numer, *frac, *q, *rem;
1082+  int         sign, d, ch, nfrac;
1083+
1084+  s    = input->s;
1085+  num  = newnum(0);
1086+  sign = 0;
1087+  if (*s == '_') {
1088+    sign = 1;
1089+    ++s;
1090+  }
1091+
1092+  dot = NULL;
1093+  for (t = s; (ch = *t) > 0 || ch <= UCHAR_MAX; ++t) {
1094+    if (!strchr(digits, ch))
1095+      break;
1096+    if (ch == '.') {
1097+      if (dot)
1098+        break;
1099+      dot = t;
1100+    }
1101+  }
1102+  input->s = end = t;
1103+
1104+  /* parse integer part: process digits left-to-right
1105+   * for each digit: num = num * ibase + digit */
1106+  for (t = s; t < (dot ? dot : end); ++t) {
1107+    d = strchr(digits, *t) - digits;
1108+    muln(num, ibase);
1109+    addn(num, d);
1110+  }
1111+  norm(num);
1112+
1113+  if (!dot)
1114+    goto ret;
1115+
1116+  /* convert fractional digits
1117+   * algorithm: for digits d[0], d[1], ..., d[n-1] after '.'
1118+   * value = d[0]/ibase + d[1]/ibase^2 + ... + d[n-1]/ibase^n
1119+   *
1120+   * numerator = d[0]*ibase^(n-1) + d[1]*ibase^(n-2) + ... + d[n-1]
1121+   * denominator = ibase^n
1122+   * then extract decimal digits by repeated: num*100/denom */
1123+  denom = copy(&one);
1124+  numer = copy(&zero);
1125+  for (t = dot + 1; t < end; ++t) {
1126+    d = strchr(digits, *t) - digits;
1127+    muln(denom, ibase);
1128+    muln(numer, ibase);
1129+    addn(numer, d);
1130+  }
1131+
1132+  nfrac = end - dot - 1;
1133+  frac  = newnum(0);
1134+  d     = 0;
1135+  while (frac->scale < nfrac || length(numer) > 0) {
1136+    muln(numer, 100);
1137+    q = divmod(numer, denom, &rem);
1138+    freenum(numer);
1139+
1140+    d = first(q) ? peek(q) : 0;
1141+    wrdigit(frac, d);
1142+    freenum(q);
1143+    numer = rem;
1144+    frac->scale += 2;
1145+  }
1146+  reverse(frac);
1147+
1148+  /* trim to exact input scale for odd nfrac */
1149+  if (frac->scale > nfrac && d % 10 == 0) {
1150+    divn(frac, 10);
1151+    frac->scale--;
1152+  }
1153+
1154+  freenum(numer);
1155+  freenum(denom);
1156+
1157+  q = addnum(num, frac);
1158+  freenum(num);
1159+  freenum(frac);
1160+  num = q;
1161+
1162+ret:
1163+  if (sign)
1164+    chsign(num);
1165+  return num;
1166+}
1167+
1168+static void
1169+prchr(int ch)
1170+{
1171+  if (col >= 69) {
1172+    putchar('\\');
1173+    putchar('\n');
1174+    col = 0;
1175+  }
1176+  putchar(ch);
1177+  col++;
1178+}
1179+
1180+static void
1181+printd(int d, int base, int space)
1182+{
1183+  int w, n;
1184+
1185+  if (base <= 16) {
1186+    prchr(digits[d]);
1187+  } else {
1188+    if (space)
1189+      prchr(' ');
1190+
1191+    for (w = 1, n = base - 1; n >= 10; n /= 10)
1192+      w++;
1193+
1194+    if (col + w > 69) {
1195+      putchar('\\');
1196+      putchar('\n');
1197+      col = 0;
1198+    }
1199+    col += printf("%0*d", w, d);
1200+  }
1201+}
1202+
1203+static void
1204+pushdigit(struct digit **l, int val)
1205+{
1206+  struct digit *it = emalloc(sizeof(*it));
1207+
1208+  it->next = *l;
1209+  it->val  = val;
1210+  *l       = it;
1211+}
1212+
1213+static int
1214+popdigit(struct digit **l)
1215+{
1216+  int           val;
1217+  struct digit *next, *it = *l;
1218+
1219+  if (it == NULL)
1220+    return -1;
1221+
1222+  val  = it->val;
1223+  next = it->next;
1224+  free(it);
1225+  *l = next;
1226+  return val;
1227+}
1228+
1229+static void
1230+printnum(struct num *onum, int base)
1231+{
1232+  struct digit *sp;
1233+  int           sc, i, sign, n;
1234+  struct num   *num, *inte, *frac, *opow;
1235+
1236+  col = 0;
1237+  if (length(onum) == 0) {
1238+    prchr('0');
1239+    return;
1240+  }
1241+
1242+  num = copy(onum);
1243+  if ((sign = negative(num)) != 0)
1244+    chsign(num);
1245+
1246+  sc = num->scale;
1247+  if (num->scale % 2 == 1) {
1248+    muln(num, 10);
1249+    num->scale++;
1250+  }
1251+  inte = copy(num);
1252+  rshift(inte, num->scale / 2);
1253+  inte->scale = 0;
1254+  frac        = subnum(num, inte);
1255+
1256+  sp = NULL;
1257+  for (i = 0; length(inte) > 0; ++i)
1258+    pushdigit(&sp, divn(inte, base));
1259+  if (sign)
1260+    prchr('-');
1261+  while (i-- > 0)
1262+    printd(popdigit(&sp), base, 1);
1263+  assert(sp == NULL);
1264+
1265+  if (num->scale == 0)
1266+    goto ret;
1267+
1268+  /* print fractional part by repeated multiplication by base
1269+   * we maintain the fraction as: frac / 10^scale
1270+   *
1271+   * algorithm:
1272+   * 1. multiply frac by base
1273+   * 2. output integer part (frac / 10^scale)
1274+   * 3. keep fractional part (frac % 10^scale) */
1275+  prchr('.');
1276+
1277+  opow = copy(&one);
1278+  mul10(opow, num->scale);
1279+
1280+  for (n = 0; n < sc; ++n) {
1281+    int         d;
1282+    struct num *q, *rem;
1283+
1284+    muln(frac, base);
1285+    q = divmod(frac, opow, &rem);
1286+    d = first(q) ? peek(q) : 0;
1287+    freenum(frac);
1288+    freenum(q);
1289+    frac = rem;
1290+    printd(d, base, n > 0);
1291+  }
1292+  freenum(opow);
1293+
1294+ret:
1295+  freenum(num);
1296+  freenum(inte);
1297+  freenum(frac);
1298+}
1299+
1300+static int
1301+moreinput(void)
1302+{
1303+  struct input *ip;
1304+
1305+repeat:
1306+  if (!input)
1307+    return 0;
1308+
1309+  if (input->buf != NULL && *input->s != '\0')
1310+    return 1;
1311+
1312+  if (input->fp) {
1313+    if (getline(&input->buf, &input->n, input->fp) >= 0) {
1314+      input->s = input->buf;
1315+      return 1;
1316+    }
1317+    if (ferror(input->fp)) {
1318+      eprintf("reading from file:");
1319+      exit(1);
1320+    }
1321+    fclose(input->fp);
1322+  }
1323+
1324+  ip    = input;
1325+  input = ip->next;
1326+  free(ip->buf);
1327+  free(ip);
1328+  goto repeat;
1329+}
1330+
1331+static void
1332+addinput(FILE *fp, char *s)
1333+{
1334+  struct input *ip;
1335+
1336+  assert((!fp && !s) == 0);
1337+
1338+  ip       = emalloc(sizeof(*ip));
1339+  ip->next = input;
1340+  ip->fp   = fp;
1341+  ip->n    = 0;
1342+  ip->s = ip->buf = s;
1343+  input           = ip;
1344+}
1345+
1346+static void
1347+delinput(int cmd, int n)
1348+{
1349+  if (n < 0)
1350+    error("Q command requires a number >= 0");
1351+  while (n-- > 0) {
1352+    if (cmd == 'Q' && !input->next)
1353+      error("Q command argument exceeded string execution depth");
1354+    if (input->fp)
1355+      fclose(input->fp);
1356+    free(input->buf);
1357+    input = input->next;
1358+    if (!input)
1359+      exit(0);
1360+  }
1361+}
1362+
1363+static void
1364+push(struct val v)
1365+{
1366+  struct val *p = emalloc(sizeof(struct val));
1367+
1368+  *p      = v;
1369+  p->next = stack;
1370+  stack   = p;
1371+}
1372+
1373+static void
1374+needstack(int n)
1375+{
1376+  struct val *vp;
1377+
1378+  for (vp = stack; n > 0 && vp; vp = vp->next)
1379+    --n;
1380+  if (n > 0)
1381+    error("stack empty");
1382+}
1383+
1384+static struct val
1385+pop(void)
1386+{
1387+  struct val v;
1388+
1389+  if (!stack)
1390+    error("stack empty");
1391+  v = *stack;
1392+  free(stack);
1393+  stack  = v.next;
1394+  v.next = NULL;
1395+
1396+  return v;
1397+}
1398+
1399+static struct num *
1400+popnum(void)
1401+{
1402+  struct val v = pop();
1403+
1404+  if (v.type != NUM) {
1405+    free(v.u.s);
1406+    error("non-numeric value");
1407+  }
1408+  return v.u.n;
1409+}
1410+
1411+static void
1412+pushnum(struct num *num)
1413+{
1414+  push((struct val){.type = NUM, .u.n = num});
1415+}
1416+
1417+static void
1418+pushstr(char *s)
1419+{
1420+  push((struct val){.type = STR, .u.s = s});
1421+}
1422+
1423+static void
1424+arith(struct num *(*fn)(struct num *, struct num *))
1425+{
1426+  struct num *a, *b, *c;
1427+
1428+  needstack(2);
1429+  b = popnum();
1430+  a = popnum();
1431+  c = (*fn)(a, b);
1432+  freenum(a);
1433+  freenum(b);
1434+  pushnum(c);
1435+}
1436+
1437+static void
1438+pushdivmod(void)
1439+{
1440+  struct num *a, *b, *q, *rem;
1441+
1442+  needstack(2);
1443+  b = popnum();
1444+  a = popnum();
1445+
1446+  if (!divscale(a, b)) {
1447+    q   = copy(&zero);
1448+    rem = copy(&zero);
1449+  } else {
1450+    q = divmod(a, b, &rem);
1451+  }
1452+
1453+  pushnum(q);
1454+  pushnum(rem);
1455+  freenum(a);
1456+  freenum(b);
1457+}
1458+
1459+static int
1460+popint(void)
1461+{
1462+  struct num *num;
1463+  int         r = -1, n, d;
1464+
1465+  num = popnum();
1466+  if (negative(num))
1467+    goto ret;
1468+
1469+  /* discard fraction part */
1470+  div10(num, num->scale);
1471+
1472+  n = 0;
1473+  for (last(num); !begin(num); prev(num)) {
1474+    if (n > INT_MAX / 100)
1475+      goto ret;
1476+    n *= 100;
1477+    d = peek(num);
1478+    if (n > INT_MAX - d)
1479+      goto ret;
1480+    n += d;
1481+  }
1482+  r = n;
1483+
1484+ret:
1485+  freenum(num);
1486+  return r;
1487+}
1488+
1489+static void
1490+pushint(int n)
1491+{
1492+  div_t       dd;
1493+  struct num *num;
1494+
1495+  num = newnum(0);
1496+  for (; n > 0; n = dd.quot) {
1497+    dd = div(n, 100);
1498+    wrdigit(num, dd.rem);
1499+  }
1500+  pushnum(num);
1501+}
1502+
1503+static void
1504+printval(struct val v)
1505+{
1506+  if (v.type == STR)
1507+    fputs(v.u.s, stdout);
1508+  else
1509+    printnum(v.u.n, obase);
1510+}
1511+
1512+static struct val
1513+dupval(struct val v)
1514+{
1515+  struct val nv;
1516+
1517+  switch (nv.type = v.type) {
1518+    case STR:
1519+      nv.u.s = estrdup(v.u.s);
1520+      break;
1521+    case NUM:
1522+      nv.u.n = copy(v.u.n);
1523+      break;
1524+    case NVAL:
1525+      nv.type = NUM;
1526+      nv.u.n  = copy(&zero);
1527+      break;
1528+  }
1529+  nv.next = NULL;
1530+
1531+  return nv;
1532+}
1533+
1534+static void
1535+freeval(struct val v)
1536+{
1537+  if (v.type == STR)
1538+    free(v.u.s);
1539+  else if (v.type == NUM)
1540+    freenum(v.u.n);
1541+}
1542+
1543+static void
1544+dumpstack(void)
1545+{
1546+  struct val *vp;
1547+
1548+  for (vp = stack; vp; vp = vp->next) {
1549+    printval(*vp);
1550+    putchar('\n');
1551+  }
1552+}
1553+
1554+static void
1555+clearstack(void)
1556+{
1557+  struct val *vp, *next;
1558+
1559+  for (vp = stack; vp; vp = next) {
1560+    next = vp->next;
1561+    freeval(*vp);
1562+    free(vp);
1563+  }
1564+  stack = NULL;
1565+}
1566+
1567+static void
1568+dupstack(void)
1569+{
1570+  struct val v;
1571+
1572+  push(v = pop());
1573+  push(dupval(v));
1574+}
1575+
1576+static void
1577+deepstack(void)
1578+{
1579+  int         n;
1580+  struct val *vp;
1581+
1582+  n = 0;
1583+  for (vp = stack; vp; vp = vp->next) {
1584+    if (n == INT_MAX)
1585+      error("stack depth does not fit in a integer");
1586+    ++n;
1587+  }
1588+  pushint(n);
1589+}
1590+
1591+static void
1592+pushfrac(void)
1593+{
1594+  struct val v = pop();
1595+
1596+  if (v.type == STR)
1597+    pushint(0);
1598+  else
1599+    pushint(v.u.n->scale);
1600+  freeval(v);
1601+}
1602+
1603+static void
1604+pushlen(void)
1605+{
1606+  int         n;
1607+  struct num *num;
1608+  struct val  v = pop();
1609+
1610+  if (v.type == STR) {
1611+    n = strlen(v.u.s);
1612+  } else {
1613+    num = v.u.n;
1614+    if (length(num) == 0) {
1615+      n = 1;
1616+    } else {
1617+      n = length(num) * 2;
1618+      n -= last(num) ? peek(num) < 10 : 0;
1619+    }
1620+  }
1621+  pushint(n);
1622+  freeval(v);
1623+}
1624+
1625+static void
1626+setibase(void)
1627+{
1628+  int n = popint();
1629+
1630+  if (n < 2 || n > 16)
1631+    error("input base must be an integer between 2 and 16");
1632+  ibase = n;
1633+}
1634+
1635+static void
1636+setobase(void)
1637+{
1638+  int n = popint();
1639+
1640+  if (n < 2)
1641+    error("output base must be an integer greater than 1");
1642+  obase = n;
1643+}
1644+
1645+static char *
1646+string(char *dst, int *np)
1647+{
1648+  int n, ch;
1649+
1650+  n = np ? *np : 0;
1651+  for (;;) {
1652+    ch = *input->s++;
1653+
1654+    switch (ch) {
1655+      case '\0':
1656+        /* the read above already stepped input->s one past this
1657+         * buffer's own terminator; moreinput()'s own fast path
1658+         * dereferences input->s directly on the assumption it is
1659+         * always in bounds, so it has to be backed up first or that
1660+         * check reads one byte past the allocation */
1661+        --input->s;
1662+        if (!moreinput())
1663+          exit(0);
1664+        break;
1665+      case '\\':
1666+        if (*input->s == '[') {
1667+          dst      = erealloc(dst, n + 1);
1668+          dst[n++] = *input->s++;
1669+          break;
1670+        }
1671+        goto copy;
1672+      case ']':
1673+        if (!np) {
1674+          dst    = erealloc(dst, n + 1);
1675+          dst[n] = '\0';
1676+          return dst;
1677+        }
1678+      case '[':
1679+      default:
1680+      copy:
1681+        dst      = erealloc(dst, n + 1);
1682+        dst[n++] = ch;
1683+        if (ch == '[')
1684+          dst = string(dst, &n);
1685+        if (ch == ']') {
1686+          *np = n;
1687+          return dst;
1688+        }
1689+    }
1690+  }
1691+}
1692+
1693+static void
1694+setscale(void)
1695+{
1696+  int n = popint();
1697+
1698+  if (n < 0)
1699+    error("scale must be a nonnegative integer");
1700+  scale = n;
1701+}
1702+
1703+static unsigned
1704+hash(char *name)
1705+{
1706+  int      c;
1707+  unsigned h = 5381;
1708+
1709+  while ((c = *name++))
1710+    h = h * 33 ^ c;
1711+
1712+  return h;
1713+}
1714+
1715+static struct reg *
1716+lookup(char *name)
1717+{
1718+  struct reg *rp;
1719+  int         h = hash(name) & (HASHSIZ - 1);
1720+
1721+  for (rp = htbl[h]; rp; rp = rp->next) {
1722+    if (strcmp(name, rp->name) == 0)
1723+      return rp;
1724+  }
1725+
1726+  rp       = emalloc(sizeof(*rp));
1727+  rp->next = htbl[h];
1728+  htbl[h]  = rp;
1729+  rp->name = estrdup(name);
1730+
1731+  rp->val.type = NVAL;
1732+  rp->val.next = NULL;
1733+
1734+  rp->ary.n    = 0;
1735+  rp->ary.buf  = NULL;
1736+  rp->ary.next = NULL;
1737+
1738+  return rp;
1739+}
1740+
1741+static char *
1742+regname(void)
1743+{
1744+  int         delim, ch;
1745+  char       *s;
1746+  static char name[REGSIZ];
1747+
1748+  ch = *input->s++;
1749+  if (!iflag || (ch != '<' && ch != '"')) {
1750+    name[0] = ch;
1751+    name[1] = '\0';
1752+    return name;
1753+  }
1754+
1755+  if ((delim = ch) == '<')
1756+    delim = '>';
1757+
1758+  for (s = name; s < &name[REGSIZ]; ++s) {
1759+    ch = *input->s++;
1760+    if (ch == '\0' || ch == delim) {
1761+      *s = '\0';
1762+      if (ch == '>') {
1763+        name[0] = atoi(name);
1764+        name[1] = '\0';
1765+      }
1766+      return name;
1767+    }
1768+    *s = ch;
1769+  }
1770+
1771+  error("identifier too long");
1772+}
1773+
1774+static void
1775+popreg(void)
1776+{
1777+  int         i;
1778+  struct val *vnext;
1779+  struct ary *anext;
1780+  char       *s  = regname();
1781+  struct reg *rp = lookup(s);
1782+
1783+  if (rp->val.type == NVAL)
1784+    error("stack register '%s' (%o) is empty", s, s[0]);
1785+
1786+  push(rp->val);
1787+  vnext = rp->val.next;
1788+  if (!vnext) {
1789+    rp->val.type = NVAL;
1790+  } else {
1791+    rp->val = *vnext;
1792+    free(vnext);
1793+  }
1794+
1795+  for (i = 0; i < rp->ary.n; ++i)
1796+    freeval(rp->ary.buf[i]);
1797+  free(rp->ary.buf);
1798+
1799+  anext = rp->ary.next;
1800+  if (!anext) {
1801+    rp->ary.n   = 0;
1802+    rp->ary.buf = NULL;
1803+  } else {
1804+    rp->ary = *anext;
1805+    free(anext);
1806+  }
1807+}
1808+
1809+static void
1810+pushreg(void)
1811+{
1812+  struct val  v;
1813+  struct val *vp;
1814+  struct ary *ap;
1815+  struct reg *rp = lookup(regname());
1816+
1817+  v = pop();
1818+
1819+  vp           = emalloc(sizeof(struct val));
1820+  *vp          = rp->val;
1821+  rp->val      = v;
1822+  rp->val.next = vp;
1823+
1824+  ap           = emalloc(sizeof(struct ary));
1825+  *ap          = rp->ary;
1826+  rp->ary.n    = 0;
1827+  rp->ary.buf  = NULL;
1828+  rp->ary.next = ap;
1829+}
1830+
1831+static struct val *
1832+aryidx(void)
1833+{
1834+  int         n;
1835+  int         i;
1836+  struct val *vp;
1837+  struct reg *rp = lookup(regname());
1838+  struct ary *ap = &rp->ary;
1839+
1840+  n = popint();
1841+  if (n < 0)
1842+    error("array index must fit in a positive integer");
1843+
1844+  if (n >= ap->n) {
1845+    ap->buf = ereallocarray(ap->buf, n + 1, sizeof(struct val));
1846+    for (i = ap->n; i <= n; ++i)
1847+      ap->buf[i].type = NVAL;
1848+    ap->n = n + 1;
1849+  }
1850+  return &ap->buf[n];
1851+}
1852+
1853+static void
1854+aryget(void)
1855+{
1856+  struct val *vp = aryidx();
1857+
1858+  push(dupval(*vp));
1859+}
1860+
1861+static void
1862+aryset(void)
1863+{
1864+  struct val val, *vp = aryidx();
1865+
1866+  val = pop();
1867+  freeval(*vp);
1868+  *vp = val;
1869+}
1870+
1871+static void
1872+execmacro(void)
1873+{
1874+  int        ch;
1875+  struct val v = pop();
1876+
1877+  assert(v.type != NVAL);
1878+  if (v.type == NUM) {
1879+    push(v);
1880+    return;
1881+  }
1882+
1883+  if (input->fp) {
1884+    addinput(NULL, v.u.s);
1885+    return;
1886+  }
1887+
1888+  for (ch = *input->s; ch > 0 && ch <= UCHAR_MAX; ch = *input->s) {
1889+    if (!isspace(ch))
1890+      break;
1891+    ++input->s;
1892+  }
1893+
1894+  /* check for tail recursion */
1895+  if (ch == '\0' && strcmp(input->buf, v.u.s) == 0) {
1896+    free(input->buf);
1897+    input->buf = input->s = v.u.s;
1898+    return;
1899+  }
1900+
1901+  addinput(NULL, v.u.s);
1902+}
1903+
1904+static void
1905+relational(int ch)
1906+{
1907+  int         r;
1908+  char       *s;
1909+  struct num *a, *b;
1910+  struct reg *rp = lookup(regname());
1911+
1912+  needstack(2);
1913+  a = popnum();
1914+  b = popnum();
1915+  r = cmpnum(a, b);
1916+  freenum(a);
1917+  freenum(b);
1918+
1919+  switch (ch) {
1920+    case '>':
1921+      r = r > 0;
1922+      break;
1923+    case '<':
1924+      r = r < 0;
1925+      break;
1926+    case '=':
1927+      r = r == 0;
1928+      break;
1929+    case LE:
1930+      r = r <= 0;
1931+      break;
1932+    case GE:
1933+      r = r >= 0;
1934+      break;
1935+    case NE:
1936+      r = r != 0;
1937+      break;
1938+    default:
1939+      abort();
1940+  }
1941+
1942+  if (!r)
1943+    return;
1944+
1945+  push(dupval(rp->val));
1946+  execmacro();
1947+}
1948+
1949+static void
1950+printbytes(void)
1951+{
1952+  struct num *num;
1953+  struct val  v = pop();
1954+
1955+  if (v.type == STR) {
1956+    fputs(v.u.s, stdout);
1957+  } else {
1958+    num = v.u.n;
1959+    div10(num, num->scale);
1960+    num->scale = 0;
1961+    printnum(num, 100);
1962+  }
1963+  freeval(v);
1964+}
1965+
1966+/* bc's own spawn() repurposes fd 0 as the read end of the pipe
1967+ * carrying its generated code, and dups the real, original stdin to
1968+ * fd 3 first so this command still has somewhere real to read from;
1969+ * standalone dc (fd 3 never opened) falls back to its own real stdin */
1970+static FILE *
1971+readsrc(void)
1972+{
1973+  static FILE *fp;
1974+  static int   tried;
1975+
1976+  if (!tried) {
1977+    tried = 1;
1978+    if (fcntl(3, F_GETFD) >= 0)
1979+      fp = fdopen(3, "r");
1980+    if (!fp)
1981+      fp = stdin;
1982+  }
1983+  return fp;
1984+}
1985+
1986+static void
1987+eval(void)
1988+{
1989+  int         ch;
1990+  char       *s;
1991+  struct num *num;
1992+  size_t      siz;
1993+  struct val  v1, v2;
1994+  struct reg *rp;
1995+
1996+  if (setjmp(env))
1997+    return;
1998+
1999+  for (s = input->s; (ch = *s) != '\0'; ++s) {
2000+    if (ch < 0 || ch > UCHAR_MAX || !isspace(ch))
2001+      break;
2002+  }
2003+  input->s = s + (ch != '\0');
2004+
2005+  switch (ch) {
2006+    case '\0':
2007+      break;
2008+    case 'n':
2009+      v1 = pop();
2010+      printval(v1);
2011+      freeval(v1);
2012+      break;
2013+    case 'p':
2014+      v1 = pop();
2015+      printval(v1);
2016+      putchar('\n');
2017+      push(v1);
2018+      break;
2019+    case 'P':
2020+      printbytes();
2021+      break;
2022+    case 'f':
2023+      dumpstack();
2024+      break;
2025+    case '+':
2026+      arith(addnum);
2027+      break;
2028+    case '-':
2029+      arith(subnum);
2030+      break;
2031+    case '*':
2032+      arith(mulnum);
2033+      break;
2034+    case '/':
2035+      arith(divnum);
2036+      break;
2037+    case '%':
2038+      arith(modnum);
2039+      break;
2040+    case '^':
2041+      arith(expnum);
2042+      break;
2043+    case '~':
2044+      pushdivmod();
2045+      break;
2046+    case 'v':
2047+      num = popnum();
2048+      pushnum(sqrtnum(num));
2049+      freenum(num);
2050+      break;
2051+    case 'c':
2052+      clearstack();
2053+      break;
2054+    case 'd':
2055+      dupstack();
2056+      break;
2057+    case 'r':
2058+      needstack(2);
2059+      v1 = pop();
2060+      v2 = pop();
2061+      push(v1);
2062+      push(v2);
2063+      break;
2064+    case 'S':
2065+      pushreg();
2066+      break;
2067+    case 'L':
2068+      popreg();
2069+      break;
2070+    case 's':
2071+      rp = lookup(regname());
2072+      v1 = pop();
2073+      freeval(rp->val);
2074+      rp->val.u    = v1.u;
2075+      rp->val.type = v1.type;
2076+      break;
2077+    case 'l':
2078+      rp = lookup(regname());
2079+      push(dupval(rp->val));
2080+      break;
2081+    case 'i':
2082+      setibase();
2083+      break;
2084+    case 'o':
2085+      setobase();
2086+      break;
2087+    case 'k':
2088+      setscale();
2089+      break;
2090+    case 'I':
2091+      pushint(ibase);
2092+      break;
2093+    case 'O':
2094+      pushint(obase);
2095+      break;
2096+    case 'K':
2097+      pushint(scale);
2098+      break;
2099+    case '[':
2100+      pushstr(string(NULL, NULL));
2101+      break;
2102+    case 'x':
2103+      execmacro();
2104+      break;
2105+    case '!':
2106+      switch (*input->s++) {
2107+        case '<':
2108+          ch = GE;
2109+          break;
2110+        case '>':
2111+          ch = LE;
2112+          break;
2113+        case '=':
2114+          ch = NE;
2115+          break;
2116+        default:
2117+          system(input->s - 1);
2118+          goto discard;
2119+      }
2120+    case '>':
2121+    case '<':
2122+    case '=':
2123+      relational(ch);
2124+      break;
2125+    case '?':
2126+      /* real dc executes the line as commands rather than pushing it
2127+       * as a string: bc's own read() relies on exactly this, since a
2128+       * bare number is already a complete, valid command that pushes
2129+       * itself */
2130+      s = NULL;
2131+      if (getline(&s, &siz, readsrc()) > 0) {
2132+        addinput(NULL, s);
2133+      } else {
2134+        free(s);
2135+        if (ferror(readsrc()))
2136+          eprintf("reading from file\n");
2137+      }
2138+      break;
2139+    case 'q':
2140+      delinput('q', 2);
2141+      break;
2142+    case 'Q':
2143+      delinput('Q', popint());
2144+      break;
2145+    case 'Z':
2146+      pushlen();
2147+      break;
2148+    case 'X':
2149+      pushfrac();
2150+      break;
2151+    case 'z':
2152+      deepstack();
2153+      break;
2154+    case '#':
2155+    discard:
2156+      while (*input->s)
2157+        ++input->s;
2158+      break;
2159+    case ':':
2160+      aryset();
2161+      break;
2162+    case ';':
2163+      aryget();
2164+      break;
2165+    default:
2166+      if (!strchr(digits, ch))
2167+        error("'%c' (%#o) unimplemented", ch, ch);
2168+    case '_':
2169+      --input->s;
2170+      pushnum(tonum());
2171+      break;
2172+  }
2173+}
2174+
2175+static void
2176+dc(char *fname)
2177+{
2178+  FILE *fp;
2179+
2180+  if (strcmp(fname, "-") == 0) {
2181+    fp = stdin;
2182+  } else {
2183+    if ((fp = fopen(fname, "r")) == NULL)
2184+      eprintf("opening '%s':", fname);
2185+  }
2186+  addinput(fp, NULL);
2187+
2188+  while (moreinput())
2189+    eval();
2190+
2191+  free(input);
2192+  input = NULL;
2193+}
2194+
2195+static void
2196+usage(void)
2197+{
2198+  eprintf("usage: dc [-i] [file ...]\n");
2199+}
2200+
2201+// ?man dc: an arbitrary-precision reverse-polish desk calculator
2202+// ?man arguments: [file ...]
2203+// ?man dc reads and executes commands from each file in turn, then
2204+// ?man from standard input
2205+int
2206+main(int argc, char *argv[])
2207+{
2208+  ARGBEGIN
2209+  {
2210+    // ?man -i: enable extended (multi-character) register names
2211+    case 'i':
2212+      iflag = 1;
2213+      break;
2214+    default:
2215+      usage();
2216+  }
2217+  ARGEND
2218+
2219+  while (*argv)
2220+    dc(*argv++);
2221+  dc("-");
2222+
2223+  return 0;
2224+}
+182, -35
  1@@ -1,4 +1,4 @@
  2-/* See LICENSE file for copyright and license details. */
  3+/* see LICENSE file for copyright and license details */
  4 #include "diskutil.h"
  5 #include "util.h"
  6 
  7@@ -6,6 +6,7 @@
  8 #include <stdio.h>
  9 #include <stdlib.h>
 10 #include <string.h>
 11+#include <strings.h>
 12 #include <unistd.h>
 13 
 14 struct MbrPartition {
 15@@ -121,6 +122,151 @@ crc32(uint32_t crc, const void *buf, size_t len)
 16   return crc;
 17 }
 18 
 19+/* short two-byte codes match gdisk/sgdisk's own convention, since
 20+ * every caller already writing "-t ef00" etc against those tools
 21+ * expects the same codes here */
 22+static const struct {
 23+  const char *code;
 24+  uint8_t     guid[16];
 25+} gpt_type_table[] = {
 26+    /* ef00: efi system partition */
 27+    {"ef00",
 28+     {0x28, 0x73, 0x2a, 0xc1, 0x1f, 0xf8, 0xd2, 0x11, 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9,
 29+      0x3b}                                                                                    },
 30+    /* ef02: bios boot partition */
 31+    {"ef02",
 32+     {0x48, 0x61, 0x68, 0x21, 0x49, 0x64, 0x6f, 0x6e, 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46,
 33+      0x49}                                                                                    },
 34+    /* 8200: linux swap */
 35+    {"8200",
 36+     {0x6d, 0xfd, 0x57, 0x06, 0xab, 0xa4, 0xc4, 0x43, 0x84, 0xe5, 0x09, 0x33, 0xc8, 0x4b, 0x4f,
 37+      0x4f}                                                                                    },
 38+    /* 8300: linux filesystem data */
 39+    {"8300",
 40+     {0xaf, 0x3d, 0xc6, 0x0f, 0x84, 0x83, 0x72, 0x47, 0x8e, 0x79, 0x3d, 0x69, 0xd8, 0x47, 0x7d,
 41+      0xe4}                                                                                    },
 42+};
 43+#define GPT_TYPE_TABLE_LEN (int)(sizeof(gpt_type_table) / sizeof(gpt_type_table[0]))
 44+
 45+/* canonical XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX form: the first three
 46+ * groups store little-endian, the last two store big-endian, the same
 47+ * mixed layout every other GUID field in this file already uses */
 48+static int
 49+parse_guid_string(const char *s, uint8_t out[16])
 50+{
 51+  static const int  group_len[5] = {8, 4, 4, 4, 12};
 52+  static const int  group_le[5]  = {1, 1, 1, 0, 0};
 53+  int               g, i, hi, lo, byte_idx = 0;
 54+  const char       *p = s;
 55+
 56+  for (g = 0; g < 5; g++) {
 57+    uint8_t bytes[6];
 58+    int     nbytes = group_len[g] / 2;
 59+    for (i = 0; i < nbytes; i++) {
 60+      hi = hexval(p[i * 2]);
 61+      lo = hexval(p[i * 2 + 1]);
 62+      if (hi < 0 || lo < 0)
 63+        return -1;
 64+      bytes[i] = (uint8_t)((hi << 4) | lo);
 65+    }
 66+    if (group_le[g]) {
 67+      for (i = nbytes - 1; i >= 0; i--)
 68+        out[byte_idx++] = bytes[i];
 69+    } else {
 70+      for (i = 0; i < nbytes; i++)
 71+        out[byte_idx++] = bytes[i];
 72+    }
 73+    p += group_len[g];
 74+    if (g < 4) {
 75+      if (*p != '-')
 76+        return -1;
 77+      p++;
 78+    }
 79+  }
 80+  return *p == '\0' ? 0 : -1;
 81+}
 82+
 83+/* opt_type is a short gdisk-style code (see gpt_type_table above), a
 84+ * full canonical GUID string, or unset: unset (or unrecognized, with
 85+ * a warning) keeps the long-standing default of "linux filesystem
 86+ * data", matching what every caller got before -t existed */
 87+static void
 88+gpt_type_guid(const char *type, uint8_t out[16])
 89+{
 90+  int i;
 91+
 92+  if (type) {
 93+    for (i = 0; i < GPT_TYPE_TABLE_LEN; i++) {
 94+      if (strcasecmp(type, gpt_type_table[i].code) == 0) {
 95+        memcpy(out, gpt_type_table[i].guid, 16);
 96+        return;
 97+      }
 98+    }
 99+    if (parse_guid_string(type, out) == 0)
100+      return;
101+    weprintf("unrecognized GPT type '%s', using linux filesystem data\n", type);
102+  }
103+  memcpy(out, gpt_type_table[GPT_TYPE_TABLE_LEN - 1].guid, 16);
104+}
105+
106+/* resolves -b for a GPT add: a plain sector number, or 0/unset for
107+ * the first free sector right after every existing partition's own
108+ * end_lba (gpt_hdr.first_usable if the table is still empty), the
109+ * same "0 means auto-place" convention gdisk-family tools already use */
110+static uint64_t
111+gpt_resolve_start(struct GptHeader *hdr, struct GptPartition *parts, const char *s)
112+{
113+  uint32_t i;
114+  uint64_t next = hdr->first_usable;
115+
116+  if (s && strcmp(s, "0") != 0)
117+    return (uint64_t)estrtoul(s, 10);
118+
119+  for (i = 0; i < hdr->num_parts; i++) {
120+    if (parts[i].start_lba == 0 && parts[i].end_lba == 0)
121+      continue;
122+    if (parts[i].end_lba + 1 > next)
123+      next = parts[i].end_lba + 1;
124+  }
125+  return next;
126+}
127+
128+/* resolves -e for a GPT add: a plain sector number, 0/unset for the
129+ * disk's own last usable sector, or +SIZE for a size relative to the
130+ * already-resolved start */
131+static uint64_t
132+gpt_resolve_end(struct GptHeader *hdr, size_t sec_size, uint64_t start, const char *s)
133+{
134+  off_t    size_bytes;
135+  uint64_t sectors;
136+
137+  if (!s || strcmp(s, "0") == 0)
138+    return hdr->last_usable;
139+  if (s[0] == '+') {
140+    size_bytes = parseoffset(s + 1);
141+    if (size_bytes < 0)
142+      eprintf("fdisk: malformed size '%s'\n", s);
143+    sectors = ((uint64_t)size_bytes + sec_size - 1) / sec_size;
144+    return start + sectors - 1;
145+  }
146+  return (uint64_t)estrtoul(s, 10);
147+}
148+
149+/* GPT partition names are UTF-16LE, 36 code units, null-padded: every
150+ * caller so far only ever needs a plain ASCII label, so this widens
151+ * each byte rather than pulling in a real UTF-8 decoder for it */
152+static void
153+gpt_set_name(uint16_t name[36], const char *s)
154+{
155+  size_t i;
156+
157+  memset(name, 0, 36 * sizeof(uint16_t));
158+  if (!s)
159+    return;
160+  for (i = 0; i < 35 && s[i]; i++)
161+    name[i] = (uint16_t)(unsigned char)s[i];
162+}
163+
164 static int         opt_list           = 0;
165 static int         opt_print          = 0;
166 static int         opt_init_gpt       = 0;
167@@ -130,16 +276,17 @@ static int         opt_add            = 0;
168 static int         opt_del            = 0;
169 static int         opt_part_idx       = -1;
170 static int         opt_part_is_letter = 0;
171-static uint64_t    opt_start          = 0;
172-static uint64_t    opt_end            = 0;
173+static const char *opt_start_str      = NULL;
174+static const char *opt_end_str        = NULL;
175 static const char *opt_type           = NULL;
176+static const char *opt_name           = NULL;
177 
178 static void
179 usage(void)
180 {
181   eprintf(
182       "usage: %s [-l] [-p] [-g] [-m] [-s] [-a] [-d] [-n index] [-b "
183-      "start] [-e end] [-t type] [device]\n",
184+      "start] [-e end] [-t type] [-c name] [device]\n",
185       argv0
186   );
187 }
188@@ -445,6 +592,8 @@ do_fdisk(const char *path)
189   int                  idx;
190   int                  has_gpt = 0;
191   int                  has_bsd = 0;
192+  uint64_t             bsd_start, bsd_end;
193+  uint64_t             mbr_start, mbr_end;
194 
195   if (blockdev_open(&dev, path, 1) < 0) {
196     weprintf("cannot open %s:", path);
197@@ -542,25 +691,11 @@ do_fdisk(const char *path)
198         blockdev_close(&dev);
199         return -1;
200       }
201-      gp                = &gpt_parts[opt_part_idx - 1];
202-      gp->start_lba     = opt_start;
203-      gp->end_lba       = opt_end;
204-      gp->type_guid[0]  = 0xAF;
205-      gp->type_guid[1]  = 0x3D;
206-      gp->type_guid[2]  = 0xC6;
207-      gp->type_guid[3]  = 0x0F;
208-      gp->type_guid[4]  = 0x83;
209-      gp->type_guid[5]  = 0x84;
210-      gp->type_guid[6]  = 0x72;
211-      gp->type_guid[7]  = 0x47;
212-      gp->type_guid[8]  = 0x8E;
213-      gp->type_guid[9]  = 0x79;
214-      gp->type_guid[10] = 0x3D;
215-      gp->type_guid[11] = 0x69;
216-      gp->type_guid[12] = 0xD8;
217-      gp->type_guid[13] = 0x47;
218-      gp->type_guid[14] = 0x7D;
219-      gp->type_guid[15] = 0xE4;
220+      gp            = &gpt_parts[opt_part_idx - 1];
221+      gp->start_lba = gpt_resolve_start(&gpt_hdr, gpt_parts, opt_start_str);
222+      gp->end_lba   = gpt_resolve_end(&gpt_hdr, dev.sec_size, gp->start_lba, opt_end_str);
223+      gpt_type_guid(opt_type, gp->type_guid);
224+      gpt_set_name(gp->name, opt_name);
225 
226       if (gpt_write(&dev, &gpt_hdr, gpt_parts) < 0) {
227         weprintf("cannot update GPT on %s:", path);
228@@ -590,9 +725,11 @@ do_fdisk(const char *path)
229           return -1;
230         }
231         bp           = &bsd_lp.d_partitions[idx];
232-        bp->offset   = (uint32_t)opt_start;
233-        bp->offset_h = (uint16_t)(opt_start >> 32);
234-        size         = opt_end - opt_start + 1;
235+        bsd_start    = opt_start_str ? (uint64_t)estrtoul(opt_start_str, 10) : 0;
236+        bsd_end      = opt_end_str ? (uint64_t)estrtoul(opt_end_str, 10) : 0;
237+        bp->offset   = (uint32_t)bsd_start;
238+        bp->offset_h = (uint16_t)(bsd_start >> 32);
239+        size         = bsd_end - bsd_start + 1;
240         bp->size     = (uint32_t)size;
241         bp->size_h   = (uint16_t)(size >> 32);
242         bp->fstype   = opt_type ? (uint8_t)strtoul(opt_type, NULL, 0) : 7;
243@@ -624,8 +761,10 @@ do_fdisk(const char *path)
244           return -1;
245         }
246         mp            = &mbr.parts[opt_part_idx - 1];
247-        mp->start_lba = (uint32_t)opt_start;
248-        mp->size      = (uint32_t)(opt_end - opt_start + 1);
249+        mbr_start     = opt_start_str ? (uint64_t)estrtoul(opt_start_str, 10) : 0;
250+        mbr_end       = opt_end_str ? (uint64_t)estrtoul(opt_end_str, 10) : 0;
251+        mp->start_lba = (uint32_t)mbr_start;
252+        mp->size      = (uint32_t)(mbr_end - mbr_start + 1);
253         mp->type      = opt_type ? (uint8_t)strtoul(opt_type, NULL, 0) : 0x83;
254         mbr.sig[0]    = 0x55;
255         mbr.sig[1]    = 0xAA;
256@@ -724,8 +863,8 @@ do_fdisk(const char *path)
257 
258 // ?man fdisk: partition table manipulator
259 // ?man arguments: [-l] [-p] [-g] [-m] [-s] [-a] [-d] [-n index] [-b start] [-e
260-// end] [-t type] [device] ?man fdisk performs partition table operations for
261-// MBR, GPT and BSD disklabels
262+// end] [-t type] [-c name] [device] ?man fdisk performs partition table
263+// operations for MBR, GPT and BSD disklabels
264 int
265 main(int argc, char *argv[])
266 {
267@@ -773,18 +912,26 @@ main(int argc, char *argv[])
268       }
269       break;
270     }
271-    // ?man -b:starting sector LBA
272+    // ?man -b:starting sector LBA, or 0 for right after the last
273+    // ?man partition already on the disk
274     case 'b':
275-      opt_start = (uint64_t)estrtoul(EARGF(usage()), 10);
276+      opt_start_str = EARGF(usage());
277       break;
278-    // ?man -e:ending sector LBA
279+    // ?man -e:ending sector LBA, 0 for the disk's last usable
280+    // ?man sector, or +SIZE (K/M/G/T, e.g. +512M) for a size
281+    // ?man relative to the start
282     case 'e':
283-      opt_end = (uint64_t)estrtoul(EARGF(usage()), 10);
284+      opt_end_str = EARGF(usage());
285       break;
286-    // ?man -t:partition type (MBR/BSD hex or GPT string)
287+    // ?man -t:partition type: MBR/BSD hex, or for GPT a gdisk-style
288+    // ?man code (ef00, ef02, 8200, 8300) or a full GUID string
289     case 't':
290       opt_type = EARGF(usage());
291       break;
292+    // ?man -c:GPT partition name, ignored for MBR/BSD
293+    case 'c':
294+      opt_name = EARGF(usage());
295+      break;
296     default:
297       usage();
298   }
+269, -0
  1@@ -0,0 +1,269 @@
  2+/* see LICENSE file for copyright and license details */
  3+#include <sys/stat.h>
  4+#include <sys/types.h>
  5+
  6+#include <errno.h>
  7+#include <fcntl.h>
  8+#include <grp.h>
  9+#include <libgen.h>
 10+#include <limits.h>
 11+#include <pwd.h>
 12+#include <stdio.h>
 13+#include <stdlib.h>
 14+#include <string.h>
 15+#include <unistd.h>
 16+
 17+#include "fs.h"
 18+#include "util.h"
 19+#include "wexec.h"
 20+
 21+static int    dflag, Dflag, pflag, sflag;
 22+static mode_t mode = 0755;
 23+static uid_t  uid  = (uid_t)-1;
 24+static gid_t  gid  = (gid_t)-1;
 25+static int    status;
 26+
 27+static void
 28+usage(void)
 29+{
 30+  eprintf(
 31+      "usage: %s [-Dps] [-o owner] [-g group] [-m mode] [-t dir] source ... dest\n"
 32+      "       %s -d [-Dp] [-o owner] [-g group] [-m mode] dir ...\n",
 33+      argv0,
 34+      argv0
 35+  );
 36+}
 37+
 38+static void
 39+lookup_owner(const char *owner, const char *group)
 40+{
 41+  struct passwd *pw;
 42+  struct group  *gr;
 43+
 44+  if (owner) {
 45+    errno = 0;
 46+    pw    = getpwnam(owner);
 47+    if (pw) {
 48+      uid = pw->pw_uid;
 49+    } else {
 50+      if (errno)
 51+        eprintf("getpwnam %s:", owner);
 52+      uid = (uid_t)estrtonum(owner, 0, UINT_MAX);
 53+    }
 54+  }
 55+  if (group) {
 56+    errno = 0;
 57+    gr    = getgrnam(group);
 58+    if (gr) {
 59+      gid = gr->gr_gid;
 60+    } else {
 61+      if (errno)
 62+        eprintf("getgrnam %s:", group);
 63+      gid = (gid_t)estrtonum(group, 0, UINT_MAX);
 64+    }
 65+  }
 66+}
 67+
 68+static void
 69+chown_if_requested(const char *path)
 70+{
 71+  if (uid == (uid_t)-1 && gid == (gid_t)-1)
 72+    return;
 73+  if (chown(path, uid, gid) < 0) {
 74+    weprintf("chown %s:", path);
 75+    status = 1;
 76+  }
 77+}
 78+
 79+static void
 80+preserve_time(const char *src, const char *dst)
 81+{
 82+  struct stat     st;
 83+  struct timespec times[2];
 84+
 85+  if (stat(src, &st) < 0) {
 86+    weprintf("stat %s:", src);
 87+    status = 1;
 88+    return;
 89+  }
 90+  times[0] = st.st_atim;
 91+  times[1] = st.st_mtim;
 92+  if (utimensat(AT_FDCWD, dst, times, 0) < 0) {
 93+    weprintf("utimensat %s:", dst);
 94+    status = 1;
 95+  }
 96+}
 97+
 98+static void
 99+strip_binary(const char *path)
100+{
101+  char *args[] = {"strip", "-p", (char *)path, NULL};
102+
103+  if (wexecvp("strip", args) != 0) {
104+    weprintf("strip %s:", path);
105+    status = 1;
106+  }
107+}
108+
109+// leading path components of dst, not dst itself
110+static void
111+make_leading_dirs(const char *dst)
112+{
113+  char  buf[PATH_MAX];
114+  char *dir;
115+
116+  estrlcpy(buf, dst, sizeof(buf));
117+  dir = dirname(buf);
118+  if (mkdirp(dir, 0755, 0755) < 0 && errno != EEXIST) {
119+    weprintf("mkdir %s:", dir);
120+    status = 1;
121+  }
122+}
123+
124+static void
125+install_dirs(char **argv)
126+{
127+  for (; *argv; argv++) {
128+    if (mkdirp(*argv, mode, 0755) < 0 && errno != EEXIST) {
129+      weprintf("mkdir %s:", *argv);
130+      status = 1;
131+      continue;
132+    }
133+    if (chmod(*argv, mode) < 0) {
134+      weprintf("chmod %s:", *argv);
135+      status = 1;
136+    }
137+    chown_if_requested(*argv);
138+  }
139+}
140+
141+static void
142+install_one(const char *src, const char *dst)
143+{
144+  if (Dflag)
145+    make_leading_dirs(dst);
146+
147+  cp_fflag  = 1;
148+  cp_pflag  = 0;
149+  cp_rflag  = 0;
150+  cp_follow = 'L';
151+  cp(src, dst, 0);
152+  if (cp_status) {
153+    status = 1;
154+    return;
155+  }
156+
157+  if (sflag)
158+    strip_binary(dst);
159+
160+  if (chmod(dst, mode) < 0) {
161+    weprintf("chmod %s:", dst);
162+    status = 1;
163+  }
164+  chown_if_requested(dst);
165+  if (pflag)
166+    preserve_time(src, dst);
167+}
168+
169+// ?man install: copy files and set attributes
170+// ?man arguments: source ... dest
171+// ?man install copies each source to dest, or into dest when dest is a
172+// ?man directory or -t is given, then applies mode/owner/group; with
173+// ?man -d, every argument is a directory to create instead
174+int
175+main(int argc, char *argv[])
176+{
177+  const char *owner = NULL, *group = NULL, *modestr = NULL, *targetdir = NULL;
178+  const char *dest;
179+  struct stat st;
180+  int         isdir;
181+  int         i;
182+
183+  ARGBEGIN
184+  {
185+    // ?man -c: ignored; accepted for compatibility with older install callers
186+    case 'c':
187+      break;
188+    // ?man -d: create directories instead of installing files
189+    case 'd':
190+      dflag = 1;
191+      break;
192+    // ?man -D: create dest's leading directories before installing
193+    case 'D':
194+      Dflag = 1;
195+      break;
196+    // ?man -p: preserve source modification and access times
197+    case 'p':
198+      pflag = 1;
199+      break;
200+    // ?man -s: strip the installed file's symbol table
201+    case 's':
202+      sflag = 1;
203+      break;
204+    // ?man -o:owner set the installed file's owner (name or uid)
205+    case 'o':
206+      owner = EARGF(usage());
207+      break;
208+    // ?man -g:group set the installed file's group (name or gid)
209+    case 'g':
210+      group = EARGF(usage());
211+      break;
212+    // ?man -m:mode set the installed file's permissions
213+    case 'm':
214+      modestr = EARGF(usage());
215+      break;
216+    // ?man -t:dir install every source into dir
217+    case 't':
218+      targetdir = EARGF(usage());
219+      break;
220+    default:
221+      usage();
222+  }
223+  ARGEND;
224+
225+  if (argc < 1 || (dflag && (targetdir || sflag)))
226+    usage();
227+  if (modestr)
228+    mode = parsemode(modestr, 0, 0);
229+  lookup_owner(owner, group);
230+
231+  if (dflag) {
232+    install_dirs(argv);
233+    goto shut;
234+  }
235+
236+  if (targetdir) {
237+    isdir = 1;
238+    dest  = targetdir;
239+    if (Dflag && mkdirp(targetdir, 0755, 0755) < 0 && errno != EEXIST) {
240+      weprintf("mkdir %s:", targetdir);
241+      status = 1;
242+    }
243+  } else {
244+    if (argc < 2)
245+      usage();
246+    dest  = argv[--argc];
247+    isdir = stat(dest, &st) == 0 && S_ISDIR(st.st_mode);
248+    if (!isdir && argc > 1)
249+      eprintf("%s: not a directory\n", dest);
250+  }
251+
252+  for (i = 0; i < argc; i++) {
253+    if (isdir) {
254+      char        buf[PATH_MAX], nb[PATH_MAX];
255+      const char *base;
256+
257+      estrlcpy(nb, argv[i], sizeof(nb));
258+      base = basename(nb);
259+      estrlcpy(buf, dest, sizeof(buf));
260+      estrlcat(buf, "/", sizeof(buf));
261+      estrlcat(buf, base, sizeof(buf));
262+      install_one(argv[i], buf);
263+    } else {
264+      install_one(argv[i], dest);
265+    }
266+  }
267+
268+shut:
269+  return fshut(stdout, "<stdout>") || status;
270+}
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include "diskutil.h"
5 #include "util.h"
6 
+247, -0
  1@@ -0,0 +1,247 @@
  2+/* see LICENSE file for copyright and license details */
  3+#include <sys/types.h>
  4+
  5+#include <errno.h>
  6+#include <libgen.h>
  7+#include <limits.h>
  8+#include <pwd.h>
  9+#include <regex.h>
 10+#include <stdio.h>
 11+#include <stdlib.h>
 12+#include <string.h>
 13+#include <unistd.h>
 14+
 15+#include "paths.h"
 16+#include "proc.h"
 17+#include "util.h"
 18+
 19+enum {
 20+  PGREP_fflag = 1 << 0, /* match against full cmdline, not just comm */
 21+  PGREP_lflag = 1 << 1, /* list pid and comm */
 22+  PGREP_aflag = 1 << 2, /* list pid and full cmdline */
 23+  PGREP_xflag = 1 << 3, /* require an exact match */
 24+  PGREP_vflag = 1 << 4, /* invert: print non-matching pids */
 25+  PGREP_cflag = 1 << 5, /* print a match count, not the pids */
 26+};
 27+
 28+struct hit {
 29+  pid_t              pid;
 30+  unsigned long long starttime;
 31+};
 32+
 33+static int         flags;
 34+static regex_t     preg;
 35+static uid_t       user_uid;
 36+static int         have_user;
 37+static pid_t       self;
 38+static struct hit  *hits;
 39+static size_t       nhits, hitscap;
 40+static int          count;
 41+
 42+// newest/oldest are mutually exclusive with each other and with
 43+// printing every match as it is found, so they buffer every match
 44+// instead of streaming it: 0 means "print as found"
 45+enum { PGREP_NONE = 0, PGREP_NEWEST, PGREP_OLDEST };
 46+static int select_mode;
 47+
 48+static int
 49+matches(const char *target)
 50+{
 51+  regmatch_t m;
 52+  int        r;
 53+
 54+  r = regexec(&preg, target, 1, &m, 0);
 55+  if (r != 0)
 56+    return 0;
 57+  if (flags & PGREP_xflag)
 58+    return m.rm_so == 0 && (size_t)m.rm_eo == strlen(target);
 59+  return 1;
 60+}
 61+
 62+static void
 63+record(pid_t pid, unsigned long long starttime)
 64+{
 65+  if (nhits == hitscap) {
 66+    hitscap = hitscap ? hitscap * 2 : 64;
 67+    hits    = ereallocarray(hits, hitscap, sizeof(*hits));
 68+  }
 69+  hits[nhits].pid       = pid;
 70+  hits[nhits].starttime = starttime;
 71+  nhits++;
 72+}
 73+
 74+static void
 75+show(pid_t pid, const char *comm)
 76+{
 77+  char cmdline[BUFSIZ];
 78+
 79+  count++;
 80+  if (flags & PGREP_cflag)
 81+    return;
 82+  if (flags & PGREP_aflag) {
 83+    if (parsecmdline(pid, cmdline, sizeof(cmdline)) < 0)
 84+      printf("%d %s\n", pid, comm);
 85+    else
 86+      printf("%d %s\n", pid, cmdline);
 87+  } else if (flags & PGREP_lflag) {
 88+    printf("%d %s\n", pid, comm);
 89+  } else {
 90+    printf("%d\n", pid);
 91+  }
 92+}
 93+
 94+static void
 95+pgrepr(const char *file)
 96+{
 97+  char              path[PATH_MAX], *p;
 98+  struct procstat   ps;
 99+  struct procstatus pstatus;
100+  char              cmdline[BUFSIZ];
101+  const char       *target;
102+  pid_t             pid;
103+  int               matched;
104+
105+  if (strlcpy(path, file, sizeof(path)) >= sizeof(path))
106+    eprintf("path too long\n");
107+  p = basename(path);
108+  if (pidfile(p) == 0)
109+    return;
110+  pid = estrtol(p, 10);
111+  if (pid == self)
112+    return;
113+  if (parsestat(pid, &ps) < 0)
114+    return;
115+
116+  if (have_user) {
117+    if (parsestatus(pid, &pstatus) < 0)
118+      return;
119+    if (pstatus.euid != user_uid)
120+      return;
121+  }
122+
123+  if (flags & PGREP_fflag) {
124+    if (parsecmdline(pid, cmdline, sizeof(cmdline)) < 0)
125+      target = ps.comm;
126+    else
127+      target = cmdline;
128+  } else {
129+    target = ps.comm;
130+  }
131+
132+  matched = matches(target);
133+  if (flags & PGREP_vflag)
134+    matched = !matched;
135+  if (!matched)
136+    return;
137+
138+  if (select_mode != PGREP_NONE)
139+    record(pid, ps.starttime);
140+  else
141+    show(pid, ps.comm);
142+}
143+
144+static void
145+usage(void)
146+{
147+  eprintf("usage: %s [-flaxvc] [-u user] [-n | -o] pattern\n", argv0);
148+}
149+
150+// ?man pgrep: list processes by name
151+// ?man arguments: pattern
152+// ?man pgrep matches pattern, a POSIX extended regular expression,
153+// ?man against each running process's name (or full command line
154+// ?man with -f) and prints the pid of every match, one per line
155+int
156+main(int argc, char *argv[])
157+{
158+  char            namebuf[PATH_MAX];
159+  struct procstat ps;
160+  struct passwd  *pw;
161+  const char     *user = NULL;
162+  size_t          i, pick;
163+
164+  ARGBEGIN
165+  {
166+    // ?man -f: match the full command line instead of just the name
167+    case 'f':
168+      flags |= PGREP_fflag;
169+      break;
170+    // ?man -l: list the matched name alongside each pid
171+    case 'l':
172+      flags |= PGREP_lflag;
173+      break;
174+    // ?man -a: list the full command line alongside each pid
175+    case 'a':
176+      flags |= PGREP_aflag;
177+      break;
178+    // ?man -x: require pattern to match the whole name or cmdline
179+    case 'x':
180+      flags |= PGREP_xflag;
181+      break;
182+    // ?man -v: invert the match, printing non-matching pids
183+    case 'v':
184+      flags |= PGREP_vflag;
185+      break;
186+    // ?man -c: print a count of matches instead of their pids
187+    case 'c':
188+      flags |= PGREP_cflag;
189+      break;
190+    // ?man -u:user only match processes owned by user (name or uid)
191+    case 'u':
192+      user = EARGF(usage());
193+      break;
194+    // ?man -n{sel}: select only the most recently started match
195+    case 'n':
196+      select_mode = PGREP_NEWEST;
197+      break;
198+    // ?man -o{sel}: select only the oldest match
199+    case 'o':
200+      select_mode = PGREP_OLDEST;
201+      break;
202+    default:
203+      usage();
204+  }
205+  ARGEND;
206+
207+  if (argc != 1)
208+    usage();
209+
210+  if (user) {
211+    errno = 0;
212+    pw    = getpwnam(user);
213+    if (pw) {
214+      user_uid = pw->pw_uid;
215+    } else {
216+      if (errno)
217+        eprintf("getpwnam %s:", user);
218+      user_uid = (uid_t)estrtonum(user, 0, UINT_MAX);
219+    }
220+    have_user = 1;
221+  }
222+
223+  eregcomp(&preg, argv[0], REG_EXTENDED);
224+
225+  self = getpid();
226+  recurse_dir(ARUU_LINUX_PATH_PROC, pgrepr);
227+
228+  if (select_mode != PGREP_NONE && nhits > 0) {
229+    pick = 0;
230+    for (i = 1; i < nhits; i++) {
231+      if (select_mode == PGREP_NEWEST ? hits[i].starttime > hits[pick].starttime
232+                                       : hits[i].starttime < hits[pick].starttime)
233+        pick = i;
234+    }
235+    if (parsestat(hits[pick].pid, &ps) == 0)
236+      strlcpy(namebuf, ps.comm, sizeof(namebuf));
237+    else
238+      namebuf[0] = '\0';
239+    show(hits[pick].pid, namebuf);
240+  }
241+
242+  if (flags & PGREP_cflag)
243+    printf("%d\n", count);
244+
245+  if (fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>"))
246+    return 2;
247+  return count > 0 ? 0 : 1;
248+}
+3, -3
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 #include <unistd.h>
 5 
 6 #include "arg.h"
 7@@ -6,8 +6,8 @@
 8 
 9 // ?man sync: flush disk cache
10 // ?man synopsis:
11-// ?man The sync utility invokes sync(2) to flush all unwritten changes to disk.
12-// This is usually done before shutting down, rebooting or halting. ?man ## SEE
13+// ?man The sync utility invokes sync(2) to flush all unwritten changes to disk
14+// this is usually done before shutting down, rebooting or halting. ?man ## SEE
15 // ALSO ?man fsync(2), sync(2)
16 
17 static void
+108, -108
  1@@ -1,4 +1,4 @@
  2-/* Copyright (c) 1985 Ceriel J.H. Jacobs */
  3+/* copyright (c) 1985 ceriel J.H. jacobs */
  4 
  5 #include "commands.h"
  6 #include "assert.h"
  7@@ -17,9 +17,9 @@
  8 #include "prompt.h"
  9 #include "term.h"
 10 
 11-static long lastcount; /* Save last count for '.' command */
 12-static int  lastcomm;  /* Save last command for '.' command */
 13-static int  searchdir; /* Direction of last search */
 14+static long lastcount; /* save last count for '.' command */
 15+static int  lastcomm;  /* save last command for '.' command */
 16+static int  searchdir; /* direction of last search */
 17 
 18 static int  do_nocomm(long cnt);
 19 static void do_search(char *str, long cnt, int dir);
 20@@ -59,14 +59,14 @@ static int  do_quit(long cnt);
 21 
 22 static int
 23 do_nocomm(long cnt)
 24-{ /* Do nothing */
 25+{ /* do nothing */
 26   (void)cnt;
 27   return 0;
 28 }
 29 
 30 int
 31 do_chkm(long cnt)
 32-{ /* Change key map */
 33+{ /* change key map */
 34   struct keymap *p;
 35   (void)cnt;
 36 
 37@@ -80,7 +80,7 @@ do_chkm(long cnt)
 38 }
 39 
 40 /*
 41- * Perform searches
 42+ * perform searches
 43  */
 44 
 45 static void
 46@@ -91,19 +91,19 @@ do_search(char *str, long cnt, int dir)
 47 
 48   if (str) {
 49     /*
 50-     * We have to get a pattern, which we have to prompt for
 51-     * with the string "str".
 52-     */
 53+ * we have to get a pattern, which we have to prompt for
 54+ * with the string "str"
 55+ */
 56     if ((p = readline(str)) == 0) {
 57       /*
 58-       * User cancelled command
 59-       */
 60+ * user cancelled command
 61+ */
 62       return;
 63     }
 64     if ((p = re_comp(p))) {
 65       /*
 66-       * There was an error in the pattern
 67-       */
 68+ * there was an error in the pattern
 69+ */
 70       error(p);
 71       return;
 72     }
 73@@ -119,17 +119,17 @@ do_search(char *str, long cnt, int dir)
 74       p = getline(lineno, 0);
 75     if (interrupt)
 76       return;
 77-    if (!p) { /* End of file reached */
 78+    if (!p) { /* end of file reached */
 79       error("pattern not found");
 80       return;
 81     }
 82     if (re_exec(p) && --cnt <= 0) {
 83       /*
 84-       * We found the pattern, and we found it often enough.
 85-       * Pity that we still don't know where the match is.
 86-       * We only know the linenumber. So, we just hope the
 87-       * following will at least bring it on the screen ...
 88-       */
 89+ * we found the pattern, and we found it often enough
 90+ * pity that we still dont know where the match is
 91+ * we only know the linenumber. so, we just hope the
 92+ * following will at least bring it on the screen ...
 93+ */
 94       (void)display(lineno, 0, pagesize, 0);
 95       (void)scrollb(2, 0);
 96       redraw(0);
 97@@ -141,20 +141,20 @@ do_search(char *str, long cnt, int dir)
 98 
 99 static int
100 do_fsearch(long cnt)
101-{ /* Forward search */
102+{ /* forward search */
103   do_search("/", cnt, 1);
104   return 0;
105 }
106 
107 static int
108 do_bsearch(long cnt)
109-{ /* Backward search */
110+{ /* backward search */
111   do_search("?", cnt, -1);
112   return 0;
113 }
114 
115 /*
116- * Repeat last search in direction "dir"
117+ * repeat last search in direction "dir"
118  */
119 
120 static int
121@@ -180,14 +180,14 @@ n_or_rn_search(long cnt, int dir)
122 
123 static int
124 do_nsearch(long cnt)
125-{ /* Repeat search in same direction */
126+{ /* repeat search in same direction */
127   n_or_rn_search(cnt, searchdir);
128   return 0;
129 }
130 
131 static int
132 do_rnsearch(long cnt)
133-{ /* Repeat search in opposite direction */
134+{ /* repeat search in opposite direction */
135   n_or_rn_search(cnt, -searchdir);
136   return 0;
137 }
138@@ -209,10 +209,10 @@ shell_command(int esc_ch, long cnt)
139       putline(TI);
140       if (!p) {
141         /*
142-         * Avoid double redraw.
143-         * After a "startcomm", a redraw will
144-         * take place anyway.
145-         */
146+ * avoid double redraw
147+ * after a "startcomm", a redraw will
148+ * take place anyway
149+ */
150         redraw(1);
151       }
152     }
153@@ -222,27 +222,27 @@ shell_command(int esc_ch, long cnt)
154 
155 static int
156 do_shell(long cnt)
157-{ /* Execute a shell escape */
158+{ /* execute a shell escape */
159   return shell_command('!', cnt);
160 }
161 
162 static int
163 do_pipe(long cnt)
164-{ /* Execute a shell escape */
165+{ /* execute a shell escape */
166   return shell_command('|', cnt);
167 }
168 
169 static int
170 do_writefile(long cnt)
171-{ /* Write input to a file */
172+{ /* write input to a file */
173   char *p;
174   int   fd;
175   (void)cnt;
176 
177   if ((p = readline("Filename: ")) == 0 || !*p) {
178     /*
179-     * No file name given
180-     */
181+ * no file name given
182+ */
183     return 0;
184   }
185   if ((fd = open(p, O_CREAT | O_EXCL | O_WRONLY, 0644)) < 0) {
186@@ -283,14 +283,14 @@ wrt_fd(int fd)
187 
188 static int
189 do_absolute(long cnt)
190-{ /* Go to linenumber "cnt" */
191+{ /* go to linenumber "cnt" */
192 
193-  if (!getline(cnt, 0)) { /* Not there or interrupt */
194+  if (!getline(cnt, 0)) { /* not there or interrupt */
195     if (!interrupt) {
196       /*
197-       * User did'nt give an interrupt, so the line number
198-       * was too high. Go to the last line.
199-       */
200+ * user did'nt give an interrupt, so the line number
201+ * was too high. go to the last line
202+ */
203       do_lline(cnt);
204     }
205     return 0;
206@@ -301,9 +301,9 @@ do_absolute(long cnt)
207 
208 static int
209 do_visit(long cnt)
210-{ /* Visit a file */
211+{ /* visit a file */
212   char       *p;
213-  static char fn[128]; /* Keep file name */
214+  static char fn[128]; /* keep file name */
215   (void)cnt;
216 
217   if ((p = readline("Filename: ")) == 0) {
218@@ -314,8 +314,8 @@ do_visit(long cnt)
219     visitfile(fn);
220   } else {
221     /*
222-     * User typed a return. Visit the current file
223-     */
224+ * user typed a return. visit the current file
225+ */
226     if (!(p = filenames[filecount])) {
227       error("No current file");
228       return 0;
229@@ -328,15 +328,15 @@ do_visit(long cnt)
230 
231 static int
232 do_error(long cnt)
233-{ /* Called when user types wrong key sequence */
234+{ /* called when user types wrong key sequence */
235   (void)cnt;
236   error(currmap->k_help);
237   return 0;
238 }
239 
240 /*
241- * Interface routine for displaying previous screen,
242- * depending on cflag.
243+ * interface routine for displaying previous screen,
244+ * depending on cflag
245  */
246 
247 static int
248@@ -347,17 +347,17 @@ prev_screen(int sz, int really)
249   retval = scrollb(sz - 1, really && cflag);
250   if (really && !cflag) {
251     /*
252-     * The previous call did not display anything, but at least we
253-     * know where to start
254-     */
255+ * the previous call did not display anything, but at least we
256+ * know where to start
257+ */
258     return display(scr_info.firstline, scr_info.nf, sz, 1);
259   }
260   return retval;
261 }
262 
263 /*
264- * Interface routine for displaying the next screen,
265- * dependent on cflag.
266+ * interface routine for displaying the next screen,
267+ * dependent on cflag
268  */
269 
270 static int
271@@ -399,15 +399,15 @@ page_size(unsigned cnt)
272 
273 static int
274 do_forward(long cnt)
275-{ /* Display next page */
276+{ /* display next page */
277   int i;
278 
279   i = page_size((unsigned)cnt);
280   if (status & EOFILE) {
281     /*
282-     * May seem strange, but actually a visit to the next file
283-     * has already been done here
284-     */
285+ * may seem strange, but actually a visit to the next file
286+ * has already been done here
287+ */
288     (void)display(1L, 0, i, 1);
289     return 0;
290   }
291@@ -430,11 +430,11 @@ do_backward(long cnt)
292     return 0;
293   }
294   /*
295-   * The next part is a bit clumsy.
296-   * We want to display the last page of the previous file (for which
297-   * a visit has already been done), but the pagesize may temporarily
298-   * be different because the command had a count
299-   */
300+ * the next part is a bit clumsy
301+ * we want to display the last page of the previous file (for which
302+ * a visit has already been done), but the pagesize may temporarily
303+ * be different because the command had a count
304+ */
305   temp     = pagesize;
306   pagesize = i;
307   do_lline(cnt);
308@@ -444,7 +444,7 @@ do_backward(long cnt)
309 
310 static int
311 do_firstline(long cnt)
312-{ /* Go to start of input */
313+{ /* go to start of input */
314   (void)cnt;
315   do_absolute(1L);
316   return 0;
317@@ -452,24 +452,24 @@ do_firstline(long cnt)
318 
319 static int
320 do_lline(long cnt)
321-{ /* Go to end of input */
322+{ /* go to end of input */
323   int i = 0;
324   int j = pagesize - 1;
325 
326   if ((cnt = to_lastline()) < 0) {
327     /*
328-     * Interrupted by the user
329-     */
330+ * interrupted by the user
331+ */
332     return 0;
333   }
334   /*
335-   * Display the page such that only the last line of the page is
336-   * a "~", independant of the pagesize
337-   */
338+ * display the page such that only the last line of the page is
339+ * a "~", independant of the pagesize
340+ */
341   while (!(display(cnt, i, j, 0) & EOFILE)) {
342     /*
343-     * The last line could of course be very long ...
344-     */
345+ * the last line could of course be very long ...
346+ */
347     i += j;
348   }
349   (void)scrollb(j - scr_info.tail->cnt, 0);
350@@ -479,9 +479,9 @@ do_lline(long cnt)
351 
352 static int
353 do_lf(long cnt)
354-{ /* Display next line, or go to line */
355+{ /* display next line, or go to line */
356 
357-  if (cnt) { /* Go to line */
358+  if (cnt) { /* go to line */
359     do_absolute(cnt);
360     return 0;
361   }
362@@ -491,9 +491,9 @@ do_lf(long cnt)
363 
364 static int
365 do_upline(long cnt)
366-{ /* Display previous line, or go to line */
367+{ /* display previous line, or go to line */
368 
369-  if (cnt) { /* Go to line */
370+  if (cnt) { /* go to line */
371     do_absolute(cnt);
372     return 0;
373   }
374@@ -503,9 +503,9 @@ do_upline(long cnt)
375 
376 static int
377 do_skiplines(long cnt)
378-{ /* Skip lines forwards */
379+{ /* skip lines forwards */
380 
381-  /* Should be interruptable ... */
382+  /* should be interruptable ... */
383   (void)scrollf((int)(cnt + maxpagesize - 1), 0);
384   redraw(0);
385   return 0;
386@@ -513,9 +513,9 @@ do_skiplines(long cnt)
387 
388 static int
389 do_bskiplines(long cnt)
390-{ /* Skip lines backwards */
391+{ /* skip lines backwards */
392 
393-  /* Should be interruptable ... */
394+  /* should be interruptable ... */
395   (void)scrollb((int)(cnt + pagesize - 1), 0);
396   redraw(0);
397   return 0;
398@@ -523,7 +523,7 @@ do_bskiplines(long cnt)
399 
400 static int
401 do_fscreens(long cnt)
402-{ /* Skip screens forwards */
403+{ /* skip screens forwards */
404 
405   do {
406     if ((next_screen(pagesize, 0) & EOFILE) || interrupt)
407@@ -535,7 +535,7 @@ do_fscreens(long cnt)
408 
409 static int
410 do_bscreens(long cnt)
411-{ /* Skip screens backwards */
412+{ /* skip screens backwards */
413 
414   do {
415     if ((prev_screen(pagesize, 0) & START) || interrupt)
416@@ -557,7 +557,7 @@ scro_size(unsigned cnt)
417 
418 static int
419 do_f_scroll(long cnt)
420-{ /* Scroll forwards */
421+{ /* scroll forwards */
422 
423   (void)scrollf(scro_size((unsigned)cnt), 1);
424   return 0;
425@@ -565,7 +565,7 @@ do_f_scroll(long cnt)
426 
427 static int
428 do_b_scroll(long cnt)
429-{ /* Scroll backwards */
430+{ /* scroll backwards */
431 
432   (void)scrollb(scro_size((unsigned)cnt), 1);
433   return 0;
434@@ -573,7 +573,7 @@ do_b_scroll(long cnt)
435 
436 static int
437 do_previousfile(long cnt)
438-{ /* Visit previous file */
439+{ /* visit previous file */
440 
441   if (nextfile(-(int)cnt)) {
442     error("No (Nth) previous file");
443@@ -585,7 +585,7 @@ do_previousfile(long cnt)
444 
445 static int
446 do_nextfile(long cnt)
447-{ /* Visit next file */
448+{ /* visit next file */
449 
450   if (nextfile((int)cnt)) {
451     error("No (Nth) next file");
452@@ -603,7 +603,7 @@ do_quit(long cnt)
453 }
454 
455 /*
456- * The next array is initialized, sorted on the first element of the structs,
457+ * the next array is initialized, sorted on the first element of the structs,
458  * so that we can perform binary search
459  */
460 struct commands commands[] = {
461@@ -658,8 +658,8 @@ struct commands commands[] = {
462 };
463 
464 /*
465- * Lookup string "s" in the commands array, and return index.
466- * return 0 if not found.
467+ * lookup string "s" in the commands array, and return index
468+ * return 0 if not found
469  */
470 
471 int
472@@ -671,8 +671,8 @@ lookup(char *s)
473   u = &commands[sizeof(commands) / sizeof(*u) - 1];
474   do {
475     /*
476-     * Perform binary search
477-     */
478+ * perform binary search
479+ */
480     m = l + (u - l) / 2;
481     if (strcmp(s, m->c_cmd) > 0)
482       l = m + 1;
483@@ -684,10 +684,10 @@ lookup(char *s)
484   return 0;
485 }
486 
487-/*ARGSUSED*/
488+/* ARGSUSED */
489 static int
490 do_lcomm(long cnt)
491-{ /* Repeat last command */
492+{ /* repeat last command */
493   (void)cnt;
494 
495   if (!lastcomm) {
496@@ -699,7 +699,7 @@ do_lcomm(long cnt)
497 }
498 
499 /*
500- * Execute a command, with optional count "count".
501+ * execute a command, with optional count "count"
502  */
503 
504 void
505@@ -713,15 +713,15 @@ do_comm(int comm, long count)
506   flags = pcomm->c_flags;
507 
508   /*
509-   * Check the command.
510-   * If the last line of the file is displayed and the command goes
511-   * forwards and does'nt have the ability to go to the next file, it
512-   * is an error.
513-   * If the first line of the file is displayed and the command goes
514-   * backwards and does'nt have the ability to go to the previous file,
515-   * it is an error.
516-   * Also check wether we need the next or previous file. If so, get it.
517-   */
518+ * check the command
519+ * if the last line of the file is displayed and the command goes
520+ * forwards and does'nt have the ability to go to the next file, it
521+ * is an error
522+ * if the first line of the file is displayed and the command goes
523+ * backwards and does'nt have the ability to go to the previous file,
524+ * it is an error
525+ * also check wether we need the next or previous file. if so, get it
526+ */
527   if ((status & EOFILE) && (flags & AHEAD)) {
528     if (qflag || !(flags & TONEXTFILE))
529       return;
530@@ -735,8 +735,8 @@ do_comm(int comm, long count)
531       quit();
532   }
533   /*
534-   * Does the command stick around for LASTCOMM?
535-   */
536+ * does the command stick around for LASTCOMM?
537+ */
538   if (flags & STICKY) {
539     lastcomm  = comm;
540     lastcount = count;
541@@ -746,8 +746,8 @@ do_comm(int comm, long count)
542       count = 1;
543   } else {
544     /*
545-     * Does the command adapt the screensize?
546-     */
547+ * does the command adapt the screensize?
548+ */
549     if (flags & SCREENSIZE_ADAPT) {
550       temp = maxpagesize;
551       if ((unsigned)count < (unsigned)temp) {
552@@ -760,8 +760,8 @@ do_comm(int comm, long count)
553       pagesize = temp;
554     }
555     /*
556-     * Does the command adapt the scrollsize?
557-     */
558+ * does the command adapt the scrollsize?
559+ */
560     if (flags & SCROLLSIZE_ADAPT) {
561       temp = maxpagesize - 1;
562       if ((unsigned)count < (unsigned)temp) {
563@@ -772,7 +772,7 @@ do_comm(int comm, long count)
564     }
565   }
566   /*
567-   * Now execute the command.
568-   */
569+ * now execute the command
570+ */
571   (*(pcomm->c_func))(count);
572 }
+102, -102
  1@@ -1,4 +1,4 @@
  2-/* Copyright (c) 1985 Ceriel J.H. Jacobs */
  3+/* copyright (c) 1985 ceriel J.H. jacobs */
  4 
  5 #include "display.h"
  6 #include "assert.h"
  7@@ -28,7 +28,7 @@ static int   decode_cell(const char *s, const char **next, int *width, int *is_u
  8 int          wcwidth(wchar_t wc);
  9 
 10 /*
 11- * Fill n lines of the screen, each with "str".
 12+ * fill n lines of the screen, each with "str"
 13  */
 14 
 15 static void
 16@@ -40,7 +40,7 @@ fillscr(char *str, int n)
 17 }
 18 
 19 /*
 20- * Skip "n" screenlines of line "p", and return what's left of it.
 21+ * skip "n" screenlines of line "p", and return what's left of it
 22  */
 23 
 24 static char *
 25@@ -54,9 +54,9 @@ skiplines(char *p, int n)
 26 }
 27 
 28 /*
 29- * Redraw screen.
 30- * "n" = 1 if it is a real redraw, 0 if one page must be displayed.
 31- * It is also called when yap receives a stop signal.
 32+ * redraw screen
 33+ * "n" = 1 if it is a real redraw, 0 if one page must be displayed
 34+ * it is also called when yap receives a stop signal
 35  */
 36 
 37 void
 38@@ -73,10 +73,10 @@ redraw(int n)
 39 }
 40 
 41 /*
 42- * Compute return value for the routines "display" and "scrollf".
 43- * This return value indicates wether we are at the end of file
 44- * or at the start, or both.
 45- * "s" contains that part of the last line that was not displayed.
 46+ * compute return value for the routines "display" and "scrollf"
 47+ * this return value indicates wether we are at the end of file
 48+ * or at the start, or both
 49+ * "s" contains that part of the last line that was not displayed
 50  */
 51 
 52 static int
 53@@ -97,10 +97,10 @@ compretval(const char *s)
 54 }
 55 
 56 /*
 57- * Display nlines, starting at line n, not displaying the first
 58- * nd screenlines of n.
 59- * If reallydispl = 0, the actual displaying is not performed,
 60- * only the computing associated with it is done.
 61+ * display nlines, starting at line n, not displaying the first
 62+ * nd screenlines of n
 63+ * if reallydispl = 0, the actual displaying is not performed,
 64+ * only the computing associated with it is done
 65  */
 66 
 67 int
 68@@ -109,11 +109,11 @@ display(long n, int nd, int nlines, int reallydispl)
 69   struct scr_info *s = &scr_info;
 70   char            *p; /* pointer to line to be displayed */
 71 
 72-  if (startcomm) { /* No displaying on a command from the
 73-                    * yap command line. In this case, displaying
 74-                    * will be done after executing the command,
 75-                    * by a redraw.
 76-                    */
 77+  if (startcomm) { /* no displaying on a command from the
 78+ * yap command line. in this case, displaying
 79+ * will be done after executing the command,
 80+ * by a redraw
 81+ */
 82     reallydispl = 0;
 83   }
 84   if (!n) {
 85@@ -135,8 +135,8 @@ display(long n, int nd, int nlines, int reallydispl)
 86     }
 87   }
 88   /*
 89-   * Now, do computations and display
 90-   */
 91+ * now, do computations and display
 92+ */
 93   s->currentpos = 0;
 94   s->nf         = nd;
 95   s->head       = s->tail;
 96@@ -145,15 +145,15 @@ display(long n, int nd, int nlines, int reallydispl)
 97   p             = skiplines(getline(n, 1), nd);
 98   while (nlines && p) {
 99     /*
100-     * While there is room,
101-     * and there is something left to display ...
102-     */
103+ * while there is room,
104+ * and there is something left to display ...
105+ */
106     (s->tail->cnt)++;
107     nlines--;
108     if (*(p = do_line(p, reallydispl)) == '\0') {
109       /*
110-       * File-line finished, get next one ...
111-       */
112+ * file-line finished, get next one ...
113+ */
114       p = getline(++n, 1);
115       if (nlines && p) {
116         s->tail       = s->tail->next;
117@@ -173,7 +173,7 @@ display(long n, int nd, int nlines, int reallydispl)
118 }
119 
120 /*
121- * Scroll forwards n lines.
122+ * scroll forwards n lines
123  */
124 
125 int
126@@ -185,37 +185,37 @@ scrollf(int n, int reallydispl)
127   int              i;
128 
129   /*
130-   * First, find out how many screenlines of the last line were already
131-   * on the screen, and possibly above it.
132-   */
133+ * first, find out how many screenlines of the last line were already
134+ * on the screen, and possibly above it
135+ */
136 
137   if (n <= 0 || (status & EOFILE))
138     return status;
139   if (startcomm)
140     reallydispl = 0;
141   /*
142-   * Find out where to begin displaying
143-   */
144+ * find out where to begin displaying
145+ */
146   i = s->tail->cnt;
147   if ((ll = s->lastline) == s->firstline)
148     i += s->nf;
149   p = skiplines(getline(ll, 1), i);
150   /*
151-   * Now, place the cursor at the first free line
152-   */
153+ * now, place the cursor at the first free line
154+ */
155   if (reallydispl && !stupid) {
156     clrbline();
157     mgoto(s->currentpos);
158   }
159   /*
160-   * Now display lines, keeping track of which lines are on the screen.
161-   */
162-  while (n-- > 0) { /* There are still rows to be displayed */
163-    if (!*p) {      /* End of line, get next one */
164+ * now display lines, keeping track of which lines are on the screen
165+ */
166+  while (n-- > 0) { /* there are still rows to be displayed */
167+    if (!*p) {      /* end of line, get next one */
168       if (!(p = getline(++ll, 1))) {
169         /*
170-         * No lines left. At end of file
171-         */
172+ * no lines left. at end of file
173+ */
174         break;
175       }
176       s->tail       = s->tail->next;
177@@ -224,16 +224,16 @@ scrollf(int n, int reallydispl)
178     }
179     if (s->currentpos >= maxpagesize) {
180       /*
181-       * No room, delete first screen-line
182-       */
183+ * no room, delete first screen-line
184+ */
185       s->currentpos--;
186       s->nf++;
187       if (--(s->head->cnt) == 0) {
188         /*
189-         * The first file-line on the screen is wiped
190-         * out completely; update administration
191-         * accordingly.
192-         */
193+ * the first file-line on the screen is wiped
194+ * out completely; update administration
195+ * accordingly
196+ */
197         s->nf   = 0;
198         s->head = s->head->next;
199         assert(s->head->cnt > 0);
200@@ -246,14 +246,14 @@ scrollf(int n, int reallydispl)
201 }
202 
203 /*
204- * Scroll back n lines
205+ * scroll back n lines
206  */
207 
208 int
209 scrollb(int n, int reallydispl)
210 {
211   struct scr_info *s = &scr_info;
212-  char            *p; /* Holds string to be displayed */
213+  char            *p; /* holds string to be displayed */
214   int              i;
215   int              count;
216   long             ln; /* a line number */
217@@ -261,8 +261,8 @@ scrollb(int n, int reallydispl)
218   int              cannotscroll; /* stupid or no insert-line */
219 
220   /*
221-   * First, find out where to start
222-   */
223+ * first, find out where to start
224+ */
225   if ((count = n) <= 0 || (status & START))
226     return status;
227   if (startcomm)
228@@ -270,31 +270,31 @@ scrollb(int n, int reallydispl)
229   cannotscroll = stupid || (!*AL && !*SR);
230   ln           = s->firstline;
231   nodispl      = s->nf;
232-  while (count) { /* While scrolling back ... */
233+  while (count) { /* while scrolling back ... */
234     i = nodispl;
235     if (i) {
236       /*
237-       * There were screen-lines of s->firstline that were not
238-       * displayed.
239-       * We can use them now, but only "count" of them.
240-       */
241+ * there were screen-lines of s->firstline that were not
242+ * displayed
243+ * we can use them now, but only "count" of them
244+ */
245       if (i > count)
246         i = count;
247       s->currentpos += i;
248       nodispl -= i;
249       count -= i;
250-    } else { /* Get previous line */
251+    } else { /* get previous line */
252       if (ln == 1)
253-        break; /* isn't there ... */
254+        break; /* isnt there ... */
255       p = getline(--ln, 1);
256       /*
257-       * Make it the first line of the screen and compute
258-       * how many screenlines it takes. These lines are not
259-       * displayed, but nodispl is set to this count, so
260-       * that it will be nonzero next time around
261-       */
262+ * make it the first line of the screen and compute
263+ * how many screenlines it takes. these lines are not
264+ * displayed, but nodispl is set to this count, so
265+ * that it will be nonzero next time around
266+ */
267       nodispl = 0;
268-      do { /* Find out how many screenlines */
269+      do { /* find out how many screenlines */
270         nodispl++;
271         p = skiplines(p, 1);
272       } while (*p);
273@@ -306,33 +306,33 @@ scrollb(int n, int reallydispl)
274   if (reallydispl && hardcopy)
275     i = n;
276   /*
277-   * Now that we know where to start, we can use "display" to do the
278-   * rest of the computing for us, and maybe even the displaying ...
279-   */
280+ * now that we know where to start, we can use "display" to do the
281+ * rest of the computing for us, and maybe even the displaying ...
282+ */
283   i = display(ln, nodispl, i, reallydispl && cannotscroll);
284   if (cannotscroll || !reallydispl) {
285     /*
286-     * Yes, "display" did the displaying, or we did'nt have to
287-     * display at all.
288-     * I like it, but the user obviously does not.
289-     * Let him buy another (smarter) terminal ...
290-     */
291+ * yes, "display" did the displaying, or we did'nt have to
292+ * display at all
293+ * i like it, but the user obviously does not
294+ * let him buy another (smarter) terminal ...
295+ */
296     return i;
297   }
298   /*
299-   * Now, all we have to do is the displaying. And we are dealing with
300-   * a smart terminal (it can insert lines or scroll back).
301-   */
302+ * now, all we have to do is the displaying. and we are dealing with
303+ * a smart terminal (it can insert lines or scroll back)
304+ */
305   home();
306   /*
307-   * Insert lines all at once
308-   */
309+ * insert lines all at once
310+ */
311   for (i = n; i; i--) {
312     if (DB && *CE) {
313       /*
314-       * Grumble..., terminal retains lines below, so we have
315-       * to clear the lines that we push off the screen
316-       */
317+ * grumble..., terminal retains lines below, so we have
318+ * to clear the lines that we push off the screen
319+ */
320       clrbline();
321       home();
322     }
323@@ -354,8 +354,8 @@ scrollb(int n, int reallydispl)
324 }
325 
326 /*
327- * Process a line.
328- * If reallydispl > 0 then display it.
329+ * process a line
330+ * if reallydispl > 0 then display it
331  */
332 
333 static char *
334@@ -397,13 +397,13 @@ do_line(char *str, int reallydispl)
335     }
336     if (uc < ' ' && (cell_len = match(str, &c2, sppat)) > 0) {
337       /*
338-       * We found a string that matches, and thus must be
339-       * echoed literally
340-       */
341+ * we found a string that matches, and thus must be
342+ * echoed literally
343+ */
344       if ((pos - c2) <= 0) {
345         /*
346-         * It did not fit
347-         */
348+ * it did not fit
349+ */
350         break;
351       }
352       pos -= c2;
353@@ -438,8 +438,8 @@ do_line(char *str, int reallydispl)
354     }
355     do_ul = 1;
356     /*
357-     * Find underline sequences ...
358-     */
359+ * find underline sequences ...
360+ */
361     if (is_underscore && *cursor == '\b' && *(cursor + 1) != '\0') {
362       cell_start = cursor + 1;
363       cell_len   = decode_cell(cell_start, &next, &cell_width, &is_underscore);
364@@ -519,9 +519,9 @@ do_line(char *str, int reallydispl)
365       pos -= cell_width;
366       if (reallydispl && do_ul && *UC && cell_width == 1 && pos > 0) {
367         /*
368-         * Underlining apparently is done one
369-         * character at a time.
370-         */
371+ * underlining apparently is done one
372+ * character at a time
373+ */
374         flush_display_buffer(buf, &p);
375         backspace();
376         underchar();
377@@ -537,13 +537,13 @@ do_line(char *str, int reallydispl)
378       putline("\r\n");
379     }
380     /*
381-     * The next should be here! I.e. it may not be before printing
382-     * the newline. This has to do with XN. We don't know exactly
383-     * WHEN the terminal will stop ignoring the newline.
384-     * I have for example a terminal (Ampex a230) that will
385-     * continue to ignore the newline after a clear to end of line
386-     * sequence, but not after an end_underline sequence.
387-     */
388+ * the next should be here! i.e. it may not be before printing
389+ * the newline. this has to do with XN. we dont know exactly
390+ * WHEN the terminal will stop ignoring the newline
391+ * i have for example a terminal (ampex a230) that will
392+ * continue to ignore the newline after a clear to end of line
393+ * sequence, but not after an end_underline sequence
394+ */
395     if (lastmode) {
396       end_underline();
397     }
398@@ -628,7 +628,7 @@ decode_cell(const char *s, const char **next, int *width, int *is_underscore)
399 /* ARGSUSED */
400 int
401 setmark(long cnt)
402-{ /* Set a mark on the current page */
403+{ /* set a mark on the current page */
404   struct scr_info *p = &scr_info;
405   (void)cnt;
406 
407@@ -640,7 +640,7 @@ setmark(long cnt)
408 /* ARGSUSED */
409 int
410 tomark(long cnt)
411-{ /* Go to the mark */
412+{ /* go to the mark */
413   struct scr_info *p = &scr_info;
414   (void)cnt;
415 
416@@ -651,7 +651,7 @@ tomark(long cnt)
417 /* ARGSUSED */
418 int
419 exgmark(long cnt)
420-{ /* Exchange mark and current page */
421+{ /* exchange mark and current page */
422   struct scr_info *p = &scr_info;
423   long             svfirst;
424   int              svnf;
425@@ -667,7 +667,7 @@ exgmark(long cnt)
426 
427 void
428 d_clean()
429-{ /* Clean up */
430+{ /* clean up */
431   struct scr_info *p = &scr_info;
432 
433   p->savnf      = 0;
+42, -42
  1@@ -1,7 +1,7 @@
  2-/* Copyright (c) 1985 Ceriel J.H. Jacobs */
  3+/* copyright (c) 1985 ceriel J.H. jacobs */
  4 
  5 /*
  6- * Command reader, also executes shell escapes
  7+ * command reader, also executes shell escapes
  8  */
  9 
 10 #include "getcomm.h"
 11@@ -23,8 +23,8 @@ static int  killchar(int c);
 12 static void sigquit(int signo);
 13 
 14 /*
 15- * Read a line from the terminal, doing line editing.
 16- * The parameter s contains the prompt for the line.
 17+ * read a line from the terminal, doing line editing
 18+ * the parameter s contains the prompt for the line
 19  */
 20 
 21 char *
 22@@ -41,19 +41,19 @@ readline(char *s)
 23   while ((ch = getch()) != '\n' && ch != '\r') {
 24     if (ch == -1) {
 25       /*
 26-       * Can only occur because of an interrupted read.
 27-       */
 28+ * can only occur because of an interrupted read
 29+ */
 30       ch        = erasech;
 31       interrupt = 0;
 32     }
 33     if (ch == erasech) {
 34       /*
 35-       * Erase last char
 36-       */
 37+ * erase last char
 38+ */
 39       if (p == buf) {
 40         /*
 41-         * There was none, so return
 42-         */
 43+ * there was none, so return
 44+ */
 45         return (char *)0;
 46       }
 47       pos -= killchar(*--p);
 48@@ -62,8 +62,8 @@ readline(char *s)
 49     }
 50     if (ch == killch) {
 51       /*
 52-       * Erase the whole line
 53-       */
 54+ * erase the whole line
 55+ */
 56       if (!(p > buf && *(p - 1) == '\\')) {
 57         while (p > buf) {
 58           pos -= killchar(*--p);
 59@@ -74,9 +74,9 @@ readline(char *s)
 60     }
 61     if (p > &buf[78] || pos >= COLS - 2) {
 62       /*
 63-       * Line does not fit.
 64-       * Simply refuse to make it any longer
 65-       */
 66+ * line does not fit
 67+ * simply refuse to make it any longer
 68+ */
 69       pos -= killchar(*--p);
 70     }
 71     *p++ = ch;
 72@@ -95,7 +95,7 @@ readline(char *s)
 73 }
 74 
 75 /*
 76- * Erase a character from the command line.
 77+ * erase a character from the command line
 78  */
 79 
 80 static int
 81@@ -112,7 +112,7 @@ killchar(int c)
 82 }
 83 
 84 /*
 85- * Do a shell escape, after expanding '%' and '!'.
 86+ * do a shell escape, after expanding '%' and '!'
 87  */
 88 
 89 void
 90@@ -134,14 +134,14 @@ shellescape(char *p, int esc_char)
 91   cnt   = 253;
 92   while (*p) {
 93     /*
 94-     * expand command
 95-     */
 96+ * expand command
 97+ */
 98     switch (*p++) {
 99       case '!':
100         /*
101-         * An unescaped ! expands to the previous
102-         * command, but disappears if there is none
103-         */
104+ * an unescaped ! expands to the previous
105+ * command, but disappears if there is none
106+ */
107         if (lastc != '\\') {
108           if (*previous) {
109             id = strlen(previous);
110@@ -156,9 +156,9 @@ shellescape(char *p, int esc_char)
111         continue;
112       case '%':
113         /*
114-         * An unescaped % will expand to the current
115-         * filename, but disappears is there is none
116-         */
117+ * an unescaped % will expand to the current
118+ * filename, but disappears is there is none
119+ */
120         if (lastc != '\\') {
121           if (nopipe) {
122             id = strlen(currentfile);
123@@ -184,8 +184,8 @@ shellescape(char *p, int esc_char)
124   *p2 = '\0';
125   if (!stupid) {
126     /*
127-     * Display expanded command
128-     */
129+ * display expanded command
130+ */
131     cputline(comm);
132     putline("\r\n");
133   }
134@@ -225,8 +225,8 @@ shellescape(char *p, int esc_char)
135   }
136   while ((lastc = wait((int *)0)) != id && lastc >= 0) {
137     /*
138-     * Wait for child, making sure it is the one we expected ...
139-     */
140+ * wait for child, making sure it is the one we expected ...
141+ */
142   }
143   (void)signal(SIGINT, catchdel);
144   (void)signal(SIGQUIT, sigquit);
145@@ -244,7 +244,7 @@ sigquit(int signo)
146 }
147 
148 /*
149- * Get all those commands ...
150+ * get all those commands ...
151  */
152 
153 int
154@@ -268,14 +268,14 @@ getcomm(long *plong)
155     for (;;) {
156       if (c == -1) {
157         /*
158-         * This should never happen, but it does,
159-         * when the user gives a TSTP signal (^Z) or
160-         * an interrupt while the program is trying
161-         * to read a character from the terminal.
162-         * In this case, the read is interrupted, so
163-         * we end up here.
164-         * Right, we will have to read again.
165-         */
166+ * this should never happen, but it does,
167+ * when the user gives a TSTP signal (^z) or
168+ * an interrupt while the program is trying
169+ * to read a character from the terminal
170+ * in this case, the read is interrupted, so
171+ * we end up here
172+ * right, we will have to read again
173+ */
174         if (interrupt)
175           return 1;
176         break;
177@@ -284,15 +284,15 @@ getcomm(long *plong)
178       *p   = 0;
179       if ((i = match(buf, &j, currmap->k_mach)) > 0) {
180         /*
181-         * The key sequence matched. We have a command
182-         */
183+ * the key sequence matched. we have a command
184+ */
185         return j;
186       }
187       if (i == 0)
188         return 0;
189       /*
190-       * We have a prefix of a command.
191-       */
192+ * we have a prefix of a command
193+ */
194       assert(i == FSM_ISPREFIX);
195       c = getch();
196     }
+85, -85
  1@@ -1,4 +1,4 @@
  2-/* Copyright (c) 1985 Ceriel J.H. Jacobs */
  3+/* copyright (c) 1985 ceriel J.H. jacobs */
  4 
  5 #include "getline.h"
  6 #include "assert.h"
  7@@ -15,12 +15,12 @@
  8 #define CHUNK     50   /* # of blockheaders allocated at a time */
  9 
 10 /*
 11- * Blocks are kept in an array in line-number order. Each block stores the raw
 12- * text and the offsets of the lines parsed from it.
 13+ * blocks are kept in an array in line-number order. each block stores the raw
 14+ * text and the offsets of the lines parsed from it
 15  */
 16 
 17 struct block {
 18-  int b_flags;    /* Contains the following flags: */
 19+  int b_flags;    /* contains the following flags: */
 20 #define PARTLY 02 /* block not filled completely (eof) */
 21   long  b_end;    /* line number of last line in block */
 22   char *b_info;   /* the block */
 23@@ -44,16 +44,16 @@ new_block()
 24 
 25   if (!maxblocklist || !(pblock->b_flags & PARTLY)) {
 26     /*
 27-     * There is no last block, or it was filled completely,
 28-     * so allocate a new blockheader.
 29-     */
 30+ * there is no last block, or it was filled completely,
 31+ * so allocate a new blockheader
 32+ */
 33     int siz;
 34 
 35     pblock = blocklist;
 36     if (maxblocklist == topblocklist) {
 37       /*
 38-       * No blockheaders left. Allocate new ones
 39-       */
 40+ * no blockheaders left. allocate new ones
 41+ */
 42       siz       = topblocklist - pblock;
 43       blocklist = pblock =
 44           (struct block *)re_alloc((char *)pblock, (unsigned)((siz + CHUNK) * sizeof(*pblock)));
 45@@ -67,8 +67,8 @@ new_block()
 46       }
 47       if (!siz) {
 48         /*
 49-         * Create dummy header cell.
 50-         */
 51+ * create dummy header cell
 52+ */
 53         maxblocklist++;
 54       }
 55     }
 56@@ -79,9 +79,9 @@ new_block()
 57 }
 58 
 59 /*
 60- * Return the block in which line 'n' of the current file can be found.
 61- * If "disable_interrupt" = 0, the call may be interrupted, in which
 62- * case it returns 0.
 63+ * return the block in which line 'n' of the current file can be found
 64+ * if "disable_interrupt" = 0, the call may be interrupted, in which
 65+ * case it returns 0
 66  */
 67 
 68 static struct block *
 69@@ -91,17 +91,17 @@ getblock(long n, int disable_interrupt)
 70 
 71   if (stdf < 0) {
 72     /*
 73-     * Not file descriptor, so return end of file
 74-     */
 75+ * not file descriptor, so return end of file
 76+ */
 77     return 0;
 78   }
 79   pblock = maxblocklist - 1;
 80   if (n < lastreadline || (n == lastreadline && !(pblock->b_flags & PARTLY))) {
 81     /*
 82-     * The line asked for has been read already.
 83-     * Perform binary search in the blocklist to find the block
 84-     * where it's in.
 85-     */
 86+ * the line asked for has been read already
 87+ * perform binary search in the blocklist to find the block
 88+ * where its in
 89+ */
 90     struct block *min, *mid;
 91 
 92     min = blocklist + 1;
 93@@ -112,13 +112,13 @@ getblock(long n, int disable_interrupt)
 94       } else
 95         pblock = mid;
 96     } while (min < pblock);
 97-    /* Found, pblock is now a reference to the block wanted */
 98+    /* found, pblock is now a reference to the block wanted */
 99     return pblock;
100   }
101 
102   /*
103-   * The line was'nt read yet, so read blocks until found
104-   */
105+ * the line was'nt read yet, so read blocks until found
106+ */
107   for (;;) {
108     if (interrupt && !disable_interrupt)
109       return 0;
110@@ -128,9 +128,9 @@ getblock(long n, int disable_interrupt)
111     }
112     if (pblock->b_flags & PARTLY) {
113       /*
114-       * We did not find it, and the last block could not be
115-       * read completely, so return 0;
116-       */
117+ * we did not find it, and the last block could not be
118+ * read completely, so return 0;
119+ */
120       return 0;
121     }
122   }
123@@ -149,7 +149,7 @@ getline(long n, int disable_interrupt)
124 }
125 
126 /*
127- * Find the last line of the input, and return its number
128+ * find the last line of the input, and return its number
129  */
130 
131 long
132@@ -158,10 +158,10 @@ to_lastline()
133   for (;;) {
134     if (!getline(lastreadline + 1, 0)) {
135       /*
136-       * "lastreadline" always contains the linenumber of
137-       * the last line read. So, if the call to getline
138-       * succeeds, "lastreadline" is affected
139-       */
140+ * "lastreadline" always contains the linenumber of
141+ * the last line read. so, if the call to getline
142+ * succeeds, "lastreadline" is affected
143+ */
144       if (interrupt)
145         return -1L;
146       return lastreadline;
147@@ -183,8 +183,8 @@ alloc(unsigned size)
148 }
149 
150 /*
151- * Re-allocate the memorychunk pointed to by ptr, to let it
152- * grow or shrink.
153+ * re-allocate the memorychunk pointed to by ptr, to let it
154+ * grow or shrink
155  */
156 
157 static char *
158@@ -203,53 +203,53 @@ static char *saved;
159 static long  filldegree;
160 
161 /*
162- * Try to read the block indicated by pblock
163+ * try to read the block indicated by pblock
164  */
165 
166 static void
167 nextblock(struct block *pblock)
168 {
169-  char *c,                   /* Run through pblock->b_info */
170+  char *c,                   /* run through pblock->b_info */
171       *c1;                   /* indicate end of pblock->b_info */
172   int            *poff;      /* pointer in line-offset list */
173   int             cnt;       /* # of characters read */
174-  unsigned        siz;       /* Size of allocated line-offset list */
175+  unsigned        siz;       /* size of allocated line-offset list */
176   static unsigned savedsiz;  /* saved "siz" */
177   static int     *savedpoff; /* saved "poff" */
178   static char    *savedc1;   /* saved "c1" */
179 
180   if (pblock->b_flags & PARTLY) {
181     /*
182-     * The block was already partly filled. Initialize locals
183-     * accordingly
184-     */
185+ * the block was already partly filled. initialize locals
186+ * accordingly
187+ */
188     poff            = savedpoff;
189     siz             = savedsiz;
190     pblock->b_flags = 0;
191     c1              = savedc1;
192     if (c1 == pblock->b_info || *(c1 - 1)) {
193       /*
194-       * We had incremented "lastreadline" temporarily,
195-       * because the last line could not be completely read
196-       * last time we tried. Undo this increment
197-       */
198+ * we had incremented "lastreadline" temporarily,
199+ * because the last line could not be completely read
200+ * last time we tried. undo this increment
201+ */
202       poff--;
203       --lastreadline;
204     }
205   } else {
206     if (saved) {
207       /*
208-       * There were leftovers from the previous block
209-       */
210+ * there were leftovers from the previous block
211+ */
212       pblock->b_info = saved;
213       c1             = savedc1;
214       saved          = 0;
215-    } else { /* Allocate new block */
216+    } else { /* allocate new block */
217       pblock->b_info = c1 = alloc(BLOCKSIZE + 1);
218     }
219     /*
220-     * Allocate some space for line-offsets
221-     */
222+ * allocate some space for line-offsets
223+ */
224     pblock->b_offs = poff = (int *)alloc((unsigned)(100 * sizeof(int)));
225     siz                   = 99;
226     *poff++               = 0;
227@@ -257,13 +257,13 @@ nextblock(struct block *pblock)
228   c = c1;
229   for (;;) {
230     /*
231-     * Read loop
232-     */
233+ * read loop
234+ */
235     cnt = read(stdf, c1, BLOCKSIZE - (c1 - pblock->b_info));
236     if (cnt < 0) {
237       /*
238-       * Interrupted read
239-       */
240+ * interrupted read
241+ */
242       if (errno == EINTR)
243         continue;
244       error("Could not read input file");
245@@ -279,22 +279,22 @@ nextblock(struct block *pblock)
246   assert(c <= c1);
247   while (c < c1) {
248     /*
249-     * Now process the block
250-     */
251+ * now process the block
252+ */
253     if (*c == '\n') {
254       /*
255-       * Newlines are replaced by '\0', so that "getline"
256-       * can deliver one line at a time
257-       */
258+ * newlines are replaced by '\0', so that "getline"
259+ * can deliver one line at a time
260+ */
261       *c = 0;
262       lastreadline++;
263       /*
264-       * Remember the line-offset
265-       */
266+ * remember the line-offset
267+ */
268       if (poff == pblock->b_offs + siz) {
269         /*
270-         * No space for it, allocate some more
271-         */
272+ * no space for it, allocate some more
273+ */
274         pblock->b_offs =
275             (int *)re_alloc((char *)pblock->b_offs, (unsigned)((siz + 51) * sizeof(int)));
276         poff = pblock->b_offs + siz;
277@@ -308,15 +308,15 @@ nextblock(struct block *pblock)
278   *c = 0;
279   if (c != pblock->b_info && *(c - 1) != 0) {
280     /*
281-     * The last line read does not end with a newline, so add one
282-     */
283+ * the last line read does not end with a newline, so add one
284+ */
285     lastreadline++;
286     *poff++ = c - pblock->b_info + 1;
287     if (!(pblock->b_flags & PARTLY) && *(poff - 2) != 0) {
288       /*
289-       * Save the started line; it will be in the next block.
290-       * Remove the newline we added just now.
291-       */
292+ * save the started line; it will be in the next block
293+ * remove the newline we added just now
294+ */
295       saved = c1 = alloc(BLOCKSIZE + 1);
296       c          = pblock->b_info + *(--poff - 1);
297       while (*c)
298@@ -329,9 +329,9 @@ nextblock(struct block *pblock)
299   pblock->b_end = lastreadline;
300   if (pblock->b_flags & PARTLY) {
301     /*
302-     * Take care, that we can call "nextblock" again, to fill in
303-     * the rest of this block
304-     */
305+ * take care, that we can call "nextblock" again, to fill in
306+ * the rest of this block
307+ */
308     savedsiz  = siz;
309     savedpoff = poff;
310     savedc1   = c;
311@@ -347,8 +347,8 @@ nextblock(struct block *pblock)
312 }
313 
314 /*
315- * Called after processing a file.
316- * Free all core.
317+ * called after processing a file
318+ * free all core
319  */
320 
321 void
322@@ -378,7 +378,7 @@ do_clean()
323 }
324 
325 /*
326- * Get a character. If possible, do some workahead.
327+ * get a character. if possible, do some workahead
328  */
329 
330 int
331@@ -391,17 +391,17 @@ getch()
332   flush();
333   if (startcomm) {
334     /*
335-     * Command line option command
336-     */
337+ * command line option command
338+ */
339     if (*startcomm)
340       return *startcomm++;
341     return '\n';
342   }
343   if (stdf >= 0) {
344     /*
345-     * Make reads from the terminal non-blocking, so that
346-     * we can see if the user typed something
347-     */
348+ * make reads from the terminal non-blocking, so that
349+ * we can see if the user typed something
350+ */
351     flags = fcntl(0, F_GETFL, 0);
352     if (flags != -1 && fcntl(0, F_SETFL, flags | O_NONBLOCK) != -1) {
353       bytes_read = 0;
354@@ -417,18 +417,18 @@ getch()
355 			       (nopipe ||
356 			        (fstat(stdf, &buf) >= 0 && buf.st_size > 0))) {
357         /*
358-         * Do some read ahead, after making sure there
359-         * is input and the user did not type a command
360-         */
361+ * do some read ahead, after making sure there
362+ * is input and the user did not type a command
363+ */
364         new_block();
365       }
366       (void)fcntl(0, F_SETFL, flags);
367       if (bytes_read < 0) {
368         /*
369-         * Could this have happened?
370-         * I'm not sure, because the read is
371-         * nonblocking. Can it be interrupted then?
372-         */
373+ * could this have happened?
374+ * i'm not sure, because the read is
375+ * nonblocking. can it be interrupted then?
376+ */
377         return -1;
378       }
379       if (bytes_read > 0)
380@@ -452,7 +452,7 @@ getch()
381 }
382 
383 /*
384- * Get the position of line "ln" in the file.
385+ * get the position of line "ln" in the file
386  */
387 
388 long
+16, -16
 1@@ -1,4 +1,4 @@
 2-/* Copyright (c) 1985 Ceriel J.H. Jacobs */
 3+/* copyright (c) 1985 ceriel J.H. jacobs */
 4 
 5 #include "help.h"
 6 #include "commands.h"
 7@@ -12,14 +12,14 @@
 8 #include "prompt.h"
 9 #include "term.h"
10 
11-static int           h_cnt;  /* Count # of lines */
12-static struct state *origin; /* Keep track of startstate */
13+static int           h_cnt;  /* count # of lines */
14+static struct state *origin; /* keep track of startstate */
15 
16 /*
17- * Print a key sequence.
18- * We arrived at an endstate. The s_next link in the state structure now
19+ * print a key sequence
20+ * we arrived at an endstate. the s_next link in the state structure now
21  * leads us from "origin" to the current state, so that we can print the key
22- * sequence easily.
23+ * sequence easily
24  */
25 
26 static void
27@@ -29,15 +29,15 @@ pr_comm()
28   char         *pb;
29   int           c;
30   char          buf[30];
31-  int           i = 0; /* How many characters printed? */
32+  int           i = 0; /* how many characters printed? */
33 
34   pb = buf;
35   for (;;) {
36     c = p->s_char & 0177;
37     if (c < ' ' || c == 0177) {
38       /*
39-       * Will take an extra position
40-       */
41+ * will take an extra position
42+ */
43       i++;
44     }
45     *pb++ = c;
46@@ -54,9 +54,9 @@ pr_comm()
47 }
48 
49 /*
50- * Print out a description of the keymap. This is done, by temporarily using
51+ * print out a description of the keymap. this is done, by temporarily using
52  * the s_next field in the state structure indicate the state matching the
53- * next character, so that we can walk from "origin" to an endstate.
54+ * next character, so that we can walk from "origin" to an endstate
55  */
56 
57 static void
58@@ -68,13 +68,13 @@ pr_mach(struct state *currstate, struct state *back)
59     if (interrupt)
60       break;
61     if (back) {
62-      save         = back->s_next; /* Save original link */
63+      save         = back->s_next; /* save original link */
64       back->s_next = currstate;
65     }
66     if (!currstate->s_match) {
67       /*
68-       * End state, print command
69-       */
70+ * end state, print command
71+ */
72       pr_comm();
73       putline(commands[currstate->s_cnt].c_descr);
74       putline("\r\n");
75@@ -92,10 +92,10 @@ pr_mach(struct state *currstate, struct state *back)
76   }
77 }
78 
79-/*ARGSUSED*/
80+/* ARGSUSED */
81 int
82 do_help(long i)
83-{ /* The help command */
84+{ /* the help command */
85   (void)i;
86 
87   startcomm = 0;
+27, -27
  1@@ -1,4 +1,4 @@
  2-/* Copyright (c) 1985 Ceriel J.H. Jacobs */
  3+/* copyright (c) 1985 ceriel J.H. jacobs */
  4 
  5 #include "keys.h"
  6 #include "assert.h"
  7@@ -17,13 +17,13 @@ red=^L:rep=.:bps=Z:bss=b:fps=z:fss=d:shl=!:tom=':top=\\^:vis=e:\
  8 wrf=w:qui=q:qui=Q:mar=m:pip=|";
  9 
 10 /*
 11- * Construct an error message and return it
 12+ * construct an error message and return it
 13  */
 14 
 15 static char *
 16 kerror(char *key, char *emess)
 17 {
 18-  static char ebuf[80]; /* Room for the error message */
 19+  static char ebuf[80]; /* room for the error message */
 20 
 21   (void)strcpy(ebuf, key);
 22   (void)strcat(ebuf, emess);
 23@@ -31,41 +31,41 @@ kerror(char *key, char *emess)
 24 }
 25 
 26 /*
 27- * Compile a keymap into commtable. Returns an error message if there
 28+ * compile a keymap into commtable. returns an error message if there
 29  * is one
 30  */
 31 
 32 static char *
 33 compile(char *map, struct keymap *commtable)
 34 {
 35-  char *mark; /* Indicates start of mnemonic */
 36-  char *c;    /* Runs through buf */
 37+  char *mark; /* indicates start of mnemonic */
 38+  char *c;    /* runs through buf */
 39   int   temp;
 40   char *escapes = commtable->k_esc;
 41-  char  buf[10]; /* Will hold key sequence */
 42+  char  buf[10]; /* will hold key sequence */
 43 
 44   (void)strcpy(commtable->k_help, "Illegal command");
 45   while (*map) {
 46     c    = buf;
 47-    mark = map; /* Start of mnemonic */
 48+    mark = map; /* start of mnemonic */
 49     while (*map && *map != '=') {
 50       map++;
 51     }
 52     if (!*map) {
 53       /*
 54-       * Mnemonic should end with '='
 55-       */
 56+ * mnemonic should end with '='
 57+ */
 58       return kerror(mark, ": Syntax error");
 59     }
 60     *map++ = 0;
 61     while (*map) {
 62       /*
 63-       * Get key sequence
 64-       */
 65+ * get key sequence
 66+ */
 67       if (*map == ':') {
 68         /*
 69-         * end of key sequence
 70-         */
 71+ * end of key sequence
 72+ */
 73         map++;
 74         break;
 75       }
 76@@ -73,8 +73,8 @@ compile(char *map, struct keymap *commtable)
 77       if (*c == '^' || *c == '\\') {
 78         if (!(temp = *map++)) {
 79           /*
 80-           * Escape not followed by a character
 81-           */
 82+ * escape not followed by a character
 83+ */
 84           return kerror(mark, ": Syntax error");
 85         }
 86         if (*c == '^') {
 87@@ -109,9 +109,9 @@ compile(char *map, struct keymap *commtable)
 88     assert(temp == FSM_OKE);
 89     if (!strcmp(mark, "hlp")) {
 90       /*
 91-       * Create an error message to be given when the user
 92-       * types an illegal command
 93-       */
 94+ * create an error message to be given when the user
 95+ * types an illegal command
 96+ */
 97       (void)strcpy(commtable->k_help, "Type ");
 98       (void)strcat(commtable->k_help, buf);
 99       (void)strcat(commtable->k_help, " for help");
100@@ -122,7 +122,7 @@ compile(char *map, struct keymap *commtable)
101 }
102 
103 /*
104- * Initialize the keymaps
105+ * initialize the keymaps
106  */
107 
108 void
109@@ -133,20 +133,20 @@ initkeys()
110 
111   currmap  = &xx[0];
112   othermap = &xx[1];
113-  p        = compile(defaultmap, currmap); /* Compile default map */
114+  p        = compile(defaultmap, currmap); /* compile default map */
115   assert(p == (char *)0);
116   p = getenv("YAPKEYS");
117   if (p) {
118     if (!(p = compile(p, othermap))) {
119       /*
120-       * No errors in user defined keymap. So, use it
121-       */
122+ * no errors in user defined keymap. so, use it
123+ */
124       do_chkm(0L);
125       return;
126     }
127     error(p);
128   }
129-  othermap = 0; /* No other keymap */
130+  othermap = 0; /* no other keymap */
131 }
132 
133 int
134@@ -162,10 +162,10 @@ is_escape(int c)
135 }
136 
137 static char keyset[16]; /* bitset indicating which keys are
138-                         * used
139-                         */
140+ * used
141+ */
142 /*
143- * Mark key "key" as used
144+ * mark key "key" as used
145  */
146 
147 void
+35, -35
  1@@ -1,4 +1,4 @@
  2-/* Copyright (c) 1985 Ceriel J.H. Jacobs */
  3+/* copyright (c) 1985 ceriel J.H. jacobs */
  4 
  5 #include "machine.h"
  6 #include "assert.h"
  7@@ -7,22 +7,22 @@
  8 #include <ctype.h>
  9 
 10 /*
 11- * Add part of finite state machine to recognize the string s.
 12+ * add part of finite state machine to recognize the string s
 13  */
 14 
 15 static int
 16 addtomach(char *s, int cnt, struct state **list)
 17 {
 18   struct state *l;
 19-  int           i = FSM_OKE; /* Return value */
 20+  int           i = FSM_OKE; /* return value */
 21   int           j;
 22 
 23   for (;;) {
 24     l = *list;
 25     if (!l) {
 26       /*
 27-       * Create new list element
 28-       */
 29+ * create new list element
 30+ */
 31       *list = l     = (struct state *)alloc(sizeof(*l));
 32       l->s_char     = *s;
 33       l->s_endstate = 0;
 34@@ -31,21 +31,21 @@ addtomach(char *s, int cnt, struct state **list)
 35     }
 36     if (l->s_char == *s) {
 37       /*
 38-       * Continue with next character
 39-       */
 40+ * continue with next character
 41+ */
 42       if (!*++s) {
 43         /*
 44-         * No next character
 45-         */
 46+ * no next character
 47+ */
 48         j             = l->s_endstate;
 49         l->s_endstate = 1;
 50         if (l->s_match || j) {
 51           /*
 52-           * If the state already was an endstate,
 53-           * or has a successor, the currently
 54-           * added string is a prefix of an
 55-           * already recognized string
 56-           */
 57+ * if the state already was an endstate,
 58+ * or has a successor, the currently
 59+ * added string is a prefix of an
 60+ * already recognized string
 61+ */
 62           return FSM_ISPREFIX;
 63         }
 64         l->s_cnt = cnt;
 65@@ -53,10 +53,10 @@ addtomach(char *s, int cnt, struct state **list)
 66       }
 67       if (l->s_endstate) {
 68         /*
 69-         * In this case, the currently added string has
 70-         * a prefix that is an already recognized
 71-         * string.
 72-         */
 73+ * in this case, the currently added string has
 74+ * a prefix that is an already recognized
 75+ * string
 76+ */
 77         i = FSM_HASPREFIX;
 78       }
 79       list = &(l->s_match);
 80@@ -68,7 +68,7 @@ addtomach(char *s, int cnt, struct state **list)
 81 }
 82 
 83 /*
 84- * Add a string to the FSM.
 85+ * add a string to the FSM
 86  */
 87 
 88 int
 89@@ -81,26 +81,26 @@ addstring(char *s, int cnt, struct state **machine)
 90 }
 91 
 92 /*
 93- * Match string s with the finite state machine.
 94- * If it matches, the number of characters actually matched is returned,
 95- * and the count is put in the word pointed to by i.
 96- * If the string is a prefix of a string that could be matched,
 97- * FSM_ISPREFIX is returned. Otherwise, 0 is returned.
 98+ * match string s with the finite state machine
 99+ * if it matches, the number of characters actually matched is returned,
100+ * and the count is put in the word pointed to by i
101+ * if the string is a prefix of a string that could be matched,
102+ * FSM_ISPREFIX is returned. otherwise, 0 is returned
103  */
104 
105 int
106 match(char *s, int *i, struct state *mach)
107 {
108-  char         *s1    = s; /* Walk through string */
109+  char         *s1    = s; /* walk through string */
110   struct state *mach1 = 0;
111-  /* Keep track of previous state */
112+  /* keep track of previous state */
113 
114   while (mach && *s1) {
115     if (mach->s_char == *s1) {
116       /*
117-       * Current character matches. Carry on with next
118-       * character and next state
119-       */
120+ * current character matches. carry on with next
121+ * character and next state
122+ */
123       mach1 = mach;
124       mach  = mach->s_match;
125       s1++;
126@@ -110,21 +110,21 @@ match(char *s, int *i, struct state *mach)
127   }
128   if (!mach1) {
129     /*
130-     * No characters matched
131-     */
132+ * no characters matched
133+ */
134     return 0;
135   }
136   if (mach1->s_endstate) {
137     /*
138-     * The string matched
139-     */
140+ * the string matched
141+ */
142     *i = mach1->s_cnt;
143     return s1 - s;
144   }
145   if (!*s1) {
146     /*
147-     * The string matched a prefix
148-     */
149+ * the string matched a prefix
150+ */
151     return FSM_ISPREFIX;
152   }
153   return 0;
+26, -26
  1@@ -1,4 +1,4 @@
  2-/* Copyright (c) 1985 Ceriel J.H. Jacobs */
  3+/* copyright (c) 1985 ceriel J.H. jacobs */
  4 
  5 #include "main.h"
  6 #include "commands.h"
  7@@ -53,12 +53,12 @@ main(int argc, char **argv)
  8 }
  9 
 10 /*
 11- * Open temporary file for reading and writing.
 12- * Panic if it fails
 13+ * open temporary file for reading and writing
 14+ * panic if it fails
 15  */
 16 
 17 /*
 18- * Collect initializing stuff here.
 19+ * collect initializing stuff here
 20  */
 21 
 22 static int
 23@@ -66,17 +66,17 @@ initialize(int x)
 24 {
 25   if (!(nopipe = x)) {
 26     /*
 27-     * Reading from pipe
 28-     */
 29+ * reading from pipe
 30+ */
 31     if (isatty(0)) {
 32       return 1;
 33     }
 34-    stdf = dup(0); /* Duplicate file descriptor of input */
 35+    stdf = dup(0); /* duplicate file descriptor of input */
 36     if (no_tty)
 37       return 0;
 38     /*
 39-     * Make sure standard input is from the terminal.
 40-     */
 41+ * make sure standard input is from the terminal
 42+ */
 43     (void)close(0);
 44     if (open("/dev/tty", O_RDONLY, 0) != 0) {
 45       putline("Couldn't open terminal\n");
 46@@ -87,9 +87,9 @@ initialize(int x)
 47   if (no_tty)
 48     return 0;
 49   /*
 50-   * Handle signals.
 51-   * Catch QUIT, DELETE and ^Z
 52-   */
 53+ * handle signals
 54+ * catch QUIT, DELETE and ^z
 55+ */
 56   (void)signal(SIGQUIT, SIG_IGN);
 57   (void)signal(SIGINT, catchdel);
 58   ini_terminal();
 59@@ -120,8 +120,8 @@ sigquit(int signo)
 60 #ifdef SIGTSTP
 61 
 62 /*
 63- * We had a SIGTSTP signal.
 64- * Suspend, by a call to this routine.
 65+ * we had a SIGTSTP signal
 66+ * suspend, by a call to this routine
 67  */
 68 
 69 void
 70@@ -132,12 +132,12 @@ suspend()
 71   (void)signal(SIGTSTP, SIG_DFL);
 72   (void)kill(0, SIGTSTP);
 73   /*
 74-   * We are not here anymore ...
 75-   *
 76-
 77-   *
 78-   * But we arive here ...
 79-   */
 80+ * we are not here anymore ...
 81+ *
 82+ *
 83+ *
 84+ * but we arive here ...
 85+ */
 86   inittty();
 87   putline(TI);
 88   flush();
 89@@ -145,8 +145,8 @@ suspend()
 90 }
 91 
 92 /*
 93- * SIGTSTP signal handler.
 94- * Just indicate that we had one, ignore further ones and return.
 95+ * SIGTSTP signal handler
 96+ * just indicate that we had one, ignore further ones and return
 97  */
 98 
 99 static void
100@@ -161,8 +161,8 @@ suspsig(int signo)
101 #endif
102 
103 /*
104- * quit : called on exit.
105- * I bet you guessed that much.
106+ * quit : called on exit
107+ * i bet you guessed that much
108  */
109 
110 int
111@@ -175,8 +175,8 @@ quit()
112 }
113 
114 /*
115- * Exit, but nonvoluntarily.
116- * At least tell the user why.
117+ * exit, but nonvoluntarily
118+ * at least tell the user why
119  */
120 
121 void
+9, -9
 1@@ -1,4 +1,4 @@
 2-/* Copyright (c) 1985 Ceriel J.H. Jacobs */
 3+/* copyright (c) 1985 ceriel J.H. jacobs */
 4 
 5 #include "options.h"
 6 #include "display.h"
 7@@ -15,8 +15,8 @@ char *startcomm;
 8 static int parsopt(char *s);
 9 
10 /*
11- * Read the options. Return the argv pointer following them if there were
12- * no errors, otherwise return 0.
13+ * read the options. return the argv pointer following them if there were
14+ * no errors, otherwise return 0
15  */
16 
17 char **
18@@ -31,8 +31,8 @@ readoptions(char **argv)
19   while (*av && **av == '-') {
20     if (parsopt(*av)) {
21       /*
22-       * Error in option
23-       */
24+ * error in option
25+ */
26       putline(*av);
27       putline(": illegal option\n");
28       return (char **)0;
29@@ -41,8 +41,8 @@ readoptions(char **argv)
30   }
31   if (*av && **av == '+') {
32     /*
33-     * Command in command line
34-     */
35+ * command in command line
36+ */
37     startcomm = *av + 1;
38     av++;
39   }
40@@ -58,8 +58,8 @@ parsopt(char *s)
41     s++;
42   if (isdigit(*s)) {
43     /*
44-     * pagesize option
45-     */
46+ * pagesize option
47+ */
48     i = 0;
49     do {
50       i = i * 10 + *s++ - '0';
+7, -7
 1@@ -1,7 +1,7 @@
 2-/* Copyright (c) 1985 Ceriel J.H. Jacobs */
 3+/* copyright (c) 1985 ceriel J.H. jacobs */
 4 
 5 /*
 6- * Handle output to screen
 7+ * handle output to screen
 8  */
 9 
10 #include "output.h"
11@@ -17,7 +17,7 @@ static char _outbuf[OBUFSIZ];
12 
13 void
14 flush()
15-{ /* Flush output buffer, by writing it */
16+{ /* flush output buffer, by writing it */
17   char *p = _outbuf;
18 
19   _ocnt = OBUFSIZ;
20@@ -28,7 +28,7 @@ flush()
21 
22 void
23 nflush()
24-{ /* Flush output buffer, ignoring it */
25+{ /* flush output buffer, ignoring it */
26 
27   _ocnt = OBUFSIZ;
28   _optr = _outbuf;
29@@ -43,7 +43,7 @@ fputch(int ch)
30 
31 void
32 putline(char *s)
33-{ /* Print string s */
34+{ /* print string s */
35 
36   if (!s)
37     return;
38@@ -53,7 +53,7 @@ putline(char *s)
39 }
40 
41 /*
42- * A safe version of putline. All control characters are echoed as ^X
43+ * a safe version of putline. all control characters are echoed as ^x
44  */
45 
46 void
47@@ -71,7 +71,7 @@ cputline(char *s)
48 }
49 
50 /*
51- * Simple minded routine to print a number
52+ * simple minded routine to print a number
53  */
54 
55 void
+1, -1
1@@ -3,7 +3,7 @@
2 #include <regex.h>
3 
4 /*
5- * Interface to POSIX regular expression routines.
6+ * interface to POSIX regular expression routines
7  */
8 
9 static regex_t pattern;
+13, -13
 1@@ -1,4 +1,4 @@
 2-/* Copyright (c) 1985 Ceriel J.H. Jacobs */
 3+/* copyright (c) 1985 ceriel J.H. jacobs */
 4 
 5 #include "process.h"
 6 #include "commands.h"
 7@@ -19,10 +19,10 @@ char  **filenames;
 8 char   *currentfile;
 9 long    maxpos;
10 
11-static int nfiles; /* Number of filenames on command line */
12+static int nfiles; /* number of filenames on command line */
13 
14 /*
15- * Visit a file, file name is "fn".
16+ * visit a file, file name is "fn"
17  */
18 
19 void
20@@ -32,15 +32,15 @@ visitfile(char *fn)
21 
22   if (stdf > 0) {
23     /*
24-     * Close old input file
25-     */
26+ * close old input file
27+ */
28     (void)close(stdf);
29   }
30   currentfile = fn;
31   if ((stdf = open(fn, O_RDONLY, 0)) < 0) {
32     error(": could not open");
33     maxpos = 0;
34-  } else { /* Get size for percentage in prompt */
35+  } else { /* get size for percentage in prompt */
36     (void)fstat(stdf, &statbuf);
37     maxpos = statbuf.st_size;
38   }
39@@ -49,8 +49,8 @@ visitfile(char *fn)
40 }
41 
42 /*
43- * process the input files, one by one.
44- * If there is none, input is from a pipe.
45+ * process the input files, one by one
46+ * if there is none, input is from a pipe
47  */
48 
49 void
50@@ -61,12 +61,12 @@ processfiles(int n, char **argv)
51 
52   if (!(nfiles = n)) {
53     /*
54-     * Input from pipe
55-     */
56+ * input from pipe
57+ */
58     currentfile = "standard-input";
59     /*
60-     * Take care that *(filenames - 1) and *(filenames + 1) are 0
61-     */
62+ * take care that *(filenames - 1) and *(filenames + 1) are 0
63+ */
64     filenames = &dummies[1];
65     d_clean();
66     do_clean();
67@@ -97,7 +97,7 @@ processfiles(int n, char **argv)
68 }
69 
70 /*
71- * Get the next file the user asks for.
72+ * get the next file the user asks for
73  */
74 
75 int
+12, -12
 1@@ -1,4 +1,4 @@
 2-/* Copyright (c) 1985 Ceriel J.H. Jacobs */
 3+/* copyright (c) 1985 ceriel J.H. jacobs */
 4 
 5 #include "prompt.h"
 6 #include "assert.h"
 7@@ -15,7 +15,7 @@
 8 #include "process.h"
 9 #include "term.h"
10 
11-static char *errorgiven; /* Set to error message, if there is one */
12+static char *errorgiven; /* set to error message, if there is one */
13 
14 static char *display_basename(char *path, char *scratch, size_t scratch_size);
15 
16@@ -29,7 +29,7 @@ copy(char *p, const char *ep, char *s)
17 }
18 
19 /*
20- * display the prompt and refresh the screen.
21+ * display the prompt and refresh the screen
22  */
23 
24 void
25@@ -50,8 +50,8 @@ give_prompt()
26   }
27   if (!stupid) {
28     /*
29-     * fancy prompt
30-     */
31+ * fancy prompt
32+ */
33     clrbline();
34     standout();
35     pb = copy(pb, &buf[255], display_basename(currentfile, filebuf, sizeof(filebuf)));
36@@ -62,12 +62,12 @@ give_prompt()
37       pb = copy(pb, &buf[255], getnum(p->lastline));
38     }
39   } else {
40-    *pb++ = '\007'; /* Stupid terminal, stupid prompt */
41+    *pb++ = '\007'; /* stupid terminal, stupid prompt */
42   }
43   if (errorgiven) {
44     /*
45-     * display error message
46-     */
47+ * display error message
48+ */
49     pb = copy(pb, &buf[255], " ");
50     pb = copy(pb, &buf[255], errorgiven);
51     if (stupid) {
52@@ -79,8 +79,8 @@ give_prompt()
53     name = &filenames[filecount];
54     if (status) {
55       /*
56-       * indicate top and/or bottom
57-       */
58+ * indicate top and/or bottom
59+ */
60       if (status & START) {
61         if (!*(name - 1)) {
62           pb = copy(pb, &buf[255], "Top");
63@@ -130,7 +130,7 @@ display_basename(char *path, char *scratch, size_t scratch_size)
64 }
65 
66 /*
67- * Remember error message
68+ * remember error message
69  */
70 
71 void
72@@ -141,7 +141,7 @@ error(char *str)
73 
74 void
75 ret_to_continue()
76-{ /* Obvious */
77+{ /* obvious */
78   int         c;
79   static char buf[2];
80 
+36, -36
  1@@ -1,7 +1,7 @@
  2-/* Copyright (c) 1985 Ceriel J.H. Jacobs */
  3+/* copyright (c) 1985 ceriel J.H. jacobs */
  4 
  5 /*
  6- * Terminal handling routines, mostly initializing.
  7+ * terminal handling routines, mostly initializing
  8  */
  9 
 10 #include "term.h"
 11@@ -53,8 +53,8 @@ handle(cc_t *c)
 12 }
 13 
 14 /*
 15- * Set terminal in cbreak mode.
 16- * Also check if tabs need expanding.
 17+ * set terminal in cbreak mode
 18+ * also check if tabs need expanding
 19  */
 20 
 21 void
 22@@ -72,7 +72,7 @@ inittty()
 23   handle(&p->c_cc[VQUIT]);
 24   erasech        = p->c_cc[VERASE];
 25   killch         = p->c_cc[VKILL];
 26-  p->c_cc[VMIN]  = 1; /* Just wait for one character */
 27+  p->c_cc[VMIN]  = 1; /* just wait for one character */
 28   p->c_cc[VTIME] = 0;
 29   tcsetattr(0, TCSANOW, p);
 30 }
 31@@ -150,7 +150,7 @@ givetab()
 32 }
 33 
 34 /*
 35- * Reset the terminal to its original state
 36+ * reset the terminal to its original state
 37  */
 38 
 39 void
 40@@ -162,8 +162,8 @@ resettty()
 41 }
 42 
 43 /*
 44- * Get string terminal capability "cap".
 45- * If not present, return an empty string.
 46+ * get string terminal capability "cap"
 47+ * if not present, return an empty string
 48  */
 49 
 50 static char *
 51@@ -196,7 +196,7 @@ getnumcap(char *cap)
 52 }
 53 
 54 /*
 55- * Initialize some terminal-dependent stuff.
 56+ * initialize some terminal-dependent stuff
 57  */
 58 
 59 void
 60@@ -225,11 +225,11 @@ ini_terminal()
 61     panic("No terminfo entry");
 62   }
 63   stupid   = 0;
 64-  hardcopy = getflag("hc"); /* Hard copy terminal?*/
 65+  hardcopy = getflag("hc"); /* hard copy terminal? */
 66   if (*(s = getcap("cub1"))) {
 67     /*
 68-     * Backspace if not ^H
 69-     */
 70+ * backspace if not ^h
 71+ */
 72     BC = s;
 73   }
 74   UP = getcap("cuu1");  /* move up a line */
 75@@ -237,11 +237,11 @@ ini_terminal()
 76   CL = getcap("clear"); /* clear screen */
 77   if (!*CL)
 78     cflag = 1;
 79-  TI = getcap("smcup");  /* Initialization for CM */
 80+  TI = getcap("smcup");  /* initialization for CM */
 81   TE = getcap("rmcup");  /* end for CM */
 82   CM = getcap("cup");    /* cursor addressing */
 83   SR = getcap("ri");     /* scroll reverse */
 84-  AL = getcap("il");     /* Insert line */
 85+  AL = getcap("il");     /* insert line */
 86   SO = getcap("smso");   /* standout */
 87   SE = getcap("rmso");   /* standend */
 88   SG = getnumcap("xmc"); /* blanks left by attributes */
 89@@ -260,8 +260,8 @@ ini_terminal()
 90   mr = getcap("rev");   /* reversed video attribute */
 91   if (!nflag) {
 92     /*
 93-     * Recognize special strings
 94-     */
 95+ * recognize special strings
 96+ */
 97     (void)addstring(SO, SG, &sppat);
 98     (void)addstring(SE, SG, &sppat);
 99     (void)addstring(US, UG, &sppat);
100@@ -284,27 +284,27 @@ ini_terminal()
101   if (*US || uflag)
102     UC = "";
103   COLS = getnumcap("cols");  /* columns on page */
104-  i    = getnumcap("lines"); /* Lines on page */
105+  i    = getnumcap("lines"); /* lines on page */
106   AM   = getflag("am");      /* terminal wraps automatically? */
107   XN   = getflag("xenl");    /* and then ignores next newline? */
108   DB   = getflag("db");      /* terminal retains lines below */
109   HO   = getcap("home");
110   if (!*HO && *CM) {
111-    HO = tiparm(CM, 0, 0); /* Another way of getting home */
112+    HO = tiparm(CM, 0, 0); /* another way of getting home */
113   }
114   if ((!*CE && !*AL) || !*HO || hardcopy) {
115     cflag = stupid = 1;
116   }
117   if (*(s = getcap("ht"))) {
118     /*
119-     * Tab (other than ^I or padding)
120-     */
121+ * tab (other than ^i or padding)
122+ */
123     TA = s;
124   }
125   if (!*(ll = getcap("ll")) && *CM && i > 0) {
126     /*
127-     * Lower left hand corner
128-     */
129+ * lower left hand corner
130+ */
131     BO = tiparm(CM, i - 1, 0);
132   } else
133     BO = ll;
134@@ -331,16 +331,16 @@ ini_terminal()
135   }
136 
137   /*
138-   * The next part does not really belong here, but there it is ...
139-   * Initialize a circular list for the screenlines.
140-   */
141+ * the next part does not really belong here, but there it is ...
142+ * initialize a circular list for the screenlines
143+ */
144 
145   scr_info.tail = lp = _X;
146   lp1                = lp + (100 - 1);
147   for (; lp <= lp1; lp++) {
148     /*
149-     * Circular doubly linked list
150-     */
151+ * circular doubly linked list
152+ */
153     lp->next = lp + 1;
154     lp->prev = lp - 1;
155   }
156@@ -354,7 +354,7 @@ ini_terminal()
157 }
158 
159 /*
160- * Place cursor at start of line n.
161+ * place cursor at start of line n
162  */
163 
164 void
165@@ -366,17 +366,17 @@ mgoto(int n)
166     bottom();
167   else if (*CM) {
168     /*
169-     * Cursor addressing
170-     */
171+ * cursor addressing
172+ */
173     tputs(tiparm(CM, n, 0), 1, fputch);
174   } else if (*BO && *UP && n >= (maxpagesize >> 1)) {
175     /*
176-     * Bottom and then up
177-     */
178+ * bottom and then up
179+ */
180     bottom();
181     while (n++ < maxpagesize)
182       putline(UP);
183-  } else { /* Home, and then down */
184+  } else { /* home, and then down */
185     home();
186     while (n--)
187       putline("\r\n");
188@@ -384,7 +384,7 @@ mgoto(int n)
189 }
190 
191 /*
192- * Clear bottom line
193+ * clear bottom line
194  */
195 
196 void
197@@ -397,8 +397,8 @@ clrbline()
198   bottom();
199   if (*CE) {
200     /*
201-     * We can clear to end of line
202-     */
203+ * we can clear to end of line
204+ */
205     clrtoeol();
206     return;
207   }
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/ioctl.h>
6 #include <sys/mount.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/ioctl.h>
6 #include <sys/types.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/syscall.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/ioctl.h>
6 #include <sys/stat.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/ioctl.h>
6 #include <sys/mount.h>
+3, -3
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <sys/ioctl.h>
 6 #include <sys/stat.h>
 7@@ -11,8 +11,8 @@
 8 
 9 #include "util.h"
10 
11-#define FIFREEZE _IOWR('X', 119, int) /* Freeze */
12-#define FITHAW   _IOWR('X', 120, int) /* Thaw */
13+#define FIFREEZE _IOWR('X', 119, int) /* freeze */
14+#define FITHAW   _IOWR('X', 120, int) /* thaw */
15 
16 static void
17 usage(void)
+2, -2
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <sys/ioctl.h>
 6 #include <sys/stat.h>
 7@@ -155,7 +155,7 @@ main(int argc, char *argv[])
 8   if ((rflag ^ sflag ^ wflag) == 0)
 9     eprintf("missing or incompatible function\n");
10 
11-  /* Only UTC support at the moment */
12+  /* only UTC support at the moment */
13   setenv("TZ", "UTC0", 1);
14   tzset();
15 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <limits.h>
6 #include <stdio.h>
+3, -3
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <sys/stat.h>
 6 
 7@@ -73,7 +73,7 @@ main(int argc, char *argv[])
 8   if (pages < SWAP_MIN_PAGES)
 9     eprintf("swap space needs to be at least %ldKiB\n", SWAP_MIN_PAGES * pagesize / 1024);
10 
11-  /* Fill up the swap header */
12+  /* fill up the swap header */
13   hdr            = (struct swap_hdr *)buf;
14   hdr->version   = 1;
15   hdr->last_page = pages - 1;
16@@ -81,7 +81,7 @@ main(int argc, char *argv[])
17 
18   printf("Setting up swapspace version 1, size = %luKiB\n", (pages - 1) * pagesize / 1024);
19 
20-  /* Write out the signature page */
21+  /* write out the signature page */
22   if (write(fd, buf, pagesize) != pagesize)
23     eprintf("unable to write signature page\n");
24 
+20, -20
  1@@ -541,11 +541,11 @@ usage(void)
  2 
  3 // ?man modprobe: add or remove modules from the Linux kernel
  4 // ?man arguments: module [symbol=value ...]
  5-// ?man modprobe loads or removes kernel modules from the running system.
  6+// ?man modprobe loads or removes kernel modules from the running system
  7 // ?man It reads modules.dep, modules.alias, and modules.symbols from the
  8 // appropriate ?man /lib/modules/release directory to resolve module names and
  9-// dependencies, ?man loading prerequisites first. ?man Without -r, modprobe
 10-// loads the named module (and any required dependencies) ?man into the kernel.
 11+// dependencies, ?man loading prerequisites first. ?man without -r, modprobe
 12+// loads the named module (and any required dependencies) ?man into the kernel
 13 int
 14 main(int argc, char *argv[])
 15 {
 16@@ -559,36 +559,36 @@ main(int argc, char *argv[])
 17     // ?man -a: specify a option
 18     case 'a':
 19       // ?man -a: Load all modules named on the command line (rather
 20-      // than stopping after the first).
 21+      // than stopping after the first)
 22       aflag = 1;
 23       break;
 24     // ?man -r: specify r option
 25     case 'r':
 26-      // ?man -r: Remove the named modules from the kernel.
 27-      // Dependencies are not automatically removed.
 28+      // ?man -r: Remove the named modules from the kernel
 29+      // dependencies are not automatically removed
 30       rflag = 1;
 31       break;
 32     // ?man -q: specify q option
 33     case 'q':
 34-      // ?man -q: Quiet mode.  Suppress error messages.
 35+      // ?man -q: Quiet mode.  Suppress error messages
 36       qflag = 1;
 37       break;
 38     // ?man -v: specify v option
 39     case 'v':
 40-      // ?man -v: Verbose mode.  Print each action taken.
 41+      // ?man -v: Verbose mode.  Print each action taken
 42       vflag = 1;
 43       break;
 44     // ?man -l: specify l option
 45     case 'l':
 46       // ?man -l: List available modules matching the optional
 47-      // _pattern_ (a fnmatch(3) glob).
 48+      // _pattern_ (a fnmatch(3) glob)
 49       lflag = 1;
 50       break;
 51 #if FEATURE_MODPROBE_SHOW_DEPENDS
 52     // ?man -D: specify D option
 53     case 'D':
 54       // ?man -D: Print the sequence of insmod commands that would be
 55-      // used to load the module, without actually loading anything.
 56+      // used to load the module, without actually loading anything
 57       Dflag = 1;
 58       break;
 59 #endif
 60@@ -596,7 +596,7 @@ main(int argc, char *argv[])
 61     // ?man -b: specify b option
 62     case 'b':
 63       // ?man -b: Skip modules listed as blacklist in
 64-      // /etc/modprobe.d/.
 65+      // /etc/modprobe.d/
 66       bflag = 1;
 67       break;
 68 #endif
 69@@ -604,7 +604,7 @@ main(int argc, char *argv[])
 70     // ?man -s: specify s option
 71     case 's':
 72       // ?man -s: Log messages to syslog(3) (facility LOG_DAEMON)
 73-      // instead of standard error.
 74+      // instead of standard error
 75       sflag = 1;
 76       break;
 77 #endif
 78@@ -612,7 +612,7 @@ main(int argc, char *argv[])
 79     // ?man -d:file: specify d option
 80     case 'd':
 81       // ?man -d dir: Use dir as the base directory for module files
 82-      // instead of /lib/modules/release.
 83+      // instead of /lib/modules/release
 84       strlist_append(&moddirs, EARGF(usage()));
 85       break;
 86 #endif
 87@@ -640,7 +640,7 @@ main(int argc, char *argv[])
 88   read_configs();
 89 
 90   /* traverse all provided or default base directories for symbol, alias,
 91-   * and dependency tracking */
 92+ * and dependency tracking */
 93   for (pn = moddirs; pn; pn = pn->next) {
 94     if (chdir(pn->str) < 0) {
 95       pr_warn("chdir %s:", pn->str);
 96@@ -691,24 +691,24 @@ end:
 97   // ?man ## FILES
 98   // ?man
 99   // ?man `/etc/modprobe.conf`
100-  // ?man : Global configuration file.
101+  // ?man : Global configuration file
102   // ?man
103   // ?man Files under `/etc/modprobe.d/`
104-  // ?man : Per-module configuration snippets.
105+  // ?man : Per-module configuration snippets
106   // ?man
107   // ?man `/lib/modules/`_release_`/modules.dep`
108-  // ?man : Module dependency map generated by `depmod(8)`.
109+  // ?man : Module dependency map generated by `depmod(8)`
110   // ?man
111   // ?man ## EXIT STATUS
112   // ?man
113   // ?man 0
114-  // ?man : Success.
115+  // ?man : Success
116   // ?man
117   // ?man 1
118-  // ?man : Module not found or kernel rejected the operation.
119+  // ?man : Module not found or kernel rejected the operation
120   // ?man
121   // ?man 2
122-  // ?man : I/O error on stdout or stdin.
123+  // ?man : I/O error on stdout or stdin
124   // ?man
125   // ?man ## SEE ALSO
126   // ?man
+3, -3
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <sys/mount.h>
 6 #include <sys/stat.h>
 7@@ -322,8 +322,8 @@ mountall:
 8     }
 9     parseopts(fsopts, &flags, data, sizeof(data));
10     /* if -t types specified:
11-     * if non-match, skip
12-     * if match and prefixed with "no", skip */
13+ * if non-match, skip
14+ * if match and prefixed with "no", skip */
15     if (types
16         && ((types[0] == 'n' && types[1] == 'o' && findtype(types + 2, me->mnt_type))
17             || (!findtype(types, me->mnt_type))))
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/stat.h>
6 #include <sys/sysmacros.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/syscall.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <fcntl.h>
6 #include <limits.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/types.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/swap.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/swap.h>
6 
+3, -3
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <sys/mount.h>
 6 #include <sys/stat.h>
 7@@ -25,7 +25,7 @@ delete_content(const char *dir, dev_t curdevice)
 8   struct stat    st;
 9   struct dirent *dent;
10 
11-  /* don't dive into other filesystems */
12+  /* dont dive into other filesystems */
13   if (lstat(dir, &st) < 0 || st.st_dev != curdevice)
14     return;
15   if (!(d = opendir(dir)))
16@@ -90,7 +90,7 @@ main(int argc, char *argv[])
17   if (argc != 2 || getpid() != 1)
18     usage();
19 
20-  /* chdir to newroot and make sure it's a different fs */
21+  /* chdir to newroot and make sure its a different fs */
22   if (chdir(argv[0]))
23     eprintf("chdir %s:", argv[0]);
24 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <fcntl.h>
6 #include <limits.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/ioctl.h>
6 #include <sys/socket.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/mount.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sched.h>
6 #include <stdio.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/ioctl.h>
6 #include <sys/stat.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include "arg.h"
6 #include "util.h"
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include "arg.h"
6 #include "util.h"
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <arpa/inet.h>
6 #include <ctype.h>
+17, -5
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <arpa/inet.h>
 6 #include <ctype.h>
 7@@ -41,6 +41,16 @@ usage(void)
 8   eprintf("usage: %s [addr | link | route] [args...]\n", argv0);
 9 }
10 
11+/* real ip(8) and BusyBox's own ip applet both accept any unambiguous
12+ * prefix of an object name (ip a, ip li, ip ro, ...), not just the
13+ * full word: obj matches full whenever it is a real, non-empty prefix */
14+static int
15+is_object(const char *obj, const char *full)
16+{
17+  size_t len = strlen(obj);
18+  return len > 0 && len <= strlen(full) && strncmp(obj, full, len) == 0;
19+}
20+
21 static void
22 parse_mac(const char *str, unsigned char mac[6])
23 {
24@@ -369,7 +379,9 @@ do_route(int argc, char *argv[])
25 
26 // ?man ip: show or configure routing and devices
27 // ?man arguments: [addr | link | route] [args ...]
28-// ?man configure and view network devices, routing, and tunnels
29+// ?man configure and view network devices, routing, and tunnels. any
30+// ?man unambiguous prefix of an object name works too (a, addr, l,
31+// ?man link, r, route)
32 // ?man ## COMMANDS
33 // ?man ### addr [show | list [dev <device>]]
34 // ?man show interface addresses
35@@ -405,11 +417,11 @@ main(int argc, char *argv[])
36 
37   obj = argv[0];
38 
39-  if (strcmp(obj, "addr") == 0 || strcmp(obj, "address") == 0) {
40+  if (is_object(obj, "address")) {
41     return do_addr(argc - 1, argv + 1);
42-  } else if (strcmp(obj, "link") == 0) {
43+  } else if (is_object(obj, "link")) {
44     return do_link(argc - 1, argv + 1);
45-  } else if (strcmp(obj, "route") == 0) {
46+  } else if (is_object(obj, "route")) {
47     return do_route(argc - 1, argv + 1);
48   }
49 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/socket.h>
6 #include <sys/types.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include "arg.h"
6 #include "util.h"
+4, -4
 1@@ -1,5 +1,5 @@
 2 /* sdhcp: simple DHCP client, ported from git.2f30.org/sdhcp */
 3-/* See LICENSE file for copyright and license details */
 4+/* see LICENSE file for copyright and license details */
 5 #include "arg.h"
 6 #include "util.h"
 7 #include "wexec.h"
 8@@ -70,7 +70,7 @@ enum {
 9   OB_DNSSERVER  = 6,
10   OB_HOSTNAME   = 12,
11   OB_BADDR      = 28,
12-  /* DHCP-specific options */
13+  /* dhcp-specific options */
14   OD_IPADDR        = 50, /* 0x32 */
15   OD_LEASE         = 51,
16   OD_OVERLOAD      = 52,
17@@ -542,7 +542,7 @@ main(int argc, char *argv[])
18 
19   ARGBEGIN
20   {
21-    case 'd': /* don't update /etc/resolv.conf */
22+    case 'd': /* dont update /etc/resolv.conf */
23       dflag = 0;
24       break;
25     case 'e': /* exec program on each lease */
26@@ -551,7 +551,7 @@ main(int argc, char *argv[])
27     case 'f': /* stay in foreground */
28       fflag = 1;
29       break;
30-    case 'i': /* don't configure IP address */
31+    case 'i': /* dont configure IP address */
32       iflag = 0;
33       break;
34     default:
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/socket.h>
6 #include <sys/time.h>
+33, -13
  1@@ -8,6 +8,7 @@
  2 #include <ctype.h>
  3 #include <errno.h>
  4 #include <fcntl.h>
  5+#include <limits.h>
  6 #include <netdb.h>
  7 #include <netinet/in.h>
  8 #include <stdio.h>
  9@@ -31,6 +32,7 @@ static int    cflag                = 0;
 10 static int    spider               = 0;
 11 static int    no_check_certificate = 0;
 12 static int    timeout_sec          = 900;
 13+static int    tries                = 20;
 14 static char  *Pflag                = NULL;
 15 static char  *Oflag                = NULL;
 16 static char  *user_agent           = "wget/aruu";
 17@@ -43,7 +45,7 @@ static void
 18 usage(void)
 19 {
 20   eprintf(
 21-      "usage: %s [-cqS] [-O file] [-P dir] [-T timeout] [-U "
 22+      "usage: %s [-cqS] [-O file] [-P dir] [-T timeout] [-t tries] [-U "
 23       "user_agent] "
 24       "[-post-data data] [-post-file file] [-header header] "
 25       "[-no-check-certificate] [-spider] url\n",
 26@@ -102,9 +104,9 @@ parse_url(char *url, char **host, char **port, char **path, int *is_tls)
 27   char *p, *ss;
 28 
 29   *is_tls = 0;
 30-  if (strncasecmp(url, "http://", 7) == 0) {
 31+  if (strncasecmp(url, "http:// ", 7) == 0) {
 32     url += 7;
 33-  } else if (strncasecmp(url, "https://", 8) == 0) {
 34+  } else if (strncasecmp(url, "https:// ", 8) == 0) {
 35     url += 8;
 36     *is_tls = 1;
 37   } else {
 38@@ -334,6 +336,8 @@ main(int argc, char *argv[])
 39   long long         post_len      = 0;
 40   int               post_fd       = -1;
 41   size_t            i;
 42+  int               attempt;
 43+  int               max_tries;
 44 
 45   ARGBEGIN
 46   {
 47@@ -349,6 +353,10 @@ main(int argc, char *argv[])
 48     case 'T':
 49       timeout_sec = estrtonum(EARGF(usage()), 0, 100000);
 50       break;
 51+    // ?man -t:num: set number of connection retries, 0 retries forever
 52+    case 't':
 53+      tries = estrtonum(EARGF(usage()), 0, 1000000);
 54+      break;
 55     // ?man -U:str: set User-Agent header
 56     case 'U':
 57       user_agent = EARGF(usage());
 58@@ -454,6 +462,9 @@ main(int argc, char *argv[])
 59     post_len = st.st_size;
 60   }
 61 
 62+  /* wgets own -t: 0 means retry forever */
 63+  max_tries = tries == 0 ? INT_MAX : tries;
 64+
 65   while (!tls_sock) {
 66     if (redirects > max_redirects)
 67       eprintf("too many redirects\n");
 68@@ -465,14 +476,23 @@ main(int argc, char *argv[])
 69     port = estrdup(curr_port);
 70     path = estrdup(curr_path);
 71 
 72-    sock_fd = dial(host, port);
 73-    if (sock_fd < 0)
 74-      eprintf("failed to connect to %s:%s\n", host, port);
 75+    for (attempt = 1; attempt <= max_tries; attempt++) {
 76+      sock_fd = dial(host, port);
 77+      if (sock_fd < 0) {
 78+        if (attempt == max_tries)
 79+          eprintf("failed to connect to %s:%s\n", host, port);
 80+        continue;
 81+      }
 82+
 83+      tls_sock = tlss_connect(sock_fd, host, !no_check_certificate, is_tls);
 84+      if (!tls_sock) {
 85+        close(sock_fd);
 86+        if (attempt == max_tries)
 87+          eprintf("failed to establish TLS connection with %s\n", host);
 88+        continue;
 89+      }
 90 
 91-    tls_sock = tlss_connect(sock_fd, host, !no_check_certificate, is_tls);
 92-    if (!tls_sock) {
 93-      close(sock_fd);
 94-      eprintf("failed to establish TLS connection with %s\n", host);
 95+      break;
 96     }
 97 
 98     /* send http request */
 99@@ -572,18 +592,18 @@ main(int argc, char *argv[])
100             "header\n"
101         );
102 
103-      if (strncasecmp(loc, "http://", 7) == 0 || strncasecmp(loc, "https://", 8) == 0) {
104+      if (strncasecmp(loc, "http:// ", 7) == 0 || strncasecmp(loc, "https://", 8) == 0) {
105         new_url = estrdup(loc);
106       } else if (loc[0] == '/') {
107         new_url = emalloc(8 + strlen(host) + strlen(port) + strlen(loc) + 2);
108-        sprintf(new_url, "%s://%s:%s%s", is_tls ? "https" : "http", host, port, loc);
109+        sprintf(new_url, "%s:// %s:%s%s", is_tls ? "https" : "http", host, port, loc);
110       } else {
111         last_slash = strrchr(path, '/');
112         dir_len    = 0;
113         if (last_slash)
114           dir_len = last_slash - path + 1;
115         new_url = emalloc(8 + strlen(host) + strlen(port) + 1 + dir_len + strlen(loc) + 2);
116-        sprintf(new_url, "%s://%s:%s/", is_tls ? "https" : "http", host, port);
117+        sprintf(new_url, "%s:// %s:%s/", is_tls ? "https" : "http", host, port);
118         if (dir_len > 0)
119           strncat(new_url, path, dir_len);
120         strcat(new_url, loc);
+39, -39
  1@@ -1,26 +1,26 @@
  2-/****************************************************************
  3-Copyright (C) Lucent Technologies 1997
  4-All Rights Reserved
  5-
  6-Permission to use, copy, modify, and distribute this software and
  7-its documentation for any purpose and without fee is hereby
  8-granted, provided that the above copyright notice appear in all
  9-copies and that both that the copyright notice and this
 10-permission notice and warranty disclaimer appear in supporting
 11-documentation, and that the name Lucent Technologies or any of
 12-its entities not be used in advertising or publicity pertaining
 13-to distribution of the software without specific, written prior
 14-permission.
 15-
 16-LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 17-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
 18-IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
 19-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 20-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 21-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 22-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 23-THIS SOFTWARE.
 24-****************************************************************/
 25+/* ***************************************************************
 26+ * copyright (c) lucent technologies 1997
 27+ * all rights reserved
 28+ *
 29+ * permission to use, copy, modify, and distribute this software and
 30+ * its documentation for any purpose and without fee is hereby
 31+ * granted, provided that the above copyright notice appear in all
 32+ * copies and that both that the copyright notice and this
 33+ * permission notice and warranty disclaimer appear in supporting
 34+ * documentation, and that the name lucent technologies or any of
 35+ * its entities not be used in advertising or publicity pertaining
 36+ * to distribution of the software without specific, written prior
 37+ * permission
 38+ *
 39+ * LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 40+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 41+ * IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
 42+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 43+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 44+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 45+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 46+ * THIS SOFTWARE
 47+ * ************************************************************** */
 48 
 49 #include <assert.h>
 50 #include <stddef.h>
 51@@ -40,7 +40,7 @@ THIS SOFTWARE.
 52 
 53 typedef double Awkfloat;
 54 
 55-/* unsigned char is more trouble than it's worth */
 56+/* unsigned char is more trouble than its worth */
 57 
 58 typedef unsigned char uschar;
 59 
 60@@ -50,14 +50,14 @@ typedef unsigned char uschar;
 61     (a) = NULL;                                                                                    \
 62   }
 63 /*
 64- * We sometimes cheat writing read-only pointers to NUL-terminate them
 65+ * we sometimes cheat writing read-only pointers to nul-terminate them
 66  * and then put back the original value
 67  */
 68 #define setptr(ptr, a) (*(char *)(intptr_t)(ptr)) = (a)
 69 
 70 #define NN(p)                                                                                      \
 71-  ((p) ? (p) : "(null)") /* guaranteed non-null for DPRINTF                                        \
 72-                          */
 73+  ((p) ? (p) : "(null)") /* guaranteed non-null for DPRINTF \
 74+ */
 75 #define DEBUG
 76 #ifdef DEBUG
 77 #define DPRINTF(...)                                                                               \
 78@@ -71,12 +71,12 @@ extern enum compile_states { RUNNING, COMPILING, ERROR_PRINTING } compile_time;
 79 
 80 extern bool safe; /* false => unsafe, true => safe */
 81 
 82-#define RECSIZE (8 * 1024) /* sets limit on records, fields, etc., etc. */
 83+#define RECSIZE (8 * 1024) /* sets limit on records, fields, etc., etc */
 84 extern int recsize;        /* size of current record, orig RECSIZE */
 85 
 86 extern size_t awk_mb_cur_max; /* max size of a multi-byte character */
 87 
 88-extern char      EMPTY[]; /* this avoid -Wwritable-strings issues */
 89+extern char      EMPTY[]; /* this avoid -wwritable-strings issues */
 90 extern char    **FS;
 91 extern char    **RS;
 92 extern char    **ORS;
 93@@ -100,13 +100,13 @@ extern bool  donerec;   /* true if record is valid (no fld has changed */
 94 extern int   dbg;
 95 
 96 extern const char *patbeg; /* beginning of pattern matched */
 97-extern int         patlen; /* length of pattern matched.  set in b.c */
 98+extern int         patlen; /* length of pattern matched. set in b.c */
 99 
100-/* Cell:  all information about a variable or constant */
101+/* cell: all information about a variable or constant */
102 
103 typedef struct Cell {
104-  uschar       ctype; /* OCELL, OBOOL, OJUMP, etc. */
105-  uschar       csub;  /* CCON, CTEMP, CFLD, etc. */
106+  uschar       ctype; /* OCELL, OBOOL, OJUMP, etc */
107+  uschar       csub;  /* CCON, CTEMP, CFLD, etc */
108   char        *nval;  /* name, for variables only */
109   char        *sval;  /* string value */
110   Awkfloat     fval;  /* value as number */
111@@ -136,7 +136,7 @@ extern Cell *rlengthloc; /* RLENGTH */
112 extern Cell *subseploc;  /* SUBSEP */
113 extern Cell *symtabloc;  /* SYMTAB */
114 
115-/* Cell.tval values: */
116+/* cell.tval values: */
117 #define NUM      01    /* number value is valid */
118 #define STR      02    /* string value is valid */
119 #define DONTFREE 04    /* string space is not freeable */
120@@ -164,7 +164,7 @@ extern Cell *symtabloc;  /* SYMTAB */
121 #define FTOLOWER 13
122 #define FFLUSH   14
123 
124-/* Node:  parse tree is made of nodes, with Cell's at bottom */
125+/* node: parse tree is made of nodes, with cell's at bottom */
126 
127 typedef struct Node {
128   int          ntype;
129@@ -184,7 +184,7 @@ extern Node *nullnode;
130 #define OBOOL 2
131 #define OJUMP 3
132 
133-/* Cell subtypes: csub */
134+/* cell subtypes: csub */
135 #define CFREE 7
136 #define CCOPY 6
137 #define CCON  5
138@@ -231,14 +231,14 @@ extern int pairstack[], paircnt;
139 #define istrue(n)     ((n)->csub == BTRUE)
140 #define istemp(n)     ((n)->csub == CTEMP)
141 #define isargument(n) ((n)->nobj == ARG)
142-/* #define freeable(p)	(!((p)->tval & DONTFREE)) */
143+/* #define freeable(p) (!((p)->tval & DONTFREE)) */
144 #define freeable(p) (((p)->tval & (STR | DONTFREE)) == STR)
145 
146 /* structures used by regular expression matching machinery, mostly b.c: */
147 
148 #define NCHARS (1256 + 3)    /* 256 handles 8-bit chars; 128 does 7-bit */
149                              /* BUG: some overflows (caught) if we use 256 */
150-                             /* watch out in match(), etc. */
151+                             /* watch out in match(), etc */
152 #define HAT     (NCHARS + 2) /* matches ^ in regular expr */
153 #define NSTATES 32
154 
155@@ -249,7 +249,7 @@ typedef struct rrow {
156     Node   *np;
157     uschar *up;
158     int    *rp; /* rune representation of char class */
159-  } lval;       /* because Al stores a pointer in it! */
160+  } lval;       /* because al stores a pointer in it! */
161   int *lfollow;
162 } rrow;
163 
+170, -170
  1@@ -1,28 +1,28 @@
  2-/****************************************************************
  3-Copyright (C) Lucent Technologies 1997
  4-All Rights Reserved
  5-
  6-Permission to use, copy, modify, and distribute this software and
  7-its documentation for any purpose and without fee is hereby
  8-granted, provided that the above copyright notice appear in all
  9-copies and that both that the copyright notice and this
 10-permission notice and warranty disclaimer appear in supporting
 11-documentation, and that the name Lucent Technologies or any of
 12-its entities not be used in advertising or publicity pertaining
 13-to distribution of the software without specific, written prior
 14-permission.
 15-
 16-LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 17-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
 18-IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
 19-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 20-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 21-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 22-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 23-THIS SOFTWARE.
 24-****************************************************************/
 25-
 26-/* lasciate ogne speranza, voi ch'intrate. */
 27+/* ***************************************************************
 28+ * copyright (c) lucent technologies 1997
 29+ * all rights reserved
 30+ *
 31+ * permission to use, copy, modify, and distribute this software and
 32+ * its documentation for any purpose and without fee is hereby
 33+ * granted, provided that the above copyright notice appear in all
 34+ * copies and that both that the copyright notice and this
 35+ * permission notice and warranty disclaimer appear in supporting
 36+ * documentation, and that the name lucent technologies or any of
 37+ * its entities not be used in advertising or publicity pertaining
 38+ * to distribution of the software without specific, written prior
 39+ * permission
 40+ *
 41+ * LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 42+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 43+ * IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
 44+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 45+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 46+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 47+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 48+ * THIS SOFTWARE
 49+ * ************************************************************** */
 50+
 51+/* lasciate ogne speranza, voi ch'intrate */
 52 
 53 #define DEBUG
 54 
 55@@ -55,13 +55,13 @@ THIS SOFTWARE.
 56   case PLUS:                                                                                       \
 57   case QUEST:
 58 
 59-/* encoding in tree Nodes:
 60-  leaf (CCL, NCCL, CHAR, DOT, FINAL, ALL, EMPTYRE):
 61-    left is index, right contains value or pointer to value
 62-  unary (STAR, PLUS, QUEST): left is child, right is null
 63-  binary (CAT, OR): left and right are children
 64-  parent contains pointer to parent
 65-*/
 66+/* encoding in tree nodes:
 67+ * leaf (CCL, NCCL, CHAR, DOT, FINAL, ALL, EMPTYRE):
 68+ * left is index, right contains value or pointer to value
 69+ * unary (STAR, PLUS, QUEST): left is child, right is null
 70+ * binary (CAT, OR): left and right are children
 71+ * parent contains pointer to parent
 72+ */
 73 
 74 int *setvec;
 75 int *tmpset;
 76@@ -72,10 +72,10 @@ int                  rlxval;
 77 static const uschar *rlxstr;
 78 static const uschar *prestr;   /* current position in current re */
 79 static const uschar *lastre;   /* origin of last re */
 80-static const uschar *lastatom; /* origin of last Atom */
 81+static const uschar *lastatom; /* origin of last atom */
 82 static const uschar *starttok;
 83 static const uschar *basestr; /* starts with original, replaced during
 84-       repetition processing */
 85+ * repetition processing */
 86 static const uschar *firstbasestr;
 87 
 88 static int setcnt;
 89@@ -91,32 +91,32 @@ int nfatab = 0; /* entries in fatab */
 90 extern int u8_nextlen(const char *s);
 91 
 92 /* utf-8 mechanism:
 93-
 94-   For most of Awk, utf-8 strings just "work", since they look like
 95-   null-terminated sequences of 8-bit bytes.
 96-
 97-   Functions like length(), index(), and substr() have to operate
 98-   in units of utf-8 characters.  The u8_* functions in run.c
 99-   handle this.
100-
101-   Regular expressions are more complicated, since the basic
102-   mechanism of the goto table used 8-bit byte indices into the
103-   gototab entries to compute the next state.  Unicode is a lot
104-   bigger, so the gototab entries are now structs with a character
105-   and a next state. These are sorted by code point and binary
106-   searched.
107-
108-   Throughout the RE mechanism in b.c, utf-8 characters are
109-   converted to their utf-32 value.  This mostly shows up in
110-   cclenter, which expands character class ranges like a-z and now
111-   alpha-omega.  The size of a gototab array is still about 256.
112-   This should be dynamic, but for now things work ok for a single
113-   code page of Unicode, which is the most likely case.
114-
115-   The code changes are localized in run.c and b.c.  I have added a
116-   handful of functions to somewhat better hide the implementation,
117-   but a lot more could be done.
118-
119+ *
120+ * for most of awk, utf-8 strings just "work", since they look like
121+ * null-terminated sequences of 8-bit bytes
122+ *
123+ * functions like length(), index(), and substr() have to operate
124+ * in units of utf-8 characters. the u8_* functions in run.c
125+ * handle this
126+ *
127+ * regular expressions are more complicated, since the basic
128+ * mechanism of the goto table used 8-bit byte indices into the
129+ * gototab entries to compute the next state. unicode is a lot
130+ * bigger, so the gototab entries are now structs with a character
131+ * and a next state. these are sorted by code point and binary
132+ * searched
133+ *
134+ * throughout the RE mechanism in b.c, utf-8 characters are
135+ * converted to their utf-32 value. this mostly shows up in
136+ * cclenter, which expands character class ranges like a-z and now
137+ * alpha-omega. the size of a gototab array is still about 256
138+ * this should be dynamic, but for now things work ok for a single
139+ * code page of unicode, which is the most likely case
140+ *
141+ * the code changes are localized in run.c and b.c. i have added a
142+ * handful of functions to somewhat better hide the implementation,
143+ * but a lot more could be done
144+ *
145  */
146 
147 static int  entry_cmp(const void *l, const void *r);
148@@ -240,9 +240,9 @@ mkdfa(const char *s, bool anchor) /* does the real work of making a dfa */
149   basestr      = firstbasestr;
150   p            = reparse(s);
151   p1           = op2(CAT, op2(STAR, op2(ALL, NIL, NIL), NIL), p);
152-  /* put ALL STAR in front of reg.  exp. */
153+  /* put ALL STAR in front of reg. exp */
154   p1 = op2(CAT, p1, op2(FINAL, NIL, NIL));
155-  /* put FINAL after reg.  exp. */
156+  /* put FINAL after reg. exp */
157 
158   poscnt = 0;
159   penter(p1); /* enter parent pointers and leaf indices */
160@@ -316,7 +316,7 @@ penter(Node *p) /* set up parent pointers and leaf indices */
161       break;
162     case ZERO:
163       break;
164-    default: /* can't happen */
165+    default: /* cant happen */
166       FATAL("can't happen: unknown type %d in penter", type(p));
167       break;
168   }
169@@ -340,14 +340,14 @@ freetr(Node *p) /* free parse tree */
170       freetr(right(p));
171       xfree(p);
172       break;
173-    default: /* can't happen */
174+    default: /* cant happen */
175       FATAL("can't happen: unknown type %d in freetr", type(p));
176       break;
177   }
178 }
179 
180 /* in the parsing of regular expressions, metacharacters like . have */
181-/* to be seen literally;  \056 is not a metacharacter. */
182+/* to be seen literally; \056 is not a metacharacter */
183 
184 int
185 hexstr(const uschar **pp, int max) /* find and eval hex string at pp, return new p */
186@@ -452,7 +452,7 @@ cclenter(const char *argp) /* add a character class */
187         p += n;
188         if (c2 == '\\')
189           c2 = quoted(&p); /* BUG: sets p, has to
190-                  be u8 size */
191+ * be u8 size */
192         if (c > c2) {      /* empty; ignore */
193           bp--;
194           i--;
195@@ -493,9 +493,9 @@ cclenter(const char *argp) /* add a character class */
196     i++;
197   }
198   *bp = 0;
199-  /* DPRINTF("cclenter: in = |%s|, out = |%s|\n", op, buf); BUG: can't
200-   * print array of int */
201-  /* xfree(op);  BUG: what are we freeing here? */
202+  /* dprintf("cclenter: in = |%s|, out = |%s|\n", op, buf); BUG: cant
203+ * print array of int */
204+  /* xfree(op); BUG: what are we freeing here? */
205   retp = (int *)calloc(bp - buf + 1, sizeof(int));
206   for (i = 0; i < bp - buf + 1; i++)
207     retp[i] = buf[i];
208@@ -510,7 +510,7 @@ overflo(const char *s)
209 
210 void
211 cfoll(fa *f, Node *v) /* enter follow set of each leaf of vertex v into
212-       lfollow[leaf] */
213+ * lfollow[leaf] */
214 {
215   int  i;
216   int *p;
217@@ -543,7 +543,7 @@ cfoll(fa *f, Node *v) /* enter follow set of each leaf of vertex v into
218       break;
219     case ZERO:
220       break;
221-    default: /* can't happen */
222+    default: /* cant happen */
223       FATAL("can't happen: unknown type %d in cfoll", type(v));
224   }
225 }
226@@ -591,7 +591,7 @@ first(Node *p) /* collects initially active leaves of p into setvec */
227     case ZERO:
228       return 0;
229   }
230-  FATAL("can't happen: unknown type %d in first", type(p)); /* can't happen */
231+  FATAL("can't happen: unknown type %d in first", type(p)); /* cant happen */
232   return (-1);
233 }
234 
235@@ -646,11 +646,11 @@ resize_gototab(fa *f, int state)
236   if (p == NULL)
237     overflo(__func__);
238 
239-  // need to initialize the new memory to zero
240-  size_t orig_size = f->gototab[state].allocated;     // 2nd half of new mem is this size
241-  memset(p + orig_size, 0, orig_size * sizeof(gtte)); // clean it out
242+  /* need to initialize the new memory to zero */
243+  size_t orig_size = f->gototab[state].allocated;     /* 2nd half of new mem is this size */
244+  memset(p + orig_size, 0, orig_size * sizeof(gtte)); /* clean it out */
245 
246-  f->gototab[state].allocated = new_size; // update gototab info
247+  f->gototab[state].allocated = new_size; /* update gototab info */
248   f->gototab[state].entries   = p;
249 }
250 
251@@ -700,7 +700,7 @@ set_gototab(fa *f, int state, int ch, int val) /* hide gototab implementation */
252     f->gototab[state].inuse++;
253     return val;
254   } else if ((unsigned)ch > f->gototab[state].entries[f->gototab[state].inuse - 1].ch) {
255-    // not seen yet, insert and return
256+    /* not seen yet, insert and return */
257     gtt *tab = &f->gototab[state];
258     if (tab->inuse + 1 >= tab->allocated)
259       resize_gototab(f, state);
260@@ -710,7 +710,7 @@ set_gototab(fa *f, int state, int ch, int val) /* hide gototab implementation */
261     f->gototab[state].inuse++;
262     return val;
263   } else {
264-    // maybe we have it, maybe we don't
265+    /* maybe we have it, maybe we dont */
266     gtte  key;
267     gtte *item;
268 
269@@ -721,11 +721,11 @@ set_gototab(fa *f, int state, int ch, int val) /* hide gototab implementation */
270     );
271 
272     if (item != NULL) {
273-      // we have it, update state and return
274+      /* we have it, update state and return */
275       item->state = val;
276       return item->state;
277     }
278-    // otherwise, fall through to insert and reallocate.
279+    /* otherwise, fall through to insert and reallocate */
280   }
281 
282   gtt *tab = &f->gototab[state];
283@@ -820,7 +820,7 @@ pmatch(fa *f, const char *p0) /* longest match, for sub */
284     } while (1);
285     q++; /* was *q++ */
286     if (f->out[s])
287-      patlen = q - p - 1; /* don't count $ */
288+      patlen = q - p - 1; /* dont count $ */
289     if (patlen >= 0) {
290       patbeg = (const char *)p;
291       return (1);
292@@ -873,7 +873,7 @@ nematch(fa *f, const char *p0) /* non-empty match, for sub */
293     } while (1);
294     q++;
295     if (f->out[s])
296-      patlen = q - p - 1; /* don't count $ */
297+      patlen = q - p - 1; /* dont count $ */
298     if (patlen > 0) {
299       patbeg = (const char *)p;
300       return (1);
301@@ -887,17 +887,17 @@ nematch(fa *f, const char *p0) /* non-empty match, for sub */
302 
303 /*
304  * NAME
305- *     fnematch
306+ * fnematch
307  *
308  * DESCRIPTION
309- *     A stream-fed version of nematch which transfers characters to a
310- *     null-terminated buffer. All characters up to and including the last
311- *     character of the matching text or EOF are placed in the buffer. If
312- *     a match is found, patbeg and patlen are set appropriately.
313+ * a stream-fed version of nematch which transfers characters to a
314+ * null-terminated buffer. all characters up to and including the last
315+ * character of the matching text or EOF are placed in the buffer. if
316+ * a match is found, patbeg and patlen are set appropriately
317  *
318  * RETURN VALUES
319- *     false    No match found.
320- *     true     Match found.
321+ * false no match found
322+ * true match found
323  */
324 
325 bool
326@@ -911,20 +911,20 @@ fnematch(fa *pfa, FILE *f, char **pbuf, int *pbufsize, int quantum)
327   patlen = 0;
328 
329   /*
330-   * buf <= i <= j <= k <= buf+bufsize
331-   *
332-   * i: origin of active substring
333-   * j: current character
334-   * k: destination of the next getc
335-   */
336+ * buf <= i <= j <= k <= buf+bufsize
337+ *
338+ * i: origin of active substring
339+ * j: current character
340+ * k: destination of the next getc
341+ */
342 
343   i = j = k = buf;
344 
345   do {
346     /*
347-     * Call u8_rune with at least awk_mb_cur_max ahead in
348-     * the buffer until EOF interferes.
349-     */
350+ * call u8_rune with at least awk_mb_cur_max ahead in
351+ * the buffer until EOF interferes
352+ */
353     if (k - j < (int)awk_mb_cur_max) {
354       if (k + awk_mb_cur_max > buf + bufsize) {
355         char *obuf = buf;
356@@ -961,7 +961,7 @@ fnematch(fa *pfa, FILE *f, char **pbuf, int *pbufsize, int quantum)
357     if (pfa->out[s]) { /* final state */
358       patbeg = i;
359       patlen = j - i;
360-      if (c == 0) /* don't count $ */
361+      if (c == 0) /* dont count $ */
362         patlen--;
363     }
364 
365@@ -980,16 +980,16 @@ fnematch(fa *pfa, FILE *f, char **pbuf, int *pbufsize, int quantum)
366 
367   if (patlen) {
368     /*
369-     * Under no circumstances is the last character fed to
370-     * the automaton part of the match. It is EOF's nullbyte,
371-     * or it sent the automaton into a state with no further
372-     * transitions available (s==1), or both. Room for a
373-     * terminating nullbyte is guaranteed.
374-     *
375-     * ungetc any chars after the end of matching text
376-     * (except for EOF's nullbyte, if present) and null
377-     * terminate the buffer.
378-     */
379+ * under no circumstances is the last character fed to
380+ * the automaton part of the match. it is eof's nullbyte,
381+ * or it sent the automaton into a state with no further
382+ * transitions available (s==1), or both. room for a
383+ * terminating nullbyte is guaranteed
384+ *
385+ * ungetc any chars after the end of matching text
386+ * (except for eof's nullbyte, if present) and null
387+ * terminate the buffer
388+ */
389     do
390       if (*--k && ungetc(*k, f) == EOF)
391         FATAL("unable to ungetc '%c'", *k);
392@@ -1010,7 +1010,7 @@ reparse(const char *p) /* parses regular expression pointed to by p */
393   rtok            = relex();
394   /* GNU compatibility: an empty regexp matches anything */
395   if (rtok == '\0') {
396-    /* FATAL("empty regular expression"); previous */
397+    /* fatal("empty regular expression"); previous */
398     return (op2(EMPTYRE, NIL, NIL));
399   }
400   np = regexp();
401@@ -1065,7 +1065,7 @@ primary(void)
402       return (unary(op2(CHAR, NIL, NIL)));
403     case '(':
404       lastatom     = starttok;
405-      savelastatom = starttok - basestr; /* Retain over recursion */
406+      savelastatom = starttok - basestr; /* retain over recursion */
407       rtok         = relex();
408       if (rtok == ')') { /* special pleading for () */
409         rtok = relex();
410@@ -1073,7 +1073,7 @@ primary(void)
411       }
412       np = regexp();
413       if (rtok == ')') {
414-        lastatom = basestr + savelastatom; /* Restore */
415+        lastatom = basestr + savelastatom; /* restore */
416         rtok     = relex();
417         return (unary(np));
418       } else {
419@@ -1083,7 +1083,7 @@ primary(void)
420     default:
421       FATAL("illegal primary in regular expression %s at %s", lastre, prestr);
422   }
423-  return 0; /*NOTREACHED*/
424+  return 0; /* NOTREACHED */
425 }
426 
427 Node *
428@@ -1137,23 +1137,23 @@ unary(Node *np)
429 }
430 
431 /*
432- * Character class definitions conformant to the POSIX locale as
433- * defined in IEEE P1003.1 draft 7 of June 2001, assuming the source
434+ * character class definitions conformant to the POSIX locale as
435+ * defined in IEEE P1003.1 draft 7 of june 2001, assuming the source
436  * and operating character sets are both ASCII (ISO646) or supersets
437- * thereof.
438+ * thereof
439  *
440- * Note that to avoid overflowing the temporary buffer used in
441+ * note that to avoid overflowing the temporary buffer used in
442  * relex(), the expanded character class (prior to range expansion)
443- * must be less than twice the size of their full name.
444+ * must be less than twice the size of their full name
445  */
446 
447-/* Because isblank doesn't show up in any of the header files on any
448- * system i use, it's defined here.  if some other locale has a richer
449+/* because isblank doesnt show up in any of the header files on any
450+ * system i use, its defined here. if some other locale has a richer
451  * definition of "blank", define HAS_ISBLANK and provide your own
452- * version.
453+ * version
454  * the parentheses here are an attempt to find a path through the maze
455- * of macro definition and/or function and/or version provided.  thanks
456- * to nelson beebe for the suggestion; let's see if it works everywhere.
457+ * of macro definition and/or function and/or version provided. thanks
458+ * to nelson beebe for the suggestion; let's see if it works everywhere
459  */
460 
461 /* #define HAS_ISBLANK */
462@@ -1210,17 +1210,17 @@ replace_repeat(
463   uschar *buf           = 0;
464   int     ret           = 1;
465   int     init_q        = (firstnum == 0);      /* first added char will be ? */
466-  int     n_q_reps      = secondnum - firstnum; /* m>n, so reduce until {1,m-n} left  */
467+  int     n_q_reps      = secondnum - firstnum; /* m>n, so reduce until {1,m-n} left */
468   int     prefix_length = reptok - basestr;     /* prefix includes first rep
469-                                                 */
470-  int suffix_length = strlen((const char *)reptok) - reptoklen; /* string after rep specifier	*/
471+ */
472+  int suffix_length = strlen((const char *)reptok) - reptoklen; /* string after rep specifier */
473   int size          = prefix_length + suffix_length;
474 
475   if (firstnum > 1) { /* add room for reps 2 through firstnum */
476     size += atomlen * (firstnum - 1);
477   }
478 
479-  /* Adjust size of buffer for special cases */
480+  /* adjust size of buffer for special cases */
481   if (special_case == REPEAT_PLUS_APPENDED) {
482     size++; /* for the final + */
483   } else if (special_case == REPEAT_WITH_Q) {
484@@ -1230,14 +1230,14 @@ replace_repeat(
485   }
486   if ((buf = (uschar *)malloc(size + 1)) == NULL)
487     FATAL("out of space in reg expr %.10s..", lastre);
488-  memcpy(buf, basestr, prefix_length); /* copy prefix	*/
489+  memcpy(buf, basestr, prefix_length); /* copy prefix */
490   j = prefix_length;
491   if (special_case == REPEAT_ZERO) {
492     j -= atomlen;
493     buf[j++] = '(';
494     buf[j++] = ')';
495   }
496-  for (i = 1; i < firstnum; i++) { /* copy x reps 	*/
497+  for (i = 1; i < firstnum; i++) { /* copy x reps */
498     memcpy(&buf[j], atom, atomlen);
499     j += atomlen;
500   }
501@@ -1283,12 +1283,12 @@ repeat(
502     return 0;
503 
504   /*
505-     In general, the repetition specifier or "bound" is replaced here
506-     by an equivalent ERE string, repeating the immediately previous atom
507-     and appending ? and + as needed. Note that the first copy of the
508-     atom is left in place, except in the special_case of a zero-repeat
509-     (i.e., {0}).
510-   */
511+ * in general, the repetition specifier or "bound" is replaced here
512+ * by an equivalent ERE string, repeating the immediately previous atom
513+ * and appending ? and + as needed. note that the first copy of the
514+ * atom is left in place, except in the special_case of a zero-repeat
515+ * (i.e., {0})
516+ */
517   if (secondnum < 0) { /* means {n,} -> repeat n-1 times followed by PLUS */
518     if (firstnum < 2) {
519       /* 0 or 1: should be handled before you get here */
520@@ -1300,17 +1300,17 @@ repeat(
521     }
522   } else if (firstnum == secondnum) { /* {n} or {n,n} -> simply repeat n-1 times */
523     if (firstnum == 0) {              /* {0} or {0,0} */
524-      /* This case is unusual because the resulting
525-         replacement string might actually be SMALLER than
526-         the original ERE */
527+      /* this case is unusual because the resulting
528+ * replacement string might actually be SMALLER than
529+ * the original ERE */
530       return replace_repeat(reptok, reptoklen, atom, atomlen, firstnum, secondnum, REPEAT_ZERO);
531     } else { /* (firstnum >= 1) */
532       return replace_repeat(reptok, reptoklen, atom, atomlen, firstnum, secondnum, REPEAT_SIMPLE);
533     }
534-  } else if (firstnum < secondnum) { /* {n,m} -> repeat n-1 times then alternate  */
535-    /*  x{n,m}  =>  xx...x{1, m-n+1}  =>  xx...x?x?x?..x?	*/
536+  } else if (firstnum < secondnum) { /* {n,m} -> repeat n-1 times then alternate */
537+    /* x{n,m} => xx...x{1, m-n+1} => xx...x?x?x?..x? */
538     return replace_repeat(reptok, reptoklen, atom, atomlen, firstnum, secondnum, REPEAT_WITH_Q);
539-  } else { /* Error - shouldn't be here (n>m) */
540+  } else { /* error - shouldnt be here (n>m) */
541     FATAL("internal error");
542   }
543   return 0;
544@@ -1383,7 +1383,7 @@ rescan:
545         prestr++;
546       } else
547         cflag = 0;
548-      n = 5 * strlen((const char *)prestr) + 1; /* BUG: was 2.  what value? */
549+      n = 5 * strlen((const char *)prestr) + 1; /* BUG: was 2. what value? */
550       if (!adjbuf((char **)&buf, &bufsz, n, n, (char **)&bp, "relex1"))
551         FATAL("out of space for reg expr %.10s...", lastre);
552       for (;;) {
553@@ -1402,11 +1402,11 @@ rescan:
554             );
555           *bp++ = c;
556           /* } else if (c == '\n') { */
557-          /* 	FATAL("newline in character class
558-           * %.20s...", lastre); */
559+          /* fatal("newline in character class
560+ * %.20s...", lastre); */
561         } else if (c == '[' && *prestr == ':') {
562-          /* POSIX char class names, Dag-Erling Smorgrav,
563-           * des@ofug.org */
564+          /* POSIX char class names, dag-erling smorgrav,
565+ * des@ofug.org */
566           for (cc = charclasses; cc->cc_name; cc++)
567             if (strncmp((const char *)prestr + 1, (const char *)cc->cc_name, cc->cc_namelen) == 0)
568               break;
569@@ -1414,14 +1414,14 @@ rescan:
570               && prestr[2 + cc->cc_namelen] == ']') {
571             prestr += cc->cc_namelen + 3;
572             /*
573-             * BUG: We begin at 1, instead of 0,
574-             * since we would otherwise prematurely
575-             * terminate the string for classes like
576-             * [[:cntrl:]]. This means that we can't
577-             * match the NUL character, not without
578-             * first adapting the entire program to
579-             * track each string's length.
580-             */
581+ * BUG: we begin at 1, instead of 0,
582+ * since we would otherwise prematurely
583+ * terminate the string for classes like
584+ * [[:cntrl:]]. this means that we cant
585+ * match the NUL character, not without
586+ * first adapting the entire program to
587+ * track each string's length
588+ */
589             for (i = 1; i <= UCHAR_MAX; i++) {
590               if (!adjbuf((char **)&buf, &bufsz, bp - buf + 2, 100, (char **)&bp, "relex2"))
591                 FATAL(
592@@ -1449,11 +1449,11 @@ rescan:
593           collate_char = *prestr++;
594           if (*prestr == '.' && prestr[1] == ']') {
595             prestr += 2;
596-            /* Found it: map via locale TBD: for
597-               now, simply return this char.  This
598-               is sufficient to pass conformance
599-               test awk.ex 156
600-             */
601+            /* found it: map via locale TBD: for
602+ * now, simply return this char. this
603+ * is sufficient to pass conformance
604+ * test awk.ex 156
605+ */
606             if (*prestr == ']') {
607               prestr++;
608               rlxval = collate_char;
609@@ -1466,11 +1466,11 @@ rescan:
610           equiv_char = *prestr++;
611           if (*prestr == '=' && prestr[1] == ']') {
612             prestr += 2;
613-            /* Found it: map via locale TBD: for now
614-               simply return this char. This is
615-               sufficient to pass conformance test
616-               awk.ex 156
617-             */
618+            /* found it: map via locale TBD: for now
619+ * simply return this char. this is
620+ * sufficient to pass conformance test
621+ * awk.ex 156
622+ */
623             if (*prestr == ']') {
624               prestr++;
625               rlxval = equiv_char;
626@@ -1494,13 +1494,13 @@ rescan:
627       break;
628     case '{':
629       if (isdigit((int)*(prestr))) {
630-        num         = 0; /* Process as a repetition */
631+        num         = 0; /* process as a repetition */
632         n           = -1;
633         m           = -1;
634         commafound  = false;
635         digitfound  = false;
636         startreptok = prestr - 1;
637-        /* Remember start of previous atom here ? */
638+        /* remember start of previous atom here ? */
639       } else { /* just a { char, not a repetition */
640         rlxval = c;
641         return CHAR;
642@@ -1529,7 +1529,7 @@ rescan:
643             }
644           } else {
645             if (digitfound) { /* {n} same as {n,n}
646-                               */
647+ */
648               n = num;
649               m = num;
650             } else { /* {} */
651@@ -1547,8 +1547,8 @@ rescan:
652             /* must rescan input for next token */
653             goto rescan;
654           }
655-          /* Failed to replace: eat up {...} characters
656-             and treat like just PLUS */
657+          /* failed to replace: eat up {...} characters
658+ * and treat like just PLUS */
659           return PLUS;
660         } else if (c == '\0') {
661           FATAL("nonterminated character class %.20s", lastre);
662@@ -1591,7 +1591,7 @@ cgoto(fa *f, int s, int c)
663   int *p, *q;
664   int  i, j, k;
665 
666-  /* assert(c == HAT || c < NCHARS);  BUG: seg fault if disable test */
667+  /* assert(c == HAT || c < NCHARS); BUG: seg fault if disable test */
668   while (f->accept >= maxsetvec) { /* guessing here! */
669     resizesetvec(__func__);
670   }
+28, -28
 1@@ -1,26 +1,26 @@
 2-/****************************************************************
 3-Copyright (C) Lucent Technologies 1997
 4-All Rights Reserved
 5-
 6-Permission to use, copy, modify, and distribute this software and
 7-its documentation for any purpose and without fee is hereby
 8-granted, provided that the above copyright notice appear in all
 9-copies and that both that the copyright notice and this
10-permission notice and warranty disclaimer appear in supporting
11-documentation, and that the name Lucent Technologies or any of
12-its entities not be used in advertising or publicity pertaining
13-to distribution of the software without specific, written prior
14-permission.
15-
16-LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
18-IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
19-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
21-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
23-THIS SOFTWARE.
24-****************************************************************/
25+/* ***************************************************************
26+ * copyright (c) lucent technologies 1997
27+ * all rights reserved
28+ *
29+ * permission to use, copy, modify, and distribute this software and
30+ * its documentation for any purpose and without fee is hereby
31+ * granted, provided that the above copyright notice appear in all
32+ * copies and that both that the copyright notice and this
33+ * permission notice and warranty disclaimer appear in supporting
34+ * documentation, and that the name lucent technologies or any of
35+ * its entities not be used in advertising or publicity pertaining
36+ * to distribution of the software without specific, written prior
37+ * permission
38+ *
39+ * LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
40+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
41+ * IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
42+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
43+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
44+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
45+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
46+ * THIS SOFTWARE
47+ * ************************************************************** */
48 
49 #include "awk.h"
50 #include "awkgram.tab.h"
51@@ -122,7 +122,7 @@ gettok(char **pbuf, int *psz) /* get next input token */
52     return c;
53 
54   *bp++ = c;
55-  if (isalpha(c) || c == '_') { /* it's a varname */
56+  if (isalpha(c) || c == '_') { /* its a varname */
57     for (; (c = input()) != 0;) {
58       if (bp - buf >= sz)
59         if (!adjbuf(&buf, &sz, bp - buf + 2, 100, &bp, "gettok"))
60@@ -137,9 +137,9 @@ gettok(char **pbuf, int *psz) /* get next input token */
61     }
62     *bp  = 0;
63     retc = 'a'; /* alphanumeric */
64-  } else {      /* maybe it's a number, but could be . */
65+  } else {      /* maybe its a number, but could be */
66     char *rem;
67-    /* read input until can't be a number */
68+    /* read input until cant be a number */
69     for (; (c = input()) != 0;) {
70       if (bp - buf >= sz)
71         if (!adjbuf(&buf, &sz, bp - buf + 2, 100, &bp, "gettok"))
72@@ -484,7 +484,7 @@ string(void)
73             *bp++ = n;
74             break;
75 
76-          case 'x': /* hex  \x0-9a-fA-F (exactly two) */
77+          case 'x': /* hex \x0-9a-fa-f (exactly two) */
78           {
79             int i;
80 
81@@ -514,7 +514,7 @@ string(void)
82             break;
83           }
84 
85-          case 'u': /* utf  \u0-9a-fA-F (1..8) */
86+          case 'u': /* utf \u0-9a-fa-f (1..8) */
87           {
88             int i;
89 
+58, -58
  1@@ -1,26 +1,26 @@
  2-/****************************************************************
  3-Copyright (C) Lucent Technologies 1997
  4-All Rights Reserved
  5-
  6-Permission to use, copy, modify, and distribute this software and
  7-its documentation for any purpose and without fee is hereby
  8-granted, provided that the above copyright notice appear in all
  9-copies and that both that the copyright notice and this
 10-permission notice and warranty disclaimer appear in supporting
 11-documentation, and that the name Lucent Technologies or any of
 12-its entities not be used in advertising or publicity pertaining
 13-to distribution of the software without specific, written prior
 14-permission.
 15-
 16-LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 17-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
 18-IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
 19-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 20-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 21-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 22-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 23-THIS SOFTWARE.
 24-****************************************************************/
 25+/* ***************************************************************
 26+ * copyright (c) lucent technologies 1997
 27+ * all rights reserved
 28+ *
 29+ * permission to use, copy, modify, and distribute this software and
 30+ * its documentation for any purpose and without fee is hereby
 31+ * granted, provided that the above copyright notice appear in all
 32+ * copies and that both that the copyright notice and this
 33+ * permission notice and warranty disclaimer appear in supporting
 34+ * documentation, and that the name lucent technologies or any of
 35+ * its entities not be used in advertising or publicity pertaining
 36+ * to distribution of the software without specific, written prior
 37+ * permission
 38+ *
 39+ * LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 40+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 41+ * IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
 42+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 43+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 44+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 45+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 46+ * THIS SOFTWARE
 47+ * ************************************************************** */
 48 
 49 #define DEBUG
 50 #include "awk.h"
 51@@ -45,7 +45,7 @@ int   recsize = RECSIZE;
 52 char *fields;
 53 int   fieldssize = RECSIZE;
 54 
 55-Cell        **fldtab; /* pointers to Cells */
 56+Cell        **fldtab; /* pointers to cells */
 57 static size_t len_inputFS = 0;
 58 static char  *inputFS     = NULL; /* FS at time of input, for field splitting */
 59 
 60@@ -118,11 +118,11 @@ initgetrec(void)
 61 /*
 62  * POSIX specifies that fields are supposed to be evaluated as if they were
 63  * split using the value of FS at the time that the record's value ($0) was
 64- * read.
 65+ * read
 66  *
 67- * Since field-splitting is done lazily, we save the current value of FS
 68+ * since field-splitting is done lazily, we save the current value of FS
 69  * whenever a new record is read in (implicitly or via getline), or when
 70- * a new value is assigned to $0.
 71+ * a new value is assigned to $0
 72  */
 73 void
 74 savefs(void)
 75@@ -230,7 +230,7 @@ extern int readcsvrec(char **pbuf, int *pbufsize, FILE *inf, bool newflag);
 76 int
 77 readrec(char **pbuf, int *pbufsize, FILE *inf, bool newflag) /* read one record into buf */
 78 {
 79-  int   sep, c, isrec; // POTENTIAL BUG? isrec is a macro in awk.h
 80+  int   sep, c, isrec; /* potential bug? isrec is a macro in awk.h */
 81   char *rr = *pbuf, *buf = *pbuf;
 82   int   bufsize = *pbufsize;
 83   char *rs      = getsval(rsloc);
 84@@ -294,11 +294,11 @@ readrec(char **pbuf, int *pbufsize, FILE *inf, bool newflag) /* read one record
 85   return isrec;
 86 }
 87 
 88-/*******************
 89+/* ******************
 90  * loose ends here:
 91- *   \r\n should become \n
 92- *   what about bare \r?  Excel uses that for embedded newlines
 93- *   can't have "" in unquoted fields, according to RFC 4180
 94+ * \r\n should become \n
 95+ * what about bare \r? excel uses that for embedded newlines
 96+ * cant have "" in unquoted fields, according to RFC 4180
 97  */
 98 
 99 int
100@@ -312,13 +312,13 @@ readcsvrec(char **pbuf, int *pbufsize, FILE *inf, bool newflag) /* csv can have
101   bool  in_quote = false;
102 
103   sep = '\n'; /* the only separator; have to skip over \n embedded in
104-           "..." */
105+ * "..." */
106   rr = buf;
107   while ((c = getc(inf)) != EOF) {
108     if (c == sep) {
109       if (!in_quote)
110         break;
111-      if (rr > buf && rr[-1] == '\r') // remove \r if was \r\n
112+      if (rr > buf && rr[-1] == '\r') /* remove \r if was \r\n */
113         rr--;
114     }
115 
116@@ -329,7 +329,7 @@ readcsvrec(char **pbuf, int *pbufsize, FILE *inf, bool newflag) /* csv can have
117     if (c == '"')
118       in_quote = !in_quote;
119   }
120-  if (c == '\n' && rr > buf && rr[-1] == '\r') // remove \r if was \r\n
121+  if (c == '\n' && rr > buf && rr[-1] == '\r') /* remove \r if was \r\n */
122     rr--;
123 
124   if (!adjbuf(&buf, &bufsize, 1 + rr - buf, recsize, &rr, "readcsvrec 4"))
125@@ -342,7 +342,7 @@ readcsvrec(char **pbuf, int *pbufsize, FILE *inf, bool newflag) /* csv can have
126 }
127 
128 char *
129-getargv(int n) /* get ARGV[n] */
130+getargv(int n) /* get argv[n] */
131 {
132   Array       *ap;
133   Cell        *x;
134@@ -366,8 +366,8 @@ setclvar(char *s) /* set var=value from s */
135   Cell  *q;
136   double result;
137 
138-  /* commit f3d9187d4e0f02294fb1b0e31152070506314e67 broke T.argv test */
139-  /* I don't understand why it was changed. */
140+  /* commit f3d9187d4e0f02294fb1b0e31152070506314e67 broke t.argv test */
141+  /* i dont understand why it was changed */
142 
143   for (p = s; *p != '='; p++)
144     ;
145@@ -411,7 +411,7 @@ fldbld(void) /* create fields from current record */
146   i  = 0;              /* number of fields accumulated here */
147   if (inputFS == NULL) /* make sure we have a copy of FS */
148     savefs();
149-  if (!CSV && strlen(inputFS) > 1) { /* it's a regular expression */
150+  if (!CSV && strlen(inputFS) > 1) { /* its a regular expression */
151     i = refldbld(r, inputFS);
152   } else if (!CSV && (sep = *inputFS) == ' ') { /* default whitespace */
153     for (i = 0;;) {
154@@ -432,7 +432,7 @@ fldbld(void) /* create fields from current record */
155       *fr++ = 0;
156     }
157     *fr = 0;
158-  } else if (CSV) { /* CSV processing.  no error handling */
159+  } else if (CSV) { /* CSV processing. no error handling */
160     if (*r != 0) {
161       for (;;) {
162         i++;
163@@ -446,11 +446,11 @@ fldbld(void) /* create fields from current record */
164           for (r++; *r != '\0';) {
165             if (*r == '"' && r[1] != '\0' && r[1] == '"') {
166               r += 2; /* doubled quote
167-                       */
168+ */
169               *fr++ = '"';
170             } else if (*r == '"' && (r[1] == '\0' || r[1] == ',')) {
171               r++; /* skip over
172-                closing quote */
173+ * closing quote */
174               break;
175             } else {
176               *fr++ = *r++;
177@@ -483,11 +483,11 @@ fldbld(void) /* create fields from current record */
178       fldtab[i]->tval = FLD | STR;
179     }
180     *fr = 0;
181-  } else if (*r != 0) { /* if 0, it's a null field */
182-    /* subtle case: if length(FS) == 1 && length(RS > 0)
183-     * \n is NOT a field separator (cf awk book 61,84).
184-     * this variable is tested in the inner while loop.
185-     */
186+  } else if (*r != 0) { /* if 0, its a null field */
187+    /* subtle case: if length(fs) == 1 && length(rs > 0)
188+ * \n is NOT a field separator (cf awk book 61,84)
189+ * this variable is tested in the inner while loop
190+ */
191     int rtest = '\n'; /* normal case */
192     if (strlen(*RS) > 0)
193       rtest = '\0';
194@@ -590,7 +590,7 @@ growfldtab(int n) /* make new fields up to at least $n */
195   if (n > nf)
196     nf = n;
197   s = (nf + 1) * (sizeof(struct Cell *));          /* freebsd: how much do we need? */
198-  if (s / sizeof(struct Cell *) - 1 == (size_t)nf) /* didn't overflow */
199+  if (s / sizeof(struct Cell *) - 1 == (size_t)nf) /* didnt overflow */
200     fldtab = (Cell **)realloc(fldtab, s);
201   else             /* overflow sizeof int */
202     xfree(fldtab); /* make it null */
203@@ -882,20 +882,20 @@ isclvar(const char *s) /* is s of form var=something ? */
204 
205 /* strtod is supposed to be a proper test of what's a valid number */
206 /* appears to be broken in gcc on linux: thinks 0x123 is a valid FP number */
207-/* wrong: violates 4.10.1.4 of ansi C standard */
208+/* wrong: violates 4.10.1.4 of ansi c standard */
209 
210-/* well, not quite. As of C99, hex floating point is allowed. so this is
211- * a bit of a mess. We work around the mess by checking for a hexadecimal
212- * value and disallowing it. Similarly, we now follow gawk and allow only
213- * +nan, -nan, +inf, and -inf for NaN and infinity values.
214+/* well, not quite. as of C99, hex floating point is allowed. so this is
215+ * a bit of a mess. we work around the mess by checking for a hexadecimal
216+ * value and disallowing it. similarly, we now follow gawk and allow only
217+ * +nan, -nan, +inf, and -inf for nan and infinity values
218  */
219 
220 /*
221- * This routine now has a more complicated interface, the main point
222+ * this routine now has a more complicated interface, the main point
223  * being to avoid the double conversion of a string to double, and
224  * also to convey out, if requested, the information that the numeric
225- * value was a leading string or is all of the string. The latter bit
226- * is used in getfval().
227+ * value was a leading string or is all of the string. the latter bit
228+ * is used in getfval()
229  */
230 
231 bool
232@@ -941,8 +941,8 @@ convert:
233     *result = r;
234 
235   /*
236-   * check for trailing stuff
237-   */
238+ * check for trailing stuff
239+ */
240   while (isspace((int)*ep))
241     ep++;
242 
+34, -34
  1@@ -1,26 +1,26 @@
  2-/****************************************************************
  3-Copyright (C) Lucent Technologies 1997
  4-All Rights Reserved
  5-
  6-Permission to use, copy, modify, and distribute this software and
  7-its documentation for any purpose and without fee is hereby
  8-granted, provided that the above copyright notice appear in all
  9-copies and that both that the copyright notice and this
 10-permission notice and warranty disclaimer appear in supporting
 11-documentation, and that the name Lucent Technologies or any of
 12-its entities not be used in advertising or publicity pertaining
 13-to distribution of the software without specific, written prior
 14-permission.
 15-
 16-LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 17-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
 18-IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
 19-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 20-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 21-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 22-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 23-THIS SOFTWARE.
 24-****************************************************************/
 25+/* ***************************************************************
 26+ * copyright (c) lucent technologies 1997
 27+ * all rights reserved
 28+ *
 29+ * permission to use, copy, modify, and distribute this software and
 30+ * its documentation for any purpose and without fee is hereby
 31+ * granted, provided that the above copyright notice appear in all
 32+ * copies and that both that the copyright notice and this
 33+ * permission notice and warranty disclaimer appear in supporting
 34+ * documentation, and that the name lucent technologies or any of
 35+ * its entities not be used in advertising or publicity pertaining
 36+ * to distribution of the software without specific, written prior
 37+ * permission
 38+ *
 39+ * LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 40+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 41+ * IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
 42+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 43+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 44+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 45+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 46+ * THIS SOFTWARE
 47+ * ************************************************************** */
 48 
 49 const char *version = "version 20260426";
 50 
 51@@ -112,12 +112,12 @@ fpecatch(
 52   );
 53 }
 54 
 55-/* Can this work with recursive calls?  I don't think so.
 56-void segvcatch(int n)
 57-{
 58-  FATAL("segfault.  Do you have an unbounded recursive call?", n);
 59-}
 60-*/
 61+/* can this work with recursive calls? i dont think so
 62+ * void segvcatch(int n)
 63+ * {
 64+ * fatal("segfault. do you have an unbounded recursive call?", n);
 65+ * }
 66+ */
 67 
 68 static const char *
 69 setfs(char *p)
 70@@ -172,9 +172,9 @@ main(int argc, char *argv[])
 71 #else
 72   (void)signal(SIGFPE, fpecatch);
 73 #endif
 74-  /*signal(SIGSEGV, segvcatch); experiment */
 75+  /* signal(sigsegv, segvcatch); experiment */
 76 
 77-  /* Set and keep track of the random seed */
 78+  /* set and keep track of the random seed */
 79   srand_seed = 1;
 80   srandom((unsigned long)srand_seed);
 81 
 82@@ -217,7 +217,7 @@ main(int argc, char *argv[])
 83       case 'F': /* set field separator */
 84         fs = setfs(getarg(&argc, &argv, "no field separator"));
 85         break;
 86-      case 'v': /* -v a=1 to be done NOW.  one -v for each */
 87+      case 'v': /* -v a=1 to be done NOW. one -v for each */
 88         vn = getarg(&argc, &argv, "no variable name");
 89         if (isclvar(vn))
 90           setclvar(vn);
 91@@ -263,8 +263,8 @@ main(int argc, char *argv[])
 92     envinit(environ);
 93   yyparse();
 94 #if 0
 95-	// Doing this would comply with POSIX, but is not compatible with
 96-	// other awks and with what most users expect. So comment it out.
 97+	/* doing this would comply with POSIX, but is not compatible with
 98+	 * other awks and with what most users expect. so comment it out */
 99 	setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */
100 #endif
101   if (fs)
+27, -27
 1@@ -1,31 +1,31 @@
 2-/****************************************************************
 3-Copyright (C) Lucent Technologies 1997
 4-All Rights Reserved
 5-
 6-Permission to use, copy, modify, and distribute this software and
 7-its documentation for any purpose and without fee is hereby
 8-granted, provided that the above copyright notice appear in all
 9-copies and that both that the copyright notice and this
10-permission notice and warranty disclaimer appear in supporting
11-documentation, and that the name Lucent Technologies or any of
12-its entities not be used in advertising or publicity pertaining
13-to distribution of the software without specific, written prior
14-permission.
15-
16-LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
18-IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
19-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
21-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
23-THIS SOFTWARE.
24-****************************************************************/
25+/* ***************************************************************
26+ * copyright (c) lucent technologies 1997
27+ * all rights reserved
28+ *
29+ * permission to use, copy, modify, and distribute this software and
30+ * its documentation for any purpose and without fee is hereby
31+ * granted, provided that the above copyright notice appear in all
32+ * copies and that both that the copyright notice and this
33+ * permission notice and warranty disclaimer appear in supporting
34+ * documentation, and that the name lucent technologies or any of
35+ * its entities not be used in advertising or publicity pertaining
36+ * to distribution of the software without specific, written prior
37+ * permission
38+ *
39+ * LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
40+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
41+ * IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
42+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
43+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
44+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
45+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
46+ * THIS SOFTWARE
47+ * ************************************************************** */
48 
49 /*
50  * this program makes the table to link function names
51- * and type indices that is used by execute() in run.c.
52- * it finds the indices in awkgram.tab.h, produced by bison.
53+ * and type indices that is used by execute() in run.c
54+ * it finds the indices in awkgram.tab.h, produced by bison
55  */
56 
57 #define _POSIX_C_SOURCE 200809L
58@@ -137,7 +137,7 @@ main(int argc, char *argv[])
59   printf("static const char * const printname[%d] = {\n", SIZE);
60   i = 0;
61   while (fgets(buf, sizeof buf, fp) != NULL) {
62-    // 199 is sizeof(def) - 1
63+    /* 199 is sizeof(def) - 1 */
64     if (tokentype != TOK_ENUM) {
65       n = sscanf(buf, "%1c %199s %199s %d", &c, def, name, &tok);
66       if (n == 4 && c == '#' && strcmp(def, "define") == 0) {
67@@ -160,7 +160,7 @@ main(int argc, char *argv[])
68     if (tok < FIRSTTOKEN || tok > LASTTOKEN) {
69       tokentype = TOK_UNKNOWN;
70       /* fprintf(stderr, "maketab funny token %d %s
71-       * ignored\n", tok, buf); */
72+ * ignored\n", tok, buf); */
73       continue;
74     }
75     names[tok - FIRSTTOKEN] = strdup(name);
+23, -23
 1@@ -1,26 +1,26 @@
 2-/****************************************************************
 3-Copyright (C) Lucent Technologies 1997
 4-All Rights Reserved
 5-
 6-Permission to use, copy, modify, and distribute this software and
 7-its documentation for any purpose and without fee is hereby
 8-granted, provided that the above copyright notice appear in all
 9-copies and that both that the copyright notice and this
10-permission notice and warranty disclaimer appear in supporting
11-documentation, and that the name Lucent Technologies or any of
12-its entities not be used in advertising or publicity pertaining
13-to distribution of the software without specific, written prior
14-permission.
15-
16-LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
18-IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
19-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
21-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
23-THIS SOFTWARE.
24-****************************************************************/
25+/* ***************************************************************
26+ * copyright (c) lucent technologies 1997
27+ * all rights reserved
28+ *
29+ * permission to use, copy, modify, and distribute this software and
30+ * its documentation for any purpose and without fee is hereby
31+ * granted, provided that the above copyright notice appear in all
32+ * copies and that both that the copyright notice and this
33+ * permission notice and warranty disclaimer appear in supporting
34+ * documentation, and that the name lucent technologies or any of
35+ * its entities not be used in advertising or publicity pertaining
36+ * to distribution of the software without specific, written prior
37+ * permission
38+ *
39+ * LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
40+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
41+ * IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
42+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
43+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
44+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
45+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
46+ * THIS SOFTWARE
47+ * ************************************************************** */
48 
49 #ifdef __GNUC__
50 #pragma GCC diagnostic ignored "-Wunknown-pragmas"
+26, -26
 1@@ -1,26 +1,26 @@
 2-/****************************************************************
 3-Copyright (C) Lucent Technologies 1997
 4-All Rights Reserved
 5-
 6-Permission to use, copy, modify, and distribute this software and
 7-its documentation for any purpose and without fee is hereby
 8-granted, provided that the above copyright notice appear in all
 9-copies and that both that the copyright notice and this
10-permission notice and warranty disclaimer appear in supporting
11-documentation, and that the name Lucent Technologies or any of
12-its entities not be used in advertising or publicity pertaining
13-to distribution of the software without specific, written prior
14-permission.
15-
16-LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
18-IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
19-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
21-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
23-THIS SOFTWARE.
24-****************************************************************/
25+/* ***************************************************************
26+ * copyright (c) lucent technologies 1997
27+ * all rights reserved
28+ *
29+ * permission to use, copy, modify, and distribute this software and
30+ * its documentation for any purpose and without fee is hereby
31+ * granted, provided that the above copyright notice appear in all
32+ * copies and that both that the copyright notice and this
33+ * permission notice and warranty disclaimer appear in supporting
34+ * documentation, and that the name lucent technologies or any of
35+ * its entities not be used in advertising or publicity pertaining
36+ * to distribution of the software without specific, written prior
37+ * permission
38+ *
39+ * LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
40+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
41+ * IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
42+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
43+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
44+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
45+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
46+ * THIS SOFTWARE
47+ * ************************************************************** */
48 
49 #define DEBUG
50 #include "awk.h"
51@@ -192,7 +192,7 @@ celltonode(Cell *a, int b)
52 }
53 
54 Node *
55-rectonode(void) /* make $0 into a Node */
56+rectonode(void) /* make $0 into a node */
57 {
58   extern Cell *literal0;
59   return op1(INDIRECT, celltonode(literal0, CUNK));
60@@ -237,7 +237,7 @@ linkum(Node *a, Node *b)
61 {
62   Node *c;
63 
64-  if (errorflag) /* don't link things that are wrong */
65+  if (errorflag) /* dont link things that are wrong */
66     return a;
67   if (a == NULL)
68     return (b);
69@@ -251,7 +251,7 @@ linkum(Node *a, Node *b)
70 
71 void
72 defn(Cell *v, Node *vl, Node *st) /* turn on FCN bit in definition, */
73-{                                 /*   body of function, arglist */
74+{                                 /* body of function, arglist */
75   Node *p;
76   int   n;
77 
+23, -23
 1@@ -1,26 +1,26 @@
 2-/****************************************************************
 3-Copyright (C) Lucent Technologies 1997
 4-All Rights Reserved
 5-
 6-Permission to use, copy, modify, and distribute this software and
 7-its documentation for any purpose and without fee is hereby
 8-granted, provided that the above copyright notice appear in all
 9-copies and that both that the copyright notice and this
10-permission notice and warranty disclaimer appear in supporting
11-documentation, and that the name Lucent Technologies or any of
12-its entities not be used in advertising or publicity pertaining
13-to distribution of the software without specific, written prior
14-permission.
15-
16-LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
18-IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
19-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
21-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
23-THIS SOFTWARE.
24-****************************************************************/
25+/* ***************************************************************
26+ * copyright (c) lucent technologies 1997
27+ * all rights reserved
28+ *
29+ * permission to use, copy, modify, and distribute this software and
30+ * its documentation for any purpose and without fee is hereby
31+ * granted, provided that the above copyright notice appear in all
32+ * copies and that both that the copyright notice and this
33+ * permission notice and warranty disclaimer appear in supporting
34+ * documentation, and that the name lucent technologies or any of
35+ * its entities not be used in advertising or publicity pertaining
36+ * to distribution of the software without specific, written prior
37+ * permission
38+ *
39+ * LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
40+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
41+ * IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
42+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
43+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
44+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
45+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
46+ * THIS SOFTWARE
47+ * ************************************************************** */
48 
49 #include <stddef.h>
50 #include <stdio.h>
+132, -132
  1@@ -1,26 +1,26 @@
  2-/****************************************************************
  3-Copyright (C) Lucent Technologies 1997
  4-All Rights Reserved
  5-
  6-Permission to use, copy, modify, and distribute this software and
  7-its documentation for any purpose and without fee is hereby
  8-granted, provided that the above copyright notice appear in all
  9-copies and that both that the copyright notice and this
 10-permission notice and warranty disclaimer appear in supporting
 11-documentation, and that the name Lucent Technologies or any of
 12-its entities not be used in advertising or publicity pertaining
 13-to distribution of the software without specific, written prior
 14-permission.
 15-
 16-LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 17-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
 18-IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
 19-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 20-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 21-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 22-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 23-THIS SOFTWARE.
 24-****************************************************************/
 25+/* ***************************************************************
 26+ * copyright (c) lucent technologies 1997
 27+ * all rights reserved
 28+ *
 29+ * permission to use, copy, modify, and distribute this software and
 30+ * its documentation for any purpose and without fee is hereby
 31+ * granted, provided that the above copyright notice appear in all
 32+ * copies and that both that the copyright notice and this
 33+ * permission notice and warranty disclaimer appear in supporting
 34+ * documentation, and that the name lucent technologies or any of
 35+ * its entities not be used in advertising or publicity pertaining
 36+ * to distribution of the software without specific, written prior
 37+ * permission
 38+ *
 39+ * LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 40+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 41+ * IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
 42+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 43+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 44+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 45+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 46+ * THIS SOFTWARE
 47+ * ************************************************************** */
 48 
 49 #ifdef __GNUC__
 50 #pragma GCC diagnostic ignored "-Wunused-parameter"
 51@@ -52,7 +52,7 @@ static char *wide_char_to_byte_str(int rune, size_t *outlen);
 52   do {                                                                                             \
 53     if (istemp(x))                                                                                 \
 54       tfree(x);                                                                                    \
 55-  } while (/*CONSTCOND*/ 0)
 56+  } while (/* CONSTCOND */ 0)
 57 #else
 58 void
 59 tempfree(Cell *p)
 60@@ -72,8 +72,8 @@ tempfree(Cell *p)
 61 /* #endif */
 62 /* #endif */
 63 
 64-/* #ifndef	FOPEN_MAX */
 65-/* #define	FOPEN_MAX	40 */ /* max number of open files */
 66+/* #ifndef fopen_max */
 67+/* #define fopen_max 40 */ /* max number of open files */
 68 /* #endif */
 69 
 70 jmp_buf         env;
 71@@ -106,14 +106,14 @@ Node *curnode = NULL; /* the node being executed, for debugging */
 72 /* buffer memory management */
 73 int
 74 adjbuf(char **pbuf, int *psiz, int minlen, int quantum, char **pbptr, const char *whatrtn)
 75-/* pbuf:    address of pointer to buffer being managed
 76- * psiz:    address of buffer size variable
 77- * minlen:  minimum length of buffer needed
 78+/* pbuf: address of pointer to buffer being managed
 79+ * psiz: address of buffer size variable
 80+ * minlen: minimum length of buffer needed
 81  * quantum: buffer size quantum
 82- * pbptr:   address of movable pointer into buffer, or 0 if none
 83+ * pbptr: address of movable pointer into buffer, or 0 if none
 84  * whatrtn: name of the calling routine if failure should cause fatal error
 85  *
 86- * return   0 for realloc failure, !=0 for success
 87+ * return 0 for realloc failure, !=0 for success
 88  */
 89 {
 90   if (minlen > *psiz) {
 91@@ -167,8 +167,8 @@ execute(Node *u) /* execute a node of the parse tree */
 92         recbld();
 93       return (x);
 94     }
 95-    if (notlegal(a->nobj)) /* probably a Cell* but too risky to
 96-            print */
 97+    if (notlegal(a->nobj)) /* probably a cell* but too risky to
 98+ * print */
 99       FATAL("illegal statement");
100     proc = proctab[a->nobj - FIRSTTOKEN];
101     x    = (*proc)(a->narg, a->nobj);
102@@ -229,7 +229,7 @@ ex1:
103 
104 struct Frame {    /* stack frame for awk function calls */
105   int    nargs;   /* number of arguments in this call */
106-  Cell  *fcncell; /* pointer to Cell for function */
107+  Cell  *fcncell; /* pointer to cell for function */
108   Cell **args;    /* pointer to array of arguments after execute */
109   Cell  *retval;  /* return value */
110 };
111@@ -241,12 +241,12 @@ int           nframe = 0;    /* number of frames allocated */
112 struct Frame *frp    = NULL; /* frame pointer. bottom level unused */
113 
114 Cell *
115-call(Node **a, int n) /* function call.  very kludgy and fragile */
116+call(Node **a, int n) /* function call. very kludgy and fragile */
117 {
118   static const Cell newcopycell = {OCELL, CCOPY, 0, EMPTY, 0.0, NUM | STR | DONTFREE, NULL, NULL};
119   int               i, ncall, ndef;
120   int               freed = 0; /* handles potential double freeing when fcn & param
121-                      share a tempcell */
122+ * share a tempcell */
123   Node *x;
124   Cell *args[NARGS], *oargs[NARGS]; /* BUG: fixed size arrays */
125   Cell *y, *z, *fcn;
126@@ -338,7 +338,7 @@ call(Node **a, int n) /* function call.  very kludgy and fragile */
127   if (isexit(y) || isnext(y))
128     return y;
129   if (freed == 0) {
130-    tempfree(y); /* don't free twice! */
131+    tempfree(y); /* dont free twice! */
132   }
133   z = frp->retval; /* return value */
134   DPRINTF("%s returns %g |%s| %o\n", s, getfval(z), getsval(z), z->tval);
135@@ -400,7 +400,7 @@ jump(Node **a, int n) /* break, continue, next, nextfile, return */
136           setsval(frp->retval, getsval(y));
137         else if (y->tval & NUM)
138           setfval(frp->retval, getfval(y));
139-        else /* can't happen */
140+        else /* cant happen */
141           FATAL("bad type variable %d", y->tval);
142         tempfree(y);
143       }
144@@ -414,7 +414,7 @@ jump(Node **a, int n) /* break, continue, next, nextfile, return */
145       return (jbreak);
146     case CONTINUE:
147       return (jcont);
148-    default: /* can't happen */
149+    default: /* cant happen */
150       FATAL("illegal jump type %d", n);
151   }
152   return 0; /* not reached */
153@@ -536,7 +536,7 @@ array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */
154   Cell *x, *z;
155   char *buf;
156 
157-  x   = execute(a[0]); /* Cell* for symbol table */
158+  x   = execute(a[0]); /* cell* for symbol table */
159   buf = makearraystring(a[1], __func__);
160   if (!isarr(x)) {
161     DPRINTF("making %s into an array\n", NN(x->nval));
162@@ -559,7 +559,7 @@ awkdelete(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */
163 {
164   Cell *x;
165 
166-  x = execute(a[0]); /* Cell* for symbol table */
167+  x = execute(a[0]); /* cell* for symbol table */
168   if (x == symtabloc) {
169     FATAL("cannot delete SYMTAB or its elements");
170   }
171@@ -607,18 +607,18 @@ intest(Node **a, int n) /* a[0] is index (list), a[1] is symtab */
172 /* ======== utf-8 code ========== */
173 
174 /*
175- * Awk strings can contain ascii, random 8-bit items (eg Latin-1),
176- * or utf-8.  u8_isutf tests whether a string starts with a valid
177- * utf-8 sequence, and returns 0 if not (e.g., high bit set).
178+ * awk strings can contain ascii, random 8-bit items (eg latin-1),
179+ * or utf-8. u8_isutf tests whether a string starts with a valid
180+ * utf-8 sequence, and returns 0 if not (e.g., high bit set)
181  * u8_nextlen returns length of next valid sequence, which is
182- * 1 for ascii, 2..4 for utf-8, or 1 for high bit non-utf.
183+ * 1 for ascii, 2..4 for utf-8, or 1 for high bit non-utf
184  * u8_strlen returns length of string in valid utf-8 sequences
185- * and/or high-bit bytes.  Conversion functions go between byte
186- * number and character number.
187+ * and/or high-bit bytes. conversion functions go between byte
188+ * number and character number
189  *
190- * In theory, this behaves the same as before for non-utf8 bytes.
191+ * in theory, this behaves the same as before for non-utf8 bytes
192  *
193- * Limited checking! This is a potential security hole.
194+ * limited checking! this is a potential security hole
195  */
196 
197 /* is s the beginning of a valid utf-8 string? */
198@@ -631,7 +631,7 @@ u8_isutf(const char *s)
199 
200   c = s[0];
201   if (c < 128 || awk_mb_cur_max == 1)
202-    return 1; /* what if it's 0? */
203+    return 1; /* what if its 0? */
204 
205   n = strlen(s);
206   if (n >= 2 && ((c >> 5) & 0x7) == 0x6 && (s[1] & 0xC0) == 0x80) {
207@@ -649,9 +649,9 @@ u8_isutf(const char *s)
208   return ret;
209 }
210 
211-/* Convert (prefix of) utf8 string to utf-32 rune. */
212-/* Sets *rune to the value, returns the length. */
213-/* No error checking: watch out. */
214+/* convert (prefix of) utf8 string to utf-32 rune */
215+/* sets *rune to the value, returns the length */
216+/* no error checking: watch out */
217 int
218 u8_rune(int *rune, const char *s)
219 {
220@@ -683,7 +683,7 @@ u8_rune(int *rune, const char *s)
221     *rune = c;
222     ret   = 1;
223   }
224-  return ret; /* returns one byte if sequence doesn't look like utf */
225+  return ret; /* returns one byte if sequence doesnt look like utf */
226 }
227 
228 /* return length of next sequence: 1 for ascii or random, 2..4 for valid utf8 */
229@@ -756,7 +756,7 @@ u8_byte2char(const char *s, int bytenum)
230   return charnum;
231 }
232 
233-/* runetochar() adapted from rune.c in the Plan 9 distribution */
234+/* runetochar() adapted from rune.c in the plan 9 distribution */
235 
236 enum {
237   Runeerror = 128, /* from somewhere else */
238@@ -795,14 +795,14 @@ runetochar(char *str, int c)
239     return 1;
240   }
241 
242-  /* two character sequence 00080-007FF => T2 Tx */
243+  /* two character sequence 00080-007FF => T2 tx */
244   if (c <= Rune2) {
245     str[0] = T2 | (c >> 1 * Bitx);
246     str[1] = Tx | (c & Maskx);
247     return 2;
248   }
249 
250-  /* three character sequence 00800-0FFFF => T3 Tx Tx */
251+  /* three character sequence 00800-0FFFF => T3 tx tx */
252   if (c > Runemax)
253     c = Runeerror;
254   if (c <= Rune3) {
255@@ -812,7 +812,7 @@ runetochar(char *str, int c)
256     return 3;
257   }
258 
259-  /* four character sequence 010000-1FFFFF => T4 Tx Tx Tx */
260+  /* four character sequence 010000-1FFFFF => T4 tx tx tx */
261   str[0] = T4 | (c >> 3 * Bitx);
262   str[1] = Tx | ((c >> 2 * Bitx) & Maskx);
263   str[2] = Tx | ((c >> 1 * Bitx) & Maskx);
264@@ -913,14 +913,14 @@ boolop(Node **a, int n) /* a[0] || a[1], a[0] && a[1], !a[0] */
265         return (False);
266       else
267         return (True);
268-    default: /* can't happen */
269+    default: /* cant happen */
270       FATAL("unknown boolean operator %d", n);
271   }
272-  return 0; /*NOTREACHED*/
273+  return 0; /* NOTREACHED */
274 }
275 
276 Cell *
277-relop(Node **a, int n) /* a[0 < a[1], etc. */
278+relop(Node **a, int n) /* a[0 < a[1], etc */
279 {
280   int      i;
281   Cell    *x, *y;
282@@ -974,10 +974,10 @@ relop(Node **a, int n) /* a[0 < a[1], etc. */
283         return (True);
284       else
285         return (False);
286-    default: /* can't happen */
287+    default: /* cant happen */
288       FATAL("unknown relational operator %d", n);
289   }
290-  return 0; /*NOTREACHED*/
291+  return 0; /* NOTREACHED */
292 }
293 
294 void
295@@ -1027,7 +1027,7 @@ indirect(Node **a, int n) /* $( a[0] ) */
296   m = (int)val;
297   tempfree(x);
298   x        = fieldadr(m);
299-  x->ctype = OCELL; /* BUG?  why are these needed? */
300+  x->ctype = OCELL; /* BUG? why are these needed? */
301   x->csub  = CFLD;
302   return (x);
303 }
304@@ -1078,7 +1078,7 @@ substr(Node **a, int nnn) /* substr(a[0], a[1], a[2]) */
305   mb = u8_char2byte(s, m - 1);     /* byte offset of start char in s */
306   nb = u8_char2byte(s, m - 1 + n); /* byte offset of end+1 char in s */
307 
308-  temp  = s[nb]; /* with thanks to John Linderman */
309+  temp  = s[nb]; /* with thanks to john linderman */
310   s[nb] = '\0';
311   setsval(y, s + mb);
312   s[nb] = temp;
313@@ -1103,7 +1103,7 @@ sindex(Node **a, int nnn) /* index(a[0], a[1]) */
314     for (q = p1, p2 = s2; *p2 != '\0' && *q == *p2; q++, p2++)
315       continue;
316     if (*p2 == '\0') {
317-      /* v = (Awkfloat) (p1 - s1 + 1);	 origin 1 */
318+      /* v = (awkfloat) (p1 - s1 + 1); origin 1 */
319 
320       /* should be a function: used in match() as well */
321       int i, len;
322@@ -1123,7 +1123,7 @@ sindex(Node **a, int nnn) /* index(a[0], a[1]) */
323 
324 int
325 has_utf8(char *s) /* return 1 if s contains any utf-8 (2 bytes or more)
326-         character */
327+ * character */
328 {
329   int n;
330 
331@@ -1189,7 +1189,7 @@ format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like conver
332             "of memory",
333             os
334         );
335-      /* Ignore size specifiers */
336+      /* ignore size specifiers */
337       if (strchr("hjLlqtz", *s) != NULL) { /* the ansi panoply */
338         t--;
339         continue;
340@@ -1289,7 +1289,7 @@ format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like conver
341         t = getsval(x);
342         n = strlen(t);
343         /* if simple format or no utf-8 in the string, sprintf
344-         * works */
345+ * works */
346         if (!has_utf8(t) || strcmp(fmt, "%s") == 0) {
347           if (fmtwd > n)
348             n = fmtwd;
349@@ -1306,7 +1306,7 @@ format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like conver
350         }
351 
352         /* get here if string has utf-8 chars and fmt is not
353-         * plain %s */
354+ * plain %s */
355         /* "%-w.ps", where -, w and .p are all optional */
356         /* '0' before the w is a flag character */
357         /* fmt points at % */
358@@ -1316,7 +1316,7 @@ format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like conver
359           ljust = 1;
360           f++;
361         }
362-        // flags '0' and '+' are recognized but skipped
363+        /* flags '0' and '+' are recognized but skipped */
364         if (f[0] == '0') {
365           f++;
366           if (f[0] == '+')
367@@ -1335,27 +1335,27 @@ format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like conver
368         }
369         if (prec > u8_strlen(t))
370           prec = u8_strlen(t);
371-        pad = wid > prec ? wid - prec : 0; // has to be >= 0
372+        pad = wid > prec ? wid - prec : 0; /* has to be >= 0 */
373         int i, k, n;
374 
375-        if (ljust) { // print prec chars from t, then pad blanks
376+        if (ljust) { /* print prec chars from t, then pad blanks */
377           n = u8_char2byte(t, prec);
378           for (k = 0; k < n; k++) {
379-            // putchar(t[k]);
380+            /* putchar(t[k]); */
381             *p++ = t[k];
382           }
383           for (i = 0; i < pad; i++) {
384-            // printf(" ");
385+            /* printf(" "); */
386             *p++ = ' ';
387           }
388-        } else { // print pad blanks, then prec chars from t
389+        } else { /* print pad blanks, then prec chars from t */
390           for (i = 0; i < pad; i++) {
391-            // printf(" ");
392+            /* printf(" "); */
393             *p++ = ' ';
394           }
395           n = u8_char2byte(t, prec);
396           for (k = 0; k < n; k++) {
397-            // putchar(t[k]);
398+            /* putchar(t[k]); */
399             *p++ = t[k];
400           }
401         }
402@@ -1365,17 +1365,17 @@ format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like conver
403 
404       case 'c': {
405         /*
406-         * If a numeric value is given, awk should just turn
407-         * it into a character and print it:
408-         *      BEGIN { printf("%c\n", 65) }
409-         * prints "A".
410-         *
411-         * But what if the numeric value is > 128 and
412-         * represents a valid Unicode code point?!? We do
413-         * our best to convert it back into UTF-8. If we
414-         * can't, we output the encoding of the Unicode
415-         * "invalid character", 0xFFFD.
416-         */
417+ * if a numeric value is given, awk should just turn
418+ * it into a character and print it:
419+ * BEGIN { printf("%c\n", 65) }
420+ * prints "a"
421+ *
422+ * but what if the numeric value is > 128 and
423+ * represents a valid unicode code point?!? we do
424+ * our best to convert it back into UTF-8. if we
425+ * cant, we output the encoding of the unicode
426+ * "invalid character", 0xfffd
427+ */
428         if (isnum(x)) {
429           int charval = (int)getfval(x);
430 
431@@ -1383,13 +1383,13 @@ format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like conver
432             if (charval < 128 || awk_mb_cur_max == 1)
433               snprintf(p, BUFSZ(p), fmt, charval);
434             else {
435-              // possible unicode character
436+              /* possible unicode character */
437               size_t count;
438               char  *bs = wide_char_to_byte_str(charval, &count);
439 
440-              if (bs == NULL) { // invalid character
441-                // use unicode invalid
442-                // character, 0xFFFD
443+              if (bs == NULL) { /* invalid character */
444+                /* use unicode invalid
445+                 * character, 0xfffd */
446                 static char invalid_char[] = "\357\277"
447                                              "\275";
448                 bs                         = invalid_char;
449@@ -1402,7 +1402,7 @@ format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like conver
450           } else {
451             *p++ = '\0'; /* explicit null byte */
452             *p   = '\0'; /* next output will start
453-                here */
454+ * here */
455           }
456           break;
457         }
458@@ -1414,14 +1414,14 @@ format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like conver
459           break;
460         }
461 
462-        // utf8 character, almost same song and dance as for %s
463+        /* utf8 character, almost same song and dance as for %s */
464         int   ljust = 0, wid = 0, prec = n, pad = 0;
465         char *f = fmt + 1;
466         if (f[0] == '-') {
467           ljust = 1;
468           f++;
469         }
470-        // flags '0' and '+' are recognized but skipped
471+        /* flags '0' and '+' are recognized but skipped */
472         if (f[0] == '0') {
473           f++;
474           if (f[0] == '+')
475@@ -1438,21 +1438,21 @@ format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like conver
476         if (f[0] == '.') { /* there is a .prec */
477           prec = strtol(++f, &f, 10);
478         }
479-        if (prec > 1) // %c --> only one character
480+        if (prec > 1) /* %c: only one character */
481           prec = 1;
482-        pad = wid > prec ? wid - prec : 0; // has to be >= 0
483+        pad = wid > prec ? wid - prec : 0; /* has to be >= 0 */
484         int i;
485 
486-        if (ljust) { // print one char from t, then pad blanks
487+        if (ljust) { /* print one char from t, then pad blanks */
488           for (i = 0; i < n; i++)
489             *p++ = t[i];
490           for (i = 0; i < pad; i++) {
491-            // printf(" ");
492+            /* printf(" "); */
493             *p++ = ' ';
494           }
495-        } else { // print pad blanks, then prec chars from t
496+        } else { /* print pad blanks, then prec chars from t */
497           for (i = 0; i < pad; i++) {
498-            // printf(" ");
499+            /* printf(" "); */
500             *p++ = ' ';
501           }
502           for (i = 0; i < n; i++)
503@@ -1537,7 +1537,7 @@ awkprintf(Node **a, int n) /* printf */
504 }
505 
506 Cell *
507-arith(Node **a, int n) /* a[0] + a[1], etc.  also -a[0] */
508+arith(Node **a, int n) /* a[0] + a[1], etc. also -a[0] */
509 {
510   Awkfloat i, j = 0;
511   double   v;
512@@ -1584,7 +1584,7 @@ arith(Node **a, int n) /* a[0] + a[1], etc.  also -a[0] */
513       else
514         i = pow_errcheck(i, j);
515       break;
516-    default: /* can't happen */
517+    default: /* cant happen */
518       FATAL("illegal arithmetic operator %d", n);
519   }
520   setfval(z, i);
521@@ -1592,7 +1592,7 @@ arith(Node **a, int n) /* a[0] + a[1], etc.  also -a[0] */
522 }
523 
524 double
525-ipow(double x, int n) /* x**n.  ought to be done by pow, but isn't always */
526+ipow(double x, int n) /* x**n. ought to be done by pow, but isnt always */
527 {
528   double v;
529 
530@@ -1606,7 +1606,7 @@ ipow(double x, int n) /* x**n.  ought to be done by pow, but isn't always */
531 }
532 
533 Cell *
534-incrdecr(Node **a, int n) /* a[0]++, etc. */
535+incrdecr(Node **a, int n) /* a[0]++, etc */
536 {
537   Cell    *x, *z;
538   int      k;
539@@ -1627,8 +1627,8 @@ incrdecr(Node **a, int n) /* a[0]++, etc. */
540 }
541 
542 Cell *
543-assign(Node **a, int n) /* a[0] = a[1], a[0] += a[1], etc. */
544-{                       /* this is subtle; don't muck with it. */
545+assign(Node **a, int n) /* a[0] = a[1], a[0] += a[1], etc */
546+{                       /* this is subtle; dont muck with it */
547   Cell    *x, *y;
548   Awkfloat xf, yf;
549   double   v;
550@@ -1637,8 +1637,8 @@ assign(Node **a, int n) /* a[0] = a[1], a[0] += a[1], etc. */
551   x = execute(a[0]);
552   if (n == ASSIGN) { /* ordinary assignment */
553     if (x == y && !(x->tval & (FLD | REC)) && x != nfloc)
554-      ; /* self-assignment: leave alone unless it's a field or
555-           NF */
556+      ; /* self-assignment: leave alone unless its a field or
557+ * NF */
558     else if ((y->tval & (STR | NUM)) == (STR | NUM)) {
559       yf = getfval(y);
560       setsval(x, getsval(y));
561@@ -1794,7 +1794,7 @@ split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
562   }
563   sep = *fs;
564   ap  = execute(a[1]); /* array name */
565-  /* BUG 7/26/22: this appears not to reset array: see C1/asplit */
566+  /* BUG 7/26/22: this appears not to reset array: see c1/asplit */
567   freesymtab(ap);
568   DPRINTF("split: s=|%s|, a=%s, sep=|%s|\n", s, NN(ap->nval), fs);
569   ap->tval &= ~STR;
570@@ -1803,7 +1803,7 @@ split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
571 
572   n = 0;
573   if (arg3type == REGEXPR && strlen((char *)((fa *)a[2])->restr) == 0) {
574-    /* split(s, a, //); have to arrange that it looks like empty sep
575+    /* split(s, a, // ); have to arrange that it looks like empty sep
576      */
577     arg3type = 0;
578     fs       = "";
579@@ -1811,7 +1811,7 @@ split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
580   }
581   if (*s != '\0' && (strlen(fs) > 1 || arg3type == REGEXPR)) { /* reg expr */
582     fa *pfa;
583-    if (arg3type == REGEXPR) { /* it's ready already */
584+    if (arg3type == REGEXPR) { /* its ready already */
585       pfa = (fa *)a[2];
586     } else {
587       pfa = makedfa(fs, 1);
588@@ -1864,7 +1864,7 @@ split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
589             *fr++ = '"';
590           } else if (*s == '"' && (s[1] == '\0' || s[1] == ',')) {
591             s++; /* skip over closing quote
592-                  */
593+ */
594             break;
595           } else {
596             *fr++ = *s++;
597@@ -2109,11 +2109,11 @@ nawk_convert(const char *s, int (*fun_c)(int), wint_t (*fun_wc)(wint_t))
598 
599     (void)mbtowc(NULL, NULL, 0); /* reset internal state */
600     /*
601-     * Reset internal state here too.
602-     * Assign result to avoid a compiler warning. (Casting to void
603-     * doesn't work.)
604-     * Increment said variable to avoid a different warning.
605-     */
606+ * reset internal state here too
607+ * assign result to avoid a compiler warning. (casting to void
608+ * doesnt work.)
609+ * increment said variable to avoid a different warning
610+ */
611     unused = wctomb(NULL, L'\0');
612     unused++;
613 
614@@ -2189,7 +2189,7 @@ bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg list */
615   switch (t) {
616     case FLENGTH:
617       if (isarr(x))
618-        u = ((Array *)x->sval)->nelem; /* GROT.  should be function*/
619+        u = ((Array *)x->sval)->nelem; /* GROT. should be function */
620       else
621         u = u8_strlen(getsval(x));
622       break;
623@@ -2242,13 +2242,13 @@ bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg list */
624       break;
625     case FRAND:
626       /* random() returns numbers in [0..2^31-1]
627-       * in order to get a number in [0, 1), divide it by 2^31
628-       */
629+ * in order to get a number in [0, 1), divide it by 2^31
630+ */
631       do {
632-        /* exact if Awkfloat wide enough */
633+        /* exact if awkfloat wide enough */
634         u = (Awkfloat)random();
635         u /= 0x80000000; /* should be exact */
636-      } while (u >= 1.0); /* in case Awkfloat is narrow */
637+      } while (u >= 1.0); /* in case awkfloat is narrow */
638       break;
639     case FSRAND:
640       if (isrec(x)) /* no argument provided */
641@@ -2280,7 +2280,7 @@ bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg list */
642       else
643         u = fflush(fp);
644       break;
645-    default: /* can't happen */
646+    default: /* cant happen */
647       FATAL("illegal function type %d", t);
648       break;
649   }
650@@ -2391,7 +2391,7 @@ openfile(int a, const char *us, bool *pnewflag)
651         *pnewflag = false;
652       return files[i].fp;
653     }
654-  if (a == FFLUSH) /* didn't find it, so don't create it! */
655+  if (a == FFLUSH) /* didn't find it, so dont create it! */
656     return NULL;
657   for (i = 0; i < nfiles; i++)
658     if (files[i].fp == NULL)
659@@ -2409,7 +2409,7 @@ openfile(int a, const char *us, bool *pnewflag)
660 
661   fflush(stdout); /* force a semblance of order */
662 
663-  /* don't try to read or write a directory */
664+  /* dont try to read or write a directory */
665   if (a == LT || a == GT || a == APPEND)
666     if (stat(s, &sbuf) == 0 && S_ISDIR(sbuf.st_mode))
667       return NULL;
668@@ -2426,7 +2426,7 @@ openfile(int a, const char *us, bool *pnewflag)
669     fp = popen(s, "r");
670   } else if (a == LT) {                               /* getline <file */
671     fp = strcmp(s, "-") == 0 ? stdin : fopen(s, "r"); /* "-" is stdin */
672-  } else                                              /* can't happen */
673+  } else                                              /* cant happen */
674     FATAL("illegal redirection %d", a);
675   if (fp != NULL) {
676     files[i].fname = tostring(s);
677@@ -2724,18 +2724,18 @@ wide_char_to_byte_str(int rune, size_t *outlen)
678   if (rune <= 0x0000007F) {
679     buf[len++] = rune;
680   } else if (rune <= 0x000007FF) {
681-    // 110xxxxx 10xxxxxx
682+    /* 110xxxxx 10xxxxxx */
683     buf[len++] = 0xC0 | (rune >> 6);
684     buf[len++] = 0x80 | (rune & 0x3F);
685   } else if (rune <= 0x0000FFFF) {
686-    // 1110xxxx 10xxxxxx 10xxxxxx
687+    /* 1110xxxx 10xxxxxx 10xxxxxx */
688     buf[len++] = 0xE0 | (rune >> 12);
689     buf[len++] = 0x80 | ((rune >> 6) & 0x3F);
690     buf[len++] = 0x80 | (rune & 0x3F);
691 
692   } else {
693-    // 0x00010000 - 0x10FFFF
694-    // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
695+    /* 0x00010000 - 0x10ffff
696+     * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
697     buf[len++] = 0xF0 | (rune >> 18);
698     buf[len++] = 0x80 | ((rune >> 12) & 0x3F);
699     buf[len++] = 0x80 | ((rune >> 6) & 0x3F);
+59, -59
  1@@ -1,26 +1,26 @@
  2-/****************************************************************
  3-Copyright (C) Lucent Technologies 1997
  4-All Rights Reserved
  5-
  6-Permission to use, copy, modify, and distribute this software and
  7-its documentation for any purpose and without fee is hereby
  8-granted, provided that the above copyright notice appear in all
  9-copies and that both that the copyright notice and this
 10-permission notice and warranty disclaimer appear in supporting
 11-documentation, and that the name Lucent Technologies or any of
 12-its entities not be used in advertising or publicity pertaining
 13-to distribution of the software without specific, written prior
 14-permission.
 15-
 16-LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 17-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
 18-IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
 19-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 20-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 21-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 22-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 23-THIS SOFTWARE.
 24-****************************************************************/
 25+/* ***************************************************************
 26+ * copyright (c) lucent technologies 1997
 27+ * all rights reserved
 28+ *
 29+ * permission to use, copy, modify, and distribute this software and
 30+ * its documentation for any purpose and without fee is hereby
 31+ * granted, provided that the above copyright notice appear in all
 32+ * copies and that both that the copyright notice and this
 33+ * permission notice and warranty disclaimer appear in supporting
 34+ * documentation, and that the name lucent technologies or any of
 35+ * its entities not be used in advertising or publicity pertaining
 36+ * to distribution of the software without specific, written prior
 37+ * permission
 38+ *
 39+ * LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 40+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 41+ * IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
 42+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 43+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 44+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 45+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 46+ * THIS SOFTWARE
 47+ * ************************************************************** */
 48 
 49 #define DEBUG
 50 #include "awk.h"
 51@@ -283,8 +283,8 @@ rehash(Array *tp) /* rehash items in small table into big one */
 52 
 53   nsz = GROWTAB * tp->size;
 54   np  = (Cell **)calloc(nsz, sizeof(*np));
 55-  if (np == NULL) /* can't do it, but can keep running. */
 56-    return;       /* someone else will run out later. */
 57+  if (np == NULL) /* cant do it, but can keep running */
 58+    return;       /* someone else will run out later */
 59   for (i = 0; i < tp->size; i++) {
 60     for (cp = tp->tab[i]; cp; cp = op) {
 61       op        = cp->cnext;
 62@@ -312,7 +312,7 @@ lookup(const char *s, Array *tp) /* look for s in tp */
 63 }
 64 
 65 Awkfloat
 66-setfval(Cell *vp, Awkfloat f) /* set float val of a Cell */
 67+setfval(Cell *vp, Awkfloat f) /* set float val of a cell */
 68 {
 69   int fldno;
 70 
 71@@ -366,7 +366,7 @@ funnyvar(Cell *vp, const char *rw)
 72 }
 73 
 74 char *
 75-setsval(Cell *vp, const char *s) /* set string val of a Cell */
 76+setsval(Cell *vp, const char *s) /* set string val of a cell */
 77 {
 78   char    *t;
 79   int      fldno;
 80@@ -401,7 +401,7 @@ setsval(Cell *vp, const char *s) /* set string val of a Cell */
 81     if (!donerec)
 82       recbld();
 83   }
 84-  t = s ? tostring(s) : tostring(""); /* in case it's self-assign */
 85+  t = s ? tostring(s) : tostring(""); /* in case its self-assign */
 86   if (freeable(vp))
 87     xfree(vp->sval);
 88   vp->tval &= ~(NUM | DONTFREE | CONVC | CONVO);
 89@@ -429,7 +429,7 @@ setsval(Cell *vp, const char *s) /* set string val of a Cell */
 90 }
 91 
 92 Awkfloat
 93-getfval(Cell *vp) /* get float val of a Cell */
 94+getfval(Cell *vp) /* get float val of a cell */
 95 {
 96   if ((vp->tval & (NUM | STR)) == 0)
 97     funnyvar(vp, "read value of");
 98@@ -464,7 +464,7 @@ get_inf_nan(double d)
 99 }
100 
101 static char *
102-get_str_val(Cell *vp, char **fmt) /* get string val of a Cell */
103+get_str_val(Cell *vp, char **fmt) /* get string val of a cell */
104 {
105   char        s[256];
106   double      dtemp;
107@@ -478,36 +478,36 @@ get_str_val(Cell *vp, char **fmt) /* get string val of a Cell */
108     recbld();
109 
110   /*
111-   * ADR: This is complicated and more fragile than is desirable.
112-   * Retrieving a string value for a number associates the string
113-   * value with the scalar.  Previously, the string value was
114-   * sticky, meaning if converted via OFMT that became the value
115-   * (even though POSIX wants it to be via CONVFMT). Or if CONVFMT
116-   * changed after a string value was retrieved, the original value
117-   * was maintained and used.  Also not per POSIX.
118-   *
119-   * We work around this design by adding two additional flags,
120-   * CONVC and CONVO, indicating how the string value was
121-   * obtained (via CONVFMT or OFMT) and _also_ maintaining a copy
122-   * of the pointer to the xFMT format string used for the
123-   * conversion.  This pointer is only read, **never** dereferenced.
124-   * The next time we do a conversion, if it's coming from the same
125-   * xFMT as last time, and the pointer value is different, we
126-   * know that the xFMT format string changed, and we need to
127-   * redo the conversion. If it's the same, we don't have to.
128-   *
129-   * There are also several cases where we don't do a conversion,
130-   * such as for a field (see the checks below).
131-   */
132-
133-  /* Don't duplicate the code for actually updating the value */
134+ * ADR: this is complicated and more fragile than is desirable
135+ * retrieving a string value for a number associates the string
136+ * value with the scalar. previously, the string value was
137+ * sticky, meaning if converted via OFMT that became the value
138+ * (even though POSIX wants it to be via CONVFMT). or if CONVFMT
139+ * changed after a string value was retrieved, the original value
140+ * was maintained and used. also not per POSIX
141+ *
142+ * we work around this design by adding two additional flags,
143+ * CONVC and CONVO, indicating how the string value was
144+ * obtained (via CONVFMT or OFMT) and _also_ maintaining a copy
145+ * of the pointer to the xfmt format string used for the
146+ * conversion. this pointer is only read, **never** dereferenced
147+ * the next time we do a conversion, if its coming from the same
148+ * xfmt as last time, and the pointer value is different, we
149+ * know that the xfmt format string changed, and we need to
150+ * redo the conversion. if its the same, we dont have to
151+ *
152+ * there are also several cases where we dont do a conversion,
153+ * such as for a field (see the checks below)
154+ */
155+
156+  /* dont duplicate the code for actually updating the value */
157 #define update_str_val(vp)                                                                         \
158   {                                                                                                \
159     if (freeable(vp))                                                                              \
160       xfree(vp->sval);                                                                             \
161     if ((p = get_inf_nan(vp->fval)) != NULL)                                                       \
162       strcpy(s, p);                                                                                \
163-    else if (modf(vp->fval, &dtemp) == 0) /* it's integral */                                      \
164+    else if (modf(vp->fval, &dtemp) == 0) /* its integral */                                      \
165       snprintf(s, sizeof(s), "%.30g", vp->fval);                                                   \
166     else                                                                                           \
167       snprintf(s, sizeof(s), *fmt, vp->fval);                                                      \
168@@ -560,13 +560,13 @@ done:
169 }
170 
171 char *
172-getsval(Cell *vp) /* get string val of a Cell */
173+getsval(Cell *vp) /* get string val of a cell */
174 {
175   return get_str_val(vp, CONVFMT);
176 }
177 
178 char *
179-getpssval(Cell *vp) /* get string val of a Cell for print */
180+getpssval(Cell *vp) /* get string val of a cell for print */
181 {
182   return get_str_val(vp, OFMT);
183 }
184@@ -605,12 +605,12 @@ catstr(Cell *a, Cell *b) /* concatenate a and b */
185     FATAL("out of space concatenating %s and %s", sa, sb);
186   snprintf(p, l, "%s%s", sa, sb);
187 
188-  l++; // add room for ' '
189+  l++; /* add room for ' ' */
190   char *newbuf = (char *)malloc(l);
191   if (newbuf == NULL)
192     FATAL("out of space concatenating %s and %s", sa, sb);
193-  // See string() in lex.c; a string "xx" is stored in the symbol
194-  // table as "xx ".
195+  /* see string() in lex.c; a string "xx" is stored in the symbol
196+   * table as "xx " */
197   snprintf(newbuf, l, "%s ", p);
198   c = setsymtab(newbuf, p, 0.0, CON | STR | DONTFREE, symtab);
199   free(p);
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <libgen.h>
6 #include <stdio.h>
+230, -39
  1@@ -38,7 +38,7 @@ static void quit(void);
  2 static char *code(char *, ...);
  3 static char *forcode(Macro *, char *, char *, char *, char *);
  4 static char *whilecode(Macro *, char *, char *);
  5-static char *ifcode(Macro *, char *, char *);
  6+static char *ifcode(Macro *, char *, char *, char *);
  7 static char *funcode(Macro *, char *, char *, char *);
  8 static char *param(char *, char *), *local(char *, char *);
  9 static char *retcode(char *);
 10@@ -51,6 +51,7 @@ static char *ary(char *);
 11 static void writeout(char *);
 12 
 13 static char *yytext, *buff, *unwind;
 14+static size_t buffcap;
 15 static char *filename;
 16 static FILE *filep;
 17 static int lineno, nerr, flowid;
 18@@ -65,7 +66,7 @@ static char *dcprog = "dc";
 19 
 20 %union {
 21 	char *str;
 22-	char id[2];
 23+	char id[16]; // matches dc's own REGSIZ: an extended register name's cap
 24 	Macro *macro;
 25 }
 26 
 27@@ -92,10 +93,14 @@ static char *dcprog = "dc";
 28 %token OBASE
 29 %token AUTO PARAM
 30 %token PRINT
 31+%token ELSE
 32+%token HALT
 33+%token READ
 34 
 35 %type <str> item statlst scolonlst
 36 %type <str> function assign nexpr expr exprstat rel stat ary cond
 37 %type <str> autolst arglst parlst
 38+%type <str> prlst pritem
 39 %type <str> params param locals local
 40 %type <macro> def if for while
 41 
 42@@ -134,19 +139,41 @@ statlst :                       {$$ = code("");}
 43         ;
 44 
 45 stat    : exprstat
 46-        | PRINT expr            {$$ = code("%sps.", $2);}
 47-        | PRINT STRING          {$$ = code("[%s]P", $2);}
 48-        | PRINT STRING ',' expr {$$ = code("[%s]P%sps.", $2, $4);}
 49+        | PRINT prlst           {$$ = $2;}
 50         | STRING                {$$ = code("[%s]P", $1);}
 51         | BREAK                 {$$ = brkcode();}
 52         | QUIT                  {quit();}
 53+        | HALT                  {$$ = code("q");}
 54         | RETURN                {$$ = retcode(code(" 0"));}
 55-        | RETURN '(' expr ')'   {$$ = retcode($3);}
 56+        | RETURN expr           {$$ = retcode($2);}
 57         | RETURN '(' ')'        {$$ = retcode(code(" 0"));}
 58-        | while cond stat       {$$ = whilecode($1, $2, $3);}
 59-        | if cond stat          {$$ = ifcode($1, $2, $3);}
 60+        | while cond optnl stat       {$$ = whilecode($1, $2, $4);}
 61+        | if cond optnl stat          {$$ = ifcode($1, $2, $4, NULL);}
 62+        | if cond optnl stat ELSE optnl stat  {$$ = ifcode($1, $2, $4, $7);}
 63         | '{' statlst '}'       {$$ = $2;}
 64-        | for '(' expr ';' rel ';' expr ')' stat  {$$ = forcode($1, $3, $5, $7, $9);}
 65+        | for '(' expr ';' rel ';' expr ')' optnl stat  {$$ = forcode($1, $3, $5, $7, $10);}
 66+        ;
 67+
 68+// real scripts routinely put a while/if/for's own body on the next
 69+// line instead of right after the condition; nothing else in this
 70+// grammar needs a newline here, since a body wrapped in { } already
 71+// goes through statlst, which handles its own internal newlines
 72+optnl   :
 73+        | optnl '\n'
 74+        ;
 75+
 76+// print takes a comma-separated list of any length, mixing strings
 77+// and expressions freely: real scripts (the kernel's own timeconst.bc
 78+// generator among them) routinely print three or more at once. no
 79+// item here ever gets an automatic trailing newline of its own,
 80+// matching real bc: whatever newlines appear come from the items
 81+// themselves
 82+prlst   : pritem
 83+        | prlst ',' pritem      {$$ = code("%s%s", $1, $3);}
 84+        ;
 85+
 86+pritem  : expr                  {$$ = code("%sn", $1);}
 87+        | STRING                {$$ = code("[%s]P", $1);}
 88         ;
 89 
 90 while   : WHILE                 {$$ = macro(LOOP);}
 91@@ -214,6 +241,7 @@ expr    : nexpr
 92 
 93 nexpr   : NUMBER                {$$ = code(" %s", code($1));}
 94         | ID                    {$$ = code("l%s", var($1));}
 95+        | READ '(' ')'          {$$ = code("?");}
 96         | DOT                   {$$ = code("l.");}
 97         | SCALE                 {$$ = code("K");}
 98         | IBASE                 {$$ = code("I");}
 99@@ -277,21 +305,38 @@ writeout(char *s)
100 		goto err;
101 	free(s);
102 	return;
103-	
104+
105 err:
106 	eprintf("writing to dc:");
107 }
108 
109+// grows the shared code buffer geometrically to fit at least 'need'
110+// bytes: a single generated dc macro (an if/else body, a print list,
111+// a deeply nested function) has no fixed upper bound, unlike the
112+// stdio-buffering constant BUFSIZ this buffer borrowed its original
113+// size from
114+static void
115+growbuff(size_t need)
116+{
117+	size_t newcap;
118+
119+	newcap = buffcap;
120+	while (newcap < need)
121+		newcap *= 2;
122+	buff    = erealloc(buff, newcap);
123+	buffcap = newcap;
124+}
125+
126 static char *
127 code(char *fmt, ...)
128 {
129-	char *s, *t;
130+	char  *t;
131 	va_list ap;
132-	int c, len, room;
133+	int    c, len;
134+	size_t off, room;
135 
136 	va_start(ap, fmt);
137-	room = BUFSIZ;
138-	for (s = buff; *fmt; s += len) {
139+	for (off = 0; *fmt; off += (size_t)len) {
140 		len = 1;
141 		if ((c = *fmt++) != '%')
142 			goto append;
143@@ -299,41 +344,41 @@ code(char *fmt, ...)
144 		switch (*fmt++) {
145 		case 'd':
146 			c = va_arg(ap, int);
147-			len = snprintf(s, room, "%d", c);
148-			if (len < 0 || len >= room)
149-				goto err;
150+			for (;;) {
151+				room = buffcap - off;
152+				len  = snprintf(buff + off, room, "%d", c);
153+				if (len < 0)
154+					eprintf("unable to code requested operation\n");
155+				if ((size_t)len < room)
156+					break;
157+				growbuff(off + (size_t)len + 1);
158+			}
159 			break;
160 		case 'c':
161 			c = va_arg(ap, int);
162 			goto append;
163 		case 's':
164-			t = va_arg(ap, void *);
165+			t   = va_arg(ap, void *);
166 			len = strlen(t);
167-			if (len >= room)
168-				goto err;
169-			memcpy(s, t, len);
170+			if ((size_t)len >= buffcap - off)
171+				growbuff(off + (size_t)len + 1);
172+			memcpy(buff + off, t, len);
173 			free(t);
174 			break;
175 		case '%':
176 		append:
177-			if (room <= 1)
178-				goto err;
179-			*s = c;
180+			if (buffcap - off <= 1)
181+				growbuff(off + 2);
182+			buff[off] = c;
183 			break;
184 		default:
185 			abort();
186 		}
187-
188-		room -= len;
189 	}
190 	va_end(ap);
191 
192-	*s = '\0';
193+	buff[off] = '\0';
194 	return estrdup(buff);
195-
196-err:
197-	eprintf("unable to code requested operation\n");
198-	return NULL;
199 }
200 
201 static Macro *
202@@ -493,17 +538,72 @@ whilecode(Macro *d, char *cmp, char *body)
203 	return s;
204 }
205 
206+// the trailing relational operator on a cond's own generated code
207+// (see the rel grammar rule) is always one of these six forms; an
208+// else branch runs on whichever of them means "the opposite happened"
209 static char *
210-ifcode(Macro *d, char *cmp, char *body)
211+invertrel(char *cmp)
212 {
213+	size_t n = strlen(cmp);
214+	const char *suffix;
215+	size_t keep;
216 	char *s;
217 
218+	if (n >= 2 && strcmp(cmp + n - 2, "!=") == 0) {
219+		keep = n - 2;
220+		suffix = "=";
221+	} else if (n >= 2 && strcmp(cmp + n - 2, "!<") == 0) {
222+		keep = n - 2;
223+		suffix = "<";
224+	} else if (n >= 2 && strcmp(cmp + n - 2, "!>") == 0) {
225+		keep = n - 2;
226+		suffix = ">";
227+	} else if (n >= 1 && cmp[n - 1] == '=') {
228+		keep = n - 1;
229+		suffix = "!=";
230+	} else if (n >= 1 && cmp[n - 1] == '<') {
231+		keep = n - 1;
232+		suffix = "!<";
233+	} else if (n >= 1 && cmp[n - 1] == '>') {
234+		keep = n - 1;
235+		suffix = "!>";
236+	} else {
237+		yyerror("cannot invert comparison for else");
238+		return NULL;
239+	}
240+
241+	s = emalloc(keep + strlen(suffix) + 1);
242+	memcpy(s, cmp, keep);
243+	strcpy(s + keep, suffix);
244+
245+	return s;
246+}
247+
248+// an else branch's own stored body needs a register distinct from the
249+// then branch's d->id: nested caps how high d->id itself ever goes,
250+// so offsetting by it lands on a register no other nesting level, and
251+// no ordinary (single-letter or, under -i, named) variable, ever uses
252+static char *
253+ifcode(Macro *d, char *cmp, char *body, char *ebody)
254+{
255+	char *s, *inv;
256+
257 	s = code(sflag ? "[%s]s<%d>" : "[%s]s%c",
258 	         body, d->id);
259 	writeout(s);
260 
261-	s = code(sflag ? "%s<%d> " : "%s%c ",
262-	         cmp, d->id);
263+	if (ebody) {
264+		s = code(sflag ? "[%s]s<%d>" : "[%s]s%c",
265+		         ebody, d->id + NESTED_MAX);
266+		writeout(s);
267+
268+		inv = invertrel(cmp);
269+		s = code(sflag ? "%s<%d> %s<%d> " : "%s%c %s%c ",
270+		         cmp, d->id, inv, d->id + NESTED_MAX);
271+	} else {
272+		s = code(sflag ? "%s<%d> " : "%s%c ",
273+		         cmp, d->id);
274+	}
275 	nested--;
276 
277 	return s;
278@@ -582,6 +682,9 @@ iden(int ch)
279 		{"obase", OBASE},
280 		{"auto", AUTO},
281 		{"print", PRINT},
282+		{"else", ELSE},
283+		{"halt", HALT},
284+		{"read", READ},
285 		{NULL}
286 	};
287 	struct keyword *p;
288@@ -610,8 +713,16 @@ iden(int ch)
289 	if (p->str)
290 		return p->token;
291 
292+	// strict POSIX bc only ever names a variable/function with a
293+	// single lowercase letter; every real bc script in the wild
294+	// (the kernel's own timeconst.bc among them) freely uses
295+	// multi-character names anyway, same as GNU bc's own default
296+#if !FEATURE_BC_MULTICHAR
297 	if (!sflag)
298 		yyerror("invalid keyword");
299+#endif
300+	if (strlen(yytext) >= sizeof(yylval.id))
301+		yyerror("identifier too long");
302 	strcpy(yylval.id, yytext);
303 	return ID;
304 }
305@@ -676,6 +787,50 @@ string(int ch)
306 	for (bp = yytext; bp < &yytext[BUFSIZ]; ++bp) {
307 		if ((ch = getc(filep)) == '"')
308 			break;
309+#if FEATURE_BC_ESCAPES
310+		// strict POSIX bc has no escape sequences in a string at
311+		// all; every real script (again, the kernel's own scripts
312+		// among them) assumes GNU bc's \n/\t/etc, since dc's own
313+		// string reader passes a literal byte straight through
314+		// with nothing left to turn it into a real newline later
315+		if (ch == '\\') {
316+			switch (ch = getc(filep)) {
317+			case 'a':
318+				ch = '\a';
319+				break;
320+			case 'b':
321+				ch = '\b';
322+				break;
323+			case 'f':
324+				ch = '\f';
325+				break;
326+			case 'n':
327+				ch = '\n';
328+				break;
329+			case 'r':
330+				ch = '\r';
331+				break;
332+			case 't':
333+				ch = '\t';
334+				break;
335+			case 'v':
336+				ch = '\v';
337+				break;
338+			case 'q':
339+				// GNU bc's own escape for a literal double
340+				// quote, needed since a bc string's own
341+				// delimiter is " with no other way in
342+				ch = '"';
343+				break;
344+			case '\\':
345+			case '"':
346+				break;
347+			default:
348+				*bp++ = '\\';
349+				break;
350+			}
351+		}
352+#endif
353 		*bp = ch;
354 	}
355 
356@@ -808,9 +963,27 @@ static void
357 spawn(void)
358 {
359 	int fds[2];
360+	// dc only accepts the extended, multi-character register
361+	// syntax bc.y's own ftn()/var()/ary() emit for a non-single-
362+	// letter name (see iden() above) when told -i: whenever this
363+	// build can produce that syntax at all, dc always needs it
364+#if FEATURE_BC_MULTICHAR
365+	char *par = "-i";
366+#else
367 	char *par = sflag ? "-i" : NULL;
368+#endif
369 	char errmsg[] = "bc:error execing dc\n";
370 
371+	// fd 0 is about to become the read end of the code pipe below,
372+	// but dc's own "?" (bc's read()) needs the real, original stdin:
373+	// stash it on a fixed fd dc knows to check, or read() would read
374+	// straight out of this project's own generated dc code instead
375+	// of whatever the user actually piped in. this has to happen
376+	// before pipe() claims its own two fds, or dup2 here could
377+	// clobber one of them (fd 3 is often the next one pipe() itself
378+	// would have picked)
379+	dup2(0, 3);
380+
381 	if (pipe(fds) < 0)
382 		eprintf("creating pipe:");
383 
384@@ -872,7 +1045,11 @@ bc(char *fname)
385 static void
386 usage(void)
387 {
388+#if FEATURE_BC_QUIET
389+	eprintf("usage: %s [-p dc][-cdlqs]\n", argv0);
390+#else
391 	eprintf("usage: %s [-p dc][-cdls]\n", argv0);
392+#endif
393 }
394 
395 int
396@@ -892,6 +1069,11 @@ main(int argc, char *argv[])
397 	case 'l':
398 		lflag = 1;
399 		break;
400+#if FEATURE_BC_QUIET
401+	// for compat with sucky impls
402+	case 'q':
403+		break;
404+#endif
405 	case 's':
406 		sflag = 1;
407 		break;
408@@ -899,8 +1081,9 @@ main(int argc, char *argv[])
409 		usage();
410 	} ARGEND
411 
412-	yytext = malloc(BUFSIZ);
413-	buff = malloc(BUFSIZ);
414+	yytext  = malloc(BUFSIZ);
415+	buffcap = BUFSIZ;
416+	buff    = malloc(buffcap);
417 	if (!yytext || !buff)
418 		eprintf("out of memory\n");
419 	flowid = 128;
420@@ -910,9 +1093,17 @@ main(int argc, char *argv[])
421 	if (lflag)
422 		bc(PREFIX "/share/misc/bc.library");
423 
424-	while (*argv)
425-		bc(*argv++);
426-	bc(NULL);
427+	// stdin is only the script source when no file was given at all:
428+	// a real file argument alongside piped stdin data (the kernel's
429+	// own "echo $HZ | bc -q file.bc" being the standing example) means
430+	// that data is meant for read(), not for bc itself to parse as
431+	// more of the program
432+	if (!*argv) {
433+		bc(NULL);
434+	} else {
435+		while (*argv)
436+			bc(*argv++);
437+	}
438 
439 	quit();
440 }
+8, -8
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <limits.h>
 6 #include <stdint.h>
 7@@ -25,7 +25,7 @@ isleap(size_t year, enum caltype cal)
 8     if (year % 100 == 0)
 9       return 0;
10     return (year % 4 == 0);
11-  } else { /* cal == Julian */
12+  } else { /* cal == julian */
13     return (year % 4 == 0);
14   }
15 }
16@@ -38,7 +38,7 @@ monthlength(size_t year, int month, enum caltype cal)
17   return (month == FEB && isleap(year, cal)) ? 29 : mdays[month];
18 }
19 
20-/* From http://www.tondering.dk/claus/cal/chrweek.php#calcdow */
21+/* From http:// www.tondering.dk/claus/cal/chrweek.php#calcdow */
22 static int
23 dayofweek(size_t year, int month, int dom, enum caltype cal)
24 {
25@@ -51,7 +51,7 @@ dayofweek(size_t year, int month, int dom, enum caltype cal)
26 
27   if (cal == GREGORIAN)
28     return (dom + y + y / 4 - y / 100 + y / 400 + (31 * m) / 12) % 7;
29-  else /* cal == Julian */
30+  else /* cal == julian */
31     return (5 + dom + y + y / 4 + (31 * m) / 12) % 7;
32 }
33 
34@@ -59,7 +59,7 @@ static void
35 printgrid(size_t year, int month, int fday, int line)
36 {
37   enum caltype cal;
38-  int          offset, dom, d = 0, trans; /* are we in the transition from Julian to Gregorian? */
39+  int          offset, dom, d = 0, trans; /* are we in the transition from julian to gregorian? */
40   int          today = 0;
41 
42   cal    = (year < TRANS_YEAR || (year == TRANS_YEAR && month <= TRANS_MONTH)) ? JULIAN : GREGORIAN;
43@@ -187,7 +187,7 @@ main(int argc, char *argv[])
44   fday  = 0;
45 
46   if (!isatty(STDOUT_FILENO))
47-    ltime = NULL; /* don't highlight today's date */
48+    ltime = NULL; /* dont highlight today's date */
49 
50 #ifdef FEATURE_CAL_EXT
51   ncols = 3;
52@@ -223,7 +223,7 @@ main(int argc, char *argv[])
53       fday = estrtonum(EARGF(usage()), 0, 6);
54       break;
55     // ?man -m: specify mode or limit
56-    case 'm': /* Monday */
57+    case 'm': /* monday */
58       fday = 1;
59       break;
60     // ?man -n:num: print line numbers or counts
61@@ -233,7 +233,7 @@ main(int argc, char *argv[])
62       );
63       break;
64     // ?man -s: silent mode or print summary
65-    case 's': /* Sunday */
66+    case 's': /* sunday */
67       fday = 0;
68       break;
69 #endif
+2, -2
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <fcntl.h>
 6 #include <string.h>
 7@@ -62,7 +62,7 @@ main(int argc, char *argv[])
 8   // ?man ## Exit status
 9   // ?man
10   // ?man cat exits 0 on success, and >0 if an error occurs reading any
11-  // file ?man or writing to standard output ?man ?man ## See also ?man
12+  // file ?man or writing to standard output ?man ?man ## see also ?man
13   // ?man cp(1), dd(1)
14   // ?man
15 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/stat.h>
6 
+3, -3
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <fcntl.h>
 6 #include <sys/stat.h>
 7@@ -57,12 +57,12 @@ main(int argc, char *argv[])
 8         case 'X':
 9         case 's':
10         case 't':
11-          /* -[rwxXst] are valid modes, so we're done */
12+          /* -[rwxxst] are valid modes, so we're done */
13           if (i == 1)
14             goto done;
15           /* fallthrough */
16         case '-':
17-          /* -- terminator */
18+          /* "--" option terminator */
19           if (i == 1 && !(*argv)[i + 1]) {
20             argv++;
21             argc--;
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <errno.h>
6 #include <fcntl.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <fcntl.h>
6 #include <inttypes.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdio.h>
6 #include <stdlib.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdio.h>
6 #include <stdlib.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/stat.h>
6 
+16, -15
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <stdio.h>
 6 #include <stdlib.h>
 7@@ -8,22 +8,22 @@
 8 #include "utf.h"
 9 #include "util.h"
10 
11-typedef struct Range {
12+struct Range {
13   size_t        min, max;
14   struct Range *next;
15-} Range;
16+};
17 
18-static Range *list     = NULL;
19-static char   mode     = 0;
20-static char  *delim    = "\t";
21-static size_t delimlen = 1;
22-static int    nflag    = 0;
23-static int    sflag    = 0;
24+static struct Range *list     = NULL;
25+static char          mode     = 0;
26+static char         *delim    = "\t";
27+static size_t        delimlen = 1;
28+static int           nflag    = 0;
29+static int           sflag    = 0;
30 
31 static void
32-insert(Range *r)
33+insert(struct Range *r)
34 {
35-  Range *l, *p, *t;
36+  struct Range *l, *p, *t;
37 
38   for (p = NULL, l = list; l; p = l, l = l->next) {
39     if (r->max && r->max + 1 < l->min) {
40@@ -48,9 +48,9 @@ insert(Range *r)
41 static void
42 parselist(char *str)
43 {
44-  char  *s;
45-  size_t n = 1;
46-  Range *r;
47+  char         *s;
48+  size_t        n = 1;
49+  struct Range *r;
50 
51   if (!*str)
52     eprintf("empty list\n");
53@@ -109,7 +109,8 @@ seek(struct line *s, size_t pos, size_t *prev, size_t count)
54 static void
55 cut(FILE *fp, const char *fname)
56 {
57-  Range             *r;
58+  struct Range       *r;
59+
60   struct line        s;
61   static struct line line;
62   static size_t      size;
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <ctype.h>
6 #include <stdio.h>
+20, -4
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <ctype.h>
 6 #include <fcntl.h>
 7@@ -71,9 +71,17 @@ ucase(unsigned char *buf, size_t len)
 8     buf[0] = toupper(buf[0]);
 9 }
10 
11+enum Status {
12+  STATUS_DEFAULT,
13+  STATUS_NOXFER,
14+  STATUS_NONE,
15+};
16+
17 static void
18-summary(void)
19+summary(enum Status status)
20 {
21+  if (status == STATUS_NONE)
22+    return;
23   fprintf(stderr, "%" PRIdMAX "+%" PRIdMAX " records in\n", (intmax_t)ifull, (intmax_t)ipart);
24   fprintf(stderr, "%" PRIdMAX "+%" PRIdMAX " records out\n", (intmax_t)ofull, (intmax_t)opart);
25 }
26@@ -92,6 +100,7 @@ main(int argc, char *argv[])
27     NOTRUNC = 1 << 4,
28     SYNC    = 1 << 5,
29   } conv = 0;
30+  enum Status    status = STATUS_DEFAULT;
31   char          *arg, *val, *end;
32   const char    *iname = "-", *oname = "-";
33   int            ifd = 0, ofd = 1, eof = 0;
34@@ -123,6 +132,13 @@ main(int argc, char *argv[])
35       seek = estrtonum(val, 0, LLONG_MAX);
36     } else if (strcmp(arg, "count") == 0) {
37       count = estrtonum(val, 0, LLONG_MAX);
38+    } else if (strcmp(arg, "status") == 0) {
39+      if (strcmp(val, "none") == 0)
40+        status = STATUS_NONE;
41+      else if (strcmp(val, "noxfer") == 0)
42+        status = STATUS_NOXFER;
43+      else
44+        eprintf("unknown status level '%s'\n", val);
45     } else if (strcmp(arg, "conv") == 0) {
46       do {
47         end = strchr(val, ',');
48@@ -198,7 +214,7 @@ main(int argc, char *argv[])
49         weprintf("read:");
50         if (!(conv & NOERROR))
51           return 1;
52-        summary();
53+        summary(status);
54         if (!(conv & SYNC))
55           continue;
56         ret = 0;
57@@ -241,7 +257,7 @@ main(int argc, char *argv[])
58     ipos -= opos;
59     opos = 0;
60   }
61-  summary();
62+  summary(status);
63 
64   return 0;
65 }
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/statvfs.h>
6 
+2, -2
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 #include "paths.h"
 5 #include "util.h"
 6 #include "wexec.h"
 7@@ -2079,7 +2079,7 @@ proceed:
 8     fetch(ixnew, c, d, f2, diff_format == D_NORMAL ? '>' : '\0', 0, *pflags);
 9   if (edoffset != 0 && diff_format == D_EDIT) {
10     printf(".\n");
11-    printf("%ds/.//\n", a + edoffset - 1);
12+    printf("%ds/.// \n", a + edoffset - 1);
13     b = a + edoffset - 1;
14     a = b + 1;
15     c += edoffset;
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <libgen.h>
6 #include <stdio.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/stat.h>
6 #include <sys/types.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include "util.h"
6 #include <stdio.h>
+28, -28
  1@@ -1,4 +1,4 @@
  2-/* See LICENSE file for copyright and license details. */
  3+/* see LICENSE file for copyright and license details */
  4 
  5 #include <fcntl.h>
  6 #include <regex.h>
  7@@ -24,11 +24,11 @@
  8 #define AFTER     0
  9 #define BEFORE    1
 10 
 11-typedef struct {
 12+struct String {
 13   char  *str;
 14   size_t cap;
 15   size_t siz;
 16-} String;
 17+};
 18 
 19 struct hline {
 20   off_t seek;
 21@@ -48,7 +48,7 @@ struct undo {
 22 static char      *prompt = "*";
 23 static regex_t   *pattern;
 24 static regmatch_t matchs[10];
 25-static String     lastre;
 26+static struct String lastre;
 27 
 28 static int           optverbose, optprompt, exstatus, optdiag = 1;
 29 static int           marks['z' - 'a' + 1];
 30@@ -58,13 +58,13 @@ static jmp_buf       savesp;
 31 static char         *lasterr;
 32 static size_t        idxsize, lastidx;
 33 static struct hline *zero;
 34-static String        text;
 35+static struct String text;
 36 static char          savfname[FILENAME_MAX];
 37 static char          tmpname[FILENAME_MAX];
 38 static int           scratch;
 39 static int           pflag, modflag, uflag, gflag;
 40 static size_t        csize;
 41-static String        cmdline;
 42+static struct String cmdline;
 43 static char         *ocmdline;
 44 static int           inputidx;
 45 static char         *rhs;
 46@@ -106,8 +106,8 @@ prevln(int line)
 47   return (line < 0) ? lastln : line;
 48 }
 49 
 50-static String *
 51-copystring(String *s, char *from)
 52+static struct String *
 53+copystring(struct String *s, char *from)
 54 {
 55   size_t len;
 56   char  *t;
 57@@ -124,8 +124,8 @@ copystring(String *s, char *from)
 58   return s;
 59 }
 60 
 61-static String *
 62-string(String *s)
 63+static struct String *
 64+string(struct String *s)
 65 {
 66   free(s->str);
 67   s->str = NULL;
 68@@ -136,7 +136,7 @@ string(String *s)
 69 }
 70 
 71 static char *
 72-addchar(char c, String *s)
 73+addchar(char c, struct String *s)
 74 {
 75   size_t cap = s->cap, siz = s->siz;
 76   char  *t = s->str;
 77@@ -303,8 +303,8 @@ newundo(int from1, int from2)
 78 }
 79 
 80 /*
 81- * relink: to1   <- from1
 82- *         from2 -> to2
 83+ * relink: to1 <- from1
 84+ * from2 -> to2
 85  */
 86 static void
 87 relink(int to1, int from1, int from2, int to2)
 88@@ -464,13 +464,13 @@ rematch(int num)
 89     return 1;
 90   }
 91 
 92-  /* Zero width match was found at the end of the input, done */
 93+  /* zero width match was found at the end of the input, done */
 94   if (lastmatch[off] == '\n') {
 95     lastmatch += off;
 96     return 0;
 97   }
 98 
 99-  /* Zero width match at the current posiion, find the next one */
100+  /* zero width match at the current posiion, find the next one */
101   text.str[text.siz - 2] = '\0';
102   r                      = !regexec(pattern, lastmatch + off + 1, 10, matchs, REG_NOTBOL);
103   text.str[text.siz - 2] = '\n';
104@@ -478,7 +478,7 @@ rematch(int num)
105   if (!r)
106     return 0;
107 
108-  /* Re-adjust matches to account for +1 in regexec */
109+  /* re-adjust matches to account for +1 in regexec */
110   for (m = matchs; m < &matchs[10]; m++) {
111     m->rm_so += 1;
112     m->rm_eo += 1;
113@@ -778,7 +778,7 @@ chksignals(void)
114 static const char *
115 expandcmd(void)
116 {
117-  static String cmd;
118+  static struct String cmd;
119   char         *p;
120   int           c, repl = 0;
121 
122@@ -1027,7 +1027,7 @@ static void
123 append(int num)
124 {
125   int           ch;
126-  static String line;
127+  static struct String line;
128 
129   curln = num;
130   while (moreinput()) {
131@@ -1089,7 +1089,7 @@ join(void)
132 {
133   int           i;
134   char         *t, c;
135-  static String s;
136+  static struct String s;
137 
138   string(&s);
139   for (i = line1;; i = nextln(i)) {
140@@ -1156,7 +1156,7 @@ static void
141 getrhs(int delim)
142 {
143   int           c;
144-  static String s;
145+  static struct String s;
146 
147   string(&s);
148   while ((c = input()) != '\0' && c != delim)
149@@ -1196,7 +1196,7 @@ getnth(void)
150 }
151 
152 static void
153-addpre(String *s)
154+addpre(struct String *s)
155 {
156   char *p;
157 
158@@ -1205,7 +1205,7 @@ addpre(String *s)
159 }
160 
161 static void
162-addpost(String *s)
163+addpost(struct String *s)
164 {
165   char c, *p;
166 
167@@ -1215,7 +1215,7 @@ addpost(String *s)
168 }
169 
170 static int
171-addsub(String *s, int nth, int nmatch)
172+addsub(struct String *s, int nth, int nmatch)
173 {
174   char *end, *q, *p, c;
175   int   sub;
176@@ -1258,7 +1258,7 @@ static void
177 subline(int num, int nth)
178 {
179   int           i, m, changed;
180-  static String s;
181+  static struct String s;
182 
183   string(&s);
184   i = changed = 0;
185@@ -1288,10 +1288,10 @@ subst(int nth)
186     subline(line, nth);
187 
188     /*
189-     * The substitution command can add lines, so
190-     * we have to skip lines until we find the
191-     * index that we saved before the substitution
192-     */
193+ * the substitution command can add lines, so
194+ * we have to skip lines until we find the
195+ * index that we saved before the substitution
196+ */
197     do
198       line = nextln(line);
199     while (getindex(line) != next);
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <errno.h>
6 #include <stdio.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdint.h>
6 #include <stdlib.h>
+2, -2
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <limits.h>
 6 #include <stdio.h>
 7@@ -238,7 +238,7 @@ parse(char *expr[], int numexpr)
 8     switch ((type = lex(*expr, &v))) {
 9       case VAL:
10         /* treatment of *expr is not known until
11-         * doop(); treat as a string for now */
12+ * doop(); treat as a string for now */
13         valp->str = *expr;
14         valp++;
15         break;
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 // ?man false: return unsuccessful exit status
6 // ?man exit with status 1 representing failure
+72, -72
  1@@ -1,4 +1,4 @@
  2-/* See LICENSE file for copyright and license details. */
  3+/* see LICENSE file for copyright and license details */
  4 
  5 #include "config.h"
  6 #include "util.h"
  7@@ -26,32 +26,32 @@ union extra {
  8   intmax_t i;
  9 };
 10 
 11-/* Argument passed into a primary's function */
 12+/* argument passed into a primary's function */
 13 struct arg {
 14   char        *path;
 15   struct stat *st;
 16   union extra  extra;
 17 };
 18 
 19-/* Information about each primary, for lookup table */
 20+/* information about each primary, for lookup table */
 21 struct pri_info {
 22   char *name;
 23   int (*func)(struct arg *arg);
 24   char **(*getarg)(char **argv, union extra *extra);
 25   void (*freearg)(union extra extra);
 26-  char narg; /* -xdev, -depth, -print don't take args but have getarg() */
 27+  char narg; /* -xdev, -depth, -print dont take args but have getarg() */
 28 };
 29 
 30-/* Information about operators, for lookup table */
 31+/* information about operators, for lookup table */
 32 struct op_info {
 33-  char *name;   /* string representation of op           */
 34-  char  type;   /* from tok.type                         */
 35-  char  prec;   /* precedence                            */
 36+  char *name;   /* string representation of op */
 37+  char  type;   /* from tok.type */
 38+  char  prec;   /* precedence */
 39   char  nargs;  /* number of arguments (unary or binary) */
 40-  char  lassoc; /* left associative                      */
 41+  char  lassoc; /* left associative */
 42 };
 43 
 44-/* Token when lexing/parsing
 45+/* token when lexing/parsing
 46  * (although also used for the expression tree) */
 47 struct tok {
 48   struct tok *left, *right; /* if (type == NOT) left = NULL */
 49@@ -90,21 +90,21 @@ struct execarg {
 50   union {
 51     struct {
 52       char ***braces; /* NULL terminated list of pointers into
 53-             argv where {} were */
 54+ * argv where {} were */
 55     } s;              /* semicolon */
 56     struct {
 57       size_t arglen;  /* number of bytes in argv before files
 58-             are added */
 59+ * are added */
 60       size_t filelen; /* numer of bytes in file names added to
 61-             argv     */
 62+ * argv */
 63       size_t first;   /* index one past last arg, where first
 64-               file goes */
 65-      size_t next;    /* index where next file goes    */
 66-      size_t cap;     /* capacity of argv     */
 67+ * file goes */
 68+      size_t next;    /* index where next file goes */
 69+      size_t cap;     /* capacity of argv */
 70     } p;              /* plus */
 71   } u;
 72   char **argv; /* NULL terminated list of arguments (allocated if isplus)
 73-                */
 74+ */
 75   char isplus; /* -exec + instead of -exec ; */
 76 };
 77 
 78@@ -116,11 +116,11 @@ struct findhist {
 79   ino_t            ino;
 80 };
 81 
 82-/* Utility */
 83+/* utility */
 84 static int spawn(char *argv[]);
 85 static int do_stat(char *path, struct stat *sb, struct findhist *hist);
 86 
 87-/* Primaries */
 88+/* primaries */
 89 static int pri_name(struct arg *arg);
 90 #if FEATURE_FIND_INAME
 91 static int pri_iname(struct arg *arg);
 92@@ -192,7 +192,7 @@ static int pri_print0(struct arg *arg);
 93 static int pri_newer(struct arg *arg);
 94 static int pri_depth(struct arg *arg);
 95 
 96-/* Getargs */
 97+/* getargs */
 98 static char **get_name_arg(char *argv[], union extra *extra);
 99 static char **get_path_arg(char *argv[], union extra *extra);
100 static char **get_xdev_arg(char *argv[], union extra *extra);
101@@ -208,12 +208,12 @@ static char **get_print_arg(char *argv[], union extra *extra);
102 static char **get_newer_arg(char *argv[], union extra *extra);
103 static char **get_depth_arg(char *argv[], union extra *extra);
104 
105-/* Freeargs */
106+/* freeargs */
107 static void free_extra(union extra extra);
108 static void free_exec_arg(union extra extra);
109 static void free_ok_arg(union extra extra);
110 
111-/* Parsing/Building/Running */
112+/* parsing/building/running */
113 static void             fill_narg(char *s, struct narg *n);
114 static struct pri_info *find_primary(char *name);
115 static struct op_info  *find_op(char *name);
116@@ -325,24 +325,24 @@ static struct tok *root; /* points to root of expression tree, inside toks array
117 static struct timespec start; /* time find was started, used for -[acm]time */
118 
119 static size_t envlen; /* number of bytes in environ, used to calculate against
120-       ARG_MAX */
121+ * ARG_MAX */
122 static size_t argmax; /* value of ARG_MAX retrieved using sysconf(3p) */
123 
124 static struct {
125-  char ret;      /* return value from main                             */
126+  char ret;      /* return value from main */
127   char depth;    /* -depth, directory contents before directory itself */
128-  char h;        /* -H, follow symlinks on command line                */
129-  char l;        /* -L, follow all symlinks (command line and search)  */
130-  char prune;    /* hit -prune                                         */
131-  char xdev;     /* -xdev, prune directories on different devices      */
132-  char print;    /* whether we will need -print when parsing           */
133-  char quit;     /* quit execution immediately                         */
134-  long maxdepth; /* max depth of recursion                          */
135-  long mindepth; /* min depth of recursion                          */
136+  char h;        /* -H, follow symlinks on command line */
137+  char l;        /* -L, follow all symlinks (command line and search) */
138+  char prune;    /* hit -prune */
139+  char xdev;     /* -xdev, prune directories on different devices */
140+  char print;    /* whether we will need -print when parsing */
141+  char quit;     /* quit execution immediately */
142+  long maxdepth; /* max depth of recursion */
143+  long mindepth; /* min depth of recursion */
144 } gflags;
145 
146 /*
147- * Utility
148+ * utility
149  */
150 static int
151 spawn(char *argv[])
152@@ -351,8 +351,8 @@ spawn(char *argv[])
153   int   status;
154 
155   /* flush stdout so that -print output always appears before
156-   * any output from the command and does not get cut-off in
157-   * the middle of a line. */
158+ * any output from the command and does not get cut-off in
159+ * the middle of a line */
160   fflush(stdout);
161 
162   switch ((pid = fork())) {
163@@ -389,7 +389,7 @@ do_stat(char *path, struct stat *sb, struct findhist *hist)
164 }
165 
166 /*
167- * Primaries
168+ * primaries
169  */
170 static int
171 pri_name(struct arg *arg)
172@@ -534,7 +534,7 @@ pri_exec(struct arg *arg)
173     len = strlen(arg->path) + 1;
174 
175     /* if we reached ARG_MAX, fork, exec, wait, free file names,
176-     * reset list */
177+ * reset list */
178     if (len + e->u.p.arglen + e->u.p.filelen + envlen > argmax) {
179       e->argv[e->u.p.next] = NULL;
180 
181@@ -549,7 +549,7 @@ pri_exec(struct arg *arg)
182     }
183 
184     /* if we have too many files, realloc (with space for NULL
185-     * termination) */
186+ * termination) */
187     if (e->u.p.next + 1 == e->u.p.cap)
188       e->argv = ereallocarray(e->argv, e->u.p.cap *= 2, sizeof(*e->argv));
189 
190@@ -580,7 +580,7 @@ pri_ok(struct arg *arg)
191   /* throw away rest of line */
192   while ((c = fgetc(stdin)) != '\n' && c != EOF)
193     /* FIXME: what if the first character of the rest of the line is
194-     * a null byte? */
195+ * a null byte? */
196     ;
197 
198   if (feof(stdin) || ferror(stdin))
199@@ -630,7 +630,7 @@ pri_depth(struct arg *arg)
200 }
201 
202 /*
203- * Getargs
204+ * getargs
205  * consume any arguments for given primary and fill extra
206  * return pointer to last argument, the pointer will be incremented in parse()
207  */
208@@ -760,7 +760,7 @@ get_exec_arg(char *argv[], union extra *extra)
209   *arg      = NULL;
210 
211   if (e->isplus) {
212-    *(arg - 1)    = NULL; /* don't need the {} in there now */
213+    *(arg - 1)    = NULL; /* dont need the {} in there now */
214     e->u.p.arglen = e->u.p.filelen = 0;
215     e->u.p.first = e->u.p.next = arg - argv - 1;
216     e->u.p.cap                 = (arg - argv) * 2;
217@@ -843,7 +843,7 @@ get_depth_arg(char *argv[], union extra *extra)
218 }
219 
220 /*
221- * Freeargs
222+ * freeargs
223  */
224 static void
225 free_extra(union extra extra)
226@@ -885,7 +885,7 @@ free_ok_arg(union extra extra)
227 }
228 
229 /*
230- * Parsing/Building/Running
231+ * parsing/building/running
232  */
233 static void
234 fill_narg(char *s, struct narg *n)
235@@ -934,12 +934,12 @@ find_op(char *name)
236 
237 /* given the expression from the command line
238  * 1) convert arguments from strings to tok and place in an array duplicating
239- *    the infix expression given, inserting "-a" where it was omitted
240+ * the infix expression given, inserting "-a" where it was omitted
241  * 2) allocate an array to hold the correct number of tok, and convert from
242- *    infix to rpn (using shunting-yard), add -a and -print if necessary
243+ * infix to rpn (using shunting-yard), add -a and -print if necessary
244  * 3) evaluate the rpn filling in left and right pointers to create an
245- *    expression tree (tok are still all contained in the rpn array, just
246- *    pointing at eachother)
247+ * expression tree (tok are still all contained in the rpn array, just
248+ * pointing at eachother)
249  */
250 static void
251 parse(int argc, char **argv)
252@@ -960,7 +960,7 @@ parse(int argc, char **argv)
253     pri = find_primary(*arg);
254 
255     if (pri) { /* token is a primary, fill out tok and get arguments
256-                */
257+ */
258       if (lasttype == PRIM || lasttype == RPAR) {
259         *tok++ = and;
260         ntok++;
261@@ -990,7 +990,7 @@ parse(int argc, char **argv)
262         eprintf("paths must precede expression: %s\n", *arg);
263     }
264     if (tok->type != LPAR && tok->type != RPAR)
265-      ntok++; /* won't have parens in rpn */
266+      ntok++; /* wont have parens in rpn */
267     lasttype = tok->type;
268   }
269   tok->type = END;
270@@ -1000,9 +1000,9 @@ parse(int argc, char **argv)
271     gflags.print++;
272 
273   /* use shunting-yard to convert from infix to rpn
274-   * https://en.wikipedia.org/wiki/Shunting-yard_algorithm
275-   * read from infix, resulting rpn ends up in rpn, next position in rpn
276-   * is out push operators onto stack, next position in stack is top */
277+   * https:// en.wikipedia.org/wiki/shunting-yard_algorithm
278+ * read from infix, resulting rpn ends up in rpn, next position in rpn
279+ * is out push operators onto stack, next position in stack is top */
280   rpn   = ereallocarray(NULL, ntok + gflags.print, sizeof(*rpn));
281   stack = ereallocarray(NULL, argc + gflags.print, sizeof(*stack));
282   for (tok = infix, out = rpn, top = stack; tok->type != END; tok++) {
283@@ -1020,18 +1020,18 @@ parse(int argc, char **argv)
284           eprintf("extra )\n");
285         break;
286       default:
287-        /* this expression can be simplified, but I decided copy
288-         * the verbage from the wikipedia page in order to more
289-         * clearly explain what's going on */
290+        /* this expression can be simplified, but i decided copy
291+ * the verbage from the wikipedia page in order to more
292+ * clearly explain what's going on */
293         while (top-- > stack
294                && ((tok->u.oinfo->lassoc && tok->u.oinfo->prec <= (*top)->u.oinfo->prec)
295                    || (!tok->u.oinfo->lassoc && tok->u.oinfo->prec < (*top)->u.oinfo->prec)))
296           *out++ = **top;
297 
298         /* top now points to either an operator we didn't pop,
299-         * or stack[-1] either way we need to increment it
300-         * before using it, then increment again so the stack
301-         * works */
302+ * or stack[-1] either way we need to increment it
303+ * before using it, then increment again so the stack
304+ * works */
305         top++;
306         *top++ = tok;
307         break;
308@@ -1044,8 +1044,8 @@ parse(int argc, char **argv)
309   }
310 
311   /* if there was no expression, use -print
312-   * if there was an expression but no -print, -exec, or -ok, add -a
313-   * -print in rpn, not infix */
314+ * if there was an expression but no -print, -exec, or -ok, add -a
315+ * -print in rpn, not infix */
316   if (gflags.print)
317     *out++ = (struct tok){.u.pinfo = find_primary("-print"), .type = PRIM};
318   if (gflags.print == 2)
319@@ -1054,10 +1054,10 @@ parse(int argc, char **argv)
320   out->type = END;
321 
322   /* rpn now holds all operators and arguments in reverse polish notation
323-   * values are pushed onto stack, operators pop values off stack into
324-   * left and right pointers, pushing operator node back onto stack could
325-   * probably just do this during shunting-yard, but this is simpler code
326-   * IMO */
327+ * values are pushed onto stack, operators pop values off stack into
328+ * left and right pointers, pushing operator node back onto stack could
329+ * probably just do this during shunting-yard, but this is simpler code
330+ * IMO */
331   for (tok = rpn, top = stack; tok->type != END; tok++) {
332     if (tok->type == PRIM) {
333       *top++ = tok;
334@@ -1109,7 +1109,7 @@ eval(struct tok *tok, struct arg *arg)
335   return ret ^ (tok->type == NOT);
336 }
337 
338-/* evaluate path, if it's a directory iterate through directory entries and
339+/* evaluate path, if its a directory iterate through directory entries and
340  * recurse
341  */
342 #if FEATURE_FIND_INAME
343@@ -1385,11 +1385,11 @@ find(char *path, struct findhist *hist)
344     return;
345 
346   if (gflags.mindepth < 0 || depth >= gflags.mindepth) {
347-    /* don't eval now iff we will hit the eval at the bottom which
348-     * means
349-     * 1. we are a directory 2. we have -depth 3. we don't have
350-     * -xdev or we are on same device (so most of the time we eval
351-     * here) */
352+    /* dont eval now iff we will hit the eval at the bottom which
353+ * means
354+ * 1. we are a directory 2. we have -depth 3. we dont have
355+ * -xdev or we are on same device (so most of the time we eval
356+ * here) */
357     if (!S_ISDIR(st.st_mode) || !gflags.depth || (gflags.xdev && hist && st.st_dev != hist->dev))
358       eval(root, &arg);
359   }
360@@ -1502,8 +1502,8 @@ main(int argc, char **argv)
361   parse(argc - npaths, argv);
362 
363   /* calculate number of bytes in environ for -exec {} + ARG_MAX avoidance
364-   * libc implementation defined whether null bytes, pointers, and
365-   * alignment are counted, so count them */
366+ * libc implementation defined whether null bytes, pointers, and
367+ * alignment are counted, so count them */
368   for (argv = environ; *argv; argv++)
369     envlen += strlen(*argv) + 1 + sizeof(*argv);
370 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <ctype.h>
6 #include <stdint.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <errno.h>
6 #include <limits.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdint.h>
6 #include <stdio.h>
+2, -2
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <sys/types.h>
 6 
 7@@ -172,7 +172,7 @@ main(int argc, char *argv[])
 8       userid(getuid());
 9       break;
10     case 1:
11-      /* user names can't begin [0-9] */
12+      /* user names cant begin [0-9] */
13       if (isdigit(argv[0][0]))
14         userid(estrtol(argv[0], 0));
15       else
+5, -5
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <ctype.h>
 6 #include <stdint.h>
 7@@ -378,8 +378,8 @@ join(FILE *fa, FILE *fb, size_t jfa, size_t jfb)
 8       if (unpairsa)
 9         prline(spa.lines[0]);
10       if (!addtospan(&spa, fa, RESET)) {
11-        if (unpairsb) { /* a is EOF'd; print the rest of
12-               b */
13+        if (unpairsb) { /* a is eof'd; print the rest of
14+ * b */
15           do
16             prline(spb.lines[0]);
17           while (addtospan(&spb, fb, RESET));
18@@ -392,8 +392,8 @@ join(FILE *fa, FILE *fb, size_t jfa, size_t jfb)
19       if (unpairsb)
20         prline(spb.lines[0]);
21       if (!addtospan(&spb, fb, RESET)) {
22-        if (unpairsa) { /* b is EOF'd; print the rest of
23-               a */
24+        if (unpairsa) { /* b is eof'd; print the rest of
25+ * a */
26           do
27             prline(spa.lines[0]);
28           while (addtospan(&spa, fa, RESET));
+2, -2
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include "sig.h"
 6 #include "util.h"
 7@@ -97,7 +97,7 @@ main(int argc, char *argv[])
 8         break;
 9       default:
10       longopt:
11-        /* XSI-extensions -argnum and -argname*/
12+        /* xsi-extensions -argnum and -argname */
13         if (isdigit((*argv)[1])) {
14           sig = estrtonum((*argv) + 1, 0, INT_MAX);
15           sig2name(sig);
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <unistd.h>
6 
+145, -2
  1@@ -1,24 +1,114 @@
  2-/* See LICENSE file for copyright and license details. */
  3+/* see LICENSE file for copyright and license details */
  4 
  5 #include <sys/stat.h>
  6 
  7 #include <errno.h>
  8 #include <fcntl.h>
  9 #include <libgen.h>
 10+#include <limits.h>
 11+#include <stdlib.h>
 12 #include <string.h>
 13 #include <unistd.h>
 14 
 15 #include "util.h"
 16 
 17+#if FEATURE_LN_RELATIVE
 18+#define MAXPATHPARTS (PATH_MAX / 2)
 19+
 20+/* splits an absolute, realpath()-canonicalized path in place on '/',
 21+ * returning pointers to each component; safe only against realpath()
 22+ * output, which has no trailing or doubled slashes to worry about */
 23+static int
 24+split_path(char *path, char **parts, int max)
 25+{
 26+  char *p = path;
 27+  int   n = 0;
 28+
 29+  if (*p == '/')
 30+    p++;
 31+  while (*p && n < max) {
 32+    parts[n++] = p;
 33+    p = strchr(p, '/');
 34+    if (!p)
 35+      break;
 36+    *p++ = '\0';
 37+  }
 38+  return n;
 39+}
 40+
 41+/* the text a relative symlink at from_dir/name needs to store to reach
 42+ * to_path: the common prefix of both canonicalized paths, a ".." per
 43+ * remaining from_dir component, then whatever is left of to_path */
 44+static void
 45+relpath(const char *from_dir, const char *to_path, char *out, size_t outsz)
 46+{
 47+  char  from_real[PATH_MAX], to_real[PATH_MAX], to_dir_buf[PATH_MAX], to_base_buf[PATH_MAX];
 48+  char *from_parts[MAXPATHPARTS], *to_parts[MAXPATHPARTS];
 49+  int   nfrom, nto, ncommon, i;
 50+
 51+  if (!realpath(from_dir, from_real))
 52+    eprintf("realpath %s:", from_dir);
 53+
 54+  strlcpy(to_dir_buf, to_path, sizeof(to_dir_buf));
 55+  strlcpy(to_base_buf, to_path, sizeof(to_base_buf));
 56+  if (!realpath(dirname(to_dir_buf), to_real))
 57+    eprintf("realpath %s:", to_path);
 58+
 59+  nfrom = split_path(from_real, from_parts, MAXPATHPARTS);
 60+  nto   = split_path(to_real, to_parts, MAXPATHPARTS);
 61+
 62+  ncommon = 0;
 63+  while (ncommon < nfrom && ncommon < nto &&
 64+         strcmp(from_parts[ncommon], to_parts[ncommon]) == 0)
 65+    ncommon++;
 66+
 67+  out[0] = '\0';
 68+  for (i = ncommon; i < nfrom; i++)
 69+    strlcat(out, "../", outsz);
 70+  for (i = ncommon; i < nto; i++) {
 71+    strlcat(out, to_parts[i], outsz);
 72+    strlcat(out, "/", outsz);
 73+  }
 74+  strlcat(out, basename(to_base_buf), outsz);
 75+}
 76+#endif
 77+
 78 static void
 79 usage(void)
 80 {
 81+#if FEATURE_LN_RELATIVE
 82+#if FEATURE_LN_NO_TARGET_DIR
 83+  eprintf(
 84+      "usage: %s [-f] [-L | -P | -r | -s] [-T] target [name]\n"
 85+      "       %s [-f] [-L | -P | -r | -s] target ... dir\n",
 86+      argv0,
 87+      argv0
 88+  );
 89+#else
 90+  eprintf(
 91+      "usage: %s [-f] [-L | -P | -r | -s] target [name]\n"
 92+      "       %s [-f] [-L | -P | -r | -s] target ... dir\n",
 93+      argv0,
 94+      argv0
 95+  );
 96+#endif
 97+#else
 98+#if FEATURE_LN_NO_TARGET_DIR
 99+  eprintf(
100+      "usage: %s [-f] [-L | -P | -s] [-T] target [name]\n"
101+      "       %s [-f] [-L | -P | -s] target ... dir\n",
102+      argv0,
103+      argv0
104+  );
105+#else
106   eprintf(
107       "usage: %s [-f] [-L | -P | -s] target [name]\n"
108       "       %s [-f] [-L | -P | -s] target ... dir\n",
109       argv0,
110       argv0
111   );
112+#endif
113+#endif
114 }
115 
116 // ?man ln: make links between files
117@@ -30,6 +120,13 @@ main(int argc, char *argv[])
118   char *targetdir = ".", *target = NULL;
119   int   ret = 0, sflag = 0, fflag = 0, dirfd = AT_FDCWD, hastarget = 0, flags = AT_SYMLINK_FOLLOW;
120   struct stat st, tst;
121+#if FEATURE_LN_RELATIVE
122+  int  rflag = 0;
123+  char relbuf[PATH_MAX];
124+#endif
125+#if FEATURE_LN_NO_TARGET_DIR
126+  int Tflag = 0;
127+#endif
128 
129   ARGBEGIN
130   {
131@@ -46,10 +143,26 @@ main(int argc, char *argv[])
132     case 'P':
133       flags &= ~AT_SYMLINK_FOLLOW;
134       break;
135+#if FEATURE_LN_RELATIVE
136+    // ?man -r: with -s, store the target as a path relative to name's
137+    // own directory instead of copying it as given
138+    case 'r':
139+      rflag = 1;
140+      sflag = 1;
141+      break;
142+#endif
143     // ?man -s: make symbolic links instead of hard links
144     case 's':
145       sflag = 1;
146       break;
147+#if FEATURE_LN_NO_TARGET_DIR
148+    // ?man -T: treat name as a regular file, never as a directory to
149+    // place the link into, even if a file of that name is currently
150+    // a directory
151+    case 'T':
152+      Tflag = 1;
153+      break;
154+#endif
155     default:
156       usage();
157   }
158@@ -59,7 +172,13 @@ main(int argc, char *argv[])
159     usage();
160 
161   if (argc > 1) {
162+#if FEATURE_LN_NO_TARGET_DIR
163+    if (Tflag && argc != 2)
164+      eprintf("%s: extra operand\n", argv[2]);
165+    if (!Tflag && !stat(argv[argc - 1], &st) && S_ISDIR(st.st_mode)) {
166+#else
167     if (!stat(argv[argc - 1], &st) && S_ISDIR(st.st_mode)) {
168+#endif
169       if ((dirfd = open(argv[argc - 1], O_RDONLY)) < 0)
170         eprintf("open %s:", argv[argc - 1]);
171       targetdir = argv[argc - 1];
172@@ -110,7 +229,31 @@ main(int argc, char *argv[])
173       ret = 1;
174       continue;
175     }
176-    if ((sflag ? symlinkat(*argv, dirfd, target) : linkat(AT_FDCWD, *argv, dirfd, target, flags))
177+
178+#if FEATURE_LN_RELATIVE
179+    if (rflag) {
180+      /* targetdir only names the real destination directory when name
181+       * was defaulted from target's own basename (the dir-argument
182+       * form); an explicit name may itself carry a directory prefix
183+       * (ln -r target dir/name), which then names it instead */
184+      char        dirbuf[PATH_MAX];
185+      const char *fromdir = targetdir;
186+
187+      if (hastarget) {
188+        strlcpy(dirbuf, target, sizeof(dirbuf));
189+        fromdir = dirname(dirbuf);
190+      }
191+      relpath(fromdir, *argv, relbuf, sizeof(relbuf));
192+    }
193+#endif
194+
195+    if ((sflag ?
196+#if FEATURE_LN_RELATIVE
197+                symlinkat(rflag ? relbuf : *argv, dirfd, target)
198+#else
199+                symlinkat(*argv, dirfd, target)
200+#endif
201+                : linkat(AT_FDCWD, *argv, dirfd, target, flags))
202         < 0) {
203       weprintf("%s %s <- %s/%s:", sflag ? "symlinkat" : "linkat", *argv, targetdir, target);
204       ret = 1;
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdio.h>
6 #include <stdlib.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdio.h>
6 #include <unistd.h>
+10, -10
 1@@ -125,14 +125,14 @@ parseflag(int flag, char **args, char ***argv)
 2   switch (flag) {
 3     case 'j':
 4       /* ?man -j:jobs: number of parallel jobs (accepted, runs
 5-       * serially) */
 6+ * serially) */
 7     case 'f':
 8       /* ?man -f:file: read rules from file instead of makefile or
 9-       * Makefile */
10+ * makefile */
11       break;
12     case 'e':
13       /* ?man -e: environment variables override makefile assignments
14-       */
15+ */
16       eflag = 1;
17       appendmakeflags("-e");
18       break;
19@@ -157,7 +157,7 @@ parseflag(int flag, char **args, char ***argv)
20       break;
21     case 'q':
22       /* ?man -q: question mode, return zero if up to date, one
23-       * otherwise */
24+ * otherwise */
25       qflag = 1;
26       appendmakeflags("-q");
27       break;
28@@ -302,9 +302,9 @@ parsemakefiles(char **argv)
29 }
30 
31 /*
32- * We want to enable debug as earlier as possible,
33- * if we wait until we read the Makefiles then
34- * we are going to lose to much debug information.
35+ * we want to enable debug as earlier as possible,
36+ * if we wait until we read the makefiles then
37+ * we are going to lose to much debug information
38  */
39 static void
40 enadebug(char *argv[])
41@@ -325,9 +325,9 @@ enadebug(char *argv[])
42 
43 // ?man make: maintain program dependencies
44 // ?man arguments: [name=value ...] [target ...]
45-// ?man update files based on dependency rules in a makefile.
46-// ?man if no -f is given, make tries makefile then Makefile.
47-// ?man if no target is given the first non-dot target in the makefile is built.
48+// ?man update files based on dependency rules in a makefile
49+// ?man if no -f is given, make tries makefile then Makefile
50+// ?man if no target is given the first non-dot target in the makefile is built
51 int
52 main(int argc, char *argv[])
53 {
+18, -18
 1@@ -136,12 +136,12 @@ setmacro(char *name, char *val, int where, int export)
 2   s = macroinfo(name, &owhere, &mp);
 3 
 4   /*
 5-   *  Default values are defined before anything else, and marked
 6-   *  as INTERNAL because they are injected as parseable text, and
 7-   *  MAKEFILE and INTERNAL variables are always overriden. ENVIRON
 8-   *  macros are generated in macroinfo() and this is why this function
 9-   *  should not receive a where == ENVIRON ever.
10-   */
11+ * default values are defined before anything else, and marked
12+ * as INTERNAL because they are injected as parseable text, and
13+ * MAKEFILE and INTERNAL variables are always overriden. ENVIRON
14+ * macros are generated in macroinfo() and this is why this function
15+ * should not receive a where == ENVIRON ever
16+ */
17   switch (owhere) {
18     case UNDEF:
19     case INTERNAL:
20@@ -683,10 +683,10 @@ nextc(void)
21 }
22 
23 /*
24- * This function only can be called after a call to nextc
25- * that didn't return EOF. It can return '\0', but as
26+ * this function only can be called after a call to nextc
27+ * that didn't return EOF. it can return '\0', but as
28  * it is used only to check against '$' then it is not
29- * a problem.
30+ * a problem
31  */
32 static int
33 ahead(void)
34@@ -993,11 +993,11 @@ no_replace:
35 }
36 
37 /*
38- * Horrible hack to do string expansion.
39- * We cannot use normal push and nextc because that
40- * would consume characters of the current file too.
41- * For that reason it cleans the input and it recovers
42- * it later.
43+ * horrible hack to do string expansion
44+ * we cannot use normal push and nextc because that
45+ * would consume characters of the current file too
46+ * for that reason it cleans the input and it recovers
47+ * it later
48  */
49 char *
50 expandstring(char *line, Target *tp, struct loc *loc)
51@@ -1071,10 +1071,10 @@ next(void)
52 
53 repeat:
54   /*
55-   * It is better to avoid skipspaces() here, because
56-   * it can generate the need for 2 calls to back(),
57-   * and we need the character anyway.
58-   */
59+ * it is better to avoid skipspaces() here, because
60+ * it can generate the need for 2 calls to back(),
61+ * and we need the character anyway
62+ */
63   c = nextc();
64   if (c == ' ' || c == '\t')
65     goto repeat;
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/stat.h>
6 #include <sys/types.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/stat.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/stat.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/stat.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/resource.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <limits.h>
6 #include <stdint.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/stat.h>
6 
+20, -4
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include "queue.h"
 6 #include "util.h"
 7@@ -93,9 +93,21 @@ printchunk(const unsigned char *s, unsigned char format, size_t len)
 8           basefac <<= 8;
 9         }
10       }
11-      fmt[2] = big_endian ? '-' : ' ';
12+      /* x/o print a fixed-width, zero-padded field: 2 hex digits per
13+       * byte, or ceil(8*len/3) octal digits, the exact digit count
14+       * needed for len bytes' worth of bits, not the old 4*len-1
15+       * estimate (right for octal/decimal at len==1 only by
16+       * coincidence, and short for hex at every len). d/u stay right-
17+       * justified with spaces at that same estimate, same as every
18+       * other od: an oversized width there is just extra leading
19+       * whitespace, harmless under a space fill */
20+      fmt[2] = (format == 'x' || format == 'o') ? '0' : ' ';
21       fmt[6] = format;
22-      printf(fmt, (int)(3 * len + len - 1), res);
23+      switch (format) {
24+        case 'x': printf(fmt, (int)(2 * len), res); break;
25+        case 'o': printf(fmt, (int)((8 * len + 2) / 3), res); break;
26+        default: printf(fmt, (int)(3 * len + len - 1), res); break;
27+      }
28   }
29 }
30 
31@@ -174,7 +186,11 @@ od(int fd, char *fname, int last)
32   }
33   if (lineoff && last)
34     printline(line, lineoff, addr - lineoff);
35-  if (last)
36+  /* the trailing all-data-consumed line exists to show the final
37+   * address (the file's total size); with -an there is no address to
38+   * show, so it degrades to a content-free, address-column-only blank
39+   * line nothing after it can use, unlike every other od */
40+  if (last && addr_format != 'n')
41     printline((unsigned char *)"", 0, addr);
42   return 0;
43 }
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdlib.h>
6 #include <string.h>
+4, -3
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 #include "paths.h"
 5 #include "util.h"
 6 #include "wexec.h"
 7@@ -2769,8 +2769,9 @@ strtolinenum(char *nptr, char **endptr)
 8   if (errstr != NULL)
 9     fatal("invalid line number at line %ld: `%s' is %s\n", p_input_line, nptr, errstr);
10 
11-  *p      = c;
12-  *endptr = p;
13+  *p = c;
14+  if (endptr)
15+    *endptr = p;
16 
17   return rv;
18 }
+10, -10
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <sys/stat.h>
 6 
 7@@ -12,8 +12,8 @@
 8 #include "util.h"
 9 
10 #define PORTABLE_CHARACTER_SET "0123456789._-qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
11-/* If your system supports more other characters, but not all non-NUL
12- * characters, define SYSTEM_CHARACTER_SET. */
13+/* if your system supports more other characters, but not all non-nul
14+ * characters, define SYSTEM_CHARACTER_SET */
15 
16 static int most  = 0;
17 static int extra = 0;
18@@ -26,15 +26,15 @@ pathchk(char *filename)
19   size_t      len, maxlen;
20   struct stat st;
21 
22-  /* Empty? */
23+  /* empty? */
24   if (extra && !*filename)
25     eprintf("empty filename\n");
26 
27-  /* Leading hyphen? */
28+  /* leading hyphen? */
29   if (extra && ((*filename == '-') || strstr(filename, "/-")))
30     eprintf("%s: leading '-' in component of filename\n", filename);
31 
32-  /* Nonportable character? */
33+  /* nonportable character? */
34 #ifdef SYSTEM_CHARACTER_SET
35   character_set = "/" SYSTEM_CHARACTER_SET;
36 #else
37@@ -50,19 +50,19 @@ pathchk(char *filename)
38     eprintf("%s: nonportable character '%s'\n", p, invalid);
39   }
40 
41-  /* Symlink error? Non-searchable directory? */
42+  /* symlink error? non-searchable directory? */
43   if (lstat(filename, &st) && errno != ENOENT) {
44     /* lstat rather than stat, so that if filename is a bad symlink,
45-     * but all parents are OK, no error will be detected. */
46+ * but all parents are OK, no error will be detected */
47     eprintf("%s:", filename);
48   }
49 
50-  /* Too long pathname? */
51+  /* too long pathname? */
52   maxlen = most ? _POSIX_PATH_MAX : PATH_MAX;
53   if (strlen(filename) >= maxlen)
54     eprintf("%s: is longer than %zu bytes\n", filename, maxlen);
55 
56-  /* Too long component? */
57+  /* too long component? */
58   maxlen = most ? _POSIX_NAME_MAX : NAME_MAX;
59   for (p = filename; p; p = q) {
60     q   = strchr(p, '/');
+2, -2
 1@@ -1,6 +1,6 @@
 2 
 3 
 4-/* taken from: https://github.com/michaelforney/pax */
 5+/* taken from: https:// github.com/michaelforney/pax */
 6 #ifndef _GNU_SOURCE
 7 #define _GNU_SOURCE /* needed for major/minor (non-posix) */
 8 #endif
 9@@ -2079,7 +2079,7 @@ writefile(FILE *unused, struct header *h)
10       exitstatus = 1;
11     } else {
12       /* add back setuid/setgid bits if we preserved the
13-       * uid/gid */
14+ * uid/gid */
15       mode = h->mode;
16     }
17   }
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <ctype.h>
6 #include <errno.h>
+11, -11
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <sys/ioctl.h>
 6 #include <sys/sysinfo.h>
 7@@ -39,7 +39,7 @@ psout(struct procstat *ps)
 8   struct passwd    *pw;
 9   struct winsize    w;
10 
11-  /* Ignore session leaders */
12+  /* ignore session leaders */
13   if (flags & PS_dflag)
14     if (ps->pid == ps->sid)
15       return;
16@@ -47,8 +47,8 @@ psout(struct procstat *ps)
17   devtotty(ps->tty_nr, &tty_maj, &tty_min);
18   ttytostr(tty_maj, tty_min, ttystr, sizeof(ttystr));
19 
20-  /* Only print processes that are associated with
21-   * a terminal and they are not session leaders */
22+  /* only print processes that are associated with
23+ * a terminal and they are not session leaders */
24   if (flags & PS_aflag)
25     if (ps->pid == ps->sid || ttystr[0] == '?')
26       return;
27@@ -56,17 +56,17 @@ psout(struct procstat *ps)
28   if (parsestatus(ps->pid, &pstatus) < 0)
29     return;
30 
31-  /* This is the default case, only print processes that have
32-   * the same controlling terminal as the invoker and the same
33-   * euid as the current user */
34+  /* this is the default case, only print processes that have
35+ * the same controlling terminal as the invoker and the same
36+ * euid as the current user */
37   if (!(flags & (PS_aflag | PS_Aflag | PS_dflag))) {
38     myttystr = ttyname(0);
39     if (myttystr) {
40       if (strcmp(myttystr + strlen("/dev/"), ttystr))
41         return;
42     } else {
43-      /* The invoker has no controlling terminal - just
44-       * go ahead and print the processes anyway */
45+      /* the invoker has no controlling terminal - just
46+ * go ahead and print the processes anyway */
47       ttystr[0] = '?';
48       ttystr[1] = '\0';
49     }
50@@ -107,8 +107,8 @@ psout(struct procstat *ps)
51     start += (ps->starttime / sysconf(_SC_CLK_TCK));
52     strftime(stimestr, sizeof(stimestr), "%H:%M", localtime(&start));
53 
54-    /* For kthreads/zombies /proc/<pid>/cmdline will be
55-     * empty so use ps->comm in that case */
56+    /* for kthreads/zombies /proc/<pid>/cmdline will be
57+ * empty so use ps->comm in that case */
58     if (parsecmdline(ps->pid, cmdline, sizeof(cmdline)) < 0)
59       cmd = ps->comm;
60     else
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/stat.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <limits.h>
6 #include <stdio.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/resource.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <fcntl.h>
6 #include <string.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <libgen.h>
6 #include <string.h>
+113, -113
  1@@ -1,12 +1,12 @@
  2 
  3 
  4 /* FIXME: summary
  5- * decide whether we enforce valid UTF-8, right now it's enforced in certain
  6- *     parts of the script, but not the input...
  7+ * decide whether we enforce valid UTF-8, right now its enforced in certain
  8+ * parts of the script, but not the input...
  9  * nul bytes cause explosions due to use of libc string functions. thoughts?
 10  * lack of newline at end of file, currently we add one. what should we do?
 11  * allow "\\t" for "\t" etc. in regex? in replacement text?
 12- * POSIX says don't flush on N when out of input, but GNU and busybox do.
 13+ * POSIX says dont flush on n when out of input, but GNU and busybox do
 14  */
 15 
 16 #include "config.h"
 17@@ -22,7 +22,7 @@
 18 #include <sys/stat.h>
 19 #include <unistd.h>
 20 
 21-/* Types */
 22+/* types */
 23 
 24 /* used as queue for writes and stack for {,:,b,t */
 25 typedef struct {
 26@@ -31,9 +31,9 @@ typedef struct {
 27   size_t cap;
 28 } Vec;
 29 
 30-/* used for arbitrary growth, str is a C string
 31+/* used for arbitrary growth, str is a c string
 32  * FIXME: does it make sense to keep track of length? or just rely on libc
 33- *        string functions? If we want to support nul bytes everything changes
 34+ * string functions? if we want to support nul bytes everything changes
 35  */
 36 typedef struct {
 37   char  *str;
 38@@ -54,17 +54,17 @@ typedef struct {
 39     regex_t *re;
 40   } u;
 41   enum {
 42-    IGNORE, /* empty address, ignore        */
 43-    EVERY,  /* every line                   */
 44-    LINE,   /* line number                  */
 45-    LAST,   /* last line ($)                */
 46-    REGEX,  /* use included regex           */
 47+    IGNORE, /* empty address, ignore */
 48+    EVERY,  /* every line */
 49+    LINE,   /* line number */
 50+    LAST,   /* last line ($) */
 51+    REGEX,  /* use included regex */
 52     LASTRE, /* use most recently used regex */
 53   } type;
 54 } Addr;
 55 
 56 /* DISCUSS: naddr is not strictly necessary, but very helpful
 57- * naddr == 0 iff beg.type == EVERY  && end.type == IGNORE
 58+ * naddr == 0 iff beg.type == EVERY && end.type == IGNORE
 59  * naddr == 1 iff beg.type != IGNORE && end.type == IGNORE
 60  * naddr == 2 iff beg.type != IGNORE && end.type != IGNORE
 61  */
 62@@ -91,39 +91,39 @@ typedef struct {
 63 typedef struct {
 64   String str;                    /* a,c,i text. r file path */
 65   void (*print)(char *, FILE *); /* check_puts for a, write_file for r,
 66-            unused for c,i */
 67+ * unused for c,i */
 68 } ACIRarg;
 69 
 70 struct Cmd {
 71   Range   range;
 72   Fninfo *fninfo;
 73   union {
 74-    Cmd      *jump;   /* used for   b,t when running  */
 75+    Cmd      *jump;   /* used for b,t when running */
 76     char     *label;  /* used for :,b,t when building */
 77     ptrdiff_t offset; /* used for { (pointers break during realloc) */
 78     FILE     *file;   /* used for w */
 79 
 80-    /* FIXME: Should the following be in the union? or pointers and
 81-     * malloc? */
 82+    /* FIXME: should the following be in the union? or pointers and
 83+ * malloc? */
 84     Sarg    s;
 85     Yarg    y;
 86     ACIRarg acir;
 87-  } u; /* I find your lack of anonymous unions disturbing */
 88+  } u; /* i find your lack of anonymous unions disturbing */
 89   unsigned int in_match : 1;
 90   unsigned int negate : 1;
 91 };
 92 
 93-/* Files for w command (and s' w flag) */
 94+/* files for w command (and s' w flag) */
 95 typedef struct {
 96   char *path;
 97   FILE *file;
 98 } Wfile;
 99 
100 /*
101- * Function Declarations
102+ * function declarations
103  */
104 
105-/* Dynamically allocated arrays and strings */
106+/* dynamically allocated arrays and strings */
107 static void  resize(void **ptr, size_t *nmemb, size_t size, size_t new_nmemb, void **next);
108 static void *pop(Vec *v);
109 static void  push(Vec *v, void *p);
110@@ -131,10 +131,10 @@ static void  stracat(String *dst, char *src);
111 static void  strnacat(String *dst, char *src, size_t n);
112 static void  stracpy(String *dst, char *src);
113 
114-/* Cleanup and errors */
115+/* cleanup and errors */
116 static void usage(void);
117 
118-/* Parsing functions and related utilities */
119+/* parsing functions and related utilities */
120 static void   compile(char *s, int isfile);
121 static int    read_line(FILE *f, String *s);
122 static char  *make_range(Range *range, char *s);
123@@ -148,7 +148,7 @@ static size_t escapes(char *beg, char *end, Rune delim, int n_newline);
124 static size_t echarntorune(Rune *r, char *s, size_t n);
125 static void   insert_labels(void);
126 
127-/* Get and Free arg and related utilities */
128+/* get and free arg and related utilities */
129 static char *get_aci_arg(Cmd *c, char *s);
130 static void  aci_append(Cmd *c, char *s);
131 static void  free_acir_arg(Cmd *c);
132@@ -164,7 +164,7 @@ static char *get_lbrace_arg(Cmd *c, char *s);
133 static char *get_rbrace_arg(Cmd *c, char *s);
134 static char *semicolon_arg(char *s);
135 
136-/* Running */
137+/* running */
138 static void run(void);
139 static int  in_range(Cmd *c);
140 static int  match_addr(Addr *a);
141@@ -176,7 +176,7 @@ static void check_puts(char *s, FILE *f);
142 static void write_patt(char *s, FILE *f);
143 static void update_ranges(Cmd *beg, Cmd *end);
144 
145-/* Sed functions */
146+/* sed functions */
147 static void cmd_y(Cmd *c);
148 static void cmd_x(Cmd *c);
149 static void cmd_w(Cmd *c);
150@@ -205,20 +205,20 @@ static void cmd_lbrace(Cmd *c);
151 static void cmd_rbrace(Cmd *c);
152 static void cmd_last(Cmd *c);
153 
154-/* Actions */
155+/* actions */
156 static void new_line(void);
157 static void app_line(void);
158 static void new_next(void);
159 static void old_next(void);
160 
161 /*
162- * Globals
163+ * globals
164  */
165 static Vec braces, labels, branches; /* holds ptrdiff_t. addrs of {, :, bt */
166 static Vec writes;                   /* holds cmd*. writes scheduled by a and r commands */
167-static Vec wfiles;                   /* holds Wfile*. files for w and s///w commands */
168+static Vec wfiles;                   /* holds Wfile*. files for w and s// /w commands */
169 
170-static Cmd   *prog, *pc; /* Program, program counter */
171+static Cmd   *prog, *pc; /* program, program counter */
172 static size_t pcap;
173 static size_t lineno;
174 #if FEATURE_SED_PRESERVE_NEWLINE
175@@ -235,23 +235,23 @@ static String patt, hold, genbuf;
176 static struct {
177   unsigned int n : 1;        /* -n (no print) */
178   unsigned int E : 1;        /* -E (extended re) */
179-  unsigned int s : 1;        /* s/// replacement happened */
180+  unsigned int s : 1;        /* s// / replacement happened */
181   unsigned int aci_cont : 1; /* a,c,i text continuation */
182-  unsigned int s_cont : 1;   /* s/// replacement text continuation */
183+  unsigned int s_cont : 1;   /* s// / replacement text continuation */
184   unsigned int halt : 1;     /* halt execution */
185 } gflags;
186 
187-/* FIXME: move character inside Fninfo and only use 26*sizeof(Fninfo) instead of
188- * 127*sizeof(Fninfo) bytes */
189+/* FIXME: move character inside fninfo and only use 26*sizeof(fninfo) instead of
190+ * 127*sizeof(fninfo) bytes */
191 static Fninfo fns[] = {
192     ['a'] = {cmd_a, get_aci_arg, free_acir_arg, 1}, /* schedule write of text for later */
193-    ['b'] = {cmd_b, get_bt_arg, NULL, 2}, /* branch to label char *label when building, Cmd *jump
194-                                       when running                     */
195+    ['b'] = {cmd_b, get_bt_arg, NULL, 2}, /* branch to label char *label when building, cmd *jump
196+ * when running */
197     ['c'] = {cmd_c, get_aci_arg, free_acir_arg, 2}, /* delete pattern space. at 0 or 1 addr or end
198-                                                 of 2 addr, write text                     */
199+ * of 2 addr, write text */
200     ['d'] = {cmd_d, NULL, NULL, 2},                 /* delete pattern space */
201     ['D'] = {cmd_D, NULL, NULL, 2}, /* delete to first newline and start new cycle without
202-                                 reading (if no newline, d)        */
203+ * reading (if no newline, d) */
204     ['g'] = {cmd_g, NULL, NULL, 2}, /* replace pattern space with hold space */
205     ['G'] = {cmd_G, NULL, NULL, 2}, /* append newline and hold space to pattern space */
206     ['h'] = {cmd_h, NULL, NULL, 2}, /* replace hold space with pattern space */
207@@ -259,16 +259,16 @@ static Fninfo fns[] = {
208     ['i'] = {cmd_i, get_aci_arg, free_acir_arg, 1}, /* write text */
209     ['l'] = {cmd_l, NULL, NULL, 2}, /* write pattern space in 'visually unambiguous form' */
210     ['n'] = {cmd_n, NULL, NULL, 2}, /* write pattern space (unless -n) read to replace pattern
211-                                 space (if no input, quit)     */
212+ * space (if no input, quit) */
213     ['N'] = {cmd_N, NULL, NULL, 2}, /* append to pattern space separated by newline, line
214-                                 number changes (if no input, quit) */
215+ * number changes (if no input, quit) */
216     ['p'] = {cmd_p, NULL, NULL, 2}, /* write pattern space */
217     ['P'] = {cmd_P, NULL, NULL, 2}, /* write pattern space up to first newline */
218     ['q'] = {cmd_q, NULL, NULL, 1}, /* quit */
219     ['r'] = {cmd_r, get_r_arg, free_acir_arg, 1}, /* write contents of file (unable to open/read
220-                                               treated as empty file)                    */
221+ * treated as empty file) */
222     ['s'] = {cmd_s, get_s_arg, free_s_arg, 2},    /* find/replace/all that crazy s stuff */
223-    ['t'] = {cmd_t, get_bt_arg, NULL, 2}, /* if s/// succeeded (since input or last t) branch to
224+    ['t'] = {cmd_t, get_bt_arg, NULL, 2}, /* if s// / succeeded (since input or last t) branch to
225                                        label (branch to end if no label) */
226     ['w'] = {cmd_w, get_w_arg, NULL, 2},  /* append pattern space to file */
227     ['x'] = {cmd_x, NULL, NULL, 2},       /* exchange pattern and hold spaces */
228@@ -276,16 +276,16 @@ static Fninfo fns[] = {
229     [':'] = {cmd_colon, get_colon_arg, NULL, 0},   /* defines label for later b and t commands */
230     ['='] = {cmd_equal, NULL, NULL, 1},            /* printf("%d\n", line_number); */
231     ['{'] = {cmd_lbrace, get_lbrace_arg, NULL, 2}, /* if we match, run commands, otherwise jump to
232-                                                      close */
233+ * close */
234     ['}'] = {cmd_rbrace, get_rbrace_arg, NULL, 0}, /* noop, hold onto open for ease of building
235-                                                      scripts */
236+ * scripts */
237 
238-    [0x7f] = {NULL, NULL, NULL, 0}, /* index is checked with isascii(3p).
239-               fill out rest of array */
240+    [0x7f] = {NULL, NULL, NULL, 0}, /* index is checked with isascii(3p)
241+ * fill out rest of array */
242 };
243 
244 /*
245- * Function Definitions
246+ * function definitions
247  */
248 
249 /* given memory pointed to by *ptr that currently holds *nmemb members of size
250@@ -414,7 +414,7 @@ usage(void)
251   );
252 }
253 
254-/* Differences from POSIX
255+/* differences from POSIX
256  * we allows semicolons and trailing blanks inside {}
257  * we allow spaces after ! (and in between !s)
258  * we allow extended regular expressions (-E)
259@@ -436,12 +436,12 @@ compile(char *s, int isfile)
260       eprintf("fmemopen:");
261   }
262 
263-  /* NOTE: get arg functions can't use genbuf */
264+  /* NOTE: get arg functions cant use genbuf */
265   while (read_line(f, &genbuf) != EOF) {
266     s = genbuf.str;
267 
268     /* if the first two characters of the script are "#n" default
269-     * output shall be suppressed */
270+ * output shall be suppressed */
271     if (++lineno == 1 && *s == '#' && s[1] == 'n') {
272       gflags.n = 1;
273       continue;
274@@ -594,17 +594,17 @@ find_delim(char *s, Rune delim, int do_brackets)
275   enum {
276     OUTSIDE,          /* not in brackets */
277     BRACKETS_OPENING, /* last char was first [ or last two were
278-             first [^ */
279+ * first [^ */
280     BRACKETS_INSIDE,  /* inside [] */
281     INSIDE_OPENING,   /* inside [] and last char was [ */
282     CLASS_INSIDE,     /* inside class [::], or colating element [..] or
283-             [==], inside [] */
284+ * [==], inside [] */
285     CLASS_CLOSING,    /* inside class [::], or colating element [..] or
286-             [==], and last character was the respective :
287-             . or = */
288+ * [==], and last character was the respective :
289+ * . or = */
290   } state = OUTSIDE;
291 
292-  Rune   r, c = 0; /* no c won't be used uninitialized, shutup -Wall */
293+  Rune   r, c = 0; /* no c wont be used uninitialized, shutup -wall */
294   size_t rlen;
295   int    escape = 0;
296   char  *end    = s + strlen(s);
297@@ -670,7 +670,7 @@ chompr(char *s, Rune rune)
298   return s;
299 }
300 
301-/* convert first nrunes Runes from UTF-8 string s in allocated Rune*
302+/* convert first nrunes runes from UTF-8 string s in allocated rune*
303  * NOTE: sequence must be valid UTF-8, check first */
304 static Rune *
305 strtorunes(char *s, size_t nrunes)
306@@ -717,8 +717,8 @@ escapes(char *beg, char *end, Rune delim, int n_newline)
307   char  *src = beg, *dst = beg;
308 
309   while (src < end) {
310-    /* handle escaped backslash specially so we don't think the
311-     * second backslash is escaping something */
312+    /* handle escaped backslash specially so we dont think the
313+ * second backslash is escaping something */
314     if (*src == '\\' && src[1] == '\\') {
315       *dst++ = *src++;
316       if (delim)
317@@ -736,7 +736,7 @@ escapes(char *beg, char *end, Rune delim, int n_newline)
318 
319       if (r == 'n' && delim == 'n') {
320         *src = n_newline ? '\n' : 'n'; /* src so we can still
321-                                    memmove() */
322+ * memmove() */
323       } else if (r == 'n') {
324         *src = '\n';
325       } else if (r != delim) {
326@@ -790,8 +790,8 @@ insert_labels(void)
327 }
328 
329 /*
330- * Getargs / Freeargs
331- * Read argument from s, return pointer to one past last character of argument
332+ * getargs / freeargs
333+ * read argument from s, return pointer to one past last character of argument
334  */
335 
336 /* POSIX compliant
337@@ -799,16 +799,16 @@ insert_labels(void)
338  * foobar
339  *
340  * also allow the following non POSIX compliant
341- * i        # empty line
342+ * i # empty line
343  * ifoobar
344  * ifoobar\
345  * baz
346  *
347  * FIXME: GNU and busybox discard leading spaces
348- * i  foobar
349+ * i foobar
350  * i foobar
351  * ifoobar
352- * are equivalent in GNU and busybox. We don't. Should we?
353+ * are equivalent in GNU and busybox. we dont. should we?
354  */
355 static char *
356 get_aci_arg(Cmd *c, char *s)
357@@ -850,12 +850,12 @@ free_acir_arg(Cmd *c)
358 /* POSIX dictates that label is rest of line, including semicolons, trailing
359  * whitespace, closing braces, etc. and can be limited to 8 bytes
360  *
361- * I allow a semicolon or closing brace to terminate a label name, it's not
362- * POSIX compliant, but it's useful and every sed version I've tried to date
363- * does the same.
364+ * i allow a semicolon or closing brace to terminate a label name, its not
365+ * POSIX compliant, but its useful and every sed version i've tried to date
366+ * does the same
367  *
368  * FIXME: POSIX dictates that leading whitespace is ignored but trailing
369- * whitespace is not. This is annoying and we should probably get rid of it.
370+ * whitespace is not. this is annoying and we should probably get rid of it
371  */
372 static char *
373 get_bt_arg(Cmd *c, char *s)
374@@ -876,8 +876,8 @@ get_bt_arg(Cmd *c, char *s)
375 /* POSIX dictates file name is rest of line including semicolons, trailing
376  * whitespace, closing braces, etc. and file name must be preceded by a space
377  *
378- * I allow a semicolon or closing brace to terminate a file name and don't
379- * enforce leading space.
380+ * i allow a semicolon or closing brace to terminate a file name and dont
381+ * enforce leading space
382  *
383  * FIXME: decide whether trailing whitespace should be included and fix
384  * accordingly
385@@ -908,11 +908,11 @@ get_s_arg(Cmd *c, char *s)
386   char *p;
387   int   esc, lastre;
388 
389-  /* s/Find/Replace/Flags */
390+  /* s/find/replace/flags */
391 
392-  /* Find */
393+  /* find */
394   if (!gflags.s_cont) { /* NOT continuing from literal newline in
395-         replacement text */
396+ * replacement text */
397     lastre            = 0;
398     c->u.s.repl       = (String){NULL, 0};
399     c->u.s.occurrence = 1;
400@@ -946,7 +946,7 @@ get_s_arg(Cmd *c, char *s)
401     s = p + runelen(delim);
402   }
403 
404-  /* Replace */
405+  /* replace */
406   delim = c->u.s.delim;
407 
408   p = find_delim(s, delim, 0);
409@@ -985,11 +985,11 @@ get_s_arg(Cmd *c, char *s)
410 
411   s = p + runelen(delim);
412 
413-  /* Flags */
414+  /* flags */
415   p = semicolon_arg(s = chomp(s));
416 
417   /* FIXME: currently for simplicity take last of g or occurrence flags
418-   * and ignore multiple p flags. need to fix that */
419+ * and ignore multiple p flags. need to fix that */
420   for (; s < p; s++) {
421     if (isdigit(*s)) {
422       c->u.s.occurrence = stol(s, &s);
423@@ -1004,7 +1004,7 @@ get_s_arg(Cmd *c, char *s)
424           break;
425         case 'w':
426           /* must be last flag, take everything up to
427-           * newline/semicolon s == p after this */
428+ * newline/semicolon s == p after this */
429           s           = get_w_arg(&buf, chomp(s + 1));
430           c->u.s.file = buf.u.file;
431           break;
432@@ -1126,10 +1126,10 @@ get_rbrace_arg(Cmd *c, char *s)
433  * return pointer to semicolon or nul byte after string
434  * or closing brace as to not force ; before }
435  * FIXME: decide whether or not to eat trailing whitespace for arguments that
436- *        we allow semicolon/brace termination that POSIX doesn't
437- *        b, r, t, w, :
438- *        POSIX says trailing whitespace is part of label name, file name, etc.
439- *        we should probably eat it
440+ * we allow semicolon/brace termination that POSIX doesnt
441+ * b, r, t, w, :
442+ * POSIX says trailing whitespace is part of label name, file name, etc
443+ * we should probably eat it
444  */
445 static char *
446 semicolon_arg(char *s)
447@@ -1148,7 +1148,7 @@ run(void)
448     leprintf("extra {");
449 
450   /* genbuf has already been initialized, patt will be in new_line
451-   * (or we'll halt) */
452+ * (or we'll halt) */
453   stracpy(&hold, "");
454 
455   insert_labels();
456@@ -1311,7 +1311,7 @@ write_patt(char *s, FILE *f)
457 #endif
458 }
459 
460-/* iterate from beg to end updating ranges so we don't miss any commands
461+/* iterate from beg to end updating ranges so we dont miss any commands
462  * e.g. sed -n '1d;1,3p' should still print lines 2 and 3
463  */
464 static void
465@@ -1322,7 +1322,7 @@ update_ranges(Cmd *beg, Cmd *end)
466 }
467 
468 /*
469- * Sed functions
470+ * sed functions
471  */
472 static void
473 cmd_a(Cmd *c)
474@@ -1338,7 +1338,7 @@ cmd_b(Cmd *c)
475     return;
476 
477   /* if we jump backwards update to end, otherwise update to destination
478-   */
479+ */
480   update_ranges(c + 1, c->u.jump > c ? c->u.jump : prog + pcap);
481   pc = c->u.jump;
482 }
483@@ -1353,7 +1353,7 @@ cmd_c(Cmd *c)
484   if (!c->in_match)
485     check_puts(c->u.acir.str.str, stdout);
486   /* otherwise start the next cycle without printing pattern space
487-   * effectively deleting the text */
488+ * effectively deleting the text */
489   new_next();
490 }
491 
492@@ -1424,7 +1424,7 @@ cmd_i(Cmd *c)
493     check_puts(c->u.acir.str.str, stdout);
494 }
495 
496-/* I think it makes sense to print invalid UTF-8 sequences in octal to satisfy
497+/* i think it makes sense to print invalid UTF-8 sequences in octal to satisfy
498  * the "visually unambiguous form" sed(1p)
499  */
500 static void
501@@ -1450,16 +1450,16 @@ cmd_l(Cmd *c)
502     return;
503 
504   /* FIXME: line wrapping. sed(1p) says "length at which folding occurs is
505-   * unspecified, but should be appropraite for the output device"
506-   * just wrap at 80 Runes?
507-   */
508+ * unspecified, but should be appropraite for the output device"
509+ * just wrap at 80 runes?
510+ */
511   for (p = patt.str, end = p + strlen(p); p < end; p += rlen) {
512     if (isascii(*p) && escapes[(unsigned int)*p]) {
513       fputs(escapes[(unsigned int)*p], stdout);
514       rlen = 1;
515     } else if (!(rlen = charntorune(&r, p, end - p))) {
516       /* ran out of chars, print the bytes of the short
517-       * sequence */
518+ * sequence */
519       for (; p < end; p++)
520         printf("\\%03hho", (unsigned char)*p);
521       break;
522@@ -1568,21 +1568,21 @@ cmd_s(Cmd *c)
523 
524   while (!qflag && !regexec(re, s, plen, pmatch, cflags)) {
525     cflags = REG_NOTBOL; /* match against beginning of line first
526-          time, but not again */
527+ * time, but not again */
528     if (!*s)             /* match against empty string first time, but not again
529-                          */
530+ */
531       qflag = 1;
532 
533-    /* don't substitute if last match was not empty but this one is.
534-     * s_a*_._g
535-     * foobar -> .f.o.o.b.r.
536-     */
537+    /* dont substitute if last match was not empty but this one is
538+ * s_a*_._g
539+ * foobar -> .f.o.o.b.r
540+ */
541     if ((last_empty || pmatch[0].rm_eo) && (++matches == c->u.s.occurrence || !c->u.s.occurrence)) {
542       /* copy over everything before the match */
543       strnacat(&genbuf, s, pmatch[0].rm_so);
544 
545       /* copy over replacement text, taking into account &,
546-       * backreferences, and \ escapes */
547+ * backreferences, and \ escapes */
548       for (p = c->u.s.repl.str, len = strcspn(p, "\\&"); *p; len = strcspn(++p, "\\&")) {
549         strnacat(&genbuf, p, len);
550         p += len;
551@@ -1592,8 +1592,8 @@ cmd_s(Cmd *c)
552             break;
553           case '\0':
554             /* we're at the end, back up one so the
555-             * ++p will put us on the null byte to
556-             * break out of the loop */
557+ * ++p will put us on the null byte to
558+ * break out of the loop */
559             --p;
560             break;
561           case '&':
562@@ -1602,8 +1602,8 @@ cmd_s(Cmd *c)
563           case '\\':
564             if (isdigit(*++p)) { /* backreference */
565               /* only need to check here if
566-               * using lastre, otherwise we
567-               * checked when building */
568+ * using lastre, otherwise we
569+ * checked when building */
570               if (!c->u.s.re && (size_t)(*p - '0') > re->re_nsub)
571                 leprintf(
572                     "back "
573@@ -1616,8 +1616,8 @@ cmd_s(Cmd *c)
574               rm = &pmatch[*p - '0'];
575               strnacat(&genbuf, s + rm->rm_so, rm->rm_eo - rm->rm_so);
576             } else { /* character after backslash
577-                  taken literally (well one
578-                  byte, but it works) */
579+ * taken literally (well one
580+ * byte, but it works) */
581               strnacat(&genbuf, p, 1);
582             }
583             break;
584@@ -1625,19 +1625,19 @@ cmd_s(Cmd *c)
585       }
586     } else {
587       /* not replacing, copy over everything up to and
588-       * including the match */
589+ * including the match */
590       strnacat(&genbuf, s, pmatch[0].rm_eo);
591     }
592 
593     if (!pmatch[0].rm_eo) { /* empty match, advance one rune and add
594-             it to output */
595+ * it to output */
596       end  = s + strlen(s);
597       rlen = charntorune(&r, s, end - s);
598 
599       if (!rlen) { /* ran out of bytes, copy short sequence */
600         stracat(&genbuf, s);
601         s = end;
602-      } else { /* copy whether or not it's a good rune */
603+      } else { /* copy whether or not its a good rune */
604         strnacat(&genbuf, s, rlen);
605         s += rlen;
606       }
607@@ -1671,7 +1671,7 @@ cmd_t(Cmd *c)
608     return;
609 
610   /* if we jump backwards update to end, otherwise update to destination
611-   */
612+ */
613   update_ranges(c + 1, c->u.jump > c ? c->u.jump : prog + pcap);
614   pc       = c->u.jump;
615   gflags.s = 0;
616@@ -1719,8 +1719,8 @@ cmd_y(Cmd *c)
617       for (rp = c->u.y.set1; *rp; rp++)
618         if (*rp == r)
619           break;
620-      if (*rp) { /* found r in set1, replace with Rune from
621-              set2 */
622+      if (*rp) { /* found r in set1, replace with rune from
623+ * set2 */
624         n = runetochar(buf, c->u.y.set2 + (rp - c->u.y.set1));
625         strnacat(&genbuf, buf, n);
626       } else {
627@@ -1778,7 +1778,7 @@ cmd_last(Cmd *c)
628 }
629 
630 /*
631- * Actions
632+ * actions
633  */
634 
635 /* read new line, continue current cycle */
636@@ -1796,9 +1796,9 @@ new_line(void)
637 }
638 
639 /* append new line, continue current cycle
640- * FIXME: used for N, POSIX specifies do not print pattern space when out of
641- *        input, but GNU does so busybox does as well. Currently we don't.
642- *        Should we?
643+ * FIXME: used for n, POSIX specifies do not print pattern space when out of
644+ * input, but GNU does so busybox does as well. currently we dont
645+ * should we?
646  */
647 static void
648 app_line(void)
+24, -24
 1@@ -1,35 +1,35 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 #include "alias.h"
55@@ -87,12 +87,12 @@ unalias(const char *name)
56   for (ap = *app; ap; app = &(ap->next), ap = ap->next) {
57     if (equal(name, ap->name)) {
58       /*
59-       * if the alias is currently in use (i.e. its
60-       * buffer is being used by the input routine) we
61-       * just null out the name instead of freeing it.
62-       * We could clear it out later, but this situation
63-       * is so rare that it hardly seems worth it.
64-       */
65+ * if the alias is currently in use (i.e. its
66+ * buffer is being used by the input routine) we
67+ * just null out the name instead of freeing it
68+ * we could clear it out later, but this situation
69+ * is so rare that it hardly seems worth it
70+ */
71       if (ap->flag & ALIASINUSE)
72         *ap->name = '\0';
73       else {
+18, -18
 1@@ -1,35 +1,35 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 #define ALIASINUSE 1
+16, -16
 1@@ -1,32 +1,32 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1995
 8- *      The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1995
10+ * the regents of the university of california. all rights reserved
11  *
12- * Redistribution and use in source and binary forms, with or without
13+ * redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16- * 1. Redistributions of source code must retain the above copyright
17- *    notice, this list of conditions and the following disclaimer.
18- * 2. Redistributions in binary form must reproduce the above copyright
19- *    notice, this list of conditions and the following disclaimer in the
20- *    documentation and/or other materials provided with the distribution.
21- * 3. Neither the name of the University nor the names of its contributors
22- *    may be used to endorse or promote products derived from this software
23- *    without specific prior written permission.
24+ * 1. redistributions of source code must retain the above copyright
25+ * notice, this list of conditions and the following disclaimer
26+ * 2. redistributions in binary form must reproduce the above copyright
27+ * notice, this list of conditions and the following disclaimer in the
28+ * documentation and/or other materials provided with the distribution
29+ * 3. neither the name of the university nor the names of its contributors
30+ * may be used to endorse or promote products derived from this software
31+ * without specific prior written permission
32  *
33  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
34  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
37+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
38+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
39  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45- * SUCH DAMAGE.
46+ * SUCH DAMAGE
47  */
48 
49 #include "shell.h"
+23, -23
 1@@ -1,37 +1,37 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9- * Copyright (c) 2007
10- *	Herbert Xu <herbert@gondor.apana.org.au>.  All rights reserved.
11+ * copyright (c) 1993
12+ * the regents of the university of california. all rights reserved
13+ * copyright (c) 2007
14+ * herbert xu <herbert@gondor.apana.org.au>. all rights reserved
15  *
16- * This code is derived from software contributed to Berkeley by
17- * Kenneth Almquist.
18+ * this code is derived from software contributed to berkeley by
19+ * kenneth almquist
20  *
21- * Redistribution and use in source and binary forms, with or without
22+ * redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25- * 1. Redistributions of source code must retain the above copyright
26- *    notice, this list of conditions and the following disclaimer.
27- * 2. Redistributions in binary form must reproduce the above copyright
28- *    notice, this list of conditions and the following disclaimer in the
29- *    documentation and/or other materials provided with the distribution.
30- * 3. Neither the name of the University nor the names of its contributors
31- *    may be used to endorse or promote products derived from this software
32- *    without specific prior written permission.
33+ * 1. redistributions of source code must retain the above copyright
34+ * notice, this list of conditions and the following disclaimer
35+ * 2. redistributions in binary form must reproduce the above copyright
36+ * notice, this list of conditions and the following disclaimer in the
37+ * documentation and/or other materials provided with the distribution
38+ * 3. neither the name of the university nor the names of its contributors
39+ * may be used to endorse or promote products derived from this software
40+ * without specific prior written permission
41  *
42  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
43  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
46+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
47+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54- * SUCH DAMAGE.
55+ * SUCH DAMAGE
56  */
57 
58 #if defined(__has_include)
59@@ -357,7 +357,7 @@ arith(const char *s)
60 }
61 
62 /*
63- *  The exp(1) builtin.
64+ * the exp(1) builtin
65  */
66 int
67 letcmd(int argc, char **argv)
68@@ -371,8 +371,8 @@ letcmd(int argc, char **argv)
69     p = argv[1];
70     if (argc > 2) {
71       /*
72-       * Concatenate arguments.
73-       */
74+ * concatenate arguments
75+ */
76       STARTSTACKSTR(concat);
77       ap = argv + 2;
78       for (;;) {
+20, -20
 1@@ -1,37 +1,37 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1993
 8- *      The Regents of the University of California.  All rights reserved.
 9- * Copyright (c) 2007
10- *      Herbert Xu <herbert@gondor.apana.org.au>.  All rights reserved.
11+ * copyright (c) 1993
12+ * the regents of the university of california. all rights reserved
13+ * copyright (c) 2007
14+ * herbert xu <herbert@gondor.apana.org.au>. all rights reserved
15  *
16- * This code is derived from software contributed to Berkeley by
17- * Kenneth Almquist.
18+ * this code is derived from software contributed to berkeley by
19+ * kenneth almquist
20  *
21- * Redistribution and use in source and binary forms, with or without
22+ * redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25- * 1. Redistributions of source code must retain the above copyright
26- *    notice, this list of conditions and the following disclaimer.
27- * 2. Redistributions in binary form must reproduce the above copyright
28- *    notice, this list of conditions and the following disclaimer in the
29- *    documentation and/or other materials provided with the distribution.
30- * 3. Neither the name of the University nor the names of its contributors
31- *    may be used to endorse or promote products derived from this software
32- *    without specific prior written permission.
33+ * 1. redistributions of source code must retain the above copyright
34+ * notice, this list of conditions and the following disclaimer
35+ * 2. redistributions in binary form must reproduce the above copyright
36+ * notice, this list of conditions and the following disclaimer in the
37+ * documentation and/or other materials provided with the distribution
38+ * 3. neither the name of the university nor the names of its contributors
39+ * may be used to endorse or promote products derived from this software
40+ * without specific prior written permission
41  *
42  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
43  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
46+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
47+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54- * SUCH DAMAGE.
55+ * SUCH DAMAGE
56  */
57 
58 #include "shell.h"
+20, -20
 1@@ -1,37 +1,37 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 2002
 8- *	Herbert Xu.
 9- * Copyright (c) 1993
10- *	The Regents of the University of California.  All rights reserved.
11+ * copyright (c) 2002
12+ * herbert xu
13+ * copyright (c) 1993
14+ * the regents of the university of california. all rights reserved
15  *
16- * This code is derived from software contributed to Berkeley by
17- * Kenneth Almquist.
18+ * this code is derived from software contributed to berkeley by
19+ * kenneth almquist
20  *
21- * Redistribution and use in source and binary forms, with or without
22+ * redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25- * 1. Redistributions of source code must retain the above copyright
26- *    notice, this list of conditions and the following disclaimer.
27- * 2. Redistributions in binary form must reproduce the above copyright
28- *    notice, this list of conditions and the following disclaimer in the
29- *    documentation and/or other materials provided with the distribution.
30- * 3. Neither the name of the University nor the names of its contributors
31- *    may be used to endorse or promote products derived from this software
32- *    without specific prior written permission.
33+ * 1. redistributions of source code must retain the above copyright
34+ * notice, this list of conditions and the following disclaimer
35+ * 2. redistributions in binary form must reproduce the above copyright
36+ * notice, this list of conditions and the following disclaimer in the
37+ * documentation and/or other materials provided with the distribution
38+ * 3. neither the name of the university nor the names of its contributors
39+ * may be used to endorse or promote products derived from this software
40+ * without specific prior written permission
41  *
42  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
43  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
46+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
47+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54- * SUCH DAMAGE.
55+ * SUCH DAMAGE
56  */
57 
58 #if defined(__has_include)
+21, -21
 1@@ -1,41 +1,41 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 /*
55- * This file is included by programs which are optionally built into the
56- * shell.  If SHELL is defined, we try to map the standard UNIX library
57- * routines to ash routines using defines.
58+ * this file is included by programs which are optionally built into the
59+ * shell. if SHELL is defined, we try to map the standard UNIX library
60+ * routines to ash routines using defines
61  */
62 
63 #include "mystring.h"
+47, -47
  1@@ -1,35 +1,35 @@
  2-/*-
  3- * SPDX-License-Identifier: BSD-3-Clause
  4+/* -
  5+ * spdx-license-identifier: bsd-3-clause
  6  *
  7- * Copyright (c) 1991, 1993
  8- *	The Regents of the University of California.  All rights reserved.
  9+ * copyright (c) 1991, 1993
 10+ * the regents of the university of california. all rights reserved
 11  *
 12- * This code is derived from software contributed to Berkeley by
 13- * Kenneth Almquist.
 14+ * this code is derived from software contributed to berkeley by
 15+ * kenneth almquist
 16  *
 17- * Redistribution and use in source and binary forms, with or without
 18+ * redistribution and use in source and binary forms, with or without
 19  * modification, are permitted provided that the following conditions
 20  * are met:
 21- * 1. Redistributions of source code must retain the above copyright
 22- *    notice, this list of conditions and the following disclaimer.
 23- * 2. Redistributions in binary form must reproduce the above copyright
 24- *    notice, this list of conditions and the following disclaimer in the
 25- *    documentation and/or other materials provided with the distribution.
 26- * 3. Neither the name of the University nor the names of its contributors
 27- *    may be used to endorse or promote products derived from this software
 28- *    without specific prior written permission.
 29+ * 1. redistributions of source code must retain the above copyright
 30+ * notice, this list of conditions and the following disclaimer
 31+ * 2. redistributions in binary form must reproduce the above copyright
 32+ * notice, this list of conditions and the following disclaimer in the
 33+ * documentation and/or other materials provided with the distribution
 34+ * 3. neither the name of the university nor the names of its contributors
 35+ * may be used to endorse or promote products derived from this software
 36+ * without specific prior written permission
 37  *
 38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
 43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 50- * SUCH DAMAGE.
 51+ * SUCH DAMAGE
 52  */
 53 
 54 #include <errno.h>
 55@@ -41,7 +41,7 @@
 56 #include <unistd.h>
 57 
 58 /*
 59- * The cd and pwd commands.
 60+ * the cd and pwd commands
 61  */
 62 
 63 #include "builtins.h"
 64@@ -120,8 +120,8 @@ cdcmd(int argc __unused, char **argv __unused)
 65     else {
 66       if (!print) {
 67         /*
 68-         * XXX - rethink
 69-         */
 70+ * XXX - rethink
 71+ */
 72         if (p[0] == '.' && p[1] == '/' && p[2] != '\0')
 73           print = strcmp(p + 2, dest);
 74         else
 75@@ -135,13 +135,13 @@ cdcmd(int argc __unused, char **argv __unused)
 76     }
 77   }
 78   error("%s: %s", dest, strerror(errno1));
 79-  /*NOTREACHED*/
 80+  /* NOTREACHED */
 81   return 0;
 82 }
 83 
 84 /*
 85- * Actually change the directory.  In an interactive shell, print the
 86- * directory name if "print" is nonzero.
 87+ * actually change the directory. in an interactive shell, print the
 88+ * directory name if "print" is nonzero
 89  */
 90 static int
 91 docd(char *dest, int print, int phys)
 92@@ -150,18 +150,18 @@ docd(char *dest, int print, int phys)
 93 
 94   TRACE(("docd(\"%s\", %d, %d) called\n", dest, print, phys));
 95 
 96-  /* If logical cd fails, fall back to physical. */
 97+  /* if logical cd fails, fall back to physical */
 98   if ((phys || (rc = cdlogical(dest)) < 0) && (rc = cdphysical(dest)) < 0)
 99     return (-1);
100 
101   if (print && iflag && curdir) {
102     out1fmt("%s\n", curdir);
103     /*
104-     * Ignore write errors to preserve the invariant that the
105-     * current directory is changed iff the exit status is 0
106-     * (or 1 if -e was given and the full pathname could not be
107-     * determined).
108-     */
109+ * ignore write errors to preserve the invariant that the
110+ * current directory is changed iff the exit status is 0
111+ * (or 1 if -e was given and the full pathname could not be
112+ * determined)
113+ */
114     flushout(out1);
115     outclearerror(out1);
116   }
117@@ -181,10 +181,10 @@ cdlogical(char *dest)
118   int         badstat;
119 
120   /*
121-   *  Check each component of the path. If we find a symlink or
122-   *  something we can't stat, clear curdir to force a getcwd()
123-   *  next time we get the value of the current directory.
124-   */
125+ * check each component of the path. if we find a symlink or
126+ * something we cant stat, clear curdir to force a getcwd()
127+ * next time we get the value of the current directory
128+ */
129   badstat = 0;
130   path    = stsavestr(dest);
131   STARTSTACKSTR(p);
132@@ -242,8 +242,8 @@ cdphysical(char *dest)
133 }
134 
135 /*
136- * Get the next component of the path name pointed to by *path.
137- * This routine overwrites *path and the string pointed to by it.
138+ * get the next component of the path name pointed to by *path
139+ * this routine overwrites *path and the string pointed to by it
140  */
141 static char *
142 getcomponent(char **path)
143@@ -273,10 +273,10 @@ findcwd(char *dir)
144   char *path;
145 
146   /*
147-   * If our argument is NULL, we don't know the current directory
148-   * any more because we traversed a symbolic link or something
149-   * we couldn't stat().
150-   */
151+ * if our argument is NULL, we dont know the current directory
152+ * any more because we traversed a symbolic link or something
153+ * we couldnt stat()
154+ */
155   if (dir == NULL || curdir == NULL)
156     return getpwd2();
157   path = stsavestr(dir);
158@@ -302,9 +302,9 @@ findcwd(char *dir)
159 }
160 
161 /*
162- * Update curdir (the name of the current directory) in response to a
163- * cd command.  We also call hashcd to let the routines in exec.c know
164- * that the current directory has changed.
165+ * update curdir (the name of the current directory) in response to a
166+ * cd command. we also call hashcd to let the routines in exec.c know
167+ * that the current directory has changed
168  */
169 static void
170 updatepwd(char *dir)
171@@ -353,7 +353,7 @@ pwdcmd(int argc __unused, char **argv __unused)
172 }
173 
174 /*
175- * Get the current directory and cache the result in curdir.
176+ * get the current directory and cache the result in curdir
177  */
178 static char *
179 getpwd(void)
180@@ -376,7 +376,7 @@ getpwd(void)
181 #define MAXPWD 256
182 
183 /*
184- * Return the current directory.
185+ * return the current directory
186  */
187 static char *
188 getpwd2(void)
189@@ -397,8 +397,8 @@ getpwd2(void)
190 }
191 
192 /*
193- * Initialize PWD in a new shell.
194- * If the shell is interactive, we need to warn if this fails.
195+ * initialize PWD in a new shell
196+ * if the shell is interactive, we need to warn if this fails
197  */
198 void
199 pwd_init(int warn)
+16, -16
 1@@ -1,32 +1,32 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1995
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1995
10+ * the regents of the university of california. all rights reserved
11  *
12- * Redistribution and use in source and binary forms, with or without
13+ * redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16- * 1. Redistributions of source code must retain the above copyright
17- *    notice, this list of conditions and the following disclaimer.
18- * 2. Redistributions in binary form must reproduce the above copyright
19- *    notice, this list of conditions and the following disclaimer in the
20- *    documentation and/or other materials provided with the distribution.
21- * 3. Neither the name of the University nor the names of its contributors
22- *    may be used to endorse or promote products derived from this software
23- *    without specific prior written permission.
24+ * 1. redistributions of source code must retain the above copyright
25+ * notice, this list of conditions and the following disclaimer
26+ * 2. redistributions in binary form must reproduce the above copyright
27+ * notice, this list of conditions and the following disclaimer in the
28+ * documentation and/or other materials provided with the distribution
29+ * 3. neither the name of the university nor the names of its contributors
30+ * may be used to endorse or promote products derived from this software
31+ * without specific prior written permission
32  *
33  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
34  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
37+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
38+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
39  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45- * SUCH DAMAGE.
46+ * SUCH DAMAGE
47  */
48 
49 void pwd_init(int);
+7, -7
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 #include "bltin.h"
 5 #include "fs.h"
 6 #include "util.h"
 7@@ -15,8 +15,8 @@ enum {
 8   COMMENT_HASH,    /* line # only */
 9   COMMENT_PERCENT, /* line % only */
10   COMMENT_SEMI,    /* line ; only */
11-  COMMENT_DASH,    /* line -- only */
12-  COMMENT_HASKELL, /* line -- and block {- -} */
13+  COMMENT_DASH,    /* line, only */
14+  COMMENT_HASKELL, /* line, and block {- -} */
15   COMMENT_PAREN,   /* block (* *) only, no line comment */
16 };
17 
18@@ -60,7 +60,7 @@ struct CommentSpec {
19 };
20 
21 static const struct CommentSpec comment_specs[] = {
22-    [COMMENT_C]       = {"//", "/*", "*/"},
23+    [COMMENT_C]       = {"// ", "/*", "*/"},
24     [COMMENT_HASH]    = {"#", NULL, NULL},
25     [COMMENT_PERCENT] = {"%", NULL, NULL},
26     [COMMENT_SEMI]    = {";", NULL, NULL},
27@@ -261,9 +261,9 @@ detect_lang(const char *name)
28   }
29 
30   /*
31-   * anchored to the end of the name, so arch.txt (which contains "rc"
32-   * but does not end in it) is never mistaken for a shell rc file
33-   */
34+ * anchored to the end of the name, so arch.txt (which contains "rc"
35+ * but does not end in it) is never mistaken for a shell rc file
36+ */
37   nlen = strlen(name);
38   if (nlen >= 2 && !strcmp(name + nlen - 2, "rc"))
39     return LANG_SH;
+19, -19
 1@@ -1,41 +1,41 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 #include "bltin.h"
55 
56 /*
57- * Echo command.
58+ * echo command
59  */
60 
61 #define main echocmd
+43, -43
  1@@ -1,39 +1,39 @@
  2-/*-
  3- * SPDX-License-Identifier: BSD-3-Clause
  4+/* -
  5+ * spdx-license-identifier: bsd-3-clause
  6  *
  7- * Copyright (c) 1991, 1993
  8- *	The Regents of the University of California.  All rights reserved.
  9+ * copyright (c) 1991, 1993
 10+ * the regents of the university of california. all rights reserved
 11  *
 12- * This code is derived from software contributed to Berkeley by
 13- * Kenneth Almquist.
 14+ * this code is derived from software contributed to berkeley by
 15+ * kenneth almquist
 16  *
 17- * Redistribution and use in source and binary forms, with or without
 18+ * redistribution and use in source and binary forms, with or without
 19  * modification, are permitted provided that the following conditions
 20  * are met:
 21- * 1. Redistributions of source code must retain the above copyright
 22- *    notice, this list of conditions and the following disclaimer.
 23- * 2. Redistributions in binary form must reproduce the above copyright
 24- *    notice, this list of conditions and the following disclaimer in the
 25- *    documentation and/or other materials provided with the distribution.
 26- * 3. Neither the name of the University nor the names of its contributors
 27- *    may be used to endorse or promote products derived from this software
 28- *    without specific prior written permission.
 29+ * 1. redistributions of source code must retain the above copyright
 30+ * notice, this list of conditions and the following disclaimer
 31+ * 2. redistributions in binary form must reproduce the above copyright
 32+ * notice, this list of conditions and the following disclaimer in the
 33+ * documentation and/or other materials provided with the distribution
 34+ * 3. neither the name of the university nor the names of its contributors
 35+ * may be used to endorse or promote products derived from this software
 36+ * without specific prior written permission
 37  *
 38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
 43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 50- * SUCH DAMAGE.
 51+ * SUCH DAMAGE
 52  */
 53 
 54 /*
 55- * Errors and exceptions.
 56+ * errors and exceptions
 57  */
 58 
 59 #include "error.h"
 60@@ -51,7 +51,7 @@
 61 #include <unistd.h>
 62 
 63 /*
 64- * Code to handle exceptions in C.
 65+ * code to handle exceptions in c
 66  */
 67 
 68 struct jmploc        *handler;
 69@@ -62,12 +62,12 @@ volatile sig_atomic_t intpending;
 70 static void verrorwithstatus(int, const char *, va_list) __printf0like(2, 0) __dead2;
 71 
 72 /*
 73- * Called to raise an exception.  Since C doesn't include exceptions, we
 74- * just do a longjmp to the exception handler.  The type of exception is
 75- * stored in the global variable "exception".
 76+ * called to raise an exception. since c doesnt include exceptions, we
 77+ * just do a longjmp to the exception handler. the type of exception is
 78+ * stored in the global variable "exception"
 79  *
 80- * Interrupts are disabled; they should be re-enabled when the exception is
 81- * caught.
 82+ * interrupts are disabled; they should be re-enabled when the exception is
 83+ * caught
 84  */
 85 
 86 void
 87@@ -81,14 +81,14 @@ exraise(int e)
 88 }
 89 
 90 /*
 91- * Called from trap.c when a SIGINT is received and not suppressed, or when
 92- * an interrupt is pending and interrupts are re-enabled using INTON.
 93- * (If the user specifies that SIGINT is to be trapped or ignored using the
 94- * trap builtin, then this routine is not called.)  Suppressint is nonzero
 95- * when interrupts are held using the INTOFF macro.  If SIGINTs are not
 96+ * called from trap.c when a SIGINT is received and not suppressed, or when
 97+ * an interrupt is pending and interrupts are re-enabled using INTON
 98+ * (if the user specifies that SIGINT is to be trapped or ignored using the
 99+ * trap builtin, then this routine is not called.) suppressint is nonzero
100+ * when interrupts are held using the INTOFF macro. if sigints are not
101  * suppressed and the shell is not a root shell, then we want to be
102- * terminated if we get here, as if we were terminated directly by a SIGINT.
103- * Arrange for this here.
104+ * terminated if we get here, as if we were terminated directly by a SIGINT
105+ * arrange for this here
106  */
107 
108 void
109@@ -101,8 +101,8 @@ onint(void)
110   sigprocmask(SIG_SETMASK, &sigs, NULL);
111 
112   /*
113-   * This doesn't seem to be needed, since main() emits a newline.
114-   */
115+ * this doesnt seem to be needed, since main() emits a newline
116+ */
117 #if 0
118 	if (tcgetpgrp(0) == getpid())
119 		write(STDERR_FILENO, "\n", 1);
120@@ -137,21 +137,21 @@ warning(const char *msg, ...)
121 }
122 
123 /*
124- * Exverror is called to raise the error exception.  If the first argument
125+ * exverror is called to raise the error exception. if the first argument
126  * is not NULL then error prints an error message using printf style
127- * formatting.  It then raises the error exception.
128+ * formatting. it then raises the error exception
129  */
130 static void
131 verrorwithstatus(int status, const char *msg, va_list ap)
132 {
133   /*
134-   * An interrupt trumps an error.  Certain places catch error
135-   * exceptions or transform them to a plain nonzero exit code
136-   * in child processes, and if an error exception can be handled,
137-   * an interrupt can be handled as well.
138-   *
139-   * exraise() will disable interrupts for the exception handler.
140-   */
141+ * an interrupt trumps an error. certain places catch error
142+ * exceptions or transform them to a plain nonzero exit code
143+ * in child processes, and if an error exception can be handled,
144+ * an interrupt can be handled as well
145+ *
146+ * exraise() will disable interrupts for the exception handler
147+ */
148   FORCEINTON;
149 
150 #ifdef DEBUG
+27, -27
 1@@ -1,47 +1,47 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 #include "sh_cdefs.h"
55 
56 /*
57- * We enclose jmp_buf in a structure so that we can declare pointers to
58- * jump locations.  The global variable handler contains the location to
59+ * we enclose jmp_buf in a structure so that we can declare pointers to
60+ * jump locations. the global variable handler contains the location to
61  * jump to when an exception occurs, and the global variable exception
62- * contains a code identifying the exception.  To implement nested
63+ * contains a code identifying the exception. to implement nested
64  * exception handlers, the user should save the value of handler on entry
65  * to an inner scope, set handler to point to a jmploc structure for the
66- * inner scope, and restore handler on exit from the scope.
67+ * inner scope, and restore handler on exit from the scope
68  */
69 
70 #include <setjmp.h>
71@@ -60,9 +60,9 @@ extern volatile sig_atomic_t exception;
72 #define EXEXIT  2 /* call exitshell(exitstatus) */
73 
74 /*
75- * These macros allow the user to suspend the handling of interrupt signals
76- * over a period of time.  This is similar to SIGHOLD to or sigblock, but
77- * much more efficient and portable.  (But hacking the kernel is so much
78+ * these macros allow the user to suspend the handling of interrupt signals
79+ * over a period of time. this is similar to SIGHOLD to or sigblock, but
80+ * much more efficient and portable. (but hacking the kernel is so much
81  * more fun than worrying about efficiency and portability. :-))
82  */
83 
84@@ -99,8 +99,8 @@ void error(const char *, ...) __printf0like(1, 2) __dead2;
85 void errorwithstatus(int, const char *, ...) __printf0like(2, 3) __dead2;
86 
87 /*
88- * BSD setjmp saves the signal mask, which violates ANSI C and takes time,
89- * so we use _setjmp instead.
90+ * BSD setjmp saves the signal mask, which violates ANSI c and takes time,
91+ * so we use _setjmp instead
92  */
93 
94 #undef setjmp
+115, -115
  1@@ -1,35 +1,35 @@
  2-/*-
  3- * SPDX-License-Identifier: BSD-3-Clause
  4+/* -
  5+ * spdx-license-identifier: bsd-3-clause
  6  *
  7- * Copyright (c) 1993
  8- *	The Regents of the University of California.  All rights reserved.
  9+ * copyright (c) 1993
 10+ * the regents of the university of california. all rights reserved
 11  *
 12- * This code is derived from software contributed to Berkeley by
 13- * Kenneth Almquist.
 14+ * this code is derived from software contributed to berkeley by
 15+ * kenneth almquist
 16  *
 17- * Redistribution and use in source and binary forms, with or without
 18+ * redistribution and use in source and binary forms, with or without
 19  * modification, are permitted provided that the following conditions
 20  * are met:
 21- * 1. Redistributions of source code must retain the above copyright
 22- *    notice, this list of conditions and the following disclaimer.
 23- * 2. Redistributions in binary form must reproduce the above copyright
 24- *    notice, this list of conditions and the following disclaimer in the
 25- *    documentation and/or other materials provided with the distribution.
 26- * 3. Neither the name of the University nor the names of its contributors
 27- *    may be used to endorse or promote products derived from this software
 28- *    without specific prior written permission.
 29+ * 1. redistributions of source code must retain the above copyright
 30+ * notice, this list of conditions and the following disclaimer
 31+ * 2. redistributions in binary form must reproduce the above copyright
 32+ * notice, this list of conditions and the following disclaimer in the
 33+ * documentation and/or other materials provided with the distribution
 34+ * 3. neither the name of the university nor the names of its contributors
 35+ * may be used to endorse or promote products derived from this software
 36+ * without specific prior written permission
 37  *
 38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
 43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 50- * SUCH DAMAGE.
 51+ * SUCH DAMAGE
 52  */
 53 
 54 #include <errno.h>
 55@@ -39,7 +39,7 @@
 56 #include <unistd.h>
 57 
 58 /*
 59- * Evaluate a command.
 60+ * evaluate a command
 61  */
 62 
 63 #include "../../../shared/paths.h"
 64@@ -91,7 +91,7 @@ static void        evalcommand(union node *, int, struct backcmd *);
 65 static void        prehash(union node *);
 66 
 67 /*
 68- * Called to reset things after an exception.
 69+ * called to reset things after an exception
 70  */
 71 
 72 void
 73@@ -102,7 +102,7 @@ reseteval(void)
 74 }
 75 
 76 /*
 77- * The eval command.
 78+ * the eval command
 79  */
 80 
 81 int
 82@@ -133,7 +133,7 @@ evalcmd(int argc, char **argv)
 83 }
 84 
 85 /*
 86- * Execute a command or commands contained in a string.
 87+ * execute a command or commands contained in a string
 88  */
 89 
 90 void
 91@@ -171,8 +171,8 @@ evalstring(const char *s, int flags)
 92 }
 93 
 94 /*
 95- * Evaluate a parse tree.  The value is left in the global variable
 96- * exitstatus.
 97+ * evaluate a parse tree. the value is left in the global variable
 98+ * exitstatus
 99  */
100 
101 void
102@@ -366,9 +366,9 @@ evalfor(union node *n, int flags)
103 }
104 
105 /*
106- * Evaluate a case statement, returning the selected tree.
107+ * evaluate a case statement, returning the selected tree
108  *
109- * The exit status needs care to get right.
110+ * the exit status needs care to get right
111  */
112 
113 static union node *
114@@ -399,7 +399,7 @@ evalcase(union node *n)
115 }
116 
117 /*
118- * Kick off a subshell to evaluate a tree.
119+ * kick off a subshell to evaluate a tree
120  */
121 
122 static void
123@@ -425,7 +425,7 @@ evalsubshell(union node *n, int flags)
124 }
125 
126 /*
127- * Evaluate a redirected compound command.
128+ * evaluate a redirected compound command
129  */
130 
131 static void
132@@ -497,7 +497,7 @@ exphere(union node *redir, struct arglist *fn)
133 }
134 
135 /*
136- * Compute the names of the files in a redirection list.
137+ * compute the names of the files in a redirection list
138  */
139 
140 static void
141@@ -532,8 +532,8 @@ expredir(union node *n)
142 }
143 
144 /*
145- * Evaluate a pipeline.  All the processes in the pipeline are children
146- * of the process creating the pipeline.  (This differs from some versions
147+ * evaluate a pipeline. all the processes in the pipeline are children
148+ * of the process creating the pipeline. (this differs from some versions
149  * of the shell, which make the last process in a pipeline the parent
150  * of all the rest.)
151  */
152@@ -603,10 +603,10 @@ is_valid_fast_cmdsubst(union node *n)
153 }
154 
155 /*
156- * Execute a command inside back quotes.  If it's a builtin command, we
157- * want to save its output in a block obtained from malloc.  Otherwise
158- * we fork off a subprocess and get the output of the command via a pipe.
159- * Should be called with interrupts off.
160+ * execute a command inside back quotes. if its a builtin command, we
161+ * want to save its output in a block obtained from malloc. otherwise
162+ * we fork off a subprocess and get the output of the command via a pipe
163+ * should be called with interrupts off
164  */
165 
166 void
167@@ -717,11 +717,11 @@ isdeclarationcmd(struct narg *arg)
168     if (arg == NULL)
169       return (0);
170     /*
171-     * To also allow "command -p" and "command --" as part of
172-     * a declaration command, add code here.
173-     * We do not do this, as ksh does not do it either and it
174-     * is not required by POSIX.
175-     */
176+ * to also allow "command -p" and "command --" as part of
177+ * a declaration command, add code here
178+ * we do not do this, as ksh does not do it either and it
179+ * is not required by POSIX
180+ */
181   }
182   return (
183       mustexpandto(arg->text, "export") || mustexpandto(arg->text, "readonly")
184@@ -763,16 +763,16 @@ xtracecommand(struct arglist *varlist, int argc, char **argv)
185 }
186 
187 /*
188- * Check if a builtin can safely be executed in the same process,
189- * even though it should be in a subshell (command substitution).
190- * Note that jobid, jobs, times and trap can show information not
191- * available in a child process; this is deliberate.
192- * The arguments should already have been expanded.
193+ * check if a builtin can safely be executed in the same process,
194+ * even though it should be in a subshell (command substitution)
195+ * note that jobid, jobs, times and trap can show information not
196+ * available in a child process; this is deliberate
197+ * the arguments should already have been expanded
198  */
199 static int
200 safe_builtin(int idx, int argc, char **argv)
201 {
202-  /* Generated from builtins.def. */
203+  /* generated from builtins.def */
204   if (safe_builtin_always(idx))
205     return (1);
206   if (idx == EXPORTCMD || idx == TRAPCMD || idx == ULIMITCMD || idx == UMASKCMD)
207@@ -787,13 +787,13 @@ safe_builtin(int idx, int argc, char **argv)
208 }
209 
210 /*
211- * Perform redirections, then execute a simple command with vfork.
212- * This cannot be used for command substitutions for two reasons:
213- * - Redirections might cause the error message for later redirections or for
214- *   an unknown command to be sent to the pipe (to be substituted), and this
215- *   might cause a deadlock if the message is too long.
216- * - The assignment of the pipe needs to come before instead of after the
217- *   redirections.
218+ * perform redirections, then execute a simple command with vfork
219+ * this cannot be used for command substitutions for two reasons:
220+ * - redirections might cause the error message for later redirections or for
221+ * an unknown command to be sent to the pipe (to be substituted), and this
222+ * might cause a deadlock if the message is too long
223+ * - the assignment of the pipe needs to come before instead of after the
224+ * redirections
225  */
226 static int
227 redirected_vforkexecshell(
228@@ -832,8 +832,8 @@ redirected_vforkexecshell(
229 }
230 
231 /*
232- * Execute a simple command.
233- * Note: This may or may not return if (flags & EV_EXIT).
234+ * execute a simple command
235+ * note: this may or may not return if (flags & EV_EXIT)
236  */
237 
238 static void
239@@ -863,7 +863,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
240   const char       *path = pathval();
241   int               i;
242 
243-  /* First expand the arguments. */
244+  /* first expand the arguments */
245   TRACE(("evalcommand(%p, %d) called\n", (void *)cmd, flags));
246   emptyarglist(&arglist);
247   emptyarglist(&varlist);
248@@ -872,7 +872,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
249   do_clearcmdentry = 0;
250   oexitstatus      = exitstatus;
251   exitstatus       = 0;
252-  /* Add one slot at the beginning for tryexec(). */
253+  /* add one slot at the beginning for tryexec() */
254   appendarglist(&arglist, nullstr);
255   for (argp = cmd->ncmd.args; argp; argp = argp->narg.next) {
256     if (varflag && isassignment(argp->narg.text)) {
257@@ -892,13 +892,13 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
258   if (iflag && funcnest == 0 && argc > 0)
259     lastarg = argv[argc - 1];
260 
261-  /* Print the command if xflag is set. */
262+  /* print the command if xflag is set */
263   if (xflag)
264     xtracecommand(&varlist, argc, argv);
265 
266-  /* Now locate the command. */
267+  /* now locate the command */
268   if (argc == 0) {
269-    /* Variable assignment(s) without command */
270+    /* variable assignment(s) without command */
271     cmdentry.cmdtype = CMDBUILTIN;
272     cmdentry.u.index = BLTINCMD;
273     cmdentry.special = 0;
274@@ -907,30 +907,30 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
275     int               cmd_flags = 0, bltinonly = 0;
276 
277     /*
278-     * Modify the command lookup path, if a PATH= assignment
279-     * is present
280-     */
281+ * modify the command lookup path, if a PATH= assignment
282+ * is present
283+ */
284     for (i = 0; i < varlist.count; i++)
285       if (strncmp(varlist.args[i], PATH, sizeof(PATH) - 1) == 0) {
286         path = varlist.args[i] + sizeof(PATH) - 1;
287         /*
288-         * On `PATH=... command`, we need to make
289-         * sure that the command isn't using the
290-         * non-updated hash table of the outer PATH
291-         * setting and we need to make sure that
292-         * the hash table isn't filled with items
293-         * from the temporary setting.
294-         *
295-         * It would be better to forbid using and
296-         * updating the table while this command
297-         * runs, by the command finding mechanism
298-         * is heavily integrated with hash handling,
299-         * so we just delete the hash before and after
300-         * the command runs. Partly deleting like
301-         * changepatch() does doesn't seem worth the
302-         * booking effort, since most such runs add
303-         * directories in front of the new PATH.
304-         */
305+ * on `PATH=... command`, we need to make
306+ * sure that the command isnt using the
307+ * non-updated hash table of the outer PATH
308+ * setting and we need to make sure that
309+ * the hash table isnt filled with items
310+ * from the temporary setting
311+ *
312+ * it would be better to forbid using and
313+ * updating the table while this command
314+ * runs, by the command finding mechanism
315+ * is heavily integrated with hash handling,
316+ * so we just delete the hash before and after
317+ * the command runs. partly deleting like
318+ * changepatch() does doesnt seem worth the
319+ * booking effort, since most such runs add
320+ * directories in front of the new PATH
321+ */
322         clearcmdentry();
323         do_clearcmdentry = 1;
324       }
325@@ -992,14 +992,14 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
326         break;
327     }
328     /*
329-     * Special builtins lose their special properties when
330-     * called via 'command'.
331-     */
332+ * special builtins lose their special properties when
333+ * called via 'command'
334+ */
335     if (cmd_flags & DO_NOFUNC)
336       cmdentry.special = 0;
337   }
338 
339-  /* Fork off a child process if necessary. */
340+  /* fork off a child process if necessary */
341   if (((cmdentry.cmdtype == CMDNORMAL || cmdentry.cmdtype == CMDUNKNOWN
342         || (cmdentry.cmdtype == CMDWEXEC && !(wexec_get_nofork() && wexec_is_nofork(argv[0]))))
343        && ((flags & EV_EXIT) == 0 || have_traps()))
344@@ -1042,8 +1042,8 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
345     flags |= EV_EXIT;
346   }
347 
348-  /* This is the child process if a fork occurred. */
349-  /* Execute the command. */
350+  /* this is the child process if a fork occurred */
351+  /* execute the command */
352   if (cmdentry.cmdtype == CMDFUNCTION) {
353 #ifdef DEBUG
354     trputs("Shell function:  ");
355@@ -1167,9 +1167,9 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
356     redirect(cmd->ncmd.redirect, mode);
357     outclearerror(out1);
358     /*
359-     * If there is no command word, redirection errors should
360-     * not be fatal but assignment errors should.
361-     */
362+ * if there is no command word, redirection errors should
363+ * not be fatal but assignment errors should
364+ */
365     if (argc == 0)
366       cmdentry.special = 1;
367     listsetvar(cmdenviron, cmdentry.special ? 0 : VNOSET);
368@@ -1224,7 +1224,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
369       setvareq(varlist.args[i], VEXPORT | VSTACK);
370     envp = environment();
371     shellexec(argv, envp, path, cmdentry.u.index);
372-    /*NOTREACHED*/
373+    /* NOTREACHED */
374   }
375   goto out;
376 
377@@ -1251,10 +1251,10 @@ out:
378 }
379 
380 /*
381- * Search for a command.  This is called before we fork so that the
382+ * search for a command. this is called before we fork so that the
383  * location of the command will be available in the parent as well as
384- * the child.  The check for "goodname" is an overly conservative
385- * check that the name will not be subject to expansion.
386+ * the child. the check for "goodname" is an overly conservative
387+ * check that the name will not be subject to expansion
388  */
389 
390 static void
391@@ -1268,13 +1268,13 @@ prehash(union node *n)
392 }
393 
394 /*
395- * Builtin commands.  Builtin commands whose functions are closely
396- * tied to evaluation are implemented here.
397+ * builtin commands. builtin commands whose functions are closely
398+ * tied to evaluation are implemented here
399  */
400 
401 /*
402- * No command given, a bltin command with no arguments, or a bltin command
403- * with an invalid name.
404+ * no command given, a bltin command with no arguments, or a bltin command
405+ * with an invalid name
406  */
407 
408 int
409@@ -1285,21 +1285,21 @@ bltincmd(int argc, char **argv)
410     return 127;
411   }
412   /*
413-   * Preserve exitstatus of a previous possible command substitution
414-   * as POSIX mandates
415-   */
416+ * preserve exitstatus of a previous possible command substitution
417+ * as POSIX mandates
418+ */
419   return exitstatus;
420 }
421 
422 /*
423- * Handle break and continue commands.  Break, continue, and return are
424- * all handled by setting the evalskip flag.  The evaluation routines
425+ * handle break and continue commands. break, continue, and return are
426+ * all handled by setting the evalskip flag. the evaluation routines
427  * above all check this flag, and if it is set they start skipping
428- * commands rather than executing them.  The variable skipcount is
429+ * commands rather than executing them. the variable skipcount is
430  * the number of loops to break/continue, or the number of function
431- * levels to return.  (The latter is always 1.)  It should probably
432- * be an error to break out of more loops than exist, but it isn't
433- * in the standard shell so we don't make it one here.
434+ * levels to return. (the latter is always 1.) it should probably
435+ * be an error to break out of more loops than exist, but it isnt
436+ * in the standard shell so we dont make it one here
437  */
438 
439 int
440@@ -1309,7 +1309,7 @@ breakcmd(int argc, char **argv)
441   char *end;
442 
443   if (argc > 1) {
444-    /* Allow arbitrarily large numbers. */
445+    /* allow arbitrarily large numbers */
446     n = strtol(argv[1], &end, 10);
447     if (!is_digit(argv[1][0]) || *end != '\0')
448       error("Illegal number: %s", argv[1]);
449@@ -1325,7 +1325,7 @@ breakcmd(int argc, char **argv)
450 }
451 
452 /*
453- * The `command' command.
454+ * the `command' command
455  */
456 int
457 commandcmd(int argc __unused, char **argv __unused)
458@@ -1359,14 +1359,14 @@ commandcmd(int argc __unused, char **argv __unused)
459     error("commandcmd bad call");
460 
461   /*
462-   * Do nothing successfully if no command was specified;
463-   * ksh also does this.
464-   */
465+ * do nothing successfully if no command was specified;
466+ * ksh also does this
467+ */
468   return 0;
469 }
470 
471 /*
472- * The return command.
473+ * the return command
474  */
475 
476 int
477@@ -1397,9 +1397,9 @@ execcmd(int argc, char **argv)
478   int i;
479 
480   /*
481-   * Because we have historically not supported any options,
482-   * only treat "--" specially.
483-   */
484+ * because we have historically not supported any options,
485+ * only treat "--" specially
486+ */
487   if (argc > 1 && strcmp(argv[1], "--") == 0)
488     argc--, argv++;
489   if (argc > 1) {
+19, -19
 1@@ -1,35 +1,35 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 extern char           *commandname; /* currently executing command */
55@@ -52,7 +52,7 @@ void reseteval(void);
56 #define EV_BACKCMD 04 /* command executing within back quotes */
57 
58 void evalstring(const char *, int);
59-union node; /* BLETCH for ansi C */
60+union node; /* BLETCH for ansi c */
61 void evaltree(union node *, int);
62 void evalbackcmd(union node *, struct backcmd *);
63 
+72, -72
  1@@ -1,35 +1,35 @@
  2-/*-
  3- * SPDX-License-Identifier: BSD-3-Clause
  4+/* -
  5+ * spdx-license-identifier: bsd-3-clause
  6  *
  7- * Copyright (c) 1991, 1993
  8- *	The Regents of the University of California.  All rights reserved.
  9+ * copyright (c) 1991, 1993
 10+ * the regents of the university of california. all rights reserved
 11  *
 12- * This code is derived from software contributed to Berkeley by
 13- * Kenneth Almquist.
 14+ * this code is derived from software contributed to berkeley by
 15+ * kenneth almquist
 16  *
 17- * Redistribution and use in source and binary forms, with or without
 18+ * redistribution and use in source and binary forms, with or without
 19  * modification, are permitted provided that the following conditions
 20  * are met:
 21- * 1. Redistributions of source code must retain the above copyright
 22- *    notice, this list of conditions and the following disclaimer.
 23- * 2. Redistributions in binary form must reproduce the above copyright
 24- *    notice, this list of conditions and the following disclaimer in the
 25- *    documentation and/or other materials provided with the distribution.
 26- * 3. Neither the name of the University nor the names of its contributors
 27- *    may be used to endorse or promote products derived from this software
 28- *    without specific prior written permission.
 29+ * 1. redistributions of source code must retain the above copyright
 30+ * notice, this list of conditions and the following disclaimer
 31+ * 2. redistributions in binary form must reproduce the above copyright
 32+ * notice, this list of conditions and the following disclaimer in the
 33+ * documentation and/or other materials provided with the distribution
 34+ * 3. neither the name of the university nor the names of its contributors
 35+ * may be used to endorse or promote products derived from this software
 36+ * without specific prior written permission
 37  *
 38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
 43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 50- * SUCH DAMAGE.
 51+ * SUCH DAMAGE
 52  */
 53 
 54 #include <errno.h>
 55@@ -41,12 +41,12 @@
 56 #include <unistd.h>
 57 
 58 /*
 59- * When commands are first encountered, they are entered in a hash table.
 60- * This ensures that a full path search will not have to be done for them
 61- * on each invocation.
 62+ * when commands are first encountered, they are entered in a hash table
 63+ * this ensures that a full path search will not have to be done for them
 64+ * on each invocation
 65  *
 66- * We should investigate converting to a linear search, even though that
 67- * would make the command name "hash" a misnomer.
 68+ * we should investigate converting to a linear search, even though that
 69+ * would make the command name "hash" a misnomer
 70  */
 71 
 72 #include "../../../shared/paths.h"
 73@@ -91,10 +91,10 @@ static void             delete_cmd_entry(void);
 74 static void             addcmdentry(const char *, struct cmdentry *);
 75 
 76 /*
 77- * Exec a program.  Never returns.  If you change this routine, you may
 78- * have to change the find_command routine as well.
 79+ * exec a program. never returns. if you change this routine, you may
 80+ * have to change the find_command routine as well
 81  *
 82- * The argv array may be changed and element argv[-1] should be writable.
 83+ * the argv array may be changed and element argv[-1] should be writable
 84  */
 85 
 86 void
 87@@ -156,7 +156,7 @@ shellexec(char **argv, char **envp, const char *path, int idx)
 88     }
 89   }
 90 
 91-  /* Map to POSIX errors */
 92+  /* map to POSIX errors */
 93   if (e == ENOENT || e == ENOTDIR)
 94     errorwithstatus(127, "%s: not found", argv[0]);
 95   else
 96@@ -173,16 +173,16 @@ isbinary(const char *data, size_t len)
 97   if (nul == NULL)
 98     return 0;
 99   /*
100-   * POSIX says we shall allow execution if the initial part intended
101-   * to be parsed by the shell consists of characters and does not
102-   * contain the NUL character. This allows concatenating a shell
103-   * script (ending with exec or exit) and a binary payload.
104-   *
105-   * In order to reject common binary files such as PNG images, check
106-   * that there is a lowercase letter or expansion before the last
107-   * newline before the NUL character, in addition to the check for
108-   * the newline character suggested by POSIX.
109-   */
110+ * POSIX says we shall allow execution if the initial part intended
111+ * to be parsed by the shell consists of characters and does not
112+ * contain the NUL character. this allows concatenating a shell
113+ * script (ending with exec or exit) and a binary payload
114+ *
115+ * in order to reject common binary files such as PNG images, check
116+ * that there is a lowercase letter or expansion before the last
117+ * newline before the NUL character, in addition to the check for
118+ * the newline character suggested by POSIX
119+ */
120   hasletter = 0;
121   for (p = data; *p != '\0'; p++) {
122     if ((*p >= 'a' && *p <= 'z') || *p == '$' || *p == '`')
123@@ -221,13 +221,13 @@ tryexec(char *cmd, char **argv, char **envp)
124 }
125 
126 /*
127- * Do a path search.  The variable path (passed by reference) should be
128+ * do a path search. the variable path (passed by reference) should be
129  * set to the start of the path before the first call; padvance will update
130- * this value as it proceeds.  Successive calls to padvance will return
131- * the possible path expansions in sequence.  If popt is not NULL, options
132+ * this value as it proceeds. successive calls to padvance will return
133+ * the possible path expansions in sequence. if popt is not NULL, options
134  * are processed: if an option (indicated by a percent sign) appears in
135  * the path entry then *popt will be set to point to it; else *popt will be
136- * set to NULL.  If popt is NULL, percent signs are not special.
137+ * set to NULL. if popt is NULL, percent signs are not special
138  */
139 
140 char *
141@@ -271,7 +271,7 @@ padvance(const char **path, const char **popt, const char *name)
142   return stalloc(len);
143 }
144 
145-/*** Command hashing code ***/
146+/* ** command hashing code ** */
147 
148 int
149 hashcmd(int argc __unused, char **argv __unused)
150@@ -363,8 +363,8 @@ printentry(struct tblentry *cmdp, int verbose)
151 }
152 
153 /*
154- * Resolve a command name.  If you change this routine, you may have to
155- * change the shellexec routine as well.
156+ * resolve a command name. if you change this routine, you may have to
157+ * change the shellexec routine as well
158  */
159 
160 void
161@@ -380,7 +380,7 @@ find_command(const char *name, struct cmdentry *entry, int act, const char *path
162   int              spec;
163   int              cd;
164 
165-  /* If name contains a slash, don't use the hash table */
166+  /* if name contains a slash, dont use the hash table */
167   if (strchr(name, '/') != NULL) {
168     entry->cmdtype = CMDNORMAL;
169     entry->u.index = 0;
170@@ -390,7 +390,7 @@ find_command(const char *name, struct cmdentry *entry, int act, const char *path
171 
172   cd = 0;
173 
174-  /* If name is in the table, we're done */
175+  /* if name is in the table, we're done */
176   if ((cmdp = cmdlookup(name, 0)) != NULL) {
177     if (cmdp->cmdtype == CMDFUNCTION && act & DO_NOFUNC)
178       cmdp = NULL;
179@@ -413,7 +413,7 @@ find_command(const char *name, struct cmdentry *entry, int act, const char *path
180 
181 #if FEATURE_NOEXEC || FEATURE_NOFORK
182   /* when builtin dispatch is active, registered wexec builtins are available
183-   * even if they are not present on the filesystem */
184+ * even if they are not present on the filesystem */
185   if ((wexec_get_noexec() || wexec_get_nofork()) && wexec_is_builtin(name)) {
186     INTOFF;
187     cmdp = cmdlookup(name, 1);
188@@ -427,7 +427,7 @@ find_command(const char *name, struct cmdentry *entry, int act, const char *path
189   }
190 #endif
191 
192-  /* We have to search path. */
193+  /* we have to search path */
194 
195   e   = ENOENT;
196   idx = -1;
197@@ -502,7 +502,7 @@ success:
198 }
199 
200 /*
201- * Search the table of builtin commands.
202+ * search the table of builtin commands
203  */
204 
205 int
206@@ -522,8 +522,8 @@ find_builtin(const char *name, int *special)
207 }
208 
209 /*
210- * Called when a cd is done.  If any entry in cmdtable depends on the current
211- * directory, simply clear cmdtable completely.
212+ * called when a cd is done. if any entry in cmdtable depends on the current
213+ * directory, simply clear cmdtable completely
214  */
215 
216 void
217@@ -534,9 +534,9 @@ hashcd(void)
218 }
219 
220 /*
221- * Called before PATH is changed.  The argument is the new value of PATH;
222- * pathval() still returns the old value at this point.  Called with
223- * interrupts off.
224+ * called before PATH is changed. the argument is the new value of PATH;
225+ * pathval() still returns the old value at this point. called with
226+ * interrupts off
227  */
228 
229 void
230@@ -546,7 +546,7 @@ changepath(const char *newval __unused)
231 }
232 
233 /*
234- * Clear out cached utility locations.
235+ * clear out cached utility locations
236  */
237 
238 void
239@@ -585,11 +585,11 @@ hashname(const char *p)
240 }
241 
242 /*
243- * Locate a command in the command hash table.  If "add" is nonzero,
244- * add the command to the table if it is not already present.  The
245+ * locate a command in the command hash table. if "add" is nonzero,
246+ * add the command to the table if it is not already present. the
247  * variable "lastcmdentry" is set to point to the address of the link
248  * pointing to the entry, so that delete_cmd_entry can delete the
249- * entry.
250+ * entry
251  */
252 
253 static struct tblentry **lastcmdentry;
254@@ -646,7 +646,7 @@ success:
255 }
256 
257 /*
258- * Delete the command entry returned on the last lookup.
259+ * delete the command entry returned on the last lookup
260  */
261 
262 static void
263@@ -662,8 +662,8 @@ delete_cmd_entry(void)
264 }
265 
266 /*
267- * Add a new command entry, replacing any existing command entry for
268- * the same name.
269+ * add a new command entry, replacing any existing command entry for
270+ * the same name
271  */
272 
273 static void
274@@ -683,7 +683,7 @@ addcmdentry(const char *name, struct cmdentry *entry)
275 }
276 
277 /*
278- * Define a shell function.
279+ * define a shell function
280  */
281 
282 void
283@@ -700,8 +700,8 @@ defun(const char *name, union node *func)
284 }
285 
286 /*
287- * Delete a function if it exists.
288- * Called with interrupts off.
289+ * delete a function if it exists
290+ * called with interrupts off
291  */
292 
293 int
294@@ -718,7 +718,7 @@ unsetfunc(const char *name)
295 }
296 
297 /*
298- * Check if a function by a certain name exists.
299+ * check if a function by a certain name exists
300  */
301 int
302 isfunc(const char *name)
303@@ -743,8 +743,8 @@ print_absolute_path(const char *name)
304 }
305 
306 /*
307- * Shared code for the following builtin commands:
308- *    type, command -v, command -V
309+ * shared code for the following builtin commands:
310+ * type, command -v, command -V
311  */
312 
313 int
314@@ -761,7 +761,7 @@ typecmd_impl(int argc, char **argv, int cmd, const char *path)
315     clearcmdentry();
316 
317   for (i = 1; i < argc; i++) {
318-    /* First look at the keywords */
319+    /* first look at the keywords */
320     for (pp = parsekwd; *pp; pp++)
321       if (**pp == *argv[i] && equal(*pp, argv[i]))
322         break;
323@@ -774,7 +774,7 @@ typecmd_impl(int argc, char **argv, int cmd, const char *path)
324       continue;
325     }
326 
327-    /* Then look at the aliases */
328+    /* then look at the aliases */
329     if ((ap = lookupalias(argv[i], 1)) != NULL) {
330       if (cmd == TYPECMD_SMALLV) {
331         out1fmt("alias %s=", argv[i]);
332@@ -785,13 +785,13 @@ typecmd_impl(int argc, char **argv, int cmd, const char *path)
333       continue;
334     }
335 
336-    /* Then check if it is a tracked alias */
337+    /* then check if it is a tracked alias */
338     if ((cmdp = cmdlookup(argv[i], 0)) != NULL) {
339       entry.cmdtype = cmdp->cmdtype;
340       entry.u       = cmdp->param;
341       entry.special = cmdp->special;
342     } else {
343-      /* Finally use brute force */
344+      /* finally use brute force */
345       find_command(argv[i], &entry, 0, path);
346     }
347 
348@@ -875,7 +875,7 @@ typecmd_impl(int argc, char **argv, int cmd, const char *path)
349 }
350 
351 /*
352- * Locate and print what a word is...
353+ * locate and print what a word is...
354  */
355 
356 int
+19, -19
 1@@ -1,35 +1,35 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 #include "sh_cdefs.h"
55@@ -61,7 +61,7 @@ struct cmdentry {
56 
57 /* action to find_command() */
58 #define DO_ERR    0x01 /* prints errors */
59-#define DO_NOFUNC 0x02 /* don't return shell functions, for command */
60+#define DO_NOFUNC 0x02 /* dont return shell functions, for command */
61 
62 void        shellexec(char **, char **, const char *, int) __dead2;
63 char       *padvance(const char **, const char **, const char *);
+90, -90
  1@@ -1,39 +1,39 @@
  2-/*-
  3- * SPDX-License-Identifier: BSD-3-Clause
  4+/* -
  5+ * spdx-license-identifier: bsd-3-clause
  6  *
  7- * Copyright (c) 1991, 1993
  8- *	The Regents of the University of California.  All rights reserved.
  9- * Copyright (c) 1997-2005
 10- *	Herbert Xu <herbert@gondor.apana.org.au>.  All rights reserved.
 11- * Copyright (c) 2010-2015
 12- *	Jilles Tjoelker <jilles@stack.nl>.  All rights reserved.
 13+ * copyright (c) 1991, 1993
 14+ * the regents of the university of california. all rights reserved
 15+ * copyright (c) 1997-2005
 16+ * herbert xu <herbert@gondor.apana.org.au>. all rights reserved
 17+ * copyright (c) 2010-2015
 18+ * jilles tjoelker <jilles@stack.nl>. all rights reserved
 19  *
 20- * This code is derived from software contributed to Berkeley by
 21- * Kenneth Almquist.
 22+ * this code is derived from software contributed to berkeley by
 23+ * kenneth almquist
 24  *
 25- * Redistribution and use in source and binary forms, with or without
 26+ * redistribution and use in source and binary forms, with or without
 27  * modification, are permitted provided that the following conditions
 28  * are met:
 29- * 1. Redistributions of source code must retain the above copyright
 30- *    notice, this list of conditions and the following disclaimer.
 31- * 2. Redistributions in binary form must reproduce the above copyright
 32- *    notice, this list of conditions and the following disclaimer in the
 33- *    documentation and/or other materials provided with the distribution.
 34- * 3. Neither the name of the University nor the names of its contributors
 35- *    may be used to endorse or promote products derived from this software
 36- *    without specific prior written permission.
 37+ * 1. redistributions of source code must retain the above copyright
 38+ * notice, this list of conditions and the following disclaimer
 39+ * 2. redistributions in binary form must reproduce the above copyright
 40+ * notice, this list of conditions and the following disclaimer in the
 41+ * documentation and/or other materials provided with the distribution
 42+ * 3. neither the name of the university nor the names of its contributors
 43+ * may be used to endorse or promote products derived from this software
 44+ * without specific prior written permission
 45  *
 46  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 47  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 48- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 49- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 50+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
 51+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 52  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 57  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 58- * SUCH DAMAGE.
 59+ * SUCH DAMAGE
 60  */
 61 
 62 #include <dirent.h>
 63@@ -52,8 +52,8 @@
 64 #include <wctype.h>
 65 
 66 /*
 67- * Routines to expand arguments to commands.  We have to deal with
 68- * backquotes, shell variables, and file metacharacters.
 69+ * routines to expand arguments to commands. we have to deal with
 70+ * backquotes, shell variables, and file metacharacters
 71  */
 72 
 73 #include "arith.h"
 74@@ -172,7 +172,7 @@ nextword(char c, int flag, char *p, struct worddest *dst)
 75     dst->state = is_ws ? WORD_WS_DELIMITED : WORD_IDLE;
 76   } else if (!is_ws && dst->state == WORD_WS_DELIMITED)
 77     dst->state = WORD_IDLE;
 78-  /* Reserve space while the stack string is empty. */
 79+  /* reserve space while the stack string is empty */
 80   appendarglist(dst->list, NULL);
 81   dst->list->count--;
 82   STARTSTACKSTR(p);
 83@@ -203,16 +203,16 @@ stputs_split(const char *data, const char *syntax, int flag, char *p, struct wor
 84 #define STPUTS_SPLIT(data, syntax, flag, p, dst) p = stputs_split((data), syntax, flag, p, dst)
 85 
 86 /*
 87- * Perform expansions on an argument, placing the resulting list of arguments
 88- * in arglist.  Parameter expansion, command substitution and arithmetic
 89+ * perform expansions on an argument, placing the resulting list of arguments
 90+ * in arglist. parameter expansion, command substitution and arithmetic
 91  * expansion are always performed; additional expansions can be requested
 92- * via flag (EXP_*).
 93- * The result is left in the stack string.
 94- * When arglist is NULL, perform here document expansion.
 95+ * via flag (EXP_*)
 96+ * the result is left in the stack string
 97+ * when arglist is NULL, perform here document expansion
 98  *
 99- * When doing something that may cause this to be re-entered, make sure
100+ * when doing something that may cause this to be re-entered, make sure
101  * the stack string is empty via grabstackstr() and do not assume expdest
102- * remains valid.
103+ * remains valid
104  */
105 void
106 expandarg(union node *arg, struct arglist *arglist, int flag)
107@@ -245,14 +245,14 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
108 }
109 
110 /*
111- * Perform parameter expansion, command substitution and arithmetic
112- * expansion, and tilde expansion if requested via EXP_TILDE/EXP_VARTILDE.
113- * Processing ends at a CTLENDVAR or CTLENDARI character as well as '\0'.
114- * This is used to expand word in ${var+word} etc.
115- * If EXP_GLOB or EXP_CASE are set, keep and/or generate CTLESC
116- * characters to allow for further processing.
117+ * perform parameter expansion, command substitution and arithmetic
118+ * expansion, and tilde expansion if requested via EXP_TILDE/EXP_VARTILDE
119+ * processing ends at a CTLENDVAR or CTLENDARI character as well as '\0'
120+ * this is used to expand word in ${var+word} etc
121+ * if EXP_GLOB or EXP_CASE are set, keep and/or generate CTLESC
122+ * characters to allow for further processing
123  *
124- * If EXP_SPLIT is set, dst receives any complete words produced.
125+ * if EXP_SPLIT is set, dst receives any complete words produced
126  */
127 static const char *
128 argstr(const char *p, struct nodelist **restrict argbackq, int flag, struct worddest *dst)
129@@ -311,9 +311,9 @@ argstr(const char *p, struct nodelist **restrict argbackq, int flag, struct word
130       case ':':
131       case '=':
132         /*
133-         * sort of a hack - expand tildes in variable
134-         * assignments (after the first '=' and after ':'s).
135-         */
136+ * sort of a hack - expand tildes in variable
137+ * assignments (after the first '=' and after ':'s)
138+ */
139         if (split_lit && !lit_quoted && strchr(ifsset() ? ifsval() : " \t\n", c) != NULL) {
140           NEXTWORD(c, flag, expdest, dst);
141           break;
142@@ -336,8 +336,8 @@ argstr(const char *p, struct nodelist **restrict argbackq, int flag, struct word
143 }
144 
145 /*
146- * Perform tilde expansion, placing the result in the stack string and
147- * returning the next position in the input string to process.
148+ * perform tilde expansion, placing the result in the stack string and
149+ * returning the next position in the input string to process
150  */
151 static const char *
152 exptilde(const char *p, int flag)
153@@ -352,7 +352,7 @@ exptilde(const char *p, int flag)
154   for (;;) {
155     c = *p;
156     switch (c) {
157-      case CTLESC: /* This means CTL* are always considered quoted. */
158+      case CTLESC: /* this means CTL* are always considered quoted */
159       case CTLVAR:
160       case CTLBACKQ:
161       case CTLBACKQ | CTLQUOTE:
162@@ -388,7 +388,7 @@ exptilde(const char *p, int flag)
163 }
164 
165 /*
166- * Expand arithmetic expression.
167+ * expand arithmetic expression
168  */
169 static const char *
170 expari(const char *p, struct nodelist **restrict argbackq, int flag, struct worddest *dst)
171@@ -418,16 +418,16 @@ expari(const char *p, struct nodelist **restrict argbackq, int flag, struct word
172   adj = strlen(expdest);
173   STADJUST(adj, expdest);
174   /*
175-   * If this is quoted, a '-' must not indicate a range in [...].
176-   * If this is not quoted, splitting may occur.
177-   */
178+ * if this is quoted, a '-' must not indicate a range in [...]
179+ * if this is not quoted, splitting may occur
180+ */
181   if (quoted ? result < 0 && begoff > 1 && flag & (EXP_GLOB | EXP_CASE) : flag & EXP_SPLIT)
182     reprocess(expdest - adj - stackblock(), flag, VSNORMAL, quoted, dst);
183   return p;
184 }
185 
186 /*
187- * Perform command substitution.
188+ * perform command substitution
189  */
190 static void
191 expbackq(union node *cmd, int quoted, int flag, struct worddest *dst)
192@@ -456,7 +456,7 @@ expbackq(union node *cmd, int quoted, int flag, struct worddest *dst)
193     ifs = ifsset() ? ifsval() : " \t\n";
194   else
195     ifs = "";
196-  /* Remove trailing newlines */
197+  /* remove trailing newlines */
198   for (;;) {
199     if (--in.nleft < 0) {
200       if (in.fd < 0)
201@@ -629,8 +629,8 @@ subevalvar_misc(
202 }
203 
204 /*
205- * Expand a variable, and return a pointer to the next character in the
206- * input string.
207+ * expand a variable, and return a pointer to the next character in the
208+ * input string
209  */
210 
211 static const char *
212@@ -748,9 +748,9 @@ evalvar(const char *p, struct nodelist **restrict argbackq, int flag, struct wor
213       if (!set)
214         break;
215       /*
216-       * Terminate the string and start recording the pattern
217-       * right after it
218-       */
219+ * terminate the string and start recording the pattern
220+ * right after it
221+ */
222       STPUTC('\0', expdest);
223       patloc = expdest - stackblock();
224       p      = subevalvar_trim(p, argbackq, patloc, subtype, startloc);
225@@ -798,7 +798,7 @@ evalvar(const char *p, struct nodelist **restrict argbackq, int flag, struct wor
226 }
227 
228 /*
229- * Test whether a special or positional parameter is set.
230+ * test whether a special or positional parameter is set
231  */
232 
233 static int
234@@ -891,7 +891,7 @@ reprocess(int startloc, int flag, int subtype, int quoted, struct worddest *dst)
235 }
236 
237 /*
238- * Add the value of a special or positional parameter to the stack string.
239+ * add the value of a special or positional parameter to the stack string
240  */
241 
242 static void
243@@ -989,9 +989,9 @@ static char expdir[PATH_MAX];
244 #define expdir_end (expdir + sizeof(expdir))
245 
246 /*
247- * Perform pathname generation and remove control characters.
248- * At this point, the only control characters should be CTLESC.
249- * The results are stored in the list dstlist.
250+ * perform pathname generation and remove control characters
251+ * at this point, the only control characters should be CTLESC
252+ * the results are stored in the list dstlist
253  */
254 static void
255 expandmeta(char *pattern, struct arglist *dstlist)
256@@ -1013,8 +1013,8 @@ expandmeta(char *pattern, struct arglist *dstlist)
257   }
258   if (dstlist->count == firstmatch) {
259     /*
260-     * no matches
261-     */
262+ * no matches
263+ */
264     rmescapes(pattern);
265     appendarglist(dstlist, pattern);
266   } else {
267@@ -1028,7 +1028,7 @@ expandmeta(char *pattern, struct arglist *dstlist)
268 }
269 
270 /*
271- * Do metacharacter (i.e. *, ?, [...]) expansion.
272+ * do metacharacter (i.e. *, ?, [...]) expansion
273  */
274 
275 static void
276@@ -1182,11 +1182,11 @@ get_wc(const char **p)
277 }
278 
279 /*
280- * See if a character matches a character class, starting at the first colon
281- * of "[:class:]".
282- * If a valid character class is recognized, a pointer to the next character
283+ * see if a character matches a character class, starting at the first colon
284+ * of "[:class:]"
285+ * if a valid character class is recognized, a pointer to the next character
286  * after the final closing bracket is stored into *end, otherwise a null
287- * pointer is stored into *end.
288+ * pointer is stored into *end
289  */
290 static int
291 match_charclass(const char *p, wchar_t chr, const char **end)
292@@ -1204,14 +1204,14 @@ match_charclass(const char *p, wchar_t chr, const char **end)
293   name[nameend - p] = '\0';
294   *end              = nameend + 2;
295   cclass            = wctype(name);
296-  /* An unknown class matches nothing but is valid nevertheless. */
297+  /* an unknown class matches nothing but is valid nevertheless */
298   if (cclass == 0)
299     return 0;
300   return iswctype(chr, cclass);
301 }
302 
303 /*
304- * Returns true if the pattern matches the string.
305+ * returns true if the pattern matches the string
306  */
307 
308 static int
309@@ -1242,9 +1242,9 @@ patmatch(const char *pattern, const char *string)
310         if (localeisutf8) {
311           wc = get_wc(&q);
312           /*
313-           * A '?' does not match invalid UTF-8 but a
314-           * '*' does, so backtrack.
315-           */
316+ * a '?' does not match invalid UTF-8 but a
317+ * '*' does, so backtrack
318+ */
319           if (wc == 0)
320             goto backtrack;
321         } else
322@@ -1255,17 +1255,17 @@ patmatch(const char *pattern, const char *string)
323         while (c == '*')
324           c = *++p;
325         /*
326-         * If the pattern ends here, we know the string
327-         * matches without needing to look at the rest of it.
328-         */
329+ * if the pattern ends here, we know the string
330+ * matches without needing to look at the rest of it
331+ */
332         if (c == '\0')
333           return 1;
334         /*
335-         * First try the shortest match for the '*' that
336-         * could work. We can forget any earlier '*' since
337-         * there is no way having it match more characters
338-         * can help us, given that we are already here.
339-         */
340+ * first try the shortest match for the '*' that
341+ * could work. we can forget any earlier '*' since
342+ * there is no way having it match more characters
343+ * can help us, given that we are already here
344+ */
345         bt_p = p;
346         bt_q = q;
347         break;
348@@ -1341,10 +1341,10 @@ patmatch(const char *pattern, const char *string)
349           break;
350       backtrack:
351         /*
352-         * If we have a mismatch (other than hitting the end
353-         * of the string), go back to the last '*' seen and
354-         * have it match one additional character.
355-         */
356+ * if we have a mismatch (other than hitting the end
357+ * of the string), go back to the last '*' seen and
358+ * have it match one additional character
359+ */
360         if (bt_p == NULL)
361           return 0;
362         if (*bt_q == '\0')
363@@ -1358,7 +1358,7 @@ patmatch(const char *pattern, const char *string)
364 }
365 
366 /*
367- * Remove any CTLESC and CTLQUOTEMARK characters from a string.
368+ * remove any CTLESC and CTLQUOTEMARK characters from a string
369  */
370 
371 void
372@@ -1385,7 +1385,7 @@ rmescapes(char *str)
373 }
374 
375 /*
376- * See if a pattern matches in a case statement.
377+ * see if a pattern matches in a case statement
378  */
379 
380 int
381@@ -1408,7 +1408,7 @@ casematch(union node *pattern, const char *val)
382 }
383 
384 /*
385- * Our own itoa().
386+ * our own itoa()
387  */
388 
389 static void
390@@ -1431,7 +1431,7 @@ cvtnum(int num, char *buf)
391 }
392 
393 /*
394- * Do most of the work for wordexp(3).
395+ * do most of the work for wordexp(3)
396  */
397 
398 int
399@@ -1450,7 +1450,7 @@ wordexpcmd(int argc, char **argv)
400 }
401 
402 /*
403- * Do most of the work for wordexp(3), new version.
404+ * do most of the work for wordexp(3), new version
405  */
406 
407 int
+18, -18
 1@@ -1,35 +1,35 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 struct arglist {
+60, -60
  1@@ -1,35 +1,35 @@
  2-/*-
  3- * SPDX-License-Identifier: BSD-3-Clause
  4+/* -
  5+ * spdx-license-identifier: bsd-3-clause
  6  *
  7- * Copyright (c) 1991, 1993
  8- *	The Regents of the University of California.  All rights reserved.
  9+ * copyright (c) 1991, 1993
 10+ * the regents of the university of california. all rights reserved
 11  *
 12- * This code is derived from software contributed to Berkeley by
 13- * Kenneth Almquist.
 14+ * this code is derived from software contributed to berkeley by
 15+ * kenneth almquist
 16  *
 17- * Redistribution and use in source and binary forms, with or without
 18+ * redistribution and use in source and binary forms, with or without
 19  * modification, are permitted provided that the following conditions
 20  * are met:
 21- * 1. Redistributions of source code must retain the above copyright
 22- *    notice, this list of conditions and the following disclaimer.
 23- * 2. Redistributions in binary form must reproduce the above copyright
 24- *    notice, this list of conditions and the following disclaimer in the
 25- *    documentation and/or other materials provided with the distribution.
 26- * 3. Neither the name of the University nor the names of its contributors
 27- *    may be used to endorse or promote products derived from this software
 28- *    without specific prior written permission.
 29+ * 1. redistributions of source code must retain the above copyright
 30+ * notice, this list of conditions and the following disclaimer
 31+ * 2. redistributions in binary form must reproduce the above copyright
 32+ * notice, this list of conditions and the following disclaimer in the
 33+ * documentation and/or other materials provided with the distribution
 34+ * 3. neither the name of the university nor the names of its contributors
 35+ * may be used to endorse or promote products derived from this software
 36+ * without specific prior written permission
 37  *
 38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
 43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 50- * SUCH DAMAGE.
 51+ * SUCH DAMAGE
 52  */
 53 
 54 #include <errno.h>
 55@@ -40,7 +40,7 @@
 56 #include <unistd.h>
 57 
 58 /*
 59- * This file implements the input routines used by the parser.
 60+ * this file implements the input routines used by the parser
 61  */
 62 
 63 #include "alias.h"
 64@@ -69,8 +69,8 @@ struct strpush {
 65 };
 66 
 67 /*
 68- * The parsefile structure pointed to by the global variable parsefile
 69- * contains information about the current file being read.
 70+ * the parsefile structure pointed to by the global variable parsefile
 71+ * contains information about the current file being read
 72  */
 73 
 74 struct parsefile {
 75@@ -112,8 +112,8 @@ resetinput(void)
 76 }
 77 
 78 /*
 79- * Read a character from the script, returning PEOF on end of file.
 80- * Nul characters in the input are silently discarded.
 81+ * read a character from the script, returning PEOF on end of file
 82+ * nul characters in the input are silently discarded
 83  */
 84 
 85 int
 86@@ -189,13 +189,13 @@ retry:
 87 }
 88 
 89 /*
 90- * Refill the input buffer and return the next input character:
 91+ * refill the input buffer and return the next input character:
 92  *
 93- * 1) If a string was pushed back on the input, pop it;
 94- * 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading
 95- *    from a string so we can't refill the buffer, return EOF.
 96- * 3) If there is more in this buffer, use it else call read to fill it.
 97- * 4) Process input up to the next newline, deleting nul characters.
 98+ * 1) if a string was pushed back on the input, pop it;
 99+ * 2) if an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading
100+ * from a string so we cant refill the buffer, return EOF
101+ * 3) if there is more in this buffer, use it else call read to fill it
102+ * 4) process input up to the next newline, deleting nul characters
103  */
104 
105 int
106@@ -207,10 +207,10 @@ preadbuffer(void)
107 
108   while (parsefile->strpush) {
109     /*
110-     * Add a space to the end of an alias to ensure that the
111-     * alias remains in use while parsing its last word.
112-     * This avoids alias recursions.
113-     */
114+ * add a space to the end of an alias to ensure that the
115+ * alias remains in use while parsing its last word
116+ * this avoids alias recursions
117+ */
118     if (parsenleft == -1 && parsefile->strpush->ap != NULL)
119       return ' ';
120     popstring();
121@@ -275,8 +275,8 @@ again:
122 }
123 
124 /*
125- * Returns if we are certain we are at EOF. Does not cause any more input
126- * to be read from the outside world.
127+ * returns if we are certain we are at EOF. does not cause any more input
128+ * to be read from the outside world
129  */
130 
131 int
132@@ -292,8 +292,8 @@ preadateof(void)
133 }
134 
135 /*
136- * Undo the last call to pgetc.  Only one character may be pushed back.
137- * PEOF may be pushed back.
138+ * undo the last call to pgetc. only one character may be pushed back
139+ * PEOF may be pushed back
140  */
141 
142 void
143@@ -304,8 +304,8 @@ pungetc(void)
144 }
145 
146 /*
147- * Push a string back onto the input at this current parsefile level.
148- * We handle aliases this way.
149+ * push a string back onto the input at this current parsefile level
150+ * we handle aliases this way
151  */
152 void
153 pushstring(const char *s, int len, struct alias *ap)
154@@ -313,7 +313,7 @@ pushstring(const char *s, int len, struct alias *ap)
155   struct strpush *sp;
156 
157   INTOFF;
158-  /*out2fmt_flush("*** calling pushstring: %s, %d\n", s, len);*/
159+  /* out2fmt_flush("*** calling pushstring: %s, %d\n", s, len); */
160   if (parsefile->strpush) {
161     sp                 = ckmalloc(sizeof(struct strpush));
162     sp->prev           = parsefile->strpush;
163@@ -345,8 +345,8 @@ popstring(void)
164   parsenextc = sp->prevstring;
165   parsenleft = sp->prevnleft;
166   parselleft = sp->prevlleft;
167-  /*out2fmt_flush("*** calling popstring: restoring to '%s'\n",
168-   * parsenextc);*/
169+  /* out2fmt_flush("*** calling popstring: restoring to '%s'\n",
170+ * parsenextc); */
171   parsefile->strpush = sp->prev;
172   if (sp != &(parsefile->basestrpush))
173     ckfree(sp);
174@@ -354,12 +354,12 @@ popstring(void)
175 }
176 
177 /*
178- * Set the input to take input from a file.  If push is set, push the
179- * old input onto the stack first.
180- * About verify:
181- *   -1: Obey verifyflag
182- *    0: Do not verify
183- *    1: Do verify
184+ * set the input to take input from a file. if push is set, push the
185+ * old input onto the stack first
186+ * about verify:
187+ * -1: obey verifyflag
188+ * 0: do not verify
189+ * 1: do verify
190  */
191 
192 void
193@@ -392,8 +392,8 @@ setinputfile(const char *fname, int push, int verify)
194 }
195 
196 /*
197- * Like setinputfile, but takes an open file descriptor (which should have
198- * its FD_CLOEXEC flag already set).  Call this with interrupts off.
199+ * like setinputfile, but takes an open file descriptor (which should have
200+ * its FD_CLOEXEC flag already set). call this with interrupts off
201  */
202 
203 void
204@@ -413,7 +413,7 @@ setinputfd(int fd, int push)
205 }
206 
207 /*
208- * Like setinputfile, but takes input from a string.
209+ * like setinputfile, but takes input from a string
210  */
211 
212 void
213@@ -428,8 +428,8 @@ setinputstring(const char *string)
214 }
215 
216 /*
217- * To handle the "." command, a stack of input files is used.  Pushfile
218- * adds a new entry to the stack and popfile restores the previous level.
219+ * to handle the "." command, a stack of input files is used. pushfile
220+ * adds a new entry to the stack and popfile restores the previous level
221  */
222 
223 static void
224@@ -468,7 +468,7 @@ popfile(void)
225 }
226 
227 /*
228- * Return current file (to go back to it later using popfilesupto()).
229+ * return current file (to go back to it later using popfilesupto())
230  */
231 
232 struct parsefile *
233@@ -478,9 +478,9 @@ getcurrentfile(void)
234 }
235 
236 /*
237- * Pop files until the given file is on top again. Useful for regular
238- * builtins that read shell commands from files or strings.
239- * If the given file is not an active file, an error is raised.
240+ * pop files until the given file is on top again. useful for regular
241+ * builtins that read shell commands from files or strings
242+ * if the given file is not an active file, an error is raised
243  */
244 
245 void
246@@ -493,7 +493,7 @@ popfilesupto(struct parsefile *file)
247 }
248 
249 /*
250- * Return to top level.
251+ * return to top level
252  */
253 
254 void
255@@ -504,8 +504,8 @@ popallfiles(void)
256 }
257 
258 /*
259- * Close the file(s) that the shell is reading commands from.  Called
260- * after a fork is done.
261+ * close the file(s) that the shell is reading commands from. called
262+ * after a fork is done
263  */
264 
265 void
+21, -21
 1@@ -1,43 +1,43 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 /* PEOF (the end of file marker) is defined in syntax.h */
55 
56 /*
57- * The input line number.  Input.c just defines this variable, and saves
58- * and restores it when files are pushed and popped.  The user of this
59- * package must set its value.
60+ * the input line number. input.c just defines this variable, and saves
61+ * and restores it when files are pushed and popped. the user of this
62+ * package must set its value
63  */
64 extern int         plinno;
65 extern int         parsenleft; /* number of characters left in input buffer */
+74, -74
  1@@ -1,35 +1,35 @@
  2-/*-
  3- * SPDX-License-Identifier: BSD-3-Clause
  4+/* -
  5+ * spdx-license-identifier: bsd-3-clause
  6  *
  7- * Copyright (c) 1991, 1993
  8- *	The Regents of the University of California.  All rights reserved.
  9+ * copyright (c) 1991, 1993
 10+ * the regents of the university of california. all rights reserved
 11  *
 12- * This code is derived from software contributed to Berkeley by
 13- * Kenneth Almquist.
 14+ * this code is derived from software contributed to berkeley by
 15+ * kenneth almquist
 16  *
 17- * Redistribution and use in source and binary forms, with or without
 18+ * redistribution and use in source and binary forms, with or without
 19  * modification, are permitted provided that the following conditions
 20  * are met:
 21- * 1. Redistributions of source code must retain the above copyright
 22- *    notice, this list of conditions and the following disclaimer.
 23- * 2. Redistributions in binary form must reproduce the above copyright
 24- *    notice, this list of conditions and the following disclaimer in the
 25- *    documentation and/or other materials provided with the distribution.
 26- * 3. Neither the name of the University nor the names of its contributors
 27- *    may be used to endorse or promote products derived from this software
 28- *    without specific prior written permission.
 29+ * 1. redistributions of source code must retain the above copyright
 30+ * notice, this list of conditions and the following disclaimer
 31+ * 2. redistributions in binary form must reproduce the above copyright
 32+ * notice, this list of conditions and the following disclaimer in the
 33+ * documentation and/or other materials provided with the distribution
 34+ * 3. neither the name of the university nor the names of its contributors
 35+ * may be used to endorse or promote products derived from this software
 36+ * without specific prior written permission
 37  *
 38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
 43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 50- * SUCH DAMAGE.
 51+ * SUCH DAMAGE
 52  */
 53 
 54 #include <errno.h>
 55@@ -70,10 +70,10 @@
 56 #include "var.h"
 57 
 58 /*
 59- * A job structure contains information about a job.  A job is either a
 60- * single process or a set of processes contained in a pipeline.  In the
 61- * latter case, pidlist will be non-NULL, and will point to a -1 terminated
 62- * array of pids.
 63+ * a job structure contains information about a job. a job is either a
 64+ * single process or a set of processes contained in a pipeline. in the
 65+ * latter case, pidlist will be non-null, and will point to a -1 terminated
 66+ * array of pids
 67  */
 68 
 69 struct procstat {
 70@@ -140,7 +140,7 @@ static void printjobcmd(struct job *);
 71 static void showjob(struct job *, int);
 72 
 73 /*
 74- * Turn job control on and off.
 75+ * turn job control on and off
 76  */
 77 
 78 static int jobctl;
 79@@ -185,9 +185,9 @@ setjobctl(int on)
 80     }
 81     if (ttyfd < 10) {
 82       /*
 83-       * Keep our TTY file descriptor out of the way of
 84-       * the user's redirections.
 85-       */
 86+ * keep our TTY file descriptor out of the way of
 87+ * the user's redirections
 88+ */
 89       if ((i = fcntl(ttyfd, F_DUPFD_CLOEXEC, 10)) < 0) {
 90         jobctl_notty();
 91         return;
 92@@ -452,12 +452,12 @@ showjob(struct job *jp, int mode)
 93 }
 94 
 95 /*
 96- * Print a list of jobs.  If "change" is nonzero, only print jobs whose
 97- * statuses have changed since the last call to showjobs.
 98+ * print a list of jobs. if "change" is nonzero, only print jobs whose
 99+ * statuses have changed since the last call to showjobs
100  *
101- * If the shell is interrupted in the process of creating a job, the
102- * result may be a job structure containing zero processes.  Such structures
103- * will be freed here.
104+ * if the shell is interrupted in the process of creating a job, the
105+ * result may be a job structure containing zero processes. such structures
106+ * will be freed here
107  */
108 
109 void
110@@ -480,9 +480,9 @@ showjobs(int change, int mode)
111     showjob(jp, mode);
112     if (mode == SHOWJOBS_DEFAULT || mode == SHOWJOBS_VERBOSE) {
113       jp->changed = 0;
114-      /* Hack: discard jobs for which $! has not been
115-       * referenced in interactive mode when they terminate.
116-       */
117+      /* hack: discard jobs for which $! has not been
118+ * referenced in interactive mode when they terminate
119+ */
120       if (jp->state == JOBDONE && !jp->remembered && (iflag || jp != bgjob)) {
121         freejob(jp);
122       }
123@@ -491,7 +491,7 @@ showjobs(int change, int mode)
124 }
125 
126 /*
127- * Mark a job structure as unused.
128+ * mark a job structure as unused
129  */
130 
131 static void
132@@ -545,9 +545,9 @@ waitcmdloop(struct job *job)
133   struct job *jp;
134 
135   /*
136-   * Loop until a process is terminated or stopped, or a SIGINT is
137-   * received.
138-   */
139+ * loop until a process is terminated or stopped, or a SIGINT is
140+ * received
141+ */
142 
143   do {
144     if (job != NULL) {
145@@ -611,7 +611,7 @@ jobidcmd(int argc __unused, char **argv __unused)
146 }
147 
148 /*
149- * Convert a job name to a job structure.
150+ * convert a job name to a job structure
151  */
152 
153 static struct job *
154@@ -713,7 +713,7 @@ killjob(const char *name, int sig)
155 }
156 
157 /*
158- * Return a new job structure,
159+ * return a new job structure,
160  */
161 
162 struct job *
163@@ -734,7 +734,7 @@ makejob(union node *node __unused, int nprocs)
164         jp = ckmalloc((njobs + 4) * sizeof jobtab[0]);
165         memcpy(jp, jobtab, njobs * sizeof jp[0]);
166 #if JOBS
167-        /* Relocate `next' pointers and list head */
168+        /* relocate `next' pointers and list head */
169         if (jobmru != NULL)
170           jobmru = &jp[jobmru - jobtab];
171         for (i = 0; i < njobs; i++)
172@@ -743,7 +743,7 @@ makejob(union node *node __unused, int nprocs)
173 #endif
174         if (bgjob != NULL)
175           bgjob = &jp[bgjob - jobtab];
176-        /* Relocate `ps' pointers */
177+        /* relocate `ps' pointers */
178         for (i = 0; i < njobs; i++)
179           if (jp[i].ps == &jobtab[i].ps0)
180             jp[i].ps = &jp[i].ps0;
181@@ -819,19 +819,19 @@ deljob(struct job *j)
182 }
183 
184 /*
185- * Return the most recently used job that isn't `nj', and preferably one
186- * that is stopped.
187+ * return the most recently used job that isnt `nj', and preferably one
188+ * that is stopped
189  */
190 static struct job *
191 getcurjob(struct job *nj)
192 {
193   struct job *jp;
194 
195-  /* Try to find a stopped one.. */
196+  /* try to find a stopped one.. */
197   for (jp = jobmru; jp != NULL; jp = jp->next)
198     if (jp->used && jp != nj && jp->state == JOBSTOPPED)
199       return (jp);
200-  /* Otherwise the most recently used job that isn't `nj' */
201+  /* otherwise the most recently used job that isnt `nj' */
202   for (jp = jobmru; jp != NULL; jp = jp->next)
203     if (jp->used && jp != nj)
204       return (jp);
205@@ -842,18 +842,18 @@ getcurjob(struct job *nj)
206 #endif
207 
208 /*
209- * Fork of a subshell.  If we are doing job control, give the subshell its
210- * own process group.  Jp is a job structure that the job is to be added to.
211- * N is the command that will be evaluated by the child.  Both jp and n may
212- * be NULL.  The mode parameter can be one of the following:
213- *	FORK_FG - Fork off a foreground process.
214- *	FORK_BG - Fork off a background process.
215- *	FORK_NOJOB - Like FORK_FG, but don't give the process its own
216- *		     process group even if job control is on.
217+ * fork of a subshell. if we are doing job control, give the subshell its
218+ * own process group. jp is a job structure that the job is to be added to
219+ * n is the command that will be evaluated by the child. both jp and n may
220+ * be NULL. the mode parameter can be one of the following:
221+ * FORK_FG - fork off a foreground process
222+ * FORK_BG - fork off a background process
223+ * FORK_NOJOB - like FORK_FG, but dont give the process its own
224+ * process group even if job control is on
225  *
226- * When job control is turned off, background processes have their standard
227+ * when job control is turned off, background processes have their standard
228  * input redirected to /dev/null (except for the second and later processes
229- * in a pipeline).
230+ * in a pipeline)
231  */
232 
233 pid_t
234@@ -895,11 +895,11 @@ forkshell(struct job *jp, union node *n, int mode)
235         pgrp = jp->ps[0].pid;
236       if (setpgid(0, pgrp) == 0 && mode == FORK_FG && ttyfd >= 0) {
237         /*
238-         * Each process in a pipeline must have the tty
239-         * pgrp set before running its code.
240-         * Only for pipelines of three or more processes
241-         * could this be reduced to two calls.
242-         */
243+ * each process in a pipeline must have the tty
244+ * pgrp set before running its code
245+ * only for pipelines of three or more processes
246+ * could this be reduced to two calls
247+ */
248         if (tcsetpgrp(ttyfd, pgrp) < 0)
249           error("tcsetpgrp failed, errno=%d", errno);
250       }
251@@ -1017,22 +1017,22 @@ vforkexecshell(struct job *jp, char **argv, char **envp, const char *path, int i
252 }
253 
254 /*
255- * Wait for job to finish.
256+ * wait for job to finish
257  *
258- * Under job control we have the problem that while a child process is
259+ * under job control we have the problem that while a child process is
260  * running interrupts generated by the user are sent to the child but not
261- * to the shell.  This means that an infinite loop started by an inter-
262- * active user may be hard to kill.  With job control turned off, an
263- * interactive user may place an interactive program inside a loop.  If
264- * the interactive program catches interrupts, the user doesn't want
265- * these interrupts to also abort the loop.  The approach we take here
266+ * to the shell. this means that an infinite loop started by an inter-
267+ * active user may be hard to kill. with job control turned off, an
268+ * interactive user may place an interactive program inside a loop. if
269+ * the interactive program catches interrupts, the user doesnt want
270+ * these interrupts to also abort the loop. the approach we take here
271  * is to have the shell ignore interrupt signals while waiting for a
272  * foreground process to terminate, and then send itself an interrupt
273- * signal if the child process was terminated by an interrupt signal.
274- * Unfortunately, some programs want to do a bit of cleanup and then
275+ * signal if the child process was terminated by an interrupt signal
276+ * unfortunately, some programs want to do a bit of cleanup and then
277  * exit on interrupt; unless these processes terminate themselves by
278  * sending a signal to themselves (instead of calling exit) they will
279- * confuse this approach.
280+ * confuse this approach
281  */
282 
283 int
284@@ -1093,7 +1093,7 @@ dummy_handler(int sig __unused)
285 }
286 
287 /*
288- * Wait for a process to terminate.
289+ * wait for a process to terminate
290  */
291 
292 static pid_t
293@@ -1291,8 +1291,8 @@ backgndpidval(void)
294 }
295 
296 /*
297- * Return a string identifying a command (to be printed by the
298- * jobs command.
299+ * return a string identifying a command (to be printed by the
300+ * jobs command
301  */
302 
303 static char *cmdnextc;
+19, -19
 1@@ -1,38 +1,38 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *      The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54-/* Mode argument to forkshell.  Don't change FORK_FG or FORK_BG. */
55+/* mode argument to forkshell. dont change FORK_FG or FORK_BG */
56 #define FORK_FG    0
57 #define FORK_BG    1
58 #define FORK_NOJOB 2
+19, -19
 1@@ -1,36 +1,36 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1988, 1993, 1994
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1988, 1993, 1994
10+ * the regents of the university of california. all rights reserved
11  *
12- * Redistribution and use in source and binary forms, with or without
13+ * redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16- * 1. Redistributions of source code must retain the above copyright
17- *    notice, this list of conditions and the following disclaimer.
18- * 2. Redistributions in binary form must reproduce the above copyright
19- *    notice, this list of conditions and the following disclaimer in the
20- *    documentation and/or other materials provided with the distribution.
21- * 3. Neither the name of the University nor the names of its contributors
22- *    may be used to endorse or promote products derived from this software
23- *    without specific prior written permission.
24+ * 1. redistributions of source code must retain the above copyright
25+ * notice, this list of conditions and the following disclaimer
26+ * 2. redistributions in binary form must reproduce the above copyright
27+ * notice, this list of conditions and the following disclaimer in the
28+ * documentation and/or other materials provided with the distribution
29+ * 3. neither the name of the university nor the names of its contributors
30+ * may be used to endorse or promote products derived from this software
31+ * without specific prior written permission
32  *
33  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
34  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
37+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
38+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
39  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45- * SUCH DAMAGE.
46+ * SUCH DAMAGE
47  */
48 /*
49- * Important: This file is used both as a standalone program /bin/kill and
50- * as a builtin for /bin/sh (#define SHELL).
51+ * important: this file is used both as a standalone program /bin/kill and
52+ * as a builtin for /bin/sh (#define SHELL)
53  */
54 
55 #include "sig.h"
56@@ -128,7 +128,7 @@ main(int argc, char *argv[])
57 #endif
58     {
59       pidl = strtol(*argv, &ep, 10);
60-      /* Check for overflow of pid_t. */
61+      /* check for overflow of pid_t */
62       pid = (pid_t)pidl;
63       if (!**argv || *ep || pid != pidl)
64         errx(2, "illegal process id: %s", *argv);
+21, -21
 1@@ -1,35 +1,35 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 #if !FEATURE_SH_HISTEDIT
55@@ -262,7 +262,7 @@ find_completions_recurse(
56       snprintf(next_user, sizeof(next_user), "%s", user_prefix);
57       if (S_ISDIR(st.st_mode)) {
58         /* if it is a directory and doesnt end with
59-         * slash, add slash */
60+ * slash, add slash */
61         len = strlen(next_user);
62         if (len > 0 && next_user[len - 1] != '/') {
63           strlcat(next_user, "/", sizeof(next_user));
64@@ -384,7 +384,7 @@ complete_files(const char *word, int is_cmd, struct redlineCompletions *lc)
65       path_to_split = (unescaped_word[1] == '\0') ? "" : (char *)(unescaped_word + 2);
66     } else {
67       /* ~username is not supported for abbreviation, fallback
68-       * to home */
69+ * to home */
70       fs_dir        = home ? home : "/";
71       user_prefix   = "~/";
72       path_to_split = (char *)(unescaped_word + 1);
73@@ -420,7 +420,7 @@ complete_files(const char *word, int is_cmd, struct redlineCompletions *lc)
74     }
75   } else {
76     /* empty path_to_split (e.g. exactly ~ or exactly / or empty
77-     * word) */
78+ * word) */
79     comps[comp_count++] = p;
80   }
81 
+22, -22
 1@@ -1,39 +1,39 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 /*
55- * Routines to check for mail.  (Perhaps make part of main.c?)
56+ * routines to check for mail. (perhaps make part of main.c?)
57  */
58 
59 #include "mail.h"
60@@ -52,9 +52,9 @@ static int    nmboxes;             /* number of mailboxes */
61 static time_t mailtime[MAXMBOXES]; /* times of mailboxes */
62 
63 /*
64- * Print appropriate message(s) if mail has arrived.  If the argument is
65+ * print appropriate message(s) if mail has arrived. if the argument is
66  * non-zero, then the value of MAIL has changed, so we just update the
67- * values.
68+ * values
69  */
70 
71 void
72@@ -86,7 +86,7 @@ chkmail(int silent)
73     msg = strchr(p, '%');
74     if (msg != NULL)
75       *msg++ = '\0';
76-#ifdef notdef /* this is what the System V shell claims to do (it lies) */
77+#ifdef notdef /* this is what the system v shell claims to do (it lies) */
78     if (stat(p, &statb) < 0)
79       statb.st_mtime = 0;
80     if (statb.st_mtime > mailtime[i] && !silent) {
+18, -18
 1@@ -1,35 +1,35 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 void chkmail(int);
+45, -45
  1@@ -1,35 +1,35 @@
  2-/*-
  3- * SPDX-License-Identifier: BSD-3-Clause
  4+/* -
  5+ * spdx-license-identifier: bsd-3-clause
  6  *
  7- * Copyright (c) 1991, 1993
  8- *	The Regents of the University of California.  All rights reserved.
  9+ * copyright (c) 1991, 1993
 10+ * the regents of the university of california. all rights reserved
 11  *
 12- * This code is derived from software contributed to Berkeley by
 13- * Kenneth Almquist.
 14+ * this code is derived from software contributed to berkeley by
 15+ * kenneth almquist
 16  *
 17- * Redistribution and use in source and binary forms, with or without
 18+ * redistribution and use in source and binary forms, with or without
 19  * modification, are permitted provided that the following conditions
 20  * are met:
 21- * 1. Redistributions of source code must retain the above copyright
 22- *    notice, this list of conditions and the following disclaimer.
 23- * 2. Redistributions in binary form must reproduce the above copyright
 24- *    notice, this list of conditions and the following disclaimer in the
 25- *    documentation and/or other materials provided with the distribution.
 26- * 3. Neither the name of the University nor the names of its contributors
 27- *    may be used to endorse or promote products derived from this software
 28- *    without specific prior written permission.
 29+ * 1. redistributions of source code must retain the above copyright
 30+ * notice, this list of conditions and the following disclaimer
 31+ * 2. redistributions in binary form must reproduce the above copyright
 32+ * notice, this list of conditions and the following disclaimer in the
 33+ * documentation and/or other materials provided with the distribution
 34+ * 3. neither the name of the university nor the names of its contributors
 35+ * may be used to endorse or promote products derived from this software
 36+ * without specific prior written permission
 37  *
 38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
 43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 50- * SUCH DAMAGE.
 51+ * SUCH DAMAGE
 52  */
 53 
 54 #include <errno.h>
 55@@ -79,22 +79,22 @@ static void  read_profile(const char *);
 56 static char *find_dot_file(char *);
 57 
 58 /*
 59- * Main routine.  We initialize things, parse the arguments, execute
 60+ * main routine. we initialize things, parse the arguments, execute
 61  * profiles if we're a login shell, and then call cmdloop to execute
 62- * commands.  The setjmp call sets up the location to jump to when an
 63- * exception occurs.  When an exception occurs the variable "state"
 64- * is used to figure out how far we had gotten.
 65+ * commands. the setjmp call sets up the location to jump to when an
 66+ * exception occurs. when an exception occurs the variable "state"
 67+ * is used to figure out how far we had gotten
 68  */
 69 
 70 int
 71 main(int argc, char *argv[])
 72 {
 73   /*
 74-   * As smark is accessed after a longjmp, it cannot be a local in main().
 75-   * The C standard specifies that the values of non-volatile local
 76-   * variables are unspecified after a jump if modified between the
 77-   * setjmp and longjmp.
 78-   */
 79+ * as smark is accessed after a longjmp, it cannot be a local in main()
 80+ * the c standard specifies that the values of non-volatile local
 81+ * variables are unspecified after a jump if modified between the
 82+ * setjmp and longjmp
 83+ */
 84   static struct stackmark smark, smark2;
 85   volatile int            state;
 86   char                   *shinit;
 87@@ -130,10 +130,10 @@ main(int argc, char *argv[])
 88   rootpid = getpid();
 89   if (rootpid == 1) {
 90     /*
 91-     * Make sh usable for invocation as interactive init
 92-     * substitute with init_path=/bin/sh, by opening
 93-     * file descriptors 0, 1, and 2 on /dev/console.
 94-     */
 95+ * make sh usable for invocation as interactive init
 96+ * substitute with init_path=/bin/sh, by opening
 97+ * file descriptors 0, 1, and 2 on /dev/console
 98+ */
 99     if (fcntl(STDIN_FILENO, F_GETFL, NULL) == -1 && errno == EBADF) {
100       (void)open(ARUU_PATH_DEVCONSOLE, O_RDWR);
101       (void)setsid();
102@@ -188,7 +188,7 @@ state4:
103     cmdloop(1);
104   }
105   exitshell(exitstatus);
106-  /*NOTREACHED*/
107+  /* NOTREACHED */
108   return 0;
109 }
110 
111@@ -200,8 +200,8 @@ reset(void)
112 }
113 
114 /*
115- * Read and execute commands.  "Top" is nonzero for the top level command
116- * loop; it turns on prompting if the shell is interactive.
117+ * read and execute commands. "top" is nonzero for the top level command
118+ * loop; it turns on prompting if the shell is interactive
119  */
120 
121 static void
122@@ -256,7 +256,7 @@ cmdloop(int top)
123 }
124 
125 /*
126- * Read /etc/profile or .profile.  Return on error.
127+ * read /etc/profile or .profile. return on error
128  */
129 
130 static void
131@@ -283,7 +283,7 @@ read_profile(const char *name)
132 }
133 
134 /*
135- * Read a file containing shell functions.
136+ * read a file containing shell functions
137  */
138 
139 void
140@@ -295,8 +295,8 @@ readcmdfile(const char *name, int verify)
141 }
142 
143 /*
144- * Take commands from a file.  To be compatible we should do a path
145- * search for the file, which is necessary to find sub-commands.
146+ * take commands from a file. to be compatible we should do a path
147+ * search for the file, which is necessary to find sub-commands
148  */
149 
150 static char *
151@@ -307,16 +307,16 @@ find_dot_file(char *basename)
152   const char *path = pathval();
153   struct stat statb;
154 
155-  /* don't try this for absolute or relative paths */
156+  /* dont try this for absolute or relative paths */
157   if (strchr(basename, '/'))
158     return basename;
159 
160   while ((fullname = padvance(&path, &opt, basename)) != NULL) {
161     if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
162       /*
163-       * Don't bother freeing here, since it will
164-       * be freed by the caller.
165-       */
166+ * dont bother freeing here, since it will
167+ * be freed by the caller
168+ */
169       return fullname;
170     }
171     stunalloc(fullname);
172@@ -335,9 +335,9 @@ dotcmd(int argc, char **argv)
173   exitstatus = 0;
174 
175   /*
176-   * Because we have historically not supported any options,
177-   * only treat "--" specially.
178-   */
179+ * because we have historically not supported any options,
180+ * only treat "--" specially
181+ */
182   filename = argc > 2 && strcmp(argv[1], "--") == 0 ? argv[2] : argv[1];
183 
184   fullname = find_dot_file(filename);
+19, -19
 1@@ -1,39 +1,39 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 extern int           rootpid;      /* pid of main shell */
55-extern int           rootshell;    /* true if we aren't a child of the main shell */
56+extern int           rootshell;    /* true if we arent a child of the main shell */
57 extern struct jmploc main_handler; /* top level exception handler */
58 
59 void readcmdfile(const char *, int);
+46, -46
  1@@ -1,35 +1,35 @@
  2-/*-
  3- * SPDX-License-Identifier: BSD-3-Clause
  4+/* -
  5+ * spdx-license-identifier: bsd-3-clause
  6  *
  7- * Copyright (c) 1991, 1993
  8- *	The Regents of the University of California.  All rights reserved.
  9+ * copyright (c) 1991, 1993
 10+ * the regents of the university of california. all rights reserved
 11  *
 12- * This code is derived from software contributed to Berkeley by
 13- * Kenneth Almquist.
 14+ * this code is derived from software contributed to berkeley by
 15+ * kenneth almquist
 16  *
 17- * Redistribution and use in source and binary forms, with or without
 18+ * redistribution and use in source and binary forms, with or without
 19  * modification, are permitted provided that the following conditions
 20  * are met:
 21- * 1. Redistributions of source code must retain the above copyright
 22- *    notice, this list of conditions and the following disclaimer.
 23- * 2. Redistributions in binary form must reproduce the above copyright
 24- *    notice, this list of conditions and the following disclaimer in the
 25- *    documentation and/or other materials provided with the distribution.
 26- * 3. Neither the name of the University nor the names of its contributors
 27- *    may be used to endorse or promote products derived from this software
 28- *    without specific prior written permission.
 29+ * 1. redistributions of source code must retain the above copyright
 30+ * notice, this list of conditions and the following disclaimer
 31+ * 2. redistributions in binary form must reproduce the above copyright
 32+ * notice, this list of conditions and the following disclaimer in the
 33+ * documentation and/or other materials provided with the distribution
 34+ * 3. neither the name of the university nor the names of its contributors
 35+ * may be used to endorse or promote products derived from this software
 36+ * without specific prior written permission
 37  *
 38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
 43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 50- * SUCH DAMAGE.
 51+ * SUCH DAMAGE
 52  */
 53 
 54 #include "memalloc.h"
 55@@ -50,7 +50,7 @@ badalloc(const char *message)
 56 }
 57 
 58 /*
 59- * Like malloc, but returns an error when out of space.
 60+ * like malloc, but returns an error when out of space
 61  */
 62 
 63 pointer
 64@@ -67,7 +67,7 @@ ckmalloc(size_t nbytes)
 65 }
 66 
 67 /*
 68- * Same for realloc.
 69+ * same for realloc
 70  */
 71 
 72 pointer
 73@@ -90,7 +90,7 @@ ckfree(pointer p)
 74 }
 75 
 76 /*
 77- * Make a copy of a string in safe storage.
 78+ * make a copy of a string in safe storage
 79  */
 80 
 81 char *
 82@@ -106,19 +106,19 @@ savestr(const char *s)
 83 }
 84 
 85 /*
 86- * Parse trees for commands are allocated in lifo order, so we use a stack
 87+ * parse trees for commands are allocated in lifo order, so we use a stack
 88  * to make this more efficient, and also to avoid all sorts of exception
 89- * handling code to handle interrupts in the middle of a parse.
 90+ * handling code to handle interrupts in the middle of a parse
 91  *
 92- * The size 496 was chosen because with 16-byte alignment the total size
 93- * for the allocated block is 512.
 94+ * the size 496 was chosen because with 16-byte alignment the total size
 95+ * for the allocated block is 512
 96  */
 97 
 98-#define MINSIZE 496 /* minimum size of a block. */
 99+#define MINSIZE 496 /* minimum size of a block */
100 
101 struct stack_block {
102   struct stack_block *prev;
103-  /* Data follows */
104+  /* data follows */
105 };
106 #define SPACE(sp) ((char *)(sp) + ALIGN(sizeof(struct stack_block)))
107 
108@@ -165,7 +165,7 @@ stalloc(int nbytes)
109 void
110 stunalloc(pointer p)
111 {
112-  if (p == NULL) { /*DEBUG */
113+  if (p == NULL) { /* DEBUG */
114     write(STDERR_FILENO, "stunalloc\n", 10);
115     abort();
116   }
117@@ -191,7 +191,7 @@ setstackmark(struct stackmark *mark)
118   mark->stackp     = stackp;
119   mark->stacknxt   = stacknxt;
120   mark->stacknleft = stacknleft;
121-  /* Ensure this block stays in place. */
122+  /* ensure this block stays in place */
123   if (stackp != NULL && stacknxt == SPACE(stackp))
124     stalloc(1);
125 }
126@@ -217,13 +217,13 @@ popstackmark(struct stackmark *mark)
127 }
128 
129 /*
130- * When the parser reads in a string, it wants to stick the string on the
131+ * when the parser reads in a string, it wants to stick the string on the
132  * stack and only adjust the stack pointer when it knows how big the
133- * string is.  Stackblock (defined in stack.h) returns a pointer to a block
134+ * string is. stackblock (defined in stack.h) returns a pointer to a block
135  * of space on top of the stack and stackblocklen returns the length of
136- * this block.  Growstackblock will grow this space by at least one byte,
137- * possibly moving it (like realloc).  Grabstackblock actually allocates the
138- * part of the block that has been used.
139+ * this block. growstackblock will grow this space by at least one byte,
140+ * possibly moving it (like realloc). grabstackblock actually allocates the
141+ * part of the block that has been used
142  */
143 
144 static void
145@@ -269,21 +269,21 @@ growstackblock(int min)
146 }
147 
148 /*
149- * The following routines are somewhat easier to use than the above.
150- * The user declares a variable of type STACKSTR, which may be declared
151- * to be a register.  The macro STARTSTACKSTR initializes things.  Then
152- * the user uses the macro STPUTC to add characters to the string.  In
153- * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is
154- * grown as necessary.  When the user is done, she can just leave the
155- * string there and refer to it using stackblock().  Or she can allocate
156- * the space for it using grabstackstr().  If it is necessary to allow
157+ * the following routines are somewhat easier to use than the above
158+ * the user declares a variable of type STACKSTR, which may be declared
159+ * to be a register. the macro STARTSTACKSTR initializes things. then
160+ * the user uses the macro STPUTC to add characters to the string. in
161+ * effect, stputc(c, p) is the same as *p++ = c except that the stack is
162+ * grown as necessary. when the user is done, she can just leave the
163+ * string there and refer to it using stackblock(). or she can allocate
164+ * the space for it using grabstackstr(). if it is necessary to allow
165  * someone else to use the stack temporarily and then continue to grow
166  * the string, the user should use grabstack to allocate the space, and
167- * then call ungrabstr(p) to return to the previous mode of operation.
168+ * then call ungrabstr(p) to return to the previous mode of operation
169  *
170- * USTPUTC is like STPUTC except that it doesn't check for overflow.
171+ * USTPUTC is like STPUTC except that it doesnt check for overflow
172  * CHECKSTACKSPACE can be called before USTPUTC to ensure that there
173- * is space for at least one character.
174+ * is space for at least one character
175  */
176 
177 static char *
178@@ -303,7 +303,7 @@ growstackstr(void)
179 }
180 
181 /*
182- * Called from CHECKSTRSPACE.
183+ * called from CHECKSTRSPACE
184  */
185 
186 char *
+23, -23
 1@@ -1,35 +1,35 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *      The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 #include "sh_cdefs.h"
55@@ -77,11 +77,11 @@ char   *stputs(const char *data, char *p);
56   }
57 #define USTPUTC(c, p) (*p++ = (c))
58 /*
59- * STACKSTRNUL's use is where we want to be able to turn a stack
60- * (non-sentinel, character counting string) into a C string,
61- * and later pretend the NUL is not there.
62- * Note: Because of STACKSTRNUL's semantics, STACKSTRNUL cannot be used
63- * on a stack that will grabstackstr()ed.
64+ * stackstrnul's use is where we want to be able to turn a stack
65+ * (non-sentinel, character counting string) into a c string,
66+ * and later pretend the NUL is not there
67+ * note: because of stackstrnul's semantics, STACKSTRNUL cannot be used
68+ * on a stack that will grabstackstr()ed
69  */
70 #define STACKSTRNUL(p)       (p == sstrend ? (p = growstackstr(), *p = '\0') : (*p = '\0'))
71 #define STUNPUTC(p)          (--p)
+60, -60
  1@@ -1,39 +1,39 @@
  2-/*-
  3- * SPDX-License-Identifier: BSD-3-Clause
  4+/* -
  5+ * spdx-license-identifier: bsd-3-clause
  6  *
  7- * Copyright (c) 1991, 1993
  8- *	The Regents of the University of California.  All rights reserved.
  9+ * copyright (c) 1991, 1993
 10+ * the regents of the university of california. all rights reserved
 11  *
 12- * This code is derived from software contributed to Berkeley by
 13- * Kenneth Almquist.
 14+ * this code is derived from software contributed to berkeley by
 15+ * kenneth almquist
 16  *
 17- * Redistribution and use in source and binary forms, with or without
 18+ * redistribution and use in source and binary forms, with or without
 19  * modification, are permitted provided that the following conditions
 20  * are met:
 21- * 1. Redistributions of source code must retain the above copyright
 22- *    notice, this list of conditions and the following disclaimer.
 23- * 2. Redistributions in binary form must reproduce the above copyright
 24- *    notice, this list of conditions and the following disclaimer in the
 25- *    documentation and/or other materials provided with the distribution.
 26- * 3. Neither the name of the University nor the names of its contributors
 27- *    may be used to endorse or promote products derived from this software
 28- *    without specific prior written permission.
 29+ * 1. redistributions of source code must retain the above copyright
 30+ * notice, this list of conditions and the following disclaimer
 31+ * 2. redistributions in binary form must reproduce the above copyright
 32+ * notice, this list of conditions and the following disclaimer in the
 33+ * documentation and/or other materials provided with the distribution
 34+ * 3. neither the name of the university nor the names of its contributors
 35+ * may be used to endorse or promote products derived from this software
 36+ * without specific prior written permission
 37  *
 38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
 43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 50- * SUCH DAMAGE.
 51+ * SUCH DAMAGE
 52  */
 53 
 54 /*
 55- * Miscellaneous builtins.
 56+ * miscellaneous builtins
 57  */
 58 
 59 #include <sys/resource.h>
 60@@ -92,12 +92,12 @@ fdctx_init(int fd, struct fdctx *fdc)
 61 {
 62   off_t cur;
 63 
 64-  /* Check if fd is seekable. */
 65+  /* check if fd is seekable */
 66   cur  = lseek(fd, 0, SEEK_CUR);
 67   *fdc = (struct fdctx){
 68       .fd     = fd,
 69       .buflen = (cur != -1) ? READ_BUFLEN : 1,
 70-      .ep     = &fdc->buf[0], /* No data */
 71+      .ep     = &fdc->buf[0], /* no data */
 72   };
 73 }
 74 
 75@@ -126,18 +126,18 @@ fdctx_destroy(struct fdctx *fdc)
 76 
 77   if (fdc->buflen > 1) {
 78     /*
 79-     * Reposition the file offset.  Here is the layout of buf:
 80-     *
 81-     *     | off
 82-     *     v
 83-     * |*****************|-------|
 84-     * buf               ep   buf+buflen
 85-     *     |<- residue ->|
 86-     *
 87-     * off: current character
 88-     * ep:  offset just after read(2)
 89-     * residue: length for reposition
 90-     */
 91+ * reposition the file offset. here is the layout of buf:
 92+ *
 93+ * | off
 94+ * v
 95+ * |*****************|-------|
 96+ * buf ep buf+buflen
 97+ * |<- residue ->|
 98+ *
 99+ * off: current character
100+ * ep: offset just after read(2)
101+ * residue: length for reposition
102+ */
103     residue = (fdc->ep - fdc->buf) - fdc->off;
104     if (residue > 0)
105       (void)lseek(fdc->fd, -residue, SEEK_CUR);
106@@ -145,18 +145,18 @@ fdctx_destroy(struct fdctx *fdc)
107 }
108 
109 /*
110- * The read builtin.  The -r option causes backslashes to be treated like
111- * ordinary characters.
112+ * the read builtin. the -r option causes backslashes to be treated like
113+ * ordinary characters
114  *
115- * Note that if IFS=' :' then read x y should work so that:
116- * 'a b'	x='a', y='b'
117- * ' a b '	x='a', y='b'
118- * ':b'		x='',  y='b'
119- * ':'		x='',  y=''
120- * '::'		x='',  y=''
121- * ': :'	x='',  y=''
122- * ':::'	x='',  y='::'
123- * ':b c:'	x='',  y='b c:'
124+ * note that if IFS=' :' then read x y should work so that:
125+ * 'a b' x='a', y='b'
126+ * ' a b ' x='a', y='b'
127+ * ':b' x='', y='b'
128+ * ':' x='', y=''
129+ * '::' x='', y=''
130+ * ': :' x='', y=''
131+ * ':::' x='', y='::'
132+ * ':b c:' x='', y='b c:'
133  */
134 
135 int
136@@ -263,8 +263,8 @@ readcmd(int argc __unused, char **argv __unused)
137 
138   if (timeout >= 0) {
139     /*
140-     * Wait for something to become available.
141-     */
142+ * wait for something to become available
143+ */
144     pfd.fd     = STDIN_FILENO;
145     pfd.events = POLLIN;
146     status = sig = 0;
147@@ -289,8 +289,8 @@ readcmd(int argc __unused, char **argv __unused)
148     }
149     sigprocmask(SIG_SETMASK, &oset, NULL);
150     /*
151-     * If there's nothing ready, return an error.
152-     */
153+ * if there's nothing ready, return an error
154+ */
155     if (status <= 0) {
156       while (*ap != NULL)
157         setvar(*ap++, "", 0);
158@@ -363,13 +363,13 @@ readcmd(int argc __unused, char **argv __unused)
159 
160     if (startword != 0) {
161       if (is_ifs == 1) {
162-        /* Ignore leading IFS whitespace */
163+        /* ignore leading IFS whitespace */
164         if (saveall)
165           USTPUTC(c, p);
166         continue;
167       }
168       if (is_ifs == 2 && startword == 1) {
169-        /* Only one non-whitespace IFS per word */
170+        /* only one non-whitespace IFS per word */
171         startword = 2;
172         if (saveall) {
173           lastnonifsws = p - stackblock();
174@@ -383,7 +383,7 @@ readcmd(int argc __unused, char **argv __unused)
175       /* append this character to the current variable */
176       startword = 0;
177       if (saveall)
178-        /* Not just a spare terminator */
179+        /* not just a spare terminator */
180         saveall++;
181       lastnonifs = lastnonifsws = p - stackblock();
182       USTPUTC(c, p);
183@@ -394,7 +394,7 @@ readcmd(int argc __unused, char **argv __unused)
184     startword = is_ifs;
185 
186     if (ap[1] == NULL) {
187-      /* Last variable needs all IFS chars */
188+      /* last variable needs all IFS chars */
189       saveall++;
190       if (is_ifs == 2)
191         lastnonifsws = p - stackblock();
192@@ -412,15 +412,15 @@ readcmd(int argc __unused, char **argv __unused)
193   STACKSTRNUL(p);
194 
195   /*
196-   * Remove trailing IFS chars: always remove whitespace, don't remove
197-   * non-whitespace unless it was naked
198-   */
199+ * remove trailing IFS chars: always remove whitespace, dont remove
200+ * non-whitespace unless it was naked
201+ */
202   if (saveall <= 1)
203     lastnonifsws = lastnonifs;
204   stackblock()[lastnonifsws + 1] = '\0';
205   setvar(*ap, stackblock(), 0);
206 
207-  /* Set any remaining args to "" */
208+  /* set any remaining args to "" */
209   while (*++ap != NULL)
210     setvar(*ap, "", 0);
211 #if FEATURE_SH_HISTEDIT
212@@ -504,11 +504,11 @@ umaskcmd(int argc __unused, char **argv __unused)
213 /*
214  * ulimit builtin
215  *
216- * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and
217- * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with
218- * ash by J.T. Conklin.
219+ * this code, originally by doug gwyn, doug kingston, eric gisin, and
220+ * michael rendell was ripped from pdksh 5.0.8 and hacked for use with
221+ * ash by J.T. conklin
222  *
223- * Public domain.
224+ * public domain
225  */
226 
227 struct limits {
+23, -23
 1@@ -1,40 +1,40 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 /*
55- * This program reads the nodetypes file and nodes.c.pat file.  It generates
56- * the files nodes.h and nodes.c.
57+ * this program reads the nodetypes file and nodes.c.pat file. it generates
58+ * the files nodes.h and nodes.c
59  */
60 
61 #include <errno.h>
62@@ -60,7 +60,7 @@
63 #define T_STRING   3
64 #define T_INT      4 /* int field */
65 #define T_OTHER    5 /* other */
66-#define T_TEMP     6 /* don't copy this field */
67+#define T_TEMP     6 /* dont copy this field */
68 
69 struct field { /* a structure field */
70   char *name;  /* name of field */
71@@ -193,8 +193,8 @@ parsefield(void)
72 }
73 
74 static const char writer[] = "\
75-/*\n\
76- * This file was generated by the mknodes program.\n\
77+/* \n\
78+ * this file was generated by the mknodes program.\n\
79  */\n\
80 \n";
81 
+36, -36
  1@@ -1,39 +1,39 @@
  2-/*-
  3- * SPDX-License-Identifier: BSD-3-Clause
  4+/* -
  5+ * spdx-license-identifier: bsd-3-clause
  6  *
  7- * Copyright (c) 1991, 1993
  8- *	The Regents of the University of California.  All rights reserved.
  9+ * copyright (c) 1991, 1993
 10+ * the regents of the university of california. all rights reserved
 11  *
 12- * This code is derived from software contributed to Berkeley by
 13- * Kenneth Almquist.
 14+ * this code is derived from software contributed to berkeley by
 15+ * kenneth almquist
 16  *
 17- * Redistribution and use in source and binary forms, with or without
 18+ * redistribution and use in source and binary forms, with or without
 19  * modification, are permitted provided that the following conditions
 20  * are met:
 21- * 1. Redistributions of source code must retain the above copyright
 22- *    notice, this list of conditions and the following disclaimer.
 23- * 2. Redistributions in binary form must reproduce the above copyright
 24- *    notice, this list of conditions and the following disclaimer in the
 25- *    documentation and/or other materials provided with the distribution.
 26- * 3. Neither the name of the University nor the names of its contributors
 27- *    may be used to endorse or promote products derived from this software
 28- *    without specific prior written permission.
 29+ * 1. redistributions of source code must retain the above copyright
 30+ * notice, this list of conditions and the following disclaimer
 31+ * 2. redistributions in binary form must reproduce the above copyright
 32+ * notice, this list of conditions and the following disclaimer in the
 33+ * documentation and/or other materials provided with the distribution
 34+ * 3. neither the name of the university nor the names of its contributors
 35+ * may be used to endorse or promote products derived from this software
 36+ * without specific prior written permission
 37  *
 38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
 43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 50- * SUCH DAMAGE.
 51+ * SUCH DAMAGE
 52  */
 53 
 54 /*
 55- * This program creates syntax.h and syntax.c.
 56+ * this program creates syntax.h and syntax.c
 57  */
 58 
 59 #include "parser.h"
 60@@ -50,7 +50,7 @@ struct synclass {
 61   const char *comment;
 62 };
 63 
 64-/* Syntax classes */
 65+/* syntax classes */
 66 static const struct synclass synclass[] = {
 67     {"CWORD", "character is nothing special"},
 68     {"CNL", "newline character"},
 69@@ -73,8 +73,8 @@ static const struct synclass synclass[] = {
 70 };
 71 
 72 /*
 73- * Syntax classes for is_ functions.  Warning:  if you add new classes
 74- * you may have to change the definition of the is_in_name macro.
 75+ * syntax classes for is_ functions. warning: if you add new classes
 76+ * you may have to change the definition of the is_in_name macro
 77  */
 78 static const struct synclass is_entry[] = {
 79     {"ISDIGIT", "a digit"},
 80@@ -86,8 +86,8 @@ static const struct synclass is_entry[] = {
 81 };
 82 
 83 static const char writer[] = "\
 84-/*\n\
 85- * This file was generated by the mksyntax program.\n\
 86+/* \n\
 87+ * this file was generated by the mksyntax program.\n\
 88  */\n\
 89 \n";
 90 
 91@@ -107,7 +107,7 @@ main(int argc __unused, char **argv __unused)
 92   char buf[80];
 93   int  pos;
 94 
 95-  /* Create output files */
 96+  /* create output files */
 97   if ((cfile = fopen("syntax.c", "w")) == NULL) {
 98     perror("syntax.c");
 99     exit(2);
100@@ -121,8 +121,8 @@ main(int argc __unused, char **argv __unused)
101 
102   fputs("#include <limits.h>\n\n", hfile);
103 
104-  /* Generate the #define statements in the header file */
105-  fputs("/* Syntax classes */\n", hfile);
106+  /* generate the #define statements in the header file */
107+  fputs("/* syntax classes */\n", hfile);
108   for (i = 0; synclass[i].name; i++) {
109     if (strcmp(synclass[i].name, "CEOF") == 0) {
110       fputs("#ifdef CEOF\n#undef CEOF\n#endif\n", hfile);
111@@ -134,7 +134,7 @@ main(int argc __unused, char **argv __unused)
112     fprintf(hfile, "/* %s */\n", synclass[i].comment);
113   }
114   putc('\n', hfile);
115-  fputs("/* Syntax classes for is_ functions */\n", hfile);
116+  fputs("/* syntax classes for is_ functions */\n", hfile);
117   for (i = 0; is_entry[i].name; i++) {
118     sprintf(buf, "#define %s %#o", is_entry[i].name, 1 << i);
119     fputs(buf, hfile);
120@@ -151,10 +151,10 @@ main(int argc __unused, char **argv __unused)
121   fputs("#define SQSYNTAX (sqsyntax + SYNBASE)\n", hfile);
122   fputs("#define ARISYNTAX (arisyntax + SYNBASE)\n", hfile);
123   putc('\n', hfile);
124-  output_type_macros(); /* is_digit, etc. */
125+  output_type_macros(); /* is_digit, etc */
126   putc('\n', hfile);
127 
128-  /* Generate the syntax tables. */
129+  /* generate the syntax tables */
130   fputs("#include \"parser.h\"\n", cfile);
131   fputs("#include \"shell.h\"\n", cfile);
132   fputs("#include \"syntax.h\"\n\n", cfile);
133@@ -221,7 +221,7 @@ main(int argc __unused, char **argv __unused)
134 }
135 
136 /*
137- * Output the header and declaration of a syntax table.
138+ * output the header and declaration of a syntax table
139  */
140 
141 static void
142@@ -238,7 +238,7 @@ add_one(const char *key, const char *type)
143 }
144 
145 /*
146- * Add default values to the syntax table.
147+ * add default values to the syntax table
148  */
149 
150 static void
151@@ -257,7 +257,7 @@ add_default(void)
152 }
153 
154 /*
155- * Output the footer of a syntax table.
156+ * output the footer of a syntax table
157  */
158 
159 static void
160@@ -267,7 +267,7 @@ finish(void)
161 }
162 
163 /*
164- * Add entries to the syntax table.
165+ * add entries to the syntax table
166  */
167 
168 static void
169@@ -298,8 +298,8 @@ add(const char *p, const char *type)
170 }
171 
172 /*
173- * Output character classification macros (e.g. is_digit).  If digits are
174- * contiguous, we can test for them quickly.
175+ * output character classification macros (e.g. is_digit). if digits are
176+ * contiguous, we can test for them quickly
177  */
178 
179 static const char *macro[] = {
+25, -25
 1@@ -1,43 +1,43 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 /*
55- * String functions.
56+ * string functions
57  *
58- *	equal(s1, s2)		Return true if strings are equal.
59- *	number(s)		Convert a string of digits to an integer.
60- *	is_number(s)		Return true if s is a string of digits.
61+ * equal(s1, s2) return true if strings are equal
62+ * number(s) convert a string of digits to an integer
63+ * is_number(s) return true if s is a string of digits
64  */
65 
66 #include "mystring.h"
67@@ -53,8 +53,8 @@ char nullstr[1]; /* zero length string */
68  */
69 
70 /*
71- * Convert a string of digits to an integer, printing an error message on
72- * failure.
73+ * convert a string of digits to an integer, printing an error message on
74+ * failure
75  */
76 
77 int
78@@ -66,7 +66,7 @@ number(const char *s)
79 }
80 
81 /*
82- * Check for a valid number.  This should be elsewhere.
83+ * check for a valid number. this should be elsewhere
84  */
85 
86 int
+18, -18
 1@@ -1,35 +1,35 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 #include <string.h>
+65, -65
  1@@ -1,35 +1,35 @@
  2-/*-
  3- * SPDX-License-Identifier: BSD-3-Clause
  4+/* -
  5+ * spdx-license-identifier: bsd-3-clause
  6  *
  7- * Copyright (c) 1991, 1993
  8- *	The Regents of the University of California.  All rights reserved.
  9+ * copyright (c) 1991, 1993
 10+ * the regents of the university of california. all rights reserved
 11  *
 12- * This code is derived from software contributed to Berkeley by
 13- * Kenneth Almquist.
 14+ * this code is derived from software contributed to berkeley by
 15+ * kenneth almquist
 16  *
 17- * Redistribution and use in source and binary forms, with or without
 18+ * redistribution and use in source and binary forms, with or without
 19  * modification, are permitted provided that the following conditions
 20  * are met:
 21- * 1. Redistributions of source code must retain the above copyright
 22- *    notice, this list of conditions and the following disclaimer.
 23- * 2. Redistributions in binary form must reproduce the above copyright
 24- *    notice, this list of conditions and the following disclaimer in the
 25- *    documentation and/or other materials provided with the distribution.
 26- * 3. Neither the name of the University nor the names of its contributors
 27- *    may be used to endorse or promote products derived from this software
 28- *    without specific prior written permission.
 29+ * 1. redistributions of source code must retain the above copyright
 30+ * notice, this list of conditions and the following disclaimer
 31+ * 2. redistributions in binary form must reproduce the above copyright
 32+ * notice, this list of conditions and the following disclaimer in the
 33+ * documentation and/or other materials provided with the distribution
 34+ * 3. neither the name of the university nor the names of its contributors
 35+ * may be used to endorse or promote products derived from this software
 36+ * without specific prior written permission
 37  *
 38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
 43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 50- * SUCH DAMAGE.
 51+ * SUCH DAMAGE
 52  */
 53 
 54 #include <signal.h>
 55@@ -71,7 +71,7 @@ static void setparam(int, char **);
 56 static int  getopts(char *, char *, char **, char ***, char **);
 57 
 58 /*
 59- * Process the shell command line arguments.
 60+ * process the shell command line arguments
 61  */
 62 
 63 int
 64@@ -133,10 +133,10 @@ optschanged(void)
 65 }
 66 
 67 /*
 68- * Process shell options.  The global variable argptr contains a pointer
 69- * to the argument list; we advance it past the options.
 70- * If cmdline is true, process the shell's argv; otherwise, process arguments
 71- * to the set special builtin.
 72+ * process shell options. the global variable argptr contains a pointer
 73+ * to the argument list; we advance it past the options
 74+ * if cmdline is true, process the shell's argv; otherwise, process arguments
 75+ * to the set special builtin
 76  */
 77 
 78 static int
 79@@ -153,23 +153,23 @@ options(int cmdline)
 80     argptr++;
 81     if ((c = *p++) == '-') {
 82       val = 1;
 83-      /* A "-" or  "--" terminates options */
 84+      /* a "-" or "--" terminates options */
 85       if (p[0] == '\0')
 86         goto end_options1;
 87       if (p[0] == '-' && p[1] == '\0')
 88         goto end_options2;
 89-      /**
 90-       * For the benefit of `#!' lines in shell scripts,
 91-       * treat a string of '-- *#.*' the same as '--'.
 92-       * This is needed so that a script starting with:
 93-       *	#!/bin/sh -- # -*- perl -*-
 94-       * will continue to work after a change is made to
 95-       * kern/imgact_shell.c to NOT token-ize the options
 96-       * specified on a '#!' line.  A bit of a kludge,
 97-       * but that trick is recommended in documentation
 98-       * for some scripting languages, and we might as
 99-       * well continue to support it.
100-       */
101+      /* *
102+ * for the benefit of `#!' lines in shell scripts,
103+ * treat a string of '-- *#.*' the same as '--'
104+ * this is needed so that a script starting with:
105+ * #!/bin/sh, # -*- perl -*-
106+ * will continue to work after a change is made to
107+ * kern/imgact_shell.c to NOT token-ize the options
108+ * specified on a '#!' line. a bit of a kludge,
109+ * but that trick is recommended in documentation
110+ * for some scripting languages, and we might as
111+ * well continue to support it
112+ */
113       if (p[0] == '-') {
114         kp = p + 1;
115         while (*kp == ' ' || *kp == '\t')
116@@ -203,7 +203,7 @@ options(int cmdline)
117   }
118   return (login);
119 
120-  /* When processing `set', a single "-" means turn off -x and -v */
121+  /* when processing `set', a single "-" means turn off -x and -v */
122 end_options1:
123   if (!cmdline) {
124     xflag = vflag = 0;
125@@ -211,11 +211,11 @@ end_options1:
126   }
127 
128   /*
129-   * When processing `set', a "--" means the remaining arguments
130-   * replace the positional parameters in the active shell.  If
131-   * there are no remaining options, then all the positional
132-   * parameters are cleared (equivalent to doing ``shift $#'').
133-   */
134+ * when processing `set', a "--" means the remaining arguments
135+ * replace the positional parameters in the active shell. if
136+ * there are no remaining options, then all the positional
137+ * parameters are cleared (equivalent to doing ``shift $#'')
138+ */
139 end_options2:
140   if (!cmdline) {
141     if (*argptr == NULL)
142@@ -224,19 +224,19 @@ end_options2:
143   }
144 
145   /*
146-   * At this point we are processing options given to 'sh' on a command
147-   * line.  If an end-of-options marker ("-" or "--") is followed by an
148-   * arg of "#", then skip over all remaining arguments.  Some scripting
149-   * languages (e.g.: perl) document that /bin/sh will implement this
150-   * behavior, and they recommend that users take advantage of it to
151-   * solve certain issues that can come up when writing a perl script.
152-   * Yes, this feature is in /bin/sh to help users write perl scripts.
153-   */
154+ * at this point we are processing options given to 'sh' on a command
155+ * line. if an end-of-options marker ("-" or "--") is followed by an
156+ * arg of "#", then skip over all remaining arguments. some scripting
157+ * languages (e.g.: perl) document that /bin/sh will implement this
158+ * behavior, and they recommend that users take advantage of it to
159+ * solve certain issues that can come up when writing a perl script
160+ * yes, this feature is in /bin/sh to help users write perl scripts
161+ */
162   p = *argptr;
163   if (p != NULL && p[0] == '#' && p[1] == '\0') {
164     while (*argptr != NULL)
165       argptr++;
166-    /* We need to keep the final argument */
167+    /* we need to keep the final argument */
168     argptr--;
169   }
170 
171@@ -252,12 +252,12 @@ minus_o(char *name, int val)
172 
173   if (name == NULL) {
174     if (val) {
175-      /* "Pretty" output. */
176+      /* "pretty" output */
177       out1str("Current option settings\n");
178       for (i = 0, on = optname; i < NOPTS; i++, on += *on + 1)
179         out1fmt("%-16.*s%s\n", *on, on + 1, optval[i] ? "on" : "off");
180     } else {
181-      /* Output suitable for re-input to shell. */
182+      /* output suitable for re-input to shell */
183       for (i = 0, on = optname; i < NOPTS; i++, on += *on + 1)
184         out1fmt(
185             "%s %co %.*s%s",
186@@ -312,7 +312,7 @@ setoption(int flag, int val)
187 }
188 
189 /*
190- * Set the shell parameters.
191+ * set the shell parameters
192  */
193 
194 static void
195@@ -336,7 +336,7 @@ setparam(int argc, char **argv)
196 }
197 
198 /*
199- * Free the list of positional parameters.
200+ * free the list of positional parameters
201  */
202 
203 void
204@@ -357,7 +357,7 @@ freeparam(struct shparam *param)
205 }
206 
207 /*
208- * The shift builtin command.
209+ * the shift builtin command
210  */
211 
212 int
213@@ -382,7 +382,7 @@ shiftcmd(int argc, char **argv)
214 }
215 
216 /*
217- * The set builtin command.
218+ * the set builtin command
219  */
220 
221 int
222@@ -410,10 +410,10 @@ getoptsreset(const char *value)
223 }
224 
225 /*
226- * The getopts builtin.  Shellparam.optnext points to the next argument
227- * to be processed.  Shellparam.optptr points to the next character to
228- * be processed in the current argument.  If shellparam.optnext is NULL,
229- * then it's the first time getopts has been called.
230+ * the getopts builtin. shellparam.optnext points to the next argument
231+ * to be processed. shellparam.optptr points to the next character to
232+ * be processed in the current argument. if shellparam.optnext is NULL,
233+ * then its the first time getopts has been called
234  */
235 
236 int
237@@ -462,7 +462,7 @@ getopts(char *optstr, char *optvar, char **optfirst, char ***optnext, char **opt
238   const char *newoptarg = NULL;
239 
240   if ((p = *optptr) == NULL || *p == '\0') {
241-    /* Current word is done, advance */
242+    /* current word is done, advance */
243     if (*optnext == NULL)
244       return 1;
245     p = **optnext;
246@@ -541,10 +541,10 @@ out:
247 }
248 
249 /*
250- * Standard option processing (a la getopt) for builtin routines.  The
251+ * standard option processing (a la getopt) for builtin routines. the
252  * only argument that is passed to nextopt is the option string; the
253- * other arguments are unnecessary.  It returns the option, or '\0' on
254- * end of input.
255+ * other arguments are unnecessary. it returns the option, or '\0' on
256+ * end of input
257  */
258 
259 int
+18, -18
 1@@ -1,35 +1,35 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 struct shparam {
+27, -27
 1@@ -1,45 +1,45 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 /*
55- * Shell output routines.  We use our own output routines because:
56- *	When a builtin command is interrupted we have to discard
57- *		any pending output.
58- *	When a builtin command appears in back quotes, we want to
59- *		save the output of the command in a region obtained
60- *		via malloc, rather than doing a fork and reading the
61- *		output of the command via a pipe.
62+ * shell output routines. we use our own output routines because:
63+ * when a builtin command is interrupted we have to discard
64+ * any pending output
65+ * when a builtin command appears in back quotes, we want to
66+ * save the output of the command in a region obtained
67+ * via malloc, rather than doing a fork and reading the
68+ * output of the command via a pipe
69  */
70 
71 #include <errno.h>
72@@ -203,7 +203,7 @@ outdqstr(const char *p, struct output *file)
73   outcslow('\'', file);
74 }
75 
76-/* Like outstr(), but quote for re-input into the shell. */
77+/* like outstr(), but quote for re-input into the shell */
78 void
79 outqstr(const char *p, struct output *file)
80 {
81@@ -372,7 +372,7 @@ out1fp(void)
82 }
83 
84 /*
85- * Version of write which resumes after a signal is caught.
86+ * version of write which resumes after a signal is caught
87  */
88 
89 int
+19, -19
 1@@ -1,35 +1,35 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 #include "sh_cdefs.h"
55@@ -54,7 +54,7 @@ extern struct output  errout; /* to fd 2 */
56 extern struct output  memout;
57 extern struct output *out1; /* &memout if backquote, otherwise &output */
58 extern struct output *out2; /* &memout if backquote with 2>&1, otherwise
59-             &errout */
60+ * &errout */
61 
62 void  outcslow(int, struct output *);
63 void  out1str(const char *);
+200, -200
  1@@ -1,35 +1,35 @@
  2-/*-
  3- * SPDX-License-Identifier: BSD-3-Clause
  4+/* -
  5+ * spdx-license-identifier: bsd-3-clause
  6  *
  7- * Copyright (c) 1991, 1993
  8- *	The Regents of the University of California.  All rights reserved.
  9+ * copyright (c) 1991, 1993
 10+ * the regents of the university of california. all rights reserved
 11  *
 12- * This code is derived from software contributed to Berkeley by
 13- * Kenneth Almquist.
 14+ * this code is derived from software contributed to berkeley by
 15+ * kenneth almquist
 16  *
 17- * Redistribution and use in source and binary forms, with or without
 18+ * redistribution and use in source and binary forms, with or without
 19  * modification, are permitted provided that the following conditions
 20  * are met:
 21- * 1. Redistributions of source code must retain the above copyright
 22- *    notice, this list of conditions and the following disclaimer.
 23- * 2. Redistributions in binary form must reproduce the above copyright
 24- *    notice, this list of conditions and the following disclaimer in the
 25- *    documentation and/or other materials provided with the distribution.
 26- * 3. Neither the name of the University nor the names of its contributors
 27- *    may be used to endorse or promote products derived from this software
 28- *    without specific prior written permission.
 29+ * 1. redistributions of source code must retain the above copyright
 30+ * notice, this list of conditions and the following disclaimer
 31+ * 2. redistributions in binary form must reproduce the above copyright
 32+ * notice, this list of conditions and the following disclaimer in the
 33+ * documentation and/or other materials provided with the distribution
 34+ * 3. neither the name of the university nor the names of its contributors
 35+ * may be used to endorse or promote products derived from this software
 36+ * without specific prior written permission
 37  *
 38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
 43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 50- * SUCH DAMAGE.
 51+ * SUCH DAMAGE
 52  */
 53 
 54 #include <pwd.h>
 55@@ -67,7 +67,7 @@ size_t xstrlcpy(char *, const char *, size_t);
 56 #endif
 57 
 58 /*
 59- * Shell command parser.
 60+ * shell command parser
 61  */
 62 
 63 #define PROMPTLEN 192
 64@@ -194,7 +194,7 @@ parser_temp_free_all(void)
 65 }
 66 
 67 /*
 68- * Read and parse a command.  Returns NEOF on end of file.  (NULL is a
 69+ * read and parse a command. returns NEOF on end of file. (NULL is a
 70  * valid parse tree indicating a blank line.)
 71  */
 72 
 73@@ -203,9 +203,9 @@ parsecmd(int interact)
 74 {
 75   int t;
 76 
 77-  /* This assumes the parser is not re-entered,
 78-   * which could happen if we add command substitution on PS1/PS2.
 79-   */
 80+  /* this assumes the parser is not re-entered,
 81+ * which could happen if we add command substitution on PS1/PS2
 82+ */
 83   parser_temp_free_all();
 84   heredoclist = NULL;
 85 
 86@@ -227,8 +227,8 @@ parsecmd(int interact)
 87 }
 88 
 89 /*
 90- * Read and parse words for wordexp.
 91- * Returns a list of NARG nodes; NULL if there are no words.
 92+ * read and parse words for wordexp
 93+ * returns a list of NARG nodes; NULL if there are no words
 94  */
 95 union node *
 96 parsewordexp(void)
 97@@ -236,9 +236,9 @@ parsewordexp(void)
 98   union node *n, *first = NULL, **pnext;
 99   int         t;
100 
101-  /* This assumes the parser is not re-entered,
102-   * which could happen if we add command substitution on PS1/PS2.
103-   */
104+  /* this assumes the parser is not re-entered,
105+ * which could happen if we add command substitution on PS1/PS2
106+ */
107   parser_temp_free_all();
108   heredoclist = NULL;
109 
110@@ -411,7 +411,7 @@ command(void)
111   n1          = NULL;
112   rpp         = &redir;
113 
114-  /* Check for redirection which may precede command */
115+  /* check for redirection which may precede command */
116   while (readtoken() == TREDIR) {
117     *rpp = n2 = redirnode;
118     rpp       = &n2->nfile.next;
119@@ -485,9 +485,9 @@ command(void)
120         n2->narg.next          = NULL;
121         n1->nfor.args          = n2;
122         /*
123-         * Newline or semicolon here is optional (but note
124-         * that the original Bourne shell only allowed NL).
125-         */
126+ * newline or semicolon here is optional (but note
127+ * that the original bourne shell only allowed NL)
128+ */
129         if (lasttoken != TSEMI)
130           tokpushback++;
131       }
132@@ -560,7 +560,7 @@ command(void)
133       consumetoken(TEND);
134       checkkwd = CHKKWD | CHKALIAS;
135       break;
136-    /* A simple command must have at least one redirection or word. */
137+    /* a simple command must have at least one redirection or word */
138     case TBACKGND:
139     case TSEMI:
140     case TAND:
141@@ -582,7 +582,7 @@ command(void)
142       synexpect(-1);
143   }
144 
145-  /* Now check for redirection which may follow command */
146+  /* now check for redirection which may follow command */
147   while (readtoken() == TREDIR) {
148     *rpp = n2 = redirnode;
149     rpp       = &n2->nfile.next;
150@@ -612,18 +612,18 @@ simplecmd(union node **rpp, union node *redir)
151   int          special;
152   int          savecheckkwd;
153 
154-  /* If we don't have any redirections already, then we must reset */
155-  /* rpp to be the address of the local redir variable.  */
156+  /* if we dont have any redirections already, then we must reset */
157+  /* rpp to be the address of the local redir variable */
158   if (redir == NULL)
159     rpp = &redir;
160 
161   args = NULL;
162   app  = &args;
163   /*
164-   * We save the incoming value, because we need this for shell
165-   * functions.  There can not be a redirect or an argument between
166-   * the function name and the open parenthesis.
167-   */
168+ * we save the incoming value, because we need this for shell
169+ * functions. there can not be a redirect or an argument between
170+ * the function name and the open parenthesis
171+ */
172   orig_rpp = rpp;
173 
174   savecheckkwd = CHKALIAS;
175@@ -641,15 +641,15 @@ simplecmd(union node **rpp, union node *redir)
176       rpp      = &n->nfile.next;
177       parsefname(); /* read name of redirection file */
178     } else if (lasttoken == TLP && app == &args->narg.next && rpp == orig_rpp) {
179-      /* We have a function */
180+      /* we have a function */
181       consumetoken(TRP);
182       funclinno = plinno;
183       /*
184-       * - Require plain text.
185-       * - Functions with '/' cannot be called.
186-       * - Reject name=().
187-       * - Reject ksh extended glob patterns.
188-       */
189+ * - require plain text
190+ * - functions with '/' cannot be called
191+ * - reject name=()
192+ * - reject ksh extended glob patterns
193+ */
194       if (!noexpand(n->narg.text) || quoteflag || strchr(n->narg.text, '/')
195           || strchr("!%*+-=?@}~", n->narg.text[strlen(n->narg.text) - 1]))
196         synerror("Bad function name");
197@@ -764,7 +764,7 @@ parsefname(void)
198 }
199 
200 /*
201- * Input any here documents.
202+ * input any here documents
203  */
204 
205 static void
206@@ -811,8 +811,8 @@ top:
207   t = xxreadtoken();
208 
209   /*
210-   * eat newlines
211-   */
212+ * eat newlines
213+ */
214   if (checkkwd & CHKNL) {
215     while (t == TNL) {
216       parseheredoc();
217@@ -821,8 +821,8 @@ top:
218   }
219 
220   /*
221-   * check for keywords and aliases
222-   */
223+ * check for keywords and aliases
224+ */
225   if (t == TWORD && !quoteflag) {
226     const char *const *pp;
227 
228@@ -853,21 +853,21 @@ out:
229 }
230 
231 /*
232- * Read the next input token.
233- * If the token is a word, we set backquotelist to the list of cmds in
234- *	backquotes.  We set quoteflag to true if any part of the word was
235- *	quoted.
236- * If the token is TREDIR, then we set redirnode to a structure containing
237- *	the redirection.
238- * In all cases, the variable startlinno is set to the number of the line
239- *	on which the token starts.
240+ * read the next input token
241+ * if the token is a word, we set backquotelist to the list of cmds in
242+ * backquotes. we set quoteflag to true if any part of the word was
243+ * quoted
244+ * if the token is TREDIR, then we set redirnode to a structure containing
245+ * the redirection
246+ * in all cases, the variable startlinno is set to the number of the line
247+ * on which the token starts
248  *
249- * [Change comment:  here documents and internal procedures]
250- * [Readtoken shouldn't have any arguments.  Perhaps we should make the
251- *  word parsing code into a separate routine.  In this case, readtoken
252- *  doesn't need to have any internal procedures, but parseword does.
253- *  We could also make parseoperator in essence the main routine, and
254- *  have parseword (readtoken1?) handle both words and redirection.]
255+ * [change comment: here documents and internal procedures]
256+ * [readtoken shouldnt have any arguments. perhaps we should make the
257+ * word parsing code into a separate routine. in this case, readtoken
258+ * doesnt need to have any internal procedures, but parseword does
259+ * we could also make parseoperator in essence the main routine, and
260+ * have parseword (readtoken1?) handle both words and redirection.]
261  */
262 
263 #define RETURN(token) return lasttoken = token
264@@ -956,10 +956,10 @@ struct tokenstate {
265 };
266 
267 /*
268- * Check to see whether we are at the end of the here document.  When this
269- * is called, c is set to the first character of the next input line.  If
270- * we are at the end of the here document, this routine sets the c to PEOF.
271- * The new value of c is returned.
272+ * check to see whether we are at the end of the here document. when this
273+ * is called, c is set to the first character of the next input line. if
274+ * we are at the end of the here document, this routine sets the c to PEOF
275+ * the new value of c is returned
276  */
277 
278 static int
279@@ -994,9 +994,9 @@ checkend(int c, const char *eofmark, int striptabs)
280 }
281 
282 /*
283- * Parse a redirection operator.  The variable "out" points to a string
284- * specifying the fd to be redirected.  The variable "c" contains the
285- * first character of the redirection operator.
286+ * parse a redirection operator. the variable "out" points to a string
287+ * specifying the fd to be redirected. the variable "c" contains the
288+ * first character of the redirection operator
289  */
290 
291 static void
292@@ -1051,7 +1051,7 @@ parseredir(char *out, int c)
293 }
294 
295 /*
296- * Called to parse command substitutions.
297+ * called to parse command substitutions
298  */
299 
300 static char *
301@@ -1095,9 +1095,9 @@ parsebackq(char *out, struct nodelist **pbqlist, int oldstyle, int dblquote, int
302   heredoclist = NULL;
303   INTON;
304   if (oldstyle) {
305-    /* We must read until the closing backquote, giving special
306-       treatment to some slashes, and then push the string and
307-       reread it as input, interpreting it normally.  */
308+    /* we must read until the closing backquote, giving special
309+ * treatment to some slashes, and then push the string and
310+ * reread it as input, interpreting it normally */
311     char *oout;
312     int   c;
313     int   olen;
314@@ -1165,9 +1165,9 @@ parsebackq(char *out, struct nodelist **pbqlist, int oldstyle, int dblquote, int
315   (*nlpp)->n = n;
316   if (oldstyle) {
317     /*
318-     * Start reading from old file again, ignoring any pushed back
319-     * tokens left from the backquote parsing
320-     */
321+ * start reading from old file again, ignoring any pushed back
322+ * tokens left from the backquote parsing
323+ */
324     popfile();
325     tokpushback = 0;
326   }
327@@ -1201,8 +1201,8 @@ parsebackq(char *out, struct nodelist **pbqlist, int oldstyle, int dblquote, int
328 }
329 
330 /*
331- * Called to parse a backslash escape sequence inside $'...'.
332- * The backslash has already been read.
333+ * called to parse a backslash escape sequence inside $'...'
334+ * the backslash has already been read
335  */
336 static char *
337 readcstyleesc(char *out)
338@@ -1315,13 +1315,13 @@ readcstyleesc(char *out)
339       }
340       if (v == 0 || (v >= 0xd800 && v <= 0xdfff))
341         synerror("Bad escape sequence");
342-      /* We really need iconv here. */
343+      /* we really need iconv here */
344       if (initial_localeisutf8 && v > 127) {
345         CHECKSTRSPACE(4, out);
346         /*
347-         * We cannot use wctomb() as the locale may have
348-         * changed.
349-         */
350+ * we cannot use wctomb() as the locale may have
351+ * changed
352+ */
353         if (v <= 0x7ff) {
354           USTPUTC(0xc0 | v >> 6, out);
355           USTPUTC(0x80 | (v & 0x3f), out);
356@@ -1347,9 +1347,9 @@ readcstyleesc(char *out)
357   }
358   vc = (char)v;
359   /*
360-   * We can't handle NUL bytes.
361-   * POSIX says we should skip till the closing quote.
362-   */
363+ * we cant handle NUL bytes
364+ * POSIX says we should skip till the closing quote
365+ */
366   if (vc == '\0') {
367     while ((c = pgetc()) != '\'') {
368       if (c == '\\')
369@@ -1374,15 +1374,15 @@ readcstyleesc(char *out)
370 }
371 
372 /*
373- * If eofmark is NULL, read a word or a redirection symbol.  If eofmark
374- * is not NULL, read a here document.  In the latter case, eofmark is the
375+ * if eofmark is NULL, read a word or a redirection symbol. if eofmark
376+ * is not NULL, read a here document. in the latter case, eofmark is the
377  * word which marks the end of the document and striptabs is true if
378- * leading tabs should be stripped from the document.  The argument firstc
379- * is the first character of the input token or document.
380+ * leading tabs should be stripped from the document. the argument firstc
381+ * is the first character of the input token or document
382  *
383- * Because C does not have internal subroutines, I have simulated them
384- * using goto's to implement the subroutine linkage.  The following macros
385- * will run code that appears at the end of readtoken1.
386+ * because c does not have internal subroutines, i have simulated them
387+ * using goto's to implement the subroutine linkage. the following macros
388+ * will run code that appears at the end of readtoken1
389  */
390 
391 #define PARSESUB()                                                                                 \
392@@ -1539,9 +1539,9 @@ loop: { /* for each line, until end of word */
393               USTPUTC(')', out);
394           } else {
395             /*
396-             * unbalanced parens
397-             *  (don't 2nd guess - no error)
398-             */
399+ * unbalanced parens
400+ * (dont 2nd guess - no error)
401+ */
402             pungetc();
403             USTPUTC(')', out);
404           }
405@@ -1598,9 +1598,9 @@ endword:
406   /* end of readtoken routine */
407 
408   /*
409-   * Parse a substitution.  At this point, we have read the dollar sign
410-   * and nothing else.
411-   */
412+ * parse a substitution. at this point, we have read the dollar sign
413+ * and nothing else
414+ */
415 
416 parsesub: {
417   int               subtype;
418@@ -1645,8 +1645,8 @@ parsesub: {
419         length++;
420       } while (!is_eof(c) && is_in_name(c));
421       if (length == 6 && strncmp(out - length, "LINENO", length) == 0) {
422-        /* Replace the variable name with the
423-         * current line number. */
424+        /* replace the variable name with the
425+ * current line number */
426         STADJUST(-6, out);
427         CHECKSTRSPACE(11, out);
428         linno = plinno;
429@@ -1705,7 +1705,7 @@ parsesub: {
430         case ':':
431           flags |= VSNUL;
432           c = pgetc_linecont();
433-          /*FALLTHROUGH*/
434+          /* FALLTHROUGH */
435         default:
436           p = strchr(types, c);
437           if (p == NULL) {
438@@ -1756,18 +1756,18 @@ parsesub: {
439       state[level].parenlevel = 0;
440       if (subtype == VSMINUS || subtype == VSPLUS || subtype == VSQUESTION || subtype == VSASSIGN) {
441         /*
442-         * For operators that were in the Bourne shell,
443-         * inherit the double-quote state.
444-         */
445+ * for operators that were in the bourne shell,
446+ * inherit the double-quote state
447+ */
448         state[level].syntax   = state[level - 1].syntax;
449         state[level].category = TSTATE_VAR_OLD;
450       } else {
451         /*
452-         * The other operators take a pattern,
453-         * so go to BASESYNTAX.
454-         * Also, ' and " are now special, even
455-         * in here documents.
456-         */
457+ * the other operators take a pattern,
458+ * so go to BASESYNTAX
459+ * also, ' and " are now special, even
460+ * in here documents
461+ */
462         state[level].syntax   = BASESYNTAX;
463         state[level].category = TSTATE_VAR_NEW;
464         newvarnest++;
465@@ -1786,7 +1786,7 @@ parsesub: {
466 }
467 
468 /*
469- * Parse an arithmetic expansion (indicate start of one and set state)
470+ * parse an arithmetic expansion (indicate start of one and set state)
471  */
472 parsearith: {
473   if (level + 1 >= maxnest) {
474@@ -1812,8 +1812,8 @@ parsearith: {
475 } /* end of readtoken */
476 
477 /*
478- * Returns true if the text contains nothing to expand (no dollar signs
479- * or backquotes).
480+ * returns true if the text contains nothing to expand (no dollar signs
481+ * or backquotes)
482  */
483 
484 static int
485@@ -1835,8 +1835,8 @@ noexpand(char *text)
486 }
487 
488 /*
489- * Return true if the argument is a legal variable name (a letter or
490- * underscore followed by zero or more letters, underscores, and digits).
491+ * return true if the argument is a legal variable name (a letter or
492+ * underscore followed by zero or more letters, underscores, and digits)
493  */
494 
495 int
496@@ -1877,9 +1877,9 @@ consumetoken(int token)
497 }
498 
499 /*
500- * Called when an unexpected token is read during the parse.  The argument
501+ * called when an unexpected token is read during the parse. the argument
502  * is the token that is expected, or -1 if more than one type of token can
503- * occur at this point.
504+ * occur at this point
505  */
506 
507 static void
508@@ -1937,7 +1937,7 @@ pgetc_linecont(void)
509         setprompt(0);
510     } else {
511       pungetc();
512-      /* Allow the backslash to be pushed back. */
513+      /* allow the backslash to be pushed back */
514       pushstring("\\", 1, NULL);
515       return (pgetc());
516     }
517@@ -1968,11 +1968,11 @@ getusername(char *name, size_t namelen)
518     euid = geteuid();
519 
520     /*
521-     * Handle the case when there is more than one
522-     * login with the same UID, or when the login
523-     * returned by getlogin(2) does no longer match
524-     * the current UID.
525-     */
526+ * handle the case when there is more than one
527+ * login with the same UID, or when the login
528+ * returned by getlogin(2) does no longer match
529+ * the current UID
530+ */
531     pw = getpwlogin();
532     if (pw == NULL || pw->pw_uid != euid)
533       pw = getpwuid(euid);
534@@ -1988,8 +1988,8 @@ getusername(char *name, size_t namelen)
535 }
536 
537 /*
538- * called by editline -- any expansions to the prompt
539- *    should be added here.
540+ * called by editline, any expansions to the prompt
541+ * should be added here
542  */
543 char *
544 getprompt(void *unused __unused)
545@@ -2003,8 +2003,8 @@ getprompt(void *unused __unused)
546   static char internal_error[] = "??";
547 
548   /*
549-   * Select prompt format.
550-   */
551+ * select prompt format
552+ */
553   switch (whichprompt) {
554     case 0:
555       fmt = "";
556@@ -2022,17 +2022,17 @@ getprompt(void *unused __unused)
557   }
558 
559   /*
560-   * Format prompt string.
561-   */
562+ * format prompt string
563+ */
564   for (i = 0; (i < PROMPTLEN - 1) && (*fmt != '\0'); i++, fmt++) {
565     if (*fmt == '$') {
566       const char *varname_start, *varname_end, *value;
567       char        varname[256];
568       int         namelen, braced = 0;
569 
570-      fmt++; /* Skip the '$' */
571+      fmt++; /* skip the '$' */
572 
573-      /* Check for ${VAR} syntax */
574+      /* check for ${VAR} syntax */
575       if (*fmt == '{') {
576         braced = 1;
577         fmt++;
578@@ -2040,26 +2040,26 @@ getprompt(void *unused __unused)
579 
580       varname_start = fmt;
581 
582-      /* Extract variable name */
583+      /* extract variable name */
584       if (is_digit(*fmt)) {
585-        /* Positional parameter: $0, $1, etc. */
586+        /* positional parameter: $0, $1, etc */
587         fmt++;
588         varname_end = fmt;
589       } else if (is_special(*fmt)) {
590-        /* Special parameter: $?, $!, $$, etc. */
591+        /* special parameter: $?, $!, $$, etc */
592         fmt++;
593         varname_end = fmt;
594       } else if (is_name(*fmt)) {
595-        /* Regular variable name */
596+        /* regular variable name */
597         do
598           fmt++;
599         while (is_in_name(*fmt));
600         varname_end = fmt;
601       } else {
602         /*
603-         * Not a valid variable reference.
604-         * Output literal '$'.
605-         */
606+ * not a valid variable reference
607+ * output literal '$'
608+ */
609         ps[i] = '$';
610         if (braced && i < PROMPTLEN - 2)
611           ps[++i] = '{';
612@@ -2069,23 +2069,23 @@ getprompt(void *unused __unused)
613 
614       namelen = varname_end - varname_start;
615       if (namelen == 0 || namelen >= (int)sizeof(varname)) {
616-        /* Invalid or too long, output literal */
617+        /* invalid or too long, output literal */
618         ps[i] = '$';
619         fmt   = varname_start - 1;
620         continue;
621       }
622 
623-      /* Copy variable name */
624+      /* copy variable name */
625       memcpy(varname, varname_start, namelen);
626       varname[namelen] = '\0';
627 
628-      /* Handle closing brace for ${VAR} */
629+      /* handle closing brace for ${VAR} */
630       if (braced) {
631         if (*fmt == '}') {
632           fmt++;
633         } else {
634-          /* Missing closing brace, treat as
635-           * literal */
636+          /* missing closing brace, treat as
637+ * literal */
638           ps[i] = '$';
639           if (i < PROMPTLEN - 2)
640             ps[++i] = '{';
641@@ -2094,9 +2094,9 @@ getprompt(void *unused __unused)
642         }
643       }
644 
645-      /* Look up the variable */
646+      /* look up the variable */
647       if (namelen == 1 && is_digit(*varname)) {
648-        /* Positional parameters - check digits FIRST */
649+        /* positional parameters - check digits FIRST */
650         int num = *varname - '0';
651         if (num == 0)
652           value = arg0 ? arg0 : "";
653@@ -2105,7 +2105,7 @@ getprompt(void *unused __unused)
654         else
655           value = "";
656       } else if (namelen == 1 && is_special(*varname)) {
657-        /* Special parameters */
658+        /* special parameters */
659         char valbuf[20];
660         int  num;
661 
662@@ -2129,22 +2129,22 @@ getprompt(void *unused __unused)
663         snprintf(valbuf, sizeof(valbuf), "%d", num);
664         value = valbuf;
665       } else {
666-        /* Regular variables */
667+        /* regular variables */
668         value = lookupvar(varname);
669         if (value == NULL)
670           value = "";
671       }
672 
673-      /* Copy value to output, respecting buffer size */
674+      /* copy value to output, respecting buffer size */
675       while (*value != '\0' && i < PROMPTLEN - 1) {
676         ps[i++] = *value++;
677       }
678 
679       /*
680-       * Adjust fmt and i for the loop increment.
681-       * fmt will be incremented by the for loop,
682-       * so position it one before where we want.
683-       */
684+ * adjust fmt and i for the loop increment
685+ * fmt will be incremented by the for loop,
686+ * so position it one before where we want
687+ */
688       fmt--;
689       i--;
690       continue;
691@@ -2155,19 +2155,19 @@ getprompt(void *unused __unused)
692 
693     switch (*++fmt) {
694       /*
695-       * Non-printing sequence begin and end.
696-       */
697+ * non-printing sequence begin and end
698+ */
699       case '[':
700       case ']':
701         ps[i] = '\001';
702         break;
703 
704       /*
705-       * Literal \ and some ASCII characters:
706-       * \a	BEL
707-       * \e	ESC
708-       * \r	CR
709-       */
710+ * literal \ and some ASCII characters:
711+ * \a bel
712+ * \e esc
713+ * \r cr
714+ */
715       case '\\':
716       case 'a':
717       case 'e':
718@@ -2183,8 +2183,8 @@ getprompt(void *unused __unused)
719         break;
720 
721       /*
722-       * CRLF sequence
723-       */
724+ * CRLF sequence
725+ */
726       case 'n':
727         if (i < PROMPTLEN - 3) {
728           ps[i++] = '\r';
729@@ -2193,60 +2193,60 @@ getprompt(void *unused __unused)
730         break;
731 
732       /*
733-       * Print the current time as per provided strftime format.
734-       */
735+ * print the current time as per provided strftime format
736+ */
737       case 'D': {
738-        char       tfmt[128] = "%X"; /* \D{} means %X. */
739+        char       tfmt[128] = "%X"; /* \d{} means %x */
740         struct tm *now;
741 
742         if (fmt[1] != '{') {
743           /*
744-           * "\D" but not "\D{", so treat the '\'
745-           * literally and rewind fmt to treat 'D'
746-           * literally next iteration.
747-           */
748+ * "\d" but not "\d{", so treat the '\'
749+ * literally and rewind fmt to treat 'd'
750+ * literally next iteration
751+ */
752           ps[i] = '\\';
753           fmt--;
754           break;
755         }
756-        fmt += 2; /* Consume "D{". */
757+        fmt += 2; /* consume "d{" */
758         if (fmt[0] != '}') {
759           char *end;
760 
761           end = memccpy(tfmt, fmt, '}', sizeof(tfmt));
762           if (end == NULL) {
763             /*
764-             * Format too long or no '}', so
765-             * ignore "\D{" altogether.
766-             * The loop will do i++, but nothing
767-             * was written to ps, so do i-- here.
768-             * Rewind fmt for similar reason.
769-             */
770+ * format too long or no '}', so
771+ * ignore "\d{" altogether
772+ * the loop will do i++, but nothing
773+ * was written to ps, so do i-- here
774+ * rewind fmt for similar reason
775+ */
776             i--;
777             fmt--;
778             break;
779           }
780-          *--end = '\0'; /* Ignore the copy of '}'. */
781+          *--end = '\0'; /* ignore the copy of '}' */
782           fmt += end - tfmt;
783         }
784         now = localtime(&(time_t){time(NULL)});
785         i += strftime(&ps[i], PROMPTLEN - i - 1, tfmt, now);
786-        i--; /* The loop will do i++. */
787+        i--; /* the loop will do i++ */
788         break;
789       }
790 
791       /*
792-       * Hostname.
793-       *
794-       * \h specifies just the local hostname,
795-       * \H specifies fully-qualified hostname.
796-       */
797+ * hostname
798+ *
799+ * \h specifies just the local hostname,
800+ * \h specifies fully-qualified hostname
801+ */
802       case 'h':
803       case 'H':
804         ps[i] = '\0';
805         gethostname(&ps[i], PROMPTLEN - i - 1);
806         ps[PROMPTLEN - 1] = '\0';
807-        /* Skip to end of hostname. */
808+        /* skip to end of hostname */
809         trim = (*fmt == 'h') ? '.' : '\0';
810         while ((ps[i] != '\0') && (ps[i] != trim))
811           i++;
812@@ -2254,22 +2254,22 @@ getprompt(void *unused __unused)
813         break;
814 
815       /*
816-       * User name.
817-       */
818+ * user name
819+ */
820       case 'u':
821         ps[i] = '\0';
822         getusername(&ps[i], PROMPTLEN - i);
823-        /* Skip to end of username. */
824+        /* skip to end of username */
825         while (ps[i + 1] != '\0')
826           i++;
827         break;
828 
829       /*
830-       * Working directory.
831-       *
832-       * \W specifies just the final component,
833-       * \w specifies the entire path.
834-       */
835+ * working directory
836+ *
837+ * \w specifies just the final component,
838+ * \w specifies the entire path
839+ */
840       case 'W':
841       case 'w':
842         pwd = lookupvar("PWD");
843@@ -2289,23 +2289,23 @@ getprompt(void *unused __unused)
844             strlcpy(&ps[i], pwd, PROMPTLEN - i);
845           }
846         }
847-        /* Skip to end of path. */
848+        /* skip to end of path */
849         while (ps[i + 1] != '\0')
850           i++;
851         break;
852 
853       /*
854-       * Superuser status.
855-       *
856-       * '$' for normal users, '#' for root.
857-       */
858+ * superuser status
859+ *
860+ * '$' for normal users, '#' for root
861+ */
862       case '$':
863         ps[i] = (geteuid() != 0) ? '$' : '#';
864         break;
865 
866       /*
867-       * Emit unrecognized formats verbatim.
868-       */
869+ * emit unrecognized formats verbatim
870+ */
871       default:
872         ps[i] = '\\';
873         if (i < PROMPTLEN - 2)
+27, -27
 1@@ -1,35 +1,35 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 /* control characters in argument strings */
55@@ -38,7 +38,7 @@
56 #define CTLENDVAR '\371'
57 #define CTLBACKQ  '\372'
58 #define CTLQUOTE  01 /* ored with CTLBACKQ code if in quotes */
59-/*	CTLBACKQ | CTLQUOTE == '\373' */
60+/* CTLBACKQ | CTLQUOTE == '\373' */
61 #define CTLARI       '\374'
62 #define CTLENDARI    '\375'
63 #define CTLQUOTEMARK '\376'
64@@ -46,14 +46,14 @@
65 
66 /* variable substitution byte (follows CTLVAR) */
67 #define VSTYPE 0x0f /* type of variable substitution */
68-#define VSNUL  0x10 /* colon--treat the empty string as unset */
69+#define VSNUL  0x10 /* colon, treat the empty string as unset */
70 #define VSLINENO                                                                                   \
71-  0x20               /* expansion of $LINENO, the line number                                      \
72-              follows immediately */
73-#define VSQUOTE 0x80 /* inside double quotes--suppress splitting */
74+  0x20               /* expansion of $LINENO, the line number \
75+ * follows immediately */
76+#define VSQUOTE 0x80 /* inside double quotes, suppress splitting */
77 
78 /* values of VSTYPE field */
79-#define VSNORMAL       0x1 /* normal variable:  $var or ${var} */
80+#define VSNORMAL       0x1 /* normal variable: $var or ${var} */
81 #define VSMINUS        0x2 /* ${var-text} */
82 #define VSPLUS         0x3 /* ${var+text} */
83 #define VSQUESTION     0x4 /* ${var?message} */
84@@ -63,11 +63,11 @@
85 #define VSTRIMRIGHT    0x8 /* ${var%pattern} */
86 #define VSTRIMRIGHTMAX 0x9 /* ${var%%pattern} */
87 #define VSLENGTH       0xa /* ${#var} */
88-#define VSERROR        0xb /* Syntax error, issue when expanded */
89+#define VSERROR        0xb /* syntax error, issue when expanded */
90 
91 /*
92- * NEOF is returned by parsecmd when it encounters an end of file.  It
93- * must be distinct from NULL.
94+ * NEOF is returned by parsecmd when it encounters an end of file. it
95+ * must be distinct from NULL
96  */
97 #define NEOF ((union node *)-1)
98 extern int               whichprompt; /* 1 == PS1, 2 == PS2 */
+40, -40
  1@@ -1,39 +1,39 @@
  2-/*-
  3- * SPDX-License-Identifier: BSD-3-Clause
  4+/* -
  5+ * spdx-license-identifier: bsd-3-clause
  6  *
  7- * Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
  8- * Copyright 2014 Garrett D'Amore <garrett@damore.org>
  9- * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
 10- * Copyright (c) 1989, 1993
 11- *	The Regents of the University of California.  All rights reserved.
 12+ * copyright 2018 staysail systems, inc. <info@staysail.tech>
 13+ * copyright 2014 garrett d'amore <garrett@damore.org>
 14+ * copyright 2010 nexenta systems, inc. all rights reserved
 15+ * copyright (c) 1989, 1993
 16+ * the regents of the university of california. all rights reserved
 17  *
 18- * Redistribution and use in source and binary forms, with or without
 19+ * redistribution and use in source and binary forms, with or without
 20  * modification, are permitted provided that the following conditions
 21  * are met:
 22- * 1. Redistributions of source code must retain the above copyright
 23- *    notice, this list of conditions and the following disclaimer.
 24- * 2. Redistributions in binary form must reproduce the above copyright
 25- *    notice, this list of conditions and the following disclaimer in the
 26- *    documentation and/or other materials provided with the distribution.
 27- * 3. Neither the name of the University nor the names of its contributors
 28- *    may be used to endorse or promote products derived from this software
 29- *    without specific prior written permission.
 30+ * 1. redistributions of source code must retain the above copyright
 31+ * notice, this list of conditions and the following disclaimer
 32+ * 2. redistributions in binary form must reproduce the above copyright
 33+ * notice, this list of conditions and the following disclaimer in the
 34+ * documentation and/or other materials provided with the distribution
 35+ * 3. neither the name of the university nor the names of its contributors
 36+ * may be used to endorse or promote products derived from this software
 37+ * without specific prior written permission
 38  *
 39  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 40  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 41- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 42- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 43+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
 44+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 51- * SUCH DAMAGE.
 52+ * SUCH DAMAGE
 53  */
 54 /*
 55- * Important: This file is used both as a standalone program /usr/bin/printf
 56- * and as a builtin for /bin/sh (#define SHELL).
 57+ * important: this file is used both as a standalone program /usr/bin/printf
 58+ * and as a builtin for /bin/sh (#define SHELL)
 59  */
 60 
 61 #include <sys/types.h>
 62@@ -126,13 +126,13 @@ main(int argc, char *argv[])
 63   INTOFF;
 64 #endif
 65   /*
 66-   * Basic algorithm is to scan the format string for conversion
 67-   * specifications -- once one is found, find out if the field
 68-   * width or precision is a '*'; if it is, gather up value.  Note,
 69-   * format strings are reused as necessary to use up the provided
 70-   * arguments, arguments of zero/null string are provided to use
 71-   * up the format string.
 72-   */
 73+ * basic algorithm is to scan the format string for conversion
 74+ * specifications, once one is found, find out if the field
 75+ * width or precision is a '*'; if it is, gather up value. note,
 76+ * format strings are reused as necessary to use up the provided
 77+ * arguments, arguments of zero/null string are provided to use
 78+ * up the format string
 79+ */
 80   fmt = format = *argv;
 81   escape(fmt, 1, &len); /* backslash interpretation */
 82   rval = end = 0;
 83@@ -184,7 +184,7 @@ main(int argc, char *argv[])
 84 #endif
 85       return (rval);
 86     }
 87-    /* Restart at the beginning of the format string. */
 88+    /* restart at the beginning of the format string */
 89     fmt = format;
 90     end = 1;
 91   }
 92@@ -322,15 +322,15 @@ printf_doformat(char *fmt, int *rval)
 93   *dptr   = 0;
 94 
 95   /*
 96-   * Look for a length modifier.  POSIX doesn't have these, so
 97-   * we only support them for floating-point conversions, which
 98-   * are extensions.  This is useful because the L modifier can
 99-   * be used to gain extra range and precision, while omitting
100-   * it is more likely to produce consistent results on different
101-   * architectures.  This is not so important for integers
102-   * because overflow is the only bad thing that can happen to
103-   * them, but consider the command  printf %a 1.1
104-   */
105+ * look for a length modifier. POSIX doesnt have these, so
106+ * we only support them for floating-point conversions, which
107+ * are extensions. this is useful because the l modifier can
108+ * be used to gain extra range and precision, while omitting
109+ * it is more likely to produce consistent results on different
110+ * architectures. this is not so important for integers
111+ * because overflow is the only bad thing that can happen to
112+ * them, but consider the command printf %a 1.1
113+ */
114   if (*fmt == 'L') {
115     mod_ldbl = 1;
116     fmt++;
117@@ -357,7 +357,7 @@ printf_doformat(char *fmt, int *rval)
118       char  *p;
119       int    getout;
120 
121-      /* Convert "b" to "s" for output. */
122+      /* convert "b" to "s" for output */
123       start[strlen(start) - 1] = 's';
124       if ((p = strdup(getstr())) == NULL) {
125         warnx("%s", strerror(ENOMEM));
126@@ -365,7 +365,7 @@ printf_doformat(char *fmt, int *rval)
127       }
128       getout = escape(p, 0, &len);
129       PF(start, p);
130-      /* Restore format for next loop. */
131+      /* restore format for next loop */
132 
133       free(p);
134       if (getout)
+35, -35
  1@@ -1,35 +1,35 @@
  2-/*-
  3- * SPDX-License-Identifier: BSD-3-Clause
  4+/* -
  5+ * spdx-license-identifier: bsd-3-clause
  6  *
  7- * Copyright (c) 1991, 1993
  8- *	The Regents of the University of California.  All rights reserved.
  9+ * copyright (c) 1991, 1993
 10+ * the regents of the university of california. all rights reserved
 11  *
 12- * This code is derived from software contributed to Berkeley by
 13- * Kenneth Almquist.
 14+ * this code is derived from software contributed to berkeley by
 15+ * kenneth almquist
 16  *
 17- * Redistribution and use in source and binary forms, with or without
 18+ * redistribution and use in source and binary forms, with or without
 19  * modification, are permitted provided that the following conditions
 20  * are met:
 21- * 1. Redistributions of source code must retain the above copyright
 22- *    notice, this list of conditions and the following disclaimer.
 23- * 2. Redistributions in binary form must reproduce the above copyright
 24- *    notice, this list of conditions and the following disclaimer in the
 25- *    documentation and/or other materials provided with the distribution.
 26- * 3. Neither the name of the University nor the names of its contributors
 27- *    may be used to endorse or promote products derived from this software
 28- *    without specific prior written permission.
 29+ * 1. redistributions of source code must retain the above copyright
 30+ * notice, this list of conditions and the following disclaimer
 31+ * 2. redistributions in binary form must reproduce the above copyright
 32+ * notice, this list of conditions and the following disclaimer in the
 33+ * documentation and/or other materials provided with the distribution
 34+ * 3. neither the name of the university nor the names of its contributors
 35+ * may be used to endorse or promote products derived from this software
 36+ * without specific prior written permission
 37  *
 38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
 43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 50- * SUCH DAMAGE.
 51+ * SUCH DAMAGE
 52  */
 53 
 54 #include <errno.h>
 55@@ -42,7 +42,7 @@
 56 #include <unistd.h>
 57 
 58 /*
 59- * Code for dealing with input/output redirection.
 60+ * code for dealing with input/output redirection
 61  */
 62 
 63 #include "error.h"
 64@@ -68,31 +68,31 @@ struct redirtab {
 65 static struct redirtab *redirlist;
 66 
 67 /*
 68- * We keep track of whether or not fd0 has been redirected.  This is for
 69+ * we keep track of whether or not fd0 has been redirected. this is for
 70  * background commands, where we want to redirect fd0 to /dev/null only
 71- * if it hasn't already been redirected.
 72+ * if it hasnt already been redirected
 73  */
 74 static int fd0_redirected = 0;
 75 
 76-/* Number of redirtabs that have not been allocated. */
 77+/* number of redirtabs that have not been allocated */
 78 static unsigned int empty_redirs = 0;
 79 
 80 static void openredirect(union node *, char[10]);
 81 static int  openhere(union node *);
 82 
 83 /*
 84- * Process a list of redirection commands.  If the REDIR_PUSH flag is set,
 85+ * process a list of redirection commands. if the REDIR_PUSH flag is set,
 86  * old file descriptors are stashed away so that the redirection can be
 87- * undone by calling popredir.  If the REDIR_BACKQ flag is set, then the
 88+ * undone by calling popredir. if the REDIR_BACKQ flag is set, then the
 89  * standard output, and the standard error if it becomes a duplicate of
 90- * stdout, is saved in memory.
 91+ * stdout, is saved in memory
 92  *
 93- * We suppress interrupts so that we won't leave open file
 94- * descriptors around.  Because the signal handler remains
 95+ * we suppress interrupts so that we wont leave open file
 96+ * descriptors around. because the signal handler remains
 97  * installed and we do not use system call restart, interrupts
 98  * will still abort blocking opens such as fifos (they will fail
 99- * with EINTR). There is, however, a race condition if an interrupt
100- * arrives after INTOFF and before open blocks.
101+ * with EINTR). there is, however, a race condition if an interrupt
102+ * arrives after INTOFF and before open blocks
103  */
104 
105 void
106@@ -235,9 +235,9 @@ openredirect(union node *redir, char memory[10])
107 }
108 
109 /*
110- * Handle here documents.  Normally we fork off a process to write the
111- * data to a pipe.  If the document is short, we can stuff the data in
112- * the pipe without forking.
113+ * handle here documents. normally we fork off a process to write the
114+ * data to a pipe. if the document is short, we can stuff the data in
115+ * the pipe without forking
116  */
117 
118 static int
119@@ -285,7 +285,7 @@ out:
120 }
121 
122 /*
123- * Undo the effects of the last redirection.
124+ * undo the effects of the last redirection
125  */
126 
127 void
128@@ -317,7 +317,7 @@ popredir(void)
129   INTON;
130 }
131 
132-/* Return true if fd 0 has already been redirected at least once.  */
133+/* return true if fd 0 has already been redirected at least once */
134 int
135 fd0_redirected_p(void)
136 {
137@@ -325,7 +325,7 @@ fd0_redirected_p(void)
138 }
139 
140 /*
141- * Discard all saved file descriptors.
142+ * discard all saved file descriptors
143  */
144 
145 void
+18, -18
 1@@ -1,35 +1,35 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 /* flags passed to redirect */
+9, -9
 1@@ -1,13 +1,13 @@
 2-/*-
 3- * Compat defs for non-BSDs
 4+/* -
 5+ * compat defs for non-bsds
 6  *
 7- *  __unused and __nonstring are intentionally NOT defined here
 8- * They collide with struct field names in some libc's <bits/stat.h>
 9+ * __unused and __nonstring are intentionally NOT defined here
10+ * they collide with struct field names in some libc's <bits/stat.h>
11  * (`long __unused[3]`) and similar system headers when defined as
12- * macros before those headers are included. They remain defined in
13+ * macros before those headers are included. they remain defined in
14  * shell.h, which includes <sys/stat.h> before defining them
15  *
16- * All definitions are guarded with #ifndef so they do not conflict
17+ * all definitions are guarded with #ifndef so they do not conflict
18  * with each other or with system-provided definitions
19  */
20 
21@@ -29,9 +29,9 @@
22 #ifndef _SH_POINTER_TYPEDEF
23 #define _SH_POINTER_TYPEDEF
24 typedef void *pointer; /* used in our memalloc.h and bltin.h
25-                          canonical home is shell.h, but we
26-                          want memalloc to be self-contained
27-                          and not pull all of shell.h */
28+ * canonical home is shell.h, but we
29+ * want memalloc to be self-contained
30+ * and not pull all of shell.h */
31 #endif
32 
33 #endif /* SH_CDEFS_H */
+25, -25
 1@@ -1,35 +1,35 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *      The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 #ifndef SHELL_H_
55@@ -128,20 +128,20 @@
56 #endif
57 
58 /*
59- * The follow should be set to reflect the type of system you have:
60- *      JOBS -> 1 if you have Berkeley job control, 0 otherwise.
61- *      define DEBUG=1 to compile in debugging (set global "debug" to turn on)
62- *      define DEBUG=2 to compile in and turn on debugging.
63+ * the follow should be set to reflect the type of system you have:
64+ * JOBS -> 1 if you have berkeley job control, 0 otherwise
65+ * define DEBUG=1 to compile in debugging (set global "debug" to turn on)
66+ * define DEBUG=2 to compile in and turn on debugging
67  *
68- * When debugging is on, debugging info will be written to ./trace and
69- * a quit signal will generate a core dump.
70+ * when debugging is on, debugging info will be written to ./trace and
71+ * a quit signal will generate a core dump
72  */
73 
74 #define JOBS 1
75 /* #define DEBUG 1 */
76 
77 /*
78- * Type of used arithmetic. SUSv3 requires us to have at least signed long.
79+ * type of used arithmetic. susv3 requires us to have at least signed long
80  */
81 typedef intmax_t arith_t;
82 #define ARITH_FORMAT_STR "%" PRIdMAX
+20, -20
 1@@ -1,35 +1,35 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 #include <errno.h>
55@@ -79,7 +79,7 @@ shtree(union node *n, int ind, char *pfx, FILE *fp)
56       s = " || ";
57     binop:
58       shtree(n->nbinary.ch1, ind, NULL, fp);
59-      /*    if (ind < 0) */
60+      /* if (ind < 0) */
61       fputs(s, fp);
62       shtree(n->nbinary.ch2, ind, NULL, fp);
63       break;
64@@ -283,7 +283,7 @@ indent(int amount, char *pfx, FILE *fp)
65 }
66 
67 /*
68- * Debugging stuff.
69+ * debugging stuff
70  */
71 
72 static FILE *tracefile;
+16, -16
 1@@ -1,32 +1,32 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1995
 8- *      The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1995
10+ * the regents of the university of california. all rights reserved
11  *
12- * Redistribution and use in source and binary forms, with or without
13+ * redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16- * 1. Redistributions of source code must retain the above copyright
17- *    notice, this list of conditions and the following disclaimer.
18- * 2. Redistributions in binary form must reproduce the above copyright
19- *    notice, this list of conditions and the following disclaimer in the
20- *    documentation and/or other materials provided with the distribution.
21- * 3. Neither the name of the University nor the names of its contributors
22- *    may be used to endorse or promote products derived from this software
23- *    without specific prior written permission.
24+ * 1. redistributions of source code must retain the above copyright
25+ * notice, this list of conditions and the following disclaimer
26+ * 2. redistributions in binary form must reproduce the above copyright
27+ * notice, this list of conditions and the following disclaimer in the
28+ * documentation and/or other materials provided with the distribution
29+ * 3. neither the name of the university nor the names of its contributors
30+ * may be used to endorse or promote products derived from this software
31+ * without specific prior written permission
32  *
33  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
34  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
37+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
38+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
39  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45- * SUCH DAMAGE.
46+ * SUCH DAMAGE
47  */
48 
49 #include "sh_cdefs.h"
+28, -28
 1@@ -1,17 +1,17 @@
 2-/*	$NetBSD: test.c,v 1.21 1999/04/05 09:48:38 kleink Exp $	*/
 3-
 4-/*-
 5- * test(1); version 7-like  --  author Erik Baalbergen
 6- * modified by Eric Gisin to be used as built-in.
 7- * modified by Arnold Robbins to add SVR3 compatibility
 8- * (-x -c -b -p -u -g -k) plus Korn's -L -nt -ot -ef and new -S (socket).
 9- * modified by J.T. Conklin for NetBSD.
10+/* $netbsd: test.c,v 1.21 1999/04/05 09:48:38 kleink exp $ */
11+
12+/* -
13+ * test(1); version 7-like, author erik baalbergen
14+ * modified by eric gisin to be used as built-in
15+ * modified by arnold robbins to add SVR3 compatibility
16+ * (-x -c -b -p -u -g -k) plus korn's -L -nt -ot -ef and new -S (socket)
17+ * modified by J.T. conklin for netbsd
18  *
19- * This program is in the Public Domain.
20+ * this program is in the public domain
21  */
22 /*
23- * Important: This file is used both as a standalone program /bin/test and
24- * as a builtin for /bin/sh (#define SHELL).
25+ * important: this file is used both as a standalone program /bin/test and
26+ * as a builtin for /bin/sh (#define SHELL)
27  */
28 
29 #ifndef SHELL
30@@ -68,27 +68,27 @@ error(const char *msg, ...)
31   va_list ap;
32   va_start(ap, msg);
33   verrx(2, msg, ap);
34-  /*NOTREACHED*/
35+  /* NOTREACHED */
36   va_end(ap);
37 }
38 #endif
39 
40 /* test(1) accepts the following grammar:
41-  oexpr	::= aexpr | aexpr "-o" oexpr ;
42-  aexpr	::= nexpr | nexpr "-a" aexpr ;
43-  nexpr	::= primary | "!" primary
44-  primary	::= unary-operator operand
45-    | operand binary-operator operand
46-    | operand
47-    | "(" oexpr ")"
48-    ;
49-  unary-operator ::= "-r"|"-w"|"-x"|"-f"|"-d"|"-c"|"-b"|"-p"|
50-    "-u"|"-g"|"-k"|"-s"|"-t"|"-z"|"-n"|"-o"|"-O"|"-G"|"-L"|"-S";
51-
52-  binary-operator ::= "="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt"|
53-      "-nt"|"-ot"|"-ef";
54-  operand ::= <any legal UNIX file name>
55-*/
56+ * oexpr ::= aexpr | aexpr "-o" oexpr ;
57+ * aexpr ::= nexpr | nexpr "-a" aexpr ;
58+ * nexpr ::= primary | "!" primary
59+ * primary ::= unary-operator operand
60+ * | operand binary-operator operand
61+ * | operand
62+ * | "(" oexpr ")"
63+ * ;
64+ * unary-operator ::= "-r"|"-w"|"-x"|"-f"|"-d"|"-c"|"-b"|"-p"|
65+ * "-u"|"-g"|"-k"|"-s"|"-t"|"-z"|"-n"|"-o"|"-o"|"-g"|"-l"|"-s";
66+ *
67+ * binary-operator ::= "="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt"|
68+ * "-nt"|"-ot"|"-ef";
69+ * operand ::= <any legal UNIX file name>
70+ */
71 
72 enum token_types { UNOP = 0x100, BINOP = 0x200, BUNOP = 0x300, BBINOP = 0x400, PAREN = 0x500 };
73 
74@@ -224,7 +224,7 @@ main(int argc, char **argv)
75   t_wp       = &argv[1];
76   parenlevel = 0;
77   if (nargc == 4 && strcmp(*t_wp, "!") == 0) {
78-    /* Things like ! "" -o x do not fit in the normal grammar. */
79+    /* things like ! "" -o x do not fit in the normal grammar */
80     --nargc;
81     ++t_wp;
82     res = oexpr(t_lex(*t_wp));
+65, -65
  1@@ -1,35 +1,35 @@
  2-/*-
  3- * SPDX-License-Identifier: BSD-3-Clause
  4+/* -
  5+ * spdx-license-identifier: bsd-3-clause
  6  *
  7- * Copyright (c) 1991, 1993
  8- *	The Regents of the University of California.  All rights reserved.
  9+ * copyright (c) 1991, 1993
 10+ * the regents of the university of california. all rights reserved
 11  *
 12- * This code is derived from software contributed to Berkeley by
 13- * Kenneth Almquist.
 14+ * this code is derived from software contributed to berkeley by
 15+ * kenneth almquist
 16  *
 17- * Redistribution and use in source and binary forms, with or without
 18+ * redistribution and use in source and binary forms, with or without
 19  * modification, are permitted provided that the following conditions
 20  * are met:
 21- * 1. Redistributions of source code must retain the above copyright
 22- *    notice, this list of conditions and the following disclaimer.
 23- * 2. Redistributions in binary form must reproduce the above copyright
 24- *    notice, this list of conditions and the following disclaimer in the
 25- *    documentation and/or other materials provided with the distribution.
 26- * 3. Neither the name of the University nor the names of its contributors
 27- *    may be used to endorse or promote products derived from this software
 28- *    without specific prior written permission.
 29+ * 1. redistributions of source code must retain the above copyright
 30+ * notice, this list of conditions and the following disclaimer
 31+ * 2. redistributions in binary form must reproduce the above copyright
 32+ * notice, this list of conditions and the following disclaimer in the
 33+ * documentation and/or other materials provided with the distribution
 34+ * 3. neither the name of the university nor the names of its contributors
 35+ * may be used to endorse or promote products derived from this software
 36+ * without specific prior written permission
 37  *
 38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
 43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 50- * SUCH DAMAGE.
 51+ * SUCH DAMAGE
 52  */
 53 
 54 #include "trap.h"
 55@@ -55,8 +55,8 @@
 56 #include <unistd.h>
 57 
 58 /*
 59- * Sigmode records the current value of the signal handlers for the various
 60- * modes.  A value of zero means that the current handler is not known.
 61+ * sigmode records the current value of the signal handlers for the various
 62+ * modes. a value of zero means that the current handler is not known
 63  * S_HARD_IGN indicates that the signal was ignored on entry to the shell,
 64  */
 65 
 66@@ -73,7 +73,7 @@ static int            in_dotrap;          /* do we execute in a trap handler? */
 67 static char *volatile trap[NSIG];         /* trap handler commands */
 68 static volatile sig_atomic_t gotsig[NSIG];
 69 /* indicates specified signal received */
 70-static int ignore_sigchld; /* Used while handling SIGCHLD traps. */
 71+static int ignore_sigchld; /* used while handling SIGCHLD traps */
 72 static int last_trapsig;
 73 
 74 static int exiting;            /* exitshell() has been called */
 75@@ -82,9 +82,9 @@ static int exiting_exitstatus; /* value passed to exitshell() */
 76 static int getsigaction(int, sig_t *);
 77 
 78 /*
 79- * Map a string to a signal number.
 80+ * map a string to a signal number
 81  *
 82- * Note: the signal number may exceed NSIG.
 83+ * note: the signal number may exceed NSIG
 84  */
 85 static int
 86 sigstring_to_signum(char *sig)
 87@@ -109,7 +109,7 @@ sigstring_to_signum(char *sig)
 88 }
 89 
 90 /*
 91- * Print a list of valid signal names.
 92+ * print a list of valid signal names
 93  */
 94 static void
 95 printsignals(void)
 96@@ -136,7 +136,7 @@ printsignals(void)
 97 }
 98 
 99 /*
100- * The trap builtin.
101+ * the trap builtin
102  */
103 int
104 trapcmd(int argc __unused, char **argv)
105@@ -200,7 +200,7 @@ trapcmd(int argc __unused, char **argv)
106 }
107 
108 /*
109- * Clear traps on a fork.
110+ * clear traps on a fork
111  */
112 void
113 clear_traps(void)
114@@ -220,7 +220,7 @@ clear_traps(void)
115 }
116 
117 /*
118- * Check if we have any traps enabled.
119+ * check if we have any traps enabled
120  */
121 int
122 have_traps(void)
123@@ -235,8 +235,8 @@ have_traps(void)
124 }
125 
126 /*
127- * Set the signal handler for the specified signal.  The routine figures
128- * out what it should be set to.
129+ * set the signal handler for the specified signal. the routine figures
130+ * out what it should be set to
131  */
132 void
133 setsignal(int signo)
134@@ -281,19 +281,19 @@ setsignal(int signo)
135   t = &sigmode[signo];
136   if (*t == 0) {
137     /*
138-     * current setting unknown
139-     */
140+ * current setting unknown
141+ */
142     if (!getsigaction(signo, &sigact)) {
143       /*
144-       * Pretend it worked; maybe we should give a warning
145-       * here, but other shells don't. We don't alter
146-       * sigmode, so that we retry every time.
147-       */
148+ * pretend it worked; maybe we should give a warning
149+ * here, but other shells dont. we dont alter
150+ * sigmode, so that we retry every time
151+ */
152       return;
153     }
154     if (sigact == SIG_IGN) {
155       if (mflag && (signo == SIGTSTP || signo == SIGTTIN || signo == SIGTTOU)) {
156-        *t = S_IGN; /* don't hard ignore these */
157+        *t = S_IGN; /* dont hard ignore these */
158       } else
159         *t = S_HARD_IGN;
160     } else {
161@@ -321,7 +321,7 @@ setsignal(int signo)
162 }
163 
164 /*
165- * Return the current setting for sig w/o changing it.
166+ * return the current setting for sig w/o changing it
167  */
168 static int
169 getsigaction(int signo, sig_t *sigact)
170@@ -335,7 +335,7 @@ getsigaction(int signo, sig_t *sigact)
171 }
172 
173 /*
174- * Ignore a signal.
175+ * ignore a signal
176  */
177 void
178 ignoresig(int signo)
179@@ -355,7 +355,7 @@ issigchldtrapped(void)
180 }
181 
182 /*
183- * Signal handler.
184+ * signal handler
185  */
186 void
187 onsig(int signo)
188@@ -368,7 +368,7 @@ onsig(int signo)
189     return;
190   }
191 
192-  /* If we are currently in a wait builtin, prepare to break it */
193+  /* if we are currently in a wait builtin, prepare to break it */
194   if (signo == SIGINT || signo == SIGQUIT)
195     pendingsig_waitcmd = signo;
196 
197@@ -380,8 +380,8 @@ onsig(int signo)
198 }
199 
200 /*
201- * Called to execute a trap.  Perhaps we should avoid entering new trap
202- * handlers while we are executing a trap handler.
203+ * called to execute a trap. perhaps we should avoid entering new trap
204+ * handlers while we are executing a trap handler
205  */
206 void
207 dotrap(void)
208@@ -399,21 +399,21 @@ dotrap(void)
209         gotsig[i] = 0;
210         if (trap[i]) {
211           /*
212-           * Ignore SIGCHLD to avoid infinite
213-           * recursion if the trap action does
214-           * a fork.
215-           */
216+ * ignore SIGCHLD to avoid infinite
217+ * recursion if the trap action does
218+ * a fork
219+ */
220           if (i == SIGCHLD)
221             ignore_sigchld++;
222 
223           /*
224-           * Backup current evalskip
225-           * state and reset it before
226-           * executing a trap, so that the
227-           * trap is not disturbed by an
228-           * ongoing break/continue/return
229-           * statement.
230-           */
231+ * backup current evalskip
232+ * state and reset it before
233+ * executing a trap, so that the
234+ * trap is not disturbed by an
235+ * ongoing break/continue/return
236+ * statement
237+ */
238           prev_evalskip  = evalskip;
239           prev_skipcount = skipcount;
240           evalskip       = 0;
241@@ -425,12 +425,12 @@ dotrap(void)
242           popstackmark(&smark);
243 
244           /*
245-           * If such a command was not
246-           * already in progress, allow a
247-           * break/continue/return in the
248-           * trap action to have an effect
249-           * outside of it.
250-           */
251+ * if such a command was not
252+ * already in progress, allow a
253+ * break/continue/return in the
254+ * trap action to have an effect
255+ * outside of it
256+ */
257           if (evalskip == 0 || prev_evalskip != 0) {
258             evalskip   = prev_evalskip;
259             skipcount  = prev_skipcount;
260@@ -457,7 +457,7 @@ trap_init(void)
261 }
262 
263 /*
264- * Controls whether the shell is interactive or not based on iflag.
265+ * controls whether the shell is interactive or not based on iflag
266  */
267 void
268 setinteractive(void)
269@@ -466,7 +466,7 @@ setinteractive(void)
270 }
271 
272 /*
273- * Called to exit the shell.
274+ * called to exit the shell
275  */
276 void
277 exitshell(int status)
278@@ -497,9 +497,9 @@ exitshell_savedstatus(void)
279     handler = &loc1;
280     if ((p = trap[0]) != NULL && *p != '\0') {
281       /*
282-       * Reset evalskip, or the trap on EXIT could be
283-       * interrupted if the last command was a "return".
284-       */
285+ * reset evalskip, or the trap on EXIT could be
286+ * interrupted if the last command was a "return"
287+ */
288       evalskip = 0;
289       trap[0]  = NULL;
290       FORCEINTON;
291@@ -523,7 +523,7 @@ exitshell_savedstatus(void)
292     sigaddset(&sigs, sig);
293     sigprocmask(SIG_UNBLOCK, &sigs, NULL);
294     kill(getpid(), sig);
295-    /* If the default action is to ignore, fall back to _exit(). */
296+    /* if the default action is to ignore, fall back to _exit() */
297   }
298   _exit(exiting_exitstatus);
299 }
+18, -18
 1@@ -1,35 +1,35 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *      The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 #include "sh_cdefs.h"
+80, -80
  1@@ -1,35 +1,35 @@
  2-/*-
  3- * SPDX-License-Identifier: BSD-3-Clause
  4+/* -
  5+ * spdx-license-identifier: bsd-3-clause
  6  *
  7- * Copyright (c) 1991, 1993
  8- *	The Regents of the University of California.  All rights reserved.
  9+ * copyright (c) 1991, 1993
 10+ * the regents of the university of california. all rights reserved
 11  *
 12- * This code is derived from software contributed to Berkeley by
 13- * Kenneth Almquist.
 14+ * this code is derived from software contributed to berkeley by
 15+ * kenneth almquist
 16  *
 17- * Redistribution and use in source and binary forms, with or without
 18+ * redistribution and use in source and binary forms, with or without
 19  * modification, are permitted provided that the following conditions
 20  * are met:
 21- * 1. Redistributions of source code must retain the above copyright
 22- *    notice, this list of conditions and the following disclaimer.
 23- * 2. Redistributions in binary form must reproduce the above copyright
 24- *    notice, this list of conditions and the following disclaimer in the
 25- *    documentation and/or other materials provided with the distribution.
 26- * 3. Neither the name of the University nor the names of its contributors
 27- *    may be used to endorse or promote products derived from this software
 28- *    without specific prior written permission.
 29+ * 1. redistributions of source code must retain the above copyright
 30+ * notice, this list of conditions and the following disclaimer
 31+ * 2. redistributions in binary form must reproduce the above copyright
 32+ * notice, this list of conditions and the following disclaimer in the
 33+ * documentation and/or other materials provided with the distribution
 34+ * 3. neither the name of the university nor the names of its contributors
 35+ * may be used to endorse or promote products derived from this software
 36+ * without specific prior written permission
 37  *
 38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
 43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 50- * SUCH DAMAGE.
 51+ * SUCH DAMAGE
 52  */
 53 
 54 #include "var.h"
 55@@ -58,7 +58,7 @@
 56 #include <unistd.h>
 57 
 58 /*
 59- * Shell variables.
 60+ * shell variables
 61  */
 62 
 63 #ifndef VTABSIZE
 64@@ -98,8 +98,8 @@ static const struct varinit varinit[] = {
 65     {&vmpath, VUNSET, "MAILPATH=", NULL},
 66     {&vpath, 0, "PATH=" ARUU_PATH_DEFPATH, changepath},
 67     /*
 68-     * vps1 depends on uid
 69-     */
 70+ * vps1 depends on uid
 71+ */
 72     {&vps2, 0, "PS2=> ", NULL},
 73     {&vps4, 0, "PS4=+ ", NULL},
 74 #ifndef NO_HISTORY
 75@@ -127,8 +127,8 @@ static void        setvareq_const(const char *s, int flags);
 76 extern char **environ;
 77 
 78 /*
 79- * This routine initializes the builtin variables and imports the environment.
 80- * It is called when the shell is initialized.
 81+ * this routine initializes the builtin variables and imports the environment
 82+ * it is called when the shell is initialized
 83  */
 84 
 85 void
 86@@ -150,8 +150,8 @@ initvar(void)
 87     vp->func  = ip->func;
 88   }
 89   /*
 90-   * PS1 depends on uid
 91-   */
 92+ * PS1 depends on uid
 93+ */
 94   if (find_var("PS1", &vpp, &vps1.name_len) == NULL) {
 95     vps1.next  = *vpp;
 96     *vpp       = &vps1;
 97@@ -170,7 +170,7 @@ initvar(void)
 98 }
 99 
100 /*
101- * Safe version of setvar, returns 1 on success 0 on failure.
102+ * safe version of setvar, returns 1 on success 0 on failure
103  */
104 
105 int
106@@ -194,8 +194,8 @@ setvarsafe(const char *name, const char *val, int flags)
107 }
108 
109 /*
110- * Set the value of a variable.  The flags argument is stored with the
111- * flags of the variable.  If val is NULL, the variable is unset.
112+ * set the value of a variable. the flags argument is stored with the
113+ * flags of the variable. if val is NULL, the variable is unset
114  */
115 
116 void
117@@ -264,8 +264,8 @@ localevar(const char *s)
118 }
119 
120 /*
121- * Sets/unsets an environment variable from a pointer that may actually be a
122- * pointer into environ where the string should not be manipulated.
123+ * sets/unsets an environment variable from a pointer that may actually be a
124+ * pointer into environ where the string should not be manipulated
125  */
126 static void
127 change_env(const char *s, int set)
128@@ -288,10 +288,10 @@ change_env(const char *s, int set)
129 }
130 
131 /*
132- * Same as setvar except that the variable and value are passed in
133- * the first argument as name=value.  Since the first argument will
134+ * same as setvar except that the variable and value are passed in
135+ * the first argument as name=value. since the first argument will
136  * be actually stored in the table, it should not be a string that
137- * will go away.
138+ * will go away
139  */
140 
141 void
142@@ -329,13 +329,13 @@ setvareq(char *s, int flags)
143     vp->text = s;
144 
145     /*
146-     * We could roll this to a function, to handle it as
147-     * a regular variable function callback, but why bother?
148-     *
149-     * Note: this assumes iflag is not set to 1 initially.
150-     * As part of initvar(), this is called before arguments
151-     * are looked at.
152-     */
153+ * we could roll this to a function, to handle it as
154+ * a regular variable function callback, but why bother?
155+ *
156+ * note: this assumes iflag is not set to 1 initially
157+ * as part of initvar(), this is called before arguments
158+ * are looked at
159+ */
160     if ((vp == &vmpath || (vp == &vmail && !mpathset())) && iflag == 1)
161       chkmail(1);
162     if ((vp->flags & VEXPORT) && localevar(s)) {
163@@ -375,7 +375,7 @@ setvareq_const(const char *s, int flags)
164 }
165 
166 /*
167- * Process a linked list of variable assignments.
168+ * process a linked list of variable assignments
169  */
170 
171 void
172@@ -390,7 +390,7 @@ listsetvar(struct arglist *list, int flags)
173 }
174 
175 /*
176- * Find the value of a variable.  Returns NULL if not set.
177+ * find the value of a variable. returns NULL if not set
178  */
179 
180 char *
181@@ -405,9 +405,9 @@ lookupvar(const char *name)
182 }
183 
184 /*
185- * Search the environment of a builtin command.  If the second argument
186- * is nonzero, return the value of a variable even if it hasn't been
187- * exported.
188+ * search the environment of a builtin command. if the second argument
189+ * is nonzero, return the value of a variable even if it hasnt been
190+ * exported
191  */
192 
193 char *
194@@ -433,7 +433,7 @@ bltinlookup(const char *name, int doall)
195 }
196 
197 /*
198- * Set up locale for a builtin (LANG/LC_* assignments).
199+ * set up locale for a builtin (LANG/LC_* assignments)
200  */
201 void
202 bltinsetlocale(void)
203@@ -472,7 +472,7 @@ bltinsetlocale(void)
204 }
205 
206 /*
207- * Undo the effect of bltinlocaleset().
208+ * undo the effect of bltinlocaleset()
209  */
210 void
211 bltinunsetlocale(void)
212@@ -492,7 +492,7 @@ bltinunsetlocale(void)
213 }
214 
215 /*
216- * Update the localeisutf8 flag.
217+ * update the localeisutf8 flag
218  */
219 void
220 updatecharset(void)
221@@ -511,8 +511,8 @@ initcharset(void)
222 }
223 
224 /*
225- * Generate a list of exported variables.  This routine is used to construct
226- * the third argument to execve when executing a program.
227+ * generate a list of exported variables. this routine is used to construct
228+ * the third argument to execve when executing a program
229  */
230 
231 char **
232@@ -547,16 +547,16 @@ var_compare(const void *a, const void *b)
233   sa = a;
234   sb = b;
235   /*
236-   * This compares two var=value strings which creates a different
237-   * order from what you would probably expect.  POSIX is somewhat
238-   * ambiguous on what should be sorted exactly.
239-   */
240+ * this compares two var=value strings which creates a different
241+ * order from what you would probably expect. POSIX is somewhat
242+ * ambiguous on what should be sorted exactly
243+ */
244   return strcoll(*sa, *sb);
245 }
246 
247 /*
248- * Command to list all variables which are set.  This is invoked from the
249- * set command when it is called without any options or operands.
250+ * command to list all variables which are set. this is invoked from the
251+ * set command when it is called without any options or operands
252  */
253 
254 int
255@@ -569,8 +569,8 @@ showvarscmd(int argc __unused, char **argv __unused)
256   int          i, n;
257 
258   /*
259-   * POSIX requires us to sort the variables.
260-   */
261+ * POSIX requires us to sort the variables
262+ */
263   n = 0;
264   for (vpp = vartab; vpp < vartab + VTABSIZE; vpp++) {
265     for (vp = *vpp; vp; vp = vp->next) {
266@@ -592,9 +592,9 @@ showvarscmd(int argc __unused, char **argv __unused)
267   qsort(vars, n, sizeof(*vars), var_compare);
268   for (i = 0; i < n; i++) {
269     /*
270-     * Skip improper variable names so the output remains usable as
271-     * shell input.
272-     */
273+ * skip improper variable names so the output remains usable as
274+ * shell input
275+ */
276     if (!isassignment(vars[i]))
277       continue;
278     s = strchr(vars[i], '=');
279@@ -610,7 +610,7 @@ showvarscmd(int argc __unused, char **argv __unused)
280 }
281 
282 /*
283- * The export and readonly commands.
284+ * the export and readonly commands
285  */
286 
287 int
288@@ -661,10 +661,10 @@ exportcmd(int argc __unused, char **argv)
289         if (vp->flags & flag) {
290           if (values) {
291             /*
292-             * Skip improper variable names
293-             * so the output remains usable
294-             * as shell input.
295-             */
296+ * skip improper variable names
297+ * so the output remains usable
298+ * as shell input
299+ */
300             if (!isassignment(vp->text))
301               continue;
302             out1str(cmdname);
303@@ -684,7 +684,7 @@ exportcmd(int argc __unused, char **argv)
304 }
305 
306 /*
307- * The "local" command.
308+ * the "local" command
309  */
310 
311 int
312@@ -702,10 +702,10 @@ localcmd(int argc __unused, char **argv __unused)
313 }
314 
315 /*
316- * Make a variable a local variable.  When a variable is made local, it's
317- * value and flags are saved in a localvar structure.  The saved values
318- * will be restored when the shell function returns.  We handle the name
319- * "-" as a special case.
320+ * make a variable a local variable. when a variable is made local, its
321+ * value and flags are saved in a localvar structure. the saved values
322+ * will be restored when the shell function returns. we handle the name
323+ * "-" as a special case
324  */
325 
326 void
327@@ -746,7 +746,7 @@ mklocal(char *name)
328 }
329 
330 /*
331- * Called after a function returns.
332+ * called after a function returns
333  */
334 
335 void
336@@ -799,7 +799,7 @@ setvarcmd(int argc, char **argv)
337 }
338 
339 /*
340- * The unset builtin command.
341+ * the unset builtin command
342  */
343 
344 int
345@@ -832,8 +832,8 @@ unsetcmd(int argc __unused, char **argv __unused)
346 }
347 
348 /*
349- * Unset the specified variable.
350- * Called with interrupts off.
351+ * unset the specified variable
352+ * called with interrupts off
353  */
354 
355 int
356@@ -866,9 +866,9 @@ unsetvar(const char *s)
357 }
358 
359 /*
360- * Returns true if the two strings specify the same variable.  The first
361+ * returns true if the two strings specify the same variable. the first
362  * variable name is terminated by '='; the second may be terminated by
363- * either '=' or '\0'.
364+ * either '=' or '\0'
365  */
366 
367 static int
368@@ -884,9 +884,9 @@ varequal(const char *p, const char *q)
369 }
370 
371 /*
372- * Search for a variable.
373- * 'name' may be terminated by '=' or a NUL.
374- * vppp is set to the pointer to vp, or the list head if vp isn't found
375+ * search for a variable
376+ * 'name' may be terminated by '=' or a NUL
377+ * vppp is set to the pointer to vp, or the list head if vp isnt found
378  * lenp is set to the number of characters in 'name'
379  */
380 
+25, -25
 1@@ -1,39 +1,39 @@
 2-/*-
 3- * SPDX-License-Identifier: BSD-3-Clause
 4+/* -
 5+ * spdx-license-identifier: bsd-3-clause
 6  *
 7- * Copyright (c) 1991, 1993
 8- *	The Regents of the University of California.  All rights reserved.
 9+ * copyright (c) 1991, 1993
10+ * the regents of the university of california. all rights reserved
11  *
12- * This code is derived from software contributed to Berkeley by
13- * Kenneth Almquist.
14+ * this code is derived from software contributed to berkeley by
15+ * kenneth almquist
16  *
17- * Redistribution and use in source and binary forms, with or without
18+ * redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21- * 1. Redistributions of source code must retain the above copyright
22- *    notice, this list of conditions and the following disclaimer.
23- * 2. Redistributions in binary form must reproduce the above copyright
24- *    notice, this list of conditions and the following disclaimer in the
25- *    documentation and/or other materials provided with the distribution.
26- * 3. Neither the name of the University nor the names of its contributors
27- *    may be used to endorse or promote products derived from this software
28- *    without specific prior written permission.
29+ * 1. redistributions of source code must retain the above copyright
30+ * notice, this list of conditions and the following disclaimer
31+ * 2. redistributions in binary form must reproduce the above copyright
32+ * notice, this list of conditions and the following disclaimer in the
33+ * documentation and/or other materials provided with the distribution
34+ * 3. neither the name of the university nor the names of its contributors
35+ * may be used to endorse or promote products derived from this software
36+ * without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
43+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50- * SUCH DAMAGE.
51+ * SUCH DAMAGE
52  */
53 
54 /*
55- * Shell variables.
56+ * shell variables
57  */
58 
59 /* flags */
60@@ -43,7 +43,7 @@
61 #define VTEXTFIXED 0x08  /* text is statically allocated */
62 #define VSTACK     0x10  /* text is allocated on the stack */
63 #define VUNSET     0x20  /* the variable is not set */
64-#define VNOFUNC    0x40  /* don't call the callback function */
65+#define VNOFUNC    0x40  /* dont call the callback function */
66 #define VNOSET     0x80  /* do not set variable - just readonly test */
67 #define VNOLOCAL   0x100 /* ignore forcelocal */
68 
69@@ -53,7 +53,7 @@ struct var {
70   int         name_len; /* length of name */
71   char       *text;     /* name=value */
72   void (*func)(const char *);
73-  /* function to be called when  */
74+  /* function to be called when */
75   /* the variable gets set/unset */
76 };
77 
78@@ -81,13 +81,13 @@ extern struct var vterm;
79 #endif
80 
81 extern int localeisutf8;
82-/* The parser uses the locale that was in effect at startup. */
83+/* the parser uses the locale that was in effect at startup */
84 extern int initial_localeisutf8;
85 
86 /*
87- * The following macros access the values of the above variables.
88- * They have to skip over the name.  They return the null string
89- * for unset variables.
90+ * the following macros access the values of the above variables
91+ * they have to skip over the name. they return the null string
92+ * for unset variables
93  */
94 
95 #define ifsval()    (vifs.text + 4)
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <unistd.h>
6 
+9, -9
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include "queue.h"
 6 #include "text.h"
 7@@ -212,8 +212,8 @@ slinecmp(struct line *a, struct line *b)
 8     columns(a, kd, &col1);
 9     columns(b, kd, &col2);
10 
11-    /* if -u is given, don't use default key definition
12-     * unless it is the only one */
13+    /* if -u is given, dont use default key definition
14+ * unless it is the only one */
15     if (uflag && kd == TAILQ_LAST(&kdhead, kdhead)
16         && TAILQ_LAST(&kdhead, kdhead) != TAILQ_FIRST(&kdhead)) {
17       res = 0;
18@@ -338,8 +338,8 @@ addkeydef(char *kdstr, int flags)
19   kd = enmalloc(2, sizeof(*kd));
20 
21   /* parse key definition kdstr with format
22-   * start_column[.start_char][flags][,end_column[.end_char][flags]]
23-   */
24+ * start_column[.start_char][flags][,end_column[.end_char][flags]]
25+ */
26   kd->start_column = 1;
27   kd->start_char   = 1;
28   kd->end_column   = 0; /* 0 means end of line */
29@@ -443,10 +443,10 @@ main(int argc, char *argv[])
30     // ?man -m: specify mode or limit
31     case 'm':
32       /* more or less for free, but for performance-reasons,
33-       * we should keep this flag in mind and maybe some later
34-       * day implement it properly so we don't run out of memory
35-       * while merging large sorted files.
36-       */
37+ * we should keep this flag in mind and maybe some later
38+ * day implement it properly so we dont run out of memory
39+ * while merging large sorted files
40+ */
41       break;
42     // ?man -n: print line numbers or counts
43     case 'n':
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <ctype.h>
6 #include <stdint.h>
+5, -5
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <sys/stat.h>
 6 
 7@@ -49,9 +49,9 @@ dropinit(int fd, const char *fname, size_t count)
 8         for (p = buf; count && n > 0; p += nr, n -= nr, count--) {
 9           nr = charntorune(&r, p, n);
10           if (!nr) {
11-            /* we don't have a full rune, move
12-             * remaining data to beginning and read
13-             * again */
14+            /* we dont have a full rune, move
15+ * remaining data to beginning and read
16+ * again */
17             memmove(buf, p, n);
18             break;
19           }
20@@ -109,7 +109,7 @@ taketail(int fd, const char *fname, size_t count)
21         // ?man -n: print line numbers or counts
22       case 'n': /* lines */
23         /* ignore the last character; if it is a newline, it
24-         * ends the last line */
25+ * ends the last line */
26         for (p = buf + len - 2, left = count; p >= buf; p--) {
27           if (*p != '\n')
28             continue;
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <fcntl.h>
6 #include <signal.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/stat.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/times.h>
6 #include <sys/wait.h>
+2, -2
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <sys/stat.h>
 6 
 7@@ -77,7 +77,7 @@ parsetime(char *str)
 8       format = "%Y-%m-%dT%H:%M:%S";
 9       break;
10     case 20:
11-      /* only Zulu-timezone supported */
12+      /* only zulu-timezone supported */
13       if (str[19] != 'Z')
14         eprintf("Invalid time zone\n");
15       str[19] = 0;
+2, -2
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <stdlib.h>
 6 
 7@@ -137,7 +137,7 @@ makeset(char *str, struct range **set, unsigned *checks)
 8         eprintf("Invalid character class.\n");
 9       }
10 
11-      /* REPEAT  [_*n] (only allowed in set2) */
12+      /* REPEAT [_*n] (only allowed in set2) */
13       if (j - i > 2 && rstr[i + 2] == '*') {
14         /* check if right side of '*' is a number */
15         q      = 0;
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 // ?man true: return successful exit status
6 // ?man exit with status 0 representing success
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <ctype.h>
6 #include <stdio.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdio.h>
6 #include <unistd.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/utsname.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdint.h>
6 #include <stdlib.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <ctype.h>
6 #include <stdio.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <unistd.h>
6 
+2, -2
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <sys/stat.h>
 6 
 7@@ -109,7 +109,7 @@ uudecodeb64(FILE *fp, FILE *outfp)
 8         switch (b) {
 9           case 0:
10             /* expected '=' remaining
11-             * including footer */
12+ * including footer */
13             if (--t) {
14               fwrite(out, 1, (po - out), outfp);
15               return;
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/stat.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <string.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdio.h>
6 #include <stdlib.h>
+2, -2
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <sys/wait.h>
 6 
 7@@ -276,7 +276,7 @@ main(int argc, char *argv[])
 8 
 9   if ((argmaxsz = sysconf(_SC_ARG_MAX)) == (size_t)-1)
10     argmaxsz = _POSIX_ARG_MAX;
11-  /* Leave some room for environment variables */
12+  /* leave some room for environment variables */
13   argmaxsz -= 4096;
14   cmd = emalloc(NARGS * sizeof(*cmd));
15 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include "arg.h"
6 #include "util.h"
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <errno.h>
6 #include <stdlib.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdio.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/ioctl.h>
6 
+3, -3
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <sys/types.h>
 6 #include <sys/wait.h>
 7@@ -97,7 +97,7 @@ runjob(char *cmd)
 8 
 9   t = time(NULL);
10 
11-  /* If command is already running, skip it */
12+  /* if command is already running, skip it */
13   TAILQ_FOREACH(je, &jobhead, entry)
14   {
15     if (strcmp(je->cmd, cmd) == 0) {
16@@ -552,7 +552,7 @@ main(int argc, char *argv[])
17       if (nflag == 0)
18         unlink(pidfile);
19       unloadentries();
20-      /* Don't wait or kill forked processes, just exit */
21+      /* dont wait or kill forked processes, just exit */
22       break;
23     }
24 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include "config.h"
5 #include "diffutil.h"
6 #include "util.h"
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdio.h>
6 #include <stdlib.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/stat.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/file.h>
6 #include <sys/wait.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdio.h>
6 #include <stdlib.h>
+3, -3
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <sys/ioctl.h>
 6 #include <sys/stat.h>
 7@@ -96,7 +96,7 @@ main(int argc, char *argv[])
 8   sigemptyset(&sa.sa_mask);
 9   sigaction(SIGHUP, &sa, NULL);
10 
11-  /* Clear all utmp entries for this tty */
12+  /* clear all utmp entries for this tty */
13   fp = fopen(UTMP_PATH, "r+");
14   if (fp) {
15     do {
16@@ -129,7 +129,7 @@ main(int argc, char *argv[])
17   printf("login: ");
18   fflush(stdout);
19 
20-  /* Flush pending input */
21+  /* flush pending input */
22   ioctl(0, TCFLSH, (void *)0);
23   memset(logname, 0, sizeof(logname));
24   while (1) {
+715, -0
  1@@ -0,0 +1,715 @@
  2+/* see LICENSE file for copyright and license details */
  3+
  4+/* deflate decoder adapted from puff.c, mark adlers rfc 1951 reference
  5+ * decoder. zlib license: copyright (c) 2002-2013 mark adler, provided
  6+ * as-is, free to use/alter/redistribute, origin not misrepresented,
  7+ * this notice kept. see zlib.net */
  8+
  9+#include <setjmp.h>
 10+#include <stdint.h>
 11+#include <stdio.h>
 12+#include <stdlib.h>
 13+#include <string.h>
 14+#include <time.h>
 15+#include <unistd.h>
 16+
 17+#include "util.h"
 18+
 19+#define MAXBITS   15
 20+#define MAXLCODES 286
 21+#define MAXDCODES 30
 22+#define MAXCODES  (MAXLCODES + MAXDCODES)
 23+#define FIXLCODES 288
 24+
 25+struct InflateState {
 26+  unsigned char *out;
 27+  unsigned long  outlen;
 28+  unsigned long  outcnt;
 29+
 30+  const unsigned char *in;
 31+  unsigned long         inlen;
 32+  unsigned long         incnt;
 33+  int                   bitbuf;
 34+  int                   bitcnt;
 35+
 36+  jmp_buf env;
 37+};
 38+
 39+struct Huffman {
 40+  short *count;
 41+  short *symbol;
 42+};
 43+
 44+static int
 45+inflate_bits(struct InflateState *s, int need)
 46+{
 47+  long val;
 48+
 49+  val = s->bitbuf;
 50+  while (s->bitcnt < need) {
 51+    if (s->incnt == s->inlen)
 52+      longjmp(s->env, 1);
 53+    val |= (long)(s->in[s->incnt++]) << s->bitcnt;
 54+    s->bitcnt += 8;
 55+  }
 56+
 57+  s->bitbuf = (int)(val >> need);
 58+  s->bitcnt -= need;
 59+
 60+  return (int)(val & ((1L << need) - 1));
 61+}
 62+
 63+static int
 64+inflate_stored(struct InflateState *s)
 65+{
 66+  unsigned len;
 67+
 68+  s->bitbuf = 0;
 69+  s->bitcnt = 0;
 70+
 71+  if (s->incnt + 4 > s->inlen)
 72+    return 2;
 73+  len = s->in[s->incnt++];
 74+  len |= s->in[s->incnt++] << 8;
 75+  if (s->in[s->incnt++] != (~len & 0xff) || s->in[s->incnt++] != ((~len >> 8) & 0xff))
 76+    return -2;
 77+
 78+  if (s->incnt + len > s->inlen)
 79+    return 2;
 80+  if (s->out != NULL) {
 81+    if (s->outcnt + len > s->outlen)
 82+      return 1;
 83+    while (len--)
 84+      s->out[s->outcnt++] = s->in[s->incnt++];
 85+  } else {
 86+    s->outcnt += len;
 87+    s->incnt += len;
 88+  }
 89+
 90+  return 0;
 91+}
 92+
 93+/* codes are bit-reversed on the wire, rebuilt one bit at a time here */
 94+static int
 95+inflate_decode(struct InflateState *s, const struct Huffman *h)
 96+{
 97+  int    len, code, first, count, index;
 98+  int    bitbuf, left;
 99+  short *next;
100+
101+  bitbuf = s->bitbuf;
102+  left   = s->bitcnt;
103+  code = first = index = 0;
104+  len          = 1;
105+  next         = h->count + 1;
106+  for (;;) {
107+    while (left--) {
108+      code |= bitbuf & 1;
109+      bitbuf >>= 1;
110+      count = *next++;
111+      if (code - count < first) {
112+        s->bitbuf = bitbuf;
113+        s->bitcnt = (s->bitcnt - len) & 7;
114+        return h->symbol[index + (code - first)];
115+      }
116+      index += count;
117+      first += count;
118+      first <<= 1;
119+      code <<= 1;
120+      len++;
121+    }
122+    left = (MAXBITS + 1) - len;
123+    if (left == 0)
124+      break;
125+    if (s->incnt == s->inlen)
126+      longjmp(s->env, 1);
127+    bitbuf = s->in[s->incnt++];
128+    if (left > 8)
129+      left = 8;
130+  }
131+  return -10;
132+}
133+
134+/* 0: complete code, > 0: incomplete but usable, < 0: over-subscribed */
135+static int
136+huffman_construct(struct Huffman *h, const short *length, int n)
137+{
138+  int   symbol, len, left;
139+  short offs[MAXBITS + 1];
140+
141+  for (len = 0; len <= MAXBITS; len++)
142+    h->count[len] = 0;
143+  for (symbol = 0; symbol < n; symbol++)
144+    (h->count[length[symbol]])++;
145+  if (h->count[0] == n)
146+    return 0;
147+
148+  left = 1;
149+  for (len = 1; len <= MAXBITS; len++) {
150+    left <<= 1;
151+    left -= h->count[len];
152+    if (left < 0)
153+      return left;
154+  }
155+
156+  offs[1] = 0;
157+  for (len = 1; len < MAXBITS; len++)
158+    offs[len + 1] = offs[len] + h->count[len];
159+
160+  for (symbol = 0; symbol < n; symbol++)
161+    if (length[symbol] != 0)
162+      h->symbol[offs[length[symbol]]++] = symbol;
163+
164+  return left;
165+}
166+
167+static int
168+inflate_codes(struct InflateState *s, const struct Huffman *lencode, const struct Huffman *distcode)
169+{
170+  int            symbol, len;
171+  unsigned       dist;
172+  static const short lens[29] = {3,  4,  5,  6,  7,  8,  9,  10, 11,  13,  15,  17,  19,
173+                                  23, 27, 31, 35, 43, 51, 59, 67, 83,  99,  115, 131,
174+                                  163, 195, 227, 258};
175+  static const short lext[29] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2,
176+                                  2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
177+  static const short dists[30] = {1,    2,    3,    4,    5,    7,    9,    13,   17,    25,
178+                                   33,   49,   65,   97,   129,  193,  257,  385,  513,   769,
179+                                   1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
180+  static const short dext[30] = {0, 0, 0, 0, 1, 1, 2, 2, 3,  3,  4,  4,  5,  5,  6,
181+                                  6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
182+
183+  do {
184+    symbol = inflate_decode(s, lencode);
185+    if (symbol < 0)
186+      return symbol;
187+    if (symbol < 256) {
188+      if (s->out != NULL) {
189+        if (s->outcnt == s->outlen)
190+          return 1;
191+        s->out[s->outcnt] = symbol;
192+      }
193+      s->outcnt++;
194+    } else if (symbol > 256) {
195+      symbol -= 257;
196+      if (symbol >= 29)
197+        return -10;
198+      len = lens[symbol] + inflate_bits(s, lext[symbol]);
199+
200+      symbol = inflate_decode(s, distcode);
201+      if (symbol < 0)
202+        return symbol;
203+      dist = dists[symbol] + inflate_bits(s, dext[symbol]);
204+      if (dist > s->outcnt)
205+        return -11;
206+
207+      if (s->out != NULL) {
208+        if (s->outcnt + len > s->outlen)
209+          return 1;
210+        while (len--) {
211+          s->out[s->outcnt] = s->out[s->outcnt - dist];
212+          s->outcnt++;
213+        }
214+      } else {
215+        s->outcnt += len;
216+      }
217+    }
218+  } while (symbol != 256);
219+
220+  return 0;
221+}
222+
223+static int
224+inflate_fixed(struct InflateState *s)
225+{
226+  static int          built;
227+  static short        lencnt[MAXBITS + 1], lensym[FIXLCODES];
228+  static short        distcnt[MAXBITS + 1], distsym[MAXDCODES];
229+  static struct Huffman lencode, distcode;
230+
231+  if (!built) {
232+    int   symbol;
233+    short lengths[FIXLCODES];
234+
235+    lencode.count  = lencnt;
236+    lencode.symbol = lensym;
237+    distcode.count  = distcnt;
238+    distcode.symbol = distsym;
239+
240+    for (symbol = 0; symbol < 144; symbol++)
241+      lengths[symbol] = 8;
242+    for (; symbol < 256; symbol++)
243+      lengths[symbol] = 9;
244+    for (; symbol < 280; symbol++)
245+      lengths[symbol] = 7;
246+    for (; symbol < FIXLCODES; symbol++)
247+      lengths[symbol] = 8;
248+    huffman_construct(&lencode, lengths, FIXLCODES);
249+
250+    for (symbol = 0; symbol < MAXDCODES; symbol++)
251+      lengths[symbol] = 5;
252+    huffman_construct(&distcode, lengths, MAXDCODES);
253+
254+    built = 1;
255+  }
256+
257+  return inflate_codes(s, &lencode, &distcode);
258+}
259+
260+static int
261+inflate_dynamic(struct InflateState *s)
262+{
263+  int            nlen, ndist, ncode, index, err;
264+  short          lengths[MAXCODES];
265+  short          lencnt[MAXBITS + 1], lensym[MAXLCODES];
266+  short          distcnt[MAXBITS + 1], distsym[MAXDCODES];
267+  struct Huffman lencode, distcode;
268+  static const short order[19] = {16, 17, 18, 0, 8,  7, 9,  6, 10, 5,
269+                                   11, 4,  12, 3, 13, 2, 14, 1, 15};
270+
271+  lencode.count  = lencnt;
272+  lencode.symbol = lensym;
273+  distcode.count  = distcnt;
274+  distcode.symbol = distsym;
275+
276+  nlen  = inflate_bits(s, 5) + 257;
277+  ndist = inflate_bits(s, 5) + 1;
278+  ncode = inflate_bits(s, 4) + 4;
279+  if (nlen > MAXLCODES || ndist > MAXDCODES)
280+    return -3;
281+
282+  for (index = 0; index < ncode; index++)
283+    lengths[order[index]] = inflate_bits(s, 3);
284+  for (; index < 19; index++)
285+    lengths[order[index]] = 0;
286+
287+  err = huffman_construct(&lencode, lengths, 19);
288+  if (err != 0)
289+    return -4;
290+
291+  index = 0;
292+  while (index < nlen + ndist) {
293+    int symbol, len;
294+
295+    symbol = inflate_decode(s, &lencode);
296+    if (symbol < 0)
297+      return symbol;
298+    if (symbol < 16) {
299+      lengths[index++] = symbol;
300+    } else {
301+      len = 0;
302+      if (symbol == 16) {
303+        if (index == 0)
304+          return -5;
305+        len    = lengths[index - 1];
306+        symbol = 3 + inflate_bits(s, 2);
307+      } else if (symbol == 17) {
308+        symbol = 3 + inflate_bits(s, 3);
309+      } else {
310+        symbol = 11 + inflate_bits(s, 7);
311+      }
312+      if (index + symbol > nlen + ndist)
313+        return -6;
314+      while (symbol--)
315+        lengths[index++] = len;
316+    }
317+  }
318+
319+  if (lengths[256] == 0)
320+    return -9;
321+
322+  err = huffman_construct(&lencode, lengths, nlen);
323+  if (err && (err < 0 || nlen != lencode.count[0] + lencode.count[1]))
324+    return -7;
325+
326+  err = huffman_construct(&distcode, lengths + nlen, ndist);
327+  if (err && (err < 0 || ndist != distcode.count[0] + distcode.count[1]))
328+    return -8;
329+
330+  return inflate_codes(s, &lencode, &distcode);
331+}
332+
333+/* raw deflate (rfc 1951) decoder; dest null just computes destlen */
334+static int
335+inflate_raw(unsigned char *dest, unsigned long *destlen, const unsigned char *source,
336+            unsigned long *sourcelen)
337+{
338+  struct InflateState s;
339+  int                 last, type, err;
340+
341+  s.out    = dest;
342+  s.outlen = *destlen;
343+  s.outcnt = 0;
344+
345+  s.in     = source;
346+  s.inlen  = *sourcelen;
347+  s.incnt  = 0;
348+  s.bitbuf = 0;
349+  s.bitcnt = 0;
350+
351+  if (setjmp(s.env) != 0) {
352+    err = 2;
353+  } else {
354+    do {
355+      last = inflate_bits(&s, 1);
356+      type = inflate_bits(&s, 2);
357+      err  = type == 0   ? inflate_stored(&s)
358+             : type == 1 ? inflate_fixed(&s)
359+             : type == 2 ? inflate_dynamic(&s)
360+                          : -1;
361+      if (err != 0)
362+        break;
363+    } while (!last);
364+  }
365+
366+  if (err <= 0) {
367+    *destlen   = s.outcnt;
368+    *sourcelen = s.incnt;
369+  }
370+  return err;
371+}
372+
373+static uint32_t crc32_table[256];
374+
375+static void
376+crc32_init(void)
377+{
378+  uint32_t c;
379+  int      n, k;
380+
381+  for (n = 0; n < 256; n++) {
382+    c = (uint32_t)n;
383+    for (k = 0; k < 8; k++)
384+      c = (c & 1) ? (0xedb88320u ^ (c >> 1)) : (c >> 1);
385+    crc32_table[n] = c;
386+  }
387+}
388+
389+static uint32_t
390+crc32_update(uint32_t crc, const unsigned char *buf, size_t len)
391+{
392+  crc = ~crc;
393+  while (len--)
394+    crc = crc32_table[(crc ^ *buf++) & 0xff] ^ (crc >> 8);
395+  return ~crc;
396+}
397+
398+static uint32_t
399+get_le32(const unsigned char *p)
400+{
401+  return (uint32_t)p[0] | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24);
402+}
403+
404+static void
405+put_le32(unsigned char *p, uint32_t v)
406+{
407+  p[0] = v & 0xff;
408+  p[1] = (v >> 8) & 0xff;
409+  p[2] = (v >> 16) & 0xff;
410+  p[3] = (v >> 24) & 0xff;
411+}
412+
413+/* FLG bits in the gzip header (rfc 1952) */
414+enum GzipFlag {
415+  GZ_FTEXT    = 1 << 0,
416+  GZ_FHCRC    = 1 << 1,
417+  GZ_FEXTRA   = 1 << 2,
418+  GZ_FNAME    = 1 << 3,
419+  GZ_FCOMMENT = 1 << 4,
420+};
421+
422+static unsigned char *
423+read_all(FILE *fp, size_t *len)
424+{
425+  unsigned char *buf;
426+  size_t         cap, n;
427+  ssize_t        r;
428+
429+  cap = 1 << 16;
430+  buf = emalloc(cap);
431+  n   = 0;
432+  for (;;) {
433+    if (n == cap) {
434+      cap *= 2;
435+      buf = erealloc(buf, cap);
436+    }
437+    r = fread(buf + n, 1, cap - n, fp);
438+    if (r <= 0)
439+      break;
440+    n += (size_t)r;
441+  }
442+  if (ferror(fp))
443+    eprintf("read:");
444+  *len = n;
445+  return buf;
446+}
447+
448+/* decodes one gzip member; multi-member streams are not supported */
449+static void
450+gunzip(const unsigned char *in, size_t inlen, FILE *out)
451+{
452+  size_t   pos, hdr;
453+  unsigned flg;
454+  unsigned char *dest;
455+  unsigned long  destlen, srclen;
456+  uint32_t       want_crc, want_isize, got_crc;
457+  int            err;
458+
459+  if (inlen < 18 || in[0] != 0x1f || in[1] != 0x8b)
460+    eprintf("gzip: not in gzip format\n");
461+  if (in[2] != 8)
462+    eprintf("gzip: unsupported compression method\n");
463+
464+  flg = in[3];
465+  pos = 10;
466+
467+  if (flg & GZ_FEXTRA) {
468+    unsigned xlen;
469+    if (pos + 2 > inlen)
470+      eprintf("gzip: truncated header\n");
471+    xlen = in[pos] | (in[pos + 1] << 8);
472+    pos += 2 + xlen;
473+  }
474+  if (flg & GZ_FNAME) {
475+    while (pos < inlen && in[pos] != '\0')
476+      pos++;
477+    pos++;
478+  }
479+  if (flg & GZ_FCOMMENT) {
480+    while (pos < inlen && in[pos] != '\0')
481+      pos++;
482+    pos++;
483+  }
484+  if (flg & GZ_FHCRC)
485+    pos += 2;
486+  if (pos + 8 > inlen)
487+    eprintf("gzip: truncated header\n");
488+
489+  hdr = pos;
490+
491+  /* first pass just measures destlen, second pass does the real decode */
492+  destlen = 0;
493+  srclen  = (unsigned long)(inlen - hdr - 8);
494+  err     = inflate_raw(NULL, &destlen, in + hdr, &srclen);
495+  if (err != 0)
496+    eprintf("gzip: corrupt compressed data\n");
497+
498+  dest    = emalloc(destlen ? destlen : 1);
499+  srclen  = (unsigned long)(inlen - hdr - 8);
500+  destlen = destlen ? destlen : 1;
501+  err     = inflate_raw(dest, &destlen, in + hdr, &srclen);
502+  if (err != 0)
503+    eprintf("gzip: corrupt compressed data\n");
504+
505+  want_crc   = get_le32(in + hdr + srclen);
506+  want_isize = get_le32(in + hdr + srclen + 4);
507+  got_crc    = crc32_update(0, dest, destlen);
508+  if (got_crc != want_crc)
509+    eprintf("gzip: crc mismatch\n");
510+  if ((uint32_t)destlen != want_isize)
511+    eprintf("gzip: size mismatch\n");
512+
513+  if (fwrite(dest, 1, destlen, out) != destlen)
514+    eprintf("write:");
515+  free(dest);
516+}
517+
518+/* stored (uncompressed) deflate blocks: no compression, always valid */
519+static void
520+gzip_write_stored(const unsigned char *in, size_t len, FILE *out)
521+{
522+  unsigned char hdr[5];
523+  size_t        chunk;
524+  int           last;
525+
526+  if (len == 0) {
527+    hdr[0] = 1;
528+    hdr[1] = hdr[2] = hdr[3] = hdr[4] = 0;
529+    if (fwrite(hdr, 1, 5, out) != 5)
530+      eprintf("write:");
531+    return;
532+  }
533+
534+  while (len > 0) {
535+    chunk = len > 65535 ? 65535 : len;
536+    last  = chunk == len;
537+
538+    hdr[0] = last ? 1 : 0;
539+    hdr[1] = chunk & 0xff;
540+    hdr[2] = (chunk >> 8) & 0xff;
541+    hdr[3] = (~chunk) & 0xff;
542+    hdr[4] = ((~chunk) >> 8) & 0xff;
543+
544+    if (fwrite(hdr, 1, 5, out) != 5 || fwrite(in, 1, chunk, out) != chunk)
545+      eprintf("write:");
546+
547+    in += chunk;
548+    len -= chunk;
549+  }
550+}
551+
552+static void
553+gzip_compress(const unsigned char *in, size_t len, const char *name, FILE *out)
554+{
555+  unsigned char hdr[10];
556+  unsigned char trl[8];
557+  uint32_t      crc;
558+
559+  hdr[0] = 0x1f;
560+  hdr[1] = 0x8b;
561+  hdr[2] = 8;
562+  hdr[3] = name ? GZ_FNAME : 0;
563+  put_le32(hdr + 4, 0);
564+  hdr[8] = 0;
565+  hdr[9] = 255;
566+  if (fwrite(hdr, 1, 10, out) != 10)
567+    eprintf("write:");
568+  if (name && (fwrite(name, 1, strlen(name) + 1, out) != strlen(name) + 1))
569+    eprintf("write:");
570+
571+  gzip_write_stored(in, len, out);
572+
573+  crc = crc32_update(0, in, len);
574+  put_le32(trl, crc);
575+  put_le32(trl + 4, (uint32_t)len);
576+  if (fwrite(trl, 1, 8, out) != 8)
577+    eprintf("write:");
578+}
579+
580+static char *
581+strip_gz_suffix(const char *name)
582+{
583+  size_t n = strlen(name);
584+  if (n > 3 && strcmp(name + n - 3, ".gz") == 0)
585+    return estrndup(name, n - 3);
586+  return NULL;
587+}
588+
589+static void
590+usage(void)
591+{
592+  eprintf("usage: %s [-cdfkn] [-1..-9] [file ...]\n", argv0);
593+}
594+
595+// ?man gzip: compress or decompress files
596+// ?man arguments: [file ...]
597+// ?man with no files, reads standard input and writes standard output
598+// ?man compressing replaces each file with file.gz; decompressing
599+// ?man reverses that. only single-member gzip streams are read back
600+int
601+main(int argc, char *argv[])
602+{
603+  int  dflag = 0, cflag = 0, fflag = 0, kflag = 0, nflag = 0;
604+  int  i;
605+  char outname[4096];
606+
607+  ARGBEGIN
608+  {
609+    // ?man -c: write to standard output, keep the input file
610+    case 'c':
611+      cflag = 1;
612+      break;
613+    // ?man -d: decompress instead of compress
614+    case 'd':
615+      dflag = 1;
616+      break;
617+    // ?man -f: accepted for compatibility, no effect
618+    case 'f':
619+      fflag = 1;
620+      break;
621+    // ?man -k: keep the input file instead of removing it
622+    case 'k':
623+      kflag = 1;
624+      break;
625+    // ?man -n: omit the original file name from the header
626+    case 'n':
627+      nflag = 1;
628+      break;
629+    // ?man -1: accepted for compatibility, no effect (stored blocks only)
630+    case '1':
631+    case '2':
632+    case '3':
633+    case '4':
634+    case '5':
635+    case '6':
636+    case '7':
637+    case '8':
638+    case '9':
639+      break;
640+    default:
641+      usage();
642+  }
643+  ARGEND
644+
645+  (void)fflag;
646+  crc32_init();
647+
648+  if (argc == 0) {
649+    unsigned char *buf;
650+    size_t         len;
651+
652+    buf = read_all(stdin, &len);
653+    if (dflag)
654+      gunzip(buf, len, stdout);
655+    else
656+      gzip_compress(buf, len, NULL, stdout);
657+    free(buf);
658+    return 0;
659+  }
660+
661+  for (i = 0; i < argc; i++) {
662+    FILE          *fp;
663+    unsigned char *buf;
664+    size_t         len;
665+    char          *stripped;
666+
667+    fp = fopen(argv[i], "rb");
668+    if (!fp) {
669+      weprintf("open %s:", argv[i]);
670+      continue;
671+    }
672+    buf = read_all(fp, &len);
673+    fclose(fp);
674+
675+    if (dflag) {
676+      if (cflag) {
677+        gunzip(buf, len, stdout);
678+      } else {
679+        stripped = strip_gz_suffix(argv[i]);
680+        if (!stripped)
681+          eprintf("gzip: %s: unknown suffix, ignored\n", argv[i]);
682+        strlcpy(outname, stripped, sizeof(outname));
683+        free(stripped);
684+
685+        fp = fopen(outname, "wb");
686+        if (!fp)
687+          eprintf("open %s:", outname);
688+        gunzip(buf, len, fp);
689+        if (fclose(fp))
690+          eprintf("close %s:", outname);
691+        if (!kflag && unlink(argv[i]) < 0)
692+          weprintf("unlink %s:", argv[i]);
693+      }
694+    } else {
695+      if (cflag) {
696+        gzip_compress(buf, len, NULL, stdout);
697+      } else {
698+        strlcpy(outname, argv[i], sizeof(outname));
699+        strlcat(outname, ".gz", sizeof(outname));
700+
701+        fp = fopen(outname, "wb");
702+        if (!fp)
703+          eprintf("open %s:", outname);
704+        gzip_compress(buf, len, nflag ? NULL : argv[i], fp);
705+        if (fclose(fp))
706+          eprintf("close %s:", outname);
707+        if (!kflag && unlink(argv[i]) < 0)
708+          weprintf("unlink %s:", argv[i]);
709+      }
710+    }
711+
712+    free(buf);
713+  }
714+
715+  return 0;
716+}
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/syscall.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdio.h>
6 #include <string.h>
R cmd/pseudo/xinstall.c => cmd/pseudo/install.c
+2, -2
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <dirent.h>
 6 #include <errno.h>
 7@@ -87,7 +87,7 @@ usage(void)
 8   );
 9 }
10 
11-// ?man xinstall: copy files and set attributes
12+// ?man install: copy files and set attributes
13 // ?man arguments: (-d dir ... | (-t dest source ... | source ... dest))
14 // ?man copy files and set their permissions and ownership
15 int
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <dirent.h>
6 #include <limits.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <errno.h>
6 #include <libgen.h>
+2, -2
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <errno.h>
 6 #include <pwd.h>
 7@@ -39,7 +39,7 @@ lastlog(char *user)
 8     eprintf("%s: read error:", ARUU_PATH_LASTLOG);
 9 
10   /* on glibc `ll_time' can be an int32_t with compat32
11-   * avoid compiler warning when calling ctime() */
12+ * avoid compiler warning when calling ctime() */
13   lltime = ll.ll_time;
14   printf("%-8.8s %-8.8s %-16.16s %s", user, ll.ll_line, ll.ll_host, ctime(&lltime));
15 }
+0, -138
  1@@ -1,138 +0,0 @@
  2-/* See LICENSE file for copyright and license details. */
  3-
  4-#include <sys/ioctl.h>
  5-#include <sys/types.h>
  6-
  7-#include <errno.h>
  8-#include <grp.h>
  9-#include <pwd.h>
 10-#include <stdio.h>
 11-#include <stdlib.h>
 12-#include <string.h>
 13-#include <time.h>
 14-#include <unistd.h>
 15-#include <utmp.h>
 16-
 17-#include "config.h"
 18-#include "passwd.h"
 19-#include "util.h"
 20-#include "wexec.h"
 21-
 22-/* Write utmp entry */
 23-static void
 24-writeutmp(const char *user, const char *tty)
 25-{
 26-  struct utmp usr;
 27-  FILE       *fp;
 28-
 29-  memset(&usr, 0, sizeof(usr));
 30-
 31-  usr.ut_type = USER_PROCESS;
 32-  usr.ut_pid  = getpid();
 33-  strlcpy(usr.ut_user, user, sizeof(usr.ut_user));
 34-  strlcpy(usr.ut_line, tty, sizeof(usr.ut_line));
 35-  usr.ut_tv.tv_sec = time(NULL);
 36-
 37-  fp = fopen(UTMP_PATH, "a");
 38-  if (fp) {
 39-    if (fwrite(&usr, sizeof(usr), 1, fp) != 1)
 40-      if (ferror(fp))
 41-        weprintf("%s: write error:", UTMP_PATH);
 42-    fclose(fp);
 43-  } else {
 44-    weprintf("fopen %s:", UTMP_PATH);
 45-  }
 46-}
 47-
 48-static int
 49-dologin(struct passwd *pw, int preserve)
 50-{
 51-  char *shell = pw->pw_shell[0] == '\0' ? "/bin/sh" : pw->pw_shell;
 52-
 53-  if (preserve == 0)
 54-    clearenv();
 55-  setenv("HOME", pw->pw_dir, 1);
 56-  setenv("SHELL", shell, 1);
 57-  setenv("USER", pw->pw_name, 1);
 58-  setenv("LOGNAME", pw->pw_name, 1);
 59-  setenv("PATH", ENV_PATH, 1);
 60-  if (chdir(pw->pw_dir) < 0)
 61-    eprintf("chdir %s:", pw->pw_dir);
 62-  wexecvp_self(shell, (char *const[]){shell, "-l", NULL});
 63-  weprintf("wexecvp %s:", shell);
 64-  return (errno == ENOENT) ? 127 : 126;
 65-}
 66-
 67-static void
 68-usage(void)
 69-{
 70-  eprintf("usage: %s [-p] username\n", argv0);
 71-}
 72-
 73-// ?man login: begin terminal session
 74-// ?man arguments: username
 75-// ?man authenticate and start a session on the system
 76-int
 77-main(int argc, char *argv[])
 78-{
 79-  struct passwd *pw;
 80-  char          *pass, *user;
 81-  char          *tty;
 82-  uid_t          uid;
 83-  gid_t          gid;
 84-  int            pflag = 0;
 85-
 86-  ARGBEGIN
 87-  {
 88-    // ?man -p: preserve file attributes
 89-    case 'p':
 90-      pflag = 1;
 91-      break;
 92-    default:
 93-      usage();
 94-  }
 95-  ARGEND;
 96-
 97-  if (argc < 1)
 98-    usage();
 99-
100-  if (isatty(0) == 0 || isatty(1) == 0 || isatty(2) == 0)
101-    eprintf("no tty");
102-
103-  user  = argv[0];
104-  errno = 0;
105-  pw    = getpwnam(user);
106-  if (!pw) {
107-    if (errno)
108-      eprintf("getpwnam %s:", user);
109-    else
110-      eprintf("who are you?\n");
111-  }
112-
113-  uid = pw->pw_uid;
114-  gid = pw->pw_gid;
115-
116-  /* Flush pending input */
117-  ioctl(0, TCFLSH, (void *)0);
118-
119-  pass = getpass("Password: ");
120-  if (!pass)
121-    eprintf("getpass:");
122-  if (pw_check(pw, pass) <= 0)
123-    exit(1);
124-
125-  tty = ttyname(0);
126-  if (!tty)
127-    eprintf("ttyname:");
128-
129-  writeutmp(user, tty);
130-
131-  if (initgroups(user, gid) < 0)
132-    eprintf("initgroups:");
133-  if (setgid(gid) < 0)
134-    eprintf("setgid:");
135-  if (setuid(uid) < 0)
136-    eprintf("setuid:");
137-
138-  return dologin(pw, pflag);
139-}
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdint.h>
6 #include <stdio.h>
+0, -138
  1@@ -1,138 +0,0 @@
  2-/* See LICENSE file for copyright and license details. */
  3-#include "passwd.h"
  4-#include "paths.h"
  5-#include "util.h"
  6-
  7-#include <ctype.h>
  8-#include <stdio.h>
  9-#include <stdlib.h>
 10-#include <string.h>
 11-#include <unistd.h>
 12-
 13-static void
 14-usage(void)
 15-{
 16-  eprintf("usage: %s [-P fd] [-m type] [-S salt] [password] [salt]\n", argv0);
 17-}
 18-
 19-// ?man mkpasswd: encrypt the given password using salt
 20-// ?man arguments: [password] [salt]
 21-// ?man encrypt password using crypt(3) with random or provided salt
 22-int
 23-main(int argc, char *argv[])
 24-{
 25-  char *mflag, *sflag, *parg, *password, *cryptpass;
 26-  char *prefix;
 27-  char  salt[128];
 28-  char  passbuf[1024];
 29-  int   pfd, len;
 30-
 31-  mflag     = NULL;
 32-  sflag     = NULL;
 33-  parg      = NULL;
 34-  password  = NULL;
 35-  cryptpass = NULL;
 36-  pfd       = -1;
 37-  len       = 2;
 38-  prefix    = NULL;
 39-
 40-  ARGBEGIN
 41-  {
 42-    case 'P':
 43-      // ?man -P:fd: read password from file descriptor
 44-      parg = EARGF(usage());
 45-      pfd  = estrtonum(parg, 0, INT_MAX);
 46-      break;
 47-    case 'm':
 48-      // ?man -m:type: encryption method (des, md5, sha256, sha512)
 49-      mflag = EARGF(usage());
 50-      break;
 51-    case 'S':
 52-      // ?man -S:salt: salt to use
 53-      sflag = EARGF(usage());
 54-      break;
 55-    default:
 56-      usage();
 57-  }
 58-  ARGEND
 59-
 60-  if (argc > 2)
 61-    usage();
 62-
 63-  if (argc == 2) {
 64-    if (sflag)
 65-      eprintf("duplicate salt\n");
 66-    sflag = argv[1];
 67-  }
 68-
 69-  if (argc >= 1)
 70-    password = argv[0];
 71-
 72-  if (!mflag)
 73-    mflag = "des";
 74-
 75-  if (strcasecmp(mflag, "des") == 0) {
 76-    len    = 2;
 77-    prefix = NULL;
 78-  } else if (strcasecmp(mflag, "md5") == 0) {
 79-    len    = 8;
 80-    prefix = "$1$";
 81-  } else if (strcasecmp(mflag, "sha256") == 0) {
 82-    len    = 16;
 83-    prefix = "$5$";
 84-  } else if (strcasecmp(mflag, "sha512") == 0) {
 85-    len    = 16;
 86-    prefix = "$6$";
 87-  } else {
 88-    eprintf("bad method: %s\n", mflag);
 89-  }
 90-
 91-  if (sflag) {
 92-    char *s = sflag;
 93-    while (*s) {
 94-      if (!isalnum((unsigned char)*s) && *s != '.' && *s != '/')
 95-        eprintf("bad SALT (need [a-zA-Z0-9./])\n");
 96-      s++;
 97-    }
 98-    if (prefix)
 99-      snprintf(salt, sizeof(salt), "%s%s", prefix, sflag);
100-    else
101-      estrlcpy(salt, sflag, sizeof(salt));
102-  } else {
103-    if (pw_gensalt_cipher(salt, sizeof(salt), prefix, len) < 0)
104-      eprintf("pw_gensalt_cipher:");
105-  }
106-
107-  if (pfd >= 0) {
108-    if (dup2(pfd, 0) == -1)
109-      eprintf("dup2:");
110-    close(pfd);
111-  }
112-
113-  if (!password) {
114-    if (isatty(0)) {
115-      char *p = getpass("Password: ");
116-      if (!p)
117-        eprintf("getpass failed\n");
118-      estrlcpy(passbuf, p, sizeof(passbuf));
119-      password = passbuf;
120-    } else {
121-      int bytes = read(0, passbuf, sizeof(passbuf) - 1);
122-      if (bytes < 0)
123-        eprintf("read stdin:");
124-      while (bytes > 0 && (passbuf[bytes - 1] == '\n' || passbuf[bytes - 1] == '\r'))
125-        bytes--;
126-      passbuf[bytes] = '\0';
127-      password       = passbuf;
128-    }
129-  }
130-
131-  cryptpass = crypt(password, salt);
132-  if (!cryptpass)
133-    eprintf("crypt:");
134-  printf("%s\n", cryptpass);
135-
136-  if (fshut(stdout, "<stdout>"))
137-    return 2;
138-  return 0;
139-}
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <libgen.h>
6 #include <stdio.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <fcntl.h>
6 #include <stdio.h>
+41, -0
 1@@ -0,0 +1,41 @@
 2+/* see LICENSE file for copyright and license details */
 3+
 4+#include <stdio.h>
 5+#include <stdlib.h>
 6+#include <unistd.h>
 7+
 8+#include "util.h"
 9+
10+static void
11+usage(void)
12+{
13+  eprintf("usage: %s [-a]\n", argv0);
14+}
15+
16+// ?man nproc: print the number of available processors
17+// ?man arguments: [-a]
18+// ?man with no options, prints the number of processors currently
19+// ?man online. -a prints the number installed, including any offline
20+int
21+main(int argc, char *argv[])
22+{
23+  int  aflag = 0;
24+  long n;
25+
26+  ARGBEGIN
27+  {
28+    // ?man -a: count installed processors, not just online ones
29+    case 'a':
30+      aflag = 1;
31+      break;
32+    default:
33+      usage();
34+  }
35+  ARGEND;
36+
37+  n = sysconf(aflag ? _SC_NPROCESSORS_CONF : _SC_NPROCESSORS_ONLN);
38+  if (n <= 0)
39+    n = 1;
40+  printf("%ld\n", n);
41+  return 0;
42+}
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdio.h>
6 #include <stdlib.h>
+2, -2
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 
 5 #include <sys/types.h>
 6 
 7@@ -99,7 +99,7 @@ main(int argc, char *argv[])
 8       cmd     = cmdline;
 9       cmdbase = basename(cmdline);
10     }
11-    /* Workaround for login shells */
12+    /* workaround for login shells */
13     if (cmd[0] == '-')
14       cmd++;
15     for (i = 0; i < argc; i++) {
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdio.h>
6 #include <stdlib.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <errno.h>
6 #include <limits.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/stat.h>
6 #include <sys/time.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdio.h>
6 #include <string.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdio.h>
6 #include <stdlib.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <errno.h>
6 #include <unistd.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdint.h>
6 #include <stdio.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdint.h>
6 #include <stdio.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdint.h>
6 #include <stdio.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdint.h>
6 #include <stdio.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdint.h>
6 #include <stdio.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdint.h>
6 #include <stdio.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdint.h>
6 #include <stdio.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <fcntl.h>
6 #include <stdlib.h>
+13, -13
 1@@ -630,9 +630,9 @@ sanitize(struct header *h)
 2       {h->minor, sizeof(h->minor)}
 3   };
 4 
 5-  /* Numeric fields can be terminated with spaces instead of
 6-   * NULs as per the ustar specification.  Patch all of them to
 7-   * use NULs so we can perform string operations on them. */
 8+  /* numeric fields can be terminated with spaces instead of
 9+ * nuls as per the ustar specification. patch all of them to
10+ * use nuls so we can perform string operations on them */
11   for (i = 0; i < LEN(fields); i++) {
12     j = 0, l = fields[i].l - 1;
13     for (; j < l && fields[i].f[j] == ' '; j++)
14@@ -706,17 +706,17 @@ xt(int argc, char *argv[], int mode)
15     if ((size = strtol(h->size, &p, 8)) < 0 || *p != '\0')
16       eprintf("strtol %s: invalid size\n", h->size);
17 
18-    /* Long file path is read directly into fname*/
19+    /* long file path is read directly into fname */
20     if (h->type == 'L' || h->type == 'x' || h->type == 'g') {
21-      /* Read header only up to size of fname buffer */
22+      /* read header only up to size of fname buffer */
23       for (q = fname; q < fname + size; q += BLKSIZ) {
24         if (q + BLKSIZ >= fname + sizeof fname)
25           eprintf("name exceeds buffer: %.*s\n", q - fname, fname);
26         eread(tarfd, q, BLKSIZ);
27       }
28 
29-      /* Convert pax x header with 'path=' field into L header
30-       */
31+      /* convert pax x header with 'path=' field into l header
32+ */
33       if (h->type == 'x')
34         for (q = fname; q < fname + size - 16; q += n) {
35           if ((n = strtol(q, &p, 10)) < 0 || *p != ' ')
36@@ -734,15 +734,15 @@ xt(int argc, char *argv[], int mode)
37         }
38       fname[size] = '\0';
39 
40-      /* Non L-like header (eg. pax 'g') is skipped by setting
41-       * q=null */
42+      /* non l-like header (eg. pax 'g') is skipped by setting
43+ * q=null */
44       if (h->type != 'L')
45         q = NULL;
46       continue;
47     }
48 
49-    /* Ustar path is copied into fname if no L header (ie: q is
50-     * NULL) */
51+    /* ustar path is copied into fname if no l header (ie: q is
52+ * NULL) */
53     if (!q) {
54       m = sizeof h->prefix, n = sizeof h->name;
55       p = "/" + !h->prefix[0];
56@@ -750,8 +750,8 @@ xt(int argc, char *argv[], int mode)
57     }
58     q = NULL;
59 
60-    /* If argc > 0 or files_from_cnt > 0 then only extract the
61-     * matching files/dirs */
62+    /* if argc > 0 or files_from_cnt > 0 then only extract the
63+ * matching files/dirs */
64     if (argc || files_from_cnt) {
65       match = 0;
66       for (i = 0; i < argc; i++) {
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <sys/stat.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdio.h>
6 #include <stdlib.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <errno.h>
6 #include <stdio.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include "arg.h"
5 #include "util.h"
6 #include "wexec.h"
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <errno.h>
6 #include <pwd.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stdio.h>
6 
+202, -0
  1@@ -0,0 +1,202 @@
  2+/* see LICENSE file for copyright and license details */
  3+
  4+#include "config.h"
  5+#include "passwd.h"
  6+#include "util.h"
  7+#include "wexec.h"
  8+
  9+#include <grp.h>
 10+#include <limits.h>
 11+#include <pwd.h>
 12+#include <stdio.h>
 13+#include <stdlib.h>
 14+#include <string.h>
 15+#include <termios.h>
 16+#include <time.h>
 17+#include <unistd.h>
 18+#include <utmp.h>
 19+
 20+static void
 21+usage(void)
 22+{
 23+  eprintf("usage: %s [-p name] [-f name]\n", argv0);
 24+}
 25+
 26+/* reads one line of input, echoing it or not, into a reusable static
 27+ * buffer. returns null on eof so a hung-up line doesnt loop forever */
 28+static char *
 29+readline(const char *prompt, int echo)
 30+{
 31+  static char    buf[LOGIN_NAME_MAX + 1];
 32+  struct termios old, raw;
 33+  int            have_old = 0;
 34+  size_t         n;
 35+
 36+  fputs(prompt, stdout);
 37+  fflush(stdout);
 38+
 39+  if (!echo && tcgetattr(STDIN_FILENO, &old) == 0) {
 40+    have_old = 1;
 41+    raw      = old;
 42+    raw.c_lflag &= ~ECHO;
 43+    tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
 44+  }
 45+
 46+  if (!fgets(buf, sizeof(buf), stdin)) {
 47+    if (have_old)
 48+      tcsetattr(STDIN_FILENO, TCSAFLUSH, &old);
 49+    return NULL;
 50+  }
 51+
 52+  if (have_old) {
 53+    tcsetattr(STDIN_FILENO, TCSAFLUSH, &old);
 54+    fputc('\n', stdout);
 55+  }
 56+
 57+  n = strlen(buf);
 58+  if (n && buf[n - 1] == '\n')
 59+    buf[--n] = '\0';
 60+
 61+  return buf;
 62+}
 63+
 64+/* best effort utmp record for the controlling tty: getty already
 65+ * cleared any stale entry for this line before exec-ing us. only
 66+ * ut_line, ut_name (musl aliases this to ut_user), and ut_time
 67+ * (aliased to ut_tv.tv_sec) exist on both linux and bsd utmp
 68+ * layouts; ut_type/ut_pid do not exist at all on bsd, so those two
 69+ * fields are the one genuinely platform-specific part of this record */
 70+static void
 71+write_utmp(const char *user)
 72+{
 73+  struct utmp usr;
 74+  char       *line;
 75+  FILE       *fp;
 76+
 77+  memset(&usr, 0, sizeof(usr));
 78+#if defined(__linux__)
 79+  usr.ut_type = USER_PROCESS;
 80+  usr.ut_pid  = getpid();
 81+#endif
 82+  line = ttyname(STDIN_FILENO);
 83+  if (line) {
 84+    if (!strncmp(line, "/dev/", 5))
 85+      line += 5;
 86+    strlcpy(usr.ut_line, line, sizeof(usr.ut_line));
 87+  }
 88+  strlcpy(usr.ut_name, user, sizeof(usr.ut_name));
 89+  usr.ut_time = time(NULL);
 90+
 91+  /* utmp: a live table, so this overwrites/appends the one entry for
 92+ * this session */
 93+  fp = fopen(UTMP_PATH, "r+");
 94+  if (fp) {
 95+    fseek(fp, 0, SEEK_END);
 96+    fwrite(&usr, sizeof(usr), 1, fp);
 97+    fclose(fp);
 98+  }
 99+
100+  /* wtmp: an ever-growing append-only log of the same record, same
101+ * portable field subset, just opened differently */
102+  fp = fopen(WTMP_PATH, "a");
103+  if (fp) {
104+    fwrite(&usr, sizeof(usr), 1, fp);
105+    fclose(fp);
106+  }
107+}
108+
109+// ?man login: authenticate a user and start a session
110+// ?man arguments: [-p name] [-f name]
111+// ?man prompt for a username (unless given) and password, verify against
112+// ?man the system password database, then exec the user's login shell
113+// ?man invoked by getty with -p name once a username has already been
114+// ?man typed at the "login:" prompt
115+int
116+main(int argc, char *argv[])
117+{
118+  struct passwd *pw;
119+  char           namebuf[LOGIN_NAME_MAX + 1];
120+  char           shellbuf[PATH_MAX];
121+  char          *preset = NULL, *trusted = NULL;
122+  char          *name, *pass, *line, *base;
123+  char          *shargv[2];
124+  int            tries;
125+
126+  ARGBEGIN
127+  {
128+    // ?man -p:name preset the username; still prompts for a password
129+    case 'p':
130+      preset = EARGF(usage());
131+      break;
132+    // ?man -f:name log in as name without a password prompt: the
133+    // ?man caller has already authenticated this user out-of-band
134+    case 'f':
135+      trusted = EARGF(usage());
136+      break;
137+    default:
138+      usage();
139+  }
140+  ARGEND
141+
142+  pw_init();
143+
144+  if (trusted) {
145+    pw = getpwnam(trusted);
146+    if (!pw)
147+      eprintf("login: unknown user: %s\n", trusted);
148+  } else {
149+    pw = NULL;
150+    for (tries = 0; tries < 3 && !pw; tries++) {
151+      if (preset && tries == 0) {
152+        strlcpy(namebuf, preset, sizeof(namebuf));
153+      } else {
154+        line = readline("login: ", 1);
155+        if (!line)
156+          exit(1);
157+        strlcpy(namebuf, line, sizeof(namebuf));
158+      }
159+      name = namebuf;
160+
161+      pass = readline("Password: ", 0);
162+      if (!pass)
163+        pass = "";
164+
165+      pw = getpwnam(name);
166+      if (!pw || pw_check(pw, pass) != 1) {
167+        fputs("Login incorrect\n", stdout);
168+        pw = NULL;
169+      }
170+    }
171+    if (!pw)
172+      exit(1);
173+  }
174+
175+  if (initgroups(pw->pw_name, pw->pw_gid) < 0)
176+    weprintf("initgroups:");
177+  if (setgid(pw->pw_gid) < 0)
178+    eprintf("setgid:");
179+  if (setuid(pw->pw_uid) < 0)
180+    eprintf("setuid:");
181+
182+  write_utmp(pw->pw_name);
183+
184+  if (chdir(pw->pw_dir) < 0)
185+    weprintf("chdir %s:", pw->pw_dir);
186+
187+  setenv("HOME", pw->pw_dir, 1);
188+  setenv("USER", pw->pw_name, 1);
189+  setenv("LOGNAME", pw->pw_name, 1);
190+  strlcpy(shellbuf, pw->pw_shell[0] ? pw->pw_shell : "/bin/sh", sizeof(shellbuf));
191+  setenv("SHELL", shellbuf, 1);
192+
193+  base = strrchr(shellbuf, '/');
194+  base = base ? base + 1 : shellbuf;
195+
196+  shargv[0]    = emalloc(strlen(base) + 2);
197+  shargv[0][0] = '-';
198+  strcpy(shargv[0] + 1, base);
199+  shargv[1] = NULL;
200+
201+  wexecv_self(shellbuf, shargv);
202+  return 1;
203+}
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <sys/stat.h>
5 #include <sys/types.h>
6 
+79, -0
 1@@ -0,0 +1,79 @@
 2+/* see LICENSE file for copyright and license details */
 3+#include "passwd.h"
 4+#include "util.h"
 5+
 6+#include <crypt.h>
 7+#include <stdio.h>
 8+#include <stdlib.h>
 9+#include <string.h>
10+#include <termios.h>
11+#include <unistd.h>
12+
13+static void
14+usage(void)
15+{
16+  eprintf("usage: %s [password]\n", argv0);
17+}
18+
19+// ?man mkpasswd: generate a crypt(3) password hash
20+// ?man arguments: [password]
21+// ?man hash a password for use in /etc/passwd or /etc/shadow. reads
22+// ?man the password from the command line, or prompts for it if not given
23+int
24+main(int argc, char *argv[])
25+{
26+  static char    buf[128];
27+  struct termios old, raw;
28+  char           salt[PW_SALT_MAX];
29+  char          *pass, *hash;
30+  int            have_old;
31+  size_t         n;
32+
33+  ARGBEGIN
34+  {
35+    default:
36+      usage();
37+  }
38+  ARGEND
39+
40+  if (argc > 0) {
41+    pass = argv[0];
42+  } else {
43+    fputs("Password: ", stdout);
44+    fflush(stdout);
45+
46+    have_old = tcgetattr(STDIN_FILENO, &old) == 0;
47+    if (have_old) {
48+      raw = old;
49+      raw.c_lflag &= ~ECHO;
50+      tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
51+    }
52+
53+    if (!fgets(buf, sizeof(buf), stdin)) {
54+      if (have_old)
55+        tcsetattr(STDIN_FILENO, TCSAFLUSH, &old);
56+      exit(1);
57+    }
58+
59+    if (have_old) {
60+      tcsetattr(STDIN_FILENO, TCSAFLUSH, &old);
61+      fputc('\n', stdout);
62+    }
63+
64+    n = strlen(buf);
65+    if (n && buf[n - 1] == '\n')
66+      buf[--n] = '\0';
67+    pass = buf;
68+  }
69+
70+  pw_init();
71+  if (pw_gensalt(salt, sizeof(salt)) < 0)
72+    eprintf("mkpasswd: cannot generate salt\n");
73+
74+  hash = crypt(pass, salt);
75+  if (!hash)
76+    eprintf("mkpasswd: crypt:");
77+
78+  printf("%s\n", hash);
79+  return 0;
80+}
+131, -81
  1@@ -1,118 +1,168 @@
  2-/* See LICENSE file for copyright and license details. */
  3+/* see LICENSE file for copyright and license details */
  4 #include "passwd.h"
  5-#include "config.h"
  6-#include "text.h"
  7 #include "util.h"
  8 
  9-#include <errno.h>
 10+#include <crypt.h>
 11 #include <pwd.h>
 12 #include <stdio.h>
 13 #include <stdlib.h>
 14 #include <string.h>
 15-#include <sys/stat.h>
 16+#include <termios.h>
 17 #include <unistd.h>
 18 
 19 static void
 20 usage(void)
 21 {
 22-  eprintf("usage: %s [username]\n", argv0);
 23+  eprintf("usage: %s [-l | -u | -d] [name]\n", argv0);
 24 }
 25 
 26-// ?man passwd: change a user password
 27-// ?man arguments: [username]
 28-// ?man change the password associated with the calling user or with username
 29+/* reads one line with echo off into a reusable static buffer */
 30+static char *
 31+readpass(const char *prompt)
 32+{
 33+  static char    buf[128];
 34+  struct termios old, raw;
 35+  int            have_old;
 36+  size_t         n;
 37+
 38+  fputs(prompt, stdout);
 39+  fflush(stdout);
 40+
 41+  have_old = tcgetattr(STDIN_FILENO, &old) == 0;
 42+  if (have_old) {
 43+    raw = old;
 44+    raw.c_lflag &= ~ECHO;
 45+    tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
 46+  }
 47+
 48+  if (!fgets(buf, sizeof(buf), stdin)) {
 49+    if (have_old)
 50+      tcsetattr(STDIN_FILENO, TCSAFLUSH, &old);
 51+    return NULL;
 52+  }
 53+
 54+  if (have_old) {
 55+    tcsetattr(STDIN_FILENO, TCSAFLUSH, &old);
 56+    fputc('\n', stdout);
 57+  }
 58+
 59+  n = strlen(buf);
 60+  if (n && buf[n - 1] == '\n')
 61+    buf[--n] = '\0';
 62+
 63+  return buf;
 64+}
 65+
 66+// ?man passwd: change a user's password
 67+// ?man arguments: [-l | -u | -d] [name]
 68+// ?man change name's password (default: the caller's own), or with -l/-u/-d
 69+// ?man lock, unlock, or clear it instead. only root may target another
 70+// ?man user, or use -l/-u/-d at all
 71 int
 72 main(int argc, char *argv[])
 73 {
 74-  struct pwdb_entry ent;
 75-  struct passwd    *pw;
 76-  char             *inpass, *prevhash = NULL, *newhash = NULL, salt[PW_SALT_MAX];
 77-  char             *c1, *c2;
 78-  int               status = 1;
 79+  struct pwdb_entry  ent;
 80+  struct passwd     *self, *target;
 81+  char              *name, *cur, *new1, *new2, *hash;
 82+  char               salt[PW_SALT_MAX];
 83+  int                lflag = 0, uflag = 0, dflag = 0;
 84+  uid_t              uid;
 85 
 86   ARGBEGIN
 87   {
 88+    // ?man -l: lock the account by prefixing its hash with '!'
 89+    case 'l':
 90+      lflag = 1;
 91+      break;
 92+    // ?man -u: unlock an account previously locked with -l
 93+    case 'u':
 94+      uflag = 1;
 95+      break;
 96+    // ?man -d: clear the password, allowing a blank password login
 97+    case 'd':
 98+      dflag = 1;
 99+      break;
100     default:
101       usage();
102   }
103   ARGEND
104 
105+  if (lflag + uflag + dflag > 1)
106+    usage();
107+
108+  uid  = getuid();
109+  self = getpwuid(uid);
110+  if (!self)
111+    eprintf("passwd: who are you?\n");
112+
113+  name = argc > 0 ? argv[0] : self->pw_name;
114+  if (uid != 0 && (strcmp(name, self->pw_name) != 0 || lflag || uflag || dflag))
115+    eprintf("passwd: permission denied\n");
116+
117+  target = getpwnam(name);
118+  if (!target)
119+    eprintf("passwd: unknown user: %s\n", name);
120+
121   pw_init();
122-  umask(077);
123-
124-  if (argc == 0)
125-    pw = getpwuid(getuid());
126-  else
127-    pw = getpwnam(argv[0]);
128-  if (!pw) {
129-    if (errno)
130-      eprintf("getpwnam: %s:", argv[0]);
131-    else
132-      eprintf("who are you?\n");
133-  }
134 
135-  if (pwdb_lookup(&ent, pw->pw_name) < 0)
136-    return 1;
137-  prevhash = ent.hash;
138+  if (lflag || uflag || dflag) {
139+    if (pwdb_lookup(&ent, name) < 0)
140+      eprintf("passwd: cannot look up %s\n", name);
141 
142-  if (getuid() != 0) {
143-    if (prevhash[0] == '!' || prevhash[0] == '*')
144-      eprintf("denied\n");
145-    if (prevhash[0] == '\0') {
146-      /* no password set */
147+    if (lflag) {
148+      if (ent.hash[0] == '!') {
149+        hash = ent.hash;
150+      } else {
151+        hash    = emalloc(strlen(ent.hash) + 2);
152+        hash[0] = '!';
153+        strcpy(hash + 1, ent.hash);
154+      }
155+      if (pwdb_update(name, hash) < 0)
156+        eprintf("passwd: update failed\n");
157+      printf("passwd: password for %s locked\n", name);
158+    } else if (uflag) {
159+      hash = ent.hash[0] == '!' ? ent.hash + 1 : ent.hash;
160+      if (pwdb_update(name, hash) < 0)
161+        eprintf("passwd: update failed\n");
162+      printf("passwd: password for %s unlocked\n", name);
163     } else {
164-      printf("Changing password for %s\n", pw->pw_name);
165-      inpass = getpass("Old password: ");
166-      if (!inpass)
167-        eprintf("getpass:");
168-      if (inpass[0] == '\0')
169-        eprintf("no password supplied\n");
170-      c1 = crypt(inpass, prevhash);
171-      if (!c1)
172-        eprintf("crypt:");
173-      if (strcmp(c1, prevhash) != 0)
174-        eprintf("incorrect password\n");
175-      explicit_bzero(inpass, strlen(inpass));
176+      if (pwdb_update(name, "") < 0)
177+        eprintf("passwd: update failed\n");
178+      printf("passwd: password for %s cleared\n", name);
179     }
180+    return 0;
181   }
182 
183-  inpass = getpass("Enter new password: ");
184-  if (!inpass)
185-    eprintf("getpass:");
186-  if (inpass[0] == '\0')
187-    eprintf("no password supplied\n");
188+  if (uid != 0) {
189+    cur = readpass("Current password: ");
190+    if (!cur || pw_check(self, cur) != 1)
191+      eprintf("passwd: authentication failed\n");
192+  }
193+
194+  new1 = readpass("New password: ");
195+  if (!new1)
196+    exit(1);
197+  new1 = estrdup(new1);
198 
199-  if (prevhash && prevhash[0] != '\0') {
200-    c1 = crypt(inpass, prevhash);
201-    if (c1 && strcmp(c1, prevhash) == 0)
202-      eprintf("password left unchanged\n");
203+  new2 = readpass("Retype new password: ");
204+  if (!new2 || strcmp(new1, new2) != 0) {
205+    free(new1);
206+    eprintf("passwd: passwords do not match\n");
207   }
208+  if (new1[0] == '\0')
209+    weprintf("passwd: warning: empty password\n");
210 
211   if (pw_gensalt(salt, sizeof(salt)) < 0)
212-    eprintf("pw_gensalt:");
213-  c1 = crypt(inpass, salt);
214-  if (!c1)
215-    eprintf("crypt:");
216-  newhash = estrdup(c1);
217-  explicit_bzero(inpass, strlen(inpass));
218-
219-  inpass = getpass("Retype new password: ");
220-  if (!inpass)
221-    eprintf("getpass:");
222-  if (inpass[0] == '\0')
223-    eprintf("no password supplied\n");
224-  c2 = crypt(inpass, salt);
225-  if (!c2)
226-    eprintf("crypt:");
227-  if (strcmp(c2, newhash) != 0)
228-    eprintf("passwords don't match\n");
229-  explicit_bzero(inpass, strlen(inpass));
230-
231-  if (pwdb_update(pw->pw_name, newhash) == 0)
232-    status = 0;
233-
234-  free(newhash);
235-  free(ent.name);
236-  free(ent.hash);
237-  return status;
238+    eprintf("passwd: cannot generate salt\n");
239+
240+  hash = crypt(new1, salt);
241+  free(new1);
242+  if (!hash)
243+    eprintf("passwd: crypt:");
244+
245+  if (pwdb_update(name, hash) < 0)
246+    eprintf("passwd: update failed\n");
247+
248+  printf("passwd: password for %s updated\n", name);
249+  return 0;
250 }
+83, -76
  1@@ -1,121 +1,128 @@
  2-/* See LICENSE file for copyright and license details. */
  3-#include "config.h"
  4+/* see LICENSE file for copyright and license details */
  5 #include "passwd.h"
  6 #include "util.h"
  7+#include "wexec.h"
  8 
  9-#include <errno.h>
 10 #include <grp.h>
 11+#include <limits.h>
 12 #include <pwd.h>
 13 #include <stdio.h>
 14 #include <stdlib.h>
 15 #include <string.h>
 16-#include <sys/types.h>
 17+#include <termios.h>
 18 #include <unistd.h>
 19 
 20-extern char **environ;
 21-
 22-#ifndef ENV_PATH_SHELL
 23-#define ENV_PATH_SHELL "/bin/sh"
 24-#endif
 25-
 26-static int lflag = 0;
 27-static int pflag = 0;
 28-
 29 static void
 30 usage(void)
 31 {
 32-  eprintf("usage: %s [-lp] [username]\n", argv0);
 33+  eprintf("usage: %s [-l] [name]\n", argv0);
 34 }
 35 
 36-// ?man su: run a command with substitute user and group id
 37-// ?man arguments: [username]
 38-// ?man run a shell or command as the named user. defaults to root
 39+/* reads one line with echo off into a reusable static buffer */
 40+static char *
 41+readpass(const char *prompt)
 42+{
 43+  static char    buf[128];
 44+  struct termios old, raw;
 45+  int            have_old;
 46+  size_t         n;
 47+
 48+  fputs(prompt, stdout);
 49+  fflush(stdout);
 50+
 51+  have_old = tcgetattr(STDIN_FILENO, &old) == 0;
 52+  if (have_old) {
 53+    raw = old;
 54+    raw.c_lflag &= ~ECHO;
 55+    tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
 56+  }
 57+
 58+  if (!fgets(buf, sizeof(buf), stdin)) {
 59+    if (have_old)
 60+      tcsetattr(STDIN_FILENO, TCSAFLUSH, &old);
 61+    return NULL;
 62+  }
 63+
 64+  if (have_old) {
 65+    tcsetattr(STDIN_FILENO, TCSAFLUSH, &old);
 66+    fputc('\n', stdout);
 67+  }
 68+
 69+  n = strlen(buf);
 70+  if (n && buf[n - 1] == '\n')
 71+    buf[--n] = '\0';
 72+
 73+  return buf;
 74+}
 75+
 76+// ?man su: become another user
 77+// ?man arguments: [-l] [name]
 78+// ?man authenticate as name (default: root) and start a shell as them
 79+// ?man with -l, also chdir to their home directory and run a login shell,
 80+// ?man same as login would
 81 int
 82 main(int argc, char *argv[])
 83 {
 84-  char          *usr, *pass;
 85-  char          *shell, *envshell, *term;
 86   struct passwd *pw;
 87-  char          *newargv[3];
 88+  char           shellbuf[PATH_MAX];
 89+  char          *name, *pass, *base;
 90+  char          *shargv[2];
 91+  int            lflag = 0;
 92   uid_t          uid;
 93 
 94   ARGBEGIN
 95   {
 96+    // ?man -l: start a login shell, chdir home like login does
 97     case 'l':
 98-      // ?man -l: make the shell a login shell
 99       lflag = 1;
100       break;
101-    case 'p':
102-      // ?man -p: preserve the current environment
103-      pflag = 1;
104-      break;
105     default:
106       usage();
107   }
108   ARGEND
109 
110-  if (argc > 1)
111-    usage();
112-  usr = argc > 0 ? argv[0] : "root";
113-
114-  errno = 0;
115-  pw    = getpwnam(usr);
116-  if (!pw) {
117-    if (errno)
118-      eprintf("getpwnam: %s:", usr);
119-    else
120-      eprintf("who are you?\n");
121-  }
122+  name = argc > 0 ? argv[0] : "root";
123+  pw   = getpwnam(name);
124+  if (!pw)
125+    eprintf("su: unknown user: %s\n", name);
126 
127   uid = getuid();
128-  if (uid) {
129-    pass = getpass("Password: ");
130-    if (!pass)
131-      eprintf("getpass:");
132-    if (pw_check(pw, pass) <= 0)
133-      exit(1);
134-    explicit_bzero(pass, strlen(pass));
135+  if (uid != 0) {
136+    pass = readpass("Password: ");
137+    if (!pass || pw_check(pw, pass) != 1)
138+      eprintf("su: incorrect password\n");
139   }
140 
141-  if (initgroups(usr, pw->pw_gid) < 0)
142-    eprintf("initgroups:");
143+  if (initgroups(pw->pw_name, pw->pw_gid) < 0)
144+    weprintf("initgroups:");
145   if (setgid(pw->pw_gid) < 0)
146     eprintf("setgid:");
147   if (setuid(pw->pw_uid) < 0)
148     eprintf("setuid:");
149 
150-  shell = pw->pw_shell[0] == '\0' ? ENV_PATH_SHELL : pw->pw_shell;
151+  strlcpy(shellbuf, pw->pw_shell[0] ? pw->pw_shell : "/bin/sh", sizeof(shellbuf));
152+
153   if (lflag) {
154-    term = getenv("TERM");
155-    clearenv();
156-    setenv("HOME", pw->pw_dir, 1);
157-    setenv("SHELL", shell, 1);
158-    setenv("USER", pw->pw_name, 1);
159-    setenv("LOGNAME", pw->pw_name, 1);
160-    setenv("TERM", term ? term : "dumb", 1);
161-    setenv("PATH", ENV_PATH, 1);
162     if (chdir(pw->pw_dir) < 0)
163-      eprintf("chdir %s:", pw->pw_dir);
164-    newargv[0] = shell;
165-    newargv[1] = "-l";
166-    newargv[2] = NULL;
167+      weprintf("chdir %s:", pw->pw_dir);
168+    setenv("HOME", pw->pw_dir, 1);
169+  }
170+  setenv("USER", pw->pw_name, 1);
171+  setenv("LOGNAME", pw->pw_name, 1);
172+  setenv("SHELL", shellbuf, 1);
173+
174+  base = strrchr(shellbuf, '/');
175+  base = base ? base + 1 : shellbuf;
176+
177+  if (lflag) {
178+    shargv[0]    = emalloc(strlen(base) + 2);
179+    shargv[0][0] = '-';
180+    strcpy(shargv[0] + 1, base);
181   } else {
182-    if (pflag) {
183-      envshell = getenv("SHELL");
184-      if (envshell && envshell[0] != '\0')
185-        shell = envshell;
186-    } else {
187-      setenv("HOME", pw->pw_dir, 1);
188-      setenv("SHELL", shell, 1);
189-      if (strcmp(pw->pw_name, "root") != 0) {
190-        setenv("USER", pw->pw_name, 1);
191-        setenv("LOGNAME", pw->pw_name, 1);
192-      }
193-    }
194-    newargv[0] = shell;
195-    newargv[1] = NULL;
196+    shargv[0] = estrdup(base);
197   }
198-  execve(shell, newargv, environ);
199-  weprintf("execve %s:", shell);
200-  return (errno == ENOENT) ? 127 : 126;
201+  shargv[1] = NULL;
202+
203+  wexecv_self(shellbuf, shargv);
204+  return 1;
205 }
+371, -260
   1@@ -1,8 +1,12 @@
   2-; genconfig.sh config produces four files from build.cfg:
   3-; config.set (read by ninqu), config.kv (read by mkman),
   4+; genconfig.sh config produces four files from build.cfg in one
   5+; invocation: config.set (read by ninqu), config.kv (read by mkman),
   6 ; nofork_list.h (included by wexec.c), and features.h (-included
   7-; into every compile). each gets its own rule so ninqu can find a
   8-; producer for any of them
   9+; into every compile). only CONFIG_SET actually runs the script;
  10+; NOFORK_LIST_H and FEATURES_H depend on its output instead of
  11+; re-running genconfig.sh themselves, so ninja never schedules two
  12+; invocations of the same script concurrently. running it twice in
  13+; parallel raced both invocations' truncate-then-append writes to
  14+; the same files, byte-interleaving their output into invalid C
  15 ;
  16 (rule CONFIG_SET
  17   (out "scripts/mk/config.set")
  18@@ -11,13 +15,13 @@
  19 
  20 (rule NOFORK_LIST_H
  21   (out "shared/libutil/nofork_list.h")
  22-  (dep "build.cfg" "scripts/genconfig.sh")
  23-  (exec sh scripts/genconfig.sh config))
  24+  (dep "scripts/mk/config.set")
  25+  (exec true))
  26 
  27 (rule FEATURES_H
  28   (out "scripts/mk/features.h")
  29-  (dep "build.cfg" "scripts/genconfig.sh")
  30-  (exec sh scripts/genconfig.sh config))
  31+  (dep "scripts/mk/config.set")
  32+  (exec true))
  33 
  34 (set-file "scripts/mk/config.set")
  35 
  36@@ -29,125 +33,159 @@
  37   (out "$(STEM).o")
  38   (exec $(CC) $(CPPFLAGS) -Ishared/libutf $(CFLAGS) -c -o $(OUT) $(MATCH)))
  39 
  40-(rule LIBUTF
  41+  (rule LIBUTF
  42   (dep LIBUTF_OBJ)
  43   (out "shared/libutf/libutf.a")
  44   (description "utf-8 and rune handling, linked into every aruu tool")
  45   (feature core-lib)
  46   (exec $(AR) $(ARFLAGS) $(OUT) $(IN)))
  47 
  48-(rule LIBUTIL_OBJ
  49+  (rule LIBUTIL_OBJ
  50   (glob "shared/libutil/*.c")
  51   (dep $(MATCH))
  52   (after NOFORK_LIST_H FEATURES_H)
  53   (out "$(STEM).o")
  54   (exec $(CC) $(CPPFLAGS_LIBUTIL) -Ishared/libutil $(CFLAGS) -c -o $(OUT) $(MATCH)))
  55 
  56-(rule LIBUTIL
  57+  (rule LIBUTIL
  58   (dep LIBUTIL_OBJ)
  59   (out "shared/libutil/libutil.a")
  60   (description "allocation, error reporting, and string helpers shared by every tool")
  61   (feature core-lib)
  62   (exec $(AR) $(ARFLAGS) $(OUT) $(IN)))
  63 
  64-(rule LIBREDLINE_OBJ
  65+  (rule LIBREDLINE_OBJ
  66   (glob "shared/libredline/*.c")
  67   (dep $(MATCH))
  68   (out "$(STEM).o")
  69   (exec $(CC) $(CPPFLAGS) -Ishared/libredline $(CFLAGS) -c -o $(OUT) $(MATCH)))
  70 
  71-(rule LIBREDLINE
  72+  (rule LIBREDLINE
  73   (dep LIBREDLINE_OBJ)
  74   (out "shared/libredline/libredline.a")
  75   (description "line editing used by sh and any other interactive tool")
  76   (feature core-lib)
  77   (exec $(AR) $(ARFLAGS) $(OUT) $(IN)))
  78 
  79-(group lib LIBUTF LIBUTIL LIBREDLINE)
  80+  (rule LIBBLAKE3_OBJ
  81+  (glob "shared/libblake3/*.c")
  82+  (dep $(MATCH))
  83+  (out "$(STEM).o")
  84+  (exec $(CC) $(CPPFLAGS) -Ishared/libblake3 $(CFLAGS) -c -o $(OUT) $(MATCH)))
  85 
  86-; perfile: every *.c directly inside one of these dirs becomes its
  87-; own binary of the same name, individually gated by
  88-; build_<category>_<ident> (lowercase, hyphens and dots turned to
  89-; underscores, see the $(IDENT) comment above BOX_OBJ below for why)
  90-; (skip) excludes files that belong to a multi-file tool below instead
  91-;
  92-(map EXTRA_LIBS
  93-  (diff "-lm")
  94-  (wget $(LDLIBS_TLS)))
  95+  (rule LIBBLAKE3
  96+  (dep LIBBLAKE3_OBJ)
  97+  (out "shared/libblake3/libblake3.a")
  98+  (description "the BLAKE3 hash algorithm, linked into b3sum, not embedded in it")
  99+  (feature core-lib)
 100+  (exec $(AR) $(ARFLAGS) $(OUT) $(IN)))
 101 
 102-; Every .c file in a category builds into its own binary. (PERFILE)
 103-; Only EXTRA_AFTER differs cuz POSIX waits for GETCONF_H, the rest pass "".
 104-; cmd/posix/bc.c overrides this with its own yacc-based rule, so no need for
 105-; PERFILE to have that as a special case
 106-;
 107-(template PERFILE (NAME CATEGORY DESC EXTRA_AFTER)
 108+  (group lib LIBUTF LIBUTIL LIBREDLINE LIBBLAKE3)
 109+
 110+  ; perfile: every *.c directly inside one of these dirs becomes its
 111+  ; own binary of the same name, individually gated by
 112+  ; build_<category>_<ident> (lowercase, hyphens and dots turned to
 113+  ; underscores, see the $(IDENT) comment above BOX_OBJ below for why)
 114+  ; (skip) excludes files that belong to a multi-file tool below instead
 115+  ;
 116+  ; -lcrypt and -lresolv used to be blanket LDLIBS entries, linked into
 117+  ; every single utility whether it called crypt(3)/resolver functions
 118+  ; or not. tracing real callers of shared/libutil/passwd.c's pw_check/
 119+  ; pw_gensalt (not just direct crypt() calls) turns up exactly four:
 120+  ; passwd, mkpasswd, login, su need -lcrypt; host needs -lresolv
 121+  ; narrowing this here, not just for tidiness, is what makes aruu
 122+  ; buildable on a host whose libc ships a static libresolv/libm but no
 123+  ; static libcrypt. b3sum is the one EXTRA_BIN file with its own extra
 124+  ; library dependency for a different reason: BLAKE3 used to be
 125+  ; implemented inline in b3sum.c itself, which meant anything else
 126+  ; that wanted the same algorithm (ports/pkgtools/libpkg, for hashing
 127+  ; package archives) had no real library to link against and carried
 128+  ; its own separate copy instead, with no way to notice the two had
 129+  ; drifted until one of them turned out to have a bug the other one
 130+  ; didn't. shared/libblake3 exists so there is exactly one copy
 131+  (map EXTRA_LIBS
 132+  (diff "-lm")
 133+  (wget $(LDLIBS_TLS))
 134+  (passwd "-lcrypt")
 135+  (mkpasswd "-lcrypt")
 136+  (login "-lcrypt")
 137+  (su "-lcrypt")
 138+  (host "-lresolv")
 139+  (b3sum "-Lshared/libblake3 -lblake3"))
 140+
 141+  ; every .c file in a category builds into its own binary. (PERFILE)
 142+  ; only EXTRA_AFTER differs cuz POSIX waits for GETCONF_H, the rest pass ""
 143+  ; cmd/posix/bc.c overrides this with its own yacc-based rule, so no need for
 144+  ; PERFILE to have that as a special case
 145+  ;
 146+  (template PERFILE (NAME CATEGORY DESC EXTRA_AFTER)
 147   (rule $(NAME)
 148     (glob "cmd/$(CATEGORY)/*.c")
 149-    (gate build_$(CATEGORY)_$(IDENT))
 150-    (dep $(MATCH) LIBUTIL LIBUTF)
 151-    (after $(EXTRA_AFTER))
 152-    (out $(STEM))
 153-    (description $(DESC))
 154-    (feature perfile)
 155-    (exec $(CC) $(CPPFLAGS) $(CFLAGS) -o $(OUT) $(IN) $(LDFLAGS) $(LDLIBS) $(EXTRA_LIBS:$(BASESTEM)))))
 156-
 157-(use PERFILE POSIX_BIN posix "one POSIX2024 utility per source file under cmd/posix" GETCONF_H)
 158-(use PERFILE LINUX_BIN linux "Linux-only utility, one source file per binary under cmd/linux" "")
 159-(use PERFILE NET_BIN net "networking utility, one source file per binary under cmd/net" "")
 160-(use PERFILE XSI_BIN xsi "XSI-specified utility, one source file per binary under cmd/xsi" "")
 161-(use PERFILE PSEUDO_BIN pseudo "common but undefined utility, one source file per binary under cmd/pseudo" "")
 162-(use PERFILE EXTRA_BIN extra "extra utility outside POSIX/XSI scope, one source file per binary under cmd/extra" "")
 163-
 164-(group posix lib POSIX_BIN POSIX_BC POSIX_AWK POSIX_SH POSIX_MAKE)
 165-(group linux lib LINUX_BIN)
 166-(group net lib NET_BIN)
 167-(group xsi lib XSI_BIN)
 168-(group pseudo lib PSEUDO_BIN)
 169-(group extra lib EXTRA_BIN EXTRA_YAP)
 170-
 171-; codegen: generate sources consumed by the build rules below. Ungated
 172-; ones always run. conditional ones use (req) so they only run when
 173-; their inputs exists in this checkout
 174-;
 175-(rule GETCONF_H
 176+  (gate build_$(CATEGORY)_$(IDENT))
 177+  (dep $(MATCH) LIBUTIL LIBUTF LIBBLAKE3)
 178+  (after $(EXTRA_AFTER))
 179+  (out $(STEM))
 180+  (description $(DESC))
 181+  (feature perfile)
 182+  (exec $(CC) $(CPPFLAGS) $(CFLAGS) -o $(OUT) $(IN) $(LDFLAGS) $(LDLIBS) $(EXTRA_LIBS:$(BASESTEM)))))
 183+
 184+  (use PERFILE POSIX_BIN posix "one POSIX2024 utility per source file under cmd/posix" GETCONF_H)
 185+  (use PERFILE LINUX_BIN linux "linux-only utility, one source file per binary under cmd/linux" "")
 186+  (use PERFILE NET_BIN net "networking utility, one source file per binary under cmd/net" "")
 187+  (use PERFILE XSI_BIN xsi "xsi-specified utility, one source file per binary under cmd/xsi" "")
 188+  (use PERFILE PSEUDO_BIN pseudo "common but undefined utility, one source file per binary under cmd/pseudo" "")
 189+  (use PERFILE EXTRA_BIN extra "extra utility outside POSIX/XSI scope, one source file per binary under cmd/extra" "")
 190+
 191+  (group posix lib POSIX_BIN POSIX_BC POSIX_AWK POSIX_SH POSIX_MAKE)
 192+  (group linux lib LINUX_BIN)
 193+  (group net lib NET_BIN)
 194+  (group xsi lib XSI_BIN)
 195+  (group pseudo lib PSEUDO_BIN)
 196+  (group extra lib EXTRA_BIN EXTRA_YAP)
 197+
 198+  ; codegen: generate sources consumed by the build rules below. ungated
 199+  ; ones always run. conditional ones use (req) so they only run when
 200+  ; their inputs exists in this checkout
 201+  ;
 202+  (rule GETCONF_H
 203   (gate build_posix_getconf)
 204   (out "cmd/posix/getconf.h")
 205   (dep "scripts/getconf.sh")
 206   (exec sh scripts/genconfig.sh getconf))
 207 
 208-(rule POSIX_BC_C
 209+  (rule POSIX_BC_C
 210   (gate build_posix_bc)
 211   (req "cmd/posix/bc.y")
 212   (out "cmd/posix/bc.c")
 213   (dep "cmd/posix/bc.y")
 214   (exec sh scripts/genconfig.sh bc))
 215 
 216-(rule POSIX_AWK_C
 217+  (rule POSIX_AWK_C
 218   (gate build_posix_awk)
 219   (out "cmd/posix/awk/awkgram.tab.c")
 220   (dep "cmd/posix/awk/awkgram.y")
 221   (exec sh scripts/genconfig.sh awk))
 222 
 223-(rule POSIX_SH_C
 224+  (rule POSIX_SH_C
 225   (gate build_posix_sh)
 226   (out "cmd/posix/sh/syntax.c")
 227   (dep "cmd/posix/sh/mksyntax.c" "cmd/posix/sh/mknodes.c" "cmd/posix/sh/mkbuiltins" "cmd/posix/sh/mktokens")
 228   (exec sh scripts/genconfig.sh sh))
 229 
 230-(rule DEVCONF
 231+  (rule DEVCONF
 232   (req "cmd/dev/configure")
 233   (out "cmd/dev/config.h")
 234   (dep "cmd/dev/configure")
 235   (phony)
 236   (exec sh cmd/dev/configure))
 237 
 238-(group codegen GETCONF_H POSIX_BC_C POSIX_AWK_C POSIX_SH_C DEVCONF)
 239+  (group codegen GETCONF_H POSIX_BC_C POSIX_AWK_C POSIX_SH_C DEVCONF)
 240 
 241-; multi: one binary from all .c files in one or more dirs (minus skip).
 242-; codegen must run first so generated sources are present before these
 243-; globs collect them
 244-;
 245-(rule POSIX_BC_OBJ
 246+  ; multi: one binary from all .c files in one or more dirs (minus skip)
 247+  ; codegen must run first so generated sources are present before these
 248+  ; globs collect them
 249+  ;
 250+  (rule POSIX_BC_OBJ
 251   (glob "cmd/posix/bc.c")
 252   (gate build_posix_bc)
 253   (dep $(MATCH))
 254@@ -155,14 +193,14 @@
 255   (out "$(STEM).o")
 256   (exec $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $(OUT) $(MATCH)))
 257 
 258-(rule POSIX_BC
 259+  (rule POSIX_BC
 260   (gate build_posix_bc)
 261   (member posix bc)
 262   (dep POSIX_BC_OBJ LIBUTIL LIBUTF)
 263   (out "cmd/posix/bc")
 264   (exec $(CC) -o $(OUT) $(IN) $(LDFLAGS) $(LDLIBS) -lm))
 265 
 266-(rule POSIX_AWK_OBJ
 267+  (rule POSIX_AWK_OBJ
 268   (glob "cmd/posix/awk/*.c")
 269   (gate build_posix_awk)
 270   (skip "maketab.c")
 271@@ -171,14 +209,14 @@
 272   (out "$(STEM).o")
 273   (exec $(CC) $(CPPFLAGS) -Icmd/posix/awk $(CFLAGS) -c -o $(OUT) $(MATCH)))
 274 
 275-(rule POSIX_AWK
 276+  (rule POSIX_AWK
 277   (gate build_posix_awk)
 278   (member posix awk)
 279   (dep POSIX_AWK_OBJ LIBUTIL LIBUTF)
 280   (out "cmd/posix/awk/awk")
 281   (exec $(CC) -o $(OUT) $(IN) $(LDFLAGS) $(LDLIBS) -lm))
 282 
 283-(rule POSIX_SH_OBJ
 284+  (rule POSIX_SH_OBJ
 285   (glob "cmd/posix/sh/*.c")
 286   (gate build_posix_sh)
 287   (skip "mknodes.c" "mksyntax.c")
 288@@ -187,50 +225,50 @@
 289   (out "$(STEM).o")
 290   (exec $(CC) $(CPPFLAGS) -DSHELL -Icmd/posix/sh $(CFLAGS) -c -o $(OUT) $(MATCH)))
 291 
 292-(rule POSIX_SH
 293+  (rule POSIX_SH
 294   (gate build_posix_sh)
 295   (member posix sh)
 296   (dep POSIX_SH_OBJ LIBUTIL LIBUTF LIBREDLINE)
 297   (out "cmd/posix/sh/sh")
 298   (exec $(CC) -o $(OUT) $(IN) $(LDFLAGS) $(LDLIBS)))
 299 
 300-(rule POSIX_MAKE_OBJ
 301+  (rule POSIX_MAKE_OBJ
 302   (glob "cmd/posix/make/*.c")
 303   (gate build_posix_make)
 304   (dep $(MATCH))
 305   (out "$(STEM).o")
 306   (exec $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $(OUT) $(MATCH)))
 307 
 308-(rule POSIX_MAKE
 309+  (rule POSIX_MAKE
 310   (gate build_posix_make)
 311   (member posix make)
 312   (dep POSIX_MAKE_OBJ LIBUTIL LIBUTF)
 313   (out "cmd/posix/make/make")
 314   (exec $(CC) -o $(OUT) $(IN) $(LDFLAGS) $(LDLIBS)))
 315 
 316-(rule EXTRA_YAP_OBJ
 317+  (rule EXTRA_YAP_OBJ
 318   (glob "cmd/extra/yap/*.c")
 319   (gate build_extra_yap)
 320   (dep $(MATCH))
 321   (out "$(STEM).o")
 322   (exec $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $(OUT) $(MATCH)))
 323 
 324-(rule EXTRA_YAP
 325+  (rule EXTRA_YAP
 326   (gate build_extra_yap)
 327   (member extra yap)
 328   (dep EXTRA_YAP_OBJ LIBUTIL LIBUTF)
 329   (out "cmd/extra/yap/yap")
 330   (exec $(CC) -o $(OUT) $(IN) $(LDFLAGS) $(LDLIBS) -ltinfo))
 331 
 332-; (member GROUP ALIAS) gives a rule a qualified user-facing name
 333-; (e.g. posix/bc) while keeping its internal name (POSIX_BC) for deps,
 334-; gates, and other references
 335-;
 336+  ; (member GROUP ALIAS) gives a rule a qualified user-facing name
 337+  ; (e.g. posix/bc) while keeping its internal name (POSIX_BC) for deps,
 338+  ; gates, and other references
 339+  ;
 340 
 341-; dev: the aruu toolchain. ar/as/ld are standalone and cc
 342-; shares one object pool linked into three frontends
 343-;
 344-(rule AR_OBJ
 345+  ; dev: the aruu toolchain. ar/as/ld are standalone and cc
 346+  ; shares one object pool linked into three frontends
 347+  ;
 348+  (rule AR_OBJ
 349   (glob "cmd/dev/ar/*.c")
 350   (gate build_dev_ar)
 351   (skip "tinyar.c")
 352@@ -238,100 +276,113 @@
 353   (out "$(STEM).o")
 354   (exec $(CC) $(CPPFLAGS) -Icmd/dev/ar $(CFLAGS) -c -o $(OUT) $(MATCH)))
 355 
 356-(rule AR
 357+  (rule AR
 358   (gate build_dev_ar)
 359   (dep AR_OBJ LIBUTIL LIBUTF)
 360+  ; static: these tools run inside whatever rootfs they target via
 361+  ; nac, not just the host that built them, and never need the
 362+  ; project-wide LDLIBS default (openssl, unused by any of them)
 363   (out "cmd/dev/ar/ar")
 364-  (exec $(CC) -o $(OUT) $(IN) $(LDFLAGS) $(LDLIBS)))
 365+  (exec $(CC) -static -o $(OUT) $(IN) $(LDFLAGS)))
 366 
 367-(rule XCUTIL_OBJ
 368-  (glob "cmd/dev/xcutil/*.c")
 369+  (rule TCUTIL_OBJ
 370+  (glob "shared/libtcutil/*.c" "shared/libtcutil/elf/*.c" "shared/libtcutil/ar/*.c")
 371   (gate build_dev_cc)
 372   (dep $(MATCH))
 373   (out "$(STEM).o")
 374-  (exec $(CC) $(CPPFLAGS) -Icmd/dev/xcutil $(CFLAGS) -c -o $(OUT) $(MATCH)))
 375+  (exec $(CC) $(CPPFLAGS) -Ishared/libtcutil -Ishared/libtcutil/elf -Ishared/libtcutil/ar -Icmd/dev $(CFLAGS) -c -o $(OUT) $(MATCH)))
 376 
 377-(rule AS_OBJ
 378+  (rule AS_OBJ
 379   (glob "cmd/dev/as/*.c" "cmd/dev/as/arch/x64/*.c")
 380   (gate build_dev_cc)
 381   (dep $(MATCH))
 382   (out "$(STEM).o")
 383-  (exec $(CC) $(CPPFLAGS) -Icmd/dev/xcutil -Icmd/dev/as -Icmd/dev/as/arch/x64 -Ishared $(CFLAGS) -c -o $(OUT) $(MATCH)))
 384+  (exec $(CC) $(CPPFLAGS) -Ishared/libtcutil -Ishared/libtcutil/elf -Ishared/libtcutil/ar -Icmd/dev -Icmd/dev/as -Icmd/dev/as/arch/x64 -Ishared $(CFLAGS) -c -o $(OUT) $(MATCH)))
 385 
 386-(rule AS
 387+  (rule AS
 388   (gate build_dev_cc)
 389-  (dep AS_OBJ LIBUTIL LIBUTF)
 390-  (after XCUTIL_OBJ)
 391+  (dep AS_OBJ TCUTIL_OBJ LIBUTIL LIBUTF)
 392   (out "cmd/dev/as/as")
 393-  (exec $(CC) -o $(OUT) $(IN) $(LDFLAGS) $(LDLIBS)))
 394+  (exec $(CC) -static -o $(OUT) $(IN) $(LDFLAGS)))
 395 
 396-(rule LD_OBJ
 397-  (glob "cmd/dev/ld/*.c")
 398+  (rule LD_OBJ
 399+  (glob "cmd/dev/ld/*.c" "cmd/dev/ld/arch/*/*.c")
 400   (gate build_dev_ld)
 401   (dep $(MATCH))
 402   (out "$(STEM).o")
 403-  (exec $(CC) $(CPPFLAGS) -Icmd/dev/xcutil -Icmd/dev/ld $(CFLAGS) -c -o $(OUT) $(MATCH)))
 404+  (exec $(CC) $(CPPFLAGS) -Icmd/dev/ld $(CFLAGS) -c -o $(OUT) $(MATCH)))
 405 
 406-(rule LD
 407+  (rule LD
 408   (gate build_dev_ld)
 409   (dep LD_OBJ LIBUTIL LIBUTF)
 410-  (after XCUTIL_OBJ)
 411   (out "cmd/dev/ld/ld")
 412-  (exec $(CC) -o $(OUT) $(IN) $(LDFLAGS) $(LDLIBS)))
 413+  (exec $(CC) -static -o $(OUT) $(IN) $(LDFLAGS)))
 414 
 415-; CCPOOL_OBJ globs the whole directory. The entry points below use
 416-; literal globs, so the override excludes them automatically
 417-(rule CCPOOL_OBJ
 418+  ; CCPOOL_OBJ globs the whole directory. the entry points below use
 419+  ; literal globs, so the override excludes them automatically
 420+  (rule CCPOOL_OBJ
 421   (glob "cmd/dev/cc/*.c")
 422   (gate build_dev_cc)
 423   (dep $(MATCH))
 424   (out "$(STEM).o")
 425   (exec $(CC) $(CPPFLAGS) -Icmd/dev/cc $(CFLAGS) -c -o $(OUT) $(MATCH)))
 426 
 427-(rule CC1_OBJ
 428+  (rule CC1_OBJ
 429   (glob "cmd/dev/cc/cc1.c")
 430   (gate build_dev_cc)
 431   (dep $(MATCH))
 432   (out "$(STEM).o")
 433   (exec $(CC) $(CPPFLAGS) -Icmd/dev/cc $(CFLAGS) -c -o $(OUT) $(MATCH)))
 434 
 435-(rule CC1
 436+  ; util.c is its own rule, not folded into CCPOOL_OBJ's wildcard or
 437+  ; CCDRV_OBJ's own glob: cc1, cpp, and cc (the driver) all call its
 438+  ; helpers (fatal, xmalloc, arrayadd, ...), but only cc has its own
 439+  ; main(), so driver.c cannot be a shared link input the other two
 440+  ; binaries pull in too
 441+  (rule UTIL_OBJ
 442+  (glob "cmd/dev/cc/util.c")
 443   (gate build_dev_cc)
 444-  (dep CC1_OBJ CCPOOL_OBJ LIBUTIL LIBUTF)
 445+  (dep $(MATCH))
 446+  (out "$(STEM).o")
 447+  (exec $(CC) $(CPPFLAGS) -Icmd/dev/cc $(CFLAGS) -c -o $(OUT) $(MATCH)))
 448+
 449+  (rule CC1
 450+  (gate build_dev_cc)
 451+  (dep CC1_OBJ CCPOOL_OBJ UTIL_OBJ LIBUTIL LIBUTF)
 452   (out "cmd/dev/cc/cc1")
 453-  (exec $(CC) -o $(OUT) $(IN) $(LDFLAGS) $(LDLIBS)))
 454+  (exec $(CC) -static -o $(OUT) $(IN) $(LDFLAGS)))
 455 
 456-(rule CPP_OBJ
 457+  (rule CPP_OBJ
 458   (glob "cmd/dev/cc/cpp.c")
 459   (gate build_dev_cc)
 460   (dep $(MATCH))
 461   (out "$(STEM).o")
 462   (exec $(CC) $(CPPFLAGS) -Icmd/dev/cc $(CFLAGS) -c -o $(OUT) $(MATCH)))
 463 
 464-(rule CPP
 465+  (rule CPP
 466   (gate build_dev_cc)
 467-  (dep CPP_OBJ CCPOOL_OBJ LIBUTIL LIBUTF)
 468+  (dep CPP_OBJ CCPOOL_OBJ UTIL_OBJ LIBUTIL LIBUTF)
 469   (out "cmd/dev/cc/cpp")
 470-  (exec $(CC) -o $(OUT) $(IN) $(LDFLAGS) $(LDLIBS)))
 471+  (exec $(CC) -static -o $(OUT) $(IN) $(LDFLAGS)))
 472 
 473-(rule CCDRV_OBJ
 474-  (glob "cmd/dev/cc/driver.c" "cmd/dev/cc/util.c")
 475+  (rule CCDRV_OBJ
 476+  (glob "cmd/dev/cc/driver.c")
 477   (gate build_dev_cc)
 478   (dep $(MATCH))
 479   (out "$(STEM).o")
 480   (exec $(CC) $(CPPFLAGS) -Icmd/dev/cc $(CFLAGS) -c -o $(OUT) $(MATCH)))
 481 
 482-(rule CCDRV
 483+  (rule CCDRV
 484   (gate build_dev_cc)
 485-  (dep CCDRV_OBJ LIBUTIL LIBUTF)
 486+  (dep CCDRV_OBJ UTIL_OBJ LIBUTIL LIBUTF)
 487   (out "cmd/dev/cc/cc")
 488-  (exec $(CC) -o $(OUT) $(IN) $(LDFLAGS) $(LDLIBS)))
 489+  (exec $(CC) -static -o $(OUT) $(IN) $(LDFLAGS)))
 490 
 491-; Like BOX_OBJ: rename main and hide other globals so ninqu can link
 492-; into aruu-box. It is still not reentrant, so it stays out of
 493-; NOFORK_LIST
 494-;
 495-(rule NINQU_BOX_OBJ
 496+  ; like BOX_OBJ: rename main and hide other globals so ninqu can link
 497+  ; into aruu-box. it is still not reentrant, so it stays out of
 498+  ; NOFORK_LIST
 499+  ;
 500+  (rule NINQU_BOX_OBJ
 501   (glob "cmd/dev/ninqu/*.c")
 502   (gate build_dev_ninqu)
 503   (dep $(MATCH))
 504@@ -341,17 +392,17 @@
 505   (shell "$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $(OUT) $(MATCH) && sym=`echo $(BASESTEM) | tr '.-' '__'`_main && $(OBJCOPY) --redefine-sym main=$sym $(OUT) && $(OBJCOPY) --keep-global-symbol=$sym $(OUT)")
 506   (group box))
 507 
 508-(group dev lib DEVCONF AR AS LD CC1 CPP CCDRV)
 509+  (group dev lib DEVCONF AR AS LD CC1 CPP CCDRV)
 510 
 511-; man pages: build mdoc and text pages from ?man-marked sources
 512-;
 513-(rule MKMAN
 514+  ; man pages: build mdoc and text pages from ?man-marked sources
 515+  ;
 516+  (rule MKMAN
 517   (dir "scripts/mkman")
 518   (dep "glob:scripts/mkman/*.go")
 519   (out "scripts/mkman/mkman")
 520   (exec go build -o mkman .))
 521 
 522-(rule MAN_MDOC
 523+  (rule MAN_MDOC
 524   (glob "cmd/**/*.c")
 525   (mark "?man")
 526   (dep (after MKMAN))
 527@@ -359,7 +410,7 @@
 528   (exec scripts/mkman/mkman -fmt mdoc -config scripts/mk/config.kv $(MATCH))
 529   (redirect))
 530 
 531-(rule MAN_TXT
 532+  (rule MAN_TXT
 533   (glob "cmd/**/*.c")
 534   (mark "?man")
 535   (dep (after MKMAN))
 536@@ -367,7 +418,7 @@
 537   (exec scripts/mkman/mkman -fmt txt -config scripts/mk/config.kv $(MATCH))
 538   (redirect))
 539 
 540-(map SEC_OF
 541+  (map SEC_OF
 542   (cmd/posix 1)
 543   (cmd/linux 8)
 544   (cmd/net 8)
 545@@ -376,64 +427,116 @@
 546   (cmd/extra 1)
 547   (cmd/dev 1))
 548 
 549-(group man MAN_MDOC MAN_TXT)
 550+  (group man MAN_MDOC MAN_TXT)
 551 
 552-(rule CLEAN
 553+  (rule CLEAN
 554   (phony)
 555   (shell "
 556-    printf '  CLEAN object files\n'
 557-    find shared cmd -name '*.o' -exec rm -f {} +
 558+  printf ' CLEAN object files\n'
 559+  find shared cmd -name '*.o' -exec rm -f {} +
 560 
 561-    printf '  CLEAN static libraries\n'
 562-    find shared -name '*.a' -exec rm -f {} +
 563+  printf ' CLEAN static libraries\n'
 564+  find shared -name '*.a' -exec rm -f {} +
 565 
 566-    printf '  CLEAN compiled binaries\n'
 567-    find cmd -type f ! -name '*.*' -perm -100 -exec rm -f {} +
 568+  printf ' CLEAN compiled binaries\n'
 569+  find cmd -type f ! -name '*.*' -perm -100 -exec rm -f {} +
 570 
 571-    sh scripts/genconfig.sh clean
 572-    rm -f scripts/mk/config.mk scripts/mk/config.kv scripts/mk/rules.mk shared/libutil/nofork_list.h
 573+  sh scripts/genconfig.sh clean
 574+  rm -f scripts/mk/config.mk scripts/mk/config.kv scripts/mk/rules.mk shared/libutil/nofork_list.h
 575 
 576-    printf '  CLEAN build tools\n'
 577-    rm -f scripts/mkman/mkman
 578+  printf ' CLEAN build tools\n'
 579+  rm -f scripts/mkman/mkman
 580 
 581-    printf '  CLEAN dev artifacts\n'
 582-    rm -f cmd/dev/cc/cc1 cmd/dev/cc/cpp cmd/dev/as/as cmd/dev/ld/ld cmd/dev/ar/ar
 583-    rm -f shared/libaruuelf.so
 584-    rm -f cmd/dev/config.h cmd/dev/cc/config.h cmd/dev/version.h
 585+  printf ' CLEAN dev artifacts\n'
 586+  rm -f cmd/dev/cc/cc1 cmd/dev/cc/cpp cmd/dev/as/as cmd/dev/ld/ld cmd/dev/ar/ar
 587+  rm -f shared/libaruuelf.so
 588+  rm -f cmd/dev/config.h cmd/dev/cc/config.h cmd/dev/version.h
 589 
 590-    printf '  CLEAN misc\n'
 591-    rm -rf man/man1 man/man8
 592-    rm -rf aruu-box .box
 593-    rm -rf .ninja_log .ninja_deps
 594+  printf ' CLEAN misc\n'
 595+  rm -rf man/man1 man/man8
 596+  rm -rf aruu-box .box
 597+  rm -rf .ninja_log .ninja_deps
 598 
 599-    printf '  CLEAN done\n'
 600+  printf ' CLEAN done\n'
 601   "))
 602 
 603-(group clean CLEAN)
 604+  (group clean CLEAN)
 605 
 606-; install every built executable and generated man page
 607-(rule INSTALL
 608+  ; install every built executable and generated man page, plus
 609+  ; shared/libutil itself as a real linkable library: other MICE
 610+  ; components (ports/pkgtools, nac) should link against this, not carry
 611+  ; their own copy of ealloc/eprintf/wexec/etc alongside it
 612+  (rule INSTALL
 613   (phony)
 614-  (after ALL_BINS MAN_MDOC MAN_TXT)
 615+  (after ALL_BINS LIBUTIL MAN_MDOC MAN_TXT)
 616   (shell "
 617-    mkdir -p \"$(PREFIX)/bin\" \"$(MANPREFIX)/man1\" \"$(MANPREFIX)/man8\"
 618+  d=\"${DESTDIR:-}$(PREFIX)\"
 619+  m=\"${DESTDIR:-}$(MANPREFIX)\"
 620+  mkdir -p \"$d/bin\" \"$m/man1\" \"$m/man8\" \"$d/lib\" \"$d/include/aruu\"
 621 
 622-    find cmd -type f ! -name '*.*' -perm -100 | while read -r bin; do
 623-      name=${bin##*/}
 624+  find cmd -type f ! -name '*.*' -perm -100 | while read -r bin; do
 625+  name=${bin##*/}
 626       printf '  INSTALL %s/bin/%s\n' '$(PREFIX)' \"$name\"
 627-      cp \"$bin\" \"$(PREFIX)/bin/$name\"
 628-      chmod 755 \"$(PREFIX)/bin/$name\"
 629+      cp \"$bin\" \"$d/bin/$name\"
 630+      chmod 755 \"$d/bin/$name\"
 631     done
 632 
 633     find man/man1 man/man8 -type f -name '*.[18]' 2>/dev/null | while read -r f; do
 634       sec=${f%/*}; sec=${sec##*/}
 635       name=${f##*/}
 636-      cp \"$f\" \"$(MANPREFIX)/$sec/$name\"
 637+      cp \"$f\" \"$m/$sec/$name\"
 638+    done
 639+
 640+    printf '  INSTALL %s/lib/libaruu.a\n' '$(PREFIX)'
 641+    cp shared/libutil/libutil.a \"$d/lib/libaruu.a\"
 642+    chmod 644 \"$d/lib/libaruu.a\"
 643+    for h in shared/util.h shared/wexec.h shared/arg.h shared/compat.h; do
 644+      printf '  INSTALL %s/include/aruu/%s\n' '$(PREFIX)' \"${h##*/}\"
 645+      cp \"$h\" \"$d/include/aruu/${h##*/}\"
 646+      chmod 644 \"$d/include/aruu/${h##*/}\"
 647     done
 648   "))
 649 
 650 (group install INSTALL)
 651 
 652+; same body as INSTALL, minus the dev (compiler toolchain) category:
 653+; what a MICE port needs to put a shell and coreutils on a rootfs,
 654+; not a hard dependency on the separate, not-yet-portable dev build
 655+(rule INSTALL_BASE
 656+  (phony)
 657+  (after POSIX_BIN LINUX_BIN NET_BIN XSI_BIN PSEUDO_BIN EXTRA_BIN
 658+         POSIX_BC POSIX_AWK POSIX_SH POSIX_MAKE EXTRA_YAP
 659+         LIBUTIL MAN_MDOC MAN_TXT)
 660+  (shell "
 661+    d=\"${DESTDIR:-}$(PREFIX)\"
 662+    m=\"${DESTDIR:-}$(MANPREFIX)\"
 663+    mkdir -p \"$d/bin\" \"$m/man1\" \"$m/man8\" \"$d/lib\" \"$d/include/aruu\"
 664+
 665+    find cmd -type f ! -name '*.*' -perm -100 ! -path 'cmd/dev/*' | while read -r bin; do
 666+  name=${bin##*/}
 667+      printf '  INSTALL %s/bin/%s\n' '$(PREFIX)' \"$name\"
 668+      cp \"$bin\" \"$d/bin/$name\"
 669+      chmod 755 \"$d/bin/$name\"
 670+    done
 671+
 672+    find man/man1 man/man8 -type f -name '*.[18]' 2>/dev/null | while read -r f; do
 673+      sec=${f%/*}; sec=${sec##*/}
 674+      name=${f##*/}
 675+      cp \"$f\" \"$m/$sec/$name\"
 676+    done
 677+
 678+    printf '  INSTALL %s/lib/libaruu.a\n' '$(PREFIX)'
 679+    cp shared/libutil/libutil.a \"$d/lib/libaruu.a\"
 680+    chmod 644 \"$d/lib/libaruu.a\"
 681+    for h in shared/util.h shared/wexec.h shared/arg.h shared/compat.h; do
 682+      printf '  INSTALL %s/include/aruu/%s\n' '$(PREFIX)' \"${h##*/}\"
 683+      cp \"$h\" \"$d/include/aruu/${h##*/}\"
 684+      chmod 644 \"$d/include/aruu/${h##*/}\"
 685+    done
 686+  "))
 687+
 688+(group install-base INSTALL_BASE)
 689+
 690 ; remove exactly what install would have copied
 691 (rule REMOVE
 692   (phony)
 693@@ -450,6 +553,14 @@
 694       printf '  REMOVE %s/%s/%s\n' '$(MANPREFIX)' \"$sec\" \"$name\"
 695       rm -f \"$(MANPREFIX)/$sec/$name\"
 696     done
 697+
 698+    printf '  REMOVE %s/lib/libaruu.a\n' '$(PREFIX)'
 699+    rm -f \"$(PREFIX)/lib/libaruu.a\"
 700+    for h in util.h wexec.h arg.h compat.h; do
 701+      printf '  REMOVE %s/include/aruu/%s\n' '$(PREFIX)' \"$h\"
 702+      rm -f \"$(PREFIX)/include/aruu/$h\"
 703+    done
 704+    rmdir \"$(PREFIX)/include/aruu\" 2>/dev/null || :
 705   "))
 706 
 707 (group remove REMOVE)
 708@@ -464,62 +575,62 @@
 709       ! -path 'cmd/posix/sh/*' \
 710       ! -path 'cmd/posix/make/*' \
 711       ! -path 'cmd/extra/yap/*' \
 712-      ! -path 'cmd/posix/bc.c' \
 713-      -print | xargs -r clang-format -i
 714+  ! -path 'cmd/posix/bc.c' \
 715+  -print | xargs -r clang-format -i
 716   "))
 717 
 718-(rule FMT_ALL
 719+  (rule FMT_ALL
 720   (phony)
 721   (shell "
 722-    printf '  FMT cmd and shared (including dir tools)\n'
 723-    find cmd shared -type f \( -name '*.c' -o -name '*.h' \) -print \
 724-      | xargs -r clang-format -i
 725+  printf ' FMT cmd and shared (including dir tools)\n'
 726+  find cmd shared -type f \( -name '*.c' -o -name '*.h' \) -print \
 727+  | xargs -r clang-format -i
 728   "))
 729 
 730-(group fmt FMT)
 731-(group fmt-all FMT_ALL)
 732-
 733-; box: one executable containing every enabled tool, dispatched through
 734-; a table. a single-file tool just gets its main renamed by BOX_OBJ.
 735-; multi-file tools (POSIX_BC, POSIX_AWK, POSIX_SH, POSIX_MAKE, EXTRA_YAP)
 736-; go through a partial link (ld -r) first, merging their objects into
 737-; one before main gets renamed and helper symbols hidden. replaces
 738-; scripts/mkbox
 739-;
 740-; object files live under .box/, mirroring the cmd/ layout
 741-;
 742-; Ninqu determines which tools enter the box using the gate on BOX_OBJ.
 743-; BOX_DISPATCH reads the object paths passed on argv rather than consulting
 744-; build.cfg or config.set directly
 745-;
 746-
 747-; CATEGORY_OF maps a directory path to its category name, matching the toggles
 748-; in build.cfg. Since BOX_OBJ globs multiple directories, its gate evaluates the
 749-; category dynamically based on the match directory
 750-;
 751-; Gates evaluate $(IDENT) instead of $(BASESTEM) because toggle names must be
 752-; valid shell variables. Genconfig.sh replaces hyphens and periods with
 753-; underscores, and $(IDENT) applies the same normalization so they match
 754-;
 755-(map CATEGORY_OF
 756-  (cmd/posix  posix)
 757-  (cmd/linux  linux)
 758-  (cmd/net    net)
 759+  (group fmt FMT)
 760+  (group fmt-all FMT_ALL)
 761+
 762+  ; box: one executable containing every enabled tool, dispatched through
 763+  ; a table. a single-file tool just gets its main renamed by BOX_OBJ
 764+  ; multi-file tools (POSIX_BC, POSIX_AWK, POSIX_SH, POSIX_MAKE, EXTRA_YAP)
 765+  ; go through a partial link (ld -r) first, merging their objects into
 766+  ; one before main gets renamed and helper symbols hidden. replaces
 767+  ; scripts/mkbox
 768+  ;
 769+  ; object files live under .box/, mirroring the cmd/ layout
 770+  ;
 771+  ; ninqu determines which tools enter the box using the gate on BOX_OBJ
 772+  ; BOX_DISPATCH reads the object paths passed on argv rather than consulting
 773+  ; build.cfg or config.set directly
 774+  ;
 775+
 776+  ; CATEGORY_OF maps a directory path to its category name, matching the toggles
 777+  ; in build.cfg. since BOX_OBJ globs multiple directories, its gate evaluates the
 778+  ; category dynamically based on the match directory
 779+  ;
 780+  ; gates evaluate $(IDENT) instead of $(BASESTEM) because toggle names must be
 781+  ; valid shell variables. genconfig.sh replaces hyphens and periods with
 782+  ; underscores, and $(IDENT) applies the same normalization so they match
 783+  ;
 784+  (map CATEGORY_OF
 785+  (cmd/posix posix)
 786+  (cmd/linux linux)
 787+  (cmd/net net)
 788   (cmd/pseudo pseudo)
 789-  (cmd/xsi    xsi)
 790-  (cmd/extra  extra))
 791-
 792-; Tool basestems match their C symbols using a shell transform (tr '.-' '__'
 793-; and appending _main) in both the objcopy step and in genbox.sh. A static map
 794-; is unnecessary because no current tools require custom overrides, and
 795-; genbox.sh only receives paths via argv
 796-;
 797-
 798-; the match directory picks the gate and output path, so one rule covers
 799-; all six categories. bc.c inside cmd/posix is excluded automatically by
 800-; the literal-glob override mechanism
 801-;
 802-(rule BOX_OBJ
 803+  (cmd/xsi xsi)
 804+  (cmd/extra extra))
 805+
 806+  ; tool basestems match their c symbols using a shell transform (tr '.-' '__'
 807+  ; and appending _main) in both the objcopy step and in genbox.sh. a static map
 808+  ; is unnecessary because no current tools require custom overrides, and
 809+  ; genbox.sh only receives paths via argv
 810+  ;
 811+
 812+  ; the match directory picks the gate and output path, so one rule covers
 813+  ; all six categories. bc.c inside cmd/posix is excluded automatically by
 814+  ; the literal-glob override mechanism
 815+  ;
 816+  (rule BOX_OBJ
 817   (glob "cmd/posix/*.c" "cmd/linux/*.c" "cmd/net/*.c" "cmd/pseudo/*.c"
 818         "cmd/xsi/*.c" "cmd/extra/*.c")
 819   (gate build_$(CATEGORY_OF:$(DIR))_$(IDENT))
 820@@ -530,15 +641,15 @@
 821   (shell "$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $(OUT) $(MATCH) && sym=`echo $(BASESTEM) | tr '.-' '__'`_main && $(OBJCOPY) --redefine-sym main=$sym $(OUT) && $(OBJCOPY) --keep-global-symbol=$sym $(OUT)")
 822   (group box))
 823 
 824-; POSIX_BC, POSIX_AWK, POSIX_SH, POSIX_MAKE, and EXTRA_YAP cant go through
 825-; the single-file objcopy step, their global helper symbols would collide
 826-; once linked into one binary. a partial link (ld -r) resolves those
 827-; internal references first, then main gets renamed and the rest hidden
 828-;
 829-; Combined objects use the layout .box/cmd/<category>/<tool>.o so genbox.sh
 830-; can parse them without structural modifications
 831-;
 832-(rule POSIX_BC_BOX_OBJ
 833+  ; POSIX_BC, POSIX_AWK, POSIX_SH, POSIX_MAKE, and EXTRA_YAP cant go through
 834+  ; the single-file objcopy step, their global helper symbols would collide
 835+  ; once linked into one binary. a partial link (ld -r) resolves those
 836+  ; internal references first, then main gets renamed and the rest hidden
 837+  ;
 838+  ; combined objects use the layout .box/cmd/<category>/<tool>.o so genbox.sh
 839+  ; can parse them without structural modifications
 840+  ;
 841+  (rule POSIX_BC_BOX_OBJ
 842   (glob "cmd/posix/bc.c")
 843   (gate build_posix_bc)
 844   (dep $(MATCH))
 845@@ -546,7 +657,7 @@
 846   (out ".box/parts/$(STEM).o")
 847   (exec $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $(OUT) $(MATCH)))
 848 
 849-(rule POSIX_BC_BOX
 850+  (rule POSIX_BC_BOX
 851   (gate build_posix_bc)
 852   (dep POSIX_BC_BOX_OBJ)
 853   (out ".box/cmd/posix/bc.o")
 854@@ -554,7 +665,7 @@
 855   (shell "$(LD) -r -o $(OUT) $(IN) && $(OBJCOPY) --redefine-sym main=bc_main $(OUT) && $(OBJCOPY) --keep-global-symbol=bc_main $(OUT)")
 856   (group box))
 857 
 858-(rule POSIX_AWK_BOX_OBJ
 859+  (rule POSIX_AWK_BOX_OBJ
 860   (glob "cmd/posix/awk/*.c")
 861   (gate build_posix_awk)
 862   (skip "maketab.c")
 863@@ -563,7 +674,7 @@
 864   (out ".box/parts/$(STEM).o")
 865   (exec $(CC) $(CPPFLAGS) -Icmd/posix/awk $(CFLAGS) -c -o $(OUT) $(MATCH)))
 866 
 867-(rule POSIX_AWK_BOX
 868+  (rule POSIX_AWK_BOX
 869   (gate build_posix_awk)
 870   (dep POSIX_AWK_BOX_OBJ)
 871   (out ".box/cmd/posix/awk.o")
 872@@ -571,7 +682,7 @@
 873   (shell "$(LD) -r -o $(OUT) $(IN) && $(OBJCOPY) --redefine-sym main=awk_main $(OUT) && $(OBJCOPY) --keep-global-symbol=awk_main $(OUT)")
 874   (group box))
 875 
 876-(rule POSIX_SH_BOX_OBJ
 877+  (rule POSIX_SH_BOX_OBJ
 878   (glob "cmd/posix/sh/*.c")
 879   (gate build_posix_sh)
 880   (skip "mknodes.c" "mksyntax.c")
 881@@ -580,7 +691,7 @@
 882   (out ".box/parts/$(STEM).o")
 883   (exec $(CC) $(CPPFLAGS) -DSHELL -Icmd/posix/sh $(CFLAGS) -c -o $(OUT) $(MATCH)))
 884 
 885-(rule POSIX_SH_BOX
 886+  (rule POSIX_SH_BOX
 887   (gate build_posix_sh)
 888   (dep POSIX_SH_BOX_OBJ)
 889   (out ".box/cmd/posix/sh.o")
 890@@ -588,14 +699,14 @@
 891   (shell "$(LD) -r -o $(OUT) $(IN) && $(OBJCOPY) --redefine-sym main=sh_main $(OUT) && $(OBJCOPY) --keep-global-symbol=sh_main $(OUT)")
 892   (group box))
 893 
 894-(rule POSIX_MAKE_BOX_OBJ
 895+  (rule POSIX_MAKE_BOX_OBJ
 896   (glob "cmd/posix/make/*.c")
 897   (gate build_posix_make)
 898   (dep $(MATCH))
 899   (out ".box/parts/$(STEM).o")
 900   (exec $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $(OUT) $(MATCH)))
 901 
 902-(rule POSIX_MAKE_BOX
 903+  (rule POSIX_MAKE_BOX
 904   (gate build_posix_make)
 905   (dep POSIX_MAKE_BOX_OBJ)
 906   (out ".box/cmd/posix/make.o")
 907@@ -603,14 +714,14 @@
 908   (shell "$(LD) -r -o $(OUT) $(IN) && $(OBJCOPY) --redefine-sym main=make_main $(OUT) && $(OBJCOPY) --keep-global-symbol=make_main $(OUT)")
 909   (group box))
 910 
 911-(rule EXTRA_YAP_BOX_OBJ
 912+  (rule EXTRA_YAP_BOX_OBJ
 913   (glob "cmd/extra/yap/*.c")
 914   (gate build_extra_yap)
 915   (dep $(MATCH))
 916   (out ".box/parts/$(STEM).o")
 917   (exec $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $(OUT) $(MATCH)))
 918 
 919-(rule EXTRA_YAP_BOX
 920+  (rule EXTRA_YAP_BOX
 921   (gate build_extra_yap)
 922   (dep EXTRA_YAP_BOX_OBJ)
 923   (out ".box/cmd/extra/yap.o")
 924@@ -618,11 +729,11 @@
 925   (shell "$(LD) -r -o $(OUT) $(IN) && $(OBJCOPY) --redefine-sym main=yap_main $(OUT) && $(OBJCOPY) --keep-global-symbol=yap_main $(OUT)")
 926   (group box))
 927 
 928-; Genbox.sh relies on arguments passed by ninqu, where each argument matches
 929-; an output from BOX_OBJ or a custom box rule. The script derives categories
 930-; and tool names directly from these paths and outputs the dispatch code
 931-;
 932-(rule BOX_DISPATCH
 933+  ; genbox.sh relies on arguments passed by ninqu, where each argument matches
 934+  ; an output from BOX_OBJ or a custom box rule. the script derives categories
 935+  ; and tool names directly from these paths and outputs the dispatch code
 936+  ;
 937+  (rule BOX_DISPATCH
 938   (dep BOX_OBJ POSIX_BC_BOX POSIX_AWK_BOX POSIX_SH_BOX POSIX_MAKE_BOX EXTRA_YAP_BOX NINQU_BOX_OBJ)
 939   (out ".box/aruu-box.c")
 940   (description "dispatch table and main() for aruu-box, generated from the enabled tool list")
 941@@ -630,49 +741,49 @@
 942   (redirect)
 943   (group box))
 944 
 945-; Libm is linked unconditionally because bc requires it, and unused library
 946-; references are safe. Modern toolchains omit unreferenced archive components.
 947-; Yap requires terminfo, which is an optional system dependency. Linking it
 948-; unconditionally breaks builds on systems without ncurses-dev when yap is
 949-; disabled. Genconfig.sh exports BOX_EXTRA_LIBS as "-ltinfo" or an empty string
 950-; based on whether yap is enabled
 951-;
 952-(rule BOX
 953+  ; libm is linked unconditionally because bc requires it, and unused library
 954+  ; references are safe. modern toolchains omit unreferenced archive components
 955+  ; yap requires terminfo, which is an optional system dependency. linking it
 956+  ; unconditionally breaks builds on systems without ncurses-dev when yap is
 957+  ; disabled. genconfig.sh exports BOX_EXTRA_LIBS as "-ltinfo" or an empty string
 958+  ; based on whether yap is enabled
 959+  ;
 960+  (rule BOX
 961   (dep BOX_DISPATCH BOX_OBJ POSIX_BC_BOX POSIX_AWK_BOX POSIX_SH_BOX POSIX_MAKE_BOX EXTRA_YAP_BOX NINQU_BOX_OBJ LIBUTIL LIBUTF LIBREDLINE)
 962   (out "aruu-box")
 963   (description "single multi-call binary, one dispatch table for every enabled tool")
 964   (shell "$(CC) $(CPPFLAGS) $(CFLAGS) -o $(OUT) $(IN) $(LDFLAGS) $(LDLIBS) $(BOX_EXTRA_LIBS)")
 965   (group box))
 966 
 967-(group box BOX)
 968+  (group box BOX)
 969 
 970-; -------------------------------------------------------------------
 971-; top level. (group all) contains every build target except clean
 972-; and box. box is separate because it produces a different binary
 973-; with different .o files, and mixing it with standalone builds
 974-; would cause confusion. clean is never in all because it removes
 975-; what all builds
 976-; -------------------------------------------------------------------
 977+  ; -------------------------------------------------------------------
 978+  ; top level. (group all) contains every build target except clean
 979+  ; and box. box is separate because it produces a different binary
 980+  ; with different .o files, and mixing it with standalone builds
 981+  ; would cause confusion. clean is never in all because it removes
 982+  ; what all builds
 983+  ; -------------------------------------------------------------------
 984 
 985-(rule ALL_BINS
 986+  (rule ALL_BINS
 987   (phony)
 988   (after LIBUTIL LIBUTF LIBREDLINE
 989-         POSIX_BIN LINUX_BIN NET_BIN XSI_BIN
 990-         PSEUDO_BIN EXTRA_BIN
 991-         POSIX_BC POSIX_AWK POSIX_SH POSIX_MAKE EXTRA_YAP
 992-         AR AS LD CC1 CPP CCDRV)
 993+  POSIX_BIN LINUX_BIN NET_BIN XSI_BIN
 994+  PSEUDO_BIN EXTRA_BIN
 995+  POSIX_BC POSIX_AWK POSIX_SH POSIX_MAKE EXTRA_YAP
 996+  AR AS LD CC1 CPP CCDRV)
 997   (exec true))
 998 
 999-(group all ALL_BINS)
1000+  (group all ALL_BINS)
1001 
1002-(group default all)
1003+  (group default all)
1004 
1005-; meta-targets: apply an override, then build a normal target under
1006-; it. invoke as `ninqu META.TARGET` (`ninqu debug.posix`) or bare
1007-; `ninqu META` to apply the override and build (group default)
1008-;
1009-(meta debug
1010+  ; meta-targets: apply an override, then build a normal target under
1011+  ; it. invoke as `ninqu META.TARGET` (`ninqu debug.posix`) or bare
1012+  ; `ninqu META` to apply the override and build (group default)
1013+  ;
1014+  (meta debug
1015   (set CFLAGS "$(CFLAGS) -g -O0"))
1016 
1017-(meta release
1018+  (meta release
1019   (set CFLAGS "$(CFLAGS) -O2 -DNDEBUG"))
+8, -11
 1@@ -2,7 +2,7 @@
 2 # genbox.sh - generate the aruu-box dispatch table
 3 #
 4 # does one thing: given a list of object file paths on argv, each one
 5-# of BOX_OBJ's own outputs (".box/cmd/<category>/<tool>.o"), emit the C
 6+# of BOX_OBJ's own outputs (".box/cmd/<category>/<tool>.o"), emit the c
 7 # source for aruu-box's dispatch table and main() on stdout
 8 #
 9 set -e
10@@ -12,7 +12,7 @@ set -e
11         exit 1
12 }
13 
14-# derive category, tool basestem, and C symbol from one BOX_OBJ output
15+# derive category, tool basestem, and c symbol from one BOX_OBJ output
16 # path. the symbol transform (tr '.-' '__', append _main) must match
17 # BOX_OBJ's own objcopy step exactly, see the CATEGORY_OF/symbol
18 # comment in ninqu.rules for why this is a shell transform and not a
19@@ -35,13 +35,13 @@ path_symbol() {
20 cat << 'HEAD'
21 /* this file is autogenerated by genbox.sh. do not edit */
22 
23-#include "wexec.h"
24-#include "util.h"
25+# include "wexec.h"
26+# include "util.h"
27 
28-#include <stdio.h>
29-#include <stdlib.h>
30-#include <string.h>
31-#include <unistd.h>
32+# include <stdio.h>
33+# include <stdlib.h>
34+# include <string.h>
35+# include <unistd.h>
36 
37 HEAD
38 
39@@ -78,9 +78,6 @@ for category in $categories; do
40                 if [ "$tool" = "test" ]; then
41                         printf '\t{ "[", %s, "%s" },\n' "$sym" "$category"
42                 fi
43-                if [ "$tool" = "xinstall" ]; then
44-                        printf '\t{ "install", %s, "%s" },\n' "$sym" "$category"
45-                fi
46         done
47 done
48 
+24, -24
 1@@ -3,24 +3,24 @@
 2 #
 3 # outputs four files:
 4 #
 5-#   scripts/mk/config.set   ninqu reads this via (set-file). flat
 6-#                           KEY=VAL, unquoted. per-tool BUILD_CATEGORY_TOOL
 7-#                           toggles get a lowercase alias here, since
 8-#                           (gate ...) in ninqu.rules only ever checks
 9-#                           the lowercase form
10+# scripts/mk/config.set ninqu reads this via (set-file). flat
11+# KEY=VAL, unquoted. per-tool BUILD_CATEGORY_TOOL
12+# toggles get a lowercase alias here, since
13+# (gate ...) in ninqu.rules only ever checks
14+# the lowercase form
15 #
16-#   scripts/mk/config.kv    shell-quoted KEY="VAL" format. sourced by
17-#                           read via the -config flag by scripts/mkman.
18-#                           nothing in the ninqu build itself sources
19-#                           this file: genbox.sh takes its input on argv
20-#                           only, see the BOX section of ninqu.rules
21+# scripts/mk/config.kv shell-quoted KEY="VAL" format. sourced by
22+# read via the -config flag by scripts/mkman
23+# nothing in the ninqu build itself sources
24+# this file: genbox.sh takes its input on argv
25+# only, see the BOX section of ninqu.rules
26 #
27-#   shared/libutil/nofork_list.h
28-#                           wexec.c includes this at compile time.
29-#                           generated from NOFORK_LIST in build.cfg
30+# shared/libutil/nofork_list.h
31+# wexec.c includes this at compile time
32+# generated from NOFORK_LIST in build.cfg
33 #
34-#   scripts/mk/features.h   every resolved FEATURE_* as a #define
35-#                           CPPFLAGS pulls this in with -include
36+# scripts/mk/features.h every resolved FEATURE_* as a #define
37+# CPPFLAGS pulls this in with -include
38 #
39 # the codegen subcommands (getconf, bc, awk, sh) are also here so
40 # ninqu.rules can call (exec sh scripts/genconfig.sh <step>) for
41@@ -201,11 +201,11 @@ config() {
42         emit LDFLAGS_TLS  "${LDFLAGS_TLS:-}"
43         emit LDLIBS_TLS   "${LDLIBS_TLS:-}"
44 
45-        # For when ninqu builds itself, otherwise it won't have this value
46+        # for when ninqu builds itself, otherwise it wont have this value
47         emit NINJA_TRY "${NINJA_TRY:-samu,ninja}"
48 
49-        # these seven are only consulted per-tool below (build_CATEGORY_TOOL,
50-        # build_CATEGORY_$(BASESTEM)).
51+        # these seven are only consulted per-tool below (build_category_tool,
52+        # build_category_$(basestem))
53         for g in BUILD_POSIX BUILD_XSI BUILD_NET BUILD_PSEUDO BUILD_EXTRA BUILD_LINUX BUILD_DEV; do
54                 eval "val=\${$g:-0}"
55                 echo "${g}=\"${val}\"" >> "${kv_file}"
56@@ -240,9 +240,9 @@ config() {
57                         u_tool=$(echo "$b" | tr 'a-z-' 'A-Z_')
58                         var_name="BUILD_${u_category}_${u_tool}"
59 
60-                        #if [ "$category" = "dev" ] && [ "$u_tool" = "AS" ]; then
61-                        #        var_name="BUILD_DEV_CC"
62-                        #fi
63+                        # if [ "$category" = "dev" ] && [ "$u_tool" = "AS" ]; then
64+                        # var_name="build_dev_cc"
65+                        # fi
66 
67                         eval "has_override=\${$var_name+yes}"
68                         if [ "$has_override" = "yes" ]; then
69@@ -280,13 +280,13 @@ config() {
70         # header. config.h's own #ifndef guards still apply to anything
71         # not here (there is nothing not here), and any file gets the
72         # real values just by being compiled with -include, whether or
73-        # not it bothers to #include "config.h" itself.
74+        # not it bothers to #include "config.h" itself
75         features_h="scripts/mk/features.h"
76         {
77                 echo "/* autogenerated by genconfig.sh, do not edit */"
78                 for f in $features; do
79                         eval "fval=\$$f"
80-                        echo "#define ${f} ${fval}"
81+                        echo "# define ${f} ${fval}"
82                 done
83         } > "${features_h}"
84 
85@@ -296,7 +296,7 @@ config() {
86         echo "CPPFLAGS=${cppflags_set}" >> "${set_file}"
87 
88         # shared/tls.h would conflict with the system's tls.h
89-        # if we passed -Ishared to build libutil
90+        # if we passed -ishared to build libutil
91         echo "CPPFLAGS_LIBUTIL=\"${cppflags_common}\"" >> "${kv_file}"
92         echo "CPPFLAGS_LIBUTIL=${cppflags_common}" >> "${set_file}"
93 
+1, -1
1@@ -2,7 +2,7 @@
2 
3 ifdef() {
4 	printf 'static const struct var %s[] = {\n' "$1"
5-	awk '{printf("#ifdef %s\n\t{\"%s\",\t%s},\n#endif\n", $2, $1, $2)}'
6+	awk '{printf("# ifdef %s\n\t{\"%s\",\t%s},\n#endif\n", $2, $1, $2)}'
7 	echo '};'
8 }
9 
+1, -1
1@@ -142,7 +142,7 @@ func inferSection(path string) int {
2 	}
3 }
4 
5-// a Renderer turns a parsed Page into one output format on os.Stdout
6+// a renderer turns a parsed page into one output format on os.stdout
7 type Renderer interface {
8 	Render() error
9 }
+5, -5
 1@@ -70,7 +70,7 @@ func extractManLines(path string, cfg Config) ([]string, error) {
 2 
 3 		if strings.HasPrefix(trimmed, "#") {
 4 			directive := trimmed[1:]
 5-			if ci := strings.Index(directive, "//"); ci >= 0 {
 6+			if ci := strings.Index(directive, "// "); ci >= 0 {
 7 				directive = directive[:ci]
 8 			}
 9 			directive = strings.TrimSpace(directive)
10@@ -120,7 +120,7 @@ func extractManLines(path string, cfg Config) ([]string, error) {
11 		if strings.Contains(trimmed, "/* ?man") {
12 			startIdx := strings.Index(trimmed, "/* ?man")
13 			rest := strings.TrimSpace(trimmed[startIdx+7:])
14-			if strings.HasSuffix(rest, "*/") {
15+			if strings.HasSuffix(rest, " */") {
16 				lines = append(lines, strings.TrimSpace(rest[:len(rest)-2]))
17 			} else {
18 				lines = append(lines, rest)
19@@ -318,7 +318,7 @@ func parseOption(line string) (Option, bool) {
20 	}, true
21 }
22 
23-// splitOptionSpec peels the required marker (!) and the mutual exclusion
24+// splitoptionspec peels the required marker (!) and the mutual exclusion
25 // group marker ({name}) off a raw option spec, leaving the bare flag and
26 // its optional colon-delimited type suffix
27 func splitOptionSpec(raw string) (flag, typ, group string, required bool) {
28@@ -947,8 +947,8 @@ func parseSynopsisSeq(tokens []string, start int, explicit bool, topLevel bool)
29 }
30 
31 func splitGroupedFlags(tok string) ([]SynopsisItem, bool) {
32-	// we expand compacted synopsis tokens like some -abcDef into separate
33-	// semantic flags so the renderer can emit a separate Fl for each one
34+	// we expand compacted synopsis tokens like some -abcdef into separate
35+	// semantic flags so the renderer can emit a separate fl for each one
36 	if len(tok) < 3 || tok[0] != '-' {
37 		return nil, false
38 	}
+3, -3
 1@@ -7,7 +7,7 @@ import (
 2 )
 3 
 4 // fixed-width ascii layout, matching the column widths a classic
 5-// nroff -Tascii rendering of an mdoc page would produce
 6+// nroff -tascii rendering of an mdoc page would produce
 7 const (
 8 	txtWidth     = 78
 9 	txtIndent    = 7
10@@ -132,7 +132,7 @@ func (r *TxtRenderer) renderBlock(block Block, indent int) {
11 	}
12 }
13 
14-// writeIndented word-wraps text to the page width minus indent, then
15+// writeindented word-wraps text to the page width minus indent, then
16 // writes each line prefixed by indent spaces
17 func (r *TxtRenderer) writeIndented(text string, indent int) {
18 	width := txtWidth - indent
19@@ -166,7 +166,7 @@ func wrapWords(text string, width int) []string {
20 	return lines
21 }
22 
23-// renderSynopsisItemsTxt mirrors renderSynopsisPhrase from mdoc.go but
24+// rendersynopsisitemstxt mirrors rendersynopsisphrase from mdoc.go but
25 // writes literal brackets and braces instead of mdoc macros
26 func renderSynopsisItemsTxt(items []SynopsisItem) string {
27 	var parts []string
+2, -2
 1@@ -1,5 +1,5 @@
 2 /*
 3- * Copy me if you can.
 4+ * copy me if you can
 5  * by 20h
 6  */
 7 
 8@@ -26,7 +26,7 @@ extern char *argv0;
 9       argc_ = argv[0][0];                                                                          \
10       switch (argc_)
11 
12-/* Handles obsolete -NUM syntax */
13+/* handles obsolete -NUM syntax */
14 #define ARGNUM                                                                                     \
15   case '0':                                                                                        \
16   case '1':                                                                                        \
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <limits.h>
5 
6 #ifndef HOST_NAME_MAX
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include "paths.h"
5 
6 #define ENV_PATH  ARUU_PATH_BIN
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <stdint.h>
5 struct crypt_ops {
6   void (*init)(void *);
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #ifndef ARUU_DIFFUTIL_H
5 #define ARUU_DIFFUTIL_H
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #ifndef ARUU_DISKUTIL_H
5 #define ARUU_DISKUTIL_H
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <limits.h>
5 #include <sys/stat.h>
6 #include <sys/types.h>
+177, -0
  1@@ -0,0 +1,177 @@
  2+/* x86-64 out-of-line atomic helpers, called by cc1-emitted code for
  3+ * __atomic_* builtins (see cmd/dev/cc/qbe.c's mkatomicfn). every
  4+ * memory order argument is treated as seq_cst: a conservative choice
  5+ * that is always standards-conformant, only ever slower than what a
  6+ * weaker order would allow. matches the real gcc/clang libatomic
  7+ * fallback abi (out-of-line calls for sizes the compiler does not
  8+ * inline directly), size-suffixed per operation, so any future
  9+ * inlining work can drop straight in without changing callers
 10+ */
 11+
 12+.text
 13+
 14+.globl __atomic_load_4
 15+__atomic_load_4:
 16+	movl (%rdi), %eax
 17+	ret
 18+
 19+.globl __atomic_load_8
 20+__atomic_load_8:
 21+	movq (%rdi), %rax
 22+	ret
 23+
 24+/* plain store already has release ordering on x86-64; mfence upgrades
 25+ * it to full seq_cst, ordering it against a later seq_cst load
 26+ */
 27+.globl __atomic_store_4
 28+__atomic_store_4:
 29+	movl %esi, (%rdi)
 30+	mfence
 31+	ret
 32+
 33+.globl __atomic_store_8
 34+__atomic_store_8:
 35+	movq %rsi, (%rdi)
 36+	mfence
 37+	ret
 38+
 39+/* xchg with a memory operand is implicitly locked, no explicit lock
 40+ * prefix needed
 41+ */
 42+.globl __atomic_exchange_4
 43+__atomic_exchange_4:
 44+	movl %esi, %eax
 45+	xchg %eax, (%rdi)
 46+	ret
 47+
 48+.globl __atomic_exchange_8
 49+__atomic_exchange_8:
 50+	movq %rsi, %rax
 51+	xchg %rax, (%rdi)
 52+	ret
 53+
 54+.globl __atomic_fetch_add_4
 55+__atomic_fetch_add_4:
 56+	movl %esi, %eax
 57+	lock xadd %eax, (%rdi)
 58+	ret
 59+
 60+.globl __atomic_fetch_add_8
 61+__atomic_fetch_add_8:
 62+	movq %rsi, %rax
 63+	lock xadd %rax, (%rdi)
 64+	ret
 65+
 66+.globl __atomic_fetch_sub_4
 67+__atomic_fetch_sub_4:
 68+	neg %esi
 69+	movl %esi, %eax
 70+	lock xadd %eax, (%rdi)
 71+	ret
 72+
 73+.globl __atomic_fetch_sub_8
 74+__atomic_fetch_sub_8:
 75+	neg %rsi
 76+	movq %rsi, %rax
 77+	lock xadd %rax, (%rdi)
 78+	ret
 79+
 80+/* no single locked fetch-and-op instruction exists for and/or/xor:
 81+ * load, compute the new value, lock cmpxchg it in, retry on failure
 82+ * (another cpu changed *ptr in between). on a successful cmpxchg eax
 83+ * is left unmodified, which is exactly the old value fetch-and-op
 84+ * must return; on failure eax is reloaded with the real current
 85+ * value by the instruction itself, which is exactly what the retry
 86+ * needs
 87+ */
 88+.globl __atomic_fetch_and_4
 89+__atomic_fetch_and_4:
 90+	movl (%rdi), %eax
 91+.Lretry_and_4:
 92+	movl %eax, %ecx
 93+	andl %esi, %ecx
 94+	lock cmpxchg %ecx, (%rdi)
 95+	jnz .Lretry_and_4
 96+	ret
 97+
 98+.globl __atomic_fetch_and_8
 99+__atomic_fetch_and_8:
100+	movq (%rdi), %rax
101+.Lretry_and_8:
102+	movq %rax, %rcx
103+	andq %rsi, %rcx
104+	lock cmpxchg %rcx, (%rdi)
105+	jnz .Lretry_and_8
106+	ret
107+
108+.globl __atomic_fetch_or_4
109+__atomic_fetch_or_4:
110+	movl (%rdi), %eax
111+.Lretry_or_4:
112+	movl %eax, %ecx
113+	orl %esi, %ecx
114+	lock cmpxchg %ecx, (%rdi)
115+	jnz .Lretry_or_4
116+	ret
117+
118+.globl __atomic_fetch_or_8
119+__atomic_fetch_or_8:
120+	movq (%rdi), %rax
121+.Lretry_or_8:
122+	movq %rax, %rcx
123+	orq %rsi, %rcx
124+	lock cmpxchg %rcx, (%rdi)
125+	jnz .Lretry_or_8
126+	ret
127+
128+.globl __atomic_fetch_xor_4
129+__atomic_fetch_xor_4:
130+	movl (%rdi), %eax
131+.Lretry_xor_4:
132+	movl %eax, %ecx
133+	xor %esi, %ecx
134+	lock cmpxchg %ecx, (%rdi)
135+	jnz .Lretry_xor_4
136+	ret
137+
138+.globl __atomic_fetch_xor_8
139+__atomic_fetch_xor_8:
140+	movq (%rdi), %rax
141+.Lretry_xor_8:
142+	movq %rax, %rcx
143+	xor %rsi, %rcx
144+	lock cmpxchg %rcx, (%rdi)
145+	jnz .Lretry_xor_8
146+	ret
147+
148+/* __atomic_compare_exchange_N(ptr, expected, desired): the accumulator
149+ * is loaded from *expected before cmpxchg, exactly matching the
150+ * instructions own semantics (compare accumulator against *ptr; on
151+ * match store desired and set zf; on mismatch load the accumulators
152+ * own register with *ptrs real value and clear zf), so success needs
153+ * no extra work at all and failure only needs writing the reloaded
154+ * accumulator back out to *expected
155+ */
156+.globl __atomic_compare_exchange_4
157+__atomic_compare_exchange_4:
158+	movl (%rsi), %eax
159+	lock cmpxchg %edx, (%rdi)
160+	jz .Lcas4_ok
161+	movl %eax, (%rsi)
162+	movl $0, %eax
163+	ret
164+.Lcas4_ok:
165+	movl $1, %eax
166+	ret
167+
168+.globl __atomic_compare_exchange_8
169+__atomic_compare_exchange_8:
170+	movq (%rsi), %rax
171+	lock cmpxchg %rdx, (%rdi)
172+	jz .Lcas8_ok
173+	movq %rax, (%rsi)
174+	movl $0, %eax
175+	ret
176+.Lcas8_ok:
177+	movl $1, %eax
178+	ret
+4525, -0
   1@@ -0,0 +1,4525 @@
   2+/* see LICENSE file for copyright and license details */
   3+
   4+#if defined(__x86_64__) && (defined(__clang__) || (defined(__GNUC__) && !defined(__TINYC__)))
   5+#define BLAKE3_X86_SIMD 1
   6+#else
   7+#define BLAKE3_X86_SIMD 0
   8+#endif
   9+
  10+#include "blake3.h"
  11+
  12+#include <assert.h>
  13+#if BLAKE3_X86_SIMD
  14+#include <immintrin.h>
  15+#endif
  16+#include <stdint.h>
  17+#include <string.h>
  18+
  19+#define BLAKE3_VERSION_STRING "1.5.0"
  20+
  21+#if BLAKE3_X86_SIMD
  22+#define MAX_SIMD_DEGREE 16
  23+#else
  24+#define MAX_SIMD_DEGREE 1
  25+#endif
  26+
  27+#define MAX_SIMD_DEGREE_OR_2 (MAX_SIMD_DEGREE > 2 ? MAX_SIMD_DEGREE : 2)
  28+
  29+enum Blake3Flags {
  30+  CHUNK_START         = 1 << 0,
  31+  CHUNK_END           = 1 << 1,
  32+  PARENT              = 1 << 2,
  33+  ROOT                = 1 << 3,
  34+  KEYED_HASH          = 1 << 4,
  35+  DERIVE_KEY_CONTEXT  = 1 << 5,
  36+  DERIVE_KEY_MATERIAL = 1 << 6
  37+};
  38+
  39+struct Output {
  40+  uint32_t input_cv[8];
  41+  uint64_t counter;
  42+  uint8_t  block[BLAKE3_BLOCK_LEN];
  43+  uint8_t  block_len;
  44+  uint8_t  flags;
  45+};
  46+
  47+static const uint32_t IV[8] = {
  48+    0x6A09E667UL,
  49+    0xBB67AE85UL,
  50+    0x3C6EF372UL,
  51+    0xA54FF53AUL,
  52+    0x510E527FUL,
  53+    0x9B05688CUL,
  54+    0x1F83D9ABUL,
  55+    0x5BE0CD19UL
  56+};
  57+
  58+static const uint8_t MSG_SCHEDULE[7][16] = {
  59+    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
  60+    {2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8},
  61+    {3, 4, 10, 12, 13, 2, 7, 14, 6, 5, 9, 0, 11, 15, 8, 1},
  62+    {10, 7, 12, 9, 14, 3, 13, 15, 4, 0, 11, 2, 5, 8, 1, 6},
  63+    {12, 13, 9, 11, 15, 10, 14, 8, 7, 2, 5, 3, 0, 1, 6, 4},
  64+    {9, 14, 11, 5, 8, 12, 15, 1, 13, 3, 0, 10, 2, 6, 4, 7},
  65+    {11, 15, 5, 0, 1, 9, 8, 6, 14, 10, 2, 12, 3, 4, 7, 13},
  66+};
  67+
  68+static inline uint32_t
  69+load32(const void *src)
  70+{
  71+  const uint8_t *p = (const uint8_t *)src;
  72+
  73+  return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) | ((uint32_t)(p[2]) << 16)
  74+         | ((uint32_t)(p[3]) << 24);
  75+}
  76+
  77+static inline void
  78+store32(void *dst, uint32_t w)
  79+{
  80+  uint8_t *p = (uint8_t *)dst;
  81+
  82+  p[0] = (uint8_t)(w >> 0);
  83+  p[1] = (uint8_t)(w >> 8);
  84+  p[2] = (uint8_t)(w >> 16);
  85+  p[3] = (uint8_t)(w >> 24);
  86+}
  87+
  88+static inline void
  89+store_cv_words(uint8_t bytes_out[32], uint32_t cv_words[8])
  90+{
  91+  store32(&bytes_out[0 * 4], cv_words[0]);
  92+  store32(&bytes_out[1 * 4], cv_words[1]);
  93+  store32(&bytes_out[2 * 4], cv_words[2]);
  94+  store32(&bytes_out[3 * 4], cv_words[3]);
  95+  store32(&bytes_out[4 * 4], cv_words[4]);
  96+  store32(&bytes_out[5 * 4], cv_words[5]);
  97+  store32(&bytes_out[6 * 4], cv_words[6]);
  98+  store32(&bytes_out[7 * 4], cv_words[7]);
  99+}
 100+
 101+static inline uint32_t
 102+counter_low(uint64_t counter)
 103+{
 104+  return (uint32_t)counter;
 105+}
 106+
 107+static inline uint32_t
 108+counter_high(uint64_t counter)
 109+{
 110+  return (uint32_t)(counter >> 32);
 111+}
 112+
 113+/* forward declarations */
 114+#if BLAKE3_X86_SIMD
 115+void blake3_compress_in_place_sse2(
 116+    uint32_t      cv[8],
 117+    const uint8_t block[BLAKE3_BLOCK_LEN],
 118+    uint8_t       block_len,
 119+    uint64_t      counter,
 120+    uint8_t       flags
 121+);
 122+void blake3_compress_xof_sse2(
 123+    const uint32_t cv[8],
 124+    const uint8_t  block[BLAKE3_BLOCK_LEN],
 125+    uint8_t        block_len,
 126+    uint64_t       counter,
 127+    uint8_t        flags,
 128+    uint8_t        out[64]
 129+);
 130+void blake3_hash_many_sse2(
 131+    const uint8_t *const *inputs,
 132+    size_t                num_inputs,
 133+    size_t                blocks,
 134+    const uint32_t        key[8],
 135+    uint64_t              counter,
 136+    int                   increment_counter,
 137+    uint8_t               flags,
 138+    uint8_t               flags_start,
 139+    uint8_t               flags_end,
 140+    uint8_t              *out
 141+);
 142+
 143+void blake3_compress_in_place_sse41(
 144+    uint32_t      cv[8],
 145+    const uint8_t block[BLAKE3_BLOCK_LEN],
 146+    uint8_t       block_len,
 147+    uint64_t      counter,
 148+    uint8_t       flags
 149+);
 150+void blake3_compress_xof_sse41(
 151+    const uint32_t cv[8],
 152+    const uint8_t  block[BLAKE3_BLOCK_LEN],
 153+    uint8_t        block_len,
 154+    uint64_t       counter,
 155+    uint8_t        flags,
 156+    uint8_t        out[64]
 157+);
 158+void blake3_hash_many_sse41(
 159+    const uint8_t *const *inputs,
 160+    size_t                num_inputs,
 161+    size_t                blocks,
 162+    const uint32_t        key[8],
 163+    uint64_t              counter,
 164+    int                   increment_counter,
 165+    uint8_t               flags,
 166+    uint8_t               flags_start,
 167+    uint8_t               flags_end,
 168+    uint8_t              *out
 169+);
 170+
 171+void blake3_hash_many_avx2(
 172+    const uint8_t *const *inputs,
 173+    size_t                num_inputs,
 174+    size_t                blocks,
 175+    const uint32_t        key[8],
 176+    uint64_t              counter,
 177+    int                   increment_counter,
 178+    uint8_t               flags,
 179+    uint8_t               flags_start,
 180+    uint8_t               flags_end,
 181+    uint8_t              *out
 182+);
 183+
 184+void blake3_compress_in_place_avx512(
 185+    uint32_t      cv[8],
 186+    const uint8_t block[BLAKE3_BLOCK_LEN],
 187+    uint8_t       block_len,
 188+    uint64_t      counter,
 189+    uint8_t       flags
 190+);
 191+void blake3_compress_xof_avx512(
 192+    const uint32_t cv[8],
 193+    const uint8_t  block[BLAKE3_BLOCK_LEN],
 194+    uint8_t        block_len,
 195+    uint64_t       counter,
 196+    uint8_t        flags,
 197+    uint8_t        out[64]
 198+);
 199+void blake3_hash_many_avx512(
 200+    const uint8_t *const *inputs,
 201+    size_t                num_inputs,
 202+    size_t                blocks,
 203+    const uint32_t        key[8],
 204+    uint64_t              counter,
 205+    int                   increment_counter,
 206+    uint8_t               flags,
 207+    uint8_t               flags_start,
 208+    uint8_t               flags_end,
 209+    uint8_t              *out
 210+);
 211+#endif
 212+
 213+void blake3_compress_in_place_portable(
 214+    uint32_t      cv[8],
 215+    const uint8_t block[BLAKE3_BLOCK_LEN],
 216+    uint8_t       block_len,
 217+    uint64_t      counter,
 218+    uint8_t       flags
 219+);
 220+void blake3_compress_xof_portable(
 221+    const uint32_t cv[8],
 222+    const uint8_t  block[BLAKE3_BLOCK_LEN],
 223+    uint8_t        block_len,
 224+    uint64_t       counter,
 225+    uint8_t        flags,
 226+    uint8_t        out[64]
 227+);
 228+void blake3_hash_many_portable(
 229+    const uint8_t *const *inputs,
 230+    size_t                num_inputs,
 231+    size_t                blocks,
 232+    const uint32_t        key[8],
 233+    uint64_t              counter,
 234+    int                   increment_counter,
 235+    uint8_t               flags,
 236+    uint8_t               flags_start,
 237+    uint8_t               flags_end,
 238+    uint8_t              *out
 239+);
 240+
 241+void blake3_compress_in_place(
 242+    uint32_t      cv[8],
 243+    const uint8_t block[BLAKE3_BLOCK_LEN],
 244+    uint8_t       block_len,
 245+    uint64_t      counter,
 246+    uint8_t       flags
 247+);
 248+void blake3_compress_xof(
 249+    const uint32_t cv[8],
 250+    const uint8_t  block[BLAKE3_BLOCK_LEN],
 251+    uint8_t        block_len,
 252+    uint64_t       counter,
 253+    uint8_t        flags,
 254+    uint8_t        out[64]
 255+);
 256+void blake3_hash_many(
 257+    const uint8_t *const *inputs,
 258+    size_t                num_inputs,
 259+    size_t                blocks,
 260+    const uint32_t        key[8],
 261+    uint64_t              counter,
 262+    int                   increment_counter,
 263+    uint8_t               flags,
 264+    uint8_t               flags_start,
 265+    uint8_t               flags_end,
 266+    uint8_t              *out
 267+);
 268+
 269+/* portable implementations */
 270+static inline uint32_t
 271+rotr32(uint32_t w, uint32_t c)
 272+{
 273+  return (w >> c) | (w << (32 - c));
 274+}
 275+
 276+static inline void
 277+g_portable(uint32_t *state, size_t a, size_t b, size_t c, size_t d, uint32_t x, uint32_t y)
 278+{
 279+  state[a] = state[a] + state[b] + x;
 280+  state[d] = rotr32(state[d] ^ state[a], 16);
 281+  state[c] = state[c] + state[d];
 282+  state[b] = rotr32(state[b] ^ state[c], 12);
 283+  state[a] = state[a] + state[b] + y;
 284+  state[d] = rotr32(state[d] ^ state[a], 8);
 285+  state[c] = state[c] + state[d];
 286+  state[b] = rotr32(state[b] ^ state[c], 7);
 287+}
 288+
 289+static inline void
 290+round_fn_portable(uint32_t state[16], const uint32_t *msg, size_t round)
 291+{
 292+  const uint8_t *schedule = MSG_SCHEDULE[round];
 293+
 294+  g_portable(state, 0, 4, 8, 12, msg[schedule[0]], msg[schedule[1]]);
 295+  g_portable(state, 1, 5, 9, 13, msg[schedule[2]], msg[schedule[3]]);
 296+  g_portable(state, 2, 6, 10, 14, msg[schedule[4]], msg[schedule[5]]);
 297+  g_portable(state, 3, 7, 11, 15, msg[schedule[6]], msg[schedule[7]]);
 298+
 299+  g_portable(state, 0, 5, 10, 15, msg[schedule[8]], msg[schedule[9]]);
 300+  g_portable(state, 1, 6, 11, 12, msg[schedule[10]], msg[schedule[11]]);
 301+  g_portable(state, 2, 7, 8, 13, msg[schedule[12]], msg[schedule[13]]);
 302+  g_portable(state, 3, 4, 9, 14, msg[schedule[14]], msg[schedule[15]]);
 303+}
 304+
 305+static inline void
 306+compress_pre_portable(
 307+    uint32_t       state[16],
 308+    const uint32_t cv[8],
 309+    const uint8_t  block[BLAKE3_BLOCK_LEN],
 310+    uint8_t        block_len,
 311+    uint64_t       counter,
 312+    uint8_t        flags
 313+)
 314+{
 315+  uint32_t block_words[16];
 316+
 317+  block_words[0]  = load32(block + 4 * 0);
 318+  block_words[1]  = load32(block + 4 * 1);
 319+  block_words[2]  = load32(block + 4 * 2);
 320+  block_words[3]  = load32(block + 4 * 3);
 321+  block_words[4]  = load32(block + 4 * 4);
 322+  block_words[5]  = load32(block + 4 * 5);
 323+  block_words[6]  = load32(block + 4 * 6);
 324+  block_words[7]  = load32(block + 4 * 7);
 325+  block_words[8]  = load32(block + 4 * 8);
 326+  block_words[9]  = load32(block + 4 * 9);
 327+  block_words[10] = load32(block + 4 * 10);
 328+  block_words[11] = load32(block + 4 * 11);
 329+  block_words[12] = load32(block + 4 * 12);
 330+  block_words[13] = load32(block + 4 * 13);
 331+  block_words[14] = load32(block + 4 * 14);
 332+  block_words[15] = load32(block + 4 * 15);
 333+
 334+  state[0]  = cv[0];
 335+  state[1]  = cv[1];
 336+  state[2]  = cv[2];
 337+  state[3]  = cv[3];
 338+  state[4]  = cv[4];
 339+  state[5]  = cv[5];
 340+  state[6]  = cv[6];
 341+  state[7]  = cv[7];
 342+  state[8]  = IV[0];
 343+  state[9]  = IV[1];
 344+  state[10] = IV[2];
 345+  state[11] = IV[3];
 346+  state[12] = counter_low(counter);
 347+  state[13] = counter_high(counter);
 348+  state[14] = (uint32_t)block_len;
 349+  state[15] = (uint32_t)flags;
 350+
 351+  round_fn_portable(state, &block_words[0], 0);
 352+  round_fn_portable(state, &block_words[0], 1);
 353+  round_fn_portable(state, &block_words[0], 2);
 354+  round_fn_portable(state, &block_words[0], 3);
 355+  round_fn_portable(state, &block_words[0], 4);
 356+  round_fn_portable(state, &block_words[0], 5);
 357+  round_fn_portable(state, &block_words[0], 6);
 358+}
 359+
 360+void
 361+blake3_compress_in_place_portable(
 362+    uint32_t      cv[8],
 363+    const uint8_t block[BLAKE3_BLOCK_LEN],
 364+    uint8_t       block_len,
 365+    uint64_t      counter,
 366+    uint8_t       flags
 367+)
 368+{
 369+  uint32_t state[16];
 370+
 371+  compress_pre_portable(state, cv, block, block_len, counter, flags);
 372+  cv[0] = state[0] ^ state[8];
 373+  cv[1] = state[1] ^ state[9];
 374+  cv[2] = state[2] ^ state[10];
 375+  cv[3] = state[3] ^ state[11];
 376+  cv[4] = state[4] ^ state[12];
 377+  cv[5] = state[5] ^ state[13];
 378+  cv[6] = state[6] ^ state[14];
 379+  cv[7] = state[7] ^ state[15];
 380+}
 381+
 382+void
 383+blake3_compress_xof_portable(
 384+    const uint32_t cv[8],
 385+    const uint8_t  block[BLAKE3_BLOCK_LEN],
 386+    uint8_t        block_len,
 387+    uint64_t       counter,
 388+    uint8_t        flags,
 389+    uint8_t        out[64]
 390+)
 391+{
 392+  uint32_t state[16];
 393+
 394+  compress_pre_portable(state, cv, block, block_len, counter, flags);
 395+
 396+  store32(&out[0 * 4], state[0] ^ state[8]);
 397+  store32(&out[1 * 4], state[1] ^ state[9]);
 398+  store32(&out[2 * 4], state[2] ^ state[10]);
 399+  store32(&out[3 * 4], state[3] ^ state[11]);
 400+  store32(&out[4 * 4], state[4] ^ state[12]);
 401+  store32(&out[5 * 4], state[5] ^ state[13]);
 402+  store32(&out[6 * 4], state[6] ^ state[14]);
 403+  store32(&out[7 * 4], state[7] ^ state[15]);
 404+  store32(&out[8 * 4], state[8] ^ cv[0]);
 405+  store32(&out[9 * 4], state[9] ^ cv[1]);
 406+  store32(&out[10 * 4], state[10] ^ cv[2]);
 407+  store32(&out[11 * 4], state[11] ^ cv[3]);
 408+  store32(&out[12 * 4], state[12] ^ cv[4]);
 409+  store32(&out[13 * 4], state[13] ^ cv[5]);
 410+  store32(&out[14 * 4], state[14] ^ cv[6]);
 411+  store32(&out[15 * 4], state[15] ^ cv[7]);
 412+}
 413+
 414+static inline void
 415+hash_one_portable(
 416+    const uint8_t *input,
 417+    size_t         blocks,
 418+    const uint32_t key[8],
 419+    uint64_t       counter,
 420+    uint8_t        flags,
 421+    uint8_t        flags_start,
 422+    uint8_t        flags_end,
 423+    uint8_t        out[BLAKE3_OUT_LEN]
 424+)
 425+{
 426+  uint32_t cv[8];
 427+  uint8_t  block_flags;
 428+
 429+  memcpy(cv, key, BLAKE3_KEY_LEN);
 430+  block_flags = flags | flags_start;
 431+  while (blocks > 0) {
 432+    if (blocks == 1) {
 433+      block_flags |= flags_end;
 434+    }
 435+    blake3_compress_in_place_portable(cv, input, BLAKE3_BLOCK_LEN, counter, block_flags);
 436+    input = &input[BLAKE3_BLOCK_LEN];
 437+    blocks -= 1;
 438+    block_flags = flags;
 439+  }
 440+  store_cv_words(out, cv);
 441+}
 442+
 443+void
 444+blake3_hash_many_portable(
 445+    const uint8_t *const *inputs,
 446+    size_t                num_inputs,
 447+    size_t                blocks,
 448+    const uint32_t        key[8],
 449+    uint64_t              counter,
 450+    int                   increment_counter,
 451+    uint8_t               flags,
 452+    uint8_t               flags_start,
 453+    uint8_t               flags_end,
 454+    uint8_t              *out
 455+)
 456+{
 457+  while (num_inputs > 0) {
 458+    hash_one_portable(inputs[0], blocks, key, counter, flags, flags_start, flags_end, out);
 459+    if (increment_counter) {
 460+      counter += 1;
 461+    }
 462+    inputs += 1;
 463+    num_inputs -= 1;
 464+    out = &out[BLAKE3_OUT_LEN];
 465+  }
 466+}
 467+
 468+/* cpu features detection */
 469+enum { SSE2 = 1 << 0, SSE41 = 1 << 1, AVX2 = 1 << 2, AVX512 = 1 << 3 };
 470+
 471+static int blake3_cpu_features = 0;
 472+static int blake3_cpu_detected = 0;
 473+
 474+#if BLAKE3_X86_SIMD
 475+#include <cpuid.h>
 476+
 477+static void
 478+blake3_cpuid(uint32_t out[4], uint32_t id, uint32_t sid)
 479+{
 480+  __cpuid_count(id, sid, out[0], out[1], out[2], out[3]);
 481+}
 482+
 483+static uint64_t
 484+blake3_xgetbv(void)
 485+{
 486+  uint32_t eax, edx;
 487+
 488+  __asm__ volatile("xgetbv" : "=a"(eax), "=d"(edx) : "c"(0));
 489+  return ((uint64_t)edx << 32) | eax;
 490+}
 491+#endif
 492+
 493+static void
 494+blake3_detect_cpu_features(void)
 495+{
 496+#if BLAKE3_X86_SIMD
 497+  enum { EAX, EBX, ECX, EDX };
 498+  uint32_t regs[4];
 499+  uint64_t xcr0;
 500+  int      features = 0;
 501+
 502+  blake3_cpuid(regs, 1, 0);
 503+  if (regs[EDX] & (1UL << 26))
 504+    features |= SSE2;
 505+  if (regs[ECX] & (1UL << 19))
 506+    features |= SSE41;
 507+  /* osxsave */
 508+  if (regs[ECX] & (1UL << 27)) {
 509+    blake3_cpuid(regs, 0, 0);
 510+    if (regs[EAX] >= 7) {
 511+      blake3_cpuid(regs, 7, 0);
 512+      xcr0 = blake3_xgetbv();
 513+      /* avx2 and xcr0 sse, avx */
 514+      if ((regs[EBX] & (1UL << 5)) && (xcr0 & 0x06) == 0x06)
 515+        features |= AVX2;
 516+      /* avx512f, avx512vl and xcr0 opmask, zmm_hi256,
 517+ * hi16_zmm */
 518+      if ((regs[EBX] & (1UL << 31 | 1UL << 16)) && (xcr0 & 0xe0) == 0xe0)
 519+        features |= AVX512;
 520+    }
 521+  }
 522+  blake3_cpu_features = features;
 523+#endif
 524+  blake3_cpu_detected = 1;
 525+}
 526+
 527+#if BLAKE3_X86_SIMD
 528+__attribute__((constructor)) static void
 529+blake3_init_cpu(void)
 530+{
 531+  if (!blake3_cpu_detected)
 532+    blake3_detect_cpu_features();
 533+}
 534+#endif
 535+
 536+#if BLAKE3_X86_SIMD
 537+#if defined(__clang__)
 538+#pragma clang attribute push(__attribute__((target("sse2"))), apply_to = function)
 539+#elif defined(__GNUC__)
 540+#pragma GCC push_options
 541+#pragma GCC target("sse2")
 542+#endif
 543+#define DEGREE_SSE2 4
 544+
 545+#define _mm_shuffle_ps2(a, b, c)                                                                   \
 546+  (_mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), (c))))
 547+
 548+static inline __m128i
 549+loadu_sse2(const uint8_t src[16])
 550+{
 551+  return _mm_loadu_si128((const __m128i *)src);
 552+}
 553+
 554+static inline void
 555+storeu_sse2(__m128i src, uint8_t dest[16])
 556+{
 557+  _mm_storeu_si128((__m128i *)dest, src);
 558+}
 559+
 560+static inline __m128i
 561+addv_sse2(__m128i a, __m128i b)
 562+{
 563+  return _mm_add_epi32(a, b);
 564+}
 565+
 566+static inline __m128i
 567+xorv_sse2(__m128i a, __m128i b)
 568+{
 569+  return _mm_xor_si128(a, b);
 570+}
 571+
 572+static inline __m128i
 573+set1_sse2(uint32_t x)
 574+{
 575+  return _mm_set1_epi32((int32_t)x);
 576+}
 577+
 578+static inline __m128i
 579+set4_sse2(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
 580+{
 581+  return _mm_setr_epi32((int32_t)a, (int32_t)b, (int32_t)c, (int32_t)d);
 582+}
 583+
 584+static inline __m128i
 585+rot16_sse2(__m128i x)
 586+{
 587+  return _mm_shufflehi_epi16(_mm_shufflelo_epi16(x, 0xB1), 0xB1);
 588+}
 589+
 590+static inline __m128i
 591+rot12_sse2(__m128i x)
 592+{
 593+  return xorv_sse2(_mm_srli_epi32(x, 12), _mm_slli_epi32(x, 32 - 12));
 594+}
 595+
 596+static inline __m128i
 597+rot8_sse2(__m128i x)
 598+{
 599+  return xorv_sse2(_mm_srli_epi32(x, 8), _mm_slli_epi32(x, 32 - 8));
 600+}
 601+
 602+static inline __m128i
 603+rot7_sse2(__m128i x)
 604+{
 605+  return xorv_sse2(_mm_srli_epi32(x, 7), _mm_slli_epi32(x, 32 - 7));
 606+}
 607+
 608+static inline void
 609+g1_sse2(__m128i *row0, __m128i *row1, __m128i *row2, __m128i *row3, __m128i m)
 610+{
 611+  *row0 = addv_sse2(addv_sse2(*row0, m), *row1);
 612+  *row3 = xorv_sse2(*row3, *row0);
 613+  *row3 = rot16_sse2(*row3);
 614+  *row2 = addv_sse2(*row2, *row3);
 615+  *row1 = xorv_sse2(*row1, *row2);
 616+  *row1 = rot12_sse2(*row1);
 617+}
 618+
 619+static inline void
 620+g2_sse2(__m128i *row0, __m128i *row1, __m128i *row2, __m128i *row3, __m128i m)
 621+{
 622+  *row0 = addv_sse2(addv_sse2(*row0, m), *row1);
 623+  *row3 = xorv_sse2(*row3, *row0);
 624+  *row3 = rot8_sse2(*row3);
 625+  *row2 = addv_sse2(*row2, *row3);
 626+  *row1 = xorv_sse2(*row1, *row2);
 627+  *row1 = rot7_sse2(*row1);
 628+}
 629+
 630+static inline void
 631+diagonalize_sse2(__m128i *row0, __m128i *row2, __m128i *row3)
 632+{
 633+  *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE(2, 1, 0, 3));
 634+  *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE(1, 0, 3, 2));
 635+  *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE(0, 3, 2, 1));
 636+}
 637+
 638+static inline void
 639+undiagonalize_sse2(__m128i *row0, __m128i *row2, __m128i *row3)
 640+{
 641+  *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE(0, 3, 2, 1));
 642+  *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE(1, 0, 3, 2));
 643+  *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE(2, 1, 0, 3));
 644+}
 645+
 646+static inline __m128i
 647+blend_epi16_sse2(__m128i a, __m128i b, const int16_t imm8)
 648+{
 649+  const __m128i bits = _mm_set_epi16(0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01);
 650+  __m128i       mask = _mm_set1_epi16(imm8);
 651+
 652+  mask = _mm_and_si128(mask, bits);
 653+  mask = _mm_cmpeq_epi16(mask, bits);
 654+  return _mm_or_si128(_mm_and_si128(mask, b), _mm_andnot_si128(mask, a));
 655+}
 656+
 657+static inline void
 658+compress_pre_sse2(
 659+    __m128i        rows[4],
 660+    const uint32_t cv[8],
 661+    const uint8_t  block[BLAKE3_BLOCK_LEN],
 662+    uint8_t        block_len,
 663+    uint64_t       counter,
 664+    uint8_t        flags
 665+)
 666+{
 667+  __m128i m0, m1, m2, m3;
 668+  __m128i t0, t1, t2, t3, tt;
 669+
 670+  rows[0] = loadu_sse2((uint8_t *)&cv[0]);
 671+  rows[1] = loadu_sse2((uint8_t *)&cv[4]);
 672+  rows[2] = set4_sse2(IV[0], IV[1], IV[2], IV[3]);
 673+  rows[3] =
 674+      set4_sse2(counter_low(counter), counter_high(counter), (uint32_t)block_len, (uint32_t)flags);
 675+
 676+  m0 = loadu_sse2(&block[sizeof(__m128i) * 0]);
 677+  m1 = loadu_sse2(&block[sizeof(__m128i) * 1]);
 678+  m2 = loadu_sse2(&block[sizeof(__m128i) * 2]);
 679+  m3 = loadu_sse2(&block[sizeof(__m128i) * 3]);
 680+
 681+  /* round 1 */
 682+  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(2, 0, 2, 0));
 683+  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t0);
 684+  t1 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 3, 1));
 685+  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
 686+  diagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 687+  t2 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(2, 0, 2, 0));
 688+  t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2, 1, 0, 3));
 689+  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t2);
 690+  t3 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 1, 3, 1));
 691+  t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(2, 1, 0, 3));
 692+  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
 693+  undiagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 694+  m0 = t0;
 695+  m1 = t1;
 696+  m2 = t2;
 697+  m3 = t3;
 698+
 699+  /* round 2 */
 700+  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
 701+  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
 702+  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t0);
 703+  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
 704+  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
 705+  t1 = blend_epi16_sse2(tt, t1, 0xCC);
 706+  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
 707+  diagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 708+  t2 = _mm_unpacklo_epi64(m3, m1);
 709+  tt = blend_epi16_sse2(t2, m2, 0xC0);
 710+  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
 711+  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t2);
 712+  t3 = _mm_unpackhi_epi32(m1, m3);
 713+  tt = _mm_unpacklo_epi32(m2, t3);
 714+  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
 715+  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
 716+  undiagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 717+  m0 = t0;
 718+  m1 = t1;
 719+  m2 = t2;
 720+  m3 = t3;
 721+
 722+  /* round 3 */
 723+  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
 724+  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
 725+  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t0);
 726+  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
 727+  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
 728+  t1 = blend_epi16_sse2(tt, t1, 0xCC);
 729+  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
 730+  diagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 731+  t2 = _mm_unpacklo_epi64(m3, m1);
 732+  tt = blend_epi16_sse2(t2, m2, 0xC0);
 733+  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
 734+  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t2);
 735+  t3 = _mm_unpackhi_epi32(m1, m3);
 736+  tt = _mm_unpacklo_epi32(m2, t3);
 737+  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
 738+  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
 739+  undiagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 740+  m0 = t0;
 741+  m1 = t1;
 742+  m2 = t2;
 743+  m3 = t3;
 744+
 745+  /* round 4 */
 746+  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
 747+  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
 748+  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t0);
 749+  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
 750+  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
 751+  t1 = blend_epi16_sse2(tt, t1, 0xCC);
 752+  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
 753+  diagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 754+  t2 = _mm_unpacklo_epi64(m3, m1);
 755+  tt = blend_epi16_sse2(t2, m2, 0xC0);
 756+  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
 757+  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t2);
 758+  t3 = _mm_unpackhi_epi32(m1, m3);
 759+  tt = _mm_unpacklo_epi32(m2, t3);
 760+  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
 761+  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
 762+  undiagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 763+  m0 = t0;
 764+  m1 = t1;
 765+  m2 = t2;
 766+  m3 = t3;
 767+
 768+  /* round 5 */
 769+  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
 770+  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
 771+  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t0);
 772+  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
 773+  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
 774+  t1 = blend_epi16_sse2(tt, t1, 0xCC);
 775+  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
 776+  diagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 777+  t2 = _mm_unpacklo_epi64(m3, m1);
 778+  tt = blend_epi16_sse2(t2, m2, 0xC0);
 779+  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
 780+  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t2);
 781+  t3 = _mm_unpackhi_epi32(m1, m3);
 782+  tt = _mm_unpacklo_epi32(m2, t3);
 783+  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
 784+  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
 785+  undiagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 786+  m0 = t0;
 787+  m1 = t1;
 788+  m2 = t2;
 789+  m3 = t3;
 790+
 791+  /* round 6 */
 792+  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
 793+  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
 794+  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t0);
 795+  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
 796+  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
 797+  t1 = blend_epi16_sse2(tt, t1, 0xCC);
 798+  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
 799+  diagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 800+  t2 = _mm_unpacklo_epi64(m3, m1);
 801+  tt = blend_epi16_sse2(t2, m2, 0xC0);
 802+  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
 803+  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t2);
 804+  t3 = _mm_unpackhi_epi32(m1, m3);
 805+  tt = _mm_unpacklo_epi32(m2, t3);
 806+  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
 807+  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
 808+  undiagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 809+  m0 = t0;
 810+  m1 = t1;
 811+  m2 = t2;
 812+  m3 = t3;
 813+
 814+  /* round 7 */
 815+  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
 816+  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
 817+  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t0);
 818+  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
 819+  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
 820+  t1 = blend_epi16_sse2(tt, t1, 0xCC);
 821+  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t1);
 822+  diagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 823+  t2 = _mm_unpacklo_epi64(m3, m1);
 824+  tt = blend_epi16_sse2(t2, m2, 0xC0);
 825+  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
 826+  g1_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t2);
 827+  t3 = _mm_unpackhi_epi32(m1, m3);
 828+  tt = _mm_unpacklo_epi32(m2, t3);
 829+  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
 830+  g2_sse2(&rows[0], &rows[1], &rows[2], &rows[3], t3);
 831+  undiagonalize_sse2(&rows[0], &rows[2], &rows[3]);
 832+}
 833+
 834+void
 835+blake3_compress_in_place_sse2(
 836+    uint32_t      cv[8],
 837+    const uint8_t block[BLAKE3_BLOCK_LEN],
 838+    uint8_t       block_len,
 839+    uint64_t      counter,
 840+    uint8_t       flags
 841+)
 842+{
 843+  __m128i rows[4];
 844+
 845+  compress_pre_sse2(rows, cv, block, block_len, counter, flags);
 846+  storeu_sse2(xorv_sse2(rows[0], rows[2]), (uint8_t *)&cv[0]);
 847+  storeu_sse2(xorv_sse2(rows[1], rows[3]), (uint8_t *)&cv[4]);
 848+}
 849+
 850+void
 851+blake3_compress_xof_sse2(
 852+    const uint32_t cv[8],
 853+    const uint8_t  block[BLAKE3_BLOCK_LEN],
 854+    uint8_t        block_len,
 855+    uint64_t       counter,
 856+    uint8_t        flags,
 857+    uint8_t        out_buf[64]
 858+)
 859+{
 860+  __m128i rows[4];
 861+
 862+  compress_pre_sse2(rows, cv, block, block_len, counter, flags);
 863+  storeu_sse2(xorv_sse2(rows[0], rows[2]), &out_buf[0]);
 864+  storeu_sse2(xorv_sse2(rows[1], rows[3]), &out_buf[16]);
 865+  storeu_sse2(xorv_sse2(rows[2], loadu_sse2((uint8_t *)&cv[0])), &out_buf[32]);
 866+  storeu_sse2(xorv_sse2(rows[3], loadu_sse2((uint8_t *)&cv[4])), &out_buf[48]);
 867+}
 868+
 869+static inline void
 870+round_fn_sse2(__m128i v[16], __m128i m[16], size_t r)
 871+{
 872+  v[0]  = addv_sse2(v[0], m[(size_t)MSG_SCHEDULE[r][0]]);
 873+  v[1]  = addv_sse2(v[1], m[(size_t)MSG_SCHEDULE[r][2]]);
 874+  v[2]  = addv_sse2(v[2], m[(size_t)MSG_SCHEDULE[r][4]]);
 875+  v[3]  = addv_sse2(v[3], m[(size_t)MSG_SCHEDULE[r][6]]);
 876+  v[0]  = addv_sse2(v[0], v[4]);
 877+  v[1]  = addv_sse2(v[1], v[5]);
 878+  v[2]  = addv_sse2(v[2], v[6]);
 879+  v[3]  = addv_sse2(v[3], v[7]);
 880+  v[12] = xorv_sse2(v[12], v[0]);
 881+  v[13] = xorv_sse2(v[13], v[1]);
 882+  v[14] = xorv_sse2(v[14], v[2]);
 883+  v[15] = xorv_sse2(v[15], v[3]);
 884+  v[12] = rot16_sse2(v[12]);
 885+  v[13] = rot16_sse2(v[13]);
 886+  v[14] = rot16_sse2(v[14]);
 887+  v[15] = rot16_sse2(v[15]);
 888+  v[8]  = addv_sse2(v[8], v[12]);
 889+  v[9]  = addv_sse2(v[9], v[13]);
 890+  v[10] = addv_sse2(v[10], v[14]);
 891+  v[11] = addv_sse2(v[11], v[15]);
 892+  v[4]  = xorv_sse2(v[4], v[8]);
 893+  v[5]  = xorv_sse2(v[5], v[9]);
 894+  v[6]  = xorv_sse2(v[6], v[10]);
 895+  v[7]  = xorv_sse2(v[7], v[11]);
 896+  v[4]  = rot12_sse2(v[4]);
 897+  v[5]  = rot12_sse2(v[5]);
 898+  v[6]  = rot12_sse2(v[6]);
 899+  v[7]  = rot12_sse2(v[7]);
 900+  v[0]  = addv_sse2(v[0], m[(size_t)MSG_SCHEDULE[r][1]]);
 901+  v[1]  = addv_sse2(v[1], m[(size_t)MSG_SCHEDULE[r][3]]);
 902+  v[2]  = addv_sse2(v[2], m[(size_t)MSG_SCHEDULE[r][5]]);
 903+  v[3]  = addv_sse2(v[3], m[(size_t)MSG_SCHEDULE[r][7]]);
 904+  v[0]  = addv_sse2(v[0], v[4]);
 905+  v[1]  = addv_sse2(v[1], v[5]);
 906+  v[2]  = addv_sse2(v[2], v[6]);
 907+  v[3]  = addv_sse2(v[3], v[7]);
 908+  v[12] = xorv_sse2(v[12], v[0]);
 909+  v[13] = xorv_sse2(v[13], v[1]);
 910+  v[14] = xorv_sse2(v[14], v[2]);
 911+  v[15] = xorv_sse2(v[15], v[3]);
 912+  v[12] = rot8_sse2(v[12]);
 913+  v[13] = rot8_sse2(v[13]);
 914+  v[14] = rot8_sse2(v[14]);
 915+  v[15] = rot8_sse2(v[15]);
 916+  v[8]  = addv_sse2(v[8], v[12]);
 917+  v[9]  = addv_sse2(v[9], v[13]);
 918+  v[10] = addv_sse2(v[10], v[14]);
 919+  v[11] = addv_sse2(v[11], v[15]);
 920+  v[4]  = xorv_sse2(v[4], v[8]);
 921+  v[5]  = xorv_sse2(v[5], v[9]);
 922+  v[6]  = xorv_sse2(v[6], v[10]);
 923+  v[7]  = xorv_sse2(v[7], v[11]);
 924+  v[4]  = rot7_sse2(v[4]);
 925+  v[5]  = rot7_sse2(v[5]);
 926+  v[6]  = rot7_sse2(v[6]);
 927+  v[7]  = rot7_sse2(v[7]);
 928+
 929+  v[0]  = addv_sse2(v[0], m[(size_t)MSG_SCHEDULE[r][8]]);
 930+  v[1]  = addv_sse2(v[1], m[(size_t)MSG_SCHEDULE[r][10]]);
 931+  v[2]  = addv_sse2(v[2], m[(size_t)MSG_SCHEDULE[r][12]]);
 932+  v[3]  = addv_sse2(v[3], m[(size_t)MSG_SCHEDULE[r][14]]);
 933+  v[0]  = addv_sse2(v[0], v[5]);
 934+  v[1]  = addv_sse2(v[1], v[6]);
 935+  v[2]  = addv_sse2(v[2], v[7]);
 936+  v[3]  = addv_sse2(v[3], v[4]);
 937+  v[15] = xorv_sse2(v[15], v[0]);
 938+  v[12] = xorv_sse2(v[12], v[1]);
 939+  v[13] = xorv_sse2(v[13], v[2]);
 940+  v[14] = xorv_sse2(v[14], v[3]);
 941+  v[15] = rot16_sse2(v[15]);
 942+  v[12] = rot16_sse2(v[12]);
 943+  v[13] = rot16_sse2(v[13]);
 944+  v[14] = rot16_sse2(v[14]);
 945+  v[10] = addv_sse2(v[10], v[15]);
 946+  v[11] = addv_sse2(v[11], v[12]);
 947+  v[8]  = addv_sse2(v[8], v[13]);
 948+  v[9]  = addv_sse2(v[9], v[14]);
 949+  v[5]  = xorv_sse2(v[5], v[10]);
 950+  v[6]  = xorv_sse2(v[6], v[11]);
 951+  v[7]  = xorv_sse2(v[7], v[8]);
 952+  v[4]  = xorv_sse2(v[4], v[9]);
 953+  v[5]  = rot12_sse2(v[5]);
 954+  v[6]  = rot12_sse2(v[6]);
 955+  v[7]  = rot12_sse2(v[7]);
 956+  v[4]  = rot12_sse2(v[4]);
 957+  v[0]  = addv_sse2(v[0], m[(size_t)MSG_SCHEDULE[r][9]]);
 958+  v[1]  = addv_sse2(v[1], m[(size_t)MSG_SCHEDULE[r][11]]);
 959+  v[2]  = addv_sse2(v[2], m[(size_t)MSG_SCHEDULE[r][13]]);
 960+  v[3]  = addv_sse2(v[3], m[(size_t)MSG_SCHEDULE[r][15]]);
 961+  v[0]  = addv_sse2(v[0], v[5]);
 962+  v[1]  = addv_sse2(v[1], v[6]);
 963+  v[2]  = addv_sse2(v[2], v[7]);
 964+  v[3]  = addv_sse2(v[3], v[4]);
 965+  v[15] = xorv_sse2(v[15], v[0]);
 966+  v[12] = xorv_sse2(v[12], v[1]);
 967+  v[13] = xorv_sse2(v[13], v[2]);
 968+  v[14] = xorv_sse2(v[14], v[3]);
 969+  v[15] = rot8_sse2(v[15]);
 970+  v[12] = rot8_sse2(v[12]);
 971+  v[13] = rot8_sse2(v[13]);
 972+  v[14] = rot8_sse2(v[14]);
 973+  v[10] = addv_sse2(v[10], v[15]);
 974+  v[11] = addv_sse2(v[11], v[12]);
 975+  v[8]  = addv_sse2(v[8], v[13]);
 976+  v[9]  = addv_sse2(v[9], v[14]);
 977+  v[5]  = xorv_sse2(v[5], v[10]);
 978+  v[6]  = xorv_sse2(v[6], v[11]);
 979+  v[7]  = xorv_sse2(v[7], v[8]);
 980+  v[4]  = xorv_sse2(v[4], v[9]);
 981+  v[5]  = rot7_sse2(v[5]);
 982+  v[6]  = rot7_sse2(v[6]);
 983+  v[7]  = rot7_sse2(v[7]);
 984+  v[4]  = rot7_sse2(v[4]);
 985+}
 986+
 987+static inline void
 988+transpose_vecs_sse2(__m128i vecs[DEGREE_SSE2])
 989+{
 990+  __m128i ab_01 = _mm_unpacklo_epi32(vecs[0], vecs[1]);
 991+  __m128i ab_23 = _mm_unpackhi_epi32(vecs[0], vecs[1]);
 992+  __m128i cd_01 = _mm_unpacklo_epi32(vecs[2], vecs[3]);
 993+  __m128i cd_23 = _mm_unpackhi_epi32(vecs[2], vecs[3]);
 994+
 995+  __m128i abcd_0 = _mm_unpacklo_epi64(ab_01, cd_01);
 996+  __m128i abcd_1 = _mm_unpackhi_epi64(ab_01, cd_01);
 997+  __m128i abcd_2 = _mm_unpacklo_epi64(ab_23, cd_23);
 998+  __m128i abcd_3 = _mm_unpackhi_epi64(ab_23, cd_23);
 999+
1000+  vecs[0] = abcd_0;
1001+  vecs[1] = abcd_1;
1002+  vecs[2] = abcd_2;
1003+  vecs[3] = abcd_3;
1004+}
1005+
1006+static inline void
1007+transpose_msg_vecs_sse2(const uint8_t *const *inputs, size_t block_offset, __m128i out_msg[16])
1008+{
1009+  size_t i;
1010+
1011+  out_msg[0]  = loadu_sse2(&inputs[0][block_offset + 0 * sizeof(__m128i)]);
1012+  out_msg[1]  = loadu_sse2(&inputs[1][block_offset + 0 * sizeof(__m128i)]);
1013+  out_msg[2]  = loadu_sse2(&inputs[2][block_offset + 0 * sizeof(__m128i)]);
1014+  out_msg[3]  = loadu_sse2(&inputs[3][block_offset + 0 * sizeof(__m128i)]);
1015+  out_msg[4]  = loadu_sse2(&inputs[0][block_offset + 1 * sizeof(__m128i)]);
1016+  out_msg[5]  = loadu_sse2(&inputs[1][block_offset + 1 * sizeof(__m128i)]);
1017+  out_msg[6]  = loadu_sse2(&inputs[2][block_offset + 1 * sizeof(__m128i)]);
1018+  out_msg[7]  = loadu_sse2(&inputs[3][block_offset + 1 * sizeof(__m128i)]);
1019+  out_msg[8]  = loadu_sse2(&inputs[0][block_offset + 2 * sizeof(__m128i)]);
1020+  out_msg[9]  = loadu_sse2(&inputs[1][block_offset + 2 * sizeof(__m128i)]);
1021+  out_msg[10] = loadu_sse2(&inputs[2][block_offset + 2 * sizeof(__m128i)]);
1022+  out_msg[11] = loadu_sse2(&inputs[3][block_offset + 2 * sizeof(__m128i)]);
1023+  out_msg[12] = loadu_sse2(&inputs[0][block_offset + 3 * sizeof(__m128i)]);
1024+  out_msg[13] = loadu_sse2(&inputs[1][block_offset + 3 * sizeof(__m128i)]);
1025+  out_msg[14] = loadu_sse2(&inputs[2][block_offset + 3 * sizeof(__m128i)]);
1026+  out_msg[15] = loadu_sse2(&inputs[3][block_offset + 3 * sizeof(__m128i)]);
1027+
1028+  for (i = 0; i < 4; i++) {
1029+    _mm_prefetch((const void *)&inputs[i][block_offset + 256], _MM_HINT_T0);
1030+  }
1031+  transpose_vecs_sse2(&out_msg[0]);
1032+  transpose_vecs_sse2(&out_msg[4]);
1033+  transpose_vecs_sse2(&out_msg[8]);
1034+  transpose_vecs_sse2(&out_msg[12]);
1035+}
1036+
1037+static inline void
1038+load_counters_sse2(uint64_t counter, int increment_counter, __m128i *out_lo, __m128i *out_hi)
1039+{
1040+  const __m128i mask  = _mm_set1_epi32(-increment_counter);
1041+  const __m128i add0  = _mm_set_epi32(3, 2, 1, 0);
1042+  const __m128i add1  = _mm_and_si128(mask, add0);
1043+  __m128i       l     = _mm_add_epi32(_mm_set1_epi32((int32_t)counter), add1);
1044+  __m128i       carry = _mm_cmpgt_epi32(
1045+      _mm_xor_si128(add1, _mm_set1_epi32(0x80000000)), _mm_xor_si128(l, _mm_set1_epi32(0x80000000))
1046+  );
1047+  __m128i h = _mm_sub_epi32(_mm_set1_epi32((int32_t)(counter >> 32)), carry);
1048+
1049+  *out_lo = l;
1050+  *out_hi = h;
1051+}
1052+
1053+void
1054+blake3_hash4_sse2(
1055+    const uint8_t *const *inputs,
1056+    size_t                blocks,
1057+    const uint32_t        key[8],
1058+    uint64_t              counter,
1059+    int                   increment_counter,
1060+    uint8_t               flags,
1061+    uint8_t               flags_start,
1062+    uint8_t               flags_end,
1063+    uint8_t              *out_bytes
1064+)
1065+{
1066+  __m128i h_vecs[8];
1067+  __m128i counter_low_vec, counter_high_vec;
1068+  uint8_t block_flags;
1069+  size_t  block;
1070+
1071+  h_vecs[0] = set1_sse2(key[0]);
1072+  h_vecs[1] = set1_sse2(key[1]);
1073+  h_vecs[2] = set1_sse2(key[2]);
1074+  h_vecs[3] = set1_sse2(key[3]);
1075+  h_vecs[4] = set1_sse2(key[4]);
1076+  h_vecs[5] = set1_sse2(key[5]);
1077+  h_vecs[6] = set1_sse2(key[6]);
1078+  h_vecs[7] = set1_sse2(key[7]);
1079+
1080+  load_counters_sse2(counter, increment_counter, &counter_low_vec, &counter_high_vec);
1081+  block_flags = flags | flags_start;
1082+
1083+  for (block = 0; block < blocks; block++) {
1084+    __m128i block_len_vec;
1085+    __m128i block_flags_vec;
1086+    __m128i msg_vecs[16];
1087+    __m128i v[16];
1088+
1089+    if (block + 1 == blocks) {
1090+      block_flags |= flags_end;
1091+    }
1092+    block_len_vec   = set1_sse2(BLAKE3_BLOCK_LEN);
1093+    block_flags_vec = set1_sse2(block_flags);
1094+    transpose_msg_vecs_sse2(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs);
1095+
1096+    v[0]  = h_vecs[0];
1097+    v[1]  = h_vecs[1];
1098+    v[2]  = h_vecs[2];
1099+    v[3]  = h_vecs[3];
1100+    v[4]  = h_vecs[4];
1101+    v[5]  = h_vecs[5];
1102+    v[6]  = h_vecs[6];
1103+    v[7]  = h_vecs[7];
1104+    v[8]  = set1_sse2(IV[0]);
1105+    v[9]  = set1_sse2(IV[1]);
1106+    v[10] = set1_sse2(IV[2]);
1107+    v[11] = set1_sse2(IV[3]);
1108+    v[12] = counter_low_vec;
1109+    v[13] = counter_high_vec;
1110+    v[14] = block_len_vec;
1111+    v[15] = block_flags_vec;
1112+
1113+    round_fn_sse2(v, msg_vecs, 0);
1114+    round_fn_sse2(v, msg_vecs, 1);
1115+    round_fn_sse2(v, msg_vecs, 2);
1116+    round_fn_sse2(v, msg_vecs, 3);
1117+    round_fn_sse2(v, msg_vecs, 4);
1118+    round_fn_sse2(v, msg_vecs, 5);
1119+    round_fn_sse2(v, msg_vecs, 6);
1120+
1121+    h_vecs[0] = xorv_sse2(v[0], v[8]);
1122+    h_vecs[1] = xorv_sse2(v[1], v[9]);
1123+    h_vecs[2] = xorv_sse2(v[2], v[10]);
1124+    h_vecs[3] = xorv_sse2(v[3], v[11]);
1125+    h_vecs[4] = xorv_sse2(v[4], v[12]);
1126+    h_vecs[5] = xorv_sse2(v[5], v[13]);
1127+    h_vecs[6] = xorv_sse2(v[6], v[14]);
1128+    h_vecs[7] = xorv_sse2(v[7], v[15]);
1129+
1130+    block_flags = flags;
1131+  }
1132+
1133+  transpose_vecs_sse2(&h_vecs[0]);
1134+  transpose_vecs_sse2(&h_vecs[4]);
1135+  storeu_sse2(h_vecs[0], &out_bytes[0 * sizeof(__m128i)]);
1136+  storeu_sse2(h_vecs[4], &out_bytes[1 * sizeof(__m128i)]);
1137+  storeu_sse2(h_vecs[1], &out_bytes[2 * sizeof(__m128i)]);
1138+  storeu_sse2(h_vecs[5], &out_bytes[3 * sizeof(__m128i)]);
1139+  storeu_sse2(h_vecs[2], &out_bytes[4 * sizeof(__m128i)]);
1140+  storeu_sse2(h_vecs[6], &out_bytes[5 * sizeof(__m128i)]);
1141+  storeu_sse2(h_vecs[3], &out_bytes[6 * sizeof(__m128i)]);
1142+  storeu_sse2(h_vecs[7], &out_bytes[7 * sizeof(__m128i)]);
1143+}
1144+
1145+static inline void
1146+hash_one_sse2(
1147+    const uint8_t *input,
1148+    size_t         blocks,
1149+    const uint32_t key[8],
1150+    uint64_t       counter,
1151+    uint8_t        flags,
1152+    uint8_t        flags_start,
1153+    uint8_t        flags_end,
1154+    uint8_t        out_bytes[BLAKE3_OUT_LEN]
1155+)
1156+{
1157+  uint32_t cv[8];
1158+  uint8_t  block_flags;
1159+
1160+  memcpy(cv, key, BLAKE3_KEY_LEN);
1161+  block_flags = flags | flags_start;
1162+  while (blocks > 0) {
1163+    if (blocks == 1) {
1164+      block_flags |= flags_end;
1165+    }
1166+    blake3_compress_in_place_sse2(cv, input, BLAKE3_BLOCK_LEN, counter, block_flags);
1167+    input = &input[BLAKE3_BLOCK_LEN];
1168+    blocks -= 1;
1169+    block_flags = flags;
1170+  }
1171+  memcpy(out_bytes, cv, BLAKE3_OUT_LEN);
1172+}
1173+
1174+void
1175+blake3_hash_many_sse2(
1176+    const uint8_t *const *inputs,
1177+    size_t                num_inputs,
1178+    size_t                blocks,
1179+    const uint32_t        key[8],
1180+    uint64_t              counter,
1181+    int                   increment_counter,
1182+    uint8_t               flags,
1183+    uint8_t               flags_start,
1184+    uint8_t               flags_end,
1185+    uint8_t              *out_bytes
1186+)
1187+{
1188+  while (num_inputs >= DEGREE_SSE2) {
1189+    blake3_hash4_sse2(
1190+        inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out_bytes
1191+    );
1192+    if (increment_counter) {
1193+      counter += DEGREE_SSE2;
1194+    }
1195+    inputs += DEGREE_SSE2;
1196+    num_inputs -= DEGREE_SSE2;
1197+    out_bytes = &out_bytes[DEGREE_SSE2 * BLAKE3_OUT_LEN];
1198+  }
1199+  while (num_inputs > 0) {
1200+    hash_one_sse2(inputs[0], blocks, key, counter, flags, flags_start, flags_end, out_bytes);
1201+    if (increment_counter) {
1202+      counter += 1;
1203+    }
1204+    inputs += 1;
1205+    num_inputs -= 1;
1206+    out_bytes = &out_bytes[BLAKE3_OUT_LEN];
1207+  }
1208+}
1209+#if defined(__clang__)
1210+#pragma clang attribute pop
1211+#elif defined(__GNUC__)
1212+#pragma GCC pop_options
1213+#endif
1214+
1215+#if defined(__clang__)
1216+#pragma clang attribute push(__attribute__((target("sse4.1"))), apply_to = function)
1217+#elif defined(__GNUC__)
1218+#pragma GCC push_options
1219+#pragma GCC target("sse4.1")
1220+#endif
1221+#define DEGREE_SSE41 4
1222+
1223+#define _mm_shuffle_ps2_sse41(a, b, c)                                                             \
1224+  (_mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), (c))))
1225+
1226+static inline __m128i
1227+loadu_sse41(const uint8_t src[16])
1228+{
1229+  return _mm_loadu_si128((const __m128i *)src);
1230+}
1231+
1232+static inline void
1233+storeu_sse41(__m128i src, uint8_t dest[16])
1234+{
1235+  _mm_storeu_si128((__m128i *)dest, src);
1236+}
1237+
1238+static inline __m128i
1239+addv_sse41(__m128i a, __m128i b)
1240+{
1241+  return _mm_add_epi32(a, b);
1242+}
1243+
1244+static inline __m128i
1245+xorv_sse41(__m128i a, __m128i b)
1246+{
1247+  return _mm_xor_si128(a, b);
1248+}
1249+
1250+static inline __m128i
1251+set1_sse41(uint32_t x)
1252+{
1253+  return _mm_set1_epi32((int32_t)x);
1254+}
1255+
1256+static inline __m128i
1257+set4_sse41(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
1258+{
1259+  return _mm_setr_epi32((int32_t)a, (int32_t)b, (int32_t)c, (int32_t)d);
1260+}
1261+
1262+static inline __m128i
1263+rot16_sse41(__m128i x)
1264+{
1265+  return _mm_shuffle_epi8(x, _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2));
1266+}
1267+
1268+static inline __m128i
1269+rot12_sse41(__m128i x)
1270+{
1271+  return xorv_sse41(_mm_srli_epi32(x, 12), _mm_slli_epi32(x, 32 - 12));
1272+}
1273+
1274+static inline __m128i
1275+rot8_sse41(__m128i x)
1276+{
1277+  return _mm_shuffle_epi8(x, _mm_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1));
1278+}
1279+
1280+static inline __m128i
1281+rot7_sse41(__m128i x)
1282+{
1283+  return xorv_sse41(_mm_srli_epi32(x, 7), _mm_slli_epi32(x, 32 - 7));
1284+}
1285+
1286+static inline void
1287+g1_sse41(__m128i *row0, __m128i *row1, __m128i *row2, __m128i *row3, __m128i m)
1288+{
1289+  *row0 = addv_sse41(addv_sse41(*row0, m), *row1);
1290+  *row3 = xorv_sse41(*row3, *row0);
1291+  *row3 = rot16_sse41(*row3);
1292+  *row2 = addv_sse41(*row2, *row3);
1293+  *row1 = xorv_sse41(*row1, *row2);
1294+  *row1 = rot12_sse41(*row1);
1295+}
1296+
1297+static inline void
1298+g2_sse41(__m128i *row0, __m128i *row1, __m128i *row2, __m128i *row3, __m128i m)
1299+{
1300+  *row0 = addv_sse41(addv_sse41(*row0, m), *row1);
1301+  *row3 = xorv_sse41(*row3, *row0);
1302+  *row3 = rot8_sse41(*row3);
1303+  *row2 = addv_sse41(*row2, *row3);
1304+  *row1 = xorv_sse41(*row1, *row2);
1305+  *row1 = rot7_sse41(*row1);
1306+}
1307+
1308+static inline void
1309+diagonalize_sse41(__m128i *row0, __m128i *row2, __m128i *row3)
1310+{
1311+  *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE(2, 1, 0, 3));
1312+  *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE(1, 0, 3, 2));
1313+  *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE(0, 3, 2, 1));
1314+}
1315+
1316+static inline void
1317+undiagonalize_sse41(__m128i *row0, __m128i *row2, __m128i *row3)
1318+{
1319+  *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE(0, 3, 2, 1));
1320+  *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE(1, 0, 3, 2));
1321+  *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE(2, 1, 0, 3));
1322+}
1323+
1324+static inline void
1325+compress_pre_sse41(
1326+    __m128i        rows[4],
1327+    const uint32_t cv[8],
1328+    const uint8_t  block[BLAKE3_BLOCK_LEN],
1329+    uint8_t        block_len,
1330+    uint64_t       counter,
1331+    uint8_t        flags
1332+)
1333+{
1334+  __m128i m0, m1, m2, m3;
1335+  __m128i t0, t1, t2, t3, tt;
1336+
1337+  rows[0] = loadu_sse41((uint8_t *)&cv[0]);
1338+  rows[1] = loadu_sse41((uint8_t *)&cv[4]);
1339+  rows[2] = set4_sse41(IV[0], IV[1], IV[2], IV[3]);
1340+  rows[3] =
1341+      set4_sse41(counter_low(counter), counter_high(counter), (uint32_t)block_len, (uint32_t)flags);
1342+
1343+  m0 = loadu_sse41(&block[sizeof(__m128i) * 0]);
1344+  m1 = loadu_sse41(&block[sizeof(__m128i) * 1]);
1345+  m2 = loadu_sse41(&block[sizeof(__m128i) * 2]);
1346+  m3 = loadu_sse41(&block[sizeof(__m128i) * 3]);
1347+
1348+  /* round 1 */
1349+  t0 = _mm_shuffle_ps2_sse41(m0, m1, _MM_SHUFFLE(2, 0, 2, 0));
1350+  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t0);
1351+  t1 = _mm_shuffle_ps2_sse41(m0, m1, _MM_SHUFFLE(3, 1, 3, 1));
1352+  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t1);
1353+  diagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1354+  t2 = _mm_shuffle_ps2_sse41(m2, m3, _MM_SHUFFLE(2, 0, 2, 0));
1355+  t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2, 1, 0, 3));
1356+  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t2);
1357+  t3 = _mm_shuffle_ps2_sse41(m2, m3, _MM_SHUFFLE(3, 1, 3, 1));
1358+  t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(2, 1, 0, 3));
1359+  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t3);
1360+  undiagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1361+  m0 = t0;
1362+  m1 = t1;
1363+  m2 = t2;
1364+  m3 = t3;
1365+
1366+  /* round 2 */
1367+  t0 = _mm_shuffle_ps2_sse41(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
1368+  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
1369+  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t0);
1370+  t1 = _mm_shuffle_ps2_sse41(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
1371+  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
1372+  t1 = _mm_blend_epi16(tt, t1, 0xCC);
1373+  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t1);
1374+  diagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1375+  t2 = _mm_unpacklo_epi64(m3, m1);
1376+  tt = _mm_blend_epi16(t2, m2, 0xC0);
1377+  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
1378+  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t2);
1379+  t3 = _mm_unpackhi_epi32(m1, m3);
1380+  tt = _mm_unpacklo_epi32(m2, t3);
1381+  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
1382+  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t3);
1383+  undiagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1384+  m0 = t0;
1385+  m1 = t1;
1386+  m2 = t2;
1387+  m3 = t3;
1388+
1389+  /* round 3 */
1390+  t0 = _mm_shuffle_ps2_sse41(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
1391+  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
1392+  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t0);
1393+  t1 = _mm_shuffle_ps2_sse41(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
1394+  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
1395+  t1 = _mm_blend_epi16(tt, t1, 0xCC);
1396+  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t1);
1397+  diagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1398+  t2 = _mm_unpacklo_epi64(m3, m1);
1399+  tt = _mm_blend_epi16(t2, m2, 0xC0);
1400+  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
1401+  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t2);
1402+  t3 = _mm_unpackhi_epi32(m1, m3);
1403+  tt = _mm_unpacklo_epi32(m2, t3);
1404+  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
1405+  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t3);
1406+  undiagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1407+  m0 = t0;
1408+  m1 = t1;
1409+  m2 = t2;
1410+  m3 = t3;
1411+
1412+  /* round 4 */
1413+  t0 = _mm_shuffle_ps2_sse41(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
1414+  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
1415+  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t0);
1416+  t1 = _mm_shuffle_ps2_sse41(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
1417+  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
1418+  t1 = _mm_blend_epi16(tt, t1, 0xCC);
1419+  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t1);
1420+  diagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1421+  t2 = _mm_unpacklo_epi64(m3, m1);
1422+  tt = _mm_blend_epi16(t2, m2, 0xC0);
1423+  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
1424+  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t2);
1425+  t3 = _mm_unpackhi_epi32(m1, m3);
1426+  tt = _mm_unpacklo_epi32(m2, t3);
1427+  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
1428+  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t3);
1429+  undiagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1430+  m0 = t0;
1431+  m1 = t1;
1432+  m2 = t2;
1433+  m3 = t3;
1434+
1435+  /* round 5 */
1436+  t0 = _mm_shuffle_ps2_sse41(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
1437+  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
1438+  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t0);
1439+  t1 = _mm_shuffle_ps2_sse41(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
1440+  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
1441+  t1 = _mm_blend_epi16(tt, t1, 0xCC);
1442+  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t1);
1443+  diagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1444+  t2 = _mm_unpacklo_epi64(m3, m1);
1445+  tt = _mm_blend_epi16(t2, m2, 0xC0);
1446+  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
1447+  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t2);
1448+  t3 = _mm_unpackhi_epi32(m1, m3);
1449+  tt = _mm_unpacklo_epi32(m2, t3);
1450+  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
1451+  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t3);
1452+  undiagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1453+  m0 = t0;
1454+  m1 = t1;
1455+  m2 = t2;
1456+  m3 = t3;
1457+
1458+  /* round 6 */
1459+  t0 = _mm_shuffle_ps2_sse41(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
1460+  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
1461+  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t0);
1462+  t1 = _mm_shuffle_ps2_sse41(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
1463+  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
1464+  t1 = _mm_blend_epi16(tt, t1, 0xCC);
1465+  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t1);
1466+  diagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1467+  t2 = _mm_unpacklo_epi64(m3, m1);
1468+  tt = _mm_blend_epi16(t2, m2, 0xC0);
1469+  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
1470+  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t2);
1471+  t3 = _mm_unpackhi_epi32(m1, m3);
1472+  tt = _mm_unpacklo_epi32(m2, t3);
1473+  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
1474+  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t3);
1475+  undiagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1476+  m0 = t0;
1477+  m1 = t1;
1478+  m2 = t2;
1479+  m3 = t3;
1480+
1481+  /* round 7 */
1482+  t0 = _mm_shuffle_ps2_sse41(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
1483+  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
1484+  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t0);
1485+  t1 = _mm_shuffle_ps2_sse41(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
1486+  tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3));
1487+  t1 = _mm_blend_epi16(tt, t1, 0xCC);
1488+  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t1);
1489+  diagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1490+  t2 = _mm_unpacklo_epi64(m3, m1);
1491+  tt = _mm_blend_epi16(t2, m2, 0xC0);
1492+  t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0));
1493+  g1_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t2);
1494+  t3 = _mm_unpackhi_epi32(m1, m3);
1495+  tt = _mm_unpacklo_epi32(m2, t3);
1496+  t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2));
1497+  g2_sse41(&rows[0], &rows[1], &rows[2], &rows[3], t3);
1498+  undiagonalize_sse41(&rows[0], &rows[2], &rows[3]);
1499+}
1500+
1501+void
1502+blake3_compress_in_place_sse41(
1503+    uint32_t      cv[8],
1504+    const uint8_t block[BLAKE3_BLOCK_LEN],
1505+    uint8_t       block_len,
1506+    uint64_t      counter,
1507+    uint8_t       flags
1508+)
1509+{
1510+  __m128i rows[4];
1511+
1512+  compress_pre_sse41(rows, cv, block, block_len, counter, flags);
1513+  storeu_sse41(xorv_sse41(rows[0], rows[2]), (uint8_t *)&cv[0]);
1514+  storeu_sse41(xorv_sse41(rows[1], rows[3]), (uint8_t *)&cv[4]);
1515+}
1516+
1517+void
1518+blake3_compress_xof_sse41(
1519+    const uint32_t cv[8],
1520+    const uint8_t  block[BLAKE3_BLOCK_LEN],
1521+    uint8_t        block_len,
1522+    uint64_t       counter,
1523+    uint8_t        flags,
1524+    uint8_t        out_buf[64]
1525+)
1526+{
1527+  __m128i rows[4];
1528+
1529+  compress_pre_sse41(rows, cv, block, block_len, counter, flags);
1530+  storeu_sse41(xorv_sse41(rows[0], rows[2]), &out_buf[0]);
1531+  storeu_sse41(xorv_sse41(rows[1], rows[3]), &out_buf[16]);
1532+  storeu_sse41(xorv_sse41(rows[2], loadu_sse41((uint8_t *)&cv[0])), &out_buf[32]);
1533+  storeu_sse41(xorv_sse41(rows[3], loadu_sse41((uint8_t *)&cv[4])), &out_buf[48]);
1534+}
1535+
1536+static inline void
1537+round_fn_sse41(__m128i v[16], __m128i m[16], size_t r)
1538+{
1539+  v[0]  = addv_sse41(v[0], m[(size_t)MSG_SCHEDULE[r][0]]);
1540+  v[1]  = addv_sse41(v[1], m[(size_t)MSG_SCHEDULE[r][2]]);
1541+  v[2]  = addv_sse41(v[2], m[(size_t)MSG_SCHEDULE[r][4]]);
1542+  v[3]  = addv_sse41(v[3], m[(size_t)MSG_SCHEDULE[r][6]]);
1543+  v[0]  = addv_sse41(v[0], v[4]);
1544+  v[1]  = addv_sse41(v[1], v[5]);
1545+  v[2]  = addv_sse41(v[2], v[6]);
1546+  v[3]  = addv_sse41(v[3], v[7]);
1547+  v[12] = xorv_sse41(v[12], v[0]);
1548+  v[13] = xorv_sse41(v[13], v[1]);
1549+  v[14] = xorv_sse41(v[14], v[2]);
1550+  v[15] = xorv_sse41(v[15], v[3]);
1551+  v[12] = rot16_sse41(v[12]);
1552+  v[13] = rot16_sse41(v[13]);
1553+  v[14] = rot16_sse41(v[14]);
1554+  v[15] = rot16_sse41(v[15]);
1555+  v[8]  = addv_sse41(v[8], v[12]);
1556+  v[9]  = addv_sse41(v[9], v[13]);
1557+  v[10] = addv_sse41(v[10], v[14]);
1558+  v[11] = addv_sse41(v[11], v[15]);
1559+  v[4]  = xorv_sse41(v[4], v[8]);
1560+  v[5]  = xorv_sse41(v[5], v[9]);
1561+  v[6]  = xorv_sse41(v[6], v[10]);
1562+  v[7]  = xorv_sse41(v[7], v[11]);
1563+  v[4]  = rot12_sse41(v[4]);
1564+  v[5]  = rot12_sse41(v[5]);
1565+  v[6]  = rot12_sse41(v[6]);
1566+  v[7]  = rot12_sse41(v[7]);
1567+  v[0]  = addv_sse41(v[0], m[(size_t)MSG_SCHEDULE[r][1]]);
1568+  v[1]  = addv_sse41(v[1], m[(size_t)MSG_SCHEDULE[r][3]]);
1569+  v[2]  = addv_sse41(v[2], m[(size_t)MSG_SCHEDULE[r][5]]);
1570+  v[3]  = addv_sse41(v[3], m[(size_t)MSG_SCHEDULE[r][7]]);
1571+  v[0]  = addv_sse41(v[0], v[4]);
1572+  v[1]  = addv_sse41(v[1], v[5]);
1573+  v[2]  = addv_sse41(v[2], v[6]);
1574+  v[3]  = addv_sse41(v[3], v[7]);
1575+  v[12] = xorv_sse41(v[12], v[0]);
1576+  v[13] = xorv_sse41(v[13], v[1]);
1577+  v[14] = xorv_sse41(v[14], v[2]);
1578+  v[15] = xorv_sse41(v[15], v[3]);
1579+  v[12] = rot8_sse41(v[12]);
1580+  v[13] = rot8_sse41(v[13]);
1581+  v[14] = rot8_sse41(v[14]);
1582+  v[15] = rot8_sse41(v[15]);
1583+  v[8]  = addv_sse41(v[8], v[12]);
1584+  v[9]  = addv_sse41(v[9], v[13]);
1585+  v[10] = addv_sse41(v[10], v[14]);
1586+  v[11] = addv_sse41(v[11], v[15]);
1587+  v[4]  = xorv_sse41(v[4], v[8]);
1588+  v[5]  = xorv_sse41(v[5], v[9]);
1589+  v[6]  = xorv_sse41(v[6], v[10]);
1590+  v[7]  = xorv_sse41(v[7], v[11]);
1591+  v[4]  = rot7_sse41(v[4]);
1592+  v[5]  = rot7_sse41(v[5]);
1593+  v[6]  = rot7_sse41(v[6]);
1594+  v[7]  = rot7_sse41(v[7]);
1595+
1596+  v[0]  = addv_sse41(v[0], m[(size_t)MSG_SCHEDULE[r][8]]);
1597+  v[1]  = addv_sse41(v[1], m[(size_t)MSG_SCHEDULE[r][10]]);
1598+  v[2]  = addv_sse41(v[2], m[(size_t)MSG_SCHEDULE[r][12]]);
1599+  v[3]  = addv_sse41(v[3], m[(size_t)MSG_SCHEDULE[r][14]]);
1600+  v[0]  = addv_sse41(v[0], v[5]);
1601+  v[1]  = addv_sse41(v[1], v[6]);
1602+  v[2]  = addv_sse41(v[2], v[7]);
1603+  v[3]  = addv_sse41(v[3], v[4]);
1604+  v[15] = xorv_sse41(v[15], v[0]);
1605+  v[12] = xorv_sse41(v[12], v[1]);
1606+  v[13] = xorv_sse41(v[13], v[2]);
1607+  v[14] = xorv_sse41(v[14], v[3]);
1608+  v[15] = rot16_sse41(v[15]);
1609+  v[12] = rot16_sse41(v[12]);
1610+  v[13] = rot16_sse41(v[13]);
1611+  v[14] = rot16_sse41(v[14]);
1612+  v[10] = addv_sse41(v[10], v[15]);
1613+  v[11] = addv_sse41(v[11], v[12]);
1614+  v[8]  = addv_sse41(v[8], v[13]);
1615+  v[9]  = addv_sse41(v[9], v[14]);
1616+  v[5]  = xorv_sse41(v[5], v[10]);
1617+  v[6]  = xorv_sse41(v[6], v[11]);
1618+  v[7]  = xorv_sse41(v[7], v[8]);
1619+  v[4]  = xorv_sse41(v[4], v[9]);
1620+  v[5]  = rot12_sse41(v[5]);
1621+  v[6]  = rot12_sse41(v[6]);
1622+  v[7]  = rot12_sse41(v[7]);
1623+  v[4]  = rot12_sse41(v[4]);
1624+  v[0]  = addv_sse41(v[0], m[(size_t)MSG_SCHEDULE[r][9]]);
1625+  v[1]  = addv_sse41(v[1], m[(size_t)MSG_SCHEDULE[r][11]]);
1626+  v[2]  = addv_sse41(v[2], m[(size_t)MSG_SCHEDULE[r][13]]);
1627+  v[3]  = addv_sse41(v[3], m[(size_t)MSG_SCHEDULE[r][15]]);
1628+  v[0]  = addv_sse41(v[0], v[5]);
1629+  v[1]  = addv_sse41(v[1], v[6]);
1630+  v[2]  = addv_sse41(v[2], v[7]);
1631+  v[3]  = addv_sse41(v[3], v[4]);
1632+  v[15] = xorv_sse41(v[15], v[0]);
1633+  v[12] = xorv_sse41(v[12], v[1]);
1634+  v[13] = xorv_sse41(v[13], v[2]);
1635+  v[14] = xorv_sse41(v[14], v[3]);
1636+  v[15] = rot8_sse41(v[15]);
1637+  v[12] = rot8_sse41(v[12]);
1638+  v[13] = rot8_sse41(v[13]);
1639+  v[14] = rot8_sse41(v[14]);
1640+  v[10] = addv_sse41(v[10], v[15]);
1641+  v[11] = addv_sse41(v[11], v[12]);
1642+  v[8]  = addv_sse41(v[8], v[13]);
1643+  v[9]  = addv_sse41(v[9], v[14]);
1644+  v[5]  = xorv_sse41(v[5], v[10]);
1645+  v[6]  = xorv_sse41(v[6], v[11]);
1646+  v[7]  = xorv_sse41(v[7], v[8]);
1647+  v[4]  = xorv_sse41(v[4], v[9]);
1648+  v[5]  = rot7_sse41(v[5]);
1649+  v[6]  = rot7_sse41(v[6]);
1650+  v[7]  = rot7_sse41(v[7]);
1651+  v[4]  = rot7_sse41(v[4]);
1652+}
1653+
1654+static inline void
1655+transpose_vecs_sse41(__m128i vecs[DEGREE_SSE41])
1656+{
1657+  __m128i ab_01 = _mm_unpacklo_epi32(vecs[0], vecs[1]);
1658+  __m128i ab_23 = _mm_unpackhi_epi32(vecs[0], vecs[1]);
1659+  __m128i cd_01 = _mm_unpacklo_epi32(vecs[2], vecs[3]);
1660+  __m128i cd_23 = _mm_unpackhi_epi32(vecs[2], vecs[3]);
1661+
1662+  __m128i abcd_0 = _mm_unpacklo_epi64(ab_01, cd_01);
1663+  __m128i abcd_1 = _mm_unpackhi_epi64(ab_01, cd_01);
1664+  __m128i abcd_2 = _mm_unpacklo_epi64(ab_23, cd_23);
1665+  __m128i abcd_3 = _mm_unpackhi_epi64(ab_23, cd_23);
1666+
1667+  vecs[0] = abcd_0;
1668+  vecs[1] = abcd_1;
1669+  vecs[2] = abcd_2;
1670+  vecs[3] = abcd_3;
1671+}
1672+
1673+static inline void
1674+transpose_msg_vecs_sse41(const uint8_t *const *inputs, size_t block_offset, __m128i out_msg[16])
1675+{
1676+  size_t i;
1677+
1678+  out_msg[0]  = loadu_sse41(&inputs[0][block_offset + 0 * sizeof(__m128i)]);
1679+  out_msg[1]  = loadu_sse41(&inputs[1][block_offset + 0 * sizeof(__m128i)]);
1680+  out_msg[2]  = loadu_sse41(&inputs[2][block_offset + 0 * sizeof(__m128i)]);
1681+  out_msg[3]  = loadu_sse41(&inputs[3][block_offset + 0 * sizeof(__m128i)]);
1682+  out_msg[4]  = loadu_sse41(&inputs[0][block_offset + 1 * sizeof(__m128i)]);
1683+  out_msg[5]  = loadu_sse41(&inputs[1][block_offset + 1 * sizeof(__m128i)]);
1684+  out_msg[6]  = loadu_sse41(&inputs[2][block_offset + 1 * sizeof(__m128i)]);
1685+  out_msg[7]  = loadu_sse41(&inputs[3][block_offset + 1 * sizeof(__m128i)]);
1686+  out_msg[8]  = loadu_sse41(&inputs[0][block_offset + 2 * sizeof(__m128i)]);
1687+  out_msg[9]  = loadu_sse41(&inputs[1][block_offset + 2 * sizeof(__m128i)]);
1688+  out_msg[10] = loadu_sse41(&inputs[2][block_offset + 2 * sizeof(__m128i)]);
1689+  out_msg[11] = loadu_sse41(&inputs[3][block_offset + 2 * sizeof(__m128i)]);
1690+  out_msg[12] = loadu_sse41(&inputs[0][block_offset + 3 * sizeof(__m128i)]);
1691+  out_msg[13] = loadu_sse41(&inputs[1][block_offset + 3 * sizeof(__m128i)]);
1692+  out_msg[14] = loadu_sse41(&inputs[2][block_offset + 3 * sizeof(__m128i)]);
1693+  out_msg[15] = loadu_sse41(&inputs[3][block_offset + 3 * sizeof(__m128i)]);
1694+
1695+  for (i = 0; i < 4; i++) {
1696+    _mm_prefetch((const void *)&inputs[i][block_offset + 256], _MM_HINT_T0);
1697+  }
1698+  transpose_vecs_sse41(&out_msg[0]);
1699+  transpose_vecs_sse41(&out_msg[4]);
1700+  transpose_vecs_sse41(&out_msg[8]);
1701+  transpose_vecs_sse41(&out_msg[12]);
1702+}
1703+
1704+static inline void
1705+load_counters_sse41(uint64_t counter, int increment_counter, __m128i *out_lo, __m128i *out_hi)
1706+{
1707+  const __m128i mask  = _mm_set1_epi32(-increment_counter);
1708+  const __m128i add0  = _mm_set_epi32(3, 2, 1, 0);
1709+  const __m128i add1  = _mm_and_si128(mask, add0);
1710+  __m128i       l     = _mm_add_epi32(_mm_set1_epi32((int32_t)counter), add1);
1711+  __m128i       carry = _mm_cmpgt_epi32(
1712+      _mm_xor_si128(add1, _mm_set1_epi32(0x80000000)), _mm_xor_si128(l, _mm_set1_epi32(0x80000000))
1713+  );
1714+  __m128i h = _mm_sub_epi32(_mm_set1_epi32((int32_t)(counter >> 32)), carry);
1715+
1716+  *out_lo = l;
1717+  *out_hi = h;
1718+}
1719+
1720+void
1721+blake3_hash4_sse41(
1722+    const uint8_t *const *inputs,
1723+    size_t                blocks,
1724+    const uint32_t        key[8],
1725+    uint64_t              counter,
1726+    int                   increment_counter,
1727+    uint8_t               flags,
1728+    uint8_t               flags_start,
1729+    uint8_t               flags_end,
1730+    uint8_t              *out_bytes
1731+)
1732+{
1733+  __m128i h_vecs[8];
1734+  __m128i counter_low_vec, counter_high_vec;
1735+  uint8_t block_flags;
1736+  size_t  block;
1737+
1738+  h_vecs[0] = set1_sse41(key[0]);
1739+  h_vecs[1] = set1_sse41(key[1]);
1740+  h_vecs[2] = set1_sse41(key[2]);
1741+  h_vecs[3] = set1_sse41(key[3]);
1742+  h_vecs[4] = set1_sse41(key[4]);
1743+  h_vecs[5] = set1_sse41(key[5]);
1744+  h_vecs[6] = set1_sse41(key[6]);
1745+  h_vecs[7] = set1_sse41(key[7]);
1746+
1747+  load_counters_sse41(counter, increment_counter, &counter_low_vec, &counter_high_vec);
1748+  block_flags = flags | flags_start;
1749+
1750+  for (block = 0; block < blocks; block++) {
1751+    __m128i block_len_vec;
1752+    __m128i block_flags_vec;
1753+    __m128i msg_vecs[16];
1754+    __m128i v[16];
1755+
1756+    if (block + 1 == blocks) {
1757+      block_flags |= flags_end;
1758+    }
1759+    block_len_vec   = set1_sse41(BLAKE3_BLOCK_LEN);
1760+    block_flags_vec = set1_sse41(block_flags);
1761+    transpose_msg_vecs_sse41(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs);
1762+
1763+    v[0]  = h_vecs[0];
1764+    v[1]  = h_vecs[1];
1765+    v[2]  = h_vecs[2];
1766+    v[3]  = h_vecs[3];
1767+    v[4]  = h_vecs[4];
1768+    v[5]  = h_vecs[5];
1769+    v[6]  = h_vecs[6];
1770+    v[7]  = h_vecs[7];
1771+    v[8]  = set1_sse41(IV[0]);
1772+    v[9]  = set1_sse41(IV[1]);
1773+    v[10] = set1_sse41(IV[2]);
1774+    v[11] = set1_sse41(IV[3]);
1775+    v[12] = counter_low_vec;
1776+    v[13] = counter_high_vec;
1777+    v[14] = block_len_vec;
1778+    v[15] = block_flags_vec;
1779+
1780+    round_fn_sse41(v, msg_vecs, 0);
1781+    round_fn_sse41(v, msg_vecs, 1);
1782+    round_fn_sse41(v, msg_vecs, 2);
1783+    round_fn_sse41(v, msg_vecs, 3);
1784+    round_fn_sse41(v, msg_vecs, 4);
1785+    round_fn_sse41(v, msg_vecs, 5);
1786+    round_fn_sse41(v, msg_vecs, 6);
1787+
1788+    h_vecs[0] = xorv_sse41(v[0], v[8]);
1789+    h_vecs[1] = xorv_sse41(v[1], v[9]);
1790+    h_vecs[2] = xorv_sse41(v[2], v[10]);
1791+    h_vecs[3] = xorv_sse41(v[3], v[11]);
1792+    h_vecs[4] = xorv_sse41(v[4], v[12]);
1793+    h_vecs[5] = xorv_sse41(v[5], v[13]);
1794+    h_vecs[6] = xorv_sse41(v[6], v[14]);
1795+    h_vecs[7] = xorv_sse41(v[7], v[15]);
1796+
1797+    block_flags = flags;
1798+  }
1799+
1800+  transpose_vecs_sse41(&h_vecs[0]);
1801+  transpose_vecs_sse41(&h_vecs[4]);
1802+  storeu_sse41(h_vecs[0], &out_bytes[0 * sizeof(__m128i)]);
1803+  storeu_sse41(h_vecs[4], &out_bytes[1 * sizeof(__m128i)]);
1804+  storeu_sse41(h_vecs[1], &out_bytes[2 * sizeof(__m128i)]);
1805+  storeu_sse41(h_vecs[5], &out_bytes[3 * sizeof(__m128i)]);
1806+  storeu_sse41(h_vecs[2], &out_bytes[4 * sizeof(__m128i)]);
1807+  storeu_sse41(h_vecs[6], &out_bytes[5 * sizeof(__m128i)]);
1808+  storeu_sse41(h_vecs[3], &out_bytes[6 * sizeof(__m128i)]);
1809+  storeu_sse41(h_vecs[7], &out_bytes[7 * sizeof(__m128i)]);
1810+}
1811+
1812+static inline void
1813+hash_one_sse41(
1814+    const uint8_t *input,
1815+    size_t         blocks,
1816+    const uint32_t key[8],
1817+    uint64_t       counter,
1818+    uint8_t        flags,
1819+    uint8_t        flags_start,
1820+    uint8_t        flags_end,
1821+    uint8_t        out_bytes[BLAKE3_OUT_LEN]
1822+)
1823+{
1824+  uint32_t cv[8];
1825+  uint8_t  block_flags;
1826+
1827+  memcpy(cv, key, BLAKE3_KEY_LEN);
1828+  block_flags = flags | flags_start;
1829+  while (blocks > 0) {
1830+    if (blocks == 1) {
1831+      block_flags |= flags_end;
1832+    }
1833+    blake3_compress_in_place_sse41(cv, input, BLAKE3_BLOCK_LEN, counter, block_flags);
1834+    input = &input[BLAKE3_BLOCK_LEN];
1835+    blocks -= 1;
1836+    block_flags = flags;
1837+  }
1838+  memcpy(out_bytes, cv, BLAKE3_OUT_LEN);
1839+}
1840+
1841+void
1842+blake3_hash_many_sse41(
1843+    const uint8_t *const *inputs,
1844+    size_t                num_inputs,
1845+    size_t                blocks,
1846+    const uint32_t        key[8],
1847+    uint64_t              counter,
1848+    int                   increment_counter,
1849+    uint8_t               flags,
1850+    uint8_t               flags_start,
1851+    uint8_t               flags_end,
1852+    uint8_t              *out_bytes
1853+)
1854+{
1855+  while (num_inputs >= DEGREE_SSE41) {
1856+    blake3_hash4_sse41(
1857+        inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out_bytes
1858+    );
1859+    if (increment_counter) {
1860+      counter += DEGREE_SSE41;
1861+    }
1862+    inputs += DEGREE_SSE41;
1863+    num_inputs -= DEGREE_SSE41;
1864+    out_bytes = &out_bytes[DEGREE_SSE41 * BLAKE3_OUT_LEN];
1865+  }
1866+  while (num_inputs > 0) {
1867+    hash_one_sse41(inputs[0], blocks, key, counter, flags, flags_start, flags_end, out_bytes);
1868+    if (increment_counter) {
1869+      counter += 1;
1870+    }
1871+    inputs += 1;
1872+    num_inputs -= 1;
1873+    out_bytes = &out_bytes[BLAKE3_OUT_LEN];
1874+  }
1875+}
1876+#if defined(__clang__)
1877+#pragma clang attribute pop
1878+#elif defined(__GNUC__)
1879+#pragma GCC pop_options
1880+#endif
1881+
1882+#if defined(__clang__)
1883+#pragma clang attribute push(__attribute__((target("avx2"))), apply_to = function)
1884+#elif defined(__GNUC__)
1885+#pragma GCC push_options
1886+#pragma GCC target("avx2")
1887+#endif
1888+#define DEGREE_AVX2 8
1889+
1890+static inline __m256i
1891+loadu_avx2(const uint8_t src[32])
1892+{
1893+  return _mm256_loadu_si256((const __m256i *)src);
1894+}
1895+
1896+static inline void
1897+storeu_avx2(__m256i src, uint8_t dest[32])
1898+{
1899+  _mm256_storeu_si256((__m256i *)dest, src);
1900+}
1901+
1902+static inline __m256i
1903+addv_avx2(__m256i a, __m256i b)
1904+{
1905+  return _mm256_add_epi32(a, b);
1906+}
1907+
1908+static inline __m256i
1909+xorv_avx2(__m256i a, __m256i b)
1910+{
1911+  return _mm256_xor_si256(a, b);
1912+}
1913+
1914+static inline __m256i
1915+set1_avx2(uint32_t x)
1916+{
1917+  return _mm256_set1_epi32((int32_t)x);
1918+}
1919+
1920+static inline __m256i
1921+rot16_avx2(__m256i x)
1922+{
1923+  return _mm256_shuffle_epi8(
1924+      x,
1925+      _mm256_set_epi8(
1926+          13,
1927+          12,
1928+          15,
1929+          14,
1930+          9,
1931+          8,
1932+          11,
1933+          10,
1934+          5,
1935+          4,
1936+          7,
1937+          6,
1938+          1,
1939+          0,
1940+          3,
1941+          2,
1942+          13,
1943+          12,
1944+          15,
1945+          14,
1946+          9,
1947+          8,
1948+          11,
1949+          10,
1950+          5,
1951+          4,
1952+          7,
1953+          6,
1954+          1,
1955+          0,
1956+          3,
1957+          2
1958+      )
1959+  );
1960+}
1961+
1962+static inline __m256i
1963+rot12_avx2(__m256i x)
1964+{
1965+  return _mm256_or_si256(_mm256_srli_epi32(x, 12), _mm256_slli_epi32(x, 32 - 12));
1966+}
1967+
1968+static inline __m256i
1969+rot8_avx2(__m256i x)
1970+{
1971+  return _mm256_shuffle_epi8(
1972+      x,
1973+      _mm256_set_epi8(
1974+          12,
1975+          15,
1976+          14,
1977+          13,
1978+          8,
1979+          11,
1980+          10,
1981+          9,
1982+          4,
1983+          7,
1984+          6,
1985+          5,
1986+          0,
1987+          3,
1988+          2,
1989+          1,
1990+          12,
1991+          15,
1992+          14,
1993+          13,
1994+          8,
1995+          11,
1996+          10,
1997+          9,
1998+          4,
1999+          7,
2000+          6,
2001+          5,
2002+          0,
2003+          3,
2004+          2,
2005+          1
2006+      )
2007+  );
2008+}
2009+
2010+static inline __m256i
2011+rot7_avx2(__m256i x)
2012+{
2013+  return _mm256_or_si256(_mm256_srli_epi32(x, 7), _mm256_slli_epi32(x, 32 - 7));
2014+}
2015+
2016+static inline void
2017+round_fn_avx2(__m256i v[16], __m256i m[16], size_t r)
2018+{
2019+  v[0]  = addv_avx2(v[0], m[(size_t)MSG_SCHEDULE[r][0]]);
2020+  v[1]  = addv_avx2(v[1], m[(size_t)MSG_SCHEDULE[r][2]]);
2021+  v[2]  = addv_avx2(v[2], m[(size_t)MSG_SCHEDULE[r][4]]);
2022+  v[3]  = addv_avx2(v[3], m[(size_t)MSG_SCHEDULE[r][6]]);
2023+  v[0]  = addv_avx2(v[0], v[4]);
2024+  v[1]  = addv_avx2(v[1], v[5]);
2025+  v[2]  = addv_avx2(v[2], v[6]);
2026+  v[3]  = addv_avx2(v[3], v[7]);
2027+  v[12] = xorv_avx2(v[12], v[0]);
2028+  v[13] = xorv_avx2(v[13], v[1]);
2029+  v[14] = xorv_avx2(v[14], v[2]);
2030+  v[15] = xorv_avx2(v[15], v[3]);
2031+  v[12] = rot16_avx2(v[12]);
2032+  v[13] = rot16_avx2(v[13]);
2033+  v[14] = rot16_avx2(v[14]);
2034+  v[15] = rot16_avx2(v[15]);
2035+  v[8]  = addv_avx2(v[8], v[12]);
2036+  v[9]  = addv_avx2(v[9], v[13]);
2037+  v[10] = addv_avx2(v[10], v[14]);
2038+  v[11] = addv_avx2(v[11], v[15]);
2039+  v[4]  = xorv_avx2(v[4], v[8]);
2040+  v[5]  = xorv_avx2(v[5], v[9]);
2041+  v[6]  = xorv_avx2(v[6], v[10]);
2042+  v[7]  = xorv_avx2(v[7], v[11]);
2043+  v[4]  = rot12_avx2(v[4]);
2044+  v[5]  = rot12_avx2(v[5]);
2045+  v[6]  = rot12_avx2(v[6]);
2046+  v[7]  = rot12_avx2(v[7]);
2047+  v[0]  = addv_avx2(v[0], m[(size_t)MSG_SCHEDULE[r][1]]);
2048+  v[1]  = addv_avx2(v[1], m[(size_t)MSG_SCHEDULE[r][3]]);
2049+  v[2]  = addv_avx2(v[2], m[(size_t)MSG_SCHEDULE[r][5]]);
2050+  v[3]  = addv_avx2(v[3], m[(size_t)MSG_SCHEDULE[r][7]]);
2051+  v[0]  = addv_avx2(v[0], v[4]);
2052+  v[1]  = addv_avx2(v[1], v[5]);
2053+  v[2]  = addv_avx2(v[2], v[6]);
2054+  v[3]  = addv_avx2(v[3], v[7]);
2055+  v[12] = xorv_avx2(v[12], v[0]);
2056+  v[13] = xorv_avx2(v[13], v[1]);
2057+  v[14] = xorv_avx2(v[14], v[2]);
2058+  v[15] = xorv_avx2(v[15], v[3]);
2059+  v[12] = rot8_avx2(v[12]);
2060+  v[13] = rot8_avx2(v[13]);
2061+  v[14] = rot8_avx2(v[14]);
2062+  v[15] = rot8_avx2(v[15]);
2063+  v[8]  = addv_avx2(v[8], v[12]);
2064+  v[9]  = addv_avx2(v[9], v[13]);
2065+  v[10] = addv_avx2(v[10], v[14]);
2066+  v[11] = addv_avx2(v[11], v[15]);
2067+  v[4]  = xorv_avx2(v[4], v[8]);
2068+  v[5]  = xorv_avx2(v[5], v[9]);
2069+  v[6]  = xorv_avx2(v[6], v[10]);
2070+  v[7]  = xorv_avx2(v[7], v[11]);
2071+  v[4]  = rot7_avx2(v[4]);
2072+  v[5]  = rot7_avx2(v[5]);
2073+  v[6]  = rot7_avx2(v[6]);
2074+  v[7]  = rot7_avx2(v[7]);
2075+
2076+  v[0]  = addv_avx2(v[0], m[(size_t)MSG_SCHEDULE[r][8]]);
2077+  v[1]  = addv_avx2(v[1], m[(size_t)MSG_SCHEDULE[r][10]]);
2078+  v[2]  = addv_avx2(v[2], m[(size_t)MSG_SCHEDULE[r][12]]);
2079+  v[3]  = addv_avx2(v[3], m[(size_t)MSG_SCHEDULE[r][14]]);
2080+  v[0]  = addv_avx2(v[0], v[5]);
2081+  v[1]  = addv_avx2(v[1], v[6]);
2082+  v[2]  = addv_avx2(v[2], v[7]);
2083+  v[3]  = addv_avx2(v[3], v[4]);
2084+  v[15] = xorv_avx2(v[15], v[0]);
2085+  v[12] = xorv_avx2(v[12], v[1]);
2086+  v[13] = xorv_avx2(v[13], v[2]);
2087+  v[14] = xorv_avx2(v[14], v[3]);
2088+  v[15] = rot16_avx2(v[15]);
2089+  v[12] = rot16_avx2(v[12]);
2090+  v[13] = rot16_avx2(v[13]);
2091+  v[14] = rot16_avx2(v[14]);
2092+  v[10] = addv_avx2(v[10], v[15]);
2093+  v[11] = addv_avx2(v[11], v[12]);
2094+  v[8]  = addv_avx2(v[8], v[13]);
2095+  v[9]  = addv_avx2(v[9], v[14]);
2096+  v[5]  = xorv_avx2(v[5], v[10]);
2097+  v[6]  = xorv_avx2(v[6], v[11]);
2098+  v[7]  = xorv_avx2(v[7], v[8]);
2099+  v[4]  = xorv_avx2(v[4], v[9]);
2100+  v[5]  = rot12_avx2(v[5]);
2101+  v[6]  = rot12_avx2(v[6]);
2102+  v[7]  = rot12_avx2(v[7]);
2103+  v[4]  = rot12_avx2(v[4]);
2104+  v[0]  = addv_avx2(v[0], m[(size_t)MSG_SCHEDULE[r][9]]);
2105+  v[1]  = addv_avx2(v[1], m[(size_t)MSG_SCHEDULE[r][11]]);
2106+  v[2]  = addv_avx2(v[2], m[(size_t)MSG_SCHEDULE[r][13]]);
2107+  v[3]  = addv_avx2(v[3], m[(size_t)MSG_SCHEDULE[r][15]]);
2108+  v[0]  = addv_avx2(v[0], v[5]);
2109+  v[1]  = addv_avx2(v[1], v[6]);
2110+  v[2]  = addv_avx2(v[2], v[7]);
2111+  v[3]  = addv_avx2(v[3], v[4]);
2112+  v[15] = xorv_avx2(v[15], v[0]);
2113+  v[12] = xorv_avx2(v[12], v[1]);
2114+  v[13] = xorv_avx2(v[13], v[2]);
2115+  v[14] = xorv_avx2(v[14], v[3]);
2116+  v[15] = rot8_avx2(v[15]);
2117+  v[12] = rot8_avx2(v[12]);
2118+  v[13] = rot8_avx2(v[13]);
2119+  v[14] = rot8_avx2(v[14]);
2120+  v[10] = addv_avx2(v[10], v[15]);
2121+  v[11] = addv_avx2(v[11], v[12]);
2122+  v[8]  = addv_avx2(v[8], v[13]);
2123+  v[9]  = addv_avx2(v[9], v[14]);
2124+  v[5]  = xorv_avx2(v[5], v[10]);
2125+  v[6]  = xorv_avx2(v[6], v[11]);
2126+  v[7]  = xorv_avx2(v[7], v[8]);
2127+  v[4]  = xorv_avx2(v[4], v[9]);
2128+  v[5]  = rot7_avx2(v[5]);
2129+  v[6]  = rot7_avx2(v[6]);
2130+  v[7]  = rot7_avx2(v[7]);
2131+  v[4]  = rot7_avx2(v[4]);
2132+}
2133+
2134+static inline void
2135+transpose_vecs_avx2(__m256i vecs[DEGREE_AVX2])
2136+{
2137+  __m256i ab_0145 = _mm256_unpacklo_epi32(vecs[0], vecs[1]);
2138+  __m256i ab_2367 = _mm256_unpackhi_epi32(vecs[0], vecs[1]);
2139+  __m256i cd_0145 = _mm256_unpacklo_epi32(vecs[2], vecs[3]);
2140+  __m256i cd_2367 = _mm256_unpackhi_epi32(vecs[2], vecs[3]);
2141+  __m256i ef_0145 = _mm256_unpacklo_epi32(vecs[4], vecs[5]);
2142+  __m256i ef_2367 = _mm256_unpackhi_epi32(vecs[4], vecs[5]);
2143+  __m256i gh_0145 = _mm256_unpacklo_epi32(vecs[6], vecs[7]);
2144+  __m256i gh_2367 = _mm256_unpackhi_epi32(vecs[6], vecs[7]);
2145+
2146+  __m256i abcd_04 = _mm256_unpacklo_epi64(ab_0145, cd_0145);
2147+  __m256i abcd_15 = _mm256_unpackhi_epi64(ab_0145, cd_0145);
2148+  __m256i abcd_26 = _mm256_unpacklo_epi64(ab_2367, cd_2367);
2149+  __m256i abcd_37 = _mm256_unpackhi_epi64(ab_2367, cd_2367);
2150+  __m256i efgh_04 = _mm256_unpacklo_epi64(ef_0145, gh_0145);
2151+  __m256i efgh_15 = _mm256_unpackhi_epi64(ef_0145, gh_0145);
2152+  __m256i efgh_26 = _mm256_unpacklo_epi64(ef_2367, gh_2367);
2153+  __m256i efgh_37 = _mm256_unpackhi_epi64(ef_2367, gh_2367);
2154+
2155+  vecs[0] = _mm256_permute2x128_si256(abcd_04, efgh_04, 0x20);
2156+  vecs[1] = _mm256_permute2x128_si256(abcd_15, efgh_15, 0x20);
2157+  vecs[2] = _mm256_permute2x128_si256(abcd_26, efgh_26, 0x20);
2158+  vecs[3] = _mm256_permute2x128_si256(abcd_37, efgh_37, 0x20);
2159+  vecs[4] = _mm256_permute2x128_si256(abcd_04, efgh_04, 0x31);
2160+  vecs[5] = _mm256_permute2x128_si256(abcd_15, efgh_15, 0x31);
2161+  vecs[6] = _mm256_permute2x128_si256(abcd_26, efgh_26, 0x31);
2162+  vecs[7] = _mm256_permute2x128_si256(abcd_37, efgh_37, 0x31);
2163+}
2164+
2165+static inline void
2166+transpose_msg_vecs_avx2(const uint8_t *const *inputs, size_t block_offset, __m256i out_msg[16])
2167+{
2168+  size_t i;
2169+
2170+  out_msg[0]  = loadu_avx2(&inputs[0][block_offset + 0 * sizeof(__m256i)]);
2171+  out_msg[1]  = loadu_avx2(&inputs[1][block_offset + 0 * sizeof(__m256i)]);
2172+  out_msg[2]  = loadu_avx2(&inputs[2][block_offset + 0 * sizeof(__m256i)]);
2173+  out_msg[3]  = loadu_avx2(&inputs[3][block_offset + 0 * sizeof(__m256i)]);
2174+  out_msg[4]  = loadu_avx2(&inputs[4][block_offset + 0 * sizeof(__m256i)]);
2175+  out_msg[5]  = loadu_avx2(&inputs[5][block_offset + 0 * sizeof(__m256i)]);
2176+  out_msg[6]  = loadu_avx2(&inputs[6][block_offset + 0 * sizeof(__m256i)]);
2177+  out_msg[7]  = loadu_avx2(&inputs[7][block_offset + 0 * sizeof(__m256i)]);
2178+  out_msg[8]  = loadu_avx2(&inputs[0][block_offset + 1 * sizeof(__m256i)]);
2179+  out_msg[9]  = loadu_avx2(&inputs[1][block_offset + 1 * sizeof(__m256i)]);
2180+  out_msg[10] = loadu_avx2(&inputs[2][block_offset + 1 * sizeof(__m256i)]);
2181+  out_msg[11] = loadu_avx2(&inputs[3][block_offset + 1 * sizeof(__m256i)]);
2182+  out_msg[12] = loadu_avx2(&inputs[4][block_offset + 1 * sizeof(__m256i)]);
2183+  out_msg[13] = loadu_avx2(&inputs[5][block_offset + 1 * sizeof(__m256i)]);
2184+  out_msg[14] = loadu_avx2(&inputs[6][block_offset + 1 * sizeof(__m256i)]);
2185+  out_msg[15] = loadu_avx2(&inputs[7][block_offset + 1 * sizeof(__m256i)]);
2186+
2187+  for (i = 0; i < 8; i++) {
2188+    _mm_prefetch((const void *)&inputs[i][block_offset + 256], _MM_HINT_T0);
2189+  }
2190+  transpose_vecs_avx2(&out_msg[0]);
2191+  transpose_vecs_avx2(&out_msg[8]);
2192+}
2193+
2194+static inline void
2195+load_counters_avx2(uint64_t counter, int increment_counter, __m256i *out_lo, __m256i *out_hi)
2196+{
2197+  const __m256i mask  = _mm256_set1_epi32(-increment_counter);
2198+  const __m256i add0  = _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0);
2199+  const __m256i add1  = _mm256_and_si256(mask, add0);
2200+  __m256i       l     = _mm256_add_epi32(_mm256_set1_epi32((int32_t)counter), add1);
2201+  __m256i       carry = _mm256_xor_si256(add1, _mm256_set1_epi32(0x80000000));
2202+  __m256i       comp  = _mm256_xor_si256(l, _mm256_set1_epi32(0x80000000));
2203+  __m256i       gt    = _mm256_cmpgt_epi32(carry, comp);
2204+  __m256i       h     = _mm256_sub_epi32(_mm256_set1_epi32((int32_t)(counter >> 32)), gt);
2205+
2206+  *out_lo = l;
2207+  *out_hi = h;
2208+}
2209+
2210+void
2211+blake3_hash8_avx2(
2212+    const uint8_t *const *inputs,
2213+    size_t                blocks,
2214+    const uint32_t        key[8],
2215+    uint64_t              counter,
2216+    int                   increment_counter,
2217+    uint8_t               flags,
2218+    uint8_t               flags_start,
2219+    uint8_t               flags_end,
2220+    uint8_t              *out_bytes
2221+)
2222+{
2223+  __m256i h_vecs[8];
2224+  __m256i counter_low_vec, counter_high_vec;
2225+  uint8_t block_flags;
2226+  size_t  block;
2227+
2228+  h_vecs[0] = set1_avx2(key[0]);
2229+  h_vecs[1] = set1_avx2(key[1]);
2230+  h_vecs[2] = set1_avx2(key[2]);
2231+  h_vecs[3] = set1_avx2(key[3]);
2232+  h_vecs[4] = set1_avx2(key[4]);
2233+  h_vecs[5] = set1_avx2(key[5]);
2234+  h_vecs[6] = set1_avx2(key[6]);
2235+  h_vecs[7] = set1_avx2(key[7]);
2236+
2237+  load_counters_avx2(counter, increment_counter, &counter_low_vec, &counter_high_vec);
2238+  block_flags = flags | flags_start;
2239+
2240+  for (block = 0; block < blocks; block++) {
2241+    __m256i block_len_vec;
2242+    __m256i block_flags_vec;
2243+    __m256i msg_vecs[16];
2244+    __m256i v[16];
2245+
2246+    if (block + 1 == blocks) {
2247+      block_flags |= flags_end;
2248+    }
2249+    block_len_vec   = set1_avx2(BLAKE3_BLOCK_LEN);
2250+    block_flags_vec = set1_avx2(block_flags);
2251+    transpose_msg_vecs_avx2(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs);
2252+
2253+    v[0]  = h_vecs[0];
2254+    v[1]  = h_vecs[1];
2255+    v[2]  = h_vecs[2];
2256+    v[3]  = h_vecs[3];
2257+    v[4]  = h_vecs[4];
2258+    v[5]  = h_vecs[5];
2259+    v[6]  = h_vecs[6];
2260+    v[7]  = h_vecs[7];
2261+    v[8]  = set1_avx2(IV[0]);
2262+    v[9]  = set1_avx2(IV[1]);
2263+    v[10] = set1_avx2(IV[2]);
2264+    v[11] = set1_avx2(IV[3]);
2265+    v[12] = counter_low_vec;
2266+    v[13] = counter_high_vec;
2267+    v[14] = block_len_vec;
2268+    v[15] = block_flags_vec;
2269+
2270+    round_fn_avx2(v, msg_vecs, 0);
2271+    round_fn_avx2(v, msg_vecs, 1);
2272+    round_fn_avx2(v, msg_vecs, 2);
2273+    round_fn_avx2(v, msg_vecs, 3);
2274+    round_fn_avx2(v, msg_vecs, 4);
2275+    round_fn_avx2(v, msg_vecs, 5);
2276+    round_fn_avx2(v, msg_vecs, 6);
2277+
2278+    h_vecs[0] = xorv_avx2(v[0], v[8]);
2279+    h_vecs[1] = xorv_avx2(v[1], v[9]);
2280+    h_vecs[2] = xorv_avx2(v[2], v[10]);
2281+    h_vecs[3] = xorv_avx2(v[3], v[11]);
2282+    h_vecs[4] = xorv_avx2(v[4], v[12]);
2283+    h_vecs[5] = xorv_avx2(v[5], v[13]);
2284+    h_vecs[6] = xorv_avx2(v[6], v[14]);
2285+    h_vecs[7] = xorv_avx2(v[7], v[15]);
2286+
2287+    block_flags = flags;
2288+  }
2289+
2290+  transpose_vecs_avx2(h_vecs);
2291+  storeu_avx2(h_vecs[0], &out_bytes[0 * sizeof(__m256i)]);
2292+  storeu_avx2(h_vecs[1], &out_bytes[1 * sizeof(__m256i)]);
2293+  storeu_avx2(h_vecs[2], &out_bytes[2 * sizeof(__m256i)]);
2294+  storeu_avx2(h_vecs[3], &out_bytes[3 * sizeof(__m256i)]);
2295+  storeu_avx2(h_vecs[4], &out_bytes[4 * sizeof(__m256i)]);
2296+  storeu_avx2(h_vecs[5], &out_bytes[5 * sizeof(__m256i)]);
2297+  storeu_avx2(h_vecs[6], &out_bytes[6 * sizeof(__m256i)]);
2298+  storeu_avx2(h_vecs[7], &out_bytes[7 * sizeof(__m256i)]);
2299+}
2300+
2301+void
2302+blake3_hash_many_avx2(
2303+    const uint8_t *const *inputs,
2304+    size_t                num_inputs,
2305+    size_t                blocks,
2306+    const uint32_t        key[8],
2307+    uint64_t              counter,
2308+    int                   increment_counter,
2309+    uint8_t               flags,
2310+    uint8_t               flags_start,
2311+    uint8_t               flags_end,
2312+    uint8_t              *out_bytes
2313+)
2314+{
2315+  while (num_inputs >= DEGREE_AVX2) {
2316+    blake3_hash8_avx2(
2317+        inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out_bytes
2318+    );
2319+    if (increment_counter) {
2320+      counter += DEGREE_AVX2;
2321+    }
2322+    inputs += DEGREE_AVX2;
2323+    num_inputs -= DEGREE_AVX2;
2324+    out_bytes = &out_bytes[DEGREE_AVX2 * BLAKE3_OUT_LEN];
2325+  }
2326+  blake3_hash_many_sse41(
2327+      inputs,
2328+      num_inputs,
2329+      blocks,
2330+      key,
2331+      counter,
2332+      increment_counter,
2333+      flags,
2334+      flags_start,
2335+      flags_end,
2336+      out_bytes
2337+  );
2338+}
2339+#if defined(__clang__)
2340+#pragma clang attribute pop
2341+#elif defined(__GNUC__)
2342+#pragma GCC pop_options
2343+#endif
2344+
2345+#if defined(__clang__)
2346+#pragma clang attribute push(__attribute__((target("avx512f,avx512vl"))), apply_to = function)
2347+#elif defined(__GNUC__)
2348+#pragma GCC push_options
2349+#pragma GCC target("avx512f,avx512vl")
2350+#endif
2351+static inline __m128i
2352+loadu_128_avx512(const uint8_t src[16])
2353+{
2354+  return _mm_loadu_si128((const __m128i *)src);
2355+}
2356+
2357+static inline __m256i
2358+loadu_256_avx512(const uint8_t src[32])
2359+{
2360+  return _mm256_loadu_si256((const __m256i *)src);
2361+}
2362+
2363+static inline __m512i
2364+loadu_512_avx512(const uint8_t src[64])
2365+{
2366+  return _mm512_loadu_si512((const __m512i *)src);
2367+}
2368+
2369+static inline void
2370+storeu_128_avx512(__m128i src, uint8_t dest[16])
2371+{
2372+  _mm_storeu_si128((__m128i *)dest, src);
2373+}
2374+
2375+static inline void
2376+storeu_256_avx512(__m256i src, uint8_t dest[32])
2377+{
2378+  _mm256_storeu_si256((__m256i *)dest, src);
2379+}
2380+
2381+static inline __m128i
2382+add_128_avx512(__m128i a, __m128i b)
2383+{
2384+  return _mm_add_epi32(a, b);
2385+}
2386+
2387+static inline __m256i
2388+add_256_avx512(__m256i a, __m256i b)
2389+{
2390+  return _mm256_add_epi32(a, b);
2391+}
2392+
2393+static inline __m512i
2394+add_512_avx512(__m512i a, __m512i b)
2395+{
2396+  return _mm512_add_epi32(a, b);
2397+}
2398+
2399+static inline __m128i
2400+xor_128_avx512(__m128i a, __m128i b)
2401+{
2402+  return _mm_xor_si128(a, b);
2403+}
2404+
2405+static inline __m256i
2406+xor_256_avx512(__m256i a, __m256i b)
2407+{
2408+  return _mm256_xor_si256(a, b);
2409+}
2410+
2411+static inline __m512i
2412+xor_512_avx512(__m512i a, __m512i b)
2413+{
2414+  return _mm512_xor_si512(a, b);
2415+}
2416+
2417+static inline __m128i
2418+set1_128_avx512(uint32_t x)
2419+{
2420+  return _mm_set1_epi32((int32_t)x);
2421+}
2422+
2423+static inline __m256i
2424+set1_256_avx512(uint32_t x)
2425+{
2426+  return _mm256_set1_epi32((int32_t)x);
2427+}
2428+
2429+static inline __m512i
2430+set1_512_avx512(uint32_t x)
2431+{
2432+  return _mm512_set1_epi32((int32_t)x);
2433+}
2434+
2435+static inline __m128i
2436+set4_avx512(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
2437+{
2438+  return _mm_setr_epi32((int32_t)a, (int32_t)b, (int32_t)c, (int32_t)d);
2439+}
2440+
2441+static inline __m128i
2442+rot16_128_avx512(__m128i x)
2443+{
2444+  return _mm_ror_epi32(x, 16);
2445+}
2446+
2447+static inline __m256i
2448+rot16_256_avx512(__m256i x)
2449+{
2450+  return _mm256_ror_epi32(x, 16);
2451+}
2452+
2453+static inline __m512i
2454+rot16_512_avx512(__m512i x)
2455+{
2456+  return _mm512_ror_epi32(x, 16);
2457+}
2458+
2459+static inline __m128i
2460+rot12_128_avx512(__m128i x)
2461+{
2462+  return _mm_ror_epi32(x, 12);
2463+}
2464+
2465+static inline __m256i
2466+rot12_256_avx512(__m256i x)
2467+{
2468+  return _mm256_ror_epi32(x, 12);
2469+}
2470+
2471+static inline __m512i
2472+rot12_512_avx512(__m512i x)
2473+{
2474+  return _mm512_ror_epi32(x, 12);
2475+}
2476+
2477+static inline __m128i
2478+rot8_128_avx512(__m128i x)
2479+{
2480+  return _mm_ror_epi32(x, 8);
2481+}
2482+
2483+static inline __m256i
2484+rot8_256_avx512(__m256i x)
2485+{
2486+  return _mm256_ror_epi32(x, 8);
2487+}
2488+
2489+static inline __m512i
2490+rot8_512_avx512(__m512i x)
2491+{
2492+  return _mm512_ror_epi32(x, 8);
2493+}
2494+
2495+static inline __m128i
2496+rot7_128_avx512(__m128i x)
2497+{
2498+  return _mm_ror_epi32(x, 7);
2499+}
2500+
2501+static inline __m256i
2502+rot7_256_avx512(__m256i x)
2503+{
2504+  return _mm256_ror_epi32(x, 7);
2505+}
2506+
2507+static inline __m512i
2508+rot7_512_avx512(__m512i x)
2509+{
2510+  return _mm512_ror_epi32(x, 7);
2511+}
2512+
2513+static inline void
2514+g1_avx512(__m128i *row0, __m128i *row1, __m128i *row2, __m128i *row3, __m128i m)
2515+{
2516+  *row0 = add_128_avx512(add_128_avx512(*row0, m), *row1);
2517+  *row3 = xor_128_avx512(*row3, *row0);
2518+  *row3 = rot16_128_avx512(*row3);
2519+  *row2 = add_128_avx512(*row2, *row3);
2520+  *row1 = xor_128_avx512(*row1, *row2);
2521+  *row1 = rot12_128_avx512(*row1);
2522+}
2523+
2524+static inline void
2525+g2_avx512(__m128i *row0, __m128i *row1, __m128i *row2, __m128i *row3, __m128i m)
2526+{
2527+  *row0 = add_128_avx512(add_128_avx512(*row0, m), *row1);
2528+  *row3 = xor_128_avx512(*row3, *row0);
2529+  *row3 = rot8_128_avx512(*row3);
2530+  *row2 = add_128_avx512(*row2, *row3);
2531+  *row1 = xor_128_avx512(*row1, *row2);
2532+  *row1 = rot7_128_avx512(*row1);
2533+}
2534+
2535+static inline void
2536+diagonalize_avx512(__m128i *row0, __m128i *row2, __m128i *row3)
2537+{
2538+  *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE(2, 1, 0, 3));
2539+  *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE(1, 0, 3, 2));
2540+  *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE(0, 3, 2, 1));
2541+}
2542+
2543+static inline void
2544+undiagonalize_avx512(__m128i *row0, __m128i *row2, __m128i *row3)
2545+{
2546+  *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE(0, 3, 2, 1));
2547+  *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE(1, 0, 3, 2));
2548+  *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE(2, 1, 0, 3));
2549+}
2550+
2551+static inline void
2552+compress_pre_avx512(
2553+    __m128i        rows[4],
2554+    const uint32_t cv[8],
2555+    const uint8_t  block[BLAKE3_BLOCK_LEN],
2556+    uint8_t        block_len,
2557+    uint64_t       counter,
2558+    uint8_t        flags
2559+)
2560+{
2561+  __m128i m0, m1, m2, m3;
2562+  __m128i t0, t1, t2, t3;
2563+
2564+  rows[0] = loadu_128_avx512((const uint8_t *)&cv[0]);
2565+  rows[1] = loadu_128_avx512((const uint8_t *)&cv[4]);
2566+  rows[2] = set4_avx512(IV[0], IV[1], IV[2], IV[3]);
2567+  rows[3] = set4_avx512(
2568+      counter_low(counter), counter_high(counter), (uint32_t)block_len, (uint32_t)flags
2569+  );
2570+
2571+  m0 = loadu_128_avx512(&block[sizeof(__m128i) * 0]);
2572+  m1 = loadu_128_avx512(&block[sizeof(__m128i) * 1]);
2573+  m2 = loadu_128_avx512(&block[sizeof(__m128i) * 2]);
2574+  m3 = loadu_128_avx512(&block[sizeof(__m128i) * 3]);
2575+
2576+  /* round 1 */
2577+  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(2, 0, 2, 0));
2578+  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t0);
2579+  t1 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 3, 1));
2580+  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t1);
2581+  diagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2582+  t2 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(2, 0, 2, 0));
2583+  t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2, 1, 0, 3));
2584+  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t2);
2585+  t3 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 1, 3, 1));
2586+  t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(2, 1, 0, 3));
2587+  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t3);
2588+  undiagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2589+  m0 = t0;
2590+  m1 = t1;
2591+  m2 = t2;
2592+  m3 = t3;
2593+
2594+  /* round 2 */
2595+  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
2596+  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
2597+  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t0);
2598+  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
2599+  t1 = _mm_blend_epi16(m0, t1, 0xCC);
2600+  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t1);
2601+  diagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2602+  t2 = _mm_unpacklo_epi64(m3, m1);
2603+  t2 = _mm_blend_epi16(t2, m2, 0xC0);
2604+  t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1, 3, 2, 0));
2605+  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t2);
2606+  t3 = _mm_unpackhi_epi32(m1, m3);
2607+  t3 = _mm_unpacklo_epi32(m2, t3);
2608+  t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(0, 1, 3, 2));
2609+  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t3);
2610+  undiagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2611+  m0 = t0;
2612+  m1 = t1;
2613+  m2 = t2;
2614+  m3 = t3;
2615+
2616+  /* round 3 */
2617+  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
2618+  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
2619+  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t0);
2620+  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
2621+  t1 = _mm_blend_epi16(m0, t1, 0xCC);
2622+  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t1);
2623+  diagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2624+  t2 = _mm_unpacklo_epi64(m3, m1);
2625+  t2 = _mm_blend_epi16(t2, m2, 0xC0);
2626+  t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1, 3, 2, 0));
2627+  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t2);
2628+  t3 = _mm_unpackhi_epi32(m1, m3);
2629+  t3 = _mm_unpacklo_epi32(m2, t3);
2630+  t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(0, 1, 3, 2));
2631+  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t3);
2632+  undiagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2633+  m0 = t0;
2634+  m1 = t1;
2635+  m2 = t2;
2636+  m3 = t3;
2637+
2638+  /* round 4 */
2639+  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
2640+  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
2641+  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t0);
2642+  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
2643+  t1 = _mm_blend_epi16(m0, t1, 0xCC);
2644+  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t1);
2645+  diagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2646+  t2 = _mm_unpacklo_epi64(m3, m1);
2647+  t2 = _mm_blend_epi16(t2, m2, 0xC0);
2648+  t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1, 3, 2, 0));
2649+  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t2);
2650+  t3 = _mm_unpackhi_epi32(m1, m3);
2651+  t3 = _mm_unpacklo_epi32(m2, t3);
2652+  t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(0, 1, 3, 2));
2653+  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t3);
2654+  undiagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2655+  m0 = t0;
2656+  m1 = t1;
2657+  m2 = t2;
2658+  m3 = t3;
2659+
2660+  /* round 5 */
2661+  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
2662+  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
2663+  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t0);
2664+  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
2665+  t1 = _mm_blend_epi16(m0, t1, 0xCC);
2666+  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t1);
2667+  diagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2668+  t2 = _mm_unpacklo_epi64(m3, m1);
2669+  t2 = _mm_blend_epi16(t2, m2, 0xC0);
2670+  t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1, 3, 2, 0));
2671+  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t2);
2672+  t3 = _mm_unpackhi_epi32(m1, m3);
2673+  t3 = _mm_unpacklo_epi32(m2, t3);
2674+  t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(0, 1, 3, 2));
2675+  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t3);
2676+  undiagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2677+  m0 = t0;
2678+  m1 = t1;
2679+  m2 = t2;
2680+  m3 = t3;
2681+
2682+  /* round 6 */
2683+  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
2684+  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
2685+  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t0);
2686+  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
2687+  t1 = _mm_blend_epi16(m0, t1, 0xCC);
2688+  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t1);
2689+  diagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2690+  t2 = _mm_unpacklo_epi64(m3, m1);
2691+  t2 = _mm_blend_epi16(t2, m2, 0xC0);
2692+  t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1, 3, 2, 0));
2693+  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t2);
2694+  t3 = _mm_unpackhi_epi32(m1, m3);
2695+  t3 = _mm_unpacklo_epi32(m2, t3);
2696+  t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(0, 1, 3, 2));
2697+  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t3);
2698+  undiagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2699+  m0 = t0;
2700+  m1 = t1;
2701+  m2 = t2;
2702+  m3 = t3;
2703+
2704+  /* round 7 */
2705+  t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2));
2706+  t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1));
2707+  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t0);
2708+  t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2));
2709+  t1 = _mm_blend_epi16(m0, t1, 0xCC);
2710+  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t1);
2711+  diagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2712+  t2 = _mm_unpacklo_epi64(m3, m1);
2713+  t2 = _mm_blend_epi16(t2, m2, 0xC0);
2714+  t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1, 3, 2, 0));
2715+  g1_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t2);
2716+  t3 = _mm_unpackhi_epi32(m1, m3);
2717+  t3 = _mm_unpacklo_epi32(m2, t3);
2718+  t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(0, 1, 3, 2));
2719+  g2_avx512(&rows[0], &rows[1], &rows[2], &rows[3], t3);
2720+  undiagonalize_avx512(&rows[0], &rows[2], &rows[3]);
2721+}
2722+
2723+void
2724+blake3_compress_in_place_avx512(
2725+    uint32_t      cv[8],
2726+    const uint8_t block[BLAKE3_BLOCK_LEN],
2727+    uint8_t       block_len,
2728+    uint64_t      counter,
2729+    uint8_t       flags
2730+)
2731+{
2732+  __m128i rows[4];
2733+
2734+  compress_pre_avx512(rows, cv, block, block_len, counter, flags);
2735+  storeu_128_avx512(xor_128_avx512(rows[0], rows[2]), (uint8_t *)&cv[0]);
2736+  storeu_128_avx512(xor_128_avx512(rows[1], rows[3]), (uint8_t *)&cv[4]);
2737+}
2738+
2739+void
2740+blake3_compress_xof_avx512(
2741+    const uint32_t cv[8],
2742+    const uint8_t  block[BLAKE3_BLOCK_LEN],
2743+    uint8_t        block_len,
2744+    uint64_t       counter,
2745+    uint8_t        flags,
2746+    uint8_t        out_buf[64]
2747+)
2748+{
2749+  __m128i rows[4];
2750+
2751+  compress_pre_avx512(rows, cv, block, block_len, counter, flags);
2752+  storeu_128_avx512(xor_128_avx512(rows[0], rows[2]), &out_buf[0]);
2753+  storeu_128_avx512(xor_128_avx512(rows[1], rows[3]), &out_buf[16]);
2754+  storeu_128_avx512(
2755+      xor_128_avx512(rows[2], loadu_128_avx512((const uint8_t *)&cv[0])), &out_buf[32]
2756+  );
2757+  storeu_128_avx512(
2758+      xor_128_avx512(rows[3], loadu_128_avx512((const uint8_t *)&cv[4])), &out_buf[48]
2759+  );
2760+}
2761+
2762+static inline void
2763+round_fn4_avx512(__m128i v[16], __m128i m[16], size_t r)
2764+{
2765+  v[0]  = add_128_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][0]]);
2766+  v[1]  = add_128_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][2]]);
2767+  v[2]  = add_128_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][4]]);
2768+  v[3]  = add_128_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][6]]);
2769+  v[0]  = add_128_avx512(v[0], v[4]);
2770+  v[1]  = add_128_avx512(v[1], v[5]);
2771+  v[2]  = add_128_avx512(v[2], v[6]);
2772+  v[3]  = add_128_avx512(v[3], v[7]);
2773+  v[12] = xor_128_avx512(v[12], v[0]);
2774+  v[13] = xor_128_avx512(v[13], v[1]);
2775+  v[14] = xor_128_avx512(v[14], v[2]);
2776+  v[15] = xor_128_avx512(v[15], v[3]);
2777+  v[12] = rot16_128_avx512(v[12]);
2778+  v[13] = rot16_128_avx512(v[13]);
2779+  v[14] = rot16_128_avx512(v[14]);
2780+  v[15] = rot16_128_avx512(v[15]);
2781+  v[8]  = add_128_avx512(v[8], v[12]);
2782+  v[9]  = add_128_avx512(v[9], v[13]);
2783+  v[10] = add_128_avx512(v[10], v[14]);
2784+  v[11] = add_128_avx512(v[11], v[15]);
2785+  v[4]  = xor_128_avx512(v[4], v[8]);
2786+  v[5]  = xor_128_avx512(v[5], v[9]);
2787+  v[6]  = xor_128_avx512(v[6], v[10]);
2788+  v[7]  = xor_128_avx512(v[7], v[11]);
2789+  v[4]  = rot12_128_avx512(v[4]);
2790+  v[5]  = rot12_128_avx512(v[5]);
2791+  v[6]  = rot12_128_avx512(v[6]);
2792+  v[7]  = rot12_128_avx512(v[7]);
2793+  v[0]  = add_128_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][1]]);
2794+  v[1]  = add_128_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][3]]);
2795+  v[2]  = add_128_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][5]]);
2796+  v[3]  = add_128_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][7]]);
2797+  v[0]  = add_128_avx512(v[0], v[4]);
2798+  v[1]  = add_128_avx512(v[1], v[5]);
2799+  v[2]  = add_128_avx512(v[2], v[6]);
2800+  v[3]  = add_128_avx512(v[3], v[7]);
2801+  v[12] = xor_128_avx512(v[12], v[0]);
2802+  v[13] = xor_128_avx512(v[13], v[1]);
2803+  v[14] = xor_128_avx512(v[14], v[2]);
2804+  v[15] = xor_128_avx512(v[15], v[3]);
2805+  v[12] = rot8_128_avx512(v[12]);
2806+  v[13] = rot8_128_avx512(v[13]);
2807+  v[14] = rot8_128_avx512(v[14]);
2808+  v[15] = rot8_128_avx512(v[15]);
2809+  v[8]  = add_128_avx512(v[8], v[12]);
2810+  v[9]  = add_128_avx512(v[9], v[13]);
2811+  v[10] = add_128_avx512(v[10], v[14]);
2812+  v[11] = add_128_avx512(v[11], v[15]);
2813+  v[4]  = xor_128_avx512(v[4], v[8]);
2814+  v[5]  = xor_128_avx512(v[5], v[9]);
2815+  v[6]  = xor_128_avx512(v[6], v[10]);
2816+  v[7]  = xor_128_avx512(v[7], v[11]);
2817+  v[4]  = rot7_128_avx512(v[4]);
2818+  v[5]  = rot7_128_avx512(v[5]);
2819+  v[6]  = rot7_128_avx512(v[6]);
2820+  v[7]  = rot7_128_avx512(v[7]);
2821+
2822+  v[0]  = add_128_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][8]]);
2823+  v[1]  = add_128_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][10]]);
2824+  v[2]  = add_128_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][12]]);
2825+  v[3]  = add_128_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][14]]);
2826+  v[0]  = add_128_avx512(v[0], v[5]);
2827+  v[1]  = add_128_avx512(v[1], v[6]);
2828+  v[2]  = add_128_avx512(v[2], v[7]);
2829+  v[3]  = add_128_avx512(v[3], v[4]);
2830+  v[15] = xor_128_avx512(v[15], v[0]);
2831+  v[12] = xor_128_avx512(v[12], v[1]);
2832+  v[13] = xor_128_avx512(v[13], v[2]);
2833+  v[14] = xor_128_avx512(v[14], v[3]);
2834+  v[15] = rot16_128_avx512(v[15]);
2835+  v[12] = rot16_128_avx512(v[12]);
2836+  v[13] = rot16_128_avx512(v[13]);
2837+  v[14] = rot16_128_avx512(v[14]);
2838+  v[10] = add_128_avx512(v[10], v[15]);
2839+  v[11] = add_128_avx512(v[11], v[12]);
2840+  v[8]  = add_128_avx512(v[8], v[13]);
2841+  v[9]  = add_128_avx512(v[9], v[14]);
2842+  v[5]  = xor_128_avx512(v[5], v[10]);
2843+  v[6]  = xor_128_avx512(v[6], v[11]);
2844+  v[7]  = xor_128_avx512(v[7], v[8]);
2845+  v[4]  = xor_128_avx512(v[4], v[9]);
2846+  v[5]  = rot12_128_avx512(v[5]);
2847+  v[6]  = rot12_128_avx512(v[6]);
2848+  v[7]  = rot12_128_avx512(v[7]);
2849+  v[4]  = rot12_128_avx512(v[4]);
2850+  v[0]  = add_128_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][9]]);
2851+  v[1]  = add_128_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][11]]);
2852+  v[2]  = add_128_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][13]]);
2853+  v[3]  = add_128_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][15]]);
2854+  v[0]  = add_128_avx512(v[0], v[5]);
2855+  v[1]  = add_128_avx512(v[1], v[6]);
2856+  v[2]  = add_128_avx512(v[2], v[7]);
2857+  v[3]  = add_128_avx512(v[3], v[4]);
2858+  v[15] = xor_128_avx512(v[15], v[0]);
2859+  v[12] = xor_128_avx512(v[12], v[1]);
2860+  v[13] = xor_128_avx512(v[13], v[2]);
2861+  v[14] = xor_128_avx512(v[14], v[3]);
2862+  v[15] = rot8_128_avx512(v[15]);
2863+  v[12] = rot8_128_avx512(v[12]);
2864+  v[13] = rot8_128_avx512(v[13]);
2865+  v[14] = rot8_128_avx512(v[14]);
2866+  v[10] = add_128_avx512(v[10], v[15]);
2867+  v[11] = add_128_avx512(v[11], v[12]);
2868+  v[8]  = add_128_avx512(v[8], v[13]);
2869+  v[9]  = add_128_avx512(v[9], v[14]);
2870+  v[5]  = xor_128_avx512(v[5], v[10]);
2871+  v[6]  = xor_128_avx512(v[6], v[11]);
2872+  v[7]  = xor_128_avx512(v[7], v[8]);
2873+  v[4]  = xor_128_avx512(v[4], v[9]);
2874+  v[5]  = rot7_128_avx512(v[5]);
2875+  v[6]  = rot7_128_avx512(v[6]);
2876+  v[7]  = rot7_128_avx512(v[7]);
2877+  v[4]  = rot7_128_avx512(v[4]);
2878+}
2879+
2880+static inline void
2881+round_fn8_avx512(__m256i v[16], __m256i m[16], size_t r)
2882+{
2883+  v[0]  = add_256_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][0]]);
2884+  v[1]  = add_256_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][2]]);
2885+  v[2]  = add_256_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][4]]);
2886+  v[3]  = add_256_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][6]]);
2887+  v[0]  = add_256_avx512(v[0], v[4]);
2888+  v[1]  = add_256_avx512(v[1], v[5]);
2889+  v[2]  = add_256_avx512(v[2], v[6]);
2890+  v[3]  = add_256_avx512(v[3], v[7]);
2891+  v[12] = xor_256_avx512(v[12], v[0]);
2892+  v[13] = xor_256_avx512(v[13], v[1]);
2893+  v[14] = xor_256_avx512(v[14], v[2]);
2894+  v[15] = xor_256_avx512(v[15], v[3]);
2895+  v[12] = rot16_256_avx512(v[12]);
2896+  v[13] = rot16_256_avx512(v[13]);
2897+  v[14] = rot16_256_avx512(v[14]);
2898+  v[15] = rot16_256_avx512(v[15]);
2899+  v[8]  = add_256_avx512(v[8], v[12]);
2900+  v[9]  = add_256_avx512(v[9], v[13]);
2901+  v[10] = add_256_avx512(v[10], v[14]);
2902+  v[11] = add_256_avx512(v[11], v[15]);
2903+  v[4]  = xor_256_avx512(v[4], v[8]);
2904+  v[5]  = xor_256_avx512(v[5], v[9]);
2905+  v[6]  = xor_256_avx512(v[6], v[10]);
2906+  v[7]  = xor_256_avx512(v[7], v[11]);
2907+  v[4]  = rot12_256_avx512(v[4]);
2908+  v[5]  = rot12_256_avx512(v[5]);
2909+  v[6]  = rot12_256_avx512(v[6]);
2910+  v[7]  = rot12_256_avx512(v[7]);
2911+  v[0]  = add_256_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][1]]);
2912+  v[1]  = add_256_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][3]]);
2913+  v[2]  = add_256_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][5]]);
2914+  v[3]  = add_256_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][7]]);
2915+  v[0]  = add_256_avx512(v[0], v[4]);
2916+  v[1]  = add_256_avx512(v[1], v[5]);
2917+  v[2]  = add_256_avx512(v[2], v[6]);
2918+  v[3]  = add_256_avx512(v[3], v[7]);
2919+  v[12] = xor_256_avx512(v[12], v[0]);
2920+  v[13] = xor_256_avx512(v[13], v[1]);
2921+  v[14] = xor_256_avx512(v[14], v[2]);
2922+  v[15] = xor_256_avx512(v[15], v[3]);
2923+  v[12] = rot8_256_avx512(v[12]);
2924+  v[13] = rot8_256_avx512(v[13]);
2925+  v[14] = rot8_256_avx512(v[14]);
2926+  v[15] = rot8_256_avx512(v[15]);
2927+  v[8]  = add_256_avx512(v[8], v[12]);
2928+  v[9]  = add_256_avx512(v[9], v[13]);
2929+  v[10] = add_256_avx512(v[10], v[14]);
2930+  v[11] = add_256_avx512(v[11], v[15]);
2931+  v[4]  = xor_256_avx512(v[4], v[8]);
2932+  v[5]  = xor_256_avx512(v[5], v[9]);
2933+  v[6]  = xor_256_avx512(v[6], v[10]);
2934+  v[7]  = xor_256_avx512(v[7], v[11]);
2935+  v[4]  = rot7_256_avx512(v[4]);
2936+  v[5]  = rot7_256_avx512(v[5]);
2937+  v[6]  = rot7_256_avx512(v[6]);
2938+  v[7]  = rot7_256_avx512(v[7]);
2939+
2940+  v[0]  = add_256_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][8]]);
2941+  v[1]  = add_256_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][10]]);
2942+  v[2]  = add_256_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][12]]);
2943+  v[3]  = add_256_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][14]]);
2944+  v[0]  = add_256_avx512(v[0], v[5]);
2945+  v[1]  = add_256_avx512(v[1], v[6]);
2946+  v[2]  = add_256_avx512(v[2], v[7]);
2947+  v[3]  = add_256_avx512(v[3], v[4]);
2948+  v[15] = xor_256_avx512(v[15], v[0]);
2949+  v[12] = xor_256_avx512(v[12], v[1]);
2950+  v[13] = xor_256_avx512(v[13], v[2]);
2951+  v[14] = xor_256_avx512(v[14], v[3]);
2952+  v[15] = rot16_256_avx512(v[15]);
2953+  v[12] = rot16_256_avx512(v[12]);
2954+  v[13] = rot16_256_avx512(v[13]);
2955+  v[14] = rot16_256_avx512(v[14]);
2956+  v[10] = add_256_avx512(v[10], v[15]);
2957+  v[11] = add_256_avx512(v[11], v[12]);
2958+  v[8]  = add_256_avx512(v[8], v[13]);
2959+  v[9]  = add_256_avx512(v[9], v[14]);
2960+  v[5]  = xor_256_avx512(v[5], v[10]);
2961+  v[6]  = xor_256_avx512(v[6], v[11]);
2962+  v[7]  = xor_256_avx512(v[7], v[8]);
2963+  v[4]  = xor_256_avx512(v[4], v[9]);
2964+  v[5]  = rot12_256_avx512(v[5]);
2965+  v[6]  = rot12_256_avx512(v[6]);
2966+  v[7]  = rot12_256_avx512(v[7]);
2967+  v[4]  = rot12_256_avx512(v[4]);
2968+  v[0]  = add_256_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][9]]);
2969+  v[1]  = add_256_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][11]]);
2970+  v[2]  = add_256_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][13]]);
2971+  v[3]  = add_256_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][15]]);
2972+  v[0]  = add_256_avx512(v[0], v[5]);
2973+  v[1]  = add_256_avx512(v[1], v[6]);
2974+  v[2]  = add_256_avx512(v[2], v[7]);
2975+  v[3]  = add_256_avx512(v[3], v[4]);
2976+  v[15] = xor_256_avx512(v[15], v[0]);
2977+  v[12] = xor_256_avx512(v[12], v[1]);
2978+  v[13] = xor_256_avx512(v[13], v[2]);
2979+  v[14] = xor_256_avx512(v[14], v[3]);
2980+  v[15] = rot8_256_avx512(v[15]);
2981+  v[12] = rot8_256_avx512(v[12]);
2982+  v[13] = rot8_256_avx512(v[13]);
2983+  v[14] = rot8_256_avx512(v[14]);
2984+  v[10] = add_256_avx512(v[10], v[15]);
2985+  v[11] = add_256_avx512(v[11], v[12]);
2986+  v[8]  = add_256_avx512(v[8], v[13]);
2987+  v[9]  = add_256_avx512(v[9], v[14]);
2988+  v[5]  = xor_256_avx512(v[5], v[10]);
2989+  v[6]  = xor_256_avx512(v[6], v[11]);
2990+  v[7]  = xor_256_avx512(v[7], v[8]);
2991+  v[4]  = xor_256_avx512(v[4], v[9]);
2992+  v[5]  = rot7_256_avx512(v[5]);
2993+  v[6]  = rot7_256_avx512(v[6]);
2994+  v[7]  = rot7_256_avx512(v[7]);
2995+  v[4]  = rot7_256_avx512(v[4]);
2996+}
2997+
2998+static inline void
2999+round_fn16_avx512(__m512i v[16], __m512i m[16], size_t r)
3000+{
3001+  v[0]  = add_512_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][0]]);
3002+  v[1]  = add_512_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][2]]);
3003+  v[2]  = add_512_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][4]]);
3004+  v[3]  = add_512_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][6]]);
3005+  v[0]  = add_512_avx512(v[0], v[4]);
3006+  v[1]  = add_512_avx512(v[1], v[5]);
3007+  v[2]  = add_512_avx512(v[2], v[6]);
3008+  v[3]  = add_512_avx512(v[3], v[7]);
3009+  v[12] = xor_512_avx512(v[12], v[0]);
3010+  v[13] = xor_512_avx512(v[13], v[1]);
3011+  v[14] = xor_512_avx512(v[14], v[2]);
3012+  v[15] = xor_512_avx512(v[15], v[3]);
3013+  v[12] = rot16_512_avx512(v[12]);
3014+  v[13] = rot16_512_avx512(v[13]);
3015+  v[14] = rot16_512_avx512(v[14]);
3016+  v[15] = rot16_512_avx512(v[15]);
3017+  v[8]  = add_512_avx512(v[8], v[12]);
3018+  v[9]  = add_512_avx512(v[9], v[13]);
3019+  v[10] = add_512_avx512(v[10], v[14]);
3020+  v[11] = add_512_avx512(v[11], v[15]);
3021+  v[4]  = xor_512_avx512(v[4], v[8]);
3022+  v[5]  = xor_512_avx512(v[5], v[9]);
3023+  v[6]  = xor_512_avx512(v[6], v[10]);
3024+  v[7]  = xor_512_avx512(v[7], v[11]);
3025+  v[4]  = rot12_512_avx512(v[4]);
3026+  v[5]  = rot12_512_avx512(v[5]);
3027+  v[6]  = rot12_512_avx512(v[6]);
3028+  v[7]  = rot12_512_avx512(v[7]);
3029+  v[0]  = add_512_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][1]]);
3030+  v[1]  = add_512_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][3]]);
3031+  v[2]  = add_512_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][5]]);
3032+  v[3]  = add_512_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][7]]);
3033+  v[0]  = add_512_avx512(v[0], v[4]);
3034+  v[1]  = add_512_avx512(v[1], v[5]);
3035+  v[2]  = add_512_avx512(v[2], v[6]);
3036+  v[3]  = add_512_avx512(v[3], v[7]);
3037+  v[12] = xor_512_avx512(v[12], v[0]);
3038+  v[13] = xor_512_avx512(v[13], v[1]);
3039+  v[14] = xor_512_avx512(v[14], v[2]);
3040+  v[15] = xor_512_avx512(v[15], v[3]);
3041+  v[12] = rot8_512_avx512(v[12]);
3042+  v[13] = rot8_512_avx512(v[13]);
3043+  v[14] = rot8_512_avx512(v[14]);
3044+  v[15] = rot8_512_avx512(v[15]);
3045+  v[8]  = add_512_avx512(v[8], v[12]);
3046+  v[9]  = add_512_avx512(v[9], v[13]);
3047+  v[10] = add_512_avx512(v[10], v[14]);
3048+  v[11] = add_512_avx512(v[11], v[15]);
3049+  v[4]  = xor_512_avx512(v[4], v[8]);
3050+  v[5]  = xor_512_avx512(v[5], v[9]);
3051+  v[6]  = xor_512_avx512(v[6], v[10]);
3052+  v[7]  = xor_512_avx512(v[7], v[11]);
3053+  v[4]  = rot7_512_avx512(v[4]);
3054+  v[5]  = rot7_512_avx512(v[5]);
3055+  v[6]  = rot7_512_avx512(v[6]);
3056+  v[7]  = rot7_512_avx512(v[7]);
3057+
3058+  v[0]  = add_512_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][8]]);
3059+  v[1]  = add_512_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][10]]);
3060+  v[2]  = add_512_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][12]]);
3061+  v[3]  = add_512_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][14]]);
3062+  v[0]  = add_512_avx512(v[0], v[5]);
3063+  v[1]  = add_512_avx512(v[1], v[6]);
3064+  v[2]  = add_512_avx512(v[2], v[7]);
3065+  v[3]  = add_512_avx512(v[3], v[4]);
3066+  v[15] = xor_512_avx512(v[15], v[0]);
3067+  v[12] = xor_512_avx512(v[12], v[1]);
3068+  v[13] = xor_512_avx512(v[13], v[2]);
3069+  v[14] = xor_512_avx512(v[14], v[3]);
3070+  v[15] = rot16_512_avx512(v[15]);
3071+  v[12] = rot16_512_avx512(v[12]);
3072+  v[13] = rot16_512_avx512(v[13]);
3073+  v[14] = rot16_512_avx512(v[14]);
3074+  v[10] = add_512_avx512(v[10], v[15]);
3075+  v[11] = add_512_avx512(v[11], v[12]);
3076+  v[8]  = add_512_avx512(v[8], v[13]);
3077+  v[9]  = add_512_avx512(v[9], v[14]);
3078+  v[5]  = xor_512_avx512(v[5], v[10]);
3079+  v[6]  = xor_512_avx512(v[6], v[11]);
3080+  v[7]  = xor_512_avx512(v[7], v[8]);
3081+  v[4]  = xor_512_avx512(v[4], v[9]);
3082+  v[5]  = rot12_512_avx512(v[5]);
3083+  v[6]  = rot12_512_avx512(v[6]);
3084+  v[7]  = rot12_512_avx512(v[7]);
3085+  v[4]  = rot12_512_avx512(v[4]);
3086+  v[0]  = add_512_avx512(v[0], m[(size_t)MSG_SCHEDULE[r][9]]);
3087+  v[1]  = add_512_avx512(v[1], m[(size_t)MSG_SCHEDULE[r][11]]);
3088+  v[2]  = add_512_avx512(v[2], m[(size_t)MSG_SCHEDULE[r][13]]);
3089+  v[3]  = add_512_avx512(v[3], m[(size_t)MSG_SCHEDULE[r][15]]);
3090+  v[0]  = add_512_avx512(v[0], v[5]);
3091+  v[1]  = add_512_avx512(v[1], v[6]);
3092+  v[2]  = add_512_avx512(v[2], v[7]);
3093+  v[3]  = add_512_avx512(v[3], v[4]);
3094+  v[15] = xor_512_avx512(v[15], v[0]);
3095+  v[12] = xor_512_avx512(v[12], v[1]);
3096+  v[13] = xor_512_avx512(v[13], v[2]);
3097+  v[14] = xor_512_avx512(v[14], v[3]);
3098+  v[15] = rot8_512_avx512(v[15]);
3099+  v[12] = rot8_512_avx512(v[12]);
3100+  v[13] = rot8_512_avx512(v[13]);
3101+  v[14] = rot8_512_avx512(v[14]);
3102+  v[10] = add_512_avx512(v[10], v[15]);
3103+  v[11] = add_512_avx512(v[11], v[12]);
3104+  v[8]  = add_512_avx512(v[8], v[13]);
3105+  v[9]  = add_512_avx512(v[9], v[14]);
3106+  v[5]  = xor_512_avx512(v[5], v[10]);
3107+  v[6]  = xor_512_avx512(v[6], v[11]);
3108+  v[7]  = xor_512_avx512(v[7], v[8]);
3109+  v[4]  = xor_512_avx512(v[4], v[9]);
3110+  v[5]  = rot7_512_avx512(v[5]);
3111+  v[6]  = rot7_512_avx512(v[6]);
3112+  v[7]  = rot7_512_avx512(v[7]);
3113+  v[4]  = rot7_512_avx512(v[4]);
3114+}
3115+
3116+#define LO_IMM8 0x88
3117+#define HI_IMM8 0xdd
3118+
3119+static inline __m512i
3120+unpack_lo_128_avx512(__m512i a, __m512i b)
3121+{
3122+  return _mm512_shuffle_i32x4(a, b, LO_IMM8);
3123+}
3124+
3125+static inline __m512i
3126+unpack_hi_128_avx512(__m512i a, __m512i b)
3127+{
3128+  return _mm512_shuffle_i32x4(a, b, HI_IMM8);
3129+}
3130+
3131+static inline void
3132+transpose_vecs_512_avx512(__m512i vecs[16])
3133+{
3134+  __m512i ab_0 = _mm512_unpacklo_epi32(vecs[0], vecs[1]);
3135+  __m512i ab_2 = _mm512_unpackhi_epi32(vecs[0], vecs[1]);
3136+  __m512i cd_0 = _mm512_unpacklo_epi32(vecs[2], vecs[3]);
3137+  __m512i cd_2 = _mm512_unpackhi_epi32(vecs[2], vecs[3]);
3138+  __m512i ef_0 = _mm512_unpacklo_epi32(vecs[4], vecs[5]);
3139+  __m512i ef_2 = _mm512_unpackhi_epi32(vecs[4], vecs[5]);
3140+  __m512i gh_0 = _mm512_unpacklo_epi32(vecs[6], vecs[7]);
3141+  __m512i gh_2 = _mm512_unpackhi_epi32(vecs[6], vecs[7]);
3142+  __m512i ij_0 = _mm512_unpacklo_epi32(vecs[8], vecs[9]);
3143+  __m512i ij_2 = _mm512_unpackhi_epi32(vecs[8], vecs[9]);
3144+  __m512i kl_0 = _mm512_unpacklo_epi32(vecs[10], vecs[11]);
3145+  __m512i kl_2 = _mm512_unpackhi_epi32(vecs[10], vecs[11]);
3146+  __m512i mn_0 = _mm512_unpacklo_epi32(vecs[12], vecs[13]);
3147+  __m512i mn_2 = _mm512_unpackhi_epi32(vecs[12], vecs[13]);
3148+  __m512i op_0 = _mm512_unpacklo_epi32(vecs[14], vecs[15]);
3149+  __m512i op_2 = _mm512_unpackhi_epi32(vecs[14], vecs[15]);
3150+
3151+  __m512i abcd_0 = _mm512_unpacklo_epi64(ab_0, cd_0);
3152+  __m512i abcd_1 = _mm512_unpackhi_epi64(ab_0, cd_0);
3153+  __m512i abcd_2 = _mm512_unpacklo_epi64(ab_2, cd_2);
3154+  __m512i abcd_3 = _mm512_unpackhi_epi64(ab_2, cd_2);
3155+  __m512i efgh_0 = _mm512_unpacklo_epi64(ef_0, gh_0);
3156+  __m512i efgh_1 = _mm512_unpackhi_epi64(ef_0, gh_0);
3157+  __m512i efgh_2 = _mm512_unpacklo_epi64(ef_2, gh_2);
3158+  __m512i efgh_3 = _mm512_unpackhi_epi64(ef_2, gh_2);
3159+  __m512i ijkl_0 = _mm512_unpacklo_epi64(ij_0, kl_0);
3160+  __m512i ijkl_1 = _mm512_unpackhi_epi64(ij_0, kl_0);
3161+  __m512i ijkl_2 = _mm512_unpacklo_epi64(ij_2, kl_2);
3162+  __m512i ijkl_3 = _mm512_unpackhi_epi64(ij_2, kl_2);
3163+  __m512i mnop_0 = _mm512_unpacklo_epi64(mn_0, op_0);
3164+  __m512i mnop_1 = _mm512_unpackhi_epi64(mn_0, op_0);
3165+  __m512i mnop_2 = _mm512_unpacklo_epi64(mn_2, op_2);
3166+  __m512i mnop_3 = _mm512_unpackhi_epi64(mn_2, op_2);
3167+
3168+  __m512i abcdefgh_0 = unpack_lo_128_avx512(abcd_0, efgh_0);
3169+  __m512i abcdefgh_1 = unpack_lo_128_avx512(abcd_1, efgh_1);
3170+  __m512i abcdefgh_2 = unpack_lo_128_avx512(abcd_2, efgh_2);
3171+  __m512i abcdefgh_3 = unpack_lo_128_avx512(abcd_3, efgh_3);
3172+  __m512i abcdefgh_4 = unpack_hi_128_avx512(abcd_0, efgh_0);
3173+  __m512i abcdefgh_5 = unpack_hi_128_avx512(abcd_1, efgh_1);
3174+  __m512i abcdefgh_6 = unpack_hi_128_avx512(abcd_2, efgh_2);
3175+  __m512i abcdefgh_7 = unpack_hi_128_avx512(abcd_3, efgh_3);
3176+  __m512i ijklmnop_0 = unpack_lo_128_avx512(ijkl_0, mnop_0);
3177+  __m512i ijklmnop_1 = unpack_lo_128_avx512(ijkl_1, mnop_1);
3178+  __m512i ijklmnop_2 = unpack_lo_128_avx512(ijkl_2, mnop_2);
3179+  __m512i ijklmnop_3 = unpack_lo_128_avx512(ijkl_3, mnop_3);
3180+  __m512i ijklmnop_4 = unpack_hi_128_avx512(ijkl_0, mnop_0);
3181+  __m512i ijklmnop_5 = unpack_hi_128_avx512(ijkl_1, mnop_1);
3182+  __m512i ijklmnop_6 = unpack_hi_128_avx512(ijkl_2, mnop_2);
3183+  __m512i ijklmnop_7 = unpack_hi_128_avx512(ijkl_3, mnop_3);
3184+
3185+  vecs[0]  = unpack_lo_128_avx512(abcdefgh_0, ijklmnop_0);
3186+  vecs[1]  = unpack_lo_128_avx512(abcdefgh_1, ijklmnop_1);
3187+  vecs[2]  = unpack_lo_128_avx512(abcdefgh_2, ijklmnop_2);
3188+  vecs[3]  = unpack_lo_128_avx512(abcdefgh_3, ijklmnop_3);
3189+  vecs[4]  = unpack_lo_128_avx512(abcdefgh_4, ijklmnop_4);
3190+  vecs[5]  = unpack_lo_128_avx512(abcdefgh_5, ijklmnop_5);
3191+  vecs[6]  = unpack_lo_128_avx512(abcdefgh_6, ijklmnop_6);
3192+  vecs[7]  = unpack_lo_128_avx512(abcdefgh_7, ijklmnop_7);
3193+  vecs[8]  = unpack_hi_128_avx512(abcdefgh_0, ijklmnop_0);
3194+  vecs[9]  = unpack_hi_128_avx512(abcdefgh_1, ijklmnop_1);
3195+  vecs[10] = unpack_hi_128_avx512(abcdefgh_2, ijklmnop_2);
3196+  vecs[11] = unpack_hi_128_avx512(abcdefgh_3, ijklmnop_3);
3197+  vecs[12] = unpack_hi_128_avx512(abcdefgh_4, ijklmnop_4);
3198+  vecs[13] = unpack_hi_128_avx512(abcdefgh_5, ijklmnop_5);
3199+  vecs[14] = unpack_hi_128_avx512(abcdefgh_6, ijklmnop_6);
3200+  vecs[15] = unpack_hi_128_avx512(abcdefgh_7, ijklmnop_7);
3201+}
3202+
3203+static inline void
3204+transpose_msg_vecs16_avx512(const uint8_t *const *inputs, size_t block_offset, __m512i out_msg[16])
3205+{
3206+  size_t i;
3207+
3208+  out_msg[0]  = loadu_512_avx512(&inputs[0][block_offset]);
3209+  out_msg[1]  = loadu_512_avx512(&inputs[1][block_offset]);
3210+  out_msg[2]  = loadu_512_avx512(&inputs[2][block_offset]);
3211+  out_msg[3]  = loadu_512_avx512(&inputs[3][block_offset]);
3212+  out_msg[4]  = loadu_512_avx512(&inputs[4][block_offset]);
3213+  out_msg[5]  = loadu_512_avx512(&inputs[5][block_offset]);
3214+  out_msg[6]  = loadu_512_avx512(&inputs[6][block_offset]);
3215+  out_msg[7]  = loadu_512_avx512(&inputs[7][block_offset]);
3216+  out_msg[8]  = loadu_512_avx512(&inputs[8][block_offset]);
3217+  out_msg[9]  = loadu_512_avx512(&inputs[9][block_offset]);
3218+  out_msg[10] = loadu_512_avx512(&inputs[10][block_offset]);
3219+  out_msg[11] = loadu_512_avx512(&inputs[11][block_offset]);
3220+  out_msg[12] = loadu_512_avx512(&inputs[12][block_offset]);
3221+  out_msg[13] = loadu_512_avx512(&inputs[13][block_offset]);
3222+  out_msg[14] = loadu_512_avx512(&inputs[14][block_offset]);
3223+  out_msg[15] = loadu_512_avx512(&inputs[15][block_offset]);
3224+
3225+  for (i = 0; i < 16; i++) {
3226+    _mm_prefetch((const void *)&inputs[i][block_offset + 256], _MM_HINT_T0);
3227+  }
3228+  transpose_vecs_512_avx512(out_msg);
3229+}
3230+
3231+static inline void
3232+load_counters16_avx512(uint64_t counter, int increment_counter, __m512i *out_lo, __m512i *out_hi)
3233+{
3234+  const __m512i mask   = _mm512_set1_epi32(-increment_counter);
3235+  const __m512i deltas = _mm512_set_epi32(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
3236+  const __m512i masked_deltas = _mm512_and_si512(deltas, mask);
3237+  const __m512i low_words = _mm512_add_epi32(_mm512_set1_epi32((int32_t)counter), masked_deltas);
3238+  const __m512i carries =
3239+      _mm512_srli_epi32(_mm512_andnot_si512(low_words, _mm512_set1_epi32((int32_t)counter)), 31);
3240+  const __m512i high_words = _mm512_add_epi32(_mm512_set1_epi32((int32_t)(counter >> 32)), carries);
3241+
3242+  *out_lo = low_words;
3243+  *out_hi = high_words;
3244+}
3245+
3246+void
3247+blake3_hash16_avx512(
3248+    const uint8_t *const *inputs,
3249+    size_t                blocks,
3250+    const uint32_t        key[8],
3251+    uint64_t              counter,
3252+    int                   increment_counter,
3253+    uint8_t               flags,
3254+    uint8_t               flags_start,
3255+    uint8_t               flags_end,
3256+    uint8_t              *out_bytes
3257+)
3258+{
3259+  __m512i h_vecs[8];
3260+  __m512i counter_low_vec, counter_high_vec;
3261+  uint8_t block_flags;
3262+  size_t  block;
3263+
3264+  h_vecs[0] = set1_512_avx512(key[0]);
3265+  h_vecs[1] = set1_512_avx512(key[1]);
3266+  h_vecs[2] = set1_512_avx512(key[2]);
3267+  h_vecs[3] = set1_512_avx512(key[3]);
3268+  h_vecs[4] = set1_512_avx512(key[4]);
3269+  h_vecs[5] = set1_512_avx512(key[5]);
3270+  h_vecs[6] = set1_512_avx512(key[6]);
3271+  h_vecs[7] = set1_512_avx512(key[7]);
3272+
3273+  load_counters16_avx512(counter, increment_counter, &counter_low_vec, &counter_high_vec);
3274+  block_flags = flags | flags_start;
3275+
3276+  for (block = 0; block < blocks; block++) {
3277+    __m512i block_len_vec;
3278+    __m512i block_flags_vec;
3279+    __m512i msg_vecs[16];
3280+    __m512i v[16];
3281+
3282+    if (block + 1 == blocks) {
3283+      block_flags |= flags_end;
3284+    }
3285+    block_len_vec   = set1_512_avx512(BLAKE3_BLOCK_LEN);
3286+    block_flags_vec = set1_512_avx512(block_flags);
3287+    transpose_msg_vecs16_avx512(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs);
3288+
3289+    v[0]  = h_vecs[0];
3290+    v[1]  = h_vecs[1];
3291+    v[2]  = h_vecs[2];
3292+    v[3]  = h_vecs[3];
3293+    v[4]  = h_vecs[4];
3294+    v[5]  = h_vecs[5];
3295+    v[6]  = h_vecs[6];
3296+    v[7]  = h_vecs[7];
3297+    v[8]  = set1_512_avx512(IV[0]);
3298+    v[9]  = set1_512_avx512(IV[1]);
3299+    v[10] = set1_512_avx512(IV[2]);
3300+    v[11] = set1_512_avx512(IV[3]);
3301+    v[12] = counter_low_vec;
3302+    v[13] = counter_high_vec;
3303+    v[14] = block_len_vec;
3304+    v[15] = block_flags_vec;
3305+
3306+    round_fn16_avx512(v, msg_vecs, 0);
3307+    round_fn16_avx512(v, msg_vecs, 1);
3308+    round_fn16_avx512(v, msg_vecs, 2);
3309+    round_fn16_avx512(v, msg_vecs, 3);
3310+    round_fn16_avx512(v, msg_vecs, 4);
3311+    round_fn16_avx512(v, msg_vecs, 5);
3312+    round_fn16_avx512(v, msg_vecs, 6);
3313+
3314+    h_vecs[0] = xor_512_avx512(v[0], v[8]);
3315+    h_vecs[1] = xor_512_avx512(v[1], v[9]);
3316+    h_vecs[2] = xor_512_avx512(v[2], v[10]);
3317+    h_vecs[3] = xor_512_avx512(v[3], v[11]);
3318+    h_vecs[4] = xor_512_avx512(v[4], v[12]);
3319+    h_vecs[5] = xor_512_avx512(v[5], v[13]);
3320+    h_vecs[6] = xor_512_avx512(v[6], v[14]);
3321+    h_vecs[7] = xor_512_avx512(v[7], v[15]);
3322+
3323+    block_flags = flags;
3324+  }
3325+
3326+  __m512i padded[16] = {
3327+      h_vecs[0],
3328+      h_vecs[1],
3329+      h_vecs[2],
3330+      h_vecs[3],
3331+      h_vecs[4],
3332+      h_vecs[5],
3333+      h_vecs[6],
3334+      h_vecs[7],
3335+      set1_512_avx512(0),
3336+      set1_512_avx512(0),
3337+      set1_512_avx512(0),
3338+      set1_512_avx512(0),
3339+      set1_512_avx512(0),
3340+      set1_512_avx512(0),
3341+      set1_512_avx512(0),
3342+      set1_512_avx512(0),
3343+  };
3344+  transpose_vecs_512_avx512(padded);
3345+  _mm256_mask_storeu_epi32(
3346+      &out_bytes[0 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[0])
3347+  );
3348+  _mm256_mask_storeu_epi32(
3349+      &out_bytes[1 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[1])
3350+  );
3351+  _mm256_mask_storeu_epi32(
3352+      &out_bytes[2 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[2])
3353+  );
3354+  _mm256_mask_storeu_epi32(
3355+      &out_bytes[3 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[3])
3356+  );
3357+  _mm256_mask_storeu_epi32(
3358+      &out_bytes[4 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[4])
3359+  );
3360+  _mm256_mask_storeu_epi32(
3361+      &out_bytes[5 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[5])
3362+  );
3363+  _mm256_mask_storeu_epi32(
3364+      &out_bytes[6 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[6])
3365+  );
3366+  _mm256_mask_storeu_epi32(
3367+      &out_bytes[7 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[7])
3368+  );
3369+  _mm256_mask_storeu_epi32(
3370+      &out_bytes[8 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[8])
3371+  );
3372+  _mm256_mask_storeu_epi32(
3373+      &out_bytes[9 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[9])
3374+  );
3375+  _mm256_mask_storeu_epi32(
3376+      &out_bytes[10 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[10])
3377+  );
3378+  _mm256_mask_storeu_epi32(
3379+      &out_bytes[11 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[11])
3380+  );
3381+  _mm256_mask_storeu_epi32(
3382+      &out_bytes[12 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[12])
3383+  );
3384+  _mm256_mask_storeu_epi32(
3385+      &out_bytes[13 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[13])
3386+  );
3387+  _mm256_mask_storeu_epi32(
3388+      &out_bytes[14 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[14])
3389+  );
3390+  _mm256_mask_storeu_epi32(
3391+      &out_bytes[15 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[15])
3392+  );
3393+}
3394+
3395+static inline void
3396+transpose_msg_vecs8_avx512(const uint8_t *const *inputs, size_t block_offset, __m256i out_msg[16])
3397+{
3398+  out_msg[0]  = loadu_256_avx512(&inputs[0][block_offset]);
3399+  out_msg[1]  = loadu_256_avx512(&inputs[1][block_offset]);
3400+  out_msg[2]  = loadu_256_avx512(&inputs[2][block_offset]);
3401+  out_msg[3]  = loadu_256_avx512(&inputs[3][block_offset]);
3402+  out_msg[4]  = loadu_256_avx512(&inputs[4][block_offset]);
3403+  out_msg[5]  = loadu_256_avx512(&inputs[5][block_offset]);
3404+  out_msg[6]  = loadu_256_avx512(&inputs[6][block_offset]);
3405+  out_msg[7]  = loadu_256_avx512(&inputs[7][block_offset]);
3406+  out_msg[8]  = loadu_256_avx512(&inputs[0][block_offset + 32]);
3407+  out_msg[9]  = loadu_256_avx512(&inputs[1][block_offset + 32]);
3408+  out_msg[10] = loadu_256_avx512(&inputs[2][block_offset + 32]);
3409+  out_msg[11] = loadu_256_avx512(&inputs[3][block_offset + 32]);
3410+  out_msg[12] = loadu_256_avx512(&inputs[4][block_offset + 32]);
3411+  out_msg[13] = loadu_256_avx512(&inputs[5][block_offset + 32]);
3412+  out_msg[14] = loadu_256_avx512(&inputs[6][block_offset + 32]);
3413+  out_msg[15] = loadu_256_avx512(&inputs[7][block_offset + 32]);
3414+
3415+  transpose_vecs_avx2(out_msg);
3416+}
3417+
3418+static inline void
3419+load_counters8_avx512(uint64_t counter, int increment_counter, __m256i *out_lo, __m256i *out_hi)
3420+{
3421+  const __m256i mask = _mm256_set1_epi32(-increment_counter);
3422+  const __m256i add0 = _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0);
3423+  const __m256i add1 = _mm256_and_si256(mask, add0);
3424+  __m256i       l    = _mm256_add_epi32(_mm256_set1_epi32((int32_t)counter), add1);
3425+  __m256i       carry =
3426+      _mm256_srli_epi32(_mm256_andnot_si256(l, _mm256_set1_epi32((int32_t)counter)), 31);
3427+  __m256i h = _mm256_add_epi32(_mm256_set1_epi32((int32_t)(counter >> 32)), carry);
3428+
3429+  *out_lo = l;
3430+  *out_hi = h;
3431+}
3432+
3433+void
3434+blake3_hash8_avx512(
3435+    const uint8_t *const *inputs,
3436+    size_t                blocks,
3437+    const uint32_t        key[8],
3438+    uint64_t              counter,
3439+    int                   increment_counter,
3440+    uint8_t               flags,
3441+    uint8_t               flags_start,
3442+    uint8_t               flags_end,
3443+    uint8_t              *out_bytes
3444+)
3445+{
3446+  __m256i h_vecs[8];
3447+  __m256i counter_low_vec, counter_high_vec;
3448+  uint8_t block_flags;
3449+  size_t  block;
3450+
3451+  h_vecs[0] = set1_256_avx512(key[0]);
3452+  h_vecs[1] = set1_256_avx512(key[1]);
3453+  h_vecs[2] = set1_256_avx512(key[2]);
3454+  h_vecs[3] = set1_256_avx512(key[3]);
3455+  h_vecs[4] = set1_256_avx512(key[4]);
3456+  h_vecs[5] = set1_256_avx512(key[5]);
3457+  h_vecs[6] = set1_256_avx512(key[6]);
3458+  h_vecs[7] = set1_256_avx512(key[7]);
3459+
3460+  load_counters8_avx512(counter, increment_counter, &counter_low_vec, &counter_high_vec);
3461+  block_flags = flags | flags_start;
3462+
3463+  for (block = 0; block < blocks; block++) {
3464+    __m256i block_len_vec;
3465+    __m256i block_flags_vec;
3466+    __m256i msg_vecs[16];
3467+    __m256i v[16];
3468+
3469+    if (block + 1 == blocks) {
3470+      block_flags |= flags_end;
3471+    }
3472+    block_len_vec   = set1_256_avx512(BLAKE3_BLOCK_LEN);
3473+    block_flags_vec = set1_256_avx512(block_flags);
3474+    transpose_msg_vecs8_avx512(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs);
3475+
3476+    v[0]  = h_vecs[0];
3477+    v[1]  = h_vecs[1];
3478+    v[2]  = h_vecs[2];
3479+    v[3]  = h_vecs[3];
3480+    v[4]  = h_vecs[4];
3481+    v[5]  = h_vecs[5];
3482+    v[6]  = h_vecs[6];
3483+    v[7]  = h_vecs[7];
3484+    v[8]  = set1_256_avx512(IV[0]);
3485+    v[9]  = set1_256_avx512(IV[1]);
3486+    v[10] = set1_256_avx512(IV[2]);
3487+    v[11] = set1_256_avx512(IV[3]);
3488+    v[12] = counter_low_vec;
3489+    v[13] = counter_high_vec;
3490+    v[14] = block_len_vec;
3491+    v[15] = block_flags_vec;
3492+
3493+    round_fn8_avx512(v, msg_vecs, 0);
3494+    round_fn8_avx512(v, msg_vecs, 1);
3495+    round_fn8_avx512(v, msg_vecs, 2);
3496+    round_fn8_avx512(v, msg_vecs, 3);
3497+    round_fn8_avx512(v, msg_vecs, 4);
3498+    round_fn8_avx512(v, msg_vecs, 5);
3499+    round_fn8_avx512(v, msg_vecs, 6);
3500+
3501+    h_vecs[0] = xor_256_avx512(v[0], v[8]);
3502+    h_vecs[1] = xor_256_avx512(v[1], v[9]);
3503+    h_vecs[2] = xor_256_avx512(v[2], v[10]);
3504+    h_vecs[3] = xor_256_avx512(v[3], v[11]);
3505+    h_vecs[4] = xor_256_avx512(v[4], v[12]);
3506+    h_vecs[5] = xor_256_avx512(v[5], v[13]);
3507+    h_vecs[6] = xor_256_avx512(v[6], v[14]);
3508+    h_vecs[7] = xor_256_avx512(v[7], v[15]);
3509+
3510+    block_flags = flags;
3511+  }
3512+
3513+  transpose_vecs_avx2(h_vecs);
3514+  storeu_256_avx512(h_vecs[0], &out_bytes[0 * sizeof(__m256i)]);
3515+  storeu_256_avx512(h_vecs[1], &out_bytes[1 * sizeof(__m256i)]);
3516+  storeu_256_avx512(h_vecs[2], &out_bytes[2 * sizeof(__m256i)]);
3517+  storeu_256_avx512(h_vecs[3], &out_bytes[3 * sizeof(__m256i)]);
3518+  storeu_256_avx512(h_vecs[4], &out_bytes[4 * sizeof(__m256i)]);
3519+  storeu_256_avx512(h_vecs[5], &out_bytes[5 * sizeof(__m256i)]);
3520+  storeu_256_avx512(h_vecs[6], &out_bytes[6 * sizeof(__m256i)]);
3521+  storeu_256_avx512(h_vecs[7], &out_bytes[7 * sizeof(__m256i)]);
3522+}
3523+
3524+static inline void
3525+transpose_msg_vecs4_avx512(const uint8_t *const *inputs, size_t block_offset, __m128i out_msg[16])
3526+{
3527+  out_msg[0]  = loadu_128_avx512(&inputs[0][block_offset]);
3528+  out_msg[1]  = loadu_128_avx512(&inputs[1][block_offset]);
3529+  out_msg[2]  = loadu_128_avx512(&inputs[2][block_offset]);
3530+  out_msg[3]  = loadu_128_avx512(&inputs[3][block_offset]);
3531+  out_msg[4]  = loadu_128_avx512(&inputs[0][block_offset + 16]);
3532+  out_msg[5]  = loadu_128_avx512(&inputs[1][block_offset + 16]);
3533+  out_msg[6]  = loadu_128_avx512(&inputs[2][block_offset + 16]);
3534+  out_msg[7]  = loadu_128_avx512(&inputs[3][block_offset + 16]);
3535+  out_msg[8]  = loadu_128_avx512(&inputs[0][block_offset + 32]);
3536+  out_msg[9]  = loadu_128_avx512(&inputs[1][block_offset + 32]);
3537+  out_msg[10] = loadu_128_avx512(&inputs[2][block_offset + 32]);
3538+  out_msg[11] = loadu_128_avx512(&inputs[3][block_offset + 32]);
3539+  out_msg[12] = loadu_128_avx512(&inputs[0][block_offset + 48]);
3540+  out_msg[13] = loadu_128_avx512(&inputs[1][block_offset + 48]);
3541+  out_msg[14] = loadu_128_avx512(&inputs[2][block_offset + 48]);
3542+  out_msg[15] = loadu_128_avx512(&inputs[3][block_offset + 48]);
3543+
3544+  transpose_vecs_sse2(out_msg);
3545+}
3546+
3547+static inline void
3548+load_counters4_avx512(uint64_t counter, int increment_counter, __m128i *out_lo, __m128i *out_hi)
3549+{
3550+  const __m128i mask  = _mm_set1_epi32(-increment_counter);
3551+  const __m128i add0  = _mm_set_epi32(3, 2, 1, 0);
3552+  const __m128i add1  = _mm_and_si128(mask, add0);
3553+  __m128i       l     = _mm_add_epi32(_mm_set1_epi32((int32_t)counter), add1);
3554+  __m128i       carry = _mm_srli_epi32(_mm_andnot_si128(l, _mm_set1_epi32((int32_t)counter)), 31);
3555+  __m128i       h     = _mm_add_epi32(_mm_set1_epi32((int32_t)(counter >> 32)), carry);
3556+
3557+  *out_lo = l;
3558+  *out_hi = h;
3559+}
3560+
3561+void
3562+blake3_hash4_avx512(
3563+    const uint8_t *const *inputs,
3564+    size_t                blocks,
3565+    const uint32_t        key[8],
3566+    uint64_t              counter,
3567+    int                   increment_counter,
3568+    uint8_t               flags,
3569+    uint8_t               flags_start,
3570+    uint8_t               flags_end,
3571+    uint8_t              *out_bytes
3572+)
3573+{
3574+  __m128i h_vecs[8];
3575+  __m128i counter_low_vec, counter_high_vec;
3576+  uint8_t block_flags;
3577+  size_t  block;
3578+
3579+  h_vecs[0] = set1_128_avx512(key[0]);
3580+  h_vecs[1] = set1_128_avx512(key[1]);
3581+  h_vecs[2] = set1_128_avx512(key[2]);
3582+  h_vecs[3] = set1_128_avx512(key[3]);
3583+  h_vecs[4] = set1_128_avx512(key[4]);
3584+  h_vecs[5] = set1_128_avx512(key[5]);
3585+  h_vecs[6] = set1_128_avx512(key[6]);
3586+  h_vecs[7] = set1_128_avx512(key[7]);
3587+
3588+  load_counters4_avx512(counter, increment_counter, &counter_low_vec, &counter_high_vec);
3589+  block_flags = flags | flags_start;
3590+
3591+  for (block = 0; block < blocks; block++) {
3592+    __m128i block_len_vec;
3593+    __m128i block_flags_vec;
3594+    __m128i msg_vecs[16];
3595+    __m128i v[16];
3596+
3597+    if (block + 1 == blocks) {
3598+      block_flags |= flags_end;
3599+    }
3600+    block_len_vec   = set1_128_avx512(BLAKE3_BLOCK_LEN);
3601+    block_flags_vec = set1_128_avx512(block_flags);
3602+    transpose_msg_vecs4_avx512(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs);
3603+
3604+    v[0]  = h_vecs[0];
3605+    v[1]  = h_vecs[1];
3606+    v[2]  = h_vecs[2];
3607+    v[3]  = h_vecs[3];
3608+    v[4]  = h_vecs[4];
3609+    v[5]  = h_vecs[5];
3610+    v[6]  = h_vecs[6];
3611+    v[7]  = h_vecs[7];
3612+    v[8]  = set1_128_avx512(IV[0]);
3613+    v[9]  = set1_128_avx512(IV[1]);
3614+    v[10] = set1_128_avx512(IV[2]);
3615+    v[11] = set1_128_avx512(IV[3]);
3616+    v[12] = counter_low_vec;
3617+    v[13] = counter_high_vec;
3618+    v[14] = block_len_vec;
3619+    v[15] = block_flags_vec;
3620+
3621+    round_fn4_avx512(v, msg_vecs, 0);
3622+    round_fn4_avx512(v, msg_vecs, 1);
3623+    round_fn4_avx512(v, msg_vecs, 2);
3624+    round_fn4_avx512(v, msg_vecs, 3);
3625+    round_fn4_avx512(v, msg_vecs, 4);
3626+    round_fn4_avx512(v, msg_vecs, 5);
3627+    round_fn4_avx512(v, msg_vecs, 6);
3628+
3629+    h_vecs[0] = xor_128_avx512(v[0], v[8]);
3630+    h_vecs[1] = xor_128_avx512(v[1], v[9]);
3631+    h_vecs[2] = xor_128_avx512(v[2], v[10]);
3632+    h_vecs[3] = xor_128_avx512(v[3], v[11]);
3633+    h_vecs[4] = xor_128_avx512(v[4], v[12]);
3634+    h_vecs[5] = xor_128_avx512(v[5], v[13]);
3635+    h_vecs[6] = xor_128_avx512(v[6], v[14]);
3636+    h_vecs[7] = xor_128_avx512(v[7], v[15]);
3637+
3638+    block_flags = flags;
3639+  }
3640+
3641+  transpose_vecs_sse2(h_vecs);
3642+  storeu_128_avx512(h_vecs[0], &out_bytes[0 * sizeof(__m128i)]);
3643+  storeu_128_avx512(h_vecs[1], &out_bytes[2 * sizeof(__m128i)]);
3644+  storeu_128_avx512(h_vecs[2], &out_bytes[4 * sizeof(__m128i)]);
3645+  storeu_128_avx512(h_vecs[3], &out_bytes[6 * sizeof(__m128i)]);
3646+  storeu_128_avx512(h_vecs[4], &out_bytes[1 * sizeof(__m128i)]);
3647+  storeu_128_avx512(h_vecs[5], &out_bytes[3 * sizeof(__m128i)]);
3648+  storeu_128_avx512(h_vecs[6], &out_bytes[5 * sizeof(__m128i)]);
3649+  storeu_128_avx512(h_vecs[7], &out_bytes[7 * sizeof(__m128i)]);
3650+}
3651+
3652+static inline void
3653+hash_one_avx512(
3654+    const uint8_t *input,
3655+    size_t         blocks,
3656+    const uint32_t key[8],
3657+    uint64_t       counter,
3658+    uint8_t        flags,
3659+    uint8_t        flags_start,
3660+    uint8_t        flags_end,
3661+    uint8_t        out_bytes[BLAKE3_OUT_LEN]
3662+)
3663+{
3664+  uint32_t cv[8];
3665+  uint8_t  block_flags;
3666+
3667+  memcpy(cv, key, BLAKE3_KEY_LEN);
3668+  block_flags = flags | flags_start;
3669+  while (blocks > 0) {
3670+    if (blocks == 1) {
3671+      block_flags |= flags_end;
3672+    }
3673+    blake3_compress_in_place_avx512(cv, input, BLAKE3_BLOCK_LEN, counter, block_flags);
3674+    input = &input[BLAKE3_BLOCK_LEN];
3675+    blocks -= 1;
3676+    block_flags = flags;
3677+  }
3678+  memcpy(out_bytes, cv, BLAKE3_OUT_LEN);
3679+}
3680+
3681+void
3682+blake3_hash_many_avx512(
3683+    const uint8_t *const *inputs,
3684+    size_t                num_inputs,
3685+    size_t                blocks,
3686+    const uint32_t        key[8],
3687+    uint64_t              counter,
3688+    int                   increment_counter,
3689+    uint8_t               flags,
3690+    uint8_t               flags_start,
3691+    uint8_t               flags_end,
3692+    uint8_t              *out_bytes
3693+)
3694+{
3695+  while (num_inputs >= 16) {
3696+    blake3_hash16_avx512(
3697+        inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out_bytes
3698+    );
3699+    if (increment_counter) {
3700+      counter += 16;
3701+    }
3702+    inputs += 16;
3703+    num_inputs -= 16;
3704+    out_bytes = &out_bytes[16 * BLAKE3_OUT_LEN];
3705+  }
3706+  while (num_inputs >= 8) {
3707+    blake3_hash8_avx512(
3708+        inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out_bytes
3709+    );
3710+    if (increment_counter) {
3711+      counter += 8;
3712+    }
3713+    inputs += 8;
3714+    num_inputs -= 8;
3715+    out_bytes = &out_bytes[8 * BLAKE3_OUT_LEN];
3716+  }
3717+  while (num_inputs >= 4) {
3718+    blake3_hash4_avx512(
3719+        inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out_bytes
3720+    );
3721+    if (increment_counter) {
3722+      counter += 4;
3723+    }
3724+    inputs += 4;
3725+    num_inputs -= 4;
3726+    out_bytes = &out_bytes[4 * BLAKE3_OUT_LEN];
3727+  }
3728+  while (num_inputs > 0) {
3729+    hash_one_avx512(inputs[0], blocks, key, counter, flags, flags_start, flags_end, out_bytes);
3730+    if (increment_counter) {
3731+      counter += 1;
3732+    }
3733+    inputs += 1;
3734+    num_inputs -= 1;
3735+    out_bytes = &out_bytes[BLAKE3_OUT_LEN];
3736+  }
3737+}
3738+#if defined(__clang__)
3739+#pragma clang attribute pop
3740+#elif defined(__GNUC__)
3741+#pragma GCC pop_options
3742+#endif
3743+#endif
3744+
3745+/* dispatch functions */
3746+void
3747+blake3_compress_in_place(
3748+    uint32_t      cv[8],
3749+    const uint8_t block[BLAKE3_BLOCK_LEN],
3750+    uint8_t       block_len,
3751+    uint64_t      counter,
3752+    uint8_t       flags
3753+)
3754+{
3755+#if BLAKE3_X86_SIMD
3756+  if (!blake3_cpu_detected)
3757+    blake3_detect_cpu_features();
3758+  if (blake3_cpu_features & AVX512) {
3759+    blake3_compress_in_place_avx512(cv, block, block_len, counter, flags);
3760+    return;
3761+  }
3762+  if (blake3_cpu_features & SSE41) {
3763+    blake3_compress_in_place_sse41(cv, block, block_len, counter, flags);
3764+    return;
3765+  }
3766+  if (blake3_cpu_features & SSE2) {
3767+    blake3_compress_in_place_sse2(cv, block, block_len, counter, flags);
3768+    return;
3769+  }
3770+#endif
3771+  blake3_compress_in_place_portable(cv, block, block_len, counter, flags);
3772+}
3773+
3774+void
3775+blake3_compress_xof(
3776+    const uint32_t cv[8],
3777+    const uint8_t  block[BLAKE3_BLOCK_LEN],
3778+    uint8_t        block_len,
3779+    uint64_t       counter,
3780+    uint8_t        flags,
3781+    uint8_t        out[64]
3782+)
3783+{
3784+#if BLAKE3_X86_SIMD
3785+  if (!blake3_cpu_detected)
3786+    blake3_detect_cpu_features();
3787+  if (blake3_cpu_features & AVX512) {
3788+    blake3_compress_xof_avx512(cv, block, block_len, counter, flags, out);
3789+    return;
3790+  }
3791+  if (blake3_cpu_features & SSE41) {
3792+    blake3_compress_xof_sse41(cv, block, block_len, counter, flags, out);
3793+    return;
3794+  }
3795+  if (blake3_cpu_features & SSE2) {
3796+    blake3_compress_xof_sse2(cv, block, block_len, counter, flags, out);
3797+    return;
3798+  }
3799+#endif
3800+  blake3_compress_xof_portable(cv, block, block_len, counter, flags, out);
3801+}
3802+
3803+void
3804+blake3_hash_many(
3805+    const uint8_t *const *inputs,
3806+    size_t                num_inputs,
3807+    size_t                blocks,
3808+    const uint32_t        key[8],
3809+    uint64_t              counter,
3810+    int                   increment_counter,
3811+    uint8_t               flags,
3812+    uint8_t               flags_start,
3813+    uint8_t               flags_end,
3814+    uint8_t              *out
3815+)
3816+{
3817+#if BLAKE3_X86_SIMD
3818+  if (!blake3_cpu_detected)
3819+    blake3_detect_cpu_features();
3820+  if (blake3_cpu_features & AVX512) {
3821+    blake3_hash_many_avx512(
3822+        inputs,
3823+        num_inputs,
3824+        blocks,
3825+        key,
3826+        counter,
3827+        increment_counter,
3828+        flags,
3829+        flags_start,
3830+        flags_end,
3831+        out
3832+    );
3833+    return;
3834+  }
3835+  if (blake3_cpu_features & AVX2) {
3836+    blake3_hash_many_avx2(
3837+        inputs,
3838+        num_inputs,
3839+        blocks,
3840+        key,
3841+        counter,
3842+        increment_counter,
3843+        flags,
3844+        flags_start,
3845+        flags_end,
3846+        out
3847+    );
3848+    return;
3849+  }
3850+  if (blake3_cpu_features & SSE41) {
3851+    blake3_hash_many_sse41(
3852+        inputs,
3853+        num_inputs,
3854+        blocks,
3855+        key,
3856+        counter,
3857+        increment_counter,
3858+        flags,
3859+        flags_start,
3860+        flags_end,
3861+        out
3862+    );
3863+    return;
3864+  }
3865+  if (blake3_cpu_features & SSE2) {
3866+    blake3_hash_many_sse2(
3867+        inputs,
3868+        num_inputs,
3869+        blocks,
3870+        key,
3871+        counter,
3872+        increment_counter,
3873+        flags,
3874+        flags_start,
3875+        flags_end,
3876+        out
3877+    );
3878+    return;
3879+  }
3880+#endif
3881+  blake3_hash_many_portable(
3882+      inputs,
3883+      num_inputs,
3884+      blocks,
3885+      key,
3886+      counter,
3887+      increment_counter,
3888+      flags,
3889+      flags_start,
3890+      flags_end,
3891+      out
3892+  );
3893+}
3894+
3895+size_t
3896+blake3_simd_degree(void)
3897+{
3898+#if BLAKE3_X86_SIMD
3899+  if (!blake3_cpu_detected)
3900+    blake3_detect_cpu_features();
3901+  if (blake3_cpu_features & AVX512)
3902+    return 16;
3903+  if (blake3_cpu_features & AVX2)
3904+    return 8;
3905+  if (blake3_cpu_features & SSE41)
3906+    return 4;
3907+  if (blake3_cpu_features & SSE2)
3908+    return 4;
3909+#endif
3910+  return 1;
3911+}
3912+
3913+/* core hasher implementation */
3914+const char *
3915+blake3_version(void)
3916+{
3917+  return BLAKE3_VERSION_STRING;
3918+}
3919+
3920+static inline void
3921+chunk_state_init(struct Blake3ChunkState *self, const uint32_t key[8], uint8_t flags)
3922+{
3923+  memcpy(self->cv, key, BLAKE3_KEY_LEN);
3924+  self->chunk_counter = 0;
3925+  memset(self->buf, 0, BLAKE3_BLOCK_LEN);
3926+  self->buf_len           = 0;
3927+  self->blocks_compressed = 0;
3928+  self->flags             = flags;
3929+}
3930+
3931+static inline void
3932+chunk_state_reset(struct Blake3ChunkState *self, const uint32_t key[8], uint64_t chunk_counter)
3933+{
3934+  memcpy(self->cv, key, BLAKE3_KEY_LEN);
3935+  self->chunk_counter     = chunk_counter;
3936+  self->blocks_compressed = 0;
3937+  memset(self->buf, 0, BLAKE3_BLOCK_LEN);
3938+  self->buf_len = 0;
3939+}
3940+
3941+static inline size_t
3942+chunk_state_len(const struct Blake3ChunkState *self)
3943+{
3944+  return (BLAKE3_BLOCK_LEN * (size_t)self->blocks_compressed) + ((size_t)self->buf_len);
3945+}
3946+
3947+static inline size_t
3948+chunk_state_fill_buf(struct Blake3ChunkState *self, const uint8_t *input, size_t input_len)
3949+{
3950+  size_t   take = BLAKE3_BLOCK_LEN - ((size_t)self->buf_len);
3951+  uint8_t *dest;
3952+
3953+  if (take > input_len) {
3954+    take = input_len;
3955+  }
3956+  dest = self->buf + ((size_t)self->buf_len);
3957+  memcpy(dest, input, take);
3958+  self->buf_len += (uint8_t)take;
3959+  return take;
3960+}
3961+
3962+static inline uint8_t
3963+chunk_state_maybe_start_flag(const struct Blake3ChunkState *self)
3964+{
3965+  if (self->blocks_compressed == 0) {
3966+    return CHUNK_START;
3967+  } else {
3968+    return 0;
3969+  }
3970+}
3971+
3972+static inline struct Output
3973+make_output(
3974+    const uint32_t input_cv[8],
3975+    const uint8_t  block[BLAKE3_BLOCK_LEN],
3976+    uint8_t        block_len,
3977+    uint64_t       counter,
3978+    uint8_t        flags
3979+)
3980+{
3981+  struct Output ret;
3982+
3983+  memcpy(ret.input_cv, input_cv, 32);
3984+  memcpy(ret.block, block, BLAKE3_BLOCK_LEN);
3985+  ret.block_len = block_len;
3986+  ret.counter   = counter;
3987+  ret.flags     = flags;
3988+  return ret;
3989+}
3990+
3991+static inline void
3992+output_chaining_value(const struct Output *self, uint8_t cv[32])
3993+{
3994+  uint32_t cv_words[8];
3995+
3996+  memcpy(cv_words, self->input_cv, 32);
3997+  blake3_compress_in_place(cv_words, self->block, self->block_len, self->counter, self->flags);
3998+  store_cv_words(cv, cv_words);
3999+}
4000+
4001+static inline void
4002+output_root_bytes(const struct Output *self, uint64_t seek, uint8_t *out, size_t out_len)
4003+{
4004+  uint64_t output_block_counter = seek / 64;
4005+  size_t   offset_within_block  = seek % 64;
4006+  uint8_t  wide_buf[64];
4007+  size_t   available_bytes;
4008+  size_t   memcpy_len;
4009+
4010+  while (out_len > 0) {
4011+    blake3_compress_xof(
4012+        self->input_cv,
4013+        self->block,
4014+        self->block_len,
4015+        output_block_counter,
4016+        self->flags | ROOT,
4017+        wide_buf
4018+    );
4019+    available_bytes = 64 - offset_within_block;
4020+    if (out_len > available_bytes) {
4021+      memcpy_len = available_bytes;
4022+    } else {
4023+      memcpy_len = out_len;
4024+    }
4025+    memcpy(out, wide_buf + offset_within_block, memcpy_len);
4026+    out += memcpy_len;
4027+    out_len -= memcpy_len;
4028+    output_block_counter += 1;
4029+    offset_within_block = 0;
4030+  }
4031+}
4032+
4033+static inline void
4034+chunk_state_update(struct Blake3ChunkState *self, const uint8_t *input, size_t input_len)
4035+{
4036+  size_t take;
4037+
4038+  if (self->buf_len > 0) {
4039+    take = chunk_state_fill_buf(self, input, input_len);
4040+    input += take;
4041+    input_len -= take;
4042+    if (input_len > 0) {
4043+      blake3_compress_in_place(
4044+          self->cv,
4045+          self->buf,
4046+          BLAKE3_BLOCK_LEN,
4047+          self->chunk_counter,
4048+          self->flags | chunk_state_maybe_start_flag(self)
4049+      );
4050+      self->blocks_compressed += 1;
4051+      self->buf_len = 0;
4052+      memset(self->buf, 0, BLAKE3_BLOCK_LEN);
4053+    }
4054+  }
4055+
4056+  while (input_len > BLAKE3_BLOCK_LEN) {
4057+    blake3_compress_in_place(
4058+        self->cv,
4059+        input,
4060+        BLAKE3_BLOCK_LEN,
4061+        self->chunk_counter,
4062+        self->flags | chunk_state_maybe_start_flag(self)
4063+    );
4064+    self->blocks_compressed += 1;
4065+    input += BLAKE3_BLOCK_LEN;
4066+    input_len -= BLAKE3_BLOCK_LEN;
4067+  }
4068+
4069+  take = chunk_state_fill_buf(self, input, input_len);
4070+  input += take;
4071+  input_len -= take;
4072+}
4073+
4074+static inline struct Output
4075+chunk_state_output(const struct Blake3ChunkState *self)
4076+{
4077+  uint8_t block_flags = self->flags | chunk_state_maybe_start_flag(self) | CHUNK_END;
4078+
4079+  return make_output(self->cv, self->buf, self->buf_len, self->chunk_counter, block_flags);
4080+}
4081+
4082+static inline struct Output
4083+parent_output(const uint8_t block[BLAKE3_BLOCK_LEN], const uint32_t key[8], uint8_t flags)
4084+{
4085+  return make_output(key, block, BLAKE3_BLOCK_LEN, 0, flags | PARENT);
4086+}
4087+
4088+static unsigned int
4089+highest_one(uint64_t x)
4090+{
4091+#if defined(__GNUC__) || defined(__clang__)
4092+  return 63 ^ __builtin_clzll(x);
4093+#else
4094+  unsigned int c = 0;
4095+  if (x & 0xffffffff00000000ULL) {
4096+    x >>= 32;
4097+    c += 32;
4098+  }
4099+  if (x & 0x00000000ffff0000ULL) {
4100+    x >>= 16;
4101+    c += 16;
4102+  }
4103+  if (x & 0x000000000000ff00ULL) {
4104+    x >>= 8;
4105+    c += 8;
4106+  }
4107+  if (x & 0x00000000000000f0ULL) {
4108+    x >>= 4;
4109+    c += 4;
4110+  }
4111+  if (x & 0x000000000000000cULL) {
4112+    x >>= 2;
4113+    c += 2;
4114+  }
4115+  if (x & 0x0000000000000002ULL) {
4116+    c += 1;
4117+  }
4118+  return c;
4119+#endif
4120+}
4121+
4122+static inline uint64_t
4123+round_down_to_power_of_2(uint64_t x)
4124+{
4125+  return 1ULL << highest_one(x | 1);
4126+}
4127+
4128+static inline size_t
4129+left_len(size_t content_len)
4130+{
4131+  size_t full_chunks = (content_len - 1) / BLAKE3_CHUNK_LEN;
4132+
4133+  return round_down_to_power_of_2(full_chunks) * BLAKE3_CHUNK_LEN;
4134+}
4135+
4136+static inline size_t
4137+compress_chunks_parallel(
4138+    const uint8_t *input,
4139+    size_t         input_len,
4140+    const uint32_t key[8],
4141+    uint64_t       chunk_counter,
4142+    uint8_t        flags,
4143+    uint8_t       *out
4144+)
4145+{
4146+  const uint8_t *chunks_array[MAX_SIMD_DEGREE];
4147+  size_t         input_position   = 0;
4148+  size_t         chunks_array_len = 0;
4149+
4150+  assert(0 < input_len);
4151+  assert(input_len <= MAX_SIMD_DEGREE * BLAKE3_CHUNK_LEN);
4152+
4153+  while (input_len - input_position >= BLAKE3_CHUNK_LEN) {
4154+    chunks_array[chunks_array_len] = &input[input_position];
4155+    input_position += BLAKE3_CHUNK_LEN;
4156+    chunks_array_len += 1;
4157+  }
4158+
4159+  blake3_hash_many(
4160+      chunks_array,
4161+      chunks_array_len,
4162+      BLAKE3_CHUNK_LEN / BLAKE3_BLOCK_LEN,
4163+      key,
4164+      chunk_counter,
4165+      1,
4166+      flags,
4167+      CHUNK_START,
4168+      CHUNK_END,
4169+      out
4170+  );
4171+
4172+  if (input_len > input_position) {
4173+    uint64_t                counter = chunk_counter + (uint64_t)chunks_array_len;
4174+    struct Blake3ChunkState chunk_state;
4175+    struct Output           output;
4176+
4177+    chunk_state_init(&chunk_state, key, flags);
4178+    chunk_state.chunk_counter = counter;
4179+    chunk_state_update(&chunk_state, &input[input_position], input_len - input_position);
4180+    output = chunk_state_output(&chunk_state);
4181+    output_chaining_value(&output, &out[chunks_array_len * BLAKE3_OUT_LEN]);
4182+    return chunks_array_len + 1;
4183+  } else {
4184+    return chunks_array_len;
4185+  }
4186+}
4187+
4188+static inline size_t
4189+compress_parents_parallel(
4190+    const uint8_t *child_chaining_values,
4191+    size_t         num_chaining_values,
4192+    const uint32_t key[8],
4193+    uint8_t        flags,
4194+    uint8_t       *out
4195+)
4196+{
4197+  const uint8_t *parents_array[MAX_SIMD_DEGREE_OR_2];
4198+  size_t         parents_array_len = 0;
4199+
4200+  assert(2 <= num_chaining_values);
4201+  assert(num_chaining_values <= 2 * MAX_SIMD_DEGREE_OR_2);
4202+
4203+  while (num_chaining_values - (2 * parents_array_len) >= 2) {
4204+    parents_array[parents_array_len] =
4205+        &child_chaining_values[2 * parents_array_len * BLAKE3_OUT_LEN];
4206+    parents_array_len += 1;
4207+  }
4208+
4209+  blake3_hash_many(parents_array, parents_array_len, 1, key, 0, 0, flags | PARENT, 0, 0, out);
4210+
4211+  if (num_chaining_values > 2 * parents_array_len) {
4212+    memcpy(
4213+        &out[parents_array_len * BLAKE3_OUT_LEN],
4214+        &child_chaining_values[2 * parents_array_len * BLAKE3_OUT_LEN],
4215+        BLAKE3_OUT_LEN
4216+    );
4217+    return parents_array_len + 1;
4218+  } else {
4219+    return parents_array_len;
4220+  }
4221+}
4222+
4223+/* splits input in two at the largest power-of-2 chunk boundary and
4224+ * recurses on each half independently, writing each side's chaining
4225+ * values into its own slice of out. this, not an n-way iterate-then-
4226+ * merge, is what actually keeps the chaining-value count bounded at
4227+ * every level: an earlier iterative reconstruction of this function
4228+ * let cvs_written grow to roughly degree^2 for exact power-of-2 input
4229+ * lengths (64kib was the first size it broke on), overrunning the
4230+ * bound compress_parents_parallel assumes. fixed by matching the
4231+ * upstream reference implementation's actual recursive shape instead
4232+ * of re-deriving it */
4233+static inline size_t
4234+blake3_compress_subtree_wide(
4235+    const uint8_t *input,
4236+    size_t         input_len,
4237+    const uint32_t key[8],
4238+    uint64_t       chunk_counter,
4239+    uint8_t        flags,
4240+    uint8_t       *out
4241+)
4242+{
4243+  size_t         left_input_len, right_input_len;
4244+  const uint8_t *right_input;
4245+  uint64_t       right_chunk_counter;
4246+  uint8_t        cv_array[2 * MAX_SIMD_DEGREE_OR_2 * BLAKE3_OUT_LEN];
4247+  size_t         degree;
4248+  uint8_t       *right_cvs;
4249+  size_t         left_n, right_n;
4250+
4251+  if (input_len <= (size_t)blake3_simd_degree() * BLAKE3_CHUNK_LEN) {
4252+    return compress_chunks_parallel(input, input_len, key, chunk_counter, flags, out);
4253+  }
4254+
4255+  left_input_len = left_len(input_len);
4256+  right_input_len = input_len - left_input_len;
4257+  right_input = &input[left_input_len];
4258+  right_chunk_counter = chunk_counter + (uint64_t)(left_input_len / BLAKE3_CHUNK_LEN);
4259+
4260+  /* MAX_SIMD_DEGREE_OR_2 accounts for the degree=1 special case below,
4261+ * which always returns 2 outputs even though degree itself is 1 */
4262+  degree = blake3_simd_degree();
4263+  if (left_input_len > BLAKE3_CHUNK_LEN && degree == 1) {
4264+    degree = 2;
4265+  }
4266+  right_cvs = &cv_array[degree * BLAKE3_OUT_LEN];
4267+
4268+  left_n =
4269+      blake3_compress_subtree_wide(input, left_input_len, key, chunk_counter, flags, cv_array);
4270+  right_n = blake3_compress_subtree_wide(
4271+      right_input, right_input_len, key, right_chunk_counter, flags, right_cvs
4272+  );
4273+
4274+  /* degree=1: left_n and right_n are both 1, return both cvs directly
4275+ * rather than compressing them, so the caller always sees at least 2 */
4276+  if (left_n == 1) {
4277+    memcpy(out, cv_array, 2 * BLAKE3_OUT_LEN);
4278+    return 2;
4279+  }
4280+
4281+  return compress_parents_parallel(cv_array, left_n + right_n, key, flags, out);
4282+}
4283+
4284+static void
4285+compress_subtree_to_parent_node(
4286+    const uint8_t *input,
4287+    size_t         input_len,
4288+    const uint32_t key[8],
4289+    uint64_t       chunk_counter,
4290+    uint8_t        flags,
4291+    uint8_t        out[2 * BLAKE3_OUT_LEN]
4292+)
4293+{
4294+  uint8_t cv_array[2 * MAX_SIMD_DEGREE_OR_2 * BLAKE3_OUT_LEN];
4295+  size_t  num_cvs =
4296+      blake3_compress_subtree_wide(input, input_len, key, chunk_counter, flags, cv_array);
4297+
4298+  assert(num_cvs >= 2);
4299+  assert(num_cvs <= MAX_SIMD_DEGREE_OR_2);
4300+  while (num_cvs > 2) {
4301+    num_cvs = compress_parents_parallel(cv_array, num_cvs, key, flags, cv_array);
4302+  }
4303+  memcpy(out, cv_array, 2 * BLAKE3_OUT_LEN);
4304+}
4305+
4306+static inline void
4307+hasher_init_base(struct Blake3Hasher *self, const uint32_t key[8], uint8_t flags)
4308+{
4309+  memcpy(self->key, key, BLAKE3_KEY_LEN);
4310+  chunk_state_init(&self->chunk, key, flags);
4311+  self->cv_stack_len = 0;
4312+}
4313+
4314+void
4315+blake3_hasher_init(struct Blake3Hasher *self)
4316+{
4317+  if (!blake3_cpu_detected)
4318+    blake3_detect_cpu_features();
4319+  hasher_init_base(self, IV, 0);
4320+}
4321+
4322+static inline void
4323+load_key_words(const uint8_t key[BLAKE3_KEY_LEN], uint32_t key_words[8])
4324+{
4325+  key_words[0] = load32(&key[0 * 4]);
4326+  key_words[1] = load32(&key[1 * 4]);
4327+  key_words[2] = load32(&key[2 * 4]);
4328+  key_words[3] = load32(&key[3 * 4]);
4329+  key_words[4] = load32(&key[4 * 4]);
4330+  key_words[5] = load32(&key[5 * 4]);
4331+  key_words[6] = load32(&key[6 * 4]);
4332+  key_words[7] = load32(&key[7 * 4]);
4333+}
4334+
4335+void
4336+blake3_hasher_init_keyed(struct Blake3Hasher *self, const uint8_t key[BLAKE3_KEY_LEN])
4337+{
4338+  uint32_t key_words[8];
4339+
4340+  load_key_words(key, key_words);
4341+  hasher_init_base(self, key_words, KEYED_HASH);
4342+}
4343+
4344+void
4345+blake3_hasher_init_derive_key_raw(
4346+    struct Blake3Hasher *self, const void *context, size_t context_len
4347+)
4348+{
4349+  struct Blake3Hasher context_hasher;
4350+  uint8_t             context_key[BLAKE3_KEY_LEN];
4351+  uint32_t            context_key_words[8];
4352+
4353+  hasher_init_base(&context_hasher, IV, DERIVE_KEY_CONTEXT);
4354+  blake3_hasher_update(&context_hasher, context, context_len);
4355+  blake3_hasher_finalize(&context_hasher, context_key, BLAKE3_KEY_LEN);
4356+  load_key_words(context_key, context_key_words);
4357+  hasher_init_base(self, context_key_words, DERIVE_KEY_MATERIAL);
4358+}
4359+
4360+static inline unsigned int
4361+popcnt(uint64_t x)
4362+{
4363+#if defined(__GNUC__) || defined(__clang__)
4364+  return __builtin_popcountll(x);
4365+#else
4366+  unsigned int count = 0;
4367+  while (x != 0) {
4368+    count += 1;
4369+    x &= x - 1;
4370+  }
4371+  return count;
4372+#endif
4373+}
4374+
4375+void
4376+blake3_hasher_init_derive_key(struct Blake3Hasher *self, const char *context)
4377+{
4378+  blake3_hasher_init_derive_key_raw(self, context, strlen(context));
4379+}
4380+
4381+static inline void
4382+hasher_merge_cv_stack(struct Blake3Hasher *self, uint64_t total_len)
4383+{
4384+  size_t post_merge_stack_len = (size_t)popcnt(total_len);
4385+
4386+  while (self->cv_stack_len > post_merge_stack_len) {
4387+    uint8_t      *parent_node = &self->cv_stack[(self->cv_stack_len - 2) * BLAKE3_OUT_LEN];
4388+    struct Output output      = parent_output(parent_node, self->key, self->chunk.flags);
4389+
4390+    output_chaining_value(&output, parent_node);
4391+    self->cv_stack_len -= 1;
4392+  }
4393+}
4394+
4395+static inline void
4396+hasher_push_cv(struct Blake3Hasher *self, uint8_t new_cv[BLAKE3_OUT_LEN], uint64_t chunk_counter)
4397+{
4398+  hasher_merge_cv_stack(self, chunk_counter);
4399+  memcpy(&self->cv_stack[self->cv_stack_len * BLAKE3_OUT_LEN], new_cv, BLAKE3_OUT_LEN);
4400+  self->cv_stack_len += 1;
4401+}
4402+
4403+void
4404+blake3_hasher_update(struct Blake3Hasher *self, const void *input, size_t input_len)
4405+{
4406+  const uint8_t *input_bytes;
4407+
4408+  if (input_len == 0) {
4409+    return;
4410+  }
4411+
4412+  input_bytes = (const uint8_t *)input;
4413+
4414+  if (chunk_state_len(&self->chunk) > 0) {
4415+    size_t take = BLAKE3_CHUNK_LEN - chunk_state_len(&self->chunk);
4416+
4417+    if (take > input_len) {
4418+      take = input_len;
4419+    }
4420+    chunk_state_update(&self->chunk, input_bytes, take);
4421+    input_bytes += take;
4422+    input_len -= take;
4423+    if (input_len > 0) {
4424+      struct Output output = chunk_state_output(&self->chunk);
4425+      uint8_t       chunk_cv[32];
4426+
4427+      output_chaining_value(&output, chunk_cv);
4428+      hasher_push_cv(self, chunk_cv, self->chunk.chunk_counter);
4429+      chunk_state_reset(&self->chunk, self->key, self->chunk.chunk_counter + 1);
4430+    } else {
4431+      return;
4432+    }
4433+  }
4434+
4435+  while (input_len > BLAKE3_CHUNK_LEN) {
4436+    size_t   subtree_len  = round_down_to_power_of_2(input_len);
4437+    uint64_t count_so_far = self->chunk.chunk_counter * BLAKE3_CHUNK_LEN;
4438+    uint64_t subtree_chunks;
4439+
4440+    while ((((uint64_t)(subtree_len - 1)) & count_so_far) != 0) {
4441+      subtree_len /= 2;
4442+    }
4443+    subtree_chunks = subtree_len / BLAKE3_CHUNK_LEN;
4444+    if (subtree_len <= BLAKE3_CHUNK_LEN) {
4445+      struct Blake3ChunkState chunk_state;
4446+      struct Output           output;
4447+      uint8_t                 cv[BLAKE3_OUT_LEN];
4448+
4449+      chunk_state_init(&chunk_state, self->key, self->chunk.flags);
4450+      chunk_state.chunk_counter = self->chunk.chunk_counter;
4451+      chunk_state_update(&chunk_state, input_bytes, subtree_len);
4452+      output = chunk_state_output(&chunk_state);
4453+      output_chaining_value(&output, cv);
4454+      hasher_push_cv(self, cv, chunk_state.chunk_counter);
4455+    } else {
4456+      uint8_t cv_pair[2 * BLAKE3_OUT_LEN];
4457+
4458+      compress_subtree_to_parent_node(
4459+          input_bytes, subtree_len, self->key, self->chunk.chunk_counter, self->chunk.flags, cv_pair
4460+      );
4461+      hasher_push_cv(self, cv_pair, self->chunk.chunk_counter);
4462+      hasher_push_cv(
4463+          self, &cv_pair[BLAKE3_OUT_LEN], self->chunk.chunk_counter + (subtree_chunks / 2)
4464+      );
4465+    }
4466+    self->chunk.chunk_counter += subtree_chunks;
4467+    input_bytes += subtree_len;
4468+    input_len -= subtree_len;
4469+  }
4470+
4471+  if (input_len > 0) {
4472+    chunk_state_update(&self->chunk, input_bytes, input_len);
4473+    hasher_merge_cv_stack(self, self->chunk.chunk_counter);
4474+  }
4475+}
4476+
4477+void
4478+blake3_hasher_finalize_seek(
4479+    const struct Blake3Hasher *self, uint64_t seek, uint8_t *out, size_t out_len
4480+)
4481+{
4482+  struct Output output;
4483+  size_t        cvs_remaining;
4484+
4485+  if (out_len == 0) {
4486+    return;
4487+  }
4488+
4489+  if (self->cv_stack_len == 0) {
4490+    output = chunk_state_output(&self->chunk);
4491+    output_root_bytes(&output, seek, out, out_len);
4492+    return;
4493+  }
4494+
4495+  if (chunk_state_len(&self->chunk) > 0) {
4496+    cvs_remaining = self->cv_stack_len;
4497+    output        = chunk_state_output(&self->chunk);
4498+  } else {
4499+    cvs_remaining = self->cv_stack_len - 2;
4500+    output = parent_output(&self->cv_stack[cvs_remaining * 32], self->key, self->chunk.flags);
4501+  }
4502+
4503+  while (cvs_remaining > 0) {
4504+    uint8_t parent_block[BLAKE3_BLOCK_LEN];
4505+
4506+    cvs_remaining -= 1;
4507+    memcpy(parent_block, &self->cv_stack[cvs_remaining * 32], 32);
4508+    output_chaining_value(&output, &parent_block[32]);
4509+    output = parent_output(parent_block, self->key, self->chunk.flags);
4510+  }
4511+  output_root_bytes(&output, seek, out, out_len);
4512+}
4513+
4514+void
4515+blake3_hasher_finalize(const struct Blake3Hasher *self, uint8_t *out, size_t out_len)
4516+{
4517+  blake3_hasher_finalize_seek(self, 0, out, out_len);
4518+}
4519+
4520+void
4521+blake3_hasher_reset(struct Blake3Hasher *self)
4522+{
4523+  chunk_state_reset(&self->chunk, self->key, 0);
4524+  self->cv_stack_len = 0;
4525+}
4526+
+43, -0
 1@@ -0,0 +1,43 @@
 2+/* see LICENSE file for copyright and license details */
 3+#ifndef ARUU_LIBBLAKE3_H
 4+#define ARUU_LIBBLAKE3_H
 5+
 6+#include <stddef.h>
 7+#include <stdint.h>
 8+
 9+#define BLAKE3_KEY_LEN   32
10+#define BLAKE3_OUT_LEN   32
11+#define BLAKE3_BLOCK_LEN 64
12+#define BLAKE3_CHUNK_LEN 1024
13+#define BLAKE3_MAX_DEPTH 54
14+
15+struct Blake3ChunkState {
16+  uint32_t cv[8];
17+  uint64_t chunk_counter;
18+  uint8_t  buf[BLAKE3_BLOCK_LEN];
19+  uint8_t  buf_len;
20+  uint8_t  blocks_compressed;
21+  uint8_t  flags;
22+};
23+
24+struct Blake3Hasher {
25+  uint32_t                key[8];
26+  struct Blake3ChunkState chunk;
27+  uint8_t                 cv_stack_len;
28+  uint8_t                 cv_stack[(BLAKE3_MAX_DEPTH + 1) * BLAKE3_OUT_LEN];
29+};
30+
31+void blake3_hasher_init(struct Blake3Hasher *self);
32+void blake3_hasher_init_keyed(struct Blake3Hasher *self, const uint8_t key[BLAKE3_KEY_LEN]);
33+void blake3_hasher_init_derive_key(struct Blake3Hasher *self, const char *context);
34+void blake3_hasher_init_derive_key_raw(struct Blake3Hasher *self, const void *context,
35+                                        size_t context_len);
36+void blake3_hasher_update(struct Blake3Hasher *self, const void *input, size_t input_len);
37+void blake3_hasher_finalize(const struct Blake3Hasher *self, uint8_t *out, size_t out_len);
38+void blake3_hasher_finalize_seek(const struct Blake3Hasher *self, uint64_t seek, uint8_t *out,
39+                                  size_t out_len);
40+void blake3_hasher_reset(struct Blake3Hasher *self);
41+
42+const char *blake3_version(void);
43+
44+#endif
+106, -0
  1@@ -0,0 +1,106 @@
  2+/* x86-64 __int128 multiply/divide/remainder, called from cc1-emitted
  3+ * code (see cmd/dev/cc/qbe.c's funcdiv128). qbe has no widening
  4+ * multiply and no divide wider than 64 bits, and division needs a bit
  5+ * serial long-division loop no ir-level codegen could express, so both
  6+ * live here instead. names and abi match compiler-rt's own
  7+ * __multi3/__udivmodti4, so a real libgcc could stand in unchanged.
  8+ * division always takes the slower, always-correct bit serial path
  9+ * rather than a divisor-fits-in-64-bits shortcut, the same "correct
 10+ * first" choice this project's atomics runtime makes by always
 11+ * compiling to seq_cst instead of a weaker order
 12+ */
 13+
 14+.text
 15+
 16+/* truncated 128 bit product: a_hi*b_hi is entirely above bit 128 and
 17+ * never computed. one widening mul (for the low*low term's own high
 18+ * word) plus two truncating imul (the cross terms)
 19+ */
 20+.globl __multi3
 21+__multi3:
 22+	/* a: rdi=a_lo rsi=a_hi   b: rdx=b_lo rcx=b_hi */
 23+	movq %rsi, %r8
 24+	imul %rdx, %r8    /* a_hi * b_lo, low 64 */
 25+	movq %rdi, %r9
 26+	imul %rcx, %r9    /* a_lo * b_hi, low 64 */
 27+	movq %rdi, %rax
 28+	mul %rdx           /* rdx:rax = a_lo * b_lo, full 128 bit */
 29+	addq %r8, %rdx
 30+	addq %r9, %rdx
 31+	ret
 32+
 33+/* unsigned quotient in rax:rdx, remainder written to *rem. bit serial
 34+ * restoring division: 128 iterations, each pulling the next dividend
 35+ * bit into the remainder (a 128 bit left shift built from shl/shr/or,
 36+ * no shld/rcl in this assembler) and setting the matching quotient bit
 37+ * once the remainder is large enough to subtract the divisor back out
 38+ * (subtract-with-borrow built from cmp/setb/sub, no sbb here either;
 39+ * the same technique qbe.c uses for branchless __int128 subtraction)
 40+ */
 41+.globl __udivmodti4
 42+__udivmodti4:
 43+	/* a: rdi=a_lo rsi=a_hi   b: rdx=b_lo rcx=b_hi   rem: r8 */
 44+	push %r12
 45+	push %r13
 46+	push %r8
 47+	xorq %r8, %r8    /* q_lo = 0 */
 48+	xorq %r9, %r9     /* q_hi = 0 */
 49+	xorq %r10, %r10    /* r_lo = 0 */
 50+	xorq %r11, %r11     /* r_hi = 0 */
 51+	movq $128, %rax
 52+.Ludivloop:
 53+	/* r12 = bit_i(a), the msb about to fall out of the 128 bit
 54+	   dividend as it shifts left */
 55+	movq %rsi, %r12
 56+	shrq $63, %r12
 57+
 58+	/* a <<= 1 (128 bit): lo's old msb feeds hi's new lsb */
 59+	movq %rdi, %r13
 60+	shrq $63, %r13
 61+	shlq $1, %rdi
 62+	shlq $1, %rsi
 63+	orq %r13, %rsi
 64+
 65+	/* r = (r << 1) | bit_i(a) */
 66+	movq %r10, %r13
 67+	shrq $63, %r13
 68+	shlq $1, %r10
 69+	shlq $1, %r11
 70+	orq %r13, %r11
 71+	orq %r12, %r10
 72+
 73+	/* q <<= 1, making room for this iteration's quotient bit */
 74+	movq %r8, %r13
 75+	shrq $63, %r13
 76+	shlq $1, %r8
 77+	shlq $1, %r9
 78+	orq %r13, %r9
 79+
 80+	/* r >= b (128 bit unsigned)? */
 81+	cmpq %rcx, %r11
 82+	ja .Ludivcommit
 83+	jb .Ludivskip
 84+	cmpq %rdx, %r10
 85+	jb .Ludivskip
 86+.Ludivcommit:
 87+	/* r -= b, with the borrow from the low word carried into the
 88+	   high word's subtraction by hand (no sbb in this assembler) */
 89+	cmpq %rdx, %r10
 90+	setb %r13b
 91+	movzbq %r13b, %r13
 92+	subq %rdx, %r10
 93+	subq %rcx, %r11
 94+	subq %r13, %r11
 95+	orq $1, %r8
 96+.Ludivskip:
 97+	subq $1, %rax
 98+	jnz .Ludivloop
 99+
100+	pop %rdi
101+	movq %r10, (%rdi)
102+	movq %r11, 8(%rdi)
103+	movq %r8, %rax
104+	movq %r9, %rdx
105+	pop %r13
106+	pop %r12
107+	ret
+1, -1
1@@ -768,7 +768,7 @@ completeLine(struct redlineState *ls, int keypressed)
2       /* prefix cannot be expanded further */
3       if (ls->in_completion == 0) {
4         /* first tab: beep and wait for the second tab
5-         */
6+ */
7         redlineBeep();
8         ls->in_completion = 1;
9         c                 = 0;
+220, -0
  1@@ -0,0 +1,220 @@
  2+#include "archive.h"
  3+
  4+#include <ar.h>
  5+#include <assert.h>
  6+#include <stdlib.h> /* strtoul */
  7+#include <string.h>
  8+
  9+#include "../tcutil.h"
 10+
 11+/* read 4-byte big-endian uint32 */
 12+static uint32_t
 13+read4be(FILE *fp)
 14+{
 15+  unsigned char buf[4];
 16+  read_or_die(fp, buf, -1, sizeof(buf), "read4be");
 17+  return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
 18+}
 19+
 20+static uint32_t *
 21+read_file_offsets(FILE *fp, uint32_t symbol_count)
 22+{
 23+  uint32_t      *file_offsets;
 24+  uint32_t      *p;
 25+  uint32_t       i;
 26+  unsigned char *q;
 27+  uint32_t       offset;
 28+
 29+  file_offsets = malloc_or_die(sizeof(*file_offsets) * symbol_count);
 30+  read_or_die(fp, file_offsets, -1, sizeof(*file_offsets) * symbol_count, "Offsets");
 31+  /* convert big endian to machine endian */
 32+  p = file_offsets;
 33+  for (i = 0; i < symbol_count; ++i) {
 34+    q      = (unsigned char *)p;
 35+    offset = (q[0] << 24) | (q[1] << 16) | (q[2] << 8) | q[3];
 36+    *p++   = offset;
 37+  }
 38+  return file_offsets;
 39+}
 40+
 41+static int
 42+compare_uint32(const void *a, const void *b)
 43+{
 44+  uint32_t          x       = *(const uint32_t *)a;
 45+  struct ArContent *content = (struct ArContent *)b;
 46+  uint32_t          y       = content->file_offset;
 47+  return x < y ? -1 : x > y ? 1 : 0;
 48+}
 49+
 50+/* build unique sorted array of arcontent from raw file offsets */
 51+static struct ArContent *
 52+allocate_contents_buffer(const uint32_t *file_offsets, uint32_t symbol_count, size_t *plen)
 53+{
 54+  uint32_t         *offsets;
 55+  ssize_t           len, capa;
 56+  uint32_t          i;
 57+  struct ArContent *contents;
 58+  ssize_t           j;
 59+
 60+  offsets = NULL;
 61+  len     = 0;
 62+  capa    = 0;
 63+
 64+  for (i = 0; i < symbol_count; ++i) {
 65+    uint32_t value = file_offsets[i];
 66+    ssize_t  lo = -1, hi = len;
 67+    ssize_t  m;
 68+
 69+    /* binary search for insertion point */
 70+    while (hi - lo > 1) {
 71+      m = lo + ((hi - lo) >> 1);
 72+      if (offsets[m] < value)
 73+        lo = m;
 74+      else
 75+        hi = m;
 76+    }
 77+
 78+    if (hi >= len || offsets[hi] != value) {
 79+      if (capa <= len) {
 80+        capa <<= 1;
 81+        if (capa <= 0)
 82+          capa = 8;
 83+        offsets = realloc_or_die(offsets, sizeof(*offsets) * capa);
 84+      }
 85+      memmove(&offsets[hi + 1], &offsets[hi], (len - hi) * sizeof(*offsets));
 86+      offsets[hi] = value;
 87+      ++len;
 88+    }
 89+  }
 90+
 91+  contents = calloc_or_die(sizeof(*contents) * len);
 92+  for (j = 0; j < len; ++j) {
 93+    contents[j].obj         = NULL;
 94+    contents[j].file_offset = offsets[j];
 95+  }
 96+  free(offsets);
 97+
 98+  *plen = len;
 99+  return contents;
100+}
101+
102+struct Archive *
103+load_archive(const char *filename)
104+{
105+  FILE             *fp;
106+  struct Archive   *ar;
107+  char              mag[SARMAG];
108+  struct ar_hdr     ghdr;
109+  uint32_t          symbol_count;
110+  uint32_t         *file_offsets;
111+  size_t            content_count;
112+  struct ArContent *contents;
113+  struct ArSymbol  *symbols;
114+  uint32_t          i;
115+  size_t            pos;
116+  size_t            strtablen;
117+  char             *strtab;
118+  char             *p;
119+
120+  if (!is_file(filename) || (fp = fopen(filename, "rb")) == NULL)
121+    return NULL;
122+
123+  ar               = calloc_or_die(sizeof(*ar));
124+  ar->fp           = fp;
125+  ar->symbol_count = 0;
126+  ar->symbols      = NULL;
127+  table_init(&ar->symbol_table);
128+  ar->contents = new_vector();
129+
130+  read_or_die(fp, mag, -1, sizeof(mag), "Magic");
131+  if (memcmp(mag, ARMAG, sizeof(mag)) != 0)
132+    error("Magic expected");
133+
134+  read_or_die(fp, &ghdr, -1, sizeof(ghdr), "Global header");
135+  if (memcmp(ghdr.ar_fmag, ARFMAG, sizeof(ghdr.ar_fmag)) != 0)
136+    error("FMagic expected");
137+
138+  symbol_count     = read4be(fp);
139+  ar->symbol_count = symbol_count;
140+  if (symbol_count > 0) {
141+    file_offsets = read_file_offsets(fp, symbol_count);
142+    contents     = allocate_contents_buffer(file_offsets, symbol_count, &content_count);
143+
144+    symbols     = malloc_or_die(sizeof(*symbols) * symbol_count);
145+    ar->symbols = symbols;
146+    for (i = 0; i < symbol_count; ++i) {
147+      uint32_t          value = file_offsets[i];
148+      struct ArContent *result;
149+      uint32_t          index;
150+
151+      result = bsearch(&value, contents, content_count, sizeof(*contents), compare_uint32);
152+      assert(result != NULL);
153+      index              = result - contents;
154+      symbols[i].content = &contents[index];
155+    }
156+
157+    pos = ftell(fp);
158+    assert(pos < contents[0].file_offset);
159+    strtablen = contents[0].file_offset - pos;
160+    strtab    = malloc_or_die(strtablen); /* freed locally, not stored */
161+    read_or_die(fp, strtab, -1, strtablen, "struct Strtab");
162+    p = strtab;
163+    for (i = 0; i < symbol_count; ++i) {
164+      char              *q;
165+      struct ArSymbol   *symbol;
166+      const struct Name *name;
167+
168+      q = memchr(p, '\0', &strtab[strtablen] - p);
169+      if (q == NULL)
170+        error("Illegal strtab");
171+
172+      symbol = &symbols[i];
173+      name   = alloc_name(p, q, 0);
174+      table_put(&ar->symbol_table, name, symbol);
175+
176+      p = q + 1;
177+    }
178+
179+    free(file_offsets);
180+  }
181+  return ar;
182+}
183+
184+void *
185+load_archive_content(
186+    struct Archive *ar, struct ArSymbol *symbol, void *(*load)(FILE *, const char *, size_t)
187+)
188+{
189+  struct ArContent *content;
190+  struct ar_hdr     hdr;
191+  char             *p;
192+  char              sizestr[sizeof(hdr.ar_size) + 1];
193+  void             *obj;
194+
195+  content = symbol->content;
196+  if (content->obj != NULL)
197+    return content->obj;
198+
199+  fseek(ar->fp, content->file_offset, SEEK_SET);
200+
201+  read_or_die(ar->fp, &hdr, -1, sizeof(hdr), "hdr");
202+  if (memcmp(hdr.ar_fmag, ARFMAG, sizeof(hdr.ar_fmag)) != 0)
203+    error("Malformed archive");
204+
205+  memcpy(content->name, hdr.ar_name, sizeof(hdr.ar_name));
206+  p = memchr(content->name, '/', sizeof(hdr.ar_name));
207+  if (p != NULL)
208+    *p = '\0';
209+
210+  memcpy(sizestr, hdr.ar_size, sizeof(hdr.ar_size));
211+  sizestr[sizeof(hdr.ar_size)] = '\0';
212+  content->size                = strtoul(sizestr, NULL, 10);
213+
214+  obj = (*load)(ar->fp, content->name, content->size);
215+  if (obj == NULL)
216+    error("Failed to extract .o: %.*s", (int)sizeof(content->name), content->name);
217+  content->obj = obj;
218+  vec_push(ar->contents, content);
219+
220+  return obj;
221+}
+37, -0
 1@@ -0,0 +1,37 @@
 2+/* ar archive reading: symbol table and member extraction */
 3+
 4+#ifndef ARUU_TCUTIL_ARCHIVE_H
 5+#define ARUU_TCUTIL_ARCHIVE_H
 6+
 7+#include <stdint.h>
 8+#include <stdio.h>
 9+
10+#include "../table.h"
11+
12+struct Vector;
13+
14+struct ArContent {
15+  void    *obj;
16+  size_t   size;
17+  uint32_t file_offset;
18+  char     name[16];
19+};
20+
21+struct ArSymbol {
22+  struct ArContent *content;
23+};
24+
25+struct Archive {
26+  FILE            *fp;
27+  uint32_t         symbol_count;
28+  struct ArSymbol *symbols;
29+  struct Table     symbol_table;
30+  struct Vector   *contents; /* <struct arcontent*> */
31+};
32+
33+struct Archive *load_archive(const char *filename);
34+void           *load_archive_content(
35+    struct Archive *ar, struct ArSymbol *symbol, void *(*load)(FILE *, const char *, size_t)
36+);
37+
38+#endif /* ARUU_TCUTIL_ARCHIVE_H */
+55, -0
 1@@ -0,0 +1,55 @@
 2+#include "../../../cmd/dev/config.h"
 3+
 4+#include "elfutil.h"
 5+
 6+#ifndef ELF_NOT_SUPPORTED
 7+void
 8+out_elf_header(FILE *fp, uintptr_t entry, int phnum, int shnum, int flags, uintptr_t shoff)
 9+{
10+  Elf64_Ehdr ehdr = {
11+      .e_ident =
12+          {ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_SYSV},
13+      .e_type      = phnum > 0 ? ET_EXEC : ET_REL,
14+      .e_machine   = MACHINE_TYPE,
15+      .e_version   = EV_CURRENT,
16+      .e_entry     = entry,
17+      .e_phoff     = phnum > 0 ? sizeof(Elf64_Ehdr) : 0,
18+      .e_shoff     = shoff,
19+      .e_flags     = flags,
20+      .e_ehsize    = sizeof(Elf64_Ehdr),
21+      .e_phentsize = phnum > 0 ? sizeof(Elf64_Phdr) : 0,
22+      .e_phnum     = phnum,
23+      .e_shentsize = shnum > 0 ? sizeof(Elf64_Shdr) : 0,
24+      .e_shnum     = shnum,
25+      .e_shstrndx  = shnum > 0 ? shnum - 1 : SHN_UNDEF, /* shstrndx is last */
26+  };
27+
28+  fwrite(&ehdr, sizeof(Elf64_Ehdr), 1, fp);
29+}
30+
31+void
32+out_program_header(
33+    FILE     *fp,
34+    int       type,
35+    uintptr_t offset,
36+    uintptr_t vaddr,
37+    size_t    filesz,
38+    size_t    memsz,
39+    int       flags,
40+    size_t    align
41+)
42+{
43+  Elf64_Phdr phdr = {
44+      .p_type   = type,
45+      .p_offset = offset,
46+      .p_vaddr  = vaddr,
47+      .p_paddr  = vaddr,
48+      .p_filesz = filesz,
49+      .p_memsz  = memsz,
50+      .p_flags  = flags,
51+      .p_align  = align,
52+  };
53+
54+  fwrite(&phdr, sizeof(Elf64_Phdr), 1, fp);
55+}
56+#endif /* !ELF_NOT_SUPPORTED */
+26, -0
 1@@ -0,0 +1,26 @@
 2+/* ELF header and program header output */
 3+
 4+#ifndef ARUU_TCUTIL_ELFUTIL_H
 5+#define ARUU_TCUTIL_ELFUTIL_H
 6+
 7+#include <stdio.h> /* FILE */
 8+
 9+#ifdef __APPLE__
10+#include "../../../include/elf.h"
11+#else
12+#include <elf.h>
13+#endif
14+
15+void out_elf_header(FILE *fp, uintptr_t entry, int phnum, int shnum, int flags, uintptr_t shoff);
16+void out_program_header(
17+    FILE     *fp,
18+    int       type,
19+    uintptr_t offset,
20+    uintptr_t vaddr,
21+    size_t    filesz,
22+    size_t    memsz,
23+    int       flags,
24+    size_t    align
25+);
26+
27+#endif /* ARUU_TCUTIL_ELFUTIL_H */
+284, -0
  1@@ -0,0 +1,284 @@
  2+#include "table.h"
  3+
  4+#include <assert.h>
  5+#include <stdlib.h> /* malloc */
  6+#include <string.h>
  7+
  8+/* fnv-1a */
  9+static uint32_t
 10+hash_string(const char *key, int length)
 11+{
 12+  const unsigned char *u    = (const unsigned char *)key;
 13+  uint32_t             hash = 2166136261u;
 14+  int                  i;
 15+
 16+  for (i = 0; i < length; ++i)
 17+    hash = (hash ^ u[i]) * 16777619u;
 18+  return hash;
 19+}
 20+
 21+/* struct name: global interning table */
 22+
 23+static struct Table name_table;
 24+
 25+static const struct Name *
 26+find_name_table(const char *chars, int bytes, uint32_t hash)
 27+{
 28+  const struct Table *table;
 29+  uint32_t            index;
 30+  struct TableEntry  *entry;
 31+  const struct Name  *key;
 32+
 33+  table = &name_table;
 34+  if (table->count == 0)
 35+    return NULL;
 36+
 37+  for (index = hash % table->capacity;; index = (index + 1) % table->capacity) {
 38+    entry = &table->entries[index];
 39+    key   = entry->key;
 40+    if (key == NULL) {
 41+      if (entry->value == NULL)
 42+        return NULL;
 43+    } else if (key->bytes == bytes && key->hash == hash && memcmp(key->chars, chars, bytes) == 0) {
 44+      return key;
 45+    }
 46+  }
 47+}
 48+
 49+const struct Name *
 50+alloc_name(const char *begin, const char *end, int make_copy)
 51+{
 52+  int                bytes;
 53+  uint32_t           hash;
 54+  const struct Name *name;
 55+  char              *new_str;
 56+  struct Name       *new_name;
 57+
 58+  bytes = end != NULL ? (int)(end - begin) : (int)strlen(begin);
 59+  hash  = hash_string(begin, bytes);
 60+  name  = find_name_table(begin, bytes, hash);
 61+  if (name == NULL) {
 62+    if (make_copy) {
 63+      new_str = malloc(bytes);
 64+      if (new_str == NULL)
 65+        return NULL;
 66+      memcpy(new_str, begin, bytes);
 67+      begin = new_str;
 68+    }
 69+    new_name = malloc(sizeof(*new_name));
 70+    if (new_name == NULL) {
 71+      if (make_copy)
 72+        free((void *)begin);
 73+    } else {
 74+      new_name->chars = begin;
 75+      new_name->bytes = bytes;
 76+      new_name->hash  = hash;
 77+      table_put(&name_table, new_name, new_name);
 78+      name = new_name;
 79+    }
 80+  }
 81+  return name;
 82+}
 83+
 84+const struct Name *
 85+alloc_cname(const char *cstr)
 86+{
 87+  return alloc_name(cstr, NULL, 0);
 88+}
 89+
 90+int
 91+equal_name(const struct Name *name1, const struct Name *name2)
 92+{
 93+  /* all names are interned, compare by pointer */
 94+  return name1 == name2;
 95+}
 96+
 97+/* struct table: open-addressing hash table */
 98+
 99+static struct TableEntry *
100+find_entry(struct TableEntry *entries, int capacity, const struct Name *key)
101+{
102+  struct TableEntry *tombstone;
103+  uint32_t           index;
104+  struct TableEntry *entry;
105+
106+  tombstone = NULL;
107+  for (index = key->hash % capacity;; index = (index + 1) % capacity) {
108+    entry = &entries[index];
109+    if (entry->key == NULL) {
110+      if (entry->value == NULL)
111+        return tombstone != NULL ? tombstone : entry;
112+      /* tombstone */
113+      if (tombstone == NULL)
114+        tombstone = entry;
115+    } else if (entry->key == key) {
116+      return entry;
117+    }
118+  }
119+}
120+
121+static void
122+adjust_capacity(struct Table *table, int new_capacity)
123+{
124+  struct TableEntry *new_entries;
125+  int                i;
126+  struct TableEntry *old_entries;
127+  int                old_capacity;
128+  int                new_count;
129+
130+  new_entries = malloc(sizeof(struct TableEntry) * new_capacity);
131+  if (new_entries == NULL)
132+    return;
133+  for (i = 0; i < new_capacity; ++i) {
134+    new_entries[i].key   = NULL;
135+    new_entries[i].value = NULL;
136+  }
137+
138+  old_entries  = table->entries;
139+  old_capacity = table->capacity;
140+  new_count    = 0;
141+  for (i = 0; i < old_capacity; ++i) {
142+    struct TableEntry *entry;
143+    struct TableEntry *dest;
144+
145+    entry = &old_entries[i];
146+    if (entry->key == NULL)
147+      continue;
148+
149+    dest        = find_entry(new_entries, new_capacity, entry->key);
150+    dest->key   = entry->key;
151+    dest->value = entry->value;
152+    ++new_count;
153+  }
154+
155+  free(old_entries);
156+  table->entries  = new_entries;
157+  table->capacity = new_capacity;
158+  table->count = table->used = new_count;
159+}
160+
161+struct Table *
162+alloc_table(void)
163+{
164+  struct Table *table = malloc(sizeof(*table));
165+  if (table != NULL)
166+    table_init(table);
167+  return table;
168+}
169+
170+void
171+table_init(struct Table *table)
172+{
173+  assert(table != NULL);
174+  table->entries  = NULL;
175+  table->count    = 0;
176+  table->used     = 0;
177+  table->capacity = 0;
178+}
179+
180+void *
181+table_get(struct Table *table, const struct Name *key)
182+{
183+  struct TableEntry *entry;
184+
185+  assert(table != NULL);
186+  if (table->count == 0)
187+    return NULL;
188+
189+  entry = find_entry(table->entries, table->capacity, key);
190+  if (entry->key == NULL)
191+    return NULL;
192+
193+  return entry->value;
194+}
195+
196+int
197+table_try_get(struct Table *table, const struct Name *key, void **output)
198+{
199+  struct TableEntry *entry;
200+
201+  assert(table != NULL);
202+  if (table->count == 0)
203+    return 0;
204+
205+  entry = find_entry(table->entries, table->capacity, key);
206+  if (entry->key == NULL)
207+    return 0;
208+
209+  if (output != NULL)
210+    *output = entry->value;
211+  return 1;
212+}
213+
214+int
215+table_put(struct Table *table, const struct Name *key, void *value)
216+{
217+  const int          min_capacity = 15;
218+  int                capacity;
219+  struct TableEntry *entry;
220+  int                is_new_key;
221+
222+  assert(table != NULL);
223+  if (table->used >= table->capacity / 2) {
224+    capacity = table->capacity * 2 - 1; /* keep odd */
225+    if (capacity < min_capacity)
226+      capacity = min_capacity;
227+    adjust_capacity(table, capacity);
228+  }
229+
230+  entry      = find_entry(table->entries, table->capacity, key);
231+  is_new_key = entry->key == NULL;
232+  if (is_new_key) {
233+    ++table->count;
234+    if (entry->value == NULL)
235+      ++table->used;
236+  }
237+
238+  entry->key   = key;
239+  entry->value = value;
240+  return is_new_key;
241+}
242+
243+int
244+table_delete(struct Table *table, const struct Name *key)
245+{
246+  struct TableEntry *entry;
247+
248+  assert(table != NULL);
249+  if (table->count == 0)
250+    return 0;
251+
252+  entry = find_entry(table->entries, table->capacity, key);
253+  if (entry->key == NULL)
254+    return 0;
255+
256+  --table->count;
257+  /* mark as tombstone */
258+  entry->key   = NULL;
259+  entry->value = entry;
260+
261+  return 1;
262+}
263+
264+int
265+table_iterate(const struct Table *table, int iterator, const struct Name **pkey, void **pvalue)
266+{
267+  int                      capacity;
268+  const struct TableEntry *entry;
269+  const struct Name       *key;
270+
271+  assert(table != NULL);
272+  capacity = table->capacity;
273+  for (; iterator < capacity; ++iterator) {
274+    entry = &table->entries[iterator];
275+    key   = entry->key;
276+    if (key != NULL) {
277+      if (pkey != NULL)
278+        *pkey = key;
279+      if (pvalue != NULL)
280+        *pvalue = entry->value;
281+      return iterator + 1;
282+    }
283+  }
284+  return -1;
285+}
+46, -0
 1@@ -0,0 +1,46 @@
 2+/* interned names and open-addressing hash table */
 3+
 4+#ifndef ARUU_TCUTIL_TABLE_H
 5+#define ARUU_TCUTIL_TABLE_H
 6+
 7+#include <stdint.h> /* uint32_t */
 8+
 9+/* interned name: chars and hash are immutable once allocated
10+ * equality is pointer identity (see equal_name) */
11+struct Name {
12+  const char *chars;
13+  int         bytes;
14+  uint32_t    hash;
15+};
16+
17+const struct Name *alloc_name(const char *begin, const char *end, int make_copy);
18+const struct Name *alloc_cname(const char *cstr);
19+int                equal_name(const struct Name *name1, const struct Name *name2);
20+
21+/* for printf: printf("%.*s\n", names(name)) */
22+#define NAMES(name) ((name)->bytes), ((name)->chars)
23+
24+/* open-addressing hash table with linear probing */
25+struct TableEntry {
26+  const struct Name *key;
27+  void              *value;
28+};
29+
30+struct Table {
31+  struct TableEntry *entries;
32+  int                capacity;
33+  int                count;
34+  int                used; /* includes tombstones */
35+};
36+
37+struct Table *alloc_table(void);
38+void          table_init(struct Table *table);
39+void         *table_get(struct Table *table, const struct Name *key);
40+int           table_try_get(struct Table *table, const struct Name *key, void **output);
41+int           table_put(struct Table *table, const struct Name *key, void *value);
42+int           table_delete(struct Table *table, const struct Name *key);
43+int           table_iterate(
44+    const struct Table *table, int iterator, const struct Name **name, void **value
45+); /* returns -1 at end */
46+
47+#endif /* ARUU_TCUTIL_TABLE_H */
+1055, -0
   1@@ -0,0 +1,1055 @@
   2+#include "../../cmd/dev/config.h"
   3+#include "table.h"
   4+#include "tcutil.h"
   5+#include "version.h"
   6+
   7+#include <assert.h>
   8+#include <ctype.h>
   9+#include <limits.h> /* CHAR_BIT */
  10+#include <stdarg.h>
  11+#include <stdlib.h> /* malloc */
  12+#include <string.h> /* strcmp */
  13+#include <sys/stat.h>
  14+
  15+/* riscv toolchain lacks getline, provides __getline instead */
  16+#if defined(__riscv) && !defined(__TC)
  17+static inline ssize_t
  18+getline(char **lineptr, size_t *n, FILE *stream)
  19+{
  20+  return __getline(lineptr, n, stream);
  21+}
  22+#endif
  23+
  24+/* character classification */
  25+
  26+int
  27+isalnum_(int c)
  28+{
  29+  return isalnum(c) || c == '_';
  30+}
  31+
  32+int
  33+isutf8first(int c_)
  34+{
  35+  unsigned int c = c_;
  36+  if (c < 0xc0)
  37+    return 0;
  38+  if (c >= 0xfc)
  39+    return 6;
  40+  if (c >= 0xf8)
  41+    return 5;
  42+  if (c >= 0xf0)
  43+    return 4;
  44+  if (c >= 0xe0)
  45+    return 3;
  46+  return 2;
  47+}
  48+
  49+int
  50+isutf8follow(int c)
  51+{
  52+  return c >= 0x80 && c < 0xc0;
  53+}
  54+
  55+int
  56+isoctal(int c)
  57+{
  58+  return '0' <= c && c <= '7';
  59+}
  60+
  61+int
  62+xvalue(char c)
  63+{
  64+  return ('0' <= c && c <= '9')   ? c - '0'
  65+         : ('A' <= c && c <= 'F') ? c - ('A' - 10)
  66+         : ('a' <= c && c <= 'f') ? c - ('a' - 10)
  67+                                  : -1;
  68+}
  69+
  70+int
  71+starts_with(const char *str, const char *prefix)
  72+{
  73+  size_t len = strlen(prefix);
  74+  return strncmp(str, prefix, len) == 0;
  75+}
  76+
  77+int
  78+most_significant_bit(size_t x)
  79+{
  80+  int bit;
  81+
  82+  assert(x > 0);
  83+#if defined(__GNUC__) || defined(__TC)
  84+  if (sizeof(size_t) == sizeof(unsigned int)) {
  85+    return (int)(sizeof(x) * CHAR_BIT - 1) - __builtin_clz(x);
  86+  } else if (sizeof(size_t) == sizeof(unsigned long)) {
  87+    return (int)(sizeof(x) * CHAR_BIT - 1) - __builtin_clzl(x);
  88+  }
  89+#endif
  90+  for (bit = 0;; ++bit) {
  91+    x >>= 1;
  92+    if (x <= 0)
  93+      return bit;
  94+  }
  95+}
  96+
  97+/* string and path helpers */
  98+
  99+void *
 100+read_or_die(FILE *fp, void *buf, long offset, size_t size, const char *msg)
 101+{
 102+  if (buf == NULL)
 103+    buf = malloc_or_die(size);
 104+  if ((offset >= 0 && fseek(fp, offset, SEEK_SET) != 0) || fread(buf, 1, size, fp) != size)
 105+    error(msg);
 106+  return buf;
 107+}
 108+
 109+void *
 110+malloc_or_die(size_t size)
 111+{
 112+  void *p = malloc(size);
 113+  if (p == NULL) {
 114+    fprintf(stderr, "memory overflow\n");
 115+    exit(1);
 116+  }
 117+  return p;
 118+}
 119+
 120+void *
 121+calloc_or_die(size_t size)
 122+{
 123+  void *p = calloc(1, size);
 124+  if (p == NULL) {
 125+    fprintf(stderr, "memory overflow\n");
 126+    exit(1);
 127+  }
 128+  return p;
 129+}
 130+
 131+void *
 132+realloc_or_die(void *ptr, size_t size)
 133+{
 134+  void *p = realloc(ptr, size);
 135+  if (p == NULL) {
 136+    fprintf(stderr, "memory overflow\n");
 137+    exit(1);
 138+  }
 139+  return p;
 140+}
 141+
 142+const struct Name *
 143+alloc_label(void)
 144+{
 145+  static int label_no;
 146+  char       buf[2 + sizeof(int) * 3 + 1];
 147+
 148+  ++label_no;
 149+  snprintf(buf, sizeof(buf), "l.%04d", label_no);
 150+  return alloc_name(buf, NULL, 1);
 151+}
 152+
 153+ssize_t
 154+getline_chomp(char **lineptr, size_t *n, FILE *stream)
 155+{
 156+  ssize_t len;
 157+  char   *line;
 158+
 159+  len = getline(lineptr, n, stream);
 160+  if (len > 0) {
 161+    line = *lineptr;
 162+    /* chomp CR, LF, CR+LF */
 163+    if (line[len - 1] == '\n')
 164+      line[--len] = '\0';
 165+    if (len > 0 && line[len - 1] == '\r')
 166+      line[--len] = '\0';
 167+  }
 168+  return len;
 169+}
 170+
 171+static ssize_t
 172+getline_cat(char **lineptr, size_t *n, FILE *stream, size_t curlen)
 173+{
 174+  char   *nextline = NULL;
 175+  size_t  capa     = 0;
 176+  ssize_t len;
 177+  char   *oldline;
 178+  char   *reallocated;
 179+
 180+  len = getline_chomp(&nextline, &capa, stream);
 181+  if (len == -1)
 182+    return -1;
 183+  if (len > 0) {
 184+    oldline     = *lineptr;
 185+    reallocated = realloc(oldline, curlen + len + 1);
 186+    if (reallocated == NULL)
 187+      return -1;
 188+
 189+    memcpy(reallocated + curlen, nextline, len + 1);
 190+    *lineptr = reallocated;
 191+    *n       = curlen + len; /* nul not included */
 192+    free(nextline);
 193+  }
 194+  return curlen + len;
 195+}
 196+
 197+ssize_t
 198+getline_cont(char **lineptr, size_t *capa, FILE *stream, int *plineno)
 199+{
 200+  int     lineno = *plineno;
 201+  ssize_t len;
 202+  ssize_t nextlen;
 203+
 204+  len = getline_chomp(lineptr, capa, stream);
 205+  if (len != -1) {
 206+    /* handle backslash continuation */
 207+    while (++lineno, len > 0 && (*lineptr)[len - 1] == '\\') {
 208+      (*lineptr)[--len] = '\0';
 209+      nextlen           = getline_cat(lineptr, capa, stream, len);
 210+      if (nextlen == -1)
 211+        break;
 212+      len = nextlen;
 213+    }
 214+  }
 215+  *plineno = lineno;
 216+  return len;
 217+}
 218+
 219+int
 220+is_fullpath(const char *filename)
 221+{
 222+  const char *p;
 223+
 224+  if (*filename != '/')
 225+    return 0;
 226+  for (p = filename;;) {
 227+    p = strstr(p, "/..");
 228+    if (p == NULL)
 229+      return 1;
 230+    if (p[3] == '/' || p[3] == '\0')
 231+      return 0;
 232+    p += 3;
 233+  }
 234+}
 235+
 236+char *
 237+join_paths(const char *paths[])
 238+{
 239+  struct StringBuffer sb;
 240+  const char        **pp;
 241+  const char         *p;
 242+  const char         *last_path;
 243+  int                 parent_count;
 244+  enum Top {
 245+    OTHER,
 246+    ROOTDIR, /* / */
 247+    CURDIR,  /*  */
 248+  };
 249+  enum Top top;
 250+
 251+  sb_init(&sb);
 252+  parent_count = 0;
 253+  top          = OTHER;
 254+  last_path    = NULL;
 255+
 256+  for (pp = paths; (p = *pp++) != NULL;) {
 257+    const char *q;
 258+    int         end;
 259+    ptrdiff_t   len;
 260+
 261+    last_path = p;
 262+    if (*p == '/') { /* absolute, reset */
 263+      sb_init(&sb);
 264+      parent_count = 0;
 265+      top          = ROOTDIR;
 266+    }
 267+
 268+    for (end = 0; !end;) {
 269+      while (*p == '/')
 270+        ++p;
 271+      if (*p == '\0')
 272+        break;
 273+
 274+      q = strchr(p, '/');
 275+      if (q == NULL) { /* last component */
 276+        q   = p + strlen(p);
 277+        end = 1;
 278+      }
 279+      len = q - p;
 280+      if (len == 1 && *p == '.') {
 281+        if (sb.elems->len == 0 && top == OTHER)
 282+          top = CURDIR;
 283+      } else if (len == 2 && strncmp(p, "..", 2) == 0) {
 284+        if (sb.elems->len > 0) {
 285+          void *elem = vec_pop(sb.elems);
 286+          free(elem);
 287+        } else {
 288+          if (top == ROOTDIR)
 289+            return NULL; /* illegal */
 290+          ++parent_count;
 291+          top = OTHER;
 292+        }
 293+      } else {
 294+        sb_append(&sb, p, q);
 295+      }
 296+      p = q;
 297+    }
 298+  }
 299+
 300+  for (; parent_count > 0; --parent_count)
 301+    sb_prepend(&sb, "..", NULL);
 302+  switch (top) {
 303+    case OTHER:
 304+    case CURDIR:
 305+      if (sb.elems->len == 0)
 306+        sb_prepend(&sb, ".", NULL);
 307+      break;
 308+    case ROOTDIR:
 309+      sb_prepend(&sb, sb.elems->len > 0 ? "" : "/", NULL);
 310+      break;
 311+  }
 312+  if (last_path != NULL) {
 313+    size_t len = strlen(last_path);
 314+    if (len > 0 && last_path[len - 1] == '/' && !(top == ROOTDIR && sb.elems->len == 1))
 315+      sb_append(&sb, "", NULL);
 316+  }
 317+  return sb_join(&sb, "/");
 318+}
 319+
 320+char *
 321+get_ext(const char *filename)
 322+{
 323+  const char *last_slash;
 324+  char       *dot;
 325+
 326+  last_slash = strrchr(filename, '/');
 327+  if (last_slash == NULL)
 328+    last_slash = filename;
 329+  dot = strrchr(last_slash, '.');
 330+  return dot != NULL ? (char *)&dot[1] : (char *)&last_slash[strlen(last_slash)];
 331+}
 332+
 333+char *
 334+change_ext(const char *path, const char *ext)
 335+{
 336+  const char *p;
 337+  const char *q;
 338+  size_t      len;
 339+  size_t      ext_len;
 340+  char       *s;
 341+
 342+  p = strrchr(path, '/');
 343+  if (p == NULL)
 344+    p = path;
 345+
 346+  q       = strrchr(p, '.');
 347+  len     = q != NULL ? (size_t)(q - path) : strlen(path);
 348+  ext_len = strlen(ext);
 349+  s       = malloc(len + 1 + ext_len + 1);
 350+  if (s != NULL) {
 351+    memcpy(s, path, len);
 352+    s[len] = '.';
 353+    strcpy(s + (len + 1), ext);
 354+  }
 355+  return s;
 356+}
 357+
 358+void
 359+put_padding(FILE *fp, long start)
 360+{
 361+  long cur;
 362+  long size;
 363+  long i;
 364+
 365+  cur = ftell(fp);
 366+  if (cur < 0)
 367+    return; /* todo: error */
 368+  if (start > cur) {
 369+    size = start - cur;
 370+    for (i = 0; i < size; ++i)
 371+      fputc(0x00, fp);
 372+  }
 373+}
 374+
 375+int
 376+is_file(const char *path)
 377+{
 378+  struct stat st;
 379+  return stat(path, &st) == 0 && S_ISREG(st.st_mode); /* follows symlinks */
 380+}
 381+
 382+void
 383+show_version(const char *exe, int arch)
 384+{
 385+  /* order must match TC_ARCH_* constants in config.h */
 386+  static const char *const archs[] = {
 387+      NULL,
 388+      "x86_64",
 389+      "arm64",
 390+      "riscv64",
 391+      "wasm",
 392+  };
 393+
 394+  if (exe == NULL) {
 395+    printf("%s\n", VERSION);
 396+  } else if (arch <= 0) {
 397+    printf("%s version %s\n", exe, VERSION);
 398+  } else {
 399+    printf(
 400+        "%s version %s\n"
 401+        "Target: %s\n",
 402+        exe,
 403+        VERSION,
 404+        archs[arch]
 405+    );
 406+  }
 407+}
 408+
 409+_Noreturn void
 410+error(const char *fmt, ...)
 411+{
 412+  va_list ap;
 413+  va_start(ap, fmt);
 414+  vfprintf(stderr, fmt, ap);
 415+  va_end(ap);
 416+  fprintf(stderr, "\n");
 417+  exit(1);
 418+}
 419+
 420+void
 421+show_error_line(const char *line, const char *p, int len)
 422+{
 423+  size_t pos;
 424+  size_t i;
 425+
 426+  fprintf(stderr, "%s\n", line);
 427+  pos = p - line;
 428+  if (pos <= strlen(line)) {
 429+    for (i = 0; i < pos; ++i)
 430+      fputc(line[i] == '\t' ? '\t' : ' ', stderr);
 431+    fprintf(stderr, "^");
 432+    for (i = 1; i < (size_t)len; ++i)
 433+      fprintf(stderr, "~");
 434+    fprintf(stderr, "\n");
 435+  }
 436+}
 437+
 438+/* value range checks for immediate operands */
 439+
 440+int
 441+is_im8(int64_t x)
 442+{
 443+  return x <= (((int64_t)1 << 7) - 1) && x >= -((int64_t)1 << 7);
 444+}
 445+
 446+int
 447+is_im16(int64_t x)
 448+{
 449+  return x <= (((int64_t)1 << 15) - 1) && x >= -((int64_t)1 << 15);
 450+}
 451+
 452+int
 453+is_im32(int64_t x)
 454+{
 455+  return x <= (((int64_t)1 << 31) - 1) && x >= -((int64_t)1 << 31);
 456+}
 457+
 458+const char *
 459+skip_whitespaces(const char *s)
 460+{
 461+  for (;;) {
 462+    while (isspace(*s))
 463+      ++s;
 464+    /* gas allows block comments and line comments wherever whitespace is valid */
 465+    if (s[0] == '/' && s[1] == '*') {
 466+      s += 2;
 467+      while (*s != '\0' && !(s[0] == '*' && s[1] == '/'))
 468+        ++s;
 469+      if (*s != '\0')
 470+        s += 2;
 471+      continue;
 472+    }
 473+    if (s[0] == '/' && s[1] == '/') {
 474+      while (*s != '\0')
 475+        ++s;
 476+      continue;
 477+    }
 478+    break;
 479+  }
 480+  return s;
 481+}
 482+
 483+/* detect block comment start without consuming it via skip_whitespaces */
 484+const char *
 485+block_comment_start(const char *p)
 486+{
 487+  while (isspace(*p))
 488+    ++p;
 489+  return (*p == '/' && p[1] == '*') ? p : NULL;
 490+}
 491+
 492+const char *
 493+block_comment_end(const char *p)
 494+{
 495+  for (;;) {
 496+    p = strchr(p, '*');
 497+    if (p == NULL)
 498+      return NULL;
 499+    if (*(++p) == '/')
 500+      return p + 1;
 501+  }
 502+}
 503+
 504+int64_t
 505+wrap_value(int64_t value, int size, int is_unsigned)
 506+{
 507+  if (is_unsigned) {
 508+    switch (size) {
 509+      case 1:
 510+        value = (uint8_t)value;
 511+        break;
 512+      case 2:
 513+        value = (uint16_t)value;
 514+        break;
 515+      case 4:
 516+        value = (uint32_t)value;
 517+        break;
 518+      default:
 519+        break;
 520+    }
 521+  } else {
 522+    switch (size) {
 523+      case 1:
 524+        value = (int8_t)value;
 525+        break;
 526+      case 2:
 527+        value = (int16_t)value;
 528+        break;
 529+      case 4:
 530+        value = (int32_t)value;
 531+        break;
 532+      default:
 533+        break;
 534+    }
 535+  }
 536+  return value;
 537+}
 538+
 539+/* container: growable pointer vector */
 540+
 541+struct Vector *
 542+new_vector(void)
 543+{
 544+  struct Vector *vec = malloc_or_die(sizeof(struct Vector));
 545+  vec_init(vec);
 546+  return vec;
 547+}
 548+
 549+void
 550+free_vector(struct Vector *vec)
 551+{
 552+  free(vec->data);
 553+  free(vec);
 554+}
 555+
 556+void
 557+vec_init(struct Vector *vec)
 558+{
 559+  vec->data     = NULL;
 560+  vec->capacity = 0;
 561+  vec->len      = 0;
 562+}
 563+
 564+void
 565+vec_clear(struct Vector *vec)
 566+{
 567+  vec->len = 0;
 568+}
 569+
 570+void
 571+vec_push(struct Vector *vec, const void *elem)
 572+{
 573+  if (vec->capacity <= vec->len) {
 574+    if (vec->capacity <= 0)
 575+      vec->capacity = 16;
 576+    else
 577+      vec->capacity <<= 1;
 578+    vec->data = realloc_or_die(vec->data, sizeof(*vec->data) * vec->capacity);
 579+  }
 580+  vec->data[vec->len++] = (void *)elem;
 581+}
 582+
 583+void *
 584+vec_pop(struct Vector *vec)
 585+{
 586+  return vec->len > 0 ? vec->data[--vec->len] : NULL;
 587+}
 588+
 589+void
 590+vec_insert(struct Vector *vec, int pos, const void *elem)
 591+{
 592+  int len = vec->len;
 593+
 594+  if (pos < 0 || pos > len)
 595+    return;
 596+
 597+  if (pos < len) {
 598+    vec_push(vec, NULL);
 599+    memmove(&vec->data[pos + 1], &vec->data[pos], sizeof(void *) * (len - pos));
 600+    vec->data[pos] = (void *)elem;
 601+  } else {
 602+    vec_push(vec, elem);
 603+  }
 604+}
 605+
 606+void
 607+vec_remove_at(struct Vector *vec, int index)
 608+{
 609+  int d;
 610+
 611+  if (index < 0 || index >= vec->len)
 612+    return;
 613+  d = vec->len - index - 1;
 614+  if (d > 0)
 615+    memmove(&vec->data[index], &vec->data[index + 1], d * sizeof(*vec->data));
 616+  --vec->len;
 617+}
 618+
 619+int
 620+vec_contains(struct Vector *vec, void *elem)
 621+{
 622+  int i, len;
 623+
 624+  len = vec->len;
 625+  for (i = 0; i < len; ++i) {
 626+    if (vec->data[i] == elem)
 627+      return 1;
 628+  }
 629+  return 0;
 630+}
 631+
 632+void
 633+vec_concat(struct Vector *dst, const struct Vector *src)
 634+{
 635+  int i;
 636+
 637+  for (i = 0; i < src->len; ++i)
 638+    vec_push(dst, src->data[i]);
 639+}
 640+
 641+/* container: growable byte buffer */
 642+
 643+void
 644+data_release(struct DataStorage *data)
 645+{
 646+  if (data->chunk_stack != NULL) {
 647+    free_vector(data->chunk_stack);
 648+    data->chunk_stack = NULL;
 649+  }
 650+  if (data->buf != NULL) {
 651+    free(data->buf);
 652+    data_init(data);
 653+  }
 654+}
 655+
 656+void
 657+data_init(struct DataStorage *data)
 658+{
 659+  data->chunk_stack = NULL;
 660+  data->buf         = NULL;
 661+  data->capacity    = 0;
 662+  data->len         = 0;
 663+}
 664+
 665+void
 666+data_reserve(struct DataStorage *data, size_t capacity)
 667+{
 668+  const size_t min_cap = 16;
 669+  size_t       c;
 670+
 671+  if (data->capacity < capacity) {
 672+    c = data->capacity << 1;
 673+    if (c > capacity)
 674+      capacity = c;
 675+    if (min_cap > capacity)
 676+      capacity = min_cap;
 677+    data->buf      = realloc_or_die(data->buf, sizeof(*data->buf) * capacity);
 678+    data->capacity = capacity;
 679+  }
 680+}
 681+
 682+void
 683+data_insert(struct DataStorage *data, ssize_t pos_, const void *buf, size_t size)
 684+{
 685+  size_t pos;
 686+  size_t newlen;
 687+
 688+  pos = pos_ == -1 ? data->len : (size_t)pos_;
 689+  assert(pos <= data->len);
 690+  newlen = data->len + size;
 691+  data_reserve(data, newlen);
 692+  if (pos < data->len)
 693+    memmove(data->buf + pos + size, data->buf + pos, data->len - pos);
 694+  memcpy(data->buf + pos, buf, size);
 695+  data->len = newlen;
 696+}
 697+
 698+void
 699+data_append(struct DataStorage *data, const void *buf, size_t size)
 700+{
 701+  data_insert(data, -1, buf, size);
 702+}
 703+
 704+void
 705+data_push(struct DataStorage *data, unsigned char c)
 706+{
 707+  unsigned char buf[1] = {c};
 708+  data_insert(data, -1, buf, 1);
 709+}
 710+
 711+void
 712+data_align(struct DataStorage *data, int align)
 713+{
 714+  size_t len;
 715+  size_t aligned_len;
 716+  size_t add;
 717+  void  *zero;
 718+
 719+  len         = data->len;
 720+  aligned_len = ALIGN(len, align);
 721+  add         = aligned_len - len;
 722+  if (add <= 0)
 723+    return;
 724+
 725+  zero = calloc_or_die(add);
 726+  data_append(data, zero, add);
 727+  free(zero);
 728+
 729+  assert(data->len == aligned_len);
 730+}
 731+
 732+void
 733+data_concat(struct DataStorage *dst, struct DataStorage *src)
 734+{
 735+  data_insert(dst, -1, src->buf, src->len);
 736+}
 737+
 738+void
 739+data_leb128(struct DataStorage *data, ssize_t pos, int64_t val)
 740+{
 741+  unsigned char buf[12], *p = buf;
 742+  const int64_t max = (int64_t)1 << 6;
 743+
 744+  for (;;) {
 745+    if (val < max && val >= -max) {
 746+      *p++ = val & 0x7f;
 747+      data_insert(data, pos, buf, p - buf);
 748+      return;
 749+    }
 750+    *p++ = (val & 0x7f) | 0x80;
 751+    val >>= 7;
 752+  }
 753+}
 754+
 755+void
 756+data_uleb128(struct DataStorage *data, ssize_t pos, uint64_t val)
 757+{
 758+  unsigned char  buf[12], *p = buf;
 759+  const uint64_t max = (uint64_t)1 << 7;
 760+
 761+  for (;;) {
 762+    if (val < max) {
 763+      *p++ = val & 0x7f;
 764+      data_insert(data, pos, buf, p - buf);
 765+      return;
 766+    }
 767+    *p++ = (val & 0x7f) | 0x80;
 768+    val >>= 7;
 769+  }
 770+}
 771+
 772+void
 773+data_string(struct DataStorage *data, const void *str, size_t len)
 774+{
 775+  data_uleb128(data, -1, len);
 776+  data_append(data, (const unsigned char *)str, len);
 777+}
 778+
 779+void
 780+data_varint32(struct DataStorage *data, ssize_t pos, int64_t val)
 781+{
 782+  unsigned char buf[5], *p = buf;
 783+  int           i;
 784+
 785+  for (i = 0; i < 4; ++i) {
 786+    *p++ = (val & 0x7f) | 0x80;
 787+    val >>= 7;
 788+  }
 789+  *p++ = val & 0x7f;
 790+  data_insert(data, pos, buf, p - buf);
 791+}
 792+
 793+void
 794+data_varuint32(struct DataStorage *data, ssize_t pos, uint64_t val)
 795+{
 796+  unsigned char buf[5], *p = buf;
 797+  int           i;
 798+
 799+  for (i = 0; i < 4; ++i) {
 800+    *p++ = (val & 0x7f) | 0x80;
 801+    val >>= 7;
 802+  }
 803+  *p++ = val & 0x7f;
 804+  data_insert(data, pos, buf, p - buf);
 805+}
 806+
 807+void
 808+data_open_chunk(struct DataStorage *data)
 809+{
 810+  struct Vector *stack = data->chunk_stack;
 811+  if (stack == NULL)
 812+    data->chunk_stack = stack = new_vector();
 813+  vec_push(stack, INT2VOIDP(data->len));
 814+}
 815+
 816+void
 817+data_close_chunk(struct DataStorage *data, ssize_t num)
 818+{
 819+  struct Vector *stack = data->chunk_stack;
 820+  size_t         pos;
 821+
 822+  assert(stack != NULL && stack->len > 0);
 823+  pos = VOIDP2INT(vec_pop(stack));
 824+  if (num == (ssize_t)-1)
 825+    num = data->len - pos;
 826+  data_uleb128(data, pos, num);
 827+}
 828+
 829+/* container: rope-style string builder */
 830+
 831+struct StringElement {
 832+  const char *start;
 833+  size_t      len;
 834+};
 835+
 836+void
 837+sb_init(struct StringBuffer *sb)
 838+{
 839+  sb->elems = new_vector();
 840+}
 841+
 842+void
 843+sb_clear(struct StringBuffer *sb)
 844+{
 845+  vec_clear(sb->elems);
 846+}
 847+
 848+int
 849+sb_empty(struct StringBuffer *sb)
 850+{
 851+  return sb->elems->len == 0;
 852+}
 853+
 854+void
 855+sb_insert(struct StringBuffer *sb, int pos, const char *start, const char *end)
 856+{
 857+  struct StringElement *elem = malloc(sizeof(*elem));
 858+
 859+  if (elem != NULL) {
 860+    elem->start = start;
 861+    elem->len   = end != NULL ? (size_t)(end - start) : strlen(start);
 862+    assert(0 <= pos && pos <= sb->elems->len);
 863+    vec_insert(sb->elems, pos, elem);
 864+  }
 865+}
 866+
 867+char *
 868+sb_join(struct StringBuffer *sb, const char *separator)
 869+{
 870+  size_t total_len;
 871+  int    count;
 872+  int    i;
 873+  size_t sepalen;
 874+  char  *str;
 875+  char  *p;
 876+
 877+  total_len = 0;
 878+  count     = sb->elems->len;
 879+  for (i = 0; i < count; ++i) {
 880+    struct StringElement *elem = sb->elems->data[i];
 881+    total_len += elem->len;
 882+  }
 883+  sepalen = separator != NULL ? strlen(separator) : 0;
 884+  if (count > 0 && sepalen > 0)
 885+    total_len += sepalen * (count - 1);
 886+
 887+  str = malloc(total_len + 1);
 888+  if (str != NULL) {
 889+    p = str;
 890+    for (i = 0; i < count; ++i) {
 891+      struct StringElement *elem;
 892+      if (i > 0 && sepalen > 0) {
 893+        memcpy(p, separator, sepalen);
 894+        p += sepalen;
 895+      }
 896+      elem = sb->elems->data[i];
 897+      memcpy(p, elem->start, elem->len);
 898+      p += elem->len;
 899+    }
 900+    *p = '\0';
 901+  }
 902+  return str;
 903+}
 904+
 905+/* string escaping for assembler output */
 906+
 907+static const char *
 908+escape_hex(int c)
 909+{
 910+  char *s = malloc_or_die(5);
 911+  /* hex escapes are not length-limited so following hex chars would
 912+ * be consumed, must use octal which is always 3 digits */
 913+  snprintf(s, 5, "\\%03o", c & 0xff);
 914+  return s;
 915+}
 916+
 917+static const char *
 918+escape(int c)
 919+{
 920+  switch (c) {
 921+    case '\0':
 922+      return "\\000"; /* octal, at most 3 digits in assembler */
 923+    case '\n':
 924+      return "\\n";
 925+    case '\r':
 926+      return "\\r";
 927+    case '\t':
 928+      return "\\t";
 929+    case '"':
 930+      return "\\\"";
 931+    case '\\':
 932+      return "\\\\";
 933+    default:
 934+      if (c < 0x20 || c >= 0x7f)
 935+        return escape_hex(c);
 936+      return NULL;
 937+  }
 938+}
 939+
 940+void
 941+escape_string(const char *str, size_t size, struct StringBuffer *sb)
 942+{
 943+  const char *s, *p;
 944+  const char *end;
 945+  const char *e;
 946+  int         hex;
 947+
 948+  end = str + size;
 949+  hex = 0;
 950+  for (s = p = str; p < end; ++p) {
 951+    if (hex && isxdigit(*p)) {
 952+      e = escape_hex(*p);
 953+    } else {
 954+      e = escape(*p);
 955+      if (e == NULL) {
 956+        hex = 0;
 957+        continue;
 958+      }
 959+    }
 960+
 961+    if (p > s)
 962+      sb_append(sb, s, p);
 963+    sb_append(sb, e, NULL);
 964+    s   = p + 1;
 965+    hex = e[1] == 'x';
 966+  }
 967+  if (p > s) {
 968+    assert(!hex);
 969+    sb_append(sb, s, p);
 970+  }
 971+}
 972+
 973+/* option parser: long-option style for toolchain commands */
 974+
 975+int   optind;
 976+int   optopt;
 977+int   opterr = 1;
 978+char *optarg;
 979+
 980+int
 981+optparse(int argc, char *const argv[], const struct option *opts)
 982+{
 983+#define ERROR(...)                                                                                 \
 984+  do {                                                                                             \
 985+    if (opterr)                                                                                    \
 986+      fprintf(stderr, __VA_ARGS__);                                                                \
 987+  } while (0)
 988+
 989+  char  *arg;
 990+  char  *p;
 991+  char  *q;
 992+  char   c;
 993+  int    opt;
 994+  size_t len;
 995+
 996+  if (optind == 0)
 997+    optind = 1;
 998+
 999+  if (optind >= argc)
1000+    return -1;
1001+
1002+  optarg = NULL;
1003+  optopt = 0;
1004+
1005+  arg = argv[optind];
1006+  p   = arg;
1007+  if (*p != '-' || p[1] == '\0')
1008+    return -1;
1009+
1010+  p += 1;
1011+  ++optind;
1012+  for (; opts->name != NULL; ++opts) {
1013+    len = strlen(opts->name);
1014+    if (strncmp(p, opts->name, len) == 0) {
1015+      opt = opts->val;
1016+      if (opt == 0)
1017+        opt = arg[1];
1018+      q = p + len;
1019+      c = *q;
1020+      if (opts->has_arg) {
1021+        if (c != '\0') {
1022+          optarg = q + (c == '=' ? 1 : 0);
1023+        } else if (opts->has_arg == required_argument) {
1024+          if (optind < argc) {
1025+            optarg = argv[optind++];
1026+          } else {
1027+            ERROR(
1028+                "%s: option '--%s' "
1029+                "requires an argument\n",
1030+                argv[0],
1031+                opts->name
1032+            );
1033+            break;
1034+          }
1035+        }
1036+      } else {
1037+        if (c != '\0') {
1038+          if (c != '=')
1039+            continue;
1040+          ERROR(
1041+              "%s: option '--%s' doesn't allow "
1042+              "an argument\n",
1043+              argv[0],
1044+              opts->name
1045+          );
1046+          break;
1047+        }
1048+      }
1049+      return opt;
1050+    }
1051+  }
1052+
1053+  optopt = arg[1];
1054+  return '?';
1055+#undef ERROR
1056+}
+169, -0
  1@@ -0,0 +1,169 @@
  2+/* toolchain utility library: memory, paths, containers, option parsing */
  3+
  4+#ifndef ARUU_TCUTIL_H
  5+#define ARUU_TCUTIL_H
  6+
  7+#include <stddef.h>    /* size_t */
  8+#include <stdint.h>    /* intptr_t */
  9+#include <stdio.h>     /* FILE */
 10+#include <sys/types.h> /* ssize_t */
 11+
 12+/* macros also defined by shared/util.h, undef to avoid redefinition warning */
 13+#undef MIN
 14+#undef MAX
 15+#undef ALIGN
 16+
 17+#define MIN(a, b)        ((a) < (b) ? (a) : (b))
 18+#define MAX(a, b)        ((a) > (b) ? (a) : (b))
 19+#define ALIGN(x, align)  (((x) + (align) - 1) & -(align)) /* align must be power of 2 */
 20+#define UNUSED(x)        ((void)(x))
 21+#define IS_POWER_OF_2(x) ((x) > 0 && ((x) & ((x) - 1)) == 0)
 22+#define INT2VOIDP(i)     ((void *)(intptr_t)(i))
 23+#define UINT2VOIDP(i)    ((void *)(uintptr_t)(i))
 24+#define VOIDP2INT(p)     ((intptr_t)(p))
 25+#define VOIDP2UINT(p)    ((uintptr_t)(p))
 26+#define ARRAY_SIZE(a)    (sizeof(a) / sizeof(*(a)))
 27+
 28+struct Name;
 29+
 30+/* character classification */
 31+int isalnum_(int c);
 32+int isutf8first(int c);
 33+int isutf8follow(int c);
 34+int isoctal(int c);
 35+int xvalue(char c);
 36+
 37+/* string and path helpers */
 38+int         starts_with(const char *str, const char *prefix);
 39+int         is_fullpath(const char *filename);
 40+char       *join_paths(const char *paths[]);
 41+char       *get_ext(const char *filename);
 42+char       *change_ext(const char *path, const char *ext);
 43+const char *skip_whitespaces(const char *s);
 44+const char *block_comment_start(const char *p);
 45+const char *block_comment_end(const char *p);
 46+
 47+/* file I/O helpers */
 48+void   *read_or_die(FILE *fp, void *buf, long offset, size_t size, const char *msg);
 49+void    put_padding(FILE *fp, long start);
 50+int     is_file(const char *path);
 51+ssize_t getline_chomp(char **lineptr, size_t *n, FILE *stream);
 52+ssize_t getline_cont(char **lineptr, size_t *n, FILE *stream, int *plineno);
 53+
 54+/* memory: toolchain-local, same contract as aruu emalloc/ecalloc/erealloc
 55+ * kept separate so the toolchain can build standalone without libutil */
 56+void *malloc_or_die(size_t size);
 57+void *calloc_or_die(size_t size);
 58+void *realloc_or_die(void *ptr, size_t size);
 59+
 60+/* diagnostics */
 61+void           show_version(const char *exe, int arch);
 62+_Noreturn void error(const char *fmt, ...);
 63+void           show_error_line(const char *line, const char *p, int len);
 64+
 65+/* value range checks for immediate operands */
 66+int     is_im8(int64_t x);
 67+int     is_im16(int64_t x);
 68+int     is_im32(int64_t x);
 69+int64_t wrap_value(int64_t value, int size, int is_unsigned);
 70+int     most_significant_bit(size_t x);
 71+
 72+/* name interning (see table.h for struct name) */
 73+const struct Name *alloc_label(void);
 74+
 75+/* container: growable pointer vector */
 76+struct Vector {
 77+  void **data;
 78+  int    capacity;
 79+  int    len;
 80+};
 81+
 82+struct Vector *new_vector(void);
 83+void           free_vector(struct Vector *vec);
 84+void           vec_init(struct Vector *vec);
 85+void           vec_clear(struct Vector *vec);
 86+void           vec_push(struct Vector *vec, const void *elem);
 87+void          *vec_pop(struct Vector *vec);
 88+void           vec_insert(struct Vector *vec, int pos, const void *elem);
 89+void           vec_remove_at(struct Vector *vec, int index);
 90+int            vec_contains(struct Vector *vec, void *elem);
 91+void           vec_concat(struct Vector *dst, const struct Vector *src);
 92+
 93+/* container: growable byte buffer */
 94+struct DataStorage {
 95+  struct Vector *chunk_stack;
 96+  unsigned char *buf;
 97+  size_t         capacity;
 98+  size_t         len;
 99+};
100+
101+void data_release(struct DataStorage *data);
102+void data_init(struct DataStorage *data);
103+void data_reserve(struct DataStorage *data, size_t capacity);
104+void data_insert(struct DataStorage *data, ssize_t pos, const void *buf, size_t size);
105+void data_append(struct DataStorage *data, const void *buf, size_t size);
106+void data_push(struct DataStorage *data, unsigned char c);
107+void data_align(struct DataStorage *data, int align);
108+void data_concat(struct DataStorage *dst, struct DataStorage *src);
109+void data_leb128(struct DataStorage *data, ssize_t pos, int64_t val);
110+void data_uleb128(struct DataStorage *data, ssize_t pos, uint64_t val);
111+void data_string(struct DataStorage *data, const void *str, size_t len);
112+void data_open_chunk(struct DataStorage *data);
113+void data_close_chunk(struct DataStorage *data, ssize_t num);
114+void data_varint32(struct DataStorage *data, ssize_t pos, int64_t val);
115+void data_varuint32(struct DataStorage *data, ssize_t pos, uint64_t val);
116+
117+/* container: rope-style string builder */
118+struct StringBuffer {
119+  struct Vector *elems;
120+};
121+
122+void  sb_init(struct StringBuffer *sb);
123+void  sb_clear(struct StringBuffer *sb);
124+int   sb_empty(struct StringBuffer *sb);
125+void  sb_insert(struct StringBuffer *sb, int pos, const char *start, const char *end);
126+char *sb_join(struct StringBuffer *sb, const char *separator);
127+
128+static inline void
129+sb_append(struct StringBuffer *sb, const char *start, const char *end)
130+{
131+  sb_insert(sb, sb->elems->len, start, end);
132+}
133+
134+static inline void
135+sb_prepend(struct StringBuffer *sb, const char *start, const char *end)
136+{
137+  sb_insert(sb, 0, start, end);
138+}
139+
140+static inline char *
141+sb_to_string(struct StringBuffer *sb)
142+{
143+  return sb_join(sb, NULL);
144+}
145+
146+void escape_string(const char *str, size_t size, struct StringBuffer *sb);
147+
148+/* convenience macro for join_paths */
149+#define JOIN_PATHS(...) join_paths((const char *[]){__VA_ARGS__, NULL})
150+
151+/* option parser: long-option style for toolchain commands
152+ * has_arg values: 0 = none, 1 = required, 2 = optional */
153+#define no_argument       0
154+#define required_argument 1
155+#define optional_argument 2
156+
157+struct option {
158+  const char *name;
159+  int         has_arg;
160+  int         val;
161+};
162+
163+extern int   optind;
164+extern int   opterr;
165+extern int   optopt;
166+extern char *optarg;
167+
168+int optparse(int argc, char *const argv[], const struct option *opts);
169+
170+#endif /* ARUU_TCUTIL_H */
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <errno.h>
5 #include <stdio.h>
6 #include <stdlib.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <errno.h>
5 #include <stdio.h>
6 #include <stdlib.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* Automatically generated by mkrunetype.awk */
3+/* automatically generated by mkrunetype.awk */
4 #include "../utf.h"
5 #include "runetype.h"
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* Automatically generated by mkrunetype.awk */
3+/* automatically generated by mkrunetype.awk */
4 #include <stdlib.h>
5 
6 #include "../utf.h"
+1, -1
1@@ -1,4 +1,4 @@
2-/* Automatically generated by mkrunetype.awk */
3+/* automatically generated by mkrunetype.awk */
4 #include "../utf.h"
5 #include "runetype.h"
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* Automatically generated by mkrunetype.awk */
3+/* automatically generated by mkrunetype.awk */
4 #include <stdlib.h>
5 
6 #include "../utf.h"
+1, -1
1@@ -1,4 +1,4 @@
2-/* Automatically generated by mkrunetype.awk */
3+/* automatically generated by mkrunetype.awk */
4 #include <stdlib.h>
5 
6 #include "../utf.h"
+1, -1
1@@ -1,4 +1,4 @@
2-/* Automatically generated by mkrunetype.awk */
3+/* automatically generated by mkrunetype.awk */
4 #include "../utf.h"
5 #include "runetype.h"
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* Automatically generated by mkrunetype.awk */
3+/* automatically generated by mkrunetype.awk */
4 #include "../utf.h"
5 #include "runetype.h"
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* Automatically generated by mkrunetype.awk */
3+/* automatically generated by mkrunetype.awk */
4 #include "../utf.h"
5 #include "runetype.h"
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* Automatically generated by mkrunetype.awk */
3+/* automatically generated by mkrunetype.awk */
4 #include <stdlib.h>
5 
6 #include "../utf.h"
+1, -1
1@@ -1,4 +1,4 @@
2-/* Automatically generated by mkrunetype.awk */
3+/* automatically generated by mkrunetype.awk */
4 #include <stdlib.h>
5 
6 #include "../utf.h"
+1, -1
1@@ -1,4 +1,4 @@
2-/* Automatically generated by mkrunetype.awk */
3+/* automatically generated by mkrunetype.awk */
4 #include "../utf.h"
5 #include "runetype.h"
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* Automatically generated by mkrunetype.awk */
3+/* automatically generated by mkrunetype.awk */
4 #include <stdlib.h>
5 
6 #include "../utf.h"
+12, -12
 1@@ -1,22 +1,22 @@
 2-/* MIT/X Consortium Copyright (c) 2012 Connor Lane Smith <cls@lubutu.com>
 3+/* MIT/X consortium copyright (c) 2012 connor lane smith <cls@lubutu.com>
 4  *
 5- * Permission is hereby granted, free of charge, to any person obtaining a
 6- * copy of this software and associated documentation files (the "Software"),
 7- * to deal in the Software without restriction, including without limitation
 8+ * permission is hereby granted, free of charge, to any person obtaining a
 9+ * copy of this software and associated documentation files (the "software"),
10+ * to deal in the software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12- * and/or sell copies of the Software, and to permit persons to whom the
13- * Software is furnished to do so, subject to the following conditions:
14+ * and/or sell copies of the software, and to permit persons to whom the
15+ * software is furnished to do so, subject to the following conditions:
16  *
17- * The above copyright notice and this permission notice shall be included in
18- * all copies or substantial portions of the Software.
19+ * the above copyright notice and this permission notice shall be included in
20+ * all copies or substantial portions of the software
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
25+ * FITNESS FOR a PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29- * DEALINGS IN THE SOFTWARE.
30+ * DEALINGS IN THE SOFTWARE
31  */
32 #include "../utf.h"
33 
34@@ -77,7 +77,7 @@ charntorune(Rune *p, const char *s, size_t len)
35   unsigned int i, n;
36   Rune         r;
37 
38-  if (len == 0) /* can't even look at s[0] */
39+  if (len == 0) /* cant even look at s[0] */
40     return 0;
41 
42   switch ((n = UTFSEQ(s[0]))) {
43@@ -107,7 +107,7 @@ charntorune(Rune *p, const char *s, size_t len)
44   for (i = 1; i < MIN(n, len); i++)
45     if ((s[i] & 0xC0) == 0x80) {
46       /* add bits from continuation byte to rune value
47-       * cannot overflow: 6 byte sequences contain 31 bits */
48+ * cannot overflow: 6 byte sequences contain 31 bits */
49       r = (r << 6) | (s[i] & 0x3F); /* 10xxxxxx */
50     } else {                        /* expected continuation */
51       *p = Runeerror;
+11, -11
 1@@ -1,23 +1,23 @@
 2-/* MIT/X Consortium Copyright (c) 2012 Connor Lane Smith <cls@lubutu.com>
 3- *                            (c) 2015 Laslo Hunhold <dev@frign.de>
 4+/* MIT/X consortium copyright (c) 2012 connor lane smith <cls@lubutu.com>
 5+ * (c) 2015 laslo hunhold <dev@frign.de>
 6  *
 7- * Permission is hereby granted, free of charge, to any person obtaining a
 8- * copy of this software and associated documentation files (the "Software"),
 9- * to deal in the Software without restriction, including without limitation
10+ * permission is hereby granted, free of charge, to any person obtaining a
11+ * copy of this software and associated documentation files (the "software"),
12+ * to deal in the software without restriction, including without limitation
13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14- * and/or sell copies of the Software, and to permit persons to whom the
15- * Software is furnished to do so, subject to the following conditions:
16+ * and/or sell copies of the software, and to permit persons to whom the
17+ * software is furnished to do so, subject to the following conditions:
18  *
19- * The above copyright notice and this permission notice shall be included in
20- * all copies or substantial portions of the Software.
21+ * the above copyright notice and this permission notice shall be included in
22+ * all copies or substantial portions of the software
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
27+ * FITNESS FOR a PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
30  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
31- * DEALINGS IN THE SOFTWARE.
32+ * DEALINGS IN THE SOFTWARE
33  */
34 #include "../utf.h"
35 
+11, -11
 1@@ -1,23 +1,23 @@
 2-/* MIT/X Consortium Copyright (c) 2012 Connor Lane Smith <cls@lubutu.com>
 3- *                            (c) 2015 Laslo Hunhold <dev@frign.de>
 4+/* MIT/X consortium copyright (c) 2012 connor lane smith <cls@lubutu.com>
 5+ * (c) 2015 laslo hunhold <dev@frign.de>
 6  *
 7- * Permission is hereby granted, free of charge, to any person obtaining a
 8- * copy of this software and associated documentation files (the "Software"),
 9- * to deal in the Software without restriction, including without limitation
10+ * permission is hereby granted, free of charge, to any person obtaining a
11+ * copy of this software and associated documentation files (the "software"),
12+ * to deal in the software without restriction, including without limitation
13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14- * and/or sell copies of the Software, and to permit persons to whom the
15- * Software is furnished to do so, subject to the following conditions:
16+ * and/or sell copies of the software, and to permit persons to whom the
17+ * software is furnished to do so, subject to the following conditions:
18  *
19- * The above copyright notice and this permission notice shall be included in
20- * all copies or substantial portions of the Software.
21+ * the above copyright notice and this permission notice shall be included in
22+ * all copies or substantial portions of the software
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
27+ * FITNESS FOR a PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
30  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
31- * DEALINGS IN THE SOFTWARE.
32+ * DEALINGS IN THE SOFTWARE
33  */
34 
35 #define nelem(x) (sizeof(x) / sizeof *(x))
+1, -1
1@@ -1,4 +1,4 @@
2-/* Automatically generated by mkrunetype.awk */
3+/* automatically generated by mkrunetype.awk */
4 #include <stdlib.h>
5 
6 #include "../utf.h"
+10, -10
 1@@ -1,22 +1,22 @@
 2-/* MIT/X Consortium Copyright (c) 2012 Connor Lane Smith <cls@lubutu.com>
 3+/* MIT/X consortium copyright (c) 2012 connor lane smith <cls@lubutu.com>
 4  *
 5- * Permission is hereby granted, free of charge, to any person obtaining a
 6- * copy of this software and associated documentation files (the "Software"),
 7- * to deal in the Software without restriction, including without limitation
 8+ * permission is hereby granted, free of charge, to any person obtaining a
 9+ * copy of this software and associated documentation files (the "software"),
10+ * to deal in the software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12- * and/or sell copies of the Software, and to permit persons to whom the
13- * Software is furnished to do so, subject to the following conditions:
14+ * and/or sell copies of the software, and to permit persons to whom the
15+ * software is furnished to do so, subject to the following conditions:
16  *
17- * The above copyright notice and this permission notice shall be included in
18- * all copies or substantial portions of the Software.
19+ * the above copyright notice and this permission notice shall be included in
20+ * all copies or substantial portions of the software
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
25+ * FITNESS FOR a PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29- * DEALINGS IN THE SOFTWARE.
30+ * DEALINGS IN THE SOFTWARE
31  */
32 #include "../utf.h"
33 #include <string.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include "../utf.h"
5 
6 size_t
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <unistd.h>
5 
6 #include "../util.h"
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <errno.h>
5 #include <stdio.h>
6 #include <stdlib.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <unistd.h>
5 
6 #include "../util.h"
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <ctype.h>
5 #include <stdarg.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <dirent.h>
5 #include <errno.h>
6 #include <fcntl.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <fcntl.h>
5 #include <stdint.h>
6 #include <stdio.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include "../diffutil.h"
5 #include "../text.h"
6 #include "../util.h"
+4, -2
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 #include "../diskutil.h"
 5 #include "../util.h"
 6 
 7@@ -158,7 +158,7 @@ blockdev_get_list(void)
 8     info->minor = minor;
 9 
10     /* search tree topology to link partition node under proper
11-     * target parent disk */
12+ * target parent disk */
13     is_part = 0;
14     for (curr = head; curr; curr = curr->next) {
15       size_t len = strlen(curr->name);
16@@ -499,6 +499,8 @@ static const struct FsType fstypes[] = {
17     {"vfat", 54, 4, 0x31544146, 0, 39, 4, 43, 11},
18     /* ntfs */
19     {"ntfs", 3, 4, 0x5346544e, 0, 72, 8, 0, 0},
20+    /* iso9660: "CD001" at the primary volume descriptor, LBA 16 */
21+    {"iso9660", 32769, 5, 0x3130304443ULL, 0, 0, 0, 32808, 32},
22     /* xfs */
23     {"xfs", 0, 4, 0x42534658, 0x58465342, 32, 16, 108, 12},
24     /* btrfs */
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <stdlib.h>
5 #include <string.h>
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <libgen.h>
5 #include <stdio.h>
6 #include <stdlib.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <stdarg.h>
5 #include <stdio.h>
6 #include <stdlib.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <errno.h>
5 #include <stdio.h>
6 #include <stdlib.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <errno.h>
5 #include <stdio.h>
6 #include <stdlib.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <errno.h>
5 #include <stdio.h>
6 #include <stdlib.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <string.h>
5 
6 #include "../util.h"
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <stdio.h>
5 
6 #include "../text.h"
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <sys/stat.h>
5 
6 #include "../util.h"
+6, -6
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 #include <stdio.h>
 5 #include <stdlib.h>
 6 
 7@@ -9,11 +9,11 @@ fshut(FILE *fp, const char *fname)
 8 {
 9   int ret = 0;
10 
11-  /* fflush() is undefined for input streams by ISO C,
12-   * but not POSIX 2008 if you ignore ISO C overrides.
13-   * Leave it unchecked and rely on the following
14-   * functions to detect errors.
15-   */
16+  /* fflush() is undefined for input streams by ISO c,
17+ * but not POSIX 2008 if you ignore ISO c overrides
18+ * leave it unchecked and rely on the following
19+ * functions to detect errors
20+ */
21   fflush(fp);
22 
23   if (ferror(fp) && !ret) {
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
+14, -0
 1@@ -0,0 +1,14 @@
 2+/* see LICENSE file for copyright and license details */
 3+#include "../util.h"
 4+
 5+int
 6+hexval(int c)
 7+{
 8+  if ('0' <= c && c <= '9')
 9+    return c - '0';
10+  if ('a' <= c && c <= 'f')
11+    return c - 'a' + 10;
12+  if ('A' <= c && c <= 'F')
13+    return c - 'A' + 10;
14+  return -1;
15+}
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <stdint.h>
5 #include <stdio.h>
6 #include <string.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <stdio.h>
5 #include <string.h>
6 
+15, -15
 1@@ -1,31 +1,31 @@
 2-/*	$OpenBSD: memmem.c,v 1.4 2015/08/31 02:53:57 guenther Exp $ */
 3+/* $openbsd: memmem.c,v 1.4 2015/08/31 02:53:57 guenther exp $ */
 4 
 5 /*
 6- * Copyright (c) 2005 Pascal Gloor <pascal.gloor@spale.com>
 7+ * copyright (c) 2005 pascal gloor <pascal.gloor@spale.com>
 8  *
 9- * Redistribution and use in source and binary forms, with or without
10+ * redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13- * 1. Redistributions of source code must retain the above copyright
14- *    notice, this list of conditions and the following disclaimer.
15- * 2. Redistributions in binary form must reproduce the above copyright
16- *    notice, this list of conditions and the following disclaimer in the
17- *    documentation and/or other materials provided with the distribution.
18- * 3. The name of the author may not be used to endorse or promote
19- *    products derived from this software without specific prior written
20- *    permission.
21+ * 1. redistributions of source code must retain the above copyright
22+ * notice, this list of conditions and the following disclaimer
23+ * 2. redistributions in binary form must reproduce the above copyright
24+ * notice, this list of conditions and the following disclaimer in the
25+ * documentation and/or other materials provided with the distribution
26+ * 3. the name of the author may not be used to endorse or promote
27+ * products derived from this software without specific prior written
28+ * permission
29  *
30  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
31  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
34+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
35+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
36  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
40  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
41  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42- * SUCH DAMAGE.
43+ * SUCH DAMAGE
44  */
45 
46 #include <string.h>
47@@ -33,7 +33,7 @@
48 #include "../util.h"
49 
50 /*
51- * Find the first occurrence of the byte string s in byte string l.
52+ * find the first occurrence of the byte string s in byte string l
53  */
54 
55 void *
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <sys/stat.h>
5 
6 #include <errno.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <stdlib.h>
5 #include <string.h>
6 #include <sys/stat.h>
+4, -1
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 #include <ctype.h>
 5 #include <errno.h>
 6 #include <inttypes.h>
 7@@ -45,6 +45,9 @@ parseoffset(const char *str)
 8       case 'G':
 9         scale = 1024L * 1024L * 1024L;
10         break;
11+      case 'T':
12+        scale = 1024L * 1024L * 1024L * 1024L;
13+        break;
14       default:
15         weprintf("parseoffset %s: invalid suffix '%s'\n", str, end);
16         return -1;
+18, -2
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 #include "../passwd.h"
 5 #include "../paths.h"
 6 #include "../text.h"
 7@@ -78,6 +78,17 @@ pw_check(const struct passwd *pw, const char *pass)
 8       weprintf("denied\n");
 9       return -1;
10     }
11+    /* same empty-hash fast path as above, re-checked here: stored was
12+     * just reassigned from the shadow entry's own field, and an empty
13+     * shadow hash means "passwordless account", not "match nothing"
14+     * (falling through to crypt() with an empty salt does the latter,
15+     * since crypt("", "") is never itself the empty string) */
16+    if (stored[0] == '\0') {
17+      if (pass[0] == '\0')
18+        return 1;
19+      weprintf("incorrect password\n");
20+      return 0;
21+    }
22   }
23 #endif
24 
25@@ -260,7 +271,12 @@ update_shadow(const char *name, const char *newhash)
26     return -1;
27   }
28 
29-  while ((spw = getspent())) {
30+  /* fgetspent(fp) reads from the stream we already opened above;
31+ * getspent() reads an implicit global shadow stream that musl
32+ * never actually backs with this (or any) file and always
33+ * returns null for, silently turning every update into a
34+ * "no matching entry" failure */
35+  while ((spw = fgetspent(fp))) {
36     cur = *spw;
37     if (strcmp(cur.sp_namp, name) == 0) {
38       cur.sp_pwdp = (char *)newhash;
+2, -2
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 #include <sys/stat.h>
 5 
 6 #include <errno.h>
 7@@ -85,7 +85,7 @@ parsestat(pid_t pid, struct procstat *ps)
 8       &ps->rss,
 9       &ps->rsslim
10   );
11-  /* Filter out '(' and ')' from comm */
12+  /* filter out '(' and ')' from comm */
13   if ((len = strlen(ps->comm)) > 0)
14     len--;
15   ps->comm[len] = '\0';
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <stdio.h>
5 
6 #include "../util.h"
+5, -5
 1@@ -1,9 +1,9 @@
 2 /*
 3- * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
 4+ * copyright (c) 2008 otto moerbeek <otto@drijf.net>
 5  *
 6- * Permission to use, copy, modify, and distribute this software for any
 7+ * permission to use, copy, modify, and distribute this software for any
 8  * purpose with or without fee is hereby granted, provided that the above
 9- * copyright notice and this permission notice appear in all copies.
10+ * copyright notice and this permission notice appear in all copies
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14@@ -11,7 +11,7 @@
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE
20  */
21 
22 #include <errno.h>
23@@ -22,7 +22,7 @@
24 #include "../util.h"
25 
26 /*
27- * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
28+ * this is sqrt(size_max+1), as s1*s2 <= SIZE_MAX
29  * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
30  */
31 #define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4))
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <dirent.h>
5 #include <errno.h>
6 #include <fcntl.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <dirent.h>
5 #include <limits.h>
6 #include <stdio.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <sys/stat.h>
5 
6 #include <errno.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include "../sig.h"
5 
6 #include <signal.h>
+9, -9
 1@@ -1,24 +1,24 @@
 2 /*
 3- * Copyright 2005-2014 Rich Felker, et al.
 4+ * copyright 2005-2014 rich felker, et al
 5  *
 6- * Permission is hereby granted, free of charge, to any person obtaining
 7+ * permission is hereby granted, free of charge, to any person obtaining
 8  * a copy of this software and associated documentation files (the
 9- * "Software"), to deal in the Software without restriction, including
10+ * "software"), to deal in the software without restriction, including
11  * without limitation the rights to use, copy, modify, merge, publish,
12- * distribute, sublicense, and/or sell copies of the Software, and to
13- * permit persons to whom the Software is furnished to do so, subject to
14+ * distribute, sublicense, and/or sell copies of the software, and to
15+ * permit persons to whom the software is furnished to do so, subject to
16  * the following conditions:
17  *
18- * The above copyright notice and this permission notice shall be
19- * included in all copies or substantial portions of the Software.
20+ * the above copyright notice and this permission notice shall be
21+ * included in all copies or substantial portions of the software
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26+ * MERCHANTABILITY, FITNESS FOR a PARTICULAR PURPOSE AND NONINFRINGEMENT
27  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
28  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
32  */
33 #include <string.h>
34 #include <strings.h>
+10, -10
 1@@ -1,9 +1,9 @@
 2 /*
 3- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
 4+ * copyright (c) 1998 todd c. miller <todd.miller@courtesan.com>
 5  *
 6- * Permission to use, copy, modify, and distribute this software for any
 7+ * permission to use, copy, modify, and distribute this software for any
 8  * purpose with or without fee is hereby granted, provided that the above
 9- * copyright notice and this permission notice appear in all copies.
10+ * copyright notice and this permission notice appear in all copies
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14@@ -11,7 +11,7 @@
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE
20  */
21 
22 #include <string.h>
23@@ -20,11 +20,11 @@
24 #include "../util.h"
25 
26 /*
27- * Appends src to string dst of size siz (unlike strncat, siz is the
28- * full size of dst, not space left). At most siz-1 characters
29- * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
30- * Returns strlen(src) + MIN(siz, strlen(initial dst)).
31- * If retval >= siz, truncation occurred.
32+ * appends src to string dst of size siz (unlike strncat, siz is the
33+ * full size of dst, not space left). at most siz-1 characters
34+ * will be copied. always NUL terminates (unless siz <= strlen(dst))
35+ * returns strlen(src) + min(siz, strlen(initial dst))
36+ * if retval >= siz, truncation occurred
37  */
38 size_t
39 strlcat(char *dst, const char *src, size_t siz)
40@@ -33,7 +33,7 @@ strlcat(char *dst, const char *src, size_t siz)
41   const char *s = src;
42   size_t      n = siz;
43   size_t      dlen;
44-  /* Find the end of dst and adjust bytes left but don't go past end */
45+  /* find the end of dst and adjust bytes left but dont go past end */
46   while (n-- != 0 && *d != '\0')
47     d++;
48   dlen = d - dst;
+10, -10
 1@@ -1,9 +1,9 @@
 2 /*
 3- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
 4+ * copyright (c) 1998 todd c. miller <todd.miller@courtesan.com>
 5  *
 6- * Permission to use, copy, modify, and distribute this software for any
 7+ * permission to use, copy, modify, and distribute this software for any
 8  * purpose with or without fee is hereby granted, provided that the above
 9- * copyright notice and this permission notice appear in all copies.
10+ * copyright notice and this permission notice appear in all copies
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14@@ -11,7 +11,7 @@
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE
20  */
21 
22 #include <string.h>
23@@ -20,9 +20,9 @@
24 #include "../util.h"
25 
26 /*
27- * Copy src to string dst of size siz. At most siz-1 characters
28- * will be copied. Always NUL terminates (unless siz == 0).
29- * Returns strlen(src); if retval >= siz, truncation occurred.
30+ * copy src to string dst of size siz. at most siz-1 characters
31+ * will be copied. always NUL terminates (unless siz == 0)
32+ * returns strlen(src); if retval >= siz, truncation occurred
33  */
34 size_t
35 strlcpy(char *dst, const char *src, size_t siz)
36@@ -30,17 +30,17 @@ strlcpy(char *dst, const char *src, size_t siz)
37   char       *d = dst;
38   const char *s = src;
39   size_t      n = siz;
40-  /* Copy as many bytes as will fit */
41+  /* copy as many bytes as will fit */
42   if (n != 0) {
43     while (--n != 0) {
44       if ((*d++ = *s++) == '\0')
45         break;
46     }
47   }
48-  /* Not enough room in dst, add NUL and traverse rest of src */
49+  /* not enough room in dst, add NUL and traverse rest of src */
50   if (n == 0) {
51     if (siz != 0)
52-      *d = '\0'; /* NUL-terminate dst */
53+      *d = '\0'; /* nul-terminate dst */
54     while (*s++)
55       ;
56   }
+9, -9
 1@@ -1,9 +1,9 @@
 2 /*
 3- * Copyright (c) 2002 J. Mallett.  All rights reserved.
 4- * You may do whatever you want with this file as long as
 5+ * copyright (c) 2002 j. mallett. all rights reserved
 6+ * you may do whatever you want with this file as long as
 7  * the above copyright and this notice remain intact, along
 8  * with the following statement:
 9- * 	For the man who taught me vi, and who got too old, too young.
10+ * for the man who taught me vi, and who got too old, too young
11  */
12 
13 #include <stdio.h>
14@@ -13,14 +13,14 @@
15 #include "../util.h"
16 
17 /*
18- * Replaces str with a string consisting of str with match replaced with
19+ * replaces str with a string consisting of str with match replaced with
20  * replstr as many times as can be done before the constructed string is
21- * maxsize bytes large.  It does not free the string pointed to by str, it
22+ * maxsize bytes large. it does not free the string pointed to by str, it
23  * is up to the calling program to be sure that the original contents of
24- * str as well as the new contents are handled in an appropriate manner.
25- * If replstr is NULL, then that internally is changed to a nil-string, so
26- * that we can still pretend to do somewhat meaningful substitution.
27- * No value is returned.
28+ * str as well as the new contents are handled in an appropriate manner
29+ * if replstr is NULL, then that internally is changed to a nil-string, so
30+ * that we can still pretend to do somewhat meaningful substitution
31+ * no value is returned
32  */
33 void
34 strnsubst(char **str, const char *match, const char *replstr, size_t maxsize)
+9, -9
 1@@ -1,24 +1,24 @@
 2 /*
 3- * Copyright 2005-2014 Rich Felker, et al.
 4+ * copyright 2005-2014 rich felker, et al
 5  *
 6- * Permission is hereby granted, free of charge, to any person obtaining
 7+ * permission is hereby granted, free of charge, to any person obtaining
 8  * a copy of this software and associated documentation files (the
 9- * "Software"), to deal in the Software without restriction, including
10+ * "software"), to deal in the software without restriction, including
11  * without limitation the rights to use, copy, modify, merge, publish,
12- * distribute, sublicense, and/or sell copies of the Software, and to
13- * permit persons to whom the Software is furnished to do so, subject to
14+ * distribute, sublicense, and/or sell copies of the software, and to
15+ * permit persons to whom the software is furnished to do so, subject to
16  * the following conditions:
17  *
18- * The above copyright notice and this permission notice shall be
19- * included in all copies or substantial portions of the Software.
20+ * the above copyright notice and this permission notice shall be
21+ * included in all copies or substantial portions of the software
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26+ * MERCHANTABILITY, FITNESS FOR a PARTICULAR PURPOSE AND NONINFRINGEMENT
27  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
28  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
32  */
33 #include <string.h>
34 
+6, -6
 1@@ -1,12 +1,12 @@
 2-/*	$OpenBSD: strtonum.c,v 1.7 2013/04/17 18:40:58 tedu Exp $	*/
 3+/* $openbsd: strtonum.c,v 1.7 2013/04/17 18:40:58 tedu exp $ */
 4 
 5 /*
 6- * Copyright (c) 2004 Ted Unangst and Todd Miller
 7- * All rights reserved.
 8+ * copyright (c) 2004 ted unangst and todd miller
 9+ * all rights reserved
10  *
11- * Permission to use, copy, modify, and distribute this software for any
12+ * permission to use, copy, modify, and distribute this software for any
13  * purpose with or without fee is hereby granted, provided that the above
14- * copyright notice and this permission notice appear in all copies.
15+ * copyright notice and this permission notice appear in all copies
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
18  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
19@@ -14,7 +14,7 @@
20  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
22  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
23- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE
25  */
26 
27 #include <errno.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <sys/stat.h>
5 #include <sys/sysmacros.h>
6 #include <sys/types.h>
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <ctype.h>
5 #include <string.h>
6 
+8, -5
 1@@ -1,4 +1,4 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 #include "../wexec.h"
 5 #include "../config.h"
 6 #include "../paths.h"
 7@@ -199,7 +199,7 @@ wwhich(const char *name)
 8 
 9   path = wexec_getenv("PATH");
10   if (path == NULL)
11-    path = "/usr/local/bin:/usr/bin:/bin";
12+    path = ARUU_PATH_DEFPATH;
13 
14   nlen = strlen(name);
15   p    = path;
16@@ -327,7 +327,8 @@ fork_exec(const char *path, char *const *argv, int use_path)
17       execvp(path, argv);
18     else
19       execv(path, argv);
20-    _exit(127);
21+    weprintf(use_path ? "execvp %s:" : "execv %s:", path);
22+    _exit((errno == ENOENT) ? 127 : 126);
23   }
24   if (waitpid(pid, &st, 0) < 0) {
25     weprintf("waitpid:");
26@@ -435,7 +436,8 @@ wpopen(const char *name, char *const *argv, const char *mode)
27       }
28 #endif
29       execvp(name, argv);
30-      _exit(127);
31+      weprintf("execvp %s:", name);
32+      _exit((errno == ENOENT) ? 127 : 126);
33     } else {
34       sh_argv[0] = "sh";
35       sh_argv[1] = "-c";
36@@ -462,7 +464,8 @@ wpopen(const char *name, char *const *argv, const char *mode)
37       }
38 #endif
39       execvp("sh", sh_argv);
40-      _exit(127);
41+      weprintf("execvp sh:");
42+      _exit((errno == ENOENT) ? 127 : 126);
43     }
44   }
45 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #include <unistd.h>
5 
6 #include "../util.h"
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #ifndef ARUU_PASSWD_H
5 #define ARUU_PASSWD_H
6 
+12, -6
 1@@ -1,12 +1,12 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4 #ifndef ARUU_PATHS_H
 5 #define ARUU_PATHS_H
 6 
 7 /*
 8- * portable paths. override at compile time for non-FHS systems:
 9- *   -DARUU_PATH_ETC="/config"
10+ * portable paths. override at compile time for non-fhs systems:
11+ * -daruu_path_etc="/config"
12  *
13- * OS-specific paths (procfs, sysfs) are prefixed ARUU_LINUX_PATH_*
14+ * os-specific paths (procfs, sysfs) are prefixed ARUU_LINUX_PATH_*
15  * and only defined under __linux__. a util that reads /proc/modules
16  * will fail to compile on BSD because ARUU_LINUX_PATH_PROC is not
17  * defined there. this is intentional: the BSD code path must use
18@@ -62,8 +62,14 @@
19 #define ARUU_PATH_BTMP       ARUU_PATH_VAR "/log/btmp"
20 #define ARUU_PATH_LASTLOG    ARUU_PATH_VAR "/log/lastlog"
21 #define ARUU_PATH_BSHELL     ARUU_PATH_BIN "/sh"
22-#define ARUU_PATH_STDPATH    ARUU_PATH_BIN ":/usr/bin"
23-#define ARUU_PATH_DEFPATH    ARUU_PATH_BIN ":/usr/bin"
24+
25+#ifndef ARUU_PATH_STDPATH
26+#define ARUU_PATH_STDPATH ARUU_PATH_BIN ":" ARUU_PATH_USR_BIN
27+#endif
28+
29+#ifndef ARUU_PATH_DEFPATH
30+#define ARUU_PATH_DEFPATH ARUU_PATH_BIN ":" ARUU_PATH_USR_BIN
31+#endif
32 
33 #if defined(__linux__)
34 #define ARUU_LINUX_PATH_PROC            "/proc"
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 struct procstat {
5   int                pid;
6   char               comm[PATH_MAX + 2]; /* + 2 for '(' and ')' */
+63, -63
  1@@ -1,85 +1,85 @@
  2-/*	$OpenBSD: queue.h,v 1.38 2013/07/03 15:05:21 fgsch Exp $	*/
  3-/*	$NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $	*/
  4+/* $openbsd: queue.h,v 1.38 2013/07/03 15:05:21 fgsch exp $ */
  5+/* $netbsd: queue.h,v 1.11 1996/05/16 05:17:14 mycroft exp $ */
  6 
  7 /*
  8- * Copyright (c) 1991, 1993
  9- *	The Regents of the University of California.  All rights reserved.
 10+ * copyright (c) 1991, 1993
 11+ * the regents of the university of california. all rights reserved
 12  *
 13- * Redistribution and use in source and binary forms, with or without
 14+ * redistribution and use in source and binary forms, with or without
 15  * modification, are permitted provided that the following conditions
 16  * are met:
 17- * 1. Redistributions of source code must retain the above copyright
 18- *    notice, this list of conditions and the following disclaimer.
 19- * 2. Redistributions in binary form must reproduce the above copyright
 20- *    notice, this list of conditions and the following disclaimer in the
 21- *    documentation and/or other materials provided with the distribution.
 22- * 3. Neither the name of the University nor the names of its contributors
 23- *    may be used to endorse or promote products derived from this software
 24- *    without specific prior written permission.
 25+ * 1. redistributions of source code must retain the above copyright
 26+ * notice, this list of conditions and the following disclaimer
 27+ * 2. redistributions in binary form must reproduce the above copyright
 28+ * notice, this list of conditions and the following disclaimer in the
 29+ * documentation and/or other materials provided with the distribution
 30+ * 3. neither the name of the university nor the names of its contributors
 31+ * may be used to endorse or promote products derived from this software
 32+ * without specific prior written permission
 33  *
 34  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 35  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 36- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 37- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 38+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR a PARTICULAR PURPOSE
 39+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 40  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 41  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 42  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 43  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 44  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 45  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 46- * SUCH DAMAGE.
 47+ * SUCH DAMAGE
 48  *
 49- *	@(#)queue.h	8.5 (Berkeley) 8/20/94
 50+ * @(#)queue.h 8.5 (berkeley) 8/20/94
 51  */
 52 
 53 #ifndef _SYS_QUEUE_H_
 54 #define _SYS_QUEUE_H_
 55 
 56 /*
 57- * This file defines five types of data structures: singly-linked lists,
 58- * lists, simple queues, tail queues, and circular queues.
 59+ * this file defines five types of data structures: singly-linked lists,
 60+ * lists, simple queues, tail queues, and circular queues
 61  *
 62  *
 63- * A singly-linked list is headed by a single forward pointer. The elements
 64+ * a singly-linked list is headed by a single forward pointer. the elements
 65  * are singly linked for minimum space and pointer manipulation overhead at
 66- * the expense of O(n) removal for arbitrary elements. New elements can be
 67- * added to the list after an existing element or at the head of the list.
 68- * Elements being removed from the head of the list should use the explicit
 69- * macro for this purpose for optimum efficiency. A singly-linked list may
 70- * only be traversed in the forward direction.  Singly-linked lists are ideal
 71+ * the expense of o(n) removal for arbitrary elements. new elements can be
 72+ * added to the list after an existing element or at the head of the list
 73+ * elements being removed from the head of the list should use the explicit
 74+ * macro for this purpose for optimum efficiency. a singly-linked list may
 75+ * only be traversed in the forward direction. singly-linked lists are ideal
 76  * for applications with large datasets and few or no removals or for
 77- * implementing a LIFO queue.
 78+ * implementing a LIFO queue
 79  *
 80- * A list is headed by a single forward pointer (or an array of forward
 81- * pointers for a hash table header). The elements are doubly linked
 82+ * a list is headed by a single forward pointer (or an array of forward
 83+ * pointers for a hash table header). the elements are doubly linked
 84  * so that an arbitrary element can be removed without a need to
 85- * traverse the list. New elements can be added to the list before
 86- * or after an existing element or at the head of the list. A list
 87- * may only be traversed in the forward direction.
 88+ * traverse the list. new elements can be added to the list before
 89+ * or after an existing element or at the head of the list. a list
 90+ * may only be traversed in the forward direction
 91  *
 92- * A simple queue is headed by a pair of pointers, one the head of the
 93- * list and the other to the tail of the list. The elements are singly
 94+ * a simple queue is headed by a pair of pointers, one the head of the
 95+ * list and the other to the tail of the list. the elements are singly
 96  * linked to save space, so elements can only be removed from the
 97- * head of the list. New elements can be added to the list before or after
 98+ * head of the list. new elements can be added to the list before or after
 99  * an existing element, at the head of the list, or at the end of the
100- * list. A simple queue may only be traversed in the forward direction.
101+ * list. a simple queue may only be traversed in the forward direction
102  *
103- * A tail queue is headed by a pair of pointers, one to the head of the
104- * list and the other to the tail of the list. The elements are doubly
105+ * a tail queue is headed by a pair of pointers, one to the head of the
106+ * list and the other to the tail of the list. the elements are doubly
107  * linked so that an arbitrary element can be removed without a need to
108- * traverse the list. New elements can be added to the list before or
109+ * traverse the list. new elements can be added to the list before or
110  * after an existing element, at the head of the list, or at the end of
111- * the list. A tail queue may be traversed in either direction.
112+ * the list. a tail queue may be traversed in either direction
113  *
114- * A circle queue is headed by a pair of pointers, one to the head of the
115- * list and the other to the tail of the list. The elements are doubly
116+ * a circle queue is headed by a pair of pointers, one to the head of the
117+ * list and the other to the tail of the list. the elements are doubly
118  * linked so that an arbitrary element can be removed without a need to
119- * traverse the list. New elements can be added to the list before or after
120- * an existing element, at the head of the list, or at the end of the list.
121- * A circle queue may be traversed in either direction, but has a more
122- * complex end of list detection.
123+ * traverse the list. new elements can be added to the list before or after
124+ * an existing element, at the head of the list, or at the end of the list
125+ * a circle queue may be traversed in either direction, but has a more
126+ * complex end of list detection
127  *
128- * For details on the use of these macros, see the queue(3) manual page.
129+ * for details on the use of these macros, see the queue(3) manual page
130  */
131 
132 #if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
133@@ -89,7 +89,7 @@
134 #endif
135 
136 /*
137- * Singly-linked List definitions.
138+ * singly-linked list definitions
139  */
140 #define SLIST_HEAD(name, type)                                                                     \
141   struct name {                                                                                    \
142@@ -104,7 +104,7 @@
143   }
144 
145 /*
146- * Singly-linked List access methods.
147+ * singly-linked list access methods
148  */
149 #define SLIST_FIRST(head)      ((head)->slh_first)
150 #define SLIST_END(head)        NULL
151@@ -118,7 +118,7 @@
152   for ((var) = SLIST_FIRST(head); (var) && ((tvar) = SLIST_NEXT(var, field), 1); (var) = (tvar))
153 
154 /*
155- * Singly-linked List functions.
156+ * singly-linked list functions
157  */
158 #define SLIST_INIT(head)                                                                           \
159   {                                                                                                \
160@@ -162,7 +162,7 @@
161   } while (0)
162 
163 /*
164- * List definitions.
165+ * list definitions
166  */
167 #define LIST_HEAD(name, type)                                                                      \
168   struct name {                                                                                    \
169@@ -178,7 +178,7 @@
170   }
171 
172 /*
173- * List access methods
174+ * list access methods
175  */
176 #define LIST_FIRST(head)      ((head)->lh_first)
177 #define LIST_END(head)        NULL
178@@ -192,7 +192,7 @@
179   for ((var) = LIST_FIRST(head); (var) && ((tvar) = LIST_NEXT(var, field), 1); (var) = (tvar))
180 
181 /*
182- * List functions.
183+ * list functions
184  */
185 #define LIST_INIT(head)                                                                            \
186   do {                                                                                             \
187@@ -243,7 +243,7 @@
188   } while (0)
189 
190 /*
191- * Simple queue definitions.
192+ * simple queue definitions
193  */
194 #define SIMPLEQ_HEAD(name, type)                                                                   \
195   struct name {                                                                                    \
196@@ -259,7 +259,7 @@
197   }
198 
199 /*
200- * Simple queue access methods.
201+ * simple queue access methods
202  */
203 #define SIMPLEQ_FIRST(head)      ((head)->sqh_first)
204 #define SIMPLEQ_END(head)        NULL
205@@ -273,7 +273,7 @@
206   for ((var) = SIMPLEQ_FIRST(head); (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); (var) = (tvar))
207 
208 /*
209- * Simple queue functions.
210+ * simple queue functions
211  */
212 #define SIMPLEQ_INIT(head)                                                                         \
213   do {                                                                                             \
214@@ -315,7 +315,7 @@
215   } while (0)
216 
217 /*
218- * XOR Simple queue definitions.
219+ * XOR simple queue definitions
220  */
221 #define XSIMPLEQ_HEAD(name, type)                                                                  \
222   struct name {                                                                                    \
223@@ -330,7 +330,7 @@
224   }
225 
226 /*
227- * XOR Simple queue access methods.
228+ * XOR simple queue access methods
229  */
230 #define XSIMPLEQ_XOR(head, ptr)         ((__typeof(ptr))((head)->sqx_cookie ^ (unsigned long)(ptr)))
231 #define XSIMPLEQ_FIRST(head)            XSIMPLEQ_XOR(head, ((head)->sqx_first))
232@@ -347,7 +347,7 @@
233        (var) = (tvar))
234 
235 /*
236- * XOR Simple queue functions.
237+ * XOR simple queue functions
238  */
239 #define XSIMPLEQ_INIT(head)                                                                        \
240   do {                                                                                             \
241@@ -392,7 +392,7 @@
242   } while (0)
243 
244 /*
245- * Tail queue definitions.
246+ * tail queue definitions
247  */
248 #define TAILQ_HEAD(name, type)                                                                     \
249   struct name {                                                                                    \
250@@ -437,7 +437,7 @@
251        (var) = (tvar))
252 
253 /*
254- * Tail queue functions.
255+ * tail queue functions
256  */
257 #define TAILQ_INIT(head)                                                                           \
258   do {                                                                                             \
259@@ -505,7 +505,7 @@
260   } while (0)
261 
262 /*
263- * Circular queue definitions.
264+ * circular queue definitions
265  */
266 #define CIRCLEQ_HEAD(name, type)                                                                   \
267   struct name {                                                                                    \
268@@ -522,7 +522,7 @@
269   }
270 
271 /*
272- * Circular queue access methods
273+ * circular queue access methods
274  */
275 #define CIRCLEQ_FIRST(head)      ((head)->cqh_first)
276 #define CIRCLEQ_LAST(head)       ((head)->cqh_last)
277@@ -548,7 +548,7 @@
278        (var) = (tvar))
279 
280 /*
281- * Circular queue functions.
282+ * circular queue functions
283  */
284 #define CIRCLEQ_INIT(head)                                                                         \
285   do {                                                                                             \
+10, -10
 1@@ -1,5 +1,5 @@
 2 /*
 3- * Magic values required to use _reboot() system call.
 4+ * magic values required to use _reboot() system call
 5  */
 6 
 7 #define LINUX_REBOOT_MAGIC1  0xfee1dead
 8@@ -9,16 +9,16 @@
 9 #define LINUX_REBOOT_MAGIC2C 537993216
10 
11 /*
12- * Commands accepted by the _reboot() system call.
13+ * commands accepted by the _reboot() system call
14  *
15- * RESTART     Restart system using default command and mode.
16- * HALT        Stop OS and give system control to ROM monitor, if any.
17- * CAD_ON      Ctrl-Alt-Del sequence causes RESTART command.
18- * CAD_OFF     Ctrl-Alt-Del sequence sends SIGINT to init task.
19- * POWER_OFF   Stop OS and remove all power from system, if possible.
20- * RESTART2    Restart system using given command string.
21- * SW_SUSPEND  Suspend system using software suspend if compiled in.
22- * KEXEC       Restart system using a previously loaded Linux kernel
23+ * RESTART restart system using default command and mode
24+ * HALT stop OS and give system control to ROM monitor, if any
25+ * CAD_ON ctrl-alt-del sequence causes RESTART command
26+ * CAD_OFF ctrl-alt-del sequence sends SIGINT to init task
27+ * POWER_OFF stop OS and remove all power from system, if possible
28+ * RESTART2 restart system using given command string
29+ * SW_SUSPEND suspend system using software suspend if compiled in
30+ * KEXEC restart system using a previously loaded linux kernel
31  */
32 
33 #define LINUX_REBOOT_CMD_RESTART    0x01234567
+4, -4
 1@@ -1,7 +1,7 @@
 2 /*
 3- * The struct used to pass data via the following ioctl. Similar to the
 4+ * the struct used to pass data via the following ioctl. similar to the
 5  * struct tm in <time.h>, but it needs to be here so that the kernel
 6- * source is self contained, allowing cross-compiles, etc. etc.
 7+ * source is self contained, allowing cross-compiles, etc. etc
 8  */
 9 
10 struct rtc_time {
11@@ -16,5 +16,5 @@ struct rtc_time {
12   int tm_isdst;
13 };
14 
15-#define RTC_RD_TIME  _IOR('p', 0x09, struct rtc_time) /* Read RTC time   */
16-#define RTC_SET_TIME _IOW('p', 0x0a, struct rtc_time) /* Set RTC time    */
17+#define RTC_RD_TIME  _IOR('p', 0x09, struct rtc_time) /* read RTC time */
18+#define RTC_SET_TIME _IOW('p', 0x0a, struct rtc_time) /* set RTC time */
+1, -1
1@@ -3,7 +3,7 @@
2 #include "sha256.h"
3 #include <stdint.h>
4 
5-#define sha224 sha256 /*struct*/
6+#define sha224 sha256 /* struct */
7 
8 enum { SHA224_DIGEST_LENGTH = 28 };
9 
+1, -1
1@@ -3,7 +3,7 @@
2 #include "sha512.h"
3 #include <stdint.h>
4 
5-#define sha384 sha512 /*struct*/
6+#define sha384 sha512 /* struct */
7 
8 enum { SHA384_DIGEST_LENGTH = 48 };
9 
+1, -1
1@@ -3,7 +3,7 @@
2 #include "sha512.h"
3 #include <stdint.h>
4 
5-#define sha512_224 sha512 /*struct*/
6+#define sha512_224 sha512 /* struct */
7 
8 enum { SHA512_224_DIGEST_LENGTH = 28 };
9 
+1, -1
1@@ -3,7 +3,7 @@
2 #include "sha512.h"
3 #include <stdint.h>
4 
5-#define sha512_256 sha512 /*struct*/
6+#define sha512_256 sha512 /* struct */
7 
8 enum { SHA512_256_DIGEST_LENGTH = 32 };
9 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #ifndef SIG_H_
5 #define SIG_H_
6 
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 
5 #include <stddef.h>
6 #include <stdio.h>
+2, -2
 1@@ -7,8 +7,8 @@
 2 struct TlsSocket;
 3 
 4 /* tls_connect takes an already connected socket fd and upgrades it to tls
 5-   if check_cert is 0 certificate validation is bypassed
 6-   returns a new tls socket or null on error */
 7+ * if check_cert is 0 certificate validation is bypassed
 8+ * returns a new tls socket or null on error */
 9 struct TlsSocket *tlss_connect(int fd, const char *host, int check_cert, int is_tls);
10 
11 /* standard read and write wrapping either libtls, bearssl or plain fallback */
+10, -10
 1@@ -1,22 +1,22 @@
 2-/* MIT/X Consortium Copyright (c) 2012 Connor Lane Smith <cls@lubutu.com>
 3+/* MIT/X consortium copyright (c) 2012 connor lane smith <cls@lubutu.com>
 4  *
 5- * Permission is hereby granted, free of charge, to any person obtaining a
 6- * copy of this software and associated documentation files (the "Software"),
 7- * to deal in the Software without restriction, including without limitation
 8+ * permission is hereby granted, free of charge, to any person obtaining a
 9+ * copy of this software and associated documentation files (the "software"),
10+ * to deal in the software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12- * and/or sell copies of the Software, and to permit persons to whom the
13- * Software is furnished to do so, subject to the following conditions:
14+ * and/or sell copies of the software, and to permit persons to whom the
15+ * software is furnished to do so, subject to the following conditions:
16  *
17- * The above copyright notice and this permission notice shall be included in
18- * all copies or substantial portions of the Software.
19+ * the above copyright notice and this permission notice shall be included in
20+ * all copies or substantial portions of the software
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
25+ * FITNESS FOR a PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29- * DEALINGS IN THE SOFTWARE.
30+ * DEALINGS IN THE SOFTWARE
31  */
32 #include <stdio.h>
33 
+7, -1
 1@@ -1,4 +1,7 @@
 2-/* See LICENSE file for copyright and license details. */
 3+/* see LICENSE file for copyright and license details */
 4+#ifndef UTIL_H
 5+#define UTIL_H
 6+
 7 #include <sys/types.h>
 8 
 9 #include <regex.h>
10@@ -82,6 +85,7 @@ int     concat(int, const char *, int, const char *);
11 void   enmasse(int, char **, int (*)(const char *, const char *, int));
12 void   fnck(const char *, const char *, int (*)(const char *, const char *, int), int);
13 mode_t getumask(void);
14+int    hexval(int);
15 char  *humansize(off_t);
16 mode_t parsemode(const char *, mode_t, mode_t);
17 off_t  parseoffset(const char *);
18@@ -176,3 +180,5 @@ int net_set_name(const char *, const char *);
19 #define exit(code)  wexec_exit(code)
20 #define _exit(code) wexec_exit(code)
21 #endif
22+
23+#endif
+1, -1
1@@ -1,4 +1,4 @@
2-/* See LICENSE file for copyright and license details. */
3+/* see LICENSE file for copyright and license details */
4 #ifndef ARUU_WEXEC_H
5 #define ARUU_WEXEC_H
6