readapt 1.0.0 → 1.1.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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +16 -15
  3. data/.rspec +2 -2
  4. data/.travis.yml +18 -18
  5. data/CHANGELOG.md +72 -69
  6. data/Gemfile +4 -4
  7. data/LICENSE.txt +21 -21
  8. data/README.md +37 -29
  9. data/Rakefile +14 -14
  10. data/bin/console +14 -14
  11. data/bin/setup +8 -8
  12. data/exe/readapt +5 -5
  13. data/ext/readapt/breakpoints.c +83 -83
  14. data/ext/readapt/breakpoints.h +11 -11
  15. data/ext/readapt/extconf.rb +0 -0
  16. data/ext/readapt/frame.c +137 -137
  17. data/ext/readapt/frame.h +17 -17
  18. data/ext/readapt/hash_table.c +211 -211
  19. data/ext/readapt/hash_table.h +30 -30
  20. data/ext/readapt/inspector.c +51 -51
  21. data/ext/readapt/inspector.h +8 -8
  22. data/ext/readapt/monitor.c +1 -1
  23. data/ext/readapt/monitor.h +0 -0
  24. data/ext/readapt/normalize.c +59 -59
  25. data/ext/readapt/normalize.h +7 -7
  26. data/ext/readapt/readapt.c +18 -18
  27. data/ext/readapt/stack.c +86 -86
  28. data/ext/readapt/stack.h +20 -20
  29. data/ext/readapt/threads.c +15 -11
  30. data/ext/readapt/threads.h +1 -1
  31. data/lib/readapt.rb +21 -20
  32. data/lib/readapt/adapter.rb +98 -98
  33. data/lib/readapt/breakpoint.rb +20 -20
  34. data/lib/readapt/data_reader.rb +62 -62
  35. data/lib/readapt/debugger.rb +220 -220
  36. data/lib/readapt/error.rb +63 -63
  37. data/lib/readapt/finder.rb +20 -20
  38. data/lib/readapt/frame.rb +40 -40
  39. data/lib/readapt/input.rb +7 -7
  40. data/lib/readapt/message.rb +62 -62
  41. data/lib/readapt/message/attach.rb +11 -11
  42. data/lib/readapt/message/base.rb +32 -32
  43. data/lib/readapt/message/configuration_done.rb +11 -11
  44. data/lib/readapt/message/continue.rb +15 -15
  45. data/lib/readapt/message/disconnect.rb +13 -13
  46. data/lib/readapt/message/evaluate.rb +18 -18
  47. data/lib/readapt/message/initialize.rb +13 -13
  48. data/lib/readapt/message/launch.rb +11 -11
  49. data/lib/readapt/message/next.rb +12 -12
  50. data/lib/readapt/message/pause.rb +11 -11
  51. data/lib/readapt/message/scopes.rb +26 -26
  52. data/lib/readapt/message/set_breakpoints.rb +25 -25
  53. data/lib/readapt/message/set_exception_breakpoints.rb +8 -8
  54. data/lib/readapt/message/stack_trace.rb +38 -38
  55. data/lib/readapt/message/step_in.rb +11 -11
  56. data/lib/readapt/message/step_out.rb +11 -11
  57. data/lib/readapt/message/threads.rb +18 -18
  58. data/lib/readapt/message/variables.rb +61 -61
  59. data/lib/readapt/monitor.rb +0 -0
  60. data/lib/readapt/output.rb +25 -25
  61. data/lib/readapt/references.rb +27 -0
  62. data/lib/readapt/server.rb +22 -22
  63. data/lib/readapt/shell.rb +104 -104
  64. data/lib/readapt/snapshot.rb +0 -0
  65. data/lib/readapt/thread.rb +23 -23
  66. data/lib/readapt/variable.rb +1 -1
  67. data/lib/readapt/version.rb +3 -3
  68. data/readapt.gemspec +39 -39
  69. metadata +4 -3
@@ -1,11 +1,11 @@
1
- #ifndef BREAKPOINTS_H_
2
- #define BREAKPOINTS_H_
3
-
4
- void initialize_breakpoints(VALUE m_Readapt);
5
-
6
- void breakpoints_set(char *file, long *lines);
7
- void breakpoints_delete(char *file);
8
- int breakpoints_match(char *file, long line);
9
- long breakpoints_files();
10
-
11
- #endif
1
+ #ifndef BREAKPOINTS_H_
2
+ #define BREAKPOINTS_H_
3
+
4
+ void initialize_breakpoints(VALUE m_Readapt);
5
+
6
+ void breakpoints_set(char *file, long *lines);
7
+ void breakpoints_delete(char *file);
8
+ int breakpoints_match(char *file, long line);
9
+ long breakpoints_files();
10
+
11
+ #endif
File without changes
@@ -1,137 +1,137 @@
1
- #include "ruby.h"
2
- #include "ruby/debug.h"
3
- #include "frame.h"
4
- #include "normalize.h"
5
-
6
- static VALUE c_Frame;
7
-
8
- void frame_free(void *data)
9
- {
10
- frame_t *frm = data;
11
-
12
- free(frm->file);
13
- free(frm);
14
- }
15
-
16
- static size_t
17
- frame_size(const void *data)
18
- {
19
- return sizeof(frame_t);
20
- }
21
-
22
- static const rb_data_type_t frame_type = {
23
- .wrap_struct_name = "frame_data",
24
- .function = {
25
- .dmark = NULL,
26
- .dfree = frame_free,
27
- .dsize = frame_size,
28
- },
29
- .data = NULL,
30
- .flags = RUBY_TYPED_FREE_IMMEDIATELY,
31
- };
32
-
33
- VALUE frame_allocate_s(VALUE self)
34
- {
35
- VALUE obj;
36
- frame_t *data = malloc(sizeof(frame_t));
37
- obj = TypedData_Wrap_Struct(self, &frame_type, data);
38
- data->file = NULL;
39
- data->line = 0;
40
- data->binding = Qnil;
41
- return obj;
42
- }
43
-
44
- VALUE frame_allocate()
45
- {
46
- return frame_allocate_s(c_Frame);
47
- }
48
-
49
- frame_t *frame_data_from_tracepoint(VALUE tracepoint)
50
- {
51
- frame_t *data;
52
- VALUE tmp;
53
- rb_trace_arg_t *tracearg;
54
- char *file;
55
- int line;
56
-
57
- data = malloc(sizeof(frame_t));
58
- tracearg = rb_tracearg_from_tracepoint(tracepoint);
59
- tmp = rb_tracearg_path(tracearg);
60
- file = (tmp == Qnil ? NULL : normalize_path_new_cstr(StringValueCStr(tmp)));
61
- line = NUM2INT(rb_tracearg_lineno(tracearg));
62
-
63
- data->file = file;
64
- data->line = line;
65
- data->binding = Qnil;
66
-
67
- return data;
68
- }
69
-
70
- VALUE frame_initialize_m(VALUE self, VALUE file, VALUE line, VALUE binding)
71
- {
72
- frame_t *data;
73
- TypedData_Get_Struct(self, frame_t, &frame_type, data);
74
- if (file == Qnil)
75
- {
76
- data->file = NULL;
77
- }
78
- else
79
- {
80
- data->file = normalize_path_new_cstr(StringValueCStr(file));
81
- }
82
- data->line = NUM2INT(line);
83
- data->binding = binding;
84
- return self;
85
- }
86
-
87
- VALUE frame_new_from_data(frame_t *data)
88
- {
89
- VALUE obj;
90
-
91
- obj = frame_allocate();
92
- frame_initialize_m(
93
- obj,
94
- rb_str_new_cstr(data->file),
95
- INT2NUM(data->line),
96
- data->binding);
97
-
98
- return obj;
99
- }
100
-
101
- VALUE frame_file_m(VALUE self)
102
- {
103
- frame_t *data;
104
- VALUE str = Qnil;
105
-
106
- TypedData_Get_Struct(self, frame_t, &frame_type, data);
107
- if (data->file)
108
- {
109
- str = rb_str_new_cstr(data->file);
110
- rb_obj_freeze(str);
111
- }
112
- return str;
113
- }
114
-
115
- VALUE frame_line_m(VALUE self)
116
- {
117
- frame_t *data;
118
- TypedData_Get_Struct(self, frame_t, &frame_type, data);
119
- return INT2NUM(data->line);
120
- }
121
-
122
- VALUE frame_binding_m(VALUE self)
123
- {
124
- frame_t *data;
125
- TypedData_Get_Struct(self, frame_t, &frame_type, data);
126
- return data->binding;
127
- }
128
-
129
- void initialize_frame(VALUE m_Readapt)
130
- {
131
- c_Frame = rb_define_class_under(m_Readapt, "Frame", rb_cData);
132
- rb_define_alloc_func(c_Frame, frame_allocate_s);
133
- rb_define_method(c_Frame, "initialize", frame_initialize_m, 3);
134
- rb_define_method(c_Frame, "file", frame_file_m, 0);
135
- rb_define_method(c_Frame, "line", frame_line_m, 0);
136
- rb_define_method(c_Frame, "frame_binding", frame_binding_m, 0);
137
- }
1
+ #include "ruby.h"
2
+ #include "ruby/debug.h"
3
+ #include "frame.h"
4
+ #include "normalize.h"
5
+
6
+ static VALUE c_Frame;
7
+
8
+ void frame_free(void *data)
9
+ {
10
+ frame_t *frm = data;
11
+
12
+ free(frm->file);
13
+ free(frm);
14
+ }
15
+
16
+ static size_t
17
+ frame_size(const void *data)
18
+ {
19
+ return sizeof(frame_t);
20
+ }
21
+
22
+ static const rb_data_type_t frame_type = {
23
+ .wrap_struct_name = "frame_data",
24
+ .function = {
25
+ .dmark = NULL,
26
+ .dfree = frame_free,
27
+ .dsize = frame_size,
28
+ },
29
+ .data = NULL,
30
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
31
+ };
32
+
33
+ VALUE frame_allocate_s(VALUE self)
34
+ {
35
+ VALUE obj;
36
+ frame_t *data = malloc(sizeof(frame_t));
37
+ obj = TypedData_Wrap_Struct(self, &frame_type, data);
38
+ data->file = NULL;
39
+ data->line = 0;
40
+ data->binding = Qnil;
41
+ return obj;
42
+ }
43
+
44
+ VALUE frame_allocate()
45
+ {
46
+ return frame_allocate_s(c_Frame);
47
+ }
48
+
49
+ frame_t *frame_data_from_tracepoint(VALUE tracepoint)
50
+ {
51
+ frame_t *data;
52
+ VALUE tmp;
53
+ rb_trace_arg_t *tracearg;
54
+ char *file;
55
+ int line;
56
+
57
+ data = malloc(sizeof(frame_t));
58
+ tracearg = rb_tracearg_from_tracepoint(tracepoint);
59
+ tmp = rb_tracearg_path(tracearg);
60
+ file = (tmp == Qnil ? NULL : normalize_path_new_cstr(StringValueCStr(tmp)));
61
+ line = NUM2INT(rb_tracearg_lineno(tracearg));
62
+
63
+ data->file = file;
64
+ data->line = line;
65
+ data->binding = Qnil;
66
+
67
+ return data;
68
+ }
69
+
70
+ VALUE frame_initialize_m(VALUE self, VALUE file, VALUE line, VALUE binding)
71
+ {
72
+ frame_t *data;
73
+ TypedData_Get_Struct(self, frame_t, &frame_type, data);
74
+ if (file == Qnil)
75
+ {
76
+ data->file = NULL;
77
+ }
78
+ else
79
+ {
80
+ data->file = normalize_path_new_cstr(StringValueCStr(file));
81
+ }
82
+ data->line = NUM2INT(line);
83
+ data->binding = binding;
84
+ return self;
85
+ }
86
+
87
+ VALUE frame_new_from_data(frame_t *data)
88
+ {
89
+ VALUE obj;
90
+
91
+ obj = frame_allocate();
92
+ frame_initialize_m(
93
+ obj,
94
+ rb_str_new_cstr(data->file),
95
+ INT2NUM(data->line),
96
+ data->binding);
97
+
98
+ return obj;
99
+ }
100
+
101
+ VALUE frame_file_m(VALUE self)
102
+ {
103
+ frame_t *data;
104
+ VALUE str = Qnil;
105
+
106
+ TypedData_Get_Struct(self, frame_t, &frame_type, data);
107
+ if (data->file)
108
+ {
109
+ str = rb_str_new_cstr(data->file);
110
+ rb_obj_freeze(str);
111
+ }
112
+ return str;
113
+ }
114
+
115
+ VALUE frame_line_m(VALUE self)
116
+ {
117
+ frame_t *data;
118
+ TypedData_Get_Struct(self, frame_t, &frame_type, data);
119
+ return INT2NUM(data->line);
120
+ }
121
+
122
+ VALUE frame_binding_m(VALUE self)
123
+ {
124
+ frame_t *data;
125
+ TypedData_Get_Struct(self, frame_t, &frame_type, data);
126
+ return data->binding;
127
+ }
128
+
129
+ void initialize_frame(VALUE m_Readapt)
130
+ {
131
+ c_Frame = rb_define_class_under(m_Readapt, "Frame", rb_cData);
132
+ rb_define_alloc_func(c_Frame, frame_allocate_s);
133
+ rb_define_method(c_Frame, "initialize", frame_initialize_m, 3);
134
+ rb_define_method(c_Frame, "file", frame_file_m, 0);
135
+ rb_define_method(c_Frame, "line", frame_line_m, 0);
136
+ rb_define_method(c_Frame, "frame_binding", frame_binding_m, 0);
137
+ }
@@ -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
@@ -1,211 +1,211 @@
1
- #include <math.h>
2
- #include <stdlib.h>
3
- #include <string.h>
4
-
5
- #include "hash_table.h"
6
-
7
- static ht_long_array *copy_array(const long *value, const long size)
8
- {
9
- long i;
10
- long *items = malloc(sizeof(long) * size);
11
- ht_long_array *result;
12
-
13
- for (i = 0; i < size; i++)
14
- {
15
- items[i] = value[i];
16
- }
17
- result = malloc(sizeof(ht_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 ht_item *ht_new_item(char *key, const long *value, const long size)
27
- {
28
- ht_item *i = malloc(sizeof(ht_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 ht_item
37
- */
38
- static void ht_del_item(ht_item *i)
39
- {
40
- free(i->key);
41
- free(i->value->items);
42
- free(i);
43
- }
44
-
45
- /*
46
- * Initialize a new empty hash table
47
- */
48
- ht_hash_table *ht_new()
49
- {
50
- ht_hash_table *ht = malloc(sizeof(ht_hash_table));
51
- ht->items = NULL;
52
- ht->size = 0;
53
- return ht;
54
- }
55
-
56
- /*
57
- * Delete the hash table
58
- */
59
- void ht_del_hash_table(ht_hash_table *ht)
60
- {
61
- int i;
62
- ht_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
- ht_del_item(item);
69
- }
70
- free(ht->items);
71
- free(ht);
72
- }
73
-
74
- static ht_long_array *ht_search_part(ht_hash_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 ht_search_part(ht, key, next + 1, next + ((ht->size - next) / 2));
98
- }
99
- else
100
- {
101
- return ht_search_part(ht, key, cursor + 1, next / 2);
102
- }
103
- }
104
- return ht_search_part(ht, key, cursor + 1, next / 2);
105
- }
106
-
107
- static ht_long_array *ht_search_key(ht_hash_table *ht, char *key)
108
- {
109
- return ht_search_part(ht, key, 0, ht->size / 2);
110
- }
111
-
112
- static void ht_delete_key(ht_hash_table *ht, char *key)
113
- {
114
- ht_long_array *found;
115
- ht_item **tmp;
116
- long i;
117
- long cursor = 0;
118
-
119
- found = ht_search_key(ht, key);
120
- if (found)
121
- {
122
- tmp = malloc(sizeof(ht_item) * (ht->size - 1));
123
- for (i = 0; i < ht->size; i++)
124
- {
125
- if (ht->items[i]->key == key)
126
- {
127
- ht_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 ht_insert_key(ht_hash_table *ht, char *key, const long *value, const long size)
142
- {
143
- ht_item *item;
144
- ht_item **tmp;
145
- long i;
146
- long cursor = 0;
147
- int inserted = 0;
148
- int cmp;
149
-
150
- ht_delete_key(ht, key);
151
-
152
- if (size == 0)
153
- {
154
- return;
155
- }
156
-
157
- item = ht_new_item(key, value, size);
158
- tmp = malloc(sizeof(ht_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 hash table
191
- */
192
- void ht_insert(ht_hash_table *ht, char *key, const long *value, const long size)
193
- {
194
- ht_insert_key(ht, key, value, size);
195
- }
196
-
197
- /*
198
- * Get the key's value or NULL if it doesn't exist
199
- */
200
- ht_long_array *ht_search(ht_hash_table *ht, char *key)
201
- {
202
- return ht_search_key(ht, key);
203
- }
204
-
205
- /*
206
- * Delete the key's item if it exists
207
- */
208
- void ht_delete(ht_hash_table *ht, char *key)
209
- {
210
- ht_delete_key(ht, key);
211
- }
1
+ #include <math.h>
2
+ #include <stdlib.h>
3
+ #include <string.h>
4
+
5
+ #include "hash_table.h"
6
+
7
+ static ht_long_array *copy_array(const long *value, const long size)
8
+ {
9
+ long i;
10
+ long *items = malloc(sizeof(long) * size);
11
+ ht_long_array *result;
12
+
13
+ for (i = 0; i < size; i++)
14
+ {
15
+ items[i] = value[i];
16
+ }
17
+ result = malloc(sizeof(ht_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 ht_item *ht_new_item(char *key, const long *value, const long size)
27
+ {
28
+ ht_item *i = malloc(sizeof(ht_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 ht_item
37
+ */
38
+ static void ht_del_item(ht_item *i)
39
+ {
40
+ free(i->key);
41
+ free(i->value->items);
42
+ free(i);
43
+ }
44
+
45
+ /*
46
+ * Initialize a new empty hash table
47
+ */
48
+ ht_hash_table *ht_new()
49
+ {
50
+ ht_hash_table *ht = malloc(sizeof(ht_hash_table));
51
+ ht->items = NULL;
52
+ ht->size = 0;
53
+ return ht;
54
+ }
55
+
56
+ /*
57
+ * Delete the hash table
58
+ */
59
+ void ht_del_hash_table(ht_hash_table *ht)
60
+ {
61
+ int i;
62
+ ht_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
+ ht_del_item(item);
69
+ }
70
+ free(ht->items);
71
+ free(ht);
72
+ }
73
+
74
+ static ht_long_array *ht_search_part(ht_hash_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 ht_search_part(ht, key, next + 1, next + ((ht->size - next) / 2));
98
+ }
99
+ else
100
+ {
101
+ return ht_search_part(ht, key, cursor + 1, next / 2);
102
+ }
103
+ }
104
+ return ht_search_part(ht, key, cursor + 1, next / 2);
105
+ }
106
+
107
+ static ht_long_array *ht_search_key(ht_hash_table *ht, char *key)
108
+ {
109
+ return ht_search_part(ht, key, 0, ht->size / 2);
110
+ }
111
+
112
+ static void ht_delete_key(ht_hash_table *ht, char *key)
113
+ {
114
+ ht_long_array *found;
115
+ ht_item **tmp;
116
+ long i;
117
+ long cursor = 0;
118
+
119
+ found = ht_search_key(ht, key);
120
+ if (found)
121
+ {
122
+ tmp = malloc(sizeof(ht_item) * (ht->size - 1));
123
+ for (i = 0; i < ht->size; i++)
124
+ {
125
+ if (ht->items[i]->key == key)
126
+ {
127
+ ht_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 ht_insert_key(ht_hash_table *ht, char *key, const long *value, const long size)
142
+ {
143
+ ht_item *item;
144
+ ht_item **tmp;
145
+ long i;
146
+ long cursor = 0;
147
+ int inserted = 0;
148
+ int cmp;
149
+
150
+ ht_delete_key(ht, key);
151
+
152
+ if (size == 0)
153
+ {
154
+ return;
155
+ }
156
+
157
+ item = ht_new_item(key, value, size);
158
+ tmp = malloc(sizeof(ht_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 hash table
191
+ */
192
+ void ht_insert(ht_hash_table *ht, char *key, const long *value, const long size)
193
+ {
194
+ ht_insert_key(ht, key, value, size);
195
+ }
196
+
197
+ /*
198
+ * Get the key's value or NULL if it doesn't exist
199
+ */
200
+ ht_long_array *ht_search(ht_hash_table *ht, char *key)
201
+ {
202
+ return ht_search_key(ht, key);
203
+ }
204
+
205
+ /*
206
+ * Delete the key's item if it exists
207
+ */
208
+ void ht_delete(ht_hash_table *ht, char *key)
209
+ {
210
+ ht_delete_key(ht, key);
211
+ }