kanayago 0.2.0 → 0.3.0

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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/Rakefile +5 -48
  4. data/ext/kanayago/extconf.rb +8 -0
  5. data/lib/kanayago/version.rb +1 -1
  6. data/script/setup_parser.rb +136 -0
  7. metadata +2 -64
  8. data/ext/kanayago/ccan/check_type/check_type.h +0 -63
  9. data/ext/kanayago/ccan/container_of/container_of.h +0 -142
  10. data/ext/kanayago/ccan/list/list.h +0 -791
  11. data/ext/kanayago/ccan/str/str.h +0 -17
  12. data/ext/kanayago/constant.h +0 -53
  13. data/ext/kanayago/id.h +0 -354
  14. data/ext/kanayago/id_table.h +0 -54
  15. data/ext/kanayago/include/ruby/st.h +0 -199
  16. data/ext/kanayago/internal/array.h +0 -154
  17. data/ext/kanayago/internal/basic_operators.h +0 -65
  18. data/ext/kanayago/internal/bignum.h +0 -245
  19. data/ext/kanayago/internal/bits.h +0 -650
  20. data/ext/kanayago/internal/compile.h +0 -34
  21. data/ext/kanayago/internal/compilers.h +0 -107
  22. data/ext/kanayago/internal/complex.h +0 -29
  23. data/ext/kanayago/internal/encoding.h +0 -39
  24. data/ext/kanayago/internal/error.h +0 -251
  25. data/ext/kanayago/internal/fixnum.h +0 -185
  26. data/ext/kanayago/internal/gc.h +0 -358
  27. data/ext/kanayago/internal/hash.h +0 -194
  28. data/ext/kanayago/internal/imemo.h +0 -322
  29. data/ext/kanayago/internal/io.h +0 -163
  30. data/ext/kanayago/internal/namespace.h +0 -81
  31. data/ext/kanayago/internal/numeric.h +0 -275
  32. data/ext/kanayago/internal/parse.h +0 -131
  33. data/ext/kanayago/internal/rational.h +0 -71
  34. data/ext/kanayago/internal/re.h +0 -33
  35. data/ext/kanayago/internal/ruby_parser.h +0 -125
  36. data/ext/kanayago/internal/sanitizers.h +0 -346
  37. data/ext/kanayago/internal/serial.h +0 -23
  38. data/ext/kanayago/internal/set_table.h +0 -70
  39. data/ext/kanayago/internal/static_assert.h +0 -16
  40. data/ext/kanayago/internal/string.h +0 -203
  41. data/ext/kanayago/internal/symbol.h +0 -46
  42. data/ext/kanayago/internal/thread.h +0 -112
  43. data/ext/kanayago/internal/variable.h +0 -74
  44. data/ext/kanayago/internal/vm.h +0 -136
  45. data/ext/kanayago/internal/warnings.h +0 -16
  46. data/ext/kanayago/internal.h +0 -105
  47. data/ext/kanayago/lex.c +0 -302
  48. data/ext/kanayago/method.h +0 -271
  49. data/ext/kanayago/node.c +0 -446
  50. data/ext/kanayago/node.h +0 -122
  51. data/ext/kanayago/node_name.inc +0 -224
  52. data/ext/kanayago/parse.c +0 -27377
  53. data/ext/kanayago/parse.h +0 -244
  54. data/ext/kanayago/parser_bits.h +0 -564
  55. data/ext/kanayago/parser_node.h +0 -32
  56. data/ext/kanayago/parser_st.c +0 -165
  57. data/ext/kanayago/parser_st.h +0 -162
  58. data/ext/kanayago/parser_value.h +0 -106
  59. data/ext/kanayago/probes.h +0 -4
  60. data/ext/kanayago/ruby_assert.h +0 -14
  61. data/ext/kanayago/ruby_atomic.h +0 -66
  62. data/ext/kanayago/ruby_parser.c +0 -1137
  63. data/ext/kanayago/rubyparser.h +0 -1394
  64. data/ext/kanayago/shape.h +0 -444
  65. data/ext/kanayago/st.c +0 -3223
  66. data/ext/kanayago/symbol.h +0 -116
  67. data/ext/kanayago/thread_pthread.h +0 -175
  68. data/ext/kanayago/universal_parser.c +0 -211
  69. data/ext/kanayago/vm_core.h +0 -2349
  70. data/ext/kanayago/vm_opts.h +0 -67
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6b8dcde5a49288a284edf3323cc0279740a923e0ea85d895571dcfa1be774970
4
- data.tar.gz: 5c7bf5ef11155f14e6b8f2049bd344228c10089cb430b4d4c453a7b02e94bdb5
3
+ metadata.gz: 5a3eb2ad59c4bf7537be2abff7da6f0b93e79173d8fa6ae51dee86a8966ee83b
4
+ data.tar.gz: c2c4608ccf7ef25054abd327702f6fbd1713c31769bb78062290d8248bce9b0f
5
5
  SHA512:
6
- metadata.gz: ce3d04f88db918e619f94195b2ca33cae122466b502a56df3e399acfadc7e4ed193ff045b0d12e326ff2fbeb4435587ce75507a02c7a1185c4f3a0290f7d3935
7
- data.tar.gz: 0a3981c9eae87d6fd12ff320a3f3d8759c78830b2936569c604e7c1c82ca614f2ba07c2d1e97b2c765c81ed4eb0b7e63424af75e8342320c8bc0134fb69aa3b5
6
+ metadata.gz: 16dd25fc0a69b15b85010abd4bb4784d2559cd7a5a0024bd4b60814fa2b376249d222a1c16cd16c049db31cbe855fb12eb5571e3af872e9d83d36a08e9fdd6f8
7
+ data.tar.gz: 07b9d5a878182eedb53d637dd6f4a02d8b53fdd8b0f7a6786ce045d3269abc52843c9792efcd9f482d1f7ebf4e7fa7e051548b998f48f81703799b975bf85fd1
data/README.md CHANGED
@@ -31,7 +31,7 @@ Finally, build `Kanayago` gem and install it.
31
31
 
32
32
  ```console
33
33
  bundle exec rake build
34
- gem install pkg/kanayago-0.2.0.gem
34
+ gem install pkg/kanayago-0.3.0.gem
35
35
  ```
36
36
 
37
37
  ## Usage
data/Rakefile CHANGED
@@ -14,52 +14,9 @@ else
14
14
  end
15
15
 
16
16
  namespace :ruby_parser do
17
- desc 'import ruby parser files'
18
- task :import do
19
- tar_name = if RUBY_DESCRIPTION.include?('dev')
20
- 'snapshot/snapshot-master.tar.gz'
21
- else
22
- "#{RUBY_VERSION[0..2]}/ruby-#{RUBY_VERSION}.tar.gz"
23
- end
24
-
25
- `mkdir -p tmp/ruby`
26
- `curl -L https://cache.ruby-lang.org/pub/ruby/#{tar_name} -o tmp/ruby.tar.gz`
27
- `tar -zxvf tmp/ruby.tar.gz -C tmp/ruby --strip-components 1`
28
-
29
- dist = File.expand_path('ext/kanayago', __dir__)
30
- ruby_dir = File.expand_path('tmp/ruby', __dir__)
31
-
32
- MAKE_DIRECTORIES.each do |dir|
33
- Dir.mkdir File.join(dist, dir) unless Dir.exist? dir
34
- end
35
-
36
- RUBY_PARSER_COPY_TARGETS.each do |target|
37
- FileUtils.cp File.join(ruby_dir, target), File.join(dist, target)
38
- end
39
-
40
- # "probes.h"
41
- probes_h_path = File.join(dist, 'probes.h')
42
- File.open(probes_h_path, 'w+') do |f|
43
- f << <<~SRC
44
- #define RUBY_DTRACE_PARSE_BEGIN_ENABLED() (0)
45
- #define RUBY_DTRACE_PARSE_BEGIN(arg0, arg1) (void)(arg0), (void)(arg1);
46
- #define RUBY_DTRACE_PARSE_END_ENABLED() (0)
47
- #define RUBY_DTRACE_PARSE_END(arg0, arg1) (void)(arg0), (void)(arg1);
48
- SRC
49
- end
50
-
51
- `rm -rf tmp/ruby tmp/ruby.tar.gz`
52
- end
53
-
54
- desc 'patched ro ruby parse that build for Kanayago'
55
- task :patch do
56
- running_ruby_version = if RUBY_DESCRIPTION.include?('dev')
57
- 'head'
58
- else
59
- RUBY_VERSION[..2]
60
- end
61
-
62
- sh "patch -p1 < patch/#{running_ruby_version}/kanayago.patch"
17
+ desc 'import ruby parser files and apply patch'
18
+ task :setup do
19
+ sh 'ruby script/setup_parser.rb'
63
20
  end
64
21
 
65
22
  desc 'clean to ruby parser file'
@@ -82,8 +39,8 @@ namespace :ruby_parser do
82
39
  end
83
40
  end
84
41
 
85
- task build: ['ruby_parser:import', 'ruby_parser:patch', 'compile']
86
- task install: ['ruby_parser:import', 'ruby_parser:patch', 'compile']
42
+ task :build # rubocop:disable Rake/Desc
43
+ task install: ['ruby_parser:clean', 'ruby_parser:setup', 'compile']
87
44
 
88
45
  GEMSPEC = Gem::Specification.load('kanayago.gemspec')
89
46
 
@@ -2,6 +2,14 @@
2
2
 
3
3
  require 'mkmf'
4
4
 
5
+ # Run setup script to prepare Ruby parser files before building
6
+ setup_script = File.expand_path('../../script/setup_parser.rb', __dir__)
7
+ puts 'Running parser setup script...'
8
+ unless system("ruby #{setup_script}")
9
+ warn 'Failed to setup parser files. Please check the error messages above.'
10
+ exit 1
11
+ end
12
+
5
13
  $objs = %w[
6
14
  node
7
15
  parse
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kanayago
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.0'
5
5
  end
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'fileutils'
5
+
6
+ # Ruby parser setup script for Kanayago
7
+ # This script downloads Ruby source code and prepares parser files for building
8
+ module KanayagoSetup
9
+ class << self
10
+ def run
11
+ puts 'Setting up Ruby parser files for Kanayago...'
12
+
13
+ # Determine Ruby version
14
+ ruby_version = detect_ruby_version
15
+ puts "Detected Ruby version: #{ruby_version}"
16
+
17
+ # Load copy targets for this Ruby version
18
+ load_copy_targets(ruby_version)
19
+
20
+ # Import parser files
21
+ import_parser_files(ruby_version)
22
+
23
+ # Apply patch
24
+ apply_patch(ruby_version)
25
+
26
+ puts 'Setup completed successfully!'
27
+ rescue StandardError => e
28
+ warn "Error during setup: #{e.message}"
29
+ warn e.backtrace.join("\n")
30
+ exit 1
31
+ end
32
+
33
+ private
34
+
35
+ def detect_ruby_version
36
+ if RUBY_DESCRIPTION.include?('dev')
37
+ 'head'
38
+ else
39
+ RUBY_VERSION[0..2]
40
+ end
41
+ end
42
+
43
+ def load_copy_targets(version)
44
+ copy_target_path = File.expand_path("../patch/#{version}/copy_target.rb", __dir__)
45
+
46
+ raise "Copy target file not found: #{copy_target_path}" unless File.exist?(copy_target_path)
47
+
48
+ require copy_target_path
49
+ end
50
+
51
+ def import_parser_files(version) # rubocop:disable Metrics/PerceivedComplexity
52
+ puts 'Importing Ruby parser files...'
53
+
54
+ tar_name = if version == 'head'
55
+ 'snapshot/snapshot-master.tar.gz'
56
+ else
57
+ "#{version}/ruby-#{RUBY_VERSION}.tar.gz"
58
+ end
59
+
60
+ # Get project root directory
61
+ project_root = File.expand_path('..', __dir__)
62
+ tmp_dir = File.join(project_root, 'tmp')
63
+ tmp_ruby_dir = File.join(tmp_dir, 'ruby')
64
+ tmp_tar_file = File.join(tmp_dir, 'ruby.tar.gz')
65
+
66
+ # Create temporary directory
67
+ FileUtils.mkdir_p(tmp_ruby_dir)
68
+
69
+ # Download Ruby source
70
+ puts 'Downloading Ruby source from cache.ruby-lang.org...'
71
+ system("curl -L https://cache.ruby-lang.org/pub/ruby/#{tar_name} -o #{tmp_tar_file}") ||
72
+ raise('Failed to download Ruby source')
73
+
74
+ # Extract
75
+ puts 'Extracting Ruby source...'
76
+ system("tar -zxf #{tmp_tar_file} -C #{tmp_ruby_dir} --strip-components 1") ||
77
+ raise('Failed to extract Ruby source')
78
+
79
+ dist = File.join(project_root, 'ext', 'kanayago')
80
+
81
+ # Create necessary directories
82
+ MAKE_DIRECTORIES.each do |dir|
83
+ dir_path = File.join(dist, dir)
84
+ FileUtils.mkdir_p(dir_path)
85
+ end
86
+
87
+ # Copy files
88
+ puts 'Copying parser files...'
89
+ RUBY_PARSER_COPY_TARGETS.each do |target|
90
+ src = File.join(tmp_ruby_dir, target)
91
+ dst = File.join(dist, target)
92
+
93
+ if File.exist?(src)
94
+ FileUtils.cp(src, dst)
95
+ else
96
+ warn "Warning: Source file not found: #{src}"
97
+ end
98
+ end
99
+
100
+ # Generate probes.h
101
+ puts 'Generating probes.h...'
102
+ probes_h_path = File.join(dist, 'probes.h')
103
+ File.open(probes_h_path, 'w+') do |f|
104
+ f << <<~SRC
105
+ #define RUBY_DTRACE_PARSE_BEGIN_ENABLED() (0)
106
+ #define RUBY_DTRACE_PARSE_BEGIN(arg0, arg1) (void)(arg0), (void)(arg1);
107
+ #define RUBY_DTRACE_PARSE_END_ENABLED() (0)
108
+ #define RUBY_DTRACE_PARSE_END(arg0, arg1) (void)(arg0), (void)(arg1);
109
+ SRC
110
+ end
111
+
112
+ # Cleanup
113
+ puts 'Cleaning up temporary files...'
114
+ FileUtils.rm_rf(tmp_ruby_dir)
115
+ FileUtils.rm_f(tmp_tar_file)
116
+ end
117
+
118
+ def apply_patch(version)
119
+ puts "Applying patch for Ruby #{version}..."
120
+
121
+ patch_file = File.expand_path("../patch/#{version}/kanayago.patch", __dir__)
122
+
123
+ raise "Patch file not found: #{patch_file}" unless File.exist?(patch_file)
124
+
125
+ # Change to project root directory before applying patch
126
+ project_root = File.expand_path('..', __dir__)
127
+ Dir.chdir(project_root) do
128
+ system("patch -p1 < #{patch_file}") ||
129
+ raise('Failed to apply patch')
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ # Run setup if this script is executed directly
136
+ KanayagoSetup.run if __FILE__ == $PROGRAM_NAME
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kanayago
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - S-H-GAMELINKS
@@ -23,84 +23,21 @@ files:
23
23
  - LICENSE.txt
24
24
  - README.md
25
25
  - Rakefile
26
- - ext/kanayago/ccan/check_type/check_type.h
27
- - ext/kanayago/ccan/container_of/container_of.h
28
- - ext/kanayago/ccan/list/list.h
29
- - ext/kanayago/ccan/str/str.h
30
- - ext/kanayago/constant.h
31
26
  - ext/kanayago/extconf.rb
32
- - ext/kanayago/id.h
33
- - ext/kanayago/id_table.h
34
- - ext/kanayago/include/ruby/st.h
35
- - ext/kanayago/internal.h
36
- - ext/kanayago/internal/array.h
37
- - ext/kanayago/internal/basic_operators.h
38
- - ext/kanayago/internal/bignum.h
39
- - ext/kanayago/internal/bits.h
40
- - ext/kanayago/internal/compile.h
41
- - ext/kanayago/internal/compilers.h
42
- - ext/kanayago/internal/complex.h
43
- - ext/kanayago/internal/encoding.h
44
- - ext/kanayago/internal/error.h
45
- - ext/kanayago/internal/fixnum.h
46
- - ext/kanayago/internal/gc.h
47
- - ext/kanayago/internal/hash.h
48
- - ext/kanayago/internal/imemo.h
49
- - ext/kanayago/internal/io.h
50
- - ext/kanayago/internal/namespace.h
51
- - ext/kanayago/internal/numeric.h
52
- - ext/kanayago/internal/parse.h
53
- - ext/kanayago/internal/rational.h
54
- - ext/kanayago/internal/re.h
55
- - ext/kanayago/internal/ruby_parser.h
56
- - ext/kanayago/internal/sanitizers.h
57
- - ext/kanayago/internal/serial.h
58
- - ext/kanayago/internal/set_table.h
59
- - ext/kanayago/internal/static_assert.h
60
- - ext/kanayago/internal/string.h
61
- - ext/kanayago/internal/symbol.h
62
- - ext/kanayago/internal/thread.h
63
- - ext/kanayago/internal/variable.h
64
- - ext/kanayago/internal/vm.h
65
- - ext/kanayago/internal/warnings.h
66
27
  - ext/kanayago/kanayago.c
67
28
  - ext/kanayago/kanayago.h
68
- - ext/kanayago/lex.c
69
29
  - ext/kanayago/literal_node.c
70
30
  - ext/kanayago/literal_node.h
71
- - ext/kanayago/method.h
72
- - ext/kanayago/node.c
73
- - ext/kanayago/node.h
74
- - ext/kanayago/node_name.inc
75
- - ext/kanayago/parse.c
76
- - ext/kanayago/parse.h
77
- - ext/kanayago/parser_bits.h
78
- - ext/kanayago/parser_node.h
79
- - ext/kanayago/parser_st.c
80
- - ext/kanayago/parser_st.h
81
- - ext/kanayago/parser_value.h
82
31
  - ext/kanayago/pattern_node.c
83
32
  - ext/kanayago/pattern_node.h
84
- - ext/kanayago/probes.h
85
- - ext/kanayago/ruby_assert.h
86
- - ext/kanayago/ruby_atomic.h
87
- - ext/kanayago/ruby_parser.c
88
- - ext/kanayago/rubyparser.h
89
33
  - ext/kanayago/scope_node.c
90
34
  - ext/kanayago/scope_node.h
91
- - ext/kanayago/shape.h
92
- - ext/kanayago/st.c
93
35
  - ext/kanayago/statement_node.c
94
36
  - ext/kanayago/statement_node.h
95
37
  - ext/kanayago/string_node.c
96
38
  - ext/kanayago/string_node.h
97
- - ext/kanayago/symbol.h
98
- - ext/kanayago/thread_pthread.h
99
- - ext/kanayago/universal_parser.c
100
39
  - ext/kanayago/variable_node.c
101
40
  - ext/kanayago/variable_node.h
102
- - ext/kanayago/vm_core.h
103
- - ext/kanayago/vm_opts.h
104
41
  - lib/kanayago.rb
105
42
  - lib/kanayago/literal_node.rb
106
43
  - lib/kanayago/pattern_node.rb
@@ -114,6 +51,7 @@ files:
114
51
  - patch/head/kanayago.patch
115
52
  - sample/minitest_generator.rb
116
53
  - sample/test_generator.rb
54
+ - script/setup_parser.rb
117
55
  - sig/kanayago.rbs
118
56
  - typeprof.conf.json
119
57
  homepage: https://github.com/S-H-GAMELINKS/kanayago
@@ -1,63 +0,0 @@
1
- /* CC0 (Public domain) - see ccan/licenses/CC0 file for details */
2
- #ifndef CCAN_CHECK_TYPE_H
3
- #define CCAN_CHECK_TYPE_H
4
-
5
- /**
6
- * ccan_check_type - issue a warning or build failure if type is not correct.
7
- * @expr: the expression whose type we should check (not evaluated).
8
- * @type: the exact type we expect the expression to be.
9
- *
10
- * This macro is usually used within other macros to try to ensure that a macro
11
- * argument is of the expected type. No type promotion of the expression is
12
- * done: an unsigned int is not the same as an int!
13
- *
14
- * ccan_check_type() always evaluates to 0.
15
- *
16
- * If your compiler does not support typeof, then the best we can do is fail
17
- * to compile if the sizes of the types are unequal (a less complete check).
18
- *
19
- * Example:
20
- * // They should always pass a 64-bit value to _set_some_value!
21
- * #define set_some_value(expr) \
22
- * _set_some_value((ccan_check_type((expr), uint64_t), (expr)))
23
- */
24
-
25
- /**
26
- * ccan_check_types_match - issue a warning or build failure if types are not same.
27
- * @expr1: the first expression (not evaluated).
28
- * @expr2: the second expression (not evaluated).
29
- *
30
- * This macro is usually used within other macros to try to ensure that
31
- * arguments are of identical types. No type promotion of the expressions is
32
- * done: an unsigned int is not the same as an int!
33
- *
34
- * ccan_check_types_match() always evaluates to 0.
35
- *
36
- * If your compiler does not support typeof, then the best we can do is fail
37
- * to compile if the sizes of the types are unequal (a less complete check).
38
- *
39
- * Example:
40
- * // Do subtraction to get to enclosing type, but make sure that
41
- * // pointer is of correct type for that member.
42
- * #define ccan_container_of(mbr_ptr, encl_type, mbr) \
43
- * (ccan_check_types_match((mbr_ptr), &((encl_type *)0)->mbr), \
44
- * ((encl_type *) \
45
- * ((char *)(mbr_ptr) - offsetof(enclosing_type, mbr))))
46
- */
47
- #if defined(HAVE_TYPEOF) && HAVE_TYPEOF
48
- #define ccan_check_type(expr, type) \
49
- ((typeof(expr) *)0 != (type *)0)
50
-
51
- #define ccan_check_types_match(expr1, expr2) \
52
- ((typeof(expr1) *)0 != (typeof(expr2) *)0)
53
- #else
54
- #include "ccan/build_assert/build_assert.h"
55
- /* Without typeof, we can only test the sizes. */
56
- #define ccan_check_type(expr, type) \
57
- CCAN_BUILD_ASSERT_OR_ZERO(sizeof(expr) == sizeof(type))
58
-
59
- #define ccan_check_types_match(expr1, expr2) \
60
- CCAN_BUILD_ASSERT_OR_ZERO(sizeof(expr1) == sizeof(expr2))
61
- #endif /* HAVE_TYPEOF */
62
-
63
- #endif /* CCAN_CHECK_TYPE_H */
@@ -1,142 +0,0 @@
1
- /* CC0 (Public domain) - see ccan/licenses/CC0 file for details */
2
- #ifndef CCAN_CONTAINER_OF_H
3
- #define CCAN_CONTAINER_OF_H
4
- #include "ccan/check_type/check_type.h"
5
-
6
- /**
7
- * ccan_container_of - get pointer to enclosing structure
8
- * @member_ptr: pointer to the structure member
9
- * @containing_type: the type this member is within
10
- * @member: the name of this member within the structure.
11
- *
12
- * Given a pointer to a member of a structure, this macro does pointer
13
- * subtraction to return the pointer to the enclosing type.
14
- *
15
- * Example:
16
- * struct foo {
17
- * int fielda, fieldb;
18
- * // ...
19
- * };
20
- * struct info {
21
- * int some_other_field;
22
- * struct foo my_foo;
23
- * };
24
- *
25
- * static struct info *foo_to_info(struct foo *foo)
26
- * {
27
- * return ccan_container_of(foo, struct info, my_foo);
28
- * }
29
- */
30
- #define ccan_container_of(member_ptr, containing_type, member) \
31
- ((containing_type *) \
32
- ((char *)(member_ptr) \
33
- - ccan_container_off(containing_type, member)) \
34
- + ccan_check_types_match(*(member_ptr), ((containing_type *)0)->member))
35
-
36
-
37
- /**
38
- * ccan_container_of_or_null - get pointer to enclosing structure, or NULL
39
- * @member_ptr: pointer to the structure member
40
- * @containing_type: the type this member is within
41
- * @member: the name of this member within the structure.
42
- *
43
- * Given a pointer to a member of a structure, this macro does pointer
44
- * subtraction to return the pointer to the enclosing type, unless it
45
- * is given NULL, in which case it also returns NULL.
46
- *
47
- * Example:
48
- * struct foo {
49
- * int fielda, fieldb;
50
- * // ...
51
- * };
52
- * struct info {
53
- * int some_other_field;
54
- * struct foo my_foo;
55
- * };
56
- *
57
- * static struct info *foo_to_info_allowing_null(struct foo *foo)
58
- * {
59
- * return ccan_container_of_or_null(foo, struct info, my_foo);
60
- * }
61
- */
62
- static inline char *container_of_or_null_(void *member_ptr, size_t offset)
63
- {
64
- return member_ptr ? (char *)member_ptr - offset : NULL;
65
- }
66
- #define ccan_container_of_or_null(member_ptr, containing_type, member) \
67
- ((containing_type *) \
68
- ccan_container_of_or_null_(member_ptr, \
69
- ccan_container_off(containing_type, member)) \
70
- + ccan_check_types_match(*(member_ptr), ((containing_type *)0)->member))
71
-
72
- /**
73
- * ccan_container_off - get offset to enclosing structure
74
- * @containing_type: the type this member is within
75
- * @member: the name of this member within the structure.
76
- *
77
- * Given a pointer to a member of a structure, this macro does
78
- * typechecking and figures out the offset to the enclosing type.
79
- *
80
- * Example:
81
- * struct foo {
82
- * int fielda, fieldb;
83
- * // ...
84
- * };
85
- * struct info {
86
- * int some_other_field;
87
- * struct foo my_foo;
88
- * };
89
- *
90
- * static struct info *foo_to_info(struct foo *foo)
91
- * {
92
- * size_t off = ccan_container_off(struct info, my_foo);
93
- * return (void *)((char *)foo - off);
94
- * }
95
- */
96
- #define ccan_container_off(containing_type, member) \
97
- offsetof(containing_type, member)
98
-
99
- /**
100
- * ccan_container_of_var - get pointer to enclosing structure using a variable
101
- * @member_ptr: pointer to the structure member
102
- * @container_var: a pointer of same type as this member's container
103
- * @member: the name of this member within the structure.
104
- *
105
- * Given a pointer to a member of a structure, this macro does pointer
106
- * subtraction to return the pointer to the enclosing type.
107
- *
108
- * Example:
109
- * static struct info *foo_to_i(struct foo *foo)
110
- * {
111
- * struct info *i = ccan_container_of_var(foo, i, my_foo);
112
- * return i;
113
- * }
114
- */
115
- #if defined(HAVE_TYPEOF) && HAVE_TYPEOF
116
- #define ccan_container_of_var(member_ptr, container_var, member) \
117
- ccan_container_of(member_ptr, typeof(*container_var), member)
118
- #else
119
- #define ccan_container_of_var(member_ptr, container_var, member) \
120
- ((void *)((char *)(member_ptr) - \
121
- ccan_container_off_var(container_var, member)))
122
- #endif
123
-
124
- /**
125
- * ccan_container_off_var - get offset of a field in enclosing structure
126
- * @container_var: a pointer to a container structure
127
- * @member: the name of a member within the structure.
128
- *
129
- * Given (any) pointer to a structure and a its member name, this
130
- * macro does pointer subtraction to return offset of member in a
131
- * structure memory layout.
132
- *
133
- */
134
- #if defined(HAVE_TYPEOF) && HAVE_TYPEOF
135
- #define ccan_container_off_var(var, member) \
136
- ccan_container_off(typeof(*var), member)
137
- #else
138
- #define ccan_container_off_var(var, member) \
139
- ((const char *)&(var)->member - (const char *)(var))
140
- #endif
141
-
142
- #endif /* CCAN_CONTAINER_OF_H */