]>
Commit | Line | Data |
---|---|---|
716cd410 KB |
1 | /**************************************************************************** |
2 | * | |
3 | * wxWindows HTML Applet Package | |
4 | * | |
5 | * Copyright (C) 1991-2001 SciTech Software, Inc. | |
6 | * All rights reserved. | |
7 | * | |
8 | * ======================================================================== | |
9 | * | |
10 | * The contents of this file are subject to the wxWindows License | |
11 | * Version 3.0 (the "License"); you may not use this file except in | |
12 | * compliance with the License. You may obtain a copy of the License at | |
13 | * http://www.wxwindows.org/licence3.txt | |
14 | * | |
15 | * Software distributed under the License is distributed on an | |
16 | * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or | |
17 | * implied. See the License for the specific language governing | |
18 | * rights and limitations under the License. | |
19 | * | |
20 | * ======================================================================== | |
21 | * | |
22 | * Language: ANSI C++ | |
23 | * Environment: Any | |
24 | * | |
25 | * Description: This file is the implementation of the Preprocessor object | |
26 | * for parsing the <!--#if directive | |
27 | * | |
28 | ****************************************************************************/ | |
29 | ||
30 | // For compilers that support precompilation | |
31 | #include "wx/wxprec.h" | |
32 | #include "wx/html/forcelnk.h" | |
33 | ||
34 | // Include private headers | |
35 | #include "wx/applet/prepifelse.h" | |
36 | #include "wx/applet/ifelsevar.h" | |
37 | ||
38 | /*---------------------------- Global variables ---------------------------*/ | |
39 | ||
40 | ||
41 | /*----------------------------- Implementation ----------------------------*/ | |
42 | ||
43 | /* {SECRET} */ | |
44 | /**************************************************************************** | |
45 | REMARKS: | |
46 | None of the Reverse Find functions in wxWindows appear to work in a way that | |
47 | can be used by our code. This includes the libstr rfind implementations which | |
48 | do not correctly pass the given return value. | |
49 | ****************************************************************************/ | |
50 | int ReverseFind( | |
51 | const wxString &tstr, | |
52 | const wxString &str) | |
53 | { | |
54 | wxASSERT( str.GetStringData()->IsValid() ); | |
55 | ||
56 | // TODO could be made much quicker than that | |
57 | int p = tstr.Len()-str.Len()-1; | |
58 | while ( p >= 0 ) { | |
59 | if ( wxStrncmp(tstr.c_str() + p, str.c_str(), str.Len()) == 0 ) | |
60 | return p; | |
61 | p--; | |
62 | } | |
63 | ||
64 | return -1; | |
65 | } | |
66 | ||
67 | /**************************************************************************** | |
68 | PARAMETERS: | |
69 | text - HTML to process for if/else blocks | |
70 | ||
71 | RETURNS: | |
72 | The string containing the processed HTML | |
73 | ||
74 | REMARKS: | |
75 | This function replaces #if, #else, and #endif directives with the text | |
76 | contained within the blocks, dependant on the value of the given boolean | |
77 | variable. The variable is created by making a sub class of wxIfElseVariable. | |
78 | Dynamic class construction is used at run time internally to create an instance | |
79 | of this class and access the value of the variable. | |
80 | ||
81 | SEE ALSO: | |
82 | wxIfElseVariable | |
83 | ****************************************************************************/ | |
84 | wxString wxIfElsePrep::Process( | |
85 | const wxString& text) const | |
86 | { | |
87 | int b; | |
88 | char ft[] = "<!--#if "; | |
505710ca KB |
89 | char ftnot[] = "<!--#if NOT "; |
90 | char ftnot2[] = "<!--#if !"; | |
91 | ||
92 | ||
716cd410 KB |
93 | // make a copy so we can replace text as we go without affecting the original |
94 | wxString output = text; | |
95 | while ((b = ReverseFind(output.Lower(), ft)) != -1) { | |
505710ca | 96 | // Loop until every #if directive is found |
716cd410 KB |
97 | // We search from the end of the string so that #if statements will properly recurse |
98 | // and we avoid the hassle of matching statements with the correct <!--#endif--> | |
505710ca KB |
99 | bool notval = false; |
100 | int off = 0; | |
101 | int end, c, n; | |
716cd410 KB |
102 | wxString usecode, code; |
103 | wxString cname; | |
104 | wxString tag; | |
105 | bool value; | |
106 | ||
107 | code = wxString(""); | |
108 | ||
505710ca KB |
109 | if (output.Mid(b, strlen(ftnot) ).CmpNoCase(ftnot) == 0 ) { |
110 | notval = true; | |
111 | off = 4; | |
112 | } | |
113 | else if (output.Mid(b, strlen(ftnot2) ).CmpNoCase(ftnot2) == 0 ) { | |
114 | notval = true; | |
115 | off = 1; | |
116 | } | |
117 | ||
716cd410 KB |
118 | // grab the tag and get the name of the variable |
119 | end = (output.Mid(b)).Find("-->"); | |
120 | if (end == -1) { | |
121 | #ifdef CHECKED | |
122 | wxMessageBox("wxHTML #if error: Premature end of file while parsing #if.","Error",wxICON_ERROR); | |
123 | #endif | |
124 | break; | |
125 | } | |
126 | ||
127 | end += 3; | |
128 | tag = output.Mid(b, end); | |
129 | output.Remove(b, end); | |
130 | ||
131 | c = tag.Find("-->"); | |
132 | n = c; | |
133 | ||
134 | // find the classname | |
505710ca KB |
135 | c = (tag.Mid(8+off, n-(8+off))).Find(" "); |
136 | if (c == -1) n -= (8+off); | |
716cd410 | 137 | else n = c; |
505710ca | 138 | cname = tag.Mid(8+off, n); |
716cd410 KB |
139 | |
140 | cname.Trim(false); | |
141 | c = cname.Find("\""); | |
142 | if (c != -1) cname = cname.Mid(c+1); | |
143 | c = cname.Find("\""); | |
144 | if (c != -1) cname = cname.Mid(0, c); | |
145 | ||
146 | // Grab the value from the variable class identified by cname | |
d699f48b | 147 | value = wxIfElseVariable::FindValue(cname); |
505710ca | 148 | if (notval) value = !value; |
716cd410 KB |
149 | |
150 | // Find the end of the tag (<!--#endif-->) and copy it all into the variable code | |
151 | end = ((output.Mid(b)).Lower()).Find("<!--#endif-->"); | |
152 | if (end == -1) { | |
153 | #ifdef CHECKED | |
154 | wxMessageBox("wxHTML #if error: Premature end of file while searching for matching #endif.","Error",wxICON_ERROR); | |
155 | #endif | |
156 | break; | |
157 | } | |
158 | ||
159 | code = output.Mid(b, end); | |
160 | output.Remove(b, end+13); // remove the entire #if block from original document | |
161 | ||
162 | // Find out if there is an else statement | |
163 | end = (code.Lower()).Find("<!--#else-->"); | |
164 | if (end != -1) { | |
165 | if (!value) { | |
166 | // Use the else statement | |
167 | usecode = code.Mid(end+12); | |
168 | } | |
169 | else { | |
170 | // Use statement before #else | |
171 | usecode = code.Mid(0, end); | |
172 | } | |
173 | } | |
174 | else if (value) { | |
175 | // There is no #else statement | |
176 | usecode = code; | |
177 | } | |
178 | ||
179 | if (usecode != wxString("")) | |
180 | output = (output.Mid(0,b) + usecode + output.Mid(b)); | |
181 | } | |
182 | ||
183 | return output; | |
184 | } | |
185 | ||
186 | FORCE_LINK(ifelsevar) |