/[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 1129 - (show annotations)
Sun May 11 09:17:25 2014 UTC (5 years, 7 months ago) by dbug
File size: 12546 byte(s)
Got the latest changes from Hialmar and Jylam, and made the Visual Studio build work again (hopefully did not break the Linux stuff)

Also some changes that were not committed yet:
FloppyBuilder 0.16 - 2014/04/06
- Added a mode where data can be extracted from an existing DSK file
- The parser now accepts quoted strings

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 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 int main(int argc, char *argv[])
94 {
95 //
96 // Some initialization for the common library
97 //
98 SetApplicationParameters(
99 "FloppyBuilder",
100 TOOL_VERSION_MAJOR,
101 TOOL_VERSION_MINOR,
102 "{ApplicationName} - Version {ApplicationVersion} - This program is a part of the OSDK\r\n"
103 "\r\n"
104 "Author:\r\n"
105 " (c) 2002 Debrune Jerome for the initial version \r\n"
106 " (c) 2013 Pointier Mickael for the subsequent changes \r\n"
107 "\r\n"
108 "Purpose:\r\n"
109 " Generating bootable floppies for the Oric computer.\r\n"
110 "\r\n"
111 "Usage:\r\n"
112 " {ApplicationName} <init|build|extract> <description file path>\r\n"
113 "\r\n"
114 );
115
116 // makedisk filetobuild.txt default.dsk ..\build\%OSDKDISK%
117
118 long param=1;
119
120 if (argc>1)
121 {
122 for (;;)
123 {
124 long nb_arg=argc;
125 const char *ptr_arg=argv[param];
126
127 if (nb_arg==argc) break;
128 }
129 }
130
131
132 if (argc!=3)
133 {
134 ShowError(nullptr);
135 }
136
137 Floppy floppy;
138
139 bool extract=false;
140 if (!strcmp(argv[param],"init"))
141 {
142 floppy.AllowMissingFiles(true);
143 }
144 else
145 if (!strcmp(argv[param],"extract"))
146 {
147 floppy.AllowMissingFiles(true);
148 extract=true;
149 }
150 else
151 if (!strcmp(argv[param],"build"))
152 {
153 floppy.AllowMissingFiles(false);
154 }
155 else
156 {
157 ShowError("The first parameter should be either 'init' or 'build'.");
158 }
159 param++;
160
161
162 //
163 // Open the description file
164 //
165 const char* description_name(argv[param]);
166 std::vector<std::string> script;
167 if (!LoadText(description_name,script))
168 {
169 ShowError("Can't load script file '%s'\n",description_name);
170 }
171
172
173 std::string outputLayoutFileName;
174 std::string targetFloppyDiskName;
175
176 int lineNumber=0;
177 for (auto it(script.begin());it!=script.end();++it)
178 {
179 ++lineNumber;
180
181 std::string currentLine(*it);
182
183 std::size_t found = currentLine.find(";");
184 if (found!=std::string::npos)
185 {
186 // Comments, just skip them
187 currentLine=currentLine.substr(0,found);
188 }
189
190 std::istringstream iss(currentLine);
191
192 std::map<std::string,std::string> metadata;
193 std::string item;
194 std::vector<std::string> tokens;
195 //while (std::getline(iss,item,' '))
196 while (GetNextToken(item,currentLine,lineNumber))
197 {
198 // Remove eventual superfluous spaces and tabs
199 item=StringTrim(item);
200 if (!item.empty())
201 {
202 if ( ((*item.begin())=='[') && ((*item.rbegin())==']') )
203 {
204 // Let's say it's metadata
205 std::string metaItem=StringTrim(item,"[]");
206 std::size_t found = metaItem.find(":");
207 if (found!=std::string::npos)
208 {
209 // Comments, just skip them
210 std::string key =metaItem.substr(0,found);
211 std::string value=metaItem.substr(found+1);
212 metadata[key]=value;
213 }
214 else
215 {
216 ShowError("Syntax error line (%d), found invalid '%s' metadata format, should be '[key:value]'\n",lineNumber,item.c_str());
217 }
218 }
219 else
220 {
221 // Let's say it's an actual parameter
222 item=StringTrim(item,"\"");
223 tokens.push_back(item);
224 }
225 }
226 }
227
228 if (!tokens.empty())
229 {
230 if (tokens[0]=="LoadDiskTemplate")
231 {
232 if (tokens.size()==2)
233 {
234 const std::string& templateFisk(tokens[1]);
235 if (!floppy.LoadDisk(templateFisk.c_str()))
236 {
237 ShowError("Can't load '%s'\n",templateFisk.c_str());
238 }
239
240 }
241 else
242 {
243 ShowError("Syntax error line (%d), syntax is 'LoadDiskTemplate FilePath' \n",lineNumber);
244 }
245 }
246 else
247 if (tokens[0]=="DefineDisk")
248 {
249 if (tokens.size()==4)
250 {
251 int numberOfSides =std::atoi(tokens[1].c_str());
252 int numberOfTracks =std::atoi(tokens[2].c_str());
253 int numberOfSectors =std::atoi(tokens[3].c_str());
254
255 if ( numberOfSides!=2 )
256 {
257 ShowError("Syntax error line (%d), numberOfSides has to be 2 (so far)\n",lineNumber);
258 }
259
260 /*
261 if ( numberOfTracks!=42 )
262 {
263 ShowError("Syntax error line (%d), numberOfTracks has to be 42 (so far)\n",lineNumber);
264 }
265 */
266
267 if ( numberOfSectors!=17 )
268 {
269 ShowError("Syntax error line (%d), numberOfSectors has to be 17 (so far)\n",lineNumber);
270 }
271
272 if (!floppy.CreateDisk(numberOfSides,numberOfTracks,numberOfSectors))
273 {
274 ShowError("Can't create the requested disk format\n");
275 }
276
277 }
278 else
279 {
280 ShowError("Syntax error line (%d), syntax is 'DefineDisk numberOfSides numberOfTracks numberOfSectors' \n",lineNumber);
281 }
282 }
283 else
284 if (tokens[0]=="OutputLayoutFile")
285 {
286 if (tokens.size()==2)
287 {
288 outputLayoutFileName=tokens[1];
289 }
290 else
291 {
292 ShowError("Syntax error line (%d), syntax is 'OutputLayoutFile FilePath' \n",lineNumber);
293 }
294 }
295 else
296 if (tokens[0]=="OutputFloppyFile")
297 {
298 if (tokens.size()==2)
299 {
300 targetFloppyDiskName=tokens[1];
301 }
302 else
303 {
304 ShowError("Syntax error line (%d), syntax is 'targetFloppyDiskName FilePath' \n",lineNumber);
305 }
306 }
307 else
308 if (tokens[0]=="SetPosition")
309 {
310 if (tokens.size()==3)
311 {
312 int currentTrack =std::atoi(tokens[1].c_str());
313 if ( (currentTrack<0) || (currentTrack>41) )
314 {
315 ShowError("Syntax error line (%d), TrackNumber has to be between 0 and 41' \n",lineNumber);
316 }
317 int currentSector=std::atoi(tokens[2].c_str());
318 if ( (currentSector<0) || (currentSector>41) )
319 {
320 ShowError("Syntax error line (%d), SectorNumber has to be between 1 and 17' \n",lineNumber);
321 }
322 floppy.SetPosition(currentTrack,currentSector);
323 }
324 else
325 {
326 ShowError("Syntax error line (%d), syntax is 'SetPosition TrackNumber SectorNumber' \n",lineNumber);
327 }
328 }
329 else
330 if (tokens[0]=="WriteSector")
331 {
332 if (tokens.size()==2)
333 {
334 std::string fileName=tokens[1];
335 if (!floppy.WriteSector(fileName.c_str()))
336 {
337 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());
338 }
339 }
340 else
341 {
342 ShowError("Syntax error line (%d), syntax is 'WriteSector FilePath' \n",lineNumber);
343 }
344 }
345 else
346 if (tokens[0]=="AddFile")
347 {
348 if (tokens.size()==3)
349 {
350 std::string fileName=tokens[1];
351 int loadAddress=ConvertAdress(tokens[2].c_str());
352 if (!floppy.WriteFile(fileName.c_str(),loadAddress,false,metadata))
353 {
354 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());
355 }
356 }
357 else
358 {
359 ShowError("Syntax error line (%d), syntax is 'AddFile FilePath LoadAddress' \n",lineNumber);
360 }
361 }
362 else
363 if (tokens[0]=="AddTapFile")
364 {
365 if (tokens.size()==2)
366 {
367 std::string fileName=tokens[1];
368 if (!floppy.WriteFile(fileName.c_str(),-1,true,metadata))
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 'AddTapFile FilePath' \n",lineNumber);
376 }
377 }
378 else
379 if (tokens[0]=="SaveFile")
380 {
381 // ; SaveFile "File_0.bin" $80 $01 $47 ; Name Track Sector Lenght adress
382 if (tokens.size()==5)
383 {
384 std::string fileName=tokens[1];
385 int trackNumber =ConvertAdress(tokens[2].c_str());
386 int sectorNumber=ConvertAdress(tokens[3].c_str());
387 int sectorCount =ConvertAdress(tokens[4].c_str());
388 if (!floppy.ExtractFile(fileName.c_str(),trackNumber,sectorNumber,sectorCount))
389 {
390 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());
391 }
392 }
393 else
394 {
395 ShowError("Syntax error line (%d), syntax is 'ExtractFile FilePath TrackNumber SectorNumber SectorCount' \n",lineNumber);
396 }
397 }
398 else
399 if (tokens[0]=="AddDefine")
400 {
401 if (tokens.size()==3)
402 {
403 floppy.AddDefine(tokens[1],tokens[2]);
404 }
405 else
406 {
407 ShowError("Syntax error line (%d), syntax is 'AddDefine DefineName DefineValue' \n",lineNumber);
408 }
409 }
410 else
411 if (tokens[0]=="SetCompressionMode")
412 {
413 if (tokens.size()==2)
414 {
415 if (tokens[1]=="None")
416 {
417 floppy.SetCompressionMode(e_CompressionNone);
418 }
419 else
420 if (tokens[1]=="FilePack")
421 {
422 floppy.SetCompressionMode(e_CompressionFilepack);
423 }
424 else
425 {
426 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());
427 }
428 }
429 else
430 {
431 ShowError("Syntax error line (%d), syntax is 'SetCompressionMode [None|FilePack]' \n",lineNumber);
432 }
433 }
434 else
435 {
436 ShowError("Syntax error line (%d), unknown keyword '%s' \n",lineNumber,tokens[0].c_str());
437 }
438 }
439 }
440
441
442 if (!extract)
443 {
444 // We write the resulting files only in 'init' or 'build' mode
445 if (!floppy.SaveDescription(outputLayoutFileName.c_str()))
446 {
447 ShowError("Failed saving description '%s'\n",outputLayoutFileName.c_str());
448 }
449
450 if (!floppy.SaveDisk(targetFloppyDiskName.c_str()))
451 {
452 ShowError("Failed saving disk '%s'\n",targetFloppyDiskName.c_str());
453 }
454 else
455 {
456 printf("Successfully created '%s'\n",targetFloppyDiskName.c_str());
457 }
458 }
459 }

  ViewVC Help
Powered by ViewVC 1.1.26