add config support
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
/driver
|
||||
/out
|
||||
@@ -0,0 +1,21 @@
|
||||
CFLAGS := -O0 -g -fsanitize=address,undefined -std=c17 -Wmissing-declarations -Wall -Wextra -MMD
|
||||
|
||||
all: driver
|
||||
|
||||
driver: scankey.c
|
||||
$(CC) $(CFLAGS) -o $@ scankey.c
|
||||
|
||||
test: all
|
||||
bash run.sh
|
||||
|
||||
-include driver.d
|
||||
|
||||
clean:
|
||||
rm -f *.o *.d driver
|
||||
|
||||
distclean: clean
|
||||
|
||||
format:
|
||||
clang-format -i *.[ch]
|
||||
|
||||
.PHONY: all clean distclean format test
|
||||
@@ -0,0 +1,5 @@
|
||||
str1 =
|
||||
# comment
|
||||
|
||||
str2 #comment
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
"title" =
|
||||
'title' =
|
||||
bare_key =
|
||||
bare-key =
|
||||
1234 =
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
apple.type =
|
||||
3.14159 =
|
||||
1.2 .3 . 4 =
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
[table-1]
|
||||
[dog."tater.man"]
|
||||
[a.b.c] # this is best practice
|
||||
[ d.e.f ] # same as [d.e.f]
|
||||
[ g . h . i ] # same as [g.h.i]
|
||||
[ j . "ʞ" . 'l' ] # same as [j."ʞ".'l']
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
# [x] you
|
||||
# [x.y] don't
|
||||
# [x.y.z] need these
|
||||
[x.y.z.w] # for this to work
|
||||
|
||||
[x] # defining a super-table afterward is ok
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
name { # error
|
||||
name } # error
|
||||
name [ # error
|
||||
name ] # error
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
[[products.1]]
|
||||
[[products.2]]
|
||||
@@ -0,0 +1,3 @@
|
||||
café =
|
||||
ñoño =
|
||||
日本語 =
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
mkdir -p out
|
||||
|
||||
echo
|
||||
echo =========================
|
||||
echo == scankey test
|
||||
echo =========================
|
||||
|
||||
for fname in {1..100}; do
|
||||
IN="in/$fname"
|
||||
if [ -f $IN ]; then
|
||||
echo test $fname
|
||||
OUT="out/$fname.out"
|
||||
GOOD="good/$fname.out"
|
||||
./driver $IN &> $OUT
|
||||
diff $GOOD $OUT || { echo '--- FAILED ---'; exit 1; }
|
||||
fi
|
||||
done
|
||||
|
||||
echo DONE
|
||||
@@ -0,0 +1,127 @@
|
||||
#include "../../src/tomlc17.c"
|
||||
#include <stdlib.h>
|
||||
|
||||
const char **g_argv = 0;
|
||||
int g_argc = 0;
|
||||
|
||||
static void usage() {
|
||||
fprintf(stderr, "Usage: %s fname\n", g_argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void printspecial(const char *p, int n) {
|
||||
for (int i = 0; i < n; i++, p++) {
|
||||
int ch = (*p == '\n') ? '_' : *p;
|
||||
putchar(ch);
|
||||
}
|
||||
}
|
||||
|
||||
static void printtok(char *content, const token_t tok) {
|
||||
// clang-format off
|
||||
#define CASESTR(x) case TOK_ ## x: s = #x; break
|
||||
// clang-format on
|
||||
char *s = 0;
|
||||
switch (tok.toktyp) {
|
||||
CASESTR(DOT);
|
||||
CASESTR(EQUAL);
|
||||
CASESTR(COMMA);
|
||||
CASESTR(LBRACK);
|
||||
CASESTR(LLBRACK);
|
||||
CASESTR(RBRACK);
|
||||
CASESTR(RRBRACK);
|
||||
CASESTR(LBRACE);
|
||||
CASESTR(RBRACE);
|
||||
CASESTR(STRING);
|
||||
CASESTR(MLSTRING);
|
||||
CASESTR(LITSTRING);
|
||||
CASESTR(MLLITSTRING);
|
||||
CASESTR(TIME);
|
||||
CASESTR(DATE);
|
||||
CASESTR(DATETIME);
|
||||
CASESTR(DATETIMETZ);
|
||||
CASESTR(INTEGER);
|
||||
CASESTR(FLOAT);
|
||||
CASESTR(BOOL);
|
||||
CASESTR(LIT);
|
||||
CASESTR(ENDL);
|
||||
CASESTR(FIN);
|
||||
}
|
||||
printf("%s %ld %d ", s, tok.str.ptr - content, tok.str.len);
|
||||
printspecial(tok.str.ptr, tok.str.len);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static char *readfile(const char *fname, int *ret_len) {
|
||||
FILE *fp = fopen(fname, "r");
|
||||
if (!fp) {
|
||||
perror("fopen");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Seek to the end of the file to determine its size
|
||||
if (fseek(fp, 0, SEEK_END) != 0) {
|
||||
perror("fseek");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
long file_size = ftell(fp);
|
||||
if (file_size == -1) {
|
||||
perror("ftell");
|
||||
exit(1);
|
||||
}
|
||||
rewind(fp); // Go back to the beginning of the file
|
||||
|
||||
// Allocate memory for the file content, plus one for the null terminator
|
||||
char *content = malloc(file_size + 1);
|
||||
if (!content) {
|
||||
perror("out of memory");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Read the file into the buffer
|
||||
size_t read_size = fread(content, 1, file_size, fp);
|
||||
if (read_size != (size_t)file_size) {
|
||||
perror("fread");
|
||||
exit(1);
|
||||
}
|
||||
content[file_size] = '\0'; // Null-terminate the string
|
||||
fclose(fp);
|
||||
|
||||
*ret_len = file_size;
|
||||
return content;
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
g_argc = argc;
|
||||
g_argv = argv;
|
||||
if (argc != 2) {
|
||||
usage();
|
||||
}
|
||||
int len;
|
||||
char *content = readfile(argv[1], &len);
|
||||
char errbuf[200];
|
||||
|
||||
scanner_t scanner;
|
||||
scanner_t *sp = &scanner;
|
||||
scan_init(sp, content, len, errbuf, sizeof(errbuf));
|
||||
|
||||
for (;;) {
|
||||
(void)scan_value; // silent compiler
|
||||
token_t tok;
|
||||
if (scan_key(sp, &tok)) {
|
||||
break;
|
||||
}
|
||||
if (tok.toktyp == TOK_FIN) {
|
||||
break;
|
||||
}
|
||||
printtok(content, tok);
|
||||
}
|
||||
|
||||
if (sp->errmsg) {
|
||||
printf("ERROR: %s (line %d)\n", sp->errmsg, sp->lineno);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
free(content);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user