1// re2c $INPUT -o $OUTPUT -wb
2
3#define YYFILL(n) if (cursor >= limit) break;
4#define YYCTYPE unsigned short
5#define YYCURSOR cursor
6#define YYLIMIT limit
7#define YYMARKER marker
8
9/*!re2c
10any     = (.|"\n");
11value	= (":" (.\"$")+)?;
12cvsdat	= "Date";
13cvsid	= "Id";
14cvslog	= "Log";
15cvsrev	= "Revision";
16cvssrc	= "Source";
17*/
18
19#define APPEND(text) \
20	append(output, outsize, text, sizeof(text) - sizeof(YYCTYPE))
21
22inline void append(YYCTYPE *output, size_t & outsize, const YYCTYPE * text, size_t len)
23{
24	memcpy(output + outsize, text, len);
25	outsize += (len / sizeof(YYCTYPE));
26}
27
28void scan(YYCTYPE *pText, size_t *pSize, int *pbChanged)
29{
30	// rule
31	// scan lines
32	// find $ in lines
33	//   compact $<keyword>: .. $ to $<keyword>$
34
35	YYCTYPE *output;
36	const YYCTYPE *cursor, *limit, *marker;
37
38	cursor = marker = output = *pText;
39
40	size_t insize = *pSize;
41	size_t outsize = 0;
42
43	limit = cursor + insize;
44
45	while(1) {
46loop:
47/*!re2c
48
49"$" cvsdat value "$"	{ APPEND(L"$" L"Date$"); goto loop; }
50"$" cvsid  value "$"	{ APPEND(L"$" L"Id$"); goto loop; }
51"$" cvslog value "$"	{ APPEND(L"$" L"Log$"); goto loop; }
52"$" cvsrev value "$"	{ APPEND(L"$" L"Revision$"); goto loop; }
53"$" cvssrc value "$"	{ APPEND(L"$" L"Source$"); goto loop; }
54any						{ output[outsize++] = cursor[-1]; if (cursor >= limit) break; goto loop; }
55
56*/
57	}
58	output[outsize] = '\0';
59
60	// set the new size
61	*pSize = outsize;
62
63	*pbChanged = (insize == outsize) ? 0 : 1;
64}
65