getpart.pm 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #use strict;
  2. my @xml;
  3. my $warning=0;
  4. my $trace=0;
  5. sub decode_base64 {
  6. tr:A-Za-z0-9+/::cd; # remove non-base64 chars
  7. tr:A-Za-z0-9+/: -_:; # convert to uuencoded format
  8. my $len = pack("c", 32 + 0.75*length); # compute length byte
  9. return unpack("u", $len . $_); # uudecode and print
  10. }
  11. sub getpartattr {
  12. # if $part is undefined (ie only one argument) then
  13. # return the attributes of the section
  14. my ($section, $part)=@_;
  15. my %hash;
  16. my $inside=0;
  17. # print "Section: $section, part: $part\n";
  18. for(@xml) {
  19. # print "$inside: $_";
  20. if(!$inside && ($_ =~ /^ *\<$section/)) {
  21. $inside++;
  22. }
  23. if((1 ==$inside) && ( ($_ =~ /^ *\<$part([^>]*)/) ||
  24. !(defined($part)) )
  25. ) {
  26. $inside++;
  27. my $attr=$1;
  28. while($attr =~ s/ *([^=]*)= *(\"([^\"]*)\"|([^\"> ]*))//) {
  29. my ($var, $cont)=($1, $2);
  30. $cont =~ s/^\"(.*)\"$/$1/;
  31. $hash{$var}=$cont;
  32. }
  33. last;
  34. }
  35. elsif((2 ==$inside) && ($_ =~ /^ *\<\/$part/)) {
  36. $inside--;
  37. }
  38. }
  39. return %hash;
  40. }
  41. sub getpart {
  42. my ($section, $part)=@_;
  43. my @this;
  44. my $inside=0;
  45. my $base64=0;
  46. # print "Section: $section, part: $part\n";
  47. for(@xml) {
  48. # print "$inside: $_";
  49. if(!$inside && ($_ =~ /^ *\<$section/)) {
  50. $inside++;
  51. }
  52. elsif((1 ==$inside) && ($_ =~ /^ *\<$part[ \>]/)) {
  53. if($_ =~ /$part [^>]*base64=/) {
  54. # attempt to detect base64 encoded parts
  55. $base64=1;
  56. }
  57. $inside++;
  58. }
  59. elsif((2 ==$inside) && ($_ =~ /^ *\<\/$part/)) {
  60. $inside--;
  61. }
  62. elsif((1==$inside) && ($_ =~ /^ *\<\/$section/)) {
  63. if($trace) {
  64. print STDERR "*** getpart.pm: $section/$part returned data!\n";
  65. }
  66. if(!@this && $warning) {
  67. print STDERR "*** getpart.pm: $section/$part returned empty!\n";
  68. }
  69. if($base64) {
  70. # decode the whole array before returning it!
  71. for(@this) {
  72. my $decoded = decode_base64($_);
  73. $_ = $decoded;
  74. }
  75. }
  76. return @this;
  77. }
  78. elsif(2==$inside) {
  79. push @this, $_;
  80. }
  81. }
  82. if($warning) {
  83. print STDERR "*** getpart.pm: $section/$part returned empty!\n";
  84. }
  85. return @this; #empty!
  86. }
  87. sub loadtest {
  88. my ($file)=@_;
  89. undef @xml;
  90. if(open(XML, "<$file")) {
  91. binmode XML; # for crapage systems, use binary
  92. while(<XML>) {
  93. push @xml, $_;
  94. }
  95. close(XML);
  96. }
  97. else {
  98. # failure
  99. if($warning) {
  100. print STDERR "file $file wouldn't open!\n";
  101. }
  102. return 1;
  103. }
  104. return 0;
  105. }
  106. #
  107. # Strip off all lines that match the specified pattern and return
  108. # the new array.
  109. #
  110. sub striparray {
  111. my ($pattern, $arrayref) = @_;
  112. my @array;
  113. for(@$arrayref) {
  114. if($_ !~ /$pattern/) {
  115. push @array, $_;
  116. }
  117. }
  118. return @array;
  119. }
  120. #
  121. # pass array *REFERENCES* !
  122. #
  123. sub compareparts {
  124. my ($firstref, $secondref)=@_;
  125. my $first = join("", @$firstref);
  126. my $second = join("", @$secondref);
  127. # we cannot compare arrays index per index since with the base64 chunks,
  128. # they may not be "evenly" distributed
  129. # NOTE: this no longer strips off carriage returns from the arrays. Is that
  130. # really necessary? It ruins the testing of newlines. I believe it was once
  131. # added to enable tests on win32.
  132. if($first ne $second) {
  133. return 1;
  134. }
  135. return 0;
  136. }
  137. #
  138. # Write a given array to the specified file
  139. #
  140. sub writearray {
  141. my ($filename, $arrayref)=@_;
  142. open(TEMP, ">$filename");
  143. binmode(TEMP,":raw"); # cygwin fix by Kevin Roth
  144. for(@$arrayref) {
  145. print TEMP $_;
  146. }
  147. close(TEMP);
  148. }
  149. #
  150. # Load a specified file an return it as an array
  151. #
  152. sub loadarray {
  153. my ($filename)=@_;
  154. my @array;
  155. open(TEMP, "<$filename");
  156. while(<TEMP>) {
  157. push @array, $_;
  158. }
  159. close(TEMP);
  160. return @array;
  161. }
  162. # Given two array references, this function will store them in two temporary
  163. # files, run 'diff' on them, store the result and return the diff output!
  164. sub showdiff {
  165. my ($logdir, $firstref, $secondref)=@_;
  166. my $file1="$logdir/check-generated";
  167. my $file2="$logdir/check-expected";
  168. open(TEMP, ">$file1");
  169. for(@$firstref) {
  170. print TEMP $_;
  171. }
  172. close(TEMP);
  173. open(TEMP, ">$file2");
  174. for(@$secondref) {
  175. print TEMP $_;
  176. }
  177. close(TEMP);
  178. my @out = `diff -u $file2 $file1 2>/dev/null`;
  179. if(!$out[0]) {
  180. @out = `diff -c $file2 $file1 2>/dev/null`;
  181. }
  182. return @out;
  183. }
  184. 1;