Regex tests
This commit is contained in:
		| @@ -75,7 +75,7 @@ mpc_ast_t* parse_maths(const char* input) { | ||||
|  | ||||
| If you were to input something like `"(4 * 2 * 11 + 2) - 5"` into this function the `mpc_ast_t` you get out would look something like this: | ||||
|  | ||||
| ```c | ||||
| ```python | ||||
| >: | ||||
|   value|>: | ||||
|     char: '(' | ||||
|   | ||||
							
								
								
									
										61
									
								
								mpc.c
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								mpc.c
									
									
									
									
									
								
							| @@ -1804,11 +1804,12 @@ static mpc_val_t* mpcf_re_repeat(int n, mpc_val_t** xs) { | ||||
|   return mpc_count(num, mpcf_strfold, xs[0], free); | ||||
| } | ||||
|  | ||||
| static mpc_parser_t* mpc_re_escape_char(char c, int range) { | ||||
| static mpc_parser_t* mpc_re_escape_char(char c) { | ||||
|   switch (c) { | ||||
|     case 'a': return mpc_char('\a'); | ||||
|     case 'f': return mpc_char('\f'); | ||||
|     case 'n': return mpc_char('\n'); | ||||
|     case 'r': return mpc_char('\r'); | ||||
|     case 't': return mpc_char('\t'); | ||||
|     case 'v': return mpc_char('\v'); | ||||
|     case 'b': return mpc_char('\b'); | ||||
| @@ -1836,7 +1837,7 @@ static mpc_val_t* mpcf_re_escape(mpc_val_t* x) { | ||||
|    | ||||
|   /* Regex Escape */ | ||||
|   if (s[0] == '\\') { | ||||
|     p = mpc_re_escape_char(s[1], 0); | ||||
|     p = mpc_re_escape_char(s[1]); | ||||
|     p = (p == NULL) ? mpc_char(s[1]) : p; | ||||
|     free(s); | ||||
|     return p; | ||||
| @@ -1848,18 +1849,35 @@ static mpc_val_t* mpcf_re_escape(mpc_val_t* x) { | ||||
|   return p; | ||||
| } | ||||
|  | ||||
| static char* mpc_re_range_escape_char(char c) { | ||||
|   switch (c) { | ||||
|     case '-': return "-"; | ||||
|     case 'a': return "\a"; | ||||
|     case 'f': return "\f"; | ||||
|     case 'n': return "\n"; | ||||
|     case 'r': return "\r"; | ||||
|     case 't': return "\t"; | ||||
|     case 'v': return "\v"; | ||||
|     case 'b': return "\b"; | ||||
|     case 'd': return "0123456789"; | ||||
|     case 's': return " \f\n\r\t\v"; | ||||
|     case 'w': return "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; | ||||
|     default: return NULL; | ||||
|   } | ||||
| } | ||||
|  | ||||
| static mpc_val_t* mpcf_re_range(mpc_val_t* x) { | ||||
|      | ||||
|   char* range = calloc(1,1); | ||||
|   char* tmp = NULL; | ||||
|   char* s = x; | ||||
|   int i = 0; | ||||
|   char start, end; | ||||
|   int i, j; | ||||
|   int comp = 0; | ||||
|    | ||||
|   mpc_parser_t* q = NULL; | ||||
|   mpc_parser_t* p = mpc_failf("Invalid Range Specifier"); | ||||
|    | ||||
|   if (s[0] == '\0') { free(x); return p; }  | ||||
|   if (s[0] == '\0') { free(x); return mpc_fail("Invalid Regex Range Expression"); }  | ||||
|   if (s[0] == '^' &&  | ||||
|       s[1] == '\0') { free(x); return p; } | ||||
|       s[1] == '\0') { free(x); return mpc_fail("Invalid Regex Range Expression"); } | ||||
|    | ||||
|   if (s[0] == '^') { comp = 1;} | ||||
|    | ||||
| @@ -1867,28 +1885,41 @@ static mpc_val_t* mpcf_re_range(mpc_val_t* x) { | ||||
|      | ||||
|     /* Regex Range Escape */ | ||||
|     if (s[i] == '\\') { | ||||
|       q = mpc_re_escape_char(s[i+1], 1); | ||||
|       q = (q == NULL) ? mpc_char(s[i+1]) : q; | ||||
|       p = mpc_or(2, p, q); | ||||
|       tmp = mpc_re_range_escape_char(s[i+1]); | ||||
|       if (tmp != NULL) { | ||||
|         range = realloc(range, strlen(range) + strlen(tmp) + 1); | ||||
|         strcat(range, tmp); | ||||
|       } | ||||
|       i++; | ||||
|     } | ||||
|      | ||||
|     /* Regex Range...Range */ | ||||
|     else if (s[i] == '-') { | ||||
|       if (s[i+1] == '\0' || i == 0) { | ||||
|         p = mpc_or(2, p, mpc_char('-')); | ||||
|           range = realloc(range, strlen(range) + strlen("-") + 1); | ||||
|           strcat(range, "-"); | ||||
|       } else { | ||||
|         p = mpc_or(2, p, mpc_range(s[i-1]+1, s[i+1]-1)); | ||||
|         start = s[i-1]+1; | ||||
|         end = s[i+1]-1; | ||||
|         for (j = start; j <= end; j++) { | ||||
|           range = realloc(range, strlen(range) + 1 + 1); | ||||
|           range[strlen(range) + 1] = '\0'; | ||||
|           range[strlen(range) + 0] = j; | ||||
|         }         | ||||
|       } | ||||
|     } | ||||
|      | ||||
|     /* Regex Range Normal */ | ||||
|     else { p = mpc_or(2, p, mpc_char(s[i])); } | ||||
|     else { | ||||
|       range = realloc(range, strlen(range) + 1 + 1); | ||||
|       range[strlen(range) + 1] = '\0'; | ||||
|       range[strlen(range) + 0] = s[i]; | ||||
|     } | ||||
|    | ||||
|   } | ||||
|    | ||||
|   free(x); | ||||
|   return comp ? mpc_not_lift(p, free, mpcf_ctor_str) : p; | ||||
|   return comp ? mpc_noneof(range) : mpc_oneof(range); | ||||
| } | ||||
|  | ||||
| static mpc_val_t* mpcf_re_invalid(void) { | ||||
|   | ||||
| @@ -9,7 +9,7 @@ static void string_print(void* x) { printf("'%s'", (char*)x); } | ||||
|  | ||||
| void test_regex_basic(void) { | ||||
|  | ||||
|   mpc_parser_t *re0, *re1, *re2, *re3, *re4, *re5; | ||||
|   mpc_parser_t *re0, *re1, *re2, *re3, *re4, *re5, *re6, *re7; | ||||
|  | ||||
|   re0 = mpc_re("abc|bcd"); | ||||
|   re1 = mpc_re("abc|bcd|e"); | ||||
| @@ -17,6 +17,8 @@ void test_regex_basic(void) { | ||||
|   re3 = mpc_re("abc(abdd)?"); | ||||
|   re4 = mpc_re("ab|c(abdd)?"); | ||||
|   re5 = mpc_re("abc(ab|dd)+g$"); | ||||
|   re6 = mpc_re("\"(\\\\.|[^\"])*\""); | ||||
|   re7 = mpc_re(";[^\\n\\r]*"); | ||||
|    | ||||
|   PT_ASSERT(mpc_match(re0, "abc", "abc", string_eq, free, string_print)); | ||||
|   PT_ASSERT(mpc_match(re0, "bcd", "bcd", string_eq, free, string_print)); | ||||
| @@ -26,7 +28,13 @@ void test_regex_basic(void) { | ||||
|   PT_ASSERT(mpc_match(re2, "abc", "abc", string_eq, free, string_print)); | ||||
|   PT_ASSERT(mpc_match(re2, "abcabab", "abcabab", string_eq, free, string_print)); | ||||
|   PT_ASSERT(mpc_match(re2, "abcababd", "abcabab", string_eq, free, string_print)); | ||||
|   PT_ASSERT(mpc_match(re5, "abck", "", string_eq, free, string_print)); | ||||
|   PT_ASSERT(mpc_match(re5, "abcddg", "abcddg", string_eq, free, string_print)); | ||||
|   PT_ASSERT(mpc_match(re6, "\"there\"", "\"there\"", string_eq, free, string_print)); | ||||
|   PT_ASSERT(mpc_match(re6, "\"hello\"", "\"hello\"", string_eq, free, string_print)); | ||||
|   PT_ASSERT(mpc_match(re6, "\"i am dan\"", "\"i am dan\"", string_eq, free, string_print)); | ||||
|   PT_ASSERT(mpc_match(re6, "\"i a\\\"m dan\"", "\"i a\\\"m dan\"", string_eq, free, string_print)); | ||||
|   PT_ASSERT(mpc_match(re7, ";comment", ";comment", string_eq, free, string_print)); | ||||
|   PT_ASSERT(mpc_match(re7, ";i am the\nman", ";i am the", string_eq, free, string_print)); | ||||
|    | ||||
|   mpc_delete(re0); | ||||
|   mpc_delete(re1); | ||||
| @@ -34,6 +42,8 @@ void test_regex_basic(void) { | ||||
|   mpc_delete(re3); | ||||
|   mpc_delete(re4); | ||||
|   mpc_delete(re5); | ||||
|   mpc_delete(re6); | ||||
|   mpc_delete(re7); | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Daniel Holden
					Daniel Holden