main
ansi.c
1#include "in_all.h"
2#include "ansi.h"
3
4static int
5consume_csi(const char *s, const char **next, enum ansi_kind *kind)
6{
7 const unsigned char *p = (const unsigned char *)s + 2;
8
9 while (*p >= 0x30 && *p <= 0x3f) {
10 p++;
11 }
12 while (*p >= 0x20 && *p <= 0x2f) {
13 p++;
14 }
15 if (*p >= 0x40 && *p <= 0x7e) {
16 *kind = (*p == 'm') ? ANSI_SGR : ANSI_DISCARD;
17 *next = (const char *)p + 1;
18 return 1;
19 }
20 return 0;
21}
22
23static int
24consume_string(const char *s, const char **next)
25{
26 const unsigned char *p = (const unsigned char *)s + 2;
27
28 while (*p) {
29 if (*p == '\a') {
30 *next = (const char *)p + 1;
31 return 1;
32 }
33 if (*p == '\x1b' && p[1] == '\\') {
34 *next = (const char *)p + 2;
35 return 1;
36 }
37 p++;
38 }
39 return 0;
40}
41
42static int
43consume_esc(const char *s, const char **next)
44{
45 const unsigned char *p = (const unsigned char *)s + 1;
46
47 while (*p >= 0x20 && *p <= 0x2f) {
48 p++;
49 }
50 if (*p >= 0x30 && *p <= 0x7e) {
51 *next = (const char *)p + 1;
52 return 1;
53 }
54 return 0;
55}
56
57int
58ansi_escape(const char *s, const char **next, enum ansi_kind *kind)
59{
60 *kind = ANSI_NONE;
61 *next = s;
62 if ((unsigned char)s[0] != 0x1b || s[1] == '\0') {
63 return 0;
64 }
65 if (s[1] == '[') {
66 return consume_csi(s, next, kind);
67 }
68 if (s[1] == ']' || s[1] == 'P' || s[1] == 'X' || s[1] == '^' ||
69 s[1] == '_') {
70 *kind = ANSI_DISCARD;
71 return consume_string(s, next);
72 }
73 *kind = ANSI_DISCARD;
74 return consume_esc(s, next);
75}