1 // -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the GNU General Public License v3+, or later.
7 // See license.mkd for licensing and copyright information.
8 // ---------------------------------------------------------------------------
10 package cc
.squirreljme
.plugin
;
12 import java
.nio
.file
.Path
;
13 import java
.util
.ArrayDeque
;
14 import java
.util
.ArrayList
;
15 import java
.util
.Collections
;
16 import java
.util
.Deque
;
17 import java
.util
.List
;
20 * A single error that exists in source code.
24 public final class SourceError
26 /** The maximum error code index that can exist. */
27 static final int _MAX_ERROR_CODE
=
28 Character
.MAX_RADIX
* Character
.MAX_RADIX
;
30 /** The code for the project. */
31 public final String projectCode
;
33 /** The error index. */
34 public final int index
;
36 /** The body of the error. */
37 public final String body
;
39 /** Extra parameters. */
40 public final List
<String
> parameters
;
42 /** Where is this located? */
43 public final Path where
;
46 * Decodes the content to tag information.
48 * @param __content The content to decode.
49 * @param __where Where the file is located.
50 * @throws IllegalArgumentException If the content is not valid.
51 * @throws NullPointerException On null arguments.
54 public SourceError(Iterable
<String
> __content
, Path __where
)
55 throws IllegalArgumentException
, NullPointerException
57 if (__content
== null)
58 throw new NullPointerException();
63 // Put items into the queue
64 Deque
<String
> queue
= new ArrayDeque
<String
>();
65 for (String item
: __content
)
68 // Read the error code
69 String errorCode
= queue
.pollFirst();
70 if (errorCode
== null)
71 throw new IllegalArgumentException("No error code.");
73 if (errorCode
.length() < 4)
74 throw new IllegalArgumentException("Error code too short.");
76 // Project code is the first two characters
77 this.projectCode
= errorCode
.substring(0, 2).toUpperCase();
78 this.index
= SourceError
.stringToIndex(errorCode
.substring(2, 4));
80 // Fill in content description
81 StringBuilder body
= new StringBuilder();
82 while (!queue
.isEmpty())
84 // Stop when nothing is left, or if there are starting parameters
85 String item
= queue
.peekFirst();
86 if (item
== null || item
.equals("("))
89 // Add formatting space
90 if (body
.length() > 0)
93 // And append whatever we put in
94 body
.append(queue
.removeFirst());
98 this.body
= body
.toString();
101 List
<String
> parameters
= new ArrayList
<String
>();
102 if ("(".equals(queue
.peekFirst()))
104 // Remove the starting parenthesis so it is not added
108 StringBuilder buffer
= new StringBuilder();
109 while (!queue
.isEmpty())
111 String item
= queue
.peekFirst();
113 // End parameter or next?
114 boolean isEnd
= (item
== null || item
.equals(")"));
115 if (isEnd
|| item
.equals(";"))
120 // Store into parameter list?
121 if (buffer
.length() > 0)
123 parameters
.add(buffer
.toString());
132 // Add formatting space
133 if (buffer
.length() > 0)
136 // And append whatever we put in
137 buffer
.append(queue
.removeFirst());
142 this.parameters
= Collections
.<String
>unmodifiableList(parameters
);
150 public final String
toString()
152 StringBuilder sb
= new StringBuilder();
155 sb
.append(this.projectCode
);
156 sb
.append(SourceError
.indexToString(this.index
));
160 sb
.append(this.body
);
162 List
<String
> parameters
= this.parameters
;
163 if (!parameters
.isEmpty())
167 for (int i
= 0, n
= parameters
.size(); i
< n
; i
++)
172 sb
.append(parameters
.get(0));
178 // Place location of this file
179 Path where
= this.where
;
187 return sb
.toString();
191 * Returns string form of the given index.
193 * @param __index The index to translate.
194 * @return The translated string to index.
197 public static String
indexToString(int __index
)
199 StringBuilder sb
= new StringBuilder(4);
201 sb
.append(Character
.toLowerCase(Character
.forDigit(
202 __index
/ Character
.MAX_RADIX
, Character
.MAX_RADIX
)));
203 sb
.append(Character
.toLowerCase(Character
.forDigit(
204 __index
% Character
.MAX_RADIX
, Character
.MAX_RADIX
)));
206 return sb
.toString();
210 * Returns the index for the given string.
212 * @return The resulting index.
213 * @throws IllegalArgumentException If the string is not valid.
214 * @throws NullPointerException On null arguments.
217 public static int stringToIndex(String __string
)
218 throws IllegalArgumentException
, NullPointerException
220 if (__string
== null)
221 throw new NullPointerException("No string specified.");
223 if (__string
.length() != 2)
224 throw new IllegalArgumentException("Invalid string length.");
226 int rv
= (Character
.digit(__string
.charAt(0), Character
.MAX_RADIX
) *
227 Character
.MAX_RADIX
) +
228 Character
.digit(__string
.charAt(1), Character
.MAX_RADIX
);
230 if (rv
< 0 || rv
> SourceError
._MAX_ERROR_CODE
)
231 throw new IllegalArgumentException("Out of range index.");