JSMN API issues

I am struggling to understand how the jsmn library works. Here is my current code and what it produces. My problem is only based on 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 need to return the jsmn marker, but I'm not really sure how to create it using just the first or last name. Here is some sample code that uses this feature.

    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 him to just produce

Prof. <firstName> <lastName>
Classes: ...

      

fmt is a string of characters 's' and 'd' that describes whether the rest of the arguments are object keys or array indices. For example, derefBy (marker, "sds", key1, sub1, key2) will first dereference the marker with the key, then index sub1 and finally key2

+3


source to share





All Articles