langscan 1.2-x86-mswin32-60

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 (180) hide show
  1. data/AUTHORS.txt +19 -0
  2. data/History.txt +126 -0
  3. data/Manifest.txt +167 -0
  4. data/README.rdoc +91 -0
  5. data/Rakefile +40 -0
  6. data/ext/langscan/_make_c.rb +20 -0
  7. data/ext/langscan/_make_h.rb +30 -0
  8. data/ext/langscan/_template.c +134 -0
  9. data/ext/langscan/_template.h +53 -0
  10. data/ext/langscan/c/c/Makefile +188 -0
  11. data/ext/langscan/c/c/c.c +134 -0
  12. data/ext/langscan/c/c/c.h +66 -0
  13. data/ext/langscan/c/c/ctok.c +4629 -0
  14. data/ext/langscan/c/c/ctok.l +212 -0
  15. data/ext/langscan/c/c/extconf.rb +3 -0
  16. data/ext/langscan/c/c/modulename.txt +1 -0
  17. data/ext/langscan/c/c/tokenlist.txt +13 -0
  18. data/ext/langscan/csharp/csharp/Makefile +188 -0
  19. data/ext/langscan/csharp/csharp/csharp.c +134 -0
  20. data/ext/langscan/csharp/csharp/csharp.h +65 -0
  21. data/ext/langscan/csharp/csharp/csharptok.c +2971 -0
  22. data/ext/langscan/csharp/csharp/csharptok.l +200 -0
  23. data/ext/langscan/csharp/csharp/extconf.rb +3 -0
  24. data/ext/langscan/csharp/csharp/modulename.txt +1 -0
  25. data/ext/langscan/csharp/csharp/tokenlist.txt +12 -0
  26. data/ext/langscan/d/d/Makefile +188 -0
  27. data/ext/langscan/d/d/d.c +134 -0
  28. data/ext/langscan/d/d/d.h +64 -0
  29. data/ext/langscan/d/d/dtok.c +5468 -0
  30. data/ext/langscan/d/d/dtok.l +282 -0
  31. data/ext/langscan/d/d/extconf.rb +3 -0
  32. data/ext/langscan/d/d/modulename.txt +1 -0
  33. data/ext/langscan/d/d/tokenlist.txt +11 -0
  34. data/ext/langscan/elisp/elisp/Makefile +188 -0
  35. data/ext/langscan/elisp/elisp/elisp.c +134 -0
  36. data/ext/langscan/elisp/elisp/elisp.h +62 -0
  37. data/ext/langscan/elisp/elisp/elisptok.c +2108 -0
  38. data/ext/langscan/elisp/elisp/elisptok.l +151 -0
  39. data/ext/langscan/elisp/elisp/extconf.rb +3 -0
  40. data/ext/langscan/elisp/elisp/modulename.txt +1 -0
  41. data/ext/langscan/elisp/elisp/tokenlist.txt +9 -0
  42. data/ext/langscan/java/java/Makefile +188 -0
  43. data/ext/langscan/java/java/extconf.rb +3 -0
  44. data/ext/langscan/java/java/java.c +134 -0
  45. data/ext/langscan/java/java/java.h +64 -0
  46. data/ext/langscan/java/java/javatok.c +2097 -0
  47. data/ext/langscan/java/java/javatok.l +155 -0
  48. data/ext/langscan/java/java/modulename.txt +1 -0
  49. data/ext/langscan/java/java/tokenlist.txt +11 -0
  50. data/ext/langscan/javascript/javascript/Makefile +188 -0
  51. data/ext/langscan/javascript/javascript/extconf.rb +3 -0
  52. data/ext/langscan/javascript/javascript/javascript.c +134 -0
  53. data/ext/langscan/javascript/javascript/javascript.h +63 -0
  54. data/ext/langscan/javascript/javascript/javascripttok.c +2058 -0
  55. data/ext/langscan/javascript/javascript/javascripttok.l +147 -0
  56. data/ext/langscan/javascript/javascript/modulename.txt +1 -0
  57. data/ext/langscan/javascript/javascript/tokenlist.txt +10 -0
  58. data/ext/langscan/pairmatcher/pairmatcher/Makefile +188 -0
  59. data/ext/langscan/pairmatcher/pairmatcher/extconf.rb +3 -0
  60. data/ext/langscan/pairmatcher/pairmatcher/pairmatcher.c +890 -0
  61. data/ext/langscan/php/php/Makefile +188 -0
  62. data/ext/langscan/php/php/extconf.rb +3 -0
  63. data/ext/langscan/php/php/modulename.txt +1 -0
  64. data/ext/langscan/php/php/php.c +134 -0
  65. data/ext/langscan/php/php/php.h +64 -0
  66. data/ext/langscan/php/php/phptok.c +2413 -0
  67. data/ext/langscan/php/php/phptok.l +212 -0
  68. data/ext/langscan/php/php/tokenlist.txt +11 -0
  69. data/ext/langscan/post-distclean.rb +21 -0
  70. data/ext/langscan/pre-config.rb +57 -0
  71. data/ext/langscan/python/python/Makefile +188 -0
  72. data/ext/langscan/python/python/extconf.rb +3 -0
  73. data/ext/langscan/python/python/modulename.txt +1 -0
  74. data/ext/langscan/python/python/python.c +134 -0
  75. data/ext/langscan/python/python/python.h +61 -0
  76. data/ext/langscan/python/python/pythontok.c +2109 -0
  77. data/ext/langscan/python/python/pythontok.l +155 -0
  78. data/ext/langscan/python/python/tokenlist.txt +8 -0
  79. data/ext/langscan/ruby/compat/ripper/Makefile +189 -0
  80. data/ext/langscan/ruby/compat/ripper/depend +1 -0
  81. data/ext/langscan/ruby/compat/ripper/extconf.rb +4 -0
  82. data/ext/langscan/ruby/compat/ripper/include/eventids1.c +251 -0
  83. data/ext/langscan/ruby/compat/ripper/include/eventids2.c +277 -0
  84. data/ext/langscan/ruby/compat/ripper/include/lex.c +138 -0
  85. data/ext/langscan/ruby/compat/ripper/ripper.c +14420 -0
  86. data/ext/langscan/scheme/scheme/Makefile +188 -0
  87. data/ext/langscan/scheme/scheme/extconf.rb +3 -0
  88. data/ext/langscan/scheme/scheme/modulename.txt +1 -0
  89. data/ext/langscan/scheme/scheme/scheme.c +134 -0
  90. data/ext/langscan/scheme/scheme/scheme.h +60 -0
  91. data/ext/langscan/scheme/scheme/schemetok.c +2454 -0
  92. data/ext/langscan/scheme/scheme/schemetok.l +177 -0
  93. data/ext/langscan/scheme/scheme/tokenlist.txt +7 -0
  94. data/ext/langscan/sh/sh/Makefile +188 -0
  95. data/ext/langscan/sh/sh/extconf.rb +3 -0
  96. data/ext/langscan/sh/sh/modulename.txt +1 -0
  97. data/ext/langscan/sh/sh/sh.c +134 -0
  98. data/ext/langscan/sh/sh/sh.h +61 -0
  99. data/ext/langscan/sh/sh/shtok.c +2477 -0
  100. data/ext/langscan/sh/sh/shtok.l +325 -0
  101. data/ext/langscan/sh/sh/tokenlist.txt +8 -0
  102. data/lib/langscan.rb +124 -0
  103. data/lib/langscan/_common.rb +50 -0
  104. data/lib/langscan/_easyscanner.rb +78 -0
  105. data/lib/langscan/_pairmatcher.rb +46 -0
  106. data/lib/langscan/_type.rb +125 -0
  107. data/lib/langscan/autoconf.rb +51 -0
  108. data/lib/langscan/automake.rb +51 -0
  109. data/lib/langscan/brainfuck.rb +48 -0
  110. data/lib/langscan/c.rb +144 -0
  111. data/lib/langscan/c/c.so +0 -0
  112. data/lib/langscan/csharp.rb +101 -0
  113. data/lib/langscan/csharp/csharp.so +0 -0
  114. data/lib/langscan/css.rb +109 -0
  115. data/lib/langscan/d.rb +201 -0
  116. data/lib/langscan/d/d.so +0 -0
  117. data/lib/langscan/eiffel.rb +167 -0
  118. data/lib/langscan/elisp.rb +132 -0
  119. data/lib/langscan/elisp/elisp.so +0 -0
  120. data/lib/langscan/io.rb +84 -0
  121. data/lib/langscan/java.rb +95 -0
  122. data/lib/langscan/java/java.so +0 -0
  123. data/lib/langscan/javascript.rb +97 -0
  124. data/lib/langscan/javascript/javascript.so +0 -0
  125. data/lib/langscan/lua.rb +116 -0
  126. data/lib/langscan/ocaml.rb +298 -0
  127. data/lib/langscan/ocaml/camlexer.ml +28 -0
  128. data/lib/langscan/ocaml/lexer.mll +230 -0
  129. data/lib/langscan/ocaml/types.ml +36 -0
  130. data/lib/langscan/pairmatcher/pairmatcher.so +0 -0
  131. data/lib/langscan/perl.rb +87 -0
  132. data/lib/langscan/perl/tokenizer.pl +231 -0
  133. data/lib/langscan/php.rb +80 -0
  134. data/lib/langscan/php/php.so +0 -0
  135. data/lib/langscan/python.rb +101 -0
  136. data/lib/langscan/python/python.so +0 -0
  137. data/lib/langscan/rpmspec.rb +71 -0
  138. data/lib/langscan/ruby.rb +164 -0
  139. data/lib/langscan/ruby/compat/README +5 -0
  140. data/lib/langscan/ruby/compat/ripper.rb +4 -0
  141. data/lib/langscan/ruby/compat/ripper.so +0 -0
  142. data/lib/langscan/ruby/compat/ripper/core.rb +918 -0
  143. data/lib/langscan/ruby/compat/ripper/filter.rb +70 -0
  144. data/lib/langscan/ruby/compat/ripper/lexer.rb +179 -0
  145. data/lib/langscan/ruby/compat/ripper/sexp.rb +100 -0
  146. data/lib/langscan/scheme.rb +160 -0
  147. data/lib/langscan/scheme/scheme.so +0 -0
  148. data/lib/langscan/sh.rb +116 -0
  149. data/lib/langscan/sh/sh.so +0 -0
  150. data/lib/langscan/text.rb +37 -0
  151. data/metaconfig +2 -0
  152. data/script/console +10 -0
  153. data/script/destroy +14 -0
  154. data/script/generate +14 -0
  155. data/script/makemanifest.rb +21 -0
  156. data/setup.rb +1604 -0
  157. data/tasks/extconf.rake +13 -0
  158. data/tasks/extconf/langscan.rake +42 -0
  159. data/test/langscan/brainfuck/test/test_scan.rb +55 -0
  160. data/test/langscan/c/test/test_scan.rb +216 -0
  161. data/test/langscan/c/test/test_token.rb +41 -0
  162. data/test/langscan/csharp/test/test_scan.rb +157 -0
  163. data/test/langscan/css/test/test_css.rb +79 -0
  164. data/test/langscan/d/test/test_scan.rb +233 -0
  165. data/test/langscan/d/test/test_token.rb +205 -0
  166. data/test/langscan/eiffel/test/test_eiffel.rb +95 -0
  167. data/test/langscan/elisp/test/test_elisp.rb +177 -0
  168. data/test/langscan/io/test/test_io.rb +79 -0
  169. data/test/langscan/java/test/test_java.rb +74 -0
  170. data/test/langscan/javascript/test/test_javascript.rb +39 -0
  171. data/test/langscan/lua/test/test_lua.rb +69 -0
  172. data/test/langscan/ocaml/test/test_ocaml.rb +161 -0
  173. data/test/langscan/php/test/test_scan.rb +138 -0
  174. data/test/langscan/python/test/test_scan.rb +105 -0
  175. data/test/langscan/rpmspec/test/test_rpmspec.rb +51 -0
  176. data/test/langscan/ruby/test/test_scan.rb +71 -0
  177. data/test/langscan/scheme/test/test_scan.rb +198 -0
  178. data/test/test_helper.rb +7 -0
  179. data/test/test_langscan.rb +123 -0
  180. metadata +320 -0
@@ -0,0 +1,13 @@
1
+ namespace :extconf do
2
+ desc "Compiles the Ruby extension"
3
+ task :compile
4
+ end
5
+
6
+ task :compile => "extconf:compile"
7
+
8
+ task :test => :compile
9
+
10
+ BIN = "*.{bundle,jar,so,obj,pdb,lib,def,exp}"
11
+ $hoe.clean_globs |= ["ext/**/#{BIN}", "lib/**/#{BIN}", 'ext/**/Makefile']
12
+ $hoe.spec.require_paths = Dir['{lib,ext/*}']
13
+ $hoe.spec.extensions = FileList["ext/**/extconf.rb"].to_a
@@ -0,0 +1,42 @@
1
+ namespace :extconf do
2
+ extension = File.basename(__FILE__, '.rake')
3
+ ext_confs = Dir.glob("**/extconf.rb")
4
+
5
+ task :compile => :compile_all do
6
+ if Dir.glob("**/*.{o,so,dll,bundle}").length == 0
7
+ STDERR.puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
8
+ STDERR.puts "Gem actually failed to build. Your system is"
9
+ STDERR.puts "NOT configured properly to build langscan."
10
+ STDERR.puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
11
+ exit(1)
12
+ end
13
+ end
14
+
15
+ task :compile_all do
16
+ oks = []
17
+ ngs = []
18
+ ext_confs.each do |ext_conf|
19
+ _ext = File.dirname(ext_conf)
20
+ lang_name = File.basename(_ext)
21
+ Dir.chdir(_ext) do
22
+ ruby "extconf.rb"
23
+ sh(PLATFORM =~ /win32/ ? 'nmake' : 'make') do |ok, res|
24
+ if !ok
25
+ require "fileutils"
26
+ FileUtils.rm Dir.glob('*.{so,o,dll,bundle}')
27
+ ngs << lang_name
28
+ else
29
+ oks << lang_name
30
+ end
31
+ end
32
+ end
33
+ end
34
+ oks.each do |lang_name|
35
+ STDOUT.puts "#{lang_name}: SUCCESS"
36
+ end
37
+ ngs.each do |lang_name|
38
+ STDERR.puts "#{lang_name}: FAILED"
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,55 @@
1
+ require 'test/unit'
2
+ require 'langscan/brainfuck'
3
+
4
+ class TestScan < Test::Unit::TestCase
5
+ def assert_yield(recv, meth, *args)
6
+ yielded = false
7
+ recv.__send__(meth, *args) {|*block_args|
8
+ yielded = true
9
+ yield(*block_args)
10
+ }
11
+ assert(yielded, "block not yielded")
12
+ end
13
+
14
+ def assert_not_yield(recv, meth, *args)
15
+ yielded = false
16
+ recv.__send__(meth, *args) {|*block_args|
17
+ assert(false, "block yielded")
18
+ }
19
+ end
20
+
21
+ def assert_yield_any(recv, meth, *args)
22
+ success = false
23
+ recv.__send__(meth, *args) {|*block_args|
24
+ if yield(*block_args)
25
+ assert(true)
26
+ success = true
27
+ break
28
+ end
29
+ }
30
+ assert(false, "no expected yields") unless success
31
+ end
32
+
33
+ def assert_yield_all(recv, meth, *args)
34
+ recv.__send__(meth, *args) {|*block_args|
35
+ if !yield(*block_args)
36
+ assert(false, "unexpected yields")
37
+ return
38
+ end
39
+ }
40
+ assert(true)
41
+ end
42
+
43
+ def test_scan
44
+ assert_yield_all(LangScan::Brainfuck, :scan, "+-.,<>[]") {|f|
45
+ f.type == :ident && f.text.length==1
46
+ }
47
+ assert_yield_all(LangScan::Brainfuck, :scan, "+++") {|f|
48
+ f.type == :ident && f.text.length==1
49
+ }
50
+ assert_yield_all(LangScan::Brainfuck, :scan, "I love you") {|f|
51
+ f.type == :comment
52
+ }
53
+ end
54
+ end
55
+
@@ -0,0 +1,216 @@
1
+ require 'test/unit'
2
+ require 'langscan/c'
3
+
4
+ class TestScan < Test::Unit::TestCase
5
+ def assert_yield(recv, meth, *args)
6
+ yielded = false
7
+ recv.__send__(meth, *args) {|*block_args|
8
+ yielded = true
9
+ yield(*block_args)
10
+ }
11
+ assert(yielded, "block not yielded")
12
+ end
13
+
14
+ def assert_not_yield(recv, meth, *args)
15
+ yielded = false
16
+ recv.__send__(meth, *args) {|*block_args|
17
+ assert(false, "block yielded")
18
+ }
19
+ end
20
+
21
+ def test_token_position
22
+ assert_yield(LangScan::C, :scan, "a(1,2,3)") {|f|
23
+ next if f.type != :funcall
24
+ assert_equal(0, f.beg_byteno)
25
+ #assert_equal(1, f.end_byteno)
26
+ }
27
+ end
28
+
29
+ def assert_yield_any(recv, meth, *args)
30
+ success = false
31
+ recv.__send__(meth, *args) {|*block_args|
32
+ if yield(*block_args)
33
+ assert(true)
34
+ success = true
35
+ break
36
+ end
37
+ }
38
+ assert(false, "no expected yields") unless success
39
+ end
40
+
41
+ def assert_yield_all(recv, meth, *args)
42
+ recv.__send__(meth, *args) {|*block_args|
43
+ if !yield(*block_args)
44
+ assert(false, "unexpected yields")
45
+ return
46
+ end
47
+ }
48
+ assert(true)
49
+ end
50
+
51
+ def test_name
52
+ assert_yield_any(LangScan::C, :scan, "a()") {|f|
53
+ f.type == :funcall && f.text == 'a'
54
+ }
55
+ end
56
+
57
+ def test_macro
58
+ assert_yield_any(LangScan::C, :scan, "#define a() b") {|f|
59
+ f.type == :fundef
60
+ }
61
+ assert_yield_all(LangScan::C, :scan, "#define a () b") {|f|
62
+ f.type != :fundef
63
+ }
64
+ end
65
+
66
+ def test_funtype
67
+ assert_yield_all(LangScan::C, :scan, "int fun(type (*)())") {|f|
68
+ !(f.type == :fundef || f.type == :funcall || f.type == :fundecl) ||
69
+ f.text == 'fun'
70
+ }
71
+ end
72
+
73
+ def test_decl
74
+ assert_yield_any(LangScan::C, :scan, "int f();") {|f|
75
+ f.type == :fundecl && f.text == 'f'
76
+ }
77
+ end
78
+
79
+ def test_preproc_defined
80
+ assert_yield_all(LangScan::C, :scan, "#if defined(MACRO)\n") {|f|
81
+ !(f.type == :funcall && f.text == 'defined')
82
+ }
83
+ end
84
+
85
+ def test_fragment_and_function
86
+ regions = {}
87
+ LangScan::C.scan("a()") {|t|
88
+ f = t
89
+ f = f.name_token if f.respond_to? :name_token
90
+ r = f.beg_byteno
91
+ assert(!regions.include?(r), "duplicate token: #{regions[r].inspect} and #{t.inspect}")
92
+ regions[r] = t
93
+ }
94
+ end
95
+
96
+ def test_kandr_portability_fundecl
97
+ src = "void rbuf_initialize PARAMS ((struct rbuf *, int));"
98
+ result = []
99
+ assert_yield(LangScan::C, :scan, src) {|f|
100
+ if f.type == :fundecl && f.text == 'rbuf_initialize'
101
+ result << :rbuf_initialize
102
+ end
103
+ if f.type == :funcall && f.text == 'PARAMS'
104
+ result << :PARAMS
105
+ end
106
+ }
107
+ assert_equal([:rbuf_initialize], result)
108
+ end
109
+
110
+ def test_funcdef
111
+ [
112
+ "int fun() {}",
113
+ "int fun(void) {}",
114
+ "int fun(int arg) {}",
115
+ "int fun(arg) int arg; {}",
116
+ "int fun(arg) struct tag *arg; {}",
117
+ "int fun(arg) typedefed_ident arg; {}",
118
+ ].each {|src|
119
+ result = false
120
+ assert_yield(LangScan::C, :scan, src) {|f|
121
+ if f.type == :fundef && f.text == 'fun'
122
+ result = true
123
+ end
124
+ }
125
+ assert(result, src)
126
+ }
127
+ end
128
+
129
+ def test_extern_c
130
+ src = 'extern "C" { void fun(); }'
131
+ assert_yield_any(LangScan::C, :scan, src) {|f|
132
+ f.type == :fundecl && f.text == 'fun'
133
+ }
134
+ end
135
+
136
+ def test_keyword
137
+ assert_yield_all(LangScan::C, :scan, "int()") {|f|
138
+ f.type != :funcall
139
+ }
140
+ end
141
+
142
+ def test_toplevel_comma
143
+ assert_yield(LangScan::C, :scan, ",") {|f|
144
+ assert_equal(LangScan::Fragment, f.class)
145
+ assert_equal(:punct, f.type)
146
+ assert_equal(",", f.text)
147
+ }
148
+ end
149
+
150
+ def test_funcall
151
+ result = []
152
+ LangScan::C.scan("f(){g();}") {|f|
153
+ next unless f.type == :fundef || f.type == :funcall
154
+ result << [f.type, f.text]
155
+ }
156
+ assert_equal([[:fundef, 'f'], [:funcall, 'g']], result)
157
+ end
158
+
159
+ # C++
160
+
161
+ def assert_fragment_type(type, text, src)
162
+ found = false
163
+ LangScan::C.scan(src) {|f|
164
+ if f.text == text
165
+ if found
166
+ raise "token #{text} occurred twice"
167
+ else
168
+ found = true
169
+ assert_equal(type, f.type, "fragment type of #{text}")
170
+ end
171
+ end
172
+ }
173
+ unless found
174
+ raise "token #{text} not found"
175
+ end
176
+ end
177
+
178
+ def test_class
179
+ assert_fragment_type(:classdef, 'c', "class c {};")
180
+ assert_fragment_type(:classdef, 'c1', "class c1 : c2 {};")
181
+ assert_fragment_type(:classref, 'c2', "class c1 : c2 {};")
182
+ assert_fragment_type(:classdecl, 'c3', "class c3;")
183
+ end
184
+
185
+ def test_struct
186
+ assert_fragment_type(:classdef, 'c', "struct c {};")
187
+ assert_fragment_type(:classdef, 'c1', "struct c1 : c2 {};")
188
+ assert_fragment_type(:classref, 'c2', "struct c1 : c2 {};")
189
+ assert_fragment_type(:classdecl, 'c3', "struct c3;")
190
+ end
191
+
192
+ def test_struct_2
193
+ src = 'void f(void) { struct s v; return; }'
194
+ assert_fragment_type(:classref, 's', src)
195
+ assert_fragment_type(:keyword, 'return', src)
196
+ end
197
+
198
+ def check_scan(src)
199
+ LangScan::C.scan(src) {|f|
200
+ assert_equal(f.text, src[f.beg_byteno...f.end_byteno])
201
+ }
202
+ end
203
+
204
+ def test_sharp_in_non_initial_state
205
+ check_scan("struct x\n#;")
206
+ end
207
+
208
+ def test_invalid_escape_sequence
209
+ assert_fragment_type(:string, '"\w"', '"\w"')
210
+ assert_fragment_type(:string, '"foo\bar.h"', '#include "foo\bar.h"')
211
+ end
212
+
213
+ def test_fundef_returns_user_defined_type
214
+ assert_fragment_type(:fundef, 'foo', 'VALUE foo() {}')
215
+ end
216
+ end
@@ -0,0 +1,41 @@
1
+ require 'test/unit'
2
+ require 'langscan/c'
3
+
4
+ class TestToken < Test::Unit::TestCase
5
+ def test_comment
6
+ t = LangScan::C::Tokenizer.new("/* * */")
7
+ type, text = t.get_token
8
+ assert_equal("/* * */", text)
9
+ assert_equal(:comment, type)
10
+ assert_equal(nil, t.get_token)
11
+
12
+ t = LangScan::C::Tokenizer.new("/* **/")
13
+ type, text = t.get_token
14
+ assert_equal("/* **/", text)
15
+ assert_equal(:comment, type)
16
+ assert_equal(nil, t.get_token)
17
+ end
18
+
19
+ def test_c99_comment
20
+ t = LangScan::C::Tokenizer.new("// abc")
21
+ type, text = t.get_token
22
+ assert_equal("// abc", text)
23
+ assert_equal(:comment, type)
24
+ assert_equal(nil, t.get_token)
25
+
26
+ t = LangScan::C::Tokenizer.new("//")
27
+ type, text = t.get_token
28
+ assert_equal("//", text)
29
+ assert_equal(:comment, type)
30
+ assert_equal(nil, t.get_token)
31
+
32
+ t = LangScan::C::Tokenizer.new("//def \n")
33
+ type, text = t.get_token
34
+ assert_equal("//def ", text)
35
+ assert_equal(:comment, type)
36
+ type, text = t.get_token
37
+ assert_equal("\n", text)
38
+ assert_equal(:space, type)
39
+ assert_equal(nil, t.get_token)
40
+ end
41
+ end
@@ -0,0 +1,157 @@
1
+ require 'test/unit'
2
+ require 'langscan/csharp'
3
+
4
+ class TestCsharp < Test::Unit::TestCase
5
+ def assert_yield(recv, meth, *args)
6
+ yielded = false
7
+ recv.__send__(meth, *args) {|*block_args|
8
+ yielded = true
9
+ yield(*block_args)
10
+ }
11
+ assert(yielded, "block not yielded")
12
+ end
13
+
14
+ def assert_not_yield(recv, meth, *args)
15
+ yielded = false
16
+ recv.__send__(meth, *args) {|*block_args|
17
+ assert(false, "block yielded")
18
+ }
19
+ end
20
+
21
+ def test_token_position
22
+ assert_yield(LangScan::Csharp, :scan, "a(1,2,3)") {|f|
23
+ next if f.type != :funcall
24
+ assert_equal(0, f.beg_byteno)
25
+ }
26
+ end
27
+
28
+ def assert_yield_any(recv, meth, *args)
29
+ success = false
30
+ recv.__send__(meth, *args) {|*block_args|
31
+ if yield(*block_args)
32
+ assert(true)
33
+ success = true
34
+ break
35
+ end
36
+ }
37
+ assert(false, "no expected yields") unless success
38
+ end
39
+
40
+ def assert_yield_all(recv, meth, *args)
41
+ recv.__send__(meth, *args) {|*block_args|
42
+ if !yield(*block_args)
43
+ assert(false, "unexpected yields")
44
+ return
45
+ end
46
+ }
47
+ assert(true)
48
+ end
49
+
50
+ def test_name
51
+ assert_yield_any(LangScan::Csharp, :scan, "a()") {|f|
52
+ f.type == :funcall && f.text == 'a'
53
+ }
54
+ end
55
+
56
+
57
+ def test_delegate
58
+ assert_yield_any(LangScan::Csharp, :scan, "delegate int f();") {|f|
59
+ f.type == :ident && f.text == 'f'
60
+ }
61
+ end
62
+
63
+
64
+ def test_fragment_and_function
65
+ regions = {}
66
+ LangScan::Csharp.scan("a()") {|t|
67
+ f = t
68
+ f = f.name_token if f.respond_to? :name_token
69
+ r = f.beg_byteno
70
+ assert(!regions.include?(r), "duplicate token: #{regions[r].inspect} and #{t.inspect}")
71
+ regions[r] = t
72
+ }
73
+ end
74
+
75
+ def test_funcdef
76
+ [
77
+ "int fun() {}",
78
+ "int fun(int arg) {}",
79
+ "public static void fun() {}",
80
+ "int fun() /* comment */ {}",
81
+ "int fun() // comment\n {}",
82
+ ].each {|src|
83
+ result = false
84
+ assert_yield(LangScan::Csharp, :scan, src) {|f|
85
+ if f.type == :fundef && f.text == 'fun'
86
+ result = true
87
+ end
88
+ }
89
+ assert(result, src)
90
+ }
91
+ end
92
+
93
+ def test_keyword
94
+ assert_yield_all(LangScan::Csharp, :scan, "int()") {|f|
95
+ f.type != :funcall
96
+ }
97
+ end
98
+
99
+ def test_funcall
100
+ result = []
101
+ LangScan::Csharp.scan("f(){g();}") {|f|
102
+ next unless f.type == :fundef || f.type == :funcall
103
+ result << [f.type, f.text]
104
+ }
105
+ assert_equal([[:fundef, 'f'], [:funcall, 'g']], result)
106
+ end
107
+
108
+ def assert_fragment_type(type, text, src)
109
+ found = false
110
+ LangScan::Csharp.scan(src) {|f|
111
+ if f.text == text
112
+ if found
113
+ raise "token #{text} occurred twice"
114
+ else
115
+ found = true
116
+ assert_equal(type, f.type, "fragment type of #{text}")
117
+ end
118
+ end
119
+ }
120
+ unless found
121
+ raise "token #{text} not found"
122
+ end
123
+ end
124
+
125
+ def test_class
126
+ assert_fragment_type(:classdef, 'c', "class c {};")
127
+ assert_fragment_type(:classdef, 'c1', "class c1 : c2 {};")
128
+ assert_fragment_type(:classref, 'c2', "class c1 : c2 {};")
129
+ assert_fragment_type(:classref, 'c4', "class c1 : c2.c3.c4 {};")
130
+ end
131
+
132
+ def test_struct
133
+ assert_fragment_type(:classdef, 'c', "struct c {};")
134
+ assert_fragment_type(:classdef, 'c1', "struct c1 : c2 {};")
135
+ assert_fragment_type(:classref, 'c2', "struct c1 : c2 {};")
136
+ end
137
+
138
+ def check_scan(src)
139
+ LangScan::Csharp.scan(src) {|f|
140
+ assert_equal(f.text, src[f.beg_byteno...f.end_byteno])
141
+ }
142
+ end
143
+
144
+ def test_sharp_in_non_initial_state
145
+ check_scan("struct x\n#;")
146
+ end
147
+
148
+ def test_invalid_escape_sequence
149
+ assert_fragment_type(:string, '"\w"', '"\w"')
150
+ assert_fragment_type(:string, '"foo\bar.h"', 'str = "foo\bar.h"')
151
+ end
152
+
153
+ def test_fundef_returns_user_defined_type
154
+ assert_fragment_type(:fundef, 'foo', 'VALUE foo() {}')
155
+ end
156
+
157
+ end