scm/c++: fix review issues in handler code
- Fix comments and some debug strings (copy-pasta) - Fix mime-stream destruction (g_object_unref) - Fix type-checking of scm types
This commit is contained in:
@ -46,7 +46,7 @@ static const Message&
|
||||
to_message(SCM scm, const char *func, int pos)
|
||||
{
|
||||
if (!SCM_IS_A_P(scm, message_type))
|
||||
throw ScmError{ScmError::Id::WrongType, func, pos, scm, "mesagestore"};
|
||||
throw ScmError{ScmError::Id::WrongType, func, pos, scm, "message"};
|
||||
|
||||
return *reinterpret_cast<Message*>(scm_foreign_object_ref(scm, 0));
|
||||
}
|
||||
@ -67,16 +67,19 @@ subr_cc_message_make(SCM message_path_scm) try {
|
||||
constexpr auto func{"cc-message-make"};
|
||||
|
||||
// message objects eat fds, tickle the gc... letting it handle it
|
||||
// automatically is not soon enough.
|
||||
// automatically is not soon enough. Note: if a script _holds_
|
||||
// references to this many messages, the map cannot shrink and this
|
||||
// triggers a full GC on each call; slow, but better than running
|
||||
// out of fds.
|
||||
if (message_map.size() >= 0.8 * max_message_map_size)
|
||||
scm_gc();
|
||||
|
||||
std::unique_lock lock{map_lock};
|
||||
|
||||
// qttempt to give an good error message rather then getting something
|
||||
// attempt to give a good error message rather than getting something
|
||||
// from GMime)
|
||||
if (message_map.size() >= max_message_map_size)
|
||||
throw ScmError{"cc-make-message", "too many open messages"};
|
||||
throw ScmError{func, "too many open messages"};
|
||||
|
||||
// if we already have the message in our map, return it.
|
||||
auto path{from_scm<std::string>(message_path_scm, func, 1)};
|
||||
@ -103,7 +106,7 @@ subr_cc_message_make(SCM message_path_scm) try {
|
||||
static SCM
|
||||
subr_cc_message_body(SCM message_scm, SCM html_scm) try {
|
||||
|
||||
constexpr auto func{"cc-message-make"};
|
||||
constexpr auto func{"cc-message-body"};
|
||||
|
||||
const auto& message{to_message(message_scm, func, 1)};
|
||||
const auto html{from_scm<bool>(html_scm, func, 2)};
|
||||
|
||||
@ -80,7 +80,11 @@ make_mime_stream_port_type()
|
||||
{
|
||||
auto ptype = scm_make_port_type(const_cast<char*>("mime-stream"), mime_stream_read, {});
|
||||
|
||||
scm_set_port_close(ptype, [](SCM port){g_mime_stream_close(from_scm_port(port));});
|
||||
scm_set_port_close(ptype, [](SCM port){
|
||||
auto stream{from_scm_port(port)};
|
||||
g_mime_stream_close(stream);
|
||||
g_object_unref(stream); // the port owns the stream
|
||||
});
|
||||
scm_set_port_needs_close_on_gc(ptype, true);
|
||||
|
||||
scm_set_port_seek(ptype, mime_stream_seek);
|
||||
@ -164,10 +168,10 @@ subr_make_mime_stream_port(SCM mime_part_scm, SCM content_only_scm,
|
||||
GMimeStream *stream{};
|
||||
try {
|
||||
auto part = part_from_scm(mime_part_scm, func, 1);
|
||||
const auto decode{from_scm<bool>(decode_scm,
|
||||
func, 2)};
|
||||
const auto content_only{from_scm<bool>(content_only_scm,
|
||||
func, 3)};
|
||||
func, 2)};
|
||||
const auto decode{from_scm<bool>(decode_scm,
|
||||
func, 3)};
|
||||
if (decode)
|
||||
stream = get_decoded_stream(part);
|
||||
else
|
||||
|
||||
@ -167,9 +167,13 @@ subr_cc_store_mfind(SCM store_scm, SCM query_scm, SCM related_scm, SCM skip_dups
|
||||
SCM msgs{SCM_EOL};
|
||||
// iterate in reverse order, so the message get consed
|
||||
// into the list in the right order.
|
||||
for (auto it{qres->end()}; it-- != qres->begin();)
|
||||
if (auto plist{it.document()->get_data()}; !plist.empty())
|
||||
for (auto it{qres->end()}; it-- != qres->begin();) {
|
||||
const auto doc{it.document()};
|
||||
if (!doc)
|
||||
continue; // e.g., removed since the query ran
|
||||
if (auto plist{doc->get_data()}; !plist.empty())
|
||||
msgs = scm_cons(to_scm(plist), msgs);
|
||||
}
|
||||
return msgs;
|
||||
|
||||
} catch (const ScmError& err) {
|
||||
|
||||
@ -160,12 +160,12 @@ maybe_remove_socket_path()
|
||||
|
||||
// opportunistic, so no real warnings, but be careful deleting!
|
||||
|
||||
if (const int res = ::stat(sock.c_str(), &statbuf); res != 0) {
|
||||
mu_debug("can't stat '{}'; err={}", sock, -res);
|
||||
if (::stat(sock.c_str(), &statbuf) != 0) {
|
||||
mu_debug("can't stat '{}': {}", sock, ::strerror(errno));
|
||||
} else if ((statbuf.st_mode & S_IFMT) != S_IFSOCK) {
|
||||
mu_debug("{} is not a socket", sock);
|
||||
} else if (const int ulres = ::unlink(sock.c_str()); ulres != 0) {
|
||||
mu_debug("failed to unlink '{}'; err={}", sock, -ulres);
|
||||
} else if (::unlink(sock.c_str()) != 0) {
|
||||
mu_debug("failed to unlink '{}': {}", sock, ::strerror(errno));
|
||||
} else {
|
||||
mu_debug("unlinked {}", sock);
|
||||
}
|
||||
@ -308,7 +308,7 @@ test_scm_script()
|
||||
|
||||
MemDb mdb;
|
||||
Config conf{mdb};
|
||||
; conf.set<Config::Id::PersonalAddresses>(
|
||||
conf.set<Config::Id::PersonalAddresses>(
|
||||
std::vector<std::string>{"user@example.com"});
|
||||
|
||||
auto store{Store::make_new(tempdir.path(), MuTestMaildir, conf)};
|
||||
|
||||
@ -188,18 +188,22 @@ namespace Mu::Scm {
|
||||
if (!pred)
|
||||
throw ScmError{ScmError::Id::WrongType, func, pos, ARG, expected};
|
||||
};
|
||||
// note: use the C predicates (scm_is_string etc.); the Scheme
|
||||
// predicates (scm_string_p etc.) return an SCM boolean, which
|
||||
// is truthy as a C++ bool even when it is #f.
|
||||
using Type = std::remove_const_t<T>; // *not* std::remove_const
|
||||
if constexpr (std::is_same_v<Type, std::string>) {
|
||||
ensure(scm_string_p(ARG), ARG, "string");
|
||||
auto str{scm_to_utf8_string(ARG)};
|
||||
std::string res{str};
|
||||
ensure(scm_is_string(ARG), ARG, "string");
|
||||
size_t len{};
|
||||
auto str{scm_to_utf8_stringn(ARG, &len)};
|
||||
std::string res{str, len};
|
||||
::free(str);
|
||||
return res;
|
||||
} else if constexpr (std::is_same_v<Type, char>) {
|
||||
ensure(scm_char_p(ARG), ARG, "character");
|
||||
return scm_to_char(ARG);
|
||||
ensure(SCM_CHARP(ARG), ARG, "character");
|
||||
return static_cast<char>(SCM_CHAR(ARG));
|
||||
} else if constexpr (std::is_same_v<Type, bool>) {
|
||||
ensure(scm_boolean_p(ARG), ARG, "bool");
|
||||
ensure(scm_is_bool(ARG), ARG, "bool");
|
||||
return scm_to_bool(ARG);
|
||||
} else if constexpr (std::is_same_v<Type, int>) {
|
||||
ensure(scm_is_signed_integer(ARG, std::numeric_limits<int>::min(),
|
||||
@ -292,7 +296,7 @@ namespace Mu::Scm {
|
||||
*/
|
||||
template<typename Key, typename Value, typename... KeyVals>
|
||||
static inline SCM alist_add(SCM alist, const Key& key, const Value& val,
|
||||
KeyVals... keyvals) {
|
||||
KeyVals&&... keyvals) {
|
||||
SCM res = scm_acons(to_scm(key), to_scm(val), alist);
|
||||
return alist_add(res, std::forward<KeyVals>(keyvals)...);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user