()
| 298 | * Validates that return alias exists in the macro body. |
| 299 | */ |
| 300 | void validate() throws IOException { |
| 301 | if (rets.isEmpty()) { |
| 302 | return; |
| 303 | } |
| 304 | |
| 305 | HashSet<String> testSet = new HashSet<String>(); |
| 306 | |
| 307 | StreamTokenizer st = new StreamTokenizer(new StringReader(body)); |
| 308 | |
| 309 | st.wordChars('.', '.'); |
| 310 | st.wordChars('0', '9'); |
| 311 | st.wordChars('_', '_'); |
| 312 | st.wordChars('$', '$'); |
| 313 | st.lowerCaseMode(false); |
| 314 | st.ordinaryChar('/'); |
| 315 | st.slashStarComments(true); |
| 316 | |
| 317 | while (st.nextToken() != StreamTokenizer.TT_EOF) { |
| 318 | if (matchWord(st, "define", false) && matchDollarAlias(st, true)) { |
| 319 | testSet.add(st.sval.substring(1)); |
| 320 | } else if (matchDollarAlias(st, false)) { |
| 321 | String prevWord = st.sval; |
| 322 | if (matchWord(st, "if", true) || matchWord(st, "otherwise", true)) { |
| 323 | testSet.add(prevWord.substring(1)); |
| 324 | } else if (matchChar(st, '=', true) && !matchChar(st, '=', true)) { |
| 325 | testSet.add(prevWord.substring(1)); |
| 326 | } else if (matchChar(st, ',', true)) { |
| 327 | // possible mult-alias inlining of a macro |
| 328 | ArrayList<String> mlist = new ArrayList<String>(); |
| 329 | mlist.add(prevWord); |
| 330 | if (isMultiValueReturn(st, mlist, true)) { |
| 331 | for (String s : mlist) { |
| 332 | testSet.add(s.substring(1)); |
| 333 | } |
| 334 | } |
| 335 | } |
| 336 | } else if (matchChar(st, '-', false) && matchChar(st, '-', true)) { |
| 337 | skipSingleLineComment(st); |
| 338 | } |
| 339 | } |
| 340 | |
| 341 | for (String s : rets) { |
| 342 | if (!testSet.contains(s)) { |
| 343 | throw new IOException("Macro '" + name |
| 344 | + "' missing return alias: " + s); |
| 345 | } |
| 346 | } |
| 347 | } |
| 348 | |
| 349 | // check for multi-value return pattern: alias, alias, ..., alias = |
| 350 | private static boolean isMultiValueReturn(StreamTokenizer st, |
no test coverage detected