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