xref: /aosp_15_r20/external/skia/tools/skslc/ProcessWorklist.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2022 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "src/base/SkStringView.h"
9 #include "tools/skslc/ProcessWorklist.h"
10 
11 #include <algorithm>
12 #include <fstream>
13 #include <vector>
14 
ProcessWorklist(const char * worklistPath,const std::function<ResultCode (SkSpan<std::string> args)> & processCommandFn)15 ResultCode ProcessWorklist(
16         const char* worklistPath,
17         const std::function<ResultCode(SkSpan<std::string> args)>& processCommandFn) {
18     std::string inputPath(worklistPath);
19     if (!skstd::ends_with(inputPath, ".worklist")) {
20         printf("expected .worklist file, found: %s\n\n", worklistPath);
21         return ResultCode::kConfigurationError;
22     }
23 
24     // The worklist contains one line per argument to pass. When a blank line is reached, those
25     // arguments will be passed to `processCommandFn`.
26     auto resultCode = ResultCode::kSuccess;
27     std::vector<std::string> args = {"sksl"};
28     std::ifstream in(worklistPath);
29     for (std::string line; std::getline(in, line); ) {
30         if (in.rdstate()) {
31             printf("error reading '%s'\n", worklistPath);
32             return ResultCode::kInputError;
33         }
34 
35         if (!line.empty()) {
36             // We found an argument. Remember it.
37             args.push_back(std::move(line));
38         } else {
39             // We found a blank line. If we have any arguments stored up, process them as a command.
40             if (!args.empty()) {
41                 ResultCode outcome = processCommandFn(args);
42                 resultCode = std::max(resultCode, outcome);
43 
44                 // Clear every argument except the first.
45                 args.resize(1);
46             }
47         }
48     }
49 
50     // If the worklist ended with a list of arguments but no blank line, process those now.
51     if (args.size() > 1) {
52         ResultCode outcome = processCommandFn(args);
53         resultCode = std::max(resultCode, outcome);
54     }
55 
56     // Return the "worst" status we encountered. For our purposes, compilation errors are the least
57     // serious, because they are expected to occur in unit tests. Other types of errors are not
58     // expected at all during a build.
59     return resultCode;
60 }
61