Merge pull request '”add Q42 and passed“' (#8) from developed_in_2024_12_18 into main
Reviewed-on: https://external.feng-arch.cn:35127/fengqi/ysyx/pulls/8
This commit is contained in:
commit
eda1f91cff
135
.clang-format
Normal file
135
.clang-format
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveMacros: false
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignEscapedNewlines: Right
|
||||||
|
AlignOperands: true
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllArgumentsOnNextLine: false
|
||||||
|
AllowAllConstructorInitializersOnNextLine: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: None
|
||||||
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
BinPackArguments: false
|
||||||
|
BinPackParameters: false
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: true
|
||||||
|
AfterClass: true
|
||||||
|
AfterControlStatement: true
|
||||||
|
AfterEnum: true
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: true
|
||||||
|
AfterObjCDeclaration: true
|
||||||
|
AfterStruct: true
|
||||||
|
AfterUnion: true
|
||||||
|
AfterExternBlock: true
|
||||||
|
BeforeCatch: true
|
||||||
|
BeforeElse: true
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializersBeforeComma: false
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 120
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DeriveLineEnding: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 0
|
||||||
|
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||||
|
Priority: 3
|
||||||
|
SortPriority: 0
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 0
|
||||||
|
IncludeIsMainRegex: '(Test)?$'
|
||||||
|
IncludeIsMainSourceRegex: ''
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentGotoLabels: true
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 2
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCBinPackProtocolList: Auto
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 1000
|
||||||
|
PointerAlignment: Right
|
||||||
|
ReflowComments: false
|
||||||
|
SortIncludes: true
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInConditionalStatement: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
Standard: Latest
|
||||||
|
StatementMacros:
|
||||||
|
- Q_UNUSED
|
||||||
|
- QT_REQUIRE_VERSION
|
||||||
|
TabWidth: 4
|
||||||
|
UseCRLF: false
|
||||||
|
UseTab: Never
|
||||||
|
...
|
||||||
9
.clang-tidy
Normal file
9
.clang-tidy
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
Checks: 'clang-analyzer-*,cppcoreguidelines-*,modernize-*,bugprone-*,performance-*,readability-*,readability-non-const-parameter,misc-const-correctness,misc-use-anonymous-namespace,google-explicit-constructor,-modernize-use-trailing-return-type,-bugprone-exception-escape,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-avoid-magic-numbers,-bugprone-easily-swappable-parameters,-cppcoreguidelines-non-private-member-variables-in-classes'
|
||||||
|
WarningsAsErrors: ''
|
||||||
|
HeaderFilterRegex: ''
|
||||||
|
CheckOptions:
|
||||||
|
- key: readability-magic-numbers.IgnoredFloatingPointValues
|
||||||
|
value: '0.0;1.0;100.0;'
|
||||||
|
- key: readability-magic-numbers.IgnoredIntegerValues
|
||||||
|
value: '0;1;2;3;4;5;6;7;8;9;'
|
||||||
17
.editorconfig
Normal file
17
.editorconfig
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# EditorConfig is awesome: http://EditorConfig.org
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
end_of_line = lf
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
[Makefile]
|
||||||
|
indent_style = tab
|
||||||
|
trim_trailing_whitespace = false
|
||||||
11
.gitattributes
vendored
Normal file
11
.gitattributes
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Set the default behavior for all files.
|
||||||
|
* text=auto eol=lf
|
||||||
|
|
||||||
|
# Normalized and converts to native line endings on checkout.
|
||||||
|
*.c text
|
||||||
|
*.cc text
|
||||||
|
*.cxx
|
||||||
|
*.cpp text
|
||||||
|
*.h text
|
||||||
|
*.hxx text
|
||||||
|
*.hpp text
|
||||||
59
.vscode/launch.json
vendored
Normal file
59
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Q42_1",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "/home/fengqi/Documents/GitRepos/ysyx/pre-study_phase/2025_02_17/Q42/tests/stack_tests.out",
|
||||||
|
"args": [],
|
||||||
|
"stopAtEntry": true,
|
||||||
|
"cwd": "/home/fengqi/Documents/GitRepos/ysyx/pre-study_phase/2025_02_17/Q42",
|
||||||
|
"environment": [],
|
||||||
|
"externalConsole": false,
|
||||||
|
"MIMode": "gdb",
|
||||||
|
"setupCommands": [
|
||||||
|
{
|
||||||
|
"description": "Enable pretty-printing for gdb",
|
||||||
|
"text": "-enable-pretty-printing",
|
||||||
|
"ignoreFailures": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Set Disassembly Flavor to Intel",
|
||||||
|
"text": "-gdb-set disassembly-flavor intel",
|
||||||
|
"ignoreFailures": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"preLaunchTask": "Q42_build"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Q42_2",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "/home/fengqi/Documents/GitRepos/ysyx/pre-study_phase/2025_02_17/Q42/tests/queue_tests.out",
|
||||||
|
"args": [],
|
||||||
|
"stopAtEntry": true,
|
||||||
|
"cwd": "/home/fengqi/Documents/GitRepos/ysyx/pre-study_phase/2025_02_17/Q42",
|
||||||
|
"environment": [],
|
||||||
|
"externalConsole": false,
|
||||||
|
"MIMode": "gdb",
|
||||||
|
"setupCommands": [
|
||||||
|
{
|
||||||
|
"description": "Enable pretty-printing for gdb",
|
||||||
|
"text": "-enable-pretty-printing",
|
||||||
|
"ignoreFailures": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Set Disassembly Flavor to Intel",
|
||||||
|
"text": "-gdb-set disassembly-flavor intel",
|
||||||
|
"ignoreFailures": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"preLaunchTask": "Q42_build"
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -2,4 +2,4 @@
|
|||||||
"files.associations": {
|
"files.associations": {
|
||||||
"assert.h": "c"
|
"assert.h": "c"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
.vscode/tasks.json
vendored
Normal file
15
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||||
|
// for the documentation about the tasks.json format
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "Q42_build",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "make || true",
|
||||||
|
"options": {
|
||||||
|
"cwd": "/home/fengqi/Documents/GitRepos/ysyx/pre-study_phase/2025_02_17/Q42"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
0
pre-study_phase/2025_02_17/Q42/LICENSE
Normal file
0
pre-study_phase/2025_02_17/Q42/LICENSE
Normal file
61
pre-study_phase/2025_02_17/Q42/Makefile
Normal file
61
pre-study_phase/2025_02_17/Q42/Makefile
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
CFLAGS=-g -O0 -Wall -Wextra -Isrc -rdynamic -DNDEBUG $(OPTFLAGS)
|
||||||
|
LIBS=-ldl $(OPTLIBS)
|
||||||
|
PREFIX?=/usr/local
|
||||||
|
|
||||||
|
SOURCES=$(wildcard src/**/*.c src/*.c)
|
||||||
|
OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
|
||||||
|
|
||||||
|
TEST_SRC=$(wildcard tests/*_tests.c)
|
||||||
|
TESTS=$(patsubst %.c,%,$(TEST_SRC))
|
||||||
|
|
||||||
|
# TARGET=build/lcthw.a
|
||||||
|
SO_TARGET=$(patsubst %.a,%.so,$(TARGET))
|
||||||
|
|
||||||
|
# The Target Build
|
||||||
|
all: $(TARGET) $(SO_TARGET) tests
|
||||||
|
|
||||||
|
dev: CFLAGS=-g -Wall -Isrc -Wall -Wextra $(OPTFLAGS)
|
||||||
|
dev: all
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$(TARGET): CFLAGS += -fPIC
|
||||||
|
$(TARGET): build $(OBJECTS)
|
||||||
|
ar rcs $@ $(OBJECTS)
|
||||||
|
ranlib $@
|
||||||
|
|
||||||
|
$(SO_TARGET): $(TARGET) $(OBJECTS)
|
||||||
|
$(CC) -shared -o $@ $(OBJECTS)
|
||||||
|
|
||||||
|
build:
|
||||||
|
@mkdir -p build
|
||||||
|
@mkdir -p bin
|
||||||
|
|
||||||
|
# The Unit Tests
|
||||||
|
.PHONY: tests
|
||||||
|
$(TESTS): %: %.c $(TARGET)
|
||||||
|
$(CC) $(CFLAGS) $< -o $@.out $(TARGET) $(LIBS)
|
||||||
|
tests: $(TESTS)
|
||||||
|
sh ./tests/runtests.sh
|
||||||
|
|
||||||
|
valgrind:
|
||||||
|
VALGRIND="valgrind --log-file=/tmp/valgrind-%p.log" $(MAKE)
|
||||||
|
|
||||||
|
# The Cleaner
|
||||||
|
clean:
|
||||||
|
rm -rf build $(OBJECTS) $(TESTS)
|
||||||
|
rm -f tests/tests.log
|
||||||
|
find . -name "*.gc*" -exec rm {} \;
|
||||||
|
find . -name "*.out*" -exec rm {} \;
|
||||||
|
rm -rf `find . -name "*.dSYM" -print`
|
||||||
|
|
||||||
|
# The Install
|
||||||
|
install: all
|
||||||
|
install -d $(DESTDIR)/$(PREFIX)/lib/
|
||||||
|
install $(TARGET) $(DESTDIR)/$(PREFIX)/lib/
|
||||||
|
|
||||||
|
# The Checker
|
||||||
|
BADFUNCS='[^_.>a-zA-Z0-9](str(n?cpy|n?cat|xfrm|n?dup|str|pbrk|tok|_)|stpn?cpy|a?sn?printf|byte_)'
|
||||||
|
check:
|
||||||
|
@echo Files with potentially dangerous functions.
|
||||||
|
@egrep $(BADFUNCS) $(SOURCES) || true
|
||||||
45
pre-study_phase/2025_02_17/Q42/src/lcthw/dbg.h
Normal file
45
pre-study_phase/2025_02_17/Q42/src/lcthw/dbg.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#ifndef _dbg_h_
|
||||||
|
#define _dbg_h_
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#ifdef NDEBUG
|
||||||
|
#define debug(M, ...)
|
||||||
|
#else
|
||||||
|
#define debug(M, ...) fprintf(stderr, "DEBUG %s:%d:" M "\n", __FILE__, __LINE__, ##__VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define clean_errno() (errno == 0 ? "None" : strerror(errno))
|
||||||
|
|
||||||
|
#define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#define log_warn(M, ...) fprintf(stderr, "[WARN] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#define log_info(M, ...) fprintf(stderr, "[INFO] (%s:%d) " M "\n", __FILE__, __LINE__, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#define check(A, M, ...) \
|
||||||
|
if (!(A)) \
|
||||||
|
{ \
|
||||||
|
log_err(M, ##__VA_ARGS__); \
|
||||||
|
errno = 0; \
|
||||||
|
goto error; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define sentinel(M, ...) \
|
||||||
|
{ \
|
||||||
|
log_err(M, ##__VA_ARGS__); \
|
||||||
|
errno = 0; \
|
||||||
|
goto error; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define check_mem(A) check((A), "Out of memory.")
|
||||||
|
|
||||||
|
#define check_debug(A, M, ...) \
|
||||||
|
if (!(A)) \
|
||||||
|
{ \
|
||||||
|
debug(M, ##__VA_ARGS__); \
|
||||||
|
errno = 0; \
|
||||||
|
goto error; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
89
pre-study_phase/2025_02_17/Q42/src/lcthw/queue.h
Normal file
89
pre-study_phase/2025_02_17/Q42/src/lcthw/queue.h
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#ifndef lcthw_Queue_h
|
||||||
|
#define lcthw_Queue_h
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
typedef struct QueueNode
|
||||||
|
{
|
||||||
|
void *value;
|
||||||
|
struct QueueNode *next;
|
||||||
|
struct QueueNode *prev;
|
||||||
|
} QueueNode;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct Queue
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
QueueNode *first;
|
||||||
|
QueueNode *last;
|
||||||
|
} Queue;
|
||||||
|
|
||||||
|
|
||||||
|
#define QUEUE_FOREACH(Q, C) \
|
||||||
|
QueueNode *C = NULL; \
|
||||||
|
for (C = Q->first; C != NULL; C = C->next)
|
||||||
|
|
||||||
|
|
||||||
|
Queue *Queue_create()
|
||||||
|
{
|
||||||
|
return calloc(1, sizeof(Queue));
|
||||||
|
}
|
||||||
|
void Queue_destroy(Queue *q)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < q->count;i++){
|
||||||
|
QueueNode *temp = q->first;
|
||||||
|
q->first = temp->next;
|
||||||
|
free(temp);
|
||||||
|
}
|
||||||
|
free(q);
|
||||||
|
}
|
||||||
|
void Queue_send(Queue *q, void *value)
|
||||||
|
{
|
||||||
|
q->count++;
|
||||||
|
QueueNode *temp = calloc(1, sizeof(QueueNode));
|
||||||
|
temp->value = value;
|
||||||
|
if (q->first == NULL)
|
||||||
|
{
|
||||||
|
temp->prev = NULL;
|
||||||
|
temp->next = NULL;
|
||||||
|
q->first = temp;
|
||||||
|
q->last = temp;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
temp->next = q->first;
|
||||||
|
q->first->prev = temp;
|
||||||
|
temp->prev = NULL;
|
||||||
|
q->first = temp;
|
||||||
|
}
|
||||||
|
void *Queue_peek(Queue *q)
|
||||||
|
{
|
||||||
|
return q->last->value;
|
||||||
|
}
|
||||||
|
int Queue_count(Queue *q)
|
||||||
|
{
|
||||||
|
if (q == NULL)
|
||||||
|
return 0;
|
||||||
|
return q->count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *Queue_recv(Queue *q)
|
||||||
|
{
|
||||||
|
void *result = NULL;
|
||||||
|
if (q->count == 0)
|
||||||
|
return NULL;
|
||||||
|
q->count--;
|
||||||
|
result = q->last->value;
|
||||||
|
QueueNode *temp = q->last;
|
||||||
|
if (q->count == 0)
|
||||||
|
{
|
||||||
|
free(temp);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
q->last = q->last->prev;
|
||||||
|
q->last->next = NULL;
|
||||||
|
free(temp);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
85
pre-study_phase/2025_02_17/Q42/src/lcthw/stack.h
Normal file
85
pre-study_phase/2025_02_17/Q42/src/lcthw/stack.h
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#ifndef lcthw_Stack_h
|
||||||
|
#define lcthw_Stack_h
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define STACK_FOREACH(S, C) \
|
||||||
|
Stack *C = NULL; \
|
||||||
|
for (C = S; C != NULL && C->value != NULL; C = C->next)
|
||||||
|
|
||||||
|
typedef struct Stack
|
||||||
|
{
|
||||||
|
void *value;
|
||||||
|
struct Stack *next;
|
||||||
|
} Stack;
|
||||||
|
|
||||||
|
Stack *Stack_create()
|
||||||
|
{
|
||||||
|
return calloc(1, sizeof(Stack));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stack_destroy(Stack *s)
|
||||||
|
{
|
||||||
|
STACK_FOREACH(s, cur)
|
||||||
|
{
|
||||||
|
free(s);
|
||||||
|
s = cur;
|
||||||
|
}
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stack_push(Stack *s, void *value)
|
||||||
|
{
|
||||||
|
if (s->value == NULL)
|
||||||
|
{
|
||||||
|
s->value = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Stack *temp = calloc(1, sizeof(Stack));
|
||||||
|
temp->value = s->value;
|
||||||
|
temp->next = s->next;
|
||||||
|
s->value = value;
|
||||||
|
s->next = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Stack_count(Stack *s)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
STACK_FOREACH(s, cur)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *Stack_peek(Stack *s)
|
||||||
|
{
|
||||||
|
if (s == NULL)
|
||||||
|
return NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return s->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *Stack_pop(Stack *s)
|
||||||
|
{
|
||||||
|
if (s == NULL || s->value == NULL)
|
||||||
|
return NULL;
|
||||||
|
Stack *temp = s->next;
|
||||||
|
void *value = s->value;
|
||||||
|
if (temp != NULL)
|
||||||
|
{
|
||||||
|
s->next = temp->next;
|
||||||
|
s->value = temp->value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s->value = NULL;
|
||||||
|
s->next = NULL;
|
||||||
|
}
|
||||||
|
free(temp);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
45
pre-study_phase/2025_02_17/Q42/tests/dbg.h
Normal file
45
pre-study_phase/2025_02_17/Q42/tests/dbg.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#ifndef _dbg_h_
|
||||||
|
#define _dbg_h_
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#ifdef NDEBUG
|
||||||
|
#define debug(M, ...)
|
||||||
|
#else
|
||||||
|
#define debug(M, ...) fprintf(stderr, "DEBUG %s:%d:" M "\n", __FILE__, __LINE__, ##__VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define clean_errno() (errno == 0 ? "None" : strerror(errno))
|
||||||
|
|
||||||
|
#define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#define log_warn(M, ...) fprintf(stderr, "[WARN] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#define log_info(M, ...) fprintf(stderr, "[INFO] (%s:%d) " M "\n", __FILE__, __LINE__, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#define check(A, M, ...) \
|
||||||
|
if (!(A)) \
|
||||||
|
{ \
|
||||||
|
log_err(M, ##__VA_ARGS__); \
|
||||||
|
errno = 0; \
|
||||||
|
goto error; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define sentinel(M, ...) \
|
||||||
|
{ \
|
||||||
|
log_err(M, ##__VA_ARGS__); \
|
||||||
|
errno = 0; \
|
||||||
|
goto error; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define check_mem(A) check((A), "Out of memory.")
|
||||||
|
|
||||||
|
#define check_debug(A, M, ...) \
|
||||||
|
if (!(A)) \
|
||||||
|
{ \
|
||||||
|
debug(M, ##__VA_ARGS__); \
|
||||||
|
errno = 0; \
|
||||||
|
goto error; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
45
pre-study_phase/2025_02_17/Q42/tests/minunit.h
Normal file
45
pre-study_phase/2025_02_17/Q42/tests/minunit.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#undef NDEBUG
|
||||||
|
#ifndef _minunit_h
|
||||||
|
#define _minunit_h
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "dbg.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define mu_suite_start() char *message = NULL
|
||||||
|
|
||||||
|
#define mu_assert(test, message) \
|
||||||
|
if (!(test)) \
|
||||||
|
{ \
|
||||||
|
log_err(message); \
|
||||||
|
return message; \
|
||||||
|
}
|
||||||
|
#define mu_run_test(test) \
|
||||||
|
debug("\n-----%s", " " #test); \
|
||||||
|
message = test(); \
|
||||||
|
tests_run++; \
|
||||||
|
if (message) \
|
||||||
|
return message;
|
||||||
|
|
||||||
|
#define RUN_TESTS(name) \
|
||||||
|
int main(int argc, char *argv[]) \
|
||||||
|
{ \
|
||||||
|
(void)argc; \
|
||||||
|
debug("----- RUNNING: %s", argv[0]); \
|
||||||
|
printf("----\nRUNNING: %s\n", argv[0]); \
|
||||||
|
char *result = name(); \
|
||||||
|
if (result != 0) \
|
||||||
|
{ \
|
||||||
|
printf("FAILED: %s\n", result); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
printf("ALL TESTS PASSED\n"); \
|
||||||
|
} \
|
||||||
|
printf("Tests run: %d\n", tests_run); \
|
||||||
|
exit(result != 0); \
|
||||||
|
}
|
||||||
|
|
||||||
|
int tests_run;
|
||||||
|
|
||||||
|
#endif
|
||||||
63
pre-study_phase/2025_02_17/Q42/tests/queue_tests.c
Normal file
63
pre-study_phase/2025_02_17/Q42/tests/queue_tests.c
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#include "minunit.h"
|
||||||
|
#include <lcthw/queue.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
static Queue *queue = NULL;
|
||||||
|
char *tests[] = {"test1 data", "test2 data", "test3 data"};
|
||||||
|
#define NUM_TESTS 3
|
||||||
|
|
||||||
|
char *test_create()
|
||||||
|
{
|
||||||
|
queue = Queue_create();
|
||||||
|
mu_assert(queue != NULL, "Failed to create queue.");
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *test_destroy()
|
||||||
|
{
|
||||||
|
mu_assert(queue != NULL, "Failed to make queue #2");
|
||||||
|
Queue_destroy(queue);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *test_send_recv()
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
for (i = 0; i < NUM_TESTS; i++)
|
||||||
|
{
|
||||||
|
Queue_send(queue, tests[i]);
|
||||||
|
mu_assert(Queue_peek(queue) == tests[0], "Wrong next value.");
|
||||||
|
}
|
||||||
|
|
||||||
|
mu_assert(Queue_count(queue) == NUM_TESTS, "Wrong count on send.");
|
||||||
|
|
||||||
|
QUEUE_FOREACH(queue, cur)
|
||||||
|
{
|
||||||
|
debug("VAL: %s", (char *)cur->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_TESTS; i++)
|
||||||
|
{
|
||||||
|
char *val = Queue_recv(queue);
|
||||||
|
mu_assert(val == tests[i], "Wrong value on recv.");
|
||||||
|
}
|
||||||
|
|
||||||
|
mu_assert(Queue_count(queue) == 0, "Wrong count after recv.");
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *all_tests()
|
||||||
|
{
|
||||||
|
mu_suite_start();
|
||||||
|
|
||||||
|
mu_run_test(test_create);
|
||||||
|
mu_run_test(test_send_recv);
|
||||||
|
mu_run_test(test_destroy);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
RUN_TESTS(all_tests);
|
||||||
5
pre-study_phase/2025_02_17/Q42/tests/runtests.sh
Normal file
5
pre-study_phase/2025_02_17/Q42/tests/runtests.sh
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
|
||||||
|
cd "$SCRIPT_DIR"
|
||||||
|
./stack_tests.out
|
||||||
|
./queue_tests.out
|
||||||
60
pre-study_phase/2025_02_17/Q42/tests/stack_tests.c
Normal file
60
pre-study_phase/2025_02_17/Q42/tests/stack_tests.c
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#include "minunit.h"
|
||||||
|
#include <lcthw/stack.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
static Stack *stack = NULL;
|
||||||
|
char *tests[] = {"test1 data", "test2 data", "test3 data"};
|
||||||
|
#define NUM_TESTS 3
|
||||||
|
|
||||||
|
|
||||||
|
char *test_create()
|
||||||
|
{
|
||||||
|
stack = Stack_create();
|
||||||
|
mu_assert(stack != NULL, "Failed to create stack.");
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *test_destroy()
|
||||||
|
{
|
||||||
|
mu_assert(stack != NULL, "Failed to make stack #2");
|
||||||
|
Stack_destroy(stack);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *test_push_pop()
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
for(i = 0; i < NUM_TESTS; i++) {
|
||||||
|
Stack_push(stack, tests[i]);
|
||||||
|
mu_assert(Stack_peek(stack) == tests[i], "Wrong next value.");
|
||||||
|
}
|
||||||
|
|
||||||
|
mu_assert(Stack_count(stack) == NUM_TESTS, "Wrong count on push.");
|
||||||
|
|
||||||
|
STACK_FOREACH(stack, cur) {
|
||||||
|
debug("VAL: %s", (char *)cur->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = NUM_TESTS - 1; i >= 0; i--) {
|
||||||
|
char *val = Stack_pop(stack);
|
||||||
|
mu_assert(val == tests[i], "Wrong value on pop.");
|
||||||
|
}
|
||||||
|
|
||||||
|
mu_assert(Stack_count(stack) == 0, "Wrong count after pop.");
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *all_tests() {
|
||||||
|
mu_suite_start();
|
||||||
|
|
||||||
|
mu_run_test(test_create);
|
||||||
|
mu_run_test(test_push_pop);
|
||||||
|
mu_run_test(test_destroy);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
RUN_TESTS(all_tests);
|
||||||
Loading…
x
Reference in New Issue
Block a user