accessibility_core 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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