Fixed extracting common.MPQ under *nix
[getmangos.git] / src / tools / gensvnrevision / gensvnrevision.cpp
blobdaca90119f954fe401fc0f6f0cee97f905d52ef7
1 /*
2 * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include <fstream>
20 #include <sstream>
21 #include <time.h>
23 #pragma warning(disable:4996)
25 struct RawData
27 char rev_str[200];
28 char date_str[200];
29 char time_str[200];
32 void extractDataFromSvn(FILE* EntriesFile, bool url, RawData& data)
34 char buf[200];
36 char repo_str[200];
37 char num_str[200];
39 fgets(buf,200,EntriesFile);
40 fgets(buf,200,EntriesFile);
41 fgets(buf,200,EntriesFile);
42 fgets(buf,200,EntriesFile); sscanf(buf,"%s",num_str);
43 fgets(buf,200,EntriesFile); sscanf(buf,"%s",repo_str);
44 fgets(buf,200,EntriesFile);
45 fgets(buf,200,EntriesFile);
46 fgets(buf,200,EntriesFile);
47 fgets(buf,200,EntriesFile);
48 fgets(buf,200,EntriesFile); sscanf(buf,"%10sT%8s",data.date_str,data.time_str);
50 if(url)
51 sprintf(data.rev_str,"%s at %s",num_str,repo_str);
52 else
53 strcpy(data.rev_str,num_str);
56 void extractDataFromGit(FILE* EntriesFile, std::string path, bool url, RawData& data)
58 char buf[200];
59 fgets(buf,200,EntriesFile);
61 char hash_str[200];
62 char branch_str[200];
63 char url_str[200];
64 sscanf(buf,"%s branch %s of %s",hash_str,branch_str,url_str);
66 if(url)
68 char* host_str = NULL;
69 char* acc_str = NULL;
70 char* repo_str = NULL;
72 // parse URL like git@github.com:mangos/mangos
73 char url_buf[200];
74 int res = sscanf(url_str,"git@%s",url_buf);
75 if(res)
77 host_str = strtok(url_buf,":");
78 acc_str = strtok(NULL,"/");
79 repo_str = strtok(NULL," ");
81 else
83 int res = sscanf(url_str,"git://%s",url_buf);
84 if(res)
86 host_str = strtok(url_buf,"/");
87 acc_str = strtok(NULL,"/");
88 repo_str = strtok(NULL,".");
92 // can generate nice link
93 if(res)
94 sprintf(data.rev_str,"http://%s/%s/%s/commit/%s",host_str,acc_str,repo_str,hash_str);
95 // unknonw URL format, use as-is
96 else
97 sprintf(data.rev_str,"%s at %s",hash_str,url_str);
99 else
100 strcpy(data.rev_str,hash_str);
102 time_t rev_time = 0;
103 // extracting date/time
104 FILE* LogFile = fopen((path+".git/logs/HEAD").c_str(), "r");
105 if(LogFile)
107 while(fgets(buf,200,LogFile))
109 char buf2[200];
110 char new_hash[200];
111 int unix_time = 0;
112 int res2 = sscanf(buf,"%s %s %s %s %i",buf2,new_hash,buf2,buf2,&unix_time,buf2);
113 if(res2!=5)
114 continue;
116 if(strcmp(hash_str,new_hash))
117 continue;
119 rev_time = unix_time;
120 break;
123 fclose(LogFile);
125 if(rev_time)
127 tm* aTm = localtime(&rev_time);
128 // YYYY year
129 // MM month (2 digits 01-12)
130 // DD day (2 digits 01-31)
131 // HH hour (2 digits 00-23)
132 // MM minutes (2 digits 00-59)
133 // SS seconds (2 digits 00-59)
134 sprintf(data.date_str,"%04d-%02d-%02d",aTm->tm_year+1900,aTm->tm_mon+1,aTm->tm_mday);
135 sprintf(data.time_str,"%02d:%02d:%02d",aTm->tm_hour,aTm->tm_min,aTm->tm_sec);
137 else
139 strcpy(data.date_str,"Unknown");
140 strcpy(data.time_str,"Unknown");
143 else
145 strcpy(data.date_str,"Unknown");
146 strcpy(data.time_str,"Unknown");
150 bool extractDataFromSvn(std::string filename, bool url, RawData& data)
152 FILE* EntriesFile = fopen(filename.c_str(), "r");
153 if(!EntriesFile)
154 return false;
156 extractDataFromSvn(EntriesFile,url,data);
157 fclose(EntriesFile);
158 return true;
161 bool extractDataFromGit(std::string filename, std::string path, bool url, RawData& data)
163 FILE* EntriesFile = fopen(filename.c_str(), "r");
164 if(!EntriesFile)
165 return false;
167 extractDataFromGit(EntriesFile,path,url,data);
168 fclose(EntriesFile);
169 return true;
172 std::string generateHeader(char const* rev_str, char const* date_str, char const* time_str)
174 std::ostringstream newData;
175 newData << "#ifndef __SVN_REVISION_H__" << std::endl;
176 newData << "#define __SVN_REVISION_H__" << std::endl;
177 newData << " #define SVN_REVISION \"" << rev_str << "\"" << std::endl;
178 newData << " #define SVN_DATE \"" << date_str << "\"" << std::endl;
179 newData << " #define SVN_TIME \"" << time_str << "\""<< std::endl;
180 newData << "#endif // __SVN_REVISION_H__" << std::endl;
181 return newData.str();
184 int main(int argc, char **argv)
186 bool use_url = false;
187 bool svn_prefered = false;
188 std::string path;
190 // Call: tool {options} [path]
191 // -g use git prefered (default)
192 // -s use svn prefered
193 // -r use only revision (without repo URL) (default)
194 // -u include repositire URL as commit URL or "rev at URL"
195 for(int k = 1; k <= argc; ++k)
197 if(!argv[k] || !*argv[k])
198 break;
200 if(argv[k][0]!='-')
202 path = argv[k];
203 if(path.size() > 0 && (path[path.size()-1]!='/' || path[path.size()-1]!='\\'))
204 path += '/';
205 break;
208 switch(argv[k][1])
210 case 'g':
211 svn_prefered = false;
212 continue;
213 case 'r':
214 use_url = false;
215 continue;
216 case 's':
217 svn_prefered = true;
218 continue;
219 case 'u':
220 use_url = true;
221 continue;
222 default:
223 printf("Unknown option %s",argv[k]);
224 return 1;
228 /// new data extraction
229 std::string newData;
232 RawData data;
234 bool res = false;
236 if(svn_prefered)
238 /// SVN data
239 res = extractDataFromSvn(path+".svn/entries",use_url,data);
240 if (!res)
241 res = extractDataFromSvn(path+"_svn/entries",use_url,data);
242 // GIT data
243 if (!res)
244 res = extractDataFromGit(path+".git/FETCH_HEAD",path,use_url,data);
246 else
248 // GIT data
249 res = extractDataFromGit(path+".git/FETCH_HEAD",path,use_url,data);
250 /// SVN data
251 if (!res)
252 res = extractDataFromSvn(path+".svn/entries",use_url,data);
253 if (!res)
254 res = extractDataFromSvn(path+"_svn/entries",use_url,data);
257 if(res)
258 newData = generateHeader(data.rev_str,data.date_str,data.time_str);
259 else
260 newData = generateHeader("Unknown", "Unknown", "Unknown");
263 /// get existed header data for compare
264 std::string oldData;
266 if(FILE* HeaderFile = fopen("svn_revision.h","rb"))
268 while(!feof(HeaderFile))
270 int c = fgetc(HeaderFile);
271 if(c < 0)
272 break;
273 oldData += (char)c;
276 fclose(HeaderFile);
279 /// update header only if different data
280 if(newData != oldData)
282 if(FILE* OutputFile = fopen("svn_revision.h","wb"))
284 fprintf(OutputFile,"%s",newData.c_str());
285 fclose(OutputFile);
289 return 0;