]> icculus.org git repositories - taylor/freespace2.git/blob - src/platform/unix.cpp
const-char warning fixes
[taylor/freespace2.git] / src / platform / unix.cpp
1 #include <unistd.h>
2 #include <stdio.h>
3 #include <stdarg.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <ctype.h>
7 #include <errno.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10
11 #include "pstypes.h"
12
13 // use system versions of this stuff in here rather than the vm_* versions
14 #undef malloc
15 #undef free
16 #undef strdup
17
18
19 #define MAX_LINE_WIDTH 128
20
21 void strlwr (char * str)
22 {
23         while (*str) {*str = tolower (*str); str++; }
24 }
25
26 void strupr (char * str)
27 {
28         while (*str) {*str = toupper (*str); str++; }
29 }
30
31 int filelength (int fd)
32 {
33         struct stat buf;
34         if (fstat (fd, &buf) == -1)
35                 return -1;
36                 
37         return buf.st_size;
38 }
39
40 unsigned long _beginthread (void (*pfuncStart)(void *), unsigned unStackSize, void* pArgList)
41 {
42         STUB_FUNCTION;
43         
44         return 0;
45 }
46
47 void Sleep (int mili)
48 {
49 #ifdef __APPLE__
50         // ughh, SDL_Delay causes a slowdown on Tiger for some reason and though I hate
51         // doing this, even the few Apple examples I've seen do this over what SDL_Delay does.
52         uint then = SDL_GetTicks() + mili;
53
54         while ( then > SDL_GetTicks() );
55 #else
56         SDL_Delay( long(mili) );
57 #endif
58 }
59
60 void OutputDebugString (const char *str)
61 {
62         fprintf(stderr, "OutputDebugString: %s\n", str);
63 }
64
65 int WSAGetLastError()
66 {
67         return errno;
68 }
69
70 // make specified directory, recursively
71 // NOTE: since this is for use with CFILE this code assumes that there will be a trailing '/'
72 //       or a trailing filename.  any directory name not followed by a '/' will be considered a file
73 int _mkdir(const char *path)
74 {
75         int status = 1;         // if we don't ever call mkdir() to update this then assume we are in error
76         char *c, tmp_path[MAX_PATH];
77
78         memset(tmp_path, 0, MAX_PATH);
79         strncpy(tmp_path, path, MAX_PATH-1);
80
81         c = &tmp_path[1];
82
83         while (c++) {
84                 c = strchr(c, '/');
85
86                 if (c) {
87                         *c = '\0';
88
89                         status = mkdir(tmp_path, 0700);
90
91 #ifndef NDEBUG
92                         int m_error = errno;
93
94                         if (status && (m_error != EEXIST) ) {
95                                 Warning(__FILE__, __LINE__, "Cannot mkdir %s: %s", tmp_path, strerror(m_error));
96                         }
97 #endif
98
99                         *c = '/';
100                 }
101         }
102
103         return status;
104 }
105
106 void _splitpath (const char *path, char *drive, char *dir, char *fname, char *ext)
107 {
108         if (path == NULL)
109                 return;
110
111         /* fs2 only uses fname */
112         if (fname != NULL) {
113                 const char *ls = strrchr(path, '/');
114                 if (ls != NULL) {
115                         ls++;           // move past '/'
116                 } else {
117                         ls = path;
118                 }
119         
120                 const char *lp = strrchr(path, '.');
121                 if (lp == NULL) {
122                         lp = ls + strlen(ls);   // move to the end
123                 }
124         
125                 int dist = lp-ls;
126                 if (dist > (_MAX_FNAME-1))
127                         dist = _MAX_FNAME-1;
128                 
129                 strncpy(fname, ls, dist);
130                 fname[dist] = 0;        // add null, just in case
131         }
132 }
133
134 int MulDiv(int a, int b, int c)
135 {
136         /* slow long long version */
137         __extension__ long long aa = a;
138         __extension__ long long bb = b;
139         __extension__ long long cc = c;
140         
141         __extension__ long long dd = aa * bb;
142         __extension__ long long ee = dd / cc;
143         
144         int retr = (int) ee;
145         
146         return retr;
147 }
148
149 /* mem debug junk */
150 #ifndef NDEBUG
151 //#define WANT_DEBUG
152 #endif
153
154 int TotalRam = 0;
155
156 #ifdef WANT_DEBUG
157 typedef struct RAM {
158         void *addr;
159         int size;
160         
161         char *file;
162         int line;
163         
164         RAM *next;
165 } RAM;
166
167 static RAM *RamTable;
168 #endif
169
170 #ifndef NDEBUG
171 void vm_free(void* ptr, const char *file, int line)
172 #else
173 void vm_free(void* ptr)
174 #endif
175 {
176 #ifdef WANT_DEBUG
177         fprintf(stderr, "FREE: %s:%d addr = %p\n", file, line, ptr);
178         
179         RAM *item = RamTable;
180         RAM **mark = &RamTable;
181         
182         while (item != NULL) {
183                 if (item->addr == ptr) {
184                         RAM *tmp = item;
185                         
186                         *mark = item->next;
187                         
188                         free(tmp->addr);
189                         free(tmp);
190                         
191                         return;
192                 }
193                 
194                 mark = &(item->next);
195                 
196                 item = item->next;
197         }
198         
199         fprintf(stderr, "ERROR: vm_free caught invalid free: addr = %p, file = %s/%d\n", ptr, file, line);
200 #else   
201         free(ptr);
202 #endif
203 }
204
205 #ifndef NDEBUG
206 void *vm_malloc(int size, const char *file, int line)
207 #else
208 void *vm_malloc(int size)
209 #endif
210 {
211 #ifdef WANT_DEBUG
212         fprintf(stderr, "MALLOC: %s:%d %d bytes\n", file, line, size);
213         
214         RAM *next = (RAM *)malloc(sizeof(RAM));
215         
216         next->addr = malloc(size);
217         next->size = size;
218         next->file = file;
219         next->line = line;
220         
221         next->next = RamTable;
222         RamTable = next;
223         
224         return next->addr;
225 #else
226         return malloc(size);
227 #endif  
228 }
229
230 #ifndef NDEBUG
231 char *vm_strdup(char const* str, const char *file, int line)
232 #else
233 char *vm_strdup(char const* str)
234 #endif
235 {
236 #ifdef WANT_DEBUG
237         fprintf(stderr, "STRDUP: %s:%d\n", file, line);
238         
239         RAM *next = (RAM *)malloc(sizeof(RAM));
240         
241         next->addr = strdup(str);
242         next->size = strlen(str)+1;
243         next->file = file;
244         next->line = line;
245         
246         next->next = RamTable;
247         RamTable = next;
248         
249         return (char *)next->addr;
250 #else
251         return strdup(str);
252 #endif
253 }
254
255 void vm_dump()
256 {
257 #ifdef WANT_DEBUG
258         int i = 0;
259         int mem = 0;
260         fprintf(stderr, "\nDumping allocated memory:\n");
261         
262         RAM *ptr = RamTable;
263         while (ptr) {
264                 fprintf(stderr, "%d: file: %s:%d: addr:%p size:%d\n", i, ptr->file, ptr->line, ptr->addr, ptr->size);
265                 mem += ptr->size;
266                 ptr = ptr->next;
267                 i++;
268         }
269         
270         fprintf(stderr, "\nTotal of %d left-over bytes from %d allocations\n", mem, i);
271 #endif  
272 }
273
274 void windebug_memwatch_init()
275 {
276         TotalRam = 0;
277 }
278
279 /* error message debugging junk */
280 /*
281 int Log_debug_output_to_file = 0;
282
283 void load_filter_info(void)
284 {
285 //      STUB_FUNCTION;
286 }
287
288 void outwnd_printf(char* id, char* format, ...)
289 {
290         char tmp[MAX_LINE_WIDTH*4];
291         va_list args;
292
293         va_start (args, format);
294         vsprintf (tmp, format, args);
295         va_end(args);
296         fprintf (stderr, "%s: %s\n", id, tmp);
297 }
298
299 void outwnd_printf2(char* format, ...)
300 {
301         char tmp[MAX_LINE_WIDTH*4];
302         va_list args;
303
304         va_start (args, format);
305         vsprintf (tmp, format, args);
306         va_end(args);
307         fprintf (stderr, "General: %s", tmp);
308 }
309
310 void outwnd_close()
311 {
312 //      STUB_FUNCTION;
313 }
314 */
315 void Warning( const char * filename, int line, const char * format, ... )
316 {
317         char tmp[MAX_LINE_WIDTH*4];
318         va_list args;
319
320         va_start (args, format);
321         vsprintf (tmp, format, args);
322         va_end(args);
323         fprintf (stderr, "Warning: (%s:%d): %s\n", filename, line, tmp);
324 }
325
326 void Error( const char * filename, int line, const char * format, ... )
327 {
328         char tmp[MAX_LINE_WIDTH*4];
329         va_list args;
330
331         va_start (args, format);
332         vsprintf (tmp, format, args);
333         va_end(args);
334         fprintf (stderr, "Error: (%s:%d): %s\n", filename, line, tmp);
335         exit (1);
336 }
337
338 void WinAssert(const char * text, const char *filename, int line)
339 {
340         fprintf (stderr, "Assertion: (%s:%d) %s\n", filename, line, text);
341 //      exit(1);
342 }