1313#include "scanners.h"
1414#include "inlines.h"
1515#include "syntax_extension.h"
16- #include "mutex.h"
1716
1817static const char * EMDASH = "\xE2\x80\x94" ;
1918static const char * ENDASH = "\xE2\x80\x93" ;
@@ -64,10 +63,14 @@ typedef struct subject{
6463 bool scanned_for_backticks ;
6564} subject ;
6665
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 ];
6968
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+ }
7174
7275static CMARK_INLINE bool S_is_line_end_char (char c ) {
7376 return (c == '\n' || c == '\r' );
@@ -80,7 +83,7 @@ static int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent,
8083
8184static void subject_from_buf (cmark_mem * mem , int line_number , int block_offset , subject * e ,
8285 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 );
8487
8588// Create an inline with a literal string value.
8689static 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) {
394397
395398// Scan ***, **, or * and return number scanned, or 0.
396399// 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 ) {
399402 int numdelims = 0 ;
400403 bufsize_t before_char_pos , after_char_pos ;
401404 int32_t after_char = 0 ;
@@ -408,19 +411,15 @@ static int scan_delims(subject *subj, unsigned char c, bool *can_open,
408411 } else {
409412 before_char_pos = subj -> pos - 1 ;
410413
411- CMARK_INITIALIZE_AND_LOCK (chars );
412-
413414 // 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 ) {
415416 before_char_pos -= 1 ;
416417 }
417418 len = cmark_utf8proc_iterate (subj -> input .data + before_char_pos ,
418419 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 ])) {
420421 before_char = 10 ;
421422 }
422-
423- CMARK_UNLOCK (chars );
424423 }
425424
426425 if (c == '\'' || c == '"' ) {
@@ -438,18 +437,14 @@ static int scan_delims(subject *subj, unsigned char c, bool *can_open,
438437 } else {
439438 after_char_pos = subj -> pos ;
440439
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 ) {
444441 after_char_pos += 1 ;
445442 }
446443 len = cmark_utf8proc_iterate (subj -> input .data + after_char_pos ,
447444 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 ])) {
449446 after_char = 10 ;
450447 }
451-
452- CMARK_UNLOCK (chars );
453448 }
454449
455450 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)
548543}
549544
550545// 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 ) {
552547 bufsize_t numdelims ;
553548 cmark_node * inl_text ;
554549 bool can_open , can_close ;
555550 cmark_chunk contents ;
556551
557- numdelims = scan_delims (subj , c , & can_open , & can_close );
552+ numdelims = scan_delims (parser , subj , c , & can_open , & can_close );
558553
559554 if (c == '\'' && smart ) {
560555 contents = cmark_chunk_literal (RIGHTSINGLEQUOTE );
@@ -1346,18 +1341,25 @@ static cmark_node *handle_newline(subject *subj) {
13461341}
13471342
13481343// "\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+ }
13611363
13621364// " ' . -
13631365static const char SMART_PUNCT_CHARS [] = {
@@ -1374,41 +1376,30 @@ static const char SMART_PUNCT_CHARS[] = {
13741376 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
13751377};
13761378
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 ) {
13781380 bufsize_t n = subj -> pos + 1 ;
1379- bufsize_t ret = subj -> input .len ;
13801381
1381- CMARK_INITIALIZE_AND_LOCK (chars );
13821382 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 ;
13911387 n ++ ;
13921388 }
1393- CMARK_UNLOCK (chars );
13941389
1395- return ret ;
1390+ return subj -> input . len ;
13961391}
13971392
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 ;
14011395 if (emphasis )
1402- SKIP_CHARS [c ] = 1 ;
1403- CMARK_UNLOCK (chars );
1396+ parser -> skip_chars [c ] = 1 ;
14041397}
14051398
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 ;
14091401 if (emphasis )
1410- SKIP_CHARS [c ] = 0 ;
1411- CMARK_UNLOCK (chars );
1402+ parser -> skip_chars [c ] = 0 ;
14121403}
14131404
14141405static cmark_node * try_extensions (cmark_parser * parser ,
@@ -1466,7 +1457,7 @@ static int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent,
14661457 case '_' :
14671458 case '\'' :
14681459 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 );
14701461 break ;
14711462 case '-' :
14721463 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,
15081499 if (new_inl != NULL )
15091500 break ;
15101501
1511- endpos = subject_find_special_char (subj , options );
1502+ endpos = subject_find_special_char (parser , subj , options );
15121503 contents = cmark_chunk_dup (& subj -> input , subj -> pos , endpos - subj -> pos );
15131504 startpos = subj -> pos ;
15141505 subj -> pos = endpos ;
0 commit comments