OSDN Git Service

* Added sibling selectors parser.
authorkonn <konn@1a406e8e-add9-4483-a2c8-d8cac5b7c224>
Wed, 11 Jun 2008 01:06:42 +0000 (01:06 +0000)
committerkonn <konn@1a406e8e-add9-4483-a2c8-d8cac5b7c224>
Wed, 11 Jun 2008 01:06:42 +0000 (01:06 +0000)
git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/modchxj/mod_chxj/branches/sandbox@2705 1a406e8e-add9-4483-a2c8-d8cac5b7c224

include/qs_parse_string.h
src/chxj_css.c
src/qs_parse_string.c
test/chxj_css/test_chxj_css.c

index b7c2b4e..8f08f4a 100644 (file)
@@ -110,6 +110,7 @@ typedef struct Node Node;
 struct Node {
   struct Node   *next;
   struct Node   *parent;
+  struct Node   *prev;
   struct Node   *child;
   struct Node   *child_tail;
   struct Attr   *attr;
@@ -192,8 +193,9 @@ extern char* qs_get_node_name(
 
 extern int qs_get_node_size(Doc* doc, Node* node) ;
 
-extern Node *qs_get_child_node(Doc *doc, Node *node) ;
-extern Node *qs_get_next_node(Doc *doc, Node *node) ;
+extern Node *qs_get_child_node(Doc *doc, Node *node);
+extern Node *qs_get_next_node(Doc *doc, Node *node);
+extern Node *qs_get_prev_node(Doc *doc, Node *node);
 
 Attr* qs_get_attr(Doc* doc, Node* node) ;
 Attr* qs_get_next_attr(Doc* doc, Attr* attr) ;
index 19f9ea7..155669a 100644 (file)
@@ -223,6 +223,8 @@ static css_selector_t *
 s_search_selector_regexp(Doc *doc, request_rec *r, apr_pool_t *pool, css_stylesheet_t *stylesheet, const char *pattern_str1, const char *pattern_str2, Node *node)
 {
   Node *node_sv = node;
+  Node *sib_node = NULL;
+  css_selector_t *ret_sel = NULL;
   css_selector_t *tail;
   css_selector_t *cur;
   DBG(r, "pattern1:[%s]", pattern_str1);
@@ -230,7 +232,7 @@ s_search_selector_regexp(Doc *doc, request_rec *r, apr_pool_t *pool, css_stylesh
   ap_regex_t *pattern1 = chxj_ap_pregcomp(pool, pattern_str1, AP_REG_EXTENDED|AP_REG_ICASE);
   ap_regex_t *pattern2 = chxj_ap_pregcomp(pool, pattern_str2, AP_REG_EXTENDED|AP_REG_ICASE);
   ap_regex_t *pattern3 = chxj_ap_pregcomp(pool, "^.*([>+ ])([^>+ ]+?)$", AP_REG_EXTENDED|AP_REG_ICASE);
-  ap_regex_t *pattern4 = chxj_ap_pregcomp(pool, "^([^.#]+?)(\\.[^#]+?)?(#.+?)?$", AP_REG_EXTENDED|AP_REG_ICASE);
+  ap_regex_t *pattern4 = chxj_ap_pregcomp(pool, "^([^.#]+?)?(\\.[^#]+?)?(#.+?)?$", AP_REG_EXTENDED|AP_REG_ICASE);
                               
   tail = (css_selector_t *)((apr_size_t)stylesheet->selector_head.ref - (apr_size_t)APR_OFFSETOF(css_selector_t, next));
   for (cur = tail; 
@@ -240,7 +242,8 @@ s_search_selector_regexp(Doc *doc, request_rec *r, apr_pool_t *pool, css_stylesh
     DBG(r, "cur->name:[%s]", cur->name);
     if (chxj_ap_regexec(pattern1, cur->name, pattern1->re_nsub + 1, match, 0) == 0) {
       DBG(r, "match(independent of)");
-      return cur;
+      ret_sel = cur;
+      goto end_of_search;
     }
     else 
     if (chxj_ap_regexec(pattern2, cur->name, pattern2->re_nsub + 1, match, 0) == 0) {
@@ -250,7 +253,6 @@ s_search_selector_regexp(Doc *doc, request_rec *r, apr_pool_t *pool, css_stylesh
       int loop = 0;
       do {
         DBG(r, "start do while");
-        node = node->parent;
         *strrchr(src, *one) = 0;
         switch (*one) {
         case '>': /* Child selectors */
@@ -258,38 +260,81 @@ s_search_selector_regexp(Doc *doc, request_rec *r, apr_pool_t *pool, css_stylesh
           if (chxj_ap_regexec(pattern3, src, pattern3->re_nsub + 1, match, 0) == 0) {
             DBG(r, "has any parent");
             one = chxj_ap_pregsub(pool, "$1",src, pattern3->re_nsub + 1, match);
-            char *ret = s_cmp_now_node_vs_current_style(doc, r, pool, strrchr(src, *one)+1, pattern4, node);
+            char *ret = s_cmp_now_node_vs_current_style(doc, r, pool, strrchr(src, *one)+1, pattern4, node->parent);
             if (ret) {
               DBG(r, "continue do while");
+              node = node->parent;
               loop = 1;
             }
           }
           else {
-            DBG(r, "parent:[%x]", node);
-            DBG(r, "parent->name:[%s] src:[%s]", node->name, src);
-            char *ret = s_cmp_now_node_vs_current_style(doc, r, pool, src, pattern4, node);
-            if (ret) return ret;
+            DBG(r, "parent:[%x]", node->parent);
+            DBG(r, "parent->name:[%s] src:[%s]", node->parent->name, src);
+            char *ret = s_cmp_now_node_vs_current_style(doc, r, pool, src, pattern4, node->parent);
+            if (ret) {
+              ret_sel = cur;
+              goto end_of_search;
+            }
             loop = 0;
           }
           break;
+
+
         case '+': /* Adjacent sibling selectors */
-          loop = 0;
+          DBG(r, "descendant selectors");
+          if (chxj_ap_regexec(pattern3, src, pattern3->re_nsub + 1, match, 0) == 0) {
+            DBG(r, "has any parent");
+            one = chxj_ap_pregsub(pool, "$1",src, pattern3->re_nsub + 1, match);
+            char *ret = s_cmp_now_node_vs_current_style(doc, r, pool, strrchr(src, *one)+1, pattern4, node->prev);
+            if (ret) {
+              DBG(r, "continue do while");
+              loop = 1;
+              if (*one == '+') {
+                if (sib_node) {
+                  sib_node = node;
+                }
+                node = node->prev;
+              }
+              else {
+                if (sib_node) {
+                  node = sib_node->parent;
+                  sib_node = NULL;
+                }
+                else {
+                  node = node->parent;
+                }
+              }
+              break;
+            }
+          }
+          else {
+            DBG(r, "prev:[%x]", node->prev);
+            DBG(r, "prev->name:[%s] src:[%s]", node->prev->name, src);
+            char *ret = s_cmp_now_node_vs_current_style(doc, r, pool, src, pattern4, node->prev);
+            if (ret) {
+              ret_sel = cur;
+              goto end_of_search;
+            }
+          }
           break;
+
+
         case ' ': /* Descendant selectors */
           DBG(r, "descendant selectors");
           if (chxj_ap_regexec(pattern3, src, pattern3->re_nsub + 1, match, 0) == 0) {
             DBG(r, "has any parent");
             one = chxj_ap_pregsub(pool, "$1",src, pattern3->re_nsub + 1, match);
-            for (; node; node = node->parent) {
-              if (strcasecmp(node->name, "ROOT") == 0) {
+            for (; node && node->parent; node = node->parent) {
+              if (strcasecmp(node->name, "ROOT") == 0 || strcasecmp(node->parent->name, "ROOT") == 0) {
                 DBG(r, "unmatch");
                 loop = 0;
                 break;
               }
-              char *ret = s_cmp_now_node_vs_current_style(doc, r, pool, strrchr(src, *one)+1, pattern4, node);
+              char *ret = s_cmp_now_node_vs_current_style(doc, r, pool, strrchr(src, *one)+1, pattern4, node->parent);
               if (ret) {
                 DBG(r, "continue do while");
                 loop = 1;
+                node = node->parent;
                 break;
               }
             }
@@ -297,14 +342,17 @@ s_search_selector_regexp(Doc *doc, request_rec *r, apr_pool_t *pool, css_stylesh
           else {
             DBG(r, "parent:[%x]", node);
             DBG(r, "parent->name:[%s] src:[%s]", node->name, src);
-            for (; node; node = node->parent) {
-              if (strcasecmp(node->name, "ROOT") == 0) {
+            for (; node && node->parent; node = node->parent) {
+              if (strcasecmp(node->name, "ROOT") == 0 || strcasecmp(node->parent->name, "ROOT") == 0) {
                 DBG(r, "unmatch");
                 loop = 0;
                 break;
               }
-              char *ret = s_cmp_now_node_vs_current_style(doc, r, pool, src, pattern4, node);
-              if (ret) return ret;
+              char *ret = s_cmp_now_node_vs_current_style(doc, r, pool, src, pattern4, node->parent);
+              if (ret) {
+                ret_sel = cur;
+                goto end_of_search;
+              }
             }
           }
           break;
@@ -317,9 +365,13 @@ s_search_selector_regexp(Doc *doc, request_rec *r, apr_pool_t *pool, css_stylesh
     }
     DBG(r, "unmatch [%s]", cur->name);
   }
+
+end_of_search:
   chxj_ap_pregfree(pool, pattern1);
   chxj_ap_pregfree(pool, pattern2);
-  return NULL;
+  chxj_ap_pregfree(pool, pattern3);
+  chxj_ap_pregfree(pool, pattern4);
+  return ret_sel;
 }
 static css_stylesheet_t *
 s_chxj_css_parse_from_uri(request_rec *r, apr_pool_t *pool, struct css_already_import_stack *imported_stack, css_stylesheet_t *old_stylesheet, const char *uri)
@@ -858,6 +910,7 @@ static char *
 s_cmp_now_node_vs_current_style(Doc *doc, request_rec *r, apr_pool_t *pool, char *src, ap_regex_t *pattern4, Node *node)
 {
   ap_regmatch_t match[256];
+  DBG(r, "src:[%s]", src);
   if (chxj_ap_regexec(pattern4, src, pattern4->re_nsub + 1, match, 0) == 0) {
     char *tag_name   = chxj_ap_pregsub(pool, "$1", src, pattern4->re_nsub + 1, match);
     char *class_name = chxj_ap_pregsub(pool, "$2", src, pattern4->re_nsub + 1, match);
@@ -871,14 +924,22 @@ s_cmp_now_node_vs_current_style(Doc *doc, request_rec *r, apr_pool_t *pool, char
     char *node_class_name = NULL;
     char *node_id_name    = NULL;
     s_get_tag_and_class_and_id(doc, node, &node_tag_name, &node_class_name, &node_id_name);
-    if (strcasecmp(node_tag_name, tag_name) == 0 || strcmp("*", tag_name) == 0) {
+    if (*tag_name == 0 || strcasecmp(node_tag_name, tag_name) == 0 || strcmp("*", tag_name) == 0) {
       if (class_name && *class_name != 0) {
+        if (!node_class_name) {
+          DBG(r, "unmatch (class) node:[NULL]");
+          return NULL;
+        }
         if (strcasecmp(node_class_name, &class_name[1]) != 0) {
           DBG(r, "unmatch (class) node:[%s] style:[%s]", node_class_name, &class_name[1]);
           return NULL;
         }
       }
       if (id_name && *id_name != 0) {
+        if (!node_id_name) {
+          DBG(r, "unmatch (id) node:[NULL]");
+          return NULL;
+        }
         if (strcasecmp(node_id_name, &id_name[1]) != 0) {
           DBG(r, "unmatch (id)");
           return NULL;
index 49ee4ac..de99415 100644 (file)
@@ -520,6 +520,7 @@ qs_init_root_node(Doc *doc)
     QX_LOGGER_FATAL("Out Of Memory");
   }
 
+  doc->root_node->prev   = NULL;
   doc->root_node->next   = NULL;
   doc->root_node->parent = NULL;
   doc->root_node->child  = NULL;
@@ -540,6 +541,7 @@ qs_init_root_node(Doc *doc)
 void
 qs_add_child_node(Doc *doc,Node *node) 
 {
+  node->prev       = NULL;
   node->next       = NULL;
   node->child      = NULL;
   node->child_tail = NULL;
@@ -552,6 +554,7 @@ qs_add_child_node(Doc *doc,Node *node)
 #ifdef DEBUG
     QX_LOGGER_DEBUG("search child free node");
 #endif
+    node->prev = doc->now_parent_node->child_tail;
     doc->now_parent_node->child_tail->next = node;
     doc->now_parent_node->child_tail       = node;
   }
@@ -592,14 +595,23 @@ qs_get_child_node(Doc *UNUSED(doc), Node *node) {
 
 
 Node *
-qs_get_next_node(Doc *UNUSED(doc), Node *node) {
+qs_get_next_node(Doc *UNUSED(doc), Node *node) 
+{
   return node->next;
 }
 
 
+Node *
+qs_get_prev_node(Doc *UNUSED(doc), Node *node) 
+{
+  return node->prev;
+}
+
+
 
 Attr *
-qs_get_attr(Doc *UNUSED(doc), Node *node) {
+qs_get_attr(Doc *UNUSED(doc), Node *node) 
+{
   return node->attr;
 }
 
index 30fc08c..5702368 100644 (file)
@@ -64,6 +64,22 @@ void test_chxj_css_find_selector_des_002();
 void test_chxj_css_find_selector_des_003();
 void test_chxj_css_find_selector_des_004();
 void test_chxj_css_find_selector_des_005();
+void test_chxj_css_find_selector_des_006();
+void test_chxj_css_find_selector_des_007();
+void test_chxj_css_find_selector_des_008();
+void test_chxj_css_find_selector_des_009();
+void test_chxj_css_find_selector_des_010();
+
+/* E + F */
+void test_chxj_css_find_selector_shib_001();
+void test_chxj_css_find_selector_shib_002();
+void test_chxj_css_find_selector_shib_003();
+void test_chxj_css_find_selector_shib_004();
+void test_chxj_css_find_selector_shib_005();
+void test_chxj_css_find_selector_shib_006();
+void test_chxj_css_find_selector_shib_007();
+void test_chxj_css_find_selector_shib_008();
+void test_chxj_css_find_selector_shib_009();
 /* pend */
 
 int
@@ -106,6 +122,21 @@ main()
   CU_add_test(css_suite, "test css find_selector with ' ' 003",             test_chxj_css_find_selector_des_003);
   CU_add_test(css_suite, "test css find_selector with ' ' 004",             test_chxj_css_find_selector_des_004);
   CU_add_test(css_suite, "test css find_selector with ' ' 005",             test_chxj_css_find_selector_des_005);
+  CU_add_test(css_suite, "test css find_selector with ' ' 006",             test_chxj_css_find_selector_des_006);
+  CU_add_test(css_suite, "test css find_selector with ' ' 007",             test_chxj_css_find_selector_des_007);
+  CU_add_test(css_suite, "test css find_selector with ' ' 008",             test_chxj_css_find_selector_des_008);
+  CU_add_test(css_suite, "test css find_selector with ' ' 009",             test_chxj_css_find_selector_des_009);
+  CU_add_test(css_suite, "test css find_selector with ' ' 010",             test_chxj_css_find_selector_des_010);
+
+  CU_add_test(css_suite, "test css find_selector with '+' 001",             test_chxj_css_find_selector_shib_001);
+  CU_add_test(css_suite, "test css find_selector with '+' 002",             test_chxj_css_find_selector_shib_002);
+  CU_add_test(css_suite, "test css find_selector with '+' 003",             test_chxj_css_find_selector_shib_003);
+  CU_add_test(css_suite, "test css find_selector with '+' 004",             test_chxj_css_find_selector_shib_004);
+  CU_add_test(css_suite, "test css find_selector with '+' 005",             test_chxj_css_find_selector_shib_005);
+  CU_add_test(css_suite, "test css find_selector with '+' 006",             test_chxj_css_find_selector_shib_006);
+  CU_add_test(css_suite, "test css find_selector with '+' 007",             test_chxj_css_find_selector_shib_007);
+  CU_add_test(css_suite, "test css find_selector with '+' 008",             test_chxj_css_find_selector_shib_008);
+  CU_add_test(css_suite, "test css find_selector with '+' 009",             test_chxj_css_find_selector_shib_009);
   /* aend */
 
   CU_basic_run_tests();
@@ -1709,6 +1740,717 @@ void test_chxj_css_find_selector_des_005()
   fprintf(stderr, "end %s\n", __func__);
 #undef TEST_STRING
 }
+
+char *test_chxj_serf_get033(request_rec *r, apr_pool_t *ppool, const char *uri_path)
+{
+  static char *css = "html,body, .def hr { display: none }";
+
+  return css;
+}
+void test_chxj_css_find_selector_des_006()
+{
+#define TEST_STRING "<html><head></head><body class=\"def\" id=\"id2\"><div class=\"def\" id=\"id2\"><div><hr class=\"abc\" id=\"id1\"></div></div></body></html>"
+  Doc doc;
+  Node *node;
+  Node *tmp_node;
+  Node *node_sv;
+  css_stylesheet_t *ret;
+  css_selector_t *sel;
+  APR_INIT;
+  chxj_serf_get = test_chxj_serf_get033;
+
+  fprintf(stderr, "start %s\n", __func__);
+  doc.r = &r;
+  qs_init_malloc(&doc);
+  qs_init_root_node(&doc);
+  doc.parse_mode = PARSE_MODE_CHTML;
+
+  node_sv = node = qs_parse_string(&doc, TEST_STRING, sizeof(TEST_STRING)-1);
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+
+  apr_uri_parse(p, "http://localhost:888/abc", &r.parsed_uri); \
+
+  ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "/hoge.css");
+  CU_ASSERT(ret != NULL);
+
+  sel = chxj_css_find_selector(&doc, ret, node);
+  CU_ASSERT(sel != NULL);
+  APR_TERM;
+  fprintf(stderr, "end %s\n", __func__);
+#undef TEST_STRING
+}
+
+char *test_chxj_serf_get034(request_rec *r, apr_pool_t *ppool, const char *uri_path)
+{
+  static char *css = "html,body, .abc hr { display: none }";
+
+  return css;
+}
+void test_chxj_css_find_selector_des_007()
+{
+#define TEST_STRING "<html><head></head><body class=\"def\" id=\"id2\"><div class=\"def\" id=\"id2\"><div><hr class=\"abc\" id=\"id1\"></div></div></body></html>"
+  Doc doc;
+  Node *node;
+  Node *tmp_node;
+  Node *node_sv;
+  css_stylesheet_t *ret;
+  css_selector_t *sel;
+  APR_INIT;
+  chxj_serf_get = test_chxj_serf_get034;
+
+  fprintf(stderr, "start %s\n", __func__);
+  doc.r = &r;
+  qs_init_malloc(&doc);
+  qs_init_root_node(&doc);
+  doc.parse_mode = PARSE_MODE_CHTML;
+
+  node_sv = node = qs_parse_string(&doc, TEST_STRING, sizeof(TEST_STRING)-1);
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+
+  apr_uri_parse(p, "http://localhost:888/abc", &r.parsed_uri); \
+
+  ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "/hoge.css");
+  CU_ASSERT(ret != NULL);
+
+  sel = chxj_css_find_selector(&doc, ret, node);
+  CU_ASSERT(sel == NULL);
+  APR_TERM;
+  fprintf(stderr, "end %s\n", __func__);
+#undef TEST_STRING
+}
+
+char *test_chxj_serf_get035(request_rec *r, apr_pool_t *ppool, const char *uri_path)
+{
+  static char *css = "html,body, .abc hr { display: none }";
+
+  return css;
+}
+void test_chxj_css_find_selector_des_008()
+{
+#define TEST_STRING "<html><head></head><body class=\"abc\" id=\"id2\"><div class=\"def\" id=\"id2\"><div><hr class=\"abc\" id=\"id1\"></div></div></body></html>"
+  Doc doc;
+  Node *node;
+  Node *tmp_node;
+  Node *node_sv;
+  css_stylesheet_t *ret;
+  css_selector_t *sel;
+  APR_INIT;
+  chxj_serf_get = test_chxj_serf_get035;
+
+  fprintf(stderr, "start %s\n", __func__);
+  doc.r = &r;
+  qs_init_malloc(&doc);
+  qs_init_root_node(&doc);
+  doc.parse_mode = PARSE_MODE_CHTML;
+
+  node_sv = node = qs_parse_string(&doc, TEST_STRING, sizeof(TEST_STRING)-1);
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+
+  apr_uri_parse(p, "http://localhost:888/abc", &r.parsed_uri); \
+
+  ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "/hoge.css");
+  CU_ASSERT(ret != NULL);
+
+  sel = chxj_css_find_selector(&doc, ret, node);
+  CU_ASSERT(sel != NULL);
+  APR_TERM;
+  fprintf(stderr, "end %s\n", __func__);
+#undef TEST_STRING
+}
+
+char *test_chxj_serf_get036(request_rec *r, apr_pool_t *ppool, const char *uri_path)
+{
+  static char *css = "html,body, #id2 hr { display: none }";
+
+  return css;
+}
+void test_chxj_css_find_selector_des_009()
+{
+#define TEST_STRING "<html><head></head><body class=\"abc\" id=\"id3\"><div class=\"def\" id=\"id2\"><div><hr class=\"abc\" id=\"id1\"></div></div></body></html>"
+  Doc doc;
+  Node *node;
+  Node *tmp_node;
+  Node *node_sv;
+  css_stylesheet_t *ret;
+  css_selector_t *sel;
+  APR_INIT;
+  chxj_serf_get = test_chxj_serf_get036;
+
+  fprintf(stderr, "start %s\n", __func__);
+  doc.r = &r;
+  qs_init_malloc(&doc);
+  qs_init_root_node(&doc);
+  doc.parse_mode = PARSE_MODE_CHTML;
+
+  node_sv = node = qs_parse_string(&doc, TEST_STRING, sizeof(TEST_STRING)-1);
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+
+  apr_uri_parse(p, "http://localhost:888/abc", &r.parsed_uri); \
+
+  ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "/hoge.css");
+  CU_ASSERT(ret != NULL);
+
+  sel = chxj_css_find_selector(&doc, ret, node);
+  CU_ASSERT(sel != NULL);
+  APR_TERM;
+  fprintf(stderr, "end %s\n", __func__);
+#undef TEST_STRING
+}
+
+char *test_chxj_serf_get037(request_rec *r, apr_pool_t *ppool, const char *uri_path)
+{
+  static char *css = "html,body, #id3 hr { display: none }";
+
+  return css;
+}
+void test_chxj_css_find_selector_des_010()
+{
+#define TEST_STRING "<html><head></head><body class=\"abc\" id=\"id3\"><div class=\"def\" id=\"id2\"><div><hr class=\"abc\" id=\"id1\"></div></div></body></html>"
+  Doc doc;
+  Node *node;
+  Node *tmp_node;
+  Node *node_sv;
+  css_stylesheet_t *ret;
+  css_selector_t *sel;
+  APR_INIT;
+  chxj_serf_get = test_chxj_serf_get037;
+
+  fprintf(stderr, "start %s\n", __func__);
+  doc.r = &r;
+  qs_init_malloc(&doc);
+  qs_init_root_node(&doc);
+  doc.parse_mode = PARSE_MODE_CHTML;
+
+  node_sv = node = qs_parse_string(&doc, TEST_STRING, sizeof(TEST_STRING)-1);
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+
+  apr_uri_parse(p, "http://localhost:888/abc", &r.parsed_uri); \
+
+  ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "/hoge.css");
+  CU_ASSERT(ret != NULL);
+
+  sel = chxj_css_find_selector(&doc, ret, node);
+  CU_ASSERT(sel != NULL);
+  APR_TERM;
+  fprintf(stderr, "end %s\n", __func__);
+#undef TEST_STRING
+}
+
+char *test_chxj_serf_get038(request_rec *r, apr_pool_t *ppool, const char *uri_path)
+{
+  static char *css = "html,body, p + hr { display: none }";
+
+  return css;
+}
+void test_chxj_css_find_selector_shib_001()
+{
+#define TEST_STRING "<html><head></head><body class=\"abc\" id=\"id3\"><div class=\"def\" id=\"id2\"><div><p>aaa</p><hr class=\"abc\" id=\"id1\"></div></div></body></html>"
+  Doc doc;
+  Node *node;
+  Node *tmp_node;
+  Node *node_sv;
+  css_stylesheet_t *ret;
+  css_selector_t *sel;
+  APR_INIT;
+  chxj_serf_get = test_chxj_serf_get038;
+
+  fprintf(stderr, "start %s\n", __func__);
+  doc.r = &r;
+  qs_init_malloc(&doc);
+  qs_init_root_node(&doc);
+  doc.parse_mode = PARSE_MODE_CHTML;
+
+  node_sv = node = qs_parse_string(&doc, TEST_STRING, sizeof(TEST_STRING)-1);
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+
+  apr_uri_parse(p, "http://localhost:888/abc", &r.parsed_uri); \
+
+  ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "/hoge.css");
+  CU_ASSERT(ret != NULL);
+
+  sel = chxj_css_find_selector(&doc, ret, node);
+  CU_ASSERT(sel != NULL);
+  APR_TERM;
+  fprintf(stderr, "end %s\n", __func__);
+#undef TEST_STRING
+}
+
+char *test_chxj_serf_get039(request_rec *r, apr_pool_t *ppool, const char *uri_path)
+{
+  static char *css = "html,body, p.pclass#pid + hr { display: none }";
+
+  return css;
+}
+void test_chxj_css_find_selector_shib_002()
+{
+#define TEST_STRING "<html><head></head><body class=\"abc\" id=\"id3\"><div class=\"def\" id=\"id2\"><div><p class=\"pclass\" id=\"pid\">aaa</p><hr class=\"abc\" id=\"id1\"></div></div></body></html>"
+  Doc doc;
+  Node *node;
+  Node *tmp_node;
+  Node *node_sv;
+  css_stylesheet_t *ret;
+  css_selector_t *sel;
+  APR_INIT;
+  chxj_serf_get = test_chxj_serf_get039;
+
+  fprintf(stderr, "start %s\n", __func__);
+  doc.r = &r;
+  qs_init_malloc(&doc);
+  qs_init_root_node(&doc);
+  doc.parse_mode = PARSE_MODE_CHTML;
+
+  node_sv = node = qs_parse_string(&doc, TEST_STRING, sizeof(TEST_STRING)-1);
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+
+  apr_uri_parse(p, "http://localhost:888/abc", &r.parsed_uri); \
+
+  ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "/hoge.css");
+  CU_ASSERT(ret != NULL);
+
+  sel = chxj_css_find_selector(&doc, ret, node);
+  CU_ASSERT(sel != NULL);
+  APR_TERM;
+  fprintf(stderr, "end %s\n", __func__);
+#undef TEST_STRING
+}
+char *test_chxj_serf_get040(request_rec *r, apr_pool_t *ppool, const char *uri_path)
+{
+  static char *css = "html,body, .pclass#pid + hr { display: none }";
+
+  return css;
+}
+void test_chxj_css_find_selector_shib_003()
+{
+#define TEST_STRING "<html><head></head><body class=\"abc\" id=\"id3\"><div class=\"def\" id=\"id2\"><div><p class=\"pclass\" id=\"pid\">aaa</p><hr class=\"abc\" id=\"id1\"></div></div></body></html>"
+  Doc doc;
+  Node *node;
+  Node *tmp_node;
+  Node *node_sv;
+  css_stylesheet_t *ret;
+  css_selector_t *sel;
+  APR_INIT;
+  chxj_serf_get = test_chxj_serf_get040;
+
+  fprintf(stderr, "start %s\n", __func__);
+  doc.r = &r;
+  qs_init_malloc(&doc);
+  qs_init_root_node(&doc);
+  doc.parse_mode = PARSE_MODE_CHTML;
+
+  node_sv = node = qs_parse_string(&doc, TEST_STRING, sizeof(TEST_STRING)-1);
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+
+  apr_uri_parse(p, "http://localhost:888/abc", &r.parsed_uri); \
+
+  ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "/hoge.css");
+  CU_ASSERT(ret != NULL);
+
+  sel = chxj_css_find_selector(&doc, ret, node);
+  CU_ASSERT(sel != NULL);
+  APR_TERM;
+  fprintf(stderr, "end %s\n", __func__);
+#undef TEST_STRING
+}
+char *test_chxj_serf_get041(request_rec *r, apr_pool_t *ppool, const char *uri_path)
+{
+  static char *css = "html,body, #pid + hr { display: none }";
+
+  return css;
+}
+void test_chxj_css_find_selector_shib_004()
+{
+#define TEST_STRING "<html><head></head><body class=\"abc\" id=\"id3\"><div class=\"def\" id=\"id2\"><div><p class=\"pclass\" id=\"pid\">aaa</p><hr class=\"abc\" id=\"id1\"></div></div></body></html>"
+  Doc doc;
+  Node *node;
+  Node *tmp_node;
+  Node *node_sv;
+  css_stylesheet_t *ret;
+  css_selector_t *sel;
+  APR_INIT;
+  chxj_serf_get = test_chxj_serf_get041;
+
+  fprintf(stderr, "start %s\n", __func__);
+  doc.r = &r;
+  qs_init_malloc(&doc);
+  qs_init_root_node(&doc);
+  doc.parse_mode = PARSE_MODE_CHTML;
+
+  node_sv = node = qs_parse_string(&doc, TEST_STRING, sizeof(TEST_STRING)-1);
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+
+  apr_uri_parse(p, "http://localhost:888/abc", &r.parsed_uri); \
+
+  ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "/hoge.css");
+  CU_ASSERT(ret != NULL);
+
+  sel = chxj_css_find_selector(&doc, ret, node);
+  CU_ASSERT(sel != NULL);
+  APR_TERM;
+  fprintf(stderr, "end %s\n", __func__);
+#undef TEST_STRING
+}
+char *test_chxj_serf_get042(request_rec *r, apr_pool_t *ppool, const char *uri_path)
+{
+  static char *css = "html,body, .pclass + hr { display: none }";
+
+  return css;
+}
+void test_chxj_css_find_selector_shib_005()
+{
+#define TEST_STRING "<html><head></head><body class=\"abc\" id=\"id3\"><div class=\"def\" id=\"id2\"><div><p class=\"pclass\" id=\"pid\">aaa</p><hr class=\"abc\" id=\"id1\"></div></div></body></html>"
+  Doc doc;
+  Node *node;
+  Node *tmp_node;
+  Node *node_sv;
+  css_stylesheet_t *ret;
+  css_selector_t *sel;
+  APR_INIT;
+  chxj_serf_get = test_chxj_serf_get042;
+
+  fprintf(stderr, "start %s\n", __func__);
+  doc.r = &r;
+  qs_init_malloc(&doc);
+  qs_init_root_node(&doc);
+  doc.parse_mode = PARSE_MODE_CHTML;
+
+  node_sv = node = qs_parse_string(&doc, TEST_STRING, sizeof(TEST_STRING)-1);
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+
+  apr_uri_parse(p, "http://localhost:888/abc", &r.parsed_uri); \
+
+  ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "/hoge.css");
+  CU_ASSERT(ret != NULL);
+
+  sel = chxj_css_find_selector(&doc, ret, node);
+  CU_ASSERT(sel != NULL);
+  APR_TERM;
+  fprintf(stderr, "end %s\n", __func__);
+#undef TEST_STRING
+}
+char *test_chxj_serf_get043(request_rec *r, apr_pool_t *ppool, const char *uri_path)
+{
+  static char *css = "html,body, p.pclass + hr { display: none }";
+
+  return css;
+}
+void test_chxj_css_find_selector_shib_006()
+{
+#define TEST_STRING "<html><head></head><body class=\"abc\" id=\"id3\"><div class=\"def\" id=\"id2\"><div><p class=\"pclass\" id=\"pid\">aaa</p><hr class=\"abc\" id=\"id1\"></div></div></body></html>"
+  Doc doc;
+  Node *node;
+  Node *tmp_node;
+  Node *node_sv;
+  css_stylesheet_t *ret;
+  css_selector_t *sel;
+  APR_INIT;
+  chxj_serf_get = test_chxj_serf_get043;
+
+  fprintf(stderr, "start %s\n", __func__);
+  doc.r = &r;
+  qs_init_malloc(&doc);
+  qs_init_root_node(&doc);
+  doc.parse_mode = PARSE_MODE_CHTML;
+
+  node_sv = node = qs_parse_string(&doc, TEST_STRING, sizeof(TEST_STRING)-1);
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+
+  apr_uri_parse(p, "http://localhost:888/abc", &r.parsed_uri); \
+
+  ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "/hoge.css");
+  CU_ASSERT(ret != NULL);
+
+  sel = chxj_css_find_selector(&doc, ret, node);
+  CU_ASSERT(sel != NULL);
+  APR_TERM;
+  fprintf(stderr, "end %s\n", __func__);
+#undef TEST_STRING
+}
+char *test_chxj_serf_get044(request_rec *r, apr_pool_t *ppool, const char *uri_path)
+{
+  static char *css = "html,body, p#pid + hr { display: none }";
+
+  return css;
+}
+void test_chxj_css_find_selector_shib_007()
+{
+#define TEST_STRING "<html><head></head><body class=\"abc\" id=\"id3\"><div class=\"def\" id=\"id2\"><div><p class=\"pclass\" id=\"pid\">aaa</p><hr class=\"abc\" id=\"id1\"></div></div></body></html>"
+  Doc doc;
+  Node *node;
+  Node *tmp_node;
+  Node *node_sv;
+  css_stylesheet_t *ret;
+  css_selector_t *sel;
+  APR_INIT;
+  chxj_serf_get = test_chxj_serf_get044;
+
+  fprintf(stderr, "start %s\n", __func__);
+  doc.r = &r;
+  qs_init_malloc(&doc);
+  qs_init_root_node(&doc);
+  doc.parse_mode = PARSE_MODE_CHTML;
+
+  node_sv = node = qs_parse_string(&doc, TEST_STRING, sizeof(TEST_STRING)-1);
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+
+  apr_uri_parse(p, "http://localhost:888/abc", &r.parsed_uri); \
+
+  ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "/hoge.css");
+  CU_ASSERT(ret != NULL);
+
+  sel = chxj_css_find_selector(&doc, ret, node);
+  CU_ASSERT(sel != NULL);
+  APR_TERM;
+  fprintf(stderr, "end %s\n", __func__);
+#undef TEST_STRING
+}
+char *test_chxj_serf_get045(request_rec *r, apr_pool_t *ppool, const char *uri_path)
+{
+  static char *css = "html,body, p.aclass#pid + hr { display: none }";
+
+  return css;
+}
+void test_chxj_css_find_selector_shib_008()
+{
+#define TEST_STRING "<html><head></head><body class=\"abc\" id=\"id3\"><div class=\"def\" id=\"id2\"><div><p class=\"pclass\" id=\"pid\">aaa</p><hr class=\"abc\" id=\"id1\"></div></div></body></html>"
+  Doc doc;
+  Node *node;
+  Node *tmp_node;
+  Node *node_sv;
+  css_stylesheet_t *ret;
+  css_selector_t *sel;
+  APR_INIT;
+  chxj_serf_get = test_chxj_serf_get045;
+
+  fprintf(stderr, "start %s\n", __func__);
+  doc.r = &r;
+  qs_init_malloc(&doc);
+  qs_init_root_node(&doc);
+  doc.parse_mode = PARSE_MODE_CHTML;
+
+  node_sv = node = qs_parse_string(&doc, TEST_STRING, sizeof(TEST_STRING)-1);
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+
+  apr_uri_parse(p, "http://localhost:888/abc", &r.parsed_uri); \
+
+  ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "/hoge.css");
+  CU_ASSERT(ret != NULL);
+
+  sel = chxj_css_find_selector(&doc, ret, node);
+  CU_ASSERT(sel == NULL);
+  APR_TERM;
+  fprintf(stderr, "end %s\n", __func__);
+#undef TEST_STRING
+}
+char *test_chxj_serf_get046(request_rec *r, apr_pool_t *ppool, const char *uri_path)
+{
+  static char *css = "html,body, p.pclass#did + hr { display: none }";
+
+  return css;
+}
+void test_chxj_css_find_selector_shib_009()
+{
+#define TEST_STRING "<html><head></head><body class=\"abc\" id=\"id3\"><div class=\"def\" id=\"id2\"><div><p class=\"pclass\" id=\"pid\">aaa</p><hr class=\"abc\" id=\"id1\"></div></div></body></html>"
+  Doc doc;
+  Node *node;
+  Node *tmp_node;
+  Node *node_sv;
+  css_stylesheet_t *ret;
+  css_selector_t *sel;
+  APR_INIT;
+  chxj_serf_get = test_chxj_serf_get046;
+
+  fprintf(stderr, "start %s\n", __func__);
+  doc.r = &r;
+  qs_init_malloc(&doc);
+  qs_init_root_node(&doc);
+  doc.parse_mode = PARSE_MODE_CHTML;
+
+  node_sv = node = qs_parse_string(&doc, TEST_STRING, sizeof(TEST_STRING)-1);
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->child;
+  node = tmp_node;
+  tmp_node = node->next;
+  node = tmp_node;
+
+  apr_uri_parse(p, "http://localhost:888/abc", &r.parsed_uri); \
+
+  ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "/hoge.css");
+  CU_ASSERT(ret != NULL);
+
+  sel = chxj_css_find_selector(&doc, ret, node);
+  CU_ASSERT(sel == NULL);
+  APR_TERM;
+  fprintf(stderr, "end %s\n", __func__);
+#undef TEST_STRING
+}
 /*
  * vim:ts=2 et
  */