Запись и чтение из файла с символом "точка с запятой"

Приключилась история, у VLC SDK, под Windows имеется проблема с заголовочными файлами (включая MSYS2).

В общем, при переносе плагина с *nix, в заголовочном файле vlc_threads.h написано:

static inline int vlc_poll(struct pollfd *fds, unsigned nfds, int timeout)
{
    int val;

    vlc_testcancel();
    val = poll(fds, nfds, timeout);
    if (val < 0)
        vlc_testcancel();
    return val;
}
# define poll(u,n,t) vlc_poll(u, n, t)

И ни один из компиляторов не хочет это кушать. Говоря о том что сначала poll не определен, а так же libtorrent-rasterbar, который использует boost, не может обратиться к функии poll из-за того что определен макрос.

Я решил пойти путем таким, качаем SDK, распаковываем (он нам нужен только на момент сборки библиотеки), далее если сборка под WIN32, идем в папку с заголовками, читаем файл, выпилываем оттуда макрос, с заменой:

if (WIN32)
  include (FetchContent)
  cmake_policy (SET CMP0135 NEW)

  FetchContent_Declare (
    vlc_windows
    URL "https://github.com/evo-i/vlc-bittorrent-sdk-windows/raw/vlc-3.0.32-win64/vlc-3.0.21-win64.7z")

  FetchContent_MakeAvailable(vlc_windows)

  add_library (libvlccore SHARED IMPORTED)
  set_target_properties (libvlccore
    PROPERTIES
      IMPORTED_IMPLIB "${vlc_windows_SOURCE_DIR}/sdk/lib/libvlccore.lib"
      INTERFACE_INCLUDE_DIRECTORIES "${vlc_windows_SOURCE_DIR}/sdk/include/vlc/plugins")
  add_library (Vendor::VlcPlugin ALIAS libvlccore)

  if (NOT DEFINED VLC_THREADS_FIXED)
    file (READ
      "${vlc_windows_SOURCE_DIR}/sdk/include/vlc/plugins/vlc_threads.h"
      VLC_THREADS_BUG)
    string (REPLACE "val = poll(fds, nfds, timeout)"
                    "val = vlc_poll(fds, nfds, timeout)"
            VLC_THREADS_NO_THREADS_BUG
            ${VLC_THREADS_BUG})
    string (REPLACE "# define poll(u,n,t) vlc_poll(u, n, t)" ""
            VLC_THREADS_NO_MORE_BUGS
            ${VLC_THREADS_NO_THREADS_BUG})
    
    file (WRITE
          "${vlc_windows_SOURCE_DIR}/sdk/include/vlc/plugins/vlc_threads.h"
          ${VLC_THREADS_NO_MORE_BUGS})
    
    unset (VLC_THREADS_NO_MORE_BUGS)
    set (VLC_THREADS_FIXED 1 CACHE BOOL "" FORCE)
  endif (NOT DEFINED VLC_THREADS_FIXED)
else (WIN32)
...

И так, при записи в файл все хорошо, только нет ни одной точки с запятой ;! Все съел CMake! Думая что это список...

Можно ли как-то его попросить этого не делать? При чтении или записи... Ну уж очень нужно это сделать.


Ответы (1 шт):

Автор решения: Pavel Tsayukov

Когда передаём variable reference ${some_variable}, переменнная раскрывается до своего значения (а внутри if после этого попытается раскрыться ещё раз), но если эта переменная — список, т.е. содержит хотя бы одну неэкранированную ;, то такой список развернётся, например, "a;b;c" в "a" "b" "c". Чтобы предотвратить разворачивание списка, достаточно обернуть variable reference в кавычки, чтобы переменная раскрылась как одна строка.

То есть в данном случае:

string(REPLACE "val = poll(fds, nfds, timeout)"
               "val = vlc_poll(fds, nfds, timeout)"
       VLC_THREADS_NO_THREADS_BUG
       "${VLC_THREADS_BUG}")
→ Ссылка