1#!/usr/bin/perl
2#########################################################################
3
4 #**************************************************************
5#
6#  Licensed to the Apache Software Foundation (ASF) under one
7#  or more contributor license agreements.  See the NOTICE file
8#  distributed with this work for additional information
9#  regarding copyright ownership.  The ASF licenses this file
10#  to you under the Apache License, Version 2.0 (the
11#  "License"); you may not use this file except in compliance
12#  with the License.  You may obtain a copy of the License at
13#
14#    http://www.apache.org/licenses/LICENSE-2.0
15#
16#  Unless required by applicable law or agreed to in writing,
17#  software distributed under the License is distributed on an
18#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19#  KIND, either express or implied.  See the License for the
20#  specific language governing permissions and limitations
21#  under the License.
22#
23#**************************************************************
24
25
26
27####################################################################
28# File Name: test_driver.pl
29# Version  : 1.0
30# Project  : Xmerge
31# Author   : Brian Cameron
32# Date	   : 5th Sept. 2001
33#
34#
35# This script does the following:
36#
37# Processes the input file, and runs the tests specified in that
38# file.  This will do the following for each test:
39#
40# 1. Convert a file from XML to PDB format
41# 2. Starts up the Palm OS emulator with the appropriate program
42#    running and the converted file loaded the program.
43# 3. Makes automated changes as specified in the inputfile to
44#    this script..
45# 4. Returns to the main applications window.
46#
47# Parameter
48#   Filename to convert and change
49#
50##########################################################################
51
52# Turn on auto-flushing
53#
54$|=1;
55
56use EmRPC;
57
58# Directory where converterlib is located...
59#
60#use lib "/export/home/test/qadir/qa/lib";
61use lib $ENV{'QA_LIB_HOME'};
62use converterlib;
63
64#-------------------- Start of main script ------------------------------------
65
66# Environmental Settings
67
68$pose_exe = "";
69$pose_prc = "";
70$test_list = "";
71$infile = "";
72$merge_opt = 0;
73# if testcase hasn't completed in 10 mins, then kill it off
74$testcase_timeout=600;
75
76# You may need to change this from the default if your pose emulator
77# starts faster or slower than mine.
78#
79if ($ENV{'POSE_TIMEOUT'})
80{
81  $pose_timeout  = "$ENV{'POSE_TIMEOUT'}";
82}
83else
84{
85  $pose_timeout = 15;
86}
87
88$cmdline_len = @ARGV;
89if ($cmdline_len <= 0)
90{
91	print_usage();
92	exit (0);
93}
94
95&process_cmdline(@ARGV);
96&print_env();
97&verify_env_options();
98
99# Make the output directories with timestamps included in the
100# directory names.
101#
102mkdir $pdb_orig, 0777 || die "can not create directory <$pdb_orig>.";
103`chmod 777 $pdb_orig`;
104mkdir $pdb_new,  0777 || die "can not create directory <$pdb_new>.";
105`chmod 777 $pdb_new`;
106mkdir $xml_new,  0777 || die "can not create directory <$xml_new>.";
107`chmod 777 $xml_new`;
108
109&verify_prcs_exist("DBExporter.prc");
110
111if ($test_list ne "")
112{
113	open (TESTLIST, $test_list) || die "Couldn't open testcase list file $test_list";
114
115	while (<TESTLIST>)
116	{
117		&process_testcase($_);
118	}
119}
120elsif ($infile ne "")
121{
122	if (!defined($child_pid = fork()))
123	{
124		# there was an error forking a process
125		print "ERROR: Unable to fork process\n";
126		die "ERROR: Unable to fork process\n";
127	}
128	elsif ($child_pid)
129	{
130		# this is the parent process
131		# run the actual test here
132print "********\tPARENT (pid = $$): process_testcase...\n";
133		&process_testcase($infile);
134print "********\tPARENT (pid = $$): ...process_testcase finished normally\n";
135
136		# test finished normally, so kill the monitor
137		# that is running in the child process
138print "********\tPARENT (pid = $$): kill child process ($child_pid)\n";
139print "********\tPARENT Before:\n";
140system( "/usr/bin/ptree" );
141		kill( $child_pid );
142		kill( 9, $child_pid );
143print "********\tPARENT After:\n";
144system( "/usr/bin/ptree" );
145	}
146	else
147	{
148print "********\tCHILD (pid = $$): sleep for $testcase_timeout seconds\n";
149		# this is the child process
150		# wait on the test running in the parent, and
151		# kill it if it hasn't finished on time
152		sleep( $testcase_timeout );
153
154		# if the parent hasn't killed this process before it
155		# gets here, then it's probably hung, so we need to
156		# kill it.
157		print "********\tCHILD (pid = $$): TEST HUNG? still "
158			."running after [$testcase_timeout] seconds - "
159			."need to kill test process\n";
160		$parent = getppid;
161
162		if ( $parent != 1 ) {
163			print "********\nCHILD (pid = $$): Killing process ($parent)\n";
164			kill( $parent );
165			kill( 9, $parent );
166		} else {
167			# If we cannot get the ppid, then the parent might
168			# have died abnormally, before it got a chance to
169			# kill this (child) process.
170			print "********\nCHILD (pid = $$): cannot determine ppid - "
171				."terminating\n";
172system( "/usr/bin/ptree" );
173			exit(2);
174		}
175
176		exit(1);
177	}
178}
179else
180{
181	die ("You didn't supply any test cases to process");
182}
183
184print "Finished.\n";
185exit(0);
186
187#-------------------- End of main script ----------------------------------------
188
189#--------------------------------------------------------------------------------
190# Various sub routines
191#--------------------------------------------------------------------------------
192
193# process_testcase
194# infile - test case file name
195#
196# This is the main driver function
197# Opens the infile, reads it in parses it, runs the appropriate conversion
198# starts pose and load the file into the emulator. It launches the
199# appropriate editor and then runs the commands specified in the test case.
200# It then exports the file and saves it locally. Finally it is converted
201# back to the original office format.
202#
203sub process_testcase
204{
205    my $infile = $_[0];
206    my $convert_file = "";
207    my $rc;
208
209	# Process the inputfile
210	#
211	open (INFILE, $infile) || die "Failed to open test case <$infile>";
212
213	$running_testtype = "";
214
215	# Process the input file.
216	#
217	while ($c_inline = <INFILE>)
218	{
219	   chomp $c_inline;
220	   @entry = split('\|', $c_inline);
221
222	   # Process TEST
223	   #
224	   if ($c_inline =~ /^ *#/ || $c_inline =~ /^[ \t]*$/)
225	   {
226	      # skip comments and blank lines.
227	      #
228	      next;
229	   }
230	   elsif ("$entry[0]" eq "TEST")
231	   {
232	      # Close the test if one is running.
233	      #
234	      &close_program($convert_file);
235	      $running_testtype = "";
236
237	      $valid_test = 0;
238
239	      if ($#entry != 3)
240	      {
241	         print "\nERROR, $entry[0] invalid number of arguments\n\n";
242	      }
243	      else
244	      {
245	         # Start the test.
246	         #
247	         print "\nStarting test: $entry[1]\n";
248	         $convert_file = $entry[3];
249
250	         if ("$entry[2]"  =~ /[Qq][Uu][Ii][Cc][Kk][Ww][Oo][Rr][Dd]/)
251	         {
252	            $xml_extension = "sxw";
253	            $convert_to = "application/x-aportisdoc";
254
255	            # Convert XML file to pdb format.
256	            #
257	            $rc = &convert_to_pdb("$xml_orig", $convert_file, $xml_extension ,
258	               $convert_to,"$pdb_orig");
259	            if ($rc != 0)
260	            {
261	               print "\nERROR, problem converting file $convert_file\n\n";
262	            }
263	            else
264	            {
265	               # Start pose
266	               #
267	               $rc = &start_pose("$pose_exe",
268                     "$pose_prc/Quickword.PRC,$pose_prc/DBExporter.prc,$pdb_orig/$convert_file.pdb",
269	                 "Quickword", $pose_timeout);
270
271	               if ($rc == 0)
272	               {
273	                  &start_quickword();
274	                  $valid_test = 1;
275	                  $running_testtype = "QUICKWORD";
276                      print "\npose launched, begin automated test sequence for QuickWord\n";
277	               }
278                   else
279                   {
280                      &kill_pose();
281	                  $running_testtype = "";
282                   }
283	            }
284	         }
285	         elsif ("$entry[2]"  =~ /[Mm][Ii][Nn][Ii][Cc][Aa][Ll][Cc]/)
286	         {
287	            $xml_extension = "sxc";
288	            $convert_to = "application/x-minicalc";
289
290	            # Convert XML file to pdb format.
291	            #
292	            $rc = &convert_to_pdb("$xml_orig", $convert_file,
293                  $xml_extension, $convert_to,"$pdb_orig");
294	            if ($rc != 0)
295	            {
296	               print "\nERROR, problem converting file $convert_file\n\n";
297	            }
298	            else
299	            {
300	               # Get minicalc PDB file names, since an SXC file can
301	               # be converted to more than one.
302	               #
303	               $pdb_files="";
304	               $i = 1;
305	               while (-f "$pdb_orig/$convert_file-Sheet$i.pdb")
306	               {
307	                 if ($i > 1)
308	                 {
309	                   $pdb_files .= ",";
310	                 }
311	                 $pdb_files .= "$pdb_orig/$convert_file-Sheet$i.pdb";
312	                 $i++;
313	               }
314	               $number = $i-1;
315
316	               # Start pose
317	               #
318	               $rc = &start_pose("$pose_exe",
319	                  "$pose_prc/MiniCalc.prc,$pose_prc/DBExporter.prc,$pdb_files",
320	                  "MiniCalc", $pose_timeout);
321
322	               if ($rc == 0)
323	               {
324	                  &start_minicalc();
325	                  $valid_test = 1;
326	                  $running_testtype = "MINICALC";
327                      print "pose launched, begin automated test sequence for MiniCalc\n";
328	               }
329                   else
330                   {
331                      &kill_pose();
332	                  $running_testtype = "";
333                   }
334	            }
335	         }
336	         else
337	         {
338	            print "\nERROR, invalid extension <$entry[2]>\n\n";
339	         }
340	      }
341	   }
342
343	   # Process DB_EXPORT
344	   #
345	   elsif ("$entry[0]" eq "DB_EXPORT")
346	   {
347	      if ($#entry != 1)
348	      {
349         	print "\nERROR, $entry[0] invalid number of arguments\n\n";
350	      }
351	      else
352	      {
353	         &db_export($entry[1]);
354	      }
355	   }
356
357	   # Process TAP_APPLICATIONS
358	   #
359	   elsif ("$entry[0]" eq "TAP_APPLICATIONS")
360	   {
361	      if ($#entry != 0)
362	      {
363         	print "\nERROR, $entry[0] invalid number of arguments\n\n";
364	      }
365	      else
366	      {
367	         &tap_applications(0);
368	      }
369	   }
370
371	   # Process ENTER_STRING_AT_LOCATION
372	   #
373	   elsif ("$entry[0]" eq "ENTER_STRING_AT_LOCATION")
374	   {
375	      if ($#entry != 3)
376	      {
377	         print "\nERROR, $entry[0] invalid number of arguments\n\n";
378	      }
379	      elsif ($valid_test == 0)
380	      {
381	         print "\nERROR, can not process $entry[0] for invalid test\n\n";
382	      }
383	      else
384	      {
385	         &enter_string_at_location($entry[1], $entry[2],
386               $entry[3], $running_testtype);
387	      }
388	   }
389
390	   # Process TAP_PEN
391	   #
392	   elsif ("$entry[0]" eq "TAP_PEN")
393	   {
394	      if ($#entry != 2)
395	      {
396	         print "\nERROR, $entry[0] invalid number of arguments\n\n";
397	      }
398	      elsif ($valid_test == 0)
399	      {
400	         print "\nERROR, can not process $entry[0] for invalid test\n\n";
401	      }
402	      else
403	      {
404	         &pose_tap_pen($entry[1], $entry[2], 0);
405	      }
406	   }
407
408	   # Process TAP_BUTTON
409	   #
410	   elsif ("$entry[0]" eq "TAP_BUTTON")
411	   {
412	      if ($#entry != 1)
413	      {
414	         print "\nERROR, $entry[0] invalid number of arguments\n\n";
415	      }
416	      elsif ($valid_test == 0)
417	      {
418	         print "\nERROR, can not process $entry[0] for invalid test\n\n";
419	      }
420	      else
421	      {
422	         &pose_tap_button($entry[1], 0);
423	      }
424	   }
425
426           # Process TAP_PEN_HARD
427           #
428           elsif ("$entry[0]" eq "TAP_PEN_HARD")
429           {
430              if ($#entry != 2)
431              {
432                 print "\nERROR, $entry[0] invalid number of arguments\n\n";
433              }
434              elsif ($valid_test == 0)
435              {
436                 print "\nERROR, can not process $entry[0] for invalid test\n\n";
437              }
438              else
439              {
440                 &pose_tap_pen_hard($entry[1],$entry[2], 0);
441              }
442           }
443
444
445	   # Process SLEEP
446	   #
447	   elsif ("$entry[0]" eq "SLEEP")
448	   {
449	      if ($#entry != 1)
450	      {
451         	print "\nERROR, $entry[0] invalid number of arguments\n\n";
452	      }
453	      else
454	      {
455	         &pose_sleep($entry[1]);
456	      }
457	   }
458
459	   # Process MINICALC_ENTER_CELL
460	   #
461	   elsif ("$entry[0]" eq "MINICALC_ENTER_CELL")
462	   {
463	      if ($#entry != 3)
464	      {
465	         print "\nERROR, $entry[0] invalid number of arguments\n\n";
466	      }
467	      elsif ($valid_test == 0)
468	      {
469	         print "\nERROR, can not process $entry[0] for invalid test\n\n";
470	      }
471	      else
472	      {
473	         &minicalc_enter_cell($entry[1], $entry[2], $entry[3]);
474	      }
475	   }
476
477	   # Process QUICKWORD_FIND_REPLACE
478	   #
479	   elsif ("$entry[0]" eq "QUICKWORD_FIND_REPLACE")
480	   {
481	      if ($#entry != 2)
482	      {
483	         print "\nERROR, $entry[0] invalid number of arguments\n\n";
484	      }
485	      elsif ($valid_test == 0)
486	      {
487	         print "\nERROR, can not process $entry[0] for invalid test\n\n";
488	      }
489	      else
490	      {
491	         &quickword_find_replace($entry[1], $entry[2]);
492	      }
493	   }
494	   else
495	   {
496	      print "\nERROR, invalid line <$c_inline>\n";
497	   }
498	}
499
500	&close_program($convert_file);
501}
502
503# close_program
504# convert_file - file to export
505#
506# closes the program running in pose and kills pose
507#
508sub close_program
509{
510    my $convert_file = $_[0];
511
512	if ($running_testtype eq "QUICKWORD")
513    {
514        print "QuickWord test completed.\n";
515		&close_program_quickword($convert_file);
516    }
517	elsif ($running_testtype eq "MINICALC")
518    {
519        print "MiniCalc test completed.\n";
520		&close_program_minicalc($convert_file, $number);
521    }
522}
523
524# close_program_quickword
525# convert_file - file to export
526#
527# Closes quickword and kills pose
528#
529sub close_program_quickword
530{
531      my $convert_file = $_[0];
532      my $error_file = "./error.txt";
533      my $rc;
534
535      &close_quickword();
536
537      &db_export($convert_file);
538      print "Moving /tmp/$convert_file.pdb to $pdb_new\n";
539      `mv /tmp/$convert_file.pdb $pdb_new`;
540      `chmod 666 $pdb_new/$convert_file.pdb`;
541
542      &close_connection(1);
543      &kill_pose();
544      print "\nFinishing test...\n";
545
546      # The path of where to put the error file should be specified
547      # in the properties file.  Not sure if it is really necessary
548      # to put this out to a separate file.  STDOUT should be fine.
549      #
550      $rc = &convert_to_xml($xml_new, $xml_orig,
551        "$pdb_new/$convert_file.pdb", "application/x-aportisdoc" ,
552          "sxw", $convert_file, $merge_opt);
553      if ($rc != 0)
554      {
555        print "\nERROR, problem converting file $pdb_new/$convert_file.pdb\n\n";
556      }
557}
558
559# close_program_minicalc
560# convert_file - file to export
561#
562# Closes minicalc and kills pose
563#
564sub close_program_minicalc
565{
566	  my $convert_file = $_[0];
567	  my $num_files   = $_[1];
568	  my $list="";
569	  my $rc;
570
571	  &close_minicalc();
572
573	  for ($a=1; $a <= $num_files; $a++)
574	  {
575	    &db_export("$convert_file-Sheet$a");
576	    print "Moving /tmp/$convert_file-Sheet$a.pdb to $pdb_new/\n";
577	    `mv /tmp/$convert_file-Sheet$a.pdb $pdb_new/`;
578	    `chmod 666 $pdb_new/$convert_file-Sheet$a.pdb`;
579	  }
580
581	  &close_connection(1);
582	  &kill_pose();
583	  print "\nFinishing test...\n";
584
585	  for ($a=1; $a <= $num_files; $a++)
586	  {
587	    $list .="$pdb_new/$convert_file-Sheet$a.pdb "
588	  }
589
590	  $rc = &convert_to_xml($xml_new, $xml_orig, "$list",
591		  "application/x-minicalc", "sxc", $convert_file, $merge_opt);
592	  if ($rc != 0)
593	  {
594	    print "\nERROR, problem converting file(s) $list\n\n";
595	  }
596
597      &pose_sleep(5);
598}
599
600# print_usage
601#
602# prints the usage for this program.
603#
604sub print_usage
605{
606	print "Usage : test_driver.pl\n";
607	print "\t-test=<file> \t\t: individual test case file to run\n";
608	print "\t-list=<file> \t\t: list of test case files\n";
609	print "\t-env=<file> \t\t: Properites like file defining env\n";
610	print "\t-pose-exe=<fullpath> \t: path to pose executable\n";
611	print "\t-pose-prc=<path> \t: path to directory holding prc files\n";
612	print "\t-pdb-orig=<path> \t: directory to hold original pdb files\n";
613	print "\t-pdb-new=<path> \t: directory to hold new pdb files\n";
614	print "\t-xml-orig=<path> \t: directory to hold original office documents\n";
615	print "\t-xml-new=<path> \t: directory to hold new office documents\n";
616	print "\t-merge          \t: Invokes the merge option when converting\n";
617	print "\t                \t  from PDB back to XML.\n";
618}
619
620# print_env
621#
622# Prints the current environment.
623#
624sub print_env
625{
626	print "\nUsing the following environment:\n";
627	print "\tPOSE_EXE  = $pose_exe\n";
628	print "\tPOSE_PRC  = $pose_prc\n";
629	print "\tPDB_ORIG  = $pdb_orig\n";
630	print "\tPDB_NEW   = $pdb_new\n";
631	print "\tXML_ORIG  = $xml_orig\n";
632	print "\tXML_NEW   = $xml_new\n";
633}
634
635# process_cmdline
636#
637# command line options come in as key/value pairs.
638# read them and set the appropriate global variable
639#
640# Sets these globals: pose_exe, pose_prc, xml_orig, xml_new_dir,
641# xml_new, pdb_orig_dir, pdb_orig, pdb_new_dir, pdb_new.
642#
643sub process_cmdline
644{
645	foreach $i (@_)
646	{
647		my @arg= split('=', $i);
648		@arg[0] =~ tr/A-Z/a-z/;
649
650		if (@arg[0] eq "-pose-exe")
651		{
652			$pose_exe=$arg[1];
653		}
654		elsif (@arg[0] eq "-pose-prc")
655		{
656			$pose_prc=$arg[1];
657		}
658		elsif (@arg[0] eq "-pdb-orig")
659		{
660			$pdb_orig_dir=$arg[1];
661			$pdb_orig=$arg[1];
662		}
663		elsif (@arg[0] eq "-pdb-new")
664		{
665			$pdb_new_dir=$arg[1];
666			$pdb_new=$arg[1];
667		}
668		elsif (@arg[0] eq "-xml-orig")
669		{
670			$xml_orig=$arg[1];
671		}
672		elsif (@arg[0] eq "-xml-new")
673		{
674			$xml_new_dir=$arg[1];
675			$xml_new=$arg[1];
676		}
677		elsif (@arg[0] eq "-env")
678		{
679			&set_env_from_props($arg[1]);
680		}
681		elsif (@arg[0] eq "-list")
682		{
683			$test_list = $arg[1];
684		}
685		elsif (@arg[0] eq "-test")
686		{
687			$infile = $arg[1];
688		}
689		elsif (@arg[0] eq "-merge")
690		{
691		     $merge_opt = 1;
692		}
693		else
694		{
695			print_usage();
696			die "Incorrect command line";
697		}
698	}
699}
700
701# set_env_from_props
702# infile - property file
703#
704# Read the properties file, of the form key=value
705# Valid key values are :
706#	POSE_EXE
707#	POSE_PRC
708#	PDB_ORIG
709#	PDB_NEW
710#	XML_ORIG
711#	XML_NEW
712# If a value is found the appropriate global variable is set.
713#
714# Sets these globals: pose_exe, pose_prc, xml_orig, xml_new_dir,
715# xml_new, pdb_orig_dir, pdb_orig, pdb_new_dir, pdb_new.
716#
717sub set_env_from_props
718{
719    my $infile = $_[0];
720
721	open(PROPSFILE, $infile) || die "Could not open properties file <$infile>";
722
723	while (<PROPSFILE>)
724	{
725		chomp $_;
726		my @arg = split('=', $_);
727		@arg[0] =~ tr/a-z/A-Z/;
728		my $len = @arg;
729		if ($len != 2)
730		{
731			die "Malformed property in $arg[0]";
732		}
733		if (@arg[0] eq "POSE_EXE")
734		{
735			$pose_exe=$arg[1];
736		}
737		elsif (@arg[0] eq "POSE_PRC")
738		{
739			$pose_prc=$arg[1];
740		}
741		elsif (@arg[0] eq "PDB_ORIG")
742		{
743			$pdb_orig_dir=$arg[1];
744			$pdb_orig=$arg[1];
745		}
746		elsif (@arg[0] eq "PDB_NEW")
747		{
748			$pdb_new_dir=$arg[1];
749			$pdb_new=$arg[1];
750		}
751		elsif (@arg[0] eq "XML_ORIG")
752		{
753			$xml_orig=$arg[1];
754		}
755		elsif (@arg[0] eq "XML_NEW")
756		{
757			$xml_new_dir=$arg[1];
758			$xml_new=$arg[1];
759		}
760
761	}
762	close PROPSFILE;
763}
764
765# verify_env_options
766#
767# Verify that input options are correctly set.
768# Assumes pose_exe, pose_prc, xml_orig, xml_new_dir,
769# pdb_orig_dir, and pdb_new_dir are already set.
770#
771sub verify_env_options
772{
773	if (!-e "$pose_exe")
774	{
775		die "The pose executable cannot be found at $pose_exe.";
776	}
777	if (!-x $pose_exe)
778	{
779		die "$pose_exe exists but is not executable.";
780	}
781
782	if (!-e "$pose_prc")
783	{
784		die "The PRC directory specified as $pose_prc does not exist.";
785	}
786	if (!-d "$pose_prc")
787	{
788		die "The PRC location specified as $pose_prc exists, but is not a directory.";
789	}
790
791	if (!-e "$pdb_orig_dir")
792	{
793		die "The original PDB directory specified as $pdb_orig_dir does not exist.";
794	}
795	if (!-d "$pdb_orig_dir")
796	{
797		die "The original PDB directory specified as $pdb_orig_dir exists but is not a directory.";
798	}
799
800	if (!-e "$pdb_new_dir")
801	{
802		die "The new PDB directory specified as $pdb_new_dir does not exist.";
803	}
804	if (!-d "$pdb_new_dir")
805	{
806		die "The new PDB directory specified as $pdb_new_dir exists but is not a directory.";
807	}
808
809	if (!-e "$xml_orig")
810	{
811		die "The original Office document directory specified as $xml_orig does not exist.";
812	}
813	if (!-d "$xml_orig")
814	{
815		die "The original Office document location specified as $xml_orig exists but is not a directory.";
816	}
817
818	if (!-e "$xml_new_dir")
819	{
820		die "The new Office document directory specified as $xml_new_dir does not exist.";
821	}
822	if (!-d "$xml_new_dir")
823	{
824		die "The new Office document location specified as $xml_new_dir exists but is not a directory.";
825	}
826}
827
828# verify_prcs_exist
829# prcfile - the PRC file to check
830#
831# Verifies that the specified PRC file exists.
832#
833sub verify_prcs_exist
834{
835    my $prcfile = $_[0];
836
837	if (!-e "$pose_prc/$prcfile")
838	{
839		die "The pose PRC directory ($pose_prc) is correct, but I can't find $prcfile there.";
840	}
841}
842
843