LCOV - code coverage report
Current view: top level - source/lib - path.cpp (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 32 36 88.9 %
Date: 2023-01-19 00:18:29 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /* Copyright (C) 2010 Wildfire Games.
       2             :  *
       3             :  * Permission is hereby granted, free of charge, to any person obtaining
       4             :  * a copy of this software and associated documentation files (the
       5             :  * "Software"), to deal in the Software without restriction, including
       6             :  * without limitation the rights to use, copy, modify, merge, publish,
       7             :  * distribute, sublicense, and/or sell copies of the Software, and to
       8             :  * permit persons to whom the Software is furnished to do so, subject to
       9             :  * the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice shall be included
      12             :  * in all copies or substantial portions of the Software.
      13             :  *
      14             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      15             :  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      16             :  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
      17             :  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
      18             :  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
      19             :  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
      20             :  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      21             :  */
      22             : 
      23             : /*
      24             :  * helper functions for path strings.
      25             :  */
      26             : 
      27             : #include "precompiled.h"
      28             : #include "lib/path.h"
      29             : 
      30             : #include <cstring>
      31             : #include <cerrno>
      32             : 
      33             : static const StatusDefinition pathStatusDefinitions[] = {
      34             :     { ERR::PATH_CHARACTER_ILLEGAL, L"illegal path character" },
      35             :     { ERR::PATH_CHARACTER_UNSAFE, L"unsafe path character" },
      36             :     { ERR::PATH_NOT_FOUND, L"path not found" },
      37             :     { ERR::PATH_MIXED_SEPARATORS, L"path contains both slash and backslash separators" }
      38             : };
      39           1 : STATUS_ADD_DEFINITIONS(pathStatusDefinitions);
      40             : 
      41             : 
      42           7 : static bool path_is_dir_sep(wchar_t c)
      43             : {
      44           7 :     if(c == '/' || c == '\\')
      45           3 :         return true;
      46           4 :     return false;
      47             : }
      48             : 
      49             : // is s2 a subpath of s1, or vice versa?
      50             : // (equal counts as subpath)
      51           9 : bool path_is_subpath(const wchar_t* s1, const wchar_t* s2)
      52             : {
      53             :     // make sure s1 is the shorter string
      54           9 :     if(wcslen(s1) > wcslen(s2))
      55           4 :         std::swap(s1, s2);
      56             : 
      57           9 :     wchar_t c1 = 0, last_c1, c2;
      58             :     for(;;)
      59             :     {
      60          63 :         last_c1 = c1;
      61          36 :         c1 = *s1++, c2 = *s2++;
      62             : 
      63             :         // end of s1 reached:
      64          36 :         if(c1 == '\0')
      65             :         {
      66             :             // s1 matched s2 up until:
      67          10 :             if((c2 == '\0') ||  // its end (i.e. they're equal length) OR
      68           9 :                 path_is_dir_sep(c2) ||      // start of next component OR
      69           3 :                 path_is_dir_sep(last_c1))   // ", but both have a trailing slash
      70             :                 // => is subpath
      71           5 :                 return true;
      72             :         }
      73             : 
      74             :         // mismatch => is not subpath
      75          31 :         if(c1 != c2)
      76           4 :             return false;
      77             :     }
      78             : }
      79             : 
      80             : 
      81             : //-----------------------------------------------------------------------------
      82             : 
      83             : // return pointer to the name component within path (i.e. skips over all
      84             : // characters up to the last dir separator, if any).
      85         385 : const wchar_t* path_name_only(const wchar_t* path)
      86             : {
      87         385 :     const wchar_t* slash1 = wcsrchr(path, '/');
      88         385 :     const wchar_t* slash2 = wcsrchr(path, '\\');
      89             :     // neither present, it's a filename only
      90         385 :     if(!slash1 && !slash2)
      91           2 :         return path;
      92             : 
      93             :     // return name, i.e. component after the last slash
      94         383 :     const wchar_t* name = std::max(slash1, slash2)+1;
      95         383 :     return name;
      96             : }
      97             : 
      98             : 
      99       46963 : /*static*/ Status Path::Validate(String::value_type c)
     100             : {
     101       46963 :     if(c < 32)
     102           0 :         return ERR::PATH_CHARACTER_UNSAFE;
     103             : 
     104             : #if !OS_WIN
     105       46963 :     if(c >= UCHAR_MAX)
     106           0 :         return ERR::PATH_CHARACTER_UNSAFE;
     107             : #endif
     108             : 
     109       46963 :     switch(c)
     110             :     {
     111           0 :     case '\\':
     112             :     case '/':
     113             :     case ':':
     114             :     case '"':
     115             :     case '?':
     116             :     case '*':
     117             :     case '<':
     118             :     case '>':
     119             :     case '|':
     120             :     case '^':
     121           0 :         return ERR::PATH_CHARACTER_ILLEGAL;
     122             : 
     123       46963 :     default:
     124       46963 :         return INFO::OK;
     125             :     }
     126           3 : }

Generated by: LCOV version 1.13