Add CTF metadata lexer/parser (lex/yacc)
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 7 Feb 2011 01:02:38 +0000 (20:02 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 7 Feb 2011 01:02:38 +0000 (20:02 -0500)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
configure.ac
formats/ctf/Makefile.am
formats/ctf/metadata/Makefile.am [new file with mode: 0644]
formats/ctf/metadata/ctf-ast.h [new file with mode: 0644]
formats/ctf/metadata/ctf-lexer.l [new file with mode: 0644]
formats/ctf/metadata/ctf-parser.y [new file with mode: 0644]
formats/ctf/metadata/ctf-test.txt [new file with mode: 0644]
include/helpers/list.h [new file with mode: 0644]

index 2a153583add1adec979fa80df14b6422d8092c79..1f1d28449f9865399f49f94998d43ca93873d85c 100644 (file)
@@ -18,6 +18,8 @@ AC_CONFIG_HEADERS([config.h])
 AC_PROG_CC
 AC_PROG_MAKE_SET
 AC_PROG_LIBTOOL
+AC_PROG_YACC
+AC_PROG_LEX
 
 AM_PATH_GLIB_2_0(2.4.0, ,AC_MSG_ERROR([glib is required in order to compile BabelTrace - download it from ftp://ftp.gtk.org/pub/gtk]) , gmodule)
 
@@ -44,6 +46,7 @@ AC_CONFIG_FILES([
        formats/Makefile
        formats/ctf/Makefile
        formats/ctf/types/Makefile
+       formats/ctf/metadata/Makefile
        converter/Makefile
        tests/Makefile
 ])
index ba0a4f79404b06fb22f72145bfdf78f0a23cbe78..a20d7c4aeb037a8f8e67a901498ee967d709f457 100644 (file)
@@ -1,11 +1,10 @@
 AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
 
-SUBDIRS = . types
-#metadata
+SUBDIRS = . types metadata
 
 lib_LTLIBRARIES = libctf.la
 
 libctf_la_SOURCES = \
        ctf.c \
-       types/ctf_types.o
-#      metadata/ctf_parse.o
+       types/libctf-types.a
+       metadata/libctf-parser.a
diff --git a/formats/ctf/metadata/Makefile.am b/formats/ctf/metadata/Makefile.am
new file mode 100644 (file)
index 0000000..fac978c
--- /dev/null
@@ -0,0 +1,7 @@
+AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
+BUILT_SOURCES = ctf-parser.h
+AM_YFLAGS = -t -d
+
+noinst_LIBRARIES = libctf-parser.a
+
+libctf_parser_a_SOURCES = ctf-lexer.l ctf-parser.y
diff --git a/formats/ctf/metadata/ctf-ast.h b/formats/ctf/metadata/ctf-ast.h
new file mode 100644 (file)
index 0000000..b839b2c
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef _CTF_PARSER_H
+#define _CTF_PARSER_H
+
+#include <helpers/list.h>
+
+enum node_type {
+       NODE_UNKNOWN,
+       NODE_ROOT,
+       NODE_EVENT,
+       NODE_STREAM,
+       NODE_TYPE,
+       NODE_TRACE,
+
+       NR_NODE_TYPES,
+};
+
+struct ctf_node;
+
+struct ctf_node {
+       enum node_type type;
+       char *str;
+       long long ll;
+       struct ctf_node *parent;
+       char *ident;
+       struct cds_list_head siblings;
+       struct cds_list_head children;
+       struct cds_list_head gc;
+};
+
+int is_type(const char *id);
+
+#endif /* _CTF_PARSER_H */
diff --git a/formats/ctf/metadata/ctf-lexer.l b/formats/ctf/metadata/ctf-lexer.l
new file mode 100644 (file)
index 0000000..763a1bb
--- /dev/null
@@ -0,0 +1,98 @@
+%{
+#include <stdio.h>
+#include "ctf-parser.h"
+#include "ctf-ast.h"
+
+extern YYSTYPE yylval;
+extern void setstring(const char *src);
+%}
+
+%x comment_ml comment_sl string_lit char_const
+INTEGER_SUFFIX                 [ \n\t]*(U|UL|ULL|LU|LLU|Ul|Ull|lU|llU|u|uL|uLL|Lu|LLu|ul|ull|lu|llu)
+DIGIT                          [0-9]
+NONDIGIT                       [a-zA-Z_]
+HEXDIGIT                       [0-9A-Fa-f]
+OCTALDIGIT                     [0-7]
+UCHARLOWERCASE                 \\u{HEXDIGIT}{4}
+UCHARUPPERCASE                 \\U{HEXDIGIT}{8}
+ID_NONDIGIT                    {NONDIGIT}|{UCHARLOWERCASE}|{UCHARUPPERCASE}
+IDENTIFIER                     {ID_NONDIGIT}({ID_NONDIGIT}|{DIGIT})*
+ESCSEQ                         \\(\'|\"|\?|\\|a|b|f|n|r|t|v|{OCTALDIGIT}{1,3}|u{HEXDIGIT}{4}|U{HEXDIGIT}{8}|x{HEXDIGIT}+)
+%%
+
+                               /*
+                                * Using start conditions to deal with comments
+                                * and strings.
+                                */ 
+
+"/*"                           BEGIN(comment_ml);
+<comment_ml>[^*\n]*            /* eat anything that's not a '*' */
+<comment_ml>"*"+[^*/\n]*       /* eat up '*'s not followed by '/'s */
+<comment_ml>\n                 ++yylineno;
+<comment_ml>"*"+"/"            BEGIN(INITIAL);
+
+"//"                           BEGIN(comment_sl);
+<comment_sl>[^\n]*\n           ++yylineno; BEGIN(INITIAL);
+
+L\'                            BEGIN(char_const); return CHARACTER_CONSTANT_START;
+\'                             BEGIN(char_const); return CHARACTER_CONSTANT_START;
+<char_const>\'                 BEGIN(INITIAL); return SQUOTE;
+
+L\"                            BEGIN(string_lit); return STRING_LITERAL_START;
+\"                             BEGIN(string_lit); return STRING_LITERAL_START;
+<string_lit>\"                 BEGIN(INITIAL); return DQUOTE;
+
+<char_const,string_lit>ESCSEQ  return ESCSEQ;
+<char_const,string_lit>\n      ; /* ignore */
+<char_const,string_lit>.       return CHAR_STRING_TOKEN;
+
+"["                            return LSBRAC;
+"]"                            return RSBRAC;
+"("                            return LPAREN;
+")"                            return RPAREN;
+"{"                            return LBRAC;
+"}"                            return RBRAC;
+"->"                           return RARROW;
+"*"                            return STAR;
+"+"                            return PLUS;
+"-"                            return MINUS;
+"<"                            return LT;
+">"                            return GT;
+:=                             return TYPEASSIGN;
+:                              return COLON;
+;                              return SEMICOLON;
+"..."                          return DOTDOTDOT;
+"."                            return DOT;
+=                              return EQUAL;
+","                            return COMMA;
+const                          return CONST;
+char                           return CHAR;
+double                         return DOUBLE;
+enum                           return ENUM;
+event                          return EVENT;
+floating_point                 return FLOATING_POINT;
+float                          return FLOAT;
+integer                                return INTEGER;
+int                            return INT;
+long                           return LONG;
+short                          return SHORT;
+signed                         return SIGNED;
+stream                         return STREAM;
+string                         return STRING;
+struct                         return STRUCT;
+trace                          return TRACE;
+typealias                      return TYPEALIAS;
+typedef                                return TYPEDEF;
+unsigned                       return UNSIGNED;
+variant                                return VARIANT;
+void                           return VOID;
+_Bool                          return _BOOL;
+_Complex                       return _COMPLEX;
+_Imaginary                     return _IMAGINARY;
+[1-9]{DIGIT}*{INTEGER_SUFFIX}? return DECIMAL_CONSTANT;
+0{OCTALDIGIT}*{INTEGER_SUFFIX}?        return OCTAL_CONSTANT;
+0[xX]{HEXDIGIT}+{INTEGER_SUFFIX}?      return HEXADECIMAL_CONSTANT;
+{IDENTIFIER}                   fprintf(stderr, "<IDENTIFIER %s>\n", yytext); setstring(yytext); if (is_type(yytext)) return ID_TYPE; else return IDENTIFIER;
+[ \t\n]+                       ; /* ignore */
+.                              return ERROR;
+%%
diff --git a/formats/ctf/metadata/ctf-parser.y b/formats/ctf/metadata/ctf-parser.y
new file mode 100644 (file)
index 0000000..f5cb22a
--- /dev/null
@@ -0,0 +1,598 @@
+%{
+/*
+ * ctf.y
+ *
+ * Common Trace Format Metadata Grammar.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <helpers/list.h>
+#include <glib.h>
+#include "ctf-parser.h"
+#include "ctf-ast.h"
+
+#define printf_dbg(fmt, args...)       fprintf(stderr, "%s: " fmt, __func__, args)
+#define printf_dbg_noarg(fmt)  fprintf(stderr, "%s: " fmt, __func__)
+
+int yyparse(void);
+int yylex(void);
+
+static CDS_LIST_HEAD(allocated_strings);
+int yydebug;
+
+struct scope;
+struct scope {
+       struct scope *parent;
+       GHashTable *types;
+};
+
+struct gc_string {
+       struct cds_list_head gc;
+       char s[];
+};
+
+struct scope root_scope;
+struct scope *cs = &root_scope;        /* current scope */
+
+char *strredup(char **dest, const char *src)
+{
+       size_t len = strlen(src) + 1;
+
+       *dest = realloc(*dest, len);
+       if (!*dest)
+               return NULL;
+       strcpy(*dest, src);
+       return *dest;
+}
+
+static struct gc_string *gc_string_alloc(size_t len)
+{
+       struct gc_string *gstr;
+
+       gstr = malloc(sizeof(*gstr) + len);
+       cds_list_add(&gstr->gc, &allocated_strings);
+       return gstr;
+}
+
+void setstring(const char *src)
+{
+       yylval.gs = gc_string_alloc(strlen(src) + 1);
+       strcpy(yylval.gs->s, src);
+}
+
+static void init_scope(struct scope *scope, struct scope *parent)
+{
+       scope->parent = parent;
+       scope->types = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                            (GDestroyNotify) free, NULL);
+}
+
+static void finalize_scope(struct scope *scope)
+{
+       g_hash_table_destroy(scope->types);
+}
+
+static void push_scope(void)
+{
+       struct scope *ns;
+
+       printf_dbg_noarg("push scope\n");
+       ns = malloc(sizeof(struct scope));
+       init_scope(ns, cs);
+       cs = ns;
+}
+
+static void pop_scope(void)
+{
+       struct scope *os;
+
+       printf_dbg_noarg("pop scope\n");
+       os = cs;
+       cs = os->parent;
+       finalize_scope(os);
+       free(os);
+}
+
+int lookup_type(struct scope *s, const char *id)
+{
+       int ret;
+
+       ret = (int) g_hash_table_lookup(s->types, id);
+       printf_dbg("lookup %p %s %d\n", s, id, ret);
+       return ret;
+}
+
+int is_type(const char *id)
+{
+       struct scope *it;
+       int ret = 0;
+
+       for (it = cs; it != NULL; it = it->parent) {
+               if (lookup_type(it, id)) {
+                       ret = 1;
+                       break;
+               }
+       }
+       printf_dbg("is type %s %d\n", id, ret);
+       return ret;
+}
+
+static void add_type(const char *id)
+{
+       char *type_id = NULL;
+
+       printf_dbg("add type %s\n", id);
+       if (lookup_type(cs, id))
+               return;
+       strredup(&type_id, id);
+       g_hash_table_insert(cs->types, type_id, type_id);
+}
+
+void yyerror(const char *str)
+{
+       fprintf(stderr, "error %s\n", str);
+}
+int yywrap(void)
+{
+       return 1;
+} 
+
+static void free_strings(void)
+{
+       struct gc_string *gstr, *tmp;
+
+       cds_list_for_each_entry_safe(gstr, tmp, &allocated_strings, gc)
+               free(gstr);
+}
+
+int main(int argc, char **argv)
+{
+       yydebug = 1;
+       init_scope(&root_scope, NULL);
+       yyparse();
+       finalize_scope(&root_scope);
+       free_strings();
+       return 0;
+} 
+
+%}
+
+%start file
+/* %glr-parser */
+%token CHARACTER_CONSTANT_START SQUOTE STRING_LITERAL_START DQUOTE ESCSEQ CHAR_STRING_TOKEN LSBRAC RSBRAC LPAREN RPAREN LBRAC RBRAC RARROW STAR PLUS MINUS LT GT TYPEASSIGN COLON SEMICOLON DOTDOTDOT DOT EQUAL COMMA CONST CHAR DOUBLE ENUM EVENT FLOATING_POINT FLOAT INTEGER INT LONG SHORT SIGNED STREAM STRING STRUCT TRACE TYPEALIAS TYPEDEF UNSIGNED VARIANT VOID _BOOL _COMPLEX _IMAGINARY DECIMAL_CONSTANT OCTAL_CONSTANT HEXADECIMAL_CONSTANT
+%token <gs> IDENTIFIER ID_TYPE
+%token ERROR
+%union
+{
+       long long ll;
+       char c;
+       struct gc_string *gs;
+       struct ctf_node *n;
+}
+
+/* %token <c>UPPERCASE_L LOWERCASE_L _U _NONDIGIT */
+/*%type <n> decl type_decl event_decl stream_decl trace_decl type_def
+%type <n> event_attrib field_attrib assign_attrib 
+%type <n> event_attrib_list attrib_list field_list appendval_list
+%type <n> field value type_expr typename typename_postfix
+%type <gs> typename_prefix identifier */
+%%
+
+file:
+               declaration
+       |       file declaration
+       ;
+
+keywords:
+               VOID
+       |       CHAR
+       |       SHORT
+       |       INT
+       |       LONG
+       |       FLOAT
+       |       DOUBLE
+       |       SIGNED
+       |       UNSIGNED
+       |       _BOOL
+       |       _COMPLEX
+       |       FLOATING_POINT
+       |       INTEGER
+       |       STRING
+       |       ENUM
+       |       VARIANT
+       |       STRUCT
+       |       CONST
+       |       TYPEDEF
+       |       EVENT
+       |       STREAM
+       |       TRACE
+       ;
+
+/* 1.5 Constants */
+
+c_char_sequence:
+               c_char
+       |       c_char_sequence c_char
+       ;
+
+c_char:
+               CHAR_STRING_TOKEN
+       |       ESCSEQ
+       ;
+
+/* 1.6 String literals */
+
+s_char_sequence:
+               s_char
+       |       s_char_sequence s_char
+       ;
+
+s_char:
+               CHAR_STRING_TOKEN
+       |       ESCSEQ
+       ;
+
+/* 2: Phrase structure grammar */
+
+postfix_expression:
+               IDENTIFIER
+       |       ID_TYPE
+       |       keywords
+       |       DECIMAL_CONSTANT
+       |       OCTAL_CONSTANT
+       |       HEXADECIMAL_CONSTANT
+       |       STRING_LITERAL_START DQUOTE
+       |       STRING_LITERAL_START s_char_sequence DQUOTE
+       |       CHARACTER_CONSTANT_START c_char_sequence SQUOTE
+       |       LPAREN unary_expression RPAREN
+       |       postfix_expression LSBRAC unary_expression RSBRAC
+       |       postfix_expression DOT IDENTIFIER
+       |       postfix_expression DOT ID_TYPE
+       |       postfix_expression RARROW IDENTIFIER
+       |       postfix_expression RARROW ID_TYPE
+       ;
+
+unary_expression:
+               postfix_expression
+       |       PLUS postfix_expression
+       |       MINUS postfix_expression
+       ;
+
+unary_expression_or_range:
+               unary_expression DOTDOTDOT unary_expression
+       |       unary_expression
+       ;
+
+/* 2.2: Declarations */
+
+declaration:
+               declaration_specifiers SEMICOLON
+       |       event_declaration
+       |       stream_declaration
+       |       trace_declaration
+       |       declaration_specifiers TYPEDEF declaration_specifiers type_declarator_list SEMICOLON
+       |       TYPEDEF declaration_specifiers type_declarator_list SEMICOLON
+       |       declaration_specifiers TYPEDEF type_declarator_list SEMICOLON
+       |       TYPEALIAS declaration_specifiers abstract_declarator_list COLON declaration_specifiers abstract_type_declarator_list SEMICOLON
+       |       TYPEALIAS declaration_specifiers abstract_declarator_list COLON type_declarator_list SEMICOLON
+       ;
+
+event_declaration:
+               event_declaration_begin event_declaration_end
+       |       event_declaration_begin ctf_assignment_expression_list event_declaration_end
+       ;
+
+event_declaration_begin:
+               EVENT LBRAC
+               {
+                       push_scope();
+               }
+       ;
+
+event_declaration_end:
+               RBRAC SEMICOLON
+               {
+                       pop_scope();
+               }
+       ;
+
+
+stream_declaration:
+               stream_declaration_begin stream_declaration_end
+       |       stream_declaration_begin ctf_assignment_expression_list stream_declaration_end
+       ;
+
+stream_declaration_begin:
+               STREAM LBRAC
+               {
+                       push_scope();
+               }
+       ;
+
+stream_declaration_end:
+               RBRAC SEMICOLON
+               {
+                       pop_scope();
+               }
+       ;
+
+
+trace_declaration:
+               trace_declaration_begin trace_declaration_end
+       |       trace_declaration_begin ctf_assignment_expression_list trace_declaration_end
+       ;
+
+trace_declaration_begin:
+               TRACE LBRAC
+               {
+                       push_scope();
+               }
+       ;
+
+trace_declaration_end:
+               RBRAC SEMICOLON
+               {
+                       pop_scope();
+               }
+       ;
+
+declaration_specifiers:
+               CONST
+       |       type_specifier
+       |       declaration_specifiers CONST
+       |       declaration_specifiers type_specifier
+       ;
+
+type_declarator_list:
+               type_declarator
+       |       type_declarator_list COMMA type_declarator
+       ;
+
+abstract_type_declarator_list:
+               abstract_type_declarator
+       |       abstract_type_declarator_list COMMA abstract_type_declarator
+       ;
+
+type_specifier:
+               VOID
+       |       CHAR
+       |       SHORT
+       |       INT
+       |       LONG
+       |       FLOAT
+       |       DOUBLE
+       |       SIGNED
+       |       UNSIGNED
+       |       _BOOL
+       |       _COMPLEX
+       |       ID_TYPE
+       |       FLOATING_POINT LBRAC RBRAC
+       |       FLOATING_POINT LBRAC ctf_assignment_expression_list RBRAC
+       |       INTEGER LBRAC RBRAC
+       |       INTEGER LBRAC ctf_assignment_expression_list RBRAC
+       |       STRING LBRAC RBRAC
+       |       STRING LBRAC ctf_assignment_expression_list RBRAC
+       |       ENUM enum_type_specifier
+       |       VARIANT variant_type_specifier
+       |       STRUCT struct_type_specifier
+       ;
+
+struct_type_specifier:
+               struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end
+       |       IDENTIFIER struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end
+       |       ID_TYPE struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end
+       |       IDENTIFIER
+       |       ID_TYPE
+       ;
+
+struct_declaration_begin:
+               LBRAC
+               {
+                       push_scope();
+               }
+       ;
+
+struct_declaration_end:
+               RBRAC
+               {
+                       pop_scope();
+               }
+       ;
+
+variant_type_specifier:
+               variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
+       |       LT IDENTIFIER GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
+       |       LT ID_TYPE GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
+       |       IDENTIFIER variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
+       |       IDENTIFIER LT IDENTIFIER GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
+       |       IDENTIFIER LT IDENTIFIER GT
+       |       IDENTIFIER LT ID_TYPE GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
+       |       IDENTIFIER LT ID_TYPE GT
+       |       ID_TYPE variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
+       |       ID_TYPE LT IDENTIFIER GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
+       |       ID_TYPE LT IDENTIFIER GT
+       |       ID_TYPE LT ID_TYPE GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
+       |       ID_TYPE LT ID_TYPE GT
+       ;
+
+variant_declaration_begin:
+               LBRAC
+               {
+                       push_scope();
+               }
+       ;
+
+variant_declaration_end:
+               RBRAC
+               {
+                       pop_scope();
+               }
+       ;
+
+type_specifier_or_integer_constant:
+               declaration_specifiers
+       |       DECIMAL_CONSTANT
+       |       OCTAL_CONSTANT
+       |       HEXADECIMAL_CONSTANT
+       ;
+
+enum_type_specifier:
+               LBRAC enumerator_list RBRAC
+       |       LT type_specifier_or_integer_constant GT LBRAC enumerator_list RBRAC
+       |       IDENTIFIER LBRAC enumerator_list RBRAC
+       |       IDENTIFIER LT type_specifier_or_integer_constant GT LBRAC enumerator_list RBRAC
+       |       ID_TYPE LBRAC enumerator_list RBRAC
+       |       ID_TYPE LT type_specifier_or_integer_constant GT LBRAC enumerator_list RBRAC
+       |       LBRAC enumerator_list COMMA RBRAC
+       |       LT type_specifier_or_integer_constant GT LBRAC enumerator_list COMMA RBRAC
+       |       IDENTIFIER LBRAC enumerator_list COMMA RBRAC
+       |       IDENTIFIER LT type_specifier_or_integer_constant GT LBRAC enumerator_list COMMA RBRAC
+       |       IDENTIFIER
+       |       IDENTIFIER LT type_specifier_or_integer_constant GT
+       |       ID_TYPE LBRAC enumerator_list COMMA RBRAC
+       |       ID_TYPE LT type_specifier_or_integer_constant GT LBRAC enumerator_list COMMA RBRAC
+       |       ID_TYPE
+       |       ID_TYPE LT type_specifier_or_integer_constant GT
+       ;
+
+struct_or_variant_declaration_list:
+               /* empty */
+       |       struct_or_variant_declaration_list struct_or_variant_declaration
+       ;
+
+struct_or_variant_declaration:
+               specifier_qualifier_list struct_or_variant_declarator_list SEMICOLON
+       |       specifier_qualifier_list TYPEDEF specifier_qualifier_list type_declarator_list SEMICOLON
+       |       TYPEDEF specifier_qualifier_list type_declarator_list SEMICOLON
+       |       specifier_qualifier_list TYPEDEF type_declarator_list SEMICOLON
+       |       TYPEALIAS specifier_qualifier_list abstract_declarator_list COLON specifier_qualifier_list abstract_type_declarator_list SEMICOLON
+       |       TYPEALIAS specifier_qualifier_list abstract_declarator_list COLON type_declarator_list SEMICOLON
+       ;
+
+specifier_qualifier_list:
+               CONST
+       |       type_specifier
+       |       specifier_qualifier_list CONST
+       |       specifier_qualifier_list type_specifier
+       ;
+
+struct_or_variant_declarator_list:
+               struct_or_variant_declarator
+       |       struct_or_variant_declarator_list COMMA struct_or_variant_declarator
+       ;
+
+struct_or_variant_declarator:
+               declarator
+       |       COLON unary_expression
+       |       declarator COLON unary_expression
+       ;
+
+enumerator_list:
+               enumerator
+       |       enumerator_list COMMA enumerator
+       ;
+
+enumerator:
+               IDENTIFIER
+       |       ID_TYPE
+       |       keywords
+       |       STRING_LITERAL_START DQUOTE
+       |       STRING_LITERAL_START s_char_sequence DQUOTE
+       |       IDENTIFIER EQUAL unary_expression_or_range
+       |       ID_TYPE EQUAL unary_expression_or_range
+       |       keywords EQUAL unary_expression_or_range
+       |       STRING_LITERAL_START DQUOTE EQUAL unary_expression_or_range
+       |       STRING_LITERAL_START s_char_sequence DQUOTE EQUAL unary_expression_or_range
+       ;
+
+abstract_declarator_list:
+               abstract_declarator
+       |       abstract_declarator_list COMMA abstract_declarator
+       ;
+
+abstract_declarator:
+               direct_abstract_declarator
+       |       pointer direct_abstract_declarator
+       ;
+
+direct_abstract_declarator:
+               /* empty */
+       |       IDENTIFIER
+       |       LPAREN abstract_declarator RPAREN
+       |       direct_abstract_declarator LSBRAC type_specifier_or_integer_constant RSBRAC
+       |       direct_abstract_declarator LSBRAC RSBRAC
+       ;
+
+declarator:
+               direct_declarator
+       |       pointer direct_declarator
+       ;
+
+direct_declarator:
+               IDENTIFIER
+       |       LPAREN declarator RPAREN
+       |       direct_declarator LSBRAC type_specifier_or_integer_constant RSBRAC
+       ;
+
+type_declarator:
+               direct_type_declarator
+       |       pointer direct_type_declarator
+       ;
+
+direct_type_declarator:
+               IDENTIFIER
+               {
+                       add_type($1->s);
+               }
+       |       LPAREN type_declarator RPAREN
+       |       direct_type_declarator LSBRAC type_specifier_or_integer_constant RSBRAC
+       ;
+
+abstract_type_declarator:
+               direct_abstract_type_declarator
+       |       pointer direct_abstract_type_declarator
+       ;
+
+direct_abstract_type_declarator:
+               /* empty */
+       |       IDENTIFIER
+               {
+                       add_type($1->s);
+               }
+       |       LPAREN abstract_type_declarator RPAREN
+       |       direct_abstract_type_declarator LSBRAC type_specifier_or_integer_constant RSBRAC
+       |       direct_abstract_type_declarator LSBRAC RSBRAC
+       ;
+
+pointer:       
+               STAR
+       |       STAR pointer
+       |       STAR type_qualifier_list pointer
+       ;
+
+type_qualifier_list:
+               CONST
+       |       type_qualifier_list CONST
+       ;
+
+/* 2.3: CTF-specific declarations */
+
+ctf_assignment_expression_list:
+               ctf_assignment_expression SEMICOLON
+       |       ctf_assignment_expression_list ctf_assignment_expression SEMICOLON
+       ;
+
+ctf_assignment_expression:
+               unary_expression EQUAL unary_expression
+       |       unary_expression TYPEASSIGN type_specifier
+       |       declaration_specifiers TYPEDEF declaration_specifiers type_declarator_list
+       |       TYPEDEF declaration_specifiers type_declarator_list
+       |       declaration_specifiers TYPEDEF type_declarator_list
+       |       TYPEALIAS declaration_specifiers abstract_declarator_list COLON declaration_specifiers abstract_type_declarator_list
+       |       TYPEALIAS declaration_specifiers abstract_declarator_list COLON type_declarator_list
+       ;
diff --git a/formats/ctf/metadata/ctf-test.txt b/formats/ctf/metadata/ctf-test.txt
new file mode 100644 (file)
index 0000000..f6709b1
--- /dev/null
@@ -0,0 +1,153 @@
+
+enum name <32> {
+  ZERO,
+  ONE,
+  TWO,
+  TEN = 10,
+  ELEVEN,
+};
+
+enum name <long> { ONE, TWO };
+
+enum name <unsigned long> { ONE, TWO };
+
+enum name <unsigned long> {
+  string          = 1 ... 2,
+  "other string"      = 3...4,
+  yet_another_string,   /* will be assigned to end_value2 + 1 */
+  "some other string" = 10,
+};
+
+enum name <long> { "int" = 1, };
+
+typealias floating_point {
+  exp_dig = 8;         /* sizeof(float) * CHAR_BIT - FLT_MANT_DIG */
+  mant_dig = 24;       /* FLT_MANT_DIG */
+  byte_order = native;
+} : float;
+
+typealias integer {
+  size = 32;
+  align = 32;
+  sign = false;
+} : struct page *;
+
+stream {
+  typealias integer { size = 64; align = 64; signed = false; } : uint64_t;
+  typealias integer { size = 16; align = 16; signed = false; } : uint16_t;
+  typealias integer { size = 32; align = 32; signed = true; } : int;
+  typedef int pid_t;
+
+  id = 5;
+  /* Type 1 - Few event IDs; Type 2 - Many event IDs. See section 6.2. */
+  event.header := struct { uint64_t timestamp; uint16_t id; };
+  event.context := struct { pid_t pid; };
+};
+
+struct example {
+  short a:12;
+  short b:5;
+};
+
+struct name {
+  typealias integer { size = 64; align = 64; signed = false; } : uint64_t;
+  typealias integer { size = 32; align = 32; signed = false; } : uint32_t;
+  typealias integer { size = 32; align = 32; signed = true; } : int32_t;
+  typealias integer { size = 2; align = 8; signed = false; } : uint2_t;
+  typealias integer { size = 16; align = 16; signed = true; } : short;
+  typealias uint32_t : unsigned int;
+
+  enum <uint2_t> { a, b, c, d } choice;
+  /* Unrelated fields can be added between the variant and its tag */
+  int32_t somevalue;
+  variant <choice> {
+    uint32_t a;
+    uint64_t b;
+    short c;
+    struct {
+      unsigned int field1;
+      uint64_t field2;
+    } d;
+  } s;
+};
+
+typealias integer {
+  size = 32;
+  signed = false;
+  align = 32;
+} : uint32_t;
+
+typealias string { encoding = UTF8; } : test;
+
+struct event_packet_header {
+  typealias integer { size = 32; align = 32; signed = false; } : uint32_t;
+  typealias integer { size = 8; align = 8; signed = false; } : uint8_t;
+
+  uint32_t magic;
+  uint8_t  trace_uuid[16];
+  uint32_t stream_id;
+};
+
+struct event_packet_context {
+  typealias integer { size = 64; align = 64; signed = false; } : uint64_t;
+  typealias integer { size = 32; align = 32; signed = false; } : uint32_t;
+  typealias integer { size = 16; align = 16; signed = false; } : uint16_t;
+  typealias integer { size = 8; align = 8; signed = false; } : uint8_t;
+
+  uint64_t timestamp_begin;
+  uint64_t timestamp_end;
+  uint32_t checksum;
+  uint32_t stream_packet_count;
+  uint32_t events_discarded;
+  uint32_t cpu_id;
+  uint16_t content_size;
+  uint16_t packet_size;
+  uint8_t  stream_packet_count_bits;    /* Significant counter bits */
+  uint8_t  compression_scheme;
+  uint8_t  encryption_scheme;
+  uint8_t  checksum_scheme;
+};
+
+struct event_header_1 {
+  typealias integer { size = 64; align = 64; signed = false; } : uint64_t;
+  typealias integer { size = 32; align = 32; signed = false; } : uint32_t;
+  typealias integer { size = 5; align = 1; signed = false; } : uint5_t;
+  typealias integer { size = 27; align = 1; signed = false; } : uint27_t;
+
+  /*
+   * id: range: 0 - 30.
+   * id 31 is reserved to indicate an extended header.
+   */
+  enum <uint5_t> { compact = 0 ... 30, extended = 31 } id;
+  variant <id> {
+    struct {
+      uint27_t timestamp;
+    } compact;
+    struct {
+      uint32_t id;                       /* 32-bit event IDs */
+      uint64_t timestamp;                /* 64-bit timestamps */
+    } extended;
+  } v;
+};
+
+struct event_header_2 {
+  typealias integer { size = 64; align = 64; signed = false; } : uint64_t;
+  typealias integer { size = 32; align = 32; signed = false; } : uint32_t;
+  typealias integer { size = 16; align = 16; signed = false; } : uint16_t;
+
+  /*
+   * id: range: 0 - 65534.
+   * id 65535 is reserved to indicate an extended header.
+   */
+  enum <uint16_t> { compact = 0 ... 65534, extended = 65535 } id;
+  variant <id> {
+    struct {
+      uint32_t timestamp;
+    } compact;
+    struct {
+      uint32_t id;                       /* 32-bit event IDs */
+      uint64_t timestamp;                /* 64-bit timestamps */
+    } extended;
+  } v;
+};
+
diff --git a/include/helpers/list.h b/include/helpers/list.h
new file mode 100644 (file)
index 0000000..b872713
--- /dev/null
@@ -0,0 +1,170 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   The GNU C Library 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.
+
+   The GNU C Library 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 the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _LIST_H
+#define _LIST_H        1
+
+/* The definitions of this file are adopted from those which can be
+   found in the Linux kernel headers to enable people familiar with
+   the latter find their way in these sources as well.  */
+
+
+/* Basic type for the double-link list.  */
+typedef struct cds_list_head
+{
+  struct cds_list_head *next;
+  struct cds_list_head *prev;
+} list_t;
+
+
+/* Define a variable with the head and tail of the list.  */
+#define CDS_LIST_HEAD(name) \
+  list_t name = { &(name), &(name) }
+
+/* Initialize a new list head.  */
+#define CDS_INIT_LIST_HEAD(ptr) \
+  (ptr)->next = (ptr)->prev = (ptr)
+
+#define CDS_LIST_HEAD_INIT(name) { .prev = &(name), .next = &(name) }
+
+/* Add new element at the head of the list.  */
+static inline void
+cds_list_add (list_t *newp, list_t *head)
+{
+  head->next->prev = newp;
+  newp->next = head->next;
+  newp->prev = head;
+  head->next = newp;
+}
+
+
+/* Add new element at the tail of the list.  */
+static inline void
+cds_list_add_tail (list_t *newp, list_t *head)
+{
+  head->prev->next = newp;
+  newp->next = head;
+  newp->prev = head->prev;
+  head->prev = newp;
+}
+
+
+/* Remove element from list.  */
+static inline void
+__cds_list_del (list_t *prev, list_t *next)
+{
+  next->prev = prev;
+  prev->next = next;
+}
+
+/* Remove element from list.  */
+static inline void
+cds_list_del (list_t *elem)
+{
+  __cds_list_del (elem->prev, elem->next);
+}
+
+/* delete from list, add to another list as head */
+static inline void
+cds_list_move (list_t *elem, list_t *head)
+{
+  __cds_list_del (elem->prev, elem->next);
+  cds_list_add (elem, head);
+}
+
+/* replace an old entry.
+ */
+static inline void
+cds_list_replace(list_t *old, list_t *_new)
+{
+       _new->next = old->next;
+       _new->prev = old->prev;
+       _new->prev->next = _new;
+       _new->next->prev = _new;
+}
+
+/* Join two lists.  */
+static inline void
+cds_list_splice (list_t *add, list_t *head)
+{
+  /* Do nothing if the list which gets added is empty.  */
+  if (add != add->next)
+    {
+      add->next->prev = head;
+      add->prev->next = head->next;
+      head->next->prev = add->prev;
+      head->next = add->next;
+    }
+}
+
+
+/* Get typed element from list at a given position.  */
+#define cds_list_entry(ptr, type, member) \
+  ((type *) ((char *) (ptr) - (unsigned long) (&((type *) 0)->member)))
+
+
+
+/* Iterate forward over the elements of the list.  */
+#define cds_list_for_each(pos, head) \
+  for (pos = (head)->next; pos != (head); pos = pos->next)
+
+
+/* Iterate forward over the elements of the list.  */
+#define cds_list_for_each_prev(pos, head) \
+  for (pos = (head)->prev; pos != (head); pos = pos->prev)
+
+
+/* Iterate backwards over the elements list.  The list elements can be
+   removed from the list while doing this.  */
+#define cds_list_for_each_prev_safe(pos, p, head) \
+  for (pos = (head)->prev, p = pos->prev; \
+       pos != (head); \
+       pos = p, p = pos->prev)
+
+#define cds_list_for_each_entry(pos, head, member)                             \
+       for (pos = cds_list_entry((head)->next, typeof(*pos), member);  \
+            &pos->member != (head);                                    \
+            pos = cds_list_entry(pos->member.next, typeof(*pos), member))
+
+#define cds_list_for_each_entry_reverse(pos, head, member)                     \
+       for (pos = cds_list_entry((head)->prev, typeof(*pos), member);  \
+            &pos->member != (head);                                    \
+            pos = cds_list_entry(pos->member.prev, typeof(*pos), member))
+
+#define cds_list_for_each_entry_safe(pos, p, head, member)                     \
+       for (pos = cds_list_entry((head)->next, typeof(*pos), member),  \
+                    p = cds_list_entry(pos->member.next,typeof(*pos), member); \
+            &pos->member != (head);                                    \
+            pos = p, p = cds_list_entry(pos->member.next, typeof(*pos), member))
+
+static inline int cds_list_empty(list_t *head)
+{
+       return head == head->next;
+}
+
+static inline void cds_list_replace_init(list_t *old,
+                                    list_t *_new)
+{
+       list_t *head = old->next;
+       cds_list_del(old);
+       cds_list_add_tail(_new, head);
+       CDS_INIT_LIST_HEAD(old);
+}
+
+#endif /* list.h */
This page took 0.03613 seconds and 4 git commands to generate.