dbc 1.2.1 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/dbcparse.rb +46 -37
- data/lib/dbc/ctokenizer.rb +5 -4
- data/lib/dbc/ctype.rb +3 -3
- data/lib/dbc/define.rb +2 -2
- data/lib/dbc/ocl.rb +2 -2
- data/lib/dbc/parameters.rb +2 -2
- data/lib/dbc/preprocessor.rb +53 -24
- data/lib/dbc/searchpath.rb +33 -15
- metadata +2 -2
data/bin/dbcparse.rb
CHANGED
@@ -42,7 +42,7 @@ opts = GetoptLong.new(
|
|
42
42
|
[ "--output", "-o", GetoptLong::REQUIRED_ARGUMENT ],
|
43
43
|
# cc compatibility options
|
44
44
|
[ "--define", "-D", GetoptLong::REQUIRED_ARGUMENT ],
|
45
|
-
[ "--include", "-I", GetoptLong::
|
45
|
+
[ "--include", "-I", GetoptLong::OPTIONAL_ARGUMENT ]
|
46
46
|
)
|
47
47
|
|
48
48
|
# initialize with defaults
|
@@ -50,6 +50,7 @@ dest_file = nil
|
|
50
50
|
src_file = nil
|
51
51
|
search_path = SearchPath.new
|
52
52
|
defines = []
|
53
|
+
search_usr_include = true
|
53
54
|
|
54
55
|
always_output = false
|
55
56
|
check_level = nil
|
@@ -70,10 +71,15 @@ begin
|
|
70
71
|
end
|
71
72
|
when "--include"
|
72
73
|
# should support including file in the future
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
74
|
+
if arg
|
75
|
+
begin
|
76
|
+
search_path.unshift(arg)
|
77
|
+
rescue
|
78
|
+
opts.error($!)
|
79
|
+
end
|
80
|
+
else
|
81
|
+
# -I with no argument means don't search /usr/include
|
82
|
+
search_usr_include = false
|
77
83
|
end
|
78
84
|
when "--define"
|
79
85
|
unless arg =~ /\A([A-Za-z_]\w*)(?:\(([\w,\s]*)\))?(?:=(.*))?\Z/
|
@@ -168,12 +174,32 @@ else
|
|
168
174
|
end
|
169
175
|
|
170
176
|
### Compatibility with various compilers ###
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
177
|
+
|
178
|
+
# the following are added to the end of the search path
|
179
|
+
if search_usr_include
|
180
|
+
if File.exists?('/usr/include')
|
181
|
+
search_path << '/usr/include'
|
182
|
+
# search for /usr/lib/gcc*/<system>/<version>/include
|
183
|
+
Dir['/usr/lib/gcc*/*/*/include'].each do |gcc_inc|
|
184
|
+
search_path << gcc_inc if File.directory?(gcc_inc)
|
185
|
+
end
|
186
|
+
else
|
187
|
+
if env_include = ENV['INCLUDE']
|
188
|
+
env_include.split(';').each do |p|
|
189
|
+
# any anci c installation should have stdlib.h or stdio.h
|
190
|
+
if File.exists?(File.join(p, 'stdlib.h'))
|
191
|
+
search_path << p
|
192
|
+
end
|
193
|
+
end # each
|
194
|
+
end
|
195
|
+
end # if File.exists?('/usr/include')
|
176
196
|
end
|
197
|
+
|
198
|
+
search_path_limited = search_path.dup
|
199
|
+
# Add directory of file to the begining of the search_path
|
200
|
+
# search_path_limited does not include the directory of the file being parsed
|
201
|
+
search_path.unshift( src_file ? File.dirname(src_file) : '.' )
|
202
|
+
|
177
203
|
case RUBY_PLATFORM
|
178
204
|
when /i[0-9]86|cygwin|mingw/
|
179
205
|
defines << ['__i386__', nil, nil]
|
@@ -181,8 +207,11 @@ case RUBY_PLATFORM
|
|
181
207
|
# experiance may vary :)
|
182
208
|
defines << ['__GLIBC_HAVE_LONG_LONG', nil, '1']
|
183
209
|
defines << ['__extension__', nil, ' ']
|
210
|
+
defines << ['__inline__', nil, ' ']
|
184
211
|
when /powerpc|darwin/
|
185
212
|
defines << ['__ppc__', nil, nil]
|
213
|
+
else
|
214
|
+
warn "unrecognized platform: #{RUBY_PLATFORM}"
|
186
215
|
end
|
187
216
|
# for gcc 3.4+ compatibility
|
188
217
|
defines << ['__builtin_va_list', nil, 'int *']
|
@@ -191,9 +220,6 @@ defines << ['SHLIB_COMPAT', ['arg'], '(0)']
|
|
191
220
|
defines << ['__STDC__', nil, '1']
|
192
221
|
#############################################
|
193
222
|
|
194
|
-
# included files
|
195
|
-
includes = {}
|
196
|
-
|
197
223
|
# Cache Tokens => Preprocessor => Parse OCL => Parse C Types
|
198
224
|
# Cached tokens are output.
|
199
225
|
if not docs and check_level == DBC::NONE
|
@@ -204,17 +230,10 @@ else
|
|
204
230
|
out_str = DBC.parse_docs(CTokenizer::Lexer.new(text, src_file))
|
205
231
|
elsif preprocess_only
|
206
232
|
out_str = ''
|
207
|
-
preproc = Preprocessor::Parser.new(
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
begin
|
212
|
-
File.open(search_path.find(f)) { |in_f| includes[f] = in_f.read }
|
213
|
-
rescue ArgumentError
|
214
|
-
preproc.error($!)
|
215
|
-
end
|
216
|
-
end
|
217
|
-
end
|
233
|
+
preproc = Preprocessor::Parser.new( search_path,
|
234
|
+
search_path_limited,
|
235
|
+
text, src_file )
|
236
|
+
|
218
237
|
defines.each { |d,p,v| preproc.define(d, p, v) }
|
219
238
|
preproc.each do |t|
|
220
239
|
out_str << t[1]
|
@@ -224,20 +243,10 @@ else
|
|
224
243
|
# cache statements
|
225
244
|
cache = DBC::Cache.new(text, src_file)
|
226
245
|
# preprocesses all tokens
|
227
|
-
preproc = Preprocessor::Parser.new(cache)
|
228
|
-
|
229
|
-
if inc_text = includes[f]
|
230
|
-
inc_text
|
231
|
-
else
|
232
|
-
begin
|
233
|
-
File.open(search_path.find(f)) { |in_f| includes[f] = in_f.read }
|
234
|
-
rescue ArgumentError
|
235
|
-
preproc.error($!)
|
236
|
-
end
|
237
|
-
end
|
238
|
-
end
|
246
|
+
preproc = Preprocessor::Parser.new(search_path, search_path_limited, cache)
|
247
|
+
|
239
248
|
# define tokens passed
|
240
|
-
defines.each { |d
|
249
|
+
defines.each { |d| preproc.define(*d) }
|
241
250
|
|
242
251
|
# extracts DBC condtions
|
243
252
|
source = DBC::OCLParser.new(preproc)
|
data/lib/dbc/ctokenizer.rb
CHANGED
@@ -40,10 +40,10 @@ module CTokenizer
|
|
40
40
|
#FLOAT = %r(#{FLOAT_1}|#{FLOAT_2}|#{FLOAT_3})
|
41
41
|
FLOAT = %r(#{FLOAT_1}|#{FLOAT_2})
|
42
42
|
|
43
|
-
i_s = /[
|
44
|
-
INTEGER_1 = /0[xX][0-9a-fA-F]+#{i_s}
|
45
|
-
INTEGER_2 = /0[0-7]+#{i_s}
|
46
|
-
INTEGER_3 = /[0-9]+#{i_s}
|
43
|
+
i_s = /[uUlL]*/
|
44
|
+
INTEGER_1 = /0[xX][0-9a-fA-F]+#{i_s}/
|
45
|
+
INTEGER_2 = /0[0-7]+#{i_s}/
|
46
|
+
INTEGER_3 = /[0-9]+#{i_s}/
|
47
47
|
INTEGER = %r(#{INTEGER_1}|#{INTEGER_2}|#{INTEGER_3})
|
48
48
|
end # Expression
|
49
49
|
|
@@ -146,6 +146,7 @@ module CTokenizer
|
|
146
146
|
when m = scan(Expression::COMMENT)
|
147
147
|
@line += CTokenizer.line_count(m)
|
148
148
|
[:COMMENT, m]
|
149
|
+
# SYMBOL should come before INTEGER and FLOAT
|
149
150
|
when m = scan(Expression::SYMBOL)
|
150
151
|
[:SYMBOL, m]
|
151
152
|
when m = scan(Expression::NEWLINE)
|
data/lib/dbc/ctype.rb
CHANGED
@@ -69,7 +69,7 @@ module CType
|
|
69
69
|
|
70
70
|
def CType.[]=(val, new_val)
|
71
71
|
raise "expecting a String got #{val.class}" if val.class != String
|
72
|
-
raise "type #{val} already defined" if @@typedefs.include?(val)
|
72
|
+
raise ParseError, "type #{val} already defined" if @@typedefs.include?(val)
|
73
73
|
@@typedefs[val] = new_val
|
74
74
|
end
|
75
75
|
|
@@ -601,7 +601,7 @@ module CType
|
|
601
601
|
|
602
602
|
class Parser < Racc::Parser
|
603
603
|
|
604
|
-
module_eval <<'..end src/ctype.y modeval..
|
604
|
+
module_eval <<'..end src/ctype.y modeval..idcee92c23da', 'src/ctype.y', 1137
|
605
605
|
|
606
606
|
def parse(str, file=nil, line=1)
|
607
607
|
@tokens = CTokenizer::CLexer.new(str, file, line)
|
@@ -640,7 +640,7 @@ protected
|
|
640
640
|
t
|
641
641
|
end
|
642
642
|
|
643
|
-
..end src/ctype.y modeval..
|
643
|
+
..end src/ctype.y modeval..idcee92c23da
|
644
644
|
|
645
645
|
##### racc 1.4.4 generates ###
|
646
646
|
|
data/lib/dbc/define.rb
CHANGED
@@ -16,7 +16,7 @@ module Preprocessor
|
|
16
16
|
|
17
17
|
class Define < Racc::Parser
|
18
18
|
|
19
|
-
module_eval <<'..end src/define.y modeval..
|
19
|
+
module_eval <<'..end src/define.y modeval..idbc0a52f69c', 'src/define.y', 75
|
20
20
|
|
21
21
|
def initialize(params, tokens)
|
22
22
|
if params and not params.class == Parameters
|
@@ -87,7 +87,7 @@ protected
|
|
87
87
|
@q.shift
|
88
88
|
end
|
89
89
|
|
90
|
-
..end src/define.y modeval..
|
90
|
+
..end src/define.y modeval..idbc0a52f69c
|
91
91
|
|
92
92
|
##### racc 1.4.4 generates ###
|
93
93
|
|
data/lib/dbc/ocl.rb
CHANGED
@@ -413,7 +413,7 @@ module OCL
|
|
413
413
|
|
414
414
|
class Parser < Racc::Parser
|
415
415
|
|
416
|
-
module_eval <<'..end src/ocl.y modeval..
|
416
|
+
module_eval <<'..end src/ocl.y modeval..ida1d027bef5', 'src/ocl.y', 849
|
417
417
|
|
418
418
|
def Parser.reserved_word?(str)
|
419
419
|
str =~ /\A(?:context|forall|exists|in|and|or|implies|not|xor)\Z/
|
@@ -511,7 +511,7 @@ protected
|
|
511
511
|
t
|
512
512
|
end
|
513
513
|
|
514
|
-
..end src/ocl.y modeval..
|
514
|
+
..end src/ocl.y modeval..ida1d027bef5
|
515
515
|
|
516
516
|
##### racc 1.4.4 generates ###
|
517
517
|
|
data/lib/dbc/parameters.rb
CHANGED
@@ -72,7 +72,7 @@ module Preprocessor
|
|
72
72
|
|
73
73
|
class ArgumentParser < Racc::Parser
|
74
74
|
|
75
|
-
module_eval <<'..end src/parameters.y modeval..
|
75
|
+
module_eval <<'..end src/parameters.y modeval..id008fb4e411', 'src/parameters.y', 144
|
76
76
|
|
77
77
|
def ArgumentParser.parse(tokens)
|
78
78
|
self.new.parse(tokens)
|
@@ -103,7 +103,7 @@ protected
|
|
103
103
|
end # case
|
104
104
|
end
|
105
105
|
|
106
|
-
..end src/parameters.y modeval..
|
106
|
+
..end src/parameters.y modeval..id008fb4e411
|
107
107
|
|
108
108
|
##### racc 1.4.4 generates ###
|
109
109
|
|
data/lib/dbc/preprocessor.rb
CHANGED
@@ -118,22 +118,34 @@ module Preprocessor
|
|
118
118
|
end
|
119
119
|
end # Resolve
|
120
120
|
|
121
|
+
module FileMacro
|
122
|
+
def FileMacro.takes_args?; false end
|
123
|
+
def FileMacro.value(source); source.file.dup end
|
124
|
+
end
|
125
|
+
|
126
|
+
module LineMacro
|
127
|
+
def LineMacro.takes_args?; false end
|
128
|
+
def LineMacro.value(source); source.line.to_s end
|
129
|
+
end
|
130
|
+
|
121
131
|
class Parser < CTokenizer::LexerBase
|
122
132
|
|
123
133
|
include CTokenizer
|
124
134
|
include Resolve
|
125
135
|
|
126
|
-
def initialize(source, file=nil, line=1
|
127
|
-
@upon_include = upon_include
|
136
|
+
def initialize(search_path, search_path_limited, source, file=nil, line=1)
|
128
137
|
if source.class <= String
|
129
138
|
source = CTokenizer::Lexer.new(source, file, line)
|
130
139
|
end
|
140
|
+
|
141
|
+
@search_path = search_path
|
142
|
+
@search_path_limited = search_path_limited
|
131
143
|
|
132
144
|
@cond_comp = [true] # conditional compile is true at base
|
133
145
|
|
134
146
|
@source = Tokens.new(source)
|
135
147
|
@macro_tokens = CTokenizer::Lexer.new('', file, line)
|
136
|
-
@defines = {}
|
148
|
+
@defines = { '__FILE__' => FileMacro, '__LINE__' => LineMacro }
|
137
149
|
@resolving = {}
|
138
150
|
|
139
151
|
@parser = StatementParser.new(@defines)
|
@@ -190,7 +202,24 @@ module Preprocessor
|
|
190
202
|
end
|
191
203
|
|
192
204
|
protected
|
193
|
-
EMPTY_TOKEN = [:SPACE, ''].freeze
|
205
|
+
EMPTY_TOKEN = [:SPACE, ''.freeze].freeze
|
206
|
+
|
207
|
+
def include_file(file)
|
208
|
+
path = begin
|
209
|
+
if file =~ /\A"(.*)"\Z/
|
210
|
+
yield($1, @search_path)
|
211
|
+
elsif file =~ /\A<(.*)>\Z/
|
212
|
+
yield($1, @search_path_limited)
|
213
|
+
else
|
214
|
+
raise "impossible"
|
215
|
+
end
|
216
|
+
rescue ArgumentError
|
217
|
+
self.error($!)
|
218
|
+
end
|
219
|
+
str = File.open(path) { |f| f.read }
|
220
|
+
# could use *path* instead of *file* to give more info
|
221
|
+
@source.add_source( CTokenizer::Lexer.new(str, file) )
|
222
|
+
end
|
194
223
|
|
195
224
|
# @macro_tokens is empty when we parse a statement
|
196
225
|
def parse_statement
|
@@ -218,12 +247,13 @@ protected
|
|
218
247
|
self.undef(result[1])
|
219
248
|
when :INCLUDE
|
220
249
|
# note: we don't keep track of recursive includes
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
250
|
+
include_file(result[1]) do |f, search_path|
|
251
|
+
search_path.find(f)
|
252
|
+
end
|
253
|
+
when :INCLUDE_NEXT
|
254
|
+
include_file(result[1]) do |f, search_path|
|
255
|
+
search_path.find_next(f)
|
225
256
|
end
|
226
|
-
@source.add_source(str) if str
|
227
257
|
when :PRAGMA
|
228
258
|
# ignore
|
229
259
|
when :ERROR
|
@@ -259,10 +289,6 @@ protected
|
|
259
289
|
end # if
|
260
290
|
when :CLOSE
|
261
291
|
@cond_comp.pop
|
262
|
-
# for debugging
|
263
|
-
#when :IGNORE
|
264
|
-
#else
|
265
|
-
# raise "impossible"
|
266
292
|
end # case
|
267
293
|
|
268
294
|
# eat rest of line unless token is a newline
|
@@ -283,7 +309,7 @@ module Preprocessor
|
|
283
309
|
|
284
310
|
class StatementParser < Racc::Parser
|
285
311
|
|
286
|
-
module_eval <<'..end src/preprocessor.y modeval..
|
312
|
+
module_eval <<'..end src/preprocessor.y modeval..idb767efdc5e', 'src/preprocessor.y', 734
|
287
313
|
|
288
314
|
include Resolve
|
289
315
|
|
@@ -301,6 +327,14 @@ module_eval <<'..end src/preprocessor.y modeval..id895fa9d1fa', 'src/preprocesso
|
|
301
327
|
@defines.member?(t)
|
302
328
|
end
|
303
329
|
|
330
|
+
def file
|
331
|
+
@source.file
|
332
|
+
end
|
333
|
+
|
334
|
+
def line
|
335
|
+
@source.line
|
336
|
+
end
|
337
|
+
|
304
338
|
def parse_ignore(tokens, ignore_all)
|
305
339
|
@source = CTokenizer::CPLexer.new(tokens)
|
306
340
|
|
@@ -349,7 +383,7 @@ protected
|
|
349
383
|
@macro_tokens
|
350
384
|
end .scan(/.*?>/) # NOT multiline
|
351
385
|
raise ParseError, "expecting '>'" unless f
|
352
|
-
f
|
386
|
+
"<#{f}"
|
353
387
|
end
|
354
388
|
|
355
389
|
# next_ignore and next_ignore_all are used to output the first token
|
@@ -414,7 +448,7 @@ protected
|
|
414
448
|
t
|
415
449
|
end
|
416
450
|
|
417
|
-
..end src/preprocessor.y modeval..
|
451
|
+
..end src/preprocessor.y modeval..idb767efdc5e
|
418
452
|
|
419
453
|
##### racc 1.4.4 generates ###
|
420
454
|
|
@@ -482,7 +516,7 @@ racc_reduce_table = [
|
|
482
516
|
2, 67, :_reduce_60,
|
483
517
|
1, 87, :_reduce_61,
|
484
518
|
1, 87, :_reduce_62,
|
485
|
-
1, 88, :
|
519
|
+
1, 88, :_reduce_none,
|
486
520
|
1, 88, :_reduce_64,
|
487
521
|
2, 63, :_reduce_65,
|
488
522
|
3, 63, :_reduce_66,
|
@@ -1569,7 +1603,7 @@ module_eval <<'.,.,', 'src/preprocessor.y', 150
|
|
1569
1603
|
|
1570
1604
|
module_eval <<'.,.,', 'src/preprocessor.y', 155
|
1571
1605
|
def _reduce_60( val, _values, result )
|
1572
|
-
result = val[0,2]
|
1606
|
+
result = val[0,2]
|
1573
1607
|
result
|
1574
1608
|
end
|
1575
1609
|
.,.,
|
@@ -1588,12 +1622,7 @@ module_eval <<'.,.,', 'src/preprocessor.y', 166
|
|
1588
1622
|
end
|
1589
1623
|
.,.,
|
1590
1624
|
|
1591
|
-
|
1592
|
-
def _reduce_63( val, _values, result )
|
1593
|
-
val[0] =~ /\A"(.*)"\Z/; result = $1
|
1594
|
-
result
|
1595
|
-
end
|
1596
|
-
.,.,
|
1625
|
+
# reduce 63 omitted
|
1597
1626
|
|
1598
1627
|
module_eval <<'.,.,', 'src/preprocessor.y', 171
|
1599
1628
|
def _reduce_64( val, _values, result )
|
data/lib/dbc/searchpath.rb
CHANGED
@@ -5,36 +5,54 @@
|
|
5
5
|
|
6
6
|
class SearchPath
|
7
7
|
def SearchPath.check(p)
|
8
|
-
|
9
|
-
raise "invalid search path: #{p}"
|
10
|
-
end
|
8
|
+
raise "invalid search path: #{p}" unless File.directory?(p)
|
11
9
|
end
|
12
10
|
def initialize
|
13
11
|
@paths = []
|
14
|
-
|
15
|
-
def add(path, check=true)
|
16
|
-
SearchPath.check(path)
|
17
|
-
@paths << path
|
12
|
+
@next_path = {}
|
18
13
|
end
|
19
14
|
def unshift(path)
|
20
15
|
SearchPath.check(path)
|
21
16
|
@paths.unshift(path)
|
22
17
|
end
|
23
18
|
def <<(path)
|
24
|
-
|
19
|
+
SearchPath.check(path)
|
20
|
+
@paths << path
|
25
21
|
end
|
26
22
|
|
27
|
-
def
|
23
|
+
def find(file)
|
24
|
+
raise ArgumentError, "'#{file}' not found" \
|
25
|
+
unless f = self.find_in(@paths, file)
|
26
|
+
f
|
27
|
+
end
|
28
|
+
def find_next(file)
|
29
|
+
if next_paths = @next_path[file]
|
30
|
+
f = self.find_in(next_paths, file)
|
31
|
+
return f if f
|
32
|
+
end
|
33
|
+
# start the search over
|
34
|
+
self.find(file)
|
35
|
+
end
|
36
|
+
|
37
|
+
def dup
|
38
|
+
d = SearchPath.new
|
28
39
|
@paths.each do |p|
|
29
|
-
|
40
|
+
d << p
|
30
41
|
end
|
42
|
+
d
|
31
43
|
end
|
32
|
-
|
33
|
-
|
34
|
-
|
44
|
+
|
45
|
+
protected
|
46
|
+
def find_in(paths, file)
|
47
|
+
paths.each_with_index do |dir, i|
|
48
|
+
path = File.join(dir, file)
|
49
|
+
if File.exists?(path)
|
50
|
+
i += 1
|
51
|
+
@next_path[file] = @paths[i, @paths.length - i]
|
52
|
+
return path
|
53
|
+
end
|
35
54
|
end
|
36
|
-
|
37
|
-
File.join(dir, file)
|
55
|
+
return nil
|
38
56
|
end
|
39
57
|
end
|
40
58
|
|