termcap.cpp 3.4 KB

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