summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md1
-rw-r--r--httpd.c2
-rw-r--r--xs.h77
-rw-r--r--xs_set.h27
-rw-r--r--xs_unicode.h4
-rw-r--r--xs_version.h2
6 files changed, 93 insertions, 20 deletions
diff --git a/README.md b/README.md
index e1ed064..e3ef380 100644
--- a/README.md
+++ b/README.md
@@ -111,6 +111,7 @@ This will:
111- [How to run your own social network with snac (by Giacomo Tesio)](https://encrypted.tesio.it/2024/12/18/how-to-run-your-own-social-network.html). Includes information on how to run snac as a CGI. 111- [How to run your own social network with snac (by Giacomo Tesio)](https://encrypted.tesio.it/2024/12/18/how-to-run-your-own-social-network.html). Includes information on how to run snac as a CGI.
112- [Improving snac Performance with Nginx Proxy Cache (by Stefano Marinelli)](https://it-notes.dragas.net/2025/01/29/improving-snac-performance-with-nginx-proxy-cache/). 112- [Improving snac Performance with Nginx Proxy Cache (by Stefano Marinelli)](https://it-notes.dragas.net/2025/01/29/improving-snac-performance-with-nginx-proxy-cache/).
113- [Caching Snac Proxied Media With Nginx (by Stefano Marinelli)](https://it-notes.dragas.net/2025/02/08/caching-snac-proxied-media-with-nginx/). 113- [Caching Snac Proxied Media With Nginx (by Stefano Marinelli)](https://it-notes.dragas.net/2025/02/08/caching-snac-proxied-media-with-nginx/).
114- [My snac config (activitypub instance) with Caddy (by ffuentes)](https://ffuentes.sdf.org/communication/2025/08/23/my-snac-config-activitypub-instance-with-caddy.html).
114- [A bit of lore about Susie, snac's default avatar](https://comam.es/snac/grunfink/p/1754553922.333170). 115- [A bit of lore about Susie, snac's default avatar](https://comam.es/snac/grunfink/p/1754553922.333170).
115 116
116## Incredibly awesome CSS themes for snac 117## Incredibly awesome CSS themes for snac
diff --git a/httpd.c b/httpd.c
index 71e04bf..9707f9c 100644
--- a/httpd.c
+++ b/httpd.c
@@ -226,7 +226,7 @@ int server_get_handler(xs_dict *req, const char *q_path,
226 const xs_dict *q_vars = xs_dict_get(req, "q_vars"); 226 const xs_dict *q_vars = xs_dict_get(req, "q_vars");
227 const char *t = NULL; 227 const char *t = NULL;
228 228
229 if (xs_type(q_vars) == XSTYPE_DICT && (t = xs_dict_get(q_vars, "t"))) { 229 if (xs_type(q_vars) == XSTYPE_DICT && xs_is_string(t = xs_dict_get(q_vars, "t"))) {
230 /** search by tag **/ 230 /** search by tag **/
231 int skip = 0; 231 int skip = 0;
232 int show = xs_number_get(xs_dict_get_def(srv_config, "def_timeline_entries", 232 int show = xs_number_get(xs_dict_get_def(srv_config, "def_timeline_entries",
diff --git a/xs.h b/xs.h
index 54b913e..5f2e6aa 100644
--- a/xs.h
+++ b/xs.h
@@ -134,7 +134,9 @@ xs_dict *xs_dict_set_path_sep(xs_dict *dict, const char *path, const xs_val *val
134 134
135xs_val *xs_val_new(xstype t); 135xs_val *xs_val_new(xstype t);
136xs_number *xs_number_new(double f); 136xs_number *xs_number_new(double f);
137xs_number *xs_number_new_l(long l);
137double xs_number_get(const xs_number *v); 138double xs_number_get(const xs_number *v);
139long xs_number_get_l(const xs_number *v);
138const char *xs_number_str(const xs_number *v); 140const char *xs_number_str(const xs_number *v);
139 141
140xs_data *xs_data_new(const void *data, int size); 142xs_data *xs_data_new(const void *data, int size);
@@ -163,6 +165,7 @@ uint64_t xs_hash64_func(const char *data, int size);
163#define xs_is_string(v) (xs_type((v)) == XSTYPE_STRING) 165#define xs_is_string(v) (xs_type((v)) == XSTYPE_STRING)
164#define xs_is_list(v) (xs_type((v)) == XSTYPE_LIST) 166#define xs_is_list(v) (xs_type((v)) == XSTYPE_LIST)
165#define xs_is_dict(v) (xs_type((v)) == XSTYPE_DICT) 167#define xs_is_dict(v) (xs_type((v)) == XSTYPE_DICT)
168#define xs_is_number(v) (xs_type((v)) == XSTYPE_NUMBER)
166 169
167#define xs_list_foreach(l, v) for (int ct_##__LINE__ = 0; xs_list_next(l, &v, &ct_##__LINE__); ) 170#define xs_list_foreach(l, v) for (int ct_##__LINE__ = 0; xs_list_next(l, &v, &ct_##__LINE__); )
168#define xs_dict_foreach(l, k, v) for (int ct_##__LINE__ = 0; xs_dict_next(l, &k, &v, &ct_##__LINE__); ) 171#define xs_dict_foreach(l, k, v) for (int ct_##__LINE__ = 0; xs_dict_next(l, &k, &v, &ct_##__LINE__); )
@@ -362,9 +365,22 @@ int xs_is_null(const xs_val *data)
362int xs_cmp(const xs_val *v1, const xs_val *v2) 365int xs_cmp(const xs_val *v1, const xs_val *v2)
363/* compares two values */ 366/* compares two values */
364{ 367{
365 if (xs_type(v1) == XSTYPE_STRING && xs_type(v2) == XSTYPE_STRING) 368 xstype t1 = xs_type(v1);
369 xstype t2 = xs_type(v2);
370
371 if (t1 == XSTYPE_NULL || t2 == XSTYPE_NULL)
372 return 0;
373
374 if (t1 == XSTYPE_STRING && t2 == XSTYPE_STRING)
366 return strcmp(v1, v2); 375 return strcmp(v1, v2);
367 376
377 if (t1 == XSTYPE_NUMBER && t2 == XSTYPE_NUMBER) {
378 double d1 = xs_number_get(v1);
379 double d2 = xs_number_get(v2);
380
381 return d1 == d2 ? 0 : d1 < d2 ? -1 : 1;
382 }
383
368 int s1 = xs_size(v1); 384 int s1 = xs_size(v1);
369 int s2 = xs_size(v2); 385 int s2 = xs_size(v2);
370 int d = s1 - s2; 386 int d = s1 - s2;
@@ -975,6 +991,9 @@ xs_str *xs_join(const xs_list *list, const char *sep)
975 991
976 xs_list_foreach(list, v) { 992 xs_list_foreach(list, v) {
977 /* refuse to join non-string values */ 993 /* refuse to join non-string values */
994 if (xs_type(v) == XSTYPE_NUMBER)
995 v = xs_number_str(v);
996
978 if (xs_type(v) == XSTYPE_STRING) { 997 if (xs_type(v) == XSTYPE_STRING) {
979 int sz; 998 int sz;
980 999
@@ -1396,10 +1415,20 @@ xs_val *xs_val_new(xstype t)
1396 1415
1397/** numbers */ 1416/** numbers */
1398 1417
1418xs_number *_xs_number_new(const char *str)
1419{
1420 xs_number *v = xs_realloc(NULL, 1 + xs_size(str));
1421
1422 v[0] = XSTYPE_NUMBER;
1423 memcpy(&v[1], str, xs_size(str));
1424
1425 return v;
1426}
1427
1428
1399xs_number *xs_number_new(double f) 1429xs_number *xs_number_new(double f)
1400/* adds a new number value */ 1430/* creates a new number value from a double */
1401{ 1431{
1402 xs_number *v;
1403 char tmp[64]; 1432 char tmp[64];
1404 1433
1405 snprintf(tmp, sizeof(tmp), "%.15lf", f); 1434 snprintf(tmp, sizeof(tmp), "%.15lf", f);
@@ -1416,40 +1445,54 @@ xs_number *xs_number_new(double f)
1416 *ptr = '\0'; 1445 *ptr = '\0';
1417 } 1446 }
1418 1447
1419 /* alloc for the marker and the full string */ 1448 return _xs_number_new(tmp);
1420 v = xs_realloc(NULL, _xs_blk_size(1 + xs_size(tmp))); 1449}
1421 1450
1422 v[0] = XSTYPE_NUMBER;
1423 memcpy(&v[1], tmp, xs_size(tmp));
1424 1451
1425 return v; 1452xs_number *xs_number_new_l(long l)
1453/* creates a new number value from a long */
1454{
1455 char tmp[64];
1456
1457 snprintf(tmp, sizeof(tmp), "%ld", l);
1458
1459 return _xs_number_new(tmp);
1426} 1460}
1427 1461
1428 1462
1429double xs_number_get(const xs_number *v) 1463double xs_number_get(const xs_number *v)
1430/* gets the number as a double */ 1464/* gets the number as a double */
1431{ 1465{
1432 double f = 0.0; 1466 if (xs_type(v) == XSTYPE_NUMBER)
1467 v++;
1468
1469 if (xs_type(v) == XSTYPE_STRING)
1470 return atof(v);
1433 1471
1472 return 0.0;
1473}
1474
1475
1476long xs_number_get_l(const xs_number *v)
1477/* gets the number as a long */
1478{
1434 if (xs_type(v) == XSTYPE_NUMBER) 1479 if (xs_type(v) == XSTYPE_NUMBER)
1435 f = atof(&v[1]); 1480 v++;
1436 else 1481
1437 if (xs_type(v) == XSTYPE_STRING) 1482 if (xs_type(v) == XSTYPE_STRING)
1438 f = atof(v); 1483 return atol(v);
1439 1484
1440 return f; 1485 return 0;
1441} 1486}
1442 1487
1443 1488
1444const char *xs_number_str(const xs_number *v) 1489const char *xs_number_str(const xs_number *v)
1445/* gets the number as a string */ 1490/* gets the number as a string */
1446{ 1491{
1447 const char *p = NULL;
1448
1449 if (xs_type(v) == XSTYPE_NUMBER) 1492 if (xs_type(v) == XSTYPE_NUMBER)
1450 p = &v[1]; 1493 return v + 1;
1451 1494
1452 return p; 1495 return NULL;
1453} 1496}
1454 1497
1455 1498
diff --git a/xs_set.h b/xs_set.h
index 3eaefdf..8946e42 100644
--- a/xs_set.h
+++ b/xs_set.h
@@ -14,6 +14,7 @@ typedef struct _xs_set {
14void xs_set_init(xs_set *s); 14void xs_set_init(xs_set *s);
15xs_list *xs_set_result(xs_set *s); 15xs_list *xs_set_result(xs_set *s);
16void xs_set_free(xs_set *s); 16void xs_set_free(xs_set *s);
17int xs_set_in(const xs_set *s, const xs_val *data);
17int xs_set_add(xs_set *s, const xs_val *data); 18int xs_set_add(xs_set *s, const xs_val *data);
18 19
19 20
@@ -60,7 +61,7 @@ static int _store_hash(xs_set *s, const char *data, int value)
60 61
61 while (s->hash[(i = hash % s->elems)]) { 62 while (s->hash[(i = hash % s->elems)]) {
62 /* get the pointer to the stored data */ 63 /* get the pointer to the stored data */
63 char *p = &s->list[s->hash[i]]; 64 const char *p = &s->list[s->hash[i]];
64 65
65 /* already here? */ 66 /* already here? */
66 if (memcmp(p, data, sz) == 0) 67 if (memcmp(p, data, sz) == 0)
@@ -79,6 +80,30 @@ static int _store_hash(xs_set *s, const char *data, int value)
79} 80}
80 81
81 82
83int xs_set_in(const xs_set *s, const xs_val *data)
84/* returns 1 if the data is already in the set */
85{
86 unsigned int hash, i;
87 int sz = xs_size(data);
88
89 hash = xs_hash_func(data, sz);
90
91 while (s->hash[(i = hash % s->elems)]) {
92 /* get the pointer to the stored data */
93 const char *p = &s->list[s->hash[i]];
94
95 /* already here? */
96 if (memcmp(p, data, sz) == 0)
97 return 1;
98
99 /* try next value */
100 hash++;
101 }
102
103 return 0;
104}
105
106
82int xs_set_add(xs_set *s, const xs_val *data) 107int xs_set_add(xs_set *s, const xs_val *data)
83/* adds the data to the set */ 108/* adds the data to the set */
84/* returns: 1 if added, 0 if already there */ 109/* returns: 1 if added, 0 if already there */
diff --git a/xs_unicode.h b/xs_unicode.h
index ef18fea..67b3827 100644
--- a/xs_unicode.h
+++ b/xs_unicode.h
@@ -79,6 +79,10 @@ unsigned int xs_utf8_dec(const char **str)
79/* decodes an utf-8 char inside str and updates the pointer */ 79/* decodes an utf-8 char inside str and updates the pointer */
80{ 80{
81 const char *p = *str; 81 const char *p = *str;
82
83 if (!xs_is_string(p))
84 return 0;
85
82 unsigned int cpoint = 0; 86 unsigned int cpoint = 0;
83 unsigned char c = *p++; 87 unsigned char c = *p++;
84 int cb = 0; 88 int cb = 0;
diff --git a/xs_version.h b/xs_version.h
index 466535b..cd52531 100644
--- a/xs_version.h
+++ b/xs_version.h
@@ -1 +1 @@
/* 401d229ffbec89b4a5cf97793926b7afb84a4f26 2025-07-08T15:44:54+02:00 */ /* ad90abcefd455c0ba0faf155dc2976490dbde0b0 2025-08-23T20:36:11+02:00 */