ferret 0.10.1 → 0.10.2
Sign up to get free protection for your applications and to get access to all the features.
- 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 */
|