autoc 1.4 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGES.md +3 -0
- data/README.md +149 -0
- data/cmake/AutoC.cmake +39 -0
- data/lib/autoc/allocators.rb +51 -0
- data/lib/autoc/association.rb +126 -0
- data/lib/autoc/box.rb +311 -0
- data/lib/autoc/cmake.rb +54 -0
- data/lib/autoc/collection.rb +83 -110
- data/lib/autoc/composite.rb +333 -0
- data/lib/autoc/cstring.rb +263 -0
- data/lib/autoc/function.rb +247 -0
- data/lib/autoc/hash_map.rb +328 -0
- data/lib/autoc/hash_set.rb +339 -0
- data/lib/autoc/hashers.rb +102 -0
- data/lib/autoc/list.rb +444 -0
- data/lib/autoc/module.rb +434 -0
- data/lib/autoc/openmp.rb +15 -0
- data/lib/autoc/primitive.rb +27 -0
- data/lib/autoc/ranges.rb +707 -0
- data/lib/autoc/record.rb +247 -0
- data/lib/autoc/scaffold/docs.rb +117 -0
- data/lib/autoc/scaffold/generic_value.rb +86 -0
- data/lib/autoc/scaffold/project.rb +75 -0
- data/lib/autoc/scaffold/test_cstring.rb +113 -0
- data/lib/autoc/scaffold/test_cstring_hash_set.rb +35 -0
- data/lib/autoc/scaffold/test_int_box.rb +22 -0
- data/lib/autoc/scaffold/test_int_hash_set.rb +448 -0
- data/lib/autoc/scaffold/test_int_list.rb +106 -0
- data/lib/autoc/scaffold/test_int_vector.rb +83 -0
- data/lib/autoc/scaffold/test_v2v_hash_map.rb +83 -0
- data/lib/autoc/scaffold/test_value_hash_set.rb +60 -0
- data/lib/autoc/scaffold/test_value_vector.rb +146 -0
- data/{test/test.rb → lib/autoc/scaffold/tests.rb} +179 -158
- data/lib/autoc/scaffold.rb +12 -0
- data/lib/autoc/sequential.rb +99 -0
- data/lib/autoc/set.rb +331 -0
- data/lib/autoc/std.rb +149 -0
- data/lib/autoc/type.rb +93 -531
- data/lib/autoc/vector.rb +290 -0
- data/lib/autoc.rb +4 -35
- metadata +55 -85
- data/.yardopts +0 -4
- data/CHANGES +0 -23
- data/README +0 -28
- data/doc/AutoC/Code.html +0 -523
- data/doc/AutoC/Collection.html +0 -1214
- data/doc/AutoC/HashMap.html +0 -1441
- data/doc/AutoC/HashSet.html +0 -916
- data/doc/AutoC/Iterators/Bidirectional.html +0 -204
- data/doc/AutoC/Iterators/Unidirectional.html +0 -200
- data/doc/AutoC/Iterators.html +0 -126
- data/doc/AutoC/List.html +0 -1039
- data/doc/AutoC/Maps.html +0 -290
- data/doc/AutoC/Module/File.html +0 -415
- data/doc/AutoC/Module/Header.html +0 -437
- data/doc/AutoC/Module/Source.html +0 -707
- data/doc/AutoC/Module.html +0 -948
- data/doc/AutoC/Priority.html +0 -138
- data/doc/AutoC/Queue.html +0 -1172
- data/doc/AutoC/Reference.html +0 -735
- data/doc/AutoC/Sets.html +0 -520
- data/doc/AutoC/String.html +0 -1394
- data/doc/AutoC/TreeMap.html +0 -1565
- data/doc/AutoC/TreeSet.html +0 -1447
- data/doc/AutoC/Type.html +0 -2148
- data/doc/AutoC/UserDefinedType.html +0 -1047
- data/doc/AutoC/Vector.html +0 -987
- data/doc/AutoC.html +0 -331
- data/doc/_index.html +0 -388
- data/doc/class_list.html +0 -51
- data/doc/css/common.css +0 -1
- data/doc/css/full_list.css +0 -58
- data/doc/css/style.css +0 -481
- data/doc/file.CHANGES.html +0 -117
- data/doc/file.README.html +0 -116
- data/doc/file_list.html +0 -61
- data/doc/frames.html +0 -17
- data/doc/index.html +0 -116
- data/doc/js/app.js +0 -243
- data/doc/js/full_list.js +0 -216
- data/doc/js/jquery.js +0 -4
- data/doc/method_list.html +0 -1307
- data/doc/top-level-namespace.html +0 -112
- data/lib/autoc/code.rb +0 -237
- data/lib/autoc/collection/hash_map.rb +0 -385
- data/lib/autoc/collection/hash_set.rb +0 -337
- data/lib/autoc/collection/iterator.rb +0 -39
- data/lib/autoc/collection/list.rb +0 -429
- data/lib/autoc/collection/map.rb +0 -41
- data/lib/autoc/collection/queue.rb +0 -517
- data/lib/autoc/collection/set.rb +0 -134
- data/lib/autoc/collection/tree_map.rb +0 -464
- data/lib/autoc/collection/tree_set.rb +0 -611
- data/lib/autoc/collection/vector.rb +0 -336
- data/lib/autoc/string.rb +0 -492
- data/test/test_auto.c +0 -7141
- data/test/test_auto.h +0 -753
- data/test/test_char_string.rb +0 -270
- data/test/test_int_list.rb +0 -35
- data/test/test_int_tree_set.rb +0 -111
- data/test/test_int_vector.rb +0 -34
- data/test/test_value_hash_map.rb +0 -162
- data/test/test_value_hash_set.rb +0 -173
- data/test/test_value_list.rb +0 -193
- data/test/test_value_queue.rb +0 -275
- data/test/test_value_tree_map.rb +0 -176
- data/test/test_value_tree_set.rb +0 -173
- data/test/test_value_vector.rb +0 -155
- data/test/value.rb +0 -80
@@ -0,0 +1,263 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
|
4
|
+
require 'autoc/ranges'
|
5
|
+
require 'autoc/sequential'
|
6
|
+
require 'autoc/association'
|
7
|
+
|
8
|
+
|
9
|
+
module AutoC
|
10
|
+
|
11
|
+
|
12
|
+
# Value type string wrapper of the plain C string
|
13
|
+
class CString < Association
|
14
|
+
|
15
|
+
include STD
|
16
|
+
|
17
|
+
include Sequential
|
18
|
+
|
19
|
+
def default_constructible? = false
|
20
|
+
|
21
|
+
def range = @range ||= Range.new(self, visibility: visibility, parallel: @parallel)
|
22
|
+
|
23
|
+
def initialize(type = :CString, char = :char, parallel: nil, **kws)
|
24
|
+
super(type, char, :size_t, **kws)
|
25
|
+
dependencies << STRING_H
|
26
|
+
@parallel = parallel
|
27
|
+
end
|
28
|
+
|
29
|
+
def rvalue = @rv ||= Value.new(self)
|
30
|
+
|
31
|
+
def lvalue = @lv ||= Value.new(self, reference: true)
|
32
|
+
|
33
|
+
def const_rvalue = @crv ||= Value.new(self, constant: true)
|
34
|
+
|
35
|
+
def const_lvalue = @clv ||= Value.new(self, reference: true, constant: true)
|
36
|
+
|
37
|
+
def render_interface(stream)
|
38
|
+
if public?
|
39
|
+
stream << %{
|
40
|
+
/**
|
41
|
+
#{defgroup}
|
42
|
+
|
43
|
+
@brief Value type wrapper of the plain C string
|
44
|
+
|
45
|
+
This type represents a (paper thin) wrapper around the plain C string (char *) with proper value semantics.
|
46
|
+
|
47
|
+
@since 2.0
|
48
|
+
*/
|
49
|
+
}
|
50
|
+
else
|
51
|
+
stream << PRIVATE
|
52
|
+
end
|
53
|
+
stream << %{
|
54
|
+
typedef #{element.lvalue} #{signature};
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
def storage(target) = target # Return C pointer to contiguous storage
|
59
|
+
|
60
|
+
def render_forward_declarations(stream)
|
61
|
+
stream << %{
|
62
|
+
#include <stdio.h>
|
63
|
+
#include <malloc.h>
|
64
|
+
#include <stdarg.h>
|
65
|
+
/* overridable internal buffer size (in chars, not bytes) for *sprintf() operations */
|
66
|
+
#ifndef AUTOC_BUFFER_SIZE
|
67
|
+
#define AUTOC_BUFFER_SIZE 1024
|
68
|
+
#endif
|
69
|
+
}
|
70
|
+
super
|
71
|
+
end
|
72
|
+
|
73
|
+
def type_tag = "#{signature}<#{element}>"
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def configure
|
78
|
+
super
|
79
|
+
method(:void, :create, { target: lvalue, source: const_rvalue }, instance: :custom_create).configure do
|
80
|
+
header %{
|
81
|
+
@brief Create string
|
82
|
+
|
83
|
+
@param[out] target string to be created
|
84
|
+
@param[in] source string to be copied
|
85
|
+
|
86
|
+
This function creates & initializes a new string by making an independent of the source string.
|
87
|
+
This specifically means that the supplied source string may be any C string, either const or mutable, including string literal.
|
88
|
+
|
89
|
+
Previous contents of `*target` is overwritten.
|
90
|
+
|
91
|
+
Once constructed, the string is to be destroyed with @ref #{destroy}.
|
92
|
+
|
93
|
+
@since 2.0
|
94
|
+
}
|
95
|
+
inline_code %{
|
96
|
+
size_t size;
|
97
|
+
assert(target);
|
98
|
+
assert(source);
|
99
|
+
size = strlen(source);
|
100
|
+
*target = #{memory.allocate(element, 'size+1', atomic: true)}; assert(*target);
|
101
|
+
memcpy(*target, source, size*sizeof(#{element}));
|
102
|
+
(*target)[size] = '\\0';
|
103
|
+
}
|
104
|
+
end
|
105
|
+
method(:int, :create_format, { target: lvalue, format: const_rvalue }, variadic: true ).configure do
|
106
|
+
code %{
|
107
|
+
int r;
|
108
|
+
va_list args;
|
109
|
+
#if defined(HAVE_VSNPRINTF) || __STDC_VERSION__ >= 199901L || __cplusplus > 199711L || (defined(_MSC_VER) && _MSC_VER >= 1900) || defined(__POCC__)
|
110
|
+
va_start(args, format);
|
111
|
+
r = vsnprintf(NULL, 0, format, args);
|
112
|
+
va_end(args);
|
113
|
+
if(r < 0) return 0;
|
114
|
+
*target = #{memory.allocate(element, 'r+1', atomic: true)}; assert(*target);
|
115
|
+
va_start(args, format);
|
116
|
+
r = vsnprintf(*target, r+1, format, args);
|
117
|
+
va_end(args);
|
118
|
+
return r >= 0;
|
119
|
+
#else
|
120
|
+
#if defined(_MSC_VER)
|
121
|
+
#pragma message("WARNING: this code employs bare sprintf() with preallocated temporary buffer of AUTOC_BUFFER_SIZE chars; expect execution bail outs upon exceeding this limit")
|
122
|
+
#else
|
123
|
+
#warning("this code employs bare sprintf() with preallocated temporary buffer of AUTOC_BUFFER_SIZE chars; expect execution bail outs upon exceeding this limit")
|
124
|
+
#endif
|
125
|
+
va_start(args, format);
|
126
|
+
#{element.lvalue} t = #{memory.allocate(element, :AUTOC_BUFFER_SIZE, atomic: true)}; assert(t);
|
127
|
+
r = vsprintf(t, format, args);
|
128
|
+
if(r >= 0) {
|
129
|
+
if(r > AUTOC_BUFFER_SIZE-1) {
|
130
|
+
/*
|
131
|
+
the output spilled out of the preallocated buffer -
|
132
|
+
perfer to bail out right away rather than to get likely heap corruption
|
133
|
+
*/
|
134
|
+
abort();
|
135
|
+
}
|
136
|
+
/* prefer precision over performance and make a copy instead of returning a (possibly excessive) buffer */
|
137
|
+
#{default_create.(target, :t)};
|
138
|
+
}
|
139
|
+
/* FIXME handle the case of simultaneous (r < 0 && buffer overrun) */
|
140
|
+
#{memory.free(:t)};
|
141
|
+
va_end(args);
|
142
|
+
return r >= 0;
|
143
|
+
#endif
|
144
|
+
}
|
145
|
+
header %{
|
146
|
+
@brief Create formatted string
|
147
|
+
|
148
|
+
@param[out] target string to be created
|
149
|
+
@param[in] format format template
|
150
|
+
@param[in] ... format parameters
|
151
|
+
|
152
|
+
@result non-zero value on successful construction and zero value otherwise
|
153
|
+
|
154
|
+
This function employs a standard C function from the s*printf() family to create new formatted string.
|
155
|
+
|
156
|
+
@note No `*target` is modified on function failure.
|
157
|
+
|
158
|
+
@since 2.0
|
159
|
+
}
|
160
|
+
end
|
161
|
+
destroy.configure do
|
162
|
+
inline_code %{
|
163
|
+
assert(target);
|
164
|
+
#{memory.free('*target')};
|
165
|
+
}
|
166
|
+
end
|
167
|
+
copy.configure do
|
168
|
+
dependencies << custom_create
|
169
|
+
inline_code %{
|
170
|
+
#{custom_create.(*parameters)};
|
171
|
+
}
|
172
|
+
end
|
173
|
+
get.configure do
|
174
|
+
dependencies << check
|
175
|
+
inline_code %{
|
176
|
+
assert(target);
|
177
|
+
assert(#{check.(target, index)});
|
178
|
+
return target[index];
|
179
|
+
}
|
180
|
+
end
|
181
|
+
set.configure do
|
182
|
+
dependencies << check
|
183
|
+
inline_code %{
|
184
|
+
assert(target);
|
185
|
+
assert(#{check.(target, index)});
|
186
|
+
target[index] = value;
|
187
|
+
}
|
188
|
+
end
|
189
|
+
view.configure do
|
190
|
+
dependencies << check
|
191
|
+
inline_code %{
|
192
|
+
assert(target);
|
193
|
+
assert(#{check.(target, index)});
|
194
|
+
return &target[index];
|
195
|
+
}
|
196
|
+
end
|
197
|
+
equal.configure do
|
198
|
+
inline_code %{
|
199
|
+
assert(left);
|
200
|
+
assert(right);
|
201
|
+
return strcmp(left, right) == 0;
|
202
|
+
}
|
203
|
+
end
|
204
|
+
compare.configure do
|
205
|
+
inline_code %{
|
206
|
+
assert(left);
|
207
|
+
assert(right);
|
208
|
+
return strcmp(left, right);
|
209
|
+
}
|
210
|
+
end
|
211
|
+
hash_code.configure do
|
212
|
+
code %{
|
213
|
+
/* djb2 algorithm: http://www.cse.yorku.ca/~oz/hash.html */
|
214
|
+
size_t c;
|
215
|
+
size_t hash;
|
216
|
+
#{element.lvalue} s;
|
217
|
+
assert(target);
|
218
|
+
hash = 5381;
|
219
|
+
s = target;
|
220
|
+
while((c = *s++)) hash = hash*33 ^ c;
|
221
|
+
return hash;
|
222
|
+
}
|
223
|
+
end
|
224
|
+
contains.configure do
|
225
|
+
inline_code %{
|
226
|
+
assert(target);
|
227
|
+
return strchr(target, value) != NULL;
|
228
|
+
}
|
229
|
+
end
|
230
|
+
find_first.configure do
|
231
|
+
inline_code %{
|
232
|
+
assert(target);
|
233
|
+
return strchr(target, value);
|
234
|
+
}
|
235
|
+
end
|
236
|
+
check.configure do
|
237
|
+
dependencies << size
|
238
|
+
inline_code %{
|
239
|
+
assert(target);
|
240
|
+
return index < #{size.(target)};
|
241
|
+
}
|
242
|
+
end
|
243
|
+
empty.configure do
|
244
|
+
inline_code %{
|
245
|
+
assert(target);
|
246
|
+
return *target == '\\0';
|
247
|
+
}
|
248
|
+
end
|
249
|
+
size.configure do
|
250
|
+
inline_code %{
|
251
|
+
assert(target);
|
252
|
+
return strlen(target);
|
253
|
+
}
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
end # CString
|
258
|
+
|
259
|
+
|
260
|
+
CString::Range = ContiguousRange # Range
|
261
|
+
|
262
|
+
|
263
|
+
end
|
@@ -0,0 +1,247 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
|
4
|
+
require 'autoc/type'
|
5
|
+
require 'autoc/module'
|
6
|
+
require 'autoc/primitive'
|
7
|
+
|
8
|
+
|
9
|
+
module AutoC
|
10
|
+
|
11
|
+
|
12
|
+
# @private
|
13
|
+
class Value
|
14
|
+
|
15
|
+
attr_reader :type
|
16
|
+
|
17
|
+
def to_type = type
|
18
|
+
|
19
|
+
def to_value = self
|
20
|
+
|
21
|
+
def constant? = @constant == true
|
22
|
+
|
23
|
+
def reference? = @reference == true
|
24
|
+
|
25
|
+
def initialize(type, constant: false, reference: false)
|
26
|
+
@type = type
|
27
|
+
@constant = constant
|
28
|
+
@reference = reference
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_s = signature
|
32
|
+
|
33
|
+
def signature
|
34
|
+
_ = reference? ? "#{type.signature}*" : type.signature
|
35
|
+
constant? ? "const #{_}" : _
|
36
|
+
end
|
37
|
+
|
38
|
+
def call(value)
|
39
|
+
value = value.to_s
|
40
|
+
if reference?
|
41
|
+
# Manually collapse references &*xyz -> xyz for the sake of source code readability
|
42
|
+
value[0] =='*' ? value[1..-1] : "&#{value}"
|
43
|
+
else
|
44
|
+
value
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end # Value
|
48
|
+
|
49
|
+
|
50
|
+
# @private
|
51
|
+
# Function parameter
|
52
|
+
class Parameter
|
53
|
+
|
54
|
+
attr_reader :value
|
55
|
+
|
56
|
+
attr_reader :name
|
57
|
+
|
58
|
+
def initialize(value, name)
|
59
|
+
@value = value.to_value
|
60
|
+
@name = name.to_sym
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_s = name.to_s
|
64
|
+
|
65
|
+
def to_value_argument = value.reference? ? "*#{name}" : name
|
66
|
+
|
67
|
+
def signature = value.signature
|
68
|
+
|
69
|
+
def declaration = '%s %s' % [signature, name]
|
70
|
+
|
71
|
+
end # Parameter
|
72
|
+
|
73
|
+
|
74
|
+
# Standalone C side function
|
75
|
+
# The generated function is meant to be the C89-compliant
|
76
|
+
# NOTE: This function does not track parameter and result types as its dependencies
|
77
|
+
# This can be done manually by appending to #dependencies property with <<
|
78
|
+
class Function
|
79
|
+
|
80
|
+
include Entity
|
81
|
+
|
82
|
+
attr_reader :name
|
83
|
+
|
84
|
+
attr_reader :result
|
85
|
+
|
86
|
+
attr_reader :parameters
|
87
|
+
|
88
|
+
attr_reader :visibility
|
89
|
+
|
90
|
+
attr_writer :inline
|
91
|
+
|
92
|
+
def initialize(result, name, parameters, inline: false, visibility: :public, constraint: true, variadic: false, abstract: false)
|
93
|
+
@name = name.to_s
|
94
|
+
@result = result
|
95
|
+
@inline = inline
|
96
|
+
@visibility = visibility
|
97
|
+
@constraint = constraint
|
98
|
+
@abstract = abstract
|
99
|
+
@variadic = variadic
|
100
|
+
@parameters = Parameters.new(self)
|
101
|
+
if parameters.is_a?(Hash)
|
102
|
+
parameters.each do |name, descriptor|
|
103
|
+
x = Parameter.new(descriptor, name)
|
104
|
+
@parameters[x.name] = x
|
105
|
+
end
|
106
|
+
else
|
107
|
+
i = -1
|
108
|
+
parameters.each do |descriptor|
|
109
|
+
x = Parameter.new(descriptor, "_#{i+=1}")
|
110
|
+
@parameters[x.name] = x
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def inline_code(code)
|
116
|
+
@inline = true
|
117
|
+
code(code)
|
118
|
+
end
|
119
|
+
|
120
|
+
def external_code(code)
|
121
|
+
@inline = false
|
122
|
+
code(code)
|
123
|
+
end
|
124
|
+
|
125
|
+
def to_s = name
|
126
|
+
|
127
|
+
def header(header) = @header = header
|
128
|
+
|
129
|
+
def code(code) = @code = code
|
130
|
+
|
131
|
+
def inspect = "#{prototype} <#{self.class}>"
|
132
|
+
|
133
|
+
def inline? = @inline == true
|
134
|
+
|
135
|
+
def public? = @visibility == :public
|
136
|
+
|
137
|
+
def abstract? = @abstract == true
|
138
|
+
|
139
|
+
def variadic? = @variadic == true
|
140
|
+
|
141
|
+
def live? = (@constraint.is_a?(Proc) ? @constraint.() : @constraint) == true
|
142
|
+
|
143
|
+
def signature = '%s(%s)' % [result.signature, (parameters.to_a.collect(&:signature) << (variadic? ? '...' : nil)).compact.join(',')]
|
144
|
+
|
145
|
+
def prototype = '%s %s(%s)' % [result.signature, name, (parameters.to_a.collect(&:declaration) << (variadic? ? '...' : nil)).compact.join(',')]
|
146
|
+
|
147
|
+
def definition = '%s {%s}' % [prototype, @code]
|
148
|
+
|
149
|
+
def parameter(name) = @values[name]
|
150
|
+
|
151
|
+
def call(*arguments)
|
152
|
+
xs = []
|
153
|
+
ps = parameters.to_a
|
154
|
+
(0...arguments.size).each do |i|
|
155
|
+
a = arguments[i]
|
156
|
+
v = a.is_a?(Parameter) ? a.to_value_argument : a
|
157
|
+
xs << (i < ps.size ? ps[i].value.(v) : v)
|
158
|
+
end
|
159
|
+
'%s(%s)' % [name, xs.join(',')]
|
160
|
+
end
|
161
|
+
|
162
|
+
def configure(&block)
|
163
|
+
instance_eval(&block)
|
164
|
+
self
|
165
|
+
end
|
166
|
+
|
167
|
+
# This allows to call other functions with this function's individual parameters as arguments
|
168
|
+
# A call to unknown method results in the method's name being emitted
|
169
|
+
def method_missing(meth, *args) = parameters.has_key?(meth) ? parameters[meth] : meth
|
170
|
+
|
171
|
+
private
|
172
|
+
|
173
|
+
# On function inlining in C: http://www.greenend.org.uk/rjk/tech/inline.html
|
174
|
+
|
175
|
+
# static inline seems to be THE most portable way without resorting to preprocessor
|
176
|
+
# but consider the possible code bloat it incurs
|
177
|
+
|
178
|
+
def render_declaration_specifier(stream)
|
179
|
+
# The inline specifier is not a part of C89 yet descent compilers do inlining at will
|
180
|
+
# given the function definition is available at the function call
|
181
|
+
stream << 'static ' if inline?
|
182
|
+
end
|
183
|
+
|
184
|
+
# Render the commentary block preceding the function declaration, both inline or external
|
185
|
+
def render_function_header(stream)
|
186
|
+
stream << %{
|
187
|
+
/* #{@header} */
|
188
|
+
} unless @header.nil?
|
189
|
+
end
|
190
|
+
|
191
|
+
# Render full function declaration statement including the commentary block
|
192
|
+
# For inline functions this also renders a function body effectively making this also a function definition
|
193
|
+
# The declaration comes into either public interface of forward declaration block depending on the function's visibility status
|
194
|
+
def render_function_declaration(stream)
|
195
|
+
render_function_header(stream)
|
196
|
+
render_declaration_specifier(stream)
|
197
|
+
if inline?
|
198
|
+
render_function_definition(stream)
|
199
|
+
else
|
200
|
+
stream << prototype << ';'
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
# Render function definition, both inline or extern
|
205
|
+
# This code never gets into public interface
|
206
|
+
def render_function_definition(stream)
|
207
|
+
unless abstract?
|
208
|
+
raise("missing function definition for #{name}()") if @code.nil?
|
209
|
+
stream << definition
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# Render function's public interface
|
214
|
+
# Only public functions are rendered
|
215
|
+
def render_interface(stream)
|
216
|
+
render_function_declaration(stream) if live? && public?
|
217
|
+
end
|
218
|
+
|
219
|
+
# Render function's interface for non-public functions which should not appear in the public interface
|
220
|
+
def render_forward_declarations(stream)
|
221
|
+
render_function_declaration(stream) if live? && !public?
|
222
|
+
end
|
223
|
+
|
224
|
+
# Render non-inline function definition regardless of function's visibility status
|
225
|
+
def render_implementation(stream)
|
226
|
+
render_function_definition(stream) if live? && !inline?
|
227
|
+
end
|
228
|
+
|
229
|
+
end # Function
|
230
|
+
|
231
|
+
|
232
|
+
# @private
|
233
|
+
# Named parameter list for the function
|
234
|
+
class Function::Parameters < ::Hash
|
235
|
+
def initialize(function)
|
236
|
+
@function = function
|
237
|
+
super()
|
238
|
+
end
|
239
|
+
def to_a = values
|
240
|
+
def [](name)
|
241
|
+
raise "unknown parameter #{name} in function #{@function}()" unless has_key?(name)
|
242
|
+
super
|
243
|
+
end
|
244
|
+
end # Parameters
|
245
|
+
|
246
|
+
|
247
|
+
end
|