java/ch/wlkl/wsh/Strings.java
package ch.wlkl.wsh;
import static ch.wlkl.wsh.Env.env;
import java.util.Collection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Strings extends Top {
final static Pattern oneWord = Pattern.compile("\\s*(\\S+)");
final private static Matcher xQuoteMatcher = Pattern.compile("[^\"\\\\\n]+").matcher("");
public static String unquote(String src) {
if (src.length() == 0)
return src;
final char qu = src.charAt(0);
String res = "";
int ex, bx = 1;
while (true) {
ex = src.indexOf(qu, bx);
if (ex < 0)
sFail("non terminated string: " + src);
if (ex == src.length() - 1 )
return res + src.substring(bx, ex);
if (src.charAt(ex+1) != qu)
sFail("single quote at position " + ex + " in string: " + src);
res += src.substring(bx, ex) + qu;
bx = ex+2;
}
}
public static String quote(String src) {
return quote(src, "\"");
}
public static String quote(String src, String q) {
String res = q;
if (src == null)
return q + q;
int fx = 0;
int px;
while(true) {
px = src.indexOf(q, fx);
if (px < 0)
break;
res += src.substring(fx, fx = q.length() + px) + q;
}
return res + src.substring(fx) + q;
}
public static String hex(CharSequence src) {
StringBuffer b = new StringBuffer(2 * src.length());
for (int ix=0; ix < src. length(); ix ++) {
char c = src.charAt(ix);
if (c < 256)
b.append(String.format("%2h", c));
else
b.append("\\u(").append(String.format("%h", c)).append(')');
}
return b.toString();
}
public static String xUnquote(String src) {
if (src == null || src.length() <= 1)
sFail("cannot unquote this string: <" + src + ">");
StringBuffer buf = new StringBuffer("");
final char qu = src.charAt(0);
char c = 0;
int sx = 1, qx = 0, bx = 0;
while (true) {
if (qx < sx)
if ((qx = src.indexOf(qu, sx)) < 0)
qx = src.length();
if (bx < sx)
if ((bx = src.indexOf('\\', sx)) < 0)
bx = src.length();
if (bx < qx) {
if (bx + 1>= src.length())
sFail("backslash at end of String: <" + src + ">");
buf.append(src, sx, bx).append((c = src.charAt(bx+1)) == 'n' ? '\n' : c == 't' ? 't' : c);
sx = bx+2;
} else {
if (qx + 1 == src.length())
return buf.append(src, sx, qx).toString();
else
sFail("quote within String: <" + src + ">");
}
}
}
public static String xQuote(String src) {
if (src == null)
return "\"\"";
StringBuffer buf = new StringBuffer("\"");
int nx = 0;
xQuoteMatcher.reset(src);
while (true) {
if (xQuoteMatcher.lookingAt()) {
buf.append(xQuoteMatcher.group());
nx = xQuoteMatcher.end();
}
if (nx >= src.length())
return buf.append('"').toString();
buf.append('\\').append(src.charAt(nx) == '\n' ? 'n' : src.charAt(nx));
xQuoteMatcher.region(++nx, src.length());
}
}
public static String fill(String rep, int len) {
StringBuffer b = new StringBuffer(rep == null || rep.equals("") ? " " : rep);
while (b.length() < len)
b.append(b);
return b.substring(0, len);
}
public static String cut(String src, int len, String rep) {
int l = src.length();
return l == len ? src : l < len ? src + fill(rep, len - l) : src.substring(0, len);
}
public static String cat(Collection<String> lst, String le, String mi, String ri) {
StringBuffer b = new StringBuffer(le);
boolean first = true;
for (String s : lst) {
if (first)
first = false;
else
b.append(mi);
b.append(s);
}
return b.append(ri).toString();
}
public static String cat(Collection<String> lst, String mi) {
return cat(lst, "", mi, "");
}
public static void words() {
Matcher match = oneWord.matcher("");
String one;
while (null != (one = env().read())) {
match.reset(one);
while (match.lookingAt()) {
env().write(match.group(1));
match.region(match.end(), one.length());
}
}
}
public static void wc(boolean wrLines) {
Matcher match = oneWord.matcher("");
String one;
int lc = 0, wc = 0, cc = 0;
while (null != (one = env().read())) {
lc ++;
cc += one.length();
match.reset(one);
while (match.lookingAt()) {
wc++;
match.region(match.end(), one.length());
}
if (wrLines)
env().write(one);
}
env().write("counted " + lc + " lines, " + wc + " words, " + cc + " chars");
}
}