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