PageRenderTime 4130ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/diss/tags/finalsubmission/src/compiler/tools/AllErrorPrinter.java

http://thesandbox.googlecode.com/
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
  1. package compiler.tools;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.HashSet;
  5. /**
  6. * The All Error Printer class works out which errors from either compiler are
  7. * required for printing to the user.
  8. *
  9. * @author Richard Hill
  10. */
  11. public class AllErrorPrinter
  12. {
  13. //The lists of errors generated by both compilers (GCC and NCC).
  14. private ArrayList<GccError> gccErrors;
  15. private ArrayList<NccError> nccErrors;
  16. //The Command Line Options
  17. private CommandLineOptions clo;
  18. //Complete list of error to order errors by line no.
  19. private ArrayList<GeneralError> totalErrors;
  20. //Must be adjusted dependent on the number of possible errors:
  21. private HashMap<Integer, ArrayList<NccError>> nccErrorPresentList = new HashMap<Integer, ArrayList<NccError>>();
  22. private HashMap<Integer, ArrayList<GccError>> gccErrorPresentList = new HashMap<Integer, ArrayList<GccError>>();
  23. /*
  24. * The print NccError regardless list contains a list of NccError Numbers
  25. * that should be printed whatever happens.
  26. */
  27. private HashSet<Integer> printRegardless;
  28. //The constant width of the console we're writing too.
  29. private final int cll = 80;
  30. /**
  31. * Constructor.
  32. *
  33. * @param gccErrors The list of error and warnings generated by GCC.
  34. * @param nccErrors The list of error and warnings generated by NCC.
  35. */
  36. public AllErrorPrinter(ArrayList<GccError> gccErrors, ArrayList<NccError> nccErrors, CommandLineOptions clo)
  37. {
  38. totalErrors = new ArrayList<GeneralError>();
  39. this.gccErrors = gccErrors;
  40. this.nccErrors = nccErrors;
  41. this.clo = clo;
  42. initRegardless();
  43. if(!clo.verbose){
  44. fillLists();
  45. begin();
  46. //Order and print the list of totalErrors
  47. System.out.println();
  48. printList(orderList(totalErrors), true);
  49. if(clo.forceNcc){
  50. System.out.println("\nVerbatim NCC Output:");
  51. //Order and print the list of nccErrors
  52. printList(orderList(nccErrors), false);
  53. }
  54. }
  55. else{
  56. /*
  57. * Verbose mode of operation, the GCC error will be printed as per
  58. * normal is the Driver class after we finish up execution in this
  59. * class so we don't have to worry about printing them, we do
  60. * however need to order and print the list of NCC errors.
  61. * Note: By the definition of verbose mode in the requirements of
  62. * the project we don't need to print a combined and filtered
  63. * list of NCC and GCC errors first.
  64. */
  65. System.out.println("\nVerbatim NCC Output:");
  66. //Order and print the list of nccErrors
  67. printList(orderList(nccErrors), false);
  68. }
  69. }
  70. /**
  71. * Initialises the print regardless list.
  72. */
  73. public void initRegardless()
  74. {
  75. printRegardless = new HashSet<Integer>();
  76. printRegardless.add(qConvert(102));
  77. printRegardless.add(qConvert(103));
  78. printRegardless.add(qConvert(111));
  79. printRegardless.add(qConvert(112)); //Can be removed if good reason(s) found!
  80. printRegardless.add(qConvert(113));
  81. printRegardless.add(qConvert(115));
  82. printRegardless.add(qConvert(116));
  83. printRegardless.add(qConvert(117));
  84. printRegardless.add(qConvert(118));
  85. printRegardless.add(qConvert(119));
  86. printRegardless.add(qConvert(120));
  87. printRegardless.add(qConvert(122));
  88. }
  89. /**
  90. * Fill the list of present errors.
  91. */
  92. public void fillLists()
  93. {
  94. for(int p = 0; p < gccErrors.size(); p++){
  95. GccError g = gccErrors.get(p);
  96. //Debugging printer
  97. //System.err.println(g.getErrorNumber() + ": " + g.getMessage());
  98. if(gccErrorPresentList.containsKey(qConvert(g.getErrorNumber()))){
  99. //add the error to the array list currently stored at the key location
  100. gccErrorPresentList.get(qConvert(g.getErrorNumber())).add(g);
  101. }
  102. else{
  103. ArrayList<GccError> keyList = new ArrayList<GccError>();
  104. keyList.add(g);
  105. gccErrorPresentList.put(qConvert(g.getErrorNumber()), keyList);
  106. }
  107. }
  108. for(int q = 0; q < nccErrors.size(); q++){
  109. NccError n = nccErrors.get(q);
  110. //Debugging printer
  111. //System.err.println(n.getErrorNumber() + ": " + n.getMessage());
  112. if(nccErrorPresentList.containsKey(qConvert(n.getErrorNumber()))){
  113. //add the error to the array list currently stored at the key location
  114. nccErrorPresentList.get(qConvert(n.getErrorNumber())).add(n);
  115. }
  116. else{
  117. ArrayList<NccError> keyList = new ArrayList<NccError>();
  118. keyList.add(n);
  119. nccErrorPresentList.put(qConvert(n.getErrorNumber()), keyList);
  120. }
  121. }
  122. }
  123. /**
  124. * Begins the process. Checking error numbers etc.
  125. */
  126. public void begin()
  127. {
  128. //Prepare the list of GCC Errors and Warnings to be printed.
  129. for(int i = 0; i < gccErrors.size(); i++){
  130. GccError e = gccErrors.get(i);
  131. if(e.getErrorNumber() == 111){
  132. //Don't print this error message if the NCC equivalent is present
  133. if(nccErrorPresentList.containsKey(qConvert(111))){
  134. //do anything but print
  135. }
  136. }
  137. else if(e.getErrorNumber() == -1){
  138. //Discard all GCC errors with ErrorNumber = -1
  139. }
  140. else if(nccErrorPresentList.containsKey(qConvert(e.getErrorNumber()))){
  141. //Don't print this message
  142. }
  143. /*
  144. * Eventually we'll stop everything with error number = 0 printing
  145. * but not until the bitter end when all required GCC and NCC
  146. * error number have been specified.
  147. *
  148. * Still a little unsure about this bit of code, might be best off
  149. * leaving the 0's to print away as some of them provide valid extra
  150. * information.
  151. */
  152. /*else if(nccErrorPresentList.containsKey(qConvert(0))){
  153. //Don't print these either!
  154. }*/ //I think this code is supposed to be the code below:
  155. /*else if(e.getErrorNumber() == 0){
  156. //Don't print these either!
  157. }*/
  158. else{
  159. GeneralError ge = new GeneralError(e.getLine(), e.getErrorNumber());
  160. ge.addText("GCC: " + e.getFileName() + ": " + e.getFunctionName() + ": " + e.getLine() + ": " + e.getMessage());
  161. totalErrors.add(ge);
  162. }
  163. }
  164. //print the full list of NCC Errors and Warnings:
  165. for(int a = 0; a < nccErrors.size(); a++){
  166. NccError e = nccErrors.get(a);
  167. if(printRegardless.contains(qConvert(e.getErrorNumber()))){
  168. totalErrors.add((GeneralError)e);
  169. }
  170. else if(e.getErrorNumber() == 111){
  171. /*
  172. * See if the gcc error list contains a 111 error as it is a
  173. * special case in that it always occurs on line zero for NCC
  174. * and would have not line in GCC because the message is too
  175. * generic.
  176. */
  177. if(gccErrorPresentList.containsKey(qConvert(e.getErrorNumber()))){
  178. totalErrors.add((GeneralError)e);
  179. }
  180. }
  181. else if(gccErrorPresentList.containsKey(qConvert(e.getErrorNumber()))){
  182. ArrayList<GccError> errNoList = gccErrorPresentList.get(qConvert(e.getErrorNumber()));
  183. for(int b = 0; b < errNoList.size(); b++){
  184. if(errNoList.get(b).getLine() == e.getLine()){
  185. totalErrors.add((GeneralError)e);
  186. break; //break from the for loop to avoid adding NccErrors twice
  187. }
  188. else{
  189. //Don't print the error message.
  190. }
  191. }
  192. }
  193. //will need to do something with printRegardless here eventually
  194. else{
  195. //totalErrors.add((GeneralError)e);
  196. }
  197. }
  198. }
  199. /**
  200. * Order a list of errors.
  201. */
  202. public ArrayList<GeneralError> orderList(ArrayList list)
  203. {
  204. //put the list in an array
  205. GeneralError[] temp = new GeneralError[list.size()];
  206. //fill the temp array
  207. for(int i = 0; i < list.size(); i++){
  208. temp[i] = (GeneralError) list.get(i);
  209. }
  210. bubbleSort(temp);
  211. ArrayList<GeneralError> retArr = new ArrayList<GeneralError>();
  212. //fill the ArrayList to return
  213. for(int i = 0; i < temp.length; i++){
  214. retArr.add(temp[i]);
  215. }
  216. return retArr;
  217. }
  218. /**
  219. * Prints a list of errors.
  220. */
  221. public void printList(ArrayList<GeneralError> list, boolean printSummary)
  222. {
  223. for(int i = 0; i < list.size(); i++){
  224. //System.out.println(totalErrors.get(i).getMessage());
  225. GeneralError ge = (GeneralError) list.get(i);
  226. ArrayList<String> fm = formatMessage(ge.getMessage());
  227. //Print all the lines removing unnecessary whitespace
  228. for(int j = 0; j < fm.size(); j++){
  229. if(j == 0){
  230. System.out.println(fm.get(j).trim());
  231. }
  232. else{
  233. //Stop truncated blank lines being printed
  234. if(fm.get(j).trim().equals("")){
  235. //Skip the line
  236. }
  237. else{
  238. //Print the line
  239. if( (fm.get(j).startsWith("Error:")) || (fm.get(j).startsWith("Warning:")) ){
  240. System.out.println(fm.get(j).trim());
  241. }
  242. else if(Character.isWhitespace(fm.get(j).charAt(0))){
  243. System.out.println(" > " + fm.get(j));
  244. }
  245. else{
  246. System.out.println(" > " + fm.get(j).trim());
  247. }
  248. }
  249. }
  250. }
  251. }
  252. if(printSummary){
  253. System.out.println("A total of " + list.size() + " Errors / Warnings were found.");
  254. }
  255. }
  256. /**
  257. * Formats a String so that it does not break mid word in an error message.
  258. *
  259. * @param message The message to format
  260. * @return The ArrayList of formatted strings
  261. */
  262. private ArrayList<String> formatMessage(String message)
  263. {
  264. //System.out.println("In formatMessage()");
  265. ArrayList<String> retVal = new ArrayList<String>();
  266. message = message.concat(Character.toString('\n'));
  267. char[] cArray = message.toCharArray();
  268. //Set the length of the console we're printing too. -1 for array index
  269. int curcll = cll - 1;
  270. int i = 0;
  271. int beginLineAt = i;
  272. int counter = 0;
  273. while(i < cArray.length){
  274. //After first round printer shorter lines
  275. if((curcll != (cll - 4)) & (counter != 0) ){
  276. curcll = cll -4;
  277. }
  278. //System.out.println("In while(1)");
  279. String nextLine = "";
  280. while(i < (beginLineAt + curcll)){
  281. //System.out.println((int)cArray[i] + " = " + cArray[i]);
  282. if(cArray[i] != '\n'){
  283. nextLine = nextLine.concat(Character.toString(cArray[i]));
  284. i++;
  285. }
  286. else{
  287. //New line to be printed - don't add '\n' char!
  288. retVal.add(nextLine);
  289. //System.out.println("Added line length = " + nextLine.length());
  290. i++; //Move i on
  291. beginLineAt = i; //Set the new line beginning index
  292. break; //Break from inner while complete line found
  293. }
  294. }
  295. /*
  296. * If we're out of the inner while loop and beginLineAt doesn't
  297. * equal i then it means that portion of the message exceeded 80
  298. * chars so must be truncated.
  299. */
  300. //System.out.println("i = " + i + ", beginLineAt = " + beginLineAt);
  301. if(i != beginLineAt){
  302. // Begin rolling i back until a space character is found.
  303. try{
  304. while(cArray[i] != ' '){
  305. i--;
  306. }
  307. }
  308. catch(ArrayIndexOutOfBoundsException e){
  309. i = beginLineAt + cll;
  310. }
  311. /*
  312. * i should now hold a reference to a space so move it on by
  313. * one and print that group of character. Then continue by
  314. * analysing the char i points after the next increment.
  315. */
  316. i++;
  317. nextLine = "";
  318. /*
  319. * Instead of resetting nextLine could I just remove the
  320. * appropriate number of characters?
  321. */
  322. for(int j = beginLineAt; j < i; j++){
  323. nextLine = nextLine.concat(Character.toString(cArray[j]));
  324. }
  325. retVal.add(nextLine);
  326. //System.out.println("Added line length = " + nextLine.length());
  327. beginLineAt = i;
  328. }
  329. else{
  330. //The last line was successfully added at under 80 chars...
  331. }
  332. //System.out.println(nextLine);
  333. counter++;
  334. }
  335. return retVal;
  336. }
  337. /**
  338. * This is the bubble sort algorithm.
  339. */
  340. public void bubbleSort(GeneralError[] sorta)
  341. {
  342. GeneralError temp;
  343. int outX;
  344. int inX;
  345. //outer loop from top to bottom
  346. for(outX = sorta.length -1; outX > 0; outX--){
  347. //inner loop from bottom to current outX
  348. for(inX = 1; inX <= outX; inX++){
  349. // if adjacent items are out of order, swap them!
  350. if(sorta[inX -1].getLine() > sorta[inX].getLine()){
  351. temp = sorta[inX -1];
  352. sorta[inX -1] = sorta[inX];
  353. sorta[inX] = temp;
  354. }
  355. }
  356. }
  357. }
  358. /**
  359. * Performs a quick convert from int to Integer.
  360. *
  361. * @param i The int to convert.
  362. * @return The Integer object this int represents.
  363. */
  364. private Integer qConvert(int i)
  365. {
  366. return Integer.valueOf(i);
  367. }
  368. }