From bd2e1f99c1dcbed76d7223fb3ed739fd7e1abd87 Mon Sep 17 00:00:00 2001 From: Keith Winstein Date: Sat, 22 Jan 2011 16:10:23 -0500 Subject: [PATCH] Now can send debugging info (actions) to separate tty --- termemu.cpp | 36 ++++++++++++++++++++++++--------- terminal.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++------- terminal.hpp | 4 ++-- 3 files changed, 78 insertions(+), 19 deletions(-) diff --git a/termemu.cpp b/termemu.cpp index 4545507..306823a 100644 --- a/termemu.cpp +++ b/termemu.cpp @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include "terminal.hpp" @@ -22,14 +24,28 @@ const size_t buf_size = 1024; -void emulate_terminal( int fd ); +void emulate_terminal( int fd, int debug_fd ); int copy( int src, int dest ); -int termemu( int fd, Terminal::Emulator *terminal ); +int termemu( int fd, Terminal::Emulator *terminal, int debug_fd ); -int main( int argc __attribute__((unused)), - char *argv[] __attribute__((unused)), +int main( int argc, + char *argv[], char *envp[] ) { + int debug_fd; + if ( argc == 1 ) { + debug_fd = -1; + } else if ( argc == 2 ) { + debug_fd = open( argv[ 1 ], O_WRONLY ); + if ( debug_fd < 0 ) { + perror( "open" ); + exit( 1 ); + } + } else { + fprintf( stderr, "Usage: %s [debugfd]\n", argv[ 0 ] ); + exit( 1 ); + } + int master; struct termios saved_termios, raw_termios, child_termios; @@ -86,7 +102,7 @@ int main( int argc __attribute__((unused)), exit( 1 ); } - emulate_terminal( master ); + emulate_terminal( master, debug_fd ); if ( tcsetattr( STDIN_FILENO, TCSANOW, &saved_termios ) < 0 ) { perror( "tcsetattr" ); @@ -97,7 +113,7 @@ int main( int argc __attribute__((unused)), return 0; } -void emulate_terminal( int fd ) +void emulate_terminal( int fd, int debug_fd ) { Terminal::Emulator terminal( 80, 24 ); struct pollfd pollfds[ 2 ]; @@ -120,7 +136,7 @@ void emulate_terminal( int fd ) return; } } else if ( pollfds[ 1 ].revents & POLLIN ) { - if ( termemu( fd, &terminal ) < 0 ) { + if ( termemu( fd, &terminal, debug_fd ) < 0 ) { return; } } else if ( (pollfds[ 0 ].revents | pollfds[ 1 ].revents) @@ -159,7 +175,7 @@ int copy( int src, int dest ) return 0; } -int termemu( int fd, Terminal::Emulator *terminal ) +int termemu( int fd, Terminal::Emulator *terminal, int debug_fd ) { char buf[ buf_size ]; @@ -176,10 +192,10 @@ int termemu( int fd, Terminal::Emulator *terminal ) /* feed to terminal */ for ( int i = 0; i < bytes_read; i++ ) { - terminal_to_host.append( terminal->input( buf[ i ] ) ); + terminal_to_host.append( terminal->input( buf[ i ], debug_fd ) ); } - terminal->debug_printout( stdout ); + terminal->debug_printout( STDOUT_FILENO ); /* write writeback */ ssize_t total_bytes_written = 0; diff --git a/terminal.cpp b/terminal.cpp index 62723d2..55c2537 100644 --- a/terminal.cpp +++ b/terminal.cpp @@ -2,11 +2,14 @@ #include #include #include +#include #include "terminal.hpp" using namespace Terminal; +static void swrite( int fd, const char *str ); + Cell::Cell() : overlapping_cell( NULL ), contents(), @@ -49,7 +52,7 @@ Emulator::~Emulator() } -std::string Emulator::input( char c ) +std::string Emulator::input( char c, int actfd ) { terminal_to_host.clear(); @@ -60,6 +63,24 @@ std::string Emulator::input( char c ) i++ ) { Parser::Action *act = *i; + if ( (actfd > 0) && (typeid(*act) != typeid(Parser::Print)) ) { + char actsum[ 32 ]; + if ( act->char_present ) { + if ( isprint( act->ch ) ) { + snprintf( actsum, 32, "%s(0x%02x=%lc) ", + act->name().c_str(), act->ch, act->ch ); + } else { + snprintf( actsum, 32, "%s(0x%02x) ", + act->name().c_str(), act->ch ); + } + } else { + snprintf( actsum, 32, "[%s] ", + act->name().c_str() ); + } + + swrite( actfd, actsum ); + } + act->act_on_terminal( this ); delete act; @@ -168,26 +189,48 @@ void Emulator::print( Parser::Print *act ) } } -void Emulator::debug_printout( FILE *f ) +static void swrite( int fd, const char *str ) { - fprintf( f, "\033[H\033[2J" ); + ssize_t total_bytes_written = 0; + ssize_t bytes_to_write = strlen( str ); + while ( total_bytes_written < bytes_to_write ) { + ssize_t bytes_written = write( fd, str + total_bytes_written, + bytes_to_write - total_bytes_written ); + if ( bytes_written <= 0 ) { + perror( "write" ); + } else { + total_bytes_written += bytes_written; + } + } +} + +void Emulator::debug_printout( int fd ) +{ + std::string screen; + screen.append( "\033[H\033[2J" ); for ( int y = 0; y < height; y++ ) { for ( int x = 0; x < width; x++ ) { - fprintf( f, "\033[%d;%dH", y + 1, x + 1 ); + char curmove[ 32 ]; + snprintf( curmove, 32, "\033[%d;%dH", y + 1, x + 1 ); + screen.append( curmove ); Cell *cell = &rows[ y ].cells[ x ]; if ( cell->overlapping_cell ) continue; for ( std::vector::iterator i = cell->contents.begin(); i != cell->contents.end(); i++ ) { - fprintf( f, "%lc", *i ); + char utf8[ 8 ]; + snprintf( utf8, 8, "%lc", *i ); + screen.append( utf8 ); } } } - fprintf( f, "\033[%d;%dH", cursor_row + 1, cursor_col + 1 ); + char curmove[ 32 ]; + snprintf( curmove, 32, "\033[%d;%dH", cursor_row + 1, cursor_col + 1 ); + screen.append( curmove ); - fflush( NULL ); + swrite( fd, screen.c_str() ); } void Emulator::param( Parser::Param *act ) diff --git a/terminal.hpp b/terminal.hpp index c24a455..52b6d95 100644 --- a/terminal.hpp +++ b/terminal.hpp @@ -77,14 +77,14 @@ namespace Terminal { Emulator( size_t s_width, size_t s_height ); ~Emulator(); - std::string input( char c ); + std::string input( char c, int debug_fd ); void resize( size_t s_width, size_t s_height ); size_t get_width( void ) { return width; } size_t get_height( void ) { return height; } - void debug_printout( FILE *f ); + void debug_printout( int fd ); }; }