Package de.fosd.typechef.jcpp

Source Code of de.fosd.typechef.jcpp.AbstractCheckTests

package de.fosd.typechef.jcpp;

import de.fosd.typechef.LexerToken;
import de.fosd.typechef.VALexer;
import de.fosd.typechef.conditional.Conditional;
import de.fosd.typechef.featureexpr.FeatureExpr;
import de.fosd.typechef.featureexpr.FeatureExprFactory;
import de.fosd.typechef.lexer.Feature;
import de.fosd.typechef.lexer.FeatureExprLib;
import de.fosd.typechef.lexer.LexerException;
import de.fosd.typechef.lexer.LexerFrontend;
import org.junit.Assert;

import java.io.*;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class AbstractCheckTests {


    public AbstractCheckTests() {
        super();
    }

    /**
     * parses a file and checks the result against the results specified in the
     * filename.check file
     *
     * @param filename
     * @throws LexerException
     * @throws IOException
     */
    protected void testFile(String filename) throws LexerException, IOException {
        testFile(filename, false);
    }


    protected void testFile(String filename, boolean debug) throws LexerException, IOException {
        testFile(filename, debug, false);
    }

    protected void testFile(String filename, boolean debug, boolean ignoreWarning)
            throws LexerException, IOException {
        String folder = "tc_data/";

        InputStream inputStream = getClass().getResourceAsStream(
                "/" + folder + filename);
        URL inputURI = getClass().getResource(
                "/" + folder + filename);
        if (inputStream == null) {
            throw new FileNotFoundException("Input file not found: " + filename);
        }

        Conditional<LexerFrontend.LexerResult> output = null;
        String error = null;
        LexerException ex = null;
        try {
            //getResource() returns an URL containing escapes. toURI().getPath() is needed to unescape them.
            //Otherwise one gets a path where, e.g., spaces are represented by %20!
            output = lex(new VALexer.StreamSource(inputStream, inputURI.getFile()),
                    debug, getClass().getResource("/" + folder).toURI().getPath(), ignoreWarning);
        } catch (LexerException e) {
            ex = e;
            error = "ERROR: " + e.toString();
            Assert.fail(error);
        } catch (URISyntaxException use) {
            //The URI was generated by Java libraries, so it should always be valid!
            System.err.println("Supposedly impossible exception!!");
            use.printStackTrace();
        }
        if (!check(filename, folder, output))
            if (ex != null)
                throw ex;

    }

    protected String preprocessCodeFragment(String code) throws LexerException,
            IOException {
        return tokenStreamToString(lex(new VALexer.TextSource(code), false, null, false));
    }

    private boolean check(String filename, String folder,
                          Conditional<LexerFrontend.LexerResult> lexerResult)
            throws FileNotFoundException, IOException {
        boolean containsErrorCheck = false;
        InputStream inputStream = getClass().getResourceAsStream(
                "/" + folder + filename + ".check");
        Assert.assertNotNull("cannot load file /" + folder + filename + ".check", inputStream);
        BufferedReader checkFile = new BufferedReader(new InputStreamReader(
                inputStream));
        String line;
        String cleanedOutput = tokenStreamToString(lexerResult).replace("definedEx(",
                "defined(");
        FeatureExpr errorCondition = LexerFrontend.getErrorCondition(lexerResult);
        while ((line = checkFile.readLine()) != null) {
            //expecting NOT to find a token
            if (line.startsWith("!")) {
                String substring = line.substring(2);
                if (cleanedOutput.contains(substring)) {
                    System.err.println(cleanedOutput);
                    Assert.fail(substring
                            + " found but not expected in output\n"
                            + cleanedOutput);
                }
            }
            //expecting to find a token a specific number of times
            if (line.startsWith("+")) {
                int expected = Integer.parseInt(line.substring(1, 2));
                int found = 0;
                String substring = line.substring(3);

                String content = cleanedOutput;
                int idx = content.indexOf(substring);
                while (idx >= 0) {
                    found++;
                    content = content.substring(idx + substring.length());
                    idx = content.indexOf(substring);
                }

                if (expected != found) {
                    failOutput(cleanedOutput);
                    Assert.fail(substring + " found " + found
                            + " times, but expected " + expected + " times\n"
                            + content);
                }
            }
            //expect to find a token an arbitrary number of times
            if (line.startsWith("*")) {
                String substring = line.substring(2);

                int idx = cleanedOutput.indexOf(substring);
                if (idx < 0) {
                    failOutput(cleanedOutput);
                    Assert.fail(substring + " not found but expected\n"
                            + cleanedOutput);
                }
            }
            //expect to find a token with a specific presence condition
            if (line.startsWith("T")) {
                // checks presence condition for token
                // Syntax: T <tokenText> with <presenceCondition>
                String expectedName = line.substring(2);
                String expectedFeature = expectedName.substring(expectedName
                        .indexOf(" with ") + 6);
                expectedName = expectedName.substring(0, expectedName
                        .indexOf(" with "));
                FeatureExpr expectedExpr = FeatureExprLib.featureExprParser().parse(expectedFeature);
                boolean foundToken = false;

                for (LexerToken t : LexerFrontend.conditionalResultToList(lexerResult, FeatureExprFactory.True())) {
                    if (t.getText().equals(expectedName)) {
                        foundToken = true;
                        // expect equivalent presence conditions
                        Assert.assertTrue("found token " + expectedName
                                + " with " + t.getFeature()
                                + " instead of expected " + expectedExpr,
                                t.getFeature().equivalentTo(expectedExpr));
                    }
                }
                Assert.assertTrue("token " + expectedName + " not found.",
                        foundToken);
            }
            //expects a lexer error (always or under a specific condition)
            if (line.startsWith("error")) {
                //error <- fails under all conditions
                //error CONFIG_FOO | CONFIG_BAR <- fails under specific conditions
                String condition = line.substring(5).trim();
                if (condition.length() == 0)
                    condition = "1";
                FeatureExpr expectedErrorCondition = FeatureExprLib.featureExprParser().parse(condition);

                containsErrorCheck = true;
                Assert.assertTrue(
                        "Expected error IF " + expectedErrorCondition + ", but preprocessing succeeded unless " + errorCondition,
                        errorCondition.equivalentTo(expectedErrorCondition));
            }
            if (line.trim().equals("print")) {
                System.out.println(cleanedOutput);
            }
            if (line.trim().equals("macrooutput")) {
//                pp.debugPreprocessorDone();
            }
        }
        return containsErrorCheck;
    }


    private void failOutput(String output) {
        System.err.println(output);
//        if (pp != null)
//            pp.debugPreprocessorDone();
    }

    private Conditional<LexerFrontend.LexerResult> lex(VALexer.LexerInput source, boolean debug, final String folder, final boolean ignoreWarnings)
            throws LexerException, IOException {
        return new LexerFrontend().run(new LexerFrontend.DefaultLexerOptions(source, debug, null) {
            @Override
            public boolean isReturnLanguageTokensOnly() {
                return false;
            }

            @Override
            public List<String> getIncludePaths() {
                return Collections.singletonList(folder);
            }

            @Override
            public boolean isHandleWarningsAsErrors() {
                return !ignoreWarnings;
            }

            @Override
            public Set<Feature> getFeatures() {
                Set<Feature> features = new HashSet<>();
                features.add(Feature.DIGRAPHS);
                features.add(Feature.TRIGRAPHS);
                features.add(Feature.LINEMARKERS);
                features.add(Feature.GNUCEXTENSIONS);
                return features;
            }
        }, true);


//        // XXX Why here? And isn't the whole thing duplicated from elsewhere?
//
//
//        pp = new Preprocessor(new MacroFilter().setPrefixFilter("CONFIG_"), null);
//        pp.addFeature(Feature.DIGRAPHS);
//        pp.addFeature(Feature.TRIGRAPHS);
//        pp.addFeature(Feature.LINEMARKERS);
//        pp.addFeature(Feature.GNUCEXTENSIONS);
//        for (Warning w : Warning.allWarnings())
//            pp.addWarning(w);
//        pp.setListener(new PreprocessorListener(pp) {
//            @Override
//            public void handleWarning(String source, int line, int column,
//                                      String msg) throws LexerException {
//                super.handleWarning(source, line, column, msg);
//                if (!ignoreWarnings)
//                    throw new LexerException(msg + " " + source + ":" + line + ":"
//                            + column);
//            }
//        });
//        pp.addMacro("__JCPP__", FeatureExprLib.True());
//
//        // include path
//        if (folder != null)
//            pp.addSystemIncludePath(folder);
//
//        pp.addInput(source);
//
//        List<LexerToken> output = new ArrayList<LexerToken>();
//        for (; ; ) {
//            LexerToken tok = pp.getNextToken();
//            if (tok == null)
//                break;
//            if (tok.isEOF())
//                break;
//
//            output.add(tok);
//            if (debug)
//                System.out.print(tok.getText());
//        }
//        return output;
    }


    private String tokenStreamToString(Conditional<LexerFrontend.LexerResult> lexerResult) {
        List<LexerToken> tokenstream = LexerFrontend.conditionalResultToList(lexerResult, FeatureExprFactory.True());
        StringWriter strWriter = new StringWriter();
        PrintWriter writer = new PrintWriter(strWriter);
        if (tokenstream != null)
            for (LexerToken t : tokenstream)
                t.lazyPrint(writer);
        return strWriter.getBuffer().toString();
    }
}
TOP

Related Classes of de.fosd.typechef.jcpp.AbstractCheckTests

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.