Changes in tools/config.py [5a8fbcb:c01f8e6] in mainline


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • tools/config.py

    r5a8fbcb rc01f8e6  
    33# Copyright (c) 2006 Ondrej Palkovsky
    44# Copyright (c) 2009 Martin Decky
     5# Copyright (c) 2010 Jiri Svoboda
    56# All rights reserved.
    67#
     
    2829# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2930#
     31
    3032"""
    3133HelenOS configuration system
    3234"""
     35
    3336import sys
    3437import os
     
    3841import xtui
    3942
    40 INPUT = sys.argv[1]
     43RULES_FILE = sys.argv[1]
    4144MAKEFILE = 'Makefile.config'
    4245MACROS = 'config.h'
    43 DEFS = 'config.defs'
    44 PRECONF = 'defaults'
    45 
    46 def read_defaults(fname, defaults):
    47         "Read saved values from last configuration run"
    48        
    49         inf = file(fname, 'r')
     46PRESETS_DIR = 'defaults'
     47
     48def read_config(fname, config):
     49        "Read saved values from last configuration run or a preset file"
     50       
     51        inf = open(fname, 'r')
    5052       
    5153        for line in inf:
    5254                res = re.match(r'^(?:#!# )?([^#]\w*)\s*=\s*(.*?)\s*$', line)
    53                 if (res):
    54                         defaults[res.group(1)] = res.group(2)
     55                if res:
     56                        config[res.group(1)] = res.group(2)
    5557       
    5658        inf.close()
    5759
    58 def check_condition(text, defaults, ask_names):
     60def check_condition(text, config, rules):
    5961        "Check that the condition specified on input line is True (only CNF and DNF is supported)"
    6062       
    6163        ctype = 'cnf'
    6264       
    63         if ((')|' in text) or ('|(' in text)):
     65        if (')|' in text) or ('|(' in text):
    6466                ctype = 'dnf'
    6567       
    66         if (ctype == 'cnf'):
     68        if ctype == 'cnf':
    6769                conds = text.split('&')
    6870        else:
     
    7072       
    7173        for cond in conds:
    72                 if (cond.startswith('(')) and (cond.endswith(')')):
     74                if cond.startswith('(') and cond.endswith(')'):
    7375                        cond = cond[1:-1]
    7476               
    75                 inside = check_inside(cond, defaults, ctype)
     77                inside = check_inside(cond, config, ctype)
    7678               
    7779                if (ctype == 'cnf') and (not inside):
    7880                        return False
    7981               
    80                 if (ctype == 'dnf') and (inside):
     82                if (ctype == 'dnf') and inside:
    8183                        return True
    8284       
    83         if (ctype == 'cnf'):
     85        if ctype == 'cnf':
    8486                return True
    8587        return False
    8688
    87 def check_inside(text, defaults, ctype):
     89def check_inside(text, config, ctype):
    8890        "Check for condition"
    8991       
    90         if (ctype == 'cnf'):
     92        if ctype == 'cnf':
    9193                conds = text.split('|')
    9294        else:
     
    9597        for cond in conds:
    9698                res = re.match(r'^(.*?)(!?=)(.*)$', cond)
    97                 if (not res):
     99                if not res:
    98100                        raise RuntimeError("Invalid condition: %s" % cond)
    99101               
     
    102104                condval = res.group(3)
    103105               
    104                 if (not defaults.has_key(condname)):
     106                if not condname in config:
    105107                        varval = ''
    106108                else:
    107                         varval = defaults[condname]
     109                        varval = config[condname]
    108110                        if (varval == '*'):
    109111                                varval = 'y'
    110112               
    111                 if (ctype == 'cnf'):
     113                if ctype == 'cnf':
    112114                        if (oper == '=') and (condval == varval):
    113115                                return True
     
    122124                                return False
    123125       
    124         if (ctype == 'cnf'):
     126        if ctype == 'cnf':
    125127                return False
    126128       
    127129        return True
    128130
    129 def parse_config(fname, ask_names):
    130         "Parse configuration file"
    131        
    132         inf = file(fname, 'r')
     131def parse_rules(fname, rules):
     132        "Parse rules file"
     133       
     134        inf = open(fname, 'r')
    133135       
    134136        name = ''
     
    137139        for line in inf:
    138140               
    139                 if (line.startswith('!')):
     141                if line.startswith('!'):
    140142                        # Ask a question
    141143                        res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line)
    142144                       
    143                         if (not res):
     145                        if not res:
    144146                                raise RuntimeError("Weird line: %s" % line)
    145147                       
     
    148150                        vartype = res.group(3)
    149151                       
    150                         ask_names.append((varname, vartype, name, choices, cond))
     152                        rules.append((varname, vartype, name, choices, cond))
    151153                        name = ''
    152154                        choices = []
    153155                        continue
    154156               
    155                 if (line.startswith('@')):
     157                if line.startswith('@'):
    156158                        # Add new line into the 'choices' array
    157159                        res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line)
     
    163165                        continue
    164166               
    165                 if (line.startswith('%')):
     167                if line.startswith('%'):
    166168                        # Name of the option
    167169                        name = line[1:].strip()
    168170                        continue
    169171               
    170                 if ((line.startswith('#')) or (line == '\n')):
     172                if line.startswith('#') or (line == '\n'):
    171173                        # Comment or empty line
    172174                        continue
     
    180182        "Return '*' if yes, ' ' if no"
    181183       
    182         if (default == 'y'):
     184        if default == 'y':
    183185                return '*'
    184186       
     
    198200        cnt = 0
    199201        for key, val in choices:
    200                 if ((default) and (key == default)):
     202                if (default) and (key == default):
    201203                        position = cnt
    202204               
     
    206208        (button, value) = xtui.choice_window(screen, name, 'Choose value', options, position)
    207209       
    208         if (button == 'cancel'):
     210        if button == 'cancel':
    209211                return None
    210212       
    211213        return choices[value][0]
    212214
    213 def check_choices(defaults, ask_names):
    214         "Check whether all accessible variables have a default"
    215        
    216         for varname, vartype, name, choices, cond in ask_names:
    217                 if ((cond) and (not check_condition(cond, defaults, ask_names))):
     215## Infer and verify configuration values.
     216#
     217# Augment @a config with values that can be inferred, purge invalid ones
     218# and verify that all variables have a value (previously specified or inferred).
     219#
     220# @param config Configuration to work on
     221# @param rules  Rules
     222#
     223# @return True if configuration is complete and valid, False
     224#         otherwise.
     225#
     226def infer_verify_choices(config, rules):
     227        "Infer and verify configuration values."
     228       
     229        for rule in rules:
     230                varname, vartype, name, choices, cond = rule
     231               
     232                if cond and (not check_condition(cond, config, rules)):
    218233                        continue
    219234               
    220                 if (not defaults.has_key(varname)):
     235                if not varname in config:
     236                        value = None
     237                else:
     238                        value = config[varname]
     239               
     240                if not validate_rule_value(rule, value):
     241                        value = None
     242               
     243                default = get_default_rule(rule)
     244
     245                #
     246                # If we don't have a value but we do have
     247                # a default, use it.
     248                #
     249                if value == None and default != None:
     250                        value = default
     251                        config[varname] = default
     252               
     253                if not varname in config:
    221254                        return False
    222255       
    223256        return True
    224257
    225 def create_output(mkname, mcname, dfname, defaults, ask_names):
     258## Get default value from a rule.
     259def get_default_rule(rule):
     260        varname, vartype, name, choices, cond = rule
     261       
     262        default = None
     263       
     264        if vartype == 'choice':
     265                # If there is just one option, use it
     266                if len(choices) == 1:
     267                        default = choices[0][0]
     268        elif vartype == 'y':
     269                default = '*'
     270        elif vartype == 'n':
     271                default = 'n'
     272        elif vartype == 'y/n':
     273                default = 'y'
     274        elif vartype == 'n/y':
     275                default = 'n'
     276        else:
     277                raise RuntimeError("Unknown variable type: %s" % vartype)
     278       
     279        return default
     280
     281## Get option from a rule.
     282#
     283# @param rule  Rule for a variable
     284# @param value Current value of the variable
     285#
     286# @return Option (string) to ask or None which means not to ask.
     287#
     288def get_rule_option(rule, value):
     289        varname, vartype, name, choices, cond = rule
     290       
     291        option = None
     292       
     293        if vartype == 'choice':
     294                # If there is just one option, don't ask
     295                if len(choices) != 1:
     296                        if (value == None):
     297                                option = "?     %s --> " % name
     298                        else:
     299                                option = "      %s [%s] --> " % (name, value)
     300        elif vartype == 'y':
     301                pass
     302        elif vartype == 'n':
     303                pass
     304        elif vartype == 'y/n':
     305                option = "  <%s> %s " % (yes_no(value), name)
     306        elif vartype == 'n/y':
     307                option ="  <%s> %s " % (yes_no(value), name)
     308        else:
     309                raise RuntimeError("Unknown variable type: %s" % vartype)
     310       
     311        return option
     312
     313## Check if variable value is valid.
     314#
     315# @param rule  Rule for the variable
     316# @param value Value of the variable
     317#
     318# @return True if valid, False if not valid.
     319#
     320def validate_rule_value(rule, value):
     321        varname, vartype, name, choices, cond = rule
     322       
     323        if value == None:
     324                return True
     325       
     326        if vartype == 'choice':
     327                if not value in [choice[0] for choice in choices]:
     328                        return False
     329        elif vartype == 'y':
     330                if value != 'y':
     331                        return False
     332        elif vartype == 'n':
     333                if value != 'n':
     334                        return False
     335        elif vartype == 'y/n':
     336                if not value in ['y', 'n']:
     337                        return False
     338        elif vartype == 'n/y':
     339                if not value in ['y', 'n']:
     340                        return False
     341        else:
     342                raise RuntimeError("Unknown variable type: %s" % vartype)
     343       
     344        return True
     345
     346def create_output(mkname, mcname, config, rules):
    226347        "Create output configuration"
    227348       
    228349        timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    229         version = subprocess.Popen(['bzr', 'version-info', '--custom', '--template={clean}:{revno}:{revision_id}'], stdout = subprocess.PIPE).communicate()[0].split(':')
    230        
    231         if (len(version) == 3):
     350       
     351        sys.stderr.write("Fetching current revision identifier ... ")
     352       
     353        try:
     354                version = subprocess.Popen(['bzr', 'version-info', '--custom', '--template={clean}:{revno}:{revision_id}'], stdout = subprocess.PIPE).communicate()[0].decode().split(':')
     355                sys.stderr.write("ok\n")
     356        except:
     357                version = [1, "unknown", "unknown"]
     358                sys.stderr.write("failed\n")
     359       
     360        if len(version) == 3:
    232361                revision = version[1]
    233                 if (version[0] != 1):
     362                if version[0] != 1:
    234363                        revision += 'M'
    235364                revision += ' (%s)' % version[2]
     
    237366                revision = None
    238367       
    239         outmk = file(mkname, 'w')
    240         outmc = file(mcname, 'w')
    241         outdf = file(dfname, 'w')
     368        outmk = open(mkname, 'w')
     369        outmc = open(mcname, 'w')
    242370       
    243371        outmk.write('#########################################\n')
     
    249377        outmc.write(' ***************************************/\n\n')
    250378       
    251         outdf.write('#########################################\n')
    252         outdf.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
    253         outdf.write('#########################################\n\n')
    254         outdf.write('CONFIG_DEFS =')
    255        
    256         for varname, vartype, name, choices, cond in ask_names:
    257                 if ((cond) and (not check_condition(cond, defaults, ask_names))):
     379        defs = 'CONFIG_DEFS ='
     380       
     381        for varname, vartype, name, choices, cond in rules:
     382                if cond and (not check_condition(cond, config, rules)):
    258383                        continue
    259384               
    260                 if (not defaults.has_key(varname)):
    261                         default = ''
     385                if not varname in config:
     386                        value = ''
    262387                else:
    263                         default = defaults[varname]
    264                         if (default == '*'):
    265                                 default = 'y'
    266                
    267                 outmk.write('# %s\n%s = %s\n\n' % (name, varname, default))
    268                
    269                 if ((vartype == "y") or (vartype == "n") or (vartype == "y/n") or (vartype == "n/y")):
    270                         if (default == "y"):
     388                        value = config[varname]
     389                        if (value == '*'):
     390                                value = 'y'
     391               
     392                outmk.write('# %s\n%s = %s\n\n' % (name, varname, value))
     393               
     394                if vartype in ["y", "n", "y/n", "n/y"]:
     395                        if value == "y":
    271396                                outmc.write('/* %s */\n#define %s\n\n' % (name, varname))
    272                                 outdf.write(' -D%s' % varname)
     397                                defs += ' -D%s' % varname
    273398                else:
    274                         outmc.write('/* %s */\n#define %s %s\n#define %s_%s\n\n' % (name, varname, default, varname, default))
    275                         outdf.write(' -D%s=%s -D%s_%s' % (varname, default, varname, default))
    276        
    277         if (revision is not None):
     399                        outmc.write('/* %s */\n#define %s %s\n#define %s_%s\n\n' % (name, varname, value, varname, value))
     400                        defs += ' -D%s=%s -D%s_%s' % (varname, value, varname, value)
     401       
     402        if revision is not None:
    278403                outmk.write('REVISION = %s\n' % revision)
    279404                outmc.write('#define REVISION %s\n' % revision)
    280                 outdf.write(' "-DREVISION=%s"' % revision)
     405                defs += ' "-DREVISION=%s"' % revision
    281406       
    282407        outmk.write('TIMESTAMP = %s\n' % timestamp)
    283408        outmc.write('#define TIMESTAMP %s\n' % timestamp)
    284         outdf.write(' "-DTIMESTAMP=%s"\n' % timestamp)
     409        defs += ' "-DTIMESTAMP=%s"\n' % timestamp
     410       
     411        outmk.write(defs)
    285412       
    286413        outmk.close()
    287414        outmc.close()
    288         outdf.close()
    289415
    290416def sorted_dir(root):
     
    293419        return list
    294420
    295 def read_preconfigured(root, fname, screen, defaults):
     421## Ask user to choose a configuration profile.
     422#
     423def choose_profile(root, fname, screen, config):
    296424        options = []
    297425        opt2path = {}
     
    303431                canon = os.path.join(path, fname)
    304432               
    305                 if ((os.path.isdir(path)) and (os.path.exists(canon)) and (os.path.isfile(canon))):
     433                if os.path.isdir(path) and os.path.exists(canon) and os.path.isfile(canon):
    306434                        subprofile = False
    307435                       
     
    311439                                subcanon = os.path.join(subpath, fname)
    312440                               
    313                                 if ((os.path.isdir(subpath)) and (os.path.exists(subcanon)) and (os.path.isfile(subcanon))):
     441                                if os.path.isdir(subpath) and os.path.exists(subcanon) and os.path.isfile(subcanon):
    314442                                        subprofile = True
    315443                                        options.append("%s (%s)" % (name, subname))
    316                                         opt2path[cnt] = (canon, subcanon)
     444                                        opt2path[cnt] = [name, subname]
    317445                                        cnt += 1
    318446                       
    319                         if (not subprofile):
     447                        if not subprofile:
    320448                                options.append(name)
    321                                 opt2path[cnt] = (canon, None)
     449                                opt2path[cnt] = [name]
    322450                                cnt += 1
    323451       
    324452        (button, value) = xtui.choice_window(screen, 'Load preconfigured defaults', 'Choose configuration profile', options, None)
    325453       
    326         if (button == 'cancel'):
     454        if button == 'cancel':
    327455                return None
    328456       
    329         read_defaults(opt2path[value][0], defaults)
    330         if (opt2path[value][1] != None):
    331                 read_defaults(opt2path[value][1], defaults)
     457        return opt2path[value]
     458
     459## Read presets from a configuration profile.
     460#
     461# @param profile Profile to load from (a list of string components)
     462# @param config  Output configuration
     463#
     464def read_presets(profile, config):
     465        path = os.path.join(PRESETS_DIR, profile[0], MAKEFILE)
     466        read_config(path, config)
     467       
     468        if len(profile) > 1:
     469                path = os.path.join(PRESETS_DIR, profile[0], profile[1], MAKEFILE)
     470                read_config(path, config)
     471
     472## Parse profile name (relative OS path) into a list of components.
     473#
     474# @param profile_name Relative path (using OS separator)
     475# @return             List of components
     476#
     477def parse_profile_name(profile_name):
     478        profile = []
     479       
     480        head, tail = os.path.split(profile_name)
     481        if head != '':
     482                profile.append(head)
     483       
     484        profile.append(tail)
     485        return profile
    332486
    333487def main():
    334         defaults = {}
    335         ask_names = []
    336        
    337         # Parse configuration file
    338         parse_config(INPUT, ask_names)
    339        
    340         # Read defaults from previous run
    341         if os.path.exists(MAKEFILE):
    342                 read_defaults(MAKEFILE, defaults)
    343        
    344         # Default mode: only check defaults and regenerate configuration
    345         if ((len(sys.argv) >= 3) and (sys.argv[2] == 'default')):
    346                 if (check_choices(defaults, ask_names)):
    347                         create_output(MAKEFILE, MACROS, DEFS, defaults, ask_names)
     488        profile = None
     489        config = {}
     490        rules = []
     491       
     492        # Parse rules file
     493        parse_rules(RULES_FILE, rules)
     494       
     495        # Input configuration file can be specified on command line
     496        # otherwise configuration from previous run is used.
     497        if len(sys.argv) >= 4:
     498                profile = parse_profile_name(sys.argv[3])
     499                read_presets(profile, config)
     500        elif os.path.exists(MAKEFILE):
     501                read_config(MAKEFILE, config)
     502       
     503        # Default mode: check values and regenerate configuration files
     504        if (len(sys.argv) >= 3) and (sys.argv[2] == 'default'):
     505                if (infer_verify_choices(config, rules)):
     506                        create_output(MAKEFILE, MACROS, config, rules)
    348507                        return 0
    349508       
    350         # Check mode: only check defaults
    351         if ((len(sys.argv) >= 3) and (sys.argv[2] == 'check')):
    352                 if (check_choices(defaults, ask_names)):
     509        # Hands-off mode: check values and regenerate configuration files,
     510        # but no interactive fallback
     511        if (len(sys.argv) >= 3) and (sys.argv[2] == 'hands-off'):
     512                # We deliberately test sys.argv >= 4 because we do not want
     513                # to read implicitly any possible previous run configuration
     514                if len(sys.argv) < 4:
     515                        sys.stderr.write("Configuration error: No presets specified\n")
     516                        return 2
     517               
     518                if (infer_verify_choices(config, rules)):
     519                        create_output(MAKEFILE, MACROS, config, rules)
     520                        return 0
     521               
     522                sys.stderr.write("Configuration error: The presets are ambiguous\n")
     523                return 1
     524       
     525        # Check mode: only check configuration
     526        if (len(sys.argv) >= 3) and (sys.argv[2] == 'check'):
     527                if infer_verify_choices(config, rules):
    353528                        return 0
    354529                return 1
     
    360535                while True:
    361536                       
    362                         # Cancel out all defaults which have to be deduced
    363                         for varname, vartype, name, choices, cond in ask_names:
    364                                 if ((vartype == 'y') and (defaults.has_key(varname)) and (defaults[varname] == '*')):
    365                                         defaults[varname] = None
     537                        # Cancel out all values which have to be deduced
     538                        for varname, vartype, name, choices, cond in rules:
     539                                if (vartype == 'y') and (varname in config) and (config[varname] == '*'):
     540                                        config[varname] = None
    366541                       
    367542                        options = []
     
    371546                        options.append("  --- Load preconfigured defaults ... ")
    372547                       
    373                         for varname, vartype, name, choices, cond in ask_names:
    374                                
    375                                 if ((cond) and (not check_condition(cond, defaults, ask_names))):
     548                        for rule in rules:
     549                                varname, vartype, name, choices, cond = rule
     550                               
     551                                if cond and (not check_condition(cond, config, rules)):
    376552                                        continue
    377553                               
    378                                 if (varname == selname):
     554                                if varname == selname:
    379555                                        position = cnt
    380556                               
    381                                 if (not defaults.has_key(varname)):
    382                                         default = None
     557                                if not varname in config:
     558                                        value = None
    383559                                else:
    384                                         default = defaults[varname]
    385                                
    386                                 if (vartype == 'choice'):
    387                                         # Check if the default is an acceptable value
    388                                         if ((default) and (not default in [choice[0] for choice in choices])):
    389                                                 default = None
    390                                                 defaults.pop(varname)
    391                                        
    392                                         # If there is just one option, use it
    393                                         if (len(choices) == 1):
    394                                                 defaults[varname] = choices[0][0]
    395                                                 continue
    396                                        
    397                                         if (default == None):
    398                                                 options.append("?     %s --> " % name)
    399                                         else:
    400                                                 options.append("      %s [%s] --> " % (name, default))
    401                                 elif (vartype == 'y'):
    402                                         defaults[varname] = '*'
     560                                        value = config[varname]
     561                               
     562                                if not validate_rule_value(rule, value):
     563                                        value = None
     564                               
     565                                default = get_default_rule(rule)
     566
     567                                #
     568                                # If we don't have a value but we do have
     569                                # a default, use it.
     570                                #
     571                                if value == None and default != None:
     572                                        value = default
     573                                        config[varname] = default
     574                               
     575                                option = get_rule_option(rule, value)
     576                                if option != None:
     577                                        options.append(option)
     578                                else:
    403579                                        continue
    404                                 elif (vartype == 'n'):
    405                                         defaults[varname] = 'n'
    406                                         continue
    407                                 elif (vartype == 'y/n'):
    408                                         if (default == None):
    409                                                 default = 'y'
    410                                                 defaults[varname] = default
    411                                         options.append("  <%s> %s " % (yes_no(default), name))
    412                                 elif (vartype == 'n/y'):
    413                                         if (default == None):
    414                                                 default = 'n'
    415                                                 defaults[varname] = default
    416                                         options.append("  <%s> %s " % (yes_no(default), name))
    417                                 else:
    418                                         raise RuntimeError("Unknown variable type: %s" % vartype)
    419580                               
    420581                                opt2row[cnt] = (varname, vartype, name, choices)
     
    422583                                cnt += 1
    423584                       
    424                         if (position >= options):
     585                        if (position != None) and (position >= len(options)):
    425586                                position = None
    426587                       
    427588                        (button, value) = xtui.choice_window(screen, 'HelenOS configuration', 'Choose configuration option', options, position)
    428589                       
    429                         if (button == 'cancel'):
     590                        if button == 'cancel':
    430591                                return 'Configuration canceled'
    431592                       
    432                         if (button == 'done'):
    433                                 if (check_choices(defaults, ask_names)):
     593                        if button == 'done':
     594                                if (infer_verify_choices(config, rules)):
    434595                                        break
    435596                                else:
     
    437598                                        continue
    438599                       
    439                         if (value == 0):
    440                                 read_preconfigured(PRECONF, MAKEFILE, screen, defaults)
     600                        if value == 0:
     601                                profile = choose_profile(PRESETS_DIR, MAKEFILE, screen, config)
     602                                if profile != None:
     603                                        read_presets(profile, config)
    441604                                position = 1
    442605                                continue
    443606                       
    444607                        position = None
    445                         if (not opt2row.has_key(value)):
     608                        if not value in opt2row:
    446609                                raise RuntimeError("Error selecting value: %s" % value)
    447610                       
    448611                        (selname, seltype, name, choices) = opt2row[value]
    449612                       
    450                         if (not defaults.has_key(selname)):
    451                                         default = None
     613                        if not selname in config:
     614                                value = None
    452615                        else:
    453                                 default = defaults[selname]
    454                        
    455                         if (seltype == 'choice'):
    456                                 defaults[selname] = subchoice(screen, name, choices, default)
    457                         elif ((seltype == 'y/n') or (seltype == 'n/y')):
    458                                 if (defaults[selname] == 'y'):
    459                                         defaults[selname] = 'n'
     616                                value = config[selname]
     617                       
     618                        if seltype == 'choice':
     619                                config[selname] = subchoice(screen, name, choices, value)
     620                        elif (seltype == 'y/n') or (seltype == 'n/y'):
     621                                if config[selname] == 'y':
     622                                        config[selname] = 'n'
    460623                                else:
    461                                         defaults[selname] = 'y'
     624                                        config[selname] = 'y'
    462625        finally:
    463626                xtui.screen_done(screen)
    464627       
    465         create_output(MAKEFILE, MACROS, DEFS, defaults, ask_names)
     628        create_output(MAKEFILE, MACROS, config, rules)
    466629        return 0
    467630
Note: See TracChangeset for help on using the changeset viewer.