17 #include "cpp_lexer.hpp"
29 void getTokenData(
const char* fname, vector<char>& vdata);
30 string getmd5hash(
const char* fname,
const vector<char>& vbasedata);
32 int main(
int argc,
char* argv[])
35 cerr <<
"No filename given" << endl
36 <<
"cpp-gen-md5 [common-string] [shared-filename] [filename1 define1] [filename2 define2]* ..." << endl
37 <<
"Generates a md5 sum from the lexical tokens of a C++ ignoring directives and whitespace." << endl
38 <<
"If only a filename is given, will output a 16 byte string" << endl
39 <<
"If both filename and define are given will output #define @define2@ \"@md5hash@\"" << endl;
43 vector<char> vbasedata;
44 vbasedata.resize(strlen(argv[1]));
45 if( vbasedata.size() > 0 ) {
46 memcpy(&vbasedata[0],argv[1],vbasedata.size());
48 if( strlen(argv[2]) > 0 ) {
51 for(
int i = 3; i < argc; i += 2) {
52 vector<char> vdata=vbasedata;
58 cout <<
"#define " << argv[i+1] <<
" \"" << md5hash <<
"\"" << endl;
61 cout << md5hash << endl;
71 FILE* f = fopen(fname,
"rb");
73 cerr <<
"Cannot open input file: " << fname << endl;
77 fseek(f, 0, SEEK_END);
78 int const size = ftell(f);
79 fseek(f, 0, SEEK_SET);
80 vector<char> buf(size);
81 size_t read = fread(&buf[0], 1, size, f);
83 if( read == 0 || read != size ) {
88 cpp::lexer_iterator first(cpp::NewLexer(&buf[0], &buf[0]+buf.size(), fname));
89 cpp::lexer_iterator last;
91 while (first != last) {
92 cpp::Token
const& token = *first;
94 case cpp::Unknown_token:
95 case cpp::Directive_token:
98 case cpp::Comment_token:
101 vdata.push_back(token.id&0xff);
102 if( token.id&0xffff00) {
103 vdata.push_back((token.id>>8)&0xff);
104 vdata.push_back((token.id>>16)&0xff);
106 vdata.push_back((token.id>>24)&0xff);
108 if( (token.id&cpp::TokenTypeMask) == cpp::OperatorTokenType ) {
111 if( (token.id&cpp::TokenTypeMask) == cpp::IdentifierTokenType ) {
112 if (token.id < cpp::Kwd_last) {
116 for(
size_t i = 0; i < token.text.size(); ++i) {
117 vdata.push_back(token.text[i]);
125 string getmd5hash(
const char* fname,
const vector<char>& vbasedata)
127 vector<char> vdata = vbasedata;
128 vdata.reserve(vdata.capacity()+10000);
132 md5_byte_t digest[16];
135 md5_append(&state, (
const md5_byte_t *)&vdata[0], vdata.size());
136 md5_finish(&state, digest);
137 char hex_output[16*2+1];
138 for (
int di = 0; di < 16; ++di) {
139 sprintf(hex_output + di * 2,
"%02x", digest[di]);
141 return string(hex_output);