LCOV - code coverage report
Current view: top level - libs/kiss/src - path.cpp (source / functions) Coverage Total Hit
Test: coverage.info.cleaned Lines: 25.0 % 52 13
Test Date: 2026-07-13 06:03:10 Functions: 37.5 % 8 3

            Line data    Source code
       1              : #include "kiss/path.h"
       2              : 
       3              : #ifdef WIN32
       4              : #  include "windows.h"
       5              : #  ifndef S_ISREG
       6              : #    define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
       7              : #  endif
       8              : #  ifndef S_ISDIR
       9              : #    define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
      10              : #  endif
      11              : #  include "sys/stat.h"
      12              : #else
      13              : #include <sys/types.h>
      14              : #include <fcntl.h>
      15              : #include <unistd.h>
      16              : #include <dirent.h>
      17              : #include "sys/stat.h"
      18              : #endif
      19              : 
      20              : #ifdef __APPLE__
      21              : #include <mach-o/dyld.h>
      22              : #endif
      23              : 
      24              : #ifndef PATH_MAX
      25              : #define PATH_MAX 4096
      26              : #endif
      27              : 
      28              : #include <stdexcept>
      29              : #include <cstdio>
      30              : 
      31            0 : bool create_directory(const std::string &path, size_t user_permission,
      32              :                 size_t group_permission, size_t other_permission) {
      33              : #ifdef WIN32
      34              :         BOOL result = ::CreateDirectoryA(path.c_str(), 0);
      35              :         return result == TRUE;
      36              : #else
      37              :         mode_t m = 0;
      38            0 :         m |= (user_permission << 6);
      39            0 :         m |= (group_permission << 3);
      40            0 :         m |= (other_permission << 0);
      41            0 :         int result = mkdir(path.c_str(), m);
      42            0 :         return (result == 0);
      43              : #endif
      44              : }
      45              : 
      46          187 : bool is_directory(const std::string &path) {
      47              : #ifdef WIN32
      48              :         struct _stat buf;
      49              :         int result = _stat(path.c_str(), &buf);
      50              :         if (result == 0 && S_ISDIR(buf.st_mode))
      51              :                 return true;
      52              :         else
      53              :                 return false;
      54              : #else
      55              :         struct stat buf;
      56          187 :         int result = stat(path.c_str(), &buf);
      57          187 :         if (result == 0 && S_ISDIR(buf.st_mode))
      58              :         return true;
      59              :         else
      60          173 :         return false;
      61              : #endif
      62              : }
      63              : 
      64            0 : bool list_directory(const std::string &directory,
      65              :                 std::vector<std::string> &elements) {
      66              : #ifdef WIN32
      67              :         WIN32_FIND_DATA findData;
      68              :         HANDLE hFind = FindFirstFileA((directory + "\\*.*").c_str(), &findData);
      69              :         if (hFind == INVALID_HANDLE_VALUE)
      70              :                 throw std::runtime_error("Failed to get directory list");
      71              :         for (;;) {
      72              :                 if (findData.cFileName[0] != '.') {
      73              :                         elements.push_back(findData.cFileName);
      74              :                 }
      75              :                 if (FindNextFileA(hFind, &findData) == 0)
      76              :                         break;
      77              :         }
      78              :         FindClose(hFind);
      79              : #else
      80            0 :         DIR* dir = opendir(directory.c_str());
      81            0 :         if (dir == NULL)
      82              :         return false;
      83              :         dirent* entry;
      84            0 :         while ((entry = readdir(dir)) != NULL) {
      85            0 :                 if (entry->d_name[0] != '.') {
      86            0 :                         elements.push_back(entry->d_name);
      87              :                 }
      88              :         }
      89            0 :         closedir(dir);
      90              : #endif
      91            0 :         return true;
      92              : }
      93              : 
      94            0 : bool create_directory_recursive(const std::string &dir, size_t user_permission,
      95              :                 size_t group_permission, size_t other_permission) {
      96              :         // split path
      97            0 :         const char seperators[] = "\\/";
      98              :         std::vector<std::string> elements;
      99              :         std::string::size_type a, b;
     100              :         a = dir.find_first_not_of(seperators), b = dir.find_first_of(seperators, a);
     101            0 :         while (a != std::string::npos) {
     102            0 :                 elements.push_back(dir.substr(a, b - a));
     103              :                 a = dir.find_first_not_of(seperators, b), b = dir.find_first_of(
     104              :                                 seperators, a);
     105              :         }
     106              : 
     107              :         // create all non existing parts
     108              :         std::string path;
     109            0 :         for (size_t i = 0; i < elements.size(); i++) {
     110              :                 path += elements[i];
     111              :                 path += path_seperator;
     112            0 :                 if (is_directory(path) == false)
     113            0 :                         create_directory(path);
     114              :         }
     115              : 
     116            0 :         return is_directory(dir);
     117            0 : }
     118              : 
     119          597 : std::string concat_path(const std::string &a, const std::string &b) {
     120          597 :         char last = *a.rbegin();
     121          597 :         if (last == '\\' || last == '/')
     122              :                 return a + b;
     123              :         else
     124         1194 :                 return a + path_seperator + b;
     125              : 
     126              : }
     127              : 
     128            0 : std::string concat_path(const std::string &a, const std::string &b,
     129              :                 const std::string &c) {
     130              :         std::string p = a;
     131            0 :         if (*p.rbegin() != '\\' && *p.rbegin() != '/')
     132              :                 p += path_seperator;
     133              :         p += b;
     134            0 :         if (*p.rbegin() != '\\' && *p.rbegin() != '/')
     135              :                 p += path_seperator;
     136              :         p += c;
     137            0 :         return p;
     138              : }
     139              : 
     140            0 : void append_file(const std::string &target, const std::string &source,
     141              :                 bool binary) {
     142            0 :         FILE *t = fopen(target.c_str(), binary ? "wb+" : "w+");
     143            0 :         if (t == NULL)
     144            0 :                 return;
     145              : 
     146            0 :         FILE *s = fopen(source.c_str(), binary ? "rb" : "r");
     147            0 :         if (s == NULL) {
     148            0 :                 fclose(t);
     149            0 :                 return;
     150              :         }
     151              : 
     152              :         size_t size = 0;
     153              :         char buffer[1 << 20];
     154            0 :         while ((size = fread(buffer, 1, sizeof(buffer), s)) > 0) {
     155            0 :                 fwrite(buffer, 1, size, t);
     156              :         }
     157              : 
     158            0 :         fclose(t);
     159            0 :         fclose(s);
     160              : }
     161              : 
     162              : // see https://stackoverflow.com/a/60250581
     163           14 : std::string executable_path() {
     164              :         #ifdef __APPLE__
     165              :                 char rawPathName[PATH_MAX];
     166              :         char realPathName[PATH_MAX];
     167              :         uint32_t rawPathSize = (uint32_t)sizeof(rawPathName);
     168              : 
     169              :         if(!_NSGetExecutablePath(rawPathName, &rawPathSize)) {
     170              :             realpath(rawPathName, realPathName);
     171              :         }
     172              :         return  std::string(realPathName) + "/";
     173              :         #else
     174              :         char buf[PATH_MAX];
     175              : 
     176              :         #ifdef __linux__
     177           14 :                 size_t len = readlink("/proc/self/exe", buf, sizeof(buf)-1);
     178              :         #elif defined(_WIN32)
     179              :                 size_t len = ::GetModuleFileName(NULL, buf, sizeof(buf)-1 );
     180              :         #endif  // __linux__
     181              : 
     182          202 :         for (size_t i = 1; i < len; i++) {
     183          198 :                 if (buf[len - 1] == path_seperator)
     184              :                         break;
     185              :                 else
     186              :                         len --;
     187              :         }
     188           14 :         return std::string(buf, len);
     189              : 
     190              :         #endif // __APPLE__
     191              : }
        

Generated by: LCOV version 2.0-1