diff --git a/ChangeLog b/ChangeLog index 9747c9ac..14c0d05f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2018-09-14 Markus Gans + * Added unit test for FTermDetection with a terminal simulation + for common terminals + * Some minor terminal detection bug fixes + 2018-09-12 Markus Gans * Removes the deprecated keyword "register" from the source code diff --git a/include/final/ftermdetection.h b/include/final/ftermdetection.h index 040ed4ab..99b382dc 100644 --- a/include/final/ftermdetection.h +++ b/include/final/ftermdetection.h @@ -61,8 +61,8 @@ class FTermDetection typedef struct { // byte #0 - uInt8 xterm : 1; uInt8 ansi : 1; + uInt8 xterm : 1; uInt8 rxvt : 1; uInt8 urxvt : 1; uInt8 mlterm : 1; @@ -107,8 +107,8 @@ class FTermDetection #endif // Inquiries - static bool isXTerminal(); static bool isAnsiTerminal(); + static bool isXTerminal(); static bool isRxvtTerminal(); static bool isUrxvtTerminal(); static bool isMltermTerminal(); @@ -117,13 +117,13 @@ class FTermDetection static bool isGnomeTerminal(); static bool isKtermTerminal(); static bool isTeraTerm(); - static bool isSunTerminal(); static bool isCygwinTerminal(); static bool isMinttyTerm(); static bool isLinuxTerm(); static bool isFreeBSDTerm(); static bool isNetBSDTerm(); static bool isOpenBSDTerm(); + static bool isSunTerminal(); static bool isScreenTerm(); static bool isTmuxTerm(); static bool canDisplay256Colors(); @@ -131,8 +131,8 @@ class FTermDetection static bool hasSetCursorStyleSupport(); // Mutators - static void setXTerminal (bool); static void setAnsiTerminal (bool); + static void setXTerminal (bool); static void setRxvtTerminal (bool); static void setUrxvtTerminal (bool); static void setMltermTerminal (bool); @@ -141,13 +141,13 @@ class FTermDetection static void setGnomeTerminal (bool); static void setKtermTerminal (bool); static void setTeraTerm (bool); - static void setSunTerminal (bool); static void setCygwinTerminal (bool); static void setMinttyTerm (bool); static void setLinuxTerm (bool); static void setFreeBSDTerm (bool); static void setNetBSDTerm (bool); static void setOpenBSDTerm (bool); + static void setSunTerminal (bool); static void setScreenTerm (bool); static void setTmuxTerm (bool); static void setTerminalDetection (bool); @@ -190,6 +190,7 @@ class FTermDetection static char* secDA_Analysis_77 (char[]); static char* secDA_Analysis_82 (char[]); static char* secDA_Analysis_83 (char[]); + static char* secDA_Analysis_84 (char[]); static char* secDA_Analysis_85 (char[]); // Data Members @@ -330,10 +331,6 @@ inline bool FTermDetection::isKtermTerminal() inline bool FTermDetection::isTeraTerm() { return terminal_type.tera_term; } -//---------------------------------------------------------------------- -inline bool FTermDetection::isSunTerminal() -{ return terminal_type.sun_con; } - //---------------------------------------------------------------------- inline bool FTermDetection::isCygwinTerminal() { return terminal_type.cygwin; } @@ -358,6 +355,10 @@ inline bool FTermDetection::isNetBSDTerm() inline bool FTermDetection::isOpenBSDTerm() { return terminal_type.openbsd_con; } +//---------------------------------------------------------------------- +inline bool FTermDetection::isSunTerminal() +{ return terminal_type.sun_con; } + //---------------------------------------------------------------------- inline bool FTermDetection::isScreenTerm() { return terminal_type.screen; } @@ -410,10 +411,6 @@ inline void FTermDetection::setKtermTerminal (bool on) inline void FTermDetection::setTeraTerm (bool on) { terminal_type.tera_term = on; } -//---------------------------------------------------------------------- -inline void FTermDetection::setSunTerminal (bool on) -{ terminal_type.sun_con = on; } - //---------------------------------------------------------------------- inline void FTermDetection::setCygwinTerminal (bool on) { terminal_type.cygwin = on; } @@ -438,6 +435,10 @@ inline void FTermDetection::setNetBSDTerm (bool on) inline void FTermDetection::setOpenBSDTerm (bool on) { terminal_type.openbsd_con = on; } +//---------------------------------------------------------------------- +inline void FTermDetection::setSunTerminal (bool on) +{ terminal_type.sun_con = on; } + //---------------------------------------------------------------------- inline void FTermDetection::setScreenTerm (bool on) { terminal_type.screen = on; } diff --git a/include/final/ftermios.h b/include/final/ftermios.h index ad2e149c..bfc6e702 100644 --- a/include/final/ftermios.h +++ b/include/final/ftermios.h @@ -62,6 +62,7 @@ class FTermios static termios getTTY(); static int getStdIn(); static int getStdOut(); + static int getStdErr(); // Inquiries static bool isRaw(); @@ -85,6 +86,7 @@ class FTermios // Data Members static int stdin_no; static int stdout_no; + static int stderr_no; static bool raw_mode; static struct termios term_init; }; @@ -103,6 +105,10 @@ inline int FTermios::getStdIn() inline int FTermios::getStdOut() { return stdout_no; } +//---------------------------------------------------------------------- +inline int FTermios::getStdErr() +{ return stderr_no; } + //---------------------------------------------------------------------- inline bool FTermios::isRaw() { return raw_mode; } diff --git a/src/fterm.cpp b/src/fterm.cpp index 406d1e27..a45d4d75 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -580,10 +580,7 @@ void FTerm::resetColorMap() #if defined(__linux__) else - { - linux->resetColorMap(); - - } + linux->resetColorMap(); #endif if ( op ) @@ -1692,6 +1689,7 @@ void FTerm::redefineColorPalette() if ( isCygwinTerminal() || isKdeTerminal() || isTeraTerm() + || isMltermTerminal() || isNetBSDTerm() || isOpenBSDTerm() || isSunTerminal() @@ -1713,6 +1711,7 @@ void FTerm::restoreColorPalette() if ( isCygwinTerminal() || isKdeTerminal() || isTeraTerm() + || isMltermTerminal() || isNetBSDTerm() || isOpenBSDTerm() || isSunTerminal() diff --git a/src/ftermdetection.cpp b/src/ftermdetection.cpp index a403a0ea..bfa98af2 100644 --- a/src/ftermdetection.cpp +++ b/src/ftermdetection.cpp @@ -257,6 +257,20 @@ void FTermDetection::termtypeAnalysis() terminal_type.kterm = true; } + // mlterm + if ( std::strncmp(termtype, "mlterm", 6) == 0 ) + terminal_type.mlterm = true; + + // screen/tmux + if ( std::strncmp(termtype, "screen", 6) == 0 ) + { + terminal_type.screen = true; + char* tmux = std::getenv("TMUX"); + + if ( tmux && std::strlen(tmux) != 0 ) + terminal_type.tmux = true; + } + // Linux console if ( std::strncmp(termtype, C_STR("linux"), 5) == 0 || std::strncmp(termtype, C_STR("con"), 3) == 0 ) @@ -387,23 +401,13 @@ char* FTermDetection::termtype_256color_quirks() new_termtype = C_STR("xterm-256color"); if ( std::strncmp(termtype, "screen", 6) == 0 ) - { new_termtype = C_STR("screen-256color"); - terminal_type.screen = true; - char* tmux = std::getenv("TMUX"); - - if ( tmux && std::strlen(tmux) != 0 ) - terminal_type.tmux = true; - } if ( std::strncmp(termtype, "Eterm", 5) == 0 ) new_termtype = C_STR("Eterm-256color"); if ( std::strncmp(termtype, "mlterm", 6) == 0 ) - { new_termtype = C_STR("mlterm-256color"); - terminal_type.mlterm = true; - } if ( std::strncmp(termtype, "rxvt", 4) != 0 && color_env.string1 @@ -417,6 +421,9 @@ char* FTermDetection::termtype_256color_quirks() || (color_env.string6 && std::strlen(color_env.string6) > 0) ) terminal_type.kde_konsole = true; + if ( color_env.string3 && std::strlen(color_env.string3) > 0 ) + decscusr_support = true; + if ( (color_env.string1 && std::strncmp(color_env.string1, "gnome-terminal", 14) == 0) || color_env.string2 ) { @@ -445,8 +452,10 @@ char* FTermDetection::determineMaxColor (char current_termtype[]) && ! isNetBSDTerm() && ! getXTermColorName(0).isEmpty() ) { - if ( ! getXTermColorName(256).isEmpty() ) + if ( ! getXTermColorName(255).isEmpty() ) { + color256 = true; + if ( isPuttyTerminal() ) new_termtype = C_STR("putty-256color"); else @@ -728,6 +737,10 @@ char* FTermDetection::secDA_Analysis (char current_termtype[]) new_termtype = secDA_Analysis_83(current_termtype); break; + case 84: // tmux + new_termtype = secDA_Analysis_84(current_termtype); + break; + case 85: // rxvt-unicode new_termtype = secDA_Analysis_85(current_termtype); break; @@ -834,6 +847,7 @@ inline char* FTermDetection::secDA_Analysis_77 (char[]) char* new_termtype; terminal_type.mintty = true; + decscusr_support = true; new_termtype = C_STR("xterm-256color"); std::fflush(stdout); return new_termtype; @@ -866,6 +880,17 @@ inline char* FTermDetection::secDA_Analysis_83 (char current_termtype[]) return new_termtype; } +//---------------------------------------------------------------------- +inline char* FTermDetection::secDA_Analysis_84 (char current_termtype[]) +{ + // Terminal ID 84 - tmux + + char* new_termtype = current_termtype; + terminal_type.screen = true; + terminal_type.tmux = true; + return new_termtype; +} + //---------------------------------------------------------------------- inline char* FTermDetection::secDA_Analysis_85 (char current_termtype[]) { diff --git a/src/ftermios.cpp b/src/ftermios.cpp index 4bd1115e..49dc463b 100644 --- a/src/ftermios.cpp +++ b/src/ftermios.cpp @@ -26,6 +26,7 @@ // static class attributes int FTermios::stdin_no; int FTermios::stdout_no; +int FTermios::stderr_no; bool FTermios::raw_mode; termios FTermios::term_init; @@ -56,6 +57,7 @@ void FTermios::init() // Get file descriptor for standard input and standard output stdin_no = fileno(stdin); stdout_no = fileno(stdout); + stderr_no = fileno(stderr); } //---------------------------------------------------------------------- diff --git a/src/ftermxterminal.cpp b/src/ftermxterminal.cpp index ece11d9d..f43fe417 100644 --- a/src/ftermxterminal.cpp +++ b/src/ftermxterminal.cpp @@ -532,6 +532,7 @@ void FTermXTerminal::setXTerm8ColorDefaults() if ( xterm_default_colors && ! (term_detection->isMinttyTerm() + || term_detection->isMltermTerminal() || term_detection->isRxvtTerminal() || term_detection->isScreenTerm()) ) { @@ -559,6 +560,7 @@ void FTermXTerminal::setXTerm16ColorDefaults() if ( xterm_default_colors && ! (term_detection->isMinttyTerm() + || term_detection->isMltermTerminal() || term_detection->isRxvtTerminal() || term_detection->isScreenTerm()) ) { @@ -578,7 +580,8 @@ void FTermXTerminal::resetXTermColorMap() && term_detection->getGnomeTerminalID() < 3502 ) return; - if ( term_detection->isPuttyTerminal() ) + if ( term_detection->isPuttyTerminal() + || term_detection->isMltermTerminal() ) return; if ( term_detection->isXTerminal() @@ -601,7 +604,8 @@ void FTermXTerminal::resetXTermForeground() && term_detection->getGnomeTerminalID() < 3502 ) return; - if ( term_detection->isPuttyTerminal() ) + if ( term_detection->isPuttyTerminal() + || term_detection->isMltermTerminal() ) return; if ( term_detection->isXTerminal() @@ -624,7 +628,8 @@ void FTermXTerminal::resetXTermBackground() && term_detection->getGnomeTerminalID() < 3502 ) return; - if ( term_detection->isPuttyTerminal() ) + if ( term_detection->isPuttyTerminal() + || term_detection->isMltermTerminal() ) return; if ( term_detection->isXTerminal() diff --git a/src/test/Makefile.am b/src/test/Makefile.am index 3d4a2ba4..43d9cc3b 100644 --- a/src/test/Makefile.am +++ b/src/test/Makefile.am @@ -10,6 +10,7 @@ noinst_PROGRAMS = \ fobject_test \ fmouse_test \ fkeyboard_test \ + ftermdetection_test \ ftermcapquirks_test \ foptimove_test \ foptiattr_test \ @@ -20,6 +21,7 @@ noinst_PROGRAMS = \ fobject_test_SOURCES = fobject-test.cpp fmouse_test_SOURCES = fmouse-test.cpp fkeyboard_test_SOURCES = fkeyboard-test.cpp +ftermdetection_test_SOURCES = ftermdetection-test.cpp ftermcapquirks_test_SOURCES = ftermcapquirks-test.cpp foptimove_test_SOURCES = foptimove-test.cpp foptiattr_test_SOURCES = foptiattr-test.cpp @@ -30,6 +32,7 @@ frect_test_SOURCES = frect-test.cpp TESTS = fobject_test \ fmouse_test \ fkeyboard_test \ + ftermdetection_test \ ftermcapquirks_test \ foptimove_test \ foptiattr_test \ diff --git a/src/test/Makefile.in b/src/test/Makefile.in index 25698d2c..a2930fa9 100644 --- a/src/test/Makefile.in +++ b/src/test/Makefile.in @@ -85,6 +85,7 @@ host_triplet = @host@ @CPPUNIT_TEST_TRUE@noinst_PROGRAMS = fobject_test$(EXEEXT) \ @CPPUNIT_TEST_TRUE@ fmouse_test$(EXEEXT) \ @CPPUNIT_TEST_TRUE@ fkeyboard_test$(EXEEXT) \ +@CPPUNIT_TEST_TRUE@ ftermdetection_test$(EXEEXT) \ @CPPUNIT_TEST_TRUE@ ftermcapquirks_test$(EXEEXT) \ @CPPUNIT_TEST_TRUE@ foptimove_test$(EXEEXT) \ @CPPUNIT_TEST_TRUE@ foptiattr_test$(EXEEXT) \ @@ -92,6 +93,7 @@ host_triplet = @host@ @CPPUNIT_TEST_TRUE@ frect_test$(EXEEXT) @CPPUNIT_TEST_TRUE@TESTS = fobject_test$(EXEEXT) fmouse_test$(EXEEXT) \ @CPPUNIT_TEST_TRUE@ fkeyboard_test$(EXEEXT) \ +@CPPUNIT_TEST_TRUE@ ftermdetection_test$(EXEEXT) \ @CPPUNIT_TEST_TRUE@ ftermcapquirks_test$(EXEEXT) \ @CPPUNIT_TEST_TRUE@ foptimove_test$(EXEEXT) \ @CPPUNIT_TEST_TRUE@ foptiattr_test$(EXEEXT) \ @@ -116,6 +118,7 @@ CONFIG_CLEAN_VPATH_FILES = @CPPUNIT_TEST_TRUE@am__EXEEXT_1 = fobject_test$(EXEEXT) \ @CPPUNIT_TEST_TRUE@ fmouse_test$(EXEEXT) \ @CPPUNIT_TEST_TRUE@ fkeyboard_test$(EXEEXT) \ +@CPPUNIT_TEST_TRUE@ ftermdetection_test$(EXEEXT) \ @CPPUNIT_TEST_TRUE@ ftermcapquirks_test$(EXEEXT) \ @CPPUNIT_TEST_TRUE@ foptimove_test$(EXEEXT) \ @CPPUNIT_TEST_TRUE@ foptiattr_test$(EXEEXT) \ @@ -166,6 +169,11 @@ am__ftermcapquirks_test_SOURCES_DIST = ftermcapquirks-test.cpp @CPPUNIT_TEST_TRUE@ ftermcapquirks-test.$(OBJEXT) ftermcapquirks_test_OBJECTS = $(am_ftermcapquirks_test_OBJECTS) ftermcapquirks_test_LDADD = $(LDADD) +am__ftermdetection_test_SOURCES_DIST = ftermdetection-test.cpp +@CPPUNIT_TEST_TRUE@am_ftermdetection_test_OBJECTS = \ +@CPPUNIT_TEST_TRUE@ ftermdetection-test.$(OBJEXT) +ftermdetection_test_OBJECTS = $(am_ftermdetection_test_OBJECTS) +ftermdetection_test_LDADD = $(LDADD) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -204,7 +212,7 @@ SOURCES = $(fkeyboard_test_SOURCES) $(fmouse_test_SOURCES) \ $(fobject_test_SOURCES) $(foptiattr_test_SOURCES) \ $(foptimove_test_SOURCES) $(fpoint_test_SOURCES) \ $(frect_test_SOURCES) $(fstring_test_SOURCES) \ - $(ftermcapquirks_test_SOURCES) + $(ftermcapquirks_test_SOURCES) $(ftermdetection_test_SOURCES) DIST_SOURCES = $(am__fkeyboard_test_SOURCES_DIST) \ $(am__fmouse_test_SOURCES_DIST) \ $(am__fobject_test_SOURCES_DIST) \ @@ -212,7 +220,8 @@ DIST_SOURCES = $(am__fkeyboard_test_SOURCES_DIST) \ $(am__foptimove_test_SOURCES_DIST) \ $(am__fpoint_test_SOURCES_DIST) $(am__frect_test_SOURCES_DIST) \ $(am__fstring_test_SOURCES_DIST) \ - $(am__ftermcapquirks_test_SOURCES_DIST) + $(am__ftermcapquirks_test_SOURCES_DIST) \ + $(am__ftermdetection_test_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -573,6 +582,7 @@ top_srcdir = @top_srcdir@ @CPPUNIT_TEST_TRUE@fobject_test_SOURCES = fobject-test.cpp @CPPUNIT_TEST_TRUE@fmouse_test_SOURCES = fmouse-test.cpp @CPPUNIT_TEST_TRUE@fkeyboard_test_SOURCES = fkeyboard-test.cpp +@CPPUNIT_TEST_TRUE@ftermdetection_test_SOURCES = ftermdetection-test.cpp @CPPUNIT_TEST_TRUE@ftermcapquirks_test_SOURCES = ftermcapquirks-test.cpp @CPPUNIT_TEST_TRUE@foptimove_test_SOURCES = foptimove-test.cpp @CPPUNIT_TEST_TRUE@foptiattr_test_SOURCES = foptiattr-test.cpp @@ -668,6 +678,10 @@ ftermcapquirks_test$(EXEEXT): $(ftermcapquirks_test_OBJECTS) $(ftermcapquirks_te @rm -f ftermcapquirks_test$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(ftermcapquirks_test_OBJECTS) $(ftermcapquirks_test_LDADD) $(LIBS) +ftermdetection_test$(EXEEXT): $(ftermdetection_test_OBJECTS) $(ftermdetection_test_DEPENDENCIES) $(EXTRA_ftermdetection_test_DEPENDENCIES) + @rm -f ftermdetection_test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(ftermdetection_test_OBJECTS) $(ftermdetection_test_LDADD) $(LIBS) + mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -683,6 +697,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frect-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstring-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftermcapquirks-test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftermdetection-test.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -925,6 +940,13 @@ fkeyboard_test.log: fkeyboard_test$(EXEEXT) --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +ftermdetection_test.log: ftermdetection_test$(EXEEXT) + @p='ftermdetection_test$(EXEEXT)'; \ + b='ftermdetection_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) ftermcapquirks_test.log: ftermcapquirks_test$(EXEEXT) @p='ftermcapquirks_test$(EXEEXT)'; \ b='ftermcapquirks_test'; \ diff --git a/src/test/ftermcapquirks-test.cpp b/src/test/ftermcapquirks-test.cpp index 4b3b5463..479a86e6 100644 --- a/src/test/ftermcapquirks-test.cpp +++ b/src/test/ftermcapquirks-test.cpp @@ -229,7 +229,7 @@ void FTermcapQuirksTest::generalTest() { const int last_item = int(sizeof(test::tcap) / sizeof(test::tcap[0])) - 1; test::tcap_map* caps = new test::tcap_map[last_item]; - + for (int i = 0; i < last_item; i++) memcpy(&caps[i], &test::tcap[i], sizeof(test::tcap[0])); @@ -292,10 +292,10 @@ void FTermcapQuirksTest::xtermTest() { const int last_item = int(sizeof(test::tcap) / sizeof(test::tcap[0])) - 1; test::tcap_map* caps = new test::tcap_map[last_item]; - + for (int i = 0; i < last_item; i++) memcpy(&caps[i], &test::tcap[i], sizeof(test::tcap[0])); - + FTermcapQuirks quirks; FTermDetection detect; detect.setXTerminal (true); @@ -323,7 +323,7 @@ void FTermcapQuirksTest::freebsdTest() { const int last_item = int(sizeof(test::tcap) / sizeof(test::tcap[0])) - 1; test::tcap_map* caps = new test::tcap_map[last_item]; - + for (int i = 0; i < last_item; i++) memcpy(&caps[i], &test::tcap[i], sizeof(test::tcap[0])); @@ -362,7 +362,7 @@ void FTermcapQuirksTest::cygwinTest() { const int last_item = int(sizeof(test::tcap) / sizeof(test::tcap[0])) - 1; test::tcap_map* caps = new test::tcap_map[last_item]; - + for (int i = 0; i < last_item; i++) memcpy(&caps[i], &test::tcap[i], sizeof(test::tcap[0])); @@ -389,7 +389,7 @@ void FTermcapQuirksTest::linuxTest() { const int last_item = int(sizeof(test::tcap) / sizeof(test::tcap[0])) - 1; test::tcap_map* caps = new test::tcap_map[last_item]; - + for (int i = 0; i < last_item; i++) memcpy(&caps[i], &test::tcap[i], sizeof(test::tcap[0])); @@ -413,7 +413,7 @@ void FTermcapQuirksTest::linuxTest() // 16 colors FTermcap::max_color = 16; quirks.terminalFixup(); - + CPPUNIT_ASSERT_CSTRING ( caps[fc::t_set_a_foreground].string , C_STR(CSI "3%p1%{8}%m%d%?%p1%{7}%>%t;1%e;22%;m") ); CPPUNIT_ASSERT_CSTRING ( caps[fc::t_set_a_background].string @@ -463,7 +463,7 @@ void FTermcapQuirksTest::rxvtTest() { const int last_item = int(sizeof(test::tcap) / sizeof(test::tcap[0])) - 1; test::tcap_map* caps = new test::tcap_map[last_item]; - + for (int i = 0; i < last_item; i++) memcpy(&caps[i], &test::tcap[i], sizeof(test::tcap[0])); @@ -495,7 +495,7 @@ void FTermcapQuirksTest::rxvtTest() , C_STR(CSI "%?%p1%{8}%<%t%p1%{30}%+%e%p1%'R'%+%;%dm") ); CPPUNIT_ASSERT_CSTRING ( caps[fc::t_set_a_background].string , C_STR(CSI "%?%p1%{8}%<%t%p1%'('%+%e%p1%{92}%+%;%dm") ); - + detect.setUrxvtTerminal (false); detect.setRxvtTerminal (false); delete[] caps; @@ -506,7 +506,7 @@ void FTermcapQuirksTest::vteTest() { const int last_item = int(sizeof(test::tcap) / sizeof(test::tcap[0])) - 1; test::tcap_map* caps = new test::tcap_map[last_item]; - + for (int i = 0; i < last_item; i++) memcpy(&caps[i], &test::tcap[i], sizeof(test::tcap[0])); @@ -532,7 +532,7 @@ void FTermcapQuirksTest::puttyTest() { const int last_item = int(sizeof(test::tcap) / sizeof(test::tcap[0])) - 1; test::tcap_map* caps = new test::tcap_map[last_item]; - + for (int i = 0; i < last_item; i++) memcpy(&caps[i], &test::tcap[i], sizeof(test::tcap[0])); @@ -617,7 +617,7 @@ void FTermcapQuirksTest::teratermTest() { const int last_item = int(sizeof(test::tcap) / sizeof(test::tcap[0])) - 1; test::tcap_map* caps = new test::tcap_map[last_item]; - + for (int i = 0; i < last_item; i++) memcpy(&caps[i], &test::tcap[i], sizeof(test::tcap[0])); @@ -649,7 +649,7 @@ void FTermcapQuirksTest::sunTest() { const int last_item = int(sizeof(test::tcap) / sizeof(test::tcap[0])) - 1; test::tcap_map* caps = new test::tcap_map[last_item]; - + for (int i = 0; i < last_item; i++) memcpy(&caps[i], &test::tcap[i], sizeof(test::tcap[0])); @@ -673,7 +673,7 @@ void FTermcapQuirksTest::screenTest() { const int last_item = int(sizeof(test::tcap) / sizeof(test::tcap[0])) - 1; test::tcap_map* caps = new test::tcap_map[last_item]; - + for (int i = 0; i < last_item; i++) memcpy(&caps[i], &test::tcap[i], sizeof(test::tcap[0])); diff --git a/src/test/ftermdetection-test.cpp b/src/test/ftermdetection-test.cpp new file mode 100644 index 00000000..fdef2343 --- /dev/null +++ b/src/test/ftermdetection-test.cpp @@ -0,0 +1,2320 @@ +/*********************************************************************** +* ftermdetection-test.cpp - FTermDetection unit tests * +* * +* This file is part of the Final Cut widget toolkit * +* * +* Copyright 2018 Markus Gans * +* * +* The Final Cut is free software; you can redistribute it and/or * +* modify it under the terms of the GNU Lesser General Public License * +* as published by the Free Software Foundation; either version 3 of * +* the License, or (at your option) any later version. * +* * +* The Final Cut is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU Lesser General Public License for more details. * +* * +* You should have received a copy of the GNU Lesser General Public * +* License along with this program. If not, see * +* . * +***********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define CPPUNIT_ASSERT_CSTRING(expected, actual) \ + check_c_string (expected, actual, CPPUNIT_SOURCELINE()) + +static char* colorname[] = +{ + C_STR("0000/0000/0000"), // 0 + C_STR("bbbb/0000/0000"), // 1 + C_STR("0000/bbbb/0000"), // 2 + C_STR("bbbb/bbbb/0000"), // 3 + C_STR("0000/0000/bbbb"), // 4 + C_STR("bbbb/0000/bbbb"), // 5 + C_STR("0000/bbbb/bbbb"), // 6 + C_STR("bbbb/bbbb/bbbb"), // 7 + C_STR("5555/5555/5555"), // 8 + C_STR("ffff/5555/5555"), // 9 + C_STR("5555/ffff/5555"), // 10 + C_STR("ffff/ffff/5555"), // 11 + C_STR("5555/5555/ffff"), // 12 + C_STR("ffff/5555/ffff"), // 13 + C_STR("5555/ffff/ffff"), // 14 + C_STR("ffff/ffff/ffff"), // 15 + C_STR("0000/0000/0000"), // 16 + C_STR("0000/0000/5f5f"), // 17 + C_STR("0000/0000/8787"), // 18 + C_STR("0000/0000/afaf"), // 19 + C_STR("0000/0000/d7d7"), // 20 + C_STR("0000/0000/ffff"), // 21 + C_STR("0000/5f5f/0000"), // 22 + C_STR("0000/5f5f/5f5f"), // 23 + C_STR("0000/5f5f/8787"), // 24 + C_STR("0000/5f5f/afaf"), // 25 + C_STR("0000/5f5f/d7d7"), // 26 + C_STR("0000/5f5f/ffff"), // 27 + C_STR("0000/8787/0000"), // 28 + C_STR("0000/8787/5f5f"), // 29 + C_STR("0000/8787/8787"), // 30 + C_STR("0000/8787/afaf"), // 31 + C_STR("0000/8787/d7d7"), // 32 + C_STR("0000/8787/ffff"), // 33 + C_STR("0000/afaf/0000"), // 34 + C_STR("0000/afaf/5f5f"), // 35 + C_STR("0000/afaf/8787"), // 36 + C_STR("0000/afaf/afaf"), // 37 + C_STR("0000/afaf/d7d7"), // 38 + C_STR("0000/afaf/ffff"), // 39 + C_STR("0000/d7d7/0000"), // 40 + C_STR("0000/d7d7/5f5f"), // 41 + C_STR("0000/d7d7/8787"), // 42 + C_STR("0000/d7d7/afaf"), // 43 + C_STR("0000/d7d7/d7d7"), // 44 + C_STR("0000/d7d7/ffff"), // 45 + C_STR("0000/ffff/0000"), // 46 + C_STR("0000/ffff/5f5f"), // 47 + C_STR("0000/ffff/8787"), // 48 + C_STR("0000/ffff/afaf"), // 49 + C_STR("0000/ffff/d7d7"), // 50 + C_STR("0000/ffff/ffff"), // 51 + C_STR("5f5f/0000/0000"), // 52 + C_STR("5f5f/0000/5f5f"), // 53 + C_STR("5f5f/0000/8787"), // 54 + C_STR("5f5f/0000/afaf"), // 55 + C_STR("5f5f/0000/d7d7"), // 56 + C_STR("5f5f/0000/ffff"), // 57 + C_STR("5f5f/5f5f/0000"), // 58 + C_STR("5f5f/5f5f/5f5f"), // 59 + C_STR("5f5f/5f5f/8787"), // 60 + C_STR("5f5f/5f5f/afaf"), // 61 + C_STR("5f5f/5f5f/d7d7"), // 62 + C_STR("5f5f/5f5f/ffff"), // 63 + C_STR("5f5f/8787/0000"), // 64 + C_STR("5f5f/8787/5f5f"), // 65 + C_STR("5f5f/8787/8787"), // 66 + C_STR("5f5f/8787/afaf"), // 67 + C_STR("5f5f/8787/d7d7"), // 68 + C_STR("5f5f/8787/ffff"), // 69 + C_STR("5f5f/afaf/0000"), // 70 + C_STR("5f5f/afaf/5f5f"), // 71 + C_STR("5f5f/afaf/8787"), // 72 + C_STR("5f5f/afaf/afaf"), // 73 + C_STR("5f5f/afaf/d7d7"), // 74 + C_STR("5f5f/afaf/ffff"), // 75 + C_STR("5f5f/d7d7/0000"), // 76 + C_STR("5f5f/d7d7/5f5f"), // 77 + C_STR("5f5f/d7d7/8787"), // 78 + C_STR("5f5f/d7d7/afaf"), // 79 + C_STR("5f5f/d7d7/d7d7"), // 80 + C_STR("5f5f/d7d7/ffff"), // 81 + C_STR("5f5f/ffff/0000"), // 82 + C_STR("5f5f/ffff/5f5f"), // 83 + C_STR("5f5f/ffff/8787"), // 84 + C_STR("5f5f/ffff/afaf"), // 85 + C_STR("5f5f/ffff/d7d7"), // 86 + C_STR("5f5f/ffff/ffff"), // 87 + C_STR("8787/0000/0000"), // 88 + C_STR("8787/0000/5f5f"), // 89 + C_STR("8787/0000/8787"), // 90 + C_STR("8787/0000/afaf"), // 91 + C_STR("8787/0000/d7d7"), // 92 + C_STR("8787/0000/ffff"), // 93 + C_STR("8787/5f5f/0000"), // 94 + C_STR("8787/5f5f/5f5f"), // 95 + C_STR("8787/5f5f/8787"), // 96 + C_STR("8787/5f5f/afaf"), // 97 + C_STR("8787/5f5f/d7d7"), // 98 + C_STR("8787/5f5f/ffff"), // 99 + C_STR("8787/8787/0000"), // 100 + C_STR("8787/8787/5f5f"), // 101 + C_STR("8787/8787/8787"), // 102 + C_STR("8787/8787/afaf"), // 103 + C_STR("8787/8787/d7d7"), // 104 + C_STR("8787/8787/ffff"), // 105 + C_STR("8787/afaf/0000"), // 106 + C_STR("8787/afaf/5f5f"), // 107 + C_STR("8787/afaf/8787"), // 108 + C_STR("8787/afaf/afaf"), // 109 + C_STR("8787/afaf/d7d7"), // 110 + C_STR("8787/afaf/ffff"), // 111 + C_STR("8787/d7d7/0000"), // 112 + C_STR("8787/d7d7/5f5f"), // 113 + C_STR("8787/d7d7/8787"), // 114 + C_STR("8787/d7d7/afaf"), // 115 + C_STR("8787/d7d7/d7d7"), // 116 + C_STR("8787/d7d7/ffff"), // 117 + C_STR("8787/ffff/0000"), // 118 + C_STR("8787/ffff/5f5f"), // 119 + C_STR("8787/ffff/8787"), // 120 + C_STR("8787/ffff/afaf"), // 121 + C_STR("8787/ffff/d7d7"), // 122 + C_STR("8787/ffff/ffff"), // 123 + C_STR("afaf/0000/0000"), // 124 + C_STR("afaf/0000/5f5f"), // 125 + C_STR("afaf/0000/8787"), // 126 + C_STR("afaf/0000/afaf"), // 127 + C_STR("afaf/0000/d7d7"), // 128 + C_STR("afaf/0000/ffff"), // 129 + C_STR("afaf/5f5f/0000"), // 130 + C_STR("afaf/5f5f/5f5f"), // 131 + C_STR("afaf/5f5f/8787"), // 132 + C_STR("afaf/5f5f/afaf"), // 133 + C_STR("afaf/5f5f/d7d7"), // 134 + C_STR("afaf/5f5f/ffff"), // 135 + C_STR("afaf/8787/0000"), // 136 + C_STR("afaf/8787/5f5f"), // 137 + C_STR("afaf/8787/8787"), // 138 + C_STR("afaf/8787/afaf"), // 139 + C_STR("afaf/8787/d7d7"), // 140 + C_STR("afaf/8787/ffff"), // 141 + C_STR("afaf/afaf/0000"), // 142 + C_STR("afaf/afaf/5f5f"), // 143 + C_STR("afaf/afaf/8787"), // 144 + C_STR("afaf/afaf/afaf"), // 145 + C_STR("afaf/afaf/d7d7"), // 146 + C_STR("afaf/afaf/ffff"), // 147 + C_STR("afaf/d7d7/0000"), // 148 + C_STR("afaf/d7d7/5f5f"), // 149 + C_STR("afaf/d7d7/8787"), // 150 + C_STR("afaf/d7d7/afaf"), // 151 + C_STR("afaf/d7d7/d7d7"), // 152 + C_STR("afaf/d7d7/ffff"), // 153 + C_STR("afaf/ffff/0000"), // 154 + C_STR("afaf/ffff/5f5f"), // 155 + C_STR("afaf/ffff/8787"), // 156 + C_STR("afaf/ffff/afaf"), // 157 + C_STR("afaf/ffff/d7d7"), // 158 + C_STR("afaf/ffff/ffff"), // 159 + C_STR("d7d7/0000/0000"), // 160 + C_STR("d7d7/0000/5f5f"), // 161 + C_STR("d7d7/0000/8787"), // 162 + C_STR("d7d7/0000/afaf"), // 163 + C_STR("d7d7/0000/d7d7"), // 164 + C_STR("d7d7/0000/ffff"), // 165 + C_STR("d7d7/5f5f/0000"), // 166 + C_STR("d7d7/5f5f/5f5f"), // 167 + C_STR("d7d7/5f5f/8787"), // 168 + C_STR("d7d7/5f5f/afaf"), // 169 + C_STR("d7d7/5f5f/d7d7"), // 170 + C_STR("d7d7/5f5f/ffff"), // 171 + C_STR("d7d7/8787/0000"), // 172 + C_STR("d7d7/8787/5f5f"), // 173 + C_STR("d7d7/8787/8787"), // 174 + C_STR("d7d7/8787/afaf"), // 175 + C_STR("d7d7/8787/d7d7"), // 176 + C_STR("d7d7/8787/ffff"), // 177 + C_STR("d7d7/afaf/0000"), // 178 + C_STR("d7d7/afaf/5f5f"), // 179 + C_STR("d7d7/afaf/8787"), // 180 + C_STR("d7d7/afaf/afaf"), // 181 + C_STR("d7d7/afaf/d7d7"), // 182 + C_STR("d7d7/afaf/ffff"), // 183 + C_STR("d7d7/d7d7/0000"), // 184 + C_STR("d7d7/d7d7/5f5f"), // 185 + C_STR("d7d7/d7d7/8787"), // 186 + C_STR("d7d7/d7d7/afaf"), // 187 + C_STR("d7d7/d7d7/d7d7"), // 188 + C_STR("d7d7/d7d7/ffff"), // 189 + C_STR("d7d7/ffff/0000"), // 190 + C_STR("d7d7/ffff/5f5f"), // 191 + C_STR("d7d7/ffff/8787"), // 192 + C_STR("d7d7/ffff/afaf"), // 193 + C_STR("d7d7/ffff/d7d7"), // 194 + C_STR("d7d7/ffff/ffff"), // 195 + C_STR("ffff/0000/0000"), // 196 + C_STR("ffff/0000/5f5f"), // 197 + C_STR("ffff/0000/8787"), // 198 + C_STR("ffff/0000/afaf"), // 199 + C_STR("ffff/0000/d7d7"), // 200 + C_STR("ffff/0000/ffff"), // 201 + C_STR("ffff/5f5f/0000"), // 202 + C_STR("ffff/5f5f/5f5f"), // 203 + C_STR("ffff/5f5f/8787"), // 204 + C_STR("ffff/5f5f/afaf"), // 205 + C_STR("ffff/5f5f/d7d7"), // 206 + C_STR("ffff/5f5f/ffff"), // 207 + C_STR("ffff/8787/0000"), // 208 + C_STR("ffff/8787/5f5f"), // 209 + C_STR("ffff/8787/8787"), // 210 + C_STR("ffff/8787/afaf"), // 211 + C_STR("ffff/8787/d7d7"), // 212 + C_STR("ffff/8787/ffff"), // 213 + C_STR("ffff/afaf/0000"), // 214 + C_STR("ffff/afaf/5f5f"), // 215 + C_STR("ffff/afaf/8787"), // 216 + C_STR("ffff/afaf/afaf"), // 217 + C_STR("ffff/afaf/d7d7"), // 218 + C_STR("ffff/afaf/ffff"), // 219 + C_STR("ffff/d7d7/0000"), // 220 + C_STR("ffff/d7d7/5f5f"), // 221 + C_STR("ffff/d7d7/8787"), // 222 + C_STR("ffff/d7d7/afaf"), // 223 + C_STR("ffff/d7d7/d7d7"), // 224 + C_STR("ffff/d7d7/ffff"), // 225 + C_STR("ffff/ffff/0000"), // 226 + C_STR("ffff/ffff/5f5f"), // 227 + C_STR("ffff/ffff/8787"), // 228 + C_STR("ffff/ffff/afaf"), // 229 + C_STR("ffff/ffff/d7d7"), // 230 + C_STR("ffff/ffff/ffff"), // 231 + C_STR("0808/0808/0808"), // 232 + C_STR("1212/1212/1212"), // 233 + C_STR("1c1c/1c1c/1c1c"), // 234 + C_STR("2626/2626/2626"), // 235 + C_STR("3030/3030/3030"), // 236 + C_STR("3a3a/3a3a/3a3a"), // 237 + C_STR("4444/4444/4444"), // 238 + C_STR("4e4e/4e4e/4e4e"), // 239 + C_STR("5858/5858/5858"), // 240 + C_STR("6262/6262/6262"), // 241 + C_STR("6c6c/6c6c/6c6c"), // 242 + C_STR("7676/7676/7676"), // 243 + C_STR("8080/8080/8080"), // 244 + C_STR("8a8a/8a8a/8a8a"), // 245 + C_STR("9494/9494/9494"), // 246 + C_STR("9e9e/9e9e/9e9e"), // 247 + C_STR("a8a8/a8a8/a8a8"), // 248 + C_STR("b2b2/b2b2/b2b2"), // 249 + C_STR("bcbc/bcbc/bcbc"), // 250 + C_STR("c6c6/c6c6/c6c6"), // 251 + C_STR("d0d0/d0d0/d0d0"), // 252 + C_STR("dada/dada/dada"), // 253 + C_STR("e4e4/e4e4/e4e4"), // 254 + C_STR("eeee/eeee/eeee"), // 255 + 0 +}; + +//---------------------------------------------------------------------- +void check_c_string ( const char* s1 + , const char* s2 + , CppUnit::SourceLine sourceLine ) +{ + if ( s1 == 0 && s2 == 0 ) // Strings are equal + return; + + if ( s1 && s2 && std::strcmp (s1, s2) == 0 ) // Strings are equal + return; + + ::CppUnit::Asserter::fail ("Strings are not equal", sourceLine); +} + + +//---------------------------------------------------------------------- +// class FTermDetectionTest +//---------------------------------------------------------------------- + +#pragma pack(push) +#pragma pack(1) + +class FTermDetectionTest : public CPPUNIT_NS::TestFixture +{ + public: + // Enumeration + enum console + { + ansi, + xterm, + rxvt, + urxvt, + mlterm, + putty, + kde_konsole, + gnome_terminal, + kterm, + tera_term, + cygwin, + mintty, + linux_con, + freebsd_con, + netbsd_con, + openbsd_con, + sun_con, + screen, + tmux + }; + + FTermDetectionTest(); + ~FTermDetectionTest(); + + protected: + void classNameTest(); + void ansiTest(); + void xtermTest(); + void rxvtTest(); + void urxvtTest(); + void mltermTest(); + void puttyTest(); + void kdeKonsoleTest(); + void gnomeTerminalTest(); + void ktermTest(); + void teraTermTest(); + void cygwinTest(); + void minttyTest(); + void linuxTest(); + void freebsdTest(); + void netbsdTest(); + void openbsdTest(); + void sunTest(); + void screenTest(); + void tmuxTest(); + + private: + std::string printSequence (const std::string&); + char* getAnswerback (console); + char* getDSR (console); + char* getDECID (console); + char* getDA (console); + char* getDA1 (console); + char* getSEC_DA (console); + void debugOutput(); + bool openMasterPTY(); + bool openSlavePTY(); + void closeMasterPTY(); + void closeSlavePTY(); + pid_t forkProcess(); + bool isChildProcess (pid_t); + void terminalSimulation (console); + void parseTerminalBuffer (int, console); + + // Adds code needed to register the test suite + CPPUNIT_TEST_SUITE (FTermDetectionTest); + + // Add a methods to the test suite + CPPUNIT_TEST (classNameTest); + CPPUNIT_TEST (ansiTest); + CPPUNIT_TEST (xtermTest); + CPPUNIT_TEST (rxvtTest); + CPPUNIT_TEST (urxvtTest); + CPPUNIT_TEST (mltermTest); + CPPUNIT_TEST (puttyTest); + CPPUNIT_TEST (kdeKonsoleTest); + CPPUNIT_TEST (gnomeTerminalTest); + CPPUNIT_TEST (ktermTest); + CPPUNIT_TEST (teraTermTest); + CPPUNIT_TEST (cygwinTest); + CPPUNIT_TEST (minttyTest); + CPPUNIT_TEST (linuxTest); + CPPUNIT_TEST (freebsdTest); + CPPUNIT_TEST (netbsdTest); + CPPUNIT_TEST (openbsdTest); + CPPUNIT_TEST (sunTest); + CPPUNIT_TEST (screenTest); + CPPUNIT_TEST (tmuxTest); + + // End of test suite definition + CPPUNIT_TEST_SUITE_END(); + + // Data Members + int fd_stdin; + int fd_stdout; + int fd_stderr; + int fd_master; + int fd_slave; + bool debug; + char buffer[2048]; + static bool* shared_state; + +}; +#pragma pack(pop) + +// static class attributes +bool* FTermDetectionTest::shared_state = 0; + +//---------------------------------------------------------------------- +FTermDetectionTest::FTermDetectionTest() + : fd_stdin(fileno(stdin)) + , fd_stdout(fileno(stdout)) + , fd_stderr(fileno(stderr)) + , fd_master(-1) + , fd_slave(-1) + , debug(false) +{ + // Map shared memory + void* ptr = mmap ( NULL + , sizeof(*shared_state) + , PROT_READ | PROT_WRITE + , MAP_SHARED | MAP_ANONYMOUS, -1 + , 0 ); + shared_state = static_cast(ptr); + *shared_state = false; +} + +//---------------------------------------------------------------------- +FTermDetectionTest::~FTermDetectionTest() +{ + closeMasterPTY(); + closeSlavePTY(); + // Unmap shared memory + munmap (shared_state, sizeof(*shared_state)); +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::classNameTest() +{ + FTermDetection d; + const char* const classname = d.getClassName(); + CPPUNIT_ASSERT ( std::strcmp(classname, "FTermDetection") == 0 ); +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::ansiTest() +{ + setenv ("TERM", "ansi", 1); + FTermDetection detect; + detect.setTermFileName(C_STR("ansi")); + + pid_t pid = forkProcess(); + + if ( isChildProcess(pid) ) + { + setenv ("TERM", "ansi", 1); + unsetenv("COLORTERM"); + unsetenv("VTE_VERSION"); + unsetenv("XTERM_VERSION"); + unsetenv("ROXTERM_ID"); + unsetenv("KONSOLE_DBUS_SESSION"); + unsetenv("KONSOLE_DCOP"); + unsetenv("TMUX"); + detect.detect(); + + CPPUNIT_ASSERT ( ! detect.isXTerminal() ); + CPPUNIT_ASSERT ( detect.isAnsiTerminal() ); + CPPUNIT_ASSERT ( ! detect.isRxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isUrxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMltermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isPuttyTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKdeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isGnomeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKtermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isTeraTerm() ); + CPPUNIT_ASSERT ( ! detect.isCygwinTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMinttyTerm() ); + CPPUNIT_ASSERT ( ! detect.isLinuxTerm() ); + CPPUNIT_ASSERT ( ! detect.isFreeBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isNetBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isOpenBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isSunTerminal() ); + CPPUNIT_ASSERT ( ! detect.isScreenTerm() ); + CPPUNIT_ASSERT ( ! detect.isTmuxTerm() ); + CPPUNIT_ASSERT ( ! detect.canDisplay256Colors() ); + CPPUNIT_ASSERT ( ! detect.hasTerminalDetection() ); + CPPUNIT_ASSERT ( ! detect.hasSetCursorStyleSupport() ); + + debugOutput(); + + close(fd_stdin); + close(fd_stdout); + close(fd_stderr); + return; + } + else // Parent + { + // Start the terminal simulation + terminalSimulation (ansi); + + // Kill child process + kill (pid, SIGKILL); + } +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::xtermTest() +{ + FTermDetection detect; + detect.setTermFileName(C_STR("xterm")); + detect.setTerminalDetection(true); + + pid_t pid = forkProcess(); + + if ( isChildProcess(pid) ) + { + setenv ("TERM", "xterm", 1); + setenv ("XTERM_VERSION", "XTerm(312)", 1); + unsetenv("COLORTERM"); + unsetenv("VTE_VERSION"); + unsetenv("ROXTERM_ID"); + unsetenv("KONSOLE_DBUS_SESSION"); + unsetenv("KONSOLE_DCOP"); + unsetenv("TMUX"); + detect.detect(); + + CPPUNIT_ASSERT ( detect.isXTerminal() ); + CPPUNIT_ASSERT ( ! detect.isAnsiTerminal() ); + CPPUNIT_ASSERT ( ! detect.isRxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isUrxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMltermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isPuttyTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKdeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isGnomeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKtermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isTeraTerm() ); + CPPUNIT_ASSERT ( ! detect.isCygwinTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMinttyTerm() ); + CPPUNIT_ASSERT ( ! detect.isLinuxTerm() ); + CPPUNIT_ASSERT ( ! detect.isFreeBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isNetBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isOpenBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isSunTerminal() ); + CPPUNIT_ASSERT ( ! detect.isScreenTerm() ); + CPPUNIT_ASSERT ( ! detect.isTmuxTerm() ); + CPPUNIT_ASSERT ( detect.canDisplay256Colors() ); + CPPUNIT_ASSERT ( detect.hasTerminalDetection() ); + CPPUNIT_ASSERT ( detect.hasSetCursorStyleSupport() ); + + debugOutput(); + + close(fd_stdin); + close(fd_stdout); + close(fd_stderr); + return; + } + else // Parent + { + // Start the terminal simulation + terminalSimulation (xterm); + + // Kill child process + kill (pid, SIGKILL); + } +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::rxvtTest() +{ + FTermDetection detect; + detect.setTermFileName(C_STR("rxvt-cygwin-native")); + detect.setTerminalDetection(true); + + pid_t pid = forkProcess(); + + if ( isChildProcess(pid) ) + { + setenv ("TERM", "rxvt-cygwin-native", 1); + setenv ("COLORTERM", "rxvt-xpm", 1); + unsetenv("VTE_VERSION"); + unsetenv("XTERM_VERSION"); + unsetenv("ROXTERM_ID"); + unsetenv("KONSOLE_DBUS_SESSION"); + unsetenv("KONSOLE_DCOP"); + unsetenv("TMUX"); + detect.detect(); + + CPPUNIT_ASSERT ( ! detect.isXTerminal() ); + CPPUNIT_ASSERT ( ! detect.isAnsiTerminal() ); + CPPUNIT_ASSERT ( detect.isRxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isUrxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMltermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isPuttyTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKdeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isGnomeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKtermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isTeraTerm() ); + CPPUNIT_ASSERT ( ! detect.isCygwinTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMinttyTerm() ); + CPPUNIT_ASSERT ( ! detect.isLinuxTerm() ); + CPPUNIT_ASSERT ( ! detect.isFreeBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isNetBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isOpenBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isSunTerminal() ); + CPPUNIT_ASSERT ( ! detect.isScreenTerm() ); + CPPUNIT_ASSERT ( ! detect.isTmuxTerm() ); + CPPUNIT_ASSERT ( detect.canDisplay256Colors() ); + CPPUNIT_ASSERT ( detect.hasTerminalDetection() ); + CPPUNIT_ASSERT ( ! detect.hasSetCursorStyleSupport() ); + + debugOutput(); + + close(fd_stdin); + close(fd_stdout); + close(fd_stderr); + return; + } + else // Parent + { + // Start the terminal simulation + terminalSimulation (rxvt); + + // Kill child process + kill (pid, SIGKILL); + } +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::urxvtTest() +{ + FTermDetection detect; + detect.setTermFileName(C_STR("rxvt-unicode-256color")); + detect.setTerminalDetection(true); + + pid_t pid = forkProcess(); + + if ( isChildProcess(pid) ) + { + setenv ("TERM", "rxvt-unicode-256color", 1); + setenv ("COLORTERM", "rxvt-xpm", 1); + unsetenv("VTE_VERSION"); + unsetenv("XTERM_VERSION"); + unsetenv("ROXTERM_ID"); + unsetenv("KONSOLE_DBUS_SESSION"); + unsetenv("KONSOLE_DCOP"); + unsetenv("TMUX"); + detect.detect(); + + CPPUNIT_ASSERT ( ! detect.isXTerminal() ); + CPPUNIT_ASSERT ( ! detect.isAnsiTerminal() ); + CPPUNIT_ASSERT ( detect.isRxvtTerminal() ); + CPPUNIT_ASSERT ( detect.isUrxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMltermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isPuttyTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKdeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isGnomeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKtermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isTeraTerm() ); + CPPUNIT_ASSERT ( ! detect.isCygwinTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMinttyTerm() ); + CPPUNIT_ASSERT ( ! detect.isLinuxTerm() ); + CPPUNIT_ASSERT ( ! detect.isFreeBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isNetBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isOpenBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isSunTerminal() ); + CPPUNIT_ASSERT ( ! detect.isScreenTerm() ); + CPPUNIT_ASSERT ( ! detect.isTmuxTerm() ); + CPPUNIT_ASSERT ( detect.canDisplay256Colors() ); + CPPUNIT_ASSERT ( detect.hasTerminalDetection() ); + CPPUNIT_ASSERT ( ! detect.hasSetCursorStyleSupport() ); + + debugOutput(); + + close(fd_stdin); + close(fd_stdout); + close(fd_stderr); + return; + } + else // Parent + { + // Start the terminal simulation + terminalSimulation (urxvt); + + // Kill child process + kill (pid, SIGKILL); + } +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::mltermTest() +{ + FTermDetection detect; + detect.setTermFileName(C_STR("mlterm")); + detect.setTerminalDetection(true); + + pid_t pid = forkProcess(); + + if ( isChildProcess(pid) ) + { + setenv ("TERM", "mlterm", 1); + setenv ("MLTERM", "3.8.4", 1); + unsetenv("COLORTERM"); + unsetenv("VTE_VERSION"); + unsetenv("XTERM_VERSION"); + unsetenv("ROXTERM_ID"); + unsetenv("KONSOLE_DBUS_SESSION"); + unsetenv("KONSOLE_DCOP"); + unsetenv("TMUX"); + detect.detect(); + + CPPUNIT_ASSERT ( ! detect.isXTerminal() ); + CPPUNIT_ASSERT ( ! detect.isAnsiTerminal() ); + CPPUNIT_ASSERT ( ! detect.isRxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isUrxvtTerminal() ); + CPPUNIT_ASSERT ( detect.isMltermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isPuttyTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKdeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isGnomeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKtermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isTeraTerm() ); + CPPUNIT_ASSERT ( ! detect.isCygwinTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMinttyTerm() ); + CPPUNIT_ASSERT ( ! detect.isLinuxTerm() ); + CPPUNIT_ASSERT ( ! detect.isFreeBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isNetBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isOpenBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isSunTerminal() ); + CPPUNIT_ASSERT ( ! detect.isScreenTerm() ); + CPPUNIT_ASSERT ( ! detect.isTmuxTerm() ); + CPPUNIT_ASSERT ( detect.canDisplay256Colors() ); + CPPUNIT_ASSERT ( detect.hasTerminalDetection() ); + CPPUNIT_ASSERT ( ! detect.hasSetCursorStyleSupport() ); + + debugOutput(); + + close(fd_stdin); + close(fd_stdout); + close(fd_stderr); + return; + } + else // Parent + { + // Start the terminal simulation + terminalSimulation (mlterm); + + // Kill child process + kill (pid, SIGKILL); + } +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::puttyTest() +{ + FTermDetection detect; + detect.setTermFileName(C_STR("xterm")); + detect.setTerminalDetection(true); + + pid_t pid = forkProcess(); + + if ( isChildProcess(pid) ) + { + setenv ("TERM", "xterm", 1); + unsetenv("COLORTERM"); + unsetenv("VTE_VERSION"); + unsetenv("XTERM_VERSION"); + unsetenv("ROXTERM_ID"); + unsetenv("KONSOLE_DBUS_SESSION"); + unsetenv("KONSOLE_DCOP"); + unsetenv("TMUX"); + detect.detect(); + + CPPUNIT_ASSERT ( detect.isXTerminal() ); + CPPUNIT_ASSERT ( ! detect.isAnsiTerminal() ); + CPPUNIT_ASSERT ( ! detect.isRxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isUrxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMltermTerminal() ); + CPPUNIT_ASSERT ( detect.isPuttyTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKdeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isGnomeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKtermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isTeraTerm() ); + CPPUNIT_ASSERT ( ! detect.isCygwinTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMinttyTerm() ); + CPPUNIT_ASSERT ( ! detect.isLinuxTerm() ); + CPPUNIT_ASSERT ( ! detect.isFreeBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isNetBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isOpenBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isSunTerminal() ); + CPPUNIT_ASSERT ( ! detect.isScreenTerm() ); + CPPUNIT_ASSERT ( ! detect.isTmuxTerm() ); + CPPUNIT_ASSERT ( detect.canDisplay256Colors() ); + CPPUNIT_ASSERT ( detect.hasTerminalDetection() ); + CPPUNIT_ASSERT ( ! detect.hasSetCursorStyleSupport() ); + + //debug = true; + debugOutput(); + + close(fd_stdin); + close(fd_stdout); + close(fd_stderr); + return; + } + else // Parent + { + // Start the terminal simulation + terminalSimulation (putty); + + // Kill child process + kill (pid, SIGKILL); + } +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::kdeKonsoleTest() +{ + FTermDetection detect; + detect.setTermFileName(C_STR("xterm-256color")); + detect.setTerminalDetection(true); + + pid_t pid = forkProcess(); + + if ( isChildProcess(pid) ) + { + setenv ("TERM", "xterm-256color", 1); + setenv ("COLORTERM", "truecolor", 1); + setenv ("KONSOLE_DBUS_SERVICE", "DCOPRef(konsole-11768,konsole)", 1); + setenv ("KONSOLE_DCOP", ":1.77", 1); + unsetenv("VTE_VERSION"); + unsetenv("XTERM_VERSION"); + unsetenv("ROXTERM_ID"); + unsetenv("TMUX"); + detect.detect(); + + CPPUNIT_ASSERT ( detect.isXTerminal() ); + CPPUNIT_ASSERT ( ! detect.isAnsiTerminal() ); + CPPUNIT_ASSERT ( ! detect.isRxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isUrxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMltermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isPuttyTerminal() ); + CPPUNIT_ASSERT ( detect.isKdeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isGnomeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKtermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isTeraTerm() ); + CPPUNIT_ASSERT ( ! detect.isCygwinTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMinttyTerm() ); + CPPUNIT_ASSERT ( ! detect.isLinuxTerm() ); + CPPUNIT_ASSERT ( ! detect.isFreeBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isNetBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isOpenBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isSunTerminal() ); + CPPUNIT_ASSERT ( ! detect.isScreenTerm() ); + CPPUNIT_ASSERT ( ! detect.isTmuxTerm() ); + CPPUNIT_ASSERT ( detect.canDisplay256Colors() ); + CPPUNIT_ASSERT ( detect.hasTerminalDetection() ); + CPPUNIT_ASSERT ( ! detect.hasSetCursorStyleSupport() ); + + debugOutput(); + + close(fd_stdin); + close(fd_stdout); + close(fd_stderr); + return; + } + else // Parent + { + // Start the terminal simulation + terminalSimulation (kde_konsole); + + // Kill child process + kill (pid, SIGKILL); + } +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::gnomeTerminalTest() +{ + FTermDetection detect; + detect.setTermFileName(C_STR("xterm-256color")); + detect.setTerminalDetection(true); + + pid_t pid = forkProcess(); + + if ( isChildProcess(pid) ) + { + setenv ("TERM", "xterm-256color", 1); + setenv ("COLORTERM", "truecolor", 1); + setenv ("VTE_VERSION", "5202", 1); + unsetenv("XTERM_VERSION"); + unsetenv("ROXTERM_ID"); + unsetenv("KONSOLE_DBUS_SESSION"); + unsetenv("KONSOLE_DCOP"); + unsetenv("TMUX"); + + detect.detect(); + + CPPUNIT_ASSERT ( detect.isXTerminal() ); + CPPUNIT_ASSERT ( ! detect.isAnsiTerminal() ); + CPPUNIT_ASSERT ( ! detect.isRxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isUrxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMltermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isPuttyTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKdeTerminal() ); + CPPUNIT_ASSERT ( detect.isGnomeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKtermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isTeraTerm() ); + CPPUNIT_ASSERT ( ! detect.isCygwinTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMinttyTerm() ); + CPPUNIT_ASSERT ( ! detect.isLinuxTerm() ); + CPPUNIT_ASSERT ( ! detect.isFreeBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isNetBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isOpenBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isSunTerminal() ); + CPPUNIT_ASSERT ( ! detect.isScreenTerm() ); + CPPUNIT_ASSERT ( ! detect.isTmuxTerm() ); + CPPUNIT_ASSERT ( detect.canDisplay256Colors() ); + CPPUNIT_ASSERT ( detect.hasTerminalDetection() ); + CPPUNIT_ASSERT ( detect.hasSetCursorStyleSupport() ); + + debugOutput(); + + close(fd_stdin); + close(fd_stdout); + close(fd_stderr); + return; + } + else // Parent + { + // Start the terminal simulation + terminalSimulation (gnome_terminal); + + // Kill child process + kill (pid, SIGKILL); + } +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::ktermTest() +{ + FTermDetection detect; + detect.setTermFileName(C_STR("kterm")); + detect.setTerminalDetection(true); + + pid_t pid = forkProcess(); + + if ( isChildProcess(pid) ) + { + setenv ("TERM", "kterm", 1); + unsetenv("COLORTERM"); + unsetenv("VTE_VERSION"); + unsetenv("XTERM_VERSION"); + unsetenv("ROXTERM_ID"); + unsetenv("KONSOLE_DBUS_SESSION"); + unsetenv("KONSOLE_DCOP"); + unsetenv("TMUX"); + + detect.detect(); + + CPPUNIT_ASSERT ( ! detect.isXTerminal() ); + CPPUNIT_ASSERT ( ! detect.isAnsiTerminal() ); + CPPUNIT_ASSERT ( ! detect.isRxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isUrxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMltermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isPuttyTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKdeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isGnomeTerminal() ); + CPPUNIT_ASSERT ( detect.isKtermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isTeraTerm() ); + CPPUNIT_ASSERT ( ! detect.isCygwinTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMinttyTerm() ); + CPPUNIT_ASSERT ( ! detect.isLinuxTerm() ); + CPPUNIT_ASSERT ( ! detect.isFreeBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isNetBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isOpenBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isSunTerminal() ); + CPPUNIT_ASSERT ( ! detect.isScreenTerm() ); + CPPUNIT_ASSERT ( ! detect.isTmuxTerm() ); + CPPUNIT_ASSERT ( ! detect.canDisplay256Colors() ); + CPPUNIT_ASSERT ( ! detect.hasTerminalDetection() ); + CPPUNIT_ASSERT ( ! detect.hasSetCursorStyleSupport() ); + + debugOutput(); + + close(fd_stdin); + close(fd_stdout); + close(fd_stderr); + return; + } + else // Parent + { + // Start the terminal simulation + terminalSimulation (kterm); + + // Kill child process + kill (pid, SIGKILL); + } +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::teraTermTest() +{ + FTermDetection detect; + detect.setTermFileName(C_STR("xterm")); + detect.setTerminalDetection(true); + + pid_t pid = forkProcess(); + + if ( isChildProcess(pid) ) + { + setenv ("TERM", "xterm", 1); + unsetenv("COLORTERM"); + unsetenv("VTE_VERSION"); + unsetenv("XTERM_VERSION"); + unsetenv("ROXTERM_ID"); + unsetenv("KONSOLE_DBUS_SESSION"); + unsetenv("KONSOLE_DCOP"); + unsetenv("TMUX"); + + detect.detect(); + + CPPUNIT_ASSERT ( detect.isXTerminal() ); + CPPUNIT_ASSERT ( ! detect.isAnsiTerminal() ); + CPPUNIT_ASSERT ( ! detect.isRxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isUrxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMltermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isPuttyTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKdeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isGnomeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKtermTerminal() ); + CPPUNIT_ASSERT ( detect.isTeraTerm() ); + CPPUNIT_ASSERT ( ! detect.isCygwinTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMinttyTerm() ); + CPPUNIT_ASSERT ( ! detect.isLinuxTerm() ); + CPPUNIT_ASSERT ( ! detect.isFreeBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isNetBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isOpenBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isSunTerminal() ); + CPPUNIT_ASSERT ( ! detect.isScreenTerm() ); + CPPUNIT_ASSERT ( ! detect.isTmuxTerm() ); + CPPUNIT_ASSERT ( ! detect.canDisplay256Colors() ); + CPPUNIT_ASSERT ( detect.hasTerminalDetection() ); + CPPUNIT_ASSERT ( ! detect.hasSetCursorStyleSupport() ); + + debugOutput(); + + close(fd_stdin); + close(fd_stdout); + close(fd_stderr); + return; + } + else // Parent + { + // Start the terminal simulation + terminalSimulation (tera_term); + + // Kill child process + kill (pid, SIGKILL); + } +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::cygwinTest() +{ + FTermDetection detect; + detect.setTermFileName(C_STR("cygwin")); + detect.setTerminalDetection(true); + + pid_t pid = forkProcess(); + + if ( isChildProcess(pid) ) + { + setenv ("TERM", "cygwin", 1); + unsetenv("COLORTERM"); + unsetenv("VTE_VERSION"); + unsetenv("XTERM_VERSION"); + unsetenv("ROXTERM_ID"); + unsetenv("KONSOLE_DBUS_SESSION"); + unsetenv("KONSOLE_DCOP"); + unsetenv("TMUX"); + + detect.detect(); + + CPPUNIT_ASSERT ( ! detect.isXTerminal() ); + CPPUNIT_ASSERT ( ! detect.isAnsiTerminal() ); + CPPUNIT_ASSERT ( ! detect.isRxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isUrxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMltermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isPuttyTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKdeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isGnomeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKtermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isTeraTerm() ); + CPPUNIT_ASSERT ( detect.isCygwinTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMinttyTerm() ); + CPPUNIT_ASSERT ( ! detect.isLinuxTerm() ); + CPPUNIT_ASSERT ( ! detect.isFreeBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isNetBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isOpenBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isSunTerminal() ); + CPPUNIT_ASSERT ( ! detect.isScreenTerm() ); + CPPUNIT_ASSERT ( ! detect.isTmuxTerm() ); + CPPUNIT_ASSERT ( ! detect.canDisplay256Colors() ); + CPPUNIT_ASSERT ( detect.hasTerminalDetection() ); + CPPUNIT_ASSERT ( ! detect.hasSetCursorStyleSupport() ); + + debugOutput(); + + close(fd_stdin); + close(fd_stdout); + close(fd_stderr); + return; + } + else // Parent + { + // Start the terminal simulation + terminalSimulation (cygwin); + + // Kill child process + kill (pid, SIGKILL); + } +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::minttyTest() +{ + FTermDetection detect; + detect.setTermFileName(C_STR("xterm-256color")); + detect.setTerminalDetection(true); + + pid_t pid = forkProcess(); + + if ( isChildProcess(pid) ) + { + setenv ("TERM", "xterm-256color", 1); + unsetenv("COLORTERM"); + unsetenv("VTE_VERSION"); + unsetenv("XTERM_VERSION"); + unsetenv("ROXTERM_ID"); + unsetenv("KONSOLE_DBUS_SESSION"); + unsetenv("KONSOLE_DCOP"); + unsetenv("TMUX"); + + detect.detect(); + + CPPUNIT_ASSERT ( detect.isXTerminal() ); + CPPUNIT_ASSERT ( ! detect.isAnsiTerminal() ); + CPPUNIT_ASSERT ( ! detect.isRxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isUrxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMltermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isPuttyTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKdeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isGnomeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKtermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isTeraTerm() ); + CPPUNIT_ASSERT ( ! detect.isCygwinTerminal() ); + CPPUNIT_ASSERT ( detect.isMinttyTerm() ); + CPPUNIT_ASSERT ( ! detect.isLinuxTerm() ); + CPPUNIT_ASSERT ( ! detect.isFreeBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isNetBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isOpenBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isSunTerminal() ); + CPPUNIT_ASSERT ( ! detect.isScreenTerm() ); + CPPUNIT_ASSERT ( ! detect.isTmuxTerm() ); + CPPUNIT_ASSERT ( detect.canDisplay256Colors() ); + CPPUNIT_ASSERT ( detect.hasTerminalDetection() ); + CPPUNIT_ASSERT ( detect.hasSetCursorStyleSupport() ); + + debugOutput(); + + close(fd_stdin); + close(fd_stdout); + close(fd_stderr); + return; + } + else // Parent + { + // Start the terminal simulation + terminalSimulation (mintty); + + // Kill child process + kill (pid, SIGKILL); + } +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::linuxTest() +{ + FTermDetection detect; + detect.setTermFileName(C_STR("linux")); + detect.setTerminalDetection(true); + + pid_t pid = forkProcess(); + + if ( isChildProcess(pid) ) + { + setenv ("TERM", "linux", 1); + unsetenv("COLORTERM"); + unsetenv("VTE_VERSION"); + unsetenv("XTERM_VERSION"); + unsetenv("ROXTERM_ID"); + unsetenv("KONSOLE_DBUS_SESSION"); + unsetenv("KONSOLE_DCOP"); + unsetenv("TMUX"); + + detect.detect(); + + CPPUNIT_ASSERT ( ! detect.isXTerminal() ); + CPPUNIT_ASSERT ( ! detect.isAnsiTerminal() ); + CPPUNIT_ASSERT ( ! detect.isRxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isUrxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMltermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isPuttyTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKdeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isGnomeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKtermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isTeraTerm() ); + CPPUNIT_ASSERT ( ! detect.isCygwinTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMinttyTerm() ); + CPPUNIT_ASSERT ( detect.isLinuxTerm() ); + CPPUNIT_ASSERT ( ! detect.isFreeBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isNetBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isOpenBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isSunTerminal() ); + CPPUNIT_ASSERT ( ! detect.isScreenTerm() ); + CPPUNIT_ASSERT ( ! detect.isTmuxTerm() ); + CPPUNIT_ASSERT ( ! detect.canDisplay256Colors() ); + CPPUNIT_ASSERT ( detect.hasTerminalDetection() ); + CPPUNIT_ASSERT ( ! detect.hasSetCursorStyleSupport() ); + + debugOutput(); + + close(fd_stdin); + close(fd_stdout); + close(fd_stderr); + return; + } + else // Parent + { + // Start the terminal simulation + terminalSimulation (linux_con); + + // Kill child process + kill (pid, SIGKILL); + } +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::freebsdTest() +{ + FTermDetection detect; + detect.setTermFileName(C_STR("xterm")); + detect.setTerminalDetection(true); + + pid_t pid = forkProcess(); + + if ( isChildProcess(pid) ) + { + setenv ("TERM", "xterm", 1); + unsetenv("COLORTERM"); + unsetenv("VTE_VERSION"); + unsetenv("XTERM_VERSION"); + unsetenv("ROXTERM_ID"); + unsetenv("KONSOLE_DBUS_SESSION"); + unsetenv("KONSOLE_DCOP"); + unsetenv("TMUX"); + + detect.detect(); + detect.setFreeBSDTerm (true); // Fake FreeBSD Console detection + + CPPUNIT_ASSERT ( detect.isXTerminal() ); + CPPUNIT_ASSERT ( ! detect.isAnsiTerminal() ); + CPPUNIT_ASSERT ( ! detect.isRxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isUrxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMltermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isPuttyTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKdeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isGnomeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKtermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isTeraTerm() ); + CPPUNIT_ASSERT ( ! detect.isCygwinTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMinttyTerm() ); + CPPUNIT_ASSERT ( ! detect.isLinuxTerm() ); + CPPUNIT_ASSERT ( detect.isFreeBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isNetBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isOpenBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isSunTerminal() ); + CPPUNIT_ASSERT ( ! detect.isScreenTerm() ); + CPPUNIT_ASSERT ( ! detect.isTmuxTerm() ); + CPPUNIT_ASSERT ( ! detect.canDisplay256Colors() ); + CPPUNIT_ASSERT ( detect.hasTerminalDetection() ); + CPPUNIT_ASSERT ( ! detect.hasSetCursorStyleSupport() ); + + debugOutput(); + + close(fd_stdin); + close(fd_stdout); + close(fd_stderr); + return; + } + else // Parent + { + // Start the terminal simulation + terminalSimulation (freebsd_con); + + // Kill child process + kill (pid, SIGKILL); + } +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::netbsdTest() +{ + FTermDetection detect; + detect.setTermFileName(C_STR("wsvt25")); + detect.setTerminalDetection(true); + + pid_t pid = forkProcess(); + + if ( isChildProcess(pid) ) + { + setenv ("TERM", "wsvt25", 1); + unsetenv("COLORTERM"); + unsetenv("VTE_VERSION"); + unsetenv("XTERM_VERSION"); + unsetenv("ROXTERM_ID"); + unsetenv("KONSOLE_DBUS_SESSION"); + unsetenv("KONSOLE_DCOP"); + unsetenv("TMUX"); + + detect.detect(); + detect.setNetBSDTerm (true); // Fake NetBSD Console detection + + CPPUNIT_ASSERT ( ! detect.isXTerminal() ); + CPPUNIT_ASSERT ( ! detect.isAnsiTerminal() ); + CPPUNIT_ASSERT ( ! detect.isRxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isUrxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMltermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isPuttyTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKdeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isGnomeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKtermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isTeraTerm() ); + CPPUNIT_ASSERT ( ! detect.isCygwinTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMinttyTerm() ); + CPPUNIT_ASSERT ( ! detect.isLinuxTerm() ); + CPPUNIT_ASSERT ( ! detect.isFreeBSDTerm() ); + CPPUNIT_ASSERT ( detect.isNetBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isOpenBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isSunTerminal() ); + CPPUNIT_ASSERT ( ! detect.isScreenTerm() ); + CPPUNIT_ASSERT ( ! detect.isTmuxTerm() ); + CPPUNIT_ASSERT ( ! detect.canDisplay256Colors() ); + CPPUNIT_ASSERT ( detect.hasTerminalDetection() ); + CPPUNIT_ASSERT ( ! detect.hasSetCursorStyleSupport() ); + + debugOutput(); + + close(fd_stdin); + close(fd_stdout); + close(fd_stderr); + return; + } + else // Parent + { + // Start the terminal simulation + terminalSimulation (netbsd_con); + + // Kill child process + kill (pid, SIGKILL); + } +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::openbsdTest() +{ + FTermDetection detect; + detect.setTermFileName(C_STR("vt220")); + detect.setTerminalDetection(true); + + pid_t pid = forkProcess(); + + if ( isChildProcess(pid) ) + { + setenv ("TERM", "vt220", 1); + unsetenv("COLORTERM"); + unsetenv("VTE_VERSION"); + unsetenv("XTERM_VERSION"); + unsetenv("ROXTERM_ID"); + unsetenv("KONSOLE_DBUS_SESSION"); + unsetenv("KONSOLE_DCOP"); + unsetenv("TMUX"); + + detect.detect(); + detect.setOpenBSDTerm (true); // Fake OpenBSD Console detection + + CPPUNIT_ASSERT ( ! detect.isXTerminal() ); + CPPUNIT_ASSERT ( ! detect.isAnsiTerminal() ); + CPPUNIT_ASSERT ( ! detect.isRxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isUrxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMltermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isPuttyTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKdeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isGnomeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKtermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isTeraTerm() ); + CPPUNIT_ASSERT ( ! detect.isCygwinTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMinttyTerm() ); + CPPUNIT_ASSERT ( ! detect.isLinuxTerm() ); + CPPUNIT_ASSERT ( ! detect.isFreeBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isNetBSDTerm() ); + CPPUNIT_ASSERT ( detect.isOpenBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isSunTerminal() ); + CPPUNIT_ASSERT ( ! detect.isScreenTerm() ); + CPPUNIT_ASSERT ( ! detect.isTmuxTerm() ); + CPPUNIT_ASSERT ( ! detect.canDisplay256Colors() ); + CPPUNIT_ASSERT ( detect.hasTerminalDetection() ); + CPPUNIT_ASSERT ( ! detect.hasSetCursorStyleSupport() ); + + debugOutput(); + + close(fd_stdin); + close(fd_stdout); + close(fd_stderr); + return; + } + else // Parent + { + // Start the terminal simulation + terminalSimulation (openbsd_con); + + // Kill child process + kill (pid, SIGKILL); + } +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::sunTest() +{ + FTermDetection detect; + detect.setTermFileName(C_STR("sun-color")); + + pid_t pid = forkProcess(); + + if ( isChildProcess(pid) ) + { + setenv ("TERM", "sun-color", 1); + unsetenv("COLORTERM"); + unsetenv("VTE_VERSION"); + unsetenv("XTERM_VERSION"); + unsetenv("ROXTERM_ID"); + unsetenv("KONSOLE_DBUS_SESSION"); + unsetenv("KONSOLE_DCOP"); + unsetenv("TMUX"); + + detect.detect(); + + CPPUNIT_ASSERT ( ! detect.isXTerminal() ); + CPPUNIT_ASSERT ( ! detect.isAnsiTerminal() ); + CPPUNIT_ASSERT ( ! detect.isRxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isUrxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMltermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isPuttyTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKdeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isGnomeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKtermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isTeraTerm() ); + CPPUNIT_ASSERT ( ! detect.isCygwinTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMinttyTerm() ); + CPPUNIT_ASSERT ( ! detect.isLinuxTerm() ); + CPPUNIT_ASSERT ( ! detect.isFreeBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isNetBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isOpenBSDTerm() ); + CPPUNIT_ASSERT ( detect.isSunTerminal() ); + CPPUNIT_ASSERT ( ! detect.isScreenTerm() ); + CPPUNIT_ASSERT ( ! detect.isTmuxTerm() ); + CPPUNIT_ASSERT ( ! detect.canDisplay256Colors() ); + CPPUNIT_ASSERT ( ! detect.hasTerminalDetection() ); + CPPUNIT_ASSERT ( ! detect.hasSetCursorStyleSupport() ); + + debugOutput(); + + close(fd_stdin); + close(fd_stdout); + close(fd_stderr); + return; + } + else // Parent + { + // Start the terminal simulation + terminalSimulation (sun_con); + + // Kill child process + kill (pid, SIGKILL); + } +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::screenTest() +{ + FTermDetection detect; + detect.setTermFileName(C_STR("screen")); + detect.setTerminalDetection(true); + + pid_t pid = forkProcess(); + + if ( isChildProcess(pid) ) + { + setenv ("TERM", "screen", 1); + setenv ("TERMCAP", "SC|screen|VT 100/ANSI X3.64 virtual terminal:...", 1); + unsetenv("COLORTERM"); + unsetenv("VTE_VERSION"); + unsetenv("XTERM_VERSION"); + unsetenv("ROXTERM_ID"); + unsetenv("KONSOLE_DBUS_SESSION"); + unsetenv("KONSOLE_DCOP"); + unsetenv("TMUX"); + + detect.detect(); + + CPPUNIT_ASSERT ( ! detect.isXTerminal() ); + CPPUNIT_ASSERT ( ! detect.isAnsiTerminal() ); + CPPUNIT_ASSERT ( ! detect.isRxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isUrxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMltermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isPuttyTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKdeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isGnomeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKtermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isTeraTerm() ); + CPPUNIT_ASSERT ( ! detect.isCygwinTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMinttyTerm() ); + CPPUNIT_ASSERT ( ! detect.isLinuxTerm() ); + CPPUNIT_ASSERT ( ! detect.isFreeBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isNetBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isOpenBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isSunTerminal() ); + CPPUNIT_ASSERT ( detect.isScreenTerm() ); + CPPUNIT_ASSERT ( ! detect.isTmuxTerm() ); + CPPUNIT_ASSERT ( ! detect.canDisplay256Colors() ); + CPPUNIT_ASSERT ( detect.hasTerminalDetection() ); + CPPUNIT_ASSERT ( ! detect.hasSetCursorStyleSupport() ); + + debugOutput(); + + close(fd_stdin); + close(fd_stdout); + close(fd_stderr); + return; + } + else // Parent + { + // Start the terminal simulation + terminalSimulation (screen); + + // Kill child process + kill (pid, SIGKILL); + } +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::tmuxTest() +{ + FTermDetection detect; + detect.setTermFileName(C_STR("screen")); + detect.setTerminalDetection(true); + + pid_t pid = forkProcess(); + + if ( isChildProcess(pid) ) + { + setenv ("TERM", "screen", 1); + setenv ("TMUX", "/tmp/tmux-1000/default,7844,0", 1); + setenv ("TMUX_PANE", "%0", 1); + unsetenv("COLORTERM"); + unsetenv("VTE_VERSION"); + unsetenv("XTERM_VERSION"); + unsetenv("ROXTERM_ID"); + unsetenv("KONSOLE_DBUS_SESSION"); + unsetenv("KONSOLE_DCOP"); + + detect.detect(); + + CPPUNIT_ASSERT ( ! detect.isXTerminal() ); + CPPUNIT_ASSERT ( ! detect.isAnsiTerminal() ); + CPPUNIT_ASSERT ( ! detect.isRxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isUrxvtTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMltermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isPuttyTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKdeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isGnomeTerminal() ); + CPPUNIT_ASSERT ( ! detect.isKtermTerminal() ); + CPPUNIT_ASSERT ( ! detect.isTeraTerm() ); + CPPUNIT_ASSERT ( ! detect.isCygwinTerminal() ); + CPPUNIT_ASSERT ( ! detect.isMinttyTerm() ); + CPPUNIT_ASSERT ( ! detect.isLinuxTerm() ); + CPPUNIT_ASSERT ( ! detect.isFreeBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isNetBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isOpenBSDTerm() ); + CPPUNIT_ASSERT ( ! detect.isSunTerminal() ); + CPPUNIT_ASSERT ( detect.isScreenTerm() ); + CPPUNIT_ASSERT ( detect.isTmuxTerm() ); + CPPUNIT_ASSERT ( ! detect.canDisplay256Colors() ); + CPPUNIT_ASSERT ( detect.hasTerminalDetection() ); + CPPUNIT_ASSERT ( ! detect.hasSetCursorStyleSupport() ); + + debugOutput(); + + close(fd_stdin); + close(fd_stdout); + close(fd_stderr); + return; + } + else // Parent + { + // Start the terminal simulation + terminalSimulation (tmux); + + // Kill child process + kill (pid, SIGKILL); + } +} + + +// private methods of FOptiMoveTest +//---------------------------------------------------------------------- +std::string FTermDetectionTest::printSequence (const std::string& s) +{ + std::string sequence; + const std::string ctrl_character[] = + { + "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", + "BS", "Tab", "LF", "VT", "FF", "CR", "SO", "SI", + "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", + "CAN", "EM", "SUB", "Esc", "FS", "GS", "RS", "US", + "Space" + }; + + for (std::string::size_type i = 0; i < s.length(); ++i) + { + char ch = buffer[i]; + + if ( ch < 0x21 ) + sequence += ctrl_character[uInt(ch)]; + else + sequence += ch; + + sequence += ' '; + } + + return sequence; +} + +//---------------------------------------------------------------------- +char* FTermDetectionTest::getAnswerback (console con) +{ + static char* Answerback[] = + { + 0, // Ansi, + 0, // XTerm + 0, // Rxvt + 0, // Urxvt + 0, // mlterm - Multi Lingual TERMinal + C_STR("PuTTY"), // PuTTY + 0, // KDE Konsole + 0, // GNOME Terminal + 0, // kterm, + 0, // Tera Term + 0, // Cygwin + 0, // Mintty + 0, // Linux console + 0, // FreeBSD console + 0, // NetBSD console + 0, // OpenBSD console + 0, // Sun console + 0, // screen + 0 // tmux + }; + + return Answerback[con]; +} + +//---------------------------------------------------------------------- +char* FTermDetectionTest::getDSR (console con) +{ + static char* DSR[] = + { + 0, // Ansi, + C_STR("\033[0n"), // XTerm + C_STR("\033[0n"), // Rxvt + C_STR("\033[0n"), // Urxvt + C_STR("\033[0n"), // mlterm - Multi Lingual TERMinal + C_STR("\033[0n"), // PuTTY + C_STR("\033[0n"), // KDE Konsole + C_STR("\033[0n"), // GNOME Terminal + C_STR("\033[0n"), // kterm, + C_STR("\033[0n"), // Tera Term + 0, // Cygwin + C_STR("\033[0n"), // Mintty + C_STR("\033[0n"), // Linux console + C_STR("\033[0n"), // FreeBSD console + C_STR("\033[0n"), // NetBSD console + C_STR("\033[0n"), // OpenBSD console + 0, // Sun console + C_STR("\033[0n"), // screen + C_STR("\033[0n") // tmux + }; + + return DSR[con]; +} + +//---------------------------------------------------------------------- +char* FTermDetectionTest::getDECID (console con) +{ + static char* DECID[] = + { + 0, // Ansi, + C_STR("\033[?63;1;2;6;4;6;9;15;22c"), // XTerm + C_STR("\033[?1;2c"), // Rxvt + C_STR("\033[?1;2c"), // Urxvt + C_STR("\033[?63;1;2;3;4;7;29c"), // mlterm - Multi Lingual TERMinal + C_STR("\033[?6c"), // PuTTY + C_STR("\033[?1;2c"), // KDE Konsole + C_STR("\033[?62;c"), // GNOME Terminal + C_STR("\033[?1;2c"), // kterm, + C_STR("\033[?1;2c"), // Tera Term + 0, // Cygwin + C_STR("\033[?1;2;6;22c"), // Mintty + C_STR("\033[?6c"), // Linux console + 0, // FreeBSD console + 0, // NetBSD console + 0, // OpenBSD console + 0, // Sun console + C_STR("\033[?1;2c"), // screen + 0 // tmux + }; + + return DECID[con]; +} + +//---------------------------------------------------------------------- +char* FTermDetectionTest::getDA (console con) +{ + static char* DA[] = + { + 0, // Ansi, + C_STR("\033[?63;1;2;6;4;6;9;15;22c"), // XTerm + C_STR("\033[?1;2c"), // Rxvt + C_STR("\033[?1;2c"), // Urxvt + C_STR("\033[?63;1;2;3;4;7;29c"), // mlterm - Multi Lingual TERMinal + C_STR("\033[?6c"), // PuTTY + C_STR("\033[?1;2c"), // KDE Konsole + C_STR("\033[?62;c"), // GNOME Terminal + C_STR("\033[?1;2c"), // kterm, + C_STR("\033[?1;2c"), // Tera Term + C_STR("\033[?6c"), // Cygwin + C_STR("\033[?1;2;6;22c"), // Mintty + C_STR("\033[?6c"), // Linux console + C_STR("\033[?1;2c"), // FreeBSD console + C_STR("\033[?62;6c"), // NetBSD console + C_STR("\033[?62;6c"), // OpenBSD console + 0, // Sun console + C_STR("\033[?1;2c"), // screen + C_STR("\033[?1;2c") // tmux + }; + + return DA[con]; +} + +//---------------------------------------------------------------------- +char* FTermDetectionTest::getDA1 (console con) +{ + static char* DA1[] = + { + 0, // Ansi, + 0, // XTerm + C_STR("\033[?1;2c"), // Rxvt + C_STR("\033[?1;2c"), // Urxvt + C_STR("\033[?63;1;2;3;4;7;29c"), // mlterm - Multi Lingual TERMinal + C_STR("\033[?6c"), // PuTTY + C_STR("\033[?1;2c"), // KDE Konsole + C_STR("\033[?62;c"), // GNOME Terminal + 0, // kterm, + C_STR("\033[?1;2c"), // Tera Term + C_STR("\033[?6c"), // Cygwin + C_STR("\033[?1;2;6;22c"), // Mintty + 0, // Linux console + 0, // FreeBSD console + 0, // NetBSD console + 0, // OpenBSD console + 0, // Sun console + 0, // screen + 0 // tmux + }; + + return DA1[con]; +} + +//---------------------------------------------------------------------- +char* FTermDetectionTest::getSEC_DA (console con) +{ + static char* SEC_DA[] = + { + 0, // Ansi, + C_STR("\033[>19;312;0c"), // XTerm + C_STR("\033[>82;20710;0c"), // Rxvt + C_STR("\033[>85;95;0c"), // Urxvt + C_STR("\033[>24;279;0c"), // mlterm - Multi Lingual TERMinal + C_STR("\033[>0;136;0c"), // PuTTY + C_STR("\033[>0;115;0c"), // KDE Konsole + C_STR("\033[>1;5202;0c"), // GNOME Terminal + C_STR("\033[?1;2c"), // kterm, + C_STR("\033[>32;278;0c"), // Tera Term + C_STR("\033[>67;200502;0c"), // Cygwin + C_STR("\033[>77;20402;0c"), // Mintty + 0, // Linux console + 0, // FreeBSD console + 0, // NetBSD console + 0, // OpenBSD console + 0, // Sun console + C_STR("\033[>83;40201;0c"), // screen + C_STR("\033[>84;0;0c") // tmux + }; + + return SEC_DA[con]; +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::debugOutput() +{ + if ( ! debug ) + return; + + setenv ("DSR", "\\033[5n", 1); + setenv ("CURSOR_POS", "\\033[6n", 1); + setenv ("DECID", "\\033Z", 1); + setenv ("DA", "\\033[c", 1); + setenv ("DA1", "\\033[1c", 1); + setenv ("SEC_DA", "\\033[>c", 1); + setenv ("ANSWERBACK", "\\005", 1); + setenv ("TITLE", "\\033[21t", 1); + setenv ("COLOR16", "\\033]4;15;?\\a", 1); + setenv ("COLOR88", "\\033]4;87;?\\a", 1); + setenv ("COLOR256", "\\033]4;254;?\\a", 1); + + setenv ("GO_MIDDLE", "\\033[80D\\033[15C", 1); + setenv ("GO_RIGHT", "\\033[79D\\033[40C", 1); + + FString line (69, '-'); + ::printf ("\n%s\n", line.c_str()); + ::printf ("Probe Escape sequence Reply\n"); + ::printf ("%s\n", line.c_str()); + + // Command line + char* child_av[] = + { + C_STR("/bin/bash"), + C_STR("-c"), + C_STR("for i in DSR CURSOR_POS DECID DA DA1 SEC_DA ANSWERBACK \ + TITLE COLOR16 COLOR88 COLOR256; \ + do \ + eval \"echo -en \\\"$i${GO_MIDDLE}\\\"; \ + echo -n \\\"\\${$i}\\\"; \ + echo -en \\\"${GO_RIGHT}\\${$i}\\\"\"; \ + sleep 0.5; \ + echo -e \"\\r\"; \ + done"), + 0 + }; + + execvp(child_av[0], child_av); +} + +//---------------------------------------------------------------------- +bool FTermDetectionTest::openMasterPTY() +{ + int result; + + // Open a pseudoterminal device + fd_master = posix_openpt(O_RDWR); + + if ( fd_master < 0 ) + return false; + + // Change the slave pseudoterminal access rights + result = grantpt(fd_master); + + if ( result != 0 ) + return false; + + // Unlock the pseudoterminal master/slave pair + result = unlockpt(fd_master); + + if ( result != 0 ) + return false; + + return true; +} + +//---------------------------------------------------------------------- +bool FTermDetectionTest::openSlavePTY() +{ + closeSlavePTY(); + + // Get PTY filename + const char* pty_name = ptsname(fd_master); + + if ( pty_name == 0 ) + return false; + + // Open the slave PTY + fd_slave = open(pty_name, O_RDWR); + + if ( fd_slave < 0 ) + return false; + + return true; +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::closeMasterPTY() +{ + if ( fd_master <= 0 ) + return; + + close (fd_master); + fd_master = -1; +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::closeSlavePTY() +{ + if ( fd_slave <= 0 ) + return; + + close (fd_slave); + fd_slave = -1; +} + +//---------------------------------------------------------------------- +pid_t FTermDetectionTest::forkProcess() +{ + // Initialize buffer with '\0' + std::fill_n (buffer, sizeof(buffer), '\0'); + + bool result = openMasterPTY(); + + if ( ! result ) + return -1; + + result = openSlavePTY(); + + if ( ! result ) + return -1; + + pid_t pid = fork(); // Create a child process + + if ( pid < 0) // Fork failed + return -1; + + if ( isChildProcess(pid) ) // Child process + { + struct termios term_settings; + closeMasterPTY(); + + // Creates a session and makes the current process to the leader + setsid(); + +#ifdef TIOCSCTTY + // Set controlling tty + ioctl(fd_slave, TIOCSCTTY, 0); +#endif + + // Get current terminal settings + result = tcgetattr(fd_slave, &term_settings); + + // Set raw mode on the slave side of the PTY + cfmakeraw (&term_settings); + tcsetattr (fd_slave, TCSANOW, &term_settings); + + close(fd_stdin); + close(fd_stdout); + close(fd_stderr); + + dup(fd_slave); // PTY becomes stdin (0) + dup(fd_slave); // PTY becomes stdout (1) + dup(fd_slave); // PTY becomes stderr (2) + + closeSlavePTY(); + + // The child process is now ready for input + *shared_state = true; + } + else + { + const int timeout = 150; // 1.5 seconds + int i = 0; + + // Wait until the child process is ready for input + while ( ! *shared_state && i < timeout ) + { + usleep(10000); // wait 10 ms + i++; + } + + *shared_state = false; + } + + return pid; +} + +//---------------------------------------------------------------------- +inline bool FTermDetectionTest::isChildProcess (pid_t pid) +{ + return bool( pid == 0 ); +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::terminalSimulation (console con) +{ + closeSlavePTY(); + + while ( 1 ) + { + fd_set ifds; + int len; + + FD_ZERO(&ifds); + FD_SET(fd_stdin, &ifds); + FD_SET(fd_master, &ifds); + + // Wait for data from stdin or the master side of PTY + if ( select(fd_master + 1, &ifds, 0, 0, 0) < 0 ) + break; + + // Data on standard input + if ( FD_ISSET(fd_stdin, &ifds) ) + { + len = read (fd_stdin, buffer, sizeof(buffer)); + + if ( len > 0 ) + write (fd_master, buffer, len); // Send data to the master side + } + + // Data on the master side of PTY + if ( FD_ISSET(fd_master, &ifds) ) + { + len = read (fd_master, buffer, sizeof(buffer)); + + if ( len < 0 ) + break; + else if ( len > 0 ) + parseTerminalBuffer (len, con); + } + } +} + +//---------------------------------------------------------------------- +void FTermDetectionTest::parseTerminalBuffer (int length, console con) +{ + for (int i = 0; i < length; i++) + { + if ( buffer[i] == ENQ[0] ) // Enquiry character + { + char* answer = getAnswerback(con); + + if ( answer ) + write(fd_master, answer, std::strlen(answer)); + } + else if ( i < length - 1 // Terminal ID (DECID) + && buffer[i] == '\033' + && buffer[i + 1] == 'Z' ) + { + char* DECID = getDECID(con); + + if ( DECID ) + write (fd_master, DECID, std::strlen(DECID)); + + i += 2; + } + else if ( i < length - 3 // Device status report (DSR) + && buffer[i] == '\033' + && buffer[i + 1] == '[' + && buffer[i + 2] == '5' + && buffer[i + 3] == 'n' ) + { + char* DSR = getDSR(con); + + if ( DSR ) + write (fd_master, DSR, std::strlen(DSR)); + + i += 4; + } + else if ( i < length - 3 // Report cursor position (CPR) + && buffer[i] == '\033' + && buffer[i + 1] == '[' + && buffer[i + 2] == '6' + && buffer[i + 3] == 'n' ) + { + write (fd_master, "\033[25;80R", 8); // row 25 ; column 80 + i += 4; + } + else if ( i < length - 2 // Device attributes (DA) + && buffer[i] == '\033' + && buffer[i + 1] == '[' + && buffer[i + 2] == 'c' ) + { + char* DA = getDA(con); + + if ( DA ) + write (fd_master, DA, std::strlen(DA)); + + i += 3; + } + else if ( i < length - 3 // Device attributes (DA1) + && buffer[i] == '\033' + && buffer[i + 1] == '[' + && buffer[i + 2] == '1' + && buffer[i + 3] == 'c' ) + { + char* DA1 = getDA1(con); + + if ( DA1 ) + write (fd_master, DA1, std::strlen(DA1)); + i += 4; + } + else if ( i < length - 3 // Secondary device attributes (SEC_DA) + && buffer[i] == '\033' + && buffer[i + 1] == '[' + && buffer[i + 2] == '>' + && buffer[i + 3] == 'c' ) + { + char* SEC_DA = getSEC_DA(con); + + if ( SEC_DA ) + write (fd_master, SEC_DA, std::strlen(SEC_DA)); + + i += 4; + } + else if ( i < length - 4 // Report xterm window's title + && buffer[i] == '\033' + && buffer[i + 1] == '[' + && buffer[i + 2] == '2' + && buffer[i + 3] == '1' + && buffer[i + 4] == 't' ) + { + if ( con == urxvt ) + write (fd_master, "\033]l", 3); + else if ( con == tera_term ) + write (fd_master, "\033]l\033\\", 5); + else if ( con == screen ) + write (fd_master, "\033]lbash\033\\", 9); + else if ( con != ansi + && con != rxvt + && con != mlterm + && con != kde_konsole + && con != kterm + && con != cygwin + && con != mintty + && con != linux_con + && con != freebsd_con + && con != netbsd_con + && con != openbsd_con + && con != sun_con + && con != tmux ) + write (fd_master, "\033]lTITLE\033\\", 10); + + i += 5; + } + else if ( i < length - 7 // Get xterm color name 0-9 + && buffer[i] == '\033' + && buffer[i + 1] == ']' + && buffer[i + 2] == '4' + && buffer[i + 3] == ';' + && buffer[i + 4] >= '0' && buffer[i + 4] <= '9' + && buffer[i + 5] == ';' + && buffer[i + 6] == '?' + && buffer[i + 7] == '\a' ) + { + if ( con != ansi + && con != rxvt + && con != kde_konsole + && con != kterm + && con != cygwin + && con != mintty + && con != linux_con + && con != freebsd_con + && con != netbsd_con + && con != openbsd_con + && con != sun_con + && con != screen + && con != tmux ) + { + int n = buffer[i + 4] - '0'; + write (fd_master, "\033]4;", 4); + write (fd_master, &buffer[i + 4], 1); + write (fd_master, ";rgb:", 5); + write (fd_master, colorname[n], 14); + write (fd_master, "\a", 1); + } + + i += 8; + } + else if ( i < length - 8 // Get xterm color name 0-9 + && buffer[i] == '\033' + && buffer[i + 1] == ']' + && buffer[i + 2] == '4' + && buffer[i + 3] == ';' + && buffer[i + 4] >= '0' && buffer[i + 4] <= '9' + && buffer[i + 5] >= '0' && buffer[i + 5] <= '9' + && buffer[i + 6] == ';' + && buffer[i + 7] == '?' + && buffer[i + 8] == '\a' ) + { + if ( con != ansi + && con != rxvt + && con != kde_konsole + && con != kterm + && con != cygwin + && con != mintty + && con != linux_con + && con != freebsd_con + && con != netbsd_con + && con != openbsd_con + && con != sun_con + && con != screen + && con != tmux ) + { + int n = (buffer[i + 4] - '0') * 10 + + (buffer[i + 5] - '0'); + write (fd_master, "\033]4;", 4); + write (fd_master, &buffer[i + 4], 1); + write (fd_master, &buffer[i + 5], 1); + write (fd_master, ";rgb:", 5); + write (fd_master, colorname[n], 14); + write (fd_master, "\a", 1); + } + + i += 9; + } + else if ( i < length - 9 // Get xterm color name 0-9 + && buffer[i] == '\033' + && buffer[i + 1] == ']' + && buffer[i + 2] == '4' + && buffer[i + 3] == ';' + && buffer[i + 4] >= '0' && buffer[i + 4] <= '9' + && buffer[i + 5] >= '0' && buffer[i + 5] <= '9' + && buffer[i + 6] >= '0' && buffer[i + 6] <= '9' + && buffer[i + 7] == ';' + && buffer[i + 8] == '?' + && buffer[i + 9] == '\a' ) + { + if ( con != ansi + && con != rxvt + && con != kde_konsole + && con != kterm + && con != cygwin + && con != mintty + && con != linux_con + && con != freebsd_con + && con != netbsd_con + && con != openbsd_con + && con != sun_con + && con != screen + && con != tmux ) + { + int n = (buffer[i + 4] - '0') * 100 + + (buffer[i + 5] - '0') * 10 + + (buffer[i + 6] - '0'); + + if ( n < 256 ) + { + write (fd_master, "\033]4;", 4); + write (fd_master, &buffer[i + 4], 1); + write (fd_master, &buffer[i + 5], 1); + write (fd_master, &buffer[i + 6], 1); + write (fd_master, ";rgb:", 5); + write (fd_master, colorname[n], 14); + write (fd_master, "\a", 1); + } + } + + i += 10; + } + else + { + write (fd_stdout, &buffer[i], 1); // Send data to stdout + } + } +} + + +// Put the test suite in the registry +CPPUNIT_TEST_SUITE_REGISTRATION (FTermDetectionTest); + +// The general unit test main part +#include diff --git a/src/test/main-test.inc b/src/test/main-test.inc index 84cd52a6..d2bb1122 100644 --- a/src/test/main-test.inc +++ b/src/test/main-test.inc @@ -19,7 +19,6 @@ int main (int, char**) CPPUNIT_NS::TestRunner testrunner; testrunner.addTest (CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest()); testrunner.run (testresult); - // Outputting results in compiler format CPPUNIT_NS::CompilerOutputter compileroutputter ( &collectedresults , std::cerr );