/[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 1383 - (show annotations)
Sun Oct 2 17:14:13 2016 UTC (2 years, 11 months ago) by mmu_man
File size: 22227 byte(s)
Fix Linux build (missing defines)

Also remove duplicated define.

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

  ViewVC Help
Powered by ViewVC 1.1.26