2 * Copyright 2012 Aleksas Pantechovskis, <alexp.frl@gmail.com>
3 * All rights reserved. Distributed under the terms of the MIT License.
14 #include <ByteOrder.h>
15 #include <FindDirectory.h>
18 #include <TypeConstants.h>
24 const char* kUsageMessage
= \
26 "# proj2make <projPath> [makePath]\n"
27 "# if makePath parameter doesn't specified makefile will be created in\n"
28 "# the same directory as .proj file\n"
29 "# example: proj2make /boot/home/myprog/myprog.proj\n";
37 fstream gTemplateFile
;
45 const char* gAppTypes
[] = {
58 static_cast<uint32
>(B_BENDIAN_TO_HOST_INT32(fId
)); }
59 uint32
Size() { return
60 static_cast<uint32
>(B_BENDIAN_TO_HOST_INT32(fSize
)); }
61 const char* Data() { return (char*)(this + 1); }
68 class Error
: public std::exception
72 Error(const char* what
, ...);
73 virtual ~Error() throw() {}
74 virtual const char* what() const throw() { return fWhat
.String(); }
78 Error::Error(const char* what
, ...)
80 const int size
= 1024;
83 vsnprintf(fWhat
.LockBuffer(size
), size
, what
, args
);
90 CheckFiles(const char* projPath
, const char* makePath
)
92 gProjFile
.open(projPath
, fstream::in
| fstream::binary
);
93 if (!gProjFile
.is_open())
94 throw Error("%s not found", projPath
);
96 gProjFile
.seekg(0, ios::end
);
97 uint32 projFileLength
= gProjFile
.tellg();
98 gProjFile
.seekg(0, ios::beg
);
100 char* name
= new char[5];
101 gProjFile
.read(name
, 4);
104 gProjFile
.read((char*)&length
, 4);
106 length
= static_cast<uint32
>(B_BENDIAN_TO_HOST_INT32(length
));
107 gProjLength
= length
+ 8;
109 if (strcmp(name
, "MIDE") != 0 || gProjLength
> projFileLength
)
110 throw Error("File corrupted or it is not BeIDE *.proj file");
112 gMakeFile
.open(makePath
, fstream::in
);
113 if (gMakeFile
.is_open())
114 throw Error("%s already exists", makePath
);
116 gMakeFile
.open(makePath
, fstream::out
);
117 if (!gMakeFile
.is_open())
118 throw Error("Can not create makefile");
120 BPath templateFileName
;
121 // not supporter yet in my haiku rev
122 // find_directory(B_SYSTEM_DEVELOP_DIR, &templateFileName);
123 // templateFileName.Append("etc/makefile");
124 templateFileName
.SetTo("/boot/develop/etc/makefile");
126 gTemplateFile
.open(templateFileName
.Path(), fstream::in
);
127 if (!gTemplateFile
.is_open())
128 throw Error("Can not open template %s", templateFileName
.Path());
135 hdr
* child
= (hdr
*)data
->Data();
136 char* name
= (char*)(child
+ 1);
137 int len
= strlen(name
) + 1;
139 uint32 u
= child
->Id();
141 printf("\t%c%c%c%c:%d:%s\n", c
[3], c
[2], c
[1], c
[0], child
->Size(), name
);
143 if (strncmp(name
, "ProjectPrefsx86", len
- 1) == 0) {
144 const char* type
= child
->Data() + len
+ 8;
148 type
+= 64; // skip the mime type name
158 ~_l() { _s
.resize(_s
.size() - 1); }
160 char* str() { _s
.c_str(); }
166 Parse(hdr
* current
, hdr
* parent
)
170 uint32 u
= current
->Id();
172 printf("%#06x:%s%c%c%c%c:%d\n",
173 (uint8
*)current
- gProjData
, l
.str(),
174 c
[3], c
[2], c
[1], c
[0], current
->Size());
176 bool useGrandParent
= false;
178 switch(current
->Id()) {
190 useGrandParent
= true;
193 gSPthString
+= " \\\n\t";
194 gSPthString
+= ¤t
->Data()[5];
197 gPPthString
+= " \\\n\t";
198 gPPthString
+= ¤t
->Data()[5];
201 if (parent
->Id() == 'Fil1') {
202 gFil1String
+= " \\\n\t";
203 gFil1String
+= ¤t
->Data()[4];
204 } else if (parent
->Id() == 'Link') {
205 gLinkString
+= " \\\n\t";
206 gLinkString
+= ¤t
->Data()[4];
207 } else if (parent
->Id() == 'PLnk') {
208 gPLnkString
+= " \\\n\t";
209 gPLnkString
+= ¤t
->Data()[4];
219 hdr
* child
= (hdr
*)(current
->Data() + off
);
220 while (off
< current
->Size()) {
221 Parse(child
, useGrandParent
? parent
: current
);
222 off
+= child
->Size() + sizeof(hdr
);
223 child
= (hdr
*)(child
->Data() + child
->Size());
231 gProjFile
.seekg(0, ios::beg
);
232 gProjData
= new uint8
[gProjLength
];
233 gProjFile
.read((char*)gProjData
, gProjLength
);
236 Parse((hdr
*)gProjData
, NULL
);
251 while (gTemplateFile
.good()) {
252 getline(gTemplateFile
, str
);
254 if (str
.find("SRCS") == 0)
255 str
= str
+ gFil1String
;
256 else if (str
.find("LIBS") == 0)
257 str
= str
+ gLinkString
;
258 else if (str
.find("SYSTEM_INCLUDE_PATHS") == 0)
259 str
= str
+ gSPthString
;
260 else if (str
.find("LOCAL_INCLUDE_PATHS") == 0)
261 str
= str
+ gPPthString
;
262 else if (str
.find("TYPE") == 0)
263 str
= str
+ gAppTypes
[gAppType
];
264 else if (str
.find("NAME") == 0)
265 str
= str
+ gAppName
;
266 else if (str
.find("RSRCS") == 0)
267 str
= str
+ gPLnkString
;
269 gMakeFile
<< str
<< endl
;
273 gTemplateFile
.close();
278 main(int argc
, char** argv
)
281 if (argc
<= 1 || (argc
> 1 && strcmp(argv
[1], "--help") == 0))
284 BString projPath
= argv
[1];
287 // if makefile path specified
290 // default makefile path
293 path
.GetParent(&path
);
294 path
.Append("makefile");
295 makePath
= path
.Path();
298 CheckFiles(projPath
.String(), makePath
.String());
302 } catch(exception
& exc
) {
303 cerr
<< argv
[0] << " : " << exc
.what() << endl
;
304 cerr
<< kUsageMessage
;