cgialib 0.0.1
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.
- data/History.txt +4 -0
- data/Manifest.txt +35 -0
- data/PostInstall.txt +7 -0
- data/README.rdoc +49 -0
- data/Rakefile +28 -0
- data/bin/testgen +10 -0
- data/config/website.yml.sample +2 -0
- data/features/development.feature +13 -0
- data/features/steps/common.rb +174 -0
- data/features/steps/env.rb +6 -0
- data/lib/cgialib/lp/CLanguageScanner.rb +446 -0
- data/lib/cgialib/lp/CPPLanguageScanner.rb +326 -0
- data/lib/cgialib/lp/CTokenizer.rb +481 -0
- data/lib/cgialib/lp/Language.rb +293 -0
- data/lib/cgialib/lp/Tokenizer.rb +281 -0
- data/lib/cgialib/lp.rb +10 -0
- data/lib/cgialib/template/ut/c.rb +41 -0
- data/lib/cgialib/template/ut.rb +6 -0
- data/lib/cgialib/template.rb +6 -0
- data/lib/cgialib.rb +9 -0
- data/lib/testgen/cli.rb +210 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +82 -0
- data/spec/cgialib_spec.rb +11 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/testgen_cli_spec.rb +15 -0
- data/tasks/rspec.rake +21 -0
- data/website/index.html +86 -0
- data/website/index.txt +79 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +159 -0
- data/website/template.html.erb +50 -0
- metadata +112 -0
@@ -0,0 +1,326 @@
|
|
1
|
+
# File: CPPLanguageScanner.rb
|
2
|
+
# Author: Jack Herrington
|
3
|
+
# Purpose: The CPPLanguageScanner object specialized to look for C++ language
|
4
|
+
# features.
|
5
|
+
# Date: 12/21/02
|
6
|
+
|
7
|
+
#require "Tokenizer"
|
8
|
+
#require "CLanguageScanner"
|
9
|
+
|
10
|
+
module LanguageParser
|
11
|
+
# Class : CPPLanguageScanner
|
12
|
+
#
|
13
|
+
# The scanner specialized for processing C++ headers.
|
14
|
+
|
15
|
+
class CPPLanguageScanner < CLanguageScanner
|
16
|
+
|
17
|
+
# initialize()
|
18
|
+
#
|
19
|
+
# Constructs the scanner object
|
20
|
+
|
21
|
+
def initialize()
|
22
|
+
|
23
|
+
super()
|
24
|
+
|
25
|
+
@classes = []
|
26
|
+
|
27
|
+
@prototypeClass = Prototype
|
28
|
+
@variableClass = ClassVariable
|
29
|
+
@languageClass = LanguageClass
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
attr_reader :classes # The classes found
|
34
|
+
|
35
|
+
attr_accessor :languageClass # The class to use when building class objects
|
36
|
+
|
37
|
+
attr_accessor :variableClass # The class to use when building variable objects
|
38
|
+
|
39
|
+
# parse( tokens )
|
40
|
+
#
|
41
|
+
# tokens - Tokens returned from CTokenizer
|
42
|
+
#
|
43
|
+
# Parses the tokens read from the CTokenizer
|
44
|
+
|
45
|
+
def parse( tokens )
|
46
|
+
|
47
|
+
# Handle the function prototypes in the base class
|
48
|
+
|
49
|
+
super( tokens )
|
50
|
+
|
51
|
+
# Set up the code buffer
|
52
|
+
|
53
|
+
codefrag = TokenStream.new()
|
54
|
+
|
55
|
+
# Set up the state machine flags
|
56
|
+
|
57
|
+
has_class = false
|
58
|
+
found_open = false
|
59
|
+
level = 0
|
60
|
+
comments = ""
|
61
|
+
|
62
|
+
# Look through the tokens for classes, and build up the full class bodies
|
63
|
+
# in codefrag. Then send the codefrags on to parse_class
|
64
|
+
|
65
|
+
tokens.each_index { |index|
|
66
|
+
|
67
|
+
tok = tokens[ index ]
|
68
|
+
|
69
|
+
if ( has_class )
|
70
|
+
|
71
|
+
comments = tokens.get_comments( index )
|
72
|
+
|
73
|
+
codefrag.push( tok )
|
74
|
+
|
75
|
+
if ( tok.to_s == "{" )
|
76
|
+
|
77
|
+
level += 1
|
78
|
+
|
79
|
+
found_open = true
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
level -= 1 if ( tok.to_s == "}" )
|
84
|
+
|
85
|
+
if ( tok.to_s == ";" && level == 0 )
|
86
|
+
|
87
|
+
parse_class( codefrag, comments ) if ( codefrag.length > 0 && found_open )
|
88
|
+
|
89
|
+
codefrag = TokenStream.new()
|
90
|
+
|
91
|
+
has_class = false
|
92
|
+
found_open = false
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
has_class = true if ( tok.to_s.downcase == "class" && level == 0 )
|
99
|
+
|
100
|
+
}
|
101
|
+
|
102
|
+
parse_class( codefrag, comments ) if ( codefrag.length > 0 && found_open )
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
# to_s()
|
107
|
+
#
|
108
|
+
# A pretty printer for the object
|
109
|
+
|
110
|
+
def to_s()
|
111
|
+
|
112
|
+
text = ""
|
113
|
+
|
114
|
+
classes.each { |cpp_class| text += cpp_class.to_s }
|
115
|
+
|
116
|
+
text
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
protected
|
121
|
+
|
122
|
+
# parse_class( codefrag, comments )
|
123
|
+
#
|
124
|
+
# codefrag - The class tokens
|
125
|
+
# comments - The comments before the class
|
126
|
+
#
|
127
|
+
# Parse the class tokens to find methods, instance variables, constants,
|
128
|
+
# etc.
|
129
|
+
|
130
|
+
def parse_class( codefrag, comments )
|
131
|
+
|
132
|
+
class_data = build_class()
|
133
|
+
|
134
|
+
proto = TokenStream.new()
|
135
|
+
|
136
|
+
level = 0
|
137
|
+
|
138
|
+
visibility = "public"
|
139
|
+
|
140
|
+
comments = TokenStream.new()
|
141
|
+
|
142
|
+
codefrag.each { |tok|
|
143
|
+
|
144
|
+
break if ( tok.to_s == "}" && level == 1 )
|
145
|
+
|
146
|
+
if ( level == 0 )
|
147
|
+
|
148
|
+
next if tok.to_s == ":" || tok.to_s == "public"
|
149
|
+
next if tok.to_s == "private" || tok.to_s == ","
|
150
|
+
|
151
|
+
next unless tok.is_a?( CodeToken )
|
152
|
+
|
153
|
+
if ( class_data.name.length == 0 )
|
154
|
+
|
155
|
+
class_data.name = tok.to_s
|
156
|
+
|
157
|
+
else
|
158
|
+
|
159
|
+
class_data.add_parent( tok.to_s ) unless ( tok.to_s == "{" )
|
160
|
+
|
161
|
+
end
|
162
|
+
|
163
|
+
else
|
164
|
+
|
165
|
+
if ( tok.to_s =~ /^public$/ )
|
166
|
+
|
167
|
+
visibility = "public"
|
168
|
+
comments = TokenStream.new()
|
169
|
+
proto = TokenStream.new()
|
170
|
+
|
171
|
+
elsif ( tok.to_s =~ /^private$/ )
|
172
|
+
|
173
|
+
visibility = "private"
|
174
|
+
comments = TokenStream.new()
|
175
|
+
proto = TokenStream.new()
|
176
|
+
|
177
|
+
elsif ( tok.to_s =~ /^protected$/ )
|
178
|
+
|
179
|
+
visibility = "protected"
|
180
|
+
comments = TokenStream.new()
|
181
|
+
proto = TokenStream.new()
|
182
|
+
|
183
|
+
elsif ( tok.is_a?( CommentToken ) )
|
184
|
+
|
185
|
+
comments.push( tok ) if ( level == 1 )
|
186
|
+
|
187
|
+
elsif ( tok.to_s == ":" && level == 1 )
|
188
|
+
|
189
|
+
elsif ( tok.to_s == ";" && level == 1 )
|
190
|
+
|
191
|
+
parse_method_prototype( class_data, visibility, proto, comments ) if proto.length > 0
|
192
|
+
comments = TokenStream.new()
|
193
|
+
proto = TokenStream.new()
|
194
|
+
|
195
|
+
elsif ( level == 1 )
|
196
|
+
|
197
|
+
proto.push( tok )
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
|
203
|
+
if ( tok.to_s == "{" )
|
204
|
+
|
205
|
+
parse_method_prototype( class_data, visibility, proto, comments ) if proto.length > 0
|
206
|
+
comments = TokenStream.new()
|
207
|
+
|
208
|
+
level += 1
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
}
|
213
|
+
|
214
|
+
@classes.push( class_data )
|
215
|
+
|
216
|
+
end
|
217
|
+
|
218
|
+
# parse_method_prototype( class_data, visibility, codefrag, comment )
|
219
|
+
#
|
220
|
+
# class_data - The current class object
|
221
|
+
# visibility - 'private', 'protected', or 'public'
|
222
|
+
# codefrag - The tokens of the prototype
|
223
|
+
# comment - The comments before the method declaration
|
224
|
+
|
225
|
+
def parse_method_prototype( class_data, visibility, codefrag, comment )
|
226
|
+
|
227
|
+
# Get down to just the code, no comments or whitespace
|
228
|
+
|
229
|
+
code = codefrag.code_only
|
230
|
+
|
231
|
+
# The primary switch is whether this is a method or an instance variable.
|
232
|
+
# That's decided on the existence of the paren.
|
233
|
+
|
234
|
+
if ( code.find( "(" ) )
|
235
|
+
|
236
|
+
# Get the prototype
|
237
|
+
|
238
|
+
proto = parse_prototype( codefrag, comment )
|
239
|
+
|
240
|
+
# Add in the visibility
|
241
|
+
|
242
|
+
proto.visibility = visibility
|
243
|
+
|
244
|
+
# Check for a static method
|
245
|
+
|
246
|
+
if ( proto.method_type =~ /^static/ )
|
247
|
+
|
248
|
+
proto.method_type.sub!( /^static\s+/, "" )
|
249
|
+
proto.static = true
|
250
|
+
|
251
|
+
end
|
252
|
+
|
253
|
+
# Add this method into the class
|
254
|
+
|
255
|
+
class_data.add_method( proto )
|
256
|
+
|
257
|
+
else
|
258
|
+
|
259
|
+
# Build the variable object
|
260
|
+
|
261
|
+
varItem = build_class_variable()
|
262
|
+
|
263
|
+
# Parse the declaration
|
264
|
+
|
265
|
+
varSpec = parse_declaration( codefrag )
|
266
|
+
|
267
|
+
# Look for static
|
268
|
+
|
269
|
+
static = false
|
270
|
+
if ( varSpec[ 'type' ] =~ /^static/ )
|
271
|
+
|
272
|
+
varSpec[ 'type' ].sub!( /^static\s+/, "" )
|
273
|
+
static = true
|
274
|
+
|
275
|
+
end
|
276
|
+
|
277
|
+
# Look for const
|
278
|
+
|
279
|
+
if ( varSpec[ 'type' ] =~ /^const/ )
|
280
|
+
|
281
|
+
varSpec[ 'type' ].sub!( /^const\s+/, "" )
|
282
|
+
const = true
|
283
|
+
|
284
|
+
end
|
285
|
+
|
286
|
+
# Fill the fields of the object mainly with the return from
|
287
|
+
# parse_declaration
|
288
|
+
|
289
|
+
varItem.name = varSpec[ 'name' ]
|
290
|
+
varItem.type = varSpec[ 'type' ]
|
291
|
+
varItem.value = varSpec[ 'value' ]
|
292
|
+
varItem.static = static
|
293
|
+
varItem.const = const
|
294
|
+
varItem.visibility = visibility
|
295
|
+
varItem.comment = comment
|
296
|
+
|
297
|
+
# Add the variable to the class
|
298
|
+
|
299
|
+
class_data.add_variable( varItem )
|
300
|
+
|
301
|
+
end
|
302
|
+
|
303
|
+
end
|
304
|
+
|
305
|
+
# build_class_variable()
|
306
|
+
#
|
307
|
+
# Returns a new class variable object
|
308
|
+
|
309
|
+
def build_class_variable
|
310
|
+
|
311
|
+
@variableClass.new()
|
312
|
+
|
313
|
+
end
|
314
|
+
|
315
|
+
# build_class()
|
316
|
+
#
|
317
|
+
# REturns a new class object
|
318
|
+
|
319
|
+
def build_class
|
320
|
+
|
321
|
+
@languageClass.new()
|
322
|
+
|
323
|
+
end
|
324
|
+
|
325
|
+
end
|
326
|
+
end
|