You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by ha...@apache.org on 2004/09/27 17:33:46 UTC
cvs commit: ws-axis/c/tools/trace/org/apache/axis/tracetool AddEntryAndExitTrace.java Exclusions.java InputCppSourceCode.java MacroPart.java Parameter.java Signature.java Tracer.java Utils.java
hawkeye 2004/09/27 08:33:46
Modified: c/tools/trace/org/apache/axis/tracetool
AddEntryAndExitTrace.java Exclusions.java
InputCppSourceCode.java MacroPart.java
Parameter.java Signature.java Tracer.java
Utils.java
Log:
Parameter tracing
Revision Changes Path
1.2 +1 -1 ws-axis/c/tools/trace/org/apache/axis/tracetool/AddEntryAndExitTrace.java
Index: AddEntryAndExitTrace.java
===================================================================
RCS file: /home/cvs/ws-axis/c/tools/trace/org/apache/axis/tracetool/AddEntryAndExitTrace.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- AddEntryAndExitTrace.java 20 Sep 2004 16:09:58 -0000 1.1
+++ AddEntryAndExitTrace.java 27 Sep 2004 15:33:46 -0000 1.2
@@ -128,7 +128,7 @@
* @throws IOException if htere is a problem dealing with the files.
*/
private void parseFile(InputCppSourceCode inputFile, Tracer outputFile)
- throws IOException, ParsingException {
+ throws Exception {
Iterator it = inputFile.getPartIterator();
while (it.hasNext()) {
FilePart fp = (FilePart) (it.next());
1.3 +20 -4 ws-axis/c/tools/trace/org/apache/axis/tracetool/Exclusions.java
Index: Exclusions.java
===================================================================
RCS file: /home/cvs/ws-axis/c/tools/trace/org/apache/axis/tracetool/Exclusions.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Exclusions.java 21 Sep 2004 10:20:09 -0000 1.2
+++ Exclusions.java 27 Sep 2004 15:33:46 -0000 1.3
@@ -32,6 +32,8 @@
"iasciitab.h",
"latin1tab.h",
"spp_converter.h",
+ "spp_converter.c",
+ "spp_tokenizer.c",
"utf8tab.h",
"SoapBinInputStream.h",
"SoapInputSource.h",
@@ -39,10 +41,24 @@
"apr_base64.c",
"apr_base64.h",
"apr_xlate.h",
- // Axis.cpp contains a copyright sign (circle with a "C" in it) which
- // makes readline throw a MalformedInputException on linux possibly due to
- // locale/charset problems.
- "Axis.cpp",
+ "Channel.hpp",
+ "Call.h",
+ "AxisConfig.h",
+ "AxisTransport.h",
+ "ClientAxisEngine.h",
+ "SOAPTransportFactory.h",
+ "SOAPTransport.h",
+ "SoapSerializer.h",
+ "SoapDeSerializer.h",
+ "HeaderBlock.h",
+
+ // Axis.cpp contains a copyright sign (circle with a "C" in it) which
+ // makes readline throw a MalformedInputException on linux possibly due to
+ // locale/charset problems.
+ "Axis.cpp",
+ // spp.c contains a bad return statement that looks like it
+ // shouldn't compile
+ "spp.c",
//Don't trace trace
"AxisTrace.cpp", "AxisTrace.h", "GDefine.h", "AxisFile.h" }));
1.2 +3 -3 ws-axis/c/tools/trace/org/apache/axis/tracetool/InputCppSourceCode.java
Index: InputCppSourceCode.java
===================================================================
RCS file: /home/cvs/ws-axis/c/tools/trace/org/apache/axis/tracetool/InputCppSourceCode.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- InputCppSourceCode.java 20 Sep 2004 16:09:58 -0000 1.1
+++ InputCppSourceCode.java 27 Sep 2004 15:33:46 -0000 1.2
@@ -59,10 +59,10 @@
for (int idx = 0; idx < str.length(); /* No idx++ */
) {
rest = str.substring(idx);
- if (Utils.isSpace(rest.charAt(0))) {
+ if (Character.isWhitespace(rest.charAt(0))) {
int ridx = 0;
while (ridx < rest.length()
- && Utils.isSpace(rest.charAt(ridx)))
+ && Character.isWhitespace(rest.charAt(ridx)))
ridx++;
text = rest.substring(0, ridx);
FilePart fp = new FilePart(text, FilePart.WHITESPACE);
@@ -112,7 +112,7 @@
idx++;
} else if (
- !Utils.startsWithALetter(rest) && '~' != rest.charAt(0)) {
+ !Character.isLetter(rest.charAt(0)) && '~' != rest.charAt(0)) {
Utils.rude(
"Lines must start with a letter ",
name,
1.2 +1 -1 ws-axis/c/tools/trace/org/apache/axis/tracetool/MacroPart.java
Index: MacroPart.java
===================================================================
RCS file: /home/cvs/ws-axis/c/tools/trace/org/apache/axis/tracetool/MacroPart.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- MacroPart.java 20 Sep 2004 16:09:58 -0000 1.1
+++ MacroPart.java 27 Sep 2004 15:33:46 -0000 1.2
@@ -88,7 +88,7 @@
private static String getName(String s) {
int i;
for (i = 0; i < s.length(); i++)
- if (!Utils.isAlphaNumeric(s.charAt(i)) && '_' != s.charAt(i))
+ if (!Character.isLetterOrDigit(s.charAt(i)) && '_' != s.charAt(i))
break;
if (s.length() == i)
return null;
1.2 +73 -33 ws-axis/c/tools/trace/org/apache/axis/tracetool/Parameter.java
Index: Parameter.java
===================================================================
RCS file: /home/cvs/ws-axis/c/tools/trace/org/apache/axis/tracetool/Parameter.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Parameter.java 20 Sep 2004 16:09:58 -0000 1.1
+++ Parameter.java 27 Sep 2004 15:33:46 -0000 1.2
@@ -15,6 +15,7 @@
*/
package org.apache.axis.tracetool;
+import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -23,58 +24,69 @@
* name but not its value.
*/
class Parameter {
- private String type = null;
+ private ArrayList type = new ArrayList();
private String name = null;
private boolean failed = false;
+ /**
+ * Defaults to a parameter in a parameter list so it HAS a parameter name in it
+ */
Parameter(List parts) {
this(parts, false);
}
+ /**
+ * A parameter which is a return type does not have a parameter name.
+ * Parameters in a parameter list do have parameter names embedded in them
+ */
Parameter(List parts, boolean isRetType) {
if (parts == null || parts.size() == 0)
return;
if (!isRetType && parts.size() == 1) {
- if (!"void".equals(parts.get(0)))
+ if ("...".equals(parts.get(0))) {
+ type.add("...");
+ name = "";
+ } else if (!"void".equals(parts.get(0)))
failed = true; // Seems like bad C++ code here
return;
}
if (isRetType) {
Iterator it = parts.iterator();
- while (it.hasNext()) {
- String next = (String) it.next();
- if (null == type)
- type = next;
- else if ("*".equals(next) || "&".equals(next))
- type += next;
- else
- type += " " + next;
- }
-
+ while (it.hasNext())
+ type.add(it.next());
+
// Some methods return have void on their signature and others
// have nothing. So to make them both the same, if a method
// doesn't return anything make type null.
- if ("void".equals(type))
- type = null;
+ if (1 == type.size() && "void".equals(type.get(0)))
+ type = new ArrayList();
} else {
- // Keeping track of next and prev ensures we don't append the
- // parameter name onto the type.
- Iterator it = parts.iterator();
- String next = null, prev = (String) it.next();
- while (it.hasNext()) {
- next = (String) it.next();
- if (null == type)
- type = prev;
- else if ("*".equals(prev) || "&".equals(prev))
- type += prev;
- else
- type += " " + prev;
- prev = next;
+ // Cope with array subscripts [] after the name
+ int arrIdx = -1;
+ for (int i = 0; i < parts.size(); i++) {
+ String tok = (String) parts.get(i);
+ if ("[".equals(tok)) {
+ arrIdx = i;
+ break;
+ }
}
- name = next;
+
+ // Find the name
+ int nameIdx = parts.size() - 1;
+ if (-1 != arrIdx)
+ nameIdx = arrIdx - 1;
+
+ // Construct the type
+ for (int i = 0; i < nameIdx; i++)
+ type.add(parts.get(i));
+
+ name = (String) parts.get(nameIdx);
+ if (-1 != arrIdx)
+ for (int i = arrIdx; i < parts.size(); i++)
+ type.add(parts.get(i));
}
}
@@ -83,7 +95,35 @@
}
String getType() {
- return type;
+ String s = null;
+ Iterator it = type.iterator();
+ while (it.hasNext()) {
+ String next = (String) it.next();
+ if (null == s)
+ s = next;
+ else if ("*".equals(next) || "&".equals(next))
+ s += next;
+ else
+ s += " " + next;
+ }
+ return s;
+ }
+
+ String getTypeWithoutConst() {
+ String s = null;
+ Iterator it = type.iterator();
+ while (it.hasNext()) {
+ String next = (String) it.next();
+ if ("const".equals(next))
+ continue;
+ else if (null == s)
+ s = next;
+ else if ("*".equals(next) || "&".equals(next))
+ s += next;
+ else
+ s += " " + next;
+ }
+ return s;
}
String getName() {
@@ -91,14 +131,14 @@
}
boolean isVoid() {
- return null == type;
+ return 0 == type.size();
}
public String toString() {
- if (null == type)
+ if (0 == type.size())
return "void";
if (null == name)
- return type;
- return type + " " + name;
+ return getType();
+ return getType() + " " + name;
}
}
1.2 +49 -21 ws-axis/c/tools/trace/org/apache/axis/tracetool/Signature.java
Index: Signature.java
===================================================================
RCS file: /home/cvs/ws-axis/c/tools/trace/org/apache/axis/tracetool/Signature.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Signature.java 20 Sep 2004 16:09:58 -0000 1.1
+++ Signature.java 27 Sep 2004 15:33:46 -0000 1.2
@@ -23,7 +23,7 @@
import java.util.Set;
/**
- * A C or C++ method signature
+ * A C or C++ method signature with the ability to parse it.
* TODO: support variable length argument lists using "..."
* TODO: passing or returning function pointers (hopefully not needed)
* TODO: Cope with ~<space>Classname()
@@ -47,14 +47,29 @@
"private",
"extern",
"\"C\"",
- "virtual" }));
+ "virtual",
+ "static",
+ "inline",
+ "STORAGE_CLASS_INFO",
+ "AXISCALL" }));
+
+ private final static Set spuriousAttrs =
+ new HashSet(
+ Arrays.asList(
+ new Object[] {
+ "AXISCALL" }));
private final static Set specialOperators =
- new HashSet(Arrays.asList(new Object[] { "(", ")", "*", ",", "&" }));
+ new HashSet(
+ Arrays.asList(new Object[] { "(", ")", "*", ",", "&", "]", "[" }));
- // TODO: Should optionally pass in the className here in case it's an
- // inline method implementation inside the class{}. Just so the className
- // comes out in the trace.
+ /**
+ * Takes an unparsed signature string and parses it.
+ *
+ * TODO: Should optionally pass in the className here in case it's an
+ * inline method implementation inside the class{}. Just so the className
+ * comes out in the trace.
+ */
Signature(String s) {
originalText = s;
@@ -93,7 +108,7 @@
/**
* Parse the signature into tokens. This removes whitespace and comments
- * and separates out "*", ",", "(", ")" and "&".
+ * and separates out "*", ",", "(", ")", "&", "[" and "]".
*/
private static List tokenise(String s) {
ArrayList tokens = new ArrayList();
@@ -101,7 +116,7 @@
boolean space = true;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
- if (Utils.isSpace(c)) {
+ if (Character.isWhitespace(c)) {
space = true;
continue;
}
@@ -168,6 +183,8 @@
List trailAttrs,
List inits) {
+ // nameStart points to the start of the return type if there is one
+ // else the start of the method name
int nameStart;
for (nameStart = 0; nameStart < tokens.size(); nameStart++)
if (!knownAttrs.contains(tokens.get(nameStart)))
@@ -175,11 +192,15 @@
if (nameStart == tokens.size())
return false;
+ // initStart points to the initialisers, or thrown exceptions after
+ // the parameter list. throw is a keyword so we can safely search for it.
int initStart = tokens.size();
- for (int i = nameStart; i < tokens.size(); i++)
- if (((String) tokens.get(i)).startsWith(":")
- && !((String) tokens.get(i)).startsWith("::"))
+ for (int i = nameStart; i < tokens.size(); i++) {
+ String tok = (String) tokens.get(i);
+ if ((tok.startsWith(":") && !tok.startsWith("::"))
+ || "throw".equals(tok))
initStart = i;
+ }
int parmEnd;
for (parmEnd = initStart - 1; parmEnd > nameStart; parmEnd--)
@@ -195,7 +216,7 @@
for (int i = 0; i < tokens.size(); i++) {
Object tok = tokens.get(i);
- if (i < nameStart)
+ if (i < nameStart || spuriousAttrs.contains(tok))
attrs.add(tok);
else if (i < parmStart)
nameAndRet.add(tok);
@@ -238,14 +259,17 @@
idx = size - 1;
}
- // The class name comes before the method name
- if (idx > 0 && ((String) list.get(idx - 1)).endsWith("::")) {
- className = (String) list.get(idx - 1);
+ // The class name comes before the method name
+ while (idx > 0 && ((String) list.get(idx - 1)).endsWith("::")) {
+ if (null == className)
+ className = (String) list.get(idx - 1);
+ else
+ className = (String) list.get(idx - 1) + className;
idx--;
}
- // Whatever's left before the classname/methodname must be the
- // return type
+ // Whatever's left before the classname/methodname must be the
+ // return type
ArrayList retParm = new ArrayList();
for (int i = 0; i < idx; i++)
retParm.add(list.get(i));
@@ -259,9 +283,9 @@
private void parseParameters(List list) {
ArrayList alParams = new ArrayList();
Iterator it = list.iterator();
- it.next(); // step over the (
- while (it.hasNext()) {
- String token = (String) it.next();
+ String token = (String) it.next(); // step over the (
+ while (it.hasNext() && !")".equals(token)) {
+ token = (String) it.next();
int template = 0; // Depth of template scope
ArrayList parm = new ArrayList();
@@ -274,7 +298,9 @@
template--;
token = (String) it.next();
}
- if (token.equals(")"))
+
+ // No parameters so break out
+ if (token.equals(")") && 0 == parm.size())
break;
Parameter p = new Parameter(parm);
@@ -282,6 +308,8 @@
failed = true;
return;
}
+
+ // Copes with void func(void)
if (!p.isVoid())
alParams.add(p);
}
1.2 +149 -53 ws-axis/c/tools/trace/org/apache/axis/tracetool/Tracer.java
Index: Tracer.java
===================================================================
RCS file: /home/cvs/ws-axis/c/tools/trace/org/apache/axis/tracetool/Tracer.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Tracer.java 20 Sep 2004 16:09:58 -0000 1.1
+++ Tracer.java 27 Sep 2004 15:33:46 -0000 1.2
@@ -14,19 +14,44 @@
* limitations under the License.
*/
package org.apache.axis.tracetool;
-import java.awt.image.IndexColorModel;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Writer;
+import java.util.Hashtable;
/**
* A Buffered write that also contains the methods to add in in trace
* TODO: Add in &this and threadid into each trace record
+ * TODO: Sort out indentation
*/
class Tracer extends BufferedWriter {
private Signature signature = null;
private final static String SIGNATURE = " /* AUTOINSERTED TRACE */";
+ // Escape ?'s here to avoid trigraphs which map ??) to ]
+ private final static String UNKNOWN_FORMAT = "\\?\\?\\?\\?";
+
+ private static Hashtable primitives = new Hashtable();
+ static {
+ primitives.put("int", "%i");
+ primitives.put("unsigned int", "%u");
+ primitives.put("unsigned", "%u");
+ primitives.put("short", "%hi");
+ primitives.put("short int", "%hi");
+ primitives.put("unsigned short int", "%hu");
+ primitives.put("unsigned short", "%hu");
+ primitives.put("long", "%li");
+ primitives.put("long int", "%li");
+ primitives.put("unsigned long int", "%lu");
+ primitives.put("unsigned long", "%lu");
+ primitives.put("double", "%f");
+ primitives.put("float", "%f");
+ primitives.put("char", "%c");
+ primitives.put("unsigned char", "%c");
+ primitives.put("bool", "%s");
+ // TODO: More primitives go in here
+ }
+
/**
* @param writer a writer to the output file.
*/
@@ -54,39 +79,68 @@
*/
void traceEntry(Signature signature) throws IOException {
this.signature = signature;
- // TODO: System.out.println warm fuzzy about excluding
- // method here would be nice
if (!signature.traceable())
return;
- // TODO trace parameters
- write(
- "\n#ifdef ENABLE_AXISTRACE\n"
- + "if (g_pAT) AXISTRACE1(\"> "
- + pretty(signature.toString())
- + "\",INFO);"
- + SIGNATURE
- + "\n#endif\n");
+ String line =
+ "\n"
+ + " #ifdef ENABLE_AXISTRACE\n"
+ + " if (g_pAT) {\n"
+ + " char traceLine[256];\n"
+ + " sprintf(traceLine,\"> ";
+ if (null != signature.getClassName())
+ line += signature.getClassName();
+ line += signature.getMethodName();
+ line += "(";
+
+ Parameter[] parms = signature.getParameters();
+ for (int i = 0; null != parms && i < parms.length; i++) {
+ String f = getFormat(parms[i]);
+ if (0 != i)
+ line += ",";
+ if (null == f)
+ line += UNKNOWN_FORMAT;
+ else
+ line += f;
+ }
+ line += ")\"";
+
+ for (int i = 0; null != parms && i < parms.length; i++) {
+ if (null == getFormat(parms[i]))
+ continue;
+ line += "," + getName(parms[i]);
+ }
+
+ line += ");\n";
+ line += " AXISTRACE1(traceLine,INFO);" + SIGNATURE + "\n";
+ line += " }\n";
+ line += " #endif\n";
+ write(line);
flush();
}
- void traceExit() throws IOException {
+ void traceExit() throws Exception {
if (!signature.traceable())
return;
- // TODO check this method returns void
+ // Check this method really should return void
+ if (null != signature.getReturnType().getType())
+ Utils.rude(
+ "Expecting to return void from a method that returns a value: "
+ + signature.toString());
+
// Enclose the printf/return in {} in case if/then doesn't have {}
write("{");
write(
- "\n#ifdef ENABLE_AXISTRACE\n"
- + "if (g_pAT) AXISTRACE1(\"< "
+ "\n #ifdef ENABLE_AXISTRACE\n"
+ + " if (g_pAT) AXISTRACE1(\"< "
+ signature.getMethodName()
+ "\",INFO);"
+ SIGNATURE
- + "\n#endif\n");
+ + "\n #endif\n");
// now print out the return line itself
- write("return; }");
+ write(" return;\n }\n");
flush();
}
@@ -95,28 +149,64 @@
* This method prints out the complete return line as well so the user
* does not need to print this out themselves.
*/
- void traceExit(String value) throws IOException {
+ void traceExit(String value) throws Exception {
if (!signature.traceable())
return;
- // TODO avoid side effects such as return i++;
+ // Check this method doesn't return void
+ if (null == signature.getReturnType().getType())
+ Utils.rude(
+ "Expecting to return a value from a method that returns void: "
+ + signature.toString());
+
+ // Figure out the method name
+ String methodName = "";
+ if (null != signature.getClassName())
+ methodName = signature.getClassName();
+ methodName += signature.getMethodName();
+
+ // We can't trace all kinds of C types unfortunately
+ Parameter retType = signature.getReturnType();
+ String format = getFormat(retType);
+ String retValue;
+ if (null == format) {
+ format = UNKNOWN_FORMAT;
+ retValue = "";
+ } else
+ retValue = ", " + getName(retType);
// Enclose the printf/return in {} in case if/then doesn't have {}
- write("{");
- // write out the actual exit trace line
- // TODO trace the return value properly
- write(
- "\n#ifdef ENABLE_AXISTRACE\n"
- + "if (g_pAT) AXISTRACE1(\"< "
- + signature.getMethodName()
- + " = "
- + pretty(value)
- + "\",INFO);"
- + SIGNATURE
- + "\n#endif\n");
-
- // now print out the return line itself
- write("return " + value + "; }");
+ // Copy the return value into a local called traceRet in case the
+ // return value has side-effects such as "return i++;" or "return func();"
+ // This makes sure that we don't execute the return value twice.
+ // Unfortunately if the return value is a class we will invoke
+ // a copy constructor. When initialising traceRet with value, put value
+ // in brackets in case it contains an operator that might be invoked
+ // after the assignment, like another assignment.
+ String line = " {\n";
+ line += " #ifdef ENABLE_AXISTRACE\n";
+ line += " "
+ + retType.getType()
+ + " traceRet = ("
+ + value
+ + ");\n";
+ line += " if (g_pAT) {\n";
+ line += " char traceLine[256];\n";
+ line += " sprintf(traceLine,\"< "
+ + methodName
+ + "("
+ + format
+ + ")\""
+ + retValue
+ + ");\n";
+ line += " AXISTRACE1(traceLine,INFO);" + SIGNATURE + "\n";
+ line += " }\n";
+ line += " return traceRet;\n";
+ line += " #else\n";
+ line += " return " + value + ";\n";
+ line += " #endif\n";
+ line += " }\n";
+ write(line);
flush();
}
@@ -126,24 +216,30 @@
System.out.print(s);
}
- /**
- * Escapes special characters like " so that they can be output
- * in a C string literal. Also removes newlines, since C string
- * literals can't be split over lines.
- */
- private String pretty(String s) {
- StringBuffer sb = new StringBuffer(s);
- for (int i = 0; i < sb.length(); i++)
- switch (sb.charAt(i)) {
- case '"' :
- sb = sb.insert(i, '\\');
- i++;
- break;
- case '\n' :
- sb = sb.deleteCharAt(i);
- i--;
- break;
- }
- return sb.toString();
+ private String getFormat(Parameter p) {
+ String format = null;
+ String type = p.getTypeWithoutConst();
+ if (null == type || 0 == type.length())
+ format = null;
+ else if (type.endsWith("*"))
+ // TODO print out contents of pointers where possible
+ format = "%p";
+ else if (primitives.keySet().contains(type))
+ format = (String) primitives.get(type);
+ // else System.err.println("Unknown format type "+type);
+ // TODO: more elses should go in here
+ return format;
+ }
+
+ private String getName(Parameter p) {
+ String name = p.getName();
+ if (null == name)
+ name = "traceRet";
+
+ if ("bool".equals(p.getTypeWithoutConst())) {
+ return "(" + name + "?\"true\":\"false\")";
+ } else
+ return name;
}
+
}
1.2 +37 -25 ws-axis/c/tools/trace/org/apache/axis/tracetool/Utils.java
Index: Utils.java
===================================================================
RCS file: /home/cvs/ws-axis/c/tools/trace/org/apache/axis/tracetool/Utils.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Utils.java 20 Sep 2004 16:09:58 -0000 1.1
+++ Utils.java 27 Sep 2004 15:33:46 -0000 1.2
@@ -22,39 +22,23 @@
* TODO: Many of these methods would perform better using StringBuffer not String
*/
final class Utils {
- public static final String whitespace =
- " \t" + System.getProperty("line.separator");
- private static final String letters =
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
- private static final String alphanumerics =
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
- /** Never instantiate this class */
+ /**
+ * Never instantiate this class
+ */
private Utils() {
}
- static boolean isSpace(char c) {
- return whitespace.indexOf(c) != -1;
- }
-
/**
* Is this string all whitespace?
*/
static boolean isSpace(String s) {
- for (int i = 0; i < s.length(); i++)
- if (-1 != whitespace.indexOf(s.charAt(i)))
+ for (int i = 0; i < s.length(); i++)
+ if (!Character.isWhitespace(s.charAt(i)))
return false;
return true;
}
- static boolean startsWithALetter(String s) {
- return letters.indexOf(s.charAt(0)) != -1;
- }
-
- static boolean isAlphaNumeric(char c) {
- return alphanumerics.indexOf(c) != -1;
- }
-
// TODO look for other trailing chars like { (because of class{)
static boolean startsWith(String source, String target) {
if (source == null || target == null)
@@ -63,7 +47,7 @@
return false;
if (source.length() == target.length())
return true;
- if (isSpace(source.charAt(target.length())))
+ if (Character.isWhitespace(source.charAt(target.length())))
return true;
return false;
}
@@ -97,9 +81,9 @@
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == t0
&& s.substring(i).startsWith(t)
- && (0 == i || !Utils.isAlphaNumeric(s.charAt(i - 1)))
+ && (0 == i || !Character.isLetterOrDigit(s.charAt(i - 1)))
&& (s.length() == (i + t.length())
- || !Utils.isAlphaNumeric(s.charAt(i + t.length()))))
+ || !Character.isLetterOrDigit(s.charAt(i + t.length()))))
return i;
i = skip(s.substring(i), i);
@@ -167,6 +151,27 @@
rude(reason, null, 0, null);
}
+ /**
+ * Escapes special characters like " so that they can be output
+ * in a C string literal. Also removes newlines, since C string
+ * literals can't be split over lines.
+ */
+ String pretty(String s) {
+ StringBuffer sb = new StringBuffer(s);
+ for (int i = 0; i < sb.length(); i++)
+ switch (sb.charAt(i)) {
+ case '"' :
+ sb = sb.insert(i, '\\');
+ i++;
+ break;
+ case '\n' :
+ sb = sb.deleteCharAt(i);
+ i--;
+ break;
+ }
+ return sb.toString();
+ }
+
private static boolean startsWithComment(String s) {
if (null == s || s.length() < 2)
return false;
@@ -207,13 +212,20 @@
// \" or \' does not end the literal
if ('\\' == s.charAt(i))
- escape = true;
+ // Escaping a \ should switch escape off so \\' does end
+ // the literal
+ escape = !escape;
else
escape = false;
}
return -1;
}
+ /**
+ * If the String s starts with a string literal or a comment, return
+ * i plus the index of the end of the literal or comment. String literals
+ * are enclosed in " or ' and comments start with /* or //.
+ */
private static int skip(String s, int i) {
int j = 0;
if (startsWithStringLiteral(s)) {