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