-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathgenerator.cpp
More file actions
115 lines (100 loc) · 3.41 KB
/
generator.cpp
File metadata and controls
115 lines (100 loc) · 3.41 KB
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
#include <fstream>
#include <iostream>
#include <brick-fs.h>
#include <cctype>
#include <algorithm>
#include <iterator>
using uchar = unsigned char;
std::string encode( uchar c ) {
std::string result = "\\x";
if ( ( (c >> 4) & 15 ) < 10 )
result += ( (c >> 4) & 15 ) + '0';
else
result += ( (c >> 4) & 15 ) - 10 + 'a';
if ( ( c & 15 ) < 10 )
result += ( c & 15 ) + '0';
else
result += ( c & 15 ) - 10 + 'a';
return result;
}
std::string stringify( const std::string &str ) {
std::string result;
for ( char c : str ) {
result += encode( c );
}
return result;
}
size_t stringify( std::ifstream &in, std::ofstream &out ) {
size_t length = 0;
std::for_each( std::istream_iterator< char >( in ), std::istream_iterator< char >(), [&]( char c ) {
out << encode( c );
++length;
} );
return length;
}
const char *resolveType( unsigned mode ) {
if ( ( mode & S_IFLNK ) == S_IFLNK )
return "SymLink";
if ( ( mode & S_IFREG ) == S_IFREG )
return "File";
if ( ( mode & S_IFIFO ) == S_IFIFO )
return "Pipe";
return nullptr;
}
int main( int argc, char **argv ) {
if ( argc > 3 ) {
std::cerr << "invalid number of arguments" << std::endl;
return -1;
}
std::ofstream file( "snapshot.cpp" );
file << "#include \"fs-manager.h\"\n"
<< "namespace divine{ namespace fs {\n"
<< "VFS vfs{\n";
if ( argc == 3 ) {
std::ifstream in( argv[ 2 ] );
file << "\"";
size_t length = stringify( in, file );
file << "\", " << length << ",{\n";
}
if ( argc >= 2 ) {
brick::fs::traverseDirectoryTree( argv[ 1 ],
[&]( std::string path ) {
auto shrinked = brick::fs::distinctPaths( argv[ 1 ], path );
if ( !shrinked.empty() ) {
auto st = brick::fs::stat( path );
file << "{\"" << stringify( shrinked ) << "\", Type::Directory, " << st->st_mode << ", nullptr, 0 },\n";
}
return true;
},
[]( std::string ){},
[&]( std::string path ) {
auto st = brick::fs::lstat( path );
const char *type = resolveType( st->st_mode );
file << "{\"" << stringify( brick::fs::distinctPaths( argv[ 1 ], path ) ) << "\", Type::" << type << ", "<< st->st_mode << ", ";
if ( std::string( "File" ) == type ) {
file << "\"";
std::ifstream input( path, std::ios::binary );
input >> std::noskipws;
size_t length = stringify( input, file );
file << "\", " << length;
}
else if ( std::string( "Pipe" ) == type ) {
file << "\"\", 0";
}
else if ( std::string( "SymLink" ) == type ) {
std::string link( st->st_size, '-' );
readlink( path.c_str(), &link.front(), st->st_size );
file << "\"" << stringify( link ) << "\", " << st->st_size;
}
else
file << "nullptr, 0";
file << "},\n";
}
);
}
file << "{ nullptr, Type::Nothing, 0, nullptr, 0 }";
if ( argc == 3 )
file << "}";
file <<"};}}\n" << std::endl;
return 0;
}