Re: Syslog Facility Patch - Mailing list pgsql-hackers
From | Larry Rosenman |
---|---|
Subject | Re: Syslog Facility Patch |
Date | |
Msg-id | 20001115121633.A11558@lerami.lerctr.org Whole thread Raw |
In response to | Re: Syslog Facility Patch (Peter Eisentraut <peter_e@gmx.net>) |
Responses |
Re: Syslog Facility Patch
|
List | pgsql-hackers |
* Peter Eisentraut <peter_e@gmx.net> [001115 10:26]: > Larry Rosenman writes: > > > Ok, so what I think(?) needs to happen is the FIXME: tag needs to be > > handled. We need to code a version of src/backend/parser/scansup.c > > that doesn't use palloc, and also strips the apostrophes from the > > front and end of the string? This doesn't look that hard. Do I have > > "permission" to play with it, and submit a patch when I've got it > > fixed? > > Some background information: The current > > name = value > > syntax is lexically compatible with the syntax of the SET command. > Therefore you can't have "funny" characters in 'value' unless > single-quoted. I added period(.), hyphen(-), and underscore(_). > > Now in the context of the config file this seems overly restrictive. > Therefore I'd agree that we relax that a bit and allow more characters to > go into 'value' unquoted. I'm not quite sure which, but to prevent > confusion I'd prefer no semicolons, whitespace, or equal signs, possibly > others. > > This would require making 'value' a different token type from 'name', > because the latter should not accept these characters. done, as GUC_UNQUOTED_STRING. > > Additionally, the FIXME ought to be done. I'd prefer it if it accepted > the exact same escapes and all as does the SQL parser/scanner. So it > ought to be a copy and paste from scansup.c. I'm not excited about > allowing double-quotes though. Done. Added as GUC_scanstr. Here is a patch. Comments? Index: src/backend/utils/misc/guc-file.l =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/utils/misc/guc-file.l,v retrieving revision 1.4 diff -c -r1.4 guc-file.l *** src/backend/utils/misc/guc-file.l 2000/07/27 19:49:18 1.4 --- src/backend/utils/misc/guc-file.l 2000/11/15 18:13:20 *************** *** 16,21 **** --- 16,22 ---- #include <sys/stat.h> #include <unistd.h> #include <errno.h> + #include <ctype.h> #include "miscadmin.h" #include "storage/fd.h" *************** *** 32,37 **** --- 33,39 ---- GUC_INTEGER = 3, GUC_REAL = 4, GUC_EQUALS = 5, + GUC_UNQUOTED_STRING = 6, GUC_EOL = 99, GUC_ERROR = 100 }; *************** *** 45,51 **** /* prototype, so compiler is happy with our high warnings setting */ int GUC_yylex(void); ! %} SIGN ("-"|"+") --- 47,53 ---- /* prototype, so compiler is happy with our high warnings setting */ int GUC_yylex(void); ! char *GUC_scanstr(char *); %} SIGN ("-"|"+") *************** *** 69,76 **** * work right. Now there are no string options, and if there were then * the unquoted (`ID') tokens shouldstill work. Of course this only * affects the configuration file. */ ! STRING \'([^'\n]|\\.)*' %% --- 71,83 ---- * work right. Now there are no string options, and if there were then * the unquoted (`ID') tokens shouldstill work. Of course this only * affects the configuration file. + * LER 14NOV2000: I set it up to accept either a quoted string or a string + * in apostrophes. I then kill off the 1st and last characters. There is + * no special handling for doubled terminators or 'C' escapes. + * this allows most other characters to be used. */ ! UNQUOTED_STRING {LETTER}({LETTER_OR_DIGIT}|[-._])* ! STRING (\'|\")([^'"\n]|\\.)*(\'|\") %% *************** *** 80,85 **** --- 87,93 ---- {ID} return GUC_ID; {STRING} return GUC_STRING; + {UNQUOTED_STRING} return GUC_UNQUOTED_STRING; {INTEGER} return GUC_INTEGER; {REAL} return GUC_REAL; = return GUC_EQUALS; *************** *** 210,220 **** if (token == GUC_EQUALS) token = yylex(); ! if (token != GUC_ID && token != GUC_STRING && token != GUC_INTEGER && token != GUC_REAL) goto parse_error; opt_value = strdup(yytext); if (opt_value == NULL) goto out_of_memory; parse_state = 2; break; --- 218,239 ---- if (token == GUC_EQUALS) token = yylex(); ! if (token != GUC_ID && token != GUC_STRING && token != GUC_INTEGER && token != GUC_REAL && token != GUC_UNQUOTED_STRING) goto parse_error; opt_value = strdup(yytext); if(opt_value == NULL) goto out_of_memory; + if (token == GUC_STRING) + { + /* remove the beginning and ending quote/apostrophe */ + /* first: shift the whole shooting match down one + character */ + memmove(opt_value,opt_value+1,strlen(opt_value)-1); + /* second: null out the 2 characters we shifted */ + opt_value[strlen(opt_value)-2]='\0'; + /* do the escape thing. free()'s the strdup above */ + opt_value=GUC_scanstr(opt_value); + } parse_state = 2; break; *************** *** 283,286 **** --- 302,400 ---- yywrap(void) { return 1; + } + + /* ---------------- + * scanstr + * + * if the string passed in has escaped codes, map the escape codes to actual + * chars + * + * the string returned is palloc'd and should eventually be pfree'd by the + * caller! + * ---------------- + */ + + char * + GUC_scanstr(char *s) + { + char *newStr; + int len, + i, + j; + + if (s == NULL || s[0] == '\0') + { + if (s != NULL) free (s); + return strdup(""); + + } + len = strlen(s); + + newStr = malloc(len + 1); /* string cannot get longer */ + + for (i = 0, j = 0; i < len; i++) + { + if (s[i] == '\'') + { + + /* + * Note: if scanner is working right, unescaped quotes can + * only appear in pairs, so there should be another character. + */ + i++; + newStr[j] = s[i]; + } + else 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 */ + } /* s[i] == '\\' */ + else + newStr[j] = s[i]; + j++; + } + newStr[j] = '\0'; + free(s); + return newStr; } -- Larry Rosenman http://www.lerctr.org/~ler Phone: +1 972-414-9812 (voice) Internet: ler@lerctr.org US Mail: 1905 Steamboat Springs Drive, Garland, TX 75044-6749
pgsql-hackers by date: