Curses { public static void tputs(Writer out, String str, Object... params) throws IOException { int index = 0; int length = str.length(); int ifte = IFTE_NONE; boolean exec = true; Stack<Object> stack = new Stack<Object>(); while (index < length) { char ch = str.charAt(index++); switch (ch) { case '\\': ch = str.charAt(index++); if (ch >= '0' && ch <= '9') { throw new UnsupportedOperationException(); } else { switch (ch) { case 'e': case 'E': if (exec) { out.write(27); } break; case 'n': out.write('\n'); break; case 'r': if (exec) { out.write('\r'); } break; case 't': if (exec) { out.write('\t'); } break; case 'b': if (exec) { out.write('\b'); } break; case 'f': if (exec) { out.write('\f'); } break; case 's': if (exec) { out.write(' '); } break; case ':': case '^': case '\\': if (exec) { out.write(ch); } break; default: throw new IllegalArgumentException(); } } break; case '^': ch = str.charAt(index++); if (exec) { out.write(ch - '@'); } break; case '%': ch = str.charAt(index++); switch (ch) { case '%': if (exec) { out.write('%'); } break; case 'p': ch = str.charAt(index++); if (exec) { stack.push(params[ch - '1']); } break; case 'P': ch = str.charAt(index++); if (ch >= 'a' && ch <= 'z') { if (exec) { dv[ch - 'a'] = stack.pop(); } } else if (ch >= 'A' && ch <= 'Z') { if (exec) { sv[ch - 'A'] = stack.pop(); } } else { throw new IllegalArgumentException(); } break; case 'g': ch = str.charAt(index++); if (ch >= 'a' && ch <= 'z') { if (exec) { stack.push(dv[ch - 'a']); } } else if (ch >= 'A' && ch <= 'Z') { if (exec) { stack.push(sv[ch - 'A']); } } else { throw new IllegalArgumentException(); } break; case '\'': ch = str.charAt(index++); if (exec) { stack.push((int) ch); } ch = str.charAt(index++); if (ch != '\'') { throw new IllegalArgumentException(); } break; case '{': int start = index; while (str.charAt(index++) != '}'); if (exec) { int v = Integer.valueOf(str.substring(start, index - 1)); stack.push(v); } break; case 'l': if (exec) { stack.push(stack.pop().toString().length()); } break; case '+': if (exec) { int v2 = toInteger(stack.pop()); int v1 = toInteger(stack.pop()); stack.push(v1 + v2); } break; case '-': if (exec) { int v2 = toInteger(stack.pop()); int v1 = toInteger(stack.pop()); stack.push(v1 - v2); } break; case '*': if (exec) { int v2 = toInteger(stack.pop()); int v1 = toInteger(stack.pop()); stack.push(v1 * v2); } break; case '/': if (exec) { int v2 = toInteger(stack.pop()); int v1 = toInteger(stack.pop()); stack.push(v1 / v2); } break; case 'm': if (exec) { int v2 = toInteger(stack.pop()); int v1 = toInteger(stack.pop()); stack.push(v1 % v2); } break; case '&': if (exec) { int v2 = toInteger(stack.pop()); int v1 = toInteger(stack.pop()); stack.push(v1 & v2); } break; case '|': if (exec) { int v2 = toInteger(stack.pop()); int v1 = toInteger(stack.pop()); stack.push(v1 | v2); } break; case '^': if (exec) { int v2 = toInteger(stack.pop()); int v1 = toInteger(stack.pop()); stack.push(v1 ^ v2); } break; case '=': if (exec) { int v2 = toInteger(stack.pop()); int v1 = toInteger(stack.pop()); stack.push(v1 == v2); } break; case '>': if (exec) { int v2 = toInteger(stack.pop()); int v1 = toInteger(stack.pop()); stack.push(v1 > v2); } break; case '<': if (exec) { int v2 = toInteger(stack.pop()); int v1 = toInteger(stack.pop()); stack.push(v1 < v2); } break; case 'A': if (exec) { int v2 = toInteger(stack.pop()); int v1 = toInteger(stack.pop()); stack.push(v1 != 0 && v2 != 0); } break; case '!': if (exec) { int v1 = toInteger(stack.pop()); stack.push(v1 == 0); } break; case '~': if (exec) { int v1 = toInteger(stack.pop()); stack.push(~v1); } break; case 'O': if (exec) { int v2 = toInteger(stack.pop()); int v1 = toInteger(stack.pop()); stack.push(v1 != 0 || v2 != 0); } break; case '?': if (ifte != IFTE_NONE) { throw new IllegalArgumentException(); } else { ifte = IFTE_IF; } break; case 't': if (ifte != IFTE_IF && ifte != IFTE_ELSE) { throw new IllegalArgumentException(); } else { ifte = IFTE_THEN; } exec = toInteger(stack.pop()) != 0; break; case 'e': if (ifte != IFTE_THEN) { throw new IllegalArgumentException(); } else { ifte = IFTE_ELSE; } exec = !exec; break; case ';': if (ifte == IFTE_NONE || ifte == IFTE_IF) { throw new IllegalArgumentException(); } else { ifte = IFTE_NONE; } exec = true; break; case 'i': if (params.length >= 1) { params[0] = toInteger(params[0]) + 1; } if (params.length >= 2) { params[1] = toInteger(params[1]) + 1; } break; case 'd': out.write(Integer.toString(toInteger(stack.pop()))); break; default: throw new UnsupportedOperationException(); } break; case '$': if (str.charAt(index) == '<') { while (str.charAt(index++) != '>'); } else { if (exec) { out.write(ch); } } break; default: if (exec) { out.write(ch); } break; } } } private  Curses(); static void tputs(Writer out, String str, Object... params);  }
@Test public void testTputs() throws Exception { assertEquals("\033[3;4r", tputs("\\E[%i%p1%d;%p2%dr", 2, 3)); }