From ae212aa9cf0c7ed3bf76d85e4f62b328d4378176 Mon Sep 17 00:00:00 2001 From: Shevek Date: Wed, 15 Apr 2015 11:30:38 -0700 Subject: Backport source API to Java 1.5 for compatibility. --- src/main/java/org/anarres/cpp/CppReader.java | 5 ++++- src/main/java/org/anarres/cpp/NumericValue.java | 6 ++++-- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'src/main') diff --git a/src/main/java/org/anarres/cpp/CppReader.java b/src/main/java/org/anarres/cpp/CppReader.java index 5517f47..4da49a5 100644 --- a/src/main/java/org/anarres/cpp/CppReader.java +++ b/src/main/java/org/anarres/cpp/CppReader.java @@ -111,7 +111,10 @@ public class CppReader extends Reader implements Closeable { } return true; } catch (LexerException e) { - throw new IOException(String.valueOf(e), e); + // new IOException(String, Throwable) is since 1.6 + IOException _e = new IOException(String.valueOf(e)); + _e.initCause(e); + throw _e; } } diff --git a/src/main/java/org/anarres/cpp/NumericValue.java b/src/main/java/org/anarres/cpp/NumericValue.java index e4235d3..7feb758 100644 --- a/src/main/java/org/anarres/cpp/NumericValue.java +++ b/src/main/java/org/anarres/cpp/NumericValue.java @@ -135,7 +135,8 @@ public class NumericValue extends Number { @Override public int intValue() { - int v = integer.isEmpty() ? 0 : Integer.parseInt(integer, base); + // String.isEmpty() is since 1.6 + int v = integer.length() == 0 ? 0 : Integer.parseInt(integer, base); if (expbase == 2) v = v << exponentValue(); else if (expbase != 0) @@ -145,7 +146,8 @@ public class NumericValue extends Number { @Override public long longValue() { - long v = integer.isEmpty() ? 0 : Long.parseLong(integer, base); + // String.isEmpty() is since 1.6 + long v = integer.length() == 0 ? 0 : Long.parseLong(integer, base); if (expbase == 2) v = v << exponentValue(); else if (expbase != 0) -- cgit v1.2.3 From 0945363c62d31735e1a172c42410f54b783fd35b Mon Sep 17 00:00:00 2001 From: Shevek Date: Wed, 15 Apr 2015 11:36:22 -0700 Subject: Improve javadoc. --- src/main/java/org/anarres/cpp/LexerSource.java | 21 +++++++++--- src/main/java/org/anarres/cpp/Preprocessor.java | 41 +++++++++++++++++++---- src/main/java/org/anarres/cpp/SourceIterator.java | 2 +- src/main/java/org/anarres/cpp/Token.java | 27 +++++++++++++-- 4 files changed, 78 insertions(+), 13 deletions(-) (limited to 'src/main') diff --git a/src/main/java/org/anarres/cpp/LexerSource.java b/src/main/java/org/anarres/cpp/LexerSource.java index 82d76b6..931f4a7 100644 --- a/src/main/java/org/anarres/cpp/LexerSource.java +++ b/src/main/java/org/anarres/cpp/LexerSource.java @@ -68,11 +68,25 @@ public class LexerSource extends Source { this.reader.init(pp, this); } + /** + * Returns the line number of the last read character in this source. + * + * Lines are numbered from 1. + * + * @return the line number of the last read character in this source. + */ @Override public int getLine() { return line; } + /** + * Returns the column number of the last read character in this source. + * + * Columns are numbered from 0. + * + * @return the column number of the last read character in this source. + */ @Override public int getColumn() { return column; @@ -513,8 +527,7 @@ public class LexerSource extends Source { flags |= NumericValue.F_DOUBLE; text.append((char) d); d = read(); - } - else if (Character.isUnicodeIdentifierPart(d)) { + } else if (Character.isUnicodeIdentifierPart(d)) { String reason = "Invalid suffix \"" + (char) d + "\" on numeric constant"; // We've encountered something initially identified as a number. // Read in the rest of this token as an identifer but return it as an invalid. @@ -628,9 +641,9 @@ public class LexerSource extends Source { /** * Section 6.4.4.1 of C99 - * + * * (Not pasted here, but says that the initial negation is a separate token.) - * + * * Section 6.4.4.2 of C99 * * A floating constant has a significand part that may be followed diff --git a/src/main/java/org/anarres/cpp/Preprocessor.java b/src/main/java/org/anarres/cpp/Preprocessor.java index 27f609f..a790813 100644 --- a/src/main/java/org/anarres/cpp/Preprocessor.java +++ b/src/main/java/org/anarres/cpp/Preprocessor.java @@ -351,6 +351,8 @@ public class Preprocessor implements Closeable { * * The given {@link Macro} object encapsulates both the name * and the expansion. + * + * @throws LexerException if the definition fails or is otherwise illegal. */ public void addMacro(@Nonnull Macro m) throws LexerException { // System.out.println("Macro " + m); @@ -366,6 +368,8 @@ public class Preprocessor implements Closeable { * * The String value is lexed into a token stream, which is * used as the macro expansion. + * + * @throws LexerException if the definition fails or is otherwise illegal. */ public void addMacro(@Nonnull String name, @Nonnull String value) throws LexerException { @@ -389,6 +393,8 @@ public class Preprocessor implements Closeable { * * This is a convnience method, and is equivalent to * addMacro(name, "1"). + * + * @throws LexerException if the definition fails or is otherwise illegal. */ public void addMacro(@Nonnull String name) throws LexerException { @@ -453,6 +459,8 @@ public class Preprocessor implements Closeable { /** * Returns the Map of Macros parsed during the run of this * Preprocessor. + * + * @return The {@link Map} of macros currently defined. */ @Nonnull public Map getMacros() { @@ -464,9 +472,11 @@ public class Preprocessor implements Closeable { * * While you can modify the returned object, unexpected things * might happen if you do. + * + * @return the Macro object, or null if not found. */ @CheckForNull - public Macro getMacro(String name) { + public Macro getMacro(@Nonnull String name) { return macros.get(name); } @@ -510,6 +520,8 @@ public class Preprocessor implements Closeable { * @see Source * @see #push_source(Source,boolean) * @see #pop_source() + * + * @return the top Source on the input stack. */ // @CheckForNull protected Source getSource() { @@ -519,6 +531,8 @@ public class Preprocessor implements Closeable { /** * Pushes a Source onto the input stack. * + * @param source the new Source to push onto the top of the input stack. + * @param autopop if true, the Source is automatically removed from the input stack at EOF. * @see #getSource() * @see #pop_source() */ @@ -538,6 +552,9 @@ public class Preprocessor implements Closeable { * * @see #getSource() * @see #push_source(Source,boolean) + * + * @param linemarker TODO: currently ignored, might be a bug? + * @throws IOException if an I/O error occurs. */ @CheckForNull protected Token pop_source(boolean linemarker) @@ -1114,10 +1131,13 @@ public class Preprocessor implements Closeable { * * User code may override this method to implement a virtual * file system. + * + * @param file The VirtualFile to attempt to include. + * @return true if the file was successfully included, false otherwise. + * @throws IOException if an I/O error occurs. */ protected boolean include(@Nonnull VirtualFile file) - throws IOException, - LexerException { + throws IOException { // System.out.println("Try to include " + ((File)file).getAbsolutePath()); if (!file.isFile()) return false; @@ -1129,11 +1149,15 @@ public class Preprocessor implements Closeable { } /** - * Includes a file from an include path, by name. + * Attempts to include a file from an include path, by name. + * + * @param path The list of virtual directories to search for the given name. + * @param name The name of the file to attempt to include. + * @return true if the file was successfully included, false otherwise. + * @throws IOException if an I/O error occurs. */ protected boolean include(@Nonnull Iterable path, @Nonnull String name) - throws IOException, - LexerException { + throws IOException { for (String dir : path) { VirtualFile file = getFileSystem().getFile(dir, name); if (include(file)) @@ -1144,6 +1168,9 @@ public class Preprocessor implements Closeable { /** * Handles an include directive. + * + * @throws IOException if an I/O error occurs. + * @throws LexerException if the include fails, and the error handler is fatal. */ private void include( @CheckForNull String parent, int line, @@ -2093,6 +2120,8 @@ public class Preprocessor implements Closeable { * Returns the next preprocessor token. * * @see Token + * @return The next fully preprocessed token. + * @throws IOException if an I/O error occurs. * @throws LexerException if a preprocessing error occurs. * @throws InternalException if an unexpected error condition arises. */ diff --git a/src/main/java/org/anarres/cpp/SourceIterator.java b/src/main/java/org/anarres/cpp/SourceIterator.java index 82e36d9..240b3b3 100644 --- a/src/main/java/org/anarres/cpp/SourceIterator.java +++ b/src/main/java/org/anarres/cpp/SourceIterator.java @@ -79,7 +79,7 @@ public class SourceIterator implements Iterator { /** * Not supported. * - * @throws UnsupportedOperationException. + * @throws UnsupportedOperationException unconditionally. */ public void remove() { throw new UnsupportedOperationException(); diff --git a/src/main/java/org/anarres/cpp/Token.java b/src/main/java/org/anarres/cpp/Token.java index 3e6eb3e..b80c1ae 100644 --- a/src/main/java/org/anarres/cpp/Token.java +++ b/src/main/java/org/anarres/cpp/Token.java @@ -16,6 +16,9 @@ */ package org.anarres.cpp; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + /** * A Preprocessor token. * @@ -57,6 +60,9 @@ public final class Token { /** * Returns the semantic type of this token. + * + * @return the semantic type of this token. + * @see #getTokenName(int) */ public int getType() { return type; @@ -70,8 +76,12 @@ public final class Token { /** * Returns the line at which this token started. * - * Lines are numbered from zero. + * Lines are numbered from 1. + * + * @return the line at which this token started. + * @see LexerSource#getLine() */ + // Not @Nonnegative - might not have been assigned? public int getLine() { return line; } @@ -79,8 +89,12 @@ public final class Token { /** * Returns the column at which this token started. * - * Columns are numbered from zero. + * Columns are numbered from 0. + * + * @return the column at which this token started. + * @see LexerSource#getColumn() */ + // Not @Nonnegative - might not have been assigned? public int getColumn() { return column; } @@ -90,8 +104,10 @@ public final class Token { * * This is distinct from the semantic value of the token. * + * @return the original or generated text of this token. * @see #getValue() */ + // Not @Nonnull - might not have been assigned? public String getText() { return text; } @@ -103,8 +119,10 @@ public final class Token { * For integers, this is an Integer object. * For other token types, as appropriate. * + * @return the semantic value of this token, or null. * @see #getText() */ + @CheckForNull public Object getValue() { return value; } @@ -138,7 +156,12 @@ public final class Token { * Returns the descriptive name of the given token type. * * This is mostly used for stringification and debugging. + * + * @param type The type constant from this class to name. + * @return the descriptive name of the given token type. + * @see Token#getType() */ + @Nonnull public static String getTokenName(int type) { return TokenType.getTokenName(type); } -- cgit v1.2.3 From 1bb60e9a9bc4f2f38958ca42e98134aa6dc13470 Mon Sep 17 00:00:00 2001 From: Shevek Date: Wed, 13 May 2015 12:28:39 -0700 Subject: Fix #29 - line directives out by one on pop_source. Hard to unit test without a CONSUMER for #line directives. --- src/main/java/org/anarres/cpp/Preprocessor.java | 2 +- src/test/resources/lines.c | 9 +++++++++ src/test/resources/lines1.h | 18 ++++++++++++++++++ src/test/resources/lines2.h | 10 ++++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/lines.c create mode 100644 src/test/resources/lines1.h create mode 100644 src/test/resources/lines2.h (limited to 'src/main') diff --git a/src/main/java/org/anarres/cpp/Preprocessor.java b/src/main/java/org/anarres/cpp/Preprocessor.java index a790813..59d8ba8 100644 --- a/src/main/java/org/anarres/cpp/Preprocessor.java +++ b/src/main/java/org/anarres/cpp/Preprocessor.java @@ -575,7 +575,7 @@ public class Preprocessor implements Closeable { /* We actually want 'did the nested source * contain a newline token', which isNumbered() * approximates. This is not perfect, but works. */ - return line_token(t.getLine() + 1, t.getName(), " 2"); + return line_token(t.getLine(), t.getName(), " 2"); } return null; diff --git a/src/test/resources/lines.c b/src/test/resources/lines.c new file mode 100644 index 0000000..e0fc75c --- /dev/null +++ b/src/test/resources/lines.c @@ -0,0 +1,9 @@ +lines-c-line-1 +#include +lines-c-line-3 + +lines-c-line-5 + +#include + +lines-c-line-9 diff --git a/src/test/resources/lines1.h b/src/test/resources/lines1.h new file mode 100644 index 0000000..934a3a9 --- /dev/null +++ b/src/test/resources/lines1.h @@ -0,0 +1,18 @@ + +lines1-h-line-2 + +/* multi +line +comment +*/ + +#include +lines1-h-line-10 + +lines1-h-line-12 +#include + +/* trailing multiline comment +with +more lines +*/ diff --git a/src/test/resources/lines2.h b/src/test/resources/lines2.h new file mode 100644 index 0000000..0a71f2f --- /dev/null +++ b/src/test/resources/lines2.h @@ -0,0 +1,10 @@ + +lines2-h-line-2 + +/* +comment + +blank and multiline*/ + +lines2-h-line-9 + -- cgit v1.2.3 From 64f955703ce6cabbc26e5806b91a28e67591446e Mon Sep 17 00:00:00 2001 From: Shevek Date: Wed, 13 May 2015 12:31:06 -0700 Subject: Fix two javadoc @param warnings. --- src/main/java/org/anarres/cpp/StringLexerSource.java | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/main') diff --git a/src/main/java/org/anarres/cpp/StringLexerSource.java b/src/main/java/org/anarres/cpp/StringLexerSource.java index 8640bc8..853cc3a 100644 --- a/src/main/java/org/anarres/cpp/StringLexerSource.java +++ b/src/main/java/org/anarres/cpp/StringLexerSource.java @@ -29,6 +29,7 @@ public class StringLexerSource extends LexerSource { /** * Creates a new Source for lexing the given String. * + * @param string The input string to lex. * @param ppvalid true if preprocessor directives are to be * honoured within the string. */ @@ -39,8 +40,12 @@ public class StringLexerSource extends LexerSource { /** * Creates a new Source for lexing the given String. * + * Equivalent to calling new StringLexerSource(string, false). + * * By default, preprocessor directives are not honoured within * the string. + * + * @param string The input string to lex. */ public StringLexerSource(String string) { this(string, false); -- cgit v1.2.3 From 26f43a21561cdc5586ba8a8af78c548def36b3f2 Mon Sep 17 00:00:00 2001 From: Shevek Date: Tue, 19 May 2015 13:33:20 -0700 Subject: Fix #27: Don't preprocess pragma tokens. --- src/main/java/org/anarres/cpp/Preprocessor.java | 6 ++-- src/test/java/org/anarres/cpp/PragmaTest.java | 39 +++++++++++++++++++++++++ src/test/resources/pragma.c | 8 +++++ 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 src/test/java/org/anarres/cpp/PragmaTest.java create mode 100644 src/test/resources/pragma.c (limited to 'src/main') diff --git a/src/main/java/org/anarres/cpp/Preprocessor.java b/src/main/java/org/anarres/cpp/Preprocessor.java index 59d8ba8..1be126f 100644 --- a/src/main/java/org/anarres/cpp/Preprocessor.java +++ b/src/main/java/org/anarres/cpp/Preprocessor.java @@ -1322,7 +1322,7 @@ public class Preprocessor implements Closeable { NAME: for (;;) { - Token tok = token(); + Token tok = source_token(); switch (tok.getType()) { case EOF: /* There ought to be a newline before EOF. @@ -1344,6 +1344,8 @@ public class Preprocessor implements Closeable { name = tok; break NAME; default: + warning(tok, + "Illegal #" + "pragma " + tok.getText()); return source_skipline(false); } } @@ -1352,7 +1354,7 @@ public class Preprocessor implements Closeable { List value = new ArrayList(); VALUE: for (;;) { - tok = token(); + tok = source_token(); switch (tok.getType()) { case EOF: /* There ought to be a newline before EOF. diff --git a/src/test/java/org/anarres/cpp/PragmaTest.java b/src/test/java/org/anarres/cpp/PragmaTest.java new file mode 100644 index 0000000..342bd52 --- /dev/null +++ b/src/test/java/org/anarres/cpp/PragmaTest.java @@ -0,0 +1,39 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.anarres.cpp; + +import com.google.common.base.Charsets; +import com.google.common.io.CharSource; +import com.google.common.io.CharStreams; +import com.google.common.io.Files; +import java.io.File; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import static org.junit.Assert.*; + +/** + * + * @author shevek + */ +public class PragmaTest { + + private static final Logger LOG = LoggerFactory.getLogger(PragmaTest.class); + + @Test + public void testPragma() throws Exception { + File file = new File("build/resources/test/pragma.c"); + assertTrue(file.exists()); + + CharSource source = Files.asCharSource(file, Charsets.UTF_8); + CppReader r = new CppReader(source.openBufferedStream()); + r.getPreprocessor().setListener(new DefaultPreprocessorListener()); + String output = CharStreams.toString(r); + r.close(); + LOG.info("Output: " + output); + // assertTrue(output.contains("absolute-result")); + } +} diff --git a/src/test/resources/pragma.c b/src/test/resources/pragma.c new file mode 100644 index 0000000..6018958 --- /dev/null +++ b/src/test/resources/pragma.c @@ -0,0 +1,8 @@ + +#pragma +#pragma once +#pragma foo(bar) +#pragma #pragma +#pragma #include +#pragma #include + -- cgit v1.2.3 From 0ff16b1540429b3fda0649a4d9ee7509ec5007eb Mon Sep 17 00:00:00 2001 From: Shevek Date: Mon, 15 Jun 2015 16:42:08 -0700 Subject: LexerSource: Comment escape() --- src/main/java/org/anarres/cpp/LexerSource.java | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/main') diff --git a/src/main/java/org/anarres/cpp/LexerSource.java b/src/main/java/org/anarres/cpp/LexerSource.java index 931f4a7..de3da8d 100644 --- a/src/main/java/org/anarres/cpp/LexerSource.java +++ b/src/main/java/org/anarres/cpp/LexerSource.java @@ -305,6 +305,13 @@ public class LexerSource extends Source { return new Token(CPPCOMMENT, text.toString()); } + /** + * Lexes an escaped character, appends the lexed escape sequence to 'text' and returns the parsed character value. + * @param text The buffer to which the literal escape sequence is appended. + * @return The new parsed character value. + * @throws IOException if it goes badly wrong. + * @throws LexerException if it goes wrong. + */ private int escape(StringBuilder text) throws IOException, LexerException { -- cgit v1.2.3 From 391fbe5ac9a6b5cdb64965a90cbeecb680dfe2be Mon Sep 17 00:00:00 2001 From: Shevek Date: Mon, 15 Jun 2015 16:42:23 -0700 Subject: NumericValue: Deal slightly more elegantly with unadorned longs. --- src/main/java/org/anarres/cpp/NumericValue.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src/main') diff --git a/src/main/java/org/anarres/cpp/NumericValue.java b/src/main/java/org/anarres/cpp/NumericValue.java index 7feb758..65544e9 100644 --- a/src/main/java/org/anarres/cpp/NumericValue.java +++ b/src/main/java/org/anarres/cpp/NumericValue.java @@ -41,7 +41,7 @@ public class NumericValue extends Number { private String exponent; private int flags; - public NumericValue(int base, String integer) { + public NumericValue(@Nonnegative int base, @Nonnull String integer) { this.base = base; this.integer = integer; } @@ -61,7 +61,7 @@ public class NumericValue extends Number { return fraction; } - /* pp */ void setFractionalPart(String fraction) { + /* pp */ void setFractionalPart(@Nonnull String fraction) { this.fraction = fraction; } @@ -75,7 +75,7 @@ public class NumericValue extends Number { return exponent; } - /* pp */ void setExponent(int expbase, String exponent) { + /* pp */ void setExponent(@Nonnegative int expbase, @Nonnull String exponent) { this.expbase = expbase; this.exponent = exponent; } @@ -125,8 +125,12 @@ public class NumericValue extends Number { return doubleValue(); // .1 is a double in Java. else if (getExponent() != null) return doubleValue(); - else - return intValue(); + else { + long value = longValue(); + if (value <= Integer.MAX_VALUE && value >= Integer.MIN_VALUE) + return (int) value; + return value; + } } private int exponentValue() { -- cgit v1.2.3 From c5f21d5d4316b338590307801b49e72e0b2806a6 Mon Sep 17 00:00:00 2001 From: Shevek Date: Mon, 15 Jun 2015 16:44:38 -0700 Subject: Update copyrights to 2015. --- src/main/java/org/anarres/cpp/Argument.java | 2 +- src/main/java/org/anarres/cpp/ChrootFileSystem.java | 2 +- src/main/java/org/anarres/cpp/CppReader.java | 2 +- src/main/java/org/anarres/cpp/CppTask.java | 2 +- src/main/java/org/anarres/cpp/DefaultPreprocessorListener.java | 2 +- src/main/java/org/anarres/cpp/Feature.java | 2 +- src/main/java/org/anarres/cpp/FileLexerSource.java | 2 +- src/main/java/org/anarres/cpp/FixedTokenSource.java | 2 +- src/main/java/org/anarres/cpp/InputLexerSource.java | 2 +- src/main/java/org/anarres/cpp/InternalException.java | 2 +- src/main/java/org/anarres/cpp/JavaFileSystem.java | 2 +- src/main/java/org/anarres/cpp/JoinReader.java | 2 +- src/main/java/org/anarres/cpp/LexerException.java | 2 +- src/main/java/org/anarres/cpp/LexerSource.java | 2 +- src/main/java/org/anarres/cpp/Macro.java | 2 +- src/main/java/org/anarres/cpp/MacroTokenSource.java | 2 +- src/main/java/org/anarres/cpp/Main.java | 4 ++-- src/main/java/org/anarres/cpp/NumericValue.java | 2 +- src/main/java/org/anarres/cpp/Preprocessor.java | 2 +- src/main/java/org/anarres/cpp/PreprocessorListener.java | 2 +- src/main/java/org/anarres/cpp/Source.java | 2 +- src/main/java/org/anarres/cpp/SourceIterator.java | 2 +- src/main/java/org/anarres/cpp/State.java | 2 +- src/main/java/org/anarres/cpp/StringLexerSource.java | 2 +- src/main/java/org/anarres/cpp/Token.java | 2 +- src/main/java/org/anarres/cpp/TokenSnifferSource.java | 2 +- src/main/java/org/anarres/cpp/VirtualFile.java | 2 +- src/main/java/org/anarres/cpp/VirtualFileSystem.java | 2 +- src/main/java/org/anarres/cpp/Warning.java | 2 +- 29 files changed, 30 insertions(+), 30 deletions(-) (limited to 'src/main') diff --git a/src/main/java/org/anarres/cpp/Argument.java b/src/main/java/org/anarres/cpp/Argument.java index 31d9e93..1dd547d 100644 --- a/src/main/java/org/anarres/cpp/Argument.java +++ b/src/main/java/org/anarres/cpp/Argument.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/ChrootFileSystem.java b/src/main/java/org/anarres/cpp/ChrootFileSystem.java index 1cec184..5abf2f8 100644 --- a/src/main/java/org/anarres/cpp/ChrootFileSystem.java +++ b/src/main/java/org/anarres/cpp/ChrootFileSystem.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/CppReader.java b/src/main/java/org/anarres/cpp/CppReader.java index 4da49a5..c3c6431 100644 --- a/src/main/java/org/anarres/cpp/CppReader.java +++ b/src/main/java/org/anarres/cpp/CppReader.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/CppTask.java b/src/main/java/org/anarres/cpp/CppTask.java index 66df1a6..a569054 100644 --- a/src/main/java/org/anarres/cpp/CppTask.java +++ b/src/main/java/org/anarres/cpp/CppTask.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/DefaultPreprocessorListener.java b/src/main/java/org/anarres/cpp/DefaultPreprocessorListener.java index 40a8686..e8e850e 100644 --- a/src/main/java/org/anarres/cpp/DefaultPreprocessorListener.java +++ b/src/main/java/org/anarres/cpp/DefaultPreprocessorListener.java @@ -2,7 +2,7 @@ package org.anarres.cpp; /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/Feature.java b/src/main/java/org/anarres/cpp/Feature.java index 369d79c..76c582d 100644 --- a/src/main/java/org/anarres/cpp/Feature.java +++ b/src/main/java/org/anarres/cpp/Feature.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/FileLexerSource.java b/src/main/java/org/anarres/cpp/FileLexerSource.java index bdc411f..b3b3e88 100644 --- a/src/main/java/org/anarres/cpp/FileLexerSource.java +++ b/src/main/java/org/anarres/cpp/FileLexerSource.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/FixedTokenSource.java b/src/main/java/org/anarres/cpp/FixedTokenSource.java index 4d9f41f..fdfd328 100644 --- a/src/main/java/org/anarres/cpp/FixedTokenSource.java +++ b/src/main/java/org/anarres/cpp/FixedTokenSource.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/InputLexerSource.java b/src/main/java/org/anarres/cpp/InputLexerSource.java index 93cda54..1e5b410 100644 --- a/src/main/java/org/anarres/cpp/InputLexerSource.java +++ b/src/main/java/org/anarres/cpp/InputLexerSource.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/InternalException.java b/src/main/java/org/anarres/cpp/InternalException.java index fc3b650..e3a7a6e 100644 --- a/src/main/java/org/anarres/cpp/InternalException.java +++ b/src/main/java/org/anarres/cpp/InternalException.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/JavaFileSystem.java b/src/main/java/org/anarres/cpp/JavaFileSystem.java index a60271d..39ae72c 100644 --- a/src/main/java/org/anarres/cpp/JavaFileSystem.java +++ b/src/main/java/org/anarres/cpp/JavaFileSystem.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/JoinReader.java b/src/main/java/org/anarres/cpp/JoinReader.java index c39ee79..5ce08ea 100644 --- a/src/main/java/org/anarres/cpp/JoinReader.java +++ b/src/main/java/org/anarres/cpp/JoinReader.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/LexerException.java b/src/main/java/org/anarres/cpp/LexerException.java index d4b2e9c..b5a1800 100644 --- a/src/main/java/org/anarres/cpp/LexerException.java +++ b/src/main/java/org/anarres/cpp/LexerException.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/LexerSource.java b/src/main/java/org/anarres/cpp/LexerSource.java index de3da8d..7e39a21 100644 --- a/src/main/java/org/anarres/cpp/LexerSource.java +++ b/src/main/java/org/anarres/cpp/LexerSource.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/Macro.java b/src/main/java/org/anarres/cpp/Macro.java index 7ab38a8..62b0532 100644 --- a/src/main/java/org/anarres/cpp/Macro.java +++ b/src/main/java/org/anarres/cpp/Macro.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/MacroTokenSource.java b/src/main/java/org/anarres/cpp/MacroTokenSource.java index b512c3d..238ab40 100644 --- a/src/main/java/org/anarres/cpp/MacroTokenSource.java +++ b/src/main/java/org/anarres/cpp/MacroTokenSource.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/Main.java b/src/main/java/org/anarres/cpp/Main.java index acf2436..3bef07b 100644 --- a/src/main/java/org/anarres/cpp/Main.java +++ b/src/main/java/org/anarres/cpp/Main.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -188,7 +188,7 @@ public class Main { private static void version(@Nonnull PrintStream out) { BuildMetadata metadata = BuildMetadata.getInstance(); out.println("Anarres Java C Preprocessor version " + metadata.getVersion() + " change-id " + metadata.getChangeId()); - out.println("Copyright (C) 2008-2014 Shevek (http://www.anarres.org/)."); + out.println("Copyright (C) 2007-2015 Shevek (http://www.anarres.org/)."); out.println("This is free software; see the source for copying conditions. There is NO"); out.println("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."); } diff --git a/src/main/java/org/anarres/cpp/NumericValue.java b/src/main/java/org/anarres/cpp/NumericValue.java index 65544e9..496b6f1 100644 --- a/src/main/java/org/anarres/cpp/NumericValue.java +++ b/src/main/java/org/anarres/cpp/NumericValue.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/Preprocessor.java b/src/main/java/org/anarres/cpp/Preprocessor.java index 1be126f..2bbea4e 100644 --- a/src/main/java/org/anarres/cpp/Preprocessor.java +++ b/src/main/java/org/anarres/cpp/Preprocessor.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/PreprocessorListener.java b/src/main/java/org/anarres/cpp/PreprocessorListener.java index 0d3f7fc..48308d8 100644 --- a/src/main/java/org/anarres/cpp/PreprocessorListener.java +++ b/src/main/java/org/anarres/cpp/PreprocessorListener.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/Source.java b/src/main/java/org/anarres/cpp/Source.java index d25e553..a4e1bd9 100644 --- a/src/main/java/org/anarres/cpp/Source.java +++ b/src/main/java/org/anarres/cpp/Source.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/SourceIterator.java b/src/main/java/org/anarres/cpp/SourceIterator.java index 240b3b3..db16f01 100644 --- a/src/main/java/org/anarres/cpp/SourceIterator.java +++ b/src/main/java/org/anarres/cpp/SourceIterator.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/State.java b/src/main/java/org/anarres/cpp/State.java index e24195d..b6f3ada 100644 --- a/src/main/java/org/anarres/cpp/State.java +++ b/src/main/java/org/anarres/cpp/State.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/StringLexerSource.java b/src/main/java/org/anarres/cpp/StringLexerSource.java index 853cc3a..e3b365a 100644 --- a/src/main/java/org/anarres/cpp/StringLexerSource.java +++ b/src/main/java/org/anarres/cpp/StringLexerSource.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/Token.java b/src/main/java/org/anarres/cpp/Token.java index b80c1ae..a717606 100644 --- a/src/main/java/org/anarres/cpp/Token.java +++ b/src/main/java/org/anarres/cpp/Token.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/TokenSnifferSource.java b/src/main/java/org/anarres/cpp/TokenSnifferSource.java index 21e1cb8..b6ad57a 100644 --- a/src/main/java/org/anarres/cpp/TokenSnifferSource.java +++ b/src/main/java/org/anarres/cpp/TokenSnifferSource.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/VirtualFile.java b/src/main/java/org/anarres/cpp/VirtualFile.java index aee1cad..9e1302e 100644 --- a/src/main/java/org/anarres/cpp/VirtualFile.java +++ b/src/main/java/org/anarres/cpp/VirtualFile.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/VirtualFileSystem.java b/src/main/java/org/anarres/cpp/VirtualFileSystem.java index 9c77d30..9d04857 100644 --- a/src/main/java/org/anarres/cpp/VirtualFileSystem.java +++ b/src/main/java/org/anarres/cpp/VirtualFileSystem.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/anarres/cpp/Warning.java b/src/main/java/org/anarres/cpp/Warning.java index 80d184a..de1b8b6 100644 --- a/src/main/java/org/anarres/cpp/Warning.java +++ b/src/main/java/org/anarres/cpp/Warning.java @@ -1,6 +1,6 @@ /* * Anarres C Preprocessor - * Copyright (c) 2007-2008, Shevek + * Copyright (c) 2007-2015, Shevek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. -- cgit v1.2.3 From 7b5040feb49da30c3a808265007ad3308ae511ee Mon Sep 17 00:00:00 2001 From: Shevek Date: Tue, 16 Jun 2015 10:34:15 -0700 Subject: NumericValue: Overflow a bit later on overlong integers. --- src/main/java/org/anarres/cpp/NumericValue.java | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/main') diff --git a/src/main/java/org/anarres/cpp/NumericValue.java b/src/main/java/org/anarres/cpp/NumericValue.java index 496b6f1..b51ca59 100644 --- a/src/main/java/org/anarres/cpp/NumericValue.java +++ b/src/main/java/org/anarres/cpp/NumericValue.java @@ -110,6 +110,10 @@ public class NumericValue extends Number { return new BigDecimal(unscaled, scale); } + // We could construct a heuristic for when an 'int' is large enough. + // private static final int S_MAXLEN_LONG = String.valueOf(Long.MAX_VALUE).length(); + // private static final int S_MAXLEN_INT = String.valueOf(Integer.MAX_VALUE).length(); + @Nonnull public Number toJavaLangNumber() { int flags = getFlags(); @@ -126,6 +130,9 @@ public class NumericValue extends Number { else if (getExponent() != null) return doubleValue(); else { + // This is an attempt to avoid overflowing on over-long integers. + // However, now we just overflow on over-long longs. + // We should really use BigInteger. long value = longValue(); if (value <= Integer.MAX_VALUE && value >= Integer.MIN_VALUE) return (int) value; -- cgit v1.2.3 From 7832018265ee5e369355381dcc170bdbbdfce65a Mon Sep 17 00:00:00 2001 From: Shevek Date: Tue, 28 Jul 2015 17:27:44 -0700 Subject: Fix some findbugs warnings. --- src/main/java/org/anarres/cpp/CppTask.java | 36 ++++++++++----------- src/main/java/org/anarres/cpp/FileLexerSource.java | 37 ++++++++++++++-------- .../java/org/anarres/cpp/InputLexerSource.java | 26 ++++++++------- src/main/java/org/anarres/cpp/LexerSource.java | 8 +++++ 4 files changed, 64 insertions(+), 43 deletions(-) (limited to 'src/main') diff --git a/src/main/java/org/anarres/cpp/CppTask.java b/src/main/java/org/anarres/cpp/CppTask.java index a569054..cc9c4d3 100644 --- a/src/main/java/org/anarres/cpp/CppTask.java +++ b/src/main/java/org/anarres/cpp/CppTask.java @@ -25,8 +25,6 @@ import java.util.Enumeration; import java.util.List; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.taskdefs.Copy; -import org.apache.tools.ant.types.FilterSet; -import org.apache.tools.ant.types.FilterSetCollection; import org.apache.tools.ant.types.Path; /** @@ -117,6 +115,11 @@ public class CppTask extends Copy { } */ private void preprocess(File input, File output) throws Exception { + if (input == null) + throw new BuildException("Input not specified"); + if (output == null) + throw new BuildException("Output not specified"); + Preprocessor cpp = new Preprocessor(); cpp.setListener(listener); for (Macro macro : macros) @@ -135,10 +138,6 @@ public class CppTask extends Copy { } FileWriter writer = null; try { - if (input == null) - throw new BuildException("Input not specified"); - if (output == null) - throw new BuildException("Output not specified"); cpp.addInput(input); writer = new FileWriter(output); for (;;) { @@ -181,18 +180,19 @@ public class CppTask extends Copy { try { log("Copying " + fromFile + " to " + toFile, verbosity); - FilterSetCollection executionFilters - = new FilterSetCollection(); - if (filtering) { - executionFilters - .addFilterSet(getProject().getGlobalFilterSet()); - } - for (Enumeration filterEnum = getFilterSets().elements(); - filterEnum.hasMoreElements();) { - executionFilters - .addFilterSet((FilterSet) filterEnum.nextElement()); - } - + /* + FilterSetCollection executionFilters + = new FilterSetCollection(); + if (filtering) { + executionFilters + .addFilterSet(getProject().getGlobalFilterSet()); + } + for (Enumeration filterEnum = getFilterSets().elements(); + filterEnum.hasMoreElements();) { + executionFilters + .addFilterSet((FilterSet) filterEnum.nextElement()); + } + */ File srcFile = new File(fromFile); File dstFile = new File(toFile); preprocess(srcFile, dstFile); diff --git a/src/main/java/org/anarres/cpp/FileLexerSource.java b/src/main/java/org/anarres/cpp/FileLexerSource.java index b3b3e88..7dc883a 100644 --- a/src/main/java/org/anarres/cpp/FileLexerSource.java +++ b/src/main/java/org/anarres/cpp/FileLexerSource.java @@ -18,8 +18,10 @@ package org.anarres.cpp; import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; +import java.nio.charset.Charset; import javax.annotation.Nonnull; /** @@ -29,7 +31,7 @@ import javax.annotation.Nonnull; * * @see Source */ -public class FileLexerSource extends LexerSource { +public class FileLexerSource extends InputLexerSource { private final String path; private final File file; @@ -39,29 +41,38 @@ public class FileLexerSource extends LexerSource { * * Preprocessor directives are honoured within the file. */ - public FileLexerSource(@Nonnull File file, String path) + public FileLexerSource(@Nonnull File file, @Nonnull Charset charset, @Nonnull String path) throws IOException { - super( - new BufferedReader( - new FileReader( - file - ) - ), - true - ); - + super(new FileInputStream(file), charset); this.file = file; this.path = path; } + public FileLexerSource(@Nonnull File file, @Nonnull String path) + throws IOException { + this(file, Charset.defaultCharset(), path); + } + + public FileLexerSource(@Nonnull File file, @Nonnull Charset charset) + throws IOException { + this(file, charset, file.getPath()); + } + + @Deprecated public FileLexerSource(@Nonnull File file) throws IOException { - this(file, file.getPath()); + this(file, Charset.defaultCharset()); + } + + public FileLexerSource(@Nonnull String path, @Nonnull Charset charset) + throws IOException { + this(new File(path), charset, path); } + @Deprecated public FileLexerSource(@Nonnull String path) throws IOException { - this(new File(path), path); + this(path, Charset.defaultCharset()); } @Nonnull diff --git a/src/main/java/org/anarres/cpp/InputLexerSource.java b/src/main/java/org/anarres/cpp/InputLexerSource.java index 1e5b410..4f7c03d 100644 --- a/src/main/java/org/anarres/cpp/InputLexerSource.java +++ b/src/main/java/org/anarres/cpp/InputLexerSource.java @@ -16,10 +16,11 @@ */ package org.anarres.cpp; -import java.io.BufferedReader; -import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.Charset; +import javax.annotation.Nonnull; /** * A {@link Source} which lexes a file. @@ -30,21 +31,22 @@ import java.io.InputStreamReader; */ public class InputLexerSource extends LexerSource { + @Deprecated + public InputLexerSource(@Nonnull InputStream input) { + this(input, Charset.defaultCharset()); + } + /** * Creates a new Source for lexing the given Reader. * * Preprocessor directives are honoured within the file. */ - public InputLexerSource(InputStream input) - throws IOException { - super( - new BufferedReader( - new InputStreamReader( - input - ) - ), - true - ); + public InputLexerSource(@Nonnull InputStream input, Charset charset) { + this(new InputStreamReader(input, charset)); + } + + public InputLexerSource(@Nonnull Reader input) { + super(toBufferedReader(input), true); } @Override diff --git a/src/main/java/org/anarres/cpp/LexerSource.java b/src/main/java/org/anarres/cpp/LexerSource.java index 7e39a21..cf4296f 100644 --- a/src/main/java/org/anarres/cpp/LexerSource.java +++ b/src/main/java/org/anarres/cpp/LexerSource.java @@ -16,6 +16,7 @@ */ package org.anarres.cpp; +import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; import javax.annotation.Nonnull; @@ -24,6 +25,13 @@ import static org.anarres.cpp.Token.*; /** Does not handle digraphs. */ public class LexerSource extends Source { + @Nonnull + protected static BufferedReader toBufferedReader(@Nonnull Reader r) { + if (r instanceof BufferedReader) + return (BufferedReader) r; + return new BufferedReader(r); + } + private static final boolean DEBUG = false; private JoinReader reader; -- cgit v1.2.3 From 666bfdd30bce3e68fc6cae8aae1383ec4ea43dd5 Mon Sep 17 00:00:00 2001 From: Shevek Date: Tue, 28 Jul 2015 17:30:35 -0700 Subject: Fix more charset issues. --- src/main/java/org/anarres/cpp/InputLexerSource.java | 2 +- src/main/java/org/anarres/cpp/ResourceFileSystem.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/main') diff --git a/src/main/java/org/anarres/cpp/InputLexerSource.java b/src/main/java/org/anarres/cpp/InputLexerSource.java index 4f7c03d..62612d7 100644 --- a/src/main/java/org/anarres/cpp/InputLexerSource.java +++ b/src/main/java/org/anarres/cpp/InputLexerSource.java @@ -23,7 +23,7 @@ import java.nio.charset.Charset; import javax.annotation.Nonnull; /** - * A {@link Source} which lexes a file. + * A {@link Source} which lexes an {@link InputStream}. * * The input is buffered. * diff --git a/src/main/java/org/anarres/cpp/ResourceFileSystem.java b/src/main/java/org/anarres/cpp/ResourceFileSystem.java index 7efd664..43d6732 100644 --- a/src/main/java/org/anarres/cpp/ResourceFileSystem.java +++ b/src/main/java/org/anarres/cpp/ResourceFileSystem.java @@ -5,10 +5,9 @@ */ package org.anarres.cpp; -import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; +import java.nio.charset.Charset; import javax.annotation.Nonnull; /** @@ -18,9 +17,11 @@ import javax.annotation.Nonnull; public class ResourceFileSystem implements VirtualFileSystem { private final ClassLoader loader; + private final Charset charset; - public ResourceFileSystem(@Nonnull ClassLoader loader) { + public ResourceFileSystem(@Nonnull ClassLoader loader, @Nonnull Charset charset) { this.loader = loader; + this.charset = charset; } @Override @@ -74,8 +75,7 @@ public class ResourceFileSystem implements VirtualFileSystem { @Override public Source getSource() throws IOException { InputStream stream = loader.getResourceAsStream(path); - BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); - return new LexerSource(reader, true); + return new InputLexerSource(stream, charset); } } } -- cgit v1.2.3 From 3a2c42d80f49e0d5c3bc862fff30b7c22af667a7 Mon Sep 17 00:00:00 2001 From: Shevek Date: Tue, 28 Jul 2015 17:31:28 -0700 Subject: Token.getValue() does not merit a @CheckForNull. --- src/main/java/org/anarres/cpp/Token.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main') diff --git a/src/main/java/org/anarres/cpp/Token.java b/src/main/java/org/anarres/cpp/Token.java index a717606..d0e2e6f 100644 --- a/src/main/java/org/anarres/cpp/Token.java +++ b/src/main/java/org/anarres/cpp/Token.java @@ -122,7 +122,7 @@ public final class Token { * @return the semantic value of this token, or null. * @see #getText() */ - @CheckForNull + // @CheckForNull // Not useful to annotate, as we have usually checked the type before calling this. public Object getValue() { return value; } -- cgit v1.2.3 From a031457d300215a11df39ea6da5344af20555ee7 Mon Sep 17 00:00:00 2001 From: Shevek Date: Tue, 17 Nov 2015 12:48:58 -0800 Subject: Test case for #24. --- src/main/java/org/anarres/cpp/Feature.java | 2 +- .../java/org/anarres/cpp/VaArgsPastingTest.java | 63 ++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/anarres/cpp/VaArgsPastingTest.java (limited to 'src/main') diff --git a/src/main/java/org/anarres/cpp/Feature.java b/src/main/java/org/anarres/cpp/Feature.java index 76c582d..a514269 100644 --- a/src/main/java/org/anarres/cpp/Feature.java +++ b/src/main/java/org/anarres/cpp/Feature.java @@ -29,7 +29,7 @@ public enum Feature { LINEMARKERS, /** Reports tokens of type INVALID as errors. */ CSYNTAX, - /** Preserves comments in the lexed output. */ + /** Preserves comments in the lexed output. Like cpp -C */ KEEPCOMMENTS, /** Preserves comments in the lexed output, even when inactive. */ KEEPALLCOMMENTS, diff --git a/src/test/java/org/anarres/cpp/VaArgsPastingTest.java b/src/test/java/org/anarres/cpp/VaArgsPastingTest.java new file mode 100644 index 0000000..7623ebf --- /dev/null +++ b/src/test/java/org/anarres/cpp/VaArgsPastingTest.java @@ -0,0 +1,63 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.anarres.cpp; + +import com.google.common.io.CharStreams; +import java.io.IOException; +import java.io.Reader; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import static org.junit.Assert.*; + +/** + * + * @author shevek + */ +public class VaArgsPastingTest { + + private static final Logger LOG = LoggerFactory.getLogger(VaArgsPastingTest.class); + + @Test + public void testWhitespacePasting() throws IOException { + String input + = "#define REGULAR_ARGS(x, y) foo(x, y)\n" + + "#define REGULAR_ELLIPSIS(x, y...) foo(x, y)\n" + + "#define REGULAR_VAARGS(x, ...) foo(x, __VA_ARGS__)\n" + + "#define PASTE_ARGS(x, y) foo(x, ## y)\n" + + "#define PASTE_ELLIPSIS(x, y...) foo(x, ## y)\n" + + "#define PASTE_VAARGS(x, ...) foo(x, ## __VA_ARGS__)\n" + + "" + + "REGULAR_ARGS(a, b) // REGULAR_ARGS 2\n" + + "REGULAR_ELLIPSIS(a, b) // REGULAR_ELLIPSIS 2\n" + + "REGULAR_ELLIPSIS(a) // REGULAR_ELLIPSIS 1\n" + + "REGULAR_VAARGS(a, b) // REGULAR_VAARGS 2\n" + + "REGULAR_VAARGS(a) // REGULAR_VAARGS 1\n" + + "" + + "PASTE_ARGS(a, b) // PASTE_ARGS 2\n" + + "PASTE_ELLIPSIS(a, b) // PASTE_ELLIPSIS 2\n" + + "PASTE_ELLIPSIS(a) // PASTE_ELLIPSIS 1\n" + + "PASTE_VAARGS(a, b) // PASTE_VAARGS 2\n" + + "PASTE_VAARGS(a) // PASTE_VAARGS 1\n"; + LOG.info("Input is:\n" + input); + Preprocessor pp = new Preprocessor(); + pp.addFeature(Feature.KEEPCOMMENTS); + pp.addInput(new StringLexerSource(input, true)); + Reader r = new CppReader(pp); + String output = CharStreams.toString(r).trim(); + LOG.info("Output is:\n" + output); + assertEquals("foo(a, b) // REGULAR_ARGS 2\n" + + "foo(a, b) // REGULAR_ELLIPSIS 2\n" + + "foo(a, ) // REGULAR_ELLIPSIS 1\n" + + "foo(a, b) // REGULAR_VAARGS 2\n" + + "foo(a, ) // REGULAR_VAARGS 1\n" + + "foo(a,b) // PASTE_ARGS 2\n" // cpp outputs a warning and a space after the comma, similar below. + + "foo(a,b) // PASTE_ELLIPSIS 2\n" + + "foo(a) // PASTE_ELLIPSIS 1\n" + + "foo(a,b) // PASTE_VAARGS 2\n" + + "foo(a) // PASTE_VAARGS 1\n", output); + } +} -- cgit v1.2.3 From 523e439a8de3807fd1d4917a03ad958e5ef91786 Mon Sep 17 00:00:00 2001 From: Shevek Date: Tue, 17 Nov 2015 13:18:05 -0800 Subject: Fix #24: Omit trailing comma pasted onto an empty variadic argument. --- .../java/org/anarres/cpp/MacroTokenSource.java | 35 +++++++++++++++++++++- src/main/java/org/anarres/cpp/SourceIterator.java | 6 +++- .../java/org/anarres/cpp/VaArgsPastingTest.java | 2 +- 3 files changed, 40 insertions(+), 3 deletions(-) (limited to 'src/main') diff --git a/src/main/java/org/anarres/cpp/MacroTokenSource.java b/src/main/java/org/anarres/cpp/MacroTokenSource.java index 238ab40..6423743 100644 --- a/src/main/java/org/anarres/cpp/MacroTokenSource.java +++ b/src/main/java/org/anarres/cpp/MacroTokenSource.java @@ -19,13 +19,17 @@ package org.anarres.cpp; import java.io.IOException; import java.util.Iterator; import java.util.List; +import javax.annotation.Nonnegative; import javax.annotation.Nonnull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.anarres.cpp.Token.*; /* This source should always be active, since we don't expand macros * in any inactive context. */ /* pp */ class MacroTokenSource extends Source { + private static final Logger LOG = LoggerFactory.getLogger(MacroTokenSource.class); private final Macro macro; private final Iterator tokens; /* Pointer into the macro. */ @@ -96,18 +100,34 @@ import static org.anarres.cpp.Token.*; str.toString(), buf.toString()); } + /** + * Returns true if the given argumentIndex is the last argument of a variadic macro. + * + * @param argumentIndex The index of the argument to inspect. + * @return true if the given argumentIndex is the last argument of a variadic macro. + */ + private boolean isVariadicArgument(@Nonnegative int argumentIndex) { + if (!macro.isVariadic()) + return false; + return argumentIndex == args.size() - 1; + } /* At this point, we have consumed the first M_PASTE. * @see Macro#addPaste(Token) */ private void paste(@Nonnull Token ptok) throws IOException, LexerException { + // List out = new ArrayList(); StringBuilder buf = new StringBuilder(); // Token err = null; /* We know here that arg is null or expired, * since we cannot paste an expanded arg. */ int count = 2; + // While I hate auxiliary booleans, this does actually seem to be the simplest solution, + // as it avoids duplicating all the logic around hasNext() in case COMMA. + boolean comma = false; + TOKEN: for (int i = 0; i < count; i++) { if (!tokens.hasNext()) { /* XXX This one really should throw. */ @@ -127,16 +147,29 @@ import static org.anarres.cpp.Token.*; break; case M_ARG: int idx = ((Integer) tok.getValue()).intValue(); - concat(buf, args.get(idx)); + Argument arg = args.get(idx); + if (comma && isVariadicArgument(idx) && arg.isEmpty()) { + // Ugly way to strip the comma. + buf.setLength(buf.length() - 1); + } else { + concat(buf, arg); + } break; /* XXX Test this. */ case CCOMMENT: case CPPCOMMENT: + // TODO: In cpp, -CC keeps these comments too, + // but turns all C++ comments into C comments. break; + case ',': + comma = true; + buf.append(tok.getText()); + continue TOKEN; default: buf.append(tok.getText()); break; } + comma = false; } /* Push and re-lex. */ diff --git a/src/main/java/org/anarres/cpp/SourceIterator.java b/src/main/java/org/anarres/cpp/SourceIterator.java index db16f01..c7fae18 100644 --- a/src/main/java/org/anarres/cpp/SourceIterator.java +++ b/src/main/java/org/anarres/cpp/SourceIterator.java @@ -19,6 +19,7 @@ package org.anarres.cpp; import java.io.IOException; import java.util.Iterator; import java.util.NoSuchElementException; +import javax.annotation.Nonnull; import static org.anarres.cpp.Token.EOF; /** @@ -30,7 +31,7 @@ public class SourceIterator implements Iterator { private final Source source; private Token tok; - public SourceIterator(Source s) { + public SourceIterator(@Nonnull Source s) { this.source = s; this.tok = null; } @@ -56,6 +57,7 @@ public class SourceIterator implements Iterator { * @throws IllegalStateException if the Source * throws a LexerException or IOException */ + @Override public boolean hasNext() { advance(); return tok.getType() != EOF; @@ -68,6 +70,7 @@ public class SourceIterator implements Iterator { * @throws IllegalStateException if the Source * throws a LexerException or IOException */ + @Override public Token next() { if (!hasNext()) throw new NoSuchElementException(); @@ -81,6 +84,7 @@ public class SourceIterator implements Iterator { * * @throws UnsupportedOperationException unconditionally. */ + @Override public void remove() { throw new UnsupportedOperationException(); } diff --git a/src/test/java/org/anarres/cpp/VaArgsPastingTest.java b/src/test/java/org/anarres/cpp/VaArgsPastingTest.java index 7623ebf..f1bcbcd 100644 --- a/src/test/java/org/anarres/cpp/VaArgsPastingTest.java +++ b/src/test/java/org/anarres/cpp/VaArgsPastingTest.java @@ -58,6 +58,6 @@ public class VaArgsPastingTest { + "foo(a,b) // PASTE_ELLIPSIS 2\n" + "foo(a) // PASTE_ELLIPSIS 1\n" + "foo(a,b) // PASTE_VAARGS 2\n" - + "foo(a) // PASTE_VAARGS 1\n", output); + + "foo(a) // PASTE_VAARGS 1", output); } } -- cgit v1.2.3 From da16a8e409ea51b3d17edb0be6f22e8d5530219e Mon Sep 17 00:00:00 2001 From: Shevek Date: Tue, 2 May 2017 00:26:44 -0700 Subject: Fix #34. --- src/main/java/org/anarres/cpp/Preprocessor.java | 12 +++- src/test/java/org/anarres/cpp/RegressionTest.java | 70 +++++++++++++++++++++++ src/test/resources/regression/lex-char.in | 4 ++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/anarres/cpp/RegressionTest.java create mode 100644 src/test/resources/regression/lex-char.in (limited to 'src/main') diff --git a/src/main/java/org/anarres/cpp/Preprocessor.java b/src/main/java/org/anarres/cpp/Preprocessor.java index 2bbea4e..5b07824 100644 --- a/src/main/java/org/anarres/cpp/Preprocessor.java +++ b/src/main/java/org/anarres/cpp/Preprocessor.java @@ -1559,6 +1559,16 @@ public class Preprocessor implements Closeable { } } + private int expr_char(Token token) { + Object value = token.getValue(); + if (value instanceof Character) + return ((Character) value).charValue(); + String text = String.valueOf(value); + if (text.length() == 0) + return 0; + return text.charAt(0); + } + private long expr(int priority) throws IOException, LexerException { @@ -1595,7 +1605,7 @@ public class Preprocessor implements Closeable { lhs = value.longValue(); break; case CHARACTER: - lhs = ((Character) tok.getValue()).charValue(); + lhs = expr_char(tok); break; case IDENTIFIER: if (warnings.contains(Warning.UNDEF)) diff --git a/src/test/java/org/anarres/cpp/RegressionTest.java b/src/test/java/org/anarres/cpp/RegressionTest.java new file mode 100644 index 0000000..3ce3568 --- /dev/null +++ b/src/test/java/org/anarres/cpp/RegressionTest.java @@ -0,0 +1,70 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.anarres.cpp; + +import com.google.common.base.Charsets; +import com.google.common.io.CharStreams; +import com.google.common.io.Files; +import com.google.common.io.PatternFilenameFilter; +import java.io.File; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.List; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import static org.junit.Assert.assertEquals; + +/** + * + * @author shevek + */ +@RunWith(Parameterized.class) +public class RegressionTest { + + private static final Logger LOG = LoggerFactory.getLogger(RegressionTest.class); + + @Parameterized.Parameters(name = "{0}") + public static List data() throws Exception { + List out = new ArrayList(); + + File dir = new File("build/resources/test/regression"); + for (File inFile : dir.listFiles(new PatternFilenameFilter(".*\\.in"))) { + String name = Files.getNameWithoutExtension(inFile.getName()); + File outFile = new File(dir, name + ".out"); + out.add(new Object[]{name, inFile, outFile}); + } + + return out; + } + + private final String name; + private final File inFile; + private final File outFile; + + public RegressionTest(String name, File inFile, File outFile) { + this.name = name; + this.inFile = inFile; + this.outFile = outFile; + } + + @Test + public void testRegression() throws Exception { + String inText = Files.toString(inFile, Charsets.UTF_8); + LOG.info("Read " + name + ":\n" + inText); + CppReader cppReader = new CppReader(new StringReader(inText)); + String cppText = CharStreams.toString(cppReader); + LOG.info("Generated " + name + ":\n" + cppText); + if (outFile.exists()) { + String outText = Files.toString(outFile, Charsets.UTF_8); + LOG.info("Expected " + name + ":\n" + outText); + assertEquals(outText, inText); + } + + } +} diff --git a/src/test/resources/regression/lex-char.in b/src/test/resources/regression/lex-char.in new file mode 100644 index 0000000..472af63 --- /dev/null +++ b/src/test/resources/regression/lex-char.in @@ -0,0 +1,4 @@ +#define EXAMPLE_X 'a' + +#if EXAMPLE == EXAMPLE_X +#endif -- cgit v1.2.3 From 6f8e7f6010cf1502110830c2c9d979ba59feace7 Mon Sep 17 00:00:00 2001 From: Shevek Date: Mon, 15 May 2017 11:50:28 -0700 Subject: Add missing @Override. --- src/main/java/org/anarres/cpp/CppReader.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main') diff --git a/src/main/java/org/anarres/cpp/CppReader.java b/src/main/java/org/anarres/cpp/CppReader.java index c3c6431..6ceeb8d 100644 --- a/src/main/java/org/anarres/cpp/CppReader.java +++ b/src/main/java/org/anarres/cpp/CppReader.java @@ -126,6 +126,7 @@ public class CppReader extends Reader implements Closeable { return token.charAt(idx++); } + @Override /* XXX Very slow and inefficient. */ public int read(char cbuf[], int off, int len) throws IOException { -- cgit v1.2.3 From 547134e1cbb29bb51a75781f559243fcea8f3860 Mon Sep 17 00:00:00 2001 From: Shevek Date: Mon, 15 May 2017 11:50:41 -0700 Subject: InputLexerSource: Don't force buffering of the reader. --- src/main/java/org/anarres/cpp/InputLexerSource.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main') diff --git a/src/main/java/org/anarres/cpp/InputLexerSource.java b/src/main/java/org/anarres/cpp/InputLexerSource.java index 62612d7..8064a9a 100644 --- a/src/main/java/org/anarres/cpp/InputLexerSource.java +++ b/src/main/java/org/anarres/cpp/InputLexerSource.java @@ -45,8 +45,12 @@ public class InputLexerSource extends LexerSource { this(new InputStreamReader(input, charset)); } + public InputLexerSource(@Nonnull Reader input, boolean ppvalid) { + super(input, true); + } + public InputLexerSource(@Nonnull Reader input) { - super(toBufferedReader(input), true); + this(input, true); } @Override -- cgit v1.2.3 From 63d4d8283509fd42505b65ddc2cb38fe546dffc0 Mon Sep 17 00:00:00 2001 From: Shevek Date: Tue, 4 Sep 2018 13:47:47 -0700 Subject: LexerSource: Support text round-trip of lost and lonely unicode. --- src/main/java/org/anarres/cpp/LexerSource.java | 17 ++++++++++++----- src/test/java/org/anarres/cpp/LexerSourceTest.java | 5 +++++ 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'src/main') diff --git a/src/main/java/org/anarres/cpp/LexerSource.java b/src/main/java/org/anarres/cpp/LexerSource.java index cf4296f..33268f8 100644 --- a/src/main/java/org/anarres/cpp/LexerSource.java +++ b/src/main/java/org/anarres/cpp/LexerSource.java @@ -315,10 +315,11 @@ public class LexerSource extends Source { /** * Lexes an escaped character, appends the lexed escape sequence to 'text' and returns the parsed character value. + * * @param text The buffer to which the literal escape sequence is appended. * @return The new parsed character value. * @throws IOException if it goes badly wrong. - * @throws LexerException if it goes wrong. + * @throws LexerException if it goes wrong. */ private int escape(StringBuilder text) throws IOException, @@ -425,7 +426,7 @@ public class LexerSource extends Source { int e = read(); if (e != '\'') { // error("Illegal character constant"); - /* We consume up to the next ' or the rest of the line. */ + /* We consume up to the next ' or the rest of the line. */ for (;;) { if (isLineSeparator(e)) { unread(e); @@ -741,8 +742,7 @@ public class LexerSource extends Source { text.append((char) c); for (;;) { d = read(); - if (ppvalid && isLineSeparator(d)) /* XXX Ugly. */ - + if (ppvalid && isLineSeparator(d)) /* XXX Ugly. */ break; if (Character.isWhitespace(d)) text.append((char) d); @@ -978,7 +978,14 @@ public class LexerSource extends Source { } else if (Character.isJavaIdentifierStart(c)) { tok = identifier(c); } else { - tok = new Token(c); + String text = TokenType.getTokenText(c); + if (text == null) { + if ((c >>> 16) == 0) // Character.isBmpCodePoint() is new in 1.7 + text = Character.toString((char) c); + else + text = new String(Character.toChars(c)); + } + tok = new Token(c, text); } } diff --git a/src/test/java/org/anarres/cpp/LexerSourceTest.java b/src/test/java/org/anarres/cpp/LexerSourceTest.java index 96ec4a3..38d0a6f 100644 --- a/src/test/java/org/anarres/cpp/LexerSourceTest.java +++ b/src/test/java/org/anarres/cpp/LexerSourceTest.java @@ -137,4 +137,9 @@ public class LexerSourceTest { testLexerSource("5 /*", false, NUMBER, WHITESPACE, INVALID); // Bug #15 testLexerSource("5 //", false, NUMBER, WHITESPACE, CPPCOMMENT); } + + @Test + public void testUnicode()throws Exception{ + testLexerSource("foo \u2018bar\u2019 baz", true, IDENTIFIER, WHITESPACE, 8216, IDENTIFIER, 8217, WHITESPACE, IDENTIFIER); + } } -- cgit v1.2.3 From f658426ba59bd956c6ec61663e87c3e594361640 Mon Sep 17 00:00:00 2001 From: Shevek Date: Mon, 19 Aug 2019 12:23:10 -0700 Subject: LexerSource: Fix handling of numeric values with explicit positive exponents. --- src/main/java/org/anarres/cpp/LexerSource.java | 2 +- src/test/java/org/anarres/cpp/NumericValueTest.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main') diff --git a/src/main/java/org/anarres/cpp/LexerSource.java b/src/main/java/org/anarres/cpp/LexerSource.java index 33268f8..c613f96 100644 --- a/src/main/java/org/anarres/cpp/LexerSource.java +++ b/src/main/java/org/anarres/cpp/LexerSource.java @@ -569,7 +569,7 @@ public class LexerSource extends Source { LexerException { StringBuilder part = new StringBuilder(); int d = read(); - if (sign && d == '-') { + if (sign && (d == '+' || d == '-')) { text.append((char) d); part.append((char) d); d = read(); diff --git a/src/test/java/org/anarres/cpp/NumericValueTest.java b/src/test/java/org/anarres/cpp/NumericValueTest.java index d4ea432..5551942 100644 --- a/src/test/java/org/anarres/cpp/NumericValueTest.java +++ b/src/test/java/org/anarres/cpp/NumericValueTest.java @@ -75,6 +75,7 @@ public class NumericValueTest { testNumericValue("1e1", 1e1); // testNumericValue("-1e1", -1e1); testNumericValue("1e-1", 1e-1); + testNumericValue("1e+1", 1e+1); // Hex numbers with decimal exponents testNumericValue("0x12e3", 0x12e3); -- cgit v1.2.3