1 #include "lib/mlr_globals.h"
2 #include "lib/mlrutil.h"
3 #include "lib/mlr_globals.h"
4 #include "containers/mixutil.h"
5 
6 // ----------------------------------------------------------------
7 // Makes a list with values pointing to the lrec's keys. slls_free() will
8 // respect that and not corrupt the lrec. However, the slls values will be
9 // invalid after the lrec is freed.
10 
mlr_reference_keys_from_record(lrec_t * prec)11 slls_t* mlr_reference_keys_from_record(lrec_t* prec) {
12 	slls_t* plist = slls_alloc();
13 	for (lrece_t* pe = prec->phead; pe != NULL; pe = pe->pnext) {
14 		slls_append_no_free(plist, pe->key);
15 	}
16 	return plist;
17 }
18 
mlr_copy_keys_from_record(lrec_t * prec)19 slls_t* mlr_copy_keys_from_record(lrec_t* prec) {
20 	slls_t* plist = slls_alloc();
21 	for (lrece_t* pe = prec->phead; pe != NULL; pe = pe->pnext) {
22 		slls_append_with_free(plist, mlr_strdup_or_die(pe->key));
23 	}
24 	return plist;
25 }
26 
mlr_reference_values_from_record(lrec_t * prec)27 slls_t* mlr_reference_values_from_record(lrec_t* prec) {
28 	slls_t* plist = slls_alloc();
29 	for (lrece_t* pe = prec->phead; pe != NULL; pe = pe->pnext) {
30 		slls_append_no_free(plist, pe->value);
31 	}
32 	return plist;
33 }
34 
mlr_reference_keys_from_record_except(lrec_t * prec,lrece_t * px)35 slls_t* mlr_reference_keys_from_record_except(lrec_t* prec, lrece_t* px) {
36 	slls_t* plist = slls_alloc();
37 	for (lrece_t* pe = prec->phead; pe != NULL; pe = pe->pnext) {
38 		if (pe != px)
39 			slls_append_no_free(plist, pe->key);
40 	}
41 	return plist;
42 }
43 
mlr_reference_values_from_record_except(lrec_t * prec,lrece_t * px)44 slls_t* mlr_reference_values_from_record_except(lrec_t* prec, lrece_t* px) {
45 	slls_t* plist = slls_alloc();
46 	for (lrece_t* pe = prec->phead; pe != NULL; pe = pe->pnext) {
47 		if (pe != px)
48 			slls_append_no_free(plist, pe->value);
49 	}
50 	return plist;
51 }
52 
53 // ----------------------------------------------------------------
54 // Makes a list with values pointing into the lrec's values. slls_free() will
55 // respect that and not corrupt the lrec. However, the slls values will be
56 // invalid after the lrec is freed.
57 
mlr_reference_selected_values_from_record(lrec_t * prec,slls_t * pselected_field_names)58 slls_t* mlr_reference_selected_values_from_record(lrec_t* prec, slls_t* pselected_field_names) {
59 	slls_t* pvalue_list = slls_alloc();
60 	for (sllse_t* pe = pselected_field_names->phead; pe != NULL; pe = pe->pnext) {
61 		char* selected_field_name = pe->value;
62 		char* value = lrec_get(prec, selected_field_name);
63 		if (value == NULL) {
64 			slls_free(pvalue_list);
65 			return NULL;
66 		} else {
67 			slls_append_no_free(pvalue_list, value);
68 		}
69 	}
70 	return pvalue_list;
71 }
72 
73 // Makes an array with values pointing into the lrec's values.
74 // string_array_free() will respect that and not corrupt the lrec. However,
75 // the array's values will be invalid after the lrec is freed.
76 
mlr_reference_values_from_record_into_string_array(lrec_t * prec,string_array_t * pselected_field_names,string_array_t * pvalues)77 void mlr_reference_values_from_record_into_string_array(lrec_t* prec, string_array_t* pselected_field_names,
78 	string_array_t* pvalues)
79 {
80 	MLR_INTERNAL_CODING_ERROR_IF(pselected_field_names->length != pvalues->length);
81 	pvalues->strings_need_freeing = FALSE;
82 	for (int i = 0; i < pselected_field_names->length; i++) {
83 		char* selected_field_name = pselected_field_names->strings[i];
84 		if (selected_field_name == NULL) {
85 			pvalues->strings[i] = NULL;
86 		} else {
87 			pvalues->strings[i] = lrec_get(prec, selected_field_name);
88 		}
89 
90 	}
91 }
92 
record_has_all_keys(lrec_t * prec,slls_t * pselected_field_names)93 int record_has_all_keys(lrec_t* prec, slls_t* pselected_field_names) {
94 	for (sllse_t* pe = pselected_field_names->phead; pe != NULL; pe = pe->pnext) {
95 		char* selected_field_name = pe->value;
96 		char* value = lrec_get(prec, selected_field_name);
97 		if (value == NULL)
98 			return FALSE;
99 	}
100 	return TRUE;
101 }
102 
103 // ----------------------------------------------------------------
mlr_reference_key_value_pairs_from_regex_names(lrec_t * prec,regex_t * pregexes,int num_regexes,int invert_matches)104 lhmss_t* mlr_reference_key_value_pairs_from_regex_names(lrec_t* prec, regex_t* pregexes, int num_regexes,
105 	int invert_matches)
106 {
107 	lhmss_t* pmap = lhmss_alloc();
108 
109 	for (lrece_t* pe = prec->phead; pe != NULL; pe = pe->pnext) {
110 		int matches_any = FALSE;
111 		for (int i = 0; i < num_regexes; i++) {
112 			regex_t* pregex = &pregexes[i];
113 			if (regmatch_or_die(pregex, pe->key, 0, NULL)) {
114 				matches_any = TRUE;
115 				break;
116 			}
117 		}
118 		if (matches_any ^ invert_matches) {
119 			lhmss_put(pmap, pe->key, pe->value, NO_FREE);
120 		}
121 	}
122 
123 	return pmap;
124 }
125 
126 // ----------------------------------------------------------------
hss_from_slls(slls_t * plist)127 hss_t* hss_from_slls(slls_t* plist) {
128 	hss_t* pset = hss_alloc();
129 	for (sllse_t* pe = plist->phead; pe != NULL; pe = pe->pnext)
130 		hss_add(pset, pe->value);
131 	return pset;
132 }
133 
134 // ----------------------------------------------------------------
lrec_print_list(sllv_t * plist)135 void lrec_print_list(sllv_t* plist) {
136 	for (sllve_t* pe = plist->phead; pe != NULL; pe = pe->pnext) {
137 		lrec_print(pe->pvvalue);
138 	}
139 }
140 
lrec_print_list_with_prefix(sllv_t * plist,char * prefix)141 void lrec_print_list_with_prefix(sllv_t* plist, char* prefix) {
142 	if (plist == NULL) {
143 		printf("%s NULL", prefix);
144 	} else {
145 		for (sllve_t* pe = plist->phead; pe != NULL; pe = pe->pnext) {
146 			printf("%s", prefix);
147 			lrec_print(pe->pvvalue);
148 		}
149 	}
150 }
151 
152 // ----------------------------------------------------------------
slls_lrec_compare_lexically(slls_t * plist,lrec_t * prec,slls_t * pkeys)153 int slls_lrec_compare_lexically(
154 	slls_t* plist,
155 	lrec_t* prec,
156 	slls_t* pkeys)
157 {
158 	sllse_t* pe = plist->phead;
159 	sllse_t* pf = pkeys->phead;
160 	while (TRUE) {
161 		if (pe == NULL && pf == NULL)
162 			return 0;
163 		if (pe == NULL)
164 			return 1;
165 		if (pf == NULL)
166 			return -1;
167 
168 		char* precval = lrec_get(prec, pf->value);
169 		if (precval == NULL) {
170 			return -1;
171 		} else {
172 			int rc = strcmp(pe->value, precval);
173 			if (rc != 0)
174 				return rc;
175 		}
176 
177 		pe = pe->pnext;
178 		pf = pf->pnext;
179 	}
180 }
181 
182 // ----------------------------------------------------------------
lrec_slls_compare_lexically(lrec_t * prec,slls_t * pkeys,slls_t * plist)183 int lrec_slls_compare_lexically(
184 	lrec_t* prec,
185 	slls_t* pkeys,
186 	slls_t* plist)
187 {
188 	return -slls_lrec_compare_lexically(plist, prec, pkeys);
189 }
190 
191 // ----------------------------------------------------------------
lrec_keys_equal_list(lrec_t * prec,slls_t * plist)192 int lrec_keys_equal_list(
193 	lrec_t* prec,
194 	slls_t* plist)
195 {
196 	lrece_t* pe = prec->phead;
197 	sllse_t* pf = plist->phead;
198 	while (TRUE) {
199 		if (pe == NULL && pf == NULL)
200 			return TRUE;
201 		if (pe == NULL || pf == NULL)
202 			return FALSE;
203 		if (!streq(pe->key, pf->value))
204 			return FALSE;
205 		pe = pe->pnext;
206 		pf = pf->pnext;
207 	}
208 }
209