OSDN Git Service

* updated copyright.
[modchxj/mod_chxj.git] / src / qs_parse_attr.c
1 /*
2  * Copyright (C) 2005-2011 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_parse_attr.h"
20 #include "qs_log.h"
21 #include "qs_ignore_sp.h"
22
23
24 Attr *
25 qs_parse_attr(Doc *doc, const char *s, int len, int *pos) 
26 {
27   int   ii;
28   int   start_pos;
29   int   size;
30   int   novalue;
31   char  *name;
32   char  *value;
33   Attr  *attr;
34   int   use_quote_sq;
35   int   use_quote_dq;
36   int   backslash;
37
38   if (! doc) {
39     QX_LOGGER_FATAL("runtime exception: qs_parse_attr(): doc is null");
40     return NULL;
41   }
42   if (! doc->pool) {
43     QX_LOGGER_FATAL("runtime exception: qs_parse_attr(): doc->pool is null");
44     return NULL;
45   }
46   if (! s) return NULL;
47
48   use_quote_sq = 0;
49   use_quote_dq = 0;
50   backslash = 0;
51
52   QX_LOGGER_DEBUG("start qs_parse_attr()");
53
54   /* ignore space */
55   ii = start_pos = qs_ignore_sp_and_quote(doc, s, len);
56   QX_LOGGER_DEBUG_INT("len",len);
57
58   /* get attr name */
59   for (;ii<len; ii++) {
60     if (is_white_space(s[ii])) 
61       break;
62
63     if (s[ii] == '=')
64       break;
65   }
66
67   size = ii - start_pos;
68   QX_LOGGER_DEBUG_INT("size", size);
69
70   /* 
71    * not found 
72    */
73   if (size == 0) {
74     *pos = ii;
75     return NULL;
76   }
77
78   name = (char *)apr_palloc(doc->pool,size+1);
79   memset(name, 0, size+1);
80   memcpy(name, &s[start_pos], size);
81
82   QX_LOGGER_DEBUG((char *)name);
83
84   novalue = 0;
85   /* find '=' */
86   for (;ii<len; ii++) {
87     if (is_white_space(s[ii])) 
88       /* ignore */
89       continue;
90     if (s[ii] == '=') 
91       ii++;
92     else 
93       /* novalue */
94       novalue = 1;
95     break;
96   }
97
98   if (ii == len) 
99     novalue = 1;
100
101   size = 0;
102   if (!novalue) {
103
104     /* 
105      * ignore space
106      */
107     ii += qs_ignore_sp(doc, &s[ii], len-ii);
108
109     backslash = 0;
110     for (;ii<len; ii++) {
111       if (s[ii] == '\\') {
112         backslash = 1;
113         break;
114       }
115       if (s[ii] == '\'') {
116         use_quote_sq = 1;
117         ii++;
118         break;
119       }
120       if (s[ii] == '"') {
121         use_quote_dq = 1;
122         ii++;
123         break;
124       }
125       if (!is_white_space(s[ii]))
126         break;
127     }
128   
129     start_pos = ii;
130     if (backslash && ii + 2 < len)
131       ii+=2;
132     
133     backslash = 0;
134     /* 
135      * get attr value 
136      */
137     for (;ii<len; ii++) {
138       if (is_sjis_kanji(s[ii])) {
139         ii++;
140         continue;
141       }
142
143       if (is_sjis_kana(s[ii])) 
144         continue;
145
146       if (is_white_space(s[ii])) {
147         if (! use_quote_sq && ! use_quote_dq) 
148           break;
149       }
150
151       if (s[ii] == '\\') {
152         ii++;
153         continue;
154       }
155
156       if (s[ii] == '"' && use_quote_dq) 
157         break;
158
159       if (s[ii] == '\'' && use_quote_sq) 
160         break;
161     }
162     size = ii - start_pos;
163
164     QX_LOGGER_DEBUG_INT("size",size);
165   }
166
167   value = (char *)apr_palloc(doc->pool, size+1);
168   memset(value, 0, size+1);
169   if (size != 0) 
170     memcpy(value, &s[start_pos], size);
171
172   attr = qs_new_attr(doc);
173
174   attr->name  = name;
175   attr->value = value;
176
177   QX_LOGGER_DEBUG("end qs_parse_attr()");
178   *pos = ii;
179
180   return attr;
181 }
182
183
184 Attr *
185 qs_new_attr(Doc *doc) 
186 {
187   Attr *attr;
188
189   if (!doc) {
190     QX_LOGGER_FATAL("runtime exception: qs_new_attr(): doc is null");
191     return NULL;
192   }
193   if (!doc->pool) {
194     QX_LOGGER_FATAL("runtime exception: qs_new_attr(): doc->pool is null");
195     return NULL;
196   }
197
198   attr = (Attr *)apr_palloc(doc->pool,sizeof(Attr));
199   if (attr == NULL) {
200     QX_LOGGER_FATAL("Out Of Memory");
201     return NULL;
202   }
203
204   attr->next   = NULL;
205   attr->parent = NULL;
206   attr->name   = NULL;
207   attr->value  = NULL;
208
209   return attr;
210 }
211 /*
212  * vim:ts=2 et
213  */