Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

251 lines
6.9 KiB

  1. @rem = '
  2. @goto endofperl
  3. ';
  4. sub FindBalParens {
  5. my $record = shift;
  6. my ($pre, $match, $result);
  7. my $count = 0;
  8. my $post = '';
  9. my $trailbs = '';
  10. my $leftparfound = 0;
  11. #
  12. # Look for the first expression with balanced parens.
  13. # Parens that are part of a quoted string or escaped with a backslash are skipped.
  14. #
  15. # The return value is a 3 element array:
  16. # [0] n=-1 means extra right parens found.
  17. # n=0 means a balanced expr found or no parens at all.
  18. # n>0 means n extra Left Parens found.
  19. # [1] contains the consumed part of the input string if [0] <= 0 above.
  20. # otherwise it contains the entire input string
  21. # [2] contains the remaining part of the string if [0] <= 0 above
  22. # otherwise it is the null string except for the no parens found case.
  23. #
  24. # In the case of no parens found outside of quoted string or escaped chars
  25. # [0] is zero, [1] is the input string, [2] = "FRS-NO-PARENS".
  26. #
  27. print $record, "\n";
  28. if (!($record =~ m/[\(\)]/)) {
  29. print "0, Found: $record Rest: FRS-NO-PARENS\n";
  30. return [0, $record, "FRS-NO-PARENS"]; # return 0 if no parens found.
  31. }
  32. if ($record =~ m/\\+$/) {
  33. ($trailbs) = $record =~ m/(\\+$)/; # strip trailing \ so they don't foul marker
  34. $record =~ s/(\\+$)//;
  35. }
  36. $record .= '(*)'; # append marker
  37. while ( $record =~ m{
  38. ( # Start of captured result
  39. (?:[^\"\\\(\)]* # swallow chars up to " or \ or ( or )
  40. (?: # followed by 4 alternatives
  41. (?=\() # 1. positive lookahead assertion for ( ends match
  42. |(?=\)) # 2. positive lookahead assertion for ) ends match
  43. |(?:\\.) # 3. if backslash, swallow it + next char
  44. |(?:\" # 4. if leading quote then find end of quoted
  45. # string but respect backslash escape char.
  46. (?:[^\"\\]* # swallow up to next " or \ if any
  47. (?:\\. # if prev ended on \ then swallow it + next char
  48. [^\"\\]* # continue to next quote or \, if any
  49. )* # loop if we hit \
  50. )
  51. \"? # consume trailing quote, if any. could be eos
  52. )
  53. ) # end of 4 alternatives
  54. )+ # continue after quoted string or \
  55. [\(\)]? # end match with next ( or ) (if any) ends captured result
  56. | (?:[^\(]+) /? # no quotes up to next (, if any, or eos
  57. | \( # eat extra (
  58. )
  59. }gx ) {
  60. $pre = $`;
  61. $match = $+;
  62. $post = $';
  63. #
  64. # if the marker is consumed in the match then we must be
  65. # in the middle of a quoted string so leave count unchanged.
  66. #
  67. if (substr($+,-3,3) ne '(*)') {
  68. if (substr($+,-1,1) eq ')') {$count--;}
  69. if (substr($+,-1,1) eq '(') {$count++;}
  70. #
  71. # record left paren found if count > 0 and it wasn't
  72. # caused by a split marker.
  73. #
  74. if (($count > 0) && ($post ne '*)')) {$leftparfound = 1;}
  75. }
  76. #print "($count) paren match:'$+'\n";
  77. #
  78. # if the count hits zero then return balanced part.
  79. # if the count goes negative then we've seen more right parens than left parens
  80. #
  81. if ($count le 0) {goto RETURN;}
  82. }
  83. RETURN:
  84. #
  85. # Clean off the marker.
  86. #
  87. $result = $pre . $match;
  88. if ($post =~ m/\(\*\)$/) {
  89. substr($post, -3, 3) = '';
  90. } else {
  91. if ($post eq '*)') {
  92. $post = '';
  93. substr($result, -1, 1) = '';
  94. } else {
  95. $result =~ s/\(\*\)$//;
  96. }
  97. }
  98. #
  99. # add back trailing backslashes
  100. #
  101. if ($post ne "") {
  102. $post = $post . $trailbs;
  103. } else {
  104. $result = $result . $trailbs;
  105. #
  106. # The entire string was consumed so if the Count is zero
  107. # check if we ever found an unquoted left paren. If not
  108. # then return "FRS-NO-PARENS" as the result in [2].
  109. #
  110. if (($count eq 0) && ($leftparfound eq 0)) {$post = "FRS-NO-PARENS";}
  111. }
  112. print "$count, Found: $result Rest: $post \n";
  113. return [$count, $result , $post ];
  114. }
  115. $rest = '/RP=foo /R\P="D:\RSB" /SP="D:\staging" /COMPUTER="bchb/hubsite/servers/" /NAME="bchb.hubsite.ajax.com" /XXX/';
  116. print "\n\n";
  117. @pars = &FindBalParens ($rest);
  118. $rest = ' () (foo)';
  119. print "\n\n";
  120. @pars = &FindBalParens ($rest);
  121. $rest = ' ( "(" \) )';
  122. print "\n\n";
  123. @pars = &FindBalParens ($rest);
  124. $rest = '(kl(lkldkf(/ /) "))))))" ) (()cc) "(" \) ) (junk)';
  125. print "\n\n";
  126. @pars = &FindBalParens ($rest);
  127. $rest = '(kl(lkldkf(/ /) "))))))" ) (()unbalanced\) "(" \) ) junk';
  128. print "\n\n";
  129. @pars = &FindBalParens ($rest);
  130. $rest = ' junk "()" \( (kl(lkldkf(/ /) "))))))" ) (()unbalanced\) "(" \) ) junk';
  131. print "\n\n";
  132. @pars = &FindBalParens ($rest);
  133. $rest = 'junk';
  134. print "\n\n";
  135. @pars = &FindBalParens ($rest);
  136. $rest = ')))';
  137. print "\n\n";
  138. @pars = &FindBalParens ($rest);
  139. $rest = '"))) (((" \) \(';
  140. print "\n\n";
  141. @pars = &FindBalParens ($rest);
  142. $rest = '"))) ((( ) (';
  143. print "\n\n";
  144. @pars = &FindBalParens ($rest);
  145. $rest = '"))) ((( ) (';
  146. print "\n\n";
  147. @pars = &FindBalParens ($rest);
  148. $rest = 'junk"(';
  149. print "\n\n";
  150. @pars = &FindBalParens ($rest);
  151. $rest = 'junk\(';
  152. print "\n\n";
  153. @pars = &FindBalParens ($rest);
  154. $rest = 'junk';
  155. print "\n\n";
  156. @pars = &FindBalParens ($rest);
  157. $rest = '"junk(*)';
  158. print "\n\n";
  159. @pars = &FindBalParens ($rest);
  160. $rest = '"junk"(*)';
  161. print "\n\n";
  162. @pars = &FindBalParens ($rest);
  163. $rest = '"junk"(*)\\';
  164. print "\n\n";
  165. @pars = &FindBalParens ($rest);
  166. $rest = '"junk"(*)\\\\\\';
  167. print "\n\n";
  168. @pars = &FindBalParens ($rest);
  169. $rest = '"junk (*)\\';
  170. print "\n\n";
  171. @pars = &FindBalParens ($rest);
  172. $rest = '"junk (*)\\\\\\';
  173. print "\n\n";
  174. @pars = &FindBalParens ($rest);
  175. $rest = ')';
  176. print "\n\n";
  177. @pars = &FindBalParens ($rest);
  178. $rest = ')(';
  179. print "\n\n";
  180. @pars = &FindBalParens ($rest);
  181. $rest = '(';
  182. print "\n\n";
  183. @pars = &FindBalParens ($rest);
  184. $rest = ' junk "()" \() (kl(lkldkf(/ /) ))"))))))" ) (()unbalanced\) "(" \) ) junk';
  185. print "\n\n";
  186. @pars = &FindBalParens ($rest);
  187. $rest = 'junk \)\( )';
  188. print "\n\n";
  189. @pars = &FindBalParens ($rest);
  190. __END__
  191. :endofperl
  192. @rem -d -w
  193. @perl -w %~dpn0.cmd %*
  194. @goto :QUIT
  195. @:QUIT