cprover
file_util.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: File Utilities
4 
5 Author:
6 
7 Date: January 2012
8 
9 \*******************************************************************/
10 
13 
14 #include "file_util.h"
15 
16 #include <cerrno>
17 
18 #if defined(__linux__) || \
19  defined(__FreeBSD_kernel__) || \
20  defined(__GNU__) || \
21  defined(__unix__) || \
22  defined(__CYGWIN__) || \
23  defined(__MACH__)
24 #include <sys/stat.h>
25 #include <unistd.h>
26 #include <dirent.h>
27 #include <cstdlib>
28 #include <cstdio>
29 #endif
30 
31 #ifdef _WIN32
32 #include <io.h>
33 #include <windows.h>
34 #include <direct.h>
35 #include <util/unicode.h>
36 #define chdir _chdir
37 #define popen _popen
38 #define pclose _pclose
39 #else
40 #include <cstring>
41 #endif
42 
45 {
46  unsigned bsize=50;
47 
48  char *buf=reinterpret_cast<char*>(malloc(sizeof(char)*bsize));
49  if(!buf)
50  abort();
51 
52  errno=0;
53 
54  while(buf && getcwd(buf, bsize-1)==nullptr && errno==ERANGE)
55  {
56  bsize*=2;
57  buf=reinterpret_cast<char*>(realloc(buf, sizeof(char)*bsize));
58  }
59 
60  std::string working_directory=buf;
61  free(buf);
62 
63  return working_directory;
64 }
65 
67 #ifdef _WIN32
68 
69 void delete_directory_utf16(const std::wstring &path)
70 {
71  std::wstring pattern=path + L"\\*";
72  // NOLINTNEXTLINE(readability/identifiers)
73  struct _wfinddata_t info;
74  intptr_t hFile=_wfindfirst(pattern.c_str(), &info);
75  if(hFile!=-1)
76  {
77  do
78  {
79  if(wcscmp(info.name, L".")==0 || wcscmp(info.name, L"..")==0)
80  continue;
81  std::wstring sub_path=path+L"\\"+info.name;
82  if(info.attrib & _A_SUBDIR)
83  delete_directory_utf16(sub_path);
84  else
85  DeleteFileW(sub_path.c_str());
86  }
87  while(_wfindnext(hFile, &info)==0);
88  _findclose(hFile);
89  RemoveDirectoryW(path.c_str());
90  }
91 }
92 
93 #endif
94 
95 void delete_directory(const std::string &path)
96 {
97 #ifdef _WIN32
98  delete_directory_utf16(utf8_to_utf16_little_endian(path));
99 #else
100  DIR *dir=opendir(path.c_str());
101  if(dir!=nullptr)
102  {
103  struct dirent *ent;
104  while((ent=readdir(dir))!=nullptr)
105  {
106  // Needed for Alpine Linux
107  if(strcmp(ent->d_name, ".")==0 || strcmp(ent->d_name, "..")==0)
108  continue;
109 
110  std::string sub_path=path+"/"+ent->d_name;
111 
112  struct stat stbuf;
113  stat(sub_path.c_str(), &stbuf);
114 
115  if(S_ISDIR(stbuf.st_mode))
116  delete_directory(sub_path);
117  else
118  remove(sub_path.c_str());
119  }
120  closedir(dir);
121  }
122  rmdir(path.c_str());
123 #endif
124 }
125 
128 std::string concat_dir_file(
129  const std::string &directory,
130  const std::string &file_name)
131 {
132  #ifdef _WIN32
133  return (file_name.size()>1 &&
134  file_name[0]!='/' &&
135  file_name[1]!=':') ?
136  file_name : directory+"\\"+file_name;
137  #else
138  return (!file_name.empty() && file_name[0]=='/') ?
139  file_name : directory+"/"+file_name;
140  #endif
141 }
std::string concat_dir_file(const std::string &directory, const std::string &file_name)
Definition: file_util.cpp:128
std::string get_current_working_directory()
Definition: file_util.cpp:44
void free(void *)
void delete_directory(const std::string &path)
deletes all files in &#39;path&#39; and then the directory itself
Definition: file_util.cpp:95
std::wstring utf8_to_utf16_little_endian(const std::string &in)
Definition: unicode.cpp:283
void * malloc(size_t)