Ruby  2.7.2p137(2020-10-01revision5445e0435260b449decf2ac16f9d09bae3cafe72)
gdbm.c
Go to the documentation of this file.
1 /************************************************
2 
3  gdbm.c -
4 
5  $Author$
6  modified at: Mon Jan 24 15:59:52 JST 1994
7 
8  Documentation by Peter Adolphs < futzilogik at users dot sourceforge dot net >
9 
10 ************************************************/
11 
12 #include "ruby.h"
13 
14 #include <gdbm.h>
15 #include <fcntl.h>
16 #include <errno.h>
17 
18 /*
19  * Document-class: GDBM
20  *
21  * == Summary
22  *
23  * Ruby extension for GNU dbm (gdbm) -- a simple database engine for storing
24  * key-value pairs on disk.
25  *
26  * == Description
27  *
28  * GNU dbm is a library for simple databases. A database is a file that stores
29  * key-value pairs. Gdbm allows the user to store, retrieve, and delete data by
30  * key. It furthermore allows a non-sorted traversal of all key-value pairs.
31  * A gdbm database thus provides the same functionality as a hash. As
32  * with objects of the Hash class, elements can be accessed with <tt>[]</tt>.
33  * Furthermore, GDBM mixes in the Enumerable module, thus providing convenient
34  * methods such as #find, #collect, #map, etc.
35  *
36  * A process is allowed to open several different databases at the same time.
37  * A process can open a database as a "reader" or a "writer". Whereas a reader
38  * has only read-access to the database, a writer has read- and write-access.
39  * A database can be accessed either by any number of readers or by exactly one
40  * writer at the same time.
41  *
42  * == Examples
43  *
44  * 1. Opening/creating a database, and filling it with some entries:
45  *
46  * require 'gdbm'
47  *
48  * gdbm = GDBM.new("fruitstore.db")
49  * gdbm["ananas"] = "3"
50  * gdbm["banana"] = "8"
51  * gdbm["cranberry"] = "4909"
52  * gdbm.close
53  *
54  * 2. Reading out a database:
55  *
56  * require 'gdbm'
57  *
58  * gdbm = GDBM.new("fruitstore.db")
59  * gdbm.each_pair do |key, value|
60  * print "#{key}: #{value}\n"
61  * end
62  * gdbm.close
63  *
64  * produces
65  *
66  * banana: 8
67  * ananas: 3
68  * cranberry: 4909
69  *
70  * == Links
71  *
72  * * http://www.gnu.org/software/gdbm/
73  */
74 static VALUE rb_cGDBM, rb_eGDBMError, rb_eGDBMFatalError;
75 
76 #if SIZEOF_LONG > SIZEOF_INT
77 #define TOO_LONG(n) ((long)(+(int)(n)) != (long)(n))
78 #else
79 #define TOO_LONG(n) 0
80 #endif
81 
82 #define RUBY_GDBM_RW_BIT 0x20000000
83 
84 #define MY_BLOCK_SIZE (2048)
85 #define MY_FATAL_FUNC rb_gdbm_fatal
86 
87 NORETURN(static void rb_gdbm_fatal(const char *msg));
88 NORETURN(static void closed_dbm(void));
89 
90 static void
91 rb_gdbm_fatal(const char *msg)
92 {
93  rb_raise(rb_eGDBMFatalError, "%s", msg);
94 }
95 
96 struct dbmdata {
97  int di_size;
98  GDBM_FILE di_dbm;
99 };
100 
101 static void
102 closed_dbm(void)
103 {
104  rb_raise(rb_eRuntimeError, "closed GDBM file");
105 }
106 
107 #define GetDBM(obj, dbmp) do {\
108  TypedData_Get_Struct((obj), struct dbmdata, &dbm_type, (dbmp));\
109  if ((dbmp)->di_dbm == 0) closed_dbm();\
110 } while (0)
111 
112 #define GetDBM2(obj, dbmp, dbm) do {\
113  GetDBM((obj), (dbmp));\
114  (dbm) = (dbmp)->di_dbm;\
115 } while (0)
116 
117 static void
118 free_dbm(void *ptr)
119 {
120  struct dbmdata *dbmp = ptr;
121  if (dbmp->di_dbm)
122  gdbm_close(dbmp->di_dbm);
123  xfree(dbmp);
124 }
125 
126 static size_t
127 memsize_dbm(const void *ptr)
128 {
129  const struct dbmdata *dbmp = ptr;
130  size_t size = sizeof(*dbmp);
131  if (dbmp->di_dbm)
132  size += DBM_SIZEOF_DBM;
133  return size;
134 }
135 
136 static const rb_data_type_t dbm_type = {
137  "gdbm",
138  {0, free_dbm, memsize_dbm,},
139  0, 0,
141 };
142 
143 /*
144  * call-seq:
145  * gdbm.close -> nil
146  *
147  * Closes the associated database file.
148  */
149 static VALUE
150 fgdbm_close(VALUE obj)
151 {
152  struct dbmdata *dbmp;
153 
154  GetDBM(obj, dbmp);
155  gdbm_close(dbmp->di_dbm);
156  dbmp->di_dbm = 0;
157 
158  return Qnil;
159 }
160 
161 /*
162  * call-seq:
163  * gdbm.closed? -> true or false
164  *
165  * Returns true if the associated database file has been closed.
166  */
167 static VALUE
168 fgdbm_closed(VALUE obj)
169 {
170  struct dbmdata *dbmp;
171 
172  TypedData_Get_Struct(obj, struct dbmdata, &dbm_type, dbmp);
173  if (dbmp->di_dbm == 0)
174  return Qtrue;
175 
176  return Qfalse;
177 }
178 
179 static VALUE
180 fgdbm_s_alloc(VALUE klass)
181 {
182  struct dbmdata *dbmp;
183 
184  return TypedData_Make_Struct(klass, struct dbmdata, &dbm_type, dbmp);
185 }
186 
187 /*
188  * call-seq:
189  * GDBM.new(filename, mode = 0666, flags = nil)
190  *
191  * Creates a new GDBM instance by opening a gdbm file named _filename_.
192  * If the file does not exist, a new file with file mode _mode_ will be
193  * created. _flags_ may be one of the following:
194  * * *READER* - open as a reader
195  * * *WRITER* - open as a writer
196  * * *WRCREAT* - open as a writer; if the database does not exist, create a new one
197  * * *NEWDB* - open as a writer; overwrite any existing databases
198  *
199  * The values *WRITER*, *WRCREAT* and *NEWDB* may be combined with the following
200  * values by bitwise or:
201  * * *SYNC* - cause all database operations to be synchronized to the disk
202  * * *NOLOCK* - do not lock the database file
203  *
204  * If no _flags_ are specified, the GDBM object will try to open the database
205  * file as a writer and will create it if it does not already exist
206  * (cf. flag <tt>WRCREAT</tt>). If this fails (for instance, if another process
207  * has already opened the database as a reader), it will try to open the
208  * database file as a reader (cf. flag <tt>READER</tt>).
209  */
210 static VALUE
211 fgdbm_initialize(int argc, VALUE *argv, VALUE obj)
212 {
213  VALUE file, vmode, vflags;
214  GDBM_FILE dbm;
215  struct dbmdata *dbmp;
216  int mode, flags = 0;
217 
218  TypedData_Get_Struct(obj, struct dbmdata, &dbm_type, dbmp);
219  if (rb_scan_args(argc, argv, "12", &file, &vmode, &vflags) == 1) {
220  mode = 0666; /* default value */
221  }
222  else if (NIL_P(vmode)) {
223  mode = -1; /* return nil if DB does not exist */
224  }
225  else {
226  mode = NUM2INT(vmode);
227  }
228 
229  if (!NIL_P(vflags))
230  flags = NUM2INT(vflags);
231 
232  FilePathValue(file);
233 
234 #ifdef GDBM_CLOEXEC
235  /* GDBM_CLOEXEC is available since gdbm 1.10. */
236  flags |= GDBM_CLOEXEC;
237 #endif
238 
239  if (flags & RUBY_GDBM_RW_BIT) {
240  flags &= ~RUBY_GDBM_RW_BIT;
241  dbm = gdbm_open(RSTRING_PTR(file), MY_BLOCK_SIZE,
242  flags, mode, MY_FATAL_FUNC);
243  }
244  else {
245  dbm = 0;
246  if (mode >= 0)
247  dbm = gdbm_open(RSTRING_PTR(file), MY_BLOCK_SIZE,
248  GDBM_WRCREAT|flags, mode, MY_FATAL_FUNC);
249  if (!dbm)
250  dbm = gdbm_open(RSTRING_PTR(file), MY_BLOCK_SIZE,
251  GDBM_WRITER|flags, 0, MY_FATAL_FUNC);
252  if (!dbm)
253  dbm = gdbm_open(RSTRING_PTR(file), MY_BLOCK_SIZE,
254  GDBM_READER|flags, 0, MY_FATAL_FUNC);
255  }
256 
257  if (dbm) {
258  rb_fd_fix_cloexec(gdbm_fdesc(dbm));
259  }
260 
261  if (!dbm) {
262  if (mode == -1) return Qnil;
263 
264  if (gdbm_errno == GDBM_FILE_OPEN_ERROR ||
265  gdbm_errno == GDBM_CANT_BE_READER ||
266  gdbm_errno == GDBM_CANT_BE_WRITER)
267  rb_sys_fail_str(file);
268  else
269  rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
270  }
271 
272  if (dbmp->di_dbm)
273  gdbm_close(dbmp->di_dbm);
274  dbmp->di_dbm = dbm;
275  dbmp->di_size = -1;
276 
277  return obj;
278 }
279 
280 /*
281  * call-seq:
282  * GDBM.open(filename, mode = 0666, flags = nil)
283  * GDBM.open(filename, mode = 0666, flags = nil) { |gdbm| ... }
284  *
285  * If called without a block, this is synonymous to GDBM::new.
286  * If a block is given, the new GDBM instance will be passed to the block
287  * as a parameter, and the corresponding database file will be closed
288  * after the execution of the block code has been finished.
289  *
290  * Example for an open call with a block:
291  *
292  * require 'gdbm'
293  * GDBM.open("fruitstore.db") do |gdbm|
294  * gdbm.each_pair do |key, value|
295  * print "#{key}: #{value}\n"
296  * end
297  * end
298  */
299 static VALUE
300 fgdbm_s_open(int argc, VALUE *argv, VALUE klass)
301 {
302  VALUE obj = fgdbm_s_alloc(klass);
303 
304  if (NIL_P(fgdbm_initialize(argc, argv, obj))) {
305  return Qnil;
306  }
307 
308  if (rb_block_given_p()) {
309  return rb_ensure(rb_yield, obj, fgdbm_close, obj);
310  }
311 
312  return obj;
313 }
314 
315 static VALUE
316 rb_gdbm_fetch(GDBM_FILE dbm, datum key)
317 {
318  datum val;
319  VALUE str;
320 
321  val = gdbm_fetch(dbm, key);
322  if (val.dptr == 0)
323  return Qnil;
324 
325  str = rb_str_new(val.dptr, val.dsize);
326  free(val.dptr);
327  return str;
328 }
329 
330 static VALUE
331 rb_gdbm_fetch2(GDBM_FILE dbm, VALUE keystr)
332 {
333  datum key;
334  long len;
335 
336  ExportStringValue(keystr);
337  len = RSTRING_LEN(keystr);
338  if (TOO_LONG(len)) return Qnil;
339  key.dptr = RSTRING_PTR(keystr);
340  key.dsize = (int)len;
341 
342  return rb_gdbm_fetch(dbm, key);
343 }
344 
345 static VALUE
346 rb_gdbm_fetch3(VALUE obj, VALUE keystr)
347 {
348  struct dbmdata *dbmp;
349  GDBM_FILE dbm;
350 
351  GetDBM2(obj, dbmp, dbm);
352  return rb_gdbm_fetch2(dbm, keystr);
353 }
354 
355 static VALUE
356 rb_gdbm_firstkey(GDBM_FILE dbm)
357 {
358  datum key;
359  VALUE str;
360 
361  key = gdbm_firstkey(dbm);
362  if (key.dptr == 0)
363  return Qnil;
364 
365  str = rb_str_new(key.dptr, key.dsize);
366  free(key.dptr);
367  return str;
368 }
369 
370 static VALUE
371 rb_gdbm_nextkey(GDBM_FILE dbm, VALUE keystr)
372 {
373  datum key, key2;
374  VALUE str;
375  long len;
376 
377  len = RSTRING_LEN(keystr);
378  if (TOO_LONG(len)) return Qnil;
379  key.dptr = RSTRING_PTR(keystr);
380  key.dsize = (int)len;
381  key2 = gdbm_nextkey(dbm, key);
382  if (key2.dptr == 0)
383  return Qnil;
384 
385  str = rb_str_new(key2.dptr, key2.dsize);
386  free(key2.dptr);
387  return str;
388 }
389 
390 static VALUE
391 fgdbm_fetch(VALUE obj, VALUE keystr, VALUE ifnone)
392 {
393  VALUE valstr;
394 
395  valstr = rb_gdbm_fetch3(obj, keystr);
396  if (NIL_P(valstr)) {
397  if (ifnone == Qnil && rb_block_given_p())
398  return rb_yield(keystr);
399  return ifnone;
400  }
401  return valstr;
402 }
403 
404 /*
405  * call-seq:
406  * gdbm[key] -> value
407  *
408  * Retrieves the _value_ corresponding to _key_.
409  */
410 static VALUE
411 fgdbm_aref(VALUE obj, VALUE keystr)
412 {
413  return rb_gdbm_fetch3(obj, keystr);
414 }
415 
416 /*
417  * call-seq:
418  * gdbm.fetch(key [, default]) -> value
419  *
420  * Retrieves the _value_ corresponding to _key_. If there is no value
421  * associated with _key_, _default_ will be returned instead.
422  */
423 static VALUE
424 fgdbm_fetch_m(int argc, VALUE *argv, VALUE obj)
425 {
426  VALUE keystr, valstr, ifnone;
427 
428  rb_scan_args(argc, argv, "11", &keystr, &ifnone);
429  valstr = fgdbm_fetch(obj, keystr, ifnone);
430  if (argc == 1 && !rb_block_given_p() && NIL_P(valstr))
431  rb_raise(rb_eIndexError, "key not found");
432 
433  return valstr;
434 }
435 
436 /*
437  * call-seq:
438  * gdbm.key(value) -> key
439  *
440  * Returns the _key_ for a given _value_. If several keys may map to the
441  * same value, the key that is found first will be returned.
442  */
443 static VALUE
444 fgdbm_key(VALUE obj, VALUE valstr)
445 {
446  struct dbmdata *dbmp;
447  GDBM_FILE dbm;
448  VALUE keystr, valstr2;
449 
450  ExportStringValue(valstr);
451  GetDBM2(obj, dbmp, dbm);
452  for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
453  keystr = rb_gdbm_nextkey(dbm, keystr)) {
454 
455  valstr2 = rb_gdbm_fetch2(dbm, keystr);
456  if (!NIL_P(valstr2) &&
457  (int)RSTRING_LEN(valstr) == (int)RSTRING_LEN(valstr2) &&
458  memcmp(RSTRING_PTR(valstr), RSTRING_PTR(valstr2),
459  (int)RSTRING_LEN(valstr)) == 0) {
460  return keystr;
461  }
462  }
463  return Qnil;
464 }
465 
466 /* :nodoc: */
467 static VALUE
468 fgdbm_index(VALUE obj, VALUE value)
469 {
470  rb_warn("GDBM#index is deprecated; use GDBM#key");
471  return fgdbm_key(obj, value);
472 }
473 
474 /*
475  * call-seq:
476  * gdbm.select { |key, value| block } -> array
477  *
478  * Returns a new array of all key-value pairs of the database for which _block_
479  * evaluates to true.
480  */
481 static VALUE
482 fgdbm_select(VALUE obj)
483 {
484  VALUE new = rb_ary_new();
485  GDBM_FILE dbm;
486  struct dbmdata *dbmp;
487  VALUE keystr;
488 
489  GetDBM2(obj, dbmp, dbm);
490  for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
491  keystr = rb_gdbm_nextkey(dbm, keystr)) {
492  VALUE assoc = rb_assoc_new(keystr, rb_gdbm_fetch2(dbm, keystr));
493  VALUE v = rb_yield(assoc);
494 
495  if (RTEST(v)) {
496  rb_ary_push(new, assoc);
497  }
498  GetDBM2(obj, dbmp, dbm);
499  }
500 
501  return new;
502 }
503 
504 /*
505  * call-seq:
506  * gdbm.values_at(key, ...) -> array
507  *
508  * Returns an array of the values associated with each specified _key_.
509  */
510 static VALUE
511 fgdbm_values_at(int argc, VALUE *argv, VALUE obj)
512 {
513  VALUE new = rb_ary_new2(argc);
514  int i;
515 
516  for (i=0; i<argc; i++) {
517  rb_ary_push(new, rb_gdbm_fetch3(obj, argv[i]));
518  }
519 
520  return new;
521 }
522 
523 static void
524 rb_gdbm_modify(VALUE obj)
525 {
526  if (OBJ_FROZEN(obj)) rb_error_frozen("GDBM");
527 }
528 
529 static VALUE
530 rb_gdbm_delete(VALUE obj, VALUE keystr)
531 {
532  datum key;
533  struct dbmdata *dbmp;
534  GDBM_FILE dbm;
535  long len;
536 
537  rb_gdbm_modify(obj);
538  ExportStringValue(keystr);
539  len = RSTRING_LEN(keystr);
540  if (TOO_LONG(len)) return Qnil;
541  key.dptr = RSTRING_PTR(keystr);
542  key.dsize = (int)len;
543 
544  GetDBM2(obj, dbmp, dbm);
545  if (!gdbm_exists(dbm, key)) {
546  return Qnil;
547  }
548 
549  if (gdbm_delete(dbm, key)) {
550  dbmp->di_size = -1;
551  rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
552  }
553  else if (dbmp->di_size >= 0) {
554  dbmp->di_size--;
555  }
556  return obj;
557 }
558 
559 /*
560  * call-seq:
561  * gdbm.delete(key) -> value or nil
562  *
563  * Removes the key-value-pair with the specified _key_ from this database and
564  * returns the corresponding _value_. Returns nil if the database is empty.
565  */
566 static VALUE
567 fgdbm_delete(VALUE obj, VALUE keystr)
568 {
569  VALUE valstr;
570 
571  valstr = fgdbm_fetch(obj, keystr, Qnil);
572  rb_gdbm_delete(obj, keystr);
573  return valstr;
574 }
575 
576 /*
577  * call-seq:
578  * gdbm.shift -> (key, value) or nil
579  *
580  * Removes a key-value-pair from this database and returns it as a
581  * two-item array [ _key_, _value_ ]. Returns nil if the database is empty.
582  */
583 static VALUE
584 fgdbm_shift(VALUE obj)
585 {
586  struct dbmdata *dbmp;
587  GDBM_FILE dbm;
588  VALUE keystr, valstr;
589 
590  rb_gdbm_modify(obj);
591  GetDBM2(obj, dbmp, dbm);
592  keystr = rb_gdbm_firstkey(dbm);
593  if (NIL_P(keystr)) return Qnil;
594  valstr = rb_gdbm_fetch2(dbm, keystr);
595  rb_gdbm_delete(obj, keystr);
596 
597  return rb_assoc_new(keystr, valstr);
598 }
599 
600 /*
601  * call-seq:
602  * gdbm.delete_if { |key, value| block } -> gdbm
603  * gdbm.reject! { |key, value| block } -> gdbm
604  *
605  * Deletes every key-value pair from _gdbm_ for which _block_ evaluates to true.
606  */
607 static VALUE
608 fgdbm_delete_if(VALUE obj)
609 {
610  struct dbmdata *dbmp;
611  GDBM_FILE dbm;
612  VALUE keystr, valstr;
613  VALUE ret, ary = rb_ary_tmp_new(0);
614  long i;
615  int status = 0, n;
616 
617  rb_gdbm_modify(obj);
618  GetDBM2(obj, dbmp, dbm);
619  n = dbmp->di_size;
620  dbmp->di_size = -1;
621 
622  for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
623  keystr = rb_gdbm_nextkey(dbm, keystr)) {
624 
625  OBJ_FREEZE(keystr);
626  valstr = rb_gdbm_fetch2(dbm, keystr);
627  ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
628  if (status != 0) break;
629  if (RTEST(ret)) rb_ary_push(ary, keystr);
630  GetDBM2(obj, dbmp, dbm);
631  }
632 
633  for (i = 0; i < RARRAY_LEN(ary); i++)
634  rb_gdbm_delete(obj, RARRAY_AREF(ary, i));
635  if (status) rb_jump_tag(status);
636  if (n > 0) dbmp->di_size = n - (int)RARRAY_LEN(ary);
637  rb_ary_clear(ary);
638 
639  return obj;
640 }
641 
642 /*
643  * call-seq:
644  * gdbm.clear -> gdbm
645  *
646  * Removes all the key-value pairs within _gdbm_.
647  */
648 static VALUE
649 fgdbm_clear(VALUE obj)
650 {
651  datum key, nextkey;
652  struct dbmdata *dbmp;
653  GDBM_FILE dbm;
654 
655  rb_gdbm_modify(obj);
656  GetDBM2(obj, dbmp, dbm);
657  dbmp->di_size = -1;
658 
659 #if 0
660  while (key = gdbm_firstkey(dbm), key.dptr) {
661  if (gdbm_delete(dbm, key)) {
662  free(key.dptr);
663  rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
664  }
665  free(key.dptr);
666  }
667 #else
668  while (key = gdbm_firstkey(dbm), key.dptr) {
669  for (; key.dptr; key = nextkey) {
670  nextkey = gdbm_nextkey(dbm, key);
671  if (gdbm_delete(dbm, key)) {
672  free(key.dptr);
673  if (nextkey.dptr) free(nextkey.dptr);
674  rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
675  }
676  free(key.dptr);
677  }
678  }
679 #endif
680  dbmp->di_size = 0;
681 
682  return obj;
683 }
684 
685 /*
686  * call-seq:
687  * gdbm.invert -> hash
688  *
689  * Returns a hash created by using _gdbm_'s values as keys, and the keys
690  * as values.
691  */
692 static VALUE
693 fgdbm_invert(VALUE obj)
694 {
695  struct dbmdata *dbmp;
696  GDBM_FILE dbm;
697  VALUE keystr, valstr;
698  VALUE hash = rb_hash_new();
699 
700  GetDBM2(obj, dbmp, dbm);
701  for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
702  keystr = rb_gdbm_nextkey(dbm, keystr)) {
703  valstr = rb_gdbm_fetch2(dbm, keystr);
704 
705  rb_hash_aset(hash, valstr, keystr);
706  }
707  return hash;
708 }
709 
710 /*
711  * call-seq:
712  * gdbm[key]= value -> value
713  * gdbm.store(key, value) -> value
714  *
715  * Associates the value _value_ with the specified _key_.
716  */
717 static VALUE
718 fgdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
719 {
720  datum key, val;
721  struct dbmdata *dbmp;
722  GDBM_FILE dbm;
723 
724  rb_gdbm_modify(obj);
725  ExportStringValue(keystr);
726  ExportStringValue(valstr);
727 
728  key.dptr = RSTRING_PTR(keystr);
729  key.dsize = RSTRING_LENINT(keystr);
730 
731  val.dptr = RSTRING_PTR(valstr);
732  val.dsize = RSTRING_LENINT(valstr);
733 
734  GetDBM2(obj, dbmp, dbm);
735  dbmp->di_size = -1;
736  if (gdbm_store(dbm, key, val, GDBM_REPLACE)) {
737  if (errno == EPERM) rb_sys_fail(0);
738  rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
739  }
740 
741  return valstr;
742 }
743 
744 static VALUE
745 update_i(RB_BLOCK_CALL_FUNC_ARGLIST(pair, dbm))
746 {
747  const VALUE *ptr;
748  Check_Type(pair, T_ARRAY);
749  if (RARRAY_LEN(pair) < 2) {
750  rb_raise(rb_eArgError, "pair must be [key, value]");
751  }
752  ptr = RARRAY_CONST_PTR(pair);
753  fgdbm_store(dbm, ptr[0], ptr[1]);
754  return Qnil;
755 }
756 
757 /*
758  * call-seq:
759  * gdbm.update(other) -> gdbm
760  *
761  * Adds the key-value pairs of _other_ to _gdbm_, overwriting entries with
762  * duplicate keys with those from _other_. _other_ must have an each_pair
763  * method.
764  */
765 static VALUE
766 fgdbm_update(VALUE obj, VALUE other)
767 {
768  rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
769  return obj;
770 }
771 
772 /*
773  * call-seq:
774  * gdbm.replace(other) -> gdbm
775  *
776  * Replaces the content of _gdbm_ with the key-value pairs of _other_.
777  * _other_ must have an each_pair method.
778  */
779 static VALUE
780 fgdbm_replace(VALUE obj, VALUE other)
781 {
782  fgdbm_clear(obj);
783  rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
784  return obj;
785 }
786 
787 /*
788  * call-seq:
789  * gdbm.length -> fixnum
790  * gdbm.size -> fixnum
791  *
792  * Returns the number of key-value pairs in this database.
793  */
794 static VALUE
795 fgdbm_length(VALUE obj)
796 {
797  datum key, nextkey;
798  struct dbmdata *dbmp;
799  GDBM_FILE dbm;
800  int i = 0;
801 
802  GetDBM2(obj, dbmp, dbm);
803  if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);
804 
805  for (key = gdbm_firstkey(dbm); key.dptr; key = nextkey) {
806  nextkey = gdbm_nextkey(dbm, key);
807  free(key.dptr);
808  i++;
809  }
810  dbmp->di_size = i;
811 
812  return INT2FIX(i);
813 }
814 
815 /*
816  * call-seq:
817  * gdbm.empty? -> true or false
818  *
819  * Returns true if the database is empty.
820  */
821 static VALUE
822 fgdbm_empty_p(VALUE obj)
823 {
824  datum key;
825  struct dbmdata *dbmp;
826  GDBM_FILE dbm;
827 
828  GetDBM(obj, dbmp);
829  if (dbmp->di_size < 0) {
830  dbm = dbmp->di_dbm;
831 
832  key = gdbm_firstkey(dbm);
833  if (key.dptr) {
834  free(key.dptr);
835  return Qfalse;
836  }
837  return Qtrue;
838  }
839 
840  if (dbmp->di_size == 0) return Qtrue;
841  return Qfalse;
842 }
843 
844 /*
845  * call-seq:
846  * gdbm.each_value { |value| block } -> gdbm
847  *
848  * Executes _block_ for each key in the database, passing the corresponding
849  * _value_ as a parameter.
850  */
851 static VALUE
852 fgdbm_each_value(VALUE obj)
853 {
854  struct dbmdata *dbmp;
855  GDBM_FILE dbm;
856  VALUE keystr;
857 
858  RETURN_ENUMERATOR(obj, 0, 0);
859 
860  GetDBM2(obj, dbmp, dbm);
861  for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
862  keystr = rb_gdbm_nextkey(dbm, keystr)) {
863 
864  rb_yield(rb_gdbm_fetch2(dbm, keystr));
865  GetDBM2(obj, dbmp, dbm);
866  }
867  return obj;
868 }
869 
870 /*
871  * call-seq:
872  * gdbm.each_key { |key| block } -> gdbm
873  *
874  * Executes _block_ for each key in the database, passing the
875  * _key_ as a parameter.
876  */
877 static VALUE
878 fgdbm_each_key(VALUE obj)
879 {
880  struct dbmdata *dbmp;
881  GDBM_FILE dbm;
882  VALUE keystr;
883 
884  RETURN_ENUMERATOR(obj, 0, 0);
885 
886  GetDBM2(obj, dbmp, dbm);
887  for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
888  keystr = rb_gdbm_nextkey(dbm, keystr)) {
889 
890  rb_yield(keystr);
891  GetDBM2(obj, dbmp, dbm);
892  }
893  return obj;
894 }
895 
896 /*
897  * call-seq:
898  * gdbm.each_pair { |key, value| block } -> gdbm
899  *
900  * Executes _block_ for each key in the database, passing the _key_ and the
901  * corresponding _value_ as a parameter.
902  */
903 static VALUE
904 fgdbm_each_pair(VALUE obj)
905 {
906  GDBM_FILE dbm;
907  struct dbmdata *dbmp;
908  VALUE keystr;
909 
910  RETURN_ENUMERATOR(obj, 0, 0);
911 
912  GetDBM2(obj, dbmp, dbm);
913  for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
914  keystr = rb_gdbm_nextkey(dbm, keystr)) {
915 
916  rb_yield(rb_assoc_new(keystr, rb_gdbm_fetch2(dbm, keystr)));
917  GetDBM2(obj, dbmp, dbm);
918  }
919 
920  return obj;
921 }
922 
923 /*
924  * call-seq:
925  * gdbm.keys -> array
926  *
927  * Returns an array of all keys of this database.
928  */
929 static VALUE
930 fgdbm_keys(VALUE obj)
931 {
932  struct dbmdata *dbmp;
933  GDBM_FILE dbm;
934  VALUE keystr, ary;
935 
936  GetDBM2(obj, dbmp, dbm);
937  ary = rb_ary_new();
938  for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
939  keystr = rb_gdbm_nextkey(dbm, keystr)) {
940 
941  rb_ary_push(ary, keystr);
942  }
943 
944  return ary;
945 }
946 
947 /*
948  * call-seq:
949  * gdbm.values -> array
950  *
951  * Returns an array of all values of this database.
952  */
953 static VALUE
954 fgdbm_values(VALUE obj)
955 {
956  datum key, nextkey;
957  struct dbmdata *dbmp;
958  GDBM_FILE dbm;
959  VALUE valstr, ary;
960 
961  GetDBM2(obj, dbmp, dbm);
962  ary = rb_ary_new();
963  for (key = gdbm_firstkey(dbm); key.dptr; key = nextkey) {
964  nextkey = gdbm_nextkey(dbm, key);
965  valstr = rb_gdbm_fetch(dbm, key);
966  free(key.dptr);
967  rb_ary_push(ary, valstr);
968  }
969 
970  return ary;
971 }
972 
973 /*
974  * call-seq:
975  * gdbm.include?(k) -> true or false
976  * gdbm.has_key?(k) -> true or false
977  * gdbm.member?(k) -> true or false
978  * gdbm.key?(k) -> true or false
979  *
980  * Returns true if the given key _k_ exists within the database.
981  * Returns false otherwise.
982  */
983 static VALUE
984 fgdbm_has_key(VALUE obj, VALUE keystr)
985 {
986  datum key;
987  struct dbmdata *dbmp;
988  GDBM_FILE dbm;
989  long len;
990 
991  ExportStringValue(keystr);
992  len = RSTRING_LENINT(keystr);
993  if (TOO_LONG(len)) return Qfalse;
994  key.dptr = RSTRING_PTR(keystr);
995  key.dsize = (int)len;
996 
997  GetDBM2(obj, dbmp, dbm);
998  if (gdbm_exists(dbm, key))
999  return Qtrue;
1000  return Qfalse;
1001 }
1002 
1003 /*
1004  * call-seq:
1005  * gdbm.has_value?(v) -> true or false
1006  * gdbm.value?(v) -> true or false
1007  *
1008  * Returns true if the given value _v_ exists within the database.
1009  * Returns false otherwise.
1010  */
1011 static VALUE
1012 fgdbm_has_value(VALUE obj, VALUE valstr)
1013 {
1014  struct dbmdata *dbmp;
1015  GDBM_FILE dbm;
1016  VALUE keystr, valstr2;
1017 
1018  ExportStringValue(valstr);
1019  GetDBM2(obj, dbmp, dbm);
1020  for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
1021  keystr = rb_gdbm_nextkey(dbm, keystr)) {
1022 
1023  valstr2 = rb_gdbm_fetch2(dbm, keystr);
1024 
1025  if (!NIL_P(valstr2) &&
1026  (int)RSTRING_LEN(valstr) == (int)RSTRING_LEN(valstr2) &&
1027  memcmp(RSTRING_PTR(valstr), RSTRING_PTR(valstr2),
1028  (int)RSTRING_LEN(valstr)) == 0) {
1029  return Qtrue;
1030  }
1031  }
1032  return Qfalse;
1033 }
1034 
1035 /*
1036  * call-seq:
1037  * gdbm.to_a -> array
1038  *
1039  * Returns an array of all key-value pairs contained in the database.
1040  */
1041 static VALUE
1042 fgdbm_to_a(VALUE obj)
1043 {
1044  struct dbmdata *dbmp;
1045  GDBM_FILE dbm;
1046  VALUE keystr, ary;
1047 
1048  GetDBM2(obj, dbmp, dbm);
1049  ary = rb_ary_new();
1050  for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
1051  keystr = rb_gdbm_nextkey(dbm, keystr)) {
1052 
1053  rb_ary_push(ary, rb_assoc_new(keystr, rb_gdbm_fetch2(dbm, keystr)));
1054  }
1055 
1056  return ary;
1057 }
1058 
1059 /*
1060  * call-seq:
1061  * gdbm.reorganize -> gdbm
1062  *
1063  * Reorganizes the database file. This operation removes reserved space of
1064  * elements that have already been deleted. It is only useful after a lot of
1065  * deletions in the database.
1066  */
1067 static VALUE
1068 fgdbm_reorganize(VALUE obj)
1069 {
1070  struct dbmdata *dbmp;
1071  GDBM_FILE dbm;
1072 
1073  rb_gdbm_modify(obj);
1074  GetDBM2(obj, dbmp, dbm);
1075  gdbm_reorganize(dbm);
1076  rb_fd_fix_cloexec(gdbm_fdesc(dbm));
1077  return obj;
1078 }
1079 
1080 /*
1081  * call-seq:
1082  * gdbm.sync -> gdbm
1083  *
1084  * Unless the _gdbm_ object has been opened with the *SYNC* flag, it is not
1085  * guaranteed that database modification operations are immediately applied to
1086  * the database file. This method ensures that all recent modifications
1087  * to the database are written to the file. Blocks until all writing operations
1088  * to the disk have been finished.
1089  */
1090 static VALUE
1091 fgdbm_sync(VALUE obj)
1092 {
1093  struct dbmdata *dbmp;
1094  GDBM_FILE dbm;
1095 
1096  rb_gdbm_modify(obj);
1097  GetDBM2(obj, dbmp, dbm);
1098  gdbm_sync(dbm);
1099  return obj;
1100 }
1101 
1102 /*
1103  * call-seq:
1104  * gdbm.cachesize = size -> size
1105  *
1106  * Sets the size of the internal bucket cache to _size_.
1107  */
1108 static VALUE
1109 fgdbm_set_cachesize(VALUE obj, VALUE val)
1110 {
1111  struct dbmdata *dbmp;
1112  GDBM_FILE dbm;
1113  int optval;
1114 
1115  GetDBM2(obj, dbmp, dbm);
1116  optval = FIX2INT(val);
1117  if (gdbm_setopt(dbm, GDBM_CACHESIZE, &optval, sizeof(optval)) == -1) {
1118  rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
1119  }
1120  return val;
1121 }
1122 
1123 /*
1124  * call-seq:
1125  * gdbm.fastmode = boolean -> boolean
1126  *
1127  * Turns the database's fast mode on or off. If fast mode is turned on, gdbm
1128  * does not wait for writes to be flushed to the disk before continuing.
1129  *
1130  * This option is obsolete for gdbm >= 1.8 since fast mode is turned on by
1131  * default. See also: #syncmode=
1132  */
1133 static VALUE
1134 fgdbm_set_fastmode(VALUE obj, VALUE val)
1135 {
1136  struct dbmdata *dbmp;
1137  GDBM_FILE dbm;
1138  int optval;
1139 
1140  GetDBM2(obj, dbmp, dbm);
1141  optval = 0;
1142  if (RTEST(val))
1143  optval = 1;
1144 
1145  if (gdbm_setopt(dbm, GDBM_FASTMODE, &optval, sizeof(optval)) == -1) {
1146  rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
1147  }
1148  return val;
1149 }
1150 
1151 /*
1152  * call-seq:
1153  * gdbm.syncmode = boolean -> boolean
1154  *
1155  * Turns the database's synchronization mode on or off. If the synchronization
1156  * mode is turned on, the database's in-memory state will be synchronized to
1157  * disk after every database modification operation. If the synchronization
1158  * mode is turned off, GDBM does not wait for writes to be flushed to the disk
1159  * before continuing.
1160  *
1161  * This option is only available for gdbm >= 1.8 where syncmode is turned off
1162  * by default. See also: #fastmode=
1163  */
1164 static VALUE
1165 fgdbm_set_syncmode(VALUE obj, VALUE val)
1166 {
1167 #if !defined(GDBM_SYNCMODE)
1168  fgdbm_set_fastmode(obj, RTEST(val) ? Qfalse : Qtrue);
1169  return val;
1170 #else
1171  struct dbmdata *dbmp;
1172  GDBM_FILE dbm;
1173  int optval;
1174 
1175  GetDBM2(obj, dbmp, dbm);
1176  optval = 0;
1177  if (RTEST(val))
1178  optval = 1;
1179 
1180  if (gdbm_setopt(dbm, GDBM_FASTMODE, &optval, sizeof(optval)) == -1) {
1181  rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
1182  }
1183  return val;
1184 #endif
1185 }
1186 
1187 /*
1188  * call-seq:
1189  * gdbm.to_hash -> hash
1190  *
1191  * Returns a hash of all key-value pairs contained in the database.
1192  */
1193 static VALUE
1194 fgdbm_to_hash(VALUE obj)
1195 {
1196  struct dbmdata *dbmp;
1197  GDBM_FILE dbm;
1198  VALUE keystr, hash;
1199 
1200  GetDBM2(obj, dbmp, dbm);
1201  hash = rb_hash_new();
1202  for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
1203  keystr = rb_gdbm_nextkey(dbm, keystr)) {
1204 
1205  rb_hash_aset(hash, keystr, rb_gdbm_fetch2(dbm, keystr));
1206  }
1207 
1208  return hash;
1209 }
1210 
1211 /*
1212  * call-seq:
1213  * gdbm.reject { |key, value| block } -> hash
1214  *
1215  * Returns a hash copy of _gdbm_ where all key-value pairs from _gdbm_ for
1216  * which _block_ evaluates to true are removed. See also: #delete_if
1217  */
1218 static VALUE
1219 fgdbm_reject(VALUE obj)
1220 {
1221  return rb_hash_delete_if(fgdbm_to_hash(obj));
1222 }
1223 
1224 void
1226 {
1227  rb_cGDBM = rb_define_class("GDBM", rb_cObject);
1228  rb_eGDBMError = rb_define_class("GDBMError", rb_eStandardError);
1229  rb_eGDBMFatalError = rb_define_class("GDBMFatalError", rb_eException);
1230  rb_include_module(rb_cGDBM, rb_mEnumerable);
1231 
1232  rb_define_alloc_func(rb_cGDBM, fgdbm_s_alloc);
1233  rb_define_singleton_method(rb_cGDBM, "open", fgdbm_s_open, -1);
1234 
1235  rb_define_method(rb_cGDBM, "initialize", fgdbm_initialize, -1);
1236  rb_define_method(rb_cGDBM, "close", fgdbm_close, 0);
1237  rb_define_method(rb_cGDBM, "closed?", fgdbm_closed, 0);
1238  rb_define_method(rb_cGDBM, "[]", fgdbm_aref, 1);
1239  rb_define_method(rb_cGDBM, "fetch", fgdbm_fetch_m, -1);
1240  rb_define_method(rb_cGDBM, "[]=", fgdbm_store, 2);
1241  rb_define_method(rb_cGDBM, "store", fgdbm_store, 2);
1242  rb_define_method(rb_cGDBM, "index", fgdbm_index, 1);
1243  rb_define_method(rb_cGDBM, "key", fgdbm_key, 1);
1244  rb_define_method(rb_cGDBM, "select", fgdbm_select, 0);
1245  rb_define_method(rb_cGDBM, "values_at", fgdbm_values_at, -1);
1246  rb_define_method(rb_cGDBM, "length", fgdbm_length, 0);
1247  rb_define_method(rb_cGDBM, "size", fgdbm_length, 0);
1248  rb_define_method(rb_cGDBM, "empty?", fgdbm_empty_p, 0);
1249  rb_define_method(rb_cGDBM, "each", fgdbm_each_pair, 0);
1250  rb_define_method(rb_cGDBM, "each_value", fgdbm_each_value, 0);
1251  rb_define_method(rb_cGDBM, "each_key", fgdbm_each_key, 0);
1252  rb_define_method(rb_cGDBM, "each_pair", fgdbm_each_pair, 0);
1253  rb_define_method(rb_cGDBM, "keys", fgdbm_keys, 0);
1254  rb_define_method(rb_cGDBM, "values", fgdbm_values, 0);
1255  rb_define_method(rb_cGDBM, "shift", fgdbm_shift, 0);
1256  rb_define_method(rb_cGDBM, "delete", fgdbm_delete, 1);
1257  rb_define_method(rb_cGDBM, "delete_if", fgdbm_delete_if, 0);
1258  rb_define_method(rb_cGDBM, "reject!", fgdbm_delete_if, 0);
1259  rb_define_method(rb_cGDBM, "reject", fgdbm_reject, 0);
1260  rb_define_method(rb_cGDBM, "clear", fgdbm_clear, 0);
1261  rb_define_method(rb_cGDBM, "invert", fgdbm_invert, 0);
1262  rb_define_method(rb_cGDBM, "update", fgdbm_update, 1);
1263  rb_define_method(rb_cGDBM, "replace", fgdbm_replace, 1);
1264  rb_define_method(rb_cGDBM, "reorganize", fgdbm_reorganize, 0);
1265  rb_define_method(rb_cGDBM, "sync", fgdbm_sync, 0);
1266  /* rb_define_method(rb_cGDBM, "setopt", fgdbm_setopt, 2); */
1267  rb_define_method(rb_cGDBM, "cachesize=", fgdbm_set_cachesize, 1);
1268  rb_define_method(rb_cGDBM, "fastmode=", fgdbm_set_fastmode, 1);
1269  rb_define_method(rb_cGDBM, "syncmode=", fgdbm_set_syncmode, 1);
1270 
1271  rb_define_method(rb_cGDBM, "include?", fgdbm_has_key, 1);
1272  rb_define_method(rb_cGDBM, "has_key?", fgdbm_has_key, 1);
1273  rb_define_method(rb_cGDBM, "member?", fgdbm_has_key, 1);
1274  rb_define_method(rb_cGDBM, "has_value?", fgdbm_has_value, 1);
1275  rb_define_method(rb_cGDBM, "key?", fgdbm_has_key, 1);
1276  rb_define_method(rb_cGDBM, "value?", fgdbm_has_value, 1);
1277 
1278  rb_define_method(rb_cGDBM, "to_a", fgdbm_to_a, 0);
1279  rb_define_method(rb_cGDBM, "to_hash", fgdbm_to_hash, 0);
1280 
1281  /* flag for #new and #open: open database as a reader */
1282  rb_define_const(rb_cGDBM, "READER", INT2FIX(GDBM_READER|RUBY_GDBM_RW_BIT));
1283  /* flag for #new and #open: open database as a writer */
1284  rb_define_const(rb_cGDBM, "WRITER", INT2FIX(GDBM_WRITER|RUBY_GDBM_RW_BIT));
1285  /* flag for #new and #open: open database as a writer; if the database does not exist, create a new one */
1286  rb_define_const(rb_cGDBM, "WRCREAT", INT2FIX(GDBM_WRCREAT|RUBY_GDBM_RW_BIT));
1287  /* flag for #new and #open: open database as a writer; overwrite any existing databases */
1288  rb_define_const(rb_cGDBM, "NEWDB", INT2FIX(GDBM_NEWDB|RUBY_GDBM_RW_BIT));
1289 
1290  /* flag for #new and #open. this flag is obsolete for gdbm >= 1.8 */
1291  rb_define_const(rb_cGDBM, "FAST", INT2FIX(GDBM_FAST));
1292  /* this flag is obsolete in gdbm 1.8.
1293  On gdbm 1.8, fast mode is default behavior. */
1294 
1295  /* gdbm version 1.8 specific */
1296 #if defined(GDBM_SYNC)
1297  /* flag for #new and #open. only for gdbm >= 1.8 */
1298  rb_define_const(rb_cGDBM, "SYNC", INT2FIX(GDBM_SYNC));
1299 #endif
1300 #if defined(GDBM_NOLOCK)
1301  /* flag for #new and #open */
1302  rb_define_const(rb_cGDBM, "NOLOCK", INT2FIX(GDBM_NOLOCK));
1303 #endif
1304  /* version of the gdbm library*/
1305  rb_define_const(rb_cGDBM, "VERSION", rb_str_new2(gdbm_version));
1306 }
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:649
TypedData_Make_Struct
#define TypedData_Make_Struct(klass, type, data_type, sval)
Definition: ruby.h:1244
Check_Type
#define Check_Type(v, t)
Definition: ruby.h:595
rb_include_module
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:869
rb_assoc_new
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:896
rb_str_new2
#define rb_str_new2
Definition: intern.h:903
GetDBM2
#define GetDBM2(obj, dbmp, dbm)
Definition: gdbm.c:112
FIX2INT
#define FIX2INT(x)
Definition: ruby.h:717
rb_hash_new
VALUE rb_hash_new(void)
Definition: hash.c:1523
rb_warn
void rb_warn(const char *fmt,...)
Definition: error.c:315
rb_block_given_p
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:898
int
__inline__ int
Definition: rb_mjit_min_header-2.7.2.h:2877
dbmdata::di_dbm
GDBM_FILE di_dbm
Definition: gdbm.c:98
INT2FIX
#define INT2FIX(i)
Definition: ruby.h:263
RSTRING_PTR
#define RSTRING_PTR(str)
Definition: ruby.h:1009
i
uint32_t i
Definition: rb_mjit_min_header-2.7.2.h:5499
VALUE
unsigned long VALUE
Definition: ruby.h:102
rb_eArgError
VALUE rb_eArgError
Definition: error.c:925
MY_FATAL_FUNC
#define MY_FATAL_FUNC
Definition: gdbm.c:85
rb_intern
#define rb_intern(str)
datum::dptr
char * dptr
Definition: sdbm.h:51
RSTRING_LENINT
#define RSTRING_LENINT(str)
Definition: ruby.h:1017
rb_fd_fix_cloexec
void rb_fd_fix_cloexec(int fd)
Definition: io.c:268
rb_str_dup
VALUE rb_str_dup(VALUE)
Definition: string.c:1516
rb_eIndexError
VALUE rb_eIndexError
Definition: error.c:926
MY_BLOCK_SIZE
#define MY_BLOCK_SIZE
Definition: gdbm.c:84
rb_define_singleton_method
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1755
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1551
ptr
struct RIMemo * ptr
Definition: debug.c:65
Qfalse
#define Qfalse
Definition: ruby.h:467
FilePathValue
#define FilePathValue(v)
Definition: ruby.h:624
OBJ_FREEZE
#define OBJ_FREEZE(x)
Definition: ruby.h:1377
ExportStringValue
#define ExportStringValue(v)
Definition: ruby.h:617
RB_BLOCK_CALL_FUNC_ARGLIST
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
Definition: ruby.h:1964
rb_protect
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *pstate)
Protects a function call from potential global escapes from the function.
Definition: eval.c:1072
rb_error_frozen
void rb_error_frozen(const char *what)
Definition: error.c:2976
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2671
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.2.h:13302
rb_ary_tmp_new
VALUE rb_ary_tmp_new(long capa)
Definition: array.c:768
RUBY_GDBM_RW_BIT
#define RUBY_GDBM_RW_BIT
Definition: gdbm.c:82
rb_jump_tag
void rb_jump_tag(int tag)
Continues the exception caught by rb_protect() and rb_eval_string_protect().
Definition: eval.c:884
GetDBM
#define GetDBM(obj, dbmp)
Definition: gdbm.c:107
rb_hash_delete_if
VALUE rb_hash_delete_if(VALUE hash)
Definition: hash.c:2493
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:1195
ruby.h
RARRAY_AREF
#define RARRAY_AREF(a, i)
Definition: psych_emitter.c:7
rb_sys_fail
void rb_sys_fail(const char *mesg)
Definition: error.c:2795
rb_eRuntimeError
VALUE rb_eRuntimeError
Definition: error.c:922
datum
Definition: sdbm.h:50
RETURN_ENUMERATOR
#define RETURN_ENUMERATOR(obj, argc, argv)
Definition: intern.h:279
size
int size
Definition: encoding.c:58
NORETURN
NORETURN(static void rb_gdbm_fatal(const char *msg))
memcmp
int memcmp(const void *s1, const void *s2, size_t len)
Definition: memcmp.c:7
key
key
Definition: openssl_missing.h:181
EPERM
#define EPERM
Definition: _sdbm.c:92
rb_scan_args
#define rb_scan_args(argc, argvp, fmt,...)
Definition: rb_mjit_min_header-2.7.2.h:6407
rb_ary_clear
VALUE rb_ary_clear(VALUE ary)
Definition: array.c:3862
RARRAY_LEN
#define RARRAY_LEN(a)
Definition: ruby.h:1070
Init_gdbm
void Init_gdbm(void)
Definition: gdbm.c:1225
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:2010
rb_ary_new2
#define rb_ary_new2
Definition: intern.h:103
obj
const VALUE VALUE obj
Definition: rb_mjit_min_header-2.7.2.h:5777
TypedData_Get_Struct
#define TypedData_Get_Struct(obj, type, data_type, sval)
Definition: ruby.h:1252
T_ARRAY
#define T_ARRAY
Definition: ruby.h:530
argv
char ** argv
Definition: ruby.c:223
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
datum::dsize
int dsize
Definition: sdbm.h:52
RARRAY_CONST_PTR
#define RARRAY_CONST_PTR(s)
Definition: psych_emitter.c:4
RUBY_TYPED_FREE_IMMEDIATELY
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1207
rb_hash_aset
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:2852
dbmdata::di_dbm
DBM * di_dbm
Definition: dbm.c:39
ruby::backward::cxxanyargs::rb_block_call
VALUE rb_block_call(VALUE q, ID w, int e, const VALUE *r, type *t, VALUE y)
Call a method with a block.
Definition: cxxanyargs.hpp:178
NIL_P
#define NIL_P(v)
Definition: ruby.h:482
argc
int argc
Definition: ruby.c:222
rb_sys_fail_str
void rb_sys_fail_str(VALUE mesg)
Definition: error.c:2801
rb_define_const
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2891
dbmdata
Definition: dbm.c:37
free
#define free(x)
Definition: dln.c:52
rb_data_type_struct
Definition: ruby.h:1148
rb_eException
VALUE rb_eException
Definition: error.c:916
xfree
#define xfree
Definition: defines.h:216
Qtrue
#define Qtrue
Definition: ruby.h:468
errno
int errno
OBJ_FROZEN
#define OBJ_FROZEN(x)
Definition: ruby.h:1375
v
int VALUE v
Definition: rb_mjit_min_header-2.7.2.h:12380
len
uint8_t len
Definition: escape.c:17
dbmdata::di_size
int di_size
Definition: gdbm.c:97
rb_yield
VALUE rb_yield(VALUE)
Definition: vm_eval.c:1237
rb_ensure
VALUE rb_ensure(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*e_proc)(VALUE), VALUE data2)
An equivalent to ensure clause.
Definition: eval.c:1115
rb_ary_new
VALUE rb_ary_new(void)
Definition: array.c:723
NUM2INT
#define NUM2INT(x)
Definition: ruby.h:715
Qnil
#define Qnil
Definition: ruby.h:469
rb_str_new
#define rb_str_new(str, len)
Definition: rb_mjit_min_header-2.7.2.h:6151
rb_mEnumerable
VALUE rb_mEnumerable
Definition: enum.c:20
rb_eStandardError
VALUE rb_eStandardError
Definition: error.c:921
RSTRING_LEN
#define RSTRING_LEN(str)
Definition: ruby.h:1005
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
RTEST
#define RTEST(v)
Definition: ruby.h:481
TOO_LONG
#define TOO_LONG(n)
Definition: gdbm.c:79
n
const char size_t n
Definition: rb_mjit_min_header-2.7.2.h:5491