%{
/*
- * ctf-parser.y
- *
- * Common Trace Format Metadata Grammar.
+ * SPDX-License-Identifier: MIT
*
* Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Common Trace Format Metadata Grammar.
*/
#define BT_LOG_OUTPUT_LEVEL ctf_plugin_metadata_log_level
#include "common/list.h"
#include "common/assert.h"
#include "scanner.h"
-#include "parser.h"
#include "ast.h"
#include "objstack.h"
-#if BT_LOG_ENABLED_VERBOSE
-# define YYDEBUG 1
-# define YYFPRINTF(_stream, _fmt, args...) BT_LOGV(_fmt, ## args)
-#else
-# define YYDEBUG 0
-#endif
+#include "parser-wrap.h"
/* Join two lists, put "add" at the end of "head". */
static inline void
}
}
-BT_HIDDEN
-int yyparse(struct ctf_scanner *scanner, yyscan_t yyscanner);
BT_HIDDEN
int yylex(union YYSTYPE *yyval, yyscan_t yyscanner);
BT_HIDDEN
return -1;
}
}
- BT_ASSERT(nr_char > 0);
+ BT_ASSERT_DBG(nr_char > 0);
buffer[nr_char] = '\0';
*buf_len = nr_char;
return 0;
lvalp->s = objstack_alloc(scanner->objstack, len);
if (src[0] == 'L') {
// TODO: import wide string
- _BT_LOGE_LINENO(yyget_lineno(scanner),
+ _BT_LOGE_APPEND_CAUSE_LINENO(yyget_lineno(scanner),
"wide characters are not supported as of this version: "
"scanner-addr=%p", scanner);
return -1;
{
struct ctf_scanner_scope *ns;
- BT_LOGV("Pushing scope: scanner-addr=%p", scanner);
+ BT_LOGT("Pushing scope: scanner-addr=%p", scanner);
ns = malloc(sizeof(struct ctf_scanner_scope));
init_scope(ns, scanner->cs);
scanner->cs = ns;
{
struct ctf_scanner_scope *os;
- BT_LOGV("Popping scope: scanner-addr=%p", scanner);
+ BT_LOGT("Popping scope: scanner-addr=%p", scanner);
os = scanner->cs;
scanner->cs = os->parent;
finalize_scope(os);
int ret;
ret = GPOINTER_TO_INT(g_hash_table_lookup(s->classes, id));
- BT_LOGV("Looked up type: scanner-addr=%p, id=\"%s\", ret=%d",
+ BT_LOGT("Looked up type: scanner-addr=%p, id=\"%s\", ret=%d",
s, id, ret);
return ret;
}
struct ctf_scanner_scope *it;
int ret = 0;
- for (it = scanner->cs; it != NULL; it = it->parent) {
+ for (it = scanner->cs; it; it = it->parent) {
if (lookup_type(it, id)) {
ret = 1;
break;
}
}
- BT_LOGV("Found if ID is type: scanner-addr=%p, id=\"%s\", ret=%d",
+ BT_LOGT("Found if ID is type: scanner-addr=%p, id=\"%s\", ret=%d",
scanner, id, ret);
return ret;
}
static void add_type(struct ctf_scanner *scanner, char *id)
{
- BT_LOGV("Adding type: scanner-addr=%p, id=\"%s\"",
+ BT_LOGT("Adding type: scanner-addr=%p, id=\"%s\"",
scanner, id);
if (lookup_type(scanner->cs, id))
return;
node = objstack_alloc(scanner->objstack, sizeof(*node));
if (!node) {
- _BT_LOGE_LINENO(yyget_lineno(scanner->scanner),
+ _BT_LOGE_APPEND_CAUSE_LINENO(yyget_lineno(scanner->scanner),
"failed to allocate one stack entry: "
"scanner-addr=%p", scanner);
return &error_node;
return 0;
}
-BT_HIDDEN
+static
void yyerror(struct ctf_scanner *scanner, yyscan_t yyscanner, const char *str)
{
- _BT_LOGE_LINENO(yyget_lineno(scanner->scanner),
+ _BT_LOGE_APPEND_CAUSE_LINENO(yyget_lineno(scanner->scanner),
"%s: token=\"%s\"", str, yyget_text(scanner->scanner));
}
-BT_HIDDEN
-int yywrap(void)
-{
- return 1;
-}
-
#define reparent_error(scanner, str) \
do { \
yyerror(scanner, scanner->scanner, YY_("reparent_error: " str)); \
if (!scanner)
return;
- finalize_scope(&scanner->root_scope);
+
+ struct ctf_scanner_scope *scope = scanner->cs;
+
+ do {
+ struct ctf_scanner_scope *parent = scope->parent;
+ finalize_scope(scope);
+
+ /*
+ * The root scope is allocated within the ctf_scanner structure,
+ * do doesn't need freeing. All others are allocated on their
+ * own.
+ */
+ if (scope != &scanner->root_scope)
+ free(scope);
+
+ scope = parent;
+ } while (scope);
+
objstack_destroy(scanner->objstack);
ret = yylex_destroy(scanner->scanner);
if (ret)
free(scanner);
}
+/*
+ * The bison-provided version of strlen (yystrlen) generates a benign
+ * -Wnull-dereference warning. That version is used when building on cygwin,
+ * for example, but you can also enable it by hand (to test) by removing the
+ * preprocessor conditional around it.
+ *
+ * Define yystrlen such that it will always use strlen. As far as we know,
+ * strlen provided by all the platforms we use is reliable.
+ */
+#define yystrlen strlen
+
%}
+/*
+ * This ends up in parser.h and makes sure those who want to include it pass
+ * through parser-wrap.h.
+ */
+%code requires {
+#ifndef ALLOW_INCLUDE_PARSER_H
+# error "Don't include parser.h directly, include parser-wrap.h instead."
+#endif
+}
+
+%code provides {
+ BT_HIDDEN
+ void setstring(struct ctf_scanner *scanner, YYSTYPE *lvalp, const char *src);
+
+ BT_HIDDEN
+ int import_string(struct ctf_scanner *scanner, YYSTYPE *lvalp, const char *src, char delim);
+}
+
%define api.pure
/* %locations */
%error-verbose
$$->u.unary_expression.type = UNARY_SIGNED_CONSTANT;
$$->u.unary_expression.u.signed_constant =
-($$->u.unary_expression.u.unsigned_constant);
- } else if ($$->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT) {
+ } else if ($$->u.unary_expression.type == UNARY_SIGNED_CONSTANT) {
$$->u.unary_expression.u.signed_constant =
-($$->u.unary_expression.u.signed_constant);
} else {