mumble

A Lisp written in C, following the *Build Your Own Lisp* book
Log | Files | Refs | README

regex.c (5616B)


      1 #include "ptest.h"
      2 #include "../mpc.h"
      3 
      4 #include <string.h>
      5 #include <stdlib.h>
      6 
      7 static int string_eq(const void* x, const void* y) { return (strcmp(x, y) == 0); }
      8 static void string_print(const void* x) { printf("'%s'", (char*)x); }
      9 
     10 int regex_test_pass(mpc_parser_t *p, const char* value, const char* match) {
     11   return mpc_test_pass(p, value, match, string_eq, free, string_print);
     12 }
     13 
     14 int regex_test_fail(mpc_parser_t *p, const char* value, const char* match) {
     15   return mpc_test_fail(p, value, match, string_eq, free, string_print);
     16 }
     17 
     18 void test_regex_basic(void) {
     19 
     20   mpc_parser_t *re0, *re1, *re2, *re3, *re4, *re5;
     21 
     22   re0 = mpc_re("abc|bcd");
     23   re1 = mpc_re("abc|bcd|e");
     24   re2 = mpc_re("ab()c(ab)*");
     25   re3 = mpc_re("abc(abdd)?");
     26   re4 = mpc_re("ab|c(abdd)?");
     27   re5 = mpc_re("abc(ab|dd)+g$");
     28 
     29   PT_ASSERT(regex_test_pass(re0, "abc", "abc"));
     30   PT_ASSERT(regex_test_pass(re0, "bcd", "bcd"));
     31   PT_ASSERT(regex_test_fail(re0, "bc", "bc"));
     32   PT_ASSERT(regex_test_fail(re0, "ab", "ab"));
     33   PT_ASSERT(regex_test_pass(re1, "e", "e"));
     34   PT_ASSERT(regex_test_pass(re2, "abc", "abc"));
     35   PT_ASSERT(regex_test_pass(re2, "abcabab", "abcabab"));
     36   PT_ASSERT(regex_test_pass(re2, "abcababd", "abcabab"));
     37   PT_ASSERT(regex_test_pass(re5, "abcddg", "abcddg"));
     38 
     39   mpc_delete(re0);
     40   mpc_delete(re1);
     41   mpc_delete(re2);
     42   mpc_delete(re3);
     43   mpc_delete(re4);
     44   mpc_delete(re5);
     45 
     46 }
     47 
     48 void test_regex_boundary(void) {
     49 
     50   mpc_parser_t *re0, *re1, *re2;
     51 
     52   re0 = mpc_re("\\bfoo\\b");
     53   re1 = mpc_re("(w| )?\\bfoo\\b");
     54   re2 = mpc_re("py\\B.*");
     55 
     56   PT_ASSERT(regex_test_pass(re0, "foo", "foo"));
     57   PT_ASSERT(regex_test_pass(re0, "foo.", "foo"));
     58   PT_ASSERT(regex_test_pass(re0, "foo)", "foo"));
     59   PT_ASSERT(regex_test_pass(re0, "foo baz", "foo"));
     60 
     61   PT_ASSERT(regex_test_fail(re0, "foobar", "foo"));
     62   PT_ASSERT(regex_test_fail(re0, "foo3", "foo"));
     63 
     64   PT_ASSERT(regex_test_pass(re1, "foo", "foo"));
     65   PT_ASSERT(regex_test_pass(re1, " foo", " foo"));
     66   PT_ASSERT(regex_test_fail(re1, "wfoo", "foo"));
     67 
     68   PT_ASSERT(regex_test_pass(re2, "python", "python"));
     69   PT_ASSERT(regex_test_pass(re2, "py3", "py3"));
     70   PT_ASSERT(regex_test_pass(re2, "py2", "py2"));
     71   PT_ASSERT(regex_test_fail(re2, "py", "py"));
     72   PT_ASSERT(regex_test_fail(re2, "py.", "py."));
     73   PT_ASSERT(regex_test_fail(re2, "py!", "py!"));
     74 
     75   mpc_delete(re0);
     76   mpc_delete(re1);
     77   mpc_delete(re2);
     78 
     79 }
     80 
     81 void test_regex_range(void) {
     82 
     83   mpc_parser_t *re0, *re1, *re2, *re3;
     84 
     85   re0 = mpc_re("abg[abcdef]");
     86   re1 = mpc_re("y*[a-z]");
     87   re2 = mpc_re("zz(p+)?[A-Z_0\\]123]*");
     88   re3 = mpc_re("^[^56hy].*$");
     89 
     90   /* TODO: Testing */
     91 
     92   mpc_delete(re0);
     93   mpc_delete(re1);
     94   mpc_delete(re2);
     95   mpc_delete(re3);
     96 
     97 }
     98 
     99 void test_regex_string(void) {
    100 
    101   mpc_parser_t *re0 = mpc_re("\"(\\\\.|[^\"])*\"");
    102 
    103   PT_ASSERT(regex_test_pass(re0, "\"there\"", "\"there\""));
    104   PT_ASSERT(regex_test_pass(re0, "\"hello\"", "\"hello\""));
    105   PT_ASSERT(regex_test_pass(re0, "\"i am dan\"", "\"i am dan\""));
    106   PT_ASSERT(regex_test_pass(re0, "\"i a\\\"m dan\"", "\"i a\\\"m dan\""));
    107 
    108   mpc_delete(re0);
    109 
    110 }
    111 
    112 void test_regex_lisp_comment(void) {
    113 
    114   mpc_parser_t *re0 = mpc_re(";[^\\n\\r]*");
    115 
    116   PT_ASSERT(regex_test_pass(re0, ";comment", ";comment"));
    117   PT_ASSERT(regex_test_pass(re0, ";i am the\nman", ";i am the"));
    118 
    119   mpc_delete(re0);
    120 
    121 }
    122 
    123 void test_regex_newline(void) {
    124 
    125   mpc_parser_t *re0 = mpc_re("[a-z]*");
    126 
    127   PT_ASSERT(regex_test_pass(re0, "hi", "hi"));
    128   PT_ASSERT(regex_test_pass(re0, "hi\nk", "hi"));
    129   PT_ASSERT(regex_test_fail(re0, "hi\nk", "hi\nk"));
    130 
    131   mpc_delete(re0);
    132 
    133 }
    134 
    135 void test_regex_multiline(void) {
    136 
    137   mpc_parser_t *re0 = mpc_re_mode("(^[a-z]*$)*", MPC_RE_MULTILINE);
    138 
    139   PT_ASSERT(regex_test_pass(re0, "hello\nhello", "hello\nhello"));
    140   PT_ASSERT(regex_test_pass(re0, "hello\nhello\n", "hello\nhello\n"));
    141   PT_ASSERT(regex_test_pass(re0, "\nblah\n\nblah\n", "\nblah\n\nblah\n"));
    142   PT_ASSERT(regex_test_fail(re0, "45234", "45234"));
    143   PT_ASSERT(regex_test_fail(re0, "\n45234", "\n45234"));
    144   PT_ASSERT(regex_test_pass(re0, "\n45234", "\n"));
    145 
    146   mpc_delete(re0);
    147 
    148 }
    149 
    150 void test_regex_dotall(void) {
    151 
    152   mpc_parser_t *re0 = mpc_re_mode("^.*$", MPC_RE_DEFAULT);
    153   mpc_parser_t *re1 = mpc_re_mode("^.*$", MPC_RE_DOTALL);
    154 
    155   PT_ASSERT(regex_test_pass(re0, "hello", "hello"));
    156   PT_ASSERT(regex_test_fail(re0, "hello\n", "hello"));
    157   PT_ASSERT(regex_test_fail(re0, "he\nllo\n", "he"));
    158   PT_ASSERT(regex_test_pass(re0, "34njaksdklmasd", "34njaksdklmasd"));
    159   PT_ASSERT(regex_test_fail(re0, "34njaksd\nklmasd", "34njaksd"));
    160 
    161   PT_ASSERT(regex_test_pass(re1, "hello", "hello"));
    162   PT_ASSERT(regex_test_pass(re1, "hello\n", "hello\n"));
    163   PT_ASSERT(regex_test_pass(re1, "he\nllo\n", "he\nllo\n"));
    164   PT_ASSERT(regex_test_pass(re1, "34njaksdklmasd", "34njaksdklmasd"));
    165   PT_ASSERT(regex_test_pass(re1, "34njaksd\nklmasd", "34njaksd\nklmasd"));
    166 
    167   mpc_delete(re0);
    168   mpc_delete(re1);
    169 
    170 }
    171 
    172 void suite_regex(void) {
    173   pt_add_test(test_regex_basic, "Test Regex Basic", "Suite Regex");
    174   pt_add_test(test_regex_range, "Test Regex Range", "Suite Regex");
    175   pt_add_test(test_regex_string, "Test Regex String", "Suite Regex");
    176   pt_add_test(test_regex_lisp_comment, "Test Regex Lisp Comment", "Suite Regex");
    177   pt_add_test(test_regex_boundary, "Test Regex Boundary", "Suite Regex");
    178   pt_add_test(test_regex_newline, "Test Regex Newline", "Suite Regex");
    179   pt_add_test(test_regex_multiline, "Test Regex Multiline", "Suite Regex");
    180   pt_add_test(test_regex_dotall, "Test Regex Dotall", "Suite Regex");
    181 }