autoc 1.4 → 2.0.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 (110) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES.md +3 -0
  3. data/README.md +149 -0
  4. data/cmake/AutoC.cmake +39 -0
  5. data/lib/autoc/allocators.rb +51 -0
  6. data/lib/autoc/association.rb +126 -0
  7. data/lib/autoc/box.rb +311 -0
  8. data/lib/autoc/cmake.rb +54 -0
  9. data/lib/autoc/collection.rb +83 -110
  10. data/lib/autoc/composite.rb +333 -0
  11. data/lib/autoc/cstring.rb +263 -0
  12. data/lib/autoc/function.rb +247 -0
  13. data/lib/autoc/hash_map.rb +328 -0
  14. data/lib/autoc/hash_set.rb +339 -0
  15. data/lib/autoc/hashers.rb +102 -0
  16. data/lib/autoc/list.rb +444 -0
  17. data/lib/autoc/module.rb +434 -0
  18. data/lib/autoc/openmp.rb +15 -0
  19. data/lib/autoc/primitive.rb +27 -0
  20. data/lib/autoc/ranges.rb +707 -0
  21. data/lib/autoc/record.rb +247 -0
  22. data/lib/autoc/scaffold/docs.rb +117 -0
  23. data/lib/autoc/scaffold/generic_value.rb +86 -0
  24. data/lib/autoc/scaffold/project.rb +75 -0
  25. data/lib/autoc/scaffold/test_cstring.rb +113 -0
  26. data/lib/autoc/scaffold/test_cstring_hash_set.rb +35 -0
  27. data/lib/autoc/scaffold/test_int_box.rb +22 -0
  28. data/lib/autoc/scaffold/test_int_hash_set.rb +448 -0
  29. data/lib/autoc/scaffold/test_int_list.rb +106 -0
  30. data/lib/autoc/scaffold/test_int_vector.rb +83 -0
  31. data/lib/autoc/scaffold/test_v2v_hash_map.rb +83 -0
  32. data/lib/autoc/scaffold/test_value_hash_set.rb +60 -0
  33. data/lib/autoc/scaffold/test_value_vector.rb +146 -0
  34. data/{test/test.rb → lib/autoc/scaffold/tests.rb} +179 -158
  35. data/lib/autoc/scaffold.rb +12 -0
  36. data/lib/autoc/sequential.rb +99 -0
  37. data/lib/autoc/set.rb +331 -0
  38. data/lib/autoc/std.rb +149 -0
  39. data/lib/autoc/type.rb +93 -531
  40. data/lib/autoc/vector.rb +290 -0
  41. data/lib/autoc.rb +4 -35
  42. metadata +55 -85
  43. data/.yardopts +0 -4
  44. data/CHANGES +0 -23
  45. data/README +0 -28
  46. data/doc/AutoC/Code.html +0 -523
  47. data/doc/AutoC/Collection.html +0 -1214
  48. data/doc/AutoC/HashMap.html +0 -1441
  49. data/doc/AutoC/HashSet.html +0 -916
  50. data/doc/AutoC/Iterators/Bidirectional.html +0 -204
  51. data/doc/AutoC/Iterators/Unidirectional.html +0 -200
  52. data/doc/AutoC/Iterators.html +0 -126
  53. data/doc/AutoC/List.html +0 -1039
  54. data/doc/AutoC/Maps.html +0 -290
  55. data/doc/AutoC/Module/File.html +0 -415
  56. data/doc/AutoC/Module/Header.html +0 -437
  57. data/doc/AutoC/Module/Source.html +0 -707
  58. data/doc/AutoC/Module.html +0 -948
  59. data/doc/AutoC/Priority.html +0 -138
  60. data/doc/AutoC/Queue.html +0 -1172
  61. data/doc/AutoC/Reference.html +0 -735
  62. data/doc/AutoC/Sets.html +0 -520
  63. data/doc/AutoC/String.html +0 -1394
  64. data/doc/AutoC/TreeMap.html +0 -1565
  65. data/doc/AutoC/TreeSet.html +0 -1447
  66. data/doc/AutoC/Type.html +0 -2148
  67. data/doc/AutoC/UserDefinedType.html +0 -1047
  68. data/doc/AutoC/Vector.html +0 -987
  69. data/doc/AutoC.html +0 -331
  70. data/doc/_index.html +0 -388
  71. data/doc/class_list.html +0 -51
  72. data/doc/css/common.css +0 -1
  73. data/doc/css/full_list.css +0 -58
  74. data/doc/css/style.css +0 -481
  75. data/doc/file.CHANGES.html +0 -117
  76. data/doc/file.README.html +0 -116
  77. data/doc/file_list.html +0 -61
  78. data/doc/frames.html +0 -17
  79. data/doc/index.html +0 -116
  80. data/doc/js/app.js +0 -243
  81. data/doc/js/full_list.js +0 -216
  82. data/doc/js/jquery.js +0 -4
  83. data/doc/method_list.html +0 -1307
  84. data/doc/top-level-namespace.html +0 -112
  85. data/lib/autoc/code.rb +0 -237
  86. data/lib/autoc/collection/hash_map.rb +0 -385
  87. data/lib/autoc/collection/hash_set.rb +0 -337
  88. data/lib/autoc/collection/iterator.rb +0 -39
  89. data/lib/autoc/collection/list.rb +0 -429
  90. data/lib/autoc/collection/map.rb +0 -41
  91. data/lib/autoc/collection/queue.rb +0 -517
  92. data/lib/autoc/collection/set.rb +0 -134
  93. data/lib/autoc/collection/tree_map.rb +0 -464
  94. data/lib/autoc/collection/tree_set.rb +0 -611
  95. data/lib/autoc/collection/vector.rb +0 -336
  96. data/lib/autoc/string.rb +0 -492
  97. data/test/test_auto.c +0 -7141
  98. data/test/test_auto.h +0 -753
  99. data/test/test_char_string.rb +0 -270
  100. data/test/test_int_list.rb +0 -35
  101. data/test/test_int_tree_set.rb +0 -111
  102. data/test/test_int_vector.rb +0 -34
  103. data/test/test_value_hash_map.rb +0 -162
  104. data/test/test_value_hash_set.rb +0 -173
  105. data/test/test_value_list.rb +0 -193
  106. data/test/test_value_queue.rb +0 -275
  107. data/test/test_value_tree_map.rb +0 -176
  108. data/test/test_value_tree_set.rb +0 -173
  109. data/test/test_value_vector.rb +0 -155
  110. data/test/value.rb +0 -80
@@ -0,0 +1,60 @@
1
+ require 'autoc/hash_set'
2
+
3
+ type_test(AutoC::HashSet, :ValueHashSet, Value) do
4
+
5
+ ###
6
+
7
+ setup %{
8
+ #{self} t;
9
+ }
10
+
11
+ cleanup %{
12
+ #{destroy}(&t);
13
+ }
14
+
15
+ test :create_default, %{
16
+ #{default_create}(&t);
17
+ TEST_EQUAL( #{size}(&t), 0 );
18
+ }
19
+
20
+ test :create_custom, %{
21
+ #{create_capacity}(&t, 1024);
22
+ TEST_EQUAL( #{size}(&t), 0 );
23
+ }
24
+
25
+ ###
26
+
27
+ setup %{
28
+ #{self} t;
29
+ #{default_create}(&t);
30
+ }
31
+
32
+ cleanup %{
33
+ #{destroy}(&t);
34
+ }
35
+
36
+ test :put, %{
37
+ #{element} e;
38
+ #{element.create}(&e);
39
+ TEST_TRUE( #{put}(&t, e) );
40
+ TEST_EQUAL( #{size}(&t), 1 );
41
+ TEST_FALSE( #{put}(&t, e) );
42
+ TEST_EQUAL( #{size}(&t), 1 );
43
+ #{element.destroy}(&e);
44
+ }
45
+
46
+ test :push, %{
47
+ #{element} e1, e2;
48
+ #{element.create}(&e1);
49
+ #{element.set}(&e2, -1);
50
+ TEST_FALSE( #{push}(&t, e1) );
51
+ TEST_EQUAL( #{size}(&t), 1 );
52
+ TEST_FALSE( #{push}(&t, e2) );
53
+ TEST_EQUAL( #{size}(&t), 2 );
54
+ TEST_TRUE( #{push}(&t, e1) );
55
+ TEST_EQUAL( #{size}(&t), 2 );
56
+ #{element.destroy}(&e1);
57
+ #{element.destroy}(&e2);
58
+ }
59
+
60
+ end
@@ -0,0 +1,146 @@
1
+ require 'autoc/vector'
2
+
3
+ type_test(AutoC::Vector, :ValueVector, Value) do
4
+
5
+ #
6
+
7
+ setup %{ #{self} t; }
8
+ cleanup %{ #{destroy}(&t); }
9
+
10
+ test :create_smallest, %{
11
+ #{create_size}(&t, 1);
12
+ TEST_EQUAL( #{size}(&t), 1 );
13
+ }
14
+
15
+ test :create_large, %{
16
+ #{create_size}(&t, 1024);
17
+ TEST_EQUAL( #{size}(&t), 1024 );
18
+ }
19
+
20
+ #
21
+
22
+ setup %{
23
+ #{self} t;
24
+ #{element} e;
25
+ int i, c = 3;
26
+ #{create_size}(&t, c);
27
+ for(i = 0; i < c; ++i) {
28
+ #{element.custom_create}(&e, i);
29
+ #{set}(&t, i, e);
30
+ #{element.destroy}(&e);
31
+ }
32
+ }
33
+ cleanup %{ #{destroy}(&t); }
34
+
35
+ test :get, %{
36
+ #{element} e2;
37
+ #{element.custom_create}(&e, 2);
38
+ e2 = #{get}(&t, 2);
39
+ TEST_TRUE( #{element.equal}(e, e2) );
40
+ #{element.destroy}(&e);
41
+ #{element.destroy}(&e2);
42
+ }
43
+
44
+ test :set, %{
45
+ #{element} e2;
46
+ #{element.custom_create}(&e, -1);
47
+ #{set}(&t, 2, e);
48
+ e2 = #{get}(&t, 2);
49
+ TEST_TRUE( #{element.equal}(e, e2) );
50
+ #{element.destroy}(&e);
51
+ #{element.destroy}(&e2);
52
+ }
53
+
54
+ test :check_position, %{
55
+ TEST_TRUE( #{check}(&t, 0) );
56
+ TEST_TRUE( #{check}(&t, 2) );
57
+ TEST_FALSE( #{check}(&t, 3) );
58
+ }
59
+
60
+ test :iterate_forward, %{
61
+ i = 0;
62
+ #{range} r;
63
+ for(#{range.create}(&r, &t); !#{range.empty}(&r); #{range.pop_front}(&r)) {
64
+ e = #{range.take_front}(&r);
65
+ TEST_EQUAL( #{element.get}(e), i++ );
66
+ #{element.destroy}(&e);
67
+ }
68
+ }
69
+
70
+ test :iterate_backward, %{
71
+ i = c-1;
72
+ #{range} r;
73
+ for(#{range.create}(&r, &t); !#{range.empty}(&r); #{range.pop_back}(&r)) {
74
+ e = #{range.take_back}(&r);
75
+ TEST_EQUAL( #{element.get}(e), i-- );
76
+ #{element.destroy}(&e);
77
+ }
78
+ }
79
+
80
+ #
81
+
82
+ setup %{
83
+ #{self} t1, t2;
84
+ #{element} e;
85
+ int i, c = 3;
86
+ #{create_size}(&t1, c);
87
+ #{create_size}(&t2, c);
88
+ TEST_TRUE( #{equal}(&t1, &t2) );
89
+ for(i = 0; i < c; ++i) {
90
+ #{element.custom_create}(&e, i);
91
+ #{set}(&t1, i, e);
92
+ #{set}(&t2, i, e);
93
+ #{element.destroy}(&e);
94
+ }
95
+ TEST_TRUE( #{equal}(&t1, &t2) );
96
+ }
97
+ cleanup %{
98
+ #{destroy}(&t1);
99
+ #{destroy}(&t2);
100
+ }
101
+
102
+ test :size, %{
103
+ TEST_EQUAL( #{size}(&t1), 3 );
104
+ TEST_EQUAL( #{size}(&t1), #{size}(&t2) );
105
+ #{resize}(&t2, 1);
106
+ TEST_EQUAL( #{size}(&t2), 1 );
107
+ TEST_NOT_EQUAL( #{size}(&t1), #{size}(&t2) );
108
+ }
109
+
110
+ test :equal, %{
111
+ #{element.custom_create}(&e, -1);
112
+ #{set}(&t1, 0, e);
113
+ #{element.destroy}(&e);
114
+ TEST_FALSE( #{equal}(&t1, &t2) );
115
+ }
116
+
117
+ test :resize_shrink, %{
118
+ #{resize}(&t2, 2);
119
+ TEST_EQUAL( #{size}(&t2), 2 );
120
+ TEST_FALSE( #{equal}(&t1, &t2) );
121
+ }
122
+
123
+ test :resize_expand, %{
124
+ #{resize}(&t2, 4);
125
+ TEST_EQUAL( #{size}(&t2), 4 );
126
+ TEST_FALSE( #{equal}(&t1, &t2) );
127
+ e = #{get}(&t2, 3);
128
+ TEST_EQUAL( #{element.get}(e), 0 );
129
+ TEST_NOT_EQUAL( #{element.get}(e), 1 );
130
+ #{element.destroy}(&e);
131
+ }
132
+
133
+ test :sort, %{
134
+ #{sort}(&t2, +1);
135
+ TEST_TRUE( #{equal}(&t1, &t2) );
136
+ e = #{get}(&t2, 0);
137
+ TEST_EQUAL( #{element.get}(e), 0 );
138
+ #{element.destroy}(&e);
139
+ #{sort}(&t2, -1);
140
+ TEST_FALSE( #{equal}(&t1, &t2) );
141
+ e = #{get}(&t2, 0);
142
+ TEST_EQUAL( #{element.get}(e), 2 );
143
+ #{element.destroy}(&e);
144
+ }
145
+
146
+ end
@@ -1,158 +1,179 @@
1
- =begin
2
-
3
- This is the AutoC automatic unit test generator.
4
- Usage instruction:
5
-
6
- 1. Generate get test's source code (test_auto.c and test_auto.h):
7
- > ruby -I . -I ../lib test.rb
8
-
9
- 2. Compile the generated code:
10
- > cc test_auto.c
11
-
12
- 3. Run the tests:
13
- > ./a.out
14
-
15
- The code is intended to finish succesfully,
16
- the process' exit code is zero when all tests are passed
17
- ano non-zero if there were failed tests.
18
-
19
- The compile-time warnings are possible and may be ignored.
20
-
21
- The compiled code should also pass the memory leakage tests
22
- (with Valgrind, Dr.Memory etc.)
23
-
24
- =end
25
-
26
- require "autoc"
27
-
28
- Prologue = Class.new(AutoC::Code) do
29
- def write_defs(stream)
30
- stream << %~
31
- #include <stdio.h>
32
- struct {
33
- int total, processed, failed;
34
- } tests;
35
- int failure;
36
- typedef void (*test_func)(void);
37
- void run_test(const char* name, test_func func) {
38
- fprintf(stdout, "| %s\\n", name);
39
- fflush(stdout);
40
- failure = 0;
41
- func();
42
- if(failure) tests.failed++;
43
- tests.processed++;
44
- }
45
- void print_condition_failure(const char* message, const char* condition, const char* file, int line) {
46
- fprintf(stderr, "*** %s : %s (%s:%d)\\n", condition, message, file, line);
47
- fflush(stderr);
48
- failure = 1;
49
- }
50
- void print_equality_failure(const char* message, const char* x, const char* y, const char* file, int line) {
51
- fprintf(stderr, "*** %s == %s : %s (%s:%d)\\n", x, y, message, file, line);
52
- fflush(stderr);
53
- failure = 1;
54
- }
55
- void print_summary(void) {
56
- if(tests.failed)
57
- fprintf(stdout, "*** Failed %d of %d tests\\n", tests.failed, tests.processed);
58
- else
59
- fprintf(stdout, "+++ All %d tests passed successfully\\n", tests.processed);
60
- fflush(stdout);
61
- }
62
- #define TEST_MESSAGE(s) fprintf(stderr, "*** %s\\n", s); fflush(stderr);
63
- #define TEST_ASSERT(x) if(x) {} else print_condition_failure("evaluated to FALSE", #x, __FILE__, __LINE__)
64
- #define TEST_TRUE(x) if(x) {} else print_condition_failure("expected TRUE but got FALSE", #x, __FILE__, __LINE__)
65
- #define TEST_FALSE(x) if(x) print_condition_failure("expected FALSE but got TRUE", #x, __FILE__, __LINE__)
66
- #define TEST_NULL(x) if((x) == NULL) {} else print_condition_failure("expected NULL", #x, __FILE__, __LINE__)
67
- #define TEST_NOT_NULL(x) if((x) == NULL) print_condition_failure("expected not NULL", #x, __FILE__, __LINE__)
68
- #define TEST_EQUAL(x, y) if((x) == (y)) {} else print_equality_failure("expected equality", #x, #y, __FILE__, __LINE__)
69
- #define TEST_NOT_EQUAL(x, y) if((x) == (y)) print_equality_failure("expected non-equality", #x, #y, __FILE__, __LINE__)
70
- #define TEST_EQUAL_CHARS(x, y) if(strcmp(x, y) == 0) {} else print_equality_failure("expected strings equality", #x, #y, __FILE__, __LINE__)
71
- #define TEST_NOT_EQUAL_CHARS(x, y) if(strcmp(x, y) == 0) print_equality_failure("expected strings non-equality", #x, #y, __FILE__, __LINE__)
72
- ~
73
- end
74
- end.new
75
-
76
-
77
- Epilogue = Class.new(AutoC::Code) do
78
- def priority; AutoC::Priority::MIN end
79
- def write_defs(stream)
80
- total = 0
81
- $tests.each {|t| total += t.tests.size}
82
- stream << %~int main(int argc, char** argv) {~
83
- stream << %~
84
- tests.total = #{total};
85
- tests.processed = tests.failed = 0;
86
- ~
87
- $tests.each {|t| t.write_test_calls(stream)}
88
- stream << %~print_summary();~
89
- stream << %~return tests.failed > 0;}~
90
- end
91
- end.new
92
-
93
-
94
- $tests = []
95
-
96
-
97
- def type_test(cls, *opts, &code)
98
- t = Class.new(cls) do
99
- def entities; super << Prologue end
100
- attr_reader :tests
101
- def initialize(*args)
102
- super
103
- @tests = []
104
- @test_names = []
105
- end
106
- def setup(code = nil)
107
- @setup_code = code
108
- end
109
- def cleanup(code = nil)
110
- @cleanup_code = code
111
- end
112
- def test(name, code)
113
- s = name.to_s
114
- @test_names << [name, func_name = eval("test#{s[0,1].upcase}#{s[1..-1]}")]
115
- @tests << %~
116
- void #{func_name}(void) {
117
- #{@setup_code}
118
- #{code}
119
- #{@cleanup_code}
120
- }
121
- ~
122
- end
123
- def write_defs(stream)
124
- super
125
- @tests.each {|f| stream << f}
126
- stream << %~void #{runTests}(void) {~
127
- stream << %~
128
- fprintf(stdout, "* %s\\n", "#{type}");
129
- fflush(stdout);
130
- ~
131
- @test_names.each do |name, func_name|
132
- stream << %~
133
- run_test("#{name}", #{func_name});
134
- ~
135
- end
136
- stream << %~
137
- fputs("\\n", stdout); fflush(stdout);}
138
- ~
139
- end
140
- def write_test_calls(stream)
141
- stream << %$
142
- #{runTests}();
143
- $
144
- end
145
- end.new(*opts)
146
- $tests << t
147
- t.instance_eval(&code)
148
- end
149
-
150
-
151
- Dir["**/test_*.rb"].each {|t| load t}
152
-
153
-
154
- AutoC::Module.generate!(:Test) do |c|
155
- c << Prologue
156
- $tests.each {|t| c << t}
157
- c << Epilogue
158
- end
1
+ =begin
2
+
3
+ This is the AutoC automatic unit test generator.
4
+ Usage instruction:
5
+
6
+ 1. Generate get test's source code (test_auto.c and test_auto.h):
7
+ > ruby -I . -I ../lib tests.rb
8
+
9
+ 2. Compile the generated code:
10
+ > cc test_auto.c
11
+
12
+ 3. Run the tests:
13
+ > ./a.out
14
+
15
+ The code is intended to finish succesfully,
16
+ the process' exit code is zero when all tests are passed
17
+ ano non-zero if there were failed tests.
18
+
19
+ The compile-time warnings are possible and may be ignored.
20
+
21
+ The compiled code should also pass the memory leakage tests
22
+ (with Valgrind, Dr.Memory etc.)
23
+
24
+ =end
25
+
26
+ require 'autoc/module'
27
+
28
+ def type_test(cls, *opts, **kws, &code)
29
+ t = Class.new(cls) do
30
+ attr_reader :tests
31
+ def initialize(*args, **kws)
32
+ super
33
+ @tests = []
34
+ @test_names = []
35
+ dependencies << $common
36
+ end
37
+ def setup(code = nil)
38
+ @setup_code = code
39
+ end
40
+ def cleanup(code = nil)
41
+ @cleanup_code = code
42
+ end
43
+ def test(name, code)
44
+ s = name.to_s
45
+ @test_names << [name, func_name = identifier("test_#{name}")]
46
+ @tests << %{
47
+ void #{func_name}(void) {
48
+ #{@setup_code}
49
+ #{code}
50
+ #{@cleanup_code}
51
+ } /* #{func_name} */
52
+ }
53
+ end
54
+ def render_forward_declarations(stream)
55
+ super
56
+ stream << "void #{run_tests}(void);"
57
+ end
58
+ def render_implementation(stream)
59
+ super
60
+ @tests.each { |f| stream << f }
61
+ stream << "void #{run_tests}(void) {"
62
+ stream << %{
63
+ fprintf(stdout, "* %s\\n", "#{type}");
64
+ fflush(stdout);
65
+ }
66
+ @test_names.each { |name, func_name| stream << %$run_test("#{name}", #{func_name});$ }
67
+ stream << %$fputs("\\n", stdout); fflush(stdout);}$
68
+ end
69
+ def write_test_calls(stream)
70
+ stream << "#{run_tests}();"
71
+ end
72
+ end.new(*opts, **kws)
73
+ $tests << t
74
+ t.instance_eval(&code)
75
+ t
76
+ end
77
+
78
+ $common = Class.new do
79
+
80
+ include AutoC::Entity
81
+
82
+ def render_forward_declarations(stream)
83
+ super
84
+ stream << %{
85
+ #include <stdio.h>
86
+ typedef void (*test_func)(void);
87
+ void run_test(const char* name, test_func func);
88
+ void print_condition_failure(const char* message, const char* condition, const char* file, int line);
89
+ void print_equality_failure(const char* message, const char* x, const char* y, const char* file, int line);
90
+ void print_summary(void);
91
+ #define TEST_MESSAGE(s) fprintf(stderr, "*** %s\\n", s); fflush(stderr);
92
+ #define TEST_ASSERT(x) if(x) {} else print_condition_failure("evaluated to FALSE", #x, __FILE__, __LINE__)
93
+ #define TEST_TRUE(x) if(x) {} else print_condition_failure("expected TRUE but got FALSE", #x, __FILE__, __LINE__)
94
+ #define TEST_FALSE(x) if(x) print_condition_failure("expected FALSE but got TRUE", #x, __FILE__, __LINE__)
95
+ #define TEST_NULL(x) if((x) == NULL) {} else print_condition_failure("expected NULL", #x, __FILE__, __LINE__)
96
+ #define TEST_NOT_NULL(x) if((x) == NULL) print_condition_failure("expected not NULL", #x, __FILE__, __LINE__)
97
+ #define TEST_EQUAL(x, y) if((x) == (y)) {} else print_equality_failure("expected equality", #x, #y, __FILE__, __LINE__)
98
+ #define TEST_NOT_EQUAL(x, y) if((x) == (y)) print_equality_failure("expected non-equality", #x, #y, __FILE__, __LINE__)
99
+ #define TEST_EQUAL_CHARS(x, y) if(strcmp(x, y) == 0) {} else print_equality_failure("expected strings equality", #x, #y, __FILE__, __LINE__)
100
+ #define TEST_NOT_EQUAL_CHARS(x, y) if(strcmp(x, y) == 0) print_equality_failure("expected strings non-equality", #x, #y, __FILE__, __LINE__)
101
+ }
102
+ end
103
+ end.new
104
+
105
+ $suite = Class.new do
106
+
107
+ include AutoC::Entity
108
+
109
+ def initialize = dependencies << $common
110
+
111
+ def render_implementation(stream)
112
+ super
113
+ stream << %{
114
+ #include <stdio.h>
115
+ struct {
116
+ int total, processed, failed;
117
+ } tests;
118
+ int failure;
119
+ void run_test(const char* name, test_func func) {
120
+ fprintf(stdout, "| %s\\n", name);
121
+ fflush(stdout);
122
+ failure = 0;
123
+ func();
124
+ if(failure) tests.failed++;
125
+ tests.processed++;
126
+ }
127
+ void print_condition_failure(const char* message, const char* condition, const char* file, int line) {
128
+ fprintf(stderr, "*** %s : %s (%s:%d)\\n", condition, message, file, line);
129
+ fflush(stderr);
130
+ failure = 1;
131
+ }
132
+ void print_equality_failure(const char* message, const char* x, const char* y, const char* file, int line) {
133
+ fprintf(stderr, "*** %s == %s : %s (%s:%d)\\n", x, y, message, file, line);
134
+ fflush(stderr);
135
+ failure = 1;
136
+ }
137
+ void print_summary(void) {
138
+ if(tests.failed)
139
+ fprintf(stdout, "*** Failed %d of %d tests\\n", tests.failed, tests.processed);
140
+ else
141
+ fprintf(stdout, "+++ All %d tests passed successfully\\n", tests.processed);
142
+ fflush(stdout);
143
+ }
144
+ }
145
+ total = 0
146
+ $tests.each { |t| total += t.tests.size }
147
+ stream << "int main(int argc, char** argv) {"
148
+ stream << %{
149
+ tests.total = #{total};
150
+ tests.processed = tests.failed = 0;
151
+ }
152
+ $tests.each { |t| t.write_test_calls(stream) }
153
+ stream << "print_summary();"
154
+ stream << "return tests.failed > 0;}"
155
+ end
156
+
157
+ end.new
158
+
159
+ $tests = []
160
+
161
+ require 'autoc/composite'
162
+
163
+ #AutoC::Composite.decorator = AutoC::Composite::SNAKE_CASE_DECORATOR
164
+
165
+ require_relative 'generic_value'
166
+
167
+ Value = GenericValue.new(:Value)
168
+
169
+ Dir[File.join(File.dirname(__FILE__), 'test_*.rb')].each { |t| require t }
170
+
171
+ require 'autoc/cmake'
172
+
173
+ x = AutoC::Module.render(:tests) do |m|
174
+ m << $suite
175
+ m.source_threshold = 100*1024 # Split module code into a set of TUs with ~100 Kb in size
176
+ $tests.each { |t| $suite.dependencies << t }
177
+ end
178
+
179
+ AutoC::CMake.render(x)
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # These methods are meant to be used by the one-liners: ruby -r autoc/scaffold -e tests
4
+
5
+ # Generate generated interface reference header to processable with Doxygen
6
+ def docs = require_relative 'scaffold/docs'
7
+
8
+ # Generated test suite
9
+ def tests = require_relative 'scaffold/tests'
10
+
11
+ # Generate skeleton project
12
+ def project = require_relative 'scaffold/project'
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ module AutoC
5
+
6
+
7
+ # Method implementations for types which maintain predictable element order (vector, list, queue etc.)
8
+ module Sequential
9
+
10
+ private
11
+
12
+ def configure
13
+ super
14
+ contains.configure do
15
+ dependencies << find_first
16
+ inline_code %{
17
+ return #{find_first.(*parameters)} != NULL;
18
+ }
19
+ end
20
+ find_first.configure do
21
+ code %{
22
+ #{range} r;
23
+ assert(target);
24
+ for(r = #{range.new.(target)}; !#{range.empty.(:r)}; #{range.pop_front.(:r)}) {
25
+ #{element.const_lvalue} e = #{range.view_front.(:r)};
26
+ if(#{element.equal.('*e', value)}) return e;
27
+ }
28
+ return NULL;
29
+ }
30
+ end
31
+ equal.configure do
32
+ code %{
33
+ assert(left);
34
+ assert(right);
35
+ if(#{size.(left)} == #{size.(right)}) {
36
+ #{range} lr, rr;
37
+ for(
38
+ lr = #{range.new.(left)}, rr = #{range.new.(right)};
39
+ !#{range.empty.(:lr)} && !#{range.empty.(:rr)};
40
+ #{range.pop_front.(:lr)}, #{range.pop_front.(:rr)}
41
+ ) {
42
+ #{element.const_lvalue} le = #{range.view_front.(:lr)};
43
+ #{element.const_lvalue} re = #{range.view_front.(:rr)};
44
+ if(!(#{element.equal.('*le', '*re')})) return 0;
45
+ }
46
+ return 1;
47
+ }
48
+ return 0;
49
+ }
50
+ end
51
+ compare.configure do
52
+ code %{
53
+ size_t remaining, ls, rs;
54
+ #{range} lr, rr;
55
+ assert(left);
56
+ assert(right);
57
+ ls = #{size.(left)};
58
+ rs = #{size.(right)};
59
+ /* comparing common parts */
60
+ for(
61
+ lr = #{range.new.(left)}, rr = #{range.new.(right)}, remaining = ls < rs ? ls : rs; /* min(ls, rs) */
62
+ remaining > 0;
63
+ #{range.pop_front.(:lr)}, #{range.pop_front.(:rr)}, --remaining
64
+ ) {
65
+ #{element.const_lvalue} le = #{range.view_front.(:lr)};
66
+ #{element.const_lvalue} re = #{range.view_front.(:rr)};
67
+ int c = #{element.compare.('*le', '*re')};
68
+ if(c != 0) {
69
+ return c; /* early exit on first non-equal pair encountered */
70
+ }
71
+ }
72
+ if(ls == rs) {
73
+ return 0; /* both vectors are completely equal */
74
+ } else {
75
+ return ls > rs ? +1 : -1; /* the longer sequence of the two with equal common part is considered "the more" */
76
+ }
77
+ }
78
+ end
79
+ hash_code.configure do
80
+ code %{
81
+ #{range} r;
82
+ size_t result;
83
+ #{hasher.to_s} hash;
84
+ #{hasher.create(:hash)};
85
+ for(r = #{range.new.(target)}; !#{range.empty.(:r)}; #{range.pop_front.(:r)}) {
86
+ #{element.const_lvalue} e = #{range.view_front.(:r)};
87
+ #{hasher.update(:hash, element.hash_code.('*e'))};
88
+ }
89
+ result = #{hasher.result(:hash)};
90
+ #{hasher.destroy(:hash)};
91
+ return result;
92
+ }
93
+ end
94
+ end
95
+
96
+ end # Sequential
97
+
98
+
99
+ end