From 8b9d5b5e700bdf66edf4c0fa035fdf10cb3b36f3 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Sun, 6 Feb 2011 20:02:38 -0500 Subject: [PATCH] Add CTF metadata lexer/parser (lex/yacc) Signed-off-by: Mathieu Desnoyers --- configure.ac | 3 + formats/ctf/Makefile.am | 7 +- formats/ctf/metadata/Makefile.am | 7 + formats/ctf/metadata/ctf-ast.h | 32 ++ formats/ctf/metadata/ctf-lexer.l | 98 +++++ formats/ctf/metadata/ctf-parser.y | 598 ++++++++++++++++++++++++++++++ formats/ctf/metadata/ctf-test.txt | 153 ++++++++ include/helpers/list.h | 170 +++++++++ 8 files changed, 1064 insertions(+), 4 deletions(-) create mode 100644 formats/ctf/metadata/Makefile.am create mode 100644 formats/ctf/metadata/ctf-ast.h create mode 100644 formats/ctf/metadata/ctf-lexer.l create mode 100644 formats/ctf/metadata/ctf-parser.y create mode 100644 formats/ctf/metadata/ctf-test.txt create mode 100644 include/helpers/list.h diff --git a/configure.ac b/configure.ac index 2a153583..1f1d2844 100644 --- a/configure.ac +++ b/configure.ac @@ -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 ]) diff --git a/formats/ctf/Makefile.am b/formats/ctf/Makefile.am index ba0a4f79..a20d7c4a 100644 --- a/formats/ctf/Makefile.am +++ b/formats/ctf/Makefile.am @@ -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 index 00000000..fac978cc --- /dev/null +++ b/formats/ctf/metadata/Makefile.am @@ -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 index 00000000..b839b2c6 --- /dev/null +++ b/formats/ctf/metadata/ctf-ast.h @@ -0,0 +1,32 @@ +#ifndef _CTF_PARSER_H +#define _CTF_PARSER_H + +#include + +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 index 00000000..763a1bb8 --- /dev/null +++ b/formats/ctf/metadata/ctf-lexer.l @@ -0,0 +1,98 @@ +%{ +#include +#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); +[^*\n]* /* eat anything that's not a '*' */ +"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ +\n ++yylineno; +"*"+"/" BEGIN(INITIAL); + +"//" BEGIN(comment_sl); +[^\n]*\n ++yylineno; BEGIN(INITIAL); + +L\' BEGIN(char_const); return CHARACTER_CONSTANT_START; +\' BEGIN(char_const); return CHARACTER_CONSTANT_START; +\' BEGIN(INITIAL); return SQUOTE; + +L\" BEGIN(string_lit); return STRING_LITERAL_START; +\" BEGIN(string_lit); return STRING_LITERAL_START; +\" BEGIN(INITIAL); return DQUOTE; + +ESCSEQ return ESCSEQ; +\n ; /* ignore */ +. 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, "\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 index 00000000..f5cb22ad --- /dev/null +++ b/formats/ctf/metadata/ctf-parser.y @@ -0,0 +1,598 @@ +%{ +/* + * ctf.y + * + * Common Trace Format Metadata Grammar. + */ + +#include +#include +#include +#include +#include +#include +#include +#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 IDENTIFIER ID_TYPE +%token ERROR +%union +{ + long long ll; + char c; + struct gc_string *gs; + struct ctf_node *n; +} + +/* %token UPPERCASE_L LOWERCASE_L _U _NONDIGIT */ +/*%type decl type_decl event_decl stream_decl trace_decl type_def +%type event_attrib field_attrib assign_attrib +%type event_attrib_list attrib_list field_list appendval_list +%type field value type_expr typename typename_postfix +%type 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 index 00000000..f6709b1d --- /dev/null +++ b/formats/ctf/metadata/ctf-test.txt @@ -0,0 +1,153 @@ + +enum name <32> { + ZERO, + ONE, + TWO, + TEN = 10, + ELEVEN, +}; + +enum name { ONE, TWO }; + +enum name { ONE, TWO }; + +enum name { + string = 1 ... 2, + "other string" = 3...4, + yet_another_string, /* will be assigned to end_value2 + 1 */ + "some other string" = 10, +}; + +enum name { "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 { a, b, c, d } choice; + /* Unrelated fields can be added between the variant and its tag */ + int32_t somevalue; + variant { + 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 { compact = 0 ... 30, extended = 31 } id; + variant { + 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 { compact = 0 ... 65534, extended = 65535 } id; + variant { + 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 index 00000000..b872713f --- /dev/null +++ b/include/helpers/list.h @@ -0,0 +1,170 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 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 */ -- 2.34.1