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