DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

lv2_ttl_generator.c (3819B)


      1 /*
      2  * DISTRHO Plugin Framework (DPF)
      3  * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com>
      4  *
      5  * Permission to use, copy, modify, and/or distribute this software for any purpose with
      6  * or without fee is hereby granted, provided that the above copyright notice and this
      7  * permission notice appear in all copies.
      8  *
      9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
     10  * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
     11  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
     12  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
     13  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
     14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     15  */
     16 
     17 #include <stdio.h>
     18 #include <stdlib.h>
     19 #include <string.h>
     20 
     21 #ifdef _WIN32
     22  #include <windows.h>
     23  #define TTL_GENERATOR_WINDOWS
     24 #else
     25  #include <dlfcn.h>
     26 #endif
     27 
     28 #ifndef nullptr
     29  #define nullptr (0)
     30 #endif
     31 
     32 typedef void (*TTL_Generator_Function)(const char* basename);
     33 
     34 static int isPathSeparator(char c);
     35 static char* makeNormalPath(const char* path);
     36 
     37 // TODO support Unicode paths on the Windows platform
     38 
     39 int main(int argc, char* argv[])
     40 {
     41     if (argc != 2)
     42     {
     43         printf("usage: %s /path/to/plugin-DLL\n", argv[0]);
     44         return 1;
     45     }
     46 
     47     const char* path = argv[1];
     48 
     49 #ifdef TTL_GENERATOR_WINDOWS
     50     const HMODULE handle = LoadLibraryA(path);
     51 #else
     52     void* const handle = dlopen(path, RTLD_LAZY);
     53 #endif
     54 
     55     if (! handle)
     56     {
     57 #ifdef TTL_GENERATOR_WINDOWS
     58         printf("Failed to open plugin DLL\n");
     59 #else
     60         printf("Failed to open plugin DLL, error was:\n%s\n", dlerror());
     61 #endif
     62         return 2;
     63     }
     64 
     65 #ifdef TTL_GENERATOR_WINDOWS
     66 # if defined(__GNUC__) && (__GNUC__ >= 9)
     67 #  pragma GCC diagnostic push
     68 #  pragma GCC diagnostic ignored "-Wcast-function-type"
     69 # endif
     70     const TTL_Generator_Function ttlFn = (TTL_Generator_Function)GetProcAddress(handle, "lv2_generate_ttl");
     71 # if defined(__GNUC__) && (__GNUC__ >= 9)
     72 #  pragma GCC diagnostic pop
     73 # endif
     74 #else
     75     const TTL_Generator_Function ttlFn = (TTL_Generator_Function)dlsym(handle, "lv2_generate_ttl");
     76 #endif
     77 
     78     if (ttlFn != NULL)
     79     {
     80         // convert the paths to a normalized form, such that path separators are
     81         // replaced with '/', and duplicate separators are removed
     82         char* normalPath = makeNormalPath(path);
     83 
     84         // get rid of any "./" prefixes
     85         path = normalPath;
     86         while (path[0] == '.' && path[1] == '/')
     87             path += 2;
     88 
     89         // extract the file name part
     90         char* basename = strrchr(path, '/');
     91         if (basename != NULL)
     92             basename += 1;
     93         else
     94             basename = (char*)path;
     95 
     96         // remove the file extension
     97         char* dotPos = strrchr(basename, '.');
     98         if (dotPos)
     99             *dotPos = '\0';
    100 
    101         printf("Generate ttl data for '%s', basename: '%s'\n", path, basename);
    102 
    103         ttlFn(basename);
    104 
    105         free(normalPath);
    106     }
    107     else
    108         printf("Failed to find 'lv2_generate_ttl' function\n");
    109 
    110 #ifdef TTL_GENERATOR_WINDOWS
    111     FreeLibrary(handle);
    112 #else
    113     dlclose(handle);
    114 #endif
    115 
    116     return 0;
    117 }
    118 
    119 static int isPathSeparator(char c)
    120 {
    121 #ifdef TTL_GENERATOR_WINDOWS
    122     return c == '/' || c == '\\';
    123 #else
    124     return c == '/';
    125 #endif
    126 }
    127 
    128 static char* makeNormalPath(const char* path)
    129 {
    130     size_t i, j;
    131     size_t len = strlen(path);
    132     char* result = (char*)malloc(len + 1);
    133     int isSep, wasSep = 0;
    134     for (i = 0, j = 0; i < len; ++i)
    135     {
    136         isSep = isPathSeparator(path[i]);
    137         if (!isSep)
    138             result[j++] = path[i];
    139         else if (!wasSep)
    140             result[j++] = '/';
    141         wasSep = isSep;
    142     }
    143     result[j] = '\0';
    144     return result;
    145 }