… | |
… | |
92 | |
92 | |
93 | =cut |
93 | =cut |
94 | |
94 | |
95 | BEGIN { |
95 | BEGIN { |
96 | be_strict(); # an alias for use strict. This means that all global variable must contain main:: as a prefix. |
96 | be_strict(); # an alias for use strict. This means that all global variable must contain main:: as a prefix. |
97 | |
97 | |
98 | } |
98 | } |
99 | |
99 | |
|
|
100 | my $debugON = 0; |
100 | |
101 | |
101 | sub _dangerousMacros_init { |
102 | sub _dangerousMacros_init { |
102 | } |
103 | } |
103 | |
104 | |
104 | sub _dangerousMacros_export { |
105 | sub _dangerousMacros_export { |
… | |
… | |
173 | ); |
174 | ); |
174 | |
175 | |
175 | sub loadMacros { |
176 | sub loadMacros { |
176 | my @files = @_; |
177 | my @files = @_; |
177 | my $fileName; |
178 | my $fileName; |
|
|
179 | eval {main::time_it("begin load macros");}; |
178 | ############################################################################### |
180 | ############################################################################### |
179 | # At this point the directories have been defined from %envir and we can define |
181 | # At this point the directories have been defined from %envir and we can define |
180 | # the directories for this file |
182 | # the directories for this file |
181 | ############################################################################### |
183 | ############################################################################### |
182 | |
184 | |
183 | $macroDirectory = eval('$main::macroDirectory') unless defined($macroDirectory); |
185 | $macroDirectory = eval('$main::macroDirectory') unless defined($macroDirectory); |
184 | $courseScriptsDirectory = eval('$main::courseScriptsDirectory') unless defined($courseScriptsDirectory); |
186 | $courseScriptsDirectory = eval('$main::courseScriptsDirectory') unless defined($courseScriptsDirectory); |
185 | $templateDirectory = eval('$main::courseScriptsDirectory') unless defined($templateDirectory); |
187 | $templateDirectory = eval('$main::courseScriptsDirectory') unless defined($templateDirectory); |
186 | $scriptDirectory = eval('$main::scriptDirectory') unless defined($scriptDirectory); |
188 | $scriptDirectory = eval('$main::scriptDirectory') unless defined($scriptDirectory); |
187 | |
189 | |
188 | unless (defined( $main::externalTTHPath) and $main::externalTTHPath) { |
190 | unless (defined( eval('$main::externalTTHPath') and eval('$main::externalTTHPath') )){ |
189 | warn "WARNING::Please make sure that the DOCUMENT() statement comes before<BR>\n" . |
191 | warn "WARNING::Please make sure that the DOCUMENT() statement comes before<BR>\n" . |
190 | " the loadMacros() statement in the problem template.<p>" . |
192 | " the loadMacros() statement in the problem template.<p>" . |
191 | " The externalTTHPath variable |$main::externalTTHPath| was\n". |
193 | " The externalTTHPath variable |$main::externalTTHPath| was\n". |
192 | " not defined which usually indicates the problem above.<br>\n"; |
194 | " not defined which usually indicates the problem above.<br>\n"; |
193 | |
195 | |
… | |
… | |
199 | |
201 | |
200 | my $macro_file_name = $fileName; |
202 | my $macro_file_name = $fileName; |
201 | $macro_file_name =~s/\.pl//; # trim off the extension |
203 | $macro_file_name =~s/\.pl//; # trim off the extension |
202 | $macro_file_name =~s/\.pg//; # sometimes the extension is .pg (e.g. CAPA files) |
204 | $macro_file_name =~s/\.pg//; # sometimes the extension is .pg (e.g. CAPA files) |
203 | my $init_subroutine_name = "_${macro_file_name}_init"; |
205 | my $init_subroutine_name = "_${macro_file_name}_init"; |
204 | my $macro_file_loaded; |
206 | |
205 | #no strict; |
207 | #no strict; |
206 | ############################################################################### |
208 | ############################################################################### |
207 | # For some reason the "no stict" which works on webwork-db doesn't work on |
209 | # For some reason the "no stict" which works on webwork-db doesn't work on |
208 | # webwork. For this reason the constuction &{$init_subroutine_name} |
210 | # webwork. For this reason the constuction &{$init_subroutine_name} |
209 | # was abandoned and replaced by eval. This is considerably more dangerous |
211 | # was abandoned and replaced by eval. This is considerably more dangerous |
210 | # since one could hide something nasty in a file name. |
212 | # since one could hide something nasty in a file name. |
211 | # Keep an eye on this ??? |
213 | # Keep an eye on this ??? |
212 | # webwork-db used perl 5.6.1 and webwork used perl 5.6.0 It seems |
214 | # webwork-db used perl 5.6.1 and webwork used perl 5.6.0 It seems |
213 | # unlikely that this was the problem. Otherwise all files seemed to |
215 | # unlikely that this was the problem. Otherwise all files seemed to |
214 | # be the same. |
216 | # be the same. |
|
|
217 | |
|
|
218 | # local($temp::rf_init_subroutine); |
|
|
219 | # eval qq{ \$temp::rf_init_subroutine = \\&main::$init_subroutine_name;}; |
|
|
220 | # #warn "loadMacros: defining \$temp::rf_init_subroutine ",$temp::rf_init_subroutine; |
|
|
221 | # |
|
|
222 | # $macro_file_loaded = defined($temp::rf_init_subroutine) && defined( &{$temp::rf_init_subroutine} ); |
215 | ############################################################################### |
223 | ############################################################################### |
216 | |
224 | no strict; |
217 | local($temp::rf_init_subroutine); |
225 | # warn "dangerousMacros main:: contains <br>\n ".join("<br>\n ", %main::) if $debugON; |
218 | eval qq{ \$temp::rf_init_subroutine = \\&main::$init_subroutine_name;}; |
226 | my $init_subroutine = eval { \&{$init_subroutine_name} }; |
219 | #warn "loadMacros: defining \$temp::rf_init_subroutine ",$temp::rf_init_subroutine; |
227 | use strict; |
220 | |
228 | my $macro_file_loaded = defined($init_subroutine); |
221 | $macro_file_loaded = defined($temp::rf_init_subroutine) && defined( &{$temp::rf_init_subroutine} ); |
229 | warn "dangerousMacros: macro init $init_subroutine_name defined |$init_subroutine| |$macro_file_loaded|" if $debugON; |
222 | |
|
|
223 | # macros are searched for first in the $macroDirectory of the course |
230 | # macros are searched for first in the $macroDirectory of the course |
224 | # and then in the webwork $courseScripts directory. |
231 | # and then in the webwork $courseScripts directory. |
225 | unless ($macro_file_loaded) { |
232 | unless ($macro_file_loaded) { |
226 | #print STDERR "loadMacros: loading macro file $fileName\n"; |
233 | #print STDERR "loadMacros: loading macro file $fileName\n"; |
227 | if (-r "${main::macroDirectory}$fileName") { |
234 | if (-r "$macroDirectory$fileName") { |
228 | compile_file("${main::macroDirectory}$fileName"); |
235 | compile_file("$macroDirectory$fileName"); |
229 | |
236 | |
230 | } elsif (-r "${main::courseScriptsDirectory}$fileName" ) { |
237 | } elsif (-r "$courseScriptsDirectory$fileName" ) { |
231 | compile_file("${main::courseScriptsDirectory}$fileName"); |
238 | compile_file("$courseScriptsDirectory$fileName"); |
232 | } else { |
239 | } else { |
233 | die "Can't locate macro file via path: |${main::macroDirectory}$fileName| or |${main::courseScriptsDirectory}$fileName|"; |
240 | die "Can't locate macro file via path: |$macroDirectory$fileName| or |$courseScriptsDirectory$fileName|"; |
234 | } |
241 | } |
235 | } |
242 | } |
236 | # Try again to define the initialization subroutine. |
243 | # Try again to define the initialization subroutine. |
237 | eval qq{ \$temp::rf_init_subroutine = \\&main::$init_subroutine_name;}; |
244 | #eval qq{ \$temp::rf_init_subroutine = \\&main::$init_subroutine_name;}; |
|
|
245 | no strict; |
|
|
246 | $init_subroutine = eval { \&{'main::'.$init_subroutine_name} }; |
|
|
247 | use strict; |
238 | #warn "loadMacros: defining \$temp::rf_init_subroutine ",$temp::rf_init_subroutine; |
248 | #warn "loadMacros: defining \$temp::rf_init_subroutine ",$temp::rf_init_subroutine; |
|
|
249 | warn "init file defined: $macro_file_name = ", defined(&{$init_subroutine}) if $debugON; |
|
|
250 | |
|
|
251 | if ( defined( &{$init_subroutine} ) ) { |
239 | |
252 | |
240 | if ( defined($temp::rf_init_subroutine) and defined( &{$temp::rf_init_subroutine} ) ) { |
253 | warn "dangerousMacros: initializing $macro_file_name" if $debugON; |
241 | #print " &$init_subroutine_name defined = ", $macro_file_loaded,"\n"; |
254 | &$init_subroutine($main::displayMode); |
242 | &{$temp::rf_init_subroutine}(); #initialize file |
|
|
243 | #print "initializing $init_subroutine_name\n"; |
|
|
244 | } |
255 | } |
|
|
256 | #warn "main:: contains <br>\n $macro_file_name ".join("<br>\n $macro_file_name ", %main::); |
245 | |
257 | |
246 | } |
258 | } |
|
|
259 | eval{main::time_it("end load macros");}; |
247 | } |
260 | } |
248 | |
261 | |
249 | # errors in compiling macros is not always being reported. |
262 | # errors in compiling macros is not always being reported. |
250 | sub compile_file { |
263 | sub compile_file { |
251 | my $filePath = shift; |
264 | my $filePath = shift; |
|
|
265 | warn "loading $filePath" if $debugON; |
252 | local(*MACROFILE); |
266 | local(*MACROFILE); |
253 | local($/); |
267 | local($/); |
254 | $/ = undef; # allows us to treat the file as a single line |
268 | $/ = undef; # allows us to treat the file as a single line |
255 | open(MACROFILE, "<$filePath") || die "Cannot open file: $filePath"; |
269 | open(MACROFILE, "<$filePath") || die "Cannot open file: $filePath"; |
256 | my $string = <MACROFILE>; |
270 | my $string = <MACROFILE>; |
… | |
… | |
1164 | |
1178 | |
1165 | # This allows the use of i for imaginary numbers |
1179 | # This allows the use of i for imaginary numbers |
1166 | # one can write 3 +2i rather than 3+2i() |
1180 | # one can write 3 +2i rather than 3+2i() |
1167 | # |
1181 | # |
1168 | |
1182 | |
|
|
1183 | |
1169 | sub i; |
1184 | sub i { |
|
|
1185 | } |
1170 | |
1186 | |
1171 | 1; # required to load properly |
1187 | 1; # required to load properly |