summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjolsa@redhat.com <jolsa@redhat.com>2011-03-12 13:59:21 +0100
committerJiri Olsa <Jiri Olsa jolsa@redhat.com>2011-04-05 17:35:56 +0200
commit252af820ecf406c7dac397bcb54f763883e1eb8f (patch)
tree8302abfb4dffe2aa46d200e5d09590fd2a091dda
parent79381b3ed5b490054cb211d0374f4338ef9d5931 (diff)
downloadlatrace-252af820ecf406c7dac397bcb54f763883e1eb8f.tar.gz
latrace-252af820ecf406c7dac397bcb54f763883e1eb8f.tar.xz
latrace-252af820ecf406c7dac397bcb54f763883e1eb8f.zip
adding support for configuration file
- separating bison/flex functions for args and config - the "include file support" unified among new conf and C header parsing - support for following options: HEADERS INDENT_SYM PIPE TIMESTAMP FRAMESIZE FRAMESIZE_CHECK HIDE_TID FOLLOW_FORK FOLLOW_EXEC DEMANGLE BRACES ENABLE_ARGS DETAIL_ARGS
-rw-r--r--Makefile3
-rw-r--r--etc/latrace.d/latrace.conf.in64
-rw-r--r--src/Makefile13
-rw-r--r--src/args-bison.y16
-rw-r--r--src/args-flex.l22
-rw-r--r--src/args.c148
-rw-r--r--src/args.h7
-rw-r--r--src/config-bison.y179
-rw-r--r--src/config-flex.l119
-rw-r--r--src/config.c264
-rw-r--r--src/config.h27
-rw-r--r--src/lib-include.c161
-rw-r--r--src/lib-include.h61
-rw-r--r--src/sysdeps/x86_64/args.h4
14 files changed, 905 insertions, 183 deletions
diff --git a/Makefile b/Makefile
index 55af41d..a153d53 100644
--- a/Makefile
+++ b/Makefile
@@ -86,6 +86,7 @@ all::
install:: all
$(call install,etc/latrace.d/latrace.conf,$(confdir),644)
+ $(call install,etc/latrace.d/headers/latrace.h,$(headdir),644)
$(call install,etc/latrace.d/headers/ctype.h,$(headdir),644)
$(call install,etc/latrace.d/headers/inet.h,$(headdir),644)
$(call install,etc/latrace.d/headers/misc.h,$(headdir),644)
@@ -162,6 +163,7 @@ all:: $(PROGRAMS) LATRACE-CFLAGS
clean::
$(call remove, $(OBJS) $(PROGRAMS))
$(call remove, src/args-bison.c src/args-flex.c src/args-bison.h src/args-bison.output)
+ $(call remove, src/config-bison.c src/config-flex.c src/config-bison.h src/config-bison.output)
$(call remove, lib bin share deps.make latrace-$(CONFIG_VERSION))
mrproper::
@@ -187,6 +189,7 @@ package:
# gcc option to do that.
# - no dependency for flex and bison definitions
DEPS_OBJS=$(filter-out src/args-flex.o src/args-bison.o,$(OBJS))
+DEPS_OBJS:=$(filter-out src/config-bison.o src/config-flex.o,$(DEPS_OBJS))
deps.make:
$(QUIET_DEP)$(RM) -f deps.make; \
diff --git a/etc/latrace.d/latrace.conf.in b/etc/latrace.d/latrace.conf.in
index 5183c85..ec2481d 100644
--- a/etc/latrace.d/latrace.conf.in
+++ b/etc/latrace.d/latrace.conf.in
@@ -1,18 +1,60 @@
+# latrace configuration file - version @CONFIG_VERSION@
-INCLUDE krava.conf
+# include another configuration file
+# INCLUDE "latrace-user.conf"
-GLOBAL {
- # headers definition
- HEADERS = @sysconfdir@/latrace.d/headers/latrace.h
+OPTIONS {
+ # -a, --args
+ # arguments definition file, implies '-A'
+ # defaults to $sysconfdir/etc/latrace.d/headers/latrace.h
+ # HEADERS = "headers.h"
- # options definitions
+ # -i, --indent-sym
+ # specify indent size specification
+ INDENT_SYM = 2
- # -l, --libs
- OPT_LIBS = krava
+ # -p, --pipe
+ # use pipe to latrace process to send audit data
+ # latrace app is then the one displaying the output
+ PIPE = YES
- # -t, --libs-to
- OPT_LIBS_TO = krava
+ # -S, --timestamp
+ # display timestamp for each symbol
+ TIMESTAMP = NO
- # -p, --pipe
- OPT_PIPE = yes
+ # -y, --framesize
+ # framesize for storing the stack before pltexit
+ FRAMESIZE = 1000
+
+ # -Y, --no-framesize-check
+ # framesize check
+ FRAMESIZE_CHECK = YES
+
+ # -T, --hide-tid
+ # dont display thread id
+ HIDE_TID = NO
+
+ # -F, --no-follow-fork
+ # dont follow fork calls - childs
+ FOLLOW_FORK = YES
+
+ # -E, --no-follow-exec
+ # dont follow exec calls
+ FOLLOW_EXEC = YES
+
+ # -d, --demangle
+ # run the symbol name throught the C++ demangler
+ DEMANGLE = NO
+
+ # -B, --braces
+ # always display braces {}
+ BRACES = NO
+
+ # -A, --enable-args
+ # enable arguments output (definitions from headers)
+ ENABLE_ARGS = NO
+
+ # -D, --detail-args
+ # display struct arguments in more detail
+ DETAIL_ARGS = NO
}
diff --git a/src/Makefile b/src/Makefile
index 7263eec..dd7b56f 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -29,7 +29,8 @@ AUDIT_OBJS=\
src/output.o \
src/objsearch.o \
src/stack.o \
- src/symbol.o
+ src/symbol.o \
+ src/lib-include.o
ifeq ($(CONFIG_ARCH_HAVE_ARGS),y)
AUDIT_OBJS+=\
@@ -61,13 +62,17 @@ LATRACE_OBJS=\
src/stats.o \
src/fifo.o \
src/thread.o \
- src/output.o
+ src/output.o \
+ src/config-bison.o \
+ src/config-flex.o \
+ src/lib-include.o
OBJS+=$(LATRACE_OBJS)
PROGRAMS+=$(LATRACE_BIN)
CPPFLAGS+=-DCONFIG_LIBDIR=\"$(libdir)\"
-CPPFLAGS+=-DLT_ARGS_DEF_DIR=\"$(confdir)\"
-CPPFLAGS+=-DLT_ARGS_DEF_CONF=\"$(sysconfdir)/headers/latrace.h\"
+CPPFLAGS+=-DLT_CONF_DIR=\"$(sysconfdir)/latrace.d\"
+CPPFLAGS+=-DLT_CONF_HEADERS_DIR=\"$(sysconfdir)/latrace.d/headers\"
+CPPFLAGS+=-DLT_CONF_HEADERS_FILE=\"$(sysconfdir)/latrace.d/headers/latrace.h\"
$(LATRACE_BIN): $(LATRACE_OBJS)
$(QUIET_LD)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(LATRACE_OBJS) $(LATRACE_LIBS) $(LATRACE_LIB)
diff --git a/src/args-bison.y b/src/args-bison.y
index 1776a1e..fc6787c 100644
--- a/src/args-bison.y
+++ b/src/args-bison.y
@@ -18,6 +18,7 @@
<http://www.gnu.org/licenses/>.
*/
+%name-prefix "lt_args_"
%{
@@ -27,18 +28,20 @@
#include <string.h>
#include "config.h"
+#include "lib-include.h"
-int yylex (void);
-void yyerror(const char *m);
+int lt_args_lex(void);
+void lt_args_error(const char *m);
static struct lt_config_shared *scfg;
static int struct_alive = 0;
+struct lt_include *lt_args_sinc;
#define ERROR(fmt, args...) \
do { \
char ebuf[1024]; \
sprintf(ebuf, fmt, ## args); \
- yyerror(ebuf); \
+ lt_args_error(ebuf); \
YYERROR; \
} while(0)
@@ -100,7 +103,7 @@ entry include_def
|
entry END
{
- if (lt_args_buf_close(scfg))
+ if (lt_inc_close(scfg, lt_args_sinc))
return 0;
}
|
@@ -289,14 +292,15 @@ ENUM_REF:
/* include definitions */
include_def: INCLUDE '"' FILENAME '"'
{
- if (lt_args_buf_open(scfg, $3))
+ if (lt_inc_open(scfg, lt_args_sinc, $3))
ERROR("failed to process include");
}
%%
-int lt_args_parse_init(struct lt_config_shared *cfg)
+int lt_args_parse_init(struct lt_config_shared *cfg, struct lt_include *inc)
{
scfg = cfg;
+ lt_args_sinc = inc;
return 0;
}
diff --git a/src/args-flex.l b/src/args-flex.l
index cd68fb3..368e4df 100644
--- a/src/args-flex.l
+++ b/src/args-flex.l
@@ -18,6 +18,7 @@
<http://www.gnu.org/licenses/>.
*/
+%option prefix="lt_args_"
%{
@@ -25,8 +26,9 @@
#include "config.h"
#include "args-bison.h"
+#include "lib-include.h"
-struct lt_args_include* lt_args_buf_get(void);
+extern struct lt_include *lt_args_sinc;
%}
@@ -40,11 +42,11 @@ filename ([-0-9a-zA-Z\./_])+
"/*" BEGIN(comment);
<comment>[^*\n]* /* eat anything that's not a '*' */
<comment>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */
-<comment>\n { lt_args_buf_get()->lineno++; }
+<comment>\n { lt_inc_stack(lt_args_sinc)->lineno++; }
<comment>"*"+"/" BEGIN(INITIAL);
"#include" { BEGIN(include); return INCLUDE; }
-<include>{filename} { yylval.s = strdup(yytext); return FILENAME; }
+<include>{filename} { lt_args_lval.s = strdup(lt_args_text); return FILENAME; }
<include>"\"" { return '"'; }
<include>\n { BEGIN(INITIAL); }
<include>. { ; }
@@ -55,7 +57,7 @@ filename ([-0-9a-zA-Z\./_])+
"struct" { return STRUCT; }
"enum" { return ENUM; }
"typedef" { return TYPEDEF; }
-{name} { yylval.s = strdup(yytext); return NAME; }
+{name} { lt_args_lval.s = strdup(lt_args_text); return NAME; }
"\*"+ { return POINTER; }
")" { return ')'; }
"(" { return '('; }
@@ -65,7 +67,7 @@ filename ([-0-9a-zA-Z\./_])+
"," { return ','; }
"=" { return '='; }
\ { ; }
-\n { lt_args_buf_get()->lineno++; }
+\n { lt_inc_stack(lt_args_sinc)->lineno++; }
. { ; }
%%
@@ -80,10 +82,10 @@ int yywrap()
}
#endif
-void yyerror(const char *m)
+void lt_args_error(const char *m)
{
- printf("latrace config file [%s] line %d: %s\n",
- lt_args_buf_get()->file,
- lt_args_buf_get()->lineno,
- m);
+ printf("header file [%s] line %d: %s\n",
+ lt_inc_stack(lt_args_sinc)->file,
+ lt_inc_stack(lt_args_sinc)->lineno,
+ m);
}
diff --git a/src/args.c b/src/args.c
index a7b745e..b766326 100644
--- a/src/args.c
+++ b/src/args.c
@@ -28,26 +28,26 @@
#include <stdio.h>
#include "config.h"
+#include "lib-include.h"
-
-#define YY_BUF_SIZE 16384
-#define MAX_INCLUDE_DEPTH 10
#define LT_EQUAL " = "
-
extern int errno;
+extern FILE *lt_args_in;
+int lt_args_parse();
+void lt_args__switch_to_buffer (YY_BUFFER_STATE new_buffer );
+void lt_args__delete_buffer (YY_BUFFER_STATE b );
+YY_BUFFER_STATE lt_args__create_buffer (FILE *file,int size );
+
+static struct lt_include inc = {
+ .create_buffer = lt_args__create_buffer,
+ .switch_to_buffer = lt_args__switch_to_buffer,
+ .delete_buffer = lt_args__delete_buffer,
+ .in = &lt_args_in,
+};
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-YY_BUFFER_STATE yy_create_buffer(FILE *file, int size);
-extern FILE *yyin;
-
-int yyparse();
-void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer);
-void yy_delete_buffer(YY_BUFFER_STATE b);
+int lt_args_parse_init(struct lt_config_shared *cfg, struct lt_include *inc);
-int lt_args_parse_init(struct lt_config_shared *cfg);
-static struct lt_args_include include_stack[MAX_INCLUDE_DEPTH];
-static int include_stack_ptr = 0;
static int enum_init = 0;
@@ -706,7 +706,7 @@ int lt_args_add_typedef(struct lt_config_shared *cfg, char *base,
int lt_args_init(struct lt_config_shared *cfg)
{
- char *file = LT_ARGS_DEF_CONF;
+ char *file = LT_CONF_HEADERS_FILE;
int ret = 0;
if (!hcreate_r(LT_ARGS_TAB, &cfg->args_tab)) {
@@ -714,38 +714,33 @@ int lt_args_init(struct lt_config_shared *cfg)
return -1;
}
- lt_args_parse_init(cfg);
+ lt_args_parse_init(cfg, &inc);
if (*cfg->args_def)
file = cfg->args_def;
PRINT_VERBOSE(cfg, 1, "arguments definition file %s\n", file);
- if (lt_args_buf_open(cfg, file))
+ if (lt_inc_open(cfg, &inc, file))
return -1;
- if (yyparse()) {
- printf("failed to parse config file %s\n", file);
+ if (lt_args_parse()) {
+ printf("failed to header file(s) %s\n", file);
ret = -1;
}
#if defined(LT_ARGS_ARCH_CONF)
/* Some architectures provides specific
* configuration file. */
- if (lt_args_buf_open(cfg, lt_args_arch_conf(cfg)))
+ if (lt_inc_open(cfg, &inc, lt_args_arch_conf(cfg)))
return -1;
- if (yyparse()) {
+ if (lt_args_parse()) {
printf("failed to parse config file %s\n", file);
ret = -1;
}
#endif
- if (fclose(yyin)) {
- perror("failed to close " LT_ARGS_DEF_CONF);
- return -1;
- }
-
return ret;
}
@@ -976,107 +971,6 @@ static int getargs(struct lt_config_shared *cfg, struct lt_args_sym *asym,
return lt_stack_process(cfg, asym, regs, &data);
}
-static FILE* open_include(struct lt_config_shared *cfg, char *file)
-{
- FILE *f;
- char fn[LT_MAXFILE];
-
- /* we got an absolute path */
- if ((NULL != (f = fopen(file, "r")))) {
- PRINT_VERBOSE(cfg, 1, "open ok [%s]\n", file);
- return f;
- }
-
- PRINT_VERBOSE(cfg, 1, "open failed [%s]: %s\n",
- file, strerror(errno));
-
- /* give up if there was already the absolute name */
- if (*file == '/') {
- printf("open failed [%s]: %s\n", file, strerror(errno));
- return NULL;
- }
-
- /* not an absolute name, give it a chance
- inside of the /etc config directory */
- if (strlen(file) > (LT_MAXFILE - sizeof(LT_ARGS_DEF_DIR))) {
- printf("file name length crossed the max %u: %s\n",
- (u_int) (LT_MAXFILE - sizeof(LT_ARGS_DEF_DIR)), file);
- return NULL;
- }
-
- sprintf(fn, "%s/%s", LT_ARGS_DEF_DIR, file);
-
- if ((NULL == (f = fopen(fn, "r")))) {
- PRINT_VERBOSE(cfg, 1, "open failed [%s]: %s\n",
- fn, strerror(errno));
- printf("open failed [%s]: %s\n", file, strerror(errno));
- return NULL;
- }
-
- PRINT_VERBOSE(cfg, 1, "open ok [%s]\n", fn);
- return f;
-}
-
-int lt_args_buf_open(struct lt_config_shared *cfg, char *file)
-{
- struct lt_args_include *inc;
-
- PRINT_VERBOSE(cfg, 1, "opening buffer for [%s] depth %d\n",
- file, include_stack_ptr);
-
- if ((include_stack_ptr + 1) == MAX_INCLUDE_DEPTH) {
- printf("include depth overstep");
- return -1;
- }
-
- if (NULL == (yyin = open_include(cfg, file)))
- return -1;
-
- inc = &include_stack[include_stack_ptr++];
- memset(inc, 0, sizeof(*inc));
-
- inc->yyin = yyin;
- inc->file = strdup(file);
- inc->lineno = 1;
- inc->yybuf = yy_create_buffer(yyin, YY_BUF_SIZE);
-
- yy_switch_to_buffer(inc->yybuf);
-
- PRINT_VERBOSE(cfg, 1, "opened buffer for [%s] depth %d\n",
- file, include_stack_ptr);
- return 0;
-}
-
-int lt_args_buf_close(struct lt_config_shared *cfg)
-{
- struct lt_args_include *inc = &include_stack[--include_stack_ptr];
-
- PRINT_VERBOSE(cfg, 1, "buffer closed [%s], depth [%d]\n",
- inc->file, include_stack_ptr);
-
- free(inc->file);
-
- /* EOF with no other includes on stack */
- if (!include_stack_ptr)
- return -1;
-
- /* looks like the base buffer is cleaned up by the
- flex itself, so we do the actual cleaning
- only for includes */
- yy_delete_buffer(inc->yybuf);
- fclose(inc->yyin);
-
- inc = &include_stack[include_stack_ptr - 1];
- yy_switch_to_buffer(inc->yybuf);
- return 0;
-}
-
-struct lt_args_include* lt_args_buf_get(void)
-{
- struct lt_args_include *inc = &include_stack[include_stack_ptr - 1];
- return inc;
-}
-
struct lt_args_sym* lt_args_sym_get(struct lt_config_shared *cfg,
const char *sym)
{
diff --git a/src/args.h b/src/args.h
index e0f4846..439fb79 100644
--- a/src/args.h
+++ b/src/args.h
@@ -98,13 +98,6 @@ struct lt_args_sym {
struct lt_arg **args;
};
-struct lt_args_include {
- FILE *yyin;
- void *yybuf;
- char *file;
- int lineno;
-};
-
/* used in lt_args_cb_struct for argument type */
enum {
LT_ARGS_STRUCT_ITSELF = 0,
diff --git a/src/config-bison.y b/src/config-bison.y
new file mode 100644
index 0000000..a544fa7
--- /dev/null
+++ b/src/config-bison.y
@@ -0,0 +1,179 @@
+/*
+ Copyright (C) 2011 Jiri Olsa <olsajiri@gmail.com>
+
+ This file is part of the latrace.
+
+ The latrace is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ The latrace 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the latrace (file COPYING). If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+%name-prefix "lt_config_"
+
+%{
+#include "config.h"
+#include "lib-include.h"
+
+struct lt_include *lt_config_sinc;
+static struct lt_config_app *scfg;
+
+int lt_config_lex(void);
+void lt_config_error(const char *m);
+
+#define ERROR(fmt, args...) \
+do { \
+ char ebuf[1024]; \
+ sprintf(ebuf, fmt, ## args); \
+ lt_config_error(ebuf); \
+ YYERROR; \
+} while(0)
+
+static LT_LIST_HEAD(opt_list);
+
+#define OPTION_ADD(idx, sval, nval) \
+do { \
+ struct lt_config_opt *opt; \
+ opt = lt_config_opt_new(idx, sval, nval); \
+ if (!opt) \
+ ERROR("failed to process option\n"); \
+ lt_list_add_tail(&opt->list, &opt_list); \
+} while(0)
+%}
+
+%token INCLUDE FILENAME BOOL VALUE END
+%token OPTIONS
+%token OPT_HEADERS OPT_INDENT_SYM OPT_PIPE
+%token OPT_TIMESTAMP OPT_FRAMESIZE OPT_FRAMESIZE_CHECK
+%token OPT_HIDE_TID OPT_FOLLOW_FORK OPT_FOLLOW_EXEC
+%token OPT_DEMANGLE OPT_BRACES OPT_ENABLE_ARGS
+%token OPT_DETAIL_ARGS
+
+%union
+{
+ char *s;
+ unsigned long l;
+}
+
+%type <s> FILENAME
+%type <s> BOOL
+%type <l> VALUE
+
+%%
+entry:
+entry include_def
+|
+entry options_def
+|
+entry END
+{
+ if (lt_inc_close(scfg->sh, lt_config_sinc))
+ return 0;
+}
+|
+/* left blank intentionally */
+
+include_def: INCLUDE '"' FILENAME '"'
+{
+ if (lt_inc_open(scfg->sh, lt_config_sinc, $3))
+ ERROR("failed to process include");
+}
+
+options_def: OPTIONS '{' OPTIONS_DEF '}'
+{
+ struct lt_config_opt *opt, *opth;
+
+ if (lt_config_opt_process(scfg, &opt_list))
+ ERROR("failed to process options");
+
+ lt_list_for_each_entry_safe(opt, opth, &opt_list, list) {
+ lt_list_del(&opt->list);
+ free(opt);
+ }
+}
+
+OPTIONS_DEF:
+OPTIONS_DEF OPT_HEADERS '=' '"' FILENAME '"'
+{
+ OPTION_ADD(LT_OPT_HEADERS, $5, -1);
+}
+|
+OPTIONS_DEF OPT_INDENT_SYM '=' VALUE
+{
+ OPTION_ADD(LT_OPT_INDENT_SYM, NULL, $4);
+}
+|
+OPTIONS_DEF OPT_PIPE '=' BOOL
+{
+ OPTION_ADD(LT_OPT_PIPE, $4, -1);
+}
+|
+OPTIONS_DEF OPT_TIMESTAMP '=' BOOL
+{
+ OPTION_ADD(LT_OPT_TIMESTAMP, $4, -1);
+}
+|
+OPTIONS_DEF OPT_FRAMESIZE '=' VALUE
+{
+ OPTION_ADD(LT_OPT_FRAMESIZE, NULL, $4);
+}
+|
+OPTIONS_DEF OPT_FRAMESIZE_CHECK '=' BOOL
+{
+ OPTION_ADD(LT_OPT_FRAMESIZE_CHECK, $4, -1);
+}
+|
+OPTIONS_DEF OPT_HIDE_TID '=' BOOL
+{
+ OPTION_ADD(LT_OPT_HIDE_TID, $4, -1);
+}
+|
+OPTIONS_DEF OPT_FOLLOW_FORK '=' BOOL
+{
+ OPTION_ADD(LT_OPT_FOLLOW_FORK, $4, -1);
+}
+|
+OPTIONS_DEF OPT_FOLLOW_EXEC '=' BOOL
+{
+ OPTION_ADD(LT_OPT_FOLLOW_EXEC, $4, -1);
+}
+|
+OPTIONS_DEF OPT_DEMANGLE '=' BOOL
+{
+ OPTION_ADD(LT_OPT_DEMANGLE, $4, -1);
+}
+|
+OPTIONS_DEF OPT_BRACES '=' BOOL
+{
+ OPTION_ADD(LT_OPT_BRACES, $4, -1);
+}
+|
+OPTIONS_DEF OPT_ENABLE_ARGS '=' BOOL
+{
+ OPTION_ADD(LT_OPT_ENABLE_ARGS, $4, -1);
+}
+|
+OPTIONS_DEF OPT_DETAIL_ARGS '=' BOOL
+{
+ OPTION_ADD(LT_OPT_DETAIL_ARGS, $4, -1);
+}
+|
+/* left blank intentionally */
+
+%%
+
+int lt_config_parse_init(struct lt_config_app *cfg, struct lt_include *inc)
+{
+ scfg = cfg;
+ lt_config_sinc = inc;
+ return 0;
+}
diff --git a/src/config-flex.l b/src/config-flex.l
new file mode 100644
index 0000000..61a775e
--- /dev/null
+++ b/src/config-flex.l
@@ -0,0 +1,119 @@
+/*
+ Copyright (C) 2011 Jiri Olsa <olsajiri@gmail.com>
+
+ This file is part of the latrace.
+
+ The latrace is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ The latrace 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the latrace (file COPYING). If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+%option prefix="lt_config_"
+
+%{
+
+#include <string.h>
+
+#include "config.h"
+#include "config-bison.h"
+#include "lib-include.h"
+
+extern struct lt_include *lt_config_sinc;
+
+
+#define NEW_LINE() \
+do { \
+ lt_inc_stack(lt_config_sinc)->lineno++; \
+} while(0)
+
+#define RETURN_STR(token) \
+do { \
+ lt_config_lval.s = strdup(lt_config_text); return token; \
+} while(0)
+
+#define RETURN_LONG(token) \
+do { \
+ lt_config_lval.l = atol(lt_config_text); return token; \
+} while(0)
+
+%}
+
+num [-0-9]
+value ({num})+
+alphnum [-0-9a-zA-Z_]
+name ({alphnum})+
+filename ([-0-9a-zA-Z\./_])+
+bool YES|NO
+comment ^([\s\t])*#.*
+
+%x comment include options
+
+%%
+
+<<EOF>> { return END; }
+"\n" { NEW_LINE(); }
+{comment} { ; }
+. { ; }
+
+INCLUDE { BEGIN(include); return INCLUDE; }
+<include>{filename} { RETURN_STR(FILENAME); }
+<include>"\"" { return '"'; }
+<include>\n { BEGIN(INITIAL); NEW_LINE(); }
+<include>. { ; }
+
+OPTIONS { BEGIN(options); return OPTIONS; }
+<options>HEADERS { return OPT_HEADERS; }
+<options>INDENT_SYM { return OPT_INDENT_SYM; }
+<options>PIPE { return OPT_PIPE; }
+<options>TIMESTAMP { return OPT_TIMESTAMP; }
+<options>FRAMESIZE { return OPT_FRAMESIZE; }
+<options>FRAMESIZE_CHECK { return OPT_FRAMESIZE_CHECK; }
+<options>HIDE_TID { return OPT_HIDE_TID; }
+<options>FOLLOW_FORK { return OPT_FOLLOW_FORK; }
+<options>FOLLOW_EXEC { return OPT_FOLLOW_EXEC; }
+<options>DEMANGLE { return OPT_DEMANGLE; }
+<options>BRACES { return OPT_BRACES; }
+<options>ENABLE_ARGS { return OPT_ENABLE_ARGS; }
+<options>DETAIL_ARGS { return OPT_DETAIL_ARGS; }
+
+<options>{bool} { RETURN_STR(BOOL); }
+<options>{value} { RETURN_LONG(VALUE); }
+<options>{filename} { RETURN_STR(FILENAME); }
+<options>{comment} { ; }
+<options>"}" { BEGIN(INITIAL); return '}'; }
+<options>"{" { return '{'; }
+<options>"=" { return '='; }
+<options>"\"" { return '"'; }
+<options>"\\" { ; }
+<options>"\n" { NEW_LINE(); }
+<options>. { ; }
+
+%%
+
+#ifndef yywrap
+int yywrap()
+{
+ return 1;
+ /* XXX not to get the compiler 'not used' warning */
+ yyunput(0, NULL);
+ input();
+}
+#endif
+
+void lt_config_error(const char *m)
+{
+ printf("conf file [%s] line %d: %s\n",
+ lt_inc_stack(lt_config_sinc)->file,
+ lt_inc_stack(lt_config_sinc)->lineno,
+ m);
+}
diff --git a/src/config.c b/src/config.c
index 3cf734b..8ba7b0b 100644
--- a/src/config.c
+++ b/src/config.c
@@ -23,8 +23,26 @@
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
+#include <errno.h>
#include "config.h"
+#include "lib-include.h"
+
+extern FILE *lt_config_in;
+int lt_config_parse();
+void lt_config__switch_to_buffer (YY_BUFFER_STATE new_buffer );
+void lt_config__delete_buffer (YY_BUFFER_STATE b );
+YY_BUFFER_STATE lt_config__create_buffer (FILE *file,int size );
+
+static struct lt_include inc = {
+ .stack_idx = 0,
+ .create_buffer = lt_config__create_buffer,
+ .switch_to_buffer = lt_config__switch_to_buffer,
+ .delete_buffer = lt_config__delete_buffer,
+ .in = &lt_config_in,
+};
+
+int lt_config_parse_init(struct lt_config_app *cfg, struct lt_include *inc);
static void usage() NORETURN;
static void usage()
@@ -46,7 +64,7 @@ static void usage()
#ifndef CONFIG_ARCH_HAVE_ARGS
printf(" -[ADa] arguments display support not compiled in\n");
#else
- printf(" -A, --enable-args enable arguments output (definitions from /etc/latrace.conf)\n");
+ printf(" -A, --enable-args enable arguments output (definitions from headers)\n");
printf(" -D, --detail-args display struct arguments in more detail\n");
printf(" -a, --args file arguments definition file, implies \'-A\'\n");
#endif
@@ -107,10 +125,204 @@ static int get_type(struct lt_config_app *cfg, struct lt_config_tv *tv,
return -1;
}
+/* read conf file */
+static int read_config(struct lt_config_app *cfg, char *file)
+{
+ int ret = 0;
+ lt_config_parse_init(cfg, &inc);
+
+ PRINT_VERBOSE(cfg, 1, "arguments definition file %s\n", file);
+
+ if (lt_inc_open(cfg->sh, &inc, file))
+ return -1;
+
+ if (lt_config_parse()) {
+ printf("failed to parse config file %s\n", file);
+ ret = -1;
+ }
+
+ return ret;
+}
+
+#define CHECK_BOOL(str, sval, ival) \
+do { \
+ if (ival != -1) \
+ val = ival; \
+ else if (!strcmp(sval, "YES")) \
+ val = 1; \
+ else if (!strcmp(sval, "NO")) \
+ val = 0; \
+ else \
+ return -1; \
+} while(0)
+
+#define CHECK_INT(val, sval, ival) \
+do { \
+ val = ival; \
+ if (val == -1) \
+ val = atoi(sval); \
+} while(0)
+
+static int process_option_val(struct lt_config_app *cfg, int idx,
+ char *sval, int ival)
+{
+ int val;
+
+ PRINT_VERBOSE(cfg, 1, "option idx %d, sval %s, ival %d\n",
+ idx, sval, ival);
+
+ switch(idx) {
+ case LT_OPT_HEADERS:
+ strcpy(lt_sh(cfg, args_def), sval);
+
+ PRINT_VERBOSE(cfg, 1, "HEADERS '%s'\n",
+ lt_sh(cfg, args_def));
+ break;
+
+ case LT_OPT_INDENT_SYM:
+ CHECK_INT(val, sval, ival);
+ lt_sh(cfg, indent_size) = val;
+
+ PRINT_VERBOSE(cfg, 1, "INDENT_SYM %d\n",
+ lt_sh(cfg, indent_size));
+ break;
+
+ case LT_OPT_PIPE:
+ CHECK_BOOL(val, sval, ival);
+ lt_sh(cfg, pipe) = val;
+
+ PRINT_VERBOSE(cfg, 1, "PIPE %d\n",
+ lt_sh(cfg, pipe));
+ break;
+
+ case LT_OPT_TIMESTAMP:
+ CHECK_BOOL(val, sval, ival);
+ lt_sh(cfg, timestamp) = val;
+
+ PRINT_VERBOSE(cfg, 1, "TIMESTAMP %d\n",
+ lt_sh(cfg, timestamp));
+ break;
+
+ case LT_OPT_FRAMESIZE:
+ CHECK_INT(val, sval, ival);
+ lt_sh(cfg, framesize) = val;
+
+ PRINT_VERBOSE(cfg, 1, "FRAMESIZE %d\n",
+ lt_sh(cfg, framesize));
+ break;
+
+ case LT_OPT_FRAMESIZE_CHECK:
+ CHECK_BOOL(val, sval, ival);
+ lt_sh(cfg, framesize_check) = val;
+
+ PRINT_VERBOSE(cfg, 1, "FRAMESIZE_CHECK %d\n",
+ lt_sh(cfg, framesize_check));
+ break;
+
+ case LT_OPT_HIDE_TID:
+ CHECK_BOOL(val, sval, ival);
+ lt_sh(cfg, hide_tid) = val;
+
+ PRINT_VERBOSE(cfg, 1, "HIDE_TID %d\n",
+ lt_sh(cfg, hide_tid));
+ break;
+
+ case LT_OPT_FOLLOW_FORK:
+ CHECK_BOOL(val, sval, ival);
+ lt_sh(cfg, not_follow_fork) = !val;
+
+ PRINT_VERBOSE(cfg, 1, "NOT FOLLOW_FORK %d\n",
+ lt_sh(cfg, not_follow_fork));
+ break;
+
+ case LT_OPT_FOLLOW_EXEC:
+ CHECK_BOOL(val, sval, ival);
+ lt_sh(cfg, not_follow_exec) = !val;
+
+ PRINT_VERBOSE(cfg, 1, "NOT FOLLOW_EXEC %d\n",
+ lt_sh(cfg, not_follow_exec));
+ break;
+
+ case LT_OPT_DEMANGLE:
+ CHECK_BOOL(val, sval, ival);
+ lt_sh(cfg, demangle) = val;
+
+ PRINT_VERBOSE(cfg, 1, "DEMANGLE %d\n",
+ lt_sh(cfg, demangle));
+ break;
+
+ case LT_OPT_BRACES:
+ CHECK_BOOL(val, sval, ival);
+ lt_sh(cfg, braces) = val;
+
+ PRINT_VERBOSE(cfg, 1, "BRACES %d\n",
+ lt_sh(cfg, braces));
+ break;
+
+ case LT_OPT_ENABLE_ARGS:
+ CHECK_BOOL(val, sval, ival);
+ lt_sh(cfg, args_enabled) = val;
+
+ PRINT_VERBOSE(cfg, 1, "ENABLE_ARGS %d\n",
+ lt_sh(cfg, args_enabled));
+ break;
+
+ case LT_OPT_DETAIL_ARGS:
+ CHECK_BOOL(val, sval, ival);
+ lt_sh(cfg, args_detailed) = val;
+
+ PRINT_VERBOSE(cfg, 1, "DETAIL_ARGS %d\n",
+ lt_sh(cfg, args_detailed));
+ break;
+
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+static int process_option(struct lt_config_app *cfg, struct lt_config_opt *opt)
+{
+ return process_option_val(cfg, opt->idx, opt->sval, opt->nval);
+}
+
+int lt_config_opt_process(struct lt_config_app *cfg, struct lt_list_head *list)
+{
+ struct lt_config_opt *opt;
+
+ lt_list_for_each_entry(opt, list, list) {
+ int ret;
+
+ ret = process_option(cfg, opt);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+struct lt_config_opt *lt_config_opt_new(int idx, char *sval, long nval)
+{
+ struct lt_config_opt *opt;
+
+ opt = malloc(sizeof(*opt));
+ if (!opt)
+ return NULL;
+
+ lt_init_list_head(&opt->list);
+ opt->idx = idx;
+ opt->sval = sval ? strdup(sval) : NULL;
+ opt->nval = nval;
+
+ return opt;
+}
+
int lt_config(struct lt_config_app *cfg, int argc, char **argv)
{
+ char *conf_file = LT_CONF_DIR "/latrace.conf";
+
memset(cfg, 0, sizeof(*cfg));
- cfg->sh = &cfg->sh_storage;
+ cfg->sh = cfg->sh_storage.sh = &cfg->sh_storage;
/* default values settings */
lt_sh(cfg, magic) = LT_CONFIG_MAGIC;
@@ -123,6 +335,15 @@ int lt_config(struct lt_config_app *cfg, int argc, char **argv)
lt_sh(cfg, args_detail_maxlen) = LR_ARGS_DETAIL_MAXLEN;
cfg->csort = LT_CSORT_CALL;
+
+ /* read the default config file first */
+ if (read_config(cfg, conf_file)) {
+ printf("failed: read config file '%s'\n", conf_file);
+ usage();
+ }
+
+ conf_file = NULL;
+
while (1) {
int c;
int option_index = 0;
@@ -142,6 +363,7 @@ int lt_config(struct lt_config_app *cfg, int argc, char **argv)
{"sort-counts", required_argument, 0, 'C'},
{"pipe", no_argument, 0, 'p'},
{"output", required_argument, 0, 'o'},
+ {"conf", required_argument, 0, 'N'},
{"args", required_argument, 0, 'a'},
{"enable-args", required_argument, 0, 'A'},
{"detail-args", required_argument, 0, 'D'},
@@ -159,7 +381,7 @@ int lt_config(struct lt_config_app *cfg, int argc, char **argv)
{0, 0, 0, 0}
};
- c = getopt_long(argc, argv, "+s:n:l:t:f:vhi:BdISb:cC:y:YL:po:a:ADVTFERq",
+ c = getopt_long(argc, argv, "+s:n:l:t:f:vhi:BdISb:cC:y:YL:po:a:N:ADVTFERq",
long_options, &option_index);
if (c == -1)
@@ -213,19 +435,19 @@ int lt_config(struct lt_config_app *cfg, int argc, char **argv)
break;
case 'S':
- lt_sh(cfg, timestamp) = 1;
+ process_option_val(cfg, LT_OPT_TIMESTAMP, NULL, 1);
break;
case 'T':
- lt_sh(cfg, hide_tid) = 1;
+ process_option_val(cfg, LT_OPT_HIDE_TID, NULL, 1);
break;
case 'F':
- lt_sh(cfg, not_follow_fork) = 1;
+ process_option_val(cfg, LT_OPT_FOLLOW_FORK, NULL, 0);
break;
case 'E':
- lt_sh(cfg, not_follow_exec) = 1;
+ process_option_val(cfg, LT_OPT_FOLLOW_EXEC, NULL, 0);
break;
case 'i':
@@ -233,7 +455,7 @@ int lt_config(struct lt_config_app *cfg, int argc, char **argv)
break;
case 'B':
- lt_sh(cfg, braces) = 1;
+ process_option_val(cfg, LT_OPT_BRACES, NULL, 0);
break;
case 'd':
@@ -243,7 +465,7 @@ int lt_config(struct lt_config_app *cfg, int argc, char **argv)
break;
#endif
- lt_sh(cfg, demangle) = 1;
+ process_option_val(cfg, LT_OPT_DEMANGLE, NULL, 0);
break;
case 'I':
@@ -251,11 +473,11 @@ int lt_config(struct lt_config_app *cfg, int argc, char **argv)
break;
case 'y':
- lt_sh(cfg, framesize) = atoi(optarg);
+ process_option_val(cfg, LT_OPT_FRAMESIZE, optarg, -1);
break;
case 'Y':
- lt_sh(cfg, framesize_check) = 0;
+ process_option_val(cfg, LT_OPT_FRAMESIZE_CHECK, NULL, 0);
break;
case 'L':
@@ -274,7 +496,7 @@ int lt_config(struct lt_config_app *cfg, int argc, char **argv)
lt_sh(cfg, counts) = 1;
/* falling through */
case 'p':
- lt_sh(cfg, pipe) = 1;
+ process_option_val(cfg, LT_OPT_PIPE, NULL, 1);
break;
#ifndef CONFIG_ARCH_HAVE_ARGS
@@ -285,18 +507,22 @@ int lt_config(struct lt_config_app *cfg, int argc, char **argv)
break;
#else
case 'a':
- strcpy(lt_sh(cfg, args_def), optarg);
+ process_option_val(cfg, LT_OPT_HEADERS, optarg, -1);
+
/* falling through */
case 'A':
-
- lt_sh(cfg, args_enabled) = 1;
+ process_option_val(cfg, LT_OPT_ENABLE_ARGS, NULL, 1);
break;
case 'D':
- lt_sh(cfg, args_detailed) = 1;
+ process_option_val(cfg, LT_OPT_DETAIL_ARGS, NULL, 1);
break;
#endif /* CONFIG_ARCH_HAVE_ARGS */
+ case 'N':
+ conf_file = optarg;
+ break;
+
case 'o':
strcpy(lt_sh(cfg, output), optarg);
break;
@@ -332,6 +558,12 @@ int lt_config(struct lt_config_app *cfg, int argc, char **argv)
cfg->arg_num = i_arg;
}
+ /* read user-specifide config file */
+ if (conf_file && read_config(cfg, conf_file)) {
+ printf("failed: read config file '%s'\n", conf_file);
+ usage();
+ }
+
if (!cfg->prog) {
printf("failed: no program specified\n");
usage();
diff --git a/src/config.h b/src/config.h
index c7f88ee..9bdae88 100644
--- a/src/config.h
+++ b/src/config.h
@@ -70,6 +70,29 @@ struct lt_config_tv {
char *name;
};
+enum {
+ LT_OPT_HEADERS = 1,
+ LT_OPT_PIPE,
+ LT_OPT_INDENT_SYM,
+ LT_OPT_TIMESTAMP,
+ LT_OPT_FRAMESIZE,
+ LT_OPT_FRAMESIZE_CHECK,
+ LT_OPT_HIDE_TID,
+ LT_OPT_FOLLOW_FORK,
+ LT_OPT_FOLLOW_EXEC,
+ LT_OPT_DEMANGLE,
+ LT_OPT_BRACES,
+ LT_OPT_ENABLE_ARGS,
+ LT_OPT_DETAIL_ARGS,
+};
+
+struct lt_config_opt {
+ int idx;
+ char *sval;
+ unsigned long nval;
+ struct lt_list_head list;
+};
+
struct lt_config_shared {
#define LT_CONFIG_VERSION 1
#define LT_CONFIG_MAGIC ((LT_CONFIG_VERSION << 16) + 0xdead)
@@ -323,6 +346,10 @@ struct lt_symbol* lt_symbol_bind(struct lt_config_shared *cfg,
struct lt_symbol* lt_symbol_get(struct lt_config_shared *cfg,
void *ptr, const char *name);
+/* config options */
+struct lt_config_opt *lt_config_opt_new(int idx, char *sval, long nval);
+int lt_config_opt_process(struct lt_config_app *cfg, struct lt_list_head *list);
+
#define PRINT(fmt, args...) \
do { \
char lpbuf[1024]; \
diff --git a/src/lib-include.c b/src/lib-include.c
new file mode 100644
index 0000000..afdabf8
--- /dev/null
+++ b/src/lib-include.c
@@ -0,0 +1,161 @@
+/*
+ Copyright (C) 2011 Jiri Olsa <olsajiri@gmail.com>
+
+ This file is part of the latrace.
+
+ The latrace is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ The latrace 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the latrace (file COPYING). If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include "config.h"
+#include "lib-include.h"
+
+#define YY_BUF_SIZE 16384
+
+extern int errno;
+
+static FILE* open_include_dir(struct lt_config_shared *cfg, char *file,
+ char *dir)
+{
+ FILE *f;
+ char fn[LT_MAXFILE];
+ int len_file, len_dir;
+
+ len_file = strlen(file);
+ len_dir = strlen(dir);
+
+ if (len_file > (LT_MAXFILE - len_dir - 1)) {
+ printf("file name length crossed the max %u: %s\n",
+ (u_int) (LT_MAXFILE - len_dir), file);
+ return NULL;
+ }
+
+ sprintf(fn, "%s/%s", dir, file);
+
+ f = fopen(fn, "r");
+ if (f) {
+ PRINT_VERBOSE(cfg, 1, "open ok [%s]\n", fn);
+ return f;
+ }
+
+ PRINT_VERBOSE(cfg, 1, "open failed [%s]: %s\n",
+ fn, strerror(errno));
+ return NULL;
+}
+
+static FILE* open_include(struct lt_config_shared *cfg, char *file)
+{
+ FILE *f;
+
+ /* we got an absolute path */
+ if ((NULL != (f = fopen(file, "r")))) {
+ PRINT_VERBOSE(cfg, 1, "open ok [%s]\n", file);
+ return f;
+ }
+
+ /* give up if there was already the absolute name */
+ if (*file == '/') {
+ printf("open failed [%s]: %s\n", file, strerror(errno));
+ return NULL;
+ }
+
+ PRINT_VERBOSE(cfg, 1, "open failed [%s]: %s\n",
+ file, strerror(errno));
+
+ /* not an absolute name, give it a chance
+ inside of the LT_CONF_DIR directory */
+ f = open_include_dir(cfg, file, LT_CONF_DIR);
+ if (f)
+ return f;
+
+ /* not in LT_CONF_DIR directory, give it a chance
+ inside of the LT_CONF_HEADERS_DIR directory */
+ f = open_include_dir(cfg, file, LT_CONF_HEADERS_DIR);
+ if (f)
+ return f;
+
+ return NULL;
+}
+
+int lt_inc_open(struct lt_config_shared *cfg, struct lt_include *inc,
+ char *file)
+{
+ struct lt_include_stack *inc_stack;
+ FILE *f;
+
+ PRINT_VERBOSE(cfg, 1, "opening buffer for [%s] depth %d\n",
+ file, inc->stack_idx);
+
+ if ((inc->stack_idx + 1) == MAX_INCLUDE_DEPTH) {
+ printf("include depth overstep");
+ return -1;
+ }
+
+ if (NULL == (f = open_include(cfg, file)))
+ return -1;
+
+ *inc->in = f;
+
+ inc_stack = &inc->stack[inc->stack_idx++];
+ memset(inc_stack, 0, sizeof(*inc_stack));
+
+ inc_stack->in = f;
+ inc_stack->file = strdup(file);
+ inc_stack->lineno = 1;
+ inc_stack->buf = inc->create_buffer(f, YY_BUF_SIZE);
+
+ inc->switch_to_buffer(inc_stack->buf);
+
+ PRINT_VERBOSE(cfg, 1, "opened buffer for [%s] depth %d\n",
+ file, inc->stack_idx);
+ return 0;
+}
+
+int lt_inc_close(struct lt_config_shared *cfg, struct lt_include *inc)
+{
+ struct lt_include_stack *inc_stack = &inc->stack[--inc->stack_idx];
+
+ PRINT_VERBOSE(cfg, 1, "buffer closed [%s], depth [%d]\n",
+ inc_stack->file, inc->stack_idx);
+
+ free(inc_stack->file);
+
+ /* EOF with no other includes on stack */
+ if (!inc->stack_idx)
+ return -1;
+
+ /* looks like the base buffer is cleaned up by the
+ flex itself, so we do the actual cleaning
+ only for includes */
+ inc->delete_buffer(inc_stack->buf);
+ fclose(inc_stack->in);
+
+ inc_stack = &inc->stack[inc->stack_idx - 1];
+ inc->switch_to_buffer(inc_stack->buf);
+ return 0;
+}
+
+struct lt_include_stack* lt_inc_stack(struct lt_include *inc)
+{
+ struct lt_include_stack *inc_stack = &inc->stack[inc->stack_idx - 1];
+ return inc_stack;
+}
diff --git a/src/lib-include.h b/src/lib-include.h
new file mode 100644
index 0000000..e5647fd
--- /dev/null
+++ b/src/lib-include.h
@@ -0,0 +1,61 @@
+/*
+ Copyright (C) 2011 Jiri Olsa <olsajiri@gmail.com>
+
+ This file is part of the latrace.
+
+ The latrace is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ The latrace 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the latrace (file COPYING). If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef LIB_INCLUDE_H
+#define LIB_INCLUDE_H
+
+#include <stdio.h>
+#include "config.h"
+
+#define MAX_INCLUDE_DEPTH 10
+
+struct lt_include_stack {
+ FILE *in;
+ void *buf;
+ char *file;
+ int lineno;
+};
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+typedef YY_BUFFER_STATE (*yy_create_buffer_t)(FILE*, int);
+typedef void (*yy_switch_to_buffer_t)(YY_BUFFER_STATE);
+typedef void (*yy_delete_buffer_t)(YY_BUFFER_STATE);
+
+struct lt_include {
+ struct lt_include_stack stack[MAX_INCLUDE_DEPTH];
+ int stack_idx;
+
+ FILE **in;
+ yy_create_buffer_t create_buffer;
+ yy_switch_to_buffer_t switch_to_buffer;
+ yy_delete_buffer_t delete_buffer;
+};
+
+int lt_inc_open(struct lt_config_shared *cfg, struct lt_include *inc,
+ char *file);
+int lt_inc_close(struct lt_config_shared *cfg, struct lt_include *inc);
+struct lt_include_stack* lt_inc_stack(struct lt_include *inc);
+
+#endif /* LIB_INCLUDE_H */
diff --git a/src/sysdeps/x86_64/args.h b/src/sysdeps/x86_64/args.h
index 125c0a1..caa91a6 100644
--- a/src/sysdeps/x86_64/args.h
+++ b/src/sysdeps/x86_64/args.h
@@ -31,8 +31,8 @@ char* lt_args_arch_conf(struct lt_config_shared *cfg)
static char buf[LT_MAXFILE];
sprintf(buf, "%s/%s",
- LT_ARGS_DEF_DIR,
- "sysdeps/x86_64/latrace.conf");
+ LT_CONF_HEADERS_DIR,
+ "sysdeps/x86_64/latrace.h");
return buf;
}