/[projet1]/public/pc/tools/osdk/main/makedisk/FloppyBuilder.cpp
Defence Force logotype

Contents of /public/pc/tools/osdk/main/makedisk/FloppyBuilder.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1072 - (show annotations)
Wed Jan 8 21:07:43 2014 UTC (6 years ago) by dbug
File size: 11218 byte(s)
FloppyBuilder 0.13
- Added a new parameter to make it possible to bootstrap the floppy building process: With 'init' a description fill be generated even if data is missing,
this makes it possible to do a multi-pass build process which will not fail because it depends on things not yet generated :)

1
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <sstream>
6 #include <iostream>
7 #include <vector>
8
9 #include "infos.h"
10 #include "common.h"
11 #include "Floppy.h"
12
13
14 // while (std::getline(iss,item,' '))
15 bool GetNextToken(std::string& returnedToken,std::string& restOfLine,int lineNumber)
16 {
17 returnedToken.clear();
18
19 const char* startOfLine =restOfLine.c_str();
20 const char* currentPosition=startOfLine;
21 char car;
22
23 // First skip all the white space stuff
24 while ( (car=*currentPosition) && ( (car==' ') || (car=='\t') ) )
25 {
26 ++currentPosition;
27 }
28
29 // Then depending of the character we have, we need a terminator token
30 if (car)
31 {
32 char match =0;
33
34 if (car=='"')
35 {
36 match='"';
37 }
38 else
39 if (car=='{')
40 {
41 match='}';
42 }
43 else
44 if (car=='[')
45 {
46 match =']';
47 }
48
49 while ( (car=*currentPosition) && ( (match && (car!=match)) || ( (!match) && ((car!=' ') && (car!='\t')) ) ) )
50 {
51 returnedToken.push_back(car);
52 ++currentPosition;
53 }
54
55 if (match && (car==match))
56 {
57 // Including the matching character
58 returnedToken.push_back(car);
59 ++currentPosition;
60 car=*currentPosition;
61 }
62
63 if (car)
64 {
65 // We have reach the end of the token, just make sure there's a white space behind
66 if ((car==' ') || (car=='\t'))
67 {
68 restOfLine=currentPosition;
69 }
70 else
71 {
72 // Parse error
73 ShowError("Parse error line '%d'\n",lineNumber);
74 }
75 }
76 else
77 {
78 // End of Line
79 restOfLine.clear();
80 }
81 return true;
82 }
83 return false;
84 }
85
86 void main(int argc, char *argv[])
87 {
88 //
89 // Some initialization for the common library
90 //
91 SetApplicationParameters(
92 "FloppyBuilder",
93 TOOL_VERSION_MAJOR,
94 TOOL_VERSION_MINOR,
95 "{ApplicationName} - Version {ApplicationVersion} - This program is a part of the OSDK\r\n"
96 "\r\n"
97 "Author:\r\n"
98 " (c) 2002 Debrune Jerome for the initial version \r\n"
99 " (c) 2013 Pointier Mickael for the subsequent changes \r\n"
100 "\r\n"
101 "Purpose:\r\n"
102 " Generating bootable floppies for the Oric computer.\r\n"
103 "\r\n"
104 "Usage:\r\n"
105 " {ApplicationName} <init|build> <description file path>\r\n"
106 "\r\n"
107 );
108
109 // makedisk filetobuild.txt default.dsk ..\build\%OSDKDISK%
110
111 long param=1;
112
113 if (argc>1)
114 {
115 for (;;)
116 {
117 long nb_arg=argc;
118 const char *ptr_arg=argv[param];
119
120 if (nb_arg==argc) break;
121 }
122 }
123
124
125 if (argc!=3)
126 {
127 ShowError(nullptr);
128 }
129
130 Floppy floppy;
131
132 if (!strcmp(argv[param],"init"))
133 {
134 floppy.AllowMissingFiles(true);
135 }
136 else
137 if (!strcmp(argv[param],"build"))
138 {
139 floppy.AllowMissingFiles(false);
140 }
141 else
142 {
143 ShowError("The first parameter should be either 'init' or 'build'.");
144 }
145 param++;
146
147
148 //
149 // Open the description file
150 //
151 const char* description_name(argv[param]);
152 std::vector<std::string> script;
153 if (!LoadText(description_name,script))
154 {
155 ShowError("Can't load script file '%s'\n",description_name);
156 }
157
158
159 std::string outputLayoutFileName;
160 std::string targetFloppyDiskName;
161
162 int lineNumber=0;
163 for (auto it(script.begin());it!=script.end();++it)
164 {
165 ++lineNumber;
166
167 std::string currentLine(*it);
168
169 std::size_t found = currentLine.find(";");
170 if (found!=std::string::npos)
171 {
172 // Comments, just skip them
173 currentLine=currentLine.substr(0,found);
174 }
175
176 std::istringstream iss(currentLine);
177
178 std::map<std::string,std::string> metadata;
179 std::string item;
180 std::vector<std::string> tokens;
181 //while (std::getline(iss,item,' '))
182 while (GetNextToken(item,currentLine,lineNumber))
183 {
184 // Remove eventual superfluous spaces and tabs
185 item=StringTrim(item);
186 if (!item.empty())
187 {
188 if ( ((*item.begin())=='[') && ((*item.rbegin())==']') )
189 {
190 // Let's say it's metadata
191 std::string metaItem=StringTrim(item,"[]");
192 std::size_t found = metaItem.find(":");
193 if (found!=std::string::npos)
194 {
195 // Comments, just skip them
196 std::string key =metaItem.substr(0,found);
197 std::string value=metaItem.substr(found+1);
198 metadata[key]=value;
199 }
200 else
201 {
202 ShowError("Syntax error line (%d), found invalid '%s' metadata format, should be '[key:value]'\n",lineNumber,item.c_str());
203 }
204 }
205 else
206 {
207 // Let's say it's an actual parameter
208 tokens.push_back(item);
209 }
210 }
211 }
212
213 if (!tokens.empty())
214 {
215 if (tokens[0]=="LoadDiskTemplate")
216 {
217 if (tokens.size()==2)
218 {
219 const std::string& templateFisk(tokens[1]);
220 if (!floppy.LoadDisk(templateFisk.c_str()))
221 {
222 ShowError("Can't load '%s'\n",templateFisk.c_str());
223 }
224
225 }
226 else
227 {
228 ShowError("Syntax error line (%d), syntax is 'LoadDiskTemplate FilePath' \n",lineNumber);
229 }
230 }
231 else
232 if (tokens[0]=="DefineDisk")
233 {
234 if (tokens.size()==4)
235 {
236 int numberOfSides =std::atoi(tokens[1].c_str());
237 int numberOfTracks =std::atoi(tokens[2].c_str());
238 int numberOfSectors =std::atoi(tokens[3].c_str());
239
240 if ( numberOfSides!=2 )
241 {
242 ShowError("Syntax error line (%d), numberOfSides has to be 2 (so far)\n",lineNumber);
243 }
244
245 /*
246 if ( numberOfTracks!=42 )
247 {
248 ShowError("Syntax error line (%d), numberOfTracks has to be 42 (so far)\n",lineNumber);
249 }
250 */
251
252 if ( numberOfSectors!=17 )
253 {
254 ShowError("Syntax error line (%d), numberOfSectors has to be 17 (so far)\n",lineNumber);
255 }
256
257 if (!floppy.CreateDisk(numberOfSides,numberOfTracks,numberOfSectors))
258 {
259 ShowError("Can't create the requested disk format\n");
260 }
261
262 }
263 else
264 {
265 ShowError("Syntax error line (%d), syntax is 'DefineDisk numberOfSides numberOfTracks numberOfSectors' \n",lineNumber);
266 }
267 }
268 else
269 if (tokens[0]=="OutputLayoutFile")
270 {
271 if (tokens.size()==2)
272 {
273 outputLayoutFileName=tokens[1];
274 }
275 else
276 {
277 ShowError("Syntax error line (%d), syntax is 'OutputLayoutFile FilePath' \n",lineNumber);
278 }
279 }
280 else
281 if (tokens[0]=="OutputFloppyFile")
282 {
283 if (tokens.size()==2)
284 {
285 targetFloppyDiskName=tokens[1];
286 }
287 else
288 {
289 ShowError("Syntax error line (%d), syntax is 'targetFloppyDiskName FilePath' \n",lineNumber);
290 }
291 }
292 else
293 if (tokens[0]=="SetPosition")
294 {
295 if (tokens.size()==3)
296 {
297 int currentTrack =std::atoi(tokens[1].c_str());
298 if ( (currentTrack<0) || (currentTrack>41) )
299 {
300 ShowError("Syntax error line (%d), TrackNumber has to be between 0 and 41' \n",lineNumber);
301 }
302 int currentSector=std::atoi(tokens[2].c_str());
303 if ( (currentSector<0) || (currentSector>41) )
304 {
305 ShowError("Syntax error line (%d), SectorNumber has to be between 1 and 17' \n",lineNumber);
306 }
307 floppy.SetPosition(currentTrack,currentSector);
308 }
309 else
310 {
311 ShowError("Syntax error line (%d), syntax is 'SetPosition TrackNumber SectorNumber' \n",lineNumber);
312 }
313 }
314 else
315 if (tokens[0]=="WriteSector")
316 {
317 if (tokens.size()==2)
318 {
319 std::string fileName=tokens[1];
320 if (!floppy.WriteSector(fileName.c_str()))
321 {
322 ShowError("Error line (%d), could not write file '%s' to disk. Make sure you have a valid floppy format declared. \n",lineNumber,fileName.c_str());
323 }
324 }
325 else
326 {
327 ShowError("Syntax error line (%d), syntax is 'WriteSector FilePath' \n",lineNumber);
328 }
329 }
330 else
331 if (tokens[0]=="AddFile")
332 {
333 if (tokens.size()==3)
334 {
335 std::string fileName=tokens[1];
336 int loadAddress=ConvertAdress(tokens[2].c_str());
337 if (!floppy.WriteFile(fileName.c_str(),loadAddress,false,metadata))
338 {
339 ShowError("Error line (%d), could not write file '%s' to disk. Make sure you have a valid floppy format declared. \n",lineNumber,fileName.c_str());
340 }
341 }
342 else
343 {
344 ShowError("Syntax error line (%d), syntax is 'AddFile FilePath LoadAddress' \n",lineNumber);
345 }
346 }
347 else
348 if (tokens[0]=="AddTapFile")
349 {
350 if (tokens.size()==2)
351 {
352 std::string fileName=tokens[1];
353 if (!floppy.WriteFile(fileName.c_str(),-1,true,metadata))
354 {
355 ShowError("Error line (%d), could not write file '%s' to disk. Make sure you have a valid floppy format declared. \n",lineNumber,fileName.c_str());
356 }
357 }
358 else
359 {
360 ShowError("Syntax error line (%d), syntax is 'AddTapFile FilePath' \n",lineNumber);
361 }
362 }
363 else
364 if (tokens[0]=="AddDefine")
365 {
366 if (tokens.size()==3)
367 {
368 floppy.AddDefine(tokens[1],tokens[2]);
369 }
370 else
371 {
372 ShowError("Syntax error line (%d), syntax is 'AddDefine DefineName DefineValue' \n",lineNumber);
373 }
374 }
375 else
376 if (tokens[0]=="SetCompressionMode")
377 {
378 if (tokens.size()==2)
379 {
380 if (tokens[1]=="None")
381 {
382 floppy.SetCompressionMode(e_CompressionNone);
383 }
384 else
385 if (tokens[1]=="FilePack")
386 {
387 floppy.SetCompressionMode(e_CompressionFilepack);
388 }
389 else
390 {
391 ShowError("Syntax error line (%d), '%s' is not a valid compression mode, it should be either 'None' or 'FilePack' \n",lineNumber,tokens[1].c_str());
392 }
393 }
394 else
395 {
396 ShowError("Syntax error line (%d), syntax is 'SetCompressionMode [None|FilePack]' \n",lineNumber);
397 }
398 }
399 else
400 {
401 ShowError("Syntax error line (%d), unknown keyword '%s' \n",lineNumber,tokens[0].c_str());
402 }
403 }
404 }
405
406
407
408 if (!floppy.SaveDescription(outputLayoutFileName.c_str()))
409 {
410 ShowError("Failed saving description '%s'\n",outputLayoutFileName.c_str());
411 }
412
413 if (!floppy.SaveDisk(targetFloppyDiskName.c_str()))
414 {
415 ShowError("Failed saving disk '%s'\n",targetFloppyDiskName.c_str());
416 }
417 else
418 {
419 printf("Successfully created '%s'\n",targetFloppyDiskName.c_str());
420 }
421 }

  ViewVC Help
Powered by ViewVC 1.1.26