adlint 2.2.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
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.