Move json to submodule

master
teknomunk 2 years ago
parent e31b804fdc
commit 12292c201e

3
.gitmodules vendored

@ -0,0 +1,3 @@
[submodule "src/json"]
path = src/json
url = https://teknomunk@gitea.polaris-1.work/teknomunk/json.git

@ -0,0 +1 @@
Subproject commit 5dd89c8024b5ac0a3eb3675cc3871799e9c9c010

@ -1,463 +0,0 @@
#include "json.h"
#include <stdint.h>
#include <stdlib.h>
#include <ctype.h>
enum parser_state
{
ps_object_expect_key = 1,
ps_object_expect_comma_then_key = 2,
ps_object_expect_value = 3,
ps_array_expect_value = 11,
ps_array_expect_comma_then_value = 12,
ps_expect_value = 20,
};
struct json_pull_parser
{
FILE* f;
int curr_state;
};
static void eat_whitespace( FILE* f )
{
for(;;) {
int i = fgetc(f);
if( i == EOF ) {
return;
}
if( !isspace(i) ) {
ungetc(i,f);
return;
}
}
}
static bool json_pull_parser_handle_array_comma( struct json_pull_parser* jpp )
{
eat_whitespace(jpp->f);
switch( jpp->curr_state ) {
case ps_array_expect_comma_then_value:
break;
case ps_object_expect_key:
case ps_object_expect_comma_then_key:
return false;
default:
return true;
}
int i = fgetc(jpp->f);
if( i == ']' ) {
ungetc(i,jpp->f);
return true;
}
if( i != ',' ) {
printf( "expecting comma, got %c(%d)\n", (char)i, i );
return false;
}
eat_whitespace(jpp->f);
return true;
}
static bool finish_value_read( struct json_pull_parser* jpp, bool result )
{
switch( jpp->curr_state ) {
case ps_object_expect_value:
jpp->curr_state = ps_object_expect_comma_then_key;
break;
case ps_array_expect_value:
jpp->curr_state = ps_array_expect_comma_then_value;
break;
}
return result;
}
struct json_pull_parser* json_pull_parser_new( FILE* f )
{
if( !f ) {
return NULL;
}
struct json_pull_parser* jpp = (struct json_pull_parser*)malloc( sizeof( struct json_pull_parser ) );
if( !jpp ) {
return NULL;
}
jpp->f = f;
jpp->curr_state = ps_expect_value;
return jpp;
}
void json_pull_parser_release( struct json_pull_parser* jpp )
{
free(jpp);
}
bool json_pull_parser_begin_object( struct json_pull_parser* jpp, int* save )
{
if( !json_pull_parser_handle_array_comma( jpp ) ) {
return false;
}
*save = jpp->curr_state;
FILE* f = jpp->f;
eat_whitespace(f);
int i = fgetc( f );
if( i != '{' ) {
ungetc( i, jpp->f );
return false;
}
jpp->curr_state = ps_object_expect_key;
return true;
}
bool json_pull_parser_end_object( struct json_pull_parser* jpp, int* save )
{
eat_whitespace( jpp->f );
int i = fgetc( jpp->f );
if( i != '}' ) {
printf( "Missing }, got %c (%d)\n", (char)i, i );
return false;
}
jpp->curr_state = *save;
return finish_value_read( jpp, true );
}
bool json_pull_parser_begin_array( struct json_pull_parser* jpp, int* save )
{
*save = jpp->curr_state;
eat_whitespace(jpp->f);
int i = fgetc(jpp->f);
if( i != '[' ) {
printf( "Unable to start array, i=%c(%d)\n", (char)i, i );
ungetc( i, jpp->f );
return false;
}
jpp->curr_state = ps_array_expect_value;
return true;
}
bool json_pull_parser_end_array( struct json_pull_parser* jpp, int* save )
{
eat_whitespace(jpp->f);
int i = fgetc( jpp->f );
if( i != ']' ) {
ungetc(i,jpp->f);
return false;
}
jpp->curr_state = *save;
return finish_value_read( jpp, true );
}
static char* json_pull_parser_raw_read_string( struct json_pull_parser* jpp )
{
eat_whitespace(jpp->f);
int c = fgetc(jpp->f);
if( c != '"' ) {
ungetc(c,jpp->f);
return NULL;
}
char* result = (char*)malloc(17);
if( !result ) {
return NULL;
}
size_t alloc_size = 17;
size_t length = 0;
result[0] = '\0';
bool done = false;
while(!done) {
c = fgetc(jpp->f);
if( c == EOF ) {
return NULL;
}
char ch;
if( c == '"' ) {
done = true;
break;
} else if( c == '\\' ) {
printf( "TODO: handle string escape sequences\n" );
exit(1);
} else {
ch = (char)c;
}
if( length + 1 >= alloc_size ) {
result = realloc( result, alloc_size + 16 );
alloc_size += 16;
}
result[length] = ch;
result[length+1] = '\0';
length += 1;
}
finish_value_read( jpp, true );
return result;
}
char* json_pull_parser_read_object_key ( struct json_pull_parser* jpp )
{
if( jpp->curr_state == ps_object_expect_comma_then_key ) {
eat_whitespace(jpp->f);
int i = fgetc(jpp->f);
if( i != ',' ) {
ungetc( i, jpp->f );
return NULL;
}
} else if( jpp->curr_state != ps_object_expect_key ) {
return NULL;
}
char* str = json_pull_parser_raw_read_string( jpp );
if( !str ) {
return NULL;
}
eat_whitespace(jpp->f);
int i = fgetc( jpp->f );
if( i != ':' ) {
free(str);
return NULL;
}
jpp->curr_state = ps_object_expect_value;
return str;
}
char* json_pull_parser_read_string( struct json_pull_parser* jpp )
{
if( !json_pull_parser_handle_array_comma( jpp ) ) {
return false;
}
return json_pull_parser_raw_read_string(jpp);
}
enum number_type {
nt_no_result = 0,
nt_integer = 1,
nt_float = 2,
};
int json_pull_parser_read_number( struct json_pull_parser* jpp, int* i, float* f )
{
eat_whitespace(jpp->f);
char buffer[50];
char* pos = &buffer[0];
bool must_be_float = false;
int c = fgetc(jpp->f);
if( c == '-' ) {
*pos = '-';
pos += 1;
c = fgetc(jpp->f);
}
if( c == EOF ) { return nt_no_result; }
if( c == '0' ) {
*pos = c;
pos += 1;
} else if( c >= '1' && c <= '9' ) {
*pos = c;
pos += 1;
for(;;) {
c = fgetc(jpp->f);
if( c == EOF ) { return nt_no_result; }
if( c >= '0' && c <= '9' ) {
*pos = c;
pos += 1;
} else {
break;
}
}
} else {
ungetc(c,jpp->f);
return false;
}
if( c == '.' ) {
// fractional part
for(;;) {
c = fgetc(jpp->f);
if( c == '0' ) {
} else if( c >= '1' && c <= '9' ) {
must_be_float = true;
} else {
break;
}
*pos = c;
++pos;
}
}
if( c == 'e' || c == 'E' ) {
bool negative_exponent = false;
// exponent part
c = fgetc( jpp->f );
if( c == '-' ) {
negative_exponent = true;
c = fgetc(jpp->f);
} else if( c == '+' ) {
c = fgetc(jpp->f);
}
for(;;) {
if( c >= '1' && c <= '9' ) {
if( negative_exponent ) {
must_be_float = true;
}
*pos = c;
pos += 1;
c = fgetc(jpp->f);
} else {
break;
}
}
}
ungetc( c, jpp->f );
int res = nt_no_result;
*pos = '\0';
if( pos == &buffer[0] ) {
return nt_no_result;
}
if( f ) {
char* rem = NULL;
*f = strtof( buffer, &rem );
if( rem != pos ) {
return nt_no_result;
}
if( i && !must_be_float ) {
*i = *f;
res = nt_integer;
goto finish;
}
res = nt_float;
goto finish;
} else if( must_be_float ) {
return nt_no_result;
}
if( i ) {
char* rem = NULL;
*i = strtol( buffer, &rem, 10 );
if( rem != pos ) {
return nt_no_result;
}
res = nt_integer;
goto finish;
}
return nt_no_result;
finish:
return finish_value_read( jpp, res );
}
bool json_pull_parser_read_int( struct json_pull_parser* jpp, int* i )
{
return json_pull_parser_read_number(jpp,i,NULL) == nt_integer;
}
bool json_pull_parser_read_float( struct json_pull_parser* jpp, float* f )
{
return json_pull_parser_read_number(jpp,NULL,f) == nt_float;
}
bool json_pull_parser_read_null( struct json_pull_parser* jpp )
{
return false;
}
bool json_pull_parser_read_value( struct json_pull_parser* jpp )
{
if( json_pull_parser_read_null(jpp) ) {
return true;
}
if( !json_pull_parser_handle_array_comma( jpp ) ) {
return false;
}
int i;
float f;
if( json_pull_parser_read_number(jpp,&i,&f) ) {
return true;
}
char* s;
if( s = json_pull_parser_read_string(jpp) ) {
free(s);
return true;
}
if( json_pull_parser_begin_object(jpp,&i) ) {
while( s = json_pull_parser_read_object_key(jpp) ) {
free(s);
if( !json_pull_parser_read_value(jpp) ) {
return false;
}
}
return json_pull_parser_end_object(jpp,&i);
}
if( json_pull_parser_begin_array(jpp,&i) ) {
for(;;) {
if( json_pull_parser_end_array(jpp,&i) ) {
return true;
}
if( !json_pull_parser_read_value(jpp) ) {
return false;
}
}
return true;
}
return false;
}
void json_pull_parser_debug_dump( struct json_pull_parser* jpp )
{
printf( "state = %d\n", jpp->curr_state );
FILE* f = jpp->f;
for(;;) {
int c = fgetc(f);
if( c == EOF ) {
return;
}
printf( "%c", (char)c );
}
}

@ -1,26 +0,0 @@
#pragma once
#include <stdbool.h>
#include <stdio.h>
struct json_pull_parser;
struct json_pull_parser* json_pull_parser_new( FILE* f );
void json_pull_parser_release ( struct json_pull_parser* jpp );
bool json_pull_parser_begin_object ( struct json_pull_parser* jpp, int* save );
bool json_pull_parser_end_object ( struct json_pull_parser* jpp, int* save );
bool json_pull_parser_begin_array ( struct json_pull_parser* jpp, int* save );
bool json_pull_parser_end_array ( struct json_pull_parser* jpp, int* save );
char* json_pull_parser_read_object_key ( struct json_pull_parser* jpp );
char* json_pull_parser_read_string ( struct json_pull_parser* jpp );
bool json_pull_parser_read_int ( struct json_pull_parser* jpp, int* i );
bool json_pull_parser_read_float ( struct json_pull_parser* jpp, float* i );
bool json_pull_parser_read_null ( struct json_pull_parser* jpp );
bool json_pull_parser_read_value ( struct json_pull_parser* jpp );
void json_pull_parser_debug_dump ( struct json_pull_parser* jpp );

@ -1,4 +1,4 @@
#include "json.h"
#include "json/json.h"
#include "vector.h"
#include "json_vector.h"

Loading…
Cancel
Save