All tests passing for C implementation.
This commit is contained in:
		
							
								
								
									
										1
									
								
								packages/c/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								packages/c/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
test/test-runner
 | 
			
		||||
							
								
								
									
										9
									
								
								packages/c/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								packages/c/package.json
									
									
									
									
									
										Normal 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"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										63
									
								
								packages/c/test/test-runner.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								packages/c/test/test-runner.c
									
									
									
									
									
										Normal 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;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user