Changeset a35b458 in mainline for tools/config.py


Ignore:
Timestamp:
2018-03-02T20:10:49Z (7 years ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f1380b7
Parents:
3061bc1
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
Message:

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • tools/config.py

    r3061bc1 ra35b458  
    4949def read_config(fname, config):
    5050        "Read saved values from last configuration run or a preset file"
    51        
     51
    5252        inf = open(fname, 'r')
    53        
     53
    5454        for line in inf:
    5555                res = re.match(r'^(?:#!# )?([^#]\w*)\s*=\s*(.*?)\s*$', line)
    5656                if res:
    5757                        config[res.group(1)] = res.group(2)
    58        
     58
    5959        inf.close()
    6060
    6161def check_condition(text, config, rules):
    6262        "Check that the condition specified on input line is True (only CNF and DNF is supported)"
    63        
     63
    6464        ctype = 'cnf'
    65        
     65
    6666        if (')|' in text) or ('|(' in text):
    6767                ctype = 'dnf'
    68        
     68
    6969        if ctype == 'cnf':
    7070                conds = text.split('&')
    7171        else:
    7272                conds = text.split('|')
    73        
     73
    7474        for cond in conds:
    7575                if cond.startswith('(') and cond.endswith(')'):
    7676                        cond = cond[1:-1]
    77                
     77
    7878                inside = check_inside(cond, config, ctype)
    79                
     79
    8080                if (ctype == 'cnf') and (not inside):
    8181                        return False
    82                
     82
    8383                if (ctype == 'dnf') and inside:
    8484                        return True
    85        
     85
    8686        if ctype == 'cnf':
    8787                return True
    88        
     88
    8989        return False
    9090
    9191def check_inside(text, config, ctype):
    9292        "Check for condition"
    93        
     93
    9494        if ctype == 'cnf':
    9595                conds = text.split('|')
    9696        else:
    9797                conds = text.split('&')
    98        
     98
    9999        for cond in conds:
    100100                res = re.match(r'^(.*?)(!?=)(.*)$', cond)
    101101                if not res:
    102102                        raise RuntimeError("Invalid condition: %s" % cond)
    103                
     103
    104104                condname = res.group(1)
    105105                oper = res.group(2)
    106106                condval = res.group(3)
    107                
     107
    108108                if not condname in config:
    109109                        varval = ''
     
    112112                        if (varval == '*'):
    113113                                varval = 'y'
    114                
     114
    115115                if ctype == 'cnf':
    116116                        if (oper == '=') and (condval == varval):
    117117                                return True
    118                
     118
    119119                        if (oper == '!=') and (condval != varval):
    120120                                return True
     
    122122                        if (oper == '=') and (condval != varval):
    123123                                return False
    124                        
     124
    125125                        if (oper == '!=') and (condval == varval):
    126126                                return False
    127        
     127
    128128        if ctype == 'cnf':
    129129                return False
    130        
     130
    131131        return True
    132132
    133133def parse_rules(fname, rules):
    134134        "Parse rules file"
    135        
     135
    136136        inf = open(fname, 'r')
    137        
     137
    138138        name = ''
    139139        choices = []
    140        
     140
    141141        for line in inf:
    142                
     142
    143143                if line.startswith('!'):
    144144                        # Ask a question
    145145                        res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line)
    146                        
     146
    147147                        if not res:
    148148                                raise RuntimeError("Weird line: %s" % line)
    149                        
     149
    150150                        cond = res.group(1)
    151151                        varname = res.group(2)
    152152                        vartype = res.group(3)
    153                        
     153
    154154                        rules.append((varname, vartype, name, choices, cond))
    155155                        name = ''
    156156                        choices = []
    157157                        continue
    158                
     158
    159159                if line.startswith('@'):
    160160                        # Add new line into the 'choices' array
    161161                        res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line)
    162                        
     162
    163163                        if not res:
    164164                                raise RuntimeError("Bad line: %s" % line)
    165                        
     165
    166166                        choices.append((res.group(2), res.group(3)))
    167167                        continue
    168                
     168
    169169                if line.startswith('%'):
    170170                        # Name of the option
    171171                        name = line[1:].strip()
    172172                        continue
    173                
     173
    174174                if line.startswith('#') or (line == '\n'):
    175175                        # Comment or empty line
    176176                        continue
    177                
    178                
     177
     178
    179179                raise RuntimeError("Unknown syntax: %s" % line)
    180        
     180
    181181        inf.close()
    182182
    183183def yes_no(default):
    184184        "Return '*' if yes, ' ' if no"
    185        
     185
    186186        if default == 'y':
    187187                return '*'
    188        
     188
    189189        return ' '
    190190
    191191def subchoice(screen, name, choices, default):
    192192        "Return choice of choices"
    193        
     193
    194194        maxkey = 0
    195195        for key, val in choices:
     
    197197                if (length > maxkey):
    198198                        maxkey = length
    199        
     199
    200200        options = []
    201201        position = None
     
    204204                if (default) and (key == default):
    205205                        position = cnt
    206                
     206
    207207                options.append(" %-*s  %s " % (maxkey, key, val))
    208208                cnt += 1
    209        
     209
    210210        (button, value) = xtui.choice_window(screen, name, 'Choose value', options, position)
    211        
     211
    212212        if button == 'cancel':
    213213                return None
    214        
     214
    215215        return choices[value][0]
    216216
     
    228228def infer_verify_choices(config, rules):
    229229        "Infer and verify configuration values."
    230        
     230
    231231        for rule in rules:
    232232                varname, vartype, name, choices, cond = rule
    233                
     233
    234234                if cond and (not check_condition(cond, config, rules)):
    235235                        continue
    236                
     236
    237237                if not varname in config:
    238238                        value = None
    239239                else:
    240240                        value = config[varname]
    241                
     241
    242242                if not validate_rule_value(rule, value):
    243243                        value = None
    244                
     244
    245245                default = get_default_rule(rule)
    246                
     246
    247247                #
    248248                # If we don't have a value but we do have
     
    252252                        value = default
    253253                        config[varname] = default
    254                
     254
    255255                if not varname in config:
    256256                        return False
    257        
     257
    258258        return True
    259259
     
    275275        if start_index >= len(rules):
    276276                return True
    277        
     277
    278278        varname, vartype, name, choices, cond = rules[start_index]
    279279
     
    282282                if not check_condition(cond, config, rules):
    283283                        return random_choices(config, rules, start_index + 1)
    284        
     284
    285285        # Remember previous choices for backtracking
    286286        yes_no = 0
    287287        choices_indexes = range(0, len(choices))
    288288        random.shuffle(choices_indexes)
    289        
     289
    290290        # Remember current configuration value
    291291        old_value = None
     
    294294        except KeyError:
    295295                old_value = None
    296        
     296
    297297        # For yes/no choices, we ran the loop at most 2 times, for select
    298298        # choices as many times as there are options.
     
    320320                else:
    321321                        raise RuntimeError("Unknown variable type: %s" % vartype)
    322        
     322
    323323                config[varname] = value
    324                
     324
    325325                ok = random_choices(config, rules, start_index + 1)
    326326                if ok:
    327327                        return True
    328                
     328
    329329                try_counter = try_counter + 1
    330        
     330
    331331        # Restore the old value and backtrack
    332332        # (need to delete to prevent "ghost" variables that do not exist under
     
    335335        if old_value is None:
    336336                del config[varname]
    337        
     337
    338338        return random_choices(config, rules, start_index + 1)
    339        
     339
    340340
    341341## Get default value from a rule.
    342342def get_default_rule(rule):
    343343        varname, vartype, name, choices, cond = rule
    344        
     344
    345345        default = None
    346        
     346
    347347        if vartype == 'choice':
    348348                # If there is just one option, use it
     
    359359        else:
    360360                raise RuntimeError("Unknown variable type: %s" % vartype)
    361        
     361
    362362        return default
    363363
     
    371371def get_rule_option(rule, value):
    372372        varname, vartype, name, choices, cond = rule
    373        
     373
    374374        option = None
    375        
     375
    376376        if vartype == 'choice':
    377377                # If there is just one option, don't ask
     
    391391        else:
    392392                raise RuntimeError("Unknown variable type: %s" % vartype)
    393        
     393
    394394        return option
    395395
     
    403403def validate_rule_value(rule, value):
    404404        varname, vartype, name, choices, cond = rule
    405        
     405
    406406        if value == None:
    407407                return True
    408        
     408
    409409        if vartype == 'choice':
    410410                if not value in [choice[0] for choice in choices]:
     
    424424        else:
    425425                raise RuntimeError("Unknown variable type: %s" % vartype)
    426        
     426
    427427        return True
    428428
    429429def preprocess_config(config, rules):
    430430        "Preprocess configuration"
    431        
     431
    432432        varname_mode = 'CONFIG_BFB_MODE'
    433433        varname_width = 'CONFIG_BFB_WIDTH'
    434434        varname_height = 'CONFIG_BFB_HEIGHT'
    435        
     435
    436436        if varname_mode in config:
    437437                mode = config[varname_mode].partition('x')
    438                
     438
    439439                config[varname_width] = mode[0]
    440440                rules.append((varname_width, 'choice', 'Default framebuffer width', None, None))
    441                
     441
    442442                config[varname_height] = mode[2]
    443443                rules.append((varname_height, 'choice', 'Default framebuffer height', None, None))
     
    445445def create_output(mkname, mcname, config, rules):
    446446        "Create output configuration"
    447        
     447
    448448        varname_strip = 'CONFIG_STRIP_REVISION_INFO'
    449449        strip_rev_info = (varname_strip in config) and (config[varname_strip] == 'y')
    450        
     450
    451451        if strip_rev_info:
    452452                timestamp_unix = int(0)
     
    454454                # TODO: Use commit timestamp instead of build time.
    455455                timestamp_unix = int(time.time())
    456        
     456
    457457        timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(timestamp_unix))
    458        
     458
    459459        sys.stderr.write("Fetching current revision identifier ... ")
    460        
     460
    461461        try:
    462462                version = subprocess.Popen(['git', 'log', '-1', '--pretty=%h'], stdout = subprocess.PIPE).communicate()[0].decode().strip()
     
    465465                version = None
    466466                sys.stderr.write("failed\n")
    467        
     467
    468468        if (not strip_rev_info) and (version is not None):
    469469                revision = version
    470470        else:
    471471                revision = None
    472        
     472
    473473        outmk = open(mkname, 'w')
    474474        outmc = open(mcname, 'w')
    475        
     475
    476476        outmk.write('#########################################\n')
    477477        outmk.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
    478478        outmk.write('## Generated by: tools/config.py       ##\n')
    479479        outmk.write('#########################################\n\n')
    480        
     480
    481481        outmc.write('/***************************************\n')
    482482        outmc.write(' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n')
    483483        outmc.write(' * Generated by: tools/config.py       *\n')
    484484        outmc.write(' ***************************************/\n\n')
    485        
     485
    486486        defs = 'CONFIG_DEFS ='
    487        
     487
    488488        for varname, vartype, name, choices, cond in rules:
    489489                if cond and (not check_condition(cond, config, rules)):
    490490                        continue
    491                
     491
    492492                if not varname in config:
    493493                        value = ''
     
    496496                        if (value == '*'):
    497497                                value = 'y'
    498                
     498
    499499                outmk.write('# %s\n%s = %s\n\n' % (name, varname, value))
    500                
     500
    501501                if vartype in ["y", "n", "y/n", "n/y"]:
    502502                        if value == "y":
     
    506506                        outmc.write('/* %s */\n#define %s %s\n#define %s_%s\n\n' % (name, varname, value, varname, value))
    507507                        defs += ' -D%s=%s -D%s_%s' % (varname, value, varname, value)
    508        
     508
    509509        if revision is not None:
    510510                outmk.write('REVISION = %s\n' % revision)
    511511                outmc.write('#define REVISION %s\n' % revision)
    512512                defs += ' "-DREVISION=%s"' % revision
    513        
     513
    514514        outmk.write('TIMESTAMP_UNIX = %d\n' % timestamp_unix)
    515515        outmc.write('#define TIMESTAMP_UNIX %d\n' % timestamp_unix)
    516516        defs += ' "-DTIMESTAMP_UNIX=%d"\n' % timestamp_unix
    517        
     517
    518518        outmk.write('TIMESTAMP = %s\n' % timestamp)
    519519        outmc.write('#define TIMESTAMP %s\n' % timestamp)
    520520        defs += ' "-DTIMESTAMP=%s"\n' % timestamp
    521        
     521
    522522        outmk.write(defs)
    523        
     523
    524524        outmk.close()
    525525        outmc.close()
     
    536536        opt2path = {}
    537537        cnt = 0
    538        
     538
    539539        # Look for profiles
    540540        for name in sorted_dir(root):
    541541                path = os.path.join(root, name)
    542542                canon = os.path.join(path, fname)
    543                
     543
    544544                if os.path.isdir(path) and os.path.exists(canon) and os.path.isfile(canon):
    545545                        subprofile = False
    546                        
     546
    547547                        # Look for subprofiles
    548548                        for subname in sorted_dir(path):
    549549                                subpath = os.path.join(path, subname)
    550550                                subcanon = os.path.join(subpath, fname)
    551                                
     551
    552552                                if os.path.isdir(subpath) and os.path.exists(subcanon) and os.path.isfile(subcanon):
    553553                                        subprofile = True
     
    555555                                        opt2path[cnt] = [name, subname]
    556556                                        cnt += 1
    557                        
     557
    558558                        if not subprofile:
    559559                                options.append(name)
    560560                                opt2path[cnt] = [name]
    561561                                cnt += 1
    562        
     562
    563563        (button, value) = xtui.choice_window(screen, 'Load preconfigured defaults', 'Choose configuration profile', options, None)
    564        
     564
    565565        if button == 'cancel':
    566566                return None
    567        
     567
    568568        return opt2path[value]
    569569
     
    576576        path = os.path.join(PRESETS_DIR, profile[0], MAKEFILE)
    577577        read_config(path, config)
    578        
     578
    579579        if len(profile) > 1:
    580580                path = os.path.join(PRESETS_DIR, profile[0], profile[1], MAKEFILE)
     
    588588def parse_profile_name(profile_name):
    589589        profile = []
    590        
     590
    591591        head, tail = os.path.split(profile_name)
    592592        if head != '':
    593593                profile.append(head)
    594        
     594
    595595        profile.append(tail)
    596596        return profile
     
    600600        config = {}
    601601        rules = []
    602        
     602
    603603        # Parse rules file
    604604        parse_rules(RULES_FILE, rules)
    605        
     605
    606606        # Input configuration file can be specified on command line
    607607        # otherwise configuration from previous run is used.
     
    611611        elif os.path.exists(MAKEFILE):
    612612                read_config(MAKEFILE, config)
    613        
     613
    614614        # Default mode: check values and regenerate configuration files
    615615        if (len(sys.argv) >= 3) and (sys.argv[2] == 'default'):
     
    618618                        create_output(MAKEFILE, MACROS, config, rules)
    619619                        return 0
    620        
     620
    621621        # Hands-off mode: check values and regenerate configuration files,
    622622        # but no interactive fallback
     
    627627                        sys.stderr.write("Configuration error: No presets specified\n")
    628628                        return 2
    629                
     629
    630630                if (infer_verify_choices(config, rules)):
    631631                        preprocess_config(config, rules)
    632632                        create_output(MAKEFILE, MACROS, config, rules)
    633633                        return 0
    634                
     634
    635635                sys.stderr.write("Configuration error: The presets are ambiguous\n")
    636636                return 1
    637        
     637
    638638        # Check mode: only check configuration
    639639        if (len(sys.argv) >= 3) and (sys.argv[2] == 'check'):
     
    641641                        return 0
    642642                return 1
    643        
     643
    644644        # Random mode
    645645        if (len(sys.argv) == 3) and (sys.argv[2] == 'random'):
     
    653653                preprocess_config(config, rules)
    654654                create_output(MAKEFILE, MACROS, config, rules)
    655                
     655
    656656                return 0
    657        
     657
    658658        screen = xtui.screen_init()
    659659        try:
     
    661661                position = None
    662662                while True:
    663                        
     663
    664664                        # Cancel out all values which have to be deduced
    665665                        for varname, vartype, name, choices, cond in rules:
    666666                                if (vartype == 'y') and (varname in config) and (config[varname] == '*'):
    667667                                        config[varname] = None
    668                        
     668
    669669                        options = []
    670670                        opt2row = {}
    671671                        cnt = 1
    672                        
     672
    673673                        options.append("  --- Load preconfigured defaults ... ")
    674                        
     674
    675675                        for rule in rules:
    676676                                varname, vartype, name, choices, cond = rule
    677                                
     677
    678678                                if cond and (not check_condition(cond, config, rules)):
    679679                                        continue
    680                                
     680
    681681                                if varname == selname:
    682682                                        position = cnt
    683                                
     683
    684684                                if not varname in config:
    685685                                        value = None
    686686                                else:
    687687                                        value = config[varname]
    688                                
     688
    689689                                if not validate_rule_value(rule, value):
    690690                                        value = None
    691                                
     691
    692692                                default = get_default_rule(rule)
    693                                
     693
    694694                                #
    695695                                # If we don't have a value but we do have
     
    699699                                        value = default
    700700                                        config[varname] = default
    701                                
     701
    702702                                option = get_rule_option(rule, value)
    703703                                if option != None:
     
    705705                                else:
    706706                                        continue
    707                                
     707
    708708                                opt2row[cnt] = (varname, vartype, name, choices)
    709                                
     709
    710710                                cnt += 1
    711                        
     711
    712712                        if (position != None) and (position >= len(options)):
    713713                                position = None
    714                        
     714
    715715                        (button, value) = xtui.choice_window(screen, 'HelenOS configuration', 'Choose configuration option', options, position)
    716                        
     716
    717717                        if button == 'cancel':
    718718                                return 'Configuration canceled'
    719                        
     719
    720720                        if button == 'done':
    721721                                if (infer_verify_choices(config, rules)):
     
    724724                                        xtui.error_dialog(screen, 'Error', 'Some options have still undefined values. These options are marked with the "?" sign.')
    725725                                        continue
    726                        
     726
    727727                        if value == 0:
    728728                                profile = choose_profile(PRESETS_DIR, MAKEFILE, screen, config)
     
    731731                                position = 1
    732732                                continue
    733                        
     733
    734734                        position = None
    735735                        if not value in opt2row:
    736736                                raise RuntimeError("Error selecting value: %s" % value)
    737                        
     737
    738738                        (selname, seltype, name, choices) = opt2row[value]
    739                        
     739
    740740                        if not selname in config:
    741741                                value = None
    742742                        else:
    743743                                value = config[selname]
    744                        
     744
    745745                        if seltype == 'choice':
    746746                                config[selname] = subchoice(screen, name, choices, value)
     
    752752        finally:
    753753                xtui.screen_done(screen)
    754        
     754
    755755        preprocess_config(config, rules)
    756756        create_output(MAKEFILE, MACROS, config, rules)
Note: See TracChangeset for help on using the changeset viewer.