]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/applet/prepifelse.cpp
Significantly changed how the Python interpreter lock and thread state
[wxWidgets.git] / contrib / src / applet / prepifelse.cpp
CommitLineData
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/****************************************************************************
45REMARKS:
46None of the Reverse Find functions in wxWindows appear to work in a way that
47can be used by our code. This includes the libstr rfind implementations which
48do not correctly pass the given return value.
49****************************************************************************/
50int 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/****************************************************************************
68PARAMETERS:
69text - HTML to process for if/else blocks
70
71RETURNS:
72The string containing the processed HTML
73
74REMARKS:
75This function replaces #if, #else, and #endif directives with the text
76contained within the blocks, dependant on the value of the given boolean
77variable. The variable is created by making a sub class of wxIfElseVariable.
78Dynamic class construction is used at run time internally to create an instance
79of this class and access the value of the variable.
80
81SEE ALSO:
82wxIfElseVariable
83****************************************************************************/
84wxString 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
186FORCE_LINK(ifelsevar)