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
M
Makefile
+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
M
Makefile
+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,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
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,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,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,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,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,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,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>
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
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+
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
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@@ -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;
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+}
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 */
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 */
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 */
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+}
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 */
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+}
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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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;
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
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,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,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,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,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,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,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,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,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,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,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,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"
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,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,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,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,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,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,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,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,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,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"
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,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@@ -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,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,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
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,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,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>
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;
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;
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,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"
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,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,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,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,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>
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>
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;
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 }
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)
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
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,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,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
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,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,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
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,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 ')' */
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 { \
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
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@@ -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@@ -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@@ -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@@ -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,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,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>
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 */
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
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,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