3 * lexical scanner internal declarations
5 * This file declares the PsqlScanStateData structure used by psqlscan.l
6 * and shared by other lexers compatible with it, such as psqlscanslash.l.
8 * One difficult aspect of this code is that we need to work in multibyte
9 * encodings that are not ASCII-safe. A "safe" encoding is one in which each
10 * byte of a multibyte character has the high bit set (it's >= 0x80). Since
11 * all our lexing rules treat all high-bit-set characters alike, we don't
12 * really need to care whether such a byte is part of a sequence or not.
13 * In an "unsafe" encoding, we still expect the first byte of a multibyte
14 * sequence to be >= 0x80, but later bytes might not be. If we scan such
15 * a sequence as-is, the lexing rules could easily be fooled into matching
16 * such bytes to ordinary ASCII characters. Our solution for this is to
17 * substitute 0xFF for each non-first byte within the data presented to flex.
18 * The flex rules will then pass the FF's through unmolested. The
19 * psqlscan_emit() subroutine is responsible for looking back to the original
20 * string and replacing FF's with the corresponding original bytes.
22 * Another interesting thing we do here is scan different parts of the same
23 * input with physically separate flex lexers (ie, lexers written in separate
24 * .l files). We can get away with this because the only part of the
25 * persistent state of a flex lexer that depends on its parsing rule tables
26 * is the start state number, which is easy enough to manage --- usually,
27 * in fact, we just need to set it to INITIAL when changing lexers. But to
28 * make that work at all, we must use re-entrant lexers, so that all the
29 * relevant state is in the yyscanner_t attached to the PsqlScanState;
30 * if we were using lexers with separate static state we would soon end up
31 * with dangling buffer pointers in one or the other. Also note that this
32 * is unlikely to work very nicely if the lexers aren't all built with the
35 * Copyright (c) 2000-2016, PostgreSQL Global Development Group
37 * src/bin/psql/psqlscan_int.h
39 #ifndef PSQLSCAN_INT_H
40 #define PSQLSCAN_INT_H
44 /* This is just to allow this file to be compilable standalone */
45 #ifndef YY_TYPEDEF_YY_BUFFER_STATE
46 #define YY_TYPEDEF_YY_BUFFER_STATE
47 typedef struct yy_buffer_state *YY_BUFFER_STATE;
51 * We use a stack of flex buffers to handle substitution of psql variables.
52 * Each stacked buffer contains the as-yet-unread text from one psql variable.
53 * When we pop the stack all the way, we resume reading from the outer buffer
54 * identified by scanbufhandle.
56 typedef struct StackElem
58 YY_BUFFER_STATE buf; /* flex input control structure */
59 char *bufstring; /* data actually being scanned by flex */
60 char *origstring; /* copy of original data, if needed */
61 char *varname; /* name of variable providing data, or NULL */
62 struct StackElem *next;
66 * All working state of the lexer must be stored in PsqlScanStateData
67 * between calls. This allows us to have multiple open lexer operations,
68 * which is needed for nested include files. The lexer itself is not
69 * recursive, but it must be re-entrant.
71 typedef struct PsqlScanStateData
73 yyscan_t scanner; /* Flex's state for this PsqlScanState */
75 PQExpBuffer output_buf; /* current output buffer */
77 StackElem *buffer_stack; /* stack of variable expansion buffers */
80 * These variables always refer to the outer buffer, never to any stacked
81 * variable-expansion buffer.
83 YY_BUFFER_STATE scanbufhandle;
84 char *scanbuf; /* start of outer-level input buffer */
85 const char *scanline; /* current input line at outer level */
87 /* safe_encoding, curline, refline are used by emit() to replace FFs */
88 int encoding; /* encoding being used now */
89 bool safe_encoding; /* is current encoding "safe"? */
90 bool std_strings; /* are string literals standard? */
91 const char *curline; /* actual flex input string for cur buf */
92 const char *refline; /* original data for cur buffer */
95 * All this state lives across successive input lines, until explicitly
96 * reset by psql_scan_reset. start_state is adopted by yylex() on entry,
97 * and updated with its finishing state on exit.
99 int start_state; /* yylex's starting/finishing state */
100 int paren_depth; /* depth of nesting in parentheses */
101 int xcdepth; /* depth of nesting in slash-star comments */
102 char *dolqstart; /* current $foo$ quote start string */
105 * Callback functions provided by the program making use of the lexer.
107 const PsqlScanCallbacks *callbacks;
112 * Functions exported by psqlscan.l, but only meant for use within
115 extern void psqlscan_push_new_buffer(PsqlScanState state,
116 const char *newstr, const char *varname);
117 extern void psqlscan_pop_buffer_stack(PsqlScanState state);
118 extern void psqlscan_select_top_buffer(PsqlScanState state);
119 extern YY_BUFFER_STATE psqlscan_prepare_buffer(PsqlScanState state,
120 const char *txt, int len,
122 extern void psqlscan_emit(PsqlScanState state, const char *txt, int len);
123 extern char *psqlscan_extract_substring(PsqlScanState state,
124 const char *txt, int len);
125 extern void psqlscan_escape_variable(PsqlScanState state,
126 const char *txt, int len,
129 #endif /* PSQLSCAN_INT_H */