Newer
Older
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
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
#include <unistd.h>
#include <fstream>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>
namespace util
{
using namespace std;
namespace internal
{
extern const char * error_prefix;
}
/************************************************************************/
/* Comparator for case-insensitive comparison in STL assos. containers */
/* From Abhay: */
/* http://stackoverflow.com/questions/1801892/making-mapfind-operation-case-insensitive */
/************************************************************************/
struct ci_less : std::binary_function<std::string, std::string, bool>
{
// case-independent (ci) compare_less binary function
struct nocase_compare : public std::binary_function<unsigned char,unsigned char,bool>
{
bool operator() (const unsigned char& c1, const unsigned char& c2) const
{
return tolower (c1) < tolower (c2);
}
};
bool operator() (const std::string & s1, const std::string & s2) const
{
return std::lexicographical_compare
(s1.begin (), s1.end (), // source range
s2.begin (), s2.end (), // dest range
nocase_compare ()); // comparison
}
};
/**
* Here we create a useful and easily understanable alias for the map.
**/
typedef map<string, vector<string>, ci_less> FileMap;
typedef map<string, bool, ci_less> OptionsMap;
// EXEC()
int8_t exec(int redirect_fd, const char * command,
const char * arg1 = NULL,
const char * arg2 = NULL,
const char * arg3 = NULL,
const char * arg4 = NULL,
const char * arg5 = NULL,
const char * arg6 = NULL);
inline
int8_t exec(const char * command,
const char * arg1 = NULL,
const char * arg2 = NULL,
const char * arg3 = NULL,
const char * arg4 = NULL,
const char * arg5 = NULL,
const char * arg6 = NULL)
{ return exec(STDOUT_FILENO, command, arg1, arg2, arg3, arg4, arg5, arg6); }
inline int8_t exec(const string & command) { return exec(command.c_str()); }
inline int8_t exec(const string & command, const string & arg1) { return exec(command.c_str(), arg1.c_str()); }
inline int8_t exec(const string & command, const string & arg1, const string & arg2) { return exec(command.c_str(), arg1.c_str(), arg2.c_str()); }
inline int8_t exec(const string & command, const string & arg1, const string & arg2, const string & arg3) { return exec(command.c_str(), arg1.c_str(), arg2.c_str(), arg3.c_str()); }
inline int8_t exec(const string & command, const string & arg1, const string & arg2, const string & arg3, const string & arg4) { return exec(command.c_str(), arg1.c_str(), arg2.c_str(), arg3.c_str(), arg4.c_str()); }
inline int8_t exec(const string & command, const string & arg1, const string & arg2, const string & arg3, const string & arg4, const string & arg5) { return exec(command.c_str(), arg1.c_str(), arg2.c_str(), arg3.c_str(), arg4.c_str(), arg5.c_str()); }
inline int8_t exec(const string & command, const string & arg1, const string & arg2, const string & arg3, const string & arg4, const string & arg5, const string & arg6) { return exec(command.c_str(), arg1.c_str(), arg2.c_str(), arg3.c_str(), arg4.c_str(), arg5.c_str(), arg6.c_str()); }
inline int8_t exec(int redirect_fd, const string & command) { return exec(redirect_fd, command.c_str()); }
inline int8_t exec(int redirect_fd, const string & command, const string & arg1) { return exec(redirect_fd, command.c_str(), arg1.c_str()); }
inline int8_t exec(int redirect_fd, const string & command, const string & arg1, const string & arg2) { return exec(redirect_fd, command.c_str(), arg1.c_str(), arg2.c_str()); }
inline int8_t exec(int redirect_fd, const string & command, const string & arg1, const string & arg2, const string & arg3) { return exec(redirect_fd, command.c_str(), arg1.c_str(), arg2.c_str(), arg3.c_str()); }
inline int8_t exec(int redirect_fd, const string & command, const string & arg1, const string & arg2, const string & arg3, const string & arg4) { return exec(redirect_fd, command.c_str(), arg1.c_str(), arg2.c_str(), arg3.c_str(), arg4.c_str()); }
inline int8_t exec(int redirect_fd, const string & command, const string & arg1, const string & arg2, const string & arg3, const string & arg4, const string & arg5) { return exec(redirect_fd, command.c_str(), arg1.c_str(), arg2.c_str(), arg3.c_str(), arg4.c_str(), arg5.c_str()); }
inline int8_t exec(int redirect_fd, const string & command, const string & arg1, const string & arg2, const string & arg3, const string & arg4, const string & arg5, const string & arg6) { return exec(redirect_fd, command.c_str(), arg1.c_str(), arg2.c_str(), arg3.c_str(), arg4.c_str(), arg5.c_str(), arg6.c_str()); }
// FILESYSTEM FUNCTIONS
void assertExists(const string & path, int exit_code = -1);
bool exists(const string & path);
mode_t permissions(const string & path);
void forceRemoveDir(string dir);
string getcwdstr();
void copyFile(const string & source, const string & dest);
void copyFiles(const string & sourceFolder, const string & destFolder, const vector<string> & files);
void protectFiles(const string & folder, const vector<string> & files);
void protectDir(const string & dir);
void linkDirs(const string & sourceFolder, const string & destFolder, const vector<string> & dirs);
vector<string> get_files_in_dir(const string & dir);
bool is_symlink(const string & file);
string get_symlink_target(const string & symlink);
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
// STRING REPLACEMENT
bool replaceFirst(string & str, const string & toreplace, const string & with);
size_t replaceAll (string & str, const string & toreplace, const string & with);
size_t replaceAllInternal(string & str, const string & toreplace, const string & with);
size_t findNthLast(const string & str, char c, size_t n);
vector<string> tokenize(const string & str, char delim);
// IO OPERATIONS
string read_string_from_FILE(FILE * file, size_t max_length = -1);
void write_string_to_FILE(FILE * file, const char * str);
ssize_t writeBytesToFile(signed int fileDescriptor, const char * buffer, unsigned int bufferLength);
ssize_t writen(int fd, const void *vptr, size_t n);
ssize_t write(int fd, const string & str);
ssize_t write(int fd, int val);
ssize_t write(int fd, long val);
ssize_t readn(int fd, void *vptr, size_t n);
ssize_t read(int fd, int & val);
ssize_t read(int fd, long & val);
// STRING TYPE OPERATIONS
int intlen(unsigned int a);
void makeLower(string & str);
string toLower(const string & str);
// String concatenation
template <typename T>
string to_string(const T & value);
string operator+(const string & lhs, const string & rhs); // These 5 functions are to disambiguate
string operator+(const string & lhs, const char * rhs); // operator+ so that the following
string operator+(const string & lhs, char rhs); // templates may exist
string operator+(const char * lhs, const string & rhs);
string operator+(char lhs, const string & rhs);
template <typename T>
string & operator+=(string & str, const T & value);
template <typename T>
string operator+(const string & str, const T & value);
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
// CONFIGURATION
void readConfig(const string & testsFolder, FileMap & map, const string & discriminator = "");
void readFile(const string & file, vector<string> & lines);
string readFile(const string & filename);
void readFileGeneric(const string & file, FileMap * map, vector<string> * lines, const string & discriminator = "");
char * processOptions(int argc, char ** argv, OptionsMap & opts, vector<string> & args);
// AUTOGRADER
// STUDENT CODE COMPILATION FUNCTIONS
void rename_main(const string & file, const string & newname);
// MACROS
void SET_ERROR_MESSAGE(const char * message);
#define STRINGIFY1(p) #p
#define STR(p) STRINGIFY1(p)
namespace internal
{
template<typename StrType>
void exit_if_error_output(const char * file, int32_t line, StrType message);
}
#define EXIT_IF_ERROR2(statement_check, message) \
do { \
errno = 0; \
if ((statement_check) || errno != 0) \
util::internal::exit_if_error_output(__FILE__, __LINE__, message); \
} while (0)
#define EXIT_IF_ERROR1(statement_check) \
EXIT_IF_ERROR2(statement_check, #statement_check)
// Crazy hack for overloading!
// Arg counting from:
// http://cplusplus.co.il/2010/07/17/variadic-macro-to-count-number-of-arguments/
// Overloading tips:
// http://stackoverflow.com/questions/3046889/optional-parameters-with-c-macros
#define EXIT_IF_ERROR_THIRD_ARG(a, b, c, ...) c
#define EXIT_IF_ERROR(...) \
EXIT_IF_ERROR_THIRD_ARG(__VA_ARGS__, \
EXIT_IF_ERROR2, \
EXIT_IF_ERROR1, 0) (__VA_ARGS__)
// Colorization
namespace colorize
{
extern const char * BLACK;
extern const char * GREEN;
extern const char * RED;
extern const bool is_color_enabled;
inline string make_color(const char * color, const string & str)
{
return (is_color_enabled ? color + str + BLACK : str);
}
} // namespace colorize
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
// INLINE IMPLEMENTATIONS
// Originally by radu
// http://notfaq.wordpress.com/2006/08/30/c-convert-int-to-string/
template <typename T>
inline string to_string(const T & value)
{
stringstream ss;
ss << value;
return ss.str();
}
inline int intlen(unsigned int a)
{
int len = 1;
a /= 10;
while (a != 0)
{
a = a/10;
len++;
}
return len;
}
inline ssize_t write(int fd, const string & str)
{
return writen(fd, str.c_str(), str.length()+1);
}
inline ssize_t write(int fd, int val)
{
return writen(fd, &val, sizeof val);
}
inline ssize_t write(int fd, long val)
{
return writen(fd, &val, sizeof val);
}
inline ssize_t read(int fd, int & val)
{
return readn(fd, &val, sizeof val);
}
inline ssize_t read(int fd, long & val)
{
return readn(fd, &val, sizeof val);
}
template <typename T, typename C, typename BinaryOp>
T accumulate(const C & collect, BinaryOp op, T init)
{
typename C::const_iterator it = collect.begin();
typename C::const_iterator end = collect.end();
while (it != end)
init = init + *it++;
return init;
}
inline string operator+(const string & lhs, const string & rhs) { return std::operator+(lhs, rhs); }
inline string operator+(const string & lhs, const char * rhs) { return std::operator+(lhs, rhs); }
inline string operator+(const string & lhs, char rhs) { return std::operator+(lhs, rhs); }
inline string operator+(char lhs, const string & rhs) { return std::operator+(lhs, rhs); }
inline string operator+(const char * lhs, const string & rhs) { return std::operator+(lhs, rhs); }
template <typename T>
inline std::string & operator+=(std::string & str, const T & value)
{
str += util::to_string(value);
return str;
template <typename T>
inline std::string operator+(const std::string & str, const T & value)
{
std::stringstream ss;
ss << str << value;
return ss.str();
}
inline uint64_t process_clock()
{
#ifdef CLOCK_PROCESS_CPUTIME_ID
timespec ts;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
return ts.tv_sec * 1000000 + (ts.tv_nsec + 500) / 1000;
#else
return clock();
#endif
}