Browse Source

BUG: Add cmSourceFile::GetPropertyForUser to centralize the LOCATION property hack. This fixes the LOCATION property when retrieved via the get_property command.

Brad King 18 years ago
parent
commit
d5db5a275a

+ 2 - 1
Source/cmGetPropertyCommand.cxx

@@ -287,7 +287,8 @@ bool cmGetPropertyCommand::HandleSourceMode()
   if(cmSourceFile* sf =
   if(cmSourceFile* sf =
      this->Makefile->GetOrCreateSource(this->Name.c_str()))
      this->Makefile->GetOrCreateSource(this->Name.c_str()))
     {
     {
-    return this->StoreResult(sf->GetProperty(this->PropertyName.c_str()));
+    return
+      this->StoreResult(sf->GetPropertyForUser(this->PropertyName.c_str()));
     }
     }
   else
   else
     {
     {

+ 2 - 14
Source/cmGetSourceFilePropertyCommand.cxx

@@ -38,24 +38,12 @@ bool cmGetSourceFilePropertyCommand
     }
     }
   if(sf)
   if(sf)
     {
     {
-    if(args[2] == "LOCATION")
-      {
-      // Make sure the location is known.  Update: this is a hack to work
-      // around a problem with const methods in cmSourceFile, by design
-      // GetProperty("LOCATION") should work but right now it has to be
-      // "primed" by calling GetFullPath() first on a non-const cmSourceFile
-      // instance. This is because LOCATION is a computed-on-demand
-      // property. Either GetProperty needs to be non-const or the map
-      // needs to be changed to be mutable etc. for computed properties to
-      // work properly.
-      sf->GetFullPath();
-      } 
-    else if(args[2] == "LANGUAGE")
+    if(args[2] == "LANGUAGE")
       {
       {
       this->Makefile->AddDefinition(var, sf->GetLanguage());
       this->Makefile->AddDefinition(var, sf->GetLanguage());
       return true;
       return true;
       }
       }
-    const char *prop = sf->GetProperty(args[2].c_str());
+    const char *prop = sf->GetPropertyForUser(args[2].c_str());
     if (prop)
     if (prop)
       {
       {
       this->Makefile->AddDefinition(var, prop);
       this->Makefile->AddDefinition(var, prop);

+ 27 - 0
Source/cmSourceFile.cxx

@@ -280,6 +280,33 @@ void cmSourceFile::AppendProperty(const char* prop, const char* value)
   this->Properties.AppendProperty(prop, value, cmProperty::SOURCE_FILE);
   this->Properties.AppendProperty(prop, value, cmProperty::SOURCE_FILE);
 }
 }
 
 
+//----------------------------------------------------------------------------
+const char* cmSourceFile::GetPropertyForUser(const char *prop)
+{
+  // This method is a consequence of design history and backwards
+  // compatibility.  GetProperty is (and should be) a const method.
+  // Computed properties should not be stored back in the property map
+  // but instead reference information already known.  If they need to
+  // cache information in a mutable ivar to provide the return string
+  // safely then so be it.
+  //
+  // The LOCATION property is particularly problematic.  The CMake
+  // language has very loose restrictions on the names that will match
+  // a given source file (for historical reasons).  Implementing
+  // lookups correctly with such loose naming requires the
+  // cmSourceFileLocation class to commit to a particular full path to
+  // the source file as late as possible.  If the users requests the
+  // LOCATION property we must commit now.
+  if(strcmp(prop, "LOCATION") == 0)
+    {
+    // Commit to a location.
+    this->GetFullPath();
+    }
+
+  // Perform the normal property lookup.
+  return this->GetProperty(prop);
+}
+
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 const char* cmSourceFile::GetProperty(const char* prop) const
 const char* cmSourceFile::GetProperty(const char* prop) const
 {
 {

+ 4 - 0
Source/cmSourceFile.h

@@ -53,6 +53,10 @@ public:
   const char *GetProperty(const char *prop) const;
   const char *GetProperty(const char *prop) const;
   bool GetPropertyAsBool(const char *prop) const;
   bool GetPropertyAsBool(const char *prop) const;
 
 
+  /** Implement getting a property when called from a CMake language
+      command like get_property or get_source_file_property.  */
+  const char* GetPropertyForUser(const char *prop);
+
   /**
   /**
    * The full path to the file.  The non-const version of this method
    * The full path to the file.  The non-const version of this method
    * may attempt to locate the file on disk and finalize its location.
    * may attempt to locate the file on disk and finalize its location.