ematch related bugfix and cleanup

Bugfix: use strtoul rather than strtol for bstrtol to handle large key/mask.
Deinline larger functions to save space.
diff --git a/tc/m_ematch.c b/tc/m_ematch.c
index da4f22b..7065fd0 100644
--- a/tc/m_ematch.c
+++ b/tc/m_ematch.c
@@ -491,3 +491,80 @@
 
 	return print_ematch_list(fd, hdr, tb[TCA_EMATCH_TREE_LIST]);
 }
+
+struct bstr * bstr_alloc(const char *text)
+{
+	struct bstr *b = calloc(1, sizeof(*b));
+
+	if (b == NULL)
+		return NULL;
+
+	b->data = strdup(text);
+	if (b->data == NULL) {
+		free(b);
+		return NULL;
+	}
+
+	b->len = strlen(text);
+
+	return b;
+}
+
+unsigned long bstrtoul(const struct bstr *b)
+{
+	char *inv = NULL;
+	unsigned long l;
+	char buf[b->len+1];
+
+	memcpy(buf, b->data, b->len);
+	buf[b->len] = '\0';
+
+	l = strtoul(buf, &inv, 0);
+	if (l == ULONG_MAX || inv == buf)
+		return ULONG_MAX;
+
+	return l;
+}
+
+void bstr_print(FILE *fd, const struct bstr *b, int ascii)
+{
+	int i;
+	char *s = b->data;
+
+	if (ascii)
+		for (i = 0; i < b->len; i++)
+		    fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.');
+	else {
+		for (i = 0; i < b->len; i++)
+		    fprintf(fd, "%02x", s[i]);
+		fprintf(fd, "\"");
+		for (i = 0; i < b->len; i++)
+		    fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.');
+		fprintf(fd, "\"");
+	}
+}
+
+void print_ematch_tree(const struct ematch *tree)
+{
+	const struct ematch *t;
+
+	for (t = tree; t; t = t->next) {
+		if (t->inverted)
+			printf("NOT ");
+
+		if (t->child) {
+			printf("(");
+			print_ematch_tree(t->child);
+			printf(")");
+		} else {
+			struct bstr *b;
+			for (b = t->args; b; b = b->next)
+				printf("%s%s", b->data, b->next ? " " : "");
+		}
+
+		if (t->relation == TCF_EM_REL_AND)
+			printf(" AND ");
+		else if (t->relation == TCF_EM_REL_OR)
+			printf(" OR ");
+	}
+}
diff --git a/tc/m_ematch.h b/tc/m_ematch.h
index 2b5d293..5036e9b 100644
--- a/tc/m_ematch.h
+++ b/tc/m_ematch.h
@@ -18,23 +18,7 @@
 	struct bstr	*next;
 };
 
-static inline struct bstr * bstr_alloc(const char *text)
-{
-	struct bstr *b = calloc(1, sizeof(*b));
-
-	if (b == NULL)
-		return NULL;
-
-	b->data = strdup(text);
-	if (b->data == NULL) {
-		free(b);
-		return NULL;
-	}
-
-	b->len = strlen(text);
-
-	return b;
-}
+extern struct bstr * bstr_alloc(const char *text);
 
 static inline struct bstr * bstr_new(char *data, unsigned int len)
 {
@@ -60,45 +44,15 @@
 	return d;
 }
 
-static inline unsigned long bstrtoul(struct bstr *b)
-{
-	char *inv = NULL;
-	unsigned long l;
-	char buf[b->len+1];
-
-	memcpy(buf, b->data, b->len);
-	buf[b->len] = '\0';
-
-	l = strtol(buf, &inv, 0);
-	if (l == ULONG_MAX || inv == buf)
-		return LONG_MAX;
-
-	return l;
-}
-
-static inline void bstr_print(FILE *fd, struct bstr *b, int ascii)
-{
-	int i;
-	char *s = b->data;
-
-	if (ascii)
-		for (i = 0; i < b->len; i++)
-		    fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.');
-	else {
-		for (i = 0; i < b->len; i++)
-		    fprintf(fd, "%02x", s[i]);
-		fprintf(fd, "\"");
-		for (i = 0; i < b->len; i++)
-		    fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.');
-		fprintf(fd, "\"");
-	}
-}
-
 static inline struct bstr *bstr_next(struct bstr *b)
 {
 	return b->next;
 }
 
+extern unsigned long bstrtoul(const struct bstr *b);
+extern void bstr_print(FILE *fd, const struct bstr *b, int ascii);
+
+
 struct ematch
 {
 	struct bstr	*args;
@@ -123,30 +77,8 @@
 	return e;
 }
 
-static inline void print_ematch_tree(struct ematch *tree)
-{
-	struct ematch *t;
+extern void print_ematch_tree(const struct ematch *tree);
 
-	for (t = tree; t; t = t->next) {
-		if (t->inverted)
-			printf("NOT ");
-
-		if (t->child) {
-			printf("(");
-			print_ematch_tree(t->child);
-			printf(")");
-		} else {
-			struct bstr *b;
-			for (b = t->args; b; b = b->next)
-				printf("%s%s", b->data, b->next ? " " : "");
-		}
-
-		if (t->relation == TCF_EM_REL_AND)
-			printf(" AND ");
-		else if (t->relation == TCF_EM_REL_OR)
-			printf(" OR ");
-	}
-}
 
 struct ematch_util
 {