Generate __attribute__(deprecated) for deprecated APIs.

We allow also a custom deprecation message.

Change-Id: I297bed611c7fbbb34d41e7edd796557c9afe50da
diff --git a/api/Utilities.cpp b/api/Utilities.cpp
index 311d7c6..4268278 100644
--- a/api/Utilities.cpp
+++ b/api/Utilities.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <algorithm>
 #include <iostream>
 #include <sstream>
 
@@ -149,6 +150,48 @@
     return (double)l;
 }
 
+// Add the value to the stream, prefixed with a ", " if needed.
+static void addCommaSeparated(const string& value, ostringstream* stream, bool* needComma) {
+    if (value.empty()) {
+        return;
+    }
+    if (*needComma) {
+        *stream << ", ";
+    }
+    *stream << value;
+    *needComma = true;
+}
+
+string makeAttributeTag(const string& userAttribute, const string& additionalAttribute,
+                        int deprecatedApiLevel, const string& deprecatedMessage) {
+    ostringstream stream;
+    bool needComma = false;
+    if (userAttribute[0] == '=') {
+        /* If starts with an equal, we don't automatically add additionalAttribute.
+         * This is because of the error we made defining rsUnpackColor8888().
+         */
+        addCommaSeparated(userAttribute.substr(1), &stream, &needComma);
+    } else {
+        addCommaSeparated(userAttribute, &stream, &needComma);
+        addCommaSeparated(additionalAttribute, &stream, &needComma);
+    }
+    if (deprecatedApiLevel > 0) {
+        stream << "\n#if (defined(RS_VERSION) && (RS_VERSION >= " << deprecatedApiLevel << "))\n";
+        addCommaSeparated("deprecated", &stream, &needComma);
+        if (!deprecatedMessage.empty()) {
+            // Remove any @ that's used for generating documentation cross references.
+            string s = deprecatedMessage;
+            s.erase(std::remove(s.begin(), s.end(), '@'), s.end());
+            stream << "(\"" << s << "\")";
+        }
+        stream << "\n#endif\n";
+    }
+    if (stream.tellp() == 0) {
+        return "";
+    }
+    return " __attribute__((" + stream.str() + "))";
+}
+
 // Opens the stream.  Reports an error if it can't.
 bool GeneratedFile::start(const string& directory, const string& name) {
     const string path = directory + "/" + name;