Initial import package mtools: Programs for accessing MS-DOS disks without mounting...
[profile/ivi/mtools.git] / missFuncs.c
1 /*  Copyright 1991 Free Software Foundation, Inc.
2  *  Copyright 1997,1999-2002,2007-2009 Alain Knaff.
3  *  This file is part of mtools.
4  *
5  *  Mtools is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  Mtools is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with Mtools.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 #include "sysincludes.h"
19 #include "mtools.h"
20
21 #ifndef HAVE_STRDUP
22
23
24 char *strdup(const char *str)
25 {
26     char *nstr;
27
28     if (str == (char*)0)
29         return 0;
30
31     nstr = (char*)malloc((strlen(str) + 1));
32
33     if (nstr == (char*)0)
34     {
35         (void)fprintf(stderr, "strdup(): not enough memory to duplicate `%s'\n",
36                       str);
37         exit(1);
38     }
39
40     (void)strcpy(nstr, str);
41
42     return nstr;
43 }
44 #endif /* HAVE_STRDUP */
45
46 #ifdef HAVE_WCHAR_H
47 #ifndef HAVE_WCSDUP
48 wchar_t *wcsdup(const wchar_t *wcs)
49 {
50     wchar_t *nwcs;
51
52     if (wcs == (wchar_t*)0)
53         return 0;
54
55     nwcs = (wchar_t*)calloc(wcslen(wcs) + 1, sizeof(wchar_t));
56
57     if (nwcs == (wchar_t*)0)
58     {
59         (void)fprintf(stderr, "wcsdup(): not enough memory to duplicate `%ls'\n",
60                       wcs);
61         exit(1);
62     }
63
64     (void)wcscpy(nwcs, wcs);
65
66     return nwcs;
67 }
68 #endif /* HAVE_WCSDUP */
69 #endif
70
71 #ifndef HAVE_MEMCPY
72 /*
73  * Copy contents of memory (with possible overlapping).
74  */
75 char *memcpy(char *s1, const char *s2, size_t n)
76 {
77         bcopy(s2, s1, n);
78         return(s1);
79 }
80 #endif
81
82 #ifndef HAVE_MEMSET
83 /*
84  * Copies the character c, n times to string s
85  */
86 char *memset(char *s, char c, size_t n)
87 {
88         char *s1 = s;
89
90         while (n > 0) {
91                 --n;
92                 *s++ = c;
93         }
94         return(s1);
95 }
96 #endif /* HAVE_MEMSET */
97
98
99 #ifndef HAVE_STRCHR
100
101 char * strchr (const char* s, int c)
102 {
103         if (!s) return NULL;
104         while (*s && *s != c) s++;
105         if (*s) 
106                 return (char*) s;
107         else
108                 return NULL;
109 }
110
111 #endif
112
113 #ifndef HAVE_STRRCHR
114
115 char * strrchr (const char* s1, int c) 
116 {
117         char* s = (char*) s1;
118         char* start = (char*) s;
119         if (!s) return NULL;
120         s += strlen(s)-1;
121         while (*s != c && (unsigned long) s != (unsigned long) start) s--;
122         if ((unsigned long) s == (unsigned long) start && *s != c)
123                 return NULL;
124         else
125                 return s;
126 }
127
128 #endif
129
130 #ifndef HAVE_STRPBRK
131 /*
132  * Return ptr to first occurrence of any character from `brkset'
133  * in the character string `string'; NULL if none exists.
134  */
135 char *strpbrk(const char *string, const char *brkset)
136 {
137         register char *p;
138
139         if (!string || !brkset)
140                 return(0);
141         do {
142                 for (p = brkset; *p != '\0' && *p != *string; ++p)
143                         ;
144                 if (*p != '\0')
145                         return(string);
146         }
147         while (*string++);
148         return(0);
149 }
150 #endif /* HAVE_STRPBRK */
151
152
153 #ifndef HAVE_STRTOUL
154 static int getdigit(char a, int max)
155 {
156         int dig;
157         
158         if(a < '0')
159                 return -1;
160         if(a <= '9') {
161                 dig = a - '0';
162         } else if(a >= 'a')
163                 dig = a - 'a' + 10;
164         else if(a >= 'A')
165                 dig = a - 'A' + 10;
166         if(dig >= max)
167                 return -1;
168         else
169                 return dig;
170 }
171
172 unsigned long strtoul(const char *string, char **eptr, int base)
173 {
174         int accu, dig;
175
176         if(base < 1 || base > 36) {
177                 if(string[0] == '0') {
178                         switch(string[1]) {
179                                 case 'x':
180                                 case 'X':
181                                         return strtoul(string+2, eptr, 16);
182                                 case 'b':
183                                 case 'B':
184                                         return strtoul(string+2, eptr, 2);
185                                 default:
186                                         return strtoul(string, eptr, 8);
187                         }
188                 }
189                 return strtoul(string, eptr, 10);
190         }
191         if(base == 16 && string[0] == '0' &&
192            (string[1] == 'x' || string[1] == 'X'))
193                 string += 2;
194
195         if(base == 2 && string[0] == '0' &&
196            (string[1] == 'b' || string[1] == 'B'))
197                 string += 2;
198         accu = 0;
199         while( (dig = getdigit(*string, base)) != -1 ) {
200                 accu = accu * base + dig;
201                 string++;
202         }
203         if(eptr)
204                 *eptr = (char *) string;
205         return accu;
206 }
207 #endif /* HAVE_STRTOUL */
208
209 #ifndef HAVE_STRTOL
210 long strtol(const char *string, char **eptr, int base)
211 {
212         long l;
213
214         if(*string == '-') {
215                 return -(long) strtoul(string+1, eptr, base);
216         } else {
217                 if (*string == '+')
218                         string ++;
219                 return (long) strtoul(string, eptr, base);
220         }
221 }
222 #endif
223
224
225
226 #ifndef HAVE_STRSPN
227 /* Return the length of the maximum initial segment
228    of S which contains only characters in ACCEPT.  */
229 size_t strspn(const char *s, const char *accept)
230 {
231   register char *p;
232   register char *a;
233   register size_t count = 0;
234
235   for (p = s; *p != '\0'; ++p)
236     {
237       for (a = accept; *a != '\0'; ++a)
238         if (*p == *a)
239           break;
240       if (*a == '\0')
241         return count;
242       else
243         ++count;
244     }
245
246   return count;
247 }
248 #endif /* HAVE_STRSPN */
249
250 #ifndef HAVE_STRCSPN
251 /* Return the length of the maximum inital segment of S
252    which contains no characters from REJECT.  */
253 size_t strcspn (const char *s, const char *reject)
254 {
255   register size_t count = 0;
256
257   while (*s != '\0')
258     if (strchr (reject, *s++) == NULL)
259       ++count;
260     else
261       return count;
262
263   return count;
264 }
265
266 #endif /* HAVE_STRCSPN */
267
268 #ifndef HAVE_STRERROR
269
270 #ifndef DECL_SYS_ERRLIST
271 extern char *sys_errlist[];
272 #endif
273
274 char *strerror(int errno)
275 {
276   return sys_errlist[errno];
277 }
278 #endif
279
280 #ifndef HAVE_STRCASECMP
281 /* Compare S1 and S2, ignoring case, returning less than, equal to or
282    greater than zero if S1 is lexiographically less than,
283    equal to or greater than S2.  */
284 int strcasecmp(const char *s1, const char *s2)
285 {
286   register const unsigned char *p1 = (const unsigned char *) s1;
287   register const unsigned char *p2 = (const unsigned char *) s2;
288   unsigned char c1, c2;
289
290   if (p1 == p2)
291     return 0;
292
293   do
294     {
295       c1 = tolower (*p1++);
296       c2 = tolower (*p2++);
297       if (c1 == '\0')
298         break;
299     }
300   while (c1 == c2);
301
302   return c1 - c2;
303 }
304 #endif
305
306 #ifdef HAVE_WCHAR_H
307 #ifndef HAVE_WCSCASECMP
308 /* Compare S1 and S2, ignoring case, returning less than, equal to or
309    greater than zero if S1 is lexiographically less than,
310    equal to or greater than S2.  */
311 int wcscasecmp(const wchar_t *s1, const wchar_t *s2)
312 {
313   register const wchar_t *p1 = s1;
314   register const wchar_t *p2 = s2;
315   wchar_t c1, c2;
316
317   if (p1 == p2)
318     return 0;
319
320   do
321     {
322       c1 = towlower (*p1++);
323       c2 = towlower (*p2++);
324       if (c1 == '\0')
325         break;
326     }
327   while (c1 == c2);
328
329   return c1 - c2;
330 }
331 #endif
332 #endif
333
334
335 #ifndef HAVE_STRCASECMP
336 /* Compare S1 and S2, ignoring case, returning less than, equal to or
337    greater than zero if S1 is lexiographically less than,
338    equal to or greater than S2.  */
339 int strncasecmp(const char *s1, const char *s2, size_t n)
340 {
341   register const unsigned char *p1 = (const unsigned char *) s1;
342   register const unsigned char *p2 = (const unsigned char *) s2;
343   unsigned char c1, c2;
344
345   if (p1 == p2)
346     return 0;
347
348   c1 = c2 = 1;
349   while (c1 && c1 == c2 && n-- > 0)
350     {
351       c1 = tolower (*p1++);
352       c2 = tolower (*p2++);
353     }
354
355   return c1 - c2;
356 }
357 #endif
358
359 #ifndef HAVE_GETPASS
360 char *getpass(const char *prompt)
361 {
362         static char password[129];
363         int l;
364
365         fprintf(stderr,"%s",prompt);
366         fgets(password, 128, stdin);
367         l = strlen(password);
368         if(l && password[l-1] == '\n')
369                 password[l-1] = '\0';
370         return password;
371
372 }
373 #endif
374
375 #ifndef HAVE_ATEXIT
376
377 #ifdef HAVE_ON_EXIT
378 int atexit(void (*function)(void))
379 {
380         return on_exit( (void(*)(int,void*)) function, 0);
381 }
382 #else
383
384 typedef struct exitCallback {
385         void (*function) (void);
386         struct exitCallback *next;
387 } exitCallback_t;
388
389 static exitCallback_t *callback = 0;
390
391 int atexit(void (*function) (void))
392 {
393         exitCallback_t *newCallback;
394                 
395         newCallback = New(exitCallback_t);
396         if(!newCallback) {
397                 printOom();
398                 exit(1);
399         }
400         newCallback->function = function;
401         newCallback->next = callback;
402         callback = newCallback;
403         return 0;
404 }
405 #undef exit
406
407 void myexit(int code)
408 {
409   void (*function)(void);
410
411   while(callback) {
412     function = callback->function;
413     callback = callback->next;
414     function();
415   }
416   exit(code);
417 }
418
419 #endif
420
421 #endif
422
423 static const char PATH_SEP = '/';
424
425 /*#ifndef HAVE_BASENAME*/
426 const char *_basename(const char *filename)
427 {
428         char *ptr;
429
430         ptr = strrchr(filename, PATH_SEP);
431         if(ptr)
432                 filename = ptr + 1;
433
434 #ifdef OS_mingw32msvc
435         ptr = strrchr(filename, '\\');
436         if(ptr)
437                 filename = ptr + 1;
438 #endif
439
440         return filename;
441 }
442 /*#endif*/
443
444 /* Strip the suffix ".exe" from the argument, if present. */
445 void _stripexe(char *filename)
446 {
447         char *ptr;
448         ptr = strrchr(filename, '.');
449         if(ptr && !strcasecmp(ptr, ".exe"))
450                 *ptr = '\0';
451 }
452
453 #ifndef HAVE_STRNLEN
454 size_t strnlen(const char *str, size_t l)
455 {
456   size_t i;
457   for(i=0; i<l; i++) {
458     if(str[i] == 0)
459       break;
460   }
461   return i;
462 }
463 #endif /* HAVE_STRNLEN */
464
465 #ifdef HAVE_WCHAR_H
466 #ifndef HAVE_WCSNLEN
467 size_t wcsnlen(const wchar_t *wcs, size_t l)
468 {
469   size_t i;
470   for(i=0; i<l; i++) {
471     if(wcs[i] == 0)
472       break;
473   }
474   return i;
475 }
476 #endif /* HAVE_WCSNLEN */
477 #endif