1 /*-------------------------------------------------------------------------
2  *
3  * Simple list facilities for frontend code
4  *
5  * Data structures for simple lists of OIDs and strings.  The support for
6  * these is very primitive compared to the backend's List facilities, but
7  * it's all we need in, eg, pg_dump.
8  *
9  *
10  * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
11  * Portions Copyright (c) 1994, Regents of the University of California
12  *
13  * src/fe_utils/simple_list.c
14  *
15  *-------------------------------------------------------------------------
16  */
17 #include "postgres_fe.h"
18 
19 #include "fe_utils/simple_list.h"
20 
21 
22 /*
23  * Append an OID to the list.
24  */
25 void
simple_oid_list_append(SimpleOidList * list,Oid val)26 simple_oid_list_append(SimpleOidList *list, Oid val)
27 {
28 	SimpleOidListCell *cell;
29 
30 	cell = (SimpleOidListCell *) pg_malloc(sizeof(SimpleOidListCell));
31 	cell->next = NULL;
32 	cell->val = val;
33 
34 	if (list->tail)
35 		list->tail->next = cell;
36 	else
37 		list->head = cell;
38 	list->tail = cell;
39 }
40 
41 /*
42  * Is OID present in the list?
43  */
44 bool
simple_oid_list_member(SimpleOidList * list,Oid val)45 simple_oid_list_member(SimpleOidList *list, Oid val)
46 {
47 	SimpleOidListCell *cell;
48 
49 	for (cell = list->head; cell; cell = cell->next)
50 	{
51 		if (cell->val == val)
52 			return true;
53 	}
54 	return false;
55 }
56 
57 /*
58  * Append a string to the list.
59  *
60  * The given string is copied, so it need not survive past the call.
61  */
62 void
simple_string_list_append(SimpleStringList * list,const char * val)63 simple_string_list_append(SimpleStringList *list, const char *val)
64 {
65 	SimpleStringListCell *cell;
66 
67 	cell = (SimpleStringListCell *)
68 		pg_malloc(offsetof(SimpleStringListCell, val) + strlen(val) + 1);
69 
70 	cell->next = NULL;
71 	cell->touched = false;
72 	strcpy(cell->val, val);
73 
74 	if (list->tail)
75 		list->tail->next = cell;
76 	else
77 		list->head = cell;
78 	list->tail = cell;
79 }
80 
81 /*
82  * Is string present in the list?
83  *
84  * If found, the "touched" field of the first match is set true.
85  */
86 bool
simple_string_list_member(SimpleStringList * list,const char * val)87 simple_string_list_member(SimpleStringList *list, const char *val)
88 {
89 	SimpleStringListCell *cell;
90 
91 	for (cell = list->head; cell; cell = cell->next)
92 	{
93 		if (strcmp(cell->val, val) == 0)
94 		{
95 			cell->touched = true;
96 			return true;
97 		}
98 	}
99 	return false;
100 }
101 
102 /*
103  * Find first not-touched list entry, if there is one.
104  */
105 const char *
simple_string_list_not_touched(SimpleStringList * list)106 simple_string_list_not_touched(SimpleStringList *list)
107 {
108 	SimpleStringListCell *cell;
109 
110 	for (cell = list->head; cell; cell = cell->next)
111 	{
112 		if (!cell->touched)
113 			return cell->val;
114 	}
115 	return NULL;
116 }
117