#ifndef NETWORKD_STRING_H
#define NETWORKD_STRING_H
+#include <ctype.h>
+#include <errno.h>
#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#define nw_string_vformat(s, format, ...) \
+ __nw_string_vformat(s, sizeof(s), format, __VA_ARGS__)
static inline int __nw_string_vformat(char* s, const size_t length,
const char* format, va_list args) {
return __nw_string_format(s, length, "%s", value);
}
+static inline int nw_string_lstrip(char* s) {
+ char* p = s;
+
+ // Count any leading spaces
+ while (*p && isspace(*p))
+ p++;
+
+ // Move the string to the beginning of the buffer
+ while (*p)
+ *s++ = *p++;
+
+ // Terminate the string
+ *s = '\0';
+
+ return 0;
+}
+
+static inline int nw_string_rstrip(char* s) {
+ ssize_t l = strlen(s) - 1;
+
+ while (l >= 0 && isspace(s[l]))
+ s[l--] = '\0';
+
+ return 0;
+}
+
+static inline int nw_string_strip(char* s) {
+ int r;
+
+ r = nw_string_lstrip(s);
+ if (r)
+ return r;
+
+ r = nw_string_rstrip(s);
+ if (r)
+ return r;
+
+ return 0;
+}
+
+static inline void nw_string_empty(char* s) {
+ if (s)
+ *s = '\0';
+}
+
+/*
+ Tables
+*/
+
+typedef struct nw_string_table {
+ const int id;
+ const char* string;
+} nw_string_table_t;
+
+static inline const char* nw_string_table_lookup_string(
+ const nw_string_table_t* table, const int id) {
+ const nw_string_table_t* entry = NULL;
+
+ for (entry = table; entry->string; entry++)
+ if (entry->id == id)
+ return entry->string;
+
+ return NULL;
+}
+
+static inline int nw_string_table_lookup_id(
+ const nw_string_table_t* table, const char* string) {
+ const nw_string_table_t* entry = NULL;
+
+ for (entry = table; entry->string; entry++)
+ if (strcmp(entry->string, string) == 0)
+ return entry->id;
+
+ return -1;
+}
+
+#define NW_STRING_TABLE_LOOKUP_ID(type, table, method) \
+ __attribute__((unused)) static type method(const char* s) { \
+ return nw_string_table_lookup_id(table, s); \
+ }
+
+#define NW_STRING_TABLE_LOOKUP_STRING(type, table, method) \
+ __attribute__((unused)) static const char* method(const type id) { \
+ return nw_string_table_lookup_string(table, id); \
+ }
+
+#define NW_STRING_TABLE_LOOKUP(type, table) \
+ NW_STRING_TABLE_LOOKUP_ID(type, table, table ## _from_string) \
+ NW_STRING_TABLE_LOOKUP_STRING(type, table, table ## _to_string)
+
+/*
+ Paths
+*/
+
+#define nw_path_join(s, first, second) \
+ __nw_path_join(s, sizeof(s), first, second)
+
+static inline int __nw_path_join(char* s, const size_t length,
+ const char* first, const char* second) {
+ if (!first)
+ return __nw_string_format(s, length, "%s", second);
+
+ if (!second)
+ return __nw_string_format(s, length, "%s", first);
+
+ // Remove leading slashes from second argument
+ while (*second == '/')
+ second++;
+
+ return __nw_string_format(s, length, "%s/%s", first, second);
+}
+
+static inline const char* nw_path_basename(const char* path) {
+ const char* basename = strrchr(path, '/');
+ if (!basename)
+ return NULL;
+
+ return basename + 1;
+}
+
#endif /* NETWORKD_STRING_H */