@@ -6,6 +6,7 @@ import 'dart:io';
6
6
7
7
import 'package:ffigen/src/code_generator.dart' ;
8
8
import 'package:ffigen/src/code_generator/utils.dart' ;
9
+ import 'package:ffigen/src/header_parser/type_extractor/cxtypekindmap.dart' ;
9
10
import 'package:file/local.dart' ;
10
11
import 'package:glob/glob.dart' ;
11
12
import 'package:logging/logging.dart' ;
@@ -329,29 +330,91 @@ Map<String, ImportedType> makeImportTypeMapping(
329
330
return typeMappings;
330
331
}
331
332
333
+ Type makePointerToType (Type type, int pointerCount) {
334
+ for (var i = 0 ; i < pointerCount; i++ ) {
335
+ type = PointerType (type);
336
+ }
337
+ return type;
338
+ }
339
+
340
+ String makePostfixFromRawVarArgType (List <String > rawVarArgType) {
341
+ return rawVarArgType
342
+ .map ((e) => e
343
+ .replaceAll ('*' , 'Ptr' )
344
+ .replaceAll (r'\s' , '' )
345
+ .replaceAll ('_t' , '' )
346
+ .replaceAll (' ' , '' )
347
+ .replaceAll ('[^A-Za-z0-9]' , '' ))
348
+ .map ((e) => e.length > 1 ? '${e [0 ].toUpperCase ()}${e .substring (1 )}' : e)
349
+ .join ('' );
350
+ }
351
+
352
+ Type makeTypeFromRawVarArgType (
353
+ String rawVarArgType, Map <String , LibraryImport > libraryImportsMap) {
354
+ rawVarArgType = rawVarArgType.trim ();
355
+ final typeStringRegexp = RegExp (r'([a-zA-Z0-9_\s\.]+)(\**)$' );
356
+ if (! typeStringRegexp.hasMatch (rawVarArgType)) {
357
+ throw Exception ('Cannot parse variadic argument type - $rawVarArgType .' );
358
+ }
359
+ final regExpMatch = typeStringRegexp.firstMatch (rawVarArgType)! ;
360
+ final groups = regExpMatch.groups ([1 , 2 ]);
361
+ rawVarArgType = groups[0 ]! ;
362
+ final pointerCount = groups[1 ]! .length;
363
+ // Handle pointers.
364
+ if (cxTypeKindToImportedTypes.containsKey (rawVarArgType)) {
365
+ return makePointerToType (
366
+ cxTypeKindToImportedTypes[rawVarArgType]! , pointerCount);
367
+ } else if (supportedTypedefToImportedType.containsKey (rawVarArgType)) {
368
+ return makePointerToType (
369
+ supportedTypedefToImportedType[rawVarArgType]! , pointerCount);
370
+ } else if (suportedTypedefToSuportedNativeType.containsKey (rawVarArgType)) {
371
+ return makePointerToType (
372
+ NativeType (suportedTypedefToSuportedNativeType[rawVarArgType]! ),
373
+ pointerCount);
374
+ } else {
375
+ final rawVarArgTypeSplit = rawVarArgType.split ('.' );
376
+ if (rawVarArgTypeSplit.length == 1 ) {
377
+ final typeName = rawVarArgTypeSplit[0 ].replaceAll (' ' , '' );
378
+ return makePointerToType (
379
+ SelfImportedType (typeName, typeName), pointerCount);
380
+ } else if (rawVarArgTypeSplit.length == 2 ) {
381
+ final lib = rawVarArgTypeSplit[0 ];
382
+ final libraryImport = strings.predefinedLibraryImports[lib] ??
383
+ libraryImportsMap[rawVarArgTypeSplit[0 ]];
384
+ if (libraryImport == null ) {
385
+ throw Exception ('Please declare $lib in library-imports.' );
386
+ }
387
+ final typeName = rawVarArgTypeSplit[1 ].replaceAll (' ' , '' );
388
+ return makePointerToType (
389
+ ImportedType (libraryImport, typeName, typeName), pointerCount);
390
+ } else {
391
+ throw Exception (
392
+ 'Invalid type $rawVarArgType : Expected 0 or 1 .(dot) separators.' );
393
+ }
394
+ }
395
+ }
396
+
332
397
Map <String , List <VarArgFunction >> makeVarArgFunctionsMapping (
333
- Map <String , List <List < List < String >> >> rawVarArgMappings,
398
+ Map <String , List <RawVarArgFunction >> rawVarArgMappings,
334
399
Map <String , LibraryImport > libraryImportsMap) {
335
400
final mappings = < String , List <VarArgFunction >> {};
336
401
for (final key in rawVarArgMappings.keys) {
337
402
final varArgList = < VarArgFunction > [];
338
- for (final rawVarArgs in rawVarArgMappings[key]! ) {
403
+ for (final rawVarArg in rawVarArgMappings[key]! ) {
404
+ var postfix = rawVarArg.postfix ?? '' ;
339
405
final types = < Type > [];
340
- for (final rva in rawVarArgs) {
341
- final lib = rva[0 ];
342
- final cType = rva[1 ]; // TODO: deduce these automatically
343
- final dartType = rva[1 ]; // TODO: deduce these automatically
344
- if (strings.predefinedLibraryImports.containsKey (lib)) {
345
- types.add (ImportedType (
346
- strings.predefinedLibraryImports[lib]! , cType, dartType));
347
- } else if (libraryImportsMap.containsKey (lib)) {
348
- types.add (ImportedType (libraryImportsMap[lib]! , cType, dartType));
406
+ for (final rva in rawVarArg.rawTypeStrings) {
407
+ types.add (makeTypeFromRawVarArgType (rva, libraryImportsMap));
408
+ }
409
+ if (postfix.isEmpty) {
410
+ if (rawVarArgMappings[key]! .length == 1 ) {
411
+ postfix = '' ;
349
412
} else {
350
- throw Exception ( "Please declare $ lib under library-imports." );
413
+ postfix = makePostfixFromRawVarArgType (rawVarArg.rawTypeStrings );
351
414
}
352
415
}
353
416
// Extract postfix from config and/or deduce from var names.
354
- varArgList.add (VarArgFunction ('vaf' , types));
417
+ varArgList.add (VarArgFunction (postfix , types));
355
418
}
356
419
mappings[key] = varArgList;
357
420
}
@@ -772,38 +835,79 @@ Includer _extractIncluderFromYaml(dynamic yamlMap) {
772
835
);
773
836
}
774
837
775
- Map <String , List <List < List < String >> >> varArgFunctionConfigExtractor (
838
+ Map <String , List <RawVarArgFunction >> varArgFunctionConfigExtractor (
776
839
dynamic yamlMap) {
777
- final result = < String , List <List < List < String >> >> {};
840
+ final result = < String , List <RawVarArgFunction >> {};
778
841
final configMap = (yamlMap as YamlMap );
779
842
for (final key in configMap.keys) {
780
- final List <List <List <String >>> vf = [];
781
- for (final vaFuncs in (configMap[key] as YamlList )) {
782
- final List <List <String >> vfTypes = [];
783
- for (final typeStrings in (vaFuncs as YamlList )) {
784
- vfTypes.add ((typeStrings as String ).split ("." ));
843
+ final List <RawVarArgFunction > vafuncs = [];
844
+ for (final rawVaFunc in (configMap[key] as YamlList )) {
845
+ if (rawVaFunc is YamlList ) {
846
+ vafuncs.add (RawVarArgFunction (null , rawVaFunc.cast ()));
847
+ } else if (rawVaFunc is YamlMap ) {
848
+ vafuncs.add (RawVarArgFunction (rawVaFunc[strings.postfix] as String ? ,
849
+ (rawVaFunc[strings.types] as YamlList ).cast ()));
850
+ } else {
851
+ throw Exception ("Unexpected type in variadic-argument config." );
785
852
}
786
- vf.add (vfTypes);
787
853
}
788
- result[key as String ] = vf ;
854
+ result[key as String ] = vafuncs ;
789
855
}
856
+
790
857
return result;
791
858
}
792
859
793
- bool varArgFunctionConfigExtractorValidator (List <String > name, dynamic value) {
860
+ bool varArgFunctionConfigValidator (List <String > name, dynamic value) {
794
861
if (! checkType <YamlMap >(name, value)) {
795
862
return false ;
796
863
}
797
864
var _result = true ;
798
- for (final key in (value as YamlMap ).cast < String , dynamic >(). keys) {
799
- final list = value[key];
865
+ for (final key in (value as YamlMap ).keys) {
866
+ final list = value[key as String ];
800
867
if (! checkType <YamlList >([...name, key], list)) {
801
868
_result = false ;
802
869
continue ;
803
870
}
804
871
(list as YamlList ).asMap ().forEach ((idx, subList) {
805
- if (! checkType <YamlList >([...name, key, idx.toString ()], subList)) {
872
+ if (subList is YamlMap ) {
873
+ if (! subList.containsKey (strings.types)) {
874
+ _result = false ;
875
+ _logger.severe ('Missing required key - ${[
876
+ ...name ,
877
+ key ,
878
+ idx .toString (),
879
+ strings .types
880
+ ].join (" -> " )}' );
881
+ }
882
+ subList.forEach ((subkey, subvalue) {
883
+ subkey = subkey as String ;
884
+ if (subkey == strings.postfix) {
885
+ if (! checkType <String >(
886
+ [...name, key, idx.toString (), subkey], subvalue)) {
887
+ _result = false ;
888
+ }
889
+ } else if (subkey == strings.types) {
890
+ if (! checkType <YamlList >(
891
+ [...name, key, idx.toString (), subkey], subvalue)) {
892
+ _result = false ;
893
+ }
894
+ } else {
895
+ _result = false ;
896
+ _logger.severe ('Unknown key - ${[
897
+ ...name ,
898
+ key ,
899
+ idx .toString (),
900
+ subkey
901
+ ].join (" -> " )}' );
902
+ }
903
+ });
904
+ } else if (subList is ! YamlList ) {
806
905
_result = false ;
906
+ _logger.severe ('Expected ${[
907
+ ...name ,
908
+ key ,
909
+ idx
910
+ ].join (" -> " )} to be a List or a Map.' );
807
911
}
808
912
});
809
913
}
0 commit comments