miller/c/containers/mixutil.c
2016-10-14 19:52:13 -04:00

185 lines
5 KiB
C

#include "lib/mlr_globals.h"
#include "lib/mlrutil.h"
#include "lib/mlr_globals.h"
#include "containers/mixutil.h"
// ----------------------------------------------------------------
// Makes a list with values pointing to the lrec's keys. slls_free() will
// respect that and not corrupt the lrec. However, the slls values will be
// invalid after the lrec is freed.
slls_t* mlr_reference_keys_from_record(lrec_t* prec) {
slls_t* plist = slls_alloc();
for (lrece_t* pe = prec->phead; pe != NULL; pe = pe->pnext) {
slls_append_no_free(plist, pe->key);
}
return plist;
}
slls_t* mlr_copy_keys_from_record(lrec_t* prec) {
slls_t* plist = slls_alloc();
for (lrece_t* pe = prec->phead; pe != NULL; pe = pe->pnext) {
slls_append_with_free(plist, mlr_strdup_or_die(pe->key));
}
return plist;
}
slls_t* mlr_reference_values_from_record(lrec_t* prec) {
slls_t* plist = slls_alloc();
for (lrece_t* pe = prec->phead; pe != NULL; pe = pe->pnext) {
slls_append_no_free(plist, pe->value);
}
return plist;
}
slls_t* mlr_reference_keys_from_record_except(lrec_t* prec, lrece_t* px) {
slls_t* plist = slls_alloc();
for (lrece_t* pe = prec->phead; pe != NULL; pe = pe->pnext) {
if (pe != px)
slls_append_no_free(plist, pe->key);
}
return plist;
}
slls_t* mlr_reference_values_from_record_except(lrec_t* prec, lrece_t* px) {
slls_t* plist = slls_alloc();
for (lrece_t* pe = prec->phead; pe != NULL; pe = pe->pnext) {
if (pe != px)
slls_append_no_free(plist, pe->value);
}
return plist;
}
// ----------------------------------------------------------------
// Makes a list with values pointing into the lrec's values. slls_free() will
// respect that and not corrupt the lrec. However, the slls values will be
// invalid after the lrec is freed.
slls_t* mlr_reference_selected_values_from_record(lrec_t* prec, slls_t* pselected_field_names) {
slls_t* pvalue_list = slls_alloc();
for (sllse_t* pe = pselected_field_names->phead; pe != NULL; pe = pe->pnext) {
char* selected_field_name = pe->value;
char* value = lrec_get(prec, selected_field_name);
if (value == NULL) {
slls_free(pvalue_list);
return NULL;
} else {
slls_append_no_free(pvalue_list, value);
}
}
return pvalue_list;
}
// Makes an array with values pointing into the lrec's values.
// string_array_free() will respect that and not corrupt the lrec. However,
// the array's values will be invalid after the lrec is freed.
void mlr_reference_values_from_record_into_string_array(lrec_t* prec, string_array_t* pselected_field_names,
string_array_t* pvalues)
{
MLR_INTERNAL_CODING_ERROR_IF(pselected_field_names->length != pvalues->length);
pvalues->strings_need_freeing = FALSE;
for (int i = 0; i < pselected_field_names->length; i++) {
char* selected_field_name = pselected_field_names->strings[i];
if (selected_field_name == NULL) {
pvalues->strings[i] = NULL;
} else {
pvalues->strings[i] = lrec_get(prec, selected_field_name);
}
}
}
int record_has_all_keys(lrec_t* prec, slls_t* pselected_field_names) {
for (sllse_t* pe = pselected_field_names->phead; pe != NULL; pe = pe->pnext) {
char* selected_field_name = pe->value;
char* value = lrec_get(prec, selected_field_name);
if (value == NULL)
return FALSE;
}
return TRUE;
}
// ----------------------------------------------------------------
hss_t* hss_from_slls(slls_t* plist) {
hss_t* pset = hss_alloc();
for (sllse_t* pe = plist->phead; pe != NULL; pe = pe->pnext)
hss_add(pset, pe->value);
return pset;
}
// ----------------------------------------------------------------
void lrec_print_list(sllv_t* plist) {
for (sllve_t* pe = plist->phead; pe != NULL; pe = pe->pnext) {
lrec_print(pe->pvvalue);
}
}
void lrec_print_list_with_prefix(sllv_t* plist, char* prefix) {
if (plist == NULL) {
printf("%s NULL", prefix);
} else {
for (sllve_t* pe = plist->phead; pe != NULL; pe = pe->pnext) {
printf("%s", prefix);
lrec_print(pe->pvvalue);
}
}
}
// ----------------------------------------------------------------
int slls_lrec_compare_lexically(
slls_t* plist,
lrec_t* prec,
slls_t* pkeys)
{
sllse_t* pe = plist->phead;
sllse_t* pf = pkeys->phead;
while (TRUE) {
if (pe == NULL && pf == NULL)
return 0;
if (pe == NULL)
return 1;
if (pf == NULL)
return -1;
char* precval = lrec_get(prec, pf->value);
if (precval == NULL) {
return -1;
} else {
int rc = strcmp(pe->value, precval);
if (rc != 0)
return rc;
}
pe = pe->pnext;
pf = pf->pnext;
}
}
// ----------------------------------------------------------------
int lrec_slls_compare_lexically(
lrec_t* prec,
slls_t* pkeys,
slls_t* plist)
{
return -slls_lrec_compare_lexically(plist, prec, pkeys);
}
// ----------------------------------------------------------------
int lrec_keys_equal_list(
lrec_t* prec,
slls_t* plist)
{
lrece_t* pe = prec->phead;
sllse_t* pf = plist->phead;
while (TRUE) {
if (pe == NULL && pf == NULL)
return TRUE;
if (pe == NULL || pf == NULL)
return FALSE;
if (!streq(pe->key, pf->value))
return FALSE;
pe = pe->pnext;
pf = pf->pnext;
}
}