~aleteoryx/muditaos

523eb6f5771accb52d741030e868ee6934c1927a — Lucjan Bryndza 3 years ago b1ee717
[MOS-513] Fix issues related to the GCC12 gcc

Fix issues related to the GCC 12
Fix paths for ignore license headers
M board/rt1051/CMakeLists.txt => board/rt1051/CMakeLists.txt +9 -1
@@ 9,6 9,13 @@ endif()

set (CMAKE_EXE_LINKER_FLAGS "-nostdlib -Xlinker --gc-sections -Xlinker --sort-section=alignment -mcpu=cortex-m7 -mfpu=fpv5-sp-d16 -mfloat-abi=hard -mthumb -Xlinker -print-memory-usage -T ${LDSCRIPTSDIR}/libs.ld -T ${MEMORY_LINKER_FILE_PATH} -T ${LDSCRIPTSDIR}/sections.ld -nostartfiles" CACHE INTERNAL "")

if(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 12))
    set(GCC_CXX_DIR_ITERATOR "newlib/gcc11/fs_dir.cc")
else()
    set(GCC_CXX_DIR_ITERATOR "newlib/gcc12/fs_dir.cc")
endif()


target_sources(board
    PRIVATE
        memcpy-armv7m.S


@@ 16,14 23,15 @@ target_sources(board
        crashdump/crashcatcher_impl.cpp
        crashdump/crashdumpwriter_vfs.cpp
        memwrap.c
        newlib/fs_dir.cc
        newlib/io_syscalls.cpp
        newlib/cxx_guards.cpp
        xip/evkbimxrt1050_flexspi_nor_config.c
        xip/evkbimxrt1050_sdram_ini_dcd.c
        xip/fsl_flexspi_nor_boot.c
        ${GCC_CXX_DIR_ITERATOR}
)


target_include_directories(board
    PUBLIC
        $<BUILD_INTERFACE:

R board/rt1051/newlib/dir-common.h => board/rt1051/newlib/gcc11/dir-common.h +0 -0
R board/rt1051/newlib/fs_dir.cc => board/rt1051/newlib/gcc11/fs_dir.cc +0 -0
A board/rt1051/newlib/gcc12/dir-common.h => board/rt1051/newlib/gcc12/dir-common.h +270 -0
@@ 0,0 1,270 @@
// Filesystem directory iterator utilities -*- C++ -*-

// Copyright (C) 2014-2022 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

#ifndef _GLIBCXX_DIR_COMMON_H
#define _GLIBCXX_DIR_COMMON_H 1

#include <string.h>  // strcmp
#include <errno.h>
#if _GLIBCXX_FILESYSTEM_IS_WINDOWS
#include <wchar.h>  // wcscmp
#endif
#ifdef _GLIBCXX_HAVE_DIRENT_H
# ifdef _GLIBCXX_HAVE_SYS_TYPES_H
#  include <sys/types.h>
# endif
# include <dirent.h> // opendir, readdir, fdopendir, dirfd
# ifdef _GLIBCXX_HAVE_FCNTL_H
#  include <fcntl.h>  // open, openat, fcntl, AT_FDCWD, O_NOFOLLOW etc.
#  include <unistd.h> // close, unlinkat
# endif
#endif

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace filesystem
{
namespace __gnu_posix
{
#if _GLIBCXX_FILESYSTEM_IS_WINDOWS
// Adapt the Windows _wxxx functions to look like POSIX xxx, but for wchar_t*.
using char_type = wchar_t;
using DIR = ::_WDIR;
using dirent = _wdirent;
inline DIR* opendir(const wchar_t* path) { return ::_wopendir(path); }
inline dirent* readdir(DIR* dir) { return ::_wreaddir(dir); }
inline int closedir(DIR* dir) { return ::_wclosedir(dir); }
#elif defined _GLIBCXX_HAVE_DIRENT_H
using char_type = char;
using DIR = ::DIR;
typedef struct ::dirent dirent;
using ::opendir;
using ::readdir;
using ::closedir;
#else
using char_type = char;
struct dirent { const char* d_name; };
struct DIR { };
inline DIR* opendir(const char*) { return nullptr; }
inline dirent* readdir(DIR*) { return nullptr; }
inline int closedir(DIR*) { return -1; }
#undef _GLIBCXX_HAVE_DIRFD
#undef _GLIBCXX_HAVE_UNLINKAT
#endif
} // namespace __gnu_posix

namespace posix = __gnu_posix;

inline bool
is_permission_denied_error(int e)
{
  if (e == EACCES)
    return true;
#ifdef __APPLE__
  if (e == EPERM) // See PR 99533
    return true;
#endif
  return false;
}

struct _Dir_base
{
  // If no error occurs then dirp is non-null,
  // otherwise null (even if a permission denied error is ignored).
  _Dir_base(int fd, const posix::char_type* pathname,
	    bool skip_permission_denied, bool nofollow,
	    error_code& ec) noexcept
  : dirp(_Dir_base::openat(fd, pathname, nofollow))
  {
    if (dirp)
      ec.clear();
    else if (is_permission_denied_error(errno) && skip_permission_denied)
      ec.clear();
    else
      ec.assign(errno, std::generic_category());
  }

  _Dir_base(_Dir_base&& d) : dirp(std::exchange(d.dirp, nullptr)) { }

  _Dir_base& operator=(_Dir_base&&) = delete;

  ~_Dir_base() { if (dirp) posix::closedir(dirp); }

  const posix::dirent*
  advance(bool skip_permission_denied, error_code& ec) noexcept
  {
    ec.clear();

    int err = std::exchange(errno, 0);
    const posix::dirent* entp = posix::readdir(dirp);
    // std::swap cannot be used with Bionic's errno
    err = std::exchange(errno, err);

    if (entp)
      {
	// skip past dot and dot-dot
	if (is_dot_or_dotdot(entp->d_name))
	  return advance(skip_permission_denied, ec);
	return entp;
      }
    else if (err)
      {
	if (err == EACCES && skip_permission_denied)
	  return nullptr;
	ec.assign(err, std::generic_category());
	return nullptr;
      }
    else
      {
	// reached the end
	return nullptr;
      }
  }

  static constexpr int
  fdcwd() noexcept
  {
#ifdef AT_FDCWD
    return AT_FDCWD;
#else
    return -1; // Use invalid fd if AT_FDCWD isn't supported.
#endif
  }

  static bool is_dot_or_dotdot(const char* s) noexcept
  { return !strcmp(s, ".") || !strcmp(s, ".."); }

#if _GLIBCXX_FILESYSTEM_IS_WINDOWS
  static bool is_dot_or_dotdot(const wchar_t* s) noexcept
  { return !wcscmp(s, L".") || !wcscmp(s, L".."); }
#endif

  // Set the close-on-exec flag if not already done via O_CLOEXEC.
  static bool
  set_close_on_exec([[maybe_unused]] int fd)
  {
#if ! defined O_CLOEXEC && defined FD_CLOEXEC
    int flags = ::fcntl(fd, F_GETFD);
    if (flags == -1 || ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
      return false;
#endif
    return true;
  }

  static posix::DIR*
  openat(int fd, const posix::char_type* pathname, bool nofollow)
  {
#if _GLIBCXX_HAVE_FDOPENDIR && defined O_RDONLY && defined O_DIRECTORY \
    && ! _GLIBCXX_FILESYSTEM_IS_WINDOWS

    // Any file descriptor we open here should be closed on exec.
#ifdef O_CLOEXEC
    constexpr int close_on_exec = O_CLOEXEC;
#else
    constexpr int close_on_exec = 0;
#endif

    int flags = O_RDONLY | O_DIRECTORY | close_on_exec;

    // Directory iterators are vulnerable to race conditions unless O_NOFOLLOW
    // is supported, because a directory could be replaced with a symlink after
    // checking is_directory(symlink_status(f)). O_NOFOLLOW avoids the race.
#ifdef O_NOFOLLOW
    if (nofollow)
      flags |= O_NOFOLLOW;
#else
    nofollow = false;
#endif


#ifdef AT_FDCWD
    fd = ::openat(fd, pathname, flags);
#else
    // If we cannot use openat, there's no benefit to using posix::open unless
    // we will use O_NOFOLLOW, so just use the simpler posix::opendir.
    if (!nofollow)
      return posix::opendir(pathname);

    fd = ::open(pathname, flags);
#endif

    if (fd == -1)
      return nullptr;
    if (set_close_on_exec(fd))
      if (::DIR* dirp = ::fdopendir(fd))
	return dirp;
    int err = errno;
    ::close(fd);
    errno = err;
    return nullptr;
#else
    return posix::opendir(pathname);
#endif
  }

  posix::DIR*	dirp;
};

} // namespace filesystem

// BEGIN/END macros must be defined before including this file.
_GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM

inline file_type
get_file_type(const std::filesystem::__gnu_posix::dirent& d [[gnu::unused]])
{
#ifdef _GLIBCXX_HAVE_STRUCT_DIRENT_D_TYPE
  switch (d.d_type)
  {
  case DT_BLK:
    return file_type::block;
  case DT_CHR:
    return file_type::character;
  case DT_DIR:
    return file_type::directory;
  case DT_FIFO:
    return file_type::fifo;
  case DT_LNK:
    return file_type::symlink;
  case DT_REG:
    return file_type::regular;
  case DT_SOCK:
    return file_type::socket;
  case DT_UNKNOWN:
    return file_type::unknown;
  default:
    return file_type::none;
  }
#else
  return file_type::none;
#endif
}

_GLIBCXX_END_NAMESPACE_FILESYSTEM

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // _GLIBCXX_DIR_COMMON_H

A board/rt1051/newlib/gcc12/fs_dir.cc => board/rt1051/newlib/gcc12/fs_dir.cc +567 -0
@@ 0,0 1,567 @@
// Class filesystem::directory_entry etc. -*- C++ -*-

// Copyright (C) 2014-2022 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

#ifndef _GLIBCXX_USE_CXX11_ABI
# define _GLIBCXX_USE_CXX11_ABI 1
#endif

#undef _GLIBCXX_HAVE_UNLINKAT
#undef _GLIBCXX_HAVE_DIRFD

#include <filesystem>
#include <utility>
#include <stack>
#include <string.h>
#include <errno.h>
#define _GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM namespace filesystem {
#define _GLIBCXX_END_NAMESPACE_FILESYSTEM }
#include "dir-common.h"

#undef _GLIBCXX_HAVE_UNLINKAT
#undef _GLIBCXX_HAVE_DIRFD


namespace fs = std::filesystem;
namespace posix = std::filesystem::__gnu_posix;

template class std::__shared_ptr<fs::_Dir>;
template class std::__shared_ptr<fs::recursive_directory_iterator::_Dir_stack>;

struct fs::_Dir : _Dir_base
{
  _Dir(const fs::path& p, bool skip_permission_denied, bool nofollow,
       [[maybe_unused]] bool filename_only, error_code& ec)
  : _Dir_base(fdcwd(), p.c_str(), skip_permission_denied, nofollow, ec)
  {
#if _GLIBCXX_HAVE_DIRFD
    if (filename_only)
      return; // Do not store path p when we aren't going to use it.
#endif

    if (!ec)
      path = p;
  }

  _Dir(_Dir_base&& d, const path& p) : _Dir_base(std::move(d)), path(p) { }

  _Dir(_Dir&&) = default;

  // Returns false when the end of the directory entries is reached.
  // Reports errors by setting ec.
  bool advance(bool skip_permission_denied, error_code& ec) noexcept
  {
    if (const auto entp = _Dir_base::advance(skip_permission_denied, ec))
      {
	auto name = path;
	name /= entp->d_name;
	file_type type = file_type::none;
#ifdef _GLIBCXX_HAVE_STRUCT_DIRENT_D_TYPE
	// Even if the OS supports dirent::d_type the filesystem might not:
	if (entp->d_type != DT_UNKNOWN)
	  type = get_file_type(*entp);
#endif
	entry = fs::directory_entry{std::move(name), type};
	return true;
      }
    else if (!ec)
      {
	// reached the end
	entry = {};
      }
    return false;
  }

  bool advance(error_code& ec) noexcept { return advance(false, ec); }

  // Returns false when the end of the directory entries is reached.
  // Reports errors by throwing.
  bool advance(bool skip_permission_denied = false)
  {
    error_code ec;
    const bool ok = advance(skip_permission_denied, ec);
    if (ec)
      _GLIBCXX_THROW_OR_ABORT(filesystem_error(
	      "directory iterator cannot advance", ec));
    return ok;
  }

  bool should_recurse(bool follow_symlink, error_code& ec) const
  {
    file_type type = entry._M_type;
    if (type == file_type::none)
    {
      type = entry.symlink_status(ec).type();
      if (ec)
	return false;
    }

    if (type == file_type::directory)
      return true;
    if (type == file_type::symlink)
      return follow_symlink && is_directory(entry.status(ec));
    return false;
  }

  // Return a file descriptor for the directory and current entry's path.
  // If dirfd is available, use it and return only the filename.
  // Otherwise, return AT_FDCWD and return the full path.
  pair<int, const posix::char_type*>
  dir_and_pathname() const noexcept
  {
    const fs::path& p = entry.path();
#if _GLIBCXX_HAVE_DIRFD
    if (!p.empty())
      return {::dirfd(this->dirp), std::prev(p.end())->c_str()};
#endif
    return {this->fdcwd(), p.c_str()};
  }

  // Create a new _Dir for the directory this->entry.path().
  _Dir
  open_subdir(bool skip_permission_denied, bool nofollow,
	      error_code& ec) const noexcept
  {
    auto [dirfd, pathname] = dir_and_pathname();
    _Dir_base d(dirfd, pathname, skip_permission_denied, nofollow, ec);
    // If this->path is empty, the new _Dir should have an empty path too.
    const fs::path& p = this->path.empty() ? this->path : this->entry.path();
    return _Dir(std::move(d), p);
  }

  bool
  do_unlink(bool is_directory, error_code& ec) const noexcept
  {
#if _GLIBCXX_HAVE_UNLINKAT
    auto [dirfd, pathname] = dir_and_pathname();
    if (::unlinkat(dirfd, pathname, is_directory ? AT_REMOVEDIR : 0) == -1)
      {
	ec.assign(errno, std::generic_category());
	return false;
      }
    else
      {
	ec.clear();
	return true;
      }
#else
    return fs::remove(entry.path(), ec);
#endif
  }

  // Remove the non-directory that this->entry refers to.
  bool
  unlink(error_code& ec) const noexcept
  { return do_unlink(/* is_directory*/ false, ec); }

  // Remove the directory that this->entry refers to.
  bool
  rmdir(error_code& ec) const noexcept
  { return do_unlink(/* is_directory*/ true, ec); }

  fs::path		path; // Empty if only using unlinkat with file descr.
  directory_entry	entry;
};

namespace
{
  template<typename Bitmask>
    inline bool
    is_set(Bitmask obj, Bitmask bits)
    {
      return (obj & bits) != Bitmask::none;
    }

// Non-standard directory option flags, currently only for internal use:
//
// Do not allow directory iterator to open a symlink.
// This might seem redundant given directory_options::follow_directory_symlink
// but that is only checked for recursing into sub-directories, and we need
// something that controls the initial opendir() call in the constructor.
constexpr fs::directory_options __directory_iterator_nofollow{64};
// Do not store full paths in std::filesystem::recursive_directory_iterator.
// When fs::remove_all uses recursive_directory_iterator::__erase and unlinkat
// is available in libc, we do not need the parent directory's path, only the
// filenames of the directory entries (and a file descriptor for the parent).
// This flag avoids allocating memory for full paths that won't be needed.
constexpr fs::directory_options __directory_iterator_filename_only{128};
}

fs::directory_iterator::
directory_iterator(const path& p, directory_options options, error_code* ecptr)
{
  // Do not report an error for permission denied errors.
  const bool skip_permission_denied
    = is_set(options, directory_options::skip_permission_denied);
  // Do not allow opening a symlink.
  const bool nofollow = is_set(options, __directory_iterator_nofollow);

  error_code ec;
  _Dir dir(p, skip_permission_denied, nofollow, /*filename only*/false, ec);

  if (dir.dirp)
    {
      auto sp = std::__make_shared<fs::_Dir>(std::move(dir));
      if (sp->advance(skip_permission_denied, ec))
	_M_dir.swap(sp);
    }
  if (ecptr)
    *ecptr = ec;
  else if (ec)
    _GLIBCXX_THROW_OR_ABORT(fs::filesystem_error(
	  "directory iterator cannot open directory", p, ec));
}

const fs::directory_entry&
fs::directory_iterator::operator*() const noexcept
{
  return _M_dir->entry;
}

fs::directory_iterator&
fs::directory_iterator::operator++()
{
  if (!_M_dir)
    _GLIBCXX_THROW_OR_ABORT(filesystem_error(
	  "cannot advance non-dereferenceable directory iterator",
	  std::make_error_code(errc::invalid_argument)));
  if (!_M_dir->advance())
    _M_dir.reset();
  return *this;
}

fs::directory_iterator&
fs::directory_iterator::increment(error_code& ec)
{
  if (!_M_dir)
    {
      ec = std::make_error_code(errc::invalid_argument);
      return *this;
    }
  if (!_M_dir->advance(ec))
    _M_dir.reset();
  return *this;
}

struct fs::recursive_directory_iterator::_Dir_stack : std::stack<_Dir>
{
  _Dir_stack(directory_options opts, _Dir&& dir)
  : options(opts), pending(true)
  {
    this->push(std::move(dir));
  }

  path::string_type orig;
  const directory_options options;
  bool pending;

  void clear() { c.clear(); }

  path current_path() const
  {
    path p;
    if (top().path.empty())
      {
	// Reconstruct path that failed from dir stack.
	p = orig;
	for (auto& d : this->c)
	  p /= d.entry.path();
      }
    else
      p = top().entry.path();
    return p;
  }
};

fs::recursive_directory_iterator::
recursive_directory_iterator(const path& p, directory_options options,
                             error_code* ecptr)
{
  // Do not report an error for permission denied errors.
  const bool skip_permission_denied
    = is_set(options, directory_options::skip_permission_denied);
  // Do not allow opening a symlink as the starting directory.
  const bool nofollow = is_set(options, __directory_iterator_nofollow);
  // Prefer to store only filenames (not full paths) in directory_entry values.
  const bool filename_only
     = is_set(options, __directory_iterator_filename_only);

  error_code ec;
  _Dir dir(p, skip_permission_denied, nofollow, filename_only, ec);

  if (dir.dirp)
    {
      auto sp = std::__make_shared<_Dir_stack>(options, std::move(dir));
      if (ecptr ? sp->top().advance(skip_permission_denied, *ecptr)
		: sp->top().advance(skip_permission_denied))
	{
	  _M_dirs.swap(sp);
	  if (filename_only) // Need to save original path for error reporting.
	    _M_dirs->orig = p.native();
	}
    }
  else if (ecptr)
    *ecptr = ec;
  else if (ec)
    _GLIBCXX_THROW_OR_ABORT(fs::filesystem_error(
	  "recursive directory iterator cannot open directory", p, ec));
}

fs::recursive_directory_iterator::~recursive_directory_iterator() = default;

fs::directory_options
fs::recursive_directory_iterator::options() const noexcept
{
  return _M_dirs->options;
}

int
fs::recursive_directory_iterator::depth() const noexcept
{
  return int(_M_dirs->size()) - 1;
}

bool
fs::recursive_directory_iterator::recursion_pending() const noexcept
{
  return _M_dirs->pending;
}

const fs::directory_entry&
fs::recursive_directory_iterator::operator*() const noexcept
{
  return _M_dirs->top().entry;
}

fs::recursive_directory_iterator&
fs::recursive_directory_iterator::
operator=(const recursive_directory_iterator& other) noexcept = default;

fs::recursive_directory_iterator&
fs::recursive_directory_iterator::
operator=(recursive_directory_iterator&& other) noexcept = default;

fs::recursive_directory_iterator&
fs::recursive_directory_iterator::operator++()
{
  error_code ec;
  increment(ec);
  if (ec)
    _GLIBCXX_THROW_OR_ABORT(filesystem_error(
	  "cannot increment recursive directory iterator", ec));
  return *this;
}

fs::recursive_directory_iterator&
fs::recursive_directory_iterator::increment(error_code& ec)
{
  if (!_M_dirs)
    {
      ec = std::make_error_code(errc::invalid_argument);
      return *this;
    }

  const bool follow
    = is_set(_M_dirs->options, directory_options::follow_directory_symlink);
  const bool skip_permission_denied
    = is_set(_M_dirs->options, directory_options::skip_permission_denied);

  auto& top = _M_dirs->top();

  if (std::exchange(_M_dirs->pending, true) && top.should_recurse(follow, ec))
    {
      _Dir dir = top.open_subdir(skip_permission_denied, !follow, ec);
      if (ec)
	{
	  _M_dirs.reset();
	  return *this;
	}
      if (dir.dirp)
	_M_dirs->push(std::move(dir));
    }

  while (!_M_dirs->top().advance(skip_permission_denied, ec) && !ec)
    {
      _M_dirs->pop();
      if (_M_dirs->empty())
	{
	  _M_dirs.reset();
	  return *this;
	}
    }

  if (ec)
    _M_dirs.reset();

  return *this;
}

void
fs::recursive_directory_iterator::pop(error_code& ec)
{
  if (!_M_dirs)
    {
      ec = std::make_error_code(errc::invalid_argument);
      return;
    }

  const bool skip_permission_denied
    = is_set(_M_dirs->options, directory_options::skip_permission_denied);

  do {
    _M_dirs->pop();
    if (_M_dirs->empty())
      {
	_M_dirs.reset();
	ec.clear();
	return;
      }
  } while (!_M_dirs->top().advance(skip_permission_denied, ec) && !ec);

  if (ec)
    _M_dirs.reset();
}

void
fs::recursive_directory_iterator::pop()
{
  [[maybe_unused]] const bool dereferenceable = _M_dirs != nullptr;
  error_code ec;
  pop(ec);
  if (ec)
    _GLIBCXX_THROW_OR_ABORT(filesystem_error(dereferenceable
	  ? "recursive directory iterator cannot pop"
	  : "non-dereferenceable recursive directory iterator cannot pop",
	  ec));
}

void
fs::recursive_directory_iterator::disable_recursion_pending() noexcept
{
  _M_dirs->pending = false;
}

// Used to implement filesystem::remove_all.
fs::recursive_directory_iterator&
fs::recursive_directory_iterator::__erase(error_code* ecptr)
{
  error_code ec;
  if (!_M_dirs)
    {
      ec = std::make_error_code(errc::invalid_argument);
      return *this;
    }

  // We never want to skip permission denied when removing files.
  const bool skip_permission_denied = false;
  // We never want to follow directory symlinks when removing files.
  const bool nofollow = true;

  // Loop until we find something we can remove.
  while (!ec)
    {
      auto& top = _M_dirs->top();

#if _GLIBCXX_FILESYSTEM_IS_WINDOWS
      // _Dir::unlink uses fs::remove which uses std::system_category() for
      // Windows errror codes, so we can't just check for EPERM and EISDIR.
      // Use directory_entry::refresh() here to check if we have a directory.
      // This can be a TOCTTOU race, but we don't have openat or unlinkat to
      // solve that on Windows, and generally don't support symlinks anyway.
      if (top.entry._M_type == file_type::none)
	top.entry.refresh();
#endif

      if (top.entry._M_type == file_type::directory)
	{
	  _Dir dir = top.open_subdir(skip_permission_denied, nofollow, ec);
	  if (!ec)
	    {
	      __glibcxx_assert(dir.dirp != nullptr);
	      if (dir.advance(skip_permission_denied, ec))
		{
		  // Non-empty directory, recurse into it.
		  _M_dirs->push(std::move(dir));
		  continue;
		}
	      if (!ec)
		{
		  // Directory is empty so we can remove it.
		  if (top.rmdir(ec))
		    break; // Success
		}
	    }
	}
      else if (top.unlink(ec))
	break; // Success
#if ! _GLIBCXX_FILESYSTEM_IS_WINDOWS
      else if (top.entry._M_type == file_type::none)
	{
	  // We did not have a cached type, so it's possible that top.entry
	  // is actually a directory, and that's why the unlink above failed.
#ifdef EPERM
	  // POSIX.1-2017 says unlink on a directory returns EPERM,
	  // but LSB allows EISDIR too. Some targets don't even define EPERM.
	  if (ec.value() == EPERM || ec.value() == EISDIR)
#else
	  if (ec.value() == EISDIR)
#endif
	    {
	      // Retry, treating it as a directory.
	      top.entry._M_type = file_type::directory;
	      ec.clear();
	      continue;
	    }
	}
#endif
    }

  if (!ec)
    {
      // We successfully removed the current entry, so advance to the next one.
      if (_M_dirs->top().advance(skip_permission_denied, ec))
	return *this;
      else if (!ec)
	{
	  // Reached the end of the current directory.
	  _M_dirs->pop();
	  if (_M_dirs->empty())
	    _M_dirs.reset();
	  return *this;
	}
    }

  // Reset _M_dirs to empty.
  auto dirs = std::move(_M_dirs);

  // Need to report an error
  if (ecptr)
    *ecptr = ec;
  else
    _GLIBCXX_THROW_OR_ABORT(fs::filesystem_error("cannot remove all",
						 dirs->orig,
						 dirs->current_path(),
						 ec));

  return *this;
}

M board/rt1051/newlib/io_syscalls.cpp => board/rt1051/newlib/io_syscalls.cpp +5 -0
@@ 169,4 169,9 @@ extern "C"
    {
        return syscalls::pathconf(_REENT->_errno, path, name);
    }
    int getentropy([[maybe_unused]] void *buf, [[maybe_unused]] size_t buflen)
    {
        errno = -ENOTSUP;
        return -1;
    }
}

M config/format-config.sh => config/format-config.sh +2 -0
@@ 22,6 22,8 @@ export declare ignore_paths=(
    'board/rt1051/newlib/cxx_guards.cpp'
    'board/rt1051/newlib/dir-common.h'
    'board/rt1051/newlib/include/'
    'board/rt1051/newlib/gcc11/'
    'board/rt1051/newlib/gcc12/'
    'host-tools/littlefs-fuse/lfsfuse/'
    'module-audio/Audio/decoder/dr_flac.h'
    'module-bluetooth/Bluetooth/btstack_config.h'

M module-apps/CMakeLists.txt => module-apps/CMakeLists.txt +0 -1
@@ 128,7 128,6 @@ target_compile_options(${PROJECT_NAME}
        $<$<COMPILE_LANGUAGE:C>:-std=gnu11>
        $<$<COMPILE_LANGUAGE:C>:-Wno-discarded-qualifiers>

        $<$<COMPILE_LANGUAGE:CXX>:-fno-non-call-exceptions>
        $<$<COMPILE_LANGUAGE:CXX>:-Wno-literal-suffix>

)

M module-apps/apps-common/CMakeLists.txt => module-apps/apps-common/CMakeLists.txt +0 -1
@@ 137,7 137,6 @@ target_compile_options(apps-common
        $<$<COMPILE_LANGUAGE:C>:-std=gnu11>
        $<$<COMPILE_LANGUAGE:C>:-Wno-discarded-qualifiers>

        $<$<COMPILE_LANGUAGE:CXX>:-fno-non-call-exceptions>
        $<$<COMPILE_LANGUAGE:CXX>:-Wno-literal-suffix>

)

M module-audio/Audio/codec.hpp => module-audio/Audio/codec.hpp +1 -0
@@ 4,6 4,7 @@
#pragma once

#include <cstdint>
#include <array>
#include <module-audio/Audio/equalizer/Equalizer.hpp>

namespace audio::codec

M module-bsp/board/rt1051/CMakeLists.txt => module-bsp/board/rt1051/CMakeLists.txt +1 -0
@@ 66,6 66,7 @@ target_include_directories(module-bsp
set_source_files_properties(
	eMMC/fsl_mmc.c PROPERTIES COMPILE_FLAGS -Wno-unused-function
	common/i2c.c PROPERTIES COMPILE_FLAGS -Wno-unused-function
    bsp/rtc/rtc.cpp PROPERTIES COMPILE_FLAGS "-Wno-unused-value -Wno-error=unused-value"
)

target_compile_definitions(module-bsp PUBLIC USB_STACK_FREERTOS)

M module-bsp/board/rt1051/bsp/rtc/rtc.cpp => module-bsp/board/rt1051/bsp/rtc/rtc.cpp +1 -1
@@ 32,7 32,7 @@ namespace bsp::rtc
        s_rtcConfig.rtcCalEnable = true;
        SNVS_HP_RTC_Init(SNVS, &s_rtcConfig);

        SNVS_LPCR_LPTA_EN(1);
        (void)SNVS_LPCR_LPTA_EN(1);

        bool timedOut     = false;
        auto timeoutTicks = cpp_freertos::Ticks::GetTicks() + pdMS_TO_TICKS(utils::time::milisecondsInSecond);

M module-bsp/board/rt1051/common/fsl_drivers/fsl_sai.c => module-bsp/board/rt1051/common/fsl_drivers/fsl_sai.c +2 -4
@@ 187,13 187,11 @@ static uint32_t SAI_GetInstance(I2S_Type *base)
    /* Find the instance index from base address mappings. */
    for (instance = 0; instance < ARRAY_SIZE(s_saiBases); instance++) {
        if (s_saiBases[instance] == base) {
            break;
            return instance;
        }
    }

    assert(instance < ARRAY_SIZE(s_saiBases));

    return instance;
    return 0;
}

static void SAI_WriteNonBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size)

M module-bsp/board/rt1051/common/fsl_drivers/fsl_semc.c => module-bsp/board/rt1051/common/fsl_drivers/fsl_semc.c +4 -8
@@ 255,8 255,8 @@ void SEMC_GetDefaultConfig(semc_config_t *config)
    queuebWeight.weightPagehit    = SEMC_BMCR1_TYPICAL_WPH;
    queuebWeight.bankRotation     = SEMC_BMCR1_TYPICAL_WBR;

    config->queueWeight.queueaWeight = &queueaWeight;
    config->queueWeight.queuebWeight = &queuebWeight;
    config->queueWeight.queueaWeight = queueaWeight;
    config->queueWeight.queuebWeight = queuebWeight;
}

void SEMC_Init(SEMC_Type *base, semc_config_t *configure)


@@ 285,12 285,8 @@ void SEMC_Init(SEMC_Type *base, semc_config_t *configure)
                 SEMC_MCR_CTO(configure->cmdTimeoutCycles) | SEMC_MCR_DQSMD(configure->dqsMode);

    /* Configure Queue 0/1 for AXI bus. */
    if (configure->queueWeight.queueaWeight) {
        base->BMCR0 = (uint32_t)(configure->queueWeight.queueaWeight);
    }
    if (configure->queueWeight.queuebWeight) {
        base->BMCR1 = (uint32_t)(configure->queueWeight.queuebWeight);
    }
    base->BMCR0 = (uint32_t)&(configure->queueWeight.queueaWeight);
    base->BMCR1 = (uint32_t)&(configure->queueWeight.queuebWeight);
    /* Enable SEMC. */
    base->MCR &= ~SEMC_MCR_MDIS_MASK;
}

M module-bsp/board/rt1051/common/fsl_drivers/fsl_semc.h => module-bsp/board/rt1051/common/fsl_drivers/fsl_semc.h +2 -2
@@ 526,8 526,8 @@ typedef struct _semc_queueb_weight
/*! @brief SEMC AXI queue weight setting. */
typedef struct _semc_axi_queueweight
{
    semc_queuea_weight_t *queueaWeight; /*!< Weight settings for queue a. */
    semc_queueb_weight_t *queuebWeight; /*!< Weight settings for queue b. */
    semc_queuea_weight_t queueaWeight; /*!< Weight settings for queue a. */
    semc_queueb_weight_t queuebWeight; /*!< Weight settings for queue b. */
} semc_axi_queueweight_t;

/*!

M module-bsp/board/rt1051/drivers/RT1051DriverPWM.hpp => module-bsp/board/rt1051/drivers/RT1051DriverPWM.hpp +1 -0
@@ 12,6 12,7 @@

#include <vector>
#include <map>
#include <array>
namespace drivers
{
    class RT1051DriverPWM : public DriverPWM

M module-cellular/at/Cmd.hpp => module-cellular/at/Cmd.hpp +4 -4
@@ 37,10 37,10 @@ namespace at
        Cmd() = delete;
        Cmd(std::string cmd, cmd::Modifier mod, std::chrono::milliseconds timeout = default_timeout) noexcept;
        Cmd(std::string cmd, std::chrono::milliseconds timeout = default_timeout) noexcept;
        Cmd(const Cmd &p) noexcept;
        Cmd(Cmd &&) noexcept;
        auto operator  =(const Cmd &) noexcept -> Cmd &;
        auto operator  =(Cmd &&) noexcept -> Cmd &;
        Cmd(const Cmd &p) noexcept = default;
        Cmd(Cmd &&) noexcept       = default;
        auto operator=(const Cmd &) noexcept -> Cmd & = default;
        auto operator=(Cmd &&) noexcept -> Cmd & = default;
        virtual ~Cmd() = default;

        auto setModifier(cmd::Modifier mod) noexcept

M module-cellular/at/UrcFactory.hpp => module-cellular/at/UrcFactory.hpp +1 -0
@@ 4,6 4,7 @@
#pragma once

#include "Urc.hpp"
#include <memory>

namespace at::urc
{

M module-cellular/at/src/ATFactory.cpp => module-cellular/at/src/ATFactory.cpp +127 -124
@@ 3,137 3,140 @@

#include "ATFactory.hpp"
#include "cmd/CSCA.hpp"
#include <memory>

namespace at
{
    using namespace std::chrono_literals;

    std::initializer_list<std::pair<const AT, const Cmd>> initializer = {
        {AT::AT, {"AT"}},
        {AT::ECHO_OFF, {"ATE0"}},
        {AT::FACTORY_RESET, {"AT&F"}},
        {AT::SW_INFO, {"ATI\r"}},
        {AT::FLOW_CTRL_ON, {"AT+IFC=2,2\r\n"}},
        {AT::FLOW_CTRL_OFF, {"AT+IFC=0,0"}},
        {AT::URC_NOTIF_CHANNEL, {"AT+QCFG=\"cmux/urcport\",1"}},
        {AT::RI_PIN_AUTO_CALL, {"AT+QCFG=\"urc/ri/ring\",\"auto\""}},
        {AT::RI_PIN_OFF_CALL, {"AT+QCFG=\"urc/ri/ring\",\"off\""}},
        {AT::RI_PIN_PULSE_SMS, {"AT+QCFG=\"urc/ri/smsincoming\",\"pulse\",450"}},
        {AT::RI_PIN_OFF_SMS, {"AT+QCFG=\"urc/ri/smsincoming\",\"off\""}},
        {AT::RI_PIN_PULSE_OTHER, {"AT+QCFG=\"urc/ri/other\",\"pulse\""}},
        {AT::URC_DELAY_ON, {"AT+QCFG=\"urc/delay\",1"}},
        {AT::URC_UART1, {"AT+QURCCFG=\"urcport\",\"uart1\""}},
        {AT::AT_PIN_READY_LOGIC, {"AT+QCFG=\"apready\",1,1,200"}},
        {AT::CSQ_URC_ON, {"AT+QINDCFG=\"csq\",1"}},
        {AT::CSQ_URC_OFF, {"AT+QINDCFG=\"csq\",0"}},
        {AT::CRC_ON, {"AT+CRC=1"}},
        {AT::CALLER_NUMBER_PRESENTATION, {"AT+CLIP=1", default_long_timeout}},
        {AT::SMS_TEXT_FORMAT, {"AT+CMGF=1"}},
        {AT::SMS_UCSC2, {"AT+CSCS=\"UCS2\""}},
        {AT::SMS_GSM, {"AT+CSCS=\"GSM\""}},
        {AT::QSCLK_ON, {"AT+QSCLK=1"}},
        {AT::QDAI, {"AT+QDAI?"}},
        {AT::QDAI_INIT, {"AT+QDAI=1,0,0,3,0,1,1,1"}},
        {AT::SET_URC_CHANNEL, {"AT+QCFG=\"cmux/urcport\",2"}},
        {AT::CSQ, {"AT+CSQ"}},
        {AT::CLCC, {"AT+CLCC"}},
        {AT::CMGD, {"AT+CMGD="}},
        {AT::CNUM, {"AT+CNUM"}},
        {AT::CIMI, {"AT+CIMI"}},
        {AT::QCMGR, {"AT+QCMGR=", 180s}},
        {AT::ATH, {"ATH", 100s}},
        {AT::QHUP_BUSY, {"AT+QHUP=17", 100s}},
        {AT::ATA, {"ATA", 100s}},
        {AT::ATD, {"ATD", 6s}},
        {AT::IPR, {"AT+IPR="}},
        {AT::CMUX, {"AT+CMUX="}},
        {AT::CFUN, {"AT+CFUN=", default_long_timeout}},
        {AT::CFUN_RESET, {"AT+CFUN=1,1", default_long_timeout}},
        {AT::CFUN_MIN_FUNCTIONALITY, {"AT+CFUN=0", default_long_timeout}},
        {AT::CFUN_FULL_FUNCTIONALITY, {"AT+CFUN=1", default_long_timeout}},
        {AT::CFUN_DISABLE_TRANSMITTING, {"AT+CFUN=4", default_long_timeout}},
        {AT::CMGS, {"AT+CMGS=\"", 180s}}, //
        {AT::QCMGS, {"AT+QCMGS=\"", 180s}},
        {AT::CREG, {"AT+CREG?"}},
        {AT::QNWINFO, {"AT+QNWINFO"}},
        {AT::COPS, {"AT+COPS", 200s}},
        {AT::QSIMSTAT, {"AT+QSIMSTAT?"}},
        {AT::SIM_DET, {"AT+QSIMDET?"}},
        {AT::SIM_DET_ON, {"AT+QSIMDET=1,0"}},
        {AT::SIMSTAT_ON, {"AT+QSIMSTAT=1"}},
        {AT::SET_DEFAULT_SCANMODE, {"AT+QCFG=\"nwscanmode\",0"}},
        {AT::SET_DEFAULT_SERVICEDOMAIN, {"AT+QCFG=\"servicedomain\",2"}},
        {AT::SET_SCANMODE, {"AT+QCFG=\"nwscanmode\","}},
        {AT::GET_SCANMODE, {"AT+QCFG=\"nwscanmode\""}},
        {AT::SET_SERVICEDOMAIN, {"AT+QCFG=\"servicedomain\","}},
        {AT::GET_SERVICEDOMAIN, {"AT+QCFG=\"servicedomain\""}},
        {AT::QGMR, {"AT+QGMR"}},
        {AT::STORE_SETTINGS_ATW, {"AT&W"}},
        {AT::CEER, {"AT+CEER", 1s}},
        {AT::QIGETERROR, {"AT+QIGETERROR"}},
        {AT::VTS, {"AT+VTS=", default_long_timeout}},
        {AT::QLDTMF, {"AT+QLDTMF=1,"}},
        {AT::CUSD_OPEN_SESSION, {"AT+CUSD=1", 150s}},
        {AT::CUSD_CLOSE_SESSION, {"AT+CUSD=2", 150s}},
        {AT::CUSD_SEND, {"AT+CUSD=1,", 150s}},
        {AT::SET_SMS_STORAGE, {"AT+CPMS=\"SM\",\"SM\",\"SM\""}},
        {AT::CPIN, {"AT+CPIN=", default_long_timeout}},
        {AT::GET_CPIN, {"AT+CPIN?", default_long_timeout}},
        {AT::QPINC, {"AT+QPINC=", default_long_timeout}},
        {AT::CLCK, {"AT+CLCK=", default_long_timeout}},
        {AT::CPWD, {"AT+CPWD=", default_long_timeout}},
        {AT::ENABLE_TIME_ZONE_UPDATE, {"AT+CTZU=3"}},
        {AT::SET_TIME_ZONE_REPORTING, {"AT+CTZR=2"}},
        {AT::DISABLE_TIME_ZONE_UPDATE, {"AT+CTZU=0"}},
        {AT::DISABLE_TIME_ZONE_REPORTING, {"AT+CTZR=0"}},
        {AT::ENABLE_NETWORK_REGISTRATION_URC, {"AT+CREG=2"}},
        {AT::SET_SMS_TEXT_MODE_UCS2, {"AT+CSMP=17,167,0,8"}},
        {AT::LIST_MESSAGES, {"AT+CMGL=\"ALL\""}},
        {AT::GET_IMEI, {"AT+GSN"}},
        {AT::CCFC, {"AT+CCFC="}},
        {AT::CCWA, {"AT+CCWA="}},
        {AT::CCWA_GET, {"AT+CCWA?"}},
        {AT::CHLD, {"AT+CHLD=\""}},
        {AT::CLIP, {"AT+CLIP=", default_long_timeout}},
        {AT::CLIP_GET, {"AT+CLIP?", default_long_timeout}},
        {AT::CLIR, {"AT+CLIR=", default_long_timeout}},
        {AT::CLIR_GET, {"AT+CLIR?", default_long_timeout}},
        {AT::CLIR_RESET, {"AT+CLIR=0", default_long_timeout}},
        {AT::CLIR_ENABLE, {"AT+CLIR=1", default_long_timeout}},
        {AT::CLIR_DISABLE, {"AT+CLIR=2", default_long_timeout}},
        {AT::COLP, {"AT+COLP", default_long_timeout}},
        {AT::COLP_GET, {"AT+COLP?", default_long_timeout}},
        {AT::COLP_ENABLE, {"AT+COLP=1", default_long_timeout}},
        {AT::COLP_DISABLE, {"AT+COLP=0", default_long_timeout}},
        {AT::CSSN, {"AT+CSSN=\""}},
        {AT::QICSGP, {"AT+QICSGP"}},
        {AT::QIACT, {"AT+QIACT", 150s}},
        {AT::QIDEACT, {"AT+QIDEACT", 40s}},
        {AT::QRXGAIN, {"AT+QRXGAIN=40000"}},
        {AT::CLVL, {"AT+CLVL=3"}},
        {AT::QMIC, {"AT+QMIC=15000,15000"}},
        {AT::QEEC, {"AT+QEEC="}},
        {AT::QNVFR, {"AT+QNVFR=", default_long_timeout}},
        {AT::QNVFW, {"AT+QNVFW=", default_long_timeout}},
        {AT::QMBNCFG, {"AT+QMBNCFG=", default_long_timeout}},
        {AT::QCFG_IMS, {"AT+QCFG=\"ims\""}},
        {AT::RING_URC_ON, {"AT+QINDCFG=\"ring\",1"}},
        {AT::RING_URC_OFF, {"AT+QINDCFG=\"ring\",0"}},
        {AT::ACT_URC_OFF, {"AT+QINDCFG=\"act\",0"}},
        {AT::ACT_URC_ON, {"AT+QINDCFG=\"act\",1"}},
        {AT::SMS_URC_ON, {"AT+QINDCFG=\"smsincoming\",1"}},
        {AT::SMS_URC_OFF, {"AT+QINDCFG=\"smsincoming\",0"}},
        {AT::SET_RNDIS, {"AT+QCFG=\"usbnet\",3"}},

    };

    using namespace std::string_literals;
    namespace
    {
        std::map<const AT, std::shared_ptr<const Cmd>> g_cmds_map{
            {AT::AT, std::make_shared<Cmd>("AT")},
            {AT::ECHO_OFF, std::make_shared<Cmd>("ATE0")},
            {AT::FACTORY_RESET, std::make_shared<Cmd>("AT&F")},
            {AT::SW_INFO, std::make_shared<Cmd>("ATI\r")},
            {AT::FLOW_CTRL_ON, std::make_shared<Cmd>("AT+IFC=2,2\r\n")},
            {AT::FLOW_CTRL_OFF, std::make_shared<Cmd>("AT+IFC=0,0")},
            {AT::URC_NOTIF_CHANNEL, std::make_shared<Cmd>("AT+QCFG=\"cmux/urcport\",1")},
            {AT::RI_PIN_AUTO_CALL, std::make_shared<Cmd>("AT+QCFG=\"urc/ri/ring\",\"auto\"")},
            {AT::RI_PIN_OFF_CALL, std::make_shared<Cmd>("AT+QCFG=\"urc/ri/ring\",\"off\"")},
            {AT::RI_PIN_PULSE_SMS, std::make_shared<Cmd>("AT+QCFG=\"urc/ri/smsincoming\",\"pulse\",450")},
            {AT::RI_PIN_OFF_SMS, std::make_shared<Cmd>("AT+QCFG=\"urc/ri/smsincoming\",\"off\"")},
            {AT::RI_PIN_PULSE_OTHER, std::make_shared<Cmd>("AT+QCFG=\"urc/ri/other\",\"pulse\"")},
            {AT::URC_DELAY_ON, std::make_shared<Cmd>("AT+QCFG=\"urc/delay\",1")},
            {AT::URC_UART1, std::make_shared<Cmd>("AT+QURCCFG=\"urcport\",\"uart1\"")},
            {AT::AT_PIN_READY_LOGIC, std::make_shared<Cmd>("AT+QCFG=\"apready\",1,1,200")},
            {AT::CSQ_URC_ON, std::make_shared<Cmd>("AT+QINDCFG=\"csq\",1")},
            {AT::CSQ_URC_OFF, std::make_shared<Cmd>("AT+QINDCFG=\"csq\",0")},
            {AT::CRC_ON, std::make_shared<Cmd>("AT+CRC=1")},
            {AT::CALLER_NUMBER_PRESENTATION, std::make_shared<Cmd>("AT+CLIP=1", default_long_timeout)},
            {AT::SMS_TEXT_FORMAT, std::make_shared<Cmd>("AT+CMGF=1")},
            {AT::SMS_UCSC2, std::make_shared<Cmd>("AT+CSCS=\"UCS2\"")},
            {AT::SMS_GSM, std::make_shared<Cmd>("AT+CSCS=\"GSM\"")},
            {AT::QSCLK_ON, std::make_shared<Cmd>("AT+QSCLK=1")},
            {AT::QDAI, std::make_shared<Cmd>("AT+QDAI?")},
            {AT::QDAI_INIT, std::make_shared<Cmd>("AT+QDAI=1,0,0,3,0,1,1,1")},
            {AT::SET_URC_CHANNEL, std::make_shared<Cmd>("AT+QCFG=\"cmux/urcport\",2")},
            {AT::CSQ, std::make_shared<Cmd>("AT+CSQ")},
            {AT::CLCC, std::make_shared<Cmd>("AT+CLCC")},
            {AT::CMGD, std::make_shared<Cmd>("AT+CMGD=")},
            {AT::CNUM, std::make_shared<Cmd>("AT+CNUM")},
            {AT::CIMI, std::make_shared<Cmd>("AT+CIMI")},
            {AT::QCMGR, std::make_shared<Cmd>("AT+QCMGR=", 180s)},
            {AT::ATH, std::make_shared<Cmd>("ATH", 100s)},
            {AT::QHUP_BUSY, std::make_shared<Cmd>("AT+QHUP=17", 100s)},
            {AT::ATA, std::make_shared<Cmd>("ATA", 100s)},
            {AT::ATD, std::make_shared<Cmd>("ATD", 6s)},
            {AT::IPR, std::make_shared<Cmd>("AT+IPR=")},
            {AT::CMUX, std::make_shared<Cmd>("AT+CMUX=")},
            {AT::CFUN, std::make_shared<Cmd>("AT+CFUN=", default_long_timeout)},
            {AT::CFUN_RESET, std::make_shared<Cmd>("AT+CFUN=1,1", default_long_timeout)},
            {AT::CFUN_MIN_FUNCTIONALITY, std::make_shared<Cmd>("AT+CFUN=0", default_long_timeout)},
            {AT::CFUN_FULL_FUNCTIONALITY, std::make_shared<Cmd>("AT+CFUN=1", default_long_timeout)},
            {AT::CFUN_DISABLE_TRANSMITTING, std::make_shared<Cmd>("AT+CFUN=4", default_long_timeout)},
            {AT::CMGS, std::make_shared<Cmd>("AT+CMGS=\"", 180s)}, //
            {AT::QCMGS, std::make_shared<Cmd>("AT+QCMGS=\"", 180s)},
            {AT::CREG, std::make_shared<Cmd>("AT+CREG?")},
            {AT::QNWINFO, std::make_shared<Cmd>("AT+QNWINFO")},
            {AT::COPS, std::make_shared<Cmd>("AT+COPS", 200s)},
            {AT::QSIMSTAT, std::make_shared<Cmd>("AT+QSIMSTAT?")},
            {AT::SIM_DET, std::make_shared<Cmd>("AT+QSIMDET?")},
            {AT::SIM_DET_ON, std::make_shared<Cmd>("AT+QSIMDET=1,0")},
            {AT::SIMSTAT_ON, std::make_shared<Cmd>("AT+QSIMSTAT=1")},
            {AT::SET_DEFAULT_SCANMODE, std::make_shared<Cmd>("AT+QCFG=\"nwscanmode\",0")},
            {AT::SET_DEFAULT_SERVICEDOMAIN, std::make_shared<Cmd>("AT+QCFG=\"servicedomain\",2")},
            {AT::SET_SCANMODE, std::make_shared<Cmd>("AT+QCFG=\"nwscanmode\",")},
            {AT::GET_SCANMODE, std::make_shared<Cmd>("AT+QCFG=\"nwscanmode\"")},
            {AT::SET_SERVICEDOMAIN, std::make_shared<Cmd>("AT+QCFG=\"servicedomain\",")},
            {AT::GET_SERVICEDOMAIN, std::make_shared<Cmd>("AT+QCFG=\"servicedomain\"")},
            {AT::QGMR, std::make_shared<Cmd>("AT+QGMR")},
            {AT::STORE_SETTINGS_ATW, std::make_shared<Cmd>("AT&W")},
            {AT::CEER, std::make_shared<Cmd>("AT+CEER", 1s)},
            {AT::QIGETERROR, std::make_shared<Cmd>("AT+QIGETERROR")},
            {AT::VTS, std::make_shared<Cmd>("AT+VTS=", default_long_timeout)},
            {AT::QLDTMF, std::make_shared<Cmd>("AT+QLDTMF=1,")},
            {AT::CUSD_OPEN_SESSION, std::make_shared<Cmd>("AT+CUSD=1", 150s)},
            {AT::CUSD_CLOSE_SESSION, std::make_shared<Cmd>("AT+CUSD=2", 150s)},
            {AT::CUSD_SEND, std::make_shared<Cmd>("AT+CUSD=1,", 150s)},
            {AT::SET_SMS_STORAGE, std::make_shared<Cmd>("AT+CPMS=\"SM\",\"SM\",\"SM\"")},
            {AT::CPIN, std::make_shared<Cmd>("AT+CPIN=", default_long_timeout)},
            {AT::GET_CPIN, std::make_shared<Cmd>("AT+CPIN?", default_long_timeout)},
            {AT::QPINC, std::make_shared<Cmd>("AT+QPINC=", default_long_timeout)},
            {AT::CLCK, std::make_shared<Cmd>("AT+CLCK=", default_long_timeout)},
            {AT::CPWD, std::make_shared<Cmd>("AT+CPWD=", default_long_timeout)},
            {AT::ENABLE_TIME_ZONE_UPDATE, std::make_shared<Cmd>("AT+CTZU=3")},
            {AT::SET_TIME_ZONE_REPORTING, std::make_shared<Cmd>("AT+CTZR=2")},
            {AT::DISABLE_TIME_ZONE_UPDATE, std::make_shared<Cmd>("AT+CTZU=0")},
            {AT::DISABLE_TIME_ZONE_REPORTING, std::make_shared<Cmd>("AT+CTZR=0")},
            {AT::ENABLE_NETWORK_REGISTRATION_URC, std::make_shared<Cmd>("AT+CREG=2")},
            {AT::SET_SMS_TEXT_MODE_UCS2, std::make_shared<Cmd>("AT+CSMP=17,167,0,8")},
            {AT::LIST_MESSAGES, std::make_shared<Cmd>("AT+CMGL=\"ALL\"")},
            {AT::GET_IMEI, std::make_shared<Cmd>("AT+GSN")},
            {AT::CCFC, std::make_shared<Cmd>("AT+CCFC=")},
            {AT::CCWA, std::make_shared<Cmd>("AT+CCWA=")},
            {AT::CCWA_GET, std::make_shared<Cmd>("AT+CCWA?")},
            {AT::CHLD, std::make_shared<Cmd>("AT+CHLD=\"")},
            {AT::CLIP, std::make_shared<Cmd>("AT+CLIP=", default_long_timeout)},
            {AT::CLIP_GET, std::make_shared<Cmd>("AT+CLIP?", default_long_timeout)},
            {AT::CLIR, std::make_shared<Cmd>("AT+CLIR=", default_long_timeout)},
            {AT::CLIR_GET, std::make_shared<Cmd>("AT+CLIR?", default_long_timeout)},
            {AT::CLIR_RESET, std::make_shared<Cmd>("AT+CLIR=0", default_long_timeout)},
            {AT::CLIR_ENABLE, std::make_shared<Cmd>("AT+CLIR=1", default_long_timeout)},
            {AT::CLIR_DISABLE, std::make_shared<Cmd>("AT+CLIR=2", default_long_timeout)},
            {AT::COLP, std::make_shared<Cmd>("AT+COLP", default_long_timeout)},
            {AT::COLP_GET, std::make_shared<Cmd>("AT+COLP?", default_long_timeout)},
            {AT::COLP_ENABLE, std::make_shared<Cmd>("AT+COLP=1", default_long_timeout)},
            {AT::COLP_DISABLE, std::make_shared<Cmd>("AT+COLP=0", default_long_timeout)},
            {AT::CSSN, std::make_shared<Cmd>("AT+CSSN=\"")},
            {AT::QICSGP, std::make_shared<Cmd>("AT+QICSGP")},
            {AT::QIACT, std::make_shared<Cmd>("AT+QIACT", 150s)},
            {AT::QIDEACT, std::make_shared<Cmd>("AT+QIDEACT", 40s)},
            {AT::QRXGAIN, std::make_shared<Cmd>("AT+QRXGAIN=40000")},
            {AT::CLVL, std::make_shared<Cmd>("AT+CLVL=3")},
            {AT::QMIC, std::make_shared<Cmd>("AT+QMIC=15000,15000")},
            {AT::QEEC, std::make_shared<Cmd>("AT+QEEC=")},
            {AT::QNVFR, std::make_shared<Cmd>("AT+QNVFR=", default_long_timeout)},
            {AT::QNVFW, std::make_shared<Cmd>("AT+QNVFW=", default_long_timeout)},
            {AT::QMBNCFG, std::make_shared<Cmd>("AT+QMBNCFG=", default_long_timeout)},
            {AT::QCFG_IMS, std::make_shared<Cmd>("AT+QCFG=\"ims\"")},
            {AT::RING_URC_ON, std::make_shared<Cmd>("AT+QINDCFG=\"ring\",1")},
            {AT::RING_URC_OFF, std::make_shared<Cmd>("AT+QINDCFG=\"ring\",0")},
            {AT::ACT_URC_OFF, std::make_shared<Cmd>("AT+QINDCFG=\"act\",0")},
            {AT::ACT_URC_ON, std::make_shared<Cmd>("AT+QINDCFG=\"act\",1")},
            {AT::SMS_URC_ON, std::make_shared<Cmd>("AT+QINDCFG=\"smsincoming\",1")},
            {AT::SMS_URC_OFF, std::make_shared<Cmd>("AT+QINDCFG=\"smsincoming\",0")},
            {AT::SET_RNDIS, std::make_shared<Cmd>("AT+QCFG=\"usbnet\",3")},
        };
    }
    auto factory(AT at) -> const Cmd &
    {
        static auto fact = std::map<AT, const Cmd>(initializer);
        if (fact.count(at) != 0u) {
            return fact.at(at);
        if (g_cmds_map.count(at) != 0u) {
            assert(g_cmds_map.at(at));
            return *(g_cmds_map.at(at));
        }
        LOG_ERROR("no such at command defined: %d", static_cast<int>(at));
        return fact.at(AT::AT);
        assert(g_cmds_map.at(AT::AT));
        return *(g_cmds_map.at(AT::AT));
    }
} // namespace at

M module-cellular/at/src/Cmd.cpp => module-cellular/at/src/Cmd.cpp +0 -34
@@ 13,16 13,6 @@ namespace at
    Cmd::Cmd(std::string cmd, std::chrono::milliseconds timeout) noexcept : Cmd(cmd, cmd::Modifier::None, timeout)
    {}

    Cmd::Cmd(const Cmd &p) noexcept
    {
        *this = operator=(p);
    }

    Cmd::Cmd(Cmd &&p) noexcept
    {
        *this = operator=(p);
    }

    void Cmd::split(const std::string &str, Result &result)
    {
        constexpr char tokenDelimiter = ',';


@@ 37,30 27,6 @@ namespace at
        }
    }

    auto Cmd::operator=(const Cmd &p) noexcept -> Cmd &
    {
        if (&p == this) {
            return *this;
        }
        this->cmd     = p.cmd;
        this->timeout = p.timeout;
        this->mod     = p.mod;
        this->body    = p.body;
        return *this;
    }

    auto Cmd::operator=(Cmd &&p) noexcept -> Cmd &
    {
        if (&p == this) {
            return *this;
        }
        this->cmd     = std::move(p.cmd);
        this->timeout = std::move(p.timeout);
        this->mod     = std::move(p.mod);
        this->body    = std::move(p.body);
        return *this;
    }

    Result Cmd::parseBase(const Result &that)
    {
        auto result = that;

M module-db/CMakeLists.txt => module-db/CMakeLists.txt +1 -0
@@ 132,6 132,7 @@ target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_INCLUDES})

set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/Database/sqlite3vfs.cpp PROPERTIES COMPILE_FLAGS -Wno-overflow)
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/Database/sqlite3.c PROPERTIES COMPILE_FLAGS "-DSQLITE_DEFAULT_WAL_AUTOCHECKPOINT=1 -Wno-misleading-indentation")
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/Tables/NotesTable.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=narrowing")

target_compile_definitions(${PROJECT_NAME}


M module-db/Database/DatabaseInitializer.cpp => module-db/Database/DatabaseInitializer.cpp +1 -0
@@ 9,6 9,7 @@
#include <set>
#include <string>
#include <sstream>
#include <array>
#include <log/log.hpp>

DatabaseInitializer::DatabaseInitializer(Database *db) : db(db)

M module-db/Tables/NotesTable.cpp => module-db/Tables/NotesTable.cpp +1 -1
@@ 135,7 135,7 @@ std::pair<std::vector<NotesTableRow>, int> NotesTable::getByText(const std::stri
    auto retQuery = db->query(queryText.c_str());

    if (retQuery == nullptr || retQuery->getRowCount() == 0) {
        return {{}, count};
        return {{}, int(count)};
    }

    std::vector<NotesTableRow> records;

M module-services/CMakeLists.txt => module-services/CMakeLists.txt +0 -1
@@ 66,6 66,5 @@ target_compile_options(${PROJECT_NAME}
        -Wall
        $<$<COMPILE_LANGUAGE:C>:-std=gnu11>
        $<$<COMPILE_LANGUAGE:C>:-Wno-discarded-qualifiers>
        $<$<COMPILE_LANGUAGE:CXX>:-fno-non-call-exceptions>
        $<$<COMPILE_LANGUAGE:CXX>:-Wno-literal-suffix>
)

M module-services/service-cellular/service-cellular/requests/CallRequest.hpp => module-services/service-cellular/service-cellular/requests/CallRequest.hpp +1 -0
@@ 4,6 4,7 @@
#pragma once

#include <at/Result.hpp>
#include <memory>

#include "service-cellular/RequestHandler.hpp"
#include "service-cellular/requests/Request.hpp"

M module-services/service-fileindexer/Common.hpp => module-services/service-fileindexer/Common.hpp +1 -0
@@ 5,6 5,7 @@

#include <algorithm>
#include <filesystem>
#include <array>

namespace service::detail
{

M module-utils/unicode/ucs2/ucs2/UCS2.cpp => module-utils/unicode/ucs2/ucs2/UCS2.cpp +1 -0
@@ 11,6 11,7 @@
#include <iterator>
#include <locale>
#include <codecvt>
#include <array>

namespace ucs2
{

M module-utils/utility/Utils.hpp => module-utils/utility/Utils.hpp +1 -0
@@ 13,6 13,7 @@
#include <chrono>
#include <random>
#include <tuple>
#include <functional>

namespace utils
{

M module-utils/utility/ValueScaler.hpp => module-utils/utility/ValueScaler.hpp +1 -0
@@ 7,6 7,7 @@
#include <algorithm>
#include <optional>
#include <cmath>
#include <array>

namespace utils
{

M third-party/date => third-party/date +1 -1
@@ 1,1 1,1 @@
Subproject commit 4ed13fa351ae73ca7254068c3e193032d6ce9235
Subproject commit 38d9771211f09adfece42e2b2a24fc256c197383