00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <basix/port.hpp>
00014 #include <basix/system.hpp>
00015
00017
00018 namespace mmx {
00019
00020
00021
00022
00023
00024 bool
00025 supports_color () {
00026 static bool terminal_supports_color=
00027 get_env ("TERM") == string ("xterm") ||
00028 get_env ("TERM") == string ("xterm-color") ||
00029 get_env ("TERM") == string ("xterm-256color");
00030 return terminal_supports_color && !texmacs_mode && color_mode;
00031 }
00032
00033
00034
00035
00036
00037 class formatting_port_rep: public port_rep {
00038 port p;
00039 string prefix;
00040 bool need_indent;
00041 string indenter;
00042
00043 public:
00044 syntactic expression () const {
00045 return syn ("formatting_port", flatten (p)); }
00046 bool is_output_port () {
00047 return mmx::is_output_port (p); }
00048 bool is_input_port () {
00049 return mmx::is_input_port (p); }
00050 bool error_flag () {
00051 return mmx::error_flag (p); }
00052 string error_message () {
00053 return mmx::error_message (p); }
00054 bool busy () {
00055 return mmx::busy (p); }
00056 nat can_write () {
00057 return mmx::can_write (p); }
00058 nat can_read () {
00059 return mmx::can_read (p); }
00060 void write (const char* s, nat n) {
00061 for (nat i=0; i<n; ) {
00062 nat start= i;
00063 while (i<n && s[i] != '\n') i++;
00064 if (i>start && need_indent) mmx::write (p, prefix);
00065 need_indent= (i<n);
00066 if (need_indent) i++;
00067 mmx::write (p, s+start, i-start);
00068 } }
00069 void read (char* s, nat n) {
00070 mmx::read (p, s, n); }
00071 void flush () {
00072 mmx::flush (p); }
00073 bool wait (int msecs) {
00074 return mmx::wait (p, msecs); }
00075 port component (const string& name) {
00076 if (name == "wrapped") return p;
00077 ERROR ("port not found"); }
00078
00079 void format (const print_format& fm) {
00080 switch (fm) {
00081 case blank:
00082 indenter= " ";
00083 break;
00084 case stroke:
00085 indenter= "| ";
00086 break;
00087 case indent:
00088 prefix << indenter;
00089 break;
00090 case unindent:
00091 inside (prefix) -> resize (max (N(prefix), N(indenter)) - N(indenter));
00092 break;
00093 case reset_indent:
00094 inside (prefix) -> resize (0);
00095 break;
00096 case cr:
00097 write ("\r", 1);
00098 break;
00099 case lf:
00100 write ("\n", 1);
00101 break;
00102 case hrule:
00103 write ("--------------------------------------------------------------------------------", 80);
00104 break;
00105 case flush_now:
00106 flush ();
00107 break;
00108
00109 case black_foreground:
00110 if (supports_color ()) write ("\x1b[30m", 5);
00111 break;
00112 case red_foreground:
00113 if (supports_color ()) write ("\x1b[31m", 5);
00114 break;
00115 case green_foreground:
00116 if (supports_color ()) write ("\x1b[32m", 5);
00117 break;
00118 case yellow_foreground:
00119 if (supports_color ()) write ("\x1b[33m", 5);
00120 break;
00121 case blue_foreground:
00122 if (supports_color ()) write ("\x1b[34m", 5);
00123 break;
00124 case magenta_foreground:
00125 if (supports_color ()) write ("\x1b[35m", 5);
00126 break;
00127 case cyan_foreground:
00128 if (supports_color ()) write ("\x1b[36m", 5);
00129 break;
00130 case white_foreground:
00131 if (supports_color ()) write ("\x1b[37m", 5);
00132 break;
00133
00134 case black_background:
00135 if (supports_color ()) write ("\x1b[40m", 5);
00136 break;
00137 case red_background:
00138 if (supports_color ()) write ("\x1b[41m", 5);
00139 break;
00140 case green_background:
00141 if (supports_color ()) write ("\x1b[42m", 5);
00142 break;
00143 case yellow_background:
00144 if (supports_color ()) write ("\x1b[43m", 5);
00145 break;
00146 case blue_background:
00147 if (supports_color ()) write ("\x1b[44m", 5);
00148 break;
00149 case magenta_background:
00150 if (supports_color ()) write ("\x1b[45m", 5);
00151 break;
00152 case cyan_background:
00153 if (supports_color ()) write ("\x1b[46m", 5);
00154 break;
00155 case white_background:
00156 if (supports_color ()) write ("\x1b[47m", 5);
00157 break;
00158
00159 case bold:
00160 if (supports_color ()) write ("\x1b[1m", 4);
00161 break;
00162 case underline:
00163 if (supports_color ()) write ("\x1b[4m", 4);
00164 break;
00165 case blink:
00166 if (supports_color ()) write ("\x1b[5m", 4);
00167 break;
00168
00169 case reset_attributes:
00170 if (supports_color ()) write ("\x1b[0m", 4);
00171 flush ();
00172 break;
00173 }
00174 }
00175
00176 public:
00177 inline formatting_port_rep (const port& p2):
00178 p (p2), prefix (""), need_indent (true), indenter (" ") {}
00179 };
00180
00181
00182
00183
00184
00185 port
00186 formatting_port (const port& p) {
00187 return (port_rep*) new formatting_port_rep (p);
00188 }
00189
00190 }