OSDN Git Service

* Added New Features.
[modchxj/mod_chxj.git] / src / qs_parse_tag.c
1 /*
2  * Copyright (C) 2005-2009 Atsushi Konno All rights reserved.
3  * Copyright (C) 2005 QSDN,Inc. All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #include <stdio.h>
18 #include "qs_parse_string.h"
19 #include "qs_log.h"
20 #include "qs_parse_attr.h"
21 #include "qs_parse_tag.h"
22
23 static char *s_get_tag_name(Doc *doc, const char *s, int len) ; 
24
25
26
27 Node *
28 qs_parse_tag(Doc *doc, const char *s, int len) 
29 {
30   Node   *node;
31   char   *tag_name;
32   char   *sp;
33   char   *sv_s;
34   int    ll;
35   int    next_point;
36
37   if (! doc) {
38     QX_LOGGER_FATAL("runtime exception: qs_parse_tag(): doc is null");
39     return NULL;
40   }
41
42   sv_s = sp = (char *)s;
43   ll         = len;
44   next_point = 0;
45
46   QX_LOGGER_DEBUG("start parse_tag()");
47
48
49   /* 
50    * s[0] == '<' && s[len] == '>' 
51    */
52   tag_name = (char *)s_get_tag_name(doc, ++s, --ll);
53
54   node = (Node *)qs_new_tag(doc);
55   if (! node) {
56     QX_LOGGER_DEBUG("runtime exception: qs_parse_tag(): Out of memory.");
57     return NULL;
58   }
59   node->name = tag_name;
60   node->otext = apr_palloc(doc->pool,len+2);
61   memset(node->otext, 0, len+2);
62   memcpy(node->otext, sp, len+1);
63
64   QX_LOGGER_DEBUG(tag_name);
65
66   ll -= (strlen(tag_name));
67   QX_LOGGER_DEBUG_INT("ll",ll);
68   sp += (strlen(tag_name)+1);
69   for (;;) {
70     Attr *attr = qs_parse_attr(doc,sp, ll, &next_point);
71     if (attr == NULL) {
72       QX_LOGGER_DEBUG("End of QS_PARSE_ATTR()");
73       break;
74     }
75     QX_LOGGER_DEBUG(attr->name);
76     QX_LOGGER_DEBUG(attr->value);
77     sp += next_point;
78     ll -= next_point;
79     QX_LOGGER_DEBUG_INT(sp, ll);
80     node = (Node *)qs_add_attr(doc,node, attr);
81   }
82
83   if (sv_s[len-1] == '/') {
84     node->closed_by_itself = 1;
85   }
86   else {
87     node->closed_by_itself = 0;
88   }
89   QX_LOGGER_DEBUG("end parse_tag()");
90
91   return node;
92 }
93
94
95
96
97 static char * 
98 s_get_tag_name(Doc *doc, const char *s, int len)  
99 {
100   int ii;
101   int sp;
102   int size;
103   char *return_value = NULL;
104
105   /* ignore space. */
106   for (ii = 0; ii < len; ii++) {
107     if (is_white_space(s[ii])) 
108       continue;
109     break;
110   }
111
112   sp = ii;
113   for (;ii<len; ii++) {
114     if (is_white_space(s[ii])) 
115       break;
116   }
117
118   size = ii-sp;
119
120   return_value = (char *)apr_palloc(doc->pool, size+1);
121
122   memset(return_value, 0, size+1);
123   memcpy(return_value, &s[sp], size);
124
125   QX_LOGGER_DEBUG(return_value);
126   return return_value;
127 }
128
129
130
131 Node *
132 qs_new_tag(Doc *doc) 
133 {
134   Node *node;
135
136   if (! doc) {
137     QX_LOGGER_FATAL("runtime exception: qs_new_tag(): doc is NULL");
138     return NULL;
139   }
140   if (! doc->pool) {
141     QX_LOGGER_FATAL("runtime exception: qs_new_tag(): doc->pool is NULL");
142     return NULL;
143   }
144
145   node = (Node *)apr_palloc(doc->pool, sizeof(Node));
146   node->next      = NULL;
147   node->parent    = NULL;
148   node->child     = NULL;
149   node->child_tail= NULL;
150   node->attr      = NULL;
151   node->attr_tail = NULL;
152   node->name      = NULL;
153   node->value     = NULL;
154
155   return node;
156 }
157
158
159
160
161 Node *
162 qs_add_attr(Doc *doc, Node *node, Attr *attr) 
163 {
164   if (node == NULL) {
165     QX_LOGGER_FATAL("runtime exception: qs_add_attr(): node is null");
166     return NULL;
167   }
168   if (! attr) {
169     return node;
170   }
171
172   attr->parent = node;
173   attr->next   = NULL;
174
175   if (node->attr == NULL) {
176     node->attr      = attr;
177     node->attr_tail = attr;
178
179     return node;
180   }
181
182   node->attr_tail->next = attr;
183   node->attr_tail       = attr;
184
185   return node;
186 }
187 /*
188  * vim:ts=2 et
189  */