mirror of
https://github.com/logos-storage/easylibstorage.git
synced 2026-02-09 11:23:06 +00:00
initial import
This commit is contained in:
commit
51958d8310
58
.clang-format
Normal file
58
.clang-format
Normal file
@ -0,0 +1,58 @@
|
||||
# Generated from CLion C/C++ Code Style settings
|
||||
---
|
||||
Language: Cpp
|
||||
BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -4
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: false
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBraces: Custom
|
||||
BreakConstructorInitializers: AfterColon
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
ColumnLimit: 120
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ContinuationIndentWidth: 8
|
||||
IncludeCategories:
|
||||
- Regex: '^<.*'
|
||||
Priority: 1
|
||||
- Regex: '^".*'
|
||||
Priority: 2
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
IncludeIsMainRegex: '([-_](test|unittest))?$'
|
||||
IndentCaseLabels: true
|
||||
IndentWidth: 4
|
||||
InsertNewlineAtEOF: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 2
|
||||
NamespaceIndentation: All
|
||||
SpaceAfterCStyleCast: true
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeRangeBasedForLoopColon: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesInAngles: false
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
TabWidth: 4
|
||||
...
|
||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
cmake-*
|
||||
.idea
|
||||
28
CLAUDE.md
Normal file
28
CLAUDE.md
Normal file
@ -0,0 +1,28 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
storageconsole is a C11 interactive CLI application for managing a distributed storage node. It wraps an external `libstorage` library (Nim-based) through a command dispatch console.
|
||||
|
||||
## Build
|
||||
|
||||
Requires the `LOGOS_STORAGE_NIM_ROOT` environment variable pointing to the external storage library root (contains `library/libstorage.h` and platform-specific shared library).
|
||||
|
||||
```sh
|
||||
cmake -B build -S .
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
The build output is an executable named `storageconsole`.
|
||||
|
||||
## Architecture
|
||||
|
||||
- **main.c** — Entry point and interactive console. Implements a command dispatch loop using a static table of `command` structs mapping names to function pointers. The `console` struct holds an opaque `void *ctx` pointer to the storage node instance.
|
||||
- **easylibstorage.h** — High-level wrapper API declarations over `libstorage`. Defines `STORAGE_NODE` (opaque pointer), `node_config`, `progress_callback`, and functions for node lifecycle (`e_storage_new/start/stop/destroy`) and data operations (`e_storage_upload/download`). These are declared but not all wired into console commands yet.
|
||||
- **External dependency**: `libstorage` (platform-specific `.so`/`.dylib`/`.dll`) found via `LOGOS_STORAGE_NIM_ROOT`. Currently only `sync_start()` from `libstorage.h` is called directly.
|
||||
|
||||
## Code Style
|
||||
|
||||
Formatting is enforced via `.clang-format` (LLVM-based, 4-space indent, 120-char column limit).
|
||||
30
CMakeLists.txt
Normal file
30
CMakeLists.txt
Normal file
@ -0,0 +1,30 @@
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
project(storageconsole C)
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
|
||||
add_executable(storageconsole main.c
|
||||
easylibstorage.h
|
||||
)
|
||||
|
||||
if(NOT DEFINED LOGOS_STORAGE_NIM_ROOT)
|
||||
message(FATAL_ERROR "Need to set LOGOS_STORAGE_NIM_ROOT")
|
||||
endif()
|
||||
|
||||
target_include_directories(storageconsole PRIVATE "${LOGOS_STORAGE_NIM_ROOT}/library")
|
||||
|
||||
if(APPLE)
|
||||
set(LIBSTORAGE_NAMES libstorage.dylib)
|
||||
elseif(WIN32)
|
||||
set(LIBSTORAGE_NAMES libstorage.dll)
|
||||
else()
|
||||
set(LIBSTORAGE_NAMES libstorage.so)
|
||||
endif()
|
||||
|
||||
find_library(LIBSTORAGE_PATH NAMES ${LIBSTORAGE_NAMES} PATHS ${LOGOS_STORAGE_NIM_ROOT}/build NO_DEFAULT_PATH)
|
||||
|
||||
if(LIBSTORAGE_PATH)
|
||||
target_link_libraries(storageconsole PRIVATE ${LIBSTORAGE_PATH})
|
||||
else()
|
||||
message(WARNING "libstorage not found. Build or provide it before linking.")
|
||||
endif()
|
||||
|
||||
32
PROMPT.md
Normal file
32
PROMPT.md
Normal file
@ -0,0 +1,32 @@
|
||||
I want you to implement the API described in easylibstorage.h in a file name easylibstorage.c. This is a simplified
|
||||
wrapper on top of libstorage. You can find the headers for libstorage here:
|
||||
|
||||
- /home/giuliano/Work/Status/logos-storage-nim/library/libstorage.h
|
||||
|
||||
You can find examples of how to use libstorage here:
|
||||
|
||||
- /home/giuliano/Work/Status/logos-storage-nim/examples/c/examples.c
|
||||
|
||||
I want you to implement one function at a time. You MUST follow a Test Driven Development approach where you:
|
||||
|
||||
1. write a test for a function; (red)
|
||||
2. write the function;
|
||||
3. run it until your test is green; (green)
|
||||
4. stop, think of ways to refactor and simplify the code, and do it; (refactor)
|
||||
5. once you're done refactoring and the tests are green, move to the next function. This step is VERY IMPORTANT. You MUST look for ways to simplify,
|
||||
deduplicate, and coalesce code here, WITHOUT OVERCOMPLICATING. SIMPLICITY
|
||||
IS KEY AND YOUR GUIDING PRINCIPLE.
|
||||
|
||||
Feel free to use an idiomatic C way to write your unit tests, but DO NOT implement the next function before doing
|
||||
the full 1-5 cycle first. You need to follow the red-greed-refactor tenets of TDD.
|
||||
|
||||
Finally, I want you to wire all of the above in the console application under main.c. This console application must
|
||||
support the following commands:
|
||||
|
||||
- help (prints help)
|
||||
- start [API PORT] [DISCOVERY PORT] [BOOTSTRAP NODE] - creates and starts the node, all parameters are mandatory.
|
||||
- stop - stops and destroys the node
|
||||
- upload [LOCAL PATH] - uploads a local file to the node. Shows simple progress, prints the CID on screen when done.
|
||||
- download [CID] [LOCAL PATH] - downloads a remote CID to a local path. Shows simple progress, prints CID on screen when done.
|
||||
|
||||
If needed, the code for libstorage can also be found under /home/giuliano/Work/Status/logos-storage-nim/library.
|
||||
32
easylibstorage.h
Normal file
32
easylibstorage.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef STORAGECONSOLE_EASYLIBSTORAGE_H
|
||||
#define STORAGECONSOLE_EASYLIBSTORAGE_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define STORAGE_NODE void *
|
||||
#define CID char *
|
||||
|
||||
enum log_level {
|
||||
WARN,
|
||||
INFO,
|
||||
DEBUG,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int api_port;
|
||||
int disc_port;
|
||||
char *data_dir;
|
||||
char *log_level;
|
||||
char *bootstrap_node;
|
||||
} node_config;
|
||||
|
||||
typedef void (*progress_callback)(int total, int complete, int status);
|
||||
|
||||
STORAGE_NODE e_storage_new(node_config config);
|
||||
int e_storage_start(STORAGE_NODE node);
|
||||
int e_storage_stop(STORAGE_NODE node);
|
||||
int e_storage_destroy(STORAGE_NODE node);
|
||||
CID e_storage_upload(STORAGE_NODE node, FILE *input, progress_callback cb);
|
||||
STORAGE_NODE e_storage_download(STORAGE_NODE node, CID cid, FILE *output, progress_callback cb);
|
||||
|
||||
#endif // STORAGECONSOLE_EASYLIBSTORAGE_H
|
||||
103
main.c
Normal file
103
main.c
Normal file
@ -0,0 +1,103 @@
|
||||
#include "easylibstorage.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
void *ctx;
|
||||
} console;
|
||||
|
||||
typedef void (*fn)(void *, console *);
|
||||
|
||||
struct command {
|
||||
const char *name;
|
||||
const char *desc;
|
||||
fn command;
|
||||
};
|
||||
|
||||
int n_commands();
|
||||
static const struct command commands[];
|
||||
|
||||
void cmd_help(void *_, console *c) {
|
||||
printf("Commands:\n");
|
||||
for (int i = 0; i < n_commands(); i++) {
|
||||
printf(" [%s]: %s\n", commands[i].name, commands[i].desc);
|
||||
}
|
||||
}
|
||||
|
||||
void cmd_quit(void *_, console *c) {
|
||||
|
||||
}
|
||||
|
||||
void progress_print(int total, int complete, int status) {
|
||||
if (total > 0) {
|
||||
printf("\r %d / %d bytes", complete, total);
|
||||
} else {
|
||||
printf("\r %d bytes", complete);
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void cmd_start(void *args, console *c) {
|
||||
|
||||
}
|
||||
|
||||
void cmd_stop(void *args, console *c) {
|
||||
|
||||
}
|
||||
|
||||
void cmd_upload(void *args, console *c) {
|
||||
|
||||
}
|
||||
|
||||
void cmd_download(void *args, console *c) {
|
||||
|
||||
}
|
||||
|
||||
static const struct command commands[] = {
|
||||
{"help", "prints this help message", cmd_help},
|
||||
{"quit", "quits this program", cmd_quit},
|
||||
{"start", "[API PORT] [DISC PORT] [BOOTSTRAP NODE] creates and starts a node", cmd_start},
|
||||
{"stop", "stops and destroys the node", cmd_stop},
|
||||
{"upload", "[PATH] uploads a file to the node", cmd_upload},
|
||||
{"download", "[CID] [PATH] downloads content to a file", cmd_download},
|
||||
};
|
||||
|
||||
int n_commands() { return sizeof(commands) / sizeof(commands[0]); }
|
||||
|
||||
int main(void) {
|
||||
char buf[4096];
|
||||
console c;
|
||||
int i;
|
||||
|
||||
c.ctx = NULL;
|
||||
|
||||
while (1) {
|
||||
printf("> ");
|
||||
fflush(stdout);
|
||||
|
||||
if (!fgets(buf, sizeof(buf), stdin)) {
|
||||
break;
|
||||
}
|
||||
buf[strcspn(buf, "\n")] = 0;
|
||||
|
||||
char *cmd = strtok(buf, " ");
|
||||
if (cmd == NULL) {
|
||||
// user has input an empty string
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_commands(); i++) {
|
||||
if (strcmp(cmd, commands[i].name) == 0) {
|
||||
char *arg = strtok(NULL, " ");
|
||||
commands[i].command(arg, &c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == n_commands()) {
|
||||
printf("Invalid command %s\n", buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user