adlint 2.2.0 → 2.4.0

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 (100) hide show
  1. data/AUTHORS +0 -1
  2. data/ChangeLog +185 -1
  3. data/MANIFEST +3 -0
  4. data/NEWS +28 -5
  5. data/bin/adlintize +70 -7
  6. data/etc/conf.d/fallback/traits.erb +12 -3
  7. data/etc/conf.d/i686-cygwin/traits-gcc_4.3.4.erb +12 -3
  8. data/etc/conf.d/i686-devkit/traits-gcc_4.5.2.erb +12 -3
  9. data/etc/conf.d/i686-linux/traits-gcc_4.5.1.erb +12 -3
  10. data/etc/conf.d/i686-mingw/traits-gcc_4.6.1.erb +12 -3
  11. data/etc/conf.d/x86_64-ubuntu_12.04/traits-gcc_4.6.3.erb +12 -4
  12. data/etc/mesg.d/c_builtin/en_US/messages.yml +1 -1
  13. data/etc/mesg.d/c_builtin/ja_JP/messages.yml +1 -1
  14. data/etc/mesg.d/core/en_US/messages.yml +1 -1
  15. data/etc/mesg.d/core/ja_JP/messages.yml +1 -1
  16. data/features/code_check/W0070.feature +51 -0
  17. data/features/code_check/W0071.feature +51 -0
  18. data/features/code_check/W0425.feature +279 -0
  19. data/features/code_check/W0692.feature +14 -1
  20. data/features/code_check/W0834.feature +7 -5
  21. data/features/code_check/W1073.feature +0 -1
  22. data/features/code_check/W1074.feature +6 -0
  23. data/features/code_check/W9003.feature +54 -0
  24. data/features/support/env.rb +15 -3
  25. data/lib/adlint/c/expr.rb +30 -6
  26. data/lib/adlint/c/interp.rb +4 -0
  27. data/lib/adlint/cpp/eval.rb +24 -14
  28. data/lib/adlint/cpp/macro.rb +52 -40
  29. data/lib/adlint/exam/c_builtin/c_check.rb +76 -42
  30. data/lib/adlint/exam/c_builtin/cpp_check.rb +4 -2
  31. data/lib/adlint/traits.rb +37 -23
  32. data/lib/adlint/util.rb +6 -0
  33. data/lib/adlint/version.rb +3 -3
  34. data/share/doc/developers_guide_ja.html +3 -3
  35. data/share/doc/developers_guide_ja.texi +1 -1
  36. data/share/doc/users_guide_en.html +1679 -1651
  37. data/share/doc/users_guide_en.texi +56 -24
  38. data/share/doc/users_guide_ja.html +1697 -1669
  39. data/share/doc/users_guide_ja.texi +57 -24
  40. data/share/sample/bison-2.5/adlint/adlint_traits.yml +13 -4
  41. data/share/sample/bison-2.5/adlint/lib/adlint_traits.yml +13 -4
  42. data/share/sample/bison-2.5/adlint/src/adlint_traits.yml +13 -4
  43. data/share/sample/ctags-5.8/adlint/adlint_traits.yml +13 -4
  44. data/share/sample/flex-2.5.35/adlint/adlint_traits.yml +13 -4
  45. data/share/sample/ruby-1.9.3-p0/adlint/adlint_traits.yml +13 -4
  46. data/share/sample/ruby-1.9.3-p0/adlint/core/adlint_traits.yml +13 -4
  47. data/share/sample/ruby-1.9.3-p0/adlint/enc/adlint_traits.yml +13 -4
  48. data/share/sample/ruby-1.9.3-p0/adlint/enc-trans/adlint_traits.yml +13 -4
  49. data/share/sample/ruby-1.9.3-p0/adlint/ext-bigdecimal/adlint_traits.yml +13 -4
  50. data/share/sample/ruby-1.9.3-p0/adlint/ext-continuation/adlint_traits.yml +13 -4
  51. data/share/sample/ruby-1.9.3-p0/adlint/ext-coverage/adlint_traits.yml +13 -4
  52. data/share/sample/ruby-1.9.3-p0/adlint/ext-curses/adlint_traits.yml +13 -4
  53. data/share/sample/ruby-1.9.3-p0/adlint/ext-date/adlint_traits.yml +13 -4
  54. data/share/sample/ruby-1.9.3-p0/adlint/ext-dbm/adlint_traits.yml +13 -4
  55. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest/adlint_traits.yml +13 -4
  56. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-bubblebabble/adlint_traits.yml +13 -4
  57. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-md5/adlint_traits.yml +13 -4
  58. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-rmd160/adlint_traits.yml +13 -4
  59. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha1/adlint_traits.yml +13 -4
  60. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha2/adlint_traits.yml +13 -4
  61. data/share/sample/ruby-1.9.3-p0/adlint/ext-dl/adlint_traits.yml +13 -4
  62. data/share/sample/ruby-1.9.3-p0/adlint/ext-dl-callback/adlint_traits.yml +13 -4
  63. data/share/sample/ruby-1.9.3-p0/adlint/ext-etc/adlint_traits.yml +13 -4
  64. data/share/sample/ruby-1.9.3-p0/adlint/ext-fcntl/adlint_traits.yml +13 -4
  65. data/share/sample/ruby-1.9.3-p0/adlint/ext-fiber/adlint_traits.yml +13 -4
  66. data/share/sample/ruby-1.9.3-p0/adlint/ext-fiddle/adlint_traits.yml +13 -4
  67. data/share/sample/ruby-1.9.3-p0/adlint/ext-gdbm/adlint_traits.yml +13 -4
  68. data/share/sample/ruby-1.9.3-p0/adlint/ext-iconv/adlint_traits.yml +13 -4
  69. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-console/adlint_traits.yml +13 -4
  70. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-nonblock/adlint_traits.yml +13 -4
  71. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-wait/adlint_traits.yml +13 -4
  72. data/share/sample/ruby-1.9.3-p0/adlint/ext-json-generator/adlint_traits.yml +13 -4
  73. data/share/sample/ruby-1.9.3-p0/adlint/ext-json-parser/adlint_traits.yml +13 -4
  74. data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-complex/adlint_traits.yml +13 -4
  75. data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-rational/adlint_traits.yml +13 -4
  76. data/share/sample/ruby-1.9.3-p0/adlint/ext-nkf/adlint_traits.yml +13 -4
  77. data/share/sample/ruby-1.9.3-p0/adlint/ext-openssl/adlint_traits.yml +13 -4
  78. data/share/sample/ruby-1.9.3-p0/adlint/ext-pathname/adlint_traits.yml +13 -4
  79. data/share/sample/ruby-1.9.3-p0/adlint/ext-psych/adlint_traits.yml +13 -4
  80. data/share/sample/ruby-1.9.3-p0/adlint/ext-pty/adlint_traits.yml +13 -4
  81. data/share/sample/ruby-1.9.3-p0/adlint/ext-racc-cparse/adlint_traits.yml +13 -4
  82. data/share/sample/ruby-1.9.3-p0/adlint/ext-readline/adlint_traits.yml +13 -4
  83. data/share/sample/ruby-1.9.3-p0/adlint/ext-ripper/adlint_traits.yml +13 -4
  84. data/share/sample/ruby-1.9.3-p0/adlint/ext-sdbm/adlint_traits.yml +13 -4
  85. data/share/sample/ruby-1.9.3-p0/adlint/ext-socket/adlint_traits.yml +13 -4
  86. data/share/sample/ruby-1.9.3-p0/adlint/ext-stringio/adlint_traits.yml +13 -4
  87. data/share/sample/ruby-1.9.3-p0/adlint/ext-strscan/adlint_traits.yml +13 -4
  88. data/share/sample/ruby-1.9.3-p0/adlint/ext-syck/adlint_traits.yml +13 -4
  89. data/share/sample/ruby-1.9.3-p0/adlint/ext-syslog/adlint_traits.yml +13 -4
  90. data/share/sample/ruby-1.9.3-p0/adlint/ext-zlib/adlint_traits.yml +13 -4
  91. data/share/sample/screen-4.0.3/adlint/adlint_traits.yml +13 -4
  92. data/share/sample/vim-7.3/adlint/vim/adlint_traits.yml +13 -4
  93. data/share/sample/vim-7.3/adlint/xxd/adlint_traits.yml +13 -4
  94. data/share/sample/zsh-4.3.15/adlint/adlint_traits.yml +13 -4
  95. data/share/sample/zsh-4.3.15/adlint/builtins/adlint_traits.yml +13 -4
  96. data/share/sample/zsh-4.3.15/adlint/core/adlint_traits.yml +13 -4
  97. data/share/sample/zsh-4.3.15/adlint/modules/adlint_traits.yml +13 -4
  98. data/share/sample/zsh-4.3.15/adlint/zle/adlint_traits.yml +13 -4
  99. data/spec/conf.d/default_traits.yml +12 -4
  100. metadata +5 -2
@@ -109,18 +109,28 @@ module Cpp #:nodoc:
109
109
  def replaceable_size(tokens)
110
110
  return 0 unless name.value == tokens.first.value
111
111
  args, index = parse_arguments(tokens, 1)
112
- args && @parameter_names.size >= args.size ? index + 1 : 0
112
+ case
113
+ when args && @parameter_names.empty?
114
+ index + 1
115
+ when args && @parameter_names.size >= args.size
116
+ index + 1
117
+ else
118
+ 0
119
+ end
113
120
  end
114
121
 
115
122
  def expand(tokens, macro_table, context)
116
123
  super
117
124
 
118
125
  args, * = parse_arguments(tokens, 1)
119
- result = expand_replacement_list(
120
- @parameter_names.each_with_index.with_object({}) { |(name, i), hash|
121
- arg = args[i] and hash[name] = arg
122
- }, tokens.first.location, macro_table, context)
126
+ args = [] if @parameter_names.empty?
127
+ args_hash =
128
+ @parameter_names.zip(args).each_with_object({}) { |(name, arg), hash|
129
+ hash[name] = arg
130
+ }
123
131
 
132
+ result = expand_replacement_list(args_hash, tokens.first.location,
133
+ macro_table, context)
124
134
  macro_table.notify_function_like_macro_replacement(self, tokens, args,
125
135
  result)
126
136
  result
@@ -144,15 +154,10 @@ module Cpp #:nodoc:
144
154
  return nil, index unless token
145
155
 
146
156
  args = []
147
- while token = tokens[index]
148
- if token.value == ","
149
- args.push(nil)
150
- index += 1
151
- else
152
- arg, index = parse_one_argument(tokens, index)
153
- break unless arg
154
- args.push(arg)
155
- end
157
+ loop do
158
+ arg, index, last = parse_one_argument(tokens, index)
159
+ args.push(arg)
160
+ break if last
156
161
  end
157
162
  return args, index
158
163
  end
@@ -163,30 +168,29 @@ module Cpp #:nodoc:
163
168
  while token = tokens[index]
164
169
  case token.value
165
170
  when "("
166
- arg << token
171
+ arg.push(token)
167
172
  paren_depth += 1
168
173
  when ")"
169
174
  paren_depth -= 1
170
175
  if paren_depth >= 0
171
- arg << token
176
+ arg.push(token)
172
177
  else
173
- break
178
+ return arg, index, true
174
179
  end
175
180
  when ","
176
181
  if paren_depth > 0
177
- arg << token
182
+ arg.push(token)
178
183
  else
179
- index += 1
180
- break
184
+ return arg, index + 1, false
181
185
  end
182
186
  when "\n"
183
187
  ;
184
188
  else
185
- arg << token
189
+ arg.push(token)
186
190
  end
187
191
  index += 1
188
192
  end
189
- return (arg.empty? ? nil : arg), index
193
+ return arg, index, true # NOTREACHED
190
194
  end
191
195
 
192
196
  def expand_replacement_list(args, location, macro_table, context)
@@ -202,15 +206,16 @@ module Cpp #:nodoc:
202
206
  substitute_argument(curr_token, next_token, arg, location, result,
203
207
  macro_table, context)
204
208
  when curr_token.value == "#"
205
- if next_token and arg = args[next_token.value] || []
206
- stringized = stringize_argument(arg, location, macro_table)
209
+ if next_token
210
+ stringized = stringize_argument(args[next_token.value], location,
211
+ macro_table)
207
212
  result.push(stringized)
208
213
  index += 1
209
214
  end
210
215
  when curr_token.value == "##" && next_token.value == "#"
211
- if next_next_token = replacement_list.tokens[index + 2] and
212
- arg = args[next_next_token.value] || []
213
- stringized = stringize_argument(arg, location, macro_table)
216
+ if next_next_token = replacement_list.tokens[index + 2]
217
+ stringized = stringize_argument(args[next_next_token.value],
218
+ location, macro_table)
214
219
  concat_with_last_token([stringized], location, result, macro_table)
215
220
  index += 2
216
221
  end
@@ -336,21 +341,28 @@ module Cpp #:nodoc:
336
341
  # The resulting token is available for further macro replacement. The
337
342
  # order of evaluation of ## operators is unspecified.
338
343
 
339
- if lhs = result_tokens.pop and rhs = arg_tokens.first
340
- # NOTE: To avoid syntax error when the concatenated token can be
341
- # retokenize to two or more tokens.
342
- new_tokens = StringToPPTokensLexer.new(lhs.value + rhs.value).execute
343
- new_tokens.map! do |token|
344
- ReplacedToken.new(token.type, token.value, expansion_location,
345
- token.type_hint, false)
344
+ if lhs = result_tokens.pop
345
+ if rhs = arg_tokens.first
346
+ # NOTE: To avoid syntax error when the concatenated token can be
347
+ # retokenize to two or more tokens.
348
+ new_tokens = StringToPPTokensLexer.new(lhs.value + rhs.value).execute
349
+ new_tokens.map! do |token|
350
+ ReplacedToken.new(token.type, token.value, expansion_location,
351
+ token.type_hint, false)
352
+ end
353
+ result_tokens.concat(new_tokens)
354
+ result_tokens.concat(arg_tokens[1..-1].map { |token|
355
+ ReplacedToken.new(token.type, token.value, expansion_location,
356
+ token.type_hint, false)
357
+ })
358
+ else
359
+ new_tokens = [ReplacedToken.new(lhs.type, lhs.value,
360
+ expansion_location, lhs.type_hint,
361
+ false)]
362
+ result_tokens.concat(new_tokens)
346
363
  end
347
- macro_table.notify_sharpsharp_operator_evaled(lhs, rhs, new_tokens)
348
364
 
349
- result_tokens.concat(new_tokens)
350
- result_tokens.concat(arg_tokens[1..-1].map { |token|
351
- ReplacedToken.new(token.type, token.value, expansion_location,
352
- token.type_hint, false)
353
- })
365
+ macro_table.notify_sharpsharp_operator_evaled(lhs, rhs, new_tokens)
354
366
  end
355
367
  end
356
368
  end
@@ -1926,7 +1926,16 @@ module CBuiltin #:nodoc:
1926
1926
  interp.on_variable_value_updated += method(:write_variable)
1927
1927
  interp.on_block_started += method(:enter_block)
1928
1928
  interp.on_block_ended += method(:leave_block)
1929
+ interp.on_while_stmt_started += method(:enter_iteration)
1930
+ interp.on_while_stmt_ended += method(:leave_iteration)
1931
+ interp.on_do_stmt_started += method(:enter_iteration)
1932
+ interp.on_do_stmt_ended += method(:leave_iteration)
1933
+ interp.on_for_stmt_started += method(:enter_iteration)
1934
+ interp.on_for_stmt_ended += method(:leave_iteration)
1935
+ interp.on_c99_for_stmt_started += method(:enter_iteration)
1936
+ interp.on_c99_for_stmt_ended += method(:leave_iteration)
1929
1937
  @variable_stack = [{}]
1938
+ @iteration_stmt_stack = []
1930
1939
  end
1931
1940
 
1932
1941
  private
@@ -1957,11 +1966,26 @@ module CBuiltin #:nodoc:
1957
1966
 
1958
1967
  @variable_stack.reverse_each do |variables|
1959
1968
  if record = variables[variable]
1960
- record[1] += 1
1969
+ if @iteration_stmt_stack.empty?
1970
+ record[1] += 1
1971
+ else
1972
+ # NOTE: Update twice in order not to over-warn about this variable,
1973
+ # because an iteration is treated as a normal selection by
1974
+ # the abstract interpreter.
1975
+ record[1] += 2
1976
+ end
1961
1977
  end
1962
1978
  end
1963
1979
  end
1964
1980
 
1981
+ def enter_iteration(iteration_stmt)
1982
+ @iteration_stmt_stack.push(iteration_stmt)
1983
+ end
1984
+
1985
+ def leave_iteration(iteration_stmt)
1986
+ @iteration_stmt_stack.pop
1987
+ end
1988
+
1965
1989
  def check_constant_variables(variables)
1966
1990
  variables.each do |variable, (location, assign_count)|
1967
1991
  case
@@ -6948,122 +6972,132 @@ module CBuiltin #:nodoc:
6948
6972
 
6949
6973
  def initialize(context)
6950
6974
  @context = context
6951
- @decl_location = Location.new
6952
- @stmt_location = Location.new
6975
+ @last_decl_or_stmt_location = Location.new
6976
+ @last_memb_decl_location = Location.new
6953
6977
  end
6954
6978
 
6955
6979
  def visit_function_declaration(node)
6956
- check_declaration(node)
6980
+ check_decl_or_stmt(node)
6981
+ @last_decl_or_stmt_location = node.location
6957
6982
  end
6958
6983
 
6959
6984
  def visit_variable_declaration(node)
6960
- check_declaration(node)
6985
+ check_decl_or_stmt(node)
6986
+ @last_decl_or_stmt_location = node.location
6961
6987
  end
6962
6988
 
6963
6989
  def visit_variable_definition(node)
6964
- check_declaration(node)
6990
+ check_decl_or_stmt(node)
6991
+ @last_decl_or_stmt_location = node.location
6965
6992
  end
6966
6993
 
6967
6994
  def visit_typedef_declaration(node)
6968
- check_declaration(node)
6995
+ check_decl_or_stmt(node)
6996
+ @last_decl_or_stmt_location = node.location
6969
6997
  end
6970
6998
 
6971
- def visit_struct_type_declaration(node)
6972
- check_declaration(node)
6973
- end
6974
-
6975
- def visit_union_type_declaration(node)
6976
- check_declaration(node)
6977
- end
6978
-
6979
- def visit_enum_type_declaration(node)
6980
- check_declaration(node)
6999
+ def visit_member_declaration(node)
7000
+ check_member_decl(node)
7001
+ @last_memb_decl_location = node.location
6981
7002
  end
6982
7003
 
6983
7004
  def visit_generic_labeled_statement(node)
6984
- check_statement(node)
7005
+ check_decl_or_stmt(node)
7006
+ @last_decl_or_stmt_location = node.location
6985
7007
  end
6986
7008
 
6987
7009
  def visit_case_labeled_statement(node)
6988
- check_statement(node)
7010
+ check_decl_or_stmt(node)
7011
+ @last_decl_or_stmt_location = node.location
6989
7012
  end
6990
7013
 
6991
7014
  def visit_default_labeled_statement(node)
6992
- check_statement(node)
7015
+ check_decl_or_stmt(node)
7016
+ @last_decl_or_stmt_location = node.location
6993
7017
  end
6994
7018
 
6995
7019
  def visit_expression_statement(node)
6996
- check_statement(node)
7020
+ check_decl_or_stmt(node)
7021
+ @last_decl_or_stmt_location = node.location
6997
7022
  end
6998
7023
 
6999
7024
  def visit_if_statement(node)
7000
- check_statement(node)
7025
+ check_decl_or_stmt(node)
7001
7026
  node.statement.accept(self)
7027
+ @last_decl_or_stmt_location = node.location
7002
7028
  end
7003
7029
 
7004
7030
  def visit_if_else_statement(node)
7005
- check_statement(node)
7031
+ check_decl_or_stmt(node)
7032
+ orig_location = @last_decl_or_stmt_location
7006
7033
  node.then_statement.accept(self)
7034
+ @last_decl_or_stmt_location = orig_location
7007
7035
  node.else_statement.accept(self)
7036
+ @last_decl_or_stmt_location = node.location
7008
7037
  end
7009
7038
 
7010
7039
  def visit_switch_statement(node)
7011
- check_statement(node)
7040
+ check_decl_or_stmt(node)
7012
7041
  node.statement.accept(self)
7042
+ @last_decl_or_stmt_location = node.location
7013
7043
  end
7014
7044
 
7015
7045
  def visit_while_statement(node)
7016
- check_statement(node)
7046
+ check_decl_or_stmt(node)
7017
7047
  node.statement.accept(self)
7048
+ @last_decl_or_stmt_location = node.location
7018
7049
  end
7019
7050
 
7020
7051
  def visit_do_statement(node)
7021
- check_statement(node)
7052
+ check_decl_or_stmt(node)
7022
7053
  node.statement.accept(self)
7054
+ @last_decl_or_stmt_location = node.location
7023
7055
  end
7024
7056
 
7025
7057
  def visit_for_statement(node)
7026
- check_statement(node)
7058
+ check_decl_or_stmt(node)
7027
7059
  node.body_statement.accept(self)
7060
+ @last_decl_or_stmt_location = node.location
7028
7061
  end
7029
7062
 
7030
7063
  def visit_c99_for_statement(node)
7031
- check_statement(node)
7064
+ check_decl_or_stmt(node)
7032
7065
  node.body_statement.accept(self)
7066
+ @last_decl_or_stmt_location = node.location
7033
7067
  end
7034
7068
 
7035
7069
  def visit_goto_statement(node)
7036
- check_statement(node)
7070
+ check_decl_or_stmt(node)
7071
+ @last_decl_or_stmt_location = node.location
7037
7072
  end
7038
7073
 
7039
7074
  def visit_continue_statement(node)
7040
- check_statement(node)
7075
+ check_decl_or_stmt(node)
7076
+ @last_decl_or_stmt_location = node.location
7041
7077
  end
7042
7078
 
7043
7079
  def visit_break_statement(node)
7044
- check_statement(node)
7080
+ check_decl_or_stmt(node)
7081
+ @last_decl_or_stmt_location = node.location
7045
7082
  end
7046
7083
 
7047
7084
  def visit_return_statement(node)
7048
- check_statement(node)
7085
+ check_decl_or_stmt(node)
7086
+ @last_decl_or_stmt_location = node.location
7049
7087
  end
7050
7088
 
7051
7089
  private
7052
- def check_declaration(node)
7053
- if @decl_location.fpath == node.location.fpath &&
7054
- @decl_location.line_no == node.location.line_no
7090
+ def check_decl_or_stmt(node)
7091
+ if @last_decl_or_stmt_location.fpath == node.location.fpath &&
7092
+ @last_decl_or_stmt_location.line_no == node.location.line_no
7055
7093
  W(:W0425, node.location)
7056
- else
7057
- @decl_location = node.location
7058
7094
  end
7059
7095
  end
7060
7096
 
7061
- def check_statement(node)
7062
- if @stmt_location.fpath == node.location.fpath &&
7063
- @stmt_location.line_no == node.location.line_no
7097
+ def check_member_decl(node)
7098
+ if @last_memb_decl_location.fpath == node.location.fpath &&
7099
+ @last_memb_decl_location.line_no == node.location.line_no
7064
7100
  W(:W0425, node.location)
7065
- else
7066
- @stmt_location = node.location
7067
7101
  end
7068
7102
  end
7069
7103
 
@@ -1153,8 +1153,10 @@ module CBuiltin #:nodoc:
1153
1153
 
1154
1154
  private
1155
1155
  def check(macro, replacing_tokens, args, *)
1156
- if args.empty?
1157
- W(:W0692, replacing_tokens.first.location, macro.name.value)
1156
+ unless macro.parameter_names.empty?
1157
+ if args.any? { |arg| arg.empty? }
1158
+ W(:W0692, replacing_tokens.first.location, macro.name.value)
1159
+ end
1158
1160
  end
1159
1161
  end
1160
1162
  end
data/lib/adlint/traits.rb CHANGED
@@ -90,7 +90,7 @@ module AdLint #:nodoc:
90
90
  end
91
91
  validate_version(doc["version"])
92
92
 
93
- @exam_packages = doc["exam_packages"].uniq.map { |name|
93
+ @exam_packages = (doc["exam_packages"] || []).uniq.map { |name|
94
94
  ExaminationPackage.new(name)
95
95
  }.freeze
96
96
 
@@ -105,7 +105,7 @@ module AdLint #:nodoc:
105
105
  def validate_version(version)
106
106
  version == TRAITS_SCHEMA_VERSION or
107
107
  raise "invalid version of the trailts file.\n" +
108
- "please, regenerate traits file by new `adlintize' command."
108
+ "regenerate or migrate traits file by new `adlintize' command."
109
109
  end
110
110
  end
111
111
 
@@ -114,13 +114,11 @@ module AdLint #:nodoc:
114
114
 
115
115
  def initialize(doc)
116
116
  @project_name = doc["project_name"]
117
-
118
- if path_strs = doc["include_path"]
119
- @include_path = path_strs.map { |str| Pathname.new(str) }
120
- else
121
- @include_path = []
122
- end
123
-
117
+ @project_root = Pathname.new(doc["project_root"])
118
+ @include_path =
119
+ (doc["include_path"] || []).compact.map { |compound_path_str|
120
+ compound_path_str.split(":").map { |str| Pathname.new(str) }
121
+ }.flatten
124
122
  @initial_header = doc["initial_header"]
125
123
  @coding_style = CodingStyle.new(doc["coding_style"])
126
124
  @file_encoding = doc["file_encoding"]
@@ -133,6 +131,9 @@ module AdLint #:nodoc:
133
131
  attr_reader :project_name
134
132
  ensure_presence_of :project_name
135
133
 
134
+ attr_reader :project_root
135
+ ensure_dir_presence_of :project_root
136
+
136
137
  attr_reader :include_path
137
138
  ensure_dirs_presence_of :include_path
138
139
 
@@ -197,13 +198,10 @@ module AdLint #:nodoc:
197
198
 
198
199
  def initialize(doc)
199
200
  @standard_type = StandardType.new(doc["standard_type"])
200
-
201
- if path_strs = doc["include_path"]
202
- @include_path = path_strs.map { |str| Pathname.new(str) }
203
- else
204
- @include_path = []
205
- end
206
-
201
+ @include_path =
202
+ (doc["include_path"] || []).compact.map { |compound_path_str|
203
+ compound_path_str.split(":").map { |str| Pathname.new(str) }
204
+ }.flatten
207
205
  @initial_header = doc["initial_header"]
208
206
  @arithmetic = Arithmetic.new(doc["arithmetic"])
209
207
  @extension_substitution = doc["extension_substitution"] || {}
@@ -491,14 +489,21 @@ module AdLint #:nodoc:
491
489
  def initialize(doc)
492
490
  @language = doc["language"]
493
491
  @message_with_class = doc["message_with_class"]
494
- @warn_only_files_in = doc["warn_only_files_in"]
492
+ @warn_files_in =
493
+ (doc["warn_files_in"] || []).compact.map { |compound_path_str|
494
+ compound_path_str.split(":").map { |str| Pathname.new(str) }
495
+ }.flatten
496
+ @warn_files_not_in =
497
+ (doc["warn_files_not_in"] || []).compact.map { |compound_path_str|
498
+ compound_path_str.split(":").map { |str| Pathname.new(str) }
499
+ }.flatten
495
500
  @individual_selection = doc["individual_selection"]
496
501
  @exclusion = Exclusion.new(doc["exclusion"])
497
502
  @inclusion = Inclusion.new(doc["inclusion"])
498
- str_hash_array = doc["change_list"] || []
499
- @change_list = str_hash_array.each_with_object({}) { |(id, content), h|
500
- h[[content["package"], id.intern]] = content
501
- }
503
+ @change_list =
504
+ (doc["change_list"] || []).each_with_object({}) { |(id, content), hash|
505
+ hash[[content["package"], id.intern]] = content
506
+ }
502
507
  end
503
508
 
504
509
  def name
@@ -511,8 +516,11 @@ module AdLint #:nodoc:
511
516
  attr_reader :message_with_class
512
517
  ensure_true_or_false_of :message_with_class
513
518
 
514
- attr_reader :warn_only_files_in
515
- ensure_dir_presence_of :warn_only_files_in, :allow_nil => true
519
+ attr_reader :warn_files_in
520
+ ensure_dirs_presence_of :warn_files_in
521
+
522
+ attr_reader :warn_files_not_in
523
+ ensure_dirs_presence_of :warn_files_not_in
516
524
 
517
525
  attr_reader :individual_selection
518
526
  ensure_true_or_false_of :individual_selection
@@ -589,6 +597,12 @@ module AdLint #:nodoc:
589
597
 
590
598
  def freeze
591
599
  @language.freeze
600
+ @message_with_class.freeze
601
+ @warn_files_in.freeze
602
+ @warn_files_not_in.freeze
603
+ @individual_selection.freeze
604
+ @exclusion.freeze
605
+ @inclusion.freeze
592
606
  @change_list.freeze
593
607
  super
594
608
  end
data/lib/adlint/util.rb CHANGED
@@ -367,6 +367,12 @@ module AdLint #:nodoc:
367
367
  def execute(attr_owner)
368
368
  value = target_value(attr_owner)
369
369
 
370
+ if value.empty?
371
+ @errors.push("`#{qualified_attr_name(attr_owner)}' " +
372
+ "is not specified.")
373
+ return false
374
+ end
375
+
370
376
  bad_exams = value.reject { |exam_package| exam_package.load }
371
377
 
372
378
  unless bad_exams.empty?
@@ -32,11 +32,11 @@
32
32
  module AdLint #:nodoc:
33
33
 
34
34
  MAJOR_VERSION = 2
35
- MINOR_VERSION = 2
35
+ MINOR_VERSION = 4
36
36
  PATCH_VERSION = 0
37
- RELEASE_DATE = "2012-09-12"
37
+ RELEASE_DATE = "2012-09-21"
38
38
 
39
- TRAITS_SCHEMA_VERSION = "2.0.0"
39
+ TRAITS_SCHEMA_VERSION = "2.4.0"
40
40
 
41
41
  SHORT_VERSION = "#{MAJOR_VERSION}.#{MINOR_VERSION}.#{PATCH_VERSION}"
42
42
 
@@ -1,8 +1,8 @@
1
1
  <html lang="ja">
2
2
  <head>
3
- <title>AdLint 2.2.0 開発者ガイド</title>
3
+ <title>AdLint 2.4.0 開発者ガイド</title>
4
4
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
- <meta name="description" content="AdLint 2.2.0 開発者ガイド">
5
+ <meta name="description" content="AdLint 2.4.0 開発者ガイド">
6
6
  <meta name="generator" content="makeinfo 4.13">
7
7
  <link title="Top" rel="top" href="#Top">
8
8
  <link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
@@ -44,7 +44,7 @@ td { border: 1px solid black; }
44
44
  --></style>
45
45
  </head>
46
46
  <body>
47
- <h1 class="settitle">AdLint 2.2.0 開発者ガイド</h1>
47
+ <h1 class="settitle">AdLint 2.4.0 開発者ガイド</h1>
48
48
  <div class="contents">
49
49
  <h2>Table of Contents</h2>
50
50
  <ul>
@@ -2,7 +2,7 @@
2
2
  @setfilename developers_guide_ja.info
3
3
  @documentlanguage ja
4
4
  @documentencoding utf-8
5
- @settitle AdLint 2.2.0 開発者ガイド
5
+ @settitle AdLint 2.4.0 開発者ガイド
6
6
 
7
7
  @copying
8
8
  Copyright (C) 2010-2012, OGIS-RI Co.,Ltd.