From ad5fb58e07572b4dca7cfbc8c441297e807b9aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 11 Aug 2016 21:57:22 -0700 Subject: [PATCH 1/5] stylo: Regenerate bindings to take into account the nsStyleContent cleanup. --- ports/geckolib/gecko_bindings/bindings.rs | 5 ++++- ports/geckolib/gecko_bindings/structs_debug.rs | 11 ++++------- ports/geckolib/gecko_bindings/structs_release.rs | 11 ++++------- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/ports/geckolib/gecko_bindings/bindings.rs b/ports/geckolib/gecko_bindings/bindings.rs index 2a330fb21b6..99baada7fe9 100644 --- a/ports/geckolib/gecko_bindings/bindings.rs +++ b/ports/geckolib/gecko_bindings/bindings.rs @@ -302,7 +302,8 @@ extern "C" { pub fn Gecko_GetNodeFlags(node: *mut RawGeckoNode) -> u32; pub fn Gecko_SetNodeFlags(node: *mut RawGeckoNode, flags: u32); pub fn Gecko_UnsetNodeFlags(node: *mut RawGeckoNode, flags: u32); - pub fn Gecko_GetStyleContext(node: *mut RawGeckoNode) + pub fn Gecko_GetStyleContext(node: *mut RawGeckoNode, + aPseudoTagOrNull: *mut nsIAtom) -> *mut nsStyleContext; pub fn Gecko_CalcStyleDifference(oldstyle: *mut nsStyleContext, newstyle: ServoComputedValuesBorrowed) @@ -311,6 +312,8 @@ extern "C" { change: nsChangeHint); pub fn Gecko_EnsureTArrayCapacity(array: *mut ::std::os::raw::c_void, capacity: usize, elem_size: usize); + pub fn Gecko_ClearPODTArray(array: *mut ::std::os::raw::c_void, + elem_size: usize, elem_align: usize); pub fn Gecko_EnsureImageLayersLength(layers: *mut nsStyleImageLayers, len: usize); pub fn Gecko_InitializeImageLayer(layer: *mut Layer, diff --git a/ports/geckolib/gecko_bindings/structs_debug.rs b/ports/geckolib/gecko_bindings/structs_debug.rs index aba838068c0..f726e9ee3ff 100644 --- a/ports/geckolib/gecko_bindings/structs_debug.rs +++ b/ports/geckolib/gecko_bindings/structs_debug.rs @@ -6567,16 +6567,13 @@ fn bindgen_test_layout_nsStyleCounterData() { #[derive(Debug)] pub struct nsStyleContent { pub mMarkerOffset: nsStyleCoord, - pub mContents: *mut nsStyleContentData, - pub mIncrements: *mut nsStyleCounterData, - pub mResets: *mut nsStyleCounterData, - pub mContentCount: u32, - pub mIncrementCount: u32, - pub mResetCount: u32, + pub mContents: nsTArray, + pub mIncrements: nsTArray, + pub mResets: nsTArray, } #[test] fn bindgen_test_layout_nsStyleContent() { - assert_eq!(::std::mem::size_of::() , 56usize); + assert_eq!(::std::mem::size_of::() , 40usize); assert_eq!(::std::mem::align_of::() , 8usize); } #[repr(C)] diff --git a/ports/geckolib/gecko_bindings/structs_release.rs b/ports/geckolib/gecko_bindings/structs_release.rs index 26dc0b01f61..3f4a833acd7 100644 --- a/ports/geckolib/gecko_bindings/structs_release.rs +++ b/ports/geckolib/gecko_bindings/structs_release.rs @@ -6544,16 +6544,13 @@ fn bindgen_test_layout_nsStyleCounterData() { #[derive(Debug)] pub struct nsStyleContent { pub mMarkerOffset: nsStyleCoord, - pub mContents: *mut nsStyleContentData, - pub mIncrements: *mut nsStyleCounterData, - pub mResets: *mut nsStyleCounterData, - pub mContentCount: u32, - pub mIncrementCount: u32, - pub mResetCount: u32, + pub mContents: nsTArray, + pub mIncrements: nsTArray, + pub mResets: nsTArray, } #[test] fn bindgen_test_layout_nsStyleContent() { - assert_eq!(::std::mem::size_of::() , 56usize); + assert_eq!(::std::mem::size_of::() , 40usize); assert_eq!(::std::mem::align_of::() , 8usize); } #[repr(C)] From d85a60e36626fe5e68bc193f90c29cabefc5385f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 11 Aug 2016 22:00:22 -0700 Subject: [PATCH 2/5] stylo: Use the improved version of Gecko_GetStyleContext() --- components/style/gecko_selector_impl.rs | 2 +- components/style/properties/gecko.mako.rs | 2 +- ports/geckolib/wrapper.rs | 11 +++-------- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/components/style/gecko_selector_impl.rs b/components/style/gecko_selector_impl.rs index 7002483e95b..d78349af2aa 100644 --- a/components/style/gecko_selector_impl.rs +++ b/components/style/gecko_selector_impl.rs @@ -34,7 +34,7 @@ pub struct PseudoElement(Atom, bool); impl PseudoElement { #[inline] - fn as_atom(&self) -> &Atom { + pub fn as_atom(&self) -> &Atom { &self.0 } diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 95cc6de7cb3..d8697e7611a 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -455,7 +455,7 @@ impl Clone for ${style_struct.gecko_struct_name} { impl Debug for ${style_struct.gecko_struct_name} { // FIXME(bholley): Generate this. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "GECKO STYLE STRUCT") + write!(f, "Gecko style struct: ${style_struct.gecko_struct_name}") } } %else: diff --git a/ports/geckolib/wrapper.rs b/ports/geckolib/wrapper.rs index 62fc84a36fe..5d35acf6ef7 100644 --- a/ports/geckolib/wrapper.rs +++ b/ports/geckolib/wrapper.rs @@ -319,15 +319,10 @@ impl<'ln> TNode for GeckoNode<'ln> { return None; } - if pseudo.is_some() { - // FIXME(emilio): This makes us reconstruct frame for pseudos every - // restyle, add a FFI call to get the style context associated with - // a PE. - return None; - } - unsafe { - let context_ptr = Gecko_GetStyleContext(self.node); + let atom_ptr = pseudo.map(|p| p.as_atom().as_ptr()) + .unwrap_or(ptr::null_mut()); + let context_ptr = Gecko_GetStyleContext(self.node, atom_ptr); context_ptr.as_ref() } } From 46afc56c41500c2a98e6d5a387479edfb095b5a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 11 Aug 2016 22:01:14 -0700 Subject: [PATCH 3/5] stylo: Implement support for the contents property. --- components/style/properties/gecko.mako.rs | 87 +++++++++++++++++++ ports/geckolib/gecko_bindings/bindings.rs | 3 + .../gecko_bindings/sugar/ns_t_array.rs | 34 +++++++- 3 files changed, 120 insertions(+), 4 deletions(-) diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index d8697e7611a..085c35219c3 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -1355,6 +1355,93 @@ fn static_assert() { ${impl_coord_copy('column_width', 'mColumnWidth')} +<%self:impl_trait style_struct_name="Counters" + skip_longhands="content"> + pub fn set_content(&mut self, v: longhands::content::computed_value::T) { + use properties::longhands::content::computed_value::T; + use properties::longhands::content::computed_value::ContentItem; + use gecko_bindings::structs::nsStyleContentData; + use gecko_bindings::structs::nsStyleContentType::*; + use gecko_bindings::bindings::Gecko_ClearStyleContents; + + // Converts a string as utf16, and returns an owned, zero-terminated raw buffer. + fn as_utf16_and_forget(s: &str) -> *mut u16 { + use std::mem; + let mut vec = s.encode_utf16().collect::>(); + vec.push(0u16); + let ptr = vec.as_mut_ptr(); + mem::forget(vec); + ptr + } + + #[inline(always)] + #[cfg(debug_assertions)] + fn set_image_tracked(contents: &mut nsStyleContentData, val: bool) { + contents.mImageTracked = val; + } + + #[inline(always)] + #[cfg(not(debug_assertions))] + fn set_image_tracked(_contents: &mut nsStyleContentData, _val: bool) {} + + // Ensure destructors run, otherwise we could leak. + if !self.gecko.mContents.is_empty() { + unsafe { + Gecko_ClearStyleContents(&mut self.gecko); + } + } + + match v { + T::none | + T::normal => {}, // Do nothing, already cleared. + T::Content(items) => { + // NB: set_len also reserves the appropriate space. + unsafe { self.gecko.mContents.set_len(items.len() as u32) } + for (i, item) in items.into_iter().enumerate() { + // TODO: Servo lacks support for attr(), and URIs, + // We don't support images, but need to remember to + // explicitly initialize mImageTracked in debug builds. + set_image_tracked(&mut self.gecko.mContents[i], false); + // NB: Gecko compares the mString value if type is not image + // or URI independently of whatever gets there. In the quote + // cases, they set it to null, so do the same here. + unsafe { + *self.gecko.mContents[i].mContent.mString.as_mut() = ptr::null_mut(); + } + match item { + ContentItem::String(value) => { + self.gecko.mContents[i].mType = eStyleContentType_String; + unsafe { + // NB: we share allocators, so doing this is fine. + *self.gecko.mContents[i].mContent.mString.as_mut() = + as_utf16_and_forget(&value); + } + } + ContentItem::OpenQuote + => self.gecko.mContents[i].mType = eStyleContentType_OpenQuote, + ContentItem::CloseQuote + => self.gecko.mContents[i].mType = eStyleContentType_CloseQuote, + ContentItem::NoOpenQuote + => self.gecko.mContents[i].mType = eStyleContentType_NoOpenQuote, + ContentItem::NoCloseQuote + => self.gecko.mContents[i].mType = eStyleContentType_NoCloseQuote, + ContentItem::Counter(..) | + ContentItem::Counters(..) + => self.gecko.mContents[i].mType = eStyleContentType_Uninitialized, + } + } + } + } + } + + pub fn copy_content_from(&mut self, other: &Self) { + use gecko_bindings::bindings::Gecko_CopyStyleContentsFrom; + unsafe { + Gecko_CopyStyleContentsFrom(&mut self.gecko, &other.gecko) + } + } + + <%def name="define_ffi_struct_accessor(style_struct)"> #[no_mangle] #[allow(non_snake_case, unused_variables)] diff --git a/ports/geckolib/gecko_bindings/bindings.rs b/ports/geckolib/gecko_bindings/bindings.rs index 99baada7fe9..1acaeb72925 100644 --- a/ports/geckolib/gecko_bindings/bindings.rs +++ b/ports/geckolib/gecko_bindings/bindings.rs @@ -314,6 +314,9 @@ extern "C" { capacity: usize, elem_size: usize); pub fn Gecko_ClearPODTArray(array: *mut ::std::os::raw::c_void, elem_size: usize, elem_align: usize); + pub fn Gecko_ClearStyleContents(content: *mut nsStyleContent); + pub fn Gecko_CopyStyleContentsFrom(content: *mut nsStyleContent, + other: *const nsStyleContent); pub fn Gecko_EnsureImageLayersLength(layers: *mut nsStyleImageLayers, len: usize); pub fn Gecko_InitializeImageLayer(layer: *mut Layer, diff --git a/ports/geckolib/gecko_bindings/sugar/ns_t_array.rs b/ports/geckolib/gecko_bindings/sugar/ns_t_array.rs index ec6b72d5c16..3615f30d246 100644 --- a/ports/geckolib/gecko_bindings/sugar/ns_t_array.rs +++ b/ports/geckolib/gecko_bindings/sugar/ns_t_array.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use bindings::Gecko_EnsureTArrayCapacity; +use bindings; use std::mem; use std::ops::{Deref, DerefMut}; use std::os::raw::c_void; @@ -38,6 +38,7 @@ impl nsTArray { // unsafe, since header may be in shared static or something unsafe fn header_mut<'a>(&'a mut self) -> &'a mut nsTArrayHeader { debug_assert!(!self.mBuffer.is_null()); + mem::transmute(self.mBuffer) } @@ -47,12 +48,37 @@ impl nsTArray { (self.mBuffer as *const nsTArrayHeader).offset(1) as *mut _ } - fn ensure_capacity(&mut self, cap: usize) { - unsafe { - Gecko_EnsureTArrayCapacity(self as *mut nsTArray as *mut c_void, cap, mem::size_of::()) + /// Ensures the array has enough capacity at least to hold `cap` elements. + /// + /// NOTE: This doesn't call the constructor on the values! + pub fn ensure_capacity(&mut self, cap: usize) { + if cap >= self.len() { + unsafe { + bindings::Gecko_EnsureTArrayCapacity(self as *mut nsTArray as *mut _, + cap, mem::size_of::()) + } } } + /// Clears the array storage without calling the destructor on the values. + #[inline] + pub unsafe fn clear(&mut self) { + if self.len() != 0 { + bindings::Gecko_ClearPODTArray(self as *mut nsTArray as *mut _, + mem::size_of::(), + mem::align_of::()); + } + } + + + /// Clears a POD array. This is safe since copy types are memcopyable. + #[inline] + pub fn clear_pod(&mut self) + where T: Copy + { + unsafe { self.clear() } + } + // unsafe because the array may contain uninits // This will not call constructors, either manually // add bindings or run the typed ensurecapacity call From 9a5ffb128ae20cb4b95b4134f15729dd732779d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 15 Aug 2016 03:34:02 -0700 Subject: [PATCH 4/5] stylo: Regen bindings with https://github.com/servo/rust-bindgen/pull/29 --- ports/geckolib/binding_tools/regen.py | 2 - .../geckolib/gecko_bindings/structs_debug.rs | 42 +++++++++++-------- .../gecko_bindings/structs_release.rs | 42 +++++++++++-------- 3 files changed, 50 insertions(+), 36 deletions(-) diff --git a/ports/geckolib/binding_tools/regen.py b/ports/geckolib/binding_tools/regen.py index ba041fc9200..49b2557b91b 100755 --- a/ports/geckolib/binding_tools/regen.py +++ b/ports/geckolib/binding_tools/regen.py @@ -106,8 +106,6 @@ COMPILATION_TARGETS = { "Maybe", # <- AlignedStorage, which means templated union, which # means impossible to represent in stable rust as of # right now. - # Union handling falls over for templated types. - "StyleShapeSource", "StyleClipPath", "StyleShapeOutside", ], }, # Generation of the ffi bindings. diff --git a/ports/geckolib/gecko_bindings/structs_debug.rs b/ports/geckolib/gecko_bindings/structs_debug.rs index f726e9ee3ff..432fc55e86d 100644 --- a/ports/geckolib/gecko_bindings/structs_debug.rs +++ b/ports/geckolib/gecko_bindings/structs_debug.rs @@ -6389,25 +6389,33 @@ fn bindgen_test_layout_StyleBasicShape() { assert_eq!(::std::mem::align_of::() , 8usize); } #[repr(C)] -pub struct StyleShapeSource; -#[repr(C)] -pub struct StyleClipPath { - pub _bindgen_opaque_blob: [u64; 2usize], -} -#[test] -fn bindgen_test_layout_StyleClipPath() { - assert_eq!(::std::mem::size_of::() , 16usize); - assert_eq!(::std::mem::align_of::() , 8usize); +#[derive(Debug)] +pub struct StyleShapeSource { + pub StyleShapeSource_nsStyleStruct_h_unnamed_26: StyleShapeSource_nsStyleStruct_h_unnamed_26, + pub mType: StyleShapeSourceType, + pub mReferenceBox: ReferenceBox, } #[repr(C)] -pub struct StyleShapeOutside { - pub _bindgen_opaque_blob: [u64; 2usize], +#[derive(Debug, Copy, Clone)] +pub struct StyleShapeSource_nsStyleStruct_h_unnamed_26 { + pub mBasicShape: __BindgenUnionField<*mut StyleBasicShape>, + pub mURL: __BindgenUnionField<*mut FragmentOrURL>, + pub _bindgen_data_: u64, + pub _phantom0: ::std::marker::PhantomData, } -#[test] -fn bindgen_test_layout_StyleShapeOutside() { - assert_eq!(::std::mem::size_of::() , 16usize); - assert_eq!(::std::mem::align_of::() , 8usize); +impl StyleShapeSource_nsStyleStruct_h_unnamed_26 + { + pub unsafe fn mBasicShape(&mut self) -> *mut *mut StyleBasicShape { + let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_); + ::std::mem::transmute(raw.offset(0)) + } + pub unsafe fn mURL(&mut self) -> *mut *mut FragmentOrURL { + let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_); + ::std::mem::transmute(raw.offset(0)) + } } +pub type StyleClipPath = StyleShapeSource; +pub type StyleShapeOutside = StyleShapeSource; #[repr(C)] pub struct nsStyleDisplay { pub mBinding: RefPtr, @@ -6461,7 +6469,7 @@ pub struct nsStyleDisplay { pub mAnimationFillModeCount: u32, pub mAnimationPlayStateCount: u32, pub mAnimationIterationCountCount: u32, - pub mShapeOutside: [u64; 2usize], + pub mShapeOutside: StyleShapeOutside, } #[test] fn bindgen_test_layout_nsStyleDisplay() { @@ -6794,7 +6802,7 @@ fn bindgen_test_layout_nsStyleFilter() { #[repr(C)] pub struct nsStyleSVGReset { pub mMask: nsStyleImageLayers, - pub mClipPath: [u64; 2usize], + pub mClipPath: StyleClipPath, pub mStopColor: nscolor, pub mFloodColor: nscolor, pub mLightingColor: nscolor, diff --git a/ports/geckolib/gecko_bindings/structs_release.rs b/ports/geckolib/gecko_bindings/structs_release.rs index 3f4a833acd7..30ae855567d 100644 --- a/ports/geckolib/gecko_bindings/structs_release.rs +++ b/ports/geckolib/gecko_bindings/structs_release.rs @@ -6367,25 +6367,33 @@ fn bindgen_test_layout_StyleBasicShape() { assert_eq!(::std::mem::align_of::() , 8usize); } #[repr(C)] -pub struct StyleShapeSource; -#[repr(C)] -pub struct StyleClipPath { - pub _bindgen_opaque_blob: [u64; 2usize], -} -#[test] -fn bindgen_test_layout_StyleClipPath() { - assert_eq!(::std::mem::size_of::() , 16usize); - assert_eq!(::std::mem::align_of::() , 8usize); +#[derive(Debug)] +pub struct StyleShapeSource { + pub StyleShapeSource_nsStyleStruct_h_unnamed_26: StyleShapeSource_nsStyleStruct_h_unnamed_26, + pub mType: StyleShapeSourceType, + pub mReferenceBox: ReferenceBox, } #[repr(C)] -pub struct StyleShapeOutside { - pub _bindgen_opaque_blob: [u64; 2usize], +#[derive(Debug, Copy, Clone)] +pub struct StyleShapeSource_nsStyleStruct_h_unnamed_26 { + pub mBasicShape: __BindgenUnionField<*mut StyleBasicShape>, + pub mURL: __BindgenUnionField<*mut FragmentOrURL>, + pub _bindgen_data_: u64, + pub _phantom0: ::std::marker::PhantomData, } -#[test] -fn bindgen_test_layout_StyleShapeOutside() { - assert_eq!(::std::mem::size_of::() , 16usize); - assert_eq!(::std::mem::align_of::() , 8usize); +impl StyleShapeSource_nsStyleStruct_h_unnamed_26 + { + pub unsafe fn mBasicShape(&mut self) -> *mut *mut StyleBasicShape { + let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_); + ::std::mem::transmute(raw.offset(0)) + } + pub unsafe fn mURL(&mut self) -> *mut *mut FragmentOrURL { + let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_); + ::std::mem::transmute(raw.offset(0)) + } } +pub type StyleClipPath = StyleShapeSource; +pub type StyleShapeOutside = StyleShapeSource; #[repr(C)] pub struct nsStyleDisplay { pub mBinding: RefPtr, @@ -6439,7 +6447,7 @@ pub struct nsStyleDisplay { pub mAnimationFillModeCount: u32, pub mAnimationPlayStateCount: u32, pub mAnimationIterationCountCount: u32, - pub mShapeOutside: [u64; 2usize], + pub mShapeOutside: StyleShapeOutside, } #[test] fn bindgen_test_layout_nsStyleDisplay() { @@ -6771,7 +6779,7 @@ fn bindgen_test_layout_nsStyleFilter() { #[repr(C)] pub struct nsStyleSVGReset { pub mMask: nsStyleImageLayers, - pub mClipPath: [u64; 2usize], + pub mClipPath: StyleClipPath, pub mStopColor: nscolor, pub mFloodColor: nscolor, pub mLightingColor: nscolor, From 49742554118c574e8a3ea16c1d038fcf8a2bfc84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 15 Aug 2016 22:38:50 -0700 Subject: [PATCH 5/5] stylo: Allow passing --debug and --debugger flags to the python script. --- ports/geckolib/binding_tools/regen.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/ports/geckolib/binding_tools/regen.py b/ports/geckolib/binding_tools/regen.py index 49b2557b91b..88c423931d8 100755 --- a/ports/geckolib/binding_tools/regen.py +++ b/ports/geckolib/binding_tools/regen.py @@ -210,7 +210,7 @@ def extend_object(obj, other): obj[key] = copy.deepcopy(other[key]) -def build(objdir, target_name, kind_name=None, +def build(objdir, target_name, debug, debugger, kind_name=None, output_filename=None, bindgen=None, skip_test=False, verbose=False): assert target_name in COMPILATION_TARGETS @@ -344,10 +344,15 @@ def build(objdir, target_name, kind_name=None, flags.append(current_target["files"][0].format(objdir)) flags = bindgen + flags - output = None + + output = "" try: - output = subprocess.check_output(flags, stderr=subprocess.STDOUT) - output = output.decode('utf8') + if debug: + flags = [debugger, "--args"] + flags + subprocess.check_call(flags) + else: + output = subprocess.check_output(flags, stderr=subprocess.STDOUT) + output = output.decode('utf8') except subprocess.CalledProcessError as e: print("FAIL\n", e.output.decode('utf8')) return 1 @@ -426,7 +431,7 @@ def builds_for(target_name, kind): def main(): parser = argparse.ArgumentParser(description=DESCRIPTION) - parser.add_argument('--target', default="all", + parser.add_argument('--target', default='all', help='The target to build, either "structs" or "bindings"') parser.add_argument('--kind', help='Kind of build') @@ -440,6 +445,11 @@ def main(): parser.add_argument('--verbose', '-v', action='store_true', help='Be... verbose') + parser.add_argument('--debug', + action='store_true', + help='Try to use a debugger to debug bindgen commands (default: gdb)') + parser.add_argument('--debugger', default='gdb', + help='Debugger to use. Only used if --debug is passed.') parser.add_argument('objdir') args = parser.parse_args() @@ -465,7 +475,8 @@ def main(): return 1 for target, kind in builds_for(args.target, args.kind): - ret = build(args.objdir, target, kind, + ret = build(args.objdir, target, kind_name=kind, + debug=args.debug, debugger=args.debugger, bindgen=args.bindgen, skip_test=args.skip_test, output_filename=args.output, verbose=args.verbose)