rroonga 2.1.2 → 2.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -127,14 +127,18 @@ def extract_groonga_win32_binary(major, minor, micro)
127
127
  message(" done\n")
128
128
 
129
129
  if File.exist?(install_dir)
130
- message("remove old install... #{install_dir}")
130
+ message("removing old install... #{install_dir}")
131
131
  FileUtils.rm_rf(install_dir)
132
132
  message(" done\n")
133
133
  end
134
134
 
135
- message("install...")
135
+ message("installing...")
136
136
  FileUtils.mv(File.basename(zip, ".zip"), install_dir)
137
137
  message(" done\n")
138
+
139
+ message("removing binary archive...")
140
+ FileUtils.rm_rf(zip)
141
+ message(" done\n")
138
142
  end
139
143
 
140
144
  def configure_command_line(prefix)
@@ -143,6 +147,8 @@ def configure_command_line(prefix)
143
147
  debug_flags = ["CFLAGS=-ggdb3 -O0", "CXXFLAGS=-ggdb3 -O0"]
144
148
  command_line.concat(debug_flags) if debug_build_p
145
149
  command_line << "--prefix=#{prefix}"
150
+ command_line << "--disable-static"
151
+ command_line << "--disable-document"
146
152
  escaped_command_line = command_line.collect do |command|
147
153
  Shellwords.escape(command)
148
154
  end
@@ -190,6 +196,14 @@ def build_groonga(major, minor, micro)
190
196
  exit(false)
191
197
  end
192
198
  end
199
+
200
+ message("removing source...")
201
+ FileUtils.rm_rf(groonga_source_dir)
202
+ message(" done\n")
203
+
204
+ message("removing source archive...")
205
+ FileUtils.rm_rf(tar_gz)
206
+ message(" done\n")
193
207
  end
194
208
 
195
209
  unless PKGConfig.have_package(package_name, major, minor, micro)
@@ -1,6 +1,6 @@
1
1
  /* -*- coding: utf-8; c-file-style: "ruby" -*- */
2
2
  /*
3
- Copyright (C) 2009-2011 Kouhei Sutou <kou@clear-code.com>
3
+ Copyright (C) 2009-2013 Kouhei Sutou <kou@clear-code.com>
4
4
 
5
5
  This library is free software; you can redistribute it and/or
6
6
  modify it under the terms of the GNU Lesser General Public
@@ -18,12 +18,6 @@
18
18
 
19
19
  #include "rb-grn.h"
20
20
 
21
- /* FIXME */
22
- void grn_log_reopen(grn_ctx *ctx);
23
- extern const char *grn_log_path;
24
- extern const char *grn_qlog_path;
25
-
26
-
27
21
  /*
28
22
  * Document-class: Groonga::Logger
29
23
  *
@@ -31,63 +25,20 @@ extern const char *grn_qlog_path;
31
25
  *
32
26
  */
33
27
 
34
- #define RVAL2GRNWRAPPER(object) (rb_grn_logger_info_wrapper_from_ruby_object(object))
35
- #define RVAL2GRNLOGLEVEL(object) (rb_grn_log_level_from_ruby_object(object))
36
- #define GRNLOGLEVEL2RVAL(level) (rb_grn_log_level_to_ruby_object(level))
28
+ #define GRNLOGLEVEL2RVAL(level) (rb_grn_log_level_to_ruby_object(level))
29
+ #define RVAL2GRNLOGLEVEL(rb_level) (rb_grn_log_level_from_ruby_object(rb_level))
37
30
 
38
31
  VALUE cGrnLogger;
32
+ VALUE mGrnLoggerFlags;
33
+ VALUE cGrnCallbackLogger;
39
34
 
40
- typedef struct _rb_grn_logger_info_wrapper
41
- {
42
- grn_logger_info *logger;
43
- VALUE handler;
44
- } rb_grn_logger_info_wrapper;
45
-
46
- static rb_grn_logger_info_wrapper *
47
- rb_grn_logger_info_wrapper_from_ruby_object (VALUE object)
48
- {
49
- rb_grn_logger_info_wrapper *wrapper;
50
-
51
- if (NIL_P(object))
52
- return NULL;
53
-
54
- if (!RVAL2CBOOL(rb_obj_is_kind_of(object, cGrnLogger))) {
55
- rb_raise(rb_eTypeError, "not a groonga logger");
56
- }
35
+ static ID id_new;
36
+ static ID id_parse;
37
+ static ID id_log;
38
+ static ID id_reopen;
39
+ static ID id_fin;
57
40
 
58
- Data_Get_Struct(object, rb_grn_logger_info_wrapper, wrapper);
59
- if (!wrapper)
60
- rb_raise(rb_eTypeError, "groonga logger is NULL");
61
-
62
- return wrapper;
63
- }
64
-
65
- grn_logger_info *
66
- rb_grn_logger_from_ruby_object (VALUE object)
67
- {
68
- rb_grn_logger_info_wrapper *wrapper;
69
-
70
- wrapper = RVAL2GRNWRAPPER(object);
71
- if (!wrapper)
72
- return NULL;
73
-
74
- return wrapper->logger;
75
- }
76
-
77
- static void
78
- rb_grn_logger_free (void *object)
79
- {
80
- rb_grn_logger_info_wrapper *wrapper = object;
81
-
82
- xfree(wrapper->logger);
83
- xfree(wrapper);
84
- }
85
-
86
- static VALUE
87
- rb_grn_logger_alloc (VALUE klass)
88
- {
89
- return Data_Wrap_Struct(klass, NULL, rb_grn_logger_free, NULL);
90
- }
41
+ static grn_logger rb_grn_logger;
91
42
 
92
43
  static grn_log_level
93
44
  rb_grn_log_level_from_ruby_object (VALUE rb_level)
@@ -172,80 +123,70 @@ rb_grn_log_level_to_ruby_object (grn_log_level level)
172
123
  }
173
124
 
174
125
  static void
175
- rb_grn_log (int level, const char *time, const char *title,
176
- const char *message, const char *location, void *func_arg)
126
+ rb_grn_logger_reset_with_error_check (VALUE klass, grn_ctx *context)
177
127
  {
178
- rb_grn_logger_info_wrapper *wrapper = func_arg;
128
+ VALUE current_logger;
179
129
 
180
- rb_funcall(wrapper->handler, rb_intern("call"), 5,
181
- GRNLOGLEVEL2RVAL(level),
182
- rb_str_new2(time),
183
- rb_str_new2(title),
184
- rb_str_new2(message),
185
- rb_str_new2(location));
130
+ current_logger = rb_cv_get(klass, "@@current_logger");
131
+ if (NIL_P(current_logger))
132
+ return;
133
+ rb_cv_set(klass, "@@current_logger", Qnil);
134
+
135
+ if (context) {
136
+ grn_logger_set(context, NULL);
137
+ rb_grn_context_check(context, current_logger);
138
+ } else {
139
+ grn_logger_set(NULL, NULL);
140
+ }
186
141
  }
187
142
 
188
143
  static void
189
- rb_grn_logger_set_handler (VALUE self, VALUE rb_handler)
144
+ rb_grn_logger_reset (VALUE klass)
190
145
  {
191
- rb_grn_logger_info_wrapper *wrapper;
192
- grn_logger_info *logger;
193
-
194
- wrapper = RVAL2GRNWRAPPER(self);
195
- wrapper->handler = rb_handler;
196
- rb_iv_set(self, "@handler", rb_handler);
197
-
198
- logger = wrapper->logger;
199
- if (NIL_P(rb_handler)) {
200
- logger->func = NULL;
201
- logger->func_arg = NULL;
202
- } else {
203
- logger->func = rb_grn_log;
204
- logger->func_arg = wrapper;
205
- }
146
+ rb_grn_logger_reset_with_error_check(klass, NULL);
206
147
  }
207
148
 
208
- static VALUE
209
- rb_grn_logger_initialize (int argc, VALUE *argv, VALUE self)
149
+ static void
150
+ rb_grn_logger_log (grn_ctx *ctx, grn_log_level level,
151
+ const char *timestamp, const char *title, const char *message,
152
+ const char *location, void *user_data)
210
153
  {
211
- rb_grn_logger_info_wrapper *wrapper;
212
- grn_logger_info *logger;
213
- grn_log_level level;
214
- int flags = 0;
215
- VALUE options, rb_level, rb_time, rb_title, rb_message, rb_location;
216
- VALUE rb_handler;
154
+ VALUE handler = (VALUE)user_data;
217
155
 
218
- rb_scan_args(argc, argv, "01&", &options, &rb_handler);
156
+ if (NIL_P(handler))
157
+ return;
219
158
 
220
- rb_grn_scan_options(options,
221
- "level", &rb_level,
222
- "time", &rb_time,
223
- "title", &rb_title,
224
- "message", &rb_message,
225
- "location", &rb_location,
226
- NULL);
159
+ /* TODO: use rb_protect(). */
160
+ rb_funcall(handler, id_log, 5,
161
+ GRNLOGLEVEL2RVAL(level),
162
+ rb_str_new2(timestamp),
163
+ rb_str_new2(title),
164
+ rb_str_new2(message),
165
+ rb_str_new2(location));
166
+ }
227
167
 
228
- level = RVAL2GRNLOGLEVEL(rb_level);
168
+ static void
169
+ rb_grn_logger_reopen (grn_ctx *ctx, void *user_data)
170
+ {
171
+ VALUE handler = (VALUE)user_data;
229
172
 
230
- if (NIL_P(rb_time) || RVAL2CBOOL(rb_time))
231
- flags |= GRN_LOG_TIME;
232
- if (NIL_P(rb_title) || RVAL2CBOOL(rb_title))
233
- flags |= GRN_LOG_TITLE;
234
- if (NIL_P(rb_message) || RVAL2CBOOL(rb_message))
235
- flags |= GRN_LOG_MESSAGE;
236
- if (NIL_P(rb_location) || RVAL2CBOOL(rb_location))
237
- flags |= GRN_LOG_LOCATION;
173
+ if (NIL_P(handler))
174
+ return;
238
175
 
239
- wrapper = ALLOC(rb_grn_logger_info_wrapper);
240
- logger = ALLOC(grn_logger_info);
241
- wrapper->logger = logger;
242
- DATA_PTR(self) = wrapper;
176
+ /* TODO: use rb_protect(). */
177
+ rb_funcall(handler, id_reopen, 0);
178
+ }
243
179
 
244
- logger->max_level = level;
245
- logger->flags = flags;
246
- rb_grn_logger_set_handler(self, rb_handler);
180
+ static void
181
+ rb_grn_logger_fin (grn_ctx *ctx, void *user_data)
182
+ {
183
+ VALUE handler = (VALUE)user_data;
247
184
 
248
- return Qnil;
185
+ if (NIL_P(handler))
186
+ return;
187
+
188
+ /* TODO: use rb_protect(). */
189
+ rb_funcall(handler, id_fin, 0);
249
190
  }
250
191
 
251
192
  /*
@@ -281,102 +222,122 @@ rb_grn_logger_initialize (int argc, VALUE *argv, VALUE self)
281
222
  static VALUE
282
223
  rb_grn_logger_s_register (int argc, VALUE *argv, VALUE klass)
283
224
  {
284
- VALUE logger, rb_context = Qnil;
225
+ VALUE rb_context = Qnil;
285
226
  grn_ctx *context;
227
+ VALUE rb_logger, rb_callback;
228
+ VALUE rb_options, rb_max_level;
229
+ VALUE rb_time, rb_title, rb_message, rb_location;
230
+ VALUE rb_flags;
231
+ grn_log_level max_level = GRN_LOG_DEFAULT_LEVEL;
232
+ int flags = 0;
233
+
234
+ rb_scan_args(argc, argv, "02&", &rb_logger, &rb_options, &rb_callback);
235
+
236
+ if (rb_block_given_p()) {
237
+ rb_logger = rb_funcall(cGrnCallbackLogger, id_new, 1, rb_callback);
238
+ }
239
+
240
+ rb_grn_scan_options(rb_options,
241
+ "max_level", &rb_max_level,
242
+ "time", &rb_time,
243
+ "title", &rb_title,
244
+ "message", &rb_message,
245
+ "location", &rb_location,
246
+ "flags", &rb_flags,
247
+ NULL);
248
+ if (!NIL_P(rb_max_level)) {
249
+ max_level = RVAL2GRNLOGLEVEL(rb_max_level);
250
+ }
251
+
252
+ if (NIL_P(rb_time) || CBOOL2RVAL(rb_time)) {
253
+ flags |= GRN_LOG_TIME;
254
+ }
255
+ if (NIL_P(rb_title) || CBOOL2RVAL(rb_title)) {
256
+ flags |= GRN_LOG_TITLE;
257
+ }
258
+ if (NIL_P(rb_message) || CBOOL2RVAL(rb_message)) {
259
+ flags |= GRN_LOG_MESSAGE;
260
+ }
261
+ if (NIL_P(rb_location) || CBOOL2RVAL(rb_location)) {
262
+ flags |= GRN_LOG_LOCATION;
263
+ }
264
+ if (!NIL_P(rb_flags)) {
265
+ flags = rb_funcall(mGrnLoggerFlags, id_parse, 2,
266
+ INT2NUM(flags), rb_flags);
267
+ }
268
+
269
+ rb_grn_logger.max_level = max_level;
270
+ rb_grn_logger.flags = flags;
271
+ rb_grn_logger.user_data = (void *)rb_logger;
286
272
 
287
- logger = rb_funcall2(klass, rb_intern("new"), argc, argv);
288
- rb_grn_logger_set_handler(logger, rb_block_proc());
289
273
  context = rb_grn_context_ensure(&rb_context);
290
- grn_logger_info_set(context, RVAL2GRNLOGGER(logger));
291
- rb_grn_context_check(context, logger);
292
- rb_cv_set(klass, "@@current_logger", logger);
274
+ grn_logger_set(context, &rb_grn_logger);
275
+ rb_grn_context_check(context, rb_logger);
276
+ rb_cv_set(klass, "@@current_logger", rb_logger);
293
277
 
294
278
  return Qnil;
295
279
  }
296
280
 
297
- static void
298
- rb_grn_logger_reset_with_error_check (VALUE klass, grn_ctx *context)
281
+ /*
282
+ * Unregister the registered logger. The default logger is used after
283
+ * unregistering.
284
+ *
285
+ * @overload unregister
286
+ * @return void
287
+ */
288
+ static VALUE
289
+ rb_grn_logger_s_unregister (VALUE klass)
299
290
  {
300
291
  VALUE current_logger;
292
+ VALUE rb_context = Qnil;
293
+ grn_ctx *context;
301
294
 
302
295
  current_logger = rb_cv_get(klass, "@@current_logger");
303
296
  if (NIL_P(current_logger))
304
- return;
297
+ return Qnil;
305
298
 
306
299
  rb_cv_set(klass, "@@current_logger", Qnil);
307
- if (context) {
308
- grn_logger_info_set(context, NULL);
309
- rb_grn_context_check(context, current_logger);
310
- } else {
311
- grn_logger_info_set(NULL, NULL);
312
- }
313
- }
314
300
 
315
- static void
316
- rb_grn_logger_reset (VALUE klass)
317
- {
318
- rb_grn_logger_reset_with_error_check(klass, NULL);
301
+ context = rb_grn_context_ensure(&rb_context);
302
+ grn_logger_set(context, NULL);
303
+ rb_grn_context_check(context, klass);
304
+
305
+ return Qnil;
319
306
  }
320
307
 
321
308
  static VALUE
322
309
  rb_grn_logger_s_reopen_with_related_object (VALUE klass, VALUE related_object)
323
310
  {
324
- #ifdef WIN32
325
- rb_raise(rb_eNotImpError, "grn_log_reopen() isn't available on Windows.");
326
- #else
327
311
  VALUE rb_context = Qnil;
328
312
  grn_ctx *context;
329
313
 
330
314
  context = rb_grn_context_ensure(&rb_context);
331
315
  rb_grn_logger_reset_with_error_check(klass, context);
332
- grn_log_reopen(context);
316
+ grn_logger_reopen(context);
333
317
  rb_grn_context_check(context, related_object);
334
- #endif
335
318
 
336
319
  return Qnil;
337
320
  }
338
321
 
339
322
  /*
340
- * groongaのデフォルトロガーがログを出力するファイルを再オー
341
- * プンする。ログファイルのバックアップ時などに使用する。
342
- *
343
- * {Groonga::Logger.register} で独自のロガーを設定している場合
344
- * は例外が発生する。
323
+ * Sends reopen request to the current logger. It is useful for
324
+ * rotating log file.
345
325
  *
346
326
  * @overload reopen
327
+ * @return void
347
328
  */
348
329
  static VALUE
349
330
  rb_grn_logger_s_reopen (VALUE klass)
350
331
  {
351
- return rb_grn_logger_s_reopen_with_related_object(klass, klass);
352
- }
353
-
354
- #ifndef WIN32
355
- static VALUE
356
- rb_grn_logger_s_set_path (VALUE klass, VALUE rb_path,
357
- const char **path, const char *class_variable_name)
358
- {
359
- grn_bool need_reopen = GRN_FALSE;
360
-
361
- if (NIL_P(rb_path)) {
362
- need_reopen = *path != NULL;
363
- *path = NULL;
364
- } else {
365
- const char *current_path = *path;
366
- *path = RSTRING_PTR(rb_path);
367
- if (!current_path || strcmp(*path, current_path) != 0) {
368
- need_reopen = GRN_TRUE;
369
- }
370
- }
371
- rb_cv_set(klass, class_variable_name, rb_path);
332
+ VALUE rb_context = Qnil;
333
+ grn_ctx *context;
372
334
 
373
- if (need_reopen) {
374
- rb_grn_logger_s_reopen_with_related_object(klass, rb_path);
375
- }
335
+ context = rb_grn_context_ensure(&rb_context);
336
+ grn_logger_reopen(context);
337
+ rb_grn_context_check(context, klass);
376
338
 
377
339
  return Qnil;
378
340
  }
379
- #endif
380
341
 
381
342
  /*
382
343
  * groongaのデフォルトロガーがログを出力するファイルのパスを返す。
@@ -387,16 +348,14 @@ rb_grn_logger_s_set_path (VALUE klass, VALUE rb_path,
387
348
  static VALUE
388
349
  rb_grn_logger_s_get_log_path (VALUE klass)
389
350
  {
390
- #ifdef WIN32
391
- rb_raise(rb_eNotImpError, "grn_log_path isn't available on Windows.");
392
- return Qnil;
393
- #else
394
- if (grn_log_path) {
395
- return rb_str_new2(grn_log_path);
351
+ const char *path;
352
+
353
+ path = grn_default_logger_get_path();
354
+ if (path) {
355
+ return rb_str_new2(path);
396
356
  } else {
397
357
  return Qnil;
398
358
  }
399
- #endif
400
359
  }
401
360
 
402
361
  /*
@@ -409,14 +368,30 @@ rb_grn_logger_s_get_log_path (VALUE klass)
409
368
  * @overload log_path=(path)
410
369
  */
411
370
  static VALUE
412
- rb_grn_logger_s_set_log_path (VALUE klass, VALUE path)
371
+ rb_grn_logger_s_set_log_path (VALUE klass, VALUE rb_path)
413
372
  {
414
- #ifdef WIN32
415
- rb_raise(rb_eNotImpError, "grn_qlog_path isn't available on Windows.");
373
+ grn_bool need_reopen = GRN_FALSE;
374
+ const char *current_path;
375
+
376
+ current_path = grn_default_logger_get_path();
377
+ if (NIL_P(rb_path)) {
378
+ need_reopen = current_path != NULL;
379
+ grn_default_logger_set_path(NULL);
380
+ } else {
381
+ const char *new_path;
382
+ new_path = RSTRING_PTR(rb_path);
383
+ if (!current_path || strcmp(new_path, current_path) != 0) {
384
+ need_reopen = GRN_TRUE;
385
+ }
386
+ grn_default_logger_set_path(new_path);
387
+ }
388
+ rb_cv_set(klass, "@@log_path", rb_path);
389
+
390
+ if (need_reopen) {
391
+ rb_grn_logger_s_reopen_with_related_object(klass, rb_path);
392
+ }
393
+
416
394
  return Qnil;
417
- #else
418
- return rb_grn_logger_s_set_path(klass, path, &grn_log_path, "@@log_path");
419
- #endif
420
395
  }
421
396
 
422
397
  /*
@@ -428,16 +403,14 @@ rb_grn_logger_s_set_log_path (VALUE klass, VALUE path)
428
403
  static VALUE
429
404
  rb_grn_logger_s_get_query_log_path (VALUE klass)
430
405
  {
431
- #ifdef WIN32
432
- rb_raise(rb_eNotImpError, "grn_qlog_path isn't available on Windows.");
433
- return Qnil;
434
- #else
435
- if (grn_qlog_path) {
436
- return rb_str_new2(grn_qlog_path);
406
+ const char *path;
407
+
408
+ path = grn_default_query_logger_get_path();
409
+ if (path) {
410
+ return rb_str_new2(path);
437
411
  } else {
438
412
  return Qnil;
439
413
  }
440
- #endif
441
414
  }
442
415
 
443
416
  /*
@@ -450,28 +423,56 @@ rb_grn_logger_s_get_query_log_path (VALUE klass)
450
423
  * @overload query_log_path=(path)
451
424
  */
452
425
  static VALUE
453
- rb_grn_logger_s_set_query_log_path (VALUE klass, VALUE path)
426
+ rb_grn_logger_s_set_query_log_path (VALUE klass, VALUE rb_path)
454
427
  {
455
- #ifdef WIN32
456
- rb_raise(rb_eNotImpError, "grn_qlog_path isn't available on Windows.");
428
+ grn_bool need_reopen = GRN_FALSE;
429
+ const char *current_path;
430
+
431
+ current_path = grn_default_query_logger_get_path();
432
+ if (NIL_P(rb_path)) {
433
+ need_reopen = current_path != NULL;
434
+ grn_default_query_logger_set_path(NULL);
435
+ } else {
436
+ const char *new_path;
437
+ new_path = RSTRING_PTR(rb_path);
438
+ if (!current_path || strcmp(new_path, current_path) != 0) {
439
+ need_reopen = GRN_TRUE;
440
+ }
441
+ grn_default_query_logger_set_path(new_path);
442
+ }
443
+ rb_cv_set(klass, "@@query_log_path", rb_path);
444
+
445
+ if (need_reopen) {
446
+ rb_grn_logger_s_reopen_with_related_object(klass, rb_path);
447
+ }
448
+
457
449
  return Qnil;
458
- #else
459
- return rb_grn_logger_s_set_path(klass, path, &grn_qlog_path,
460
- "@@query_log_path");
461
- #endif
462
450
  }
463
451
 
464
452
  void
465
453
  rb_grn_init_logger (VALUE mGrn)
466
454
  {
455
+ id_new = rb_intern("new");
456
+ id_parse = rb_intern("parse");
457
+ id_log = rb_intern("log");
458
+ id_reopen = rb_intern("reopen");
459
+ id_fin = rb_intern("fin");
460
+
461
+ rb_grn_logger.log = rb_grn_logger_log;
462
+ rb_grn_logger.reopen = rb_grn_logger_reopen;
463
+ rb_grn_logger.fin = rb_grn_logger_fin;
464
+
465
+ rb_grn_logger.user_data = (void *)Qnil;
466
+
467
467
  cGrnLogger = rb_define_class_under(mGrn, "Logger", rb_cObject);
468
- rb_define_alloc_func(cGrnLogger, rb_grn_logger_alloc);
469
468
 
470
469
  rb_cv_set(cGrnLogger, "@@current_logger", Qnil);
471
470
  rb_cv_set(cGrnLogger, "@@log_path", Qnil);
472
471
  rb_cv_set(cGrnLogger, "@@query_log_path", Qnil);
473
472
  rb_define_singleton_method(cGrnLogger, "register",
474
473
  rb_grn_logger_s_register, -1);
474
+ rb_define_singleton_method(cGrnLogger, "unregister",
475
+ rb_grn_logger_s_unregister, 0);
475
476
  rb_define_singleton_method(cGrnLogger, "reopen",
476
477
  rb_grn_logger_s_reopen, 0);
477
478
  rb_define_singleton_method(cGrnLogger, "log_path",
@@ -484,5 +485,16 @@ rb_grn_init_logger (VALUE mGrn)
484
485
  rb_grn_logger_s_set_query_log_path, 1);
485
486
  rb_set_end_proc(rb_grn_logger_reset, cGrnLogger);
486
487
 
487
- rb_define_method(cGrnLogger, "initialize", rb_grn_logger_initialize, -1);
488
+ mGrnLoggerFlags = rb_define_module_under(cGrnLogger, "Flags");
489
+ #define DEFINE_FLAG(NAME) \
490
+ rb_define_const(mGrnLoggerFlags, \
491
+ #NAME, INT2NUM(GRN_LOG_ ## NAME))
492
+ DEFINE_FLAG(TIME);
493
+ DEFINE_FLAG(TITLE);
494
+ DEFINE_FLAG(MESSAGE);
495
+ DEFINE_FLAG(LOCATION);
496
+ #undef DEFINE_FLAG
497
+
498
+ cGrnCallbackLogger =
499
+ rb_define_class_under(mGrn, "CallbackLogger", cGrnLogger);
488
500
  }