Module Name: othersrc
Committed By: dyoung
Date: Thu Oct 8 22:00:56 UTC 2015
Modified Files:
othersrc/external/bsd/arfe/dt: Makefile core.c core.h macaddr.c
portability.h
othersrc/external/bsd/arfe/dt/rr: daily-output-2-daily-output-5
daily-output-5-daily-output-2 daily-output-5-daily-output-6
daily-output-6-daily-output-5 daily-output-6-daily-output-7
daily-output-7-daily-output-6
othersrc/external/bsd/arfe/it: Makefile
othersrc/external/bsd/arfe/tt: Makefile
Added Files:
othersrc/external/bsd/arfe/dt: dec.c dec.h
Log Message:
Make ARFE understand numbers with decimal points.
To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 othersrc/external/bsd/arfe/dt/Makefile
cvs rdiff -u -r1.2 -r1.3 othersrc/external/bsd/arfe/dt/core.c \
othersrc/external/bsd/arfe/dt/core.h
cvs rdiff -u -r0 -r1.1 othersrc/external/bsd/arfe/dt/dec.c \
othersrc/external/bsd/arfe/dt/dec.h
cvs rdiff -u -r1.3 -r1.4 othersrc/external/bsd/arfe/dt/macaddr.c
cvs rdiff -u -r1.1 -r1.2 othersrc/external/bsd/arfe/dt/portability.h
cvs rdiff -u -r1.1 -r1.2 \
othersrc/external/bsd/arfe/dt/rr/daily-output-2-daily-output-5 \
othersrc/external/bsd/arfe/dt/rr/daily-output-5-daily-output-2 \
othersrc/external/bsd/arfe/dt/rr/daily-output-5-daily-output-6 \
othersrc/external/bsd/arfe/dt/rr/daily-output-6-daily-output-5 \
othersrc/external/bsd/arfe/dt/rr/daily-output-6-daily-output-7 \
othersrc/external/bsd/arfe/dt/rr/daily-output-7-daily-output-6
cvs rdiff -u -r1.4 -r1.5 othersrc/external/bsd/arfe/it/Makefile
cvs rdiff -u -r1.2 -r1.3 othersrc/external/bsd/arfe/tt/Makefile
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/dt/Makefile
diff -u othersrc/external/bsd/arfe/dt/Makefile:1.5 othersrc/external/bsd/arfe/dt/Makefile:1.6
--- othersrc/external/bsd/arfe/dt/Makefile:1.5 Tue Sep 22 01:12:09 2015
+++ othersrc/external/bsd/arfe/dt/Makefile Thu Oct 8 22:00:56 2015
@@ -1,9 +1,10 @@
-# $ARFE: Makefile 250 2015-09-22 01:04:13Z dyoung $
+# $ARFE: Makefile 262 2015-10-08 21:47:24Z dyoung $
NOMAN=
.include <bsd.own.mk>
+DPINCS+=core.h dec.h hex.h ipv4.h macaddr.h
PROG=dt
-SRCS+=core.c dt.c hex.c ipv4.c macaddr.c
+SRCS+=core.c dec.c dt.c hex.c ipv4.c macaddr.c
#CPPFLAGS+=-DHB_DEBUG
CPPFLAGS+=-DHB_ASSERT
DBG+=-g -O3
@@ -13,7 +14,7 @@ DBG+=-g -O3
CFLAGS+=-std=c99
WARNS=5
-tags: $(SRCS) $(INCS)
+tags: $(SRCS) $(DPINCS) $(INCS)
@rm -f $(.OBJDIR)/tags
@ctags -atwd $(.ALLSRC)
@sort -o $(.OBJDIR)/tags $(.OBJDIR)/tags
Index: othersrc/external/bsd/arfe/dt/core.c
diff -u othersrc/external/bsd/arfe/dt/core.c:1.2 othersrc/external/bsd/arfe/dt/core.c:1.3
--- othersrc/external/bsd/arfe/dt/core.c:1.2 Wed Sep 23 19:32:34 2015
+++ othersrc/external/bsd/arfe/dt/core.c Thu Oct 8 22:00:56 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: core.c,v 1.2 2015/09/23 19:32:34 dyoung Exp $ */
+/* $NetBSD: core.c,v 1.3 2015/10/08 22:00:56 dyoung Exp $ */
/* $ARFE$ */
/*-
@@ -25,6 +25,7 @@
* (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 <ctype.h> /* for isdigit() */
#include <err.h>
#include <errno.h>
#include <fcntl.h>
@@ -41,6 +42,7 @@
#include <arpa/inet.h> /* for inet_net_pton */
#include "core.h"
+#include "dec.h"
#include "hex.h"
#include "ipv4.h"
#include "macaddr.h"
@@ -521,35 +523,78 @@ hex_clocc(const scratch_t *scratch, int
return newchain_with_match_idx(strdup("<hexmax>"), column, idx_b);
}
+static void
+align_decimal_points(const decimal_t *ina, const decimal_t *inb,
+ decimal_t *outa, decimal_t *outb)
+{
+ *outa = *ina;
+ *outb = *inb;
+ while (outa->log10denom > outb->log10denom) {
+ outa->num *= 10;
+ outa->log10denom--;
+ }
+ while (outb->log10denom > outa->log10denom) {
+ outb->num *= 10;
+ outb->log10denom--;
+ }
+}
+
+static intmax_t
+power10(unsigned int x)
+{
+ if (x == 0)
+ return 1;
+
+ if (x % 2 == 0) {
+ intmax_t root = power10(x / 2);
+ return root * root;
+ }
+ return power10(x - 1) * 10;
+}
+
static chain_t *
-int_clocc(const scratch_t *scratch, int idx_a, int idx_b)
+dec_clocc(const scratch_t *scratch, int idx_a, int idx_b)
{
char *ret;
int column;
intmax_t result;
const clocc_t * const a = &scratch->Aoccs.occs[idx_a],
* const b = &scratch->Boccs.occs[idx_b];
+ struct {
+ decimal_t a, b;
+ } val;
column = cloccs_to_column(a, b);
- dbg2_printf("%jd @ %d / %jd @ %d -> column %d\n",
- a->val_u.u_intmax, a->column,
- b->val_u.u_intmax, b->column, column);
+ align_decimal_points(&a->val_u.u_dec, &b->val_u.u_dec, &val.a, &val.b);
+
+ dbg2_printf("%jd / 10^%d @ %d ; %jd / 10^%d @ %d -> column %d\n",
+ val.a.num, val.a.log10denom, a->column,
+ val.b.num, val.b.log10denom, b->column, column);
switch (scratch->dec_op) {
case '-':
- result = b->val_u.u_intmax - a->val_u.u_intmax;
+ result = val.b.num - val.a.num;
break;
case '+':
- result = b->val_u.u_intmax + a->val_u.u_intmax;
+ result = val.b.num + val.a.num;
break;
case 'l':
default:
- result = a->val_u.u_intmax;
+ result = val.a.num;
break;
}
- if (asprintf(&ret, "%jd", result) != -1)
+ intmax_t lop = result / power10(val.a.log10denom),
+ rop = imaxabs(result) % power10(val.a.log10denom);
+
+#if 0
+ assert(result >= 0);
+#endif
+
+ if (val.a.log10denom != 0 && asprintf(&ret, "%s%jd.%0*jd", (result < 0 && lop == 0) ? "-" : "", lop, (int)val.a.log10denom, rop) != -1)
+ return newchain_with_match_idx(ret, column, idx_b);
+ if (val.a.log10denom == 0 && asprintf(&ret, "%jd", result) != -1)
return newchain_with_match_idx(ret, column, idx_b);
return newchain_with_match_idx(strdup("<intmax>"), column, idx_b);
@@ -570,7 +615,7 @@ clocc(const scratch_t *scratch, int idx_
}
if (b->kind == KIND_INTMAX_DEC)
- return int_clocc(scratch, idx_a, idx_b);
+ return dec_clocc(scratch, idx_a, idx_b);
if (b->kind == KIND_IPv4)
return ipv4_clocc(scratch, idx_a, idx_b);
@@ -1107,6 +1152,66 @@ emit_ipv4_clocc(ipv4_detection_t *d, voi
}
static void
+emit_dec_clocc(dec_detection_t *d, void *arg)
+{
+ cloccs_t *o = arg;
+ intmax_t val, ropval = 0;
+ char *end, *ropend;
+ unsigned int log10denom = 0;
+ uintmax_t denom = 1;
+ int sign = 1;
+ char *next;
+
+ dbg_printf("found decimal string %s @ [%d, %d]\n", d->d_digits,
+ d->d_idx.start, d->d_idx.stop);
+
+ if (o->noccs >= (int)__arraycount(o->occs))
+ return;
+
+ if (d->d_digits[0] == '-') {
+ next = &d->d_digits[1];
+ sign = -1;
+ } else {
+ next = &d->d_digits[0];
+ sign = 1;
+ }
+ if (!isdigit((unsigned char)*next)) {
+ val = 0;
+ end = next;
+ } else {
+ val = strtoimax(next, &end, 10);
+
+ if (*end != '\0' && errno == ERANGE) {
+ warnx("%s: over/underflow at %d", __func__,
+ d->d_column.start);
+ }
+ }
+
+ if (*end == '.') {
+ ++end;
+ ropval = strtoimax(end, &ropend, 10);
+
+ if (*ropend != '\0' && errno == ERANGE) {
+ warnx("%s: over/underflow at %d", __func__,
+ d->d_column.start + end - d->d_digits);
+ }
+ for (; end < ropend; end++) {
+ log10denom++;
+ denom *= 10;
+ }
+ }
+
+ 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_INTMAX_DEC;
+ o->occs[o->noccs].qual = QUAL_NONE;
+ o->occs[o->noccs].val_u.u_dec.num = sign * (val * denom + ropval);
+ o->occs[o->noccs].val_u.u_dec.log10denom = log10denom;
+ o->noccs++;
+}
+
+static void
emit_hex_clocc(hex_detection_t *d, void *arg, bool use0x)
{
cloccs_t *o = arg;
@@ -1203,13 +1308,13 @@ cloccs_hash(cloccs_t *o, const slice_t *
void
cloccs_init(cloccs_t *o, const slice_t *s)
{
+ dec_parser_t *dec_parser;
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? */
+ unsigned int j;
clocc_htbl_init(&o->htbl);
@@ -1286,59 +1391,27 @@ parse_hexadecimal:
hex_parser_free(hex_parser);
parse_decimal:
+ dec_parser = dec_parser_alloc(emit_dec_clocc, o);
+ if (dec_parser == NULL)
+ goto out;
- j = 0;
column = 0;
- while (o->noccs < (int)__arraycount(o->occs)) {
- intmax_t val;
- char *end;
+ for (j = 0; j < n; j++) {
char c;
- ++column;
-
- if (j == n)
- break;
-
c = get(s, j);
- for (k = j + 1; k < n; k++) {
- if (strchr("0123456789", get(s, k)) == NULL)
- break;
- }
- if (c == '-') {
- if (j == k - 1) {
- j++;
- continue;
- }
- } else if (strchr("0123456789", c) == NULL) {
- if (c == '\n')
- column = 0;
- j++;
- continue;
- }
-
- if (k - j > __arraycount(digits) - 1)
- goto next;
+ ++column;
+ dec_parser_drive(dec_parser, j, column, c);
+ if (c == '\n')
+ column = 0;
+ }
+ dec_parser_drive(dec_parser, n, column + 1, -1);
- extract(s, j, k - 1, digits);
+ dec_parser_free(dec_parser);
- val = strtoimax(digits, &end, 10);
- if (*end == '\0') {
- o->occs[o->noccs].column = column;
- o->occs[o->noccs].first = j;
- o->occs[o->noccs].last = k - 1;
- o->occs[o->noccs].kind = KIND_INTMAX_DEC;
- o->occs[o->noccs].val_u.u_intmax = val;
- dbg_printf("found %jd at %d - %d\n",
- val, o->occs[o->noccs].first,
- o->occs[o->noccs].last);
- o->noccs++;
- } else if (errno == ERANGE)
- warnx("%s: over/underflow at %d", __func__, j);
-next:
- column += k - 1 - j;
- j = k;
- }
- mergesort(o->occs, o->noccs, sizeof(*o->occs), clocc_cmp);
+out:
+ if (o->noccs > 0)
+ mergesort(o->occs, o->noccs, sizeof(*o->occs), clocc_cmp);
cloccs_dedup(o);
}
Index: othersrc/external/bsd/arfe/dt/core.h
diff -u othersrc/external/bsd/arfe/dt/core.h:1.2 othersrc/external/bsd/arfe/dt/core.h:1.3
--- othersrc/external/bsd/arfe/dt/core.h:1.2 Wed Sep 23 19:32:34 2015
+++ othersrc/external/bsd/arfe/dt/core.h Thu Oct 8 22:00:56 2015
@@ -1,5 +1,5 @@
-/* $NetBSD: core.h,v 1.2 2015/09/23 19:32:34 dyoung Exp $ */
-/* $ARFE: core.h 258 2015-09-23 19:31:17Z dyoung $ */
+/* $NetBSD: core.h,v 1.3 2015/10/08 22:00:56 dyoung Exp $ */
+/* $ARFE: core.h 262 2015-10-08 21:47:24Z dyoung $ */
/*-
* Copyright (c) 2014,2015 David Young <[email protected]>
@@ -113,6 +113,13 @@ typedef enum {
struct chainelt;
typedef struct chainelt chainelt_t;
+struct decimal {
+ intmax_t num;
+ unsigned int log10denom;
+};
+
+typedef struct decimal decimal_t;
+
typedef struct clocc {
int column;
int first;
@@ -120,7 +127,7 @@ typedef struct clocc {
clocc_kind_t kind;
clocc_qual_t qual;
union {
- intmax_t u_intmax;
+ decimal_t u_dec;
uintmax_t u_uintmax;
uint32_t u_ipv4;
uint8_t u_macaddr[6];
Index: othersrc/external/bsd/arfe/dt/macaddr.c
diff -u othersrc/external/bsd/arfe/dt/macaddr.c:1.3 othersrc/external/bsd/arfe/dt/macaddr.c:1.4
--- othersrc/external/bsd/arfe/dt/macaddr.c:1.3 Tue Sep 22 01:12:09 2015
+++ othersrc/external/bsd/arfe/dt/macaddr.c Thu Oct 8 22:00:56 2015
@@ -1,5 +1,5 @@
-/* $NetBSD: macaddr.c,v 1.3 2015/09/22 01:12:09 dyoung Exp $ */
-/* $ARFE:47:33Z dyoung $ */
+/* $NetBSD: macaddr.c,v 1.4 2015/10/08 22:00:56 dyoung Exp $ */
+/* $ARFE: macaddr.c 260 2015-09-23 19:37:44Z dyoung $ */
/*-
* Copyright (c) 2014,2015 David Young <[email protected]>
Index: othersrc/external/bsd/arfe/dt/portability.h
diff -u othersrc/external/bsd/arfe/dt/portability.h:1.1 othersrc/external/bsd/arfe/dt/portability.h:1.2
--- othersrc/external/bsd/arfe/dt/portability.h:1.1 Wed Sep 16 21:07:44 2015
+++ othersrc/external/bsd/arfe/dt/portability.h Thu Oct 8 22:00:56 2015
@@ -1,3 +1,6 @@
+/* $NetBSD: portability.h,v 1.2 2015/10/08 22:00:56 dyoung Exp $ */
+/* $ARFE: portability.h 261 2015-09-23 19:39:10Z dyoung $ */
+
#ifndef __NetBSD__
#define __aligned(__x) /* */
#define __arraycount(__x) (sizeof(__x) / sizeof(__x[0]))
Index: othersrc/external/bsd/arfe/dt/rr/daily-output-2-daily-output-5
diff -u othersrc/external/bsd/arfe/dt/rr/daily-output-2-daily-output-5:1.1 othersrc/external/bsd/arfe/dt/rr/daily-output-2-daily-output-5:1.2
--- othersrc/external/bsd/arfe/dt/rr/daily-output-2-daily-output-5:1.1 Mon Aug 10 21:10:59 2015
+++ othersrc/external/bsd/arfe/dt/rr/daily-output-2-daily-output-5 Thu Oct 8 22:00:56 2015
@@ -1,6 +1,6 @@
-Uptime: 0: 0AM up 3 day, 0:0, -10 users, load averages: 0.13, 0. 4, 0. 1
+Uptime: 0: 0AM up 3 day, 0:0, -10 users, load averages: 0.13, 0.04, 0.01
Checking subsystem status:
Index: othersrc/external/bsd/arfe/dt/rr/daily-output-5-daily-output-2
diff -u othersrc/external/bsd/arfe/dt/rr/daily-output-5-daily-output-2:1.1 othersrc/external/bsd/arfe/dt/rr/daily-output-5-daily-output-2:1.2
--- othersrc/external/bsd/arfe/dt/rr/daily-output-5-daily-output-2:1.1 Mon Aug 10 21:10:59 2015
+++ othersrc/external/bsd/arfe/dt/rr/daily-output-5-daily-output-2 Thu Oct 8 22:00:56 2015
@@ -1,6 +1,6 @@
-Uptime: 0: 0AM up -3 day, 0:0, 10 users, load averages: 0.-13, 0.-4, 0.-1
+Uptime: 0: 0AM up -3 day, 0:0, 10 users, load averages: -0.13, -0.04, -0.01
Checking subsystem status:
Index: othersrc/external/bsd/arfe/dt/rr/daily-output-5-daily-output-6
diff -u othersrc/external/bsd/arfe/dt/rr/daily-output-5-daily-output-6:1.1 othersrc/external/bsd/arfe/dt/rr/daily-output-5-daily-output-6:1.2
--- othersrc/external/bsd/arfe/dt/rr/daily-output-5-daily-output-6:1.1 Mon Aug 10 21:10:59 2015
+++ othersrc/external/bsd/arfe/dt/rr/daily-output-5-daily-output-6 Thu Oct 8 22:00:56 2015
@@ -1,6 +1,6 @@
-Uptime: 0: 0AM up 1 days, 0: 0, 0 users, load averages: 0.-11, 0.-2, 0.-1
+Uptime: 0: 0AM up 1 days, 0: 0, 0 users, load averages: -0.11, -0.02, -0.01
Checking subsystem status:
Index: othersrc/external/bsd/arfe/dt/rr/daily-output-6-daily-output-5
diff -u othersrc/external/bsd/arfe/dt/rr/daily-output-6-daily-output-5:1.1 othersrc/external/bsd/arfe/dt/rr/daily-output-6-daily-output-5:1.2
--- othersrc/external/bsd/arfe/dt/rr/daily-output-6-daily-output-5:1.1 Mon Aug 10 21:10:59 2015
+++ othersrc/external/bsd/arfe/dt/rr/daily-output-6-daily-output-5 Thu Oct 8 22:00:56 2015
@@ -1,6 +1,6 @@
-Uptime: 0: 0AM up -1 days, 0: 0, 0 users, load averages: 0.11, 0. 2, 0. 1
+Uptime: 0: 0AM up -1 days, 0: 0, 0 users, load averages: 0.11, 0.02, 0.01
Checking subsystem status:
Index: othersrc/external/bsd/arfe/dt/rr/daily-output-6-daily-output-7
diff -u othersrc/external/bsd/arfe/dt/rr/daily-output-6-daily-output-7:1.1 othersrc/external/bsd/arfe/dt/rr/daily-output-6-daily-output-7:1.2
--- othersrc/external/bsd/arfe/dt/rr/daily-output-6-daily-output-7:1.1 Mon Aug 10 21:10:59 2015
+++ othersrc/external/bsd/arfe/dt/rr/daily-output-6-daily-output-7 Thu Oct 8 22:00:56 2015
@@ -1,6 +1,6 @@
-Uptime: 0: 0AM up 1 days, 0: 0, 0 users, load averages: 0.-2, 0.-2, 0. 0
+Uptime: 0: 0AM up 1 days, 0: 0, 0 users, load averages: -0.02, -0.02, 0.00
Checking subsystem status:
Index: othersrc/external/bsd/arfe/dt/rr/daily-output-7-daily-output-6
diff -u othersrc/external/bsd/arfe/dt/rr/daily-output-7-daily-output-6:1.1 othersrc/external/bsd/arfe/dt/rr/daily-output-7-daily-output-6:1.2
--- othersrc/external/bsd/arfe/dt/rr/daily-output-7-daily-output-6:1.1 Mon Aug 10 21:10:59 2015
+++ othersrc/external/bsd/arfe/dt/rr/daily-output-7-daily-output-6 Thu Oct 8 22:00:56 2015
@@ -1,6 +1,6 @@
-Uptime: 0: 0AM up -1 days, 0: 0, 0 users, load averages: 0. 2, 0. 2, 0. 0
+Uptime: 0: 0AM up -1 days, 0: 0, 0 users, load averages: 0.02, 0.02, 0.00
Checking subsystem status:
Index: othersrc/external/bsd/arfe/it/Makefile
diff -u othersrc/external/bsd/arfe/it/Makefile:1.4 othersrc/external/bsd/arfe/it/Makefile:1.5
--- othersrc/external/bsd/arfe/it/Makefile:1.4 Tue Sep 22 01:12:09 2015
+++ othersrc/external/bsd/arfe/it/Makefile Thu Oct 8 22:00:56 2015
@@ -2,7 +2,7 @@ NOMAN=
.include <bsd.own.mk>
PROG=it
-SRCS+=core.c hex.c ipv4.c it.c macaddr.c
+SRCS+=core.c dec.c hex.c ipv4.c it.c macaddr.c
#CPPFLAGS+=-DHB_DEBUG
CPPFLAGS+=-I$(.CURDIR)/../dt
DBG+=-g -O3
Index: othersrc/external/bsd/arfe/tt/Makefile
diff -u othersrc/external/bsd/arfe/tt/Makefile:1.2 othersrc/external/bsd/arfe/tt/Makefile:1.3
--- othersrc/external/bsd/arfe/tt/Makefile:1.2 Tue Sep 22 01:12:09 2015
+++ othersrc/external/bsd/arfe/tt/Makefile Thu Oct 8 22:00:56 2015
@@ -2,7 +2,7 @@ NOMAN=
.include <bsd.own.mk>
PROG=tt
-SRCS+=core.c hex.c ipv4.c macaddr.c tt.c
+SRCS+=core.c dec.c hex.c ipv4.c macaddr.c tt.c
#CPPFLAGS+=-DHB_DEBUG
CPPFLAGS+=-DHB_ASSERT
CPPFLAGS+=-I$(.CURDIR)/../dt
Added files:
Index: othersrc/external/bsd/arfe/dt/dec.c
diff -u /dev/null othersrc/external/bsd/arfe/dt/dec.c:1.1
--- /dev/null Thu Oct 8 22:00:56 2015
+++ othersrc/external/bsd/arfe/dt/dec.c Thu Oct 8 22:00:56 2015
@@ -0,0 +1,256 @@
+/* $NetBSD: dec.c,v 1.1 2015/10/08 22:00:56 dyoung Exp $ */
+/* $ARFE: dec.c 262 2015-10-08 21:47:24Z 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 <stdlib.h>
+#include <string.h>
+
+#include "core.h"
+#include "dec.h"
+
+typedef enum dec_op {
+ DEC_OP_NONE = 0
+ , DEC_OP_PUSH
+ , DEC_OP_EMIT
+ , DEC_OP_START
+} dec_op_t;
+
+struct dec_state;
+typedef struct dec_state dec_state_t;
+
+typedef struct dec_transition {
+ const dec_state_t *t_newstate;
+ dec_op_t t_op;
+} dec_transition_t;
+
+struct dec_state {
+ const char *s_descr;
+ dec_transition_t s_other;
+ dec_transition_t s_minus;
+ dec_transition_t s_point;
+ dec_transition_t s_0_9;
+ dec_transition_t s_delimiter;
+ dec_transition_t s_eof;
+};
+
+enum dec_state_idxs {
+ READ_SIGN
+ , READ_POINT
+ , READ_POINT_DIGITS
+ , READ_DIGITS
+ , READ_DIGITS_POINT
+ , READ_DIGITS_POINT_DIGITS
+ , READ_EOF
+ , READ_OTHER
+ , READ_DELIMITER
+};
+
+#define read_sign dec_states[READ_SIGN]
+#define read_point dec_states[READ_POINT]
+#define read_point_digits dec_states[READ_POINT_DIGITS]
+#define read_digits dec_states[READ_DIGITS]
+#define read_digits_point dec_states[READ_DIGITS_POINT]
+#define read_digits_point_digits dec_states[READ_DIGITS_POINT_DIGITS]
+#define read_eof dec_states[READ_EOF]
+#define read_other dec_states[READ_OTHER]
+#define read_delimiter dec_states[READ_DELIMITER]
+
+static const dec_state_t dec_states[] = {[READ_SIGN] = {
+ .s_descr = "read sign",
+ .s_other = {&read_other, DEC_OP_NONE},
+ .s_point = {&read_point, DEC_OP_PUSH},
+ .s_0_9 = {&read_digits, DEC_OP_PUSH},
+}, [READ_POINT] = {
+ .s_descr = "read point",
+ .s_other = {&read_other, DEC_OP_NONE},
+ .s_0_9 = {&read_point_digits, DEC_OP_PUSH},
+}, [READ_POINT_DIGITS] = {
+ .s_descr = "read point digits",
+ .s_other = {&read_other, DEC_OP_NONE},
+ .s_minus = {&read_delimiter, DEC_OP_EMIT},
+ .s_delimiter = {&read_delimiter, DEC_OP_EMIT},
+ .s_eof = {&read_eof, DEC_OP_EMIT},
+ .s_0_9 = {&read_point_digits, DEC_OP_PUSH},
+}, [READ_DIGITS] = {
+ .s_descr = "read digits",
+ .s_other = {&read_other, DEC_OP_NONE},
+ .s_delimiter = {&read_delimiter, DEC_OP_EMIT},
+ .s_minus = {&read_delimiter, DEC_OP_EMIT},
+ .s_eof = {&read_eof, DEC_OP_EMIT},
+ .s_0_9 = {&read_digits, DEC_OP_PUSH},
+ .s_point = {&read_digits_point, DEC_OP_PUSH},
+}, [READ_DIGITS_POINT] = {
+ .s_descr = "read digits point",
+ .s_other = {&read_other, DEC_OP_NONE},
+ .s_delimiter = {&read_delimiter, DEC_OP_EMIT},
+ .s_minus = {&read_delimiter, DEC_OP_EMIT},
+ .s_eof = {&read_eof, DEC_OP_EMIT},
+ .s_0_9 = {&read_digits_point_digits, DEC_OP_PUSH},
+}, [READ_DIGITS_POINT_DIGITS] = {
+ .s_descr = "read digits point digits",
+ .s_other = {&read_other, DEC_OP_NONE},
+ .s_delimiter = {&read_delimiter, DEC_OP_EMIT},
+ .s_minus = {&read_delimiter, DEC_OP_EMIT},
+ .s_eof = {&read_eof, DEC_OP_EMIT},
+ .s_0_9 = {&read_digits_point_digits, DEC_OP_PUSH},
+}, [READ_EOF] = {
+ .s_descr = "read eof",
+ .s_other = {&read_eof, DEC_OP_NONE},
+}, [READ_OTHER] = {
+ .s_descr = "read other",
+ .s_other = {&read_other, DEC_OP_NONE},
+ .s_delimiter = {&read_delimiter, DEC_OP_NONE},
+}, [READ_DELIMITER] = {
+ .s_descr = "read delimiter",
+ .s_minus = {&read_sign, DEC_OP_START},
+ .s_point = {&read_point, DEC_OP_START},
+ .s_0_9 = {&read_digits, DEC_OP_START},
+ .s_delimiter = {&read_delimiter, DEC_OP_NONE},
+ .s_other = {&read_other, DEC_OP_NONE},
+}};
+
+struct dec_parser {
+ dec_detection_t p_detection;
+#define p_column p_detection.d_column
+#define p_digits p_detection.d_digits
+#define p_idx p_detection.d_idx
+ char *p_top;
+ const dec_state_t *p_state;
+ dec_emitter_t p_emitter;
+ void *p_arg;
+};
+
+void
+dec_parser_free(dec_parser_t *p)
+{
+ free(p);
+}
+
+static void
+dec_parser_init(dec_parser_t *p, dec_emitter_t emitter, void *arg)
+{
+ memset(p, 0, sizeof(*p));
+ p->p_state = &read_delimiter;
+ p->p_emitter = emitter;
+ p->p_arg = arg;
+}
+
+dec_parser_t *
+dec_parser_alloc(dec_emitter_t emitter, void *arg)
+{
+ dec_parser_t *p;
+
+ p = malloc(sizeof(*p));
+ if (p == NULL)
+ return NULL;
+
+ dec_parser_init(p, emitter, arg);
+ return p;
+}
+
+static const char *
+dec_op_string(dec_op_t op)
+{
+ switch (op) {
+ case DEC_OP_NONE:
+ return "none";
+ case DEC_OP_EMIT:
+ return "emit";
+ case DEC_OP_PUSH:
+ return "push";
+ case DEC_OP_START:
+ return "start";
+ default:
+ return "unknown";
+ }
+}
+
+void
+dec_parser_drive(dec_parser_t *p, int idx, int column, int c)
+{
+ const dec_transition_t *t;
+ const dec_state_t *ns, *s;
+
+ s = p->p_state;
+
+ if (c == -1 && (ns = s->s_eof.t_newstate) != NULL)
+ t = &s->s_eof;
+ else if (c == '-' && (ns = s->s_minus.t_newstate) != NULL)
+ t = &s->s_minus;
+ else if (c == '.' && (ns = s->s_point.t_newstate) != NULL)
+ t = &s->s_point;
+ else if ((isalpha(c) || isspace(c) || ispunct(c)) && c != '.' && c != '-' &&
+ (ns = s->s_delimiter.t_newstate) != NULL)
+ t = &s->s_delimiter;
+ else if (isdigit(c) && (ns = s->s_0_9.t_newstate) != NULL)
+ t = &s->s_0_9;
+ 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, dec_op_string(t->t_op));
+ } else {
+ dbg_printf("%s: transition (%s, %c) -> %s (op %s)\n", __func__,
+ s->s_descr, c, ns->s_descr, dec_op_string(t->t_op));
+ }
+
+ switch (t->t_op) {
+ case DEC_OP_START:
+ p->p_column.start = column;
+ p->p_idx.start = idx;
+ p->p_top = &p->p_digits[0];
+ /*FALLTHROUGH*/
+ case DEC_OP_PUSH:
+ if (p->p_top == NULL)
+ ;
+ else if (p->p_top - &p->p_digits[0] ==
+ __arraycount(p->p_digits) - 1)
+ p->p_top = NULL;
+ else {
+ *p->p_top = c;
+ p->p_top++;
+ }
+ p->p_column.stop = column;
+ p->p_idx.stop = idx;
+ break;
+ case DEC_OP_EMIT:
+ if (p->p_top == NULL)
+ dbg_printf("decimal string too long\n");
+ *p->p_top = '\0';
+ (*p->p_emitter)(&p->p_detection, p->p_arg);
+ break;
+ case DEC_OP_NONE:
+ break;
+ }
+
+ p->p_state = ns;
+}
Index: othersrc/external/bsd/arfe/dt/dec.h
diff -u /dev/null othersrc/external/bsd/arfe/dt/dec.h:1.1
--- /dev/null Thu Oct 8 22:00:56 2015
+++ othersrc/external/bsd/arfe/dt/dec.h Thu Oct 8 22:00:56 2015
@@ -0,0 +1,49 @@
+/* $NetBSD: dec.h,v 1.1 2015/10/08 22:00:56 dyoung Exp $ */
+/* $ARFE: dec.h 262 2015-10-08 21:47:24Z 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.
+ */
+#ifndef _DEC_H
+#define _DEC_H
+
+#include <stdbool.h>
+
+typedef struct dec_detection {
+ struct {
+ int start, stop;
+ } d_column, d_idx;
+ /* XXX how many decimal digits in an intmax_t? */
+ char d_digits[64 / 3 + 1];
+} dec_detection_t;
+
+struct dec_parser;
+typedef struct dec_parser dec_parser_t;
+
+typedef void (*dec_emitter_t)(dec_detection_t *, void *);
+dec_parser_t *dec_parser_alloc(dec_emitter_t, void *);
+void dec_parser_drive(dec_parser_t *, int, int, int);
+void dec_parser_free(dec_parser_t *);
+
+#endif /* _DEC_H */