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,293 @@
|
|
1
|
+
# File: Language.rb
|
2
|
+
# Author: Jack Herrington
|
3
|
+
# Purpose: The basic language classes
|
4
|
+
# Date: 12/21/02
|
5
|
+
|
6
|
+
# class : ClassVariable
|
7
|
+
#
|
8
|
+
# A data structure class to store all of the information about the variables
|
9
|
+
# associated with a class
|
10
|
+
|
11
|
+
module LanguageParser
|
12
|
+
class ClassVariable
|
13
|
+
|
14
|
+
# initialize()
|
15
|
+
#
|
16
|
+
# Constructor
|
17
|
+
|
18
|
+
def initialize()
|
19
|
+
|
20
|
+
@name = nil
|
21
|
+
@type = nil
|
22
|
+
@static = false
|
23
|
+
@const = false
|
24
|
+
@visibility = nil
|
25
|
+
@value = nil
|
26
|
+
@comment = ""
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_accessor :name # The name of the variable
|
31
|
+
|
32
|
+
attr_accessor :type # The type of the variable
|
33
|
+
|
34
|
+
attr_accessor :static # True if it's static
|
35
|
+
|
36
|
+
attr_accessor :const # True if it's const
|
37
|
+
|
38
|
+
attr_accessor :visibility # "public", "private" or "protected"
|
39
|
+
|
40
|
+
attr_accessor :value # The value of the variable
|
41
|
+
|
42
|
+
attr_accessor :comment # The comment surrounding the variable
|
43
|
+
|
44
|
+
# to_s()
|
45
|
+
#
|
46
|
+
# Pretty printing the variable
|
47
|
+
|
48
|
+
def to_s()
|
49
|
+
|
50
|
+
text = "#{name} - #{type}"
|
51
|
+
|
52
|
+
text += " - #{@visibility}" if ( @visibility )
|
53
|
+
text += " - const" if ( @const )
|
54
|
+
text += " - static" if ( @static )
|
55
|
+
text += " = #{@value}" if ( @value )
|
56
|
+
|
57
|
+
text
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
# class : LanguageClass
|
64
|
+
#
|
65
|
+
# This is a simple data structure that defines what we know about a given
|
66
|
+
# class. Ruby already has a class named 'Class', so we called this one
|
67
|
+
# 'LanguageClass' to avoid collisions.
|
68
|
+
|
69
|
+
class LanguageClass
|
70
|
+
|
71
|
+
# initialize()
|
72
|
+
#
|
73
|
+
# Constructor
|
74
|
+
|
75
|
+
def initialize()
|
76
|
+
|
77
|
+
@type = "class"
|
78
|
+
@name = ""
|
79
|
+
@comments = ""
|
80
|
+
@parents = []
|
81
|
+
@methods = []
|
82
|
+
@variables = []
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
attr_accessor :type # The type of class (could be interface, or struct)
|
87
|
+
attr_accessor :name # The name of the class
|
88
|
+
attr_reader :methods # The array of methods
|
89
|
+
attr_reader :variables # The array of instance variables (or constants)
|
90
|
+
attr_accessor :comments # The text of any comments
|
91
|
+
attr_reader :parents # An array of parent class names
|
92
|
+
|
93
|
+
# add_method( method )
|
94
|
+
#
|
95
|
+
# method - The method object
|
96
|
+
#
|
97
|
+
# Adds a method
|
98
|
+
|
99
|
+
def add_method( method )
|
100
|
+
@methods.push( method )
|
101
|
+
end
|
102
|
+
|
103
|
+
# add_parent( parent )
|
104
|
+
#
|
105
|
+
# parent - The parent name as text
|
106
|
+
#
|
107
|
+
# Adds a parent class
|
108
|
+
|
109
|
+
def add_parent( parent )
|
110
|
+
@parents.push( parent )
|
111
|
+
end
|
112
|
+
|
113
|
+
# add_variable( variable )
|
114
|
+
#
|
115
|
+
# variable - The variable object
|
116
|
+
#
|
117
|
+
# Adds a variable to the class definition
|
118
|
+
|
119
|
+
def add_variable( variable )
|
120
|
+
@variables.push( variable )
|
121
|
+
end
|
122
|
+
|
123
|
+
# to_s()
|
124
|
+
#
|
125
|
+
# Pretty printing string converter
|
126
|
+
|
127
|
+
def to_s()
|
128
|
+
|
129
|
+
text = "class : #{@name} - "
|
130
|
+
text += @parents.join( ", " )
|
131
|
+
text += "\n"
|
132
|
+
|
133
|
+
text += "Methods:\n"
|
134
|
+
|
135
|
+
methods.each { |method|
|
136
|
+
text += " #{method}\n"
|
137
|
+
}
|
138
|
+
|
139
|
+
text += "Variables:\n"
|
140
|
+
|
141
|
+
variables.each { |var|
|
142
|
+
text += " #{var}\n"
|
143
|
+
}
|
144
|
+
|
145
|
+
text
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
# class : PrototypeComment
|
152
|
+
#
|
153
|
+
# The class represents a comment in the prototype.
|
154
|
+
|
155
|
+
class PrototypeComment
|
156
|
+
|
157
|
+
# initialize()
|
158
|
+
#
|
159
|
+
# Constructs the object
|
160
|
+
|
161
|
+
def initialize() @text = ""; end
|
162
|
+
|
163
|
+
attr_accessor :text # The text of the comment
|
164
|
+
|
165
|
+
# to_s()
|
166
|
+
#
|
167
|
+
# Turns this object into text
|
168
|
+
|
169
|
+
def to_s() @text; end
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
# class : PrototypeArgument
|
174
|
+
#
|
175
|
+
# This class represents arguments on the prototype.
|
176
|
+
|
177
|
+
class PrototypeArgument
|
178
|
+
|
179
|
+
# initialie()
|
180
|
+
#
|
181
|
+
# Constucts the argument object
|
182
|
+
|
183
|
+
def initialize()
|
184
|
+
|
185
|
+
@name = nil
|
186
|
+
@type = nil
|
187
|
+
|
188
|
+
end
|
189
|
+
|
190
|
+
attr_accessor :name # The argument name
|
191
|
+
attr_accessor :type # The argument type
|
192
|
+
|
193
|
+
# to_s()
|
194
|
+
#
|
195
|
+
# Turns this argument into a string
|
196
|
+
|
197
|
+
def to_s() @type ? "#{@name} - #{@type}" : @name; end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
# class : Prototype
|
202
|
+
#
|
203
|
+
# This class stores all of the information about a prototype
|
204
|
+
|
205
|
+
class Prototype
|
206
|
+
|
207
|
+
# initialize()
|
208
|
+
#
|
209
|
+
# Constructs the Prototype object
|
210
|
+
|
211
|
+
def initialize()
|
212
|
+
|
213
|
+
@class_name = nil
|
214
|
+
@method_name = nil
|
215
|
+
@method_type = nil
|
216
|
+
@arguments = []
|
217
|
+
@comments = []
|
218
|
+
@static = false
|
219
|
+
@visibility = nil
|
220
|
+
|
221
|
+
end
|
222
|
+
|
223
|
+
attr_accessor :visibility # Visibility of the method (public, private, etc.)
|
224
|
+
attr_accessor :static # True if the method is static
|
225
|
+
attr_accessor :class_name # The class name
|
226
|
+
attr_accessor :method_name # The name of the method
|
227
|
+
attr_accessor :method_type # The return type of the method
|
228
|
+
attr_reader :arguments # The method arguments
|
229
|
+
attr_reader :comments # Comments associated with the method
|
230
|
+
|
231
|
+
# to_s()
|
232
|
+
#
|
233
|
+
# Returns the object pretty printed as a string
|
234
|
+
|
235
|
+
def to_s()
|
236
|
+
|
237
|
+
text = "#{method_name} - #{method_type} - "
|
238
|
+
text += "( #{@arguments.map{ |arg| arg.to_s }.join(', ')} )"
|
239
|
+
|
240
|
+
text += " - #{@visibility}" if ( @visibility )
|
241
|
+
text += " - static" if ( @static )
|
242
|
+
|
243
|
+
text
|
244
|
+
|
245
|
+
end
|
246
|
+
|
247
|
+
# add_argument( name, type )
|
248
|
+
#
|
249
|
+
# name - The name of the argument
|
250
|
+
# type - The type of the argument
|
251
|
+
#
|
252
|
+
# Adds an argument to the ordered argument list
|
253
|
+
|
254
|
+
def add_argument( name, type = nil )
|
255
|
+
|
256
|
+
arg = PrototypeArgument.new()
|
257
|
+
arg.name = name
|
258
|
+
arg.type = type
|
259
|
+
@arguments.push( arg )
|
260
|
+
|
261
|
+
end
|
262
|
+
|
263
|
+
# add_comment( text )
|
264
|
+
#
|
265
|
+
# text - The text of the comment
|
266
|
+
#
|
267
|
+
# Adds a comment to the prototype
|
268
|
+
|
269
|
+
def add_comment( text )
|
270
|
+
|
271
|
+
comment = PrototypeComment.new()
|
272
|
+
comment.text = text
|
273
|
+
@comments.push( comment )
|
274
|
+
|
275
|
+
end
|
276
|
+
|
277
|
+
end
|
278
|
+
|
279
|
+
# class : LanguageScanner
|
280
|
+
#
|
281
|
+
# This is the base class for scanners which turn tokens streams
|
282
|
+
# into prototypes and other language specific elements.
|
283
|
+
# It is meant to be overridden for each language.
|
284
|
+
|
285
|
+
class LanguageScanner
|
286
|
+
|
287
|
+
def parse( tokens )
|
288
|
+
|
289
|
+
end
|
290
|
+
|
291
|
+
end
|
292
|
+
|
293
|
+
end
|
@@ -0,0 +1,281 @@
|
|
1
|
+
# File: Tokenizer.rb
|
2
|
+
# Author: Jack Herrington
|
3
|
+
# Purpose: The basic tokenizer classes
|
4
|
+
# Date: 12/21/02
|
5
|
+
|
6
|
+
# class : Token
|
7
|
+
#
|
8
|
+
# The base type for all tokens
|
9
|
+
|
10
|
+
module LanguageParser
|
11
|
+
class Token
|
12
|
+
|
13
|
+
# initialize( text )
|
14
|
+
#
|
15
|
+
# text - The text of the token
|
16
|
+
#
|
17
|
+
# Initialieze the token with it's text
|
18
|
+
|
19
|
+
def initialize( text ) @text = text; end
|
20
|
+
|
21
|
+
# to_s()
|
22
|
+
#
|
23
|
+
# Overload of the to-string method to return the text
|
24
|
+
# of the token
|
25
|
+
|
26
|
+
def to_s() @text; end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
# class : CommentToken
|
31
|
+
#
|
32
|
+
# This represents a comment token
|
33
|
+
|
34
|
+
class CommentToken < Token
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
# class : WhitespaceToken
|
39
|
+
#
|
40
|
+
# This represents a string of whitespace within a source file
|
41
|
+
|
42
|
+
class WhitespaceToken < Token
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
# class : CodeToken
|
47
|
+
#
|
48
|
+
# This represents a code fragment within a source file
|
49
|
+
|
50
|
+
class CodeToken < Token
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
# class : Tokenizer
|
55
|
+
#
|
56
|
+
# The base class for all Tokenizers. The Tokenizers are meant to be
|
57
|
+
# specialized to parse the text of various languages into token streams
|
58
|
+
# that consist of CodeToken, WhitespaceToken, and CommentToken objects
|
59
|
+
|
60
|
+
class Tokenizer
|
61
|
+
|
62
|
+
# initialize()
|
63
|
+
#
|
64
|
+
# Constructs the Tokenizer base class
|
65
|
+
|
66
|
+
def initialize( )
|
67
|
+
@tokens = TokenStream.new()
|
68
|
+
end
|
69
|
+
|
70
|
+
attr_reader :tokens # The ordered array of tokens
|
71
|
+
|
72
|
+
# parse( text )
|
73
|
+
#
|
74
|
+
# text - The string of code to be turned into tokens
|
75
|
+
#
|
76
|
+
# This should be overridden by all derived classes. It is
|
77
|
+
# meant to parse the text into tokens. Which should be stored
|
78
|
+
# in @tokens.
|
79
|
+
|
80
|
+
def parse( text )
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
# class : TokenStream
|
86
|
+
#
|
87
|
+
# An array of tokens with many useful helper methods
|
88
|
+
|
89
|
+
class TokenStream < Array
|
90
|
+
|
91
|
+
# initialize()
|
92
|
+
#
|
93
|
+
# Initalizes the array
|
94
|
+
|
95
|
+
def initialize()
|
96
|
+
|
97
|
+
super()
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
# to_s()
|
102
|
+
#
|
103
|
+
# Converts all of the tokens back to text
|
104
|
+
|
105
|
+
def to_s()
|
106
|
+
|
107
|
+
text = ""
|
108
|
+
each { |tok| text += tok.to_s }
|
109
|
+
text
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
# strip!()
|
114
|
+
#
|
115
|
+
# Deletes any leading or trailing whitespace
|
116
|
+
|
117
|
+
def strip!()
|
118
|
+
|
119
|
+
while( first.is_a?( WhitespaceToken ) )
|
120
|
+
shift
|
121
|
+
end
|
122
|
+
while( last.is_a?( WhitespaceToken ) )
|
123
|
+
pop
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
# code_only()
|
129
|
+
#
|
130
|
+
# Returns a new token stream with the code tokens only
|
131
|
+
|
132
|
+
def code_only()
|
133
|
+
|
134
|
+
out = TokenStream.new()
|
135
|
+
|
136
|
+
each { |tok| out.push( tok ) if ( tok.is_a?( CodeToken ) ) }
|
137
|
+
|
138
|
+
out
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
# comments_only()
|
143
|
+
#
|
144
|
+
# Returns a new token stream with the comments only
|
145
|
+
|
146
|
+
def comments_only()
|
147
|
+
|
148
|
+
out = TokenStream.new()
|
149
|
+
|
150
|
+
each { |tok| out.push( tok ) if ( tok.is_a?( CommentToken ) ) }
|
151
|
+
|
152
|
+
out
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
# find_pattern( pattern )
|
157
|
+
#
|
158
|
+
# pattern - A pattern array
|
159
|
+
#
|
160
|
+
# This searches the set of tokens for a pattern of strings. The array should contain
|
161
|
+
# a series of strings and lambdas. In the first pass the pattern finder looks for the
|
162
|
+
# strings. If a match is found the lambdas are called with the token in the original
|
163
|
+
# string for that position.
|
164
|
+
#
|
165
|
+
# For example:
|
166
|
+
#
|
167
|
+
# find_pattern( "primary", "key", "(", lambda { |name| print name }, ")" )
|
168
|
+
#
|
169
|
+
# Would print "myname" if the original sequence was "primary key ( myname )"
|
170
|
+
|
171
|
+
def find_pattern( pattern )
|
172
|
+
|
173
|
+
code = code_only
|
174
|
+
|
175
|
+
delta = ( code.length - pattern.length ) + 1
|
176
|
+
|
177
|
+
delta.times { |start|
|
178
|
+
|
179
|
+
found = true
|
180
|
+
|
181
|
+
pattern.each_index { |index|
|
182
|
+
|
183
|
+
if ( pattern[ index ].is_a?( String ) )
|
184
|
+
|
185
|
+
unless ( pattern[ index ].downcase == code[ start + index ].to_s.downcase )
|
186
|
+
found = false
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
|
191
|
+
}
|
192
|
+
|
193
|
+
next unless ( found )
|
194
|
+
|
195
|
+
pattern.each_index { |index|
|
196
|
+
|
197
|
+
unless ( pattern[ index ].is_a?( String ) )
|
198
|
+
|
199
|
+
pattern[index].call( code[ start + index ].to_s.downcase )
|
200
|
+
|
201
|
+
end
|
202
|
+
|
203
|
+
}
|
204
|
+
|
205
|
+
return true
|
206
|
+
|
207
|
+
}
|
208
|
+
|
209
|
+
false
|
210
|
+
|
211
|
+
end
|
212
|
+
|
213
|
+
# get_comments( start )
|
214
|
+
#
|
215
|
+
# start - The start index
|
216
|
+
#
|
217
|
+
# This method looks backwards from the starting index to find all of the
|
218
|
+
# comments and to put them together into a comment stream. It stops if it
|
219
|
+
# finds new CodeTokens.
|
220
|
+
|
221
|
+
def get_comments( start )
|
222
|
+
|
223
|
+
commentStream = TokenStream.new()
|
224
|
+
|
225
|
+
index = start - 1
|
226
|
+
|
227
|
+
while ( index > -1 )
|
228
|
+
|
229
|
+
break if ( at( index ).is_a?( CodeToken ) )
|
230
|
+
|
231
|
+
commentStream.unshift( at( index ) )
|
232
|
+
|
233
|
+
index -= 1
|
234
|
+
|
235
|
+
end
|
236
|
+
|
237
|
+
comments = commentStream.map { |tok| tok.to_s }.join( "" )
|
238
|
+
|
239
|
+
comments
|
240
|
+
|
241
|
+
end
|
242
|
+
|
243
|
+
# find( code_value )
|
244
|
+
#
|
245
|
+
# code_value - The code token text as a string
|
246
|
+
#
|
247
|
+
# This finds a CodeToken with the same text as the input (case insensitive)
|
248
|
+
# and returns the index.
|
249
|
+
|
250
|
+
def find( code_value )
|
251
|
+
|
252
|
+
each_index { |index|
|
253
|
+
|
254
|
+
next unless ( at( index ).is_a?( CodeToken ) )
|
255
|
+
|
256
|
+
return index if ( at( index ).to_s.downcase == code_value.to_s.downcase )
|
257
|
+
|
258
|
+
}
|
259
|
+
|
260
|
+
nil
|
261
|
+
|
262
|
+
end
|
263
|
+
|
264
|
+
# find_and_remove( code_value )
|
265
|
+
#
|
266
|
+
# code_value - The code token text as a string
|
267
|
+
#
|
268
|
+
# This is the same as find, but it removes the item. It returns true if it
|
269
|
+
# found something and false if not.
|
270
|
+
|
271
|
+
def find_and_remove( code_value )
|
272
|
+
|
273
|
+
index = find( code_value )
|
274
|
+
|
275
|
+
delete_at( index ) if ( index != nil )
|
276
|
+
|
277
|
+
( index == nil ) ? false : true
|
278
|
+
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
data/lib/cgialib/lp.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
require 'lp/Language'
|
4
|
+
require 'lp/Tokenizer'
|
5
|
+
require 'lp/CTokenizer'
|
6
|
+
require 'lp/CLanguageScanner'
|
7
|
+
require 'lp/CPPLanguageScanner'
|
8
|
+
module LanguageParser
|
9
|
+
VERSION = '0.0.1'
|
10
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module CGIA_UT_Template
|
2
|
+
C_UT_TEMPLATE = <<'EOF'
|
3
|
+
/*
|
4
|
+
* ==========================================================================
|
5
|
+
* WARNING: This code has been generated by 'testgen'. Any modifications
|
6
|
+
* you make to it will be lost when it is regenerated.
|
7
|
+
* ==========================================================================
|
8
|
+
*/
|
9
|
+
static int run_tests()
|
10
|
+
{
|
11
|
+
<%
|
12
|
+
prototypes.each { |proto|
|
13
|
+
name = proto.method_name
|
14
|
+
proto.tests.each { |test|
|
15
|
+
values = []
|
16
|
+
proto.arguments.each { |arg|
|
17
|
+
values.push( test.arguments[ arg.name.to_s ] )
|
18
|
+
}
|
19
|
+
args = values.join( ", " )
|
20
|
+
result = test.result
|
21
|
+
test_name = test.name
|
22
|
+
%>
|
23
|
+
if ( <%= name %>( <%= args %> ) != <%= result %> )
|
24
|
+
{
|
25
|
+
printf( stderr, "Unit test <%= test_name %> failed!\n" );
|
26
|
+
return 0;
|
27
|
+
}
|
28
|
+
<%
|
29
|
+
}
|
30
|
+
}
|
31
|
+
%>
|
32
|
+
return 1;
|
33
|
+
}
|
34
|
+
/*
|
35
|
+
* ==========================================================================
|
36
|
+
* WARNING: This code has been generated by 'testgen'. Any modifications
|
37
|
+
* you make to it will be lost when it is regenerated.
|
38
|
+
* ==========================================================================
|
39
|
+
*/
|
40
|
+
EOF
|
41
|
+
end
|