Module Name: othersrc
Committed By: dyoung
Date: Fri Sep 11 01:50:43 UTC 2015
Modified Files:
othersrc/external/bsd/arfe: Makefile
othersrc/external/bsd/arfe/dt: Makefile README dt.c dt.h hex.c hex.h
ipv4.c ipv4.h testit
othersrc/external/bsd/arfe/dt/rr: if-re0-if-wm0 if-wm0-if-re0
ifconfig.0-ifconfig.1 ifconfig.0-logger-ifconfig.0
ifconfig.1-ifconfig.0 logger-ifconfig.0-ifconfig.0 wm0-a-wm0-b
wm0-b-wm0-a
othersrc/external/bsd/arfe/it: Makefile README
Added Files:
othersrc/external/bsd/arfe/dt: macaddr.c macaddr.h
othersrc/external/bsd/arfe/tt: .cvsignore Makefile README testit.sh
Log Message:
Add a new tool, tt, that transforms its input based on the transform
exemplified by a match/transform-template pair.
Add a data detector for MAC addresses. Update expected test outputs.
To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 othersrc/external/bsd/arfe/Makefile
cvs rdiff -u -r1.3 -r1.4 othersrc/external/bsd/arfe/dt/Makefile
cvs rdiff -u -r1.5 -r1.6 othersrc/external/bsd/arfe/dt/README
cvs rdiff -u -r1.9 -r1.10 othersrc/external/bsd/arfe/dt/dt.c
cvs rdiff -u -r1.1 -r1.2 othersrc/external/bsd/arfe/dt/dt.h \
othersrc/external/bsd/arfe/dt/hex.c othersrc/external/bsd/arfe/dt/hex.h \
othersrc/external/bsd/arfe/dt/ipv4.c othersrc/external/bsd/arfe/dt/ipv4.h
cvs rdiff -u -r0 -r1.1 othersrc/external/bsd/arfe/dt/macaddr.c \
othersrc/external/bsd/arfe/dt/macaddr.h
cvs rdiff -u -r1.2 -r1.3 othersrc/external/bsd/arfe/dt/testit
cvs rdiff -u -r1.3 -r1.4 othersrc/external/bsd/arfe/dt/rr/if-re0-if-wm0 \
othersrc/external/bsd/arfe/dt/rr/if-wm0-if-re0
cvs rdiff -u -r1.4 -r1.5 \
othersrc/external/bsd/arfe/dt/rr/ifconfig.0-ifconfig.1 \
othersrc/external/bsd/arfe/dt/rr/ifconfig.0-logger-ifconfig.0 \
othersrc/external/bsd/arfe/dt/rr/ifconfig.1-ifconfig.0 \
othersrc/external/bsd/arfe/dt/rr/logger-ifconfig.0-ifconfig.0 \
othersrc/external/bsd/arfe/dt/rr/wm0-a-wm0-b \
othersrc/external/bsd/arfe/dt/rr/wm0-b-wm0-a
cvs rdiff -u -r1.2 -r1.3 othersrc/external/bsd/arfe/it/Makefile
cvs rdiff -u -r1.3 -r1.4 othersrc/external/bsd/arfe/it/README
cvs rdiff -u -r0 -r1.1 othersrc/external/bsd/arfe/tt/.cvsignore \
othersrc/external/bsd/arfe/tt/Makefile \
othersrc/external/bsd/arfe/tt/README \
othersrc/external/bsd/arfe/tt/testit.sh
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: othersrc/external/bsd/arfe/Makefile
diff -u othersrc/external/bsd/arfe/Makefile:1.1 othersrc/external/bsd/arfe/Makefile:1.2
--- othersrc/external/bsd/arfe/Makefile:1.1 Mon Aug 10 21:10:59 2015
+++ othersrc/external/bsd/arfe/Makefile Fri Sep 11 01:50:42 2015
@@ -1,5 +1,5 @@
.include <bsd.own.mk>
-SUBDIR=dt it
+SUBDIR=dt it tt
.include <bsd.subdir.mk>
Index: othersrc/external/bsd/arfe/dt/Makefile
diff -u othersrc/external/bsd/arfe/dt/Makefile:1.3 othersrc/external/bsd/arfe/dt/Makefile:1.4
--- othersrc/external/bsd/arfe/dt/Makefile:1.3 Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/dt/Makefile Fri Sep 11 01:50:42 2015
@@ -1,9 +1,9 @@
-# $ARFE: Makefile 231 2015-09-02 22:31:30Z dyoung $
+# $ARFE: Makefile 239 2015-09-10 22:49:40Z dyoung $
NOMAN=
.include <bsd.own.mk>
PROG=dt
-SRCS+=dt.c hex.c ipv4.c
+SRCS+=dt.c hex.c ipv4.c macaddr.c
#CPPFLAGS+=-DHB_DEBUG
CPPFLAGS+=-DHB_ASSERT
DBG+=-g -O3
Index: othersrc/external/bsd/arfe/dt/README
diff -u othersrc/external/bsd/arfe/dt/README:1.5 othersrc/external/bsd/arfe/dt/README:1.6
--- othersrc/external/bsd/arfe/dt/README:1.5 Wed Sep 2 22:45:47 2015
+++ othersrc/external/bsd/arfe/dt/README Fri Sep 11 01:50:42 2015
@@ -1,5 +1,5 @@
-$ARFE: README 235 2015-09-02 22:44:54Z dyoung $
-$NetBSD: README,v 1.5 2015/09/02 22:45:47 dyoung Exp $
+$ARFE: README 236 2015-09-02 22:47:33Z dyoung $
+$NetBSD: README,v 1.6 2015/09/11 01:50:42 dyoung Exp $
DT---(d)ifferentiate (t)ext---finds a longest common subsequence (LCS)
of two texts where the numbers and IPv4 addresses are "wild": a span
Index: othersrc/external/bsd/arfe/dt/dt.c
diff -u othersrc/external/bsd/arfe/dt/dt.c:1.9 othersrc/external/bsd/arfe/dt/dt.c:1.10
--- othersrc/external/bsd/arfe/dt/dt.c:1.9 Wed Sep 2 22:45:47 2015
+++ othersrc/external/bsd/arfe/dt/dt.c Fri Sep 11 01:50:42 2015
@@ -1,5 +1,5 @@
-/* $NetBSD: dt.c,v 1.9 2015/09/02 22:45:47 dyoung Exp $ */
-/* $ARFE: dt.c 235 2015-09-02 22:44:54Z dyoung $ */
+/* $NetBSD: dt.c,v 1.10 2015/09/11 01:50:42 dyoung Exp $ */
+/* $ARFE: dt.c 239 2015-09-10 22:49:40Z dyoung $ */
/*-
* Copyright (c) 2014,2015 David Young <[email protected]>
@@ -51,6 +51,7 @@
#include "dt.h"
#include "hex.h"
#include "ipv4.h"
+#include "macaddr.h"
#if defined(HB_ASSERT)
#define dbg_assert assert
@@ -63,19 +64,6 @@ typedef struct origin {
int j;
} origin_t;
-typedef struct chainelt {
- TAILQ_ENTRY(chainelt) ce_link;
- int ce_column; /* 0: no column alignment,
- * -x: starts at column x (1 = first column)
- * x: ends at column x (1 = first column)
- */
- char *ce_content;
-} chainelt_t;
-
-typedef struct chain {
- TAILQ_HEAD(chainhead, chainelt) c_head;
-} chain_t;
-
typedef struct slice {
const char *first;
const char *last;
@@ -88,6 +76,7 @@ typedef enum {
, KIND_INTMAX_HEX
, KIND_INTMAX_0xHEX
, KIND_IPv4
+ , KIND_MACADDR
, KIND_STRING
} clocc_kind_t;
@@ -96,6 +85,9 @@ typedef enum {
, QUAL_ALLCAPS
} clocc_qual_t;
+struct chainelt;
+typedef struct chainelt chainelt_t;
+
typedef struct clocc {
int column;
int first;
@@ -106,12 +98,44 @@ typedef struct clocc {
intmax_t u_intmax;
uintmax_t u_uintmax;
uint32_t u_ipv4;
+ uint8_t u_macaddr[6];
} val_u;
+ TAILQ_ENTRY(clocc) bucket;
+ chainelt_t *match;
} clocc_t;
+struct chainelt {
+ TAILQ_ENTRY(chainelt) ce_link;
+ int ce_column; /* 0: no column alignment,
+ * -x: starts at column x (1 = first column)
+ * x: ends at column x (1 = first column)
+ */
+ char *ce_content;
+ int ce_match_idx;
+};
+
+typedef struct chain {
+ TAILQ_HEAD(chainhead, chainelt) c_head;
+} chain_t;
+
+TAILQ_HEAD(clocc_bucket, clocc);
+
+typedef struct clocc_bucket clocc_bucket_t;
+
+enum {
+ MATCH_TBL_IDX = 0
+ , TRANSFORM_TBL_IDX = 1
+ , NTBL = 2
+};
+
+typedef struct clocc_htbl {
+ clocc_bucket_t bucket[1024];
+} clocc_htbl_t;
+
typedef struct cloccs {
int noccs;
clocc_t occs[1024];
+ clocc_htbl_t htbl;
} cloccs_t;
typedef struct scratch {
@@ -122,8 +146,18 @@ typedef struct scratch {
cloccs_t Aoccs, Boccs;
slice_t *Abasis, *Bbasis;
size_t expected_lcs;
- char dec_op;
- char hex_op;
+ char ipv4_op; /* 'p' for prefix (smallest containing subnet),
+ * 'l' for copy left argument
+ */
+ char macaddr_op;/* 'p' for prefix (leading octets in common),
+ * 'l' for copy left argument
+ */
+ char dec_op; /* '+' or '-' for add or subtract, 'l' for copy left
+ * argument
+ */
+ char hex_op; /* '&' or '|' for bitwise-AND and -OR, 'l' for copy
+ * left argument
+ */
} scratch_t;
union freeslice;
@@ -390,7 +424,7 @@ clocc_ends_in_slice_at(const cloccs_t *o
}
static chain_t *
-newchain(char *content, int column)
+newchain_with_match_idx(char *content, int column, int midx)
{
chain_t *c;
chainelt_t *ce;
@@ -403,12 +437,19 @@ newchain(char *content, int column)
ce->ce_column = column;
ce->ce_content = content;
+ ce->ce_match_idx = midx;
TAILQ_INIT(&c->c_head);
TAILQ_INSERT_TAIL(&c->c_head, ce, ce_link);
return c;
}
+static chain_t *
+newchain(char *content, int column)
+{
+ return newchain_with_match_idx(content, column, -1);
+}
+
/* Return 0 if the `a' and `b' are not left- or right-aligned on
* the same column, the column they right-align on, or zero minus
* the column they left-align on.
@@ -425,24 +466,117 @@ cloccs_to_column(const clocc_t * const a
return 0;
}
+static unsigned int
+clocc_hash(const slice_t *s, const clocc_t *c)
+{
+ unsigned int hash;
+ int i;
+
+ assert(c->last >= c->first);
+
+ for (hash = c->kind, i = c->first; i <= c->last; i++) {
+ if (((hash << 1) >> 1) != hash) {
+ hash <<= 1;
+ hash |= 0x1;
+ } else
+ hash <<= 1;
+
+ hash ^= get(s, i);
+ }
+
+ return hash;
+}
+
+/* Look up the class occurrence `occ` on slice `s` in the class occurrences
+ * `occs` occurring on slice `os`.
+ */
+static clocc_t *
+clocc_cross_lookup(cloccs_t *occs, const slice_t *os, const slice_t *s,
+ clocc_t *occ)
+{
+ clocc_htbl_t *tbl = &occs->htbl;
+ unsigned int hash = clocc_hash(s, occ);
+ clocc_bucket_t *bkt = &tbl->bucket[hash % __arraycount(tbl->bucket)];
+ clocc_t *bocc;
+ int i, n;
+
+ TAILQ_FOREACH(bocc, bkt, bucket) {
+ assert(bocc->first <= bocc->last);
+ if (bocc->last - bocc->first != occ->last - occ->first)
+ continue;
+ n = bocc->last - bocc->first + 1;
+ for (i = 0; i < n; i++) {
+ if (get(os, bocc->first + i) != get(s, occ->first + i))
+ break;
+ }
+ if (i == n)
+ return bocc;
+ }
+ return NULL;
+}
+
+static chain_t *
+mac_clocc(const scratch_t *scratch, int idx_a, int idx_b)
+{
+ int column, i, rc;
+ char *buf;
+ uint8_t combo[6];
+ const clocc_t * const a = &scratch->Aoccs.occs[idx_a],
+ * const b = &scratch->Boccs.occs[idx_b];
+
+ column = cloccs_to_column(a, b);
+
+ switch (scratch->macaddr_op) {
+ case 'p':
+ for (i = 0; i < 6; i++) {
+ uint8_t l, r;
+ l = a->val_u.u_macaddr[i];
+ r = b->val_u.u_macaddr[i];
+ combo[i] = (l == r) ? l : 0;
+ }
+ break;
+ default:
+ case 'l':
+ memcpy(combo, a->val_u.u_macaddr, sizeof(combo));
+ break;
+ }
+
+ rc = asprintf(&buf, "%02" PRIx8 ":%02" PRIx8 ":%02" PRIx8 ":"
+ "%02" PRIx8 ":%02" PRIx8 ":%02" PRIx8,
+ combo[0], combo[1], combo[2], combo[3], combo[4], combo[5]);
+
+ if (rc != -1)
+ return newchain_with_match_idx(buf, column, idx_b);
+
+ return newchain_with_match_idx(strdup("<macaddr>"), column, idx_b);
+}
+
static chain_t *
ipv4_clocc(const scratch_t *scratch, int idx_a, int idx_b)
{
int column;
char *erasep, *ret;
- uint32_t combo, mask;
+ uint32_t combo, mask, discrepancies;
const clocc_t * const a = &scratch->Aoccs.occs[idx_a],
* const b = &scratch->Boccs.occs[idx_b];
- char buf[sizeof("255.255.255.255")];
+ char buf[sizeof("255.255.255.255/32 ")];
column = cloccs_to_column(a, b);
- for (mask = 0xffffffff;
- ((b->val_u.u_ipv4 ^ a->val_u.u_ipv4) & mask) != 0;
- mask &= (mask - 1))
+ switch (scratch->ipv4_op) {
+ case 'p':
+ discrepancies = b->val_u.u_ipv4 ^ a->val_u.u_ipv4;
+ break;
+ default:
+ case 'l':
+ discrepancies = 0;
+ break;
+ }
+
+ for (mask = 0xffffffff; (discrepancies & mask) != 0; mask &= (mask - 1))
; // do nothing
- combo = htonl(b->val_u.u_ipv4 & mask);
+ combo = htonl(a->val_u.u_ipv4 & mask);
ret = inet_net_ntop(AF_INET, &combo, 32, buf, sizeof(buf));
@@ -450,9 +584,9 @@ ipv4_clocc(const scratch_t *scratch, int
*erasep = '\0';
if (ret != NULL)
- return newchain(strdup(buf), column);
+ return newchain_with_match_idx(strdup(buf), column, idx_b);
- return newchain(strdup("<ipv4>"), column);
+ return newchain_with_match_idx(strdup("<ipv4>"), column, idx_b);
}
static chain_t *
@@ -471,13 +605,21 @@ hex_clocc(const scratch_t *scratch, int
a->val_u.u_uintmax, a->column,
b->val_u.u_uintmax, b->column, column);
- if (scratch->hex_op == '&')
+ switch (scratch->hex_op) {
+ case '&':
result = b->val_u.u_uintmax & a->val_u.u_uintmax;
- else
+ break;
+ case '|':
result = b->val_u.u_uintmax | a->val_u.u_uintmax;
+ break;
+ case 'l':
+ default:
+ result = a->val_u.u_uintmax;
+ break;
+ }
if (result == 0 && kind == KIND_INTMAX_0xHEX)
- return newchain(strdup("0x0"), column);
+ return newchain_with_match_idx(strdup("0x0"), column, idx_b);
if (qual == QUAL_ALLCAPS) {
rc = asprintf(&buf,
@@ -486,11 +628,11 @@ hex_clocc(const scratch_t *scratch, int
rc = asprintf(&buf,
(kind == KIND_INTMAX_0xHEX) ? "0x%jx" : "%jx", result);
}
-
+
if (rc != -1)
- return newchain(buf, column);
+ return newchain_with_match_idx(buf, column, idx_b);
- return newchain(strdup("<hexmax>"), column);
+ return newchain_with_match_idx(strdup("<hexmax>"), column, idx_b);
}
static chain_t *
@@ -508,15 +650,23 @@ int_clocc(const scratch_t *scratch, int
a->val_u.u_intmax, a->column,
b->val_u.u_intmax, b->column, column);
- if (scratch->dec_op == '-')
+ switch (scratch->dec_op) {
+ case '-':
result = b->val_u.u_intmax - a->val_u.u_intmax;
- else
+ break;
+ case '+':
result = b->val_u.u_intmax + a->val_u.u_intmax;
+ break;
+ case 'l':
+ default:
+ result = a->val_u.u_intmax;
+ break;
+ }
if (asprintf(&ret, "%jd", result) != -1)
- return newchain(ret, column);
+ return newchain_with_match_idx(ret, column, idx_b);
- return newchain(strdup("<intmax>"), column);
+ return newchain_with_match_idx(strdup("<intmax>"), column, idx_b);
}
static chain_t *
@@ -526,7 +676,7 @@ clocc(const scratch_t *scratch, int idx_
* const b = &scratch->Boccs.occs[idx_b];
if (a->kind != b->kind)
- return newchain(strdup("<clocc>"), 0);
+ return newchain(strdup("<clocc*>"), 0);
if (b->kind == KIND_INTMAX_0xHEX || b->kind == KIND_INTMAX_HEX) {
return hex_clocc(scratch, idx_a, idx_b, b->kind,
@@ -539,7 +689,13 @@ clocc(const scratch_t *scratch, int idx_
if (b->kind == KIND_IPv4)
return ipv4_clocc(scratch, idx_a, idx_b);
- return newchain(strdup("<word>"), 0);
+ if (b->kind == KIND_MACADDR)
+ return mac_clocc(scratch, idx_a, idx_b);
+
+ if (b->kind == KIND_STRING)
+ return newchain(strdup("<word>"), 0);
+
+ return newchain(strdup("<clocc>"), 0);
}
static chain_t *
@@ -781,7 +937,8 @@ joinchains(chain_t *ac, chain_t *bc)
ace = TAILQ_LAST(&ac->c_head, chainhead);
bce = TAILQ_FIRST(&bc->c_head);
- if (ace->ce_column == 0 && bce->ce_column == 0) {
+ if (ace->ce_column == 0 && bce->ce_column == 0 &&
+ ace->ce_match_idx == -1 && bce->ce_match_idx == -1) {
char *c, *c1, *c2;
c1 = ace->ce_content;
c2 = bce->ce_content;
@@ -996,6 +1153,41 @@ slicestr(const slice_t *s, const char *t
}
static void
+emit_mac_clocc(mac_detection_t *d, void *arg)
+{
+ cloccs_t *o = arg;
+ uint8_t addr[6];
+ int rc;
+
+ dbg_printf("found mac string %s @ [%d, %d]\n", d->d_string,
+ d->d_idx.start, d->d_idx.stop);
+
+ if (o->noccs >= (int)__arraycount(o->occs))
+ return;
+
+ rc = sscanf(d->d_string,
+ "%" SCNx8 ":%" SCNx8 ":%" SCNx8 ":%" SCNx8 ":%" SCNx8 ":%" SCNx8 "",
+ &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]);
+
+ assert(rc == 6);
+
+ dbg_printf("converted ipv4 string %s @ [%d, %d] -> "
+ "%02" PRIx8 ":%02" PRIx8 ":%02" PRIx8 ":"
+ "%02" PRIx8 ":%02" PRIx8 ":%02" PRIx8 "\n",
+ d->d_string, d->d_idx.start, d->d_idx.stop,
+ addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+
+ o->occs[o->noccs].column = d->d_column.start;
+ o->occs[o->noccs].first = d->d_idx.start;
+ o->occs[o->noccs].last = d->d_idx.stop;
+ o->occs[o->noccs].kind = KIND_MACADDR;
+ o->occs[o->noccs].qual = QUAL_NONE;
+ memcpy(&o->occs[o->noccs].val_u.u_macaddr[0], &addr[0],
+ sizeof(o->occs[o->noccs].val_u.u_macaddr));
+ o->noccs++;
+}
+
+static void
emit_ipv4_clocc(ipv4_detection_t *d, void *arg)
{
cloccs_t *o = arg;
@@ -1099,15 +1291,43 @@ cloccs_dedup(cloccs_t *o)
}
static void
+clocc_htbl_init(clocc_htbl_t *tbl)
+{
+ int i;
+
+ for (i = 0; i < (int)__arraycount(tbl->bucket); i++)
+ TAILQ_INIT(&tbl->bucket[i]);
+}
+
+static void
+clocc_htbl_insert(clocc_htbl_t *tbl, const slice_t *s, clocc_t *occ)
+{
+ int i = clocc_hash(s, occ) % __arraycount(tbl->bucket);
+ TAILQ_INSERT_HEAD(&tbl->bucket[i], occ, bucket);
+}
+
+static void
+cloccs_hash(cloccs_t *o, const slice_t *s)
+{
+ int i;
+
+ for (i = 0; i < o->noccs; i++)
+ clocc_htbl_insert(&o->htbl, s, &o->occs[i]);
+}
+
+static void
cloccs_init(cloccs_t *o, const slice_t *s)
{
hex_parser_t *hex_parser;
ipv4_parser_t *ipv4_parser;
+ mac_parser_t *mac_parser;
size_t column, i;
size_t n = length(s);
unsigned int j, k;
char digits[64 / 3 + 1]; /* XXX how many digits in an intmax_t? */
+ clocc_htbl_init(&o->htbl);
+
o->noccs = 0;
for (i = 0; i < __arraycount(names); i++) {
int loc;
@@ -1124,6 +1344,25 @@ cloccs_init(cloccs_t *o, const slice_t *
o->noccs++;
}
+ mac_parser = mac_parser_alloc(emit_mac_clocc, o);
+ if (mac_parser == NULL)
+ goto parse_ipv4;
+
+ column = 0;
+ for (j = 0; j < n; j++) {
+ char c;
+
+ c = get(s, j);
+ ++column;
+ mac_parser_drive(mac_parser, j, column, c);
+ if (c == '\n')
+ column = 0;
+ }
+ mac_parser_drive(mac_parser, n, column + 1, -1);
+
+ mac_parser_free(mac_parser);
+
+parse_ipv4:
ipv4_parser = ipv4_parser_alloc(emit_ipv4_clocc, o);
if (ipv4_parser == NULL)
goto parse_hexadecimal;
@@ -1247,39 +1486,112 @@ printchain(chain_t *c)
}
}
+static void
+emit_transformed_text(chain_t *O, cloccs_t *Moccs, cloccs_t *Toccs,
+ const slice_t *match, const slice_t *transform)
+{
+ chainelt_t *ce;
+ int i, next;
+
+ TAILQ_FOREACH(ce, &O->c_head, ce_link) {
+ clocc_t *occ = &Moccs->occs[ce->ce_match_idx];
+
+ if (ce->ce_match_idx == -1)
+ continue;
+
+ if (occ->match == NULL)
+ occ->match = ce;
+ }
+
+ for (next = i = 0; i < Toccs->noccs; i++) {
+ clocc_t *Tocc = &Toccs->occs[i];
+ clocc_t *Mocc = clocc_cross_lookup(Moccs, match, transform,
+ Tocc);
+
+ for (; next < Tocc->first; next++) {
+ char c = get(transform, next);
+ fputc(c, stdout); // XXX check error
+ }
+
+ if (Mocc != NULL && Mocc->match != NULL) {
+ fprintf(stdout, "%s", Mocc->match->ce_content);
+ next = Tocc->last + 1;
+ } else
+ next = Tocc->first;
+ }
+
+ for (; next < (int)length(transform); next++) {
+ char c = get(transform, next);
+ fputc(c, stdout); // XXX check error
+ }
+}
+
int
main(int argc, char **argv)
{
- slice_t *A, *B;
+ slice_t *left, *match, *transform;
size_t n;
- chain_t *C;
+ chain_t *O;
scratch_t scratch;
+ size_t lcs;
+ bool dotransform = false;
+ cloccs_t Toccs;
setprogname(argv[0]);
- if (argc < 3)
+ if (strcmp(getprogname(), "tt") == 0)
+ dotransform = true;
+
+ switch (argc) {
+ case 4:
+ if (!dotransform)
+ usage();
+ /*FALLTHROUGH*/
+ case 3:
+ break;
+ default:
usage();
+ break;
+ }
+
+ left = file_to_slice(argv[1]);
+ match = file_to_slice(argv[2]);
- A = file_to_slice(argv[1]);
- B = file_to_slice(argv[2]);
- n = length(B);
- scratch_init(&scratch, n, A, B);
- if (strcmp(getprogname(), "dt") == 0) {
+ n = length(match);
+ scratch_init(&scratch, n, left, match);
+ cloccs_init(&scratch.Aoccs, left);
+ cloccs_init(&scratch.Boccs, match);
+ cloccs_hash(&scratch.Boccs, match);
+
+ if (dotransform) {
+ scratch.macaddr_op = 'l';
+ scratch.ipv4_op = 'l';
+ scratch.dec_op = 'l';
+ scratch.hex_op = 'l';
+ transform = file_to_slice(argv[3]);
+ cloccs_init(&Toccs, transform);
+ } else if (strcmp(getprogname(), "dt") == 0) {
+ scratch.macaddr_op = 'p';
+ scratch.ipv4_op = 'p';
scratch.dec_op = '-';
scratch.hex_op = '&';
} else if (strcmp(getprogname(), "it") == 0) {
+ scratch.macaddr_op = 'p';
+ scratch.ipv4_op = 'p';
scratch.dec_op = '+';
scratch.hex_op = '|';
} else
errx(EXIT_FAILURE, "not implemented");
- cloccs_init(&scratch.Aoccs, A);
- cloccs_init(&scratch.Boccs, B);
- size_t lcs;
- C = algc(A, B, &scratch, (origin_t){0, 0}, no_expected_lcs, &lcs);
+ O = algc(left, match, &scratch, (origin_t){0, 0}, no_expected_lcs,
+ &lcs);
dbg_printf("lcs = %zu\n", lcs);
- printchain(C);
+ if (dotransform) {
+ emit_transformed_text(O, &scratch.Boccs, &Toccs, match,
+ transform);
+ } else
+ printchain(O);
dbg_printf("\n");
return EXIT_SUCCESS;
Index: othersrc/external/bsd/arfe/dt/dt.h
diff -u othersrc/external/bsd/arfe/dt/dt.h:1.1 othersrc/external/bsd/arfe/dt/dt.h:1.2
--- othersrc/external/bsd/arfe/dt/dt.h:1.1 Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/dt/dt.h Fri Sep 11 01:50:42 2015
@@ -1,5 +1,5 @@
-/* $NetBSD: dt.h,v 1.1 2015/09/02 22:43:17 dyoung Exp $ */
-/* $ARFE$ */
+/* $NetBSD: dt.h,v 1.2 2015/09/11 01:50:42 dyoung Exp $ */
+/* $ARFE: dt.h 237 2015-09-02 22:48:04Z dyoung $ */
/*-
* Copyright (c) 2014,2015 David Young <[email protected]>
Index: othersrc/external/bsd/arfe/dt/hex.c
diff -u othersrc/external/bsd/arfe/dt/hex.c:1.1 othersrc/external/bsd/arfe/dt/hex.c:1.2
--- othersrc/external/bsd/arfe/dt/hex.c:1.1 Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/dt/hex.c Fri Sep 11 01:50:42 2015
@@ -1,5 +1,5 @@
-/* $NetBSD: hex.c,v 1.1 2015/09/02 22:43:17 dyoung Exp $ */
-/* $ARFE$ */
+/* $NetBSD: hex.c,v 1.2 2015/09/11 01:50:42 dyoung Exp $ */
+/* $ARFE: hex.c 236 2015-09-02 22:47:33Z dyoung $ */
/*-
* Copyright (c) 2014,2015 David Young <[email protected]>
Index: othersrc/external/bsd/arfe/dt/hex.h
diff -u othersrc/external/bsd/arfe/dt/hex.h:1.1 othersrc/external/bsd/arfe/dt/hex.h:1.2
--- othersrc/external/bsd/arfe/dt/hex.h:1.1 Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/dt/hex.h Fri Sep 11 01:50:42 2015
@@ -1,5 +1,5 @@
-/* $NetBSD: hex.h,v 1.1 2015/09/02 22:43:17 dyoung Exp $ */
-/* $ARFE$ */
+/* $NetBSD: hex.h,v 1.2 2015/09/11 01:50:42 dyoung Exp $ */
+/* $ARFE: hex.h 236 2015-09-02 22:47:33Z dyoung $ */
/*-
* Copyright (c) 2014,2015 David Young <[email protected]>
Index: othersrc/external/bsd/arfe/dt/ipv4.c
diff -u othersrc/external/bsd/arfe/dt/ipv4.c:1.1 othersrc/external/bsd/arfe/dt/ipv4.c:1.2
--- othersrc/external/bsd/arfe/dt/ipv4.c:1.1 Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/dt/ipv4.c Fri Sep 11 01:50:42 2015
@@ -1,5 +1,5 @@
-/* $NetBSD: ipv4.c,v 1.1 2015/09/02 22:43:17 dyoung Exp $ */
-/* $ARFE$ */
+/* $NetBSD: ipv4.c,v 1.2 2015/09/11 01:50:42 dyoung Exp $ */
+/* $ARFE: ipv4.c 238 2015-09-10 20:16:07Z dyoung $ */
/*-
* Copyright (c) 2014,2015 David Young <[email protected]>
@@ -91,8 +91,6 @@ enum ipv4_state_idxs {
, READ_250_255
, READ_3_9
, SECOND_NUMBER
- , THIRD_NUMBER = FIRST_NUMBER + (SECOND_NUMBER - FIRST_NUMBER) * 2
- , FOURTH_NUMBER = FIRST_NUMBER + (SECOND_NUMBER - FIRST_NUMBER) * 3
};
__CTASSERT(SECOND_NUMBER > FIRST_NUMBER)
Index: othersrc/external/bsd/arfe/dt/ipv4.h
diff -u othersrc/external/bsd/arfe/dt/ipv4.h:1.1 othersrc/external/bsd/arfe/dt/ipv4.h:1.2
--- othersrc/external/bsd/arfe/dt/ipv4.h:1.1 Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/dt/ipv4.h Fri Sep 11 01:50:42 2015
@@ -1,5 +1,5 @@
-/* $NetBSD: ipv4.h,v 1.1 2015/09/02 22:43:17 dyoung Exp $ */
-/* $ARFE$ */
+/* $NetBSD: ipv4.h,v 1.2 2015/09/11 01:50:42 dyoung Exp $ */
+/* $ARFE: ipv4.h 236 2015-09-02 22:47:33Z dyoung $ */
/*-
* Copyright (c) 2014,2015 David Young <[email protected]>
Index: othersrc/external/bsd/arfe/dt/testit
diff -u othersrc/external/bsd/arfe/dt/testit:1.2 othersrc/external/bsd/arfe/dt/testit:1.3
--- othersrc/external/bsd/arfe/dt/testit:1.2 Sat Aug 22 05:08:48 2015
+++ othersrc/external/bsd/arfe/dt/testit Fri Sep 11 01:50:42 2015
@@ -1,5 +1,7 @@
#!/bin/sh
-# $ARFE: testit 216 2015-08-22 05:04:28Z dyoung $
+# $ARFE: testit 239 2015-09-10 22:49:40Z dyoung $
+
+DT=${OBJDIR:-.}/dt
results=rr
@@ -9,10 +11,10 @@ while read l r ; do
o=${results}/${l}-${r}
if [ -e $o ]; then
echo diffing $l $r 1>&2
- ./dt t/$l t/$r | diff $o -
+ ${DT} t/$l t/$r | diff $o -
else
echo generating $l $r 1>&2
- ./dt t/$l t/$r > $o
+ ${DT} t/$l t/$r > $o
fi
done <<EOF
netstat-s.0 netstat-s.1
Index: othersrc/external/bsd/arfe/dt/rr/if-re0-if-wm0
diff -u othersrc/external/bsd/arfe/dt/rr/if-re0-if-wm0:1.3 othersrc/external/bsd/arfe/dt/rr/if-re0-if-wm0:1.4
--- othersrc/external/bsd/arfe/dt/rr/if-re0-if-wm0:1.3 Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/dt/rr/if-re0-if-wm0 Fri Sep 11 01:50:43 2015
@@ -1,7 +1,7 @@
0: flags= 0<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 0
capabilities=3f80<TSO0,IP0CSUM_Rx,IP0CSUM_Tx,TCP0CSUM_Rx,TCP0CSUM_Tx,UDP0CSUM_Rx,UDP0CSUM_Tx>
enabled=3f80<TSO0,IP0CSUM_Rx,IP0CSUM_Tx,TCP0CSUM_Rx,TCP0CSUM_Tx,UDP0CSUM_Rx,UDP0CSUM_Tx>
- address: 0:-25:c:0: a0:80
+ address: 00:00:00:00:00:00
media: Ethernet autoselect (e)
status: aie
inet 0.0.0.0 netmask 0xff000000 broadcast 0.0.0.0
Index: othersrc/external/bsd/arfe/dt/rr/if-wm0-if-re0
diff -u othersrc/external/bsd/arfe/dt/rr/if-wm0-if-re0:1.3 othersrc/external/bsd/arfe/dt/rr/if-wm0-if-re0:1.4
--- othersrc/external/bsd/arfe/dt/rr/if-wm0-if-re0:1.3 Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/dt/rr/if-wm0-if-re0 Fri Sep 11 01:50:43 2015
@@ -1,7 +1,7 @@
0: flags= 0<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 0
capabilities=3f80<TSO0,IP0CSUM_Rx,IP0CSUM_Tx,TCP0CSUM_Rx,TCP0CSUM_Tx,UDP0CSUM_Rx,UDP-2CSUM_Tx>
enabled=3f80<TSO0,IP0CSUM_Rx,IP0CSUM_Tx,TCP0CSUM_Rx,TCP0CSUM_Tx,UDP0CSUM_Rx,UDP-2CSUM_Tx>
- address: 0:25: c:0: a0:80
+ address: 00:00:00:00:00:00
media: Ethernet autoselect (e)
status: cie
inet 0.0.0.0 netmask 0xff000000 broadcast 0.0.0.0
Index: othersrc/external/bsd/arfe/dt/rr/ifconfig.0-ifconfig.1
diff -u othersrc/external/bsd/arfe/dt/rr/ifconfig.0-ifconfig.1:1.4 othersrc/external/bsd/arfe/dt/rr/ifconfig.0-ifconfig.1:1.5
--- othersrc/external/bsd/arfe/dt/rr/ifconfig.0-ifconfig.1:1.4 Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/dt/rr/ifconfig.0-ifconfig.1 Fri Sep 11 01:50:43 2015
@@ -1,7 +1,7 @@
wm0: flags= 0<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 0
capabilities=2bf80<TSO0,IP0CSUM_Rx,IP0CSUM_Tx,TCP0CSUM_Rx,TCP0CSUM_Tx,UDP0CSUM_Rx,UDP0CSUM_Tx,TCP0CSUM_Tx,UDP0CSUM_Tx>
enabled=2bf80<TSO0,IP0CSUM_Rx,IP0CSUM_Tx,TCP0CSUM_Rx,TCP0CSUM_Tx,UDP0CSUM_Rx,UDP0CSUM_Tx,TCP0CSUM_Tx,UDP0CSUM_Tx>
- address: 0: a: b:cd: 0:ef
+ address: 00:0a:0b:cd:01:ef
media: Ethernet autoselect ( 0baseT full-duplex)
status: active
input: 61 packets, 5432 bytes, 3 multicasts
Index: othersrc/external/bsd/arfe/dt/rr/ifconfig.0-logger-ifconfig.0
diff -u othersrc/external/bsd/arfe/dt/rr/ifconfig.0-logger-ifconfig.0:1.4 othersrc/external/bsd/arfe/dt/rr/ifconfig.0-logger-ifconfig.0:1.5
--- othersrc/external/bsd/arfe/dt/rr/ifconfig.0-logger-ifconfig.0:1.4 Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/dt/rr/ifconfig.0-logger-ifconfig.0 Fri Sep 11 01:50:43 2015
@@ -1,7 +1,7 @@
wm0: flags=0<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 0
capabilities=2bf80<TSO0,IP0CSUM_Rx,IP0CSUM_Tx,TCP0CSUM_Rx,TCP0CSUM_Tx,UDP0CSUM_Rx,UDP0CSUM_Tx,TCP0CSUM_Tx,UDP0CSUM_Tx>
enabled=2bf80<TSO0,IP0CSUM_Rx,IP0CSUM_Tx,TCP0CSUM_Rx,TCP0CSUM_Tx,UDP0CSUM_Rx,UDP0CSUM_Tx,TCP0CSUM_Tx,UDP0CSUM_Tx>
-address: 0:a:b:cd:0:ef
+address: 00:0a:0b:cd:01:ef
media: Ethernet autoselect (0baseT full-duplex)
status: active
input: 0 packets, 0 bytes, 0 multicasts
Index: othersrc/external/bsd/arfe/dt/rr/ifconfig.1-ifconfig.0
diff -u othersrc/external/bsd/arfe/dt/rr/ifconfig.1-ifconfig.0:1.4 othersrc/external/bsd/arfe/dt/rr/ifconfig.1-ifconfig.0:1.5
--- othersrc/external/bsd/arfe/dt/rr/ifconfig.1-ifconfig.0:1.4 Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/dt/rr/ifconfig.1-ifconfig.0 Fri Sep 11 01:50:43 2015
@@ -1,7 +1,7 @@
wm0: flags= 0<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 0
capabilities=2bf80<TSO0,IP0CSUM_Rx,IP0CSUM_Tx,TCP0CSUM_Rx,TCP0CSUM_Tx,UDP0CSUM_Rx,UDP0CSUM_Tx,TCP0CSUM_Tx,UDP0CSUM_Tx>
enabled=2bf80<TSO0,IP0CSUM_Rx,IP0CSUM_Tx,TCP0CSUM_Rx,TCP0CSUM_Tx,UDP0CSUM_Rx,UDP0CSUM_Tx,TCP0CSUM_Tx,UDP0CSUM_Tx>
- address: 0: a: b:cd: 0:ef
+ address: 00:0a:0b:cd:01:ef
media: Ethernet autoselect ( 0baseT full-duplex)
status: active
input: -61 packets, -5432 bytes, -3 multicasts
Index: othersrc/external/bsd/arfe/dt/rr/logger-ifconfig.0-ifconfig.0
diff -u othersrc/external/bsd/arfe/dt/rr/logger-ifconfig.0-ifconfig.0:1.4 othersrc/external/bsd/arfe/dt/rr/logger-ifconfig.0-ifconfig.0:1.5
--- othersrc/external/bsd/arfe/dt/rr/logger-ifconfig.0-ifconfig.0:1.4 Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/dt/rr/logger-ifconfig.0-ifconfig.0 Fri Sep 11 01:50:43 2015
@@ -1,7 +1,7 @@
wm0: flags=0<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 0
capabilities=2bf80<TSO0,IP0CSUM_Rx,IP0CSUM_Tx,TCP0CSUM_Rx,TCP0CSUM_Tx,UDP0CSUM_Rx,UDP0CSUM_Tx,TCP0CSUM_Tx,UDP0CSUM_Tx>
enabled=2bf80<TSO0,IP0CSUM_Rx,IP0CSUM_Tx,TCP0CSUM_Rx,TCP0CSUM_Tx,UDP0CSUM_Rx,UDP0CSUM_Tx,TCP0CSUM_Tx,UDP0CSUM_Tx>
-address: 0:a:b:cd:0:ef
+address: 00:0a:0b:cd:01:ef
media: Ethernet autoselect (0baseT full-duplex)
status: active
input: 0 packets, 0 bytes, 0 multicasts
Index: othersrc/external/bsd/arfe/dt/rr/wm0-a-wm0-b
diff -u othersrc/external/bsd/arfe/dt/rr/wm0-a-wm0-b:1.4 othersrc/external/bsd/arfe/dt/rr/wm0-a-wm0-b:1.5
--- othersrc/external/bsd/arfe/dt/rr/wm0-a-wm0-b:1.4 Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/dt/rr/wm0-a-wm0-b Fri Sep 11 01:50:43 2015
@@ -1,7 +1,7 @@
wm0: flags= 0<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 0
capabilities=2bf80<TSO0,IP0CSUM_Rx,IP0CSUM_Tx,TCP0CSUM_Rx,TCP0CSUM_Tx,UDP0CSUM_Rx,UDP0CSUM_Tx,TCP0CSUM_Tx,UDP0CSUM_Tx>
enabled=2bf80<TSO0,IP0CSUM_Rx,IP0CSUM_Tx,TCP0CSUM_Rx,TCP0CSUM_Tx,UDP0CSUM_Rx,UDP0CSUM_Tx,TCP0CSUM_Tx,UDP0CSUM_Tx>
- address: 0: a: b:cd: 0:ef
+ address: 00:0a:0b:cd:01:ef
media: Ethernet autoselect ( 0baseT full-duplex)
status: active
input: 112 packets, 11380 bytes, 11 multicasts
Index: othersrc/external/bsd/arfe/dt/rr/wm0-b-wm0-a
diff -u othersrc/external/bsd/arfe/dt/rr/wm0-b-wm0-a:1.4 othersrc/external/bsd/arfe/dt/rr/wm0-b-wm0-a:1.5
--- othersrc/external/bsd/arfe/dt/rr/wm0-b-wm0-a:1.4 Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/dt/rr/wm0-b-wm0-a Fri Sep 11 01:50:43 2015
@@ -1,7 +1,7 @@
wm0: flags= 0<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 0
capabilities=2bf80<TSO0,IP0CSUM_Rx,IP0CSUM_Tx,TCP0CSUM_Rx,TCP0CSUM_Tx,UDP0CSUM_Rx,UDP0CSUM_Tx,TCP0CSUM_Tx,UDP0CSUM_Tx>
enabled=2bf80<TSO0,IP0CSUM_Rx,IP0CSUM_Tx,TCP0CSUM_Rx,TCP0CSUM_Tx,UDP0CSUM_Rx,UDP0CSUM_Tx,TCP0CSUM_Tx,UDP0CSUM_Tx>
- address: 0: a: b:cd: 0:ef
+ address: 00:0a:0b:cd:01:ef
media: Ethernet autoselect ( 0baseT full-duplex)
status: active
input: -112 packets, -11380 bytes, -11 multicasts
Index: othersrc/external/bsd/arfe/it/Makefile
diff -u othersrc/external/bsd/arfe/it/Makefile:1.2 othersrc/external/bsd/arfe/it/Makefile:1.3
--- othersrc/external/bsd/arfe/it/Makefile:1.2 Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/it/Makefile Fri Sep 11 01:50:43 2015
@@ -2,7 +2,7 @@ NOMAN=
.include <bsd.own.mk>
PROG=it
-SRCS+=dt.c hex.c ipv4.c
+SRCS+=dt.c hex.c ipv4.c macaddr.c
#CPPFLAGS+=-DHB_DEBUG
DBG+=-g -O3
#DBG+=-g -O0
Index: othersrc/external/bsd/arfe/it/README
diff -u othersrc/external/bsd/arfe/it/README:1.3 othersrc/external/bsd/arfe/it/README:1.4
--- othersrc/external/bsd/arfe/it/README:1.3 Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/it/README Fri Sep 11 01:50:43 2015
@@ -1,5 +1,5 @@
-$ARFE$
-$NetBSD: README,v 1.3 2015/09/02 22:43:17 dyoung Exp $
+$ARFE: README 237 2015-09-02 22:48:04Z dyoung $
+$NetBSD: README,v 1.4 2015/09/11 01:50:43 dyoung Exp $
IT---(i)ntegrate (t)ext---is a variation on DT that adds decimal numbers
instead of subtracts, and bitwise-ORs hexadecimal numbers instead of
Added files:
Index: othersrc/external/bsd/arfe/dt/macaddr.c
diff -u /dev/null othersrc/external/bsd/arfe/dt/macaddr.c:1.1
--- /dev/null Fri Sep 11 01:50:43 2015
+++ othersrc/external/bsd/arfe/dt/macaddr.c Fri Sep 11 01:50:42 2015
@@ -0,0 +1,336 @@
+/* $NetBSD: macaddr.c,v 1.1 2015/09/11 01:50:42 dyoung Exp $ */
+/* $ARFE:47:33Z dyoung $ */
+
+/*-
+ * Copyright (c) 2014,2015 David Young <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <assert.h>
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/cdefs.h> /* for __predict_true() */
+
+#include "dt.h"
+#include "macaddr.h"
+
+typedef enum mac_op {
+ MAC_OP_NONE = 0
+ , MAC_OP_PUSH
+ , MAC_OP_EMIT
+ , MAC_OP_START
+} mac_op_t;
+
+struct mac_state;
+typedef struct mac_state mac_state_t;
+
+typedef struct mac_transition {
+ const mac_state_t *t_newstate;
+ mac_op_t t_op;
+} mac_transition_t;
+
+struct mac_state {
+ const char *s_descr;
+ mac_transition_t s_delimiter;
+ mac_transition_t s_eof;
+ mac_transition_t s_other;
+ mac_transition_t s_colon;
+ mac_transition_t s_hexdigit;
+};
+
+enum mac_state_idxs {
+ READ_OTHER = 0
+ , READ_DELIMITER /* Initial state: beginning of file, or read
+ * Space, or read punctuation other than '.'
+ */
+ , READ_EOF
+ , FIRST_NUMBER
+ , READ_COLON = FIRST_NUMBER
+ , READ_HEX
+ , READ_HEX_HEX
+ , SECOND_NUMBER
+};
+
+__CTASSERT(SECOND_NUMBER > FIRST_NUMBER)
+
+#define __skip(__n) ((SECOND_NUMBER - FIRST_NUMBER) * ((__n) - 1))
+
+#define read_colon(__n) mac_states[READ_COLON + __skip(__n)]
+#define read_hex(__n) mac_states[READ_HEX + __skip(__n)]
+#define read_hex_hex(__n) mac_states[READ_HEX_HEX + __skip(__n)]
+#define read_other mac_states[READ_OTHER]
+#define read_delimiter mac_states[READ_DELIMITER]
+#define read_eof mac_states[READ_EOF]
+
+#define first(__n) (__skip(1) + __n)
+#define second(__n) (__skip(2) + __n)
+#define third(__n) (__skip(3) + __n)
+#define fourth(__n) (__skip(4) + __n)
+#define fifth(__n) (__skip(5) + __n)
+#define sixth(__n) (__skip(6) + __n)
+
+// see notebook, 9 Sep 2015
+static mac_state_t mac_states[] = {
+ [READ_DELIMITER] = {
+ .s_descr = "read delimiter"
+ , .s_delimiter = {&read_delimiter, MAC_OP_NONE}
+ , .s_eof = {&read_eof, MAC_OP_NONE}
+ , .s_other = {&read_other, MAC_OP_NONE}
+ , .s_hexdigit = {&read_hex(1), MAC_OP_START}
+}, [READ_EOF] = {
+ .s_descr = "read eof",
+ .s_other = {&read_eof, MAC_OP_NONE},
+}, [READ_OTHER] = {
+ .s_descr = "read other",
+ .s_other = {&read_other, MAC_OP_NONE},
+ .s_delimiter = {&read_delimiter, MAC_OP_NONE},
+}, [first(READ_COLON)] = {
+ .s_descr = "read colon"
+ , .s_delimiter = {&read_delimiter, MAC_OP_NONE}
+ , .s_eof = {&read_eof, MAC_OP_NONE}
+ , .s_hexdigit = {&read_hex(2), MAC_OP_PUSH}
+}, [first(READ_HEX_HEX)] = {
+ .s_descr = "read hex hex"
+ , .s_delimiter = {&read_delimiter, MAC_OP_NONE}
+ , .s_eof = {&read_eof, MAC_OP_NONE}
+ , .s_colon = {&read_colon(1), MAC_OP_PUSH}
+ , .s_other = {&read_other, MAC_OP_NONE}
+}, [first(READ_HEX)] = {
+ .s_descr = "read hex"
+ , .s_colon = {&read_colon(1), MAC_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, MAC_OP_NONE}
+ , .s_eof = {&read_eof, MAC_OP_NONE}
+ , .s_other = {&read_other, MAC_OP_NONE}
+ , .s_hexdigit = {&read_hex_hex(1), MAC_OP_PUSH}
+}, [second(READ_COLON)] = {
+ .s_descr = "read colon 2"
+ , .s_delimiter = {&read_delimiter, MAC_OP_NONE}
+ , .s_eof = {&read_eof, MAC_OP_NONE}
+ , .s_hexdigit = {&read_hex(3), MAC_OP_PUSH}
+ , .s_other = {&read_other, MAC_OP_NONE}
+}, [second(READ_HEX_HEX)] = {
+ .s_descr = "read hex hex 2"
+ , .s_delimiter = {&read_delimiter, MAC_OP_NONE}
+ , .s_eof = {&read_eof, MAC_OP_NONE}
+ , .s_colon = {&read_colon(2), MAC_OP_PUSH}
+ , .s_other = {&read_other, MAC_OP_NONE}
+}, [second(READ_HEX)] = {
+ .s_descr = "read hex 2"
+ , .s_colon = {&read_colon(2), MAC_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, MAC_OP_NONE}
+ , .s_eof = {&read_eof, MAC_OP_NONE}
+ , .s_other = {&read_other, MAC_OP_NONE}
+ , .s_hexdigit = {&read_hex_hex(2), MAC_OP_PUSH}
+}, [third(READ_COLON)] = {
+ .s_descr = "read colon 3"
+ , .s_delimiter = {&read_delimiter, MAC_OP_NONE}
+ , .s_eof = {&read_eof, MAC_OP_NONE}
+ , .s_hexdigit = {&read_hex(4), MAC_OP_PUSH}
+ , .s_other = {&read_other, MAC_OP_NONE}
+}, [third(READ_HEX_HEX)] = {
+ .s_descr = "read hex hex 3"
+ , .s_delimiter = {&read_delimiter, MAC_OP_NONE}
+ , .s_eof = {&read_eof, MAC_OP_NONE}
+ , .s_colon = {&read_colon(3), MAC_OP_PUSH}
+ , .s_other = {&read_other, MAC_OP_NONE}
+}, [third(READ_HEX)] = {
+ .s_descr = "read hex 3"
+ , .s_colon = {&read_colon(3), MAC_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, MAC_OP_NONE}
+ , .s_eof = {&read_eof, MAC_OP_NONE}
+ , .s_other = {&read_other, MAC_OP_NONE}
+ , .s_hexdigit = {&read_hex_hex(3), MAC_OP_PUSH}
+}, [fourth(READ_COLON)] = {
+ .s_descr = "read colon 4"
+ , .s_delimiter = {&read_delimiter, MAC_OP_NONE}
+ , .s_eof = {&read_eof, MAC_OP_NONE}
+ , .s_hexdigit = {&read_hex(5), MAC_OP_PUSH}
+ , .s_other = {&read_other, MAC_OP_NONE}
+}, [fourth(READ_HEX_HEX)] = {
+ .s_descr = "read hex hex 4"
+ , .s_delimiter = {&read_delimiter, MAC_OP_NONE}
+ , .s_eof = {&read_eof, MAC_OP_NONE}
+ , .s_colon = {&read_colon(4), MAC_OP_PUSH}
+ , .s_other = {&read_other, MAC_OP_NONE}
+}, [fourth(READ_HEX)] = {
+ .s_descr = "read hex 4"
+ , .s_colon = {&read_colon(4), MAC_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, MAC_OP_NONE}
+ , .s_eof = {&read_eof, MAC_OP_NONE}
+ , .s_other = {&read_other, MAC_OP_NONE}
+ , .s_hexdigit = {&read_hex_hex(4), MAC_OP_PUSH}
+}, [fifth(READ_COLON)] = {
+ .s_descr = "read colon 5"
+ , .s_delimiter = {&read_delimiter, MAC_OP_NONE}
+ , .s_eof = {&read_eof, MAC_OP_NONE}
+ , .s_hexdigit = {&read_hex(6), MAC_OP_PUSH}
+ , .s_other = {&read_other, MAC_OP_NONE}
+}, [fifth(READ_HEX_HEX)] = {
+ .s_descr = "read hex hex 5"
+ , .s_delimiter = {&read_delimiter, MAC_OP_NONE}
+ , .s_eof = {&read_eof, MAC_OP_NONE}
+ , .s_colon = {&read_colon(5), MAC_OP_PUSH}
+ , .s_other = {&read_other, MAC_OP_NONE}
+}, [fifth(READ_HEX)] = {
+ .s_descr = "read hex 5"
+ , .s_colon = {&read_colon(5), MAC_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, MAC_OP_NONE}
+ , .s_eof = {&read_eof, MAC_OP_NONE}
+ , .s_other = {&read_other, MAC_OP_NONE}
+ , .s_hexdigit = {&read_hex_hex(5), MAC_OP_PUSH}
+//*****************************
+}, [sixth(READ_HEX)] = {
+ .s_descr = "read hex"
+ , .s_delimiter = {&read_delimiter, MAC_OP_EMIT}
+ , .s_eof = {&read_eof, MAC_OP_EMIT}
+ , .s_other = {&read_other, MAC_OP_NONE}
+ , .s_hexdigit = {&read_hex_hex(6), MAC_OP_PUSH}
+}, [sixth(READ_HEX_HEX)] = {
+ .s_descr = "read hex"
+ , .s_delimiter = {&read_delimiter, MAC_OP_EMIT}
+ , .s_eof = {&read_eof, MAC_OP_EMIT}
+ , .s_other = {&read_other, MAC_OP_NONE}
+}};
+
+struct mac_parser {
+ mac_detection_t p_detection;
+#define p_column p_detection.d_column
+#define p_string p_detection.d_string
+#define p_idx p_detection.d_idx
+ char *p_last;
+ const mac_state_t *p_state;
+ mac_emitter_t p_emitter;
+ void *p_arg;
+};
+
+void
+mac_parser_free(mac_parser_t *p)
+{
+ free(p);
+}
+
+static void
+mac_parser_init(mac_parser_t *p, mac_emitter_t emitter, void *arg)
+{
+ memset(p, 0, sizeof(*p));
+ p->p_state = &read_delimiter;
+ p->p_emitter = emitter;
+ p->p_arg = arg;
+}
+
+mac_parser_t *
+mac_parser_alloc(mac_emitter_t emitter, void *arg)
+{
+ mac_parser_t *p;
+
+ p = malloc(sizeof(*p));
+ if (p == NULL)
+ return NULL;
+
+ mac_parser_init(p, emitter, arg);
+ return p;
+}
+
+static const char *
+mac_op_string(mac_op_t op)
+{
+ switch (op) {
+ case MAC_OP_NONE:
+ return "none";
+ case MAC_OP_EMIT:
+ return "emit";
+ case MAC_OP_PUSH:
+ return "push";
+ case MAC_OP_START:
+ return "start";
+ default:
+ return "unknown";
+ }
+}
+
+void
+mac_parser_drive(mac_parser_t *p, int idx, int column, int c)
+{
+ const mac_transition_t *t;
+ const mac_state_t *ns, *s;
+
+ s = p->p_state;
+
+ if (c == -1 && (ns = s->s_eof.t_newstate) != NULL)
+ t = &s->s_eof;
+ else if (strchr("abcdefABCDEF0123456789", c) != NULL &&
+ (ns = s->s_hexdigit.t_newstate) != NULL)
+ t = &s->s_hexdigit;
+ else if (c == ':' && (ns = s->s_colon.t_newstate) != NULL)
+ t = &s->s_colon;
+ else if ((isspace(c) || ispunct(c)) && c != ':' &&
+ (ns = s->s_delimiter.t_newstate) != NULL)
+ t = &s->s_delimiter;
+ else if ((ns = s->s_other.t_newstate) != NULL)
+ t = &s->s_other;
+ else
+ ns = NULL;
+
+ assert(ns != NULL);
+ if (c == -1) {
+ dbg_printf("%s: transition (%s, eof) -> %s (op %s)\n", __func__,
+ s->s_descr, ns->s_descr, mac_op_string(t->t_op));
+ } else {
+ dbg_printf("%s: transition (%s, %c) -> %s (op %s)\n", __func__,
+ s->s_descr, c, ns->s_descr, mac_op_string(t->t_op));
+ }
+
+ switch (t->t_op) {
+ case MAC_OP_START:
+ p->p_column.start = column;
+ p->p_idx.start = idx;
+ p->p_last = &p->p_string[0];
+ /*FALLTHROUGH*/
+ case MAC_OP_PUSH:
+ if (p->p_last == NULL)
+ ;
+ else if (p->p_last - &p->p_string[0] ==
+ __arraycount(p->p_string) - 1)
+ p->p_last = NULL;
+ else {
+ *p->p_last = c;
+ p->p_last++;
+ }
+ p->p_column.stop = column;
+ p->p_idx.stop = idx;
+ break;
+ case MAC_OP_EMIT:
+ if (p->p_last == NULL)
+ dbg_printf("mac string too long\n");
+ *p->p_last = '\0';
+ (*p->p_emitter)(&p->p_detection, p->p_arg);
+ break;
+ case MAC_OP_NONE:
+ break;
+ }
+
+ p->p_state = ns;
+}
+
Index: othersrc/external/bsd/arfe/dt/macaddr.h
diff -u /dev/null othersrc/external/bsd/arfe/dt/macaddr.h:1.1
--- /dev/null Fri Sep 11 01:50:43 2015
+++ othersrc/external/bsd/arfe/dt/macaddr.h Fri Sep 11 01:50:42 2015
@@ -0,0 +1,46 @@
+/* $NetBSD: macaddr.h,v 1.1 2015/09/11 01:50:42 dyoung Exp $ */
+/* $ARFE$ */
+
+/*-
+ * Copyright (c) 2014,2015 David Young <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _MACADDR_H_
+#define _MACADDR_H_
+
+typedef struct mac_detection {
+ struct {
+ int start, stop;
+ } d_column, d_idx;
+ char d_string[sizeof("00:11:22:33:44:55")];
+} mac_detection_t;
+
+struct mac_parser;
+typedef struct mac_parser mac_parser_t;
+
+typedef void (*mac_emitter_t)(mac_detection_t *, void *);
+mac_parser_t *mac_parser_alloc(mac_emitter_t, void *);
+void mac_parser_drive(mac_parser_t *, int, int, int);
+void mac_parser_free(mac_parser_t *);
+
+#endif /* _MACADDR_H_ */
Index: othersrc/external/bsd/arfe/tt/.cvsignore
diff -u /dev/null othersrc/external/bsd/arfe/tt/.cvsignore:1.1
--- /dev/null Fri Sep 11 01:50:43 2015
+++ othersrc/external/bsd/arfe/tt/.cvsignore Fri Sep 11 01:50:43 2015
@@ -0,0 +1,3 @@
+*.d
+.depend
+it
Index: othersrc/external/bsd/arfe/tt/Makefile
diff -u /dev/null othersrc/external/bsd/arfe/tt/Makefile:1.1
--- /dev/null Fri Sep 11 01:50:43 2015
+++ othersrc/external/bsd/arfe/tt/Makefile Fri Sep 11 01:50:43 2015
@@ -0,0 +1,25 @@
+NOMAN=
+.include <bsd.own.mk>
+
+PROG=tt
+SRCS+=dt.c hex.c ipv4.c macaddr.c
+#CPPFLAGS+=-DHB_DEBUG
+CPPFLAGS+=-DHB_ASSERT
+DBG+=-g -O3
+#DBG+=-g -O0
+#COPTS+=-pg
+#LDFLAGS+=-pg
+CFLAGS+=-std=c99
+WARNS=5
+
+tags: $(SRCS) $(INCS)
+ @rm -f $(.OBJDIR)/tags
+ @ctags -atwd $(.ALLSRC)
+ @sort -o $(.OBJDIR)/tags $(.OBJDIR)/tags
+
+test: ${.OBJDIR}/${PROG}
+ @OBJDIR=${.OBJDIR} sh testit.sh
+
+.PATH: $(.CURDIR)/../dt
+
+.include <bsd.prog.mk>
Index: othersrc/external/bsd/arfe/tt/README
diff -u /dev/null othersrc/external/bsd/arfe/tt/README:1.1
--- /dev/null Fri Sep 11 01:50:43 2015
+++ othersrc/external/bsd/arfe/tt/README Fri Sep 11 01:50:43 2015
@@ -0,0 +1,33 @@
+$ARFE: README 239 2015-09-10 22:49:40Z dyoung $
+$NetBSD: README,v 1.1 2015/09/11 01:50:43 dyoung Exp $
+
+TT---(t)ransform (t)ext---transforms its input based on a
+match/transform-template pair that exemplifies the changes that should
+be made. Like DT and IT, TT detects data in its input---decimal and
+hexadecimal numbers, network addresses. TT also detects the data in
+the match and transform templates, and notes occurrences of identical
+data in both templates. TT aligns its input with the match template in
+the same way that DT and TT do. Then it generates its output from the
+transform template. Non-data parts of the transform template are copied
+directly to the output. Whenever a datum in the transform template
+is identical to a datum in the match template, and TT has aligned the
+match datum with an input datum, then TT copies the corresponding datum
+from its input to its output. Otherwise, data parts of the transform
+template are copied directly to the output.
+
+The TT reads its input from the first command-line argument, the match
+template from the second argument, and the transform template from the
+third. TT writes the transformed text to standard output.
+
+Example
+-------
+
+TT can transpose a 3x3 matrix.
+
+input match template transform template output
+
+5 9 99 11 12 13 11 21 31 5 6 1
+6 53 10 21 22 23 12 22 32 9 53 8
+1 8 40 31 32 33 13 23 33 99 10 40
+
+See also ../dt/README.
Index: othersrc/external/bsd/arfe/tt/testit.sh
diff -u /dev/null othersrc/external/bsd/arfe/tt/testit.sh:1.1
--- /dev/null Fri Sep 11 01:50:43 2015
+++ othersrc/external/bsd/arfe/tt/testit.sh Fri Sep 11 01:50:43 2015
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+TT=${OBJDIR:-.}/tt
+
+for i in $(ls tests)
+do
+ d=./tests/${i}
+ if [ -e $d/expected-output ]; then
+ echo running $i
+ if ! ${TT} $d/input $d/match $d/transform | \
+ diff $d/expected-output - ; then
+ exit 1
+ fi
+ else
+ echo generating $i ...
+ ${TT} $d/input $d/match $d/transform > $d/expected-output ||\
+ rm -f $d/expected-output
+ fi
+done
+
+exit 0