You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
3.0 KiB
C
137 lines
3.0 KiB
C
/**
|
|
@cond IGNORE
|
|
|
|
A wrapper functions to deal with a cstrings done as an io wrapper
|
|
Copyright (C) 2018 Alexander Vdolainen <avdolainen@zoho.com>
|
|
|
|
|
|
It is free software: you can redistribute it and/or modify it
|
|
under the terms of the GNU Lesser General Public License as published
|
|
by the Free Software Foundation, either version 2.1 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
See the GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.";
|
|
|
|
@endcond
|
|
**/
|
|
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sexpr/sexp.h>
|
|
|
|
sexp_cstrwrap_t *init_cstrwrap(const char *src)
|
|
{
|
|
sexp_cstrwrap_t *ow = NULL;
|
|
|
|
if(!src) {
|
|
sexp_errno = SEXP_ERR_NULLSTRING;
|
|
return NULL;
|
|
}
|
|
|
|
ow = (sexp_cstrwrap_t *)sexp_calloc(1, sizeof(sexp_cstrwrap_t));
|
|
|
|
if(!ow) {
|
|
sexp_errno = SEXP_ERR_MEMORY;
|
|
return NULL;
|
|
}
|
|
|
|
memset(ow, 0, sizeof(sexp_cstrwrap_t));
|
|
ow->seval = src;
|
|
ow->sln = strlen(src);
|
|
|
|
return ow;
|
|
}
|
|
|
|
void destroy_cstrwrap(sexp_cstrwrap_t *csw)
|
|
{
|
|
if(!csw) return;
|
|
|
|
if(csw->cc) destroy_continuation(csw->cc);
|
|
sexp_free(csw, sizeof(sexp_cstrwrap_t));
|
|
|
|
return;
|
|
}
|
|
|
|
static inline void __rnc_buf(sexp_cstrwrap_t *wr)
|
|
{
|
|
int sbuf_size = 0;
|
|
|
|
if(wr->sln - wr->cnt >= CSTRBUFSIZ) sbuf_size = CSTRBUFSIZ;
|
|
else sbuf_size = wr->sln - wr->cnt;
|
|
|
|
/*
|
|
* FIXME: is it ugly to copy?
|
|
* TODO: way to optimize is to modify a source string
|
|
* temproary - it's a way more worse
|
|
*/
|
|
memcpy(wr->buf, wr->seval + wr->cnt, sbuf_size);
|
|
wr->cnt += sbuf_size;
|
|
wr->rl = sbuf_size;
|
|
|
|
return;
|
|
}
|
|
|
|
sexp_t *get_one_sexp(sexp_cstrwrap_t *wr)
|
|
{
|
|
sexp_t *sx = NULL;
|
|
|
|
if(!wr) return NULL;
|
|
|
|
/* check for existing leftovers in continuation */
|
|
if(wr->cc && wr->cc->lastPos) {
|
|
wr->cc = cparse_sexp(wr->buf, wr->rl, wr->cc);
|
|
|
|
if(!wr->cc) return NULL; /* check the errno: it's set here */
|
|
if(wr->cc->last_sexp) {
|
|
sx = wr->cc->last_sexp;
|
|
wr->cc->last_sexp = NULL;
|
|
return sx;
|
|
}
|
|
wr->rl = 0;
|
|
}
|
|
|
|
if(wr->rl == 0) {
|
|
/* check for EOB */
|
|
if(wr->sln == wr->cnt) {
|
|
sexp_errno = SEXP_ERR_OK;
|
|
return NULL; /* we're done here */
|
|
}
|
|
|
|
__rnc_buf(wr);
|
|
}
|
|
|
|
wr->cc = cparse_sexp(wr->buf, wr->rl, wr->cc);
|
|
|
|
/* if expression more then buf size, read more */
|
|
while(wr->cc->last_sexp == NULL) {
|
|
if(wr->cc->error != SEXP_ERR_OK) {
|
|
sexp_errno = wr->cc->error;
|
|
return NULL;
|
|
}
|
|
|
|
/* check for EOB */
|
|
if(wr->sln == wr->cnt) {
|
|
sexp_errno = SEXP_ERR_IO_EMPTY;
|
|
return NULL; /* we're done here, s expression didn't finished */
|
|
}
|
|
|
|
__rnc_buf(wr);
|
|
|
|
wr->cc = cparse_sexp(wr->buf, wr->rl, wr->cc);
|
|
wr->rl = 0;
|
|
}
|
|
|
|
sx = wr->cc->last_sexp;
|
|
wr->cc->last_sexp = NULL;
|
|
|
|
return sx;
|
|
}
|