*** /dev/null Sat Nov 23 01:11:00 2024
--- - Sat Nov 23 01:11:09 2024
***************
*** 0 ****
--- 1,202 ----
+ %{
+ /*
+ ** L2 - OSSP Logging Library
+ ** Copyright (c) 2001 The OSSP Project (http://www.ossp.org/)
+ ** Copyright (c) 2001 Cable & Wireless Deutschland (http://www.cw.com/de/)
+ **
+ ** This file is part of OSSP L2, a flexible logging library which
+ ** can be found at http://www.ossp.org/pkg/l2/.
+ **
+ ** Permission to use, copy, modify, and distribute this software for
+ ** any purpose with or without fee is hereby granted, provided that
+ ** the above copyright notice and this permission notice appear in all
+ ** copies.
+ **
+ ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+ ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ** ON 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 ADVISED OF THE POSSIBILITY OF
+ ** SUCH DAMAGE.
+ **
+ ** l2_spec_parse.y: GNU Bison (Yacc-style) parser specification
+ **
+ ** ATTENTION: This requires GNU Bison 1.30 or newer!
+ */
+
+ #include "l2.h" /* for l2_xxx() */
+ #include "l2_p.h" /* for l2_channel_t and l2_env_t internals */
+ #include "l2_spec.h" /* for l2_spec_ctx_t */
+
+ /* make sure yyparse() accepts a context pointer and
+ passes through its inlined scanner context to yylex() */
+ #define CTX ((l2_spec_ctx_t *)ctx)
+ #define YYPARSE_PARAM ctx
+ #define YYLEX_PARAM CTX->yyscan
+
+ /* provide an explicit prototype for the yylex() function */
+ extern int yylex(/*YYSTYPE*/ void *lvalp,
+ /*YYLTYPE*/ void *llocp, l2_spec_ctx_t *ctx);
+
+ /* generate verbose error messages and remember them inside the context */
+ #undef yyerror
+ #define yyerror(msg) \
+ do { \
+ l2_env_errorinfo(CTX->env, L2_ERR_ARG, "%s", msg); \
+ CTX->rv = L2_ERR_ARG; \
+ } while (0)
+ #define YYERROR_VERBOSE
+
+ #define YYDEBUG 1
+ %}
+
+ %pure_parser
+ %locations
+ %defines
+
+ %union {
+ char *cpValue;
+ l2_channel_t *chChannel;
+ unsigned int nLevels;
+ }
+
+ %type <chChannel> stream
+ %type <chChannel> streams
+ %type <chChannel> channel
+ %type <chChannel> channel_spec
+ %type <nLevels> channel_mask
+ %type <nLevels> channel_levels
+
+ %token <cpValue> T_ID
+ %token <cpValue> T_STRING
+
+ %token T_OP_ARROW
+ %left T_OP_ARROW
+
+ %%
+
+ root : stream
+ { CTX->ch = $1; }
+ ;
+
+ stream : channel
+ {
+ $$ = $1;
+ }
+ | channel T_OP_ARROW stream
+ {
+ $$ = $1;
+ if ((CTX->rv = l2_channel_link($1, L2_LINK_CHILD, $3, NULL)) != L2_OK) {
+ l2_env_errorinfo(CTX->env, CTX->rv,
+ "unable to link parent '%s' with child '%s'",
+ $1->handler.name, $3->handler.name);
+ YYERROR;
+ }
+ }
+ | channel T_OP_ARROW '{' streams '}'
+ {
+ $$ = $1;
+ if ((CTX->rv = l2_channel_link($1, L2_LINK_CHILD, $4, NULL)) != L2_OK) {
+ l2_env_errorinfo(CTX->env, CTX->rv,
+ "unable to link parent '%s' with child list",
+ $1->handler.name);
+ YYERROR;
+ }
+ }
+ ;
+
+ streams : stream
+ { $$ = $1; }
+ | stream ';' streams
+ { $$ = $1; l2_channel_link($1, L2_LINK_SIBLING, $3, NULL); }
+ ;
+
+ channel : channel_mask '/' channel_mask ':' channel_spec
+ { $$ = $5; l2_channel_levels($5, $1, $3); }
+ | channel_mask ':' channel_spec
+ { $$ = $3; l2_channel_levels($3, $1, L2_LEVEL_NONE); }
+ | channel_spec
+ { $$ = $1; }
+ ;
+
+ channel_mask : T_ID
+ {
+ unsigned int levelmask;
+ if ((CTX->rv = l2_util_s2l($1, strlen($1), ',', &levelmask)) != L2_OK) {
+ l2_env_errorinfo(CTX->env, CTX->rv, "invalid level '%s'", $1);
+ YYERROR;
+ }
+ $$ = L2_LEVEL_UPTO(levelmask);
+ }
+ | '(' channel_levels ')'
+ { $$ = $2; }
+ ;
+
+ channel_levels : T_ID
+ {
+ unsigned int levelmask;
+ if ((CTX->rv = l2_util_s2l($1, strlen($1), ',', &levelmask)) != L2_OK) {
+ l2_env_errorinfo(CTX->env, CTX->rv, "invalid level '%s'", $1);
+ YYERROR;
+ }
+ $$ = levelmask;
+ }
+ | T_ID '|' channel_levels
+ {
+ unsigned int levelmask;
+ if ((CTX->rv = l2_util_s2l($1, strlen($1), ',', &levelmask)) != L2_OK) {
+ l2_env_errorinfo(CTX->env, CTX->rv, "invalid level '%s'", $1);
+ YYERROR;
+ }
+ $$ = levelmask | $3;
+ }
+ ;
+
+ channel_spec : T_ID
+ {
+ l2_channel_t *ch;
+ if ((CTX->rv = l2_channel_create(&ch, CTX->env, $1)) != L2_OK) {
+ l2_env_errorinfo(CTX->env, CTX->rv, "failed to create channel '%s'", $1);
+ YYERROR;
+ }
+ $$ = ch;
+ /* provide channel to channel_param rule below
+ because it does not know where on the token stack
+ our $$ is because it is a sub-rule of the recursive
+ channel_param_list rule and hence cannot use
+ "$<chChannel>-n". */
+ CTX->chTmp = ch;
+ }
+ channel_params
+ {
+ $$ = $<chChannel>2;
+ CTX->chTmp = NULL;
+ }
+ ;
+
+ channel_params : /* empty */
+ | '(' channel_param_list ')'
+ ;
+
+ channel_param_list : /* empty */
+ | channel_param
+ | channel_param ',' channel_param_list
+ ;
+
+ channel_param : T_ID '=' T_STRING
+ {
+ if ((CTX->rv = l2_channel_configure(CTX->chTmp, "%s=\"%s\"", $1, $3)) != L2_OK) {
+ l2_env_errorinfo(CTX->env, CTX->rv, "failed to configure channel with '%s=\"%s\"'", $1, $3);
+ YYERROR;
+ }
+ }
+ ;
+
+ %%
+
|