Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 350cb92

Browse files
committed
Restructure hba.c to replace 3 parallel lists with single list of structs.
tokenize_file() now returns a single list of TokenizedLine structs, carrying the same information as before. We were otherwise going to grow a fourth list to deal with error messages, and that was getting a bit silly. Haribabu Kommi, revised a bit by me Discussion: https://postgr.es/m/CAJrrPGfbgbKsjYp=bgZXhMcgxoaGSoBb9fyjrDoOW_YymXv1Kw@mail.gmail.com
1 parent fde5c03 commit 350cb92

File tree

1 file changed

+70
-64
lines changed

1 file changed

+70
-64
lines changed

src/backend/libpq/hba.c

Lines changed: 70 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ typedef struct check_network_data
6666
#define token_matches(t, k) (strcmp(t->string, k) == 0)
6767

6868
/*
69-
* A single string token lexed from the HBA config file, together with whether
69+
* A single string token lexed from a config file, together with whether
7070
* the token had been quoted.
7171
*/
7272
typedef struct HbaToken
@@ -75,6 +75,19 @@ typedef struct HbaToken
7575
bool quoted;
7676
} HbaToken;
7777

78+
/*
79+
* TokenizedLine represents one line lexed from a config file.
80+
* Each item in the "fields" list is a sub-list of HbaTokens.
81+
* We don't emit a TokenizedLine for empty or all-comment lines,
82+
* so "fields" is never NIL (nor are any of its sub-lists).
83+
*/
84+
typedef struct TokenizedLine
85+
{
86+
List *fields; /* List of lists of HbaTokens */
87+
int line_num; /* Line number */
88+
char *raw_line; /* Raw line text */
89+
} TokenizedLine;
90+
7891
/*
7992
* pre-parsed content of HBA config file: list of HbaLine structs.
8093
* parsed_hba_context is the memory context where it lives.
@@ -95,7 +108,7 @@ static MemoryContext parsed_ident_context = NULL;
95108

96109

97110
static MemoryContext tokenize_file(const char *filename, FILE *file,
98-
List **lines, List **line_nums, List **raw_lines);
111+
List **tok_lines);
99112
static List *tokenize_inc_file(List *tokens, const char *outer_filename,
100113
const char *inc_filename);
101114
static bool parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline,
@@ -305,7 +318,6 @@ tokenize_inc_file(List *tokens,
305318
char *inc_fullname;
306319
FILE *inc_file;
307320
List *inc_lines;
308-
List *inc_line_nums;
309321
ListCell *inc_line;
310322
MemoryContext linecxt;
311323

@@ -337,17 +349,18 @@ tokenize_inc_file(List *tokens,
337349
}
338350

339351
/* There is possible recursion here if the file contains @ */
340-
linecxt = tokenize_file(inc_fullname, inc_file, &inc_lines, &inc_line_nums, NULL);
352+
linecxt = tokenize_file(inc_fullname, inc_file, &inc_lines);
341353

342354
FreeFile(inc_file);
343355
pfree(inc_fullname);
344356

357+
/* Copy all tokens found in the file and append to the tokens list */
345358
foreach(inc_line, inc_lines)
346359
{
347-
List *inc_fields = lfirst(inc_line);
360+
TokenizedLine *tok_line = (TokenizedLine *) lfirst(inc_line);
348361
ListCell *inc_field;
349362

350-
foreach(inc_field, inc_fields)
363+
foreach(inc_field, tok_line->fields)
351364
{
352365
List *inc_tokens = lfirst(inc_field);
353366
ListCell *inc_token;
@@ -366,23 +379,18 @@ tokenize_inc_file(List *tokens,
366379
}
367380

368381
/*
369-
* Tokenize the given file, storing the resulting data into three Lists: a
370-
* List of lines, a List of line numbers, and a List of raw line contents.
382+
* Tokenize the given file.
371383
*
372-
* The list of lines is a triple-nested List structure. Each line is a List of
373-
* fields, and each field is a List of HbaTokens.
384+
* The output is a list of TokenizedLine structs; see struct definition above.
374385
*
375386
* filename must be the absolute path to the target file.
376387
*
377388
* Return value is a memory context which contains all memory allocated by
378-
* this function.
389+
* this function (it's a child of caller's context).
379390
*/
380391
static MemoryContext
381-
tokenize_file(const char *filename, FILE *file,
382-
List **lines, List **line_nums, List **raw_lines)
392+
tokenize_file(const char *filename, FILE *file, List **tok_lines)
383393
{
384-
List *current_line = NIL;
385-
List *current_field = NIL;
386394
int line_number = 1;
387395
MemoryContext linecxt;
388396
MemoryContext oldcxt;
@@ -392,12 +400,13 @@ tokenize_file(const char *filename, FILE *file,
392400
ALLOCSET_SMALL_SIZES);
393401
oldcxt = MemoryContextSwitchTo(linecxt);
394402

395-
*lines = *line_nums = NIL;
403+
*tok_lines = NIL;
396404

397405
while (!feof(file) && !ferror(file))
398406
{
399407
char rawline[MAX_LINE];
400408
char *lineptr;
409+
List *current_line = NIL;
401410

402411
if (!fgets(rawline, sizeof(rawline), file))
403412
break;
@@ -414,32 +423,30 @@ tokenize_file(const char *filename, FILE *file,
414423
while (lineptr >= rawline && (*lineptr == '\n' || *lineptr == '\r'))
415424
*lineptr-- = '\0';
416425

426+
/* Parse fields */
417427
lineptr = rawline;
418-
while (strlen(lineptr) > 0)
428+
while (*lineptr)
419429
{
430+
List *current_field;
431+
420432
current_field = next_field_expand(filename, &lineptr);
433+
/* add field to line, unless we are at EOL or comment start */
434+
if (current_field != NIL)
435+
current_line = lappend(current_line, current_field);
436+
}
421437

422-
/* add tokens to list, unless we are at EOL or comment start */
423-
if (list_length(current_field) > 0)
424-
{
425-
if (current_line == NIL)
426-
{
427-
/* make a new line List, record its line number */
428-
current_line = lappend(current_line, current_field);
429-
*lines = lappend(*lines, current_line);
430-
*line_nums = lappend_int(*line_nums, line_number);
431-
if (raw_lines)
432-
*raw_lines = lappend(*raw_lines, pstrdup(rawline));
433-
}
434-
else
435-
{
436-
/* append tokens to current line's list */
437-
current_line = lappend(current_line, current_field);
438-
}
439-
}
438+
/* Reached EOL; emit line to TokenizedLine list unless it's boring */
439+
if (current_line != NIL)
440+
{
441+
TokenizedLine *tok_line;
442+
443+
tok_line = (TokenizedLine *) palloc(sizeof(TokenizedLine));
444+
tok_line->fields = current_line;
445+
tok_line->line_num = line_number;
446+
tok_line->raw_line = pstrdup(rawline);
447+
*tok_lines = lappend(*tok_lines, tok_line);
440448
}
441-
/* we are at real or logical EOL, so force a new line List */
442-
current_line = NIL;
449+
443450
line_number++;
444451
}
445452

@@ -789,7 +796,7 @@ check_same_host_or_net(SockAddr *raddr, IPCompareMethod method)
789796
ereport(LOG, \
790797
(errcode(ERRCODE_CONFIG_FILE_ERROR), \
791798
errmsg("missing entry in file \"%s\" at end of line %d", \
792-
IdentFileName, line_number))); \
799+
IdentFileName, line_num))); \
793800
return NULL; \
794801
} \
795802
} while (0);
@@ -800,26 +807,26 @@ check_same_host_or_net(SockAddr *raddr, IPCompareMethod method)
800807
(errcode(ERRCODE_CONFIG_FILE_ERROR), \
801808
errmsg("multiple values in ident field"), \
802809
errcontext("line %d of configuration file \"%s\"", \
803-
line_number, IdentFileName))); \
810+
line_num, IdentFileName))); \
804811
return NULL; \
805812
} \
806813
} while (0);
807814

808815

809816
/*
810817
* Parse one tokenised line from the hba config file and store the result in a
811-
* HbaLine structure, or NULL if parsing fails.
818+
* HbaLine structure.
812819
*
813-
* The tokenised line is a List of fields, each field being a List of
814-
* HbaTokens.
820+
* Return NULL if parsing fails.
815821
*
816822
* Note: this function leaks memory when an error occurs. Caller is expected
817823
* to have set a memory context that will be reset if this function returns
818824
* NULL.
819825
*/
820826
static HbaLine *
821-
parse_hba_line(List *line, int line_num, char *raw_line)
827+
parse_hba_line(TokenizedLine *tok_line)
822828
{
829+
int line_num = tok_line->line_num;
823830
char *str;
824831
struct addrinfo *gai_result;
825832
struct addrinfo hints;
@@ -834,10 +841,11 @@ parse_hba_line(List *line, int line_num, char *raw_line)
834841

835842
parsedline = palloc0(sizeof(HbaLine));
836843
parsedline->linenumber = line_num;
837-
parsedline->rawline = pstrdup(raw_line);
844+
parsedline->rawline = pstrdup(tok_line->raw_line);
838845

839846
/* Check the record type. */
840-
field = list_head(line);
847+
Assert(tok_line->fields != NIL);
848+
field = list_head(tok_line->fields);
841849
tokens = lfirst(field);
842850
if (tokens->length > 1)
843851
{
@@ -1769,11 +1777,7 @@ load_hba(void)
17691777
{
17701778
FILE *file;
17711779
List *hba_lines = NIL;
1772-
List *hba_line_nums = NIL;
1773-
List *hba_raw_lines = NIL;
1774-
ListCell *line,
1775-
*line_num,
1776-
*raw_line;
1780+
ListCell *line;
17771781
List *new_parsed_lines = NIL;
17781782
bool ok = true;
17791783
MemoryContext linecxt;
@@ -1790,7 +1794,7 @@ load_hba(void)
17901794
return false;
17911795
}
17921796

1793-
linecxt = tokenize_file(HbaFileName, file, &hba_lines, &hba_line_nums, &hba_raw_lines);
1797+
linecxt = tokenize_file(HbaFileName, file, &hba_lines);
17941798
FreeFile(file);
17951799

17961800
/* Now parse all the lines */
@@ -1799,11 +1803,12 @@ load_hba(void)
17991803
"hba parser context",
18001804
ALLOCSET_SMALL_SIZES);
18011805
oldcxt = MemoryContextSwitchTo(hbacxt);
1802-
forthree(line, hba_lines, line_num, hba_line_nums, raw_line, hba_raw_lines)
1806+
foreach(line, hba_lines)
18031807
{
1808+
TokenizedLine *tok_line = (TokenizedLine *) lfirst(line);
18041809
HbaLine *newline;
18051810

1806-
if ((newline = parse_hba_line(lfirst(line), lfirst_int(line_num), lfirst(raw_line))) == NULL)
1811+
if ((newline = parse_hba_line(tok_line)) == NULL)
18071812
{
18081813
/*
18091814
* Parse error in the file, so indicate there's a problem. NB: a
@@ -1861,9 +1866,9 @@ load_hba(void)
18611866

18621867
/*
18631868
* Parse one tokenised line from the ident config file and store the result in
1864-
* an IdentLine structure, or NULL if parsing fails.
1869+
* an IdentLine structure.
18651870
*
1866-
* The tokenised line is a nested List of fields and tokens.
1871+
* Return NULL if parsing fails.
18671872
*
18681873
* If ident_user is a regular expression (ie. begins with a slash), it is
18691874
* compiled and stored in IdentLine structure.
@@ -1873,18 +1878,19 @@ load_hba(void)
18731878
* NULL.
18741879
*/
18751880
static IdentLine *
1876-
parse_ident_line(List *line, int line_number)
1881+
parse_ident_line(TokenizedLine *tok_line)
18771882
{
1883+
int line_num = tok_line->line_num;
18781884
ListCell *field;
18791885
List *tokens;
18801886
HbaToken *token;
18811887
IdentLine *parsedline;
18821888

1883-
Assert(line != NIL);
1884-
field = list_head(line);
1889+
Assert(tok_line->fields != NIL);
1890+
field = list_head(tok_line->fields);
18851891

18861892
parsedline = palloc0(sizeof(IdentLine));
1887-
parsedline->linenumber = line_number;
1893+
parsedline->linenumber = line_num;
18881894

18891895
/* Get the map token (must exist) */
18901896
tokens = lfirst(field);
@@ -2144,9 +2150,7 @@ load_ident(void)
21442150
{
21452151
FILE *file;
21462152
List *ident_lines = NIL;
2147-
List *ident_line_nums = NIL;
21482153
ListCell *line_cell,
2149-
*num_cell,
21502154
*parsed_line_cell;
21512155
List *new_parsed_lines = NIL;
21522156
bool ok = true;
@@ -2166,7 +2170,7 @@ load_ident(void)
21662170
return false;
21672171
}
21682172

2169-
linecxt = tokenize_file(IdentFileName, file, &ident_lines, &ident_line_nums, NULL);
2173+
linecxt = tokenize_file(IdentFileName, file, &ident_lines);
21702174
FreeFile(file);
21712175

21722176
/* Now parse all the lines */
@@ -2175,9 +2179,11 @@ load_ident(void)
21752179
"ident parser context",
21762180
ALLOCSET_SMALL_SIZES);
21772181
oldcxt = MemoryContextSwitchTo(ident_context);
2178-
forboth(line_cell, ident_lines, num_cell, ident_line_nums)
2182+
foreach(line_cell, ident_lines)
21792183
{
2180-
if ((newline = parse_ident_line(lfirst(line_cell), lfirst_int(num_cell))) == NULL)
2184+
TokenizedLine *tok_line = (TokenizedLine *) lfirst(line_cell);
2185+
2186+
if ((newline = parse_ident_line(tok_line)) == NULL)
21812187
{
21822188
/*
21832189
* Parse error in the file, so indicate there's a problem. Free

0 commit comments

Comments
 (0)