/[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 1321 - (show annotations)
Sat Oct 24 15:53:43 2015 UTC (3 years, 11 months ago) by dbug
File size: 18706 byte(s)
coFixed Coverity issues:
- 22101 Leaked file handle on allocation error



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

  ViewVC Help
Powered by ViewVC 1.1.26