autoc 0.8 → 1.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 (49) hide show
  1. checksums.yaml +7 -0
  2. data/README +15 -4
  3. data/doc/AutoC.html +245 -0
  4. data/doc/AutoC/Code.html +520 -0
  5. data/doc/AutoC/Collection.html +923 -0
  6. data/doc/AutoC/HashMap.html +1161 -0
  7. data/doc/AutoC/HashSet.html +1122 -0
  8. data/doc/AutoC/List.html +1002 -0
  9. data/doc/AutoC/Module.html +951 -0
  10. data/doc/AutoC/Module/File.html +412 -0
  11. data/doc/AutoC/Module/Header.html +432 -0
  12. data/doc/AutoC/Module/Source.html +704 -0
  13. data/doc/AutoC/Priority.html +138 -0
  14. data/doc/AutoC/Queue.html +1167 -0
  15. data/doc/AutoC/Type.html +1152 -0
  16. data/doc/AutoC/UserDefinedType.html +655 -0
  17. data/doc/AutoC/Vector.html +856 -0
  18. data/doc/_index.html +299 -0
  19. data/doc/class_list.html +54 -0
  20. data/doc/css/common.css +1 -0
  21. data/doc/css/full_list.css +57 -0
  22. data/doc/css/style.css +339 -0
  23. data/doc/file.README.html +112 -0
  24. data/doc/file_list.html +56 -0
  25. data/doc/frames.html +26 -0
  26. data/doc/index.html +112 -0
  27. data/doc/js/app.js +219 -0
  28. data/doc/js/full_list.js +178 -0
  29. data/doc/js/jquery.js +4 -0
  30. data/doc/method_list.html +605 -0
  31. data/doc/top-level-namespace.html +112 -0
  32. data/lib/autoc.rb +35 -12
  33. data/lib/autoc/{code_builder.rb → code.rb} +230 -247
  34. data/lib/autoc/collection.rb +137 -0
  35. data/lib/autoc/collection/hash_map.rb +388 -0
  36. data/lib/autoc/collection/hash_set.rb +433 -0
  37. data/lib/autoc/collection/list.rb +410 -0
  38. data/lib/autoc/collection/queue.rb +514 -0
  39. data/lib/autoc/collection/vector.rb +295 -0
  40. data/lib/autoc/type.rb +198 -0
  41. data/test/test.c +921 -396
  42. data/test/test.h +41 -0
  43. data/test/test.rb +21 -26
  44. data/test/test_auto.c +2630 -3961
  45. data/test/test_auto.h +449 -560
  46. metadata +50 -17
  47. data/lib/autoc/data_struct_builder.rb +0 -1794
  48. data/lib/autoc/type_builder.rb +0 -24
  49. data/manual/manual.pdf +0 -0
@@ -0,0 +1,295 @@
1
+ require "autoc/collection"
2
+
3
+
4
+ module AutoC
5
+
6
+
7
+ =begin
8
+
9
+ Vector is an ordered random access sequence container.
10
+
11
+ The collection's C++ counterpart is +std::vector<>+ template class.
12
+
13
+ == Generated C interface
14
+
15
+ === Collection management
16
+
17
+ [cols="2*"]
18
+ |===
19
+ |*_void_* ~type~Copy(*_Type_* * +dst+, *_Type_* * +src+)
20
+ |
21
+ Create a new vector +dst+ filled with the contents of +src+.
22
+ A copy operation is performed on every element in +src+.
23
+
24
+ NOTE: Previous contents of +dst+ is overwritten.
25
+
26
+ |*_void_* ~type~Ctor(*_Type_* * +self+, *_size_t_* +size+)
27
+ |
28
+ Create a new vector +self+ of size +size+.
29
+ The elements are initialized with either supplied or generated default parameterless constructor.
30
+
31
+ WARNING: +size+ must be greater than zero.
32
+
33
+ NOTE: Previous contents of +self+ is overwritten.
34
+
35
+ |*_void_* ~type~Dtor(*_Type_* * +self+)
36
+ |
37
+ Destroy vector +self+.
38
+ Stored elements are destroyed as well by calling the respective destructors.
39
+
40
+ |*_int_* ~type~Equal(*_Type_* * +lt+, *_Type_* * +rt+)
41
+ |
42
+ Return non-zero value if vectors +lt+ and +rt+ are considered equal by contents and zero value otherwise.
43
+
44
+ |*_size_t_* ~type~Identify(*_Type_* * +self+)
45
+ |
46
+ Return hash code for vector +self+.
47
+ |===
48
+
49
+ === Basic operations
50
+
51
+ [cols=2*]
52
+ |===
53
+ |*_E_* ~type~Get(*_Type_* * +self+, *_size_t_* +index+)
54
+ |
55
+ Return a _copy_ of the element stored in +self+ at position +index+.
56
+
57
+ WARNING: +index+ *must* be a valid index otherwise the behavior is undefined. See ~type~Within().
58
+
59
+ |*_void_* ~type~Resize(*_Type_* * +self+, *_size_t_* +size+)
60
+ |
61
+ Set new size of vector +self+ to +size+.
62
+
63
+ If new size is greater than the old one, extra elements are created with default parameterless constructors.
64
+ If new size is smaller the the old one, excessive elements are destroyed.
65
+
66
+ WARNING: +size+ *must* be greater than zero.
67
+
68
+ |*_void_* ~type~Set(*_Type_* * +self+, *_size_t_* +index+, *_E_* +what+)
69
+ |
70
+
71
+ Store a _copy_ of the element +what+ in vector +self+ at position +index+ destroying previous contents.
72
+
73
+ WARNING: +index+ *must* be a valid index otherwise the behavior is undefined. See ~type~Within().
74
+
75
+ |*_size_t_* ~type~Size(*_Type_* * +self+)
76
+ |
77
+ Return number of elements stored in vector +self+.
78
+
79
+ |*_void_* ~type~Sort(*_Type_* * +self+)
80
+ |
81
+ Perform a sorting operation on the contents of vector +self+ utilizing either generated of user supplied ordering functions.
82
+
83
+ |*_int_* ~type~Within(*_Type_* * +self+, *_size_t_* +index+)
84
+ |
85
+ Return non-zero value if +index+ is a valid index and zero value otherwise.
86
+ Valid index belongs to the range 0 ... ~type~Size()-1.
87
+ |===
88
+
89
+ === Iteration
90
+
91
+ [cols=2*]
92
+ |===
93
+ |*_void_* ~it~Ctor(*_IteratorType_* * +it+, *_Type_* * +self+)
94
+ |
95
+ Create a new forward iterator +it+ on vector +self+.
96
+
97
+ NOTE: Previous contents of +it+ is overwritten.
98
+
99
+ |*_void_* ~it~CtorEx(*_IteratorType_* * +it+, *_Type_* * +self+, *_int_* +forward+)
100
+ |
101
+ Create a new iterator +it+ on vector +self+.
102
+ Non-zero value of +forward+ specifies a forward iterator, zero value specifies a backward iterator.
103
+
104
+ NOTE: Previous contents of +it+ is overwritten.
105
+
106
+ |*_int_* ~it~Move(*_IteratorType_* * +it+)
107
+ |
108
+ Advance iterator position of +it+ *and* return non-zero value if new position is valid and zero value otherwise.
109
+
110
+ |*_E_* ~it~Get(*_IteratorType_* * +it+)
111
+ |
112
+ Return a _copy_ of current element pointed to by the iterator +it+.
113
+
114
+ WARNING: current position *must* be valid otherwise the behavior is undefined. See ~it~Move().
115
+ |===
116
+
117
+ =end
118
+ class Vector < Collection
119
+
120
+ def ctor(*args)
121
+ args.empty? ? super() : raise("#{self.class} provides no default constructor")
122
+ end
123
+
124
+ def write_exported_types(stream)
125
+ stream << %$
126
+ /***
127
+ **** #{type}<#{element.type}> (#{self.class})
128
+ ***/
129
+ $ if public?
130
+ stream << %$
131
+ typedef struct #{type} #{type};
132
+ typedef struct #{it} #{it};
133
+ struct #{type} {
134
+ #{element.type}* values;
135
+ size_t element_count;
136
+ };
137
+ struct #{it} {
138
+ #{type}* vector;
139
+ int index;
140
+ int forward;
141
+ };
142
+ $
143
+ end
144
+
145
+ def write_exported_declarations(stream, declare, define)
146
+ stream << %$
147
+ #{declare} void #{ctor}(#{type}*, size_t);
148
+ #{declare} void #{dtor}(#{type}*);
149
+ #{declare} void #{copy}(#{type}*, #{type}*);
150
+ #{declare} int #{equal}(#{type}*, #{type}*);
151
+ #{declare} void #{resize}(#{type}*, size_t);
152
+ #{declare} size_t #{identify}(#{type}*);
153
+ #{define} size_t #{size}(#{type}* self) {
154
+ #{assert}(self);
155
+ return self->element_count;
156
+ }
157
+ #{define} int #{within}(#{type}* self, size_t index) {
158
+ #{assert}(self);
159
+ return index < #{size}(self);
160
+ }
161
+ #{define} #{element.type} #{get}(#{type}* self, size_t index) {
162
+ #{element.type} result;
163
+ #{assert}(self);
164
+ #{assert}(#{within}(self, index));
165
+ #{element.copy("result", "self->values[index]")};
166
+ return result;
167
+ }
168
+ #{define} void #{set}(#{type}* self, size_t index, #{element.type} value) {
169
+ #{assert}(self);
170
+ #{assert}(#{within}(self, index));
171
+ #{element.dtor("self->values[index]")};
172
+ #{element.copy("self->values[index]", "value")};
173
+ }
174
+ #{declare} void #{sort}(#{type}*);
175
+ #define #{itCtor}(self, type) #{itCtorEx}(self, type, 1)
176
+ #{define} void #{itCtorEx}(#{it}* self, #{type}* vector, int forward) {
177
+ #{assert}(self);
178
+ #{assert}(vector);
179
+ self->vector = vector;
180
+ self->forward = forward;
181
+ self->index = forward ? -1 : #{size}(vector);
182
+ }
183
+ #{define} int #{itMove}(#{it}* self) {
184
+ #{assert}(self);
185
+ if(self->forward) ++self->index; else --self->index;
186
+ return #{within}(self->vector, self->index);
187
+ }
188
+ #{define} #{element.type} #{itGet}(#{it}* self) {
189
+ #{assert}(self);
190
+ return #{get}(self->vector, self->index);
191
+ }
192
+ $
193
+ end
194
+
195
+ def write_implementations(stream, define)
196
+ stream << %$
197
+ static void #{allocate}(#{type}* self, size_t element_count) {
198
+ #{assert}(self);
199
+ #{assert}(element_count > 0);
200
+ self->element_count = element_count;
201
+ self->values = (#{element.type}*)#{malloc}(element_count*sizeof(#{element.type})); #{assert}(self->values);
202
+ }
203
+ #{define} void #{ctor}(#{type}* self, size_t element_count) {
204
+ size_t index;
205
+ #{assert}(self);
206
+ #{allocate}(self, element_count);
207
+ for(index = 0; index < #{size}(self); ++index) {
208
+ #{element.ctor("self->values[index]")};
209
+ }
210
+ }
211
+ #{define} void #{dtor}(#{type}* self) {
212
+ size_t index;
213
+ #{assert}(self);
214
+ for(index = 0; index < #{size}(self); ++index) {
215
+ #{element.dtor("self->values[index]")};
216
+ }
217
+ #{free}(self->values);
218
+ }
219
+ #{define} void #{copy}(#{type}* dst, #{type}* src) {
220
+ size_t index, size;
221
+ #{assert}(src);
222
+ #{assert}(dst);
223
+ #{allocate}(dst, size = #{size}(src));
224
+ for(index = 0; index < size; ++index) {
225
+ #{element.copy("dst->values[index]", "src->values[index]")};
226
+ }
227
+ }
228
+ #{define} int #{equal}(#{type}* lt, #{type}* rt) {
229
+ size_t index, size;
230
+ #{assert}(lt);
231
+ #{assert}(rt);
232
+ if(#{size}(lt) == (size = #{size}(rt))) {
233
+ for(index = 0; index < size; ++index) {
234
+ if(!#{element.equal("lt->values[index]", "rt->values[index]")}) return 0;
235
+ }
236
+ return 1;
237
+ } else
238
+ return 0;
239
+ }
240
+ #{define} void #{resize}(#{type}* self, size_t new_element_count) {
241
+ size_t index, element_count, from, to;
242
+ #{assert}(self);
243
+ if((element_count = #{size}(self)) != new_element_count) {
244
+ #{element.type}* values = (#{element.type}*)#{malloc}(new_element_count*sizeof(#{element.type})); #{assert}(values);
245
+ from = AUTOC_MIN(element_count, new_element_count);
246
+ to = AUTOC_MAX(element_count, new_element_count);
247
+ for(index = 0; index < from; ++index) {
248
+ values[index] = self->values[index];
249
+ }
250
+ if(element_count > new_element_count) {
251
+ for(index = from; index < to; ++index) {
252
+ #{element.dtor("self->values[index]")};
253
+ }
254
+ } else {
255
+ for(index = from; index < to; ++index) {
256
+ #{element.ctor("values[index]")};
257
+ }
258
+ }
259
+ #{free}(self->values);
260
+ self->values = values;
261
+ self->element_count = new_element_count;
262
+ }
263
+ }
264
+ #{define} size_t #{identify}(#{type}* self) {
265
+ size_t index, result = 0;
266
+ #{assert}(self);
267
+ for(index = 0; index < self->element_count; ++index) {
268
+ result ^= #{element.identify("self->values[index]")};
269
+ result = AUTOC_RCYCLE(result);
270
+ }
271
+ return result;
272
+ }
273
+ static int #{comparator}(void* lp_, void* rp_) {
274
+ #{element.type}* lp = (#{element.type}*)lp_;
275
+ #{element.type}* rp = (#{element.type}*)rp_;
276
+ if(#{element.equal("*lp", "*rp")}) {
277
+ return 0;
278
+ } else if(#{element.less("*lp", "*rp")}) {
279
+ return -1;
280
+ } else {
281
+ return +1;
282
+ }
283
+ }
284
+ #{define} void #{sort}(#{type}* self) {
285
+ typedef int (*F)(const void*, const void*);
286
+ #{assert}(self);
287
+ qsort(self->values, #{size}(self), sizeof(#{element.type}), (F)#{comparator});
288
+ }
289
+ $
290
+ end
291
+
292
+ end # Vector
293
+
294
+
295
+ end # AutoC
data/lib/autoc/type.rb ADDED
@@ -0,0 +1,198 @@
1
+ require "autoc/code"
2
+
3
+
4
+ module AutoC
5
+
6
+
7
+ class Type < Code
8
+
9
+ # @private
10
+ CommonCode = Class.new(Code) do
11
+ def write_intf(stream)
12
+ stream << %$
13
+ #ifndef AUTOC_INLINE
14
+ #ifdef _MSC_VER
15
+ #define AUTOC_INLINE __inline
16
+ #elif __STDC_VERSION__ >= 199901L
17
+ #define AUTOC_INLINE inline AUTOC_STATIC
18
+ #else
19
+ #define AUTOC_INLINE AUTOC_STATIC
20
+ #endif
21
+ #endif
22
+ #ifndef AUTOC_EXTERN
23
+ #ifdef __cplusplus
24
+ #define AUTOC_EXTERN extern "C"
25
+ #else
26
+ #define AUTOC_EXTERN extern
27
+ #endif
28
+ #endif
29
+ #ifndef AUTOC_STATIC
30
+ #ifdef _MSC_VER
31
+ #define AUTOC_STATIC __pragma(warning(suppress:4100)) static
32
+ #elif defined(__GNUC__)
33
+ #define AUTOC_STATIC __attribute__((__used__)) static
34
+ #else
35
+ #define AUTOC_STATIC static
36
+ #endif
37
+ #endif
38
+ #include <stddef.h>
39
+ #include <stdlib.h>
40
+ #include <assert.h>
41
+ $
42
+ end
43
+ def write_decls(stream)
44
+ stream << %$
45
+ #include <limits.h>
46
+ #define AUTOC_MIN(a,b) ((a) > (b) ? (b) : (a))
47
+ #define AUTOC_MAX(a,b) ((a) > (b) ? (a) : (b))
48
+ #define AUTOC_RCYCLE(x) (((x) << 1) | ((x) >> (sizeof(x)*CHAR_BIT - 1))) /* NOTE : valid for unsigned types only */
49
+ $
50
+ end
51
+ end.new
52
+
53
+ attr_reader :type
54
+
55
+ def entities; [CommonCode] end
56
+
57
+ def initialize(type, visibility = :public)
58
+ @type = type.to_s
59
+ @visibility = [:public, :private, :static].include?(visibility) ? visibility : raise("unsupported visibility")
60
+ end
61
+
62
+ def method_missing(method, *args)
63
+ str = method.to_s
64
+ func = @type + str[0,1].capitalize + str[1..-1] # Ruby 1.8 compatible
65
+ if args.empty?
66
+ func # Emit bare function name
67
+ elsif args.size == 1 && args.first == nil
68
+ func + "()" # Use sole nil argument to emit function call with no arguments
69
+ else
70
+ func + "(" + args.join(", ") + ")" # Emit normal function call with supplied arguments
71
+ end
72
+ end
73
+
74
+ def write_intf(stream)
75
+ case @visibility
76
+ when :public
77
+ write_exported_types(stream)
78
+ write_exported_declarations(stream, extern, inline)
79
+ end
80
+ end
81
+
82
+ def write_decls(stream)
83
+ case @visibility
84
+ when :private
85
+ write_exported_types(stream)
86
+ write_exported_declarations(stream, extern, inline)
87
+ when :static
88
+ write_exported_types(stream)
89
+ write_exported_declarations(stream, static, inline)
90
+ end
91
+ end
92
+
93
+ def write_defs(stream)
94
+ case @visibility
95
+ when :public, :private
96
+ write_implementations(stream, nil)
97
+ when :static
98
+ write_implementations(stream, static)
99
+ end
100
+ end
101
+
102
+ def write_exported_types(stream) end
103
+
104
+ def write_exported_declarations(stream, declare, define) end
105
+
106
+ def write_implementations(stream, define) end
107
+
108
+ def extern; "AUTOC_EXTERN" end
109
+
110
+ def inline; "AUTOC_INLINE" end
111
+
112
+ def static; "AUTOC_STATIC" end
113
+
114
+ def assert; "assert" end
115
+
116
+ def malloc; "malloc" end
117
+
118
+ def calloc; "calloc" end
119
+
120
+ def free; "free" end
121
+
122
+ def abort; "abort" end
123
+
124
+ protected
125
+
126
+ def public?; @visibility == :public end
127
+
128
+ def private?; @visibility == :private end
129
+
130
+ def static?; @visibility == :static end
131
+
132
+ end # Type
133
+
134
+
135
+ class UserDefinedType < Type
136
+
137
+ # @private
138
+ class PublicDeclaration < Code
139
+ def entities; super + [Type::CommonCode] end
140
+ def initialize(forward) @forward = forward.to_s end
141
+ def hash; @forward.hash end
142
+ def eql?(other) self.class == other.class && @forward == other.instance_variable_get(:@forward) end
143
+ def write_intf(stream)
144
+ stream << "\n"
145
+ stream << @forward
146
+ stream << "\n"
147
+ end
148
+ end # PublicDeclaration
149
+
150
+ def entities; super + @deps end
151
+
152
+ def initialize(opt)
153
+ @deps = []
154
+ v = :public
155
+ if [Symbol, String].include?(opt.class)
156
+ t = opt
157
+ elsif opt.is_a?(Hash)
158
+ t = opt[:type].nil? ? raise("type is not specified") : opt[:type]
159
+ [:ctor, :dtor, :copy, :equal, :less, :identify].each do |key|
160
+ instance_variable_set("@#{key}".to_sym, opt[key].to_s) unless opt[key].nil?
161
+ end
162
+ @deps << PublicDeclaration.new(opt[:forward]) unless opt[:forward].nil?
163
+ optv = opt[:visibility]
164
+ v = optv.nil? ? :public : optv
165
+ else
166
+ raise "failed to decode the argument"
167
+ end
168
+ super(t, v)
169
+ end
170
+
171
+ def ctor(obj)
172
+ @ctor.nil? ? "(#{obj} = 0)" : "#{@ctor}(#{obj})"
173
+ end
174
+
175
+ def dtor(obj)
176
+ @dtor.nil? ? nil : "#{@dtor}(#{obj})"
177
+ end
178
+
179
+ def copy(dst, src)
180
+ @copy.nil? ? "(#{dst} = #{src})" : "#{@copy}(#{dst}, #{src})"
181
+ end
182
+
183
+ def equal(lt, rt)
184
+ @equal.nil? ? "(#{lt} == #{rt})" : "#{@equal}(#{lt}, #{rt})"
185
+ end
186
+
187
+ def less(lt, rt)
188
+ @less.nil? ? "(#{lt} < #{rt})" : "#{@less}(#{lt}, #{rt})"
189
+ end
190
+
191
+ def identify(obj)
192
+ @identify.nil? ? "(size_t)(#{obj})" : "#{@identify}(#{obj})"
193
+ end
194
+
195
+ end # UserDefinedType
196
+
197
+
198
+ end # AutoC