3

jsmn ライブラリがどのように機能するかを理解するのに苦労しています。これが私の現在のコードとそれが生成するものです。私の問題は derefBy 関数のみに基づいています

#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");
  }
}

jsmn マーカーを返さなければならないことはわかっていますが、名前または姓だけでそれを作成する方法がよくわかりません。この関数を使用したコード例を次に示します。

    char * firstName = tokenText(derefBy(faculty,"ds",i,"firstName"));
    char * lastName = tokenText(derefBy(faculty,"ds",i,"lastName"));
    fprintf(stdout,"Prof. %s %s \n",firstName,lastName);

私の混乱は結果に基づいています。私が得るのは完全にランダムなようです

Faculty Schedules
0
string firstName
0
string lastName
Prof. (null) (null)
0
string classes
Segmentation fault (core dumped)

または、何も変更せずにこれを取得します

Faculty Schedules
0
string firstName
Segmentation fault (core dumped)

単純に生成したい

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

fmt は 's' および 'd' 文字の文字列で、残りの引数がオブジェクト キーまたは配列インデックスのどちらであるかを示します。たとえば、derefBy(marker,"sds",key1, sub1, key2) は、最初に key1 によってマーカーを逆参照し、次に sub1 をインデックス付けし、最後に key2 をインデックス付けします。

4

0 に答える 0