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 }