readapt 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }