]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/applet/prepifelse.cpp
fix for wxExecute(subprocess which produces a lot of output) bug
[wxWidgets.git] / contrib / src / applet / prepifelse.cpp
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 ";
89 char ftnot[] = "<!--#if NOT ";
90 char ftnot2[] = "<!--#if !";
91
92
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) {
96 // Loop until every #if directive is found
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-->
99 bool notval = false;
100 int off = 0;
101 int end, c, n;
102 wxString usecode, code;
103 wxString cname;
104 wxString tag;
105 bool value;
106
107 code = wxString("");
108
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
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
135 c = (tag.Mid(8+off, n-(8+off))).Find(" ");
136 if (c == -1) n -= (8+off);
137 else n = c;
138 cname = tag.Mid(8+off, n);
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
147 value = wxIfElseVariable::FindValue(cname);
148 if (notval) value = !value;
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)