ferret 0.9.6 → 0.10.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 (295) hide show
  1. data/MIT-LICENSE +1 -1
  2. data/README +12 -24
  3. data/Rakefile +38 -54
  4. data/TODO +14 -17
  5. data/ext/analysis.c +982 -823
  6. data/ext/analysis.h +133 -76
  7. data/ext/array.c +96 -58
  8. data/ext/array.h +40 -13
  9. data/ext/bitvector.c +476 -118
  10. data/ext/bitvector.h +264 -22
  11. data/ext/compound_io.c +217 -229
  12. data/ext/defines.h +49 -0
  13. data/ext/document.c +107 -317
  14. data/ext/document.h +31 -65
  15. data/ext/except.c +81 -36
  16. data/ext/except.h +117 -55
  17. data/ext/extconf.rb +2 -9
  18. data/ext/ferret.c +211 -104
  19. data/ext/ferret.h +22 -11
  20. data/ext/filter.c +97 -82
  21. data/ext/fs_store.c +348 -367
  22. data/ext/global.c +226 -188
  23. data/ext/global.h +44 -26
  24. data/ext/hash.c +474 -391
  25. data/ext/hash.h +441 -68
  26. data/ext/hashset.c +124 -96
  27. data/ext/hashset.h +169 -20
  28. data/ext/helper.c +56 -5
  29. data/ext/helper.h +7 -0
  30. data/ext/inc/lang.h +29 -49
  31. data/ext/inc/threading.h +31 -0
  32. data/ext/ind.c +288 -278
  33. data/ext/ind.h +68 -0
  34. data/ext/index.c +5688 -0
  35. data/ext/index.h +663 -616
  36. data/ext/lang.h +29 -49
  37. data/ext/libstemmer.c +3 -3
  38. data/ext/mem_pool.c +84 -0
  39. data/ext/mem_pool.h +35 -0
  40. data/ext/posh.c +1006 -0
  41. data/ext/posh.h +1007 -0
  42. data/ext/priorityqueue.c +117 -194
  43. data/ext/priorityqueue.h +135 -39
  44. data/ext/q_boolean.c +1305 -1108
  45. data/ext/q_const_score.c +106 -93
  46. data/ext/q_filtered_query.c +138 -135
  47. data/ext/q_fuzzy.c +206 -242
  48. data/ext/q_match_all.c +94 -80
  49. data/ext/q_multi_term.c +663 -0
  50. data/ext/q_parser.c +667 -593
  51. data/ext/q_phrase.c +992 -555
  52. data/ext/q_prefix.c +72 -61
  53. data/ext/q_range.c +235 -210
  54. data/ext/q_span.c +1480 -1166
  55. data/ext/q_term.c +273 -246
  56. data/ext/q_wildcard.c +127 -114
  57. data/ext/r_analysis.c +1720 -711
  58. data/ext/r_index.c +3049 -0
  59. data/ext/r_qparser.c +433 -146
  60. data/ext/r_search.c +2934 -1993
  61. data/ext/r_store.c +372 -143
  62. data/ext/r_utils.c +941 -0
  63. data/ext/ram_store.c +330 -326
  64. data/ext/search.c +1291 -668
  65. data/ext/search.h +403 -702
  66. data/ext/similarity.c +91 -113
  67. data/ext/similarity.h +45 -30
  68. data/ext/sort.c +721 -484
  69. data/ext/stopwords.c +361 -273
  70. data/ext/store.c +556 -58
  71. data/ext/store.h +706 -126
  72. data/ext/tags +3578 -2780
  73. data/ext/term_vectors.c +352 -0
  74. data/ext/threading.h +31 -0
  75. data/ext/win32.h +54 -0
  76. data/lib/ferret.rb +5 -17
  77. data/lib/ferret/document.rb +130 -2
  78. data/lib/ferret/index.rb +577 -26
  79. data/lib/ferret/number_tools.rb +157 -0
  80. data/lib/ferret_version.rb +3 -0
  81. data/test/test_helper.rb +5 -13
  82. data/test/unit/analysis/tc_analyzer.rb +513 -1
  83. data/test/unit/analysis/{ctc_tokenstream.rb → tc_token_stream.rb} +23 -0
  84. data/test/unit/index/tc_index.rb +183 -240
  85. data/test/unit/index/tc_index_reader.rb +312 -479
  86. data/test/unit/index/tc_index_writer.rb +397 -13
  87. data/test/unit/index/th_doc.rb +269 -206
  88. data/test/unit/query_parser/tc_query_parser.rb +40 -33
  89. data/test/unit/search/tc_filter.rb +59 -71
  90. data/test/unit/search/tc_fuzzy_query.rb +24 -16
  91. data/test/unit/search/tc_index_searcher.rb +23 -201
  92. data/test/unit/search/tc_multi_searcher.rb +78 -226
  93. data/test/unit/search/tc_search_and_sort.rb +93 -81
  94. data/test/unit/search/tc_sort.rb +23 -23
  95. data/test/unit/search/tc_sort_field.rb +7 -7
  96. data/test/unit/search/tc_spans.rb +51 -47
  97. data/test/unit/search/tm_searcher.rb +339 -0
  98. data/test/unit/store/tc_fs_store.rb +1 -1
  99. data/test/unit/store/tm_store_lock.rb +3 -3
  100. data/test/unit/tc_document.rb +81 -0
  101. data/test/unit/ts_analysis.rb +1 -1
  102. data/test/unit/ts_utils.rb +1 -1
  103. data/test/unit/utils/tc_bit_vector.rb +288 -0
  104. data/test/unit/utils/tc_number_tools.rb +117 -0
  105. data/test/unit/utils/tc_priority_queue.rb +106 -0
  106. metadata +140 -301
  107. data/CHANGELOG +0 -9
  108. data/ext/dummy.exe +0 -0
  109. data/ext/field.c +0 -408
  110. data/ext/frtio.h +0 -13
  111. data/ext/inc/except.h +0 -90
  112. data/ext/index_io.c +0 -382
  113. data/ext/index_rw.c +0 -2658
  114. data/ext/lang.c +0 -41
  115. data/ext/nix_io.c +0 -134
  116. data/ext/q_multi_phrase.c +0 -380
  117. data/ext/r_doc.c +0 -582
  118. data/ext/r_index_io.c +0 -1021
  119. data/ext/r_term.c +0 -219
  120. data/ext/term.c +0 -820
  121. data/ext/termdocs.c +0 -611
  122. data/ext/vector.c +0 -637
  123. data/ext/w32_io.c +0 -150
  124. data/lib/ferret/analysis.rb +0 -11
  125. data/lib/ferret/analysis/analyzers.rb +0 -112
  126. data/lib/ferret/analysis/standard_tokenizer.rb +0 -71
  127. data/lib/ferret/analysis/token.rb +0 -100
  128. data/lib/ferret/analysis/token_filters.rb +0 -86
  129. data/lib/ferret/analysis/token_stream.rb +0 -26
  130. data/lib/ferret/analysis/tokenizers.rb +0 -112
  131. data/lib/ferret/analysis/word_list_loader.rb +0 -27
  132. data/lib/ferret/document/document.rb +0 -152
  133. data/lib/ferret/document/field.rb +0 -312
  134. data/lib/ferret/index/compound_file_io.rb +0 -338
  135. data/lib/ferret/index/document_writer.rb +0 -289
  136. data/lib/ferret/index/field_infos.rb +0 -279
  137. data/lib/ferret/index/fields_io.rb +0 -181
  138. data/lib/ferret/index/index.rb +0 -675
  139. data/lib/ferret/index/index_file_names.rb +0 -33
  140. data/lib/ferret/index/index_reader.rb +0 -503
  141. data/lib/ferret/index/index_writer.rb +0 -534
  142. data/lib/ferret/index/multi_reader.rb +0 -377
  143. data/lib/ferret/index/multiple_term_doc_pos_enum.rb +0 -98
  144. data/lib/ferret/index/segment_infos.rb +0 -130
  145. data/lib/ferret/index/segment_merge_info.rb +0 -49
  146. data/lib/ferret/index/segment_merge_queue.rb +0 -16
  147. data/lib/ferret/index/segment_merger.rb +0 -358
  148. data/lib/ferret/index/segment_reader.rb +0 -412
  149. data/lib/ferret/index/segment_term_enum.rb +0 -169
  150. data/lib/ferret/index/segment_term_vector.rb +0 -58
  151. data/lib/ferret/index/term.rb +0 -53
  152. data/lib/ferret/index/term_buffer.rb +0 -83
  153. data/lib/ferret/index/term_doc_enum.rb +0 -291
  154. data/lib/ferret/index/term_enum.rb +0 -52
  155. data/lib/ferret/index/term_info.rb +0 -37
  156. data/lib/ferret/index/term_infos_io.rb +0 -321
  157. data/lib/ferret/index/term_vector_offset_info.rb +0 -20
  158. data/lib/ferret/index/term_vectors_io.rb +0 -553
  159. data/lib/ferret/query_parser.rb +0 -312
  160. data/lib/ferret/query_parser/query_parser.tab.rb +0 -928
  161. data/lib/ferret/search.rb +0 -50
  162. data/lib/ferret/search/boolean_clause.rb +0 -100
  163. data/lib/ferret/search/boolean_query.rb +0 -299
  164. data/lib/ferret/search/boolean_scorer.rb +0 -294
  165. data/lib/ferret/search/caching_wrapper_filter.rb +0 -40
  166. data/lib/ferret/search/conjunction_scorer.rb +0 -99
  167. data/lib/ferret/search/disjunction_sum_scorer.rb +0 -205
  168. data/lib/ferret/search/exact_phrase_scorer.rb +0 -32
  169. data/lib/ferret/search/explanation.rb +0 -41
  170. data/lib/ferret/search/field_cache.rb +0 -215
  171. data/lib/ferret/search/field_doc.rb +0 -31
  172. data/lib/ferret/search/field_sorted_hit_queue.rb +0 -184
  173. data/lib/ferret/search/filter.rb +0 -11
  174. data/lib/ferret/search/filtered_query.rb +0 -130
  175. data/lib/ferret/search/filtered_term_enum.rb +0 -79
  176. data/lib/ferret/search/fuzzy_query.rb +0 -154
  177. data/lib/ferret/search/fuzzy_term_enum.rb +0 -247
  178. data/lib/ferret/search/hit_collector.rb +0 -34
  179. data/lib/ferret/search/hit_queue.rb +0 -11
  180. data/lib/ferret/search/index_searcher.rb +0 -200
  181. data/lib/ferret/search/match_all_query.rb +0 -104
  182. data/lib/ferret/search/multi_phrase_query.rb +0 -216
  183. data/lib/ferret/search/multi_searcher.rb +0 -261
  184. data/lib/ferret/search/multi_term_query.rb +0 -65
  185. data/lib/ferret/search/non_matching_scorer.rb +0 -22
  186. data/lib/ferret/search/phrase_positions.rb +0 -55
  187. data/lib/ferret/search/phrase_query.rb +0 -214
  188. data/lib/ferret/search/phrase_scorer.rb +0 -152
  189. data/lib/ferret/search/prefix_query.rb +0 -54
  190. data/lib/ferret/search/query.rb +0 -140
  191. data/lib/ferret/search/query_filter.rb +0 -51
  192. data/lib/ferret/search/range_filter.rb +0 -103
  193. data/lib/ferret/search/range_query.rb +0 -139
  194. data/lib/ferret/search/req_excl_scorer.rb +0 -125
  195. data/lib/ferret/search/req_opt_sum_scorer.rb +0 -70
  196. data/lib/ferret/search/score_doc.rb +0 -38
  197. data/lib/ferret/search/score_doc_comparator.rb +0 -114
  198. data/lib/ferret/search/scorer.rb +0 -91
  199. data/lib/ferret/search/similarity.rb +0 -278
  200. data/lib/ferret/search/sloppy_phrase_scorer.rb +0 -47
  201. data/lib/ferret/search/sort.rb +0 -112
  202. data/lib/ferret/search/sort_comparator.rb +0 -60
  203. data/lib/ferret/search/sort_field.rb +0 -91
  204. data/lib/ferret/search/spans.rb +0 -12
  205. data/lib/ferret/search/spans/near_spans_enum.rb +0 -304
  206. data/lib/ferret/search/spans/span_first_query.rb +0 -79
  207. data/lib/ferret/search/spans/span_near_query.rb +0 -108
  208. data/lib/ferret/search/spans/span_not_query.rb +0 -130
  209. data/lib/ferret/search/spans/span_or_query.rb +0 -176
  210. data/lib/ferret/search/spans/span_query.rb +0 -25
  211. data/lib/ferret/search/spans/span_scorer.rb +0 -74
  212. data/lib/ferret/search/spans/span_term_query.rb +0 -105
  213. data/lib/ferret/search/spans/span_weight.rb +0 -84
  214. data/lib/ferret/search/spans/spans_enum.rb +0 -44
  215. data/lib/ferret/search/term_query.rb +0 -128
  216. data/lib/ferret/search/term_scorer.rb +0 -183
  217. data/lib/ferret/search/top_docs.rb +0 -36
  218. data/lib/ferret/search/top_field_docs.rb +0 -17
  219. data/lib/ferret/search/weight.rb +0 -54
  220. data/lib/ferret/search/wildcard_query.rb +0 -26
  221. data/lib/ferret/search/wildcard_term_enum.rb +0 -61
  222. data/lib/ferret/stemmers.rb +0 -1
  223. data/lib/ferret/stemmers/porter_stemmer.rb +0 -218
  224. data/lib/ferret/store.rb +0 -5
  225. data/lib/ferret/store/buffered_index_io.rb +0 -190
  226. data/lib/ferret/store/directory.rb +0 -141
  227. data/lib/ferret/store/fs_store.rb +0 -381
  228. data/lib/ferret/store/index_io.rb +0 -245
  229. data/lib/ferret/store/ram_store.rb +0 -286
  230. data/lib/ferret/utils.rb +0 -8
  231. data/lib/ferret/utils/bit_vector.rb +0 -123
  232. data/lib/ferret/utils/date_tools.rb +0 -138
  233. data/lib/ferret/utils/number_tools.rb +0 -91
  234. data/lib/ferret/utils/parameter.rb +0 -41
  235. data/lib/ferret/utils/priority_queue.rb +0 -120
  236. data/lib/ferret/utils/string_helper.rb +0 -47
  237. data/lib/ferret/utils/thread_local.rb +0 -28
  238. data/lib/ferret/utils/weak_key_hash.rb +0 -60
  239. data/lib/rferret.rb +0 -37
  240. data/rake_utils/code_statistics.rb +0 -106
  241. data/test/benchmark/tb_ram_store.rb +0 -76
  242. data/test/benchmark/tb_rw_vint.rb +0 -26
  243. data/test/functional/thread_safety_index_test.rb +0 -81
  244. data/test/functional/thread_safety_test.rb +0 -137
  245. data/test/longrunning/tc_numbertools.rb +0 -60
  246. data/test/longrunning/tm_store.rb +0 -19
  247. data/test/unit/analysis/ctc_analyzer.rb +0 -532
  248. data/test/unit/analysis/data/wordfile +0 -6
  249. data/test/unit/analysis/rtc_letter_tokenizer.rb +0 -20
  250. data/test/unit/analysis/rtc_lower_case_filter.rb +0 -20
  251. data/test/unit/analysis/rtc_lower_case_tokenizer.rb +0 -27
  252. data/test/unit/analysis/rtc_per_field_analyzer_wrapper.rb +0 -39
  253. data/test/unit/analysis/rtc_porter_stem_filter.rb +0 -16
  254. data/test/unit/analysis/rtc_standard_analyzer.rb +0 -20
  255. data/test/unit/analysis/rtc_standard_tokenizer.rb +0 -20
  256. data/test/unit/analysis/rtc_stop_analyzer.rb +0 -20
  257. data/test/unit/analysis/rtc_stop_filter.rb +0 -14
  258. data/test/unit/analysis/rtc_white_space_analyzer.rb +0 -21
  259. data/test/unit/analysis/rtc_white_space_tokenizer.rb +0 -20
  260. data/test/unit/analysis/rtc_word_list_loader.rb +0 -32
  261. data/test/unit/analysis/tc_token.rb +0 -25
  262. data/test/unit/document/rtc_field.rb +0 -28
  263. data/test/unit/document/tc_document.rb +0 -47
  264. data/test/unit/document/tc_field.rb +0 -98
  265. data/test/unit/index/rtc_compound_file_io.rb +0 -107
  266. data/test/unit/index/rtc_field_infos.rb +0 -127
  267. data/test/unit/index/rtc_fields_io.rb +0 -167
  268. data/test/unit/index/rtc_multiple_term_doc_pos_enum.rb +0 -83
  269. data/test/unit/index/rtc_segment_infos.rb +0 -74
  270. data/test/unit/index/rtc_segment_term_docs.rb +0 -17
  271. data/test/unit/index/rtc_segment_term_enum.rb +0 -60
  272. data/test/unit/index/rtc_segment_term_vector.rb +0 -71
  273. data/test/unit/index/rtc_term_buffer.rb +0 -57
  274. data/test/unit/index/rtc_term_info.rb +0 -19
  275. data/test/unit/index/rtc_term_infos_io.rb +0 -192
  276. data/test/unit/index/rtc_term_vectors_io.rb +0 -108
  277. data/test/unit/index/tc_term.rb +0 -27
  278. data/test/unit/index/tc_term_voi.rb +0 -18
  279. data/test/unit/search/rtc_similarity.rb +0 -37
  280. data/test/unit/search/rtc_sort_field.rb +0 -14
  281. data/test/unit/search/tc_multi_searcher2.rb +0 -126
  282. data/test/unit/store/rtc_fs_store.rb +0 -62
  283. data/test/unit/store/rtc_ram_store.rb +0 -15
  284. data/test/unit/store/rtm_store.rb +0 -150
  285. data/test/unit/store/rtm_store_lock.rb +0 -2
  286. data/test/unit/ts_document.rb +0 -2
  287. data/test/unit/utils/rtc_bit_vector.rb +0 -73
  288. data/test/unit/utils/rtc_date_tools.rb +0 -50
  289. data/test/unit/utils/rtc_number_tools.rb +0 -59
  290. data/test/unit/utils/rtc_parameter.rb +0 -40
  291. data/test/unit/utils/rtc_priority_queue.rb +0 -62
  292. data/test/unit/utils/rtc_string_helper.rb +0 -21
  293. data/test/unit/utils/rtc_thread.rb +0 -61
  294. data/test/unit/utils/rtc_weak_key_hash.rb +0 -25
  295. data/test/utils/number_to_spoken.rb +0 -132
data/ext/document.h CHANGED
@@ -1,62 +1,32 @@
1
1
  #ifndef FRT_DOCUMENT_H
2
2
  #define FRT_DOCUMENT_H
3
3
 
4
- #include <global.h>
5
- #include <hash.h>
6
- #include <array.h>
4
+ #include "global.h"
5
+ #include "hash.h"
7
6
 
8
7
  /****************************************************************************
9
8
  *
10
9
  * DocField
11
10
  *
12
11
  ****************************************************************************/
13
- enum {
14
- DF_STORE_YES = 0,
15
- DF_STORE_NO = 1,
16
- DF_STORE_COMPRESS = 2
17
- };
18
12
 
19
- enum {
20
- DF_INDEX_UNTOKENIZED = 0,
21
- DF_INDEX_TOKENIZED = 1,
22
- DF_INDEX_NO = 2,
23
- DF_INDEX_NO_NORMS = 3
24
- };
25
-
26
- enum {
27
- DF_TERM_VECTOR_NO = 0,
28
- DF_TERM_VECTOR_YES = 1,
29
- DF_TERM_VECTOR_WITH_POSITIONS = 2,
30
- DF_TERM_VECTOR_WITH_OFFSETS = 3,
31
- DF_TERM_VECTOR_WITH_POSITIONS_OFFSETS = 4
32
- };
33
-
34
- typedef struct DocField {
35
- char *name;
36
- char *data;
37
- int blen; /* used for binary fields to store data length */
38
- float boost;
39
- bool is_stored : 1;
40
- bool is_compressed : 1;
41
- bool is_indexed : 1;
42
- bool is_tokenized : 1;
43
- bool store_tv : 1;
44
- bool store_pos : 1;
45
- bool store_offset : 1;
46
- bool omit_norms : 1;
47
- bool is_binary : 1;
13
+ #define DF_INIT_CAPA 1
14
+ typedef struct DocField
15
+ {
16
+ char *name;
17
+ int size;
18
+ int capa;
19
+ int *lengths;
20
+ char **data;
21
+ float boost;
22
+ bool destroy_data : 1;
48
23
  } DocField;
49
24
 
50
- DocField *df_create(const char *name, char *data, int store, int index, int tv);
51
- DocField *df_clone(DocField *self);
52
- void df_set(DocField *df, const char *name, char *data, int store, int index, int tv);
53
- void df_destroy(DocField *df);
54
- void df_destroy_data(DocField *df);
55
- void df_set_store(DocField *df, int store);
56
- void df_set_index(DocField *df, int index);
57
- void df_set_term_vector(DocField *df, int tv);
58
- char *df_to_s(DocField *df);
59
- DocField *df_create_binary(char *name, char *data, int blen, int store);
25
+ extern DocField *df_new(const char *name);
26
+ extern DocField *df_add_data(DocField *df, char *data);
27
+ extern DocField *df_add_data_len(DocField *df, char *data, int len);
28
+ extern void df_destroy(DocField *df);
29
+ extern char *df_to_s(DocField *df);
60
30
 
61
31
  /****************************************************************************
62
32
  *
@@ -64,24 +34,20 @@ DocField *df_create_binary(char *name, char *data, int blen, int store);
64
34
  *
65
35
  ****************************************************************************/
66
36
 
67
- typedef struct Document {
68
- HshTable *fields;
69
- Array **field_arr;
70
- int fcnt;
71
- DocField **df_arr;
72
- int dfcnt;
73
- float boost;
74
- free_ft free_data;
37
+ #define DOC_INIT_CAPA 8
38
+ typedef struct Document
39
+ {
40
+ HashTable *field_dict;
41
+ int size;
42
+ int capa;
43
+ DocField **fields;
44
+ float boost;
75
45
  } Document;
76
46
 
77
- Document *doc_create();
78
- Document *doc_create_keep_data();
79
- void doc_destroy(Document *doc);
80
- void doc_add_field(Document *doc, DocField *df);
81
- DocField *doc_get_field(Document *doc, const char *fname);
82
- Array *doc_get_fields(Document *doc, const char *fname);
83
- Array *doc_remove_fields(Document *doc, const char *fname);
84
- DocField *doc_remove_field(Document *doc, const char *fname);
85
- bool doc_delete_fields(Document *doc, const char *fname);
86
- char *doc_to_s(Document *doc);
47
+ extern Document *doc_new();
48
+ extern DocField *doc_add_field(Document *doc, DocField *df);
49
+ extern DocField *doc_get_field(Document *doc, const char *fname);
50
+ extern char *doc_to_s(Document *doc);
51
+ extern void doc_destroy(Document *doc);
52
+
87
53
  #endif
data/ext/except.c CHANGED
@@ -1,61 +1,106 @@
1
+ #include <stdarg.h>
1
2
  #include "global.h"
2
3
  #include "except.h"
4
+ #include "threading.h"
3
5
 
6
+ /**
7
+ * Set this to false if you don't want to print the error location when an
8
+ * exception occurs.
9
+ */
4
10
  bool except_show_pos = true;
5
11
 
6
- char * const UNSUPPORTED_ERROR_MSG = "Unsupported operation";
7
- char * const EOF_ERROR_MSG = "Read past end of file";
12
+ const char *const FRT_ERROR_TYPES[] = {
13
+ "Body",
14
+ "Finally",
15
+ "Exception",
16
+ "IO Error",
17
+ "Argument Error",
18
+ "End-of-File Error",
19
+ "Unsupported Function Error",
20
+ "State Error",
21
+ "Parse Error",
22
+ "Memory Error",
23
+ "Index Error",
24
+ "Lock Error"
25
+ };
26
+
27
+ char *const UNSUPPORTED_ERROR_MSG = "Unsupported operation";
28
+ char *const EOF_ERROR_MSG = "Read past end of file";
29
+ char xmsg_buffer[2048];
30
+ char xmsg_buffer_final[2048];
8
31
 
9
32
  static thread_key_t exception_stack_key;
10
33
  static thread_once_t exception_stack_key_once = THREAD_ONCE_INIT;
11
34
 
12
- void exception_stack_alloc()
35
+ static void exception_stack_alloc(void)
13
36
  {
14
- thread_key_create(&exception_stack_key, NULL);
37
+ thread_key_create(&exception_stack_key, NULL);
15
38
  }
16
39
 
17
40
  void xpush_context(xcontext_t *context)
18
41
  {
19
- xcontext_t *top_context;
20
- thread_once(&exception_stack_key_once, *exception_stack_alloc);
21
- top_context = thread_getspecific(exception_stack_key);
22
- context->next = top_context;
23
- thread_setspecific(exception_stack_key, context);
24
- context->handled = true;
25
- context->in_finally = false;
42
+ xcontext_t *top_context;
43
+ thread_once(&exception_stack_key_once, *exception_stack_alloc);
44
+ top_context = thread_getspecific(exception_stack_key);
45
+ context->next = top_context;
46
+ thread_setspecific(exception_stack_key, context);
47
+ context->handled = true;
48
+ context->in_finally = false;
26
49
  }
27
50
 
28
- static inline void xraise_context(xcontext_t *context, int excode, char *msg)
51
+ static inline void xraise_context(xcontext_t *context,
52
+ volatile int excode,
53
+ const char *const msg)
29
54
  {
30
- context->msg = msg;
31
- context->excode = excode;
32
- context->handled = false;
33
- longjmp(context->jbuf, excode);
55
+ context->msg = msg;
56
+ context->excode = excode;
57
+ context->handled = false;
58
+ longjmp(context->jbuf, excode);
34
59
  }
35
60
 
36
- void xraise(int excode, char *msg)
61
+ #ifndef FRT_HAS_VARARGS
62
+ void RAISE(int excode, const char *fmt, ...)
37
63
  {
38
- xcontext_t *top_context;
39
- top_context = thread_getspecific(exception_stack_key);
40
- if (!top_context) {
41
- eprintf(EXCEPTION_CODE, "Error: exception %d not handled: %s", excode, msg);
42
- } else if (!top_context->in_finally) {
43
- xraise_context(top_context, excode, msg);
44
- } else if (top_context->handled) {
45
- top_context->msg = msg;
46
- top_context->excode = excode;
47
- top_context->handled = false;
48
- }
64
+ va_list args;
65
+ va_start(args, fmt);
66
+ vsprintf(xmsg_buffer, fmt, args);
67
+ xraise(excode, xmsg_buffer);
68
+ va_end(args);
69
+ }
70
+ #endif
71
+
72
+ void xraise(int excode, const char *const msg)
73
+ {
74
+ xcontext_t *top_context;
75
+ thread_once(&exception_stack_key_once, *exception_stack_alloc);
76
+ top_context = thread_getspecific(exception_stack_key);
77
+
78
+ if (!top_context) {
79
+ FRT_EXIT(FRT_ERROR_TYPES[excode], msg);
80
+ }
81
+ else if (!top_context->in_finally) {
82
+ xraise_context(top_context, excode, msg);
83
+ }
84
+ else if (top_context->handled) {
85
+ top_context->msg = msg;
86
+ top_context->excode = excode;
87
+ top_context->handled = false;
88
+ }
49
89
  }
50
90
 
51
91
  void xpop_context()
52
92
  {
53
- xcontext_t *top_context, *context;
54
- thread_once(&exception_stack_key_once, *exception_stack_alloc);
55
- top_context = thread_getspecific(exception_stack_key);
56
- context = top_context->next;
57
- thread_setspecific(exception_stack_key, context);
58
- if (!top_context->handled) {
59
- xraise_context(context, top_context->excode, top_context->msg);
60
- }
93
+ xcontext_t *top_cxt, *context;
94
+ thread_once(&exception_stack_key_once, *exception_stack_alloc);
95
+ top_cxt = thread_getspecific(exception_stack_key);
96
+ context = top_cxt->next;
97
+ thread_setspecific(exception_stack_key, context);
98
+ if (!top_cxt->handled) {
99
+ if (context) {
100
+ xraise_context(context, top_cxt->excode, top_cxt->msg);
101
+ }
102
+ else {
103
+ FRT_EXIT(FRT_ERROR_TYPES[top_cxt->excode], top_cxt->msg);
104
+ }
105
+ }
61
106
  }
data/ext/except.h CHANGED
@@ -1,90 +1,152 @@
1
+ /**
2
+ * Exception Handling Framework
3
+ *
4
+ * Exception Handling looks something like this;
5
+ *
6
+ * <pre>
7
+ * TRY
8
+ * RAISE(EXCEPTION, msg1);
9
+ * break;
10
+ * case EXCEPTION:
11
+ * // This should be called
12
+ * exception_handled = true;
13
+ * HANDLED();
14
+ * break;
15
+ * default:
16
+ * // shouldn't enter here
17
+ * break;
18
+ * XFINALLY
19
+ * // this code will always be run
20
+ * if (close_widget_one(arg) == 0) {
21
+ * RAISE(EXCEPTION_CODE, msg);
22
+ * }
23
+ * // this code will also always run, even if the above exception is
24
+ * // raised
25
+ * if (close_widget_two(arg) == 0) {
26
+ * RAISE(EXCEPTION_CODE, msg);
27
+ * }
28
+ * ENDTRY
29
+ * </pre>
30
+ *
31
+ * Basically exception handling uses the following macros;
32
+ *
33
+ * TRY
34
+ * Sets up the exception handler and need be placed before any expected
35
+ * exceptions would be raised.
36
+ *
37
+ * case <EXCEPTION_CODE>:
38
+ * Internally the exception handling uses a switch statement so use the case
39
+ * statement with the appropriate error code to catch Exceptions. Hence, if
40
+ * you want to catch all exceptions, use the default keyword.
41
+ *
42
+ * HANDLED
43
+ * If you catch and handle an exception you need to explicitely call
44
+ * HANDLED(); or the exeption will be re-raised once the current exception
45
+ * handling context is left.
46
+ *
47
+ * case FINALLY:
48
+ * Code in this block is always called. Use this block to close any
49
+ * resources opened in the Exception handling body.
50
+ *
51
+ * XFINALLY
52
+ * Similar to case FINALLY: except that any exceptions thrown in this block
53
+ * are ignored until the end of the block is reached at which time the first
54
+ * exception which was raise will be re-raised. This is useful for closing a
55
+ * number of resources that all might raise exceptions so as much as
56
+ * possible will be successfully closed.
57
+ *
58
+ * ENDTRY
59
+ * Must be placed at the end of all exception handling code.
60
+ */
61
+
1
62
  #ifndef FRT_EXCEPT_H
2
63
  #define FRT_EXCEPT_H
3
64
 
4
65
  #include <setjmp.h>
5
- #include <ruby.h>
66
+ #include "defines.h"
6
67
 
7
68
  #define BODY 0
8
- #define FINALLY -1
9
- #define EXCEPTION 1
10
- #define IO_ERROR 2
11
- #define ARG_ERROR 3
12
- #define EOF_ERROR 4
13
- #define UNSUPPORTED_ERROR 5
14
- #define STATE_ERROR 6
15
- #define PARSE_ERROR 7
16
- #define MEM_ERROR 8
17
-
18
- typedef struct xcontext_t {
19
- jmp_buf jbuf;
20
- struct xcontext_t *next;
21
- char *msg;
22
- volatile int excode;
23
- int handled : 1;
24
- int in_finally : 1;
25
- } xcontext_t;
69
+ #define FINALLY 1
70
+ #define EXCEPTION 2
71
+ #define ERROR 2
72
+ #define IO_ERROR 3
73
+ #define ARG_ERROR 4
74
+ #define EOF_ERROR 5
75
+ #define UNSUPPORTED_ERROR 6
76
+ #define STATE_ERROR 7
77
+ #define PARSE_ERROR 8
78
+ #define MEM_ERROR 9
79
+ #define INDEX_ERROR 10
80
+ #define LOCK_ERROR 11
81
+
82
+ extern char *const UNSUPPORTED_ERROR_MSG;
83
+ extern char *const EOF_ERROR_MSG;
84
+ extern bool except_show_pos;
26
85
 
27
- RUBY_EXTERN int rb_thread_critical;
28
- extern xcontext_t *xtop_context;
86
+ typedef struct xcontext_t
87
+ {
88
+ jmp_buf jbuf;
89
+ struct xcontext_t *next;
90
+ const char *msg;
91
+ volatile int excode;
92
+ unsigned int handled : 1;
93
+ unsigned int in_finally : 1;
94
+ } xcontext_t;
29
95
 
30
96
  #define TRY\
31
97
  do {\
32
98
  xcontext_t xcontext;\
33
- rb_thread_critical = Qtrue;\
34
- xcontext.next = xtop_context;\
35
- xtop_context = &xcontext;\
36
- xcontext.handled = true;\
37
- xcontext.in_finally = false;\
99
+ xpush_context(&xcontext);\
38
100
  switch (setjmp(xcontext.jbuf)) {\
39
101
  case BODY:
40
102
 
41
103
 
42
104
  #define XENDTRY\
43
105
  }\
44
- xtop_context = xcontext.next;\
45
- if (!xcontext.handled) {\
46
- RAISE(xcontext.excode, xcontext.msg);\
47
- }\
48
- rb_thread_critical = 0;\
106
+ xpop_context();\
49
107
  } while (0);
50
108
 
51
109
  #define ENDTRY\
52
110
  }\
53
111
  if (!xcontext.in_finally) {\
54
- xtop_context = xcontext.next;\
55
- if (!xcontext.handled) {\
56
- RAISE(xcontext.excode, xcontext.msg);\
57
- }\
112
+ xpop_context();\
58
113
  xcontext.in_finally = 1;\
59
114
  longjmp(xcontext.jbuf, FINALLY);\
60
115
  }\
61
- rb_thread_critical = 0;\
62
116
  } while (0);
63
117
 
64
118
  #define XFINALLY default: xcontext.in_finally = 1;
65
119
 
66
120
  #define XCATCHALL break; default: xcontext.in_finally = 1;
67
121
 
68
- //fprintf(stderr,"Error occured in %s, %d: %s\n", __FILE__, __LINE__, __func__);
69
- #define RAISE(xexcode, xmsg) \
70
- do {\
71
- if (!xtop_context) {\
72
- eprintf(EXCEPTION_CODE, "Error: exception %d not handled: %s", xexcode, xmsg);\
73
- } else if (!xtop_context->in_finally) {\
74
- xtop_context->msg = xmsg;\
75
- xtop_context->excode = xexcode;\
76
- xtop_context->handled = false;\
77
- longjmp(xtop_context->jbuf, xexcode);\
78
- } else if (xtop_context->handled) {\
79
- xtop_context->msg = xmsg;\
80
- xtop_context->excode = xexcode;\
81
- xtop_context->handled = false;\
82
- }\
83
- } while (0)
122
+ #define HANDLED() xcontext.handled = 1; /* true */
123
+
124
+ #ifdef FRT_HAS_ISO_VARARGS
125
+ # define RAISE(excode, ...) do {\
126
+ sprintf(xmsg_buffer, __VA_ARGS__);\
127
+ sprintf(xmsg_buffer_final, "Error occured in %s:%d - %s\n\t%s\n",\
128
+ __FILE__, __LINE__, __func__, xmsg_buffer);\
129
+ xraise(excode, xmsg_buffer_final);\
130
+ } while (0)
131
+ #elif defined(FRT_HAS_GNUC_VARARGS)
132
+ # define RAISE(excode, args...) do {\
133
+ sprintf(xmsg_buffer, ##args);\
134
+ sprintf(xmsg_buffer_final, "Error occured in %s:%d - %s\n\t%s\n",\
135
+ __FILE__, __LINE__, __func__, xmsg_buffer);\
136
+ xraise(excode, xmsg_buffer_final);\
137
+ } while (0)
138
+
139
+ #else
140
+ extern void RAISE(int excode, const char *fmt, ...);
141
+ #endif
142
+ #define RAISE_HELL() RAISE(ERROR, "Hell")
143
+
84
144
 
85
- #define HANDLED() xcontext.handled = 1 /* true */
145
+ extern void xraise(int excode, const char *const msg);
146
+ extern void xpush_context(xcontext_t *context);
147
+ extern void xpop_context();
86
148
 
87
- extern char * const UNSUPPORTED_ERROR_MSG;
88
- extern char * const EOF_ERROR_MSG;
149
+ extern char xmsg_buffer[2048];
150
+ extern char xmsg_buffer_final[2048];
89
151
 
90
152
  #endif