2021-02-14 01:59:06 +01:00
|
|
|
#pragma once
|
2021-02-28 19:22:54 +01:00
|
|
|
#include <cstdint>
|
|
|
|
#include <cstdio>
|
|
|
|
#include <cstdlib>
|
2021-02-14 01:59:06 +01:00
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
namespace ss {
|
|
|
|
|
|
|
|
struct none {};
|
|
|
|
|
|
|
|
using string_range = std::pair<const char*, const char*>;
|
|
|
|
using split_data = std::vector<string_range>;
|
|
|
|
|
|
|
|
constexpr inline auto default_delimiter = ",";
|
2024-02-19 01:16:19 +01:00
|
|
|
constexpr static auto get_line_initial_buffer_size = 128;
|
2021-02-14 01:59:06 +01:00
|
|
|
|
|
|
|
template <bool StringError>
|
|
|
|
inline void assert_string_error_defined() {
|
|
|
|
static_assert(StringError,
|
|
|
|
"'string_error' needs to be enabled to use 'error_msg'");
|
|
|
|
}
|
|
|
|
|
2023-08-04 16:48:07 +02:00
|
|
|
template <bool ThrowOnError>
|
|
|
|
inline void assert_throw_on_error_not_defined() {
|
|
|
|
static_assert(!ThrowOnError, "cannot handle errors manually if "
|
|
|
|
"'throw_on_error' is enabled");
|
|
|
|
}
|
|
|
|
|
2021-02-21 22:25:58 +01:00
|
|
|
#if __unix__
|
2024-02-17 00:55:36 +01:00
|
|
|
inline ssize_t get_line_file(char** lineptr, size_t* n, FILE* stream) {
|
2021-02-21 22:25:58 +01:00
|
|
|
return getline(lineptr, n, stream);
|
|
|
|
}
|
|
|
|
#else
|
2021-02-21 22:22:18 +01:00
|
|
|
using ssize_t = int64_t;
|
2024-02-17 01:07:29 +01:00
|
|
|
inline ssize_t get_line_file(char** lineptr, size_t* n, FILE* stream) {
|
2021-02-21 22:22:18 +01:00
|
|
|
size_t pos;
|
|
|
|
int c;
|
|
|
|
|
|
|
|
if (lineptr == nullptr || stream == nullptr || n == nullptr) {
|
|
|
|
errno = EINVAL;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
c = getc(stream);
|
|
|
|
if (c == EOF) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*lineptr == nullptr) {
|
2024-02-19 01:16:19 +01:00
|
|
|
*lineptr = static_cast<char*>(malloc(get_line_initial_buffer_size));
|
2021-02-21 22:22:18 +01:00
|
|
|
if (*lineptr == nullptr) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
*n = 128;
|
|
|
|
}
|
|
|
|
|
|
|
|
pos = 0;
|
|
|
|
while (c != EOF) {
|
|
|
|
if (pos + 1 >= *n) {
|
|
|
|
size_t new_size = *n + (*n >> 2);
|
2024-02-19 01:16:19 +01:00
|
|
|
if (new_size < get_line_initial_buffer_size) {
|
|
|
|
new_size = get_line_initial_buffer_size;
|
2021-02-21 22:22:18 +01:00
|
|
|
}
|
|
|
|
char* new_ptr = static_cast<char*>(
|
|
|
|
realloc(static_cast<void*>(*lineptr), new_size));
|
|
|
|
if (new_ptr == nullptr) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
*n = new_size;
|
|
|
|
*lineptr = new_ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
(*lineptr)[pos++] = c;
|
|
|
|
if (c == '\n') {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
c = getc(stream);
|
|
|
|
}
|
|
|
|
|
|
|
|
(*lineptr)[pos] = '\0';
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-02-14 01:59:06 +01:00
|
|
|
} /* ss */
|