changeset 9585:06b8b51dca48

also handle user-defined graphics properties in new property name validation scheme
author John W. Eaton <jwe@octave.org>
date Fri, 28 Aug 2009 18:37:31 -0400
parents 0fcbfddaa87f
children 1393896df3b3
files src/ChangeLog src/genprops.awk src/graphics.cc src/graphics.h.in
diffstat 4 files changed, 90 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Fri Aug 28 05:30:29 2009 -0400
+++ b/src/ChangeLog	Fri Aug 28 18:37:31 2009 -0400
@@ -1,3 +1,18 @@
+2009-08-28  John W. Eaton  <jwe@octave.org>
+
+	* genprops.awk: Generate static member functions has_core_property
+	and core_property_names.  Make has_property and all_property_names
+	non-static const member functions.  Pass object type to
+	validate_property_name.
+	* graphics.cc (validate_property_name): New arg, WHAT.
+	Improve warning and error messages.
+	(property_list::set): Use has_core_property instead of has_property.
+	(base_properties::has_property): Delete definition.
+	(base_graphics_object::remove_all_listeners): Move unwind protect
+	block here, from old base_properties::has_property function.
+	* graphics.h.in (base_properties::has_property): Now virtual.
+	Unconditionally call panic_impossible.
+
 2009-08-28  John W. Eaton  <jwe@octave.org>
 
 	* graphics.cc (validate_property_name): Return full name of
--- a/src/genprops.awk	Fri Aug 28 05:30:29 2009 -0400
+++ b/src/genprops.awk	Fri Aug 28 18:37:31 2009 -0400
@@ -257,11 +257,15 @@
   if (class_name && ! base)
     emit_common_declarations();
 
-  printf ("public:\n\n");
+  printf ("public:\n\n\n  static std::set<std::string> core_property_names (void);\n\n  static bool has_core_property (const caseless_str& pname);\n\n  std::set<std::string> all_property_names (");
   if (base)
-    printf ("\n  static std::set<std::string> all_property_names (const std::string& cname);\n\n  static bool has_property (const std::string& pname, const std::string& cname);\n\n");
+    printf ("const std::string& cname");
   else
-    printf ("\n  static std::set<std::string> all_property_names (void);\n\n  static bool has_property (const std::string& pname);\n\n");
+    printf ("void");
+  printf (") const;\n\n");
+
+  if (! base)
+    printf ("  bool has_property (const caseless_str& pname) const;\n\n");
 
   if (idx > 0)
     print (base ? "protected:\n" : "private:\n");
@@ -434,7 +438,7 @@
               class_name) >> filename;
 
     if (! base)
-      printf ("  const std::set<std::string>& pnames = all_property_names ();\n\n  caseless_str pname = validate_property_name (\"get\", pnames, pname_arg);\n\n  if (error_state)\n    return;\n\n") >> filename;
+      printf ("  const std::set<std::string>& pnames = all_property_names ();\n\n  caseless_str pname = validate_property_name (\"get\", go_name, pnames, pname_arg);\n\n  if (error_state)\n    return;\n\n") >> filename;
 
     first = 1;
 
@@ -488,7 +492,7 @@
     printf ("  octave_value retval;\n\n") >> filename;
 
     if (! base)
-      printf ("  const std::set<std::string>& pnames = all_property_names ();\n\n  caseless_str pname = validate_property_name (\"get\", pnames, pname_arg);\n\n  if (error_state)\n    return retval;\n\n") >> filename;
+      printf ("  const std::set<std::string>& pnames = all_property_names ();\n\n  caseless_str pname = validate_property_name (\"get\", go_name, pnames, pname_arg);\n\n  if (error_state)\n    return retval;\n\n") >> filename;
 
     for (i = 1; i<= idx; i++)
     {
@@ -513,7 +517,7 @@
               class_name) >> filename;
 
     if (! base)
-      printf ("  const std::set<std::string>& pnames = all_property_names ();\n\n  caseless_str pname = validate_property_name (\"get\", pnames, pname_arg);\n\n  if (error_state)\n    return property ();\n\n") >> filename;
+      printf ("  const std::set<std::string>& pnames = all_property_names ();\n\n  caseless_str pname = validate_property_name (\"get\", go_name, pnames, pname_arg);\n\n  if (error_state)\n    return property ();\n\n") >> filename;
 
     for (i = 1; i<= idx; i++)
     {
@@ -575,25 +579,43 @@
       printf ("std::string %s::properties::go_name (\"%s\");\n\n",
               class_name, object_name) >> filename;
 
+    printf ("std::set<std::string>\n") >> filename;
     if (base)
-      printf ("std::set<std::string>\nbase_properties::all_property_names (const std::string& cname") >> filename;
+      printf ("base_properties") >> filename;
     else
-      printf ("std::set<std::string>\n%s::properties::all_property_names (void", class_name) >> filename;
-    printf (")\n{\n  static std::set<std::string> all_pnames;\n\n  static bool initialized = false;\n\n  if (! initialized)\n    {\n") >> filename;
+      printf ("%s::properties", class_name) >> filename;
+    printf ("::core_property_names (void)\n{\n  static std::set<std::string> all_pnames;\n\n  static bool initialized = false;\n\n  if (! initialized)\n    {\n") >> filename;
     for (i = 1; i <= idx; i++)
       printf ("      all_pnames.insert (\"%s\");\n", name[i]) >> filename;
-    printf ("\n      initialized = true;\n    }\n\n") >> filename;
+    if (! base)
+      printf ("\n      std::set<std::string> base_pnames = base_properties::core_property_names ();\n      all_pnames.insert (base_pnames.begin (), base_pnames.end ());\n") >> filename;
+    printf ("\n      initialized = true;\n    }\n\n  return all_pnames;\n}\n\n") >> filename;
+
+    printf ("bool\n") >> filename;
     if (base)
-      printf ("  std::set<std::string> retval = all_pnames;\n  std::set<std::string> dyn_props = dynamic_property_names (cname);\n  retval.insert (dyn_props.begin(), dyn_props.end ());\n  return retval;\n}\n\n") >> filename;
+      printf ("base_properties") >> filename;
     else
-      printf ("  std::set<std::string> retval = all_pnames;\n  std::set<std::string> base_props = base_properties::all_property_names (\"%s\");\n  retval.insert (base_props.begin (), base_props.end ());\n  return retval;\n}\n\n", class_name) >> filename;
+      printf ("%s::properties", class_name) >> filename;
+    printf ("::has_core_property (const caseless_str& pname)\n{\n  std::set<std::string> pnames = core_property_names ();\n\n  return pnames.find (pname) != pnames.end ();\n}\n\n", class_name) >> filename;
 
+    printf ("std::set<std::string>\n") >> filename;
     if (base)
-      printf ("bool\nbase_properties::has_property (const std::string& pname, const std::string& cname)\n{\n  std::set<std::string> pnames = all_property_names (cname);\n\n") >> filename;
+	printf ("base_properties") >> filename;
+    else
+      printf ("%s::properties", class_name) >> filename;
+    printf ("::all_property_names (") >> filename;
+    if (base)
+      printf ("const std::string& cname") >> filename;
     else
-      printf ("bool\n%s::properties::has_property (const std::string& pname)\n{\n  std::set<std::string> pnames = all_property_names ();\n\n", class_name) >> filename;
+      printf ("void") >> filename;
+    printf (") const\n{\n  static std::set<std::string> all_pnames = core_property_names ();\n\n") >> filename;
+    if (base)
+      printf ("  std::set<std::string> retval = all_pnames;\n  std::set<std::string> dyn_props = dynamic_property_names (cname);\n  retval.insert (dyn_props.begin (), dyn_props.end ());\n  for (std::map<caseless_str, property, cmp_caseless_str>::const_iterator p = all_props.begin ();\n       p != all_props.end (); p++)\n    retval.insert (p->first);\n\n  return retval;\n}\n\n") >> filename;
+    else
+      printf ("  std::set<std::string> retval = all_pnames;\n  std::set<std::string> base_props = base_properties::all_property_names (\"%s\");\n  retval.insert (base_props.begin (), base_props.end ());\n\n  return retval;\n}\n\n", class_name) >> filename;
 
-    printf ("  return pnames.find (pname) != pnames.end ();\n}\n\n") >> filename;
+    if (! base)
+      printf ("bool\n%s::properties::has_property (const caseless_str& pname) const\n{\n  std::set<std::string> pnames = all_property_names ();\n\n  return pnames.find (pname) != pnames.end ();\n}\n\n", class_name) >> filename;
   }
 }
 
--- a/src/graphics.cc	Fri Aug 28 05:30:29 2009 -0400
+++ b/src/graphics.cc	Fri Aug 28 18:37:31 2009 -0400
@@ -66,7 +66,7 @@
 // if there is no match, or the match is ambiguous.
 
 static caseless_str
-validate_property_name (const std::string& who,
+validate_property_name (const std::string& who, const std::string& what,
 			const std::set<std::string>& pnames,
 			const caseless_str& pname)
 {
@@ -92,7 +92,8 @@
 
   if (num_matches == 0)
     {
-      error ("%s: unknown property %s", who.c_str (), pname.c_str ());
+      error ("%s: unknown %s property %s",
+	     who.c_str (), what.c_str (), pname.c_str ());
     }
   else if (num_matches > 1)
     {
@@ -104,8 +105,8 @@
 
       std::string match_list = os.str ();
 
-      error ("%s: ambiguous property name %s; possible matches:\n\n%s",
-	     who.c_str (), pname.c_str (), match_list.c_str ());
+      error ("%s: ambiguous %s property name %s; possible matches:\n\n%s",
+	     who.c_str (), what.c_str (), pname.c_str (), match_list.c_str ());
     }
   else if (num_matches == 1)
     {
@@ -114,8 +115,9 @@
       std::string possible_match = *(matches.begin ());
 
       warning_with_id ("Octave:abbreviated-property-match",
-		       "%s: allowing %s to match %s", who.c_str (),
-		       pname.c_str (), possible_match.c_str ());
+		       "%s: allowing %s to match %s property %s",
+		       who.c_str (), pname.c_str (), what.c_str (),
+		       possible_match.c_str ());
 
       return possible_match;
     }
@@ -1248,21 +1250,21 @@
 
 	  bool has_property = false;
 	  if (pfx == "axes")
-	    has_property = axes::properties::has_property (pname);
+	    has_property = axes::properties::has_core_property (pname);
 	  else if (pfx == "line")
-	    has_property = line::properties::has_property (pname);
+	    has_property = line::properties::has_core_property (pname);
 	  else if (pfx == "text")
-	    has_property = text::properties::has_property (pname);
+	    has_property = text::properties::has_core_property (pname);
 	  else if (pfx == "image")
-	    has_property = image::properties::has_property (pname);
+	    has_property = image::properties::has_core_property (pname);
 	  else if (pfx == "patch")
-	    has_property = patch::properties::has_property (pname);
+	    has_property = patch::properties::has_core_property (pname);
 	  else if (pfx == "figure")
-	    has_property = figure::properties::has_property (pname);
+	    has_property = figure::properties::has_core_property (pname);
 	  else if (pfx == "surface")
-	    has_property = surface::properties::has_property (pname);
+	    has_property = surface::properties::has_core_property (pname);
 	  else if (pfx == "hggroup")
-	    has_property = hggroup::properties::has_property (pname);
+	    has_property = hggroup::properties::has_core_property (pname);
 
 	  if (has_property)
 	    {
@@ -1853,25 +1855,6 @@
     return it->second;
 }
 
-bool
-base_properties::has_property (const caseless_str& name)
-{
-  property p;
-
-  unwind_protect::frame_id_t uwp_frame = unwind_protect::begin_frame ();
-
-  unwind_protect::protect_var (discard_error_messages);
-  unwind_protect::protect_var (error_state);
-
-  discard_error_messages = true;
-
-  p = get_property (name);
-
-  unwind_protect::run_frame (uwp_frame);
-
-  return (p.ok ());
-}
-
 void
 base_properties::remove_child (const graphics_handle& h)
 {
@@ -2169,13 +2152,23 @@
 
   for (Octave_map::const_iterator pa = m.begin (); pa != m.end (); pa++)
     {
-      if (get_properties().has_property (pa->first))
-	{
-	  property p = get_properties ().get_property (pa->first);
-
-	  if (! error_state && p.ok ())
-	    p.delete_listener ();
-	}
+      // FIXME -- there has to be a better way.  I think we want to
+      // ask whether it is OK to delete the listener for the given
+      // property.  How can we know in advance that it will be OK?
+
+      unwind_protect::frame_id_t uwp_frame = unwind_protect::begin_frame ();
+
+      unwind_protect::protect_var (discard_error_messages);
+      unwind_protect::protect_var (error_state);
+
+      discard_error_messages = true;
+
+      property p = get_properties ().get_property (pa->first);
+
+      if (! error_state && p.ok ())
+	p.delete_listener ();
+
+      unwind_protect::run_frame (uwp_frame);
     }
 }
 
--- a/src/graphics.h.in	Fri Aug 28 05:30:29 2009 -0400
+++ b/src/graphics.h.in	Fri Aug 28 18:37:31 2009 -0400
@@ -1656,7 +1656,11 @@
 
   virtual property get_property (const caseless_str& pname);
 
-  bool has_property (const caseless_str& pname);
+  virtual bool has_property (const caseless_str&) const
+  {
+    panic_impossible ();
+    return false;
+  }
 
   bool is_modified (void) const { return is___modified__ (); }