diff --git a/ChangeLog b/ChangeLog index aa2d50e2..6c0fe35c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2017-02-19 Markus Gans + * Refactoring FTerm::init_termcaps + 2017-02-18 Markus Gans * Avoid scroll bar overshooting * Refactoring FListView::onMouseMove diff --git a/examples/termcap.cpp b/examples/termcap.cpp index ea1c09e8..4f729329 100644 --- a/examples/termcap.cpp +++ b/examples/termcap.cpp @@ -31,7 +31,7 @@ static FVTerm* terminal; // Function prototype -void tcapBooleans (const std::string&, bool); +void tcapBoolean (const std::string&, bool); void tcapNumeric (const std::string&, int); void tcapString (const std::string&, const char[]); void debug (FApplication&); @@ -142,7 +142,7 @@ const int last_item = int ( sizeof(strings) / sizeof(strings[0]) ) - 1; //---------------------------------------------------------------------- // Functions //---------------------------------------------------------------------- -void tcapBooleans (const std::string& name, bool cap_bool) +void tcapBoolean (const std::string& name, bool cap_bool) { std::cout << "FTermcap::" << name << ": "; @@ -232,20 +232,20 @@ void debug (FApplication& TermApp) void booleans() { std::cout << "\r\n[Booleans]\r\n"; - tcapBooleans ( "background_color_erase" - , FTermcap::background_color_erase ); - tcapBooleans ( "automatic_left_margin" - , FTermcap::automatic_left_margin ); - tcapBooleans ( "automatic_right_margin" - , FTermcap::automatic_right_margin ); - tcapBooleans ( "eat_nl_glitch" - , FTermcap::eat_nl_glitch ); - tcapBooleans ( "ansi_default_color" - , FTermcap::ansi_default_color ); - tcapBooleans ( "osc_support" - , FTermcap::osc_support ); - tcapBooleans ( "no_utf8_acs_chars" - , FTermcap::no_utf8_acs_chars ); + tcapBoolean ( "background_color_erase" + , FTermcap::background_color_erase ); + tcapBoolean ( "automatic_left_margin" + , FTermcap::automatic_left_margin ); + tcapBoolean ( "automatic_right_margin" + , FTermcap::automatic_right_margin ); + tcapBoolean ( "eat_nl_glitch" + , FTermcap::eat_nl_glitch ); + tcapBoolean ( "ansi_default_color" + , FTermcap::ansi_default_color ); + tcapBoolean ( "osc_support" + , FTermcap::osc_support ); + tcapBoolean ( "no_utf8_acs_chars" + , FTermcap::no_utf8_acs_chars ); } //---------------------------------------------------------------------- diff --git a/include/final/fterm.h b/include/final/fterm.h index 08f235dc..5605ce0f 100644 --- a/include/final/fterm.h +++ b/include/final/fterm.h @@ -495,8 +495,10 @@ class FTerm static void init_cygwin_charmap(); static void init_teraterm_charmap(); static void init_termcaps(); + static void init_termcaps_error (int); + static void init_termcaps_variables(char*&); static void init_termcaps_booleans(); - static void init_termcaps_numeric(); + static void init_termcaps_numerics(); static void init_termcaps_strings (char*&); static void init_termcaps_quirks(); #if defined(__FreeBSD__) || defined(__DragonFly__) diff --git a/src/fterm.cpp b/src/fterm.cpp index e1664dc5..db715f60 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -3366,21 +3366,20 @@ void FTerm::init_teraterm_charmap() } //---------------------------------------------------------------------- +/* Terminal capability data base + * ----------------------------- + * Info under: man 5 terminfo + * + * Importent shell commands: + * captoinfo - convert all termcap descriptions into terminfo descriptions + * infocmp - print out terminfo description from the current terminal + */ void FTerm::init_termcaps() { - /* Terminal capability data base - * ----------------------------- - * Info under: man 5 terminfo - * - * Importent shell commands: - * captoinfo - convert all termcap descriptions into terminfo descriptions - * infocmp - print out terminfo description from the current terminal - */ - static const int - success = 1 - , no_entry = 0 - , db_not_found = -1 - , uninitialized = -2; + std::vector terminals; + std::vector::iterator iter; + static const int success = 1; + static const int uninitialized = -2; static char term_buffer[2048]; static char string_buf[2048]; char* buffer = string_buf; @@ -3389,43 +3388,46 @@ void FTerm::init_termcaps() // share the terminal capabilities FTermcap().setTermcapMap(tcap); - if ( termtype[0] ) - { - // open the termcap file + load entry for termtype - status = tgetent(term_buffer, termtype); - } + // open termcap file + terminals.push_back(termtype); // available terminal type - if ( status != success && color256 ) - { - // use "xterm-256color" as fallback if not found - std::strncpy (termtype, C_STR("xterm-256color"), 15); - status = tgetent(term_buffer, termtype); - } + if ( color256 ) // 1st fallback if not found + terminals.push_back("xterm-256color"); - if ( status != success ) + terminals.push_back("xterm"); // 2nd fallback if not found + terminals.push_back("ansi"); // 3rd fallback if not found + terminals.push_back("vt100"); // 4th fallback if not found + iter = terminals.begin(); + + while ( iter != terminals.end() ) { - // use "xterm" as fallback if not found - std::strncpy (termtype, C_STR("xterm"), 6); + // Copy c-string + terminating null-character ('\0') + std::strncpy (termtype, (*iter).c_str(), (*iter).length() + 1); + + // Open the termcap file + load entry for termtype status = tgetent(term_buffer, termtype); - if ( status != success ) - { - // use "ansi" as fallback if not found - std::strncpy (termtype, C_STR("ansi"), 5); - status = tgetent(term_buffer, termtype); - ansi_terminal = true; + if ( status == success || ! terminal_detection ) + break; - if ( status != success ) - { - // use "vt100" as fallback if not found - std::strncpy (termtype, C_STR("vt100"), 6); - status = tgetent(term_buffer, termtype); - ansi_terminal = false; - } - } + ++iter; } - if ( status == no_entry ) + if ( std::strncmp(termtype, "ansi", 4) == 0 ) + ansi_terminal = true; + + init_termcaps_error (status); + init_termcaps_variables (buffer); +} + +//---------------------------------------------------------------------- +void FTerm::init_termcaps_error (int status) +{ + static const int no_entry = 0; + static const int db_not_found = -1; + static const int uninitialized = -2; + + if ( status == no_entry || status == uninitialized ) { std::cerr << "Unknown terminal: " << termtype << "\n" << "Check the TERM environment variable\n" @@ -3438,12 +3440,16 @@ void FTerm::init_termcaps() std::cerr << "The termcap/terminfo database could not be found.\n"; std::abort(); } +} +//---------------------------------------------------------------------- +void FTerm::init_termcaps_variables (char*& buffer) +{ // Get termcap booleans init_termcaps_booleans(); - // Get termcap numeric - init_termcaps_numeric(); + // Get termcap numerics + init_termcaps_numerics(); // Get termcap strings init_termcaps_strings(buffer); @@ -3490,7 +3496,7 @@ void FTerm::init_termcaps_booleans() } //---------------------------------------------------------------------- -void FTerm::init_termcaps_numeric() +void FTerm::init_termcaps_numerics() { // Get termcap numeric