xot 0.3.14 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/release-gem.yml +10 -1
- data/.github/workflows/test.yml +9 -0
- data/ChangeLog.md +14 -0
- data/VERSION +1 -1
- data/include/xot/defs.h +1 -1
- data/include/xot/ref.h +145 -0
- data/include/xot/string.h +24 -10
- data/include/xot/windows.h +5 -1
- data/lib/xot/extconf.rb +2 -2
- data/lib/xot/extension.rb +1 -1
- data/lib/xot/rake/util.rb +22 -10
- data/lib/xot/rake.rb +5 -1
- data/lib/xot/util.rb +9 -0
- data/src/string.cpp +60 -16
- data/test/test_util.rb +33 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7e347867590b9d9d97a002320ac500f075dde62556b0944b2a35705b415e2806
|
|
4
|
+
data.tar.gz: c684375fa42a755e7cef817aad1c658fd26f484b515876cb35323e56e1c313bd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d94d2378ba6835df631dd21ef26140f3cc43af8c370478d7b7c6ce0e6e433fd08deafa45810970995942e3f1a1f04f4343894aa9ce5c5a276c60f442f1faf0de
|
|
7
|
+
data.tar.gz: 2dd7f8827dd1804be81babfe7b89410f41a96b280ac57f30724c67b63b3356a2ab71cddb4d10465e4ee49c34450d1e5f961dff24a84931a89a0bbf5f60159cda
|
|
@@ -26,8 +26,17 @@ jobs:
|
|
|
26
26
|
- name: setup dependencies
|
|
27
27
|
run: "ruby -I.github/workflows -rutils -e 'setup_dependencies'"
|
|
28
28
|
|
|
29
|
+
- name: packages
|
|
30
|
+
run: bundle exec rake packages
|
|
31
|
+
|
|
32
|
+
- name: setup zig
|
|
33
|
+
if: github.event.repository.name == 'reflex-terminal'
|
|
34
|
+
uses: mlugg/setup-zig@v2
|
|
35
|
+
with:
|
|
36
|
+
version: 0.16.0
|
|
37
|
+
|
|
29
38
|
- name: test
|
|
30
|
-
run: bundle exec rake
|
|
39
|
+
run: bundle exec rake test
|
|
31
40
|
|
|
32
41
|
- name: create gem
|
|
33
42
|
id: gem
|
data/.github/workflows/test.yml
CHANGED
|
@@ -27,6 +27,15 @@ jobs:
|
|
|
27
27
|
- name: packages
|
|
28
28
|
run: bundle exec rake verbose packages
|
|
29
29
|
|
|
30
|
+
- name: setup zig
|
|
31
|
+
if: github.event.repository.name == 'reflex-terminal'
|
|
32
|
+
uses: mlugg/setup-zig@v2
|
|
33
|
+
with:
|
|
34
|
+
version: 0.16.0
|
|
35
|
+
|
|
36
|
+
- name: vendor
|
|
37
|
+
run: bundle exec rake vendor
|
|
38
|
+
|
|
30
39
|
- name: lib
|
|
31
40
|
run: bundle exec rake verbose lib
|
|
32
41
|
|
data/ChangeLog.md
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
# xot ChangeLog
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## [v0.4.0] - 2026-08-04
|
|
5
|
+
|
|
6
|
+
- [BREAKING] Rework String conversions to std::wstring and CFString
|
|
7
|
+
- Add a String constructor taking a pointer and a size
|
|
8
|
+
- Add Xot.warn with a uniq option to suppress duplicate warnings
|
|
9
|
+
- Let a source raise _WIN32_WINNT above the Windows 7 baseline
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## [v0.3.15] - 2026-06-23
|
|
13
|
+
|
|
14
|
+
- Add WeakRef for weak references to RefCountable
|
|
15
|
+
- Compile vendored C sources with the C compiler
|
|
16
|
+
|
|
17
|
+
|
|
4
18
|
## [v0.3.14] - 2026-06-12
|
|
5
19
|
|
|
6
20
|
- Link static archive explicitly in export_all_symbols on ucrt32
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.4.0
|
data/include/xot/defs.h
CHANGED
data/include/xot/ref.h
CHANGED
|
@@ -28,6 +28,28 @@ namespace Xot
|
|
|
28
28
|
class EmptyClass {};
|
|
29
29
|
|
|
30
30
|
|
|
31
|
+
struct WeakRefCount : public NonCopyable
|
|
32
|
+
{
|
|
33
|
+
|
|
34
|
+
bool alive = true;
|
|
35
|
+
|
|
36
|
+
int ref_count = 1;
|
|
37
|
+
|
|
38
|
+
void retain ()
|
|
39
|
+
{
|
|
40
|
+
++ref_count;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
void release ()
|
|
44
|
+
{
|
|
45
|
+
assert(ref_count > 0);
|
|
46
|
+
|
|
47
|
+
if (--ref_count == 0) delete this;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
};// WeakRefCount
|
|
51
|
+
|
|
52
|
+
|
|
31
53
|
template <typename SuperClass = EmptyClass>
|
|
32
54
|
class RefCountable : public SuperClass, public NonCopyable
|
|
33
55
|
{
|
|
@@ -61,6 +83,12 @@ namespace Xot
|
|
|
61
83
|
if (del) delete this;
|
|
62
84
|
}
|
|
63
85
|
|
|
86
|
+
WeakRefCount* get_weak_ref_count ()
|
|
87
|
+
{
|
|
88
|
+
if (!wref_count) wref_count = new WeakRefCount();
|
|
89
|
+
return wref_count;
|
|
90
|
+
}
|
|
91
|
+
|
|
64
92
|
virtual void* rucy_wrapper_value () const
|
|
65
93
|
{
|
|
66
94
|
return NULL;
|
|
@@ -86,12 +114,20 @@ namespace Xot
|
|
|
86
114
|
|
|
87
115
|
virtual ~RefCountable ()
|
|
88
116
|
{
|
|
117
|
+
if (wref_count)
|
|
118
|
+
{
|
|
119
|
+
wref_count->alive = false;
|
|
120
|
+
wref_count->release();
|
|
121
|
+
wref_count = NULL;
|
|
122
|
+
}
|
|
89
123
|
}
|
|
90
124
|
|
|
91
125
|
private:
|
|
92
126
|
|
|
93
127
|
mutable int refc_count = 0;
|
|
94
128
|
|
|
129
|
+
WeakRefCount* wref_count = NULL;
|
|
130
|
+
|
|
95
131
|
int refc_update_count (bool increment) const
|
|
96
132
|
{
|
|
97
133
|
int c = refc_count + (increment ? +1 : -1);
|
|
@@ -304,6 +340,115 @@ namespace Xot
|
|
|
304
340
|
};// Ref
|
|
305
341
|
|
|
306
342
|
|
|
343
|
+
template <typename T>
|
|
344
|
+
class WeakRef
|
|
345
|
+
{
|
|
346
|
+
|
|
347
|
+
typedef WeakRef<T> This;
|
|
348
|
+
|
|
349
|
+
typedef T Value;
|
|
350
|
+
|
|
351
|
+
typedef const T ConstValue;
|
|
352
|
+
|
|
353
|
+
typedef T& Reference;
|
|
354
|
+
|
|
355
|
+
typedef const T& ConstReference;
|
|
356
|
+
|
|
357
|
+
typedef T* Pointer;
|
|
358
|
+
|
|
359
|
+
typedef const T* ConstPointer;
|
|
360
|
+
|
|
361
|
+
public:
|
|
362
|
+
|
|
363
|
+
WeakRef (Pointer ptr = NULL)
|
|
364
|
+
{
|
|
365
|
+
reset(ptr);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
WeakRef (const This& obj)
|
|
369
|
+
{
|
|
370
|
+
reset(obj.ptr, obj.wref_count);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
This& operator = (Pointer ptr)
|
|
374
|
+
{
|
|
375
|
+
reset(ptr);
|
|
376
|
+
return *this;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
This& operator = (const This& obj)
|
|
380
|
+
{
|
|
381
|
+
if (&obj != this) reset(obj.ptr, obj.wref_count);
|
|
382
|
+
return *this;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
~WeakRef ()
|
|
386
|
+
{
|
|
387
|
+
if (wref_count) wref_count->release();
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
void reset (Pointer ptr = NULL)
|
|
391
|
+
{
|
|
392
|
+
reset(ptr, ptr ? ptr->get_weak_ref_count() : NULL);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
Pointer get () {return wref_count && wref_count->alive ? ptr : NULL;}
|
|
396
|
+
|
|
397
|
+
ConstPointer get () const {return wref_count && wref_count->alive ? ptr : NULL;}
|
|
398
|
+
|
|
399
|
+
Pointer operator -> () {return get();}
|
|
400
|
+
|
|
401
|
+
ConstPointer operator -> () const {return get();}
|
|
402
|
+
|
|
403
|
+
Reference operator * () {return *get();}
|
|
404
|
+
|
|
405
|
+
ConstReference operator * () const {return *get();}
|
|
406
|
+
|
|
407
|
+
operator Pointer () {return get();}
|
|
408
|
+
|
|
409
|
+
operator ConstPointer () const {return get();}
|
|
410
|
+
|
|
411
|
+
bool operator == (Pointer ptr) const {return get() == ptr;}
|
|
412
|
+
|
|
413
|
+
bool operator != (Pointer ptr) const {return !operator==(ptr);}
|
|
414
|
+
|
|
415
|
+
bool operator == (ConstPointer ptr) const {return get() == ptr;}
|
|
416
|
+
|
|
417
|
+
bool operator != (ConstPointer ptr) const {return !operator==(ptr);}
|
|
418
|
+
|
|
419
|
+
bool operator == (const This& obj) const {return get() == obj.get();}
|
|
420
|
+
|
|
421
|
+
bool operator != (const This& obj) const {return !operator==(obj);}
|
|
422
|
+
|
|
423
|
+
template <typename X>
|
|
424
|
+
bool operator == (const WeakRef<X>& obj) const {return get() == obj.get();}
|
|
425
|
+
|
|
426
|
+
template <typename X>
|
|
427
|
+
bool operator != (const WeakRef<X>& obj) const {return !operator==(obj);}
|
|
428
|
+
|
|
429
|
+
bool operator < (const This& obj) const {return get() < obj.get();}
|
|
430
|
+
|
|
431
|
+
operator bool () const {return get();}
|
|
432
|
+
|
|
433
|
+
bool operator ! () const {return !operator bool();}
|
|
434
|
+
|
|
435
|
+
private:
|
|
436
|
+
|
|
437
|
+
void reset (Pointer ptr, WeakRefCount* count)
|
|
438
|
+
{
|
|
439
|
+
if (count) count->retain();
|
|
440
|
+
if (wref_count) wref_count->release();
|
|
441
|
+
this->ptr = ptr;
|
|
442
|
+
this->wref_count = count;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
Pointer ptr = NULL;
|
|
446
|
+
|
|
447
|
+
WeakRefCount* wref_count = NULL;
|
|
448
|
+
|
|
449
|
+
};// WeakRef
|
|
450
|
+
|
|
451
|
+
|
|
307
452
|
}// Xot
|
|
308
453
|
|
|
309
454
|
|
data/include/xot/string.h
CHANGED
|
@@ -26,7 +26,9 @@
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
#if defined(OSX) || defined(IOS)
|
|
29
|
-
|
|
29
|
+
|
|
30
|
+
struct __CFString;
|
|
31
|
+
|
|
30
32
|
#endif
|
|
31
33
|
|
|
32
34
|
|
|
@@ -34,6 +36,13 @@ namespace Xot
|
|
|
34
36
|
{
|
|
35
37
|
|
|
36
38
|
|
|
39
|
+
#if defined(OSX) || defined(IOS)
|
|
40
|
+
|
|
41
|
+
typedef std::shared_ptr<const __CFString> CFStringPtr;
|
|
42
|
+
|
|
43
|
+
#endif
|
|
44
|
+
|
|
45
|
+
|
|
37
46
|
class String : public std::string
|
|
38
47
|
{
|
|
39
48
|
|
|
@@ -45,6 +54,8 @@ namespace Xot
|
|
|
45
54
|
|
|
46
55
|
String (const char* str);
|
|
47
56
|
|
|
57
|
+
String (const char* str, size_t size);
|
|
58
|
+
|
|
48
59
|
String (const std::string& str);
|
|
49
60
|
|
|
50
61
|
template <typename ITERATOR>
|
|
@@ -64,6 +75,18 @@ namespace Xot
|
|
|
64
75
|
|
|
65
76
|
friend String operator + (const char* lhs, const String& rhs);
|
|
66
77
|
|
|
78
|
+
#if defined(OSX) || defined(IOS)
|
|
79
|
+
|
|
80
|
+
CFStringPtr to_cfstr () const;
|
|
81
|
+
|
|
82
|
+
#elif defined(WIN32)
|
|
83
|
+
|
|
84
|
+
String (const wchar_t* str, size_t size);
|
|
85
|
+
|
|
86
|
+
std::wstring to_wstr () const;
|
|
87
|
+
|
|
88
|
+
#endif
|
|
89
|
+
|
|
67
90
|
};// String
|
|
68
91
|
|
|
69
92
|
|
|
@@ -79,15 +102,6 @@ namespace Xot
|
|
|
79
102
|
template <typename T> String to_s (const T& val);
|
|
80
103
|
|
|
81
104
|
|
|
82
|
-
#if defined(OSX) || defined(IOS)
|
|
83
|
-
|
|
84
|
-
typedef std::shared_ptr<const __CFString> CFStringPtr;
|
|
85
|
-
|
|
86
|
-
CFStringPtr cfstring (const char* str);
|
|
87
|
-
|
|
88
|
-
#endif
|
|
89
|
-
|
|
90
|
-
|
|
91
105
|
}// Xot
|
|
92
106
|
|
|
93
107
|
|
data/include/xot/windows.h
CHANGED
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
|
|
7
7
|
#ifdef WIN32
|
|
8
8
|
#undef _WIN32_WINNT
|
|
9
|
-
#
|
|
9
|
+
#ifdef XOT_WIN32_WINNT
|
|
10
|
+
#define _WIN32_WINNT XOT_WIN32_WINNT
|
|
11
|
+
#else
|
|
12
|
+
#define _WIN32_WINNT _WIN32_WINNT_WIN7
|
|
13
|
+
#endif
|
|
10
14
|
#include <windows.h>
|
|
11
15
|
#include <windowsx.h>
|
|
12
16
|
#endif
|
data/lib/xot/extconf.rb
CHANGED
|
@@ -51,8 +51,8 @@ module Xot
|
|
|
51
51
|
local_libs << 'stdc++' if gcc?
|
|
52
52
|
|
|
53
53
|
$CPPFLAGS = make_cppflags $CPPFLAGS, defs, inc_dirs
|
|
54
|
-
$CFLAGS =
|
|
55
|
-
$CXXFLAGS =
|
|
54
|
+
$CFLAGS = make_cxxflags $CFLAGS + ' -x c++'
|
|
55
|
+
$CXXFLAGS = make_cxxflags $CXXFLAGS + ' -x c++' if $CXXFLAGS
|
|
56
56
|
$LDFLAGS = make_ldflags ldflags, lib_dirs, frameworks
|
|
57
57
|
$LOCAL_LIBS << local_libs.reverse.map {|s| " -l#{s}"}.join
|
|
58
58
|
end
|
data/lib/xot/extension.rb
CHANGED
data/lib/xot/rake/util.rb
CHANGED
|
@@ -213,22 +213,28 @@ module Xot
|
|
|
213
213
|
[root, RbConfig::CONFIG['rubyarchhdrdir'] || "#{root}/#{RUBY_PLATFORM}"]
|
|
214
214
|
end
|
|
215
215
|
|
|
216
|
-
def make_cflags(flags = '')
|
|
217
|
-
|
|
218
|
-
|
|
216
|
+
def make_cflags(flags = '', std: 'gnu17', stdlib: nil)
|
|
217
|
+
warn_opts = %w[no-unknown-pragmas]
|
|
218
|
+
warn_opts += %w[
|
|
219
219
|
no-deprecated-register
|
|
220
220
|
no-reserved-user-defined-literal
|
|
221
221
|
] if clang?
|
|
222
|
+
|
|
222
223
|
s = flags.dup
|
|
223
|
-
s <<
|
|
224
|
-
s << " -
|
|
225
|
-
s <<
|
|
226
|
-
s << ' -
|
|
227
|
-
s << ' ' + RbConfig::CONFIG['debugflags']
|
|
228
|
-
s.gsub!(/-O\d?\w*/, '-O0')
|
|
224
|
+
s << " -arch arm64" if osx? && arm64?
|
|
225
|
+
s << " -std=#{std}" if clang? || gcc? || emcc?
|
|
226
|
+
s << " -stdlib=#{stdlib}" if clang? && stdlib
|
|
227
|
+
s << ' -mmacosx-version-min=10.10' if clang? && osx?
|
|
228
|
+
s << ' ' + RbConfig::CONFIG['debugflags'] if debug?
|
|
229
|
+
s.gsub!(/-O\d?\w*/, '-O0') if debug?
|
|
230
|
+
s << warn_opts.map {|s| " -W#{s}"}.join
|
|
229
231
|
s
|
|
230
232
|
end
|
|
231
233
|
|
|
234
|
+
def make_cxxflags(flags = '')
|
|
235
|
+
make_cflags flags, std: 'c++20', stdlib: 'libc++'
|
|
236
|
+
end
|
|
237
|
+
|
|
232
238
|
def make_ldflags(flags = '', libdirs = [], frameworks = [])
|
|
233
239
|
s = flags.dup
|
|
234
240
|
s << libdirs.map {|s| " -L#{s}"}.join
|
|
@@ -242,11 +248,17 @@ module Xot
|
|
|
242
248
|
make_cppflags flags, defs, inc_dirs
|
|
243
249
|
end
|
|
244
250
|
|
|
251
|
+
def cflags(warnings = true)
|
|
252
|
+
cflags = get_env :CFLAGS, RbConfig::CONFIG['CFLAGS']
|
|
253
|
+
cflags = cflags.gsub(/-W[\w\-\=]+/, '') + ' -w' unless warnings
|
|
254
|
+
make_cflags cflags
|
|
255
|
+
end
|
|
256
|
+
|
|
245
257
|
def cxxflags(warnings = true)
|
|
246
258
|
cflags = get_env :CFLAGS, RbConfig::CONFIG['CFLAGS']
|
|
247
259
|
cxxflags = get_env :CXXFLAGS, RbConfig::CONFIG['CXXFLAGS']
|
|
248
260
|
cflags = cflags.gsub(/-W[\w\-\=]+/, '') + ' -w' unless warnings
|
|
249
|
-
|
|
261
|
+
make_cxxflags "#{cflags} #{cxxflags}"
|
|
250
262
|
end
|
|
251
263
|
|
|
252
264
|
def arflags()
|
data/lib/xot/rake.rb
CHANGED
|
@@ -327,7 +327,11 @@ module Xot
|
|
|
327
327
|
unless get_env :VENDOR_NOCOMPILE, false
|
|
328
328
|
vendor_srcs_map(*srcdirs).each do |src, obj|
|
|
329
329
|
rake_puts "compiling #{src}"
|
|
330
|
-
|
|
330
|
+
if File.extname(src) == '.c'
|
|
331
|
+
sh %( #{cc} -c #{cppflags} #{cflags false} -o #{obj} #{src} )
|
|
332
|
+
else
|
|
333
|
+
sh %( #{cxx} -c #{cppflags} #{cxxflags false} -o #{obj} #{src} )
|
|
334
|
+
end
|
|
331
335
|
end
|
|
332
336
|
end
|
|
333
337
|
end
|
data/lib/xot/util.rb
CHANGED
|
@@ -6,6 +6,15 @@ module Xot
|
|
|
6
6
|
|
|
7
7
|
extend module Util
|
|
8
8
|
|
|
9
|
+
def warn(message, uniq: false)
|
|
10
|
+
if uniq
|
|
11
|
+
@warnings__ ||= {}
|
|
12
|
+
return if @warnings__[message]
|
|
13
|
+
@warnings__[message] = true
|
|
14
|
+
end
|
|
15
|
+
Kernel.warn message
|
|
16
|
+
end
|
|
17
|
+
|
|
9
18
|
def get_env!(name, defval = nil)
|
|
10
19
|
val = ENV[name.to_s] || Object.const_get(name) rescue defval
|
|
11
20
|
val.dup rescue val
|
data/src/string.cpp
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
#include "xot/string.h"
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
#include <limits.h>
|
|
4
5
|
#include <stdio.h>
|
|
5
6
|
#include <string.h>
|
|
6
7
|
#include <algorithm>
|
|
7
8
|
#include "xot/exception.h"
|
|
8
9
|
|
|
9
10
|
#if defined(OSX) || defined(IOS)
|
|
10
|
-
#import <CoreFoundation/CoreFoundation.h>
|
|
11
|
+
#import <CoreFoundation/CoreFoundation.h>
|
|
12
|
+
#elif defined(WIN32)
|
|
13
|
+
#include "xot/windows.h"
|
|
11
14
|
#endif
|
|
12
15
|
|
|
13
16
|
|
|
@@ -24,6 +27,11 @@ namespace Xot
|
|
|
24
27
|
{
|
|
25
28
|
}
|
|
26
29
|
|
|
30
|
+
String::String (const char* str, size_t size)
|
|
31
|
+
: Super(str, size)
|
|
32
|
+
{
|
|
33
|
+
}
|
|
34
|
+
|
|
27
35
|
String::String (const std::string& str)
|
|
28
36
|
: Super(str)
|
|
29
37
|
{
|
|
@@ -88,6 +96,57 @@ namespace Xot
|
|
|
88
96
|
return t;
|
|
89
97
|
}
|
|
90
98
|
|
|
99
|
+
#if defined(OSX) || defined(IOS)
|
|
100
|
+
|
|
101
|
+
static void
|
|
102
|
+
release_cfstring (CFTypeRef ref)
|
|
103
|
+
{
|
|
104
|
+
if (ref) CFRelease(ref);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
CFStringPtr
|
|
108
|
+
String::to_cfstr () const
|
|
109
|
+
{
|
|
110
|
+
return CFStringPtr(
|
|
111
|
+
CFStringCreateWithCString(kCFAllocatorDefault, c_str(), kCFStringEncodingUTF8),
|
|
112
|
+
release_cfstring);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
#elif defined(WIN32)
|
|
116
|
+
|
|
117
|
+
String::String (const wchar_t* str, size_t size)
|
|
118
|
+
{
|
|
119
|
+
if (size > INT_MAX)
|
|
120
|
+
argument_error(__FILE__, __LINE__);
|
|
121
|
+
if (!str || size == 0) return;
|
|
122
|
+
|
|
123
|
+
int len = WideCharToMultiByte(CP_UTF8, 0, str, (int) size, NULL, 0, NULL, NULL);
|
|
124
|
+
if (len <= 0) system_error(__FILE__, __LINE__);
|
|
125
|
+
|
|
126
|
+
resize((size_t) len);
|
|
127
|
+
WideCharToMultiByte(CP_UTF8, 0, str, (int) size, &(*this)[0], len, NULL, NULL);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
std::wstring
|
|
131
|
+
String::to_wstr () const
|
|
132
|
+
{
|
|
133
|
+
if (empty()) return std::wstring();
|
|
134
|
+
|
|
135
|
+
size_t size = this->size();
|
|
136
|
+
if (size > INT_MAX)
|
|
137
|
+
invalid_state_error(__FILE__, __LINE__);
|
|
138
|
+
|
|
139
|
+
int len = MultiByteToWideChar(CP_UTF8, 0, data(), (int) size, NULL, 0);
|
|
140
|
+
if (len <= 0) system_error(__FILE__, __LINE__);
|
|
141
|
+
|
|
142
|
+
std::wstring result;
|
|
143
|
+
result.resize((size_t) len);
|
|
144
|
+
MultiByteToWideChar(CP_UTF8, 0, data(), (int) size, &result[0], len);
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
#endif
|
|
149
|
+
|
|
91
150
|
|
|
92
151
|
String
|
|
93
152
|
stringf (const char* format, ...)
|
|
@@ -199,21 +258,6 @@ namespace Xot
|
|
|
199
258
|
return to_s((CFStringRef) val.get());
|
|
200
259
|
}
|
|
201
260
|
|
|
202
|
-
|
|
203
|
-
static void
|
|
204
|
-
release_cfstring (CFTypeRef ref)
|
|
205
|
-
{
|
|
206
|
-
if (ref) CFRelease(ref);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
CFStringPtr
|
|
210
|
-
cfstring (const char* str)
|
|
211
|
-
{
|
|
212
|
-
CFStringRef ref = CFStringCreateWithCString(
|
|
213
|
-
kCFAllocatorDefault, str, kCFStringEncodingUTF8);
|
|
214
|
-
return CFStringPtr(ref, release_cfstring);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
261
|
#endif
|
|
218
262
|
|
|
219
263
|
|
data/test/test_util.rb
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require_relative 'helper'
|
|
2
|
+
require 'stringio'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class TestUtil < Test::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
def util()
|
|
8
|
+
Object.new.extend Xot::Util
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def capture_stderr(&block)
|
|
12
|
+
stderr, $stderr = $stderr, StringIO.new
|
|
13
|
+
block.call
|
|
14
|
+
$stderr.string
|
|
15
|
+
ensure
|
|
16
|
+
$stderr = stderr
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def test_warn()
|
|
20
|
+
u = util
|
|
21
|
+
assert_equal "x\nx\n", capture_stderr {u.warn "x"; u.warn "x"}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_warn_uniq()
|
|
25
|
+
u = util
|
|
26
|
+
assert_equal "x\ny\n", capture_stderr {
|
|
27
|
+
u.warn "x", uniq: true
|
|
28
|
+
u.warn "x", uniq: true
|
|
29
|
+
u.warn "y", uniq: true
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end# TestUtil
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: xot
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- xordog
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-08-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: This library include some useful utility classes and functions for development
|
|
14
14
|
with C++.
|
|
@@ -81,6 +81,7 @@ files:
|
|
|
81
81
|
- test/test_setter.rb
|
|
82
82
|
- test/test_tester.rb
|
|
83
83
|
- test/test_universal_accessor.rb
|
|
84
|
+
- test/test_util.rb
|
|
84
85
|
- xot.gemspec
|
|
85
86
|
homepage: https://github.com/xord/xot
|
|
86
87
|
licenses:
|
|
@@ -119,3 +120,4 @@ test_files:
|
|
|
119
120
|
- test/test_setter.rb
|
|
120
121
|
- test/test_tester.rb
|
|
121
122
|
- test/test_universal_accessor.rb
|
|
123
|
+
- test/test_util.rb
|