Skip to content

Commit fc82b20

Browse files
Update jellyfish.c
1 parent 91f3eab commit fc82b20

File tree

1 file changed

+112
-113
lines changed

1 file changed

+112
-113
lines changed

code/logic/jellyfish.c

Lines changed: 112 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -19,101 +19,6 @@
1919
#include <ctype.h>
2020
#include <time.h>
2121

22-
#if defined(_WIN32)
23-
#include <winsock2.h>
24-
#else
25-
#include <unistd.h>
26-
#endif
27-
28-
29-
// Parses a string like: "key": "value"
30-
static bool match_key_value(const char **ptr, const char *key, const char *value) {
31-
const char *p = *ptr;
32-
while (isspace(*p)) p++;
33-
size_t klen = strlen(key);
34-
if (strncmp(p, "\"", 1) != 0 || strncmp(p + 1, key, klen) != 0 || strncmp(p + 1 + klen, "\":", 2) != 0)
35-
return false;
36-
p += klen + 3;
37-
while (isspace(*p)) p++;
38-
size_t vlen = strlen(value);
39-
if (strncmp(p, "\"", 1) != 0 || strncmp(p + 1, value, vlen) != 0 || strncmp(p + 1 + vlen, "\"", 1) != 0)
40-
return false;
41-
*ptr = p + vlen + 2;
42-
return true;
43-
}
44-
45-
static bool skip_key(const char **ptr, const char *key) {
46-
const char *p = *ptr;
47-
while (isspace(*p)) p++;
48-
size_t klen = strlen(key);
49-
if (strncmp(p, "\"", 1) != 0 || strncmp(p + 1, key, klen) != 0 || strncmp(p + 1 + klen, "\":", 2) != 0)
50-
return false;
51-
*ptr = p + klen + 3;
52-
return true;
53-
}
54-
55-
static bool skip_symbol(const char **ptr, char symbol) {
56-
const char *p = *ptr;
57-
while (isspace(*p)) p++;
58-
if (*p != symbol)
59-
return false;
60-
*ptr = p + 1;
61-
return true;
62-
}
63-
64-
static bool skip_comma(const char **ptr) {
65-
const char *p = *ptr;
66-
while (isspace(*p)) p++;
67-
if (*p == ',') {
68-
*ptr = p + 1;
69-
return true;
70-
}
71-
return false;
72-
}
73-
74-
static bool parse_string_field(const char **ptr, const char *key, char *out, size_t max) {
75-
if (!skip_key(ptr, key)) return false;
76-
if (!skip_symbol(ptr, '"')) return false;
77-
78-
const char *p = *ptr;
79-
size_t i = 0;
80-
81-
while (*p && *p != '"' && i < max - 1) {
82-
if (*p == '\\' && *(p + 1)) p++; // skip escape
83-
out[i++] = *p++;
84-
}
85-
86-
if (*p != '"') return false;
87-
out[i] = '\0';
88-
*ptr = p + 1;
89-
return true;
90-
}
91-
92-
static bool parse_number_field(const char **ptr, const char *key, double *out_d, uint64_t *out_u64, int *out_i, uint32_t *out_u32) {
93-
if (!skip_key(ptr, key)) return false;
94-
95-
char *end;
96-
const char *p = *ptr;
97-
98-
while (isspace(*p)) p++;
99-
100-
if (out_d) {
101-
*out_d = strtod(p, &end);
102-
} else if (out_u64) {
103-
*out_u64 = strtoull(p, &end, 10);
104-
} else if (out_i) {
105-
*out_i = strtol(p, &end, 10);
106-
} else if (out_u32) {
107-
*out_u32 = strtoul(p, &end, 10);
108-
} else {
109-
return false;
110-
}
111-
112-
if (end == p) return false;
113-
*ptr = end;
114-
return true;
115-
}
116-
11722
// HASH Algorithm magic
11823

11924
#if defined(_WIN32) || defined(_WIN64)
@@ -134,27 +39,33 @@ uint64_t get_time_microseconds(void) {
13439
#endif
13540

13641
static uint64_t get_device_salt(void) {
42+
// FNV-1a 64-bit base offset
13743
uint64_t hash = 0xcbf29ce484222325ULL;
138-
const char *user = getenv("USER");
139-
const char *host = getenv("HOSTNAME");
140-
char hostname[256];
141-
142-
if (!host) {
143-
gethostname(hostname, sizeof(hostname));
144-
host = hostname;
145-
}
14644

147-
if (user) {
148-
for (size_t i = 0; i < strlen(user); ++i) {
149-
hash ^= user[i];
150-
hash *= 0x100000001b3ULL;
151-
}
152-
}
45+
// Cross-platform user and home detection
46+
#if defined(_WIN32) || defined(_WIN64)
47+
const char *vars[] = {
48+
getenv("USERNAME"),
49+
getenv("USERPROFILE"),
50+
getenv("COMPUTERNAME")
51+
};
52+
#else
53+
const char *vars[] = {
54+
getenv("USER"),
55+
getenv("HOME"),
56+
getenv("SHELL"),
57+
getenv("HOSTNAME")
58+
};
59+
#endif
15360

154-
if (host) {
155-
for (size_t i = 0; i < strlen(host); ++i) {
156-
hash ^= host[i];
157-
hash *= 0x100000001b3ULL;
61+
// Mix in each variable if it exists
62+
for (size_t v = 0; v < sizeof(vars) / sizeof(vars[0]); ++v) {
63+
const char *val = vars[v];
64+
if (val) {
65+
for (size_t i = 0; val[i]; ++i) {
66+
hash ^= (uint8_t)val[i];
67+
hash *= 0x100000001b3ULL;
68+
}
15869
}
15970
}
16071

@@ -762,6 +673,94 @@ bool fossil_jellyfish_verify_chain(const fossil_jellyfish_chain* chain) {
762673
return true;
763674
}
764675

676+
// Parses a string like: "key": "value"
677+
static bool match_key_value(const char **ptr, const char *key, const char *value) {
678+
const char *p = *ptr;
679+
while (isspace(*p)) p++;
680+
size_t klen = strlen(key);
681+
if (strncmp(p, "\"", 1) != 0 || strncmp(p + 1, key, klen) != 0 || strncmp(p + 1 + klen, "\":", 2) != 0)
682+
return false;
683+
p += klen + 3;
684+
while (isspace(*p)) p++;
685+
size_t vlen = strlen(value);
686+
if (strncmp(p, "\"", 1) != 0 || strncmp(p + 1, value, vlen) != 0 || strncmp(p + 1 + vlen, "\"", 1) != 0)
687+
return false;
688+
*ptr = p + vlen + 2;
689+
return true;
690+
}
691+
692+
static bool skip_key(const char **ptr, const char *key) {
693+
const char *p = *ptr;
694+
while (isspace(*p)) p++;
695+
size_t klen = strlen(key);
696+
if (strncmp(p, "\"", 1) != 0 || strncmp(p + 1, key, klen) != 0 || strncmp(p + 1 + klen, "\":", 2) != 0)
697+
return false;
698+
*ptr = p + klen + 3;
699+
return true;
700+
}
701+
702+
static bool skip_symbol(const char **ptr, char symbol) {
703+
const char *p = *ptr;
704+
while (isspace(*p)) p++;
705+
if (*p != symbol)
706+
return false;
707+
*ptr = p + 1;
708+
return true;
709+
}
710+
711+
static bool skip_comma(const char **ptr) {
712+
const char *p = *ptr;
713+
while (isspace(*p)) p++;
714+
if (*p == ',') {
715+
*ptr = p + 1;
716+
return true;
717+
}
718+
return false;
719+
}
720+
721+
static bool parse_string_field(const char **ptr, const char *key, char *out, size_t max) {
722+
if (!skip_key(ptr, key)) return false;
723+
if (!skip_symbol(ptr, '"')) return false;
724+
725+
const char *p = *ptr;
726+
size_t i = 0;
727+
728+
while (*p && *p != '"' && i < max - 1) {
729+
if (*p == '\\' && *(p + 1)) p++; // skip escape
730+
out[i++] = *p++;
731+
}
732+
733+
if (*p != '"') return false;
734+
out[i] = '\0';
735+
*ptr = p + 1;
736+
return true;
737+
}
738+
739+
static bool parse_number_field(const char **ptr, const char *key, double *out_d, uint64_t *out_u64, int *out_i, uint32_t *out_u32) {
740+
if (!skip_key(ptr, key)) return false;
741+
742+
char *end;
743+
const char *p = *ptr;
744+
745+
while (isspace(*p)) p++;
746+
747+
if (out_d) {
748+
*out_d = strtod(p, &end);
749+
} else if (out_u64) {
750+
*out_u64 = strtoull(p, &end, 10);
751+
} else if (out_i) {
752+
*out_i = strtol(p, &end, 10);
753+
} else if (out_u32) {
754+
*out_u32 = strtoul(p, &end, 10);
755+
} else {
756+
return false;
757+
}
758+
759+
if (end == p) return false;
760+
*ptr = end;
761+
return true;
762+
}
763+
765764
/**
766765
* Parses a .jellyfish (JellyDSL) file with Meson-like syntax and extracts models.
767766
*

0 commit comments

Comments
 (0)