mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-08 01:45:32 +00:00
329 lines
6.3 KiB
C++
329 lines
6.3 KiB
C++
#pragma once
|
|
#include "kmx_u16.h"
|
|
#include "xstring.h"
|
|
|
|
std::vector<signed long long> createIntVector(signed long long in1, signed long long in2 , signed long long in3 , signed long long in4 )
|
|
{
|
|
std::vector<signed long long> V_in;
|
|
if ( in1 !=-1) V_in.push_back(in1);
|
|
if (in2 != -1) V_in.push_back(in2);
|
|
if (in3 != -1) V_in.push_back(in3);
|
|
if (in4 != -1) V_in.push_back(in4);
|
|
return V_in;
|
|
}
|
|
|
|
std::string toHex(int num1) {
|
|
if (num1 == 0)
|
|
return "0";
|
|
int num = num1;
|
|
std::string s = "";
|
|
while (num) {
|
|
int temp = num % 16;
|
|
if (temp <= 9)
|
|
s += (48 + temp);
|
|
else
|
|
s += (87 + temp);
|
|
num = num / 16;
|
|
}
|
|
reverse(s.begin(), s.end());
|
|
return s;
|
|
}
|
|
|
|
void u16printf(km_kbp_cp** dst, char sys, km_kbp_cp sep, std::vector<signed long long> V_in, km_kbp_cp* src1 , const km_kbp_cp* src2 , const km_kbp_cp* src3 )
|
|
{
|
|
// CAUTION: this function does not replace swprintf() or wsprintf() for general purpose -> it is only suitable for special contexts in kmcompx. !!
|
|
// The function takes 2 const char16_t* ( if available) and a vector of signed long long as input, concats and saves result to dst
|
|
// it prints in the following order src1, all V_in, src2, src3
|
|
// sep to seperate integer values
|
|
// sys = 'i' -> insert second text before numbers ( src1, src2, all V_in, src3)
|
|
// sys = 'c' -> write integer value in V_in as char
|
|
// sys = 'd' -> write integer value in V_in decimal number
|
|
// sys = 'x' -> write integer value in V_in hex number
|
|
// sys = 'u' -> write integer value in V_in unicode x0024
|
|
|
|
char digit;
|
|
std::string s = "";
|
|
std::string s0, sx;
|
|
km_kbp_cp text[4096];
|
|
km_kbp_cp target[4096];
|
|
km_kbp_cp* cpl = text;
|
|
km_kbp_cp* o = cpl;
|
|
|
|
if (sys == 'i')
|
|
u16ncat(src1, src2, xstrlen(src1));
|
|
|
|
// handle first text src1
|
|
if (src1 != NULL) {
|
|
while (*src1)
|
|
*cpl++ = *src1++;
|
|
}
|
|
|
|
// handle numbers according to the variable sys.
|
|
for (int j = 0; j < V_in.size(); j++) {
|
|
// convert int to char
|
|
if (sys == 'c')
|
|
s = s + (char)V_in[j] + ".";
|
|
|
|
// similar to use of L"%d" in swprintf()
|
|
if ((sys == 'd') || (sys == 'i'))
|
|
s = s + std::to_string(V_in[j]) + ".";
|
|
|
|
//similar to use of L"%x" in swprintf()
|
|
if (sys == 'x')
|
|
s = s + toHex(V_in[j]) + ".";
|
|
|
|
//similar to use of L"x%04.4x " in swprintf()
|
|
if (sys == 'u') {
|
|
s0 = 'x';
|
|
sx = toHex(V_in[j]);
|
|
if (sx.size() < 5) {
|
|
for (int i = 0; i < 4 - sx.size(); i++)
|
|
s0 = s0 + '0';
|
|
}
|
|
s = s + s0 + toHex(V_in[j]) + " .";
|
|
}
|
|
}
|
|
if (s.size() > 1)
|
|
s.pop_back();
|
|
|
|
for (int i = 0; i < s.length(); i++) {
|
|
digit = s[i];
|
|
if (s[i] != '.') {
|
|
target[i] = 0x0030 + ((int)digit - (int)'0');
|
|
}
|
|
else
|
|
target[i] = sep;
|
|
target[i + 1] = 0;
|
|
|
|
*cpl++ = target[i];
|
|
}
|
|
|
|
if (sys != 'i')
|
|
{
|
|
// handle second text src2
|
|
if (src2 != NULL) {
|
|
*cpl++ = 0x0020;
|
|
while (*src2)
|
|
*cpl++ = *src2++;
|
|
}
|
|
// handle third text src3
|
|
if (src3 != NULL) {
|
|
//*cpl++ = 0x0020;
|
|
while (*src3)
|
|
*cpl++ = *src3++;
|
|
}
|
|
}
|
|
*cpl++ = 0;
|
|
*dst = o;
|
|
}
|
|
|
|
void u16printf(KMX_WCHAR** dst, KMX_WCHAR* src1, KMX_WCHAR* src2)
|
|
{
|
|
// simple version for printing 2 KMX_WCHAR only
|
|
char16_t text0[256];
|
|
char16_t* cpl = text0;
|
|
char16_t* o = text0;
|
|
|
|
while (*src1)
|
|
*cpl++ = *src1++;
|
|
|
|
*cpl++ = src2[0];
|
|
|
|
*cpl++ = 0;
|
|
*dst = o;
|
|
}
|
|
|
|
const KMX_WCHAR * u16ncat(KMX_WCHAR *dst, const KMX_WCHAR *src, size_t max) {
|
|
KMX_WCHAR* o = dst;
|
|
dst = dst + max;
|
|
while (*src) {
|
|
*dst++ = *src++;
|
|
}
|
|
*dst = 0;
|
|
return o;
|
|
}
|
|
|
|
const KMX_WCHAR * u16chr(const KMX_WCHAR *p, KMX_WCHAR ch) {
|
|
while (*p) {
|
|
if (*p == ch) return p;
|
|
p++;
|
|
}
|
|
return ch == 0 ? p : NULL;
|
|
}
|
|
|
|
const KMX_WCHAR * u16cpy(KMX_WCHAR *dst, const KMX_WCHAR *src) {
|
|
KMX_WCHAR *o = dst;
|
|
while (*src) {
|
|
*dst++ = *src++;
|
|
}
|
|
*dst = 0;
|
|
return o;
|
|
}
|
|
|
|
const KMX_WCHAR * u16ncpy(KMX_WCHAR *dst, const KMX_WCHAR *src, size_t max) {
|
|
KMX_WCHAR *o = dst;
|
|
while (*src && max > 0) {
|
|
*dst++ = *src++;
|
|
max--;
|
|
}
|
|
while(max > 0) {
|
|
*dst++ = 0;
|
|
max--;
|
|
}
|
|
return o;
|
|
}
|
|
|
|
size_t u16len(const KMX_WCHAR *p) {
|
|
int i = 0;
|
|
while (*p) {
|
|
p++;
|
|
i++;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
size_t u16lenQ(const KMX_WCHAR *p) {
|
|
int i = 0;
|
|
while (*p) {
|
|
p++;
|
|
i++;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
int u16cmp(const KMX_WCHAR *p, const KMX_WCHAR *q) {
|
|
while (*p && *q) {
|
|
if (*p != *q) return *p - *q;
|
|
p++;
|
|
q++;
|
|
}
|
|
return *p - *q;
|
|
}
|
|
|
|
int u16icmp(const KMX_WCHAR *p, const KMX_WCHAR *q) {
|
|
while (*p && *q) {
|
|
if (toupper(*p) != toupper(*q)) return *p - *q;
|
|
p++;
|
|
q++;
|
|
}
|
|
return *p - *q;
|
|
}
|
|
|
|
int u16ncmp(const KMX_WCHAR *p, const KMX_WCHAR *q, size_t count) {
|
|
while (*p && *q && count) {
|
|
if (*p != *q) return *p - *q;
|
|
p++;
|
|
q++;
|
|
count--;
|
|
}
|
|
if (count)
|
|
return *p - *q;
|
|
return 0;
|
|
}
|
|
|
|
KMX_WCHAR * u16tok(KMX_WCHAR *p, KMX_WCHAR ch, KMX_WCHAR **ctx) {
|
|
if (!p) {
|
|
p = *ctx;
|
|
if (!p) return NULL;
|
|
}
|
|
|
|
km_kbp_cp *q = p;
|
|
while (*q && *q != ch) {
|
|
q++;
|
|
}
|
|
if (*q) {
|
|
*q = 0;
|
|
q++;
|
|
while (*q == ch) q++;
|
|
*ctx = q;
|
|
}
|
|
else {
|
|
*ctx = NULL;
|
|
}
|
|
return p;
|
|
}
|
|
|
|
km_kbp_cp * u16tok(km_kbp_cp* p, km_kbp_cp* ch, km_kbp_cp** ctx) {
|
|
if (!p) {
|
|
p = *ctx;
|
|
if (!p) return NULL;
|
|
}
|
|
|
|
km_kbp_cp* q = p;
|
|
while (*q && *q != *ch) {
|
|
q++;
|
|
}
|
|
if (*q) {
|
|
*q = 0;
|
|
q++;
|
|
while (*q == *ch) q++;
|
|
*ctx = q;
|
|
}
|
|
else {
|
|
*ctx = NULL;
|
|
}
|
|
return p;
|
|
}
|
|
|
|
long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base)
|
|
{
|
|
int pwr;
|
|
char first = static_cast<char>(towupper(*str));
|
|
int offset;
|
|
|
|
if (base == 16 && first == 'U') {
|
|
offset = 3;
|
|
(str)++;
|
|
if (*str != '+') return 0;
|
|
(str)++;
|
|
}
|
|
|
|
else if ((base == 16 && first == 'X') || (base == 10 && first == 'D')) {
|
|
offset =2 ;
|
|
(str)++;
|
|
}
|
|
|
|
else if (base == 8 && first<10)
|
|
offset = 1;
|
|
|
|
else
|
|
return 0;
|
|
|
|
long int num = 0;
|
|
pwr = (int) pow( base, (int) u16len(str) - offset);
|
|
for (int i = u16len(str) - 1; i >= 0; i--)
|
|
{
|
|
char tst = static_cast<char>(towupper(*str));
|
|
num += (((int)(tst)) - 48) * pwr;
|
|
pwr = pwr / base;
|
|
str++;
|
|
}
|
|
return num;
|
|
}
|
|
|
|
double u16tof( KMX_WCHAR* str)
|
|
{
|
|
double val = 0;
|
|
int offsetdot=0;
|
|
char digit;
|
|
|
|
PKMX_WCHAR q = (PKMX_WCHAR)u16chr(str, '.');
|
|
int pos_dot = q-str ;
|
|
|
|
if (pos_dot < 0)
|
|
pos_dot = u16len(str);
|
|
|
|
for (int i = 0; i < u16len(str); i++)
|
|
{
|
|
digit = static_cast<char>(towupper(*str));
|
|
|
|
if ((i > pos_dot - 1) )
|
|
offsetdot = 1;
|
|
|
|
if (digit != '.')
|
|
val =val+ ((int(digit)) - 48) * pow(10, (pos_dot - 1- i + offsetdot));
|
|
|
|
str++;
|
|
}
|
|
return val;
|
|
}
|