1# Copyright 2012 the V8 project authors. All rights reserved.
2# Redistribution and use in source and binary forms, with or without
3# modification, are permitted provided that the following conditions are
4# met:
5#
6#     * Redistributions of source code must retain the above copyright
7#       notice, this list of conditions and the following disclaimer.
8#     * Redistributions in binary form must reproduce the above
9#       copyright notice, this list of conditions and the following
10#       disclaimer in the documentation and/or other materials provided
11#       with the distribution.
12#     * Neither the name of Google Inc. nor the names of its
13#       contributors may be used to endorse or promote products derived
14#       from this software without specific prior written permission.
15#
16# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28# for py2/py3 compatibility
29from __future__ import print_function
30
31from os.path import exists
32from os.path import isdir
33from os.path import join
34import os
35import platform
36import re
37import urllib
38
39
40### Exit codes and their meaning.
41# Normal execution.
42EXIT_CODE_PASS = 0
43# Execution with test failures.
44EXIT_CODE_FAILURES = 1
45# Execution with no tests executed.
46EXIT_CODE_NO_TESTS = 2
47# Execution aborted with SIGINT (Ctrl-C).
48EXIT_CODE_INTERRUPTED = 3
49# Execution aborted with SIGTERM.
50EXIT_CODE_TERMINATED = 4
51# Internal error.
52EXIT_CODE_INTERNAL_ERROR = 5
53
54
55def GetSuitePaths(test_root):
56  return [ f for f in os.listdir(test_root) if isdir(join(test_root, f)) ]
57
58
59# Reads a file into an array of strings
60def ReadLinesFrom(name):
61  lines = []
62  with open(name) as f:
63    for line in f:
64      if line.startswith('#'): continue
65      if '#' in line:
66        line = line[:line.find('#')]
67      line = line.strip()
68      if not line: continue
69      lines.append(line)
70  return lines
71
72
73def GuessOS():
74  system = platform.system()
75  if system == 'Linux':
76    return 'linux'
77  elif system == 'Darwin':
78    return 'macos'
79  elif system.find('CYGWIN') >= 0:
80    return 'cygwin'
81  elif system == 'Windows' or system == 'Microsoft':
82    # On Windows Vista platform.system() can return 'Microsoft' with some
83    # versions of Python, see http://bugs.python.org/issue1082
84    return 'windows'
85  elif system == 'DragonFlyBSD':
86    return 'dragonfly'
87  elif system == 'DragonFly':
88    return 'dragonfly'
89  elif system == 'FreeBSD':
90    return 'freebsd'
91  elif system == 'OpenBSD':
92    return 'openbsd'
93  elif system == 'SunOS':
94    return 'solaris'
95  elif system == 'NetBSD':
96    return 'netbsd'
97  elif system == 'AIX':
98    return 'aix'
99  else:
100    return None
101
102
103def UseSimulator(arch):
104  machine = platform.machine()
105  return (machine and
106      (arch == "mipsel" or arch == "arm" or arch == "arm64") and
107      not arch.startswith(machine))
108
109
110# This will default to building the 32 bit VM even on machines that are
111# capable of running the 64 bit VM.
112def DefaultArch():
113  machine = platform.machine()
114  machine = machine.lower()  # Windows 7 capitalizes 'AMD64'.
115  if machine.startswith('arm'):
116    return 'arm'
117  elif (not machine) or (not re.match('(x|i[3-6])86$', machine) is None):
118    return 'ia32'
119  elif machine == 'i86pc':
120    return 'ia32'
121  elif machine == 'x86_64':
122    return 'ia32'
123  elif machine == 'amd64':
124    return 'ia32'
125  elif machine == 's390x':
126    return 's390'
127  elif machine == 'ppc64':
128    return 'ppc'
129  else:
130    return None
131
132
133def GuessWordsize():
134  if '64' in platform.machine():
135    return '64'
136  else:
137    return '32'
138
139
140def IsWindows():
141  return GuessOS() == 'windows'
142
143
144class FrozenDict(dict):
145  def __setitem__(self, *args, **kwargs):
146    raise Exception('Tried to mutate a frozen dict')
147
148  def update(self, *args, **kwargs):
149    raise Exception('Tried to mutate a frozen dict')
150
151
152def Freeze(obj):
153  if isinstance(obj, dict):
154    return FrozenDict((k, Freeze(v)) for k, v in obj.iteritems())
155  elif isinstance(obj, set):
156    return frozenset(obj)
157  elif isinstance(obj, list):
158    return tuple(Freeze(item) for item in obj)
159  else:
160    # Make sure object is hashable.
161    hash(obj)
162    return obj
163