summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/fastcsi.c141
1 files changed, 36 insertions, 105 deletions
diff --git a/src/fastcsi.c b/src/fastcsi.c
index 6cae7a3..2e0f004 100644
--- a/src/fastcsi.c
+++ b/src/fastcsi.c
@@ -10,121 +10,52 @@
#include <string.h>
TERM_ALWAYS_INLINE
-static inline const char *parse_color_sequence(const char *p, const char *end, uint32_t *color)
+static inline const char *parse_byte_delim(const char *s, const char *end, char delim, uint32_t *val)
{
- const char *s = p + 5;
- uint32_t r, g, b;
-
- if (TERM_EXPECT(s >= end, 0)) return NULL;
- unsigned char c0 = (unsigned char)*s++;
- unsigned char d0 = (unsigned char)(c0 - '0');
- if (TERM_EXPECT(d0 > 9, 0)) return NULL;
- if (TERM_EXPECT(s >= end, 0)) return NULL;
- unsigned char c1 = (unsigned char)*s++;
- if (c1 == ';') {
- r = d0;
- } else {
- unsigned char d1 = (unsigned char)(c1 - '0');
- if (TERM_EXPECT(d1 > 9, 0)) return NULL;
- if (TERM_EXPECT(s >= end, 0)) return NULL;
- unsigned char c2 = (unsigned char)*s++;
- if (c2 == ';') {
- r = d0 * 10 + d1;
- } else {
- unsigned char d2 = (unsigned char)(c2 - '0');
- if (TERM_EXPECT(d2 > 9 || s >= end || *s++ != ';', 0)) return NULL;
- r = d0 * 100 + d1 * 10 + d2;
- if (TERM_EXPECT(r > 255, 0)) return NULL;
- }
+ if (s >= end) return NULL;
+ unsigned char d0 = (unsigned char)(*s++ - '0');
+ if (d0 > 9) return NULL;
+ if (s < end && *s == delim) {
+ *val = d0;
+ return s + 1;
}
-
- if (TERM_EXPECT(s >= end, 0)) return NULL;
- c0 = (unsigned char)*s++;
- d0 = (unsigned char)(c0 - '0');
- if (TERM_EXPECT(d0 > 9, 0)) return NULL;
- if (TERM_EXPECT(s >= end, 0)) return NULL;
- c1 = (unsigned char)*s++;
- if (c1 == ';') {
- g = d0;
- } else {
- unsigned char d1 = (unsigned char)(c1 - '0');
- if (TERM_EXPECT(d1 > 9, 0)) return NULL;
- if (TERM_EXPECT(s >= end, 0)) return NULL;
- unsigned char c2 = (unsigned char)*s++;
- if (c2 == ';') {
- g = d0 * 10 + d1;
- } else {
- unsigned char d2 = (unsigned char)(c2 - '0');
- if (TERM_EXPECT(d2 > 9 || s >= end || *s++ != ';', 0)) return NULL;
- g = d0 * 100 + d1 * 10 + d2;
- if (TERM_EXPECT(g > 255, 0)) return NULL;
- }
- }
-
- if (TERM_EXPECT(s >= end, 0)) return NULL;
- c0 = (unsigned char)*s++;
- d0 = (unsigned char)(c0 - '0');
- if (TERM_EXPECT(d0 > 9, 0)) return NULL;
- if (TERM_EXPECT(s >= end, 0)) return NULL;
- c1 = (unsigned char)*s++;
- if (c1 == 'm') {
- b = d0;
- } else {
- unsigned char d1 = (unsigned char)(c1 - '0');
- if (TERM_EXPECT(d1 > 9, 0)) return NULL;
- if (TERM_EXPECT(s >= end, 0)) return NULL;
- unsigned char c2 = (unsigned char)*s++;
- if (c2 == 'm') {
- b = d0 * 10 + d1;
- } else {
- unsigned char d2 = (unsigned char)(c2 - '0');
- if (TERM_EXPECT(d2 > 9 || s >= end || *s++ != 'm', 0)) return NULL;
- b = d0 * 100 + d1 * 10 + d2;
- if (TERM_EXPECT(b > 255, 0)) return NULL;
- }
+ if (s >= end) return NULL;
+ unsigned char d1 = (unsigned char)(*s++ - '0');
+ if (d1 > 9) return NULL;
+ if (s < end && *s == delim) {
+ *val = d0 * 10 + d1;
+ return s + 1;
}
+ if (s >= end) return NULL;
+ unsigned char d2 = (unsigned char)(*s++ - '0');
+ if (d2 > 9 || s >= end || *s++ != delim) return NULL;
+ unsigned v = d0 * 100 + d1 * 10 + d2;
+ if (v > 255) return NULL;
+ *val = v;
+ return s;
+}
+static inline const char *parse_color_sequence(const char *p, const char *end, uint32_t *color)
+{
+ const char *s = p + 5;
+ uint32_t r, g, b;
+ s = parse_byte_delim(s, end, ';', &r);
+ if (!s) return NULL;
+ s = parse_byte_delim(s, end, ';', &g);
+ if (!s) return NULL;
+ s = parse_byte_delim(s, end, 'm', &b);
+ if (!s) return NULL;
*color = term_rgb((int)r, (int)g, (int)b);
return s;
}
static const char *parse_256color(const char *p, const char *end, uint32_t *color)
{
- const char *q = p + 2;
- if (q >= end)
- return NULL;
- unsigned char d0 = (unsigned char)(*q - '0');
- if (d0 > 9)
- return NULL;
- q++;
- if (q < end && *q == 'm') {
- *color = term_color_index(d0);
- return q + 1;
- }
- if (q >= end)
- return NULL;
- unsigned char d1 = (unsigned char)(*q - '0');
- if (d1 > 9)
- return NULL;
- q++;
- if (q < end && *q == 'm') {
- *color = term_color_index(d0 * 10 + d1);
- return q + 1;
- }
- if (q >= end)
- return NULL;
- unsigned char d2 = (unsigned char)(*q - '0');
- if (d2 > 9)
- return NULL;
- q++;
- if (q < end && *q == 'm') {
- unsigned v = d0 * 100 + d1 * 10 + d2;
- if (v <= 255) {
- *color = term_color_index(v);
- return q + 1;
- }
- }
- return NULL;
+ uint32_t v;
+ const char *s = parse_byte_delim(p + 2, end, 'm', &v);
+ if (!s) return NULL;
+ *color = term_color_index(v);
+ return s;
}
TERM_NOINLINE