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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,6 @@ Makefile

api_test
ccos_disk_tool

build/
.cache/
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"clangd.arguments": [
"--compile-commands-dir=build"
]
}
18 changes: 11 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
cmake_minimum_required(VERSION 3.10)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

project(ccos_disk_tool)

set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${SOURCE_DIR})

option(CCOS_ENABLE_TESTS "Build and run tests (Criterion)" OFF)

add_library(ccos_api STATIC
${SOURCE_DIR}/string_utils.h
${SOURCE_DIR}/string_utils.c
Expand All @@ -26,10 +32,8 @@ add_executable(ccos_disk_tool

TARGET_LINK_LIBRARIES(ccos_disk_tool ccos_api)

project(api_test)

add_executable(api_test
${SOURCE_DIR}/api_test.c
)

TARGET_LINK_LIBRARIES(api_test ccos_api)
if(CCOS_ENABLE_TESTS)
include(CTest)
enable_testing()
add_subdirectory(tests)
endif()
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,29 @@ OPTIONS:
-l, --in-place Write changes to the original image
```

## Build

To build the project, run the following commands:

```bash
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel
```

After building, the compiled binary will be located at `build/ccos_disk_tool`.

## Run Tests

To run the tests, use the following commands:

```bash
cmake -S . -B build -DCCOS_ENABLE_TESTS=ON
cmake --build build --parallel
ctest --test-dir build --output-on-failure
```

Tests depend on the [Criterion](https://github.com/Snaipe/Criterion) library, which must be installed before running the tests.

## Examples

### Working with bubble memory images or other non-standard images
Expand Down
100 changes: 100 additions & 0 deletions cmake/FindCriterion.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# This file is licensed under the WTFPL version 2 -- you can see the full
# license over at http://www.wtfpl.net/txt/copying/
#
# Find Criterion.
#
# Module defines the following imported library:
# Criterion::Criterion
#
# Module defines the following result variables:
# Criterion_FOUND - True if the Criterion library has been found
# Criterion_INCLUDE_DIRS - Include directories needed to use Criterion
# Criterion_LIBRARIES - Libraries needed to link to Criterion
# Criterion_VERSION - The version of the Criterion which was found
#
# Cache variables:
# Criterion_INCLUDE_DIR - The directory containing criterion/criterion.h
# Criterion_LIBRARY - The path to the Criterion library
#
# Example usage:
# find_package(Criterion)
# target_link_libraries(foo PRIVATE Criterion::Criterion)

set(_criterionReason "")

# Try pkg-config.
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_check_modules(PC_Criterion QUIET criterion)
endif()

find_path(
Criterion_INCLUDE_DIR
criterion/criterion.h
HINTS ${PC_Criterion_INCLUDE_DIRS}
DOC "The directory containing criterion/criterion.h"
)
mark_as_advanced(Criterion_INCLUDE_DIR)

if(NOT Criterion_INCLUDE_DIR)
string(APPEND _criterionReason "criterion/criterion.h not found. ")
endif()

find_library(
Criterion_LIBRARY
NAMES criterion libcriterion
HINTS ${PC_Criterion_LIBRARY_DIRS}
DOC "The path to the Criterion library"
)
mark_as_advanced(Criterion_LIBRARY)

if(NOT Criterion_LIBRARY)
string(APPEND _criterionReason "Criterion library (libcriterion) not found. ")
endif()

# Get Criterion version from pkg-config if available. Conditional check ensures
# that Criterion found by pkg-config is the one found by the find_path() and
# find_library().
if(PC_Criterion_VERSION AND Criterion_INCLUDE_DIR IN_LIST PC_Criterion_INCLUDE_DIRS)
set(Criterion_VERSION ${PC_Criterion_VERSION})
endif()

include(FindPackageHandleStandardArgs)
# Handle the REQUIRED, QUIET, and version-related arguments of find_package().
find_package_handle_standard_args(
Criterion
REQUIRED_VARS Criterion_LIBRARY Criterion_INCLUDE_DIR
VERSION_VAR Criterion_VERSION
HANDLE_VERSION_RANGE
REASON_FAILURE_MESSAGE "${_criterionReason}"
)

unset(_criterionReason)

if(NOT Criterion_FOUND)
return()
endif()

set(Criterion_INCLUDE_DIRS ${Criterion_INCLUDE_DIR})
set(Criterion_LIBRARIES ${Criterion_LIBRARY})

if(NOT TARGET Criterion::Criterion)
if(IS_ABSOLUTE "${Criterion_LIBRARY}")
add_library(Criterion::Criterion UNKNOWN IMPORTED)
set_target_properties(
Criterion::Criterion
PROPERTIES IMPORTED_LOCATION "${Criterion_LIBRARY}"
)
else()
add_library(Criterion::Criterion INTERFACE IMPORTED)
set_target_properties(
Criterion::Criterion
PROPERTIES IMPORTED_LIBNAME "${Criterion_LIBRARY}"
)
endif()

set_target_properties(
Criterion::Criterion
PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${Criterion_INCLUDE_DIRS}"
)
endif()
9 changes: 9 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
find_package(Criterion REQUIRED)

add_executable(ccos_tests
${CMAKE_CURRENT_LIST_DIR}/api_test.c
)

target_link_libraries(ccos_tests PRIVATE ccos_api Criterion::Criterion)

add_test(NAME ccos_tests COMMAND ccos_tests)
58 changes: 21 additions & 37 deletions api_test.c → tests/api_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,15 @@
// Created by kirill on 04.06.2020.
//

#include <criterion/criterion.h>

#include <ccos_image.h>
#include <ccos_private.h>
#include <stdio.h>
#include <string.h>

#define __STR(X) #X
#define STR(X) __STR(X)

#define ASSERT(CONDITION) \
do { \
if (!(CONDITION)) { \
fprintf(stderr, "%s:%d: \"%s\" Failed!\n", __FUNCTION__, __LINE__, STR(CONDITION)); \
return -1; \
} \
} while (0)
#include <stdint.h>
#include <string.h>

uint8_t test_inode_data[] = {
static const uint8_t test_inode_data[] = {
0x98U, 0x00U, 0x00U, 0x00U, 0x84U, 0xD0U, 0x00U, 0x00U, 0x15U, 0x47U, 0x52U, 0x69U, 0x44U, 0x50U, 0x61U, 0x69U,
0x6EU, 0x74U, 0x7EU, 0x52U, 0x75U, 0x6EU, 0x20U, 0x43U, 0x61U, 0x6EU, 0x76U, 0x61U, 0x73U, 0x7EU, 0x00U, 0x00U,
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
Expand Down Expand Up @@ -52,43 +44,35 @@ uint8_t test_inode_data[] = {
0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU,
0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0x00U, 0x00U, 0x00U, 0x00U};

int check_image_test() {
Test(ccos_image, check_image) {
uint8_t data[0x200] = {0};
ASSERT(ccos_check_image(data) == 0);
cr_assert_eq(ccos_check_image(data), 0);
data[0] = 'I';
data[1] = 'M';
data[2] = 'D';
data[3] = ' ';
ASSERT(ccos_check_image(data) == -1);
cr_assert_eq(ccos_check_image(data), -1);
memset(data, 0, 0x200);
data[0] = 0xEB;
data[2] = 0x90;
*((uint16_t *)(&data[0x1FE])) = 0xAA55;
ASSERT(ccos_check_image(data) == -1);
return 0;
cr_assert_eq(ccos_check_image(data), -1);
}

int ccos_get_file_version_test() {
ccos_inode_t inode = *((ccos_inode_t *)&test_inode_data);
Test(ccos_image, get_file_version) {
ccos_inode_t inode;
memcpy(&inode, test_inode_data, sizeof(inode));
version_t version = ccos_get_file_version(&inode);
ASSERT(version.major == 3);
ASSERT(version.minor == 1);
ASSERT(version.patch == 5);
return 0;
cr_assert_eq(version.major, 3);
cr_assert_eq(version.minor, 1);
cr_assert_eq(version.patch, 5);
}

int ccos_get_file_name_test() {
ccos_inode_t inode = *((ccos_inode_t *)&test_inode_data);
Test(ccos_image, get_file_name) {
ccos_inode_t inode;
memcpy(&inode, test_inode_data, sizeof(inode));
short_string_t *name = ccos_get_file_name(&inode);
ASSERT(name->length == 21);
ASSERT(!strncmp(name->data, "GRiDPaint~Run Canvas~", name->length));
return 0;
}

int main() {
ASSERT(check_image_test() == 0);
ASSERT(ccos_get_file_version_test() == 0);
ASSERT(ccos_get_file_name_test() == 0);
printf("All tests completed!\n");
return 0;
cr_assert_not_null(name);
cr_assert_eq(name->length, 21);
cr_assert_eq(strncmp(name->data, "GRiDPaint~Run Canvas~", name->length), 0);
}