diff --git a/pkgs/hooks/example/build/native_add_library/constants-ffigen.yaml b/pkgs/hooks/example/build/native_add_library/constants-ffigen.yaml new file mode 100644 index 0000000000..f13e8aa75b --- /dev/null +++ b/pkgs/hooks/example/build/native_add_library/constants-ffigen.yaml @@ -0,0 +1,31 @@ +# Run with `flutter pub run ffigen --config ffigen.yaml`. +name: NativeAddBindings +description: | + Bindings for `src/native_add_library.h`. + + Regenerate bindings with `flutter pub run ffigen --config ffigen.yaml`. +output: 'lib/src/constant_bindings.dart' +headers: + entry-points: + - 'src/constants.g.h' + + include-directives: + - 'src/constants.g.h' +preamble: | + // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file + // for details. All rights reserved. Use of this source code is governed by a + // BSD-style license that can be found in the LICENSE file. +comments: + style: any + length: full +ffi-native: + +structs: + rename: + 'my_(.*)': '$1' +functions: + rename: + 'my_(.*)': '$1' +typedefs: + rename: + 'my_(.*)': '$1' diff --git a/pkgs/hooks/example/build/native_add_library/constants.json b/pkgs/hooks/example/build/native_add_library/constants.json new file mode 100644 index 0000000000..c765c52e92 --- /dev/null +++ b/pkgs/hooks/example/build/native_add_library/constants.json @@ -0,0 +1,32 @@ +[ + "S_IEXEC", + "S_IFBLK", + "S_IFCHR", + "S_IFDIR", + "S_IFIFO", + "S_IFLNK", + "S_IFMT", + "S_IFREG", + "S_IFSOCK", + "S_IFWHT", + "S_IREAD", + "S_IRGRP", + "S_IROTH", + "S_IRUSR", + "S_IRWXG", + "S_IRWXO", + "S_IRWXU", + "S_ISGID", + "S_ISTXT", + "S_ISUID", + "S_ISVTX", + "S_IWGRP", + "S_IWOTH", + "S_IWRITE", + "S_IWUSR", + "S_IXGRP", + "S_IXOTH", + "S_IXUSR", + "UF_APPEND", + "UF_HIDDEN" +] \ No newline at end of file diff --git a/pkgs/hooks/example/build/native_add_library/ffigen.yaml b/pkgs/hooks/example/build/native_add_library/ffigen.yaml index 11e58af753..13a8713e68 100644 --- a/pkgs/hooks/example/build/native_add_library/ffigen.yaml +++ b/pkgs/hooks/example/build/native_add_library/ffigen.yaml @@ -4,10 +4,11 @@ description: | Bindings for `src/native_add_library.h`. Regenerate bindings with `flutter pub run ffigen --config ffigen.yaml`. -output: 'lib/native_add_library.dart' +output: 'lib/src/libc_bindings.dart' headers: entry-points: - 'src/native_add_library.h' + include-directives: - 'src/native_add_library.h' preamble: | @@ -18,3 +19,13 @@ comments: style: any length: full ffi-native: + +structs: + rename: + 'my_(.*)': '$1' +functions: + rename: + 'my_(.*)': '$1' +typedefs: + rename: + 'my_(.*)': '$1' diff --git a/pkgs/hooks/example/build/native_add_library/hook/build.dart b/pkgs/hooks/example/build/native_add_library/hook/build.dart index 0ff9ad95e4..80cc6ff83f 100644 --- a/pkgs/hooks/example/build/native_add_library/hook/build.dart +++ b/pkgs/hooks/example/build/native_add_library/hook/build.dart @@ -11,8 +11,9 @@ void main(List args) async { final packageName = input.packageName; final cbuilder = CBuilder.library( name: packageName, - assetName: '$packageName.dart', - sources: ['src/$packageName.c'], + assetName: 'src/libc_bindings.dart', + sources: ['src/$packageName.c', 'src/constants.g.c'], + flags: ['-Weverything'], ); await cbuilder.run( input: input, diff --git a/pkgs/hooks/example/build/native_add_library/lib/native_add_library.dart b/pkgs/hooks/example/build/native_add_library/lib/native_add_library.dart index 419f8b03f6..106183a05b 100644 --- a/pkgs/hooks/example/build/native_add_library/lib/native_add_library.dart +++ b/pkgs/hooks/example/build/native_add_library/lib/native_add_library.dart @@ -1,12 +1,7 @@ -// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. +import 'src/libc_bindings.dart' as libc; -// AUTO GENERATED FILE, DO NOT EDIT. -// -// Generated by `package:ffigen`. -// ignore_for_file: type=lint -import 'dart:ffi' as ffi; +export 'src/constants.g.dart'; +export 'src/libc_bindings.dart' hide errno, seterrno; -@ffi.Native() -external int add(int a, int b); +int get errno => libc.errno(); +set errno(int err) => libc.seterrno(err); diff --git a/pkgs/hooks/example/build/native_add_library/lib/src/constant_bindings.dart b/pkgs/hooks/example/build/native_add_library/lib/src/constant_bindings.dart new file mode 100644 index 0000000000..c51b41425d --- /dev/null +++ b/pkgs/hooks/example/build/native_add_library/lib/src/constant_bindings.dart @@ -0,0 +1,101 @@ +// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// AUTO GENERATED FILE, DO NOT EDIT. +// +// Generated by `package:ffigen`. +// ignore_for_file: type=lint +import 'dart:ffi' as ffi; + +@ffi.Native(symbol: 'my_get_S_IEXEC') +external int get_S_IEXEC(); + +@ffi.Native(symbol: 'my_get_S_IFBLK') +external int get_S_IFBLK(); + +@ffi.Native(symbol: 'my_get_S_IFCHR') +external int get_S_IFCHR(); + +@ffi.Native(symbol: 'my_get_S_IFDIR') +external int get_S_IFDIR(); + +@ffi.Native(symbol: 'my_get_S_IFIFO') +external int get_S_IFIFO(); + +@ffi.Native(symbol: 'my_get_S_IFLNK') +external int get_S_IFLNK(); + +@ffi.Native(symbol: 'my_get_S_IFMT') +external int get_S_IFMT(); + +@ffi.Native(symbol: 'my_get_S_IFREG') +external int get_S_IFREG(); + +@ffi.Native(symbol: 'my_get_S_IFSOCK') +external int get_S_IFSOCK(); + +@ffi.Native(symbol: 'my_get_S_IFWHT') +external int get_S_IFWHT(); + +@ffi.Native(symbol: 'my_get_S_IREAD') +external int get_S_IREAD(); + +@ffi.Native(symbol: 'my_get_S_IRGRP') +external int get_S_IRGRP(); + +@ffi.Native(symbol: 'my_get_S_IROTH') +external int get_S_IROTH(); + +@ffi.Native(symbol: 'my_get_S_IRUSR') +external int get_S_IRUSR(); + +@ffi.Native(symbol: 'my_get_S_IRWXG') +external int get_S_IRWXG(); + +@ffi.Native(symbol: 'my_get_S_IRWXO') +external int get_S_IRWXO(); + +@ffi.Native(symbol: 'my_get_S_IRWXU') +external int get_S_IRWXU(); + +@ffi.Native(symbol: 'my_get_S_ISGID') +external int get_S_ISGID(); + +@ffi.Native(symbol: 'my_get_S_ISTXT') +external int get_S_ISTXT(); + +@ffi.Native(symbol: 'my_get_S_ISUID') +external int get_S_ISUID(); + +@ffi.Native(symbol: 'my_get_S_ISVTX') +external int get_S_ISVTX(); + +@ffi.Native(symbol: 'my_get_S_IWGRP') +external int get_S_IWGRP(); + +@ffi.Native(symbol: 'my_get_S_IWOTH') +external int get_S_IWOTH(); + +@ffi.Native(symbol: 'my_get_S_IWRITE') +external int get_S_IWRITE(); + +@ffi.Native(symbol: 'my_get_S_IWUSR') +external int get_S_IWUSR(); + +@ffi.Native(symbol: 'my_get_S_IXGRP') +external int get_S_IXGRP(); + +@ffi.Native(symbol: 'my_get_S_IXOTH') +external int get_S_IXOTH(); + +@ffi.Native(symbol: 'my_get_S_IXUSR') +external int get_S_IXUSR(); + +@ffi.Native(symbol: 'my_get_UF_APPEND') +external int get_UF_APPEND(); + +@ffi.Native(symbol: 'my_get_UF_HIDDEN') +external int get_UF_HIDDEN(); + +const int my_UNDEFINED = 9223372036854775807; diff --git a/pkgs/hooks/example/build/native_add_library/lib/src/constants.g.dart b/pkgs/hooks/example/build/native_add_library/lib/src/constants.g.dart new file mode 100644 index 0000000000..f2b8efb257 --- /dev/null +++ b/pkgs/hooks/example/build/native_add_library/lib/src/constants.g.dart @@ -0,0 +1,273 @@ +// ignore_for_file: non_constant_identifier_names + +import 'constant_bindings.dart'; +int get S_IEXEC { + final v = get_S_IEXEC(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IEXEC'); + } else { + return v; + } +} + +int get S_IFBLK { + final v = get_S_IFBLK(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IFBLK'); + } else { + return v; + } +} + +int get S_IFCHR { + final v = get_S_IFCHR(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IFCHR'); + } else { + return v; + } +} + +int get S_IFDIR { + final v = get_S_IFDIR(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IFDIR'); + } else { + return v; + } +} + +int get S_IFIFO { + final v = get_S_IFIFO(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IFIFO'); + } else { + return v; + } +} + +int get S_IFLNK { + final v = get_S_IFLNK(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IFLNK'); + } else { + return v; + } +} + +int get S_IFMT { + final v = get_S_IFMT(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IFMT'); + } else { + return v; + } +} + +int get S_IFREG { + final v = get_S_IFREG(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IFREG'); + } else { + return v; + } +} + +int get S_IFSOCK { + final v = get_S_IFSOCK(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IFSOCK'); + } else { + return v; + } +} + +int get S_IFWHT { + final v = get_S_IFWHT(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IFWHT'); + } else { + return v; + } +} + +int get S_IREAD { + final v = get_S_IREAD(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IREAD'); + } else { + return v; + } +} + +int get S_IRGRP { + final v = get_S_IRGRP(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IRGRP'); + } else { + return v; + } +} + +int get S_IROTH { + final v = get_S_IROTH(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IROTH'); + } else { + return v; + } +} + +int get S_IRUSR { + final v = get_S_IRUSR(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IRUSR'); + } else { + return v; + } +} + +int get S_IRWXG { + final v = get_S_IRWXG(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IRWXG'); + } else { + return v; + } +} + +int get S_IRWXO { + final v = get_S_IRWXO(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IRWXO'); + } else { + return v; + } +} + +int get S_IRWXU { + final v = get_S_IRWXU(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IRWXU'); + } else { + return v; + } +} + +int get S_ISGID { + final v = get_S_ISGID(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_ISGID'); + } else { + return v; + } +} + +int get S_ISTXT { + final v = get_S_ISTXT(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_ISTXT'); + } else { + return v; + } +} + +int get S_ISUID { + final v = get_S_ISUID(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_ISUID'); + } else { + return v; + } +} + +int get S_ISVTX { + final v = get_S_ISVTX(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_ISVTX'); + } else { + return v; + } +} + +int get S_IWGRP { + final v = get_S_IWGRP(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IWGRP'); + } else { + return v; + } +} + +int get S_IWOTH { + final v = get_S_IWOTH(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IWOTH'); + } else { + return v; + } +} + +int get S_IWRITE { + final v = get_S_IWRITE(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IWRITE'); + } else { + return v; + } +} + +int get S_IWUSR { + final v = get_S_IWUSR(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IWUSR'); + } else { + return v; + } +} + +int get S_IXGRP { + final v = get_S_IXGRP(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IXGRP'); + } else { + return v; + } +} + +int get S_IXOTH { + final v = get_S_IXOTH(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IXOTH'); + } else { + return v; + } +} + +int get S_IXUSR { + final v = get_S_IXUSR(); + if (v == my_UNDEFINED) { + throw UnsupportedError('S_IXUSR'); + } else { + return v; + } +} + +int get UF_APPEND { + final v = get_UF_APPEND(); + if (v == my_UNDEFINED) { + throw UnsupportedError('UF_APPEND'); + } else { + return v; + } +} + +int get UF_HIDDEN { + final v = get_UF_HIDDEN(); + if (v == my_UNDEFINED) { + throw UnsupportedError('UF_HIDDEN'); + } else { + return v; + } +} + diff --git a/pkgs/hooks/example/build/native_add_library/lib/src/libc_bindings.dart b/pkgs/hooks/example/build/native_add_library/lib/src/libc_bindings.dart new file mode 100644 index 0000000000..0ceee9e6a9 --- /dev/null +++ b/pkgs/hooks/example/build/native_add_library/lib/src/libc_bindings.dart @@ -0,0 +1,159 @@ +// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// AUTO GENERATED FILE, DO NOT EDIT. +// +// Generated by `package:ffigen`. +// ignore_for_file: type=lint +import 'dart:ffi' as ffi; + +/// +@ffi.Native, ffi.Int64, ffi.Int64)>( + symbol: 'my_open') +external int open( + ffi.Pointer pathname, + int flags, + int mode, +); + +@ffi.Native, ffi.Pointer)>( + symbol: 'my_rename') +external int rename( + ffi.Pointer old, + ffi.Pointer new$, +); + +/// +@ffi.Native(symbol: 'my_close') +external int close( + int fd, +); + +@ffi.Native, ffi.Int64)>() +external int unlinkat( + int dirfd, + ffi.Pointer pathname, + int flags, +); + +/// +@ffi.Native(symbol: 'my_seterrno') +external void seterrno( + int err, +); + +@ffi.Native(symbol: 'my_errno') +external int errno(); + +/// +@ffi.Native Function(ffi.Pointer)>( + symbol: 'my_getenv') +external ffi.Pointer getenv( + ffi.Pointer name, +); + +@ffi.Native Function(ffi.Pointer)>( + symbol: 'my_mkdtemp') +external ffi.Pointer mkdtemp( + ffi.Pointer template, +); + +@ffi.Native)>(symbol: 'my_closedir') +external int closedir( + ffi.Pointer d, +); + +@ffi.Native Function(ffi.Pointer)>( + symbol: 'my_opendir') +external ffi.Pointer opendir( + ffi.Pointer path, +); + +@ffi.Native Function(ffi.Pointer)>( + symbol: 'my_readdir') +external ffi.Pointer readdir( + ffi.Pointer d, +); + +@ffi.Native, ffi.Int64)>( + symbol: 'my_mkdir') +external int mkdir( + ffi.Pointer pathname, + int mode, +); + +@ffi.Native, ffi.Pointer)>( + symbol: 'my_stat') +external int stat( + ffi.Pointer path, + ffi.Pointer buf, +); + +@ffi.Native, ffi.Pointer)>( + symbol: 'my_lstat') +external int lstat( + ffi.Pointer path, + ffi.Pointer buf, +); + +@ffi.Native)>( + symbol: 'my_fstat') +external int fstat( + int fd, + ffi.Pointer buf, +); + +/// +final class dirent extends ffi.Struct { + @ffi.Int64() + external int d_ino; + + @ffi.Array.multi([512]) + external ffi.Array d_name; +} + +final class DIR extends ffi.Struct { + external dirent my_dirent; + + external ffi.Pointer _dir; +} + +/// +final class timespec extends ffi.Struct { + @ffi.Int64() + external int tv_sec; + + @ffi.Int64() + external int tv_nsec; +} + +final class Stat extends ffi.Struct { + @ffi.Int64() + external int st_dev; + + @ffi.Int64() + external int st_ino; + + @ffi.Int64() + external int st_mode; + + @ffi.Int64() + external int st_nlink; + + @ffi.Int64() + external int std_uid; + + external timespec st_atim; + + external timespec st_mtim; + + external timespec st_ctim; + + /// Only valid on macOS/iOS + external timespec st_btime; + + /// Only valid on macOS/iOS + @ffi.Int64() + external int st_flags; +} diff --git a/pkgs/hooks/example/build/native_add_library/pubspec.yaml b/pkgs/hooks/example/build/native_add_library/pubspec.yaml index 7285f8ea2e..0632ff1bb8 100644 --- a/pkgs/hooks/example/build/native_add_library/pubspec.yaml +++ b/pkgs/hooks/example/build/native_add_library/pubspec.yaml @@ -12,6 +12,7 @@ environment: dependencies: code_assets: ^0.19.0 + ffi: ^2.1.4 hooks: ^0.19.0 logging: ^1.3.0 native_toolchain_c: ^0.16.1-wip diff --git a/pkgs/hooks/example/build/native_add_library/src/constants.g.c b/pkgs/hooks/example/build/native_add_library/src/constants.g.c new file mode 100644 index 0000000000..266c19868a --- /dev/null +++ b/pkgs/hooks/example/build/native_add_library/src/constants.g.c @@ -0,0 +1,185 @@ +#include + +#include "constants.g.h" + + +int64_t my_get_S_IEXEC(void) { +#ifdef S_IEXEC + return S_IEXEC; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IFBLK(void) { +#ifdef S_IFBLK + return S_IFBLK; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IFCHR(void) { +#ifdef S_IFCHR + return S_IFCHR; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IFDIR(void) { +#ifdef S_IFDIR + return S_IFDIR; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IFIFO(void) { +#ifdef S_IFIFO + return S_IFIFO; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IFLNK(void) { +#ifdef S_IFLNK + return S_IFLNK; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IFMT(void) { +#ifdef S_IFMT + return S_IFMT; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IFREG(void) { +#ifdef S_IFREG + return S_IFREG; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IFSOCK(void) { +#ifdef S_IFSOCK + return S_IFSOCK; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IFWHT(void) { +#ifdef S_IFWHT + return S_IFWHT; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IREAD(void) { +#ifdef S_IREAD + return S_IREAD; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IRGRP(void) { +#ifdef S_IRGRP + return S_IRGRP; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IROTH(void) { +#ifdef S_IROTH + return S_IROTH; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IRUSR(void) { +#ifdef S_IRUSR + return S_IRUSR; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IRWXG(void) { +#ifdef S_IRWXG + return S_IRWXG; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IRWXO(void) { +#ifdef S_IRWXO + return S_IRWXO; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IRWXU(void) { +#ifdef S_IRWXU + return S_IRWXU; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_ISGID(void) { +#ifdef S_ISGID + return S_ISGID; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_ISTXT(void) { +#ifdef S_ISTXT + return S_ISTXT; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_ISUID(void) { +#ifdef S_ISUID + return S_ISUID; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_ISVTX(void) { +#ifdef S_ISVTX + return S_ISVTX; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IWGRP(void) { +#ifdef S_IWGRP + return S_IWGRP; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IWOTH(void) { +#ifdef S_IWOTH + return S_IWOTH; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IWRITE(void) { +#ifdef S_IWRITE + return S_IWRITE; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IWUSR(void) { +#ifdef S_IWUSR + return S_IWUSR; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IXGRP(void) { +#ifdef S_IXGRP + return S_IXGRP; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IXOTH(void) { +#ifdef S_IXOTH + return S_IXOTH; +#endif + return my_UNDEFINED; +} +int64_t my_get_S_IXUSR(void) { +#ifdef S_IXUSR + return S_IXUSR; +#endif + return my_UNDEFINED; +} +int64_t my_get_UF_APPEND(void) { +#ifdef UF_APPEND + return UF_APPEND; +#endif + return my_UNDEFINED; +} +int64_t my_get_UF_HIDDEN(void) { +#ifdef UF_HIDDEN + return UF_HIDDEN; +#endif + return my_UNDEFINED; +} diff --git a/pkgs/hooks/example/build/native_add_library/src/constants.g.h b/pkgs/hooks/example/build/native_add_library/src/constants.g.h new file mode 100644 index 0000000000..7413e9e029 --- /dev/null +++ b/pkgs/hooks/example/build/native_add_library/src/constants.g.h @@ -0,0 +1,33 @@ +#include + +#define my_UNDEFINED 9223372036854775807; +int64_t my_get_S_IEXEC(void); +int64_t my_get_S_IFBLK(void); +int64_t my_get_S_IFCHR(void); +int64_t my_get_S_IFDIR(void); +int64_t my_get_S_IFIFO(void); +int64_t my_get_S_IFLNK(void); +int64_t my_get_S_IFMT(void); +int64_t my_get_S_IFREG(void); +int64_t my_get_S_IFSOCK(void); +int64_t my_get_S_IFWHT(void); +int64_t my_get_S_IREAD(void); +int64_t my_get_S_IRGRP(void); +int64_t my_get_S_IROTH(void); +int64_t my_get_S_IRUSR(void); +int64_t my_get_S_IRWXG(void); +int64_t my_get_S_IRWXO(void); +int64_t my_get_S_IRWXU(void); +int64_t my_get_S_ISGID(void); +int64_t my_get_S_ISTXT(void); +int64_t my_get_S_ISUID(void); +int64_t my_get_S_ISVTX(void); +int64_t my_get_S_IWGRP(void); +int64_t my_get_S_IWOTH(void); +int64_t my_get_S_IWRITE(void); +int64_t my_get_S_IWUSR(void); +int64_t my_get_S_IXGRP(void); +int64_t my_get_S_IXOTH(void); +int64_t my_get_S_IXUSR(void); +int64_t my_get_UF_APPEND(void); +int64_t my_get_UF_HIDDEN(void); diff --git a/pkgs/hooks/example/build/native_add_library/src/native_add_library.c b/pkgs/hooks/example/build/native_add_library/src/native_add_library.c index cf68dd3ffd..5b9f6187f1 100644 --- a/pkgs/hooks/example/build/native_add_library/src/native_add_library.c +++ b/pkgs/hooks/example/build/native_add_library/src/native_add_library.c @@ -4,13 +4,128 @@ #include "native_add_library.h" +#include +#include +#include +#include +#include +#include +#include +#include + #ifdef DEBUG #include #endif -int32_t add(int32_t a, int32_t b) { -#ifdef DEBUG - printf("Adding %i and %i.\n", a, b); +int64_t my_open(const char *pathname, int64_t flags, int64_t mode) { + return open(pathname, flags, mode); +} + +int my_rename(const char *old, const char *new) { return rename(old, new); } + +int64_t my_close(int64_t fd) { return close(fd); } + +int64_t my_unlinkat(int64_t dirfd, const char *pathname, int64_t flags) { + return unlinkat(dirfd, pathname, flags); +} + +void my_seterrno(int64_t err) { errno = err; } + +int64_t my_errno(void) { return errno; } + +char *my_getenv(const char *name) { return getenv(name); } + +char *my_mkdtemp(char *template) { return mkdtemp(template); } + +int64_t my_closedir(my_DIR *d) { + int r = closedir(d->_dir); + free(d); + return r; +} + +my_DIR *my_opendir(const char *path) { + my_DIR *myd = malloc(sizeof(my_DIR)); + + DIR *d = opendir(path); + if (d == NULL) { + return NULL; + } + myd->_dir = d; + return myd; +} + +struct my_dirent *my_readdir(my_DIR *myd) { + struct dirent *d = readdir(myd->_dir); + if (d == NULL) { + return NULL; + } + + myd->my_dirent.d_ino = d->d_ino; + strncpy(myd->my_dirent.d_name, d->d_name, sizeof(myd->my_dirent.d_name)); + return &(myd->my_dirent); +} + +static void _fill(struct my_Stat *buf, struct stat *s) { + buf->st_dev = s->st_dev; + buf->st_ino = s->st_ino; + buf->st_mode = s->st_mode; + buf->st_nlink = s->st_nlink; + buf->std_uid = s->st_uid; +#ifdef __APPLE__ + buf->st_atim.tv_sec = s->st_atimespec.tv_sec; + buf->st_atim.tv_nsec = s->st_atimespec.tv_nsec; + + buf->st_ctim.tv_sec = s->st_ctimespec.tv_sec; + buf->st_ctim.tv_nsec = s->st_ctimespec.tv_nsec; + + buf->st_mtim.tv_sec = s->st_mtimespec.tv_sec; + buf->st_mtim.tv_nsec = s->st_mtimespec.tv_nsec; + + buf->st_btime.tv_sec = s->st_birthtimespec.tv_sec; + buf->st_btime.tv_nsec = s->st_birthtimespec.tv_nsec; + + buf->st_flags = s->st_flags; +#elif + // https://man7.org/linux/man-pages/man3/stat.3type.html + + buf->st_atim.tv_sec = s->st_atim.tv_sec; + buf->st_atim.tv_nsec = s->st_atim.tv_nsec; + + buf->st_ctim.tv_sec = s->st_ctim.tv_sec; + buf->st_ctim.tv_nsec = s->st_ctim.tv_nsec; + + buf->st_mtim.tv_sec = s->st_mtim.tv_sec; + buf->st_mtim.tv_nsec = s->st_mtim.tv_nsec; #endif - return a + b; +} + +int64_t my_mkdir(const char *pathname, int64_t mode) { + return mkdir(pathname, mode); +} + +int64_t my_stat(const char *path, struct my_Stat *buf) { + struct stat s; + int r = stat(path, &s); + if (r != -1) { + _fill(buf, &s); + } + return r; +} + +int64_t my_lstat(const char *path, struct my_Stat *buf) { + struct stat s; + int r = lstat(path, &s); + if (r != -1) { + _fill(buf, &s); + } + return r; +} + +int64_t my_fstat(int64_t fd, struct my_Stat *buf) { + struct stat s; + int r = fstat(fd, &s); + if (r != -1) { + _fill(buf, &s); + } + return r; } diff --git a/pkgs/hooks/example/build/native_add_library/src/native_add_library.h b/pkgs/hooks/example/build/native_add_library/src/native_add_library.h index 5824f98a7d..dd34ce857d 100644 --- a/pkgs/hooks/example/build/native_add_library/src/native_add_library.h +++ b/pkgs/hooks/example/build/native_add_library/src/native_add_library.h @@ -10,4 +10,66 @@ #define MYLIB_EXPORT #endif -MYLIB_EXPORT int32_t add(int32_t a, int32_t b); +// +MYLIB_EXPORT int64_t my_open(const char *pathname, int64_t flags, int64_t mode); + +// +MYLIB_EXPORT int my_rename(const char *old, const char *new); + +// + +MYLIB_EXPORT int64_t my_close(int64_t fd); +MYLIB_EXPORT int64_t my_unlinkat(int64_t dirfd, const char *pathname, + int64_t flags); + +// +MYLIB_EXPORT void my_seterrno(int64_t err); +MYLIB_EXPORT int64_t my_errno(void); + +// +MYLIB_EXPORT char *my_getenv(const char *name); +MYLIB_EXPORT char *my_mkdtemp(char *template); + +// + +struct my_dirent { + int64_t d_ino; + char d_name[512]; +}; + +typedef struct { + struct my_dirent my_dirent; + void *_dir; +} my_DIR; + +MYLIB_EXPORT int64_t my_closedir(my_DIR *d); +MYLIB_EXPORT my_DIR *my_opendir(const char *path); +MYLIB_EXPORT struct my_dirent *my_readdir(my_DIR *d); + +// +struct my_timespec { + int64_t tv_sec; + int64_t tv_nsec; +}; + +struct my_Stat { + int64_t st_dev; + int64_t st_ino; + int64_t st_mode; + int64_t st_nlink; + int64_t std_uid; + + struct my_timespec st_atim; + struct my_timespec st_mtim; + struct my_timespec st_ctim; + // Only valid on macOS/iOS + struct my_timespec st_btime; + + // Only valid on macOS/iOS + int64_t st_flags; +}; + +MYLIB_EXPORT int64_t my_mkdir(const char *pathname, int64_t mode); +MYLIB_EXPORT int64_t my_stat(const char *path, struct my_Stat *buf); +MYLIB_EXPORT int64_t my_lstat(const char *path, struct my_Stat *buf); +MYLIB_EXPORT int64_t my_fstat(int64_t fd, struct my_Stat *buf); diff --git a/pkgs/hooks/example/build/native_add_library/test/native_add_library_test.dart b/pkgs/hooks/example/build/native_add_library/test/native_add_library_test.dart index 692446e2e5..c7bb825931 100644 --- a/pkgs/hooks/example/build/native_add_library/test/native_add_library_test.dart +++ b/pkgs/hooks/example/build/native_add_library/test/native_add_library_test.dart @@ -2,11 +2,60 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'dart:ffi'; + +import 'package:ffi/ffi.dart'; import 'package:native_add_library/native_add_library.dart'; import 'package:test/test.dart'; +// Symbols currently in use by io_file: +// errno +// close +// open +// getenv +// fstat +// rename +// unlinkat +// mkdtemp +// mkdir +// stat +// strerror +// error constants +// + 5 or 6 constants void main() { - test('invoke native function', () { - expect(add(24, 18), 42); - }); + test( + 'invoke native function', + () => using((arena) { + final fd = open('foobarbaz'.toNativeUtf8(allocator: arena).cast(), 0, 0); + print('fd: $fd'); + print('errno: $errno'); + + final s = arena(); + final r = stat('/'.toNativeUtf8(allocator: arena).cast(), s); + print(r); + print(s.ref.st_dev); + print(s.ref.st_ino); + print(s.ref.st_mode); + print(s.ref.st_btime.tv_sec); + + print('UF_HIDDEN: $UF_HIDDEN'); + print('S_IFMT: $S_IFMT'); + + final d = opendir('/'.toNativeUtf8(allocator: arena).cast()); + if (d == nullptr) { + print('open failed'); + } + final h = readdir(d); + final b = StringBuffer(); + for (var i = 0; ; i++) { + if (h.ref.d_name[i] == 0) { + print(b); + break; + } else { + b.writeCharCode(h.ref.d_name[i]); + } + } + closedir(d); + }), + ); } diff --git a/pkgs/hooks/example/build/native_add_library/tool/build_constants.dart b/pkgs/hooks/example/build/native_add_library/tool/build_constants.dart new file mode 100644 index 0000000000..021e1da03b --- /dev/null +++ b/pkgs/hooks/example/build/native_add_library/tool/build_constants.dart @@ -0,0 +1,71 @@ +import 'dart:convert'; +import 'dart:io'; + +const _cSourceTemplate = ''' +#include + +#include "constants.g.h" + + +'''; + +const _cHeaderTemplate = ''' +#include + +#define my_UNDEFINED 9223372036854775807; +'''; + +const _dartTemplate = ''' +// ignore_for_file: non_constant_identifier_names + +import 'constant_bindings.dart'; +'''; + +void addConstantToCSource(String constant, StringBuffer b) { + b.write(''' +int64_t my_get_$constant(void) { +#ifdef $constant + return $constant; +#endif + return my_UNDEFINED; +} +'''); +} + +void addConstantToCHeader(String constant, StringBuffer b) { + b.write(''' +int64_t my_get_$constant(void); +'''); +} + +void addConstantToDart(String constant, StringBuffer b) { + b.writeln(''' +int get $constant { + final v = get_$constant(); + if (v == my_UNDEFINED) { + throw UnsupportedError('$constant'); + } else { + return v; + } +} +'''); +} + +void main() { + final constants = + (json.decode(File('constants.json').readAsStringSync()) as List) + .cast(); + + final cSourceBuffer = StringBuffer(_cSourceTemplate); + final cHeaderBuffer = StringBuffer(_cHeaderTemplate); + final dartBuffer = StringBuffer(_dartTemplate); + + for (final constant in constants) { + addConstantToCHeader(constant, cHeaderBuffer); + addConstantToCSource(constant, cSourceBuffer); + addConstantToDart(constant, dartBuffer); + } + File('lib/src/constants.g.dart').writeAsStringSync(dartBuffer.toString()); + File('src/constants.g.c').writeAsStringSync(cSourceBuffer.toString()); + File('src/constants.g.h').writeAsStringSync(cHeaderBuffer.toString()); +}