blob: 0134cb1bb4524c4e77ac66592564dece1a8345ed [file] [log] [blame]
/*
*******************************************************************************
* Copyright (C) 2001-2009, International Business Machines
* Corporation and others. All Rights Reserved.
*******************************************************************************
*/
package com.ibm.icu.dev.test.shaping;
import com.ibm.icu.text.ArabicShaping;
import com.ibm.icu.text.ArabicShapingException;
/**
* Interactive test for Arabic shaping.
* Invoke from a command line passing args and strings. Use '-help' to see description of arguments.
*/
public class ArabicShapingTest{
private static final int COPY = 0;
private static final int INPLACE = 1;
private static final int STRING = 2;
public static final void main(String[] args) {
int testtype = COPY;
int options = 0;
int ss = 0;
int sl = -1;
int ds = 0;
int dl = -1;
String text = "$22.4 test 123 \ufef6\u0644\u0622 456 \u0664\u0665\u0666!";
for (int i = 0; i < args.length; ++i) {
String arg = args[i];
if (arg.charAt(0) == '-') {
String opt = arg.substring(1);
String val = opt;
int index = arg.indexOf(':');
if (index != -1) {
opt = opt.substring(0, Math.min(index, 3));
val = arg.substring(index + 1);
}
if (opt.equalsIgnoreCase("len")) {
options &= ~ArabicShaping.LENGTH_MASK;
if (val.equalsIgnoreCase("gs")) {
options |= ArabicShaping.LENGTH_GROW_SHRINK;
} else if (val.equalsIgnoreCase("sn")) {
options |= ArabicShaping.LENGTH_FIXED_SPACES_NEAR;
} else if (val.equalsIgnoreCase("se")) {
options |= ArabicShaping.LENGTH_FIXED_SPACES_AT_END;
} else if (val.equalsIgnoreCase("sb")) {
options |= ArabicShaping.LENGTH_FIXED_SPACES_AT_BEGINNING;
} else {
throwValError(opt, val);
}
} else if (opt.equalsIgnoreCase("dir")) {
options &= ~ArabicShaping.TEXT_DIRECTION_MASK;
if (val.equalsIgnoreCase("log")) {
options |= ArabicShaping.TEXT_DIRECTION_LOGICAL;
} else if (val.equalsIgnoreCase("vis")) {
options |= ArabicShaping.TEXT_DIRECTION_VISUAL_LTR;
} else {
throwValError(opt, val);
}
} else if (opt.equalsIgnoreCase("let")) {
options &= ~ArabicShaping.LETTERS_MASK;
if (val.equalsIgnoreCase("no")) {
options |= ArabicShaping.LETTERS_NOOP;
} else if (val.equalsIgnoreCase("sh")) {
options |= ArabicShaping.LETTERS_SHAPE;
} else if (val.equalsIgnoreCase("un")) {
options |= ArabicShaping.LETTERS_UNSHAPE;
} else if (val.equalsIgnoreCase("ta")) {
options |= ArabicShaping.LETTERS_SHAPE_TASHKEEL_ISOLATED;
} else {
throwValError(opt, val);
}
} else if (opt.equalsIgnoreCase("dig")) {
options &= ~ArabicShaping.DIGITS_MASK;
if (val.equalsIgnoreCase("no")) {
options |= ArabicShaping.DIGITS_NOOP;
} else if (val.equalsIgnoreCase("ea")) {
options |= ArabicShaping.DIGITS_EN2AN;
} else if (val.equalsIgnoreCase("ae")) {
options |= ArabicShaping.DIGITS_AN2EN;
} else if (val.equalsIgnoreCase("lr")) {
options |= ArabicShaping.DIGITS_EN2AN_INIT_LR;
} else if (val.equalsIgnoreCase("al")) {
options |= ArabicShaping.DIGITS_EN2AN_INIT_AL;
} else {
throwValError(opt, val);
}
} else if (opt.equalsIgnoreCase("typ")) {
options &= ~ArabicShaping.DIGIT_TYPE_MASK;
if (val.equalsIgnoreCase("an")) {
options |= ArabicShaping.DIGIT_TYPE_AN;
} else if (val.equalsIgnoreCase("ex")) {
options |= ArabicShaping.DIGIT_TYPE_AN_EXTENDED;
} else {
throwValError(opt, val);
}
} else if (opt.equalsIgnoreCase("dst")) {
try {
ds = Integer.parseInt(val);
}
catch (Exception e) {
throwValError(opt, val);
}
} else if (opt.equalsIgnoreCase("dln")) {
try {
dl = Integer.parseInt(val);
}
catch (Exception e) {
throwValError(opt, val);
}
} else if (opt.equalsIgnoreCase("sst")) {
try {
ss = Integer.parseInt(val);
}
catch (Exception e) {
throwValError(opt, val);
}
} else if (opt.equalsIgnoreCase("sln")) {
try {
sl = Integer.parseInt(val);
}
catch (Exception e) {
throwValError(opt, val);
}
} else if (opt.equalsIgnoreCase("tes")) {
if (val.equalsIgnoreCase("cp")) {
testtype = COPY;
} else if (val.equalsIgnoreCase("ip")) {
testtype = INPLACE;
} else if (val.equalsIgnoreCase("st")) {
testtype = STRING;
} else {
throwValError(opt, val);
}
} else if (opt.equalsIgnoreCase("help")) {
System.out.println(usage);
} else {
throwOptError(opt);
}
} else {
// assume text
text = parseText(arg);
}
}
if (sl < 0) {
sl = text.length() - ss;
System.out.println("sl defaulting to " + sl);
}
if (dl < 0) {
dl = 2 * sl;
System.out.println("dl defaulting to " + dl);
}
ArabicShaping shaper = new ArabicShaping(options);
System.out.println("shaper: " + shaper);
char[] src = text.toCharArray();
System.out.println(" input: '" + escapedText(src, ss, sl) + "'");
if (testtype != STRING) {
System.out.println("start: " + ss + " length: " + sl + " total length: " + src.length);
}
int result = -1;
char[] dest = null;
try {
switch (testtype) {
case COPY:
dest = new char[ds + dl];
result = shaper.shape(src, ss, sl, dest, ds, dl);
break;
case INPLACE:
shaper.shape(src, ss, sl);
ds = ss;
result = sl;
dest = src;
break;
case STRING:
dest = shaper.shape(text).toCharArray();
ds = 0;
result = dest.length;
break;
}
System.out.println("output: '" + escapedText(dest, ds, result) + "'");
System.out.println("length: " + result);
if (ds != 0 || result != dest.length) {
System.out.println("full output: '" + escapedText(dest, 0, dest.length) + "'");
}
}
catch (ArabicShapingException e) {
System.out.println("Caught ArabicShapingException");
System.out.println(e);
}
catch (Exception e) {
System.out.println("Caught Exception");
System.out.println(e);
}
}
private static void throwOptError(String opt) {
throwUsageError("unknown option: " + opt);
}
private static void throwValError(String opt, String val) {
throwUsageError("unknown value: " + val + " for option: " + opt);
}
private static void throwUsageError(String message) {
StringBuffer buf = new StringBuffer("*** usage error ***\n");
buf.append(message);
buf.append("\n");
buf.append(usage);
throw new Error(buf.toString());
}
private static final String usage =
"Usage: [option]* [text]\n" +
" where option is in the format '-opt[:val]'\n" +
" options are:\n" +
" -len:[gs|sn|se|sb] (length: grow/shrink, spaces near, spaces end, spaces beginning)\n" +
" -dir:[log|vis] (direction: logical, visual)\n" +
" -let:[no|sh|un|ta] (letters: noop, shape, unshape, tashkeel)\n" +
// " -let:[no|sh|un] (letters: noop, shape, unshape)\n" +
" -dig:[no|ea|ae|lr|al] (digits: noop, en2an, an2en, en2an_lr, en2an_al)\n" +
" -typ:[an|ex] (digit type: arabic, arabic extended)\n" +
" -dst:# (dest start: [integer])\n" +
" -dln:# (dest length (max size): [integer])\n" +
" -sst:# (source start: [integer])\n" +
" -sln:# (source length: [integer])\n" +
" -tes:[cp|ip|st] (test type: copy, in place, string)\n" +
" -help (print this help message)\n" +
" text can contain unicode escape values in the format '\\uXXXX' only\n";
private static String escapedText(char[] text, int start, int length) {
StringBuffer buf = new StringBuffer();
for (int i = start, e = start + length; i < e; ++i) {
char ch = text[i];
if (ch < 0x20 || ch > 0x7e) {
buf.append("\\u");
if (ch < 0x1000) {
buf.append('0');
}
if (ch < 0x100) {
buf.append('0');
}
if (ch < 0x10) {
buf.append('0');
}
buf.append(Integer.toHexString(ch));
} else {
buf.append(ch);
}
}
return buf.toString();
}
private static String parseText(String text) {
// process unicode escapes (only)
StringBuffer buf = new StringBuffer();
char[] chars = text.toCharArray();
for (int i = 0; i < chars.length; ++i) {
char ch = chars[i];
if (ch == '\\') {
if ((i < chars.length - 1) &&
(chars[i+1] == 'u')) {
int val = Integer.parseInt(text.substring(i+2, i+6), 16);
buf.append((char)val);
i += 5;
} else {
buf.append('\\');
}
} else {
buf.append(ch);
}
}
return buf.toString();
}
}