adlint 3.0.4 → 3.0.8
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/ChangeLog +374 -13
- data/INSTALL +1 -3
- data/MANIFEST +12 -0
- data/NEWS +30 -4
- data/README +0 -4
- data/TODO +2 -1
- data/etc/mesg.d/c_builtin/en_US/messages.yml +2 -2
- data/etc/mesg.d/c_builtin/ja_JP/messages.yml +2 -2
- data/etc/mesg.d/core/en_US/messages.yml +5 -1
- data/etc/mesg.d/core/ja_JP/messages.yml +5 -1
- data/features/code_check/W0422.feature +128 -0
- data/features/code_check/W0491.feature +57 -0
- data/features/code_check/W0492.feature +80 -0
- data/features/code_check/W0542.feature +20 -0
- data/features/code_check/W0580.feature +25 -0
- data/features/code_check/W0610.feature +36 -0
- data/features/code_check/W0642.feature +67 -0
- data/features/code_check/W0786.feature +39 -0
- data/features/code_check/W0830.feature +27 -0
- data/features/code_check/W1047.feature +72 -0
- data/features/code_check/W9003.feature +22 -0
- data/features/code_extraction/TODO +1 -0
- data/features/metric_measurement/TODO +1 -0
- data/lib/adlint/analyzer.rb +2 -2
- data/lib/adlint/cc1/ctrlexpr.rb +27 -6
- data/lib/adlint/cc1/domain.rb +72 -12
- data/lib/adlint/cc1/enum.rb +4 -0
- data/lib/adlint/cc1/expr.rb +31 -29
- data/lib/adlint/cc1/interp.rb +45 -56
- data/lib/adlint/cc1/lexer.rb +26 -5
- data/lib/adlint/cc1/mediator.rb +35 -6
- data/lib/adlint/cc1/object.rb +62 -19
- data/lib/adlint/cc1/parser.rb +948 -904
- data/lib/adlint/cc1/parser.y +59 -29
- data/lib/adlint/cc1/phase.rb +6 -8
- data/lib/adlint/cc1/syntax.rb +70 -17
- data/lib/adlint/cc1/util.rb +4 -4
- data/lib/adlint/code.rb +16 -6
- data/lib/adlint/cpp/eval.rb +31 -25
- data/lib/adlint/cpp/lexer.rb +11 -5
- data/lib/adlint/cpp/macro.rb +34 -7
- data/lib/adlint/cpp/phase.rb +8 -8
- data/lib/adlint/error.rb +6 -0
- data/lib/adlint/exam/c_builtin/cc1_check.rb +557 -594
- data/lib/adlint/exam/c_builtin/cc1_check_shima.rb +72 -72
- data/lib/adlint/exam/c_builtin/cc1_code.rb +72 -52
- data/lib/adlint/exam/c_builtin/cc1_metric.rb +131 -131
- data/lib/adlint/exam/c_builtin/cpp_check.rb +48 -48
- data/lib/adlint/exam/c_builtin/cpp_check_shima.rb +2 -2
- data/lib/adlint/exam/c_builtin/cpp_code.rb +21 -21
- data/lib/adlint/exam/c_builtin/ld_check.rb +88 -87
- data/lib/adlint/exam/c_builtin/ld_metric.rb +4 -5
- data/lib/adlint/exam/c_builtin.rb +6 -6
- data/lib/adlint/ld/object.rb +269 -186
- data/lib/adlint/ld/phase.rb +19 -19
- data/lib/adlint/ld/typedef.rb +7 -7
- data/lib/adlint/ld/util.rb +25 -17
- data/lib/adlint/location.rb +6 -1
- data/lib/adlint/memo.rb +66 -13
- data/lib/adlint/prelude.rb +2 -2
- data/lib/adlint/report.rb +13 -14
- data/lib/adlint/util.rb +1 -1
- data/lib/adlint/version.rb +2 -2
- data/share/doc/Makefile +6 -2
- data/share/doc/c99gram.dot +502 -0
- data/share/doc/c99gram.pdf +0 -0
- data/share/doc/developers_guide_ja.html +4 -3
- data/share/doc/developers_guide_ja.texi +2 -1
- data/share/doc/users_guide_en.html +9 -9
- data/share/doc/users_guide_en.texi +7 -7
- data/share/doc/users_guide_ja.html +9 -9
- data/share/doc/users_guide_ja.texi +7 -7
- metadata +14 -2
data/lib/adlint/cpp/eval.rb
CHANGED
@@ -363,24 +363,27 @@ module Cpp #:nodoc:
|
|
363
363
|
end
|
364
364
|
discard_extra_tokens_until_newline(pp_ctxt)
|
365
365
|
PPTokensNormalizer.normalize(pp_toks, pp_ctxt)
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
366
|
+
unless pp_toks.tokens.empty?
|
367
|
+
case param = pp_toks.tokens.map { |tok| tok.value }.join
|
368
|
+
when /\A".*"\z/
|
369
|
+
usr_include_line = UserIncludeLine.new(
|
370
|
+
keyword, Token.new(:USR_HEADER_NAME, param,
|
371
|
+
pp_toks.tokens.first.location),
|
372
|
+
pp_ctxt.include_depth)
|
373
|
+
include_first_user_header(usr_include_line, pp_ctxt)
|
374
|
+
return usr_include_line
|
375
|
+
when /\A<.*>\z/
|
376
|
+
sys_include_line = SystemIncludeLine.new(
|
377
|
+
keyword, Token.new(:SYS_HEADER_NAME, param,
|
378
|
+
pp_toks.tokens.first.location),
|
379
|
+
pp_ctxt.include_depth)
|
380
|
+
include_first_system_header(sys_include_line, pp_ctxt)
|
381
|
+
return sys_include_line
|
382
|
+
end
|
382
383
|
end
|
383
|
-
|
384
|
+
E(:E0017, keyword.location)
|
385
|
+
raise IllformedIncludeDirectiveError.new(
|
386
|
+
keyword.location, pp_ctxt.msg_fpath, pp_ctxt.log_fpath)
|
384
387
|
end
|
385
388
|
|
386
389
|
def macro_include_next_line(pp_ctxt, keyword)
|
@@ -815,10 +818,10 @@ module Cpp #:nodoc:
|
|
815
818
|
on_extra_tokens_found.invoke(extra_toks)
|
816
819
|
end
|
817
820
|
|
818
|
-
def handle_unterminated_block_comment(
|
821
|
+
def handle_unterminated_block_comment(loc)
|
819
822
|
E(:E0016, loc)
|
820
|
-
raise UnterminatedCommentError.new(loc, pp_ctxt.msg_fpath,
|
821
|
-
pp_ctxt.log_fpath)
|
823
|
+
raise UnterminatedCommentError.new(loc, @pp_ctxt.msg_fpath,
|
824
|
+
@pp_ctxt.log_fpath)
|
822
825
|
end
|
823
826
|
|
824
827
|
extend Forwardable
|
@@ -879,12 +882,15 @@ module Cpp #:nodoc:
|
|
879
882
|
end
|
880
883
|
|
881
884
|
def top_token
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
885
|
+
unless @lexer_stack.empty?
|
886
|
+
unless tok = @lexer_stack.last.top_token
|
887
|
+
@lexer_stack.pop
|
888
|
+
top_token
|
889
|
+
else
|
890
|
+
tok
|
891
|
+
end
|
886
892
|
else
|
887
|
-
|
893
|
+
nil
|
888
894
|
end
|
889
895
|
end
|
890
896
|
|
data/lib/adlint/cpp/lexer.rb
CHANGED
@@ -165,19 +165,25 @@ module Cpp #:nodoc:
|
|
165
165
|
|
166
166
|
def scan_block_comment(cont)
|
167
167
|
comment = ""
|
168
|
-
|
168
|
+
nest_depth = 0
|
169
169
|
until cont.empty?
|
170
170
|
loc = cont.location
|
171
171
|
case
|
172
|
-
when cont.scan(/\/\*/)
|
173
|
-
|
172
|
+
when nest_depth == 0 && cont.scan(/\/\*/)
|
173
|
+
nest_depth = 1
|
174
174
|
comment += "/*"
|
175
|
-
|
175
|
+
when nest_depth > 0 && cont.check(/\/\*\//)
|
176
|
+
comment += cont.scan(/\//)
|
177
|
+
when nest_depth > 0 && cont.check(/\/\*/)
|
178
|
+
nest_depth += 1
|
179
|
+
comment += cont.scan(/\/\*/)
|
180
|
+
notify_nested_block_comment_found(loc)
|
176
181
|
when cont.scan(/\*\//)
|
177
182
|
comment += "*/"
|
178
183
|
break
|
184
|
+
when nest_depth == 0
|
185
|
+
return nil
|
179
186
|
else
|
180
|
-
return nil if block_depth == 0
|
181
187
|
if scanned = cont.scan(/.*?(?=\/\*|\*\/)/m)
|
182
188
|
comment += scanned
|
183
189
|
else
|
data/lib/adlint/cpp/macro.rb
CHANGED
@@ -343,26 +343,53 @@ module Cpp #:nodoc:
|
|
343
343
|
# order of evaluation of ## operators is unspecified.
|
344
344
|
|
345
345
|
if lhs = res_toks.pop
|
346
|
-
|
346
|
+
unless arg_toks.empty?
|
347
347
|
# NOTE: To avoid syntax error when the concatenated token can be
|
348
348
|
# retokenize to two or more tokens.
|
349
|
-
|
349
|
+
unlexed_arg = unlex_tokens(arg_toks)
|
350
|
+
new_toks = StringToPPTokensLexer.new(lhs.value + unlexed_arg).execute
|
350
351
|
new_toks.map! do |tok|
|
351
352
|
ReplacedToken.new(tok.type, tok.value, expansion_loc,
|
352
353
|
tok.type_hint, false)
|
353
354
|
end
|
354
355
|
res_toks.concat(new_toks)
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
356
|
+
|
357
|
+
macro_tbl.notify_sharpsharp_operator_evaled(
|
358
|
+
lhs, Token.new(:MACRO_ARG, unlexed_arg, arg_toks.first.location),
|
359
|
+
new_toks)
|
359
360
|
else
|
360
361
|
new_toks = [ReplacedToken.new(lhs.type, lhs.value, expansion_loc,
|
361
362
|
lhs.type_hint, false)]
|
362
363
|
res_toks.concat(new_toks)
|
363
364
|
end
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
def unlex_tokens(arg_toks)
|
369
|
+
# NOTE: To regenerate source string from pp_tokens in preparation for
|
370
|
+
# the argument substitution.
|
364
371
|
|
365
|
-
|
372
|
+
# 6.10.3 Macro replacement
|
373
|
+
#
|
374
|
+
# Semantics
|
375
|
+
#
|
376
|
+
# 11 The sequence of preprocessing tokens bounded by the outside-most
|
377
|
+
# matching parentheses forms the list of arguments for the
|
378
|
+
# function-like macro. The individual arguments within the list are
|
379
|
+
# separated by comma preprocessing tokens, but comma preprocessing
|
380
|
+
# tokens between matching inner parentheses do not separate arguments.
|
381
|
+
# If there are sequences of preprocessing tokens within the list of
|
382
|
+
# arguments that would otherwise act as preprocessing directives, the
|
383
|
+
# behavior is undefined.
|
384
|
+
|
385
|
+
arg_toks.each_cons(2).reduce(arg_toks.first.value) do |str, (lhs, rhs)|
|
386
|
+
lhs_loc, rhs_loc = lhs.location, rhs.location
|
387
|
+
if lhs_loc.line_no == rhs_loc.line_no
|
388
|
+
tok_gap = rhs_loc.column_no - lhs_loc.column_no - lhs.value.length
|
389
|
+
str + " " * [tok_gap, 0].max + rhs.value
|
390
|
+
else
|
391
|
+
"#{str} #{rhs.value}"
|
392
|
+
end
|
366
393
|
end
|
367
394
|
end
|
368
395
|
end
|
data/lib/adlint/cpp/phase.rb
CHANGED
@@ -52,10 +52,10 @@ module Cpp #:nodoc:
|
|
52
52
|
private
|
53
53
|
def do_execute(phase_ctxt, *)
|
54
54
|
root_src = phase_ctxt[:sources].first
|
55
|
-
phase_ctxt[:cc1_source]
|
56
|
-
phase_ctxt[:cpp_macro_table]
|
57
|
-
phase_ctxt[:cpp_interpreter]
|
58
|
-
phase_ctxt[:
|
55
|
+
phase_ctxt[:cc1_source] = PreprocessedSource.new(root_src)
|
56
|
+
phase_ctxt[:cpp_macro_table] = MacroTable.new
|
57
|
+
phase_ctxt[:cpp_interpreter] = Preprocessor.new
|
58
|
+
phase_ctxt[:cpp_ast_traversal] = SyntaxTreeMulticastVisitor.new
|
59
59
|
register_annotation_parser
|
60
60
|
end
|
61
61
|
|
@@ -105,7 +105,7 @@ module Cpp #:nodoc:
|
|
105
105
|
else
|
106
106
|
init_header = EmptySource.new
|
107
107
|
end
|
108
|
-
phase_ctxt[:
|
108
|
+
phase_ctxt[:cpp_ast] =
|
109
109
|
phase_ctxt[:cpp_interpreter].execute(pp_ctxt, init_header)
|
110
110
|
end
|
111
111
|
|
@@ -116,13 +116,13 @@ module Cpp #:nodoc:
|
|
116
116
|
else
|
117
117
|
init_header = EmptySource.new
|
118
118
|
end
|
119
|
-
phase_ctxt[:
|
119
|
+
phase_ctxt[:cpp_ast].concat(
|
120
120
|
phase_ctxt[:cpp_interpreter].execute(pp_ctxt, init_header))
|
121
121
|
end
|
122
122
|
|
123
123
|
def process_target_source(phase_ctxt, pp_ctxt)
|
124
124
|
root_src = phase_ctxt[:sources].first
|
125
|
-
phase_ctxt[:
|
125
|
+
phase_ctxt[:cpp_ast].concat(
|
126
126
|
phase_ctxt[:cpp_interpreter].execute(pp_ctxt, root_src))
|
127
127
|
end
|
128
128
|
end
|
@@ -145,7 +145,7 @@ module Cpp #:nodoc:
|
|
145
145
|
|
146
146
|
private
|
147
147
|
def do_execute(phase_ctxt, *)
|
148
|
-
phase_ctxt[:
|
148
|
+
phase_ctxt[:cpp_ast].accept(phase_ctxt[:cpp_ast_traversal])
|
149
149
|
end
|
150
150
|
end
|
151
151
|
|
data/lib/adlint/error.rb
CHANGED
@@ -151,6 +151,12 @@ module AdLint #:nodoc:
|
|
151
151
|
end
|
152
152
|
end
|
153
153
|
|
154
|
+
class IllformedIncludeDirectiveError < FatalError
|
155
|
+
def initialize(loc, msg_fpath, log_fpath)
|
156
|
+
super("#include expects a filename", loc, msg_fpath, log_fpath)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
154
160
|
class UnterminatedCommentError < FatalError
|
155
161
|
def initialize(loc, msg_fpath, log_fpath)
|
156
162
|
super("unterminated comment block found.", loc, msg_fpath, log_fpath)
|