Browse Source

Merge pull request #278 from jpcima/msvc-cmake

Build with MS compiler
pull/280/head
Filipe Coelho GitHub 4 years ago
parent
commit
7b707fff52
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 218 additions and 63 deletions
  1. +76
    -0
      .github/workflows/build.yml
  2. +2
    -0
      .gitignore
  3. +37
    -21
      cmake/DPF-plugin.cmake
  4. +17
    -12
      distrho/DistrhoUtils.hpp
  5. +5
    -1
      distrho/extra/String.hpp
  6. +2
    -2
      distrho/src/DistrhoDefines.h
  7. +2
    -2
      distrho/src/DistrhoUIInternal.hpp
  8. +4
    -1
      distrho/src/DistrhoUILV2.cpp
  9. +5
    -1
      distrho/src/dssi/dssi.h
  10. +9
    -1
      distrho/src/ladspa/ladspa.h
  11. +59
    -22
      utils/lv2-ttl-generator/lv2_ttl_generator.c

+ 76
- 0
.github/workflows/build.yml View File

@@ -82,3 +82,79 @@ jobs:
with: with:
name: macOS artifacts name: macOS artifacts
path: ${{runner.workspace}}/build/bin/ path: ${{runner.workspace}}/build/bin/

cmake_win32:
runs-on: windows-2019
steps:
- name: Set environment
run: |
echo "release_arch=Win32" >> "${Env:GITHUB_ENV}"
echo "vcpkg_triplet=x86-windows-static" >> "${Env:GITHUB_ENV}"
echo "vcpkg_git_commit_id=a3db16a4475b963cacf0260068c497fb72c8f3c0" >> "${Env:GITHUB_ENV}"
- name: Restore from cache and install vcpkg
uses: lukka/run-vcpkg@v6
with:
setupOnly: true
vcpkgTriplet: ${{env.vcpkg_triplet}}
vcpkgGitCommitId: ${{env.vcpkg_git_commit_id}}
#- name: Install packages
# run: |
# & "${Env:VCPKG_ROOT}/vcpkg" install "cairo:${Env:vcpkg_triplet}"
- uses: actions/checkout@v2
with:
submodules: recursive
- name: Create Build Environment
working-directory: ${{runner.workspace}}
run: cmake -E make_directory build
- name: Configure CMake
working-directory: ${{runner.workspace}}/build
run: |
cmake "${Env:GITHUB_WORKSPACE}" -G"Visual Studio 16 2019" -A"${Env:release_arch}" -DCMAKE_BUILD_TYPE="${Env:BUILD_TYPE}" -DVCPKG_TARGET_TRIPLET="${Env:vcpkg_triplet}" -DCMAKE_TOOLCHAIN_FILE="${Env:VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake"
- name: Build all
working-directory: ${{runner.workspace}}/build
run: cmake --build . --config "${Env:BUILD_TYPE}" -j 2
- name: Show built files
working-directory: ${{runner.workspace}}/build/bin
run: tree
- uses: actions/upload-artifact@v2
with:
name: Win32 artifacts
path: ${{runner.workspace}}/build/bin/

cmake_win64:
runs-on: windows-2019
steps:
- name: Set environment
run: |
echo "release_arch=x64" >> "${Env:GITHUB_ENV}"
echo "vcpkg_triplet=x64-windows-static" >> "${Env:GITHUB_ENV}"
echo "vcpkg_git_commit_id=a3db16a4475b963cacf0260068c497fb72c8f3c0" >> "${Env:GITHUB_ENV}"
- name: Restore from cache and install vcpkg
uses: lukka/run-vcpkg@v6
with:
setupOnly: true
vcpkgTriplet: ${{env.vcpkg_triplet}}
vcpkgGitCommitId: ${{env.vcpkg_git_commit_id}}
#- name: Install packages
# run: |
# & "${Env:VCPKG_ROOT}/vcpkg" install "cairo:${Env:vcpkg_triplet}"
- uses: actions/checkout@v2
with:
submodules: recursive
- name: Create Build Environment
working-directory: ${{runner.workspace}}
run: cmake -E make_directory build
- name: Configure CMake
working-directory: ${{runner.workspace}}/build
run: |
cmake "${Env:GITHUB_WORKSPACE}" -G"Visual Studio 16 2019" -A"${Env:release_arch}" -DCMAKE_BUILD_TYPE="${Env:BUILD_TYPE}" -DVCPKG_TARGET_TRIPLET="${Env:vcpkg_triplet}" -DCMAKE_TOOLCHAIN_FILE="${Env:VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake"
- name: Build all
working-directory: ${{runner.workspace}}/build
run: cmake --build . --config "${Env:BUILD_TYPE}" -j 2
- name: Show built files
working-directory: ${{runner.workspace}}/build/bin
run: tree
- uses: actions/upload-artifact@v2
with:
name: Win64 artifacts
path: ${{runner.workspace}}/build/bin/

+ 2
- 0
.gitignore View File

@@ -10,6 +10,8 @@
.kdev_include_paths .kdev_include_paths
.kdev4/ .kdev4/
.DS_Store .DS_Store
.vs/
CMakeSettings.json


bin/ bin/
build/ build/


+ 37
- 21
cmake/DPF-plugin.cmake View File

@@ -293,7 +293,8 @@ function(dpf__build_lv2 NAME DGL_LIBRARY MONOLITHIC)
COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR}
"$<TARGET_FILE:lv2_ttl_generator>" "$<TARGET_FILE:lv2_ttl_generator>"
"$<TARGET_FILE:${NAME}-lv2>" "$<TARGET_FILE:${NAME}-lv2>"
WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2")
WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2"
DEPENDS lv2_ttl_generator)
endfunction() endfunction()


# dpf__build_vst2 # dpf__build_vst2
@@ -488,6 +489,22 @@ function(dpf__add_dgl_system_libs)
# target_compile_definitions(dgl-system-libs-definitions INTERFACE "HAVE_XCURSOR") # target_compile_definitions(dgl-system-libs-definitions INTERFACE "HAVE_XCURSOR")
#endif() #endif()
endif() endif()

if(MSVC)
file(MAKE_DIRECTORY "${DPF_ROOT_DIR}/khronos/GL")
foreach(_gl_header "glext.h")
if(NOT EXISTS "${DPF_ROOT_DIR}/khronos/GL/${_gl_header}")
file(DOWNLOAD "https://www.khronos.org/registry/OpenGL/api/GL/${_gl_header}" "${DPF_ROOT_DIR}/khronos/GL/${_gl_header}" SHOW_PROGRESS)
endif()
endforeach()
foreach(_khr_header "khrplatform.h")
if(NOT EXISTS "${DPF_ROOT_DIR}/khronos/KHR/${_khr_header}")
file(DOWNLOAD "https://www.khronos.org/registry/EGL/api/KHR/${_khr_header}" "${DPF_ROOT_DIR}/khronos/KHR/${_khr_header}" SHOW_PROGRESS)
endif()
endforeach()
target_include_directories(dgl-system-libs-definitions INTERFACE "${DPF_ROOT_DIR}/khronos")
endif()

target_link_libraries(dgl-system-libs INTERFACE dgl-system-libs-definitions) target_link_libraries(dgl-system-libs INTERFACE dgl-system-libs-definitions)
endfunction() endfunction()


@@ -498,14 +515,7 @@ endfunction()
# #
function(dpf__add_executable NAME) function(dpf__add_executable NAME)
add_executable("${NAME}" ${ARGN}) add_executable("${NAME}" ${ARGN})
set_target_properties("${NAME}" PROPERTIES
POSITION_INDEPENDENT_CODE TRUE
C_VISIBILITY_PRESET "hidden"
CXX_VISIBILITY_PRESET "hidden"
VISIBILITY_INLINES_HIDDEN TRUE)
if (MINGW)
target_compile_options("${NAME}" PUBLIC "-mstackrealign")
endif()
dpf__set_target_defaults("${NAME}")
endfunction() endfunction()


# dpf__add_module # dpf__add_module
@@ -515,17 +525,7 @@ endfunction()
# #
function(dpf__add_module NAME) function(dpf__add_module NAME)
add_library("${NAME}" MODULE ${ARGN}) add_library("${NAME}" MODULE ${ARGN})
set_target_properties("${NAME}" PROPERTIES
POSITION_INDEPENDENT_CODE TRUE
C_VISIBILITY_PRESET "hidden"
CXX_VISIBILITY_PRESET "hidden"
VISIBILITY_INLINES_HIDDEN TRUE)
if ((NOT WIN32 AND NOT APPLE) OR MINGW)
target_link_libraries("${NAME}" PRIVATE "-Wl,--no-undefined")
endif()
if (MINGW)
target_compile_options("${NAME}" PUBLIC "-mstackrealign")
endif()
dpf__set_target_defaults("${NAME}")
endfunction() endfunction()


# dpf__add_static_library # dpf__add_static_library
@@ -535,14 +535,30 @@ endfunction()
# #
function(dpf__add_static_library NAME) function(dpf__add_static_library NAME)
add_library("${NAME}" STATIC ${ARGN}) add_library("${NAME}" STATIC ${ARGN})
dpf__set_target_defaults("${NAME}")
endfunction()

# dpf__set_target_defaults
# ------------------------------------------------------------------------------
#
# Set default properties which must apply to all DPF-defined targets.
#
function(dpf__set_target_defaults NAME)
set_target_properties("${NAME}" PROPERTIES set_target_properties("${NAME}" PROPERTIES
POSITION_INDEPENDENT_CODE TRUE POSITION_INDEPENDENT_CODE TRUE
C_VISIBILITY_PRESET "hidden" C_VISIBILITY_PRESET "hidden"
CXX_VISIBILITY_PRESET "hidden" CXX_VISIBILITY_PRESET "hidden"
VISIBILITY_INLINES_HIDDEN TRUE) VISIBILITY_INLINES_HIDDEN TRUE)
if(WIN32)
target_compile_definitions("${NAME}" PUBLIC "NOMINMAX")
endif()
if (MINGW) if (MINGW)
target_compile_options("${NAME}" PUBLIC "-mstackrealign") target_compile_options("${NAME}" PUBLIC "-mstackrealign")
endif() endif()
if (MSVC)
target_compile_options("${NAME}" PUBLIC "/UTF-8")
target_compile_definitions("${NAME}" PUBLIC "_CRT_SECURE_NO_WARNINGS")
endif()
endfunction() endfunction()


# dpf__add_plugin_main # dpf__add_plugin_main
@@ -597,7 +613,7 @@ function(dpf__add_lv2_ttl_generator)
return() return()
endif() endif()
add_executable(lv2_ttl_generator "${DPF_ROOT_DIR}/utils/lv2-ttl-generator/lv2_ttl_generator.c") add_executable(lv2_ttl_generator "${DPF_ROOT_DIR}/utils/lv2-ttl-generator/lv2_ttl_generator.c")
if(NOT WINDOWS AND NOT APPLE AND NOT HAIKU)
if((NOT WIN32) AND (NOT APPLE) AND (NOT HAIKU))
target_link_libraries(lv2_ttl_generator "dl") target_link_libraries(lv2_ttl_generator "dl")
endif() endif()
endfunction() endfunction()


+ 17
- 12
distrho/DistrhoUtils.hpp View File

@@ -33,6 +33,11 @@
# include <stdint.h> # include <stdint.h>
#endif #endif


#if defined(DISTRHO_OS_WINDOWS) && defined(_MSC_VER)
#include <basetsd.h>
typedef SSIZE_T ssize_t;
#endif

#if defined(DISTRHO_OS_MAC) && ! defined(CARLA_OS_MAC) && ! defined(DISTRHO_PROPER_CPP11_SUPPORT) #if defined(DISTRHO_OS_MAC) && ! defined(CARLA_OS_MAC) && ! defined(DISTRHO_PROPER_CPP11_SUPPORT)
namespace std { namespace std {
inline float fmin(float __x, float __y) inline float fmin(float __x, float __y)
@@ -94,12 +99,12 @@ static inline
void d_debug(const char* const fmt, ...) noexcept void d_debug(const char* const fmt, ...) noexcept
{ {
try { try {
::va_list args;
::va_start(args, fmt);
va_list args;
va_start(args, fmt);
std::fprintf(stdout, "\x1b[30;1m"); std::fprintf(stdout, "\x1b[30;1m");
std::vfprintf(stdout, fmt, args); std::vfprintf(stdout, fmt, args);
std::fprintf(stdout, "\x1b[0m\n"); std::fprintf(stdout, "\x1b[0m\n");
::va_end(args);
va_end(args);
} catch (...) {} } catch (...) {}
} }
#endif #endif
@@ -111,11 +116,11 @@ static inline
void d_stdout(const char* const fmt, ...) noexcept void d_stdout(const char* const fmt, ...) noexcept
{ {
try { try {
::va_list args;
::va_start(args, fmt);
va_list args;
va_start(args, fmt);
std::vfprintf(stdout, fmt, args); std::vfprintf(stdout, fmt, args);
std::fprintf(stdout, "\n"); std::fprintf(stdout, "\n");
::va_end(args);
va_end(args);
} catch (...) {} } catch (...) {}
} }


@@ -126,11 +131,11 @@ static inline
void d_stderr(const char* const fmt, ...) noexcept void d_stderr(const char* const fmt, ...) noexcept
{ {
try { try {
::va_list args;
::va_start(args, fmt);
va_list args;
va_start(args, fmt);
std::vfprintf(stderr, fmt, args); std::vfprintf(stderr, fmt, args);
std::fprintf(stderr, "\n"); std::fprintf(stderr, "\n");
::va_end(args);
va_end(args);
} catch (...) {} } catch (...) {}
} }


@@ -141,12 +146,12 @@ static inline
void d_stderr2(const char* const fmt, ...) noexcept void d_stderr2(const char* const fmt, ...) noexcept
{ {
try { try {
::va_list args;
::va_start(args, fmt);
va_list args;
va_start(args, fmt);
std::fprintf(stderr, "\x1b[31m"); std::fprintf(stderr, "\x1b[31m");
std::vfprintf(stderr, fmt, args); std::vfprintf(stderr, fmt, args);
std::fprintf(stderr, "\x1b[0m\n"); std::fprintf(stderr, "\x1b[0m\n");
::va_end(args);
va_end(args);
} catch (...) {} } catch (...) {}
} }




+ 5
- 1
distrho/extra/String.hpp View File

@@ -651,14 +651,18 @@ public:
"abcdefghijklmnopqrstuvwxyz" "abcdefghijklmnopqrstuvwxyz"
"0123456789+/"; "0123456789+/";


#ifndef _MSC_VER
const std::size_t kTmpBufSize = std::min(d_nextPowerOf2(static_cast<uint32_t>(dataSize/3)), 65536U); const std::size_t kTmpBufSize = std::min(d_nextPowerOf2(static_cast<uint32_t>(dataSize/3)), 65536U);
#else
constexpr std::size_t kTmpBufSize = 65536U;
#endif


const uchar* bytesToEncode((const uchar*)data); const uchar* bytesToEncode((const uchar*)data);


uint i=0, j=0; uint i=0, j=0;
uint charArray3[3], charArray4[4]; uint charArray3[3], charArray4[4];


char strBuf[kTmpBufSize+1];
char strBuf[kTmpBufSize + 1];
strBuf[kTmpBufSize] = '\0'; strBuf[kTmpBufSize] = '\0';
std::size_t strBufIndex = 0; std::size_t strBufIndex = 0;




+ 2
- 2
distrho/src/DistrhoDefines.h View File

@@ -55,7 +55,7 @@
# if HAVE_CPP11_SUPPORT # if HAVE_CPP11_SUPPORT
# define DISTRHO_PROPER_CPP11_SUPPORT # define DISTRHO_PROPER_CPP11_SUPPORT
# endif # endif
#elif __cplusplus >= 201103L || (defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 405) || __has_extension(cxx_noexcept)
#elif __cplusplus >= 201103L || (defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 405) || __has_extension(cxx_noexcept) || (defined(_MSC_VER) && _MSVC_LANG >= 201103L)
# define DISTRHO_PROPER_CPP11_SUPPORT # define DISTRHO_PROPER_CPP11_SUPPORT
# if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407 && ! defined(__clang__)) || (defined(__clang__) && ! __has_extension(cxx_override_control)) # if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407 && ! defined(__clang__)) || (defined(__clang__) && ! __has_extension(cxx_override_control))
# define override // gcc4.7+ only # define override // gcc4.7+ only
@@ -74,7 +74,7 @@
#if defined(__GNUC__) #if defined(__GNUC__)
# define DISTRHO_DEPRECATED __attribute__((deprecated)) # define DISTRHO_DEPRECATED __attribute__((deprecated))
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
# define DISTRHO_DEPRECATED __declspec(deprecated)
# define DISTRHO_DEPRECATED [[deprecated]] /* Note: __declspec(deprecated) it not applicable to enum members */
#else #else
# define DISTRHO_DEPRECATED # define DISTRHO_DEPRECATED
#endif #endif


+ 2
- 2
distrho/src/DistrhoUIInternal.hpp View File

@@ -48,9 +48,9 @@ extern Window* d_lastUiWindow;
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
UI* createUiWrapper(void* dspPtr, uintptr_t winId, double scaleFactor, const char* bundlePath);
UI* createUiWrapper(void* const dspPtr, const uintptr_t winId, const double scaleFactor, const char* const bundlePath);
#else // DISTRHO_PLUGIN_HAS_EXTERNAL_UI #else // DISTRHO_PLUGIN_HAS_EXTERNAL_UI
UI* createUiWrapper(void* dspPtr, Window* window);
UI* createUiWrapper(void* const dspPtr, Window* const window);
#endif #endif


#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI


+ 4
- 1
distrho/src/DistrhoUILV2.cpp View File

@@ -289,7 +289,7 @@ protected:


// reserve atom space // reserve atom space
const size_t atomSize = sizeof(LV2_Atom) + msgSize; const size_t atomSize = sizeof(LV2_Atom) + msgSize;
char atomBuf[atomSize];
char* const atomBuf = (char*)malloc(atomSize);
std::memset(atomBuf, 0, atomSize); std::memset(atomBuf, 0, atomSize);


// set atom info // set atom info
@@ -302,6 +302,9 @@ protected:


// send to DSP side // send to DSP side
fWriteFunction(fController, eventInPortIndex, atomSize, fURIDs.atomEventTransfer, atom); fWriteFunction(fController, eventInPortIndex, atomSize, fURIDs.atomEventTransfer, atom);

// free atom space
free(atomBuf);
} }


#if DISTRHO_PLUGIN_WANT_MIDI_INPUT #if DISTRHO_PLUGIN_WANT_MIDI_INPUT


+ 5
- 1
distrho/src/dssi/dssi.h View File

@@ -35,6 +35,10 @@
extern "C" { extern "C" {
#endif #endif


#ifndef DSSI_PLUGIN_EXPORT
# define DSSI_PLUGIN_EXPORT LADSPA_PLUGIN_EXPORT
#endif

/* /*
There is a need for an API that supports hosted MIDI soft synths There is a need for an API that supports hosted MIDI soft synths
with GUIs in Linux audio applications. In time the GMPI initiative with GUIs in Linux audio applications. In time the GMPI initiative
@@ -411,7 +415,7 @@ typedef struct _DSSI_Descriptor {
* of a distinct plugin type. * of a distinct plugin type.
*/ */


const DSSI_Descriptor *dssi_descriptor(unsigned long Index);
DSSI_PLUGIN_EXPORT const DSSI_Descriptor *dssi_descriptor(unsigned long Index);
typedef const DSSI_Descriptor *(*DSSI_Descriptor_Function)(unsigned long Index); typedef const DSSI_Descriptor *(*DSSI_Descriptor_Function)(unsigned long Index);




+ 9
- 1
distrho/src/ladspa/ladspa.h View File

@@ -30,6 +30,14 @@
extern "C" { extern "C" {
#endif #endif


#ifndef LADSPA_PLUGIN_EXPORT
# ifdef _WIN32
# define LADSPA_PLUGIN_EXPORT __declspec(dllexport)
# else
# define LADSPA_PLUGIN_EXPORT __attribute__((visibility("default")))
# endif
#endif

/*****************************************************************************/ /*****************************************************************************/


/* Overview: /* Overview:
@@ -586,7 +594,7 @@ typedef struct _LADSPA_Descriptor {
returning NULL, so the plugin count can be determined by checking returning NULL, so the plugin count can be determined by checking
for the least index that results in NULL being returned. */ for the least index that results in NULL being returned. */


const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index);
LADSPA_PLUGIN_EXPORT const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index);


/* Datatype corresponding to the ladspa_descriptor() function. */ /* Datatype corresponding to the ladspa_descriptor() function. */
typedef const LADSPA_Descriptor * typedef const LADSPA_Descriptor *


+ 59
- 22
utils/lv2-ttl-generator/lv2_ttl_generator.c View File

@@ -15,6 +15,7 @@
*/ */


#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>


#ifdef _WIN32 #ifdef _WIN32
@@ -30,6 +31,11 @@


typedef void (*TTL_Generator_Function)(const char* basename); typedef void (*TTL_Generator_Function)(const char* basename);


static int isPathSeparator(char c);
static char* makeNormalPath(const char* path);

// TODO support Unicode paths on the Windows platform

int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if (argc != 2) if (argc != 2)
@@ -38,10 +44,12 @@ int main(int argc, char* argv[])
return 1; return 1;
} }


const char* path = argv[1];

#ifdef TTL_GENERATOR_WINDOWS #ifdef TTL_GENERATOR_WINDOWS
const HMODULE handle = LoadLibraryA(argv[1]);
const HMODULE handle = LoadLibraryA(path);
#else #else
void* const handle = dlopen(argv[1], RTLD_LAZY);
void* const handle = dlopen(path, RTLD_LAZY);
#endif #endif


if (! handle) if (! handle)
@@ -62,31 +70,32 @@ int main(int argc, char* argv[])


if (ttlFn != NULL) if (ttlFn != NULL)
{ {
char basename[strlen(argv[1])+1];
// convert the paths to a normalized form, such that path separators are
// replaced with '/', and duplicate separators are removed
char* normalPath = makeNormalPath(path);


#ifdef TTL_GENERATOR_WINDOWS
char* base2 = strrchr(argv[1], '\\');
#else
char* base2 = strrchr(argv[1], '/');
#endif
if (base2 != NULL)
{
strcpy(basename, base2+1);
basename[strrchr(base2, '.')-base2-1] = '\0';
}
else if (argv[1][0] == '.' && argv[1][1] == '/')
{
strcpy(basename, argv[1]+2);
basename[strrchr(basename, '.')-basename] = '\0';
}
// get rid of any "./" prefixes
path = normalPath;
while (path[0] == '.' && path[1] == '/')
path += 2;

// extract the file name part
char* basename = strrchr(path, '/');
if (basename != NULL)
basename += 1;
else else
{
strcpy(basename, argv[1]);
}
basename = (char*)path;

// remove the file extension
char* dotPos = strrchr(basename, '.');
if (dotPos)
*dotPos = '\0';


printf("Generate ttl data for '%s', basename: '%s'\n", argv[1], basename);
printf("Generate ttl data for '%s', basename: '%s'\n", path, basename);


ttlFn(basename); ttlFn(basename);

free(normalPath);
} }
else else
printf("Failed to find 'lv2_generate_ttl' function\n"); printf("Failed to find 'lv2_generate_ttl' function\n");
@@ -99,3 +108,31 @@ int main(int argc, char* argv[])


return 0; return 0;
} }

static int isPathSeparator(char c)
{
#ifdef TTL_GENERATOR_WINDOWS
return c == '/' || c == '\\';
#else
return c == '/';
#endif
}

static char* makeNormalPath(const char* path)
{
size_t i, j;
size_t len = strlen(path);
char* result = (char*)malloc(len + 1);
int isSep, wasSep = 0;
for (i = 0, j = 0; i < len; ++i)
{
isSep = isPathSeparator(path[i]);
if (!isSep)
result[j++] = path[i];
else if (!wasSep)
result[j++] = '/';
wasSep = isSep;
}
result[j] = '\0';
return result;
}

Loading…
Cancel
Save