13
13
#include "scanners.h"
14
14
#include "inlines.h"
15
15
#include "syntax_extension.h"
16
- #include "mutex.h"
17
16
18
17
static const char * EMDASH = "\xE2\x80\x94" ;
19
18
static const char * ENDASH = "\xE2\x80\x93" ;
@@ -64,10 +63,14 @@ typedef struct subject{
64
63
bool scanned_for_backticks ;
65
64
} subject ;
66
65
67
- // Extensions may populate this.
68
- static int8_t SKIP_CHARS [256 ];
66
+ void cmark_set_default_skip_chars ( int8_t * * skip_chars , bool use_memcpy ) {
67
+ static int8_t default_skip_chars [256 ];
69
68
70
- CMARK_DEFINE_LOCK (chars );
69
+ if (use_memcpy )
70
+ memcpy (* skip_chars , & default_skip_chars , 256 );
71
+ else
72
+ * skip_chars = default_skip_chars ;
73
+ }
71
74
72
75
static CMARK_INLINE bool S_is_line_end_char (char c ) {
73
76
return (c == '\n' || c == '\r' );
@@ -80,7 +83,7 @@ static int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent,
80
83
81
84
static void subject_from_buf (cmark_mem * mem , int line_number , int block_offset , subject * e ,
82
85
cmark_chunk * buffer , cmark_map * refmap );
83
- static bufsize_t subject_find_special_char (subject * subj , int options );
86
+ static bufsize_t subject_find_special_char (cmark_parser * parser , subject * subj , int options );
84
87
85
88
// Create an inline with a literal string value.
86
89
static CMARK_INLINE cmark_node * make_literal (subject * subj , cmark_node_type t ,
@@ -394,8 +397,8 @@ static cmark_node *handle_backticks(subject *subj, int options) {
394
397
395
398
// Scan ***, **, or * and return number scanned, or 0.
396
399
// Advances position.
397
- static int scan_delims (subject * subj , unsigned char c , bool * can_open ,
398
- bool * can_close ) {
400
+ static int scan_delims (cmark_parser * parser , subject * subj , unsigned char c ,
401
+ bool * can_open , bool * can_close ) {
399
402
int numdelims = 0 ;
400
403
bufsize_t before_char_pos , after_char_pos ;
401
404
int32_t after_char = 0 ;
@@ -408,19 +411,15 @@ static int scan_delims(subject *subj, unsigned char c, bool *can_open,
408
411
} else {
409
412
before_char_pos = subj -> pos - 1 ;
410
413
411
- CMARK_INITIALIZE_AND_LOCK (chars );
412
-
413
414
// walk back to the beginning of the UTF_8 sequence:
414
- while ((peek_at (subj , before_char_pos ) >> 6 == 2 || SKIP_CHARS [peek_at (subj , before_char_pos )]) && before_char_pos > 0 ) {
415
+ while ((peek_at (subj , before_char_pos ) >> 6 == 2 || parser -> skip_chars [peek_at (subj , before_char_pos )]) && before_char_pos > 0 ) {
415
416
before_char_pos -= 1 ;
416
417
}
417
418
len = cmark_utf8proc_iterate (subj -> input .data + before_char_pos ,
418
419
subj -> pos - before_char_pos , & before_char );
419
- if (len == -1 || (before_char < 256 && SKIP_CHARS [(unsigned char ) before_char ])) {
420
+ if (len == -1 || (before_char < 256 && parser -> skip_chars [(unsigned char ) before_char ])) {
420
421
before_char = 10 ;
421
422
}
422
-
423
- CMARK_UNLOCK (chars );
424
423
}
425
424
426
425
if (c == '\'' || c == '"' ) {
@@ -438,18 +437,14 @@ static int scan_delims(subject *subj, unsigned char c, bool *can_open,
438
437
} else {
439
438
after_char_pos = subj -> pos ;
440
439
441
- CMARK_INITIALIZE_AND_LOCK (chars );
442
-
443
- while (SKIP_CHARS [peek_at (subj , after_char_pos )] && after_char_pos < subj -> input .len ) {
440
+ while (parser -> skip_chars [peek_at (subj , after_char_pos )] && after_char_pos < subj -> input .len ) {
444
441
after_char_pos += 1 ;
445
442
}
446
443
len = cmark_utf8proc_iterate (subj -> input .data + after_char_pos ,
447
444
subj -> input .len - after_char_pos , & after_char );
448
- if (len == -1 || (after_char < 256 && SKIP_CHARS [(unsigned char ) after_char ])) {
445
+ if (len == -1 || (after_char < 256 && parser -> skip_chars [(unsigned char ) after_char ])) {
449
446
after_char = 10 ;
450
447
}
451
-
452
- CMARK_UNLOCK (chars );
453
448
}
454
449
455
450
left_flanking = numdelims > 0 && !cmark_utf8proc_is_space (after_char ) &&
@@ -548,13 +543,13 @@ static void push_bracket(subject *subj, bracket_type type, cmark_node *inl_text)
548
543
}
549
544
550
545
// Assumes the subject has a c at the current position.
551
- static cmark_node * handle_delim (subject * subj , unsigned char c , bool smart ) {
546
+ static cmark_node * handle_delim (cmark_parser * parser , subject * subj , unsigned char c , bool smart ) {
552
547
bufsize_t numdelims ;
553
548
cmark_node * inl_text ;
554
549
bool can_open , can_close ;
555
550
cmark_chunk contents ;
556
551
557
- numdelims = scan_delims (subj , c , & can_open , & can_close );
552
+ numdelims = scan_delims (parser , subj , c , & can_open , & can_close );
558
553
559
554
if (c == '\'' && smart ) {
560
555
contents = cmark_chunk_literal (RIGHTSINGLEQUOTE );
@@ -1346,18 +1341,25 @@ static cmark_node *handle_newline(subject *subj) {
1346
1341
}
1347
1342
1348
1343
// "\r\n\\`&_*[]<!"
1349
- static int8_t SPECIAL_CHARS [256 ] = {
1350
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1351
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 ,
1352
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1353
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 ,
1354
- 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1355
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1356
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1357
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1358
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1359
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1360
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
1344
+ void cmark_set_default_special_chars (int8_t * * special_chars , bool use_memcpy ) {
1345
+ static int8_t default_special_chars [256 ] = {
1346
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1347
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 ,
1348
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1349
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 ,
1350
+ 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1351
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1352
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1353
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1354
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1355
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1356
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
1357
+
1358
+ if (use_memcpy )
1359
+ memcpy (* special_chars , & default_special_chars , 256 );
1360
+ else
1361
+ * special_chars = default_special_chars ;
1362
+ }
1361
1363
1362
1364
// " ' . -
1363
1365
static const char SMART_PUNCT_CHARS [] = {
@@ -1374,41 +1376,30 @@ static const char SMART_PUNCT_CHARS[] = {
1374
1376
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1375
1377
};
1376
1378
1377
- static bufsize_t subject_find_special_char (subject * subj , int options ) {
1379
+ static bufsize_t subject_find_special_char (cmark_parser * parser , subject * subj , int options ) {
1378
1380
bufsize_t n = subj -> pos + 1 ;
1379
- bufsize_t ret = subj -> input .len ;
1380
1381
1381
- CMARK_INITIALIZE_AND_LOCK (chars );
1382
1382
while (n < subj -> input .len ) {
1383
- if (SPECIAL_CHARS [subj -> input .data [n ]]) {
1384
- ret = n ;
1385
- break ;
1386
- }
1387
- if (options & CMARK_OPT_SMART && SMART_PUNCT_CHARS [subj -> input .data [n ]]) {
1388
- ret = n ;
1389
- break ;
1390
- }
1383
+ if (parser -> special_chars [subj -> input .data [n ]])
1384
+ return n ;
1385
+ if (options & CMARK_OPT_SMART && SMART_PUNCT_CHARS [subj -> input .data [n ]])
1386
+ return n ;
1391
1387
n ++ ;
1392
1388
}
1393
- CMARK_UNLOCK (chars );
1394
1389
1395
- return ret ;
1390
+ return subj -> input . len ;
1396
1391
}
1397
1392
1398
- void cmark_inlines_add_special_character (unsigned char c , bool emphasis ) {
1399
- CMARK_INITIALIZE_AND_LOCK (chars );
1400
- SPECIAL_CHARS [c ] = 1 ;
1393
+ void cmark_inlines_add_special_character (cmark_parser * parser , unsigned char c , bool emphasis ) {
1394
+ parser -> special_chars [c ] = 1 ;
1401
1395
if (emphasis )
1402
- SKIP_CHARS [c ] = 1 ;
1403
- CMARK_UNLOCK (chars );
1396
+ parser -> skip_chars [c ] = 1 ;
1404
1397
}
1405
1398
1406
- void cmark_inlines_remove_special_character (unsigned char c , bool emphasis ) {
1407
- CMARK_INITIALIZE_AND_LOCK (chars );
1408
- SPECIAL_CHARS [c ] = 0 ;
1399
+ void cmark_inlines_remove_special_character (cmark_parser * parser , unsigned char c , bool emphasis ) {
1400
+ parser -> special_chars [c ] = 0 ;
1409
1401
if (emphasis )
1410
- SKIP_CHARS [c ] = 0 ;
1411
- CMARK_UNLOCK (chars );
1402
+ parser -> skip_chars [c ] = 0 ;
1412
1403
}
1413
1404
1414
1405
static cmark_node * try_extensions (cmark_parser * parser ,
@@ -1466,7 +1457,7 @@ static int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent,
1466
1457
case '_' :
1467
1458
case '\'' :
1468
1459
case '"' :
1469
- new_inl = handle_delim (subj , c , (options & CMARK_OPT_SMART ) != 0 );
1460
+ new_inl = handle_delim (parser , subj , c , (options & CMARK_OPT_SMART ) != 0 );
1470
1461
break ;
1471
1462
case '-' :
1472
1463
new_inl = handle_hyphen (subj , (options & CMARK_OPT_SMART ) != 0 );
@@ -1508,7 +1499,7 @@ static int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent,
1508
1499
if (new_inl != NULL )
1509
1500
break ;
1510
1501
1511
- endpos = subject_find_special_char (subj , options );
1502
+ endpos = subject_find_special_char (parser , subj , options );
1512
1503
contents = cmark_chunk_dup (& subj -> input , subj -> pos , endpos - subj -> pos );
1513
1504
startpos = subj -> pos ;
1514
1505
subj -> pos = endpos ;
0 commit comments