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.
Files changed (73) hide show
  1. data/ChangeLog +374 -13
  2. data/INSTALL +1 -3
  3. data/MANIFEST +12 -0
  4. data/NEWS +30 -4
  5. data/README +0 -4
  6. data/TODO +2 -1
  7. data/etc/mesg.d/c_builtin/en_US/messages.yml +2 -2
  8. data/etc/mesg.d/c_builtin/ja_JP/messages.yml +2 -2
  9. data/etc/mesg.d/core/en_US/messages.yml +5 -1
  10. data/etc/mesg.d/core/ja_JP/messages.yml +5 -1
  11. data/features/code_check/W0422.feature +128 -0
  12. data/features/code_check/W0491.feature +57 -0
  13. data/features/code_check/W0492.feature +80 -0
  14. data/features/code_check/W0542.feature +20 -0
  15. data/features/code_check/W0580.feature +25 -0
  16. data/features/code_check/W0610.feature +36 -0
  17. data/features/code_check/W0642.feature +67 -0
  18. data/features/code_check/W0786.feature +39 -0
  19. data/features/code_check/W0830.feature +27 -0
  20. data/features/code_check/W1047.feature +72 -0
  21. data/features/code_check/W9003.feature +22 -0
  22. data/features/code_extraction/TODO +1 -0
  23. data/features/metric_measurement/TODO +1 -0
  24. data/lib/adlint/analyzer.rb +2 -2
  25. data/lib/adlint/cc1/ctrlexpr.rb +27 -6
  26. data/lib/adlint/cc1/domain.rb +72 -12
  27. data/lib/adlint/cc1/enum.rb +4 -0
  28. data/lib/adlint/cc1/expr.rb +31 -29
  29. data/lib/adlint/cc1/interp.rb +45 -56
  30. data/lib/adlint/cc1/lexer.rb +26 -5
  31. data/lib/adlint/cc1/mediator.rb +35 -6
  32. data/lib/adlint/cc1/object.rb +62 -19
  33. data/lib/adlint/cc1/parser.rb +948 -904
  34. data/lib/adlint/cc1/parser.y +59 -29
  35. data/lib/adlint/cc1/phase.rb +6 -8
  36. data/lib/adlint/cc1/syntax.rb +70 -17
  37. data/lib/adlint/cc1/util.rb +4 -4
  38. data/lib/adlint/code.rb +16 -6
  39. data/lib/adlint/cpp/eval.rb +31 -25
  40. data/lib/adlint/cpp/lexer.rb +11 -5
  41. data/lib/adlint/cpp/macro.rb +34 -7
  42. data/lib/adlint/cpp/phase.rb +8 -8
  43. data/lib/adlint/error.rb +6 -0
  44. data/lib/adlint/exam/c_builtin/cc1_check.rb +557 -594
  45. data/lib/adlint/exam/c_builtin/cc1_check_shima.rb +72 -72
  46. data/lib/adlint/exam/c_builtin/cc1_code.rb +72 -52
  47. data/lib/adlint/exam/c_builtin/cc1_metric.rb +131 -131
  48. data/lib/adlint/exam/c_builtin/cpp_check.rb +48 -48
  49. data/lib/adlint/exam/c_builtin/cpp_check_shima.rb +2 -2
  50. data/lib/adlint/exam/c_builtin/cpp_code.rb +21 -21
  51. data/lib/adlint/exam/c_builtin/ld_check.rb +88 -87
  52. data/lib/adlint/exam/c_builtin/ld_metric.rb +4 -5
  53. data/lib/adlint/exam/c_builtin.rb +6 -6
  54. data/lib/adlint/ld/object.rb +269 -186
  55. data/lib/adlint/ld/phase.rb +19 -19
  56. data/lib/adlint/ld/typedef.rb +7 -7
  57. data/lib/adlint/ld/util.rb +25 -17
  58. data/lib/adlint/location.rb +6 -1
  59. data/lib/adlint/memo.rb +66 -13
  60. data/lib/adlint/prelude.rb +2 -2
  61. data/lib/adlint/report.rb +13 -14
  62. data/lib/adlint/util.rb +1 -1
  63. data/lib/adlint/version.rb +2 -2
  64. data/share/doc/Makefile +6 -2
  65. data/share/doc/c99gram.dot +502 -0
  66. data/share/doc/c99gram.pdf +0 -0
  67. data/share/doc/developers_guide_ja.html +4 -3
  68. data/share/doc/developers_guide_ja.texi +2 -1
  69. data/share/doc/users_guide_en.html +9 -9
  70. data/share/doc/users_guide_en.texi +7 -7
  71. data/share/doc/users_guide_ja.html +9 -9
  72. data/share/doc/users_guide_ja.texi +7 -7
  73. metadata +14 -2
@@ -57,7 +57,7 @@ module Ld #:nodoc:
57
57
  end
58
58
  end
59
59
 
60
- class TypedefMapping
60
+ class TypedefMap
61
61
  def initialize
62
62
  @name_index = Hash.new { |hash, key| hash[key] = Set.new }
63
63
  @composing_fpaths = Set.new
@@ -83,10 +83,10 @@ module Ld #:nodoc:
83
83
 
84
84
  class TypedefMapper
85
85
  def initialize
86
- @result = TypedefMapping.new
86
+ @map = TypedefMap.new
87
87
  end
88
88
 
89
- attr_reader :result
89
+ attr_reader :map
90
90
 
91
91
  def execute(met_fpath)
92
92
  sma_wd = Pathname.pwd
@@ -96,15 +96,15 @@ module Ld #:nodoc:
96
96
  when rec.version?
97
97
  sma_wd = Pathname.new(rec.exec_working_directory)
98
98
  when rec.typedef_declaration?
99
- @result.add(Typedef.new(rec.type_name, rec.location))
99
+ @map.add(Typedef.new(rec.type_name, rec.location))
100
100
  end
101
101
  end
102
102
  end
103
103
  end
104
104
 
105
105
  class TypedefTraversal
106
- def initialize(typedef_mapping)
107
- @typedef_mapping = typedef_mapping
106
+ def initialize(typedef_map)
107
+ @map = typedef_map
108
108
  end
109
109
 
110
110
  extend Pluggable
@@ -112,7 +112,7 @@ module Ld #:nodoc:
112
112
  def_plugin :on_declaration
113
113
 
114
114
  def execute
115
- @typedef_mapping.all_typedefs.each { |tdef| on_declaration.invoke(tdef) }
115
+ @map.all_typedefs.each { |tdef| on_declaration.invoke(tdef) }
116
116
  end
117
117
  end
118
118
 
@@ -39,21 +39,25 @@ module Ld #:nodoc:
39
39
  map_fname = Pathname.new("#{proj_name}.map")
40
40
  map_fpath = map_fname.expand_path(phase_ctxt.msg_fpath.dirname)
41
41
 
42
- mapping = phase_ctxt[:ld_function_mapping]
43
- call_graph = phase_ctxt[:ld_function_call_graph]
44
- return unless mapping && call_graph
42
+ map = phase_ctxt[:ld_function_map]
43
+ call_graph = phase_ctxt[:ld_call_graph]
44
+ return unless map && call_graph
45
45
 
46
46
  File.open(map_fpath, "w") do |io|
47
47
  io.puts("-- Function Call Graph --")
48
- mapping.all_functions.each do |callee|
48
+ map.all_functions.each do |callee|
49
49
  io.puts("DC of #{callee.signature}")
50
- call_graph.direct_callers_of(callee).each do |fun|
51
- io.puts(" #{fun.signature}")
50
+ call_graph.direct_callers_of(callee).each do |ref|
51
+ if fun = ref.function
52
+ io.puts(" #{fun.signature}")
53
+ end
52
54
  end
53
55
  io.puts
54
56
  io.puts("IC of #{callee.signature}")
55
- call_graph.indirect_callers_of(callee).each do |fun|
56
- io.puts(" #{fun.signature}")
57
+ call_graph.indirect_callers_of(callee).each do |ref|
58
+ if fun = ref.function
59
+ io.puts(" #{fun.signature}")
60
+ end
57
61
  end
58
62
  io.puts
59
63
  end
@@ -68,21 +72,25 @@ module Ld #:nodoc:
68
72
  map_fname = Pathname.new("#{proj_name}.map")
69
73
  map_fpath = map_fname.expand_path(phase_ctxt.msg_fpath.dirname)
70
74
 
71
- mapping = phase_ctxt[:ld_variable_mapping]
72
- ref_graph = phase_ctxt[:ld_variable_reference_graph]
73
- return unless mapping && ref_graph
75
+ map = phase_ctxt[:ld_variable_map]
76
+ ref_graph = phase_ctxt[:ld_xref_graph]
77
+ return unless map && ref_graph
74
78
 
75
79
  File.open(map_fpath, "a") do |io|
76
80
  io.puts("-- Variable Reference Graph --")
77
- mapping.all_variables.each do |accessee|
81
+ map.all_variables.each do |accessee|
78
82
  io.puts("DR of #{accessee.name}")
79
- ref_graph.direct_referrers_of(accessee).each do |fun|
80
- io.puts(" #{fun.signature}")
83
+ ref_graph.direct_referrers_of(accessee).each do |ref|
84
+ if fun = ref.function
85
+ io.puts(" #{fun.signature}")
86
+ end
81
87
  end
82
88
  io.puts
83
- io.puts("IR or #{accessee.signature}")
84
- ref_graph.indirect_referrers_of(accessee).each do |fun|
85
- io.puts(" #{fun.signature}")
89
+ io.puts("IR or #{accessee.name}")
90
+ ref_graph.indirect_referrers_of(accessee).each do |ref|
91
+ if fun = ref.function
92
+ io.puts(" #{fun.signature}")
93
+ end
86
94
  end
87
95
  io.puts
88
96
  end
@@ -69,7 +69,12 @@ module AdLint #:nodoc:
69
69
  false
70
70
  end
71
71
  end
72
- memoize :in_analysis_target?
72
+ # NOTE: Value of #in_analysis_target? depends on the `traits' parameter.
73
+ # But the `traits' parameter always points the same object in an
74
+ # AdLint instance.
75
+ # So, it is safe to treat this method as nullary method for improving
76
+ # the performance.
77
+ memoize :in_analysis_target?, force_nullary: true
73
78
 
74
79
  def ==(rhs)
75
80
  self.to_a == rhs.to_a
data/lib/adlint/memo.rb CHANGED
@@ -32,20 +32,29 @@
32
32
  module AdLint #:nodoc:
33
33
 
34
34
  module Memoizable
35
- def memoize(name, *key_indices)
36
- if instance_method(name).arity == 0
37
- memoize_noarg_method(name)
35
+ def memoize(name, *opts)
36
+ force_nullary, key_indices = extract_memoize_options(opts)
37
+ case
38
+ when instance_method(name).arity == 0 || force_nullary
39
+ memoize_nullary_method(name)
40
+ when instance_method(name).arity == 1 || key_indices.size == 1
41
+ memoize_unary_method(name, key_indices.first || 0)
38
42
  else
39
- memoize_ordinary_method(name, key_indices)
43
+ memoize_polynomial_method(name, key_indices)
40
44
  end
41
45
  end
42
46
 
43
47
  private
44
- def memoize_noarg_method(name)
48
+ def extract_memoize_options(opts)
49
+ hash = opts.first || {}
50
+ [hash[:force_nullary], hash[:key_indices] || []]
51
+ end
52
+
53
+ def memoize_nullary_method(name)
45
54
  save_memoizing_method(name)
46
- prepare_noarg_method_cache(name)
55
+ prepare_nullary_method_cache(name)
47
56
  class_eval <<-EOS
48
- define_method(:#{name}) do
57
+ define_method(:#{name}) do |*args|
49
58
  if #{cache_name_of(name)}_initialized ||= false
50
59
  #{cache_name_of(name)}_forbidden = false
51
60
  #{cache_name_of(name)}
@@ -55,16 +64,43 @@ module AdLint #:nodoc:
55
64
  #{org_name_of(name)}
56
65
  else
57
66
  #{cache_name_of(name)}_initialized = true
58
- #{cache_name_of(name)} = #{org_name_of(name)}
67
+ #{cache_name_of(name)} = #{org_name_of(name)}(*args)
68
+ end
69
+ end
70
+ end
71
+ EOS
72
+ end
73
+
74
+ def memoize_unary_method(name, key_index)
75
+ save_memoizing_method(name)
76
+ prepare_unary_method_cache(name, key_index)
77
+ class_eval <<-EOS
78
+ define_method(:#{name}) do |*args|
79
+ key = args[#{key_index}]
80
+ if #{cache_name_of(name)}_initialized ||= false
81
+ #{cache_name_of(name)}_forbidden = false
82
+ if #{cache_name_of(name)}.include?(key)
83
+ #{cache_name_of(name)}[key]
84
+ else
85
+ #{cache_name_of(name)}[key] = #{org_name_of(name)}(*args)
86
+ end
87
+ else
88
+ if #{cache_name_of(name)}_forbidden ||= false
89
+ #{cache_name_of(name)}_forbidden = false
90
+ #{org_name_of(name)}(*args)
91
+ else
92
+ #{cache_name_of(name)}_initialized = true
93
+ #{cache_name_of(name)} = {}
94
+ #{cache_name_of(name)}[key] = #{org_name_of(name)}(*args)
59
95
  end
60
96
  end
61
97
  end
62
98
  EOS
63
99
  end
64
100
 
65
- def memoize_ordinary_method(name, key_indices)
101
+ def memoize_polynomial_method(name, key_indices)
66
102
  save_memoizing_method(name)
67
- prepare_ordinary_method_cache(name, key_indices)
103
+ prepare_polynomial_method_cache(name, key_indices)
68
104
  class_eval <<-EOS
69
105
  define_method(:#{name}) do |*args|
70
106
  key = __key_for_#{name}(*args)
@@ -89,7 +125,7 @@ module AdLint #:nodoc:
89
125
  EOS
90
126
  end
91
127
 
92
- def prepare_noarg_method_cache(name)
128
+ def prepare_nullary_method_cache(name)
93
129
  class_eval <<-EOS
94
130
  define_method(:forbid_once_memo_of__#{name}) do
95
131
  #{cache_name_of(name)}_forbidden = true
@@ -104,7 +140,24 @@ module AdLint #:nodoc:
104
140
  EOS
105
141
  end
106
142
 
107
- def prepare_ordinary_method_cache(name, key_indices)
143
+ def prepare_unary_method_cache(name, key_index)
144
+ class_eval <<-EOS
145
+ define_method(:forbid_once_memo_of__#{name}) do
146
+ #{cache_name_of(name)}_forbidden = true
147
+ end
148
+ define_method(:clear_memo_of__#{name}) do
149
+ #{cache_name_of(name)} = nil
150
+ #{cache_name_of(name)}_initialized = false
151
+ end
152
+ define_method(:forget_memo_of__#{name}) do |*args|
153
+ if #{cache_name_of(name)}_initialized
154
+ #{cache_name_of(name)}.delete(args[#{key_index}])
155
+ end
156
+ end
157
+ EOS
158
+ end
159
+
160
+ def prepare_polynomial_method_cache(name, key_indices)
108
161
  define_key_generator(name, key_indices)
109
162
  class_eval <<-EOS
110
163
  define_method(:forbid_once_memo_of__#{name}) do
@@ -147,7 +200,7 @@ module AdLint #:nodoc:
147
200
  end
148
201
 
149
202
  def cache_name_of(name)
150
- "@__cache_of__#{name.to_s.sub("?", "Q")}"
203
+ "@__cache_of__#{name.to_s.sub("?", "P")}"
151
204
  end
152
205
 
153
206
  def org_name_of(name)
@@ -327,9 +327,9 @@ end
327
327
  # string_item: "foo${VAR}baz"
328
328
  #
329
329
  class Psych::TreeBuilder < Psych::Handler
330
- alias :_orig_scalar :scalar
330
+ alias :_org_scalar :scalar
331
331
  def scalar(value, anchor, tag, plain, quoted, style)
332
- _orig_scalar(substitute_environment_variables(value),
332
+ _org_scalar(substitute_environment_variables(value),
333
333
  anchor, tag, plain, quoted, style)
334
334
  end
335
335
 
data/lib/adlint/report.rb CHANGED
@@ -248,7 +248,7 @@ module AdLint #:nodoc:
248
248
  # Writes a function declaration information on the report.
249
249
  #
250
250
  # Abbreviation below is available.
251
- # write_funcdcl(...) => FUNCDCL(...)
251
+ # write_fundcl(...) => FUNDCL(...)
252
252
  #
253
253
  # === PARAMETER
254
254
  # _loc_:: Location -- Location where the declaration appears.
@@ -259,11 +259,10 @@ module AdLint #:nodoc:
259
259
  #
260
260
  # === RETURN VALUE
261
261
  # None.
262
- def write_funcdcl(loc, linkage, scope_type, dcl_type, fun_id)
263
- write_code_struct(FuncDcl.new(loc, linkage, scope_type, dcl_type,
264
- fun_id))
262
+ def write_fundcl(loc, linkage, scope_type, dcl_type, fun_id)
263
+ write_code_struct(FunDcl.new(loc, linkage, scope_type, dcl_type, fun_id))
265
264
  end
266
- alias :FUNCDCL :write_funcdcl
265
+ alias :FUNDCL :write_fundcl
267
266
 
268
267
  # === DESCRIPTION
269
268
  # Writes a variable definition information on the report.
@@ -291,7 +290,7 @@ module AdLint #:nodoc:
291
290
  # Writes a function definition information on the report.
292
291
  #
293
292
  # Abbreviation below is available.
294
- # write_funcdef(...) => FUNCDEF(...)
293
+ # write_fundef(...) => FUNDEF(...)
295
294
  #
296
295
  # === PARAMETER
297
296
  # _loc_:: Location -- Location where the definition appears.
@@ -302,10 +301,10 @@ module AdLint #:nodoc:
302
301
  #
303
302
  # === RETURN VALUE
304
303
  # None.
305
- def write_funcdef(loc, linkage, scope_type, fun_id, lines)
306
- write_code_struct(FuncDef.new(loc, linkage, scope_type, fun_id, lines))
304
+ def write_fundef(loc, linkage, scope_type, fun_id, lines)
305
+ write_code_struct(FunDef.new(loc, linkage, scope_type, fun_id, lines))
307
306
  end
308
- alias :FUNCDEF :write_funcdef
307
+ alias :FUNDEF :write_fundef
309
308
 
310
309
  # === DESCRIPTION
311
310
  # Writes a macro definition information on the report.
@@ -399,16 +398,16 @@ module AdLint #:nodoc:
399
398
  # Writes a function call information on the report.
400
399
  #
401
400
  # Abbreviation below is available.
402
- # write_call(...) => CALL(...)
401
+ # write_funcall(...) => FUNCALL(...)
403
402
  #
404
403
  # === PARAMETER
405
404
  # _loc_:: Location -- Location where the function call appears.
406
405
  # _caller_fun_:: FunctionId -- Calling function identifier.
407
406
  # _callee_fun_:: FunctionId -- Called function identifier.
408
- def write_call(loc, caller_fun, callee_fun)
409
- write_code_struct(Call.new(loc, caller_fun, callee_fun))
407
+ def write_funcall(loc, caller_fun, callee_fun)
408
+ write_code_struct(Funcall.new(loc, caller_fun, callee_fun))
410
409
  end
411
- alias :CALL :write_call
410
+ alias :FUNCALL :write_funcall
412
411
 
413
412
  # === DESCRIPTION
414
413
  # Writes a variable cross reference information on the report.
@@ -444,7 +443,7 @@ module AdLint #:nodoc:
444
443
  # === RETURN VALUE
445
444
  # None.
446
445
  def write_xref_function(loc, referrer, ref_type, fun)
447
- write_code_struct(XRefFunc.new(loc, referrer, ref_type, fun))
446
+ write_code_struct(XRefFun.new(loc, referrer, ref_type, fun))
448
447
  end
449
448
  alias :XREF_FUNC :write_xref_function
450
449
 
data/lib/adlint/util.rb CHANGED
@@ -517,7 +517,7 @@ if $0 == __FILE__
517
517
  p "foo"
518
518
  end
519
519
 
520
- extend ::AdLint::Pluggable
520
+ extend AdLint::Pluggable
521
521
 
522
522
  def_plugin :on_initialization
523
523
 
@@ -33,8 +33,8 @@ module AdLint #:nodoc:
33
33
 
34
34
  MAJOR_VERSION = 3
35
35
  MINOR_VERSION = 0
36
- PATCH_VERSION = 4
37
- RELEASE_DATE = "2013-04-12"
36
+ PATCH_VERSION = 8
37
+ RELEASE_DATE = "2013-05-31"
38
38
 
39
39
  TRAITS_SCHEMA_VERSION = "3.0.0"
40
40
 
data/share/doc/Makefile CHANGED
@@ -1,6 +1,7 @@
1
1
  MAKEINFO = makeinfo
2
+ DOT = dot
2
3
 
3
- .SUFFIXES : .texi .html .txt
4
+ .SUFFIXES : .texi .html .txt .dot .pdf
4
5
 
5
6
  .texi.html :
6
7
  $(MAKEINFO) --html --no-split --css-include=texinfo.css -o $@ $<
@@ -8,7 +9,10 @@ MAKEINFO = makeinfo
8
9
  .texi.txt :
9
10
  $(MAKEINFO) --plaintext -o $@ $<
10
11
 
11
- TARGET = users_guide_ja.html users_guide_en.html developers_guide_ja.html
12
+ .dot.pdf :
13
+ $(DOT) -Tpdf -o $@ $<
14
+
15
+ TARGET = users_guide_ja.html users_guide_en.html developers_guide_ja.html c99gram.pdf
12
16
 
13
17
  all : $(TARGET)
14
18