Skip to content

Commit cb18fec

Browse files
support backslash directory separator on WIN32
1 parent 31cf794 commit cb18fec

File tree

7 files changed

+85
-12
lines changed

7 files changed

+85
-12
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ LIB_SRC = \
5454
core/libjsonnet.cpp \
5555
core/parser.cpp \
5656
core/pass.cpp \
57+
core/path_utils.cpp \
5758
core/static_analysis.cpp \
5859
core/string_utils.cpp \
5960
core/vm.cpp \

core/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ cc_library(
99
"libjsonnet.cpp",
1010
"parser.cpp",
1111
"pass.cpp",
12+
"path_utils.cpp",
1213
"static_analysis.cpp",
1314
"string_utils.cpp",
1415
"vm.cpp",
@@ -21,6 +22,7 @@ cc_library(
2122
"lexer.h",
2223
"parser.h",
2324
"pass.h",
25+
"path_utils.h",
2426
"state.h",
2527
"static_analysis.h",
2628
"static_error.h",

core/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ set(LIBJSONNET_HEADERS
1010
../include/libjsonnet_fmt.h
1111
parser.h
1212
pass.h
13+
path_utils.h
1314
state.h
1415
static_analysis.h
1516
static_error.h
@@ -24,6 +25,7 @@ set(LIBJSONNET_SOURCE
2425
libjsonnet.cpp
2526
parser.cpp
2627
pass.cpp
28+
path_utils.cpp
2729
static_analysis.cpp
2830
string_utils.cpp
2931
vm.cpp)

core/path_utils.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
Copyright 2024 Google Inc. All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include "path_utils.h"
18+
#include <string>
19+
20+
namespace jsonnet::internal {
21+
22+
// C++17 adds <filesystem>
23+
// We could consider using that instead.
24+
25+
#if _WIN32
26+
static const char DIR_SEPARATORS[] = "\\/";
27+
#else
28+
static const char DIR_SEPARATORS[] = "/";
29+
#endif
30+
31+
std::string path_dir_with_trailing_separator(const std::string &path) {
32+
size_t last_slash = path.find_last_of(DIR_SEPARATORS);
33+
if (last_slash != std::string::npos) {
34+
return path.substr(0, last_slash + 1);
35+
}
36+
return "";
37+
}
38+
39+
} // namespace jsonnet::internal

core/path_utils.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
Copyright 2024 Google Inc. All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#ifndef JSONNET_PATH_UTILS_H
18+
#define JSONNET_PATH_UTILS_H
19+
20+
#include <string>
21+
22+
namespace jsonnet::internal {
23+
24+
/** Get everything except the filename from a path. If the path is just a filename, returns "".
25+
*
26+
* The result includes the trailing directory separator (if there is one in the input).
27+
* Exact behaviour is platform-specific (different platforms use different directory separators).
28+
*/
29+
std::string path_dir_with_trailing_separator(const std::string &path);
30+
31+
} // namespace jsonnet::internal
32+
33+
#endif
34+

core/vm.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ limitations under the License.
3535
#include "static_analysis.h"
3636
#include "string_utils.h"
3737
#include "vm.h"
38+
#include "path_utils.h"
3839

3940
namespace jsonnet::internal {
4041

@@ -54,17 +55,6 @@ using json = nlohmann::json;
5455

5556
namespace {
5657

57-
/** Turn a path e.g. "/a/b/c" into a dir, e.g. "/a/b/". If there is no path returns "".
58-
*/
59-
std::string dir_name(const std::string &path)
60-
{
61-
size_t last_slash = path.rfind('/');
62-
if (last_slash != std::string::npos) {
63-
return path.substr(0, last_slash + 1);
64-
}
65-
return "";
66-
}
67-
6858
/** Stack frames.
6959
*
7060
* Of these, FRAME_CALL is the most special, as it is the only frame the stack
@@ -800,7 +790,11 @@ class Interpreter {
800790
*/
801791
ImportCacheValue *importData(const LocationRange &loc, const LiteralString *file)
802792
{
803-
std::string dir = dir_name(loc.file);
793+
// `dir` is passed to the importCallback, which may be externally defined.
794+
// For backwards compatibility, we need to keep the trailing directory separator.
795+
// For example, the default callback in libjsonnet.cpp joins paths with simple
796+
// string concatenation. Other (external) implementations might do the same.
797+
std::string dir = path_dir_with_trailing_separator(loc.file);
804798

805799
const UString &path = file->value;
806800

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"core/lexer.cpp",
2828
"core/parser.cpp",
2929
"core/pass.cpp",
30+
"core/path_utils.cpp",
3031
"core/static_analysis.cpp",
3132
"core/string_utils.cpp",
3233
"core/vm.cpp",

0 commit comments

Comments
 (0)