1 /* ______ ___ ___
2 * /\ _ \ /\_ \ /\_ \
3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8 * /\____/
9 * \_/__/
10 *
11 * Emulation for libc routines that may be missing on some platforms.
12 *
13 * By Michael Bukin.
14 *
15 * Henrik Stokseth added _al_sane_realloc() and _al_sane_strncpy() functions.
16 *
17 * _al_srand() and _al_rand() functions based on code by Paul Pridham.
18 *
19 * See readme.txt for copyright information.
20 */
21
22
23 #include "allegro.h"
24 #include "allegro/internal/aintern.h"
25 #include <string.h>
26
27
28 static int _al_rand_seed = 0;
29
30
31
32 #ifdef ALLEGRO_NO_STRLWR
33
34 /* _alemu_strlwr:
35 * Convert all upper case characters in string to lower case.
36 */
_alemu_strlwr(char * string)37 char *_alemu_strlwr(char *string)
38 {
39 char *p;
40 ASSERT(string);
41
42 for (p=string; *p; p++)
43 *p = utolower(*p);
44
45 return string;
46 }
47
48 #endif
49
50
51
52 #ifdef ALLEGRO_NO_STRUPR
53
54 /* _alemu_strupr:
55 * Convert all lower case characters in string to upper case.
56 */
_alemu_strupr(char * string)57 char *_alemu_strupr(char *string)
58 {
59 char *p;
60 ASSERT(string);
61
62 for (p=string; *p; p++)
63 *p = utoupper(*p);
64
65 return string;
66 }
67
68 #endif
69
70
71
72 #ifdef ALLEGRO_NO_STRICMP
73
74 /* _alemu_stricmp:
75 * Case-insensitive comparison of strings.
76 */
_alemu_stricmp(AL_CONST char * s1,AL_CONST char * s2)77 int _alemu_stricmp(AL_CONST char *s1, AL_CONST char *s2)
78 {
79 int c1, c2;
80 ASSERT(s1);
81 ASSERT(s2);
82
83 do {
84 c1 = utolower(*(s1++));
85 c2 = utolower(*(s2++));
86 } while ((c1) && (c1 == c2));
87
88 return c1 - c2;
89 }
90
91 #endif
92
93
94
95 #ifdef ALLEGRO_NO_MEMCMP
96
97 /* _alemu_memcmp:
98 * Comparison of two memory blocks.
99 */
_alemu_memcmp(AL_CONST void * s1,AL_CONST void * s2,size_t num)100 int _alemu_memcmp(AL_CONST void *s1, AL_CONST void *s2, size_t num)
101 {
102 size_t i;
103 ASSERT(s1);
104 ASSERT(s2);
105 ASSERT(num >= 0);
106
107 for (i=0; i<num; i++)
108 if (((unsigned char *)s1)[i] != ((unsigned char *)s2)[i])
109 return ((((unsigned char *)s1)[i] < ((unsigned char *)s2)[i]) ? -1 : 1);
110
111 return 0;
112 }
113
114 #endif
115
116
117
118 /* _al_sane_realloc:
119 * _AL_REALLOC() substitution with guaranteed behaviour.
120 */
_al_sane_realloc(void * ptr,size_t size)121 void *_al_sane_realloc(void *ptr, size_t size)
122 {
123 void *tmp_ptr;
124
125 tmp_ptr = NULL;
126
127 if (ptr && size) {
128 tmp_ptr = _AL_REALLOC(ptr, size);
129 if (!tmp_ptr && ptr) _AL_FREE(ptr);
130 }
131 else if (!size) {
132 tmp_ptr = NULL;
133 if (ptr) _AL_FREE(ptr);
134 }
135 else if (!ptr) {
136 tmp_ptr = _AL_MALLOC(size);
137 }
138
139 return tmp_ptr;
140 }
141
142
143
144 /* _al_sane_strncpy:
145 * strncpy() substitution which properly null terminates a string.
146 */
_al_sane_strncpy(char * dest,const char * src,size_t n)147 char *_al_sane_strncpy(char *dest, const char *src, size_t n)
148 {
149 if (n <= 0)
150 return dest;
151 dest[0] = '\0';
152 strncat(dest, src, n - 1);
153
154 return dest;
155 }
156
157
158
159 /* _al_srand:
160 * Seed initialization routine for rand() replacement.
161 */
_al_srand(int seed)162 void _al_srand(int seed)
163 {
164 _al_rand_seed = seed;
165 }
166
167
168
169 /* _al_rand:
170 * Simple rand() replacement with guaranteed randomness in the lower 16 bits.
171 */
_al_rand(void)172 int _al_rand(void)
173 {
174 _al_rand_seed = (_al_rand_seed + 1) * 1103515245 + 12345;
175 return ((_al_rand_seed >> 16) & _AL_RAND_MAX);
176 }
177