]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/extra/qe4/cmdlib.c
Q2Tools source - didn't import this in initially
[xonotic/netradiant.git] / tools / quake2 / extra / qe4 / cmdlib.c
1 /*
2 ===========================================================================
3 Copyright (C) 1997-2006 Id Software, Inc.
4
5 This file is part of Quake 2 Tools source code.
6
7 Quake 2 Tools source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11
12 Quake 2 Tools source code is distributed in the hope that it will be
13 useful, 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 Quake 2 Tools source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 ===========================================================================
21 */
22
23 // cmdlib.c
24
25 #include "cmdlib.h"
26
27 #define PATHSEPERATOR   '/'
28
29 char            com_token[1024];
30 qboolean        com_eof;
31
32 /*
33 ================
34 I_FloatTime
35 ================
36 */
37 double I_FloatTime (void)
38 {
39         time_t  t;
40
41         time (&t);
42
43         return t;
44 #if 0
45 // more precise, less portable
46         struct timeval tp;
47         struct timezone tzp;
48         static int              secbase;
49
50         gettimeofday(&tp, &tzp);
51
52         if (!secbase)
53         {
54                 secbase = tp.tv_sec;
55                 return tp.tv_usec/1000000.0;
56         }
57
58         return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0;
59 #endif
60 }
61
62
63 /*
64 ==============
65 COM_Parse
66
67 Parse a token out of a string
68 ==============
69 */
70 char *COM_Parse (char *data)
71 {
72         int             c;
73         int             len;
74
75         len = 0;
76         com_token[0] = 0;
77
78         if (!data)
79                 return NULL;
80
81 // skip whitespace
82 skipwhite:
83         while ( (c = *data) <= ' ')
84         {
85                 if (c == 0)
86                 {
87                         com_eof = true;
88                         return NULL;                    // end of file;
89                 }
90                 data++;
91         }
92
93 // skip // comments
94         if (c=='/' && data[1] == '/')
95         {
96                 while (*data && *data != '\n')
97                         data++;
98                 goto skipwhite;
99         }
100
101
102 // handle quoted strings specially
103         if (c == '\"')
104         {
105                 data++;
106                 do
107                 {
108                         c = *data++;
109                         if (c=='\"')
110                         {
111                                 com_token[len] = 0;
112                                 return data;
113                         }
114                         com_token[len] = c;
115                         len++;
116                 } while (1);
117         }
118
119 // parse single characters
120         if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':')
121         {
122                 com_token[len] = c;
123                 len++;
124                 com_token[len] = 0;
125                 return data+1;
126         }
127
128 // parse a regular word
129         do
130         {
131                 com_token[len] = c;
132                 data++;
133                 len++;
134                 c = *data;
135         if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':')
136                         break;
137         } while (c>32);
138
139         com_token[len] = 0;
140         return data;
141 }
142
143
144 int Q_strncasecmp (char *s1, char *s2, int n)
145 {
146         int             c1, c2;
147
148         while (1)
149         {
150                 c1 = *s1++;
151                 c2 = *s2++;
152
153                 if (!n--)
154                         return 0;               // strings are equal until end point
155
156                 if (c1 != c2)
157                 {
158                         if (c1 >= 'a' && c1 <= 'z')
159                                 c1 -= ('a' - 'A');
160                         if (c2 >= 'a' && c2 <= 'z')
161                                 c2 -= ('a' - 'A');
162                         if (c1 != c2)
163                                 return -1;              // strings not equal
164                 }
165                 if (!c1)
166                         return 0;               // strings are equal
167         }
168
169         return -1;
170 }
171
172 int Q_strcasecmp (char *s1, char *s2)
173 {
174         return Q_strncasecmp (s1, s2, 99999);
175 }
176
177
178
179 /*
180 =============================================================================
181
182                                                 MISC FUNCTIONS
183
184 =============================================================================
185 */
186
187
188 int             argc;
189 char    *argv[MAX_NUM_ARGVS];
190
191 /*
192 ============
193 ParseCommandLine
194 ============
195 */
196 void ParseCommandLine (char *lpCmdLine)
197 {
198         argc = 1;
199         argv[0] = "programname";
200
201         while (*lpCmdLine && (argc < MAX_NUM_ARGVS))
202         {
203                 while (*lpCmdLine && ((*lpCmdLine <= 32) || (*lpCmdLine > 126)))
204                         lpCmdLine++;
205
206                 if (*lpCmdLine)
207                 {
208                         argv[argc] = lpCmdLine;
209                         argc++;
210
211                         while (*lpCmdLine && ((*lpCmdLine > 32) && (*lpCmdLine <= 126)))
212                                 lpCmdLine++;
213
214                         if (*lpCmdLine)
215                         {
216                                 *lpCmdLine = 0;
217                                 lpCmdLine++;
218                         }
219
220                 }
221         }
222 }
223
224
225
226 /*
227 =================
228 CheckParm
229
230 Checks for the given parameter in the program's command line arguments
231 Returns the argument number (1 to argc-1) or 0 if not present
232 =================
233 */
234 int CheckParm (char *check)
235 {
236         int             i;
237
238         for (i = 1;i<argc;i++)
239         {
240                 if ( !Q_strcasecmp(check, argv[i]) )
241                         return i;
242         }
243
244         return 0;
245 }
246
247
248
249 /*
250 ================
251 Q_filelength
252 ================
253 */
254 int Q_filelength (FILE *f)
255 {
256         int             pos;
257         int             end;
258
259         pos = ftell (f);
260         fseek (f, 0, SEEK_END);
261         end = ftell (f);
262         fseek (f, pos, SEEK_SET);
263
264         return end;
265 }
266
267
268 FILE *SafeOpenWrite (char *filename)
269 {
270         FILE    *f;
271
272         f = fopen(filename, "wb");
273
274         if (!f)
275                 Error ("Error opening %s: %s",filename,strerror(errno));
276
277         return f;
278 }
279
280 FILE *SafeOpenRead (char *filename)
281 {
282         FILE    *f;
283
284         f = fopen(filename, "rb");
285
286         if (!f)
287                 Error ("Error opening %s: %s",filename,strerror(errno));
288
289         return f;
290 }
291
292
293 void SafeRead (FILE *f, void *buffer, int count)
294 {
295         if ( (int)fread (buffer, 1, count, f) != count)
296                 Error ("File read failure");
297 }
298
299
300 void SafeWrite (FILE *f, void *buffer, int count)
301 {
302         if ( (int)fwrite (buffer, 1, count, f) != count)
303                 Error ("File read failure");
304 }
305
306
307
308 /*
309 ==============
310 LoadFile
311 ==============
312 */
313 int    LoadFile (char *filename, void **bufferptr)
314 {
315         FILE    *f;
316         int    length;
317         void    *buffer;
318         extern void *qmalloc( size_t size );
319
320         f = fopen (filename, "rb");
321         if (!f)
322         {
323                 *bufferptr = NULL;
324                 return -1;
325         }
326         length = Q_filelength (f);
327         buffer = qmalloc (length+1);
328         ((char *)buffer)[length] = 0;
329         SafeRead (f, buffer, length);
330         fclose (f);
331
332         *bufferptr = buffer;
333         return length;
334 }
335
336
337 /*
338 ==============
339 LoadFileNoCrash
340
341 returns -1 length if not present
342 ==============
343 */
344 int    LoadFileNoCrash (char *filename, void **bufferptr)
345 {
346         FILE    *f;
347         int    length;
348         void    *buffer;
349
350         f = fopen (filename, "rb");
351         if (!f)
352                 return -1;
353         length = Q_filelength (f);
354         buffer = qmalloc (length+1);
355         ((char *)buffer)[length] = 0;
356         SafeRead (f, buffer, length);
357         fclose (f);
358
359         *bufferptr = buffer;
360         return length;
361 }
362
363
364 /*
365 ==============
366 SaveFile
367 ==============
368 */
369 void    SaveFile (char *filename, void *buffer, int count)
370 {
371         FILE    *f;
372
373         f = SafeOpenWrite (filename);
374         SafeWrite (f, buffer, count);
375         fclose (f);
376 }
377
378
379
380 void DefaultExtension (char *path, char *extension)
381 {
382         char    *src;
383 //
384 // if path doesn't have a .EXT, append extension
385 // (extension should include the .)
386 //
387         src = path + strlen(path) - 1;
388
389         while (*src != PATHSEPERATOR && src != path)
390         {
391                 if (*src == '.')
392                         return;                 // it has an extension
393                 src--;
394         }
395
396         strcat (path, extension);
397 }
398
399
400 void DefaultPath (char *path, char *basepath)
401 {
402         char    temp[128];
403
404         if (path[0] == PATHSEPERATOR)
405                 return;                   // absolute path location
406         strcpy (temp,path);
407         strcpy (path,basepath);
408         strcat (path,temp);
409 }
410
411
412 void    StripFilename (char *path)
413 {
414         int             length;
415
416         length = strlen(path)-1;
417         while (length > 0 && path[length] != PATHSEPERATOR)
418                 length--;
419         path[length] = 0;
420 }
421
422 void    StripExtension (char *path)
423 {
424         int             length;
425
426         length = strlen(path)-1;
427         while (length > 0 && path[length] != '.')
428         {
429                 length--;
430                 if (path[length] == '/')
431                         return;         // no extension
432         }
433         if (length)
434                 path[length] = 0;
435 }
436
437
438 /*
439 ====================
440 Extract file parts
441 ====================
442 */
443 void ExtractFilePath (char *path, char *dest)
444 {
445         char    *src;
446
447         src = path + strlen(path) - 1;
448
449 //
450 // back up until a \ or the start
451 //
452         while (src != path && *(src-1) != PATHSEPERATOR)
453                 src--;
454
455         memcpy (dest, path, src-path);
456         dest[src-path] = 0;
457 }
458
459 void ExtractFileName (char *path, char *dest)
460 {
461         char    *src;
462
463         src = path + strlen(path) - 1;
464
465 //
466 // back up until a \ or the start
467 //
468         while (src != path && *(src-1) != '/'
469                  && *(src-1) != '\\' )
470                 src--;
471
472         while (*src)
473         {
474                 *dest++ = *src++;
475         }
476         *dest = 0;
477 }
478
479 void ExtractFileBase (char *path, char *dest)
480 {
481         char    *src;
482
483         src = path + strlen(path) - 1;
484
485 //
486 // back up until a \ or the start
487 //
488         while (src != path && *(src-1) != '/'
489                  && *(src-1) != '\\' )
490                 src--;
491
492         while (*src && *src != '.')
493         {
494                 *dest++ = *src++;
495         }
496         *dest = 0;
497 }
498
499 void ExtractFileExtension (char *path, char *dest)
500 {
501         char    *src;
502
503         src = path + strlen(path) - 1;
504
505 //
506 // back up until a . or the start
507 //
508         while (src != path && *(src-1) != '.')
509                 src--;
510         if (src == path)
511         {
512                 *dest = 0;      // no extension
513                 return;
514         }
515
516         strcpy (dest,src);
517 }
518
519
520 /*
521 ==============
522 ParseNum / ParseHex
523 ==============
524 */
525 int ParseHex (char *hex)
526 {
527         char    *str;
528         int    num;
529
530         num = 0;
531         str = hex;
532
533         while (*str)
534         {
535                 num <<= 4;
536                 if (*str >= '0' && *str <= '9')
537                         num += *str-'0';
538                 else if (*str >= 'a' && *str <= 'f')
539                         num += 10 + *str-'a';
540                 else if (*str >= 'A' && *str <= 'F')
541                         num += 10 + *str-'A';
542                 else
543                         Error ("Bad hex number: %s",hex);
544                 str++;
545         }
546
547         return num;
548 }
549
550
551 int ParseNum (char *str)
552 {
553         if (str[0] == '$')
554                 return ParseHex (str+1);
555         if (str[0] == '0' && str[1] == 'x')
556                 return ParseHex (str+2);
557         return atol (str);
558 }
559
560
561
562 /*
563 ============================================================================
564
565                                         BYTE ORDER FUNCTIONS
566
567 ============================================================================
568 */
569
570 #ifdef _SGI_SOURCE
571 #define __BIG_ENDIAN__
572 #endif
573
574 #ifdef __BIG_ENDIAN__
575
576 short   LittleShort (short l)
577 {
578         byte    b1,b2;
579
580         b1 = l&255;
581         b2 = (l>>8)&255;
582
583         return (b1<<8) + b2;
584 }
585
586 short   BigShort (short l)
587 {
588         return l;
589 }
590
591
592 int    LittleLong (int l)
593 {
594         byte    b1,b2,b3,b4;
595
596         b1 = l&255;
597         b2 = (l>>8)&255;
598         b3 = (l>>16)&255;
599         b4 = (l>>24)&255;
600
601         return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
602 }
603
604 int    BigLong (int l)
605 {
606         return l;
607 }
608
609
610 float   LittleFloat (float l)
611 {
612         union {byte b[4]; float f;} in, out;
613
614         in.f = l;
615         out.b[0] = in.b[3];
616         out.b[1] = in.b[2];
617         out.b[2] = in.b[1];
618         out.b[3] = in.b[0];
619
620         return out.f;
621 }
622
623 float   BigFloat (float l)
624 {
625         return l;
626 }
627
628
629 #else
630
631
632 short   BigShort (short l)
633 {
634         byte    b1,b2;
635
636         b1 = l&255;
637         b2 = (l>>8)&255;
638
639         return (b1<<8) + b2;
640 }
641
642 short   LittleShort (short l)
643 {
644         return l;
645 }
646
647
648 int    BigLong (int l)
649 {
650         byte    b1,b2,b3,b4;
651
652         b1 = l&255;
653         b2 = (l>>8)&255;
654         b3 = (l>>16)&255;
655         b4 = (l>>24)&255;
656
657         return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
658 }
659
660 int    LittleLong (int l)
661 {
662         return l;
663 }
664
665 float   BigFloat (float l)
666 {
667         union {byte b[4]; float f;} in, out;
668
669         in.f = l;
670         out.b[0] = in.b[3];
671         out.b[1] = in.b[2];
672         out.b[2] = in.b[1];
673         out.b[3] = in.b[0];
674
675         return out.f;
676 }
677
678 float   LittleFloat (float l)
679 {
680         return l;
681 }
682
683
684
685 #endif
686