@@ -63,6 +63,7 @@ pub struct CParameter {
63
63
pub transfer : library:: Transfer ,
64
64
pub caller_allocates : bool ,
65
65
pub is_error : bool ,
66
+ pub has_length : bool ,
66
67
pub scope : ParameterScope ,
67
68
/// Index of the user data parameter associated with the callback.
68
69
pub user_data_index : Option < usize > ,
@@ -76,6 +77,25 @@ pub struct CParameter {
76
77
pub move_ : bool ,
77
78
}
78
79
80
+ impl CParameter {
81
+ pub fn is_gstr ( & self , env : & Env ) -> bool {
82
+ matches ! (
83
+ env. type_( self . typ) ,
84
+ library:: Type :: Basic ( library:: Basic :: Utf8 )
85
+ ) && self . ref_mode . is_ref ( )
86
+ }
87
+ pub fn is_strv ( & self , env : & Env ) -> bool {
88
+ if let library:: Type :: CArray ( inner) = env. type_ ( self . typ ) {
89
+ matches ! (
90
+ env. type_( * inner) ,
91
+ library:: Type :: Basic ( library:: Basic :: Utf8 )
92
+ ) && !matches ! ( self . c_type. as_str( ) , "char**" | "gchar**" )
93
+ } else {
94
+ false
95
+ }
96
+ }
97
+ }
98
+
79
99
#[ derive( Clone , Debug ) ]
80
100
pub enum TransformationType {
81
101
ToGlibDirect {
@@ -288,7 +308,7 @@ pub fn analyze(
288
308
array_par = array_lengths. get ( & ( pos as u32 ) ) . copied ( ) ;
289
309
}
290
310
if array_par. is_none ( ) && !disable_length_detect {
291
- array_par = detect_length ( env, pos, par, function_parameters) ;
311
+ array_par = detect_array ( env, pos, par, function_parameters) ;
292
312
}
293
313
if let Some ( array_par) = array_par {
294
314
let mut array_name = nameutil:: mangle_keywords ( & array_par. name ) ;
@@ -319,6 +339,9 @@ pub fn analyze(
319
339
} ;
320
340
parameters. transformations . push ( transformation) ;
321
341
}
342
+ let has_length = par. array_length . is_some ( )
343
+ || ( !disable_length_detect
344
+ && detect_length ( env, pos, par, function_parameters) . is_some ( ) ) ;
322
345
323
346
let immutable = configured_parameters. iter ( ) . any ( |p| p. constant ) ;
324
347
let ref_mode =
@@ -340,6 +363,7 @@ pub fn analyze(
340
363
nullable,
341
364
ref_mode,
342
365
is_error : par. is_error ,
366
+ has_length,
343
367
scope : par. scope ,
344
368
user_data_index : par. closure ,
345
369
destroy_index : par. destroy ,
@@ -454,31 +478,22 @@ pub fn analyze(
454
478
}
455
479
456
480
let c_par = parameters. c_parameters . last ( ) . unwrap ( ) ;
457
- match env. type_ ( typ) {
458
- library:: Type :: Basic ( library:: Basic :: Utf8 ) if ref_mode. is_ref ( ) => {
459
- transformation. transformation_type = TransformationType :: RunWith {
460
- name : c_par. name . clone ( ) ,
461
- func : if * c_par. nullable {
462
- nameutil:: use_glib_type ( env, "IntoOptionalGStr::run_with_gstr" )
463
- } else {
464
- nameutil:: use_glib_type ( env, "IntoGStr::run_with_gstr" )
465
- } ,
466
- inner : Box :: new ( transformation. transformation_type ) ,
467
- } ;
468
- }
469
- library:: Type :: CArray ( inner)
470
- if matches ! (
471
- env. type_( * inner) ,
472
- library:: Type :: Basic ( library:: Basic :: Utf8 )
473
- ) && !matches ! ( c_par. c_type. as_str( ) , "char**" | "gchar**" ) =>
474
- {
475
- transformation. transformation_type = TransformationType :: RunWith {
476
- name : c_par. name . clone ( ) ,
477
- func : nameutil:: use_glib_type ( env, "IntoStrV::run_with_strv" ) ,
478
- inner : Box :: new ( TransformationType :: AsPtr ( c_par. name . clone ( ) ) ) ,
479
- } ;
480
- }
481
- _ => { }
481
+ if c_par. is_gstr ( env) && !has_length {
482
+ transformation. transformation_type = TransformationType :: RunWith {
483
+ name : c_par. name . clone ( ) ,
484
+ func : if * c_par. nullable {
485
+ nameutil:: use_glib_type ( env, "IntoOptionalGStr::run_with_gstr" )
486
+ } else {
487
+ nameutil:: use_glib_type ( env, "IntoGStr::run_with_gstr" )
488
+ } ,
489
+ inner : Box :: new ( transformation. transformation_type ) ,
490
+ } ;
491
+ } else if c_par. is_strv ( env) {
492
+ transformation. transformation_type = TransformationType :: RunWith {
493
+ name : c_par. name . clone ( ) ,
494
+ func : nameutil:: use_glib_type ( env, "IntoStrV::run_with_strv" ) ,
495
+ inner : Box :: new ( TransformationType :: AsPtr ( c_par. name . clone ( ) ) ) ,
496
+ } ;
482
497
}
483
498
484
499
parameters. transformations . push ( transformation) ;
@@ -507,30 +522,33 @@ fn detect_length<'a>(
507
522
par : & library:: Parameter ,
508
523
parameters : & ' a [ library:: Parameter ] ,
509
524
) -> Option < & ' a library:: Parameter > {
510
- if !is_length ( par) {
525
+ if !has_length ( env , par. typ ) {
511
526
return None ;
512
527
}
513
528
514
- parameters. get ( pos - 1 ) . and_then ( |p| {
515
- if has_length ( env, p. typ ) {
516
- Some ( p)
517
- } else {
518
- None
519
- }
520
- } )
529
+ parameters
530
+ . get ( pos + 1 )
531
+ . and_then ( |p| is_length ( p) . then_some ( p) )
521
532
}
522
533
523
- fn is_length ( par : & library:: Parameter ) -> bool {
524
- if par. direction != library:: ParameterDirection :: In {
525
- return false ;
534
+ fn detect_array < ' a > (
535
+ env : & Env ,
536
+ pos : usize ,
537
+ par : & library:: Parameter ,
538
+ parameters : & ' a [ library:: Parameter ] ,
539
+ ) -> Option < & ' a library:: Parameter > {
540
+ if !is_length ( par) {
541
+ return None ;
526
542
}
527
543
528
- let len = par . name . len ( ) ;
529
- if len >= 3 && & par . name [ len - 3 ..len ] == "len" {
530
- return true ;
531
- }
544
+ parameters
545
+ . get ( pos . checked_sub ( 1 ) ? )
546
+ . and_then ( |p| has_length ( env , p . typ ) . then_some ( p ) )
547
+ }
532
548
533
- par. name . contains ( "length" )
549
+ fn is_length ( par : & library:: Parameter ) -> bool {
550
+ par. direction == library:: ParameterDirection :: In
551
+ && ( par. name . ends_with ( "len" ) || par. name . contains ( "length" ) )
534
552
}
535
553
536
554
fn has_length ( env : & Env , typ : TypeId ) -> bool {
0 commit comments