@@ -122,6 +122,94 @@ void fossil_jellyfish_hash(const char *input, const char *output, uint8_t *hash_
122122 }
123123}
124124
125+ // Parses a string like: "key": "value"
126+ static bool match_key_value (const char * * ptr , const char * key , const char * value ) {
127+ const char * p = * ptr ;
128+ while (isspace (* p )) p ++ ;
129+ size_t klen = strlen (key );
130+ if (strncmp (p , "\"" , 1 ) != 0 || strncmp (p + 1 , key , klen ) != 0 || strncmp (p + 1 + klen , "\":" , 2 ) != 0 )
131+ return false;
132+ p += klen + 3 ;
133+ while (isspace (* p )) p ++ ;
134+ size_t vlen = strlen (value );
135+ if (strncmp (p , "\"" , 1 ) != 0 || strncmp (p + 1 , value , vlen ) != 0 || strncmp (p + 1 + vlen , "\"" , 1 ) != 0 )
136+ return false;
137+ * ptr = p + vlen + 2 ;
138+ return true;
139+ }
140+
141+ static bool skip_key (const char * * ptr , const char * key ) {
142+ const char * p = * ptr ;
143+ while (isspace (* p )) p ++ ;
144+ size_t klen = strlen (key );
145+ if (strncmp (p , "\"" , 1 ) != 0 || strncmp (p + 1 , key , klen ) != 0 || strncmp (p + 1 + klen , "\":" , 2 ) != 0 )
146+ return false;
147+ * ptr = p + klen + 3 ;
148+ return true;
149+ }
150+
151+ static bool skip_symbol (const char * * ptr , char symbol ) {
152+ const char * p = * ptr ;
153+ while (isspace (* p )) p ++ ;
154+ if (* p != symbol )
155+ return false;
156+ * ptr = p + 1 ;
157+ return true;
158+ }
159+
160+ static bool skip_comma (const char * * ptr ) {
161+ const char * p = * ptr ;
162+ while (isspace (* p )) p ++ ;
163+ if (* p == ',' ) {
164+ * ptr = p + 1 ;
165+ return true;
166+ }
167+ return false;
168+ }
169+
170+ static bool parse_string_field (const char * * ptr , const char * key , char * out , size_t max ) {
171+ if (!skip_key (ptr , key )) return false;
172+ if (!skip_symbol (ptr , '"' )) return false;
173+
174+ const char * p = * ptr ;
175+ size_t i = 0 ;
176+
177+ while (* p && * p != '"' && i < max - 1 ) {
178+ if (* p == '\\' && * (p + 1 )) p ++ ; // skip escape
179+ out [i ++ ] = * p ++ ;
180+ }
181+
182+ if (* p != '"' ) return false;
183+ out [i ] = '\0' ;
184+ * ptr = p + 1 ;
185+ return true;
186+ }
187+
188+ 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 ) {
189+ if (!skip_key (ptr , key )) return false;
190+
191+ char * end ;
192+ const char * p = * ptr ;
193+
194+ while (isspace (* p )) p ++ ;
195+
196+ if (out_d ) {
197+ * out_d = strtod (p , & end );
198+ } else if (out_u64 ) {
199+ * out_u64 = strtoull (p , & end , 10 );
200+ } else if (out_i ) {
201+ * out_i = strtol (p , & end , 10 );
202+ } else if (out_u32 ) {
203+ * out_u32 = strtoul (p , & end , 10 );
204+ } else {
205+ return false;
206+ }
207+
208+ if (end == p ) return false;
209+ * ptr = end ;
210+ return true;
211+ }
212+
125213void fossil_jellyfish_init (fossil_jellyfish_chain * chain ) {
126214 if (!chain ) return ;
127215 chain -> count = 0 ;
@@ -673,94 +761,6 @@ bool fossil_jellyfish_verify_chain(const fossil_jellyfish_chain* chain) {
673761 return true;
674762}
675763
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-
764764/**
765765 * Parses a .jellyfish (JellyDSL) file with Meson-like syntax and extracts models.
766766 *
0 commit comments