PostgreSQL Source Code git master
guc-file.l
Go to the documentation of this file.
1%top{
2/*
3 * Scanner for the configuration file
4 *
5 * Copyright (c) 2000-2025, PostgreSQL Global Development Group
6 *
7 * src/backend/utils/misc/guc-file.l
8 */
9
10#include "postgres.h"
11
12#include <ctype.h>
13#include <unistd.h>
14
15#include "common/file_utils.h"
16#include "guc_internal.h"
17#include "mb/pg_wchar.h"
18#include "miscadmin.h"
19#include "storage/fd.h"
20#include "utils/conffiles.h"
21#include "utils/memutils.h"
22}
23
24
25%{
26/*
27 * flex emits a yy_fatal_error() function that it calls in response to
28 * critical errors like malloc failure, file I/O errors, and detection of
29 * internal inconsistency. That function prints a message and calls exit().
30 * Mutate it to instead call our handler, which jumps out of the parser.
31 */
32#undef fprintf
33#define fprintf(file, fmt, msg) GUC_flex_fatal(msg)
34
35enum
36{
37 GUC_ID = 1,
44 GUC_EOL = 99,
45 GUC_ERROR = 100
46};
47
48static unsigned int ConfigFileLineno;
49static const char *GUC_flex_fatal_errmsg;
50static sigjmp_buf *GUC_flex_fatal_jmp;
51
52static void FreeConfigVariable(ConfigVariable *item);
53
54static int GUC_flex_fatal(const char *msg);
55
56/* LCOV_EXCL_START */
57
static sigjmp_buf * GUC_flex_fatal_jmp
Definition: guc-file.l:50
static unsigned int ConfigFileLineno
Definition: guc-file.l:48
static int GUC_flex_fatal(const char *msg)
Definition: guc-file.l:311
@ GUC_STRING
Definition: guc-file.l:38
@ GUC_UNQUOTED_STRING
Definition: guc-file.l:42
@ GUC_ERROR
Definition: guc-file.l:45
@ GUC_INTEGER
Definition: guc-file.l:39
@ GUC_QUALIFIED_ID
Definition: guc-file.l:43
@ GUC_REAL
Definition: guc-file.l:40
@ GUC_ID
Definition: guc-file.l:37
@ GUC_EOL
Definition: guc-file.l:44
@ GUC_EQUALS
Definition: guc-file.l:41
static void FreeConfigVariable(ConfigVariable *item)
Definition: guc-file.l:635
static const char * GUC_flex_fatal_errmsg
Definition: guc-file.l:49
58%}
59
60%option reentrant
61%option 8bit
62%option never-interactive
63%option nodefault
64%option noinput
65%option nounput
66%option noyywrap
67%option warn
68%option prefix="GUC_yy"
69
70
71SIGN ("-"|"+")
72DIGIT [0-9]
73HEXDIGIT [0-9a-fA-F]
74
75UNIT_LETTER [a-zA-Z]
76
77INTEGER {SIGN}?({DIGIT}+|0x{HEXDIGIT}+){UNIT_LETTER}*
78
79EXPONENT [Ee]{SIGN}?{DIGIT}+
80REAL {SIGN}?{DIGIT}*"."{DIGIT}*{EXPONENT}?
81
82LETTER [A-Za-z_\200-\377]
83LETTER_OR_DIGIT [A-Za-z_0-9\200-\377]
84
85ID {LETTER}{LETTER_OR_DIGIT}*
86QUALIFIED_ID {ID}"."{ID}
87
88UNQUOTED_STRING {LETTER}({LETTER_OR_DIGIT}|[-._:/])*
89STRING \'([^'\\\n]|\\.|\'\')*\'
90
91%%
92
93\n ConfigFileLineno++; return GUC_EOL;
94[ \t\r]+ /* eat whitespace */
95#.* /* eat comment (.* matches anything until newline) */
96
97{ID} return GUC_ID;
98{QUALIFIED_ID} return GUC_QUALIFIED_ID;
99{STRING} return GUC_STRING;
100{UNQUOTED_STRING} return GUC_UNQUOTED_STRING;
101{INTEGER} return GUC_INTEGER;
102{REAL} return GUC_REAL;
103= return GUC_EQUALS;
104
105. return GUC_ERROR;
106
107%%
108
109/* LCOV_EXCL_STOP */
110
111/*
112 * Exported function to read and process the configuration file. The
113 * parameter indicates in what context the file is being read --- either
114 * postmaster startup (including standalone-backend startup) or SIGHUP.
115 * All options mentioned in the configuration file are set to new values.
116 * If a hard error occurs, no values will be changed. (There can also be
117 * errors that prevent just one value from being changed.)
118 */
119void
121{
122 int elevel;
123 MemoryContext config_cxt;
124 MemoryContext caller_cxt;
125
126 /*
127 * Config files are processed on startup (by the postmaster only) and on
128 * SIGHUP (by the postmaster and its children)
129 */
130 Assert((context == PGC_POSTMASTER && !IsUnderPostmaster) ||
131 context == PGC_SIGHUP);
132
133 /*
134 * To avoid cluttering the log, only the postmaster bleats loudly about
135 * problems with the config file.
136 */
137 elevel = IsUnderPostmaster ? DEBUG2 : LOG;
138
139 /*
140 * This function is usually called within a process-lifespan memory
141 * context. To ensure that any memory leaked during GUC processing does
142 * not accumulate across repeated SIGHUP cycles, do the work in a private
143 * context that we can free at exit.
144 */
146 "config file processing",
148 caller_cxt = MemoryContextSwitchTo(config_cxt);
149
150 /*
151 * Read and apply the config file. We don't need to examine the result.
152 */
153 (void) ProcessConfigFileInternal(context, true, elevel);
154
155 /* Clean up */
156 MemoryContextSwitchTo(caller_cxt);
157 MemoryContextDelete(config_cxt);
158}
159
160/*
161 * Read and parse a single configuration file. This function recurses
162 * to handle "include" directives.
163 *
164 * If "strict" is true, treat failure to open the config file as an error,
165 * otherwise just skip the file.
166 *
167 * calling_file/calling_lineno identify the source of the request.
168 * Pass NULL/0 if not recursing from an inclusion request.
169 *
170 * See ParseConfigFp for further details. This one merely adds opening the
171 * config file rather than working from a caller-supplied file descriptor,
172 * and absolute-ifying the path name if necessary.
173 */
174bool
175ParseConfigFile(const char *config_file, bool strict,
176 const char *calling_file, int calling_lineno,
177 int depth, int elevel,
178 ConfigVariable **head_p,
179 ConfigVariable **tail_p)
180{
181 char *abs_path;
182 bool OK = true;
183 FILE *fp;
184
185 /*
186 * Reject file name that is all-blank (including empty), as that leads to
187 * confusion --- we'd try to read the containing directory as a file.
188 */
189 if (strspn(config_file, " \t\r\n") == strlen(config_file))
190 {
191 ereport(elevel,
192 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
193 errmsg("empty configuration file name: \"%s\"",
194 config_file)));
195 record_config_file_error("empty configuration file name",
196 calling_file, calling_lineno,
197 head_p, tail_p);
198 return false;
199 }
200
201 /*
202 * Reject too-deep include nesting depth. This is just a safety check to
203 * avoid dumping core due to stack overflow if an include file loops back
204 * to itself. The maximum nesting depth is pretty arbitrary.
205 */
206 if (depth > CONF_FILE_MAX_DEPTH)
207 {
208 ereport(elevel,
209 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
210 errmsg("could not open configuration file \"%s\": maximum nesting depth exceeded",
211 config_file)));
212 record_config_file_error("nesting depth exceeded",
213 calling_file, calling_lineno,
214 head_p, tail_p);
215 return false;
216 }
217
218 abs_path = AbsoluteConfigLocation(config_file, calling_file);
219
220 /*
221 * Reject direct recursion. Indirect recursion is also possible, but it's
222 * harder to detect and so doesn't seem worth the trouble. (We test at
223 * this step because the canonicalization done by AbsoluteConfigLocation
224 * makes it more likely that a simple strcmp comparison will match.)
225 */
226 if (calling_file && strcmp(abs_path, calling_file) == 0)
227 {
228 ereport(elevel,
229 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
230 errmsg("configuration file recursion in \"%s\"",
231 calling_file)));
232 record_config_file_error("configuration file recursion",
233 calling_file, calling_lineno,
234 head_p, tail_p);
235 pfree(abs_path);
236 return false;
237 }
238
239 fp = AllocateFile(abs_path, "r");
240 if (!fp)
241 {
242 if (strict)
243 {
244 ereport(elevel,
246 errmsg("could not open configuration file \"%s\": %m",
247 abs_path)));
248 record_config_file_error(psprintf("could not open file \"%s\"",
249 abs_path),
250 calling_file, calling_lineno,
251 head_p, tail_p);
252 OK = false;
253 }
254 else
255 {
256 ereport(LOG,
257 (errmsg("skipping missing configuration file \"%s\"",
258 abs_path)));
259 }
260 goto cleanup;
261 }
262
263 OK = ParseConfigFp(fp, abs_path, depth, elevel, head_p, tail_p);
264
265cleanup:
266 if (fp)
267 FreeFile(fp);
268 pfree(abs_path);
269
270 return OK;
271}
272
273/*
274 * Capture an error message in the ConfigVariable list returned by
275 * config file parsing.
276 */
277void
279 const char *config_file,
280 int lineno,
281 ConfigVariable **head_p,
282 ConfigVariable **tail_p)
283{
284 ConfigVariable *item;
285
286 item = palloc(sizeof *item);
287 item->name = NULL;
288 item->value = NULL;
289 item->errmsg = pstrdup(errmsg);
290 item->filename = config_file ? pstrdup(config_file) : NULL;
291 item->sourceline = lineno;
292 item->ignore = true;
293 item->applied = false;
294 item->next = NULL;
295 if (*head_p == NULL)
296 *head_p = item;
297 else
298 (*tail_p)->next = item;
299 *tail_p = item;
300}
301
302/*
303 * Flex fatal errors bring us here. Stash the error message and jump back to
304 * ParseConfigFp(). Assume all msg arguments point to string constants; this
305 * holds for all currently known flex versions. Otherwise, we would need to
306 * copy the message.
307 *
308 * We return "int" since this takes the place of calls to fprintf().
309*/
310static int
311GUC_flex_fatal(const char *msg)
312{
314 siglongjmp(*GUC_flex_fatal_jmp, 1);
315 return 0; /* keep compiler quiet */
316}
317
318/*
319 * Read and parse a single configuration file. This function recurses
320 * to handle "include" directives.
321 *
322 * Input parameters:
323 * fp: file pointer from AllocateFile for the configuration file to parse
324 * config_file: absolute or relative path name of the configuration file
325 * depth: recursion depth (should be CONF_FILE_START_DEPTH in the outermost
326 * call)
327 * elevel: error logging level to use
328 * Input/Output parameters:
329 * head_p, tail_p: head and tail of linked list of name/value pairs
330 *
331 * *head_p and *tail_p must be initialized, either to NULL or valid pointers
332 * to a ConfigVariable list, before calling the outer recursion level. Any
333 * name-value pairs read from the input file(s) will be appended to the list.
334 * Error reports will also be appended to the list, if elevel < ERROR.
335 *
336 * Returns TRUE if successful, FALSE if an error occurred. The error has
337 * already been ereport'd, it is only necessary for the caller to clean up
338 * its own state and release the ConfigVariable list.
339 *
340 * Note: if elevel >= ERROR then an error will not return control to the
341 * caller, so there is no need to check the return value in that case.
342 *
343 * Note: this function is used to parse not only postgresql.conf, but
344 * various other configuration files that use the same "name = value"
345 * syntax. Hence, do not do anything here or in the subsidiary routines
346 * ParseConfigFile/ParseConfigDirectory that assumes we are processing
347 * GUCs specifically.
348 */
349bool
350ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
351 ConfigVariable **head_p, ConfigVariable **tail_p)
352{
353 volatile bool OK = true;
354 unsigned int save_ConfigFileLineno = ConfigFileLineno;
355 sigjmp_buf *save_GUC_flex_fatal_jmp = GUC_flex_fatal_jmp;
356 sigjmp_buf flex_fatal_jmp;
357 yyscan_t scanner;
358 struct yyguts_t *yyg; /* needed for yytext macro */
359 volatile YY_BUFFER_STATE lex_buffer = NULL;
360 int errorcount;
361 int token;
362
363 if (sigsetjmp(flex_fatal_jmp, 1) == 0)
364 GUC_flex_fatal_jmp = &flex_fatal_jmp;
365 else
366 {
367 /*
368 * Regain control after a fatal, internal flex error. It may have
369 * corrupted parser state. Consequently, abandon the file, but trust
370 * that the state remains sane enough for yy_delete_buffer().
371 */
372 elog(elevel, "%s at file \"%s\" line %u",
376 head_p, tail_p);
377 OK = false;
378 goto cleanup;
379 }
380
381 /*
382 * Parse
383 */
385 errorcount = 0;
386
387 if (yylex_init(&scanner) != 0)
388 elog(elevel, "yylex_init() failed: %m");
389 yyg = (struct yyguts_t *) scanner;
390
391 lex_buffer = yy_create_buffer(fp, YY_BUF_SIZE, scanner);
392 yy_switch_to_buffer(lex_buffer, scanner);
393
394 /* This loop iterates once per logical line */
395 while ((token = yylex(scanner)))
396 {
397 char *opt_name = NULL;
398 char *opt_value = NULL;
399 ConfigVariable *item;
400
401 if (token == GUC_EOL) /* empty or comment line */
402 continue;
403
404 /* first token on line is option name */
405 if (token != GUC_ID && token != GUC_QUALIFIED_ID)
406 goto parse_error;
407 opt_name = pstrdup(yytext);
408
409 /* next we have an optional equal sign; discard if present */
410 token = yylex(scanner);
411 if (token == GUC_EQUALS)
412 token = yylex(scanner);
413
414 /* now we must have the option value */
415 if (token != GUC_ID &&
416 token != GUC_STRING &&
417 token != GUC_INTEGER &&
418 token != GUC_REAL &&
420 goto parse_error;
421 if (token == GUC_STRING) /* strip quotes and escapes */
422 opt_value = DeescapeQuotedString(yytext);
423 else
424 opt_value = pstrdup(yytext);
425
426 /* now we'd like an end of line, or possibly EOF */
427 token = yylex(scanner);
428 if (token != GUC_EOL)
429 {
430 if (token != 0)
431 goto parse_error;
432 /* treat EOF like \n for line numbering purposes, cf bug 4752 */
434 }
435
436 /* OK, process the option name and value */
437 if (guc_name_compare(opt_name, "include_dir") == 0)
438 {
439 /*
440 * An include_dir directive isn't a variable and should be
441 * processed immediately.
442 */
443 if (!ParseConfigDirectory(opt_value,
445 depth + 1, elevel,
446 head_p, tail_p))
447 OK = false;
448 yy_switch_to_buffer(lex_buffer, scanner);
449 pfree(opt_name);
450 pfree(opt_value);
451 }
452 else if (guc_name_compare(opt_name, "include_if_exists") == 0)
453 {
454 /*
455 * An include_if_exists directive isn't a variable and should be
456 * processed immediately.
457 */
458 if (!ParseConfigFile(opt_value, false,
460 depth + 1, elevel,
461 head_p, tail_p))
462 OK = false;
463 yy_switch_to_buffer(lex_buffer, scanner);
464 pfree(opt_name);
465 pfree(opt_value);
466 }
467 else if (guc_name_compare(opt_name, "include") == 0)
468 {
469 /*
470 * An include directive isn't a variable and should be processed
471 * immediately.
472 */
473 if (!ParseConfigFile(opt_value, true,
475 depth + 1, elevel,
476 head_p, tail_p))
477 OK = false;
478 yy_switch_to_buffer(lex_buffer, scanner);
479 pfree(opt_name);
480 pfree(opt_value);
481 }
482 else
483 {
484 /* ordinary variable, append to list */
485 item = palloc(sizeof *item);
486 item->name = opt_name;
487 item->value = opt_value;
488 item->errmsg = NULL;
490 item->sourceline = ConfigFileLineno - 1;
491 item->ignore = false;
492 item->applied = false;
493 item->next = NULL;
494 if (*head_p == NULL)
495 *head_p = item;
496 else
497 (*tail_p)->next = item;
498 *tail_p = item;
499 }
500
501 /* break out of loop if read EOF, else loop for next line */
502 if (token == 0)
503 break;
504 continue;
505
506parse_error:
507 /* release storage if we allocated any on this line */
508 if (opt_name)
509 pfree(opt_name);
510 if (opt_value)
511 pfree(opt_value);
512
513 /* report the error */
514 if (token == GUC_EOL || token == 0)
515 {
516 ereport(elevel,
517 (errcode(ERRCODE_SYNTAX_ERROR),
518 errmsg("syntax error in file \"%s\" line %u, near end of line",
520 record_config_file_error("syntax error",
522 head_p, tail_p);
523 }
524 else
525 {
526 ereport(elevel,
527 (errcode(ERRCODE_SYNTAX_ERROR),
528 errmsg("syntax error in file \"%s\" line %u, near token \"%s\"",
529 config_file, ConfigFileLineno, yytext)));
530 record_config_file_error("syntax error",
532 head_p, tail_p);
533 }
534 OK = false;
535 errorcount++;
536
537 /*
538 * To avoid producing too much noise when fed a totally bogus file,
539 * give up after 100 syntax errors per file (an arbitrary number).
540 * Also, if we're only logging the errors at DEBUG level anyway, might
541 * as well give up immediately. (This prevents postmaster children
542 * from bloating the logs with duplicate complaints.)
543 */
544 if (errorcount >= 100 || elevel <= DEBUG1)
545 {
546 ereport(elevel,
547 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
548 errmsg("too many syntax errors found, abandoning file \"%s\"",
549 config_file)));
550 break;
551 }
552
553 /* resync to next end-of-line or EOF */
554 while (token != GUC_EOL && token != 0)
555 token = yylex(scanner);
556 /* break out of loop on EOF */
557 if (token == 0)
558 break;
559 }
560
561cleanup:
562 yy_delete_buffer(lex_buffer, scanner);
563 yylex_destroy(scanner);
564 /* Each recursion level must save and restore these static variables. */
565 ConfigFileLineno = save_ConfigFileLineno;
566 GUC_flex_fatal_jmp = save_GUC_flex_fatal_jmp;
567 return OK;
568}
569
570/*
571 * Read and parse all config files in a subdirectory in alphabetical order
572 *
573 * includedir is the absolute or relative path to the subdirectory to scan.
574 *
575 * calling_file/calling_lineno identify the source of the request.
576 * Pass NULL/0 if not recursing from an inclusion request.
577 *
578 * See ParseConfigFp for further details.
579 */
580bool
581ParseConfigDirectory(const char *includedir,
582 const char *calling_file, int calling_lineno,
583 int depth, int elevel,
584 ConfigVariable **head_p,
585 ConfigVariable **tail_p)
586{
587 char *err_msg;
588 char **filenames;
589 int num_filenames;
590
591 filenames = GetConfFilesInDir(includedir, calling_file, elevel,
592 &num_filenames, &err_msg);
593
594 if (!filenames)
595 {
596 record_config_file_error(err_msg, calling_file, calling_lineno, head_p,
597 tail_p);
598 return false;
599 }
600
601 for (int i = 0; i < num_filenames; i++)
602 {
603 if (!ParseConfigFile(filenames[i], true,
604 calling_file, calling_lineno,
605 depth, elevel,
606 head_p, tail_p))
607 return false;
608 }
609
610 return true;
611}
612
613/*
614 * Free a list of ConfigVariables, including the names and the values
615 */
616void
618{
619 ConfigVariable *item;
620
621 item = list;
622 while (item)
623 {
624 ConfigVariable *next = item->next;
625
626 FreeConfigVariable(item);
627 item = next;
628 }
629}
630
631/*
632 * Free a single ConfigVariable
633 */
634static void
636{
637 if (item->name)
638 pfree(item->name);
639 if (item->value)
640 pfree(item->value);
641 if (item->errmsg)
642 pfree(item->errmsg);
643 if (item->filename)
644 pfree(item->filename);
645 pfree(item);
646}
647
648
649/*
650 * DeescapeQuotedString
651 *
652 * Strip the quotes surrounding the given string, and collapse any embedded
653 * '' sequences and backslash escapes.
654 *
655 * The string returned is palloc'd and should eventually be pfree'd by the
656 * caller.
657 *
658 * This is exported because it is also used by the bootstrap scanner.
659 */
660char *
662{
663 char *newStr;
664 int len,
665 i,
666 j;
667
668 /* We just Assert that there are leading and trailing quotes */
669 Assert(s != NULL && s[0] == '\'');
670 len = strlen(s);
671 Assert(len >= 2);
672 Assert(s[len - 1] == '\'');
673
674 /* Skip the leading quote; we'll handle the trailing quote below */
675 s++, len--;
676
677 /* Since len still includes trailing quote, this is enough space */
678 newStr = palloc(len);
679
680 for (i = 0, j = 0; i < len; i++)
681 {
682 if (s[i] == '\\')
683 {
684 i++;
685 switch (s[i])
686 {
687 case 'b':
688 newStr[j] = '\b';
689 break;
690 case 'f':
691 newStr[j] = '\f';
692 break;
693 case 'n':
694 newStr[j] = '\n';
695 break;
696 case 'r':
697 newStr[j] = '\r';
698 break;
699 case 't':
700 newStr[j] = '\t';
701 break;
702 case '0':
703 case '1':
704 case '2':
705 case '3':
706 case '4':
707 case '5':
708 case '6':
709 case '7':
710 {
711 int k;
712 long octVal = 0;
713
714 for (k = 0;
715 s[i + k] >= '0' && s[i + k] <= '7' && k < 3;
716 k++)
717 octVal = (octVal << 3) + (s[i + k] - '0');
718 i += k - 1;
719 newStr[j] = ((char) octVal);
720 }
721 break;
722 default:
723 newStr[j] = s[i];
724 break;
725 } /* switch */
726 }
727 else if (s[i] == '\'' && s[i + 1] == '\'')
728 {
729 /* doubled quote becomes just one quote */
730 newStr[j] = s[++i];
731 }
732 else
733 newStr[j] = s[i];
734 j++;
735 }
736
737 /* We copied the ending quote to newStr, so replace with \0 */
738 Assert(j > 0 && j <= len);
739 newStr[--j] = '\0';
740
741 return newStr;
742}
static int32 next
Definition: blutils.c:221
static void cleanup(void)
Definition: bootstrap.c:713
#define Assert(condition)
Definition: c.h:815
char * AbsoluteConfigLocation(const char *location, const char *calling_file)
Definition: conffiles.c:36
char ** GetConfFilesInDir(const char *includedir, const char *calling_file, int elevel, int *num_filenames, char **err_msg)
Definition: conffiles.c:70
#define CONF_FILE_MAX_DEPTH
Definition: conffiles.h:18
void * yyscan_t
Definition: cubedata.h:67
int errcode_for_file_access(void)
Definition: elog.c:876
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define LOG
Definition: elog.h:31
#define DEBUG2
Definition: elog.h:29
#define DEBUG1
Definition: elog.h:30
#define elog(elevel,...)
Definition: elog.h:225
#define ereport(elevel,...)
Definition: elog.h:149
int FreeFile(FILE *file)
Definition: fd.c:2803
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2605
bool IsUnderPostmaster
Definition: globals.c:119
void FreeConfigVariables(ConfigVariable *list)
Definition: guc-file.l:617
int yylex(yyscan_t yyscanner)
Definition: guc-file.l:91
void record_config_file_error(const char *errmsg, const char *config_file, int lineno, ConfigVariable **head_p, ConfigVariable **tail_p)
Definition: guc-file.l:278
bool ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel, ConfigVariable **head_p, ConfigVariable **tail_p)
Definition: guc-file.l:350
char * DeescapeQuotedString(const char *s)
Definition: guc-file.l:661
bool ParseConfigFile(const char *config_file, bool strict, const char *calling_file, int calling_lineno, int depth, int elevel, ConfigVariable **head_p, ConfigVariable **tail_p)
Definition: guc-file.l:175
bool ParseConfigDirectory(const char *includedir, const char *calling_file, int calling_lineno, int depth, int elevel, ConfigVariable **head_p, ConfigVariable **tail_p)
Definition: guc-file.l:581
void ProcessConfigFile(GucContext context)
Definition: guc-file.l:120
ConfigVariable * ProcessConfigFileInternal(GucContext context, bool applySettings, int elevel)
Definition: guc.c:282
int guc_name_compare(const char *namea, const char *nameb)
Definition: guc.c:1300
GucContext
Definition: guc.h:72
@ PGC_POSTMASTER
Definition: guc.h:74
@ PGC_SIGHUP
Definition: guc.h:75
#define token
Definition: indent_globs.h:126
int j
Definition: isn.c:73
int i
Definition: isn.c:72
char * pstrdup(const char *in)
Definition: mcxt.c:1696
void pfree(void *pointer)
Definition: mcxt.c:1521
void * palloc(Size size)
Definition: mcxt.c:1317
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
const void size_t len
static char * config_file
Definition: pg_rewind.c:71
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43
struct yy_buffer_state * YY_BUFFER_STATE
Definition: psqlscan_int.h:56
char * name
Definition: guc.h:141
bool ignore
Definition: guc.h:146
struct ConfigVariable * next
Definition: guc.h:148
bool applied
Definition: guc.h:147
char * filename
Definition: guc.h:144
int sourceline
Definition: guc.h:145
char * value
Definition: guc.h:142
char * errmsg
Definition: guc.h:143