OSDN Git Service

* bug fix
[modchxj/mod_chxj.git] / src / qs_parse_attr.c
1 /*
2  * Copyright (C) 2005 QSDN,Inc. All rights reserved.
3  * Copyright (C) 2005 Atsushi Konno 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 = 0;
35   int   backslash = 0;
36
37   QX_LOGGER_DEBUG("start qs_parse_attr()");
38
39   /* ignore space */
40   ii = start_pos = qs_ignore_sp_and_quote(doc, s, len);
41   QX_LOGGER_DEBUG_INT("len",len);
42
43   /* get attr name */
44   for (;ii<len; ii++) {
45     if (is_white_space(s[ii])) {
46       break;
47     }
48     if (s[ii] == '=') {
49       break;
50     }
51   }
52
53   size = ii - start_pos;
54   QX_LOGGER_DEBUG_INT("size", size);
55   /* not found */
56   if (size == 0) {
57     *pos = ii;
58     return NULL;
59   }
60   name = (char*)apr_palloc(doc->pool,size+1);
61   memset(name, 0, size+1);
62   memcpy(name, &s[start_pos], size);
63   QX_LOGGER_DEBUG((char*)name);
64
65   novalue = 0;
66   /* find '=' */
67   for (;ii<len; ii++) {
68     if (is_white_space(s[ii])) 
69       /* ignore */
70       continue;
71     if (s[ii] == '=') 
72       ii++;
73     else 
74       /* novalue */
75       novalue = 1;
76     break;
77   }
78
79   if (ii == len) 
80     novalue = 1;
81
82   size = 0;
83   if (!novalue) {
84     /* 
85      * ignore space
86      */
87     ii += qs_ignore_sp(doc, &s[ii], len-ii);
88
89     backslash = 0;
90     for (;ii<len; ii++) {
91       if (s[ii] == '\\') {
92         backslash = 1;
93         break;
94       }
95       if (s[ii] == '\'' || s[ii] == '"') {
96         use_quote = 1;
97         ii++;
98         break;
99       }
100       if (!is_white_space(s[ii])) {
101         break;
102       }
103     }
104   
105     start_pos = ii;
106     if (backslash && ii + 2 < len)
107       ii+=2;
108     
109     backslash = 0;
110     /* 
111      * get attr value 
112      */
113     for (;ii<len; ii++) {
114       if (is_sjis_kanji(s[ii])) {
115         ii++;
116         continue;
117       }
118       if (is_sjis_kana(s[ii])) 
119         continue;
120       if (is_white_space(s[ii])) {
121         if (! use_quote) 
122           break;
123       }
124       if (s[ii] == '\\') 
125         continue;
126
127       if (s[ii] == '"') 
128         break;
129
130       if (s[ii] == '\'') 
131         break;
132     }
133     size = ii - start_pos;
134     QX_LOGGER_DEBUG_INT("size",size);
135   }
136
137   value = (char*)apr_palloc(doc->pool, size+1);
138   memset(value, 0, size+1);
139   if (size != 0) 
140     memcpy(value, &s[start_pos], size);
141
142   attr = qs_new_attr(doc);
143   attr->name = name;
144   attr->value = value;
145
146   QX_LOGGER_DEBUG(attr->name);
147   QX_LOGGER_DEBUG(attr->value);
148
149   QX_LOGGER_DEBUG("end qs_parse_attr()");
150   *pos = ii;
151   return attr;
152 }
153
154 Attr*
155 qs_new_attr(Doc* doc) 
156 {
157   Attr* attr = (Attr*)apr_palloc(doc->pool,sizeof(Attr));
158   if (attr == NULL) {
159     QX_LOGGER_FATAL("Out Of Memory");
160   }
161   attr->next   = NULL;
162   attr->parent = NULL;
163   attr->name   = NULL;
164   attr->value  = NULL;
165   return attr;
166 }
167 /*
168  * vim:ts=2 et
169  */