rbind 0.0.32 → 0.0.35

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '09c41b56b4789ecc979d67b35ba15190c619000ed14273c3c3f2470e9fbe6a19'
4
- data.tar.gz: 9346a8964a020a5f518c2a7df144c973d03bae03055d83aad537a67a3dcae250
3
+ metadata.gz: '0892dada4084e4b38bcb49d3dca8106a038e5a2c82a4a87d420532327ac942e7'
4
+ data.tar.gz: 482377fb03e5b125550de5596365a01be1762e5bcc5596dec3b37dec5f27a0aa
5
5
  SHA512:
6
- metadata.gz: 772d21a2abaa065e5a7ce4c0ba6751d11393144f34820b203bf16a682c42d199db3e478ab9df2dc60306c2b174af681ad5f5949e479c83a54dfb941830c254b9
7
- data.tar.gz: f29591791fbf86c4cbd0bb609de4b9b2bd52c1cd4c9e4f2c337ed1072c9eea932ad08bd8e16bdbf08fe50adb8d32fb5a09cb1f5e6d0f8f3bbbfc3d32eaa06624
6
+ metadata.gz: 19adf245b190083bac225917b50ac8169deef19137364196a3623f7e3d547fb5a9c773ff59193589a204ff2666184c1805e4d359abd76a05aa504bf0165667a7
7
+ data.tar.gz: a0e111070064d5a1baca4bfb7799dc98dd6ed034d3a207a04e5005db254beb7016f50038b3dae51748fe9834fcb1edbb2344969a8a88242502fbd951c684dabf
@@ -208,5 +208,27 @@ module Rbind
208
208
  @specialize_ruby.call
209
209
  end
210
210
  end
211
+
212
+ # overwrite c
213
+ # depends on type
214
+ # at the moment only operations can be overwritten
215
+ def overwrite_c(&block)
216
+ if block
217
+ @overwrite_c = block
218
+ elsif @overwrite_c
219
+ @overwrite_c.call
220
+ end
221
+ end
222
+
223
+ # overwrite ruby
224
+ # depends on type
225
+ # at the moment only rbind_from_native can be overwritten
226
+ def overwrite_ruby(&block)
227
+ if block
228
+ @overwrite_ruby = block
229
+ elsif @overwrite_ruby
230
+ @overwrite_ruby.call
231
+ end
232
+ end
211
233
  end
212
234
  end
@@ -108,8 +108,8 @@ module Rbind
108
108
  o == other_op
109
109
  end
110
110
  next false if !op
111
- next true if o.base_class == self
112
- next true if o.base_class == other_op.base_class
111
+ next true if op.base_class == self
112
+ next true if op.base_class == other_op.base_class
113
113
 
114
114
  # ambiguous name look up due to multi
115
115
  # inheritance
@@ -133,7 +133,7 @@ module Rbind
133
133
  def parse_class(line_number,string)
134
134
  lines = string.split("\n")
135
135
  a = lines.shift.rstrip
136
- unless a =~ /class ([<>a-zA-Z\.\d_:]*) ?:?([<>a-zA-Z\.\:, \d_]*)(.*)/
136
+ unless a =~ /class ([,<>a-zA-Z\.\d_:]*) ?:?([<>a-zA-Z\.\:, \d_]*)(.*)/
137
137
  raise "cannot parse class #{a}"
138
138
  end
139
139
  name = $1
@@ -367,7 +367,8 @@ module Rbind
367
367
  @extern_package_name = extern_package_name
368
368
 
369
369
  a = split(string)
370
- #remove number at the end of the file
370
+ #remove namespances and number at the end of the file
371
+ a.pop if (a.last =~/namespaces:/) == 0
371
372
  a.pop if a.last.to_i != 0
372
373
 
373
374
  line_number = 1
@@ -192,6 +192,8 @@ module Rbind
192
192
  end
193
193
 
194
194
  def wrap_call
195
+ str = overwrite_c()
196
+ return str if str
195
197
  paras = parameters.map do |arg|
196
198
  "#{"*" if (!arg.type.ptr? && !arg.type.basic_type?)}#{arg.name}#{"_" if !arg.type.basic_type?}"
197
199
  end.join(", ")
@@ -657,6 +657,13 @@ module Rbind
657
657
  GeneratorRuby.normalize_method_name(@root.cdelete_method)
658
658
  end
659
659
 
660
+ def rbind_from_native
661
+ overwrite = @root.overwrite_ruby
662
+ return overwrite if overwrite
663
+ "#{name}.new(ptr)"
664
+ end
665
+
666
+
660
667
  def add_specializing(root = @root)
661
668
  str = root.specialize_ruby.to_s
662
669
  root.each_type(false) do |t|
@@ -5,10 +5,13 @@
5
5
  {
6
6
  <%= wrap_parameters %><%= wrap_call %>
7
7
  }
8
- catch(std::exception &error){strncpy(&last_error_message[0],error.what(),255);}
9
- catch(...){strncpy(&last_error_message[0],"Unknown Exception",255);}
8
+ catch(std::exception &error){strncpy(&last_error_message[0],error.what(),254);}
9
+ catch(...){strncpy(&last_error_message[0],"Unknown Exception",254);}
10
10
  <%- if !return_type || return_type.ptr? || !return_type.basic_type? -%>
11
11
  return NULL;
12
+ <%- elsif return_type.ref? -%>
13
+ static <%= return_type.cname %> invalid;
14
+ return invalid;
12
15
  <%- elsif return_type.name != "void" -%>
13
16
  return (<%= return_type.cname %>) <%= return_type.invalid_value %>;
14
17
  <%- end -%>
@@ -8,7 +8,7 @@ void <%= cdelete_method %>(<%= cname %> *ptr)
8
8
  delete fromC(ptr);
9
9
  ptr->obj_ptr = NULL;
10
10
  }
11
- catch(std::exception &error){strncpy(&last_error_message[0],error.what(),255);}
12
- catch(...){strncpy(&last_error_message[0],"Unknown Exception",255);}
11
+ catch(std::exception &error){strncpy(&last_error_message[0],error.what(),254);}
12
+ catch(...){strncpy(&last_error_message[0],"Unknown Exception",254);}
13
13
  delete ptr;
14
14
  }
@@ -55,7 +55,7 @@ class <%= name %>
55
55
 
56
56
  # @private
57
57
  def self.rbind_from_native(ptr,context)
58
- <%= name %>.new(ptr)
58
+ <%= rbind_from_native %>
59
59
  end
60
60
 
61
61
  # @private
@@ -52,13 +52,13 @@ class CppHeaderParser(object):
52
52
  def get_macro_arg(self, arg_str, npos):
53
53
  npos2 = npos3 = arg_str.find("(", npos)
54
54
  if npos2 < 0:
55
- print("Error: no arguments for the macro at %d" % (self.lineno,))
55
+ print("Error: no arguments for the macro at %s:%d" % (self.hname, self.lineno))
56
56
  sys.exit(-1)
57
57
  balance = 1
58
58
  while 1:
59
59
  t, npos3 = self.find_next_token(arg_str, ['(', ')'], npos3+1)
60
60
  if npos3 < 0:
61
- print("Error: no matching ')' in the macro call at %d" % (self.lineno,))
61
+ print("Error: no matching ')' in the macro call at %s:%d" % (self.hname, self.lineno))
62
62
  sys.exit(-1)
63
63
  if t == '(':
64
64
  balance += 1
@@ -110,6 +110,11 @@ class CppHeaderParser(object):
110
110
  if npos >= 0:
111
111
  modlist.append("/C")
112
112
 
113
+ npos = arg_str.find("&&")
114
+ if npos >= 0:
115
+ arg_str = arg_str.replace("&&", '')
116
+ modlist.append("/RRef")
117
+
113
118
  npos = arg_str.find("&")
114
119
  if npos >= 0:
115
120
  modlist.append("/Ref")
@@ -160,7 +165,7 @@ class CppHeaderParser(object):
160
165
  angle_stack.append(0)
161
166
  elif w == "," or w == '>':
162
167
  if not angle_stack:
163
- print("Error at %d: argument contains ',' or '>' not within template arguments" % (self.lineno,))
168
+ print("Error at %s:%d: argument contains ',' or '>' not within template arguments" % (self.hname, self.lineno))
164
169
  sys.exit(-1)
165
170
  if w == ",":
166
171
  arg_type += "_and_"
@@ -190,7 +195,7 @@ class CppHeaderParser(object):
190
195
  p1 = arg_name.find("[")
191
196
  p2 = arg_name.find("]",p1+1)
192
197
  if p2 < 0:
193
- print("Error at %d: no closing ]" % (self.lineno,))
198
+ print("Error at %s:%d: no closing ]" % (self.hname, self.lineno))
194
199
  sys.exit(-1)
195
200
  counter_str = arg_name[p1+1:p2].strip()
196
201
  if counter_str == "":
@@ -254,6 +259,8 @@ class CppHeaderParser(object):
254
259
  l = l.replace("CV_EXPORTS_W_SIMPLE", "")
255
260
  modlist.append("/Simple")
256
261
  npos = l.find("CV_EXPORTS_AS")
262
+ if npos < 0:
263
+ npos = l.find('CV_WRAP_AS')
257
264
  if npos >= 0:
258
265
  macro_arg, npos3 = self.get_macro_arg(l, npos)
259
266
  modlist.append("=" + macro_arg)
@@ -429,10 +436,18 @@ class CppHeaderParser(object):
429
436
  # filter off some common prefixes, which are meaningless for Python wrappers.
430
437
  # note that we do not strip "static" prefix, which does matter;
431
438
  # it means class methods, not instance methods
432
- decl_str = self.batch_replace(decl_str, [("static inline", ""), ("inline", ""),\
433
- ("CV_EXPORTS_W", ""), ("CV_EXPORTS", ""), ("CV_CDECL", ""), ("CV_WRAP ", " "), ("CV_INLINE", ""),
434
- ("CV_DEPRECATED", ""), ("CV_DEPRECATED_EXTERNAL", "")]).strip()
435
-
439
+ decl_str = self.batch_replace(decl_str, [("static inline", ""),
440
+ ("inline", ""),
441
+ ("explicit ", ""),
442
+ ("CV_EXPORTS_W", ""),
443
+ ("CV_EXPORTS", ""),
444
+ ("CV_CDECL", ""),
445
+ ("CV_WRAP ", " "),
446
+ ("CV_INLINE", ""),
447
+ ("CV_DEPRECATED", ""),
448
+ ("CV_DEPRECATED_EXTERNAL", ""),
449
+ ("CV_NODISCARD_STD", ""),
450
+ ("CV_NODISCARD", "")]).strip()
436
451
 
437
452
  if decl_str.strip().startswith('virtual'):
438
453
  virtual_method = True
@@ -570,8 +585,8 @@ class CppHeaderParser(object):
570
585
  arg_type, arg_name, modlist, argno = self.parse_arg(a, argno)
571
586
  if self.wrap_mode:
572
587
  # TODO: Vectors should contain UMat, but this is not very easy to support and not very needed
573
- vector_mat = "vector_{}".format("Mat")
574
- vector_mat_template = "vector<{}>".format("Mat")
588
+ vector_mat = "vector_{}".format(mat)
589
+ vector_mat_template = "vector<{}>".format(mat)
575
590
 
576
591
  if arg_type == "InputArray":
577
592
  arg_type = mat
@@ -656,6 +671,10 @@ class CppHeaderParser(object):
656
671
  stack_top = self.block_stack[-1]
657
672
  context = stack_top[self.BLOCK_TYPE]
658
673
 
674
+ if stmt.startswith('inline namespace'):
675
+ # emulate anonymous namespace
676
+ return "namespace", "", True, None
677
+
659
678
  stmt_type = ""
660
679
  if end_token == "{":
661
680
  stmt_type = "block"
@@ -713,6 +732,8 @@ class CppHeaderParser(object):
713
732
  return stmt_type, classname, True, decl
714
733
 
715
734
  if stmt.startswith("enum") or stmt.startswith("namespace"):
735
+ # NB: Drop inheritance syntax for enum
736
+ stmt = stmt.split(':')[0]
716
737
  stmt_list = stmt.rsplit(" ", 1)
717
738
  if len(stmt_list) < 2:
718
739
  stmt_list.append("<unnamed>")
@@ -792,6 +813,7 @@ class CppHeaderParser(object):
792
813
  COMMENT = 1 # inside a multi-line comment
793
814
  DIRECTIVE = 2 # inside a multi-line preprocessor directive
794
815
  DOCSTRING = 3 # inside a multi-line docstring
816
+ DIRECTIVE_IF_0 = 4 # inside a '#if 0' directive
795
817
 
796
818
  state = SCAN
797
819
 
@@ -801,19 +823,56 @@ class CppHeaderParser(object):
801
823
  self.lineno = 0
802
824
  self.wrap_mode = wmode
803
825
 
826
+ depth_if_0 = 0
827
+
804
828
  for l0 in linelist:
805
829
  self.lineno += 1
806
830
  #print(state, self.lineno, l0)
807
831
 
808
832
  l = l0.strip()
809
833
 
834
+ # G-API specific aliases
835
+ l = self.batch_replace(l, [
836
+ ("GAPI_EXPORTS", "CV_EXPORTS"),
837
+ ("GAPI_EXPORTS_W", "CV_EXPORTS_W"),
838
+ ("GAPI_EXPORTS_W_SIMPLE","CV_EXPORTS_W_SIMPLE"),
839
+ ("GAPI_WRAP", "CV_WRAP"),
840
+ ("GAPI_PROP", "CV_PROP"),
841
+ ("GAPI_PROP_RW", "CV_PROP_RW"),
842
+ ('defined(GAPI_STANDALONE)', '0'),
843
+ ])
844
+
810
845
  if state == SCAN and l.startswith("#"):
811
846
  state = DIRECTIVE
812
847
  # fall through to the if state == DIRECTIVE check
813
848
 
814
849
  if state == DIRECTIVE:
815
- if not l.endswith("\\"):
816
- state = SCAN
850
+ if l.endswith("\\"):
851
+ continue
852
+ state = SCAN
853
+ l = re.sub(r'//(.+)?', '', l).strip() # drop // comment
854
+ if l in [
855
+ '#if 0',
856
+ '#if defined(__OPENCV_BUILD)', '#ifdef __OPENCV_BUILD',
857
+ '#if !defined(OPENCV_BINDING_PARSER)', '#ifndef OPENCV_BINDING_PARSER',
858
+ ]:
859
+ state = DIRECTIVE_IF_0
860
+ depth_if_0 = 1
861
+ continue
862
+
863
+ if state == DIRECTIVE_IF_0:
864
+ if l.startswith('#'):
865
+ l = l[1:].strip()
866
+ if l.startswith("if"):
867
+ depth_if_0 += 1
868
+ continue
869
+ if l.startswith("endif"):
870
+ depth_if_0 -= 1
871
+ if depth_if_0 == 0:
872
+ state = SCAN
873
+ else:
874
+ # print('---- {:30s}:{:5d}: {}'.format(hname[-30:], self.lineno, l))
875
+ pass
817
876
  continue
818
877
 
819
878
  if state == COMMENT:
@@ -826,7 +885,7 @@ class CppHeaderParser(object):
826
885
  if state == DOCSTRING:
827
886
  pos = l.find("*/")
828
887
  if pos < 0:
829
- docstring += l + "\n"
888
+ docstring += l0
830
889
  continue
831
890
  docstring += l[:pos] + "\n"
832
891
  l = l[pos+2:]
@@ -842,7 +901,12 @@ class CppHeaderParser(object):
842
901
  sys.exit(-1)
843
902
 
844
903
  while 1:
845
- token, pos = self.find_next_token(l, [";", "\"", "{", "}", "//", "/*"])
904
+ # NB: Avoid parsing '{' for case:
905
+ # foo(Obj&& = {});
906
+ if re.search(r'=\s*\{\s*\}', l):
907
+ token, pos = ';', len(l)
908
+ else:
909
+ token, pos = self.find_next_token(l, [";", "\"", "{", "}", "//", "/*"])
846
910
 
847
911
  if not token:
848
912
  block_head += " " + l
@@ -912,14 +976,17 @@ class CppHeaderParser(object):
912
976
  else:
913
977
  decls.append(decl)
914
978
 
915
- if self._generate_gpumat_decls and "cv.cuda." in decl[0]:
979
+ if self._generate_gpumat_decls and ("cv.cuda" in decl[0] or decl[0] in [
980
+ "cv.imshow", # https://github.com/opencv/opencv/issues/18553
981
+ ]):
916
982
  # If function takes as one of arguments Mat or vector<Mat> - we want to create the
917
- # same declaration working with GpuMat (this is important for T-Api access)
983
+ # same declaration working with GpuMat
918
984
  args = decl[3]
919
985
  has_mat = len(list(filter(lambda x: x[0] in {"Mat", "vector_Mat"}, args))) > 0
920
986
  if has_mat:
921
987
  _, _, _, gpumat_decl = self.parse_stmt(stmt, token, mat="cuda::GpuMat", docstring=docstring)
922
- decls.append(gpumat_decl)
988
+ if gpumat_decl != decl:
989
+ decls.append(gpumat_decl)
923
990
 
924
991
  if self._generate_umat_decls:
925
992
  # If function takes as one of arguments Mat or vector<Mat> - we want to create the
@@ -928,12 +995,13 @@ class CppHeaderParser(object):
928
995
  has_mat = len(list(filter(lambda x: x[0] in {"Mat", "vector_Mat"}, args))) > 0
929
996
  if has_mat:
930
997
  _, _, _, umat_decl = self.parse_stmt(stmt, token, mat="UMat", docstring=docstring)
931
- decls.append(umat_decl)
998
+ if umat_decl != decl:
999
+ decls.append(umat_decl)
932
1000
 
933
1001
  docstring = ""
934
1002
  if stmt_type == "namespace":
935
1003
  chunks = [block[1] for block in self.block_stack if block[0] == 'namespace'] + [name]
936
- self.namespaces.add('.'.join(chunks))
1004
+ self.namespaces.add('.'.join(filter(lambda c: len(c)> 0, chunks)))
937
1005
  else:
938
1006
  stmt_type, name, parse_flag = "block", "", False
939
1007
 
@@ -972,13 +1040,12 @@ class CppHeaderParser(object):
972
1040
  print()
973
1041
 
974
1042
  if __name__ == '__main__':
975
- parser = CppHeaderParser(generate_umat_decls=True, generate_gpumat_decls=False)
1043
+ parser = CppHeaderParser(generate_umat_decls=False, generate_gpumat_decls=False)
976
1044
  decls = []
977
- # for hname in opencv_hdr_list:
978
- # decls += parser.parse(hname)
979
- if len(sys.argv) > 2:
980
- for hname in sys.argv[1:]:
981
- decls += parser.parse(hname)
982
- else:
983
- decls += parser.parse(sys.argv[1])
1045
+ # for hname in opencv_hdr_list:
1046
+ # decls += parser.parse(hname)
1047
+ for hname in sys.argv[1:]:
1048
+ decls += parser.parse(hname, wmode=True)
984
1049
  parser.print_decls(decls)
1050
+ print(len(decls))
1051
+ print("namespaces:", " ".join(sorted(parser.namespaces)))
@@ -18,11 +18,42 @@ module Rbind
18
18
  klass.add_operation ROperation.new("size",type("size_t"))
19
19
  klass.add_operation ROperation.new("clear",type("void"))
20
20
  klass.add_operation ROperation.new("empty",type("bool"))
21
- klass.add_operation ROperation.new("operator[]",map_value_type, RParameter.new("key_type", map_key_type))
21
+ klass.add_operation ROperation.new("operator[]",map_value_type.to_ref, RParameter.new("key_type", map_key_type))
22
+ klass.add_operation ROperation.new("add",type("void"), RParameter.new("key", map_key_type),RParameter.new("value", map_value_type.to_ref.to_const))
23
+ klass.operation("add").overwrite_c do
24
+ "(*rbind_obj_)[#{map_key_type.basic_type? ? "key" : "*key_"}] = #{map_value_type.basic_type? ? "value" : "*value_"};"
25
+ end
26
+
22
27
  klass.add_operation ROperation.new("at",map_value_type, RParameter.new("key_type",map_key_type))
23
28
  klass.add_operation ROperation.new("erase",type("void"), RParameter.new("key_type",map_key_type))
29
+ klass.add_operation ROperation.new("getKeys",type("std::vector<#{map_key_type}>"))
30
+ klass.operation("getKeys").overwrite_c do
31
+ str = %{
32
+ auto keys = new std::vector<#{map_key_type}>();
33
+ std::transform(std::begin(*rbind_obj_), std::end(*rbind_obj_), std::back_inserter(*keys),
34
+ [](std::pair<#{map_key_type},#{map_value_type}> const& pair) {
35
+ return pair.first;
36
+ });
37
+ return toC(keys);
38
+ }
39
+ end
40
+ klass
41
+ end
24
42
 
25
- klass
43
+ # called from RTemplate when ruby_specialize is called for the instance
44
+ def specialize_ruby_specialization(klass)
45
+ %Q$
46
+ def to_hash
47
+ hash = Hash.new
48
+ keys = get_keys
49
+ keys.each do |k|
50
+ hash[k] = self[k]
51
+ end
52
+ hash
53
+ end
54
+ def []=(key,val)
55
+ add(key,val)
56
+ end$
26
57
  end
27
58
  end
28
59
  end
@@ -11,7 +11,12 @@ module Rbind
11
11
 
12
12
  para = Array.new
13
13
  para << RParameter.new("size",type("size_t"))
14
- para << RParameter.new("val",vector_type).default_value(vector_type.full_name+"()").to_const
14
+ if vector_type.is_a? REnum
15
+ para << RParameter.new("val",vector_type)
16
+ else
17
+ para << RParameter.new("val",vector_type).default_value(vector_type.full_name+"()").to_const
18
+ end
19
+
15
20
  klass.add_operation ROperation.new("resize",type("void"),para)
16
21
  klass.add_operation ROperation.new("size",type("size_t"))
17
22
  klass.add_operation ROperation.new("clear",type("void"))
data/rbind.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'rbind'
3
- s.version = '0.0.32'
4
- s.date = '2020-02-29'
3
+ s.version = '0.0.35'
4
+ s.date = '2022-06-18'
5
5
  s.platform = Gem::Platform::RUBY
6
6
  s.authors = ['Alexander Duda']
7
7
  s.email = ['Alexander.Duda@me.com']
metadata CHANGED
@@ -1,35 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbind
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.32
4
+ version: 0.0.35
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Duda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-29 00:00:00.000000000 Z
11
+ date: 2022-06-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: 1.9.0
20
17
  - - "~>"
21
18
  - !ruby/object:Gem::Version
22
19
  version: '1.9'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.9.0
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: 1.9.0
30
27
  - - "~>"
31
28
  - !ruby/object:Gem::Version
32
29
  version: '1.9'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.9.0
33
33
  description: Rbind is developed to automatically generate ruby bindings for OpenCV
34
34
  but is not tight to this library.This gem is still under heavy development and the
35
35
  API might change in the future.
@@ -128,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
128
  - !ruby/object:Gem::Version
129
129
  version: 1.3.6
130
130
  requirements: []
131
- rubygems_version: 3.0.3
131
+ rubygems_version: 3.3.5
132
132
  signing_key:
133
133
  specification_version: 4
134
134
  summary: Library for genereating automated ffi-bindings for c/c++ libraries