summaryrefslogtreecommitdiffstats
path: root/Tests/ISPC/ObjectGenex/main.cxx
blob: 143e74e13a6635d33d4ce3c91f71edadbf99c2e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <stdio.h>

/*
  Define GENERATED_HEADER macro to allow c++ files to include headers
  generated based on different configuration types.
*/

/* clang-format off */
#define GENERATED_HEADER(x) GENERATED_HEADER0(CONFIG_TYPE/x)
/* clang-format on */
#define GENERATED_HEADER0(x) GENERATED_HEADER1(x)
#define GENERATED_HEADER1(x) <x>

#include GENERATED_HEADER(path_to_objs.h)

#include <vector>
std::vector<std::string> expandList(std::string const& arg)
{
  std::vector<std::string> output;
  // If argument is empty or no `;` just copy the current string
  if (arg.empty() || arg.find(';') == std::string::npos) {
    output.emplace_back(arg);
    return output;
  }

  std::string newArg;
  // Break the string at non-escaped semicolons not nested in [].
  int squareNesting = 0;
  auto last = arg.begin();
  auto const cend = arg.end();
  for (auto c = last; c != cend; ++c) {
    switch (*c) {
      case '\\': {
        // We only want to allow escaping of semicolons.  Other
        // escapes should not be processed here.
        auto cnext = c + 1;
        if ((cnext != cend) && *cnext == ';') {
          newArg.append(last, c);
          // Skip over the escape character
          last = cnext;
          c = cnext;
        }
      } break;
      case '[': {
        ++squareNesting;
      } break;
      case ']': {
        --squareNesting;
      } break;
      case ';': {
        // Break the string here if we are not nested inside square
        // brackets.
        if (squareNesting == 0) {
          newArg.append(last, c);
          // Skip over the semicolon
          last = c + 1;
          if (!newArg.empty()) {
            // Add the last argument if the string is not empty.
            output.push_back(newArg);
            newArg.clear();
          }
        }
      } break;
      default: {
        // Just append this character.
      } break;
    }
  }
  newArg.append(last, cend);
  if (!newArg.empty()) {
    // Add the last argument if the string is not empty.
    output.push_back(std::move(newArg));
  }

  return output;
}

int main()
{
  // determine that the number of object files specified in obj_paths
  // is equal to the number of arch's

  std::vector<std::string> paths = expandList(obj_paths);
  const bool correctSize = (paths.size() == ExpectedISPCObjects);

  return (correctSize) ? 0 : 1;
}