aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2020-01-31 16:08:51 -0500
committerJoseph Hunkeler <jhunkeler@gmail.com>2020-01-31 16:08:51 -0500
commitc55a46340a089fdbb3d7abdab97dbd7d32bfdffe (patch)
tree59c0890cf8a352db1f3e8832779fc0156e407847 /src
parenta208097c9091137908beaa1f1f261072df55d3fa (diff)
downloadspmc-c55a46340a089fdbb3d7abdab97dbd7d32bfdffe.tar.gz
Initial commit of generic array handler code
Diffstat (limited to 'src')
-rw-r--r--src/strlist.c309
1 files changed, 309 insertions, 0 deletions
diff --git a/src/strlist.c b/src/strlist.c
new file mode 100644
index 0000000..ccd1925
--- /dev/null
+++ b/src/strlist.c
@@ -0,0 +1,309 @@
+/**
+ * String array convenience functions
+ * @file strlist.c
+ */
+#include "spm.h"
+#include "strlist.h"
+
+/**
+ *
+ * @param pStrList `StrList`
+ */
+void strlist_free(StrList *pStrList) {
+ for (size_t i = 0; i < pStrList->num_inuse; i++) {
+ free(pStrList->data[i]);
+ }
+ free(pStrList->data);
+ free(pStrList);
+}
+
+/**
+ * Append a value to the list
+ * @param pStrList `StrList`
+ * @param str
+ */
+void strlist_append(StrList *pStrList, char *str) {
+ char **tmp = realloc(pStrList->data, (pStrList->num_alloc + 1) * sizeof(char *));
+ if (tmp == NULL) {
+ strlist_free(pStrList);
+ perror("failed to append to array");
+ exit(1);
+ }
+ pStrList->data = tmp;
+ pStrList->data[pStrList->num_inuse] = strdup(str);
+ strcpy(pStrList->data[pStrList->num_inuse], str);
+ pStrList->num_inuse++;
+ pStrList->num_alloc++;
+}
+
+/**
+ * Append the contents of a `StrList` to another `StrList`
+ * @param pStrList1 `StrList`
+ * @param pStrList2 `StrList`
+ */
+void strlist_append_strlist(StrList *pStrList1, StrList *pStrList2) {
+ size_t count = strlist_count(pStrList2);
+ for (size_t i = 0; i < count; i++) {
+ char *item = strlist_item(pStrList2, i);
+ strlist_append(pStrList1, item);
+ }
+}
+
+/**
+ *
+ * @param a
+ * @param b
+ * @return
+ */
+static int _strlist_cmpfn(const void *a, const void *b) {
+ const char *aa = *(const char**)a;
+ const char *bb = *(const char**)b;
+ int result = strcmp(aa, bb);
+ return result;
+}
+
+/**
+ *
+ * @param a
+ * @param b
+ * @return
+ */
+static int _strlist_asc_cmpfn(const void *a, const void *b) {
+ const char *aa = *(const char**)a;
+ const char *bb = *(const char**)b;
+ size_t len_a = strlen(aa);
+ size_t len_b = strlen(bb);
+ return len_a > len_b - strcmp(aa, bb);
+}
+
+/**
+ *
+ * @param a
+ * @param b
+ * @return
+ */
+static int _strlist_dsc_cmpfn(const void *a, const void *b) {
+ const char *aa = *(const char**)a;
+ const char *bb = *(const char**)b;
+ size_t len_a = strlen(aa);
+ size_t len_b = strlen(bb);
+ return len_a < len_b - strcmp(aa, bb);
+}
+
+/**
+ * Sort a `StrList` by `mode`
+ * @param pStrList
+ * @param mode Available modes: `STRLIST_DEFAULT` (alphabetic), `STRLIST_ASC` (ascending), `STRLIST_DSC` (descending)
+ */
+void strlist_sort(StrList *pStrList, unsigned int mode) {
+ void *fn = NULL;
+ switch (mode) {
+ case STRLIST_ASC:
+ fn = _strlist_asc_cmpfn;
+ break;
+ case STRLIST_DSC:
+ fn = _strlist_dsc_cmpfn;
+ break;
+ case STRLIST_DEFAULT:
+ default:
+ fn = _strlist_cmpfn;
+ break;
+ }
+
+ qsort(pStrList->data, pStrList->num_inuse, sizeof(char *), fn);
+}
+
+/**
+ * Reverse the order of a `StrList`
+ * @param pStrList
+ */
+void strlist_reverse(StrList *pStrList) {
+ char *tmp = NULL;
+ size_t i = 0;
+ size_t j = pStrList->num_inuse - 1;
+
+ for (i = 0; i < j; i++) {
+ tmp = pStrList->data[i];
+ pStrList->data[i] = pStrList->data[j];
+ pStrList->data[j] = tmp;
+ j--;
+ }
+}
+
+/**
+ * Get the count of values stored in a `StrList`
+ * @param pStrList
+ * @return
+ */
+size_t strlist_count(StrList *pStrList) {
+ return pStrList->num_inuse;
+}
+
+/**
+ * Retrieve data from a `StrList`
+ * @param pStrList
+ * @param index
+ * @return string
+ */
+char *strlist_item(StrList *pStrList, size_t index) {
+ if (index > strlist_count(pStrList)) {
+ return NULL;
+ }
+ return pStrList->data[index];
+}
+
+/**
+ * Alias of `strlist_item`
+ * @param pStrList
+ * @param index
+ * @return string
+ */
+char *strlist_item_as_str(StrList *pStrList, size_t index) {
+ return strlist_item(pStrList, index);
+}
+
+/**
+ * Convert value at index to `char`
+ * @param pStrList
+ * @param index
+ * @return `char`
+ */
+char strlist_item_as_char(StrList *pStrList, size_t index) {
+ return (char) *(strlist_item(pStrList, index));
+}
+
+/**
+ * Convert value at index to `unsigned char`
+ * @param pStrList
+ * @param index
+ * @return `unsigned char`
+ */
+unsigned char strlist_item_as_uchar(StrList *pStrList, size_t index) {
+ return (unsigned char) *(strlist_item(pStrList, index));
+}
+
+/**
+ * Convert value at index to `short`
+ * @param pStrList
+ * @param index
+ * @return `short`
+ */
+short strlist_item_as_short(StrList *pStrList, size_t index) {
+ return (short)atoi(strlist_item(pStrList, index));
+}
+
+/**
+ * Convert value at index to `unsigned short`
+ * @param pStrList
+ * @param index
+ * @return `unsigned short`
+ */
+unsigned short strlist_item_as_ushort(StrList *pStrList, size_t index) {
+ return (unsigned short)atoi(strlist_item(pStrList, index));
+}
+
+/**
+ * Convert value at index to `int`
+ * @param pStrList
+ * @param index
+ * @return `int`
+ */
+int strlist_item_as_int(StrList *pStrList, size_t index) {
+ return atoi(strlist_item(pStrList, index));
+}
+
+/**
+ * Convert value at index to `unsigned int`
+ * @param pStrList
+ * @param index
+ * @return `unsigned int`
+ */
+unsigned int strlist_item_as_uint(StrList *pStrList, size_t index) {
+ return (unsigned int)atoi(strlist_item(pStrList, index));
+}
+
+/**
+ * Convert value at index to `long`
+ * @param pStrList
+ * @param index
+ * @return `long`
+ */
+long strlist_item_as_long(StrList *pStrList, size_t index) {
+ return atol(strlist_item(pStrList, index));
+}
+
+/**
+ * Convert value at index to `unsigned long`
+ * @param pStrList
+ * @param index
+ * @return `unsigned long`
+ */
+unsigned long strlist_item_as_ulong(StrList *pStrList, size_t index) {
+ return (unsigned long)atol(strlist_item(pStrList, index));
+}
+
+/**
+ * Convert value at index to `long long`
+ * @param pStrList
+ * @param index
+ * @return `long long`
+ */
+long long strlist_item_as_long_long(StrList *pStrList, size_t index) {
+ return (long long)atoll(strlist_item(pStrList, index));
+}
+
+/**
+ * Convert value at index to `unsigned long long`
+ * @param pStrList
+ * @param index
+ * @return `unsigned long long`
+ */
+unsigned long long strlist_item_as_ulong_long(StrList *pStrList, size_t index) {
+ return (unsigned long long)atoll(strlist_item(pStrList, index));
+}
+
+/**
+ * Convert value at index to `float`
+ * @param pStrList
+ * @param index
+ * @return `float`
+ */
+float strlist_item_as_float(StrList *pStrList, size_t index) {
+ return (float)atof(strlist_item(pStrList, index));
+}
+
+/**
+ * Convert value at index to `double`
+ * @param pStrList
+ * @param index
+ * @return `double`
+ */
+double strlist_item_as_double(StrList *pStrList, size_t index) {
+ return atof(strlist_item(pStrList, index));
+}
+
+/**
+ * Convert value at index to `long double`
+ * @param pStrList
+ * @param index
+ * @return `long double`
+ */
+long double strlist_item_as_long_double(StrList *pStrList, size_t index) {
+ return (long double)atof(strlist_item(pStrList, index));
+}
+
+/**
+ * Initialize an empty `StrList`
+ * @return `StrList`
+ */
+StrList *strlist_init() {
+ StrList *pStrList = calloc(1, sizeof(StrList));
+ if (pStrList == NULL) {
+ perror("failed to allocate array");
+ exit(errno);
+ }
+ pStrList->num_inuse = 0;
+ pStrList->num_alloc = 1;
+ pStrList->data = calloc(pStrList->num_alloc, sizeof(char *));
+ return pStrList;
+}