Module Name:    othersrc
Committed By:   dyoung
Date:           Fri Aug 28 21:39:00 UTC 2015

Modified Files:
        othersrc/external/bsd/arfe/dt: dt.c

Log Message:
Identify hexadecimal numbers that do NOT begin with 0x.

When one hexadecimal number in all capitals matches another all-caps hex
number, print the result in all capitals, too, so that inputs like
this netstat -s output,

        0 packets with ECN CE bit

do not turn to this:

        0 packets with ECN ce bit

TBD: repair expected test results.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 othersrc/external/bsd/arfe/dt/dt.c

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/dt.c
diff -u othersrc/external/bsd/arfe/dt/dt.c:1.4 othersrc/external/bsd/arfe/dt/dt.c:1.5
--- othersrc/external/bsd/arfe/dt/dt.c:1.4	Tue Aug 25 22:19:09 2015
+++ othersrc/external/bsd/arfe/dt/dt.c	Fri Aug 28 21:39:00 2015
@@ -1,5 +1,5 @@
-/* $NetBSD: dt.c,v 1.4 2015/08/25 22:19:09 dyoung Exp $ */
-/* $ARFE: dt.c 217 2015-08-25 22:16:29Z dyoung $ */
+/* $NetBSD: dt.c,v 1.5 2015/08/28 21:39:00 dyoung Exp $ */
+/* $ARFE: dt.c 220 2015-08-28 21:37:51Z dyoung $ */
 
 /*-
  * Copyright (c) 2014,2015 David Young <dyo...@netbsd.org>
@@ -60,7 +60,9 @@ typedef enum hex_op {
 	  HEX_OP_NONE = 0
 	, HEX_OP_PUSH
 	, HEX_OP_EMIT
+	, HEX_OP_0xEMIT
 	, HEX_OP_START
+	, HEX_OP_0xSTART
 } hex_op_t;
 
 struct hex_state;
@@ -84,6 +86,7 @@ struct hex_state {
 enum hex_state_idxs {
 	  READ_0
 	, READ_X
+	, READ_0xHEXDIGIT
 	, READ_HEXDIGIT
 	, READ_EOF
 	, READ_OTHER
@@ -92,6 +95,7 @@ enum hex_state_idxs {
 
 #define	read_0 hex_states[READ_0]
 #define	read_x hex_states[READ_X]
+#define	read_0xhexdigit hex_states[READ_0xHEXDIGIT]
 #define	read_hexdigit hex_states[READ_HEXDIGIT]
 #define	read_eof hex_states[READ_EOF]
 #define	read_other hex_states[READ_OTHER]
@@ -100,11 +104,18 @@ enum hex_state_idxs {
 static const hex_state_t hex_states[] = {[READ_0] = {
 	.s_descr = "read 0",
 	.s_other = {&read_other, HEX_OP_NONE},
-	.s_x = {&read_x, HEX_OP_NONE},
+	.s_hexdigit = {&read_hexdigit, HEX_OP_PUSH},
+	.s_x = {&read_x, HEX_OP_0xSTART},
 }, [READ_X] = {
 	.s_descr = "read x",
 	.s_other = {&read_other, HEX_OP_NONE},
-	.s_hexdigit = {&read_hexdigit, HEX_OP_PUSH},
+	.s_hexdigit = {&read_0xhexdigit, HEX_OP_PUSH},
+}, [READ_0xHEXDIGIT] = {
+	.s_descr = "read 0xhexdigit",
+	.s_other = {&read_other, HEX_OP_NONE},
+	.s_delimiter = {&read_delimiter, HEX_OP_0xEMIT},
+	.s_eof = {&read_eof, HEX_OP_0xEMIT},
+	.s_hexdigit = {&read_0xhexdigit, HEX_OP_PUSH},
 }, [READ_HEXDIGIT] = {
 	.s_descr = "read hexdigit",
 	.s_other = {&read_other, HEX_OP_NONE},
@@ -121,13 +132,15 @@ static const hex_state_t hex_states[] = 
 }, [READ_DELIMITER] = {
 	.s_descr = "read delimiter",
 	.s_0 = {&read_0, HEX_OP_START},
+	.s_hexdigit = {&read_hexdigit, HEX_OP_START},
+	.s_delimiter = {&read_delimiter, HEX_OP_NONE},
 	.s_other = {&read_other, HEX_OP_NONE},
 }};
 
 struct hex_parser;
 typedef struct hex_parser hex_parser_t;
 
-typedef void (*hex_emitter_t)(hex_parser_t *, void *);
+typedef void (*hex_emitter_t)(hex_parser_t *, void *, bool);
 
 struct hex_parser {
 	struct {
@@ -136,6 +149,7 @@ struct hex_parser {
 	char p_digits[16 + 1];	/* XXX how many hex digits in an intmax_t? */
 	char *p_top;
 	const hex_state_t *p_state;
+	bool p_starts_0x;
 	hex_emitter_t p_emitter;
 	void *p_arg;
 };
@@ -163,14 +177,21 @@ typedef enum {
 	  KIND_NONE = 0
 	, KIND_INTMAX_DEC
 	, KIND_INTMAX_HEX
+	, KIND_INTMAX_0xHEX
 	, KIND_STRING
 } clocc_kind_t;
 
+typedef enum {
+	  QUAL_NONE = 0 
+	, QUAL_ALLCAPS
+} clocc_qual_t;
+
 typedef struct clocc {
 	int column;
 	int first;
 	int last;
 	clocc_kind_t kind;
+	clocc_qual_t qual;
 	union {
 		intmax_t u_intmax;
 		uintmax_t u_uintmax;
@@ -270,10 +291,14 @@ hex_op_string(hex_op_t op)
 		return "none";
 	case HEX_OP_EMIT:
 		return "emit";
+	case HEX_OP_0xEMIT:
+		return "0xemit";
 	case HEX_OP_PUSH:
 		return "push";
 	case HEX_OP_START:
 		return "start";
+	case HEX_OP_0xSTART:
+		return "0xstart";
 	default:
 		return "unknown";
 	}
@@ -284,6 +309,7 @@ hex_parser_drive(hex_parser_t *p, int id
 {
 	const hex_transition_t *t;
 	const hex_state_t *ns, *s;
+	bool use0x = false;
 
 	s = p->p_state;
 
@@ -313,6 +339,11 @@ hex_parser_drive(hex_parser_t *p, int id
 	}
 
 	switch (t->t_op) {
+	case HEX_OP_START:
+		p->p_column.start = column;
+		p->p_idx.start = idx;
+		p->p_top = &p->p_digits[0];
+		/*FALLTHROUGH*/
 	case HEX_OP_PUSH:
 		if (p->p_top == NULL)
 			;
@@ -323,21 +354,24 @@ hex_parser_drive(hex_parser_t *p, int id
 			*p->p_top = c;
 			p->p_top++;
 		}
-		p->p_idx.stop = idx;
 		p->p_column.stop = column;
+		p->p_idx.stop = idx;
 		break;
-	case HEX_OP_START:
-		p->p_column.start = column;
-		p->p_column.stop = column + 1;
-		p->p_idx.start = idx;
-		p->p_idx.stop = idx + 1;
+	case HEX_OP_0xSTART:
+		p->p_column.start = column - 1;
+		p->p_column.stop = column;
+		p->p_idx.start = idx - 1;
+		p->p_idx.stop = idx;
 		p->p_top = &p->p_digits[0];
 		break;
+	case HEX_OP_0xEMIT:
+		use0x = true;
+		/*FALLTHROUGH*/
 	case HEX_OP_EMIT:
 		if (p->p_top == NULL)
 			dbg_printf("hex string too long\n");
 		*p->p_top = '\0';
-		(*p->p_emitter)(p, p->p_arg);
+		(*p->p_emitter)(p, p->p_arg, use0x);
 		break;
 	case HEX_OP_NONE:
 		break;
@@ -626,17 +660,18 @@ cloccs_to_column(const clocc_t * const a
 }
 
 static chain_t *
-hex_clocc(const scratch_t *scratch, int idx_a, int idx_b)
+hex_clocc(const scratch_t *scratch, int idx_a, int idx_b, clocc_kind_t kind,
+    clocc_qual_t qual)
 {
-	char *ret;
-	int column;
+	char *buf;
+	int column, rc;
 	uintmax_t result;
 	const clocc_t * const a = &scratch->Aoccs.occs[idx_a],
 	              * const b = &scratch->Boccs.occs[idx_b];
 
 	column = cloccs_to_column(a, b);
 
-	dbg2_printf("%#jx @ %d / %#jx @ %d -> column %d\n",
+	dbg2_printf("0x%jx @ %d / 0x%jx @ %d -> column %d\n",
 	    a->val_u.u_uintmax, a->column,
 	    b->val_u.u_uintmax, b->column, column);
 
@@ -645,10 +680,19 @@ hex_clocc(const scratch_t *scratch, int 
 	else
 		result = b->val_u.u_uintmax | a->val_u.u_uintmax;
 
-	if (result == 0)
+	if (result == 0 && kind == KIND_INTMAX_0xHEX)
 		return newchain(strdup("0x0"), column);
-	if (asprintf(&ret, "%#jx", result) != -1)
-		return newchain(ret, column);
+
+	if (qual == QUAL_ALLCAPS) {
+		rc = asprintf(&buf,
+		    (kind == KIND_INTMAX_0xHEX) ? "0x%jX" : "%jX", result);
+	} else {
+		rc = asprintf(&buf,
+		    (kind == KIND_INTMAX_0xHEX) ? "0x%jx" : "%jx", result);
+	}
+	
+	if (rc != -1)
+		return newchain(buf, column);
 
 	return newchain(strdup("<hexmax>"), column);
 }
@@ -688,8 +732,10 @@ clocc(const scratch_t *scratch, int idx_
 	if (a->kind != b->kind)
 		return newchain(strdup("<clocc>"), 0);
 
-	if (b->kind == KIND_INTMAX_HEX)
-		return hex_clocc(scratch, idx_a, idx_b);
+	if (b->kind == KIND_INTMAX_0xHEX || b->kind == KIND_INTMAX_HEX) {
+		return hex_clocc(scratch, idx_a, idx_b, b->kind,
+		    (a->qual == b->qual) ? b->qual : QUAL_NONE);
+	}
 
 	if (b->kind == KIND_INTMAX_DEC)
 		return int_clocc(scratch, idx_a, idx_b);
@@ -760,10 +806,11 @@ algb(const slice_t *A, const slice_t *B,
 			if (clocc_ends_this_row &&
 			    clocc_ends_in_slice_at(&scratch->Boccs,
 			                          scratch->Bbasis, B, j,
-						  &wlen.B, &kind.B) && kind.A == kind.B) {
+						  &wlen.B, &kind.B) &&
+			    kind.A == kind.B && /* match kind */
+			    wlen.B <= j + 1 /* must not begin outside of B */) {
 				const size_t step = wlen.A * wlen.B + 1,
 				             nscore = Kclocc[j - wlen.B] + step;
-				assert(wlen.B <= j + 1);
 				dbg_printf("%s visits clocc boundary at A[%d] "
 				    "and B[%d] step %zu\n", __func__,
 				    index_versus_basis(scratch->Abasis, A, i),
@@ -1150,13 +1197,20 @@ slicestr(slice_t *s, const char *t)
 }
 
 static void
-emit_hex_clocc(hex_parser_t *p, void *arg)
+emit_hex_clocc(hex_parser_t *p, void *arg, bool use0x)
 {
 	cloccs_t *o = arg;
 	intmax_t val;
 	char *end;
+	bool allcaps;
 
-	dbg_printf("found hex string %s\n", p->p_digits);
+	if (!use0x && strspn(p->p_digits, "0123456789") == strlen(p->p_digits))
+		return;
+
+	allcaps = strcspn(p->p_digits, "abcdef") == strlen(p->p_digits);
+
+	dbg_printf("found hex string %s @ [%d, %d]%s\n", p->p_digits,
+	    p->p_idx.start, p->p_idx.stop, allcaps ? " all CAPS" : "");
 
 	if (o->noccs >= (int)__arraycount(o->occs))
 		return;
@@ -1166,14 +1220,13 @@ emit_hex_clocc(hex_parser_t *p, void *ar
 	if (*end != '\0' && errno == ERANGE)
 		warnx("%s: over/underflow at %d", __func__, p->p_column.start);
 
-#if 1
 	o->occs[o->noccs].column = p->p_column.start;
 	o->occs[o->noccs].first = p->p_idx.start;
 	o->occs[o->noccs].last = p->p_idx.stop;
-	o->occs[o->noccs].kind = KIND_INTMAX_HEX;
+	o->occs[o->noccs].kind = use0x ? KIND_INTMAX_0xHEX : KIND_INTMAX_HEX;
+	o->occs[o->noccs].qual = allcaps ? QUAL_ALLCAPS : QUAL_NONE;
 	o->occs[o->noccs].val_u.u_uintmax = val;
 	o->noccs++;
-#endif
 }
 
 static int

Reply via email to