more eol-style
[xonotic/netradiant.git] / libs / cmdlib / cmdlib.cpp
1 /*
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 //
23 // start of shared cmdlib stuff
24 // 
25
26 #include "cmdlib.h"
27
28 #ifdef _WIN32
29   #include <windows.h>
30 #endif
31 #if defined (__linux__) || defined (__APPLE__)
32   #include <unistd.h>
33 #endif
34
35 // FIXME TTimo this should be cleaned up ..
36 // NOTE: we don't use this crap .. with the total mess of mixing win32/unix paths we need to recognize both '/' and '\\'
37 #define PATHSEPERATOR   '/'
38
39 #if defined (__linux__) || defined (__APPLE__)
40 bool Q_Exec(const char *cmd, char *cmdline, const char *execdir, bool bCreateConsole)
41 {
42   char fullcmd[2048];
43   char *pCmd;
44 #ifdef _DEBUG
45   printf("Q_Exec damnit\n");
46 #endif
47   switch (fork())
48   {
49   case -1:
50     return true;
51     break;
52   case 0:
53     // always concat the command on linux
54     if (cmd)
55     {
56       strcpy(fullcmd, cmd);
57     }
58     else
59       fullcmd[0] = '\0';
60     if (cmdline)
61     {
62       strcat(fullcmd, " ");
63       strcat(fullcmd, cmdline);
64     }
65     pCmd = fullcmd;
66     while (*pCmd == ' ')
67       pCmd++;
68 #ifdef _DEBUG
69     printf("Running system...\n");
70     printf("Command: %s\n", pCmd);
71 #endif
72     system( pCmd );
73 #ifdef _DEBUG
74     printf ("system() returned\n");
75 #endif
76     _exit (0);
77     break;
78   }
79   return true;
80 }
81 #endif
82
83 #ifdef _WIN32
84 // NOTE TTimo windows is VERY nitpicky about the syntax in CreateProcess
85 bool Q_Exec(const char *cmd, char *cmdline, const char *execdir, bool bCreateConsole)
86 {
87   PROCESS_INFORMATION ProcessInformation;
88   STARTUPINFO startupinfo = {0};
89   DWORD dwCreationFlags;
90   GetStartupInfo (&startupinfo);
91   if (bCreateConsole)
92     dwCreationFlags = CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS;
93   else
94     dwCreationFlags = DETACHED_PROCESS | NORMAL_PRIORITY_CLASS;
95   const char *pCmd;
96   char *pCmdline;
97   pCmd = cmd;
98   if (pCmd)
99   {
100     while (*pCmd == ' ')
101       pCmd++;
102   }
103   pCmdline = cmdline;
104   if (pCmdline)
105   {
106     while (*pCmdline == ' ')
107       pCmdline++;
108   }
109   if (CreateProcess(
110                     pCmd,
111                     pCmdline,
112                     NULL,
113                     NULL,
114                     FALSE,
115                     dwCreationFlags,
116                     NULL,
117                     execdir,
118                     &startupinfo,
119                     &ProcessInformation
120                     ))
121     return true;
122   return false;
123 }
124 #endif
125
126 #define MEM_BLOCKSIZE 4096
127 void* qblockmalloc(size_t nSize)
128 {
129   void *b;
130   // round up to threshold
131   int nAllocSize = nSize % MEM_BLOCKSIZE;
132   if ( nAllocSize > 0)
133   {
134     nSize += MEM_BLOCKSIZE - nAllocSize;
135   }
136   b = malloc(nSize + 1);
137   memset (b, 0, nSize);
138   return b;
139 }
140
141 //++timo NOTE: can be replaced by g_malloc0(nSize+1) when moving to glib memory handling
142 void* qmalloc (size_t nSize)
143 {
144   void *b;
145   b = malloc(nSize + 1);
146   memset (b, 0, nSize);
147   return b;
148 }
149
150 /*
151 ================
152 Q_filelength
153 ================
154 */
155 int Q_filelength (FILE *f)
156 {
157   int   pos;
158   int   end;
159
160   pos = ftell (f);
161   fseek (f, 0, SEEK_END);
162   end = ftell (f);
163   fseek (f, pos, SEEK_SET);
164
165   return end;
166 }
167
168 void DefaultExtension (char *path, char *extension)
169 {
170   char    *src;
171 //
172 // if path doesn't have a .EXT, append extension
173 // (extension should include the .)
174 //
175   src = path + strlen(path) - 1;
176
177   while (*src != PATHSEPERATOR && src != path)
178   {
179     if (*src == '.')
180       return;                 // it has an extension
181     src--;
182   }
183
184   strcat (path, extension);
185 }
186
187 void DefaultPath (char *path, char *basepath)
188 {
189   char    temp[128];
190
191   if (path[0] == PATHSEPERATOR)
192     return;                   // absolute path location
193   strcpy (temp,path);
194   strcpy (path,basepath);
195   strcat (path,temp);
196 }
197
198
199 void    StripFilename (char *path)
200 {
201   int             length;
202
203   length = strlen(path)-1;
204   while (length > 0 && path[length] != PATHSEPERATOR)
205     length--;
206   path[length] = 0;
207 }
208
209 void    StripExtension (char *path)
210 {
211   int             length;
212
213   length = strlen(path)-1;
214   while (length > 0 && path[length] != '.')
215   {
216     length--;
217     if (path[length] == '/')
218       return;   // no extension
219   }
220   if (length)
221     path[length] = 0;
222 }
223
224
225 /*
226 ====================
227 Extract file parts
228 ====================
229 */
230 void ExtractFilePath (const char *path, char *dest)
231 {
232   const char *src;
233
234   src = path + strlen(path) - 1;
235
236 //
237 // back up until a \ or the start
238 //
239   while (src != path && *(src-1) != '/' && *(src-1) != '\\')
240     src--;
241
242   memcpy (dest, path, src-path);
243   dest[src-path] = 0;
244 }
245
246 void ExtractFileName (const char *path, char *dest)
247 {
248   const char *src;
249
250   src = path + strlen(path) - 1;
251
252 //
253 // back up until a \ or the start
254 //
255   while (src != path && *(src-1) != '/' 
256          && *(src-1) != '\\' )
257     src--;
258
259   while (*src)
260   {
261     *dest++ = *src++;
262   }
263   *dest = 0;
264 }
265
266 inline const char* path_get_filename_start(const char* path)
267 {
268   {
269     const char* last_forward_slash = strrchr(path, '/');
270     if(last_forward_slash != NULL)
271       return last_forward_slash + 1;
272   }
273
274   {
275     const char* last_backward_slash = strrchr(path, '\\');
276     if(last_backward_slash != NULL)
277       return last_backward_slash + 1;
278   }
279
280   return path;
281 }
282
283 inline unsigned int filename_get_base_length(const char* filename)
284 {
285   const char* last_period = strrchr(filename, '.');
286   return (last_period != NULL) ? last_period - filename : strlen(filename);
287 }
288
289 void ExtractFileBase (const char *path, char *dest)
290 {
291   const char* filename = path_get_filename_start(path);
292   unsigned int length = filename_get_base_length(filename);
293   strncpy(dest, filename, length);
294   dest[length] = '\0';
295 }
296
297 void ExtractFileExtension (const char *path, char *dest)
298 {
299   const char *src;
300
301   src = path + strlen(path) - 1;
302
303 //
304 // back up until a . or the start
305 //
306   while (src != path && *(src-1) != '.')
307     src--;
308   if (src == path)
309   {
310     *dest = 0;  // no extension
311     return;
312   }
313
314   strcpy (dest,src);
315 }
316
317
318 void ConvertDOSToUnixName( char *dst, const char *src )
319 {
320   while ( *src )
321   {
322     if ( *src == '\\' )
323       *dst = '/';
324     else
325       *dst = *src;
326     dst++; src++;
327   }
328   *dst = 0;
329 }
330
331
332 char* StrDup(char* pStr)
333
334   if (pStr)
335   {
336     return strcpy(new char[strlen(pStr)+1], pStr); 
337   }
338   return NULL;
339 }
340
341 char* StrDup(const char* pStr)
342
343   if (pStr)
344   {
345     return strcpy(new char[strlen(pStr)+1], pStr); 
346   }
347   return NULL;
348 }
349
350 void CreateDirectoryPath (const char *path) {
351   char base[PATH_MAX];
352   char *src;
353   char back;
354   
355   ExtractFilePath(path, base);
356
357   src = base+1;
358   while (1) {
359     while (*src != '\0' && *src != '/' && *src != '\\') {
360       src++;
361     }
362     if (*src == '\0') {
363       break;
364     }
365     back = *src; *src = '\0';
366     Q_mkdir(base, 0755);
367     *src = back; src++;
368   }
369 }
370
371 /*
372 ============================================================================
373
374           BYTE ORDER FUNCTIONS
375
376 ============================================================================
377 */
378
379 #ifdef _SGI_SOURCE
380   #define       __BIG_ENDIAN__
381 #endif
382
383 #ifdef __BIG_ENDIAN__
384
385 short   LittleShort (short l)
386 {
387   byte    b1,b2;
388
389   b1 = l&255;
390   b2 = (l>>8)&255;
391
392   return(b1<<8) + b2;
393 }
394
395 short   BigShort (short l)
396 {
397   return l;
398 }
399
400
401 int    LittleLong (int l)
402 {
403   byte    b1,b2,b3,b4;
404
405   b1 = l&255;
406   b2 = (l>>8)&255;
407   b3 = (l>>16)&255;
408   b4 = (l>>24)&255;
409
410   return((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
411 }
412
413 int    BigLong (int l)
414 {
415   return l;
416 }
417
418
419 float LittleFloat (float l)
420 {
421   union
422   {
423     byte b[4]; float f;
424   } in, out;
425
426   in.f = l;
427   out.b[0] = in.b[3];
428   out.b[1] = in.b[2];
429   out.b[2] = in.b[1];
430   out.b[3] = in.b[0];
431
432   return out.f;
433 }
434
435 float BigFloat (float l)
436 {
437   return l;
438 }
439
440 #else
441
442 short   BigShort (short l)
443 {
444   byte    b1,b2;
445
446   b1 = l&255;
447   b2 = (l>>8)&255;
448
449   return(b1<<8) + b2;
450 }
451
452 short   LittleShort (short l)
453 {
454   return l;
455 }
456
457
458 int    BigLong (int l)
459 {
460   byte    b1,b2,b3,b4;
461
462   b1 = l&255;
463   b2 = (l>>8)&255;
464   b3 = (l>>16)&255;
465   b4 = (l>>24)&255;
466
467   return((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
468 }
469
470 int    LittleLong (int l)
471 {
472   return l;
473 }
474
475 float BigFloat (float l)
476 {
477   union
478   {
479     byte b[4]; float f;
480   } in, out;
481
482   in.f = l;
483   out.b[0] = in.b[3];
484   out.b[1] = in.b[2];
485   out.b[2] = in.b[1];
486   out.b[3] = in.b[0];
487
488   return out.f;
489 }
490
491 float LittleFloat (float l)
492 {
493   return l;
494 }
495
496 #endif