Updating autogen script
This commit is contained in:
1 parent
feaac16804
commit
a1e0a4edbb
11 files changed
+161
-141
No files matched your search
+1
-1
@@ -17,6 +17,6 @@ script:
|
||||
- export CC=gcc-9
|
||||
- gcc --version
|
||||
- python --version
|
||||
- make
|
||||
- python autogen.py -e -b -cv -r
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
+112
-92
@@ -3,6 +3,7 @@
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import pathlib
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
@@ -39,7 +40,7 @@ INCLUDE_DIR = f"{OUTPUT_DIR}/{DIR_MAP['HEADER']}"
|
||||
# const
|
||||
SRC_DIR = f"{OUTPUT_DIR}/{DIR_MAP['SOURCE']}"
|
||||
# Where object files .o go
|
||||
OBJ_DIR = f'{BUILD_DIR}/obj'
|
||||
OBJ_DIR = BUILD_DIR
|
||||
# The name of the main test executable
|
||||
TEST_EXE = f'{OUTPUT_DIR}/main.exe'
|
||||
|
||||
@@ -53,10 +54,10 @@ CFLAGS = ['-Wall', '-Werror']
|
||||
CVFLAGS = ['--coverage', '-O0']
|
||||
# Include to the main Library
|
||||
# const
|
||||
INCLUDE = '-I ./src'
|
||||
INCLUDE = ['-I', './src']
|
||||
# Include to the test file headers
|
||||
# const
|
||||
TINCLUDE = f'-I {INCLUDE_DIR}'
|
||||
TINCLUDE = ['-I', f'{INCLUDE_DIR}']
|
||||
|
||||
# Macro expansion
|
||||
|
||||
@@ -115,25 +116,36 @@ COLLECTIONS = [
|
||||
]
|
||||
|
||||
|
||||
def full_path(path: Text) -> Text:
|
||||
'''
|
||||
Returns the full path of a 'path' with ralative paths, e.g. './' or '../'
|
||||
'''
|
||||
return str(pathlib.Path(path).resolve())
|
||||
|
||||
|
||||
def execute_command(commands: List[Text]):
|
||||
print(' '.join(commands))
|
||||
subprocess.run(commands, shell=True)
|
||||
cp = subprocess.run(commands, shell=True)
|
||||
|
||||
# if cp.returncode != 0:
|
||||
# print('Error when executing the last command')
|
||||
# exit(1)
|
||||
|
||||
|
||||
def assert_executable(program: Text):
|
||||
'''
|
||||
Asserts that a given program is installed and available in PATH
|
||||
Asserts that a given program is installed and available in PATH.
|
||||
'''
|
||||
if shutil.which(program) is None:
|
||||
raise Exception(f'The required executable {program} was not found in your path')
|
||||
|
||||
|
||||
def assert_dir(dir: Text):
|
||||
def assert_dir(directory: Text):
|
||||
'''
|
||||
Given a string 'dir' that is a path to a directory, make sure that it exists.
|
||||
Given a string 'directory' that is a path to a directory, make sure that it exists.
|
||||
'''
|
||||
if not os.path.exists(dir):
|
||||
os.makedirs(dir)
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
|
||||
|
||||
def assert_structure():
|
||||
@@ -143,13 +155,13 @@ def assert_structure():
|
||||
assert_dir(OUTPUT_DIR)
|
||||
|
||||
# include and src
|
||||
for dir in DIR_MAP.values():
|
||||
assert_dir(f'{OUTPUT_DIR}/{dir}')
|
||||
for directory in DIR_MAP.values():
|
||||
assert_dir(f'{OUTPUT_DIR}/{directory}')
|
||||
|
||||
# For each library, create a directory for include and src
|
||||
for lib in ALL_LIBS:
|
||||
for dir in DIR_MAP.values():
|
||||
assert_dir(f'{OUTPUT_DIR}/{dir}/{lib.lower()}')
|
||||
for directory in DIR_MAP.values():
|
||||
assert_dir(f'{OUTPUT_DIR}/{directory}/{lib.lower()}')
|
||||
|
||||
assert_dir(BUILD_DIR)
|
||||
assert_dir(OBJ_DIR)
|
||||
@@ -158,12 +170,21 @@ def assert_structure():
|
||||
assert_dir(f'{OBJ_DIR}/{lib.lower()}')
|
||||
|
||||
|
||||
def clean_build():
|
||||
execute_command(['find', BUILD_DIR, '-type', 'f', '-delete'])
|
||||
execute_command(['find', '.', '-iname', '*.gcov', '-type', 'f', '-delete'])
|
||||
def clean_build(cleanfull: bool):
|
||||
'''
|
||||
Removes all files generated by compilation and code coverage along with folders.
|
||||
'''
|
||||
execute_command(['rm', '-r', '*.gcov'])
|
||||
execute_command(['rm', TEST_EXE])
|
||||
|
||||
for directory in [BUILD_DIR, SRC_DIR, INCLUDE_DIR]:
|
||||
execute_command(['rm', '-r', directory])
|
||||
|
||||
|
||||
def expand_code():
|
||||
'''
|
||||
Expands code to be used in tests. This is necessary because code coverage doesn't work with macros.
|
||||
'''
|
||||
# Generate Header and Source separately
|
||||
for ftype in ['HEADER', 'SOURCE']:
|
||||
for data in COLLECTIONS:
|
||||
@@ -183,7 +204,7 @@ def expand_code():
|
||||
file.flush()
|
||||
file.close()
|
||||
|
||||
result = subprocess.getoutput(f'{CC} {EXPAND_FLAGS} {INCLUDE} {TMP_FILE}')
|
||||
result = subprocess.getoutput(f'{CC} {EXPAND_FLAGS} {" ".join(INCLUDE)} {TMP_FILE}')
|
||||
|
||||
# (?s) makes '.' match anything, even '\n'
|
||||
match = re.search(fr'(?s){UNIQUE_FLAG}(?P<code>.+){UNIQUE_FLAG}', result)
|
||||
@@ -223,6 +244,9 @@ def expand_code():
|
||||
|
||||
|
||||
def format_expand():
|
||||
'''
|
||||
Format the files outputted by 'expand_code'.
|
||||
'''
|
||||
cmd = ['clang-format', '--style=file', '--verbose', '-i']
|
||||
dirs_to_format = [f'{OUTPUT_DIR}/{DIR_MAP[ftype]}/{lib.lower()}/*.{EXT_MAP[ftype]}' for ftype in DIR_MAP.keys() for lib in ALL_LIBS]
|
||||
cmd.extend(dirs_to_format)
|
||||
@@ -230,79 +254,63 @@ def format_expand():
|
||||
|
||||
|
||||
def format_code(source: bool, tests: bool):
|
||||
'''
|
||||
Format all source files from the main library or test files.
|
||||
'''
|
||||
if source:
|
||||
execute_command(['find', './src/', '-iname', '*.h', '|', 'xargs', 'clang-format', '--style=file', '--verbose', '-i'])
|
||||
execute_command(['find', './src/', '-name', '*.h', '|', 'xargs', 'clang-format', '--style=file', '--verbose', '-i'])
|
||||
if tests:
|
||||
execute_command(['find', './tests/', '-iname', '*.c', '-o', '-iname', '*.h', '|', 'xargs', 'clang-format', '--style=file', '--verbose', '-i'])
|
||||
execute_command(['find', './tests/', '-name', '*.c', '-o', '-name', '*.h', '|', 'xargs', 'clang-format', '--style=file', '--verbose', '-i'])
|
||||
|
||||
|
||||
def build_tests(with_coverage: bool):
|
||||
'''
|
||||
Build all object files and the main executable for tests
|
||||
'''
|
||||
cflags = CFLAGS.copy()
|
||||
|
||||
if with_coverage:
|
||||
cflags += CVFLAGS
|
||||
|
||||
print("WIP")
|
||||
|
||||
|
||||
def run_tests():
|
||||
execute_command([TEST_EXE])
|
||||
|
||||
|
||||
def unused():
|
||||
# Makefile
|
||||
# Contains many usefull things dealing with tests, code coverage and formatting
|
||||
|
||||
print('Updating Makefile...')
|
||||
|
||||
file = open(f'Makefile', 'w')
|
||||
|
||||
file.write(f'''# This file was generated by a Python script
|
||||
CC = {CC}
|
||||
CFLAGS = -std=c11 -Wall -Wextra
|
||||
CFLAGS += -Wno-missing-braces -DCMC_TEST_COLOR
|
||||
CVFLAGS = --coverage -O0 -g3
|
||||
INCLUDE = {INCLUDE_DIR} -I src
|
||||
|
||||
# Runs the script to update tests, run all tests and code coverage
|
||||
all: script coverage
|
||||
|
||||
tests: script build
|
||||
\t{OUTPUT_DIR}/main.exe
|
||||
|
||||
# Like build but with coverage
|
||||
coverage: {' '.join([f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in COLLECTIONS])} {OBJ_DIR}/main.o
|
||||
\t$(CC) $^ -o {OUTPUT_DIR}/main.exe $(CFLAGS) $(CVFLAGS)
|
||||
\t{OUTPUT_DIR}/main.exe
|
||||
\tgcov {OBJ_DIR}/main.o {' '.join([f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in COLLECTIONS])}
|
||||
|
||||
# Run without coverage
|
||||
run: build
|
||||
\t{OUTPUT_DIR}/main.exe
|
||||
|
||||
script:
|
||||
\tpython autogen.py
|
||||
|
||||
clean:
|
||||
\tfind {BUILD_DIR} -type f -delete
|
||||
\trm *.gcov
|
||||
|
||||
# No coverage build
|
||||
build: {' '.join([f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in COLLECTIONS])} {OBJ_DIR}/main.o
|
||||
\t$(CC) $^ -o {OUTPUT_DIR}/main.exe $(CFLAGS)
|
||||
|
||||
{OBJ_DIR}/main.o: {OUTPUT_DIR}/main.c
|
||||
\t$(CC) -c $^ -o $@ -I $(INCLUDE) $(CFLAGS)
|
||||
''')
|
||||
else:
|
||||
cflags += ['-O3']
|
||||
|
||||
for data in COLLECTIONS:
|
||||
file.write(f'''
|
||||
{OBJ_DIR}/{data['LIB'].lower()}/{data['SNAME']}.o: {SRC_DIR}/{data['LIB'].lower()}/{data['SNAME']}.c {INCLUDE_DIR}/{data['LIB'].lower()}/{data['SNAME']}.h
|
||||
\t$(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS)
|
||||
''')
|
||||
cmd = [CC]
|
||||
cmd += cflags
|
||||
cmd += TINCLUDE # This one needs to go first
|
||||
cmd += INCLUDE
|
||||
cmd += ['-c', f"{SRC_DIR}/{data['LIB'].lower()}/{data['SNAME']}.c"]
|
||||
cmd += ['-o', f"{OBJ_DIR}/{data['LIB'].lower()}/{data['SNAME']}.o"]
|
||||
execute_command(cmd)
|
||||
|
||||
file.close()
|
||||
print('\nDone')
|
||||
# Build OUTPUT_DIR/main.c
|
||||
cmd = [CC]
|
||||
cmd += cflags
|
||||
cmd += TINCLUDE # This one needs to go first
|
||||
cmd += INCLUDE
|
||||
cmd += ['-c', f'{OUTPUT_DIR}/main.c']
|
||||
cmd += ['-o', f"{OBJ_DIR}/main.o"]
|
||||
execute_command(cmd)
|
||||
|
||||
# Link everything producing OUTPUT_DIR/main.exe
|
||||
cmd = [CC]
|
||||
cmd += cflags
|
||||
cmd += ['-o', TEST_EXE]
|
||||
cmd += [f'{OBJ_DIR}/main.o']
|
||||
cmd += [f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in COLLECTIONS]
|
||||
execute_command(cmd)
|
||||
|
||||
|
||||
def run_tests(coverage: bool):
|
||||
'''
|
||||
Runs tests. If coverage, run gcov.
|
||||
'''
|
||||
execute_command([full_path(TEST_EXE)])
|
||||
|
||||
if coverage:
|
||||
objects = [f'{OBJ_DIR}/main.o']
|
||||
objects += [f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in COLLECTIONS]
|
||||
execute_command(['gcov'] + objects)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
@@ -320,6 +328,11 @@ if __name__ == '__main__':
|
||||
default=False,
|
||||
action='store_true',
|
||||
dest='clean')
|
||||
tests.add_argument('-cf', '--clean-full',
|
||||
help='Cleans all build objects, source and header files, and removes folders',
|
||||
default=False,
|
||||
action='store_true',
|
||||
dest='cleanfull')
|
||||
tests.add_argument('-e', '--expand',
|
||||
help='Expands the header and source files',
|
||||
default=False,
|
||||
@@ -330,18 +343,23 @@ if __name__ == '__main__':
|
||||
default=False,
|
||||
action='store_true',
|
||||
dest='noformat')
|
||||
tests.add_argument('-b', '--build',
|
||||
help='Compile the object files and the main executable',
|
||||
default=False,
|
||||
action='store_true',
|
||||
dest='build')
|
||||
tests.add_argument('-r', '--run',
|
||||
help='Runs tests without code coverage',
|
||||
help='Runs tests, assuming that it is already built',
|
||||
default=False,
|
||||
action='store_true',
|
||||
dest='run')
|
||||
tests.add_argument('-cv', '--coverage',
|
||||
help='Compiles and runs tests with code coverage',
|
||||
help='Adds the code coverage flags for compilation',
|
||||
default=False,
|
||||
action='store_true',
|
||||
dest='coverage')
|
||||
tests.add_argument('-rr', '--rerun',
|
||||
help='Builds tests without code coverage and runs it',
|
||||
help='Compile the object files again and then run the tests',
|
||||
default=False,
|
||||
action='store_true',
|
||||
dest='rerun')
|
||||
@@ -365,11 +383,12 @@ if __name__ == '__main__':
|
||||
print(CONFIG)
|
||||
exit(0)
|
||||
|
||||
if args.clean:
|
||||
clean_build()
|
||||
if args.clean or args.cleanfull:
|
||||
clean_build(args.cleanfull)
|
||||
|
||||
assert_structure()
|
||||
assert_executable(CC)
|
||||
if not args.cleanfull:
|
||||
assert_structure()
|
||||
assert_executable(CC)
|
||||
|
||||
if args.expand:
|
||||
expand_code()
|
||||
@@ -382,11 +401,12 @@ if __name__ == '__main__':
|
||||
assert_executable('xargs')
|
||||
format_code(args.fmt_source, args.fmt_tests)
|
||||
|
||||
if args.rerun:
|
||||
build_tests(False)
|
||||
run_tests()
|
||||
if args.build:
|
||||
build_tests(args.coverage)
|
||||
if args.run:
|
||||
run_tests(args.coverage)
|
||||
elif args.rerun:
|
||||
build_tests(args.coverage)
|
||||
run_tests(args.coverage)
|
||||
elif args.run:
|
||||
run_tests()
|
||||
elif args.coverage:
|
||||
build_tests(True)
|
||||
run_tests()
|
||||
run_tests(args.coverage)
|
||||
+4
-4
@@ -461,8 +461,8 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
K max_key; \
|
||||
V max_val; \
|
||||
K max_key = (K) { 0 }; \
|
||||
V max_val = (V) { 0 }; \
|
||||
size_t first = 0; \
|
||||
\
|
||||
for (; first < _map_->capacity; first++) \
|
||||
@@ -505,8 +505,8 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
K min_key; \
|
||||
V min_val; \
|
||||
K min_key = (K) { 0 }; \
|
||||
V min_val = (V) { 0 }; \
|
||||
size_t first = 0; \
|
||||
\
|
||||
for (; first < _map_->capacity; first++) \
|
||||
|
||||
@@ -684,8 +684,8 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
K max_key; \
|
||||
V max_val; \
|
||||
K max_key = (K) { 0 }; \
|
||||
V max_val = (V) { 0 }; \
|
||||
\
|
||||
struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \
|
||||
\
|
||||
@@ -728,8 +728,8 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
K min_key; \
|
||||
V min_val; \
|
||||
K min_key = (K) { 0 }; \
|
||||
V min_val = (V) { 0 }; \
|
||||
\
|
||||
struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \
|
||||
\
|
||||
|
||||
@@ -477,7 +477,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
V max_val; \
|
||||
V max_val = (V) { 0 }; \
|
||||
struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \
|
||||
\
|
||||
/* TODO transform this into a normal loop */ \
|
||||
@@ -510,7 +510,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
V min_val; \
|
||||
V min_val = (V) { 0 }; \
|
||||
struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \
|
||||
\
|
||||
/* TODO transform this into a normal loop */ \
|
||||
|
||||
+10
-10
@@ -378,7 +378,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
V max_value; \
|
||||
V max_val = (V) { 0 }; \
|
||||
struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \
|
||||
\
|
||||
/* TODO turn this into a normal loop */ \
|
||||
@@ -388,13 +388,13 @@
|
||||
size_t index = CMC_(PFX, _iter_index)(&iter); \
|
||||
\
|
||||
if (index == 0) \
|
||||
max_value = result; \
|
||||
else if (_set_->f_val->cmp(result, max_value) > 0) \
|
||||
max_value = result; \
|
||||
max_val = result; \
|
||||
else if (_set_->f_val->cmp(result, max_val) > 0) \
|
||||
max_val = result; \
|
||||
} \
|
||||
\
|
||||
if (value) \
|
||||
*value = max_value; \
|
||||
*value = max_val; \
|
||||
\
|
||||
_set_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
@@ -411,7 +411,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
V min_value; \
|
||||
V min_val = (V) { 0 }; \
|
||||
struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \
|
||||
\
|
||||
/* TODO turn this into a normal loop */ \
|
||||
@@ -421,13 +421,13 @@
|
||||
size_t index = CMC_(PFX, _iter_index)(&iter); \
|
||||
\
|
||||
if (index == 0) \
|
||||
min_value = result; \
|
||||
else if (_set_->f_val->cmp(result, min_value) < 0) \
|
||||
min_value = result; \
|
||||
min_val = result; \
|
||||
else if (_set_->f_val->cmp(result, min_val) < 0) \
|
||||
min_val = result; \
|
||||
} \
|
||||
\
|
||||
if (value) \
|
||||
*value = min_value; \
|
||||
*value = min_val; \
|
||||
\
|
||||
_set_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
|
||||
@@ -25,14 +25,6 @@ struct queue_fval
|
||||
size_t (*hash)(size_t);
|
||||
int (*pri)(size_t, size_t);
|
||||
};
|
||||
struct queue_iter
|
||||
{
|
||||
struct queue *target;
|
||||
size_t cursor;
|
||||
size_t index;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct queue *q_new(size_t capacity, struct queue_fval *f_val);
|
||||
struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks);
|
||||
@@ -51,6 +43,14 @@ int q_flag(struct queue *_queue_);
|
||||
_Bool q_resize(struct queue *_queue_, size_t capacity);
|
||||
struct queue *q_copy_of(struct queue *_queue_);
|
||||
_Bool q_equals(struct queue *_queue1_, struct queue *_queue2_);
|
||||
struct queue_iter
|
||||
{
|
||||
struct queue *target;
|
||||
size_t cursor;
|
||||
size_t index;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct queue_iter q_iter_start(struct queue *target);
|
||||
struct queue_iter q_iter_end(struct queue *target);
|
||||
_Bool q_iter_at_start(struct queue_iter *iter);
|
||||
|
||||
@@ -201,8 +201,8 @@ _Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value)
|
||||
_map_->flag = CMC_FLAG_EMPTY;
|
||||
return 0;
|
||||
}
|
||||
size_t max_key;
|
||||
size_t max_val;
|
||||
size_t max_key = (size_t){ 0 };
|
||||
size_t max_val = (size_t){ 0 };
|
||||
size_t first = 0;
|
||||
for (; first < _map_->capacity; first++)
|
||||
{
|
||||
@@ -240,8 +240,8 @@ _Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value)
|
||||
_map_->flag = CMC_FLAG_EMPTY;
|
||||
return 0;
|
||||
}
|
||||
size_t min_key;
|
||||
size_t min_val;
|
||||
size_t min_key = (size_t){ 0 };
|
||||
size_t min_val = (size_t){ 0 };
|
||||
size_t first = 0;
|
||||
for (; first < _map_->capacity; first++)
|
||||
{
|
||||
|
||||
@@ -353,8 +353,8 @@ _Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value)
|
||||
_map_->flag = CMC_FLAG_EMPTY;
|
||||
return 0;
|
||||
}
|
||||
size_t max_key;
|
||||
size_t max_val;
|
||||
size_t max_key = (size_t){ 0 };
|
||||
size_t max_val = (size_t){ 0 };
|
||||
struct hashmultimap_iter iter = hmm_iter_start(_map_);
|
||||
for (; !hmm_iter_at_end(&iter); hmm_iter_next(&iter))
|
||||
{
|
||||
@@ -389,8 +389,8 @@ _Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value)
|
||||
_map_->flag = CMC_FLAG_EMPTY;
|
||||
return 0;
|
||||
}
|
||||
size_t min_key;
|
||||
size_t min_val;
|
||||
size_t min_key = (size_t){ 0 };
|
||||
size_t min_val = (size_t){ 0 };
|
||||
struct hashmultimap_iter iter = hmm_iter_start(_map_);
|
||||
for (; !hmm_iter_at_end(&iter); hmm_iter_next(&iter))
|
||||
{
|
||||
|
||||
@@ -218,7 +218,7 @@ _Bool hms_max(struct hashmultiset *_set_, size_t *value)
|
||||
_set_->flag = CMC_FLAG_EMPTY;
|
||||
return 0;
|
||||
}
|
||||
size_t max_val;
|
||||
size_t max_val = (size_t){ 0 };
|
||||
struct hashmultiset_iter iter = hms_iter_start(_set_);
|
||||
for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
|
||||
{
|
||||
@@ -244,7 +244,7 @@ _Bool hms_min(struct hashmultiset *_set_, size_t *value)
|
||||
_set_->flag = CMC_FLAG_EMPTY;
|
||||
return 0;
|
||||
}
|
||||
size_t min_val;
|
||||
size_t min_val = (size_t){ 0 };
|
||||
struct hashmultiset_iter iter = hms_iter_start(_set_);
|
||||
for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
|
||||
{
|
||||
|
||||
+10
-10
@@ -164,19 +164,19 @@ _Bool hs_max(struct hashset *_set_, size_t *value)
|
||||
_set_->flag = CMC_FLAG_EMPTY;
|
||||
return 0;
|
||||
}
|
||||
size_t max_value;
|
||||
size_t max_val = (size_t){ 0 };
|
||||
struct hashset_iter iter = hs_iter_start(_set_);
|
||||
for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
|
||||
{
|
||||
size_t result = hs_iter_value(&iter);
|
||||
size_t index = hs_iter_index(&iter);
|
||||
if (index == 0)
|
||||
max_value = result;
|
||||
else if (_set_->f_val->cmp(result, max_value) > 0)
|
||||
max_value = result;
|
||||
max_val = result;
|
||||
else if (_set_->f_val->cmp(result, max_val) > 0)
|
||||
max_val = result;
|
||||
}
|
||||
if (value)
|
||||
*value = max_value;
|
||||
*value = max_val;
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->read)
|
||||
(_set_)->callbacks->read();
|
||||
@@ -190,19 +190,19 @@ _Bool hs_min(struct hashset *_set_, size_t *value)
|
||||
_set_->flag = CMC_FLAG_EMPTY;
|
||||
return 0;
|
||||
}
|
||||
size_t min_value;
|
||||
size_t min_val = (size_t){ 0 };
|
||||
struct hashset_iter iter = hs_iter_start(_set_);
|
||||
for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
|
||||
{
|
||||
size_t result = hs_iter_value(&iter);
|
||||
size_t index = hs_iter_index(&iter);
|
||||
if (index == 0)
|
||||
min_value = result;
|
||||
else if (_set_->f_val->cmp(result, min_value) < 0)
|
||||
min_value = result;
|
||||
min_val = result;
|
||||
else if (_set_->f_val->cmp(result, min_val) < 0)
|
||||
min_val = result;
|
||||
}
|
||||
if (value)
|
||||
*value = min_value;
|
||||
*value = min_val;
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->read)
|
||||
(_set_)->callbacks->read();
|
||||
|
||||
Reference in new issue
Block a user