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

  ViewVC Help
Powered by ViewVC 1.1.26