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

Generated by: LCOV version 2.0-1