File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libpdel / tmpl / tmpl_internal.h
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 23:25:53 2012 UTC (12 years, 3 months ago) by misho
Branches: libpdel, MAIN
CVS tags: v0_5_3, HEAD
libpdel


/*
 * Copyright (c) 2001-2002 Packet Design, LLC.
 * All rights reserved.
 * 
 * Subject to the following obligations and disclaimer of warranty,
 * use and redistribution of this software, in source or object code
 * forms, with or without modifications are expressly permitted by
 * Packet Design; provided, however, that:
 * 
 *    (i)  Any and all reproductions of the source or object code
 *         must include the copyright notice above and the following
 *         disclaimer of warranties; and
 *    (ii) No rights are granted, in any manner or form, to use
 *         Packet Design trademarks, including the mark "PACKET DESIGN"
 *         on advertising, endorsements, or otherwise except as such
 *         appears in the above copyright notice or in the software.
 * 
 * THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
 * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
 * THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
 * OR NON-INFRINGEMENT.  PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
 * OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
 * OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
 * RELIABILITY OR OTHERWISE.  IN NO EVENT SHALL PACKET DESIGN BE
 * LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
 * OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
 * DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
 * USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
 * THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Author: Archie Cobbs <archie@freebsd.org>
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <assert.h>
#include <limits.h>
#include <fcntl.h>
#include <ctype.h>
#include <errno.h>
#include <paths.h>
#include <unistd.h>
#include <pthread.h>

#include "structs/structs.h"
#include "structs/type/array.h"

#include "tmpl/tmpl.h"
#include "io/string_fp.h"
#include "util/typed_mem.h"
#include "util/string_quote.h"

#ifndef TMPL_DEBUG
#define TMPL_DEBUG	0
#endif
#if TMPL_DEBUG != 0 && defined(__GNUC__)
#define DBG(fmt, args...)       \
	do { fprintf(stderr, fmt , ## args); } while(0)
#else
#define DBG(fmt, args...)       do { } while (0)
#endif

/* How much nesting is too much */
#define INFINITE_LOOP		128

/* Function types */
enum func_type {
	TY_NORMAL,
	TY_LOOP,
	TY_ENDLOOP,
	TY_WHILE,
	TY_ENDWHILE,
	TY_IF,
	TY_ELIF,
	TY_ELSE,
	TY_ENDIF,
	TY_DEFINE,
	TY_ENDDEF,
	TY_BREAK,
	TY_CONTINUE,
	TY_RETURN
};

/* Return values from _tmpl_execute_elems() */
enum exec_rtn {
	RTN_NORMAL,
	RTN_BREAK,
	RTN_CONTINUE,
	RTN_RETURN
};

/* Template element flags */
#define TMPL_ELEM_NL_WHITE	0x0001			/* text is nl+space */
#define TMPL_ELEM_MMAP_TEXT	0x0002			/* text is mmap()'d */

/* Function call */
struct func_call {
	enum func_type	type;				/* type of function */
	char		*funcname;			/* name of function */
	int		nargs;				/* number of args */
	struct func_arg	*args;				/* function arguments */
	tmpl_handler_t	*handler;			/* built-in: handler */
};

/* Function argument */
struct func_arg {
	u_char		is_literal;			/* literal vs. func */
	union {
	    struct func_call	call;			/* function call */
	    char 		*literal;		/* literal string */
	}		u;
};

/* This represents one parsed chunk of the template */
struct tmpl_elem {

	/* Lexical information */
	char			*text;		/* text, or NULL if function */
	u_int			len;		/* length of text */
	u_int16_t		flags;		/* element flags */

	/* Semantic information */
	struct func_call	call;		/* function and arguments */
	union {
	    struct {
		int			endloop;/* endloop element */
	    }			u_loop;		/* TY_LOOP */
	    struct {
		int			endwhile;/* endwhile element */
	    }			u_while;	/* TY_WHILE */
	    struct {
		int			elsie;	/* else element, or -1 */
		int			endif;	/* endif element */
	    }			u_if;		/* TY_IF */
	    struct {
		int			enddef;	/* enddef element */
	    }			u_define;	/* TY_DEFINE */
	}		u;
};

/* Run-time variables */
struct exec_var {
	char	*name;				/* variable name */
	char	*value;				/* variable value */
};

/* Run-time functions */
struct exec_func {
	char			*name;		/* function name */
	int			num_elems;	/* number of elements */
	struct tmpl_elem	*elems;		/* function elements */
	void			*eblock;	/* unified memory block */
};

/* Looping info */
struct loop_ctx {
	u_int			index;		/* current loop index */
	struct loop_ctx		*outer;		/* enclosing loop info */
};

/* Parsed template file */
struct tmpl {
	void			*mmap_addr;	/* mmap() address, or NULL */
	size_t			mmap_len;	/* mmap() length */
	int			num_elems;	/* number of parsed elements */
	struct tmpl_elem	*elems;		/* parsed template elements */
	void			*eblock;	/* unified memory block */
	char			*mtype;		/* memory type */
	char			mtype_buf[TYPED_MEM_TYPELEN];
};

/* Template context */
struct tmpl_ctx {
	FILE			*output;	/* current output */
	FILE			*orig_output;	/* original output */
	int			flags;		/* flags */
	u_char			close_output;	/* close 'output' when done */
	int			depth;		/* execution nesting level */
	void			*arg;		/* user function cookie */
	tmpl_handler_t		*handler;	/* user function handler */
	tmpl_errfmtr_t		*errfmtr;	/* user error formatter */
	struct loop_ctx		*loop;		/* innermost loop, if any */
	int			num_vars;	/* number of variables */
	struct exec_var		*vars;		/* runtime variables */
	int			num_funcs;	/* number of functions */
	struct exec_func	*funcs;		/* runtime functions */
	char			*mtype;		/* memory type */
	char			mtype_buf[TYPED_MEM_TYPELEN];
};

/*
 * Functions
 */

__BEGIN_DECLS

/* Parsing */
extern int	_tmpl_parse(struct tmpl *tmpl, FILE *input, int *num_errors);

/* Variable and function handling */
extern int	_tmpl_find_var(struct tmpl_ctx *ctx, const char *name);
extern int	_tmpl_find_func(struct tmpl_ctx *ctx, const char *name);
extern int	_tmpl_set_func(struct tmpl_ctx *ctx, const char *name,
			const struct tmpl_elem *elems, int count);

/* Memory management */
extern void	_tmpl_compact_elems(const char *mtype,
			struct tmpl_elem *elems, int num_elems,
			char *mem, size_t *bsize);
extern void	_tmpl_compact(const char *mtype, char *mem,
			void *ptrp, size_t len, size_t *bsize);
extern void	_tmpl_free_func(struct tmpl_ctx *ctx, struct exec_func *func);
extern void	_tmpl_free_elems(const char *mtype, void *eblock,
			struct tmpl_elem *elems, int num);
extern void	_tmpl_free_call(const char *mtype, struct func_call *call);
extern void	_tmpl_free_arg(const char *mtype, struct func_arg *arg);

/* Template execution */
extern enum	exec_rtn _tmpl_execute_elems(struct tmpl_ctx *ctx,
			struct tmpl_elem *elems, int first_elem, int last_elem);
extern char	*_tmpl_invoke(struct tmpl_ctx *ctx,
			char **errmsgp, const struct func_call *call);

/* Truth determination */
extern int	_tmpl_true(const char *s);

#if TMPL_DEBUG
/* Debugging */
extern const	char *_tmpl_elemstr(const struct tmpl_elem *elem, int index);
#endif

__END_DECLS


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>