summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibC/regex.cpp
blob: 394abb708a8826493bd3e5725948b52edf695219 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/*
 * Copyright (c) 2020, the SerenityOS developers.
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <AK/Assertions.h>
#include <LibDl/dlfcn.h>
#include <LibDl/dlfcn_integration.h>
#include <pthread.h>
#include <regex.h>

static void* s_libregex;
static pthread_mutex_t s_libregex_lock;

static int (*s_regcomp)(regex_t*, char const*, int);
static int (*s_regexec)(regex_t const*, char const*, size_t, regmatch_t[], int);
static size_t (*s_regerror)(int, regex_t const*, char*, size_t);
static void (*s_regfree)(regex_t*);

static void ensure_libregex()
{
    pthread_mutex_lock(&s_libregex_lock);
    if (!s_libregex) {
        s_libregex = __dlopen("libregex.so", RTLD_NOW).value();

        s_regcomp = reinterpret_cast<int (*)(regex_t*, char const*, int)>(__dlsym(s_libregex, "regcomp").value());
        s_regexec = reinterpret_cast<int (*)(regex_t const*, char const*, size_t, regmatch_t[], int)>(__dlsym(s_libregex, "regexec").value());
        s_regerror = reinterpret_cast<size_t (*)(int, regex_t const*, char*, size_t)>(__dlsym(s_libregex, "regerror").value());
        s_regfree = reinterpret_cast<void (*)(regex_t*)>(__dlsym(s_libregex, "regfree").value());
    }
    pthread_mutex_unlock(&s_libregex_lock);
}

extern "C" {

int __attribute__((weak)) regcomp(regex_t* reg, char const* pattern, int cflags)
{
    ensure_libregex();
    return s_regcomp(reg, pattern, cflags);
}

int __attribute__((weak)) regexec(regex_t const* reg, char const* string, size_t nmatch, regmatch_t pmatch[], int eflags)
{
    ensure_libregex();
    return s_regexec(reg, string, nmatch, pmatch, eflags);
}

size_t __attribute__((weak)) regerror(int errcode, regex_t const* reg, char* errbuf, size_t errbuf_size)
{
    ensure_libregex();
    return s_regerror(errcode, reg, errbuf, errbuf_size);
}

void __attribute__((weak)) regfree(regex_t* reg)
{
    ensure_libregex();
    return s_regfree(reg);
}
}