More & better formatting

master
Avril 6 years ago
parent 52f831c3b9
commit d72c20acae

@ -1,7 +1,7 @@
SOURCE:= src/*.c
TEST_SOURCE:= src/test/*.c
INCLUDE:= include/
CFLAGS:= -Wall --std=gnu99
CFLAGS:= -Wall -g --std=gnu99
OBJ:= obj
BUILD:= build
LFLAGS:= -L./$(BUILD) -lse

@ -15,6 +15,9 @@ typedef char* exString;
#define EXS(s) (* (char**)(s))
typedef char (*exsp_select)(void* state, char mapchar);
typedef int (*exsp_where)(void* state, char mapchar);
exString* exs_new(const char* from);
exString* exs_clone(exString* from);
void exs_free(exString* str);
@ -23,8 +26,18 @@ void exs_append(exString* str, const char* from);
void exs_appendf(exString* str, const char* fmt, ...);
size_t exs_realsize(exString* str);
void exs_reduce(exString* str, size_t by);
void exs_appendtimes(exString* str, char c, int times);
void exs_nappendc(exString* str, char c, int times);
void exs_appendc(exString* str, char c);
void exs_recalc(exString* str);
void exs_reset(exString * str);
exString* exs_where(exString* str, exsp_where func, void* state);
exString* exs_select(exString *str, exsp_select func, void* state);
void exs_whereip(exString* str, exsp_where, void* state);
void exs_selectip(exString* str, exsp_select, void* state);
char exspf_upper(void* state, char c);
char exspf_lower(void* state, char c);
int exspf_only(void* state, char c);
int exspf_only_not(void* state, char c);
#endif /* _EXSTRING_H */

@ -18,9 +18,15 @@ typedef struct cons {
struct cons* cdr;
} list_t;
//TODO: String quoting & escaping.
#define SET_PARSE_NIL (1<<0)
#define SET_PARSE_QUOTE (1<<1)
#define SET_PARSE_ESCAPE (1<<2)
#define SET_PARSE_INSENSITIVE (1<<3)
list_t* se_parse(const char* sexpr); //Parse string into list.
#define SETP_DEFAULT (SET_PARSE_QUOTE | SET_PARSE_ESCAPE)
#define SETP_LISP (SETP_DEFAULT | SET_PARSE_INSENSITIVE | SET_PARSE_NIL)
list_t* se_parse(const char* sexpr, unsigned int flags); //Parse string into list.
void se_free(list_t* list); //Free whole list.
void se_print(FILE* fp, const list_t* list); //Print list to fp, if fp is NULL, print to stdout.

@ -3,6 +3,7 @@
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <ctype.h>
#include <internal/exstring.h>
@ -122,7 +123,7 @@ void exs_reduce(exString *str, size_t sz)
}
}
void exs_appendtimes(exString *str, char c, int times)
void exs_nappendc(exString *str, char c, int times)
{
if(!times) return;
else if(times==1) exs_nappend(str, &c, 1);
@ -132,6 +133,11 @@ void exs_appendtimes(exString *str, char c, int times)
}
}
void exs_appendc(exString* str, char c)
{
exs_nappendc(str, c, 1);
}
void exs_recalc(exString* str)
{
register int i=0;
@ -144,7 +150,71 @@ void exs_recalc(exString* str)
}
exString* exs_select(exString* from, exsp_select func, void* data)
{
exString *ret = exs_clone(from);
memset(*ret, 0, GETOPT(ret)->currentSize);
for(register int i=0;i<strlen(*from);i++)
(*ret)[i] = func(data, (*from)[i]);
exs_recalc(ret);
return ret;
}
exString* exs_where(exString* from, exsp_where func, void* data)
{
exString *ret = exs_clone(from);
memset(*ret, 0, GETOPT(ret)->currentSize);
for(register int i=0,j=0;i<strlen(*from);i++)
if(func(data, (*from)[i]))
{
(*ret)[j] = (*from)[i];
j+=1;
}
exs_recalc(ret);
return ret;
}
void exs_selectip(exString* str, exsp_select func, void* data)
{
exString* out = exs_select(str,func,data);
exs_reset(str);
exs_append(str, *out);
exs_free(out);
}
void exs_whereip(exString* str, exsp_where func, void* data)
{
exString* out = exs_where(str,func,data);
exs_reset(str);
exs_append(str, *out);
exs_free(out);
}
void exs_reset(exString *str)
{
exs_reduce(str, GETOPT(str)->currentSize);
}
char exspf_upper(void* state, char c)
{
return toupper((unsigned char)c);
}
char exspf_lower(void* state, char c)
{
return tolower((unsigned char)c);
}
int exspf_only(void *state, char c)
{
char* st = state;
for(;*st;st++) if(*st==c) return 1;
return 0;
}
int exspf_only_not(void *state, char c)
{
char* st = state;
for(;*st;st++) if(*st==c) return 0;
return 1;
}

@ -1,53 +1,76 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <libse.h>
#include <internal/exstring.h>
static void _addcar(list_t* out, exString* token)
static void _addcar(list_t* out, exString* token, int nil, int ucase)
{
#ifdef SE_PARSE_NIL
if(strcmp(EXS(token), "nil")==0)
if(ucase)
for(char* t = *token; *t; t++)
*t = toupper((unsigned char)*t);
if(nil&&strcmp(EXS(token), "NIL")==0)
out->ptr = NULL;
else {
#endif
out->ptr = strdup(EXS(token));
out->car.size = strlen(out->ptr);
out->car.alloced = 1;
exs_reset(token);
#ifdef SE_PARSE_NIL
}
#endif
}
static list_t* _parse_list(const char* sexpr, int* lp)
static list_t* _parse_list(const char* sexpr, int* lp, unsigned int flags)
{
list_t* out = malloc(sizeof(list_t));
memset(out,0,sizeof(list_t));
exString *token = exs_new(NULL);
int instr=0;
int inesc=0;
while(*sexpr) {
if(*sexpr==' ') {
if(inesc)
{
exs_nappend(token, sexpr, 1);
inesc=0;
}
else if(instr)
{
if(*sexpr=='\"')
instr=0;
else exs_nappend(token, sexpr, 1);
}
else if(*sexpr==' ' || *sexpr == '\r' || *sexpr == '\n' || *sexpr == '\t') {
if(strlen(EXS(token))>0) {
_addcar(out, token);
_addcar(out, token, flags & SET_PARSE_NIL, flags & SET_PARSE_INSENSITIVE);
if(*(sexpr+1))
out->cdr = _parse_list(sexpr, lp);
out->cdr = _parse_list(sexpr, lp, flags);
else out->cdr =NULL;
break;
}
}
else if(*sexpr == ')')
{
_addcar(out, token);
if(**token)
_addcar(out, token, flags & SET_PARSE_NIL, flags & SET_PARSE_INSENSITIVE);
out->cdr=NULL;
(*lp)+=1;
break;
}
else if(*sexpr == '(')
{
if(**token) {
_addcar(out, token, flags & SET_PARSE_NIL, flags&SET_PARSE_INSENSITIVE);
if(*(sexpr+1))
out->cdr = _parse_list(sexpr, lp ,flags);
else out->cdr = NULL; //Invalid syntax.
break;
}
else {
int hp =0;
list_t* nc = _parse_list(sexpr+1, &hp);
list_t* nc = _parse_list(sexpr+1, &hp, flags);
out->ptr = nc;
out->car.alloced=1;
out->car.sexpr=1;
@ -56,10 +79,15 @@ static list_t* _parse_list(const char* sexpr, int* lp)
(*lp) += hp+1;
if(*(sexpr))
out->cdr = _parse_list(sexpr, lp);
out->cdr = _parse_list(sexpr, lp, flags);
else out->cdr =NULL;
break;
}
}
else if(flags & SET_PARSE_QUOTE && *sexpr == '\"')
instr = 1;
else if(flags & SET_PARSE_ESCAPE && *sexpr == '\\')
inesc = 1;
else
exs_nappend(token, sexpr, 1);
sexpr+=1;
@ -67,7 +95,7 @@ static list_t* _parse_list(const char* sexpr, int* lp)
}
if(strlen(EXS(token))>0)
_addcar(out, token);
_addcar(out, token, flags & SET_PARSE_NIL, flags & SET_PARSE_INSENSITIVE);
else if(!out->ptr && !out->cdr) {
free(out);
out=NULL;
@ -77,10 +105,89 @@ static list_t* _parse_list(const char* sexpr, int* lp)
return out;
}
list_t* se_parse(const char* str)
static int iws(char c)
{
switch(c)
{
case ' ':
case '\t':
case '\n':
case '\r':
return 1;
default: return 0;
}
}
static int nows(const char* str)
{
int lp=0;
return _parse_list(str,&lp);
register int i=0;
for(;*str&&iws(*str);str++) i++;
return !*str?0:i;
}
int se_valid(const char* str)
{
exString* s = exs_new(str);
exs_whereip(s, &exspf_only_not, " \t\n\r");
char *ns = EXS(s);
int ret = *ns && !(*ns=='(' && memcmp(ns, ns+1, strlen(ns)-1)==0);
exs_free(s);
return ret;
}
list_t* se_parse(const char* str, unsigned int flags)
{
if(!str) return NULL;
int lp=0,tst=0;
if(*str=='(')
str+=1;
else if( (tst=nows(str))>0)
return se_parse(str+tst, flags);
if(!se_valid(str)) return NULL;
return _parse_list(str,&lp, flags);
}
static int _se_add_quotes(const char* inp)
{
do {
switch (*inp) {
case '\"':
case ' ':
case ')':
case '(':
return 1;
default: break;
}
inp+=1;
}
while (*inp);
return 0;
}
void _se_append(exString *out, const char* thing)
{
int q = _se_add_quotes(thing);
exString* str = exs_new(NULL);
for(;*thing;thing++)
{
switch(*thing)
{
case '\"':
exs_appendc(str, '\\');
default:break;
}
exs_nappend(str, thing, 1);
}
if(q)
{
exs_appendc(out, '\"');
exs_appendc(str, '\"');
}
exs_append(out, *str);
exs_free(str);
}
void _list_tostring(exString *out, const list_t* list)
@ -91,7 +198,7 @@ void _list_tostring(exString *out, const list_t* list)
exs_append(out, "(");
_list_tostring(out, (list_t*)list->ptr);
}
else exs_append(out,(char*)list->ptr);
else _se_append(out,(char*)list->ptr);
if(list->cdr)
{

@ -23,7 +23,7 @@ void test_exs()
exs_append(test, " Scream: ");
exs_appendtimes(test, 'A', 6);
exs_nappendc(test, 'A', 6);
exs_appendf(test, "\nCurrent size: %d -> %d", strlen(EXS(test)), exs_realsize(test));
exs_appendf(test, "AOISDJOAIJS%s", "sokdok");
@ -37,10 +37,28 @@ void test_exs()
void test_parse()
{
const char* parse = "hello (there (firend) (i) (love (you a lot))) how are (you (doing today?))";
list_t* list = se_parse(parse);
FILE* fp = fopen("test.se", "rb");
exString *buf = exs_new(NULL);
char rb[8];
int rd=0;
memset(rb,0,sizeof(rb));
printf("Parse okay\n");
while( (rd=fread(rb, 1, 8, fp))>0)
{
exs_nappend(buf, rb, rd);
}
fclose(fp);
const char* parse = EXS(buf);
//printf("%s\n", parse);
//exs_free(buf);
list_t* list = se_parse(parse, SETP_DEFAULT);
if(!list)
{
printf("Parse failed.\n");
return;
}
//printf("Parse okay.\n");
se_print(NULL, list);
printf("\n");
@ -48,6 +66,7 @@ void test_parse()
// printf("(cadr list) -> %s\n", (list->cdr?(char*)list->cdr->ptr:"nil"));
se_free(list);
exs_free(buf);
}
int main()

@ -0,0 +1,12 @@
(root
("name1"
(key value)
(key "value string")
(key value)
)
("name 2"
(key2 value2)
(key2 "value string 2")
(\"key4 \(\))
)
)
Loading…
Cancel
Save