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

Generated by: LCOV version 2.0-1