~ubuntu-branches/ubuntu/hoary/kdemultimedia/hoary

« back to all changes in this revision

Viewing changes to admin/am_edit.py

  • Committer: Bazaar Package Importer
  • Author(s): Martin Schulze
  • Date: 2003-01-22 15:00:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030122150051-uihwkdoxf15mi1tn
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import getopt, string, posixpath, sys, os, os.path, re
 
2
 
 
3
# Some global globals...
 
4
verbose     = 0
 
5
thisProg    = posixpath.basename(sys.argv[0])
 
6
if not thisProg: # happy only when running in xemacs ;/
 
7
    thisProg = 'am_edit.py'
 
8
cppsuffixes = ['cpp', 'cc', 'cxx', 'C', 'c++']
 
9
hExt        = ['h', 'H', 'hh', 'hxx', 'h++']
 
10
progId      = "KDE tags expanded automatically by " + thisProg
 
11
use_final   = 1
 
12
dryrun      = 0
 
13
pathoption  = 0
 
14
topdir      = os.path.abspath(os.curdir) + "/"
 
15
foreigndirs = []
 
16
 
 
17
class Makefile:
 
18
    def __init__(self, file):
 
19
        # some useful globals for the subroutines called here
 
20
        self.headerdirs = ['.']
 
21
        self.haveAutomocTag   = 0
 
22
 
 
23
        self.programs = []
 
24
 
 
25
        # lists the objects compiled into $program
 
26
        self.realobjs = {}
 
27
        # lists the sources used for $program
 
28
        self.sources = {}
 
29
        # lists the objects compiled when final
 
30
        self.finalObjs = {}
 
31
        # the binary name of program variable
 
32
        self.realname = {}
 
33
        # lists the idl files used for $program
 
34
        self.idlfiles = {}
 
35
        # lists all idl generated files for cleantarget
 
36
        self.idl_output = ""
 
37
 
 
38
        self.depedmocs = {}
 
39
 
 
40
        self.dep_files      = ""
 
41
        self.dep_finals     = ""
 
42
        # the targets to add
 
43
        self.target_adds    = {}
 
44
        self.kdelang        = ""
 
45
        self.makefile       = file
 
46
        self.makefileDir    = os.path.dirname(self.makefile)
 
47
        self.options        = {}
 
48
 
 
49
 
 
50
    NoMakefileAmFound = "found Makefile.in without Makefile.am"
 
51
 
 
52
    def findLine(self, line):
 
53
        import types
 
54
        if type(line) is types.StringType:
 
55
            regexp = re.compile(line)
 
56
        else:
 
57
            regexp = line
 
58
        for line in self.lines:
 
59
            match = regexp.match(line)
 
60
            if match:
 
61
                return match
 
62
    
 
63
    def substituteLine(self, old, new):
 
64
        import types
 
65
        if type(old) is types.StringType:
 
66
            regexp = re.compile(old)
 
67
        else:
 
68
            regexp = old
 
69
            
 
70
        for index in range(len(self.lines)):
 
71
            line = self.lines[index]
 
72
            match = regexp.match(line)
 
73
            if match:
 
74
                line = '#>- ' + line
 
75
                newlines = string.split(new, '\n')
 
76
                self.lines[index:index+1] = [line, '#>+ %d' % len(newlines)] + newlines
 
77
                return
 
78
 
 
79
    def addTarget(self, target, dependson):
 
80
        if not self.target_adds.has_key(target):
 
81
            self.target_adds[target] = [dependson]
 
82
        else:
 
83
            self.target_adds[target].append(dependson)
 
84
            
 
85
    def appendLines(self, newlines):
 
86
        lines = string.split(newlines, '\n') + ['\n']
 
87
        self.lines.extend(['#>+ %d' % len(lines)] + lines)
 
88
        
 
89
    def restore(self):
 
90
        index = 0
 
91
        while index < len(self.lines):
 
92
            line = self.lines[index]
 
93
            if line[0:3] == '#>+':
 
94
                # the +1 is the comment itself
 
95
                linec = string.atoi(line[3:]) + 1
 
96
                del self.lines[index:index+linec]
 
97
                continue
 
98
            if line[0:3] == '#>-':
 
99
                self.lines[index] = self.lines[index][4:]
 
100
            index = index + 1
 
101
        
 
102
    def initialize(self):
 
103
        global foreigndirs
 
104
 
 
105
        os.chdir(self.makefileDir)
 
106
        self.printname = string.replace(self.makefile, topdir, "")
 
107
        self.makefile = os.path.basename(self.makefile)
 
108
 
 
109
        if not posixpath.exists("Makefile.am"):
 
110
            raise self.NoMakefileAmFound, self.makefileDir
 
111
 
 
112
        for dir in foreigndirs:
 
113
            if dir.match(self.makefileDir):
 
114
                print 'leaving ' + self.makefileDir
 
115
                return 0
 
116
 
 
117
        f = open(self.makefile)
 
118
        self.lines = []
 
119
      
 
120
        while 1:
 
121
            line = f.readline()
 
122
            if not line: break
 
123
            self.lines.append(string.rstrip(line))
 
124
 
 
125
        f.close()
 
126
        
 
127
        # take out the 
 
128
        self.restore()
 
129
        
 
130
        optionline = re.compile('^\s*(\w+)\s*=\s*([^\n]*)$')
 
131
        linecontinued = re.compile('\\\s*\n')
 
132
        lastline = ''
 
133
 
 
134
        index = 0
 
135
        while index < len(self.lines):
 
136
            line = self.lines[index]
 
137
            if linecontinued.search(line):
 
138
                self.lines[index] = linecontinued.sub(' ', line) + self.lines[index+1]
 
139
                continue
 
140
            else:
 
141
                index = index + 1
 
142
 
 
143
            match = optionline.search(line)
 
144
            if match:
 
145
                self.options[match.group(1)] = match.group(2)
 
146
 
 
147
        if self.options.has_key('KDE_OPTIONS'):
 
148
            options = string.split(self.options['KDE_OPTIONS'])
 
149
            if 'foreign' in options:
 
150
                foreigndirs.append(re.compile(self.makefileDir + "/.*"))
 
151
                return 0
 
152
 
 
153
        self.cxxsuffix = ""
 
154
        suffixes = re.compile('^\.SUFFIXES:(.*)$')
 
155
 
 
156
        for line in self.lines:
 
157
            match = suffixes.match(line)
 
158
            if match:
 
159
                existing_suffixes = string.split(match.group(1))
 
160
                for suffix in existing_suffixes:
 
161
                    # leave out the .
 
162
                    if suffix[1:] in cppsuffixes:
 
163
                        self.cxxsuffix = suffix[1:]
 
164
                        break
 
165
                if self.cxxsuffix:
 
166
                    break
 
167
 
 
168
        search_real_programs = {}
 
169
 
 
170
        for option in self.options.keys():
 
171
            if string.rfind(option, '_OBJECTS') > 0:
 
172
 
 
173
                program = option[0:string.find(option, '_OBJECTS')]
 
174
                objs = self.options[option]
 
175
 
 
176
                variable_in_objects = 0
 
177
 
 
178
                objlist = string.split(objs)
 
179
                variable = re.compile('\$\((\w+)\)')
 
180
                for obj in objlist:
 
181
                    match = variable.match(obj)
 
182
                    if match and not match.group(1) == 'OBJEXT':
 
183
                        variable_in_objects = 1
 
184
                        break
 
185
 
 
186
                if variable_in_objects:
 
187
                    continue
 
188
 
 
189
                if len(program) > 3 and program[3] == 'am_':
 
190
                    program = program[3:]
 
191
 
 
192
                if verbose:
 
193
                    print "found program " + program
 
194
 
 
195
                self.programs.append(program)
 
196
                self.realobjs[program] = objs
 
197
 
 
198
                if self.options.has_key(program + "_SOURCES"):
 
199
                    self.sources[program] = self.options[program + "_SOURCES"]
 
200
                else:
 
201
                    self.sources[program] = ""
 
202
                    sys.stderr.write("found program with no _SOURCES: " + program + '\n')
 
203
 
 
204
                # unmask to regexp
 
205
                realprogram = string.replace(program, '_', '.')
 
206
                search_real_programs[program] = re.compile('.*(' + realprogram +
 
207
                                                           ')(\$\(EXEEXT\)?)?:.*\$\(' +
 
208
                                                           program + '_OBJECTS\).*')
 
209
 
 
210
                self.realname[program] = "";
 
211
 
 
212
        for line in self.lines:
 
213
            if string.find(line, '_OBJECTS') > 0: # just a random piece to not use at _every_ line
 
214
                for program in self.programs:
 
215
                    match = search_real_programs[program].match(line)
 
216
                    if match:
 
217
                        self.realname[program] = match.group(1)
 
218
 
 
219
    def finalTouch(self):
 
220
        if self.options.has_key('DEPDIR'):
 
221
            sys.stderr.write(self.printname + " defines DEPDIR. This means you're using automake > 1.4 - this is not supported!")
 
222
        else:
 
223
            # taken out a random variable
 
224
            self.substituteLine('bindir\s*=.*', 'DEPDIR = .deps\nbindir = ' + self.options['bindir'])
 
225
 
 
226
        self.appendLines('cvs-clean:\n' +
 
227
                         '\t$(MAKE) -f $(top_srcdir)/admin/Makefile.common cvs-clean')
 
228
 
 
229
        self.appendLines('kde-rpo-clean:\n'+
 
230
                         '\t-rm -f *.rpo')
 
231
 
 
232
        self.addTarget('clean', 'kde-rpo-clean')
 
233
        self.addAllTargets()
 
234
 
 
235
    def addAllTargets(self):
 
236
        for target in self.target_adds.keys():
 
237
            match = self.findLine(target + ':\s*(.*)')
 
238
            if match:
 
239
                self.substituteLine(match.re, target + ': ' +
 
240
                                    string.join(self.target_adds[target]) +
 
241
                                    ' ' + match.group(1))
 
242
                    
 
243
    def writeback(self):
 
244
        f = open(self.makefile, 'w')
 
245
        for line in self.lines:
 
246
            f.write(line)
 
247
            f.write('\n')
 
248
        f.close()
 
249
 
 
250
    def tag_automake(self):
 
251
        match = self.findLine('^(.*cd \$\(top_srcdir\)\s+&&\s+\$\(AUTOMAKE\).*)$')
 
252
        if not match: return 1
 
253
        self.substituteLine(match.re, match.group(1) + '\n' +
 
254
                       '\tcd $(top_srcdir) && python ' +
 
255
                       thisProg + ' ' + self.printname)
 
256
        
 
257
def main():
 
258
    global use_final, dryrun, pathoption, thisProg, verbose
 
259
 
 
260
    optlist, makefiles = getopt.getopt(sys.argv[1:], 'vhp:n', [
 
261
        'version', 'verbose', 'path=', 'help', 'no-final'])
 
262
 
 
263
    for option, param in optlist:
 
264
        if option == '--version':
 
265
            print "\n"
 
266
            print thisProg + "$Revision: 1.3 $"
 
267
            print "This is really free software, unencumbered by the GPL."
 
268
            print "You can do anything you like with it except sueing me."
 
269
            print "Copyright 1998 Kalle Dalheimer <kalle\@kde.org>"
 
270
            print "Concept, design and unnecessary questions about perl"
 
271
            print "     by Matthias Ettrich <ettrich\@kde.org>"
 
272
            print ""
 
273
            print "Making it useful by Stephan Kulow <coolo\@kde.org> and"
 
274
            print "Harri Porten <porten\@kde.org>"
 
275
            print "Updated (Feb-1999), John Birch <jb.nz\@writeme.com>"
 
276
            print "Current Maintainer Stephan Kulow"
 
277
            sys.exit(0)
 
278
        if option == '--verbose' or option == '-v':
 
279
            verbose = 1
 
280
        if option == '-p' or option == '--path':
 
281
            thisProg = param + "/" + thisProg
 
282
            if (not posixpath.exists(thisProg)):
 
283
                sys.stderr.write(thisProg + " doesn't exist\n")
 
284
            pathoption=1
 
285
        if option == '--help' or option == '-h':
 
286
            print "Usage " + thisProg + " [OPTION] ... [dir/Makefile.in]..."
 
287
            print "Patches dir/Makefile.in generated from automake"
 
288
            print "(where dir can be a full or relative directory name)"
 
289
            print "  -v, --verbose      verbosely list files processed"
 
290
            print "  -h, --help         print this help, then exit"
 
291
            print "  --version          print version number, then exit"
 
292
            print "  -p, --path=        use the path to am_edit if the path"
 
293
            print "  --no-final         don't patch for --enable-final"
 
294
            print "                     called from is not the one to be used"
 
295
            sys.exit(0)
 
296
        if option == '--no-final':
 
297
            use_final = 0
 
298
        if option == '-n':
 
299
            dryrun = 1
 
300
 
 
301
    if not use_final:
 
302
        thisProg = thisProg + " --no-final"
 
303
 
 
304
    if thisProg[0] == '/' and not pathoption:
 
305
        sys.stderr.write( "Illegal full pathname call performed...\n"
 
306
                          "The call to \"" + thisProg + "\"\n"
 
307
                          "would be inserted in some Makefile.in.\n"
 
308
                          "Please use option --path.\n")
 
309
        sys.exit(1)
 
310
 
 
311
    if len(makefiles) == 0:
 
312
        import find
 
313
        makefiles = find.find('Makefile.in')
 
314
 
 
315
    for index in range(len(makefiles)):
 
316
        if not makefiles[index][0] == '/':
 
317
            makefiles[index] = os.path.normcase(os.path.abspath(makefiles[index]))
 
318
 
 
319
    makefiles.sort()
 
320
    for file in makefiles:
 
321
        makefile = Makefile(file)
 
322
        try:
 
323
            makefile.initialize()
 
324
            makefile.tag_automake()
 
325
            makefile.finalTouch()
 
326
            makefile.writeback()
 
327
        except Makefile.NoMakefileAmFound, param:
 
328
            if verbose: print Makefile.NoMakefileAmFound + ' in ' + param
 
329
 
 
330
main()