From 78266af453d5d9e72235a5c7acc8d3641550f6e3 Mon Sep 17 00:00:00 2001
From: "Sven M. Hallberg" <pesco@khjk.org>
Date: Fri, 23 Jan 2015 22:06:43 +0100
Subject: [PATCH] allow h_bind's function argument to return NULL as a shortcut
 for h_nothing_p()

---
 src/hammer.h       |  2 +-
 src/parsers/bind.c |  3 +++
 src/t_parser.c     | 29 ++++++++++++++++++-----------
 3 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/src/hammer.h b/src/hammer.h
index 716ab6d0..c974e1fd 100644
--- a/src/hammer.h
+++ b/src/hammer.h
@@ -675,7 +675,7 @@ HAMMER_FN_DECL(HParser*, h_get_value, const char* name);
  * Sequencing where later parsers may depend on the result(s) of earlier ones.
  *
  * Run p and call the result x. Then run k(env,x).  Fail if p fails or if
- * k(env,x) fails.
+ * k(env,x) fails or if k(env,x) is NULL.
  *
  * Result: the result of k(x,env).
  */
diff --git a/src/parsers/bind.c b/src/parsers/bind.c
index ccbf6da8..de0a8ec6 100644
--- a/src/parsers/bind.c
+++ b/src/parsers/bind.c
@@ -14,6 +14,9 @@ static HParseResult *parse_bind(void *be_, HParseState *state) {
         return NULL;
 
     HParser *kx = be->k(res->ast, be->env);
+    if(!kx)
+        return NULL;
+
     return h_do_parse(kx, state);
 }
 
diff --git a/src/t_parser.c b/src/t_parser.c
index 25495e34..c16e3840 100644
--- a/src/t_parser.c
+++ b/src/t_parser.c
@@ -569,18 +569,23 @@ static void test_permutation(gconstpointer backend) {
 }
 
 static HParser *f_test_bind(const HParsedToken *p, void *env) {
-	uint8_t one = (uintptr_t)env;
-	
-	assert(p);
-	assert(p->token_type == TT_SEQUENCE);
-
-	int v=0;
-	for(size_t i=0; i<p->seq->used; i++) {
-		assert(p->seq->elements[i]->token_type == TT_UINT);
-		v = v*10 + p->seq->elements[i]->uint - '0';
-	}
+  uint8_t one = (uintptr_t)env;
+  
+  assert(p);
+  assert(p->token_type == TT_SEQUENCE);
+
+  int v=0;
+  for(size_t i=0; i<p->seq->used; i++) {
+    assert(p->seq->elements[i]->token_type == TT_UINT);
+    v = v*10 + p->seq->elements[i]->uint - '0';
+  }
 
-	return h_ch(one - 1 + v);
+  if(v > 26)
+    return h_nothing_p();	// fail
+  else if(v > 127)
+    return NULL;		// equivalent to the above
+  else
+    return h_ch(one - 1 + v);
 }
 static void test_bind(gconstpointer backend) {
   HParserBackend be = (HParserBackend)GPOINTER_TO_INT(backend);
@@ -594,6 +599,8 @@ static void test_bind(gconstpointer backend) {
   g_check_parse_failed(p, be, "1x", 2);
   g_check_parse_failed(p, be, "29y", 3);
   g_check_parse_failed(p, be, "@", 1);
+  g_check_parse_failed(p, be, "27{", 3);
+  g_check_parse_failed(p, be, "272{", 4);
 }
 
 void register_parser_tests(void) {
-- 
GitLab