|
|
|
@ -40,11 +40,16 @@ LA-CC-04-094
|
|
|
|
|
#include <sexpr/sexp.h>
|
|
|
|
|
#include <sexpr/faststack.h>
|
|
|
|
|
|
|
|
|
|
/* we need a locks in this case and we don't have ability to change API */
|
|
|
|
|
#ifndef _NO_MEMORY_MANAGEMENT_
|
|
|
|
|
#include <pthread.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* constants related to atom buffer sizes and growth.
|
|
|
|
|
*/
|
|
|
|
|
static size_t sexp_val_start_size = 256;
|
|
|
|
|
static size_t sexp_val_grow_size = 64;
|
|
|
|
|
static size_t sexp_val_grow_size = 128;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Function for tuning growth parameters.
|
|
|
|
@ -79,6 +84,7 @@ parse_data_t;
|
|
|
|
|
*/
|
|
|
|
|
#ifndef _NO_MEMORY_MANAGEMENT_
|
|
|
|
|
faststack_t *pd_cache;
|
|
|
|
|
pthread_mutex_t pd_cache_lock;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -91,6 +97,7 @@ faststack_t *pd_cache;
|
|
|
|
|
*/
|
|
|
|
|
#ifndef _NO_MEMORY_MANAGEMENT_
|
|
|
|
|
faststack_t *sexp_t_cache;
|
|
|
|
|
pthread_mutex_t sexp_cache_lock;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -115,23 +122,28 @@ sexp_t_allocate(void) {
|
|
|
|
|
|
|
|
|
|
if (sexp_t_cache == NULL) {
|
|
|
|
|
sexp_t_cache = make_stack();
|
|
|
|
|
pthread_mutex_init(&sexp_cache_lock, NULL);
|
|
|
|
|
if (sexp_t_cache == NULL) {
|
|
|
|
|
sexp_errno = SEXP_ERR_MEMORY;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pthread_mutex_lock(&sexp_cache_lock);
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
sx = (sexp_t *)sexp_malloc(sizeof(sexp_t));
|
|
|
|
|
#else
|
|
|
|
|
sx = sexp_malloc(sizeof(sexp_t));
|
|
|
|
|
#endif
|
|
|
|
|
if (sx == NULL) {
|
|
|
|
|
pthread_mutex_unlock(&sexp_cache_lock);
|
|
|
|
|
sexp_errno = SEXP_ERR_MEMORY;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sx->next = sx->list = NULL;
|
|
|
|
|
pthread_mutex_unlock(&sexp_cache_lock);
|
|
|
|
|
} else {
|
|
|
|
|
pthread_mutex_lock(&sexp_cache_lock);
|
|
|
|
|
if (empty_stack(sexp_t_cache)) {
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
sx = (sexp_t *)sexp_malloc(sizeof(sexp_t));
|
|
|
|
@ -139,6 +151,7 @@ sexp_t_allocate(void) {
|
|
|
|
|
sx = sexp_malloc(sizeof(sexp_t));
|
|
|
|
|
#endif
|
|
|
|
|
if (sx == NULL) {
|
|
|
|
|
pthread_mutex_unlock(&sexp_cache_lock);
|
|
|
|
|
sexp_errno = SEXP_ERR_MEMORY;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
@ -148,6 +161,7 @@ sexp_t_allocate(void) {
|
|
|
|
|
l = pop(sexp_t_cache);
|
|
|
|
|
sx = (sexp_t *)l->data;
|
|
|
|
|
}
|
|
|
|
|
pthread_mutex_unlock(&sexp_cache_lock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sx;
|
|
|
|
@ -173,6 +187,7 @@ sexp_t_deallocate(sexp_t *s) {
|
|
|
|
|
|
|
|
|
|
if (sexp_t_cache == NULL) {
|
|
|
|
|
sexp_t_cache = make_stack();
|
|
|
|
|
pthread_mutex_init(&sexp_cache_lock, NULL);
|
|
|
|
|
if (sexp_t_cache == NULL) {
|
|
|
|
|
|
|
|
|
|
/**** HOW DO WE GET THE USER TO KNOW SOMETHING HAPPENED? ****/
|
|
|
|
@ -185,6 +200,7 @@ sexp_t_deallocate(sexp_t *s) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
pthread_mutex_lock(&sexp_cache_lock);
|
|
|
|
|
|
|
|
|
|
s->list = s->next = NULL;
|
|
|
|
|
|
|
|
|
@ -193,8 +209,10 @@ sexp_t_deallocate(sexp_t *s) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s->val = NULL;
|
|
|
|
|
memset(s, 0, sizeof(sexp_t));
|
|
|
|
|
|
|
|
|
|
sexp_t_cache = push(sexp_t_cache, s);
|
|
|
|
|
pthread_mutex_unlock(&sexp_cache_lock);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
@ -210,6 +228,7 @@ void sexp_cleanup(void) {
|
|
|
|
|
stack_lvl_t *l;
|
|
|
|
|
|
|
|
|
|
if (pd_cache != NULL) {
|
|
|
|
|
pthread_mutex_lock(&pd_cache_lock);
|
|
|
|
|
l = pd_cache->top;
|
|
|
|
|
while (l != NULL) {
|
|
|
|
|
sexp_free(l->data,sizeof(parse_data_t));
|
|
|
|
@ -217,15 +236,20 @@ void sexp_cleanup(void) {
|
|
|
|
|
}
|
|
|
|
|
destroy_stack(pd_cache);
|
|
|
|
|
pd_cache = NULL;
|
|
|
|
|
pthread_mutex_unlock(&pd_cache_lock);
|
|
|
|
|
pthread_mutex_destroy(&pd_cache_lock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sexp_t_cache != NULL) {
|
|
|
|
|
pthread_mutex_lock(&sexp_cache_lock);
|
|
|
|
|
l = sexp_t_cache->top;
|
|
|
|
|
while (l != NULL) {
|
|
|
|
|
sexp_free(l->data,sizeof(sexp_t));
|
|
|
|
|
l = l->below;
|
|
|
|
|
}
|
|
|
|
|
destroy_stack(sexp_t_cache);
|
|
|
|
|
pthread_mutex_lock(&sexp_cache_lock);
|
|
|
|
|
pthread_mutex_destroy(&sexp_cache_lock);
|
|
|
|
|
sexp_t_cache = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -248,13 +272,14 @@ pd_allocate(void) {
|
|
|
|
|
stack_lvl_t *l;
|
|
|
|
|
|
|
|
|
|
if (pd_cache == NULL) {
|
|
|
|
|
pthread_mutex_init(&pd_cache_lock, NULL);
|
|
|
|
|
pd_cache = make_stack();
|
|
|
|
|
|
|
|
|
|
if (pd_cache == NULL) {
|
|
|
|
|
sexp_errno = SEXP_ERR_MEMORY;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pthread_mutex_lock(&pd_cache_lock);
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
p = (parse_data_t *)sexp_malloc(sizeof(parse_data_t));
|
|
|
|
|
#else
|
|
|
|
@ -265,8 +290,9 @@ pd_allocate(void) {
|
|
|
|
|
sexp_errno = SEXP_ERR_MEMORY;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&pd_cache_lock);
|
|
|
|
|
} else {
|
|
|
|
|
pthread_mutex_lock(&pd_cache_lock);
|
|
|
|
|
if (empty_stack(pd_cache)) {
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
p = (parse_data_t *)sexp_malloc(sizeof(parse_data_t));
|
|
|
|
@ -276,12 +302,14 @@ pd_allocate(void) {
|
|
|
|
|
|
|
|
|
|
if (p == NULL) {
|
|
|
|
|
sexp_errno = SEXP_ERR_MEMORY;
|
|
|
|
|
pthread_mutex_unlock(&pd_cache_lock);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
l = pop(pd_cache);
|
|
|
|
|
p = (parse_data_t *)l->data;
|
|
|
|
|
}
|
|
|
|
|
pthread_mutex_unlock(&pd_cache_lock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return p;
|
|
|
|
@ -301,14 +329,19 @@ void
|
|
|
|
|
pd_deallocate(parse_data_t *p) {
|
|
|
|
|
if (pd_cache == NULL) {
|
|
|
|
|
pd_cache = make_stack();
|
|
|
|
|
pthread_mutex_init(&pd_cache_lock, NULL);
|
|
|
|
|
if (pd_cache == NULL) {
|
|
|
|
|
sexp_free(p, sizeof(parse_data_t));
|
|
|
|
|
sexp_errno = SEXP_ERR_MEMORY;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
pthread_mutex_lock(&pd_cache_lock);
|
|
|
|
|
|
|
|
|
|
memset(p, 0, sizeof(parse_data_t));
|
|
|
|
|
pd_cache = push(pd_cache, p);
|
|
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&pd_cache_lock);
|
|
|
|
|
}
|
|
|
|
|
#endif /* _NO_MEMORY_MANAGEMENT_ */
|
|
|
|
|
|
|
|
|
@ -509,9 +542,9 @@ init_continuation(char *str)
|
|
|
|
|
|
|
|
|
|
/* allocate atom buffer */
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
cc->val = (char *)sexp_malloc(sizeof(char)*sexp_val_start_size);
|
|
|
|
|
cc->val = (char *)sexp_calloc(1, sizeof(char)*sexp_val_start_size);
|
|
|
|
|
#else
|
|
|
|
|
cc->val = sexp_malloc(sizeof(char)*sexp_val_start_size);
|
|
|
|
|
cc->val = sexp_calloc(1, sizeof(char)*sexp_val_start_size);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (cc->val == NULL) {
|
|
|
|
@ -599,6 +632,12 @@ iparse_sexp (char *s, size_t len, pcont_t *cc) {
|
|
|
|
|
* cparse_sexp */
|
|
|
|
|
pcont_t *eparse_sexp (char *str, size_t len, pcont_t *lc);
|
|
|
|
|
|
|
|
|
|
#ifdef REGISTEROPTIMIZAITON
|
|
|
|
|
#define REGISTER register
|
|
|
|
|
#else
|
|
|
|
|
#define REGISTER
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Continuation based parser - the guts of the package.
|
|
|
|
|
*/
|
|
|
|
@ -607,17 +646,17 @@ cparse_sexp (char *str, size_t len, pcont_t *lc)
|
|
|
|
|
{
|
|
|
|
|
char *t = NULL;
|
|
|
|
|
char *s = NULL;
|
|
|
|
|
register size_t binexpected = 0;
|
|
|
|
|
register size_t binread = 0;
|
|
|
|
|
register parsermode_t mode = PARSER_NORMAL;
|
|
|
|
|
register size_t val_allocated = 0;
|
|
|
|
|
register unsigned int squoted = 0;
|
|
|
|
|
register size_t val_used = 0;
|
|
|
|
|
register unsigned int state = 1;
|
|
|
|
|
register unsigned int depth = 0;
|
|
|
|
|
register unsigned int qdepth = 0;
|
|
|
|
|
register unsigned int elts = 0;
|
|
|
|
|
register unsigned int esc = 0;
|
|
|
|
|
REGISTER size_t binexpected = 0;
|
|
|
|
|
REGISTER size_t binread = 0;
|
|
|
|
|
REGISTER parsermode_t mode = PARSER_NORMAL;
|
|
|
|
|
REGISTER size_t val_allocated = 0;
|
|
|
|
|
REGISTER unsigned int squoted = 0;
|
|
|
|
|
REGISTER size_t val_used = 0;
|
|
|
|
|
REGISTER unsigned int state = 1;
|
|
|
|
|
REGISTER unsigned int depth = 0;
|
|
|
|
|
REGISTER unsigned int qdepth = 0;
|
|
|
|
|
REGISTER unsigned int elts = 0;
|
|
|
|
|
REGISTER unsigned int esc = 0;
|
|
|
|
|
pcont_t *cc = NULL;
|
|
|
|
|
char *val = NULL;
|
|
|
|
|
char *vcur = NULL;
|
|
|
|
|