Fixes two bugs in analyzer

Wasn't delaing with relative paths outside the repo. NACL does this
for things like /usr/include/...
When combining relative paths I was missing adding a '/'. This result
in paths like baseobserver_list.h instead of base/observer_list.h.

BUG=383609
TEST=covered by unit tests
R=mark@chromium.org

Review URL: https://codereview.chromium.org/383893003

git-svn-id: http://gyp.googlecode.com/svn/trunk@1949 78cadc50-ecff-11dd-a971-7dbc132099af
diff --git a/pylib/gyp/generator/analyzer.py b/pylib/gyp/generator/analyzer.py
index 77e4647..80ef01c 100644
--- a/pylib/gyp/generator/analyzer.py
+++ b/pylib/gyp/generator/analyzer.py
@@ -55,6 +55,23 @@
     return ''
   return target[0:(last_index + 1)]
 
+def __ResolveParent(path, base_path_components):
+  """Resolves |path|, which starts with at least one '../'. Returns an empty
+  string if the path shouldn't be considered. See __AddSources() for a
+  description of |base_path_components|."""
+  depth = 0
+  while path.startswith('../'):
+    depth += 1
+    path = path[3:]
+  # Relative includes may go outside the source tree. For example, an action may
+  # have inputs in /usr/include, which are not in the source tree.
+  if depth > len(base_path_components):
+    return ''
+  if depth == len(base_path_components):
+    return path
+  return '/'.join(base_path_components[0:len(base_path_components) - depth]) + \
+      '/' + path
+
 def __AddSources(sources, base_path, base_path_components, result):
   """Extracts valid sources from |sources| and adds them to |result|. Each
   source file is relative to |base_path|, but may contain '..'. To make
@@ -69,12 +86,9 @@
     # variable expansion may lead to //.
     source = source[0] + source[1:].replace('//', '/')
     if source.startswith('../'):
-      path_components = base_path_components[:]
-      # Resolve relative paths.
-      while source.startswith('../'):
-        path_components.pop(len(path_components) - 1)
-        source = source[3:]
-      result.append('/'.join(path_components) + source)
+      source = __ResolveParent(source, base_path_components)
+      if len(source):
+        result.append(source)
       continue
     result.append(base_path + source)
 
diff --git a/test/analyzer/gyptest-analyzer.py b/test/analyzer/gyptest-analyzer.py
index a42748f..e374627 100644
--- a/test/analyzer/gyptest-analyzer.py
+++ b/test/analyzer/gyptest-analyzer.py
@@ -73,4 +73,8 @@
 __CreateTestFile(['parent_source.c'])
 test.run_gyp('test.gyp', '-Gfile_path=test_file', stdout=found)
 
+# Verifies relative paths are resolved correctly.
+__CreateTestFile(['subdir/subdir_source.h'])
+test.run_gyp('test.gyp', '-Gfile_path=test_file', stdout=found)
+
 test.pass_test()
diff --git a/test/analyzer/subdir/subdir2/subdir2.gyp b/test/analyzer/subdir/subdir2/subdir2.gyp
new file mode 100644
index 0000000..e5aaa92
--- /dev/null
+++ b/test/analyzer/subdir/subdir2/subdir2.gyp
@@ -0,0 +1,15 @@
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+  'targets': [
+    {
+      'target_name': 'subdir2',
+      'type': 'static_library',
+      'sources': [
+        '../subdir_source.h',
+      ],
+    },
+  ],
+}
diff --git a/test/analyzer/test.gyp b/test/analyzer/test.gyp
index b3fcdd3..482ede3 100644
--- a/test/analyzer/test.gyp
+++ b/test/analyzer/test.gyp
@@ -13,6 +13,7 @@
       'type': 'executable',
       'dependencies': [
         'subdir/subdir.gyp:foo',
+        'subdir/subdir2/subdir2.gyp:subdir2',
       ],
       'sources': [
         'foo.c',
@@ -31,6 +32,8 @@
           'inputs': [
             '<(PRODUCT_DIR)/product_dir_input.c',
             'action_input.c',
+            '../bad_path1.h',
+            '../../bad_path2.h',
           ],
           'outputs': [
             'action_output.c',