Store CPU list in a metadata.json file
This allows early access to the CPU list in order to emit the PRV header before consuming events from the streams.
This commit is contained in:
parent
763bcf7c33
commit
60862db890
10
Makefile
10
Makefile
@ -17,16 +17,16 @@ all: $(BIN)
|
||||
libovni.a: ovni.o
|
||||
ar -crs $@ $^
|
||||
|
||||
dump: ovni.o dump.o
|
||||
dump: ovni.o dump.o parson.o
|
||||
|
||||
test_speed: test_speed.c ovni.o
|
||||
test_speed: test_speed.c ovni.o parson.o
|
||||
|
||||
emu: emu.o emu_ovni.o emu_nosv.o ovni.o prv.o
|
||||
emu: emu.o emu_ovni.o emu_nosv.o ovni.o prv.o parson.o
|
||||
|
||||
libovni.so: ovni.o
|
||||
libovni.so: ovni.o parson.o
|
||||
$(LINK.c) -shared $^ -o $@
|
||||
|
||||
ovni2prv: ovni2prv.c ovni.o
|
||||
ovni2prv: ovni2prv.c ovni.o parson.o
|
||||
|
||||
ovnisync: ovnisync.c
|
||||
mpicc -lm $^ -o $@
|
||||
|
120
emu.c
120
emu.c
@ -190,6 +190,7 @@ emulate(struct ovni_emu *emu)
|
||||
ovni_load_next_event(stream);
|
||||
}
|
||||
|
||||
|
||||
emu->lastclock = 0;
|
||||
|
||||
/* Then process all events */
|
||||
@ -237,6 +238,112 @@ emu_get_thread(struct ovni_emu *emu, int tid)
|
||||
return thread;
|
||||
}
|
||||
|
||||
static void
|
||||
add_new_cpu(struct ovni_emu *emu, struct ovni_loom *loom, int i, int phyid)
|
||||
{
|
||||
/* The logical id must match our index */
|
||||
assert(i == loom->ncpus);
|
||||
|
||||
assert(loom->cpu[i].state == CPU_ST_UNKNOWN);
|
||||
|
||||
loom->cpu[loom->ncpus].state = CPU_ST_READY;
|
||||
loom->cpu[loom->ncpus].i = i;
|
||||
loom->cpu[loom->ncpus].phyid = phyid;
|
||||
loom->cpu[loom->ncpus].gindex = emu->total_cpus++;
|
||||
|
||||
dbg("new cpu %d at phyid=%d\n", i, phyid);
|
||||
|
||||
loom->ncpus++;
|
||||
}
|
||||
|
||||
void
|
||||
proc_load_cpus(struct ovni_emu *emu, struct ovni_loom *loom, struct ovni_eproc *proc)
|
||||
{
|
||||
JSON_Array *cpuarray;
|
||||
JSON_Object *cpu;
|
||||
JSON_Object *meta;
|
||||
int i, index, phyid;
|
||||
|
||||
meta = json_value_get_object(proc->meta);
|
||||
|
||||
assert(meta);
|
||||
|
||||
cpuarray = json_object_get_array(meta, "cpus");
|
||||
|
||||
/* This process doesn't have the cpu list */
|
||||
if(cpuarray == NULL)
|
||||
return;
|
||||
|
||||
assert(loom->ncpus == 0);
|
||||
|
||||
for(i = 0; i < json_array_get_count(cpuarray); i++)
|
||||
{
|
||||
cpu = json_array_get_object(cpuarray, i);
|
||||
|
||||
index = (int) json_object_get_number(cpu, "index");
|
||||
phyid = (int) json_object_get_number(cpu, "phyid");
|
||||
|
||||
add_new_cpu(emu, loom, index, phyid);
|
||||
}
|
||||
}
|
||||
|
||||
/* Obtain CPUs in the metadata files and other data */
|
||||
static int
|
||||
load_metadata(struct ovni_emu *emu)
|
||||
{
|
||||
int i, j, k, s;
|
||||
struct ovni_loom *loom;
|
||||
struct ovni_eproc *proc;
|
||||
struct ovni_ethread *thread;
|
||||
struct ovni_stream *stream;
|
||||
struct ovni_trace *trace;
|
||||
|
||||
trace = &emu->trace;
|
||||
|
||||
for(i=0; i<trace->nlooms; i++)
|
||||
{
|
||||
loom = &trace->loom[i];
|
||||
for(j=0; j<loom->nprocs; j++)
|
||||
{
|
||||
proc = &loom->proc[j];
|
||||
|
||||
proc_load_cpus(emu, loom, proc);
|
||||
}
|
||||
|
||||
/* One of the process must have the list of CPUs */
|
||||
/* FIXME: The CPU list should be at the loom dir */
|
||||
assert(loom->ncpus > 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
destroy_metadata(struct ovni_emu *emu)
|
||||
{
|
||||
int i, j, k, s;
|
||||
struct ovni_loom *loom;
|
||||
struct ovni_eproc *proc;
|
||||
struct ovni_ethread *thread;
|
||||
struct ovni_stream *stream;
|
||||
struct ovni_trace *trace;
|
||||
|
||||
trace = &emu->trace;
|
||||
|
||||
for(i=0; i<trace->nlooms; i++)
|
||||
{
|
||||
loom = &trace->loom[i];
|
||||
for(j=0; j<loom->nprocs; j++)
|
||||
{
|
||||
proc = &loom->proc[j];
|
||||
|
||||
assert(proc->meta);
|
||||
json_value_free(proc->meta);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
@ -256,16 +363,23 @@ main(int argc, char *argv[])
|
||||
memset(&emu, 0, sizeof(emu));
|
||||
|
||||
if(ovni_load_trace(&emu.trace, tracedir))
|
||||
return 1;
|
||||
abort();
|
||||
|
||||
if(ovni_load_streams(&emu.trace))
|
||||
return 1;
|
||||
abort();
|
||||
|
||||
printf("#Paraver (19/01/38 at 03:14):00000000000000000000_ns:0:1:1(%d:1)\n", 10);
|
||||
if(load_metadata(&emu) != 0)
|
||||
abort();
|
||||
|
||||
|
||||
printf("#Paraver (19/01/38 at 03:14):00000000000000000000_ns:0:1:1(%d:1)\n", emu.total_cpus);
|
||||
|
||||
emulate(&emu);
|
||||
|
||||
destroy_metadata(&emu);
|
||||
|
||||
ovni_free_streams(&emu.trace);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
5
emu.h
5
emu.h
@ -3,6 +3,7 @@
|
||||
|
||||
#include "ovni.h"
|
||||
#include "uthash.h"
|
||||
#include "parson.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/* Debug macros */
|
||||
@ -91,6 +92,8 @@ struct ovni_eproc {
|
||||
size_t nthreads;
|
||||
struct ovni_ethread thread[OVNI_MAX_THR];
|
||||
|
||||
JSON_Value *meta;
|
||||
|
||||
/* ------ Subsystem specific data --------*/
|
||||
/* TODO: Use dynamic allocation */
|
||||
|
||||
@ -189,7 +192,7 @@ struct ovni_emu {
|
||||
/* Total counters */
|
||||
int total_thread;
|
||||
int total_proc;
|
||||
int total_cpu;
|
||||
int total_cpus;
|
||||
};
|
||||
|
||||
/* Emulator function declaration */
|
||||
|
70
emu_ovni.c
70
emu_ovni.c
@ -243,74 +243,6 @@ ev_affinity(struct ovni_emu *emu)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ev_cpu_count(struct ovni_emu *emu)
|
||||
{
|
||||
int i, max_ncpus, max_phyid;
|
||||
struct ovni_loom *loom;
|
||||
|
||||
loom = emu->cur_loom;
|
||||
max_ncpus = emu->cur_ev->payload.i32[0];
|
||||
max_phyid = emu->cur_ev->payload.i32[1];
|
||||
|
||||
assert(max_ncpus < OVNI_MAX_CPU);
|
||||
assert(max_phyid < OVNI_MAX_CPU);
|
||||
|
||||
for(i=0; i<OVNI_MAX_CPU; i++)
|
||||
{
|
||||
loom->cpu[i].state = CPU_ST_UNKNOWN;
|
||||
loom->cpu[i].i = -1;
|
||||
loom->cpu[i].phyid = -1;
|
||||
loom->cpu[i].gindex = -1;
|
||||
}
|
||||
|
||||
loom->ncpus = 0;
|
||||
loom->max_ncpus = max_ncpus;
|
||||
loom->max_phyid = max_phyid;
|
||||
}
|
||||
|
||||
static void
|
||||
ev_cpu_id(struct ovni_emu *emu)
|
||||
{
|
||||
int i, phyid;
|
||||
struct ovni_loom *loom;
|
||||
|
||||
loom = emu->cur_loom;
|
||||
i = emu->cur_ev->payload.i32[0];
|
||||
phyid = emu->cur_ev->payload.i32[1];
|
||||
|
||||
/* The logical id must match our index */
|
||||
assert(i == loom->ncpus);
|
||||
|
||||
assert(0 <= phyid && phyid <= loom->max_phyid);
|
||||
|
||||
assert(loom->cpu[i].state == CPU_ST_UNKNOWN);
|
||||
|
||||
loom->cpu[loom->ncpus].state = CPU_ST_READY;
|
||||
loom->cpu[loom->ncpus].i = i;
|
||||
loom->cpu[loom->ncpus].phyid = phyid;
|
||||
loom->cpu[loom->ncpus].gindex = emu->total_cpu++;
|
||||
|
||||
dbg("new cpu %d at phyid=%d\n", i, phyid);
|
||||
|
||||
loom->ncpus++;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ev_cpu(struct ovni_emu *emu)
|
||||
{
|
||||
switch(emu->cur_ev->header.value)
|
||||
{
|
||||
case 'n': ev_cpu_count(emu); break;
|
||||
case 'i': ev_cpu_id(emu); break;
|
||||
default:
|
||||
dbg("unknown cpu event value %c\n",
|
||||
emu->cur_ev->header.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
hook_pre_ovni(struct ovni_emu *emu)
|
||||
{
|
||||
@ -320,7 +252,6 @@ hook_pre_ovni(struct ovni_emu *emu)
|
||||
{
|
||||
case 'H': ev_thread(emu); break;
|
||||
case 'A': ev_affinity(emu); break;
|
||||
case 'C': ev_cpu(emu); break;
|
||||
case 'B': dbg("burst %c\n", emu->cur_ev->header.value); break;
|
||||
default:
|
||||
dbg("unknown ovni event class %c\n",
|
||||
@ -410,7 +341,6 @@ hook_emit_ovni(struct ovni_emu *emu)
|
||||
emit_thread_state(emu);
|
||||
/* falltrough */
|
||||
case 'A':
|
||||
case 'C':
|
||||
emit_thread_count(emu);
|
||||
//emit_current_pid(emu);
|
||||
break;
|
||||
|
130
ovni.c
130
ovni.c
@ -19,6 +19,7 @@
|
||||
|
||||
#include "ovni.h"
|
||||
#include "ovni_trace.h"
|
||||
#include "parson.h"
|
||||
|
||||
#define ENABLE_DEBUG
|
||||
|
||||
@ -93,8 +94,113 @@ create_trace_stream()
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
proc_metadata_init(struct ovni_rproc *proc)
|
||||
{
|
||||
JSON_Value *meta;
|
||||
|
||||
proc->meta = json_value_init_object();
|
||||
|
||||
if(proc->meta == NULL)
|
||||
{
|
||||
err("failed to create json object\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
proc_metadata_store(struct ovni_rproc *proc)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
snprintf(path, PATH_MAX, "%s/metadata.json", proc->dir);
|
||||
|
||||
assert(proc->meta != NULL);
|
||||
|
||||
puts(json_serialize_to_string_pretty(proc->meta));
|
||||
|
||||
if(json_serialize_to_file_pretty(proc->meta, path) != JSONSuccess)
|
||||
{
|
||||
err("failed to write proc metadata\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ovni_add_cpu(int index, int phyid)
|
||||
{
|
||||
JSON_Array *cpuarray;
|
||||
JSON_Object *cpu;
|
||||
JSON_Object *meta;
|
||||
JSON_Value *valcpu, *valcpuarray;
|
||||
int append = 0;
|
||||
|
||||
assert(rproc.ready == 1);
|
||||
assert(rproc.meta != NULL);
|
||||
|
||||
meta = json_value_get_object(rproc.meta);
|
||||
|
||||
assert(meta);
|
||||
|
||||
/* Find the CPU array and create it if needed */
|
||||
cpuarray = json_object_dotget_array(meta, "cpus");
|
||||
|
||||
if(cpuarray == NULL)
|
||||
{
|
||||
valcpuarray = json_value_init_array();
|
||||
assert(valcpuarray);
|
||||
|
||||
cpuarray = json_array(valcpuarray);
|
||||
assert(cpuarray);
|
||||
append = 1;
|
||||
}
|
||||
|
||||
valcpuarray = json_array_get_wrapping_value(cpuarray);
|
||||
assert(valcpuarray);
|
||||
|
||||
valcpu = json_value_init_object();
|
||||
assert(valcpu);
|
||||
|
||||
cpu = json_object(valcpu);
|
||||
assert(cpu);
|
||||
|
||||
if(json_object_set_number(cpu, "index", index) != 0)
|
||||
abort();
|
||||
|
||||
if(json_object_set_number(cpu, "phyid", phyid) != 0)
|
||||
abort();
|
||||
|
||||
if(json_array_append_value(cpuarray, valcpu) != 0)
|
||||
abort();
|
||||
|
||||
if(append && json_object_set_value(meta, "cpus", valcpuarray) != 0)
|
||||
abort();
|
||||
|
||||
//puts(json_serialize_to_string_pretty(rproc.meta));
|
||||
}
|
||||
|
||||
static void
|
||||
proc_set_app(int appid)
|
||||
{
|
||||
JSON_Object *meta;
|
||||
|
||||
assert(rproc.ready == 1);
|
||||
assert(rproc.meta != NULL);
|
||||
|
||||
meta = json_value_get_object(rproc.meta);
|
||||
|
||||
assert(meta);
|
||||
|
||||
if(json_object_set_number(meta, "app_id", appid) != 0)
|
||||
abort();
|
||||
}
|
||||
|
||||
int
|
||||
ovni_proc_init(char *loom, int proc)
|
||||
ovni_proc_init(int app, char *loom, int proc)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -105,6 +211,7 @@ ovni_proc_init(char *loom, int proc)
|
||||
/* FIXME: strcpy is insecure */
|
||||
strcpy(rproc.loom, loom);
|
||||
rproc.proc = proc;
|
||||
rproc.app = app;
|
||||
|
||||
/* By default we use the monotonic clock */
|
||||
rproc.clockid = CLOCK_MONOTONIC;
|
||||
@ -112,8 +219,22 @@ ovni_proc_init(char *loom, int proc)
|
||||
if(create_trace_dirs(OVNI_TRACEDIR, loom, proc))
|
||||
abort();
|
||||
|
||||
if(proc_metadata_init(&rproc) != 0)
|
||||
abort();
|
||||
|
||||
rproc.ready = 1;
|
||||
|
||||
proc_set_app(app);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ovni_proc_fini()
|
||||
{
|
||||
if(proc_metadata_store(&rproc) != 0)
|
||||
abort();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -511,6 +632,11 @@ load_proc(struct ovni_eproc *proc, int index, int pid, char *procdir)
|
||||
proc->index = index;
|
||||
proc->gindex = total_procs++;
|
||||
|
||||
sprintf(path, "%s/%s", procdir, "metadata.json");
|
||||
proc->meta = json_parse_file_with_comments(path);
|
||||
|
||||
assert(proc->meta);
|
||||
|
||||
if((dir = opendir(procdir)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "opendir %s failed: %s\n",
|
||||
@ -545,6 +671,8 @@ load_proc(struct ovni_eproc *proc, int index, int pid, char *procdir)
|
||||
|
||||
closedir(dir);
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
11
ovni.h
11
ovni.h
@ -8,6 +8,8 @@
|
||||
#include <linux/limits.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "parson.h"
|
||||
|
||||
#define OVNI_MAX_CPU 256
|
||||
#define OVNI_MAX_PROC 32
|
||||
#define OVNI_MAX_THR 32
|
||||
@ -93,6 +95,7 @@ struct ovni_rproc {
|
||||
/* Path of the process tracedir */
|
||||
char dir[PATH_MAX];
|
||||
|
||||
int app;
|
||||
int proc;
|
||||
char loom[HOST_NAME_MAX];
|
||||
int ncpus;
|
||||
@ -100,9 +103,13 @@ struct ovni_rproc {
|
||||
char procdir[PATH_MAX];
|
||||
|
||||
int ready;
|
||||
|
||||
JSON_Value *meta;
|
||||
};
|
||||
|
||||
int ovni_proc_init(char *loom, int proc);
|
||||
int ovni_proc_init(int app, char *loom, int proc);
|
||||
|
||||
int ovni_proc_fini();
|
||||
|
||||
int ovni_thread_init(pid_t tid);
|
||||
|
||||
@ -120,6 +127,8 @@ int ovni_ev_size(struct ovni_ev *ev);
|
||||
|
||||
int ovni_payload_size(struct ovni_ev *ev);
|
||||
|
||||
void ovni_add_cpu(int index, int phyid);
|
||||
|
||||
/* Set the current clock in the event and queue it */
|
||||
void ovni_ev(struct ovni_ev *ev);
|
||||
void ovni_ev_jumbo(struct ovni_ev *ev, uint8_t *buf, uint32_t bufsize);
|
||||
|
250
parson.h
Normal file
250
parson.h
Normal file
@ -0,0 +1,250 @@
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
|
||||
Parson 1.1.3 ( http://kgabis.github.com/parson/ )
|
||||
Copyright (c) 2012 - 2021 Krzysztof Gabis
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef parson_parson_h
|
||||
#define parson_parson_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stddef.h> /* size_t */
|
||||
|
||||
/* Types and enums */
|
||||
typedef struct json_object_t JSON_Object;
|
||||
typedef struct json_array_t JSON_Array;
|
||||
typedef struct json_value_t JSON_Value;
|
||||
|
||||
enum json_value_type {
|
||||
JSONError = -1,
|
||||
JSONNull = 1,
|
||||
JSONString = 2,
|
||||
JSONNumber = 3,
|
||||
JSONObject = 4,
|
||||
JSONArray = 5,
|
||||
JSONBoolean = 6
|
||||
};
|
||||
typedef int JSON_Value_Type;
|
||||
|
||||
enum json_result_t {
|
||||
JSONSuccess = 0,
|
||||
JSONFailure = -1
|
||||
};
|
||||
typedef int JSON_Status;
|
||||
|
||||
typedef void * (*JSON_Malloc_Function)(size_t);
|
||||
typedef void (*JSON_Free_Function)(void *);
|
||||
|
||||
/* Call only once, before calling any other function from parson API. If not called, malloc and free
|
||||
from stdlib will be used for all allocations */
|
||||
void json_set_allocation_functions(JSON_Malloc_Function malloc_fun, JSON_Free_Function free_fun);
|
||||
|
||||
/* Sets if slashes should be escaped or not when serializing JSON. By default slashes are escaped.
|
||||
This function sets a global setting and is not thread safe. */
|
||||
void json_set_escape_slashes(int escape_slashes);
|
||||
|
||||
/* Parses first JSON value in a file, returns NULL in case of error */
|
||||
JSON_Value * json_parse_file(const char *filename);
|
||||
|
||||
/* Parses first JSON value in a file and ignores comments (/ * * / and //),
|
||||
returns NULL in case of error */
|
||||
JSON_Value * json_parse_file_with_comments(const char *filename);
|
||||
|
||||
/* Parses first JSON value in a string, returns NULL in case of error */
|
||||
JSON_Value * json_parse_string(const char *string);
|
||||
|
||||
/* Parses first JSON value in a string and ignores comments (/ * * / and //),
|
||||
returns NULL in case of error */
|
||||
JSON_Value * json_parse_string_with_comments(const char *string);
|
||||
|
||||
/* Serialization */
|
||||
size_t json_serialization_size(const JSON_Value *value); /* returns 0 on fail */
|
||||
JSON_Status json_serialize_to_buffer(const JSON_Value *value, char *buf, size_t buf_size_in_bytes);
|
||||
JSON_Status json_serialize_to_file(const JSON_Value *value, const char *filename);
|
||||
char * json_serialize_to_string(const JSON_Value *value);
|
||||
|
||||
/* Pretty serialization */
|
||||
size_t json_serialization_size_pretty(const JSON_Value *value); /* returns 0 on fail */
|
||||
JSON_Status json_serialize_to_buffer_pretty(const JSON_Value *value, char *buf, size_t buf_size_in_bytes);
|
||||
JSON_Status json_serialize_to_file_pretty(const JSON_Value *value, const char *filename);
|
||||
char * json_serialize_to_string_pretty(const JSON_Value *value);
|
||||
|
||||
void json_free_serialized_string(char *string); /* frees string from json_serialize_to_string and json_serialize_to_string_pretty */
|
||||
|
||||
/* Comparing */
|
||||
int json_value_equals(const JSON_Value *a, const JSON_Value *b);
|
||||
|
||||
/* Validation
|
||||
This is *NOT* JSON Schema. It validates json by checking if object have identically
|
||||
named fields with matching types.
|
||||
For example schema {"name":"", "age":0} will validate
|
||||
{"name":"Joe", "age":25} and {"name":"Joe", "age":25, "gender":"m"},
|
||||
but not {"name":"Joe"} or {"name":"Joe", "age":"Cucumber"}.
|
||||
In case of arrays, only first value in schema is checked against all values in tested array.
|
||||
Empty objects ({}) validate all objects, empty arrays ([]) validate all arrays,
|
||||
null validates values of every type.
|
||||
*/
|
||||
JSON_Status json_validate(const JSON_Value *schema, const JSON_Value *value);
|
||||
|
||||
/*
|
||||
* JSON Object
|
||||
*/
|
||||
JSON_Value * json_object_get_value (const JSON_Object *object, const char *name);
|
||||
const char * json_object_get_string (const JSON_Object *object, const char *name);
|
||||
size_t json_object_get_string_len(const JSON_Object *object, const char *name); /* doesn't account for last null character */
|
||||
JSON_Object * json_object_get_object (const JSON_Object *object, const char *name);
|
||||
JSON_Array * json_object_get_array (const JSON_Object *object, const char *name);
|
||||
double json_object_get_number (const JSON_Object *object, const char *name); /* returns 0 on fail */
|
||||
int json_object_get_boolean(const JSON_Object *object, const char *name); /* returns -1 on fail */
|
||||
|
||||
/* dotget functions enable addressing values with dot notation in nested objects,
|
||||
just like in structs or c++/java/c# objects (e.g. objectA.objectB.value).
|
||||
Because valid names in JSON can contain dots, some values may be inaccessible
|
||||
this way. */
|
||||
JSON_Value * json_object_dotget_value (const JSON_Object *object, const char *name);
|
||||
const char * json_object_dotget_string (const JSON_Object *object, const char *name);
|
||||
size_t json_object_dotget_string_len(const JSON_Object *object, const char *name); /* doesn't account for last null character */
|
||||
JSON_Object * json_object_dotget_object (const JSON_Object *object, const char *name);
|
||||
JSON_Array * json_object_dotget_array (const JSON_Object *object, const char *name);
|
||||
double json_object_dotget_number (const JSON_Object *object, const char *name); /* returns 0 on fail */
|
||||
int json_object_dotget_boolean(const JSON_Object *object, const char *name); /* returns -1 on fail */
|
||||
|
||||
/* Functions to get available names */
|
||||
size_t json_object_get_count (const JSON_Object *object);
|
||||
const char * json_object_get_name (const JSON_Object *object, size_t index);
|
||||
JSON_Value * json_object_get_value_at(const JSON_Object *object, size_t index);
|
||||
JSON_Value * json_object_get_wrapping_value(const JSON_Object *object);
|
||||
|
||||
/* Functions to check if object has a value with a specific name. Returned value is 1 if object has
|
||||
* a value and 0 if it doesn't. dothas functions behave exactly like dotget functions. */
|
||||
int json_object_has_value (const JSON_Object *object, const char *name);
|
||||
int json_object_has_value_of_type(const JSON_Object *object, const char *name, JSON_Value_Type type);
|
||||
|
||||
int json_object_dothas_value (const JSON_Object *object, const char *name);
|
||||
int json_object_dothas_value_of_type(const JSON_Object *object, const char *name, JSON_Value_Type type);
|
||||
|
||||
/* Creates new name-value pair or frees and replaces old value with a new one.
|
||||
* json_object_set_value does not copy passed value so it shouldn't be freed afterwards. */
|
||||
JSON_Status json_object_set_value(JSON_Object *object, const char *name, JSON_Value *value);
|
||||
JSON_Status json_object_set_string(JSON_Object *object, const char *name, const char *string);
|
||||
JSON_Status json_object_set_string_with_len(JSON_Object *object, const char *name, const char *string, size_t len); /* length shouldn't include last null character */
|
||||
JSON_Status json_object_set_number(JSON_Object *object, const char *name, double number);
|
||||
JSON_Status json_object_set_boolean(JSON_Object *object, const char *name, int boolean);
|
||||
JSON_Status json_object_set_null(JSON_Object *object, const char *name);
|
||||
|
||||
/* Works like dotget functions, but creates whole hierarchy if necessary.
|
||||
* json_object_dotset_value does not copy passed value so it shouldn't be freed afterwards. */
|
||||
JSON_Status json_object_dotset_value(JSON_Object *object, const char *name, JSON_Value *value);
|
||||
JSON_Status json_object_dotset_string(JSON_Object *object, const char *name, const char *string);
|
||||
JSON_Status json_object_dotset_string_with_len(JSON_Object *object, const char *name, const char *string, size_t len); /* length shouldn't include last null character */
|
||||
JSON_Status json_object_dotset_number(JSON_Object *object, const char *name, double number);
|
||||
JSON_Status json_object_dotset_boolean(JSON_Object *object, const char *name, int boolean);
|
||||
JSON_Status json_object_dotset_null(JSON_Object *object, const char *name);
|
||||
|
||||
/* Frees and removes name-value pair */
|
||||
JSON_Status json_object_remove(JSON_Object *object, const char *name);
|
||||
|
||||
/* Works like dotget function, but removes name-value pair only on exact match. */
|
||||
JSON_Status json_object_dotremove(JSON_Object *object, const char *key);
|
||||
|
||||
/* Removes all name-value pairs in object */
|
||||
JSON_Status json_object_clear(JSON_Object *object);
|
||||
|
||||
/*
|
||||
*JSON Array
|
||||
*/
|
||||
JSON_Value * json_array_get_value (const JSON_Array *array, size_t index);
|
||||
const char * json_array_get_string (const JSON_Array *array, size_t index);
|
||||
size_t json_array_get_string_len(const JSON_Array *array, size_t index); /* doesn't account for last null character */
|
||||
JSON_Object * json_array_get_object (const JSON_Array *array, size_t index);
|
||||
JSON_Array * json_array_get_array (const JSON_Array *array, size_t index);
|
||||
double json_array_get_number (const JSON_Array *array, size_t index); /* returns 0 on fail */
|
||||
int json_array_get_boolean(const JSON_Array *array, size_t index); /* returns -1 on fail */
|
||||
size_t json_array_get_count (const JSON_Array *array);
|
||||
JSON_Value * json_array_get_wrapping_value(const JSON_Array *array);
|
||||
|
||||
/* Frees and removes value at given index, does nothing and returns JSONFailure if index doesn't exist.
|
||||
* Order of values in array may change during execution. */
|
||||
JSON_Status json_array_remove(JSON_Array *array, size_t i);
|
||||
|
||||
/* Frees and removes from array value at given index and replaces it with given one.
|
||||
* Does nothing and returns JSONFailure if index doesn't exist.
|
||||
* json_array_replace_value does not copy passed value so it shouldn't be freed afterwards. */
|
||||
JSON_Status json_array_replace_value(JSON_Array *array, size_t i, JSON_Value *value);
|
||||
JSON_Status json_array_replace_string(JSON_Array *array, size_t i, const char* string);
|
||||
JSON_Status json_array_replace_string_with_len(JSON_Array *array, size_t i, const char *string, size_t len); /* length shouldn't include last null character */
|
||||
JSON_Status json_array_replace_number(JSON_Array *array, size_t i, double number);
|
||||
JSON_Status json_array_replace_boolean(JSON_Array *array, size_t i, int boolean);
|
||||
JSON_Status json_array_replace_null(JSON_Array *array, size_t i);
|
||||
|
||||
/* Frees and removes all values from array */
|
||||
JSON_Status json_array_clear(JSON_Array *array);
|
||||
|
||||
/* Appends new value at the end of array.
|
||||
* json_array_append_value does not copy passed value so it shouldn't be freed afterwards. */
|
||||
JSON_Status json_array_append_value(JSON_Array *array, JSON_Value *value);
|
||||
JSON_Status json_array_append_string(JSON_Array *array, const char *string);
|
||||
JSON_Status json_array_append_string_with_len(JSON_Array *array, const char *string, size_t len); /* length shouldn't include last null character */
|
||||
JSON_Status json_array_append_number(JSON_Array *array, double number);
|
||||
JSON_Status json_array_append_boolean(JSON_Array *array, int boolean);
|
||||
JSON_Status json_array_append_null(JSON_Array *array);
|
||||
|
||||
/*
|
||||
*JSON Value
|
||||
*/
|
||||
JSON_Value * json_value_init_object (void);
|
||||
JSON_Value * json_value_init_array (void);
|
||||
JSON_Value * json_value_init_string (const char *string); /* copies passed string */
|
||||
JSON_Value * json_value_init_string_with_len(const char *string, size_t length); /* copies passed string, length shouldn't include last null character */
|
||||
JSON_Value * json_value_init_number (double number);
|
||||
JSON_Value * json_value_init_boolean(int boolean);
|
||||
JSON_Value * json_value_init_null (void);
|
||||
JSON_Value * json_value_deep_copy (const JSON_Value *value);
|
||||
void json_value_free (JSON_Value *value);
|
||||
|
||||
JSON_Value_Type json_value_get_type (const JSON_Value *value);
|
||||
JSON_Object * json_value_get_object (const JSON_Value *value);
|
||||
JSON_Array * json_value_get_array (const JSON_Value *value);
|
||||
const char * json_value_get_string (const JSON_Value *value);
|
||||
size_t json_value_get_string_len(const JSON_Value *value); /* doesn't account for last null character */
|
||||
double json_value_get_number (const JSON_Value *value);
|
||||
int json_value_get_boolean(const JSON_Value *value);
|
||||
JSON_Value * json_value_get_parent (const JSON_Value *value);
|
||||
|
||||
/* Same as above, but shorter */
|
||||
JSON_Value_Type json_type (const JSON_Value *value);
|
||||
JSON_Object * json_object (const JSON_Value *value);
|
||||
JSON_Array * json_array (const JSON_Value *value);
|
||||
const char * json_string (const JSON_Value *value);
|
||||
size_t json_string_len(const JSON_Value *value); /* doesn't account for last null character */
|
||||
double json_number (const JSON_Value *value);
|
||||
int json_boolean(const JSON_Value *value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -13,7 +13,7 @@ int main()
|
||||
struct ovni_ev ev = {0};
|
||||
int i;
|
||||
|
||||
ovni_proc_init(0, 0);
|
||||
ovni_proc_init(0, "test", 0);
|
||||
ovni_thread_init(1);
|
||||
|
||||
ovni_ev_set_mcv(&ev, "OB.");
|
||||
|
Loading…
Reference in New Issue
Block a user