4.1 KiB
4.1 KiB
Task 1 Brief: Build scaffold and public C ABI lifecycle
Global constraints
- Use only original source code; do not link proprietary SDK binaries.
- Current workspace is not a git repository; replace commit steps with verification plus updates to progress.md.
- Keep public C ABI free of C++ types.
- Use C++17.
- libusb-1.0 is the only native runtime dependency for the core library.
- Firmware update commands are not exposed as an easy accidental CLI action.
- IR protocol gaps return MAG160C_ERR_PROTOCOL_UNKNOWN or MAG160C_ERR_UNSUPPORTED.
Files
- Create: CMakeLists.txt
- Create: include/mag160c/mag160c.h
- Create: src/core/error.hpp
- Create: src/core/error.cpp
- Create: src/core/context.hpp
- Create: src/core/context.cpp
- Create: src/c_api.cpp
- Create: tests/cpp/test_c_api.cpp
- Update: progress.md with the checkpoint at the end.
Interfaces to produce
- mag160c_error_t
- opaque mag160c_context_t
- opaque mag160c_ir_device_t
- opaque mag160c_tcm_device_t
- mag160c_error_t mag160c_init(mag160c_context_t** out_ctx)
- void mag160c_shutdown(mag160c_context_t* ctx)
- const char* mag160c_last_error(void)
- const char* mag160c_error_name(mag160c_error_t code)
Required public error enum
typedef enum mag160c_error_t {
MAG160C_OK = 0,
MAG160C_ERR_INVALID_ARGUMENT = 1,
MAG160C_ERR_NO_DEVICE = 2,
MAG160C_ERR_PERMISSION = 3,
MAG160C_ERR_USB = 4,
MAG160C_ERR_TIMEOUT = 5,
MAG160C_ERR_CHECKSUM = 6,
MAG160C_ERR_PROTOCOL_UNKNOWN = 7,
MAG160C_ERR_UNSUPPORTED = 8,
MAG160C_ERR_INTERNAL = 9
} mag160c_error_t;
Required test assertions
Create tests/cpp/test_c_api.cpp and include assertions equivalent to:
assert(std::strcmp(mag160c_error_name(MAG160C_OK), "MAG160C_OK") == 0);
assert(std::strcmp(mag160c_error_name(MAG160C_ERR_PROTOCOL_UNKNOWN), "MAG160C_ERR_PROTOCOL_UNKNOWN") == 0);
assert(std::strcmp(mag160c_error_name(static_cast<mag160c_error_t>(9999)), "MAG160C_ERR_UNKNOWN_CODE") == 0);
assert(mag160c_init(nullptr) == MAG160C_ERR_INVALID_ARGUMENT);
mag160c_context_t* ctx = nullptr;
assert(mag160c_init(&ctx) == MAG160C_OK);
assert(ctx != nullptr);
mag160c_shutdown(ctx);
Required CMake behavior
- Minimum CMake 3.16.
- Project name mag160c, C and CXX languages.
- Options:
- MAG160C_BUILD_TESTS ON by default.
- MAG160C_BUILD_CLI ON by default.
- C++ standard 17, required, no compiler extensions.
- Use PkgConfig to find libusb-1.0 if available.
- Build shared library target mag160c_core from:
- src/core/error.cpp
- src/core/context.cpp
- src/c_api.cpp
- Public include directory: include.
- Private include directory: src.
- If libusb is found, define MAG160C_HAS_LIBUSB=1 and link include/library variables.
- If libusb is absent, define MAG160C_HAS_LIBUSB=0 and still build.
- When tests are enabled, build test_c_api and register it with CTest.
Required implementation behavior
- last error is thread-local.
- mag160c_error_name returns stable string names for every enum value and MAG160C_ERR_UNKNOWN_CODE for unknown values.
- Context construction succeeds without hardware.
- When libusb is absent at build time, Context records has_libusb as false but still constructs.
- mag160c_init rejects a null output pointer, sets last_error mentioning out_ctx, and returns MAG160C_ERR_INVALID_ARGUMENT.
- mag160c_init allocates a context on success, clears last_error, and returns MAG160C_OK.
- mag160c_shutdown accepts null safely through delete behavior.
- mag160c_last_error returns the thread-local message.
Verification
Run:
cmake -S . -B build -DMAG160C_BUILD_TESTS=ON
cmake --build build
ctest --test-dir build --output-on-failure
Expected: test_c_api passes.
Progress checkpoint
Append this line to progress.md after verification:
- Implemented Task 1 scaffold: CMake, public C ABI lifecycle, error names, and lifecycle tests.
Report contract
Write a report to .superpowers/sdd/task-1-report.md with:
- status: DONE, DONE_WITH_CONCERNS, NEEDS_CONTEXT, or BLOCKED
- files created/modified
- exact commands run
- test results
- concerns, if any
- self-review notes