All tests passing for C implementation.

This commit is contained in:
Joshua Bemenderfer 2023-02-10 14:37:53 -05:00
parent c41990b793
commit 288c793d5e
7 changed files with 102 additions and 19 deletions

1
packages/c/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
test/test-runner

9
packages/c/package.json Normal file
View File

@ -0,0 +1,9 @@
{
"name": "@terrace/c",
"version": "0.0.1",
"license": "MIT",
"scripts": {
"build:test": "cc ./test/test-runner.c -o test/test-runner",
"test": "./test/test-runner"
}
}

View File

@ -2,6 +2,7 @@
#define TERRACE_PARSER_H
struct terrace_linedata_s {
char indent;
unsigned int level;
unsigned int offsetHead;
unsigned int offsetTail;
@ -10,13 +11,13 @@ struct terrace_linedata_s {
typedef struct terrace_linedata_s terrace_linedata_t;
void terrace_parse_line(char* line, terrace_linedata_t *lineData) {
if (line[0] == '\n') {
if (line == 0) {
// Reuse lineData->level from previous line.
lineData->offsetHead = 0;
lineData->offsetTail = 0;
} else {
unsigned int level = 0;
while (line[level] == ' ' && level <= lineData->level + 1) ++level;
while (line[level] == lineData->indent && level <= lineData->level + 1) ++level;
lineData->level = level;
lineData->offsetHead = level;
lineData->offsetTail = level;

View File

@ -0,0 +1,63 @@
#include "../parser.h"
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
void linedata_basic (char indent) {
char *line = NULL;
size_t bufsize = 32;
ssize_t c_read = 0;
terrace_linedata_t line_data;
line_data.indent = indent;
while(c_read = getline(&line, &bufsize, stdin)) {
if (c_read == -1) break;
char *terrace_line = strtok(line, "\n");
terrace_parse_line(terrace_line, &line_data);
if (terrace_line == 0) terrace_line = "";
printf("| level %u | indent %c | offsetHead %u | offsetTail %u | line %s |\n", line_data.level, line_data.indent, line_data.offsetHead, line_data.offsetTail, terrace_line);
};
}
void linedata_head_tail (char indent) {
char *line = NULL;
size_t bufsize = 32;
ssize_t c_read = 0;
terrace_linedata_t line_data;
line_data.indent = indent;
char *head;
char *tail;
while(c_read = getline(&line, &bufsize, stdin)) {
if (c_read == -1) break;
char *terrace_line = strtok(line, "\n");
terrace_parse_line(terrace_line, &line_data);
if (terrace_line == 0) terrace_line = "";
if (line_data.offsetTail < c_read) tail = &terrace_line[line_data.offsetTail + 1];
else tail = "";
// Cheeky move to avoid string slicing.
if (line_data.offsetHead < c_read) {
terrace_line[line_data.offsetTail] = '\0';
head = &terrace_line[line_data.offsetHead];
}
else head = "";
printf("| head %s | tail %s |\n", head, tail);
};
}
int main(int argc, char *argv[]) {
if (argc < 2) return 0;
char* test = argv[1];
if (!strcmp(test, "linedata:basic")) linedata_basic(' ');
if (!strcmp(test, "linedata:tabs")) linedata_basic('\t');
if (!strcmp(test, "linedata:head-tail")) linedata_head_tail(' ');
return 0;
}

View File

@ -8,5 +8,8 @@ pipeline
dependsOn ^build compile
outputs dist/**
test
build:test
dependsOn build
test
dependsOn build build:test

View File

@ -10,21 +10,21 @@ describe LineData
it Handles a blank line with a single space
key linedata:basic
packages js python
packages c js python
input \s
output
| level 1 | indent | offsetHead 1 | offsetTail 1 | line |
it Handles a blank line with two spaces
key linedata:basic
packages js python
packages c js python
input \s\s
output
| level 2 | indent | offsetHead 2 | offsetTail 2 | line |
it Handles a normal line at indent level 0
key linedata:basic
packages js python
packages c js python
input
line 1
output
@ -32,7 +32,7 @@ describe LineData
it Handles a normal line at indent level 1
key linedata:basic
packages js python
packages c js python
input
line 1
output
@ -40,7 +40,7 @@ describe LineData
it Handles a normal line at indent level 2
key linedata:basic
packages js python
packages c js python
input
line 1
output
@ -48,7 +48,7 @@ describe LineData
it Handles a normal line at indent level 1 indented with tabs
key linedata:tabs
packages js python
packages c js python
input
\tline 1
output
@ -56,7 +56,7 @@ describe LineData
it Handles a normal line at indent level 2 indented with tabs
key linedata:tabs
packages js python
packages c js python
input
\t\tline 1
output
@ -64,7 +64,7 @@ describe LineData
it Nests a normal line under a preceding normal line
key linedata:basic
packages js python
packages c js python
input
line 1
line 2
@ -74,7 +74,7 @@ describe LineData
it Nests multiple normal lines under a preceding normal line
key linedata:basic
packages js python
packages c js python
input
line 1
line 2
@ -88,7 +88,7 @@ describe LineData
it Does not nest an empty line under a preceding normal line
key linedata:basic
packages js python
packages c js python
comment Two newlines are needed here. A single newline will look to readline as if the input is finished.
input line 1\n\n
output
@ -97,7 +97,7 @@ describe LineData
it Does not nest multiple empty lines under a preceding normal line
key linedata:basic
packages js python
packages c js python
comment Four newlines are needed here. A single newline will look to readline as if the input is finished.
input line 1\n\n\n\n
output
@ -108,7 +108,7 @@ describe LineData
it Handles head and tail matching for lines with head and tail
key linedata:head-tail
packages js python
packages c js python
input
head1 tail1 tail2 tail3
output
@ -116,7 +116,7 @@ describe LineData
it Handles head and tail matching for lines with head but no tail
key linedata:head-tail
packages js python
packages c js python
input
head1
output
@ -124,7 +124,7 @@ describe LineData
it Handles head and tail matching for lines with head and trailing space
key linedata:head-tail
packages js python
packages c js python
input head1 \n
output
| head head1 | tail |

View File

@ -12,10 +12,16 @@
"dist/**"
]
},
"test": {
"build:test": {
"dependsOn": [
"build"
]
},
"test": {
"dependsOn": [
"build",
"build:test"
]
}
}
}
}