I'm struggling to figure out how the jsmn library works. Here is my current code and what it produces. My problem is based only in the derefBy function
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "jsmnutil.h"
char * jsmnTypes[] = {"undefined","object","array","string","primitive"};
const jsmnmarker_t jsmnErrorMarker = {NULL,-1};
jsmnmarker_t
makeMarker(jsmndata_t * data) {
jsmnmarker_t marker;
marker.data = data;
marker.index = 0;
return marker;
}
int
areEqualMarkers(jsmnmarker_t marker1, jsmnmarker_t marker2) {
return marker1.data == marker2.data && marker1.index == marker2.index;
}
int
isErrorMarker(jsmnmarker_t marker) {
return areEqualMarkers(marker,jsmnErrorMarker);
}
jsmnmarker_t
objectDeref(jsmnmarker_t marker, char * key) {
if (marker.index == -1) return marker;
int childCnt = TOKEN_SIZE(marker);
jsmnmarker_t child = marker;
child.index++;
while (childCnt > 0) {
if (TOKEN_PARENT(child) == marker.index) {
if (strncmp(TOKEN_ADDR(child),key,TOKEN_LENGTH(child)) == 0) {
child.index++;
return child;
}
childCnt--;
}
child.index++;
}
return jsmnErrorMarker;
}
jsmnmarker_t
arrayDeref(jsmnmarker_t marker, int index) {
if (marker.index == -1) return marker;
int childCnt = TOKEN_SIZE(marker);
if (index >= childCnt) return jsmnErrorMarker;
jsmnmarker_t child = marker;
child.index++;
while (1) {
if (TOKEN_PARENT(child) == marker.index) {
if (index == 0) {
return child;
}
index--;
}
child.index++;
}
return jsmnErrorMarker;
}
jsmnmarker_t
derefBy(jsmnmarker_t marker, char * fmt, ...) {
va_list ap;
char * s;
int d;
jsmnmarker_t holder = marker;
va_start(ap,fmt);
while (*fmt) {
switch(*fmt++) {
case 's':
s = va_arg(ap,char *);
printf("string %s\n",s);
break;
case 'd':
d = va_arg(ap,int);
printf("%d\n",d);
break;
}
}
va_end(ap);
}
jsmnmarker_t
nextKeyForObject(jsmnmarker_t objMarker, jsmnmarker_t keyMarker) {
}
jsmnmarker_t
valueForKey(jsmnmarker_t keyMarker) {
keyMarker.index++;
return keyMarker;
}
char * *
keysForObject(jsmnmarker_t marker) {
if (marker.index == -1) return NULL;
if (TOKEN_TYPE(marker) != JSMN_OBJECT) return NULL;
int childSize = TOKEN_SIZE(marker);
char * * keys = malloc((childSize + 1) * sizeof(char *));
jsmnmarker_t child = marker;
child.index++;
int cnt = 0;
while (cnt < childSize) {
if (TOKEN_PARENT(child) == marker.index) {
keys[cnt] = tokenText(child);
cnt++;
}
child.index++;
}
keys[cnt] = NULL;
return keys;
}
char *
tokenText(jsmnmarker_t marker) {
if (marker.index < 0) return NULL;
return strndup(TOKEN_ADDR(marker),TOKEN_LENGTH(marker));
}
void
printToken(FILE * fh, jsmnmarker_t marker) {
if (marker.index >= 0 ) {
fprintf(fh,"%.*s",TOKEN_LENGTH(marker),TOKEN_ADDR(marker));
}
else {
fprintf(fh,"unresolved reference");
}
}
void
dprintToken(int fd, jsmnmarker_t marker) {
if (marker.index >= 0 ) {
dprintf(fd,"%.*s",TOKEN_LENGTH(marker),TOKEN_ADDR(marker));
}
else {
dprintf(fd,"unresolved reference");
}
}
I know I have to return a jsmn marker, but I'm not quite sure how to create it with just the first or last name. Here is an example code that uses this function.
char * firstName = tokenText(derefBy(faculty,"ds",i,"firstName"));
char * lastName = tokenText(derefBy(faculty,"ds",i,"lastName"));
fprintf(stdout,"Prof. %s %s \n",firstName,lastName);
My confusion is based on the results. It seems completely random that I either get
Faculty Schedules
0
string firstName
0
string lastName
Prof. (null) (null)
0
string classes
Segmentation fault (core dumped)
Or I get this without changing anything
Faculty Schedules
0
string firstName
Segmentation fault (core dumped)
I want it to simply produce
Prof. <firstName> <lastName>
Classes: ...
fmt is a string of 's' and 'd' characters which describes whether the remaining arguments are object keys or array indices. For example, derefBy(marker,"sds",key1, sub1, key2) would dereference marker first by key1 then index sub1 and finally key2