Merge branch 'cktan_master'

This commit is contained in:
chinky 2020-05-10 09:27:25 +08:00
commit 4c7f351ed8
2 changed files with 1339 additions and 1348 deletions

85
toml.c
View File

@ -390,10 +390,10 @@ static int e_noimpl(context_t* ctx, const char* feature)
} }
*/ */
static int e_key_exists_error(context_t* ctx, int lineno, const char* key) static int e_key_exists_error(context_t* ctx, int lineno)
{ {
snprintf(ctx->errbuf, ctx->errbufsz, snprintf(ctx->errbuf, ctx->errbufsz,
"line %d: key %s exists", lineno, key); "line %d: key exists", lineno);
longjmp(ctx->jmp, 1); longjmp(ctx->jmp, 1);
return -1; return -1;
} }
@ -691,7 +691,7 @@ static toml_keyval_t* create_keyval_in_table(context_t* ctx, toml_table_t* tab,
toml_keyval_t* dest = 0; toml_keyval_t* dest = 0;
if (key_kind(tab, newkey)) { if (key_kind(tab, newkey)) {
xfree(newkey); xfree(newkey);
e_key_exists_error(ctx, keytok.lineno, newkey); e_key_exists_error(ctx, keytok.lineno);
return 0; /* not reached */ return 0; /* not reached */
} }
@ -738,7 +738,7 @@ static toml_table_t* create_keytable_in_table(context_t* ctx, toml_table_t* tab,
dest->implicit = 0; dest->implicit = 0;
return dest; return dest;
} }
e_key_exists_error(ctx, keytok.lineno, newkey); e_key_exists_error(ctx, keytok.lineno);
return 0; /* not reached */ return 0; /* not reached */
} }
@ -780,7 +780,7 @@ static toml_array_t* create_keyarray_in_table(context_t* ctx,
/* if key exists: error out */ /* if key exists: error out */
if (key_kind(tab, newkey)) { if (key_kind(tab, newkey)) {
xfree(newkey); /* don't need this anymore */ xfree(newkey); /* don't need this anymore */
e_key_exists_error(ctx, keytok.lineno, newkey); e_key_exists_error(ctx, keytok.lineno);
return 0; /* not reached */ return 0; /* not reached */
} }
@ -850,7 +850,15 @@ static toml_table_t* create_table_in_array(context_t* ctx,
} }
#define SKIP_NEWLINES(ctx, isdotspecial) while (ctx->tok.tok == NEWLINE) next_token(ctx, isdotspecial) static void skip_newlines(context_t* ctx, int isdotspecial)
{
while (ctx->tok.tok == NEWLINE) {
next_token(ctx, isdotspecial);
if (ctx->tok.eof) break;
}
}
#define EAT_TOKEN(ctx, typ, isdotspecial) \ #define EAT_TOKEN(ctx, typ, isdotspecial) \
if ((ctx)->tok.tok != typ) e_internal_error(ctx, FLINE); else next_token(ctx, isdotspecial) if ((ctx)->tok.tok != typ) e_internal_error(ctx, FLINE); else next_token(ctx, isdotspecial)
@ -923,7 +931,7 @@ static void parse_array(context_t* ctx, toml_array_t* arr)
EAT_TOKEN(ctx, LBRACKET, 0); EAT_TOKEN(ctx, LBRACKET, 0);
for (;;) { for (;;) {
SKIP_NEWLINES(ctx, 0); skip_newlines(ctx, 0);
/* until ] */ /* until ] */
if (ctx->tok.tok == RBRACKET) break; if (ctx->tok.tok == RBRACKET) break;
@ -1002,7 +1010,7 @@ static void parse_array(context_t* ctx, toml_array_t* arr)
return; /* not reached */ return; /* not reached */
} }
SKIP_NEWLINES(ctx, 0); skip_newlines(ctx, 0);
/* on comma, continue to scan for next element */ /* on comma, continue to scan for next element */
if (ctx->tok.tok == COMMA) { if (ctx->tok.tok == COMMA) {
@ -1013,7 +1021,7 @@ static void parse_array(context_t* ctx, toml_array_t* arr)
} }
if (ctx->tok.tok != RBRACKET) { if (ctx->tok.tok != RBRACKET) {
e_syntax_error(ctx, ctx->tok.lineno, "syntax error"); e_syntax_error(ctx, ctx->tok.lineno, "expect a right bracket");
return; /* not reached */ return; /* not reached */
} }
@ -1186,7 +1194,7 @@ static void walk_tabpath(context_t* ctx)
break; break;
case 'v': case 'v':
e_key_exists_error(ctx, ctx->tpath.tok[i].lineno, key); e_key_exists_error(ctx, ctx->tpath.tok[i].lineno);
return; /* not reached */ return; /* not reached */
default: default:
@ -2089,27 +2097,30 @@ int toml_rtod(const char* src, double* ret_)
int toml_rtos(const char* src, char** ret) int toml_rtos(const char* src, char** ret)
{ {
char dummy_errbuf[1];
int multiline = 0; int multiline = 0;
const char* sp; const char* sp;
const char* sq; const char* sq;
if (!src) return -1;
if (*src != '\'' && *src != '"') return -1;
*ret = 0; *ret = 0;
if (!src) return -1;
int qchar = src[0];
int srclen = strlen(src); int srclen = strlen(src);
if (*src == '\'') { if (! (qchar == '\'' || qchar == '"')) {
if (0 == strncmp(src, "'''", 3)) { return -1;
}
// triple quotes?
if (qchar == src[1] && qchar == src[2]) {
multiline = 1; multiline = 1;
sp = src + 3; sp = src + 3;
sq = src + srclen - 3; sq = src + srclen - 3;
/* last 3 chars in src must be ''' */ /* last 3 chars in src must be qchar */
if (! (sp <= sq && 0 == strcmp(sq, "'''"))) if (! (sp <= sq && sq[0] == qchar && sq[1] == qchar && sq[2] == qchar))
return -1; return -1;
/* skip first new line right after ''' */ /* skip new line immediate after qchar */
if (*sp == '\n') if (sp[0] == '\n')
sp++; sp++;
else if (sp[0] == '\r' && sp[1] == '\n') else if (sp[0] == '\r' && sp[1] == '\n')
sp += 2; sp += 2;
@ -2117,40 +2128,20 @@ int toml_rtos(const char* src, char** ret)
} else { } else {
sp = src + 1; sp = src + 1;
sq = src + srclen - 1; sq = src + srclen - 1;
/* last char in src must be ' */ /* last char in src must be qchar */
if (! (sp <= sq && *sq == '\'')) if (! (sp <= sq && *sq == qchar))
return -1; return -1;
/* copy from sp to p */
*ret = STRNDUP(sp, sq - sp);
} }
if (qchar == '\'') {
*ret = norm_lit_str(sp, sq - sp, *ret = norm_lit_str(sp, sq - sp,
multiline, multiline,
dummy_errbuf, sizeof(dummy_errbuf)); 0, 0);
return *ret ? 0 : -1;
}
if (0 == strncmp(src, "\"\"\"", 3)) {
multiline = 1;
sp = src + 3;
sq = src + srclen - 3;
if (! (sp <= sq && 0 == strcmp(sq, "\"\"\"")))
return -1;
/* skip first new line right after """ */
if (*sp == '\n')
sp++;
else if (sp[0] == '\r' && sp[1] == '\n')
sp += 2;
} else { } else {
sp = src + 1;
sq = src + srclen - 1;
if (! (sp <= sq && *sq == '"'))
return -1;
}
*ret = norm_basic_str(sp, sq - sp, *ret = norm_basic_str(sp, sq - sp,
multiline, multiline,
dummy_errbuf, sizeof(dummy_errbuf)); 0, 0);
}
return *ret ? 0 : -1; return *ret ? 0 : -1;
} }