-
-
Notifications
You must be signed in to change notification settings - Fork 116
/
file.h
189 lines (167 loc) · 5.29 KB
/
file.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/* file.h - file abstraction layer */
#ifndef FILE_H
#define FILE_H
#include <stdint.h>
#include <stdio.h>
#include <wchar.h> /* for wchar_t */
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _WIN32
typedef wchar_t file_tchar;
# define SYS_PATH_SEPARATOR '\\'
# define ALIEN_PATH_SEPARATOR '/'
# define IS_PATH_SEPARATOR(c) ((c) == '\\' || (c) == '/')
# define IS_PATH_SEPARATOR_W(c) ((c) == L'\\' || (c) == L'/')
#else
typedef char file_tchar;
# define SYS_PATH_SEPARATOR '/'
# define ALIEN_PATH_SEPARATOR '\\'
# define IS_PATH_SEPARATOR(c) ((c) == '/')
#endif /* _WIN32 */
typedef file_tchar* tpath_t;
typedef const file_tchar* ctpath_t;
/* Generic path functions */
char* make_path(const char* dir, const char* filename, unsigned flags);
#ifdef _WIN32
tpath_t make_wpath(ctpath_t dir_path, size_t dir_len, ctpath_t sub_path);
# define make_tpath(dir_path, sub_path) make_wpath(dir_path, (size_t)-1, sub_path)
#else
# define make_tpath(dir_path, sub_path) make_path(dir_path, sub_path, FileInitUseRealPathAsIs)
#endif /* _WIN32 */
const char* get_basename(const char* path);
/**
* Portable file information.
*/
typedef struct file_t
{
tpath_t real_path;
const char* print_path;
#ifdef _WIN32
const char* native_path; /* print_path in native encoding */
#endif
char* data;
uint64_t size;
uint64_t mtime;
unsigned mode;
} file_t;
/* bit constants for the file_t.mode bit mask */
enum FileModeBits {
FileIsDir = 0x01,
FileIsLnk = 0x02,
FileIsReg = 0x04,
FileIsInaccessible = 0x08,
FileIsRoot = 0x10,
FileIsData = 0x20,
FileIsList = 0x40,
FileIsStdStream = 0x80,
FileIsStdin = FileIsStdStream,
FileContentIsUtf8 = 0x100,
FileInitReusePath = 0x1000,
FileInitUtf8PrintPath = 0x2000,
FileInitRunFstat = 0x4000,
FileInitRunLstat = 0x8000,
FileInitUpdatePrintPathLastSlash = 0x10000,
FileInitUpdatePrintPathSlashes = 0x20000,
FileInitUseRealPathAsIs = 0x40000,
FileMaskUpdatePrintPath = (FileInitUpdatePrintPathLastSlash | FileInitUpdatePrintPathSlashes),
FileMaskStatBits = (FileIsDir | FileIsLnk | FileIsReg | FileIsInaccessible),
FileMaskIsSpecial = (FileIsData | FileIsList | FileIsStdStream),
FileMaskModeBits = (FileMaskStatBits | FileIsRoot | FileMaskIsSpecial | FileContentIsUtf8),
FileMaskSavedChar = 0xff000000,
};
#define FILE_ISDIR(file) ((file)->mode & FileIsDir)
#define FILE_ISLNK(file) ((file)->mode & FileIsLnk)
#define FILE_ISREG(file) ((file)->mode & FileIsReg)
#define FILE_ISBAD(file) ((file)->mode & FileIsInaccessible)
#define FILE_ISDATA(file) ((file)->mode & FileIsData)
#define FILE_ISLIST(file) ((file)->mode & FileIsList)
#define FILE_ISSTDIN(file) ((file)->mode & FileIsStdin)
#define FILE_ISSTDSTREAM(file) ((file)->mode & FileIsStdStream)
#define FILE_ISSPECIAL(file) ((file)->mode & (FileMaskIsSpecial))
#define FILE_IS_IN_UTF8(file) ((file)->mode & (FileContentIsUtf8))
/* file functions */
int file_init(file_t* file, ctpath_t path, unsigned init_flags);
int file_init_by_print_path(file_t* file, file_t* prepend_dir, const char* print_path, unsigned init_flags);
void file_cleanup(file_t* file);
void file_clone(file_t* file, const file_t* orig_file);
void file_swap(file_t* first, file_t* second);
int are_paths_equal(ctpath_t path, struct file_t* file);
enum FileGetPrintPathFlags {
FPathPrimaryEncoding = 0,
FPathUtf8 = 0x1,
FPathNative = 0x2,
FPathBaseName = 0x4,
FPathDirName = 0x8,
FPathNotNull = 0x10,
FPathReal = 0x20,
};
const char* file_get_print_path(file_t* file, unsigned flags);
enum FileModifyOperations {
FModifyAppendSuffix,
FModifyInsertBeforeExtension,
FModifyRemoveExtension,
FModifyGetParentDir,
};
int file_modify_path(file_t* dst, file_t* src, const char* str, int operation);
enum FileStatModes {
FNoMode = 0,
FUseLstat = FileInitRunLstat,
};
int file_stat(file_t* file, int fstat_flags);
enum FileFOpenModes {
FOpenRead = 1,
FOpenWrite = 2,
FOpenBin = 4,
FOpenMask = 7,
FOpenRW = FOpenRead | FOpenWrite,
FOpenReadBin = FOpenRead | FOpenBin,
FOpenWriteBin = FOpenWrite | FOpenBin,
FOpenRWBin = FOpenRW | FOpenBin,
};
FILE* file_fopen(file_t* file, int fopen_flags);
int file_rename(const file_t* from, const file_t* to);
int file_move_to_bak(file_t* file);
int file_is_readable(file_t* file);
/**
* A file list iterator.
*/
typedef struct file_list_t
{
FILE* fd;
file_t current_file;
unsigned state;
} file_list_t;
int file_list_open(file_list_t* list, file_t* file);
int file_list_read(file_list_t* list);
void file_list_close(file_list_t* list);
#ifndef _WIN32
# define dirent_get_tname(d) ((d)->d_name)
# define rsh_topendir(p) opendir(p)
#else
/* readdir structures and functions */
# define DIR WIN_DIR
# define dirent win_dirent
# define opendir win_opendir
# define readdir win_readdir
# define closedir win_closedir
# define dirent_get_tname(d) ((d)->d_wname)
# define rsh_topendir(p) win_wopendir(p)
/* dirent struct for windows to traverse directory content */
struct win_dirent
{
char* d_name; /* file name */
wchar_t* d_wname; /* file name in Unicode (UTF-16) */
int d_isdir; /* non-zero if file is a directory */
};
struct WIN_DIR_t;
typedef struct WIN_DIR_t WIN_DIR;
WIN_DIR* win_opendir(const char*);
WIN_DIR* win_wopendir(const wchar_t*);
struct win_dirent* win_readdir(WIN_DIR*);
void win_closedir(WIN_DIR*);
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* FILE_H */