Newer
Older
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
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
#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;
class OptionsParser
{
private:
typedef map<string, bool*> optsMap_t;
typedef map<string, bool> valueMap_t;
valueMap_t valueMap; // not static to prevent still reachable memory
optsMap_t optsMap;
vector<string *> args;
public:
OptionsParser();
void addOption(const string & name, bool & setValue) { optsMap[name] = &setValue; }
void addArg(string & setValue) { args.push_back(&setValue); }
vector<string> parse(int argc, const char ** argv);
};
// 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 concatdir = true);
bool is_symlink(const string & file);
string get_symlink_target(const string & symlink);
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
// 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);
template <typename T>
T from_string(const string & s);
template <typename T, typename F>
T lexical_cast(const F & from);
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);
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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
// 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
// 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();
}
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
// http://stackoverflow.com/questions/5017001/like-atoi-but-to-float
template <typename T>
inline T from_string(const string & s)
{
stringstream ss(s);
T value;
ss >> value;
return value;
}
template <typename T, typename F>
inline T lexical_cast(const F & from)
{
T to;
stringstream ss;
if (!(ss << from))
{
cerr << "ERROR: Could not convert types" << endl;
return to;
}
if (!(ss >> to))
{
cerr << "ERROR: Could not convert types" << endl;
return to;
}
return to;
}
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
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
}