[macruby-changes] [485] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Tue Aug 26 13:17:31 PDT 2008


Revision: 485
          http://trac.macosforge.org/projects/ruby/changeset/485
Author:   lsansonetti at apple.com
Date:     2008-08-26 13:17:30 -0700 (Tue, 26 Aug 2008)
Log Message:
-----------
introduce bs_parser_t so that we never parse the same file twice

Modified Paths:
--------------
    MacRuby/trunk/bs.c
    MacRuby/trunk/bs.h
    MacRuby/trunk/objc.m

Modified: MacRuby/trunk/bs.c
===================================================================
--- MacRuby/trunk/bs.c	2008-08-26 03:23:42 UTC (rev 484)
+++ MacRuby/trunk/bs.c	2008-08-26 20:17:30 UTC (rev 485)
@@ -358,11 +358,34 @@
   return false;
 }
 
-static bool 
-_bs_parse(const char *path, char **loaded_paths, 
-          bs_parse_options_t options, bs_parse_callback_t callback, 
-          void *context, char **error)
+struct _bs_parser {
+  CFMutableArrayRef loaded_paths; 
+};
+
+bs_parser_t *
+bs_parser_new(void)
 {
+  struct _bs_parser *parser;
+
+  parser = (struct _bs_parser *)malloc(sizeof(struct _bs_parser));
+  parser->loaded_paths = 
+    CFArrayCreateMutable(kCFAllocatorMalloc, 0, &kCFTypeArrayCallBacks);
+
+  return parser;
+}
+
+void
+bs_parser_free(bs_parser_t *parser)
+{
+  CFRelease(parser->loaded_paths);
+  free(parser);
+}
+
+bool 
+bs_parser_parse(bs_parser_t *parser, const char *path, 
+		bs_parse_options_t options, bs_parse_callback_t callback, 
+		void *context, char **error)
+{
   xmlTextReaderPtr reader;
   bs_element_function_t *func;
   bs_element_class_t *klass;
@@ -374,22 +397,19 @@
   int func_ptr_arg_depth;
   bs_element_function_pointer_t *func_ptr;
   bool success;
+  CFStringRef cf_path;
 
   if (callback == NULL)
     return false;
 
-  for (i = 0; i < PATH_MAX; i++) {
-    char *p = loaded_paths[i];
-    if (p == NULL) {
-      loaded_paths[i] = strdup(path);
-      break;
-    }
-    else if (strcmp(p, path) == 0) {
-      /* already loaded */
-      return true;
-    }
-  }  
-  
+  cf_path = CFStringCreateWithFileSystemRepresentation(kCFAllocatorMalloc, 
+    path);
+  if (CFArrayContainsValue(parser->loaded_paths, CFRangeMake(0, CFArrayGetCount(parser->loaded_paths)), cf_path)) {
+    /* already loaded */
+    CFRelease(cf_path);
+    return true;
+  }
+
   //printf("parsing %s\n", path);
 
 #define BAIL(fmt, args...)                      \
@@ -483,8 +503,8 @@
                                        sizeof bs_path);
           free(depends_on_path);
           if (bs_path_found) {
-            if (!_bs_parse(bs_path, loaded_paths, options, callback, context, 
-                           error))
+            if (!bs_parser_parse(parser, bs_path, options, callback, context, 
+                                 error))
               return false;
           }
           break;
@@ -1087,7 +1107,7 @@
     }
 
     if (bs_element != NULL)
-      (*callback)(path, bs_element_type, bs_element, context);
+      (*callback)(parser, path, bs_element_type, bs_element, context);
   }
   
   success = true;
@@ -1098,6 +1118,11 @@
 
   xmlFreeTextReader(reader);
 
+  if (success) {
+    CFArrayAppendValue(parser->loaded_paths, cf_path);
+  }
+  CFRelease(cf_path);
+
   if (success && options == BS_PARSE_OPTIONS_LOAD_DYLIBS) {
     char *p, buf[PATH_MAX];
     strncpy(buf, path, sizeof buf);
@@ -1115,26 +1140,6 @@
   return success;
 }
 
-bool 
-bs_parse(const char *path, bs_parse_options_t options, 
-         bs_parse_callback_t callback, void *context, char **error)
-{
-  char **loaded_paths;
-  bool status;
-  unsigned i;
-  
-  loaded_paths = (char **)alloca(sizeof(char *) * PATH_MAX);
-  ASSERT_ALLOC(loaded_paths);
-  memset(loaded_paths, 0, PATH_MAX);
-  
-  status = _bs_parse(path, loaded_paths, options, callback, context, error);
-
-  for (i = 0; i < PATH_MAX && loaded_paths[i] != NULL; i++)
-    free(loaded_paths[i]);
-
-  return status;
-}
-
 #define SAFE_FREE(x) do { if ((x) != NULL) free(x); } while (0)
 
 static void bs_free_retval(bs_element_retval_t *bs_retval);
@@ -1295,55 +1300,3 @@
   }
   free(value);
 }
-
-#if 0
-struct bs_register_entry {
-  bs_parse_callback_t *callback;
-  void *context;
-};
-
-static struct bs_register_entry **bs_register_entries = NULL;
-static unsigned bs_register_entries_count = 0;
-static bs_register_token_t tokens = 0;
-
-bs_register_token_t 
-bs_register(bs_parse_callback_t *callback, void *context)
-{
-  struct bs_register_entry *entry;
-
-  entry = (struct bs_register_entry *)malloc(sizeof(struct bs_register_entry));
-  ASSERT_ALLOC(entry);
-  
-  entry->callback = callback;
-  entry->context = context;
-
-  if (bs_register_entries == NULL) {
-    assert(bs_register_entries_count == 0);
-    bs_register_entries = (struct bs_register_entry **)
-      malloc(sizeof(struct bs_register_entry *));
-  }
-  else {
-    assert(bs_register_entries_count > 0);
-    
-  }
-}
-#endif
-
-bs_register_token_t 
-bs_register(bs_parse_callback_t *callback, void *context)
-{
-  /* TODO */
-  return 1;
-}
-
-void 
-bs_unregister(bs_register_token_t token)
-{
-  /* TODO */
-}
-
-void 
-bs_notify(bs_element_type_t type, void *value)
-{
-  /* TODO */
-}

Modified: MacRuby/trunk/bs.h
===================================================================
--- MacRuby/trunk/bs.h	2008-08-26 03:23:42 UTC (rev 484)
+++ MacRuby/trunk/bs.h	2008-08-26 20:17:30 UTC (rev 485)
@@ -198,8 +198,23 @@
  */
 bool bs_find_path(const char *framework_path, char *path, const size_t path_len);
 
+/* bs_parser_new()
+ * 
+ * Creates and returns a parser object, required for bs_parser_parse().
+ * Use bs_parser_free() when you're done.
+ */
+typedef struct _bs_parser bs_parser_t;
+bs_parser_t *bs_parser_new(void);
+
+/* bs_parser_free()
+ *
+ * Frees a previously-created parser object.
+ */
+void bs_parser_free(bs_parser_t *parser);
+
 typedef void (*bs_parse_callback_t)
-  (const char *path, bs_element_type_t type, void *value, void *context);
+  (bs_parser_t *parser, const char *path, bs_element_type_t type, void *value, 
+   void *context);
 
 typedef enum {
   /* Default option: parse bridge support files. */
@@ -215,6 +230,7 @@
  * to the callback function, using bs_element_free().
  * Returns true on success, otherwise false.
  *
+ * parser: the parser object.
  * path: the full path of the bridge support file to parse.
  * options: parsing options.
  * callback: a callback function pointer.
@@ -224,8 +240,9 @@
  * allocated error message. You are responsible to free it. Pass NULL if you 
  * don't need it.  
  */
-bool bs_parse(const char *path, bs_parse_options_t options, 
-  bs_parse_callback_t callback, void *context, char **error);
+bool bs_parser_parse(bs_parser_t *parser, const char *path, 
+  bs_parse_options_t options, bs_parse_callback_t callback, void *context, 
+  char **error);
 
 /* bs_element_free()
  *
@@ -237,42 +254,4 @@
  */
 void bs_element_free(bs_element_type_t type, void *value);
 
-typedef unsigned bs_register_token_t;
-
-/* bs_register()
- *
- * Registers an asynchronous callback that will be called by bs_notify(). 
- * This function is meant to be called by scripting language bridges, to 
- * register themselves for future notifications by frameworks that dynamically
- * generate APIs. You are responsible to free every element passed to the 
- * callback function, using bs_element_free(). 
- * Returns a token identifier that can be passed to bs_unregister() to 
- * unregister the callback.
- *
- * callback: a callback function pointer.
- * context: a contextual data pointer that will be passed to the callback 
- * function.
-*/
-bs_register_token_t bs_register(bs_parse_callback_t *callback, void *context);
-
-/* bs_unregister()
- *
- * Unregisters a previously-registered callback.
- *
- * token: a token that was returned by bs_register().
- */
-void bs_unregister(bs_register_token_t token);
-
-/* bs_notify()
- *
- * Notifies all clients registered through bs_register() that a new bridge 
- * support element is available. This function is meant to be called by 
- * frameworks that generate APIs at runtime. 
- *
- * type: the type of the bridge support element.
- * value: a pointer to the bridge support element. The element should be 
- * entierely composed of memory allocated by malloc(3).
- */
-void bs_notify(bs_element_type_t type, void *value);
-
 #endif /* __BS_H_ */

Modified: MacRuby/trunk/objc.m
===================================================================
--- MacRuby/trunk/objc.m	2008-08-26 03:23:42 UTC (rev 484)
+++ MacRuby/trunk/objc.m	2008-08-26 20:17:30 UTC (rev 485)
@@ -2169,16 +2169,12 @@
 }
 
 static void
-bs_parse_cb(const char *path, bs_element_type_t type, void *value, void *ctx)
+bs_parse_cb(bs_parser_t *parser, const char *path, bs_element_type_t type, 
+            void *value, void *ctx)
 {
     bool do_not_free = false;
-    static CFMutableDictionaryRef rb_cObject_dict = NULL;
+    CFMutableDictionaryRef rb_cObject_dict = (CFMutableDictionaryRef)ctx;
 
-    if (rb_cObject_dict == NULL) {
-	rb_cObject_dict = rb_class_ivar_dict(rb_cObject);
-	assert(rb_cObject_dict != NULL);
-    }
-
     switch (type) {
 	case BS_ELEMENT_ENUM:
 	{
@@ -2359,27 +2355,47 @@
 	bs_element_free(type, value);
 }
 
-static VALUE
-rb_objc_load_bs(VALUE recv, VALUE path)
+extern VALUE enable_method_added;
+
+static bs_parser_t *bs_parser = NULL;
+
+static void
+rb_objc_load_bridge_support(const char *path, int options)
 {
     char *error;
+    bool ok;
+    CFMutableDictionaryRef rb_cObject_dict;  
 
-    if (!bs_parse(StringValuePtr(path), 0, bs_parse_cb, NULL, &error))
+    if (bs_parser == NULL) {
+	bs_parser = bs_parser_new();
+    }
+
+    rb_cObject_dict = rb_class_ivar_dict(rb_cObject);
+    assert(rb_cObject_dict != NULL);
+
+    enable_method_added = Qfalse;
+    ok = bs_parser_parse(bs_parser, path, options,
+			 bs_parse_cb, rb_cObject_dict, &error);
+    enable_method_added = Qtrue;
+    if (!ok) {
 	rb_raise(rb_eRuntimeError, error);
+    }
+}
 
+static VALUE
+rb_objc_load_bs(VALUE recv, VALUE path)
+{
+    rb_objc_load_bridge_support(StringValuePtr(path), 0);
     return recv;
 }
 
 static void
-load_bridge_support(const char *framework_path)
+rb_objc_search_and_load_bridge_support(const char *framework_path)
 {
     char path[PATH_MAX];
-    char *error;
 
     if (bs_find_path(framework_path, path, sizeof path)) {
-	if (!bs_parse(path, BS_PARSE_OPTIONS_LOAD_DYLIBS, bs_parse_cb, NULL, 
-		      &error))
-	    rb_raise(rb_eRuntimeError, error);
+	rb_objc_load_bridge_support(path, BS_PARSE_OPTIONS_LOAD_DYLIBS);
     }
 }
 
@@ -2505,7 +2521,7 @@
 		 [[error description] UTF8String]); 
     }
 
-    load_bridge_support(cstr);
+    rb_objc_search_and_load_bridge_support(cstr);
     reload_class_constants();
 
     return Qtrue;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macruby-changes/attachments/20080826/576db8cc/attachment-0001.html 


More information about the macruby-changes mailing list