|
|
|
@ -132,16 +132,23 @@ int se_valid(const char* str)
|
|
|
|
|
|
|
|
|
|
char *ns = EXS(s);
|
|
|
|
|
int ret = *ns && !(*ns=='(' && memcmp(ns, ns+1, strlen(ns)-1)==0);
|
|
|
|
|
|
|
|
|
|
exs_free(s);
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
list_t* se_last(list_t *list)
|
|
|
|
|
{
|
|
|
|
|
if(list->cdr) return se_last(list->cdr);
|
|
|
|
|
else return list;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
list_t* se_parse(const char* str, unsigned int flags)
|
|
|
|
|
{
|
|
|
|
|
if(!str) return NULL;
|
|
|
|
|
int lp=0,tst=0;
|
|
|
|
|
if(*str=='(')
|
|
|
|
|
if(*str=='(' && !(flags & SET_NO_WRAP))
|
|
|
|
|
str+=1;
|
|
|
|
|
else if( (tst=nows(str))>0)
|
|
|
|
|
return se_parse(str+tst, flags);
|
|
|
|
@ -157,6 +164,8 @@ static int _se_add_quotes(const char* inp)
|
|
|
|
|
case ' ':
|
|
|
|
|
case ')':
|
|
|
|
|
case '(':
|
|
|
|
|
case '\t':
|
|
|
|
|
case '\r':
|
|
|
|
|
return 1;
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
@ -175,6 +184,7 @@ void _se_append(exString *out, const char* thing)
|
|
|
|
|
{
|
|
|
|
|
switch(*thing)
|
|
|
|
|
{
|
|
|
|
|
case '\n':
|
|
|
|
|
case '\"':
|
|
|
|
|
exs_appendc(str, '\\');
|
|
|
|
|
default:break;
|
|
|
|
@ -224,7 +234,73 @@ void se_print(FILE* fp, const list_t* list)
|
|
|
|
|
void se_free(list_t* list)
|
|
|
|
|
{
|
|
|
|
|
if(list->cdr) se_free(list->cdr);
|
|
|
|
|
if(list->ptr && list->car.alloced)
|
|
|
|
|
free(list->ptr);
|
|
|
|
|
if(list->ptr) {
|
|
|
|
|
if(list->car.alloced) {
|
|
|
|
|
if(list->car.sexpr)
|
|
|
|
|
se_free((list_t*)list->ptr);
|
|
|
|
|
else
|
|
|
|
|
free(list->ptr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
free(list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum _se_type se_typeof(list_t* list)
|
|
|
|
|
{
|
|
|
|
|
if(!list->ptr) return SE_NIL;
|
|
|
|
|
else if(list->car.sexpr) return SE_LIST;
|
|
|
|
|
else return SE_STRING;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static list_t* _se_new(void* car, enum _se_type type, int dupe)
|
|
|
|
|
{
|
|
|
|
|
list_t* m = malloc(sizeof(list_t));
|
|
|
|
|
memset(m,0,sizeof(list_t));
|
|
|
|
|
void* _car = car;
|
|
|
|
|
if(car) {
|
|
|
|
|
switch(type)
|
|
|
|
|
{
|
|
|
|
|
case SE_STRING:
|
|
|
|
|
if(dupe) {
|
|
|
|
|
char* dup = strdup((char*)car);
|
|
|
|
|
m->ptr = dup;
|
|
|
|
|
m->car.size = strlen(dup);
|
|
|
|
|
m->car.alloced = 1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
m->ptr = car;
|
|
|
|
|
m->car.size = strlen(car);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SE_LIST:
|
|
|
|
|
if(dupe) { //TODO: Clone alloced cars?
|
|
|
|
|
list_t* cr = malloc(sizeof(list_t));
|
|
|
|
|
list_t* or = cr;
|
|
|
|
|
list_t* car = _car;
|
|
|
|
|
memcpy(cr, car, sizeof(list_t));
|
|
|
|
|
while(car->cdr) {
|
|
|
|
|
cr->cdr = malloc(sizeof(list_t));
|
|
|
|
|
memcpy(cr->cdr, car->cdr, sizeof(list_t));
|
|
|
|
|
cr->cdr->car.alloced = 0;
|
|
|
|
|
car = car->cdr;
|
|
|
|
|
cr = cr->cdr;
|
|
|
|
|
}
|
|
|
|
|
m->ptr = or;
|
|
|
|
|
m->car.size = sizeof(list_t);
|
|
|
|
|
m->car.alloced = 1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
m->ptr = car;
|
|
|
|
|
m->car.size = sizeof(list_t);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return m;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
list_t* se_new(char* str, int dupe)
|
|
|
|
|
{
|
|
|
|
|
return _se_new(str, SE_STRING, dupe); //We don't need the list part.
|
|
|
|
|
}
|
|
|
|
|