Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 56 additions & 74 deletions configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,21 @@

import collections
import copy
import errno
import json
import sys
import logging
import optparse # pylint: disable=deprecated-module
import os
import os.path
import platform
import re
import shlex
import shutil
import subprocess
import traceback
import logging
import sys
import time
import errno
import optparse # pylint: disable=deprecated-module
import traceback


# An error caused by and to be fixed by the user, e.g. invalid command line argument
class UserError(Exception):
Expand All @@ -42,7 +43,7 @@ class InternalError(Exception):


def flatten(lst):
return sum(lst, [])
return [elem for sub in lst for elem in sub]

def normalize_source_path(source):
"""
Expand Down Expand Up @@ -73,7 +74,7 @@ def parse_version_file(version_path):
key_and_val = re.compile(r"([a-z_]+) = ([a-zA-Z0-9:\-\']+)")

results = {}
for line in version_file.readlines():
for line in version_file:
if not line or line[0] == '#':
continue
match = key_and_val.match(line)
Expand All @@ -95,7 +96,7 @@ class Version:
"""
Version information are all static members
"""
data = {}
data = {} # noqa: RUF012

@staticmethod
def get_data():
Expand Down Expand Up @@ -769,7 +770,7 @@ def parse_lex_dict(as_list, map_name, infofile):
raise InternalError("Lex dictionary has invalid format (input not divisible by 3): %s" % as_list)

result = {}
for key, sep, value in [as_list[3*i:3*i+3] for i in range(0, len(as_list)//3)]:
for key, sep, value in [as_list[3*i:3*i+3] for i in range(len(as_list)//3)]:
if sep != '->':
raise InternalError("Map %s in %s has invalid format" % (map_name, infofile))
if key in result:
Expand Down Expand Up @@ -825,7 +826,7 @@ def lexed_tokens(): # Convert to an iterator
raise LexerError('Group "%s" not terminated' % (group),
infofile, lexer.lineno)

elif token in name_val_pairs.keys():
elif token in name_val_pairs:
if isinstance(out.__dict__[token], list):
out.__dict__[token].append(lexer.get_token())
else:
Expand Down Expand Up @@ -1020,9 +1021,7 @@ def known_isa(isa):
return True

compound_isa = isa.split(':')
if len(compound_isa) == 2 and compound_isa[0] in arch_info and compound_isa[1] in all_isa_extn:
return True
return False
return len(compound_isa) == 2 and compound_isa[0] in arch_info and compound_isa[1] in all_isa_extn

for isa in self.isa:
if not known_isa(isa):
Expand Down Expand Up @@ -1074,11 +1073,7 @@ def compatible_cpu(self, archinfo, options):
if isa not in archinfo.isa_extensions:
return False

if self.arch != []:
if arch_name not in self.arch and cpu_name not in self.arch:
return False

return True
return self.arch == [] or arch_name in self.arch or cpu_name in self.arch

def compatible_os(self, os_data, options):
if not self.os_features:
Expand Down Expand Up @@ -1186,10 +1181,7 @@ def is_dependency_on_virtual(this_module, dependency):
if not dependency.is_virtual():
return False

if this_module.parent_module == dependency.basename:
return False

return True
return this_module.parent_module != dependency.basename

missing = [s for s in self.dependencies(None, None) if s not in modules or is_dependency_on_virtual(self, modules[s])]

Expand Down Expand Up @@ -1273,9 +1265,9 @@ def supported_isa_extensions(self, cc, options):
isas = []

for isa in self.isa_extensions:
if (isa, self.basename) not in options.disable_intrinsics:
if cc.isa_flags_for(isa, self.basename) is not None:
isas.append(isa)
if (isa, self.basename) not in options.disable_intrinsics and \
cc.isa_flags_for(isa, self.basename) is not None:
isas.append(isa)

return sorted(isas)

Expand Down Expand Up @@ -1477,7 +1469,7 @@ def mach_abi_groups():
else:
yield 'rt'

for all_except in [s for s in self.mach_abi_linking.keys() if s.startswith('all!')]:
for all_except in [s for s in self.mach_abi_linking if s.startswith('all!')]:
exceptions = all_except[4:].split(',')
if options.os not in exceptions and options.arch not in exceptions:
yield all_except
Expand Down Expand Up @@ -1582,10 +1574,9 @@ def cc_compile_flags(self, options):
if options.arch in self.cpu_flags:
yield self.cpu_flags[options.arch]

if options.arch in self.cpu_flags_no_debug:
# Only enable these if no debug/sanitizer options enabled
if not (options.debug_mode or sanitizers_enabled):
yield self.cpu_flags_no_debug[options.arch]
# Only enable these if no debug/sanitizer options enabled
if options.arch in self.cpu_flags_no_debug and not (options.debug_mode or sanitizers_enabled):
yield self.cpu_flags_no_debug[options.arch]

yield from options.extra_cxxflags

Expand Down Expand Up @@ -1737,12 +1728,12 @@ def enabled_features(self, options):
return sorted(feats)

def enabled_features_public(self, options):
public_feat = set(['threads', 'filesystem'])
return sorted(list(set(self.enabled_features(options)) & public_feat))
public_feat = {'threads', 'filesystem'}
return sorted(set(self.enabled_features(options)) & public_feat)

def enabled_features_internal(self, options):
public_feat = set(['threads', 'filesystem'])
return sorted(list(set(self.enabled_features(options)) - public_feat))
public_feat = {'threads', 'filesystem'}
return sorted(set(self.enabled_features(options)) - public_feat)

def macros(self, cc):
value = [cc.add_compile_definition_option + define
Expand Down Expand Up @@ -1872,12 +1863,10 @@ def insert_join(match):
cond_type = cond_match.group(1)
cond_var = cond_match.group(2)

include_cond = False

if cond_type == 'if' and cond_var in self.vals and self.vals.get(cond_var):
include_cond = True
elif cond_type == 'unless' and (cond_var not in self.vals or (not self.vals.get(cond_var))):
include_cond = True
if cond_type == 'if':
include_cond = bool(self.vals.get(cond_var))
else: # unless
include_cond = not self.vals.get(cond_var)

idx += 1
while idx < len(lines):
Expand Down Expand Up @@ -1949,6 +1938,16 @@ def process_template(template_file, variables):
def yield_objectfile_list(sources, obj_dir, obj_suffix, options):
obj_suffix = '.' + obj_suffix

def fixup_obj_name(name):
def remove_dups(parts):
last = None
for part in parts:
if last is None or part != last:
last = part
yield part

return '_'.join(remove_dups(name.split('_')))

for src in sources:
(directory, filename) = os.path.split(os.path.normpath(src))
parts_in_src = directory.split('src' + os.sep)
Expand All @@ -1966,16 +1965,6 @@ def yield_objectfile_list(sources, obj_dir, obj_suffix, options):
else:
name = '_'.join(parts) + '_' + filename

def fixup_obj_name(name):
def remove_dups(parts):
last = None
for part in parts:
if last is None or part != last:
last = part
yield part

return '_'.join(remove_dups(name.split('_')))

name = fixup_obj_name(name)
else:
name = filename
Expand Down Expand Up @@ -2643,7 +2632,7 @@ def resolve_dependencies(available_modules, dependency_table, module, loaded_mod
- loaded_modules: modules already loaded. Defensive copy in order to not change value for caller.
"""
if loaded_modules is None:
loaded_modules = set([])
loaded_modules = set()
else:
loaded_modules = copy.copy(loaded_modules)

Expand Down Expand Up @@ -2740,13 +2729,12 @@ def choose(self):
else:
self._handle_by_load_on(module)

if 'compression' in self._to_load:
# Confirm that we have at least one compression library enabled
# Otherwise we leave a lot of useless support code compiled in, plus a
# make_compressor call that always fails
if 'zlib' not in self._to_load and 'bzip2' not in self._to_load and 'lzma' not in self._to_load:
self._to_load.remove('compression')
self._not_using_because['no enabled compression schemes'].add('compression')
# Confirm that we have at least one compression library enabled
# Otherwise we leave a lot of useless support code compiled in, plus a
# make_compressor call that always fails
if 'compression' in self._to_load and not self._to_load & {'zlib', 'bzip2', 'lzma'}:
self._to_load.remove('compression')
self._not_using_because['no enabled compression schemes'].add('compression')

# The AVX2 implementation of Argon2 fails when compiled by GCC in
# amalgamation mode.
Expand Down Expand Up @@ -2882,7 +2870,7 @@ def __init__(self, input_filepaths):
try:
contents = AmalgamationGenerator.read_header(filepath)
self.file_contents[os.path.basename(filepath)] = contents
except IOError as ex:
except OSError as ex:
logging.error('Error processing file %s for amalgamation: %s', filepath, ex)

self.contents = ''
Expand Down Expand Up @@ -2982,10 +2970,7 @@ def generate(self):
logging.info('Writing amalgamation header to %s', amalgamation_header_fsname)
pub_header_amalag.write_to_file(amalgamation_header_fsname, "BOTAN_AMALGAMATION_H_")

internal_headers_list = []

for hdr in self._build_paths.internal_headers:
internal_headers_list.append(hdr)
internal_headers_list = list(self._build_paths.internal_headers)

# file descriptors for all `amalgamation_sources`
amalgamation_fsname = '%s.cpp' % (self._filename_prefix)
Expand All @@ -3000,7 +2985,7 @@ def generate(self):
amalgamation_file.write(internal_headers.header_includes)
amalgamation_file.write(internal_headers.contents)

unconditional_headers = set([])
unconditional_headers = set()

for mod in sorted(self._modules, key=lambda module: module.basename):
for src in sorted(mod.source):
Expand Down Expand Up @@ -3298,9 +3283,8 @@ def canonicalize_build_targets(options):
if options.os == 'windows' and options.build_shared_lib is None and options.build_static_lib is None:
options.build_shared_lib = True

if options.with_stack_protector is None:
if options.os in info_os:
options.with_stack_protector = info_os[options.os].use_stack_protector
if options.with_stack_protector is None and options.os in info_os:
options.with_stack_protector = info_os[options.os].use_stack_protector

if options.build_shared_lib is None:
if options.os == 'windows' and options.build_static_lib:
Expand Down Expand Up @@ -3408,9 +3392,8 @@ def validate_options(options, info_os, info_cc, available_module_policies):
if options.with_texinfo and not options.with_sphinx:
raise UserError('Option --with-texinfo requires --with-sphinx')

if options.ct_value_barrier_type:
if options.ct_value_barrier_type not in ['asm', 'volatile', 'none']:
raise UserError('Unknown setting "%s" for --ct-value-barrier-type' % (options.ct_value_barrier_type))
if options.ct_value_barrier_type and options.ct_value_barrier_type not in ['asm', 'volatile', 'none']:
raise UserError('Unknown setting "%s" for --ct-value-barrier-type' % (options.ct_value_barrier_type))

# Warnings
if options.os == 'windows' and options.compiler not in ('msvc', 'clangcl'):
Expand Down Expand Up @@ -3662,8 +3645,7 @@ def escape_build_lines(contents):
with open(rst2man_file, 'w', encoding='utf8') as f:
f.write(rst2man_header)
f.write("\n")
for line in cli_doc_contents:
f.write(line)
f.writelines(cli_doc_contents)

date = 'dated %d' % (Version.datestamp()) if Version.datestamp() != 0 else 'undated'

Expand All @@ -3682,8 +3664,8 @@ def escape_build_lines(contents):

def list_os_features(all_os_features, info_os):
for feat in all_os_features:
os_with_feat = [o for o in info_os.keys() if feat in info_os[o].target_features]
os_without_feat = [o for o in info_os.keys() if feat not in info_os[o].target_features]
os_with_feat = [o for o in info_os if feat in info_os[o].target_features]
os_without_feat = [o for o in info_os if feat not in info_os[o].target_features]

if len(os_with_feat) < len(os_without_feat):
print("%s: %s" % (feat, ' '.join(sorted(os_with_feat))))
Expand Down
11 changes: 11 additions & 0 deletions src/configs/ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
target-version = "py38"

[lint]
ignore = [
"BLE001", # catching Exception in a script's top level error handler is fine
"DTZ", # datetimes are fine in build/dev scripts
"LOG015", # standalone scripts use the root logger on purpose
"SIM115", # not worth rewriting every open() into a with block
"TRY002", # raising plain Exception is fine for standalone scripts
"UP031", # printf-style formatting is fine
]
15 changes: 7 additions & 8 deletions src/configs/sphinx/conf.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# -* coding: utf-8 -*-
# Sphinx configuration file

import sys
import re
import sys

#import sphinx

Expand All @@ -21,7 +20,7 @@ def parse_version_file(version_path):
key_and_val = re.compile(r"([a-z_]+) = ([a-zA-Z0-9:\-\']+)")

results = {}
for line in version_file.readlines():
for line in version_file:
if not line or line[0] == '#':
continue
match = key_and_val.match(line)
Expand Down Expand Up @@ -58,8 +57,8 @@ def parse_version_file(version_path):

master_doc = 'contents'

project = u'botan'
copyright = u'2000-2023, The Botan Authors'
project = 'botan'
copyright = '2000-2023, The Botan Authors'

version = '%d.%d' % (version_major, version_minor)
release = '%d.%d.%d%s' % (version_major, version_minor, version_patch, version_suffix)
Expand Down Expand Up @@ -101,7 +100,7 @@ def parse_version_file(version_path):

try:
# On Arch this is python-sphinx-furo
import furo # noqa: F401
import furo # noqa: F401
html_theme = "furo"

# Add a small edit button to each document to allow visitors to easily
Expand Down Expand Up @@ -195,9 +194,9 @@ def parse_version_file(version_path):
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).

authors = u'The Botan Authors'
authors = 'The Botan Authors'
latex_documents = [
('contents', 'botan.tex', u'Botan Reference Guide', authors, 'manual'),
('contents', 'botan.tex', 'Botan Reference Guide', authors, 'manual'),
]

# The name of an image file (relative to this directory) to place at the top of
Expand Down
8 changes: 5 additions & 3 deletions src/ct_selftest/ct_selftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@

Botan is released under the Simplified BSD License (see license.txt)
"""
from __future__ import annotations

import subprocess
import argparse
import json
import os
import subprocess
import sys
from typing import Self
from enum import StrEnum, auto
import json
from typing import Self


def run_command(cmd: list[str], is_text = True):
""" Run the command . """
Expand Down
Loading
Loading