mirror of https://github.com/tstack/lnav
[cleanup] start a tracer/debugger for the data parser
parent
e71a85d471
commit
5d478fc17a
@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* Written by Alexey Tourbin <at@altlinux.org>.
|
||||||
|
*
|
||||||
|
* The author has dedicated the code to the public domain. Anyone is free
|
||||||
|
* to copy, modify, publish, use, compile, sell, or distribute the original
|
||||||
|
* code, either in source code form or as a compiled binary, for any purpose,
|
||||||
|
* commercial or non-commercial, and by any means.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sqlite3.h>
|
||||||
|
|
||||||
|
#include "pcrepp.hh"
|
||||||
|
|
||||||
|
#include "sqlite-extension-func.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *s;
|
||||||
|
pcre *p;
|
||||||
|
pcre_extra *e;
|
||||||
|
} cache_entry;
|
||||||
|
|
||||||
|
#ifndef CACHE_SIZE
|
||||||
|
#define CACHE_SIZE 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static
|
||||||
|
void regexp(sqlite3_context *ctx, int argc, sqlite3_value **argv)
|
||||||
|
{
|
||||||
|
const char *re, *str;
|
||||||
|
pcre *p;
|
||||||
|
pcre_extra *e;
|
||||||
|
|
||||||
|
assert(argc == 2);
|
||||||
|
|
||||||
|
re = (const char *) sqlite3_value_text(argv[0]);
|
||||||
|
if (!re) {
|
||||||
|
sqlite3_result_error(ctx, "no regexp", -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
str = (const char *) sqlite3_value_text(argv[1]);
|
||||||
|
if (!str) {
|
||||||
|
sqlite3_result_error(ctx, "no string", -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* simple LRU cache */
|
||||||
|
{
|
||||||
|
static cache_entry cache[CACHE_SIZE];
|
||||||
|
int i;
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < CACHE_SIZE && cache[i].s; i++) {
|
||||||
|
if (strcmp(re, cache[i].s) == 0) {
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
|
if (i > 0) {
|
||||||
|
cache_entry c = cache[i];
|
||||||
|
memmove(cache + 1, cache, i * sizeof(cache_entry));
|
||||||
|
cache[0] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cache_entry c;
|
||||||
|
const char *err;
|
||||||
|
int pos;
|
||||||
|
c.p = pcre_compile(re, 0, &err, &pos, NULL);
|
||||||
|
if (!c.p) {
|
||||||
|
char *e2 = sqlite3_mprintf("%s: %s (offset %d)", re, err, pos);
|
||||||
|
sqlite3_result_error(ctx, e2, -1);
|
||||||
|
sqlite3_free(e2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
c.e = pcre_study(c.p, 0, &err);
|
||||||
|
c.s = strdup(re);
|
||||||
|
if (!c.s) {
|
||||||
|
sqlite3_result_error(ctx, "strdup: ENOMEM", -1);
|
||||||
|
pcre_free(c.p);
|
||||||
|
pcre_free(c.e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
i = CACHE_SIZE - 1;
|
||||||
|
if (cache[i].s) {
|
||||||
|
free(cache[i].s);
|
||||||
|
assert(cache[i].p);
|
||||||
|
pcre_free(cache[i].p);
|
||||||
|
pcre_free(cache[i].e);
|
||||||
|
}
|
||||||
|
memmove(cache + 1, cache, i * sizeof(cache_entry));
|
||||||
|
cache[0] = c;
|
||||||
|
}
|
||||||
|
p = cache[0].p;
|
||||||
|
e = cache[0].e;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
assert(p);
|
||||||
|
rc = pcre_exec(p, e, str, strlen(str), 0, 0, NULL, 0);
|
||||||
|
sqlite3_result_int(ctx, rc >= 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int string_extension_functions(const struct FuncDef **basic_funcs,
|
||||||
|
const struct FuncDefAgg **agg_funcs)
|
||||||
|
{
|
||||||
|
static const struct FuncDef string_funcs[] = {
|
||||||
|
{ "regexp", 2, 0, SQLITE_UTF8, 0, regexp },
|
||||||
|
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
*basic_funcs = string_funcs;
|
||||||
|
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
time_t time(time_t *loc)
|
||||||
|
{
|
||||||
|
time_t retval = 1370546000;
|
||||||
|
|
||||||
|
if (loc != NULL) {
|
||||||
|
*loc = retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
2013-06-05T14:20:24 DEBUG cc2.main CC - 4672610200547811617359537811896212984085567168.114723023 Json_Reader - Doing prepare for resource name "Json_Reader", component "com.json.components.JSONReader"
|
||||||
|
key 26:26 ^
|
||||||
|
sym 26:34 ^------^ cc2.main
|
||||||
|
pair 26:34 ^------^ cc2.main
|
||||||
|
key 35:35 ^
|
||||||
|
sym 35:37 ^^ CC
|
||||||
|
pair 35:37 ^^ CC
|
||||||
|
key 38:38 ^
|
||||||
|
sym 38:39 ^ -
|
||||||
|
pair 38:39 ^ -
|
||||||
|
key 40:40 ^
|
||||||
|
num 40:96 ^------------------------------------------------------^ 4672610200547811617359537811896212984085567168.114723023
|
||||||
|
pair 40:96 ^------------------------------------------------------^ 4672610200547811617359537811896212984085567168.114723023
|
||||||
|
key 97:97 ^
|
||||||
|
sym 97:108 ^---------^ Json_Reader
|
||||||
|
pair 97:108 ^---------^ Json_Reader
|
||||||
|
key 109:109 ^
|
||||||
|
sym 109:110 ^ -
|
||||||
|
pair 109:110 ^ -
|
||||||
|
key 144:144 ^
|
||||||
|
quot 144:155 ^---------^ Json_Reader
|
||||||
|
pair 144:155 ^---------^ Json_Reader
|
||||||
|
key 169:169 ^
|
||||||
|
quot 169:199 ^----------------------------^ com.json.components.JSONReader
|
||||||
|
pair 169:199 ^----------------------------^ com.json.components.JSONReader
|
@ -0,0 +1,204 @@
|
|||||||
|
#! /usr/bin/env python
|
||||||
|
|
||||||
|
# Copyright (c) 2013, Timothy Stack
|
||||||
|
#
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
# list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer in the documentation
|
||||||
|
# and/or other materials provided with the distribution.
|
||||||
|
# * Neither the name of Timothy Stack nor the names of its contributors
|
||||||
|
# may be used to endorse or promote products derived from this software
|
||||||
|
# without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||||
|
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import string
|
||||||
|
import readline
|
||||||
|
import itertools
|
||||||
|
import collections
|
||||||
|
|
||||||
|
TEST_DIR = os.path.dirname(__file__)
|
||||||
|
ROOT_DIR = os.path.dirname(TEST_DIR)
|
||||||
|
SRC_DIR = os.path.join(ROOT_DIR, "src")
|
||||||
|
|
||||||
|
addr_to_name = {}
|
||||||
|
name_to_addr = {}
|
||||||
|
element_lists = collections.defaultdict(list)
|
||||||
|
breakpoints = set()
|
||||||
|
|
||||||
|
def completer(text, state):
|
||||||
|
options = [x for x in itertools.chain(name_to_addr,
|
||||||
|
element_lists,
|
||||||
|
breakpoints)
|
||||||
|
if x.startswith(text)]
|
||||||
|
try:
|
||||||
|
return options[state]
|
||||||
|
except IndexError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
readline.set_completer(completer)
|
||||||
|
|
||||||
|
if 'libedit' in readline.__doc__:
|
||||||
|
readline.parse_and_bind('bind ^I rl_complete')
|
||||||
|
else:
|
||||||
|
readline.parse_and_bind('tab: complete')
|
||||||
|
|
||||||
|
input_line = ''
|
||||||
|
ops = []
|
||||||
|
for line in open("scanned.dpt"):
|
||||||
|
if line.startswith("input "):
|
||||||
|
input_line = line[6:-1]
|
||||||
|
else:
|
||||||
|
ops.append(map(string.strip, line.split()))
|
||||||
|
|
||||||
|
def getstr(capture):
|
||||||
|
start, end = capture.split(':')
|
||||||
|
return input_line[int(start):int(end)]
|
||||||
|
|
||||||
|
def printlist(name_or_addr):
|
||||||
|
if name_or_addr in name_to_addr:
|
||||||
|
print "(%s) %s" % (name_or_addr, element_lists[name_to_addr[name_or_addr]])
|
||||||
|
elif name_or_addr in element_lists:
|
||||||
|
print "(%s) %s" % (addr_to_name.get(name_or_addr, name_or_addr),
|
||||||
|
element_lists[name_or_addr])
|
||||||
|
else:
|
||||||
|
print "error: unknown list --", name_or_addr
|
||||||
|
|
||||||
|
def handleop(fields):
|
||||||
|
addr = fields[0]
|
||||||
|
loc = fields[1].split(':')
|
||||||
|
method_name = fields[2]
|
||||||
|
method_args = fields[3:]
|
||||||
|
|
||||||
|
if addr == '0x0':
|
||||||
|
el = None
|
||||||
|
else:
|
||||||
|
el = element_lists[addr]
|
||||||
|
|
||||||
|
if method_name == 'element_list_t':
|
||||||
|
addr_to_name[addr] = method_args[0]
|
||||||
|
name_to_addr[method_args[0]] = addr
|
||||||
|
elif method_name == '~element_list_t':
|
||||||
|
pass
|
||||||
|
elif method_name == 'push_back':
|
||||||
|
el.append((method_args[0], getstr(method_args[1])))
|
||||||
|
elif method_name == 'pop_front':
|
||||||
|
el.pop(0)
|
||||||
|
elif method_name == 'pop_back':
|
||||||
|
el.pop()
|
||||||
|
elif method_name == 'splice':
|
||||||
|
pos = int(method_args[0])
|
||||||
|
other = element_lists[method_args[1]]
|
||||||
|
start, from_end = map(int, method_args[2].split(':'))
|
||||||
|
end = len(other) - from_end
|
||||||
|
sub_list = other[start:end]
|
||||||
|
del other[start:end]
|
||||||
|
el[pos:pos] = sub_list
|
||||||
|
elif method_name == 'point':
|
||||||
|
breakpoints.add(method_args[0])
|
||||||
|
else:
|
||||||
|
print "Unhandled method: ", method_name
|
||||||
|
|
||||||
|
def playupto(length):
|
||||||
|
addr_to_name.clear()
|
||||||
|
name_to_addr.clear()
|
||||||
|
element_lists.clear()
|
||||||
|
for index in range(length):
|
||||||
|
handleop(ops[index])
|
||||||
|
|
||||||
|
def find_prev_point(start, name):
|
||||||
|
orig_start = start
|
||||||
|
while start > 0:
|
||||||
|
start -= 1;
|
||||||
|
fields = ops[start]
|
||||||
|
if fields[2] != 'point':
|
||||||
|
continue
|
||||||
|
if not name or fields[3] == name:
|
||||||
|
return start + 1
|
||||||
|
return orig_start + 1
|
||||||
|
|
||||||
|
def find_next_point(start, name):
|
||||||
|
orig_start = start
|
||||||
|
while start < len(ops):
|
||||||
|
start += 1;
|
||||||
|
fields = ops[start]
|
||||||
|
if fields[2] != 'point':
|
||||||
|
continue
|
||||||
|
if not name or fields[3] == name:
|
||||||
|
return start + 1
|
||||||
|
return orig_start + 1
|
||||||
|
|
||||||
|
index = len(ops)
|
||||||
|
last_cmd = ['']
|
||||||
|
watch_list = set()
|
||||||
|
while True:
|
||||||
|
playupto(index)
|
||||||
|
|
||||||
|
if index == 0:
|
||||||
|
print "init"
|
||||||
|
else:
|
||||||
|
print "#%s %s" % (index -1, ops[index - 1])
|
||||||
|
|
||||||
|
for list_name in watch_list:
|
||||||
|
printlist(list_name)
|
||||||
|
|
||||||
|
try:
|
||||||
|
cmd = raw_input("> ").split()
|
||||||
|
except EOFError:
|
||||||
|
print
|
||||||
|
break
|
||||||
|
|
||||||
|
if not cmd or cmd[0] == '':
|
||||||
|
cmd = last_cmd
|
||||||
|
|
||||||
|
if not cmd or cmd[0] == '':
|
||||||
|
pass
|
||||||
|
elif cmd[0] == 'q':
|
||||||
|
break
|
||||||
|
elif cmd[0] == 'n':
|
||||||
|
if index < len(ops):
|
||||||
|
index += 1
|
||||||
|
elif cmd[0] == 'r':
|
||||||
|
if index > 0:
|
||||||
|
index -= 1
|
||||||
|
elif cmd[0] == 'b':
|
||||||
|
if len(cmd) == 1:
|
||||||
|
cmd.append('')
|
||||||
|
|
||||||
|
index = find_prev_point(index - 1, cmd[1])
|
||||||
|
elif cmd[0] == 'c':
|
||||||
|
if len(cmd) == 1:
|
||||||
|
cmd.append('')
|
||||||
|
index = find_next_point(index - 1, cmd[1])
|
||||||
|
elif cmd[0] == 'p':
|
||||||
|
if len(cmd) > 1:
|
||||||
|
printlist(cmd[1])
|
||||||
|
else:
|
||||||
|
print input_line
|
||||||
|
for addr in element_lists:
|
||||||
|
printlist(addr)
|
||||||
|
elif cmd[0] == 'w':
|
||||||
|
watch_list.add(cmd[1])
|
||||||
|
elif cmd[0] == 'u':
|
||||||
|
watch_list.remove(cmd[1])
|
||||||
|
else:
|
||||||
|
print "error: unknown command --", cmd
|
||||||
|
|
||||||
|
last_cmd = cmd
|
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS person (
|
||||||
|
id integer PRIMARY KEY,
|
||||||
|
first_name text,
|
||||||
|
last_name text,
|
||||||
|
age integer
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO person (id, first_name, last_name, age)
|
||||||
|
VALUES (0, "Phil", "Myman", 30);
|
||||||
|
INSERT INTO person (id, first_name, last_name, age)
|
||||||
|
VALUES (1, "Lem", "Hewitt", 35);
|
@ -0,0 +1,6 @@
|
|||||||
|
sleep 0.913123
|
||||||
|
write 3b
|
||||||
|
sleep 0.822303
|
||||||
|
write 73656c656374202a2066726f6d20706572736f6e206f726465722062792061676520646573633b0d
|
||||||
|
sleep 9.068423
|
||||||
|
write 71
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue