Compare commits
	
		
			4 Commits
		
	
	
		
			301ea44759
			...
			d284a7edc8
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| d284a7edc8 | |||
| 9a686a2692 | |||
| 10f1d5686e | |||
| 50f881c655 | 
							
								
								
									
										2
									
								
								haversine_02/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								haversine_02/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -4,4 +4,4 @@ count_and_distances
 | 
				
			|||||||
pairs.json
 | 
					pairs.json
 | 
				
			||||||
main
 | 
					main
 | 
				
			||||||
genhavr
 | 
					genhavr
 | 
				
			||||||
jsonparse
 | 
					prochavr
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,16 +1,22 @@
 | 
				
			|||||||
#!/bin/bash
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CC=clang++
 | 
					CC=clang
 | 
				
			||||||
 | 
					CXX=clang++
 | 
				
			||||||
CFLAGS="-g -Wall -Wextra -Iinclude"
 | 
					CFLAGS="-g -Wall -Wextra -Iinclude"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# generator
 | 
					# generator
 | 
				
			||||||
GENSRC="./src/argparser.cpp ./src/generator.cpp ./src/haversine.cpp ./src/point_types.cpp ./src/genmain.cpp"
 | 
					GENSRC="./src/generator/gen_argparser.cpp ./src/generator/generator.cpp ./src/haversine.cpp ./src/point_types.cpp ./src/generator/main.cpp"
 | 
				
			||||||
GENOUT=genhavr
 | 
					GENOUT=genhavr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(set -x ; $CC $CFLAGS $GENSRC -o $GENOUT)
 | 
					(set -x ; $CXX $CFLAGS $GENSRC -o $GENOUT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# json parser
 | 
					# processor
 | 
				
			||||||
JSONSRC="./src/jsonparse.cpp"
 | 
					JSONSRC="./src/json/*.c"
 | 
				
			||||||
JSONOUT=jsonparse
 | 
					JSONFLAGS="-c"
 | 
				
			||||||
 | 
					PROCSRC="./*.o ./src/haversine.cpp ./src/point_types.cpp ./src/processor/proc_argparser.cpp ./src/processor/main.cpp"
 | 
				
			||||||
 | 
					PROCOUT=prochavr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(set -x ; $CC $CFLAGS $JSONSRC -o $JSONOUT)
 | 
					(set -x ; $CC $CFLAGS $JSONFLAGS $JSONSRC)
 | 
				
			||||||
 | 
					(set -x ; $CXX $CFLAGS $PROCSRC -o $PROCOUT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					rm ./*.o
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
#ifndef ARGPARSER_H
 | 
					#ifndef GEN_ARGPARSER_H
 | 
				
			||||||
#define ARGPARSER_H
 | 
					#define GEN_ARGPARSER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "aliases.h"
 | 
					#include "aliases.h"
 | 
				
			||||||
#include <argp.h>
 | 
					#include <argp.h>
 | 
				
			||||||
@@ -12,4 +12,4 @@ struct GeneratorArgs {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
GeneratorArgs parse_args(i32 argc, char *argv[]);
 | 
					GeneratorArgs parse_args(i32 argc, char *argv[]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // !ARGPARSER_H
 | 
					#endif // !GEN_ARGPARSER_H
 | 
				
			||||||
							
								
								
									
										30
									
								
								haversine_02/include/json/dstring.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								haversine_02/include/json/dstring.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					#ifndef DSTRING_H
 | 
				
			||||||
 | 
					#define DSTRING_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "aliases.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct dstring dstr_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dstr_t *dstr_with_capacity(u64 capacity);
 | 
				
			||||||
 | 
					dstr_t *dstr_from_string(const char *str);
 | 
				
			||||||
 | 
					void dstr_update(dstr_t **dst, const char *src);
 | 
				
			||||||
 | 
					void dstr_free(dstr_t **str);
 | 
				
			||||||
 | 
					void dstr_concat(dstr_t **dst, const char *src);
 | 
				
			||||||
 | 
					void dstr_append(dstr_t **dst, char c);
 | 
				
			||||||
 | 
					void dstr_resize(dstr_t **str);
 | 
				
			||||||
 | 
					void dstr_clear(dstr_t *str);
 | 
				
			||||||
 | 
					void dstr_print(const dstr_t *str);
 | 
				
			||||||
 | 
					i64 dstr_find(const dstr_t *str, const char *substr);
 | 
				
			||||||
 | 
					u64 dstr_length(const dstr_t *str);
 | 
				
			||||||
 | 
					u64 dstr_capacity(const dstr_t *str);
 | 
				
			||||||
 | 
					const char *dstr_to_cstr(const dstr_t *str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // !DSTRING_H
 | 
				
			||||||
							
								
								
									
										82
									
								
								haversine_02/include/json/json_entities.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								haversine_02/include/json/json_entities.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
				
			|||||||
 | 
					#ifndef JSON_ENTITIES_H
 | 
				
			||||||
 | 
					#define JSON_ENTITIES_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "aliases.h"
 | 
				
			||||||
 | 
					#include "dstring.h"
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct json_entity jentity_t;
 | 
				
			||||||
 | 
					typedef struct json_collection jcoll_t;
 | 
				
			||||||
 | 
					typedef struct json_value jval_t;
 | 
				
			||||||
 | 
					typedef struct json_pair jpair_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					  JVAL_EMPTY,
 | 
				
			||||||
 | 
					  JVAL_COLLECTION,
 | 
				
			||||||
 | 
					  JVAL_STRING,
 | 
				
			||||||
 | 
					  JVAL_INTEGER,
 | 
				
			||||||
 | 
					  JVAL_DOUBLE,
 | 
				
			||||||
 | 
					  JVAL_BOOLEAN,
 | 
				
			||||||
 | 
					  JVAL_NULL,
 | 
				
			||||||
 | 
					} jval_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct json_value {
 | 
				
			||||||
 | 
					  jval_type type;
 | 
				
			||||||
 | 
					  union {
 | 
				
			||||||
 | 
					    void *null_val;
 | 
				
			||||||
 | 
					    jcoll_t *collection;
 | 
				
			||||||
 | 
					    dstr_t *string;
 | 
				
			||||||
 | 
					    i64 num_int;
 | 
				
			||||||
 | 
					    f64 num_dbl;
 | 
				
			||||||
 | 
					    bool boolean;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct json_pair {
 | 
				
			||||||
 | 
					  dstr_t *key;
 | 
				
			||||||
 | 
					  jval_t value;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					  JENTITY_SINGLE,
 | 
				
			||||||
 | 
					  JENTITY_PAIR,
 | 
				
			||||||
 | 
					} jentity_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct json_entity {
 | 
				
			||||||
 | 
					  jentity_type type;
 | 
				
			||||||
 | 
					  union {
 | 
				
			||||||
 | 
					    jval_t value;
 | 
				
			||||||
 | 
					    jpair_t pair;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  jentity_t *parent;
 | 
				
			||||||
 | 
					  jentity_t *next;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					  JCOLL_OBJECT,
 | 
				
			||||||
 | 
					  JCOLL_ARRAY,
 | 
				
			||||||
 | 
					} jcoll_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct json_collection {
 | 
				
			||||||
 | 
					  u64 size;
 | 
				
			||||||
 | 
					  jcoll_type type;
 | 
				
			||||||
 | 
					  jentity_t *begin;
 | 
				
			||||||
 | 
					  jentity_t *end;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void print_json(const jentity_t *entity, u32 indent);
 | 
				
			||||||
 | 
					void free_json(jentity_t **entity);
 | 
				
			||||||
 | 
					jcoll_t *get_collection_from_entity(const jentity_t *entity);
 | 
				
			||||||
 | 
					jentity_t *create_new_single_entity(const jval_t value, jentity_t *parent);
 | 
				
			||||||
 | 
					jentity_t *create_new_pair_entity(dstr_t *key, const jval_t value,
 | 
				
			||||||
 | 
					                                  jentity_t *parent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // !JSON_ENTITIES_H
 | 
				
			||||||
							
								
								
									
										72
									
								
								haversine_02/include/json/lexer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								haversine_02/include/json/lexer.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
				
			|||||||
 | 
					#ifndef LEXER_STATES_H
 | 
				
			||||||
 | 
					#define LEXER_STATES_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "aliases.h"
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VALID_JSON true
 | 
				
			||||||
 | 
					#define INVALID_JSON false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef const char *str_view_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					  TK_NO_TOKEN,
 | 
				
			||||||
 | 
					  TK_L_BRACE,
 | 
				
			||||||
 | 
					  TK_R_BRACE,
 | 
				
			||||||
 | 
					  TK_L_BRACKET,
 | 
				
			||||||
 | 
					  TK_R_BRACKET,
 | 
				
			||||||
 | 
					  TK_NULL,
 | 
				
			||||||
 | 
					  TK_BOOL,
 | 
				
			||||||
 | 
					  TK_STR_KEY,
 | 
				
			||||||
 | 
					  TK_STR_VAL,
 | 
				
			||||||
 | 
					  TK_INTEGER,
 | 
				
			||||||
 | 
					  TK_DOUBLE,
 | 
				
			||||||
 | 
					} token_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef union {
 | 
				
			||||||
 | 
					  void *no_val;
 | 
				
			||||||
 | 
					  i64 num_int;
 | 
				
			||||||
 | 
					  f64 num_frac;
 | 
				
			||||||
 | 
					  str_view_t string;
 | 
				
			||||||
 | 
					  bool boolean;
 | 
				
			||||||
 | 
					} token_value_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  u64 line;
 | 
				
			||||||
 | 
					  u64 column;
 | 
				
			||||||
 | 
					  token_type type;
 | 
				
			||||||
 | 
					  token_value_t value;
 | 
				
			||||||
 | 
					} token_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					  LEX_ERR_NONE,
 | 
				
			||||||
 | 
					  LEX_ERR_INVALID,
 | 
				
			||||||
 | 
					} lex_err_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  lex_err_type errno;
 | 
				
			||||||
 | 
					  str_view_t msg;
 | 
				
			||||||
 | 
					} lex_err_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  lex_err_t error;
 | 
				
			||||||
 | 
					  token_t token;
 | 
				
			||||||
 | 
					} lex_result_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct lexer_s lexer_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void lexer_init(lexer_t **lexer);
 | 
				
			||||||
 | 
					void lexer_free(lexer_t **lexer);
 | 
				
			||||||
 | 
					lex_result_t get_next_token(lexer_t *lexer, const char *text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void print_token(token_t token);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // !LEXER_STATES_H
 | 
				
			||||||
							
								
								
									
										19
									
								
								haversine_02/include/json/parser.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								haversine_02/include/json/parser.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					#ifndef PARSER_H
 | 
				
			||||||
 | 
					#define PARSER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "json_entities.h"
 | 
				
			||||||
 | 
					#include "lexer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct parser_s parser_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jentity_t *load_json(const char *filepath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // !PARSER_H
 | 
				
			||||||
@@ -1,15 +1,16 @@
 | 
				
			|||||||
#include "argparser.h"
 | 
					#include "generator/gen_argparser.h"
 | 
				
			||||||
 | 
					#include "aliases.h"
 | 
				
			||||||
#include <argp.h>
 | 
					#include <argp.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <time.h>
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static error_t argp_parser(i32 key, char *arg, argp_state *state);
 | 
					INTERNAL error_t argp_parser(i32 key, char *arg, argp_state *state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static argp parser = {};
 | 
					INTERNAL argp parser = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static argp_option options[] = {
 | 
					INTERNAL argp_option options[] = {
 | 
				
			||||||
    {.name = "seed", .key = 's', .arg = "SEED"},
 | 
					    {.name = "seed", .key = 's', .arg = "SEED"},
 | 
				
			||||||
    {.name = "cluster", .key = 'c'},
 | 
					    {.name = "cluster", .key = 'c'},
 | 
				
			||||||
    {0, 0, 0, 0, 0, 0},
 | 
					    {0, 0, 0, 0, 0, 0},
 | 
				
			||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
#include "generator.h"
 | 
					#include "generator/generator.h"
 | 
				
			||||||
#include "aliases.h"
 | 
					#include "aliases.h"
 | 
				
			||||||
#include "point_types.h"
 | 
					#include "point_types.h"
 | 
				
			||||||
#include <math.h>
 | 
					#include <math.h>
 | 
				
			||||||
@@ -1,11 +1,10 @@
 | 
				
			|||||||
#include "aliases.h"
 | 
					#include "aliases.h"
 | 
				
			||||||
#include "argparser.h"
 | 
					#include "generator/gen_argparser.h"
 | 
				
			||||||
#include "generator.h"
 | 
					#include "generator/generator.h"
 | 
				
			||||||
#include "haversine.h"
 | 
					#include "haversine.h"
 | 
				
			||||||
#include "point_types.h"
 | 
					#include "point_types.h"
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <time.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define EARTH_RADIUS_KM 6371.0
 | 
					#define EARTH_RADIUS_KM 6371.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										211
									
								
								haversine_02/src/json/dstring.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								haversine_02/src/json/dstring.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,211 @@
 | 
				
			|||||||
 | 
					#include "json/dstring.h"
 | 
				
			||||||
 | 
					#include "aliases.h"
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Use this scalar to allocate extra memory in order to avoid having to
 | 
				
			||||||
 | 
					// constantly reallocate
 | 
				
			||||||
 | 
					#define CAPACITY_SCALAR 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dstring {
 | 
				
			||||||
 | 
					  u64 capacity;
 | 
				
			||||||
 | 
					  u64 size;
 | 
				
			||||||
 | 
					  char buf[];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dstr_t *dstr_with_capacity(u64 capacity) {
 | 
				
			||||||
 | 
					  dstr_t *out = (dstr_t *)malloc(sizeof(dstr_t) + capacity + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!out) {
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  out->capacity = capacity;
 | 
				
			||||||
 | 
					  out->size = 0;
 | 
				
			||||||
 | 
					  memset(out->buf, 0, capacity + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return out;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dstr_t *dstr_from_string(const char *str) {
 | 
				
			||||||
 | 
					  u64 length = strlen(str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  u64 capacity = length * CAPACITY_SCALAR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  dstr_t *out = dstr_with_capacity(capacity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!out) {
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  out->size = length;
 | 
				
			||||||
 | 
					  strncpy(out->buf, str, length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return out;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dstr_update(dstr_t **dst, const char *src) {
 | 
				
			||||||
 | 
					  if (!(*dst)) {
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  u64 length = strlen(src);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  dstr_t *str = *dst;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (length <= str->capacity) {
 | 
				
			||||||
 | 
					    memset(str->buf, 0, str->capacity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    str->size = length;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    strncpy(str->buf, src, length);
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    u64 capacity = length * CAPACITY_SCALAR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dstr_t *tmp = (dstr_t *)realloc(*dst, sizeof(dstr_t) + capacity + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!tmp) {
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    tmp->capacity = capacity;
 | 
				
			||||||
 | 
					    tmp->size = length;
 | 
				
			||||||
 | 
					    strncpy(tmp->buf, src, length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *dst = tmp;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dstr_free(dstr_t **str) {
 | 
				
			||||||
 | 
					  if (!(*str)) {
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  free(*str);
 | 
				
			||||||
 | 
					  *str = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dstr_concat(dstr_t **dst, const char *src) {
 | 
				
			||||||
 | 
					  if (!(*dst)) {
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  u64 src_length = strlen(src);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (src_length == 0) {
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  u64 new_length = (*dst)->size + src_length;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  char str[new_length + 1];
 | 
				
			||||||
 | 
					  memset(str, 0, new_length + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  strncpy(str, (*dst)->buf, (*dst)->size);
 | 
				
			||||||
 | 
					  strncat(str, src, src_length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  dstr_update(dst, str);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dstr_append(dstr_t **dst, char c) {
 | 
				
			||||||
 | 
					  if (!(*dst)) {
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  u64 new_length = (*dst)->size + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  char str[new_length + 1];
 | 
				
			||||||
 | 
					  memset(str, 0, new_length + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  strncpy(str, (*dst)->buf, (*dst)->size);
 | 
				
			||||||
 | 
					  str[(*dst)->size] = c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  dstr_update(dst, str);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dstr_resize(dstr_t **str) {
 | 
				
			||||||
 | 
					  u64 capacity = (*str)->size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  dstr_t *tmp = (dstr_t *)realloc(*str, sizeof(dstr_t) + capacity + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!tmp) {
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  tmp->capacity = capacity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  *str = tmp;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dstr_clear(dstr_t *str) {
 | 
				
			||||||
 | 
					  if (!str || str->size == 0) {
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  memset(str->buf, 0, str->capacity);
 | 
				
			||||||
 | 
					  str->size = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dstr_print(const dstr_t *str) {
 | 
				
			||||||
 | 
					  if (!str) {
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  printf("%s\n", str->buf);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					i64 dstr_find(const dstr_t *str, const char *substr) {
 | 
				
			||||||
 | 
					  if (!str || !substr) {
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  u64 substr_length = strlen(substr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (substr_length == 0 || substr_length > str->size) {
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  char buf[substr_length + 1];
 | 
				
			||||||
 | 
					  memset(buf, 0, substr_length + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (u64 i = 0; i < str->size; ++i) {
 | 
				
			||||||
 | 
					    if (i + substr_length >= str->size) {
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (u64 j = 0; j < substr_length; ++j) {
 | 
				
			||||||
 | 
					      buf[j] = str->buf[i + j];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (strcmp(buf, substr) == 0) {
 | 
				
			||||||
 | 
					      return i;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u64 dstr_length(const dstr_t *str) {
 | 
				
			||||||
 | 
					  if (!str) {
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return str->size;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u64 dstr_capacity(const dstr_t *str) {
 | 
				
			||||||
 | 
					  if (!str) {
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return str->capacity;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *dstr_to_cstr(const dstr_t *str) {
 | 
				
			||||||
 | 
					  if (!str) {
 | 
				
			||||||
 | 
					    return "";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return str->buf;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										194
									
								
								haversine_02/src/json/json_entities.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								haversine_02/src/json/json_entities.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,194 @@
 | 
				
			|||||||
 | 
					#include "json/json_entities.h"
 | 
				
			||||||
 | 
					#include "aliases.h"
 | 
				
			||||||
 | 
					#include "json/dstring.h"
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void print_json(const jentity_t *entity, u32 indent) {
 | 
				
			||||||
 | 
					  PERSISTENT i32 indentation = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  dstr_t *key = NULL;
 | 
				
			||||||
 | 
					  const jval_t *value = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (entity->type == JENTITY_SINGLE) {
 | 
				
			||||||
 | 
					    value = &(entity->value);
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    key = entity->pair.key;
 | 
				
			||||||
 | 
					    value = &(entity->pair.value);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (key) {
 | 
				
			||||||
 | 
					    printf("%*s\"%s\": ", indentation * indent, "", dstr_to_cstr(key));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  switch (value->type) {
 | 
				
			||||||
 | 
					  case JVAL_COLLECTION: {
 | 
				
			||||||
 | 
					    const char *open = "";
 | 
				
			||||||
 | 
					    const char *close = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (value->collection->type == JCOLL_OBJECT) {
 | 
				
			||||||
 | 
					      open = "{";
 | 
				
			||||||
 | 
					      close = "}";
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      open = "[";
 | 
				
			||||||
 | 
					      close = "]";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (key) {
 | 
				
			||||||
 | 
					      printf("%s\n", open);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      printf("%*s%s\n", indentation * indent, "", open);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ++indentation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (value->collection->begin) {
 | 
				
			||||||
 | 
					      print_json(value->collection->begin, indent);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    --indentation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("\n%*s%s", indentation * indent, "", close);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  case JVAL_STRING:
 | 
				
			||||||
 | 
					    if (key) {
 | 
				
			||||||
 | 
					      printf("\"%s\"", dstr_to_cstr(value->string));
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      printf("%*s\"%s\"", indentation * indent, "",
 | 
				
			||||||
 | 
					             dstr_to_cstr(value->string));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  case JVAL_INTEGER:
 | 
				
			||||||
 | 
					    if (key) {
 | 
				
			||||||
 | 
					      printf("%llu", (unsigned long long)value->num_int);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      printf("%*s%llu", indentation * indent, "",
 | 
				
			||||||
 | 
					             (unsigned long long)value->num_int);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  case JVAL_DOUBLE:
 | 
				
			||||||
 | 
					    if (key) {
 | 
				
			||||||
 | 
					      printf("%f", value->num_dbl);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      printf("%*s%f", indentation * indent, "", value->num_dbl);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  case JVAL_BOOLEAN:
 | 
				
			||||||
 | 
					    if (key) {
 | 
				
			||||||
 | 
					      printf("%s", value->boolean ? "true" : "false");
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      printf("%*s%s", indentation * indent, "",
 | 
				
			||||||
 | 
					             value->boolean ? "true" : "false");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  case JVAL_NULL:
 | 
				
			||||||
 | 
					    if (key) {
 | 
				
			||||||
 | 
					      printf("%s", "null");
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      printf("%*s%s", indentation * indent, "", "null");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  case JVAL_EMPTY:
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (entity->next) {
 | 
				
			||||||
 | 
					    printf(",\n");
 | 
				
			||||||
 | 
					    print_json(entity->next, indent);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Add newline after printing the entire json tree
 | 
				
			||||||
 | 
					  if (indentation == 0 && entity->parent == NULL && entity->next == NULL) {
 | 
				
			||||||
 | 
					    printf("\n");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void free_json(jentity_t **entity) {
 | 
				
			||||||
 | 
					  if (!(*entity)) {
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  jentity_t *entt_ptr = *entity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  dstr_t *key = NULL;
 | 
				
			||||||
 | 
					  const jval_t *value = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (entt_ptr->type == JENTITY_SINGLE) {
 | 
				
			||||||
 | 
					    value = &(entt_ptr->value);
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    key = entt_ptr->pair.key;
 | 
				
			||||||
 | 
					    value = &(entt_ptr->pair.value);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (key) {
 | 
				
			||||||
 | 
					    dstr_free(&(entt_ptr->pair.key));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  switch (value->type) {
 | 
				
			||||||
 | 
					  case JVAL_COLLECTION:
 | 
				
			||||||
 | 
					    if (value->collection->begin) {
 | 
				
			||||||
 | 
					      free_json(&(value->collection->begin));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    free(value->collection);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  case JVAL_STRING:
 | 
				
			||||||
 | 
					    dstr_free(&(entt_ptr->pair.value.string));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  default:
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (entt_ptr->next) {
 | 
				
			||||||
 | 
					    free_json(&(entt_ptr->next));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  free(*entity);
 | 
				
			||||||
 | 
					  *entity = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jcoll_t *get_collection_from_entity(const jentity_t *entity) {
 | 
				
			||||||
 | 
					  return entity->type == JENTITY_SINGLE ? entity->value.collection
 | 
				
			||||||
 | 
					                                        : entity->pair.value.collection;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jentity_t *create_new_single_entity(const jval_t value, jentity_t *parent) {
 | 
				
			||||||
 | 
					  jentity_t *entity = (jentity_t *)malloc(sizeof(jentity_t));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!entity) {
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  entity->type = JENTITY_SINGLE;
 | 
				
			||||||
 | 
					  entity->value = value;
 | 
				
			||||||
 | 
					  entity->parent = parent;
 | 
				
			||||||
 | 
					  entity->next = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return entity;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jentity_t *create_new_pair_entity(dstr_t *key, const jval_t value,
 | 
				
			||||||
 | 
					                                  jentity_t *parent) {
 | 
				
			||||||
 | 
					  jentity_t *entity = (jentity_t *)malloc(sizeof(jentity_t));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!entity) {
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  entity->type = JENTITY_PAIR;
 | 
				
			||||||
 | 
					  entity->pair.key = key;
 | 
				
			||||||
 | 
					  entity->pair.value = value;
 | 
				
			||||||
 | 
					  entity->parent = parent;
 | 
				
			||||||
 | 
					  entity->next = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return entity;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1067
									
								
								haversine_02/src/json/lexer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1067
									
								
								haversine_02/src/json/lexer.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										256
									
								
								haversine_02/src/json/parser.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										256
									
								
								haversine_02/src/json/parser.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,256 @@
 | 
				
			|||||||
 | 
					#include "json/parser.h"
 | 
				
			||||||
 | 
					#include "aliases.h"
 | 
				
			||||||
 | 
					#include "json/dstring.h"
 | 
				
			||||||
 | 
					#include "json/json_entities.h"
 | 
				
			||||||
 | 
					#include "json/lexer.h"
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct parser_s {
 | 
				
			||||||
 | 
					  jentity_t *root;
 | 
				
			||||||
 | 
					  jentity_t *current;
 | 
				
			||||||
 | 
					  jval_t value;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					INTERNAL void parser_free(parser_t **parser);
 | 
				
			||||||
 | 
					INTERNAL void parser_init(parser_t **parser);
 | 
				
			||||||
 | 
					INTERNAL void parse_token(parser_t *parser, token_t token);
 | 
				
			||||||
 | 
					INTERNAL void add_key(parser_t *parser, dstr_t *key);
 | 
				
			||||||
 | 
					INTERNAL jentity_t *add_value(parser_t *parser);
 | 
				
			||||||
 | 
					INTERNAL void add_collection(parser_t *parser);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jentity_t *load_json(const char *filepath) {
 | 
				
			||||||
 | 
					  FILE *fp = fopen(filepath, "r");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!fp) {
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  fseek(fp, 0, SEEK_END);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  u64 length = ftell(fp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  fseek(fp, 0, SEEK_SET);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  char json[length + 1];
 | 
				
			||||||
 | 
					  memset(json, 0, length + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  fread(json, sizeof(char), length, fp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  fclose(fp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  lexer_t *lexer = NULL;
 | 
				
			||||||
 | 
					  parser_t *parser = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  lexer_init(&lexer);
 | 
				
			||||||
 | 
					  if (!lexer) {
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  parser_init(&parser);
 | 
				
			||||||
 | 
					  if (!parser) {
 | 
				
			||||||
 | 
					    lexer_free(&lexer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  lex_result_t result = get_next_token(lexer, json);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (result.error.errno) {
 | 
				
			||||||
 | 
					    printf("%s\n", result.error.msg);
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    while (result.token.type != TK_NO_TOKEN) {
 | 
				
			||||||
 | 
					      parse_token(parser, result.token);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      result = get_next_token(lexer, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (result.error.errno) {
 | 
				
			||||||
 | 
					        printf("%s\n", result.error.msg);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  jentity_t *root = parser->root;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  parser_free(&parser);
 | 
				
			||||||
 | 
					  lexer_free(&lexer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return root;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void parser_init(parser_t **parser) {
 | 
				
			||||||
 | 
					  if (*parser) {
 | 
				
			||||||
 | 
					    parser_free(parser);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  *parser = (parser_t *)malloc(sizeof(parser_t));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!(*parser)) {
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (*parser)->root = NULL;
 | 
				
			||||||
 | 
					  (*parser)->current = NULL;
 | 
				
			||||||
 | 
					  (*parser)->value = (jval_t){};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void parser_free(parser_t **parser) {
 | 
				
			||||||
 | 
					  if (!(*parser)) {
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (*parser)->root = NULL;
 | 
				
			||||||
 | 
					  (*parser)->current = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  free(*parser);
 | 
				
			||||||
 | 
					  *parser = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void parse_token(parser_t *parser, token_t token) {
 | 
				
			||||||
 | 
					  switch (token.type) {
 | 
				
			||||||
 | 
					  case TK_L_BRACE:
 | 
				
			||||||
 | 
					  case TK_L_BRACKET: {
 | 
				
			||||||
 | 
					    parser->value = (jval_t){
 | 
				
			||||||
 | 
					        .type = JVAL_COLLECTION,
 | 
				
			||||||
 | 
					        .collection = (jcoll_t *)malloc(sizeof(jcoll_t)),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (token.type == TK_L_BRACE) {
 | 
				
			||||||
 | 
					      parser->value.collection->type = JCOLL_OBJECT;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      parser->value.collection->type = JCOLL_ARRAY;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    parser->value.collection->size = 0;
 | 
				
			||||||
 | 
					    parser->value.collection->begin = NULL;
 | 
				
			||||||
 | 
					    parser->value.collection->end = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    add_collection(parser);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  case TK_R_BRACE:
 | 
				
			||||||
 | 
					  case TK_R_BRACKET:
 | 
				
			||||||
 | 
					    if (parser->current->parent) {
 | 
				
			||||||
 | 
					      parser->current = parser->current->parent;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  case TK_STR_KEY: {
 | 
				
			||||||
 | 
					    parser->value = (jval_t){.type = JVAL_EMPTY, .null_val = NULL};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    add_key(parser, dstr_from_string(token.value.string));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  case TK_NULL: {
 | 
				
			||||||
 | 
					    parser->value = (jval_t){.type = JVAL_NULL, .null_val = NULL};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    add_value(parser);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  case TK_BOOL: {
 | 
				
			||||||
 | 
					    parser->value =
 | 
				
			||||||
 | 
					        (jval_t){.type = JVAL_BOOLEAN, .boolean = token.value.boolean};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    add_value(parser);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  case TK_STR_VAL: {
 | 
				
			||||||
 | 
					    parser->value = (jval_t){.type = JVAL_STRING,
 | 
				
			||||||
 | 
					                             .string = dstr_from_string(token.value.string)};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    add_value(parser);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  case TK_INTEGER: {
 | 
				
			||||||
 | 
					    parser->value =
 | 
				
			||||||
 | 
					        (jval_t){.type = JVAL_INTEGER, .num_int = token.value.num_int};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    add_value(parser);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  case TK_DOUBLE: {
 | 
				
			||||||
 | 
					    parser->value =
 | 
				
			||||||
 | 
					        (jval_t){.type = JVAL_DOUBLE, .num_dbl = token.value.num_frac};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    add_value(parser);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  case TK_NO_TOKEN:
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void add_key(parser_t *parser, dstr_t *key) {
 | 
				
			||||||
 | 
					  jcoll_t *collection = get_collection_from_entity(parser->current);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!collection) {
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!(collection->end)) {
 | 
				
			||||||
 | 
					    collection->begin = collection->end =
 | 
				
			||||||
 | 
					        create_new_pair_entity(key, parser->value, parser->current);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    collection->size = 1;
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    jentity_t *new_entity =
 | 
				
			||||||
 | 
					        create_new_pair_entity(key, parser->value, parser->current);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    collection->end->next = new_entity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    collection->end = new_entity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ++(collection->size);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jentity_t *add_value(parser_t *parser) {
 | 
				
			||||||
 | 
					  jcoll_t *collection = get_collection_from_entity(parser->current);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!collection) {
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!(collection->end)) {
 | 
				
			||||||
 | 
					    collection->begin = collection->end =
 | 
				
			||||||
 | 
					        create_new_single_entity(parser->value, parser->current);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    collection->size = 1;
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    if (collection->end->type == JENTITY_PAIR &&
 | 
				
			||||||
 | 
					        collection->end->pair.value.type == JVAL_EMPTY) {
 | 
				
			||||||
 | 
					      collection->end->pair.value = parser->value;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      jentity_t *new_entity =
 | 
				
			||||||
 | 
					          create_new_single_entity(parser->value, parser->current);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      collection->end->next = new_entity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      collection->end = new_entity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ++(collection->size);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return collection->end;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void add_collection(parser_t *parser) {
 | 
				
			||||||
 | 
					  if (!(parser->root)) {
 | 
				
			||||||
 | 
					    parser->root = parser->current =
 | 
				
			||||||
 | 
					        create_new_single_entity(parser->value, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  parser->current = add_value(parser);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,47 +0,0 @@
 | 
				
			|||||||
#include "aliases.h"
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <stdlib.h>
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
i32 main(i32 argc, char *argv[]) {
 | 
					 | 
				
			||||||
  if (argc < 2) {
 | 
					 | 
				
			||||||
    printf("Missing filename\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return EXIT_FAILURE;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const char *filename = argv[1];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  FILE *fp = fopen(filename, "r");
 | 
					 | 
				
			||||||
  if (!fp) {
 | 
					 | 
				
			||||||
    printf("Failed to open file: %s\n", filename);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return EXIT_FAILURE;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  fseek(fp, 0, SEEK_END);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  u64 length = ftell(fp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  fseek(fp, 0, SEEK_SET);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  char text[length + 1];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  memset(text, 0, length);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  fread(text, sizeof(char), length, fp);
 | 
					 | 
				
			||||||
  text[length] = '\0';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const char *delim = ", \t\n";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  char *token = strtok(text, delim);
 | 
					 | 
				
			||||||
  while (token) {
 | 
					 | 
				
			||||||
    printf("TOKEN: %s\n", token);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    token = strtok(NULL, delim);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  fclose(fp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return EXIT_SUCCESS;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Reference in New Issue
	
	Block a user