summaryrefslogtreecommitdiffstats
path: root/src/include/fe_utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/fe_utils')
-rw-r--r--src/include/fe_utils/archive.h21
-rw-r--r--src/include/fe_utils/cancel.h32
-rw-r--r--src/include/fe_utils/conditional.h100
-rw-r--r--src/include/fe_utils/mbprint.h29
-rw-r--r--src/include/fe_utils/print.h219
-rw-r--r--src/include/fe_utils/psqlscan.h90
-rw-r--r--src/include/fe_utils/psqlscan_int.h149
-rw-r--r--src/include/fe_utils/recovery_gen.h28
-rw-r--r--src/include/fe_utils/simple_list.h70
-rw-r--r--src/include/fe_utils/string_utils.h59
10 files changed, 797 insertions, 0 deletions
diff --git a/src/include/fe_utils/archive.h b/src/include/fe_utils/archive.h
new file mode 100644
index 0000000..a6beaf0
--- /dev/null
+++ b/src/include/fe_utils/archive.h
@@ -0,0 +1,21 @@
+/*-------------------------------------------------------------------------
+ *
+ * archive.h
+ * Routines to access WAL archives from frontend
+ *
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/fe_utils/archive.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef FE_ARCHIVE_H
+#define FE_ARCHIVE_H
+
+extern int RestoreArchivedFile(const char *path,
+ const char *xlogfname,
+ off_t expectedSize,
+ const char *restoreCommand);
+
+#endif /* FE_ARCHIVE_H */
diff --git a/src/include/fe_utils/cancel.h b/src/include/fe_utils/cancel.h
new file mode 100644
index 0000000..2a1169a
--- /dev/null
+++ b/src/include/fe_utils/cancel.h
@@ -0,0 +1,32 @@
+/*-------------------------------------------------------------------------
+ *
+ * Query cancellation support for frontend code
+ *
+ *
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/fe_utils/cancel.h
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef CANCEL_H
+#define CANCEL_H
+
+#include <signal.h>
+
+#include "libpq-fe.h"
+
+extern volatile sig_atomic_t CancelRequested;
+
+extern void SetCancelConn(PGconn *conn);
+extern void ResetCancelConn(void);
+
+/*
+ * A callback can be optionally set up to be called at cancellation
+ * time.
+ */
+extern void setup_cancel_handler(void (*cancel_callback) (void));
+
+#endif /* CANCEL_H */
diff --git a/src/include/fe_utils/conditional.h b/src/include/fe_utils/conditional.h
new file mode 100644
index 0000000..999de3e
--- /dev/null
+++ b/src/include/fe_utils/conditional.h
@@ -0,0 +1,100 @@
+/*-------------------------------------------------------------------------
+ * A stack of automaton states to handle nested conditionals.
+ *
+ * This file describes a stack of automaton states which
+ * allow a manage nested conditionals.
+ *
+ * It is used by:
+ * - "psql" interpreter for handling \if ... \endif
+ * - "pgbench" interpreter for handling \if ... \endif
+ * - "pgbench" syntax checker to test for proper nesting
+ *
+ * The stack holds the state of enclosing conditionals (are we in
+ * a true branch? in a false branch? have we already encountered
+ * a true branch?) so that the interpreter knows whether to execute
+ * code and whether to evaluate conditions.
+ *
+ * Copyright (c) 2000-2020, PostgreSQL Global Development Group
+ *
+ * src/include/fe_utils/conditional.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef CONDITIONAL_H
+#define CONDITIONAL_H
+
+/*
+ * Possible states of a single level of \if block.
+ */
+typedef enum ifState
+{
+ IFSTATE_NONE = 0, /* not currently in an \if block */
+ IFSTATE_TRUE, /* currently in an \if or \elif that is true
+ * and all parent branches (if any) are true */
+ IFSTATE_FALSE, /* currently in an \if or \elif that is false
+ * but no true branch has yet been seen, and
+ * all parent branches (if any) are true */
+ IFSTATE_IGNORED, /* currently in an \elif that follows a true
+ * branch, or the whole \if is a child of a
+ * false parent branch */
+ IFSTATE_ELSE_TRUE, /* currently in an \else that is true and all
+ * parent branches (if any) are true */
+ IFSTATE_ELSE_FALSE /* currently in an \else that is false or
+ * ignored */
+} ifState;
+
+/*
+ * The state of nested \ifs is stored in a stack.
+ *
+ * query_len is used to determine what accumulated text to throw away at the
+ * end of an inactive branch. (We could, perhaps, teach the lexer to not add
+ * stuff to the query buffer in the first place when inside an inactive branch;
+ * but that would be very invasive.) We also need to save and restore the
+ * lexer's parenthesis nesting depth when throwing away text. (We don't need
+ * to save and restore any of its other state, such as comment nesting depth,
+ * because a backslash command could never appear inside a comment or SQL
+ * literal.)
+ */
+typedef struct IfStackElem
+{
+ ifState if_state; /* current state, see enum above */
+ int query_len; /* length of query_buf at last branch start */
+ int paren_depth; /* parenthesis depth at last branch start */
+ struct IfStackElem *next; /* next surrounding \if, if any */
+} IfStackElem;
+
+typedef struct ConditionalStackData
+{
+ IfStackElem *head;
+} ConditionalStackData;
+
+typedef struct ConditionalStackData *ConditionalStack;
+
+
+extern ConditionalStack conditional_stack_create(void);
+
+extern void conditional_stack_destroy(ConditionalStack cstack);
+
+extern int conditional_stack_depth(ConditionalStack cstack);
+
+extern void conditional_stack_push(ConditionalStack cstack, ifState new_state);
+
+extern bool conditional_stack_pop(ConditionalStack cstack);
+
+extern ifState conditional_stack_peek(ConditionalStack cstack);
+
+extern bool conditional_stack_poke(ConditionalStack cstack, ifState new_state);
+
+extern bool conditional_stack_empty(ConditionalStack cstack);
+
+extern bool conditional_active(ConditionalStack cstack);
+
+extern void conditional_stack_set_query_len(ConditionalStack cstack, int len);
+
+extern int conditional_stack_get_query_len(ConditionalStack cstack);
+
+extern void conditional_stack_set_paren_depth(ConditionalStack cstack, int depth);
+
+extern int conditional_stack_get_paren_depth(ConditionalStack cstack);
+
+#endif /* CONDITIONAL_H */
diff --git a/src/include/fe_utils/mbprint.h b/src/include/fe_utils/mbprint.h
new file mode 100644
index 0000000..1aa718b
--- /dev/null
+++ b/src/include/fe_utils/mbprint.h
@@ -0,0 +1,29 @@
+/*-------------------------------------------------------------------------
+ *
+ * Multibyte character printing support for frontend code
+ *
+ *
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/fe_utils/mbprint.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef MBPRINT_H
+#define MBPRINT_H
+
+struct lineptr
+{
+ unsigned char *ptr;
+ int width;
+};
+
+extern unsigned char *mbvalidate(unsigned char *pwcs, int encoding);
+extern int pg_wcswidth(const char *pwcs, size_t len, int encoding);
+extern void pg_wcsformat(const unsigned char *pwcs, size_t len, int encoding,
+ struct lineptr *lines, int count);
+extern void pg_wcssize(const unsigned char *pwcs, size_t len, int encoding,
+ int *width, int *height, int *format_size);
+
+#endif /* MBPRINT_H */
diff --git a/src/include/fe_utils/print.h b/src/include/fe_utils/print.h
new file mode 100644
index 0000000..9a47efa
--- /dev/null
+++ b/src/include/fe_utils/print.h
@@ -0,0 +1,219 @@
+/*-------------------------------------------------------------------------
+ *
+ * Query-result printing support for frontend code
+ *
+ *
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/fe_utils/print.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PRINT_H
+#define PRINT_H
+
+#include <signal.h>
+
+#include "libpq-fe.h"
+
+
+/* This is not a particularly great place for this ... */
+#ifndef __CYGWIN__
+#define DEFAULT_PAGER "more"
+#else
+#define DEFAULT_PAGER "less"
+#endif
+
+enum printFormat
+{
+ PRINT_NOTHING = 0, /* to make sure someone initializes this */
+ PRINT_ALIGNED,
+ PRINT_ASCIIDOC,
+ PRINT_CSV,
+ PRINT_HTML,
+ PRINT_LATEX,
+ PRINT_LATEX_LONGTABLE,
+ PRINT_TROFF_MS,
+ PRINT_UNALIGNED,
+ PRINT_WRAPPED
+ /* add your favourite output format here ... */
+};
+
+typedef struct printTextLineFormat
+{
+ /* Line drawing characters to be used in various contexts */
+ const char *hrule; /* horizontal line character */
+ const char *leftvrule; /* left vertical line (+horizontal) */
+ const char *midvrule; /* intra-column vertical line (+horizontal) */
+ const char *rightvrule; /* right vertical line (+horizontal) */
+} printTextLineFormat;
+
+typedef enum printTextRule
+{
+ /* Additional context for selecting line drawing characters */
+ PRINT_RULE_TOP, /* top horizontal line */
+ PRINT_RULE_MIDDLE, /* intra-data horizontal line */
+ PRINT_RULE_BOTTOM, /* bottom horizontal line */
+ PRINT_RULE_DATA /* data line (hrule is unused here) */
+} printTextRule;
+
+typedef enum printTextLineWrap
+{
+ /* Line wrapping conditions */
+ PRINT_LINE_WRAP_NONE, /* No wrapping */
+ PRINT_LINE_WRAP_WRAP, /* Wraparound due to overlength line */
+ PRINT_LINE_WRAP_NEWLINE /* Newline in data */
+} printTextLineWrap;
+
+typedef struct printTextFormat
+{
+ /* A complete line style */
+ const char *name; /* for display purposes */
+ printTextLineFormat lrule[4]; /* indexed by enum printTextRule */
+ const char *midvrule_nl; /* vertical line for continue after newline */
+ const char *midvrule_wrap; /* vertical line for wrapped data */
+ const char *midvrule_blank; /* vertical line for blank data */
+ const char *header_nl_left; /* left mark after newline */
+ const char *header_nl_right; /* right mark for newline */
+ const char *nl_left; /* left mark after newline */
+ const char *nl_right; /* right mark for newline */
+ const char *wrap_left; /* left mark after wrapped data */
+ const char *wrap_right; /* right mark for wrapped data */
+ bool wrap_right_border; /* use right-hand border for wrap marks
+ * when border=0? */
+} printTextFormat;
+
+typedef enum unicode_linestyle
+{
+ UNICODE_LINESTYLE_SINGLE = 0,
+ UNICODE_LINESTYLE_DOUBLE
+} unicode_linestyle;
+
+struct separator
+{
+ char *separator;
+ bool separator_zero;
+};
+
+typedef struct printTableOpt
+{
+ enum printFormat format; /* see enum above */
+ unsigned short int expanded; /* expanded/vertical output (if supported
+ * by output format); 0=no, 1=yes, 2=auto */
+ unsigned short int border; /* Print a border around the table. 0=none,
+ * 1=dividing lines, 2=full */
+ unsigned short int pager; /* use pager for output (if to stdout and
+ * stdout is a tty) 0=off 1=on 2=always */
+ int pager_min_lines; /* don't use pager unless there are at
+ * least this many lines */
+ bool tuples_only; /* don't output headers, row counts, etc. */
+ bool start_table; /* print start decoration, eg <table> */
+ bool stop_table; /* print stop decoration, eg </table> */
+ bool default_footer; /* allow "(xx rows)" default footer */
+ unsigned long prior_records; /* start offset for record counters */
+ const printTextFormat *line_style; /* line style (NULL for default) */
+ struct separator fieldSep; /* field separator for unaligned text mode */
+ struct separator recordSep; /* record separator for unaligned text mode */
+ char csvFieldSep[2]; /* field separator for csv format */
+ bool numericLocale; /* locale-aware numeric units separator and
+ * decimal marker */
+ char *tableAttr; /* attributes for HTML <table ...> */
+ int encoding; /* character encoding */
+ int env_columns; /* $COLUMNS on psql start, 0 is unset */
+ int columns; /* target width for wrapped format */
+ unicode_linestyle unicode_border_linestyle;
+ unicode_linestyle unicode_column_linestyle;
+ unicode_linestyle unicode_header_linestyle;
+} printTableOpt;
+
+/*
+ * Table footers are implemented as a singly-linked list.
+ *
+ * This is so that you don't need to know the number of footers in order to
+ * initialise the printTableContent struct, which is very convenient when
+ * preparing complex footers (as in describeOneTableDetails).
+ */
+typedef struct printTableFooter
+{
+ char *data;
+ struct printTableFooter *next;
+} printTableFooter;
+
+/*
+ * The table content struct holds all the information which will be displayed
+ * by printTable().
+ */
+typedef struct printTableContent
+{
+ const printTableOpt *opt;
+ const char *title; /* May be NULL */
+ int ncolumns; /* Specified in Init() */
+ int nrows; /* Specified in Init() */
+ const char **headers; /* NULL-terminated array of header strings */
+ const char **header; /* Pointer to the last added header */
+ const char **cells; /* NULL-terminated array of cell content
+ * strings */
+ const char **cell; /* Pointer to the last added cell */
+ long cellsadded; /* Number of cells added this far */
+ bool *cellmustfree; /* true for cells that need to be free()d */
+ printTableFooter *footers; /* Pointer to the first footer */
+ printTableFooter *footer; /* Pointer to the last added footer */
+ char *aligns; /* Array of alignment specifiers; 'l' or 'r',
+ * one per column */
+ char *align; /* Pointer to the last added alignment */
+} printTableContent;
+
+typedef struct printQueryOpt
+{
+ printTableOpt topt; /* the options above */
+ char *nullPrint; /* how to print null entities */
+ char *title; /* override title */
+ char **footers; /* override footer (default is "(xx rows)") */
+ bool translate_header; /* do gettext on column headers */
+ const bool *translate_columns; /* translate_columns[i-1] => do gettext on
+ * col i */
+ int n_translate_columns; /* length of translate_columns[] */
+} printQueryOpt;
+
+
+extern volatile sig_atomic_t cancel_pressed;
+
+extern const printTextFormat pg_asciiformat;
+extern const printTextFormat pg_asciiformat_old;
+extern printTextFormat pg_utf8format; /* ideally would be const, but... */
+
+
+extern void disable_sigpipe_trap(void);
+extern void restore_sigpipe_trap(void);
+extern void set_sigpipe_trap_state(bool ignore);
+
+extern FILE *PageOutput(int lines, const printTableOpt *topt);
+extern void ClosePager(FILE *pagerpipe);
+
+extern void html_escaped_print(const char *in, FILE *fout);
+
+extern void printTableInit(printTableContent *const content,
+ const printTableOpt *opt, const char *title,
+ const int ncolumns, const int nrows);
+extern void printTableAddHeader(printTableContent *const content,
+ char *header, const bool translate, const char align);
+extern void printTableAddCell(printTableContent *const content,
+ char *cell, const bool translate, const bool mustfree);
+extern void printTableAddFooter(printTableContent *const content,
+ const char *footer);
+extern void printTableSetFooter(printTableContent *const content,
+ const char *footer);
+extern void printTableCleanup(printTableContent *const content);
+extern void printTable(const printTableContent *cont,
+ FILE *fout, bool is_pager, FILE *flog);
+extern void printQuery(const PGresult *result, const printQueryOpt *opt,
+ FILE *fout, bool is_pager, FILE *flog);
+
+extern char column_type_alignment(Oid);
+
+extern void setDecimalLocale(void);
+extern const printTextFormat *get_line_style(const printTableOpt *opt);
+extern void refresh_utf8format(const printTableOpt *opt);
+
+#endif /* PRINT_H */
diff --git a/src/include/fe_utils/psqlscan.h b/src/include/fe_utils/psqlscan.h
new file mode 100644
index 0000000..91d1091
--- /dev/null
+++ b/src/include/fe_utils/psqlscan.h
@@ -0,0 +1,90 @@
+/*-------------------------------------------------------------------------
+ *
+ * psqlscan.h
+ * lexical scanner for SQL commands
+ *
+ * This lexer used to be part of psql, and that heritage is reflected in
+ * the file name as well as function and typedef names, though it can now
+ * be used by other frontend programs as well. It's also possible to extend
+ * this lexer with a compatible add-on lexer to handle program-specific
+ * backslash commands.
+ *
+ *
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/fe_utils/psqlscan.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PSQLSCAN_H
+#define PSQLSCAN_H
+
+#include "pqexpbuffer.h"
+
+
+/* Abstract type for lexer's internal state */
+typedef struct PsqlScanStateData *PsqlScanState;
+
+/* Termination states for psql_scan() */
+typedef enum
+{
+ PSCAN_SEMICOLON, /* found command-ending semicolon */
+ PSCAN_BACKSLASH, /* found backslash command */
+ PSCAN_INCOMPLETE, /* end of line, SQL statement incomplete */
+ PSCAN_EOL /* end of line, SQL possibly complete */
+} PsqlScanResult;
+
+/* Prompt type returned by psql_scan() */
+typedef enum _promptStatus
+{
+ PROMPT_READY,
+ PROMPT_CONTINUE,
+ PROMPT_COMMENT,
+ PROMPT_SINGLEQUOTE,
+ PROMPT_DOUBLEQUOTE,
+ PROMPT_DOLLARQUOTE,
+ PROMPT_PAREN,
+ PROMPT_COPY
+} promptStatus_t;
+
+/* Quoting request types for get_variable() callback */
+typedef enum
+{
+ PQUOTE_PLAIN, /* just return the actual value */
+ PQUOTE_SQL_LITERAL, /* add quotes to make a valid SQL literal */
+ PQUOTE_SQL_IDENT, /* quote if needed to make a SQL identifier */
+ PQUOTE_SHELL_ARG /* quote if needed to be safe in a shell cmd */
+} PsqlScanQuoteType;
+
+/* Callback functions to be used by the lexer */
+typedef struct PsqlScanCallbacks
+{
+ /* Fetch value of a variable, as a free'able string; NULL if unknown */
+ /* This pointer can be NULL if no variable substitution is wanted */
+ char *(*get_variable) (const char *varname, PsqlScanQuoteType quote,
+ void *passthrough);
+} PsqlScanCallbacks;
+
+
+extern PsqlScanState psql_scan_create(const PsqlScanCallbacks *callbacks);
+extern void psql_scan_destroy(PsqlScanState state);
+
+extern void psql_scan_set_passthrough(PsqlScanState state, void *passthrough);
+
+extern void psql_scan_setup(PsqlScanState state,
+ const char *line, int line_len,
+ int encoding, bool std_strings);
+extern void psql_scan_finish(PsqlScanState state);
+
+extern PsqlScanResult psql_scan(PsqlScanState state,
+ PQExpBuffer query_buf,
+ promptStatus_t *prompt);
+
+extern void psql_scan_reset(PsqlScanState state);
+
+extern void psql_scan_reselect_sql_lexer(PsqlScanState state);
+
+extern bool psql_scan_in_quote(PsqlScanState state);
+
+#endif /* PSQLSCAN_H */
diff --git a/src/include/fe_utils/psqlscan_int.h b/src/include/fe_utils/psqlscan_int.h
new file mode 100644
index 0000000..311f803
--- /dev/null
+++ b/src/include/fe_utils/psqlscan_int.h
@@ -0,0 +1,149 @@
+/*-------------------------------------------------------------------------
+ *
+ * psqlscan_int.h
+ * lexical scanner internal declarations
+ *
+ * This file declares the PsqlScanStateData structure used by psqlscan.l
+ * and shared by other lexers compatible with it, such as psqlscanslash.l.
+ *
+ * One difficult aspect of this code is that we need to work in multibyte
+ * encodings that are not ASCII-safe. A "safe" encoding is one in which each
+ * byte of a multibyte character has the high bit set (it's >= 0x80). Since
+ * all our lexing rules treat all high-bit-set characters alike, we don't
+ * really need to care whether such a byte is part of a sequence or not.
+ * In an "unsafe" encoding, we still expect the first byte of a multibyte
+ * sequence to be >= 0x80, but later bytes might not be. If we scan such
+ * a sequence as-is, the lexing rules could easily be fooled into matching
+ * such bytes to ordinary ASCII characters. Our solution for this is to
+ * substitute 0xFF for each non-first byte within the data presented to flex.
+ * The flex rules will then pass the FF's through unmolested. The
+ * psqlscan_emit() subroutine is responsible for looking back to the original
+ * string and replacing FF's with the corresponding original bytes.
+ *
+ * Another interesting thing we do here is scan different parts of the same
+ * input with physically separate flex lexers (ie, lexers written in separate
+ * .l files). We can get away with this because the only part of the
+ * persistent state of a flex lexer that depends on its parsing rule tables
+ * is the start state number, which is easy enough to manage --- usually,
+ * in fact, we just need to set it to INITIAL when changing lexers. But to
+ * make that work at all, we must use re-entrant lexers, so that all the
+ * relevant state is in the yyscan_t attached to the PsqlScanState;
+ * if we were using lexers with separate static state we would soon end up
+ * with dangling buffer pointers in one or the other. Also note that this
+ * is unlikely to work very nicely if the lexers aren't all built with the
+ * same flex version, or if they don't use the same flex options.
+ *
+ *
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/fe_utils/psqlscan_int.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PSQLSCAN_INT_H
+#define PSQLSCAN_INT_H
+
+#include "fe_utils/psqlscan.h"
+
+/*
+ * These are just to allow this file to be compilable standalone for header
+ * validity checking; in actual use, this file should always be included
+ * from the body of a flex file, where these symbols are already defined.
+ */
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void *yyscan_t;
+#endif
+
+/*
+ * We use a stack of flex buffers to handle substitution of psql variables.
+ * Each stacked buffer contains the as-yet-unread text from one psql variable.
+ * When we pop the stack all the way, we resume reading from the outer buffer
+ * identified by scanbufhandle.
+ */
+typedef struct StackElem
+{
+ YY_BUFFER_STATE buf; /* flex input control structure */
+ char *bufstring; /* data actually being scanned by flex */
+ char *origstring; /* copy of original data, if needed */
+ char *varname; /* name of variable providing data, or NULL */
+ struct StackElem *next;
+} StackElem;
+
+/*
+ * All working state of the lexer must be stored in PsqlScanStateData
+ * between calls. This allows us to have multiple open lexer operations,
+ * which is needed for nested include files. The lexer itself is not
+ * recursive, but it must be re-entrant.
+ */
+typedef struct PsqlScanStateData
+{
+ yyscan_t scanner; /* Flex's state for this PsqlScanState */
+
+ PQExpBuffer output_buf; /* current output buffer */
+
+ StackElem *buffer_stack; /* stack of variable expansion buffers */
+
+ /*
+ * These variables always refer to the outer buffer, never to any stacked
+ * variable-expansion buffer.
+ */
+ YY_BUFFER_STATE scanbufhandle;
+ char *scanbuf; /* start of outer-level input buffer */
+ const char *scanline; /* current input line at outer level */
+
+ /* safe_encoding, curline, refline are used by emit() to replace FFs */
+ int encoding; /* encoding being used now */
+ bool safe_encoding; /* is current encoding "safe"? */
+ bool std_strings; /* are string literals standard? */
+ const char *curline; /* actual flex input string for cur buf */
+ const char *refline; /* original data for cur buffer */
+
+ /*
+ * All this state lives across successive input lines, until explicitly
+ * reset by psql_scan_reset. start_state is adopted by yylex() on entry,
+ * and updated with its finishing state on exit.
+ */
+ int start_state; /* yylex's starting/finishing state */
+ int state_before_str_stop; /* start cond. before end quote */
+ int paren_depth; /* depth of nesting in parentheses */
+ int xcdepth; /* depth of nesting in slash-star comments */
+ char *dolqstart; /* current $foo$ quote start string */
+
+ /*
+ * Callback functions provided by the program making use of the lexer,
+ * plus a void* callback passthrough argument.
+ */
+ const PsqlScanCallbacks *callbacks;
+ void *cb_passthrough;
+} PsqlScanStateData;
+
+
+/*
+ * Functions exported by psqlscan.l, but only meant for use within
+ * compatible lexers.
+ */
+extern void psqlscan_push_new_buffer(PsqlScanState state,
+ const char *newstr, const char *varname);
+extern void psqlscan_pop_buffer_stack(PsqlScanState state);
+extern void psqlscan_select_top_buffer(PsqlScanState state);
+extern bool psqlscan_var_is_current_source(PsqlScanState state,
+ const char *varname);
+extern YY_BUFFER_STATE psqlscan_prepare_buffer(PsqlScanState state,
+ const char *txt, int len,
+ char **txtcopy);
+extern void psqlscan_emit(PsqlScanState state, const char *txt, int len);
+extern char *psqlscan_extract_substring(PsqlScanState state,
+ const char *txt, int len);
+extern void psqlscan_escape_variable(PsqlScanState state,
+ const char *txt, int len,
+ PsqlScanQuoteType quote);
+extern void psqlscan_test_variable(PsqlScanState state,
+ const char *txt, int len);
+
+#endif /* PSQLSCAN_INT_H */
diff --git a/src/include/fe_utils/recovery_gen.h b/src/include/fe_utils/recovery_gen.h
new file mode 100644
index 0000000..c8655cd
--- /dev/null
+++ b/src/include/fe_utils/recovery_gen.h
@@ -0,0 +1,28 @@
+/*-------------------------------------------------------------------------
+ *
+ * Generator for recovery configuration
+ *
+ * Portions Copyright (c) 2011-2020, PostgreSQL Global Development Group
+ *
+ * src/include/fe_utils/recovery_gen.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef RECOVERY_GEN_H
+#define RECOVERY_GEN_H
+
+#include "libpq-fe.h"
+#include "pqexpbuffer.h"
+
+/*
+ * recovery configuration is part of postgresql.conf in version 12 and up, and
+ * in recovery.conf before that.
+ */
+#define MINIMUM_VERSION_FOR_RECOVERY_GUC 120000
+
+extern PQExpBuffer GenerateRecoveryConfig(PGconn *pgconn,
+ char *pg_replication_slot);
+extern void WriteRecoveryConfig(PGconn *pgconn, char *target_dir,
+ PQExpBuffer contents);
+
+#endif /* RECOVERY_GEN_H */
diff --git a/src/include/fe_utils/simple_list.h b/src/include/fe_utils/simple_list.h
new file mode 100644
index 0000000..db04e67
--- /dev/null
+++ b/src/include/fe_utils/simple_list.h
@@ -0,0 +1,70 @@
+/*-------------------------------------------------------------------------
+ *
+ * Simple list facilities for frontend code
+ *
+ * Data structures for simple lists of OIDs, strings, and pointers. The
+ * support for these is very primitive compared to the backend's List
+ * facilities, but it's all we need in, eg, pg_dump.
+ *
+ *
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/fe_utils/simple_list.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef SIMPLE_LIST_H
+#define SIMPLE_LIST_H
+
+typedef struct SimpleOidListCell
+{
+ struct SimpleOidListCell *next;
+ Oid val;
+} SimpleOidListCell;
+
+typedef struct SimpleOidList
+{
+ SimpleOidListCell *head;
+ SimpleOidListCell *tail;
+} SimpleOidList;
+
+typedef struct SimpleStringListCell
+{
+ struct SimpleStringListCell *next;
+ bool touched; /* true, when this string was searched and
+ * touched */
+ char val[FLEXIBLE_ARRAY_MEMBER]; /* null-terminated string here */
+} SimpleStringListCell;
+
+typedef struct SimpleStringList
+{
+ SimpleStringListCell *head;
+ SimpleStringListCell *tail;
+} SimpleStringList;
+
+typedef struct SimplePtrListCell
+{
+ struct SimplePtrListCell *next;
+ void *ptr;
+} SimplePtrListCell;
+
+typedef struct SimplePtrList
+{
+ SimplePtrListCell *head;
+ SimplePtrListCell *tail;
+} SimplePtrList;
+
+extern void simple_oid_list_append(SimpleOidList *list, Oid val);
+extern bool simple_oid_list_member(SimpleOidList *list, Oid val);
+extern void simple_oid_list_destroy(SimpleOidList *list);
+
+extern void simple_string_list_append(SimpleStringList *list, const char *val);
+extern bool simple_string_list_member(SimpleStringList *list, const char *val);
+extern void simple_string_list_destroy(SimpleStringList *list);
+
+extern const char *simple_string_list_not_touched(SimpleStringList *list);
+
+extern void simple_ptr_list_append(SimplePtrList *list, void *val);
+
+#endif /* SIMPLE_LIST_H */
diff --git a/src/include/fe_utils/string_utils.h b/src/include/fe_utils/string_utils.h
new file mode 100644
index 0000000..5924d32
--- /dev/null
+++ b/src/include/fe_utils/string_utils.h
@@ -0,0 +1,59 @@
+/*-------------------------------------------------------------------------
+ *
+ * String-processing utility routines for frontend code
+ *
+ * Utility functions that interpret backend output or quote strings for
+ * assorted contexts.
+ *
+ *
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/fe_utils/string_utils.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef STRING_UTILS_H
+#define STRING_UTILS_H
+
+#include "libpq-fe.h"
+#include "pqexpbuffer.h"
+
+/* Global variables controlling behavior of fmtId() and fmtQualifiedId() */
+extern int quote_all_identifiers;
+extern PQExpBuffer (*getLocalPQExpBuffer) (void);
+
+/* Functions */
+extern const char *fmtId(const char *identifier);
+extern const char *fmtQualifiedId(const char *schema, const char *id);
+
+extern char *formatPGVersionNumber(int version_number, bool include_minor,
+ char *buf, size_t buflen);
+
+extern void appendStringLiteral(PQExpBuffer buf, const char *str,
+ int encoding, bool std_strings);
+extern void appendStringLiteralConn(PQExpBuffer buf, const char *str,
+ PGconn *conn);
+extern void appendStringLiteralDQ(PQExpBuffer buf, const char *str,
+ const char *dqprefix);
+extern void appendByteaLiteral(PQExpBuffer buf,
+ const unsigned char *str, size_t length,
+ bool std_strings);
+
+extern void appendShellString(PQExpBuffer buf, const char *str);
+extern bool appendShellStringNoError(PQExpBuffer buf, const char *str);
+extern void appendConnStrVal(PQExpBuffer buf, const char *str);
+extern void appendPsqlMetaConnect(PQExpBuffer buf, const char *dbname);
+
+extern bool parsePGArray(const char *atext, char ***itemarray, int *nitems);
+
+extern bool appendReloptionsArray(PQExpBuffer buffer, const char *reloptions,
+ const char *prefix, int encoding, bool std_strings);
+
+extern bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf,
+ const char *pattern,
+ bool have_where, bool force_escape,
+ const char *schemavar, const char *namevar,
+ const char *altnamevar, const char *visibilityrule);
+
+#endif /* STRING_UTILS_H */