Use same warn_common.py and warn.py for Android and Chrome

* add chrome_project_list.py
* use newer Chrome's warn_common.py and severity.py
* modify warn_common.py to work with both python2 and python3,
  to work with and without google3

Test: warn.py --url=http://cs/android --separator='?l=' build.log > warnings.html
Test: warn.py --gencsv build.log > warnings.csv
Change-Id: I9aeee7031c11988d8ead1733ff4846ae6cb1ee73
diff --git a/tools/warn/warn.py b/tools/warn/warn.py
index bdfd489..56e8787 100755
--- a/tools/warn/warn.py
+++ b/tools/warn/warn.py
@@ -17,21 +17,51 @@
 """Simple wrapper to run warn_common with Python standard Pool."""
 
 import multiprocessing
+import signal
+import sys
 
 # pylint:disable=relative-beyond-top-level
-# pylint:disable=g-importing-member
-from .warn_common import common_main
+from . import warn_common as common
 
 
-# This parallel_process could be changed depending on platform
-# and availability of multi-process library functions.
-def parallel_process(num_cpu, classify_warnings, groups):
+def classify_warnings(args):
+  """Classify a list of warning lines.
+
+  Args:
+    args: dictionary {
+        'group': list of (warning, link),
+        'project_patterns': re.compile(project_list[p][1]),
+        'warn_patterns': list of warn_pattern,
+        'num_processes': number of processes being used for multiprocessing }
+  Returns:
+    results: a list of the classified warnings.
+  """
+  results = []
+  for line, link in args['group']:
+    common.classify_one_warning(line, link, results, args['project_patterns'],
+                                args['warn_patterns'])
+
+  # After the main work, ignore all other signals to a child process,
+  # to avoid bad warning/error messages from the exit clean-up process.
+  if args['num_processes'] > 1:
+    signal.signal(signal.SIGTERM, lambda *args: sys.exit(-signal.SIGTERM))
+  return results
+
+
+def create_and_launch_subprocesses(num_cpu, classify_warnings_fn, arg_groups,
+                                   group_results):
   pool = multiprocessing.Pool(num_cpu)
-  return pool.map(classify_warnings, groups)
+  for cpu in range(num_cpu):
+    proc_result = pool.map(classify_warnings_fn, arg_groups[cpu])
+    if proc_result is not None:
+      group_results.append(proc_result)
+  return group_results
 
 
 def main():
-  common_main(parallel_process)
+  use_google3 = False
+  common.common_main(use_google3, create_and_launch_subprocesses,
+                     classify_warnings)
 
 
 if __name__ == '__main__':