Added: library/trunk/lib/test/ansi.cpp (16 => 17)
--- library/trunk/lib/test/ansi.cpp 2006-08-15 17:27:10 UTC (rev 16)
+++ library/trunk/lib/test/ansi.cpp 2006-08-18 18:12:11 UTC (rev 17)
@@ -0,0 +1,374 @@
+/* Found at http://home.tiscali.dk/8x305617/provide/ansi.html */
+#include <condefs.h>
+#include <conio.h>
+#include <cstdio>
+#include <cctype>
+#include <string>
+#include <vector>
+#pragma hdrstop
+#include <io.h>
+#include <fcntl.h>
+using namespace std;
+
+/*
+ Borland C++ Builder 4.0 source code (console mode program).
+
+ Could probably compile on other
+ Win32 compilers with small changes.
+*/
+
+
+char const documentation[] =
+ "ANSI.EXE: An ANSI escape sequence filter for Win32 console mode.\n"
+ "\n"
+ "Redirect any program generating ANSI escape sequences through ANSI.EXE\n"
+ "using filtering:\n"
+ " OtherProgram.exe ...other program arguments... | ansi\n"
+ "\n"
+ "and ANSI.EXE will translate the embedded escape sequences into the\n"
+ "appropriate colours, cursor movements etc.\n"
+ "\n"
+ "Keyboard redefinition not supported.\n"
+ "\n"
+ "Freeware. Further information:\n"
+ "\t<URL:http://home13.inet.tele.dk/ajm/provide/ansi.html>\n"
+ "\n"
+ "regards,\n"
+ "Anders Munch, andersjm@post.tele.dk, June 18 2000\n"
+ ;
+
+
+
+
+//---------------------------------------------------------------------------
+static void ConvertAnsiToScreen();
+
+#pragma argsused
+int main(int argc, char* argv[])
+{
+ if(argc > 1)
+ {
+ fprintf(stderr, "%s", documentation);
+ }
+ else
+ {
+ setmode(fileno(stdin), O_BINARY);
+
+ ConvertAnsiToScreen();
+ }
+ return 0;
+}
+
+static int nextchar = EOF;
+std::string unechoed;
+
+inline unsigned char current()
+{ return static_cast<unsigned char>(nextchar); }
+inline bool atend()
+{ return nextchar == EOF || nextchar == '\032'; }
+
+static void advance()
+{
+ if(nextchar != EOF)
+ unechoed.push_back(current());
+ nextchar = getchar();
+}
+static void consume_current()
+{
+ nextchar = EOF;
+}
+static void flush()
+{
+ cputs(unechoed.c_str());
+ unechoed.clear();
+}
+static void newline()
+{
+ cputs("\r\n");
+}
+static void consume_previous() { unechoed.clear(); }
+
+static long ReadInteger()
+{
+ int val = 0;
+ while(isdigit(current()))
+ {
+ val = val * 10 + (current()-'0');
+ advance();
+ }
+ return val;
+}
+
+static int translate_colour(int ansic)
+{
+ switch(ansic)
+ {
+ default: /* impossible */;
+ case 0: return BLACK;
+ case 1: return RED;
+ case 2: return GREEN;
+ case 3: return YELLOW;
+ case 4: return BLUE;
+ case 5: return MAGENTA;
+ case 6: return CYAN;
+ case 7: return WHITE;
+ }
+}
+static void UNKNOWN_ANSI(unsigned char cmd, vector<long> const& params)
+{
+ cprintf("\r\nUNSUPPORTED ANSI COMMAND '%c', %d PARAMETERS\r\n",
+ cmd, (int)params.size());
+}
+
+
+static void InterpretAnsiCommand(
+ unsigned char command,
+ bool equals_sign,
+ vector<long>& parameters)
+/*
+ Called for input on the form:
+ ESC [ P1;P2;....;PN c (equals_sign == false)
+ or ESC [ = P1;P2;....;PN c (equals_sign == true)
+
+ c is a single alphabetic letter, stored in 'command'.
+
+ P1..PN are integer parameters, stored in 'params':
+ N==params.size().
+ Omitted (empty string) numbers are identified by EOF in 'params'.
+
+ Commands with string parameters will _not_ reach this point.
+
+ Wrt. illegal parameters and unsupported commands: some are diagnosed with
+ and error message (through UNKNOWN_ANSI). Others are silently ignored.
+*/
+
+{
+ static int saved_x = 1, saved_y = 1;
+ struct text_info ti;
+ size_t paramcount = parameters.size();
+
+ gettextinfo(&ti);
+
+ if(command == 'm')
+ {
+ int attribute = ti.attribute;
+ vector<long>::iterator it;
+ for(it=parameters.begin(); it!= parameters.end(); ++it)
+ {
+ int a = *it;
+
+ if(a >= 30 && a <= 37)
+ attribute = (attribute & 0xF0) | translate_colour(a-30);
+ else if(a >= 40 && a <= 47)
+ attribute = (attribute & 0x8F)
+ | ((translate_colour(a-40) & 0x07) << 4);
+ else if(a == 5)
+ attribute |= 0x80;
+ else if(a == 0)
+ attribute = ti.normattr;
+ else if(a == 1)
+ attribute |= 0x08;
+ else if(a == 7)
+ attribute = ((attribute & 0x70) >> 4)
+ | ((attribute & 0x07) << 4)
+ | (attribute & 0x80);
+ else if(a == 8)
+ attribute = 0;
+ }
+
+ textattr(attribute);
+
+ }
+
+ else if(paramcount == 0)
+ {
+ switch(command)
+ {
+ case 's':
+ {
+ saved_x = ti.curx;
+ saved_y = ti.cury;
+ }
+ break;
+
+ case 'u':
+ {
+ gotoxy(saved_x, saved_y);
+ }
+ break;
+
+ case 'K':
+ {
+ clreol();
+ }
+ break;
+
+ default: UNKNOWN_ANSI(command, parameters);
+ }
+ }
+
+ else if(paramcount == 1)
+ {
+ switch(command)
+ {
+ case 'J':
+ {
+ /* assume parameters.size()==1, parameters[0]==2 */
+ clrscr();
+ }
+ break;
+
+ case 'A':
+ {
+ gotoxy(ti.curx, max(1L, ti.cury-parameters[0]));
+ }
+ break;
+
+ case 'B':
+ {
+ gotoxy(ti.curx, ti.cury+parameters[0]);
+ }
+ break;
+
+ case 'C':
+ {
+ gotoxy(ti.curx+parameters[0], ti.cury);
+ }
+ break;
+
+ case 'D':
+ {
+ gotoxy(max(1L, ti.curx-parameters[0]), ti.cury);
+ }
+ break;
+
+ case 'h':
+ {
+ if(equals_sign)
+ {
+ int req = EOF;
+ const int DENIED = EOF;
+ const int NOT_IMPLEMENTED = EOF;
+ switch(parameters[0])
+ {
+ case 0: req = BW40; break;
+ case 1: req = C40; break;
+ case 2: req = BW80; break;
+ case 3: req = C80; break;
+ case 4: req = DENIED; break;
+ case 5: req = DENIED; break;
+ case 6: req = DENIED; break;
+ case 7: req = NOT_IMPLEMENTED; break;
+ }
+
+ if(req != EOF)
+ textmode(req);
+ }
+ }
+ break;
+
+ default: UNKNOWN_ANSI(command, parameters);
+ }
+ }
+
+ else if(paramcount == 2)
+ {
+ switch(command)
+ {
+ case 'H': case 'f':
+ {
+ int row = parameters[0];
+ if(row == EOF) row = 1;
+ int col = parameters[1];
+ if(col == EOF) col = 1;
+
+ gotoxy(col, row);
+ }
+ break;
+ default: UNKNOWN_ANSI(command, parameters);
+ }
+ }
+}
+
+
+static void ConvertAnsiToScreen()
+/*
+ Input parser.
+
+ Reads standard input (encapsulated by rule-based functions
+ advance(), current(), atend() etc.
+
+ When an ANSI escape sequences is met, InterpretAnsiCommand is called
+ to figure out what to do with it.
+
+*/
+{
+ advance();
+ while(! atend())
+ {
+ switch(current())
+ {
+ case '\033':
+ {
+ advance();
+
+ if(! atend() && current() == '[')
+ {
+ bool equals_sign;
+ advance();
+
+ if(! atend() && current() == '=')
+ {
+ equals_sign = true; advance();
+ }
+ else equals_sign = false;
+
+ vector<long> parameters;
+ if(!atend() && (isdigit(current()) || current()==';'))
+ {
+ if(current() == ';')
+ parameters.push_back(EOF);
+ else
+ parameters.push_back(ReadInteger());
+
+ while(!atend() && current()==';')
+ {
+ advance();
+ if(!atend() && isdigit(current()))
+ parameters.push_back(ReadInteger());
+ else
+ parameters.push_back(EOF);
+ }
+ }
+
+ if(!atend() && isalpha(current()))
+ {
+ char command = current();
+ consume_previous(); consume_current(); flush();
+ InterpretAnsiCommand(command, equals_sign, parameters);
+ advance();
+ }
+ }
+ }
+ break;
+
+ case '\n':
+ {
+ consume_current();
+ flush(); newline();
+
+ advance();
+ }
+ break;
+
+ default:
+ {
+ advance();
+ }
+ break;
+ }
+
+ flush();
+ }
+
+}
Property changes on: library/trunk/lib/test/ansi.cpp
___________________________________________________________________
Name: tsvn:logminsize
+ 15
Modified: library/trunk/lib/test/run.bat (16 => 17)
--- library/trunk/lib/test/run.bat 2006-08-15 17:27:10 UTC (rev 16)
+++ library/trunk/lib/test/run.bat 2006-08-18 18:12:11 UTC (rev 17)
@@ -26,7 +26,7 @@
IF %PHP_BIN% == "" GOTO ERROR1
IF %PHP_INI% == "" GOTO ERROR2
-%PHP_BIN% -c %PHP_INI% run.php %1 %2 %3 %4
+%PHP_BIN% -c %PHP_INI% run.php %1 %2 %3 %4 | ansi.exe
GOTO END
:ERROR1
Modified: library/trunk/lib/test/run.sh (16 => 17)
--- library/trunk/lib/test/run.sh 2006-08-15 17:27:10 UTC (rev 16)
+++ library/trunk/lib/test/run.sh 2006-08-18 18:12:11 UTC (rev 17)
@@ -15,7 +15,7 @@
# * @category config
# */
-# path to php cli
+# path to php cli binary
# example - /usr/bin/php
php_bin=