clean_header.py revision c9205dba43c45dc5a185aa26e1160c3f62e9b471
1#!/usr/bin/env python
2#
3
4import sys, cpp, kernel, glob, os, re, getopt
5from defaults import *
6from utils import *
7
8noUpdate = 1
9
10def  cleanupFile( path ):
11    """reads an original header and perform the cleanup operation on it
12       this functions returns the destination path and the clean header
13       as a single string"""
14    # check the header path
15    src_path    = path
16
17    if not os.path.exists(src_path):
18        if noUpdate:
19            panic( "file does not exist: '%s'\n" % path )
20        sys.stderr.write( "warning: file does not exit: %s\n" % path )
21        return None, None
22
23    if not os.path.isfile(src_path):
24        if noUpdate:
25            panic( "path is not a file: '%s'\n" % path )
26        sys.stderr.write( "warning: not a file: %s\n" % path )
27        return None, None
28
29    original_path = kernel_original_path
30    if os.path.commonprefix( [ src_path, original_path ] ) != original_path:
31        if noUpdate:
32            panic( "file is not in 'original' directory: %s\n" % path );
33        sys.stderr.write( "warning: file not in 'original' ignored: %s\n" % path )
34        return None, None
35
36    src_path = src_path[len(original_path):]
37    if len(src_path) > 0 and src_path[0] == '/':
38        src_path = src_path[1:]
39
40    if len(src_path) == 0:
41        panic( "oops, internal error, can't extract correct relative path" )
42
43    # convert into destination path, extracting architecture if needed
44    # and the corresponding list of known static functions
45    #
46    arch = None
47    re_asm_arch = re.compile( r"asm-([\w\d_\+\.\-]+)(/.*)" )
48    m = re_asm_arch.match(src_path)
49    statics = kernel_known_generic_statics
50    if m and m.group(1) != 'generic':
51        dst_path = "arch-%s/asm/%s" % m.groups()
52        arch     = m.group(1)
53        statics  = statics.union( kernel_known_statics.get( arch, set() ) )
54    else:
55        dst_path = "common/" + src_path
56
57    dst_path = os.path.normpath( original_path + "/../" + dst_path )
58
59    # now, let's parse the file
60    #
61    list = cpp.BlockParser().parseFile(path)
62    if not list:
63        sys.stderr.write( "error: can't parse '%s'" % path )
64        sys.exit(1)
65
66
67    list.optimizeMacros( kernel_known_macros )
68    list.optimizeIf01()
69    list.removeVarsAndFuncs( statics )
70    list.removeComments()
71    list.removeEmptyLines()
72    list.removeMacroDefines( kernel_ignored_macros )
73    list.insertDisclaimer( kernel.kernel_disclaimer )
74    list.replaceTokens( kernel_token_replacements )
75
76    out = StringOutput()
77    list.write(out)
78    return dst_path, out.get()
79
80
81if __name__ == "__main__":
82
83    def usage():
84        print """\
85    usage:  %s [options] <header_path>
86
87        options:
88            -v    enable verbose mode
89
90            -u    enabled update mode
91                this will try to update the corresponding 'clean header'
92                if the content has changed. with this, you can pass more
93                than one file on the command-line
94
95        <header_path> must be in a subdirectory of 'original'
96    """ % os.path.basename(sys.argv[0])
97        sys.exit(1)
98
99    try:
100        optlist, args = getopt.getopt( sys.argv[1:], 'uvk:' )
101    except:
102        # unrecognized option
103        sys.stderr.write( "error: unrecognized option\n" )
104        usage()
105
106    for opt, arg in optlist:
107        if opt == '-u':
108            noUpdate = 0
109        elif opt == '-v':
110            verbose = 1
111            D_setlevel(1)
112        elif opt == '-k':
113            kernel_original_path = arg
114
115    if len(args) == 0:
116        usage()
117
118    if noUpdate:
119        for path in args:
120            dst_path, newdata = cleanupFile(path)
121            print newdata
122
123        sys.exit(0)
124
125    # now let's update our files.
126
127    b = BatchFileUpdater()
128
129    for path in args:
130        dst_path, newdata = cleanupFile(path)
131        if not dst_path:
132            continue
133
134        b.readFile( dst_path )
135        r = b.editFile( dst_path, newdata )
136        if r == 0:
137            r = "unchanged"
138        elif r == 1:
139            r = "edited"
140        else:
141            r = "added"
142
143        print "cleaning: %-*s -> %-*s (%s)" % ( 35, path, 35, dst_path, r )
144
145
146    if os.environ.has_key("ANDROID_PRODUCT_OUT"):
147        b.updateP4Files()
148    else:
149        b.updateFiles()
150
151    sys.exit(0)
152