Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft: new scalar filtering #398

Closed
wants to merge 61 commits into from
Closed
Show file tree
Hide file tree
Changes from 56 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
acbc6ea
[refac] move node type enum and struct to different header
biojppm Feb 11, 2023
3c0c7b7
[wip] separating the filter code to a different class
biojppm Mar 1, 2023
f7bc287
wip
biojppm Jul 10, 2023
4cdfe06
wip
biojppm Jul 10, 2023
30ab168
wip
biojppm Jul 10, 2023
457649e
filter single quoted is working
biojppm Jul 13, 2023
bf4b825
refactor to filter processor wip
biojppm Jul 13, 2023
8026f42
double quoted wip
biojppm Jul 14, 2023
4d1ee1b
double quoted wip
biojppm Jul 16, 2023
c2f7d29
double quoted wip
biojppm Jul 17, 2023
0e15368
double quoted wip
biojppm Jul 17, 2023
82c42a7
double quoted wip
biojppm Jul 19, 2023
b8081fa
double quoted wip
biojppm Jul 19, 2023
3d08136
double quoted wip
biojppm Jul 20, 2023
17f2c43
double quoted seems to be working
biojppm Jul 22, 2023
922be40
double quoted wip
biojppm Sep 5, 2023
a4090da
double quoted wip
biojppm Sep 5, 2023
afd1c99
double quoted wip
biojppm Sep 11, 2023
41b13a8
double quoted wip
biojppm Sep 11, 2023
3989d85
double quoted wip
biojppm Sep 24, 2023
42ccf2c
double quoted wip
biojppm Sep 24, 2023
840b89e
double quoted working!
biojppm Sep 26, 2023
bb01856
filter plain scalar wip
biojppm Sep 27, 2023
316d66d
wip
biojppm Oct 2, 2023
8bb569c
filter plain scalar wip
biojppm Oct 15, 2023
474cbfb
wip
biojppm Oct 22, 2023
15e8d39
test filter processors
biojppm Oct 24, 2023
c425ec3
fix write in inplace::translate_esc
biojppm Oct 25, 2023
9460fab
block literal wip
biojppm Oct 27, 2023
aff48eb
block literal wip
biojppm Oct 27, 2023
c7d6cc3
block literal wip
biojppm Oct 28, 2023
3a6b329
block literal wip
biojppm Nov 1, 2023
b5fbe86
block literal wip
biojppm Nov 1, 2023
e9ca82f
block literal wip
biojppm Nov 1, 2023
6d2a0f1
block literal working!
biojppm Nov 4, 2023
42f1800
filter block folded wip
biojppm Nov 4, 2023
92aed7b
filter block folded wip
biojppm Nov 5, 2023
f132247
cleanup filter
biojppm Nov 7, 2023
be16ee2
filter locations are needed only for double quoted scalars
biojppm Nov 7, 2023
b401e10
add FilterResult to encapsulate validity
biojppm Nov 7, 2023
62e6795
prepare filter for using in parser
biojppm Nov 8, 2023
ec19cd7
in-parser filtering wip
biojppm Nov 8, 2023
0ace3aa
filter empty block literals
biojppm Dec 12, 2023
63eb54e
filter block folded ok
biojppm Dec 21, 2023
a3a200e
all filters working
biojppm Dec 21, 2023
c453490
moving filters to parse wip
biojppm Dec 22, 2023
4259377
fix block_folded
biojppm Dec 25, 2023
9d37093
fixing block folded WIP
biojppm Dec 27, 2023
1ffaf62
new filter: all tests passing!
biojppm Dec 27, 2023
f161e77
fix sanitizer issues
biojppm Dec 27, 2023
7968280
refactor: harmonize parser filtering function names
biojppm Jan 10, 2024
5d1ed26
wip ci fixes
biojppm Jan 11, 2024
8dd234c
coverage wip
biojppm Jan 14, 2024
816fab5
filter arena no longer needed
biojppm Jan 23, 2024
e7b0662
double quoted filter wip
biojppm Jan 23, 2024
6b9d5d9
fix wip
biojppm Jan 25, 2024
7bbd5ab
fix wip
biojppm Jan 25, 2024
418f0fe
fix wip
biojppm Jan 25, 2024
3f8d8e5
wip: inplace mid-extending vs end-extending
biojppm Jan 26, 2024
32d06f0
all tests ok
biojppm Jan 31, 2024
79905ac
missing export
biojppm Feb 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ build/
install/
.python-version
compile_commands.json
launch.json

# test files
/Testing/
Expand Down
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ c4_add_library(ryml
c4/yml/common.cpp
c4/yml/emit.def.hpp
c4/yml/emit.hpp
c4/yml/filter_processor.hpp
c4/yml/export.hpp
c4/yml/node.hpp
c4/yml/node.cpp
c4/yml/node_type.hpp
c4/yml/parse.hpp
c4/yml/parse.cpp
c4/yml/preprocess.hpp
Expand Down
2 changes: 1 addition & 1 deletion ext/c4core
31 changes: 23 additions & 8 deletions samples/quickstart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,26 +138,32 @@ namespace sample {
bool report_check(int line, const char *predicate, bool result);
#ifdef __GNUC__
#if __GNUC__ == 4 && __GNUC_MINOR__ >= 8
struct CheckPredicate {
#define CHECK CheckPredicate{__FILE__, __LINE__}
struct CheckPredicate
{
const char *file;
const int line;

void operator() (bool predicate) const
{
if (!report_check(line, nullptr, predicate))
{
#ifdef RYML_DBG
RYML_DEBUG_BREAK();
#endif
}
}
};
#define CHECK CheckPredicate{__FILE__, __LINE__}
#endif
#endif

#if !defined(CHECK)
#ifndef CHECK
#ifndef RYML_DBG
/// a quick'n'dirty assertion to verify a predicate
#define CHECK(predicate) report_check(__LINE__, #predicate, (predicate))
#else
#define CHECK(predicate) do { if(!report_check(__LINE__, #predicate, (predicate))) { RYML_DEBUG_BREAK(); } } while(0)
#endif
#endif


//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -3877,19 +3883,28 @@ void sample_error_handler()
struct GlobalAllocatorExample
{
std::vector<char> memory_pool = std::vector<char>(10u * 1024u); // 10KB
size_t num_allocs = 0, alloc_size = 0;
size_t num_allocs = 0, alloc_size = 0, corr_size = 0;
size_t num_deallocs = 0, dealloc_size = 0;

void *allocate(size_t len)
{
void *ptr = &memory_pool[alloc_size];
alloc_size += len;
++num_allocs;
if(C4_UNLIKELY(alloc_size > memory_pool.size()))
// ensure the ptr is aligned
uintptr_t uptr = (uintptr_t)ptr;
const uintptr_t align = alignof(max_align_t);
if (uptr % align)
{
std::cerr << "out of memory! requested=" << alloc_size << " vs " << memory_pool.size() << " available" << std::endl;
std::abort();
uintptr_t prev = uptr - (uptr % align);
uintptr_t next = prev + align;
uintptr_t corr = next - uptr;
ptr = (void*)(((char*)ptr) + corr);
corr_size += corr;
}
C4_CHECK_MSG(alloc_size + corr_size <= memory_pool.size(),
"out of memory! requested=%zu+%zu available=%zu\n",
alloc_size, corr_size, memory_pool.size());
return ptr;
}

Expand Down
6 changes: 3 additions & 3 deletions src/c4/yml/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ Callbacks::Callbacks(void *user_data, pfn_allocate alloc_, pfn_free free_, pfn_e
m_error(error_)
#endif
{
C4_CHECK(m_allocate);
C4_CHECK(m_free);
C4_CHECK(m_error);
RYML_CHECK(m_allocate);
RYML_CHECK(m_free);
RYML_CHECK(m_error);
}


Expand Down
102 changes: 93 additions & 9 deletions src/c4/yml/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@
#include <c4/yml/export.hpp>




#include <cstdio>


#ifndef RYML_ERRMSG_SIZE
/// size for the error message buffer
#define RYML_ERRMSG_SIZE 1024
#endif


#ifndef RYML_USE_ASSERT
# define RYML_USE_ASSERT C4_USE_ASSERT
#endif
Expand All @@ -20,24 +31,26 @@
#endif


#if defined(NDEBUG) || defined(C4_NO_DEBUG_BREAK)
#ifndef RYML_DBG
# define RYML_DEBUG_BREAK()
#elif (defined(NDEBUG) || defined(C4_NO_DEBUG_BREAK))
# define RYML_DEBUG_BREAK()
#else
# define RYML_DEBUG_BREAK() \
{ \
do { \
if(c4::get_error_flags() & c4::ON_ERROR_DEBUGBREAK) \
{ \
C4_DEBUG_BREAK(); \
} \
}
} while(0)
#endif


#define RYML_CHECK(cond) \
do { \
if(!(cond)) \
{ \
RYML_DEBUG_BREAK() \
RYML_DEBUG_BREAK(); \
c4::yml::error("check failed: " #cond, c4::yml::Location(__FILE__, __LINE__, 0)); \
} \
} while(0)
Expand All @@ -47,7 +60,7 @@
{ \
if(!(cond)) \
{ \
RYML_DEBUG_BREAK() \
RYML_DEBUG_BREAK(); \
c4::yml::error(msg ": check failed: " #cond, c4::yml::Location(__FILE__, __LINE__, 0)); \
} \
} while(0)
Expand Down Expand Up @@ -197,7 +210,7 @@ RYML_EXPORT void reset_callbacks();
do \
{ \
const char msg[] = msg_literal; \
RYML_DEBUG_BREAK() \
RYML_DEBUG_BREAK(); \
(cb).m_error(msg, sizeof(msg), c4::yml::Location(__FILE__, 0, __LINE__, 0), (cb).m_user_data); \
} while(0)
#define _RYML_CB_CHECK(cb, cond) \
Expand All @@ -206,7 +219,7 @@ do \
if(!(cond)) \
{ \
const char msg[] = "check failed: " #cond; \
RYML_DEBUG_BREAK() \
RYML_DEBUG_BREAK(); \
(cb).m_error(msg, sizeof(msg), c4::yml::Location(__FILE__, 0, __LINE__, 0), (cb).m_user_data); \
} \
} while(0)
Expand Down Expand Up @@ -236,27 +249,61 @@ struct _charconstant_t
} // namespace detail


typedef enum {
BLOCK_LITERAL, //!< keep newlines (|)
BLOCK_FOLD //!< replace newline with single space (>)
} BlockStyle_e;

typedef enum {
CHOMP_CLIP, //!< single newline at end (default)
CHOMP_STRIP, //!< no newline at end (-)
CHOMP_KEEP //!< all newlines from end (+)
} BlockChomp_e;


/** Abstracts the fact that a filter result may not fit in the intended memory. */
struct FilterResult
{
C4_ALWAYS_INLINE bool valid() const noexcept { return str.str != nullptr; }
C4_ALWAYS_INLINE size_t required_len() const noexcept { return str.len; }
C4_ALWAYS_INLINE csubstr get() { RYML_ASSERT(valid()); return str; }
csubstr str;
};
/** Abstracts the fact that a filter result may not fit in the intended memory. */
struct FilterResultInPlace
{
C4_ALWAYS_INLINE bool valid() const noexcept { return str.str != nullptr; }
C4_ALWAYS_INLINE size_t required_len() const noexcept { return reqlen; }
C4_ALWAYS_INLINE csubstr get() { RYML_ASSERT(valid()); return str; }
csubstr str;
size_t reqlen;
};


namespace detail {
struct _SubstrWriter
{
substr buf;
size_t pos;
_SubstrWriter(substr buf_, size_t pos_=0) : buf(buf_), pos(pos_) {}
_SubstrWriter(substr buf_, size_t pos_=0) : buf(buf_), pos(pos_) { C4_ASSERT(buf.str); }
void append(csubstr s)
{
C4_ASSERT(!s.overlaps(buf));
if(pos + s.len <= buf.len)
C4_ASSERT(s.str || !s.len);
if(s.len && pos + s.len <= buf.len)
memcpy(buf.str + pos, s.str, s.len);
pos += s.len;
}
void append(char c)
{
C4_ASSERT(buf.str);
if(pos < buf.len)
buf.str[pos] = c;
++pos;
}
void append_n(char c, size_t numtimes)
{
C4_ASSERT(buf.str);
if(pos + numtimes < buf.len)
memset(buf.str + pos, c, numtimes);
pos += numtimes;
Expand All @@ -274,6 +321,43 @@ struct _SubstrWriter

/// @endcond


//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

template<class DumpFn, class ...Args>
C4_NO_INLINE void _parse_dump(DumpFn dumpfn, csubstr fmt, Args&& ...args)
{
char writebuf[256];
auto results = format_dump_resume(dumpfn, writebuf, fmt, std::forward<Args>(args)...);
// resume writing if the results failed to fit the buffer
if(C4_UNLIKELY(results.bufsize > sizeof(writebuf))) // bufsize will be that of the largest element serialized. Eg int(1), will require 1 byte.
{
results = format_dump_resume(dumpfn, results, writebuf, fmt, std::forward<Args>(args)...);
if(C4_UNLIKELY(results.bufsize > sizeof(writebuf)))
{
results = format_dump_resume(dumpfn, results, writebuf, fmt, std::forward<Args>(args)...);
C4_CHECK(results.bufsize <= sizeof(writebuf));
}
}
}
template<class ...Args>
void _report_err(Callbacks const& C4_RESTRICT callbacks, Location const& C4_RESTRICT loc, csubstr fmt, Args const& C4_RESTRICT ...args)
{
char errmsg[RYML_ERRMSG_SIZE];
detail::_SubstrWriter writer(errmsg);
auto dumpfn = [&writer](csubstr s){ writer.append(s); };
_parse_dump(dumpfn, fmt, args...);
writer.append('\n');
if(loc.name.len)
_parse_dump(dumpfn, "{}:", loc.name);
_parse_dump(dumpfn, "{}:{}: ", loc.line, loc.col);
size_t len = writer.pos < RYML_ERRMSG_SIZE ? writer.pos : RYML_ERRMSG_SIZE;
printf("AQUI 0\n");
callbacks.m_error(errmsg, len, loc, callbacks.m_user_data);
}

C4_SUPPRESS_WARNING_GCC_CLANG_POP

} // namespace yml
Expand Down
25 changes: 17 additions & 8 deletions src/c4/yml/detail/parser_dbg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"

// some debugging scaffolds
#ifdef RYML_DBG
#include <c4/dump.hpp>
#ifdef RYML_DBG
namespace c4 {
inline void _dbg_dumper(csubstr s) { fwrite(s.str, 1, s.len, stdout); };
inline void _dbg_dumper(csubstr s)
{
if(s.str)
fwrite(s.str, 1, s.len, stdout);
}
template<class ...Args>
void _dbg_printf(c4::csubstr fmt, Args&& ...args)
{
Expand All @@ -50,21 +54,24 @@ void _dbg_printf(c4::csubstr fmt, Args&& ...args)
# define _c4dbgp(msg) _dbg_printf("{}:{}: " msg "\n", __FILE__, __LINE__ )
# define _c4dbgq(msg) _dbg_printf(msg "\n")
# define _c4err(fmt, ...) \
do { if(c4::is_debugger_attached()) { C4_DEBUG_BREAK(); } \
this->_err("ERROR:\n" "{}:{}: " fmt, __FILE__, __LINE__, ## __VA_ARGS__); } while(0)
do { RYML_DEBUG_BREAK(); this->_err("ERROR:\n" "{}:{}: " fmt, __FILE__, __LINE__, ## __VA_ARGS__); } while(0)
#else
# define _c4dbgt(fmt, ...)
# define _c4dbgpf(fmt, ...)
# define _c4dbgp(msg)
# define _c4dbgq(msg)
# define _c4err(fmt, ...) \
do { if(c4::is_debugger_attached()) { C4_DEBUG_BREAK(); } \
this->_err("ERROR: " fmt, ## __VA_ARGS__); } while(0)
this->_err("ERROR: " fmt, ## __VA_ARGS__)
#endif


//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

#define _c4prsp(sp) sp
#define _c4presc(s) __c4presc(s.str, s.len)
inline c4::csubstr _c4prc(const char &C4_RESTRICT c)
inline c4::csubstr _c4prc(const char &C4_RESTRICT c) // pass by reference!
{
switch(c)
{
Expand All @@ -81,6 +88,7 @@ inline c4::csubstr _c4prc(const char &C4_RESTRICT c)
}
inline void __c4presc(const char *s, size_t len)
{
RYML_ASSERT(s || !len);
size_t prev = 0;
for(size_t i = 0; i < len; ++i)
{
Expand Down Expand Up @@ -123,7 +131,8 @@ inline void __c4presc(const char *s, size_t len)
}
}
}
fwrite(s + prev, 1, len - prev, stdout);
if(len > prev)
fwrite(s + prev, 1, len - prev, stdout);
}

#pragma clang diagnostic pop
Expand Down
1 change: 1 addition & 0 deletions src/c4/yml/detail/stack.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ void stack<T, N>::reserve(size_t sz)
return;
}
T *buf = (T*) m_callbacks.m_allocate(sz * sizeof(T), m_stack, m_callbacks.m_user_data);
RYML_ASSERT(((uintptr_t)buf % alignof(T)) == 0u);
memcpy(buf, m_stack, m_size * sizeof(T));
if(m_stack != m_buf)
{
Expand Down
4 changes: 2 additions & 2 deletions src/c4/yml/emit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@

#define RYML_DEPRECATE_EMIT \
RYML_DEPRECATED("use emit_yaml() instead. See https://github.com/biojppm/rapidyaml/issues/120")
#define RYML_DEPRECATE_EMITRS \
RYML_DEPRECATED("use emitrs_yaml() instead. See https://github.com/biojppm/rapidyaml/issues/120")
#ifdef emit
#error "emit is defined, likely from a Qt include. This will cause a compilation error. See https://github.com/biojppm/rapidyaml/issues/120"
#endif
#define RYML_DEPRECATE_EMITRS \
RYML_DEPRECATED("use emitrs_yaml() instead. See https://github.com/biojppm/rapidyaml/issues/120")


//-----------------------------------------------------------------------------
Expand Down
Loading
Loading