mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-11-03 23:36:12 -08:00 
			
		
		
		
	
		
			
				
	
	
		
			434 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			434 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#ifdef INTELLISENSE_DIRECTIVES
 | 
						|
#	pragma once
 | 
						|
#	include "timing.hpp"
 | 
						|
#endif
 | 
						|
 | 
						|
#pragma region ADT
 | 
						|
 | 
						|
enum ADT_Type : u32
 | 
						|
{
 | 
						|
	EADT_TYPE_UNINITIALISED, /* node was not initialised, this is a programming error! */
 | 
						|
	EADT_TYPE_ARRAY,
 | 
						|
	EADT_TYPE_OBJECT,
 | 
						|
	EADT_TYPE_STRING,
 | 
						|
	EADT_TYPE_MULTISTRING,
 | 
						|
	EADT_TYPE_INTEGER,
 | 
						|
	EADT_TYPE_REAL,
 | 
						|
};
 | 
						|
 | 
						|
enum ADT_Props : u32
 | 
						|
{
 | 
						|
	EADT_PROPS_NONE,
 | 
						|
	EADT_PROPS_NAN,
 | 
						|
	EADT_PROPS_NAN_NEG,
 | 
						|
	EADT_PROPS_INFINITY,
 | 
						|
	EADT_PROPS_INFINITY_NEG,
 | 
						|
	EADT_PROPS_FALSE,
 | 
						|
	EADT_PROPS_TRUE,
 | 
						|
	EADT_PROPS_NULL,
 | 
						|
	EADT_PROPS_IS_EXP,
 | 
						|
	EADT_PROPS_IS_HEX,
 | 
						|
 | 
						|
	// Used internally so that people can fill in real numbers they plan to write.
 | 
						|
	EADT_PROPS_IS_PARSED_REAL,
 | 
						|
};
 | 
						|
 | 
						|
enum ADT_NamingStyle : u32
 | 
						|
{
 | 
						|
	EADT_NAME_STYLE_DOUBLE_QUOTE,
 | 
						|
	EADT_NAME_STYLE_SINGLE_QUOTE,
 | 
						|
	EADT_NAME_STYLE_NO_QUOTES,
 | 
						|
};
 | 
						|
 | 
						|
enum ADT_AssignStyle : u32
 | 
						|
{
 | 
						|
	EADT_ASSIGN_STYLE_COLON,
 | 
						|
	EADT_ASSIGN_STYLE_EQUALS,
 | 
						|
	EADT_ASSIGN_STYLE_LINE,
 | 
						|
};
 | 
						|
 | 
						|
enum ADT_DelimStyle : u32
 | 
						|
{
 | 
						|
	EADT_DELIM_STYLE_COMMA,
 | 
						|
	EADT_DELIM_STYLE_LINE,
 | 
						|
	EADT_DELIM_STYLE_NEWLINE,
 | 
						|
};
 | 
						|
 | 
						|
enum ADT_Error : u32
 | 
						|
{
 | 
						|
	EADT_ERROR_NONE,
 | 
						|
	EADT_ERROR_INTERNAL,
 | 
						|
	EADT_ERROR_ALREADY_CONVERTED,
 | 
						|
	EADT_ERROR_INVALID_TYPE,
 | 
						|
	EADT_ERROR_OUT_OF_MEMORY,
 | 
						|
};
 | 
						|
 | 
						|
struct ADT_Node
 | 
						|
{
 | 
						|
	char const*      name;
 | 
						|
	struct ADT_Node* parent;
 | 
						|
 | 
						|
	/* properties */
 | 
						|
	ADT_Type type  : 4;
 | 
						|
	u8 props : 4;
 | 
						|
#ifndef GEN_PARSER_DISABLE_ANALYSIS
 | 
						|
	u8 cfg_mode          : 1;
 | 
						|
	u8 name_style        : 2;
 | 
						|
	u8 assign_style      : 2;
 | 
						|
	u8 delim_style       : 2;
 | 
						|
	u8 delim_line_width  : 4;
 | 
						|
	u8 assign_line_width : 4;
 | 
						|
#endif
 | 
						|
 | 
						|
	/* adt data */
 | 
						|
	union
 | 
						|
	{
 | 
						|
		char const*     string;
 | 
						|
		Array(ADT_Node) nodes;    ///< zpl_array
 | 
						|
 | 
						|
		struct
 | 
						|
		{
 | 
						|
			union
 | 
						|
			{
 | 
						|
				f64 real;
 | 
						|
				s64 integer;
 | 
						|
			};
 | 
						|
 | 
						|
#ifndef GEN_PARSER_DISABLE_ANALYSIS
 | 
						|
			/* number analysis */
 | 
						|
			s32 base;
 | 
						|
			s32 base2;
 | 
						|
			u8  base2_offset : 4;
 | 
						|
			s8  exp          : 4;
 | 
						|
			u8  neg_zero     : 1;
 | 
						|
			u8  lead_digit   : 1;
 | 
						|
#endif
 | 
						|
		};
 | 
						|
	};
 | 
						|
};
 | 
						|
 | 
						|
/* ADT NODE LIMITS
 | 
						|
	* delimiter and assignment segment width is limited to 128 whitespace symbols each.
 | 
						|
	* real number limits decimal position to 128 places.
 | 
						|
	* real number exponent is limited to 64 digits.
 | 
						|
	*/
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Initialise an ADT object or array
 | 
						|
	*
 | 
						|
	* @param node
 | 
						|
	* @param backing Memory allocator used for descendants
 | 
						|
	* @param name Node's name
 | 
						|
	* @param is_array
 | 
						|
	* @return error code
 | 
						|
	*/
 | 
						|
GEN_API u8 adt_make_branch( ADT_Node* node, AllocatorInfo backing, char const* name, b32 is_array );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Destroy an ADT branch and its descendants
 | 
						|
	*
 | 
						|
	* @param node
 | 
						|
	* @return error code
 | 
						|
	*/
 | 
						|
GEN_API u8 adt_destroy_branch( ADT_Node* node );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Initialise an ADT leaf
 | 
						|
	*
 | 
						|
	* @param node
 | 
						|
	* @param name Node's name
 | 
						|
	* @param type Node's type (use zpl_adt_make_branch for container nodes)
 | 
						|
	* @return error code
 | 
						|
	*/
 | 
						|
GEN_API u8 adt_make_leaf( ADT_Node* node, char const* name, ADT_Type type );
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Fetch a node using provided URI string.
 | 
						|
	*
 | 
						|
	* This method uses a basic syntax to fetch a node from the ADT. The following features are available
 | 
						|
	* to retrieve the data:
 | 
						|
	*
 | 
						|
	* - "a/b/c" navigates through objects "a" and "b" to get to "c"
 | 
						|
	* - "arr/[foo=123]/bar" iterates over "arr" to find any object with param "foo" that matches the value "123", then gets its field called "bar"
 | 
						|
	* - "arr/3" retrieves the 4th element in "arr"
 | 
						|
	* - "arr/[apple]" retrieves the first element of value "apple" in "arr"
 | 
						|
	*
 | 
						|
	* @param node ADT node
 | 
						|
	* @param uri Locator string as described above
 | 
						|
	* @return zpl_adt_node*
 | 
						|
	*
 | 
						|
	* @see code/apps/examples/json_get.c
 | 
						|
	*/
 | 
						|
GEN_API ADT_Node* adt_query( ADT_Node* node, char const* uri );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Find a field node within an object by the given name.
 | 
						|
	*
 | 
						|
	* @param node
 | 
						|
	* @param name
 | 
						|
	* @param deep_search Perform search recursively
 | 
						|
	* @return zpl_adt_node * node
 | 
						|
	*/
 | 
						|
GEN_API ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Allocate an unitialised node within a container at a specified index.
 | 
						|
	*
 | 
						|
	* @param parent
 | 
						|
	* @param index
 | 
						|
	* @return zpl_adt_node * node
 | 
						|
	*/
 | 
						|
GEN_API ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Allocate an unitialised node within a container.
 | 
						|
	*
 | 
						|
	* @param parent
 | 
						|
	* @return zpl_adt_node * node
 | 
						|
	*/
 | 
						|
GEN_API ADT_Node* adt_alloc( ADT_Node* parent );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Move an existing node to a new container at a specified index.
 | 
						|
	*
 | 
						|
	* @param node
 | 
						|
	* @param new_parent
 | 
						|
	* @param index
 | 
						|
	* @return zpl_adt_node * node
 | 
						|
	*/
 | 
						|
GEN_API ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, ssize index );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Move an existing node to a new container.
 | 
						|
	*
 | 
						|
	* @param node
 | 
						|
	* @param new_parent
 | 
						|
	* @return zpl_adt_node * node
 | 
						|
	*/
 | 
						|
GEN_API ADT_Node* adt_move_node( ADT_Node* node, ADT_Node* new_parent );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Swap two nodes.
 | 
						|
	*
 | 
						|
	* @param node
 | 
						|
	* @param other_node
 | 
						|
	* @return
 | 
						|
	*/
 | 
						|
GEN_API void adt_swap_nodes( ADT_Node* node, ADT_Node* other_node );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Remove node from container.
 | 
						|
	*
 | 
						|
	* @param node
 | 
						|
	* @return
 | 
						|
	*/
 | 
						|
GEN_API void adt_remove_node( ADT_Node* node );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Initialise a node as an object
 | 
						|
	*
 | 
						|
	* @param obj
 | 
						|
	* @param name
 | 
						|
	* @param backing
 | 
						|
	* @return
 | 
						|
	*/
 | 
						|
GEN_API b8 adt_set_obj( ADT_Node* obj, char const* name, AllocatorInfo backing );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Initialise a node as an array
 | 
						|
	*
 | 
						|
	* @param obj
 | 
						|
	* @param name
 | 
						|
	* @param backing
 | 
						|
	* @return
 | 
						|
	*/
 | 
						|
GEN_API b8 adt_set_arr( ADT_Node* obj, char const* name, AllocatorInfo backing );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Initialise a node as a string
 | 
						|
	*
 | 
						|
	* @param obj
 | 
						|
	* @param name
 | 
						|
	* @param value
 | 
						|
	* @return
 | 
						|
	*/
 | 
						|
GEN_API b8 adt_set_str( ADT_Node* obj, char const* name, char const* value );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Initialise a node as a float
 | 
						|
	*
 | 
						|
	* @param obj
 | 
						|
	* @param name
 | 
						|
	* @param value
 | 
						|
	* @return
 | 
						|
	*/
 | 
						|
GEN_API b8 adt_set_flt( ADT_Node* obj, char const* name, f64 value );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Initialise a node as a signed integer
 | 
						|
	*
 | 
						|
	* @param obj
 | 
						|
	* @param name
 | 
						|
	* @param value
 | 
						|
	* @return
 | 
						|
	*/
 | 
						|
GEN_API b8 adt_set_int( ADT_Node* obj, char const* name, s64 value );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Append a new node to a container as an object
 | 
						|
	*
 | 
						|
	* @param parent
 | 
						|
	* @param name
 | 
						|
	* @return*
 | 
						|
	*/
 | 
						|
GEN_API ADT_Node* adt_append_obj( ADT_Node* parent, char const* name );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Append a new node to a container as an array
 | 
						|
	*
 | 
						|
	* @param parent
 | 
						|
	* @param name
 | 
						|
	* @return*
 | 
						|
	*/
 | 
						|
GEN_API ADT_Node* adt_append_arr( ADT_Node* parent, char const* name );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Append a new node to a container as a string
 | 
						|
	*
 | 
						|
	* @param parent
 | 
						|
	* @param name
 | 
						|
	* @param value
 | 
						|
	* @return*
 | 
						|
	*/
 | 
						|
GEN_API ADT_Node* adt_append_str( ADT_Node* parent, char const* name, char const* value );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Append a new node to a container as a float
 | 
						|
	*
 | 
						|
	* @param parent
 | 
						|
	* @param name
 | 
						|
	* @param value
 | 
						|
	* @return*
 | 
						|
	*/
 | 
						|
GEN_API ADT_Node* adt_append_flt( ADT_Node* parent, char const* name, f64 value );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Append a new node to a container as a signed integer
 | 
						|
	*
 | 
						|
	* @param parent
 | 
						|
	* @param name
 | 
						|
	* @param value
 | 
						|
	* @return*
 | 
						|
	*/
 | 
						|
GEN_API ADT_Node* adt_append_int( ADT_Node* parent, char const* name, s64 value );
 | 
						|
 | 
						|
/* parser helpers */
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Parses a text and stores the result into an unitialised node.
 | 
						|
	*
 | 
						|
	* @param node
 | 
						|
	* @param base
 | 
						|
	* @return*
 | 
						|
	*/
 | 
						|
GEN_API char* adt_parse_number( ADT_Node* node, char* base );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Parses a text and stores the result into an unitialised node.
 | 
						|
	* This function expects the entire input to be a number.
 | 
						|
	*
 | 
						|
	* @param node
 | 
						|
	* @param base
 | 
						|
	* @return*
 | 
						|
	*/
 | 
						|
GEN_API char* adt_parse_number_strict( ADT_Node* node, char* base_str );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Parses and converts an existing string node into a number.
 | 
						|
	*
 | 
						|
	* @param node
 | 
						|
	* @return
 | 
						|
	*/
 | 
						|
GEN_API ADT_Error adt_c_str_to_number( ADT_Node* node );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Parses and converts an existing string node into a number.
 | 
						|
	* This function expects the entire input to be a number.
 | 
						|
	*
 | 
						|
	* @param node
 | 
						|
	* @return
 | 
						|
	*/
 | 
						|
GEN_API ADT_Error adt_c_str_to_number_strict( ADT_Node* node );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Prints a number into a file stream.
 | 
						|
	*
 | 
						|
	* The provided file handle can also be a memory mapped stream.
 | 
						|
	*
 | 
						|
	* @see zpl_file_stream_new
 | 
						|
	* @param file
 | 
						|
	* @param node
 | 
						|
	* @return
 | 
						|
	*/
 | 
						|
GEN_API ADT_Error adt_print_number( FileInfo* file, ADT_Node* node );
 | 
						|
 | 
						|
/**
 | 
						|
	* @brief Prints a string into a file stream.
 | 
						|
	*
 | 
						|
	* The provided file handle can also be a memory mapped stream.
 | 
						|
	*
 | 
						|
	* @see zpl_file_stream_new
 | 
						|
	* @param file
 | 
						|
	* @param node
 | 
						|
	* @param escaped_chars
 | 
						|
	* @param escape_symbol
 | 
						|
	* @return
 | 
						|
	*/
 | 
						|
GEN_API ADT_Error adt_print_string( FileInfo* file, ADT_Node* node, char const* escaped_chars, char const* escape_symbol );
 | 
						|
 | 
						|
#pragma endregion ADT
 | 
						|
 | 
						|
#pragma region CSV
 | 
						|
 | 
						|
enum CSV_Error : u32
 | 
						|
{
 | 
						|
	ECSV_Error__NONE,
 | 
						|
	ECSV_Error__INTERNAL,
 | 
						|
	ECSV_Error__UNEXPECTED_END_OF_INPUT,
 | 
						|
	ECSV_Error__MISMATCHED_ROWS,
 | 
						|
};
 | 
						|
 | 
						|
typedef ADT_Node CSV_Object;
 | 
						|
 | 
						|
        u8   csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header );
 | 
						|
GEN_API u8   csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header, char delim );
 | 
						|
        void csv_free( CSV_Object* obj );
 | 
						|
 | 
						|
        void       csv_write( FileInfo* file, CSV_Object* obj );
 | 
						|
        StrBuilder csv_write_string( AllocatorInfo a, CSV_Object* obj );
 | 
						|
GEN_API void       csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim );
 | 
						|
GEN_API StrBuilder csv_write_strbuilder_delimiter( AllocatorInfo a, CSV_Object* obj, char delim );
 | 
						|
 | 
						|
/* inline */
 | 
						|
 | 
						|
inline
 | 
						|
u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header )
 | 
						|
{
 | 
						|
	return csv_parse_delimiter( root, text, allocator, has_header, ',' );
 | 
						|
}
 | 
						|
 | 
						|
inline
 | 
						|
void csv_write( FileInfo* file, CSV_Object* obj )
 | 
						|
{
 | 
						|
	csv_write_delimiter( file, obj, ',' );
 | 
						|
}
 | 
						|
 | 
						|
inline
 | 
						|
StrBuilder csv_write_string( AllocatorInfo a, CSV_Object* obj )
 | 
						|
{
 | 
						|
	return csv_write_strbuilder_delimiter( a, obj, ',' );
 | 
						|
}
 | 
						|
 | 
						|
#pragma endregion CSV
 |