Age Owner Branch data TLA Line data Source code
1 : : %top{
2 : : /*-------------------------------------------------------------------------
3 : : *
4 : : * syncrep_scanner.l
5 : : * a lexical scanner for synchronous_standby_names
6 : : *
7 : : * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
8 : : * Portions Copyright (c) 1994, Regents of the University of California
9 : : *
10 : : *
11 : : * IDENTIFICATION
12 : : * src/backend/replication/syncrep_scanner.l
13 : : *
14 : : *-------------------------------------------------------------------------
15 : : */
16 : : #include "postgres.h"
17 : :
18 : : #include "lib/stringinfo.h"
19 : : #include "nodes/pg_list.h"
20 : :
21 : : /*
22 : : * NB: include syncrep_gram.h only AFTER including syncrep.h, because syncrep.h
23 : : * includes node definitions needed for YYSTYPE.
24 : : */
25 : : #include "replication/syncrep.h"
26 : : #include "syncrep_gram.h"
27 : : }
28 : :
29 : : %{
30 : : /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
31 : : #undef fprintf
32 : : #define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg)
33 : :
34 : : static void
2909 tgl@sss.pgh.pa.us 35 :UBC 0 : fprintf_to_ereport(const char *fmt, const char *msg)
36 : : {
37 [ # # ]: 0 : ereport(ERROR, (errmsg_internal("%s", msg)));
38 : : }
39 : :
40 : : /* Handles to the buffer that the lexer uses internally */
41 : : static YY_BUFFER_STATE scanbufhandle;
42 : :
43 : : static StringInfoData xdbuf;
44 : :
45 : : /* LCOV_EXCL_START */
46 : :
47 : : %}
48 : :
49 : : %option 8bit
50 : : %option never-interactive
51 : : %option nodefault
52 : : %option noinput
53 : : %option nounput
54 : : %option noyywrap
55 : : %option warn
56 : : %option prefix="syncrep_yy"
57 : :
58 : : /*
59 : : * <xd> delimited identifiers (double-quoted identifiers)
60 : : */
61 : : %x xd
62 : :
63 : : space [ \t\n\r\f\v]
64 : :
65 : : digit [0-9]
66 : : ident_start [A-Za-z\200-\377_]
67 : : ident_cont [A-Za-z\200-\377_0-9\$]
68 : : identifier {ident_start}{ident_cont}*
69 : :
70 : : dquote \"
71 : : xdstart {dquote}
72 : : xdstop {dquote}
73 : : xddouble {dquote}{dquote}
74 : : xdinside [^"]+
75 : :
76 : : %%
77 : : {space}+ { /* ignore */ }
78 : :
79 : : /* brute-force case insensitivity is safer than relying on flex -i */
80 : :
81 : : [Aa][Nn][Yy] { return ANY; }
82 : : [Ff][Ii][Rr][Ss][Tt] { return FIRST; }
83 : :
84 : : {xdstart} {
85 : : initStringInfo(&xdbuf);
86 : : BEGIN(xd);
87 : : }
88 : : <xd>{xddouble} {
89 : : appendStringInfoChar(&xdbuf, '"');
90 : : }
91 : : <xd>{xdinside} {
92 : : appendStringInfoString(&xdbuf, yytext);
93 : : }
94 : : <xd>{xdstop} {
95 : : syncrep_yylval.str = xdbuf.data;
96 : : xdbuf.data = NULL;
97 : : BEGIN(INITIAL);
98 : : return NAME;
99 : : }
100 : : <xd><<EOF>> {
101 : : syncrep_yyerror("unterminated quoted identifier");
102 : : return JUNK;
103 : : }
104 : :
105 : : {identifier} {
106 : : syncrep_yylval.str = pstrdup(yytext);
107 : : return NAME;
108 : : }
109 : :
110 : : {digit}+ {
111 : : syncrep_yylval.str = pstrdup(yytext);
112 : : return NUM;
113 : : }
114 : :
115 : : "*" {
116 : : syncrep_yylval.str = "*";
117 : : return NAME;
118 : : }
119 : :
120 : : "," { return ','; }
121 : : "(" { return '('; }
122 : : ")" { return ')'; }
123 : :
124 : : . { return JUNK; }
125 : : %%
126 : :
127 : : /* LCOV_EXCL_STOP */
128 : :
129 : : /* Needs to be here for access to yytext */
130 : : void
131 : 0 : syncrep_yyerror(const char *message)
132 : : {
133 : : /* report only the first error in a parse operation */
134 [ # # ]: 0 : if (syncrep_parse_error_msg)
135 : 0 : return;
136 [ # # ]: 0 : if (yytext[0])
137 : 0 : syncrep_parse_error_msg = psprintf("%s at or near \"%s\"",
138 : : message, yytext);
139 : : else
140 : 0 : syncrep_parse_error_msg = psprintf("%s at end of input",
141 : : message);
142 : : }
143 : :
144 : : void
2930 fujii@postgresql.org 145 :CBC 136 : syncrep_scanner_init(const char *str)
146 : : {
147 : 136 : Size slen = strlen(str);
148 : : char *scanbuf;
149 : :
150 : : /*
151 : : * Might be left over after ereport()
152 : : */
153 [ + + - + ]: 136 : if (YY_CURRENT_BUFFER)
2930 fujii@postgresql.org 154 [ # # ]:UBC 0 : yy_delete_buffer(YY_CURRENT_BUFFER);
155 : :
156 : : /*
157 : : * Make a scan buffer with special termination needed by flex.
158 : : */
2930 fujii@postgresql.org 159 :CBC 136 : scanbuf = (char *) palloc(slen + 2);
160 : 136 : memcpy(scanbuf, str, slen);
161 : 136 : scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR;
162 : 136 : scanbufhandle = yy_scan_buffer(scanbuf, slen + 2);
163 : :
164 : : /* Make sure we start in proper state */
2909 tgl@sss.pgh.pa.us 165 : 136 : BEGIN(INITIAL);
2930 fujii@postgresql.org 166 : 136 : }
167 : :
168 : : void
169 : 136 : syncrep_scanner_finish(void)
170 : : {
171 : 136 : yy_delete_buffer(scanbufhandle);
172 : 136 : scanbufhandle = NULL;
173 : 136 : }
|