search.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #include <sys/types.h> // for freebsd
  2. #include <stdlib.h>
  3. #include "vt.h"
  4. #include "misc.h"
  5. #include "cache.h"
  6. #include "search.h"
  7. static void convert(u8 *p, u8 *buf, int *line)
  8. {
  9. int x, y, c, ch, gfx, hid = 0;
  10. for (y = 1, p += 40; y < 25; ++y)
  11. {
  12. if (not hid)
  13. {
  14. gfx = 0;
  15. for (x = 0; x < 40; ++x)
  16. {
  17. c = ' ';
  18. switch (ch = *p++)
  19. {
  20. case 0x00 ... 0x07:
  21. gfx = 0;
  22. break;
  23. case 0x10 ... 0x17:
  24. gfx = 1;
  25. break;
  26. case 0x0c:
  27. hid = 1;
  28. break;
  29. case 0x7f:
  30. c = '*';
  31. break;
  32. case 0x20 ... 0x7e:
  33. if (gfx && ch != ' ' && (ch & 0xa0) == 0x20)
  34. ch = '#';
  35. case 0xa0 ... 0xff:
  36. c= ch;
  37. }
  38. *buf++ = c;
  39. }
  40. *buf++ = '\n';
  41. *line++ = y;
  42. }
  43. else
  44. {
  45. p += 40;
  46. hid = 0;
  47. }
  48. }
  49. *line = y;
  50. *buf = 0;
  51. }
  52. static int search_pg(struct search *s, struct vt_page *vtp)
  53. {
  54. regmatch_t m[1];
  55. u8 buf[H *(W+1) + 1];
  56. int line[H];
  57. convert(PTR vtp->data, buf, line);
  58. if (regexec(s->pattern, buf, 1, m, 0) == 0)
  59. {
  60. s->len = 0;
  61. if (m->rm_so >= 0)
  62. {
  63. s->y = line[m->rm_so / (W+1)];
  64. s->x = m->rm_so % (W+1);
  65. s->len = m->rm_eo - m->rm_so;
  66. if (s->x + s->len > 40)
  67. s->len = 40 - s->x;
  68. }
  69. return 1;
  70. }
  71. return 0;
  72. }
  73. struct search * search_start(struct cache *ca, u8 *pattern)
  74. {
  75. struct search *s;
  76. int f = 0;
  77. if (not(s = malloc(sizeof(*s))))
  78. goto fail1;
  79. if (pattern[0] == '!')
  80. pattern++;
  81. else
  82. f = REG_ICASE;
  83. if (regcomp(s->pattern, pattern, f | REG_NEWLINE) != 0)
  84. goto fail2;
  85. s->cache = ca;
  86. return s;
  87. fail2:
  88. free(s);
  89. fail1:
  90. return 0;
  91. }
  92. void search_end(struct search *s)
  93. {
  94. regfree(s->pattern);
  95. free(s);
  96. }
  97. int search_next(struct search *s, int *pgno, int *subno, int dir)
  98. {
  99. struct vt_page *vtp = 0;
  100. if (s->cache)
  101. vtp = s->cache->op->foreach_pg(s->cache, *pgno, *subno, dir,
  102. search_pg, s);
  103. if (vtp == 0)
  104. return -1;
  105. *pgno = vtp->pgno;
  106. *subno = vtp->subno ?: ANY_SUB;
  107. return 0;
  108. }