termcap.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/Debug.h>
  7. #include <AK/DeprecatedString.h>
  8. #include <AK/HashMap.h>
  9. #include <AK/Vector.h>
  10. #include <assert.h>
  11. #include <string.h>
  12. #include <termcap.h>
  13. extern "C" {
  14. char PC;
  15. char* UP;
  16. char* BC;
  17. int __attribute__((weak)) tgetent([[maybe_unused]] char* bp, [[maybe_unused]] char const* name)
  18. {
  19. warnln_if(TERMCAP_DEBUG, "tgetent: bp={:p}, name='{}'", bp, name);
  20. PC = '\0';
  21. BC = const_cast<char*>("\033[D");
  22. UP = const_cast<char*>("\033[A");
  23. return 1;
  24. }
  25. static HashMap<DeprecatedString, char const*>* caps = nullptr;
  26. static void ensure_caps()
  27. {
  28. if (caps)
  29. return;
  30. caps = new HashMap<DeprecatedString, char const*>;
  31. caps->set("DC", "\033[%p1%dP");
  32. caps->set("IC", "\033[%p1%d@");
  33. caps->set("ce", "\033[K");
  34. caps->set("cl", "\033[H\033[J");
  35. caps->set("cr", "\015");
  36. caps->set("dc", "\033[P");
  37. caps->set("ei", "");
  38. caps->set("ic", "");
  39. caps->set("im", "");
  40. caps->set("kd", "\033[B");
  41. caps->set("kl", "\033[D");
  42. caps->set("kr", "\033[C");
  43. caps->set("ku", "\033[A");
  44. caps->set("ks", "");
  45. caps->set("ke", "");
  46. caps->set("le", "\033[D");
  47. caps->set("mm", "");
  48. caps->set("mo", "");
  49. caps->set("pc", "");
  50. caps->set("up", "\033[A");
  51. caps->set("vb", "");
  52. caps->set("am", "");
  53. caps->set("@7", "");
  54. caps->set("kH", "");
  55. caps->set("kI", "\033[L");
  56. caps->set("kh", "\033[H");
  57. caps->set("vs", "");
  58. caps->set("ve", "");
  59. caps->set("E3", "");
  60. caps->set("kD", "");
  61. caps->set("nd", "\033[C");
  62. caps->set("co", "80");
  63. caps->set("li", "25");
  64. }
  65. // Unfortunately, tgetstr() doesn't accept a size argument for the buffer
  66. // pointed to by area, so we have to use bare strcpy().
  67. #pragma GCC diagnostic push
  68. #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  69. char* __attribute__((weak)) tgetstr(char const* id, char** area)
  70. {
  71. ensure_caps();
  72. warnln_if(TERMCAP_DEBUG, "tgetstr: id='{}'", id);
  73. auto it = caps->find(id);
  74. if (it != caps->end()) {
  75. char* ret = *area;
  76. char const* val = (*it).value;
  77. strcpy(*area, val);
  78. *area += strlen(val) + 1;
  79. return ret;
  80. }
  81. warnln_if(TERMCAP_DEBUG, "tgetstr: missing cap id='{}'", id);
  82. return nullptr;
  83. }
  84. #pragma GCC diagnostic pop
  85. int __attribute__((weak)) tgetflag([[maybe_unused]] char const* id)
  86. {
  87. warnln_if(TERMCAP_DEBUG, "tgetflag: '{}'", id);
  88. auto it = caps->find(id);
  89. if (it != caps->end())
  90. return 1;
  91. return 0;
  92. }
  93. int __attribute__((weak)) tgetnum(char const* id)
  94. {
  95. warnln_if(TERMCAP_DEBUG, "tgetnum: '{}'", id);
  96. auto it = caps->find(id);
  97. if (it != caps->end())
  98. return atoi((*it).value);
  99. return -1;
  100. }
  101. static Vector<char> s_tgoto_buffer;
  102. char* __attribute__((weak)) tgoto([[maybe_unused]] char const* cap, [[maybe_unused]] int col, [[maybe_unused]] int row)
  103. {
  104. auto cap_str = StringView { cap, strlen(cap) }.replace("%p1%d"sv, DeprecatedString::number(col), ReplaceMode::FirstOnly).replace("%p2%d"sv, DeprecatedString::number(row), ReplaceMode::FirstOnly);
  105. s_tgoto_buffer.clear_with_capacity();
  106. s_tgoto_buffer.ensure_capacity(cap_str.length());
  107. (void)cap_str.copy_characters_to_buffer(s_tgoto_buffer.data(), cap_str.length());
  108. return s_tgoto_buffer.data();
  109. }
  110. int __attribute__((weak)) tputs(char const* str, [[maybe_unused]] int affcnt, int (*putc)(int))
  111. {
  112. size_t len = strlen(str);
  113. for (size_t i = 0; i < len; ++i)
  114. putc(str[i]);
  115. return 0;
  116. }
  117. }