[PATCH v2] sed: @file reads pattern or replacement from a file. Useful for shader replacement.

Arthur Huillet arthur.huillet at free.fr
Mon Jun 8 07:04:45 PDT 2015


From: Arthur Huillet <ahuillet at nvidia.com>

Replacing shaders isn't easily done on the commandline, so add "@file()" to
tell apitrace sed to read pattern or replacement from a file.
This replacement is implemented on String-type nodes, so apitrace sed now
effectively works on string elements in addition to enum elements.

The pattern/replacement separator can be a slash or any other character,
allowing use of slashes in the file path.

Signed-off-by: Arthur Huillet <ahuillet at nvidia.com>
---
 cli/cli_sed.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 48 insertions(+), 9 deletions(-)

diff --git a/cli/cli_sed.cpp b/cli/cli_sed.cpp
index ccb38b0..750b213 100644
--- a/cli/cli_sed.cpp
+++ b/cli/cli_sed.cpp
@@ -46,8 +46,11 @@ usage(void)
         << synopsis << "\n"
         "\n"
         "    -h, --help               Show detailed help for sed options and exit\n"
-        "    -e s/SEARCH/REPLACE/     Search and replace a symbol.\n"
-        "                             XXX: Only works for enums.\n"
+        "    -e s/SEARCH/REPLACE/     Search and replace a symbol. Use @file(<path>)\n"
+        "                             to read SEARCH or REPLACE from a file.\n"
+        "                             Any character (not just /) can be used as \n"
+        "                             separator.\n"
+        "                             XXX: Only works for enums and strings.\n"
         "    -o, --output=TRACE_FILE  Output trace file\n"
     ;
 }
@@ -104,6 +107,12 @@ public:
     }
 
     void visit(String *node) {
+        if (!searchName.compare(node->value)) {
+                delete [] node->value;
+                char *str = new char [replaceName.length() + 1];
+                strcpy(str, replaceName.c_str());
+                node->value = str;
+        }
     }
 
     void visit(WString *node) {
@@ -210,22 +219,22 @@ sed_trace(Replacements &replacements, const char *inFileName, std::string &outFi
 
 
 /**
- * Parse a string in the format "s/SEARCH/REPLACE/".
+ * Parse a string in the format "s,SEARCH,REPLACE,".
  */
 static bool
 parseSubstOpt(Replacements &replacements, const char *opt)
 {
+    char separator;
+
     if (*opt++ != 's') {
         return false;
     }
 
-    if (*opt++ != '/') {
-        return false;
-    }
+    separator = *opt++;
 
     // Parse the search pattern
     const char *search_begin = opt;
-    while (*opt != '/') {
+    while (*opt != separator) {
         if (*opt == 0) {
             return false;
         }
@@ -235,7 +244,7 @@ parseSubstOpt(Replacements &replacements, const char *opt)
 
     // Parse the replace pattern
     const char *replace_begin = opt;
-    while (*opt != '/') {
+    while (*opt != separator) {
         if (*opt == 0) {
             return false;
         }
@@ -250,6 +259,36 @@ parseSubstOpt(Replacements &replacements, const char *opt)
     std::string search(search_begin, search_end);
     std::string replace(replace_begin, replace_end);
 
+    // If search or replace strings are taken from a file, read the file
+    std::string file_subst = "@file(";
+
+    for (int i = 0; i < 2; i++) {
+        std::string *str = i ? &search : &replace;
+
+        if (!str->compare(0, file_subst.length(), file_subst)) {
+            if ((*str)[str->length()-1] != ')') {
+                return false;
+            }
+
+            std::string fname = str->substr(file_subst.length());
+            fname[fname.length()-1] = 0;
+            FILE *f = fopen(fname.c_str(), "r");
+            if (!f) {
+                std::cerr << "error: cannot open file " << fname << "\n";
+                return false;
+            }
+            char buf[1024];
+            (*str) = "";
+            while (!feof(f)) {
+                if (fgets(buf, 1024, f)) {
+                    str->append(buf);
+                }
+            }
+            fclose(f);
+        }
+    }
+
+
     replacements.push_back(Replacer(search, replace));
 
     return true;
@@ -273,7 +312,7 @@ command(int argc, char *argv[])
             break;
         case 'e':
             if (!parseSubstOpt(replacements, optarg)) {
-                std::cerr << "error: invalid replacement patter `" << optarg << "`\n";
+                std::cerr << "error: invalid replacement pattern `" << optarg << "`\n";
             }
             break;
         default:
-- 
2.3.5


More information about the apitrace mailing list