/diss/tags/finalsubmission/src/compiler/tools/AllErrorPrinter.java
Java | 385 lines | 232 code | 17 blank | 136 comment | 50 complexity | 0f635b95f5bf4ccca737c7e34ff2d42b MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-3.0, LGPL-2.1
- package compiler.tools;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.HashSet;
- /**
- * The All Error Printer class works out which errors from either compiler are
- * required for printing to the user.
- *
- * @author Richard Hill
- */
- public class AllErrorPrinter
- {
- //The lists of errors generated by both compilers (GCC and NCC).
- private ArrayList<GccError> gccErrors;
- private ArrayList<NccError> nccErrors;
- //The Command Line Options
- private CommandLineOptions clo;
- //Complete list of error to order errors by line no.
- private ArrayList<GeneralError> totalErrors;
- //Must be adjusted dependent on the number of possible errors:
- private HashMap<Integer, ArrayList<NccError>> nccErrorPresentList = new HashMap<Integer, ArrayList<NccError>>();
- private HashMap<Integer, ArrayList<GccError>> gccErrorPresentList = new HashMap<Integer, ArrayList<GccError>>();
- /*
- * The print NccError regardless list contains a list of NccError Numbers
- * that should be printed whatever happens.
- */
- private HashSet<Integer> printRegardless;
- //The constant width of the console we're writing too.
- private final int cll = 80;
-
- /**
- * Constructor.
- *
- * @param gccErrors The list of error and warnings generated by GCC.
- * @param nccErrors The list of error and warnings generated by NCC.
- */
- public AllErrorPrinter(ArrayList<GccError> gccErrors, ArrayList<NccError> nccErrors, CommandLineOptions clo)
- {
- totalErrors = new ArrayList<GeneralError>();
- this.gccErrors = gccErrors;
- this.nccErrors = nccErrors;
- this.clo = clo;
- initRegardless();
- if(!clo.verbose){
- fillLists();
- begin();
- //Order and print the list of totalErrors
- System.out.println();
- printList(orderList(totalErrors), true);
- if(clo.forceNcc){
- System.out.println("\nVerbatim NCC Output:");
- //Order and print the list of nccErrors
- printList(orderList(nccErrors), false);
- }
- }
- else{
- /*
- * Verbose mode of operation, the GCC error will be printed as per
- * normal is the Driver class after we finish up execution in this
- * class so we don't have to worry about printing them, we do
- * however need to order and print the list of NCC errors.
- * Note: By the definition of verbose mode in the requirements of
- * the project we don't need to print a combined and filtered
- * list of NCC and GCC errors first.
- */
- System.out.println("\nVerbatim NCC Output:");
- //Order and print the list of nccErrors
- printList(orderList(nccErrors), false);
- }
- }
-
- /**
- * Initialises the print regardless list.
- */
- public void initRegardless()
- {
- printRegardless = new HashSet<Integer>();
- printRegardless.add(qConvert(102));
- printRegardless.add(qConvert(103));
- printRegardless.add(qConvert(111));
- printRegardless.add(qConvert(112)); //Can be removed if good reason(s) found!
- printRegardless.add(qConvert(113));
- printRegardless.add(qConvert(115));
- printRegardless.add(qConvert(116));
- printRegardless.add(qConvert(117));
- printRegardless.add(qConvert(118));
- printRegardless.add(qConvert(119));
- printRegardless.add(qConvert(120));
- printRegardless.add(qConvert(122));
- }
-
- /**
- * Fill the list of present errors.
- */
- public void fillLists()
- {
- for(int p = 0; p < gccErrors.size(); p++){
- GccError g = gccErrors.get(p);
- //Debugging printer
- //System.err.println(g.getErrorNumber() + ": " + g.getMessage());
- if(gccErrorPresentList.containsKey(qConvert(g.getErrorNumber()))){
- //add the error to the array list currently stored at the key location
- gccErrorPresentList.get(qConvert(g.getErrorNumber())).add(g);
- }
- else{
- ArrayList<GccError> keyList = new ArrayList<GccError>();
- keyList.add(g);
- gccErrorPresentList.put(qConvert(g.getErrorNumber()), keyList);
- }
- }
- for(int q = 0; q < nccErrors.size(); q++){
- NccError n = nccErrors.get(q);
- //Debugging printer
- //System.err.println(n.getErrorNumber() + ": " + n.getMessage());
- if(nccErrorPresentList.containsKey(qConvert(n.getErrorNumber()))){
- //add the error to the array list currently stored at the key location
- nccErrorPresentList.get(qConvert(n.getErrorNumber())).add(n);
- }
- else{
- ArrayList<NccError> keyList = new ArrayList<NccError>();
- keyList.add(n);
- nccErrorPresentList.put(qConvert(n.getErrorNumber()), keyList);
- }
- }
- }
-
- /**
- * Begins the process. Checking error numbers etc.
- */
- public void begin()
- {
- //Prepare the list of GCC Errors and Warnings to be printed.
- for(int i = 0; i < gccErrors.size(); i++){
- GccError e = gccErrors.get(i);
- if(e.getErrorNumber() == 111){
- //Don't print this error message if the NCC equivalent is present
- if(nccErrorPresentList.containsKey(qConvert(111))){
- //do anything but print
- }
- }
- else if(e.getErrorNumber() == -1){
- //Discard all GCC errors with ErrorNumber = -1
- }
- else if(nccErrorPresentList.containsKey(qConvert(e.getErrorNumber()))){
- //Don't print this message
- }
- /*
- * Eventually we'll stop everything with error number = 0 printing
- * but not until the bitter end when all required GCC and NCC
- * error number have been specified.
- *
- * Still a little unsure about this bit of code, might be best off
- * leaving the 0's to print away as some of them provide valid extra
- * information.
- */
- /*else if(nccErrorPresentList.containsKey(qConvert(0))){
- //Don't print these either!
- }*/ //I think this code is supposed to be the code below:
- /*else if(e.getErrorNumber() == 0){
- //Don't print these either!
- }*/
- else{
- GeneralError ge = new GeneralError(e.getLine(), e.getErrorNumber());
- ge.addText("GCC: " + e.getFileName() + ": " + e.getFunctionName() + ": " + e.getLine() + ": " + e.getMessage());
- totalErrors.add(ge);
- }
- }
- //print the full list of NCC Errors and Warnings:
- for(int a = 0; a < nccErrors.size(); a++){
- NccError e = nccErrors.get(a);
- if(printRegardless.contains(qConvert(e.getErrorNumber()))){
- totalErrors.add((GeneralError)e);
- }
- else if(e.getErrorNumber() == 111){
- /*
- * See if the gcc error list contains a 111 error as it is a
- * special case in that it always occurs on line zero for NCC
- * and would have not line in GCC because the message is too
- * generic.
- */
- if(gccErrorPresentList.containsKey(qConvert(e.getErrorNumber()))){
- totalErrors.add((GeneralError)e);
- }
- }
- else if(gccErrorPresentList.containsKey(qConvert(e.getErrorNumber()))){
- ArrayList<GccError> errNoList = gccErrorPresentList.get(qConvert(e.getErrorNumber()));
- for(int b = 0; b < errNoList.size(); b++){
- if(errNoList.get(b).getLine() == e.getLine()){
- totalErrors.add((GeneralError)e);
- break; //break from the for loop to avoid adding NccErrors twice
- }
- else{
- //Don't print the error message.
- }
- }
- }
- //will need to do something with printRegardless here eventually
- else{
- //totalErrors.add((GeneralError)e);
- }
- }
- }
-
- /**
- * Order a list of errors.
- */
- public ArrayList<GeneralError> orderList(ArrayList list)
- {
- //put the list in an array
- GeneralError[] temp = new GeneralError[list.size()];
-
- //fill the temp array
- for(int i = 0; i < list.size(); i++){
- temp[i] = (GeneralError) list.get(i);
- }
-
- bubbleSort(temp);
-
- ArrayList<GeneralError> retArr = new ArrayList<GeneralError>();
- //fill the ArrayList to return
- for(int i = 0; i < temp.length; i++){
- retArr.add(temp[i]);
- }
-
- return retArr;
- }
- /**
- * Prints a list of errors.
- */
- public void printList(ArrayList<GeneralError> list, boolean printSummary)
- {
- for(int i = 0; i < list.size(); i++){
- //System.out.println(totalErrors.get(i).getMessage());
- GeneralError ge = (GeneralError) list.get(i);
- ArrayList<String> fm = formatMessage(ge.getMessage());
- //Print all the lines removing unnecessary whitespace
- for(int j = 0; j < fm.size(); j++){
- if(j == 0){
- System.out.println(fm.get(j).trim());
- }
- else{
- //Stop truncated blank lines being printed
- if(fm.get(j).trim().equals("")){
- //Skip the line
- }
- else{
- //Print the line
- if( (fm.get(j).startsWith("Error:")) || (fm.get(j).startsWith("Warning:")) ){
- System.out.println(fm.get(j).trim());
- }
- else if(Character.isWhitespace(fm.get(j).charAt(0))){
- System.out.println(" > " + fm.get(j));
- }
- else{
- System.out.println(" > " + fm.get(j).trim());
- }
- }
- }
- }
- }
- if(printSummary){
- System.out.println("A total of " + list.size() + " Errors / Warnings were found.");
- }
- }
-
- /**
- * Formats a String so that it does not break mid word in an error message.
- *
- * @param message The message to format
- * @return The ArrayList of formatted strings
- */
- private ArrayList<String> formatMessage(String message)
- {
- //System.out.println("In formatMessage()");
- ArrayList<String> retVal = new ArrayList<String>();
- message = message.concat(Character.toString('\n'));
- char[] cArray = message.toCharArray();
- //Set the length of the console we're printing too. -1 for array index
- int curcll = cll - 1;
- int i = 0;
- int beginLineAt = i;
- int counter = 0;
- while(i < cArray.length){
- //After first round printer shorter lines
- if((curcll != (cll - 4)) & (counter != 0) ){
- curcll = cll -4;
- }
- //System.out.println("In while(1)");
- String nextLine = "";
- while(i < (beginLineAt + curcll)){
- //System.out.println((int)cArray[i] + " = " + cArray[i]);
- if(cArray[i] != '\n'){
- nextLine = nextLine.concat(Character.toString(cArray[i]));
- i++;
- }
- else{
- //New line to be printed - don't add '\n' char!
- retVal.add(nextLine);
- //System.out.println("Added line length = " + nextLine.length());
- i++; //Move i on
- beginLineAt = i; //Set the new line beginning index
- break; //Break from inner while complete line found
- }
- }
- /*
- * If we're out of the inner while loop and beginLineAt doesn't
- * equal i then it means that portion of the message exceeded 80
- * chars so must be truncated.
- */
- //System.out.println("i = " + i + ", beginLineAt = " + beginLineAt);
- if(i != beginLineAt){
- // Begin rolling i back until a space character is found.
- try{
- while(cArray[i] != ' '){
- i--;
- }
- }
- catch(ArrayIndexOutOfBoundsException e){
- i = beginLineAt + cll;
- }
- /*
- * i should now hold a reference to a space so move it on by
- * one and print that group of character. Then continue by
- * analysing the char i points after the next increment.
- */
- i++;
- nextLine = "";
- /*
- * Instead of resetting nextLine could I just remove the
- * appropriate number of characters?
- */
- for(int j = beginLineAt; j < i; j++){
- nextLine = nextLine.concat(Character.toString(cArray[j]));
- }
- retVal.add(nextLine);
- //System.out.println("Added line length = " + nextLine.length());
- beginLineAt = i;
- }
- else{
- //The last line was successfully added at under 80 chars...
- }
- //System.out.println(nextLine);
- counter++;
- }
-
- return retVal;
- }
- /**
- * This is the bubble sort algorithm.
- */
- public void bubbleSort(GeneralError[] sorta)
- {
- GeneralError temp;
- int outX;
- int inX;
- //outer loop from top to bottom
- for(outX = sorta.length -1; outX > 0; outX--){
- //inner loop from bottom to current outX
- for(inX = 1; inX <= outX; inX++){
- // if adjacent items are out of order, swap them!
- if(sorta[inX -1].getLine() > sorta[inX].getLine()){
- temp = sorta[inX -1];
- sorta[inX -1] = sorta[inX];
- sorta[inX] = temp;
- }
- }
- }
- }
-
- /**
- * Performs a quick convert from int to Integer.
- *
- * @param i The int to convert.
- * @return The Integer object this int represents.
- */
- private Integer qConvert(int i)
- {
- return Integer.valueOf(i);
- }
- }