source: rtems-source-builder/source-builder/sb/config.py @ 99eee0e

4.104.114.95
Last change on this file since 99eee0e was 99eee0e, checked in by Chris Johns <chrisj@…>, on 02/26/13 at 06:55:58

Fix the != operator.

  • Property mode set to 100644
File size: 31.0 KB
Line 
1#
2# RTEMS Tools Project (http://www.rtems.org/)
3# Copyright 2010-2012 Chris Johns (chrisj@rtems.org)
4# All rights reserved.
5#
6# This file is part of the RTEMS Tools package in 'rtems-tools'.
7#
8# Permission to use, copy, modify, and/or distribute this software for any
9# purpose with or without fee is hereby granted, provided that the above
10# copyright notice and this permission notice appear in all copies.
11#
12# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
20#
21# This code is based on a tool I wrote to parse RPM spec files in the RTEMS
22# project. This is now a configuration file format that has moved away from the
23# spec file format to support the specific needs of cross-compiling GCC. This
24# module parses a configuration file into Python data types that can be used by
25# other software modules.
26#
27
28import os
29import re
30import sys
31
32import defaults
33import error
34import execute
35import log
36import path
37
38class package:
39
40    def __init__(self, name, arch):
41        self._name = name
42        self._arch = arch
43        self.directives = {}
44        self.infos = {}
45
46    def __str__(self):
47
48        def _dictlist(dl):
49            s = ''
50            dll = dl.keys()
51            dll.sort()
52            for d in dll:
53                if d:
54                    s += '  ' + d + ':\n'
55                    for l in dl[d]:
56                        s += '    ' + l + '\n'
57            return s
58
59        s = '\npackage: ' + self._name + \
60            '\n directives:\n' + _dictlist(self.directives) + \
61            '\n infos:\n' + _dictlist(self.infos)
62
63        return s
64
65    def directive_extend(self, dir, data):
66        if dir not in self.directives:
67            self.directives[dir] = []
68        for i in range(0, len(data)):
69            data[i] = data[i].strip()
70        self.directives[dir].extend(data)
71
72    def info_append(self, info, data):
73        if info not in self.infos:
74            self.infos[info] = []
75        self.infos[info].append(data)
76
77    def get_info(self, info):
78        if not info in self.infos:
79            raise error.general('no %s in package "%s"' % (info, self.name))
80        return self.info
81
82    def version(self):
83        return self.get_info('Version')
84
85    def extract_info(self, label):
86        infos = {}
87        for i in self.infos:
88            il = i.lower()
89            if il.startswith(label):
90                if il == label:
91                    il = label + '0'
92                elif not il[len(label):].isdigit():
93                    continue
94                infos[il] = self.infos[i]
95        return infos
96
97    def find_info(self, label):
98        for i in self.infos:
99            if i.lower() == label:
100                return self.infos[i]
101        return None
102
103    def find_directive(self, label):
104        for d in self.directives:
105            if d.lower() == label:
106                return self.directives[d]
107        return None
108
109    def name(self):
110        info = self.find_info('name')
111        if info:
112            return info[0]
113        return self._name
114
115    def version(self):
116        info = self.find_info('version')
117        if not info:
118            return None
119        return info[0]
120
121    def release(self):
122        info = self.find_info('release')
123        if not info:
124            return None
125        return info[0]
126
127    def buildarch(self):
128        info = self.find_info('buildarch')
129        if not info:
130            return self._arch
131        return info[0]
132
133    def sources(self):
134        return self.extract_info('source');
135
136    def patches(self):
137        return self.extract_info('patch')
138
139    def prep(self):
140        return self.find_directive('%prep')
141
142    def build(self):
143        return self.find_directive('%build')
144
145    def install(self):
146        return self.find_directive('%install')
147
148    def clean(self):
149        return self.find_directive('%clean')
150
151    def include(self):
152        return self.find_directive('%include')
153
154    def long_name(self):
155        return self.name()
156
157class file:
158    """Parse a config file."""
159
160    _directive = [ '%description',
161                   '%prep',
162                   '%build',
163                   '%clean',
164                   '%install',
165                   '%include',
166                   '%install' ]
167
168    _ignore = [ re.compile('%setup'),
169                re.compile('%configure'),
170                re.compile('%source[0-9]*'),
171                re.compile('%patch[0-9]*') ]
172
173    def __init__(self, name, _defaults, opts):
174        self.opts = opts
175        if self.opts.trace():
176            print 'config: %s' % (name)
177        self.configpath = []
178        self.wss = re.compile(r'\s+')
179        self.tags = re.compile(r':+')
180        self.sf = re.compile(r'%\([^\)]+\)')
181        self.default_defines = {}
182        for d in _defaults:
183            self.default_defines[self._label(d)] = _defaults[d][2]
184        for arg in self.opts.args:
185            if arg.startswith('--with-') or arg.startswith('--without-'):
186                label = arg[2:].lower().replace('-', '_')
187                self.default_defines[self._label(label)] = label
188        self.load_depth = 0
189        self.load(name)
190
191    def __str__(self):
192
193        def _dict(dd):
194            s = ''
195            ddl = dd.keys()
196            ddl.sort()
197            for d in ddl:
198                s += '  ' + d + ': ' + dd[d] + '\n'
199            return s
200
201        s = 'config: %s' % ('.'.join(self.configpath)) + \
202            '\n' + str(self.opts) + \
203            '\nlines parsed: %d' % (self.lc) + \
204            '\nname: ' + self.name + \
205            '\ndefines:\n' + _dict(self.defines)
206        for _package in self._packages:
207            s += str(self._packages[_package])
208        return s
209
210    def _name_line_msg(self,  msg):
211        return '%s:%d: %s' % (path.basename(self.name), self.lc,  msg)
212
213    def _output(self, text):
214        if not self.opts.quiet():
215            log.output(text)
216
217    def _warning(self, msg):
218        self._output('warning: %s' % (self._name_line_msg(msg)))
219
220    def _error(self, msg):
221        err = 'error: %s' % (self._name_line_msg(msg))
222        print >> sys.stderr, err
223        self._output(err)
224        self.in_error = True
225        if not self.opts.dry_run():
226            print >> sys.stderr, 'warning: switched to dry run due to errors'
227            self.opts.set_dry_run()
228
229    def _label(self, name):
230        return '%{' + name.lower() + '}'
231
232    def _macro_split(self, s):
233        '''Split the string (s) up by macros. Only split on the
234           outter level. Nested levels will need to split with futher calls.'''
235        trace_me = False
236        macros = []
237        nesting = []
238        has_braces = False
239        c = 0
240        while c < len(s):
241            if trace_me:
242                print 'ms:', c, '"' + s[c:] + '"', has_braces, len(nesting), nesting
243            #
244            # We need to watch for shell type variables or the form '${var}' because
245            # they can upset the brace matching.
246            #
247            if s[c] == '%' or s[c] == '$':
248                start = s[c]
249                c += 1
250                if c == len(s):
251                    continue
252                #
253                # Do we have '%%' or '%(' or '$%' or '$(' or not '${' ?
254                #
255                if s[c] == '%' or s[c] == '(' or (start == '$' and s[c] != '{'):
256                    continue
257                elif not s[c].isspace():
258                    #
259                    # If this is a shell macro and we are at the outter
260                    # level or is '$var' forget it and move on.
261                    #
262                    if start == '$' and (s[c] != '{' or len(nesting) == 0):
263                        continue
264                    if s[c] == '{':
265                        this_has_braces = True
266                    else:
267                        this_has_braces = False
268                    nesting.append((c - 1, has_braces))
269                    has_braces = this_has_braces
270            elif len(nesting) > 0:
271                if s[c] == '}' or (s[c].isspace() and not has_braces):
272                    #
273                    # Can have '%{?test: something %more}' where the
274                    # nested %more ends with the '}' which also ends
275                    # the outter macro.
276                    #
277                    if not has_braces:
278                        if s[c] == '}':
279                            macro_start, has_braces = nesting[len(nesting) - 1]
280                            nesting = nesting[:-1]
281                            if len(nesting) == 0:
282                                macros.append(s[macro_start:c].strip())
283                    if len(nesting) > 0:
284                        macro_start, has_braces = nesting[len(nesting) - 1]
285                        nesting = nesting[:-1]
286                        if len(nesting) == 0:
287                            macros.append(s[macro_start:c + 1].strip())
288            c += 1
289        if trace_me:
290            print 'ms:', macros
291        return macros
292
293    def _shell(self, line):
294        sl = self.sf.findall(line)
295        if len(sl):
296            e = execute.capture_execution()
297            for s in sl:
298                exit_code, proc, output = e.shell(s[2:-1])
299                if exit_code == 0:
300                    line = line.replace(s, output)
301                else:
302                    raise error.general('shell macro failed: %s: %s' % (s, output))
303        return line
304
305    def _expand(self, s):
306        expanded = True
307        while expanded:
308            expanded = False
309            ms = self._macro_split(s)
310            for m in ms:
311                mn = m
312                #
313                # A macro can be '%{macro}' or '%macro'. Turn the later into
314                # the former.
315                #
316                show_warning = True
317                if mn[1] != '{':
318                    for r in self._ignore:
319                        if r.match(mn) is not None:
320                            mn = None
321                            break
322                    else:
323                        mn = self._label(mn[1:])
324                        show_warning = False
325                elif m.startswith('%{expand'):
326                    colon = m.find(':')
327                    if colon < 8:
328                        self._warning('malformed expand macro, no colon found')
329                    else:
330                        e = self._expand(m[colon + 1:-1].strip())
331                        s = s.replace(m, e)
332                        expanded = True
333                        mn = None
334                elif m.startswith('%{with '):
335                    #
336                    # Change the ' ' to '_' because the macros have no spaces.
337                    #
338                    n = self._label('with_' + m[7:-1].strip())
339                    if n in self.defines:
340                        s = s.replace(m, '1')
341                    else:
342                        s = s.replace(m, '0')
343                    expanded = True
344                    mn = None
345                elif m.startswith('%{echo'):
346                    mn = None
347                elif m.startswith('%{defined'):
348                    n = self._label(m[9:-1].strip())
349                    if n in self.defines:
350                        s = s.replace(m, '1')
351                    else:
352                        s = s.replace(m, '0')
353                    expanded = True
354                    mn = None
355                elif m.startswith('%{?') or m.startswith('%{!?'):
356                    if m[2] == '!':
357                        start = 4
358                    else:
359                        start = 3
360                    colon = m[start:].find(':')
361                    if colon < 0:
362                        if not m.endswith('}'):
363                            self._warning("malform conditional macro '%s'" % (m))
364                            mn = None
365                        else:
366                            mn = self._label(m[start:-1])
367                    else:
368                        mn = self._label(m[start:start + colon])
369                    if mn:
370                        if m.startswith('%{?'):
371                            if mn in self.defines:
372                                if colon >= 0:
373                                    s = s.replace(m, m[start + colon + 1:-1])
374                                    expanded = True
375                                    mn = None
376                            else:
377                                mn = '%{nil}'
378                        else:
379                            if mn not in self.defines:
380                                if colon >= 0:
381                                    s = s.replace(m, m[start + colon + 1:-1])
382                                    expanded = True
383                                    mn = None
384                            else:
385                                mn = '%{nil}'
386                if mn:
387                    if mn.lower() in self.defines:
388                        s = s.replace(m, self.defines[mn.lower()])
389                        expanded = True
390                    elif show_warning:
391                        self._error("macro '%s' not found" % (mn))
392        return self._shell(s)
393
394    def _define(self, config, ls):
395        if len(ls) <= 1:
396            self._warning('invalid macro definition')
397        else:
398            d = self._label(ls[1])
399            if (d not in self.defines) or \
400                    (d in self.defines and len(self.defines[d]) == 0):
401                if len(ls) == 2:
402                    self.defines[d] = '1'
403                else:
404                    self.defines[d] = ls[2].strip()
405            else:
406                if self.opts.warn_all():
407                    self._warning("macro '%s' already defined" % (d))
408
409    def _undefine(self, config, ls):
410        if len(ls) <= 1:
411            self._warning('invalid macro definition')
412        else:
413            mn = self._label(ls[1])
414            if mn in self.defines:
415                self._error("macro '%s' not defined" % (mn))
416            del self.defines[mn]
417
418    def _ifs(self, config, ls, label, iftrue, isvalid):
419        text = []
420        in_iftrue = True
421        while True:
422            if isvalid and \
423                    ((iftrue and in_iftrue) or (not iftrue and not in_iftrue)):
424                this_isvalid = True
425            else:
426                this_isvalid = False
427            r = self._parse(config, roc = True, isvalid = this_isvalid)
428            if r[0] == 'control':
429                if r[1] == '%end':
430                    self._error(label + ' without %endif')
431                    raise error.general('terminating build')
432                if r[1] == '%endif':
433                    return text
434                if r[1] == '%else':
435                    in_iftrue = False
436            elif r[0] == 'data':
437                if this_isvalid:
438                    text.extend(r[1])
439
440    def _if(self, config, ls, isvalid, invert = False):
441
442        def add(x, y):
443            return x + ' ' + str(y)
444
445        def check_bool(value):
446            if value.isdigit():
447                if int(value) == 0:
448                    istrue = False
449                else:
450                    istrue = True
451            else:
452                istrue = None
453            return istrue
454
455        istrue = False
456        if isvalid:
457            if len(ls) == 2:
458                s = ls[1]
459            else:
460                s = (ls[1] + ' ' + ls[2])
461            ifls = s.split()
462            if len(ifls) == 1:
463                #
464                # Check if '%if %{x} == %{nil}' has both parts as nothing
465                # which means '%if ==' is always True and '%if !=' is always false.
466                #
467                if ifls[0] == '==':
468                    istrue = True
469                elif ifls[0] == '!=':
470                    istrue = False
471                else:
472                    istrue = check_bool(ifls[0])
473                    if istrue == None:
474                        self._error('invalid if bool value: ' + reduce(add, ls, ''))
475                        istrue = False
476            elif len(ifls) == 2:
477                if ifls[0] == '!':
478                    istrue = check_bool(ifls[1])
479                    if istrue == None:
480                        self._error('invalid if bool value: ' + reduce(add, ls, ''))
481                        istrue = False
482                    else:
483                        istrue = not istrue
484                else:
485                    #
486                    # Check is something is being checked against empty,
487                    #   ie '%if %{x} == %{nil}'
488                    # The logic is 'something == nothing' is False and
489                    # 'something != nothing' is True.
490                    #
491                    if ifls[1] == '==':
492                        istrue = False
493                    elif  ifls[1] == '!=':
494                        istrue = True
495                    else:
496                        self._error('invalid if bool operator: ' + reduce(add, ls, ''))
497            elif len(ifls) == 3:
498                if ifls[1] == '==':
499                    if ifls[0] == ifls[2]:
500                        istrue = True
501                    else:
502                        istrue = False
503                elif ifls[1] == '!=' or ifls[1] == '=!':
504                    if ifls[0] != ifls[2]:
505                        istrue = True
506                    else:
507                        istrue = False
508                elif ifls[1] == '>':
509                    if ifls[0] > ifls[2]:
510                        istrue = True
511                    else:
512                        istrue = False
513                elif ifls[1] == '>=' or ifls[1] == '=>':
514                    if ifls[0] >= ifls[2]:
515                        istrue = True
516                    else:
517                        istrue = False
518                elif ifls[1] == '<=' or ifls[1] == '=<':
519                    if ifls[0] <= ifls[2]:
520                        istrue = True
521                    else:
522                        istrue = False
523                elif ifls[1] == '<':
524                    if ifls[0] < ifls[2]:
525                        istrue = True
526                    else:
527                        istrue = False
528                else:
529                    self._error('invalid %if operator: ' + reduce(add, ls, ''))
530            else:
531                self._error('malformed if: ' + reduce(add, ls, ''))
532            if invert:
533                istrue = not istrue
534            if self.opts.trace():
535                print '_if:  ', ifls, istrue
536        return self._ifs(config, ls, '%if', istrue, isvalid)
537
538    def _ifos(self, config, ls, isvalid):
539        isos = False
540        if isvalid:
541            os = self.define('_os')
542            if ls[0].find(os) >= 0 or ls[1].find(os) >= 0:
543                isos = True
544            else:
545                isos = False
546        return self._ifs(config, ls, '%ifos', isos, isvalid)
547
548    def _ifarch(self, config, positive, ls, isvalid):
549        isarch = False
550        if isvalid:
551            arch = self.define('_arch')
552            if ls[0].find(arch) >= 0 or ls[1].find(arch) >= 0:
553                isarch = True
554            else:
555                isarch = False
556        if not positive:
557            isarch = not isarch
558        return self._ifs(config, ls, '%ifarch', isarch, isvalid)
559
560    def _parse(self, config, roc = False, isvalid = True):
561        # roc = return on control
562
563        def _clean(line):
564            line = line[0:-1]
565            b = line.find('#')
566            if b >= 0:
567                line = line[1:b]
568            return line.strip()
569
570        #
571        # Need to add code to count matching '{' and '}' and if they
572        # do not match get the next line and add to the string until
573        # they match. This closes an opening '{' that is on another
574        # line.
575        #
576
577        for l in config:
578            self.lc += 1
579            l = _clean(l)
580            if len(l) == 0:
581                continue
582            if self.opts.trace():
583                print '%03d: %d %s' % (self.lc, isvalid, l)
584            if isvalid:
585                l = self._expand(l)
586            if len(l) == 0:
587                continue
588            if l[0] == '%':
589                ls = self.wss.split(l, 2)
590                if ls[0] == '%package':
591                    if isvalid:
592                        if ls[1] == '-n':
593                            name = ls[2]
594                        else:
595                            name = self.name + '-' + ls[1]
596                        return ('package', name)
597                elif ls[0] == '%error':
598                    if isvalid:
599                        return ('data', ['%%error %s' % (self._name_line_msg(l[7:]))])
600                elif ls[0] == '%warning':
601                    if isvalid:
602                        return ('data', ['%%warning %s' % (self._name_line_msg(l[9:]))])
603                elif ls[0] == '%define' or ls[0] == '%global':
604                    if isvalid:
605                        self._define(config, ls)
606                elif ls[0] == '%undefine':
607                    if isvalid:
608                        self._undefine(config, ls)
609                elif ls[0] == '%if':
610                    d = self._if(config, ls, isvalid)
611                    if len(d):
612                        return ('data', d)
613                elif ls[0] == '%ifn':
614                    d = self._if(config, ls, isvalid, True)
615                    if len(d):
616                        return ('data', d)
617                elif ls[0] == '%ifos':
618                    d = self._ifos(config, ls, isvalid)
619                    if len(d):
620                        return ('data', d)
621                elif ls[0] == '%ifarch':
622                    d = self._ifarch(config, True, ls, isvalid)
623                    if len(d):
624                        return ('data', d)
625                elif ls[0] == '%ifnarch':
626                    d = self._ifarch(config, False, ls, isvalid)
627                    if len(d):
628                        return ('data', d)
629                elif ls[0] == '%endif':
630                    if roc:
631                        return ('control', '%endif')
632                    self._warning("unexpected '" + ls[0] + "'")
633                elif ls[0] == '%else':
634                    if roc:
635                        return ('control', '%else')
636                    self._warning("unexpected '" + ls[0] + "'")
637                elif ls[0].startswith('%defattr'):
638                    return ('data', [l])
639                elif ls[0] == '%bcond_with':
640                    if isvalid:
641                        #
642                        # Check if already defined. Would be by the command line or
643                        # even a host specific default.
644                        #
645                        if self._label('with_' + ls[1]) not in self.defines:
646                            self._define(config, (ls[0], 'without_' + ls[1]))
647                elif ls[0] == '%bcond_without':
648                    if isvalid:
649                        if self._label('without_' + ls[1]) not in self.defines:
650                            self._define(config, (ls[0], 'with_' + ls[1]))
651                else:
652                    for r in self._ignore:
653                        if r.match(ls[0]) is not None:
654                            return ('data', [l])
655                    if isvalid:
656                        for d in self._directive:
657                            if ls[0].strip() == d:
658                                return ('directive', ls[0].strip(), ls[1:])
659                        self._warning("unknown directive: '" + ls[0] + "'")
660                        return ('data', [l])
661            else:
662                return ('data', [l])
663        return ('control', '%end')
664
665    def _set_package(self, _package):
666        if self.package == 'main' and \
667                self._packages[self.package].name() != None:
668            if self._packages[self.package].name() == _package:
669                return
670        if _package not in self._packages:
671            self._packages[_package] = package(_package,
672                                               self.define('%{_arch}'))
673        self.package = _package
674
675    def _directive_extend(self, dir, data):
676        self._packages[self.package].directive_extend(dir, data)
677
678    def _info_append(self, info, data):
679        self._packages[self.package].info_append(info, data)
680
681    def load(self, name):
682
683        def common_end(left, right):
684            end = ''
685            while len(left) and len(right):
686                if left[-1] != right[-1]:
687                    return end
688                end = left[-1] + end
689                left = left[:-1]
690                right = right[:-1]
691            return end
692
693        if self.load_depth == 0:
694            self.in_error = False
695            self.lc = 0
696            self.name = name
697            self.defines = self.default_defines
698            self.conditionals = {}
699            self._packages = {}
700            self.package = 'main'
701            self._packages[self.package] = package(self.package,
702                                                   self.define('%{_arch}'))
703
704        self.load_depth += 1
705
706        save_name = self.name
707        save_lc = self.lc
708
709        self.name = name
710        self.lc = 0
711
712        #
713        # Locate the config file. Expand any macros then add the
714        # extension. Check if the file exists, therefore directly
715        # referenced. If not see if the file contains ':' or the path
716        # separator. If it does split the path else use the standard config dir
717        # path in the defaults.
718        #
719
720        exname = self.expand(name)
721
722        #
723        # Macro could add an extension.
724        #
725        if exname.endswith('.cfg'):
726            configname = exname
727        else:
728            configname = '%s.cfg' % (exname)
729            name = '%s.cfg' % (name)
730
731        if ':' in configname:
732            cfgname = path.basename(configname)
733        else:
734            cfgname = common_end(configname, name)
735
736        if not path.exists(configname):
737            if ':' in configname:
738                configdirs = path.dirname(configname).split(':')
739            else:
740                configdirs = self.define('_configdir').split(':')
741            for cp in configdirs:
742                configname = path.join(path.abspath(cp), cfgname)
743                if path.exists(configname):
744                    break
745                configname = None
746            if configname is None:
747                raise error.general('no config file found: %s' % (cfgname))
748
749        try:
750            if self.opts.trace():
751                print '_open: %s' % (path.host(configname))
752            config = open(path.host(configname), 'r')
753        except IOError, err:
754            raise error.general('error opening config file: %s' % (path.host(configname)))
755        self.configpath += [configname]
756
757        try:
758            dir = None
759            data = []
760            while True:
761                r = self._parse(config)
762                if r[0] == 'package':
763                    self._set_package(r[1])
764                    dir = None
765                elif r[0] == 'control':
766                    if r[1] == '%end':
767                        break
768                    self._warning("unexpected '" + r[1] + "'")
769                elif r[0] == 'directive':
770                    new_data = []
771                    if r[1] == '%description':
772                        new_data = [' '.join(r[2])]
773                    elif r[1] == '%include':
774                        self.load(r[2][0])
775                        continue
776                    else:
777                        if len(r[2]) == 0:
778                            _package = 'main'
779                        elif len(r[2]) == 1:
780                            _package = r[2][0]
781                        else:
782                            if r[2][0].strip() != '-n':
783                                self._warning("unknown directive option: '%s'" % (' '.join(r[2])))
784                            _package = r[2][1].strip()
785                        self._set_package(_package)
786                    if dir and dir != r[1]:
787                        self._directive_extend(dir, data)
788                    dir = r[1]
789                    data = new_data
790                elif r[0] == 'data':
791                    for l in r[1]:
792                        l = self._expand(l)
793                        if l.startswith('%error'):
794                            raise error.general('config error: %s' % (l[7:]))
795                        elif l.startswith('%warning'):
796                            print >> sys.stderr, 'warning: %s' % (l[9:])
797                            self._warning(l[9:])
798                        if not dir:
799                            ls = self.tags.split(l, 1)
800                            if self.opts.trace():
801                                print '_tag: ', l, ls
802                            if len(ls) > 1:
803                                i = ls[0]
804                                self._info_append(i, ls[1].strip())
805                                # It seems like the info's also appear as
806                                # defines or can be accessed via macros.
807                                if ls[0][len(ls[0]) - 1] == ':':
808                                    ls[0] = ls[0][:-1]
809                                ls[0] = ls[0].lower()
810                                self._define(None, ('', ls[0], ls[1]))
811                            else:
812                                self._warning("invalid format: '" + l[:-1] + "'")
813                        else:
814                            data.append(l)
815                else:
816                    self._error("invalid parse state: '" + r[0] + "'")
817            if dir is not None:
818                self._directive_extend(dir, data)
819        except:
820            config.close()
821            raise
822
823        config.close()
824
825        self.name = save_name
826        self.lc = save_lc
827
828        self.load_depth -= 1
829
830    def define(self, name):
831        if name.lower() in self.defines:
832            d = self.defines[name.lower()]
833        else:
834            n = self._label(name)
835            if n in self.defines:
836                d = self.defines[n]
837            else:
838                raise error.general('macro "' + name + '" not found')
839        return self._expand(d)
840
841    def set_define(self, name, value):
842        self.defines[name.lower()] = value
843
844    def expand(self, line):
845        return self._expand(line)
846
847    def directive(self, _package, name):
848        if _package not in self._packages:
849            raise error.general('package "' + _package + '" not found')
850        if name not in self._packages[_package].directives:
851            raise error.general('directive "' + name + \
852                                    '" not found in package "' + _package + '"')
853        return self._packages[_package].directives[name]
854
855    def abspath(self, rpath):
856        return path.abspath(self.define(rpath))
857
858    def packages(self):
859        return self._packages
860
861def run():
862    import sys
863    try:
864        opts, _defaults = defaults.load(sys.argv)
865        if opts.trace():
866            print 'config: count %d' % (len(opts.config_files()))
867        for config_file in opts.config_files():
868            s = file(config_file, _defaults = _defaults, opts = opts)
869            print s
870            del s
871    except error.general, gerr:
872        print gerr
873        sys.exit(1)
874    except error.internal, ierr:
875        print ierr
876        sys.exit(1)
877    except KeyboardInterrupt:
878        print 'user terminated'
879        sys.exit(1)
880    sys.exit(0)
881
882if __name__ == "__main__":
883    run()
Note: See TracBrowser for help on using the repository browser.