accessibility_core 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
data/History.markdown CHANGED
@@ -1,3 +1,9 @@
1
+ # 0.4.1 - Polish
2
+
3
+ * Plug various memory leaks in `core.c`
4
+ * Improved error messages for `accessibility/core` on MRI
5
+
6
+
1
7
  # 0.4.0 - Fill in the gaps and other dubious requirements
2
8
 
3
9
  * Add `Object#load_plist` to match MacRuby's `Object#load_plist`
@@ -53,15 +53,16 @@ extern ID sel_parse;
53
53
  } while (false);
54
54
 
55
55
  #define WRAP_ARRAY(wrapper) do { \
56
+ CFTypeRef obj = NULL; \
56
57
  CFIndex length = CFArrayGetCount(array); \
57
58
  VALUE ary = rb_ary_new2(length); \
58
- \
59
- for (CFIndex idx = 0; idx < length; idx++) \
60
- rb_ary_store( \
61
- ary, \
62
- idx, \
63
- wrapper(CFArrayGetValueAtIndex(array, idx)) \
64
- ); \
59
+ \
60
+ for (CFIndex idx = 0; idx < length; idx++) { \
61
+ obj = CFArrayGetValueAtIndex(array, idx); \
62
+ CFRetain(obj); \
63
+ rb_ary_store(ary, idx, wrapper(obj)); \
64
+ } \
65
+ \
65
66
  return ary; \
66
67
  } while (false);
67
68
 
@@ -25,20 +25,124 @@ static
25
25
  VALUE
26
26
  handle_error(VALUE self, AXError code)
27
27
  {
28
- // TODO port the error handler from AXElements
29
- switch (code)
30
- {
31
- case kAXErrorInvalidUIElement:
32
- rb_raise(rb_eArgError, "invalid element (probably dead)");
33
- case kAXErrorAttributeUnsupported:
34
- rb_raise(rb_eArgError, "attribute unsupported");
35
- case kAXErrorActionUnsupported:
36
- rb_raise(rb_eArgError, "action unsupported");
37
- case kAXErrorParameterizedAttributeUnsupported:
38
- rb_raise(rb_eArgError, "parameterized attribute unsupported");
39
- default:
40
- rb_raise(rb_eRuntimeError, "you done goofed [%d]", code);
41
- }
28
+ @autoreleasepool {
29
+ NSString* description = (NSString*)CFCopyDescription(unwrap_ref(self));
30
+ [description autorelease];
31
+
32
+ const char* inspected_self = CFStringGetCStringPtr(
33
+ (CFStringRef)description,
34
+ kCFStringEncodingUTF8
35
+ );
36
+
37
+ switch (code)
38
+ {
39
+ case kAXErrorSuccess:
40
+ rb_raise(
41
+ rb_eRuntimeError,
42
+ "internal accessibility_core error"
43
+ );
44
+ case kAXErrorFailure:
45
+ rb_raise(
46
+ rb_eRuntimeError,
47
+ "An accessibility system failure, possibly an allocation " \
48
+ "failure, occurred with %s; stopping to be safe",
49
+ inspected_self
50
+ );
51
+ case kAXErrorIllegalArgument:
52
+ rb_raise(
53
+ rb_eArgError,
54
+ "illegal argument was passed to the method for %s",
55
+ inspected_self
56
+ );
57
+ case kAXErrorInvalidUIElement:
58
+ rb_raise(
59
+ rb_eArgError,
60
+ "invalid element `%s' (probably dead)",
61
+ inspected_self
62
+ );
63
+ case kAXErrorInvalidUIElementObserver:
64
+ rb_raise(
65
+ rb_eArgError,
66
+ "invalid observer passed to the method for %s",
67
+ inspected_self
68
+ );
69
+ case kAXErrorCannotComplete:
70
+ spin(0);
71
+ pid_t pid = 0;
72
+ AXUIElementGetPid(unwrap_ref(self), &pid);
73
+ NSRunningApplication* app = [NSRunningApplication runningApplicationWithProcessIdentifier:pid];
74
+ if (app)
75
+ rb_raise(
76
+ rb_eRuntimeError,
77
+ "accessibility messaging failure. " \
78
+ "Perhaps the application is busy on unresponsive?"
79
+ );
80
+ else
81
+ rb_raise(
82
+ rb_eRuntimeError,
83
+ "application for pid=%d is no longer running. " \
84
+ "Maybe it crashed?",
85
+ pid
86
+ );
87
+ case kAXErrorAttributeUnsupported:
88
+ rb_raise(
89
+ rb_eArgError,
90
+ "attribute unsupported"
91
+ );
92
+ case kAXErrorActionUnsupported:
93
+ rb_raise(
94
+ rb_eArgError,
95
+ "action unsupported"
96
+ );
97
+ case kAXErrorNotificationUnsupported:
98
+ rb_raise(
99
+ rb_eArgError,
100
+ "notification unsupported"
101
+ );
102
+ case kAXErrorNotImplemented:
103
+ rb_raise(
104
+ rb_eNotImpError,
105
+ "method not supported by the receiver"
106
+ );
107
+ case kAXErrorNotificationAlreadyRegistered:
108
+ rb_raise(
109
+ rb_eArgError,
110
+ "notification has already been registered"
111
+ );
112
+ case kAXErrorNotificationNotRegistered:
113
+ rb_raise(
114
+ rb_eRuntimeError,
115
+ "notification is not registered yet"
116
+ );
117
+ case kAXErrorAPIDisabled:
118
+ rb_raise(
119
+ rb_eRuntimeError,
120
+ "AXAPI has been disabled"
121
+ );
122
+ case kAXErrorNoValue:
123
+ rb_raise(
124
+ rb_eRuntimeError,
125
+ "accessibility_core internal error; " \
126
+ "should be handled internally"
127
+ );
128
+ case kAXErrorParameterizedAttributeUnsupported:
129
+ rb_raise(
130
+ rb_eArgError,
131
+ "parameterized attribute unsupported"
132
+ );
133
+ case kAXErrorNotEnoughPrecision:
134
+ rb_raise(
135
+ rb_eRuntimeError,
136
+ "AXAPI said there was not enough precision ¯\\(°_o)/¯"
137
+ );
138
+ default:
139
+ rb_raise(
140
+ rb_eRuntimeError,
141
+ "accessibility_core majorly goofed [%d]",
142
+ code
143
+ );
144
+ }
145
+ }
42
146
 
43
147
  return Qnil;
44
148
  }
@@ -50,7 +154,7 @@ rb_acore_application_for(VALUE self, VALUE pid)
50
154
  {
51
155
  NSDate* date = [NSDate date];
52
156
  [[NSRunLoop currentRunLoop] runUntilDate:date];
53
- CFRelease(date);
157
+ [date release];
54
158
 
55
159
  pid_t the_pid = NUM2PIDT(pid);
56
160
  NSRunningApplication* running_app =
@@ -58,8 +162,8 @@ rb_acore_application_for(VALUE self, VALUE pid)
58
162
 
59
163
  if (running_app) {
60
164
  VALUE app = wrap_ref(AXUIElementCreateApplication(the_pid));
61
- CFRelease(running_app);
62
- return app;
165
+ [running_app release];
166
+ return app;
63
167
  }
64
168
 
65
169
  rb_raise(
@@ -161,6 +265,7 @@ static
161
265
  VALUE
162
266
  rb_acore_attribute(VALUE self, VALUE name)
163
267
  {
268
+ VALUE obj;
164
269
  CFTypeRef attr = NULL;
165
270
  CFStringRef attr_name = unwrap_string(name);
166
271
  AXError code = AXUIElementCopyAttributeValue(
@@ -172,7 +277,10 @@ rb_acore_attribute(VALUE self, VALUE name)
172
277
  switch (code)
173
278
  {
174
279
  case kAXErrorSuccess:
175
- return to_ruby(attr);
280
+ obj = to_ruby(attr);
281
+ if (TYPE(obj) != T_DATA)
282
+ CFRelease(attr);
283
+ return obj;
176
284
  case kAXErrorFailure:
177
285
  case kAXErrorNoValue:
178
286
  case kAXErrorInvalidUIElement:
@@ -247,6 +355,7 @@ rb_acore_set(VALUE self, VALUE name, VALUE value)
247
355
  attr_name,
248
356
  ax_value
249
357
  );
358
+ CFRelease(ax_value);
250
359
  switch (code)
251
360
  {
252
361
  case kAXErrorSuccess:
@@ -261,6 +370,7 @@ static
261
370
  VALUE
262
371
  rb_acore_role(VALUE self)
263
372
  {
373
+ VALUE obj;
264
374
  CFTypeRef value = NULL;
265
375
  AXError code = AXUIElementCopyAttributeValue(
266
376
  unwrap_ref(self),
@@ -270,7 +380,9 @@ rb_acore_role(VALUE self)
270
380
  switch (code)
271
381
  {
272
382
  case kAXErrorSuccess:
273
- return wrap_string(value);
383
+ obj = wrap_string(value);
384
+ CFRelease(value);
385
+ return obj;
274
386
  case kAXErrorNoValue:
275
387
  case kAXErrorInvalidUIElement:
276
388
  return Qnil;
@@ -284,6 +396,7 @@ static
284
396
  VALUE
285
397
  rb_acore_subrole(VALUE self)
286
398
  {
399
+ VALUE obj;
287
400
  CFTypeRef value = NULL;
288
401
  AXError code = AXUIElementCopyAttributeValue(
289
402
  unwrap_ref(self),
@@ -293,7 +406,12 @@ rb_acore_subrole(VALUE self)
293
406
  switch (code)
294
407
  {
295
408
  case kAXErrorSuccess:
296
- return wrap_string((CFStringRef)value);
409
+ if (value) {
410
+ obj = wrap_string(value);
411
+ CFRelease(value);
412
+ return obj;
413
+ }
414
+ return Qnil;
297
415
  case kAXErrorFailure:
298
416
  case kAXErrorNoValue:
299
417
  case kAXErrorInvalidUIElement:
@@ -334,6 +452,7 @@ static
334
452
  VALUE
335
453
  rb_acore_children(VALUE self)
336
454
  {
455
+ VALUE obj;
337
456
  CFTypeRef value = NULL;
338
457
  AXError code = AXUIElementCopyAttributeValue(
339
458
  unwrap_ref(self),
@@ -343,7 +462,9 @@ rb_acore_children(VALUE self)
343
462
  switch (code)
344
463
  {
345
464
  case kAXErrorSuccess:
346
- return wrap_array_refs(value);
465
+ obj = wrap_array_refs(value);
466
+ CFRelease(value);
467
+ return obj;
347
468
  case kAXErrorFailure:
348
469
  case kAXErrorNoValue:
349
470
  case kAXErrorInvalidUIElement:
@@ -358,6 +479,7 @@ static
358
479
  VALUE
359
480
  rb_acore_value(VALUE self)
360
481
  {
482
+ VALUE obj;
361
483
  CFTypeRef value = NULL;
362
484
  AXError code = AXUIElementCopyAttributeValue(
363
485
  unwrap_ref(self),
@@ -367,7 +489,10 @@ rb_acore_value(VALUE self)
367
489
  switch (code)
368
490
  {
369
491
  case kAXErrorSuccess:
370
- return to_ruby(value);
492
+ obj = to_ruby(value);
493
+ if (TYPE(obj) != T_DATA)
494
+ CFRelease(value);
495
+ return obj;
371
496
  default:
372
497
  return handle_error(self, code);
373
498
  }
@@ -436,6 +561,7 @@ static
436
561
  VALUE
437
562
  rb_acore_parameterized_attribute(VALUE self, VALUE name, VALUE parameter)
438
563
  {
564
+ VALUE obj;
439
565
  CFTypeRef param = to_ax(parameter);
440
566
  CFTypeRef attr = NULL;
441
567
  CFStringRef attr_name = unwrap_string(name);
@@ -450,7 +576,10 @@ rb_acore_parameterized_attribute(VALUE self, VALUE name, VALUE parameter)
450
576
  switch (code)
451
577
  {
452
578
  case kAXErrorSuccess:
453
- return to_ruby(attr);
579
+ obj = to_ruby(attr);
580
+ if (TYPE(obj) != T_DATA)
581
+ CFRelease(attr);
582
+ return obj;
454
583
  case kAXErrorNoValue:
455
584
  case kAXErrorInvalidUIElement:
456
585
  return Qnil;
@@ -740,7 +740,7 @@ module Accessibility::Element
740
740
  KAXErrorInvalidUIElementObserver => [
741
741
  ArgumentError,
742
742
  lambda { |*args|
743
- 'AXElements no longer supports notifications'
743
+ "Invalid observer passed to the method for #{args[0].inspect}"
744
744
  }
745
745
  ],
746
746
  KAXErrorCannotComplete => [
@@ -771,7 +771,7 @@ module Accessibility::Element
771
771
  KAXErrorNotificationUnsupported => [
772
772
  ArgumentError,
773
773
  lambda { |*args|
774
- 'AXElements no longer supports notifications'
774
+ 'Notification Unsupported'
775
775
  }
776
776
  ],
777
777
  KAXErrorNotImplemented => [
@@ -6,6 +6,6 @@ module Accessibility
6
6
  # Namespace for `accessibility_core` specific classes
7
7
  module Core
8
8
  # return [String]
9
- VERSION = '0.4.0'
9
+ VERSION = '0.4.1'
10
10
  end
11
11
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: accessibility_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-02 00:00:00.000000000 Z
12
+ date: 2013-01-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: yard
@@ -107,7 +107,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
107
107
  version: '0'
108
108
  segments:
109
109
  - 0
110
- hash: -989078667386493475
110
+ hash: 2206731083333154082
111
111
  required_rubygems_version: !ruby/object:Gem::Requirement
112
112
  none: false
113
113
  requirements:
@@ -116,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
116
  version: '0'
117
117
  segments:
118
118
  - 0
119
- hash: -989078667386493475
119
+ hash: 2206731083333154082
120
120
  requirements: []
121
121
  rubyforge_project:
122
122
  rubygems_version: 1.8.24