gogyou 0.2.4 → 0.2.5
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/HISTORY.ja.md +14 -0
- data/README.md +4 -7
- data/Rakefile +7 -1
- data/gemstub.rb +11 -5
- data/lib/gogyou.rb +8 -0
- data/lib/gogyou/accessor.rb +114 -0
- data/lib/gogyou/model.rb +55 -24
- data/lib/gogyou/version.rb +1 -1
- data/pointer.ja.md +104 -0
- metadata +13 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 163f1b2f74bea2dc136f06beb499aaf9904db858
|
|
4
|
+
data.tar.gz: b7d8d846d1dfa2ee4747ab51d5dabdf29bdc63f4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e0ab33b2ed9a6758fdd4d784839138aa78f1ef17ba18def71a46063bf8a95ed7e5b52241635abfd247c117056457bf526c25e6701425d9fc010dfb3c72a17f0d
|
|
7
|
+
data.tar.gz: 44db392c49b2afe2649b1815ea12e3770499ae0697eb848bb0744953990d25b760000c3bcf905d62fdc62bf2159c63909686c490482e2e40d2fd54fd5ef1cdea
|
data/HISTORY.ja.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# gogyou の更新履歴
|
|
2
2
|
|
|
3
|
+
## gogyou-0.2.5 (2015-10-20)
|
|
4
|
+
|
|
5
|
+
* 可変長要素に続く要素の定義
|
|
6
|
+
|
|
7
|
+
構造体定義中に可変長要素を置いた場合、続く要素を定義出来ませんでしたがこの制限を撤廃しています。
|
|
8
|
+
|
|
9
|
+
この場合、可変長要素の可変長領域と、続く要素の領域以降が重なるため、部分的に union を用いたような動作となります。
|
|
10
|
+
|
|
11
|
+
* ポインタ要素の実現 (実験的)
|
|
12
|
+
|
|
13
|
+
非常に限定的ながらポインタ要素の定義を可能としました。
|
|
14
|
+
詳細は pointer.ja.md を参照して下さい。
|
|
15
|
+
|
|
16
|
+
|
|
3
17
|
## gogyou-0.2.4 (2015-10-16)
|
|
4
18
|
|
|
5
19
|
* 環境依存の型に対する結果の正確性を修正
|
data/README.md
CHANGED
|
@@ -23,7 +23,7 @@ ruby 構文による、C 言語の構造体・共用体・多次元配列 (も
|
|
|
23
23
|
* Distribute License (頒布ライセンス): 2-clause BSD License (二条項 BSD ライセンス)
|
|
24
24
|
* Software Quarity (ソフトウェア品質): EXPERIMENTAL
|
|
25
25
|
* User (想定利用者): Rubyist
|
|
26
|
-
* Release Number (リリースナンバー): 0.2.
|
|
26
|
+
* Release Number (リリースナンバー): 0.2.5
|
|
27
27
|
* Memory Usage (使用メモリ量): 2 MB +
|
|
28
28
|
* Installed Size (インストール容量): under 1 MB
|
|
29
29
|
* Project Page: <https://osdn.jp/projects/rutsubo/>
|
|
@@ -32,7 +32,7 @@ ruby 構文による、C 言語の構造体・共用体・多次元配列 (も
|
|
|
32
32
|
## Example
|
|
33
33
|
|
|
34
34
|
ruby/ruby.h の ``struct RBasic`` と ``struct RObject`` を gogyou を用いて次のように記述出来ます
|
|
35
|
-
(
|
|
35
|
+
(ポインタの定義は ``uintptr_t`` で置き換えています):
|
|
36
36
|
|
|
37
37
|
``` ruby:ruby
|
|
38
38
|
require "gogyou"
|
|
@@ -54,8 +54,8 @@ module MyRuby
|
|
|
54
54
|
union -> {
|
|
55
55
|
struct -> {
|
|
56
56
|
long :numiv
|
|
57
|
-
uintptr_t :ivptr
|
|
58
|
-
uintptr_t :iv_index_tbl
|
|
57
|
+
uintptr_t :ivptr # VALUE *ivptr
|
|
58
|
+
uintptr_t :iv_index_tbl # struct st_table *iv_index_tbl
|
|
59
59
|
}, :heap
|
|
60
60
|
VALUE :ary, ROBJECT_EMBED_LEN_MAX
|
|
61
61
|
}, :as
|
|
@@ -632,9 +632,6 @@ data = YourStruct.bind(ptr)
|
|
|
632
632
|
|
|
633
633
|
## Demerit (短所)
|
|
634
634
|
|
|
635
|
-
* Can't be handled pointer
|
|
636
|
-
(ポインタが扱えない)
|
|
637
|
-
|
|
638
635
|
* The cost is high for reference/asignment from/to fields
|
|
639
636
|
(フィールドに対する参照・代入のコストが高い)
|
|
640
637
|
|
data/Rakefile
CHANGED
|
@@ -24,7 +24,8 @@ GEMSTUB.extensions += EXTCONF
|
|
|
24
24
|
GEMSTUB.executables += FileList["bin/*"].map { |n| File.basename n }
|
|
25
25
|
GEMSTUB.executables.sort!
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
PACKAGENAME = "#{GEMSTUB.name}-#{GEMSTUB.version}"
|
|
28
|
+
GEMFILE = "#{PACKAGENAME}.gem"
|
|
28
29
|
GEMSPEC = "#{GEMSTUB.name}.gemspec"
|
|
29
30
|
|
|
30
31
|
GEMSTUB.files += DOC + EXT + EXTCONF + BIN + LIB + SPEC + TEST + EXAMPLE + RAKEFILE + EXTRA
|
|
@@ -143,6 +144,11 @@ task gem: GEMFILE
|
|
|
143
144
|
desc "generate gemspec"
|
|
144
145
|
task gemspec: GEMSPEC
|
|
145
146
|
|
|
147
|
+
desc "print package name"
|
|
148
|
+
task "package-name" do
|
|
149
|
+
puts PACKAGENAME
|
|
150
|
+
end
|
|
151
|
+
|
|
146
152
|
file GEMFILE => DOC + EXT + EXTCONF + BIN + LIB + SPEC + TEST + EXAMPLE + RAKEFILE + [GEMSPEC] do
|
|
147
153
|
sh "gem build #{GEMSPEC}"
|
|
148
154
|
end
|
data/gemstub.rb
CHANGED
|
@@ -10,11 +10,15 @@ The gogyou is a library written at pure ruby that provides auxiliary features of
|
|
|
10
10
|
|
|
11
11
|
The C-liked struct, union and multidimensional array definition are posible in ruby syntax.
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
Available features:
|
|
14
|
+
|
|
15
|
+
(1) nested struct and union with anonymous field
|
|
16
|
+
(2) multidimensional array
|
|
17
|
+
(3) field of variable array
|
|
18
|
+
(4) const field
|
|
19
|
+
(5) packed field
|
|
20
|
+
(6) user definition types
|
|
21
|
+
(7) (EXPERIMENTAL AND LIMITATION FEATURE) pointer
|
|
18
22
|
EOS
|
|
19
23
|
s.license = "2-clause BSD License"
|
|
20
24
|
s.author = "dearblue"
|
|
@@ -26,6 +30,8 @@ EOS
|
|
|
26
30
|
s.add_development_dependency "rake", "~> 10.0"
|
|
27
31
|
end
|
|
28
32
|
|
|
33
|
+
DOC << "pointer.ja.md"
|
|
34
|
+
|
|
29
35
|
primitives = "lib/gogyou/primitives.rb"
|
|
30
36
|
mkprims = "mkprims.rb"
|
|
31
37
|
LIB << primitives
|
data/lib/gogyou.rb
CHANGED
|
@@ -163,6 +163,12 @@
|
|
|
163
163
|
module Gogyou
|
|
164
164
|
Gogyou = self
|
|
165
165
|
|
|
166
|
+
class PointerError < ::RuntimeError
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
class NullPointerError < PointerError
|
|
170
|
+
end
|
|
171
|
+
|
|
166
172
|
require_relative "gogyou/version"
|
|
167
173
|
require_relative "gogyou/typespec"
|
|
168
174
|
require_relative "gogyou/extensions"
|
|
@@ -424,6 +430,8 @@ module Gogyou
|
|
|
424
430
|
# typedef type, aliasname -> self
|
|
425
431
|
# typedef type, aliasname, *elements -> self
|
|
426
432
|
#
|
|
433
|
+
# ***limitation***: not usable the pointer.
|
|
434
|
+
#
|
|
427
435
|
# [type]
|
|
428
436
|
# This parameter can given a symbol or an object.
|
|
429
437
|
#
|
data/lib/gogyou/accessor.rb
CHANGED
|
@@ -177,6 +177,12 @@ module Gogyou
|
|
|
177
177
|
subarray
|
|
178
178
|
end
|
|
179
179
|
|
|
180
|
+
def self.define_subpointer(typeobj, constant = false)
|
|
181
|
+
newtype = Accessor::Pointer.define(typeobj)
|
|
182
|
+
Accessor.const_set("AnonymousPointer_%08X" % newtype.__id__, newtype)
|
|
183
|
+
newtype
|
|
184
|
+
end
|
|
185
|
+
|
|
180
186
|
def self.define_accessors(accessorclass, model)
|
|
181
187
|
accessorclass.class_eval do
|
|
182
188
|
namecheck = {}
|
|
@@ -252,6 +258,114 @@ module Gogyou
|
|
|
252
258
|
self::EXTENSIBLE
|
|
253
259
|
end
|
|
254
260
|
|
|
261
|
+
class Pointer < Accessor
|
|
262
|
+
BYTESIZE = Primitives::SIZE_T.bytesize
|
|
263
|
+
BYTEALIGN = Primitives::SIZE_T.bytealign
|
|
264
|
+
EXTENSIBLE = false
|
|
265
|
+
|
|
266
|
+
def self.aref(buf, off)
|
|
267
|
+
new(buf, off)
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def self.aset(buf, off, val)
|
|
271
|
+
if val.kind_of?(Fixnum)
|
|
272
|
+
buf.store_sizet(off, val)
|
|
273
|
+
else
|
|
274
|
+
raise PointerError, "wrong address (#{val.class} for Fixnum)"
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
buf
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
def self.define(type)
|
|
281
|
+
require_relative "fiddle" # for Fiddle::Pointer and extend
|
|
282
|
+
|
|
283
|
+
Class.new(Pointer) do |t|
|
|
284
|
+
define_singleton_method(:aset, ->(buf, off, val) {
|
|
285
|
+
if val.kind_of?(self)
|
|
286
|
+
addr = val.buffer.load_sizet(val.offset)
|
|
287
|
+
buf.store_sizet(off, addr)
|
|
288
|
+
else
|
|
289
|
+
super
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
buf
|
|
293
|
+
})
|
|
294
|
+
|
|
295
|
+
define_method(:pointer_address, -> {
|
|
296
|
+
@buffer__GOGYOU__.load_sizet(@offset__GOGYOU__)
|
|
297
|
+
})
|
|
298
|
+
|
|
299
|
+
define_method(:[], ->(*args) {
|
|
300
|
+
case args.size
|
|
301
|
+
when 0
|
|
302
|
+
elem = 0
|
|
303
|
+
when 1
|
|
304
|
+
elem = args[0].to_i
|
|
305
|
+
else
|
|
306
|
+
raise ArgumentError, "wrong argument size (#{args.size} for 0 .. 1)"
|
|
307
|
+
end
|
|
308
|
+
addr = @buffer__GOGYOU__.load_sizet(@offset__GOGYOU__)
|
|
309
|
+
if addr == 0
|
|
310
|
+
raise NullPointerError, "nullpo - #<%s:0x%08X>" % [self.class, __id__ << 1]
|
|
311
|
+
end
|
|
312
|
+
buf = ::Fiddle::Pointer.new(addr + elem * type.bytesize, type.bytesize)
|
|
313
|
+
type.aref(buf, 0)
|
|
314
|
+
})
|
|
315
|
+
|
|
316
|
+
define_method(:[]=, ->(*args) {
|
|
317
|
+
case args.size
|
|
318
|
+
when 1
|
|
319
|
+
elem = 0
|
|
320
|
+
v = args[0]
|
|
321
|
+
when 2
|
|
322
|
+
elem = args[0].to_i
|
|
323
|
+
v = args[1]
|
|
324
|
+
else
|
|
325
|
+
raise ArgumentError, "wrong argument size (#{args.size} for 1 .. 2)"
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
addr = @buffer__GOGYOU__.load_sizet(@offset__GOGYOU__)
|
|
329
|
+
if addr == 0
|
|
330
|
+
raise NullPointerError, "nullpo - #<%s:0x%08X>" % [self.class, __id__ << 1]
|
|
331
|
+
end
|
|
332
|
+
buf = ::Fiddle::Pointer.new(addr + elem * type.bytesize, type.bytesize)
|
|
333
|
+
type.aset(buf, 0, v)
|
|
334
|
+
v
|
|
335
|
+
})
|
|
336
|
+
|
|
337
|
+
define_method(:+, ->(elem) {
|
|
338
|
+
addr = @buffer__GOGYOU__.load_sizet(@offset__GOGYOU__)
|
|
339
|
+
buf = String.alloc(Primitives::SIZE_T.bytesize)
|
|
340
|
+
buf.store_sizet(0, addr + elem * type.bytesize)
|
|
341
|
+
self.class.new(buf, 0)
|
|
342
|
+
})
|
|
343
|
+
|
|
344
|
+
typename = String(type.respond_to?(:name) ? type.name : type) rescue String(type)
|
|
345
|
+
define_method(:inspect, -> {
|
|
346
|
+
addr = @buffer__GOGYOU__.load_sizet(@offset__GOGYOU__)
|
|
347
|
+
"#<*%s:0x%08X>" % [typename, addr]
|
|
348
|
+
})
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
#
|
|
353
|
+
# call-seq:
|
|
354
|
+
# self + elem_num -> new pointer object
|
|
355
|
+
#
|
|
356
|
+
def +(elem_num)
|
|
357
|
+
raise NotImplementedError, "this method is shall be defined in sub-class"
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
def -(off)
|
|
361
|
+
send(:+, -off.to_i)
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
def pretty_print(q)
|
|
365
|
+
q.text inspect
|
|
366
|
+
end
|
|
367
|
+
end
|
|
368
|
+
|
|
255
369
|
class BasicStruct < Accessor
|
|
256
370
|
end
|
|
257
371
|
|
data/lib/gogyou/model.rb
CHANGED
|
@@ -360,8 +360,16 @@ module Gogyou
|
|
|
360
360
|
raise ArgumentError, "nothing argument" if args.empty?
|
|
361
361
|
name = nil
|
|
362
362
|
vector = nil
|
|
363
|
-
|
|
363
|
+
args.each do |arg|
|
|
364
364
|
case arg
|
|
365
|
+
when ::Array # pointer field
|
|
366
|
+
yield(name, vector) if name
|
|
367
|
+
name = nil
|
|
368
|
+
vector = nil
|
|
369
|
+
parse!(arg) do |name1, elements|
|
|
370
|
+
raise ArgumentError, "wrong pointer definision" if name
|
|
371
|
+
name = Model::Pointer.create(name1, elements)
|
|
372
|
+
end
|
|
365
373
|
when Symbol, String
|
|
366
374
|
yield(name, vector) if name
|
|
367
375
|
raise ArgumentError, "informal field name (#{arg.to_s})" unless arg =~ FIELDNAME_PATTERN
|
|
@@ -369,16 +377,11 @@ module Gogyou
|
|
|
369
377
|
vector = nil
|
|
370
378
|
when Integer
|
|
371
379
|
raise ArgumentError, "first argument is field name only (#{arg})" unless name
|
|
372
|
-
raise ArgumentError, "
|
|
380
|
+
raise ArgumentError, "can't internal extensible in multi-dimentional array" if vector && vector[-1] < 1
|
|
381
|
+
v = arg.to_i
|
|
382
|
+
raise ArgumentError, "given negative number (#{arg})" unless v >= 0
|
|
373
383
|
vector ||= []
|
|
374
|
-
vector <<
|
|
375
|
-
if vector[-1] == 0
|
|
376
|
-
yield(name, vector)
|
|
377
|
-
unless args.empty?
|
|
378
|
-
raise ArgumentError, "given fields after extensible vector"
|
|
379
|
-
end
|
|
380
|
-
return nil
|
|
381
|
-
end
|
|
384
|
+
vector << v
|
|
382
385
|
else
|
|
383
386
|
raise ArgumentError, "given any object (#{arg.inspect})"
|
|
384
387
|
end
|
|
@@ -399,24 +402,31 @@ module Gogyou
|
|
|
399
402
|
end
|
|
400
403
|
|
|
401
404
|
def addfield!(typeobj, packexp, args)
|
|
402
|
-
#
|
|
403
|
-
# check extensible field >>> creator.fields[-1].vector[-1]
|
|
404
|
-
if (x = fields[-1]) && (x = x.vector) && x[-1] == 0
|
|
405
|
-
raise ArgumentError, "not given fields after extensible vector"
|
|
406
|
-
end
|
|
407
|
-
|
|
408
|
-
typesize = typeobj.bytesize
|
|
409
|
-
typealign = [typeobj.bytealign, 1 << packexp].min
|
|
405
|
+
typesize = typealign = nil # 自己参照構造体を実現するために必要な時に取得する
|
|
410
406
|
|
|
411
407
|
tmpfields = []
|
|
412
408
|
|
|
413
409
|
parse!(args) do |name, vect|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
410
|
+
if name.kind_of?(Model::Pointer::Creator)
|
|
411
|
+
(name, ptrtype) = name.create(typeobj)
|
|
412
|
+
self.offset = offset.align_ceil(Primitives::SIZE_T.bytealign) unless kind_of?(Model::Union::Creator)
|
|
413
|
+
fields << f = Field[offset, name, vect, ptrtype, 0 | packexp]
|
|
414
|
+
tmpfields << f
|
|
415
|
+
unless kind_of?(Model::Union::Creator)
|
|
416
|
+
elements = vect ? vect.inject(1, &:*) : 1
|
|
417
|
+
self.offset += Primitives::SIZE_T.bytesize * elements
|
|
418
|
+
end
|
|
419
|
+
else
|
|
420
|
+
typesize ||= typeobj.bytesize
|
|
421
|
+
typealign ||= [typeobj.bytealign, 1 << packexp].min
|
|
422
|
+
|
|
423
|
+
self.offset = offset.align_ceil(typealign) unless kind_of?(Model::Union::Creator)
|
|
424
|
+
fields << f = Field[offset, name, vect, typeobj, 0 | packexp]
|
|
425
|
+
tmpfields << f
|
|
426
|
+
unless kind_of?(Model::Union::Creator)
|
|
427
|
+
elements = vect ? vect.inject(1, &:*) : 1
|
|
428
|
+
self.offset += typesize * elements
|
|
429
|
+
end
|
|
420
430
|
end
|
|
421
431
|
end
|
|
422
432
|
|
|
@@ -471,6 +481,27 @@ module Gogyou
|
|
|
471
481
|
end
|
|
472
482
|
end
|
|
473
483
|
|
|
484
|
+
class Pointer < Model
|
|
485
|
+
class Creator < ::Struct.new(:token, :elements)
|
|
486
|
+
def create(typeobj)
|
|
487
|
+
name = token
|
|
488
|
+
if name.kind_of?(Creator)
|
|
489
|
+
# multiple pointer
|
|
490
|
+
(name, typeobj) = name.create(typeobj)
|
|
491
|
+
end
|
|
492
|
+
if elements && !elements.empty?
|
|
493
|
+
typeobj = Accessor.define_subarray(Model::Field[0, nil, elements, typeobj, 0])
|
|
494
|
+
end
|
|
495
|
+
model = Accessor.define_subpointer(typeobj)
|
|
496
|
+
[name, model]
|
|
497
|
+
end
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
def self.create(token, elements)
|
|
501
|
+
Creator.new(token, elements)
|
|
502
|
+
end
|
|
503
|
+
end
|
|
504
|
+
|
|
474
505
|
class Struct < Model
|
|
475
506
|
class Creator < Model::BasicCreator
|
|
476
507
|
def bytealign(bytesize)
|
data/lib/gogyou/version.rb
CHANGED
data/pointer.ja.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
|
|
2
|
+
# About pointer (ポインタについて) (***EXPERIMENTAL FEATURE***)
|
|
3
|
+
|
|
4
|
+
非常に限定的ながらポインタを扱うことが出来るようになりました (0.2.5 にて追加)。
|
|
5
|
+
|
|
6
|
+
構造体を作成する時に、ポインタとしたい要素を配列としてくくることで定義できます。
|
|
7
|
+
|
|
8
|
+
C と ruby を並べて記述しています (左側が ruby、右側が C):
|
|
9
|
+
|
|
10
|
+
``` ruby:ruby
|
|
11
|
+
int [:a] # => int *a
|
|
12
|
+
|
|
13
|
+
int [[[[:a]]]] # => int ****a
|
|
14
|
+
|
|
15
|
+
int [:a, 4] # => (NOW) int (*a)[4]
|
|
16
|
+
# (FEATURE) int *a[4] : "a" is a 4 elements pointer of int
|
|
17
|
+
|
|
18
|
+
int [:a], 4 # => (NOW) int *a[4]
|
|
19
|
+
# (FEATURE) int (*a)[4] : "a" is a pointer of 4 elements int
|
|
20
|
+
|
|
21
|
+
int [:a, 4], 8 # => (NOW) int (*a[8])[4]
|
|
22
|
+
# (FEATURE) int (*a[4])[8] : "a" is a 4 elements pointer of 8 elements int
|
|
23
|
+
|
|
24
|
+
const int [:a] # => (NOW) int *const a
|
|
25
|
+
# (FEATURE) const int *a : "a" is a pointer of constant int
|
|
26
|
+
|
|
27
|
+
int [const(:a)] # => (NOW) NOT WORK
|
|
28
|
+
# (FEATURE) int *const a : "a" is a constant pointer of int
|
|
29
|
+
|
|
30
|
+
a[] # => *a , a[0]
|
|
31
|
+
a[1] # => a[1]
|
|
32
|
+
a[][1] # => (*a)[1] , a[0][1]
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
実際に利用した例 (***ruby の規律から逸脱しているため、実用しないで下さい***):
|
|
36
|
+
|
|
37
|
+
``` ruby:ruby
|
|
38
|
+
X = Gogyou.struct {
|
|
39
|
+
int [:a]
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
frozen_str = "abcdefghijklmn"
|
|
43
|
+
x = X.new([frozen_str].pack("p"))
|
|
44
|
+
frozen_str.freeze
|
|
45
|
+
|
|
46
|
+
x.a[] = 0x44434241 # *x.a = 0x44434241
|
|
47
|
+
p frozen_str # => "ABCDefghijklmn"
|
|
48
|
+
# ^^^^
|
|
49
|
+
|
|
50
|
+
x.a[2] ^= 0x20202020 # same as C code
|
|
51
|
+
p frozen_str # => "ABCDefghIJKLmn"
|
|
52
|
+
# ^^^^
|
|
53
|
+
|
|
54
|
+
x.a += 1 # address + sizeof(int[1])
|
|
55
|
+
x.a[] = 0x24232221 # *x.a = 0x24232221
|
|
56
|
+
p frozen_str # => "ABCD!\"\#$IJKLmn"
|
|
57
|
+
# ^^^^^^
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
実験的な機能のため、以下の制限(出来無いこと)があります:
|
|
61
|
+
|
|
62
|
+
* const 修飾子が機能しない (又は挙動がおかしい)
|
|
63
|
+
* typedef 出来ない
|
|
64
|
+
* ポインタと配列の定義を混ぜると挙動がおかしい
|
|
65
|
+
* そもそも C に見えない!
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
## 自己参照構造体、相互参照構造体について
|
|
69
|
+
|
|
70
|
+
ポインタによる自己参照構造体、相互参照構造体を定義する場合、Gogyou::Struct クラスを継承したクラスを定義することで可能です。
|
|
71
|
+
|
|
72
|
+
``` C:C
|
|
73
|
+
struct TypeA;
|
|
74
|
+
|
|
75
|
+
struct TypeB
|
|
76
|
+
{
|
|
77
|
+
struct TypeA *a;
|
|
78
|
+
struct TypeB *b;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
struct TypeA
|
|
82
|
+
{
|
|
83
|
+
struct TypeB *b;
|
|
84
|
+
};
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
``` ruby:ruby
|
|
88
|
+
class TypeA < Gogyou::Struct
|
|
89
|
+
# class definition only!
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
class TypeB < Gogyou::Struct
|
|
93
|
+
struct {
|
|
94
|
+
struct TypeA, [:a]
|
|
95
|
+
struct TypeB, [:b]
|
|
96
|
+
}
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
class TypeA
|
|
100
|
+
struct {
|
|
101
|
+
struct TypeB, [:b]
|
|
102
|
+
}
|
|
103
|
+
end
|
|
104
|
+
```
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: gogyou
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- dearblue
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-10-
|
|
11
|
+
date: 2015-10-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rspec
|
|
@@ -43,11 +43,15 @@ description: |
|
|
|
43
43
|
|
|
44
44
|
The C-liked struct, union and multidimensional array definition are posible in ruby syntax.
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
Available features:
|
|
47
|
+
|
|
48
|
+
(1) nested struct and union with anonymous field
|
|
49
|
+
(2) multidimensional array
|
|
50
|
+
(3) field of variable array
|
|
51
|
+
(4) const field
|
|
52
|
+
(5) packed field
|
|
53
|
+
(6) user definition types
|
|
54
|
+
(7) (EXPERIMENTAL AND LIMITATION FEATURE) pointer
|
|
51
55
|
email: dearblue@users.osdn.me
|
|
52
56
|
executables: []
|
|
53
57
|
extensions: []
|
|
@@ -65,6 +69,7 @@ extra_rdoc_files:
|
|
|
65
69
|
- lib/gogyou/primitives.rb
|
|
66
70
|
- lib/gogyou/typespec.rb
|
|
67
71
|
- lib/gogyou/version.rb
|
|
72
|
+
- pointer.ja.md
|
|
68
73
|
files:
|
|
69
74
|
- HISTORY.ja.md
|
|
70
75
|
- LICENSE
|
|
@@ -82,6 +87,7 @@ files:
|
|
|
82
87
|
- lib/gogyou/typespec.rb
|
|
83
88
|
- lib/gogyou/version.rb
|
|
84
89
|
- mkprims.rb
|
|
90
|
+
- pointer.ja.md
|
|
85
91
|
- spec/gogyou_spec.rb
|
|
86
92
|
- test/test_loadstore.rb
|
|
87
93
|
- test/test_packbin.rb
|