Initial CST-Agent: portable Linux/Termux/Windows coding agent.
Vendored sashidown, OpenAI-compatible env (OPENAI_*), and bootstrap scripts. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Vendored
+196
@@ -0,0 +1,196 @@
|
||||
#ifndef SASHIDOWN_BLOCK_SCAN_H
|
||||
#define SASHIDOWN_BLOCK_SCAN_H
|
||||
|
||||
#include "sashidown.h"
|
||||
#include "render.h"
|
||||
#include "fsm.h"
|
||||
#include "line_index.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __SSE2__
|
||||
#include <emmintrin.h>
|
||||
#elif defined(__ARM_NEON) || defined(__aarch64__)
|
||||
#include <arm_neon.h>
|
||||
#endif
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Woverride-init"
|
||||
static inline size_t block_utf8_seq_len(unsigned char ch)
|
||||
{
|
||||
static const unsigned char tbl[256] = {
|
||||
[0x00 ... 0xFF] = 1,
|
||||
[0xC0 ... 0xDF] = 2,
|
||||
[0xE0 ... 0xEF] = 3,
|
||||
[0xF0 ... 0xF7] = 4,
|
||||
};
|
||||
return tbl[ch];
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
static inline size_t block_scan_plain_ascii(const char *restrict input, size_t end, size_t i)
|
||||
{
|
||||
#ifdef __SSE2__
|
||||
const __m128i m_star = _mm_set1_epi8('*');
|
||||
const __m128i m_us = _mm_set1_epi8('_');
|
||||
const __m128i m_tick = _mm_set1_epi8('`');
|
||||
const __m128i m_dol = _mm_set1_epi8('$');
|
||||
const __m128i m_bang = _mm_set1_epi8('!');
|
||||
const __m128i m_lb = _mm_set1_epi8('[');
|
||||
const __m128i m_amp = _mm_set1_epi8('&');
|
||||
const __m128i m_lt = _mm_set1_epi8('<');
|
||||
const __m128i m_gt = _mm_set1_epi8('>');
|
||||
const __m128i m_bs = _mm_set1_epi8('\\');
|
||||
const __m128i m_tilde = _mm_set1_epi8('~');
|
||||
while (i + 16 <= end) {
|
||||
__m128i v = _mm_loadu_si128((const __m128i *)(input + i));
|
||||
if (_mm_movemask_epi8(v))
|
||||
break; /* high bit => UTF-8 */
|
||||
__m128i hit = _mm_cmpeq_epi8(v, m_star);
|
||||
hit = _mm_or_si128(hit, _mm_cmpeq_epi8(v, m_us));
|
||||
hit = _mm_or_si128(hit, _mm_cmpeq_epi8(v, m_tick));
|
||||
hit = _mm_or_si128(hit, _mm_cmpeq_epi8(v, m_dol));
|
||||
hit = _mm_or_si128(hit, _mm_cmpeq_epi8(v, m_bang));
|
||||
hit = _mm_or_si128(hit, _mm_cmpeq_epi8(v, m_lb));
|
||||
hit = _mm_or_si128(hit, _mm_cmpeq_epi8(v, m_amp));
|
||||
hit = _mm_or_si128(hit, _mm_cmpeq_epi8(v, m_lt));
|
||||
hit = _mm_or_si128(hit, _mm_cmpeq_epi8(v, m_gt));
|
||||
hit = _mm_or_si128(hit, _mm_cmpeq_epi8(v, m_bs));
|
||||
hit = _mm_or_si128(hit, _mm_cmpeq_epi8(v, m_tilde));
|
||||
int mask = _mm_movemask_epi8(hit);
|
||||
if (mask)
|
||||
return i + (unsigned)__builtin_ctz(mask);
|
||||
i += 16;
|
||||
}
|
||||
#elif defined(__ARM_NEON) || defined(__aarch64__)
|
||||
while (i + 16 <= end) {
|
||||
uint8x16_t v = vld1q_u8((const uint8_t *)(input + i));
|
||||
if (vmaxvq_u8(vandq_u8(v, vdupq_n_u8(0x80))))
|
||||
break;
|
||||
uint8x16_t hit = vceqq_u8(v, vdupq_n_u8('*'));
|
||||
hit = vorrq_u8(hit, vceqq_u8(v, vdupq_n_u8('_')));
|
||||
hit = vorrq_u8(hit, vceqq_u8(v, vdupq_n_u8('`')));
|
||||
hit = vorrq_u8(hit, vceqq_u8(v, vdupq_n_u8('$')));
|
||||
hit = vorrq_u8(hit, vceqq_u8(v, vdupq_n_u8('!')));
|
||||
hit = vorrq_u8(hit, vceqq_u8(v, vdupq_n_u8('[')));
|
||||
hit = vorrq_u8(hit, vceqq_u8(v, vdupq_n_u8('&')));
|
||||
hit = vorrq_u8(hit, vceqq_u8(v, vdupq_n_u8('<')));
|
||||
hit = vorrq_u8(hit, vceqq_u8(v, vdupq_n_u8('>')));
|
||||
hit = vorrq_u8(hit, vceqq_u8(v, vdupq_n_u8('\\')));
|
||||
hit = vorrq_u8(hit, vceqq_u8(v, vdupq_n_u8('~')));
|
||||
if (vmaxvq_u8(hit)) {
|
||||
uint8_t lanes[16];
|
||||
vst1q_u8(lanes, hit);
|
||||
size_t pos = 0;
|
||||
while (pos < 16 && !lanes[pos]) pos++;
|
||||
return i + pos;
|
||||
}
|
||||
i += 16;
|
||||
}
|
||||
#endif
|
||||
size_t j = i;
|
||||
while (j + 4 <= end) {
|
||||
uint32_t v;
|
||||
memcpy(&v, input + j, 4);
|
||||
if (v & 0x80808080)
|
||||
break;
|
||||
if (CH_SCAN_STOP[(v & 0xFF)] ||
|
||||
CH_SCAN_STOP[(v >> 8) & 0xFF] ||
|
||||
CH_SCAN_STOP[(v >> 16) & 0xFF] ||
|
||||
CH_SCAN_STOP[(v >> 24) & 0xFF])
|
||||
break;
|
||||
j += 4;
|
||||
}
|
||||
while (j < end) {
|
||||
unsigned char c = (unsigned char)input[j];
|
||||
if ((c & 0x80))
|
||||
break;
|
||||
if (unlikely(CH_SCAN_STOP[c]))
|
||||
break;
|
||||
j++;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
static inline size_t block_scan_utf8_run(const char *input, size_t end, size_t i)
|
||||
{
|
||||
size_t j = i;
|
||||
while (j < end) {
|
||||
unsigned char c = (unsigned char)input[j];
|
||||
if (likely((c & 0x80) == 0))
|
||||
break;
|
||||
size_t seq = block_utf8_seq_len(c);
|
||||
if (j + seq > end)
|
||||
break;
|
||||
j += seq;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
static inline size_t block_scan_until_byte(const char *input, size_t end, size_t i, char delim)
|
||||
{
|
||||
if (i >= end)
|
||||
return i;
|
||||
const char *hit = memchr(input + i, delim, end - i);
|
||||
return hit ? (size_t)(hit - input) : end;
|
||||
}
|
||||
|
||||
static inline size_t block_scan_until_2byte(const char *input, size_t end, size_t start,
|
||||
char c1, char c2)
|
||||
{
|
||||
size_t i = start;
|
||||
while (i + 1 < end) {
|
||||
const char *hit = memchr(input + i, c1, end - i);
|
||||
if (!hit) return end;
|
||||
i = (size_t)(hit - input);
|
||||
if (i + 1 < end && input[i + 1] == c2)
|
||||
return i;
|
||||
i++;
|
||||
}
|
||||
return end;
|
||||
}
|
||||
|
||||
static inline size_t block_line_end(sashidown_ctx_t *ctx, const char *input, size_t len, size_t pos)
|
||||
{
|
||||
return line_end_ix((line_index_t *)ctx->line_ix, input, len, pos);
|
||||
}
|
||||
|
||||
static inline size_t block_skip_line(sashidown_ctx_t *ctx, const char *input, size_t len, size_t pos)
|
||||
{
|
||||
return skip_line_ix((line_index_t *)ctx->line_ix, input, len, pos);
|
||||
}
|
||||
|
||||
static inline void block_line_seek(sashidown_ctx_t *ctx, size_t pos)
|
||||
{
|
||||
line_index_seek((line_index_t *)ctx->line_ix, pos);
|
||||
}
|
||||
|
||||
int block_count_heading(const char *input, size_t len, size_t pos, size_t *content_start);
|
||||
int block_is_fence(const char *input, size_t len, size_t pos,
|
||||
int *fence_len, char *fence_char);
|
||||
void block_fence_info_range(const char *input, size_t len, size_t pos,
|
||||
int fence_len, char fence_char,
|
||||
size_t *info_start, size_t *info_end);
|
||||
int block_is_thematic_break(const char *input, size_t pos, size_t le);
|
||||
int block_is_setext_underline(const char *input, size_t pos, size_t le, int *level);
|
||||
int block_is_blockquote(const char *input, size_t len, size_t pos, size_t *content_start);
|
||||
int block_is_ul(const char *input, size_t len, size_t pos, size_t *content_start);
|
||||
int block_is_ol(const char *input, size_t len, size_t pos, size_t *content_start, int *num);
|
||||
int block_parse_task_marker(const char *input, size_t len, size_t content_start,
|
||||
int *task, size_t *text_start);
|
||||
int block_line_starts_table(const char *input, size_t len, size_t pos);
|
||||
int block_is_latex_line(sashidown_ctx_t *ctx, const char *input, size_t len,
|
||||
size_t pos, size_t *content_start, size_t *content_end);
|
||||
|
||||
/* Peek next-line setext underline. Does NOT advance line_index on failure.
|
||||
* `le` must be block_line_end(pos). Caller should only invoke for LK_PARA lines.
|
||||
* Returns 1 = heading, 0 = no, -1 = defer (need next line). */
|
||||
int block_try_setext(sashidown_ctx_t *ctx, const char *input, size_t len,
|
||||
size_t pos, size_t le, size_t stop, int is_final,
|
||||
line_info_t *info, size_t *end_pos);
|
||||
|
||||
line_info_t block_classify_line(sashidown_ctx_t *ctx, const char *input, size_t len,
|
||||
size_t pos, size_t le);
|
||||
|
||||
#endif /* SASHIDOWN_BLOCK_SCAN_H */
|
||||
Reference in New Issue
Block a user