]> git.saurik.com Git - wxWidgets.git/blame - src/html/htmltag.cpp
Fixes for scrolling in wxScrolledWindow
[wxWidgets.git] / src / html / htmltag.cpp
CommitLineData
5526e819
VS
1/////////////////////////////////////////////////////////////////////////////
2// Name: htmltag.cpp
3// Purpose: wxHtmlTag class (represents single tag)
4// Author: Vaclav Slavik
5// Copyright: (c) 1999 Vaclav Slavik
6// Licence: wxWindows Licence
7/////////////////////////////////////////////////////////////////////////////
8
9
10#ifdef __GNUG__
11#pragma implementation
12#endif
13
14#include <wx/wxprec.h>
15
16#include "wx/defs.h"
17#if wxUSE_HTML
18
19#ifdef __BORDLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WXPRECOMP
24#include <wx/wx.h>
25#endif
26
27#include <wx/html/htmltag.h>
7e1e0960 28#include <stdio.h> // for vsscanf
5526e819
VS
29#include <stdarg.h>
30
31
32
33
34//-----------------------------------------------------------------------------
35// wxHtmlTagsCache
36//-----------------------------------------------------------------------------
37
38IMPLEMENT_CLASS(wxHtmlTagsCache,wxObject)
39
40#define CACHE_INCREMENT 64
41
42wxHtmlTagsCache::wxHtmlTagsCache(const wxString& source)
43{
44 const char *src = source.c_str();
45 int i, tg, pos, stpos;
46 int lng = source.Length();
47 char dummy[256];
48
49 m_Cache = NULL;
50 m_CacheSize = 0;
51 m_CachePos = 0;
52
53 pos = 0;
54 while (pos < lng) {
55 if (src[pos] == '<') { // tag found:
56 if (m_CacheSize % CACHE_INCREMENT == 0)
57 m_Cache = (sCacheItem*) realloc(m_Cache, (m_CacheSize + CACHE_INCREMENT) * sizeof(sCacheItem));
58 tg = m_CacheSize++;
59 m_Cache[tg].Key = stpos = pos++;
60 dummy[0] = 0; i = 0;
61 while ((src[pos] != '>') && (src[pos] != ' ')) {
62 dummy[i] = src[pos++];
63 if ((dummy[i] >= 'a') && (dummy[i] <= 'z')) dummy[i] -= ('a' - 'A');
64 i++;
65 }
66 dummy[i] = 0;
2776d7c3 67 m_Cache[tg].Name = new char[i+1];
5526e819
VS
68 memcpy(m_Cache[tg].Name, dummy, i+1);
69
70 while (src[pos] != '>') pos++;
71
72 if (src[stpos+1] == '/') { // ending tag:
73 m_Cache[tg].End1 = m_Cache[tg].End2 = -2;
74 // find matching begin tag:
75 for (i = tg; i >= 0; i--)
76 if ((m_Cache[i].End1 == -1) && (strcmp(m_Cache[i].Name, dummy+1) == 0)) {
77 m_Cache[i].End1 = stpos;
78 m_Cache[i].End2 = pos + 1;
79 break;
80 }
81 }
82 else {
83 m_Cache[tg].End1 = m_Cache[tg].End2 = -1;
84 }
85 }
86
87 pos++;
88 }
89
90 // ok, we're done, now we'll free .Name members of cache - we don't need it anymore:
91 for (i = 0; i < m_CacheSize; i++) {
2776d7c3 92 delete[] m_Cache[i].Name;
5526e819
VS
93 m_Cache[i].Name = NULL;
94 }
95}
96
97
98
99void wxHtmlTagsCache::QueryTag(int at, int* end1, int* end2)
100{
101 if (m_Cache == NULL) return;
102 if (m_Cache[m_CachePos].Key != at) {
103 int delta = (at < m_Cache[m_CachePos].Key) ? -1 : 1;
104 do {m_CachePos += delta;} while (m_Cache[m_CachePos].Key != at);
105 }
106 *end1 = m_Cache[m_CachePos].End1;
107 *end2 = m_Cache[m_CachePos].End2;
108}
109
110
111
112
113//-----------------------------------------------------------------------------
114// wxHtmlTag
115//-----------------------------------------------------------------------------
116
117IMPLEMENT_CLASS(wxHtmlTag,wxObject)
118
119wxHtmlTag::wxHtmlTag(const wxString& source, int pos, int end_pos, wxHtmlTagsCache* cache) : wxObject()
120{
121 int i;
122 char c;
123
124 // fill-in name, params and begin pos:
125 m_Name = m_Params = wxEmptyString;
126 i = pos+1;
127 if (source[i] == '/') {m_Ending = TRUE; i++;}
128 else m_Ending = FALSE;
129
130 while ((i < end_pos) && ((c = source[i++]) != ' ') && (c != '>')) {
131 if ((c >= 'a') && (c <= 'z')) c -= ('a' - 'A');
132 m_Name += c;
133 }
134
135 if (source[i-1] != '>')
136 while ((i < end_pos) && ((c = source[i++]) != '>')) {
137 if ((c >= 'a') && (c <= 'z')) c -= ('a' - 'A');
138 m_Params += c;
139 if (c == '"') {
140 while ((i < end_pos) && ((c = source[i++]) != '"')) m_Params += c;
141 m_Params += c;
142 }
72aa4a98
VS
143 else if (c == '\'') {
144 while ((i < end_pos) && ((c = source[i++]) != '\'')) m_Params += c;
145 m_Params += c;
146 }
5526e819
VS
147 }
148 m_Begin = i;
149
150 cache -> QueryTag(pos, &m_End1, &m_End2);
151 if (m_End1 > end_pos) m_End1 = end_pos;
152 if (m_End2 > end_pos) m_End2 = end_pos;
153}
154
155
156
157bool wxHtmlTag::HasParam(const wxString& par) const
158{
159 const char *st = m_Params, *p = par;
160 const char *st2, *p2;
161
162 if (*st == 0) return FALSE;
163 if (*p == 0) return FALSE;
164 for (st2 = st, p2 = p; ; st2++) {
165 if (*p2 == 0) return TRUE;
166 if (*st2 == 0) return FALSE;
167 if (*p2 != *st2) p2 = p;
168 if (*p2 == *st2) p2++;
169 if (*st2 == ' ') p2 = p;
170 else if (*st2 == '=') {
171 p2 = p;
172 while (*st2 != ' ') {
173 if (*st2 == '"') {
174 st2++;
175 while (*st2 != '"') st2++;
176 }
177 st2++;
178 if (*st2 == 0) return FALSE;
179 }
180 }
181 }
182}
183
184
185
186wxString wxHtmlTag::GetParam(const wxString& par, bool with_commas) const
187{
188 const char *st = m_Params, *p = par;
189 const char *st2, *p2;
190 bool comma;
72aa4a98 191 char comma_char;
5526e819
VS
192
193 if (*st == 0) return "";
194 if (*p == 0) return "";
195 for (st2 = st, p2 = p; ; st2++) {
196 if (*p2 == 0) { // found
197 wxString fnd = "";
198 st2++; // '=' character
199 comma = FALSE;
72aa4a98
VS
200 comma_char = '\0';
201 if (!with_commas && (*(st2) == '"')) {
202 st2++;
203 comma = TRUE;
204 comma_char = '"';
205 }
206 else if (!with_commas && (*(st2) == '\'')) {
207 st2++;
208 comma = TRUE;
209 comma_char = '\'';
210 }
5526e819 211 while (*st2 != 0) {
72aa4a98 212 if (comma && *st2 == comma_char) comma = FALSE;
5526e819
VS
213 else if ((*st2 == ' ') && (!comma)) break;
214 fnd += (*(st2++));
215 }
72aa4a98 216 if (!with_commas && (*(st2-1) == comma_char)) fnd.RemoveLast();
5526e819
VS
217 return fnd;
218 }
219 if (*st2 == 0) return "";
220 if (*p2 != *st2) p2 = p;
221 if (*p2 == *st2) p2++;
222 if (*st2 == ' ') p2 = p;
223 else if (*st2 == '=') {
224 p2 = p;
225 while (*st2 != ' ') {
226 if (*st2 == '"') {
227 st2++;
228 while (*st2 != '"') st2++;
229 }
72aa4a98
VS
230 else if (*st2 == '\'') {
231 st2++;
232 while (*st2 != '\'') st2++;
233 }
5526e819
VS
234 st2++;
235 }
236 }
237 }
238}
239
240
241
72aa4a98 242int wxHtmlTag::ScanParam(const wxString& par, char *format, ...) const
5526e819 243{
72aa4a98 244 int retval;
5526e819
VS
245 va_list argptr;
246 wxString parval = GetParam(par);
247
248 va_start(argptr, format);
249
4d223b67
KB
250//#if defined(__MINGW32__) || defined(__CYGWIN__) || defined(__VISUALC__)
251#ifndef HAVE_VSSCANF
72aa4a98 252 retval = sscanf((const char*)parval, format, va_arg(argptr, void *));
5526e819 253#else
72aa4a98 254 retval = vsscanf((const char*)parval, format, argptr);
5526e819
VS
255#endif
256
257/*
72aa4a98 258 --- vsscanf is not defined under some compilers
5526e819
VS
259 if this module doesn't compile with your compiler,
260 modify the def statement and let me know. Thanks...
261
262 So far wxHtml functions are scanning only _one_ value
263 so I workarounded this by supposing that there is only
264 one ...-parameter
265*/
266
267 va_end(argptr);
72aa4a98 268 return retval;
5526e819
VS
269}
270
4d223b67 271#endif