mux/src/stringutil.cpp

Go to the documentation of this file.
00001 // stringutil.cpp -- string utilities.
00002 //
00003 // $Id: stringutil.cpp,v 1.75 2006/09/11 23:57:47 sdennis Exp $
00004 //
00005 // MUX 2.4
00006 // Copyright (C) 1998 through 2004 Solid Vertical Domains, Ltd. All
00007 // rights not explicitly given are reserved.
00008 //
00009 #include "copyright.h"
00010 #include "autoconf.h"
00011 #include "config.h"
00012 #include "externs.h"
00013 
00014 #include "ansi.h"
00015 #include "pcre.h"
00016 
00017 const bool mux_isprint[256] =
00018 {
00019 //  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00020 //
00021     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 0
00022     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1
00023     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 2
00024     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 3
00025     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
00026     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5
00027     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
00028     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,  // 7
00029 
00030     0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0,  // 8
00031     0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1,  // 9
00032     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A
00033     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B
00034     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
00035     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D
00036     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
00037     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F
00038 };
00039 
00040 const bool mux_isdigit[256] =
00041 {
00042 //  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00043 //
00044     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 0
00045     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1
00046     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 2
00047     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,  // 3
00048     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 4
00049     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 5
00050     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 6
00051     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 7
00052 
00053     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 8
00054     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 9
00055     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // A
00056     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // B
00057     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // C
00058     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // D
00059     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // E
00060     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0   // F
00061 };
00062 
00063 const bool mux_ishex[256] =
00064 {
00065 //  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00066 //
00067     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 0
00068     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1
00069     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 2
00070     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,  // 3
00071     0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 4
00072     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 5
00073     0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 6
00074     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 7
00075 
00076     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 8
00077     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 9
00078     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // A
00079     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // B
00080     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // C
00081     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // D
00082     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // E
00083     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0   // F
00084 };
00085 
00086 const bool mux_isazAZ[256] =
00087 {
00088 //  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00089 //
00090     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 0
00091     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1
00092     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 2
00093     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 3
00094     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
00095     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  // 5
00096     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
00097     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  // 7
00098 
00099     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 8
00100     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 9
00101     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // A
00102     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // B
00103     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // C
00104     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // D
00105     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // E
00106     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0   // F
00107 };
00108 
00109 const bool mux_isalpha[256] =
00110 {
00111 //  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00112 //
00113     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 0
00114     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1
00115     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 2
00116     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 3
00117     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
00118     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  // 5
00119     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
00120     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  // 7
00121 
00122     0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0,  // 8
00123     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1,  // 9
00124     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,  // A
00125     0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,  // B
00126     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
00127     1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,  // D
00128     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
00129     1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0   // F
00130 };
00131 
00132 const bool mux_isalnum[256] =
00133 {
00134 //  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00135 //
00136     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 0
00137     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1
00138     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 2
00139     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,  // 3
00140     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
00141     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  // 5
00142     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
00143     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  // 7
00144 
00145     0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0,  // 8
00146     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1,  // 9
00147     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,  // A
00148     0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,  // B
00149     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
00150     1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,  // D
00151     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
00152     1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0   // F
00153 };
00154 
00155 const bool mux_isupper[256] =
00156 {
00157 //  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00158 //
00159     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 0
00160     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1
00161     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 2
00162     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 3
00163     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
00164     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  // 5
00165     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 6
00166     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 7
00167 
00168     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0,  // 8
00169     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,  // 9
00170     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // A
00171     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // B
00172     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
00173     1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0,  // D
00174     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // E
00175     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0   // F
00176 };
00177 
00178 const bool mux_islower[256] =
00179 {
00180 //  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00181 //
00182     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 0
00183     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1
00184     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 2
00185     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 3
00186     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 4
00187     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 5
00188     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
00189     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  // 7
00190 
00191     0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 8
00192     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0,  // 9
00193     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,  // A
00194     0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,  // B
00195     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // C
00196     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,  // D
00197     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
00198     1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0   // F
00199 };
00200 
00201 const bool mux_isspace[256] =
00202 {
00203 //  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00204 //
00205     0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0,  // 0
00206     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1
00207     1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 2
00208     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 3
00209     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 4
00210     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 5
00211     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 6
00212     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 7
00213 
00214     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 8
00215     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 9
00216     1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // A
00217     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // B
00218     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // C
00219     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // D
00220     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // E
00221     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0   // F
00222 };
00223 
00224 // The first character of an attribute name must be either alphabetic,
00225 // '_', '#', '.', or '~'. It's handled by the following table.
00226 //
00227 // Characters thereafter may be letters, numbers, and characters from
00228 // the set {'?!`/-_.@#$^&~=+<>()}. Lower-case letters are turned into
00229 // uppercase before being used, but lower-case letters are valid input.
00230 //
00231 bool mux_AttrNameInitialSet[256] =
00232 {
00233 //  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00234 //
00235     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 0
00236     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1
00237     0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,  // 2
00238     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 3
00239     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
00240     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,  // 5
00241     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
00242     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,  // 7
00243 
00244     0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0,  // 8
00245     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1,  // 9
00246     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,  // A
00247     0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,  // B
00248     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
00249     1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,  // D
00250     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
00251     1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0   // F
00252 };
00253 
00254 bool mux_AttrNameSet[256] =
00255 {
00256 //  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00257 //
00258     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 0
00259     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1
00260     0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1,  // 2
00261     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1,  // 3
00262     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
00263     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,  // 5
00264     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
00265     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,  // 7
00266 
00267     0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0,  // 8
00268     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1,  // 9
00269     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,  // A
00270     0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,  // B
00271     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
00272     1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,  // D
00273     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
00274     1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0   // F
00275 };
00276 
00277 // Valid characters for an object name are all printable
00278 // characters except those from the set {=&|}.
00279 //
00280 const bool mux_ObjectNameSet[256] =
00281 {
00282 //  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00283 //
00284     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 0
00285     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1
00286     1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 2
00287     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1,  // 3
00288     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
00289     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5
00290     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
00291     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0,  // 7
00292 
00293     0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0,  // 8
00294     0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1,  // 9
00295     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A
00296     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B
00297     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
00298     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D
00299     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
00300     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0   // F
00301 };
00302 
00303 // Valid characters for a player name are all alphanumeric plus
00304 // {`$_-.,'} plus SPACE depending on configuration.
00305 //
00306 bool mux_PlayerNameSet[256] =
00307 {
00308 //  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00309 //
00310     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 0
00311     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1
00312     1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0,  // 2
00313     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,  // 3
00314     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
00315     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,  // 5
00316     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
00317     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  // 7
00318 
00319     0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0,  // 8
00320     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1,  // 9
00321     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,  // A
00322     0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,  // B
00323     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
00324     1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,  // D
00325     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
00326     1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0   // F
00327 };
00328 
00329 // Characters which should be escaped for the secure()
00330 // function: '%$\[](){},;'.
00331 //
00332 const bool mux_issecure[256] =
00333 {
00334 //  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00335 //
00336     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 0
00337     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1
00338     0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0,  // 2
00339     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,  // 3
00340     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 4
00341     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0,  // 5
00342     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 6
00343     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0,  // 7
00344 
00345     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 8
00346     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 9
00347     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // A
00348     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // B
00349     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // C
00350     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // D
00351     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // E
00352     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0   // F
00353 };
00354 
00355 // Characters which should be escaped for the escape()
00356 // function: '%\[]{};,()^$'.
00357 //
00358 const bool mux_isescape[256] =
00359 {
00360 //  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00361 //
00362     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 0
00363     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1
00364     0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0,  // 2
00365     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,  // 3
00366     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 4
00367     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,  // 5
00368     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 6
00369     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0,  // 7
00370 
00371     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 8
00372     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 9
00373     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // A
00374     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // B
00375     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // C
00376     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // D
00377     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // E
00378     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0   // F
00379 };
00380 
00381 const bool ANSI_TokenTerminatorTable[256] =
00382 {
00383 //  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00384 //
00385     1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 0
00386     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1
00387     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 2
00388     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 3
00389     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
00390     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  // 5
00391     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
00392     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  // 7
00393 
00394     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 8
00395     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 9
00396     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // A
00397     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // B
00398     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // C
00399     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // D
00400     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // E
00401     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0   // F
00402 };
00403 
00404 const unsigned char mux_hex2dec[256] =
00405 {
00406 //  0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
00407 //
00408     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 0
00409     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 1
00410     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 2
00411     0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  0,  0,  0,  0,  0,  0,  // 3
00412     0, 10, 11, 12, 13, 14, 15,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 4
00413     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 5
00414     0, 10, 11, 12, 13, 14, 15,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 6
00415     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 7
00416 
00417     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 8
00418     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // A
00419     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // B
00420     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // C
00421     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // D
00422     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // E
00423     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0   // F
00424 };
00425 
00426 const unsigned char mux_toupper[256] =
00427 {
00428 //   0     1     2     3     4     5     6     7     8     9     A     B     C     D     E     F
00429 //
00430     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, // 0
00431     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, // 1
00432     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, // 2
00433     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, // 3
00434     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, // 4
00435     0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, // 5
00436     0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, // 6
00437     0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, // 7
00438 
00439     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, // 8
00440     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x8A, 0x9B, 0x8C, 0x9D, 0x8E, 0x9F, // 9
00441     0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, // A
00442     0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, // B
00443     0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, // C
00444     0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, // D
00445     0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, // E
00446     0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xF7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xFF  // F
00447 };
00448 
00449 const unsigned char mux_tolower[256] =
00450 {
00451 //   0     1     2     3     4     5     6     7     8     9     A     B     C     D     E     F
00452 //
00453     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, // 0
00454     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, // 1
00455     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, // 2
00456     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, // 3
00457     0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, // 4
00458     0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, // 5
00459     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, // 6
00460     0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, // 7
00461 
00462     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x9A, 0x8B, 0x9C, 0x8D, 0x9E, 0x8F, // 8
00463     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0xFF, // 9
00464     0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, // A
00465     0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, // B
00466     0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, // C
00467     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xD7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xDF, // D
00468     0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, // E
00469     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF  // F
00470 };
00471 
00472 const unsigned char mux_StripAccents[256] =
00473 {
00474 //   0     1     2     3     4     5     6     7     8     9     A     B     C     D     E     F
00475 //
00476     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, // 0
00477     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, // 1
00478     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, // 2
00479     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, // 3
00480     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, // 4
00481     0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, // 5
00482     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, // 6
00483     0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, // 7
00484 
00485     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, // 8
00486     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, // 9
00487     0xA0, 0x21, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0x22, 0xAC, 0xAD, 0xAE, 0xAF, // A
00488     0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0x22, 0xBC, 0xBD, 0xBE, 0x3F, // B
00489     0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, // C
00490     0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, 0x55, 0x55, 0x59, 0x50, 0x42, // D
00491     0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xE6, 0x63, 0x65, 0x65, 0x65, 0x65, 0x69, 0x69, 0x69, 0x69, // E
00492     0x6F, 0x6E, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0xF7, 0x6F, 0x75, 0x75, 0x75, 0x75, 0x79, 0x70, 0x79, // F
00493 };
00494 
00495 // ANSI_lex - This function parses a string and returns two token types.
00496 // The type identifies the token type of length nLengthToken0. nLengthToken1
00497 // may also be present and is a token of the -other- type.
00498 //
00499 int ANSI_lex(int nString, const char *pString, int *nLengthToken0, int *nLengthToken1)
00500 {
00501     *nLengthToken0 = 0;
00502     *nLengthToken1 = 0;
00503 
00504     const char *p = pString;
00505 
00506     for (;;)
00507     {
00508         // Look for an ESC_CHAR
00509         //
00510         p = strchr(p, ESC_CHAR);
00511         if (!p)
00512         {
00513             // This is the most common case by far.
00514             //
00515             *nLengthToken0 = nString;
00516             return TOKEN_TEXT_ANSI;
00517         }
00518 
00519         // We have an ESC_CHAR. Let's look at the next character.
00520         //
00521         if (p[1] != '[')
00522         {
00523             // Could be a '\0' or another non-'[' character.
00524             // Move the pointer to position ourselves over it.
00525             // And continue looking for an ESC_CHAR.
00526             //
00527             p = p + 1;
00528             continue;
00529         }
00530 
00531         // We found the beginning of an ANSI sequence.
00532         // Find the terminating character.
00533         //
00534         const char *q = p+2;
00535         while (ANSI_TokenTerminatorTable[(unsigned char)*q] == 0)
00536         {
00537             q++;
00538         }
00539         if (q[0] == '\0')
00540         {
00541             // There was no good terminator. Treat everything like text.
00542             // Also, we are at the end of the string, so just return.
00543             //
00544             *nLengthToken0 = q - pString;
00545             return TOKEN_TEXT_ANSI;
00546         }
00547         else
00548         {
00549             // We found an ANSI sequence.
00550             //
00551             if (p == pString)
00552             {
00553                 // The ANSI sequence started it.
00554                 //
00555                 *nLengthToken0 = q - pString + 1;
00556                 return TOKEN_ANSI;
00557             }
00558             else
00559             {
00560                 // We have TEXT followed by an ANSI sequence.
00561                 //
00562                 *nLengthToken0 = p - pString;
00563                 *nLengthToken1 = q - p + 1;
00564                 return TOKEN_TEXT_ANSI;
00565             }
00566         }
00567     }
00568 }
00569 
00570 char *strip_ansi(const char *szString, size_t *pnString)
00571 {
00572     static char Buffer[LBUF_SIZE];
00573     char *pBuffer = Buffer;
00574 
00575     const char *pString = szString;
00576     if (!pString)
00577     {
00578         if (pnString)
00579         {
00580             *pnString = 0;
00581         }
00582         *pBuffer = '\0';
00583         return Buffer;
00584     }
00585     size_t nString = strlen(szString);
00586 
00587     while (nString)
00588     {
00589         int nTokenLength0;
00590         int nTokenLength1;
00591         int iType = ANSI_lex(nString, pString, &nTokenLength0, &nTokenLength1);
00592 
00593         if (iType == TOKEN_TEXT_ANSI)
00594         {
00595             memcpy(pBuffer, pString, nTokenLength0);
00596             pBuffer += nTokenLength0;
00597 
00598             int nSkipLength = nTokenLength0 + nTokenLength1;
00599             nString -= nSkipLength;
00600             pString += nSkipLength;
00601         }
00602         else
00603         {
00604             // TOKEN_ANSI
00605             //
00606             nString -= nTokenLength0;
00607             pString += nTokenLength0;
00608         }
00609     }
00610     if (pnString)
00611     {
00612         *pnString = pBuffer - Buffer;
00613     }
00614     *pBuffer = '\0';
00615     return Buffer;
00616 }
00617 
00618 char *strip_accents(const char *szString, size_t *pnString)
00619 {
00620     static char Buffer[LBUF_SIZE];
00621     char *pBuffer = Buffer;
00622 
00623     const char *pString = szString;
00624     if (pString)
00625     {
00626         while (*pString)
00627         {
00628             *pBuffer = mux_StripAccents(*pString);
00629             pBuffer++;
00630             pString++;
00631         }
00632     }
00633     if (pnString)
00634     {
00635         *pnString = pBuffer - Buffer;
00636     }
00637     *pBuffer = '\0';
00638     return Buffer;
00639 }
00640 
00641 #define ANSI_COLOR_INDEX_BLACK     0
00642 #define ANSI_COLOR_INDEX_RED       1
00643 #define ANSI_COLOR_INDEX_GREEN     2
00644 #define ANSI_COLOR_INDEX_YELLOW    3
00645 #define ANSI_COLOR_INDEX_BLUE      4
00646 #define ANSI_COLOR_INDEX_MAGENTA   5
00647 #define ANSI_COLOR_INDEX_CYAN      6
00648 #define ANSI_COLOR_INDEX_WHITE     7
00649 #define ANSI_COLOR_INDEX_DEFAULT   8
00650 
00651 static const ANSI_ColorState acsRestingStates[3] =
00652 {
00653     {true,  false, false, false, false, ANSI_COLOR_INDEX_DEFAULT, ANSI_COLOR_INDEX_DEFAULT},
00654     {false, false, false, false, false, ANSI_COLOR_INDEX_WHITE,   ANSI_COLOR_INDEX_DEFAULT},
00655     {true,  false, false, false, false, ANSI_COLOR_INDEX_DEFAULT, ANSI_COLOR_INDEX_DEFAULT}
00656 };
00657 
00658 static void ANSI_Parse_m(ANSI_ColorState *pacsCurrent, int nANSI, const char *pANSI,
00659                   bool *pbSawNormal)
00660 {
00661     // If the last character isn't an 'm', then it's an ANSI sequence we
00662     // don't support, yet. TODO: There should be a ANSI_Parse() function
00663     // that calls into this one -only- if there's an 'm', but since 'm'
00664     // is the only command this game understands at the moment, it's easier
00665     // to put the test here.
00666     //
00667     if (pANSI[nANSI-1] != 'm')
00668     {
00669         return;
00670     }
00671 
00672     // Process entire string and update the current color state structure.
00673     //
00674     while (nANSI)
00675     {
00676         // Process the next attribute phrase (terminated by ';' or 'm'
00677         // typically).
00678         //
00679         const char *p = pANSI;
00680         while (mux_isdigit(*p))
00681         {
00682             p++;
00683         }
00684         size_t nLen = p - pANSI + 1;
00685         if (p[0] == 'm' || p[0] == ';')
00686         {
00687             // We have an attribute.
00688             //
00689             if (nLen == 2)
00690             {
00691                 int iCode = pANSI[0] - '0';
00692                 switch (iCode)
00693                 {
00694                 case 0:
00695                     // Normal.
00696                     //
00697                     *pacsCurrent = acsRestingStates[ANSI_ENDGOAL_NORMAL];
00698                     *pbSawNormal = true;
00699                     break;
00700 
00701                 case 1:
00702                     // High Intensity.
00703                     //
00704                     pacsCurrent->bHighlite = true;
00705                     pacsCurrent->bNormal = false;
00706                     break;
00707 
00708                 case 2:
00709                     // Low Intensity.
00710                     //
00711                     pacsCurrent->bHighlite = false;
00712                     pacsCurrent->bNormal = false;
00713                     break;
00714 
00715                 case 4:
00716                     // Underline.
00717                     //
00718                     pacsCurrent->bUnder = true;
00719                     pacsCurrent->bNormal = false;
00720                     break;
00721 
00722                 case 5:
00723                     // Blinking.
00724                     //
00725                     pacsCurrent->bBlink = true;
00726                     pacsCurrent->bNormal = false;
00727                     break;
00728 
00729                 case 7:
00730                     // Reverse Video
00731                     //
00732                     pacsCurrent->bInverse = true;
00733                     pacsCurrent->bNormal = false;
00734                     break;
00735                 }
00736             }
00737             else if (nLen == 3)
00738             {
00739                 int iCode0 = pANSI[0] - '0';
00740                 int iCode1 = pANSI[1] - '0';
00741                 if (iCode0 == 3)
00742                 {
00743                     // Foreground Color
00744                     //
00745                     if (iCode1 <= 7)
00746                     {
00747                         pacsCurrent->iForeground = iCode1;
00748                         pacsCurrent->bNormal = false;
00749                     }
00750                 }
00751                 else if (iCode0 == 4)
00752                 {
00753                     // Background Color
00754                     //
00755                     if (iCode1 <= 7)
00756                     {
00757                         pacsCurrent->iBackground = iCode1;
00758                         pacsCurrent->bNormal = false;
00759                     }
00760                 }
00761             }
00762         }
00763         pANSI += nLen;
00764         nANSI -= nLen;
00765     }
00766 }
00767 
00768 // The following is really 30 (E[0mE[1mE[4mE[5mE[7mE[33mE[43m) but we are
00769 // being conservative.
00770 //
00771 #define ANSI_MAXIMUM_BINARY_TRANSITION_LENGTH 60
00772 
00773 // Generate the minimal ANSI sequence that will transition from one color state
00774 // to another.
00775 //
00776 static char *ANSI_TransitionColorBinary
00777 (
00778     ANSI_ColorState *acsCurrent,
00779     const ANSI_ColorState *pcsNext,
00780     int *nTransition,
00781     int  iEndGoal
00782 )
00783 {
00784     static char Buffer[ANSI_MAXIMUM_BINARY_TRANSITION_LENGTH+1];
00785 
00786     if (memcmp(acsCurrent, pcsNext, sizeof(ANSI_ColorState)) == 0)
00787     {
00788         *nTransition = 0;
00789         Buffer[0] = '\0';
00790         return Buffer;
00791     }
00792     ANSI_ColorState tmp = *acsCurrent;
00793     char *p = Buffer;
00794 
00795     if (pcsNext->bNormal)
00796     {
00797         // With NOBLEED, we can't stay in the normal mode. We must eventually
00798         // be on a white foreground.
00799         //
00800         pcsNext = &acsRestingStates[iEndGoal];
00801     }
00802 
00803     // Do we need to go through the normal state?
00804     //
00805     if (  tmp.bHighlite && !pcsNext->bHighlite
00806        || tmp.bUnder    && !pcsNext->bUnder
00807        || tmp.bBlink    && !pcsNext->bBlink
00808        || tmp.bInverse  && !pcsNext->bInverse
00809        || (  tmp.iBackground != ANSI_COLOR_INDEX_DEFAULT
00810           && pcsNext->iBackground == ANSI_COLOR_INDEX_DEFAULT)
00811        || (  tmp.iForeground != ANSI_COLOR_INDEX_DEFAULT
00812           && pcsNext->iForeground == ANSI_COLOR_INDEX_DEFAULT))
00813     {
00814         memcpy(p, ANSI_NORMAL, sizeof(ANSI_NORMAL)-1);
00815         p += sizeof(ANSI_NORMAL)-1;
00816         tmp = acsRestingStates[ANSI_ENDGOAL_NORMAL];
00817     }
00818     if (tmp.bHighlite != pcsNext->bHighlite)
00819     {
00820         memcpy(p, ANSI_HILITE, sizeof(ANSI_HILITE)-1);
00821         p += sizeof(ANSI_HILITE)-1;
00822     }
00823     if (tmp.bUnder != pcsNext->bUnder)
00824     {
00825         memcpy(p, ANSI_UNDER, sizeof(ANSI_UNDER)-1);
00826         p += sizeof(ANSI_UNDER)-1;
00827     }
00828     if (tmp.bBlink != pcsNext->bBlink)
00829     {
00830         memcpy(p, ANSI_BLINK, sizeof(ANSI_BLINK)-1);
00831         p += sizeof(ANSI_BLINK)-1;
00832     }
00833     if (tmp.bInverse != pcsNext->bInverse)
00834     {
00835         memcpy(p, ANSI_INVERSE, sizeof(ANSI_INVERSE)-1);
00836         p += sizeof(ANSI_INVERSE)-1;
00837     }
00838     if (tmp.iForeground != pcsNext->iForeground)
00839     {
00840         memcpy(p, ANSI_FOREGROUND, sizeof(ANSI_FOREGROUND)-1);
00841         p += sizeof(ANSI_FOREGROUND)-1;
00842         *p++ = pcsNext->iForeground + '0';
00843         *p++ = ANSI_ATTR_CMD;
00844     }
00845     if (tmp.iBackground != pcsNext->iBackground)
00846     {
00847         memcpy(p, ANSI_BACKGROUND, sizeof(ANSI_BACKGROUND)-1);
00848         p += sizeof(ANSI_BACKGROUND)-1;
00849         *p++ = pcsNext->iBackground + '0';
00850         *p++ = ANSI_ATTR_CMD;
00851     }
00852     *p = '\0';
00853     *nTransition = p - Buffer;
00854     return Buffer;
00855 }
00856 
00857 // The following is really 21 (%xn%xh%xu%xi%xf%xR%xr) but we are being conservative
00858 //
00859 #define ANSI_MAXIMUM_ESCAPE_TRANSITION_LENGTH 42
00860 
00861 // Generate the minimal MU ANSI %-sequence that will transition from one color state
00862 // to another.
00863 //
00864 static char *ANSI_TransitionColorEscape
00865 (
00866     ANSI_ColorState *acsCurrent,
00867     ANSI_ColorState *acsNext,
00868     int *nTransition
00869 )
00870 {
00871     static char Buffer[ANSI_MAXIMUM_ESCAPE_TRANSITION_LENGTH+1];
00872     static const char cForegroundColors[9] = "xrgybmcw";
00873     static const char cBackgroundColors[9] = "XRGYBMCW";
00874 
00875     if (memcmp(acsCurrent, acsNext, sizeof(ANSI_ColorState)) == 0)
00876     {
00877         *nTransition = 0;
00878         Buffer[0] = '\0';
00879         return Buffer;
00880     }
00881     ANSI_ColorState tmp = *acsCurrent;
00882     int  i = 0;
00883 
00884     // Do we need to go through the normal state?
00885     //
00886     if (  tmp.bBlink    && !acsNext->bBlink
00887        || tmp.bHighlite && !acsNext->bHighlite
00888        || tmp.bInverse  && !acsNext->bInverse
00889        || (  tmp.iBackground != ANSI_COLOR_INDEX_DEFAULT
00890           && acsNext->iBackground == ANSI_COLOR_INDEX_DEFAULT)
00891        || (  tmp.iForeground != ANSI_COLOR_INDEX_DEFAULT
00892           && acsNext->iForeground == ANSI_COLOR_INDEX_DEFAULT))
00893     {
00894         Buffer[i  ] = '%';
00895         Buffer[i+1] = 'x';
00896         Buffer[i+2] = 'n';
00897         i = i + 3;
00898         tmp = acsRestingStates[ANSI_ENDGOAL_NORMAL];
00899     }
00900     if (tmp.bHighlite != acsNext->bHighlite)
00901     {
00902         Buffer[i  ] = '%';
00903         Buffer[i+1] = 'x';
00904         Buffer[i+2] = 'h';
00905         i = i + 3;
00906     }
00907     if (tmp.bUnder != acsNext->bUnder)
00908     {
00909         Buffer[i  ] = '%';
00910         Buffer[i+1] = 'x';
00911         Buffer[i+2] = 'u';
00912         i = i + 3;
00913     }
00914     if (tmp.bBlink != acsNext->bBlink)
00915     {
00916         Buffer[i  ] = '%';
00917         Buffer[i+1] = 'x';
00918         Buffer[i+2] = 'f';
00919         i = i + 3;
00920     }
00921     if (tmp.bInverse != acsNext->bInverse)
00922     {
00923         Buffer[i  ] = '%';
00924         Buffer[i+1] = 'x';
00925         Buffer[i+2] = 'i';
00926         i = i + 3;
00927     }
00928     if (tmp.iForeground != acsNext->iForeground)
00929     {
00930         Buffer[i  ] = '%';
00931         Buffer[i+1] = 'x';
00932         Buffer[i+2] = cForegroundColors[acsNext->iForeground];
00933         i = i + 3;
00934     }
00935     if (tmp.iBackground != acsNext->iBackground)
00936     {
00937         Buffer[i  ] = '%';
00938         Buffer[i+1] = 'x';
00939         Buffer[i+2] = cBackgroundColors[acsNext->iBackground];
00940         i = i + 3;
00941     }
00942     Buffer[i] = '\0';
00943     *nTransition = i;
00944     return Buffer;
00945 }
00946 
00947 void ANSI_String_In_Init
00948 (
00949     struct ANSI_In_Context *pacIn,
00950     const char *szString,
00951     int        iEndGoal
00952 )
00953 {
00954     pacIn->m_acs = acsRestingStates[iEndGoal];
00955     pacIn->m_p   = szString;
00956     pacIn->m_n   = strlen(szString);
00957     pacIn->m_bSawNormal = false;
00958 }
00959 
00960 void ANSI_String_Out_Init
00961 (
00962     struct ANSI_Out_Context *pacOut,
00963     char *pField,
00964     int   nField,
00965     int   vwMax,
00966     int   iEndGoal
00967 )
00968 {
00969     pacOut->m_acs      = acsRestingStates[ANSI_ENDGOAL_NORMAL];
00970     pacOut->m_bDone    = false;
00971     pacOut->m_iEndGoal = iEndGoal;
00972     pacOut->m_n        = 0;
00973     pacOut->m_nMax     = nField;
00974     pacOut->m_p        = pField;
00975     pacOut->m_vw       = 0;
00976     pacOut->m_vwMax    = vwMax;
00977 }
00978 
00979 void ANSI_String_Skip
00980 (
00981     struct ANSI_In_Context *pacIn,
00982     int   maxVisualWidth,
00983     int  *pnVisualWidth)
00984 {
00985     *pnVisualWidth = 0;
00986     while (pacIn->m_n)
00987     {
00988         int nTokenLength0;
00989         int nTokenLength1;
00990         int iType = ANSI_lex(pacIn->m_n, pacIn->m_p, &nTokenLength0, &nTokenLength1);
00991 
00992         if (iType == TOKEN_TEXT_ANSI)
00993         {
00994             // Process TEXT
00995             //
00996             int nTextToSkip = maxVisualWidth - *pnVisualWidth;
00997             if (nTokenLength0 > nTextToSkip)
00998             {
00999                 // We have reached the limits of the field
01000                 //
01001                 *pnVisualWidth += nTextToSkip;
01002                 pacIn->m_p     += nTextToSkip;
01003                 pacIn->m_n     -= nTextToSkip;
01004                 return;
01005             }
01006 
01007             pacIn->m_p     += nTokenLength0;
01008             pacIn->m_n     -= nTokenLength0;
01009             *pnVisualWidth += nTokenLength0;
01010 
01011             if (nTokenLength1)
01012             {
01013                 // Process ANSI
01014                 //
01015                 ANSI_Parse_m(&(pacIn->m_acs), nTokenLength1, pacIn->m_p, &(pacIn->m_bSawNormal));
01016                 pacIn->m_p     += nTokenLength1;
01017                 pacIn->m_n     -= nTokenLength1;
01018             }
01019         }
01020         else
01021         {
01022             // Process ANSI
01023             //
01024             ANSI_Parse_m(&(pacIn->m_acs), nTokenLength0, pacIn->m_p, &(pacIn->m_bSawNormal));
01025             pacIn->m_n     -= nTokenLength0;
01026             pacIn->m_p     += nTokenLength0;
01027         }
01028     }
01029 }
01030 
01031 // TODO: Rework comment block.
01032 //
01033 // ANSI_String_Copy -- Copy characters into a buffer starting at
01034 // pField0 with maximum size of nField. Truncate the string if it would
01035 // overflow the buffer -or- if it would have a visual with of greater
01036 // than maxVisualWidth. Returns the number of ANSI-encoded characters
01037 // copied to. Also, the visual width produced by this is returned in
01038 // *pnVisualWidth.
01039 //
01040 // There are three ANSI color states that we deal with in this routine:
01041 //
01042 // 1. acsPrevious is the color state at the current end of the field.
01043 //    It has already been encoded into the field.
01044 //
01045 // 2. acsCurrent is the color state that the current TEXT will be shown
01046 //    with. It hasn't been encoded into the field, yet, and if we don't
01047 //    have enough room for at least one character of TEXT, then it may
01048 //    never be encoded into the field.
01049 //
01050 // 3. acsFinal is the required color state at the end. This is usually
01051 //    the normal state or in the case of NOBLEED, it's a specific (and
01052 //    somewhate arbitrary) foreground/background combination.
01053 //
01054 void ANSI_String_Copy
01055 (
01056     struct ANSI_Out_Context *pacOut,
01057     struct ANSI_In_Context  *pacIn,
01058     int maxVisualWidth0
01059 )
01060 {
01061     // Check whether we have previous struck the session limits (given
01062     // by ANSI_String_Out_Init() for field size or visual width.
01063     //
01064     if (pacOut->m_bDone)
01065     {
01066         return;
01067     }
01068 
01069     // What is the working limit for visual width.
01070     //
01071     int vw = 0;
01072     int vwMax = pacOut->m_vwMax;
01073     if (maxVisualWidth0 < vwMax)
01074     {
01075         vwMax = maxVisualWidth0;
01076     }
01077 
01078     // What is the working limit for field size.
01079     //
01080     int nMax = pacOut->m_nMax;
01081 
01082     char *pField = pacOut->m_p;
01083     while (pacIn->m_n)
01084     {
01085         int nTokenLength0;
01086         int nTokenLength1;
01087         int iType = ANSI_lex(pacIn->m_n, pacIn->m_p, &nTokenLength0,
01088             &nTokenLength1);
01089 
01090         if (iType == TOKEN_TEXT_ANSI)
01091         {
01092             // We have a TEXT+[ANSI] phrase. The text length is given
01093             // by nTokenLength0, and the ANSI characters that follow
01094             // (if present) are of length nTokenLength1.
01095             //
01096             // Process TEXT part first.
01097             //
01098             // TODO: If there is a maximum size for the transitions,
01099             // and we have gobs of space, don't bother calculating
01100             // sizes so carefully. It might be faster
01101 
01102             // nFieldEffective is used to allocate and plan space for
01103             // the rest of the physical field (given by the current
01104             // nField length).
01105             //
01106             int nFieldEffective = nMax - 1; // Leave room for '\0'.
01107 
01108             int nTransitionFinal = 0;
01109             if (pacOut->m_iEndGoal <= ANSI_ENDGOAL_NOBLEED)
01110             {
01111                 // If we lay down -any- of the TEXT part, we need to make
01112                 // sure we always leave enough room to get back to the
01113                 // required final ANSI color state.
01114                 //
01115                 if (memcmp( &(pacIn->m_acs),
01116                             &acsRestingStates[pacOut->m_iEndGoal],
01117                             sizeof(ANSI_ColorState)) != 0)
01118                 {
01119                     // The color state of the TEXT isn't the final state,
01120                     // so how much room will the transition back to the
01121                     // final state take?
01122                     //
01123                     ANSI_TransitionColorBinary( &(pacIn->m_acs),
01124                                                 &acsRestingStates[pacOut->m_iEndGoal],
01125                                                 &nTransitionFinal,
01126                                                 pacOut->m_iEndGoal);
01127 
01128                     nFieldEffective -= nTransitionFinal;
01129                 }
01130             }
01131 
01132             // If we lay down -any- of the TEXT part, it needs to be
01133             // the right color.
01134             //
01135             int nTransition = 0;
01136             char *pTransition =
01137                 ANSI_TransitionColorBinary( &(pacOut->m_acs),
01138                                             &(pacIn->m_acs),
01139                                             &nTransition,
01140                                             pacOut->m_iEndGoal);
01141             nFieldEffective -= nTransition;
01142 
01143             // If we find that there is no room for any of the TEXT,
01144             // then we're done.
01145             //
01146             // TODO: The visual width test can be done further up to save time.
01147             //
01148             if (  nFieldEffective <= nTokenLength0
01149                || vw + nTokenLength0 > vwMax)
01150             {
01151                 // We have reached the limits of the field.
01152                 //
01153                 if (nFieldEffective > 0)
01154                 {
01155                     // There was enough physical room in the field, but
01156                     // we would have exceeded the maximum visual width
01157                     // if we used all the text.
01158                     //
01159                     if (nTransition)
01160                     {
01161                         // Encode the TEXT color.
01162                         //
01163                         memcpy(pField, pTransition, nTransition);
01164                         pField += nTransition;
01165                     }
01166 
01167                     // Place just enough of the TEXT in the field.
01168                     //
01169                     int nTextToAdd = vwMax - vw;
01170                     if (nTextToAdd < nFieldEffective)
01171                     {
01172                         nFieldEffective = nTextToAdd;
01173                     }
01174                     memcpy(pField, pacIn->m_p, nFieldEffective);
01175                     pField += nFieldEffective;
01176                     pacIn->m_p += nFieldEffective;
01177                     pacIn->m_n -= nFieldEffective;
01178                     vw += nFieldEffective;
01179                     pacOut->m_acs = pacIn->m_acs;
01180 
01181                     // Was this visual width limit related to the session or
01182                     // the call?
01183                     //
01184                     if (vwMax != maxVisualWidth0)
01185                     {
01186                         pacOut->m_bDone = true;
01187                     }
01188                 }
01189                 else
01190                 {
01191                     // Was size limit related to the session or the call?
01192                     //
01193                     pacOut->m_bDone = true;
01194                 }
01195                 pacOut->m_n += pField - pacOut->m_p;
01196                 pacOut->m_nMax -= pField - pacOut->m_p;
01197                 pacOut->m_p  = pField;
01198                 pacOut->m_vw += vw;
01199                 return;
01200             }
01201 
01202             if (nTransition)
01203             {
01204                 memcpy(pField, pTransition, nTransition);
01205                 pField += nTransition;
01206                 nMax   -= nTransition;
01207             }
01208             memcpy(pField, pacIn->m_p, nTokenLength0);
01209             pField  += nTokenLength0;
01210             nMax    -= nTokenLength0;
01211             pacIn->m_p += nTokenLength0;
01212             pacIn->m_n -= nTokenLength0;
01213             vw += nTokenLength0;
01214             pacOut->m_acs = pacIn->m_acs;
01215 
01216             if (nTokenLength1)
01217             {
01218                 // Process ANSI
01219                 //
01220                 ANSI_Parse_m(&(pacIn->