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:
fengqi 2025-02-17 06:14:35 +00:00
commit eda1f91cff
17 changed files with 745 additions and 1 deletions

135
.clang-format Normal file
View 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
View 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
View 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
View 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
View 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"
}
]
}

View File

@ -2,4 +2,4 @@
"files.associations": { "files.associations": {
"assert.h": "c" "assert.h": "c"
} }
} }

15
.vscode/tasks.json vendored Normal file
View 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"
},
}
]
}

View File

View 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

View 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

View 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

View 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

View 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

View 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

View 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);

View File

@ -0,0 +1,5 @@
#!/bin/sh
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
cd "$SCRIPT_DIR"
./stack_tests.out
./queue_tests.out

View 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);