|
@ -22,6 +22,10 @@ static inline int is_whitespace(char c) { |
|
|
return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; |
|
|
return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static inline int is_boundary(char c) { |
|
|
|
|
|
return !isalnum(c); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
static void make_cursor(struct cursor *c, const u8 *content, size_t len) |
|
|
static void make_cursor(struct cursor *c, const u8 *content, size_t len) |
|
|
{ |
|
|
{ |
|
|
c->start = content; |
|
|
c->start = content; |
|
@ -29,6 +33,21 @@ static void make_cursor(struct cursor *c, const u8 *content, size_t len) |
|
|
c->p = content; |
|
|
c->p = content; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int consume_until_boundary(struct cursor *cur) { |
|
|
|
|
|
char c; |
|
|
|
|
|
|
|
|
|
|
|
while (cur->p < cur->end) { |
|
|
|
|
|
c = *cur->p; |
|
|
|
|
|
|
|
|
|
|
|
if (is_boundary(c)) |
|
|
|
|
|
return 1; |
|
|
|
|
|
|
|
|
|
|
|
cur->p++; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
static int consume_until_whitespace(struct cursor *cur, int or_end) { |
|
|
static int consume_until_whitespace(struct cursor *cur, int or_end) { |
|
|
char c; |
|
|
char c; |
|
|
bool consumedAtLeastOne = false; |
|
|
bool consumedAtLeastOne = false; |
|
@ -147,7 +166,7 @@ static int parse_hashtag(struct cursor *cur, struct block *block) { |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
consume_until_whitespace(cur, 1); |
|
|
consume_until_boundary(cur); |
|
|
|
|
|
|
|
|
block->type = BLOCK_HASHTAG; |
|
|
block->type = BLOCK_HASHTAG; |
|
|
block->block.str.start = (const char*)(start + 1); |
|
|
block->block.str.start = (const char*)(start + 1); |
|
|