|
23 | 23 | # :type path: string |
24 | 24 | # |
25 | 25 | function(normalize_path var path) |
26 | | - list(LENGTH path length) |
27 | | - if(NOT length EQUAL 1) |
28 | | - message(FATAL_ERROR "normalize_path() the path '${path}' must neither be empty nor contain semicolons") |
29 | | - endif() |
30 | | - # convert to list |
31 | | - file(TO_CMAKE_PATH "${path}" path) |
32 | | - string(REPLACE "/" ";" parts "${path}") |
33 | | - |
34 | | - _normalize_path__collapse_redundant(parts "${parts}") |
35 | | - _normalize_path__collapse_uplevel_reference(parts "${parts}") |
36 | | - |
37 | | - # check if path has completely collapsed |
38 | | - if(parts STREQUAL "") |
39 | | - set(parts ".") |
40 | | - endif() |
41 | | - |
42 | | - # convert back to string |
43 | | - string(REPLACE ";" "/" normalized "${parts}") |
44 | | - |
| 26 | + cmake_path(SET normalized NORMALIZE "${path}") |
45 | 27 | set(${var} "${normalized}" PARENT_SCOPE) |
46 | 28 | endfunction() |
47 | | - |
48 | | - |
49 | | -function(_normalize_path__collapse_redundant var) |
50 | | - set(parts "${ARGN}") |
51 | | - set(index 1) # index 0 is empty for absolute paths |
52 | | - while(TRUE) |
53 | | - list(LENGTH parts length) |
54 | | - if(NOT index LESS length) |
55 | | - break() |
56 | | - endif() |
57 | | - list(GET parts ${index} part) |
58 | | - # remove empty parts as well as current directory references |
59 | | - if(part STREQUAL "" OR part STREQUAL ".") |
60 | | - list(REMOVE_AT parts ${index}) |
61 | | - else() |
62 | | - math(EXPR index "${index} + 1") |
63 | | - endif() |
64 | | - endwhile() |
65 | | - set(${var} "${parts}" PARENT_SCOPE) |
66 | | -endfunction() |
67 | | - |
68 | | - |
69 | | -function(_normalize_path__collapse_uplevel_reference var) |
70 | | - set(parts "${ARGN}") |
71 | | - set(index 0) |
72 | | - while(TRUE) |
73 | | - list(LENGTH parts length) |
74 | | - if(NOT index LESS length) |
75 | | - break() |
76 | | - endif() |
77 | | - |
78 | | - # get previous element |
79 | | - set(previous_index ${index}) |
80 | | - list(GET parts ${previous_index} previous) |
81 | | - math(EXPR index "${index} + 1") |
82 | | - if(NOT index LESS length) |
83 | | - break() |
84 | | - endif() |
85 | | - # get current element |
86 | | - list(GET parts ${index} current) |
87 | | - |
88 | | - if(current STREQUAL ".." AND NOT previous STREQUAL "..") |
89 | | - # collapse the '..' |
90 | | - list(REMOVE_AT parts ${index}) |
91 | | - set(index ${previous_index}) |
92 | | - if(previous STREQUAL "") |
93 | | - # only collapse the '..' when starting with '/../' |
94 | | - if(previous_index GREATER 0) |
95 | | - string(REPLACE ";" "/" path "${parts}") |
96 | | - message(FATAL_ERROR "_normalize_path__collapse_uplevel_reference() the path '${path}' must not contain redundant separators") |
97 | | - endif() |
98 | | - else() |
99 | | - # collapse the '..' as well as the part before |
100 | | - list(REMOVE_AT parts ${previous_index}) |
101 | | - if(previous_index GREATER 0) |
102 | | - math(EXPR index "${previous_index} - 1") |
103 | | - else() |
104 | | - math(EXPR index 0) |
105 | | - endif() |
106 | | - endif() |
107 | | - endif() |
108 | | - endwhile() |
109 | | - set(${var} "${parts}" PARENT_SCOPE) |
110 | | -endfunction() |
0 commit comments