blob: 6ef79038aecc5bf1d64dead2c17ec3d08296d165 [file] [log] [blame]
Brian Silverman41cdd3e2019-01-19 19:48:58 -08001/*----------------------------------------------------------------------------*/
2/* Copyright (c) 2017-2018 FIRST. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
8#include "hal/Extensions.h"
9
10#include <wpi/SmallString.h>
11#include <wpi/StringRef.h>
12
13#include "hal/HAL.h"
14
15#if defined(WIN32) || defined(_WIN32)
16#include <windows.h>
17#else
18#include <dlfcn.h>
19#endif
20
21#if defined(WIN32) || defined(_WIN32)
22#define DELIM ';'
23#define HTYPE HMODULE
24#define DLOPEN(a) LoadLibrary(a)
25#define DLSYM GetProcAddress
26#define DLCLOSE FreeLibrary
27#else
28#define DELIM ':'
29#define HTYPE void*
30#define PREFIX "lib"
31#define DLOPEN(a) dlopen(a, RTLD_LAZY)
32#define DLSYM dlsym
33#define DLCLOSE dlclose
34#endif
35
36namespace hal {
37namespace init {
38void InitializeExtensions() {}
39} // namespace init
40} // namespace hal
41
42extern "C" {
43
44int HAL_LoadOneExtension(const char* library) {
45 int rc = 1; // It is expected and reasonable not to find an extra simulation
46 HTYPE handle = DLOPEN(library);
47#if !defined(WIN32) && !defined(_WIN32)
48 if (!handle) {
49 wpi::SmallString<128> libraryName("lib");
50 libraryName += library;
51#if defined(__APPLE__)
52 libraryName += ".dylib";
53#else
54 libraryName += ".so";
55#endif
56 handle = DLOPEN(libraryName.c_str());
57 }
58#endif
59 if (!handle) return rc;
60
61 auto init = reinterpret_cast<halsim_extension_init_func_t*>(
62 DLSYM(handle, "HALSIM_InitExtension"));
63
64 if (init) rc = (*init)();
65
66 if (rc != 0) DLCLOSE(handle);
67 return rc;
68}
69
70int HAL_LoadExtensions(void) {
71 int rc = 1;
72 wpi::SmallVector<wpi::StringRef, 2> libraries;
73 const char* e = std::getenv("HALSIM_EXTENSIONS");
74 if (!e) return rc;
75 wpi::StringRef env{e};
76 env.split(libraries, DELIM, -1, false);
77 for (auto& libref : libraries) {
78 wpi::SmallString<128> library(libref);
79 rc = HAL_LoadOneExtension(library.c_str());
80 if (rc < 0) break;
81 }
82 return rc;
83}
84
85} // extern "C"