#ifdef __unix__
# define _POSIX_SOURCE
# include<unistd.h>
# include<fcntl.h>
# include<sys/stat.h>
#endif
#include<lexlib/str.h>
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#ifdef _WIN32
# define SEP '\\'
#else
# define SEP '/'
#endif
#if __GNUC__
__attribute__((alias("lexlibStrCopy"))) char *lexlibStrNew(const char *str);
#else
char *lexlibStrNew(const char *str){return lexlibStrCopy(str);}
#endif
char *lexlibStrCat(const char *str1, const char *str2){
char *str = NULL;
if(!str1 || !str2)
return NULL;
size_t len = strlen(str1) + strlen(str2) + 1;
str = calloc(len, sizeof(char));
if(!str)
return NULL;
strcat(str, str1);
strcat(str, str2);
str[len-1] = '\0';
return str;
}
char *lexlibStrCopy(const char *str){
char *new = NULL;
size_t len = strlen(str) + 1;
new = malloc(len * sizeof(char));
if(!new)
return NULL;
memcpy(new, str, len);
return new;
}
char *lexlibStrFile(const char *filename){
char *buffer = NULL;
unsigned long length = 0;
FILE *file = fopen(filename, "r");
if(!file){
return NULL;
}
#ifdef __unix__
struct stat info;
if(fstat(fileno(file), &info) != 0){
fclose(file);
return NULL;
}
length = info.st_size;
#else
if(fseek(file, 0, SEEK_END) != 0){
fclose(file);
return NULL;
};
length = ftell(file);
if(fseek(file, 0, SEEK_SET) != 0){
fclose(file);
return NULL;
};
#endif
buffer = malloc(length+1);
if(!buffer){
fclose(file);
return NULL;
}
buffer[length] = '\0';
if(fread(buffer, sizeof(char), length, file) != length){
free(buffer);
fclose(file);
return NULL;
}
fclose(file);
return buffer;
}
char *lexlibStrPathNew(const char *str){
size_t len = strlen(str);
char *path = calloc(len+1, sizeof(char));
if(!path)
return NULL;
for(size_t i = 0; i < len; i++){
char chr = str[i];
if(chr == '/' || chr == '\\')
chr = SEP;
path[i] = chr;
}
return path;
}
uint8_t lexlibStrPathPush(char **str, const char *add){
size_t strLen = strlen(*str);
size_t addLen = strlen(add);
size_t len = strLen + addLen;
if(strLen == 0 || addLen == 0)
return LEXLIB_INVALID_VALUE;
char *path = realloc(*str, (len+2) * sizeof(char));
char *offPath = path+strLen;
if(!path)
return LEXLIB_OUT_OF_MEMORY;
if(path[strLen-1] != '/' && path[strLen-1] != '\\'){
offPath++;
path[strLen] = SEP;
}
for(size_t i = 0; i < addLen; i++){
char chr = add[i];
if(chr == '/' || chr == '\\'){
if(i == 0){
offPath--;
}
chr = SEP;
}
offPath[i] = chr;
}
offPath[addLen] = '\0';
*str = path;
return LEXLIB_OK;
}
uint8_t lexlibStrPathPop(char **str){
size_t len = 0;
char *fst;
char *lst;
fst = strchr(*str, '/');
if(!fst)
fst = strchr(*str, '\\');
lst = strrchr(*str, '/');
if(!lst)
lst = strrchr(*str, '\\');
if(!fst || !lst)
return LEXLIB_INVALID_OPERATION;
if(fst == lst)
return LEXLIB_INVALID_OPERATION;
len = strlen(lst);
memset(lst, 0, len);
return LEXLIB_OK;
}
uint8_t lexlibStrPathAsDir(char **str){
size_t len = strlen(*str);
if(len == 0)
return LEXLIB_INVALID_VALUE;
if((*str)[len-1] == '/' || (*str)[len-1] == '\\')
return LEXLIB_OK;
char *new = realloc(*str, (len+2) * sizeof(char));
if(!new)
return LEXLIB_OUT_OF_MEMORY;
new[len+1] = '\0';
new[len] = SEP;
*str = new;
return LEXLIB_OK;
}
uint8_t lexlibStrPathAsFile(char **str){
size_t len = strlen(*str);
if(len == 0)
return LEXLIB_INVALID_VALUE;
len--;
if((*str)[len] == '/' || (*str)[len] == '\\')
(*str)[len] = '\0';
else
return LEXLIB_OK;
return LEXLIB_OK;
}