kerep sources

This commit is contained in:
2023-07-12 13:53:20 +03:00
parent 683395983c
commit 44ee9e210f
88 changed files with 3051 additions and 98 deletions

View File

@@ -0,0 +1,69 @@
#include "filesystem.h"
#include "io_includes.h"
#include "../kprint/kprint.h"
bool dir_exists(const char* path){
if(path[0]=='.'){
if(path[1]==0 || (path[1]==path_sep && path[1]==0))
return true; // dir . or ./ always exists
// else if(path[1]=='.' && path[2]==path_sep)
//TODO path_resolve because windows doesnt recognize .\ pattern
}
#if KFS_USE_WINDOWS_H
DWORD dwAttrib = GetFileAttributes(path);
return (bool)(
(dwAttrib != INVALID_FILE_ATTRIBUTES) && // file exists
(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); // file is a directory
#else
struct stat stats;
i32 rez=stat(path, &stats);
return (bool)(
(rez!=-1) && // file exists
(S_ISDIR(stats.st_mode))); // file is a directory
#endif
}
Maybe dir_create(const char* path){
if (dir_exists(path))
return MaybeNull;
char* parentDir=path_parentDir(path);
dir_create(parentDir);
free(parentDir);
#if KFS_USE_WINDOWS_H
if(!CreateDirectory(path, NULL))
#else
if(mkdir(path, 0777) == -1)
#endif
{
char err[512];
IFWIN(
sprintf_s(err, 512, "can't create dicectory <%s>", path),
sprintf(err, "can't create dicectory <%s>", path));
safethrow(err,;);
}
return MaybeNull;
}
Maybe dir_delete(const char* path){
throw(ERR_NOTIMPLEMENTED);
return MaybeNull;
}
Maybe dir_getFiles(const char* path, bool recursive){
throw(ERR_NOTIMPLEMENTED);
return MaybeNull;
}
Maybe dir_getDirs(const char* path, bool recursive){
throw(ERR_NOTIMPLEMENTED);
return MaybeNull;
}
Maybe dir_findFiles(const char* path, char* searchPattern, bool recursive){
throw(ERR_NOTIMPLEMENTED);
return MaybeNull;
}
Maybe dir_findDirs(const char* path, char* searchPattern, bool recursive){
throw(ERR_NOTIMPLEMENTED);
return MaybeNull;
}

View File

@@ -0,0 +1,28 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
#include "file.h"
bool dir_exists(const char* path);
///@return Maybe<void>
Maybe dir_create(const char* path);
///@return Maybe<void>
Maybe dir_delete(const char* path);
///@return Maybe<char**>
Maybe dir_getFiles(const char* path, bool recursive);
///@return Maybe<char**>
Maybe dir_getDirs(const char* path, bool recursive);
///@return Maybe<char**>
Maybe dir_findFiles(const char* path, char* searchPattern, bool recursive);
///@return Maybe<char**>
Maybe dir_findDirs(const char* path, char* searchPattern, bool recursive);
#if __cplusplus
}
#endif

138
kerep/src/Filesystem/file.c Normal file
View File

@@ -0,0 +1,138 @@
#include "filesystem.h"
#include "../String/StringBuilder.h"
#include "io_includes.h"
void __file_freeMembers(void* _f){ fclose((FileHandle)_f); }
kt_define(FileHandle, __file_freeMembers, NULL)
bool file_exists(const char* path){
if(path[0]=='.'){
if(path[1]==0 || (path[1]==path_sep && path[2]==0))
return false; // . or ./ is not a file
// else if(path[1]=='.' && path[2]==path_sep)
//TODO path_resolve because windows doesnt recognize .\ pattern
}
#if KFS_USE_WINDOWS_H
DWORD dwAttrib = GetFileAttributes(path);
return (bool)(
(dwAttrib != INVALID_FILE_ATTRIBUTES) && // file exists
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); // file is not directory
#else
struct stat stats;
i32 rez=stat(path, &stats);
return (bool)(
(rez!=-1) && // file exists
!(S_ISDIR(stats.st_mode))); // file is not directory
#endif
}
Maybe file_delete(const char* path, bool recursive){
throw(ERR_NOTIMPLEMENTED);
return MaybeNull;
}
char* FileOpenMode_toStr(FileOpenMode m){
char* p;
switch(m){
case FileOpenMode_Read: p="rb"; break;
case FileOpenMode_Write: p="wb"; break;
case FileOpenMode_Append: p="ab"; break;
case FileOpenMode_ReadWrite: p="wb+"; break;
case FileOpenMode_ReadAppend: p="ab+"; break;
default:
dbg(m);
throw(ERR_UNEXPECTEDVAL);
}
return p;
}
Maybe file_open(const char* path, FileOpenMode mode){
FileHandle file=fopen(path, FileOpenMode_toStr(mode));
if(!file)
safethrow(cptr_concat("can't open file ", (char*)path),;);
return SUCCESS(UniHeapPtr(FileHandle,file));
}
Maybe file_close(FileHandle file){
if(!file)
safethrow(ERR_NULLPTR,;);
if(fclose(file))
safethrow(ERR_IO,;);
return MaybeNull;
}
#define ioWriteCheck() \
if(rezult==EOF) \
safethrow(ERR_IO_EOF,;); \
if(rezult!=0) \
safethrow(ERR_IO,;);
Maybe file_writeChar(FileHandle file, char byte){
i32 rezult=fputc(byte, file);
ioWriteCheck();
return MaybeNull;
}
Maybe file_writeBuffer(FileHandle file, char* buffer, u64 length){
i32 rezult=0;
for(u64 i=0; i<length && !rezult; i++)
rezult=fputc(buffer[i], file);
ioWriteCheck();
return MaybeNull;
}
Maybe file_writeCptr(FileHandle file, char* cptr){
i32 rezult=fputs(cptr, file);
ioWriteCheck();
return MaybeNull;
}
Maybe file_readChar(FileHandle file){
i32 rezult=fgetc(file);
if(feof(file)) safethrow(ERR_IO_EOF,;);
if(ferror(file)) safethrow(ERR_IO,;);
return SUCCESS(UniUInt64(rezult));
}
Maybe file_readBuffer(FileHandle file, char* buffer, u64 length){
i32 rezult=0;
u64 i=0;
for(; i<length && rezult!=EOF; i++){
rezult=fgetc(file);
buffer[i]=(char)rezult;
}
if(ferror(file)) safethrow(ERR_IO,;);
return SUCCESS(UniUInt64(i));
}
Maybe file_readAll(FileHandle file, char** allBytes){
i32 rezult=0;
char buffer[256];
string bufStr={.ptr=buffer, .length=sizeof(buffer)};
StringBuilder* sb=StringBuilder_create();
u64 i=0;
while(true){
rezult=fgetc(file);
if(rezult==EOF){
if(ferror(file))
safethrow(ERR_IO, StringBuilder_free(sb));
break;
}
buffer[i%sizeof(buffer)]=(char)rezult;
i++;
if(!(i%sizeof(buffer)))
StringBuilder_append_string(sb,bufStr);
}
bufStr.length=i%sizeof(buffer);
if(bufStr.length!=0)
StringBuilder_append_string(sb,bufStr);
string str=StringBuilder_build(sb);
*allBytes=str.ptr;
// i dont know how can it happen, but if it will have, it will be very dangerous
if(i!=str.length)
throw(ERR_UNEXPECTEDVAL);
return SUCCESS(UniUInt64(i));
}

View File

@@ -0,0 +1,75 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
#include "../String/string.h"
typedef FILE* FileHandle;
kt_declare(FileHandle);
bool file_exists(const char* path);
///@return Maybe<void>
Maybe file_delete(const char* path, bool recursive);
PACKED_ENUM(FileOpenMode,
// open a file for reading
FileOpenMode_Read=1,
// (re)create a file for writing
FileOpenMode_Write=2,
// opens file for writing additional data to the end / creates new file
FileOpenMode_Append=4,
// (re)creates file for reading/writing
FileOpenMode_ReadWrite=FileOpenMode_Read|FileOpenMode_Write,
// opens file for readng/writing additional data to the end / creates new file
FileOpenMode_ReadAppend=FileOpenMode_Read|FileOpenMode_Append
)
/// @brief opens file
/// @param path path to file
/// @param mode Read/Write/Append/ReadWrite/ReadAppend
/// @return Maybe<FileHandle>
Maybe file_open(const char* path, FileOpenMode mode);
/// @brief closes file descriptor
/// @return Maybe<void>
Maybe file_close(FileHandle file);
/// @brief closes file descriptor
/// @param byte byte to write
/// @return Maybe<void>
Maybe file_writeChar(FileHandle file, char byte);
/// @brief closes file descriptor
/// @param buffer bytes to write
/// @param length buffer length
/// @return Maybe<void>
Maybe file_writeBuffer(FileHandle file, char* buffer, u64 length);
/// @brief writes all cstring array content to file
/// @param cptr zero-terminated cstring
/// @return Maybe<void>
Maybe file_writeCptr(FileHandle file, char* cptr);
/// @brief reads single byte from file
/// @return Maybe<char>
Maybe file_readChar(FileHandle file);
/// @brief reads byte array of specofied length
/// @param buffer buffer that will be filled with file bytes
/// @param length buffer length
/// @return Maybe<u64> total number of successfully read bytes (<=length)
Maybe file_readBuffer(FileHandle file, char* buffer, u64 length);
/// @brief reads all bytes from file
/// @param allBytes ptr to the file's content will be pushed there
/// @return Maybe<u64> total number of successfully read bytes
Maybe file_readAll(FileHandle file, char** allBytes);
#if __cplusplus
}
#endif

View File

@@ -0,0 +1,3 @@
#include "path.h"
#include "dir.h"
#include "file.h"

View File

@@ -0,0 +1,15 @@
#include "../base/std.h"
#if defined(_WIN64) || defined(_WIN32)
#define KFS_USE_WINDOWS_H 1
#else
#define KFS_USE_WINDOWS_H 0
#endif
#if KFS_USE_WINDOWS_H
#include <windows.h>
#else
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#endif

View File

@@ -0,0 +1,84 @@
#include "filesystem.h"
char* __path_concat(u32 n, ...){
char** parts=(char**)malloc(n*sizeof(char*));
u32* lengths=malloc(n*sizeof(u32));
u32 totalLength=0;
// reading args from va_list
va_list vl;
va_start(vl, n);
for(u16 i=0; i<n; i++){
char* part=va_arg(vl,char*);
i16 length=cptr_length(part);
parts[i]=part;
lengths[i]=length;
totalLength+=length;
}
va_end(vl);
// allocating memory for output value
char* totality=malloc(totalLength+1);
const char* output=totality;
totality[totalLength]=0;
// copying content of all strings to rezult
u16 k=0;
for(; k<n-1; k++){
memcopy(parts[k], totality, lengths[k]);
totality+=lengths[k];
*totality=path_sep;
totality++;
}
memcopy(parts[k], totality, lengths[k]);
free(parts);
free(lengths);
return output;
}
char* path_fixSeparators(const char* path){
char* pathCopy=cptr_copy(path);
char c;
while((c=*pathCopy)){
if(c==path_notSep)
*pathCopy=path_sep;
pathCopy++;
}
return pathCopy;
}
Maybe path_throwIfEscapes(const char* path){
if(cptr_contains(path,".."))
safethrow(cptr_concat("path <",path,"> uses <..>, that's not allowed"),);
return MaybeNull;
}
char* path_parentDir(char* dir){
char* copy=cptr_copy(dir);
i32 length=cptr_length(copy);
i32 i=cptr_lastIndexOfChar(copy,path_sep);
if(i!=-1 && i==length-1){
copy[length-1]=0;
i=cptr_lastIndexOfChar(copy,path_sep);
}
if(i==-1){
free(copy);
copy=malloc(2);
copy[0]='.';
copy[1]=0;
}
return copy;
}
char* path_basename(char* path, bool with_extension){
i32 nameIndex=cptr_lastIndexOfChar(path, path_sep)+1;
string rezult=string_fromCptr(path+nameIndex);
if(!with_extension){
i32 extIndex=cptr_lastIndexOfChar(rezult.ptr, '.');
if(extIndex!=0 && extIndex!=-1)
rezult.length=extIndex;
}
return string_extract(rezult);
}

View File

@@ -0,0 +1,42 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
#if defined(_WIN32) || defined (_WIN64)
static const char path_sep='\\';
static const char path_notSep='/';
#else
static const char path_sep='/';
static const char path_notSep='\\';
#endif
char* __path_concat(u32 n, ...);
/// @brief merges path parts together and puts <path_sep> between them
/// @return new cstr
#define path_concat(PATH_PARTS...) __path_concat(count_args(PATH_PARTS), PATH_PARTS)
/// @brief fixes path separators
/// @param cstr where can be <path_notSep>
/// @return new cstr with correct separators
char* path_fixSeparators(const char* path);
#define path_resolve(PATH_PARTS...) path_fixSeparators(path_concat(PATH_PARTS))
/// @brief calls safethrow() if finds escape sequense in path
/// @param path cstr where can be <..>
/// @return Maybe<void>
Maybe path_throwIfEscapes(const char* path);
///@return path of parent dir
char* path_parentDir(char* path);
///@return file name
char* path_basename(char* path, bool with_extension);
#if __cplusplus
}
#endif