summaryrefslogtreecommitdiff
path: root/src/scanners.re
blob: 5ac7c1570f64b2e3d2de600a1e7ff217e5d6e11c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#include "scanners.h"

#define SCAN_DATA \
  const unsigned char *marker = NULL; \
  const unsigned char *p = c->data + offset; \
  const unsigned char *start = p; \
  const unsigned char *end = c->data + c->len

/*!re2c
  re2c:define:YYCTYPE  = "unsigned char";
  re2c:define:YYCURSOR = p;
  re2c:define:YYLIMIT = end;
  re2c:define:YYMARKER = marker;
  re2c:define:YYCTXMARKER = marker;
  re2c:yyfill:enable = 0;

  wordchar = [^\x00-\x20];

  spacechar = [ \t\n];

  reg_char     = [^\\()\x00-\x20];

  escaped_char = [\\][!"#$%&'()*+,./:;<=>?@[\\\]^_`{|}~-];

  tagname = [A-Za-z][A-Za-z0-9]*;

  blocktagname = 'article'|'header'|'aside'|'hgroup'|'iframe'|'blockquote'|'hr'|'body'|'li'|'map'|'button'|'object'|'canvas'|'ol'|'caption'|'output'|'col'|'p'|'colgroup'|'pre'|'dd'|'progress'|'div'|'section'|'dl'|'table'|'td'|'dt'|'tbody'|'embed'|'textarea'|'fieldset'|'tfoot'|'figcaption'|'th'|'figure'|'thead'|'footer'|'footer'|'tr'|'form'|'ul'|'h1'|'h2'|'h3'|'h4'|'h5'|'h6'|'video'|'script'|'style';

  attributename = [a-zA-Z_:][a-zA-Z0-9:._-]*;

  unquotedvalue = [^\"'=<>`\x00]+;
  singlequotedvalue = ['][^'\x00]*['];
  doublequotedvalue = [\"][^\"\x00]*[\"];

  attributevalue = unquotedvalue | singlequotedvalue | doublequotedvalue;

  attributevaluespec = spacechar* [=] spacechar* attributevalue;

  attribute = spacechar+ attributename attributevaluespec?;

  opentag = tagname attribute* spacechar* [/]? [>];
  closetag = [/] tagname spacechar* [>];

  htmlcomment = "!--" ([^-\x00]+ | [-][^-\x00]+)* "-->";

  processinginstruction = "?" ([^?>\x00]+ | [?][^>\x00])* "?>";

  declaration = "!" [A-Z]+ spacechar+ [^>\x00]* ">";

  cdata = "![CDATA[" ([^\]\x00]+ | "]" [^\]\x00] | "]]" [^>\x00])* "]]>";

  htmltag = opentag | closetag | htmlcomment | processinginstruction |
            declaration | cdata;

  in_parens_nosp   = [(] (reg_char|escaped_char)* [)];

  in_double_quotes = ["] (escaped_char|[^"\x00])* ["];
  in_single_quotes = ['] (escaped_char|[^'\x00])* ['];
  in_parens        = [(] (escaped_char|[^)\x00])* [)];

  scheme = 'coap'|'doi'|'javascript'|'aaa'|'aaas'|'about'|'acap'|'cap'|'cid'|'crid'|'data'|'dav'|'dict'|'dns'|'file'|'ftp'|'geo'|'go'|'gopher'|'h323'|'http'|'https'|'iax'|'icap'|'im'|'imap'|'info'|'ipp'|'iris'|'iris.beep'|'iris.xpc'|'iris.xpcs'|'iris.lwz'|'ldap'|'mailto'|'mid'|'msrp'|'msrps'|'mtqp'|'mupdate'|'news'|'nfs'|'ni'|'nih'|'nntp'|'opaquelocktoken'|'pop'|'pres'|'rtsp'|'service'|'session'|'shttp'|'sieve'|'sip'|'sips'|'sms'|'snmp'|'soap.beep'|'soap.beeps'|'tag'|'tel'|'telnet'|'tftp'|'thismessage'|'tn3270'|'tip'|'tv'|'urn'|'vemmi'|'ws'|'wss'|'xcon'|'xcon-userid'|'xmlrpc.beep'|'xmlrpc.beeps'|'xmpp'|'z39.50r'|'z39.50s'|'adiumxtra'|'afp'|'afs'|'aim'|'apt'|'attachment'|'aw'|'beshare'|'bitcoin'|'bolo'|'callto'|'chrome'|'chrome-extension'|'com-eventbrite-attendee'|'content'|'cvs'|'dlna-playsingle'|'dlna-playcontainer'|'dtn'|'dvb'|'ed2k'|'facetime'|'feed'|'finger'|'fish'|'gg'|'git'|'gizmoproject'|'gtalk'|'hcp'|'icon'|'ipn'|'irc'|'irc6'|'ircs'|'itms'|'jar'|'jms'|'keyparc'|'lastfm'|'ldaps'|'magnet'|'maps'|'market'|'message'|'mms'|'ms-help'|'msnim'|'mumble'|'mvn'|'notes'|'oid'|'palm'|'paparazzi'|'platform'|'proxy'|'psyc'|'query'|'res'|'resource'|'rmi'|'rsync'|'rtmp'|'secondlife'|'sftp'|'sgn'|'skype'|'smb'|'soldat'|'spotify'|'ssh'|'steam'|'svn'|'teamspeak'|'things'|'udp'|'unreal'|'ut2004'|'ventrilo'|'view-source'|'webcal'|'wtai'|'wyciwyg'|'xfire'|'xri'|'ymsgr';
*/

// Try to match URI autolink after first <, returning number of chars matched.
extern int scan_autolink_uri(chunk *c, int offset)
{
  SCAN_DATA;
/*!re2c
  scheme [:]([^\x00-\x20<>\\]|escaped_char)*[>]  { return (p - start); }
  .? { return 0; }
*/
}

// Try to match email autolink after first <, returning num of chars matched.
extern int scan_autolink_email(chunk *c, int offset)
{
  SCAN_DATA;
/*!re2c
  [a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+
    [@]
    [a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?
    ([.][a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*
    [>] { return (p - start); }
  .? { return 0; }
*/
}

// Try to match an HTML tag after first <, returning num of chars matched.
extern int scan_html_tag(chunk *c, int offset)
{
  SCAN_DATA;
/*!re2c
  htmltag { return (p - start); }
  .? { return 0; }
*/
}

// Try to match an HTML block tag including first <,
// returning num of chars matched.
extern int scan_html_block_tag(chunk *c, int offset)
{
  SCAN_DATA;
/*!re2c
  [<] [/] blocktagname (spacechar | [>])  { return (p - start); }
  [<] blocktagname (spacechar | [/>]) { return (p - start); }
  [<] [!?] { return (p - start); }
  .? { return 0; }
*/
}

// Try to match a URL in a link or reference, return number of chars matched.
// This may optionally be contained in <..>; otherwise
// whitespace and unbalanced right parentheses aren't allowed.
// Newlines aren't ever allowed.
extern int scan_link_url(chunk *c, int offset)
{
  SCAN_DATA;
/*!re2c
  [ \n]* [<] ([^<>\n\\\x00] | escaped_char | [\\])* [>] { return (p - start); }
  [ \n]* (reg_char+ | escaped_char | in_parens_nosp)* { return (p - start); }
  .? { return 0; }
*/
}

// Try to match a link title (in single quotes, in double quotes, or
// in parentheses), returning number of chars matched.  Allow one
// level of internal nesting (quotes within quotes).
extern int scan_link_title(chunk *c, int offset)
{
  SCAN_DATA;
/*!re2c
  ["] (escaped_char|[^"\x00])* ["]   { return (p - start); }
  ['] (escaped_char|[^'\x00])* ['] { return (p - start); }
  [(] (escaped_char|[^)\x00])* [)]  { return (p - start); }
  .? { return 0; }
*/
}

// Match space characters, including newlines.
extern int scan_spacechars(chunk *c, int offset)
{
  SCAN_DATA;
/*!re2c
  [ \t\n]* { return (p - start); }
  . { return 0; }
*/
}

// Match ATX header start.
extern int scan_atx_header_start(chunk *c, int offset)
{
  SCAN_DATA;
/*!re2c
  [#]{1,6} ([ ]+|[\n])  { return (p - start); }
  .? { return 0; }
*/
}

// Match sexext header line.  Return 1 for level-1 header,
// 2 for level-2, 0 for no match.
extern int scan_setext_header_line(chunk *c, int offset)
{
  SCAN_DATA;
/*!re2c
  [=]+ [ ]* [\n] { return 1; }
  [-]+ [ ]* [\n] { return 2; }
  .? { return 0; }
*/
}

// Scan a horizontal rule line: "...three or more hyphens, asterisks,
// or underscores on a line by themselves. If you wish, you may use
// spaces between the hyphens or asterisks."
extern int scan_hrule(chunk *c, int offset)
{
  SCAN_DATA;
/*!re2c
  ([*][ ]*){3,} [ \t]* [\n] { return (p - start); }
  ([_][ ]*){3,} [ \t]* [\n] { return (p - start); }
  ([-][ ]*){3,} [ \t]* [\n] { return (p - start); }
  .? { return 0; }
*/
}

// Scan an opening code fence.
extern int scan_open_code_fence(chunk *c, int offset)
{
  SCAN_DATA;
/*!re2c
  [`]{3,} / [^`\n\x00]*[\n] { return (p - start); }
  [~]{3,} / [^~\n\x00]*[\n] { return (p - start); }
  .?                        { return 0; }
*/
}

// Scan a closing code fence with length at least len.
extern int scan_close_code_fence(chunk *c, int offset, int len)
{
  SCAN_DATA;
/*!re2c
  ([`]{3,} | [~]{3,}) / spacechar* [\n]
                              { if (p - start > len) {
                                return (p - start);
                              } else {
                                return 0;
                              } }
  .? { return 0; }
*/
}

// Scans an entity.
// Returns number of chars matched.
extern int scan_entity(chunk *c, int offset)
{
  SCAN_DATA;
/*!re2c
  [&] ([#] ([Xx][A-Fa-f0-9]{1,8}|[0-9]{1,8}) |[A-Za-z][A-Za-z0-9]{1,31} ) [;]
     { return (p - start); }
  .? { return 0; }
*/
}