diff --git a/.gitignore b/.gitignore index a8b6931..1ad0f80 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ -build +/build +/target + +*~ .*.swp -.gradle + +.classpath +.project diff --git a/README b/README.md similarity index 80% rename from README rename to README.md index 0dead99..03b27ff 100644 --- a/README +++ b/README.md @@ -1,3 +1,5 @@ +# Introduction + The C Preprocessor is an interesting standard. It appears to be derived from the de-facto behaviour of the first preprocessors, and has evolved over the years. Implementation is therefore difficult. @@ -11,3 +13,8 @@ head examined). This project has has been used to successfully preprocess much of the source code of the GNU C library. As of version 1.2.5, it can also preprocess the Apple Objective C library. + +# Documentation + +* [JavaDoc API](http://shevek.github.io/jcpp/docs/javadoc/) +* [Coverage Report](http://shevek.github.io/jcpp/docs/cobertura/) diff --git a/build.gradle b/build.gradle deleted file mode 100644 index c99935d..0000000 --- a/build.gradle +++ /dev/null @@ -1,66 +0,0 @@ -// Establish version and status -ext.githubProjectName = rootProject.name // Change if github project name is not the same as the root project's name -group = "org.anarres" - -buildscript { - repositories { - // mavenLocal() - mavenCentral() // maven { url 'http://jcenter.bintray.com' } - } - apply from: file('gradle/buildscript.gradle'), to: buildscript -} - -allprojects { - repositories { - // mavenLocal() - mavenCentral() // maven { url: 'http://jcenter.bintray.com' } - } -} - -apply plugin: 'idea' - -apply from: file('gradle/convention.gradle') -apply from: file('gradle/maven.gradle') -apply from: file('gradle/check.gradle') -apply from: file('gradle/license.gradle') -// apply from: file('gradle/release.gradle') - -apply plugin: 'application' -apply plugin: VelocityPlugin - -dependencies { - compile 'com.google.code.findbugs:jsr305:2.0.2' - compile 'gnu.getopt:java-getopt:1.0.13' - compile 'org.apache.ant:ant:1.7.0' - - testCompile 'junit:junit:4.8.1' -} - -velocity { - def p = project - context { - version = p.version - } -} - -test { - systemProperty 'org.apache.commons.logging.Log', 'org.apache.commons.logging.impl.SimpleLog' - systemProperty 'org.apache.commons.logging.simplelog.defaultlog', 'debug' - - testLogging { - if (System.properties['test.single']) { - // events "passed", "skipped", "failed" - events "started", "passed", "skipped", "failed" - showExceptions true - exceptionFormat "full" - showStandardStreams true - } else { - events "failed" - } - - debug { - events "started", "passed", "skipped", "failed", "standard_out", "standard_error" - exceptionFormat "full" - } - } -} diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle deleted file mode 100644 index 324859d..0000000 --- a/buildSrc/build.gradle +++ /dev/null @@ -1,12 +0,0 @@ -apply plugin: 'groovy' -apply plugin: 'idea' - -repositories { - mavenCentral() -} - -dependencies { - compile gradleApi() - compile 'org.apache.velocity:velocity:1.7' -} - diff --git a/buildSrc/src/main/groovy/VelocityPlugin.groovy b/buildSrc/src/main/groovy/VelocityPlugin.groovy deleted file mode 100644 index cc8741a..0000000 --- a/buildSrc/src/main/groovy/VelocityPlugin.groovy +++ /dev/null @@ -1,33 +0,0 @@ -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.apache.velocity.VelocityContext -import org.apache.velocity.app.VelocityEngine -import org.apache.velocity.runtime.log.SystemLogChute - -class VelocityPluginExtension { - String inputDir = "src/main/velocity" - String outputDir = "build/generated-sources/velocity" - Map<String, Object> contextValues = [:] - def context(Closure closure) { - contextValues.with closure - } -} - -class VelocityPlugin implements Plugin<Project> { - void apply(Project project) { - - project.extensions.create("velocity", VelocityPluginExtension) - - project.task('velocityVpp', type: VelocityTask) { - description "Preprocesses velocity template files." - inputDir = project.file(project.velocity.inputDir) - outputDir = project.file(project.velocity.outputDir) - contextValues = project.velocity.contextValues - } - - project.compileJava.dependsOn(project.velocityVpp) - project.sourceSets.main.java.srcDir project.velocity.outputDir - - } -} - diff --git a/buildSrc/src/main/groovy/VelocityTask.groovy b/buildSrc/src/main/groovy/VelocityTask.groovy deleted file mode 100644 index 6a36903..0000000 --- a/buildSrc/src/main/groovy/VelocityTask.groovy +++ /dev/null @@ -1,58 +0,0 @@ -import org.apache.velocity.VelocityContext -import org.apache.velocity.app.VelocityEngine -import org.apache.velocity.runtime.log.SystemLogChute -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.TaskAction - -class VelocityTask extends DefaultTask { - - @InputDirectory - File inputDir - - @OutputDirectory - File outputDir - - String filter = '**/*.java' - - File includeDir - - Map<String, Object> contextValues = [:] - - @TaskAction - void run() { - outputDir.deleteDir() - outputDir.mkdirs() - // println "Velocity: $inputDir -> $outputDir" - - VelocityEngine engine = new VelocityEngine() - engine.setProperty(VelocityEngine.RUNTIME_LOG_LOGSYSTEM_CLASS, SystemLogChute.class.name) - engine.setProperty(VelocityEngine.RESOURCE_LOADER, "file") - engine.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_CACHE, "true") - if (includeDir != null) - engine.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, includeDir.getAbsolutePath()) - def inputFiles = project.fileTree( - dir: inputDir, - include: filter - ) - inputFiles.visit { e -> - if (e.file.isFile()) { - File outputFile = e.relativePath.getFile(outputDir) - VelocityContext context = new VelocityContext() - contextValues.each { context.put(it.key, it.value) } - context.put('project', project) - context.put('package', e.relativePath.parent.segments.join('.')) - context.put('class', e.relativePath.lastName.replaceFirst("\\.java\$", "")) - // println "Parsing ${e.file}" - e.file.withReader { reader -> - outputFile.parentFile.mkdirs() - outputFile.withWriter { writer -> - engine.evaluate(context, writer, e.relativePath.toString(), reader) - } - } - } - } - } -} - diff --git a/codequality/HEADER b/codequality/HEADER deleted file mode 100644 index 3102e4b..0000000 --- a/codequality/HEADER +++ /dev/null @@ -1,13 +0,0 @@ -Copyright ${year} Netflix, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/codequality/checkstyle.xml b/codequality/checkstyle.xml deleted file mode 100644 index 47c01a2..0000000 --- a/codequality/checkstyle.xml +++ /dev/null @@ -1,188 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE module PUBLIC - "-//Puppy Crawl//DTD Check Configuration 1.2//EN" - "http://www.puppycrawl.com/dtds/configuration_1_2.dtd"> - -<module name="Checker"> - - <!-- Checks that a package-info.java file exists for each package. --> - <!-- See http://checkstyle.sf.net/config_javadoc.html#JavadocPackage --> - <!-- - <module name="JavadocPackage"> - <property name="allowLegacy" value="true"/> - </module> - --> - - <!-- Checks whether files end with a new line. --> - <!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile --> - <module name="NewlineAtEndOfFile"/> - - <!-- Checks that property files contain the same keys. --> - <!-- See http://checkstyle.sf.net/config_misc.html#Translation --> - <module name="Translation"/> - - <!-- Checks for Size Violations. --> - <!-- See http://checkstyle.sf.net/config_sizes.html --> - <module name="FileLength"/> - - <!-- Checks for whitespace --> - <!-- See http://checkstyle.sf.net/config_whitespace.html --> - <module name="FileTabCharacter"/> - - <!-- Miscellaneous other checks. --> - <!-- See http://checkstyle.sf.net/config_misc.html --> - <module name="RegexpSingleline"> - <property name="format" value="\s+$"/> - <property name="minimum" value="0"/> - <property name="maximum" value="0"/> - <property name="message" value="Line has trailing spaces."/> - <property name="severity" value="info"/> - </module> - - <module name="TreeWalker"> - - <!-- Checks for Javadoc comments. --> - <!-- See http://checkstyle.sf.net/config_javadoc.html --> - <module name="JavadocMethod"> - <property name="scope" value="package"/> - <property name="allowMissingParamTags" value="true"/> - <property name="allowMissingThrowsTags" value="true"/> - <property name="allowMissingReturnTag" value="true"/> - <property name="allowThrowsTagsForSubclasses" value="true"/> - <property name="allowUndeclaredRTE" value="true"/> - <property name="allowMissingPropertyJavadoc" value="true"/> - </module> - <module name="JavadocType"> - <property name="scope" value="package"/> - </module> - <module name="JavadocVariable"> - <property name="scope" value="package"/> - </module> - <module name="JavadocStyle"> - <property name="checkEmptyJavadoc" value="true"/> - </module> - - <!-- Checks for Naming Conventions. --> - <!-- See http://checkstyle.sf.net/config_naming.html --> - <module name="ConstantName"/> - <module name="LocalFinalVariableName"/> - <module name="LocalVariableName"/> - <module name="MemberName"/> - <module name="MethodName"/> - <module name="PackageName"/> - <module name="ParameterName"/> - <module name="StaticVariableName"/> - <module name="TypeName"/> - - <!-- Checks for imports --> - <!-- See http://checkstyle.sf.net/config_import.html --> - <module name="AvoidStarImport"/> - <module name="IllegalImport"/> <!-- defaults to sun.* packages --> - <module name="RedundantImport"/> - <module name="UnusedImports"/> - - - <!-- Checks for Size Violations. --> - <!-- See http://checkstyle.sf.net/config_sizes.html --> - <module name="LineLength"> - <!-- what is a good max value? --> - <property name="max" value="120"/> - <!-- ignore lines like "$File: //depot/... $" --> - <property name="ignorePattern" value="\$File.*\$"/> - <property name="severity" value="info"/> - </module> - <module name="MethodLength"/> - <module name="ParameterNumber"/> - - - <!-- Checks for whitespace --> - <!-- See http://checkstyle.sf.net/config_whitespace.html --> - <module name="EmptyForIteratorPad"/> - <module name="GenericWhitespace"/> - <module name="MethodParamPad"/> - <module name="NoWhitespaceAfter"/> - <module name="NoWhitespaceBefore"/> - <module name="OperatorWrap"/> - <module name="ParenPad"/> - <module name="TypecastParenPad"/> - <module name="WhitespaceAfter"/> - <module name="WhitespaceAround"/> - - <!-- Modifier Checks --> - <!-- See http://checkstyle.sf.net/config_modifiers.html --> - <module name="ModifierOrder"/> - <module name="RedundantModifier"/> - - - <!-- Checks for blocks. You know, those {}'s --> - <!-- See http://checkstyle.sf.net/config_blocks.html --> - <module name="AvoidNestedBlocks"/> - <module name="EmptyBlock"> - <property name="option" value="text"/> - </module> - <module name="LeftCurly"/> - <module name="NeedBraces"/> - <module name="RightCurly"/> - - - <!-- Checks for common coding problems --> - <!-- See http://checkstyle.sf.net/config_coding.html --> - <!-- <module name="AvoidInlineConditionals"/> --> - <module name="EmptyStatement"/> - <module name="EqualsHashCode"/> - <module name="HiddenField"> - <property name="ignoreConstructorParameter" value="true"/> - <property name="ignoreSetter" value="true"/> - <property name="severity" value="warning"/> - </module> - <module name="IllegalInstantiation"/> - <module name="InnerAssignment"/> - <module name="MagicNumber"> - <property name="severity" value="warning"/> - </module> - <module name="MissingSwitchDefault"/> - <!-- Problem with finding exception types... --> - <module name="RedundantThrows"> - <property name="allowUnchecked" value="true"/> - <property name="suppressLoadErrors" value="true"/> - <property name="severity" value="info"/> - </module> - <module name="SimplifyBooleanExpression"/> - <module name="SimplifyBooleanReturn"/> - - <!-- Checks for class design --> - <!-- See http://checkstyle.sf.net/config_design.html --> - <!-- <module name="DesignForExtension"/> --> - <module name="FinalClass"/> - <module name="HideUtilityClassConstructor"/> - <module name="InterfaceIsType"/> - <module name="VisibilityModifier"/> - - - <!-- Miscellaneous other checks. --> - <!-- See http://checkstyle.sf.net/config_misc.html --> - <module name="ArrayTypeStyle"/> - <!-- <module name="FinalParameters"/> --> - <module name="TodoComment"> - <property name="format" value="TODO"/> - <property name="severity" value="info"/> - </module> - <module name="UpperEll"/> - - <module name="FileContentsHolder"/> <!-- Required by comment suppression filters --> - - </module> - - <!-- Enable suppression comments --> - <module name="SuppressionCommentFilter"> - <property name="offCommentFormat" value="CHECKSTYLE IGNORE\s+(\S+)"/> - <property name="onCommentFormat" value="CHECKSTYLE END IGNORE\s+(\S+)"/> - <property name="checkFormat" value="$1"/> - </module> - <module name="SuppressWithNearbyCommentFilter"> - <!-- Syntax is "SUPPRESS CHECKSTYLE name" --> - <property name="commentFormat" value="SUPPRESS CHECKSTYLE (\w+)"/> - <property name="checkFormat" value="$1"/> - <property name="influenceFormat" value="1"/> - </module> -</module> diff --git a/gradle.properties b/gradle.properties deleted file mode 100644 index 156e86d..0000000 --- a/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -version=1.4.1 diff --git a/gradle/buildscript.gradle b/gradle/buildscript.gradle deleted file mode 100644 index 3163aa9..0000000 --- a/gradle/buildscript.gradle +++ /dev/null @@ -1,11 +0,0 @@ -// Executed in context of buildscript -repositories { - // Repo in addition to maven central - repositories { maven { url 'http://dl.bintray.com/content/netflixoss/external-gradle-plugins/' } } // For gradle-release -} -dependencies { - classpath 'nl.javadude.gradle.plugins:license-gradle-plugin:0.6.1' - classpath 'com.mapvine:gradle-cobertura-plugin:0.1' - // classpath 'gradle-release:gradle-release:1.1.5' - classpath 'org.ajoberstar:gradle-git:0.5.0' -} diff --git a/gradle/check.gradle b/gradle/check.gradle deleted file mode 100644 index 78f8180..0000000 --- a/gradle/check.gradle +++ /dev/null @@ -1,25 +0,0 @@ -// Checkstyle -// apply plugin: 'checkstyle' -// checkstyle { -// ignoreFailures = true -// configFile = rootProject.file('codequality/checkstyle.xml') -// } - -// FindBugs -apply plugin: 'findbugs' -findbugs { - ignoreFailures = true -} -findbugsTest.enabled = false - -// PMD -// apply plugin: 'pmd' -// tasks.withType(Pmd) { reports.html.enabled true } - -apply plugin: 'cobertura' -cobertura { - sourceDirs = sourceSets.main.java.srcDirs - format = 'html' - includes = ['**/*.java', '**/*.groovy'] - excludes = [] -} diff --git a/gradle/convention.gradle b/gradle/convention.gradle deleted file mode 100644 index 22023ea..0000000 --- a/gradle/convention.gradle +++ /dev/null @@ -1,88 +0,0 @@ -apply plugin: 'java' // Plugin as major conventions, overwrites status - -sourceCompatibility = 1.5 - -// GRADLE-2087 workaround, perform after java plugin -status = project.hasProperty('preferredStatus')?project.preferredStatus:(version.contains('SNAPSHOT')?'snapshot':'release') - -// Indenting to align with multi-project branch - task sourcesJar(type: Jar, dependsOn:classes) { - from sourceSets.main.allSource - classifier 'sources' - extension 'jar' - } - - task javadocJar(type: Jar, dependsOn:javadoc) { - from javadoc.destinationDir - classifier 'javadoc' - extension 'jar' - } - - configurations.add('sources') - configurations.add('javadoc') - configurations.archives { - extendsFrom configurations.sources - extendsFrom configurations.javadoc - } - - // When outputing to an Ivy repo, we want to use the proper type field - gradle.taskGraph.whenReady { - def isNotMaven = !it.hasTask(project.uploadMavenCentral) - if (isNotMaven) { - def artifacts = project.configurations.sources.artifacts - def sourceArtifact = artifacts.iterator().next() - sourceArtifact.type = 'sources' - } - } - - artifacts { - sources(sourcesJar) { - // Weird Gradle quirk where type will be used for the extension, but only for sources - type 'jar' - } - javadoc(javadocJar) { - type 'javadoc' - } - } - - configurations { - provided { - description = 'much like compile, but indicates you expect the JDK or a container to provide it. It is only available on the compilation classpath, and is not transitive.' - transitive = true - visible = true - } - } - - project.sourceSets { - main.compileClasspath += project.configurations.provided - main.runtimeClasspath -= project.configurations.provided - test.compileClasspath += project.configurations.provided - test.runtimeClasspath += project.configurations.provided - } - -/* -apply plugin: 'github-pages' // Used to create publishGhPages task - -def docTasks = [:] -[Javadoc,ScalaDoc,Groovydoc].each{ Class docClass -> - tasks.withType(docClass).each { docTask -> - docTasks[docTask.name] = docTask - processGhPages.dependsOn(docTask) - } -} - -githubPages { - repoUri = "git@github.com:Netflix/${rootProject.githubProjectName}.git" - pages { - docTasks.each { shortName, docTask -> - from(docTask.outputs.files) { - into "docs/${shortName}" - } - } - } -} -*/ - -wrapper { - gradleVersion = '1.10' -} diff --git a/gradle/license.gradle b/gradle/license.gradle deleted file mode 100644 index 59b75b3..0000000 --- a/gradle/license.gradle +++ /dev/null @@ -1,8 +0,0 @@ -// Dependency for plugin was set in buildscript.gradle - -apply plugin: 'license' //nl.javadude.gradle.plugins.license.LicensePlugin -license { - header rootProject.file('codequality/HEADER') - ext.year = Calendar.getInstance().get(Calendar.YEAR) - skipExistingHeaders true -} diff --git a/gradle/maven.gradle b/gradle/maven.gradle deleted file mode 100644 index 0513719..0000000 --- a/gradle/maven.gradle +++ /dev/null @@ -1,69 +0,0 @@ -// Maven side of things -apply plugin: 'maven' // Java plugin has to have been already applied for the conf2scope mappings to work -apply plugin: 'signing' - -signing { - required { gradle.taskGraph.hasTask(uploadMavenCentral) } - sign configurations.archives -} - -/** - * Publishing to Maven Central example provided from http://jedicoder.blogspot.com/2011/11/automated-gradle-project-deployment-to.html - * artifactory will execute uploadArchives to force generation of ivy.xml, and we don't want that to trigger an upload to maven - * central, so using custom upload task. - */ -task uploadMavenCentral(type:Upload, dependsOn: signArchives) { - configuration = configurations.archives - onlyIf { ['release', 'snapshot'].contains(project.status) } - repositories.mavenDeployer { - beforeDeployment { signing.signPom(it) } - - // To test deployment locally, use the following instead of oss.sonatype.org - //repository(url: "file://localhost/${rootProject.rootDir}/repo") - - def sonatypeUsername = rootProject.hasProperty('sonatypeUsername')?rootProject.sonatypeUsername:'' - def sonatypePassword = rootProject.hasProperty('sonatypePassword')?rootProject.sonatypePassword:'' - - repository(url: 'https://oss.sonatype.org/service/local/staging/deploy/maven2') { - authentication(userName: sonatypeUsername, password: sonatypePassword) - } - - snapshotRepository(url: 'https://oss.sonatype.org/content/repositories/snapshots/') { - authentication(userName: sonatypeUsername, password: sonatypePassword) - } - - // Prevent datastamp from being appending to artifacts during deployment - uniqueVersion = false - - // Closure to configure all the POM with extra info, common to all projects - pom.project { - name "${project.name}" - description "Java C Preprocessor" - developers { - developer { - id 'shevek' - name 'Shevek' - email 'github@anarres.org' - } - } - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - url "https://github.com/shevek/${rootProject.githubProjectName}" - scm { - connection "scm:git:git@github.com:shevek/${rootProject.githubProjectName}.git" - url "scm:git:git@github.com:shevek/${rootProject.githubProjectName}.git" - developerConnection "scm:git:git@github.com:shevek/${rootProject.githubProjectName}.git" - } - issueManagement { - system 'github' - url "https://github.com/shevek/${rootProject.githubProjectName}/issues" - } - } - } -} - diff --git a/gradle/netflix-oss.gradle b/gradle/netflix-oss.gradle deleted file mode 100644 index a87bc54..0000000 --- a/gradle/netflix-oss.gradle +++ /dev/null @@ -1 +0,0 @@ -apply from: 'http://artifacts.netflix.com/gradle-netflix-local/artifactory.gradle' diff --git a/gradle/release.gradle b/gradle/release.gradle deleted file mode 100644 index 6e3c20e..0000000 --- a/gradle/release.gradle +++ /dev/null @@ -1,60 +0,0 @@ -apply plugin: 'release' - -[ uploadIvyLocal: 'uploadLocal', uploadArtifactory: 'artifactoryPublish', buildWithArtifactory: 'build' ].each { key, value -> - // Call out to compile against internal repository - task "${key}"(type: GradleBuild) { - startParameter = project.gradle.startParameter.newInstance() - doFirst { - startParameter.projectProperties = [status: project.status, preferredStatus: project.status] - } - startParameter.addInitScript( file('gradle/netflix-oss.gradle') ) - startParameter.getExcludedTaskNames().add('check') - tasks = [ 'build', value ] - } -} - -// Marker task for following code to key in on -task releaseCandidate(dependsOn: release) -task forceCandidate { - onlyIf { gradle.taskGraph.hasTask(releaseCandidate) } - doFirst { project.status = 'candidate' } -} -task forceRelease { - onlyIf { !gradle.taskGraph.hasTask(releaseCandidate) } - doFirst { project.status = 'release' } -} -release.dependsOn([forceCandidate, forceRelease]) - -task releaseSnapshot(dependsOn: [uploadArtifactory, uploadMavenCentral]) - -// Ensure our versions look like the project status before publishing -task verifyStatus << { - def hasSnapshot = version.contains('-SNAPSHOT') - if (project.status == 'snapshot' && !hasSnapshot) { - throw new GradleException("Version (${version}) needs -SNAPSHOT if publishing snapshot") - } -} -uploadArtifactory.dependsOn(verifyStatus) -uploadMavenCentral.dependsOn(verifyStatus) - -// Ensure upload happens before taggging, hence upload failures will leave repo in a revertable state -preTagCommit.dependsOn([uploadArtifactory, uploadMavenCentral]) - - -gradle.taskGraph.whenReady { taskGraph -> - def hasRelease = taskGraph.hasTask('commitNewVersion') - def indexOf = { return taskGraph.allTasks.indexOf(it) } - - if (hasRelease) { - assert indexOf(build) < indexOf(unSnapshotVersion), 'build target has to be after unSnapshotVersion' - assert indexOf(uploadMavenCentral) < indexOf(preTagCommit), 'preTagCommit has to be after uploadMavenCentral' - assert indexOf(uploadArtifactory) < indexOf(preTagCommit), 'preTagCommit has to be after uploadArtifactory' - } -} - -// Prevent plugin from asking for a version number interactively -ext.'gradle.release.useAutomaticVersion' = "true" - -release { - git.requireBranch = null -} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 5838598..0000000 Binary files a/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 40aa5f8..0000000 --- a/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Dec 27 05:48:20 PST 2013 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-bin.zip diff --git a/gradlew b/gradlew deleted file mode 100755 index 91a7e26..0000000 --- a/gradlew +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat deleted file mode 100644 index aec9973..0000000 --- a/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/lib/ant/ant-contrib.jar b/lib/ant/ant-contrib.jar deleted file mode 100644 index 6e04e84..0000000 Binary files a/lib/ant/ant-contrib.jar and /dev/null differ diff --git a/lib/checkstyle/checkstyle-all-4.1.jar b/lib/checkstyle/checkstyle-all-4.1.jar deleted file mode 100644 index ea018b6..0000000 Binary files a/lib/checkstyle/checkstyle-all-4.1.jar and /dev/null differ diff --git a/lib/checkstyle/commons-beanutils-core.jar b/lib/checkstyle/commons-beanutils-core.jar deleted file mode 100644 index ce79cbe..0000000 Binary files a/lib/checkstyle/commons-beanutils-core.jar and /dev/null differ diff --git a/lib/checkstyle/commons-cli.jar b/lib/checkstyle/commons-cli.jar deleted file mode 100644 index 22a004e..0000000 Binary files a/lib/checkstyle/commons-cli.jar and /dev/null differ diff --git a/lib/checkstyle/commons-collections.jar b/lib/checkstyle/commons-collections.jar deleted file mode 100644 index f66c6d2..0000000 Binary files a/lib/checkstyle/commons-collections.jar and /dev/null differ diff --git a/lib/checkstyle/commons-logging.jar b/lib/checkstyle/commons-logging.jar deleted file mode 100644 index b99c937..0000000 Binary files a/lib/checkstyle/commons-logging.jar and /dev/null differ diff --git a/lib/cobertura/asm-3.2.jar b/lib/cobertura/asm-3.2.jar deleted file mode 100644 index 2a83445..0000000 Binary files a/lib/cobertura/asm-3.2.jar and /dev/null differ diff --git a/lib/cobertura/asm-tree-3.2.jar b/lib/cobertura/asm-tree-3.2.jar deleted file mode 100644 index 4ab3528..0000000 Binary files a/lib/cobertura/asm-tree-3.2.jar and /dev/null differ diff --git a/lib/cobertura/cobertura.jar b/lib/cobertura/cobertura.jar deleted file mode 100644 index 438fe55..0000000 Binary files a/lib/cobertura/cobertura.jar and /dev/null differ diff --git a/lib/cobertura/jakarta-oro-2.0.8.jar b/lib/cobertura/jakarta-oro-2.0.8.jar deleted file mode 100644 index 23488d2..0000000 Binary files a/lib/cobertura/jakarta-oro-2.0.8.jar and /dev/null differ diff --git a/lib/findbugs/lib/annotations.jar b/lib/findbugs/lib/annotations.jar deleted file mode 100644 index e16db1f..0000000 Binary files a/lib/findbugs/lib/annotations.jar and /dev/null differ diff --git a/lib/findbugs/lib/asm-3.0.jar b/lib/findbugs/lib/asm-3.0.jar deleted file mode 100644 index 7a5c727..0000000 Binary files a/lib/findbugs/lib/asm-3.0.jar and /dev/null differ diff --git a/lib/findbugs/lib/asm-analysis-3.0.jar b/lib/findbugs/lib/asm-analysis-3.0.jar deleted file mode 100644 index c5f795f..0000000 Binary files a/lib/findbugs/lib/asm-analysis-3.0.jar and /dev/null differ diff --git a/lib/findbugs/lib/asm-commons-3.0.jar b/lib/findbugs/lib/asm-commons-3.0.jar deleted file mode 100644 index 2971530..0000000 Binary files a/lib/findbugs/lib/asm-commons-3.0.jar and /dev/null differ diff --git a/lib/findbugs/lib/asm-tree-3.0.jar b/lib/findbugs/lib/asm-tree-3.0.jar deleted file mode 100644 index c6347fe..0000000 Binary files a/lib/findbugs/lib/asm-tree-3.0.jar and /dev/null differ diff --git a/lib/findbugs/lib/asm-util-3.0.jar b/lib/findbugs/lib/asm-util-3.0.jar deleted file mode 100644 index 9515986..0000000 Binary files a/lib/findbugs/lib/asm-util-3.0.jar and /dev/null differ diff --git a/lib/findbugs/lib/asm-xml-3.0.jar b/lib/findbugs/lib/asm-xml-3.0.jar deleted file mode 100644 index b3d1a64..0000000 Binary files a/lib/findbugs/lib/asm-xml-3.0.jar and /dev/null differ diff --git a/lib/findbugs/lib/bcel.jar b/lib/findbugs/lib/bcel.jar deleted file mode 100644 index be093c8..0000000 Binary files a/lib/findbugs/lib/bcel.jar and /dev/null differ diff --git a/lib/findbugs/lib/buggy.icns b/lib/findbugs/lib/buggy.icns deleted file mode 100644 index b1f4660..0000000 Binary files a/lib/findbugs/lib/buggy.icns and /dev/null differ diff --git a/lib/findbugs/lib/dom4j-full.jar b/lib/findbugs/lib/dom4j-full.jar deleted file mode 100644 index 1efbf7e..0000000 Binary files a/lib/findbugs/lib/dom4j-full.jar and /dev/null differ diff --git a/lib/findbugs/lib/findbugs-ant.jar b/lib/findbugs/lib/findbugs-ant.jar deleted file mode 100644 index 3a2740e..0000000 Binary files a/lib/findbugs/lib/findbugs-ant.jar and /dev/null differ diff --git a/lib/findbugs/lib/findbugs.jar b/lib/findbugs/lib/findbugs.jar deleted file mode 100644 index 10c8f78..0000000 Binary files a/lib/findbugs/lib/findbugs.jar and /dev/null differ diff --git a/lib/findbugs/lib/findbugsGUI.jar b/lib/findbugs/lib/findbugsGUI.jar deleted file mode 100644 index 8cf6984..0000000 Binary files a/lib/findbugs/lib/findbugsGUI.jar and /dev/null differ diff --git a/lib/findbugs/lib/jsr305.jar b/lib/findbugs/lib/jsr305.jar deleted file mode 100644 index 90119cb..0000000 Binary files a/lib/findbugs/lib/jsr305.jar and /dev/null differ diff --git a/lib/findbugs/plugin/coreplugin.jar b/lib/findbugs/plugin/coreplugin.jar deleted file mode 100644 index 0f9c317..0000000 Binary files a/lib/findbugs/plugin/coreplugin.jar and /dev/null differ diff --git a/lib/findbugs/xsl/default.xsl b/lib/findbugs/xsl/default.xsl deleted file mode 100644 index e8f30d4..0000000 --- a/lib/findbugs/xsl/default.xsl +++ /dev/null @@ -1,376 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- - FindBugs - Find bugs in Java programs - Copyright (C) 2004,2005 University of Maryland - Copyright (C) 2005, Chris Nappin - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---> - -<!-- - A simple XSLT stylesheet to transform FindBugs XML results - annotated with messages into HTML. - - If you want to experiment with modifying this stylesheet, - or write your own, you need to generate XML output from FindBugs - using a special option which lets it know to include - human-readable messages in the XML. Invoke the findbugs script - as follows: - - findbugs -textui -xml:withMessages -project myProject.fb > results.xml - - Then you can use your favorite XSLT implementation to transform - the XML output into HTML. (But don't use xsltproc. It generates well-nigh - unreadable output, and generates incorrect output for the - <script> element.) - - Authors: - David Hovemeyer - Chris Nappin (summary table) ---> - -<xsl:stylesheet - version="1.0" - xmlns="http://www.w3.org/1999/xhtml" - xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> - -<xsl:output - method="xml" - indent="yes" - omit-xml-declaration="yes" - standalone="yes" - doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" - doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" - encoding="UTF-8"/> - -<xsl:variable name="literalNbsp">&nbsp;</xsl:variable> - -<!--xsl:key name="bug-category-key" match="/BugCollection/BugInstance" use="@category"/--> - -<xsl:variable name="bugTableHeader"> - <tr class="tableheader"> - <th align="left">Code</th> - <th align="left">Warning</th> - </tr> -</xsl:variable> - -<xsl:template match="/"> - <html> - <head> - <title>FindBugs Report</title> - <style type="text/css"> - .tablerow0 { - background: #EEEEEE; - } - - .tablerow1 { - background: white; - } - - .detailrow0 { - background: #EEEEEE; - } - - .detailrow1 { - background: white; - } - - .tableheader { - background: #b9b9fe; - font-size: larger; - } - - .tablerow0:hover, .tablerow1:hover { - background: #aaffaa; - } - - .priority-1 { - color: red; - font-weight: bold; - } - .priority-2 { - color: orange; - font-weight: bold; - } - .priority-3 { - color: green; - font-weight: bold; - } - .priority-4 { - color: blue; - font-weight: bold; - } - </style> - <script type="text/javascript"> - function toggleRow(elid) { - if (document.getElementById) { - element = document.getElementById(elid); - if (element) { - if (element.style.display == 'none') { - element.style.display = 'block'; - //window.status = 'Toggle on!'; - } else { - element.style.display = 'none'; - //window.status = 'Toggle off!'; - } - } - } - } - </script> - </head> - - <xsl:variable name="unique-catkey" select="/BugCollection/BugCategory/@category"/> - <!--xsl:variable name="unique-catkey" select="/BugCollection/BugInstance[generate-id() = generate-id(key('bug-category-key',@category))]/@category"/--> - - <body> - - <h1><a href="http://findbugs.sourceforge.net">FindBugs</a> Report</h1> - - <h2>Project Information</h2> - <xsl:apply-templates select="/BugCollection/Project"/> - - <h2>Metrics</h2> - <xsl:apply-templates select="/BugCollection/FindBugsSummary"/> - - <h2>Contents</h2> - <ul> - <xsl:for-each select="$unique-catkey"> - <xsl:sort select="." order="ascending"/> - <xsl:variable name="catkey" select="."/> - <xsl:variable name="catdesc" select="/BugCollection/BugCategory[@category=$catkey]/Description"/> - - <li><a href="#Warnings_{$catkey}"><xsl:value-of select="$catdesc"/> Warnings</a></li> - </xsl:for-each> - - <li><a href="#Details">Details</a></li> - </ul> - - <h1>Summary</h1> - <table width="500" cellpadding="5" cellspacing="2"> - <tr class="tableheader"> - <th align="left">Warning Type</th> - <th align="right">Number</th> - </tr> - - <xsl:for-each select="$unique-catkey"> - <xsl:sort select="." order="ascending"/> - <xsl:variable name="catkey" select="."/> - <xsl:variable name="catdesc" select="/BugCollection/BugCategory[@category=$catkey]/Description"/> - <xsl:variable name="styleclass"> - <xsl:choose><xsl:when test="position() mod 2 = 1">tablerow0</xsl:when> - <xsl:otherwise>tablerow1</xsl:otherwise> - </xsl:choose> - </xsl:variable> - - <tr class="{$styleclass}"> - <td><a href="#Warnings_{$catkey}"><xsl:value-of select="$catdesc"/> Warnings</a></td> - <td align="right"><xsl:value-of select="count(/BugCollection/BugInstance[(@category=$catkey) and not(@last)])"/></td> - </tr> - </xsl:for-each> - - <xsl:variable name="styleclass"> - <xsl:choose><xsl:when test="count($unique-catkey) mod 2 = 0">tablerow0</xsl:when> - <xsl:otherwise>tablerow1</xsl:otherwise> - </xsl:choose> - </xsl:variable> - <tr class="{$styleclass}"> - <td><b>Total</b></td> - <td align="right"><b><xsl:value-of select="count(/BugCollection/BugInstance[not(@last)])"/></b></td> - </tr> - </table> - - <h1>Warnings</h1> - - <p>Click on a warning row to see full context information.</p> - - <xsl:for-each select="$unique-catkey"> - <xsl:sort select="." order="ascending"/> - <xsl:variable name="catkey" select="."/> - <xsl:variable name="catdesc" select="/BugCollection/BugCategory[@category=$catkey]/Description"/> - - <xsl:call-template name="generateWarningTable"> - <xsl:with-param name="warningSet" select="/BugCollection/BugInstance[(@category=$catkey) and not(@last)]"/> - <xsl:with-param name="sectionTitle"><xsl:value-of select="$catdesc"/> Warnings</xsl:with-param> - <xsl:with-param name="sectionId">Warnings_<xsl:value-of select="$catkey"/></xsl:with-param> - </xsl:call-template> - </xsl:for-each> - - <h1><a name="Details">Details</a></h1> - - <xsl:apply-templates select="/BugCollection/BugPattern"> - <xsl:sort select="@abbrev"/> - <xsl:sort select="ShortDescription"/> - </xsl:apply-templates> - - </body> - </html> -</xsl:template> - -<xsl:template match="Project"> - <p>Project: - <xsl:choose> - <xsl:when test='string-length(/BugCollection/Project/@projectName)>0'><xsl:value-of select="/BugCollection/Project/@projectName" /></xsl:when> - <xsl:otherwise><xsl:value-of select="/BugCollection/Project/@filename" /></xsl:otherwise> - </xsl:choose> - </p> - <p>FindBugs version: <xsl:value-of select="/BugCollection/@version"/></p> - - <p>Code analyzed:</p> - <ul> - <xsl:for-each select="./Jar"> - <li><xsl:value-of select="text()"/></li> - </xsl:for-each> - </ul> - <p><br/><br/></p> -</xsl:template> - -<xsl:template match="BugInstance[not(@last)]"> - <xsl:variable name="warningId"><xsl:value-of select="generate-id()"/></xsl:variable> - - <tr class="tablerow{position() mod 2}" onclick="toggleRow('{$warningId}');"> - - <td> - <span><xsl:attribute name="class">priority-<xsl:value-of select="@priority"/></xsl:attribute> - <xsl:value-of select="@abbrev"/> - </span> - </td> - - <td> - <xsl:value-of select="LongMessage"/> - </td> - - </tr> - - <!-- Add bug annotation elements: Class, Method, Field, SourceLine, Field --> - <tr class="detailrow{position() mod 2}"> - <td/> - <td> - <p id="{$warningId}" style="display: none;"> - <a href="#{@type}">Bug type <xsl:value-of select="@type"/> (click for details)</a> - <xsl:for-each select="./*/Message"> - <br/><xsl:value-of select="text()" disable-output-escaping="no"/> - </xsl:for-each> - </p> - </td> - </tr> -</xsl:template> - -<xsl:template match="BugPattern"> - <h2><a name="{@type}"><xsl:value-of select="@type"/>: <xsl:value-of select="ShortDescription"/></a></h2> - <xsl:value-of select="Details" disable-output-escaping="yes"/> -</xsl:template> - -<xsl:template name="generateWarningTable"> - <xsl:param name="warningSet"/> - <xsl:param name="sectionTitle"/> - <xsl:param name="sectionId"/> - - <h2><a name="{$sectionId}"><xsl:value-of select="$sectionTitle"/></a></h2> - <table class="warningtable" width="100%" cellspacing="0"> - <xsl:copy-of select="$bugTableHeader"/> - <xsl:apply-templates select="$warningSet"> - <xsl:sort select="@abbrev"/> - <xsl:sort select="Class/@classname"/> - </xsl:apply-templates> - </table> -</xsl:template> - -<xsl:template match="FindBugsSummary"> - <xsl:variable name="kloc" select="@total_size div 1000.0"/> - <xsl:variable name="format" select="'#######0.00'"/> - - <p><xsl:value-of select="@total_size"/> lines of code analyzed, - in <xsl:value-of select="@total_classes"/> classes, - in <xsl:value-of select="@num_packages"/> packages.</p> - <table width="500" cellpadding="5" cellspacing="2"> - <tr class="tableheader"> - <th align="left">Metric</th> - <th align="right">Total</th> - <th align="right">Density*</th> - </tr> - <tr class="tablerow0"> - <td>High Priority Warnings</td> - <td align="right"><xsl:value-of select="@priority_1"/></td> - <td align="right"> - <xsl:choose> - <xsl:when test= "number($kloc) > 0.0 and number(@priority_1) > 0.0"> - <xsl:value-of select="format-number(@priority_1 div $kloc, $format)"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="format-number(0.0, $format)"/> - </xsl:otherwise> - </xsl:choose> - </td> - </tr> - <tr class="tablerow1"> - <td>Medium Priority Warnings</td> - <td align="right"><xsl:value-of select="@priority_2"/></td> - <td align="right"> - <xsl:choose> - <xsl:when test= "number($kloc) > 0.0 and number(@priority_2) > 0.0"> - <xsl:value-of select="format-number(@priority_2 div $kloc, $format)"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="format-number(0.0, $format)"/> - </xsl:otherwise> - </xsl:choose> - </td> - </tr> - - <xsl:choose> - <xsl:when test="@priority_3"> - <tr class="tablerow1"> - <td>Low Priority Warnings</td> - <td align="right"><xsl:value-of select="@priority_3"/></td> - <td align="right"> - <xsl:choose> - <xsl:when test= "number($kloc) > 0.0 and number(@priority_3) > 0.0"> - <xsl:value-of select="format-number(@priority_3 div $kloc, $format)"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="format-number(0.0, $format)"/> - </xsl:otherwise> - </xsl:choose> - </td> - </tr> - <xsl:variable name="totalClass" select="tablerow0"/> - </xsl:when> - <xsl:otherwise> - <xsl:variable name="totalClass" select="tablerow1"/> - </xsl:otherwise> - </xsl:choose> - - <tr class="$totalClass"> - <td><b>Total Warnings</b></td> - <td align="right"><b><xsl:value-of select="@total_bugs"/></b></td> - <xsl:choose> - <xsl:when test="number($kloc) > 0.0"> - <td align="right"><b><xsl:value-of select="format-number(@total_bugs div $kloc, $format)"/></b></td> - </xsl:when> - <xsl:otherwise> - <td align="right"><b><xsl:value-of select="format-number(0.0, $format)"/></b></td> - </xsl:otherwise> - </xsl:choose> - </tr> - </table> - <p><i>(* Defects per Thousand lines of non-commenting source statements)</i></p> - <p><br/><br/></p> - -</xsl:template> - -</xsl:stylesheet> - -<!-- vim:set ts=4: --> diff --git a/lib/findbugs/xsl/fancy-hist.xsl b/lib/findbugs/xsl/fancy-hist.xsl deleted file mode 100644 index 8086600..0000000 --- a/lib/findbugs/xsl/fancy-hist.xsl +++ /dev/null @@ -1,1127 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!-- - Copyright (C) 2005, 2006 Etienne Giraudy, InStranet Inc - Copyright (C) 2005, 2007 Etienne Giraudy - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---> - -<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" > - <xsl:output - method="xml" indent="yes" - doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" - doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" - encoding="UTF-8"/> - - <xsl:variable name="apos" select=""'""/> - <xsl:key name="lbc-code-key" match="/BugCollection/BugInstance" use="concat(@category,@abbrev)" /> - <xsl:key name="lbc-bug-key" match="/BugCollection/BugInstance" use="concat(@category,@abbrev,@type)" /> - <xsl:key name="lbp-class-b-t" match="/BugCollection/BugInstance" use="concat(Class/@classname,@type)" /> - -<xsl:template match="/" > - -<html> - <head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> - <title> - FindBugs (<xsl:value-of select="/BugCollection/@version" />) - Analysis for - <xsl:choose> - <xsl:when test='string-length(/BugCollection/Project/@projectName)>0'><xsl:value-of select="/BugCollection/Project/@projectName" /></xsl:when> - <xsl:otherwise><xsl:value-of select="/BugCollection/Project/@filename" /></xsl:otherwise> - </xsl:choose> - </title> - <style type="text/css"> - html, body, div, form { - margin:0px; - padding:0px; - } - body { - padding:3px; - } - a, a:link , a:active, a:visited, a:hover { - text-decoration: none; color: black; - } - #navlist { - padding: 3px 0; - margin-left: 0; - border-bottom: 1px solid #778; - font: bold 12px Verdana, sans-serif; - } - #navlist li { - list-style: none; - margin: 0; - display: inline; - } - #navlist li a { - padding: 3px 0.5em; - margin-left: 3px; - border: 1px solid #778; - border-bottom: none; - background: #DDE; - text-decoration: none; - } - #navlist li a:link { color: #448; } - #navlist li a:visited { color: #667; } - #navlist li a:hover { - color: #000; - background: #AAE; - border-color: #227; - } - #navlist li a.current { - background: white; - border-bottom: 1px solid white; - } - #filterWrapper { - margin-bottom:5px; - } - #displayWrapper { - margin-top:5px; - } - .message { - background:#BBBBBB; - border: 1px solid #778; - } - .displayContainer { - border:1px solid #555555; - margin-top:3px; - padding: 3px; - display:none; - } - #summaryContainer table, - #historyContainer table { - border:1px solid black; - } - #summaryContainer th, - #historyContainer th { - background: #aaaaaa; - color: white; - } - #summaryContainer th, #summaryContainer td, - #historyContainer th, #historyContainer td { - padding: 2px 4px 2px 4px; - } - .summary-name { - background: #eeeeee; - text-align:left; - } - .summary-size { - background: #eeeeee; - text-align:center; - } - .summary-priority-all { - background: #dddddd; - text-align:center; - } - .summary-priority-1 { - background: red; - text-align:center; - } - .summary-priority-2 { - background: orange; - text-align:center; - } - .summary-priority-3 { - background: green; - text-align:center; - } - .summary-priority-4 { - background: blue; - text-align:center; - } - - .bugList-level1 { - margin-bottom:5px; - } - .bugList-level1, .bugList-level2, .bugList-level3, .bugList-level4 { - background-color: #ffffff; - margin-left:15px; - padding-left:10px; - } - .bugList-level1-label, .bugList-level2-label, .bugList-level3-label, .bugList-level4-label { - background-color: #bbbbbb; - border: 1px solid black; - padding: 1px 3px 1px 3px;; - } - .bugList-level2-label, .bugList-level3-label, .bugList-level4-label { - border-width: 0px 1px 1px 1px; - } - .bugList-level4-label { - background-color: #ffffff; - border: 0px 0px 1px 0px; - } - .bugList-level4 { - border: 0px 1px 1px 1px; - } - - .bugList-level4-inner { - border-style: solid; - border-color: black; - border-width: 0px 1px 1px 1px; - } - .b-r { - font-size: 10pt; font-weight: bold; padding: 0 0 0 60px; - } - .b-d { - font-weight: normal; background: #ccccc0; - padding: 0 5px 0 5px; margin: 0px; - } - .b-1 { - background: red; height: 0.5em; width: 1em; - margin-right: 0.5em; - } - .b-2 { - background: orange; height: 0.5em; width: 1em; - margin-right: 0.5em; - } - .b-3 { - background: green; height: 0.5em; width: 1em; - margin-right: 0.5em; - } - .b-4 { - background: blue; height: 0.5em; width: 1em; - margin-right: 0.5em; - } - - </style> - <script type='text/javascript'><xsl:text disable-output-escaping='yes'><![CDATA[ - var menus = new Array('summary','info','history','listByCategories','listByPackages'); - var selectedMenuId = "summary"; - var selectedVersion = -1; - var selectedPriority = 4; - var lastVersion = 0; - - var bPackageNamesPopulated = false; - - var filterContainerId = "filterWrapper"; - var messageContainerId = "messageContainer"; - var summaryContainerId = "summaryContainer"; - var infoContainerId = "infoContainer"; - var historyContainerId = "historyContainer"; - var listByCategoriesContainerId = "listByCategoriesContainer"; - var listByPackagesContainerId = "listByPackagesContainer"; - - var idxCatKey = 0; var idxCatDescr = 1; var idxBugCat = 1; - var idxCodeKey = 0; var idxCodeDescr = 1; var idxBugCode = 2; - var idxPatternKey = 2; var idxPatternDescr = 3; var idxBugPattern = 3; - var idxBugKey = 0; var idxBugDescr = 6; - var idxBugClass = 6, idxBugPackage = 7; - - // main init function - function init() { - loadFilter(); - selectMenu(selectedMenuId); - lastVersion = versions.length - 1; - } - - // menu callback function - function selectMenu(menuId) { - document.getElementById(selectedMenuId).className="none"; - document.getElementById(menuId).className="current"; - if (menuId!=selectedMenuId) { - hideMenu(selectedMenuId); - selectedMenuId = menuId; - } - if (menuId=="summary") displaySummary(); - if (menuId=="info") displayInfo(); - if (menuId=="history") displayHistory(); - if (menuId=="listByCategories") displayListByCategories(); - if (menuId=="listByPackages") displayListByPackages(); - } - - // display filter - function loadFilter() { - var versionsBox = document.findbugsForm.versions.options; - versionsBox[0] = new Option(" -- All Versions -- ","-1"); - versionsBox.selectedIndex = 0; - if (versions.length>=1) { - for (x=0; versions.length>1 && x<versions.length; x++) { - versionsBox[x+1] = new Option(" Bugs at release: "+versions[versions.length-x-1][1], versions[versions.length-x-1][0]); - } - } - - var prioritiesBox = document.findbugsForm.priorities.options; - prioritiesBox[0] = new Option(" -- All priorities -- ", "4"); - prioritiesBox[1] = new Option(" P1 bugs ", "1"); - prioritiesBox[2] = new Option(" P1 and P2 bugs ", "2"); - prioritiesBox[3] = new Option(" P1, P2 and P3 bugs ", "3"); - } - - // display a message - function displayMessage(msg) { - var container = document.getElementById(messageContainerId); - container.innerHTML = "<div class='message'>"+msg+"</div>"; - } - - // reset displayed message - function resetMessage() { - var container = document.getElementById(messageContainerId); - container.innerHTML = ""; - } - - function hideMenu(menuId) { - var container = menuId+"Container"; - document.getElementById(container).style.display="none"; - } - - // filter callback function - function filter() { - var versionsBox = document.findbugsForm.versions.options; - selectedVersion = versionsBox[versionsBox.selectedIndex].value; - - var prioritiesBox = document.findbugsForm.priorities.options; - selectedPriority = prioritiesBox[prioritiesBox.selectedIndex].value; - - selectMenu(selectedMenuId); - } - - // display summary tab - function displaySummary() { - resetMessage(); - hide(filterContainerId); - var container = document.getElementById(summaryContainerId); - container.style.display="block"; - } - - // display info tab - function displayInfo() { - resetMessage(); - hide(filterContainerId); - var container = document.getElementById(infoContainerId); - container.style.display="block"; - } - - // display history tab - function displayHistory() { - displayMessage("Loading history..."); - hide(filterContainerId); - var container = document.getElementById(historyContainerId); - var content = ""; - var i=0; - var p = [0,0,0,0,0]; - var f = [0,0,0,0,0]; - - content += "<table><tr><th>Release</th><th>Bugs</th><th>Bugs p1</th><th>Bugs p2</th><th>Bugs p3</th><th>Bugs Exp.</th></tr>"; - - for (i=(versions.length-1); i>0; i--) { - v = countBugsVersion(i, 4); - t = countTotalBugsVersion(i); - o = countFixedButActiveBugsVersion(i); - f = countFixedBugsInVersion(i); - content += "<tr>"; - content += "<td class='summary-name'>" + versions[i][1] + "</td>"; - content += "<td class='summary-priority-all'> " + (t[0] + o[0]) + " (+" + v[0] + " / -" + f[0] + ") </td>"; - content += "<td class='summary-priority-1' > " + (t[1] + o[1]) + " (+" + v[1] + " / -" + f[1] + ") </td>"; - content += "<td class='summary-priority-2' > " + (t[2] + o[2]) + " (+" + v[2] + " / -" + f[2] + ") </td>"; - content += "<td class='summary-priority-3' > " + (t[3] + o[3]) + " (+" + v[3] + " / -" + f[3] + ") </td>"; - content += "<td class='summary-priority-4' > " + (t[4] + o[4]) + " (+" + v[4] + " / -" + f[4] + ") </td>"; - content += "</tr>"; - } - - t = countTotalBugsVersion(0); - o = countFixedButActiveBugsVersion(0); - content += "<tr>"; - content += "<td class='summary-name'>" + versions[0][1] + "</td>"; - content += "<td class='summary-priority-all'> " + (t[0] + o[0]) + " </td>"; - content += "<td class='summary-priority-1' > " + (t[1] + o[1]) + " </td>"; - content += "<td class='summary-priority-2' > " + (t[2] + o[2]) + " </td>"; - content += "<td class='summary-priority-3' > " + (t[3] + o[3]) + " </td>"; - content += "<td class='summary-priority-4' > " + (t[4] + o[4]) + " </td>"; - content += "</tr>"; - - content += "</table>"; - container.innerHTML = content; - container.style.display="block"; - resetMessage(); - } - - // display list by cat tab - function displayListByCategories() { - show(filterContainerId); - var container = document.getElementById(listByCategoriesContainerId); - container.innerHTML = ""; - container.style.display="block"; - displayMessage("Loading stats (categories)..."); - container.innerHTML = displayLevel1("lbc", "Stats by Bug Categories"); - resetMessage(); - } - - // display list by package tab - function displayListByPackages() { - show(filterContainerId); - var container = document.getElementById(listByPackagesContainerId); - container.style.display="block"; - if (!bPackageNamesPopulated) { - displayMessage("Initializing..."); - populatePackageNames(); - } - displayMessage("Loading stats (packages)..."); - container.innerHTML = displayLevel1("lbp", "Stats by Bug Package"); - resetMessage(); - } - - // callback function for list item click - function toggleList(listType, containerId, id1, id2, id3) { - var container = document.getElementById(containerId); - if (container.style.display=="block") { - container.style.display="none"; - } else { - if (listType=="lbc") { - if (id1.length>0 && id2.length==0 && id3.length==0) { - displayCategoriesCodes(containerId, id1); - } else if (id1.length>0 && id2.length>0 && id3.length==0) { - displayCategoriesCodesPatterns(containerId, id1, id2); - } else if (id1.length>0 && id2.length>0 && id3.length>0) { - displayCategoriesCodesPatternsBugs(containerId, id1, id2, id3); - } else { - // ??? - } - } else if (listType=="lbp") { - if (id1.length>0 && id2.length==0 && id3.length==0) { - displayPackageCodes(containerId, id1); - } else if (id1.length>0 && id2.length>0 && id3.length==0) { - displayPackageClassPatterns(containerId, id1, id2); - } else if (id1.length>0 && id2.length>0 && id3.length>0) { - displayPackageClassPatternsBugs(containerId, id1, id2, id3); - } else { - // ??? - } - } else { - // ???? - } - } - } - - // list by categories, display bug cat>codes - function displayCategoriesCodes(containerId, catId) { - displayMessage("Loading stats (codes)..."); - var container = document.getElementById(containerId); - container.style.display="block"; - if (container.innerHTML=="Loading..." || container.innerHTML=="") { - container.innerHTML = displayLevel2("lbc", catId); - } - resetMessage(); - } - - // list by categories, display bug package>codes - function displayPackageCodes(containerId, packageId) { - displayMessage("Loading stats (codes)..."); - var container = document.getElementById(containerId); - container.style.display="block"; - if (container.innerHTML=="Loading..." || container.innerHTML=="") { - container.innerHTML = displayLevel2("lbp", packageId); - } - resetMessage(); - } - - // list by categories, display bug cat>codes>patterns - function displayCategoriesCodesPatterns(containerId, catId, codeId) { - displayMessage("Loading stats (patterns)..."); - var container = document.getElementById(containerId); - container.style.display="block"; - if (container.innerHTML=="Loading..." || container.innerHTML=="") - container.innerHTML = displayLevel3("lbc", catId, codeId); - resetMessage(); - } - - // list by package, display bug package>class>patterns - function displayPackageClassPatterns(containerId, packageId, classId) { - displayMessage("Loading stats (patterns)..."); - var container = document.getElementById(containerId); - container.style.display="block"; - if (container.innerHTML=="Loading..." || container.innerHTML=="") - container.innerHTML = displayLevel3("lbp", packageId, classId); - resetMessage(); - } - - // list by categories, display bug cat>codes>patterns>bugs - function displayCategoriesCodesPatternsBugs(containerId, catId, codeId, patternId) { - displayMessage("Loading stats (bugs)..."); - var container = document.getElementById(containerId); - container.style.display="block"; - if (container.innerHTML=="Loading..." || container.innerHTML=="") - container.innerHTML = displayLevel4("lbc", catId, codeId, patternId); - resetMessage(); - } - - // list by package, display bug package>class>patterns>bugs - function displayPackageClassPatternsBugs(containerId, packageId, classId, patternId) { - displayMessage("Loading stats (bugs)..."); - var container = document.getElementById(containerId); - container.style.display="block"; - if (container.innerHTML=="Loading..." || container.innerHTML=="") - container.innerHTML = displayLevel4("lbp", packageId, classId, patternId); - resetMessage(); - } - - // generate level 1 list - function displayLevel1(list, title) { - var content = ""; - var content2 = ""; - - content += "<h3>"+title+"</h3>"; - content += getPriorityLegend(); - content2 += "<div class='bugList'>"; - - var id = ""; - var containerId = ""; - var subContainerId = ""; - var prefixSub = ""; - var prefixId = ""; - var p = [0,0,0,0,0]; - var numberOfBugs = 0; - var label = ""; - var max = 0; - if (list=="lbc") { - max = categories.length; - } else if (list=="lbp") { - max = packageStats.length; - } - - for (var x=0; x<max -1; x++) { - if (list=="lbp" && packageStats[x][1]=="0") continue; - - if (list=="lbc") { - id = categories[x][idxCatKey]; - label = categories[x][idxCatDescr]; - containerId = "categories-" + id; - subContainerId = "cat-"+id; - p = countBugsCat(selectedVersion, selectedPriority, id, idxBugCat); - } - if (list=="lbp") { - id = packageStats[x][0]; - label = packageStats[x][0]; - containerId = "packages-" + id; - subContainerId = "package-"+id; - p = countBugsPackage(selectedVersion, selectedPriority, id, idxBugPackage); - } - - subContainerId = prefixSub+id; - - var total = p[1]+p[2]+p[3]+p[4]; - if (total > 0) { - content2 += addListItem( 1, containerId, label, total, p, subContainerId, - "toggleList('" + list + "', '" + subContainerId + "', '"+ id + "', '', '')" - ); - } - numberOfBugs += total; - } - content2 += "</div>"; - content += "<h4>Total number of bugs"; - if (selectedVersion!=-1) { - content += " (introduced in release " + versions[selectedVersion][1] +")"; - } - content += ": "+numberOfBugs+"</h4>"; - return content+content2; - } - - // generate level 2 list - function displayLevel2(list, id1) { - var content = ""; - var code = ""; - var containerId = ""; - var subContainerId = ""; - var p = [0,0,0,0,0]; - var max = 0; - var id2 = ""; - if (list=="lbc") { - max = codes.length; - } else if (list=="lbp") { - max = classStats.length; - } - - for (var x=0; x<max -1; x++) { - if (list=="lbp" && classStats[x][3]=="0") continue; - - if (list=="lbc") { - id2 = codes[x][idxCodeKey]; - label = codes[x][idxCodeDescr]; - containerId = "codes-"+id1; - subContainerId = "cat-" + id1 + "-code-" + id2; - p = countBugsCode(selectedVersion, selectedPriority, id1, idxBugCat, id2, idxBugCode); - } - if (list=="lbp") { - id2 = classStats[x][0]; - label = classStats[x][0]; - containerId = "packages-"+id1; - subContainerId = "package-" + id1 + "-class-" + id2; - p = countBugsClass(selectedVersion, selectedPriority, id1, idxBugPackage, id2, idxBugClass); - } - - var total = p[1]+p[2]+p[3]+p[4]; - if (total > 0) { - content += addListItem( 2, containerId, label, total, p, subContainerId, - "toggleList('"+ list + "', '" + subContainerId + "', '"+ id1 + "', '"+ id2 + "', '')" - ); - } - } - return content; - } - - // generate level 3 list - function displayLevel3(list, id1, id2) { - var content = ""; - var containerId = ""; - var subContainerId = ""; - var p = [0,0,0,0,0]; - var max = 0; - var label = ""; - var id3 = ""; - - if (list=="lbc") { - max = patterns.length; - } else if (list=="lbp") { - max = patterns.length; - } - - for (var x=0; x<max -1; x++) { - //if (list=="lbp" && (patterns[x][0]!=id1 || patterns[x][1]!=id2)) continue; - //if (list=="lbp" && classStats[x][3]=="0") continue; - - if (list=="lbc") { - id3 = patterns[x][idxPatternKey];; - label = patterns[x][idxPatternDescr]; - containerId = "patterns-"+id1; - subContainerId = "cat-" + id1 + "-code-" + id2 + "-pattern-" + id3; - p = countBugsPattern(selectedVersion, selectedPriority, id1, idxBugCat, id2, idxBugCode, id3, idxBugPattern); - } - if (list=="lbp") { - id3 = patterns[x][idxPatternKey];; - label = patterns[x][idxPatternDescr]; - containerId = "classpatterns-"+id1; - subContainerId = "package-" + id1 + "-class-" + id2 + "-pattern-" + id3; - p = countBugsClassPattern(selectedVersion, selectedPriority, id2, idxBugClass, id3, idxBugPattern); - } - - var total = p[1]+p[2]+p[3]+p[4]; - if (total > 0) { - content += addListItem( 3, containerId, label, total, p, subContainerId, - "toggleList('" + list + "', '" + subContainerId + "', '"+ id1 + "', '"+ id2 + "', '"+ id3 + "')" - ); - } - } - return content; - } - - // generate level 4 list - function displayLevel4(list, id1, id2, id3) { - var content = ""; - var bug = ""; - var bugP = 0; - var containerId = ""; - var subContainerId = ""; - var bugId = ""; - var label = ""; - var p = [0,0,0,0,0]; - for (var x=0; x<bugs.length -1; x++) { - bug = bugs[x]; - if (list=="lbc") { - if ( bug[1]!=id1 || bug[2]!=id2 || bug[3]!=id3 ) continue; - if ( selectedVersion!=-1 - && selectedVersion!=bug[5]) continue; - if ( selectedPriority!=4 - && selectedPriority<bug[4]) continue; - - subContainerId = "cat-" + id1 + "-code-" + id2 + "-pattern-" + id3 + "-bug-" + bug[0]; - } - if (list=="lbp") { - if ( bug[7]!=id1 || bug[6]!=id2 || bug[3]!=id3 ) continue; - if ( selectedVersion!=-1 - && selectedVersion!=bug[5]) continue; - if ( selectedPriority!=4 - && selectedPriority<bug[4]) continue; - - subContainerId = "package-" + id1 + "-class-" + id2 + "-pattern-" + id3 + "-bug-" + bug[0]; - } - - bugId = "b-uid-" + bug[0]; - label = bug[idxBugDescr]; - containerId = "bugs-"+bugId; - bugP = bug[4]; - p[bugP]++; - var total = p[1]+p[2]+p[3]+p[4]; - if (total > 0) { - content += addBug( 4, containerId, label, bugP, bug[5], subContainerId, - "showbug('" + bugId + "', '" + subContainerId + "', '"+id3+"')"); - } - } - return content; - } - - - function addListItem(level, id, label, total, p, subId, onclick) { - var content = ""; - - content += "<div class='bugList-level"+level+"' >"; - content += "<div class='bugList-level"+level+"-label' id='"+id+"' >"; - content += "<a href='' onclick=\"" + onclick + ";return false;\" "; - content += ">"; - content += "<strong>"+label+"</strong>"; - content += " "+total+" bugs"; - if (selectedPriority>1) - content += " <em>("+p[1]; - if (selectedPriority>=2) - content += "/"+p[2]; - if (selectedPriority>=3) - content += "/"+p[3]; - if (selectedPriority>=4) - content += "/"+p[4]; - if (selectedPriority>1) - content += ")</em>"; - content += "</a>"; - content += "</div>"; - content += "<div class='bugList-level"+level+"-inner' id='"+subId+"' style='display:none;'>Loading...</div>"; - content += "</div>"; - return content; - } - - function addBug( level, id, label, p, version, subId, onclick) { - var content = ""; - - content += "<div class='bugList-level" + level + "' id='" + id + "'>"; - content += "<div class='bugList-level" + level + "-label' id='" + id + "'>"; - content += "<span class='b-" + p + "'> </span>"; - content += "<a href='' onclick=\"" + onclick + ";return false;\">"; - if (version==lastVersion) { - content += "<span style='color:red;font-weight:bold;'>NEW!</span> "; - } - content += "<strong>" + label + "</strong>"; - if (version==0) { - content += " <em>since release first historized release</em>"; - } else { - content += " <em>since release " + versions[version][1] + "</em>"; - } - content += "</a>"; - content += "</div>"; - content += "<div class='bugList-level" + level + "-inner' id='" + subId + "' style='display:none;'>Loading...</div>"; - content += "</div>"; - return content; - } - - function countBugsVersion(version, priority) { - return countBugs(version, priority, "", -1, "", -1, "", -1, "", -1, "", -1); - } - - function countBugsCat(version, priority, cat, idxCat) { - return countBugs(version, priority, cat, idxCat, "", -1, "", -1, "", -1, "", -1); - } - - function countBugsPackage(version, priority, packageId, idxPackage) { - return countBugs(version, priority, "", -1, "", -1, "", -1, packageId, idxPackage, "", -1); - } - - function countBugsCode(version, priority, cat, idxCat, code, idxCode) { - return countBugs(version, priority, cat, idxCat, code, idxCode, "", -1, "", -1, "", -1); - } - - function countBugsPattern(version, priority, cat, idxCat, code, idxCode, packageId, idxPattern) { - return countBugs(version, priority, cat, idxCat, code, idxCode, packageId, idxPattern, "", -1, "", -1); - } - - function countBugsClass(version, priority, id1, idxBugPackage, id2, idxBugClass) { - return countBugs(version, priority, "", -1, "", -1, "", -1, id1, idxBugPackage, id2, idxBugClass); - } - - function countBugsClassPattern(version, priority, id2, idxBugClass, id3, idxBugPattern) { - return countBugs(version, priority, "", -1, "", -1, id3, idxBugPattern, "", -1, id2, idxBugClass); - } - - function countBugs(version, priority, cat, idxCat, code, idxCode, pattern, idxPattern, packageId, idxPackage, classId, idxClass) { - var count = [0,0,0,0,0]; - var last=1000000; - for (var x=0; x<bugs.length-1; x++) { - var bug = bugs[x]; - - var bugCat = bug[idxCat]; - var bugP = bug[4]; - var bugCode = bug[idxCode]; - var bugPattern = bug[idxPattern]; - - if ( (version==-1 || version==bug[5]) - && (priority==4 || priority>=bug[4]) - && (idxCat==-1 || bug[idxCat]==cat) - && (idxCode==-1 || bug[idxCode]==code) - && (idxPattern==-1 || bug[idxPattern]==pattern) - && (idxPackage==-1 || bug[idxPackage]==packageId) - && (idxClass==-1 || bug[idxClass]==classId) - ) { - count[bug[4]]++; - } - } - count[0] = count[1] + count[2] + count[3] + count[4]; - return count; - } - - function countFixedBugsInVersion(version) { - var count = [0,0,0,0,0]; - var last=1000000; - for (var x=0; x<fixedBugs.length-1; x++) { - var bug = fixedBugs[x]; - - var bugP = bug[4]; - - if ( version==-1 || version==(bug[6]+1)) { - count[bug[4]]++; - } - } - count[0] = count[1] + count[2] + count[3] + count[4]; - return count; - } - - function countFixedButActiveBugsVersion(version) { - var count = [0,0,0,0,0]; - var last=1000000; - for (var x=0; x<fixedBugs.length-1; x++) { - var bug = fixedBugs[x]; - - var bugP = bug[4]; - - if ( version==-1 || (version >=bug[5] && version<=bug[6]) ) { - count[bug[4]]++; - } - } - count[0] = count[1] + count[2] + count[3] + count[4]; - return count; - } - - function countTotalBugsVersion(version) { - var count = [0,0,0,0,0]; - var last=1000000; - for (var x=0; x<bugs.length-1; x++) { - var bug = bugs[x]; - - var bugP = bug[4]; - - if (version==-1 || version>=bug[5]) { - count[bug[4]]++; - } - } - count[0] = count[1] + count[2] + count[3] + count[4]; - return count; - } - - function getPriorityLegend() { - var content = ""; - content += "<h5><span class='b-1'> </span> P1 "; - content += "<span class='b-2'> </span> P2 "; - content += "<span class='b-3'> </span> P3 "; - content += "<span class='b-4'> </span> Exp "; - content += "</h5>"; - return content; - } - - function populatePackageNames() { - for (var i=0; i<bugs.length; i++) { - var classId = bugs[i][6]; - var idx = classId.lastIndexOf('.'); - var packageId = ""; - - if (idx>0) { - packageId = classId.substring(0, idx); - } - - bugs[i][7] = packageId; - } - } - - function showbug(bugId, containerId, patternId) { - var bugplaceholder = document.getElementById(containerId); - var bug = document.getElementById(bugId); - - if ( bugplaceholder==null) { - alert(buguid+'-ph-'+list+' - '+buguid+' - bugplaceholder==null'); - return; - } - if ( bug==null) { - alert(buguid+'-ph-'+list+' - '+buguid+' - bug==null'); - return; - } - - var newBug = bug.innerHTML; - var pattern = document.getElementById('tip-'+patternId).innerHTML; - toggle(containerId); - bugplaceholder.innerHTML = newBug + pattern; - } - function toggle(foo) { - if( document.getElementById(foo).style.display == "none") { - show(foo); - } else { - if( document.getElementById(foo).style.display == "block") { - hide(foo); - } else { - show(foo); - } - } - } - function show(foo) { - document.getElementById(foo).style.display="block"; - } - function hide(foo) { - document.getElementById(foo).style.display="none"; - } - - window.onload = function(){ - init(); - }; - ]]></xsl:text></script> - <script type='text/javascript'> - // versions fields: release id, release label - var versions = new Array( - <xsl:for-each select="/BugCollection/History/AppVersion"> - [ "<xsl:value-of select="@sequence" />", "<xsl:value-of select="@release" />" ], - </xsl:for-each> - [ "<xsl:value-of select="/BugCollection/@sequence" />", "<xsl:value-of select="/BugCollection/@release" />" ] - ); - - // categories fields: category id, category label - var categories = new Array( - <xsl:for-each select="/BugCollection/BugCategory"> - <xsl:sort select="@category" order="ascending" /> - [ "<xsl:value-of select="@category" />", "<xsl:value-of select="Description" />" ], - </xsl:for-each> - [ "", "" ] - ); - - // codes fields: code id, code label - var codes = new Array( - <xsl:for-each select="/BugCollection/BugCode"> - <xsl:sort select="@abbrev" order="ascending" /> - [ "<xsl:value-of select="@abbrev" />", "<xsl:value-of select="Description" />" ], - </xsl:for-each> - [ "", "" ] - ); - - // patterns fields: category id, code id, pattern id, pattern label - var patterns = new Array( - <xsl:for-each select="/BugCollection/BugPattern"> - <xsl:sort select="@type" order="ascending" /> - [ "<xsl:value-of select="@category" />", "<xsl:value-of select="@abbrev" />", "<xsl:value-of select="@type" />", "<xsl:value-of select="translate(ShortDescription, '"', $apos)" />" ], - - </xsl:for-each> - [ "", "", "", "" ] - ); - - // class stats fields: class name, package name, isInterface, total bugs, bugs p1, bugs p2, bugs p3, bugs p4 - var classStats = new Array( - <xsl:for-each select="/BugCollection/FindBugsSummary/PackageStats/ClassStats"> - <xsl:sort select="@class" order="ascending" /> - [ "<xsl:value-of select="@class" />", "<xsl:value-of select="../@package" />", "<xsl:value-of select="@interface" />", "<xsl:value-of select="@bugs" />", "<xsl:value-of select="@priority_1" />", "<xsl:value-of select="@priority_2" />", "<xsl:value-of select="@priority_3" />", "<xsl:value-of select="@priority_4" />" ], - </xsl:for-each> - [ "", "", "", "", "", "", "", "" ] - ); - - // package stats fields: package name, total bugs, bugs p1, bugs p2, bugs p3, bugs p4 - var packageStats = new Array( - <xsl:for-each select="/BugCollection/FindBugsSummary/PackageStats"> - <xsl:sort select="@package" order="ascending" /> - [ "<xsl:value-of select="@package" />", "<xsl:value-of select="@total_bugs" />", "<xsl:value-of select="@priority_1" />", "<xsl:value-of select="@priority_2" />", "<xsl:value-of select="@priority_3" />", "<xsl:value-of select="@priority_4" />" ], - </xsl:for-each> - [ "", "", "", "", "", "" ] - ); - - - // bugs fields: bug id, category id, code id, pattern id, priority, release id, class name, packagename (populated by javascript) - var bugs = new Array( - <xsl:for-each select="/BugCollection/BugInstance[string-length(@last)=0]"> - - [ "<xsl:value-of select="@instanceHash" />-<xsl:value-of select="@instanceOccurrenceNum" />", - "<xsl:value-of select="@category" />", - "<xsl:value-of select="@abbrev" />", - "<xsl:value-of select="@type" />", - <xsl:value-of select="@priority" />, - <xsl:choose><xsl:when test='string-length(@first)=0'>0</xsl:when><xsl:otherwise><xsl:value-of select="@first" /></xsl:otherwise></xsl:choose>, - "<xsl:value-of select="Class/@classname" />", - ""], - </xsl:for-each> - [ "", "", "", "", 0, 0, "", "" ] - ); - - // bugs fields: bug id, category id, code id, pattern id, priority, first release id, fixed release id, class name - var fixedBugs = new Array( - <xsl:for-each select="/BugCollection/BugInstance[string-length(@last)>0]"> - - [ "<xsl:value-of select="@instanceHash" />-<xsl:value-of select="@instanceOccurrenceNum" />", - "<xsl:value-of select="@category" />", - "<xsl:value-of select="@abbrev" />", - "<xsl:value-of select="@type" />", - <xsl:value-of select="@priority" />, - <xsl:choose><xsl:when test='string-length(@first)=0'>0</xsl:when><xsl:otherwise><xsl:value-of select="@first" /></xsl:otherwise></xsl:choose>, - <xsl:choose><xsl:when test='string-length(@last)>0'><xsl:value-of select="@last" /></xsl:when><xsl:otherwise>-42</xsl:otherwise></xsl:choose>, - "<xsl:value-of select="Class/@classname" />" ], - </xsl:for-each> - [ "", "", "", "", 0, 0, 0, "" ] - ); - - </script> - </head> - <body> - <h3> - <a href="http://findbugs.sourceforge.net">FindBugs</a> (<xsl:value-of select="/BugCollection/@version" />) - Analysis for - <xsl:choose> - <xsl:when test='string-length(/BugCollection/Project/@projectName)>0'><xsl:value-of select="/BugCollection/Project/@projectName" /></xsl:when> - <xsl:otherwise><xsl:value-of select="/BugCollection/Project/@filename" /></xsl:otherwise> - </xsl:choose> - </h3> - - <div id='menuWrapper' style=''> - <div id="navcontainer"> - <ul id="navlist"> - <li><a id='summary' class="current" href="#" onclick="selectMenu('summary'); return false;" >Summary</a></li> - <li><a id='history' class="none" href="#" onclick="selectMenu('history'); return false;" >History</a></li> - <li><a id='listByCategories' class="none" href="#" onclick="selectMenu('listByCategories'); return false;">Browse By Categories</a></li> - <li><a id='listByPackages' class="none" href="#" onclick="selectMenu('listByPackages'); return false;" >Browse by Packages</a></li> - <li><a id='info' class="none" href="#" onclick="selectMenu('info'); return false;" >Info</a></li> - </ul> - </div> - </div> - - <div id='displayWrapper'> - - <div style='height:25px;'> - <div id='messageContainer' style='float:right;'> - Computing data... - </div> - <div id='filterWrapper' style='display:none;'> - <form name='findbugsForm'> - <div id='filterContainer' > - <select name='versions' onchange='filter()'> - <option value="loading">Loading filter...</option> - </select> - <select name='priorities' onchange='filter()'> - <option value="loading">Loading filter...</option> - </select> - </div> - </form> - </div> - </div> - <div id='summaryContainer' class='displayContainer'> - <h3>Package Summary</h3> - <table> - <tr> - <th>Package</th> - <th>Code Size</th> - <th>Bugs</th> - <th>Bugs p1</th> - <th>Bugs p2</th> - <th>Bugs p3</th> - <th>Bugs Exp.</th> - </tr> - <tr> - <td class='summary-name'> - Overall - (<xsl:value-of select="/BugCollection/FindBugsSummary/@num_packages" /> packages), - (<xsl:value-of select="/BugCollection/FindBugsSummary/@total_classes" /> classes) - </td> - <td class='summary-size'><xsl:value-of select="/BugCollection/FindBugsSummary/@total_size" /></td> - <td class='summary-priority-all'><xsl:value-of select="/BugCollection/FindBugsSummary/@total_bugs" /></td> - <td class='summary-priority-1'><xsl:value-of select="/BugCollection/FindBugsSummary/@priority_1" /></td> - <td class='summary-priority-2'><xsl:value-of select="/BugCollection/FindBugsSummary/@priority_2" /></td> - <td class='summary-priority-3'><xsl:value-of select="/BugCollection/FindBugsSummary/@priority_3" /></td> - <td class='summary-priority-4'><xsl:value-of select="/BugCollection/FindBugsSummary/@priority_4" /></td> - </tr> - <xsl:for-each select="/BugCollection/FindBugsSummary/PackageStats"> - <xsl:sort select="@package" order="ascending" /> - <xsl:if test="@total_bugs!='0'" > - <tr> - <td class='summary-name'><xsl:value-of select="@package" /></td> - <td class='summary-size'><xsl:value-of select="@total_size" /></td> - <td class='summary-priority-all'><xsl:value-of select="@total_bugs" /></td> - <td class='summary-priority-1'><xsl:value-of select="@priority_1" /></td> - <td class='summary-priority-2'><xsl:value-of select="@priority_2" /></td> - <td class='summary-priority-3'><xsl:value-of select="@priority_3" /></td> - <td class='summary-priority-4'><xsl:value-of select="@priority_4" /></td> - </tr> - </xsl:if> - </xsl:for-each> - </table> - </div> - - <div id='infoContainer' class='displayContainer'> - <div id='analyzed-files'> - <h3>Analyzed Files:</h3> - <ul> - <xsl:for-each select="/BugCollection/Project/Jar"> - <li><xsl:apply-templates /></li> - </xsl:for-each> - </ul> - </div> - <div id='used-libraries'> - <h3>Used Libraries:</h3> - <ul> - <xsl:for-each select="/BugCollection/Project/AuxClasspathEntry"> - <li><xsl:apply-templates /></li> - </xsl:for-each> - <xsl:if test="count(/BugCollection/Project/AuxClasspathEntry)=0" > - <li>None</li> - </xsl:if> - </ul> - </div> - <div id='analysis-error'> - <h3>Analysis Errors:</h3> - <ul> - <xsl:variable name="error-count" - select="count(/BugCollection/Errors/MissingClass)" /> - <xsl:if test="$error-count=0" > - <li>None</li> - </xsl:if> - <xsl:if test="$error-count>0" > - <li>Missing ref classes for analysis: - <ul> - <xsl:for-each select="/BugCollection/Errors/MissingClass"> - <li><xsl:apply-templates /></li> - </xsl:for-each> - </ul> - </li> - </xsl:if> - </ul> - </div> - </div> - <div id='historyContainer' class='displayContainer'>Loading...</div> - <div id='listByCategoriesContainer' class='displayContainer'>Loading...</div> - <div id='listByPackagesContainer' class='displayContainer'>Loading...</div> - </div> - - <div id='bug-collection' style='display:none;'> - <!-- advanced tooltips --> - <xsl:for-each select="/BugCollection/BugPattern"> - <xsl:variable name="b-t"><xsl:value-of select="@type" /></xsl:variable> - <div> - <xsl:attribute name="id">tip-<xsl:value-of select="$b-t" /></xsl:attribute> - <xsl:attribute name="class">tip</xsl:attribute> - <xsl:value-of select="/BugCollection/BugPattern[@type=$b-t]/Details" disable-output-escaping="yes" /> - </div> - </xsl:for-each> - - <!-- bug descriptions - hidden --> - <xsl:for-each select="/BugCollection/BugInstance[not(@last)]"> - <div style="display:none;" class='bug'> - <xsl:attribute name="id">b-uid-<xsl:value-of select="@instanceHash" />-<xsl:value-of select="@instanceOccurrenceNum" /></xsl:attribute> - <xsl:for-each select="*/Message"> - <div class="b-r"><xsl:apply-templates /></div> - </xsl:for-each> - <div class="b-d"> - <xsl:value-of select="LongMessage" disable-output-escaping="no" /> - </div> - </div> - </xsl:for-each> - </div> - </body> -</html> -</xsl:template> - - -</xsl:transform> - diff --git a/lib/findbugs/xsl/fancy.xsl b/lib/findbugs/xsl/fancy.xsl deleted file mode 100644 index 5d152dd..0000000 --- a/lib/findbugs/xsl/fancy.xsl +++ /dev/null @@ -1,846 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!-- - Copyright (C) 2005, 2006 Etienne Giraudy, InStranet Inc - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---> - -<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" > - <xsl:output - method="xml" indent="yes" - doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" - doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" - encoding="UTF-8"/> - - <!-- - Parameter for specifying HTMLized sources location; if current dir, use "./" - If not passed, no links to sources are generated. - because of back-compatibility reasons. - The source filename should be package.class.java.html - The source can have line no anchors like #11 --> - <xsl:param name="htmlsrcpath"></xsl:param> - - <!--xsl:key name="lbc-category-key" match="/BugCollection/BugInstance" use="@category" /--> - <xsl:key name="lbc-code-key" match="/BugCollection/BugInstance" use="concat(@category,@abbrev)" /> - <xsl:key name="lbc-bug-key" match="/BugCollection/BugInstance" use="concat(@category,@abbrev,@type)" /> - <xsl:key name="lbp-class-b-t" match="/BugCollection/BugInstance" use="concat(Class/@classname,@type)" /> - -<xsl:template match="/" > - -<html> - <head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> - <title> - FindBugs (<xsl:value-of select="/BugCollection/@version" />) - Analysis for - <xsl:choose> - <xsl:when test='string-length(/BugCollection/Project/@projectName)>0'><xsl:value-of select="/BugCollection/Project/@projectName" /></xsl:when> - <xsl:otherwise><xsl:value-of select="/BugCollection/Project/@filename" /></xsl:otherwise> - </xsl:choose> - </title> - <script type="text/javascript"> - function show(foo) { - document.getElementById(foo).style.display="block"; - } - function hide(foo) { - document.getElementById(foo).style.display="none"; - } - function toggle(foo) { - if( document.getElementById(foo).style.display == "none") { - show(foo); - } else { - if( document.getElementById(foo).style.display == "block") { - hide(foo); - } else { - show(foo); - } - } - } - - function showmenu(foo) { - if( document.getElementById(foo).style.display == "none") { - hide("bug-summary"); - document.getElementById("bug-summary-tab").className="menu-tab"; - hide("analysis-data"); - document.getElementById("analysis-data-tab").className="menu-tab"; - //hide("list-by-b-t"); - //document.getElementById("list-by-b-t-tab").className="menu-tab"; - hide("list-by-package"); - document.getElementById("list-by-package-tab").className="menu-tab"; - hide("list-by-category"); - document.getElementById("list-by-category-tab").className="menu-tab"; - document.getElementById(foo+"-tab").className="menu-tab-selected"; - show(foo); - - } - // else menu already selected! - } - function showbug(buguid, list) { - var bugplaceholder = document.getElementById(buguid+'-ph-'+list); - var bug = document.getElementById(buguid); - - if ( bugplaceholder==null) { - alert(buguid+'-ph-'+list+' - '+buguid+' - bugplaceholder==null'); - return; - } - if ( bug==null) { - alert(buguid+'-ph-'+list+' - '+buguid+' - bug==null'); - return; - } - - var oldBug = bugplaceholder.innerHTML; - var newBug = bug.innerHTML; - //alert(oldBug); - //alert(newBug); - toggle(buguid+'-ph-'+list); - bugplaceholder.innerHTML = newBug; - } - </script> - <script type='text/javascript'><xsl:text disable-output-escaping='yes'><![CDATA[ - // Extended Tooltip Javascript - // copyright 9th August 2002, 3rd July 2005 - // by Stephen Chapman, Felgall Pty Ltd - - // permission is granted to use this javascript provided that the below code is not altered - var DH = 0;var an = 0;var al = 0;var ai = 0;if (document.getElementById) {ai = 1; DH = 1;}else {if (document.all) {al = 1; DH = 1;} else { browserVersion = parseInt(navigator.appVersion); if (navigator.appName.indexOf('Netscape') != -1) if (browserVersion == 4) {an = 1; DH = 1;}}} - function fd(oi, wS) {if (ai) return wS ? document.getElementById(oi).style:document.getElementById(oi); if (al) return wS ? document.all[oi].style: document.all[oi]; if (an) return document.layers[oi];} - function pw() {return window.innerWidth != null? window.innerWidth: document.body.clientWidth != null? document.body.clientWidth:null;} - function mouseX(evt) {if (evt.pageX) return evt.pageX; else if (evt.clientX)return evt.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft); else return null;} - function mouseY(evt) {if (evt.pageY) return evt.pageY; else if (evt.clientY)return evt.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop); else return null;} - function popUp(evt,oi) {if (DH) {var wp = pw(); ds = fd(oi,1); dm = fd(oi,0); st = ds.visibility; if (dm.offsetWidth) ew = dm.offsetWidth; else if (dm.clip.width) ew = dm.clip.width; if (st == "visible" || st == "show") { ds.visibility = "hidden"; } else {tv = mouseY(evt) + 20; lv = mouseX(evt) - (ew/4); if (lv < 2) lv = 2; else if (lv + ew > wp) lv -= ew/2; if (!an) {lv += 'px';tv += 'px';} ds.left = lv; ds.top = tv; ds.visibility = "visible";}}} - ]]></xsl:text></script> - <style type='text/css'> - html, body { - background-color: #ffffff; - } - a, a:link , a:active, a:visited, a:hover { - text-decoration: none; color: black; - } - .b-r a { - text-decoration: underline; color: blue; - } - div, span { - vertical-align: top; - } - p { - margin: 0px; - } - h1 { - /*font-size: 14pt;*/ - color: red; - } - #menu { - margin-bottom: 10px; - } - #menu ul { - margin-left: 0; - padding-left: 0; - display: inline; - } - #menu ul li { - margin-left: 0; - margin-bottom: 0; - padding: 2px 15px 5px; - border: 1px solid #000; - list-style: none; - display: inline; - } - #menu ul li.here { - border-bottom: 1px solid #ffc; - list-style: none; - display: inline; - } - .menu-tab { - background: white; - } - .menu-tab:hover { - background: grey; - } - .menu-tab-selected { - background: #aaaaaa; - } - #analysis-data ul { - margin-left: 15px; - } - #analyzed-files, #used-libraries, #analysis-error { - margin: 2px; - border: 1px black solid; - padding: 2px; - float: left; - overflow:auto; - } - #analyzed-files { - width: 25%; - } - #used-libraries { - width: 25%; - } - #analysis-error { - width: 40%; - } - div.summary { - width:100%; - text-align:left; - } - .summary table { - border:1px solid black; - } - .summary th { - background: #aaaaaa; - color: white; - } - .summary th, .summary td { - padding: 2px 4px 2px 4px; - } - .summary-name { - background: #eeeeee; - text-align:left; - } - .summary-size { - background: #eeeeee; - text-align:center; - } - .summary-ratio { - background: #eeeeee; - text-align:center; - } - .summary-priority-all { - background: #dddddd; - text-align:center; - } - .summary-priority-1 { - background: red; - text-align:center; - } - .summary-priority-2 { - background: orange; - text-align:center; - } - .summary-priority-3 { - background: green; - text-align:center; - } - .summary-priority-4 { - background: blue; - text-align:center; - } - .ob { - border: 1px solid black; - margin: 10px; - } - .ob-t { - border-bottom: 1px solid #000000; font-size: 12pt; font-weight: bold; - background: #cccccc; margin: 0; padding: 0 5px 0 5px; - } - .t-h { - font-weight: normal; - } - .ib-1, .ib-2 { - margin: 0 0 0 10px; - } - .ib-1-t, .ib-2-t { - border-bottom: 1px solid #000000; border-left: 1px solid #000000; - margin: 0; padding: 0 5px 0 5px; - font-size: 12pt; font-weight: bold; background: #cccccc; - } - .bb { - border-bottom: 1px solid #000000; border-left: 1px solid #000000; - } - .b-1 { - background: red; height: 0.5em; width: 1em; - margin-right: 0.5em; - } - .b-2 { - background: orange; height: 0.5em; width: 1em; - margin-right: 0.5em; - } - .b-3 { - background: green; height: 0.5em; width: 1em; - margin-right: 0.5em; - } - .b-4 { - background: blue; height: 0.5em; width: 1em; - margin-right: 0.5em; - } - .b-t { - } - .b-r { - font-size: 10pt; font-weight: bold; padding: 0 0 0 60px; - } - .b-d { - font-weight: normal; background: #eeeee0; - padding: 0 5px 0 5px; margin: 0px; - } - .bug-placeholder { - top:140px; - border:1px solid black; - display:none; - } - .tip { - border:solid 1px #666666; - width:600px; - padding:3px; - position:absolute; - z-index:100; - visibility:hidden; - color:#333333; - top:20px; - left:90px; - background-color:#ffffcc; - layer-background-color:#ffffcc; - } - - - </style> - </head> - <body> - <div id='content'> - <h1> - FindBugs (<xsl:value-of select="/BugCollection/@version" />) - Analysis for - <xsl:choose> - <xsl:when test='string-length(/BugCollection/Project/@projectName)>0'><xsl:value-of select="/BugCollection/Project/@projectName" /></xsl:when> - <xsl:otherwise><xsl:value-of select="/BugCollection/Project/@filename" /></xsl:otherwise> - </xsl:choose> - </h1> - <div id="menu"> - <ul> - <li id='bug-summary-tab' class='menu-tab-selected'> - <xsl:attribute name="onclick">showmenu('bug-summary');return false;</xsl:attribute> - <a href='' onclick='return false;'>Bug Summary</a> - </li> - <li id='analysis-data-tab' class='menu-tab'> - <xsl:attribute name="onclick">showmenu('analysis-data');return false;</xsl:attribute> - <a href='' onclick='return false;'>Analysis Information</a> - </li> - <li id='list-by-category-tab' class='menu-tab'> - <xsl:attribute name="onclick">showmenu('list-by-category');return false;</xsl:attribute> - <a href='' onclick='return false;'>List bugs by bug category</a> - </li> - <li id='list-by-package-tab' class='menu-tab'> - <xsl:attribute name="onclick">showmenu('list-by-package');return false;</xsl:attribute> - <a href='' onclick='return false;'>List bugs by package</a> - </li> - </ul> - </div> - <xsl:call-template name="generateSummary" /> - <xsl:call-template name="analysis-data" /> - <xsl:call-template name="list-by-category" /> - <xsl:call-template name="list-by-package" /> - - - <!-- advanced tooltips --> - <xsl:for-each select="/BugCollection/BugPattern"> - <xsl:variable name="b-t"><xsl:value-of select="@type" /></xsl:variable> - <div> - <xsl:attribute name="id">tip-<xsl:value-of select="$b-t" /></xsl:attribute> - <xsl:attribute name="class">tip</xsl:attribute> - <b><xsl:value-of select="@abbrev" /> / <xsl:value-of select="@type" /></b><br/> - <xsl:value-of select="/BugCollection/BugPattern[@type=$b-t]/Details" disable-output-escaping="yes" /> - </div> - </xsl:for-each> - - <!-- bug descriptions - hidden --> - <xsl:for-each select="/BugCollection/BugInstance[not(@last)]"> - <div style="display:none;"> - <xsl:attribute name="id">b-uid-<xsl:value-of select="@instanceHash" />-<xsl:value-of select="@instanceOccurrenceNum" /></xsl:attribute> - <xsl:for-each select="*/Message"> - <xsl:choose> - <xsl:when test="parent::SourceLine and $htmlsrcpath != '' "> - <div class="b-r"><a> - <xsl:attribute name="href"><xsl:value-of select="$htmlsrcpath"/><xsl:value-of select="../@sourcepath" />.html#<xsl:value-of select="../@start" /></xsl:attribute> - <xsl:apply-templates /> - </a></div> - </xsl:when> - <xsl:otherwise> - <div class="b-r"><xsl:apply-templates /></div> - </xsl:otherwise> - </xsl:choose> - </xsl:for-each> - <div class="b-d"> - <xsl:value-of select="LongMessage" disable-output-escaping="no" /> - </div> - </div> - </xsl:for-each> - </div> - <div id='fixedbox'> - <div id='bug-placeholder'></div> - </div> - </body> -</html> -</xsl:template> - -<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> -<!-- generate summary report from stats --> -<xsl:template name="generateSummary" > -<div class='summary' id='bug-summary'> - <h2>FindBugs Analysis generated at: <xsl:value-of select="/BugCollection/FindBugsSummary/@timestamp" /></h2> - <table> - <tr> - <th>Package</th> - <th>Code Size</th> - <th>Bugs</th> - <th>Bugs p1</th> - <th>Bugs p2</th> - <th>Bugs p3</th> - <th>Bugs Exp.</th> - <th>Ratio</th> - </tr> - <tr> - <td class='summary-name'> - Overall - (<xsl:value-of select="/BugCollection/FindBugsSummary/@num_packages" /> packages), - (<xsl:value-of select="/BugCollection/FindBugsSummary/@total_classes" /> classes) - </td> - <td class='summary-size'><xsl:value-of select="/BugCollection/FindBugsSummary/@total_size" /></td> - <td class='summary-priority-all'><xsl:value-of select="/BugCollection/FindBugsSummary/@total_bugs" /></td> - <td class='summary-priority-1'><xsl:value-of select="/BugCollection/FindBugsSummary/@priority_1" /></td> - <td class='summary-priority-2'><xsl:value-of select="/BugCollection/FindBugsSummary/@priority_2" /></td> - <td class='summary-priority-3'><xsl:value-of select="/BugCollection/FindBugsSummary/@priority_3" /></td> - <td class='summary-priority-4'><xsl:value-of select="/BugCollection/FindBugsSummary/@priority_4" /></td> - <td class='summary-ratio'></td> - </tr> - <xsl:for-each select="/BugCollection/FindBugsSummary/PackageStats"> - <xsl:sort select="@package" /> - <xsl:if test="@total_bugs!='0'" > - <tr> - <td class='summary-name'><xsl:value-of select="@package" /></td> - <td class='summary-size'><xsl:value-of select="@total_size" /></td> - <td class='summary-priority-all'><xsl:value-of select="@total_bugs" /></td> - <td class='summary-priority-1'><xsl:value-of select="@priority_1" /></td> - <td class='summary-priority-2'><xsl:value-of select="@priority_2" /></td> - <td class='summary-priority-3'><xsl:value-of select="@priority_3" /></td> - <td class='summary-priority-4'><xsl:value-of select="@priority_4" /></td> - <td class='summary-ratio'></td> -<!-- - <xsl:for-each select="ClassStats"> - <xsl:if test="@bugs!='0'" > - <li> - <xsl:value-of select="@class" /> - total: <xsl:value-of select="@bugs" /> - </li> - </xsl:if> - </xsl:for-each> ---> - </tr> - </xsl:if> - </xsl:for-each> - </table> -</div> -</xsl:template> - -<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> -<!-- display analysis info --> -<xsl:template name="analysis-data"> - <div id='analysis-data' style='display:none;'> - <div id='analyzed-files'> - <h3>Analyzed Files:</h3> - <ul> - <xsl:for-each select="/BugCollection/Project/Jar"> - <li><xsl:apply-templates /></li> - </xsl:for-each> - </ul> - </div> - <div id='used-libraries'> - <h3>Used Libraries:</h3> - <ul> - <xsl:for-each select="/BugCollection/Project/AuxClasspathEntry"> - <li><xsl:apply-templates /></li> - </xsl:for-each> - <xsl:if test="count(/BugCollection/Project/AuxClasspathEntry)=0" > - <li>None</li> - </xsl:if> - </ul> - </div> - <div id='analysis-error'> - <h3>Analysis Errors:</h3> - <ul> - <xsl:variable name="error-count" - select="count(/BugCollection/Errors/MissingClass)" /> - <xsl:if test="$error-count=0" > - <li>None</li> - </xsl:if> - <xsl:if test="$error-count>0" > - <li>Missing ref classes for analysis: - <ul> - <xsl:for-each select="/BugCollection/Errors/MissingClass"> - <li><xsl:apply-templates /></li> - </xsl:for-each> - </ul> - </li> - </xsl:if> - </ul> - </div> - </div> -</xsl:template> - -<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> -<!-- show priorities helper --> -<xsl:template name="helpPriorities"> - <span> - <xsl:attribute name="class">b-1</xsl:attribute> -    - </span> P1 - <span> - <xsl:attribute name="class">b-2</xsl:attribute> -    - </span> P2 - <span> - <xsl:attribute name="class">b-3</xsl:attribute> -    - </span> P3 - <span> - <xsl:attribute name="class">b-4</xsl:attribute> -    - </span> Exp. -</xsl:template> - -<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> -<!-- display the details of a bug --> -<xsl:template name="display-bug" > - <xsl:param name="b-t" select="''" /> - <xsl:param name="bug-id" select="''" /> - <xsl:param name="which-list" select="''" /> - <div class="bb"> - <a> - <xsl:attribute name="href"></xsl:attribute> - <xsl:attribute name="onclick">showbug('b-uid-<xsl:value-of select="@instanceHash" />-<xsl:value-of select="@instanceOccurrenceNum" />','<xsl:value-of select="$which-list" />');return false;</xsl:attribute> - <span> - <xsl:attribute name="class">b-<xsl:value-of select="@priority"/></xsl:attribute> -    - </span> - <span class="b-t"><xsl:value-of select="@abbrev" />: </span> <xsl:value-of select="Class/Message" /> - </a> - <div style="display:none;"> - <xsl:attribute name="id">b-uid-<xsl:value-of select="@instanceHash" />-<xsl:value-of select="@instanceOccurrenceNum" />-ph-<xsl:value-of select="$which-list" /></xsl:attribute> - loading... - </div> - </div> -</xsl:template> - -<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> -<!-- main template for the list by category --> -<xsl:template name="list-by-category" > - <div id='list-by-category' class='data-box' style='display:none;'> - <xsl:call-template name="helpPriorities" /> - <xsl:variable name="unique-category" select="/BugCollection/BugCategory/@category"/> - <xsl:for-each select="$unique-category"> - <xsl:sort select="." order="ascending" /> - <xsl:call-template name="categories"> - <xsl:with-param name="category" select="." /> - </xsl:call-template> - </xsl:for-each> - </div> -</xsl:template> - -<xsl:template name="categories" > - <xsl:param name="category" select="''" /> - <xsl:variable name="category-count" - select="count(/BugCollection/BugInstance[@category=$category and not(@last)])" /> - <xsl:variable name="category-count-p1" - select="count(/BugCollection/BugInstance[@category=$category and @priority='1' and not(@last)])" /> - <xsl:variable name="category-count-p2" - select="count(/BugCollection/BugInstance[@category=$category and @priority='2' and not(@last)])" /> - <xsl:variable name="category-count-p3" - select="count(/BugCollection/BugInstance[@category=$category and @priority='3' and not(@last)])" /> - <xsl:variable name="category-count-p4" - select="count(/BugCollection/BugInstance[@category=$category and @priority='4' and not(@last)])" /> - <div class='ob'> - <div class='ob-t'> - <a> - <xsl:attribute name="href"></xsl:attribute> - <xsl:attribute name="onclick">toggle('category-<xsl:value-of select="$category" />');return false;</xsl:attribute> - <xsl:value-of select="/BugCollection/BugCategory[@category=$category]/Description" /> - (<xsl:value-of select="$category-count" />: - <span class='t-h'><xsl:value-of select="$category-count-p1" />/<xsl:value-of select="$category-count-p2" />/<xsl:value-of select="$category-count-p3" />/<xsl:value-of select="$category-count-p4" /></span>) - </a> - </div> - <div style="display:none;"> - <xsl:attribute name="id">category-<xsl:value-of select="$category" /></xsl:attribute> - <xsl:call-template name="list-by-category-and-code"> - <xsl:with-param name="category" select="$category" /> - </xsl:call-template> - </div> - </div> -</xsl:template> - -<xsl:template name="list-by-category-and-code" > - <xsl:param name="category" select="''" /> - <xsl:variable name="unique-code" select="/BugCollection/BugInstance[@category=$category and not(@last) and generate-id()= generate-id(key('lbc-code-key',concat(@category,@abbrev)))]/@abbrev" /> - <xsl:for-each select="$unique-code"> - <xsl:sort select="." order="ascending" /> - <xsl:call-template name="codes"> - <xsl:with-param name="category" select="$category" /> - <xsl:with-param name="code" select="." /> - </xsl:call-template> - </xsl:for-each> -</xsl:template> - -<xsl:template name="codes" > - <xsl:param name="category" select="''" /> - <xsl:param name="code" select="''" /> - <xsl:variable name="code-count" - select="count(/BugCollection/BugInstance[@category=$category and @abbrev=$code and not(@last)])" /> - <xsl:variable name="code-count-p1" - select="count(/BugCollection/BugInstance[@category=$category and @abbrev=$code and @priority='1' and not(@last)])" /> - <xsl:variable name="code-count-p2" - select="count(/BugCollection/BugInstance[@category=$category and @abbrev=$code and @priority='2' and not(@last)])" /> - <xsl:variable name="code-count-p3" - select="count(/BugCollection/BugInstance[@category=$category and @abbrev=$code and @priority='3' and not(@last)])" /> - <xsl:variable name="code-count-p4" - select="count(/BugCollection/BugInstance[@category=$category and @abbrev=$code and @priority='4' and not(@last)])" /> - <div class='ib-1'> - <div class="ib-1-t"> - <a> - <xsl:attribute name="href"></xsl:attribute> - <xsl:attribute name="onclick">toggle('category-<xsl:value-of select="$category" />-and-code-<xsl:value-of select="$code" />');return false;</xsl:attribute> - <xsl:value-of select="$code" />: <xsl:value-of select="/BugCollection/BugCode[@abbrev=$code]/Description" /> - (<xsl:value-of select="$code-count" />: - <span class='t-h'><xsl:value-of select="$code-count-p1" />/<xsl:value-of select="$code-count-p2" />/<xsl:value-of select="$code-count-p3" />/<xsl:value-of select="$code-count-p4" /></span>) - </a> - </div> - <div style="display:none;"> - <xsl:attribute name="id">category-<xsl:value-of select="$category" />-and-code-<xsl:value-of select="$code" /></xsl:attribute> - <xsl:call-template name="list-by-category-and-code-and-bug"> - <xsl:with-param name="category" select="$category" /> - <xsl:with-param name="code" select="$code" /> - </xsl:call-template> - </div> - </div> -</xsl:template> - -<xsl:template name="list-by-category-and-code-and-bug" > - <xsl:param name="category" select="''" /> - <xsl:param name="code" select="''" /> - <xsl:variable name="unique-bug" select="/BugCollection/BugInstance[@category=$category and not(@last) and @abbrev=$code and generate-id()= generate-id(key('lbc-bug-key',concat(@category,@abbrev,@type)))]/@type" /> - <xsl:for-each select="$unique-bug"> - <xsl:sort select="." order="ascending" /> - <xsl:call-template name="bugs"> - <xsl:with-param name="category" select="$category" /> - <xsl:with-param name="code" select="$code" /> - <xsl:with-param name="bug" select="." /> - </xsl:call-template> - </xsl:for-each> -</xsl:template> - -<xsl:template name="bugs" > - <xsl:param name="category" select="''" /> - <xsl:param name="code" select="''" /> - <xsl:param name="bug" select="''" /> - <xsl:variable name="bug-count" - select="count(/BugCollection/BugInstance[@category=$category and @abbrev=$code and @type=$bug and not(@last)])" /> - <xsl:variable name="bug-count-p1" - select="count(/BugCollection/BugInstance[@category=$category and @abbrev=$code and @type=$bug and @priority='1' and not(@last)])" /> - <xsl:variable name="bug-count-p2" - select="count(/BugCollection/BugInstance[@category=$category and @abbrev=$code and @type=$bug and @priority='2' and not(@last)])" /> - <xsl:variable name="bug-count-p3" - select="count(/BugCollection/BugInstance[@category=$category and @abbrev=$code and @type=$bug and @priority='3' and not(@last)])" /> - <xsl:variable name="bug-count-p4" - select="count(/BugCollection/BugInstance[@category=$category and @abbrev=$code and @type=$bug and @priority='4' and not(@last)])" /> - <div class='ib-2'> - <div class='ib-2-t'> - <a> - <xsl:attribute name="href"></xsl:attribute> - <xsl:attribute name="onclick">toggle('category-<xsl:value-of select="$category" />-and-code-<xsl:value-of select="$code" />-and-bug-<xsl:value-of select="$bug" />');return false;</xsl:attribute> - <xsl:attribute name="onmouseout">popUp(event,'tip-<xsl:value-of select="$bug" />');</xsl:attribute> - <xsl:attribute name="onmouseover">popUp(event,'tip-<xsl:value-of select="$bug" />');</xsl:attribute> - <xsl:value-of select="/BugCollection/BugPattern[@category=$category and @abbrev=$code and @type=$bug]/ShortDescription" />   - (<xsl:value-of select="$bug-count" />: - <span class='t-h'><xsl:value-of select="$bug-count-p1" />/<xsl:value-of select="$bug-count-p2" />/<xsl:value-of select="$bug-count-p3" />/<xsl:value-of select="$bug-count-p4" /></span>) - </a> - </div> - <div style="display:none;"> - <xsl:attribute name="id">category-<xsl:value-of select="$category" />-and-code-<xsl:value-of select="$code" />-and-bug-<xsl:value-of select="$bug" /></xsl:attribute> - <xsl:variable name="cat-code-type">category-<xsl:value-of select="$category" />-and-code-<xsl:value-of select="$code" />-and-bug-<xsl:value-of select="$bug" /></xsl:variable> - <xsl:variable name="bug-id">b-uid-<xsl:value-of select="@instanceHash" />-<xsl:value-of select="@instanceOccurrenceNum" /></xsl:variable> - <xsl:for-each select="/BugCollection/BugInstance[@category=$category and @abbrev=$code and @type=$bug and not(@last)]"> - <xsl:call-template name="display-bug"> - <xsl:with-param name="b-t" select="@type" /> - <xsl:with-param name="bug-id" select="$bug-id" /> - <xsl:with-param name="which-list" select="'c'" /> - </xsl:call-template> - </xsl:for-each> - </div> - </div> -</xsl:template> - -<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> -<!-- main template for the list by package --> -<xsl:template name="list-by-package" > - <div id='list-by-package' class='data-box' style='display:none;'> - <xsl:call-template name="helpPriorities" /> - <xsl:for-each select="/BugCollection/FindBugsSummary/PackageStats[@total_bugs != '0']/@package"> - <xsl:sort select="." order="ascending" /> - <xsl:call-template name="packages"> - <xsl:with-param name="package" select="." /> - </xsl:call-template> - </xsl:for-each> - </div> -</xsl:template> - -<xsl:template name="packages" > - <xsl:param name="package" select="''" /> - <xsl:variable name="package-count-p1"> - <xsl:if test="not(/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_1 != '')">0</xsl:if> - <xsl:if test="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_1 != ''"> - <xsl:value-of select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_1" /> - </xsl:if> - </xsl:variable> - <xsl:variable name="package-count-p2"> - <xsl:if test="not(/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_2 != '')">0</xsl:if> - <xsl:if test="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_2 != ''"> - <xsl:value-of select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_2" /> - </xsl:if> - </xsl:variable> - <xsl:variable name="package-count-p3"> - <xsl:if test="not(/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_3 != '')">0</xsl:if> - <xsl:if test="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_3 != ''"> - <xsl:value-of select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_3" /> - </xsl:if> - </xsl:variable> - <xsl:variable name="package-count-p4"> - <xsl:if test="not(/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_4 != '')">0</xsl:if> - <xsl:if test="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_4 != ''"> - <xsl:value-of select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_4" /> - </xsl:if> - </xsl:variable> - - <div class='ob'> - <div class='ob-t'> - <a> - <xsl:attribute name="href"></xsl:attribute> - <xsl:attribute name="onclick">toggle('package-<xsl:value-of select="$package" />');return false;</xsl:attribute> - <xsl:value-of select="$package" /> - (<xsl:value-of select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@total_bugs" />: - <span class='t-h'><xsl:value-of select="$package-count-p1" />/<xsl:value-of select="$package-count-p2" />/<xsl:value-of select="$package-count-p3" />/<xsl:value-of select="$package-count-p4" /></span>) - </a> - </div> - <div style="display:none;"> - <xsl:attribute name="id">package-<xsl:value-of select="$package" /></xsl:attribute> - <xsl:call-template name="list-by-package-and-class"> - <xsl:with-param name="package" select="$package" /> - </xsl:call-template> - </div> - </div> -</xsl:template> - -<xsl:template name="list-by-package-and-class" > - <xsl:param name="package" select="''" /> - <xsl:for-each select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@bugs != '0']/@class"> - <xsl:sort select="." order="ascending" /> - <xsl:call-template name="classes"> - <xsl:with-param name="package" select="$package" /> - <xsl:with-param name="class" select="." /> - </xsl:call-template> - </xsl:for-each> -</xsl:template> - -<xsl:template name="classes" > - <xsl:param name="package" select="''" /> - <xsl:param name="class" select="''" /> - <xsl:variable name="class-count" - select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@bugs" /> - - <xsl:variable name="class-count-p1"> - <xsl:if test="not(/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_1 != '')">0</xsl:if> - <xsl:if test="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_1 != ''"> - <xsl:value-of select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_1" /> - </xsl:if> - </xsl:variable> - <xsl:variable name="class-count-p2"> - <xsl:if test="not(/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_2 != '')">0</xsl:if> - <xsl:if test="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_2 != ''"> - <xsl:value-of select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_2" /> - </xsl:if> - </xsl:variable> - <xsl:variable name="class-count-p3"> - <xsl:if test="not(/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_3 != '')">0</xsl:if> - <xsl:if test="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_3 != ''"> - <xsl:value-of select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_3" /> - </xsl:if> - </xsl:variable> - <xsl:variable name="class-count-p4"> - <xsl:if test="not(/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_4 != '')">0</xsl:if> - <xsl:if test="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_4 != ''"> - <xsl:value-of select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_4" /> - </xsl:if> - </xsl:variable> - - <div class='ib-1'> - <div class="ib-1-t"> - <a> - <xsl:attribute name="href"></xsl:attribute> - <xsl:attribute name="onclick">toggle('package-<xsl:value-of select="$package" />-and-class-<xsl:value-of select="$class" />');return false;</xsl:attribute> - <xsl:value-of select="$class" /> (<xsl:value-of select="$class-count" />: - <span class='t-h'><xsl:value-of select="$class-count-p1" />/<xsl:value-of select="$class-count-p2" />/<xsl:value-of select="$class-count-p3" />/<xsl:value-of select="$class-count-p4" /></span>) - </a> - </div> - <div style="display:none;"> - <xsl:attribute name="id">package-<xsl:value-of select="$package" />-and-class-<xsl:value-of select="$class" /></xsl:attribute> - <xsl:call-template name="list-by-package-and-class-and-bug"> - <xsl:with-param name="package" select="$package" /> - <xsl:with-param name="class" select="$class" /> - </xsl:call-template> - </div> - </div> -</xsl:template> - -<xsl:template name="list-by-package-and-class-and-bug" > - <xsl:param name="package" select="''" /> - <xsl:param name="class" select="''" /> - <xsl:variable name="unique-class-bugs" select="/BugCollection/BugInstance[not(@last) and Class[position()=1 and @classname=$class] and generate-id() = generate-id(key('lbp-class-b-t',concat(Class/@classname,@type)))]/@type" /> - - <xsl:for-each select="$unique-class-bugs"> - <xsl:sort select="." order="ascending" /> - <xsl:call-template name="class-bugs"> - <xsl:with-param name="package" select="$package" /> - <xsl:with-param name="class" select="$class" /> - <xsl:with-param name="type" select="." /> - </xsl:call-template> - </xsl:for-each> -</xsl:template> - -<xsl:template name="class-bugs" > - <xsl:param name="package" select="''" /> - <xsl:param name="class" select="''" /> - <xsl:param name="type" select="''" /> - <xsl:variable name="bug-count" - select="count(/BugCollection/BugInstance[@type=$type and not(@last) and Class[position()=1 and @classname=$class]])" /> - <div class='ib-2'> - <div class='ib-2-t'> - <a> - <xsl:attribute name="href"></xsl:attribute> - <xsl:attribute name="onclick">toggle('package-<xsl:value-of select="$package" />-and-class-<xsl:value-of select="$class" />-and-type-<xsl:value-of select="$type" />');return false;</xsl:attribute> - <xsl:attribute name="onmouseout">popUp(event,'tip-<xsl:value-of select="$type" />')</xsl:attribute> - <xsl:attribute name="onmouseover">popUp(event,'tip-<xsl:value-of select="$type" />')</xsl:attribute> - <xsl:value-of select="/BugCollection/BugPattern[@type=$type]/ShortDescription" />   - (<xsl:value-of select="$bug-count" />) - </a> - </div> - <div style="display:none;"> - <xsl:attribute name="id">package-<xsl:value-of select="$package" />-and-class-<xsl:value-of select="$class" />-and-type-<xsl:value-of select="$type" /></xsl:attribute> - <xsl:variable name="package-class-type">package-<xsl:value-of select="$package" />-and-class-<xsl:value-of select="$class" />-and-type-<xsl:value-of select="$type" /></xsl:variable> - <xsl:variable name="bug-id">b-uid-<xsl:value-of select="@instanceHash" />-<xsl:value-of select="@instanceOccurrenceNum" /></xsl:variable> - <xsl:for-each select="/BugCollection/BugInstance[@type=$type and not(@last) and Class[position()=1 and @classname=$class]]"> - <xsl:call-template name="display-bug"> - <xsl:with-param name="b-t" select="@type" /> - <xsl:with-param name="bug-id" select="$bug-id" /> - <xsl:with-param name="which-list" select="'p'" /> - </xsl:call-template> - </xsl:for-each> - </div> - </div> -</xsl:template> - -</xsl:transform> diff --git a/lib/findbugs/xsl/plain.xsl b/lib/findbugs/xsl/plain.xsl deleted file mode 100644 index 80fff8d..0000000 --- a/lib/findbugs/xsl/plain.xsl +++ /dev/null @@ -1,306 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - FindBugs - Find bugs in Java programs - Copyright (C) 2004,2005 University of Maryland - Copyright (C) 2005, Chris Nappin - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---> -<xsl:stylesheet version="1.0" - xmlns="http://www.w3.org/1999/xhtml" - xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> - -<xsl:output - method="xml" - omit-xml-declaration="yes" - standalone="yes" - doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" - doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" - indent="yes" - encoding="UTF-8"/> - -<xsl:variable name="bugTableHeader"> - <tr class="tableheader"> - <th align="left">Warning</th> - <th align="left">Priority</th> - <th align="left">Details</th> - </tr> -</xsl:variable> - -<xsl:template match="/"> - <html> - <head> - <title>FindBugs Report</title> - <style type="text/css"> - .tablerow0 { - background: #EEEEEE; - } - - .tablerow1 { - background: white; - } - - .detailrow0 { - background: #EEEEEE; - } - - .detailrow1 { - background: white; - } - - .tableheader { - background: #b9b9fe; - font-size: larger; - } - </style> - </head> - - <xsl:variable name="unique-catkey" select="/BugCollection/BugCategory/@category"/> - - <body> - - <h1>FindBugs Report</h1> - <p>Produced using <a href="http://findbugs.sourceforge.net">FindBugs</a> <xsl:value-of select="/BugCollection/@version"/>.</p> - <p>Project: - <xsl:choose> - <xsl:when test='string-length(/BugCollection/Project/@projectName)>0'><xsl:value-of select="/BugCollection/Project/@projectName" /></xsl:when> - <xsl:otherwise><xsl:value-of select="/BugCollection/Project/@filename" /></xsl:otherwise> - </xsl:choose> - </p> - <h2>Metrics</h2> - <xsl:apply-templates select="/BugCollection/FindBugsSummary"/> - - <h2>Summary</h2> - <table width="500" cellpadding="5" cellspacing="2"> - <tr class="tableheader"> - <th align="left">Warning Type</th> - <th align="right">Number</th> - </tr> - - <xsl:for-each select="$unique-catkey"> - <xsl:sort select="." order="ascending"/> - <xsl:variable name="catkey" select="."/> - <xsl:variable name="catdesc" select="/BugCollection/BugCategory[@category=$catkey]/Description"/> - <xsl:variable name="styleclass"> - <xsl:choose><xsl:when test="position() mod 2 = 1">tablerow0</xsl:when> - <xsl:otherwise>tablerow1</xsl:otherwise> - </xsl:choose> - </xsl:variable> - - <tr class="{$styleclass}"> - <td><a href="#Warnings_{$catkey}"><xsl:value-of select="$catdesc"/> Warnings</a></td> - <td align="right"><xsl:value-of select="count(/BugCollection/BugInstance[(@category=$catkey) and (not(@last))])"/></td> - </tr> - </xsl:for-each> - - <xsl:variable name="styleclass"> - <xsl:choose><xsl:when test="count($unique-catkey) mod 2 = 0">tablerow0</xsl:when> - <xsl:otherwise>tablerow1</xsl:otherwise> - </xsl:choose> - </xsl:variable> - <tr class="{$styleclass}"> - <td><b>Total</b></td> - <td align="right"><b><xsl:value-of select="count(/BugCollection/BugInstance[not(@last)])"/></b></td> - </tr> - </table> - <p><br/><br/></p> - - <h1>Warnings</h1> - - <p>Click on each warning link to see a full description of the issue, and - details of how to resolve it.</p> - - <xsl:for-each select="$unique-catkey"> - <xsl:sort select="." order="ascending"/> - <xsl:variable name="catkey" select="."/> - <xsl:variable name="catdesc" select="/BugCollection/BugCategory[@category=$catkey]/Description"/> - - <xsl:call-template name="generateWarningTable"> - <xsl:with-param name="warningSet" select="/BugCollection/BugInstance[(@category=$catkey) and (not(@last))]"/> - <xsl:with-param name="sectionTitle"><xsl:value-of select="$catdesc"/> Warnings</xsl:with-param> - <xsl:with-param name="sectionId">Warnings_<xsl:value-of select="$catkey"/></xsl:with-param> - </xsl:call-template> - </xsl:for-each> - - <p><br/><br/></p> - <h1><a name="Details">Warning Types</a></h1> - - <xsl:apply-templates select="/BugCollection/BugPattern"> - <xsl:sort select="@abbrev"/> - <xsl:sort select="ShortDescription"/> - </xsl:apply-templates> - - </body> - </html> -</xsl:template> - -<xsl:template match="BugInstance[not(@last)]"> - <xsl:variable name="warningId"><xsl:value-of select="generate-id()"/></xsl:variable> - - <tr class="tablerow{position() mod 2}"> - <td width="20%" valign="top"> - <a href="#{@type}"><xsl:value-of select="ShortMessage"/></a> - </td> - <td width="10%" valign="top"> - <xsl:choose> - <xsl:when test="@priority = 1">High</xsl:when> - <xsl:when test="@priority = 2">Medium</xsl:when> - <xsl:when test="@priority = 3">Low</xsl:when> - <xsl:otherwise>Unknown</xsl:otherwise> - </xsl:choose> - </td> - <td width="70%"> - <p><xsl:value-of select="LongMessage"/><br/><br/> - - <!-- add source filename and line number(s), if any --> - <xsl:if test="SourceLine"> - <br/>In file <xsl:value-of select="SourceLine/@sourcefile"/>, - <xsl:choose> - <xsl:when test="SourceLine/@start = SourceLine/@end"> - line <xsl:value-of select="SourceLine/@start"/> - </xsl:when> - <xsl:otherwise> - lines <xsl:value-of select="SourceLine/@start"/> - to <xsl:value-of select="SourceLine/@end"/> - </xsl:otherwise> - </xsl:choose> - </xsl:if> - - <xsl:for-each select="./*/Message"> - <br/><xsl:value-of select="text()"/> - </xsl:for-each> - </p> - </td> - </tr> -</xsl:template> - -<xsl:template match="BugPattern"> - <h2><a name="{@type}"><xsl:value-of select="ShortDescription"/></a></h2> - <xsl:value-of select="Details" disable-output-escaping="yes"/> - <p><br/><br/></p> -</xsl:template> - -<xsl:template name="generateWarningTable"> - <xsl:param name="warningSet"/> - <xsl:param name="sectionTitle"/> - <xsl:param name="sectionId"/> - - <h2><a name="{$sectionId}"><xsl:value-of select="$sectionTitle"/></a></h2> - <table class="warningtable" width="100%" cellspacing="2" cellpadding="5"> - <xsl:copy-of select="$bugTableHeader"/> - <xsl:choose> - <xsl:when test="count($warningSet) > 0"> - <xsl:apply-templates select="$warningSet"> - <xsl:sort select="@priority"/> - <xsl:sort select="@abbrev"/> - <xsl:sort select="Class/@classname"/> - </xsl:apply-templates> - </xsl:when> - <xsl:otherwise> - <tr><td colspan="2"><p><i>None</i></p></td></tr> - </xsl:otherwise> - </xsl:choose> - </table> - <p><br/><br/></p> -</xsl:template> - -<xsl:template match="FindBugsSummary"> - <xsl:variable name="kloc" select="@total_size div 1000.0"/> - <xsl:variable name="format" select="'#######0.00'"/> - - <p><xsl:value-of select="@total_size"/> lines of code analyzed, - in <xsl:value-of select="@total_classes"/> classes, - in <xsl:value-of select="@num_packages"/> packages.</p> - <table width="500" cellpadding="5" cellspacing="2"> - <tr class="tableheader"> - <th align="left">Metric</th> - <th align="right">Total</th> - <th align="right">Density*</th> - </tr> - <tr class="tablerow0"> - <td>High Priority Warnings</td> - <td align="right"><xsl:value-of select="@priority_1"/></td> - <td align="right"> - <xsl:choose> - <xsl:when test= "number($kloc) > 0.0"> - <xsl:value-of select="format-number(@priority_1 div $kloc, $format)"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="format-number(0.0, $format)"/> - </xsl:otherwise> - </xsl:choose> - </td> - </tr> - <tr class="tablerow1"> - <td>Medium Priority Warnings</td> - <td align="right"><xsl:value-of select="@priority_2"/></td> - <td align="right"> - <xsl:choose> - <xsl:when test= "number($kloc) > 0.0"> - <xsl:value-of select="format-number(@priority_2 div $kloc, $format)"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="format-number(0.0, $format)"/> - </xsl:otherwise> - </xsl:choose> - </td> - </tr> - - <xsl:choose> - <xsl:when test="@priority_3"> - <tr class="tablerow1"> - <td>Low Priority Warnings</td> - <td align="right"><xsl:value-of select="@priority_3"/></td> - <td align="right"> - <xsl:choose> - <xsl:when test= "number($kloc) > 0.0"> - <xsl:value-of select="format-number(@priority_3 div $kloc, $format)"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="format-number(0.0, $format)"/> - </xsl:otherwise> - </xsl:choose> - </td> - </tr> - <xsl:variable name="totalClass" select="tablerow0"/> - </xsl:when> - <xsl:otherwise> - <xsl:variable name="totalClass" select="tablerow1"/> - </xsl:otherwise> - </xsl:choose> - - <tr class="$totalClass"> - <td><b>Total Warnings</b></td> - <td align="right"><b><xsl:value-of select="@total_bugs"/></b></td> - <td align="right"> - <b> - <xsl:choose> - <xsl:when test= "number($kloc) > 0.0"> - <xsl:value-of select="format-number(@total_bugs div $kloc, $format)"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="format-number(0.0, $format)"/> - </xsl:otherwise> - </xsl:choose> - </b> - </td> - </tr> - </table> - <p><i>(* Defects per Thousand lines of non-commenting source statements)</i></p> - <p><br/><br/></p> - -</xsl:template> - -</xsl:stylesheet> diff --git a/lib/findbugs/xsl/summary.xsl b/lib/findbugs/xsl/summary.xsl deleted file mode 100644 index faf0131..0000000 --- a/lib/findbugs/xsl/summary.xsl +++ /dev/null @@ -1,252 +0,0 @@ -<?xml version="1.0"?> -<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" > - -<xsl:output - method="xml" indent="yes" - doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" - doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" - encoding="UTF-8"/> - -<xsl:param name="PAGE.TITLE" select="'Findbugs Summary Statistics'" /> -<xsl:param name="PAGE.FONT" select="'Arial'" /> -<xsl:param name="SUMMARY.HEADER" select="'Findbugs Summary Report'" /> -<xsl:param name="SUMMARY.LABEL" select="'Summary Analysis Generated at: '" /> -<xsl:param name="PACKAGE.HEADER" select="'Bugs By Package'" /> -<xsl:param name="PACKAGE.SORT.LABEL" select="'Sorted by Total Bugs'" /> -<xsl:param name="PACKAGE.LABEL" select="'Analysis of Package: '" /> -<xsl:param name="DEFAULT.PACKAGE.NAME" select="'default package'" /> -<xsl:param name="PACKAGE.BUGCLASS.LABEL" select="'Most Buggy Class in Package with #1 $1:'" /> -<xsl:param name="TOTAL.PACKAGES.LABEL" select="'#1 $1 Analyzed'" /> - -<xsl:param name="BUGS.SINGLE.LABEL" select="'Bug'" /> -<xsl:param name="BUGS.PULURAL.LABEL" select="'Bugs'" /> -<xsl:param name="PACKAGE.SINGLE.LABEL" select="'Package'" /> -<xsl:param name="PACKAGE.PULURAL.LABEL" select="'Packages'" /> - - -<xsl:param name="TABLE.HEADING.TYPE" select="'Type Checked'" /> -<xsl:param name="TABLE.HEADING.COUNT" select="'Count'" /> -<xsl:param name="TABLE.HEADING.BUGS" select="'Bugs'" /> -<xsl:param name="TABLE.HEADING.PERCENT" select="'Percentage'" /> -<xsl:param name="TABLE.ROW.OUTER" select="'Outer Classes'" /> -<xsl:param name="TABLE.ROW.INNER" select="'Inner Classes'" /> -<xsl:param name="TABLE.ROW.INTERFACE" select="'Interfaces'" /> -<xsl:param name="TABLE.ROW.TOTAL" select="'Total'" /> -<xsl:param name="TABLE.WIDTH" select="'90%'" /> - -<xsl:param name="PERCENTAGE.FORMAT" select="'#0.00%'" /> - -<!-- This template drives the rest of the output --> -<xsl:template match="/" > - <html> - <!-- JEditorPane gets really angry if it sees this - WWP: Sorry, this needs to be explained better. Not a valid HTML document without a head. - --> - <head><title><xsl:value-of select="$PAGE.TITLE" /></title></head> - <body> - <h1 align="center"><a href="http://findbugs.sourceforge.net"><xsl:value-of select="$SUMMARY.HEADER" /></a></h1> - <h2 align="center"> Analysis for - <xsl:choose> - <xsl:when test='string-length(/BugCollection/Project/@projectName)>0'> - <xsl:value-of select="/BugCollection/Project/@projectName" /></xsl:when> - <xsl:otherwise><xsl:value-of select="/BugCollection/Project/@filename" /></xsl:otherwise> - </xsl:choose> - </h2> - <h2 align="center"><xsl:value-of select="$SUMMARY.LABEL" /> - <i><xsl:value-of select="//FindBugsSummary/@timestamp" /></i></h2> - <xsl:apply-templates select="//FindBugsSummary" /> - <br/> - <p align="center"> - <font face="{$PAGE.FONT}" size="6"><xsl:value-of select="$PACKAGE.HEADER" /></font> - <br/><font face="{$PAGE.FONT}" size="4"><i>(<xsl:value-of select="$PACKAGE.SORT.LABEL"/>)</i></font> - </p> - <xsl:for-each select="//FindBugsSummary/PackageStats"> - <xsl:sort select="@total_bugs" data-type="number" order="descending" /> - <xsl:apply-templates select="." /> - </xsl:for-each> - </body> - </html> -</xsl:template> - -<xsl:template name="status_table_row" > - <xsl:param name="LABEL" select="''" /> - <xsl:param name="COUNT" select="1" /> - <xsl:param name="BUGS" select="0" /> - <xsl:param name="FONT_SIZE" select="4" /> - <tr> - <td align="left"><font face="{$PAGE.FONT}" size="{$FONT_SIZE}"><xsl:value-of select="$LABEL" /></font></td> - <td align="center"><font face="{$PAGE.FONT}" color="green" size="{$FONT_SIZE}"><xsl:value-of select="$COUNT" /></font></td> - <td align="center"><font face="{$PAGE.FONT}" color="red" size="{$FONT_SIZE}"><xsl:value-of select="$BUGS" /></font></td> - <td align="center"><font face="{$PAGE.FONT}" color="blue" size="{$FONT_SIZE}"> - <xsl:choose> - <xsl:when test="$COUNT > 0"> - <xsl:value-of select="format-number(number($BUGS div $COUNT), $PERCENTAGE.FORMAT)"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="format-number(0, $PERCENTAGE.FORMAT)"/> - </xsl:otherwise> - </xsl:choose> - </font> - </td> - </tr> -</xsl:template> - -<xsl:template name="table_header" > - <tr> - <th><font face="{$PAGE.FONT}" size="4"><xsl:value-of select="$TABLE.HEADING.TYPE"/></font></th> - <th><font face="{$PAGE.FONT}" size="4"><xsl:value-of select="$TABLE.HEADING.COUNT"/></font></th> - <th><font face="{$PAGE.FONT}" size="4"><xsl:value-of select="$TABLE.HEADING.BUGS"/></font></th> - <th><font face="{$PAGE.FONT}" size="4"><xsl:value-of select="$TABLE.HEADING.PERCENT"/></font></th> - </tr> -</xsl:template> - -<xsl:template match="FindBugsSummary" > - <table width="{$TABLE.WIDTH}" border="1" align="center"> - <xsl:call-template name="table_header" /> - - <xsl:call-template name="status_table_row"> - <xsl:with-param name="LABEL" select="$TABLE.ROW.OUTER" /> - <xsl:with-param name="COUNT" select="count(PackageStats/ClassStats[@interface='false' and substring-after(@class,'$')=''])" /> - <xsl:with-param name="BUGS" select="sum(PackageStats/ClassStats[@interface='false' and substring-after(@class,'$')='']/@bugs)" /> - </xsl:call-template> - - <xsl:call-template name="status_table_row"> - <xsl:with-param name="LABEL" select="$TABLE.ROW.INNER" /> - <xsl:with-param name="COUNT" select="count(PackageStats/ClassStats[@interface='false' and substring-after(@class,'$')!=''])" /> - <xsl:with-param name="BUGS" select="sum(PackageStats/ClassStats[@interface='false' and substring-after(@class,'$')!='']/@bugs)" /> - </xsl:call-template> - - <xsl:call-template name="status_table_row"> - <xsl:with-param name="LABEL" select="$TABLE.ROW.INTERFACE" /> - <xsl:with-param name="COUNT" select="count(PackageStats/ClassStats[@interface='true'])" /> - <xsl:with-param name="BUGS" select="sum(PackageStats/ClassStats[@interface='true']/@bugs)" /> - </xsl:call-template> - - <xsl:call-template name="status_table_row"> - <xsl:with-param name="LABEL" select="$TABLE.ROW.TOTAL" /> - <xsl:with-param name="COUNT" select="@total_classes" /> - <xsl:with-param name="BUGS" select="@total_bugs"/> - <xsl:with-param name="FONT_SIZE" select="5"/> - </xsl:call-template> - <xsl:variable name="num_packages" select="count(PackageStats)" /> - <tr><td align="center" colspan="4"><font face="{$PAGE.FONT}" size="4"> - <xsl:call-template name='string_format'> - <xsl:with-param name="COUNT" select="$num_packages"/> - <xsl:with-param name="STRING" select="$TOTAL.PACKAGES.LABEL"/> - <xsl:with-param name="SINGLE" select="$PACKAGE.SINGLE.LABEL"/> - <xsl:with-param name="PULURAL" select="$PACKAGE.PULURAL.LABEL"/> - </xsl:call-template> - </font></td> - </tr> - </table> -</xsl:template> - - -<xsl:template name='string_format'> - <xsl:param name="COUNT" select="1"/> - <xsl:param name="STRING" select="''"/> - <xsl:param name="SINGLE" select="''"/> - <xsl:param name="PULURAL" select="''"/> - <xsl:variable name="count_str" select="concat(substring-before($STRING,'#1'), $COUNT, substring-after($STRING,'#1'))" /> - - <xsl:choose> - <xsl:when test="$COUNT > 1"> - <xsl:value-of select="concat(substring-before($count_str,'$1'), $PULURAL, substring-after($count_str,'$1'))" /> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="concat(substring-before($count_str,'$1'), $SINGLE, substring-after($count_str,'$1'))" /> - </xsl:otherwise> - </xsl:choose> -</xsl:template> - - -<xsl:template match="PackageStats" > - <xsl:variable name="package-name"> - <xsl:choose> - <xsl:when test="@package = ''"> - <xsl:value-of select="$DEFAULT.PACKAGE.NAME"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="@package"/> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <xsl:variable name="package-prefix"> - <xsl:choose> - <xsl:when test="@package = ''"> - <xsl:text></xsl:text> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="concat(@package,'.')"/> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <h2 align="center"><xsl:value-of select="$PACKAGE.LABEL"/><i><font color='green'><xsl:value-of select="$package-name" /></font></i></h2> - <table width="{$TABLE.WIDTH}" border="1" align="center"> - <xsl:call-template name="table_header" /> - - <xsl:call-template name="status_table_row"> - <xsl:with-param name="LABEL" select="$TABLE.ROW.OUTER" /> - <xsl:with-param name="COUNT" select="count(ClassStats[@interface='false' and substring-after(@class,'$')=''])" /> - <xsl:with-param name="BUGS" select="sum(ClassStats[@interface='false' and substring-after(@class,'$')='']/@bugs)" /> - </xsl:call-template> - - <xsl:call-template name="status_table_row"> - <xsl:with-param name="LABEL" select="$TABLE.ROW.INNER" /> - <xsl:with-param name="COUNT" select="count(ClassStats[@interface='false' and substring-after(@class,'$')!=''])" /> - <xsl:with-param name="BUGS" select="sum(ClassStats[@interface='false' and substring-after(@class,'$')!='']/@bugs)" /> - </xsl:call-template> - - <xsl:call-template name="status_table_row"> - <xsl:with-param name="LABEL" select="$TABLE.ROW.INTERFACE" /> - <xsl:with-param name="COUNT" select="count(ClassStats[@interface='true'])" /> - <xsl:with-param name="BUGS" select="sum(ClassStats[@interface='true']/@bugs)" /> - </xsl:call-template> - - <xsl:call-template name="status_table_row"> - <xsl:with-param name="LABEL" select="$TABLE.ROW.TOTAL" /> - <xsl:with-param name="COUNT" select="@total_types" /> - <xsl:with-param name="BUGS" select="@total_bugs" /> - <xsl:with-param name="FONT_SIZE" select="5"/> - </xsl:call-template> - - </table> - <xsl:if test="@total_bugs > 0"> - <table width="{$TABLE.WIDTH}" border="0" align="center"> - <xsl:variable name="max_bugs"> - <xsl:for-each select="ClassStats"> - <xsl:sort select="@bugs" data-type="number" order="descending"/> - <xsl:if test="position()=1"> - <xsl:value-of select="@bugs"/> - </xsl:if> - </xsl:for-each> - </xsl:variable> - - <tr> - <td align="left" colspan="2"> - <font face="{$PAGE.FONT}" size="4"> - <xsl:call-template name='string_format'> - <xsl:with-param name="COUNT" select="$max_bugs"/> - <xsl:with-param name="STRING" select="$PACKAGE.BUGCLASS.LABEL"/> - <xsl:with-param name="SINGLE" select="$BUGS.SINGLE.LABEL"/> - <xsl:with-param name="PULURAL" select="$BUGS.PULURAL.LABEL"/> - </xsl:call-template> - </font> - </td> - </tr> - - <xsl:for-each select="ClassStats"> - <xsl:if test="@bugs = $max_bugs"> - <tr> - <td>       </td> - <td align="left"><font face="{$PAGE.FONT}" color="red" size="4"><i><xsl:value-of select="$package-prefix"/><xsl:value-of select="@class" /></i></font></td> - </tr> - </xsl:if> - </xsl:for-each> - - </table> - </xsl:if> - <br/> -</xsl:template> - -</xsl:stylesheet> diff --git a/lib/jrat/bcel-326809.jar b/lib/jrat/bcel-326809.jar deleted file mode 100644 index 9c8de92..0000000 Binary files a/lib/jrat/bcel-326809.jar and /dev/null differ diff --git a/lib/jrat/jmxri.jar b/lib/jrat/jmxri.jar deleted file mode 100644 index 5e519fd..0000000 Binary files a/lib/jrat/jmxri.jar and /dev/null differ diff --git a/lib/jrat/shiftone-arbor.jar b/lib/jrat/shiftone-arbor.jar deleted file mode 100644 index f16528e..0000000 Binary files a/lib/jrat/shiftone-arbor.jar and /dev/null differ diff --git a/lib/jrat/shiftone-jrat.jar b/lib/jrat/shiftone-jrat.jar deleted file mode 100644 index 3c1c5bf..0000000 Binary files a/lib/jrat/shiftone-jrat.jar and /dev/null differ diff --git a/lib/junit/junit.jar b/lib/junit/junit.jar deleted file mode 100644 index 717cd08..0000000 Binary files a/lib/junit/junit.jar and /dev/null differ diff --git a/lib/log4j/log4j-1.2.13.jar b/lib/log4j/log4j-1.2.13.jar deleted file mode 100644 index dde9972..0000000 Binary files a/lib/log4j/log4j-1.2.13.jar and /dev/null differ diff --git a/lib/runtime/getopt/gnu.getopt.jar b/lib/runtime/getopt/gnu.getopt.jar deleted file mode 100644 index 1aea24b..0000000 Binary files a/lib/runtime/getopt/gnu.getopt.jar and /dev/null differ diff --git a/lib/svn/commons-lang-2.0.jar b/lib/svn/commons-lang-2.0.jar deleted file mode 100644 index c8a2870..0000000 Binary files a/lib/svn/commons-lang-2.0.jar and /dev/null differ diff --git a/lib/svn/jakarta-regexp-1.3.jar b/lib/svn/jakarta-regexp-1.3.jar deleted file mode 100644 index d653a38..0000000 Binary files a/lib/svn/jakarta-regexp-1.3.jar and /dev/null differ diff --git a/lib/svn/svnClientAdapter.jar b/lib/svn/svnClientAdapter.jar deleted file mode 100644 index 502a53f..0000000 Binary files a/lib/svn/svnClientAdapter.jar and /dev/null differ diff --git a/lib/svn/svnant.jar b/lib/svn/svnant.jar deleted file mode 100644 index fc5e2b9..0000000 Binary files a/lib/svn/svnant.jar and /dev/null differ diff --git a/lib/svn/svnjavahl.jar b/lib/svn/svnjavahl.jar deleted file mode 100644 index 4208165..0000000 Binary files a/lib/svn/svnjavahl.jar and /dev/null differ diff --git a/lib/vpp/commons-collections-3.1.jar b/lib/vpp/commons-collections-3.1.jar deleted file mode 100644 index 41e230f..0000000 Binary files a/lib/vpp/commons-collections-3.1.jar and /dev/null differ diff --git a/lib/vpp/foundrylogic-vpp-2.2.1-nodeps.jar b/lib/vpp/foundrylogic-vpp-2.2.1-nodeps.jar deleted file mode 100644 index 3956a43..0000000 Binary files a/lib/vpp/foundrylogic-vpp-2.2.1-nodeps.jar and /dev/null differ diff --git a/lib/vpp/velocity-1.4.jar b/lib/vpp/velocity-1.4.jar deleted file mode 100644 index 04ec9d2..0000000 Binary files a/lib/vpp/velocity-1.4.jar and /dev/null differ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..bb6ef10 --- /dev/null +++ b/pom.xml @@ -0,0 +1,124 @@ + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.anarres</groupId> + <artifactId>cpp</artifactId> + <name>Anarres JCPP</name> + <url>http://www.anarres.org/projects/jcpp/</url> + <version>1.5.1-SNAPSHOT</version> + <packaging>jar</packaging> + <description></description> + + <developers> + <developer> + <id>anarres.author</id> + <name>Anarres Author</name> + <email>contact@anarres.org</email> + </developer> + </developers> + + <licenses> + <license> + <name>Apache 2.0</name> + <url>http://www.apache.org/licenses/LICENSE-2.0.html</url> + <distribution>repo</distribution> + </license> + </licenses> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.1</version> + <configuration> + <source>1.7</source> + <target>1.7</target> + <encoding>UTF-8</encoding> + <optimize>true</optimize> + </configuration> + </plugin> + + <plugin> + <groupId>com.nativelibs4java</groupId> + <artifactId>maven-velocity-plugin</artifactId> + <version>0.8</version> + <executions> + <execution> + <phase>generate-sources</phase> + <goals> + <goal>generate</goal> + </goals> + </execution> + </executions> + <configuration> + <properties> + <version>${project.version}</version> + <project_version>${project.version}</project_version> + <project_name>${project.artifactId}</project_name> + </properties> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <version>2.4</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.16</version> + <configuration> + <redirectTestOutputToFile>true</redirectTestOutputToFile> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-assembly-plugin</artifactId> + <configuration> + <descriptorRefs> + <descriptorRef>jar-with-dependencies</descriptorRef> + </descriptorRefs> + </configuration> + <executions> + <execution> + <phase>package</phase> + <id>create-my-bundle</id> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.11</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.ant</groupId> + <artifactId>ant</artifactId> + <version>1.8.2</version> + </dependency> + <dependency> + <groupId>gnu.getopt</groupId> + <artifactId>java-getopt</artifactId> + <version>1.0.13</version> + </dependency> + <dependency> + <groupId>net.sourceforge.findbugs</groupId> + <artifactId>jsr305</artifactId> + <version>1.3.2</version> + </dependency> + </dependencies> +</project> + diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index f22856c..0000000 --- a/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name='jcpp' diff --git a/src/main/java/org/anarres/cpp/CppTask.java b/src/main/java/org/anarres/cpp/CppTask.java index 5e17786..55a8eff 100644 --- a/src/main/java/org/anarres/cpp/CppTask.java +++ b/src/main/java/org/anarres/cpp/CppTask.java @@ -34,7 +34,7 @@ */ public class CppTask extends Copy { - private class Listener extends PreprocessorListener { + private class Listener extends DefaultPreprocessorListener { @Override protected void print(String msg) { diff --git a/src/main/java/org/anarres/cpp/DefaultPreprocessorListener.java b/src/main/java/org/anarres/cpp/DefaultPreprocessorListener.java new file mode 100644 index 0000000..e6f122b --- /dev/null +++ b/src/main/java/org/anarres/cpp/DefaultPreprocessorListener.java @@ -0,0 +1,105 @@ +package org.anarres.cpp; + +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import javax.annotation.Nonnegative; + +/** + * A handler for preprocessor events, primarily errors and warnings. + * + * If no PreprocessorListener is installed in a Preprocessor, all + * error and warning events will throw an exception. Installing a + * listener allows more intelligent handling of these events. + */ +public class DefaultPreprocessorListener implements PreprocessorListener { + + private int errors; + private int warnings; + + public DefaultPreprocessorListener() { + clear(); + } + + public void clear() { + errors = 0; + warnings = 0; + } + + @Nonnegative + public int getErrors() { + return errors; + } + + @Nonnegative + public int getWarnings() { + return warnings; + } + + protected void print(String msg) { + System.err.println(msg); + } + + /** + * Handles a warning. + * + * The behaviour of this method is defined by the + * implementation. It may simply record the error message, or + * it may throw an exception. + */ + public void handleWarning(Source source, int line, int column, + String msg) + throws LexerException { + warnings++; + print(source.getName() + ":" + line + ":" + column + + ": warning: " + msg); + } + + /** + * Handles an error. + * + * The behaviour of this method is defined by the + * implementation. It may simply record the error message, or + * it may throw an exception. + */ + public void handleError(Source source, int line, int column, + String msg) + throws LexerException { + errors++; + print(source.getName() + ":" + line + ":" + column + + ": error: " + msg); + } + + public void handleSourceChange(Source source, String event) { + } + + @Override + public boolean beforeInclude(String filePath, int line) { + return false; + } + + public void handlePreprocesorDirective(Source source, PreprocessorDirective directive) { + System.err.println(directive.toString()); + } + + public void handleMacroExpansion(Source source, int line, int column, String macro, + String definitionFileName, int definitionLine, int definitionColumn) { + System.err.println(source.getName() + " : " + line + ":" + column + " macro: " + macro + + " definition: " + definitionFileName + ":" + definitionLine + ":" + + definitionColumn); + } + +} diff --git a/src/main/java/org/anarres/cpp/FileLexerSource.java b/src/main/java/org/anarres/cpp/FileLexerSource.java index 1505506..3f5a0d3 100644 --- a/src/main/java/org/anarres/cpp/FileLexerSource.java +++ b/src/main/java/org/anarres/cpp/FileLexerSource.java @@ -74,12 +74,12 @@ public File getFile() { * This is not necessarily the same as getFile().getPath() in case we are in a chroot. */ @Override - /* pp */ String getPath() { + public String getPath() { return path; } @Override - /* pp */ String getName() { + public String getName() { return getPath(); } diff --git a/src/main/java/org/anarres/cpp/InputLexerSource.java b/src/main/java/org/anarres/cpp/InputLexerSource.java index 3e1dcb3..5eb8f94 100644 --- a/src/main/java/org/anarres/cpp/InputLexerSource.java +++ b/src/main/java/org/anarres/cpp/InputLexerSource.java @@ -48,12 +48,12 @@ public InputLexerSource(InputStream input) } @Override - /* pp */ String getPath() { + public String getPath() { return "<standard-input>"; } @Override - /* pp */ String getName() { + public String getName() { return "standard input"; } diff --git a/src/main/java/org/anarres/cpp/LexerSource.java b/src/main/java/org/anarres/cpp/LexerSource.java index 5f1dac3..4f5362e 100644 --- a/src/main/java/org/anarres/cpp/LexerSource.java +++ b/src/main/java/org/anarres/cpp/LexerSource.java @@ -120,10 +120,10 @@ private void _error(String msg, boolean error) } /* - private boolean _isLineSeparator(int c) { - return Character.getType(c) == Character.LINE_SEPARATOR - || c == -1; - } + * private boolean _isLineSeparator(int c) { + * return Character.getType(c) == Character.LINE_SEPARATOR + * || c == -1; + * } */ /* XXX Move to JoinReader and canonicalise newlines. */ @@ -197,14 +197,14 @@ private int read() } /* - if (isLineSeparator(c)) { - line++; - lastcolumn = column; - column = 0; - } - else { - column++; - } + * if (isLineSeparator(c)) { + * line++; + * lastcolumn = column; + * column = 0; + * } + * else { + * column++; + * } */ return c; } @@ -241,7 +241,7 @@ private void unread(int c) /* Consumes the rest of the current line into an invalid. */ @Nonnull - private Token invalid(StringBuilder text, String reason) + private Token invalid(StringBuilder text, int expected, String reason) throws IOException, LexerException { int d = read(); @@ -250,25 +250,33 @@ private Token invalid(StringBuilder text, String reason) d = read(); } unread(d); - return new Token(INVALID, text.toString(), reason); + return new Token(INVALID, expected, text.toString(), reason); } @Nonnull private Token ccomment() throws IOException, LexerException { + StringBuilder text = new StringBuilder("/*"); int d; do { do { d = read(); - text.append((char) d); - } while (d != '*'); + if (d != -1) { + text.append((char) d); + } + } while (d != '*' && d != -1); do { d = read(); - text.append((char) d); + if (d != -1) { + text.append((char) d); + } } while (d == '*'); - } while (d != '/'); + } while (d != '/' && d != -1); + if (d == -1) { + return new Token(INVALID, CCOMMENT, text.toString(), "End of file in a multiline comment"); + } return new Token(CCOMMENT, text.toString()); } @@ -375,15 +383,15 @@ private Token character() d = escape(text); } else if (isLineSeparator(d)) { unread(d); - return new Token(INVALID, text.toString(), + return new Token(INVALID, CHARACTER, text.toString(), "Unterminated character literal"); } else if (d == '\'') { text.append('\''); - return new Token(INVALID, text.toString(), + return new Token(INVALID, CHARACTER, text.toString(), "Empty character literal"); } else if (!Character.isDefined(d)) { text.append('?'); - return invalid(text, "Illegal unicode character literal"); + return invalid(text, CHARACTER, "Illegal unicode character literal"); } else { text.append((char) d); } @@ -402,7 +410,7 @@ private Token character() break; e = read(); } - return new Token(INVALID, text.toString(), + return new Token(INVALID, CHARACTER, text.toString(), "Illegal character constant " + text); } text.append('\''); @@ -420,6 +428,26 @@ private Token string(char open, char close) StringBuilder buf = new StringBuilder(); + final int expectedTokenType; + final String expectedTokenName; + switch (open) { + case '\"': + expectedTokenType = Token.STRING; + expectedTokenName = "string"; + break; + case '\'': + expectedTokenType = Token.CHARACTER; + expectedTokenName = "character"; + break; + case '>': + expectedTokenType = Token.HEADER; + expectedTokenName = "header"; + break; + default: + expectedTokenType = 0; + expectedTokenName = "string"; + } + for (;;) { int c = read(); if (c == close) { @@ -433,13 +461,13 @@ private Token string(char open, char close) } else if (c == -1) { unread(c); // error("End of file in string literal after " + buf); - return new Token(INVALID, text.toString(), - "End of file in string literal after " + buf); + return new Token(INVALID, expectedTokenType, text.toString(), + "End of file in " + expectedTokenName + " literal after " + buf); } else if (isLineSeparator(c)) { unread(c); // error("Unterminated string literal after " + buf); - return new Token(INVALID, text.toString(), - "Unterminated string literal after " + buf); + return new Token(INVALID, expectedTokenType, text.toString(), + "Unterminated " + expectedTokenName + " literal after " + buf); } else { text.append((char) c); buf.append((char) c); @@ -479,7 +507,7 @@ private Token _number_suffix(StringBuilder text, NumericValue value, int d) d = read(); } else if (d == 'L' || d == 'l') { if ((flags & NumericValue.FF_SIZE) != 0) - warning("Nultiple length suffixes after " + text); + warning("Multiple length suffixes after " + text); text.append((char) d); int e = read(); if (e == d) { // Case must match. Ll is Welsh. @@ -492,19 +520,19 @@ private Token _number_suffix(StringBuilder text, NumericValue value, int d) } } else if (d == 'I' || d == 'i') { if ((flags & NumericValue.FF_SIZE) != 0) - warning("Nultiple length suffixes after " + text); + warning("Multiple length suffixes after " + text); flags |= NumericValue.F_INT; text.append((char) d); d = read(); } else if (d == 'F' || d == 'f') { if ((flags & NumericValue.FF_SIZE) != 0) - warning("Nultiple length suffixes after " + text); + warning("Multiple length suffixes after " + text); flags |= NumericValue.F_FLOAT; text.append((char) d); d = read(); } else if (d == 'D' || d == 'd') { if ((flags & NumericValue.FF_SIZE) != 0) - warning("Nultiple length suffixes after " + text); + warning("Multiple length suffixes after " + text); flags |= NumericValue.F_DOUBLE; text.append((char) d); d = read(); @@ -512,7 +540,7 @@ private Token _number_suffix(StringBuilder text, NumericValue value, int d) else if (Character.isLetter(d) || d == '_') { unread(d); value.setFlags(flags); - return invalid(text, + return invalid(text, Token.NUMBER, "Invalid suffix \"" + (char) d + "\" on numeric constant"); } else { @@ -526,11 +554,16 @@ else if (Character.isLetter(d) || d == '_') { /* Either a decimal part, or a hex exponent. */ @Nonnull - private String _number_part(StringBuilder text, int base) + private String _number_part(StringBuilder text, int base, boolean sign) throws IOException, LexerException { StringBuilder part = new StringBuilder(); int d = read(); + if (sign && d == '-') { + text.append((char) d); + part.append((char) d); + d = read(); + } while (Character.digit(d, base) != -1) { text.append((char) d); part.append((char) d); @@ -540,18 +573,6 @@ private String _number_part(StringBuilder text, int base) return part.toString(); } - /* We already chewed a zero, so empty is fine. */ - @Nonnull - private Token number_octal() - throws IOException, - LexerException { - StringBuilder text = new StringBuilder("0"); - String integer = _number_part(text, 8); - int d = read(); - NumericValue value = new NumericValue(8, integer); - return _number_suffix(text, value, d); - } - /* We do not know whether know the first digit is valid. */ @Nonnull private Token number_hex(char x) @@ -559,23 +580,34 @@ private Token number_hex(char x) LexerException { StringBuilder text = new StringBuilder("0"); text.append(x); - String integer = _number_part(text, 16); + String integer = _number_part(text, 16, false); NumericValue value = new NumericValue(16, integer); int d = read(); if (d == '.') { - String fraction = _number_part(text, 16); + text.append((char) d); + String fraction = _number_part(text, 16, false); value.setFractionalPart(fraction); d = read(); } if (d == 'P' || d == 'p') { - String exponent = _number_part(text, 10); - value.setExponent(exponent); + text.append((char) d); + String exponent = _number_part(text, 10, true); + value.setExponent(2, exponent); d = read(); } // XXX Make sure it's got enough parts return _number_suffix(text, value, d); } + private static boolean is_octal(@Nonnull String text) { + if (!text.startsWith("0")) + return false; + for (int i = 0; i < text.length(); i++) + if (Character.digit(text.charAt(i), 8) == -1) + return false; + return true; + } + /* We know we have at least one valid digit, but empty is not * fine. */ @Nonnull @@ -583,25 +615,95 @@ private Token number_decimal() throws IOException, LexerException { StringBuilder text = new StringBuilder(); - String integer = _number_part(text, 10); - NumericValue value = new NumericValue(10, integer); + String integer = _number_part(text, 10, false); + String fraction = null; + String exponent = null; int d = read(); if (d == '.') { text.append((char) d); - String fraction = _number_part(text, 10); - value.setFractionalPart(fraction); + fraction = _number_part(text, 10, false); d = read(); } if (d == 'E' || d == 'e') { text.append((char) d); - String exponent = _number_part(text, 10); - value.setExponent(exponent); + exponent = _number_part(text, 10, true); d = read(); } + int base = 10; + if (fraction == null && exponent == null && integer.startsWith("0")) { + if (!is_octal(integer)) + warning("Decimal constant starts with 0, but not octal: " + integer); + else + base = 8; + } + NumericValue value = new NumericValue(base, integer); + if (fraction != null) + value.setFractionalPart(fraction); + if (exponent != null) + value.setExponent(10, exponent); // XXX Make sure it's got enough parts return _number_suffix(text, value, d); } + /** + * 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 + * by an exponent part and a suffix that specifies its type. The + * components of the significand part may include a digit sequence + * representing the whole-number part, followed by a period (.), + * followed by a digit sequence representing the fraction part. + * + * The components of the exponent part are an e, E, p, or P + * followed by an exponent consisting of an optionally signed digit + * sequence. Either the whole-number part or the fraction part has to + * be present; for decimal floating constants, either the period or + * the exponent part has to be present. + * + * The significand part is interpreted as a (decimal or hexadecimal) + * rational number; the digit sequence in the exponent part is + * interpreted as a decimal integer. For decimal floating constants, + * the exponent indicates the power of 10 by which the significand + * part is to be scaled. For hexadecimal floating constants, the + * exponent indicates the power of 2 by which the significand part is + * to be scaled. + * + * For decimal floating constants, and also for hexadecimal + * floating constants when FLT_RADIX is not a power of 2, the result + * is either the nearest representable value, or the larger or smaller + * representable value immediately adjacent to the nearest representable + * value, chosen in an implementation-defined manner. For hexadecimal + * floating constants when FLT_RADIX is a power of 2, the result is + * correctly rounded. + */ + @Nonnull + private Token number() + throws IOException, + LexerException { + Token tok; + int c = read(); + if (c == '0') { + int d = read(); + if (d == 'x' || d == 'X') { + tok = number_hex((char) d); + } else { + unread(d); + unread(c); + tok = number_decimal(); + } + } else if (Character.isDigit(c) || c == '.') { + unread(c); + tok = number_decimal(); + } else { + throw new LexerException("Asked to parse something as a number which isn't: " + (char) c); + } + return tok; + } + @Nonnull private Token identifier(int c) throws IOException, @@ -611,11 +713,13 @@ private Token identifier(int c) text.append((char) c); for (;;) { d = read(); - if (Character.isIdentifierIgnorable(d)) - ; else if (Character.isJavaIdentifierPart(d)) + if (Character.isIdentifierIgnorable(d)) { + ; + } else if (Character.isJavaIdentifierPart(d)) { text.append((char) d); - else + } else { break; + } } unread(d); return new Token(IDENTIFIER, text.toString()); @@ -839,26 +943,11 @@ else if (d == '=') unread(d); if (Character.isDigit(d)) { unread('.'); - tok = number_decimal(); + tok = number(); } /* XXX decimal fraction */ break; - case '0': - /* octal or hex */ - d = read(); - if (d == 'x' || d == 'X') - tok = number_hex((char) d); - else if (d == '.') { - unread(d); - unread(c); - tok = number_decimal(); - } else { - unread(d); - tok = number_octal(); - } - break; - case '\'': tok = string('\'', '\''); break; @@ -878,7 +967,7 @@ else if (d == '.') { tok = whitespace(c); } else if (Character.isDigit(c)) { unread(c); - tok = number_decimal(); + tok = number(); } else if (Character.isJavaIdentifierStart(c)) { tok = identifier(c); } else { @@ -904,6 +993,7 @@ else if (d == '.') { return tok; } + @Override public void close() throws IOException { if (reader != null) { diff --git a/src/main/java/org/anarres/cpp/Macro.java b/src/main/java/org/anarres/cpp/Macro.java index 534cb2b..c69b693 100644 --- a/src/main/java/org/anarres/cpp/Macro.java +++ b/src/main/java/org/anarres/cpp/Macro.java @@ -29,6 +29,11 @@ * extra tokens {@link Token#M_ARG} and {@link Token#M_STRING}. */ public class Macro { + /** + * A value for indicating an unknown position of a macro name. + */ + public static final int UNKNOWN_POSITION_VALUE = -1; + private Source source; private String name; /* It's an explicit decision to keep these around here. We don't @@ -39,12 +44,32 @@ public class Macro { private boolean variadic; private List<Token> tokens; - public Macro(Source source, String name) { + /** + * Number of the line that the name of the macro in its definition starts + * in. It is set to UNKNOWN_POSITION_VALUE if it is unknown, e.g. if the + * macro does not come from any file. + */ + private final int nameStartLine; + + /** + * Number of the column that the name of the macro in its definition + * starts in. It is set to UNKNOWN_POSITION_VALUE if it us unknown. + */ + private final int nameStartColumn; + + + public Macro(Source source, String name, int nameStartLine, int nameStartColumn) { this.source = source; this.name = name; this.args = null; this.variadic = false; this.tokens = new ArrayList<Token>(); + this.nameStartLine = nameStartLine; + this.nameStartColumn = nameStartColumn; + } + + public Macro(Source source, String name) { + this(source, name, UNKNOWN_POSITION_VALUE, UNKNOWN_POSITION_VALUE); } public Macro(String name) { @@ -96,6 +121,18 @@ public int getArgs() { return args.size(); } + /** + * @return The number of the line the name of the macro in its definition + * starts or <code>UNKNOWN_POSITION_VALUE</code> if it is unknown. + */ + public int getNameStartLine() { return nameStartLine; } + + /** + * @return The number of the column the name of the macro in its definition + * starts or <code>UNKNOWN_POSITION_VALUE</code> if it is unknown. + */ + public int getNameStartColumn() { return nameStartColumn; } + /** * Sets the variadic flag on this Macro. */ diff --git a/src/main/java/org/anarres/cpp/MacroTokenSource.java b/src/main/java/org/anarres/cpp/MacroTokenSource.java index 516e4f2..6fa4970 100644 --- a/src/main/java/org/anarres/cpp/MacroTokenSource.java +++ b/src/main/java/org/anarres/cpp/MacroTokenSource.java @@ -17,6 +17,7 @@ package org.anarres.cpp; import java.io.IOException; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -32,12 +33,54 @@ private final List<Argument> args; /* { unexpanded, expanded } */ private Iterator<Token> arg; /* "current expansion" */ + private boolean argumentPasted; /* do tokens from 'arg' come from a paste? */ - /* pp */ MacroTokenSource(Macro m, List<Argument> args) { + /** + * Token with the macro identifier that tokens from this source replace. + */ + private final Token originalToken; + + /* pp */ MacroTokenSource(Macro m, List<Argument> args, Token originalToken) { this.macro = m; - this.tokens = m.getTokens().iterator(); + + /* Clone all tokens from the macro definition. It is done to keep the + appropriate original tokens in those that are returned by + MacroTokenSource objects. Cloning tokens solves a problem with that + while nesting the same macro in itself, e.g. ADD(1, ADD(1, 2)) + where ADD is defined as follows: #define ADD(x, y) x + y */ + final List<Token> clonedTokens = new ArrayList<>(); + try { + for (Token token : m.getTokens()) { + clonedTokens.add((Token) token.clone()); + } + + } catch(CloneNotSupportedException e) { + /* This type of exception should never be thrown in the above code + because Token class implements 'clone' method and Cloneable + interface properly */ + throw new RuntimeException("MacroTokenSource.<init>: CloneNotSupportedException" + + " caught\n" + e.getMessage()); + } + this.tokens = clonedTokens.iterator(); + this.args = args; this.arg = null; + this.originalToken = originalToken; + this.argumentPasted = false; + } + + @Override + MacroTokenSource getExpandingRoot() { + final Source parent = getParent(); + if (parent == null || !parent.isExpanding()) { + return this; + } + return parent.getExpandingRoot(); + } + + @Override + boolean isExpanding() { + return true; } @Override @@ -81,6 +124,31 @@ private void concat(StringBuilder buf, Argument arg) { } private Token stringify(Token pos, Argument arg) { + // Set the data for the position tracing + final MacroTokenSource expandingRoot = getExpandingRoot(); + assert expandingRoot != null; + final Token expandingRootToken = expandingRoot.getOriginalToken(); + Token origToken = null; // original token to set in the result of this method + if (arg.size() > 0) { + final Token argFirstTok = arg.get(0); + final Token argFirstTokOrigTok = argFirstTok.getOriginalMacroToken(); + + if (expandingRoot.argumentContains(argFirstTok)) { + pos = argFirstTokOrigTok != null + ? argFirstTokOrigTok + : argFirstTok; + origToken = argFirstTokOrigTok != null + ? argFirstTokOrigTok + : null; + } else { + pos = expandingRootToken; + origToken = expandingRootToken; + } + } else { + pos = expandingRootToken; + origToken = expandingRootToken; + } + StringBuilder buf = new StringBuilder(); concat(buf, arg); // System.out.println("Concat: " + arg + " -> " + buf); @@ -88,9 +156,15 @@ private Token stringify(Token pos, Argument arg) { escape(str, buf); str.append("\""); // System.out.println("Escape: " + buf + " -> " + str); - return new Token(STRING, + + final Token result = new Token(STRING, pos.getLine(), pos.getColumn(), str.toString(), buf.toString()); + result.setStringized(true); + if (origToken != null) { + result.setOriginalMacroToken(origToken); + } + return result; } @@ -146,6 +220,7 @@ private void paste(Token ptok) /* XXX Check that concatenation produces a valid token. */ arg = new SourceIterator(sl); + argumentPasted = true; } public Token token() @@ -160,9 +235,10 @@ public Token token() /* XXX PASTE -> INVALID. */ assert tok.getType() != M_PASTE : "Unexpected paste token"; - return tok; + return argumentPasted ? withOriginalToken(tok) : tok; } arg = null; + argumentPasted = false; } if (!tokens.hasNext()) @@ -185,12 +261,65 @@ public Token token() paste(tok); break; default: - return tok; + return withOriginalToken(tok); } } /* for */ } + /** + * Sets the original token of the given one to the original token from the + * source code (but not from a macro definition) that caused expansion of + * a macro that this object is result of. + * + * @param token Token whose original one is to be assigned. + * @return The given token. + */ + private Token withOriginalToken(Token token) { + assert token != null; + token.setOriginalMacroToken(getExpandingRootToken()); + return token; + } + + /** + * @return Token with a macro identifier that caused the appearance of this + * Source object. + */ + Token getOriginalToken() { + return originalToken; + } + + /** + * @return True if and only if the given token is a token from an argument + * expansion or the actual argument of a macro use that this object + * represents. + */ + boolean argumentContains(Token tok) { + if (args == null) { + return false; + } + + for (Argument arg : args) { + // Check if the token comes from an argument expansion + final Iterator<Token> argumentExpansion = arg.expansion(); + while (argumentExpansion.hasNext()) { + if (argumentExpansion.next() == tok) { + return true; + } + } + + /* Check if the token comes from the original expression passed as + an argument (before its expansion) */ + for (Token argTokBeforeExpansion : arg) { + if (argTokBeforeExpansion == tok) { + return true; + } + } + } + + return false; + } + @Override public String toString() { StringBuilder buf = new StringBuilder(); diff --git a/src/main/java/org/anarres/cpp/Main.java b/src/main/java/org/anarres/cpp/Main.java index 1902798..4c50b70 100644 --- a/src/main/java/org/anarres/cpp/Main.java +++ b/src/main/java/org/anarres/cpp/Main.java @@ -92,7 +92,7 @@ public void run(String[] args) throws Exception { pp.addFeature(Feature.TRIGRAPHS); pp.addFeature(Feature.LINEMARKERS); pp.addWarning(Warning.IMPORT); - pp.setListener(new PreprocessorListener()); + pp.setListener(new DefaultPreprocessorListener()); pp.addMacro("__JCPP__"); pp.getSystemIncludePath().add("/usr/local/include"); pp.getSystemIncludePath().add("/usr/include"); diff --git a/src/main/java/org/anarres/cpp/NumericValue.java b/src/main/java/org/anarres/cpp/NumericValue.java index 8d961c4..e38d28f 100644 --- a/src/main/java/org/anarres/cpp/NumericValue.java +++ b/src/main/java/org/anarres/cpp/NumericValue.java @@ -18,6 +18,10 @@ import java.math.BigDecimal; import java.math.BigInteger; +import javax.annotation.CheckForNull; +import javax.annotation.CheckForSigned; +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; public class NumericValue extends Number { @@ -33,6 +37,7 @@ public class NumericValue extends Number { private final int base; private final String integer; private String fraction; + private int expbase = 0; private String exponent; private int flags; @@ -41,14 +46,17 @@ public NumericValue(int base, String integer) { this.integer = integer; } + @Nonnegative public int getBase() { return base; } + @Nonnull public String getIntegerPart() { return integer; } + @CheckForNull public String getFractionalPart() { return fraction; } @@ -57,11 +65,18 @@ public String getFractionalPart() { this.fraction = fraction; } + @CheckForSigned + public int getExponentBase() { + return expbase; + } + + @CheckForNull public String getExponent() { return exponent; } - /* pp */ void setExponent(String exponent) { + /* pp */ void setExponent(int expbase, String exponent) { + this.expbase = expbase; this.exponent = exponent; } @@ -78,6 +93,7 @@ public int getFlags() { * precision numbers is nontrivial, and this routine gets it wrong * in many important cases. */ + @Nonnull public BigDecimal toBigDecimal() { int scale = 0; String text = getIntegerPart(); @@ -93,6 +109,7 @@ public BigDecimal toBigDecimal() { return new BigDecimal(unscaled, scale); } + @Nonnull public Number toJavaLangNumber() { int flags = getFlags(); if ((flags & F_DOUBLE) != 0) @@ -111,23 +128,41 @@ else if (getExponent() != null) return intValue(); } + private int exponentValue() { + return Integer.parseInt(exponent, 10); + } + @Override public int intValue() { - return Integer.parseInt(toString()); + int v = integer.isEmpty() ? 0 : Integer.parseInt(integer, base); + if (expbase == 2) + v = v << exponentValue(); + else if (expbase != 0) + v = (int) (v * Math.pow(expbase, exponentValue())); + return v; } @Override public long longValue() { - return Long.parseLong(toString()); + long v = integer.isEmpty() ? 0 : Long.parseLong(integer, base); + if (expbase == 2) + v = v << exponentValue(); + else if (expbase != 0) + v = (int) (v * Math.pow(expbase, exponentValue())); + return v; } @Override public float floatValue() { + if (getBase() != 10) + return longValue(); return Float.parseFloat(toString()); } @Override public double doubleValue() { + if (getBase() != 10) + return longValue(); return Double.parseDouble(toString()); } diff --git a/src/main/java/org/anarres/cpp/Preprocessor.java b/src/main/java/org/anarres/cpp/Preprocessor.java index e4ecdc1..9ba241e 100644 --- a/src/main/java/org/anarres/cpp/Preprocessor.java +++ b/src/main/java/org/anarres/cpp/Preprocessor.java @@ -47,31 +47,31 @@ * {@link CppReader}, which does this.) */ /* - Source file name and line number information is conveyed by lines of the form - - # linenum filename flags - - These are called linemarkers. They are inserted as needed into - the output (but never within a string or character constant). They - mean that the following line originated in file filename at line - linenum. filename will never contain any non-printing characters; - they are replaced with octal escape sequences. - - After the file name comes zero or more flags, which are `1', `2', - `3', or `4'. If there are multiple flags, spaces separate them. Here - is what the flags mean: - - `1' - This indicates the start of a new file. - `2' - This indicates returning to a file (after having included another - file). - `3' - This indicates that the following text comes from a system header - file, so certain warnings should be suppressed. - `4' - This indicates that the following text should be treated as being - wrapped in an implicit extern "C" block. + * Source file name and line number information is conveyed by lines of the form + * + * # linenum filename flags + * + * These are called linemarkers. They are inserted as needed into + * the output (but never within a string or character constant). They + * mean that the following line originated in file filename at line + * linenum. filename will never contain any non-printing characters; + * they are replaced with octal escape sequences. + * + * After the file name comes zero or more flags, which are `1', `2', + * `3', or `4'. If there are multiple flags, spaces separate them. Here + * is what the flags mean: + * + * `1' + * This indicates the start of a new file. + * `2' + * This indicates returning to a file (after having included another + * file). + * `3' + * This indicates that the following text comes from a system header + * file, so certain warnings should be suppressed. + * `4' + * This indicates that the following text should be treated as being + * wrapped in an implicit extern "C" block. */ public class Preprocessor implements Closeable { @@ -292,7 +292,7 @@ public void addInput(@Nonnull File file) * If a PreprocessorListener is installed, it receives the * error. Otherwise, an exception is thrown. */ - protected void error(int line, int column, String msg) + protected void error(int line, int column, @Nonnull String msg) throws LexerException { if (listener != null) listener.handleError(source, line, column, msg); @@ -300,6 +300,43 @@ protected void error(int line, int column, String msg) throw new LexerException("Error at " + line + ":" + column + ": " + msg); } + /** + * Handles a preprocessor directive. + * + * If a PreprocessorListener is installed, it receives the + * directive. Otherwise, it is ignored. + */ + protected void directive(PreprocessorDirective directive) { + if (listener != null) { + listener.handlePreprocesorDirective(getSource(), directive); + } + } + + protected void macroExpansion(Macro macro, Token identifier, boolean inExpandingSources) { + if (listener != null && (inExpandingSources || !getSource().isExpanding())) { + // Source can be null + final String definitionFileName = macro.getSource() != null ? macro.getSource().getPath() : null; + + listener.handleMacroExpansion(getSource(), identifier.getLine(), + identifier.getColumn(), identifier.getText(), definitionFileName, + macro.getNameStartLine(), macro.getNameStartColumn()); + } + } + + /** + * Marks all tokens that are part of macro definition. Therefore, when + * the macro is expanded and macro's tokens are returned by preprocessor, + * these tokens can be easily distinguished from tokens that comes from + * source file. + * + * @param m macro + */ + protected void markTokens(Macro m) { + for (Token token : m.getTokens()) { + token.setExpanded(true); + } + } + /** * Handles an error. * @@ -308,7 +345,7 @@ protected void error(int line, int column, String msg) * * @see #error(int, int, String) */ - protected void error(Token tok, String msg) + protected void error(@Nonnull Token tok, @Nonnull String msg) throws LexerException { error(tok.getLine(), tok.getColumn(), msg); } @@ -319,7 +356,7 @@ protected void error(Token tok, String msg) * If a PreprocessorListener is installed, it receives the * warning. Otherwise, an exception is thrown. */ - protected void warning(int line, int column, String msg) + protected void warning(int line, int column, @Nonnull String msg) throws LexerException { if (warnings.contains(Warning.ERROR)) error(line, column, msg); @@ -337,7 +374,7 @@ else if (listener != null) * * @see #warning(int, int, String) */ - protected void warning(Token tok, String msg) + protected void warning(@Nonnull Token tok, @Nonnull String msg) throws LexerException { warning(tok.getLine(), tok.getColumn(), msg); } @@ -348,12 +385,12 @@ protected void warning(Token tok, String msg) * The given {@link Macro} object encapsulates both the name * and the expansion. */ - public void addMacro(Macro m) throws LexerException { - // System.out.println("Macro " + m); + public void addMacro(@Nonnull Macro m) throws LexerException { String name = m.getName(); /* Already handled as a source error in macro(). */ if ("defined".equals(name)) throw new LexerException("Cannot redefine name 'defined'"); + markTokens(m); macros.put(m.getName(), m); } @@ -363,7 +400,7 @@ public void addMacro(Macro m) throws LexerException { * The String value is lexed into a token stream, which is * used as the macro expansion. */ - public void addMacro(String name, String value) + public void addMacro(@Nonnull String name, @Nonnull String value) throws LexerException { try { Macro m = new Macro(name); @@ -386,7 +423,7 @@ public void addMacro(String name, String value) * This is a convnience method, and is equivalent to * <code>addMacro(name, "1")</code>. */ - public void addMacro(String name) + public void addMacro(@Nonnull String name) throws LexerException { addMacro(name, "1"); } @@ -395,7 +432,7 @@ public void addMacro(String name) * Sets the user include path used by this Preprocessor. */ /* Note for future: Create an IncludeHandler? */ - public void setQuoteIncludePath(List<String> path) { + public void setQuoteIncludePath(@Nonnull List<String> path) { this.quoteincludepath = path; } @@ -404,6 +441,7 @@ public void setQuoteIncludePath(List<String> path) { * * This list may be freely modified by user code. */ + @Nonnull public List<String> getQuoteIncludePath() { return quoteincludepath; } @@ -412,7 +450,7 @@ public List<String> getQuoteIncludePath() { * Sets the system include path used by this Preprocessor. */ /* Note for future: Create an IncludeHandler? */ - public void setSystemIncludePath(List<String> path) { + public void setSystemIncludePath(@Nonnull List<String> path) { this.sysincludepath = path; } @@ -421,6 +459,7 @@ public void setSystemIncludePath(List<String> path) { * * This list may be freely modified by user code. */ + @Nonnull public List<String> getSystemIncludePath() { return sysincludepath; } @@ -429,7 +468,7 @@ public List<String> getSystemIncludePath() { * Sets the Objective-C frameworks path used by this Preprocessor. */ /* Note for future: Create an IncludeHandler? */ - public void setFrameworksPath(List<String> path) { + public void setFrameworksPath(@Nonnull List<String> path) { this.frameworkspath = path; } @@ -439,6 +478,7 @@ public void setFrameworksPath(List<String> path) { * * This list may be freely modified by user code. */ + @Nonnull public List<String> getFrameworksPath() { return frameworkspath; } @@ -447,6 +487,7 @@ public List<String> getFrameworksPath() { * Returns the Map of Macros parsed during the run of this * Preprocessor. */ + @Nonnull public Map<String, Macro> getMacros() { return macros; } @@ -457,6 +498,7 @@ public Map<String, Macro> getMacros() { * While you can modify the returned object, unexpected things * might happen if you do. */ + @CheckForNull public Macro getMacro(String name) { return macros.get(name); } @@ -765,8 +807,8 @@ private boolean macro(Macro m, Token orig) } /* - for (Argument a : args) - a.expand(this); + * for (Argument a : args) + * a.expand(this); */ for (int i = 0; i < args.size(); i++) { args.get(i).expand(this); @@ -783,12 +825,14 @@ private boolean macro(Macro m, Token orig) args = null; } + macroExpansion(m, orig, false); + if (m == __LINE__) { push_source(new FixedTokenSource( new Token[]{new Token(NUMBER, orig.getLine(), orig.getColumn(), - String.valueOf(orig.getLine()), - new NumericValue(10, "" + orig.getLine()))} + Integer.toString(orig.getLine()), + new NumericValue(10, Integer.toString(orig.getLine())))} ), true); } else if (m == __FILE__) { StringBuilder buf = new StringBuilder("\""); @@ -823,11 +867,11 @@ private boolean macro(Macro m, Token orig) push_source(new FixedTokenSource( new Token[]{new Token(NUMBER, orig.getLine(), orig.getColumn(), - String.valueOf(value), - new NumericValue(10, "" + value))} + Integer.toString(value), + new NumericValue(10, Integer.toString(value)))} ), true); } else { - push_source(new MacroTokenSource(m, args), true); + push_source(new MacroTokenSource(m, args, orig), true); } return true; @@ -875,10 +919,11 @@ private boolean macro(Macro m, Token orig) } /* processes a #define directive */ - private Token define() + private Token define(@Nonnull PreprocessorDirective preprocessorDirective) throws IOException, LexerException { Token tok = source_token_nonwhite(); + preprocessorDirective.addToken(tok); if (tok.getType() != IDENTIFIER) { error(tok, "Expected identifier"); return source_skipline(false); @@ -891,12 +936,14 @@ private Token define() return source_skipline(false); } - Macro m = new Macro(getSource(), name); + Macro m = new Macro(getSource(), name, tok.getLine(), tok.getColumn()); List<String> args; tok = source_token(); if (tok.getType() == '(') { + preprocessorDirective.addToken(tok); tok = source_token_nonwhite(); + preprocessorDirective.addToken(tok); if (tok.getType() != ')') { args = new ArrayList<String>(); ARGS: @@ -924,6 +971,7 @@ private Token define() return source_skipline(false); } tok = source_token_nonwhite(); + preprocessorDirective.addToken(tok); switch (tok.getType()) { case ',': break; @@ -950,6 +998,7 @@ private Token define() return source_skipline(false); } tok = source_token_nonwhite(); + preprocessorDirective.addToken(tok); } } else { assert tok.getType() == ')' : "Expected ')'"; @@ -970,6 +1019,7 @@ private Token define() /* Ensure no space at start. */ tok = source_token_nonwhite(); + preprocessorDirective.addToken(tok); EXPANSION: for (;;) { switch (tok.getType()) { @@ -1039,8 +1089,11 @@ private Token define() break; } tok = source_token(); + preprocessorDirective.addToken(tok); } + directive(preprocessorDirective); + if (getFeature(Feature.DEBUG)) System.err.println("Defined macro " + m); addMacro(m); @@ -1050,21 +1103,23 @@ private Token define() } @Nonnull - private Token undef() + private Token undef(@Nonnull PreprocessorDirective preprocessorDirective) throws IOException, LexerException { Token tok = source_token_nonwhite(); + preprocessorDirective.addToken(tok); if (tok.getType() != IDENTIFIER) { error(tok, "Expected identifier, not " + tok.getText()); if (tok.getType() == NL || tok.getType() == EOF) return tok; } else { - Macro m = macros.get(tok.getText()); + Macro m = getMacro(tok.getText()); if (m != null) { /* XXX error if predefined */ macros.remove(m.getName()); } + directive(preprocessorDirective); } return source_skipline(true); } @@ -1075,12 +1130,22 @@ private Token undef() * User code may override this method to implement a virtual * file system. */ - protected boolean include(@Nonnull VirtualFile file) + protected boolean include(@Nonnull VirtualFile file, int line) throws IOException, LexerException { // System.out.println("Try to include " + ((File)file).getAbsolutePath()); if (!file.isFile()) return false; + if (listener != null) { + if (getFeature(Feature.DEBUG)) + System.out.println("Trying to include " + file.getPath()); + if (listener.beforeInclude(file.getPath(), line)) { + // push_source() omitted + if (getFeature(Feature.DEBUG)) + System.err.println("pp: skipping " + file); + return true; + } + } if (getFeature(Feature.DEBUG)) System.err.println("pp: including " + file); push_source(file.getSource(), true); @@ -1090,12 +1155,12 @@ protected boolean include(@Nonnull VirtualFile file) /** * Includes a file from an include path, by name. */ - protected boolean include(@Nonnull Iterable<String> path, @Nonnull String name) + protected boolean include(@Nonnull Iterable<String> path, @Nonnull String name, int line) throws IOException, LexerException { for (String dir : path) { VirtualFile file = filesystem.getFile(dir, name); - if (include(file)) + if (include(file, line)) return true; } return false; @@ -1117,14 +1182,14 @@ private void include( } if (pdir != null) { VirtualFile ifile = pdir.getChildFile(name); - if (include(ifile)) + if (include(ifile, line)) return; } - if (include(quoteincludepath, name)) + if (include(quoteincludepath, name, line)) return; } - if (include(sysincludepath, name)) + if (include(sysincludepath, name, line)) return; StringBuilder buf = new StringBuilder(); @@ -1141,13 +1206,14 @@ private void include( } @Nonnull - private Token include(boolean next) + private Token include(boolean next, @Nonnull PreprocessorDirective preprocessorDirective) throws IOException, LexerException { LexerSource lexer = (LexerSource) source; try { lexer.setInclude(true); Token tok = token_nonwhite(); + preprocessorDirective.addToken(tok); String name; boolean quoted; @@ -1159,6 +1225,7 @@ private Token include(boolean next) HEADER: for (;;) { tok = token_nonwhite(); + preprocessorDirective.addToken(tok); switch (tok.getType()) { case STRING: buf.append((String) tok.getValue()); @@ -1190,7 +1257,7 @@ private Token include(boolean next) return source_skipline(false); } } - + directive(preprocessorDirective); /* Do the inclusion. */ include(source.getPath(), tok.getLine(), name, quoted, next); @@ -1228,7 +1295,7 @@ protected void pragma(@Nonnull Token name, @Nonnull List<Token> value) } @Nonnull - private Token pragma() + private Token pragma(@Nonnull PreprocessorDirective preprocessorDirective) throws IOException, LexerException { Token name; @@ -1236,6 +1303,7 @@ private Token pragma() NAME: for (;;) { Token tok = token(); + preprocessorDirective.addToken(tok); switch (tok.getType()) { case EOF: /* There ought to be a newline before EOF. @@ -1266,6 +1334,7 @@ private Token pragma() VALUE: for (;;) { tok = token(); + preprocessorDirective.addToken(tok); switch (tok.getType()) { case EOF: /* There ought to be a newline before EOF. @@ -1289,6 +1358,7 @@ private Token pragma() } } + directive(preprocessorDirective); pragma(name, value); return tok; /* The NL. */ @@ -1296,13 +1366,14 @@ private Token pragma() } /* For #error and #warning. */ - private void error(@Nonnull Token pptok, boolean is_error) + private void error(@Nonnull Token pptok, boolean is_error, @Nonnull PreprocessorDirective preprocessorDirective) throws IOException, LexerException { StringBuilder buf = new StringBuilder(); buf.append('#').append(pptok.getText()).append(' '); /* Peculiar construction to ditch first whitespace. */ Token tok = source_token_nonwhite(); + preprocessorDirective.addToken(tok); ERROR: for (;;) { switch (tok.getType()) { @@ -1314,11 +1385,14 @@ private void error(@Nonnull Token pptok, boolean is_error) break; } tok = source_token(); + preprocessorDirective.addToken(tok); } if (is_error) error(pptok, buf.toString()); else warning(pptok, buf.toString()); + + directive(preprocessorDirective); } /* This bypasses token() for #elif expressions. @@ -1332,7 +1406,7 @@ private Token expanded_token() Token tok = source_token(); // System.out.println("Source token is " + tok); if (tok.getType() == IDENTIFIER) { - Macro m = macros.get(tok.getText()); + Macro m = getMacro(tok.getText()); if (m == null) return tok; if (source.isExpanding(m)) @@ -1474,9 +1548,9 @@ private long expr(int priority) throws IOException, LexerException { /* - System.out.flush(); - (new Exception("expr(" + priority + ") called")).printStackTrace(); - System.err.flush(); + * System.out.flush(); + * (new Exception("expr(" + priority + ") called")).printStackTrace(); + * System.err.flush(); */ Token tok = expr_token(); @@ -1615,9 +1689,9 @@ private long expr(int priority) } /* - System.out.flush(); - (new Exception("expr returning " + lhs)).printStackTrace(); - System.err.flush(); + * System.out.flush(); + * (new Exception("expr returning " + lhs)).printStackTrace(); + * System.err.flush(); */ // System.out.println("expr returning " + lhs); return lhs; @@ -1675,6 +1749,9 @@ private Token _token() source.setActive(false); tok = source_token(); } finally { + if (source == null) { + throw new LexerException("Requested a token with a null Source"); + } /* XXX Tell lexer to stop ignoring warnings. */ source.setActive(true); } @@ -1783,7 +1860,7 @@ private Token _token() return tok; case IDENTIFIER: - Macro m = macros.get(tok.getText()); + Macro m = getMacro(tok.getText()); if (m == null) return tok; if (source.isExpanding(m)) @@ -1807,7 +1884,10 @@ private Token _token() // break; case HASH: + PreprocessorDirective preprocessorDirective = new PreprocessorDirective(); + preprocessorDirective.addToken(tok); tok = source_token_nonwhite(); + preprocessorDirective.addToken(tok); // (new Exception("here")).printStackTrace(); switch (tok.getType()) { case NL: @@ -1828,6 +1908,7 @@ private Token _token() + tok.getText()); return source_skipline(false); } + preprocessorDirective.setCommand(ppcmd); PP: switch (ppcmd) { @@ -1836,21 +1917,21 @@ private Token _token() if (!isActive()) return source_skipline(false); else - return define(); + return define(preprocessorDirective); // break; case PP_UNDEF: if (!isActive()) return source_skipline(false); else - return undef(); + return undef(preprocessorDirective); // break; case PP_INCLUDE: if (!isActive()) return source_skipline(false); else - return include(false); + return include(false, preprocessorDirective); // break; case PP_INCLUDE_NEXT: if (!isActive()) @@ -1861,7 +1942,7 @@ private Token _token() ); return source_skipline(false); } - return include(true); + return include(true, preprocessorDirective); // break; case PP_WARNING: @@ -1869,7 +1950,7 @@ private Token _token() if (!isActive()) return source_skipline(false); else - error(tok, ppcmd == PP_ERROR); + error(tok, ppcmd == PP_ERROR, preprocessorDirective); break; case PP_IF: @@ -1880,6 +1961,9 @@ private Token _token() expr_token = null; states.peek().setActive(expr(0) != 0); tok = expr_token(); /* unget */ + if (!states.peek().isActive()) + preprocessorDirective.setInactiveBlock(); + directive(preprocessorDirective); if (tok.getType() == NL) return tok; @@ -1899,6 +1983,8 @@ private Token _token() return source_skipline(false); } else if (state.isActive()) { /* The 'if' part got executed. */ + preprocessorDirective.setInactiveBlock(); + directive(preprocessorDirective); state.setParentActive(false); /* This is like # else # if but with * only one # end. */ @@ -1907,6 +1993,9 @@ private Token _token() } else { expr_token = null; state.setActive(expr(0) != 0); + if (!state.isActive()) + preprocessorDirective.setInactiveBlock(); + directive(preprocessorDirective); tok = expr_token(); /* unget */ if (tok.getType() == NL) @@ -1917,14 +2006,18 @@ private Token _token() case PP_ELSE: state = states.peek(); - if (false) - /* Check for 'if' */ ; else if (state.sawElse()) { + if (false) { + /* Check for 'if' */ ; + } else if (state.sawElse()) { error(tok, "#" + "else after #" + "else"); return source_skipline(false); } else { state.setSawElse(); state.setActive(!state.isActive()); + if (!state.isActive()) + preprocessorDirective.setInactiveBlock(); + directive(preprocessorDirective); return source_skipline(warnings.contains(Warning.ENDIF_LABELS)); } // break; @@ -1940,12 +2033,17 @@ private Token _token() error(tok, "Expected identifier, not " + tok.getText()); + directive(preprocessorDirective); return source_skipline(false); } else { + preprocessorDirective.addToken(tok); String text = tok.getText(); boolean exists = macros.containsKey(text); states.peek().setActive(exists); + if (!exists) + preprocessorDirective.setInactiveBlock(); + directive(preprocessorDirective); return source_skipline(true); } } @@ -1961,12 +2059,17 @@ private Token _token() error(tok, "Expected identifier, not " + tok.getText()); + directive(preprocessorDirective); return source_skipline(false); } else { + preprocessorDirective.addToken(tok); String text = tok.getText(); boolean exists = macros.containsKey(text); states.peek().setActive(!exists); + if (exists) + preprocessorDirective.setInactiveBlock(); + directive(preprocessorDirective); return source_skipline(true); } } @@ -1974,17 +2077,19 @@ private Token _token() case PP_ENDIF: pop_state(); + directive(preprocessorDirective); return source_skipline(warnings.contains(Warning.ENDIF_LABELS)); // break; case PP_LINE: + directive(preprocessorDirective); return source_skipline(false); // break; case PP_PRAGMA: if (!isActive()) return source_skipline(false); - return pragma(); + return pragma(preprocessorDirective); // break; default: @@ -2050,7 +2155,7 @@ public String toString() { Iterator<String> mt = keys.iterator(); while (mt.hasNext()) { String key = mt.next(); - Macro macro = macros.get(key); + Macro macro = getMacro(key); buf.append("#").append("macro ").append(macro).append("\n"); } diff --git a/src/main/java/org/anarres/cpp/PreprocessorDirective.java b/src/main/java/org/anarres/cpp/PreprocessorDirective.java new file mode 100644 index 0000000..1bb0dea --- /dev/null +++ b/src/main/java/org/anarres/cpp/PreprocessorDirective.java @@ -0,0 +1,57 @@ +package org.anarres.cpp; + +import javax.annotation.Nonnull; +import java.lang.String; +import java.util.ArrayList; +import java.util.List; + +/** + * Represents all the tokens that form a single preprocessor directive. + * Additionally informs if the block after + */ +public class PreprocessorDirective { + private final List<Token> directiveTokens = new ArrayList<>(); + private boolean activeBlock = true; + private PreprocessorCommand command; + + public PreprocessorDirective() { + } + + public void addToken(@Nonnull Token token) { + directiveTokens.add(token); + } + + public void setCommand(PreprocessorCommand cmd) { + this.command = cmd; + } + + public PreprocessorCommand getCommand() { + return this.command; + } + + @Nonnull + public List<Token> getTokenList() { return this.directiveTokens; } + + public boolean isActiveBlock() { + return this.activeBlock; + } + + public void setInactiveBlock() { + this.activeBlock = false; + } + + @Override + public String toString() { + String result = new String(); + if (!activeBlock) + result += "inactive block "; + for (Token tok : directiveTokens) { + if (tok.getType() == Token.NL) { + result += " \\n"; + } else { + result += " " + tok.getText(); + } + } + return result; + } +} diff --git a/src/main/java/org/anarres/cpp/PreprocessorListener.java b/src/main/java/org/anarres/cpp/PreprocessorListener.java index a5b4339..cf2757b 100644 --- a/src/main/java/org/anarres/cpp/PreprocessorListener.java +++ b/src/main/java/org/anarres/cpp/PreprocessorListener.java @@ -23,31 +23,7 @@ * error and warning events will throw an exception. Installing a * listener allows more intelligent handling of these events. */ -public class PreprocessorListener { - - private int errors; - private int warnings; - - public PreprocessorListener() { - clear(); - } - - public void clear() { - errors = 0; - warnings = 0; - } - - public int getErrors() { - return errors; - } - - public int getWarnings() { - return warnings; - } - - protected void print(String msg) { - System.err.println(msg); - } +public interface PreprocessorListener { /** * Handles a warning. @@ -58,11 +34,7 @@ protected void print(String msg) { */ public void handleWarning(Source source, int line, int column, String msg) - throws LexerException { - warnings++; - print(source.getName() + ":" + line + ":" + column - + ": warning: " + msg); - } + throws LexerException; /** * Handles an error. @@ -73,13 +45,30 @@ public void handleWarning(Source source, int line, int column, */ public void handleError(Source source, int line, int column, String msg) - throws LexerException { - errors++; - print(source.getName() + ":" + line + ":" + column - + ": error: " + msg); - } + throws LexerException; + + public void handleSourceChange(Source source, String event); - public void handleSourceChange(Source source, String event) { - } + /** + * Called when preprocessor is about to include file. + * + * @param filePath file path + * @param line line of include directive + * @return <code>true</code> if specified file should be skipped, + * <code>false</code> otherwise + */ + public boolean beforeInclude(String filePath, int line); + + public void handlePreprocesorDirective(Source source, PreprocessorDirective directive); + + /** + * @param definitionFileName Can be null in certain cases. + * @param definitionLine <code>Macro.UNKNOWN_POSITION_VALUE</code> if it is + * unknown, otherwise proper value + * @param definitionColumn <code>Macro.UNKNOWN_POSITION_VALUE</code> if it + * is unknown, otherwise proper value + */ + public void handleMacroExpansion(Source source, int line, int column, String macro, + String definitionFileName, int definitionLine, int definitionColumn); } diff --git a/src/main/java/org/anarres/cpp/Source.java b/src/main/java/org/anarres/cpp/Source.java index ef20803..e6df101 100644 --- a/src/main/java/org/anarres/cpp/Source.java +++ b/src/main/java/org/anarres/cpp/Source.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.util.Iterator; import javax.annotation.CheckForNull; +import javax.annotation.Nonnegative; import javax.annotation.Nonnull; import static org.anarres.cpp.Token.*; @@ -129,7 +130,7 @@ public void setListener(PreprocessorListener pl) { * If no Source on the stack is a FileLexerSource, returns null. */ @CheckForNull - /* pp */ String getPath() { + public String getPath() { Source parent = getParent(); if (parent != null) return parent.getPath(); @@ -139,7 +140,8 @@ public void setListener(PreprocessorListener pl) { /** * Returns the human-readable name of the current Source. */ - /* pp */ String getName() { + @CheckForNull + public String getName() { Source parent = getParent(); if (parent != null) return parent.getName(); @@ -149,6 +151,7 @@ public void setListener(PreprocessorListener pl) { /** * Returns the current line number within this Source. */ + @Nonnegative public int getLine() { Source parent = getParent(); if (parent == null) @@ -166,6 +169,42 @@ public int getColumn() { return parent.getColumn(); } + /** + * @return Source object that represents the root of the macro expansion + * if it is currently in progress. If no macro expansion is + * currently in progress, returns null. + */ + MacroTokenSource getExpandingRoot() { + final Source parent = getParent(); + if (parent == null) { + return null; + } + return parent.getExpandingRoot(); + } + + /** + * @return Token with a macro identifier in the source code (not from + * a macro definition) that caused appearance of this source. + * If no macro is currently being expanded, null is returned. + */ + final Token getExpandingRootToken() { + final MacroTokenSource expandingRoot = getExpandingRoot(); + if (expandingRoot != null) { + return expandingRoot.getOriginalToken(); + } + return null; + } + + /*** + * Returns true if this Source is expanding any macro. + */ + boolean isExpanding() { + Source parent = getParent(); + if (parent != null) + return parent.isExpanding(); + return false; + } + /** * Returns true if this Source is expanding the given macro. * diff --git a/src/main/java/org/anarres/cpp/Token.java b/src/main/java/org/anarres/cpp/Token.java index 3e6eb3e..5cdf229 100644 --- a/src/main/java/org/anarres/cpp/Token.java +++ b/src/main/java/org/anarres/cpp/Token.java @@ -21,22 +21,46 @@ * * @see Preprocessor */ -public final class Token { +public final class Token implements Cloneable { // public static final int EOF = -1; private final int type; + private final int expected_type; private int line; private int column; private final Object value; private final String text; + /** + * Indicates that token comes from macro expansion. + */ + private boolean isExpanded; + /** + * Token that this one replaced (because of a macro expansion). + * It can be null. + */ + private Token originalMacroToken; + /** + * True if and only if the token comes from a macro argument stringizing, + * e.g. as the result of use of a macro defined as follows: + * #define STRINGIZE(x) #x + */ + private boolean isStringized; - public Token(int type, int line, int column, + public Token(int type, int expected, int line, int column, String text, Object value) { this.type = type; + this.expected_type = expected; this.line = line; this.column = column; this.text = text; this.value = value; + this.isExpanded = false; + this.isStringized = false; + } + + public Token(int type, int line, int column, + String text, Object value) { + this(type, -1, line, column, text, value); } public Token(int type, int line, int column, String text) { @@ -47,14 +71,26 @@ public Token(int type, int line, int column, String text) { this(type, -1, -1, text, value); } + Token(int type, int expected, String text, Object value) { + this(type, expected, -1, -1, text, value); + } + /* pp */ Token(int type, String text) { this(type, text, null); } + Token(int type, int expected, String text) { + this(type, expected, text, null); + } + /* pp */ Token(int type) { this(type, TokenType.getTokenText(type)); } + Token(int type, int expected) { + this(type, expected, TokenType.getTokenText(type)); + } + /** * Returns the semantic type of this token. */ @@ -62,6 +98,13 @@ public int getType() { return type; } + /** + * If the token type is INVALID returns the expected type of this token. + */ + public int getExpectedType() { + return expected_type; + } + /* pp */ void setLocation(int line, int column) { this.line = line; this.column = column; @@ -109,6 +152,65 @@ public Object getValue() { return value; } + /** + * Returns if token comes from macro expansion. + * + * @return <code>true</code> when macro comes from macro expansion + */ + public boolean isExpanded() { + return isExpanded; + } + + /** + * @return True if and only if the token comes from a use of operator '#' + * in a macro definition. + */ + public boolean isStringized() { + return isStringized; + } + + /** + * @return Token that has been replaced by this one (and possibly some other + * ones) because of macro expansion. It can be null even if a macro + * expansion has happened. + * If it is not null, it is never a token from a macro definition. + */ + public Token getOriginalMacroToken() { + return originalMacroToken; + } + + /* pp */ void setExpanded(boolean isExpanded) { + this.isExpanded = isExpanded; + } + + /** + * Sets the <code>isStringized</code> flag to the given value. + * + * @param isStringized Value of the <code>isStringized</code> flag to set. + */ + void setStringized(boolean isStringized) { + this.isStringized = isStringized; + } + + /** + * Unconditionally sets the original macro token of this object to the given + * one. + * + * @param originalMacroToken Original macro token of this object. It can be null. + */ + void setOriginalMacroToken(Token originalMacroToken) { + this.originalMacroToken = originalMacroToken; + } + + /** + * @return Shallow copy of this token (all references in the returned object + * are the same as in this one). + */ + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + /** * Returns a description of this token, for debugging purposes. */ @@ -122,6 +224,8 @@ public String toString() { if (column != -1) buf.append(',').append(column); } + if (isExpanded) + buf.append("(expanded)"); buf.append("]:"); if (text != null) buf.append('"').append(text).append('"'); diff --git a/src/test/java/org/anarres/cpp/ErrorTest.java b/src/test/java/org/anarres/cpp/ErrorTest.java index 8777452..42240d4 100644 --- a/src/test/java/org/anarres/cpp/ErrorTest.java +++ b/src/test/java/org/anarres/cpp/ErrorTest.java @@ -22,7 +22,7 @@ private boolean testError(Preprocessor p) private void testError(String input) throws Exception { StringLexerSource sl; - PreprocessorListener pl; + DefaultPreprocessorListener pl; Preprocessor p; /* Without a PreprocessorListener, throws an exception. */ @@ -42,7 +42,7 @@ private void testError(String input) throws Exception { p = new Preprocessor(); p.addFeature(Feature.CSYNTAX); p.addInput(sl); - pl = new PreprocessorListener(); + pl = new DefaultPreprocessorListener(); p.setListener(pl); assertNotNull("CPP has listener", p.getListener()); assertTrue(testError(p)); diff --git a/src/test/java/org/anarres/cpp/IsExpandedFlagTest.java b/src/test/java/org/anarres/cpp/IsExpandedFlagTest.java new file mode 100644 index 0000000..292e422 --- /dev/null +++ b/src/test/java/org/anarres/cpp/IsExpandedFlagTest.java @@ -0,0 +1,128 @@ +package org.anarres.cpp; + +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Grzegorz Kołakowski <gk291583@students.mimuw.edu.pl> + */ +public class IsExpandedFlagTest { + + private Preprocessor preprocessor; + + @Before + public void setUp() throws Exception { + preprocessor = new Preprocessor(); + } + + @Test + public void testSimpleExpansion() throws Exception { + final List<Token> tokens = getTokens("is_expanded_flag/simple_expansion.c"); + System.out.println(tokens); + + assertEquals(10, tokens.size()); + + for (int i = 0; i < 10; ++i) { + assertEquals(tokens.get(i).toString(), i == 7, tokens.get(i).isExpanded()); + } + } + + @Test + public void testPredefinedMacroExpansion() throws Exception { + preprocessor.addMacro("PREDEFINED", "123"); + final List<Token> tokens = getTokens("is_expanded_flag/predefined_macro_expansion.c"); + System.out.println(tokens); + + assertEquals(9, tokens.size()); + + for (int i = 0; i < 9; ++i) { + assertEquals(tokens.get(i).toString(), i == 6, tokens.get(i).isExpanded()); + } + } + + @Test + public void testExpansionWithArgs() throws Exception { + final List<Token> tokens = getTokens("is_expanded_flag/expansion_with_args.c"); + System.out.println(tokens); + + assertEquals(26, tokens.size()); + + for (Token token : tokens) { + switch (token.getType()) { + case ':': + case '?': + case '>': + assertTrue(token.toString(), token.isExpanded()); + break; + case Token.WHITESPACE: + case Token.NL: + case Token.EOF: + // ignore whitespaces, eof + break; + default: + assertFalse(token.toString(), token.isExpanded()); + break; + } + } + } + + @Test + public void testNestedExpansion() throws Exception { + final List<Token> tokens = getTokens("is_expanded_flag/nested_expansion.c"); + System.out.println(tokens); + + assertEquals(32, tokens.size()); + + for (Token token : tokens) { + final String text = token.getText(); + switch (token.getType()) { + case '%': + case Token.EQ: + case Token.LAND: + assertTrue(token.toString(), token.isExpanded()); + break; + case Token.WHITESPACE: + case Token.NL: + case Token.EOF: + // ignore whitespaces, eof + break; + case Token.NUMBER: + if ("0".equals(text)) { + assertTrue(token.toString(), token.isExpanded()); + } else if ("3423".equals(text)) { + assertFalse(token.toString(), token.isExpanded()); + } + break; + default: + assertFalse(token.toString(), token.isExpanded()); + break; + } + } + } + + private List<Token> getTokens(String resourcePath) throws IOException, LexerException { + final List<Token> result = new ArrayList<>(); + final String filePath = Thread.currentThread() + .getContextClassLoader() + .getResource(resourcePath) + .getFile(); + preprocessor.addInput(new File(filePath)); + + Token token = preprocessor.token(); + while (token.getType() != Token.EOF) { + result.add(token); + token = preprocessor.token(); + } + return result; + } + +} diff --git a/src/test/java/org/anarres/cpp/LexerSourceTest.java b/src/test/java/org/anarres/cpp/LexerSourceTest.java index f51b253..db90b31 100644 --- a/src/test/java/org/anarres/cpp/LexerSourceTest.java +++ b/src/test/java/org/anarres/cpp/LexerSourceTest.java @@ -70,6 +70,7 @@ public void testLexerSource() testLexerSource("/**/", true, CCOMMENT); testLexerSource("/* /**/ */", true, CCOMMENT, WHITESPACE, '*', '/'); testLexerSource("/** ** **/", true, CCOMMENT); + testLexerSource("/*", true, INVALID); testLexerSource("//* ** **/", true, CPPCOMMENT); testLexerSource("'\\r' '\\xf' '\\xff' 'x' 'aa' ''", true, CHARACTER, WHITESPACE, @@ -98,5 +99,6 @@ public void testNumbers() throws Exception { testLexerSource("1e6", true, NUMBER); testLexerSource("1.45e6", true, NUMBER); testLexerSource(".45e6", true, NUMBER); + testLexerSource("-6", true, '-', NUMBER); } } diff --git a/src/test/java/org/anarres/cpp/NumericValueTest.java b/src/test/java/org/anarres/cpp/NumericValueTest.java new file mode 100644 index 0000000..5668452 --- /dev/null +++ b/src/test/java/org/anarres/cpp/NumericValueTest.java @@ -0,0 +1,97 @@ +package org.anarres.cpp; + +import java.io.IOException; +import org.junit.Test; +import static org.anarres.cpp.Token.*; +import static org.junit.Assert.*; + +/** + * + * @author shevek + */ +public class NumericValueTest { + + private Token testNumericValue(String in) throws IOException, LexerException { + StringLexerSource s = new StringLexerSource(in); + + Token tok = s.token(); + System.out.println("Token is " + tok); + assertEquals(NUMBER, tok.getType()); + + Token eof = s.token(); + assertEquals("Didn't get EOF, but " + tok, EOF, eof.getType()); + + return tok; + } + + private void testNumericValue(String in, double out) throws IOException, LexerException { + System.out.println("Testing '" + in + "' -> " + out); + Token tok = testNumericValue(in); + assertEquals(in, tok.getText()); + NumericValue value = (NumericValue) tok.getValue(); + assertEquals("Double mismatch", out, value.doubleValue(), 0.01d); + assertEquals("Float mismatch", (float) out, value.floatValue(), 0.01f); + assertEquals("Long mismatch", (long) out, value.longValue()); + assertEquals("Integer mismatch", (int) out, value.intValue()); + } + + @Test + public void testNumericValue() throws Exception { + + // Zero + testNumericValue("0", 0); + + // Decimal + testNumericValue("1", 1); + testNumericValue("1L", 1); + testNumericValue("12", 12); + testNumericValue("12L", 12); + + // Hex + testNumericValue("0xf", 0xf); + testNumericValue("0xfL", 0xf); + testNumericValue("0x12", 0x12); + testNumericValue("0x12L", 0x12); + + // Negative + // testNumericValue("-0", 0); + // testNumericValue("-1", -1); + + // Negative hex + // testNumericValue("-0x56", -0x56); + // testNumericValue("-0x102", -0x102); + + // Octal and negative octal + testNumericValue("0673", Integer.parseInt("673", 8)); + // testNumericValue("-0673", Integer.parseInt("-673", 8)); + + // Floating point + testNumericValue(".0", 0); + testNumericValue(".00", 0); + testNumericValue("0.", 0); + testNumericValue("0.0", 0); + testNumericValue("00.0", 0); + testNumericValue("00.", 0); + + // Sign on exponents + testNumericValue("1e1", 1e1); + // testNumericValue("-1e1", -1e1); + testNumericValue("1e-1", 1e-1); + + // Hex numbers with decimal exponents + testNumericValue("0x12e3", 0x12e3); + testNumericValue("0x12p3", 0x12p3); + + // Octal numbers with decimal exponents + testNumericValue("012e3", 012e3); // Fails + testNumericValue("067e4", 067e4); // Fails + + // Issues a warning. + try { + testNumericValue("097", 97); + fail("No warning."); + } catch (LexerException e) { + } + + } +} diff --git a/src/test/resources/is_expanded_flag/expansion_with_args.c b/src/test/resources/is_expanded_flag/expansion_with_args.c new file mode 100644 index 0000000..f479c35 --- /dev/null +++ b/src/test/resources/is_expanded_flag/expansion_with_args.c @@ -0,0 +1,3 @@ +#define MAX(a, b) a > b ? a : b + +int i = MAX(123, 321) + 1; diff --git a/src/test/resources/is_expanded_flag/nested_expansion.c b/src/test/resources/is_expanded_flag/nested_expansion.c new file mode 100644 index 0000000..526314c --- /dev/null +++ b/src/test/resources/is_expanded_flag/nested_expansion.c @@ -0,0 +1,5 @@ +#define DIVISIBLE2(n) n % 2 == 0 +#define DIVISIBLE3(n) n % 3 == 0 +#define DIVISIBLE6(n) DIVISIBLE2(n) && DIVISIBLE3(n) + +bool isDivisible = DIVISIBLE6(3423); diff --git a/src/test/resources/is_expanded_flag/predefined_macro_expansion.c b/src/test/resources/is_expanded_flag/predefined_macro_expansion.c new file mode 100644 index 0000000..dc50d96 --- /dev/null +++ b/src/test/resources/is_expanded_flag/predefined_macro_expansion.c @@ -0,0 +1 @@ +int i = PREDEFINED; diff --git a/src/test/resources/is_expanded_flag/simple_expansion.c b/src/test/resources/is_expanded_flag/simple_expansion.c new file mode 100644 index 0000000..489ef3e --- /dev/null +++ b/src/test/resources/is_expanded_flag/simple_expansion.c @@ -0,0 +1,3 @@ +#define ONE_HUNDRED 100 + +int i = ONE_HUNDRED;