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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1338 - (show annotations)
Thu Jan 7 18:51:26 2016 UTC (3 years, 8 months ago) by dbug
File size: 13788 byte(s)
Small structural change in FloppyBuilder to make Coverity happy (it complained about non trapped exception)
1
2 #include <cstdlib>
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 if (match)
50 {
51 // Push the starting character
52 returnedToken.push_back(car);
53 ++currentPosition;
54 }
55
56 while ( (car=*currentPosition) && ( (match && (car!=match)) || ( (!match) && ((car!=' ') && (car!='\t')) ) ) )
57 {
58 returnedToken.push_back(car);
59 ++currentPosition;
60 }
61
62 if (match && (car==match))
63 {
64 // Including the matching character
65 returnedToken.push_back(car);
66 ++currentPosition;
67 car=*currentPosition;
68 }
69
70 if (car)
71 {
72 // We have reach the end of the token, just make sure there's a white space behind
73 if ((car==' ') || (car=='\t'))
74 {
75 restOfLine=currentPosition;
76 }
77 else
78 {
79 // Parse error
80 ShowError("Parse error line '%d'\n",lineNumber);
81 }
82 }
83 else
84 {
85 // End of Line
86 restOfLine.clear();
87 }
88 return true;
89 }
90 return false;
91 }
92
93
94 class FloppyBuilder : public ArgumentParser
95 {
96 public:
97 FloppyBuilder(int argc,char *argv[])
98 : ArgumentParser(argc,argv)
99 {
100 }
101
102 int Main();
103
104
105 private:
106 };
107
108
109 int main(int argc, char *argv[])
110 {
111 try
112 {
113 //
114 // Some initialization for the common library
115 //
116 SetApplicationParameters(
117 "FloppyBuilder",
118 TOOL_VERSION_MAJOR,
119 TOOL_VERSION_MINOR,
120 "{ApplicationName} - Version {ApplicationVersion} - This program is a part of the OSDK\r\n"
121 "\r\n"
122 "Author:\r\n"
123 " (c) 2002 Debrune Jerome for the initial version \r\n"
124 " (c) 2015 Pointier Mickael for the subsequent changes \r\n"
125 "\r\n"
126 "Purpose:\r\n"
127 " Generating bootable floppies for the Oric computer.\r\n"
128 "\r\n"
129 "Usage:\r\n"
130 " {ApplicationName} <init|build|extract> <description file path>\r\n"
131 "\r\n"
132 );
133
134 FloppyBuilder floppyBuilder(argc,argv);
135 return floppyBuilder.Main();
136 }
137
138 catch (std::exception& e)
139 {
140 ShowError("Exception thrown: %s",e.what());
141 }
142 }
143
144
145
146 int FloppyBuilder::Main()
147 {
148
149 // makedisk filetobuild.txt default.dsk ..\build\%OSDKDISK%
150
151 long param=1;
152
153 if (m_argc>1)
154 {
155 for (;;)
156 {
157 long nb_arg=m_argc;
158 //const char *ptr_arg=argv[param];
159
160 if (nb_arg==m_argc) break;
161 }
162 }
163
164
165 if (m_argc!=3)
166 {
167 ShowError(nullptr);
168 }
169
170 Floppy floppy;
171
172 bool extract=false;
173 if (!strcmp(m_argv[param],"init"))
174 {
175 floppy.AllowMissingFiles(true);
176 }
177 else
178 if (!strcmp(m_argv[param],"extract"))
179 {
180 floppy.AllowMissingFiles(true);
181 extract=true;
182 }
183 else
184 if (!strcmp(m_argv[param],"build"))
185 {
186 floppy.AllowMissingFiles(false);
187 }
188 else
189 {
190 ShowError("The first parameter should be either 'init' or 'build'.");
191 }
192 param++;
193
194
195 //
196 // Open the description file
197 //
198 const char* description_name(m_argv[param]);
199 std::vector<std::string> script;
200 if (!LoadText(description_name,script))
201 {
202 ShowError("Can't load script file '%s'\n",description_name);
203 }
204
205
206 std::string outputLayoutFileName;
207 std::string targetFloppyDiskName;
208
209 int lineNumber=0;
210 for (auto it(script.begin());it!=script.end();++it)
211 {
212 ++lineNumber;
213
214 std::string currentLine(*it);
215
216 std::size_t found = currentLine.find(";");
217 if (found!=std::string::npos)
218 {
219 // Comments, just skip them
220 currentLine=currentLine.substr(0,found);
221 }
222
223 std::istringstream iss(currentLine);
224
225 std::map<std::string,std::string> metadata;
226 std::string item;
227 std::vector<std::string> tokens;
228 //while (std::getline(iss,item,' '))
229 while (GetNextToken(item,currentLine,lineNumber))
230 {
231 // Remove eventual superfluous spaces and tabs
232 item=StringTrim(item);
233 if (!item.empty())
234 {
235 if ( ((*item.begin())=='[') && ((*item.rbegin())==']') )
236 {
237 // Let's say it's metadata
238 std::string metaItem=StringTrim(item,"[]");
239 std::size_t found = metaItem.find(":");
240 if (found!=std::string::npos)
241 {
242 // Comments, just skip them
243 std::string key =metaItem.substr(0,found);
244 std::string value=metaItem.substr(found+1);
245 metadata[key]=value;
246 }
247 else
248 {
249 ShowError("Syntax error line (%d), found invalid '%s' metadata format, should be '[key:value]'\n",lineNumber,item.c_str());
250 }
251 }
252 else
253 {
254 // Let's say it's an actual parameter
255 item=StringTrim(item,"\"");
256 tokens.push_back(item);
257 }
258 }
259 }
260
261 if (!tokens.empty())
262 {
263 if (tokens[0]=="LoadDiskTemplate")
264 {
265 if (tokens.size()==2)
266 {
267 const std::string& templateFisk(tokens[1]);
268 if (!floppy.LoadDisk(templateFisk.c_str()))
269 {
270 ShowError("Can't load '%s'\n",templateFisk.c_str());
271 }
272
273 }
274 else
275 {
276 ShowError("Syntax error line (%d), syntax is 'LoadDiskTemplate FilePath' \n",lineNumber);
277 }
278 }
279 else
280 if (tokens[0]=="DefineDisk")
281 {
282 if (tokens.size()==4)
283 {
284 int numberOfSides =std::atoi(tokens[1].c_str());
285 int numberOfTracks =std::atoi(tokens[2].c_str());
286 int numberOfSectors =std::atoi(tokens[3].c_str());
287
288 if ( numberOfSides!=2 )
289 {
290 ShowError("Syntax error line (%d), numberOfSides has to be 2 (so far)\n",lineNumber);
291 }
292
293 /*
294 if ( numberOfTracks!=42 )
295 {
296 ShowError("Syntax error line (%d), numberOfTracks has to be 42 (so far)\n",lineNumber);
297 }
298 */
299
300 if ( numberOfSectors!=17 )
301 {
302 ShowError("Syntax error line (%d), numberOfSectors has to be 17 (so far)\n",lineNumber);
303 }
304
305 if (!floppy.CreateDisk(numberOfSides,numberOfTracks,numberOfSectors))
306 {
307 ShowError("Can't create the requested disk format\n");
308 }
309
310 }
311 else
312 {
313 ShowError("Syntax error line (%d), syntax is 'DefineDisk numberOfSides numberOfTracks numberOfSectors' \n",lineNumber);
314 }
315 }
316 else
317 if (tokens[0]=="OutputLayoutFile")
318 {
319 if (tokens.size()==2)
320 {
321 outputLayoutFileName=tokens[1];
322 }
323 else
324 {
325 ShowError("Syntax error line (%d), syntax is 'OutputLayoutFile FilePath' \n",lineNumber);
326 }
327 }
328 else
329 if (tokens[0]=="OutputFloppyFile")
330 {
331 if (tokens.size()==2)
332 {
333 targetFloppyDiskName=tokens[1];
334 }
335 else
336 {
337 ShowError("Syntax error line (%d), syntax is 'targetFloppyDiskName FilePath' \n",lineNumber);
338 }
339 }
340 else
341 if (tokens[0]=="SetPosition")
342 {
343 if (tokens.size()==3)
344 {
345 int currentTrack =std::atoi(tokens[1].c_str());
346 if ( (currentTrack<0) || (currentTrack>41) )
347 {
348 ShowError("Syntax error line (%d), TrackNumber has to be between 0 and 41' \n",lineNumber);
349 }
350 int currentSector=std::atoi(tokens[2].c_str());
351 if ( (currentSector<0) || (currentSector>41) )
352 {
353 ShowError("Syntax error line (%d), SectorNumber has to be between 1 and 17' \n",lineNumber);
354 }
355 floppy.SetPosition(currentTrack,currentSector);
356 }
357 else
358 {
359 ShowError("Syntax error line (%d), syntax is 'SetPosition TrackNumber SectorNumber' \n",lineNumber);
360 }
361 }
362 else
363 if (tokens[0]=="WriteSector")
364 {
365 if (tokens.size()==2)
366 {
367 std::string fileName=tokens[1];
368 if (!floppy.WriteSector(fileName.c_str()))
369 {
370 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());
371 }
372 }
373 else
374 {
375 ShowError("Syntax error line (%d), syntax is 'WriteSector FilePath' \n",lineNumber);
376 }
377 }
378 else
379 if (tokens[0]=="AddFile")
380 {
381 if (tokens.size()==3)
382 {
383 std::string fileName=tokens[1];
384 int loadAddress=ConvertAdress(tokens[2].c_str());
385 if (!floppy.WriteFile(fileName.c_str(),loadAddress,false,metadata))
386 {
387 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());
388 }
389 }
390 else
391 {
392 ShowError("Syntax error line (%d), syntax is 'AddFile FilePath LoadAddress' \n",lineNumber);
393 }
394 }
395 else
396 if (tokens[0]=="AddTapFile")
397 {
398 if (tokens.size()==2)
399 {
400 std::string fileName=tokens[1];
401 if (!floppy.WriteFile(fileName.c_str(),-1,true,metadata))
402 {
403 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());
404 }
405 }
406 else
407 {
408 ShowError("Syntax error line (%d), syntax is 'AddTapFile FilePath' \n",lineNumber);
409 }
410 }
411 else
412 if (tokens[0]=="ReserveSectors")
413 {
414 if ( (tokens.size()==2) || (tokens.size()==3) )
415 {
416 int sectorCount=ConvertAdress(tokens[1].c_str());
417 int fillValue=0;
418 if (tokens.size()==3)
419 {
420 fillValue=ConvertAdress(tokens[2].c_str());
421 }
422 if (!floppy.ReserveSectors(sectorCount,fillValue,metadata))
423 {
424 ShowError("Error line (%d), could not reserve %u sectors on the disk. Make sure you have a valid floppy format declared. \n",lineNumber,sectorCount);
425 }
426 }
427 else
428 {
429 ShowError("Syntax error line (%d), syntax is 'ReserveSectors SectorCount [FillValue]' \n",lineNumber);
430 }
431 }
432 else
433 if (tokens[0]=="SaveFile")
434 {
435 // ; SaveFile "File_0.bin" $80 $01 $47 ; Name Track Sector Lenght adress
436 if (tokens.size()==5)
437 {
438 std::string fileName=tokens[1];
439 int trackNumber =ConvertAdress(tokens[2].c_str());
440 int sectorNumber=ConvertAdress(tokens[3].c_str());
441 int sectorCount =ConvertAdress(tokens[4].c_str());
442 if (!floppy.ExtractFile(fileName.c_str(),trackNumber,sectorNumber,sectorCount))
443 {
444 ShowError("Error line (%d), could not extract file '%s' from disk. Make sure you have a valid floppy format declared and some available disk space. \n",lineNumber,fileName.c_str());
445 }
446 }
447 else
448 {
449 ShowError("Syntax error line (%d), syntax is 'ExtractFile FilePath TrackNumber SectorNumber SectorCount' \n",lineNumber);
450 }
451 }
452 else
453 if (tokens[0]=="AddDefine")
454 {
455 if (tokens.size()==3)
456 {
457 floppy.AddDefine(tokens[1],tokens[2]);
458 }
459 else
460 {
461 ShowError("Syntax error line (%d), syntax is 'AddDefine DefineName DefineValue' \n",lineNumber);
462 }
463 }
464 else
465 if (tokens[0]=="SetCompressionMode")
466 {
467 if (tokens.size()==2)
468 {
469 if (tokens[1]=="None")
470 {
471 floppy.SetCompressionMode(e_CompressionNone);
472 }
473 else
474 if (tokens[1]=="FilePack")
475 {
476 floppy.SetCompressionMode(e_CompressionFilepack);
477 }
478 else
479 {
480 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());
481 }
482 }
483 else
484 {
485 ShowError("Syntax error line (%d), syntax is 'SetCompressionMode [None|FilePack]' \n",lineNumber);
486 }
487 }
488 else
489 {
490 ShowError("Syntax error line (%d), unknown keyword '%s' \n",lineNumber,tokens[0].c_str());
491 }
492 }
493 }
494
495
496 if (!extract)
497 {
498 // We write the resulting files only in 'init' or 'build' mode
499 if (!floppy.SaveDescription(outputLayoutFileName.c_str()))
500 {
501 ShowError("Failed saving description '%s'\n",outputLayoutFileName.c_str());
502 }
503
504 if (!floppy.SaveDisk(targetFloppyDiskName.c_str()))
505 {
506 ShowError("Failed saving disk '%s'\n",targetFloppyDiskName.c_str());
507 }
508 else
509 {
510 printf("Successfully created '%s'\n",targetFloppyDiskName.c_str());
511 }
512 }
513 return 0;
514 }

  ViewVC Help
Powered by ViewVC 1.1.26