Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 611 lines (524 sloc) 13.92 kb
fedf489 2000-05-01
matz authored
1 /**********************************************************************
3db12e8 Initial revision
matz authored
2
3 struct.c -
4
5 $Author$
6 $Date$
7 created at: Tue Mar 22 18:44:30 JST 1995
8
8e5c3b2 * dir.c (dir_s_glob): supprt backslash escape of metacharacters
matz authored
9 Copyright (C) 1993-2001 Yukihiro Matsumoto
fedf489 2000-05-01
matz authored
10
11 **********************************************************************/
3db12e8 Initial revision
matz authored
12
13 #include "ruby.h"
14
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
15 VALUE rb_cStruct;
3db12e8 Initial revision
matz authored
16
1fe40b7 * marshal.c (r_object): better allocation type check for
matz authored
17 static VALUE struct_alloc _((VALUE));
65a5162 1.4.0
matz authored
18
b47a994 * parse.y (yylex): ternary ? can be followed by newline.
matz authored
19 VALUE
20 rb_struct_iv_get(c, name)
21 VALUE c;
65a5162 1.4.0
matz authored
22 char *name;
23 {
24 ID id;
25
26 id = rb_intern(name);
27 for (;;) {
b47a994 * parse.y (yylex): ternary ? can be followed by newline.
matz authored
28 if (rb_ivar_defined(c, id))
29 return rb_ivar_get(c, id);
30 c = RCLASS(c)->super;
31 if (c == 0 || c == rb_cStruct)
65a5162 1.4.0
matz authored
32 return Qnil;
33 }
34 }
35
36 static VALUE
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
37 rb_struct_s_members(obj)
38 VALUE obj;
39 {
40 VALUE member, ary;
41 VALUE *p, *pend;
42
b47a994 * parse.y (yylex): ternary ? can be followed by newline.
matz authored
43 member = rb_struct_iv_get(obj, "__member__");
3db12e8 Initial revision
matz authored
44 if (NIL_P(member)) {
8b1de0b 2000-05-24
matz authored
45 rb_bug("uninitialized struct");
3db12e8 Initial revision
matz authored
46 }
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
47 ary = rb_ary_new2(RARRAY(member)->len);
48 p = RARRAY(member)->ptr; pend = p + RARRAY(member)->len;
3db12e8 Initial revision
matz authored
49 while (p < pend) {
7194267 2000-04-10
matz authored
50 rb_ary_push(ary, rb_str_new2(rb_id2name(SYM2ID(*p))));
3db12e8 Initial revision
matz authored
51 p++;
52 }
53
54 return ary;
55 }
56
57 static VALUE
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
58 rb_struct_members(obj)
3db12e8 Initial revision
matz authored
59 VALUE obj;
60 {
c786866 * range.c (range_step): 'iter' here should be an array.
matz authored
61 return rb_struct_s_members(rb_obj_class(obj));
3db12e8 Initial revision
matz authored
62 }
63
64 VALUE
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
65 rb_struct_getmember(obj, id)
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
66 VALUE obj;
3db12e8 Initial revision
matz authored
67 ID id;
68 {
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
69 VALUE member, slot;
65a5162 1.4.0
matz authored
70 long i;
3db12e8 Initial revision
matz authored
71
b47a994 * parse.y (yylex): ternary ? can be followed by newline.
matz authored
72 member = rb_struct_iv_get(rb_obj_class(obj), "__member__");
3db12e8 Initial revision
matz authored
73 if (NIL_P(member)) {
8b1de0b 2000-05-24
matz authored
74 rb_bug("uninitialized struct");
3db12e8 Initial revision
matz authored
75 }
8b1de0b 2000-05-24
matz authored
76 slot = ID2SYM(id);
3db12e8 Initial revision
matz authored
77 for (i=0; i<RARRAY(member)->len; i++) {
78 if (RARRAY(member)->ptr[i] == slot) {
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
79 return RSTRUCT(obj)->ptr[i];
3db12e8 Initial revision
matz authored
80 }
81 }
ffe1cf5 * error.c (exc_exception): clone the receiver exception instead of
matz authored
82 rb_name_error(id, "%s is not struct member", rb_id2name(id));
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
83 return Qnil; /* not reached */
3db12e8 Initial revision
matz authored
84 }
85
86 static VALUE
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
87 rb_struct_ref(obj)
3db12e8 Initial revision
matz authored
88 VALUE obj;
89 {
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
90 return rb_struct_getmember(obj, rb_frame_last_func());
3db12e8 Initial revision
matz authored
91 }
92
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
93 static VALUE rb_struct_ref0(obj) VALUE obj; {return RSTRUCT(obj)->ptr[0];}
94 static VALUE rb_struct_ref1(obj) VALUE obj; {return RSTRUCT(obj)->ptr[1];}
95 static VALUE rb_struct_ref2(obj) VALUE obj; {return RSTRUCT(obj)->ptr[2];}
96 static VALUE rb_struct_ref3(obj) VALUE obj; {return RSTRUCT(obj)->ptr[3];}
97 static VALUE rb_struct_ref4(obj) VALUE obj; {return RSTRUCT(obj)->ptr[4];}
98 static VALUE rb_struct_ref5(obj) VALUE obj; {return RSTRUCT(obj)->ptr[5];}
99 static VALUE rb_struct_ref6(obj) VALUE obj; {return RSTRUCT(obj)->ptr[6];}
100 static VALUE rb_struct_ref7(obj) VALUE obj; {return RSTRUCT(obj)->ptr[7];}
101 static VALUE rb_struct_ref8(obj) VALUE obj; {return RSTRUCT(obj)->ptr[8];}
102 static VALUE rb_struct_ref9(obj) VALUE obj; {return RSTRUCT(obj)->ptr[9];}
3db12e8 Initial revision
matz authored
103
65a5162 1.4.0
matz authored
104 static VALUE (*ref_func[10])() = {
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
105 rb_struct_ref0,
106 rb_struct_ref1,
107 rb_struct_ref2,
108 rb_struct_ref3,
109 rb_struct_ref4,
110 rb_struct_ref5,
111 rb_struct_ref6,
112 rb_struct_ref7,
113 rb_struct_ref8,
114 rb_struct_ref9,
3db12e8 Initial revision
matz authored
115 };
116
14cd947 * struct.c (rb_struct_modify): should check frozen and taint
matz authored
117 static void
118 rb_struct_modify(s)
119 VALUE s;
120 {
121 if (OBJ_FROZEN(s)) rb_error_frozen("Struct");
122 if (!OBJ_TAINTED(s) && rb_safe_level() >= 4)
123 rb_raise(rb_eSecurityError, "Insecure: can't modify Struct");
124 }
125
3db12e8 Initial revision
matz authored
126 static VALUE
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
127 rb_struct_set(obj, val)
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
128 VALUE obj, val;
3db12e8 Initial revision
matz authored
129 {
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
130 VALUE member, slot;
65a5162 1.4.0
matz authored
131 long i;
3db12e8 Initial revision
matz authored
132
b47a994 * parse.y (yylex): ternary ? can be followed by newline.
matz authored
133 member = rb_struct_iv_get(rb_obj_class(obj), "__member__");
3db12e8 Initial revision
matz authored
134 if (NIL_P(member)) {
aac5ff0 * struct.c (Init_Struct): should undefine "allocate" for Struct
matz authored
135 rb_bug("uninitialized struct");
3db12e8 Initial revision
matz authored
136 }
14cd947 * struct.c (rb_struct_modify): should check frozen and taint
matz authored
137 rb_struct_modify(obj);
3db12e8 Initial revision
matz authored
138 for (i=0; i<RARRAY(member)->len; i++) {
139 slot = RARRAY(member)->ptr[i];
7194267 2000-04-10
matz authored
140 if (rb_id_attrset(SYM2ID(slot)) == rb_frame_last_func()) {
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
141 return RSTRUCT(obj)->ptr[i] = val;
3db12e8 Initial revision
matz authored
142 }
143 }
ffe1cf5 * error.c (exc_exception): clone the receiver exception instead of
matz authored
144 rb_name_error(rb_frame_last_func(), "`%s' is not a struct member",
145 rb_id2name(rb_frame_last_func()));
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
146 return Qnil; /* not reached */
3db12e8 Initial revision
matz authored
147 }
148
149 static VALUE
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
150 make_struct(name, member, klass)
151 VALUE name, member, klass;
3db12e8 Initial revision
matz authored
152 {
153 VALUE nstr;
154 ID id;
65a5162 1.4.0
matz authored
155 long i;
3db12e8 Initial revision
matz authored
156
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
157 if (NIL_P(name)) {
158 nstr = rb_class_new(klass);
5915dc2 @nobu * class.c (rb_make_metaclass): [new]
nobu authored
159 rb_class_inherited(klass, nstr);
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
160 }
161 else {
fd06a2a * eval.c (block_pass): should not downgrade safe level.
matz authored
162 char *cname = StringValuePtr(name);
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
163 id = rb_intern(cname);
9d228b1 19991214
matz authored
164 if (!rb_is_const_id(id)) {
ffe1cf5 * error.c (exc_exception): clone the receiver exception instead of
matz authored
165 rb_name_error(id, "identifier %s needs to be constant", cname);
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
166 }
167 nstr = rb_define_class_under(klass, cname, klass);
3db12e8 Initial revision
matz authored
168 }
65a5162 1.4.0
matz authored
169 rb_iv_set(nstr, "__size__", INT2NUM(RARRAY(member)->len));
3db12e8 Initial revision
matz authored
170 rb_iv_set(nstr, "__member__", member);
171
1fe40b7 * marshal.c (r_object): better allocation type check for
matz authored
172 rb_define_singleton_method(nstr, "allocate", struct_alloc, 0);
173 rb_define_singleton_method(nstr, "new", rb_class_new_instance, -1);
174 rb_define_singleton_method(nstr, "[]", rb_class_new_instance, -1);
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
175 rb_define_singleton_method(nstr, "members", rb_struct_s_members, 0);
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
176 for (i=0; i< RARRAY(member)->len; i++) {
7194267 2000-04-10
matz authored
177 ID id = SYM2ID(RARRAY(member)->ptr[i]);
3db12e8 Initial revision
matz authored
178 if (i<10) {
179 rb_define_method_id(nstr, id, ref_func[i], 0);
180 }
181 else {
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
182 rb_define_method_id(nstr, id, rb_struct_ref, 0);
3db12e8 Initial revision
matz authored
183 }
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
184 rb_define_method_id(nstr, rb_id_attrset(id), rb_struct_set, 1);
3db12e8 Initial revision
matz authored
185 }
186
187 return nstr;
188 }
189
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
190 #ifdef HAVE_STDARG_PROTOTYPES
191 #include <stdarg.h>
192 #define va_init_list(a,b) va_start(a,b)
193 #else
3db12e8 Initial revision
matz authored
194 #include <varargs.h>
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
195 #define va_init_list(a,b) va_start(a)
196 #endif
3db12e8 Initial revision
matz authored
197
198 VALUE
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
199 #ifdef HAVE_STDARG_PROTOTYPES
65a5162 1.4.0
matz authored
200 rb_struct_define(const char *name, ...)
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
201 #else
202 rb_struct_define(name, va_alist)
65a5162 1.4.0
matz authored
203 const char *name;
3db12e8 Initial revision
matz authored
204 va_dcl
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
205 #endif
3db12e8 Initial revision
matz authored
206 {
207 va_list ar;
208 VALUE nm, ary;
209 char *mem;
210
9d228b1 19991214
matz authored
211 if (!name) nm = Qnil;
212 else nm = rb_str_new2(name);
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
213 ary = rb_ary_new();
3db12e8 Initial revision
matz authored
214
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
215 va_init_list(ar, name);
3db12e8 Initial revision
matz authored
216 while (mem = va_arg(ar, char*)) {
217 ID slot = rb_intern(mem);
7194267 2000-04-10
matz authored
218 rb_ary_push(ary, ID2SYM(slot));
3db12e8 Initial revision
matz authored
219 }
220 va_end(ar);
221
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
222 return make_struct(nm, ary, rb_cStruct);
3db12e8 Initial revision
matz authored
223 }
224
225 static VALUE
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
226 rb_struct_s_def(argc, argv, klass)
3db12e8 Initial revision
matz authored
227 int argc;
228 VALUE *argv;
9d228b1 19991214
matz authored
229 VALUE klass;
3db12e8 Initial revision
matz authored
230 {
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
231 VALUE name, rest;
65a5162 1.4.0
matz authored
232 long i;
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
233 VALUE st;
9d228b1 19991214
matz authored
234 ID id;
3db12e8 Initial revision
matz authored
235
236 rb_scan_args(argc, argv, "1*", &name, &rest);
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
237 for (i=0; i<RARRAY(rest)->len; i++) {
9d228b1 19991214
matz authored
238 id = rb_to_id(RARRAY(rest)->ptr[i]);
7194267 2000-04-10
matz authored
239 RARRAY(rest)->ptr[i] = ID2SYM(id);
3db12e8 Initial revision
matz authored
240 }
d137568 matz
matz authored
241 if (!NIL_P(name) && TYPE(name) != T_STRING) {
9d228b1 19991214
matz authored
242 id = rb_to_id(name);
7194267 2000-04-10
matz authored
243 rb_ary_unshift(rest, ID2SYM(id));
9d228b1 19991214
matz authored
244 name = Qnil;
245 }
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
246 st = make_struct(name, rest, klass);
247
248 return st;
3db12e8 Initial revision
matz authored
249 }
250
65a5162 1.4.0
matz authored
251 static VALUE
252 rb_struct_initialize(self, values)
253 VALUE self, values;
3db12e8 Initial revision
matz authored
254 {
c786866 * range.c (range_step): 'iter' here should be an array.
matz authored
255 VALUE klass = rb_obj_class(self);
3db12e8 Initial revision
matz authored
256 VALUE size;
65a5162 1.4.0
matz authored
257 long n;
3db12e8 Initial revision
matz authored
258
14cd947 * struct.c (rb_struct_modify): should check frozen and taint
matz authored
259 rb_struct_modify(self);
b47a994 * parse.y (yylex): ternary ? can be followed by newline.
matz authored
260 size = rb_struct_iv_get(klass, "__size__");
7194267 2000-04-10
matz authored
261 n = FIX2LONG(size);
65a5162 1.4.0
matz authored
262 if (n < RARRAY(values)->len) {
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
263 rb_raise(rb_eArgError, "struct size differs");
3db12e8 Initial revision
matz authored
264 }
65a5162 1.4.0
matz authored
265 MEMCPY(RSTRUCT(self)->ptr, RARRAY(values)->ptr, VALUE, RARRAY(values)->len);
266 if (n > RARRAY(values)->len) {
267 rb_mem_clear(RSTRUCT(self)->ptr+RARRAY(values)->len,
268 n-RARRAY(values)->len);
3db12e8 Initial revision
matz authored
269 }
65a5162 1.4.0
matz authored
270 return Qnil;
271 }
272
273 static VALUE
1fe40b7 * marshal.c (r_object): better allocation type check for
matz authored
274 struct_alloc(klass)
65a5162 1.4.0
matz authored
275 VALUE klass;
276 {
277 VALUE size;
278 long n;
279 NEWOBJ(st, struct RStruct);
280 OBJSETUP(st, klass, T_STRUCT);
281
b47a994 * parse.y (yylex): ternary ? can be followed by newline.
matz authored
282 size = rb_struct_iv_get(klass, "__size__");
65a5162 1.4.0
matz authored
283 n = FIX2LONG(size);
284
285 st->ptr = ALLOC_N(VALUE, n);
286 rb_mem_clear(st->ptr, n);
287 st->len = n;
288
289 return (VALUE)st;
290 }
291
292 VALUE
293 rb_struct_alloc(klass, values)
294 VALUE klass, values;
295 {
1fe40b7 * marshal.c (r_object): better allocation type check for
matz authored
296 return rb_class_new_instance(RARRAY(values)->len, RARRAY(values)->ptr, klass);
3db12e8 Initial revision
matz authored
297 }
298
299 VALUE
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
300 #ifdef HAVE_STDARG_PROTOTYPES
301 rb_struct_new(VALUE klass, ...)
302 #else
303 rb_struct_new(klass, va_alist)
304 VALUE klass;
3db12e8 Initial revision
matz authored
305 va_dcl
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
306 #endif
3db12e8 Initial revision
matz authored
307 {
65a5162 1.4.0
matz authored
308 VALUE sz, *mem;
309 long size, i;
3db12e8 Initial revision
matz authored
310 va_list args;
311
b47a994 * parse.y (yylex): ternary ? can be followed by newline.
matz authored
312 sz = rb_struct_iv_get(klass, "__size__");
65a5162 1.4.0
matz authored
313 size = FIX2LONG(sz);
314 mem = ALLOCA_N(VALUE, size);
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
315 va_init_list(args, klass);
316 for (i=0; i<size; i++) {
65a5162 1.4.0
matz authored
317 mem[i] = va_arg(args, VALUE);
3db12e8 Initial revision
matz authored
318 }
319 va_end(args);
320
1fe40b7 * marshal.c (r_object): better allocation type check for
matz authored
321 return rb_class_new_instance(size, mem, klass);
3db12e8 Initial revision
matz authored
322 }
323
324 static VALUE
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
325 rb_struct_each(s)
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
326 VALUE s;
3db12e8 Initial revision
matz authored
327 {
65a5162 1.4.0
matz authored
328 long i;
3db12e8 Initial revision
matz authored
329
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
330 for (i=0; i<RSTRUCT(s)->len; i++) {
331 rb_yield(RSTRUCT(s)->ptr[i]);
3db12e8 Initial revision
matz authored
332 }
65a5162 1.4.0
matz authored
333 return s;
3db12e8 Initial revision
matz authored
334 }
335
336 static VALUE
19c42c0 * variable.c (rb_obj_remove_instance_variable): raise NameError if
matz authored
337 rb_struct_each_pair(s)
338 VALUE s;
339 {
340 VALUE member;
341 long i;
342
343 member = rb_struct_iv_get(rb_obj_class(s), "__member__");
344 if (NIL_P(member)) {
345 rb_bug("non-initialized struct");
346 }
347 for (i=0; i<RSTRUCT(s)->len; i++) {
348 rb_yield(rb_assoc_new(RARRAY(member)->ptr[i], RSTRUCT(s)->ptr[i]));
349 }
350 return s;
351 }
352
353 static VALUE
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
354 rb_struct_to_s(s)
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
355 VALUE s;
3db12e8 Initial revision
matz authored
356 {
c786866 * range.c (range_step): 'iter' here should be an array.
matz authored
357 char *cname = rb_class2name(rb_obj_class(s));
1ce6f06 matz
matz authored
358 VALUE str = rb_str_new(0, strlen(cname) + 4);
3db12e8 Initial revision
matz authored
359
1ce6f06 matz
matz authored
360 sprintf(RSTRING(str)->ptr, "#<%s>", cname);
52f90f6 matz
matz authored
361 RSTRING(str)->len = strlen(RSTRING(str)->ptr);
1ce6f06 matz
matz authored
362 return str;
3db12e8 Initial revision
matz authored
363 }
364
365 static VALUE
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
366 inspect_struct(s)
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
367 VALUE s;
3db12e8 Initial revision
matz authored
368 {
c786866 * range.c (range_step): 'iter' here should be an array.
matz authored
369 char *cname = rb_class2name(rb_obj_class(s));
3db12e8 Initial revision
matz authored
370 VALUE str, member;
65a5162 1.4.0
matz authored
371 long i;
3db12e8 Initial revision
matz authored
372
b47a994 * parse.y (yylex): ternary ? can be followed by newline.
matz authored
373 member = rb_struct_iv_get(rb_obj_class(s), "__member__");
3db12e8 Initial revision
matz authored
374 if (NIL_P(member)) {
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
375 rb_bug("non-initialized struct");
3db12e8 Initial revision
matz authored
376 }
377
abfaac7 * ruby.c (proc_options): unexpected SecurityError happens when -T4.
matz authored
378 str = rb_str_buf_new2("#<");
7194267 2000-04-10
matz authored
379 rb_str_cat2(str, cname);
380 rb_str_cat2(str, " ");
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
381 for (i=0; i<RSTRUCT(s)->len; i++) {
3db12e8 Initial revision
matz authored
382 VALUE str2, slot;
383 char *p;
384
385 if (i > 0) {
7194267 2000-04-10
matz authored
386 rb_str_cat2(str, ", ");
3db12e8 Initial revision
matz authored
387 }
388 slot = RARRAY(member)->ptr[i];
7194267 2000-04-10
matz authored
389 p = rb_id2name(SYM2ID(slot));
390 rb_str_cat2(str, p);
391 rb_str_cat2(str, "=");
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
392 str2 = rb_inspect(RSTRUCT(s)->ptr[i]);
7194267 2000-04-10
matz authored
393 rb_str_append(str, str2);
3db12e8 Initial revision
matz authored
394 }
7194267 2000-04-10
matz authored
395 rb_str_cat2(str, ">");
bf70582 2000-02-23
matz authored
396 OBJ_INFECT(str, s);
3db12e8 Initial revision
matz authored
397
398 return str;
399 }
400
401 static VALUE
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
402 rb_struct_inspect(s)
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
403 VALUE s;
3db12e8 Initial revision
matz authored
404 {
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
405 if (rb_inspecting_p(s)) {
c786866 * range.c (range_step): 'iter' here should be an array.
matz authored
406 char *cname = rb_class2name(rb_obj_class(s));
1ce6f06 matz
matz authored
407 VALUE str = rb_str_new(0, strlen(cname) + 8);
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
408
1ce6f06 matz
matz authored
409 sprintf(RSTRING(str)->ptr, "#<%s:...>", cname);
52f90f6 matz
matz authored
410 RSTRING(str)->len = strlen(RSTRING(str)->ptr);
1ce6f06 matz
matz authored
411 return str;
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
412 }
413 return rb_protect_inspect(inspect_struct, s, 0);
3db12e8 Initial revision
matz authored
414 }
415
416 static VALUE
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
417 rb_struct_to_a(s)
418 VALUE s;
419 {
420 return rb_ary_new4(RSTRUCT(s)->len, RSTRUCT(s)->ptr);
421 }
422
423 static VALUE
424 rb_struct_clone(s)
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
425 VALUE s;
3db12e8 Initial revision
matz authored
426 {
1fe40b7 * marshal.c (r_object): better allocation type check for
matz authored
427 VALUE clone = rb_obj_clone(s);
428
429 RSTRUCT(clone)->ptr = ALLOC_N(VALUE, RSTRUCT(s)->len);
430 RSTRUCT(clone)->len = RSTRUCT(s)->len;
431 MEMCPY(RSTRUCT(clone)->ptr, RSTRUCT(s)->ptr, VALUE, RSTRUCT(clone)->len);
de71615 20000105
matz authored
432
1fe40b7 * marshal.c (r_object): better allocation type check for
matz authored
433 return clone;
3db12e8 Initial revision
matz authored
434 }
435
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
436 static VALUE
437 rb_struct_aref_id(s, id)
438 VALUE s;
439 ID id;
440 {
441 VALUE member;
65a5162 1.4.0
matz authored
442 long i, len;
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
443
b47a994 * parse.y (yylex): ternary ? can be followed by newline.
matz authored
444 member = rb_struct_iv_get(rb_obj_class(s), "__member__");
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
445 if (NIL_P(member)) {
446 rb_bug("non-initialized struct");
447 }
448
449 len = RARRAY(member)->len;
450 for (i=0; i<len; i++) {
7194267 2000-04-10
matz authored
451 if (SYM2ID(RARRAY(member)->ptr[i]) == id) {
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
452 return RSTRUCT(s)->ptr[i];
453 }
454 }
ffe1cf5 * error.c (exc_exception): clone the receiver exception instead of
matz authored
455 rb_name_error(id, "no member '%s' in struct", rb_id2name(id));
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
456 return Qnil; /* not reached */
457 }
458
3db12e8 Initial revision
matz authored
459 VALUE
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
460 rb_struct_aref(s, idx)
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
461 VALUE s, idx;
3db12e8 Initial revision
matz authored
462 {
65a5162 1.4.0
matz authored
463 long i;
3db12e8 Initial revision
matz authored
464
31c5530 2000-03-13
matz authored
465 if (TYPE(idx) == T_STRING || TYPE(idx) == T_SYMBOL) {
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
466 return rb_struct_aref_id(s, rb_to_id(idx));
467 }
468
65a5162 1.4.0
matz authored
469 i = NUM2LONG(idx);
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
470 if (i < 0) i = RSTRUCT(s)->len + i;
3db12e8 Initial revision
matz authored
471 if (i < 0)
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
472 rb_raise(rb_eIndexError, "offset %d too small for struct(size:%d)",
473 i, RSTRUCT(s)->len);
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
474 if (RSTRUCT(s)->len <= i)
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
475 rb_raise(rb_eIndexError, "offset %d too large for struct(size:%d)",
476 i, RSTRUCT(s)->len);
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
477 return RSTRUCT(s)->ptr[i];
3db12e8 Initial revision
matz authored
478 }
479
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
480 static VALUE
481 rb_struct_aset_id(s, id, val)
482 VALUE s, val;
483 ID id;
484 {
485 VALUE member;
65a5162 1.4.0
matz authored
486 long i, len;
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
487
b47a994 * parse.y (yylex): ternary ? can be followed by newline.
matz authored
488 member = rb_struct_iv_get(rb_obj_class(s), "__member__");
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
489 if (NIL_P(member)) {
490 rb_bug("non-initialized struct");
491 }
492
14cd947 * struct.c (rb_struct_modify): should check frozen and taint
matz authored
493 rb_struct_modify(s);
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
494 len = RARRAY(member)->len;
495 for (i=0; i<len; i++) {
7194267 2000-04-10
matz authored
496 if (SYM2ID(RARRAY(member)->ptr[i]) == id) {
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
497 RSTRUCT(s)->ptr[i] = val;
498 return val;
499 }
500 }
ffe1cf5 * error.c (exc_exception): clone the receiver exception instead of
matz authored
501 rb_name_error(id, "no member '%s' in struct", rb_id2name(id));
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
502 }
503
3db12e8 Initial revision
matz authored
504 VALUE
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
505 rb_struct_aset(s, idx, val)
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
506 VALUE s, idx, val;
3db12e8 Initial revision
matz authored
507 {
65a5162 1.4.0
matz authored
508 long i;
3db12e8 Initial revision
matz authored
509
31c5530 2000-03-13
matz authored
510 if (TYPE(idx) == T_STRING || TYPE(idx) == T_SYMBOL) {
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
511 return rb_struct_aset_id(s, rb_to_id(idx), val);
512 }
513
65a5162 1.4.0
matz authored
514 i = NUM2LONG(idx);
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
515 if (i < 0) i = RSTRUCT(s)->len + i;
abc49e4 2000-06-14
matz authored
516 if (i < 0) {
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
517 rb_raise(rb_eIndexError, "offset %d too small for struct(size:%d)",
518 i, RSTRUCT(s)->len);
abc49e4 2000-06-14
matz authored
519 }
520 if (RSTRUCT(s)->len <= i) {
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
521 rb_raise(rb_eIndexError, "offset %d too large for struct(size:%d)",
522 i, RSTRUCT(s)->len);
abc49e4 2000-06-14
matz authored
523 }
14cd947 * struct.c (rb_struct_modify): should check frozen and taint
matz authored
524 rb_struct_modify(s);
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
525 return RSTRUCT(s)->ptr[i] = val;
3db12e8 Initial revision
matz authored
526 }
527
a59c599 * string.c (rb_str_match_m): should convert an argument into
matz authored
528
529 static VALUE
530 rb_struct_select(argc, argv, s)
531 int argc;
532 VALUE *argv;
533 VALUE s;
534 {
535 VALUE result = rb_ary_new();
536 long i;
537
538 if (rb_block_given_p()) {
539 if (argc > 0) {
540 rb_raise(rb_eArgError, "wrong number arguments(%d for 0)", argc);
541 }
542 for (i = 0; i < RSTRUCT(s)->len; i++) {
543 if (RTEST(rb_yield(RARRAY(s)->ptr[i]))) {
544 rb_ary_push(result, RSTRUCT(s)->ptr[i]);
545 }
546 }
547 }
548 else {
549 for (i=0; i<argc; i++) {
550 rb_ary_push(result, rb_struct_aref(s, argv[i]));
551 }
552 }
553 return result;
554 }
555
3db12e8 Initial revision
matz authored
556 static VALUE
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
557 rb_struct_equal(s, s2)
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
558 VALUE s, s2;
3db12e8 Initial revision
matz authored
559 {
65a5162 1.4.0
matz authored
560 long i;
3db12e8 Initial revision
matz authored
561
b47a994 * parse.y (yylex): ternary ? can be followed by newline.
matz authored
562 if (s == s2) return Qtrue;
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
563 if (TYPE(s2) != T_STRUCT) return Qfalse;
c786866 * range.c (range_step): 'iter' here should be an array.
matz authored
564 if (rb_obj_class(s) != rb_obj_class(s2)) return Qfalse;
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
565 if (RSTRUCT(s)->len != RSTRUCT(s2)->len) {
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
566 rb_bug("inconsistent struct"); /* should never happen */
3db12e8 Initial revision
matz authored
567 }
568
7ea2ced This commit was generated by cvs2svn to compensate for changes in r11,
matz authored
569 for (i=0; i<RSTRUCT(s)->len; i++) {
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
570 if (!rb_equal(RSTRUCT(s)->ptr[i], RSTRUCT(s2)->ptr[i])) return Qfalse;
3db12e8 Initial revision
matz authored
571 }
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
572 return Qtrue;
3db12e8 Initial revision
matz authored
573 }
574
575 static VALUE
c18d374 991207
matz authored
576 rb_struct_size(s)
577 VALUE s;
578 {
579 return INT2FIX(RSTRUCT(s)->len);
580 }
581
3db12e8 Initial revision
matz authored
582 void
583 Init_Struct()
584 {
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
585 rb_cStruct = rb_define_class("Struct", rb_cObject);
586 rb_include_module(rb_cStruct, rb_mEnumerable);
3db12e8 Initial revision
matz authored
587
aac5ff0 * struct.c (Init_Struct): should undefine "allocate" for Struct
matz authored
588 rb_undef_method(CLASS_OF(rb_cStruct), "allocate");
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
589 rb_define_singleton_method(rb_cStruct, "new", rb_struct_s_def, -1);
3db12e8 Initial revision
matz authored
590
65a5162 1.4.0
matz authored
591 rb_define_method(rb_cStruct, "initialize", rb_struct_initialize, -2);
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
592 rb_define_method(rb_cStruct, "clone", rb_struct_clone, 0);
3db12e8 Initial revision
matz authored
593
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
594 rb_define_method(rb_cStruct, "==", rb_struct_equal, 1);
3db12e8 Initial revision
matz authored
595
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
596 rb_define_method(rb_cStruct, "to_s", rb_struct_to_s, 0);
597 rb_define_method(rb_cStruct, "inspect", rb_struct_inspect, 0);
598 rb_define_method(rb_cStruct, "to_a", rb_struct_to_a, 0);
599 rb_define_method(rb_cStruct, "values", rb_struct_to_a, 0);
c18d374 991207
matz authored
600 rb_define_method(rb_cStruct, "size", rb_struct_size, 0);
601 rb_define_method(rb_cStruct, "length", rb_struct_size, 0);
3db12e8 Initial revision
matz authored
602
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
603 rb_define_method(rb_cStruct, "each", rb_struct_each, 0);
19c42c0 * variable.c (rb_obj_remove_instance_variable): raise NameError if
matz authored
604 rb_define_method(rb_cStruct, "each_pair", rb_struct_each_pair, 0);
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
605 rb_define_method(rb_cStruct, "[]", rb_struct_aref, 1);
606 rb_define_method(rb_cStruct, "[]=", rb_struct_aset, 2);
a59c599 * string.c (rb_str_match_m): should convert an argument into
matz authored
607 rb_define_method(rb_cStruct, "select", rb_struct_select, -1);
3db12e8 Initial revision
matz authored
608
210367e This commit was generated by cvs2svn to compensate for changes in r372,
matz authored
609 rb_define_method(rb_cStruct, "members", rb_struct_members, 0);
3db12e8 Initial revision
matz authored
610 }
Something went wrong with that request. Please try again.