libwebsockets
Lightweight C library for HTML5 websockets
Toggle main menu visibility
Loading...
Searching...
No Matches
lws-hl.h
Go to the documentation of this file.
1
/*
2
* libwebsockets - small server side websockets and web server implementation
3
*
4
* Copyright (C) 2010 - 2026 Andy Green <andy@warmcat.com>
5
*
6
* Permission is hereby granted, free of charge, to any person obtaining a copy
7
* of this software and associated documentation files (the "Software"), to
8
* deal in the Software without restriction, including without limitation the
9
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10
* sell copies of the Software, and to permit persons to whom the Software is
11
* furnished to do so, subject to the following conditions:
12
*
13
* The above copyright notice and this permission notice shall be included in
14
* all copies or substantial portions of the Software.
15
*
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22
* IN THE SOFTWARE.
23
*
24
* Streaming syntax highlighting tokenizer
25
*
26
* Hostile-input-hardened, alloc-free, streaming tokenizer for producing
27
* syntax highlighting markup from arbitrary source text. Input is fed in
28
* fragments of any size (including 0 or 1 bytes); classified token pieces
29
* are passed to a caller token sink callback. A second layer provides a
30
* stock token sink that emits strict-CSP-compatible HTML markup (entity-
31
* escaped text wrapped in <span class=...>) through a caller write callback.
32
*
33
* The tokenizer never revises emitted decisions, never backtracks, and holds
34
* O(1) state regardless of input; unterminated constructs at end of input are
35
* closed out with a best-guess classification.
36
*/
37
38
#if !defined(__LWS_HL_H__)
39
#define __LWS_HL_H__
40
41
#if !defined(LHL_SCRATCH_SIZE)
42
#define LHL_SCRATCH_SIZE 40
43
#endif
44
#if !defined(LHL_PIECE_MAX)
45
#define LHL_PIECE_MAX 96
46
#endif
47
48
/* the scratch cursor is a byte, and pieces are bounded two units in */
49
#if LHL_SCRATCH_SIZE > 255 || LHL_PIECE_MAX < 8
50
#error "LHL_SCRATCH_SIZE must be <= 255 and LHL_PIECE_MAX >= 8"
51
#endif
52
54
typedef
enum
{
55
LHL_CLS_PLAIN
,
56
LHL_CLS_IDENT
,
57
LHL_CLS_KEYWORD
,
58
LHL_CLS_TYPE
,
59
LHL_CLS_NUMBER
,
60
LHL_CLS_STRING
,
61
LHL_CLS_CHARLIT
,
62
LHL_CLS_COMMENT
,
63
LHL_CLS_PREPROC
,
64
65
/* diff presentation (lines, including their newline) */
66
67
LHL_CLS_DIFF_ADD
,
68
LHL_CLS_DIFF_REM
,
69
LHL_CLS_DIFF_HUNK
,
70
LHL_CLS_DIFF_META
,
71
72
LHL_CLS_COUNT
73
}
lws_hl_class_t
;
74
75
struct
lws_hl_ctx
;
76
typedef
struct
lws_hl_ctx
lws_hl_ctx_t
;
77
98
typedef
lws_stateful_ret_t
(*
lws_hl_token_cb
)(
void
*
user
,
lws_hl_class_t
cls,
99
const
uint8_t
*
tok
,
size_t
len);
100
101
typedef
struct
lws_hl_ops
{
102
const
char
*
name
;
104
105
int (*
construct
)(
lws_hl_ctx_t
*ctx);
108
109
lws_stateful_ret_t
(*
parse
)(
lws_hl_ctx_t
*ctx,
110
const
uint8_t
**buf,
size_t
*len);
113
114
lws_stateful_ret_t
(*
finish
)(
lws_hl_ctx_t
*ctx);
117
}
lws_hl_ops_t
;
118
126
typedef
struct
lws_hl_ctx
{
127
const
lws_hl_ops_t
*
ops
;
128
lws_hl_token_cb
cb
;
129
void
*
user
;
130
131
/* private below */
132
133
const
uint8_t
*
chunk
;
/* current input chunk base */
134
size_t
pos
;
/* scan cursor (offset in chunk) */
135
size_t
tok
;
/* current token start offset */
136
size_t
epos
;
/* emitted watermark offset */
137
uint8_t
state
;
/* driver private */
138
uint8_t
scratch_pos
;
/* driver private */
139
uint8_t
flags
;
/* driver private */
140
uint8_t
tokcls
;
/* driver private */
141
uint8_t
scratch
[
LHL_SCRATCH_SIZE
];
142
}
lws_hl_ctx_t
;
143
156
LWS_VISIBLE
LWS_EXTERN
int
157
lws_hl_construct
(
lws_hl_ctx_t
*ctx,
const
lws_hl_ops_t
*lang,
158
lws_hl_token_cb
cb,
void
*user);
159
184
LWS_VISIBLE
LWS_EXTERN
lws_stateful_ret_t
185
lws_hl_parse
(
lws_hl_ctx_t
*ctx,
const
uint8_t
**buf,
size_t
*len);
186
203
LWS_VISIBLE
LWS_EXTERN
lws_stateful_ret_t
204
lws_hl_finish
(
lws_hl_ctx_t
*ctx);
205
206
#if defined(LWS_WITH_HL_LANG_C)
214
LWS_VISIBLE
LWS_EXTERN
const
lws_hl_ops_t
*
215
lws_hl_lang_c(
void
);
216
#endif
217
218
#if defined(LWS_WITH_HL_LANG_DIFF)
228
LWS_VISIBLE
LWS_EXTERN
const
lws_hl_ops_t
*
229
lws_hl_lang_diff(
void
);
230
#endif
231
232
/*
233
* One piece's markup is composed whole before it is written: a closing
234
* </span>, the opening <span class="..."> and the worst-case escape of
235
* LHL_PIECE_MAX bytes (8 each). Class names longer than about
236
* LHL_HTML_BUF - 800 bytes do not fit, and pieces of those classes are
237
* emitted escaped but unwrapped rather than refused.
238
*/
239
#if !defined(LHL_HTML_BUF)
240
#define LHL_HTML_BUF 1024
241
#endif
242
243
typedef
lws_stateful_ret_t
(*
lws_hl_write_cb
)(
void
*user,
const
uint8_t
*buf,
244
size_t
len);
245
256
typedef
struct
lws_hl_html
{
257
/* private */
258
lws_hl_write_cb
wc
;
259
void
*
user
;
260
const
char
*
const
*
cls
;
261
lws_hl_class_t
last
;
262
size_t
buflen
;
263
uint8_t
open
;
264
char
buf
[
LHL_HTML_BUF
];
265
}
lws_hl_html_t
;
266
284
LWS_VISIBLE
LWS_EXTERN
int
285
lws_hl_html_construct
(
lws_hl_html_t
*h,
lws_hl_write_cb
wc,
void
*user,
286
const
char
*
const
*cls);
287
303
LWS_VISIBLE
LWS_EXTERN
lws_stateful_ret_t
304
lws_hl_html_token
(
void
*user,
lws_hl_class_t
cls,
const
uint8_t
*tok,
305
size_t
len);
306
316
LWS_VISIBLE
LWS_EXTERN
lws_stateful_ret_t
317
lws_hl_html_close
(
lws_hl_html_t
*h);
318
337
LWS_VISIBLE
LWS_EXTERN
lws_stateful_ret_t
338
lws_html_escape
(
lws_hl_write_cb
wc,
void
*user,
const
uint8_t
*src,
339
size_t
len);
340
#endif
LWS_EXTERN
#define LWS_EXTERN
Definition
libwebsockets.h:327
uint8_t
unsigned char uint8_t
Definition
libwebsockets.h:746
lws_stateful_ret_t
lws_stateful_ret_t
Definition
libwebsockets.h:802
LWS_VISIBLE
#define LWS_VISIBLE
Definition
libwebsockets.h:322
lws_hl_ctx::user
void * user
Definition
lws-hl.h:129
lws_hl_construct
LWS_VISIBLE LWS_EXTERN int lws_hl_construct(lws_hl_ctx_t *ctx, const lws_hl_ops_t *lang, lws_hl_token_cb cb, void *user)
lws_hl_html::wc
lws_hl_write_cb wc
Definition
lws-hl.h:258
lws_hl_ctx::ops
const lws_hl_ops_t * ops
Definition
lws-hl.h:127
lws_hl_html_token
LWS_VISIBLE LWS_EXTERN lws_stateful_ret_t lws_hl_html_token(void *user, lws_hl_class_t cls, const uint8_t *tok, size_t len)
lws_hl_ctx::scratch
uint8_t scratch[LHL_SCRATCH_SIZE]
Definition
lws-hl.h:141
lws_hl_ctx::chunk
const uint8_t * chunk
Definition
lws-hl.h:133
lws_hl_ctx::pos
size_t pos
Definition
lws-hl.h:134
LHL_HTML_BUF
#define LHL_HTML_BUF
Definition
lws-hl.h:240
lws_hl_parse
LWS_VISIBLE LWS_EXTERN lws_stateful_ret_t lws_hl_parse(lws_hl_ctx_t *ctx, const uint8_t **buf, size_t *len)
lws_hl_html_close
LWS_VISIBLE LWS_EXTERN lws_stateful_ret_t lws_hl_html_close(lws_hl_html_t *h)
lws_hl_finish
LWS_VISIBLE LWS_EXTERN lws_stateful_ret_t lws_hl_finish(lws_hl_ctx_t *ctx)
lws_hl_html_t
struct lws_hl_html lws_hl_html_t
LHL_SCRATCH_SIZE
#define LHL_SCRATCH_SIZE
Definition
lws-hl.h:42
lws_hl_html::cls
const char *const * cls
Definition
lws-hl.h:260
lws_hl_html::buflen
size_t buflen
Definition
lws-hl.h:262
lws_hl_ctx::state
uint8_t state
Definition
lws-hl.h:137
lws_hl_ctx::epos
size_t epos
Definition
lws-hl.h:136
lws_hl_ctx::tok
size_t tok
Definition
lws-hl.h:135
lws_hl_ctx::cb
lws_hl_token_cb cb
Definition
lws-hl.h:128
lws_hl_html_construct
LWS_VISIBLE LWS_EXTERN int lws_hl_html_construct(lws_hl_html_t *h, lws_hl_write_cb wc, void *user, const char *const *cls)
lws_hl_ctx_t
struct lws_hl_ctx lws_hl_ctx_t
Definition
lws-hl.h:76
lws_hl_html::last
lws_hl_class_t last
Definition
lws-hl.h:261
lws_hl_html::open
uint8_t open
Definition
lws-hl.h:263
lws_hl_html::user
void * user
Definition
lws-hl.h:259
lws_hl_html::buf
char buf[LHL_HTML_BUF]
Definition
lws-hl.h:264
lws_hl_ctx::flags
uint8_t flags
Definition
lws-hl.h:139
lws_hl_class_t
lws_hl_class_t
Definition
lws-hl.h:54
LHL_CLS_PREPROC
@ LHL_CLS_PREPROC
Definition
lws-hl.h:63
LHL_CLS_IDENT
@ LHL_CLS_IDENT
Definition
lws-hl.h:56
LHL_CLS_STRING
@ LHL_CLS_STRING
Definition
lws-hl.h:60
LHL_CLS_PLAIN
@ LHL_CLS_PLAIN
Definition
lws-hl.h:55
LHL_CLS_COMMENT
@ LHL_CLS_COMMENT
Definition
lws-hl.h:62
LHL_CLS_DIFF_REM
@ LHL_CLS_DIFF_REM
Definition
lws-hl.h:68
LHL_CLS_CHARLIT
@ LHL_CLS_CHARLIT
Definition
lws-hl.h:61
LHL_CLS_COUNT
@ LHL_CLS_COUNT
Definition
lws-hl.h:72
LHL_CLS_KEYWORD
@ LHL_CLS_KEYWORD
Definition
lws-hl.h:57
LHL_CLS_NUMBER
@ LHL_CLS_NUMBER
Definition
lws-hl.h:59
LHL_CLS_TYPE
@ LHL_CLS_TYPE
Definition
lws-hl.h:58
LHL_CLS_DIFF_ADD
@ LHL_CLS_DIFF_ADD
Definition
lws-hl.h:67
LHL_CLS_DIFF_META
@ LHL_CLS_DIFF_META
Definition
lws-hl.h:70
LHL_CLS_DIFF_HUNK
@ LHL_CLS_DIFF_HUNK
Definition
lws-hl.h:69
lws_hl_write_cb
lws_stateful_ret_t(* lws_hl_write_cb)(void *user, const uint8_t *buf, size_t len)
Definition
lws-hl.h:243
lws_html_escape
LWS_VISIBLE LWS_EXTERN lws_stateful_ret_t lws_html_escape(lws_hl_write_cb wc, void *user, const uint8_t *src, size_t len)
lws_hl_ops_t
struct lws_hl_ops lws_hl_ops_t
lws_hl_ctx::scratch_pos
uint8_t scratch_pos
Definition
lws-hl.h:138
lws_hl_ctx::tokcls
uint8_t tokcls
Definition
lws-hl.h:140
lws_hl_token_cb
lws_stateful_ret_t(* lws_hl_token_cb)(void *user, lws_hl_class_t cls, const uint8_t *tok, size_t len)
Definition
lws-hl.h:98
lws_hl_ctx
Definition
lws-hl.h:126
lws_hl_html
Definition
lws-hl.h:256
lws_hl_ops
Definition
lws-hl.h:101
lws_hl_ops::parse
lws_stateful_ret_t(* parse)(lws_hl_ctx_t *ctx, const uint8_t **buf, size_t *len)
Definition
lws-hl.h:109
lws_hl_ops::finish
lws_stateful_ret_t(* finish)(lws_hl_ctx_t *ctx)
Definition
lws-hl.h:114
lws_hl_ops::name
const char * name
Definition
lws-hl.h:102
lws_hl_ops::construct
int(* construct)(lws_hl_ctx_t *ctx)
Definition
lws-hl.h:105
include
libwebsockets
lws-hl.h
Generated on
for libwebsockets by
1.19.0