1 #include "rar.hpp"
2 
NullToEmpty(const char * Str)3 const char *NullToEmpty(const char *Str)
4 {
5   return(Str==NULL ? "":Str);
6 }
7 
8 
NullToEmpty(const wchar * Str)9 const wchar *NullToEmpty(const wchar *Str)
10 {
11   return(Str==NULL ? L"":Str);
12 }
13 
14 
15 
16 
IntNameToExt(const char * Name)17 char *IntNameToExt(const char *Name)
18 {
19   static char OutName[NM];
20   IntToExt(Name,OutName);
21   return(OutName);
22 }
23 
24 
ExtToInt(const char * Src,char * Dest)25 void ExtToInt(const char *Src,char *Dest)
26 {
27 #ifdef _WIN_ALL
28   CharToOemA(Src,Dest);
29 #else
30   if (Dest!=Src)
31     strcpy(Dest,Src);
32 #endif
33 }
34 
35 
IntToExt(const char * Src,char * Dest)36 void IntToExt(const char *Src,char *Dest)
37 {
38 #ifdef _WIN_ALL
39   OemToCharA(Src,Dest);
40 #else
41   if (Dest!=Src)
42     strcpy(Dest,Src);
43 #endif
44 }
45 
46 
strlower(char * Str)47 char* strlower(char *Str)
48 {
49 #ifdef _WIN_ALL
50   CharLowerA((LPSTR)Str);
51 #else
52   for (char *ChPtr=Str;*ChPtr;ChPtr++)
53     *ChPtr=(char)loctolower(*ChPtr);
54 #endif
55   return(Str);
56 }
57 
58 
strupper(char * Str)59 char* strupper(char *Str)
60 {
61 #ifdef _WIN_ALL
62   CharUpperA((LPSTR)Str);
63 #else
64   for (char *ChPtr=Str;*ChPtr;ChPtr++)
65     *ChPtr=(char)loctoupper(*ChPtr);
66 #endif
67   return(Str);
68 }
69 
70 
stricomp(const char * Str1,const char * Str2)71 int stricomp(const char *Str1,const char *Str2)
72 {
73   char S1[NM*2],S2[NM*2];
74   strncpyz(S1,Str1,ASIZE(S1));
75   strncpyz(S2,Str2,ASIZE(S2));
76   return(strcmp(strupper(S1),strupper(S2)));
77 }
78 
79 
strnicomp(const char * Str1,const char * Str2,size_t N)80 int strnicomp(const char *Str1,const char *Str2,size_t N)
81 {
82   char S1[NM*2],S2[NM*2];
83   strncpyz(S1,Str1,ASIZE(S1));
84   strncpyz(S2,Str2,ASIZE(S2));
85   return(strncmp(strupper(S1),strupper(S2),N));
86 }
87 
88 
RemoveEOL(char * Str)89 char* RemoveEOL(char *Str)
90 {
91   for (int I=(int)strlen(Str)-1;I>=0 && (Str[I]=='\r' || Str[I]=='\n' || Str[I]==' ' || Str[I]=='\t');I--)
92     Str[I]=0;
93   return(Str);
94 }
95 
96 
RemoveLF(char * Str)97 char* RemoveLF(char *Str)
98 {
99   for (int I=(int)strlen(Str)-1;I>=0 && (Str[I]=='\r' || Str[I]=='\n');I--)
100     Str[I]=0;
101   return(Str);
102 }
103 
104 
RemoveLF(wchar * Str)105 wchar* RemoveLF(wchar *Str)
106 {
107   for (int I=(int)wcslen(Str)-1;I>=0 && (Str[I]=='\r' || Str[I]=='\n');I--)
108     Str[I]=0;
109   return(Str);
110 }
111 
112 
loctolower(unsigned char ch)113 unsigned char loctolower(unsigned char ch)
114 {
115 #ifdef _WIN_ALL
116   // Convert to LPARAM first to avoid a warning in 64 bit mode.
117   return((int)(LPARAM)CharLowerA((LPSTR)ch));
118 #else
119   return(tolower(ch));
120 #endif
121 }
122 
123 
loctoupper(unsigned char ch)124 unsigned char loctoupper(unsigned char ch)
125 {
126 #ifdef _WIN_ALL
127   // Convert to LPARAM first to avoid a warning in 64 bit mode.
128   return((int)(LPARAM)CharUpperA((LPSTR)ch));
129 #else
130   return(toupper(ch));
131 #endif
132 }
133 
134 
135 // toupper with English only results if English input is provided.
136 // It avoids Turkish (small i) -> (big I with dot) conversion problem.
137 // We do not define 'ch' as 'int' to avoid necessity to cast all
138 // signed chars passed to this function to unsigned char.
etoupper(unsigned char ch)139 unsigned char etoupper(unsigned char ch)
140 {
141   if (ch=='i')
142     return('I');
143   return(toupper(ch));
144 }
145 
146 
147 // Unicode version of etoupper.
etoupperw(wchar ch)148 wchar etoupperw(wchar ch)
149 {
150   if (ch=='i')
151     return('I');
152   return(toupperw(ch));
153 }
154 
155 
156 // We do not want to cast every signed char to unsigned when passing to
157 // isdigit, so we implement the replacement. Shall work for Unicode too.
158 // If chars are signed, conversion from char to int could generate negative
159 // values, resulting in undefined behavior in standard isdigit.
IsDigit(int ch)160 bool IsDigit(int ch)
161 {
162   return(ch>='0' && ch<='9');
163 }
164 
165 
166 // We do not want to cast every signed char to unsigned when passing to
167 // isspace, so we implement the replacement. Shall work for Unicode too.
168 // If chars are signed, conversion from char to int could generate negative
169 // values, resulting in undefined behavior in standard isspace.
IsSpace(int ch)170 bool IsSpace(int ch)
171 {
172   return(ch==' ' || ch=='\t');
173 }
174 
175 
176 // We do not want to cast every signed char to unsigned when passing to
177 // isalpha, so we implement the replacement. Shall work for Unicode too.
178 // If chars are signed, conversion from char to int could generate negative
179 // values, resulting in undefined behavior in standard function.
IsAlpha(int ch)180 bool IsAlpha(int ch)
181 {
182   return(ch>='A' && ch<='Z' || ch>='a' && ch<='z');
183 }
184 
185 
186 
187 
188 #ifndef SFX_MODULE
GetDigits(uint Number)189 uint GetDigits(uint Number)
190 {
191   uint Digits=1;
192   while (Number>=10)
193   {
194     Number/=10;
195     Digits++;
196   }
197   return(Digits);
198 }
199 #endif
200 
201 
LowAscii(const char * Str)202 bool LowAscii(const char *Str)
203 {
204   for (int I=0;Str[I]!=0;I++)
205     if ((byte)Str[I]<32 || (byte)Str[I]>127)
206       return(false);
207   return(true);
208 }
209 
210 
LowAscii(const wchar * Str)211 bool LowAscii(const wchar *Str)
212 {
213   for (int I=0;Str[I]!=0;I++)
214   {
215     // We convert wchar_t to uint just in case if some compiler
216     // uses the signed wchar_t.
217     if ((uint)Str[I]<32 || (uint)Str[I]>127)
218       return(false);
219   }
220   return(true);
221 }
222 
223 
224 
225 
stricompc(const char * Str1,const char * Str2)226 int stricompc(const char *Str1,const char *Str2)
227 {
228 #if defined(_UNIX)
229   return(strcmp(Str1,Str2));
230 #else
231   return(stricomp(Str1,Str2));
232 #endif
233 }
234 
235 
236 #ifndef SFX_MODULE
wcsicompc(const wchar * Str1,const wchar * Str2)237 int wcsicompc(const wchar *Str1,const wchar *Str2)
238 {
239 #if defined(_UNIX)
240   return(wcscmp(Str1,Str2));
241 #else
242   return(wcsicomp(Str1,Str2));
243 #endif
244 }
245 #endif
246 
247 
248 // safe strncpy: copies maxlen-1 max and always returns zero terminated dest
strncpyz(char * dest,const char * src,size_t maxlen)249 char* strncpyz(char *dest, const char *src, size_t maxlen)
250 {
251   if (maxlen>0)
252   {
253     strncpy(dest,src,maxlen-1);
254     dest[maxlen-1]=0;
255   }
256   return(dest);
257 }
258 
259 
260 // Safe wcsncpy: copies maxlen-1 max and always returns zero terminated dest.
wcsncpyz(wchar * dest,const wchar * src,size_t maxlen)261 wchar* wcsncpyz(wchar *dest, const wchar *src, size_t maxlen)
262 {
263   if (maxlen>0)
264   {
265     wcsncpy(dest,src,maxlen-1);
266     dest[maxlen-1]=0;
267   }
268   return(dest);
269 }
270 
271 
272 // Safe strncat: resulting dest length cannot exceed maxlen and dest
273 // is always zero terminated. Note that 'maxlen' parameter defines the entire
274 // dest buffer size and is not compatible with standard strncat.
strncatz(char * dest,const char * src,size_t maxlen)275 char* strncatz(char* dest, const char* src, size_t maxlen)
276 {
277   size_t Length = strlen(dest);
278   if (Length + 1 < maxlen)
279     strncat(dest, src, maxlen - Length - 1);
280   return dest;
281 }
282 
283 
284 // Safe wcsncat: resulting dest length cannot exceed maxlen and dest
285 // is always zero terminated. Note that 'maxlen' parameter defines the entire
286 // dest buffer size and is not compatible with standard wcsncat.
wcsncatz(wchar * dest,const wchar * src,size_t maxlen)287 wchar* wcsncatz(wchar* dest, const wchar* src, size_t maxlen)
288 {
289   size_t Length = wcslen(dest);
290   if (Length + 1 < maxlen)
291     wcsncat(dest, src, maxlen - Length - 1);
292   return dest;
293 }
294 
295 
itoa(int64 n,char * Str)296 void itoa(int64 n,char *Str)
297 {
298   char NumStr[50];
299   size_t Pos=0;
300 
301   do
302   {
303     NumStr[Pos++]=char(n%10)+'0';
304     n=n/10;
305   } while (n!=0);
306 
307   for (size_t I=0;I<Pos;I++)
308     Str[I]=NumStr[Pos-I-1];
309   Str[Pos]=0;
310 }
311 
312 
313 
atoil(const char * Str)314 int64 atoil(const char *Str)
315 {
316   int64 n=0;
317   while (*Str>='0' && *Str<='9')
318   {
319     n=n*10+*Str-'0';
320     Str++;
321   }
322   return(n);
323 }
324 
325 
itoa(int64 n,wchar * Str)326 void itoa(int64 n,wchar *Str)
327 {
328   wchar NumStr[50];
329   size_t Pos=0;
330 
331   do
332   {
333     NumStr[Pos++]=wchar(n%10)+'0';
334     n=n/10;
335   } while (n!=0);
336 
337   for (size_t I=0;I<Pos;I++)
338     Str[I]=NumStr[Pos-I-1];
339   Str[Pos]=0;
340 }
341 
342 
atoil(const wchar * Str)343 int64 atoil(const wchar *Str)
344 {
345   int64 n=0;
346   while (*Str>='0' && *Str<='9')
347   {
348     n=n*10+*Str-'0';
349     Str++;
350   }
351   return(n);
352 }
353 
354 
GetWide(const char * Src)355 const wchar* GetWide(const char *Src)
356 {
357   const size_t MaxLength=NM;
358   static wchar StrTable[4][MaxLength];
359   static uint StrNum=0;
360   if (++StrNum >= ASIZE(StrTable))
361     StrNum=0;
362   wchar *Str=StrTable[StrNum];
363   CharToWide(Src,Str,MaxLength);
364   Str[MaxLength-1]=0;
365   return(Str);
366 }
367 
368 
369 #ifdef _WIN_ALL
370 // Parse string containing parameters separated with spaces.
371 // Support quote marks. Param can be NULL to return the pointer to next
372 // parameter, which can be used to estimate the buffer size for Param.
GetCmdParam(const wchar * CmdLine,wchar * Param,size_t MaxSize)373 const wchar* GetCmdParam(const wchar *CmdLine,wchar *Param,size_t MaxSize)
374 {
375   while (IsSpace(*CmdLine))
376     CmdLine++;
377   if (*CmdLine==0)
378     return NULL;
379 
380   size_t ParamSize=0;
381   bool Quote=false;
382   while (*CmdLine!=0 && (Quote || !IsSpace(*CmdLine)))
383   {
384     if (*CmdLine=='\"')
385     {
386       if (CmdLine[1]=='\"')
387       {
388         // Insert the quote character instead of two adjoining quote characters.
389         if (Param!=NULL && ParamSize<MaxSize-1)
390           Param[ParamSize++]='\"';
391         CmdLine++;
392       }
393       else
394         Quote=!Quote;
395     }
396     else
397       if (Param!=NULL && ParamSize<MaxSize-1)
398         Param[ParamSize++]=*CmdLine;
399     CmdLine++;
400   }
401   if (Param!=NULL)
402     Param[ParamSize]=0;
403   return CmdLine;
404 }
405 #endif
406