more
This commit is contained in:
parent
2f122529b0
commit
07e62d2057
@ -1,112 +0,0 @@
|
|||||||
/*
|
|
||||||
Author: José Bollo <jobol@nonadev.net>
|
|
||||||
Author: José Bollo <jose.bollo@iot.bzh>
|
|
||||||
|
|
||||||
https://gitlab.com/jobol/mustach
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _mustach_h_included_
|
|
||||||
#define _mustach_h_included_
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mustach_itf - interface for callbacks
|
|
||||||
*
|
|
||||||
* All of this function should return a negative value to stop
|
|
||||||
* the mustache processing. The returned negative value will be
|
|
||||||
* then returned to the caller of mustach as is.
|
|
||||||
*
|
|
||||||
* The functions enter and next should return 0 or 1.
|
|
||||||
*
|
|
||||||
* All other functions should normally return 0.
|
|
||||||
*
|
|
||||||
* @start: Starts the mustach processing of the closure
|
|
||||||
* 'start' is optional (can be NULL)
|
|
||||||
*
|
|
||||||
* @put: Writes the value of 'name' to 'file' with 'escape' or not
|
|
||||||
*
|
|
||||||
* @enter: Enters the section of 'name' if possible.
|
|
||||||
* Musts return 1 if entered or 0 if not entered.
|
|
||||||
* When 1 is returned, the function 'leave' will always be called.
|
|
||||||
* Conversely 'leave' is never called when enter returns 0 or
|
|
||||||
* a negative value.
|
|
||||||
* When 1 is returned, the function must activate the first
|
|
||||||
* item of the section.
|
|
||||||
*
|
|
||||||
* @next: Activates the next item of the section if it exists.
|
|
||||||
* Musts return 1 when the next item is activated.
|
|
||||||
* Musts return 0 when there is no item to activate.
|
|
||||||
*
|
|
||||||
* @leave: Leaves the last entered section
|
|
||||||
*/
|
|
||||||
struct mustach_itf {
|
|
||||||
int (*start)(void *closure);
|
|
||||||
int (*put)(void *closure, const char *name, int escape, FILE *file);
|
|
||||||
int (*enter)(void *closure, const char *name);
|
|
||||||
int (*next)(void *closure);
|
|
||||||
int (*leave)(void *closure);
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MUSTACH_OK 0
|
|
||||||
#define MUSTACH_ERROR_SYSTEM -1
|
|
||||||
#define MUSTACH_ERROR_UNEXPECTED_END -2
|
|
||||||
#define MUSTACH_ERROR_EMPTY_TAG -3
|
|
||||||
#define MUSTACH_ERROR_TAG_TOO_LONG -4
|
|
||||||
#define MUSTACH_ERROR_BAD_SEPARATORS -5
|
|
||||||
#define MUSTACH_ERROR_TOO_DEPTH -6
|
|
||||||
#define MUSTACH_ERROR_CLOSING -7
|
|
||||||
#define MUSTACH_ERROR_BAD_UNESCAPE_TAG -8
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fmustach - Renders the mustache 'template' in 'file' for 'itf' and 'closure'.
|
|
||||||
*
|
|
||||||
* @template: the template string to instanciate
|
|
||||||
* @itf: the interface to the functions that mustach calls
|
|
||||||
* @closure: the closure to pass to functions called
|
|
||||||
* @file: the file where to write the result
|
|
||||||
*
|
|
||||||
* Returns 0 in case of success, -1 with errno set in case of system error
|
|
||||||
* a other negative value in case of error.
|
|
||||||
*/
|
|
||||||
extern int fmustach(const char *template, struct mustach_itf *itf, void *closure, FILE *file);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fmustach - Renders the mustache 'template' in 'fd' for 'itf' and 'closure'.
|
|
||||||
*
|
|
||||||
* @template: the template string to instanciate
|
|
||||||
* @itf: the interface to the functions that mustach calls
|
|
||||||
* @closure: the closure to pass to functions called
|
|
||||||
* @fd: the file descriptor number where to write the result
|
|
||||||
*
|
|
||||||
* Returns 0 in case of success, -1 with errno set in case of system error
|
|
||||||
* a other negative value in case of error.
|
|
||||||
*/
|
|
||||||
extern int fdmustach(const char *template, struct mustach_itf *itf, void *closure, int fd);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fmustach - Renders the mustache 'template' in 'result' for 'itf' and 'closure'.
|
|
||||||
*
|
|
||||||
* @template: the template string to instanciate
|
|
||||||
* @itf: the interface to the functions that mustach calls
|
|
||||||
* @closure: the closure to pass to functions called
|
|
||||||
* @result: the pointer receiving the result when 0 is returned
|
|
||||||
* @size: the size of the returned result
|
|
||||||
*
|
|
||||||
* Returns 0 in case of success, -1 with errno set in case of system error
|
|
||||||
* a other negative value in case of error.
|
|
||||||
*/
|
|
||||||
extern int mustach(const char *template, struct mustach_itf *itf, void *closure, char **result, size_t *size);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -17,19 +17,23 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "mustach.h"
|
#include "mustache.hpp"
|
||||||
|
|
||||||
#define NAME_LENGTH_MAX 1024
|
#define NAME_LENGTH_MAX 1024
|
||||||
#define DEPTH_MAX 256
|
#define DEPTH_MAX 256
|
||||||
|
|
||||||
|
namespace nntpchan
|
||||||
|
{
|
||||||
|
namespace mustache
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
static int getpartial(struct mustach_itf *itf, void *closure, const char *name, char **result)
|
static int getpartial(struct mustach_itf *itf, void *closure, const char *name, char **result)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
@ -54,7 +58,7 @@ static int getpartial(struct mustach_itf *itf, void *closure, const char *name,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int process(const char *template, struct mustach_itf *itf, void *closure, FILE *file, const char *opstr, const char *clstr)
|
static int process(const char *templ, struct mustach_itf *itf, void *closure, FILE *file, const char *opstr, const char *clstr)
|
||||||
{
|
{
|
||||||
char name[NAME_LENGTH_MAX + 1], *partial, c;
|
char name[NAME_LENGTH_MAX + 1], *partial, c;
|
||||||
const char *beg, *term;
|
const char *beg, *term;
|
||||||
@ -67,20 +71,20 @@ static int process(const char *template, struct mustach_itf *itf, void *closure,
|
|||||||
cllen = strlen(clstr);
|
cllen = strlen(clstr);
|
||||||
depth = 0;
|
depth = 0;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
beg = strstr(template, opstr);
|
beg = strstr(templ, opstr);
|
||||||
if (beg == NULL) {
|
if (beg == NULL) {
|
||||||
/* no more mustach */
|
/* no more mustach */
|
||||||
if (emit)
|
if (emit)
|
||||||
fwrite(template, strlen(template), 1, file);
|
fwrite(templ, strlen(templ), 1, file);
|
||||||
return depth ? MUSTACH_ERROR_UNEXPECTED_END : 0;
|
return depth ? MUSTACH_ERROR_UNEXPECTED_END : 0;
|
||||||
}
|
}
|
||||||
if (emit)
|
if (emit)
|
||||||
fwrite(template, (size_t)(beg - template), 1, file);
|
fwrite(templ, (size_t)(beg - templ), 1, file);
|
||||||
beg += oplen;
|
beg += oplen;
|
||||||
term = strstr(beg, clstr);
|
term = strstr(beg, clstr);
|
||||||
if (term == NULL)
|
if (term == NULL)
|
||||||
return MUSTACH_ERROR_UNEXPECTED_END;
|
return MUSTACH_ERROR_UNEXPECTED_END;
|
||||||
template = term + cllen;
|
templ = term + cllen;
|
||||||
len = (size_t)(term - beg);
|
len = (size_t)(term - beg);
|
||||||
c = *beg;
|
c = *beg;
|
||||||
switch(c) {
|
switch(c) {
|
||||||
@ -96,7 +100,7 @@ static int process(const char *template, struct mustach_itf *itf, void *closure,
|
|||||||
} else {
|
} else {
|
||||||
if (term[l] != '}')
|
if (term[l] != '}')
|
||||||
return MUSTACH_ERROR_BAD_UNESCAPE_TAG;
|
return MUSTACH_ERROR_BAD_UNESCAPE_TAG;
|
||||||
template++;
|
templ++;
|
||||||
}
|
}
|
||||||
c = '&';
|
c = '&';
|
||||||
case '^':
|
case '^':
|
||||||
@ -153,7 +157,7 @@ static int process(const char *template, struct mustach_itf *itf, void *closure,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
stack[depth].name = beg;
|
stack[depth].name = beg;
|
||||||
stack[depth].again = template;
|
stack[depth].again = templ;
|
||||||
stack[depth].length = len;
|
stack[depth].length = len;
|
||||||
stack[depth].emit = emit;
|
stack[depth].emit = emit;
|
||||||
stack[depth].entered = rc;
|
stack[depth].entered = rc;
|
||||||
@ -169,7 +173,7 @@ static int process(const char *template, struct mustach_itf *itf, void *closure,
|
|||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
if (rc) {
|
if (rc) {
|
||||||
template = stack[depth++].again;
|
templ = stack[depth++].again;
|
||||||
} else {
|
} else {
|
||||||
emit = stack[depth].emit;
|
emit = stack[depth].emit;
|
||||||
if (emit && stack[depth].entered)
|
if (emit && stack[depth].entered)
|
||||||
@ -200,15 +204,15 @@ static int process(const char *template, struct mustach_itf *itf, void *closure,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int fmustach(const char *template, struct mustach_itf *itf, void *closure, FILE *file)
|
int fmustach(const char *templ, struct mustach_itf *itf, void *closure, FILE *file)
|
||||||
{
|
{
|
||||||
int rc = itf->start ? itf->start(closure) : 0;
|
int rc = itf->start ? itf->start(closure) : 0;
|
||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
rc = process(template, itf, closure, file, "{{", "}}");
|
rc = process(templ, itf, closure, file, "{{", "}}");
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fdmustach(const char *template, struct mustach_itf *itf, void *closure, int fd)
|
int fdmustach(const char *templ, struct mustach_itf *itf, void *closure, int fd)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
FILE *file;
|
FILE *file;
|
||||||
@ -218,13 +222,13 @@ int fdmustach(const char *template, struct mustach_itf *itf, void *closure, int
|
|||||||
rc = MUSTACH_ERROR_SYSTEM;
|
rc = MUSTACH_ERROR_SYSTEM;
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
} else {
|
} else {
|
||||||
rc = fmustach(template, itf, closure, file);
|
rc = fmustach(templ, itf, closure, file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mustach(const char *template, struct mustach_itf *itf, void *closure, char **result, size_t *size)
|
int mustach(const char *templ, struct mustach_itf *itf, void *closure, char **result, size_t *size)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
FILE *file;
|
FILE *file;
|
||||||
@ -238,7 +242,7 @@ int mustach(const char *template, struct mustach_itf *itf, void *closure, char *
|
|||||||
rc = MUSTACH_ERROR_SYSTEM;
|
rc = MUSTACH_ERROR_SYSTEM;
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
} else {
|
} else {
|
||||||
rc = fmustach(template, itf, closure, file);
|
rc = fmustach(templ, itf, closure, file);
|
||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
/* adds terminating null */
|
/* adds terminating null */
|
||||||
rc = fputc(0, file) ? MUSTACH_ERROR_SYSTEM : 0;
|
rc = fputc(0, file) ? MUSTACH_ERROR_SYSTEM : 0;
|
||||||
@ -254,4 +258,5 @@ int mustach(const char *template, struct mustach_itf *itf, void *closure, char *
|
|||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
96
contrib/backends/nntpchan-daemon/src/mustache.hpp
Normal file
96
contrib/backends/nntpchan-daemon/src/mustache.hpp
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
#ifndef NNTPCHAN_MUSTACHE
|
||||||
|
#define NNTPCHAN_MUSTACHE
|
||||||
|
|
||||||
|
/*
|
||||||
|
Author: José Bollo <jobol@nonadev.net>
|
||||||
|
Author: José Bollo <jose.bollo@iot.bzh>
|
||||||
|
|
||||||
|
https://gitlab.com/jobol/mustach
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define MUSTACH_OK 0
|
||||||
|
#define MUSTACH_ERROR_SYSTEM -1
|
||||||
|
#define MUSTACH_ERROR_UNEXPECTED_END -2
|
||||||
|
#define MUSTACH_ERROR_EMPTY_TAG -3
|
||||||
|
#define MUSTACH_ERROR_TAG_TOO_LONG -4
|
||||||
|
#define MUSTACH_ERROR_BAD_SEPARATORS -5
|
||||||
|
#define MUSTACH_ERROR_TOO_DEPTH -6
|
||||||
|
#define MUSTACH_ERROR_CLOSING -7
|
||||||
|
#define MUSTACH_ERROR_BAD_UNESCAPE_TAG -8
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
|
||||||
|
namespace nntpchan
|
||||||
|
{
|
||||||
|
namespace mustache
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mustach_itf - interface for callbacks
|
||||||
|
*
|
||||||
|
* All of this function should return a negative value to stop
|
||||||
|
* the mustache processing. The returned negative value will be
|
||||||
|
* then returned to the caller of mustach as is.
|
||||||
|
*
|
||||||
|
* The functions enter and next should return 0 or 1.
|
||||||
|
*
|
||||||
|
* All other functions should normally return 0.
|
||||||
|
*
|
||||||
|
* @start: Starts the mustach processing of the closure
|
||||||
|
* 'start' is optional (can be NULL)
|
||||||
|
*
|
||||||
|
* @put: Writes the value of 'name' to 'file' with 'escape' or not
|
||||||
|
*
|
||||||
|
* @enter: Enters the section of 'name' if possible.
|
||||||
|
* Musts return 1 if entered or 0 if not entered.
|
||||||
|
* When 1 is returned, the function 'leave' will always be called.
|
||||||
|
* Conversely 'leave' is never called when enter returns 0 or
|
||||||
|
* a negative value.
|
||||||
|
* When 1 is returned, the function must activate the first
|
||||||
|
* item of the section.
|
||||||
|
*
|
||||||
|
* @next: Activates the next item of the section if it exists.
|
||||||
|
* Musts return 1 when the next item is activated.
|
||||||
|
* Musts return 0 when there is no item to activate.
|
||||||
|
*
|
||||||
|
* @leave: Leaves the last entered section
|
||||||
|
*/
|
||||||
|
struct mustach_itf {
|
||||||
|
int (*start)(void *closure);
|
||||||
|
int (*put)(void *closure, const char *name, int escape, FILE *file);
|
||||||
|
int (*enter)(void *closure, const char *name);
|
||||||
|
int (*next)(void *closure);
|
||||||
|
int (*leave)(void *closure);
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* fmustach - Renders the mustache 'template' in 'file' for 'itf' and 'closure'.
|
||||||
|
*
|
||||||
|
* @template: the template string to instanciate
|
||||||
|
* @itf: the interface to the functions that mustach calls
|
||||||
|
* @closure: the closure to pass to functions called
|
||||||
|
* @file: the file where to write the result
|
||||||
|
*
|
||||||
|
* Returns 0 in case of success, -1 with errno set in case of system error
|
||||||
|
* a other negative value in case of error.
|
||||||
|
*/
|
||||||
|
int fmustach(const char *templ, struct mustach_itf *itf, void *closure, FILE *file);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue
Block a user