ferret 0.10.1 → 0.10.2
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.
- data/Rakefile +7 -1
- data/ext/analysis.c +21 -13
- data/ext/array.c +1 -1
- data/ext/bitvector.c +2 -2
- data/ext/defines.h +0 -6
- data/ext/except.c +6 -6
- data/ext/except.h +12 -8
- data/ext/extconf.rb +1 -0
- data/ext/ferret.c +4 -0
- data/ext/ferret.h +1 -0
- data/ext/fs_store.c +18 -4
- data/ext/global.c +18 -16
- data/ext/global.h +7 -2
- data/ext/hash.c +1 -1
- data/ext/helper.c +1 -1
- data/ext/helper.h +1 -1
- data/ext/inc/lang.h +7 -1
- data/ext/ind.c +4 -4
- data/ext/ind.h +3 -3
- data/ext/index.c +33 -26
- data/ext/index.h +1 -1
- data/ext/lang.h +7 -1
- data/ext/mem_pool.c +1 -1
- data/ext/mem_pool.h +1 -1
- data/ext/q_fuzzy.c +2 -2
- data/ext/q_match_all.c +2 -2
- data/ext/q_multi_term.c +1 -1
- data/ext/q_parser.c +60 -52
- data/ext/r_analysis.c +6 -4
- data/ext/r_index.c +57 -4
- data/ext/r_search.c +1 -1
- data/ext/r_utils.c +1 -1
- data/ext/ram_store.c +1 -1
- data/ext/search.c +4 -4
- data/ext/sort.c +3 -3
- data/ext/store.c +9 -9
- data/ext/store.h +4 -4
- data/ext/tags +7841 -0
- data/ext/term_vectors.c +3 -3
- data/lib/ferret/index.rb +69 -7
- data/test/test_helper.rb +3 -2
- data/test/unit/analysis/tc_token_stream.rb +1 -0
- data/test/unit/index/tc_index.rb +157 -2
- data/test/unit/index/tc_index_reader.rb +108 -5
- data/test/unit/query_parser/tc_query_parser.rb +2 -1
- data/test/unit/search/tc_index_searcher.rb +1 -1
- data/test/unit/search/tc_multi_searcher.rb +2 -1
- data/test/unit/search/tc_spans.rb +1 -1
- data/test/unit/store/tc_fs_store.rb +6 -3
- data/test/unit/ts_analysis.rb +1 -1
- data/test/unit/ts_utils.rb +1 -1
- data/test/unit/utils/tc_number_tools.rb +1 -1
- metadata +138 -137
data/Rakefile
CHANGED
@@ -34,6 +34,7 @@ EXT_SRC = FileList["../c/src/*.[c]", "../c/include/*.h",
|
|
34
34
|
"../c/lib/libstemmer_c/runtime/*.[ch]",
|
35
35
|
"../c/lib/libstemmer_c/libstemmer/*.[ch]",
|
36
36
|
"../c/lib/libstemmer_c/include/libstemmer.h"]
|
37
|
+
EXT_SRC.exclude('../**/ind.[ch]')
|
37
38
|
|
38
39
|
EXT_SRC_DEST = EXT_SRC.map {|fn| File.join("ext", File.basename(fn))}
|
39
40
|
SRC = (FileList["ext/*.[ch]"] + EXT_SRC_DEST).uniq
|
@@ -94,7 +95,12 @@ end
|
|
94
95
|
EXT_SRC.each do |fn|
|
95
96
|
dest_fn = File.join("ext", File.basename(fn))
|
96
97
|
file dest_fn => fn do |t|
|
97
|
-
|
98
|
+
begin
|
99
|
+
ln_s File.join("..", fn), dest_fn
|
100
|
+
rescue Exception => e
|
101
|
+
cp File.expand_path(fn), dest_fn
|
102
|
+
end
|
103
|
+
|
98
104
|
if fn =~ /stemmer/
|
99
105
|
# flatten the directory structure for lib_stemmer
|
100
106
|
open(dest_fn) do |in_f|
|
data/ext/analysis.c
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
*
|
13
13
|
****************************************************************************/
|
14
14
|
|
15
|
-
|
15
|
+
__inline Token *tk_set(Token *tk,
|
16
16
|
char *text, int tlen, int start, int end, int pos_inc)
|
17
17
|
{
|
18
18
|
if (tlen >= MAX_WORD_SIZE) {
|
@@ -27,20 +27,20 @@ inline Token *tk_set(Token *tk,
|
|
27
27
|
return tk;
|
28
28
|
}
|
29
29
|
|
30
|
-
|
30
|
+
__inline Token *tk_set_ts(Token *tk,
|
31
31
|
char *start, char *end, char *text, int pos_inc)
|
32
32
|
{
|
33
33
|
return tk_set(tk, start, (int)(end - start),
|
34
34
|
(int)(start - text), (int)(end - text), pos_inc);
|
35
35
|
}
|
36
36
|
|
37
|
-
|
37
|
+
__inline Token *tk_set_no_len(Token *tk,
|
38
38
|
char *text, int start, int end, int pos_inc)
|
39
39
|
{
|
40
40
|
return tk_set(tk, text, (int)strlen(text), start, end, pos_inc);
|
41
41
|
}
|
42
42
|
|
43
|
-
|
43
|
+
__inline Token *w_tk_set(Token *tk, wchar_t *text, int start, int end,
|
44
44
|
int pos_inc)
|
45
45
|
{
|
46
46
|
int len = wcstombs(tk->text, text, MAX_WORD_SIZE - 1);
|
@@ -151,7 +151,7 @@ static TokenStream *cts_new()
|
|
151
151
|
|
152
152
|
#define MBTS(token_stream) ((MultiByteTokenStream *)(token_stream))
|
153
153
|
|
154
|
-
|
154
|
+
__inline int mb_next_char(wchar_t *wchr, const char *s, mbstate_t *state)
|
155
155
|
{
|
156
156
|
int num_bytes;
|
157
157
|
if ((num_bytes = (int)mbrtowc(wchr, s, MB_CUR_MAX, state)) < 0) {
|
@@ -161,7 +161,7 @@ inline int mb_next_char(wchar_t *wchr, const char *s, mbstate_t *state)
|
|
161
161
|
ZEROSET(state, mbstate_t);
|
162
162
|
num_bytes = (int)mbrtowc(wchr, t, MB_CUR_MAX, state);
|
163
163
|
} while ((num_bytes < 0) && (*wchr != 0) && (*t != 0));
|
164
|
-
num_bytes
|
164
|
+
num_bytes = t - s;
|
165
165
|
}
|
166
166
|
return num_bytes;
|
167
167
|
}
|
@@ -774,6 +774,7 @@ static bool std_advance_to_start(TokenStream *ts)
|
|
774
774
|
{
|
775
775
|
char *t = ts->t;
|
776
776
|
while (*t != '\0' && !isalnum(*t)) {
|
777
|
+
if (isnumpunc(*t) && isdigit(t[1])) break;
|
777
778
|
t++;
|
778
779
|
}
|
779
780
|
|
@@ -790,7 +791,8 @@ static bool mb_std_advance_to_start(TokenStream *ts)
|
|
790
791
|
|
791
792
|
i = mb_next_char(&wchr, ts->t, &state);
|
792
793
|
|
793
|
-
while (wchr != 0 && !
|
794
|
+
while (wchr != 0 && !iswalpha(wchr) && !isdigit(*(ts->t))) {
|
795
|
+
if (isnumpunc(*ts->t) && isdigit(ts->t[1])) break;
|
794
796
|
ts->t += i;
|
795
797
|
i = mb_next_char(&wchr, ts->t, &state);
|
796
798
|
}
|
@@ -817,8 +819,9 @@ static Token *std_next(TokenStream *ts)
|
|
817
819
|
}
|
818
820
|
|
819
821
|
start = t = ts->t;
|
820
|
-
if (isdigit(*t))
|
821
|
-
|
822
|
+
if ((isdigit(*t) || isnumpunc(*t))
|
823
|
+
&& ((len = std_get_number(t)) > 0)) {
|
824
|
+
t += len;
|
822
825
|
ts->t = t;
|
823
826
|
tk_set_ts(&(CTS(ts)->token), start, t, ts->text, 1);
|
824
827
|
}
|
@@ -850,8 +853,9 @@ static Token *std_next(TokenStream *ts)
|
|
850
853
|
return tk_set_ts(&(CTS(ts)->token), start, t, ts->text, 1);
|
851
854
|
}
|
852
855
|
|
853
|
-
if (isdigit(*t) || isnumpunc(*t))
|
854
|
-
|
856
|
+
if ((isdigit(*t) || isnumpunc(*t)) /* possibly a number */
|
857
|
+
&& (len = std_get_number(t) > 0)) {
|
858
|
+
num_end = start + len;
|
855
859
|
if (!std_tz->is_tok_char(num_end)) { /* won't find a longer token */
|
856
860
|
ts->t = num_end;
|
857
861
|
return tk_set_ts(&(CTS(ts)->token), start, num_end, ts->text, 1);
|
@@ -908,7 +912,7 @@ static Token *std_next(TokenStream *ts)
|
|
908
912
|
t--; /* strip trailing punctuation */
|
909
913
|
}
|
910
914
|
|
911
|
-
if (t > num_end) {
|
915
|
+
if (num_end == NULL || t > num_end) {
|
912
916
|
ts->t = t;
|
913
917
|
|
914
918
|
if (is_acronym) { /* check it is one letter followed by one '.' */
|
@@ -1132,13 +1136,17 @@ Token *mb_lcf_next(TokenStream *ts)
|
|
1132
1136
|
return tk;
|
1133
1137
|
}
|
1134
1138
|
|
1135
|
-
mbstowcs(wbuf, tk->text, MAX_WORD_SIZE);
|
1139
|
+
if (mbstowcs(wbuf, tk->text, MAX_WORD_SIZE) <= 0) return tk;
|
1136
1140
|
wchr = wbuf;
|
1137
1141
|
while (*wchr != 0) {
|
1138
1142
|
*wchr = towlower(*wchr);
|
1139
1143
|
wchr++;
|
1140
1144
|
}
|
1141
1145
|
tk->len = wcstombs(tk->text, wbuf, MAX_WORD_SIZE);
|
1146
|
+
if (tk->len <= 0) {
|
1147
|
+
strcpy(tk->text, "BAD_DATA");
|
1148
|
+
tk->len = 8;
|
1149
|
+
}
|
1142
1150
|
tk->text[tk->len] = '\0';
|
1143
1151
|
return tk;
|
1144
1152
|
}
|
data/ext/array.c
CHANGED
data/ext/bitvector.c
CHANGED
@@ -190,7 +190,7 @@ const int NUM_TRAILING_ZEROS[] = {
|
|
190
190
|
/*
|
191
191
|
* This method is highly optimized, hence the loop unrolling
|
192
192
|
*/
|
193
|
-
static
|
193
|
+
static __inline int bv_get_1_offset(f_u32 word)
|
194
194
|
{
|
195
195
|
if (word & 0xff) {
|
196
196
|
return NUM_TRAILING_ZEROS[word & 0xff];
|
@@ -397,7 +397,7 @@ BitVector *bv_and_x(BitVector *bv1, BitVector *bv2)
|
|
397
397
|
return bv_and_i(bv1, bv1, bv2);
|
398
398
|
}
|
399
399
|
|
400
|
-
static
|
400
|
+
static __inline void bv_recapa(BitVector *bv, int new_capa)
|
401
401
|
{
|
402
402
|
if (bv->capa < new_capa) {
|
403
403
|
REALLOC_N(bv->bits, f_u32, new_capa);
|
data/ext/defines.h
CHANGED
@@ -30,20 +30,14 @@ typedef posh_i64_t f_i64;
|
|
30
30
|
#endif
|
31
31
|
|
32
32
|
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
|
33
|
-
#define FRT_HAS_INLINE
|
34
33
|
#define FRT_IS_C99
|
35
34
|
#define FRT_HAS_ISO_VARARGS
|
36
35
|
#define FRT_HAS_VARARGS
|
37
36
|
#endif
|
38
37
|
|
39
38
|
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
40
|
-
#define FRT_HAS_INLINE
|
41
39
|
#define FRT_HAS_GNUC_VARARGS
|
42
40
|
#define FRT_HAS_VARARGS
|
43
41
|
#endif
|
44
42
|
|
45
|
-
#ifndef FRT_HAS_INLINE
|
46
|
-
# define inline
|
47
|
-
#endif
|
48
|
-
|
49
43
|
#endif
|
data/ext/except.c
CHANGED
@@ -26,8 +26,8 @@ const char *const FRT_ERROR_TYPES[] = {
|
|
26
26
|
|
27
27
|
char *const UNSUPPORTED_ERROR_MSG = "Unsupported operation";
|
28
28
|
char *const EOF_ERROR_MSG = "Read past end of file";
|
29
|
-
char xmsg_buffer[
|
30
|
-
char xmsg_buffer_final[
|
29
|
+
char xmsg_buffer[XMSG_BUFFER_SIZE];
|
30
|
+
char xmsg_buffer_final[XMSG_BUFFER_SIZE];
|
31
31
|
|
32
32
|
static thread_key_t exception_stack_key;
|
33
33
|
static thread_once_t exception_stack_key_once = THREAD_ONCE_INIT;
|
@@ -48,9 +48,9 @@ void xpush_context(xcontext_t *context)
|
|
48
48
|
context->in_finally = false;
|
49
49
|
}
|
50
50
|
|
51
|
-
static
|
52
|
-
|
53
|
-
|
51
|
+
static __inline void xraise_context(xcontext_t *context,
|
52
|
+
volatile int excode,
|
53
|
+
const char *const msg)
|
54
54
|
{
|
55
55
|
context->msg = msg;
|
56
56
|
context->excode = excode;
|
@@ -63,7 +63,7 @@ void RAISE(int excode, const char *fmt, ...)
|
|
63
63
|
{
|
64
64
|
va_list args;
|
65
65
|
va_start(args, fmt);
|
66
|
-
|
66
|
+
vsnprintf(xmsg_buffer, XMSG_BUFFER_SIZE, fmt, args);
|
67
67
|
xraise(excode, xmsg_buffer);
|
68
68
|
va_end(args);
|
69
69
|
}
|
data/ext/except.h
CHANGED
@@ -68,7 +68,7 @@
|
|
68
68
|
#define BODY 0
|
69
69
|
#define FINALLY 1
|
70
70
|
#define EXCEPTION 2
|
71
|
-
#define
|
71
|
+
#define FERRET_ERROR 2
|
72
72
|
#define IO_ERROR 3
|
73
73
|
#define ARG_ERROR 4
|
74
74
|
#define EOF_ERROR 5
|
@@ -121,17 +121,21 @@ typedef struct xcontext_t
|
|
121
121
|
|
122
122
|
#define HANDLED() xcontext.handled = 1; /* true */
|
123
123
|
|
124
|
+
#define XMSG_BUFFER_SIZE 2048
|
125
|
+
|
124
126
|
#ifdef FRT_HAS_ISO_VARARGS
|
125
127
|
# define RAISE(excode, ...) do {\
|
126
|
-
|
127
|
-
|
128
|
+
snprintf(xmsg_buffer, XMSG_BUFFER_SIZE, __VA_ARGS__);\
|
129
|
+
snprintf(xmsg_buffer_final, XMSG_BUFFER_SIZE,\
|
130
|
+
"Error occured in %s:%d - %s\n\t%s\n",\
|
128
131
|
__FILE__, __LINE__, __func__, xmsg_buffer);\
|
129
132
|
xraise(excode, xmsg_buffer_final);\
|
130
133
|
} while (0)
|
131
134
|
#elif defined(FRT_HAS_GNUC_VARARGS)
|
132
135
|
# define RAISE(excode, args...) do {\
|
133
|
-
|
134
|
-
|
136
|
+
snprintf(xmsg_buffer, XMSG_BUFFER_SIZE, ##args);\
|
137
|
+
snprintf(xmsg_buffer_final, XMSG_BUFFER_SIZE,\
|
138
|
+
"Error occured in %s:%d - %s\n\t%s\n",\
|
135
139
|
__FILE__, __LINE__, __func__, xmsg_buffer);\
|
136
140
|
xraise(excode, xmsg_buffer_final);\
|
137
141
|
} while (0)
|
@@ -139,14 +143,14 @@ typedef struct xcontext_t
|
|
139
143
|
#else
|
140
144
|
extern void RAISE(int excode, const char *fmt, ...);
|
141
145
|
#endif
|
142
|
-
#define RAISE_HELL() RAISE(
|
146
|
+
#define RAISE_HELL() RAISE(FERRET_ERROR, "Hell")
|
143
147
|
|
144
148
|
|
145
149
|
extern void xraise(int excode, const char *const msg);
|
146
150
|
extern void xpush_context(xcontext_t *context);
|
147
151
|
extern void xpop_context();
|
148
152
|
|
149
|
-
extern char xmsg_buffer[
|
150
|
-
extern char xmsg_buffer_final[
|
153
|
+
extern char xmsg_buffer[XMSG_BUFFER_SIZE];
|
154
|
+
extern char xmsg_buffer_final[XMSG_BUFFER_SIZE];
|
151
155
|
|
152
156
|
#endif
|
data/ext/extconf.rb
CHANGED
data/ext/ferret.c
CHANGED
@@ -15,6 +15,7 @@ ID id_less_than;
|
|
15
15
|
ID id_lt;
|
16
16
|
ID id_call;
|
17
17
|
ID id_is_directory;
|
18
|
+
ID id_close;
|
18
19
|
ID id_data;
|
19
20
|
|
20
21
|
static ID id_mkdir_p;
|
@@ -182,6 +183,8 @@ VALUE frt_get_error(const char *err_type)
|
|
182
183
|
#ifdef FRT_HAS_VARARGS
|
183
184
|
void vfrt_rb_raise(const char *file, int line_num, const char *func,
|
184
185
|
const char *err_type, const char *fmt, va_list args)
|
186
|
+
#else
|
187
|
+
void V_FRT_EXIT(const char *err_type, const char *fmt, va_list args)
|
185
188
|
#endif
|
186
189
|
{
|
187
190
|
char buf[FRT_BUF_SIZ];
|
@@ -250,6 +253,7 @@ void Init_ferret_ext(void)
|
|
250
253
|
|
251
254
|
id_mkdir_p = rb_intern("mkdir_p");
|
252
255
|
id_is_directory = rb_intern("directory?");
|
256
|
+
id_close = rb_intern("close");
|
253
257
|
|
254
258
|
id_data = rb_intern("@data");
|
255
259
|
|
data/ext/ferret.h
CHANGED
data/ext/fs_store.c
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#include "store.h"
|
2
|
+
#include <time.h>
|
2
3
|
#include <sys/types.h>
|
3
4
|
#include <fcntl.h>
|
4
5
|
#include <sys/stat.h>
|
@@ -41,7 +42,7 @@ extern int file_is_lock(char *filename);
|
|
41
42
|
*/
|
42
43
|
static char *join_path(char *buf, const char *base, const char *filename)
|
43
44
|
{
|
44
|
-
|
45
|
+
snprintf(buf, MAX_FILE_PATH, "%s"DIR_SEPARATOR"%s", base, filename);
|
45
46
|
return buf;
|
46
47
|
}
|
47
48
|
|
@@ -330,6 +331,10 @@ static InStream *fs_open_input(Store *store, const char *filename)
|
|
330
331
|
|
331
332
|
#define LOCK_OBTAIN_TIMEOUT 5
|
332
333
|
|
334
|
+
#ifdef RUBY_BINDINGS
|
335
|
+
struct timeval rb_time_interval _((VALUE));
|
336
|
+
#endif
|
337
|
+
|
333
338
|
static int fs_lock_obtain(Lock *lock)
|
334
339
|
{
|
335
340
|
int f;
|
@@ -337,9 +342,18 @@ static int fs_lock_obtain(Lock *lock)
|
|
337
342
|
while (((f =
|
338
343
|
open(lock->name, O_CREAT | O_EXCL | O_RDWR,
|
339
344
|
S_IRUSR | S_IWUSR)) < 0) && (trys > 0)) {
|
345
|
+
|
346
|
+
#ifdef RUBY_BINDINGS
|
347
|
+
rb_thread_wait_for(rb_time_interval(rb_float_new(0.01)));
|
348
|
+
#endif
|
340
349
|
trys--;
|
341
|
-
/*
|
342
|
-
|
350
|
+
/* sleep for 10 milliseconds
|
351
|
+
clock_t start = clock();
|
352
|
+
trys--;
|
353
|
+
|
354
|
+
while (((double)(clock() - start) / CLOCKS_PER_SEC) < 0.01) {
|
355
|
+
}
|
356
|
+
*/
|
343
357
|
}
|
344
358
|
if (f >= 0) {
|
345
359
|
close(f);
|
@@ -375,7 +389,7 @@ static Lock *fs_open_lock(Store *store, char *lockname)
|
|
375
389
|
Lock *lock = ALLOC(Lock);
|
376
390
|
char lname[100];
|
377
391
|
char path[MAX_FILE_PATH];
|
378
|
-
|
392
|
+
snprintf(lname, 100, "%s%s.lck", LOCK_PREFIX, lockname);
|
379
393
|
lock->name = estrdup(join_path(path, store->dir.path, lname));
|
380
394
|
lock->store = store;
|
381
395
|
lock->obtain = &fs_lock_obtain;
|
data/ext/global.c
CHANGED
@@ -11,22 +11,22 @@ const char *EMPTY_STRING = "";
|
|
11
11
|
|
12
12
|
bool x_do_logging = false;
|
13
13
|
|
14
|
-
|
14
|
+
__inline int min3(int a, int b, int c)
|
15
15
|
{
|
16
16
|
return MIN3(a, b, c);
|
17
17
|
}
|
18
18
|
|
19
|
-
|
19
|
+
__inline int min2(int a, int b)
|
20
20
|
{
|
21
21
|
return MIN(a, b);
|
22
22
|
}
|
23
23
|
|
24
|
-
|
24
|
+
__inline int max3(int a, int b, int c)
|
25
25
|
{
|
26
26
|
return MAX3(a, b, c);
|
27
27
|
}
|
28
28
|
|
29
|
-
|
29
|
+
__inline int max2(int a, int b)
|
30
30
|
{
|
31
31
|
return MAX(a, b);
|
32
32
|
}
|
@@ -56,13 +56,14 @@ int icmp_risky(const void *p1, const void *p2)
|
|
56
56
|
}
|
57
57
|
|
58
58
|
|
59
|
+
#ifndef RUBY_BINDINGS
|
59
60
|
/* frt_exit: print error message and exit */
|
60
|
-
#ifdef FRT_HAS_VARARGS
|
61
|
+
# ifdef FRT_HAS_VARARGS
|
61
62
|
void vfrt_exit(const char *file, int line_num, const char *func,
|
62
63
|
const char *err_type, const char *fmt, va_list args)
|
63
|
-
#else
|
64
|
+
# else
|
64
65
|
void V_FRT_EXIT(const char *err_type, const char *fmt, va_list args)
|
65
|
-
#endif
|
66
|
+
# endif
|
66
67
|
{
|
67
68
|
fflush(stdout);
|
68
69
|
fprintf(stderr, "\n");
|
@@ -70,12 +71,12 @@ void V_FRT_EXIT(const char *err_type, const char *fmt, va_list args)
|
|
70
71
|
fprintf(stderr, "%s: ", progname());
|
71
72
|
}
|
72
73
|
|
73
|
-
#ifdef FRT_HAS_VARARGS
|
74
|
+
# ifdef FRT_HAS_VARARGS
|
74
75
|
fprintf(stderr, "%s occured at <%s>:%d in %s\n",
|
75
76
|
err_type, file, line_num, func);
|
76
|
-
#else
|
77
|
+
# else
|
77
78
|
fprintf(stderr, "%s occured:\n", err_type);
|
78
|
-
#endif
|
79
|
+
# endif
|
79
80
|
vfprintf(stderr, fmt, args);
|
80
81
|
|
81
82
|
if (fmt[0] != '\0' && fmt[strlen(fmt) - 1] == ':') {
|
@@ -87,22 +88,23 @@ void V_FRT_EXIT(const char *err_type, const char *fmt, va_list args)
|
|
87
88
|
}
|
88
89
|
|
89
90
|
|
90
|
-
#ifdef FRT_HAS_VARARGS
|
91
|
+
# ifdef FRT_HAS_VARARGS
|
91
92
|
void frt_exit(const char *file, int line_num, const char *func,
|
92
93
|
const char *err_type, const char *fmt, ...)
|
93
|
-
#else
|
94
|
+
# else
|
94
95
|
void FRT_EXIT(const char *err_type, const char *fmt, ...)
|
95
|
-
#endif
|
96
|
+
# endif
|
96
97
|
{
|
97
98
|
va_list args;
|
98
99
|
va_start(args, fmt);
|
99
|
-
#ifdef FRT_HAS_VARARGS
|
100
|
+
# ifdef FRT_HAS_VARARGS
|
100
101
|
vfrt_exit(file, line_num, func, err_type, fmt, args);
|
101
|
-
#else
|
102
|
+
# else
|
102
103
|
V_FRT_EXIT(err_type, fmt, args);
|
103
|
-
#endif
|
104
|
+
# endif
|
104
105
|
va_end(args);
|
105
106
|
}
|
107
|
+
#endif
|
106
108
|
|
107
109
|
|
108
110
|
/* weprintf: print error message and don't exit */
|