mirror of
https://github.com/tursodatabase/libsql.git
synced 2025-02-24 10:55:35 +00:00
A common complain with libSQL is how to run extensions. The main mechanism, with a .so, has a lot of issues around how those .so are distributed. The most common extensions are the ones in the sqlean package. We can improve this experience by bundling them in our sqlite build. Not all SQLean extensions are kosher: some of them, like fileio, use the vfs. Others, are deemed too complex. The extensions included here are a subset that we deem important enough, and low risk enough, to just be a part of the main bundle.
68 lines
1.8 KiB
C
68 lines
1.8 KiB
C
// Copyright (c) 2024 Anton Zhiyanov, MIT License
|
|
// https://github.com/nalgeon/sqlean
|
|
|
|
// Case conversion functions for utf8 strings.
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
#include "text/utf8/rune.h"
|
|
#include "text/utf8/utf8.h"
|
|
|
|
// utf8_transform converts the utf8 string s using the transform function.
|
|
static bool utf8_transform(char* s, size_t n, uint32_t (*transform)(uint32_t)) {
|
|
utf8_decode_t d = {.state = 0};
|
|
while ((n > 0) & (*s != 0)) {
|
|
size_t i = 0;
|
|
do {
|
|
utf8_decode(&d, (uint8_t)s[i++]);
|
|
} while (d.state);
|
|
uint32_t c = transform(d.codep);
|
|
int len = utf8_encode(s, c);
|
|
if (len == 0) {
|
|
return false;
|
|
}
|
|
s += len;
|
|
n -= len;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// utf8_tolower converts the utf8 string s to lowercase.
|
|
// Returns true if successful, false if an error occurred.
|
|
bool utf8_tolower(char* s, size_t n) {
|
|
return utf8_transform(s, n, rune_tolower);
|
|
}
|
|
|
|
// utf8_toupper converts the utf8 string s to uppercase.
|
|
bool utf8_toupper(char* s, size_t n) {
|
|
return utf8_transform(s, n, rune_toupper);
|
|
}
|
|
|
|
// utf8_casefold converts the utf8 string s to folded-case.
|
|
bool utf8_casefold(char* s, size_t n) {
|
|
return utf8_transform(s, n, rune_casefold);
|
|
}
|
|
|
|
// utf8_totitle converts the utf8 string s to title-case.
|
|
bool utf8_totitle(char* s, size_t n) {
|
|
utf8_decode_t d = {.state = 0};
|
|
bool upper = true;
|
|
while ((n > 0) & (*s != 0)) {
|
|
size_t i = 0;
|
|
do {
|
|
utf8_decode(&d, (uint8_t)s[i++]);
|
|
} while (d.state);
|
|
uint32_t c = upper ? rune_toupper(d.codep) : rune_tolower(d.codep);
|
|
int len = utf8_encode(s, c);
|
|
if (len == 0) {
|
|
return false;
|
|
}
|
|
upper = !rune_isword(d.codep);
|
|
s += len;
|
|
n -= len;
|
|
}
|
|
return true;
|
|
}
|