X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fattributes.c;h=f516dc61a172f72afb792f27026a109447b5c903;hb=08767a7c0d9b6f719c307baa8d264f989a65d7a3;hp=aa1282908438857be3437936f0d78574790625db;hpb=a1efcf97ca2f75f4be6a0389ff2372c03ed2d4e1;p=pspp diff --git a/src/data/attributes.c b/src/data/attributes.c index aa12829084..f516dc61a1 100644 --- a/src/data/attributes.c +++ b/src/data/attributes.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2008 Free Software Foundation, Inc. + Copyright (C) 2008, 2009, 2011, 2012, 2016 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,12 +16,16 @@ #include -#include +#include "data/attributes.h" + #include #include -#include -#include -#include "xalloc.h" + +#include "libpspp/array.h" +#include "libpspp/hash-functions.h" +#include "libpspp/i18n.h" + +#include "gl/xalloc.h" /* A custom attribute of the sort maintained by the DATAFILE ATTRIBUTE and VARIABLE ATTRIBUTE commands. @@ -216,14 +220,14 @@ attrset_count (const struct attrset *set) case-insensitively, or a null pointer if SET does not contain an attribute with that name. */ struct attribute * -attrset_lookup (struct attrset *set, const char *name) +attrset_lookup (const struct attrset *set, const char *name) { - struct attribute *attr; + const struct attribute *attr; HMAP_FOR_EACH_WITH_HASH (attr, struct attribute, node, - hsh_hash_case_string (name), &set->map) - if (!strcasecmp (attribute_get_name (attr), name)) + utf8_hash_case_string (name, 0), &set->map) + if (!utf8_strcasecmp (attribute_get_name (attr), name)) break; - return attr; + return CONST_CAST (struct attribute *, attr); } /* Adds ATTR to SET, which must not already contain an attribute @@ -234,7 +238,7 @@ attrset_add (struct attrset *set, struct attribute *attr) { const char *name = attribute_get_name (attr); assert (attrset_lookup (set, name) == NULL); - hmap_insert (&set->map, &attr->node, hsh_hash_case_string (name)); + hmap_insert (&set->map, &attr->node, utf8_hash_case_string (name, 0)); } /* Deletes any attribute from SET that matches NAME @@ -296,3 +300,38 @@ attrset_next (const struct attrset *set, struct attrset_iterator *iterator) iterator->node = hmap_next (&set->map, iterator->node); return iterator_data (iterator); } + +static int +compare_attribute_by_name (const void *a_, const void *b_) +{ + const struct attribute *const *a = a_; + const struct attribute *const *b = b_; + + return strcmp ((*a)->name, (*b)->name); +} + +/* Allocates and returns an array of pointers to attributes + that is sorted by attribute name. The array has + 'attrset_count (SET)' elements. The caller is responsible for + freeing the array. */ +struct attribute ** +attrset_sorted (const struct attrset *set) +{ + if (set != NULL && attrset_count (set) > 0) + { + struct attribute **attrs; + struct attribute *attr; + size_t i; + + attrs = xmalloc (attrset_count (set) * sizeof *attrs); + i = 0; + HMAP_FOR_EACH (attr, struct attribute, node, &set->map) + attrs[i++] = attr; + assert (i == attrset_count (set)); + qsort (attrs, attrset_count (set), sizeof *attrs, + compare_attribute_by_name); + return attrs; + } + else + return NULL; +}