readapt 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +16 -16
- data/.rspec +2 -2
- data/.travis.yml +19 -18
- data/CHANGELOG.md +87 -83
- data/Gemfile +4 -4
- data/LICENSE.txt +21 -21
- data/README.md +37 -37
- data/Rakefile +14 -14
- data/bin/console +14 -14
- data/bin/setup +8 -8
- data/exe/readapt +5 -5
- data/ext/readapt/breakpoints.c +83 -83
- data/ext/readapt/breakpoints.h +11 -11
- data/ext/readapt/extconf.rb +0 -0
- data/ext/readapt/frame.c +137 -137
- data/ext/readapt/frame.h +17 -17
- data/ext/readapt/inspector.c +51 -51
- data/ext/readapt/inspector.h +8 -8
- data/ext/readapt/lookup_table.c +211 -211
- data/ext/readapt/lookup_table.h +30 -30
- data/ext/readapt/monitor.c +0 -0
- data/ext/readapt/monitor.h +0 -0
- data/ext/readapt/normalize.c +59 -59
- data/ext/readapt/normalize.h +7 -7
- data/ext/readapt/readapt.c +18 -18
- data/ext/readapt/stack.c +86 -86
- data/ext/readapt/stack.h +20 -20
- data/ext/readapt/threads.c +0 -0
- data/ext/readapt/threads.h +0 -0
- data/lib/readapt.rb +21 -21
- data/lib/readapt/adapter.rb +98 -98
- data/lib/readapt/breakpoint.rb +21 -21
- data/lib/readapt/data_reader.rb +62 -62
- data/lib/readapt/debugger.rb +228 -220
- data/lib/readapt/error.rb +63 -63
- data/lib/readapt/finder.rb +34 -34
- data/lib/readapt/frame.rb +40 -40
- data/lib/readapt/input.rb +7 -7
- data/lib/readapt/message.rb +62 -62
- data/lib/readapt/message/attach.rb +11 -11
- data/lib/readapt/message/base.rb +32 -32
- data/lib/readapt/message/configuration_done.rb +11 -11
- data/lib/readapt/message/continue.rb +15 -15
- data/lib/readapt/message/disconnect.rb +13 -13
- data/lib/readapt/message/evaluate.rb +18 -18
- data/lib/readapt/message/initialize.rb +21 -13
- data/lib/readapt/message/launch.rb +11 -11
- data/lib/readapt/message/next.rb +12 -12
- data/lib/readapt/message/pause.rb +11 -11
- data/lib/readapt/message/scopes.rb +26 -26
- data/lib/readapt/message/set_breakpoints.rb +25 -25
- data/lib/readapt/message/set_exception_breakpoints.rb +11 -8
- data/lib/readapt/message/stack_trace.rb +38 -38
- data/lib/readapt/message/step_in.rb +11 -11
- data/lib/readapt/message/step_out.rb +11 -11
- data/lib/readapt/message/threads.rb +18 -18
- data/lib/readapt/message/variables.rb +53 -53
- data/lib/readapt/monitor.rb +0 -0
- data/lib/readapt/output.rb +25 -25
- data/lib/readapt/references.rb +27 -27
- data/lib/readapt/server.rb +22 -22
- data/lib/readapt/shell.rb +104 -104
- data/lib/readapt/snapshot.rb +0 -0
- data/lib/readapt/thread.rb +25 -25
- data/lib/readapt/variable.rb +0 -0
- data/lib/readapt/version.rb +3 -3
- data/readapt.gemspec +39 -39
- metadata +7 -7
data/ext/readapt/frame.h
CHANGED
@@ -1,17 +1,17 @@
|
|
1
|
-
#ifndef FRAME_H_
|
2
|
-
#define FRAME_H_
|
3
|
-
|
4
|
-
#include "ruby.h"
|
5
|
-
|
6
|
-
typedef struct frame_struct {
|
7
|
-
char *file;
|
8
|
-
int line;
|
9
|
-
VALUE binding;
|
10
|
-
} frame_t;
|
11
|
-
|
12
|
-
void initialize_frame(VALUE);
|
13
|
-
frame_t *frame_data_from_tracepoint(VALUE);
|
14
|
-
VALUE frame_new_from_data(frame_t *);
|
15
|
-
void frame_free(void *);
|
16
|
-
|
17
|
-
#endif
|
1
|
+
#ifndef FRAME_H_
|
2
|
+
#define FRAME_H_
|
3
|
+
|
4
|
+
#include "ruby.h"
|
5
|
+
|
6
|
+
typedef struct frame_struct {
|
7
|
+
char *file;
|
8
|
+
int line;
|
9
|
+
VALUE binding;
|
10
|
+
} frame_t;
|
11
|
+
|
12
|
+
void initialize_frame(VALUE);
|
13
|
+
frame_t *frame_data_from_tracepoint(VALUE);
|
14
|
+
VALUE frame_new_from_data(frame_t *);
|
15
|
+
void frame_free(void *);
|
16
|
+
|
17
|
+
#endif
|
data/ext/readapt/inspector.c
CHANGED
@@ -1,51 +1,51 @@
|
|
1
|
-
#include "ruby.h"
|
2
|
-
#include "ruby/debug.h"
|
3
|
-
#include "frame.h"
|
4
|
-
#include "threads.h"
|
5
|
-
#include "normalize.h"
|
6
|
-
|
7
|
-
static VALUE process_inspection(const rb_debug_inspector_t *inspector, void *ptr)
|
8
|
-
{
|
9
|
-
VALUE locations;
|
10
|
-
long i_size;
|
11
|
-
long i;
|
12
|
-
VALUE loc;
|
13
|
-
VALUE path;
|
14
|
-
int line;
|
15
|
-
VALUE bnd;
|
16
|
-
thread_reference_t *data;
|
17
|
-
frame_t *frm;
|
18
|
-
VALUE iseq;
|
19
|
-
|
20
|
-
data = ptr;
|
21
|
-
|
22
|
-
locations = rb_debug_inspector_backtrace_locations(inspector);
|
23
|
-
i_size = locations == Qnil ? 0 : RARRAY_LENINT(locations);
|
24
|
-
for (i = i_size - 1; i >= 0; i--)
|
25
|
-
{
|
26
|
-
iseq = rb_debug_inspector_frame_iseq_get(inspector, i);
|
27
|
-
if (iseq != Qnil)
|
28
|
-
{
|
29
|
-
loc = rb_ary_entry(locations, i);
|
30
|
-
path = rb_funcall(loc, rb_intern("absolute_path"), 0);
|
31
|
-
line = NUM2INT(rb_funcall(loc, rb_intern("lineno"), 0));
|
32
|
-
bnd = rb_debug_inspector_frame_binding_get(inspector, i);
|
33
|
-
|
34
|
-
frm = malloc(sizeof(frame_t));
|
35
|
-
frm->file = normalize_path_new_cstr(StringValueCStr(path));
|
36
|
-
frm->line = line;
|
37
|
-
frm->binding = bnd;
|
38
|
-
stack_push(data->frames, frm);
|
39
|
-
}
|
40
|
-
}
|
41
|
-
|
42
|
-
return Qnil;
|
43
|
-
}
|
44
|
-
|
45
|
-
/**
|
46
|
-
* Get an array of frames from the Ruby debug inspector.
|
47
|
-
*/
|
48
|
-
void inspector_inspect(thread_reference_t *data)
|
49
|
-
{
|
50
|
-
rb_debug_inspector_open(process_inspection, (void *)data);
|
51
|
-
}
|
1
|
+
#include "ruby.h"
|
2
|
+
#include "ruby/debug.h"
|
3
|
+
#include "frame.h"
|
4
|
+
#include "threads.h"
|
5
|
+
#include "normalize.h"
|
6
|
+
|
7
|
+
static VALUE process_inspection(const rb_debug_inspector_t *inspector, void *ptr)
|
8
|
+
{
|
9
|
+
VALUE locations;
|
10
|
+
long i_size;
|
11
|
+
long i;
|
12
|
+
VALUE loc;
|
13
|
+
VALUE path;
|
14
|
+
int line;
|
15
|
+
VALUE bnd;
|
16
|
+
thread_reference_t *data;
|
17
|
+
frame_t *frm;
|
18
|
+
VALUE iseq;
|
19
|
+
|
20
|
+
data = ptr;
|
21
|
+
|
22
|
+
locations = rb_debug_inspector_backtrace_locations(inspector);
|
23
|
+
i_size = locations == Qnil ? 0 : RARRAY_LENINT(locations);
|
24
|
+
for (i = i_size - 1; i >= 0; i--)
|
25
|
+
{
|
26
|
+
iseq = rb_debug_inspector_frame_iseq_get(inspector, i);
|
27
|
+
if (iseq != Qnil)
|
28
|
+
{
|
29
|
+
loc = rb_ary_entry(locations, i);
|
30
|
+
path = rb_funcall(loc, rb_intern("absolute_path"), 0);
|
31
|
+
line = NUM2INT(rb_funcall(loc, rb_intern("lineno"), 0));
|
32
|
+
bnd = rb_debug_inspector_frame_binding_get(inspector, i);
|
33
|
+
|
34
|
+
frm = malloc(sizeof(frame_t));
|
35
|
+
frm->file = normalize_path_new_cstr(StringValueCStr(path));
|
36
|
+
frm->line = line;
|
37
|
+
frm->binding = bnd;
|
38
|
+
stack_push(data->frames, frm);
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
return Qnil;
|
43
|
+
}
|
44
|
+
|
45
|
+
/**
|
46
|
+
* Get an array of frames from the Ruby debug inspector.
|
47
|
+
*/
|
48
|
+
void inspector_inspect(thread_reference_t *data)
|
49
|
+
{
|
50
|
+
rb_debug_inspector_open(process_inspection, (void *)data);
|
51
|
+
}
|
data/ext/readapt/inspector.h
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
#ifndef INSPECTOR_H_
|
2
|
-
#define INSPECTOR_H_
|
3
|
-
|
4
|
-
#include "ruby.h"
|
5
|
-
|
6
|
-
void inspector_inspect(thread_reference_t *);
|
7
|
-
|
8
|
-
#endif
|
1
|
+
#ifndef INSPECTOR_H_
|
2
|
+
#define INSPECTOR_H_
|
3
|
+
|
4
|
+
#include "ruby.h"
|
5
|
+
|
6
|
+
void inspector_inspect(thread_reference_t *);
|
7
|
+
|
8
|
+
#endif
|
data/ext/readapt/lookup_table.c
CHANGED
@@ -1,211 +1,211 @@
|
|
1
|
-
#include <math.h>
|
2
|
-
#include <stdlib.h>
|
3
|
-
#include <string.h>
|
4
|
-
|
5
|
-
#include "lookup_table.h"
|
6
|
-
|
7
|
-
static lt_long_array *copy_array(const long *value, const long size)
|
8
|
-
{
|
9
|
-
long i;
|
10
|
-
long *items = malloc(sizeof(long) * size);
|
11
|
-
lt_long_array *result;
|
12
|
-
|
13
|
-
for (i = 0; i < size; i++)
|
14
|
-
{
|
15
|
-
items[i] = value[i];
|
16
|
-
}
|
17
|
-
result = malloc(sizeof(lt_long_array));
|
18
|
-
result->items = (size ? items : NULL);
|
19
|
-
result->size = size;
|
20
|
-
return result;
|
21
|
-
}
|
22
|
-
|
23
|
-
/*
|
24
|
-
* Initialize a new item
|
25
|
-
*/
|
26
|
-
static lt_item *lt_new_item(char *key, const long *value, const long size)
|
27
|
-
{
|
28
|
-
lt_item *i = malloc(sizeof(lt_item));
|
29
|
-
i->key = malloc(sizeof(char) * (strlen(key) + 1));
|
30
|
-
strcpy(i->key, key);
|
31
|
-
i->value = copy_array(value, size);
|
32
|
-
return i;
|
33
|
-
}
|
34
|
-
|
35
|
-
/*
|
36
|
-
* Delete the lt_item
|
37
|
-
*/
|
38
|
-
static void lt_del_item(lt_item *i)
|
39
|
-
{
|
40
|
-
free(i->key);
|
41
|
-
free(i->value->items);
|
42
|
-
free(i);
|
43
|
-
}
|
44
|
-
|
45
|
-
/*
|
46
|
-
* Initialize a new empty lookup table
|
47
|
-
*/
|
48
|
-
lt_lookup_table *lt_new()
|
49
|
-
{
|
50
|
-
lt_lookup_table *ht = malloc(sizeof(lt_lookup_table));
|
51
|
-
ht->items = NULL;
|
52
|
-
ht->size = 0;
|
53
|
-
return ht;
|
54
|
-
}
|
55
|
-
|
56
|
-
/*
|
57
|
-
* Delete the lookup table
|
58
|
-
*/
|
59
|
-
void lt_del_lookup_table(lt_lookup_table *ht)
|
60
|
-
{
|
61
|
-
int i;
|
62
|
-
lt_item *item;
|
63
|
-
|
64
|
-
// Iterate through items and delete any that are found
|
65
|
-
for (i = 0; i < ht->size; i++)
|
66
|
-
{
|
67
|
-
item = ht->items[i];
|
68
|
-
lt_del_item(item);
|
69
|
-
}
|
70
|
-
free(ht->items);
|
71
|
-
free(ht);
|
72
|
-
}
|
73
|
-
|
74
|
-
static lt_long_array *lt_search_part(lt_lookup_table *ht, char *key, long cursor, long next)
|
75
|
-
{
|
76
|
-
int cmp;
|
77
|
-
|
78
|
-
if (cursor >= ht->size)
|
79
|
-
{
|
80
|
-
return NULL;
|
81
|
-
}
|
82
|
-
|
83
|
-
cmp = strcmp(ht->items[cursor]->key, key);
|
84
|
-
if (cmp == 0)
|
85
|
-
{
|
86
|
-
return ht->items[cursor]->value;
|
87
|
-
}
|
88
|
-
if (next > cursor && next < ht->size)
|
89
|
-
{
|
90
|
-
cmp = strcmp(ht->items[next]->key, key);
|
91
|
-
if (cmp == 0)
|
92
|
-
{
|
93
|
-
return ht->items[next]->value;
|
94
|
-
}
|
95
|
-
else if (cmp < 0)
|
96
|
-
{
|
97
|
-
return lt_search_part(ht, key, next + 1, next + ((ht->size - next) / 2));
|
98
|
-
}
|
99
|
-
else
|
100
|
-
{
|
101
|
-
return lt_search_part(ht, key, cursor + 1, next / 2);
|
102
|
-
}
|
103
|
-
}
|
104
|
-
return lt_search_part(ht, key, cursor + 1, next / 2);
|
105
|
-
}
|
106
|
-
|
107
|
-
static lt_long_array *lt_search_key(lt_lookup_table *ht, char *key)
|
108
|
-
{
|
109
|
-
return lt_search_part(ht, key, 0, ht->size / 2);
|
110
|
-
}
|
111
|
-
|
112
|
-
static void lt_delete_key(lt_lookup_table *ht, char *key)
|
113
|
-
{
|
114
|
-
lt_long_array *found;
|
115
|
-
lt_item **tmp;
|
116
|
-
long i;
|
117
|
-
long cursor = 0;
|
118
|
-
|
119
|
-
found = lt_search_key(ht, key);
|
120
|
-
if (found)
|
121
|
-
{
|
122
|
-
tmp = malloc(sizeof(lt_item) * (ht->size - 1));
|
123
|
-
for (i = 0; i < ht->size; i++)
|
124
|
-
{
|
125
|
-
if (ht->items[i]->key == key)
|
126
|
-
{
|
127
|
-
lt_del_item(ht->items[i]);
|
128
|
-
}
|
129
|
-
else
|
130
|
-
{
|
131
|
-
tmp[cursor] = ht->items[cursor];
|
132
|
-
cursor++;
|
133
|
-
}
|
134
|
-
}
|
135
|
-
free(ht->items);
|
136
|
-
ht->items = tmp;
|
137
|
-
ht->size--;
|
138
|
-
}
|
139
|
-
}
|
140
|
-
|
141
|
-
static void lt_insert_key(lt_lookup_table *ht, char *key, const long *value, const long size)
|
142
|
-
{
|
143
|
-
lt_item *item;
|
144
|
-
lt_item **tmp;
|
145
|
-
long i;
|
146
|
-
long cursor = 0;
|
147
|
-
int inserted = 0;
|
148
|
-
int cmp;
|
149
|
-
|
150
|
-
lt_delete_key(ht, key);
|
151
|
-
|
152
|
-
if (size == 0)
|
153
|
-
{
|
154
|
-
return;
|
155
|
-
}
|
156
|
-
|
157
|
-
item = lt_new_item(key, value, size);
|
158
|
-
tmp = malloc(sizeof(lt_item) * (ht->size + 1));
|
159
|
-
|
160
|
-
for (i = 0; i < ht->size; i++)
|
161
|
-
{
|
162
|
-
if (!inserted)
|
163
|
-
{
|
164
|
-
cmp = strcmp(item->key, ht->items[i]->key);
|
165
|
-
if (cmp > 0)
|
166
|
-
{
|
167
|
-
tmp[cursor] = item;
|
168
|
-
cursor++;
|
169
|
-
inserted = 1;
|
170
|
-
}
|
171
|
-
tmp[cursor] = ht->items[i];
|
172
|
-
cursor++;
|
173
|
-
}
|
174
|
-
else
|
175
|
-
{
|
176
|
-
tmp[cursor] = ht->items[i];
|
177
|
-
cursor++;
|
178
|
-
}
|
179
|
-
}
|
180
|
-
if (!inserted)
|
181
|
-
{
|
182
|
-
tmp[ht->size] = item;
|
183
|
-
}
|
184
|
-
free(ht->items);
|
185
|
-
ht->items = tmp;
|
186
|
-
ht->size++;
|
187
|
-
}
|
188
|
-
|
189
|
-
/*
|
190
|
-
* Add an item to the lookup table
|
191
|
-
*/
|
192
|
-
void lt_insert(lt_lookup_table *ht, char *key, const long *value, const long size)
|
193
|
-
{
|
194
|
-
lt_insert_key(ht, key, value, size);
|
195
|
-
}
|
196
|
-
|
197
|
-
/*
|
198
|
-
* Get the key's value or NULL if it doesn't exist
|
199
|
-
*/
|
200
|
-
lt_long_array *lt_search(lt_lookup_table *ht, char *key)
|
201
|
-
{
|
202
|
-
return lt_search_key(ht, key);
|
203
|
-
}
|
204
|
-
|
205
|
-
/*
|
206
|
-
* Delete the key's item if it exists
|
207
|
-
*/
|
208
|
-
void lt_delete(lt_lookup_table *ht, char *key)
|
209
|
-
{
|
210
|
-
lt_delete_key(ht, key);
|
211
|
-
}
|
1
|
+
#include <math.h>
|
2
|
+
#include <stdlib.h>
|
3
|
+
#include <string.h>
|
4
|
+
|
5
|
+
#include "lookup_table.h"
|
6
|
+
|
7
|
+
static lt_long_array *copy_array(const long *value, const long size)
|
8
|
+
{
|
9
|
+
long i;
|
10
|
+
long *items = malloc(sizeof(long) * size);
|
11
|
+
lt_long_array *result;
|
12
|
+
|
13
|
+
for (i = 0; i < size; i++)
|
14
|
+
{
|
15
|
+
items[i] = value[i];
|
16
|
+
}
|
17
|
+
result = malloc(sizeof(lt_long_array));
|
18
|
+
result->items = (size ? items : NULL);
|
19
|
+
result->size = size;
|
20
|
+
return result;
|
21
|
+
}
|
22
|
+
|
23
|
+
/*
|
24
|
+
* Initialize a new item
|
25
|
+
*/
|
26
|
+
static lt_item *lt_new_item(char *key, const long *value, const long size)
|
27
|
+
{
|
28
|
+
lt_item *i = malloc(sizeof(lt_item));
|
29
|
+
i->key = malloc(sizeof(char) * (strlen(key) + 1));
|
30
|
+
strcpy(i->key, key);
|
31
|
+
i->value = copy_array(value, size);
|
32
|
+
return i;
|
33
|
+
}
|
34
|
+
|
35
|
+
/*
|
36
|
+
* Delete the lt_item
|
37
|
+
*/
|
38
|
+
static void lt_del_item(lt_item *i)
|
39
|
+
{
|
40
|
+
free(i->key);
|
41
|
+
free(i->value->items);
|
42
|
+
free(i);
|
43
|
+
}
|
44
|
+
|
45
|
+
/*
|
46
|
+
* Initialize a new empty lookup table
|
47
|
+
*/
|
48
|
+
lt_lookup_table *lt_new()
|
49
|
+
{
|
50
|
+
lt_lookup_table *ht = malloc(sizeof(lt_lookup_table));
|
51
|
+
ht->items = NULL;
|
52
|
+
ht->size = 0;
|
53
|
+
return ht;
|
54
|
+
}
|
55
|
+
|
56
|
+
/*
|
57
|
+
* Delete the lookup table
|
58
|
+
*/
|
59
|
+
void lt_del_lookup_table(lt_lookup_table *ht)
|
60
|
+
{
|
61
|
+
int i;
|
62
|
+
lt_item *item;
|
63
|
+
|
64
|
+
// Iterate through items and delete any that are found
|
65
|
+
for (i = 0; i < ht->size; i++)
|
66
|
+
{
|
67
|
+
item = ht->items[i];
|
68
|
+
lt_del_item(item);
|
69
|
+
}
|
70
|
+
free(ht->items);
|
71
|
+
free(ht);
|
72
|
+
}
|
73
|
+
|
74
|
+
static lt_long_array *lt_search_part(lt_lookup_table *ht, char *key, long cursor, long next)
|
75
|
+
{
|
76
|
+
int cmp;
|
77
|
+
|
78
|
+
if (cursor >= ht->size)
|
79
|
+
{
|
80
|
+
return NULL;
|
81
|
+
}
|
82
|
+
|
83
|
+
cmp = strcmp(ht->items[cursor]->key, key);
|
84
|
+
if (cmp == 0)
|
85
|
+
{
|
86
|
+
return ht->items[cursor]->value;
|
87
|
+
}
|
88
|
+
if (next > cursor && next < ht->size)
|
89
|
+
{
|
90
|
+
cmp = strcmp(ht->items[next]->key, key);
|
91
|
+
if (cmp == 0)
|
92
|
+
{
|
93
|
+
return ht->items[next]->value;
|
94
|
+
}
|
95
|
+
else if (cmp < 0)
|
96
|
+
{
|
97
|
+
return lt_search_part(ht, key, next + 1, next + ((ht->size - next) / 2));
|
98
|
+
}
|
99
|
+
else
|
100
|
+
{
|
101
|
+
return lt_search_part(ht, key, cursor + 1, next / 2);
|
102
|
+
}
|
103
|
+
}
|
104
|
+
return lt_search_part(ht, key, cursor + 1, next / 2);
|
105
|
+
}
|
106
|
+
|
107
|
+
static lt_long_array *lt_search_key(lt_lookup_table *ht, char *key)
|
108
|
+
{
|
109
|
+
return lt_search_part(ht, key, 0, ht->size / 2);
|
110
|
+
}
|
111
|
+
|
112
|
+
static void lt_delete_key(lt_lookup_table *ht, char *key)
|
113
|
+
{
|
114
|
+
lt_long_array *found;
|
115
|
+
lt_item **tmp;
|
116
|
+
long i;
|
117
|
+
long cursor = 0;
|
118
|
+
|
119
|
+
found = lt_search_key(ht, key);
|
120
|
+
if (found)
|
121
|
+
{
|
122
|
+
tmp = malloc(sizeof(lt_item) * (ht->size - 1));
|
123
|
+
for (i = 0; i < ht->size; i++)
|
124
|
+
{
|
125
|
+
if (ht->items[i]->key == key)
|
126
|
+
{
|
127
|
+
lt_del_item(ht->items[i]);
|
128
|
+
}
|
129
|
+
else
|
130
|
+
{
|
131
|
+
tmp[cursor] = ht->items[cursor];
|
132
|
+
cursor++;
|
133
|
+
}
|
134
|
+
}
|
135
|
+
free(ht->items);
|
136
|
+
ht->items = tmp;
|
137
|
+
ht->size--;
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
141
|
+
static void lt_insert_key(lt_lookup_table *ht, char *key, const long *value, const long size)
|
142
|
+
{
|
143
|
+
lt_item *item;
|
144
|
+
lt_item **tmp;
|
145
|
+
long i;
|
146
|
+
long cursor = 0;
|
147
|
+
int inserted = 0;
|
148
|
+
int cmp;
|
149
|
+
|
150
|
+
lt_delete_key(ht, key);
|
151
|
+
|
152
|
+
if (size == 0)
|
153
|
+
{
|
154
|
+
return;
|
155
|
+
}
|
156
|
+
|
157
|
+
item = lt_new_item(key, value, size);
|
158
|
+
tmp = malloc(sizeof(lt_item) * (ht->size + 1));
|
159
|
+
|
160
|
+
for (i = 0; i < ht->size; i++)
|
161
|
+
{
|
162
|
+
if (!inserted)
|
163
|
+
{
|
164
|
+
cmp = strcmp(item->key, ht->items[i]->key);
|
165
|
+
if (cmp > 0)
|
166
|
+
{
|
167
|
+
tmp[cursor] = item;
|
168
|
+
cursor++;
|
169
|
+
inserted = 1;
|
170
|
+
}
|
171
|
+
tmp[cursor] = ht->items[i];
|
172
|
+
cursor++;
|
173
|
+
}
|
174
|
+
else
|
175
|
+
{
|
176
|
+
tmp[cursor] = ht->items[i];
|
177
|
+
cursor++;
|
178
|
+
}
|
179
|
+
}
|
180
|
+
if (!inserted)
|
181
|
+
{
|
182
|
+
tmp[ht->size] = item;
|
183
|
+
}
|
184
|
+
free(ht->items);
|
185
|
+
ht->items = tmp;
|
186
|
+
ht->size++;
|
187
|
+
}
|
188
|
+
|
189
|
+
/*
|
190
|
+
* Add an item to the lookup table
|
191
|
+
*/
|
192
|
+
void lt_insert(lt_lookup_table *ht, char *key, const long *value, const long size)
|
193
|
+
{
|
194
|
+
lt_insert_key(ht, key, value, size);
|
195
|
+
}
|
196
|
+
|
197
|
+
/*
|
198
|
+
* Get the key's value or NULL if it doesn't exist
|
199
|
+
*/
|
200
|
+
lt_long_array *lt_search(lt_lookup_table *ht, char *key)
|
201
|
+
{
|
202
|
+
return lt_search_key(ht, key);
|
203
|
+
}
|
204
|
+
|
205
|
+
/*
|
206
|
+
* Delete the key's item if it exists
|
207
|
+
*/
|
208
|
+
void lt_delete(lt_lookup_table *ht, char *key)
|
209
|
+
{
|
210
|
+
lt_delete_key(ht, key);
|
211
|
+
}
|