📄 guc-file.c
字号:
char *buf; GUC_yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = len + 2; buf = (char *) GUC_yy_flex_alloc( n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in GUC_yy_scan_bytes()" ); for ( i = 0; i < len; ++i ) buf[i] = bytes[i]; buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; b = GUC_yy_scan_buffer( buf, n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in GUC_yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->GUC_yy_is_our_buffer = 1; return b; }#endif#ifndef YY_NO_PUSH_STATE#ifdef YY_USE_PROTOSstatic void GUC_yy_push_state( int new_state )#elsestatic void GUC_yy_push_state( new_state )int new_state;#endif { if ( GUC_yy_start_stack_ptr >= GUC_yy_start_stack_depth ) { GUC_yy_size_t new_size; GUC_yy_start_stack_depth += YY_START_STACK_INCR; new_size = GUC_yy_start_stack_depth * sizeof( int ); if ( ! GUC_yy_start_stack ) GUC_yy_start_stack = (int *) GUC_yy_flex_alloc( new_size ); else GUC_yy_start_stack = (int *) GUC_yy_flex_realloc( (void *) GUC_yy_start_stack, new_size ); if ( ! GUC_yy_start_stack ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } GUC_yy_start_stack[GUC_yy_start_stack_ptr++] = YY_START; BEGIN(new_state); }#endif#ifndef YY_NO_POP_STATEstatic void GUC_yy_pop_state() { if ( --GUC_yy_start_stack_ptr < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); BEGIN(GUC_yy_start_stack[GUC_yy_start_stack_ptr]); }#endif#ifndef YY_NO_TOP_STATEstatic int GUC_yy_top_state() { return GUC_yy_start_stack[GUC_yy_start_stack_ptr - 1]; }#endif#ifndef YY_EXIT_FAILURE#define YY_EXIT_FAILURE 2#endif#ifdef YY_USE_PROTOSstatic void GUC_yy_fatal_error( GUC_yyconst char msg[] )#elsestatic void GUC_yy_fatal_error( msg )char msg[];#endif { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); }/* Redefine GUC_yyless() so it works in section 3 code. */#undef GUC_yyless#define GUC_yyless(n) \ do \ { \ /* Undo effects of setting up GUC_yytext. */ \ GUC_yytext[GUC_yyleng] = GUC_yy_hold_char; \ GUC_yy_c_buf_p = GUC_yytext + n; \ GUC_yy_hold_char = *GUC_yy_c_buf_p; \ *GUC_yy_c_buf_p = '\0'; \ GUC_yyleng = n; \ } \ while ( 0 )/* Internal utility routines. */#ifndef GUC_yytext_ptr#ifdef YY_USE_PROTOSstatic void GUC_yy_flex_strncpy( char *s1, GUC_yyconst char *s2, int n )#elsestatic void GUC_yy_flex_strncpy( s1, s2, n )char *s1;GUC_yyconst char *s2;int n;#endif { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; }#endif#ifdef YY_NEED_STRLEN#ifdef YY_USE_PROTOSstatic int GUC_yy_flex_strlen( GUC_yyconst char *s )#elsestatic int GUC_yy_flex_strlen( s )GUC_yyconst char *s;#endif { register int n; for ( n = 0; s[n]; ++n ) ; return n; }#endif#ifdef YY_USE_PROTOSstatic void *GUC_yy_flex_alloc( GUC_yy_size_t size )#elsestatic void *GUC_yy_flex_alloc( size )GUC_yy_size_t size;#endif { return (void *) malloc( size ); }#ifdef YY_USE_PROTOSstatic void *GUC_yy_flex_realloc( void *ptr, GUC_yy_size_t size )#elsestatic void *GUC_yy_flex_realloc( ptr, size )void *ptr;GUC_yy_size_t size;#endif { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); }#ifdef YY_USE_PROTOSstatic void GUC_yy_flex_free( void *ptr )#elsestatic void GUC_yy_flex_free( ptr )void *ptr;#endif { free( ptr ); }#if YY_MAINint main() { GUC_yylex(); return 0; }#endif#line 85 "guc-file.l"struct name_value_pair{ char *name; char *value; struct name_value_pair *next;};/* * Free a list of name/value pairs, including the names and the values */static voidfree_name_value_list(struct name_value_pair * list){ struct name_value_pair *item; item = list; while (item) { struct name_value_pair *save; save = item->next; pfree(item->name); pfree(item->value); pfree(item); item = save; }}/* * Official function to read and process the configuration file. The * parameter indicates in what context the file is being read --- either * postmaster startup (including standalone-backend startup) or SIGHUP. * All options mentioned in the configuration file are set to new values. * If an error occurs, no values will be changed. */voidProcessConfigFile(GucContext context){ int elevel; int token; char *opt_name, *opt_value; struct name_value_pair *item, *head, *tail; FILE *fp; Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP); if (context == PGC_SIGHUP) { /* * To avoid cluttering the log, only the postmaster bleats loudly * about problems with the config file. */ elevel = IsUnderPostmaster ? DEBUG2 : LOG; } else elevel = ERROR; fp = AllocateFile(ConfigFileName, "r"); if (!fp) { ereport(elevel, (errcode_for_file_access(), errmsg("could not open configuration file \"%s\": %m", ConfigFileName))); return; } /* * Parse */ GUC_yyrestart(fp); head = tail = NULL; opt_name = opt_value = NULL; ConfigFileLineno = 1; /* This loop iterates once per logical line */ while ((token = GUC_yylex())) { if (token == GUC_EOL) /* empty or comment line */ continue; /* first token on line is option name */ if (token != GUC_ID && token != GUC_QUALIFIED_ID) goto parse_error; opt_name = pstrdup(GUC_yytext); /* next we have an optional equal sign; discard if present */ token = GUC_yylex(); if (token == GUC_EQUALS) token = GUC_yylex(); /* now we must have the option value */ if (token != GUC_ID && token != GUC_STRING && token != GUC_INTEGER && token != GUC_REAL && token != GUC_UNQUOTED_STRING) goto parse_error; if (token == GUC_STRING) /* strip quotes and escapes */ opt_value = GUC_scanstr(GUC_yytext); else opt_value = pstrdup(GUC_yytext); /* now we'd like an end of line, or possibly EOF */ token = GUC_yylex(); if (token != GUC_EOL && token != 0) goto parse_error; /* OK, save the option name and value */ if (strcmp(opt_name, "custom_variable_classes") == 0) { /* * This variable must be processed first as it controls * the validity of other variables; so apply immediately. */ if (!set_config_option(opt_name, opt_value, context, PGC_S_FILE, false, true)) { pfree(opt_name); pfree(opt_value); FreeFile(fp); goto cleanup_exit; } pfree(opt_name); pfree(opt_value); } else { /* append to list */ item = palloc(sizeof *item); item->name = opt_name; item->value = opt_value; item->next = NULL; if (!head) head = item; else tail->next = item; tail = item; } /* break out of loop if read EOF, else loop for next line */ if (token == 0) break; } FreeFile(fp); /* * Check if all options are valid */ for(item = head; item; item=item->next) { if (!set_config_option(item->name, item->value, context, PGC_S_FILE, false, false)) goto cleanup_exit; } /* If we got here all the options parsed okay, so apply them. */ for(item = head; item; item=item->next) { set_config_option(item->name, item->value, context, PGC_S_FILE, false, true); } cleanup_exit: free_name_value_list(head); return; parse_error: FreeFile(fp); free_name_value_list(head); if (token == GUC_EOL || token == 0) ereport(elevel, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("syntax error in file \"%s\" line %u, near end of line", ConfigFileName, ConfigFileLineno - 1))); else ereport(elevel, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("syntax error in file \"%s\" line %u, near token \"%s\"", ConfigFileName, ConfigFileLineno, GUC_yytext)));}/* * scanstr * * Strip the quotes surrounding the given string, and collapse any embedded * '' sequences and backslash escapes. * * the string returned is palloc'd and should eventually be pfree'd by the * caller. */static char *GUC_scanstr(const char *s){ char *newStr; int len, i, j; Assert(s != NULL && s[0] == '\''); len = strlen(s); Assert(len >= 2); Assert(s[len-1] == '\''); /* Skip the leading quote; we'll handle the trailing quote below */ s++, len--; /* Since len still includes trailing quote, this is enough space */ newStr = palloc(len); for (i = 0, j = 0; i < len; i++) { if (s[i] == '\\') { i++; switch (s[i]) { case 'b': newStr[j] = '\b'; break; case 'f': newStr[j] = '\f'; break; case 'n': newStr[j] = '\n'; break; case 'r': newStr[j] = '\r'; break; case 't': newStr[j] = '\t'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': { int k; long octVal = 0; for (k = 0; s[i + k] >= '0' && s[i + k] <= '7' && k < 3; k++) octVal = (octVal << 3) + (s[i + k] - '0'); i += k - 1; newStr[j] = ((char) octVal); } break; default: newStr[j] = s[i]; break; } /* switch */ } else if (s[i] == '\'' && s[i+1] == '\'') { /* doubled quote becomes just one quote */ newStr[j] = s[++i]; } else newStr[j] = s[i]; j++; } /* We copied the ending quote to newStr, so replace with \0 */ Assert(j > 0 && j <= len); newStr[--j] = '\0'; return newStr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -