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
|
%{
/*
* lexer.l -- lexer for the rcfile
*/
/*
* Adapted from fetchmail's rcfile_l.l by José Fonseca
*/
#include <stdio.h>
#include <string.h>
#include "parser.h"
#define MSGBUFSIZE 8192
int lineno = 1;
void escapes(const char *tp, char *cp);
%}
%s NAME
%%
\"[^\"]*\" {
char buf[MSGBUFSIZE];
yytext[strlen(yytext)-1] = '\0';
escapes(yytext+1, buf);
yylval.sval = (char *) strdup(buf);
BEGIN(0);
return STRING;
}
\'[^\']*\' {
char buf[MSGBUFSIZE];
yytext[strlen(yytext)-1] = '\0';
escapes(yytext+1, buf);
yylval.sval = (char *) strdup(buf);
BEGIN(0);
return STRING;
}
<NAME>[^=;, \t\r\n]+ {
char buf[MSGBUFSIZE];
escapes(yytext, buf);
yylval.sval = (char *) strdup(buf);
BEGIN(0);
return STRING;
}
host(name)? { BEGIN(NAME); return HOSTNAME; }
user(name)? { BEGIN(NAME); return USERNAME; }
pass(word)? { BEGIN(NAME); return PASSWORD; }
(start)?tls { return STARTTLS; }
(certificate_)?passphrase { return CERTIFICATE_PASSPHRASE; }
= { return MAP; }
disabled { return DISABLED; }
enabled { return ENABLED; }
required { return REQUIRED; }
(#.*)?\\?\n { lineno++; } /* newline is ignored */
-?[0-9]+/[^a-zA-Z] { yylval.number = atoi(yytext); return NUMBER; }
[^=;:, \t\r\n]+ {
char buf[MSGBUFSIZE];
escapes(yytext, buf);
yylval.sval = (char *) strdup(buf);
return STRING;
}
[ \t\r]+ ; /* whitespace */
%%
void escapes(cp, tp)
/* process standard C-style escape sequences in a string */
const char *cp; /* source string with escapes */
char *tp; /* target buffer for digested string */
{
while (*cp)
{
int cval = 0;
if (*cp == '\\' && strchr("0123456789xX", cp[1]))
{
char *dp;
const char *hex = "00112233445566778899aAbBcCdDeEfF";
int dcount = 0;
if (*++cp == 'x' || *cp == 'X')
for (++cp; (dp = strchr(hex, *cp)) && (dcount++ < 2); cp++)
cval = (cval * 16) + (dp - hex) / 2;
else if (*cp == '0')
while (strchr("01234567",*cp) != (char*)NULL && (dcount++ < 3))
cval = (cval * 8) + (*cp++ - '0');
else
while ((strchr("0123456789",*cp)!=(char*)NULL)&&(dcount++ < 3))
cval = (cval * 10) + (*cp++ - '0');
}
else if (*cp == '\\') /* C-style character escapes */
{
switch (*++cp)
{
case '\\': cval = '\\'; break;
case 'n': cval = '\n'; break;
case 't': cval = '\t'; break;
case 'b': cval = '\b'; break;
case 'r': cval = '\r'; break;
default: cval = *cp;
}
cp++;
}
else
cval = *cp++;
*tp++ = cval;
}
*tp = '\0';
}
|