我正在努力弄清楚 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