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

Contents of /public/pc/tools/osdk/main/common/sources/common.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 898 - (show annotations)
Sat Sep 29 18:40:02 2012 UTC (7 years, 4 months ago) by dbug
File size: 16416 byte(s)
Fixed some issues on Visual Studio introduced by the posixification...
1
2
3 #include "common.h"
4
5 #include <memory.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8 #ifdef WIN32
9 /* for getch() */
10 #include <conio.h>
11 #else
12 /* for getch() */
13 #include <curses.h>
14 #endif
15 #include <stdio.h>
16 #include <fcntl.h>
17 #include <sys/stat.h>
18 #include <stdarg.h>
19
20 #include <assert.h>
21
22 static std::string g_cApplicationName;
23 static std::string g_cUsageMessage;
24 static std::string g_cVersionString;
25 static int g_nVersionMajor;
26 static int g_nVersionMinor;
27
28
29 void SetApplicationParameters(const char* pcApplicationName,int nVersionMajor,int nVersionMinor,const char* pcUsageMessage)
30 {
31 g_cApplicationName=pcApplicationName;
32
33 g_nVersionMajor=nVersionMajor;
34 g_nVersionMinor=nVersionMinor;
35 char cTempBuffer[256];
36 sprintf(cTempBuffer,"%d.%03d",nVersionMajor,nVersionMinor);
37 g_cVersionString=cTempBuffer;
38
39 g_cUsageMessage=pcUsageMessage;
40 }
41
42
43
44 void ShowError(const char *message)
45 {
46 std::string cErrorMessage;
47
48 if (message)
49 {
50 // Message will be something like: "MyApplication.exe: Something goes wrong, sorry !"
51 cErrorMessage=g_cApplicationName+": "+ message;
52 }
53 else
54 {
55 cErrorMessage=g_cUsageMessage;
56 StringReplace(cErrorMessage,"{ApplicationName}" ,g_cApplicationName);
57 StringReplace(cErrorMessage,"{ApplicationVersion}" ,g_cVersionString);
58 }
59
60 // Show the resulting message on screen
61 printf("\r\n%s\r\n",cErrorMessage.c_str());
62 getch();
63 exit(1);
64 }
65
66
67
68 bool LoadFile(const char* pcFileName,void* &pcBuffer,size_t &cBufferSize)
69 {
70 // get the size of the file
71 struct stat file_info;
72
73 if (stat(pcFileName, &file_info)== -1)
74 {
75 return false;
76 }
77
78 // open the file
79 cBufferSize=file_info.st_size;
80 int nHandle=open(pcFileName,O_BINARY|O_RDONLY,0);
81 if (nHandle==-1)
82 {
83 return false;
84 }
85
86 // allocate some memory
87 pcBuffer=malloc(cBufferSize+1);
88 if (!pcBuffer)
89 {
90 return false;
91 }
92
93 // read file content
94 if (read(nHandle,pcBuffer,cBufferSize)!=(int)cBufferSize)
95 {
96 free(pcBuffer);
97 return false;
98 }
99 close(nHandle);
100
101 // Add a null terminator in the additional byte
102 char *pcCharBuffer=(char*)pcBuffer;
103 pcCharBuffer[cBufferSize]=0;
104
105 return true;
106 }
107
108
109 bool SaveFile(const char* pcFileName,const void* pcBuffer,size_t cBufferSize)
110 {
111 // Open file
112 int nHandle=open(pcFileName,O_BINARY|O_WRONLY|O_TRUNC|O_CREAT,S_IREAD|S_IWRITE);
113 if (nHandle==-1)
114 {
115 return false;
116 }
117
118 // Save data
119 if (write(nHandle,pcBuffer,cBufferSize)!=(int)cBufferSize)
120 {
121 close(nHandle);
122 return false;
123 }
124
125 // close handle
126 close(nHandle);
127
128 return true;
129 }
130
131 bool DeleteFile(const char* pcFileName)
132 {
133 return unlink(pcFileName)==0;
134 }
135
136
137 /**
138 * Transforms a raw ascii buffer (0 terminated)
139 * into a vector of string where each string
140 * contains one line of the original buffer.
141 *
142 * Compute the lenght of the longest line during
143 * the process
144 */
145 bool LoadText(const char* pcFileName,std::vector<std::string>& cTextData)
146 {
147 cTextData.clear();
148
149 void* ptr_buffer_void;
150 size_t file_size;
151 if (!LoadFile(pcFileName,ptr_buffer_void,file_size))
152 {
153 return false;
154 }
155
156 const char *ptr_line=(const char *)ptr_buffer_void;
157 const char *ptr_read=ptr_line;
158
159 bool flag_new_line=true;
160
161 int line_count=0;
162 int longest_line=0;
163
164 while (1)
165 {
166 char car=*ptr_read++;
167 switch (car)
168 {
169 case 0:
170 case 0x0D:
171 case 0x0A:
172 {
173 //
174 // Find a end of line.
175 // Patch it with a "0"
176 // and insert the line in the container
177 //
178 int size_line=ptr_read-ptr_line-1;
179 std::string new_line(ptr_line,size_line);
180 cTextData.push_back(new_line);
181
182 line_count++;
183
184 if (size_line>longest_line)
185 {
186 longest_line=size_line;
187 }
188
189 if (!car)
190 {
191 //
192 // Finished parsing
193 //
194 free(ptr_buffer_void);
195 return true;
196 }
197 if ( (car==0x0D) && ((*ptr_read)==0x0A) )
198 {
199 // If we have a \r\n sequence, we skip the \n
200 ptr_read++;
201 }
202 ptr_line=ptr_read;
203 flag_new_line=true;
204 }
205 break;
206
207 default:
208 flag_new_line=false;
209 break;
210 }
211
212 /*
213 switch (car)
214 {
215 case 0:
216 case 0x0D:
217 {
218 //
219 // Find a end of line.
220 // Patch it with a "0"
221 // and insert the line in the container
222 //
223 int size_line=ptr_read-ptr_line-1;
224 std::string new_line(ptr_line,size_line);
225 cTextData.push_back(new_line);
226
227 line_count++;
228
229 if (size_line>longest_line)
230 {
231 longest_line=size_line;
232 }
233
234 if (!car)
235 {
236 //
237 // Finished parsing
238 //
239 free(ptr_buffer_void);
240 return true;
241 }
242 ptr_line=ptr_read;
243 flag_new_line=true;
244 }
245 break;
246
247 case 0x0A:
248 if (flag_new_line)
249 {
250 //
251 // Skip leading 0x0A
252 //
253 ptr_line++;
254 }
255 break;
256
257 default:
258 flag_new_line=false;
259 break;
260 }
261 */
262 }
263 }
264
265
266 int StringReplace(std::string& cMainString,const std::string& cSearchedString,const std::string& cReplaceString)
267 {
268 int nReplaceCount=0;
269 std::string::size_type pos=0;
270 while (1)
271 {
272 pos=cMainString.find(cSearchedString,pos);
273 if (pos==std::string::npos)
274 {
275 break;
276 }
277 cMainString.replace(pos,cSearchedString.size(),cReplaceString);
278 pos+=cReplaceString.size();
279 ++nReplaceCount;
280 }
281 return nReplaceCount;
282 }
283
284 std::string StringTrim(const std::string& cInputString,const std::string& cFilteredOutCharacterList)
285 {
286 size_t nStartPos=cInputString.find_first_not_of(cFilteredOutCharacterList);
287 if (nStartPos!=std::string::npos)
288 {
289 size_t nEndPos=cInputString.find_last_not_of(cFilteredOutCharacterList);
290 if (nEndPos!=std::string::npos)
291 {
292 return cInputString.substr(nStartPos,(nEndPos-nStartPos)+1);
293 }
294 }
295 // Returns an empty string: This case means that basically the input string contains ONLY characters that needed to be filtered out
296 return "";
297 }
298
299
300 ArgumentParser::ArgumentParser(int argc,char *argv[]) :
301 m_argc(argc),
302 m_argv(argv),
303 m_first_param(1),
304 m_nb_arg(-1),
305 m_remaining_argc(argc)
306 {
307 assert(argc>=1);
308
309 // We do not count the implicit first parameter (application name) in the parameter count
310 m_remaining_argc--;
311 }
312
313 const char* ArgumentParser::GetParameter(int nParameterIndex)
314 {
315 int nIndex=m_first_param+nParameterIndex;
316 if (nIndex>=m_argc)
317 {
318 // Wrong !
319 return "";
320 }
321 return m_argv[nIndex];
322 }
323
324 int ArgumentParser::GetParameterCount()
325 {
326 return m_remaining_argc;
327 }
328
329 bool ArgumentParser::ProcessNextArgument()
330 {
331 if ((!m_remaining_argc) || (m_nb_arg==m_remaining_argc))
332 {
333 // No more arguments
334 return false;
335 }
336
337 m_nb_arg =m_remaining_argc;
338 m_ptr_arg =m_argv[m_first_param];
339
340 return true;
341 }
342
343 bool ArgumentParser::IsSwitch(const char *ptr_switch)
344 {
345 if (!::get_switch(m_ptr_arg,ptr_switch))
346 {
347 return false;
348 }
349 m_first_param++;
350 m_remaining_argc--;
351 return true;
352 }
353
354 bool ArgumentParser::IsParameter()
355 {
356 if (!m_ptr_arg)
357 {
358 return false;
359 }
360 char cCar=*m_ptr_arg;
361 if ((!cCar) || (cCar=='-'))
362 {
363 return false;
364 }
365
366 m_first_param++;
367 m_remaining_argc--;
368 return true;
369 }
370
371
372 std::string ArgumentParser::GetStringValue()
373 {
374 return ::get_string(m_ptr_arg);
375 }
376
377 int ArgumentParser::GetIntegerValue(int default_value)
378 {
379 return ::get_value(m_ptr_arg,default_value);
380 }
381
382 bool ArgumentParser::GetBooleanValue(bool default_value)
383 {
384 int nValue;
385 if (default_value) nValue=1;
386 else nValue=0;
387 nValue=::get_value(m_ptr_arg,nValue);
388 if (nValue) return true;
389 else return false;
390 }
391
392 bool ArgumentParser::GetSeparator(const char* ptr_separator_list)
393 {
394 while (*ptr_separator_list)
395 {
396 if (*m_ptr_arg==*ptr_separator_list)
397 {
398 m_ptr_arg++;
399 return true;
400 }
401 ptr_separator_list++;
402 }
403 return false;
404 }
405
406 const char* ArgumentParser::GetRemainingStuff()
407 {
408 return m_ptr_arg;
409 }
410
411
412
413 bool get_switch(const char *&ptr_arg,const char *ptr_switch)
414 {
415 int lenght=strlen(ptr_switch);
416
417 if ((!ptr_arg) || strncasecmp(ptr_arg,ptr_switch,lenght))
418 {
419 // Not a match
420 return false;
421 }
422 // Validate the parameter
423 ptr_arg+=lenght;
424 return true;
425 }
426
427 std::string get_string(const char *&ptr_arg)
428 {
429 if (!ptr_arg) return 0;
430 std::string cStringValue=std::string(ptr_arg);
431 ptr_arg+=cStringValue.size();
432 return cStringValue;
433 }
434
435 int get_value(const char *&ptr_arg,long default_value)
436 {
437 char*ptr_end;
438 long value;
439
440 if (!ptr_arg) return 0;
441 value=strtoul(ptr_arg,&ptr_end,10);
442 if (ptr_arg==ptr_end)
443 {
444 value=default_value;
445 }
446 ptr_arg=ptr_end;
447 return value;
448 }
449
450
451
452 int ConvertAdress(const char *ptr_value)
453 {
454 int adress;
455 int base;
456 char car;
457
458 if (ptr_value[0]=='$')
459 {
460 // Hexadecimal
461 base=16;
462 ptr_value++;
463 }
464 else
465 {
466 // Decimal
467 base=10;
468 }
469
470 adress=0;
471 while (car=*ptr_value++)
472 {
473 if ((car>='0') && (car<='9'))
474 {
475 adress*=base;
476 adress+=car-'0';
477 }
478 else
479 if ((car>='a') && (car<='f'))
480 {
481 if (base!=16)
482 {
483 ShowError("Only hexadecimal values prefixed by a '$' can contain letters");
484 }
485 adress*=base;
486 adress+=car-'a'+10;
487 }
488 else
489 if ((car>='A') && (car<='F'))
490 {
491 if (base!=16)
492 {
493 ShowError("Only hexadecimal values prefixed by a '$' can contain letters");
494 }
495 adress*=base;
496 adress+=car-'A'+10;
497 }
498 else
499 {
500 ShowError("Unknow character in the adress value");
501 }
502 }
503
504 if ((adress<0x0000) || (adress>0xFFFF))
505 {
506 ShowError("authorized adress range is $0000 to $FFFF");
507 }
508
509 return adress;
510 }
511
512
513 std::string StringFormat(const char* pFormatString,...)
514 {
515 va_list va;
516 char temp[4096];
517
518 va_start(va,pFormatString);
519 int nChar=vsprintf(temp,pFormatString,va);
520 va_end(va);
521 if ((unsigned int)nChar>=sizeof(temp))
522 {
523 temp[sizeof(temp)-1]=0;
524 }
525 return std::string(temp);
526 }
527
528
529
530
531
532 class DataReader
533 {
534 public:
535 DataReader();
536 ~DataReader();
537
538 void SetPointer(const void* ptr);
539 const void *GetPointer();
540
541 void SetEndian(bool bIsBigEndian);
542 bool GetEndian();
543
544 unsigned int GetValue(int nSizeValue);
545
546 private:
547 const void* m_ptr;
548 bool m_bReadBigEndian;
549 };
550
551 DataReader::DataReader() :
552 m_ptr(0),
553 m_bReadBigEndian(false)
554 {
555 }
556
557 DataReader::~DataReader()
558 {
559 }
560
561 void DataReader::SetPointer(const void* ptr)
562 {
563 m_ptr=ptr;
564 }
565
566 const void *DataReader::GetPointer()
567 {
568 return m_ptr;
569 }
570
571 void DataReader::SetEndian(bool bIsBigEndian)
572 {
573 m_bReadBigEndian=bIsBigEndian;
574 }
575
576 bool DataReader::GetEndian()
577 {
578 return m_bReadBigEndian;
579 }
580
581 unsigned int DataReader::GetValue(int nSizeValue)
582 {
583 unsigned int nvalue=0;
584 unsigned char* ptr=(unsigned char*)m_ptr;
585
586 if (m_bReadBigEndian)
587 {
588 // Big endian
589 // msb...lsb
590 switch (nSizeValue)
591 {
592 case 1:
593 nvalue|=(ptr[0]<<0);
594 break;
595
596 case 2:
597 nvalue|=(ptr[1]<<0);
598 nvalue|=(ptr[0]<<8);
599 break;
600
601 case 4:
602 nvalue|=(ptr[3]<<0);
603 nvalue|=(ptr[2]<<8);
604 nvalue|=(ptr[1]<<16);
605 nvalue|=(ptr[0]<<24);
606 }
607 }
608 else
609 {
610 // Little endian
611 // lsb...msb
612 switch (nSizeValue)
613 {
614 case 1:
615 nvalue|=(ptr[0]<<0);
616 break;
617
618 case 2:
619 nvalue|=(ptr[0]<<0);
620 nvalue|=(ptr[1]<<8);
621 break;
622
623 case 4:
624 nvalue|=(ptr[0]<<0);
625 nvalue|=(ptr[1]<<8);
626 nvalue|=(ptr[2]<<16);
627 nvalue|=(ptr[3]<<24);
628 }
629 }
630
631 ptr+=nSizeValue;
632 m_ptr=(void*)ptr;
633 return nvalue;
634 }
635
636
637
638
639 TextFileGenerator::TextFileGenerator() :
640 m_nDataSize(1),
641 m_nFileType(_eLanguage_Undefined_),
642 m_nEndianness(_eEndianness_Little),
643 m_nNumericBase(_eNumericBase_Hexadecimal),
644 m_nValuesPerLine(16),
645 m_bEnableLineNumber(false),
646 m_nFirstLineNumber(10),
647 m_nIncrementLineNumber(10),
648 m_cLabelName("DefaultLabelName")
649 {
650 }
651
652 TextFileGenerator::~TextFileGenerator()
653 {
654 }
655
656
657 void TextFileGenerator::ConvertData(std::string& cDestString,const void* pSourceData,size_t nFileSize)
658 {
659 if ( ((nFileSize/m_nDataSize)*m_nDataSize)!=nFileSize)
660 {
661 ShowError("The filesize must be a multiple of the data size.");
662 }
663
664 DataReader cDataReader;
665
666 cDataReader.SetPointer(pSourceData);
667 if (m_nEndianness==_eEndianness_Big)
668 {
669 cDataReader.SetEndian(true);
670 }
671 else
672 {
673 cDataReader.SetEndian(false);
674 }
675
676 std::string cHeaderFormatString;
677 std::string cFooterFormatString;
678 std::string cHeaderPreLine;
679 std::string cEntryFormat;
680 std::string cEntrySeparator;
681
682 bool bAddSeparatorOnEndOfLine=false;
683
684 switch (m_nFileType)
685 {
686 case eLanguage_C:
687 cHeaderPreLine="\t";
688 cEntrySeparator=",";
689 bAddSeparatorOnEndOfLine=true;
690 m_bEnableLineNumber=false;
691 switch (m_nDataSize)
692 {
693 case 1:
694 cHeaderFormatString="unsigned char %s[%d]=\r\n{\r\n"; // unsigned char _SampleQuiTue[]={
695 cEntryFormat="0x%02x";
696 break;
697 case 2:
698 cHeaderFormatString="unsigned short %s[%d]=\r\n{\r\n"; // unsigned short _SampleQuiTue[]={
699 cEntryFormat="0x%04x";
700 break;
701 case 4:
702 cHeaderFormatString="unsigned long %s[%d]=\r\n{\r\n"; // unsigned long _SampleQuiTue[]={
703 cEntryFormat="0x%08x";
704 break;
705 }
706 cFooterFormatString="};";
707 break;
708
709 case eLanguage_Assembler:
710 cHeaderFormatString=m_cLabelName+"\r\n"; // _SampleQuiTue
711 cEntrySeparator=",";
712 m_bEnableLineNumber=false;
713 switch (m_nDataSize)
714 {
715 case 1:
716 cHeaderPreLine="\t.byt ";
717 cEntryFormat="$%02x";
718 break;
719 case 2:
720 cHeaderPreLine="\t.word ";
721 cEntryFormat="$%04x";
722 break;
723 case 4:
724 cHeaderPreLine="\t.long ";
725 cEntryFormat="$%08x";
726 break;
727 }
728 break;
729
730 case eLanguage_BASIC:
731 // Basic supports only uppercase hexadecimal letters !
732 cHeaderFormatString=StringFormat("%d REM %s \r\n",m_nFirstLineNumber,m_cLabelName.c_str()); // nnnn REM _SampleQuiTue
733 m_nFirstLineNumber+=m_nIncrementLineNumber;
734 cHeaderPreLine="DATA ";
735 cEntryFormat="#%d";
736 m_bEnableLineNumber=true;
737 switch (m_nDataSize)
738 {
739 case 1:
740 cEntryFormat="#%02X";
741 break;
742 case 2:
743 cEntryFormat="#%04X";
744 break;
745 case 4:
746 cEntryFormat="#%08X"; // That one will probably fail on most 8 bits basics
747 break;
748 }
749 cEntrySeparator=",";
750 break;
751 }
752
753 if (m_nNumericBase==_eNumericBase_Decimal)
754 {
755 // Set to decimal output
756 cEntryFormat="%d";
757 }
758
759 int file_size=nFileSize;
760 int nEntryCount=(file_size+m_nDataSize-1)/m_nDataSize;
761
762 // To avoid numerous memory allocation, pre allocate a string long enough
763 cDestString="";
764 cDestString.reserve(nFileSize*5);
765
766 // Block header
767 cDestString+=StringFormat(cHeaderFormatString.c_str(),m_cLabelName.c_str(),nEntryCount); // unsigned char _SampleQuiTue[]={
768 while (file_size>0)
769 {
770 // Line numbers
771 if (m_bEnableLineNumber)
772 {
773 cDestString+=StringFormat("%d ",m_nFirstLineNumber);
774 m_nFirstLineNumber+=m_nIncrementLineNumber;
775 }
776
777 // Line header
778 cDestString+=cHeaderPreLine;
779
780 // Content of the line
781 for (unsigned long x=0;x<m_nValuesPerLine;x++)
782 {
783 unsigned long c=cDataReader.GetValue(m_nDataSize);
784 file_size-=m_nDataSize;
785 cDestString+=StringFormat(cEntryFormat.c_str(),c);
786 if ((x!=(m_nValuesPerLine-1)) && file_size)
787 {
788 cDestString+=cEntrySeparator;
789 }
790 if (file_size<=0) break;
791 }
792
793 // Optional last separator (for C)
794 if (bAddSeparatorOnEndOfLine && (file_size>0))
795 {
796 cDestString+=cEntrySeparator;
797 }
798
799 // End of line carriage return
800 cDestString+="\r\n";
801 }
802 // Block footer
803 cDestString+=cFooterFormatString;
804
805 // End of file carriage return
806 cDestString+="\r\n";
807 }
808
809

  ViewVC Help
Powered by ViewVC 1.1.26