1#!/usr/bin/env python
2#
3import sys, cpp, kernel, glob, os, re, getopt, clean_header, subprocess
4from defaults import *
5from utils import *
6
7def usage():
8    print """\
9  usage: %(progname)s [kernel-original-path] [kernel-modified-path]
10
11    this program is used to update all the auto-generated clean headers
12    used by the Bionic C library. it assumes the following:
13
14      - a set of source kernel headers is located in
15        'external/kernel-headers/original', relative to the current
16        android tree
17
18      - a set of manually modified kernel header files located in
19        'external/kernel-headers/modified', relative to the current
20        android tree
21
22      - the clean headers will be placed in 'bionic/libc/kernel/arch-<arch>/asm',
23        'bionic/libc/kernel/common', etc..
24""" % { "progname" : os.path.basename(sys.argv[0]) }
25    sys.exit(0)
26
27try:
28    optlist, args = getopt.getopt(sys.argv[1:], '')
29except:
30    # unrecognized option
31    sys.stderr.write("error: unrecognized option\n")
32    usage()
33
34if len(optlist) > 0 or len(args) > 2:
35    usage()
36
37modified_dir = get_kernel_headers_modified_dir()
38if len(args) == 1 or len(args) == 2:
39    original_dir = args[0]
40    if not os.path.isdir(original_dir):
41        panic("Not a directory: %s\n" % original_dir)
42
43    if len(args) == 2:
44        modified_dir = args[1]
45        if not os.path.isdir(modified_dir):
46            panic("Not a directory: %s\n" % modified_dir)
47else:
48    original_dir = get_kernel_headers_original_dir()
49    if not os.path.isdir(original_dir):
50        panic("Missing directory, please specify one through command-line: %s\n" % original_dir)
51
52if not os.path.isdir(modified_dir):
53    modified_dir = None
54
55# Find all source files in 'original'.
56sources = dict()
57original_dir = os.path.normpath(original_dir)
58original_dir_len = len(original_dir) + 1
59for root, _, files in os.walk(original_dir):
60    for file in files:
61        _, ext = os.path.splitext(file)
62        if ext == ".h":
63            rel_path = os.path.normpath(os.path.join(root, file))
64            rel_path = rel_path[original_dir_len:]
65            # Check to see if there is a modified header to use instead.
66            if modified_dir and os.path.exists(os.path.join(modified_dir, rel_path)):
67                sources[rel_path] = False
68            else:
69                sources[rel_path] = True
70
71
72b = BatchFileUpdater()
73
74kernel_dir = get_kernel_dir()
75for arch in kernel_archs:
76    b.readDir(os.path.join(kernel_dir, "arch-%s" % arch))
77
78b.readDir(os.path.join(kernel_dir, "common"))
79
80oldlen = 120
81android_root_len = len(get_android_root()) + 1
82for rel_path in sorted(sources):
83    if sources[rel_path]:
84        src_dir = original_dir
85        src_str = "<original>/"
86    else:
87        src_dir = modified_dir
88        src_str = "<modified>/"
89    dst_path, newdata = clean_header.cleanupFile(kernel_dir, src_dir, rel_path)
90    if not dst_path:
91        continue
92
93    dst_path = os.path.join(kernel_dir, dst_path)
94    b.readFile(dst_path)
95    r = b.editFile(dst_path, newdata)
96    if r == 0:
97        state = "unchanged"
98    elif r == 1:
99        state = "edited"
100    else:
101        state = "added"
102
103    # dst_path is guaranteed to include android root.
104    rel_dst_path = dst_path[android_root_len:]
105    str = "cleaning: %-*s -> %-*s (%s)" % (35, src_str + rel_path, 35, rel_dst_path, state)
106    if sys.stdout.isatty():
107        print "%-*s" % (oldlen, str),
108        if (r == 0):
109            print "\r",
110        else:
111            print "\n",
112            oldlen = 0
113    else:
114        print str
115
116    oldlen = len(str)
117
118print "%-*s" % (oldlen, "Done!")
119
120b.updateGitFiles()
121
122sys.exit(0)
123