You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2011/06/05 07:32:26 UTC

svn commit: r1131792 [8/13] - in /incubator/mesos/trunk: ./ src/ src/third_party/gtest-1.4.0-patched/ src/third_party/gtest-1.4.0-patched/build-aux/ src/third_party/gtest-1.4.0-patched/codegear/ src/third_party/gtest-1.4.0-patched/include/gtest/ src/th...

Copied: incubator/mesos/trunk/src/third_party/gtest-1.5.0/scripts/gtest-config.in (from r1131791, incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/scripts/gtest-config.in)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/third_party/gtest-1.5.0/scripts/gtest-config.in?p2=incubator/mesos/trunk/src/third_party/gtest-1.5.0/scripts/gtest-config.in&p1=incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/scripts/gtest-config.in&r1=1131791&r2=1131792&rev=1131792&view=diff
==============================================================================
--- incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/scripts/gtest-config.in (original)
+++ incubator/mesos/trunk/src/third_party/gtest-1.5.0/scripts/gtest-config.in Sun Jun  5 05:32:17 2011
@@ -214,7 +214,7 @@ if test "${this_bindir}" = "${this_bindi
   # TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we
   # should work to remove it, and/or remove libtool altogether, replacing it
   # with direct references to the library and a link path.
-  gtest_libs="${build_dir}/lib/libgtest.la"
+  gtest_libs="${build_dir}/lib/libgtest.la @PTHREAD_CFLAGS@ @PTHREAD_LIBS@"
   gtest_ldflags=""
 
   # We provide hooks to include from either the source or build dir, where the
@@ -222,15 +222,15 @@ if test "${this_bindir}" = "${this_bindi
   # build rules for generated headers and have them automatically be preferred
   # over provided versions.
   gtest_cppflags="-I${build_dir}/include -I${src_dir}/include"
-  gtest_cxxflags=""
+  gtest_cxxflags="@PTHREAD_CFLAGS@"
 else
   # We're using an installed gtest, although it may be staged under some
   # prefix. Assume (as our own libraries do) that we can resolve the prefix,
   # and are present in the dynamic link paths.
   gtest_ldflags="-L${libdir}"
-  gtest_libs="-l${name}"
+  gtest_libs="-l${name} @PTHREAD_CFLAGS@ @PTHREAD_LIBS@"
   gtest_cppflags="-I${includedir}"
-  gtest_cxxflags=""
+  gtest_cxxflags="@PTHREAD_CFLAGS@"
 fi
 
 # Do an installation query if requested.

Added: incubator/mesos/trunk/src/third_party/gtest-1.5.0/scripts/pump.py
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/third_party/gtest-1.5.0/scripts/pump.py?rev=1131792&view=auto
==============================================================================
--- incubator/mesos/trunk/src/third_party/gtest-1.5.0/scripts/pump.py (added)
+++ incubator/mesos/trunk/src/third_party/gtest-1.5.0/scripts/pump.py Sun Jun  5 05:32:17 2011
@@ -0,0 +1,835 @@
+#!/usr/bin/env python
+#
+# Copyright 2008, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""pump v0.1 - Pretty Useful for Meta Programming.
+
+A tool for preprocessor meta programming.  Useful for generating
+repetitive boilerplate code.  Especially useful for writing C++
+classes, functions, macros, and templates that need to work with
+various number of arguments.
+
+USAGE:
+       pump.py SOURCE_FILE
+
+EXAMPLES:
+       pump.py foo.cc.pump
+         Converts foo.cc.pump to foo.cc.
+
+GRAMMAR:
+       CODE ::= ATOMIC_CODE*
+       ATOMIC_CODE ::= $var ID = EXPRESSION
+           | $var ID = [[ CODE ]]
+           | $range ID EXPRESSION..EXPRESSION
+           | $for ID SEPARATOR [[ CODE ]]
+           | $($)
+           | $ID
+           | $(EXPRESSION)
+           | $if EXPRESSION [[ CODE ]] ELSE_BRANCH
+           | [[ CODE ]]
+           | RAW_CODE
+       SEPARATOR ::= RAW_CODE | EMPTY
+       ELSE_BRANCH ::= $else [[ CODE ]]
+           | $elif EXPRESSION [[ CODE ]] ELSE_BRANCH
+           | EMPTY
+       EXPRESSION has Python syntax.
+"""
+
+__author__ = 'wan@google.com (Zhanyong Wan)'
+
+import os
+import re
+import sys
+
+
+TOKEN_TABLE = [
+    (re.compile(r'\$var\s+'), '$var'),
+    (re.compile(r'\$elif\s+'), '$elif'),
+    (re.compile(r'\$else\s+'), '$else'),
+    (re.compile(r'\$for\s+'), '$for'),
+    (re.compile(r'\$if\s+'), '$if'),
+    (re.compile(r'\$range\s+'), '$range'),
+    (re.compile(r'\$[_A-Za-z]\w*'), '$id'),
+    (re.compile(r'\$\(\$\)'), '$($)'),
+    (re.compile(r'\$\$.*'), '$$'),
+    (re.compile(r'\$'), '$'),
+    (re.compile(r'\[\[\n?'), '[['),
+    (re.compile(r'\]\]\n?'), ']]'),
+    ]
+
+
+class Cursor:
+  """Represents a position (line and column) in a text file."""
+
+  def __init__(self, line=-1, column=-1):
+    self.line = line
+    self.column = column
+
+  def __eq__(self, rhs):
+    return self.line == rhs.line and self.column == rhs.column
+
+  def __ne__(self, rhs):
+    return not self == rhs
+
+  def __lt__(self, rhs):
+    return self.line < rhs.line or (
+        self.line == rhs.line and self.column < rhs.column)
+
+  def __le__(self, rhs):
+    return self < rhs or self == rhs
+
+  def __gt__(self, rhs):
+    return rhs < self
+
+  def __ge__(self, rhs):
+    return rhs <= self
+
+  def __str__(self):
+    if self == Eof():
+      return 'EOF'
+    else:
+      return '%s(%s)' % (self.line + 1, self.column)
+
+  def __add__(self, offset):
+    return Cursor(self.line, self.column + offset)
+
+  def __sub__(self, offset):
+    return Cursor(self.line, self.column - offset)
+
+  def Clone(self):
+    """Returns a copy of self."""
+
+    return Cursor(self.line, self.column)
+
+
+# Special cursor to indicate the end-of-file.
+def Eof():
+  """Returns the special cursor to denote the end-of-file."""
+  return Cursor(-1, -1)
+
+
+class Token:
+  """Represents a token in a Pump source file."""
+
+  def __init__(self, start=None, end=None, value=None, token_type=None):
+    if start is None:
+      self.start = Eof()
+    else:
+      self.start = start
+    if end is None:
+      self.end = Eof()
+    else:
+      self.end = end
+    self.value = value
+    self.token_type = token_type
+
+  def __str__(self):
+    return 'Token @%s: \'%s\' type=%s' % (
+        self.start, self.value, self.token_type)
+
+  def Clone(self):
+    """Returns a copy of self."""
+
+    return Token(self.start.Clone(), self.end.Clone(), self.value,
+                 self.token_type)
+
+
+def StartsWith(lines, pos, string):
+  """Returns True iff the given position in lines starts with 'string'."""
+
+  return lines[pos.line][pos.column:].startswith(string)
+
+
+def FindFirstInLine(line, token_table):
+  best_match_start = -1
+  for (regex, token_type) in token_table:
+    m = regex.search(line)
+    if m:
+      # We found regex in lines
+      if best_match_start < 0 or m.start() < best_match_start:
+        best_match_start = m.start()
+        best_match_length = m.end() - m.start()
+        best_match_token_type = token_type
+
+  if best_match_start < 0:
+    return None
+
+  return (best_match_start, best_match_length, best_match_token_type)
+
+
+def FindFirst(lines, token_table, cursor):
+  """Finds the first occurrence of any string in strings in lines."""
+
+  start = cursor.Clone()
+  cur_line_number = cursor.line
+  for line in lines[start.line:]:
+    if cur_line_number == start.line:
+      line = line[start.column:]
+    m = FindFirstInLine(line, token_table)
+    if m:
+      # We found a regex in line.
+      (start_column, length, token_type) = m
+      if cur_line_number == start.line:
+        start_column += start.column
+      found_start = Cursor(cur_line_number, start_column)
+      found_end = found_start + length
+      return MakeToken(lines, found_start, found_end, token_type)
+    cur_line_number += 1
+  # We failed to find str in lines
+  return None
+
+
+def SubString(lines, start, end):
+  """Returns a substring in lines."""
+
+  if end == Eof():
+    end = Cursor(len(lines) - 1, len(lines[-1]))
+
+  if start >= end:
+    return ''
+
+  if start.line == end.line:
+    return lines[start.line][start.column:end.column]
+
+  result_lines = ([lines[start.line][start.column:]] +
+                  lines[start.line + 1:end.line] +
+                  [lines[end.line][:end.column]])
+  return ''.join(result_lines)
+
+
+def MakeToken(lines, start, end, token_type):
+  """Creates a new instance of Token."""
+
+  return Token(start, end, SubString(lines, start, end), token_type)
+
+
+def ParseToken(lines, pos, regex, token_type):
+  line = lines[pos.line][pos.column:]
+  m = regex.search(line)
+  if m and not m.start():
+    return MakeToken(lines, pos, pos + m.end(), token_type)
+  else:
+    print 'ERROR: %s expected at %s.' % (token_type, pos)
+    sys.exit(1)
+
+
+ID_REGEX = re.compile(r'[_A-Za-z]\w*')
+EQ_REGEX = re.compile(r'=')
+REST_OF_LINE_REGEX = re.compile(r'.*?(?=$|\$\$)')
+OPTIONAL_WHITE_SPACES_REGEX = re.compile(r'\s*')
+WHITE_SPACE_REGEX = re.compile(r'\s')
+DOT_DOT_REGEX = re.compile(r'\.\.')
+
+
+def Skip(lines, pos, regex):
+  line = lines[pos.line][pos.column:]
+  m = re.search(regex, line)
+  if m and not m.start():
+    return pos + m.end()
+  else:
+    return pos
+
+
+def SkipUntil(lines, pos, regex, token_type):
+  line = lines[pos.line][pos.column:]
+  m = re.search(regex, line)
+  if m:
+    return pos + m.start()
+  else:
+    print ('ERROR: %s expected on line %s after column %s.' %
+           (token_type, pos.line + 1, pos.column))
+    sys.exit(1)
+
+
+def ParseExpTokenInParens(lines, pos):
+  def ParseInParens(pos):
+    pos = Skip(lines, pos, OPTIONAL_WHITE_SPACES_REGEX)
+    pos = Skip(lines, pos, r'\(')
+    pos = Parse(pos)
+    pos = Skip(lines, pos, r'\)')
+    return pos
+
+  def Parse(pos):
+    pos = SkipUntil(lines, pos, r'\(|\)', ')')
+    if SubString(lines, pos, pos + 1) == '(':
+      pos = Parse(pos + 1)
+      pos = Skip(lines, pos, r'\)')
+      return Parse(pos)
+    else:
+      return pos
+
+  start = pos.Clone()
+  pos = ParseInParens(pos)
+  return MakeToken(lines, start, pos, 'exp')
+
+
+def RStripNewLineFromToken(token):
+  if token.value.endswith('\n'):
+    return Token(token.start, token.end, token.value[:-1], token.token_type)
+  else:
+    return token
+
+
+def TokenizeLines(lines, pos):
+  while True:
+    found = FindFirst(lines, TOKEN_TABLE, pos)
+    if not found:
+      yield MakeToken(lines, pos, Eof(), 'code')
+      return
+
+    if found.start == pos:
+      prev_token = None
+      prev_token_rstripped = None
+    else:
+      prev_token = MakeToken(lines, pos, found.start, 'code')
+      prev_token_rstripped = RStripNewLineFromToken(prev_token)
+
+    if found.token_type == '$$':  # A meta comment.
+      if prev_token_rstripped:
+        yield prev_token_rstripped
+      pos = Cursor(found.end.line + 1, 0)
+    elif found.token_type == '$var':
+      if prev_token_rstripped:
+        yield prev_token_rstripped
+      yield found
+      id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
+      yield id_token
+      pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX)
+
+      eq_token = ParseToken(lines, pos, EQ_REGEX, '=')
+      yield eq_token
+      pos = Skip(lines, eq_token.end, r'\s*')
+
+      if SubString(lines, pos, pos + 2) != '[[':
+        exp_token = ParseToken(lines, pos, REST_OF_LINE_REGEX, 'exp')
+        yield exp_token
+        pos = Cursor(exp_token.end.line + 1, 0)
+    elif found.token_type == '$for':
+      if prev_token_rstripped:
+        yield prev_token_rstripped
+      yield found
+      id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
+      yield id_token
+      pos = Skip(lines, id_token.end, WHITE_SPACE_REGEX)
+    elif found.token_type == '$range':
+      if prev_token_rstripped:
+        yield prev_token_rstripped
+      yield found
+      id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
+      yield id_token
+      pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX)
+
+      dots_pos = SkipUntil(lines, pos, DOT_DOT_REGEX, '..')
+      yield MakeToken(lines, pos, dots_pos, 'exp')
+      yield MakeToken(lines, dots_pos, dots_pos + 2, '..')
+      pos = dots_pos + 2
+      new_pos = Cursor(pos.line + 1, 0)
+      yield MakeToken(lines, pos, new_pos, 'exp')
+      pos = new_pos
+    elif found.token_type == '$':
+      if prev_token:
+        yield prev_token
+      yield found
+      exp_token = ParseExpTokenInParens(lines, found.end)
+      yield exp_token
+      pos = exp_token.end
+    elif (found.token_type == ']]' or found.token_type == '$if' or
+          found.token_type == '$elif' or found.token_type == '$else'):
+      if prev_token_rstripped:
+        yield prev_token_rstripped
+      yield found
+      pos = found.end
+    else:
+      if prev_token:
+        yield prev_token
+      yield found
+      pos = found.end
+
+
+def Tokenize(s):
+  lines = s.splitlines(True)
+  return TokenizeLines(lines, Cursor(0, 0))
+
+
+class CodeNode:
+  def __init__(self, atomic_code_list=None):
+    self.atomic_code = atomic_code_list
+
+
+class VarNode:
+  def __init__(self, identifier=None, atomic_code=None):
+    self.identifier = identifier
+    self.atomic_code = atomic_code
+
+
+class RangeNode:
+  def __init__(self, identifier=None, exp1=None, exp2=None):
+    self.identifier = identifier
+    self.exp1 = exp1
+    self.exp2 = exp2
+
+
+class ForNode:
+  def __init__(self, identifier=None, sep=None, code=None):
+    self.identifier = identifier
+    self.sep = sep
+    self.code = code
+
+
+class ElseNode:
+  def __init__(self, else_branch=None):
+    self.else_branch = else_branch
+
+
+class IfNode:
+  def __init__(self, exp=None, then_branch=None, else_branch=None):
+    self.exp = exp
+    self.then_branch = then_branch
+    self.else_branch = else_branch
+
+
+class RawCodeNode:
+  def __init__(self, token=None):
+    self.raw_code = token
+
+
+class LiteralDollarNode:
+  def __init__(self, token):
+    self.token = token
+
+
+class ExpNode:
+  def __init__(self, token, python_exp):
+    self.token = token
+    self.python_exp = python_exp
+
+
+def PopFront(a_list):
+  head = a_list[0]
+  a_list[:1] = []
+  return head
+
+
+def PushFront(a_list, elem):
+  a_list[:0] = [elem]
+
+
+def PopToken(a_list, token_type=None):
+  token = PopFront(a_list)
+  if token_type is not None and token.token_type != token_type:
+    print 'ERROR: %s expected at %s' % (token_type, token.start)
+    print 'ERROR: %s found instead' % (token,)
+    sys.exit(1)
+
+  return token
+
+
+def PeekToken(a_list):
+  if not a_list:
+    return None
+
+  return a_list[0]
+
+
+def ParseExpNode(token):
+  python_exp = re.sub(r'([_A-Za-z]\w*)', r'self.GetValue("\1")', token.value)
+  return ExpNode(token, python_exp)
+
+
+def ParseElseNode(tokens):
+  def Pop(token_type=None):
+    return PopToken(tokens, token_type)
+
+  next = PeekToken(tokens)
+  if not next:
+    return None
+  if next.token_type == '$else':
+    Pop('$else')
+    Pop('[[')
+    code_node = ParseCodeNode(tokens)
+    Pop(']]')
+    return code_node
+  elif next.token_type == '$elif':
+    Pop('$elif')
+    exp = Pop('code')
+    Pop('[[')
+    code_node = ParseCodeNode(tokens)
+    Pop(']]')
+    inner_else_node = ParseElseNode(tokens)
+    return CodeNode([IfNode(ParseExpNode(exp), code_node, inner_else_node)])
+  elif not next.value.strip():
+    Pop('code')
+    return ParseElseNode(tokens)
+  else:
+    return None
+
+
+def ParseAtomicCodeNode(tokens):
+  def Pop(token_type=None):
+    return PopToken(tokens, token_type)
+
+  head = PopFront(tokens)
+  t = head.token_type
+  if t == 'code':
+    return RawCodeNode(head)
+  elif t == '$var':
+    id_token = Pop('id')
+    Pop('=')
+    next = PeekToken(tokens)
+    if next.token_type == 'exp':
+      exp_token = Pop()
+      return VarNode(id_token, ParseExpNode(exp_token))
+    Pop('[[')
+    code_node = ParseCodeNode(tokens)
+    Pop(']]')
+    return VarNode(id_token, code_node)
+  elif t == '$for':
+    id_token = Pop('id')
+    next_token = PeekToken(tokens)
+    if next_token.token_type == 'code':
+      sep_token = next_token
+      Pop('code')
+    else:
+      sep_token = None
+    Pop('[[')
+    code_node = ParseCodeNode(tokens)
+    Pop(']]')
+    return ForNode(id_token, sep_token, code_node)
+  elif t == '$if':
+    exp_token = Pop('code')
+    Pop('[[')
+    code_node = ParseCodeNode(tokens)
+    Pop(']]')
+    else_node = ParseElseNode(tokens)
+    return IfNode(ParseExpNode(exp_token), code_node, else_node)
+  elif t == '$range':
+    id_token = Pop('id')
+    exp1_token = Pop('exp')
+    Pop('..')
+    exp2_token = Pop('exp')
+    return RangeNode(id_token, ParseExpNode(exp1_token),
+                     ParseExpNode(exp2_token))
+  elif t == '$id':
+    return ParseExpNode(Token(head.start + 1, head.end, head.value[1:], 'id'))
+  elif t == '$($)':
+    return LiteralDollarNode(head)
+  elif t == '$':
+    exp_token = Pop('exp')
+    return ParseExpNode(exp_token)
+  elif t == '[[':
+    code_node = ParseCodeNode(tokens)
+    Pop(']]')
+    return code_node
+  else:
+    PushFront(tokens, head)
+    return None
+
+
+def ParseCodeNode(tokens):
+  atomic_code_list = []
+  while True:
+    if not tokens:
+      break
+    atomic_code_node = ParseAtomicCodeNode(tokens)
+    if atomic_code_node:
+      atomic_code_list.append(atomic_code_node)
+    else:
+      break
+  return CodeNode(atomic_code_list)
+
+
+def Convert(file_path):
+  s = file(file_path, 'r').read()
+  tokens = []
+  for token in Tokenize(s):
+    tokens.append(token)
+  code_node = ParseCodeNode(tokens)
+  return code_node
+
+
+class Env:
+  def __init__(self):
+    self.variables = []
+    self.ranges = []
+
+  def Clone(self):
+    clone = Env()
+    clone.variables = self.variables[:]
+    clone.ranges = self.ranges[:]
+    return clone
+
+  def PushVariable(self, var, value):
+    # If value looks like an int, store it as an int.
+    try:
+      int_value = int(value)
+      if ('%s' % int_value) == value:
+        value = int_value
+    except Exception:
+      pass
+    self.variables[:0] = [(var, value)]
+
+  def PopVariable(self):
+    self.variables[:1] = []
+
+  def PushRange(self, var, lower, upper):
+    self.ranges[:0] = [(var, lower, upper)]
+
+  def PopRange(self):
+    self.ranges[:1] = []
+
+  def GetValue(self, identifier):
+    for (var, value) in self.variables:
+      if identifier == var:
+        return value
+
+    print 'ERROR: meta variable %s is undefined.' % (identifier,)
+    sys.exit(1)
+
+  def EvalExp(self, exp):
+    try:
+      result = eval(exp.python_exp)
+    except Exception, e:
+      print 'ERROR: caught exception %s: %s' % (e.__class__.__name__, e)
+      print ('ERROR: failed to evaluate meta expression %s at %s' %
+             (exp.python_exp, exp.token.start))
+      sys.exit(1)
+    return result
+
+  def GetRange(self, identifier):
+    for (var, lower, upper) in self.ranges:
+      if identifier == var:
+        return (lower, upper)
+
+    print 'ERROR: range %s is undefined.' % (identifier,)
+    sys.exit(1)
+
+
+class Output:
+  def __init__(self):
+    self.string = ''
+
+  def GetLastLine(self):
+    index = self.string.rfind('\n')
+    if index < 0:
+      return ''
+
+    return self.string[index + 1:]
+
+  def Append(self, s):
+    self.string += s
+
+
+def RunAtomicCode(env, node, output):
+  if isinstance(node, VarNode):
+    identifier = node.identifier.value.strip()
+    result = Output()
+    RunAtomicCode(env.Clone(), node.atomic_code, result)
+    value = result.string
+    env.PushVariable(identifier, value)
+  elif isinstance(node, RangeNode):
+    identifier = node.identifier.value.strip()
+    lower = int(env.EvalExp(node.exp1))
+    upper = int(env.EvalExp(node.exp2))
+    env.PushRange(identifier, lower, upper)
+  elif isinstance(node, ForNode):
+    identifier = node.identifier.value.strip()
+    if node.sep is None:
+      sep = ''
+    else:
+      sep = node.sep.value
+    (lower, upper) = env.GetRange(identifier)
+    for i in range(lower, upper + 1):
+      new_env = env.Clone()
+      new_env.PushVariable(identifier, i)
+      RunCode(new_env, node.code, output)
+      if i != upper:
+        output.Append(sep)
+  elif isinstance(node, RawCodeNode):
+    output.Append(node.raw_code.value)
+  elif isinstance(node, IfNode):
+    cond = env.EvalExp(node.exp)
+    if cond:
+      RunCode(env.Clone(), node.then_branch, output)
+    elif node.else_branch is not None:
+      RunCode(env.Clone(), node.else_branch, output)
+  elif isinstance(node, ExpNode):
+    value = env.EvalExp(node)
+    output.Append('%s' % (value,))
+  elif isinstance(node, LiteralDollarNode):
+    output.Append('$')
+  elif isinstance(node, CodeNode):
+    RunCode(env.Clone(), node, output)
+  else:
+    print 'BAD'
+    print node
+    sys.exit(1)
+
+
+def RunCode(env, code_node, output):
+  for atomic_code in code_node.atomic_code:
+    RunAtomicCode(env, atomic_code, output)
+
+
+def IsComment(cur_line):
+  return '//' in cur_line
+
+
+def IsInPreprocessorDirevative(prev_lines, cur_line):
+  if cur_line.lstrip().startswith('#'):
+    return True
+  return prev_lines != [] and prev_lines[-1].endswith('\\')
+
+
+def WrapComment(line, output):
+  loc = line.find('//')
+  before_comment = line[:loc].rstrip()
+  if before_comment == '':
+    indent = loc
+  else:
+    output.append(before_comment)
+    indent = len(before_comment) - len(before_comment.lstrip())
+  prefix = indent*' ' + '// '
+  max_len = 80 - len(prefix)
+  comment = line[loc + 2:].strip()
+  segs = [seg for seg in re.split(r'(\w+\W*)', comment) if seg != '']
+  cur_line = ''
+  for seg in segs:
+    if len((cur_line + seg).rstrip()) < max_len:
+      cur_line += seg
+    else:
+      if cur_line.strip() != '':
+        output.append(prefix + cur_line.rstrip())
+      cur_line = seg.lstrip()
+  if cur_line.strip() != '':
+    output.append(prefix + cur_line.strip())
+
+
+def WrapCode(line, line_concat, output):
+  indent = len(line) - len(line.lstrip())
+  prefix = indent*' '  # Prefix of the current line
+  max_len = 80 - indent - len(line_concat)  # Maximum length of the current line
+  new_prefix = prefix + 4*' '  # Prefix of a continuation line
+  new_max_len = max_len - 4  # Maximum length of a continuation line
+  # Prefers to wrap a line after a ',' or ';'.
+  segs = [seg for seg in re.split(r'([^,;]+[,;]?)', line.strip()) if seg != '']
+  cur_line = ''  # The current line without leading spaces.
+  for seg in segs:
+    # If the line is still too long, wrap at a space.
+    while cur_line == '' and len(seg.strip()) > max_len:
+      seg = seg.lstrip()
+      split_at = seg.rfind(' ', 0, max_len)
+      output.append(prefix + seg[:split_at].strip() + line_concat)
+      seg = seg[split_at + 1:]
+      prefix = new_prefix
+      max_len = new_max_len
+
+    if len((cur_line + seg).rstrip()) < max_len:
+      cur_line = (cur_line + seg).lstrip()
+    else:
+      output.append(prefix + cur_line.rstrip() + line_concat)
+      prefix = new_prefix
+      max_len = new_max_len
+      cur_line = seg.lstrip()
+  if cur_line.strip() != '':
+    output.append(prefix + cur_line.strip())
+
+
+def WrapPreprocessorDirevative(line, output):
+  WrapCode(line, ' \\', output)
+
+
+def WrapPlainCode(line, output):
+  WrapCode(line, '', output)
+
+
+def IsHeaderGuardOrInclude(line):
+  return (re.match(r'^#(ifndef|define|endif\s*//)\s*[\w_]+\s*$', line) or
+          re.match(r'^#include\s', line))
+
+
+def WrapLongLine(line, output):
+  line = line.rstrip()
+  if len(line) <= 80:
+    output.append(line)
+  elif IsComment(line):
+    if IsHeaderGuardOrInclude(line):
+      # The style guide made an exception to allow long header guard lines
+      # and includes.
+      output.append(line)
+    else:
+      WrapComment(line, output)
+  elif IsInPreprocessorDirevative(output, line):
+    if IsHeaderGuardOrInclude(line):
+      # The style guide made an exception to allow long header guard lines
+      # and includes.
+      output.append(line)
+    else:
+      WrapPreprocessorDirevative(line, output)
+  else:
+    WrapPlainCode(line, output)
+
+
+def BeautifyCode(string):
+  lines = string.splitlines()
+  output = []
+  for line in lines:
+    WrapLongLine(line, output)
+  output2 = [line.rstrip() for line in output]
+  return '\n'.join(output2) + '\n'
+
+
+def main(argv):
+  if len(argv) == 1:
+    print __doc__
+    sys.exit(1)
+
+  file_path = argv[-1]
+  ast = Convert(file_path)
+  output = Output()
+  RunCode(Env(), ast, output)
+  output_str = BeautifyCode(output.string)
+  if file_path.endswith('.pump'):
+    output_file_path = file_path[:-5]
+  else:
+    output_file_path = '-'
+  if output_file_path == '-':
+    print output_str,
+  else:
+    output_file = file(output_file_path, 'w')
+    output_file.write('// This file was GENERATED by command:\n')
+    output_file.write('//     %s %s\n' %
+                      (os.path.basename(__file__), os.path.basename(file_path)))
+    output_file.write('// DO NOT EDIT BY HAND!!!\n\n')
+    output_file.write(output_str)
+    output_file.close()
+
+
+if __name__ == '__main__':
+  main(sys.argv)

Propchange: incubator/mesos/trunk/src/third_party/gtest-1.5.0/scripts/pump.py
------------------------------------------------------------------------------
    svn:executable = *

Copied: incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-all.cc (from r1131791, incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-all.cc)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-all.cc?p2=incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-all.cc&p1=incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-all.cc&r1=1131791&r2=1131792&rev=1131792&view=diff
==============================================================================
--- incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-all.cc (original)
+++ incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-all.cc Sun Jun  5 05:32:17 2011
@@ -33,6 +33,12 @@
 //
 // Sometimes it's desirable to build Google Test by compiling a single file.
 // This file serves this purpose.
+
+// This line ensures that gtest.h can be compiled on its own, even
+// when it's fused.
+#include <gtest/gtest.h>
+
+// The following lines pull in the real gtest *.cc files.
 #include "src/gtest.cc"
 #include "src/gtest-death-test.cc"
 #include "src/gtest-filepath.cc"

Copied: incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-death-test.cc (from r1131791, incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-death-test.cc)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-death-test.cc?p2=incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-death-test.cc&p1=incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-death-test.cc&r1=1131791&r2=1131792&rev=1131792&view=diff
==============================================================================
--- incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-death-test.cc (original)
+++ incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-death-test.cc Sun Jun  5 05:32:17 2011
@@ -308,9 +308,9 @@ String DeathTest::last_death_test_messag
 // Provides cross platform implementation for some death functionality.
 class DeathTestImpl : public DeathTest {
  protected:
-  DeathTestImpl(const char* statement, const RE* regex)
-      : statement_(statement),
-        regex_(regex),
+  DeathTestImpl(const char* a_statement, const RE* a_regex)
+      : statement_(a_statement),
+        regex_(a_regex),
         spawned_(false),
         status_(-1),
         outcome_(IN_PROGRESS),
@@ -326,11 +326,11 @@ class DeathTestImpl : public DeathTest {
   const char* statement() const { return statement_; }
   const RE* regex() const { return regex_; }
   bool spawned() const { return spawned_; }
-  void set_spawned(bool spawned) { spawned_ = spawned; }
+  void set_spawned(bool is_spawned) { spawned_ = is_spawned; }
   int status() const { return status_; }
-  void set_status(int status) { status_ = status; }
+  void set_status(int a_status) { status_ = a_status; }
   DeathTestOutcome outcome() const { return outcome_; }
-  void set_outcome(DeathTestOutcome outcome) { outcome_ = outcome; }
+  void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; }
   int read_fd() const { return read_fd_; }
   void set_read_fd(int fd) { read_fd_ = fd; }
   int write_fd() const { return write_fd_; }
@@ -705,8 +705,8 @@ class ForkingDeathTest : public DeathTes
 };
 
 // Constructs a ForkingDeathTest.
-ForkingDeathTest::ForkingDeathTest(const char* statement, const RE* regex)
-    : DeathTestImpl(statement, regex),
+ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex)
+    : DeathTestImpl(a_statement, a_regex),
       child_pid_(-1) {}
 
 // Waits for the child in a death test to exit, returning its exit
@@ -718,18 +718,18 @@ int ForkingDeathTest::Wait() {
 
   ReadAndInterpretStatusByte();
 
-  int status;
-  GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status, 0));
-  set_status(status);
-  return status;
+  int status_value;
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0));
+  set_status(status_value);
+  return status_value;
 }
 
 // A concrete death test class that forks, then immediately runs the test
 // in the child process.
 class NoExecDeathTest : public ForkingDeathTest {
  public:
-  NoExecDeathTest(const char* statement, const RE* regex) :
-      ForkingDeathTest(statement, regex) { }
+  NoExecDeathTest(const char* a_statement, const RE* a_regex) :
+      ForkingDeathTest(a_statement, a_regex) { }
   virtual TestRole AssumeRole();
 };
 
@@ -782,9 +782,9 @@ DeathTest::TestRole NoExecDeathTest::Ass
 // only this specific death test to be run.
 class ExecDeathTest : public ForkingDeathTest {
  public:
-  ExecDeathTest(const char* statement, const RE* regex,
+  ExecDeathTest(const char* a_statement, const RE* a_regex,
                 const char* file, int line) :
-      ForkingDeathTest(statement, regex), file_(file), line_(line) { }
+      ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { }
   virtual TestRole AssumeRole();
  private:
   // The name of the file in which the death test is located.
@@ -1037,8 +1037,6 @@ bool DefaultDeathTestFactory::Create(con
 // Splits a given string on a given delimiter, populating a given
 // vector with the fields.  GTEST_HAS_DEATH_TEST implies that we have
 // ::std::string, so we can use it here.
-// TODO(vladl@google.com): Get rid of std::vector to be able to build on
-// Visual C++ 7.1 with exceptions disabled.
 static void SplitString(const ::std::string& str, char delimiter,
                         ::std::vector< ::std::string>* dest) {
   ::std::vector< ::std::string> parsed;

Copied: incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-filepath.cc (from r1131791, incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-filepath.cc)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-filepath.cc?p2=incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-filepath.cc&p1=incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-filepath.cc&r1=1131791&r2=1131792&rev=1131792&view=diff
==============================================================================
--- incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-filepath.cc (original)
+++ incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-filepath.cc Sun Jun  5 05:32:17 2011
@@ -63,8 +63,14 @@ namespace testing {
 namespace internal {
 
 #if GTEST_OS_WINDOWS
+// On Windows, '\\' is the standard path separator, but many tools and the
+// Windows API also accept '/' as an alternate path separator. Unless otherwise
+// noted, a file path can contain either kind of path separators, or a mixture
+// of them.
 const char kPathSeparator = '\\';
+const char kAlternatePathSeparator = '/';
 const char kPathSeparatorString[] = "\\";
+const char kAlternatePathSeparatorString[] = "/";
 #if GTEST_OS_WINDOWS_MOBILE
 // Windows CE doesn't have a current directory. You should not use
 // the current directory in tests on Windows CE, but this at least
@@ -81,6 +87,15 @@ const char kPathSeparatorString[] = "/";
 const char kCurrentDirectoryString[] = "./";
 #endif  // GTEST_OS_WINDOWS
 
+// Returns whether the given character is a valid path separator.
+static bool IsPathSeparator(char c) {
+#if GTEST_HAS_ALT_PATH_SEP_
+  return (c == kPathSeparator) || (c == kAlternatePathSeparator);
+#else
+  return c == kPathSeparator;
+#endif
+}
+
 // Returns the current working directory, or "" if unsuccessful.
 FilePath FilePath::GetCurrentDir() {
 #if GTEST_OS_WINDOWS_MOBILE
@@ -108,6 +123,22 @@ FilePath FilePath::RemoveExtension(const
   return *this;
 }
 
+// Returns a pointer to the last occurence of a valid path separator in
+// the FilePath. On Windows, for example, both '/' and '\' are valid path
+// separators. Returns NULL if no path separator was found.
+const char* FilePath::FindLastPathSeparator() const {
+  const char* const last_sep = strrchr(c_str(), kPathSeparator);
+#if GTEST_HAS_ALT_PATH_SEP_
+  const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
+  // Comparing two pointers of which only one is NULL is undefined.
+  if (last_alt_sep != NULL &&
+      (last_sep == NULL || last_alt_sep > last_sep)) {
+    return last_alt_sep;
+  }
+#endif
+  return last_sep;
+}
+
 // Returns a copy of the FilePath with the directory part removed.
 // Example: FilePath("path/to/file").RemoveDirectoryName() returns
 // FilePath("file"). If there is no directory part ("just_a_file"), it returns
@@ -115,7 +146,7 @@ FilePath FilePath::RemoveExtension(const
 // returns an empty FilePath ("").
 // On Windows platform, '\' is the path separator, otherwise it is '/'.
 FilePath FilePath::RemoveDirectoryName() const {
-  const char* const last_sep = strrchr(c_str(), kPathSeparator);
+  const char* const last_sep = FindLastPathSeparator();
   return last_sep ? FilePath(String(last_sep + 1)) : *this;
 }
 
@@ -126,7 +157,7 @@ FilePath FilePath::RemoveDirectoryName()
 // not have a file, like "just/a/dir/", it returns the FilePath unmodified.
 // On Windows platform, '\' is the path separator, otherwise it is '/'.
 FilePath FilePath::RemoveFileName() const {
-  const char* const last_sep = strrchr(c_str(), kPathSeparator);
+  const char* const last_sep = FindLastPathSeparator();
   String dir;
   if (last_sep) {
     dir = String(c_str(), last_sep + 1 - c_str());
@@ -219,7 +250,7 @@ bool FilePath::IsRootDirectory() const {
   // current directory.  Handle this properly.
   return pathname_.length() == 3 && IsAbsolutePath();
 #else
-  return pathname_ == kPathSeparatorString;
+  return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
 #endif
 }
 
@@ -231,9 +262,9 @@ bool FilePath::IsAbsolutePath() const {
      ((name[0] >= 'a' && name[0] <= 'z') ||
       (name[0] >= 'A' && name[0] <= 'Z')) &&
      name[1] == ':' &&
-     name[2] == kPathSeparator;
+     IsPathSeparator(name[2]);
 #else
-  return name[0] == kPathSeparator;
+  return IsPathSeparator(name[0]);
 #endif
 }
 
@@ -260,7 +291,8 @@ FilePath FilePath::GenerateUniqueFileNam
 // it is intended to represent a directory. Returns false otherwise.
 // This does NOT check that a directory (or file) actually exists.
 bool FilePath::IsDirectory() const {
-  return pathname_.EndsWith(kPathSeparatorString);
+  return !pathname_.empty() &&
+         IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);
 }
 
 // Create directories so that path exists. Returns true if successful or if
@@ -305,14 +337,15 @@ bool FilePath::CreateFolder() const {
 // name, otherwise return the name string unmodified.
 // On Windows platform, uses \ as the separator, other platforms use /.
 FilePath FilePath::RemoveTrailingPathSeparator() const {
-  return pathname_.EndsWith(kPathSeparatorString)
+  return IsDirectory()
       ? FilePath(String(pathname_.c_str(), pathname_.length() - 1))
       : *this;
 }
 
-// Normalize removes any redundant separators that might be in the pathname.
+// Removes any redundant separators that might be in the pathname.
 // For example, "bar///foo" becomes "bar/foo". Does not eliminate other
 // redundancies that might be in a pathname involving "." or "..".
+// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share).
 void FilePath::Normalize() {
   if (pathname_.c_str() == NULL) {
     pathname_ = "";
@@ -324,12 +357,19 @@ void FilePath::Normalize() {
   memset(dest_ptr, 0, pathname_.length() + 1);
 
   while (*src != '\0') {
-    *dest_ptr++ = *src;
-    if (*src != kPathSeparator)
+    *dest_ptr = *src;
+    if (!IsPathSeparator(*src)) {
       src++;
-    else
-      while (*src == kPathSeparator)
+    } else {
+#if GTEST_HAS_ALT_PATH_SEP_
+      if (*dest_ptr == kAlternatePathSeparator) {
+        *dest_ptr = kPathSeparator;
+      }
+#endif
+      while (IsPathSeparator(*src))
         src++;
+    }
+    dest_ptr++;
   }
   *dest_ptr = '\0';
   pathname_ = dest;

Copied: incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-internal-inl.h (from r1131791, incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-internal-inl.h)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-internal-inl.h?p2=incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-internal-inl.h&p1=incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-internal-inl.h&r1=1131791&r2=1131792&rev=1131792&view=diff
==============================================================================
--- incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-internal-inl.h (original)
+++ incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-internal-inl.h Sun Jun  5 05:32:17 2011
@@ -52,11 +52,9 @@
 #include <stdlib.h>  // For strtoll/_strtoul64/malloc/free.
 #include <string.h>  // For memmove.
 
+#include <algorithm>
 #include <string>
-
-#if GTEST_HAS_PTHREAD
-#include <pthread.h>
-#endif
+#include <vector>
 
 #include <gtest/internal/gtest-port.h>
 
@@ -64,7 +62,7 @@
 #include <windows.h>  // For DWORD.
 #endif  // GTEST_OS_WINDOWS
 
-#include <gtest/gtest.h>
+#include <gtest/gtest.h>  // NOLINT
 #include <gtest/gtest-spi.h>
 
 namespace testing {
@@ -80,7 +78,7 @@ namespace internal {
 
 // The value of GetTestTypeId() as seen from within the Google Test
 // library.  This is solely for testing GetTestTypeId().
-extern const TypeId kTestTypeIdInGoogleTest;
+GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest;
 
 // Names of the flags (needed for parsing Google Test flags).
 const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests";
@@ -94,13 +92,31 @@ const char kPrintTimeFlag[] = "print_tim
 const char kRandomSeedFlag[] = "random_seed";
 const char kRepeatFlag[] = "repeat";
 const char kShuffleFlag[] = "shuffle";
+const char kStackTraceDepthFlag[] = "stack_trace_depth";
 const char kThrowOnFailureFlag[] = "throw_on_failure";
 
 // A valid random seed must be in [1, kMaxRandomSeed].
 const int kMaxRandomSeed = 99999;
 
+// g_help_flag is true iff the --help flag or an equivalent form is
+// specified on the command line.
+GTEST_API_ extern bool g_help_flag;
+
 // Returns the current time in milliseconds.
-TimeInMillis GetTimeInMillis();
+GTEST_API_ TimeInMillis GetTimeInMillis();
+
+// Returns true iff Google Test should use colors in the output.
+GTEST_API_ bool ShouldUseColor(bool stdout_is_tty);
+
+// Formats the given time in milliseconds as seconds.
+GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms);
+
+// Parses a string for an Int32 flag, in the form of "--flag=value".
+//
+// On success, stores the value of the flag in *value, and returns
+// true.  On failure, returns false without changing *value.
+GTEST_API_ bool ParseInt32Flag(
+    const char* str, const char* flag, Int32* value);
 
 // Returns a random seed in range [1, kMaxRandomSeed] based on the
 // given --gtest_random_seed flag value.
@@ -148,6 +164,7 @@ class GTestFlagSaver {
     random_seed_ = GTEST_FLAG(random_seed);
     repeat_ = GTEST_FLAG(repeat);
     shuffle_ = GTEST_FLAG(shuffle);
+    stack_trace_depth_ = GTEST_FLAG(stack_trace_depth);
     throw_on_failure_ = GTEST_FLAG(throw_on_failure);
   }
 
@@ -167,6 +184,7 @@ class GTestFlagSaver {
     GTEST_FLAG(random_seed) = random_seed_;
     GTEST_FLAG(repeat) = repeat_;
     GTEST_FLAG(shuffle) = shuffle_;
+    GTEST_FLAG(stack_trace_depth) = stack_trace_depth_;
     GTEST_FLAG(throw_on_failure) = throw_on_failure_;
   }
  private:
@@ -186,6 +204,7 @@ class GTestFlagSaver {
   internal::Int32 random_seed_;
   internal::Int32 repeat_;
   bool shuffle_;
+  internal::Int32 stack_trace_depth_;
   bool throw_on_failure_;
 } GTEST_ATTRIBUTE_UNUSED_;
 
@@ -197,7 +216,7 @@ class GTestFlagSaver {
 // If the code_point is not a valid Unicode code point
 // (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output
 // as '(Invalid Unicode 0xXXXXXXXX)'.
-char* CodePointToUtf8(UInt32 code_point, char* str);
+GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str);
 
 // Converts a wide string to a narrow string in UTF-8 encoding.
 // The wide string is assumed to have the following encoding:
@@ -212,10 +231,7 @@ char* CodePointToUtf8(UInt32 code_point,
 // as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding
 // and contains invalid UTF-16 surrogate pairs, values in those pairs
 // will be encoded as individual Unicode characters from Basic Normal Plane.
-String WideStringToUtf8(const wchar_t* str, int num_chars);
-
-// Returns the number of active threads, or 0 when there is an error.
-size_t GetThreadCount();
+GTEST_API_ String WideStringToUtf8(const wchar_t* str, int num_chars);
 
 // Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file
 // if the variable is present. If a file already exists at this location, this
@@ -229,269 +245,78 @@ void WriteToShardStatusFileIfNeeded();
 // an error and exits. If in_subprocess_for_death_test, sharding is
 // disabled because it must only be applied to the original test
 // process. Otherwise, we could filter out death tests we intended to execute.
-bool ShouldShard(const char* total_shards_str, const char* shard_index_str,
-                 bool in_subprocess_for_death_test);
+GTEST_API_ bool ShouldShard(const char* total_shards_str,
+                            const char* shard_index_str,
+                            bool in_subprocess_for_death_test);
 
 // Parses the environment variable var as an Int32. If it is unset,
 // returns default_val. If it is not an Int32, prints an error and
 // and aborts.
-Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val);
+GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val);
 
 // Given the total number of shards, the shard index, and the test id,
 // returns true iff the test should be run on this shard. The test id is
 // some arbitrary but unique non-negative integer assigned to each test
 // method. Assumes that 0 <= shard_index < total_shards.
-bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id);
-
-// Vector is an ordered container that supports random access to the
-// elements.
-//
-// We cannot use std::vector, as Visual C++ 7.1's implementation of
-// STL has problems compiling when exceptions are disabled.  There is
-// a hack to work around the problems, but we've seen cases where the
-// hack fails to work.
-//
-// The element type must support copy constructor and operator=.
-template <typename E>  // E is the element type.
-class Vector {
- public:
-  // Creates an empty Vector.
-  Vector() : elements_(NULL), capacity_(0), size_(0) {}
-
-  // D'tor.
-  virtual ~Vector() { Clear(); }
-
-  // Clears the Vector.
-  void Clear() {
-    if (elements_ != NULL) {
-      for (int i = 0; i < size_; i++) {
-        delete elements_[i];
-      }
-
-      free(elements_);
-      elements_ = NULL;
-      capacity_ = size_ = 0;
-    }
-  }
-
-  // Gets the number of elements.
-  int size() const { return size_; }
-
-  // Adds an element to the end of the Vector.  A copy of the element
-  // is created using the copy constructor, and then stored in the
-  // Vector.  Changes made to the element in the Vector doesn't affect
-  // the source object, and vice versa.
-  void PushBack(const E& element) { Insert(element, size_); }
-
-  // Adds an element to the beginning of this Vector.
-  void PushFront(const E& element) { Insert(element, 0); }
-
-  // Removes an element from the beginning of this Vector.  If the
-  // result argument is not NULL, the removed element is stored in the
-  // memory it points to.  Otherwise the element is thrown away.
-  // Returns true iff the vector wasn't empty before the operation.
-  bool PopFront(E* result) {
-    if (size_ == 0)
-      return false;
-
-    if (result != NULL)
-      *result = GetElement(0);
-
-    Erase(0);
-    return true;
-  }
-
-  // Inserts an element at the given index.  It's the caller's
-  // responsibility to ensure that the given index is in the range [0,
-  // size()].
-  void Insert(const E& element, int index) {
-    GrowIfNeeded();
-    MoveElements(index, size_ - index, index + 1);
-    elements_[index] = new E(element);
-    size_++;
-  }
-
-  // Erases the element at the specified index, or aborts the program if the
-  // index is not in range [0, size()).
-  void Erase(int index) {
-    GTEST_CHECK_(0 <= index && index < size_)
-        << "Invalid Vector index " << index << ": must be in range [0, "
-        << (size_ - 1) << "].";
-
-    delete elements_[index];
-    MoveElements(index + 1, size_ - index - 1, index);
-    size_--;
-  }
-
-  // Returns the number of elements that satisfy a given predicate.
-  // The parameter 'predicate' is a Boolean function or functor that
-  // accepts a 'const E &', where E is the element type.
-  template <typename P>  // P is the type of the predicate function/functor
-  int CountIf(P predicate) const {
-    int count = 0;
-    for (int i = 0; i < size_; i++) {
-      if (predicate(*(elements_[i]))) {
-        count++;
-      }
-    }
-
-    return count;
-  }
-
-  // Applies a function/functor to each element in the Vector.  The
-  // parameter 'functor' is a function/functor that accepts a 'const
-  // E &', where E is the element type.  This method does not change
-  // the elements.
-  template <typename F>  // F is the type of the function/functor
-  void ForEach(F functor) const {
-    for (int i = 0; i < size_; i++) {
-      functor(*(elements_[i]));
-    }
-  }
+GTEST_API_ bool ShouldRunTestOnShard(
+    int total_shards, int shard_index, int test_id);
 
-  // Returns the first node whose element satisfies a given predicate,
-  // or NULL if none is found.  The parameter 'predicate' is a
-  // function/functor that accepts a 'const E &', where E is the
-  // element type.  This method does not change the elements.
-  template <typename P>  // P is the type of the predicate function/functor.
-  const E* FindIf(P predicate) const {
-    for (int i = 0; i < size_; i++) {
-      if (predicate(*elements_[i])) {
-        return elements_[i];
-      }
-    }
-    return NULL;
-  }
+// STL container utilities.
 
-  template <typename P>
-  E* FindIf(P predicate) {
-    for (int i = 0; i < size_; i++) {
-      if (predicate(*elements_[i])) {
-        return elements_[i];
-      }
-    }
-    return NULL;
-  }
+// Returns the number of elements in the given container that satisfy
+// the given predicate.
+template <class Container, typename Predicate>
+inline int CountIf(const Container& c, Predicate predicate) {
+  return static_cast<int>(std::count_if(c.begin(), c.end(), predicate));
+}
 
-  // Returns the i-th element of the Vector, or aborts the program if i
-  // is not in range [0, size()).
-  const E& GetElement(int i) const {
-    GTEST_CHECK_(0 <= i && i < size_)
-        << "Invalid Vector index " << i << ": must be in range [0, "
-        << (size_ - 1) << "].";
-
-    return *(elements_[i]);
-  }
-
-  // Returns a mutable reference to the i-th element of the Vector, or
-  // aborts the program if i is not in range [0, size()).
-  E& GetMutableElement(int i) {
-    GTEST_CHECK_(0 <= i && i < size_)
-        << "Invalid Vector index " << i << ": must be in range [0, "
-        << (size_ - 1) << "].";
-
-    return *(elements_[i]);
-  }
-
-  // Returns the i-th element of the Vector, or default_value if i is not
-  // in range [0, size()).
-  E GetElementOr(int i, E default_value) const {
-    return (i < 0 || i >= size_) ? default_value : *(elements_[i]);
-  }
-
-  // Swaps the i-th and j-th elements of the Vector.  Crashes if i or
-  // j is invalid.
-  void Swap(int i, int j) {
-    GTEST_CHECK_(0 <= i && i < size_)
-        << "Invalid first swap element " << i << ": must be in range [0, "
-        << (size_ - 1) << "].";
-    GTEST_CHECK_(0 <= j && j < size_)
-        << "Invalid second swap element " << j << ": must be in range [0, "
-        << (size_ - 1) << "].";
-
-    E* const temp = elements_[i];
-    elements_[i] = elements_[j];
-    elements_[j] = temp;
-  }
-
-  // Performs an in-place shuffle of a range of this Vector's nodes.
-  // 'begin' and 'end' are element indices as an STL-style range;
-  // i.e. [begin, end) are shuffled, where 'end' == size() means to
-  // shuffle to the end of the Vector.
-  void ShuffleRange(internal::Random* random, int begin, int end) {
-    GTEST_CHECK_(0 <= begin && begin <= size_)
-        << "Invalid shuffle range start " << begin << ": must be in range [0, "
-        << size_ << "].";
-    GTEST_CHECK_(begin <= end && end <= size_)
-        << "Invalid shuffle range finish " << end << ": must be in range ["
-        << begin << ", " << size_ << "].";
-
-    // Fisher-Yates shuffle, from
-    // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
-    for (int range_width = end - begin; range_width >= 2; range_width--) {
-      const int last_in_range = begin + range_width - 1;
-      const int selected = begin + random->Generate(range_width);
-      Swap(selected, last_in_range);
-    }
-  }
+// Applies a function/functor to each element in the container.
+template <class Container, typename Functor>
+void ForEach(const Container& c, Functor functor) {
+  std::for_each(c.begin(), c.end(), functor);
+}
 
-  // Performs an in-place shuffle of this Vector's nodes.
-  void Shuffle(internal::Random* random) {
-    ShuffleRange(random, 0, size());
-  }
+// Returns the i-th element of the vector, or default_value if i is not
+// in range [0, v.size()).
+template <typename E>
+inline E GetElementOr(const std::vector<E>& v, int i, E default_value) {
+  return (i < 0 || i >= static_cast<int>(v.size())) ? default_value : v[i];
+}
 
-  // Returns a copy of this Vector.
-  Vector* Clone() const {
-    Vector* const clone = new Vector;
-    clone->Reserve(size_);
-    for (int i = 0; i < size_; i++) {
-      clone->PushBack(GetElement(i));
-    }
-    return clone;
+// Performs an in-place shuffle of a range of the vector's elements.
+// 'begin' and 'end' are element indices as an STL-style range;
+// i.e. [begin, end) are shuffled, where 'end' == size() means to
+// shuffle to the end of the vector.
+template <typename E>
+void ShuffleRange(internal::Random* random, int begin, int end,
+                  std::vector<E>* v) {
+  const int size = static_cast<int>(v->size());
+  GTEST_CHECK_(0 <= begin && begin <= size)
+      << "Invalid shuffle range start " << begin << ": must be in range [0, "
+      << size << "].";
+  GTEST_CHECK_(begin <= end && end <= size)
+      << "Invalid shuffle range finish " << end << ": must be in range ["
+      << begin << ", " << size << "].";
+
+  // Fisher-Yates shuffle, from
+  // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
+  for (int range_width = end - begin; range_width >= 2; range_width--) {
+    const int last_in_range = begin + range_width - 1;
+    const int selected = begin + random->Generate(range_width);
+    std::swap((*v)[selected], (*v)[last_in_range]);
   }
+}
 
- private:
-  // Makes sure this Vector's capacity is at least the given value.
-  void Reserve(int new_capacity) {
-    if (new_capacity <= capacity_)
-      return;
-
-    capacity_ = new_capacity;
-    elements_ = static_cast<E**>(
-        realloc(elements_, capacity_*sizeof(elements_[0])));
-  }
-
-  // Grows the buffer if it is not big enough to hold one more element.
-  void GrowIfNeeded() {
-    if (size_ < capacity_)
-      return;
-
-    // Exponential bump-up is necessary to ensure that inserting N
-    // elements is O(N) instead of O(N^2).  The factor 3/2 means that
-    // no more than 1/3 of the slots are wasted.
-    const int new_capacity = 3*(capacity_/2 + 1);
-    GTEST_CHECK_(new_capacity > capacity_)  // Does the new capacity overflow?
-        << "Cannot grow a Vector with " << capacity_ << " elements already.";
-    Reserve(new_capacity);
-  }
-
-  // Moves the give consecutive elements to a new index in the Vector.
-  void MoveElements(int source, int count, int dest) {
-    memmove(elements_ + dest, elements_ + source, count*sizeof(elements_[0]));
-  }
-
-  E** elements_;
-  int capacity_;  // The number of elements allocated for elements_.
-  int size_;      // The number of elements; in the range [0, capacity_].
-
-  // We disallow copying Vector.
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(Vector);
-};  // class Vector
+// Performs an in-place shuffle of the vector's elements.
+template <typename E>
+inline void Shuffle(internal::Random* random, std::vector<E>* v) {
+  ShuffleRange(random, 0, static_cast<int>(v->size()), v);
+}
 
 // A function for deleting an object.  Handy for being used as a
 // functor.
 template <typename T>
-static void Delete(T * x) {
+static void Delete(T* x) {
   delete x;
 }
 
@@ -604,7 +429,7 @@ class TestInfoImpl {
 // test filter using either GTEST_FILTER or --gtest_filter.  If both
 // the variable and the flag are present, the latter overrides the
 // former.
-class UnitTestOptions {
+class GTEST_API_ UnitTestOptions {
  public:
   // Functions for processing the gtest_output flag.
 
@@ -646,7 +471,7 @@ class UnitTestOptions {
 
 // Returns the current application's name, removing directory path if that
 // is present.  Used by UnitTestOptions::GetOutputFile.
-FilePath GetCurrentExecutableName();
+GTEST_API_ FilePath GetCurrentExecutableName();
 
 // The role interface for getting the OS stack trace as a string.
 class OsStackTraceGetterInterface {
@@ -737,7 +562,7 @@ class DefaultPerThreadTestPartResultRepo
 // the methods under a mutex, as this class is not accessible by a
 // user and the UnitTest class that delegates work to this class does
 // proper locking.
-class UnitTestImpl {
+class GTEST_API_ UnitTestImpl {
  public:
   explicit UnitTestImpl(UnitTest* parent);
   virtual ~UnitTestImpl();
@@ -806,15 +631,15 @@ class UnitTestImpl {
   // Gets the i-th test case among all the test cases. i can range from 0 to
   // total_test_case_count() - 1. If i is not in that range, returns NULL.
   const TestCase* GetTestCase(int i) const {
-    const int index = test_case_indices_.GetElementOr(i, -1);
-    return index < 0 ? NULL : test_cases_.GetElement(i);
+    const int index = GetElementOr(test_case_indices_, i, -1);
+    return index < 0 ? NULL : test_cases_[i];
   }
 
   // Gets the i-th test case among all the test cases. i can range from 0 to
   // total_test_case_count() - 1. If i is not in that range, returns NULL.
   TestCase* GetMutableTestCase(int i) {
-    const int index = test_case_indices_.GetElementOr(i, -1);
-    return index < 0 ? NULL : test_cases_.GetElement(index);
+    const int index = GetElementOr(test_case_indices_, i, -1);
+    return index < 0 ? NULL : test_cases_[index];
   }
 
   // Provides access to the event listener list.
@@ -902,15 +727,15 @@ class UnitTestImpl {
 #endif  // GTEST_HAS_PARAM_TEST
 
   // Sets the TestCase object for the test that's currently running.
-  void set_current_test_case(TestCase* current_test_case) {
-    current_test_case_ = current_test_case;
+  void set_current_test_case(TestCase* a_current_test_case) {
+    current_test_case_ = a_current_test_case;
   }
 
   // Sets the TestInfo object for the test that's currently running.  If
   // current_test_info is NULL, the assertion results will be stored in
   // ad_hoc_test_result_.
-  void set_current_test_info(TestInfo* current_test_info) {
-    current_test_info_ = current_test_info;
+  void set_current_test_info(TestInfo* a_current_test_info) {
+    current_test_info_ = a_current_test_info;
   }
 
   // Registers all parameterized tests defined using TEST_P and
@@ -931,7 +756,7 @@ class UnitTestImpl {
 
   // Clears the results of all tests, including the ad hoc test.
   void ClearResult() {
-    test_cases_.ForEach(TestCase::ClearTestCaseResult);
+    ForEach(test_cases_, TestCase::ClearTestCaseResult);
     ad_hoc_test_result_.Clear();
   }
 
@@ -957,17 +782,14 @@ class UnitTestImpl {
 
   // Returns the vector of environments that need to be set-up/torn-down
   // before/after the tests are run.
-  internal::Vector<Environment*>* environments() { return &environments_; }
-  internal::Vector<Environment*>* environments_in_reverse_order() {
-    return &environments_in_reverse_order_;
-  }
+  std::vector<Environment*>& environments() { return environments_; }
 
   // Getters for the per-thread Google Test trace stack.
-  internal::Vector<TraceInfo>* gtest_trace_stack() {
-    return gtest_trace_stack_.pointer();
+  std::vector<TraceInfo>& gtest_trace_stack() {
+    return *(gtest_trace_stack_.pointer());
   }
-  const internal::Vector<TraceInfo>* gtest_trace_stack() const {
-    return gtest_trace_stack_.pointer();
+  const std::vector<TraceInfo>& gtest_trace_stack() const {
+    return gtest_trace_stack_.get();
   }
 
 #if GTEST_HAS_DEATH_TEST
@@ -1042,20 +864,18 @@ class UnitTestImpl {
       per_thread_test_part_result_reporter_;
 
   // The vector of environments that need to be set-up/torn-down
-  // before/after the tests are run.  environments_in_reverse_order_
-  // simply mirrors environments_ in reverse order.
-  internal::Vector<Environment*> environments_;
-  internal::Vector<Environment*> environments_in_reverse_order_;
+  // before/after the tests are run.
+  std::vector<Environment*> environments_;
 
   // The vector of TestCases in their original order.  It owns the
   // elements in the vector.
-  internal::Vector<TestCase*> test_cases_;
+  std::vector<TestCase*> test_cases_;
 
   // Provides a level of indirection for the test case list to allow
   // easy shuffling and restoring the test case order.  The i-th
   // element of this vector is the index of the i-th test case in the
   // shuffled order.
-  internal::Vector<int> test_case_indices_;
+  std::vector<int> test_case_indices_;
 
 #if GTEST_HAS_PARAM_TEST
   // ParameterizedTestRegistry object used to register value-parameterized
@@ -1121,7 +941,7 @@ class UnitTestImpl {
 #endif  // GTEST_HAS_DEATH_TEST
 
   // A per-thread stack of traces created by the SCOPED_TRACE() macro.
-  internal::ThreadLocal<internal::Vector<TraceInfo> > gtest_trace_stack_;
+  internal::ThreadLocal<std::vector<TraceInfo> > gtest_trace_stack_;
 
   GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl);
 };  // class UnitTestImpl
@@ -1134,24 +954,24 @@ inline UnitTestImpl* GetUnitTestImpl() {
 
 // Internal helper functions for implementing the simple regular
 // expression matcher.
-bool IsInSet(char ch, const char* str);
-bool IsDigit(char ch);
-bool IsPunct(char ch);
-bool IsRepeat(char ch);
-bool IsWhiteSpace(char ch);
-bool IsWordChar(char ch);
-bool IsValidEscape(char ch);
-bool AtomMatchesChar(bool escaped, char pattern, char ch);
-bool ValidateRegex(const char* regex);
-bool MatchRegexAtHead(const char* regex, const char* str);
-bool MatchRepetitionAndRegexAtHead(
+GTEST_API_ bool IsInSet(char ch, const char* str);
+GTEST_API_ bool IsDigit(char ch);
+GTEST_API_ bool IsPunct(char ch);
+GTEST_API_ bool IsRepeat(char ch);
+GTEST_API_ bool IsWhiteSpace(char ch);
+GTEST_API_ bool IsWordChar(char ch);
+GTEST_API_ bool IsValidEscape(char ch);
+GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch);
+GTEST_API_ bool ValidateRegex(const char* regex);
+GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str);
+GTEST_API_ bool MatchRepetitionAndRegexAtHead(
     bool escaped, char ch, char repeat, const char* regex, const char* str);
-bool MatchRegexAnywhere(const char* regex, const char* str);
+GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str);
 
 // Parses the command line for Google Test flags, without initializing
 // other parts of Google Test.
-void ParseGoogleTestFlagsOnly(int* argc, char** argv);
-void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv);
+GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv);
+GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv);
 
 #if GTEST_HAS_DEATH_TEST
 
@@ -1228,6 +1048,9 @@ bool ParseNaturalNumber(const ::std::str
 // TestResult contains some private methods that should be hidden from
 // Google Test user but are required for testing. This class allow our tests
 // to access them.
+//
+// This class is supplied only for the purpose of testing Google Test's own
+// constructs. Do not use it in user tests, either directly or indirectly.
 class TestResultAccessor {
  public:
   static void RecordProperty(TestResult* test_result,
@@ -1239,59 +1062,12 @@ class TestResultAccessor {
     test_result->ClearTestPartResults();
   }
 
-  static const Vector<testing::TestPartResult>& test_part_results(
+  static const std::vector<testing::TestPartResult>& test_part_results(
       const TestResult& test_result) {
     return test_result.test_part_results();
   }
 };
 
-#if GTEST_IS_THREADSAFE
-#if GTEST_HAS_PTHREAD
-template <typename T>
-class ThreadWithParam {
- public:
-  typedef void (*UserFunc)(T);
-  ThreadWithParam(UserFunc func, T param) : func_(func), param_(param),
-    thread_(), runMutex_(), startLock_(new MutexLock(&runMutex_)) {
-    int err = pthread_create(&thread_, 0, ThreadMain, this);
-    GTEST_CHECK_(err == 0) << "pthread_create failed with error:"
-      << strerror(err) << "(" << err << ")";
-    running_ = true;
-  }
-  void Start() {
-    startLock_.reset(0);
-  }
-  void Join() {
-    if (running_) {
-      Start();
-      int err = pthread_join(thread_, 0);
-      GTEST_CHECK_(err == 0) << "pthread_join failed with error:"
-        << strerror(err) << "(" << err << ")";
-      running_ = false;
-    }
-  }
-  ~ThreadWithParam() { Join(); }
- private:
-  void ThreadMain() {
-    MutexLock lock(&runMutex_);
-    func_(param_);
-  }
-  static void* ThreadMain(void* param) {
-    reinterpret_cast<ThreadWithParam<T>*> (param)->ThreadMain();
-    return 0;
-  }
-
-  UserFunc func_;
-  T param_;
-
-  pthread_t thread_;
-  Mutex runMutex_;
-  scoped_ptr<MutexLock> startLock_;
-  bool running_;
-};
-#endif
-#endif
-
 }  // namespace internal
 }  // namespace testing
 

Copied: incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-port.cc (from r1131791, incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-port.cc)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-port.cc?p2=incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-port.cc&p1=incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-port.cc&r1=1131791&r2=1131792&rev=1131792&view=diff
==============================================================================
--- incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-port.cc (original)
+++ incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-port.cc Sun Jun  5 05:32:17 2011
@@ -50,10 +50,6 @@
 #include <mach/vm_map.h>
 #endif  // GTEST_OS_MAC
 
-#if GTEST_HAS_PTHREAD
-#include <pthread.h>
-#endif
-
 #include <gtest/gtest-spi.h>
 #include <gtest/gtest-message.h>
 #include <gtest/internal/gtest-string.h>
@@ -72,125 +68,13 @@ namespace internal {
 
 #if defined(_MSC_VER) || defined(__BORLANDC__)
 // MSVC and C++Builder do not provide a definition of STDERR_FILENO.
+const int kStdOutFileno = 1;
 const int kStdErrFileno = 2;
 #else
+const int kStdOutFileno = STDOUT_FILENO;
 const int kStdErrFileno = STDERR_FILENO;
 #endif  // _MSC_VER
 
-#if GTEST_HAS_PTHREAD
-class MutexImpl {
- public:
-  MutexImpl() : owner_(0) {
-    int err = pthread_mutex_init(&mutex_, 0);
-    GTEST_CHECK_(err == 0) << "pthread_mutex_unlock failed with:" << err;
-  }
-  ~MutexImpl() {
-    int err = pthread_mutex_destroy(&mutex_);
-    GTEST_CHECK_(err == 0) << "pthread_mutex_destroy failed with:" << err;
-  }
-  void AssertHeld() const {
-    GTEST_CHECK_(owner_ == pthread_self())
-      << "Current thread is not holding mutex." << this;
-  }
-  void Lock() {
-    int err = pthread_mutex_lock(&mutex_);
-    GTEST_CHECK_(err == 0) << "pthread_mutex_lock failed with:" << err;
-    owner_ = pthread_self();
-  }
-  void Unlock() {
-    owner_ = 0;
-    int err = pthread_mutex_unlock(&mutex_);
-    GTEST_CHECK_(err == 0) << "pthread_mutex_unlock failed with:" << err;
-  }
- private:
-  pthread_mutex_t mutex_;
-  pthread_t       owner_;
-};
-
-class GlobalMutexImpl {
- public:
-  class Guard {
-   public:
-    Guard() { Get().Lock(); }
-    ~Guard() { Get().Unlock(); }
-  };
- private:
-  static MutexImpl& Get() {
-    int err = pthread_once(&once_control_, &InitGlobalMutex);
-    GTEST_CHECK_(err == 0) << "pthread_once failed with:" << err;
-    return *global_mutex_;
-  }
-  static void InitGlobalMutex() {
-    global_mutex_ = new MutexImpl();
-  }
-  static pthread_once_t once_control_;
-  static MutexImpl* global_mutex_;
-};
-
-pthread_once_t GlobalMutexImpl::once_control_ = PTHREAD_ONCE_INIT;
-MutexImpl* GlobalMutexImpl::global_mutex_;
-
-Mutex::Mutex() : type_(NormalMutex), impl_(new MutexImpl()) {}
-
-Mutex::Mutex(NoConstructorNeededSelector /*dummy*/) { impl(); }
-
-// we leak static mutexes, because they might be used after their
-// destructor.
-Mutex::~Mutex() {
-  if (type_ != StaticMutex)
-    delete impl_;
-}
-
-void Mutex::AssertHeld() { impl().AssertHeld(); }
-
-void Mutex::Lock() { impl().Lock(); }
-
-void Mutex::Unlock() { impl().Unlock(); }
-
-MutexImpl& Mutex::impl() {
-  if (type_ == StaticMutex) {
-    GlobalMutexImpl::Guard globalLock;
-    if (!impl_) {
-      impl_ = new MutexImpl();
-    }
-  }
-  return *impl_;
-}
-
-class ThreadLocalPointerImpl {
- public:
-  ThreadLocalPointerImpl(void (*deleteFunction)(void*)) {
-    int err = pthread_key_create(&key_, deleteFunction);
-    GTEST_CHECK_(err == 0) << "pthread_key_create failed with:" << err;
-  }
-  ~ThreadLocalPointerImpl() {
-    int err = pthread_key_delete(key_);
-    GTEST_CHECK_(err == 0) << "pthread_key_delete failed with:" << err;
-  }
-  void* get() {
-    return pthread_getspecific(key_);
-  }
-  void set(void* value) {
-    int err = pthread_setspecific(key_, value);
-    GTEST_CHECK_(err == 0) << "pthread_setspecific failed with:" << err;
-  }
- private:
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocalPointerImpl);
-
-  pthread_key_t key_;
-};
-
-ThreadLocalPointer::ThreadLocalPointer(void (*deleteFunction)(void*))
-  : impl_(new ThreadLocalPointerImpl(deleteFunction)) {}
-
-ThreadLocalPointer::~ThreadLocalPointer() {
-  delete impl_;
-}
-
-void* ThreadLocalPointer::get() { return impl_->get(); }
-void ThreadLocalPointer::set(void* value) { impl_->set(value); }
-#endif  // GTEST_HAS_PTHREAD
-
 #if GTEST_OS_MAC
 
 // Returns the number of threads running in the process, or 0 to indicate that
@@ -227,8 +111,14 @@ size_t GetThreadCount() {
 // Implements RE.  Currently only needed for death tests.
 
 RE::~RE() {
-  regfree(&partial_regex_);
-  regfree(&full_regex_);
+  if (is_valid_) {
+    // regfree'ing an invalid regex might crash because the content
+    // of the regex is undefined. Since the regex's are essentially
+    // the same, one cannot be valid (or invalid) without the other
+    // being so too.
+    regfree(&partial_regex_);
+    regfree(&full_regex_);
+  }
   free(const_cast<char*>(pattern_));
 }
 
@@ -268,9 +158,10 @@ void RE::Init(const char* regex) {
   // Some implementation of POSIX regex (e.g. on at least some
   // versions of Cygwin) doesn't accept the empty string as a valid
   // regex.  We change it to an equivalent form "()" to be safe.
-  const char* const partial_regex = (*regex == '\0') ? "()" : regex;
-  is_valid_ = (regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0)
-      && is_valid_;
+  if (is_valid_) {
+    const char* const partial_regex = (*regex == '\0') ? "()" : regex;
+    is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
+  }
   EXPECT_TRUE(is_valid_)
       << "Regular expression \"" << regex
       << "\" is not a valid POSIX Extended regular expression.";
@@ -557,81 +448,83 @@ GTestLog::~GTestLog() {
 #pragma warning(disable: 4996)
 #endif  // _MSC_VER
 
-// Defines the stderr capturer.
+#if GTEST_HAS_STREAM_REDIRECTION_
 
-class CapturedStderr {
+// Object that captures an output stream (stdout/stderr).
+class CapturedStream {
  public:
-  // The ctor redirects stderr to a temporary file.
-  CapturedStderr() {
-#if GTEST_OS_WINDOWS_MOBILE
-    // Not supported on Windows CE.
-    posix::Abort();
-#else
-    uncaptured_fd_ = dup(kStdErrFileno);
-
+  // The ctor redirects the stream to a temporary file.
+  CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
 #if GTEST_OS_WINDOWS
     char temp_dir_path[MAX_PATH + 1] = { '\0' };  // NOLINT
     char temp_file_path[MAX_PATH + 1] = { '\0' };  // NOLINT
 
     ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);
-    ::GetTempFileNameA(temp_dir_path, "gtest_redir", 0, temp_file_path);
+    const UINT success = ::GetTempFileNameA(temp_dir_path,
+                                            "gtest_redir",
+                                            0,  // Generate unique file name.
+                                            temp_file_path);
+    GTEST_CHECK_(success != 0)
+        << "Unable to create a temporary file in " << temp_dir_path;
     const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
+    GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file "
+                                    << temp_file_path;
     filename_ = temp_file_path;
 #else
     // There's no guarantee that a test has write access to the
     // current directory, so we create the temporary file in the /tmp
     // directory instead.
-    char name_template[] = "/tmp/captured_stderr.XXXXXX";
+    char name_template[] = "/tmp/captured_stream.XXXXXX";
     const int captured_fd = mkstemp(name_template);
     filename_ = name_template;
 #endif  // GTEST_OS_WINDOWS
     fflush(NULL);
-    dup2(captured_fd, kStdErrFileno);
+    dup2(captured_fd, fd_);
     close(captured_fd);
-#endif  // GTEST_OS_WINDOWS_MOBILE
   }
 
-  ~CapturedStderr() {
-#if !GTEST_OS_WINDOWS_MOBILE
+  ~CapturedStream() {
     remove(filename_.c_str());
-#endif  // !GTEST_OS_WINDOWS_MOBILE
   }
 
-  // Stops redirecting stderr.
-  void StopCapture() {
-#if !GTEST_OS_WINDOWS_MOBILE
-    // Restores the original stream.
-    fflush(NULL);
-    dup2(uncaptured_fd_, kStdErrFileno);
-    close(uncaptured_fd_);
-    uncaptured_fd_ = -1;
-#endif  // !GTEST_OS_WINDOWS_MOBILE
-  }
+  String GetCapturedString() {
+    if (uncaptured_fd_ != -1) {
+      // Restores the original stream.
+      fflush(NULL);
+      dup2(uncaptured_fd_, fd_);
+      close(uncaptured_fd_);
+      uncaptured_fd_ = -1;
+    }
 
-  // Returns the name of the temporary file holding the stderr output.
-  // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
-  // can use it here.
-  ::std::string filename() const { return filename_; }
+    FILE* const file = posix::FOpen(filename_.c_str(), "r");
+    const String content = ReadEntireFile(file);
+    posix::FClose(file);
+    return content;
+  }
 
  private:
+  // Reads the entire content of a file as a String.
+  static String ReadEntireFile(FILE* file);
+
+  // Returns the size (in bytes) of a file.
+  static size_t GetFileSize(FILE* file);
+
+  const int fd_;  // A stream to capture.
   int uncaptured_fd_;
+  // Name of the temporary file holding the stderr output.
   ::std::string filename_;
-};
 
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif  // _MSC_VER
-
-static CapturedStderr* g_captured_stderr = NULL;
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
+};
 
 // Returns the size (in bytes) of a file.
-static size_t GetFileSize(FILE * file) {
+size_t CapturedStream::GetFileSize(FILE* file) {
   fseek(file, 0, SEEK_END);
   return static_cast<size_t>(ftell(file));
 }
 
 // Reads the entire content of a file as a string.
-static String ReadEntireFile(FILE * file) {
+String CapturedStream::ReadEntireFile(FILE* file) {
   const size_t file_size = GetFileSize(file);
   char* const buffer = new char[file_size];
 
@@ -653,30 +546,50 @@ static String ReadEntireFile(FILE * file
   return content;
 }
 
-// Starts capturing stderr.
-void CaptureStderr() {
-  if (g_captured_stderr != NULL) {
-    GTEST_LOG_(FATAL) << "Only one stderr capturer can exist at one time.";
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif  // _MSC_VER
+
+static CapturedStream* g_captured_stderr = NULL;
+static CapturedStream* g_captured_stdout = NULL;
+
+// Starts capturing an output stream (stdout/stderr).
+void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {
+  if (*stream != NULL) {
+    GTEST_LOG_(FATAL) << "Only one " << stream_name
+                      << " capturer can exist at a time.";
   }
-  g_captured_stderr = new CapturedStderr;
+  *stream = new CapturedStream(fd);
 }
 
-// Stops capturing stderr and returns the captured string.
-// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can
-// use it here.
-String GetCapturedStderr() {
-  g_captured_stderr->StopCapture();
-
-  FILE* const file = posix::FOpen(g_captured_stderr->filename().c_str(), "r");
-  const String content = ReadEntireFile(file);
-  posix::FClose(file);
+// Stops capturing the output stream and returns the captured string.
+String GetCapturedStream(CapturedStream** captured_stream) {
+  const String content = (*captured_stream)->GetCapturedString();
 
-  delete g_captured_stderr;
-  g_captured_stderr = NULL;
+  delete *captured_stream;
+  *captured_stream = NULL;
 
   return content;
 }
 
+// Starts capturing stdout.
+void CaptureStdout() {
+  CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout);
+}
+
+// Starts capturing stderr.
+void CaptureStderr() {
+  CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr);
+}
+
+// Stops capturing stdout and returns the captured string.
+String GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); }
+
+// Stops capturing stderr and returns the captured string.
+String GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); }
+
+#endif  // GTEST_HAS_STREAM_REDIRECTION_
+
 #if GTEST_HAS_DEATH_TEST
 
 // A copy of all command line arguments.  Set by InitGoogleTest().

Copied: incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-test-part.cc (from r1131791, incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-test-part.cc)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-test-part.cc?p2=incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-test-part.cc&p1=incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-test-part.cc&r1=1131791&r2=1131792&rev=1131792&view=diff
==============================================================================
--- incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-test-part.cc (original)
+++ incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-test-part.cc Sun Jun  5 05:32:17 2011
@@ -64,19 +64,9 @@ std::ostream& operator<<(std::ostream& o
       << result.message() << std::endl;
 }
 
-// Constructs an empty TestPartResultArray.
-TestPartResultArray::TestPartResultArray()
-    : array_(new internal::Vector<TestPartResult>) {
-}
-
-// Destructs a TestPartResultArray.
-TestPartResultArray::~TestPartResultArray() {
-  delete array_;
-}
-
 // Appends a TestPartResult to the array.
 void TestPartResultArray::Append(const TestPartResult& result) {
-  array_->PushBack(result);
+  array_.push_back(result);
 }
 
 // Returns the TestPartResult at the given index (0-based).
@@ -86,12 +76,12 @@ const TestPartResult& TestPartResultArra
     internal::posix::Abort();
   }
 
-  return array_->GetElement(index);
+  return array_[index];
 }
 
 // Returns the number of TestPartResult objects in the array.
 int TestPartResultArray::size() const {
-  return array_->size();
+  return static_cast<int>(array_.size());
 }
 
 namespace internal {

Copied: incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-typed-test.cc (from r1131791, incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-typed-test.cc)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-typed-test.cc?p2=incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-typed-test.cc&p1=incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-typed-test.cc&r1=1131791&r2=1131792&rev=1131792&view=diff
==============================================================================
--- incubator/mesos/trunk/src/third_party/gtest-1.4.0-patched/src/gtest-typed-test.cc (original)
+++ incubator/mesos/trunk/src/third_party/gtest-1.5.0/src/gtest-typed-test.cc Sun Jun  5 05:32:17 2011
@@ -37,6 +37,14 @@ namespace internal {
 
 #if GTEST_HAS_TYPED_TEST_P
 
+// Skips to the first non-space char in str. Returns an empty string if str
+// contains only whitespace characters.
+static const char* SkipSpaces(const char* str) {
+  while (isspace(*str))
+    str++;
+  return str;
+}
+
 // Verifies that registered_tests match the test names in
 // defined_test_names_; returns registered_tests if successful, or
 // aborts the program otherwise.
@@ -45,6 +53,10 @@ const char* TypedTestCasePState::VerifyR
   typedef ::std::set<const char*>::const_iterator DefinedTestIter;
   registered_ = true;
 
+  // Skip initial whitespace in registered_tests since some
+  // preprocessors prefix stringizied literals with whitespace.
+  registered_tests = SkipSpaces(registered_tests);
+
   Message errors;
   ::std::set<String> tests;
   for (const char* names = registered_tests; names != NULL;