mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-22 07:30:43 +00:00
185 lines
5 KiB
C
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;
|
|
}
|
|
}
|